/*! * ONNX Runtime Web v1.26.0 * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ "use strict"; var ort = (() => { 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 __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __commonJS = (cb, mod2) => function __require2() { 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.26.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, tensorFromMLTensor, 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 (typeof HTMLCanvasElement !== "undefined" && 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 }); }; tensorFromMLTensor = (mlTensor, options) => { const { dataType, dims, download, dispose } = options; return new Tensor({ location: "ml-tensor", type: dataType ?? "float32", mlTensor, 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], ["int4", Uint8Array], ["uint4", Uint8Array] ]); 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 Float16Array2 = globalThis.Float16Array; const isFloat16ArrayAvailable = typeof Float16Array2 !== "undefined" && Float16Array2.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", Float16Array2); NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.set(Float16Array2, "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 }); case "ml-tensor": return new Tensor({ location: "ml-tensor", mlTensor: tensor.mlTensor, 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" && type !== "uint4" && type !== "int4") { 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; } case "ml-tensor": { if (type !== "float32" && type !== "float16" && type !== "int32" && type !== "int64" && type !== "uint32" && type !== "uint64" && type !== "int8" && type !== "uint8" && type !== "bool" && type !== "uint4" && type !== "int4") { throw new TypeError(`unsupported type "${type}" to create tensor from MLTensor`); } this.mlTensorData = arg0.mlTensor; 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 || arg0 === "uint4" || arg0 === "int4") { throw new TypeError(`Creating a ${arg0} tensor from number array is not supported. Please use ${typedArrayConstructor.name} 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 if (arg1 instanceof Uint8ClampedArray) { if (arg0 === "uint8") { data = Uint8Array.from(arg1); } else { throw new TypeError(`A Uint8ClampedArray tensor's data must be type of uint8`); } } else if (arg0 === "float16" && arg1 instanceof Uint16Array && typedArrayConstructor !== Uint16Array) { data = new globalThis.Float16Array(arg1.buffer, arg1.byteOffset, arg1.length); } 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 if (arg0 instanceof Uint8ClampedArray) { type = "uint8"; data = Uint8Array.from(arg0); } 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) { if ((type === "uint4" || type === "int4") && Math.ceil(size / 2) === this.cpuData.length) { } else { 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 fromMLTensor(mlTensor, options) { return tensorFromMLTensor(mlTensor, 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; } get mlTensor() { this.ensureValid(); if (!this.mlTensorData) { throw new Error("The data is not stored as a WebNN MLTensor."); } return this.mlTensorData; } // #endregion // #region methods async getData(releaseData) { this.ensureValid(); switch (this.dataLocation) { case "cpu": case "cpu-pinned": return this.data; case "texture": case "gpu-buffer": case "ml-tensor": { 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.mlTensorData = 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, TRACE_EVENT_BEGIN, TRACE_EVENT_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); }; TRACE_EVENT_BEGIN = (extraMsg) => { if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { return; } console.time(`ORT::${extraMsg}`); }; TRACE_EVENT_END = (extraMsg) => { if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { return; } console.timeEnd(`ORT::${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(); TRACE_EVENT_BEGIN("InferenceSession.run"); 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_EVENT_END("InferenceSession.run"); TRACE_FUNC_END(); return returnValue; } async release() { return this.handler.dispose(); } static async create(arg0, arg1, arg2, arg3) { TRACE_FUNC_BEGIN(); TRACE_EVENT_BEGIN("InferenceSession.create"); 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_EVENT_END("InferenceSession.create"); 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; } get inputMetadata() { return this.handler.inputMetadata; } get outputMetadata() { return this.handler.outputMetadata; } }; } }); // 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/index.js var esm_exports = {}; __export(esm_exports, { InferenceSession: () => InferenceSession2, TRACE: () => TRACE, TRACE_EVENT_BEGIN: () => TRACE_EVENT_BEGIN, TRACE_EVENT_END: () => TRACE_EVENT_END, TRACE_FUNC_BEGIN: () => TRACE_FUNC_BEGIN, TRACE_FUNC_END: () => TRACE_FUNC_END, Tensor: () => Tensor2, 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(); } }); // 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 }; ((log4) => { function verbose(arg0, arg1) { log4("verbose", arg0, arg1); } log4.verbose = verbose; function info(arg0, arg1) { log4("info", arg0, arg1); } log4.info = info; function warning(arg0, arg1) { log4("warning", arg0, arg1); } log4.warning = warning; function error(arg0, arg1) { log4("error", arg0, arg1); } log4.error = error; function fatal(arg0, arg1) { log4("fatal", arg0, arg1); } log4.fatal = fatal; function reset(config) { LOGGER_CONFIG_MAP = {}; set("", config || {}); } log4.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 }; } } log4.set = set; function setWithEnv(env3) { const config = {}; if (env3.logLevel) { config.minimalSeverity = env3.logLevel; } set("", config); } log4.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(guid2) { if (!guid2) { throw new TypeError("Invalid argument; `value` has no value."); } this.value = Guid3.EMPTY; if (guid2 && Guid3.isGuid(guid2)) { this.value = guid2; } } Guid3.isGuid = function(guid2) { var value = guid2.toString(); return guid2 && (guid2 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(guid2) { return new Guid3(guid2); }; 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), div3 = this.div(radixLong), rem1 = div3.mul(radixLong).sub(this); return div3.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/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/arg-type.js var require_arg_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/arg-type.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.ArgType = void 0; var ArgType2; (function(ArgType3) { ArgType3[ArgType3["INPUT"] = 0] = "INPUT"; ArgType3[ArgType3["OUTPUT"] = 1] = "OUTPUT"; })(ArgType2 || (exports2.ArgType = ArgType2 = {})); } }); // web/node_modules/flatbuffers/js/constants.js var require_constants = __commonJS({ "web/node_modules/flatbuffers/js/constants.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.SIZE_PREFIX_LENGTH = exports2.FILE_IDENTIFIER_LENGTH = exports2.SIZEOF_INT = exports2.SIZEOF_SHORT = void 0; exports2.SIZEOF_SHORT = 2; exports2.SIZEOF_INT = 4; exports2.FILE_IDENTIFIER_LENGTH = 4; exports2.SIZE_PREFIX_LENGTH = 4; } }); // web/node_modules/flatbuffers/js/utils.js var require_utils = __commonJS({ "web/node_modules/flatbuffers/js/utils.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.isLittleEndian = exports2.float64 = exports2.float32 = exports2.int32 = void 0; exports2.int32 = new Int32Array(2); exports2.float32 = new Float32Array(exports2.int32.buffer); exports2.float64 = new Float64Array(exports2.int32.buffer); exports2.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1; } }); // web/node_modules/flatbuffers/js/encoding.js var require_encoding = __commonJS({ "web/node_modules/flatbuffers/js/encoding.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Encoding = void 0; var Encoding; (function(Encoding2) { Encoding2[Encoding2["UTF8_BYTES"] = 1] = "UTF8_BYTES"; Encoding2[Encoding2["UTF16_STRING"] = 2] = "UTF16_STRING"; })(Encoding || (exports2.Encoding = Encoding = {})); } }); // web/node_modules/flatbuffers/js/byte-buffer.js var require_byte_buffer = __commonJS({ "web/node_modules/flatbuffers/js/byte-buffer.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.ByteBuffer = void 0; var constants_js_1 = require_constants(); var utils_js_1 = require_utils(); var encoding_js_1 = require_encoding(); var ByteBuffer2 = class _ByteBuffer { /** * Create a new ByteBuffer with a given array of bytes (`Uint8Array`) */ constructor(bytes_) { this.bytes_ = bytes_; this.position_ = 0; this.text_decoder_ = new TextDecoder(); } /** * Create and allocate a new ByteBuffer with a given size. */ static allocate(byte_size) { return new _ByteBuffer(new Uint8Array(byte_size)); } clear() { this.position_ = 0; } /** * Get the underlying `Uint8Array`. */ bytes() { return this.bytes_; } /** * Get the buffer's position. */ position() { return this.position_; } /** * Set the buffer's position. */ setPosition(position) { this.position_ = position; } /** * Get the buffer's capacity. */ capacity() { return this.bytes_.length; } readInt8(offset) { return this.readUint8(offset) << 24 >> 24; } readUint8(offset) { return this.bytes_[offset]; } readInt16(offset) { return this.readUint16(offset) << 16 >> 16; } readUint16(offset) { return this.bytes_[offset] | this.bytes_[offset + 1] << 8; } readInt32(offset) { return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24; } readUint32(offset) { return this.readInt32(offset) >>> 0; } readInt64(offset) { return BigInt.asIntN(64, BigInt(this.readUint32(offset)) + (BigInt(this.readUint32(offset + 4)) << BigInt(32))); } readUint64(offset) { return BigInt.asUintN(64, BigInt(this.readUint32(offset)) + (BigInt(this.readUint32(offset + 4)) << BigInt(32))); } readFloat32(offset) { utils_js_1.int32[0] = this.readInt32(offset); return utils_js_1.float32[0]; } readFloat64(offset) { utils_js_1.int32[utils_js_1.isLittleEndian ? 0 : 1] = this.readInt32(offset); utils_js_1.int32[utils_js_1.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4); return utils_js_1.float64[0]; } writeInt8(offset, value) { this.bytes_[offset] = value; } writeUint8(offset, value) { this.bytes_[offset] = value; } writeInt16(offset, value) { this.bytes_[offset] = value; this.bytes_[offset + 1] = value >> 8; } writeUint16(offset, value) { this.bytes_[offset] = value; this.bytes_[offset + 1] = value >> 8; } writeInt32(offset, value) { this.bytes_[offset] = value; this.bytes_[offset + 1] = value >> 8; this.bytes_[offset + 2] = value >> 16; this.bytes_[offset + 3] = value >> 24; } writeUint32(offset, value) { this.bytes_[offset] = value; this.bytes_[offset + 1] = value >> 8; this.bytes_[offset + 2] = value >> 16; this.bytes_[offset + 3] = value >> 24; } writeInt64(offset, value) { this.writeInt32(offset, Number(BigInt.asIntN(32, value))); this.writeInt32(offset + 4, Number(BigInt.asIntN(32, value >> BigInt(32)))); } writeUint64(offset, value) { this.writeUint32(offset, Number(BigInt.asUintN(32, value))); this.writeUint32(offset + 4, Number(BigInt.asUintN(32, value >> BigInt(32)))); } writeFloat32(offset, value) { utils_js_1.float32[0] = value; this.writeInt32(offset, utils_js_1.int32[0]); } writeFloat64(offset, value) { utils_js_1.float64[0] = value; this.writeInt32(offset, utils_js_1.int32[utils_js_1.isLittleEndian ? 0 : 1]); this.writeInt32(offset + 4, utils_js_1.int32[utils_js_1.isLittleEndian ? 1 : 0]); } /** * Return the file identifier. Behavior is undefined for FlatBuffers whose * schema does not include a file_identifier (likely points at padding or the * start of a the root vtable). */ getBufferIdentifier() { if (this.bytes_.length < this.position_ + constants_js_1.SIZEOF_INT + constants_js_1.FILE_IDENTIFIER_LENGTH) { throw new Error("FlatBuffers: ByteBuffer is too short to contain an identifier."); } let result = ""; for (let i = 0; i < constants_js_1.FILE_IDENTIFIER_LENGTH; i++) { result += String.fromCharCode(this.readInt8(this.position_ + constants_js_1.SIZEOF_INT + i)); } return result; } /** * Look up a field in the vtable, return an offset into the object, or 0 if the * field is not present. */ __offset(bb_pos, vtable_offset) { const vtable = bb_pos - this.readInt32(bb_pos); return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0; } /** * Initialize any Table-derived type to point to the union at the given offset. */ __union(t, offset) { t.bb_pos = offset + this.readInt32(offset); t.bb = this; return t; } /** * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer. * This allocates a new string and converts to wide chars upon each access. * * To avoid the conversion to string, pass Encoding.UTF8_BYTES as the * "optionalEncoding" argument. This is useful for avoiding conversion when * the data will just be packaged back up in another FlatBuffer later on. * * @param offset * @param opt_encoding Defaults to UTF16_STRING */ __string(offset, opt_encoding) { offset += this.readInt32(offset); const length = this.readInt32(offset); offset += constants_js_1.SIZEOF_INT; const utf8bytes = this.bytes_.subarray(offset, offset + length); if (opt_encoding === encoding_js_1.Encoding.UTF8_BYTES) return utf8bytes; else return this.text_decoder_.decode(utf8bytes); } /** * Handle unions that can contain string as its member, if a Table-derived type then initialize it, * if a string then return a new one * * WARNING: strings are immutable in JS so we can't change the string that the user gave us, this * makes the behaviour of __union_with_string different compared to __union */ __union_with_string(o, offset) { if (typeof o === "string") { return this.__string(offset); } return this.__union(o, offset); } /** * Retrieve the relative offset stored at "offset" */ __indirect(offset) { return offset + this.readInt32(offset); } /** * Get the start of data of a vector whose offset is stored at "offset" in this object. */ __vector(offset) { return offset + this.readInt32(offset) + constants_js_1.SIZEOF_INT; } /** * Get the length of a vector whose offset is stored at "offset" in this object. */ __vector_len(offset) { return this.readInt32(offset + this.readInt32(offset)); } __has_identifier(ident) { if (ident.length != constants_js_1.FILE_IDENTIFIER_LENGTH) { throw new Error("FlatBuffers: file identifier must be length " + constants_js_1.FILE_IDENTIFIER_LENGTH); } for (let i = 0; i < constants_js_1.FILE_IDENTIFIER_LENGTH; i++) { if (ident.charCodeAt(i) != this.readInt8(this.position() + constants_js_1.SIZEOF_INT + i)) { return false; } } return true; } /** * A helper function for generating list for obj api */ createScalarList(listAccessor, listLength) { const ret = []; for (let i = 0; i < listLength; ++i) { const val = listAccessor(i); if (val !== null) { ret.push(val); } } return ret; } /** * A helper function for generating list for obj api * @param listAccessor function that accepts an index and return data at that index * @param listLength listLength * @param res result list */ createObjList(listAccessor, listLength) { const ret = []; for (let i = 0; i < listLength; ++i) { const val = listAccessor(i); if (val !== null) { ret.push(val.unpack()); } } return ret; } }; exports2.ByteBuffer = ByteBuffer2; } }); // web/node_modules/flatbuffers/js/builder.js var require_builder = __commonJS({ "web/node_modules/flatbuffers/js/builder.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Builder = void 0; var byte_buffer_js_1 = require_byte_buffer(); var constants_js_1 = require_constants(); var Builder = class _Builder { /** * Create a FlatBufferBuilder. */ constructor(opt_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; this.string_maps = null; this.text_encoder = new TextEncoder(); let initial_size; if (!opt_initial_size) { initial_size = 1024; } else { initial_size = opt_initial_size; } this.bb = byte_buffer_js_1.ByteBuffer.allocate(initial_size); this.space = initial_size; } clear() { 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; this.string_maps = null; } /** * In order to save space, fields that are set to their default value * don't get serialized into the buffer. Forcing defaults provides a * way to manually disable this optimization. * * @param forceDefaults true always serializes default values */ forceDefaults(forceDefaults) { this.force_defaults = forceDefaults; } /** * Get the ByteBuffer representing the FlatBuffer. Only call this after you've * called finish(). The actual data starts at the ByteBuffer's current position, * not necessarily at 0. */ dataBuffer() { return this.bb; } /** * Get the bytes representing the FlatBuffer. Only call this after you've * called finish(). */ asUint8Array() { return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset()); } /** * Prepare to write an element of `size` after `additional_bytes` have been * written, e.g. if you write a string, you need to align such the int length * field is aligned to 4 bytes, and the string data follows it directly. If all * you need to do is alignment, `additional_bytes` will be 0. * * @param size This is the of the new element to write * @param additional_bytes The padding size */ prep(size, additional_bytes) { if (size > this.minalign) { this.minalign = size; } const align_size = ~(this.bb.capacity() - this.space + additional_bytes) + 1 & size - 1; while (this.space < align_size + size + additional_bytes) { const old_buf_size = this.bb.capacity(); this.bb = _Builder.growByteBuffer(this.bb); this.space += this.bb.capacity() - old_buf_size; } this.pad(align_size); } pad(byte_size) { for (let i = 0; i < byte_size; i++) { this.bb.writeInt8(--this.space, 0); } } writeInt8(value) { this.bb.writeInt8(this.space -= 1, value); } writeInt16(value) { this.bb.writeInt16(this.space -= 2, value); } writeInt32(value) { this.bb.writeInt32(this.space -= 4, value); } writeInt64(value) { this.bb.writeInt64(this.space -= 8, value); } writeFloat32(value) { this.bb.writeFloat32(this.space -= 4, value); } writeFloat64(value) { this.bb.writeFloat64(this.space -= 8, value); } /** * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary). * @param value The `int8` to add the buffer. */ addInt8(value) { this.prep(1, 0); this.writeInt8(value); } /** * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary). * @param value The `int16` to add the buffer. */ addInt16(value) { this.prep(2, 0); this.writeInt16(value); } /** * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary). * @param value The `int32` to add the buffer. */ addInt32(value) { this.prep(4, 0); this.writeInt32(value); } /** * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary). * @param value The `int64` to add the buffer. */ addInt64(value) { this.prep(8, 0); this.writeInt64(value); } /** * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary). * @param value The `float32` to add the buffer. */ addFloat32(value) { this.prep(4, 0); this.writeFloat32(value); } /** * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary). * @param value The `float64` to add the buffer. */ addFloat64(value) { this.prep(8, 0); this.writeFloat64(value); } addFieldInt8(voffset, value, defaultValue) { if (this.force_defaults || value != defaultValue) { this.addInt8(value); this.slot(voffset); } } addFieldInt16(voffset, value, defaultValue) { if (this.force_defaults || value != defaultValue) { this.addInt16(value); this.slot(voffset); } } addFieldInt32(voffset, value, defaultValue) { if (this.force_defaults || value != defaultValue) { this.addInt32(value); this.slot(voffset); } } addFieldInt64(voffset, value, defaultValue) { if (this.force_defaults || value !== defaultValue) { this.addInt64(value); this.slot(voffset); } } addFieldFloat32(voffset, value, defaultValue) { if (this.force_defaults || value != defaultValue) { this.addFloat32(value); this.slot(voffset); } } addFieldFloat64(voffset, value, defaultValue) { if (this.force_defaults || value != defaultValue) { this.addFloat64(value); this.slot(voffset); } } addFieldOffset(voffset, value, defaultValue) { if (this.force_defaults || value != defaultValue) { this.addOffset(value); this.slot(voffset); } } /** * Structs are stored inline, so nothing additional is being added. `d` is always 0. */ addFieldStruct(voffset, value, defaultValue) { if (value != defaultValue) { this.nested(value); this.slot(voffset); } } /** * Structures are always stored inline, they need to be created right * where they're used. You'll get this assertion failure if you * created it elsewhere. */ nested(obj) { if (obj != this.offset()) { throw new TypeError("FlatBuffers: struct must be serialized inline."); } } /** * Should not be creating any other object, string or vector * while an object is being constructed */ notNested() { if (this.isNested) { throw new TypeError("FlatBuffers: object serialization must not be nested."); } } /** * Set the current vtable at `voffset` to the current location in the buffer. */ slot(voffset) { if (this.vtable !== null) this.vtable[voffset] = this.offset(); } /** * @returns Offset relative to the end of the buffer. */ offset() { return this.bb.capacity() - this.space; } /** * Doubles the size of the backing ByteBuffer and copies the old data towards * the end of the new buffer (since we build the buffer backwards). * * @param bb The current buffer with the existing data * @returns A new byte buffer with the old data copied * to it. The data is located at the end of the buffer. * * uint8Array.set() formally takes {Array|ArrayBufferView}, so to pass * it a uint8Array we need to suppress the type check: * @suppress {checkTypes} */ static growByteBuffer(bb) { const old_buf_size = bb.capacity(); if (old_buf_size & 3221225472) { throw new Error("FlatBuffers: cannot grow buffer beyond 2 gigabytes."); } const new_buf_size = old_buf_size << 1; const nbb = byte_buffer_js_1.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; } /** * Adds on offset, relative to where it will be written. * * @param offset The offset to add. */ addOffset(offset) { this.prep(constants_js_1.SIZEOF_INT, 0); this.writeInt32(this.offset() - offset + constants_js_1.SIZEOF_INT); } /** * Start encoding a new object in the buffer. Users will not usually need to * call this directly. The FlatBuffers compiler will generate helper methods * that call this method internally. */ startObject(numfields) { this.notNested(); if (this.vtable == null) { this.vtable = []; } this.vtable_in_use = numfields; for (let i = 0; i < numfields; i++) { this.vtable[i] = 0; } this.isNested = true; this.object_start = this.offset(); } /** * Finish off writing the object that is under construction. * * @returns The offset to the object inside `dataBuffer` */ endObject() { if (this.vtable == null || !this.isNested) { throw new Error("FlatBuffers: endObject called without startObject"); } this.addInt32(0); const vtableloc = this.offset(); let i = this.vtable_in_use - 1; for (; i >= 0 && this.vtable[i] == 0; i--) { } const trimmed_size = i + 1; for (; i >= 0; i--) { this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0); } const standard_fields = 2; this.addInt16(vtableloc - this.object_start); const len = (trimmed_size + standard_fields) * constants_js_1.SIZEOF_SHORT; this.addInt16(len); let existing_vtable = 0; const vt1 = this.space; outer_loop: for (i = 0; i < this.vtables.length; i++) { const vt2 = this.bb.capacity() - this.vtables[i]; if (len == this.bb.readInt16(vt2)) { for (let j = constants_js_1.SIZEOF_SHORT; j < len; j += constants_js_1.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; } /** * Finalize a buffer, poiting to the given `root_table`. */ finish(root_table, opt_file_identifier, opt_size_prefix) { const size_prefix = opt_size_prefix ? constants_js_1.SIZE_PREFIX_LENGTH : 0; if (opt_file_identifier) { const file_identifier = opt_file_identifier; this.prep(this.minalign, constants_js_1.SIZEOF_INT + constants_js_1.FILE_IDENTIFIER_LENGTH + size_prefix); if (file_identifier.length != constants_js_1.FILE_IDENTIFIER_LENGTH) { throw new TypeError("FlatBuffers: file identifier must be length " + constants_js_1.FILE_IDENTIFIER_LENGTH); } for (let i = constants_js_1.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) { this.writeInt8(file_identifier.charCodeAt(i)); } } this.prep(this.minalign, constants_js_1.SIZEOF_INT + size_prefix); this.addOffset(root_table); if (size_prefix) { this.addInt32(this.bb.capacity() - this.space); } this.bb.setPosition(this.space); } /** * Finalize a size prefixed buffer, pointing to the given `root_table`. */ finishSizePrefixed(root_table, opt_file_identifier) { this.finish(root_table, opt_file_identifier, true); } /** * This checks a required field has been set in a given table that has * just been constructed. */ requiredField(table, field) { const table_start = this.bb.capacity() - table; const vtable_start = table_start - this.bb.readInt32(table_start); const ok = field < this.bb.readInt16(vtable_start) && this.bb.readInt16(vtable_start + field) != 0; if (!ok) { throw new TypeError("FlatBuffers: field " + field + " must be set"); } } /** * Start a new array/vector of objects. Users usually will not call * this directly. The FlatBuffers compiler will create a start/end * method for vector types in generated code. * * @param elem_size The size of each element in the array * @param num_elems The number of elements in the array * @param alignment The alignment of the array */ startVector(elem_size, num_elems, alignment) { this.notNested(); this.vector_num_elems = num_elems; this.prep(constants_js_1.SIZEOF_INT, elem_size * num_elems); this.prep(alignment, elem_size * num_elems); } /** * Finish off the creation of an array and all its elements. The array must be * created with `startVector`. * * @returns The offset at which the newly created array * starts. */ endVector() { this.writeInt32(this.vector_num_elems); return this.offset(); } /** * Encode the string `s` in the buffer using UTF-8. If the string passed has * already been seen, we return the offset of the already written string * * @param s The string to encode * @return The offset in the buffer where the encoded string starts */ createSharedString(s) { if (!s) { return 0; } if (!this.string_maps) { this.string_maps = /* @__PURE__ */ new Map(); } if (this.string_maps.has(s)) { return this.string_maps.get(s); } const offset = this.createString(s); this.string_maps.set(s, offset); return offset; } /** * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed * instead of a string, it is assumed to contain valid UTF-8 encoded data. * * @param s The string to encode * @return The offset in the buffer where the encoded string starts */ createString(s) { if (s === null || s === void 0) { return 0; } let utf8; if (s instanceof Uint8Array) { utf8 = s; } else { utf8 = this.text_encoder.encode(s); } this.addInt8(0); this.startVector(1, utf8.length, 1); this.bb.setPosition(this.space -= utf8.length); this.bb.bytes().set(utf8, this.space); return this.endVector(); } /** * Create a byte vector. * * @param v The bytes to add * @returns The offset in the buffer where the byte vector starts */ createByteVector(v) { if (v === null || v === void 0) { return 0; } this.startVector(1, v.length, 1); this.bb.setPosition(this.space -= v.length); this.bb.bytes().set(v, this.space); return this.endVector(); } /** * A helper function to pack an object * * @returns offset of obj */ createObjectOffset(obj) { if (obj === null) { return 0; } if (typeof obj === "string") { return this.createString(obj); } else { return obj.pack(this); } } /** * A helper function to pack a list of object * * @returns list of offsets of each non null object */ createObjectOffsetList(list) { const ret = []; for (let i = 0; i < list.length; ++i) { const val = list[i]; if (val !== null) { ret.push(this.createObjectOffset(val)); } else { throw new TypeError("FlatBuffers: Argument for createObjectOffsetList cannot contain null."); } } return ret; } createStructOffsetList(list, startFunc) { startFunc(this, list.length); this.createObjectOffsetList(list.slice().reverse()); return this.endVector(); } }; exports2.Builder = Builder; } }); // web/node_modules/flatbuffers/js/flatbuffers.js var require_flatbuffers = __commonJS({ "web/node_modules/flatbuffers/js/flatbuffers.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.ByteBuffer = exports2.Builder = exports2.Encoding = exports2.isLittleEndian = exports2.float64 = exports2.float32 = exports2.int32 = exports2.SIZE_PREFIX_LENGTH = exports2.FILE_IDENTIFIER_LENGTH = exports2.SIZEOF_INT = exports2.SIZEOF_SHORT = void 0; var constants_js_1 = require_constants(); Object.defineProperty(exports2, "SIZEOF_SHORT", { enumerable: true, get: function() { return constants_js_1.SIZEOF_SHORT; } }); var constants_js_2 = require_constants(); Object.defineProperty(exports2, "SIZEOF_INT", { enumerable: true, get: function() { return constants_js_2.SIZEOF_INT; } }); var constants_js_3 = require_constants(); Object.defineProperty(exports2, "FILE_IDENTIFIER_LENGTH", { enumerable: true, get: function() { return constants_js_3.FILE_IDENTIFIER_LENGTH; } }); var constants_js_4 = require_constants(); Object.defineProperty(exports2, "SIZE_PREFIX_LENGTH", { enumerable: true, get: function() { return constants_js_4.SIZE_PREFIX_LENGTH; } }); var utils_js_1 = require_utils(); Object.defineProperty(exports2, "int32", { enumerable: true, get: function() { return utils_js_1.int32; } }); Object.defineProperty(exports2, "float32", { enumerable: true, get: function() { return utils_js_1.float32; } }); Object.defineProperty(exports2, "float64", { enumerable: true, get: function() { return utils_js_1.float64; } }); Object.defineProperty(exports2, "isLittleEndian", { enumerable: true, get: function() { return utils_js_1.isLittleEndian; } }); var encoding_js_1 = require_encoding(); Object.defineProperty(exports2, "Encoding", { enumerable: true, get: function() { return encoding_js_1.Encoding; } }); var builder_js_1 = require_builder(); Object.defineProperty(exports2, "Builder", { enumerable: true, get: function() { return builder_js_1.Builder; } }); var byte_buffer_js_1 = require_byte_buffer(); Object.defineProperty(exports2, "ByteBuffer", { enumerable: true, get: function() { return byte_buffer_js_1.ByteBuffer; } }); } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/arg-type-and-index.js var require_arg_type_and_index = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/arg-type-and-index.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.ArgTypeAndIndex = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var arg_type_js_1 = require_arg_type(); var ArgTypeAndIndex2 = class _ArgTypeAndIndex { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsArgTypeAndIndex(bb, obj) { return (obj || new _ArgTypeAndIndex()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsArgTypeAndIndex(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _ArgTypeAndIndex()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } argType() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readInt8(this.bb_pos + offset) : arg_type_js_1.ArgType.INPUT; } index() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } static startArgTypeAndIndex(builder) { builder.startObject(2); } static addArgType(builder, argType) { builder.addFieldInt8(0, argType, arg_type_js_1.ArgType.INPUT); } static addIndex(builder, index) { builder.addFieldInt32(1, index, 0); } static endArgTypeAndIndex(builder) { const offset = builder.endObject(); return offset; } static createArgTypeAndIndex(builder, argType, index) { _ArgTypeAndIndex.startArgTypeAndIndex(builder); _ArgTypeAndIndex.addArgType(builder, argType); _ArgTypeAndIndex.addIndex(builder, index); return _ArgTypeAndIndex.endArgTypeAndIndex(builder); } }; exports2.ArgTypeAndIndex = ArgTypeAndIndex2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/attribute-type.js var require_attribute_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/attribute-type.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.AttributeType = void 0; var AttributeType2; (function(AttributeType3) { AttributeType3[AttributeType3["UNDEFINED"] = 0] = "UNDEFINED"; AttributeType3[AttributeType3["FLOAT"] = 1] = "FLOAT"; AttributeType3[AttributeType3["INT"] = 2] = "INT"; AttributeType3[AttributeType3["STRING"] = 3] = "STRING"; AttributeType3[AttributeType3["TENSOR"] = 4] = "TENSOR"; AttributeType3[AttributeType3["GRAPH"] = 5] = "GRAPH"; AttributeType3[AttributeType3["FLOATS"] = 6] = "FLOATS"; AttributeType3[AttributeType3["INTS"] = 7] = "INTS"; AttributeType3[AttributeType3["STRINGS"] = 8] = "STRINGS"; AttributeType3[AttributeType3["TENSORS"] = 9] = "TENSORS"; AttributeType3[AttributeType3["GRAPHS"] = 10] = "GRAPHS"; AttributeType3[AttributeType3["SPARSE_TENSOR"] = 11] = "SPARSE_TENSOR"; AttributeType3[AttributeType3["SPARSE_TENSORS"] = 12] = "SPARSE_TENSORS"; })(AttributeType2 || (exports2.AttributeType = AttributeType2 = {})); } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node-type.js var require_node_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node-type.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.NodeType = void 0; var NodeType2; (function(NodeType3) { NodeType3[NodeType3["Primitive"] = 0] = "Primitive"; NodeType3[NodeType3["Fused"] = 1] = "Fused"; })(NodeType2 || (exports2.NodeType = NodeType2 = {})); } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node.js var require_node = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Node = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var attribute_js_1 = require_attribute(); var node_type_js_1 = require_node_type(); var Node3 = class _Node { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsNode(bb, obj) { return (obj || new _Node()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsNode(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Node()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } name(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } docString(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } domain(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } sinceVersion() { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.readInt32(this.bb_pos + offset) : 0; } index() { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } opType(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } type() { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? this.bb.readInt32(this.bb_pos + offset) : node_type_js_1.NodeType.Primitive; } executionProviderType(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 18); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } inputs(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } inputsLength() { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } outputs(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 22); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } outputsLength() { const offset = this.bb.__offset(this.bb_pos, 22); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } attributes(index, obj) { const offset = this.bb.__offset(this.bb_pos, 24); return offset ? (obj || new attribute_js_1.Attribute()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } attributesLength() { const offset = this.bb.__offset(this.bb_pos, 24); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } inputArgCounts(index) { const offset = this.bb.__offset(this.bb_pos, 26); return offset ? this.bb.readInt32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; } inputArgCountsLength() { const offset = this.bb.__offset(this.bb_pos, 26); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } inputArgCountsArray() { const 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) { const offset = this.bb.__offset(this.bb_pos, 28); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } implicitInputsLength() { const offset = this.bb.__offset(this.bb_pos, 28); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startNode(builder) { builder.startObject(13); } static addName(builder, nameOffset) { builder.addFieldOffset(0, nameOffset, 0); } static addDocString(builder, docStringOffset) { builder.addFieldOffset(1, docStringOffset, 0); } static addDomain(builder, domainOffset) { builder.addFieldOffset(2, domainOffset, 0); } static addSinceVersion(builder, sinceVersion) { builder.addFieldInt32(3, sinceVersion, 0); } static addIndex(builder, index) { builder.addFieldInt32(4, index, 0); } static addOpType(builder, opTypeOffset) { builder.addFieldOffset(5, opTypeOffset, 0); } static addType(builder, type) { builder.addFieldInt32(6, type, node_type_js_1.NodeType.Primitive); } static addExecutionProviderType(builder, executionProviderTypeOffset) { builder.addFieldOffset(7, executionProviderTypeOffset, 0); } static addInputs(builder, inputsOffset) { builder.addFieldOffset(8, inputsOffset, 0); } 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(); } static startInputsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addOutputs(builder, outputsOffset) { builder.addFieldOffset(9, outputsOffset, 0); } 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(); } static startOutputsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addAttributes(builder, attributesOffset) { builder.addFieldOffset(10, attributesOffset, 0); } 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(); } static startAttributesVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addInputArgCounts(builder, inputArgCountsOffset) { builder.addFieldOffset(11, inputArgCountsOffset, 0); } 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(); } static startInputArgCountsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addImplicitInputs(builder, implicitInputsOffset) { builder.addFieldOffset(12, implicitInputsOffset, 0); } 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(); } static startImplicitInputsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endNode(builder) { const offset = builder.endObject(); return offset; } static createNode(builder, nameOffset, docStringOffset, domainOffset, sinceVersion, index, opTypeOffset, type, executionProviderTypeOffset, inputsOffset, outputsOffset, attributesOffset, inputArgCountsOffset, implicitInputsOffset) { _Node.startNode(builder); _Node.addName(builder, nameOffset); _Node.addDocString(builder, docStringOffset); _Node.addDomain(builder, domainOffset); _Node.addSinceVersion(builder, sinceVersion); _Node.addIndex(builder, index); _Node.addOpType(builder, opTypeOffset); _Node.addType(builder, type); _Node.addExecutionProviderType(builder, executionProviderTypeOffset); _Node.addInputs(builder, inputsOffset); _Node.addOutputs(builder, outputsOffset); _Node.addAttributes(builder, attributesOffset); _Node.addInputArgCounts(builder, inputArgCountsOffset); _Node.addImplicitInputs(builder, implicitInputsOffset); return _Node.endNode(builder); } }; exports2.Node = Node3; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/edge-end.js var require_edge_end = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/edge-end.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.EdgeEnd = void 0; var EdgeEnd2 = class { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } nodeIndex() { return this.bb.readUint32(this.bb_pos); } srcArgIndex() { return this.bb.readInt32(this.bb_pos + 4); } dstArgIndex() { return this.bb.readInt32(this.bb_pos + 8); } static sizeOf() { return 12; } 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(); } }; exports2.EdgeEnd = EdgeEnd2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node-edge.js var require_node_edge = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node-edge.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.NodeEdge = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var edge_end_js_1 = require_edge_end(); var NodeEdge2 = class _NodeEdge { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsNodeEdge(bb, obj) { return (obj || new _NodeEdge()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsNodeEdge(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _NodeEdge()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } nodeIndex() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } inputEdges(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new edge_end_js_1.EdgeEnd()).__init(this.bb.__vector(this.bb_pos + offset) + index * 12, this.bb) : null; } inputEdgesLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } outputEdges(index, obj) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? (obj || new edge_end_js_1.EdgeEnd()).__init(this.bb.__vector(this.bb_pos + offset) + index * 12, this.bb) : null; } outputEdgesLength() { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startNodeEdge(builder) { builder.startObject(3); } static addNodeIndex(builder, nodeIndex) { builder.addFieldInt32(0, nodeIndex, 0); } static addInputEdges(builder, inputEdgesOffset) { builder.addFieldOffset(1, inputEdgesOffset, 0); } static startInputEdgesVector(builder, numElems) { builder.startVector(12, numElems, 4); } static addOutputEdges(builder, outputEdgesOffset) { builder.addFieldOffset(2, outputEdgesOffset, 0); } static startOutputEdgesVector(builder, numElems) { builder.startVector(12, numElems, 4); } static endNodeEdge(builder) { const 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); } }; exports2.NodeEdge = NodeEdge2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/nodes-to-optimize-indices.js var require_nodes_to_optimize_indices = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/nodes-to-optimize-indices.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.NodesToOptimizeIndices = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var NodesToOptimizeIndices2 = class _NodesToOptimizeIndices { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsNodesToOptimizeIndices(bb, obj) { return (obj || new _NodesToOptimizeIndices()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsNodesToOptimizeIndices(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _NodesToOptimizeIndices()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } nodeIndices(index) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readUint32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; } nodeIndicesLength() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } nodeIndicesArray() { const 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; } numInputs() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } numOutputs() { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } hasVariadicInput() { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false; } hasVariadicOutput() { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false; } numVariadicInputs() { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } numVariadicOutputs() { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } static startNodesToOptimizeIndices(builder) { builder.startObject(7); } static addNodeIndices(builder, nodeIndicesOffset) { builder.addFieldOffset(0, nodeIndicesOffset, 0); } 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(); } static startNodeIndicesVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addNumInputs(builder, numInputs) { builder.addFieldInt32(1, numInputs, 0); } static addNumOutputs(builder, numOutputs) { builder.addFieldInt32(2, numOutputs, 0); } static addHasVariadicInput(builder, hasVariadicInput) { builder.addFieldInt8(3, +hasVariadicInput, 0); } static addHasVariadicOutput(builder, hasVariadicOutput) { builder.addFieldInt8(4, +hasVariadicOutput, 0); } static addNumVariadicInputs(builder, numVariadicInputs) { builder.addFieldInt32(5, numVariadicInputs, 0); } static addNumVariadicOutputs(builder, numVariadicOutputs) { builder.addFieldInt32(6, numVariadicOutputs, 0); } static endNodesToOptimizeIndices(builder) { const offset = builder.endObject(); return offset; } static createNodesToOptimizeIndices(builder, nodeIndicesOffset, numInputs, numOutputs, hasVariadicInput, hasVariadicOutput, numVariadicInputs, numVariadicOutputs) { _NodesToOptimizeIndices.startNodesToOptimizeIndices(builder); _NodesToOptimizeIndices.addNodeIndices(builder, nodeIndicesOffset); _NodesToOptimizeIndices.addNumInputs(builder, numInputs); _NodesToOptimizeIndices.addNumOutputs(builder, numOutputs); _NodesToOptimizeIndices.addHasVariadicInput(builder, hasVariadicInput); _NodesToOptimizeIndices.addHasVariadicOutput(builder, hasVariadicOutput); _NodesToOptimizeIndices.addNumVariadicInputs(builder, numVariadicInputs); _NodesToOptimizeIndices.addNumVariadicOutputs(builder, numVariadicOutputs); return _NodesToOptimizeIndices.endNodesToOptimizeIndices(builder); } }; exports2.NodesToOptimizeIndices = NodesToOptimizeIndices2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimization-record.js var require_runtime_optimization_record = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimization-record.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.RuntimeOptimizationRecord = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var nodes_to_optimize_indices_js_1 = require_nodes_to_optimize_indices(); var RuntimeOptimizationRecord2 = class _RuntimeOptimizationRecord { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsRuntimeOptimizationRecord(bb, obj) { return (obj || new _RuntimeOptimizationRecord()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsRuntimeOptimizationRecord(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _RuntimeOptimizationRecord()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } actionId(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } nodesToOptimizeIndices(obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new nodes_to_optimize_indices_js_1.NodesToOptimizeIndices()).__init( this.bb.__indirect(this.bb_pos + offset), this.bb ) : null; } producedOpIds(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } producedOpIdsLength() { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startRuntimeOptimizationRecord(builder) { builder.startObject(4); } static addActionId(builder, actionIdOffset) { builder.addFieldOffset(0, actionIdOffset, 0); } static addNodesToOptimizeIndices(builder, nodesToOptimizeIndicesOffset) { builder.addFieldOffset(1, nodesToOptimizeIndicesOffset, 0); } static addProducedOpIds(builder, producedOpIdsOffset) { builder.addFieldOffset(3, producedOpIdsOffset, 0); } static createProducedOpIdsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startProducedOpIdsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endRuntimeOptimizationRecord(builder) { const offset = builder.endObject(); return offset; } }; exports2.RuntimeOptimizationRecord = RuntimeOptimizationRecord2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimization-record-container-entry.js var require_runtime_optimization_record_container_entry = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimization-record-container-entry.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.RuntimeOptimizationRecordContainerEntry = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var runtime_optimization_record_js_1 = require_runtime_optimization_record(); var RuntimeOptimizationRecordContainerEntry2 = class _RuntimeOptimizationRecordContainerEntry { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsRuntimeOptimizationRecordContainerEntry(bb, obj) { return (obj || new _RuntimeOptimizationRecordContainerEntry()).__init( bb.readInt32(bb.position()) + bb.position(), bb ); } static getSizePrefixedRootAsRuntimeOptimizationRecordContainerEntry(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _RuntimeOptimizationRecordContainerEntry()).__init( bb.readInt32(bb.position()) + bb.position(), bb ); } optimizerName(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } runtimeOptimizationRecords(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new runtime_optimization_record_js_1.RuntimeOptimizationRecord()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } runtimeOptimizationRecordsLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startRuntimeOptimizationRecordContainerEntry(builder) { builder.startObject(2); } static addOptimizerName(builder, optimizerNameOffset) { builder.addFieldOffset(0, optimizerNameOffset, 0); } static addRuntimeOptimizationRecords(builder, runtimeOptimizationRecordsOffset) { builder.addFieldOffset(1, runtimeOptimizationRecordsOffset, 0); } static createRuntimeOptimizationRecordsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startRuntimeOptimizationRecordsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endRuntimeOptimizationRecordContainerEntry(builder) { const offset = builder.endObject(); builder.requiredField(offset, 4); return offset; } static createRuntimeOptimizationRecordContainerEntry(builder, optimizerNameOffset, runtimeOptimizationRecordsOffset) { _RuntimeOptimizationRecordContainerEntry.startRuntimeOptimizationRecordContainerEntry(builder); _RuntimeOptimizationRecordContainerEntry.addOptimizerName(builder, optimizerNameOffset); _RuntimeOptimizationRecordContainerEntry.addRuntimeOptimizationRecords(builder, runtimeOptimizationRecordsOffset); return _RuntimeOptimizationRecordContainerEntry.endRuntimeOptimizationRecordContainerEntry(builder); } }; exports2.RuntimeOptimizationRecordContainerEntry = RuntimeOptimizationRecordContainerEntry2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimizations.js var require_runtime_optimizations = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimizations.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.RuntimeOptimizations = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var runtime_optimization_record_container_entry_js_1 = require_runtime_optimization_record_container_entry(); var RuntimeOptimizations2 = class _RuntimeOptimizations { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsRuntimeOptimizations(bb, obj) { return (obj || new _RuntimeOptimizations()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsRuntimeOptimizations(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _RuntimeOptimizations()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } /** * mapping from optimizer name to [RuntimeOptimizationRecord] */ records(index, obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new runtime_optimization_record_container_entry_js_1.RuntimeOptimizationRecordContainerEntry()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } recordsLength() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startRuntimeOptimizations(builder) { builder.startObject(1); } static addRecords(builder, recordsOffset) { builder.addFieldOffset(0, recordsOffset, 0); } static createRecordsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startRecordsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endRuntimeOptimizations(builder) { const offset = builder.endObject(); return offset; } static createRuntimeOptimizations(builder, recordsOffset) { _RuntimeOptimizations.startRuntimeOptimizations(builder); _RuntimeOptimizations.addRecords(builder, recordsOffset); return _RuntimeOptimizations.endRuntimeOptimizations(builder); } }; exports2.RuntimeOptimizations = RuntimeOptimizations2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor-data-type.js var require_tensor_data_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor-data-type.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.TensorDataType = void 0; var TensorDataType2; (function(TensorDataType3) { TensorDataType3[TensorDataType3["UNDEFINED"] = 0] = "UNDEFINED"; TensorDataType3[TensorDataType3["FLOAT"] = 1] = "FLOAT"; TensorDataType3[TensorDataType3["UINT8"] = 2] = "UINT8"; TensorDataType3[TensorDataType3["INT8"] = 3] = "INT8"; TensorDataType3[TensorDataType3["UINT16"] = 4] = "UINT16"; TensorDataType3[TensorDataType3["INT16"] = 5] = "INT16"; TensorDataType3[TensorDataType3["INT32"] = 6] = "INT32"; TensorDataType3[TensorDataType3["INT64"] = 7] = "INT64"; TensorDataType3[TensorDataType3["STRING"] = 8] = "STRING"; TensorDataType3[TensorDataType3["BOOL"] = 9] = "BOOL"; TensorDataType3[TensorDataType3["FLOAT16"] = 10] = "FLOAT16"; TensorDataType3[TensorDataType3["DOUBLE"] = 11] = "DOUBLE"; TensorDataType3[TensorDataType3["UINT32"] = 12] = "UINT32"; TensorDataType3[TensorDataType3["UINT64"] = 13] = "UINT64"; TensorDataType3[TensorDataType3["COMPLEX64"] = 14] = "COMPLEX64"; TensorDataType3[TensorDataType3["COMPLEX128"] = 15] = "COMPLEX128"; TensorDataType3[TensorDataType3["BFLOAT16"] = 16] = "BFLOAT16"; TensorDataType3[TensorDataType3["FLOAT8E4M3FN"] = 17] = "FLOAT8E4M3FN"; TensorDataType3[TensorDataType3["FLOAT8E4M3FNUZ"] = 18] = "FLOAT8E4M3FNUZ"; TensorDataType3[TensorDataType3["FLOAT8E5M2"] = 19] = "FLOAT8E5M2"; TensorDataType3[TensorDataType3["FLOAT8E5M2FNUZ"] = 20] = "FLOAT8E5M2FNUZ"; })(TensorDataType2 || (exports2.TensorDataType = TensorDataType2 = {})); } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor.js var require_tensor = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Tensor = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var tensor_data_type_js_1 = require_tensor_data_type(); var Tensor7 = class _Tensor { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsTensor(bb, obj) { return (obj || new _Tensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsTensor(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Tensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } name(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } docString(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } dims(index) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : BigInt(0); } dimsLength() { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } dataType() { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.readInt32(this.bb_pos + offset) : tensor_data_type_js_1.TensorDataType.UNDEFINED; } rawData(index) { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0; } rawDataLength() { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } rawDataArray() { const 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) { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } stringDataLength() { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } externalDataOffset() { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("-1"); } static startTensor(builder) { builder.startObject(7); } static addName(builder, nameOffset) { builder.addFieldOffset(0, nameOffset, 0); } static addDocString(builder, docStringOffset) { builder.addFieldOffset(1, docStringOffset, 0); } static addDims(builder, dimsOffset) { builder.addFieldOffset(2, dimsOffset, 0); } 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(); } static startDimsVector(builder, numElems) { builder.startVector(8, numElems, 8); } static addDataType(builder, dataType) { builder.addFieldInt32(3, dataType, tensor_data_type_js_1.TensorDataType.UNDEFINED); } static addRawData(builder, rawDataOffset) { builder.addFieldOffset(4, rawDataOffset, 0); } 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(); } static startRawDataVector(builder, numElems) { builder.startVector(1, numElems, 1); } static addStringData(builder, stringDataOffset) { builder.addFieldOffset(5, stringDataOffset, 0); } 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(); } static startStringDataVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addExternalDataOffset(builder, externalDataOffset) { builder.addFieldInt64(6, externalDataOffset, BigInt("-1")); } static endTensor(builder) { const offset = builder.endObject(); return offset; } static createTensor(builder, nameOffset, docStringOffset, dimsOffset, dataType, rawDataOffset, stringDataOffset, externalDataOffset) { _Tensor.startTensor(builder); _Tensor.addName(builder, nameOffset); _Tensor.addDocString(builder, docStringOffset); _Tensor.addDims(builder, dimsOffset); _Tensor.addDataType(builder, dataType); _Tensor.addRawData(builder, rawDataOffset); _Tensor.addStringData(builder, stringDataOffset); _Tensor.addExternalDataOffset(builder, externalDataOffset); return _Tensor.endTensor(builder); } }; exports2.Tensor = Tensor7; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/sparse-tensor.js var require_sparse_tensor = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/sparse-tensor.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.SparseTensor = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var tensor_js_1 = require_tensor(); var SparseTensor2 = class _SparseTensor { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsSparseTensor(bb, obj) { return (obj || new _SparseTensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsSparseTensor(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _SparseTensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } values(obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new tensor_js_1.Tensor()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } indices(obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new tensor_js_1.Tensor()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } dims(index) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : BigInt(0); } dimsLength() { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startSparseTensor(builder) { builder.startObject(3); } static addValues(builder, valuesOffset) { builder.addFieldOffset(0, valuesOffset, 0); } static addIndices(builder, indicesOffset) { builder.addFieldOffset(1, indicesOffset, 0); } static addDims(builder, dimsOffset) { builder.addFieldOffset(2, dimsOffset, 0); } 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(); } static startDimsVector(builder, numElems) { builder.startVector(8, numElems, 8); } static endSparseTensor(builder) { const offset = builder.endObject(); return offset; } }; exports2.SparseTensor = SparseTensor2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/map-type.js var require_map_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/map-type.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.MapType = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var tensor_data_type_js_1 = require_tensor_data_type(); var type_info_js_1 = require_type_info(); var MapType2 = class _MapType { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsMapType(bb, obj) { return (obj || new _MapType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsMapType(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _MapType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } keyType() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readInt32(this.bb_pos + offset) : tensor_data_type_js_1.TensorDataType.UNDEFINED; } valueType(obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new type_info_js_1.TypeInfo()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } static startMapType(builder) { builder.startObject(2); } static addKeyType(builder, keyType) { builder.addFieldInt32(0, keyType, tensor_data_type_js_1.TensorDataType.UNDEFINED); } static addValueType(builder, valueTypeOffset) { builder.addFieldOffset(1, valueTypeOffset, 0); } static endMapType(builder) { const offset = builder.endObject(); return offset; } }; exports2.MapType = MapType2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/sequence-type.js var require_sequence_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/sequence-type.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.SequenceType = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var type_info_js_1 = require_type_info(); var SequenceType2 = class _SequenceType { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsSequenceType(bb, obj) { return (obj || new _SequenceType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsSequenceType(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _SequenceType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } elemType(obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new type_info_js_1.TypeInfo()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } static startSequenceType(builder) { builder.startObject(1); } static addElemType(builder, elemTypeOffset) { builder.addFieldOffset(0, elemTypeOffset, 0); } static endSequenceType(builder) { const offset = builder.endObject(); return offset; } static createSequenceType(builder, elemTypeOffset) { _SequenceType.startSequenceType(builder); _SequenceType.addElemType(builder, elemTypeOffset); return _SequenceType.endSequenceType(builder); } }; exports2.SequenceType = SequenceType2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension-value-type.js var require_dimension_value_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension-value-type.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DimensionValueType = void 0; var DimensionValueType2; (function(DimensionValueType3) { DimensionValueType3[DimensionValueType3["UNKNOWN"] = 0] = "UNKNOWN"; DimensionValueType3[DimensionValueType3["VALUE"] = 1] = "VALUE"; DimensionValueType3[DimensionValueType3["PARAM"] = 2] = "PARAM"; })(DimensionValueType2 || (exports2.DimensionValueType = DimensionValueType2 = {})); } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension-value.js var require_dimension_value = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension-value.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DimensionValue = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var dimension_value_type_js_1 = require_dimension_value_type(); var DimensionValue2 = class _DimensionValue { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsDimensionValue(bb, obj) { return (obj || new _DimensionValue()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsDimensionValue(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _DimensionValue()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } dimType() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readInt8(this.bb_pos + offset) : dimension_value_type_js_1.DimensionValueType.UNKNOWN; } dimValue() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); } dimParam(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } static startDimensionValue(builder) { builder.startObject(3); } static addDimType(builder, dimType) { builder.addFieldInt8(0, dimType, dimension_value_type_js_1.DimensionValueType.UNKNOWN); } static addDimValue(builder, dimValue) { builder.addFieldInt64(1, dimValue, BigInt("0")); } static addDimParam(builder, dimParamOffset) { builder.addFieldOffset(2, dimParamOffset, 0); } static endDimensionValue(builder) { const 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); } }; exports2.DimensionValue = DimensionValue2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension.js var require_dimension = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Dimension = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var dimension_value_js_1 = require_dimension_value(); var Dimension2 = class _Dimension { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsDimension(bb, obj) { return (obj || new _Dimension()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsDimension(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Dimension()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } value(obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new dimension_value_js_1.DimensionValue()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } denotation(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } static startDimension(builder) { builder.startObject(2); } static addValue(builder, valueOffset) { builder.addFieldOffset(0, valueOffset, 0); } static addDenotation(builder, denotationOffset) { builder.addFieldOffset(1, denotationOffset, 0); } static endDimension(builder) { const 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); } }; exports2.Dimension = Dimension2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/shape.js var require_shape = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/shape.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Shape = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var dimension_js_1 = require_dimension(); var Shape2 = class _Shape { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsShape(bb, obj) { return (obj || new _Shape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsShape(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Shape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } dim(index, obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new dimension_js_1.Dimension()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } dimLength() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startShape(builder) { builder.startObject(1); } static addDim(builder, dimOffset) { builder.addFieldOffset(0, dimOffset, 0); } 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(); } static startDimVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endShape(builder) { const offset = builder.endObject(); return offset; } static createShape(builder, dimOffset) { _Shape.startShape(builder); _Shape.addDim(builder, dimOffset); return _Shape.endShape(builder); } }; exports2.Shape = Shape2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor-type-and-shape.js var require_tensor_type_and_shape = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor-type-and-shape.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.TensorTypeAndShape = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var shape_js_1 = require_shape(); var tensor_data_type_js_1 = require_tensor_data_type(); var TensorTypeAndShape2 = class _TensorTypeAndShape { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsTensorTypeAndShape(bb, obj) { return (obj || new _TensorTypeAndShape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsTensorTypeAndShape(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _TensorTypeAndShape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } elemType() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readInt32(this.bb_pos + offset) : tensor_data_type_js_1.TensorDataType.UNDEFINED; } shape(obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new shape_js_1.Shape()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } static startTensorTypeAndShape(builder) { builder.startObject(2); } static addElemType(builder, elemType) { builder.addFieldInt32(0, elemType, tensor_data_type_js_1.TensorDataType.UNDEFINED); } static addShape(builder, shapeOffset) { builder.addFieldOffset(1, shapeOffset, 0); } static endTensorTypeAndShape(builder) { const offset = builder.endObject(); return offset; } }; exports2.TensorTypeAndShape = TensorTypeAndShape2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/type-info-value.js var require_type_info_value = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/type-info-value.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.unionListToTypeInfoValue = exports2.unionToTypeInfoValue = exports2.TypeInfoValue = void 0; var map_type_js_1 = require_map_type(); var sequence_type_js_1 = require_sequence_type(); var tensor_type_and_shape_js_1 = require_tensor_type_and_shape(); var TypeInfoValue2; (function(TypeInfoValue3) { TypeInfoValue3[TypeInfoValue3["NONE"] = 0] = "NONE"; TypeInfoValue3[TypeInfoValue3["tensor_type"] = 1] = "tensor_type"; TypeInfoValue3[TypeInfoValue3["sequence_type"] = 2] = "sequence_type"; TypeInfoValue3[TypeInfoValue3["map_type"] = 3] = "map_type"; })(TypeInfoValue2 || (exports2.TypeInfoValue = TypeInfoValue2 = {})); function unionToTypeInfoValue(type, accessor) { switch (TypeInfoValue2[type]) { case "NONE": return null; case "tensor_type": return accessor(new tensor_type_and_shape_js_1.TensorTypeAndShape()); case "sequence_type": return accessor(new sequence_type_js_1.SequenceType()); case "map_type": return accessor(new map_type_js_1.MapType()); default: return null; } } exports2.unionToTypeInfoValue = unionToTypeInfoValue; function unionListToTypeInfoValue(type, accessor, index) { switch (TypeInfoValue2[type]) { case "NONE": return null; case "tensor_type": return accessor(index, new tensor_type_and_shape_js_1.TensorTypeAndShape()); case "sequence_type": return accessor(index, new sequence_type_js_1.SequenceType()); case "map_type": return accessor(index, new map_type_js_1.MapType()); default: return null; } } exports2.unionListToTypeInfoValue = unionListToTypeInfoValue; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/type-info.js var require_type_info = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/type-info.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.TypeInfo = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var type_info_value_js_1 = require_type_info_value(); var TypeInfo2 = class _TypeInfo { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsTypeInfo(bb, obj) { return (obj || new _TypeInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsTypeInfo(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _TypeInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } denotation(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } valueType() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readUint8(this.bb_pos + offset) : type_info_value_js_1.TypeInfoValue.NONE; } value(obj) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__union(obj, this.bb_pos + offset) : null; } static startTypeInfo(builder) { builder.startObject(3); } static addDenotation(builder, denotationOffset) { builder.addFieldOffset(0, denotationOffset, 0); } static addValueType(builder, valueType) { builder.addFieldInt8(1, valueType, type_info_value_js_1.TypeInfoValue.NONE); } static addValue(builder, valueOffset) { builder.addFieldOffset(2, valueOffset, 0); } static endTypeInfo(builder) { const 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); } }; exports2.TypeInfo = TypeInfo2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/value-info.js var require_value_info = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/value-info.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.ValueInfo = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var type_info_js_1 = require_type_info(); var ValueInfo2 = class _ValueInfo { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsValueInfo(bb, obj) { return (obj || new _ValueInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsValueInfo(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _ValueInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } name(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } docString(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } type(obj) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? (obj || new type_info_js_1.TypeInfo()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } static startValueInfo(builder) { builder.startObject(3); } static addName(builder, nameOffset) { builder.addFieldOffset(0, nameOffset, 0); } static addDocString(builder, docStringOffset) { builder.addFieldOffset(1, docStringOffset, 0); } static addType(builder, typeOffset) { builder.addFieldOffset(2, typeOffset, 0); } static endValueInfo(builder) { const offset = builder.endObject(); return offset; } }; exports2.ValueInfo = ValueInfo2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/graph.js var require_graph = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/graph.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Graph = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var node_js_1 = require_node(); var node_edge_js_1 = require_node_edge(); var runtime_optimizations_js_1 = require_runtime_optimizations(); var sparse_tensor_js_1 = require_sparse_tensor(); var tensor_js_1 = require_tensor(); var value_info_js_1 = require_value_info(); var Graph3 = class _Graph { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsGraph(bb, obj) { return (obj || new _Graph()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsGraph(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Graph()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } initializers(index, obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new tensor_js_1.Tensor()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } initializersLength() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } nodeArgs(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new value_info_js_1.ValueInfo()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } nodeArgsLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } nodes(index, obj) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? (obj || new node_js_1.Node()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } nodesLength() { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } maxNodeIndex() { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } nodeEdges(index, obj) { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? (obj || new node_edge_js_1.NodeEdge()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } nodeEdgesLength() { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } inputs(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } inputsLength() { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } outputs(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } outputsLength() { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } sparseInitializers(index, obj) { const offset = this.bb.__offset(this.bb_pos, 18); return offset ? (obj || new sparse_tensor_js_1.SparseTensor()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } sparseInitializersLength() { const offset = this.bb.__offset(this.bb_pos, 18); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } runtimeOptimizations(obj) { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? (obj || new runtime_optimizations_js_1.RuntimeOptimizations()).__init( this.bb.__indirect(this.bb_pos + offset), this.bb ) : null; } static startGraph(builder) { builder.startObject(9); } static addInitializers(builder, initializersOffset) { builder.addFieldOffset(0, initializersOffset, 0); } 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(); } static startInitializersVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addNodeArgs(builder, nodeArgsOffset) { builder.addFieldOffset(1, nodeArgsOffset, 0); } 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(); } static startNodeArgsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addNodes(builder, nodesOffset) { builder.addFieldOffset(2, nodesOffset, 0); } 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(); } static startNodesVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addMaxNodeIndex(builder, maxNodeIndex) { builder.addFieldInt32(3, maxNodeIndex, 0); } static addNodeEdges(builder, nodeEdgesOffset) { builder.addFieldOffset(4, nodeEdgesOffset, 0); } 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(); } static startNodeEdgesVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addInputs(builder, inputsOffset) { builder.addFieldOffset(5, inputsOffset, 0); } 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(); } static startInputsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addOutputs(builder, outputsOffset) { builder.addFieldOffset(6, outputsOffset, 0); } 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(); } static startOutputsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addSparseInitializers(builder, sparseInitializersOffset) { builder.addFieldOffset(7, sparseInitializersOffset, 0); } 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(); } static startSparseInitializersVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addRuntimeOptimizations(builder, runtimeOptimizationsOffset) { builder.addFieldOffset(8, runtimeOptimizationsOffset, 0); } static endGraph(builder) { const offset = builder.endObject(); return offset; } }; exports2.Graph = Graph3; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/attribute.js var require_attribute = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/attribute.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Attribute = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var attribute_type_js_1 = require_attribute_type(); var graph_js_1 = require_graph(); var tensor_js_1 = require_tensor(); var Attribute3 = class _Attribute { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsAttribute(bb, obj) { return (obj || new _Attribute()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsAttribute(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Attribute()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } name(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } docString(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } type() { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.readInt32(this.bb_pos + offset) : attribute_type_js_1.AttributeType.UNDEFINED; } f() { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.readFloat32(this.bb_pos + offset) : 0; } i() { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); } s(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } t(obj) { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? (obj || new tensor_js_1.Tensor()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } g(obj) { const offset = this.bb.__offset(this.bb_pos, 18); return offset ? (obj || new graph_js_1.Graph()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } floats(index) { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? this.bb.readFloat32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; } floatsLength() { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } floatsArray() { const 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; } ints(index) { const offset = this.bb.__offset(this.bb_pos, 22); return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : BigInt(0); } intsLength() { const offset = this.bb.__offset(this.bb_pos, 22); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } strings(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 24); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } stringsLength() { const offset = this.bb.__offset(this.bb_pos, 24); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } tensors(index, obj) { const offset = this.bb.__offset(this.bb_pos, 26); return offset ? (obj || new tensor_js_1.Tensor()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } tensorsLength() { const offset = this.bb.__offset(this.bb_pos, 26); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } graphs(index, obj) { const offset = this.bb.__offset(this.bb_pos, 28); return offset ? (obj || new graph_js_1.Graph()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } graphsLength() { const offset = this.bb.__offset(this.bb_pos, 28); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startAttribute(builder) { builder.startObject(13); } static addName(builder, nameOffset) { builder.addFieldOffset(0, nameOffset, 0); } static addDocString(builder, docStringOffset) { builder.addFieldOffset(1, docStringOffset, 0); } static addType(builder, type) { builder.addFieldInt32(2, type, attribute_type_js_1.AttributeType.UNDEFINED); } static addF(builder, f) { builder.addFieldFloat32(3, f, 0); } static addI(builder, i) { builder.addFieldInt64(4, i, BigInt("0")); } static addS(builder, sOffset) { builder.addFieldOffset(5, sOffset, 0); } static addT(builder, tOffset) { builder.addFieldOffset(6, tOffset, 0); } static addG(builder, gOffset) { builder.addFieldOffset(7, gOffset, 0); } static addFloats(builder, floatsOffset) { builder.addFieldOffset(8, floatsOffset, 0); } 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(); } static startFloatsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addInts(builder, intsOffset) { builder.addFieldOffset(9, intsOffset, 0); } 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(); } static startIntsVector(builder, numElems) { builder.startVector(8, numElems, 8); } static addStrings(builder, stringsOffset) { builder.addFieldOffset(10, stringsOffset, 0); } 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(); } static startStringsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addTensors(builder, tensorsOffset) { builder.addFieldOffset(11, tensorsOffset, 0); } 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(); } static startTensorsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addGraphs(builder, graphsOffset) { builder.addFieldOffset(12, graphsOffset, 0); } 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(); } static startGraphsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endAttribute(builder) { const offset = builder.endObject(); return offset; } }; exports2.Attribute = Attribute3; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-kernel-create-infos.js var require_deprecated_kernel_create_infos = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-kernel-create-infos.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DeprecatedKernelCreateInfos = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var DeprecatedKernelCreateInfos2 = class _DeprecatedKernelCreateInfos { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsDeprecatedKernelCreateInfos(bb, obj) { return (obj || new _DeprecatedKernelCreateInfos()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsDeprecatedKernelCreateInfos(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _DeprecatedKernelCreateInfos()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } nodeIndices(index) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readUint32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; } nodeIndicesLength() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } nodeIndicesArray() { const 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; } kernelDefHashes(index) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readUint64(this.bb.__vector(this.bb_pos + offset) + index * 8) : BigInt(0); } kernelDefHashesLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startDeprecatedKernelCreateInfos(builder) { builder.startObject(2); } static addNodeIndices(builder, nodeIndicesOffset) { builder.addFieldOffset(0, nodeIndicesOffset, 0); } 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(); } static startNodeIndicesVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addKernelDefHashes(builder, kernelDefHashesOffset) { builder.addFieldOffset(1, kernelDefHashesOffset, 0); } 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(); } static startKernelDefHashesVector(builder, numElems) { builder.startVector(8, numElems, 8); } static endDeprecatedKernelCreateInfos(builder) { const offset = builder.endObject(); return offset; } static createDeprecatedKernelCreateInfos(builder, nodeIndicesOffset, kernelDefHashesOffset) { _DeprecatedKernelCreateInfos.startDeprecatedKernelCreateInfos(builder); _DeprecatedKernelCreateInfos.addNodeIndices(builder, nodeIndicesOffset); _DeprecatedKernelCreateInfos.addKernelDefHashes(builder, kernelDefHashesOffset); return _DeprecatedKernelCreateInfos.endDeprecatedKernelCreateInfos(builder); } }; exports2.DeprecatedKernelCreateInfos = DeprecatedKernelCreateInfos2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-node-index-and-kernel-def-hash.js var require_deprecated_node_index_and_kernel_def_hash = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-node-index-and-kernel-def-hash.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DeprecatedNodeIndexAndKernelDefHash = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var DeprecatedNodeIndexAndKernelDefHash2 = class _DeprecatedNodeIndexAndKernelDefHash { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsDeprecatedNodeIndexAndKernelDefHash(bb, obj) { return (obj || new _DeprecatedNodeIndexAndKernelDefHash()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsDeprecatedNodeIndexAndKernelDefHash(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _DeprecatedNodeIndexAndKernelDefHash()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } nodeIndex() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } kernelDefHash() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readUint64(this.bb_pos + offset) : BigInt("0"); } static startDeprecatedNodeIndexAndKernelDefHash(builder) { builder.startObject(2); } static addNodeIndex(builder, nodeIndex) { builder.addFieldInt32(0, nodeIndex, 0); } static addKernelDefHash(builder, kernelDefHash) { builder.addFieldInt64(1, kernelDefHash, BigInt("0")); } static endDeprecatedNodeIndexAndKernelDefHash(builder) { const offset = builder.endObject(); return offset; } static createDeprecatedNodeIndexAndKernelDefHash(builder, nodeIndex, kernelDefHash) { _DeprecatedNodeIndexAndKernelDefHash.startDeprecatedNodeIndexAndKernelDefHash(builder); _DeprecatedNodeIndexAndKernelDefHash.addNodeIndex(builder, nodeIndex); _DeprecatedNodeIndexAndKernelDefHash.addKernelDefHash(builder, kernelDefHash); return _DeprecatedNodeIndexAndKernelDefHash.endDeprecatedNodeIndexAndKernelDefHash(builder); } }; exports2.DeprecatedNodeIndexAndKernelDefHash = DeprecatedNodeIndexAndKernelDefHash2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-sub-graph-session-state.js var require_deprecated_sub_graph_session_state = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-sub-graph-session-state.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DeprecatedSubGraphSessionState = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var deprecated_session_state_js_1 = require_deprecated_session_state(); var DeprecatedSubGraphSessionState2 = class _DeprecatedSubGraphSessionState { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsDeprecatedSubGraphSessionState(bb, obj) { return (obj || new _DeprecatedSubGraphSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsDeprecatedSubGraphSessionState(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _DeprecatedSubGraphSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } graphId(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } sessionState(obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new deprecated_session_state_js_1.DeprecatedSessionState()).__init( this.bb.__indirect(this.bb_pos + offset), this.bb ) : null; } static startDeprecatedSubGraphSessionState(builder) { builder.startObject(2); } static addGraphId(builder, graphIdOffset) { builder.addFieldOffset(0, graphIdOffset, 0); } static addSessionState(builder, sessionStateOffset) { builder.addFieldOffset(1, sessionStateOffset, 0); } static endDeprecatedSubGraphSessionState(builder) { const offset = builder.endObject(); builder.requiredField(offset, 4); return offset; } }; exports2.DeprecatedSubGraphSessionState = DeprecatedSubGraphSessionState2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-session-state.js var require_deprecated_session_state = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-session-state.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DeprecatedSessionState = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var deprecated_kernel_create_infos_js_1 = require_deprecated_kernel_create_infos(); var deprecated_sub_graph_session_state_js_1 = require_deprecated_sub_graph_session_state(); var DeprecatedSessionState2 = class _DeprecatedSessionState { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsDeprecatedSessionState(bb, obj) { return (obj || new _DeprecatedSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsDeprecatedSessionState(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _DeprecatedSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } kernels(obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new deprecated_kernel_create_infos_js_1.DeprecatedKernelCreateInfos()).__init( this.bb.__indirect(this.bb_pos + offset), this.bb ) : null; } subGraphSessionStates(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new deprecated_sub_graph_session_state_js_1.DeprecatedSubGraphSessionState()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } subGraphSessionStatesLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startDeprecatedSessionState(builder) { builder.startObject(2); } static addKernels(builder, kernelsOffset) { builder.addFieldOffset(0, kernelsOffset, 0); } static addSubGraphSessionStates(builder, subGraphSessionStatesOffset) { builder.addFieldOffset(1, subGraphSessionStatesOffset, 0); } 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(); } static startSubGraphSessionStatesVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endDeprecatedSessionState(builder) { const offset = builder.endObject(); return offset; } static createDeprecatedSessionState(builder, kernelsOffset, subGraphSessionStatesOffset) { _DeprecatedSessionState.startDeprecatedSessionState(builder); _DeprecatedSessionState.addKernels(builder, kernelsOffset); _DeprecatedSessionState.addSubGraphSessionStates(builder, subGraphSessionStatesOffset); return _DeprecatedSessionState.endDeprecatedSessionState(builder); } }; exports2.DeprecatedSessionState = DeprecatedSessionState2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/kernel-type-str-args-entry.js var require_kernel_type_str_args_entry = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/kernel-type-str-args-entry.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.KernelTypeStrArgsEntry = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var arg_type_and_index_js_1 = require_arg_type_and_index(); var KernelTypeStrArgsEntry2 = class _KernelTypeStrArgsEntry { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsKernelTypeStrArgsEntry(bb, obj) { return (obj || new _KernelTypeStrArgsEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsKernelTypeStrArgsEntry(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _KernelTypeStrArgsEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } kernelTypeStr(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } args(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new arg_type_and_index_js_1.ArgTypeAndIndex()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } argsLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startKernelTypeStrArgsEntry(builder) { builder.startObject(2); } static addKernelTypeStr(builder, kernelTypeStrOffset) { builder.addFieldOffset(0, kernelTypeStrOffset, 0); } static addArgs(builder, argsOffset) { builder.addFieldOffset(1, argsOffset, 0); } static createArgsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startArgsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endKernelTypeStrArgsEntry(builder) { const offset = builder.endObject(); builder.requiredField(offset, 4); return offset; } static createKernelTypeStrArgsEntry(builder, kernelTypeStrOffset, argsOffset) { _KernelTypeStrArgsEntry.startKernelTypeStrArgsEntry(builder); _KernelTypeStrArgsEntry.addKernelTypeStr(builder, kernelTypeStrOffset); _KernelTypeStrArgsEntry.addArgs(builder, argsOffset); return _KernelTypeStrArgsEntry.endKernelTypeStrArgsEntry(builder); } }; exports2.KernelTypeStrArgsEntry = KernelTypeStrArgsEntry2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/op-id-kernel-type-str-args-entry.js var require_op_id_kernel_type_str_args_entry = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/op-id-kernel-type-str-args-entry.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.OpIdKernelTypeStrArgsEntry = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var kernel_type_str_args_entry_js_1 = require_kernel_type_str_args_entry(); var OpIdKernelTypeStrArgsEntry2 = class _OpIdKernelTypeStrArgsEntry { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsOpIdKernelTypeStrArgsEntry(bb, obj) { return (obj || new _OpIdKernelTypeStrArgsEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsOpIdKernelTypeStrArgsEntry(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _OpIdKernelTypeStrArgsEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } opId(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } kernelTypeStrArgs(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new kernel_type_str_args_entry_js_1.KernelTypeStrArgsEntry()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } kernelTypeStrArgsLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startOpIdKernelTypeStrArgsEntry(builder) { builder.startObject(2); } static addOpId(builder, opIdOffset) { builder.addFieldOffset(0, opIdOffset, 0); } static addKernelTypeStrArgs(builder, kernelTypeStrArgsOffset) { builder.addFieldOffset(1, kernelTypeStrArgsOffset, 0); } static createKernelTypeStrArgsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startKernelTypeStrArgsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endOpIdKernelTypeStrArgsEntry(builder) { const offset = builder.endObject(); builder.requiredField(offset, 4); return offset; } static createOpIdKernelTypeStrArgsEntry(builder, opIdOffset, kernelTypeStrArgsOffset) { _OpIdKernelTypeStrArgsEntry.startOpIdKernelTypeStrArgsEntry(builder); _OpIdKernelTypeStrArgsEntry.addOpId(builder, opIdOffset); _OpIdKernelTypeStrArgsEntry.addKernelTypeStrArgs(builder, kernelTypeStrArgsOffset); return _OpIdKernelTypeStrArgsEntry.endOpIdKernelTypeStrArgsEntry(builder); } }; exports2.OpIdKernelTypeStrArgsEntry = OpIdKernelTypeStrArgsEntry2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/kernel-type-str-resolver.js var require_kernel_type_str_resolver = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/kernel-type-str-resolver.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.KernelTypeStrResolver = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var op_id_kernel_type_str_args_entry_js_1 = require_op_id_kernel_type_str_args_entry(); var KernelTypeStrResolver2 = class _KernelTypeStrResolver { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsKernelTypeStrResolver(bb, obj) { return (obj || new _KernelTypeStrResolver()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsKernelTypeStrResolver(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _KernelTypeStrResolver()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } opKernelTypeStrArgs(index, obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new op_id_kernel_type_str_args_entry_js_1.OpIdKernelTypeStrArgsEntry()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } opKernelTypeStrArgsLength() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startKernelTypeStrResolver(builder) { builder.startObject(1); } static addOpKernelTypeStrArgs(builder, opKernelTypeStrArgsOffset) { builder.addFieldOffset(0, opKernelTypeStrArgsOffset, 0); } static createOpKernelTypeStrArgsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startOpKernelTypeStrArgsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endKernelTypeStrResolver(builder) { const offset = builder.endObject(); return offset; } static createKernelTypeStrResolver(builder, opKernelTypeStrArgsOffset) { _KernelTypeStrResolver.startKernelTypeStrResolver(builder); _KernelTypeStrResolver.addOpKernelTypeStrArgs(builder, opKernelTypeStrArgsOffset); return _KernelTypeStrResolver.endKernelTypeStrResolver(builder); } }; exports2.KernelTypeStrResolver = KernelTypeStrResolver2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/operator-set-id.js var require_operator_set_id = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/operator-set-id.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.OperatorSetId = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var OperatorSetId2 = class _OperatorSetId { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsOperatorSetId(bb, obj) { return (obj || new _OperatorSetId()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsOperatorSetId(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _OperatorSetId()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } domain(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } version() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); } static startOperatorSetId(builder) { builder.startObject(2); } static addDomain(builder, domainOffset) { builder.addFieldOffset(0, domainOffset, 0); } static addVersion(builder, version3) { builder.addFieldInt64(1, version3, BigInt("0")); } static endOperatorSetId(builder) { const 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); } }; exports2.OperatorSetId = OperatorSetId2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/string-string-entry.js var require_string_string_entry = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/string-string-entry.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.StringStringEntry = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var StringStringEntry2 = class _StringStringEntry { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsStringStringEntry(bb, obj) { return (obj || new _StringStringEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsStringStringEntry(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _StringStringEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } key(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } value(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } static startStringStringEntry(builder) { builder.startObject(2); } static addKey(builder, keyOffset) { builder.addFieldOffset(0, keyOffset, 0); } static addValue(builder, valueOffset) { builder.addFieldOffset(1, valueOffset, 0); } static endStringStringEntry(builder) { const offset = builder.endObject(); return offset; } static createStringStringEntry(builder, keyOffset, valueOffset) { _StringStringEntry.startStringStringEntry(builder); _StringStringEntry.addKey(builder, keyOffset); _StringStringEntry.addValue(builder, valueOffset); return _StringStringEntry.endStringStringEntry(builder); } }; exports2.StringStringEntry = StringStringEntry2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/model.js var require_model = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/model.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Model = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var graph_js_1 = require_graph(); var operator_set_id_js_1 = require_operator_set_id(); var string_string_entry_js_1 = require_string_string_entry(); var Model3 = class _Model { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsModel(bb, obj) { return (obj || new _Model()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsModel(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Model()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } irVersion() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); } opsetImport(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new operator_set_id_js_1.OperatorSetId()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } opsetImportLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } producerName(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } producerVersion(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } domain(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } modelVersion() { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); } docString(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } graph(obj) { const offset = this.bb.__offset(this.bb_pos, 18); return offset ? (obj || new graph_js_1.Graph()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } graphDocString(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } metadataProps(index, obj) { const offset = this.bb.__offset(this.bb_pos, 22); return offset ? (obj || new string_string_entry_js_1.StringStringEntry()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } metadataPropsLength() { const offset = this.bb.__offset(this.bb_pos, 22); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startModel(builder) { builder.startObject(10); } static addIrVersion(builder, irVersion) { builder.addFieldInt64(0, irVersion, BigInt("0")); } static addOpsetImport(builder, opsetImportOffset) { builder.addFieldOffset(1, opsetImportOffset, 0); } 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(); } static startOpsetImportVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addProducerName(builder, producerNameOffset) { builder.addFieldOffset(2, producerNameOffset, 0); } static addProducerVersion(builder, producerVersionOffset) { builder.addFieldOffset(3, producerVersionOffset, 0); } static addDomain(builder, domainOffset) { builder.addFieldOffset(4, domainOffset, 0); } static addModelVersion(builder, modelVersion) { builder.addFieldInt64(5, modelVersion, BigInt("0")); } static addDocString(builder, docStringOffset) { builder.addFieldOffset(6, docStringOffset, 0); } static addGraph(builder, graphOffset) { builder.addFieldOffset(7, graphOffset, 0); } static addGraphDocString(builder, graphDocStringOffset) { builder.addFieldOffset(8, graphDocStringOffset, 0); } static addMetadataProps(builder, metadataPropsOffset) { builder.addFieldOffset(9, metadataPropsOffset, 0); } static createMetadataPropsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startMetadataPropsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endModel(builder) { const offset = builder.endObject(); return offset; } }; exports2.Model = Model3; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/inference-session.js var require_inference_session = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/inference-session.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.InferenceSession = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var kernel_type_str_resolver_js_1 = require_kernel_type_str_resolver(); var model_js_1 = require_model(); var InferenceSession9 = class _InferenceSession { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsInferenceSession(bb, obj) { return (obj || new _InferenceSession()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsInferenceSession(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _InferenceSession()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static bufferHasIdentifier(bb) { return bb.__has_identifier("ORTM"); } ortVersion(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } model(obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new model_js_1.Model()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } kernelTypeStrResolver(obj) { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? (obj || new kernel_type_str_resolver_js_1.KernelTypeStrResolver()).__init( this.bb.__indirect(this.bb_pos + offset), this.bb ) : null; } static startInferenceSession(builder) { builder.startObject(4); } static addOrtVersion(builder, ortVersionOffset) { builder.addFieldOffset(0, ortVersionOffset, 0); } static addModel(builder, modelOffset) { builder.addFieldOffset(1, modelOffset, 0); } static addKernelTypeStrResolver(builder, kernelTypeStrResolverOffset) { builder.addFieldOffset(3, kernelTypeStrResolverOffset, 0); } static endInferenceSession(builder) { const offset = builder.endObject(); return offset; } static finishInferenceSessionBuffer(builder, offset) { builder.finish(offset, "ORTM"); } static finishSizePrefixedInferenceSessionBuffer(builder, offset) { builder.finish(offset, "ORTM", true); } }; exports2.InferenceSession = InferenceSession9; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs.ts var import_arg_type, import_arg_type_and_index, import_attribute, import_attribute_type, import_deprecated_kernel_create_infos, import_deprecated_node_index_and_kernel_def_hash, import_deprecated_session_state, import_deprecated_sub_graph_session_state, import_dimension, import_dimension_value, import_dimension_value_type, import_edge_end, import_graph, import_inference_session, import_kernel_type_str_args_entry, import_kernel_type_str_resolver, import_map_type, import_model, import_node, import_node_edge, import_node_type, import_nodes_to_optimize_indices, import_op_id_kernel_type_str_args_entry, import_operator_set_id, import_runtime_optimization_record, import_runtime_optimization_record_container_entry, import_runtime_optimizations, import_sequence_type, import_shape, import_sparse_tensor, import_string_string_entry, import_tensor2, import_tensor_data_type, import_tensor_type_and_shape, import_type_info, import_type_info_value, import_value_info; var init_fbs = __esm({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs.ts"() { "use strict"; import_arg_type = __toESM(require_arg_type()); import_arg_type_and_index = __toESM(require_arg_type_and_index()); import_attribute = __toESM(require_attribute()); import_attribute_type = __toESM(require_attribute_type()); import_deprecated_kernel_create_infos = __toESM(require_deprecated_kernel_create_infos()); import_deprecated_node_index_and_kernel_def_hash = __toESM(require_deprecated_node_index_and_kernel_def_hash()); import_deprecated_session_state = __toESM(require_deprecated_session_state()); import_deprecated_sub_graph_session_state = __toESM(require_deprecated_sub_graph_session_state()); import_dimension = __toESM(require_dimension()); import_dimension_value = __toESM(require_dimension_value()); import_dimension_value_type = __toESM(require_dimension_value_type()); import_edge_end = __toESM(require_edge_end()); import_graph = __toESM(require_graph()); import_inference_session = __toESM(require_inference_session()); import_kernel_type_str_args_entry = __toESM(require_kernel_type_str_args_entry()); import_kernel_type_str_resolver = __toESM(require_kernel_type_str_resolver()); import_map_type = __toESM(require_map_type()); import_model = __toESM(require_model()); import_node = __toESM(require_node()); import_node_edge = __toESM(require_node_edge()); import_node_type = __toESM(require_node_type()); import_nodes_to_optimize_indices = __toESM(require_nodes_to_optimize_indices()); import_op_id_kernel_type_str_args_entry = __toESM(require_op_id_kernel_type_str_args_entry()); import_operator_set_id = __toESM(require_operator_set_id()); import_runtime_optimization_record = __toESM(require_runtime_optimization_record()); import_runtime_optimization_record_container_entry = __toESM(require_runtime_optimization_record_container_entry()); import_runtime_optimizations = __toESM(require_runtime_optimizations()); import_sequence_type = __toESM(require_sequence_type()); import_shape = __toESM(require_shape()); import_sparse_tensor = __toESM(require_sparse_tensor()); import_string_string_entry = __toESM(require_string_string_entry()); import_tensor2 = __toESM(require_tensor()); import_tensor_data_type = __toESM(require_tensor_data_type()); import_tensor_type_and_shape = __toESM(require_tensor_type_and_shape()); import_type_info = __toESM(require_type_info()); import_type_info_value = __toESM(require_type_info_value()); import_value_info = __toESM(require_value_info()); } }); // web/lib/onnxjs/ort-schema/flatbuffers/ort-generated.ts var init_ort_generated = __esm({ "web/lib/onnxjs/ort-schema/flatbuffers/ort-generated.ts"() { "use strict"; init_fbs(); } }); // 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, slice3, 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 = slice3.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 = /* @__PURE__ */ 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; /* istanbul ignore next */ 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 Dimension2(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]]; } } Dimension2.prototype.dimValue = null; Dimension2.prototype.dimParam = null; Dimension2.prototype.denotation = ""; var $oneOfFields; Object.defineProperty(Dimension2.prototype, "value", { get: $util.oneOfGetter($oneOfFields = ["dimValue", "dimParam"]), set: $util.oneOfSetter($oneOfFields) }); Dimension2.create = function create(properties) { return new Dimension2(properties); }; Dimension2.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; }; Dimension2.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; Dimension2.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; }; Dimension2.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; Dimension2.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; }; Dimension2.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; }; Dimension2.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; }; Dimension2.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; Dimension2.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TensorShapeProto.Dimension"; }; return Dimension2; }(); 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 Tensor7(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]]; } } Tensor7.prototype.elemType = 0; Tensor7.prototype.shape = null; Tensor7.create = function create(properties) { return new Tensor7(properties); }; Tensor7.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; }; Tensor7.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; Tensor7.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; }; Tensor7.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; Tensor7.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; }; Tensor7.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; }; Tensor7.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; }; Tensor7.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; Tensor7.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TypeProto.Tensor"; }; return Tensor7; }(); 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 SparseTensor2(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]]; } } SparseTensor2.prototype.elemType = 0; SparseTensor2.prototype.shape = null; SparseTensor2.create = function create(properties) { return new SparseTensor2(properties); }; SparseTensor2.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; }; SparseTensor2.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; SparseTensor2.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; }; SparseTensor2.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; SparseTensor2.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; }; SparseTensor2.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; }; SparseTensor2.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; }; SparseTensor2.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; SparseTensor2.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TypeProto.SparseTensor"; }; return SparseTensor2; }(); 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_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 (at least 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 broadcast * @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 Tensor4(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"; // For INT64/UINT64, reduce their value to 32-bits. // Should throw exception when overflow 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 parameter to convert to a unsigned number. static longToNumber(n) { if (long_default.isLong(n)) { return n.toNumber(); } else if (typeof n === "bigint") { return Number(n); } return n; } static isLong(n) { return long_default.isLong(n) || typeof n === "bigint"; } }; 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( "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; } /** * normalize 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, pad2) { const rank = dims.length; return dims.map((v, i) => v + pad2[i] + pad2[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, split3, numOutputs) { if (split3.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, split3); } const shapes = []; const offsets = [0]; for (let i = 0; i < split3.length; ++i) { if (i !== 0) { offsets.push(offsets[i - 1] + split3[i - 1]); } const shape2 = dims.slice(); shape2[axis] = split3[i]; shapes.push(shape2); } return [shapes, offsets]; } static determineSplit(numElementsAlongAxis, numOutputs, split3) { if (numElementsAlongAxis % numOutputs !== 0) { throw new Error("cannot split tensor to equal sized parts"); } for (let i = 0; i < numOutputs; ++i) { split3.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 === import_tensor_data_type.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 === import_tensor_data_type.TensorDataType.UINT32 || type === import_onnx2.onnx.TensorProto.DataType.UINT64 || type === import_tensor_data_type.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, Tensor4; 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(); Tensor4 = 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 Tensor4( 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; // TODO: adding other activations that can be fused. 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 reduceOps2 = 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); } reduceOps2 = ` for(int j${k} = 0; j${k} < ${inputs[0].dims[k]}; j${k}++) { inputIdx[${k}] = j${k}; ${reduceOps2} }`; } 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 ${reduceOps2} ${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 Tensor4([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 split3 = node.attributes.getInts("split", []); const numOutputs = node.outputs.length; return createAttributeWithCacheKey({ axis, split: split3, 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 coordinates (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, transpose3) { let name2 = `_${varName}`; if (transpose3) { 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, transpose3) { let name2 = `_${varName}_Pack`; if (transpose3) { 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: location2, 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], location2, texturePosition); texturePosition++; break; case "float": if (arrayLength) { gl.uniform1fv(location2, value); } else { gl.uniform1f(location2, value); } break; case "int": if (arrayLength) { gl.uniform1iv(location2, value); } else { gl.uniform1i(location2, 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 { 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 init2 = backend2.initialize(); if (typeof init2 === "object" && "then" in init2) { init2 = await init2; } if (init2) { 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] && // not an initialized 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", `Running 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 { void outputTensor.data; } output.push(outputTensor); } Logger.verbose("ExecPlan", "disposing of inferenceHandler"); inferenceHandler.dispose(); return output; }); } }; } }); // web/lib/onnxjs/attribute.ts var import_onnx3, Attribute2; var init_attribute = __esm({ "web/lib/onnxjs/attribute.ts"() { "use strict"; init_ort_generated(); import_onnx3 = __toESM(require_onnx()); init_tensor2(); init_util(); Attribute2 = 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 import_attribute.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 ? Tensor4.fromProto(value) : Tensor4.fromOrtTensor(value); } if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.TENSORS) { if (attr instanceof import_onnx3.onnx.AttributeProto) { const tensorProtos = value; return tensorProtos.map((value2) => Tensor4.fromProto(value2)); } else if (attr instanceof import_attribute.Attribute) { const tensorProtos = value; return tensorProtos.map((value2) => Tensor4.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 import_attribute_type.AttributeType.FLOAT: return attr.f(); case import_attribute_type.AttributeType.INT: return attr.i(); case import_attribute_type.AttributeType.STRING: return attr.s(); case import_attribute_type.AttributeType.TENSOR: return attr.t(); case import_attribute_type.AttributeType.GRAPH: return attr.g(); case import_attribute_type.AttributeType.FLOATS: return attr.floatsArray(); case import_attribute_type.AttributeType.INTS: { const ints = []; for (let i = 0; i < attr.intsLength(); i++) { ints.push(attr.ints(i)); } return ints; } case import_attribute_type.AttributeType.STRINGS: { const strings = []; for (let i = 0; i < attr.stringsLength(); i++) { strings.push(attr.strings(i)); } return strings; } case import_attribute_type.AttributeType.TENSORS: { const tensors = []; for (let i = 0; i < attr.tensorsLength(); i++) { tensors.push(attr.tensors(i)); } return tensors; } // case ortFbs.AttributeType.GRAPHS: // TODO: Subgraph not supported yet. // const graphs = []; // for (let i = 0; i < attr.graphsLength(); i++) { // graphs.push(attr.graphs(i)!); // } // return graphs; default: throw new Error(`unsupported attribute type: ${import_attribute_type.AttributeType[attr.type()]}`); } } }; } }); // web/lib/onnxjs/graph.ts var import_onnx4, Graph2, Value, Node2, 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(); Graph2 = { /** * 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; } }; Node2 = class { constructor(_nodeProto, name2) { if (_nodeProto instanceof import_onnx4.onnx.NodeProto) { this.name = _nodeProto.name; this.opType = _nodeProto.opType; this.attributes = new Attribute2(_nodeProto.attribute); } else if (_nodeProto instanceof import_node.Node) { this.name = name2 ?? _nodeProto.name(); this.opType = _nodeProto.opType(); this.attributes = new Attribute2(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 import_graph.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 = Tensor4.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 Node2(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 = Tensor4.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 !== import_type_info_value.TypeInfoValue.tensor_type) { throw new Error("Unexpected value type for the nodeArg."); } const valueInfo = graph.nodeArgs(j).type().value(new import_tensor_type_and_shape.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 = Tensor4.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 Node2(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 = Tensor4.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 specified 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) { // TODO: add other activation methods 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 { 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 flatbuffers, import_onnx5, Model2; var init_model = __esm({ "web/lib/onnxjs/model.ts"() { "use strict"; flatbuffers = __toESM(require_flatbuffers()); init_graph(); init_ort_generated(); import_onnx5 = __toESM(require_onnx()); init_util(); Model2 = 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 = Graph2.from(modelProto.graph, graphInitializer); } loadFromOrtFormat(buf, graphInitializer) { const fb = new flatbuffers.ByteBuffer(buf); const ortModel = import_inference_session.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 = Graph2.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_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 Model2(); if (typeof arg === "string") { const isOrtFormat = arg.endsWith(".ort"); if (false) { const { readFile } = null; 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; } get inputMetadata() { throw new Error("Getting model metadata is not supported in webgl backend."); } get outputMetadata() { throw new Error("Getting model metadata is not supported in webgl backend."); } 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 Tensor4( 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/wasm/wasm-utils-env.ts var isNode; var init_wasm_utils_env = __esm({ "web/lib/wasm/wasm-utils-env.ts"() { "use strict"; isNode = false; } }); // web/lib/wasm/proxy-worker/main.ts var main_exports = {}; __export(main_exports, { default: () => main_default }); var WORKER_NAME, isProxyWorker, main_default; var init_main = __esm({ "web/lib/wasm/proxy-worker/main.ts"() { "use strict"; init_wasm_core_impl(); init_wasm_factory(); init_wasm_utils_import(); WORKER_NAME = "ort-wasm-proxy-worker"; isProxyWorker = globalThis.self?.name === WORKER_NAME; if (isProxyWorker) { self.onmessage = (ev) => { const { type, in: message } = ev.data; try { switch (type) { case "init-wasm": initializeWebAssembly(message.wasm).then( () => { initRuntime(message).then( () => { postMessage({ type }); }, (err) => { postMessage({ type, err }); } ); }, (err) => { postMessage({ type, err }); } ); break; case "init-ep": { const { epName, env: env3 } = message; initEp(env3, epName).then( () => { postMessage({ type }); }, (err) => { postMessage({ type, err }); } ); break; } case "copy-from": { const { buffer } = message; const bufferData = copyFromExternalBuffer(buffer); postMessage({ type, out: bufferData }); break; } case "create": { const { model, options } = message; createSession(model, options).then( (sessionMetadata) => { postMessage({ type, out: sessionMetadata }); }, (err) => { postMessage({ type, err }); } ); break; } case "release": releaseSession(message); postMessage({ type }); break; case "run": { const { sessionId, inputIndices, inputs, outputIndices, options } = message; run(sessionId, inputIndices, inputs, outputIndices, new Array(outputIndices.length).fill(null), options).then( (outputs) => { if (outputs.some((o) => o[3] !== "cpu")) { postMessage({ type, err: "Proxy does not support non-cpu tensor location." }); } else { postMessage( { type, out: outputs }, extractTransferableBuffers([...inputs, ...outputs]) ); } }, (err) => { postMessage({ type, err }); } ); break; } case "end-profiling": endProfiling(message); postMessage({ type }); break; default: } } catch (err) { postMessage({ type, err }); } }; } main_default = isProxyWorker ? null : (urlOverride) => new Worker(urlOverride ?? scriptSrc, { type: false ? "module" : "classic", name: WORKER_NAME }); } }); // web/lib/wasm/wasm-utils-import.ts var origin, getScriptSrc, scriptSrc, inferWasmPathPrefixFromScriptSrc, isSameOrigin, normalizeUrl, fallbackUrl, preload, dynamicImportDefault, createProxyWorker, importProxyWorker, embeddedWasmModule, importWasmModule; var init_wasm_utils_import = __esm({ "web/lib/wasm/wasm-utils-import.ts"() { "use strict"; init_wasm_utils_env(); origin = isNode || typeof location === "undefined" ? void 0 : location.origin; getScriptSrc = () => { if (isNode) { return void 0; } if (false) { if (isEsmImportMetaUrlHardcodedAsFileUri) { const URL2 = URL; return new URL(new URL2("ort.all.js", void 0).href, origin).href; } return void 0; } return typeof document !== "undefined" ? document.currentScript?.src : ( // use `self.location.href` if available typeof self !== "undefined" ? self.location?.href : void 0 ); }; scriptSrc = getScriptSrc(); inferWasmPathPrefixFromScriptSrc = () => { if (scriptSrc && !scriptSrc.startsWith("blob:")) { return scriptSrc.substring(0, scriptSrc.lastIndexOf("/") + 1); } return void 0; }; isSameOrigin = (filename, prefixOverride) => { try { const baseUrl = prefixOverride ?? scriptSrc; const url = baseUrl ? new URL(filename, baseUrl) : new URL(filename); return url.origin === origin; } catch { return false; } }; normalizeUrl = (filename, prefixOverride) => { const baseUrl = prefixOverride ?? scriptSrc; try { const url = baseUrl ? new URL(filename, baseUrl) : new URL(filename); return url.href; } catch { return void 0; } }; fallbackUrl = (filename, prefixOverride) => `${prefixOverride ?? "./"}${filename}`; preload = async (absoluteUrl) => { const response = await fetch(absoluteUrl, { credentials: "same-origin" }); const blob = await response.blob(); return URL.createObjectURL(blob); }; dynamicImportDefault = async (url) => (await import( /* webpackIgnore: true */ /* @vite-ignore */ url )).default; createProxyWorker = // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires false ? void 0 : (init_main(), __toCommonJS(main_exports)).default; importProxyWorker = async () => { if (!scriptSrc) { throw new Error("Failed to load proxy worker: cannot determine the script source URL."); } if (isSameOrigin(scriptSrc)) { return [void 0, createProxyWorker()]; } const url = await preload(scriptSrc); return [url, createProxyWorker(url)]; }; embeddedWasmModule = false ? ( // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires (true ? null : false ? null : false ? null : null).default ) : void 0; importWasmModule = async (urlOverride, prefixOverride, isMultiThreaded, isWasmOverridden) => { let useEmbeddedModule = embeddedWasmModule && !(urlOverride || prefixOverride); if (useEmbeddedModule) { if (!scriptSrc) { if (isWasmOverridden && !isMultiThreaded) { useEmbeddedModule = true; } else { throw new Error("cannot determine the script source URL."); } } else { useEmbeddedModule = isSameOrigin(scriptSrc) || isWasmOverridden && !isMultiThreaded; } } if (useEmbeddedModule) { return [void 0, embeddedWasmModule]; } else { const wasmModuleFilename = true ? "ort-wasm-simd-threaded.jsep.mjs" : false ? "ort-wasm-simd-threaded.jspi.mjs" : false ? "ort-wasm-simd-threaded.asyncify.mjs" : "ort-wasm-simd-threaded.mjs"; const wasmModuleUrl = urlOverride ?? normalizeUrl(wasmModuleFilename, prefixOverride); const needPreload = !isNode && isMultiThreaded && wasmModuleUrl && !isSameOrigin(wasmModuleUrl, prefixOverride); const url = needPreload ? await preload(wasmModuleUrl) : wasmModuleUrl ?? fallbackUrl(wasmModuleFilename, prefixOverride); return [needPreload ? url : void 0, await dynamicImportDefault(url)]; } }; } }); // web/lib/wasm/wasm-factory.ts var wasm2, initialized, initializing, aborted, isMultiThreadSupported, isSimdSupported, isRelaxedSimdSupported, initializeWebAssembly, getInstance; var init_wasm_factory = __esm({ "web/lib/wasm/wasm-factory.ts"() { "use strict"; init_wasm_utils_import(); initialized = false; initializing = false; aborted = false; isMultiThreadSupported = () => { if (typeof SharedArrayBuffer === "undefined") { return false; } try { if (typeof MessageChannel !== "undefined") { new MessageChannel().port1.postMessage(new SharedArrayBuffer(1)); } return WebAssembly.validate( new Uint8Array([ 0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 5, 4, 1, 3, 1, 1, 10, 11, 1, 9, 0, 65, 0, 254, 16, 2, 0, 26, 11 ]) ); } catch { return false; } }; isSimdSupported = () => { try { return WebAssembly.validate( new Uint8Array([ 0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 10, 30, 1, 28, 0, 65, 0, 253, 15, 253, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 186, 1, 26, 11 ]) ); } catch { return false; } }; isRelaxedSimdSupported = () => { try { return WebAssembly.validate( new Uint8Array([ 0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 96, 0, 1, 123, 3, 2, 1, 0, 10, 19, 1, 17, 0, 65, 1, 253, 15, 65, 2, 253, 15, 65, 3, 253, 15, 253, 147, 2, 11 ]) ); } catch { return false; } }; initializeWebAssembly = async (flags) => { if (initialized) { return Promise.resolve(); } if (initializing) { throw new Error("multiple calls to 'initializeWebAssembly()' detected."); } if (aborted) { throw new Error("previous call to 'initializeWebAssembly()' failed."); } initializing = true; const timeout = flags.initTimeout; let numThreads = flags.numThreads; if (flags.simd === false) { } else if (flags.simd === "relaxed") { if (!isRelaxedSimdSupported()) { throw new Error("Relaxed WebAssembly SIMD is not supported in the current environment."); } } else if (!isSimdSupported()) { throw new Error("WebAssembly SIMD is not supported in the current environment."); } if (false) { if (!("Suspending" in WebAssembly)) { throw new Error("WebAssembly JSPI is not supported in the current environment."); } } const multiThreadSupported = isMultiThreadSupported(); if (numThreads > 1 && !multiThreadSupported) { if (typeof self !== "undefined" && !self.crossOriginIsolated) { console.warn( "env.wasm.numThreads is set to " + numThreads + ", but this will not work unless you enable crossOriginIsolated mode. See https://web.dev/cross-origin-isolation-guide/ for more info." ); } console.warn( "WebAssembly multi-threading is not supported in the current environment. Falling back to single-threading." ); flags.numThreads = numThreads = 1; } const wasmPaths = flags.wasmPaths; const wasmPrefixOverride = typeof wasmPaths === "string" ? wasmPaths : void 0; const mjsPathOverrideFlag = wasmPaths?.mjs; const mjsPathOverride = mjsPathOverrideFlag?.href ?? mjsPathOverrideFlag; const wasmPathOverrideFlag = wasmPaths?.wasm; const wasmPathOverride = wasmPathOverrideFlag?.href ?? wasmPathOverrideFlag; const wasmBinaryOverride = flags.wasmBinary; const [objectUrl, ortWasmFactory] = await importWasmModule( mjsPathOverride, wasmPrefixOverride, numThreads > 1, !!wasmBinaryOverride || !!wasmPathOverride ); let isTimeout = false; const tasks = []; if (timeout > 0) { tasks.push( new Promise((resolve) => { setTimeout(() => { isTimeout = true; resolve(); }, timeout); }) ); } tasks.push( new Promise((resolve, reject) => { const config = { /** * The number of threads. WebAssembly will create (Module.numThreads - 1) workers. If it is 1, no worker will be * created. */ numThreads }; if (wasmBinaryOverride) { config.wasmBinary = wasmBinaryOverride; config.locateFile = (fileName) => fileName; } else if (wasmPathOverride || wasmPrefixOverride) { config.locateFile = (fileName) => wasmPathOverride ?? wasmPrefixOverride + fileName; } else if (mjsPathOverride && mjsPathOverride.indexOf("blob:") !== 0) { config.locateFile = (fileName) => new URL(fileName, mjsPathOverride).href; } else if (objectUrl) { const inferredWasmPathPrefix = inferWasmPathPrefixFromScriptSrc(); if (inferredWasmPathPrefix) { config.locateFile = (fileName) => inferredWasmPathPrefix + fileName; } } ortWasmFactory(config).then( // wasm module initialized successfully (module2) => { initializing = false; initialized = true; wasm2 = module2; resolve(); if (objectUrl) { URL.revokeObjectURL(objectUrl); } }, // wasm module failed to initialize (what) => { initializing = false; aborted = true; reject(what); } ); }) ); await Promise.race(tasks); if (isTimeout) { throw new Error(`WebAssembly backend initializing failed due to timeout: ${timeout}ms`); } }; getInstance = () => { if (initialized && wasm2) { return wasm2; } throw new Error("WebAssembly is not initialized yet."); }; } }); // web/lib/wasm/wasm-utils.ts var allocWasmString, iterateExtraOptions, checkLastError; var init_wasm_utils = __esm({ "web/lib/wasm/wasm-utils.ts"() { "use strict"; init_wasm_factory(); allocWasmString = (data, allocs) => { const wasm3 = getInstance(); const dataLength = wasm3.lengthBytesUTF8(data) + 1; const dataOffset = wasm3._malloc(dataLength); wasm3.stringToUTF8(data, dataOffset, dataLength); allocs.push(dataOffset); return dataOffset; }; iterateExtraOptions = (options, prefix, seen, handler) => { if (typeof options == "object" && options !== null) { if (seen.has(options)) { throw new Error("Circular reference in options"); } else { seen.add(options); } } Object.entries(options).forEach(([key, value]) => { const name2 = prefix ? prefix + key : key; if (typeof value === "object") { iterateExtraOptions(value, name2 + ".", seen, handler); } else if (typeof value === "string" || typeof value === "number") { handler(name2, value.toString()); } else if (typeof value === "boolean") { handler(name2, value ? "1" : "0"); } else { throw new Error(`Can't handle extra config type: ${typeof value}`); } }); }; checkLastError = (message) => { const wasm3 = getInstance(); const stack = wasm3.stackSave(); try { const ptrSize = wasm3.PTR_SIZE; const paramsOffset = wasm3.stackAlloc(2 * ptrSize); wasm3._OrtGetLastError(paramsOffset, paramsOffset + ptrSize); const errorCode = Number(wasm3.getValue(paramsOffset, ptrSize === 4 ? "i32" : "i64")); const errorMessagePointer = wasm3.getValue(paramsOffset + ptrSize, "*"); const errorMessage = errorMessagePointer ? wasm3.UTF8ToString(errorMessagePointer) : ""; throw new Error(`${message} ERROR_CODE: ${errorCode}, ERROR_MESSAGE: ${errorMessage}`); } finally { wasm3.stackRestore(stack); } }; } }); // web/lib/wasm/run-options.ts var setRunOptions; var init_run_options = __esm({ "web/lib/wasm/run-options.ts"() { "use strict"; init_wasm_factory(); init_wasm_utils(); setRunOptions = (options) => { const wasm3 = getInstance(); let runOptionsHandle = 0; const allocs = []; const runOptions = options || {}; try { if (options?.logSeverityLevel === void 0) { runOptions.logSeverityLevel = 2; } else if (typeof options.logSeverityLevel !== "number" || !Number.isInteger(options.logSeverityLevel) || options.logSeverityLevel < 0 || options.logSeverityLevel > 4) { throw new Error(`log severity level is not valid: ${options.logSeverityLevel}`); } if (options?.logVerbosityLevel === void 0) { runOptions.logVerbosityLevel = 0; } else if (typeof options.logVerbosityLevel !== "number" || !Number.isInteger(options.logVerbosityLevel)) { throw new Error(`log verbosity level is not valid: ${options.logVerbosityLevel}`); } if (options?.terminate === void 0) { runOptions.terminate = false; } let tagDataOffset = 0; if (options?.tag !== void 0) { tagDataOffset = allocWasmString(options.tag, allocs); } runOptionsHandle = wasm3._OrtCreateRunOptions( runOptions.logSeverityLevel, runOptions.logVerbosityLevel, !!runOptions.terminate, tagDataOffset ); if (runOptionsHandle === 0) { checkLastError("Can't create run options."); } if (options?.extra !== void 0) { iterateExtraOptions(options.extra, "", /* @__PURE__ */ new WeakSet(), (key, value) => { const keyDataOffset = allocWasmString(key, allocs); const valueDataOffset = allocWasmString(value, allocs); if (wasm3._OrtAddRunConfigEntry(runOptionsHandle, keyDataOffset, valueDataOffset) !== 0) { checkLastError(`Can't set a run config entry: ${key} - ${value}.`); } }); } return [runOptionsHandle, allocs]; } catch (e) { if (runOptionsHandle !== 0) { wasm3._OrtReleaseRunOptions(runOptionsHandle); } allocs.forEach((alloc) => wasm3._free(alloc)); throw e; } }; } }); // web/lib/wasm/session-options.ts var getGraphOptimzationLevel, getExecutionMode, appendDefaultOptions, appendSessionConfig, setExecutionProviders, setSessionOptions; var init_session_options = __esm({ "web/lib/wasm/session-options.ts"() { "use strict"; init_wasm_factory(); init_wasm_utils(); getGraphOptimzationLevel = (graphOptimizationLevel) => { switch (graphOptimizationLevel) { case "disabled": return 0; case "basic": return 1; case "extended": return 2; case "layout": return 3; case "all": return 99; default: throw new Error(`unsupported graph optimization level: ${graphOptimizationLevel}`); } }; getExecutionMode = (executionMode) => { switch (executionMode) { case "sequential": return 0; case "parallel": return 1; default: throw new Error(`unsupported execution mode: ${executionMode}`); } }; appendDefaultOptions = (options) => { if (!options.extra) { options.extra = {}; } if (!options.extra.session) { options.extra.session = {}; } const session = options.extra.session; if (!session.use_ort_model_bytes_directly) { session.use_ort_model_bytes_directly = "1"; } if (options.executionProviders && options.executionProviders.some((ep) => (typeof ep === "string" ? ep : ep.name) === "webgpu")) { options.enableMemPattern = false; } }; appendSessionConfig = (sessionOptionsHandle, key, value, allocs) => { const keyDataOffset = allocWasmString(key, allocs); const valueDataOffset = allocWasmString(value, allocs); if (getInstance()._OrtAddSessionConfigEntry(sessionOptionsHandle, keyDataOffset, valueDataOffset) !== 0) { checkLastError(`Can't set a session config entry: ${key} - ${value}.`); } }; setExecutionProviders = async (sessionOptionsHandle, sessionOptions, allocs) => { const executionProviders = sessionOptions.executionProviders; for (const ep of executionProviders) { let epName = typeof ep === "string" ? ep : ep.name; const epOptions = []; switch (epName) { case "webnn": epName = "WEBNN"; appendSessionConfig(sessionOptionsHandle, "session.disable_quant_qdq", "1", allocs); appendSessionConfig(sessionOptionsHandle, "session.disable_qdq_constant_folding", "1", allocs); if (typeof ep !== "string") { const webnnOptions = ep; const deviceType = webnnOptions?.deviceType; if (deviceType) { appendSessionConfig(sessionOptionsHandle, "deviceType", deviceType, allocs); } } break; case "webgpu": if (false) { epName = "WebGPU"; let customDevice; if (typeof ep !== "string") { const webgpuOptions = ep; if (webgpuOptions.device) { if (typeof GPUDevice !== "undefined" && webgpuOptions.device instanceof GPUDevice) { customDevice = webgpuOptions.device; } else { throw new Error("Invalid GPU device set in WebGPU EP options."); } } const { enableGraphCapture } = sessionOptions; if (typeof enableGraphCapture === "boolean" && enableGraphCapture) { appendEpOption(epOptions, "enableGraphCapture", "1", allocs); } if (typeof webgpuOptions.preferredLayout === "string") { appendEpOption(epOptions, "preferredLayout", webgpuOptions.preferredLayout, allocs); } if (webgpuOptions.forceCpuNodeNames) { const names = Array.isArray(webgpuOptions.forceCpuNodeNames) ? webgpuOptions.forceCpuNodeNames : [webgpuOptions.forceCpuNodeNames]; appendEpOption(epOptions, "forceCpuNodeNames", names.join("\n"), allocs); } if (webgpuOptions.validationMode) { appendEpOption(epOptions, "validationMode", webgpuOptions.validationMode, allocs); } } const info = getInstance().webgpuRegisterDevice(customDevice); if (info) { const [deviceId, instanceHandle, deviceHandle] = info; appendEpOption(epOptions, "deviceId", deviceId.toString(), allocs); appendEpOption(epOptions, "webgpuInstance", instanceHandle.toString(), allocs); appendEpOption(epOptions, "webgpuDevice", deviceHandle.toString(), allocs); } } else { epName = "JS"; if (typeof ep !== "string") { const webgpuOptions = ep; if (webgpuOptions?.preferredLayout) { if (webgpuOptions.preferredLayout !== "NCHW" && webgpuOptions.preferredLayout !== "NHWC") { throw new Error(`preferredLayout must be either 'NCHW' or 'NHWC': ${webgpuOptions.preferredLayout}`); } appendSessionConfig(sessionOptionsHandle, "preferredLayout", webgpuOptions.preferredLayout, allocs); } } } break; case "wasm": case "cpu": continue; default: throw new Error(`not supported execution provider: ${epName}`); } const epNameDataOffset = allocWasmString(epName, allocs); const epOptionsCount = epOptions.length; let keysOffset = 0; let valuesOffset = 0; if (epOptionsCount > 0) { keysOffset = getInstance()._malloc(epOptionsCount * getInstance().PTR_SIZE); allocs.push(keysOffset); valuesOffset = getInstance()._malloc(epOptionsCount * getInstance().PTR_SIZE); allocs.push(valuesOffset); for (let i = 0; i < epOptionsCount; i++) { getInstance().setValue(keysOffset + i * getInstance().PTR_SIZE, epOptions[i][0], "*"); getInstance().setValue(valuesOffset + i * getInstance().PTR_SIZE, epOptions[i][1], "*"); } } if (await getInstance()._OrtAppendExecutionProvider( sessionOptionsHandle, epNameDataOffset, keysOffset, valuesOffset, epOptionsCount ) !== 0) { checkLastError(`Can't append execution provider: ${epName}.`); } } }; setSessionOptions = async (options) => { const wasm3 = getInstance(); let sessionOptionsHandle = 0; const allocs = []; const sessionOptions = options || {}; appendDefaultOptions(sessionOptions); try { const graphOptimizationLevel = getGraphOptimzationLevel(sessionOptions.graphOptimizationLevel ?? "all"); const executionMode = getExecutionMode(sessionOptions.executionMode ?? "sequential"); const logIdDataOffset = typeof sessionOptions.logId === "string" ? allocWasmString(sessionOptions.logId, allocs) : 0; const logSeverityLevel = sessionOptions.logSeverityLevel ?? 2; if (!Number.isInteger(logSeverityLevel) || logSeverityLevel < 0 || logSeverityLevel > 4) { throw new Error(`log severity level is not valid: ${logSeverityLevel}`); } const logVerbosityLevel = sessionOptions.logVerbosityLevel ?? 0; if (!Number.isInteger(logVerbosityLevel) || logVerbosityLevel < 0 || logVerbosityLevel > 4) { throw new Error(`log verbosity level is not valid: ${logVerbosityLevel}`); } const optimizedModelFilePathOffset = typeof sessionOptions.optimizedModelFilePath === "string" ? allocWasmString(sessionOptions.optimizedModelFilePath, allocs) : 0; sessionOptionsHandle = wasm3._OrtCreateSessionOptions( graphOptimizationLevel, !!sessionOptions.enableCpuMemArena, !!sessionOptions.enableMemPattern, executionMode, !!sessionOptions.enableProfiling, 0, logIdDataOffset, logSeverityLevel, logVerbosityLevel, optimizedModelFilePathOffset ); if (sessionOptionsHandle === 0) { checkLastError("Can't create session options."); } if (sessionOptions.executionProviders) { await setExecutionProviders(sessionOptionsHandle, sessionOptions, allocs); } if (sessionOptions.enableGraphCapture !== void 0) { if (typeof sessionOptions.enableGraphCapture !== "boolean") { throw new Error(`enableGraphCapture must be a boolean value: ${sessionOptions.enableGraphCapture}`); } appendSessionConfig( sessionOptionsHandle, "enableGraphCapture", sessionOptions.enableGraphCapture.toString(), allocs ); } if (sessionOptions.freeDimensionOverrides) { for (const [name2, value] of Object.entries(sessionOptions.freeDimensionOverrides)) { if (typeof name2 !== "string") { throw new Error(`free dimension override name must be a string: ${name2}`); } if (typeof value !== "number" || !Number.isInteger(value) || value < 0) { throw new Error(`free dimension override value must be a non-negative integer: ${value}`); } const nameOffset = allocWasmString(name2, allocs); if (wasm3._OrtAddFreeDimensionOverride(sessionOptionsHandle, nameOffset, value) !== 0) { checkLastError(`Can't set a free dimension override: ${name2} - ${value}.`); } } } if (sessionOptions.extra !== void 0) { iterateExtraOptions(sessionOptions.extra, "", /* @__PURE__ */ new WeakSet(), (key, value) => { appendSessionConfig(sessionOptionsHandle, key, value, allocs); }); } return [sessionOptionsHandle, allocs]; } catch (e) { if (sessionOptionsHandle !== 0) { if (wasm3._OrtReleaseSessionOptions(sessionOptionsHandle) !== 0) { checkLastError("Can't release session options."); } } allocs.forEach((alloc) => wasm3._free(alloc)); throw e; } }; } }); // web/lib/wasm/wasm-common.ts var tensorDataTypeStringToEnum, tensorDataTypeEnumToString, calculateTensorSizeInBytes, tensorTypeToTypedArrayConstructor, logLevelStringToEnum, isGpuBufferSupportedType, isMLTensorSupportedType, dataLocationStringToEnum; var init_wasm_common = __esm({ "web/lib/wasm/wasm-common.ts"() { "use strict"; tensorDataTypeStringToEnum = (type) => { switch (type) { case "int8": return 3 /* int8 */; case "uint8": return 2 /* uint8 */; case "bool": return 9 /* bool */; case "int16": return 5 /* int16 */; case "uint16": return 4 /* uint16 */; case "int32": return 6 /* int32 */; case "uint32": return 12 /* uint32 */; case "float16": return 10 /* float16 */; case "float32": return 1 /* float */; case "float64": return 11 /* double */; case "string": return 8 /* string */; case "int64": return 7 /* int64 */; case "uint64": return 13 /* uint64 */; case "int4": return 22 /* int4 */; case "uint4": return 21 /* uint4 */; default: throw new Error(`unsupported data type: ${type}`); } }; tensorDataTypeEnumToString = (typeProto) => { switch (typeProto) { case 3 /* int8 */: return "int8"; case 2 /* uint8 */: return "uint8"; case 9 /* bool */: return "bool"; case 5 /* int16 */: return "int16"; case 4 /* uint16 */: return "uint16"; case 6 /* int32 */: return "int32"; case 12 /* uint32 */: return "uint32"; case 10 /* float16 */: return "float16"; case 1 /* float */: return "float32"; case 11 /* double */: return "float64"; case 8 /* string */: return "string"; case 7 /* int64 */: return "int64"; case 13 /* uint64 */: return "uint64"; case 22 /* int4 */: return "int4"; case 21 /* uint4 */: return "uint4"; default: throw new Error(`unsupported data type: ${typeProto}`); } }; calculateTensorSizeInBytes = (dateType, dimsOrSize) => { const elementSize = [ -1, // undefined = 0 4, // float = 1 1, // uint8 = 2 1, // int8 = 3 2, // uint16 = 4 2, // int16 = 5 4, // int32 = 6 8, // int64 = 7 -1, // string = 8 1, // bool = 9 2, // float16 = 10 8, // double = 11 4, // uint32 = 12 8, // uint64 = 13 -1, // complex64 = 14 -1, // complex128 = 15 -1, // bfloat16 = 16 -1, // FLOAT8E4M3FN = 17 -1, // FLOAT8E4M3FNUZ = 18 -1, // FLOAT8E5M2 = 19 -1, // FLOAT8E5M2FNUZ = 20 0.5, // uint4 = 21 0.5 // int4 = 22 ][dateType]; const size = typeof dimsOrSize === "number" ? dimsOrSize : dimsOrSize.reduce((a, b) => a * b, 1); return elementSize > 0 ? Math.ceil(size * elementSize) : void 0; }; tensorTypeToTypedArrayConstructor = (type) => { switch (type) { case "float16": return typeof Float16Array !== "undefined" && Float16Array.from ? Float16Array : Uint16Array; case "float32": return Float32Array; case "uint8": return Uint8Array; case "int8": return Int8Array; case "uint16": return Uint16Array; case "int16": return Int16Array; case "int32": return Int32Array; case "bool": return Uint8Array; case "float64": return Float64Array; case "uint32": return Uint32Array; case "int64": return BigInt64Array; case "uint64": return BigUint64Array; default: throw new Error(`unsupported type: ${type}`); } }; logLevelStringToEnum = (logLevel) => { switch (logLevel) { case "verbose": return 0; case "info": return 1; case "warning": return 2; case "error": return 3; case "fatal": return 4; default: throw new Error(`unsupported logging level: ${logLevel}`); } }; isGpuBufferSupportedType = (type) => type === "float32" || type === "float16" || type === "int32" || type === "int64" || type === "uint32" || type === "uint8" || type === "bool" || type === "uint4" || type === "int4"; isMLTensorSupportedType = (type) => type === "float32" || type === "float16" || type === "int32" || type === "int64" || type === "uint32" || type === "uint64" || type === "int8" || type === "uint8" || type === "bool" || type === "uint4" || type === "int4"; dataLocationStringToEnum = (location2) => { switch (location2) { case "none": return 0; case "cpu": return 1; case "cpu-pinned": return 2; case "texture": return 3; case "gpu-buffer": return 4; case "ml-tensor": return 5; default: throw new Error(`unsupported data location: ${location2}`); } }; } }); // web/lib/wasm/wasm-utils-load-file.ts var loadFile; var init_wasm_utils_load_file = __esm({ "web/lib/wasm/wasm-utils-load-file.ts"() { "use strict"; init_wasm_utils_env(); loadFile = async (file) => { if (typeof file === "string") { if (isNode) { try { const { readFile } = __require("node:fs/promises"); return new Uint8Array(await readFile(file)); } catch (e) { if (e.code === "ERR_FS_FILE_TOO_LARGE") { const { createReadStream } = __require("node:fs"); const stream = createReadStream(file); const chunks = []; for await (const chunk of stream) { chunks.push(chunk); } return new Uint8Array(Buffer.concat(chunks)); } throw e; } } else { const response = await fetch(file); if (!response.ok) { throw new Error(`failed to load external data file: ${file}`); } const contentLengthHeader = response.headers.get("Content-Length"); const fileSize = contentLengthHeader ? parseInt(contentLengthHeader, 10) : 0; if (fileSize < 1073741824) { return new Uint8Array(await response.arrayBuffer()); } else { if (!response.body) { throw new Error(`failed to load external data file: ${file}, no response body.`); } const reader = response.body.getReader(); let buffer; try { buffer = new ArrayBuffer(fileSize); } catch (e) { if (e instanceof RangeError) { const pages = Math.ceil(fileSize / 65536); buffer = new WebAssembly.Memory({ initial: pages, maximum: pages }).buffer; } else { throw e; } } let offset = 0; while (true) { const { done, value } = await reader.read(); if (done) { break; } const chunkSize = value.byteLength; const chunk = new Uint8Array(buffer, offset, chunkSize); chunk.set(value); offset += chunkSize; } return new Uint8Array(buffer, 0, fileSize); } } } else if (file instanceof Blob) { return new Uint8Array(await file.arrayBuffer()); } else if (file instanceof Uint8Array) { return file; } else { return new Uint8Array(file); } }; } }); // web/lib/wasm/jsep/log.ts var logLevelPrefix, doLog, configLogLevel, debug, configureLogger, LOG, LOG_DEBUG; var init_log = __esm({ "web/lib/wasm/jsep/log.ts"() { "use strict"; init_wasm_common(); logLevelPrefix = ["V", "I", "W", "E", "F"]; doLog = (level, message) => { console.log(`[${logLevelPrefix[level]},${(/* @__PURE__ */ new Date()).toISOString()}]${message}`); }; configureLogger = ($configLogLevel, $debug) => { configLogLevel = $configLogLevel; debug = $debug; }; LOG = (logLevel, msg) => { const messageLevel = logLevelStringToEnum(logLevel); const configLevel = logLevelStringToEnum(configLogLevel); if (messageLevel >= configLevel) { doLog(messageLevel, typeof msg === "function" ? msg() : msg); } }; LOG_DEBUG = (...args) => { if (debug) { LOG(...args); } }; } }); // web/lib/wasm/jsep/util.ts var MatMulUtil2, BroadcastUtil2, ShapeUtil2, PoolConvUtil2, GemmUtil2, MIN_CLIP2, MAX_CLIP2; var init_util2 = __esm({ "web/lib/wasm/jsep/util.ts"() { "use strict"; MatMulUtil2 = class { /** * 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]]; } }; BroadcastUtil2 = class { /** * 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 = MatMulUtil2.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; } const max = Math.max(aLen, bLen); if (aLen && bLen) { cdims[crank - i] = Math.max(aLen, bLen); } else { if (max > 1) { return void 0; } cdims[crank - i] = 0; } } return cdims; } /** * 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; } }; ShapeUtil2 = class _ShapeUtil { /** * calculate the size (number of elements) */ static size(dims) { return _ShapeUtil.getSizeFromDimensionRange(dims, 0, dims.length); } /** * convert dims corresponding to type change to pack. ex. uint8 data to uint32 */ static convertShape(dims, size = 4) { const rank = dims.length; if (rank === 0) { return []; } const newDims = new Array(rank); let i = rank - 1; while (i >= 0) { if (dims[i] % size === 0) { newDims[i] = dims[i] / size; break; } if (size % dims[i] !== 0) { throw new Error("cannot convert shape"); } newDims[i] = 1; size /= dims[i]; i--; } for (i--; i >= 0; i--) { newDims[i] = dims[i]; } return newDims; } /** * calculate the size (number of elements) from the given 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); } /** * calculate the size (number of elements) to the given 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); } /** * calculate the size (number of elements) from and to the given axis [start, end) */ static getSizeFromDimensionRange(dims, start, end) { let size = 1; for (let i = start; i < end; i++) { if (dims[i] < 0) { throw new Error( "cannot get valid size from specified dimension range. Most likely the range contains negative values in them." ); } size *= Number(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; } /** * normalize 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 ?? axes.length)); } /** * 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, pad2) { const rank = dims.length; return dims.map((v, i) => v + pad2[i] + pad2[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]); } }; PoolConvUtil2 = 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, isChannelLast, 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 + (isChannelLast ? 1 : 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); } } }; GemmUtil2 = 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 && !BroadcastUtil2.isValidBroadcast(biasShape, [M, N])) { throw new Error("gemm: invalid bias shape for broadcast"); } return [M, N, K]; } }; MIN_CLIP2 = -34028234663852886e22; MAX_CLIP2 = 34028234663852886e22; } }); // web/lib/wasm/jsep/tensor-view.ts var createView2; var init_tensor_view = __esm({ "web/lib/wasm/jsep/tensor-view.ts"() { "use strict"; init_wasm_common(); createView2 = (dataBuffer, type) => new (tensorTypeToTypedArrayConstructor(type))(dataBuffer); } }); // web/lib/wasm/jsep/webnn/tensor-manager.ts var webnnDataTypeToSize, convertDataToInt32, convertInt32ToData, tensorGuid, createNewTensorId, webnnDataTypeToFallback, calculateByteLength, TensorWrapper, TensorIdTracker, TensorManagerImpl, createTensorManager; var init_tensor_manager = __esm({ "web/lib/wasm/jsep/webnn/tensor-manager.ts"() { "use strict"; init_wasm_common(); init_log(); webnnDataTypeToSize = /* @__PURE__ */ new Map([ ["float32", 32], ["float16", 16], ["int32", 32], ["uint32", 32], ["int64", 64], ["uint64", 64], ["int8", 8], ["uint8", 8], ["int4", 4], ["uint4", 4] ]); convertDataToInt32 = (data, dataType) => { if (dataType === "int32") { return data; } const dataTypeSize = webnnDataTypeToSize.get(dataType); if (!dataTypeSize) { throw new Error(`WebNN backend does not support data type: ${dataType}`); } const bytesPerElement = dataTypeSize / 8; if (data.byteLength % bytesPerElement !== 0) { throw new Error(`Invalid Uint8Array length - must be a multiple of ${bytesPerElement}.`); } const numElements = data.byteLength / bytesPerElement; const originalArray = new (tensorTypeToTypedArrayConstructor(dataType))(data.buffer, data.byteOffset, numElements); switch (dataType) { case "int64": case "uint64": { const int32Array = new Int32Array(numElements); for (let i = 0; i < numElements; i++) { const value = originalArray[i]; if (value > 2147483647n || value < -2147483648n) { throw new Error(`Can not convert int64 data to int32 - value out of range.`); } int32Array[i] = Number(value); } return new Uint8Array(int32Array.buffer); } case "int8": case "uint8": case "uint32": { if (dataType === "uint32") { if (originalArray.some((value) => value > 2147483647)) { throw new Error(`Can not convert uint32 data to int32 - value out of range.`); } } const int32Array = Int32Array.from(originalArray, Number); return new Uint8Array(int32Array.buffer); } default: throw new Error(`Unsupported data conversion from ${dataType} to 'int32'`); } }; convertInt32ToData = (data, dataType) => { if (dataType === "int32") { return data; } if (data.byteLength % 4 !== 0) { throw new Error("Invalid Uint8Array length - must be a multiple of 4 (int32)."); } const numElements = data.byteLength / 4; const int32Array = new Int32Array(data.buffer, data.byteOffset, numElements); switch (dataType) { case "int64": { const bigInt64Array = BigInt64Array.from(int32Array, BigInt); return new Uint8Array(bigInt64Array.buffer); } case "uint64": { if (int32Array.some((value) => value < 0)) { throw new Error("Can not convert int32 data to uin64 - negative value found."); } const bigUint64Array = BigUint64Array.from(int32Array, BigInt); return new Uint8Array(bigUint64Array.buffer); } case "int8": { if (int32Array.some((value) => value < -128 || value > 127)) { throw new Error("Can not convert int32 data to int8 - value out of range."); } const int8Array = Int8Array.from(int32Array, Number); return new Uint8Array(int8Array.buffer); } case "uint8": { if (int32Array.some((value) => value < 0 || value > 255)) { throw new Error("Can not convert int32 data to uint8 - value out of range."); } return Uint8Array.from(int32Array, Number); } case "uint32": { if (int32Array.some((value) => value < 0)) { throw new Error("Can not convert int32 data to uint32 - negative value found."); } const uint32Array = Uint32Array.from(int32Array, Number); return new Uint8Array(uint32Array.buffer); } default: throw new Error(`Unsupported data conversion from 'int32' to ${dataType}`); } }; tensorGuid = 1; createNewTensorId = () => tensorGuid++; webnnDataTypeToFallback = /* @__PURE__ */ new Map([ ["int8", "int32"], ["uint8", "int32"], ["uint32", "int32"], ["int64", "int32"] ]); calculateByteLength = (dataType, shape2) => { const dataTypeSize = webnnDataTypeToSize.get(dataType); if (!dataTypeSize) { throw new Error(`WebNN backend does not support data type: ${dataType}`); } return shape2.length > 0 ? Math.ceil(shape2.reduce((a, b) => a * b) * dataTypeSize / 8) : 0; }; TensorWrapper = class { constructor(descriptor) { // This flag is used to indicate whether the data has been converted to fallback data type. this.isDataConverted = false; const { sessionId, context, tensor, dataType, shape: shape2, fallbackDataType } = descriptor; this.sessionId = sessionId; this.mlContext = context; this.mlTensor = tensor; this.dataType = dataType; this.tensorShape = shape2; this.fallbackDataType = fallbackDataType; } get tensor() { return this.mlTensor; } get type() { return this.dataType; } get fallbackType() { return this.fallbackDataType; } get shape() { return this.tensorShape; } get byteLength() { return calculateByteLength(this.dataType, this.tensorShape); } destroy() { LOG_DEBUG("verbose", () => "[WebNN] TensorWrapper.destroy"); this.mlTensor.destroy(); } write(data) { this.mlContext.writeTensor(this.mlTensor, data); } async read(dstBuffer) { if (this.fallbackDataType) { const data = await this.mlContext.readTensor(this.mlTensor); const originalData = convertInt32ToData(new Uint8Array(data), this.dataType); if (dstBuffer) { const targetBuffer = dstBuffer instanceof ArrayBuffer ? new Uint8Array(dstBuffer) : new Uint8Array(dstBuffer.buffer, dstBuffer.byteOffset, dstBuffer.byteLength); targetBuffer.set(originalData); return void 0; } else { return originalData.buffer; } } else { return dstBuffer ? this.mlContext.readTensor(this.mlTensor, dstBuffer) : this.mlContext.readTensor(this.mlTensor); } } canReuseTensor(context, dataType, shape2) { return this.mlContext === context && this.dataType === dataType && this.tensorShape.length === shape2.length && this.tensorShape.every((v, i) => v === shape2[i]); } setIsDataConverted(isConverted) { this.isDataConverted = isConverted; } }; TensorIdTracker = class { constructor(tensorManager, wrapper) { this.tensorManager = tensorManager; this.wrapper = wrapper; } get tensorWrapper() { return this.wrapper; } releaseTensor() { if (this.tensorWrapper) { this.tensorManager.releaseTensor(this.tensorWrapper); this.wrapper = void 0; } } async ensureTensor(sessionId, dataType, shape2, copyOld) { const context = this.tensorManager.getMLContext(sessionId); const opLimits = this.tensorManager.getMLOpSupportLimits(sessionId); let fallbackDataType; if (!opLimits?.input.dataTypes.includes(dataType)) { fallbackDataType = webnnDataTypeToFallback.get(dataType); if (!fallbackDataType || opLimits?.input.dataTypes.includes(fallbackDataType)) { throw new Error(`WebNN backend does not support data type: ${dataType}`); } LOG_DEBUG( "verbose", () => `[WebNN] TensorIdTracker.ensureTensor: fallback dataType from ${dataType} to ${fallbackDataType}` ); } if (this.wrapper) { if (this.wrapper.canReuseTensor(context, dataType, shape2)) { return this.wrapper.tensor; } else { if (copyOld) { if (this.wrapper.byteLength !== calculateByteLength(dataType, shape2)) { throw new Error("Unable to copy data to tensor with different size."); } this.activeUpload = new Uint8Array(await this.wrapper.read()); } this.tensorManager.releaseTensor(this.wrapper); } } const usage = typeof MLTensorUsage == "undefined" ? void 0 : MLTensorUsage.READ | MLTensorUsage.WRITE; this.wrapper = await this.tensorManager.getCachedTensor( sessionId, dataType, shape2, usage, true, true, fallbackDataType ); if (copyOld && this.activeUpload) { this.wrapper.write(this.activeUpload); this.activeUpload = void 0; } return this.wrapper.tensor; } upload(data) { let newData = data; if (this.wrapper) { if (this.wrapper.fallbackType) { if (this.wrapper.fallbackType === "int32") { newData = convertDataToInt32(data, this.wrapper.type); this.wrapper.setIsDataConverted(true); } else { throw new Error(`Unsupported fallback data type: ${this.wrapper.fallbackType}`); } } if (data.byteLength === this.wrapper.byteLength) { this.wrapper.write(newData); return; } else { LOG_DEBUG("verbose", () => "Data size does not match tensor size. Releasing tensor."); this.releaseTensor(); } } if (this.activeUpload) { this.activeUpload.set(newData); } else { this.activeUpload = new Uint8Array(newData); } } async download(dstBuffer) { if (this.activeUpload) { const dstData = this.wrapper?.isDataConverted ? convertInt32ToData(this.activeUpload, this.wrapper?.type) : this.activeUpload; if (dstBuffer) { if (dstBuffer instanceof ArrayBuffer) { new Uint8Array(dstBuffer).set(dstData); } else { new Uint8Array(dstBuffer.buffer, dstBuffer.byteOffset, dstBuffer.byteLength).set(dstData); } return; } else { return dstData.buffer; } } if (!this.wrapper) { throw new Error("Tensor has not been created."); } if (!dstBuffer) { return this.wrapper.read(); } return this.wrapper.read(dstBuffer); } }; TensorManagerImpl = class { constructor(backend2) { this.backend = backend2; this.tensorTrackersById = /* @__PURE__ */ new Map(); this.freeTensors = []; this.externalTensors = /* @__PURE__ */ new Set(); } getMLContext(sessionId) { const context = this.backend.getMLContext(sessionId); if (!context) { throw new Error("MLContext not found for session."); } return context; } getMLOpSupportLimits(sessionId) { return this.backend.getMLOpSupportLimits(sessionId); } reserveTensorId() { const tensorId = createNewTensorId(); this.tensorTrackersById.set(tensorId, new TensorIdTracker(this)); return tensorId; } releaseTensorId(tensorId) { const tensorTracker = this.tensorTrackersById.get(tensorId); if (!tensorTracker) { return; } this.tensorTrackersById.delete(tensorId); if (tensorTracker.tensorWrapper) { this.releaseTensor(tensorTracker.tensorWrapper); } } async ensureTensor(sessionId, tensorId, dataType, shape2, copyOld) { LOG_DEBUG( "verbose", () => `[WebNN] TensorManager.ensureTensor {tensorId: ${tensorId}, dataType: ${dataType}, shape: ${shape2}, copyOld: ${copyOld}}` ); const tensor = this.tensorTrackersById.get(tensorId); if (!tensor) { throw new Error("Tensor not found."); } return tensor.ensureTensor(sessionId, dataType, shape2, copyOld); } upload(tensorId, data) { const tensor = this.tensorTrackersById.get(tensorId); if (!tensor) { throw new Error("Tensor not found."); } tensor.upload(data); } async download(tensorId, dstBuffer) { LOG_DEBUG( "verbose", () => `[WebNN] TensorManager.download {tensorId: ${tensorId}, dstBuffer: ${dstBuffer?.byteLength}}` ); const tensorTracker = this.tensorTrackersById.get(tensorId); if (!tensorTracker) { throw new Error("Tensor not found."); } return tensorTracker.download(dstBuffer); } releaseTensorsForSession(sessionId) { for (const tensor of this.freeTensors) { if (tensor.sessionId === sessionId) { tensor.destroy(); } } this.freeTensors = this.freeTensors.filter((tensor) => tensor.sessionId !== sessionId); } registerTensor(sessionId, mlTensor, dataType, shape2) { const context = this.getMLContext(sessionId); const tensorId = createNewTensorId(); const wrapper = new TensorWrapper({ sessionId, context, tensor: mlTensor, dataType, shape: shape2 }); this.tensorTrackersById.set(tensorId, new TensorIdTracker(this, wrapper)); this.externalTensors.add(wrapper); return tensorId; } /** * Get or create an MLTensor with the given data type and shape. */ async getCachedTensor(sessionId, dataType, shape2, usage, writable, readable, fallbackDataType) { const context = this.getMLContext(sessionId); for (const [index, tensor2] of this.freeTensors.entries()) { if (tensor2.canReuseTensor(context, dataType, shape2)) { LOG_DEBUG( "verbose", () => `[WebNN] Reusing tensor {dataType: ${dataType}, ${fallbackDataType ? `fallbackDataType: ${fallbackDataType},` : ""} shape: ${shape2}` ); const wrapper = this.freeTensors.splice(index, 1)[0]; wrapper.sessionId = sessionId; return wrapper; } } LOG_DEBUG( "verbose", () => `[WebNN] MLContext.createTensor {dataType: ${dataType}, ${fallbackDataType ? `fallbackDataType: ${fallbackDataType},` : ""} shape: ${shape2}}` ); const tensor = await context.createTensor({ dataType: fallbackDataType ?? dataType, // If fallback data type is provided, use it. shape: shape2, dimensions: shape2, usage, writable, readable }); return new TensorWrapper({ sessionId, context, tensor, dataType, shape: shape2, fallbackDataType }); } /** * Release tensor for reuse unless external. */ releaseTensor(tensorWrapper) { if (this.externalTensors.has(tensorWrapper)) { this.externalTensors.delete(tensorWrapper); } this.freeTensors.push(tensorWrapper); } }; createTensorManager = (...args) => new TensorManagerImpl(...args); } }); // web/lib/wasm/jsep/backend-webnn.ts var onnxDataTypeToWebnnDataType, compareMLContextOptions, WebNNBackend; var init_backend_webnn = __esm({ "web/lib/wasm/jsep/backend-webnn.ts"() { "use strict"; init_wasm_common(); init_wasm_factory(); init_tensor_view(); init_tensor_manager(); init_log(); onnxDataTypeToWebnnDataType = /* @__PURE__ */ new Map([ [1 /* float */, "float32"], [10 /* float16 */, "float16"], [6 /* int32 */, "int32"], [12 /* uint32 */, "uint32"], [7 /* int64 */, "int64"], [13 /* uint64 */, "uint64"], [22 /* int4 */, "int4"], [21 /* uint4 */, "uint4"], [3 /* int8 */, "int8"], [2 /* uint8 */, "uint8"], [9 /* bool */, "uint8"] ]); compareMLContextOptions = (a, b) => { if (a === b) { return true; } if (a === void 0 || b === void 0) { return false; } const aKeys = Object.keys(a).sort(); const bKeys = Object.keys(b).sort(); return aKeys.length === bKeys.length && aKeys.every((key, index) => key === bKeys[index] && a[key] === b[key]); }; WebNNBackend = class { constructor(env3) { /** * Tensor managers for each session. */ this.tensorManager = createTensorManager(this); /** * Maps from session id to MLContexts. */ this.mlContextBySessionId = /* @__PURE__ */ new Map(); /** * Maps from MLContext to session ids. */ this.sessionIdsByMLContext = /* @__PURE__ */ new Map(); /** * Cache of MLContexts. */ this.mlContextCache = []; /** * Maps from session id to list of graph inputs. */ this.sessionGraphInputs = /* @__PURE__ */ new Map(); /** * Maps from session id to list of graph outputs. */ this.sessionGraphOutputs = /* @__PURE__ */ new Map(); /** * Temporary graph inputs for the current session. * These inputs will be registered when the session is created. */ this.temporaryGraphInputs = []; /** * Temporary graph outputs for the current session. * These outputs will be registered when the session is created. */ this.temporaryGraphOutputs = []; /** * Temporary tensors for the current session. */ this.temporarySessionTensorIds = /* @__PURE__ */ new Map(); /** * Maps from session id to MLOpSupportLimits. */ this.mlOpSupportLimitsBySessionId = /* @__PURE__ */ new Map(); configureLogger(env3.logLevel, !!env3.debug); } get currentSessionId() { if (this.activeSessionId === void 0) { throw new Error("No active session"); } return this.activeSessionId; } onRunStart(sessionId) { LOG_DEBUG("verbose", () => `[WebNN] onRunStart {sessionId: ${sessionId}}`); this.activeSessionId = sessionId; } onRunEnd(sessionId) { LOG_DEBUG("verbose", () => `[WebNN] onRunEnd {sessionId: ${sessionId}}`); const tensorIds = this.temporarySessionTensorIds.get(sessionId); if (!tensorIds) { return; } for (const tensorId of tensorIds) { LOG_DEBUG("verbose", () => `[WebNN] releasing temporary tensor {tensorId: ${tensorId}}`); this.tensorManager.releaseTensorId(tensorId); } this.temporarySessionTensorIds.delete(sessionId); this.activeSessionId = void 0; } async createMLContext(optionsOrDevice) { if (optionsOrDevice instanceof GPUDevice) { const mlContextIndex2 = this.mlContextCache.findIndex((entry) => entry.gpuDevice === optionsOrDevice); if (mlContextIndex2 !== -1) { return this.mlContextCache[mlContextIndex2].mlContext; } else { const mlContext = await navigator.ml.createContext(optionsOrDevice); this.mlContextCache.push({ gpuDevice: optionsOrDevice, mlContext }); return mlContext; } } else if (optionsOrDevice === void 0) { const mlContextIndex2 = this.mlContextCache.findIndex( (entry) => entry.options === void 0 && entry.gpuDevice === void 0 ); if (mlContextIndex2 !== -1) { return this.mlContextCache[mlContextIndex2].mlContext; } else { const mlContext = await navigator.ml.createContext(); this.mlContextCache.push({ mlContext }); return mlContext; } } const mlContextIndex = this.mlContextCache.findIndex( (entry) => compareMLContextOptions(entry.options, optionsOrDevice) ); if (mlContextIndex !== -1) { return this.mlContextCache[mlContextIndex].mlContext; } else { const mlContext = await navigator.ml.createContext(optionsOrDevice); this.mlContextCache.push({ options: optionsOrDevice, mlContext }); return mlContext; } } registerMLContext(sessionId, mlContext) { this.mlContextBySessionId.set(sessionId, mlContext); let sessionIds = this.sessionIdsByMLContext.get(mlContext); if (!sessionIds) { sessionIds = /* @__PURE__ */ new Set(); this.sessionIdsByMLContext.set(mlContext, sessionIds); } sessionIds.add(sessionId); if (!this.mlOpSupportLimitsBySessionId.has(sessionId)) { this.mlOpSupportLimitsBySessionId.set(sessionId, mlContext.opSupportLimits()); } if (this.temporaryGraphInputs.length > 0) { this.sessionGraphInputs.set(sessionId, this.temporaryGraphInputs); this.temporaryGraphInputs = []; } if (this.temporaryGraphOutputs.length > 0) { this.sessionGraphOutputs.set(sessionId, this.temporaryGraphOutputs); this.temporaryGraphOutputs = []; } } onReleaseSession(sessionId) { this.sessionGraphInputs.delete(sessionId); this.sessionGraphOutputs.delete(sessionId); const mlContext = this.mlContextBySessionId.get(sessionId); if (!mlContext) { return; } this.tensorManager.releaseTensorsForSession(sessionId); this.mlContextBySessionId.delete(sessionId); this.mlOpSupportLimitsBySessionId.delete(sessionId); const sessionIds = this.sessionIdsByMLContext.get(mlContext); sessionIds.delete(sessionId); if (sessionIds.size === 0) { this.sessionIdsByMLContext.delete(mlContext); const mlContextIndex = this.mlContextCache.findIndex((entry) => entry.mlContext === mlContext); if (mlContextIndex !== -1) { this.mlContextCache.splice(mlContextIndex, 1); } } } getMLContext(sessionId) { return this.mlContextBySessionId.get(sessionId); } getMLOpSupportLimits(sessionId) { return this.mlOpSupportLimitsBySessionId.get(sessionId); } reserveTensorId() { return this.tensorManager.reserveTensorId(); } releaseTensorId(tensorId) { LOG_DEBUG("verbose", () => `[WebNN] releaseTensorId {tensorId: ${tensorId}}`); this.tensorManager.releaseTensorId(tensorId); } async ensureTensor(sessionId, tensorId, onnxDataType, dimensions, copyOld) { const webnnDataType = onnxDataTypeToWebnnDataType.get(onnxDataType); if (!webnnDataType) { throw new Error(`Unsupported ONNX data type: ${onnxDataType}`); } return this.tensorManager.ensureTensor( sessionId ?? this.currentSessionId, tensorId, webnnDataType, dimensions, copyOld ); } async createTemporaryTensor(sessionId, onnxDataType, shape2) { LOG_DEBUG("verbose", () => `[WebNN] createTemporaryTensor {onnxDataType: ${onnxDataType}, shape: ${shape2}}`); const dataType = onnxDataTypeToWebnnDataType.get(onnxDataType); if (!dataType) { throw new Error(`Unsupported ONNX data type: ${onnxDataType}`); } const tensorId = this.tensorManager.reserveTensorId(); await this.tensorManager.ensureTensor(sessionId, tensorId, dataType, shape2, false); const tensorIds = this.temporarySessionTensorIds.get(sessionId); if (!tensorIds) { this.temporarySessionTensorIds.set(sessionId, [tensorId]); } else { tensorIds.push(tensorId); } return tensorId; } uploadTensor(tensorId, data) { const wasm3 = getInstance(); if (!wasm3.shouldTransferToMLTensor) { throw new Error("Trying to upload to a MLTensor while shouldTransferToMLTensor is false"); } LOG_DEBUG("verbose", () => `[WebNN] uploadTensor {tensorId: ${tensorId}, data: ${data.byteLength}}`); this.tensorManager.upload(tensorId, data); } async downloadTensor(tensorId, dstBuffer) { return this.tensorManager.download(tensorId, dstBuffer); } createMLTensorDownloader(tensorId, type) { return async () => { const data = await this.tensorManager.download(tensorId); return createView2(data, type); }; } registerMLTensor(sessionId, tensor, onnxDataType, dimensions) { const webnnDataType = onnxDataTypeToWebnnDataType.get(onnxDataType); if (!webnnDataType) { throw new Error(`Unsupported ONNX data type: ${onnxDataType}`); } const id = this.tensorManager.registerTensor(sessionId, tensor, webnnDataType, dimensions); LOG_DEBUG( "verbose", () => `[WebNN] registerMLTensor {tensor: ${tensor}, dataType: ${webnnDataType}, dimensions: ${dimensions}} -> {tensorId: ${id}}` ); return id; } // Register a WebNN Constant operand from external data. registerMLConstant(externalFilePath, dataOffset, dataLength, builder, desc, mountedFiles, shouldConvertInt64ToInt32 = false) { if (!mountedFiles) { throw new Error("External mounted files are not available."); } let filePath = externalFilePath; if (externalFilePath.startsWith("./")) { filePath = externalFilePath.substring(2); } const fileData = mountedFiles.get(filePath); if (!fileData) { throw new Error(`File with name ${filePath} not found in preloaded files.`); } if (dataOffset + dataLength > fileData.byteLength) { throw new Error("Out of bounds: data offset and length exceed the external file data size."); } const buffer = fileData.slice(dataOffset, dataOffset + dataLength).buffer; let bufferView; switch (desc.dataType) { case "float32": bufferView = new Float32Array(buffer); break; case "float16": bufferView = typeof Float16Array !== "undefined" && Float16Array.from ? new Float16Array(buffer) : new Uint16Array(buffer); break; case "int32": bufferView = new Int32Array(buffer); break; case "uint32": bufferView = new Uint32Array(buffer); break; case "int64": if (shouldConvertInt64ToInt32) { const int32Buffer = convertDataToInt32(new Uint8Array(buffer), "int64"); bufferView = new Int32Array(int32Buffer.buffer); desc.dataType = "int32"; } else { bufferView = new BigInt64Array(buffer); } break; case "uint64": bufferView = new BigUint64Array(buffer); break; case "int8": bufferView = new Int8Array(buffer); break; case "int4": case "uint4": case "uint8": bufferView = new Uint8Array(buffer); break; default: throw new Error(`Unsupported data type: ${desc.dataType} in creating WebNN Constant from external data.`); } LOG_DEBUG( "verbose", () => `[WebNN] registerMLConstant {dataType: ${desc.dataType}, shape: ${desc.shape}}} ${shouldConvertInt64ToInt32 ? "(Note: it was int64 data type and registered to int32 as workaround)" : ""}` ); return builder.constant(desc, bufferView); } registerGraphInput(inputName) { this.temporaryGraphInputs.push(inputName); } registerGraphOutput(outputName) { this.temporaryGraphOutputs.push(outputName); } isGraphInput(sessionId, inputName) { const inputNames = this.sessionGraphInputs.get(sessionId); if (!inputNames) { return false; } return inputNames.includes(inputName); } isGraphOutput(sessionId, outputName) { const outputNames = this.sessionGraphOutputs.get(sessionId); if (!outputNames) { return false; } return outputNames.includes(outputName); } isGraphInputOutputTypeSupported(sessionId, type, isInput = true) { const dataType = onnxDataTypeToWebnnDataType.get(tensorDataTypeStringToEnum(type)); const opLimits = this.mlOpSupportLimitsBySessionId.get(sessionId); if (typeof dataType === "undefined") { return false; } if (isInput) { return !!opLimits?.input.dataTypes.includes(dataType); } else { return !!opLimits?.output.dataTypes.includes(dataType); } } flush() { } }; } }); // web/lib/wasm/jsep/webgpu/types.ts var init_types2 = __esm({ "web/lib/wasm/jsep/webgpu/types.ts"() { "use strict"; } }); // web/lib/wasm/jsep/webgpu/gpu-data-manager.ts var bucketFreelist, bucketArr, calcNormalizedBufferSize, calcBucketBufferSize, guid, createNewGpuDataId, downloadGpuData, GpuDataManagerImpl, createGpuDataManager; var init_gpu_data_manager = __esm({ "web/lib/wasm/jsep/webgpu/gpu-data-manager.ts"() { "use strict"; init_log(); init_types2(); bucketFreelist = /* @__PURE__ */ new Map([ [64, 250], [128, 200], [256, 200], [512, 200], [2048, 230], [4096, 200], [8192, 50], [16384, 50], [32768, 50], [65536, 50], [131072, 50], [262144, 50], [524288, 50], [1048576, 50], [2097152, 30], [4194304, 20], [8388608, 10], [12582912, 10], [16777216, 10], [26214400, 15], [33554432, 22], [44236800, 2], [58982400, 6], // we don't want to cache the bucket sizes below but not caching them // results in some major performance hits for models like sd-turbo. [67108864, 6], [134217728, 6], [167772160, 6] ]); bucketArr = []; calcNormalizedBufferSize = (size) => Math.ceil(Number(size) / 16) * 16; calcBucketBufferSize = (size) => { for (let idx = 0; idx < bucketArr.length; idx++) { const sizeForBucket = bucketArr[idx]; if (size <= sizeForBucket) { return sizeForBucket; } } return Math.ceil(size / 16) * 16; }; guid = 1; createNewGpuDataId = () => guid++; downloadGpuData = async (backend2, gpuBuffer, originalSize, getTargetBuffer) => { const bufferSize = calcNormalizedBufferSize(originalSize); const gpuReadBuffer = backend2.device.createBuffer( // eslint-disable-next-line no-bitwise { size: bufferSize, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ } ); try { const commandEncoder = backend2.getCommandEncoder(); backend2.endComputePass(); commandEncoder.copyBufferToBuffer( gpuBuffer, 0, gpuReadBuffer, 0, bufferSize ); backend2.flush(); await gpuReadBuffer.mapAsync(GPUMapMode.READ); const arrayBuffer = gpuReadBuffer.getMappedRange(); if (getTargetBuffer) { const targetBuffer = getTargetBuffer(); targetBuffer.set(new Uint8Array(arrayBuffer, 0, originalSize)); return targetBuffer; } else { return new Uint8Array(arrayBuffer.slice(0, originalSize)); } } finally { gpuReadBuffer.destroy(); } }; GpuDataManagerImpl = class { constructor(backend2) { this.backend = backend2; this.storageCache = /* @__PURE__ */ new Map(); this.freeBuffers = /* @__PURE__ */ new Map(); this.freeUniformBuffers = /* @__PURE__ */ new Map(); this.buffersPending = []; this.capturedPendingBuffers = /* @__PURE__ */ new Map(); for (const [key] of bucketFreelist) { bucketArr.push(key); this.freeBuffers.set(key, []); this.freeUniformBuffers.set(key, []); } this.sessionCount = 0; } upload(id, data) { const srcArrayBuffer = data.buffer; const srcOffset = data.byteOffset; const srcLength = data.byteLength; const size = calcNormalizedBufferSize(srcLength); const gpuDataCache = this.storageCache.get(id); if (!gpuDataCache) { throw new Error("gpu data for uploading does not exist"); } if (Number(gpuDataCache.originalSize) !== srcLength) { throw new Error(`inconsistent data size. gpu data size=${gpuDataCache.originalSize}, data size=${srcLength}`); } const gpuBufferForUploading = this.backend.device.createBuffer( // eslint-disable-next-line no-bitwise { mappedAtCreation: true, size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.COPY_SRC } ); const arrayBuffer = gpuBufferForUploading.getMappedRange(); new Uint8Array(arrayBuffer).set(new Uint8Array(srcArrayBuffer, srcOffset, srcLength)); gpuBufferForUploading.unmap(); const commandEncoder = this.backend.device.createCommandEncoder(); commandEncoder.copyBufferToBuffer(gpuBufferForUploading, 0, gpuDataCache.gpuData.buffer, 0, size); this.backend.device.queue.submit([commandEncoder.finish()]); gpuBufferForUploading.destroy(); LOG_DEBUG("verbose", () => `[WebGPU] GpuDataManager.upload(id=${id})`); } memcpy(sourceId, destinationId) { const sourceGpuDataCache = this.storageCache.get(sourceId); if (!sourceGpuDataCache) { throw new Error("source gpu data for memcpy does not exist"); } const destinationGpuDataCache = this.storageCache.get(destinationId); if (!destinationGpuDataCache) { throw new Error("destination gpu data for memcpy does not exist"); } if (sourceGpuDataCache.originalSize !== destinationGpuDataCache.originalSize) { throw new Error("inconsistent source and destination gpu data size"); } const size = calcNormalizedBufferSize(sourceGpuDataCache.originalSize); const commandEncoder = this.backend.getCommandEncoder(); this.backend.endComputePass(); commandEncoder.copyBufferToBuffer( sourceGpuDataCache.gpuData.buffer, 0, destinationGpuDataCache.gpuData.buffer, 0, size ); } registerExternalBuffer(buffer, originalSize, previous) { let id; if (previous) { id = previous[0]; if (buffer === previous[1]) { LOG_DEBUG( "verbose", () => `[WebGPU] GpuDataManager.registerExternalBuffer(size=${originalSize}) => id=${id}, buffer is the same, skip.` ); return id; } else if (this.backend.capturedCommandList.has(this.backend.currentSessionId)) { throw new Error(`Registering a different external buffer under graph capture mode is not supported yet. Please use the previous external buffer!`); } } else { id = createNewGpuDataId(); } this.storageCache.set(id, { gpuData: { id, type: 0 /* default */, buffer }, originalSize }); LOG_DEBUG( "verbose", () => `[WebGPU] GpuDataManager.registerExternalBuffer(size=${originalSize}) => id=${id}, registered.` ); return id; } unregisterExternalBuffer(id) { if (id !== void 0) { this.storageCache.delete(id); LOG_DEBUG("verbose", () => `[WebGPU] GpuDataManager.unregisterExternalBuffer() => id=${id}`); } } // eslint-disable-next-line no-bitwise create(size, usage = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST) { const bufferSize = calcBucketBufferSize(size); let gpuBuffer; const isStorage = (usage & GPUBufferUsage.STORAGE) === GPUBufferUsage.STORAGE; const isUniform = (usage & GPUBufferUsage.UNIFORM) === GPUBufferUsage.UNIFORM; if (isStorage || isUniform) { const freeBuffers = isStorage ? this.freeBuffers : this.freeUniformBuffers; const buffers = freeBuffers.get(bufferSize); if (!buffers) { gpuBuffer = this.backend.device.createBuffer({ size: bufferSize, usage }); } else { if (buffers.length > 0) { gpuBuffer = buffers.pop(); } else { gpuBuffer = this.backend.device.createBuffer({ size: bufferSize, usage }); } } } else { gpuBuffer = this.backend.device.createBuffer({ size: bufferSize, usage }); } const gpuData = { id: createNewGpuDataId(), type: 0 /* default */, buffer: gpuBuffer }; this.storageCache.set(gpuData.id, { gpuData, originalSize: Number(size) }); LOG_DEBUG("verbose", () => `[WebGPU] GpuDataManager.create(size=${size}) => id=${gpuData.id}`); return gpuData; } get(id) { return this.storageCache.get(id)?.gpuData; } release(idInput) { const id = typeof idInput === "bigint" ? Number(idInput) : idInput; const cachedData = this.storageCache.get(id); if (!cachedData) { if (this.storageCache.size === 0) { return 0; } else { throw new Error("releasing data does not exist"); } } LOG_DEBUG("verbose", () => `[WebGPU] GpuDataManager.release(id=${id}), gpuDataId=${cachedData.gpuData.id}`); this.storageCache.delete(id); this.buffersPending.push(cachedData.gpuData.buffer); return cachedData.originalSize; } async download(id, getTargetBuffer) { const cachedData = this.storageCache.get(Number(id)); if (!cachedData) { throw new Error("data does not exist"); } await downloadGpuData(this.backend, cachedData.gpuData.buffer, cachedData.originalSize, getTargetBuffer); } refreshPendingBuffers() { if (this.buffersPending.length === 0) { return; } if (this.backend.sessionStatus === "default") { for (const buffer of this.buffersPending) { const maxInFreeList = bucketFreelist.get(buffer.size); if ((buffer.usage & GPUBufferUsage.STORAGE) === GPUBufferUsage.STORAGE) { const freelist = this.freeBuffers.get(buffer.size) || []; if (maxInFreeList === void 0 || freelist.length >= maxInFreeList) { buffer.destroy(); } else { freelist.push(buffer); } } else if ((buffer.usage & GPUBufferUsage.UNIFORM) === GPUBufferUsage.UNIFORM) { const freelist = this.freeUniformBuffers.get(buffer.size) || []; if (maxInFreeList === void 0 || freelist.length >= maxInFreeList) { buffer.destroy(); } else { freelist.push(buffer); } } else { buffer.destroy(); } } this.buffersPending = []; } else { let capturedBuffers = this.capturedPendingBuffers.get(this.backend.currentSessionId); if (!capturedBuffers) { capturedBuffers = []; this.capturedPendingBuffers.set(this.backend.currentSessionId, capturedBuffers); } for (const buffer of this.buffersPending) { capturedBuffers.push(buffer); } this.buffersPending = []; } } dispose() { this.freeBuffers.forEach((buffers) => { buffers.forEach((buffer) => { buffer.destroy(); }); }); this.freeUniformBuffers.forEach((buffers) => { buffers.forEach((buffer) => { buffer.destroy(); }); }); this.storageCache.forEach((storage) => { storage.gpuData.buffer.destroy(); }); this.capturedPendingBuffers.forEach((buffers) => { buffers.forEach((buffer) => { buffer.destroy(); }); }); this.storageCache = /* @__PURE__ */ new Map(); this.freeBuffers = /* @__PURE__ */ new Map(); this.freeUniformBuffers = /* @__PURE__ */ new Map(); this.capturedPendingBuffers = /* @__PURE__ */ new Map(); } onCreateSession() { this.sessionCount += 1; } onReleaseSession(sessionId) { const pendingBuffers = this.capturedPendingBuffers.get(sessionId); if (pendingBuffers) { pendingBuffers.forEach((buffer) => { buffer.destroy(); }); this.capturedPendingBuffers.delete(sessionId); } this.sessionCount -= 1; if (this.sessionCount === 0) { LOG_DEBUG("warning", () => "[WebGPU] Clearing webgpu buffer cache"); this.storageCache.forEach((storage) => { storage.gpuData.buffer.destroy(); }); this.storageCache = /* @__PURE__ */ new Map(); } } }; createGpuDataManager = (...args) => new GpuDataManagerImpl(...args); } }); // web/lib/wasm/jsep/webgpu/attribute-with-cache-key.ts var AttributeWithCacheKeyImpl2, createAttributeWithCacheKey2; var init_attribute_with_cache_key2 = __esm({ "web/lib/wasm/jsep/webgpu/attribute-with-cache-key.ts"() { "use strict"; AttributeWithCacheKeyImpl2 = 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; } }; createAttributeWithCacheKey2 = (attribute) => new AttributeWithCacheKeyImpl2(attribute); } }); // web/lib/wasm/jsep/webgpu/ops/common.ts var WORKGROUP_SIZE, getWgslMappedType, tensorTypeToWsglStorageType, tensorTypeToWsglValueType, createTensorShapeVariables, getMaxComponents, fillVector, castToF32, sumVector, getElementAt, createIndicesHelper, inputVariable, outputVariable, atomicOutputVariable, internalVariable, ShaderHelperImpl, createShaderHelper; var init_common = __esm({ "web/lib/wasm/jsep/webgpu/ops/common.ts"() { "use strict"; init_wasm_common(); init_util2(); WORKGROUP_SIZE = 64; getWgslMappedType = (type, components) => { if (components === 3) { throw new Error("vec3 has same alignment as vec4, use vec4 instead"); } switch (Number(type)) { case 10 /* float16 */: return components > 1 ? `vec${components}` : "f16"; case 1 /* float */: return components > 1 ? `vec${components}` : "f32"; case 6 /* int32 */: return components > 1 ? `vec${components}` : "i32"; case 12 /* uint32 */: return components > 1 ? `vec${components}` : "u32"; case 7 /* int64 */: if (components > 1) { throw new Error("currently not supported vecX of uint64 yet"); } return ["vec2", "i32"]; case 13 /* uint64 */: if (components > 1) { throw new Error("currently not supported vecX of uint64 yet"); } return ["vec2", "u32"]; case 9 /* bool */: if (components !== 4) { throw new Error("bool must be vec4"); } return ["u32", "vec4"]; case 22 /* int4 */: return "i32"; case 21 /* uint4 */: return "u32"; default: throw new Error(`Unknown data type: ${type}`); } }; tensorTypeToWsglStorageType = (type, components = 1) => { const mappedType = getWgslMappedType(type, components); return typeof mappedType === "string" ? mappedType : mappedType[0]; }; tensorTypeToWsglValueType = (type, components = 1) => { const mappedType = getWgslMappedType(type, components); return typeof mappedType === "string" ? mappedType : mappedType[1]; }; createTensorShapeVariables = (...dims) => { const programUniforms = []; dims.forEach((dim) => { if (dim.length !== 0) { programUniforms.push( { type: 12 /* uint32 */, data: dim }, { type: 12 /* uint32 */, data: ShapeUtil2.computeStrides(dim) } ); } }); return programUniforms; }; getMaxComponents = (size) => { if (size % 4 === 0) { return 4; } else if (size % 2 === 0) { return 2; } return 1; }; fillVector = (dataType = "f32", components, value = "0") => { if (!components || components === 1) { return `${dataType}(${value})`; } return `vec${components}<${dataType}>(${value})`; }; castToF32 = (dataType, components, value) => { if (dataType === "f32") { return value; } if (components === 1) { return `f32(${value})`; } return `vec${components}(${value})`; }; sumVector = (name2, components) => { if (components === 4) { return `(${name2}.x + ${name2}.y + ${name2}.z + ${name2}.w)`; } else if (components === 2) { return `(${name2}.x + ${name2}.y)`; } else if (components === 3) { return `(${name2}.x + ${name2}.y + ${name2}.z)`; } return name2; }; getElementAt = (name2, index, length, type) => { if (name2.startsWith("uniforms.") && length > 4) { if (typeof index === "string") { if (type === "f16") { return `${name2}[(${index}) / 8][(${index}) % 8 / 4][(${index}) % 8 % 4]`; } else { return `${name2}[(${index}) / 4][(${index}) % 4]`; } } else { if (type === "f16") { return `${name2}[${Math.floor(index / 8)}][${Math.floor(index % 8 / 4)}][${index % 8 % 4}]`; } else { return `${name2}[${Math.floor(index / 4)}][${index % 4}]`; } } } else { return length > 1 ? `${name2}[${index}]` : name2; } }; createIndicesHelper = (name2, tensorType, shapeOrRank, usage, components) => { const useUniform = typeof shapeOrRank === "number"; const rank = useUniform ? shapeOrRank : shapeOrRank.length; const rankIdentity = [...new Array(rank).keys()]; const indicesType = rank < 2 ? "u32" : rank <= 4 ? `vec${rank}` : `array`; const mappedType = getWgslMappedType(tensorType, components); const valueType = typeof mappedType === "string" ? mappedType : mappedType[1]; const storageType = typeof mappedType === "string" ? mappedType : mappedType[0]; const type = { indices: indicesType, value: valueType, storage: storageType, tensor: tensorType }; const normalizeDim = (dim) => typeof dim === "string" ? dim : `${dim}u`; const implementationUsed = { offsetToIndices: false, indicesToOffset: false, broadcastedIndicesToOffset: false, set: false, setByIndices: false, get: false, getByIndices: false }; const uniformPrefix = useUniform ? "uniforms." : ""; const shape2 = `${uniformPrefix}${name2}_shape`; const strides = `${uniformPrefix}${name2}_strides`; let o2iSnippet = ""; for (let i = 0; i < rank - 1; i++) { o2iSnippet += ` let dim${i} = current / ${getElementAt(strides, i, rank)}; let rest${i} = current % ${getElementAt(strides, i, rank)}; indices[${i}] = dim${i}; current = rest${i}; `; } o2iSnippet += `indices[${rank - 1}] = current;`; const offsetToIndicesImplementation = rank < 2 ? "" : ` fn o2i_${name2}(offset: u32) -> ${type.indices} { var indices: ${type.indices}; var current = offset; ${o2iSnippet} return indices; }`; const offsetToIndices2 = (varOffset) => { implementationUsed.offsetToIndices = true; return rank < 2 ? varOffset : `o2i_${name2}(${varOffset})`; }; const offsets = []; if (rank >= 2) { for (let i = rank - 1; i >= 0; i--) { offsets.push(`${getElementAt(strides, i, rank)} * (indices[${i}])`); } } const indicesToOffsetImplementation = rank < 2 ? "" : ` fn i2o_${name2}(indices: ${type.indices}) -> u32 { return ${offsets.join("+")}; }`; const indicesToOffset = (varIndices) => { implementationUsed.indicesToOffset = true; return rank < 2 ? varIndices : `i2o_${name2}(${varIndices})`; }; const indices = (...init2) => rank === 0 ? "0u" : `${type.indices}(${init2.map(normalizeDim).join(",")})`; const indicesGet = (varIndices, idx) => { if (rank < 2) { return `${varIndices}`; } else { return `${getElementAt(varIndices, idx, rank)}`; } }; const indicesSet = (varIndices, idx, value) => { if (rank < 2) { return `${varIndices}=${value};`; } else { return `${getElementAt(varIndices, idx, rank)}=${value};`; } }; const broadcastedIndicesToOffsetImplementation = {}; const broadcastedIndicesToOffset = (varIndices, output) => { implementationUsed.broadcastedIndicesToOffset = true; const implKey = `${output.name}broadcastedIndicesTo${name2}Offset`; if (implKey in broadcastedIndicesToOffsetImplementation) { return `${implKey}(${varIndices})`; } const offsets2 = []; for (let i = rank - 1; i >= 0; i--) { const idx = output.indicesGet("outputIndices", i + output.rank - rank); offsets2.push(`${indicesGet(strides, i)} * (${idx} % ${indicesGet(shape2, i)})`); } broadcastedIndicesToOffsetImplementation[implKey] = `fn ${implKey}(outputIndices: ${output.type.indices}) -> u32 { return ${offsets2.length > 0 ? offsets2.join("+") : "0u"}; }`; return `${implKey}(${varIndices})`; }; const setByOffset = (offset, value) => (() => { if (type.storage === type.value) { return `${name2}[${offset}]=${value};`; } else if (type.storage === "vec2" && type.value === "i32") { return `${name2}[${offset}]=vec2(u32(${value}), select(0u, 0xFFFFFFFFu, ${value} < 0));`; } else if (type.storage === "vec2" && type.value === "u32") { return `${name2}[${offset}]=vec2(u32(${value}), 0u);`; } else if (type.storage === "u32" && type.value === "vec4") { return `${name2}[${offset}]=dot(vec4(0x1, 0x100, 0x10000, 0x1000000), vec4(${value}));`; } else { throw new Error(`not supported combination of storage type ${type.storage} and value type ${type.value} yet`); } })(); const getByOffset = (offset) => (() => { if (type.storage === type.value) { return `${name2}[${offset}]`; } else if (type.storage === "vec2" && type.value === "i32") { return `i32(${name2}[${offset}].x)`; } else if (type.storage === "vec2" && type.value === "u32") { return `u32(${name2}[${offset}].x)`; } else if (type.storage === "u32" && type.value === "vec4") { return `vec4(bool(${name2}[${offset}] & 0xFFu), bool(${name2}[${offset}] & 0xFF00u), bool(${name2}[${offset}] & 0xFF0000u), bool(${name2}[${offset}] & 0xFF000000u))`; } else { throw new Error(`not supported combination of storage type ${type.storage} and value type ${type.value} yet`); } })(); const getByIndicesImplementation = rank < 2 ? "" : ` fn get_${name2}ByIndices(indices: ${type.indices}) -> ${valueType} { return ${getByOffset(`i2o_${name2}(indices)`)}; }`; const getImplementation = rank < 2 ? "" : (() => { const functionParams = rankIdentity.map((i) => `d${i}: u32`).join(", "); const dimsParams = rankIdentity.map((i) => `d${i}`).join(", "); return ` fn get_${name2}(${functionParams}) -> ${valueType} { return get_${name2}ByIndices(${indices(dimsParams)}); }`; })(); const get = (...indices2) => { if (indices2.length !== rank) { throw new Error(`indices length must be ${rank}`); } const normalizedIndices = indices2.map(normalizeDim).join(","); if (rank === 0) { return getByOffset("0u"); } else if (rank === 1) { return getByOffset(normalizedIndices[0]); } else { implementationUsed.get = true; implementationUsed.getByIndices = true; implementationUsed.indicesToOffset = true; return `get_${name2}(${normalizedIndices})`; } }; const getByIndices = (varIndices) => { if (rank < 2) { return getByOffset(varIndices); } else { implementationUsed.getByIndices = true; implementationUsed.indicesToOffset = true; return `get_${name2}ByIndices(${varIndices})`; } }; const setByIndicesImplementation = rank < 2 ? "" : ` fn set_${name2}ByIndices(indices: ${type.indices}, value: ${valueType}) { ${setByOffset(`i2o_${name2}(indices)`, "value")} }`; const setImplementation = rank < 2 ? "" : (() => { const functionParams = rankIdentity.map((i) => `d${i}: u32`).join(", "); const dimsParams = rankIdentity.map((i) => `d${i}`).join(", "); return ` fn set_${name2}(${functionParams}, value: ${valueType}) { set_${name2}ByIndices(${indices(dimsParams)}, value); }`; })(); const set = (...indicesAndValue) => { if (indicesAndValue.length !== rank + 1) { throw new Error(`indices length must be ${rank}`); } const value = indicesAndValue[rank]; if (typeof value !== "string") { throw new Error("value must be string"); } const normalizedIndices = indicesAndValue.slice(0, rank).map(normalizeDim).join(","); if (rank === 0) { return setByOffset("0u", value); } else if (rank === 1) { return setByOffset(normalizedIndices[0], value); } else { implementationUsed.set = true; implementationUsed.setByIndices = true; implementationUsed.indicesToOffset = true; return `set_${name2}(${normalizedIndices}, ${value})`; } }; const setByIndices = (varIndices, value) => { if (rank < 2) { return setByOffset(varIndices, value); } else { implementationUsed.setByIndices = true; implementationUsed.indicesToOffset = true; return `set_${name2}ByIndices(${varIndices}, ${value});`; } }; const impl = () => { const impls = []; let needShapeStrides = false; if (implementationUsed.offsetToIndices) { impls.push(offsetToIndicesImplementation); needShapeStrides = true; } if (implementationUsed.indicesToOffset) { impls.push(indicesToOffsetImplementation); needShapeStrides = true; } if (implementationUsed.broadcastedIndicesToOffset) { Object.values(broadcastedIndicesToOffsetImplementation).forEach((impl2) => impls.push(impl2)); needShapeStrides = true; } if (implementationUsed.set) { impls.push(setImplementation); needShapeStrides = true; } if (implementationUsed.setByIndices) { impls.push(setByIndicesImplementation); needShapeStrides = true; } if (implementationUsed.get) { impls.push(getImplementation); needShapeStrides = true; } if (implementationUsed.getByIndices) { impls.push(getByIndicesImplementation); needShapeStrides = true; } if (!useUniform && needShapeStrides) { impls.unshift( `const ${shape2} = ${type.indices}(${shapeOrRank.join(",")});`, `const ${strides} = ${type.indices}(${ShapeUtil2.computeStrides(shapeOrRank).join(",")});` ); } return impls.join("\n"); }; return { impl, type, offsetToIndices: offsetToIndices2, indicesToOffset, broadcastedIndicesToOffset, indices, indicesGet, indicesSet, set, setByOffset, setByIndices, get, getByOffset, getByIndices, // isVec4, usage, name: name2, strides, shape: shape2, rank }; }; inputVariable = (name2, type, shapeOrRank, components = 1) => createIndicesHelper(name2, type, shapeOrRank, "input", components); outputVariable = (name2, type, shapeOrRank, components = 1) => createIndicesHelper(name2, type, shapeOrRank, "output", components); atomicOutputVariable = (name2, type, shapeOrRank) => createIndicesHelper(name2, type, shapeOrRank, "atomicOutput", 1); internalVariable = (name2, type, shapeOrRank, components = 1) => createIndicesHelper(name2, type, shapeOrRank, "internal", components); ShaderHelperImpl = class { constructor(normalizedDispatchGroup, limits) { this.normalizedDispatchGroup = normalizedDispatchGroup; this.limits = limits; this.internalVariables = []; this.variables = []; this.uniforms = []; this.variableIndex = 0; } guardAgainstOutOfBoundsWorkgroupSizes(size) { const sizeInCode = typeof size === "number" ? `${size}u` : size; return `if (global_idx >= ${sizeInCode}) { return; }`; } mainStart(workgroupSize = WORKGROUP_SIZE) { const workgroupSizeX = typeof workgroupSize === "number" ? workgroupSize : workgroupSize[0]; const workgroupSizeY = typeof workgroupSize === "number" ? 1 : workgroupSize[1]; const workgroupSizeZ = typeof workgroupSize === "number" ? 1 : workgroupSize[2]; if (workgroupSizeX > this.limits.maxComputeWorkgroupSizeX || workgroupSizeY > this.limits.maxComputeWorkgroupSizeY || workgroupSizeZ > this.limits.maxComputeWorkgroupSizeZ) { throw new Error( `workgroup size [${workgroupSizeX}, ${workgroupSizeY}, ${workgroupSizeZ}] exceeds the maximum workgroup size [${this.limits.maxComputeWorkgroupSizeX}, ${this.limits.maxComputeWorkgroupSizeY}, ${this.limits.maxComputeWorkgroupSizeZ}].` ); } if (workgroupSizeX * workgroupSizeY * workgroupSizeZ > this.limits.maxComputeInvocationsPerWorkgroup) { throw new Error( `workgroup size [${workgroupSizeX}, ${workgroupSizeY}, ${workgroupSizeZ}] exceeds the maximum workgroup invocations ${this.limits.maxComputeInvocationsPerWorkgroup}.` ); } const is1DimensionDispatch = this.normalizedDispatchGroup[1] === 1 && this.normalizedDispatchGroup[2] === 1; const paramList = is1DimensionDispatch ? `@builtin(global_invocation_id) global_id : vec3, @builtin(workgroup_id) workgroup_id : vec3, @builtin(local_invocation_index) local_idx : u32, @builtin(local_invocation_id) local_id : vec3` : `@builtin(global_invocation_id) global_id : vec3, @builtin(local_invocation_id) local_id : vec3, @builtin(local_invocation_index) local_idx : u32, @builtin(workgroup_id) workgroup_id : vec3, @builtin(num_workgroups) num_workgroups : vec3`; const globalIdxDefinition = is1DimensionDispatch ? `let global_idx = global_id.x; let workgroup_index = workgroup_id.x;` : `let workgroup_index = workgroup_id.z * num_workgroups[0] * num_workgroups[1] + workgroup_id.y * num_workgroups[0] + workgroup_id.x; let global_idx = workgroup_index * ${workgroupSizeX * workgroupSizeY * workgroupSizeZ}u + local_idx;`; return `@compute @workgroup_size(${workgroupSizeX}, ${workgroupSizeY}, ${workgroupSizeZ}) fn main(${paramList}) { ${globalIdxDefinition} `; } appendVariableUniforms(variable) { if (variable.rank !== 0) { if (variable.shape.startsWith("uniforms.")) { this.uniforms.push({ name: variable.shape.replace("uniforms.", ""), type: "u32", length: variable.rank }); } if (variable.strides.startsWith("uniforms.")) { this.uniforms.push({ name: variable.strides.replace("uniforms.", ""), type: "u32", length: variable.rank }); } } } declareVariable(variable, bindingIndex) { if (variable.usage === "internal") { throw new Error("cannot use internal variable with declareVariable(). use registerInternalVariables() instead."); } this.variables.push(variable); this.appendVariableUniforms(variable); const access = variable.usage === "input" ? "read" : "read_write"; const storageType = variable.usage === "atomicOutput" ? `atomic` : variable.type.storage; return `@group(0) @binding(${bindingIndex}) var ${variable.name}: array<${storageType}>;`; } declareVariables(...variables) { return variables.map((v) => this.declareVariable(v, this.variableIndex++)).join("\n"); } registerInternalVariable(variable) { if (variable.usage !== "internal") { throw new Error( "cannot use input or output variable with registerInternalVariable(). use declareVariables() instead." ); } this.internalVariables.push(variable); this.appendVariableUniforms(variable); } registerInternalVariables(...variables) { variables.forEach((v) => this.registerInternalVariable(v)); return this; } registerUniform(name2, type, length = 1) { this.uniforms.push({ name: name2, type, length }); return this; } registerUniforms(additionalUniforms) { this.uniforms = this.uniforms.concat(additionalUniforms); return this; } uniformDeclaration() { if (this.uniforms.length === 0) { return ""; } const uniformSnippets = []; for (const { name: name2, type, length } of this.uniforms) { if (length && length > 4) { if (type === "f16") { uniformSnippets.push(`@align(16) ${name2}:array, ${Math.ceil(length / 8)}>`); } else { uniformSnippets.push(`${name2}:array, ${Math.ceil(length / 4)}>`); } } else { const typeTemp = length == null || length === 1 ? type : `vec${length}<${type}>`; uniformSnippets.push(`${name2}:${typeTemp}`); } } return ` struct Uniforms { ${uniformSnippets.join(", ")} }; @group(0) @binding(${this.variableIndex}) var uniforms: Uniforms;`; } /** * Get additional implementation that needs to be added to the shader source. */ get additionalImplementations() { return this.uniformDeclaration() + this.variables.map((i) => i.impl()).join("\n") + this.internalVariables.map((i) => i.impl()).join("\n"); } /** * Get the variable info of the shader program. */ get variablesInfo() { if (this.uniforms.length === 0) { return void 0; } const uniformWgslTypeToDataType = (type) => [12 /* uint32 */, 10 /* float16 */, 1 /* float */, 6 /* int32 */][["u32", "f16", "f32", "i32"].indexOf(type)]; return this.uniforms.map((u) => [uniformWgslTypeToDataType(u.type), u.length ?? 1]); } }; createShaderHelper = (dispatchGroup, limits) => new ShaderHelperImpl(dispatchGroup, limits); } }); // web/lib/wasm/jsep/webgpu/ops/transpose.ts var validateInputs26, getAdjustedPerm2, getOutputShape2, permFunctionBody, squeezeShape2, isTransposeReshape, createTransposeProgramInfo2, transpose2, parseTransposeAttributes2; var init_transpose2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/transpose.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateInputs26 = (inputs, perm) => { if (!inputs || inputs.length !== 1) { throw new Error("Transpose requires 1 input."); } if (perm.length !== 0 && perm.length !== inputs[0].dims.length) { throw new Error(`perm size ${perm.length} does not match input rank ${inputs[0].dims.length}`); } }; getAdjustedPerm2 = (inputRank, perm) => perm.length !== 0 ? perm : [...new Array(inputRank).keys()].reverse(); getOutputShape2 = (inputShape, perm) => ShapeUtil2.sortBasedOnPerm(inputShape, getAdjustedPerm2(inputShape.length, perm)); permFunctionBody = (perm, rank, input, output) => { let reverseFunc = `fn perm(i: ${output.type.indices}) -> ${input.type.indices} { var a: ${input.type.indices};`; for (let i = 0; i < rank; ++i) { reverseFunc += `a[${perm[i]}]=i[${i}];`; } return reverseFunc += "return a;}"; }; squeezeShape2 = (shape2, adjustedPerm) => { const newShape = []; const newPerm = []; for (let i = 0; i < shape2.length; ++i) { if (shape2[i] !== 1) { newShape.push(shape2[i]); } if (shape2[adjustedPerm[i]] !== 1) { newPerm.push(adjustedPerm[i]); } } return { newShape, newPerm }; }; isTransposeReshape = (perm, shape2) => { let lastPermutedAxis = 0; for (let i = 0; i < perm.length; ++i) { if (shape2[perm[i]] === 1) { continue; } if (perm[i] < lastPermutedAxis) { return false; } lastPermutedAxis = perm[i]; } return true; }; createTransposeProgramInfo2 = (inputTensor, permAttr) => { const inputDataType = inputTensor.dataType; const inputRank = inputTensor.dims.length; const perm = getAdjustedPerm2(inputRank, permAttr); const outputShape = getOutputShape2(inputTensor.dims, perm); let newInputShape = inputTensor.dims; let newOutputShape = outputShape; const transposeAsReshape = inputRank < 2 || isTransposeReshape(perm, inputTensor.dims); let getShaderSource; if (transposeAsReshape) { getShaderSource = (shaderHelper) => { const input = inputVariable("input", inputDataType, newInputShape, 4); const output = outputVariable("output", inputDataType, newOutputShape, 4); return ` ${shaderHelper.registerUniform("output_size", "u32").declareVariables(input, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} output[global_idx] = input[global_idx]; }`; }; return { name: "TransposeCopy", shaderCache: { inputDependencies: ["type"] }, getRunData: () => { const outputSize = ShapeUtil2.size(outputShape); return { outputs: [{ dims: outputShape, dataType: inputTensor.dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 / 4 /* components */ ) }, programUniforms: [{ type: 12 /* uint32 */, data: Math.ceil(outputSize / 4) }] }; }, getShaderSource }; } const { newShape, newPerm } = squeezeShape2(inputTensor.dims, perm); const channelsLast = ShapeUtil2.areEqual(newPerm, [2, 3, 1]); const channelsFirst = ShapeUtil2.areEqual(newPerm, [3, 1, 2]); const useShared = newShape.length === 2 || channelsLast || channelsFirst; if (useShared) { newInputShape = channelsLast ? [newShape[0], newShape[1] * newShape[2]] : channelsFirst ? [newShape[0] * newShape[1], newShape[2]] : newShape; newOutputShape = [newInputShape[1], newInputShape[0]]; const tileSize = 16; getShaderSource = (shaderHelper) => { const input = inputVariable("a", inputDataType, newInputShape.length); const output = outputVariable("output", inputDataType, newOutputShape.length); return ` ${shaderHelper.registerUniform("output_size", "u32").declareVariables(input, output)} var tile : array, ${tileSize}>; ${shaderHelper.mainStart([tileSize, tileSize, 1])} let stride = (uniforms.output_shape[1] - 1) / ${tileSize} + 1; let workgroup_id_x = workgroup_index % stride; let workgroup_id_y = workgroup_index / stride; let input_col = workgroup_id_y * ${tileSize}u + local_id.x; let input_row = workgroup_id_x * ${tileSize}u + local_id.y; if (input_row < uniforms.a_shape[0] && input_col < uniforms.a_shape[1]) { tile[local_id.y][local_id.x] = ${input.getByIndices(`${input.type.indices}(input_row, input_col)`)}; } workgroupBarrier(); let output_col = workgroup_id_x * ${tileSize}u + local_id.x; let output_row = workgroup_id_y * ${tileSize}u + local_id.y; if (output_row < uniforms.output_shape[0] && output_col < uniforms.output_shape[1]) { ${output.setByIndices(`${output.type.indices}(output_row, output_col)`, "tile[local_id.x][local_id.y]")} } }`; }; return { name: "TransposeShared", shaderCache: { inputDependencies: ["type"] }, getRunData: () => { const outputSize = ShapeUtil2.size(outputShape); return { outputs: [{ dims: outputShape, dataType: inputTensor.dataType }], dispatchGroup: { x: Math.ceil(newOutputShape[1] / tileSize), y: Math.ceil(newOutputShape[0] / tileSize) }, programUniforms: [ { type: 12 /* uint32 */, data: outputSize }, ...createTensorShapeVariables(newInputShape, newOutputShape) ] }; }, getShaderSource }; } getShaderSource = (shaderHelper) => { const input = inputVariable("a", inputDataType, newInputShape.length); const output = outputVariable("output", inputDataType, newOutputShape.length); return ` ${shaderHelper.registerUniform("output_size", "u32").declareVariables(input, output)} ${permFunctionBody(perm, inputRank, input, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let indices = ${output.offsetToIndices("global_idx")}; let aIndices = perm(indices); ${output.setByOffset("global_idx", input.getByIndices("aIndices"))} }`; }; return { name: "Transpose", shaderCache: { hint: `${permAttr}`, inputDependencies: ["rank"] }, getRunData: () => { const outputSize = ShapeUtil2.size(outputShape); return { outputs: [{ dims: outputShape, dataType: inputTensor.dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms: [ { type: 12 /* uint32 */, data: outputSize }, ...createTensorShapeVariables(newInputShape, newOutputShape) ] }; }, getShaderSource }; }; transpose2 = (context, attributes) => { validateInputs26(context.inputs, attributes.perm); context.compute(createTransposeProgramInfo2(context.inputs[0], attributes.perm)); }; parseTransposeAttributes2 = (attributes) => createAttributeWithCacheKey2({ perm: attributes.perm }); } }); // web/lib/wasm/jsep/webgpu/ops/reduce-shared.ts var reduceOps, reduceSharedOps, reduceInitValues, reduceOutputValues, getInnerMostAxes, computeOutAndReduceShapes, expandShapeToKeepDim, areAxesInnerMostDims, getAxesPermutation, createReduceSharedProgramInfo, reduceCommon, reduceMeanShared, reduceL1Shared, reduceL2Shared, reduceLogSumExpShared, reduceMaxShared, reduceMinShared, reduceProdShared, reduceSumShared, reduceSumSquareShared, reduceLogSumShared; var init_reduce_shared = __esm({ "web/lib/wasm/jsep/webgpu/ops/reduce-shared.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); init_reduce2(); init_transpose2(); reduceOps = { max: "select(bestValue, candidate, candidate > bestValue)", min: "select(bestValue, candidate, candidate < bestValue)", mean: "bestValue + candidate", sum: "bestValue + candidate", prod: "bestValue * candidate", sumSquare: "bestValue + candidate * candidate", logSumExp: "bestValue + exp(candidate)", l1: "bestValue + abs(candidate)", l2: "bestValue + candidate * candidate", logSum: "bestValue + candidate" }; reduceSharedOps = { max: "select(bestValue, candidate, candidate > bestValue)", min: "select(bestValue, candidate, candidate < bestValue)", mean: "bestValue + candidate", sum: "bestValue + candidate", prod: "bestValue * candidate", sumSquare: "bestValue + candidate", logSumExp: "bestValue + candidate", l1: "bestValue + candidate", l2: "bestValue + candidate", logSum: "bestValue + candidate" }; reduceInitValues = { max: "_A[offset]", min: "_A[offset]", mean: "0", sum: "0", prod: "1", sumSquare: "0", logSumExp: "0", l1: "0", l2: "0", logSum: "0" }; reduceOutputValues = { max: "bestValue", min: "bestValue", sum: "bestValue", prod: "bestValue", sumSquare: "bestValue", logSumExp: "log(bestValue)", l1: "bestValue", l2: "sqrt(bestValue)", logSum: "log(bestValue)" }; getInnerMostAxes = (numInnerAxes, rank) => { const res = []; for (let i = rank - numInnerAxes; i < rank; ++i) { res.push(i); } return res; }; computeOutAndReduceShapes = (shape2, axes) => { const outputShape = []; const rank = shape2.length; for (let dim = 0; dim < rank; dim++) { if (axes.indexOf(dim) === -1) { outputShape.push(shape2[dim]); } } const reduceShape = axes.map((dim) => shape2[dim]); return [outputShape, reduceShape]; }; expandShapeToKeepDim = (shape2, axes) => { const rank = shape2.length + axes.length; const expandShape = []; let shapeIdx = 0; for (let dim = 0; dim < rank; dim++) { if (axes.indexOf(dim) === -1) { expandShape.push(shape2[shapeIdx++]); } else { expandShape.push(1); } } return expandShape; }; areAxesInnerMostDims = (axes, rank) => { for (let i = 0; i < axes.length; ++i) { if (axes[axes.length - i - 1] !== rank - 1 - i) { return false; } } return true; }; getAxesPermutation = (axes, rank) => { const res = []; if (!areAxesInnerMostDims(axes, rank)) { for (let i = 0; i < rank; ++i) { if (axes.indexOf(i) === -1) { res.push(i); } } axes.forEach((axis) => res.push(axis)); } return res; }; createReduceSharedProgramInfo = (name2, cacheKey, inputs, reduceType, outputDataType, outputShape, reduceShape) => { const inputShape = inputs[0].dims; const outputSize = ShapeUtil2.size(outputShape); const reduceSize = ShapeUtil2.size(reduceShape); const input = inputVariable("_A", inputs[0].dataType, inputShape); const output = outputVariable("output", outputDataType, outputShape); let workgroupSize = 64; if (outputSize === 1) { workgroupSize = 256; } const sharedMemorySnippet = ` var aBestValues : array; `; const getShaderSource = (shaderHelper) => ` ${shaderHelper.registerUniform("reduceSize", "u32").declareVariables(input, output)} ${sharedMemorySnippet} fn DIV_CEIL(a : u32, b : u32) -> u32 { return ((a - 1u) / b + 1u); } ${shaderHelper.mainStart(workgroupSize)} let outputIndex = global_idx / ${workgroupSize}; let offset = outputIndex * uniforms.reduceSize; var bestValue = f32(${reduceInitValues[reduceType]}); let Length = uniforms.reduceSize; for (var k = local_idx; k < Length; k = k + ${workgroupSize}) { let candidate = f32(${input.getByOffset("offset + k")}); bestValue = ${reduceOps[reduceType]}; } aBestValues[local_idx] = bestValue; workgroupBarrier(); var reduceSize = min(Length, ${workgroupSize}u); for (var currentSize = reduceSize / 2u; reduceSize > 1u; currentSize = reduceSize / 2u) { let interval = DIV_CEIL(reduceSize, 2u); if (local_idx < currentSize) { let candidate = aBestValues[local_idx + interval]; bestValue = ${reduceSharedOps[reduceType]}; aBestValues[local_idx] = bestValue; } reduceSize = interval; workgroupBarrier(); } if (local_idx == 0u) { ${output.setByOffset( "outputIndex", `${reduceType === "mean" ? `${output.type.storage}(bestValue / f32(uniforms.reduceSize))` : `${output.type.storage}(${reduceOutputValues[reduceType]})`}` )}; } }`; return { name: name2, // Note that in JSEP, WG size is not included in cache by default, but WebGPU EP it is. shaderCache: { hint: `${cacheKey};${workgroupSize}`, inputDependencies: ["type"] }, getShaderSource, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: outputDataType }], dispatchGroup: { x: outputSize }, programUniforms: [{ type: 12 /* uint32 */, data: reduceSize }] }) }; }; reduceCommon = (context, name2, attributes, reduceType) => { const updatedAttributes = context.inputs.length === 1 ? attributes : createReduceAttributesFromInputs(context.inputs, attributes); let updatedAxes = updatedAttributes.axes; if (updatedAxes.length === 0 && !updatedAttributes.noopWithEmptyAxes) { updatedAxes = context.inputs[0].dims.map((_dim, i) => i); } const normalizeAxes = ShapeUtil2.normalizeAxes(updatedAxes, context.inputs[0].dims.length); let axes = normalizeAxes; let input = context.inputs[0]; const permutedAxes = getAxesPermutation(axes, context.inputs[0].dims.length); if (permutedAxes.length > 0) { input = context.compute(createTransposeProgramInfo2(context.inputs[0], permutedAxes), { inputs: [0], outputs: [-1] })[0]; axes = getInnerMostAxes(axes.length, input.dims.length); } const [outputShape, reduceShape] = computeOutAndReduceShapes(input.dims, axes); let finalOutputShape = outputShape; if (updatedAttributes.keepDims) { finalOutputShape = expandShapeToKeepDim(outputShape, normalizeAxes); } context.compute( createReduceSharedProgramInfo( name2, updatedAttributes.cacheKey, [input], reduceType, context.inputs[0].dataType, finalOutputShape, reduceShape ), { inputs: [input] } ); }; reduceMeanShared = (context, attributes) => { reduceCommon(context, "ReduceMeanShared", attributes, "mean"); }; reduceL1Shared = (context, attributes) => { reduceCommon(context, "ReduceL1Shared", attributes, "l1"); }; reduceL2Shared = (context, attributes) => { reduceCommon(context, "ReduceL2Shared", attributes, "l2"); }; reduceLogSumExpShared = (context, attributes) => { reduceCommon(context, "ReduceLogSumExpShared", attributes, "logSumExp"); }; reduceMaxShared = (context, attributes) => { reduceCommon(context, "ReduceMaxShared", attributes, "max"); }; reduceMinShared = (context, attributes) => { reduceCommon(context, "ReduceMinShared", attributes, "min"); }; reduceProdShared = (context, attributes) => { reduceCommon(context, "ReduceProdShared", attributes, "prod"); }; reduceSumShared = (context, attributes) => { reduceCommon(context, "ReduceSumShared", attributes, "sum"); }; reduceSumSquareShared = (context, attributes) => { reduceCommon(context, "ReduceSumSquareShared", attributes, "sumSquare"); }; reduceLogSumShared = (context, attributes) => { reduceCommon(context, "ReduceLogSumShared", attributes, "logSum"); }; } }); // web/lib/wasm/jsep/webgpu/ops/reduce.ts var validateInputs27, noOp, createReduceProgramInfo2, createReduceAttributesFromInputs, runReduceProgram, reduceLogSumNaive, reduceL1Naive, reduceL2Naive, reduceLogSumExpNaive, reduceMaxNaive, reduceMeanNaive, reduceMinNaive, reduceProdNaive, reduceSumNaive, reduceSumSquareNaive, useNaiveReduceMethod, reduceMean2, reduceL1, reduceL2, reduceLogSumExp, reduceMax2, reduceMin2, reduceProd2, reduceSum2, reduceSumSquare, reduceLogSum2; var init_reduce2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/reduce.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); init_reduce_shared(); validateInputs27 = (inputs) => { if (!inputs || inputs.length === 0 || inputs.length > 2) { throw new Error("Reduce op requires 1 or 2 inputs."); } if (inputs.length === 2 && inputs[1].dims.length !== 1) { throw new Error("Invalid axes input dims."); } }; noOp = (input) => ["", "", `var value = ${input.getByIndices("input_indices")};`, ""]; createReduceProgramInfo2 = (name2, shaderCache, inputs, reduceOp, axesInput, outputDataType, keepDims = false, noopWithEmptyAxes = false) => { const outputShape = []; const inputShape = inputs[0].dims; const inputRank = inputShape.length; const axes = ShapeUtil2.normalizeAxes(axesInput, inputRank); const reduceOnAllAxes = !noopWithEmptyAxes && axes.length === 0; inputShape.forEach((d, i) => { if (reduceOnAllAxes || axes.indexOf(i) >= 0) { if (keepDims) { outputShape.push(1); } } else { outputShape.push(d); } }); const outputRank = outputShape.length; const outputSize = ShapeUtil2.size(outputShape); const getShaderSource = (shaderHelper) => { const idxCopy = []; const input = inputVariable("_A", inputs[0].dataType, inputRank); const output = outputVariable("output", outputDataType, outputRank); const ops = reduceOp(input, output, axes); let reduceOps2 = ops[2]; for (let k = 0, l = 0; k < inputRank; k++) { if (reduceOnAllAxes || axes.indexOf(k) >= 0) { if (keepDims) { l++; } reduceOps2 = `for(var j${k}: u32 = 0; j${k} < ${inputShape[k]}; j${k}++) { ${ops[2].includes("last_index") ? `let last_index = j${k};` : ""} ${input.indicesSet("input_indices", k, `j${k}`)} ${reduceOps2} }`; } else { idxCopy.push(`${input.indicesSet("input_indices", k, output.indicesGet("output_indices", l))};`); l++; } } return ` ${shaderHelper.registerUniform("output_size", "u32").declareVariables(input, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} var input_indices: ${input.type.indices}; let output_indices = ${output.offsetToIndices("global_idx")}; ${idxCopy.join("\n")} ${ops[0]} // init ops for reduce max/min ${ops[1]} ${reduceOps2} ${ops[3]} ${ops.length === 4 ? output.setByOffset("global_idx", "value") : ops.slice(4).join("\n")} }`; }; return { name: name2, shaderCache, getShaderSource, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: outputDataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms: [ { type: 12 /* uint32 */, data: outputSize }, ...createTensorShapeVariables(inputShape, outputShape) ] }) }; }; createReduceAttributesFromInputs = (inputs, attributes) => { const axes = []; if (inputs[1].dims[0] > 0) { inputs[1].getBigInt64Array().forEach((v) => axes.push(Number(v))); } return createAttributeWithCacheKey2({ axes, keepDims: attributes.keepDims, noopWithEmptyAxes: attributes.noopWithEmptyAxes }); }; runReduceProgram = (context, name2, attributes, reduceOp) => { const inputs = context.inputs; const updatedAttributes = inputs.length === 1 ? attributes : createReduceAttributesFromInputs(inputs, attributes); context.compute( createReduceProgramInfo2( name2, { hint: updatedAttributes.cacheKey, inputDependencies: ["rank"] }, [inputs[0]], updatedAttributes.noopWithEmptyAxes && updatedAttributes.axes.length === 0 ? noOp : reduceOp, updatedAttributes.axes, inputs[0].dataType, updatedAttributes.keepDims, updatedAttributes.noopWithEmptyAxes ), { inputs: [0] } ); }; reduceLogSumNaive = (context, attributes) => { validateInputs27(context.inputs); const reduceOp = (input, output) => [ `var value = ${output.type.storage}(0);`, "", `value += ${input.getByIndices("input_indices")};`, "value = log(value);" ]; runReduceProgram(context, "ReduceLogSum", attributes, reduceOp); }; reduceL1Naive = (context, attributes) => { validateInputs27(context.inputs); const reduceOp = (input, output) => [ `var value = ${output.type.storage}(0);`, "", `value += abs(${input.getByIndices("input_indices")});`, "" ]; runReduceProgram(context, "ReduceL1", attributes, reduceOp); }; reduceL2Naive = (context, attributes) => { validateInputs27(context.inputs); const reduceOp = (input, output) => [ `var t = ${output.type.value}(0); var value = ${output.type.value}(0);`, "", `t = ${input.getByIndices("input_indices")}; value += (t * t);`, "value = sqrt(value);" ]; runReduceProgram(context, "ReduceL2", attributes, reduceOp); }; reduceLogSumExpNaive = (context, attributes) => { validateInputs27(context.inputs); const reduceOp = (input, output) => [ `var value = ${output.type.storage}(0);`, "", `value += exp(${input.getByIndices("input_indices")});`, "value = log(value);" ]; runReduceProgram(context, "ReduceLogSumExp", attributes, reduceOp); }; reduceMaxNaive = (context, attributes) => { validateInputs27(context.inputs); const reduceOp = (input, _output, axes) => { const idxZero = []; for (let k = 0; k < input.rank; k++) { if (axes.indexOf(k) >= 0 || axes.length === 0) { idxZero.push(input.indicesSet("input_indices", k, 0)); } } return [ `${idxZero.join("\n")}`, `var value = ${input.getByIndices("input_indices")};`, `value = max(value, ${input.getByIndices("input_indices")});`, "" ]; }; runReduceProgram(context, "ReduceMax", attributes, reduceOp); }; reduceMeanNaive = (context, attributes) => { validateInputs27(context.inputs); const reduceOp = (input, output, axes) => { let size = 1; for (let k = 0; k < input.rank; k++) { if (axes.indexOf(k) >= 0 || axes.length === 0) { size *= context.inputs[0].dims[k]; } } return [ "var sum = f32(0);", "", `sum += f32(${input.getByIndices("input_indices")});`, `let value = ${output.type.value}(sum / ${size});` ]; }; runReduceProgram(context, "ReduceMean", attributes, reduceOp); }; reduceMinNaive = (context, attributes) => { validateInputs27(context.inputs); const reduceOp = (input, _output, axes) => { const idxZero = []; for (let k = 0; k < input.rank; k++) { if (axes.indexOf(k) >= 0 || axes.length === 0) { idxZero.push(`input_indices[${k}] = 0;`); } } return [ `${idxZero.join("\n")}`, `var value = ${input.getByIndices("input_indices")};`, `value = min(value, ${input.getByIndices("input_indices")});`, "" ]; }; runReduceProgram(context, "ReduceMin", attributes, reduceOp); }; reduceProdNaive = (context, attributes) => { validateInputs27(context.inputs); const reduceOp = (input, output) => [ `var value = ${output.type.storage}(1);`, "", `value *= ${input.getByIndices("input_indices")};`, "" ]; runReduceProgram(context, "ReduceProd", attributes, reduceOp); }; reduceSumNaive = (context, attributes) => { validateInputs27(context.inputs); const reduceOp = (input, output) => [ `var value = ${output.type.storage}(0);`, "", `value += ${input.getByIndices("input_indices")};`, "" ]; runReduceProgram(context, "ReduceSum", attributes, reduceOp); }; reduceSumSquareNaive = (context, attributes) => { validateInputs27(context.inputs); const reduceOp = (input, output) => [ `var t = ${output.type.value}(0); var value = ${output.type.value}(0);`, "", `t = ${input.getByIndices("input_indices")}; value += t * t;`, "" ]; runReduceProgram(context, "ReduceSumSquare", attributes, reduceOp); }; useNaiveReduceMethod = (shape2, axes, noopWithEmptyAxes) => { if (axes.length === 0) { return noopWithEmptyAxes; } let outputSize = 1; let reduceSize = 1; for (let dim = 0; dim < axes.length; dim++) { if (axes.indexOf(dim) === -1) { outputSize *= shape2[dim]; } else { reduceSize *= shape2[dim]; } } return reduceSize < 32 && outputSize > 1024; }; reduceMean2 = (context, attributes) => { if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { reduceMeanNaive(context, attributes); } else { reduceMeanShared(context, attributes); } }; reduceL1 = (context, attributes) => { if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { reduceL1Naive(context, attributes); } else { reduceL1Shared(context, attributes); } }; reduceL2 = (context, attributes) => { if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { reduceL2Naive(context, attributes); } else { reduceL2Shared(context, attributes); } }; reduceLogSumExp = (context, attributes) => { if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { reduceLogSumExpNaive(context, attributes); } else { reduceLogSumExpShared(context, attributes); } }; reduceMax2 = (context, attributes) => { if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { reduceMaxNaive(context, attributes); } else { reduceMaxShared(context, attributes); } }; reduceMin2 = (context, attributes) => { if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { reduceMinNaive(context, attributes); } else { reduceMinShared(context, attributes); } }; reduceProd2 = (context, attributes) => { if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { reduceProdNaive(context, attributes); } else { reduceProdShared(context, attributes); } }; reduceSum2 = (context, attributes) => { if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { reduceSumNaive(context, attributes); } else { reduceSumShared(context, attributes); } }; reduceSumSquare = (context, attributes) => { if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { reduceSumSquareNaive(context, attributes); } else { reduceSumSquareShared(context, attributes); } }; reduceLogSum2 = (context, attributes) => { if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { reduceLogSumNaive(context, attributes); } else { reduceLogSumShared(context, attributes); } }; } }); // web/lib/wasm/jsep/webgpu/ops/argminmax.ts var validateInputs28, argMin, argMax, parseArgMinMaxAttributes; var init_argminmax = __esm({ "web/lib/wasm/jsep/webgpu/ops/argminmax.ts"() { "use strict"; init_wasm_common(); init_attribute_with_cache_key2(); init_reduce2(); validateInputs28 = (inputs) => { if (!inputs || inputs.length === 0 || inputs.length > 2) { throw new Error("ArgMinMaxOp op requires 1 or 2 inputs."); } if (inputs[0].dataType !== 1 /* float */) { throw new Error("Invalid input type."); } }; argMin = (context, attributes) => { validateInputs28(context.inputs); const argMinMaxOp = (input, output, axes) => { const idxZero = []; for (let k = 0; k < input.rank; k++) { if (axes.indexOf(k) >= 0 || axes.length === 0) { idxZero.push(`input_indices[${k}] = 0;`); } } return [ `${idxZero.join("\n")}`, `var value = ${input.getByIndices("input_indices")}; var best_index : i32 = 0;`, `if (${input.getByIndices("input_indices")} ${attributes.selectLastIndex > 0 ? "<=" : "<"} value) { value = ${input.getByIndices("input_indices")}; best_index = i32(last_index); }`, "", output.setByOffset("global_idx", "best_index") ]; }; context.compute( createReduceProgramInfo2( "ArgMin", { hint: attributes.cacheKey, inputDependencies: ["rank"] }, [context.inputs[0]], argMinMaxOp, [attributes.axis], 7 /* int64 */, attributes.keepDims ), { inputs: [0] } ); }; argMax = (context, attributes) => { validateInputs28(context.inputs); const argMinMaxOp = (input, output, axes) => { const idxZero = []; for (let k = 0; k < input.rank; k++) { if (axes.indexOf(k) >= 0 || axes.length === 0) { idxZero.push(`input_indices[${k}] = 0;`); } } return [ `${idxZero.join("\n")}`, `var value = ${input.getByIndices("input_indices")}; var best_index : i32 = 0;`, `if (${input.getByIndices("input_indices")} ${attributes.selectLastIndex > 0 ? ">=" : ">"} value) { value = ${input.getByIndices("input_indices")}; best_index = i32(last_index); }`, "", output.setByOffset("global_idx", "best_index") ]; }; context.compute( createReduceProgramInfo2( "argMax", { hint: attributes.cacheKey, inputDependencies: ["rank"] }, [context.inputs[0]], argMinMaxOp, [attributes.axis], 7 /* int64 */, attributes.keepDims ), { inputs: [0] } ); }; parseArgMinMaxAttributes = (attributes) => createAttributeWithCacheKey2(attributes); } }); // web/lib/wasm/jsep/webgpu/ops/attention.ts var validateAttentionInputs, initVarStub, createInPlaceSoftmaxProgramInfo, createAttentionProbsProgramInfo, createVxAttentionScoreProgramInfo, applyAttention, prepare, attention; var init_attention = __esm({ "web/lib/wasm/jsep/webgpu/ops/attention.ts"() { "use strict"; init_wasm_common(); init_util2(); init_types2(); init_common(); validateAttentionInputs = (inputs, attributes) => { const input = inputs[0]; const weights = inputs[1]; const bias = inputs[2]; const maskIndex = inputs[3]; const past = inputs[4]; const attentionBias = inputs[5]; if (past && attentionBias) { throw new Error("Attention cannot have both past and attention_bias"); } if (input.dims.length !== 3) { throw new Error('Input "input" must have 3 dimensions'); } const batchSize = input.dims[0]; const sequenceLength = input.dims[1]; const inputHiddenSize = input.dims[2]; if (bias.dims.length !== 1) { throw new Error('Input "bias" is expected to have 1 dimensions'); } if (weights.dims.length !== 2) { throw new Error('Input "weights" is expected to have 2 dimensions'); } if (weights.dims[0] !== inputHiddenSize) { throw new Error("Input 1 dimension 0 should have same length as dimension 2 of input 0"); } if (bias.dims[0] !== weights.dims[1]) { throw new Error('Input "bias" dimension 0 should have same length as dimension 1 of input "weights"'); } let qHiddenSize = bias.dims[0] / 3; let kHiddenSize = qHiddenSize; let vHiddenSize = kHiddenSize; if (attributes.qkvHiddenSizes.length > 0) { if (attributes.qkvHiddenSizes.length !== 3) { throw new Error("qkv_hidden_sizes attribute should have 3 elements"); } for (const sz of attributes.qkvHiddenSizes) { if (sz % attributes.numHeads !== 0) { throw new Error("qkv_hidden_sizes should be divisible by num_heads"); } } qHiddenSize = attributes.qkvHiddenSizes[0]; kHiddenSize = attributes.qkvHiddenSizes[1]; vHiddenSize = attributes.qkvHiddenSizes[2]; } const kvSequenceLength = sequenceLength; if (qHiddenSize !== kHiddenSize) { throw new Error("qkv_hidden_sizes first element should be same as the second"); } if (bias.dims[0] !== qHiddenSize + kHiddenSize + vHiddenSize) { throw new Error('Input "bias" dimension 0 should have same length as sum of Q/K/V hidden sizes'); } let pastSequenceLength = 0; if (past) { if (kHiddenSize !== vHiddenSize) { throw new Error('Input "past" expect k_hidden_size == v_hidden_size'); } if (past.dims.length !== 5) { throw new Error('Input "past" must have 5 dimensions'); } if (past.dims[0] !== 2) { throw new Error('Input "past" first dimension must be 2'); } if (past.dims[1] !== batchSize) { throw new Error('Input "past" second dimension must be batch_size'); } if (past.dims[2] !== attributes.numHeads) { throw new Error('Input "past" third dimension must be num_heads'); } if (past.dims[4] !== kHiddenSize / attributes.numHeads) { throw new Error('Input "past" fifth dimension must be k_hidden_size / num_heads'); } if (!attributes.pastPresentShareBuffer) { pastSequenceLength = past.dims[3]; } } const totalSequenceLength = kvSequenceLength + pastSequenceLength; const maxSequenceLength = -1; const maskType = 0 /* none */; if (maskIndex) { throw new Error("Mask not supported"); } if (past) { throw new Error("past is not supported"); } if (attentionBias) { if (attentionBias.dims.length !== 4) { throw new Error('Input "attention_bias" must have 4 dimensions'); } if (attentionBias.dims[0] !== batchSize || attentionBias.dims[1] !== attributes.numHeads || attentionBias.dims[2] !== sequenceLength || attentionBias.dims[3] !== totalSequenceLength) { throw new Error('Expect "attention_bias" shape (batch_size, num_heads, sequence_length, total_sequence_length)'); } } return { batchSize, sequenceLength, pastSequenceLength, kvSequenceLength, totalSequenceLength, maxSequenceLength, inputHiddenSize, hiddenSize: qHiddenSize, vHiddenSize, headSize: Math.floor(qHiddenSize / attributes.numHeads), vHeadSize: Math.floor(vHiddenSize / attributes.numHeads), numHeads: attributes.numHeads, isUnidirectional: false, pastPresentShareBuffer: false, maskFilterValue: attributes.maskFilterValue, maskType, scale: attributes.scale, broadcastResPosBias: false, passPastInKv: false, qkvFormat: 1 /* qkvBNSH */ }; }; initVarStub = (seqLensInput, totalSequenceLengthInput, initPastSequenceLength) => { if (totalSequenceLengthInput && seqLensInput) { return ` let total_sequence_length_input = u32(${totalSequenceLengthInput.getByOffset("0")}); let present_sequence_length = max(total_sequence_length_input, uniforms.past_sequence_length); let is_subsequent_prompt: bool = sequence_length > 1 && sequence_length != total_sequence_length_input; let is_first_prompt: bool = is_subsequent_prompt == false && sequence_length == total_sequence_length_input; total_sequence_length = u32(${seqLensInput?.getByOffset("batchIdx")}) + 1; var past_sequence_length: u32 = 0; if (is_first_prompt == false) { past_sequence_length = total_sequence_length - sequence_length; } `; } else { return ` ${initPastSequenceLength ? "let past_sequence_length = uniforms.past_sequence_length" : ""}; let present_sequence_length = total_sequence_length; `; } }; createInPlaceSoftmaxProgramInfo = (input, batchSize, numHeads, pastSequenceLength, sequenceLength, totalSequenceLength, seqLens, totalSequenceLengthInput) => { const components = getMaxComponents(seqLens ? 1 : totalSequenceLength); let WG = 64; const totalSequenceLengthComp = totalSequenceLength / components; if (totalSequenceLengthComp < WG) { WG = 32; } const elementsPerThread = Math.ceil(totalSequenceLength / components / WG); const programUniforms = [ { type: 12 /* uint32 */, data: batchSize }, { type: 12 /* uint32 */, data: numHeads }, { type: 12 /* uint32 */, data: pastSequenceLength }, { type: 12 /* uint32 */, data: sequenceLength }, { type: 12 /* uint32 */, data: totalSequenceLengthComp }, { type: 12 /* uint32 */, data: elementsPerThread } ]; const dataType = tensorTypeToWsglStorageType(input.dataType, components); const f32Type = tensorTypeToWsglValueType(1 /* float */, components); const inputDependencies = ["type"]; if (seqLens) { inputDependencies.push("type"); } if (totalSequenceLengthInput) { inputDependencies.push("type"); } const getShaderSource = (shaderHelper) => { const inputHelper = outputVariable("x", input.dataType, input.dims, components); const inputHelpers = [inputHelper]; const seqLensInputHelper = seqLens ? inputVariable("seq_lens", seqLens.dataType, seqLens.dims) : void 0; if (seqLensInputHelper) { inputHelpers.push(seqLensInputHelper); } const totalSequenceLengthInputHelper = totalSequenceLengthInput ? inputVariable("total_sequence_length_input", totalSequenceLengthInput.dataType, totalSequenceLengthInput.dims) : void 0; if (totalSequenceLengthInputHelper) { inputHelpers.push(totalSequenceLengthInputHelper); } const elemValueType = tensorTypeToWsglValueType(input.dataType); const uniforms = [ { name: "batch_size", type: "u32" }, { name: "num_heads", type: "u32" }, { name: "past_sequence_length", type: "u32" }, { name: "sequence_length", type: "u32" }, { name: "total_sequence_length", type: "u32" }, { name: "elements_per_thread", type: "u32" } ]; return ` var thread_max: array; var thread_sum: array; ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputHelpers)} ${shaderHelper.mainStart([WG, 1, 1])} let batchIdx = workgroup_id.z / uniforms.num_heads; let headIdx = workgroup_id.z % uniforms.num_heads; let sequence_length = uniforms.sequence_length; var total_sequence_length = uniforms.total_sequence_length; ${initVarStub(seqLensInputHelper, totalSequenceLengthInputHelper, false)} let local_offset = local_idx * uniforms.elements_per_thread; let offset = (global_idx / ${WG}) * uniforms.total_sequence_length + local_offset; let seq_causal_length = ${seqLens ? "u32(past_sequence_length + workgroup_id.y + 1)" : "total_sequence_length"}; var thread_max_vector = ${f32Type}(-3.4028234663852886e+38f); for (var i: u32 = 0; i < uniforms.elements_per_thread && i + local_offset < seq_causal_length; i++) { thread_max_vector = max(${f32Type}(x[offset + i]), thread_max_vector); } thread_max[local_idx] = ${(() => { switch (components) { case 1: return "thread_max_vector"; case 2: return "max(thread_max_vector.x, thread_max_vector.y)"; case 4: return "max(max(thread_max_vector.x, thread_max_vector.y), max(thread_max_vector.z, thread_max_vector.w))"; default: throw new Error(`Unsupported components: ${components}`); } })()}; workgroupBarrier(); var max_value = f32(-3.4028234663852886e+38f); for (var i = 0u; i < ${WG}; i++) { max_value = max(thread_max[i], max_value); } var sum_vector = ${f32Type}(0); for (var i: u32 = 0; i < uniforms.elements_per_thread && i + local_offset < seq_causal_length; i++) { sum_vector += exp(${f32Type}(x[offset + i]) - max_value); } thread_sum[local_idx] = ${(() => { switch (components) { case 1: return "sum_vector"; case 2: return "sum_vector.x + sum_vector.y"; case 4: return "sum_vector.x + sum_vector.y + sum_vector.z + sum_vector.w"; default: throw new Error(`Unsupported components: ${components}`); } })()}; workgroupBarrier(); var sum: f32 = 0; for (var i = 0u; i < ${WG}; i++) { sum += thread_sum[i]; } if (sum == 0) { for (var i: u32 = 0; i < uniforms.elements_per_thread && i + local_offset < seq_causal_length; i++) { x[offset + i] = ${inputHelper.type.value}(${elemValueType}(1.0) / ${elemValueType}(seq_causal_length)); } } else { for (var i: u32 = 0; i < uniforms.elements_per_thread && i + local_offset < seq_causal_length; i++) { var f32input = ${f32Type}(x[offset + i]); x[offset + i] = ${inputHelper.type.value}(exp(f32input - max_value) / sum); } } ${seqLens ? ` for (var total_seq_id: u32 = seq_causal_length; total_seq_id + local_offset < uniforms.total_sequence_length; total_seq_id++) { x[offset + total_seq_id] = ${inputHelper.type.value}(${elemValueType}(0)); }` : ""}; }`; }; return { name: "AttentionProbsSoftmax", shaderCache: { hint: `${WG};${dataType};${components}`, inputDependencies }, getShaderSource, getRunData: () => ({ outputs: [], dispatchGroup: { x: 1, y: sequenceLength, z: batchSize * numHeads }, programUniforms }) }; }; createAttentionProbsProgramInfo = (outputCount, q, key, pastKey, attentionBias, parameters, pastSequenceLength, seqLens, totalSequenceLengthInput) => { const totalSequenceLength = pastSequenceLength + parameters.kvSequenceLength; const probsShape = [parameters.batchSize, parameters.numHeads, parameters.sequenceLength, totalSequenceLength]; const presentKey = outputCount > 1 && pastKey; const kvNumHeads = parameters.kvNumHeads ? parameters.kvNumHeads : parameters.numHeads; const presentKeyShape = presentKey ? [parameters.batchSize, kvNumHeads, totalSequenceLength, parameters.headSize] : void 0; const nReps = parameters.nReps ? parameters.nReps : 1; const alpha = parameters.scale === 0 ? 1 / Math.sqrt(parameters.headSize) : parameters.scale; const components = getMaxComponents(parameters.headSize); const vectorizedHeadSize = parameters.headSize / components; const TILE_SIZE = 12; const dispatch = { x: Math.ceil(totalSequenceLength / TILE_SIZE), y: Math.ceil(parameters.sequenceLength / TILE_SIZE), z: parameters.batchSize * parameters.numHeads }; const programUniforms = [ { type: 12 /* uint32 */, data: parameters.sequenceLength }, { type: 12 /* uint32 */, data: vectorizedHeadSize }, { type: 12 /* uint32 */, data: totalSequenceLength }, { type: 12 /* uint32 */, data: parameters.numHeads }, { type: 12 /* uint32 */, data: parameters.headSize }, { type: 1 /* float */, data: alpha }, { type: 12 /* uint32 */, data: pastSequenceLength }, { type: 12 /* uint32 */, data: parameters.kvSequenceLength }, { type: 12 /* uint32 */, data: nReps } ]; const feedPastKey = presentKey && pastKey && ShapeUtil2.size(pastKey.dims) > 0; const inputDependencies = ["type", "type"]; if (feedPastKey) { inputDependencies.push("type"); } if (attentionBias) { inputDependencies.push("type"); } if (seqLens) { inputDependencies.push("type"); } if (totalSequenceLengthInput) { inputDependencies.push("type"); } const outputs = [{ dims: probsShape, dataType: q.dataType, gpuDataType: 0 /* default */ }]; if (presentKey) { outputs.push({ dims: presentKeyShape, dataType: q.dataType, gpuDataType: 0 /* default */ }); } const getShaderSource = (shaderHelper) => { const qInput = inputVariable("q", q.dataType, q.dims, components); const kInput = inputVariable("key", key.dataType, key.dims, components); const inputVars = [qInput, kInput]; if (feedPastKey) { const pastKeyInput = inputVariable("past_key", pastKey.dataType, pastKey.dims, components); inputVars.push(pastKeyInput); } if (attentionBias) { inputVars.push(inputVariable("attention_bias", attentionBias.dataType, attentionBias.dims)); } const seqLensInputVariable = seqLens ? inputVariable("seq_lens", seqLens.dataType, seqLens.dims) : void 0; if (seqLensInputVariable) { inputVars.push(seqLensInputVariable); } const totalSequenceLengthInputVariable = totalSequenceLengthInput ? inputVariable("total_sequence_length_input", totalSequenceLengthInput.dataType, totalSequenceLengthInput.dims) : void 0; if (totalSequenceLengthInputVariable) { inputVars.push(totalSequenceLengthInputVariable); } const output = outputVariable("output", q.dataType, probsShape); const outputVars = [output]; if (presentKey) { outputVars.push(outputVariable("present_key", q.dataType, presentKeyShape, components)); } const f32Type = tensorTypeToWsglValueType(1 /* float */, components); const uniforms = [ { name: "M", type: "u32" }, { name: "K", type: "u32" }, { name: "N", type: "u32" }, { name: "num_heads", type: "u32" }, { name: "head_size", type: "u32" }, { name: "alpha", type: "f32" }, { name: "past_sequence_length", type: "u32" }, { name: "kv_sequence_length", type: "u32" }, { name: "n_reps", type: "u32" } ]; return ` const TILE_SIZE = ${TILE_SIZE}u; var tileQ: array<${qInput.type.storage}, ${TILE_SIZE * TILE_SIZE}>; var tileK: array<${qInput.type.storage}, ${TILE_SIZE * TILE_SIZE}>; ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVars, ...outputVars)} ${shaderHelper.mainStart([TILE_SIZE, TILE_SIZE, 1])} // x holds the N and y holds the M let headIdx = workgroup_id.z % uniforms.num_heads; let kvHeadIdx = ${nReps === 1 ? "headIdx" : "headIdx / uniforms.n_reps"}; let kv_num_heads = ${nReps === 1 ? "uniforms.num_heads" : "uniforms.num_heads / uniforms.n_reps"}; let batchIdx = workgroup_id.z / uniforms.num_heads; let m = workgroup_id.y * TILE_SIZE; let n = workgroup_id.x * TILE_SIZE; let sequence_length = uniforms.M; var total_sequence_length = uniforms.N; ${initVarStub(seqLensInputVariable, totalSequenceLengthInputVariable, true)} let absKvHeadIdx = batchIdx * kv_num_heads + kvHeadIdx; let qOffset = workgroup_id.z * uniforms.M * uniforms.K + m * uniforms.K; ${feedPastKey && presentKey ? "let pastKeyOffset = absKvHeadIdx * uniforms.past_sequence_length * uniforms.K;" : ""}; let kOffset = absKvHeadIdx * uniforms.kv_sequence_length * uniforms.K; ${presentKey ? "let presentKeyOffset = absKvHeadIdx * uniforms.N * uniforms.K;" : ""} var value = ${f32Type}(0); for (var w: u32 = 0u; w < uniforms.K; w += TILE_SIZE) { if (global_id.y < uniforms.M && w + local_id.x < uniforms.K) { tileQ[TILE_SIZE * local_id.y + local_id.x] = q[qOffset + local_id.y * uniforms.K + w + local_id.x]; } if (n + local_id.y < uniforms.N && w + local_id.x < uniforms.K) { var idx = TILE_SIZE * local_id.y + local_id.x; ${(() => { if (feedPastKey && presentKey) { return ` if (n + local_id.y < past_sequence_length) { tileK[idx] = past_key[pastKeyOffset + (n + local_id.y) * uniforms.K + w + local_id.x]; } else if (n + local_id.y - past_sequence_length < uniforms.kv_sequence_length) { tileK[idx] = key[kOffset + (n + local_id.y - past_sequence_length) * uniforms.K + w + local_id.x]; }`; } else { return ` if (n + local_id.y < uniforms.kv_sequence_length) { tileK[idx] = key[kOffset + (n + local_id.y) * uniforms.K + w + local_id.x]; }`; } })()} ${presentKey ? `if (n + local_id.y < present_sequence_length) { present_key[presentKeyOffset + (n + local_id.y) * uniforms.K + w + local_id.x] = tileK[idx]; }` : ""} } workgroupBarrier(); for (var k: u32 = 0u; k < TILE_SIZE && w+k < uniforms.K; k++) { value += ${f32Type}(tileQ[TILE_SIZE * local_id.y + k] * tileK[TILE_SIZE * local_id.x + k]); } workgroupBarrier(); } if (global_id.y < uniforms.M && global_id.x < total_sequence_length) { let headOffset = workgroup_id.z * uniforms.M * uniforms.N; let outputIdx = headOffset + global_id.y * uniforms.N + global_id.x; var sum: f32 = ${(() => { switch (components) { case 1: return "value"; case 2: return "value.x + value.y"; case 4: return "value.x + value.y + value.z + value.w"; default: throw new Error(`Unsupported components: ${components}`); } })()}; output[outputIdx] = ${output.type.value} (sum * uniforms.alpha) + ${attentionBias ? "attention_bias[outputIdx]" : "0.0"}; } }`; }; return { name: "AttentionProbs", shaderCache: { hint: `${components};${attentionBias !== void 0};${pastKey !== void 0};${outputCount}`, inputDependencies }, getRunData: () => ({ outputs, dispatchGroup: dispatch, programUniforms }), getShaderSource }; }; createVxAttentionScoreProgramInfo = (outputCount, probs, v, pastValue, params, pastSequenceLength, seqLens = void 0, totalSequenceLengthInput = void 0) => { const totalSequenceLength = pastSequenceLength + params.kvSequenceLength; const nReps = params.nReps ? params.nReps : 1; const repeatedVHiddenSize = params.vHiddenSize * nReps; const presentValue = outputCount > 1 && pastValue; const kvNumHeads = params.kvNumHeads ? params.kvNumHeads : params.numHeads; const presentValueShape = presentValue ? [params.batchSize, kvNumHeads, totalSequenceLength, params.headSize] : void 0; const outputShape = [params.batchSize, params.sequenceLength, repeatedVHiddenSize]; const TILE_SIZE = 12; const dispatch = { x: Math.ceil(params.vHeadSize / TILE_SIZE), y: Math.ceil(params.sequenceLength / TILE_SIZE), z: params.batchSize * params.numHeads }; const programUniforms = [ { type: 12 /* uint32 */, data: params.sequenceLength }, { type: 12 /* uint32 */, data: totalSequenceLength }, { type: 12 /* uint32 */, data: params.vHeadSize }, { type: 12 /* uint32 */, data: params.numHeads }, { type: 12 /* uint32 */, data: params.headSize }, { type: 12 /* uint32 */, data: repeatedVHiddenSize }, { type: 12 /* uint32 */, data: pastSequenceLength }, { type: 12 /* uint32 */, data: params.kvSequenceLength }, { type: 12 /* uint32 */, data: nReps } ]; const feedPastValue = presentValue && pastValue && ShapeUtil2.size(pastValue.dims) > 0; const inputDependencies = ["type", "type"]; if (feedPastValue) { inputDependencies.push("type"); } if (seqLens) { inputDependencies.push("type"); } if (totalSequenceLengthInput) { inputDependencies.push("type"); } const outputs = [{ dims: outputShape, dataType: probs.dataType, gpuDataType: 0 /* default */ }]; if (presentValue) { outputs.push({ dims: presentValueShape, dataType: probs.dataType, gpuDataType: 0 /* default */ }); } const getShaderSource = (shaderHelper) => { const probsHelper = inputVariable("probs", probs.dataType, probs.dims); const vHelper = inputVariable("v", v.dataType, v.dims); const inputVars = [probsHelper, vHelper]; if (feedPastValue) { inputVars.push(inputVariable("past_value", pastValue.dataType, pastValue.dims)); } const seqLensInputVariable = seqLens ? inputVariable("seq_lens", seqLens.dataType, seqLens.dims) : void 0; if (seqLens) { inputVars.push(seqLensInputVariable); } const totalSequenceLengthInputVariable = totalSequenceLengthInput ? inputVariable("total_sequence_length_input", totalSequenceLengthInput.dataType, totalSequenceLengthInput.dims) : void 0; if (totalSequenceLengthInput) { inputVars.push(totalSequenceLengthInputVariable); } const output = outputVariable("output", probs.dataType, outputShape); const outputVars = [output]; if (presentValue) { outputVars.push(outputVariable("present_value", probs.dataType, presentValueShape)); } const uniforms = [ { name: "M", type: "u32" }, { name: "K", type: "u32" }, { name: "N", type: "u32" }, { name: "num_heads", type: "u32" }, { name: "head_size", type: "u32" }, { name: "v_hidden_size", type: "u32" }, { name: "past_sequence_length", type: "u32" }, { name: "kv_sequence_length", type: "u32" }, { name: "n_reps", type: "u32" } ]; return ` const TILE_SIZE = ${TILE_SIZE}u; var tileQ: array<${probsHelper.type.value}, ${TILE_SIZE * TILE_SIZE}>; var tileV: array<${probsHelper.type.value}, ${TILE_SIZE * TILE_SIZE}>; ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVars, ...outputVars)} ${shaderHelper.mainStart([TILE_SIZE, TILE_SIZE, 1])} let headIdx = workgroup_id.z % uniforms.num_heads; let batchIdx = workgroup_id.z / uniforms.num_heads; let kvHeadIdx = ${nReps === 1 ? "headIdx" : "headIdx / uniforms.n_reps"}; let kv_num_heads = ${nReps === 1 ? "uniforms.num_heads" : "uniforms.num_heads / uniforms.n_reps"}; let m = global_id.y; let n = global_id.x; let sequence_length = uniforms.M; var total_sequence_length = uniforms.K; ${initVarStub(seqLensInputVariable, totalSequenceLengthInputVariable, true)} let offsetA = workgroup_id.z * uniforms.M * uniforms.K + m * uniforms.K; let absKvHeadIdx = batchIdx * kv_num_heads + kvHeadIdx; // kvHeadIdx is relative to the batch ${feedPastValue && presentValue ? "let pastValueOffset = absKvHeadIdx * uniforms.N * uniforms.past_sequence_length + n;" : ""}; let vOffset = absKvHeadIdx * uniforms.N * uniforms.kv_sequence_length + n; ${presentValue ? "let presentValueOffset = absKvHeadIdx * uniforms.N * uniforms.K + n;" : ""} var value = ${probsHelper.type.storage}(0); for (var w: u32 = 0u; w < uniforms.K; w += TILE_SIZE) { if (m < uniforms.M && w + local_id.x < uniforms.K) { tileQ[TILE_SIZE * local_id.y + local_id.x] = probs[offsetA + w + local_id.x]; } if (n < uniforms.N && w + local_id.y < uniforms.K) { var idx = TILE_SIZE * local_id.y + local_id.x; ${(() => { if (feedPastValue && presentValue) { return ` if (w + local_id.y < past_sequence_length) { tileV[idx] = past_value[pastValueOffset + (w + local_id.y) * uniforms.N]; } else if (w + local_id.y - past_sequence_length < uniforms.kv_sequence_length) { tileV[idx] = v[vOffset + (w + local_id.y - past_sequence_length) * uniforms.N]; } `; } else { return ` if (w + local_id.y < uniforms.kv_sequence_length) { tileV[idx] = v[vOffset + (w + local_id.y) * uniforms.N]; }`; } })()} ${presentValue ? ` if (w + local_id.y < present_sequence_length) { present_value[presentValueOffset + (w + local_id.y) * uniforms.N] = tileV[idx]; }` : ""} } workgroupBarrier(); for (var k: u32 = 0u; k < TILE_SIZE && w+k < total_sequence_length; k++) { value += tileQ[TILE_SIZE * local_id.y + k] * tileV[TILE_SIZE * k + local_id.x]; } workgroupBarrier(); } // we need to transpose output from BNSH_v to BSND_v if (m < uniforms.M && n < uniforms.N) { let outputIdx = batchIdx * uniforms.M * uniforms.v_hidden_size + m * uniforms.v_hidden_size + headIdx * uniforms.N + n; output[outputIdx] = value; } }`; }; return { name: "AttentionScore", shaderCache: { hint: `${pastValue !== void 0};${outputCount}`, inputDependencies }, getRunData: () => ({ outputs, dispatchGroup: dispatch, programUniforms }), getShaderSource }; }; applyAttention = (context, q, k, v, _maskIndex, _past, pastKey, pastValue, attentionBiasInput, parameters, seqLens = void 0, totalSequenceLengthInput = void 0) => { const outputCount = Math.min(context.outputCount, 1 + (pastKey ? 1 : 0) + (pastValue ? 1 : 0)); const effectivePastKey = outputCount > 1 ? pastKey : void 0; const effectivePastValue = outputCount > 1 ? pastValue : void 0; const pastSequenceLength = outputCount > 1 ? parameters.pastSequenceLength : 0; const totalSequenceLength = pastSequenceLength + parameters.kvSequenceLength; const attentionBias = attentionBiasInput && ShapeUtil2.size(attentionBiasInput.dims) > 0 ? attentionBiasInput : void 0; const inputsK = [q, k]; if (effectivePastKey && ShapeUtil2.size(effectivePastKey.dims) > 0) { inputsK.push(effectivePastKey); } if (attentionBias) { inputsK.push(attentionBias); } if (seqLens) { inputsK.push(seqLens); } if (totalSequenceLengthInput) { inputsK.push(totalSequenceLengthInput); } const probs = context.compute( createAttentionProbsProgramInfo( outputCount, q, k, effectivePastKey, attentionBias, parameters, pastSequenceLength, seqLens, totalSequenceLengthInput ), { inputs: inputsK, outputs: outputCount > 1 ? [-1, 1] : [-1] } )[0]; context.compute( createInPlaceSoftmaxProgramInfo( probs, parameters.batchSize, parameters.numHeads, pastSequenceLength, parameters.sequenceLength, totalSequenceLength, seqLens, totalSequenceLengthInput ), { inputs: seqLens && totalSequenceLengthInput ? [probs, seqLens, totalSequenceLengthInput] : [probs], outputs: [] } ); const inputsV = [probs, v]; if (effectivePastValue && ShapeUtil2.size(effectivePastValue.dims) > 0) { inputsV.push(effectivePastValue); } if (seqLens) { inputsV.push(seqLens); } if (totalSequenceLengthInput) { inputsV.push(totalSequenceLengthInput); } context.compute( createVxAttentionScoreProgramInfo( outputCount, probs, v, effectivePastValue, parameters, pastSequenceLength, seqLens, totalSequenceLengthInput ), { inputs: inputsV, outputs: outputCount > 1 ? [0, 2] : [0] } ); }; prepare = (context, parameters) => { const outputShape = [parameters.batchSize, parameters.numHeads, parameters.sequenceLength, parameters.headSize]; const M = parameters.sequenceLength; const K = parameters.inputHiddenSize; const N = parameters.headSize; const TILE_SIZE = 12; const dispatch = { x: Math.ceil(parameters.headSize / TILE_SIZE), y: Math.ceil(parameters.sequenceLength / TILE_SIZE), z: parameters.batchSize * parameters.numHeads }; const inputs = [context.inputs[0], context.inputs[1], context.inputs[2]]; const programUniforms = [ { type: 12 /* uint32 */, data: M }, { type: 12 /* uint32 */, data: K }, { type: 12 /* uint32 */, data: N }, { type: 12 /* uint32 */, data: parameters.numHeads }, { type: 12 /* uint32 */, data: parameters.headSize }, { type: 12 /* uint32 */, data: parameters.hiddenSize }, { type: 12 /* uint32 */, data: parameters.hiddenSize + parameters.hiddenSize + parameters.vHiddenSize } ]; const getShaderSource = (shaderHelper) => { const outputQ = outputVariable("output_q", inputs[0].dataType, outputShape); const outputK = outputVariable("output_k", inputs[0].dataType, outputShape); const outputV = outputVariable("output_v", inputs[0].dataType, outputShape); const input = inputVariable("input", inputs[0].dataType, inputs[0].dims); const weight = inputVariable("weight", inputs[1].dataType, inputs[1].dims); const bias = inputVariable("bias", inputs[2].dataType, inputs[2].dims); const dataType = input.type.storage; const uniforms = [ { name: "M", type: "u32" }, { name: "K", type: "u32" }, { name: "N", type: "u32" }, { name: "num_heads", type: "u32" }, { name: "head_size", type: "u32" }, { name: "hidden_size", type: "u32" }, { name: "ldb", type: "u32" } ]; return ` const TILE_SIZE = ${TILE_SIZE}u; var tileInput: array<${dataType}, ${TILE_SIZE * TILE_SIZE}>; var tileWeightQ: array<${dataType}, ${TILE_SIZE * TILE_SIZE}>; var tileWeightK: array<${dataType}, ${TILE_SIZE * TILE_SIZE}>; var tileWeightV: array<${dataType}, ${TILE_SIZE * TILE_SIZE}>; ${shaderHelper.registerUniforms(uniforms).declareVariables(input, weight, bias, outputQ, outputK, outputV)} ${shaderHelper.mainStart([TILE_SIZE, TILE_SIZE, 1])} let batchIndex = workgroup_id.z / uniforms.num_heads; let headNumber = workgroup_id.z % uniforms.num_heads; let m = global_id.y; let n = global_id.x; let inputOffset = batchIndex * (uniforms.M * uniforms.K) + m * uniforms.K; let biasOffsetQ = headNumber * uniforms.head_size; let biasOffsetK = uniforms.hidden_size + biasOffsetQ; let biasOffsetV = uniforms.hidden_size + biasOffsetK; var valueQ = ${dataType}(0); var valueK = ${dataType}(0); var valueV = ${dataType}(0); for (var w: u32 = 0u; w < uniforms.K; w += TILE_SIZE) { if (m < uniforms.M && w + local_id.x < uniforms.K) { tileInput[TILE_SIZE * local_id.y + local_id.x] = input[inputOffset + w + local_id.x]; } if (n < uniforms.N && w + local_id.y < uniforms.K) { let offset = n + (w + local_id.y) * uniforms.ldb; tileWeightQ[TILE_SIZE * local_id.y + local_id.x] = weight[biasOffsetQ + offset]; tileWeightK[TILE_SIZE * local_id.y + local_id.x] = weight[biasOffsetK + offset]; tileWeightV[TILE_SIZE * local_id.y + local_id.x] = weight[biasOffsetV + offset]; } workgroupBarrier(); for (var k: u32 = 0u; k ({ outputs: [ { dims: outputShape, dataType: context.inputs[0].dataType, gpuDataType: 0 /* default */ }, { dims: outputShape, dataType: context.inputs[0].dataType, gpuDataType: 0 /* default */ }, { dims: outputShape, dataType: context.inputs[0].dataType, gpuDataType: 0 /* default */ } ], dispatchGroup: dispatch, programUniforms }), getShaderSource }, { inputs, outputs: [-1, -1, -1] } ); }; attention = (context, attributes) => { const params = validateAttentionInputs(context.inputs, attributes); const [q, k, v] = prepare(context, params); return applyAttention( context, q, k, v, context.inputs[4], void 0, void 0, void 0, context.inputs[5], params ); }; } }); // web/lib/wasm/jsep/webgpu/ops/batch-norm.ts var validateInputs29, createBatchNormInferenceProgramInfo, parseBatchNormAttributes, batchNorm; var init_batch_norm = __esm({ "web/lib/wasm/jsep/webgpu/ops/batch-norm.ts"() { "use strict"; init_esm(); init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateInputs29 = (inputs, attributes) => { if (!inputs || inputs.length !== 5) { throw new Error("BatchNormalization requires 5 inputs"); } const checkShapeEqual = (actual, expected, message) => { const r = expected.length; if (r !== actual.length) { throw new Error(`${message}: num dimensions != ${r}`); } expected.forEach((v, i) => { if (v !== actual[i]) { throw new Error(`${message}: dim[${i}] do not match`); } }); }; if (inputs[0].dims.length > 1) { const shape2 = attributes.format === "NHWC" ? attributes.spatial ? inputs[0].dims.slice(-1) : inputs[0].dims.slice(-1).concat(inputs[0].dims.slice(1, inputs[0].dims.length - 1)) : inputs[0].dims.slice(1, attributes.spatial ? 2 : void 0); checkShapeEqual(inputs[1].dims, shape2, "Invalid input scale"); checkShapeEqual(inputs[2].dims, shape2, "Invalid input B"); checkShapeEqual(inputs[3].dims, shape2, "Invalid input mean"); checkShapeEqual(inputs[4].dims, shape2, "Invalid input var"); } else { checkShapeEqual(inputs[1].dims, [1], "Invalid input scale"); checkShapeEqual(inputs[2].dims, [1], "Invalid input B"); checkShapeEqual(inputs[3].dims, [1], "Invalid input mean"); checkShapeEqual(inputs[4].dims, [1], "Invalid input var"); } }; createBatchNormInferenceProgramInfo = (inputs, attributes) => { const { epsilon, spatial, format } = attributes; const yShape = inputs[0].dims; const components = spatial ? getMaxComponents(yShape[yShape.length - 1]) : 1; const cComponents = format === "NHWC" && yShape.length > 1 ? components : 1; const outputSize = ShapeUtil2.size(yShape) / components; const useShapesUniforms = spatial; const shapeOrRank = useShapesUniforms ? yShape.length : yShape; const x = inputVariable("x", inputs[0].dataType, inputs[0].dims, components); const scale = inputVariable("scale", inputs[1].dataType, inputs[1].dims, cComponents); const bias = inputVariable("bias", inputs[2].dataType, inputs[2].dims, cComponents); const inputMean = inputVariable("inputMean", inputs[3].dataType, inputs[3].dims, cComponents); const inputVar = inputVariable("inputVar", inputs[4].dataType, inputs[4].dims, cComponents); const y = outputVariable("y", inputs[0].dataType, shapeOrRank, components); const calcCOffset = () => { let cOffset = ""; if (spatial) { cOffset = `let cOffset = ${yShape.length === 1 ? "0u" : format === "NHWC" ? `outputIndices[${yShape.length - 1}] / ${components}` : "outputIndices[1]"};`; } else { if (format === "NCHW") { cOffset = ` ${y.indicesSet("outputIndices", "0", "0")} let cOffset = ${y.indicesToOffset("outputIndices")};`; } else { cOffset = `var cIndices = ${scale.type.indices}(0); cIndices[0] = outputIndices[${yShape.length - 1}];`; for (let i = 1; i < scale.rank; i++) { cOffset += `cIndices[${i}] = outputIndices[${i}];`; } cOffset += `let cOffset = ${scale.indicesToOffset("cIndices")};`; } } return cOffset; }; const getInferenceModeShaderSource = (helper) => ` const epsilon = ${epsilon}; ${helper.registerUniform("outputSize", "u32").declareVariables(x, scale, bias, inputMean, inputVar, y)} ${helper.mainStart()} ${helper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} var outputIndices = ${y.offsetToIndices(`global_idx * ${components}`)}; ${calcCOffset()} let scale = ${scale.getByOffset("cOffset")}; let bias = ${bias.getByOffset("cOffset")}; let inputMean = ${inputMean.getByOffset("cOffset")}; let inputVar = ${inputVar.getByOffset("cOffset")}; let x = ${x.getByOffset("global_idx")}; let value = (x - inputMean) * inverseSqrt(inputVar + epsilon) * scale + bias; ${y.setByOffset("global_idx", "value")} }`; return { name: "BatchNormalization", shaderCache: { hint: `${attributes.epsilon}_${attributes.format}_${spatial}_${components}`, inputDependencies: useShapesUniforms ? ["rank", "type", "type", "type", "type"] : void 0 }, getShaderSource: getInferenceModeShaderSource, getRunData: () => ({ outputs: [{ dims: inputs[0].dims, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms: useShapesUniforms ? [{ type: 12 /* uint32 */, data: outputSize }, ...createTensorShapeVariables(yShape)] : [{ type: 12 /* uint32 */, data: outputSize }] }) }; }; parseBatchNormAttributes = (attributes) => createAttributeWithCacheKey2(attributes); batchNorm = (context, attributes) => { const { inputs, outputCount } = context; const updatedAttributes = parseBatchNormAttributes({ ...attributes, outputCount }); if (env2.webgpu.validateInputContent) { validateInputs29(inputs, updatedAttributes); } if (attributes.trainingMode) { throw new Error("BatchNormalization trainingMode is not supported yet."); } else { context.compute(createBatchNormInferenceProgramInfo(inputs, updatedAttributes)); } }; } }); // web/lib/wasm/jsep/webgpu/ops/bias-add.ts var validateInputs30, createBiasAddProgramInfo, biasAdd; var init_bias_add = __esm({ "web/lib/wasm/jsep/webgpu/ops/bias-add.ts"() { "use strict"; init_util2(); init_common(); validateInputs30 = (inputs) => { if (inputs[0].dims.length !== 3) { throw new Error("input should have 3 dimensions"); } if (![320, 640, 1280].includes(inputs[0].dims[2])) { throw new Error("number of channels should be 320, 640 or 1280"); } if (inputs[1].dims.length !== 1) { throw new Error("bias is expected to have 1 dimensions"); } if (inputs[0].dims[2] !== inputs[1].dims[0]) { throw new Error("last dimension of input and bias are not the same"); } }; createBiasAddProgramInfo = (inputs) => { const outputShape = inputs[0].dims; const channels = inputs[0].dims[2]; const outputSize = ShapeUtil2.size(outputShape) / 4; const dataType = inputs[0].dataType; const input = inputVariable("input", dataType, outputShape, 4); const bias = inputVariable("bias", dataType, [channels], 4); const residual = inputVariable("residual", dataType, outputShape, 4); const output = outputVariable("output", dataType, outputShape, 4); const getShaderSource = (shaderHelper) => ` const channels = ${channels}u / 4; ${shaderHelper.declareVariables(input, bias, residual, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes(outputSize)} let value = ${input.getByOffset("global_idx")} + ${bias.getByOffset("global_idx % channels")} + ${residual.getByOffset("global_idx")}; ${output.setByOffset("global_idx", "value")} }`; return { name: "BiasAdd", getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) } }), getShaderSource }; }; biasAdd = (context) => { validateInputs30(context.inputs); context.compute(createBiasAddProgramInfo(context.inputs)); }; } }); // web/lib/wasm/jsep/webgpu/ops/unary-op.ts var createElementwiseProgramShader, createElementwiseProgramInfo2, abs2, acos2, acosh, asin2, asinh, atan2, atanh, parseCastAttributes2, cast2, generateClipAttributesFromInputs2, clip2, ceil2, cos2, cosh, parseAlphaAttributes, elu2, erfImpl, erf, exp2, floor2, gelu, leakyRelu2, not3, neg2, reciprocal, relu2, sigmoid2, parseHardSigmoidAttributes, hardSigmoid, sin2, sinh, sqrt2, tan2, tanhExpression, tanh2, fastGeluImpl, fastGeluExpression, fastGelu, thresholdedRelu, log3, quickGeluImpl, quickGeluExpression, quickgelu; var init_unary_op2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/unary-op.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); createElementwiseProgramShader = (shaderHelper, datasize, inputDataType, outputDataType, funcCall, additionalImplementation, additionalUniformsType) => { const vecSize = Math.ceil(datasize / 4); let expression = ""; if (typeof funcCall === "string") { expression = `${funcCall}(a)`; } else { expression = funcCall("a"); } const input = inputVariable("inputData", inputDataType, [vecSize], 4); const output = outputVariable("outputData", outputDataType, [vecSize], 4); const uniforms = [{ name: "vec_size", type: "u32" }]; if (additionalUniformsType) { uniforms.push(...additionalUniformsType); } return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(input, output)} ${additionalImplementation ?? ""} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.vec_size")} let a = ${input.getByOffset("global_idx")}; ${output.setByOffset("global_idx", expression)} }`; }; createElementwiseProgramInfo2 = (input, name2, funcCall, additionalImplementation, cacheKey, outputDataType = input.dataType, additionalUniforms, additionalUniformsType) => { const programUniforms = [ { type: 12 /* uint32 */, data: Math.ceil(ShapeUtil2.size(input.dims) / 4) } ]; if (additionalUniforms) { programUniforms.push(...additionalUniforms); } return { name: name2, shaderCache: { hint: cacheKey, inputDependencies: ["type"] }, getShaderSource: (shaderHelper) => createElementwiseProgramShader( shaderHelper, ShapeUtil2.size(input.dims), input.dataType, outputDataType, funcCall, additionalImplementation, additionalUniformsType ), getRunData: (inputTensors) => ({ outputs: [{ dims: input.dims, dataType: outputDataType }], dispatchGroup: { x: Math.ceil( ShapeUtil2.size(inputTensors[0].dims) / 64 / 4 /* vec size */ ) }, programUniforms }) }; }; abs2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Abs", "abs")); }; acos2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Acos", "acos")); }; acosh = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Acosh", "acosh")); }; asin2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Asin", "asin")); }; asinh = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Asinh", "asinh")); }; atan2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Atan", "atan")); }; atanh = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Atanh", "atanh")); }; parseCastAttributes2 = (attributes) => createAttributeWithCacheKey2(attributes); cast2 = (context, attributes) => { let func; switch (attributes.to) { case 10 /* float16 */: func = "vec4"; break; case 1 /* float */: func = "vec4"; break; case 12 /* uint32 */: func = "vec4"; break; case 6 /* int32 */: func = "vec4"; break; case 9 /* bool */: func = "vec4"; break; default: throw new RangeError(`not supported type (specified in attribute 'to' from 'Cast' operator): ${attributes.to}`); } context.compute( createElementwiseProgramInfo2(context.inputs[0], "Cast", func, void 0, attributes.cacheKey, attributes.to) ); }; generateClipAttributesFromInputs2 = (inputs) => { let min; let max; const hasMin = inputs.length >= 2 && inputs[1].data !== 0; const hasMax = inputs.length >= 3 && inputs[2].data !== 0; switch (inputs[0].dataType) { case 1 /* float */: min = hasMin ? inputs[1].getFloat32Array()[0] : -34028234663852886e22; max = hasMax ? inputs[2].getFloat32Array()[0] : 34028234663852886e22; break; case 10 /* float16 */: min = hasMin ? inputs[1].getUint16Array()[0] : 64511; max = hasMax ? inputs[2].getUint16Array()[0] : 31743; break; default: throw new Error("Unsupport data type"); } return createAttributeWithCacheKey2({ min, max }); }; clip2 = (context, clipAttributes) => { const attributes = clipAttributes ? clipAttributes : generateClipAttributesFromInputs2(context.inputs); const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); context.compute( createElementwiseProgramInfo2( context.inputs[0], "Clip", (a) => `clamp(${a}, vec4<${dataType}>(uniforms.min), vec4<${dataType}>(uniforms.max))`, void 0, attributes.cacheKey, void 0, [ { type: context.inputs[0].dataType, data: attributes.min }, { type: context.inputs[0].dataType, data: attributes.max } ], [ { name: "min", type: dataType }, { name: "max", type: dataType } ] ), { inputs: [0] } ); }; ceil2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Ceil", "ceil")); }; cos2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Cos", "cos")); }; cosh = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Cosh", "cosh")); }; parseAlphaAttributes = (attributes) => createAttributeWithCacheKey2(attributes); elu2 = (context, attributes) => { const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); context.compute( createElementwiseProgramInfo2( context.inputs[0], "Elu", (a) => `elu_vf32(${a})`, ` const elu_alpha_ = ${dataType}(${attributes.alpha}); fn elu_f32(a: ${dataType}) -> ${dataType} { return select((exp(a) - 1.0) * elu_alpha_, a, a >= 0.0); } fn elu_vf32(v: vec4<${dataType}>) -> vec4<${dataType}> { return vec4(elu_f32(v.x), elu_f32(v.y), elu_f32(v.z), elu_f32(v.w)); }`, attributes.cacheKey ) ); }; erfImpl = (varType = "f32") => ` const r0: ${varType} = 0.3275911; const r1: ${varType} = 0.254829592; const r2: ${varType} = -0.284496736; const r3: ${varType} = 1.421413741; const r4: ${varType} = -1.453152027; const r5: ${varType} = 1.061405429; fn erf_vf32(v: vec4<${varType}>) -> vec4<${varType}> { let absv = abs(v); let x = 1.0 / (1.0 + r0 * absv); return sign(v) * (1.0 - ((((r5 * x + r4) * x + r3) * x + r2) * x + r1) * x * exp(-absv * absv)); }`; erf = (context) => { const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); context.compute(createElementwiseProgramInfo2(context.inputs[0], "Erf", (a) => `erf_vf32(${a})`, erfImpl(dataType))); }; exp2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Exp", "exp")); }; floor2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Floor", "floor")); }; gelu = (context) => { const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); context.compute( createElementwiseProgramInfo2( context.inputs[0], "Gelu", (a) => `0.5 * ${a} * (1.0 + erf_vf32(${a} * 0.7071067811865475))`, erfImpl(dataType) ) ); }; leakyRelu2 = (context, attributes) => { const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); context.compute( createElementwiseProgramInfo2( context.inputs[0], "LeakyRelu", (a) => `select(leaky_relu_alpha_ * ${a}, ${a}, ${a} >= vec4<${dataType}>(0.0))`, `const leaky_relu_alpha_ = ${dataType}(${attributes.alpha});`, attributes.cacheKey ) ); }; not3 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Not", (a) => `!${a}`)); }; neg2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Neg", (a) => `-${a}`)); }; reciprocal = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Reciprocal", (a) => `1.0/${a}`)); }; relu2 = (context) => { const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); context.compute( createElementwiseProgramInfo2( context.inputs[0], "Relu", (a) => `select(vec4<${dataType}>(0.0), ${a}, ${a} > vec4<${dataType}>(0.0))` ) ); }; sigmoid2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Sigmoid", (a) => `(1.0 / (1.0 + exp(-${a})))`)); }; parseHardSigmoidAttributes = (attributes) => createAttributeWithCacheKey2( attributes ); hardSigmoid = (context, attributes) => { const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); context.compute( createElementwiseProgramInfo2( context.inputs[0], "HardSigmoid", (a) => `max(vec4<${dataType}>(0.0), min(vec4<${dataType}>(1.0), ${attributes.alpha} * ${a} + vec4<${dataType}>(${attributes.beta})))`, void 0, attributes.cacheKey ) ); }; sin2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Sin", "sin")); }; sinh = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Sinh", "sinh")); }; sqrt2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Sqrt", "sqrt")); }; tan2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Tan", "tan")); }; tanhExpression = (a) => `sign(${a}) * (1 - exp(-2 * abs(${a}))) / (1 + exp(-2 * abs(${a})))`; tanh2 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Tanh", tanhExpression)); }; fastGeluImpl = (varType = "f32") => ` const fast_gelu_a: ${varType} = 0.5; const fast_gelu_b: ${varType} = 0.7978845608028654; const fast_gelu_c: ${varType} = 0.035677408136300125; fn tanh_v(v: vec4<${varType}>) -> vec4<${varType}> { return ${tanhExpression("v")}; } `; fastGeluExpression = (x) => `(fast_gelu_a + fast_gelu_a * tanh_v(${x} * (fast_gelu_c * ${x} * ${x} + fast_gelu_b))) * ${x}`; fastGelu = (context) => { const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); context.compute( createElementwiseProgramInfo2( context.inputs[0], "FastGelu", fastGeluExpression, fastGeluImpl(dataType), void 0, context.inputs[0].dataType ) ); }; thresholdedRelu = (context, attributes) => { const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); context.compute( createElementwiseProgramInfo2( context.inputs[0], "ThresholdedRelu", (a) => `select(vec4<${dataType}>(0.0), ${a}, ${a} > thresholded_relu_alpha_)`, `const thresholded_relu_alpha_ = vec4<${dataType}>(${attributes.alpha});`, attributes.cacheKey ) ); return 0; }; log3 = (context) => { context.compute(createElementwiseProgramInfo2(context.inputs[0], "Log", "log")); }; quickGeluImpl = (varType, alpha) => ` const alpha = vec4<${varType}>(${alpha}); const one = ${varType}(1.0); const zero = ${varType}(0.0); fn quick_gelu_impl(x: vec4<${varType}>) -> vec4<${varType}> { let v = x *alpha; var x1 : vec4<${varType}>; for (var i = 0; i < 4; i = i + 1) { if (v[i] >= zero) { x1[i] = one / (one + exp(-v[i])); } else { x1[i] = one - one / (one + exp(v[i])); } } return x * x1; } `; quickGeluExpression = (x) => `quick_gelu_impl(${x})`; quickgelu = (context, attributes) => { const dType = tensorTypeToWsglValueType(context.inputs[0].dataType); context.compute( createElementwiseProgramInfo2( context.inputs[0], "QuickGelu", quickGeluExpression, quickGeluImpl(dType, attributes.alpha), attributes.cacheKey, context.inputs[0].dataType ) ); }; } }); // web/lib/wasm/jsep/webgpu/ops/bias-split-gelu.ts var validateInputs31, createBiasSplitGeluProgramInfo, biasSplitGelu; var init_bias_split_gelu = __esm({ "web/lib/wasm/jsep/webgpu/ops/bias-split-gelu.ts"() { "use strict"; init_util2(); init_common(); init_unary_op2(); validateInputs31 = (inputs) => { if (inputs[0].dims.length !== 3) { throw new Error("input should have 3 dimensions"); } if (![2560, 5120, 10240].includes(inputs[0].dims[2])) { throw new Error("hidden state should be 2560, 5120 or 10240"); } if (inputs[1].dims.length !== 1) { throw new Error("bias is expected to have 1 dimensions"); } if (inputs[0].dims[2] !== inputs[1].dims[0]) { throw new Error("last dimension of input and bias are not the same"); } }; createBiasSplitGeluProgramInfo = (inputs) => { const outputShape = inputs[0].dims.slice(); outputShape[2] = outputShape[2] / 2; const input = inputVariable("input", inputs[0].dataType, inputs[0].dims, 4); const bias = inputVariable("bias", inputs[0].dataType, [inputs[0].dims[2]], 4); const output = outputVariable("output", inputs[0].dataType, outputShape, 4); const outputSize = ShapeUtil2.size(outputShape) / 4; const dataType = tensorTypeToWsglStorageType(inputs[0].dataType); const getShaderSource = (shaderHelper) => ` const M_SQRT2 = sqrt(2.0); const halfChannels = ${inputs[0].dims[2] / 4 / 2}u; ${shaderHelper.declareVariables(input, bias, output)} ${erfImpl(dataType)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes(outputSize)} let biasIdx = global_idx % halfChannels; let batchIndex = global_idx / halfChannels; let inputOffset = biasIdx + batchIndex * halfChannels * 2; let valueLeft = input[inputOffset] + bias[biasIdx]; let valueRight = input[inputOffset + halfChannels] + bias[biasIdx + halfChannels]; let geluRight = valueRight * 0.5 * (erf_vf32(valueRight / M_SQRT2) + 1); ${output.setByOffset("global_idx", "valueLeft * geluRight")} }`; return { name: "BiasSplitGelu", getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) } }), getShaderSource }; }; biasSplitGelu = (context) => { validateInputs31(context.inputs); context.compute(createBiasSplitGeluProgramInfo(context.inputs)); }; } }); // web/lib/wasm/jsep/webgpu/ops/binary-op.ts var createBinaryOpProgramShader, createBinaryOpProgramInfo, runBinaryOp, add3, div2, equal2, mul2, pow2, sub2, greater2, less2, greaterOrEqual, lessOrEqual; var init_binary_op2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/binary-op.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); createBinaryOpProgramShader = (shaderHelper, dimsA, dimsB, dimsOutput, vectorize, doBroadcast, sharedDimensionDivisibleBy4, funcCall, typeA, typeB, typeOutput, additionalImplementation) => { let expressionScalar; let expressionVector; if (typeof funcCall === "string") { expressionScalar = expressionVector = (a2, b2) => `${funcCall}((${a2}),(${b2}))`; } else if (typeof funcCall === "function") { expressionScalar = expressionVector = funcCall; } else { expressionScalar = funcCall.scalar; expressionVector = funcCall.vector; } const output = outputVariable("outputData", typeOutput, dimsOutput.length, 4); const a = inputVariable("aData", typeA, dimsA.length, 4); const b = inputVariable("bData", typeB, dimsB.length, 4); let assignment; if (vectorize) { if (doBroadcast) { const isAOneElement = ShapeUtil2.size(dimsA) === 1; const isBOneElement = ShapeUtil2.size(dimsB) === 1; const aLastDimDivisibleBy4 = dimsA.length > 0 && dimsA[dimsA.length - 1] % 4 === 0; const bLastDimDivisibleBy4 = dimsB.length > 0 && dimsB[dimsB.length - 1] % 4 === 0; if (isAOneElement || isBOneElement) { assignment = output.setByOffset( "global_idx", expressionVector( isAOneElement ? `${a.type.value}(${a.getByOffset("0")}.x)` : a.getByOffset("global_idx"), isBOneElement ? `${b.type.value}(${b.getByOffset("0")}.x)` : b.getByOffset("global_idx") ) ); } else { assignment = ` let outputIndices = ${output.offsetToIndices("global_idx * 4u")}; let offsetA = ${a.broadcastedIndicesToOffset("outputIndices", output)}; let offsetB = ${b.broadcastedIndicesToOffset("outputIndices", output)}; ${output.setByOffset( "global_idx", expressionVector( sharedDimensionDivisibleBy4 || aLastDimDivisibleBy4 ? a.getByOffset("offsetA / 4u") : `${a.type.value}(${a.getByOffset("offsetA / 4u")}[offsetA % 4u])`, sharedDimensionDivisibleBy4 || bLastDimDivisibleBy4 ? b.getByOffset("offsetB / 4u") : `${b.type.value}(${b.getByOffset("offsetB / 4u")}[offsetB % 4u])` ) )} `; } } else { assignment = output.setByOffset( "global_idx", expressionVector(a.getByOffset("global_idx"), b.getByOffset("global_idx")) ); } } else { if (!doBroadcast) { throw new Error("no necessary to use scalar implementation for element-wise binary op implementation."); } const singleAssignment = (resStr, x, typeCast = "") => { const expressionA = `aData[indexA${x}][componentA${x}]`; const expressionB = `bData[indexB${x}][componentB${x}]`; return ` let outputIndices${x} = ${output.offsetToIndices(`global_idx * 4u + ${x}u`)}; let offsetA${x} = ${a.broadcastedIndicesToOffset(`outputIndices${x}`, output)}; let offsetB${x} = ${b.broadcastedIndicesToOffset(`outputIndices${x}`, output)}; let indexA${x} = offsetA${x} / 4u; let indexB${x} = offsetB${x} / 4u; let componentA${x} = offsetA${x} % 4u; let componentB${x} = offsetB${x} % 4u; ${resStr}[${x}] = ${typeCast}(${expressionScalar(expressionA, expressionB)}); `; }; if (typeOutput === 9 /* bool */) { assignment = ` var data = vec4(0); ${singleAssignment("data", 0, "u32")} ${singleAssignment("data", 1, "u32")} ${singleAssignment("data", 2, "u32")} ${singleAssignment("data", 3, "u32")} outputData[global_idx] = dot(vec4(0x1, 0x100, 0x10000, 0x1000000), vec4(data));`; } else { assignment = ` ${singleAssignment("outputData[global_idx]", 0)} ${singleAssignment("outputData[global_idx]", 1)} ${singleAssignment("outputData[global_idx]", 2)} ${singleAssignment("outputData[global_idx]", 3)} `; } } return ` ${shaderHelper.registerUniform("vec_size", "u32").declareVariables(a, b, output)} ${additionalImplementation ?? ""} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.vec_size")} ${assignment} }`; }; createBinaryOpProgramInfo = (name2, cacheKey, a, b, funcCall, additionalImplementation, outputDataType = a.dataType) => { const aDims = a.dims.map(Number); const bDims = b.dims.map(Number); const isBroadcast = !ShapeUtil2.areEqual(aDims, bDims); let outputShape = aDims; let outputSize = ShapeUtil2.size(aDims); let vectorize = false; let sharedDimensionDivisibleBy4 = false; const cacheKeyAux = [isBroadcast]; if (isBroadcast) { const calculatedShape = BroadcastUtil2.calcShape(aDims, bDims, false); if (!calculatedShape) { throw new Error("Can't perform binary op on the given tensors"); } outputShape = calculatedShape.slice(); outputSize = ShapeUtil2.size(outputShape); const isAOneElement = ShapeUtil2.size(aDims) === 1; const isBOneElement = ShapeUtil2.size(bDims) === 1; const aLastDimDivisibleBy4 = aDims.length > 0 && aDims[aDims.length - 1] % 4 === 0; const bLastDimDivisibleBy4 = bDims.length > 0 && bDims[bDims.length - 1] % 4 === 0; cacheKeyAux.push(isAOneElement); cacheKeyAux.push(isBOneElement); cacheKeyAux.push(aLastDimDivisibleBy4); cacheKeyAux.push(bLastDimDivisibleBy4); let sharedDimension = 1; for (let i = 1; i < outputShape.length; i++) { const dimA = aDims[aDims.length - i]; const dimB = bDims[bDims.length - i]; if (dimA === dimB) { sharedDimension *= dimA; } else { break; } } if (sharedDimension % 4 === 0) { sharedDimensionDivisibleBy4 = true; vectorize = true; } else if (isAOneElement || isBOneElement || aLastDimDivisibleBy4 || bLastDimDivisibleBy4) { vectorize = true; } } else { vectorize = true; } cacheKeyAux.push(vectorize); return { name: name2, shaderCache: { hint: cacheKey + cacheKeyAux.map((x) => x.toString()).join("_"), inputDependencies: ["rank", "rank"] }, getShaderSource: (shaderHelper) => createBinaryOpProgramShader( shaderHelper, aDims, bDims, outputShape, vectorize, isBroadcast, sharedDimensionDivisibleBy4, funcCall, a.dataType, b.dataType, outputDataType, additionalImplementation ), getRunData: () => ({ outputs: [{ dims: outputShape, dataType: outputDataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 / 4 /* component size */ ) }, programUniforms: [ { type: 12 /* uint32 */, data: Math.ceil(ShapeUtil2.size(outputShape) / 4) }, ...createTensorShapeVariables(aDims, bDims, outputShape) ] }) }; }; runBinaryOp = (context, name2, funcCall, additionalImplementation, cacheKey, outputDataType) => { context.compute( createBinaryOpProgramInfo( name2, cacheKey ?? "", context.inputs[0], context.inputs[1], funcCall, additionalImplementation, outputDataType ) ); }; add3 = (context) => { runBinaryOp(context, "Add", (a, b) => `${a}+${b}`); }; div2 = (context) => { runBinaryOp(context, "Div", (a, b) => `${a}/${b}`); }; equal2 = (context) => { runBinaryOp( context, "Equal", { scalar: (a, b) => `u32(${a}==${b})`, vector: (a, b) => `vec4(${a}==${b})` }, void 0, void 0, 9 /* bool */ ); }; mul2 = (context) => { runBinaryOp(context, "Mul", (a, b) => `${a}*${b}`); }; pow2 = (context) => { const type = inputVariable("input", context.inputs[0].dataType, context.inputs[0].dims).type.value; const roundStr = type === "i32" ? "round" : ""; runBinaryOp( context, "Pow", { scalar: (a, b) => `pow_custom(${a},${b})`, vector: (a, b) => `pow_vector_custom(${a},${b})` }, ` fn pow_custom(a : ${type}, b : ${type}) -> ${type} { if (b == ${type}(0.0)) { return ${type}(1.0); } else if (a < ${type}(0.0) && f32(b) != floor(f32(b))) { return ${type}(pow(f32(a), f32(b))); // NaN } return select(sign(a), ${type}(1.0), round(f32(abs(b) % ${type}(2.0))) != 1.0) * ${type}(${roundStr}(pow(f32(abs(a)), f32(b)))); } fn pow_vector_custom(a : vec4<${type}>, b : vec4<${type}>) -> vec4<${type}> { // TODO: implement vectorized pow return vec4<${type}>(pow_custom(a.x, b.x), pow_custom(a.y, b.y), pow_custom(a.z, b.z), pow_custom(a.w, b.w)); } ` ); }; sub2 = (context) => { runBinaryOp(context, "Sub", (a, b) => `${a}-${b}`); }; greater2 = (context) => { runBinaryOp( context, "Greater", { scalar: (a, b) => `u32(${a}>${b})`, vector: (a, b) => `vec4(${a}>${b})` }, void 0, void 0, 9 /* bool */ ); }; less2 = (context) => { runBinaryOp( context, "Less", { scalar: (a, b) => `u32(${a}<${b})`, vector: (a, b) => `vec4(${a}<${b})` }, void 0, void 0, 9 /* bool */ ); }; greaterOrEqual = (context) => { runBinaryOp( context, "GreaterOrEqual", { scalar: (a, b) => `u32(${a}>=${b})`, vector: (a, b) => `vec4(${a}>=${b})` }, void 0, void 0, 9 /* bool */ ); }; lessOrEqual = (context) => { runBinaryOp( context, "LessOrEqual", { scalar: (a, b) => `u32(${a}<=${b})`, vector: (a, b) => `vec4(${a}<=${b})` }, void 0, void 0, 9 /* bool */ ); }; } }); // web/lib/wasm/jsep/webgpu/ops/concat.ts var validateInputs32, calculateInputIndexImpl, assignOutputData, createConcatProgramInfo, concat2, parseConcatAttributes2; var init_concat2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/concat.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateInputs32 = (inputs, axis) => { if (!inputs || inputs.length < 1) { throw new Error("too few inputs"); } const referenceIndex = 0; const referenceInput = inputs[referenceIndex]; const inputType = referenceInput.dataType; const inputRank = referenceInput.dims.length; inputs.forEach((input, i) => { if (i === referenceIndex) { return; } if (input.dataType !== inputType) { throw new Error("input tensors should be one type"); } if (input.dims.length !== inputRank) { throw new Error("input tensors should have the same shape"); } input.dims.forEach((dim, i2) => { if (i2 !== axis && dim !== referenceInput.dims[i2]) { throw new Error("non concat dimensions must match"); } }); }); }; calculateInputIndexImpl = (numberOfTensors, sizeInConcatAxisStr) => ` fn calculateInputIndex(index: u32) -> u32 { let sizeInConcatAxis = array(${sizeInConcatAxisStr}); for (var i: u32 = 0u; i < ${numberOfTensors}; i += 1u ) { if (index < sizeInConcatAxis[i]) { return i; } } return ${numberOfTensors}u; }`; assignOutputData = (inputs, output) => { const numberOfTensors = inputs.length; const codeLines = []; for (let i = 0; i < numberOfTensors; ++i) { const returnSnippet = output.setByOffset("global_idx", inputs[i].getByIndices("indices")); if (numberOfTensors === 1) { codeLines.push(returnSnippet); } else if (i === 0) { codeLines.push(`if (inputIndex == ${i}u) { ${returnSnippet} }`); } else if (i === numberOfTensors - 1) { codeLines.push(`else { ${returnSnippet} }`); } else { codeLines.push(`else if (inputIndex == ${i}) { ${returnSnippet} }`); } } return codeLines.join("\n"); }; createConcatProgramInfo = (inputs, adjustedAxis, outputShape, dataType) => { const outputSize = ShapeUtil2.size(outputShape); const sizeInConcatAxis = new Array(inputs.length); const inputVars = new Array(inputs.length); let previousSum = 0; const inputDependencies = []; const inputRanks = []; const programUniforms = [{ type: 12 /* uint32 */, data: outputSize }]; for (let i = 0; i < inputs.length; ++i) { previousSum += inputs[i].dims[adjustedAxis]; sizeInConcatAxis[i] = previousSum; inputRanks.push(inputs[i].dims.length); inputVars[i] = inputVariable(`input${i}`, dataType, inputRanks[i]); inputDependencies.push("rank"); programUniforms.push({ type: 12 /* uint32 */, data: sizeInConcatAxis[i] }); } for (let i = 0; i < inputs.length; ++i) { programUniforms.push(...createTensorShapeVariables(inputs[i].dims)); } programUniforms.push(...createTensorShapeVariables(outputShape)); const output = outputVariable("output", dataType, outputShape.length); const indicesAxis = output.indicesGet("indices", adjustedAxis); const sizeInConcatAxisStr = Array.from(Array(sizeInConcatAxis.length).keys()).map((i) => `uniforms.sizeInConcatAxis${i}`).join(","); const getShaderSource = (shaderHelper) => ` ${(() => { shaderHelper.registerUniform("outputSize", "u32"); for (let i = 0; i < inputs.length; i++) { shaderHelper.registerUniform(`sizeInConcatAxis${i}`, "u32"); } return shaderHelper.declareVariables(...inputVars, output); })()} ${calculateInputIndexImpl(sizeInConcatAxis.length, sizeInConcatAxisStr)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} var indices = ${output.offsetToIndices("global_idx")}; let inputIndex = calculateInputIndex(${indicesAxis}); if (inputIndex != 0u) { let sizeInConcatAxis = array(${sizeInConcatAxisStr}); ${indicesAxis} -= sizeInConcatAxis[inputIndex - 1u]; } ${assignOutputData(inputVars, output)} }`; return { name: "Concat", shaderCache: { hint: `${adjustedAxis}`, inputDependencies }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }; }; concat2 = (context, attributes) => { const inputs = context.inputs; const inputShape = inputs[0].dims; const adjustedAxis = ShapeUtil2.normalizeAxis(attributes.axis, inputShape.length); validateInputs32(inputs, adjustedAxis); const outputShape = inputShape.slice(); outputShape[adjustedAxis] = inputs.reduce( (sum2, input) => sum2 + (input.dims.length > adjustedAxis ? input.dims[adjustedAxis] : 0), 0 ); const nonEmptyInputs = inputs.filter((input) => ShapeUtil2.size(input.dims) > 0); context.compute(createConcatProgramInfo(nonEmptyInputs, adjustedAxis, outputShape, inputs[0].dataType), { inputs: nonEmptyInputs }); }; parseConcatAttributes2 = (attributes) => createAttributeWithCacheKey2({ axis: attributes.axis }); } }); // web/lib/wasm/jsep/webgpu/ops/fuse-utils.ts var getActivationSnippet2, appendActivationUniformsData, appendActivationUniforms, parseInternalActivationAttributes2; var init_fuse_utils2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/fuse-utils.ts"() { "use strict"; init_wasm_common(); init_util2(); getActivationSnippet2 = (attributes, valueType, baseType = "f32") => { switch (attributes.activation) { case "Relu": return `value = max(value, ${valueType}(0.0));`; case "Sigmoid": return `value = (${valueType}(1.0) / (${valueType}(1.0) + exp(-value)));`; case "Clip": return `value = clamp(value, ${valueType}(${baseType}(uniforms.clip_min)), ${valueType}(${baseType}(uniforms.clip_max)));`; case "HardSigmoid": return `value = max(${valueType}(0.0), min(${valueType}(1.0), ${baseType}(uniforms.alpha) * value + ${baseType}(uniforms.beta)));`; case "LeakyRelu": return `value = select(${baseType}(uniforms.alpha) * value, value, value >= ${valueType}(0.0));`; case "Tanh": return `let e2x = exp(-2.0 * abs(value)); value = sign(value) * (1.0 - e2x) / (1.0 + e2x); `; case "": return ""; // TODO: adding other activations that can be fused. default: throw new Error(`Unsupported activation ${attributes.activation}`); } }; appendActivationUniformsData = (attributes, programUniform) => { if (attributes.activation === "Clip") { programUniform.push( { type: 1 /* float */, data: attributes.clipMax }, { type: 1 /* float */, data: attributes.clipMin } ); } else if (attributes.activation === "HardSigmoid") { programUniform.push( { type: 1 /* float */, data: attributes.alpha }, { type: 1 /* float */, data: attributes.beta } ); } else if (attributes.activation === "LeakyRelu") { programUniform.push({ type: 1 /* float */, data: attributes.alpha }); } }; appendActivationUniforms = (attributes, uniforms) => { if (attributes.activation === "Clip") { uniforms.push({ name: "clip_max", type: "f32" }, { name: "clip_min", type: "f32" }); } else if (attributes.activation === "HardSigmoid") { uniforms.push({ name: "alpha", type: "f32" }, { name: "beta", type: "f32" }); } else if (attributes.activation === "LeakyRelu") { uniforms.push({ name: "alpha", type: "f32" }); } }; parseInternalActivationAttributes2 = (attributes) => { const activation = attributes?.activation || ""; if (activation === "HardSigmoid") { const [alpha, beta] = attributes?.activation_params || [0.2, 0.5]; return { activation, alpha, beta }; } else if (activation === "Clip") { const [clipMin, clipMax] = attributes?.activation_params || [MIN_CLIP2, MAX_CLIP2]; return { activation, clipMax, clipMin }; } else if (activation === "LeakyRelu") { const [alpha] = attributes?.activation_params || [0.01]; return { activation, alpha }; } return { activation }; }; } }); // web/lib/wasm/jsep/webgpu/ops/3rd-party/activation_util.ts var typeSnippet, biasSnippet; var init_activation_util = __esm({ "web/lib/wasm/jsep/webgpu/ops/3rd-party/activation_util.ts"() { "use strict"; typeSnippet = (component, dataType) => { switch (component) { case 1: return dataType; case 2: return `vec2<${dataType}>`; case 3: return `vec3<${dataType}>`; case 4: return `vec4<${dataType}>`; default: throw new Error(`${component}-component is not supported.`); } }; biasSnippet = (hasBias) => ` ${hasBias ? "value = value + getBiasByOutputCoords(coords);" : ""} `; } }); // web/lib/wasm/jsep/webgpu/ops/3rd-party/conv_util.ts var utilFunctions; var init_conv_util = __esm({ "web/lib/wasm/jsep/webgpu/ops/3rd-party/conv_util.ts"() { "use strict"; utilFunctions = (strideStr) => ` fn getIndexFromCoords4D(coords : vec4, shape : vec4) -> i32 { return dot(coords, vec4( shape.y * shape.z * shape.w, shape.z * shape.w, shape.w, 1)); } fn getOutputIndexFromCoords(coords : vec4) -> i32 { return dot(coords, vec4( i32(${strideStr}.x), i32(${strideStr}.y), i32(${strideStr}.z), 1)); } `; } }); // web/lib/wasm/jsep/webgpu/ops/matmul-shaders.ts var convertOutputBatchIndicesToInputBatchIndices, createNaiveMatmulProgramInfo; var init_matmul_shaders = __esm({ "web/lib/wasm/jsep/webgpu/ops/matmul-shaders.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); init_fuse_utils2(); convertOutputBatchIndicesToInputBatchIndices = (targetIndicesName, inputVariable2, inputBatchRank, outputBatchRank, batchIndicesName) => { const extendingInputRank = outputBatchRank - inputBatchRank; return ` ${Array.from({ length: inputBatchRank }).map( (_, i) => ` if (${getElementAt(inputVariable2.shape, i, inputVariable2.rank)} != 1) { ${inputVariable2.indicesSet(targetIndicesName, i, getElementAt(batchIndicesName, i + extendingInputRank, outputBatchRank))} } else { ${inputVariable2.indicesSet(targetIndicesName, i, 0)} }` ).join("")} `; }; createNaiveMatmulProgramInfo = (inputs, activationAttributes, outputShape, reshapedOutputShape, isChannelsLast = false, squeezeOutputShapeFunction) => { const aShape = inputs[0].dims; const bShape = inputs[1].dims; const M = aShape[aShape.length - 2]; const N = bShape[bShape.length - 1]; const K = aShape[aShape.length - 1]; const components = getMaxComponents(N); const aComponents = getMaxComponents(K); const outputNumber = getMaxComponents(M); const outputSize = ShapeUtil2.size(outputShape) / components / outputNumber; const hasBias = inputs.length > 2; const outerDims = reshapedOutputShape ? reshapedOutputShape.slice(0, -2) : outputShape.slice(0, -2); const batchSize = ShapeUtil2.size(outerDims); const outputShapeInShader = [batchSize, M, N]; const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: M }, { type: 12 /* uint32 */, data: N }, { type: 12 /* uint32 */, data: K } ]; appendActivationUniformsData(activationAttributes, programUniforms); programUniforms.push(...createTensorShapeVariables(outerDims, aShape, bShape)); if (hasBias) { programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); } programUniforms.push(...createTensorShapeVariables(outputShapeInShader)); const getShaderSource = (shaderHelper) => { const batchDims = internalVariable("batch_dims", inputs[0].dataType, outerDims.length); const a = inputVariable("a", inputs[0].dataType, aShape.length, aComponents); const b = inputVariable("b", inputs[1].dataType, bShape.length, components); const output = outputVariable("output", inputs[0].dataType, outputShapeInShader.length, components); const baseType = tensorTypeToWsglStorageType(output.type.tensor); const applyActivation = getActivationSnippet2(activationAttributes, output.type.value, baseType); const inputVariables = [a, b]; let processBias = ""; if (hasBias) { const biasComponents = isChannelsLast ? components : 1; inputVariables.push(inputVariable("bias", inputs[2].dataType, inputs[2].dims.length, biasComponents)); processBias = `${isChannelsLast ? `value += bias[col / ${biasComponents}];` : `value += ${output.type.value}(bias[row + i]);`}`; } const uniforms = [ { name: "output_size", type: "u32" }, { name: "M", type: "u32" }, { name: "N", type: "u32" }, { name: "K", type: "u32" } ]; appendActivationUniforms(activationAttributes, uniforms); const calcResult = () => { let calcStr = `var a_data: ${a.type.value};`; for (let i = 0; i < aComponents; i++) { calcStr += ` let b_data${i} = b[(b_offset + (k + ${i}) * uniforms.N + col) / ${components}];`; } for (let i = 0; i < outputNumber; i++) { calcStr += `a_data = a[(a_offset + (row + ${i}) * uniforms.K + k) / ${aComponents}];`; for (let j = 0; j < aComponents; j++) { calcStr += ` values[${i}] = fma(${b.type.value}(a_data${aComponents === 1 ? "" : `[${j}]`}), b_data${j}, values[${i}]); `; } } return calcStr; }; return ` ${shaderHelper.registerUniforms(uniforms).registerInternalVariables(batchDims).declareVariables(...inputVariables, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let col = (global_idx % (uniforms.N / ${components})) * ${components}; var index1 = global_idx / (uniforms.N / ${components}); let stride1 = uniforms.M / ${outputNumber}; let row = (index1 % stride1) * ${outputNumber}; let batch = index1 / stride1; ${outputShape.length === 2 ? "" : `let batch_indices = ${batchDims.offsetToIndices("batch")};`} var a_indices: ${a.type.indices}; ${convertOutputBatchIndicesToInputBatchIndices("a_indices", a, a.rank - 2, batchDims.rank, "batch_indices")} ${a.indicesSet("a_indices", a.rank - 2, 0)} ${a.indicesSet("a_indices", a.rank - 1, 0)} let a_offset = ${a.indicesToOffset("a_indices")}; var b_indices: ${b.type.indices}; ${convertOutputBatchIndicesToInputBatchIndices("b_indices", b, b.rank - 2, batchDims.rank, "batch_indices")} ${b.indicesSet("b_indices", b.rank - 2, 0)} ${b.indicesSet("b_indices", b.rank - 1, 0)} let b_offset = ${b.indicesToOffset("b_indices")}; var values: array<${output.type.value}, ${outputNumber}>; for (var k: u32 = 0u; k < uniforms.K; k = k + ${aComponents}) { ${calcResult()} } for (var i = 0u; i < ${outputNumber}u; i++) { var value = values[i]; ${processBias} ${applyActivation} let cur_indices = ${output.type.indices}(batch, row + i, col); let offset = ${output.indicesToOffset("cur_indices")}; ${output.setByOffset(`offset / ${components}`, "value")}; } } `; }; return { name: "MatMulNaive", shaderCache: { hint: `${activationAttributes.activation};${components};${aComponents};${outputNumber};${isChannelsLast}`, inputDependencies: hasBias ? ["rank", "rank", "rank"] : ["rank", "rank"] }, getRunData: () => ({ outputs: [ { dims: squeezeOutputShapeFunction ? squeezeOutputShapeFunction(outputShape) : outputShape, dataType: inputs[0].dataType } ], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }; }; } }); // web/lib/wasm/jsep/webgpu/ops/3rd-party/matmul_packed_webgpu.ts var writeDataToSubAVec4Snippet, calculateResultSnippet, makeMatMulPackedVec4Source, writeDataToSubASnippet, readDataFromSubASnippet, makeMatMulPackedSource, matMulReadWriteFnSource, createMatmulProgramInfo2; var init_matmul_packed_webgpu = __esm({ "web/lib/wasm/jsep/webgpu/ops/3rd-party/matmul_packed_webgpu.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); init_fuse_utils2(); init_matmul_shaders(); init_activation_util(); writeDataToSubAVec4Snippet = (transpose3, batchDims) => { if (transpose3) { return ` mm_Asub[inputRow][inputCol] = mm_readA(batch, kStart + inputRow, globalRowStart / innerElementSize + inputCol${batchDims ? ", batchIndices" : ""}); `; } else { return ` mm_Asub[inputRow][inputCol] = mm_readA(batch, globalRow + innerRow, kStart / innerElementSize + inputCol${batchDims ? ", batchIndices" : ""}); `; } }; calculateResultSnippet = (transposeA, innerElementSize) => { if (transposeA) { return ` let ACached0 = mm_Asub[k * innerElementSize][localRow]; let ACached1 = mm_Asub[k * innerElementSize + 1][localRow]; let ACached2 = mm_Asub[k * innerElementSize + 2][localRow]; ${innerElementSize === 3 ? "" : "let ACached3 = mm_Asub[k * innerElementSize + 3][localRow];"} for (var i = 0; i < rowPerThread; i = i + 1) { acc[i] = BCached0 * ACached0[i] + acc[i]; acc[i] = BCached1 * ACached1[i] + acc[i]; acc[i] = BCached2 * ACached2[i] + acc[i]; ${innerElementSize === 3 ? "" : "acc[i] = BCached3 * ACached3[i] + acc[i];"} }`; } else { return ` for (var i = 0; i < rowPerThread; i = i + 1) { let ACached = mm_Asub[tileRow + i][k]; acc[i] = BCached0 * ACached.x + acc[i]; acc[i] = BCached1 * ACached.y + acc[i]; acc[i] = BCached2 * ACached.z + acc[i]; ${innerElementSize === 3 ? "" : "acc[i] = BCached3 * ACached.w + acc[i];"} }`; } }; makeMatMulPackedVec4Source = (workPerThread, workgroupSize, type = "f32", batchDims, transposeA = false, tileInner = 32, splitK = false, splitedDimInner = 32) => { const tileAOuter = workgroupSize[1] * workPerThread[1]; const tileBOuter = workgroupSize[0] * workPerThread[0]; const tileAWidth = transposeA ? tileAOuter : tileInner; const tileAHight = transposeA ? tileInner : tileAOuter; const innerElementSize = tileAWidth / workgroupSize[0]; const rowPerThreadB = tileInner / workgroupSize[1]; if (!((transposeA && innerElementSize === 4 && workPerThread[1] === 4 || !transposeA && (innerElementSize === 3 || innerElementSize === 4)) && tileAWidth % workgroupSize[0] === 0 && tileInner % workgroupSize[1] === 0 && workPerThread[0] === 4)) { throw new Error(`If transposeA ${transposeA} is true, innerElementSize ${innerElementSize} and workPerThread[1] ${workPerThread[1]} must be 4. Otherwise, innerElementSize ${innerElementSize} must be 3 or 4. tileAWidth ${tileAWidth} must be divisible by workgroupSize[0]${workgroupSize[0]}. tileInner ${tileInner} must be divisible by workgroupSize[1] ${workgroupSize[1]}. colPerThread ${workPerThread[0]} must be 4.`); } return ` var mm_Asub: array, ${tileAWidth / innerElementSize}>, ${tileAHight}>; var mm_Bsub: array, ${tileBOuter / workPerThread[0]}>, ${tileInner}>; const rowPerThread = ${workPerThread[1]}; const colPerThread = ${workPerThread[0]}; const innerElementSize = ${innerElementSize}; const tileInner = ${tileInner}; @compute @workgroup_size(${workgroupSize[0]}, ${workgroupSize[1]}, ${workgroupSize[2]}) fn main(@builtin(local_invocation_id) localId : vec3, @builtin(global_invocation_id) globalId : vec3, @builtin(workgroup_id) workgroupId : vec3) { let localRow = i32(localId.y); let tileRow = localRow * rowPerThread; let tileCol = i32(localId.x); let globalRow =i32(globalId.y) * rowPerThread; let globalCol = i32(globalId.x); let batch = ${splitK ? "0" : "i32(globalId.z)"}; ${batchDims ? `let batchIndices = ${batchDims.offsetToIndices("u32(batch)")};` : ""} let globalRowStart = i32(workgroupId.y) * ${tileAOuter}; let num_tiles = ${splitK ? `${Math.ceil(splitedDimInner / tileInner)}` : "(uniforms.dim_inner - 1) / tileInner + 1"}; var kStart = ${splitK ? `i32(globalId.z) * ${splitedDimInner}` : "0"}; var acc: array, rowPerThread>; // Loop over shared dimension. let tileRowB = localRow * ${rowPerThreadB}; for (var t = 0; t < num_tiles; t = t + 1) { // Load one tile of A into local memory. for (var innerRow = 0; innerRow < rowPerThread; innerRow = innerRow + 1) { let inputRow = tileRow + innerRow; let inputCol = tileCol; ${writeDataToSubAVec4Snippet(transposeA, batchDims)} } // Load one tile of B into local memory. for (var innerRow = 0; innerRow < ${rowPerThreadB}; innerRow = innerRow + 1) { let inputRow = tileRowB + innerRow; let inputCol = tileCol; mm_Bsub[inputRow][inputCol] = mm_readB(batch, kStart + inputRow, globalCol${batchDims ? ", batchIndices" : ""}); } kStart = kStart + tileInner; workgroupBarrier(); // Compute acc values for a single thread. for (var k = 0; k < tileInner / innerElementSize; k = k + 1) { let BCached0 = mm_Bsub[k * innerElementSize][tileCol]; let BCached1 = mm_Bsub[k * innerElementSize + 1][tileCol]; let BCached2 = mm_Bsub[k * innerElementSize + 2][tileCol]; ${innerElementSize === 3 ? "" : "let BCached3 = mm_Bsub[k * innerElementSize + 3][tileCol];"} ${calculateResultSnippet(transposeA, innerElementSize)} } workgroupBarrier(); } for (var innerRow = 0; innerRow < rowPerThread; innerRow = innerRow + 1) { mm_write(batch, globalRow + innerRow, globalCol, acc[innerRow]); } }`; }; writeDataToSubASnippet = (transpose3, batchDims) => { if (transpose3) { return ` mm_Asub[inputRow][inputCol] = mm_readA(batch, kStart + inputRow, globalRowStart + inputCol${batchDims ? ", batchIndices" : ""}); `; } else { return ` mm_Asub[inputRow][inputCol] = mm_readA(batch, globalRowStart + inputRow, kStart + inputCol${batchDims ? ", batchIndices" : ""}); `; } }; readDataFromSubASnippet = (transposeA) => transposeA ? "let ACached = mm_Asub[k][tileRow + innerRow];" : "let ACached = mm_Asub[tileRow + innerRow][k];"; makeMatMulPackedSource = (workPerThread, workgroupSize, type = "f32", batchDims, transposeA = false, tileInner = 32, splitK = false, splitedDimInner = 32, sequentialAccessByThreads = false) => { const tileAOuter = workPerThread[1] * workgroupSize[1]; const tileBOuter = workPerThread[0] * workgroupSize[0]; const tileAWidth = transposeA ? tileAOuter : tileInner; const tileAHight = transposeA ? tileInner : tileAOuter; if (!(tileAHight % workgroupSize[1] === 0 && tileAWidth % workgroupSize[0] === 0 && tileInner % workgroupSize[1] === 0)) { throw new Error( `tileAHight ${tileAHight} must be divisible by workgroupSize[1]${workgroupSize[1]}, tileAWidth ${tileAWidth} must be divisible by workgroupSize[0]${workgroupSize[0]}, tileInner ${tileInner} must be divisible by workgroupSize[1]${workgroupSize[1]}` ); } const rowPerThreadA = tileAHight / workgroupSize[1]; const colPerThreadA = tileAWidth / workgroupSize[0]; const rowPerThreadB = tileInner / workgroupSize[1]; const matmulSnippet = sequentialAccessByThreads ? ` let localRow = i32(localId.y); let localCol = i32(localId.x); let globalRowStart = i32(workgroupId.y) * ${tileAOuter}; let globalColStart = i32(workgroupId.x) * ${tileBOuter}; // Loop over shared dimension. for (var t = 0; t < num_tiles; t = t + 1) { // Load one tile of A into local memory. for (var inputRow = localRow; inputRow < ${tileAHight}; inputRow = inputRow + ${workgroupSize[1]}) { for (var inputCol = localCol; inputCol < ${tileAWidth}; inputCol = inputCol + ${workgroupSize[0]}) { ${writeDataToSubASnippet(transposeA, batchDims)} } } // Load one tile of B into local memory. for (var inputRow = localRow; inputRow < ${tileInner}; inputRow = inputRow + ${workgroupSize[1]}) { for (var inputCol = localCol; inputCol < ${tileBOuter}; inputCol = inputCol + ${workgroupSize[0]}) { mm_Bsub[inputRow][inputCol] = mm_readB(batch, kStart + inputRow, globalColStart + inputCol${batchDims ? ", batchIndices" : ""}); } } kStart = kStart + tileInner; workgroupBarrier(); // Compute acc values for a single thread. var BCached : array<${type}, colPerThread>; for (var k = 0; k < tileInner; k = k + 1) { for (var inner = 0; inner < colPerThread; inner = inner + 1) { BCached[inner] = mm_Bsub[k][localCol + inner * ${workgroupSize[0]}]; } for (var innerRow = 0; innerRow < rowPerThread; innerRow = innerRow + 1) { let ACached = ${transposeA ? `mm_Asub[k][localRow + innerRow * ${workgroupSize[1]}];` : `mm_Asub[localRow + innerRow * ${workgroupSize[1]}][k];`} for (var innerCol = 0; innerCol < colPerThread; innerCol = innerCol + 1) { acc[innerRow][innerCol] = acc[innerRow][innerCol] + ACached * BCached[innerCol]; } } } workgroupBarrier(); } for (var innerRow = 0; innerRow < rowPerThread; innerRow = innerRow + 1) { let gRow = globalRowStart + localRow + innerRow * ${workgroupSize[1]}; for (var innerCol = 0; innerCol < colPerThread; innerCol = innerCol + 1) { let gCol = globalColStart + localCol + innerCol * ${workgroupSize[0]}; mm_write(batch, gRow, gCol, acc[innerRow][innerCol]); } } ` : ` let tileRow = i32(localId.y) * rowPerThread; let tileCol = i32(localId.x) * colPerThread; let globalRow = i32(globalId.y) * rowPerThread; let globalCol = i32(globalId.x) * colPerThread; let globalRowStart = i32(workgroupId.y) * ${tileAOuter}; let tileRowA = i32(localId.y) * ${rowPerThreadA}; let tileColA = i32(localId.x) * ${colPerThreadA}; let tileRowB = i32(localId.y) * ${rowPerThreadB}; // Loop over shared dimension. for (var t = 0; t < num_tiles; t = t + 1) { // Load one tile of A into local memory. for (var innerRow = 0; innerRow < ${rowPerThreadA}; innerRow = innerRow + 1) { for (var innerCol = 0; innerCol < ${colPerThreadA}; innerCol = innerCol + 1) { let inputRow = tileRowA + innerRow; let inputCol = tileColA + innerCol; ${writeDataToSubASnippet(transposeA, batchDims)} } } // Load one tile of B into local memory. for (var innerRow = 0; innerRow < ${rowPerThreadB}; innerRow = innerRow + 1) { for (var innerCol = 0; innerCol < colPerThread; innerCol = innerCol + 1) { let inputRow = tileRowB + innerRow; let inputCol = tileCol + innerCol; mm_Bsub[inputRow][inputCol] = mm_readB(batch, kStart + inputRow, globalCol + innerCol${batchDims ? ", batchIndices" : ""}); } } kStart = kStart + tileInner; workgroupBarrier(); // Compute acc values for a single thread. var BCached : array<${type}, colPerThread>; for (var k = 0; k < tileInner; k = k + 1) { for (var inner = 0; inner < colPerThread; inner = inner + 1) { BCached[inner] = mm_Bsub[k][tileCol + inner]; } for (var innerRow = 0; innerRow < rowPerThread; innerRow = innerRow + 1) { ${readDataFromSubASnippet(transposeA)} for (var innerCol = 0; innerCol < colPerThread; innerCol = innerCol + 1) { acc[innerRow][innerCol] = acc[innerRow][innerCol] + ACached * BCached[innerCol]; } } } workgroupBarrier(); } for (var innerRow = 0; innerRow < rowPerThread; innerRow = innerRow + 1) { for (var innerCol = 0; innerCol < colPerThread; innerCol = innerCol + 1) { mm_write(batch, globalRow + innerRow, globalCol + innerCol, acc[innerRow][innerCol]); } } `; return ` var mm_Asub : array, ${tileAHight}>; var mm_Bsub : array, ${tileInner}>; const rowPerThread = ${workPerThread[1]}; const colPerThread = ${workPerThread[0]}; const tileInner = ${tileInner}; @compute @workgroup_size(${workgroupSize[0]}, ${workgroupSize[1]}, ${workgroupSize[2]}) fn main(@builtin(local_invocation_id) localId : vec3, @builtin(global_invocation_id) globalId : vec3, @builtin(workgroup_id) workgroupId : vec3) { let batch = ${splitK ? "0" : "i32(globalId.z)"}; ${batchDims ? `let batchIndices = ${batchDims.offsetToIndices("u32(batch)")};` : ""} let num_tiles = ${splitK ? `${Math.ceil(splitedDimInner / tileInner)}` : "(uniforms.dim_inner - 1) / tileInner + 1"}; var kStart = ${splitK ? `i32(globalId.z) * ${splitedDimInner}` : "0"}; var acc : array, rowPerThread>; ${matmulSnippet} } `; }; matMulReadWriteFnSource = (component, hasBias, applyActivation, variables, isChannelsLast = false) => { const [batchVariable, aVariable, bVariable, outputVariable2] = variables; const dataType = tensorTypeToWsglStorageType(variables[0].type.tensor); const source = ` fn mm_readA(batch: i32, row: i32, colIn: i32, batchIndices: ${batchVariable.type.indices}) -> ${typeSnippet( component, dataType )} { var value = ${typeSnippet(component, dataType)}(0.0); let col = colIn * ${component}; if(row < uniforms.dim_a_outer && col < uniforms.dim_inner) { var aIndices: ${aVariable.type.indices}; ${convertOutputBatchIndicesToInputBatchIndices( "aIndices", aVariable, aVariable.rank - 2, batchVariable.rank, "batchIndices" )} ${aVariable.indicesSet("aIndices", aVariable.rank - 2, "u32(row)")} ${aVariable.indicesSet("aIndices", aVariable.rank - 1, "u32(colIn)")} value = ${aVariable.getByIndices("aIndices")}; } return value; } fn mm_readB(batch: i32, row: i32, colIn: i32, batchIndices: ${batchVariable.type.indices}) -> ${typeSnippet( component, dataType )} { var value = ${typeSnippet(component, dataType)}(0.0); let col = colIn * ${component}; if(row < uniforms.dim_inner && col < uniforms.dim_b_outer) { var bIndices: ${bVariable.type.indices}; ${convertOutputBatchIndicesToInputBatchIndices( "bIndices", bVariable, bVariable.rank - 2, batchVariable.rank, "batchIndices" )} ${bVariable.indicesSet("bIndices", bVariable.rank - 2, "u32(row)")} ${bVariable.indicesSet("bIndices", bVariable.rank - 1, "u32(colIn)")} value = ${bVariable.getByIndices("bIndices")}; } return value; } fn mm_write(batch: i32, row: i32, colIn: i32, valueIn: ${typeSnippet(component, dataType)}) { let col = colIn * ${component}; if (row < uniforms.dim_a_outer && col < uniforms.dim_b_outer) { var value = valueIn; let coords = vec3(batch, row, colIn); ${hasBias ? `value = value + ${isChannelsLast ? "bias[colIn]" : `${typeSnippet(component, dataType)}(bias[row])`};` : ""} ${applyActivation} ${outputVariable2.setByIndices("vec3(coords)", "value")} } } `; return source; }; createMatmulProgramInfo2 = (inputs, activationAttributes, outputShape, reshapedOutputShape, isChannelsLast = false, squeezeOutputShapeFunction) => { const aShape = inputs[0].dims; const bShape = inputs[1].dims; const outerDimsA = aShape.slice(0, -2); const outerDimsB = bShape.slice(0, -2); const outerDims = reshapedOutputShape ? reshapedOutputShape.slice(0, -2) : outputShape.slice(0, -2); const batchSize = ShapeUtil2.size(outerDims); const dimAOuter = aShape[aShape.length - 2]; const dimInner = aShape[aShape.length - 1]; const dimBOuter = bShape[bShape.length - 1]; const isVec4 = dimInner % 4 === 0 && dimBOuter % 4 === 0; const elementsPerThread = dimAOuter <= 8 ? [4, 1, 1] : [4, 4, 1]; const workgroupSize = [8, 8, 1]; const dispatch = [ Math.ceil(dimBOuter / workgroupSize[0] / elementsPerThread[0]), Math.ceil(dimAOuter / workgroupSize[1] / elementsPerThread[1]), Math.ceil(batchSize / workgroupSize[2] / elementsPerThread[2]) ]; const components = isVec4 ? 4 : 1; const aShapeTemp = [...outerDimsA, dimAOuter, dimInner / components]; const aRank = aShapeTemp.length; const bShapeTemp = [...outerDimsB, dimInner, dimBOuter / components]; const bRank = bShapeTemp.length; const outputShapeTemp = [batchSize, dimAOuter, dimBOuter / components]; const programUniforms = [ { type: 6 /* int32 */, data: dimAOuter }, { type: 6 /* int32 */, data: dimBOuter }, { type: 6 /* int32 */, data: dimInner } ]; appendActivationUniformsData(activationAttributes, programUniforms); programUniforms.push(...createTensorShapeVariables(outerDims, aShapeTemp, bShapeTemp)); const inputDependencies = ["rank", "rank"]; const hasBias = inputs.length > 2; if (hasBias) { programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); inputDependencies.push("rank"); } programUniforms.push(...createTensorShapeVariables(outputShapeTemp)); const getShaderSource = (shaderHelper) => { const batchRank = outerDims.length; const batchDims = internalVariable("batchDims", inputs[0].dataType, batchRank, 1); const dataType = tensorTypeToWsglStorageType(inputs[0].dataType); const A = inputVariable("a", inputs[0].dataType, aRank, components); const B = inputVariable("b", inputs[1].dataType, bRank, components); const output = outputVariable("result", inputs[0].dataType, outputShapeTemp.length, components); const inputVariables = [A, B]; if (hasBias) { const biasComponents = isChannelsLast ? components : 1; inputVariables.push(inputVariable("bias", inputs[2].dataType, inputs[2].dims.length, biasComponents)); } const uniforms = [ { name: "dim_a_outer", type: "i32" }, { name: "dim_b_outer", type: "i32" }, { name: "dim_inner", type: "i32" } ]; appendActivationUniforms(activationAttributes, uniforms); const baseType = tensorTypeToWsglStorageType(output.type.tensor); const applyActivation = getActivationSnippet2(activationAttributes, output.type.value, baseType); const declareFunctions = matMulReadWriteFnSource( components, hasBias, applyActivation, [batchDims, A, B, output], isChannelsLast ); return ` ${shaderHelper.registerUniforms(uniforms).registerInternalVariables(batchDims).declareVariables(...inputVariables, output)} ${declareFunctions} ${isVec4 ? makeMatMulPackedVec4Source(elementsPerThread, workgroupSize, dataType, batchDims) : makeMatMulPackedSource(elementsPerThread, workgroupSize, dataType, batchDims)} `; }; return { name: "MatMul", shaderCache: { hint: `${elementsPerThread};${activationAttributes.activation};${isVec4};${isChannelsLast}`, inputDependencies }, getRunData: () => ({ outputs: [ { dims: squeezeOutputShapeFunction ? squeezeOutputShapeFunction(outputShape) : outputShape, dataType: inputs[0].dataType } ], dispatchGroup: { x: dispatch[0], y: dispatch[1], z: dispatch[2] }, programUniforms }), getShaderSource }; }; } }); // web/lib/wasm/jsep/webgpu/ops/3rd-party/conv2d_mm_webgpu.ts var conv2dCommonSnippet, createConv2DMatMulProgramInfo; var init_conv2d_mm_webgpu = __esm({ "web/lib/wasm/jsep/webgpu/ops/3rd-party/conv2d_mm_webgpu.ts"() { "use strict"; init_wasm_common(); init_log(); init_common(); init_fuse_utils2(); init_activation_util(); init_conv_util(); init_matmul_packed_webgpu(); conv2dCommonSnippet = (isChannelsLast, fitAOuter, fitBOuter, fitInner, addBias = false, attributes, innerElementSizeX = 4, innerElementSizeW = 4, innerElementSize = 4, dataType = "f32") => { const getXSnippet = (innerElementSize2) => { switch (innerElementSize2) { case 1: return "resData = x[xIndex];"; case 3: return `resData = vec3<${dataType}>(x[xIndex], x[xIndex + 1], x[xIndex + 2]);`; case 4: return "resData = x[xIndex / 4];"; default: throw new Error(`innerElementSize ${innerElementSize2} is not supported.`); } }; const getWSnippet = (innerElementSize2) => { switch (innerElementSize2) { case 1: return "return w[row * i32(uniforms.w_shape[3]) + colIn];"; case 4: return "return w[row * i32(uniforms.w_shape[3]) / 4 + colIn];"; default: throw new Error(`innerElementSize ${innerElementSize2} is not supported.`); } }; const coordASnippet = isChannelsLast ? ` let coord = vec4(batch, xRow, xCol, xCh); ` : ` let coord = vec4(batch, xCh, xRow, xCol); `; const coordResSnippet = isChannelsLast ? ` let coords = vec4( batch, row / outWidth, row % outWidth, col); ` : ` let coords = vec4( batch, row, col / outWidth, col % outWidth); `; const xHeight = isChannelsLast ? "i32(uniforms.x_shape[1])" : "i32(uniforms.x_shape[2])"; const xWidth = isChannelsLast ? "i32(uniforms.x_shape[2])" : "i32(uniforms.x_shape[3])"; const row = isChannelsLast ? "row" : "col"; const col = isChannelsLast ? "col" : "row"; const readXSnippet = ` let inChannels = i32(uniforms.w_shape[2]); let outWidth = ${isChannelsLast ? "i32(uniforms.result_shape[2])" : "i32(uniforms.result_shape[3])"}; let outRow = ${row} / outWidth; let outCol = ${row} % outWidth; let WRow = ${col} / (i32(uniforms.w_shape[1]) * inChannels); let WCol = ${col} / inChannels % i32(uniforms.w_shape[1]); let xRow = outRow * uniforms.stride[0] + uniforms.dilation[0] * WRow - uniforms.pad[0]; let xCol = outCol * uniforms.stride[1] + uniforms.dilation[1] * WCol - uniforms.pad[1]; let xCh = ${col} % inChannels; var resData = ${typeSnippet(innerElementSizeX, dataType)}(0.0); // The bounds checking is always needed since we use it to pad zero for // the 'same' padding type. if (xRow >= 0 && xRow < ${xHeight} && xCol >= 0 && xCol < ${xWidth}) { ${coordASnippet} let xIndex = getIndexFromCoords4D(coord, vec4(uniforms.x_shape)); ${getXSnippet(innerElementSizeX)} } return resData;`; const sampleX = isChannelsLast ? fitAOuter && fitInner ? ` let col = colIn * ${innerElementSizeX}; ${readXSnippet}` : ` let col = colIn * ${innerElementSizeX}; if (row < uniforms.dim_a_outer && col < uniforms.dim_inner) { ${readXSnippet} } return ${typeSnippet(innerElementSizeX, dataType)}(0.0);` : fitInner && fitBOuter ? ` let col = colIn * ${innerElementSizeX}; ${readXSnippet}` : ` let col = colIn * ${innerElementSizeX}; if (row < uniforms.dim_inner && col < uniforms.dim_b_outer) { ${readXSnippet} } return ${typeSnippet(innerElementSizeX, dataType)}(0.0);`; const sampleW = isChannelsLast ? fitInner && fitBOuter ? getWSnippet(innerElementSizeW) : ` let col = colIn * ${innerElementSizeW}; if (row < uniforms.dim_inner && col < uniforms.dim_b_outer) { ${getWSnippet(innerElementSizeW)} } return ${typeSnippet(innerElementSizeW, dataType)}(0.0);` : ` let col = colIn * ${innerElementSizeW}; if (row < uniforms.dim_inner && col < uniforms.dim_a_outer) { ${getWSnippet(innerElementSizeW)} } return ${typeSnippet(innerElementSizeW, dataType)}(0.0);`; const resType = typeSnippet(innerElementSize, dataType); const aType = isChannelsLast ? typeSnippet(innerElementSizeX, dataType) : typeSnippet(innerElementSizeW, dataType); const bType = isChannelsLast ? typeSnippet(innerElementSizeW, dataType) : typeSnippet(innerElementSizeX, dataType); const applyActivation = getActivationSnippet2(attributes, resType, dataType); const userCode = ` fn mm_readA(batch: i32, row : i32, colIn : i32) -> ${aType} { ${isChannelsLast ? sampleX : sampleW} } fn mm_readB(batch: i32, row : i32, colIn : i32) -> ${bType} { ${isChannelsLast ? sampleW : sampleX} } fn mm_write(batch: i32, row : i32, colIn : i32, valueIn : ${resType}) { let col = colIn * ${innerElementSize}; if (row < uniforms.dim_a_outer && col < uniforms.dim_b_outer) { var value = valueIn; let outWidth = ${isChannelsLast ? "i32(uniforms.result_shape[2])" : "i32(uniforms.result_shape[3])"}; ${coordResSnippet} ${biasSnippet(addBias)} ${applyActivation} setOutputAtCoords(coords[0], coords[1], coords[2], coords[3], value); } }`; return userCode; }; createConv2DMatMulProgramInfo = (inputs, attributes, outputShape, dimAOuter, dimBOuter, dimInner, hasBias, sequentialAccessByThreads, squeezeOutputShapeFunction) => { const isChannelsLast = attributes.format === "NHWC"; const inChannels = isChannelsLast ? inputs[0].dims[3] : inputs[0].dims[1]; const batchSize = outputShape[0]; const outWidth = isChannelsLast ? outputShape[2] : outputShape[3]; const outHeight = isChannelsLast ? outputShape[1] : outputShape[2]; const outChannels = isChannelsLast ? outputShape[3] : outputShape[1]; const isVec4 = isChannelsLast && (inChannels % 4 === 0 || inChannels % 3 === 0) && outChannels % 4 === 0; const dispatchX = isChannelsLast ? outChannels : outWidth * outHeight; const dispatchY = isChannelsLast ? outWidth * outHeight : outChannels; const workGroupSize = [8, 8, 1]; const elementsPerThread = dimAOuter <= 8 ? [4, 1, 1] : [4, 4, 1]; const dispatch = [ Math.ceil(dispatchX / workGroupSize[0] / elementsPerThread[0]), Math.ceil(dispatchY / workGroupSize[1] / elementsPerThread[1]), Math.ceil(batchSize / workGroupSize[2] / elementsPerThread[2]) ]; LOG_DEBUG("verbose", () => `[conv2d_mm_webgpu] dispatch = ${dispatch}`); const innerElementSize = isVec4 ? isChannelsLast && inChannels % 4 !== 0 ? 3 : 4 : 1; const tileAOuter = workGroupSize[1] * elementsPerThread[1]; const tileBOuter = workGroupSize[0] * elementsPerThread[0]; const tileInner = Math.max(workGroupSize[0] * innerElementSize, workGroupSize[1]); const fitAOuter = dimAOuter % tileAOuter === 0; const fitBOuter = dimBOuter % tileBOuter === 0; const fitInner = dimInner % tileInner === 0; const elementsSize = isVec4 ? [innerElementSize, 4, 4] : [1, 1, 1]; const programUniforms = [ { type: 6 /* int32 */, data: dimAOuter }, { type: 6 /* int32 */, data: dimBOuter }, { type: 6 /* int32 */, data: dimInner }, { type: 6 /* int32 */, data: [attributes.pads[0], attributes.pads[1]] }, { type: 6 /* int32 */, data: attributes.strides }, { type: 6 /* int32 */, data: attributes.dilations } ]; appendActivationUniformsData(attributes, programUniforms); programUniforms.push(...createTensorShapeVariables(inputs[0].dims, inputs[1].dims)); const inputDependencies = ["rank", "rank"]; if (hasBias) { programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); inputDependencies.push("rank"); } programUniforms.push(...createTensorShapeVariables(outputShape)); const getShaderSource = (shaderHelper) => { const uniforms = [ { name: "dim_a_outer", type: "i32" }, { name: "dim_b_outer", type: "i32" }, { name: "dim_inner", type: "i32" }, { name: "pad", type: "i32", length: 2 }, { name: "stride", type: "i32", length: 2 }, { name: "dilation", type: "i32", length: 2 } ]; appendActivationUniforms(attributes, uniforms); const components = isVec4 ? 4 : 1; const t = tensorTypeToWsglStorageType(inputs[0].dataType); let declareFunctions = ` fn setOutputAtIndex(flatIndex : i32, value : ${isVec4 ? `vec4<${t}>` : t}) { result[flatIndex] = ${isVec4 ? `vec4<${t}>` : t}(value); } fn setOutputAtCoords(d0 : i32, d1 : i32, d2 : i32, d3 : i32, value : ${isVec4 ? `vec4<${t}>` : t}) { let flatIndex = getOutputIndexFromCoords(vec4(d0, d1, d2, d3)); setOutputAtIndex(flatIndex ${isVec4 ? "/ 4" : ""}, value); }`; const x = inputVariable( "x", inputs[0].dataType, inputs[0].dims.length, innerElementSize === 3 ? 1 : innerElementSize ); const w = inputVariable("w", inputs[1].dataType, inputs[1].dims.length, components); const inputVariables = [x, w]; const output = outputVariable("result", inputs[0].dataType, outputShape.length, components); if (hasBias) { const bias = inputVariable("bias", inputs[2].dataType, inputs[2].dims.length, components); inputVariables.push(bias); declareFunctions += ` fn getBiasByOutputCoords(coords : vec4) -> ${isVec4 ? `vec4<${t}>` : t} { return bias[coords.${isChannelsLast ? "w" : "y"}${isVec4 ? "/ 4" : ""}]; }`; } return ` ${utilFunctions("uniforms.result_strides")} //struct Uniforms { xShape : vec4, wShape : vec4, outShape : vec4, // outShapeStrides: vec3, filterDims : vec2, pad : vec2, stride : vec2, // dilation : vec2, dimAOuter : i32, dimBOuter : i32, dimInner : i32 }; ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVariables, output)} ${declareFunctions} ${conv2dCommonSnippet( isChannelsLast, fitAOuter, fitBOuter, fitInner, hasBias, attributes, elementsSize[0], elementsSize[1], elementsSize[2], t )} ${isVec4 ? makeMatMulPackedVec4Source(elementsPerThread, workGroupSize, t, void 0, !isChannelsLast, tileInner) : makeMatMulPackedSource( elementsPerThread, workGroupSize, t, void 0, !isChannelsLast, tileInner, false, void 0, sequentialAccessByThreads )}`; }; return { name: "Conv2DMatMul", shaderCache: { hint: `${attributes.cacheKey};${innerElementSize};${isVec4};${fitAOuter};${fitBOuter};${fitInner};${tileAOuter};${tileBOuter};${tileInner}`, inputDependencies }, getRunData: () => ({ outputs: [ { dims: squeezeOutputShapeFunction ? squeezeOutputShapeFunction(outputShape) : outputShape, dataType: inputs[0].dataType } ], dispatchGroup: { x: dispatch[0], y: dispatch[1], z: dispatch[2] }, programUniforms }), getShaderSource }; }; } }); // web/lib/wasm/jsep/webgpu/ops/3rd-party/conv3d_naive_webgpu.ts var arrayProduct, parse3TupleParam, getEffectiveFilterSize, computeDefaultPad, computeOutputShape4D, get3DPadAndOutInfo, computeConv3DInfo, createConv3DNaiveProgramInfo; var init_conv3d_naive_webgpu = __esm({ "web/lib/wasm/jsep/webgpu/ops/3rd-party/conv3d_naive_webgpu.ts"() { "use strict"; init_wasm_common(); init_log(); init_util2(); init_common(); init_fuse_utils2(); init_activation_util(); arrayProduct = (arr) => { let product = 1; for (let i = 0; i < arr.length; i++) { product *= arr[i]; } return product; }; parse3TupleParam = (param) => typeof param === "number" ? [param, param, param] : param; getEffectiveFilterSize = (filterSize, dilation) => { if (dilation <= 1) { return filterSize; } return filterSize + (filterSize - 1) * (dilation - 1); }; computeDefaultPad = (inputShape, fieldSize, stride, dilation = 1) => { const effectiveFieldSize = getEffectiveFilterSize(fieldSize, dilation); return Math.floor((inputShape[0] * (stride - 1) - stride + effectiveFieldSize) / 2); }; computeOutputShape4D = (inShape, filterShape, outChannels, strides, zeroPad) => { if (zeroPad == null) { zeroPad = computeDefaultPad(inShape, filterShape[0], strides[0]); } const outShape = [0, 0, 0, outChannels]; for (let index = 0; index < 3; index++) { if (inShape[index] + 2 * zeroPad >= filterShape[index]) { outShape[index] = Math.trunc((inShape[index] - filterShape[index] + 2 * zeroPad) / strides[index] + 1); } } return outShape; }; get3DPadAndOutInfo = (pad2, inDepth, inHeight, inWidth, strideDepth, strideHeight, strideWidth, filterDepth, filterHeight, filterWidth) => { let padInfo; let outDepth; let outHeight; let outWidth; if (pad2 === "VALID") { pad2 = 0; } if (typeof pad2 === "number") { padInfo = { top: pad2, bottom: pad2, left: pad2, right: pad2, front: pad2, back: pad2 }; const outShape = computeOutputShape4D( [inDepth, inHeight, inWidth, 1], [filterDepth, filterHeight, filterWidth], 1, [strideDepth, strideHeight, strideWidth], pad2 ); outDepth = outShape[0]; outHeight = outShape[1]; outWidth = outShape[2]; } else if (Array.isArray(pad2)) { if (!pad2.every((val, _, arr) => val === arr[0])) { throw Error(`Unsupported padding parameter: ${pad2}`); } padInfo = { top: pad2[0], bottom: pad2[1], left: pad2[2], right: pad2[3], front: pad2[4], back: pad2[5] }; const outShape = computeOutputShape4D( [inDepth, inHeight, inWidth, 1], [filterDepth, filterHeight, filterWidth], 1, [strideDepth, strideHeight, strideWidth], pad2[0] ); outDepth = outShape[0]; outHeight = outShape[1]; outWidth = outShape[2]; } else if (pad2 === "SAME_UPPER") { outDepth = Math.ceil(inDepth / strideDepth); outHeight = Math.ceil(inHeight / strideHeight); outWidth = Math.ceil(inWidth / strideWidth); const padAlongDepth = (outDepth - 1) * strideDepth + filterDepth - inDepth; const padAlongHeight = (outHeight - 1) * strideHeight + filterHeight - inHeight; const padAlongWidth = (outWidth - 1) * strideWidth + filterWidth - inWidth; const front = Math.floor(padAlongDepth / 2); const back = padAlongDepth - front; const top = Math.floor(padAlongHeight / 2); const bottom = padAlongHeight - top; const left = Math.floor(padAlongWidth / 2); const right = padAlongWidth - left; padInfo = { top, bottom, left, right, front, back }; } else { throw Error(`Unknown padding parameter: ${pad2}`); } return { padInfo, outDepth, outHeight, outWidth }; }; computeConv3DInfo = (inShape, filterShape, strides, dilations, pad2, depthwise = false, dataFormat = "channelsLast") => { let batchSize, inDepth, inHeight, inWidth, inChannels; if (dataFormat === "channelsLast") { [batchSize, inDepth, inHeight, inWidth, inChannels] = inShape; } else if (dataFormat === "channelsFirst") { [batchSize, inChannels, inDepth, inHeight, inWidth] = inShape; } else { throw new Error(`Unknown dataFormat ${dataFormat}`); } const [filterChannels, , filterDepth, filterHeight, filterWidth] = filterShape; const [strideDepth, strideHeight, strideWidth] = parse3TupleParam(strides); const [dilationDepth, dilationHeight, dilationWidth] = parse3TupleParam(dilations); const effectiveFilterDepth = getEffectiveFilterSize(filterDepth, dilationDepth); const effectiveFilterHeight = getEffectiveFilterSize(filterHeight, dilationHeight); const effectiveFilterWidth = getEffectiveFilterSize(filterWidth, dilationWidth); const { padInfo, outDepth, outHeight, outWidth } = get3DPadAndOutInfo( pad2, inDepth, inHeight, inWidth, strideDepth, strideHeight, strideWidth, effectiveFilterDepth, effectiveFilterHeight, effectiveFilterWidth ); const outChannels = depthwise ? filterChannels * inChannels : filterChannels; let outShape = [0, 0, 0, 0, 0]; if (dataFormat === "channelsFirst") { outShape = [batchSize, outChannels, outDepth, outHeight, outWidth]; } else if (dataFormat === "channelsLast") { outShape = [batchSize, outDepth, outHeight, outWidth, outChannels]; } return { batchSize, dataFormat, inDepth, inHeight, inWidth, inChannels, outDepth, outHeight, outWidth, outChannels, padInfo, strideDepth, strideHeight, strideWidth, filterDepth, filterHeight, filterWidth, effectiveFilterDepth, effectiveFilterHeight, effectiveFilterWidth, dilationDepth, dilationHeight, dilationWidth, inShape, outShape, filterShape }; }; createConv3DNaiveProgramInfo = (inputs, attributes, outputShape, filterDims, pads, dataFormat) => { const isChannelLast = dataFormat === "channelsLast"; const inChannels = isChannelLast ? inputs[0].dims[3] : inputs[0].dims[1]; const isVec4 = false; const workGroupSize = [64, 1, 1]; const dispatchLayout = { x: outputShape.map((_, i) => i) }; const dispatch = [Math.ceil(arrayProduct(dispatchLayout.x.map((d) => outputShape[d])) / workGroupSize[0]), 1, 1]; LOG_DEBUG("verbose", () => `[conv3d_naive_webgpu] dispatch = ${dispatch}`); const innerElementSize = isVec4 ? isChannelLast && inChannels % 4 !== 0 ? 3 : 4 : 1; const outputSize = ShapeUtil2.size(outputShape); const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: filterDims }, { type: 12 /* uint32 */, data: pads }, { type: 12 /* uint32 */, data: attributes.strides }, { type: 12 /* uint32 */, data: attributes.dilations } ]; appendActivationUniformsData(attributes, programUniforms); programUniforms.push(...createTensorShapeVariables(inputs[0].dims, inputs[1].dims)); const inputDependencies = ["rank", "rank"]; const hasBias = inputs.length === 3; if (hasBias) { programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); inputDependencies.push("rank"); } programUniforms.push(...createTensorShapeVariables(outputShape)); const getShaderSource = (shaderHelper) => { const uniforms = [ { name: "output_size", type: "u32" }, { name: "filter_dims", type: "u32", length: filterDims.length }, { name: "pads", type: "u32", length: pads.length }, { name: "strides", type: "u32", length: attributes.strides.length }, { name: "dilations", type: "u32", length: attributes.dilations.length } ]; appendActivationUniforms(attributes, uniforms); const components = isVec4 ? 4 : 1; const t = tensorTypeToWsglStorageType(inputs[0].dataType); const x = inputVariable( "x", inputs[0].dataType, inputs[0].dims.length, innerElementSize === 3 ? 1 : innerElementSize ); const w = inputVariable("W", inputs[1].dataType, inputs[1].dims.length, components); const inputVariables = [x, w]; const output = outputVariable("result", inputs[0].dataType, outputShape.length, components); let declareFunctions = ""; if (hasBias) { const bias = inputVariable("bias", inputs[2].dataType, inputs[2].dims.length, components); inputVariables.push(bias); declareFunctions += ` fn getBiasByOutputCoords(coords : array) -> ${isVec4 ? `vec4<${t}>` : t} { return bias[${isChannelLast ? getElementAt("coords", 4, 5) : getElementAt("coords", 1, 5)}${isVec4 ? "/ 4" : ""}]; }`; } const resType = typeSnippet(innerElementSize, t); const applyActivation = getActivationSnippet2(attributes, resType, t); return ` ${declareFunctions} fn getX(d0 : u32, d1 : u32, d2 : u32, d3 : u32, d4 : u32) -> f32 { let aIndices = array(d0, d1, d2, d3, d4); return ${x.getByIndices("aIndices")}; } fn getW(d0 : u32, d1 : u32, d2 : u32, d3 : u32, d4 : u32) -> f32 { let aIndices = array(d0, d1, d2, d3, d4); return ${w.getByIndices("aIndices")}; } ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVariables, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let coords = ${output.offsetToIndices("global_idx")}; let batch = ${getElementAt("coords", 0, x.rank)}; let d2 = ${isChannelLast ? getElementAt("coords", x.rank - 1, x.rank) : getElementAt("coords", 1, x.rank)}; let xFRCCorner = vec3(${isChannelLast ? getElementAt("coords", 1, x.rank) : getElementAt("coords", 2, x.rank)}, ${isChannelLast ? getElementAt("coords", 2, x.rank) : getElementAt("coords", 3, x.rank)}, ${isChannelLast ? getElementAt("coords", 3, x.rank) : getElementAt("coords", 4, x.rank)}) * uniforms.strides - uniforms.pads; let xFCorner = xFRCCorner.x; let xRCorner = xFRCCorner.y; let xCCorner = xFRCCorner.z; let xShapeY = ${isChannelLast ? getElementAt("uniforms.x_shape", 1, x.rank) : getElementAt("uniforms.x_shape", 2, x.rank)}; let xShapeZ = ${isChannelLast ? getElementAt("uniforms.x_shape", 2, x.rank) : getElementAt("uniforms.x_shape", 3, x.rank)}; let xShapeW = ${isChannelLast ? getElementAt("uniforms.x_shape", 3, x.rank) : getElementAt("uniforms.x_shape", 4, x.rank)}; let xShapeU = ${isChannelLast ? getElementAt("uniforms.x_shape", 4, x.rank) : getElementAt("uniforms.x_shape", 1, x.rank)}; let inputDepthNearestVec4 = (xShapeU / 4) * 4; let inputDepthVec4Remainder = xShapeU % 4; var value = 0.0; for (var wF = 0u; wF < uniforms.filter_dims[0]; wF++) { let xF = xFCorner + wF * uniforms.dilations[0]; if (xF < 0 || xF >= xShapeY) { continue; } for (var wR = 0u; wR < uniforms.filter_dims[1]; wR++) { let xR = xRCorner + wR * uniforms.dilations[1]; if (xR < 0 || xR >= xShapeZ) { continue; } for (var wC = 0u; wC < uniforms.filter_dims[2]; wC++) { let xC = xCCorner + wC * uniforms.dilations[2]; if (xC < 0 || xC >= xShapeW) { continue; } for (var d1 = 0u; d1 < inputDepthNearestVec4; d1 += 4) { ${isChannelLast ? `let xValues = vec4( getX(batch, xF, xR, xC, d1), getX(batch, xF, xR, xC, d1 + 1), getX(batch, xF, xR, xC, d1 + 2), getX(batch, xF, xR, xC, d1 + 3)); ` : `let xValues = vec4( getX(batch, d1, xF, xR, xC), getX(batch, d1 + 1, xF, xR, xC), getX(batch, d1 + 2, xF, xR, xC), getX(batch, d1 + 3, xF, xR, xC)); `} let wValues = vec4( getW(d2, d1, wF, wR, wC), getW(d2, d1 + 1, wF, wR, wC), getW(d2, d1 + 2, wF, wR, wC), getW(d2, d1 + 3, wF, wR, wC)); value += dot(xValues, wValues); } if (inputDepthVec4Remainder == 1) { ${isChannelLast ? `value += getX(batch, xF, xR, xC, inputDepthNearestVec4) * getW(d2, inputDepthNearestVec4, wF, wR, wC);` : `value += getX(batch, inputDepthNearestVec4, xF, xR, xC) * getW(d2, inputDepthNearestVec4, wF, wR, wC);`} } else if (inputDepthVec4Remainder == 2) { ${isChannelLast ? `let xValues = vec2( getX(batch, xF, xR, xC, inputDepthNearestVec4), getX(batch, xF, xR, xC, inputDepthNearestVec4 + 1)); ` : `let xValues = vec2( getX(batch, inputDepthNearestVec4, xF, xR, xC), getX(batch, inputDepthNearestVec4 + 1, xF, xR, xC)); `} let wValues = vec2( getW(d2, inputDepthNearestVec4, wF, wR, wC), getW(d2, inputDepthNearestVec4 + 1, wF, wR, wC)); value += dot(xValues, wValues); } else if (inputDepthVec4Remainder == 3) { ${isChannelLast ? `let xValues = vec3( getX(batch, xF, xR, xC, inputDepthNearestVec4), getX(batch, xF, xR, xC, inputDepthNearestVec4 + 1), getX(batch, xF, xR, xC, inputDepthNearestVec4 + 2)); ` : `let xValues = vec3( getX(batch, inputDepthNearestVec4, xF, xR, xC), getX(batch, inputDepthNearestVec4 + 1, xF, xR, xC), getX(batch, inputDepthNearestVec4 + 2, xF, xR, xC)); `} let wValues = vec3( getW(d2, inputDepthNearestVec4, wF, wR, wC), getW(d2, inputDepthNearestVec4 + 1, wF, wR, wC), getW(d2, inputDepthNearestVec4 + 2, wF, wR, wC)); value += dot(xValues, wValues); } } } } ${hasBias ? "value = value + getBiasByOutputCoords(coords)" : ""}; ${applyActivation} result[global_idx] = f32(value); }`; }; return { name: "Conv3DNaive", shaderCache: { hint: `${attributes.cacheKey};${isChannelLast};${innerElementSize};${hasBias}`, inputDependencies }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: dispatch[0], y: dispatch[1], z: dispatch[2] }, programUniforms }), getShaderSource }; }; } }); // web/lib/wasm/jsep/webgpu/ops/conv-grouped.ts var createGroupedConvProgramInfo, createGroupedConvVectorizeProgramInfo; var init_conv_grouped2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/conv-grouped.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); init_fuse_utils2(); createGroupedConvProgramInfo = (inputs, attributes, outputShape, squeezeOutputShapeFunction) => { const hasBias = inputs.length > 2; const processBias = hasBias ? "value += b[output_channel];" : ""; const xShape = inputs[0].dims; const wShape = inputs[1].dims; const isChannelLast = attributes.format === "NHWC"; const outputChannels = isChannelLast ? outputShape[3] : outputShape[1]; const outputChannelsPerGroup = outputChannels / attributes.group; const components = isChannelLast && outputChannelsPerGroup >= 4 ? getMaxComponents(outputChannels) : 1; const outputSize = ShapeUtil2.size(outputShape) / components; const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: attributes.dilations }, { type: 12 /* uint32 */, data: [attributes.strides[0], attributes.strides[1]] }, { type: 12 /* uint32 */, data: [attributes.pads[0], attributes.pads[1]] }, { type: 12 /* uint32 */, data: outputChannelsPerGroup } ]; appendActivationUniformsData(attributes, programUniforms); programUniforms.push( ...createTensorShapeVariables(xShape, [wShape[0], wShape[1], wShape[2], wShape[3] / components]) ); const inputDependencies = hasBias ? ["rank", "rank", "rank"] : ["rank", "rank"]; programUniforms.push( ...createTensorShapeVariables([outputShape[0], outputShape[1], outputShape[2], outputShape[3] / components]) ); const getShaderSource = (shaderHelper) => { const output = outputVariable("output", inputs[0].dataType, outputShape.length, components); const baseType = tensorTypeToWsglStorageType(output.type.tensor); const applyActivation = getActivationSnippet2(attributes, output.type.value, baseType); const x = inputVariable("x", inputs[0].dataType, xShape.length); const w = inputVariable("w", inputs[1].dataType, wShape.length, components); const inputVars = [x, w]; if (hasBias) { inputVars.push(inputVariable("b", inputs[2].dataType, inputs[2].dims, components)); } const uniforms = [ { name: "output_size", type: "u32" }, { name: "dilations", type: "u32", length: attributes.dilations.length }, { name: "strides", type: "u32", length: 2 }, { name: "pads", type: "u32", length: 2 }, { name: "output_channels_per_group", type: "u32" } ]; appendActivationUniforms(attributes, uniforms); const calculateResult = isChannelLast ? ` for (var wHeight: u32 = 0u; wHeight < uniforms.w_shape[0]; wHeight++) { let xHeight = xRCCorner.x + wHeight * uniforms.dilations[0]; if (xHeight < 0u || xHeight >= uniforms.x_shape[1]) { continue; } for (var wWidth: u32 = 0u; wWidth < uniforms.w_shape[1]; wWidth++) { let xWidth = xRCCorner.y + wWidth * uniforms.dilations[1]; if (xWidth < 0u || xWidth >= uniforms.x_shape[2]) { continue; } for (var wInChannel: u32 = 0u; wInChannel < uniforms.w_shape[2]; wInChannel++) { let input_channel = in_channel_offset + wInChannel; let xVal = ${x.get("batch", "xHeight", "xWidth", "input_channel")}; let wVal = ${w.get("wHeight", "wWidth", "wInChannel", "output_channel")}; value += xVal * wVal; } } } ` : ` for (var wInChannel: u32 = 0u; wInChannel < uniforms.w_shape[1]; wInChannel++) { let input_channel = in_channel_offset + wInChannel; for (var wHeight: u32 = 0u; wHeight < uniforms.w_shape[2]; wHeight++) { let xHeight = xRCCorner.x + wHeight * uniforms.dilations[0]; if (xHeight < 0u || xHeight >= uniforms.x_shape[2]) { continue; } for (var wWidth: u32 = 0u; wWidth < uniforms.w_shape[3]; wWidth++) { let xWidth = xRCCorner.y + wWidth * uniforms.dilations[1]; if (xWidth < 0u || xWidth >= uniforms.x_shape[3]) { continue; } let xVal = ${x.get("batch", "input_channel", "xHeight", "xWidth")}; let wVal = ${w.get("output_channel", "wInChannel", "wHeight", "wWidth")}; value += xVal * wVal; } } } `; return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVars, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let outputIndices = ${output.offsetToIndices("global_idx")}; let batch: u32 = outputIndices[0]; let output_channel: u32 = outputIndices[${isChannelLast ? 3 : 1}]; let xRCCorner: vec2 = vec2(outputIndices[${isChannelLast ? 1 : 2}], outputIndices[${isChannelLast ? 2 : 3}]) * uniforms.strides - uniforms.pads; let group_id: u32 = output_channel * ${components} / uniforms.output_channels_per_group; var in_channel_offset = group_id * uniforms.w_shape[${isChannelLast ? 2 : 1}]; var value: ${output.type.value} = ${output.type.value}(0); ${calculateResult} ${processBias} ${applyActivation} ${output.setByOffset("global_idx", "value")} }`; }; return { name: "GroupedConv", shaderCache: { hint: `${attributes.cacheKey}_${components}`, inputDependencies }, getRunData: () => ({ outputs: [ { dims: squeezeOutputShapeFunction ? squeezeOutputShapeFunction(outputShape) : outputShape, dataType: inputs[0].dataType } ], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }; }; createGroupedConvVectorizeProgramInfo = (inputs, attributes, outputShape, squeezeOutputShapeFunction) => { const hasBias = inputs.length > 2; const components = getMaxComponents(outputShape[3]); const outputNumber = getMaxComponents(outputShape[2]); const outputSize = ShapeUtil2.size(outputShape) / components / outputNumber; const xShape = [inputs[0].dims[0], inputs[0].dims[1], inputs[0].dims[2], inputs[0].dims[3] / components]; const wShape = [inputs[1].dims[0], inputs[1].dims[1], inputs[1].dims[2], inputs[1].dims[3] / components]; const outputShapeInShader = [outputShape[0], outputShape[1], outputShape[2], outputShape[3] / components]; const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 6 /* int32 */, data: [attributes.strides[0], attributes.strides[1]] }, { type: 6 /* int32 */, data: [attributes.pads[0], attributes.pads[1]] } ]; appendActivationUniformsData(attributes, programUniforms); programUniforms.push(...createTensorShapeVariables(xShape, wShape, outputShapeInShader)); const xNumber = (outputNumber - 1) * attributes.strides[1] + wShape[1]; const getShaderSource = (shaderHelper) => { const output = outputVariable("output", inputs[0].dataType, outputShapeInShader.length, components); const baseType = tensorTypeToWsglStorageType(output.type.tensor); const applyActivation = getActivationSnippet2(attributes, output.type.value, baseType); const x = inputVariable("x", inputs[0].dataType, xShape.length, components); const w = inputVariable("w", inputs[1].dataType, wShape.length, components); const inputVars = [x, w]; if (hasBias) { inputVars.push(inputVariable("b", inputs[2].dataType, inputs[2].dims, components)); } const processBias = hasBias ? "value += b[output_channel];" : ""; const uniforms = [ { name: "output_size", type: "u32" }, { name: "strides", type: "i32", length: 2 }, { name: "pads", type: "i32", length: 2 } ]; appendActivationUniforms(attributes, uniforms); return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVars, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let width0 = uniforms.output_shape[3]; let output_channel = global_idx % width0; var index1 = global_idx / width0; let width1 = uniforms.output_shape[2] / ${outputNumber}u; let col = (index1 % width1) * ${outputNumber}u; index1 = index1 / width1; let row = index1 % uniforms.output_shape[1]; let batch = index1 / uniforms.output_shape[1]; let x_corner = vec2(i32(row), i32(col)) * uniforms.strides - uniforms.pads; var x_vals: array<${x.type.value}, ${xNumber}>; var values: array<${output.type.value}, ${outputNumber}>; let input_channel = output_channel; // Use constant instead of uniform can give better performance for w's height/width. for (var w_height: u32 = 0u; w_height < ${wShape[0]}; w_height++) { let x_height = x_corner.x + i32(w_height); if (x_height >= 0 && u32(x_height) < uniforms.x_shape[1]) { for (var i = 0; i < ${xNumber}; i++) { let x_width = x_corner.y + i; if (x_width >= 0 && u32(x_width) < uniforms.x_shape[2]) { x_vals[i] = ${x.get("batch", "u32(x_height)", "u32(x_width)", "input_channel")}; } else { x_vals[i] = ${x.type.value}(0); } } for (var w_width: u32 = 0u; w_width < ${wShape[1]}; w_width++) { let w_val = ${w.get("w_height", "w_width", "0", "output_channel")}; for (var i = 0u; i < ${outputNumber}u; i++) { values[i] = fma(x_vals[i * u32(uniforms.strides[1]) + w_width], w_val, values[i]); } } } } for (var i = 0u; i < ${outputNumber}u; i++) { var value = values[i]; ${processBias} ${applyActivation} ${output.set("batch", "row", "col + i", "output_channel", "value")}; } }`; }; return { name: "GroupedConv-Vectorize", shaderCache: { hint: `${attributes.cacheKey};${components};${outputNumber};${xNumber};${wShape[0]};${wShape[1]}`, inputDependencies: hasBias ? ["rank", "rank", "type"] : ["rank", "rank"] }, getRunData: () => ({ outputs: [ { dims: squeezeOutputShapeFunction ? squeezeOutputShapeFunction(outputShape) : outputShape, dataType: inputs[0].dataType } ], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }; }; } }); // web/lib/wasm/jsep/webgpu/ops/conv.ts var calculateOutputShape2, weightTransposeAttribute, validateInputs33, getAdjustedConvAttributes2, parseConvAttributes2, conv2d2, conv1d, conv3d, conv2; var init_conv2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/conv.ts"() { "use strict"; init_util2(); init_conv2d_mm_webgpu(); init_conv3d_naive_webgpu(); init_matmul_packed_webgpu(); init_conv_grouped2(); init_fuse_utils2(); init_matmul_shaders(); init_transpose2(); calculateOutputShape2 = (inputShape, kernelShape, dilations, adjustPads, strides, isChannelLast) => { const batchSize = inputShape[0]; const inputSpatialShape = inputShape.slice(isChannelLast ? 1 : 2, isChannelLast ? 3 : 4); 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 outputShape = inputSpatialShapeWithPad.map( (v, i) => Math.floor((v - dilatedKernelShape[i] + strides[i]) / strides[i]) ); outputShape.splice(0, 0, batchSize); outputShape.splice(isChannelLast ? 3 : 1, 0, outChannels); return outputShape; }; weightTransposeAttribute = [2, 3, 1, 0]; validateInputs33 = (inputs, attributes) => { if (!inputs || inputs.length !== 2 && inputs.length !== 3) { throw new Error("Conv requires 2 or 3 inputs"); } if (inputs[0].dims.length > 5) { throw new Error("greater than 5D is not supported"); } if (inputs[0].dims.length !== inputs[1].dims.length) { throw new Error("filter does not have same dimension as input"); } const dataChannel = inputs[0].dims[attributes.format === "NHWC" ? inputs[0].dims.length - 1 : 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"); } }; getAdjustedConvAttributes2 = (attributes, inputs) => { const kernelShape = attributes.kernelShape.slice(); if (kernelShape.length < inputs[1].dims.length - 2) { kernelShape.push(...Array(inputs[1].dims.length - 2 - kernelShape.length).fill(0)); } for (let i = 2; i < inputs[1].dims.length; ++i) { if (kernelShape[i - 2] === 0) { kernelShape[i - 2] = inputs[1].dims[i]; } } const pads = attributes.pads.slice(); PoolConvUtil2.adjustPadsBasedOnAutoPad( inputs[0].dims, attributes.strides, attributes.dilations, kernelShape, pads, attributes.format === "NHWC", attributes.autoPad ); const newAttributes = Object.assign({}, attributes); Object.assign(newAttributes, { kernelShape, pads }); return newAttributes; }; parseConvAttributes2 = (attributes) => { const activationAttributes = parseInternalActivationAttributes2(attributes); const format = attributes.format; const autoPad = ["NOTSET", "VALID", "SAME_UPPER", "SAME_LOWER"][attributes.auto_pad]; const dilations = attributes.dilations; const group = attributes.group; const kernelShape = attributes.kernel_shape; const pads = attributes.pads; const strides = attributes.strides; const wIsConst = attributes.w_is_const(); return { autoPad, format, dilations, group, kernelShape, pads, strides, wIsConst, ...activationAttributes, cacheKey: `${attributes.format};${activationAttributes.activation};` }; }; conv2d2 = (context, inputs, attributes, squeezeOutputShapeFunction) => { const isChannelsLast = attributes.format === "NHWC"; const outputShape = calculateOutputShape2( inputs[0].dims, inputs[1].dims, attributes.dilations, attributes.pads, attributes.strides, isChannelsLast ); if (attributes.group !== 1) { const convInputs2 = [inputs[0]]; if (isChannelsLast) { const transposedWeight2 = context.kernelCustomData.wT ?? context.compute(createTransposeProgramInfo2(inputs[1], weightTransposeAttribute), { inputs: [1], outputs: [attributes.wIsConst ? -2 : -1] })[0]; if (attributes.wIsConst && !context.kernelCustomData.wT) { context.kernelCustomData.wT = transposedWeight2; } convInputs2.push(transposedWeight2); } else { convInputs2.push(inputs[1]); } if (inputs.length === 3) { convInputs2.push(inputs[2]); } const enableGroupedConvVectorize = !context.adapterInfo.isArchitecture("ampere"); if (enableGroupedConvVectorize && isChannelsLast && inputs[1].dims[0] === attributes.group && inputs[1].dims[1] === 1 && attributes.dilations[0] === 1 && attributes.dilations[1] === 1) { context.compute( createGroupedConvVectorizeProgramInfo(convInputs2, attributes, outputShape, squeezeOutputShapeFunction), { inputs: convInputs2 } ); } else { context.compute(createGroupedConvProgramInfo(convInputs2, attributes, outputShape, squeezeOutputShapeFunction), { inputs: convInputs2 }); } return; } const hasBias = inputs.length === 3; const inputHeight = inputs[0].dims[isChannelsLast ? 1 : 2]; const inputWidth = inputs[0].dims[isChannelsLast ? 2 : 3]; const inputChannels = inputs[0].dims[isChannelsLast ? 3 : 1]; const weightHeight = inputs[1].dims[2]; const weightWidth = inputs[1].dims[3]; const outHeight = outputShape[isChannelsLast ? 1 : 2]; const outWidth = outputShape[isChannelsLast ? 2 : 3]; const outChannels = outputShape[isChannelsLast ? 3 : 1]; const sameSize = isChannelsLast && weightHeight === inputHeight && weightWidth === inputWidth && attributes.pads[0] === 0 && attributes.pads[1] === 0; if (sameSize || weightHeight === 1 && weightWidth === 1 && attributes.dilations[0] === 1 && attributes.dilations[1] === 1 && attributes.strides[0] === 1 && attributes.strides[1] === 1 && attributes.pads[0] === 0 && attributes.pads[1] === 0) { const batch = outputShape[0]; let xReshaped, wReshaped, matmulOutputShape; const matmulInputs = []; if (isChannelsLast) { const transposedWeight2 = context.kernelCustomData.wT ?? context.compute(createTransposeProgramInfo2(inputs[1], weightTransposeAttribute), { inputs: [1], outputs: [attributes.wIsConst ? -2 : -1] })[0]; if (attributes.wIsConst && !context.kernelCustomData.wT) { context.kernelCustomData.wT = transposedWeight2; } if (sameSize) { const sharedDim = inputHeight * inputWidth * inputChannels; xReshaped = inputs[0].reshape([1, batch, sharedDim]); wReshaped = transposedWeight2.reshape([1, sharedDim, outChannels]); matmulOutputShape = [1, batch, outChannels]; } else { xReshaped = inputs[0].reshape([batch, inputHeight * inputWidth, inputChannels]); wReshaped = transposedWeight2.reshape([1, inputChannels, outChannels]); matmulOutputShape = [batch, outHeight * outWidth, outChannels]; } matmulInputs.push(xReshaped); matmulInputs.push(wReshaped); } else { xReshaped = inputs[0].reshape([batch, inputChannels, inputHeight * inputWidth]); wReshaped = inputs[1].reshape([1, outChannels, inputChannels]); matmulOutputShape = [batch, outChannels, outHeight * outWidth]; matmulInputs.push(wReshaped); matmulInputs.push(xReshaped); } if (hasBias) { matmulInputs.push(inputs[2]); } const N = matmulOutputShape[2]; const K = matmulInputs[0].dims[matmulInputs[0].dims.length - 1]; if (N < 8 && K < 8) { context.compute( createNaiveMatmulProgramInfo( matmulInputs, attributes, outputShape, matmulOutputShape, isChannelsLast, squeezeOutputShapeFunction ), { inputs: matmulInputs } ); } else { context.compute( createMatmulProgramInfo2( matmulInputs, attributes, outputShape, matmulOutputShape, isChannelsLast, squeezeOutputShapeFunction ), { inputs: matmulInputs } ); } return; } const sequentialAccessByThreads = ( /* backend.adapterInfo.isIntel() */ true ); const transposedWeight = context.kernelCustomData.wT ?? context.compute(createTransposeProgramInfo2(inputs[1], weightTransposeAttribute), { inputs: [1], outputs: [attributes.wIsConst ? -2 : -1] })[0]; if (attributes.wIsConst && !context.kernelCustomData.wT) { context.kernelCustomData.wT = transposedWeight; } const convInputs = [inputs[0], transposedWeight]; if (hasBias) { convInputs.push(inputs[2]); } const dimAOuter = isChannelsLast ? outHeight * outWidth : outChannels; const dimBOuter = isChannelsLast ? outChannels : outHeight * outWidth; const dimInner = weightHeight * weightWidth * inputChannels; context.compute( createConv2DMatMulProgramInfo( convInputs, attributes, outputShape, dimAOuter, dimBOuter, dimInner, hasBias, sequentialAccessByThreads, squeezeOutputShapeFunction ), { inputs: convInputs } ); }; conv1d = (context, attributes) => { const isChannelLast = attributes.format === "NHWC"; const inputs = [ context.inputs[0].reshape( isChannelLast ? ( // [N, W, C] -> [N, H=1, W, C] [context.inputs[0].dims[0], 1, context.inputs[0].dims[1], context.inputs[0].dims[2]] ) : ( // [N, C, W] -> [N, C, H=1, W] [context.inputs[0].dims[0], context.inputs[0].dims[1], 1, context.inputs[0].dims[2]] ) ), //[FILTER_OUT_CHANNEL, FILTER_IN_CHANNEL, kW] -> [FILTER_OUT_CHANNEL, FILTER_IN_CHANNEL, kH=1, kW] context.inputs[1].reshape([context.inputs[1].dims[0], context.inputs[1].dims[1], 1, context.inputs[1].dims[2]]) ]; if (context.inputs.length === 3) { inputs.push(context.inputs[2]); } const pads = [0, attributes.pads[0], 0, attributes.pads[1]]; const strides = [1].concat(attributes.strides); const dilations = [1].concat(attributes.dilations); const kernelShape = [1].concat(attributes.kernelShape); const adjustedAttributes = getAdjustedConvAttributes2( { ...attributes, pads, strides, dilations, kernelShape }, inputs ); conv2d2( context, inputs, adjustedAttributes, (outputShape) => isChannelLast ? [outputShape[0], outputShape[2], outputShape[3]] : [outputShape[0], outputShape[1], outputShape[3]] ); }; conv3d = (context, inputs, attributes) => { const format = attributes.format === "NHWC" ? "channelsLast" : "channelsFirst"; const adjustedAttributes = getAdjustedConvAttributes2(attributes, inputs); const pads = attributes.autoPad === "NOTSET" ? attributes.pads : attributes.autoPad; const convInfo = computeConv3DInfo( inputs[0].dims, inputs[1].dims, attributes.strides, attributes.dilations, pads, false, format ); context.compute( createConv3DNaiveProgramInfo( inputs, adjustedAttributes, convInfo.outShape, [convInfo.filterDepth, convInfo.filterHeight, convInfo.filterWidth], [convInfo.padInfo.front, convInfo.padInfo.top, convInfo.padInfo.left], format ) ); }; conv2 = (context, attributes) => { validateInputs33(context.inputs, attributes); if (context.inputs[0].dims.length === 3) { conv1d(context, attributes); } else if (context.inputs[0].dims.length === 5) { conv3d(context, context.inputs, attributes); } else { const adjustedAttributes = getAdjustedConvAttributes2(attributes, context.inputs); conv2d2(context, context.inputs, adjustedAttributes); } }; } }); // web/lib/wasm/jsep/webgpu/ops/3rd-party/conv_backprop_webgpu.ts var createConvTranspose2DProgramInfo; var init_conv_backprop_webgpu = __esm({ "web/lib/wasm/jsep/webgpu/ops/3rd-party/conv_backprop_webgpu.ts"() { "use strict"; init_wasm_common(); init_log(); init_util2(); init_common(); createConvTranspose2DProgramInfo = (inputs, attributes, squeezeOutputShapeFunction) => { const hasBias = inputs.length > 2; const outputShape = attributes.outputShape; const isChannelsLast = attributes.format === "NHWC"; const group = attributes.group; const wShape = inputs[1].dims; const inputChannelsPerGroup = wShape[2] / group; const outputChannelsPerGroup = wShape[3]; const aComponents = isChannelsLast ? getMaxComponents(inputChannelsPerGroup) : 1; const packInputAs4 = isChannelsLast && outputChannelsPerGroup === 1 && inputChannelsPerGroup >= 4; const inputChannelsPerGroupInt = packInputAs4 ? Math.floor(inputChannelsPerGroup / 4) * 4 : Math.floor(inputChannelsPerGroup / aComponents) * aComponents; const inputChannelsRemainder = inputChannelsPerGroup - inputChannelsPerGroupInt; const components = isChannelsLast ? getMaxComponents(outputChannelsPerGroup) : 1; const bComponents = isChannelsLast ? outputChannelsPerGroup === 1 ? aComponents : components : 1; const outputSize = ShapeUtil2.size(outputShape) / components; const dispatch = [Math.ceil(outputSize / 64), 1, 1]; LOG_DEBUG("verbose", () => `[conv2d_backprop_webgpu] dispatch = ${dispatch}`); const inputDependencies = ["rank", "rank"]; const strides = [attributes.strides[0], attributes.strides[1]]; const filterDims = [attributes.kernelShape[isChannelsLast ? 1 : 2], attributes.kernelShape[isChannelsLast ? 2 : 3]]; const dilations = [attributes.dilations[0], attributes.dilations[1]]; const effectiveFilterDims = [ filterDims[0] + (attributes.dilations[0] <= 1 ? 0 : (attributes.kernelShape[isChannelsLast ? 1 : 2] - 1) * (attributes.dilations[0] - 1)), filterDims[1] + (attributes.dilations[1] <= 1 ? 0 : (attributes.kernelShape[isChannelsLast ? 2 : 3] - 1) * (attributes.dilations[1] - 1)) ]; const pads = [ effectiveFilterDims[0] - 1 - Math.floor((attributes.pads[0] + attributes.pads[2]) / 2), effectiveFilterDims[1] - 1 - Math.floor((attributes.pads[1] + attributes.pads[3]) / 2) ]; const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: strides }, { type: 12 /* uint32 */, data: filterDims }, { type: 12 /* uint32 */, data: dilations }, { type: 12 /* uint32 */, data: effectiveFilterDims }, { type: 6 /* int32 */, data: pads }, { type: 12 /* uint32 */, data: inputChannelsPerGroupInt }, { type: 12 /* uint32 */, data: inputChannelsPerGroup }, { type: 12 /* uint32 */, data: outputChannelsPerGroup }, ...createTensorShapeVariables(inputs[0].dims, inputs[1].dims) ]; if (hasBias) { programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); inputDependencies.push("rank"); } programUniforms.push(...createTensorShapeVariables(outputShape)); const getShaderSource = (shaderHelper) => { const uniforms = [ { name: "output_size", type: "u32" }, { name: "strides", type: "u32", length: strides.length }, { name: "filter_dims", type: "u32", length: filterDims.length }, { name: "dilations", type: "u32", length: filterDims.length }, { name: "effective_filter_dims", type: "u32", length: effectiveFilterDims.length }, { name: "pads", type: "i32", length: pads.length }, { name: "input_channels_per_group_int", type: "u32" }, { name: "input_channels_per_group", type: "u32" }, { name: "output_channels_per_group", type: "u32" } ]; const dataType = tensorTypeToWsglStorageType(inputs[0].dataType); const rowDim = isChannelsLast ? 1 : 2; const colDim = isChannelsLast ? 2 : 3; const channelDim = isChannelsLast ? 3 : 1; const w = inputVariable("W", inputs[1].dataType, inputs[1].dims.length, bComponents); const dy = inputVariable("Dy", inputs[0].dataType, inputs[0].dims.length, aComponents); const inputVariables = [dy, w]; if (hasBias) { inputVariables.push(inputVariable("bias", inputs[2].dataType, [outputShape[channelDim]].length, components)); } const output = outputVariable("result", inputs[0].dataType, outputShape.length, components); const calculateResult = () => { let calcStr = ""; if (packInputAs4) { if (aComponents === 4) { calcStr += ` let xValue = ${dy.getByOffset("x_offset")}; let wValue = ${w.getByOffset("w_offset")}; dotProd = dotProd + dot(xValue, wValue); x_offset += 1u; w_offset += 1u;`; } else if (aComponents === 2) { calcStr += ` dotProd = dotProd + dot(vec4<${dataType}>(${dy.getByOffset("x_offset")}, ${dy.getByOffset("x_offset + 1u")}), vec4<${dataType}>(${w.getByOffset("w_offset")}, ${w.getByOffset("w_offset + 1u")})); x_offset += 2u; w_offset += 2u;`; } else if (aComponents === 1) { calcStr += ` dotProd = dotProd + dot(vec4<${dataType}>(${dy.getByOffset("x_offset")}, ${dy.getByOffset("x_offset + 1u")}, ${dy.getByOffset("x_offset + 2u")}, ${dy.getByOffset("x_offset + 3u")}), vec4<${dataType}>(${w.getByOffset("w_offset")}, ${w.getByOffset("w_offset + 1u")}, ${w.getByOffset("w_offset + 2u")}, ${w.getByOffset("w_offset + 3u")})); x_offset += 4u; w_offset += 4u;`; } } else { calcStr += ` let xValue = ${isChannelsLast ? dy.getByOffset( `${dy.indicesToOffset(`${dy.type.indices}(batch, idyR, idyC, inputChannel)`)} / ${aComponents}` ) : dy.get("batch", "inputChannel", "idyR", "idyC")}; `; if (aComponents === 1) { calcStr += ` let w_offset = ${w.indicesToOffset(`${w.type.indices}(u32(wRPerm), u32(wCPerm), inputChannel, wOutChannel)`)}; let wValue = ${w.getByOffset(`w_offset / ${bComponents}`)}; dotProd = dotProd + xValue * wValue;`; } else { for (let c = 0; c < aComponents; c++) { calcStr += ` let wValue${c} = ${w.getByOffset(`${w.indicesToOffset(`${w.type.indices}(u32(wRPerm), u32(wCPerm), inputChannel + ${c}, wOutChannel)`)} / ${bComponents}`)}; dotProd = dotProd + xValue[${c}] * wValue${c};`; } } } return calcStr; }; const calculateRemainder = () => { if (inputChannelsRemainder === 0) { return ""; } if (!packInputAs4) { throw new Error(`packInputAs4 ${packInputAs4} is not true.`); } let calcStr = ""; if (aComponents === 1) { calcStr += "dotProd = dotProd"; for (let i = 0; i < inputChannelsRemainder; i++) { calcStr += ` + ${dy.getByOffset(`x_offset + ${i}`)} * ${w.getByOffset(`w_offset + ${i}`)}`; } calcStr += ";"; } else if (aComponents === 2) { if (inputChannelsRemainder !== 2) { throw new Error(`Invalid inputChannelsRemainder ${inputChannelsRemainder}.`); } calcStr += ` let xValue = ${dy.getByOffset("x_offset")}; let wValue = ${w.getByOffset("w_offset")}; dotProd = dotProd + dot(xValue, wValue);`; } return calcStr; }; const codeSnippet = ` let outputIndices = ${output.offsetToIndices(`global_idx * ${components}`)}; let batch = ${output.indicesGet("outputIndices", 0)}; let d1 = ${output.indicesGet("outputIndices", channelDim)}; let r = ${output.indicesGet("outputIndices", rowDim)}; let c = ${output.indicesGet("outputIndices", colDim)}; let dyCorner = vec2(i32(r), i32(c)) - uniforms.pads; let dyRCorner = dyCorner.x; let dyCCorner = dyCorner.y; let groupId = d1 / uniforms.output_channels_per_group; let wOutChannel = d1 - groupId * uniforms.output_channels_per_group; // Convolve dy(?, ?, d2) with w(:, :, d1, d2) to compute dx(xR, xC, d1). // ? = to be determined. : = across all values in that axis. var dotProd = ${output.type.value}(0.0); var wR: u32 = 0; if (uniforms.dilations.x == 1) { // Minimum wR >= 0 that satisfies (dyRCorner + wR) % (uniforms.strides.x) == 0 wR = u32(((dyRCorner + i32(uniforms.strides.x) - 1) / i32(uniforms.strides.x)) * i32(uniforms.strides.x) - dyRCorner); } for (; wR < uniforms.effective_filter_dims.x; wR = wR + 1) { if (wR % uniforms.dilations.x != 0) { continue; } let dyR = (${dataType}(dyRCorner) + ${dataType}(wR)) / ${dataType}(uniforms.strides[0]); let wRPerm = uniforms.filter_dims.x - 1 - wR / uniforms.dilations.x; if (dyR < 0.0 || dyR >= ${dataType}(uniforms.Dy_shape[${rowDim}]) || fract(dyR) > 0.0 || wRPerm < 0) { continue; } let idyR: u32 = u32(dyR); var wC: u32 = 0; if (uniforms.dilations.y == 1) { // Minimum wC >= 0 that satisfies (dyCCorner + wC) % (uniforms.strides.y) == 0 wC = u32(((dyCCorner + i32(uniforms.strides.y) - 1) / i32(uniforms.strides.y)) * i32(uniforms.strides.y) - dyCCorner); } for (; wC < uniforms.effective_filter_dims.y; wC = wC + 1) { if (wC % uniforms.dilations.y != 0) { continue; } let dyC = (${dataType}(dyCCorner) + ${dataType}(wC)) / ${dataType}(uniforms.strides.y); let wCPerm = uniforms.filter_dims.y - 1 - wC / uniforms.dilations.y; if (dyC < 0.0 || dyC >= ${dataType}(uniforms.Dy_shape[${colDim}]) || fract(dyC) > 0.0 || wCPerm < 0) { continue; } let idyC: u32 = u32(dyC); var inputChannel = groupId * uniforms.input_channels_per_group; ${packInputAs4 ? ` var x_offset = ${dy.indicesToOffset(`${dy.type.indices}(batch, idyR, idyC, inputChannel)`)} / ${aComponents}; var w_offset = ${w.indicesToOffset(`${w.type.indices}(wRPerm, wCPerm, inputChannel, wOutChannel)`)} / ${bComponents}; ` : ""} for (var d2: u32 = 0; d2 < uniforms.input_channels_per_group_int; d2 = d2 + ${packInputAs4 ? 4 : aComponents}) { ${calculateResult()} inputChannel = inputChannel + ${packInputAs4 ? 4 : aComponents}; } ${calculateRemainder()} wC = wC + uniforms.strides.y - 1; } wR = wR + uniforms.strides[0] - 1; } let value = dotProd${hasBias ? ` + bias[d1 / ${components}]` : ""}; ${output.setByOffset("global_idx", "value")}; `; return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVariables, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")}; ${codeSnippet}}`; }; return { name: "ConvTranspose2D", shaderCache: { hint: `${attributes.cacheKey};${aComponents}${bComponents}${components}${packInputAs4}${inputChannelsRemainder}`, inputDependencies }, getRunData: () => ({ dispatchGroup: { x: dispatch[0], y: dispatch[1], z: dispatch[2] }, outputs: [ { dims: squeezeOutputShapeFunction ? squeezeOutputShapeFunction(outputShape) : outputShape, dataType: inputs[0].dataType } ], programUniforms }), getShaderSource }; }; } }); // web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts var computeTotalPad2, distributePadding2, calculateOutputShapeAndPads2, getAdjustedConvTransposeAttributes2, parseConvTransposeAttributes2, validateInputs34, convTranspose2d2, convTranspose1d, convTranspose2; var init_conv_transpose2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts"() { "use strict"; init_conv_backprop_webgpu(); init_fuse_utils2(); init_transpose2(); computeTotalPad2 = (inDim, stride, adj, kernel, dilation, outSize) => (inDim - 1) * stride + adj + (kernel - 1) * dilation + 1 - outSize; distributePadding2 = (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; } }; calculateOutputShapeAndPads2 = (inputShape, kernelShape, dilations, autoPad, group, pads, strides, isChannelLast, outputPadding, outputShape) => { const spatialRank = inputShape.length - 2; const updateOutputShape = outputShape.length === 0; if (outputPadding.length < spatialRank) { outputPadding.push(...Array(spatialRank - outputPadding.length).fill(0)); } const batchSize = inputShape[0]; const outChannels = kernelShape[isChannelLast ? 3 : 1] * group; for (let i = 0, j = inputShape.length - spatialRank - (isChannelLast ? 1 : 0); i < spatialRank; ++i, ++j) { const inSize = inputShape[j]; const outSize = updateOutputShape ? inSize * strides[i] : outputShape[i]; const totalPad = computeTotalPad2(inSize, strides[i], pads[i], kernelShape[j], dilations[i], outSize); distributePadding2(totalPad, autoPad, pads, i, i + spatialRank); if (updateOutputShape) { outputShape.push( strides[i] * (inSize - 1) + outputPadding[i] + (kernelShape[j] - 1) * dilations[i] + 1 - pads[i] - pads[i + spatialRank] ); } } outputShape.splice(0, 0, batchSize); outputShape.splice(isChannelLast ? 3 : 1, 0, outChannels); }; getAdjustedConvTransposeAttributes2 = (attributes, inputs) => { const kernelShape = attributes.kernelShape.slice(); if (attributes.kernelShape.length === 0 || attributes.kernelShape.reduce((a, b) => a * b, 1) === 0) { kernelShape.length = 0; for (let i = 2; i < inputs[1].dims.length; ++i) { kernelShape.push(inputs[1].dims[i]); } } const isChannelsLast = attributes.format === "NHWC"; kernelShape.splice(0, 0, inputs[1].dims[0]); kernelShape.splice(isChannelsLast ? 3 : 1, 0, inputs[1].dims[1]); const pads = attributes.pads.slice(); const outputShape = attributes.outputShape.slice(); const outputPadding = attributes.outputPadding.slice(); const inputShape = inputs[0].dims; let dilations = attributes.dilations.slice(); if (dilations.reduce((a, b) => a + b, 0) === 0) { const spatialRank = inputs[0].dims.length - 2; dilations = new Array(spatialRank).fill(1); } let strides = attributes.strides.slice(); if (strides.reduce((a, b) => a + b, 0) === 0) { const spatialRank = inputs[0].dims.length - 2; strides = new Array(spatialRank).fill(1); } calculateOutputShapeAndPads2( inputShape, kernelShape, dilations, attributes.autoPad, attributes.group, pads, strides, isChannelsLast, outputPadding, outputShape ); const newAttributes = Object.assign({}, attributes); Object.assign(newAttributes, { kernelShape, pads, outputPadding, outputShape, dilations, strides }); return newAttributes; }; parseConvTransposeAttributes2 = (attributes) => { const activationAttributes = parseInternalActivationAttributes2(attributes); const format = attributes.format; const autoPad = ["NOTSET", "VALID", "SAME_UPPER", "SAME_LOWER"][typeof attributes.autoPad == "undefined" ? 0 : attributes.autoPad]; const dilations = attributes.dilations; const group = attributes.group ?? 1; const kernelShape = attributes.kernelShape; const pads = attributes.pads; const strides = attributes.strides; const wIsConst = attributes.wIsConst(); const outputPadding = attributes.outputPadding; const outputShape = attributes.outputShape; return { autoPad, format, dilations, group, kernelShape, outputPadding, outputShape, pads, strides, wIsConst, ...activationAttributes, cacheKey: `${attributes.format};${activationAttributes.activation};` }; }; validateInputs34 = (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[0].dims.length !== 3) { throw new Error("currently only support 2-dimensional conv"); } if (inputs[0].dims.length !== inputs[1].dims.length) { throw new Error("filter does not have same dimension as input"); } const dataChannel = inputs[0].dims[attributes.format === "NHWC" ? inputs[0].dims.length - 1 : 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; const dilationsSet = attributes.dilations.reduce((a, b) => a + b, 0) > 0; if (dilationsSet && attributes.dilations.length !== spatialRank) { throw new Error(`dilations should be ${spatialRank}D`); } const stridesSet = attributes.strides.reduce((a, b) => a + b, 0) > 0; if (stridesSet && attributes.strides.length !== spatialRank) { throw new Error(`strides should be ${spatialRank}D`); } const padsSet = attributes.pads.reduce((a, b) => a + b, 0) > 0; if (padsSet && attributes.pads.length !== spatialRank * 2) { throw new Error(`pads should be ${spatialRank * 2}D`); } if (attributes.outputPadding.length !== spatialRank && attributes.outputPadding.length !== 0) { throw new Error(`output_padding should be ${spatialRank}D`); } const kernelShapeSet = attributes.kernelShape.reduce((a, b) => a + b, 0) > 0; if (kernelShapeSet && 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"); } }; convTranspose2d2 = (context, inputs, attributes, squeezeOutputShapeFunction) => { const transposedWeight = context.kernelCustomData.wT ?? context.compute(createTransposeProgramInfo2(inputs[1], [2, 3, 0, 1]), { inputs: [1], outputs: [attributes.wIsConst ? -2 : -1] })[0]; if (attributes.wIsConst && !context.kernelCustomData.wT) { context.kernelCustomData.wT = transposedWeight; } const convTransposeInputs = [inputs[0], transposedWeight]; if (inputs.length === 3) { convTransposeInputs.push(inputs[2]); } context.compute(createConvTranspose2DProgramInfo(convTransposeInputs, attributes, squeezeOutputShapeFunction), { inputs: convTransposeInputs }); }; convTranspose1d = (context, attributes) => { const isChannelLast = attributes.format === "NHWC"; const inputs = [ context.inputs[0].reshape( isChannelLast ? ( // [N, W, C] -> [N, H=1, W, C] [context.inputs[0].dims[0], 1, context.inputs[0].dims[1], context.inputs[0].dims[2]] ) : ( // [N, C, W] -> [N, C, H=1, W] [context.inputs[0].dims[0], context.inputs[0].dims[1], 1, context.inputs[0].dims[2]] ) ), //[FILTER_OUT_CHANNEL, FILTER_IN_CHANNEL, kW] -> [FILTER_OUT_CHANNEL, FILTER_IN_CHANNEL, kH=1, kW] context.inputs[1].reshape([context.inputs[1].dims[0], context.inputs[1].dims[1], 1, context.inputs[1].dims[2]]) ]; if (context.inputs.length === 3) { inputs.push(context.inputs[2]); } let kernelShape = attributes.kernelShape; if (kernelShape.length === 0 || kernelShape[0] === 0) { kernelShape = [context.inputs[1].dims[2]]; } let dilations = attributes.dilations; if (dilations.length === 0 || dilations[0] === 0) { dilations = [1]; } let strides = attributes.strides; if (strides.length === 0 || strides[0] === 0) { strides = [1]; } let pads = attributes.pads; if (pads.length === 0) { pads = [0, 0]; } pads = [0, pads[0], 0, pads[1]]; strides = [1].concat(strides); dilations = [1].concat(dilations); kernelShape = [1].concat(kernelShape); let outputPadding = attributes.outputPadding; outputPadding = [0].concat(outputPadding); const adjustedAttributes = getAdjustedConvTransposeAttributes2( { ...attributes, pads, strides, dilations, kernelShape, outputPadding }, inputs ); convTranspose2d2( context, inputs, adjustedAttributes, (outputShape) => isChannelLast ? [outputShape[0], outputShape[2], outputShape[3]] : [outputShape[0], outputShape[1], outputShape[3]] ); }; convTranspose2 = (context, attributes) => { validateInputs34(context.inputs, attributes); if (context.inputs[0].dims.length === 3) { convTranspose1d(context, attributes); } else { const adjustedAttributes = getAdjustedConvTransposeAttributes2(attributes, context.inputs); convTranspose2d2(context, context.inputs, adjustedAttributes); } }; } }); // web/lib/wasm/jsep/webgpu/ops/cumsum.ts var createCumsumProgramInfo, cumsum, parseCumSumAttributes; var init_cumsum = __esm({ "web/lib/wasm/jsep/webgpu/ops/cumsum.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); createCumsumProgramInfo = (inputType, inputShape, axisInput, attributes) => { const outputSize = ShapeUtil2.size(inputShape); const rank = inputShape.length; const input = inputVariable("input", inputType, rank); const output = outputVariable("output", inputType, rank); const axisValue = axisInput.dataType === 6 /* int32 */ ? axisInput.getInt32Array()[0] : Number(axisInput.getBigInt64Array()[0]); const axis = ShapeUtil2.normalizeAxis(axisValue, rank); const getShaderSource = (shaderHelper) => { const index = ` i32(${input.indicesGet("inputIndices", "uniforms.axis")}) `; const max = getElementAt("uniforms.input_shape", "uniforms.axis", rank); const lowerLimit = attributes.reverse ? index + (attributes.exclusive ? " + 1" : "") : "0"; const upperLimit = attributes.reverse ? max : index + (attributes.exclusive ? "" : " + 1"); return ` ${shaderHelper.registerUniform("outputSize", "u32").registerUniform("axis", "u32").declareVariables(input, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} var inputIndices = ${output.offsetToIndices("global_idx")}; var sum = ${output.type.value}(0); let first : i32 = ${lowerLimit}; let last : i32 = ${upperLimit}; for (var i : i32 = first; i < last; i++) { ${input.indicesSet("inputIndices", "uniforms.axis", "u32(i)")}; sum = sum + ${input.getByIndices("inputIndices")}; } ${output.setByOffset("global_idx", "sum")}; }`; }; return { name: "CumSum", shaderCache: { hint: attributes.cacheKey, inputDependencies: ["rank"] }, getRunData: () => ({ outputs: [{ dims: inputShape, dataType: inputType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms: [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: axis }, ...createTensorShapeVariables(inputShape, inputShape) ] }), getShaderSource }; }; cumsum = (context, attributes) => { const inputShape = context.inputs[0].dims; const inputType = context.inputs[0].dataType; const axis = context.inputs[1]; context.compute(createCumsumProgramInfo(inputType, inputShape, axis, attributes), { inputs: [0] }); }; parseCumSumAttributes = (attributes) => { const exclusive = attributes.exclusive === 1; const reverse = attributes.reverse === 1; return createAttributeWithCacheKey2({ exclusive, reverse }); }; } }); // web/lib/wasm/jsep/webgpu/ops/depth-to-space.ts var validateInputs35, permFunctionBody2, createDepthToSpaceProgramInfo, depthToSpace2, parseDepthToSpaceAttributes2; var init_depth_to_space2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/depth-to-space.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateInputs35 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("DepthToSpace requires 1 input."); } if (inputs[0].dims.length !== 4) { throw new Error("DepthToSpace requires 4D input."); } }; permFunctionBody2 = (perm, rank, input, output) => { const reverseFunc = []; reverseFunc.push(`fn perm(i: ${output.type.indices}) -> ${input.type.indices} { var a: ${input.type.indices};`); for (let i = 0; i < rank; ++i) { reverseFunc.push(input.indicesSet("a", perm[i], `i[${i}]`)); } reverseFunc.push("return a;}"); return reverseFunc.join("\n"); }; createDepthToSpaceProgramInfo = (inputTensor, attributes) => { let n, h, w, c; let shape2; let perm; const isChannelLast = attributes.format === "NHWC"; const blocksize = attributes.blocksize; const isDCRmode = attributes.mode === "DCR"; if (isChannelLast) { [n, h, w, c] = inputTensor.dims; shape2 = isDCRmode ? [n, h, w, blocksize, blocksize, c / blocksize ** 2] : [n, h, w, c / blocksize ** 2, blocksize, blocksize]; perm = isDCRmode ? [0, 1, 3, 2, 4, 5] : [0, 1, 4, 2, 5, 3]; } else { [n, h, w, c] = [inputTensor.dims[0], inputTensor.dims[2], inputTensor.dims[3], inputTensor.dims[1]]; shape2 = isDCRmode ? [n, blocksize, blocksize, c / blocksize ** 2, h, w] : [n, c / blocksize ** 2, blocksize, blocksize, h, w]; perm = isDCRmode ? [0, 3, 4, 1, 5, 2] : [0, 1, 4, 2, 5, 3]; } const reshapedInputTensor = inputTensor.reshape(shape2); const reshapedInputRank = reshapedInputTensor.dims.length; const inputDataType = inputTensor.dataType; const reshapedInput = inputVariable("a", inputDataType, reshapedInputRank); const permedOutput = outputVariable("output", inputDataType, reshapedInputRank); const getShaderSource = (shaderHelper) => ` ${shaderHelper.registerUniform("output_size", "u32").declareVariables(reshapedInput, permedOutput)} ${permFunctionBody2(perm, reshapedInputRank, reshapedInput, permedOutput)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let indices = ${permedOutput.offsetToIndices("global_idx")}; let aIndices = perm(indices); ${permedOutput.setByOffset("global_idx", reshapedInput.getByIndices("aIndices"))} }`; return { name: "DepthToSpace", shaderCache: { hint: `${inputTensor.dims};${attributes.blocksize};${attributes.mode}`, inputDependencies: ["rank"] }, getRunData: (inputs) => { const outputShape = isChannelLast ? [n, h * blocksize, w * blocksize, c / blocksize ** 2] : [n, c / blocksize ** 2, h * blocksize, w * blocksize]; const outputSize = ShapeUtil2.size(outputShape); const shapeBeforePerm = reshapedInputTensor.dims; const shapeAfterPerm = ShapeUtil2.sortBasedOnPerm(shapeBeforePerm, perm); return { outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms: [ { type: 12 /* uint32 */, data: outputSize }, ...createTensorShapeVariables(shapeBeforePerm, shapeAfterPerm) ] }; }, getShaderSource }; }; depthToSpace2 = (context, attributes) => { validateInputs35(context.inputs); context.compute(createDepthToSpaceProgramInfo(context.inputs[0], attributes)); }; parseDepthToSpaceAttributes2 = (attributes) => createAttributeWithCacheKey2({ blocksize: attributes.blocksize, mode: attributes.mode, format: attributes.format }); } }); // web/lib/wasm/jsep/webgpu/ops/einsum.ts var symbolPattern, termPattern, termPatternOnly, lhsPattern, lhsPatternOnly, EinsumTerm, EinsumEquation, appendMax, createEinsumProgramInfo, einsum, parseEinsumAttributes; var init_einsum = __esm({ "web/lib/wasm/jsep/webgpu/ops/einsum.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); symbolPattern = "[a-zA-Z]|\\.\\.\\."; termPattern = "(" + symbolPattern + ")+"; termPatternOnly = "^" + termPattern + "$"; lhsPattern = "(" + termPattern + ",)*" + termPattern; lhsPatternOnly = "^" + lhsPattern + "$"; EinsumTerm = class { constructor(inputIndex = -1) { this.symbolToIndices = /* @__PURE__ */ new Map(); this.inputIndex = inputIndex; } // Add a symbol to the term addSymbol(symbol, index) { let value = this.symbolToIndices.get(symbol); if (value === void 0) { value = [index]; } else { value.push(index); } this.symbolToIndices.set(symbol, value); } // -1 for output and 0, 1, 2, ... for inputs }; EinsumEquation = class { constructor(inputs, equation) { this.equation = equation; this.hasEllipsis = false; this.symbolToInfo = /* @__PURE__ */ new Map(); this.lhs = new Array(); this.outputDims = []; let [lhs, rhs] = equation.includes("->") ? equation.split("->", 2) : [equation, ""]; if (!lhs.match(RegExp(lhsPatternOnly))) { throw new Error("Invalid LHS term"); } const inputTerms = lhs.split(","); inputTerms.forEach((inputTerm, index) => { const dims = inputs[index].dims.slice(); if (!inputTerm.match(RegExp(termPatternOnly))) { throw new Error("Invalid LHS term"); } const einsumTerm = this.processTerm(inputTerm, true, dims, index); this.lhs.push(einsumTerm); }); if (rhs === "") { rhs += [...this.symbolToInfo.entries()].filter(([sym, info]) => info.count === 1 || sym === "...").map(([sym]) => sym).join(""); } else { if (!rhs.match(RegExp(termPattern))) { throw new Error("Invalid RHS"); } } const rhsSymbols = rhs.match(RegExp(symbolPattern, "g")); rhsSymbols?.forEach((symbol) => { if (symbol === "...") { this.outputDims = this.outputDims.concat(this.ellipsisDims); } else { const info = this.symbolToInfo.get(symbol); if (info === void 0) { throw new Error("Invalid RHS symbol"); } this.outputDims.push(info.dimValue); } }); this.rhs = this.processTerm(rhs, false, this.outputDims); } // End of EinsumEqation constructor // Add a symbol to the equation addSymbol(symbol, dimValue, inputIndex) { let info = this.symbolToInfo.get(symbol); if (info !== void 0) { if (info.dimValue !== dimValue && info.count !== 1) { throw new Error("Dimension mismatch"); } else { info.count++; info.inputIndices.push(inputIndex); } } else { info = { count: 1, dimValue, inputIndices: [inputIndex] }; } this.symbolToInfo.set(symbol, info); } // Process one input/output term processTerm(term, isInput, dims, index = -1) { const rank = dims.length; let ellipsis = false; let ellipsisDims = []; let nextDim = 0; if (!term.match(RegExp(termPatternOnly)) && !isInput && term !== "") { throw new Error("Invalid LHS term"); } const indexSymbols = term.match(RegExp(symbolPattern, "g")); const einsumTerm = new EinsumTerm(index); indexSymbols?.forEach((symbol, i) => { if (symbol === "...") { if (ellipsis) { throw new Error("Only one ellipsis is allowed per input term"); } ellipsis = true; const ellipsisDimLength = rank - indexSymbols.length + 1; if (ellipsisDimLength < 0) { throw new Error("Ellipsis out of bounds"); } ellipsisDims = dims.slice(nextDim, nextDim + ellipsisDimLength); if (this.hasEllipsis) { if (this.ellipsisDims.length !== ellipsisDims.length || this.ellipsisDims.toString() !== ellipsisDims.toString()) { throw new Error("Ellipsis dimensions mismatch"); } } else if (isInput) { this.hasEllipsis = true; this.ellipsisDims = ellipsisDims; } else { throw new Error("Ellipsis must be specified in the LHS"); } for (let j = 0; j < ellipsisDims.length; j++) { const symbol2 = String.fromCharCode("0".charCodeAt(0) + j); einsumTerm.addSymbol(symbol2, i + j); this.addSymbol(symbol2, dims[nextDim++], index); } } else { einsumTerm.addSymbol(symbol, i + (this.hasEllipsis ? this.ellipsisDims.length - 1 : 0)); this.addSymbol(symbol, dims[nextDim++], index); } }); return einsumTerm; } // Output dimensions of the equation }; appendMax = (name2) => name2 + "_max"; createEinsumProgramInfo = (inputShapes, dataType, einsumEquation, outputShape) => { const ranks = inputShapes.map((dims) => dims.length); const inputVars = ranks.map((rank, index) => inputVariable(`input${index}`, dataType, rank)); const outputSize = ShapeUtil2.size(outputShape); const output = outputVariable("output", dataType, outputShape.length); const uniformsSymbols = [...einsumEquation.symbolToInfo.keys()].filter( (symbol) => !einsumEquation.rhs.symbolToIndices.has(symbol) ); const getShaderSource = (shaderHelper) => { const idxCopy = []; const initProd = "var prod = 1.0;"; const initSum = "var sum = 0.0;"; const updateSum = "sum += prod;"; const reduceOpsSetIndices = []; const reduceOpsLoopHeaders = []; const reduceOpsLoopFooters = []; const reduceOpCompute = []; const isReduceOpsWithoutLoop = einsumEquation.symbolToInfo.size === einsumEquation.rhs.symbolToIndices.size; einsumEquation.symbolToInfo.forEach((info, symbol) => { if (einsumEquation.rhs.symbolToIndices.has(symbol)) { const outputIndex = einsumEquation.rhs.symbolToIndices.get(symbol)?.[0]; if (outputIndex !== void 0) { einsumEquation.lhs.forEach((term, i) => { if (info.inputIndices.includes(i)) { const indices = term.symbolToIndices.get(symbol); if (indices === void 0) { throw new Error("Invalid symbol error"); } indices.forEach((index) => { idxCopy.push( `${inputVars[i].indicesSet( `input${i}Indices`, index, output.indicesGet("outputIndices", outputIndex) )}` ); }); } }); } } else { einsumEquation.lhs.forEach((term, i) => { if (info.inputIndices.includes(i)) { const indices = term.symbolToIndices.get(symbol); if (indices === void 0) { throw new Error("Invalid symbol error"); } indices.forEach((index) => { reduceOpsSetIndices.push(`${inputVars[i].indicesSet(`input${i}Indices`, index, `${symbol}`)}`); }); reduceOpCompute.push(`prod *= ${inputVars[i].getByIndices(`input${i}Indices`)};`); } }); reduceOpsLoopHeaders.push( `for(var ${symbol}: u32 = 0; ${symbol} < uniforms.${appendMax(symbol)}; ${symbol}++) {` ); reduceOpsLoopFooters.push("}"); } }); const reduceOps2 = isReduceOpsWithoutLoop ? [ ...idxCopy, `let sum = ${inputVars.map((inputVar, i) => inputVar.getByIndices(`input${i}Indices`)).join(" * ")};` ] : [ ...idxCopy, initSum, ...reduceOpsLoopHeaders, ...reduceOpsSetIndices, initProd, ...reduceOpCompute, updateSum, ...reduceOpsLoopFooters ]; return ` ${shaderHelper.registerUniforms(uniformsSymbols.map((symbol) => ({ name: `${appendMax(symbol)}`, type: "u32" }))).registerUniform("outputSize", "u32").declareVariables(...inputVars, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} var outputIndices = ${output.offsetToIndices("global_idx")}; ${inputVars.map((_var, i) => `var input${i}Indices: ${inputVars[i].type.indices};`).join("\n")} ${reduceOps2.join("\n")}; ${output.setByOffset("global_idx", "sum")}; }`; }; return { name: "Einsum", shaderCache: { hint: einsumEquation.equation, inputDependencies: inputShapes.map(() => "rank") }, getRunData: () => { const programUniformsInit = uniformsSymbols.filter((symbol) => einsumEquation.symbolToInfo.has(symbol)).map((symbol) => ({ type: 12 /* uint32 */, data: einsumEquation.symbolToInfo.get(symbol)?.dimValue || 0 })); programUniformsInit.push({ type: 12 /* uint32 */, data: outputSize }); const programUniforms = inputShapes.map((dims, _) => [...createTensorShapeVariables(dims)]).reduce((acc, inputProgramUniforms) => acc.concat(inputProgramUniforms), programUniformsInit); programUniforms.push(...createTensorShapeVariables(outputShape)); return { outputs: [{ dims: outputShape, dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }; }, getShaderSource }; }; einsum = (context, attributes) => { const einsumEquation = new EinsumEquation(context.inputs, attributes.equation); const outputShape = einsumEquation.outputDims; const inputShapes = context.inputs.map((input, _) => input.dims); context.compute(createEinsumProgramInfo(inputShapes, context.inputs[0].dataType, einsumEquation, outputShape)); }; parseEinsumAttributes = (attributes) => { const equation = attributes.equation.replace(/\s+/g, ""); return createAttributeWithCacheKey2({ equation }); }; } }); // web/lib/wasm/jsep/webgpu/ops/expand.ts var validateInputs36, getAdjustedShape, calculateOutputShape3, createExpandProgramInfo, expand; var init_expand = __esm({ "web/lib/wasm/jsep/webgpu/ops/expand.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); validateInputs36 = (inputs) => { if (!inputs || inputs.length !== 2) { throw new Error("Expand requires 2 input."); } const inputShape = inputs[0].dims; const shape2 = Array.from(inputs[1].getBigInt64Array(), Number); let shapeIndex = shape2.length < inputShape.length ? 0 : shape2.length - inputShape.length; let inputShapeIndex = inputShape.length < shape2.length ? 0 : inputShape.length - shape2.length; for (; shapeIndex < shape2.length && inputShapeIndex < inputShape.length; ++shapeIndex, ++inputShapeIndex) { if (shape2[shapeIndex] !== inputShape[inputShapeIndex] && shape2[shapeIndex] !== 1 && inputShape[inputShapeIndex] !== 1) { throw new Error("Expand requires shape to be broadcastable to input"); } } }; getAdjustedShape = (shape1, shape2) => { const diff = shape1.length - shape2.length; const shape3 = []; for (let i = 0; i < diff; ++i) { shape3.push(shape1[i]); } for (let i = 0; i < shape2.length; ++i) { shape3.push(shape2[i] === 1 ? shape1[i + diff] : shape2[i]); } return shape3; }; calculateOutputShape3 = (inputShape, shape2) => inputShape.length > shape2.length ? getAdjustedShape(inputShape, shape2) : getAdjustedShape(shape2, inputShape); createExpandProgramInfo = (inputs) => { const inputShape = inputs[0].dims; const shape2 = Array.from(inputs[1].getBigInt64Array(), Number); const outputShape = calculateOutputShape3(inputShape, shape2); const dataType = inputs[0].dataType; const isBoolOrScalar = dataType === 9 /* bool */ || ShapeUtil2.size(inputShape) === 1; const iComponents = dataType === 9 /* bool */ ? 4 : inputShape.length > 0 && inputShape[inputShape.length - 1] % 4 === 0 ? 4 : 1; const components = isBoolOrScalar ? 4 : outputShape.length > 0 && outputShape[outputShape.length - 1] % 4 === 0 ? 4 : 1; const outputSize = Math.ceil(ShapeUtil2.size(outputShape) / components); const getShaderSource = (shaderHelper) => { const input = inputVariable("input", dataType, inputShape.length, iComponents); const output = outputVariable("output", dataType, outputShape.length, components); let assignment; if (dataType === 9 /* bool */) { const singleAssignment = (resStr, x, typeCast = "") => ` let outputIndices${x} = ${output.offsetToIndices(`outputOffset + ${x}u`)}; let offset${x} = ${input.broadcastedIndicesToOffset(`outputIndices${x}`, output)}; let index${x} = offset${x} / 4u; let component${x} = offset${x} % 4u; ${resStr}[${x}] = ${typeCast}(${input.getByOffset(`index${x}`)}[component${x}]); `; assignment = ` let outputOffset = global_idx * ${components}; var data = vec4(0); ${singleAssignment("data", 0, "u32")} ${singleAssignment("data", 1, "u32")} ${singleAssignment("data", 2, "u32")} ${singleAssignment("data", 3, "u32")} ${output.setByOffset("global_idx", "data")} }`; } else { assignment = ` let outputIndices = ${output.offsetToIndices(`global_idx * ${components}`)}; let inputOffset = ${input.broadcastedIndicesToOffset("outputIndices", output)}; let data = ${output.type.value}(${input.getByOffset(`inputOffset / ${iComponents}`)}); ${output.setByOffset("global_idx", "data")} }`; } return ` ${shaderHelper.registerUniform("vec_size", "u32").declareVariables(input, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.vec_size")} ${assignment}`; }; const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, ...createTensorShapeVariables(inputShape, outputShape) ]; return { name: "Expand", shaderCache: { hint: `${outputShape.length};${iComponents}${components}`, inputDependencies: ["rank"] }, getShaderSource, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }) }; }; expand = (context) => { validateInputs36(context.inputs); context.compute(createExpandProgramInfo(context.inputs), { inputs: [0] }); }; } }); // web/lib/wasm/jsep/webgpu/ops/fast-gelu.ts var createFastGeluProgramInfo, fastGelu2; var init_fast_gelu = __esm({ "web/lib/wasm/jsep/webgpu/ops/fast-gelu.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); init_unary_op2(); createFastGeluProgramInfo = (inputTensors) => { const dataType = inputTensors[0].dataType; const outputSize = ShapeUtil2.size(inputTensors[0].dims); const biasLength = ShapeUtil2.size(inputTensors[1].dims); const useVec4 = biasLength % 4 === 0; const getShaderSource = (shaderHelper) => { const x = inputVariable("x", dataType, [1], 4); const bias = inputVariable("bias", dataType, [1], 4); const y = outputVariable("y", dataType, [1], 4); const uniforms = [ { name: "output_vec_size", type: "u32" }, { name: "bias_size", type: "u32" } ]; const singleElementBias = (i) => ` let bias${i}_offset: u32 = (global_idx * 4 + ${i}) % uniforms.bias_size; let bias${i} = ${bias.getByOffset(`bias${i}_offset / 4`)}[bias${i}_offset % 4];`; const biasGetExpression = useVec4 ? ` let bias = ${bias.getByOffset("global_idx % (uniforms.bias_size / 4)")};` : `${singleElementBias(0)}${singleElementBias(1)}${singleElementBias(2)}${singleElementBias(3)} let bias = ${x.type.value}(bias0, bias1, bias2, bias3);`; return `${shaderHelper.registerUniforms(uniforms).declareVariables(x, bias, y)} ${fastGeluImpl(tensorTypeToWsglValueType(dataType))} ${shaderHelper.mainStart(WORKGROUP_SIZE)} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_vec_size")} let x = ${x.getByOffset("global_idx")}; ${biasGetExpression} let x_in = x + bias; ${y.setByOffset("global_idx", fastGeluExpression("x_in"))} }`; }; return { name: "FastGeluWithBias", shaderCache: { hint: `${useVec4}`, inputDependencies: ["type", "type"] }, getShaderSource, getRunData: (inputs) => ({ outputs: [{ dims: inputs[0].dims, dataType: inputs[0].dataType }], programUniforms: [ { type: 12 /* uint32 */, data: Math.ceil(outputSize / 4) }, { type: 12 /* uint32 */, data: biasLength } ], dispatchGroup: { x: Math.ceil(outputSize / WORKGROUP_SIZE / 4) } }) }; }; fastGelu2 = (context) => { if (context.inputs.length < 2 || ShapeUtil2.size(context.inputs[1].dims) === 0) { fastGelu(context); } else { context.compute(createFastGeluProgramInfo(context.inputs)); } }; } }); // web/lib/wasm/jsep/webgpu/ops/gather.ts var validateInputs37, createGatherProgramInfo2, parseGatherAttributes2, gather2; var init_gather2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/gather.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateInputs37 = (inputs) => { if (!inputs || inputs.length !== 2) { throw new Error("Gather requires 2 inputs."); } }; createGatherProgramInfo2 = (inputs, attributes) => { const inputShape = inputs[0].dims; const indicesShape = inputs[1].dims; const inputRank = inputShape.length; const axis = ShapeUtil2.normalizeAxis(attributes.axis, inputRank); const outputShape = inputShape.slice(0); outputShape.splice(axis, 1, ...indicesShape); const axisDimLimit = inputShape[axis]; const components = inputs[0].dataType === 9 /* bool */ ? 4 : 1; const outputSize = Math.ceil(ShapeUtil2.size(outputShape) / components); const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 6 /* int32 */, data: axisDimLimit }, { type: 12 /* uint32 */, data: axis }, ...createTensorShapeVariables(inputs[0].dims, inputs[1].dims, outputShape) ]; const getShaderSource = (shaderHelper) => { const data = inputVariable("data", inputs[0].dataType, inputs[0].dims.length, components); const indices = inputVariable("inputIndices", inputs[1].dataType, inputs[1].dims.length); const output = outputVariable("output", inputs[0].dataType, outputShape.length, components); const calcDataIndices = (x) => { const indicesRank = indicesShape.length; let calcStr = `var indicesIndices${x} = ${indices.type.indices}(0);`; for (let i = 0; i < indicesRank; i++) { calcStr += `${indicesRank > 1 ? `indicesIndices${x}[${i}]` : `indicesIndices${x}`} = ${outputShape.length > 1 ? `outputIndices${x}[uniforms.axis + ${i}]` : `outputIndices${x}`};`; } calcStr += ` var idx${x} = ${indices.getByIndices(`indicesIndices${x}`)}; if (idx${x} < 0) { idx${x} = idx${x} + uniforms.axisDimLimit; } var dataIndices${x} : ${data.type.indices}; `; for (let i = 0, j = 0; i < inputRank; i++) { if (i === axis) { calcStr += `${inputRank > 1 ? `dataIndices${x}[${i}]` : `dataIndices${x}`} = u32(idx${x});`; j += indicesRank; } else { calcStr += `${inputRank > 1 ? `dataIndices${x}[${i}]` : `dataIndices${x}`} = ${outputShape.length > 1 ? `outputIndices${x}[${j}]` : `outputIndices${x}`};`; j++; } } return calcStr; }; let assignment; if (inputs[0].dataType === 9 /* bool */) { const singleAssignment = (resStr, x, typeCast = "") => ` let outputIndices${x} = ${output.offsetToIndices(`outputOffset + ${x}u`)}; ${calcDataIndices(x)}; let offset${x} = ${data.indicesToOffset(`dataIndices${x}`)}; let index${x} = offset${x} / 4u; let component${x} = offset${x} % 4u; ${resStr}[${x}] = ${typeCast}(${data.getByOffset(`index${x}`)}[component${x}]); `; assignment = ` let outputOffset = global_idx * ${components}; var value = vec4(0); ${singleAssignment("value", 0, "u32")} ${singleAssignment("value", 1, "u32")} ${singleAssignment("value", 2, "u32")} ${singleAssignment("value", 3, "u32")} ${output.setByOffset("global_idx", "value")} `; } else { assignment = ` let outputIndices = ${output.offsetToIndices("global_idx")}; ${calcDataIndices("")}; let value = ${data.getByIndices("dataIndices")}; ${output.setByOffset("global_idx", "value")}; `; } return ` ${shaderHelper.registerUniform("outputSize", "u32").registerUniform("axisDimLimit", "i32").registerUniform("axis", "u32").declareVariables(data, indices, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} ${assignment} }`; }; return { name: "Gather", shaderCache: { hint: attributes.cacheKey, inputDependencies: ["rank", "rank"] }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }; }; parseGatherAttributes2 = (attributes) => createAttributeWithCacheKey2({ axis: attributes.axis }); gather2 = (context, attributes) => { const inputs = context.inputs; validateInputs37(inputs); context.compute(createGatherProgramInfo2(context.inputs, attributes)); }; } }); // web/lib/wasm/jsep/webgpu/ops/gather-nd.ts var computeSliceOffsets, gatherND, parseGatherNDAttributes; var init_gather_nd = __esm({ "web/lib/wasm/jsep/webgpu/ops/gather-nd.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); computeSliceOffsets = (context, indicesData, sizesFromSliceDimsData, batchDims, inputDims, numSlices, numSlicesPerBatch, inputBatchStride, numSliceDims) => { const programUniforms = [ { type: 12 /* uint32 */, data: numSlices }, { type: 12 /* uint32 */, data: batchDims }, { type: 12 /* uint32 */, data: inputDims }, { type: 12 /* uint32 */, data: sizesFromSliceDimsData }, { type: 12 /* uint32 */, data: numSlicesPerBatch }, { type: 12 /* uint32 */, data: inputBatchStride }, { type: 12 /* uint32 */, data: numSliceDims } ]; const outputShape = [numSlices]; programUniforms.push(...createTensorShapeVariables(indicesData.dims, outputShape)); const getShaderSource = (shaderHelper) => { const indices = inputVariable("indices_data", indicesData.dataType, indicesData.dims.length); const output = outputVariable("input_slice_offsets_data", 12 /* uint32 */, 1, 1); const variables = [indices, output]; const uniforms = [ { name: "output_size", type: "u32" }, { name: "batch_dims", type: "u32" }, { name: "input_dims", type: "u32", length: inputDims.length }, { name: "sizes_from_slice_dims_data", type: "u32", length: sizesFromSliceDimsData.length }, { name: "num_slices_per_batch", type: "u32" }, { name: "input_batch_stride", type: "u32" }, { name: "num_slice_dims", type: "u32" } ]; return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(...variables)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let batch_idx = global_idx / uniforms.num_slices_per_batch; let base_offset = batch_idx * uniforms.input_batch_stride; let slice_indices_base_offset = global_idx * uniforms.num_slice_dims; var relative_slice_offset = 0; for (var dim_idx = 0u; dim_idx < uniforms.num_slice_dims; dim_idx ++) { var index = i32(indices_data[dim_idx + slice_indices_base_offset].x); let input_dim_idx = uniforms.batch_dims + dim_idx; if (index < 0) { ${inputDims.length === 1 ? "index += i32(uniforms.input_dims);" : "index += i32(uniforms.input_dims[input_dim_idx]);"} } ${sizesFromSliceDimsData.length === 1 ? "relative_slice_offset += index * i32(uniforms.sizes_from_slice_dims_data);" : "relative_slice_offset += index * i32(uniforms.sizes_from_slice_dims_data[dim_idx]);"} } input_slice_offsets_data[global_idx] = base_offset + u32(relative_slice_offset); }`; }; return context.compute( { name: "computeSliceOffsets", shaderCache: { hint: `${inputDims.length}_${sizesFromSliceDimsData.length}`, inputDependencies: ["rank"] }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: context.inputs[1].dataType }], dispatchGroup: { x: Math.ceil(numSlices / 64) }, programUniforms }), getShaderSource }, { inputs: [indicesData], outputs: [-1] } )[0]; }; gatherND = (context, attributes) => { const inputs = context.inputs; const inputShape = inputs[0].dims; const inputType = inputs[0].dataType; const indicesShape = inputs[1].dims; const numSliceDims = indicesShape[indicesShape.length - 1]; const numSlices = ShapeUtil2.sizeToDimension(indicesShape, indicesShape.length - 1); const sliceSize = ShapeUtil2.sizeFromDimension(inputShape, attributes.batchDims + numSliceDims); const numBatches = ShapeUtil2.sizeToDimension(inputShape, attributes.batchDims); const inputBatchStride = ShapeUtil2.sizeFromDimension(inputShape, attributes.batchDims); const numSlicesPerBatch = numSlices / numBatches; const sizesFromSliceDims = new Array(numSliceDims); let runningProduct = sliceSize; for (let i = 0; i < numSliceDims; ++i) { sizesFromSliceDims[numSliceDims - 1 - i] = runningProduct; runningProduct *= inputShape[attributes.batchDims + numSliceDims - 1 - i]; } const inputSliceOffsets = computeSliceOffsets( context, inputs[1], sizesFromSliceDims, attributes.batchDims, inputShape, numSlices, numSlicesPerBatch, inputBatchStride, numSliceDims ); const lastIndicesDimension = attributes.batchDims + numSliceDims; if (lastIndicesDimension > inputShape.length) { throw new Error("last dimension of indices must not be larger than rank of input tensor"); } const outputShape = indicesShape.slice(0, -1).concat(inputShape.slice(lastIndicesDimension)); const outputSize = ShapeUtil2.size(outputShape); const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: sliceSize }, ...createTensorShapeVariables(inputs[0].dims, inputSliceOffsets.dims, outputShape) ]; const getShaderSource = (shaderHelper) => { const input = inputVariable("data", inputs[0].dataType, inputs[0].dims.length); const indices = inputVariable("slice_offsets", 12 /* uint32 */, inputSliceOffsets.dims.length); const output = outputVariable("output", inputs[0].dataType, outputShape.length); return ` ${shaderHelper.registerUniform("output_size", "u32").registerUniform("slice_size", "u32").declareVariables(input, indices, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let slice_offset = slice_offsets[global_idx / uniforms.slice_size]; output[global_idx] = data[u32(slice_offset) + global_idx % uniforms.slice_size]; }`; }; context.compute( { name: "GatherND", shaderCache: { hint: attributes.cacheKey, inputDependencies: ["rank", "rank"] }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }, { inputs: [inputs[0], inputSliceOffsets] } ); }; parseGatherNDAttributes = (attributes) => { const batchDims = attributes.batch_dims; return { batchDims, cacheKey: "" }; }; } }); // web/lib/wasm/jsep/webgpu/ops/gather-block-quantized.ts var validateInputs38, createGatherBlockQuantizedProgramInfo, gatherBlockQuantized, parseGatherBlockQuantizedAttributes; var init_gather_block_quantized = __esm({ "web/lib/wasm/jsep/webgpu/ops/gather-block-quantized.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateInputs38 = (inputs, attributes) => { if (inputs.length < 3 || inputs.length > 4) { throw new Error("GatherBlockQuantized requires 3 or 4 inputs."); } const quantizeAxis = ShapeUtil2.normalizeAxis(attributes.quantizeAxis, inputs[0].dims.length); const blockSize = attributes.blockSize; const data = inputs[0]; const scales = inputs[2]; const zeroPoint = inputs.length === 4 ? inputs[3] : void 0; if (scales.dims.length !== data.dims.length || !data.dims.map((d, i) => i === quantizeAxis ? Math.ceil(d / blockSize) === scales.dims[i] : d === scales.dims[i]).reduce((a, b) => a && b, true)) { throw new Error( "Scales must have the same rank as the input tensor and the dims should match except on gatherAxis." ); } if (zeroPoint) { if (zeroPoint.dataType !== data.dataType) { throw new Error("Zero point must have the same data type as the input tensor."); } if (zeroPoint.dims.length !== scales.dims.length || !zeroPoint.dims.map((d, i) => d === scales.dims[i]).reduce((a, b) => a && b, true)) { throw new Error( "Zero point must have the same rank as the input tensor and the dims should match except on quantizeAxis." ); } } }; createGatherBlockQuantizedProgramInfo = (inputs, attributes) => { const inputShape = inputs[0].dims; const indicesShape = inputs[1].dims; const inputRank = inputShape.length; const gatherAxis = ShapeUtil2.normalizeAxis(attributes.gatherAxis, inputRank); const quantizeAxis = ShapeUtil2.normalizeAxis(attributes.quantizeAxis, inputRank); const outputShape = inputShape.slice(0); outputShape.splice(gatherAxis, 1, ...indicesShape); const outputSize = ShapeUtil2.size(outputShape); const outputType = inputs[2].dataType; const inputType = inputs[0].dataType; const isSigned = inputType === 22 /* int4 */; const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: quantizeAxis }, { type: 12 /* uint32 */, data: gatherAxis }, { type: 12 /* uint32 */, data: attributes.blockSize }, ...createTensorShapeVariables(...inputs.map((input, _) => input.dims), outputShape) ]; const getShaderSource = (shaderHelper) => { const data = inputVariable("data", inputs[0].dataType, inputs[0].dims.length); const indices = inputVariable("inputIndices", inputs[1].dataType, inputs[1].dims.length); const scales = inputVariable("scales", inputs[2].dataType, inputs[2].dims.length); const zeroPoint = inputs.length > 3 ? inputVariable("zeroPoint", inputs[3].dataType, inputs[3].dims.length) : void 0; const output = outputVariable("output", outputType, outputShape.length); const inputVariables = [data, indices, scales]; if (zeroPoint) { inputVariables.push(zeroPoint); } const uniforms = [ { name: "output_size", type: "u32" }, { name: "quantize_axis", type: "u32" }, { name: "gather_axis", type: "u32" }, { name: "block_size", type: "u32" } ]; return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVariables, output)} ${shaderHelper.mainStart()} let output_indices = ${output.offsetToIndices("global_idx")}; var indices_indices = ${indices.type.indices}(0); ${(() => { if (indicesShape.length > 1) { return ` for (var i: u32 = 0; i < ${indicesShape.length}; i++) { let index = ${output.indicesGet("output_indices", "uniforms.gather_axis + i")}; ${indices.indicesSet("indices_indices", "i", "index")}; }`; } else { return `indices_indices = ${output.indicesGet("output_indices", "uniforms.gather_axis")};`; } })()}; var data_indices = ${data.type.indices}(0); for (var i: u32 = 0; i < uniforms.gather_axis; i++) { let index = ${output.indicesGet("output_indices", "i")}; ${data.indicesSet("data_indices", "i", "index")}; } var index_from_indices = ${indices.getByIndices("indices_indices")}; if (index_from_indices < 0) { index_from_indices += ${inputShape[gatherAxis]}; } ${data.indicesSet("data_indices", "uniforms.gather_axis", "u32(index_from_indices)")}; for (var i = uniforms.gather_axis + 1; i < ${outputShape.length}; i++) { let index = ${output.indicesGet("output_indices", `i + ${indicesShape.length} - 1`)}; ${data.indicesSet("data_indices", "i", "index")}; } let data_offset = ${data.indicesToOffset("data_indices")}; let data_index = data_offset % 8; // Convert 4-bit packed data to 8-bit packed data. let packed_4bit_quantized_data = ${data.getByOffset("data_offset / 8")}; let packed_8bit_quantized_data = (packed_4bit_quantized_data >> (4 * (data_index % 2))) & 0x0f0f0f0f; let quantized_data_vec = ${isSigned ? "unpack4xI8" : "unpack4xU8"}(u32(packed_8bit_quantized_data)); let quantized_data = quantized_data_vec[data_index / 2]; var scale_indices = data_indices; let quantize_axis_index = ${scales.indicesGet("data_indices", "uniforms.quantize_axis")} / uniforms.block_size; ${scales.indicesSet("scale_indices", "uniforms.quantize_axis", "quantize_axis_index")}; var scale = ${scales.getByIndices("scale_indices")}; ${(() => { if (!zeroPoint) { return "var zero_point = 0"; } else { return ` let zero_point_indices = scale_indices; let zero_point_offset = ${zeroPoint.indicesToOffset("zero_point_indices")}; let zero_point_index = zero_point_offset % 8; let packed_4bit_zero_points = ${zeroPoint.getByOffset("zero_point_offset / 8")}; let packed_8bit_zero_points = (packed_4bit_zero_points >> (4 * (zero_point_index % 2))) & 0x0f0f0f0f; let zero_point_vec = ${isSigned ? "unpack4xI8" : "unpack4xU8"}(u32(packed_8bit_zero_points)); let zero_point = zero_point_vec[zero_point_index / 2];`; } })()}; let dequantized_data = ${tensorTypeToWsglValueType(outputType)}(quantized_data - zero_point) * scale; ${output.setByOffset("global_idx", "dequantized_data")}; }`; }; return { name: "GatherBlockQuantized", shaderCache: { hint: `${attributes.cacheKey};${inputs.filter((_, i) => i !== 1).map((input) => input.dims.join("_")).join(";")}`, inputDependencies: Array.from({ length: inputs.length }, (_v, _i) => "rank") }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: outputType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }; }; gatherBlockQuantized = (context, attributes) => { const inputs = context.inputs; validateInputs38(inputs, attributes); context.compute(createGatherBlockQuantizedProgramInfo(context.inputs, attributes)); }; parseGatherBlockQuantizedAttributes = (attributes) => createAttributeWithCacheKey2({ blockSize: attributes.blockSize, gatherAxis: attributes.gatherAxis, quantizeAxis: attributes.quantizeAxis }); } }); // web/lib/wasm/jsep/webgpu/ops/gather-elements.ts var validateInputs39, createGatherElementsProgramInfo, parseGatherElementsAttributes, gatherElements; var init_gather_elements = __esm({ "web/lib/wasm/jsep/webgpu/ops/gather-elements.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateInputs39 = (inputs) => { if (!inputs || inputs.length !== 2) { throw new Error("GatherElements requires 2 inputs."); } if (inputs[0].dims.length < 1) { throw new Error("GatherElements requires that the data input be rank >= 1."); } if (inputs[0].dims.length !== inputs[1].dims.length) { throw new Error(`GatherElements requires that the data input and indices input tensors be of same rank.`); } }; createGatherElementsProgramInfo = (inputs, attributes) => { const inputShape = inputs[0].dims; const inputOutputDataType = inputs[0].dataType; const inputRank = inputShape.length; const indicesShape = inputs[1].dims; const indicesDataType = inputs[1].dataType; const axis = ShapeUtil2.normalizeAxis(attributes.axis, inputRank); const axisDimLimit = inputShape[axis]; const outputShape = indicesShape.slice(0); const outputSize = ShapeUtil2.size(outputShape); const input = inputVariable("input", inputOutputDataType, inputRank); const indices = inputVariable("indicesInput", indicesDataType, indicesShape.length); const output = outputVariable("output", inputOutputDataType, outputShape.length); const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 6 /* int32 */, data: axisDimLimit }, { type: 12 /* uint32 */, data: axis } ]; programUniforms.push(...createTensorShapeVariables(inputShape, indicesShape, outputShape)); const inputDependencies = ["rank", "rank"]; const getShaderSource = (shaderHelper) => ` ${shaderHelper.registerUniform("outputSize", "u32").registerUniform("axisDimLimit", "i32").registerUniform("axis", "u32").declareVariables(input, indices, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} let outputIndices = ${output.offsetToIndices("global_idx")}; var idx = ${indices.getByOffset("global_idx")}; if (idx < 0) { idx = idx + uniforms.axisDimLimit; } var inputIndices = ${input.type.indices}(outputIndices); ${input.indicesSet("inputIndices", "uniforms.axis", "u32(idx)")}; let value = ${input.getByIndices("inputIndices")}; ${output.setByOffset("global_idx", "value")}; }`; return { name: "GatherElements", shaderCache: { inputDependencies }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }; }; parseGatherElementsAttributes = (attributes) => createAttributeWithCacheKey2({ axis: attributes.axis }); gatherElements = (context, attributes) => { const inputs = context.inputs; validateInputs39(inputs); context.compute(createGatherElementsProgramInfo(context.inputs, attributes)); }; } }); // web/lib/wasm/jsep/webgpu/ops/gemm.ts var validateInputs40, createGemmProgramInfo2, parseGemmAttributes2, gemm2; var init_gemm2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/gemm.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); validateInputs40 = (inputs) => { if (!inputs) { throw new Error("Input is missing"); } if (inputs.length < 2 || inputs.length > 3) { throw new Error("Invaid input number."); } if (inputs.length === 3 && inputs[2].dims.length > 2) { throw new Error("Invalid input shape of C"); } if (inputs[0].dataType !== inputs[1].dataType || inputs.length === 3 && inputs[0].dataType !== inputs[2].dataType) { throw new Error("Input types are mismatched"); } }; createGemmProgramInfo2 = (inputs, attributes) => { const aShape = inputs[0].dims.slice(); const bShape = inputs[1].dims.slice(); const [M, N, K] = GemmUtil2.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"); } const tileSize = 16; const numTileN = Math.ceil(N / tileSize); const numTileM = Math.ceil(M / tileSize); const useShared = true; const outputSize = ShapeUtil2.size(outputShape); const programUniforms = [ { type: 12 /* uint32 */, data: useShared ? numTileN : outputSize }, { type: 12 /* uint32 */, data: M }, { type: 12 /* uint32 */, data: N }, { type: 12 /* uint32 */, data: K }, { type: 1 /* float */, data: attributes.alpha }, { type: 1 /* float */, data: attributes.beta } ]; const inputDependencies = ["type", "type"]; if (inputs.length === 3) { programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); inputDependencies.push("rank"); } programUniforms.push(...createTensorShapeVariables(outputShape)); const getShaderSource = (shaderHelper) => { let line = ""; if (attributes.transA && attributes.transB) { line = "value += a[k * uniforms.M + m] * b[n * uniforms.K + k];"; } else if (attributes.transA && !attributes.transB) { line = "value += a[k * uniforms.M + m] * b[k * uniforms.N + n];"; } else if (!attributes.transA && attributes.transB) { line = "value += a[m * uniforms.K + k] * b[n * uniforms.K + k];"; } else if (!attributes.transA && !attributes.transB) { line = "value += a[m * uniforms.K + k] * b[k * uniforms.N + n];"; } const calculateAlpha = attributes.alpha === 1 ? "" : "value *= uniforms.alpha;"; const a = inputVariable("a", inputs[0].dataType, inputs[0].dims); const b = inputVariable("b", inputs[1].dataType, inputs[1].dims); const dataType = a.type.value; let c = null; const variables = [a, b]; if (inputs.length === 3) { c = inputVariable("c", inputs[2].dataType, inputs[2].dims.length); variables.push(c); } const output = outputVariable("output", inputs[0].dataType, outputShape.length); variables.push(output); const uniforms = [ { name: "output_size", type: "u32" }, { name: "M", type: "u32" }, { name: "N", type: "u32" }, { name: "K", type: "u32" }, { name: "alpha", type: "f32" }, { name: "beta", type: "f32" } ]; return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(...variables)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let m = global_idx / uniforms.N; let n = global_idx % uniforms.N; var value = ${dataType}(0); for (var k: u32 = 0u; k < uniforms.K; k++) { ${line} } ${calculateAlpha} ${(() => { if (c != null) { return `let cOffset = ${c.broadcastedIndicesToOffset("vec2(m, n)", output)}; value += ${dataType}(uniforms.beta) * ${c.getByOffset("cOffset")};`; } return ""; })()} output[global_idx] = value; }`; }; const getShaderSourceShared = (shaderHelper) => { const a = inputVariable("a", inputs[0].dataType, inputs[0].dims); const b = inputVariable("b", inputs[1].dataType, inputs[1].dims); let c = null; const variables = [a, b]; if (inputs.length === 3) { c = inputVariable("c", inputs[2].dataType, inputs[2].dims.length); variables.push(c); } const output = outputVariable("output", inputs[0].dataType, outputShape.length); variables.push(output); const uniforms = [ { name: "num_tile_n", type: "u32" }, { name: "M", type: "u32" }, { name: "N", type: "u32" }, { name: "K", type: "u32" }, { name: "alpha", type: "f32" }, { name: "beta", type: "f32" } ]; let calcResult = ""; let fillWorkgroupMemory = ""; if (attributes.transA && attributes.transB) { fillWorkgroupMemory = ` var col = tile_row_start + local_id.x; var row = k_start + local_id.y; if (col < uniforms.M && row < uniforms.K) { tile_a[local_id.y][local_id.x] = a[row * uniforms.M + col]; } else { tile_a[local_id.y][local_id.x] = ${a.type.value}(0); } col = k_start + local_id.x; row = tile_col_start + local_id.y; if (col < uniforms.K && row < uniforms.N) { tile_b[local_id.y][local_id.x] = b[row * uniforms.K + col]; } else { tile_b[local_id.y][local_id.x] = ${b.type.value}(0); } `; calcResult = `value += tile_a[k][local_id.y] * tile_b[local_id.x][k];`; } else if (attributes.transA && !attributes.transB) { fillWorkgroupMemory = ` var col = tile_row_start + local_id.x; var row = k_start + local_id.y; if (col < uniforms.M && row < uniforms.K) { tile_a[local_id.y][local_id.x] = a[row * uniforms.M + col]; } else { tile_a[local_id.y][local_id.x] = ${a.type.value}(0); } col = tile_col_start + local_id.x; row = k_start + local_id.y; if (col < uniforms.N && row < uniforms.K) { tile_b[local_id.y][local_id.x] = b[row * uniforms.N + col]; } else { tile_b[local_id.y][local_id.x] = ${b.type.value}(0); } `; calcResult = `value += tile_a[k][local_id.y] * tile_b[k][local_id.x];`; } else if (!attributes.transA && attributes.transB) { fillWorkgroupMemory = ` var col = k_start + local_id.x; var row = tile_row_start + local_id.y; if (col < uniforms.K && row < uniforms.M) { tile_a[local_id.y][local_id.x] = a[row * uniforms.K + col]; } else { tile_a[local_id.y][local_id.x] = ${a.type.value}(0); } col = k_start + local_id.x; row = tile_col_start + local_id.y; if (col < uniforms.K && row < uniforms.N) { tile_b[local_id.y][local_id.x] = b[row * uniforms.K + col]; } else { tile_b[local_id.y][local_id.x] = ${b.type.value}(0); } `; calcResult = `value += tile_a[local_id.y][k] * tile_b[local_id.x][k];`; } else if (!attributes.transA && !attributes.transB) { fillWorkgroupMemory = ` var col = k_start + local_id.x; var row = tile_row_start + local_id.y; if (col < uniforms.K && row < uniforms.M) { tile_a[local_id.y][local_id.x] = a[row * uniforms.K + col]; } else { tile_a[local_id.y][local_id.x] = ${a.type.value}(0); } col = tile_col_start + local_id.x; row = k_start + local_id.y; if (col < uniforms.N && row < uniforms.K) { tile_b[local_id.y][local_id.x] = b[row * uniforms.N + col]; } else { tile_b[local_id.y][local_id.x] = ${b.type.value}(0); } `; calcResult = `value += tile_a[local_id.y][k] * tile_b[k][local_id.x];`; } const calculateAlpha = attributes.alpha === 1 ? "" : "value *= uniforms.alpha;"; return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(...variables)} var tile_a: array, ${tileSize}>; var tile_b: array, ${tileSize}>; ${shaderHelper.mainStart([tileSize, tileSize, 1])} let tile_col_start = (workgroup_index % uniforms.num_tile_n) * ${tileSize}; let tile_row_start = (workgroup_index / uniforms.num_tile_n) * ${tileSize}; let num_tiles = (uniforms.K - 1) / ${tileSize} + 1; var k_start = 0u; var value = ${output.type.value}(0); for (var t: u32 = 0u; t < num_tiles; t++) { ${fillWorkgroupMemory} k_start = k_start + ${tileSize}; workgroupBarrier(); for (var k: u32 = 0u; k < ${tileSize}; k++) { ${calcResult} } workgroupBarrier(); } ${calculateAlpha} let m = tile_row_start + local_id.y; let n = tile_col_start + local_id.x; ${(() => { if (c != null) { return `let cOffset = ${c.broadcastedIndicesToOffset("vec2(m, n)", output)}; value += ${output.type.value}(uniforms.beta) * ${c.getByOffset("cOffset")};`; } return ""; })()} if (m < uniforms.M && n < uniforms.N) { output[m * uniforms.N + n] = value; } }`; }; if (useShared) { return { name: "GemmShared", shaderCache: { hint: `${attributes.cacheKey}`, inputDependencies }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: numTileN * numTileM }, programUniforms }), getShaderSource: getShaderSourceShared }; } return { name: "Gemm", shaderCache: { hint: `${attributes.cacheKey}`, inputDependencies }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }; }; parseGemmAttributes2 = (attributes) => { const transA = attributes.transA; const transB = attributes.transB; const alpha = attributes.alpha; const beta = attributes.beta; return { transA, transB, alpha, beta, cacheKey: `${attributes.transA};${attributes.transB};${attributes.alpha === 1}` }; }; gemm2 = (context, attributes) => { validateInputs40(context.inputs); context.compute(createGemmProgramInfo2(context.inputs, attributes)); }; } }); // web/lib/wasm/jsep/webgpu/ops/grid-sample.ts var idxN, idxC, idxH, idxW, validateInputs41, gsGetCubicCoeffs, gsBicubicInterpolate, gsDenormalize, gsReflect, pixelAtGrid, computePixel, createGridSampleProgramInfo, gridSample, parseGridSampleAttributes; var init_grid_sample = __esm({ "web/lib/wasm/jsep/webgpu/ops/grid-sample.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); [idxN, idxC, idxH, idxW] = [0, 1, 2, 3]; validateInputs41 = (inputs) => { if (inputs[0].dims.length !== 4) { throw new Error("only 4-D tensor is supported."); } if (inputs[0].dims.length !== inputs[1].dims.length) { throw new Error("input dimensions must be equal to grid dimensions"); } if (inputs[0].dims.length - 2 !== inputs[1].dims[inputs[1].dims.length - 1]) { throw new Error(`last dimension of grid must be equal to ${inputs[0].dims.length - 2}`); } if (inputs[0].dims[0] !== inputs[1].dims[0]) { throw new Error("grid batch size must match input batch size"); } }; gsGetCubicCoeffs = ` fn gs_get_cubic_coeffs(x: f32) -> vec4 { let cubic_alpha = -0.75f; let x_abs = abs(x); var coeffs: vec4; coeffs[0] = (((cubic_alpha * (x_abs + 1) - 5 * cubic_alpha) * (x_abs + 1) + 8 * cubic_alpha) * (x_abs + 1) - 4 * cubic_alpha); coeffs[1] = (((cubic_alpha + 2) * x_abs - (cubic_alpha + 3)) * x_abs * x_abs + 1); coeffs[2] = (((cubic_alpha + 2) * (1 - x_abs) - (cubic_alpha + 3)) * (1 - x_abs) * (1 - x_abs) + 1); coeffs[3] = (((cubic_alpha * (2 - x_abs) - 5 * cubic_alpha) * (2 - x_abs) + 8 * cubic_alpha) * (2 - x_abs) - 4 * cubic_alpha); return coeffs; } `; gsBicubicInterpolate = (dataType) => ` fn gs_bicubic_interpolate(p: mat4x4<${dataType}>, x: f32, y: f32) -> ${dataType} { var v: vec4; var coeffs = gs_get_cubic_coeffs(x); for (var i = 0; i < 4; i++) { v[i] = coeffs[0] * p[i][0] + coeffs[1] * p[i][1] + coeffs[2] * p[i][2] + coeffs[3] * p[i][3]; } coeffs = gs_get_cubic_coeffs(y); let pixel = ${dataType}(coeffs[0] * v[0] + coeffs[1] * v[1] + coeffs[2] * v[2] + coeffs[3] * v[3]); return pixel; } `; gsDenormalize = (attributes) => ` fn gs_denormalize(n: f32, length: i32) -> f32 { ${attributes.alignCorners === 0 ? ` // alignCorners: false => [-1, 1] to [-0.5, length - 0.5] return ((n + 1.0) * f32(length) - 1.0) / 2.0; ` : ` // alignCorners: true => [-1, 1] to [0, length - 1] return (n + 1.0) / 2.0 * (f32(length - 1)); `} } `; gsReflect = (attributes) => ` ${attributes.paddingMode === "reflection" ? ` fn gs_reflect(x: i32, x_min: f32, x_max: f32) -> u32 { var dx = 0.0; var fx = f32(x); let range = x_max - x_min; if (fx < x_min) { dx = x_min - fx; let n = u32(dx / range); let r = dx - f32(n) * range; if (n % 2 == 0) { fx = x_min + r; } else { fx = x_max - r; } } else if (fx > x_max) { dx = fx - x_max; let n = u32(dx / range); let r = dx - f32(n) * range; if (n % 2 == 0) { fx = x_max - r; } else { fx = x_min + r; } } return u32(fx); }` : ""} `; pixelAtGrid = (input, dataType, attributes) => ` fn pixel_at_grid(r: i32, c: i32, H: i32, W: i32, batch: u32, channel: u32, border: vec4) -> ${dataType} { var pixel = ${dataType}(0); var indices = vec4(0); indices[${idxN}] = batch; indices[${idxC}] = channel;` + (() => { switch (attributes.paddingMode) { case "zeros": return ` if (r >= 0 && r < H && c >=0 && c < W) { indices[${idxH}] = u32(r); indices[${idxW}] = u32(c); } else { return ${dataType}(0); } `; case "border": return ` indices[${idxH}] = u32(clamp(r, 0, H - 1)); indices[${idxW}] = u32(clamp(c, 0, W - 1)); `; case "reflection": return ` indices[${idxH}] = gs_reflect(r, border[1], border[3]); indices[${idxW}] = gs_reflect(c, border[0], border[2]); `; default: throw new Error(`padding mode ${attributes.paddingMode} is not supported`); } })() + ` return ${input.getByIndices("indices")}; } `; computePixel = (output, dataType, attributes) => (() => { switch (attributes.mode) { case "nearest": return ` let result = pixel_at_grid(i32(round(y)), i32(round(x)), H_in, W_in, indices[${idxN}], indices[${idxC}], border); `; case "bilinear": return ` let x1 = i32(floor(x)); let y1 = i32(floor(y)); let x2 = x1 + 1; let y2 = y1 + 1; let p11 = pixel_at_grid(y1, x1, H_in, W_in, indices[${idxN}], indices[${idxC}], border); let p12 = pixel_at_grid(y1, x2, H_in, W_in, indices[${idxN}], indices[${idxC}], border); let p21 = pixel_at_grid(y2, x1, H_in, W_in, indices[${idxN}], indices[${idxC}], border); let p22 = pixel_at_grid(y2, x2, H_in, W_in, indices[${idxN}], indices[${idxC}], border); let dx2 = ${dataType}(f32(x2) - x); let dx1 = ${dataType}(x - f32(x1)); let dy2 = ${dataType}(f32(y2) - y); let dy1 = ${dataType}(y - f32(y1)); let result = dy2 * (dx2 * p11 + dx1 * p12) + dy1 * (dx2 * p21 + dx1 * p22); `; case "bicubic": return ` let x0 = i32(floor(x)) - 1; let y0 = i32(floor(y)) - 1; var p: mat4x4<${dataType}>; for (var h = 0; h < 4; h++) { for (var w = 0; w < 4; w++) { p[h][w] = pixel_at_grid(h + y0, w + x0, H_in, W_in, indices[${idxN}], indices[${idxC}], border); } } let dx = x - f32(x0 + 1); let dy = y - f32(y0 + 1); let result = gs_bicubic_interpolate(p, dx, dy); `; default: throw new Error(`mode ${attributes.mode} is not supported`); } })() + `${output.setByOffset("global_idx", "result")}`; createGridSampleProgramInfo = (inputs, attributes) => { const x = inputVariable("x", inputs[0].dataType, inputs[0].dims.length); const gridShape = [inputs[1].dims[0], inputs[1].dims[1], inputs[1].dims[2]]; const grid = inputVariable("grid", inputs[1].dataType, gridShape.length, 2); let outputShape = [inputs[0].dims[0], inputs[0].dims[1], inputs[1].dims[1], inputs[1].dims[2]]; if (attributes.format === "NHWC") { outputShape = [inputs[0].dims[0], inputs[1].dims[1], inputs[1].dims[2], inputs[0].dims[3]]; [idxN, idxC, idxH, idxW] = [0, 3, 1, 2]; } const output = outputVariable("output", inputs[0].dataType, outputShape.length); const dataType = x.type.value; const outputSize = ShapeUtil2.size(outputShape); const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, ...createTensorShapeVariables(inputs[0].dims, gridShape, outputShape) ]; const getShaderSource = (shaderHelper) => ` ${shaderHelper.registerUniform("output_size", "u32").declareVariables(x, grid, output)} ${gsGetCubicCoeffs} ${gsBicubicInterpolate(dataType)} ${gsDenormalize(attributes)} ${gsReflect(attributes)} ${pixelAtGrid(x, dataType, attributes)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let H_in = i32(uniforms.x_shape[${idxH}]); let W_in = i32(uniforms.x_shape[${idxW}]); ${attributes.alignCorners === 0 ? ` let x_min = -0.5; let x_max = f32(W_in) - 0.5; let y_min = -0.5; let y_max = f32(H_in) - 0.5; ` : ` let x_min = 0.0; let x_max = f32(W_in) - 1.0; let y_min = 0.0; let y_max = f32(H_in) - 1.0; `}; let border = vec4(x_min, y_min, x_max, y_max); let indices = ${output.offsetToIndices("global_idx")}; var grid_indices = vec3(indices[${idxN}], indices[${idxH}], indices[${idxW}]); let nxy = ${grid.getByIndices("grid_indices")}; var x = gs_denormalize(f32(nxy[0]), W_in); var y = gs_denormalize(f32(nxy[1]), H_in); ${computePixel(output, dataType, attributes)} }`; return { name: "GridSample", shaderCache: { hint: `${attributes.cacheKey}`, inputDependencies: ["type", "type"] }, getRunData: (inputs2) => { const outputSize2 = ShapeUtil2.size(outputShape); return { outputs: [{ dims: outputShape, dataType: inputs2[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize2 / 64 /* workgroup size */ ) }, programUniforms }; }, getShaderSource }; }; gridSample = (context, attributes) => { validateInputs41(context.inputs); context.compute(createGridSampleProgramInfo(context.inputs, attributes)); }; parseGridSampleAttributes = (attributes) => createAttributeWithCacheKey2({ alignCorners: attributes.align_corners, mode: attributes.mode, paddingMode: attributes.padding_mode, format: attributes.format }); } }); // web/lib/wasm/jsep/webgpu/ops/multihead-attention.ts var getInput, validateInputs42, parseMultiHeadAttentionAttributes, weightTransposeAttribute2, addBiasTranspose, maybeTransposeToBNSHAndAddBias, multiHeadAttention; var init_multihead_attention = __esm({ "web/lib/wasm/jsep/webgpu/ops/multihead-attention.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_types2(); init_attention(); init_common(); init_transpose2(); getInput = (inputs, i) => inputs.length > i && inputs[i].dims.length > 0 ? inputs[i] : void 0; validateInputs42 = (inputs, attributes) => { const query = inputs[0]; const key = getInput(inputs, 1); const value = getInput(inputs, 2); const bias = getInput(inputs, 3); const keyPaddingMask = getInput(inputs, 4); const attentionBias = getInput(inputs, 5); const pastKey = getInput(inputs, 6); const pastValue = getInput(inputs, 7); if (query.dims.length !== 3 && query.dims.length !== 5) { throw new Error("Input query is expected to have 3 or 5 dimensions"); } const batchSize = query.dims[0]; const sequenceLength = query.dims[1]; const hiddenSize = query.dims.length === 3 ? query.dims[2] : attributes.numHeads * query.dims[4]; let kvSequenceLength = sequenceLength; let pastSequenceLength = 0; let maxSequenceLength = 0; const headSize = Math.floor(hiddenSize / attributes.numHeads); if (pastKey && pastValue && ShapeUtil2.size(pastKey.dims) && ShapeUtil2.size(pastValue.dims)) { if (pastKey.dims.length !== 4) { throw new Error('Input "past_key" is expected to have 4 dimensions'); } if (pastKey.dims[0] !== batchSize || pastKey.dims[1] !== attributes.numHeads || pastKey.dims[3] !== headSize) { throw new Error('Input "past_key" shape (batch_size, num_heads, past_sequence_length, head_size)'); } if (pastValue.dims[0] !== batchSize || pastValue.dims[1] !== attributes.numHeads || pastValue.dims[3] !== headSize) { throw new Error('Input "past_value" shape (batch_size, num_heads, past_sequence_length, head_size)'); } if (pastKey.dims[2] !== pastValue.dims[2]) { throw new Error('Input "past_key" and "past_value" shall have same dim 2 (past_sequence_length)'); } if (pastValue.dims.length !== 4) { throw new Error('Input "past_value" is expected to have 4 dimensions'); } pastSequenceLength = pastKey.dims[2]; maxSequenceLength = pastKey.dims[2]; } else if (pastKey && ShapeUtil2.size(pastKey.dims) || pastValue && ShapeUtil2.size(pastValue.dims)) { throw new Error('Input "past_key" and "past_value" shall be both present or both absent'); } let qkvFormat; if (key && ShapeUtil2.size(key.dims) > 0) { if (query.dims.length !== 3) { throw new Error('Input "query" is expected to have 3 dimensions when key is given'); } if (key.dims.length < 3 || key.dims.length > 5) { throw new Error('Input "key" is expected to have 3, 4, or 5 dimensions'); } if (query.dims[0] !== key.dims[0]) { throw new Error('Input "query" and "key" shall have same dim 0 (batch size)'); } if (key.dims.length === 3) { if (key.dims[2] !== query.dims[2]) { throw new Error('Input "query" and "key" shall have same dim 2 (hidden_size)'); } qkvFormat = 2 /* qkvBSNH */; kvSequenceLength = key.dims[1]; } else if (key.dims.length === 5) { if (key.dims[2] !== attributes.numHeads || key.dims[3] !== 2 || key.dims[4] !== headSize) { throw new Error('Expect "key" shape (batch_size, kv_sequence_length, num_heads, 2, head_size) for packed kv'); } if (value) { throw new Error('Expect "value" be none when "key" has packed kv format.'); } qkvFormat = 5 /* qKvBSNHxBSN2H */; kvSequenceLength = key.dims[1]; } else { if (key.dims[1] !== attributes.numHeads || key.dims[3] !== headSize) { throw new Error('Expect "key" shape (batch_size, num_heads, kv_sequence_length, head_size) for past_key'); } qkvFormat = 0 /* unknown */; kvSequenceLength = key.dims[2]; } } else { if (query.dims.length !== 5) { throw new Error('Input "query" is expected to have 5 dimensions when key is empty'); } if (query.dims[2] !== attributes.numHeads || query.dims[3] !== 3) { throw new Error('Expect "query" shape (batch_size, kv_sequence_length, num_heads, 3, head_size) for packed kv'); } qkvFormat = 3 /* qkvBSN3H */; } if (bias && ShapeUtil2.size(bias.dims) > 0) { if (bias.dims.length !== 1) { throw new Error('Input "bias" is expected to have 1 dimension'); } if (key) { if (key.dims.length === 5 && key.dims[3] === 2) { throw new Error("bias is not allowed for packed kv."); } } } const totalSequenceLength = pastSequenceLength + kvSequenceLength; let maskType = 0 /* none */; if (keyPaddingMask && ShapeUtil2.size(keyPaddingMask.dims) > 0) { maskType = 8 /* maskUnknown */; const maskDims = keyPaddingMask.dims; if (maskDims.length === 1) { if (maskDims[0] === batchSize) { maskType = 1 /* mask1dKeySeqLen */; } else if (maskDims[0] === 3 * batchSize + 2) { maskType = 3 /* mask1DKeySeqLenStart */; } } else if (maskDims.length === 2 && maskDims[0] === batchSize && maskDims[1] === totalSequenceLength) { maskType = 5 /* mask2dKeyPadding */; } if (maskType === 8 /* maskUnknown */) { throw new Error('Input "key_padding_mask" shape shall be (batch_size) or (batch_size, total_sequence_length)'); } throw new Error("Mask not supported"); } let passPastInKv = false; let vHiddenSize = hiddenSize; if (value && ShapeUtil2.size(value.dims) > 0) { if (value.dims.length !== 3 && value.dims.length !== 4) { throw new Error('Input "value" is expected to have 3 or 4 dimensions'); } if (query.dims[0] !== value.dims[0]) { throw new Error('Input "query" and "value" shall have same dim 0 (batch_size)'); } if (value.dims.length === 3) { if (kvSequenceLength !== value.dims[1]) { throw new Error('Input "key" and "value" shall have the same dim 1 (kv_sequence_length)'); } vHiddenSize = value.dims[2]; } else { if (kvSequenceLength !== value.dims[2]) { throw new Error('Input "key" and "value" shall have the same dim 2 (kv_sequence_length)'); } vHiddenSize = value.dims[1] * value.dims[3]; passPastInKv = true; } } const broadcastResPosBias = false; if (keyPaddingMask && ShapeUtil2.size(keyPaddingMask.dims) > 0) { throw new Error("Key padding mask is not supported"); } if (attentionBias && ShapeUtil2.size(attentionBias.dims) > 0) { if (attentionBias.dims.length !== 4) { throw new Error('Input "attention_bias" is expected to have 4 dimensions'); } if (attentionBias.dims[0] !== batchSize || attentionBias.dims[1] !== attributes.numHeads || attentionBias.dims[2] !== sequenceLength || attentionBias.dims[3] !== totalSequenceLength) { throw new Error('Expect "attention_bias" shape (batch_size, num_heads, sequence_length, total_sequence_length)'); } } return { batchSize, sequenceLength, pastSequenceLength, kvSequenceLength, totalSequenceLength, maxSequenceLength, inputHiddenSize: 0, hiddenSize, vHiddenSize, headSize, vHeadSize: Math.floor(vHiddenSize / attributes.numHeads), numHeads: attributes.numHeads, isUnidirectional: false, pastPresentShareBuffer: false, maskFilterValue: attributes.maskFilterValue, maskType, scale: attributes.scale, broadcastResPosBias, passPastInKv, qkvFormat }; }; parseMultiHeadAttentionAttributes = (attributes) => createAttributeWithCacheKey2({ ...attributes }); weightTransposeAttribute2 = createAttributeWithCacheKey2({ perm: [0, 2, 1, 3] }); addBiasTranspose = (context, qkv, bias, batchSize, sequenceLength, hiddenSize, biasOffset) => { const outputShape = [batchSize, sequenceLength, hiddenSize]; const outputSize = ShapeUtil2.size(outputShape); const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: biasOffset }, { type: 12 /* uint32 */, data: hiddenSize } ]; const getShaderSource = (shaderHelper) => { const output = outputVariable("qkv_with_bias", qkv.dataType, outputShape); const qkvInput = inputVariable("qkv", qkv.dataType, outputShape); const biasInput = inputVariable("bias", bias.dataType, outputShape); const uniforms = [ { name: "output_size", type: "u32" }, { name: "bias_offset", type: "u32" }, { name: "hidden_size", type: "u32" } ]; return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(qkvInput, biasInput, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let bias_offset_idx = (global_idx % uniforms.hidden_size) + uniforms.bias_offset; qkv_with_bias[global_idx] = qkv[global_idx] + bias[bias_offset_idx]; }`; }; return context.compute( { name: "MultiHeadAttentionAddBias", shaderCache: { inputDependencies: ["type", "type"] }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: qkv.dataType, gpuDataType: 0 /* default */ }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }, { inputs: [qkv, bias], outputs: [-1] } )[0]; }; maybeTransposeToBNSHAndAddBias = (context, batchSize, numHeads, sequenceLength, headSize, input, bias, biasOffset) => { let reshapedInput = input; if (!(bias && ShapeUtil2.size(bias.dims) > 0)) { if (input.dims.length === 3) { reshapedInput = input.reshape([batchSize, sequenceLength, numHeads, headSize]); } if (numHeads === 1 || sequenceLength === 1) { return reshapedInput; } return context.compute(createTransposeProgramInfo2(reshapedInput, weightTransposeAttribute2.perm), { inputs: [reshapedInput], outputs: [-1] })[0]; } else { if (sequenceLength === 1) { throw new Error("AddBiasReshape is not implemented. Please export your model with packed QKV or KV"); } else { reshapedInput = addBiasTranspose( context, input, bias, batchSize, sequenceLength, numHeads * headSize, biasOffset ); reshapedInput = reshapedInput.reshape([batchSize, sequenceLength, numHeads, headSize]); if (numHeads === 1 || sequenceLength === 1) { return reshapedInput; } return context.compute(createTransposeProgramInfo2(reshapedInput, weightTransposeAttribute2.perm), { inputs: [reshapedInput], outputs: [-1] })[0]; } } }; multiHeadAttention = (context, attributes) => { const params = validateInputs42(context.inputs, attributes); const query = context.inputs[0]; const key = getInput(context.inputs, 1); const value = getInput(context.inputs, 2); const bias = getInput(context.inputs, 3); const keyPaddingMask = getInput(context.inputs, 4); const attentionBias = getInput(context.inputs, 5); const pastKey = getInput(context.inputs, 6); const pastValue = getInput(context.inputs, 7); if (query.dims.length === 5) { throw new Error("Packed QKV is not implemented"); } if (key?.dims.length === 5) { throw new Error("Packed KV is not implemented"); } const kvBNSH = key && value && key.dims.length === 4 && value.dims.length === 4; const Q = maybeTransposeToBNSHAndAddBias( context, params.batchSize, params.numHeads, params.sequenceLength, params.headSize, query, bias, 0 ); if (kvBNSH) { return applyAttention(context, Q, key, value, keyPaddingMask, void 0, pastKey, pastValue, attentionBias, params); } if (!key || !value) { throw new Error("key and value must be provided"); } const K = maybeTransposeToBNSHAndAddBias( context, params.batchSize, params.numHeads, params.kvSequenceLength, params.headSize, key, bias, params.hiddenSize ); const V = maybeTransposeToBNSHAndAddBias( context, params.batchSize, params.numHeads, params.kvSequenceLength, params.vHeadSize, value, bias, 2 * params.hiddenSize ); applyAttention(context, Q, K, V, keyPaddingMask, void 0, pastKey, pastValue, attentionBias, params); }; } }); // web/lib/wasm/jsep/webgpu/ops/split.ts var validateInputs43, createSplitAttributesFromInputs, calculateOutputIndexImpl, writeBufferDataImpl, createSplitProgramInfo2, split2, parseSplitAttributes2; var init_split2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/split.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateInputs43 = (inputs) => { if (!inputs || inputs.length < 1) { throw new Error("too few inputs"); } }; createSplitAttributesFromInputs = (inputs, attributes) => { const splitSizes = []; let numOutputs = attributes.numOutputs; if (inputs[1].dims[0] > 0) { inputs[1].getBigInt64Array().forEach((v) => splitSizes.push(Number(v))); numOutputs = splitSizes.length; } return createAttributeWithCacheKey2({ numOutputs, axis: attributes.axis, splitSizes }); }; calculateOutputIndexImpl = (numberOfTensors) => ` fn calculateOutputIndex(index: u32) -> u32 { for (var i: u32 = 0u; i < ${numberOfTensors}u; i += 1u ) { if (index < ${getElementAt("uniforms.size_in_split_axis", "i", numberOfTensors)}) { return i; } } return ${numberOfTensors}u; }`; writeBufferDataImpl = (outputs) => { const numberOfTensors = outputs.length; const codeLines = []; for (let i = 0; i < numberOfTensors; ++i) { const returnSnippet = outputs[i].setByIndices("indices", "input[global_idx]"); if (numberOfTensors === 1) { codeLines.push(returnSnippet); } else if (i === 0) { codeLines.push(`if (output_number == ${i}u) { ${returnSnippet} }`); } else if (i === numberOfTensors - 1) { codeLines.push(`else { ${returnSnippet} }`); } else { codeLines.push(`else if (output_number == ${i}) { ${returnSnippet} }`); } } return ` fn writeBufferData(output_number: u32, indices: ${outputs[0].type.indices}, global_idx: u32) { ${codeLines.join("\n")} }`; }; createSplitProgramInfo2 = (inputs, attributes) => { const inputShape = inputs[0].dims; const inputSize = ShapeUtil2.size(inputShape); const dataType = inputs[0].dataType; const axis = ShapeUtil2.normalizeAxis(attributes.axis, inputShape.length); const outputs = new Array(attributes.numOutputs); const input = inputVariable("input", dataType, inputShape.length); const sizeInSplitAxis = new Array(attributes.numOutputs); const outputsTensorInfo = []; const outputShapes = []; let previousSum = 0; const programUniforms = [{ type: 12 /* uint32 */, data: inputSize }]; for (let i = 0; i < attributes.numOutputs; i++) { previousSum += attributes.splitSizes[i]; sizeInSplitAxis[i] = previousSum; const outputShape = inputShape.slice(); outputShape[axis] = attributes.splitSizes[i]; outputShapes.push(outputShape); outputs[i] = outputVariable(`output${i}`, dataType, outputShape.length); outputsTensorInfo.push({ dims: outputShapes[i], dataType: inputs[0].dataType }); } programUniforms.push( { type: 12 /* uint32 */, data: sizeInSplitAxis }, ...createTensorShapeVariables(inputShape, ...outputShapes) ); const getShaderSource = (shaderHelper) => ` ${shaderHelper.registerUniform("input_size", "u32").registerUniform("size_in_split_axis", "u32", sizeInSplitAxis.length).declareVariables(input, ...outputs)} ${calculateOutputIndexImpl(sizeInSplitAxis.length)} ${writeBufferDataImpl(outputs)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.input_size")} var indices = ${input.offsetToIndices("global_idx")}; var index = ${input.indicesGet("indices", axis)}; let output_number = calculateOutputIndex(index); if (output_number != 0) { index -= ${getElementAt("uniforms.size_in_split_axis", "output_number - 1u", sizeInSplitAxis.length)}; ${input.indicesSet("indices", axis, "index")}; } writeBufferData(output_number, indices, global_idx); }`; return { name: "Split", shaderCache: { hint: attributes.cacheKey, inputDependencies: ["rank"] }, getShaderSource, getRunData: () => ({ outputs: outputsTensorInfo, dispatchGroup: { x: Math.ceil( inputSize / 64 /* workgroup size */ ) }, programUniforms }) }; }; split2 = (context, attributes) => { validateInputs43(context.inputs); const updatedAttributes = context.inputs.length === 1 ? attributes : createSplitAttributesFromInputs(context.inputs, attributes); context.compute(createSplitProgramInfo2(context.inputs, updatedAttributes), { inputs: [0] }); }; parseSplitAttributes2 = (attributes) => { const axis = attributes.axis; const splitSizes = attributes.splitSizes; const numOutputs = attributes.numOutputs < 0 ? splitSizes.length : attributes.numOutputs; if (numOutputs !== splitSizes.length) { throw new Error("numOutputs and splitSizes length must be equal"); } return createAttributeWithCacheKey2({ axis, numOutputs, splitSizes }); }; } }); // web/lib/wasm/jsep/webgpu/ops/rotary-embedding.ts var validateInputs44, createRotaryEmbeddingProgramInfo, rotaryEmbedding; var init_rotary_embedding = __esm({ "web/lib/wasm/jsep/webgpu/ops/rotary-embedding.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateInputs44 = (inputs, attributes) => { const [input, positionIds, cosCache, sinCache] = inputs; const { numHeads, rotaryEmbeddingDim } = attributes; if (input.dims.length !== 3 && input.dims.length !== 4) { throw new Error(`Input 'x' is expected to have 3 or 4 dimensions, got ${input.dims.length}`); } if (!ShapeUtil2.areEqual(positionIds.dims, []) && !ShapeUtil2.areEqual(positionIds.dims, [1]) && positionIds.dims.length !== 2) { throw new Error(`Input 'position_ids' is expected to have 0, 1, or 2 dimensions, got ${positionIds.dims.length}`); } if (cosCache.dims.length !== 2) { throw new Error(`Input 'cos_cache' is expected to have 2 dimensions, got ${cosCache.dims.length}`); } if (sinCache.dims.length !== 2) { throw new Error(`Input 'sin_cache' is expected to have 2 dimensions, got ${sinCache.dims.length}`); } if (!ShapeUtil2.areEqual(cosCache.dims, sinCache.dims)) { throw new Error("Inputs 'cos_cache' and 'sin_cache' are expected to have the same shape"); } if (rotaryEmbeddingDim > 0 && numHeads === 0) { throw new Error("num_heads must be provided if rotary_embedding_dim is specified"); } const batchSize = input.dims[0]; const sequenceLength = input.dims[input.dims.length - 2]; const maxSequenceLength = cosCache.dims[0]; const hiddenSize = ShapeUtil2.sizeFromDimension(input.dims, 1) / sequenceLength; const headSize = rotaryEmbeddingDim === 0 ? cosCache.dims[1] * 2 : hiddenSize / numHeads; if (rotaryEmbeddingDim > headSize) { throw new Error("rotary_embedding_dim must be less than or equal to head_size"); } if (positionIds.dims.length === 2) { if (batchSize !== positionIds.dims[0]) { throw new Error(`Input 'position_ids' dimension 0 should be of size batch_size, got ${positionIds.dims[0]}`); } if (sequenceLength !== positionIds.dims[1]) { throw new Error(`Input 'position_ids' dimension 1 should be of size sequence_length, got ${positionIds.dims[1]}`); } } if (sequenceLength > maxSequenceLength) { throw new Error("Updating cos_cache and sin_cache in RotaryEmbedding is not currently supported"); } if (headSize / 2 !== cosCache.dims[1] && rotaryEmbeddingDim / 2 !== cosCache.dims[1]) { throw new Error( `Input 'cos_cache' dimension 1 should be same as head_size / 2 or rotary_embedding_dim / 2, got ${cosCache.dims[1]}` ); } }; createRotaryEmbeddingProgramInfo = (inputs, attributes) => { const { interleaved, numHeads, rotaryEmbeddingDim, scale } = attributes; const batchSize = inputs[0].dims[0]; const batchStride = ShapeUtil2.sizeFromDimension(inputs[0].dims, 1); const sequenceLength = inputs[0].dims[inputs[0].dims.length - 2]; const hiddenSize = batchStride / sequenceLength; const halfRotaryEmbeddingDim = inputs[2].dims[1]; const headSize = rotaryEmbeddingDim === 0 ? halfRotaryEmbeddingDim * 2 : hiddenSize / numHeads; const globalShape = new Array( batchSize, sequenceLength, hiddenSize / headSize, headSize - halfRotaryEmbeddingDim ); const globalStrides = ShapeUtil2.computeStrides(globalShape); const programUniforms = [ { type: 1 /* float */, data: scale }, { type: 12 /* uint32 */, data: globalShape }, { type: 12 /* uint32 */, data: globalStrides }, // strides for addressing the input/output tensor, in permutated order to align with the unfolded global index, // i.e. BSNH ...inputs[0].dims.length === 3 ? new Array({ type: 12 /* uint32 */, data: [batchStride, hiddenSize, headSize, 1] }) : [], ...inputs[0].dims.length === 4 ? new Array({ type: 12 /* uint32 */, data: [batchStride, headSize, sequenceLength * headSize, 1] }) : [], ...createTensorShapeVariables(inputs[0].dims, inputs[1].dims, inputs[2].dims, inputs[3].dims, inputs[0].dims) ]; const getShaderSource = (shaderHelper) => { const input = inputVariable("input", inputs[0].dataType, inputs[0].dims.length); const positionIds = inputVariable("position_ids", inputs[1].dataType, inputs[1].dims.length); const cosCache = inputVariable("cos_cache", inputs[2].dataType, inputs[2].dims.length); const sinCache = inputVariable("sin_cache", inputs[3].dataType, inputs[3].dims.length); const output = outputVariable("output", inputs[0].dataType, inputs[0].dims.length); shaderHelper.registerUniforms([ { name: "scale", type: "f32" }, { name: "global_shape", type: "u32", length: globalShape.length }, { name: "global_strides", type: "u32", length: globalStrides.length }, { name: "input_output_strides", type: "u32", length: globalStrides.length } ]); return ` ${shaderHelper.declareVariables(input, positionIds, cosCache, sinCache, output)} ${shaderHelper.mainStart(WORKGROUP_SIZE)} let half_rotary_emb_dim = uniforms.${cosCache.name}_shape[1]; let bsnh = global_idx / uniforms.global_strides % uniforms.global_shape; let size = uniforms.global_shape[0] * uniforms.global_strides[0]; ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("size")} if (bsnh[3] < half_rotary_emb_dim) { let position_ids_idx = ${positionIds.broadcastedIndicesToOffset("bsnh.xy", outputVariable("", positionIds.type.tensor, 2))}; let position_id = u32(${positionIds.getByOffset("position_ids_idx")}) + select(0, bsnh[1], position_ids_idx == 0); let i = dot(bsnh, uniforms.input_output_strides) + select(0, bsnh[3], ${interleaved}); let j = i + select(half_rotary_emb_dim, 1, ${interleaved}); let re = ${input.getByOffset("i")} * ${cosCache.get("position_id", "bsnh[3]")} - ${input.getByOffset("j")} * ${sinCache.get("position_id", "bsnh[3]")}; ${output.setByOffset("i", "re")} let im = ${input.getByOffset("i")} * ${sinCache.get("position_id", "bsnh[3]")} + ${input.getByOffset("j")} * ${cosCache.get("position_id", "bsnh[3]")}; ${output.setByOffset("j", "im")} } else { let k = dot(bsnh, uniforms.input_output_strides) + half_rotary_emb_dim; ${output.setByOffset("k", input.getByOffset("k"))} } }`; }; return { name: "RotaryEmbedding", shaderCache: { hint: createAttributeWithCacheKey2({ interleaved }).cacheKey, inputDependencies: ["rank", "rank", "rank", "rank"] }, getShaderSource, getRunData: () => ({ outputs: [{ dims: inputs[0].dims, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil(ShapeUtil2.size(globalShape) / WORKGROUP_SIZE) }, programUniforms }) }; }; rotaryEmbedding = (context, attributes) => { validateInputs44(context.inputs, attributes); context.compute(createRotaryEmbeddingProgramInfo(context.inputs, attributes)); }; } }); // web/lib/wasm/jsep/webgpu/ops/group-query-attention.ts var validateInputs45, weightTransposeAttribute3, maybeTransposeToBNSH, generatePositionIdsProgramInfo, groupQueryAttention; var init_group_query_attention = __esm({ "web/lib/wasm/jsep/webgpu/ops/group-query-attention.ts"() { "use strict"; init_attribute_with_cache_key2(); init_wasm_common(); init_attention(); init_multihead_attention(); init_split2(); init_transpose2(); init_rotary_embedding(); init_common(); validateInputs45 = (inputs, attributes) => { if (attributes.doRotary && inputs.length <= 7) { throw new Error("cos_cache and sin_cache inputs are required if do_rotary is specified"); } const query = inputs[0]; const key = inputs[1]; const value = inputs[2]; const pastKey = inputs[3]; const pastValue = inputs[4]; if (attributes.doRotary !== 0 && inputs.length <= 7) { throw new Error("cos_cast and sin_cache are expected if do_rotary attribute is non-zero"); } if (attributes.localWindowSize !== -1) { throw new Error("Local attention is not supported"); } if (attributes.softcap !== 0) { throw new Error("Softcap is not supported"); } if (attributes.rotaryInterleaved !== 0) { throw new Error("Rotary interleaved is not supported"); } if (attributes.smoothSoftmax) { throw new Error("Smooth softmax is not supported"); } if (query.dims.length !== 3 && query.dims.length !== 5) { throw new Error("Input query is expected to have 3 or 5 dimensions"); } const dmmhaPacking = false; const batchSize = query.dims[0]; const sequenceLength = query.dims[1]; let hiddenSize = query.dims.length === 3 ? dmmhaPacking ? query.dims[2] / 3 : query.dims[2] : attributes.numHeads * query.dims[4]; let kvSequenceLength = sequenceLength; let pastSequenceLength = 0; const packedQKV = !key || key.dims.length === 0; const headSize = !packedQKV ? Math.floor(hiddenSize / attributes.numHeads) : Math.floor(hiddenSize / (attributes.numHeads + 2 * attributes.kvNumHeads)); if (packedQKV) { hiddenSize = headSize * attributes.numHeads; } const hasPastKey = pastKey && pastKey.dims.length !== 0; const hasPastValue = pastValue && pastValue.dims.length !== 0; const isPastkvBSNH = hasPastKey && pastKey.dims.length === 4 && pastKey.dims[0] === batchSize && pastKey.dims[1] !== attributes.kvNumHeads && pastKey.dims[2] === attributes.kvNumHeads && pastKey.dims[3] === headSize; if (isPastkvBSNH) { throw new Error("BSNH pastKey/pastValue is not supported"); } if (hasPastKey && hasPastValue) { if (pastKey.dims.length !== 4) { throw new Error('Input "past_key" is expected to have 4 dimensions'); } if (pastValue.dims.length !== 4) { throw new Error('Input "past_value" is expected to have 4 dimensions'); } pastSequenceLength = pastKey.dims[2]; } else if (hasPastKey || hasPastValue) { throw new Error('Input "past_key" and "past_value" shall be both present or both absent'); } let qkvFormat = 1 /* qkvBNSH */; if (key && key.dims.length > 0) { if (query.dims.length !== 3) { throw new Error('Input "query" is expected to have 3 dimensions when key is given'); } if (key.dims.length < 3 || key.dims.length > 5) { throw new Error('Input "key" is expected to have 3, 4, or 5 dimensions'); } if (query.dims[0] !== key.dims[0]) { throw new Error('Input "query" and "key" shall have same dim 0 (batch size)'); } if (key.dims.length === 3) { if (query.dims[2] % key.dims[2] !== 0) { throw new Error('Dimension 2 of "query" should be a multiple of "key"'); } kvSequenceLength = key.dims[1]; } else if (key.dims.length === 5) { if (key.dims[2] !== attributes.numHeads || key.dims[3] !== 2 || key.dims[4] !== headSize) { throw new Error('Expect "key" shape (batch_size, kv_sequence_length, num_heads, 2, head_size) for packed kv'); } if (value) { throw new Error('Expect "value" be none when "key" has packed kv format.'); } kvSequenceLength = key.dims[1]; } else { if (key.dims[1] !== attributes.numHeads || key.dims[3] !== headSize) { throw new Error('Expect "key" shape (batch_size, num_heads, kv_sequence_length, head_size) for past_key'); } kvSequenceLength = key.dims[2]; } } else { if (query.dims.length !== 3 && query.dims.length !== 5) { throw new Error('Input "query" is expected to have 3 or 5 dimensions when key is empty'); } if (query.dims.length === 5 && (query.dims[2] !== attributes.numHeads || query.dims[3] !== 3)) { throw new Error('Expect "query" shape (batch_size, kv_sequence_length, num_heads, 3, head_size) for packed kv'); } qkvFormat = 3 /* qkvBSN3H */; } const maskType = 0 /* none */; let passPastInKv = false; let vHiddenSize = attributes.kvNumHeads ? headSize * attributes.kvNumHeads : hiddenSize; if (value && value.dims.length > 0) { if (value.dims.length !== 3 && value.dims.length !== 4) { throw new Error('Input "value" is expected to have 3 or 4 dimensions'); } if (query.dims[0] !== value.dims[0]) { throw new Error('Input "query" and "value" shall have same dim 0 (batch_size)'); } if (value.dims.length === 3) { if (kvSequenceLength !== value.dims[1]) { throw new Error('Input "key" and "value" shall have the same dim 1 (kv_sequence_length)'); } vHiddenSize = value.dims[2]; } else { if (kvSequenceLength !== value.dims[2]) { throw new Error('Input "past_key" and "past_value" shall have the same dim 2 (kv_sequence_length)'); } vHiddenSize = value.dims[1] * value.dims[3]; passPastInKv = true; } } const seqlLens = inputs.length > 4 ? inputs[5] : void 0; if (seqlLens) { if (seqlLens.dims.length === 0) { throw new Error("seqlens_k must be at least 1D, got scalar."); } const seqlLenSize = seqlLens.dims.reduce((a, b) => a * b, 1); if (seqlLenSize !== batchSize) { throw new Error(`seqlens_k must have batch_size (${batchSize}) elements, got ${seqlLenSize}.`); } for (let i = 0; i < seqlLens.dims.length; i++) { if (seqlLens.dims[i] !== 1 && seqlLens.dims[i] !== batchSize) { throw new Error( `seqlens_k has unexpected shape. Each dimension must be 1 or batch_size (${batchSize}), got dims[${i}] = ${seqlLens.dims[i]}.` ); } } } const totalSequenceLength = -1; const maxSequenceLength = -1; const broadcastResPosBias = false; return { batchSize, sequenceLength, pastSequenceLength, kvSequenceLength, totalSequenceLength, maxSequenceLength, inputHiddenSize: 0, hiddenSize, vHiddenSize, headSize, vHeadSize: Math.floor(vHiddenSize / attributes.kvNumHeads), numHeads: attributes.numHeads, kvNumHeads: attributes.kvNumHeads, nReps: attributes.numHeads / attributes.kvNumHeads, pastPresentShareBuffer: false, maskType, scale: attributes.scale, broadcastResPosBias, passPastInKv, qkvFormat }; }; weightTransposeAttribute3 = createAttributeWithCacheKey2({ perm: [0, 2, 1, 3] }); maybeTransposeToBNSH = (context, input, params) => { let reshapedInput = input; const numHeads = params.kvNumHeads; if (input.dims.length === 3 && params.kvSequenceLength !== 0) { reshapedInput = input.reshape([params.batchSize, params.kvSequenceLength, numHeads, params.headSize]); reshapedInput = context.compute(createTransposeProgramInfo2(reshapedInput, weightTransposeAttribute3.perm), { inputs: [reshapedInput], outputs: [-1] })[0]; } return reshapedInput; }; generatePositionIdsProgramInfo = (batchSize, sequenceLength, seqLens, totalSeqLen) => { const outputDataType = 7 /* int64 */; const inputDependencies = ["type", "type"]; const outputShape = [batchSize * sequenceLength]; const outputSize = batchSize * sequenceLength; const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: sequenceLength }, { type: 12 /* uint32 */, data: batchSize } ]; const getShaderSource = (shaderHelper) => { const seqLensInputHelper = inputVariable("seq_lens", seqLens.dataType, seqLens.dims); const totalSeqLenInputHelper = inputVariable("total_seq_lens", totalSeqLen.dataType, totalSeqLen.dims); const positionIdsHelper = outputVariable("pos_ids", outputDataType, outputShape); const uniforms = [ { name: "output_size", type: "u32" }, { name: "sequence_length", type: "u32" }, { name: "batch_size", type: "u32" } ]; return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(seqLensInputHelper, totalSeqLenInputHelper, positionIdsHelper)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let total_sequence_length = u32(${totalSeqLenInputHelper.getByOffset("0")}); let is_subsequent_prompt = uniforms.sequence_length > 1 && uniforms.sequence_length != total_sequence_length; let is_first_prompt = !is_subsequent_prompt && uniforms.sequence_length == total_sequence_length; let batch_idx = global_idx / uniforms.sequence_length; let sequence_idx = i32(global_idx % uniforms.sequence_length); var pos_id: i32 = 0; let seqlen = ${seqLensInputHelper.getByOffset("batch_idx")}; let total_seqlen = seqlen + 1; if (is_first_prompt) { if (sequence_idx < total_seqlen) { pos_id = sequence_idx; } else { pos_id = 1; } ${positionIdsHelper.setByOffset("global_idx", "pos_id")} } else if (is_subsequent_prompt) { let past_seqlen = total_seqlen - i32(uniforms.sequence_length); if (past_seqlen + sequence_idx < total_seqlen) { pos_id = past_seqlen + sequence_idx; } else { pos_id = 1; } ${positionIdsHelper.setByOffset("global_idx", "pos_id")} } else if (global_idx < uniforms.batch_size) { ${positionIdsHelper.setByOffset("global_idx", "seqlen")} }; } `; }; return { name: "GeneratePositionIds", shaderCache: { hint: `${batchSize};${sequenceLength}`, inputDependencies }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: outputDataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }; }; groupQueryAttention = (context, attributes) => { const params = validateInputs45(context.inputs, attributes); if (context.inputs[0].dims.length === 5) { throw new Error("Packed QKV is not implemented"); } if (context.inputs[1]?.dims.length === 5) { throw new Error("Packed KV is not implemented"); } const q = context.inputs[0]; const k = context.inputs[1] && context.inputs[1].dims.length > 0 ? context.inputs[1] : void 0; const v = context.inputs[2] && context.inputs[2].dims.length > 0 ? context.inputs[2] : void 0; const pastKey = context.inputs[3] && context.inputs[3].dims.length !== 0 ? context.inputs[3] : void 0; const pastValue = context.inputs[4] && context.inputs[4].dims.length !== 0 ? context.inputs[4] : void 0; const seqLens = context.inputs.length > 4 ? context.inputs[5] : void 0; const totalSequenceLengthInput = context.inputs.length > 5 ? context.inputs[6] : void 0; const kvNumHeads = params.kvNumHeads ? params.kvNumHeads : params.numHeads; const splitAttributes = createAttributeWithCacheKey2({ axis: 2, numOutputs: 3, splitSizes: [params.numHeads * params.headSize, kvNumHeads * params.headSize, kvNumHeads * params.headSize] }); const [query, key, value] = !k && !v ? context.compute(createSplitProgramInfo2([q], splitAttributes), { inputs: [q], outputs: [-1, -1, -1] }) : [q, k, v]; let qRotary; let kRotary; if (attributes.doRotary) { const posIds = context.compute( generatePositionIdsProgramInfo(params.batchSize, params.sequenceLength, seqLens, totalSequenceLengthInput), { inputs: [seqLens, totalSequenceLengthInput], outputs: [-1] } )[0]; const cosCache = context.inputs[7]; const sinCache = context.inputs[8]; const qRotaryEmbeddingAttributes = createAttributeWithCacheKey2({ interleaved: attributes.rotaryInterleaved !== 0, numHeads: params.numHeads, rotaryEmbeddingDim: 0, scale: attributes.scale }); const inputs = [query, posIds, cosCache, sinCache]; const outputs = [-1]; qRotary = context.compute(createRotaryEmbeddingProgramInfo(inputs, qRotaryEmbeddingAttributes), { inputs, outputs })[0]; inputs.splice(0, 1, key); const kRotaryEmbeddingAttributes = createAttributeWithCacheKey2({ interleaved: attributes.rotaryInterleaved !== 0, numHeads: params.kvNumHeads, rotaryEmbeddingDim: 0, scale: attributes.scale }); kRotary = context.compute(createRotaryEmbeddingProgramInfo(inputs, kRotaryEmbeddingAttributes), { inputs, outputs })[0]; } const Q = maybeTransposeToBNSHAndAddBias( context, params.batchSize, params.numHeads, params.sequenceLength, params.headSize, attributes.doRotary ? qRotary : query, void 0, 0 ); const K = maybeTransposeToBNSH(context, attributes.doRotary ? kRotary : key, params); const V = maybeTransposeToBNSH(context, value, params); applyAttention( context, Q, K, V, void 0, void 0, pastKey, pastValue, void 0, params, seqLens, totalSequenceLengthInput ); }; } }); // web/lib/wasm/jsep/webgpu/ops/instance-norm.ts var computeChannelScaleShift, createInstanceNormProgramInfo, createInstanceNormNHWCProgramInfo, instanceNorm; var init_instance_norm = __esm({ "web/lib/wasm/jsep/webgpu/ops/instance-norm.ts"() { "use strict"; init_wasm_common(); init_util2(); init_transpose2(); init_common(); computeChannelScaleShift = (context, input, scale, bias, n, h, c, epsilon) => { const components = getMaxComponents(h); const f32Type = components === 1 ? "f32" : `vec${components}f`; const wgType = components === 1 ? "vec2f" : `mat2x${components}f`; const unitsOfWork = n * c; let workgroupSize = 64; if (unitsOfWork === 1) { workgroupSize = 256; } const inputShape = [n, c, h / components]; const outputShape = [n, c, 2]; const inputDependencies = ["rank", "type", "type"]; const programUniforms = []; programUniforms.push(...createTensorShapeVariables(inputShape, outputShape)); const getShaderSource = (shaderHelper) => { const x = inputVariable("x", input.dataType, 3, components); const s = inputVariable("scale", scale.dataType, scale.dims); const b = inputVariable("bias", bias.dataType, bias.dims); const output = outputVariable("output", 1 /* float */, 3, 2); const variables = [x, s, b, output]; return ` var workgroup_shared : array<${wgType}, ${workgroupSize}>; const workgroup_size = ${workgroupSize}u; ${shaderHelper.declareVariables(...variables)} ${shaderHelper.mainStart(workgroupSize)} let batch = workgroup_index / uniforms.x_shape[1]; let channel = workgroup_index % uniforms.x_shape[1]; let hight = uniforms.x_shape[2]; // initialize workgroup memory var sum = ${f32Type}(0); var squared_sum = ${f32Type}(0); for (var h = local_idx; h < hight; h += workgroup_size) { let value = ${f32Type}(${x.get("batch", "channel", "h")}); sum += value; squared_sum += value * value; } workgroup_shared[local_idx] = ${wgType}(sum, squared_sum); workgroupBarrier(); for (var currSize = workgroup_size >> 1; currSize > 0; currSize = currSize >> 1) { if (local_idx < currSize) { workgroup_shared[local_idx] = workgroup_shared[local_idx] + workgroup_shared[local_idx + currSize]; } workgroupBarrier(); } if (local_idx == 0) { let sum_final = ${sumVector("workgroup_shared[0][0]", components)} / f32(hight * ${components}); let squared_sum_final = ${sumVector("workgroup_shared[0][1]", components)} / f32(hight * ${components}); let inv_std_dev = inverseSqrt(squared_sum_final - sum_final * sum_final + f32(${epsilon})); let channel_scale = inv_std_dev * f32(scale[channel]); let channel_shift = f32(bias[channel]) - sum_final * channel_scale; output[workgroup_index] = vec2f(channel_scale, channel_shift); } }`; }; return context.compute( { name: "InstanceNormComputeChannelScaleShift", // TODO: use epsilon as uniform. Currently epsilon as uniform fails test_instancenorm_epsilon. shaderCache: { hint: `${components};${epsilon};${workgroupSize}`, inputDependencies }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: 1 /* float */ }], dispatchGroup: { x: unitsOfWork }, programUniforms }), getShaderSource }, { inputs: [input, scale, bias], outputs: [-1] } )[0]; }; createInstanceNormProgramInfo = (context, inputs, attributes) => { const xShape = inputs[0].dims; const outputShape = xShape; const axis = 2; const N = xShape[0]; const C = xShape[1]; const H = ShapeUtil2.sizeFromDimension(xShape, axis); const components = getMaxComponents(H); const outputSize = ShapeUtil2.size(outputShape) / components; const channelScaleShift = computeChannelScaleShift( context, inputs[0], inputs[1], inputs[2], N, H, C, attributes.epsilon ); const inputShape = [N, C, H / components]; const scaleShape = [N, C]; const inputDependencies = ["type", "none"]; const getShaderSource = (shaderHelper) => { const x = inputVariable("x", inputs[0].dataType, inputShape.length, components); const scale = inputVariable("scale_shift", 1 /* float */, scaleShape.length, 2); const output = outputVariable("output", inputs[0].dataType, inputShape.length, components); const variables = [x, scale, output]; return ` ${shaderHelper.registerUniform("output_size", "u32").declareVariables(...variables)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let outputIndices = ${output.offsetToIndices("global_idx")}; let batch = outputIndices[0]; let channel = outputIndices[1]; let scale_shift = ${scale.getByIndices("vec2(batch, channel)")}; let value = ${x.getByOffset("global_idx")} * ${output.type.value}(scale_shift.x) + ${output.type.value}(scale_shift.y); ${output.setByOffset("global_idx", "value")}; }`; }; context.compute( { name: "InstanceNormalization", shaderCache: { hint: `${components}`, inputDependencies }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms: [ { type: 12 /* uint32 */, data: outputSize }, ...createTensorShapeVariables(inputShape, scaleShape, inputShape) ] }), getShaderSource }, { inputs: [inputs[0], channelScaleShift] } ); }; createInstanceNormNHWCProgramInfo = (context, inputs, attributes) => { const xShape = inputs[0].dims; const outputShape = xShape; const N = xShape[0]; const C = xShape[xShape.length - 1]; const H = ShapeUtil2.sizeFromDimension(xShape, 1) / C; const components = getMaxComponents(C); const outputSize = ShapeUtil2.size(outputShape) / components; const programUniforms = [ { type: 12 /* uint32 */, data: H }, { type: 12 /* uint32 */, data: Math.floor(C / components) } ]; const inputDependencies = ["type", "type"]; let needTranspose = false; const transposedXPerm = [0, xShape.length - 1]; for (let i = 0; i < xShape.length - 2; i++) { needTranspose = needTranspose || xShape[i + 1] !== 1; transposedXPerm.push(i + 1); } needTranspose = needTranspose && xShape[xShape.length - 1] !== 1; const transposedX = needTranspose ? context.compute(createTransposeProgramInfo2(context.inputs[0], transposedXPerm), { inputs: [context.inputs[0]], outputs: [-1] })[0] : context.inputs[0].reshape(Array.from({ length: xShape.length }, (_, i) => xShape[transposedXPerm[i]])); const channelScaleShift = computeChannelScaleShift( context, transposedX, inputs[1], inputs[2], N, H, C, attributes.epsilon ); const getShaderSource = (shaderHelper) => { const dataType = tensorTypeToWsglStorageType(inputs[0].dataType); const scaleType = components === 1 ? "vec2f" : `mat${components}x2f`; const scaleData = (num) => { const index = num === 0 ? "x" : "y"; const f32Type = components === 1 ? "f32" : `vec${components}f`; switch (components) { case 1: return `${dataType}(${f32Type}(scale.${index}))`; case 2: return `vec2<${dataType}>(${f32Type}(scale[0].${index}, scale[1].${index}))`; case 4: return `vec4<${dataType}>(${f32Type}(scale[0].${index}, scale[1].${index}, scale[2].${index}, scale[3].${index}))`; default: throw new Error(`Not supported compoents ${components}`); } }; const inputHelper = inputVariable("input", inputs[0].dataType, inputs[0].dims, components); const outputHelper = outputVariable("output", inputs[0].dataType, outputShape, components); return ` @group(0) @binding(0) var input : array<${inputHelper.type.storage}>; @group(0) @binding(1) var scale_input : array<${scaleType}>; @group(0) @binding(2) var output : array<${outputHelper.type.storage}>; struct Uniforms {H: u32, C : u32}; @group(0) @binding(3) var uniforms: Uniforms; ${shaderHelper.mainStart()} let current_image_number = global_idx / (uniforms.C * uniforms.H); let current_channel_number = global_idx % uniforms.C; let scale_offset = current_image_number * uniforms.C + current_channel_number; let scale = scale_input[scale_offset]; output[global_idx] = fma(input[global_idx], ${scaleData(0)}, ${scaleData(1)}); }`; }; context.compute( { name: "InstanceNormalizationNHWC", shaderCache: { hint: `${components}`, inputDependencies }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }, { inputs: [inputs[0], channelScaleShift] } ); }; instanceNorm = (context, attributes) => { if (attributes.format === "NHWC") { createInstanceNormNHWCProgramInfo(context, context.inputs, attributes); } else { createInstanceNormProgramInfo(context, context.inputs, attributes); } }; } }); // web/lib/wasm/jsep/webgpu/ops/layer-norm.ts var validateInputs46, createLayerNormProgramInfo, layerNorm; var init_layer_norm = __esm({ "web/lib/wasm/jsep/webgpu/ops/layer-norm.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); validateInputs46 = (inputs) => { if (!inputs || inputs.length < 2) { throw new Error("layerNorm requires at least 2 inputs."); } }; createLayerNormProgramInfo = (inputs, attributes, outputCount) => { const simplified = attributes.simplified; const xShape = inputs[0].dims; const scale = inputs[1]; const bias = !simplified && inputs[2]; const outputShape = xShape; const axis = ShapeUtil2.normalizeAxis(attributes.axis, xShape.length); const normCount = ShapeUtil2.sizeToDimension(xShape, axis); const normSize = ShapeUtil2.sizeFromDimension(xShape, axis); const scaleSize = ShapeUtil2.size(scale.dims); const biasSize = bias ? ShapeUtil2.size(bias.dims) : 0; if (scaleSize !== normSize || bias && biasSize !== normSize) { throw new Error(`Size of X.shape()[axis:] == ${normSize}. Size of scale and bias (if provided) must match this. Got scale size of ${scaleSize} and bias size of ${biasSize}`); } const meanInvStdDevDim = []; for (let i = 0; i < xShape.length; ++i) { if (i < axis) { meanInvStdDevDim.push(xShape[i]); } else { meanInvStdDevDim.push(1); } } const components = getMaxComponents(normSize); const inputDependencies = ["type", "type"]; const programUniforms = [ { type: 12 /* uint32 */, data: normCount }, { type: 1 /* float */, data: normSize }, { type: 12 /* uint32 */, data: Math.floor(normSize / components) }, { type: 1 /* float */, data: attributes.epsilon } ]; if (bias) { inputDependencies.push("type"); } const hasMeanDataOutput = outputCount > 1; const hasInvStdOutput = outputCount > 2; const getShaderSource = (shaderHelper) => { const dataType = tensorTypeToWsglStorageType(inputs[0].dataType); const variables = [ inputVariable("x", inputs[0].dataType, inputs[0].dims, components), inputVariable("scale", scale.dataType, scale.dims, components) ]; if (bias) { variables.push(inputVariable("bias", bias.dataType, bias.dims, components)); } variables.push(outputVariable("output", inputs[0].dataType, outputShape, components)); if (hasMeanDataOutput) { variables.push(outputVariable("mean_data_output", 1 /* float */, meanInvStdDevDim)); } if (hasInvStdOutput) { variables.push(outputVariable("inv_std_output", 1 /* float */, meanInvStdDevDim)); } const uniforms = [ { name: "norm_count", type: "u32" }, { name: "norm_size", type: "f32" }, { name: "norm_size_vectorized", type: "u32" }, { name: "epsilon", type: "f32" } ]; return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(...variables)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.norm_count")} let offset = global_idx * uniforms.norm_size_vectorized; var mean_vector = ${fillVector("f32", components)}; var mean_square_vector = ${fillVector("f32", components)}; for (var h: u32 = 0u; h < uniforms.norm_size_vectorized; h++) { let value = ${castToF32(dataType, components, "x[h + offset]")}; mean_vector += value; mean_square_vector += value * value; } let mean = ${sumVector("mean_vector", components)} / uniforms.norm_size; let inv_std_dev = inverseSqrt(${sumVector("mean_square_vector", components)} / uniforms.norm_size ${simplified ? "" : "- mean * mean"} + uniforms.epsilon); for (var j: u32 = 0; j < uniforms.norm_size_vectorized; j++) { let f32input = ${castToF32(dataType, components, "x[j + offset]")}; let f32scale = ${castToF32(dataType, components, "scale[j]")}; output[j + offset] = ${variables[0].type.value}((f32input ${simplified ? "" : "- mean"}) * inv_std_dev * f32scale ${bias ? `+ ${castToF32(dataType, components, "bias[j]")}` : ""} ); } ${hasMeanDataOutput ? "mean_data_output[global_idx] = mean" : ""}; ${hasInvStdOutput ? "inv_std_output[global_idx] = inv_std_dev" : ""}; }`; }; const outputs = [{ dims: outputShape, dataType: inputs[0].dataType }]; if (hasMeanDataOutput) { outputs.push({ dims: meanInvStdDevDim, dataType: 1 /* float */ }); } if (hasInvStdOutput) { outputs.push({ dims: meanInvStdDevDim, dataType: 1 /* float */ }); } return { name: "LayerNormalization", shaderCache: { hint: `${components};${outputCount};${simplified}`, inputDependencies }, getRunData: () => ({ outputs, dispatchGroup: { x: Math.ceil( normCount / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }; }; layerNorm = (context, attributes) => { validateInputs46(context.inputs); context.compute(createLayerNormProgramInfo(context.inputs, attributes, context.outputCount)); }; } }); // web/lib/wasm/jsep/webgpu/ops/matmul.ts var validateInputs47, matMul2; var init_matmul2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/matmul.ts"() { "use strict"; init_util2(); init_matmul_shaders(); init_matmul_packed_webgpu(); validateInputs47 = (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."); } }; matMul2 = (context) => { validateInputs47(context.inputs); const outputShape = BroadcastUtil2.calcShape(context.inputs[0].dims, context.inputs[1].dims, true); if (!outputShape) { throw new Error("Can't use matmul on the given tensors"); } const N = outputShape[outputShape.length - 1]; const K = context.inputs[0].dims[context.inputs[0].dims.length - 1]; if (N < 8 && K < 8) { context.compute(createNaiveMatmulProgramInfo(context.inputs, { activation: "" }, outputShape)); } else { const M = outputShape[outputShape.length - 2]; const batchA = ShapeUtil2.size(context.inputs[0].dims.slice(0, -2)); const batchB = ShapeUtil2.size(context.inputs[1].dims.slice(0, -2)); if (batchA !== 1 && M === 1 && batchB === 1) { const reshapedA = context.inputs[0].reshape([1, batchA, K]); const reshapedB = context.inputs[1].reshape([1, K, N]); const matmulOutputShape = [1, batchA, N]; const matmulInputs = [reshapedA, reshapedB]; context.compute(createMatmulProgramInfo2(matmulInputs, { activation: "" }, outputShape, matmulOutputShape), { inputs: matmulInputs }); } else { context.compute(createMatmulProgramInfo2(context.inputs, { activation: "" }, outputShape)); } } }; } }); // web/lib/wasm/jsep/webgpu/ops/matmulnbits.ts var validateInputs48, createMatMulNBitsProgramInfo, createMatMulNBitsBlockSize32ProgramInfo, matMulNBits, parseMatMulNBitsAttributes; var init_matmulnbits = __esm({ "web/lib/wasm/jsep/webgpu/ops/matmulnbits.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateInputs48 = (inputs, attributes) => { if (inputs.length < 3 || inputs.length > 4) { throw new Error("MatMulNBits requires 3 or 4 inputs"); } const a = inputs[0]; const aRank = a.dims.length; if (a.dims[aRank - 1] !== attributes.k) { throw new Error("The last dim of input shape does not match the k value"); } const nBlocksPerCol = Math.floor((attributes.k + attributes.blockSize - 1) / attributes.blockSize); const blobSize = attributes.blockSize / 8 * attributes.bits; const b = inputs[1]; if (!ShapeUtil2.areEqual(b.dims, [attributes.n, nBlocksPerCol, blobSize])) { throw new Error("The second inputs must be 3D tensor with shape N X nBlocksPerCol X blobSize"); } const scales = inputs[2]; const scalesShape = scales.dims; if (ShapeUtil2.size(scalesShape) !== attributes.n * nBlocksPerCol) { throw new Error("scales input size error."); } if (inputs.length === 4) { const zeroPoints = inputs[3]; const zeroPointsShape = zeroPoints.dims; const expectedZeroPointsSize = attributes.n * (attributes.bits === 8 ? nBlocksPerCol : Math.floor((nBlocksPerCol * attributes.bits + 7) / 8)); if (ShapeUtil2.size(zeroPointsShape) !== expectedZeroPointsSize) { throw new Error("zeroPoints input size error."); } } }; createMatMulNBitsProgramInfo = (inputs, attributes) => { const inputShape = inputs[0].dims; const aRank = inputShape.length; const dimAOuter = inputShape[aRank - 2]; const dimInner = attributes.k; const dimBOuter = attributes.n; const batchDims = inputShape.slice(0, aRank - 2); const batchSize = ShapeUtil2.size(batchDims); const blobSize = inputs[1].dims[2]; const blobSizeInWords = blobSize / 4; const dataType = inputs[0].dataType; const aComponents = getMaxComponents(attributes.k); const bComponents = getMaxComponents(blobSizeInWords); const components = getMaxComponents(dimBOuter); const outputShape = batchDims.concat([dimAOuter, dimBOuter]); const outputNumber = dimAOuter > 1 && dimBOuter / components % 2 === 0 ? 2 : 1; const dispatchSize = ShapeUtil2.size(outputShape) / components / outputNumber; const workgroupSize = 64; const programUniforms = []; const inputShapeTemp = [batchSize, dimAOuter, dimInner / aComponents]; const bShape = ShapeUtil2.convertShape(inputs[1].dims).slice(); bShape.splice(-1, 1, blobSizeInWords / bComponents); programUniforms.push(...createTensorShapeVariables(inputShapeTemp)); programUniforms.push(...createTensorShapeVariables(bShape)); programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); if (inputs.length === 4) { programUniforms.push(...createTensorShapeVariables(ShapeUtil2.convertShape(inputs[3].dims))); } const outputShapeTemp = [batchSize, dimAOuter, dimBOuter / components]; programUniforms.push(...createTensorShapeVariables(outputShapeTemp)); const getShaderSource = (shaderHelper) => { const inputRank = inputShapeTemp.length; const a = inputVariable("a", inputs[0].dataType, inputRank, aComponents); const b = inputVariable("b", 12 /* uint32 */, bShape.length, bComponents); const scales = inputVariable("scales", inputs[2].dataType, inputs[2].dims.length); const inputVariables = [a, b, scales]; const zeroPoints = inputs.length === 4 ? inputVariable("zero_points", 12 /* uint32 */, inputs[3].dims.length) : void 0; if (zeroPoints) { inputVariables.push(zeroPoints); } const outputRank = outputShapeTemp.length; const output = outputVariable("output", inputs[0].dataType, outputRank, components); const dataType2 = tensorTypeToWsglStorageType(inputs[0].dataType); const qDqDataType = (() => { switch (aComponents) { case 1: return `array<${dataType2}, 8>`; case 2: return `mat4x2<${dataType2}>`; case 4: return `mat2x4<${dataType2}>`; default: throw new Error(`${aComponents}-component is not supported.`); } })(); const valuesPerWord = Math.floor(32 / attributes.bits); const passesPerWord = Math.floor(valuesPerWord / 8); const processOneWord = () => { let calcStr = ""; for (let pass = 0; pass < passesPerWord; pass++) { const lowerShift = pass * attributes.bits * 4; const upperShift = lowerShift + attributes.bits; calcStr += ` // reuse a data (pass ${pass}) var input_offset${pass > 0 ? pass : ""} = ${pass === 0 ? a.indicesToOffset(`${a.type.indices}(batch, row, word_offset)`) : `input_offset`}; var a_data${pass > 0 ? pass : ""}: ${qDqDataType}; for (var j${pass > 0 ? pass : ""}: u32 = 0; j${pass > 0 ? pass : ""} < ${8 / aComponents}; j${pass > 0 ? pass : ""}++) { a_data${pass > 0 ? pass : ""}[j${pass > 0 ? pass : ""}] = ${a.getByOffset(`input_offset${pass > 0 ? pass : ""}`)}; input_offset${pass > 0 ? pass : ""}++; } `; for (let c = 0; c < components * outputNumber; c++) { calcStr += ` b_value = ${bComponents === 1 ? `b${c}_data` : `b${c}_data[i]`}; ${attributes.bits === 2 ? `{ let half_word = b_value >> ${pass * 16}u; let byte_lo = half_word & 0xFFu; let byte_hi = (half_word >> 8u) & 0xFFu; let spread_word = (byte_lo & 0xFu) | ((byte_lo >> 4u) << 8u) | ((byte_hi & 0xFu) << 16u) | ((byte_hi >> 4u) << 24u); b_value_lower = unpack4xU8(spread_word & b_mask); b_value_upper = unpack4xU8((spread_word >> 2u) & b_mask); }` : `b_value_lower = unpack4xU8((b_value >> ${lowerShift}u) & b_mask); b_value_upper = unpack4xU8((b_value >> ${upperShift}u) & b_mask);`} b_quantized_values = ${qDqDataType}(${Array.from( { length: 4 }, (_, i) => `${dataType2}(b_value_lower[${i}]), ${dataType2}(b_value_upper[${i}])` ).join(", ")}); b_dequantized_values = ${(() => { if (aComponents === 1) { return `${qDqDataType}(${Array.from( { length: 8 }, (_, i) => `(b_quantized_values[${i}] - ${zeroPoints ? `zero_point${c}` : "zero_point"}) * scale${c}` ).join(", ")});`; } else { return `(b_quantized_values - ${qDqDataType}(${Array(8).fill(`${zeroPoints ? `zero_point${c}` : "zero_point"}`).join(",")})) * scale${c};`; } })()}; workgroup_shared[local_id.x * ${outputNumber} + ${Math.floor(c / components)}]${components > 1 ? `[${c % components}]` : ""} += ${Array.from( { length: 8 / aComponents }, (_, i) => `${aComponents === 1 ? `a_data${pass > 0 ? pass : ""}[${i}] * b_dequantized_values[${i}]` : `dot(a_data${pass > 0 ? pass : ""}[${i}], b_dequantized_values[${i}])`}` ).join(" + ")}; `; } } return calcStr; }; const prepareScaleAndZeroPoint = () => { let calcStr = ` var col_index = col * ${components}; ${zeroPoints ? ` let zero_point_values_per_byte: u32 = ${Math.floor(8 / attributes.bits)}u; let zero_point_bytes_per_col = (nBlocksPerCol + zero_point_values_per_byte - 1u) / zero_point_values_per_byte; var zero_point_byte_count: u32; var zero_point_word_index: u32; var zero_point_byte_offset: u32; let zero_point_sub_offset: u32 = block % zero_point_values_per_byte; var zero_point_bits_offset: u32; var zero_point_word: u32;` : ` // The default zero point is ${Math.pow(2, attributes.bits - 1)} for unsigned ${attributes.bits}-bit quantization. let zero_point = ${dataType2}(${Math.pow(2, attributes.bits - 1).toFixed(1)});`} `; for (let c = 0; c < components * outputNumber; c++) { calcStr += ` let scale${c} = ${scales.getByOffset(`col_index * nBlocksPerCol + block`)}; ${zeroPoints ? ` zero_point_byte_count = col_index * zero_point_bytes_per_col + (block / zero_point_values_per_byte); zero_point_word_index = zero_point_byte_count >> 0x2u; zero_point_byte_offset = zero_point_byte_count & 0x3u; zero_point_bits_offset = (zero_point_byte_offset << 3) + (zero_point_sub_offset * ${attributes.bits}u); zero_point_word = ${zeroPoints.getByOffset("zero_point_word_index")} >> zero_point_bits_offset; let zero_point${c} = ${dataType2}((zero_point_word) & ${attributes.bits === 2 ? "0x3u" : "0xFu"});` : ""} col_index += 1;`; } return calcStr; }; const prepareBData = () => { let calcStr = `col_index = col * ${components};`; for (let c = 0; c < components * outputNumber; c++) { calcStr += ` let b${c}_data = ${b.getByIndices(`${b.type.indices}(col_index, block, word)`)}; col_index += 1;`; } calcStr += ` var b_value: u32; let b_mask: u32 = ${attributes.bits === 2 ? "0x03030303u" : "0x0F0F0F0Fu"}; var b_value_lower: vec4; var b_value_upper: vec4; var b_quantized_values: ${qDqDataType}; var b_dequantized_values: ${qDqDataType};`; return calcStr; }; return ` var workgroup_shared: array<${output.type.value}, ${outputNumber * workgroupSize}>; ${shaderHelper.declareVariables(...inputVariables, output)} ${shaderHelper.mainStart([workgroupSize, 1, 1])} let output_indices = ${output.offsetToIndices(`(global_idx / ${workgroupSize}) * ${outputNumber}`)}; let col = output_indices[2]; let row = output_indices[1]; let batch = output_indices[0]; let nBlocksPerCol = uniforms.b_shape[1]; for (var block = local_id.x; block < nBlocksPerCol; block += ${workgroupSize}) { //process one block var word_offset: u32 = block * ${attributes.blockSize / aComponents}; ${prepareScaleAndZeroPoint()} for (var word: u32 = 0; word < ${blobSizeInWords}; word += ${bComponents}) { ${prepareBData()} for (var i: u32 = 0; i < ${bComponents}; i++) { ${processOneWord()} word_offset += ${valuesPerWord / aComponents}; } } } workgroupBarrier(); if (local_id.x < ${outputNumber}) { var output_value: ${output.type.value} = ${output.type.value}(0); var workgroup_shared_offset: u32 = local_id.x; for (var b: u32 = 0u; b < ${workgroupSize}u; b++) { output_value += workgroup_shared[workgroup_shared_offset]; workgroup_shared_offset += ${outputNumber}; } ${output.setByIndices(`${output.type.indices}(batch, row, col + local_id.x)`, "output_value")}; } }`; }; return { name: "MatMulNBits", shaderCache: { hint: `${attributes.blockSize};${attributes.bits};${aComponents};${bComponents};${components};${outputNumber};${workgroupSize}`, inputDependencies: Array(inputs.length).fill("rank") }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType }], dispatchGroup: { x: dispatchSize }, programUniforms }), getShaderSource }; }; createMatMulNBitsBlockSize32ProgramInfo = (inputs, attributes) => { const inputShape = inputs[0].dims; const aRank = inputShape.length; const dimAOuter = inputShape[aRank - 2]; const dimInner = attributes.k; const dimBOuter = attributes.n; const batchDims = inputShape.slice(0, aRank - 2); const batchSize = ShapeUtil2.size(batchDims); const blobSize = inputs[1].dims[2]; const blobSizeInWords = blobSize / 4; const dataType = inputs[0].dataType; const aComponents = getMaxComponents(attributes.k); const bComponents = getMaxComponents(blobSizeInWords); const outputShape = batchDims.concat([dimAOuter, dimBOuter]); const workgroupSize = 128; const workgroupY = dimBOuter % 8 === 0 ? 8 : dimBOuter % 4 === 0 ? 4 : 1; const workgroupX = workgroupSize / workgroupY; const valuesPerWordBs32 = Math.floor(32 / attributes.bits); const tileSize = workgroupX * bComponents * valuesPerWordBs32; const aLengthPerTile = tileSize / aComponents; const blocksPerTile = tileSize / attributes.blockSize; const dispatchSize = ShapeUtil2.size(outputShape) / workgroupY; const programUniforms = []; const inputShapeTemp = [batchSize, dimAOuter, dimInner / aComponents]; const bShape = ShapeUtil2.convertShape(inputs[1].dims).slice(); bShape.splice(-1, 1, blobSizeInWords / bComponents); programUniforms.push(...createTensorShapeVariables(inputShapeTemp)); programUniforms.push(...createTensorShapeVariables(bShape)); programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); if (inputs.length === 4) { programUniforms.push(...createTensorShapeVariables(ShapeUtil2.convertShape(inputs[3].dims))); } const outputShapeTemp = [batchSize, dimAOuter, dimBOuter]; programUniforms.push(...createTensorShapeVariables(outputShapeTemp)); const getShaderSource = (shaderHelper) => { const inputRank = inputShapeTemp.length; const a = inputVariable("a", inputs[0].dataType, inputRank, aComponents); const b = inputVariable("b", 12 /* uint32 */, bShape.length, bComponents); const scales = inputVariable("scales", inputs[2].dataType, inputs[2].dims.length); const inputVariables = [a, b, scales]; const zeroPoints = inputs.length === 4 ? inputVariable("zero_points", 12 /* uint32 */, inputs[3].dims.length) : void 0; if (zeroPoints) { inputVariables.push(zeroPoints); } const outputRank = outputShapeTemp.length; const output = outputVariable("output", inputs[0].dataType, outputRank); const dataType2 = tensorTypeToWsglStorageType(inputs[0].dataType); const readA = () => { switch (aComponents) { case 1: return ` let a_data0 = vec4<${dataType2}>(sub_a[word_offset], sub_a[word_offset + 1], sub_a[word_offset + 2], sub_a[word_offset + 3]); let a_data1 = vec4<${dataType2}>(sub_a[word_offset + 4], sub_a[word_offset + 5], sub_a[word_offset + 6], sub_a[word_offset + 7]);`; case 2: return ` let a_data0 = vec4<${dataType2}>(sub_a[word_offset], sub_a[word_offset + 1]); let a_data1 = vec4<${dataType2}>(sub_a[word_offset + 2], sub_a[word_offset + 3]);`; case 4: return ` let a_data0 = sub_a[word_offset]; let a_data1 = sub_a[word_offset + 1];`; default: throw new Error(`${aComponents}-component is not supported.`); } }; return ` var sub_a: array<${a.type.value}, ${aLengthPerTile}>; var inter_results: array, ${workgroupY}>; ${shaderHelper.declareVariables(...inputVariables, output)} ${shaderHelper.mainStart([workgroupX, workgroupY, 1])} let output_indices = ${output.offsetToIndices(`workgroup_index * ${workgroupY}`)}; let col = output_indices[2]; let row = output_indices[1]; let batch = output_indices[0]; let n_blocks_per_col = uniforms.b_shape[1]; let num_tiles = (n_blocks_per_col - 1) / ${blocksPerTile} + 1; // Loop over shared dimension. for (var tile: u32 = 0; tile < num_tiles; tile += 1) { let a_col_start = tile * ${aLengthPerTile}; // load one tile A data into shared memory. for (var a_offset = local_idx; a_offset < ${aLengthPerTile}; a_offset += ${workgroupSize}) { let a_col = a_col_start + a_offset; if (a_col < uniforms.a_shape[2]) { sub_a[a_offset] = ${a.getByIndices(`${a.type.indices}(batch, row, a_col)`)}; } else { sub_a[a_offset] = ${a.type.value}(0); } } workgroupBarrier(); // each thread process one block let b_row = col + local_id.y; let block = tile * ${blocksPerTile} + local_id.x; ${zeroPoints ? ` let zero_point_values_per_byte: u32 = ${Math.floor(8 / attributes.bits)}u; let zero_point_bytes_per_col = (n_blocks_per_col + zero_point_values_per_byte - 1u) / zero_point_values_per_byte; let zero_point_byte_count = b_row * zero_point_bytes_per_col + (block / zero_point_values_per_byte); let zero_point_word_index = zero_point_byte_count >> 0x2u; let zero_point_byte_offset = zero_point_byte_count & 0x3u; let zero_point_sub_offset: u32 = block % zero_point_values_per_byte; let zero_point_bits_offset = (zero_point_byte_offset << 3) + (zero_point_sub_offset * ${attributes.bits}u); let zero_point_word = ${zeroPoints.getByOffset("zero_point_word_index")} >> zero_point_bits_offset; let zero_point = ${dataType2}((zero_point_word) & ${attributes.bits === 2 ? "0x3u" : "0xFu"});` : ` // The default zero point is ${Math.pow(2, attributes.bits - 1)} for unsigned ${attributes.bits}-bit quantization. let zero_point = ${dataType2}(${Math.pow(2, attributes.bits - 1).toFixed(1)});`} let scale = ${scales.getByOffset(`b_row * n_blocks_per_col + block`)}; let b_data = ${b.getByIndices(`${b.type.indices}(b_row, block, 0)`)}; var word_offset = local_id.x * ${attributes.blockSize / aComponents}; for (var i: u32 = 0; i < ${bComponents}; i++) { let b_value = ${bComponents === 1 ? `b_data` : `b_data[i]`}; ${(() => { const passesPerWordBs32 = Math.floor(valuesPerWordBs32 / 8); let code = ""; for (let pass = 0; pass < passesPerWordBs32; pass++) { const lowerShift = pass * attributes.bits * 4; const upperShift = lowerShift + attributes.bits; code += ` ${readA()} {${attributes.bits === 2 ? ` let half_word = b_value >> ${pass * 16}u; let byte_lo = half_word & 0xFFu; let byte_hi = (half_word >> 8u) & 0xFFu; let spread_word = (byte_lo & 0xFu) | ((byte_lo >> 4u) << 8u) | ((byte_hi & 0xFu) << 16u) | ((byte_hi >> 4u) << 24u); let b_value_lower = unpack4xU8(spread_word & 0x03030303u); let b_value_upper = unpack4xU8((spread_word >> 2u) & 0x03030303u);` : ` let b_value_lower = unpack4xU8((b_value >> ${lowerShift}u) & 0x0F0F0F0Fu); let b_value_upper = unpack4xU8((b_value >> ${upperShift}u) & 0x0F0F0F0Fu);`} let b_quantized_values = mat2x4<${dataType2}>(${Array.from( { length: 4 }, (_, i) => `${dataType2}(b_value_lower[${i}]), ${dataType2}(b_value_upper[${i}])` ).join(", ")}); let b_dequantized_values = (b_quantized_values - mat2x4<${dataType2}>(${Array(8).fill("zero_point").join(",")})) * scale; inter_results[local_id.y][local_id.x] += ${Array.from( { length: 2 }, (_, i) => `${`dot(a_data${i}, b_dequantized_values[${i}])`}` ).join(" + ")}; } word_offset += ${8 / aComponents};`; } return code; })()} } workgroupBarrier(); } if (local_idx < ${workgroupY}) { var output_value: ${output.type.value} = ${output.type.value}(0); for (var b = 0u; b < ${workgroupX}; b++) { output_value += inter_results[local_idx][b]; } if (col + local_idx < uniforms.output_shape[2]) { ${output.setByIndices(`${output.type.indices}(batch, row, col + local_idx)`, "output_value")} } } }`; }; return { name: "BlockwiseMatMulNBits32", shaderCache: { hint: `${attributes.blockSize};${aComponents};${bComponents};${workgroupX};${workgroupY}`, inputDependencies: Array(inputs.length).fill("rank") }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType }], dispatchGroup: { x: dispatchSize }, programUniforms }), getShaderSource }; }; matMulNBits = (context, attributes) => { validateInputs48(context.inputs, attributes); if (attributes.blockSize === 32 && context.adapterInfo.isVendor("intel") && context.adapterInfo.isArchitecture("gen-12lp")) { context.compute(createMatMulNBitsBlockSize32ProgramInfo(context.inputs, attributes)); } else { context.compute(createMatMulNBitsProgramInfo(context.inputs, attributes)); } }; parseMatMulNBitsAttributes = (attributes) => createAttributeWithCacheKey2(attributes); } }); // web/lib/wasm/jsep/webgpu/ops/pad.ts var validateInputs49, getPadConstant2, getPadReflect2, getPadEdge2, getPadWrap, getPadSnippet, createPadProgramInfo2, createPadAttributesFromInputs, pad; var init_pad2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/pad.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); validateInputs49 = (inputs) => { if (!inputs || inputs.length < 1) { throw new Error("Too few inputs"); } if (inputs[0].dataType !== 1 /* float */ && inputs[0].dataType !== 10 /* float16 */) { throw new Error("Input type must be float or float16."); } if (inputs.length >= 2) { let validPads = inputs[0].dims.length * 2 === inputs[1].dims[0]; if (inputs.length === 4) { validPads = inputs[3].dims[0] * 2 === inputs[1].dims[0]; } if (!validPads) { throw new Error("The pads should be a 1D tensor of shape [2 * input_rank] or [2 * num_axes]."); } } }; getPadConstant2 = (output, inputRank, padsLength) => { let block = ""; for (let i = inputRank - 1; i >= 0; --i) { block += ` k = i32(${output.indicesGet("indices", i)}) - ${getElementAt("uniforms.pads", i, padsLength)}; if (k < 0) { break; } if (k >= i32(${getElementAt("uniforms.x_shape", i, inputRank)})) { break; } offset += k * i32(${getElementAt("uniforms.x_strides", i, inputRank)}); `; } return ` value = ${output.type.value}(uniforms.constant_value); for (var i = 0; i < 1; i++) { var offset = 0; var k = 0; ${block} value = x[offset]; } `; }; getPadReflect2 = (output, inputRank, padsLength) => { let block = ""; for (let i = inputRank - 1; i >= 0; --i) { block += ` k = i32(${output.indicesGet("indices", i)}) - ${getElementAt("uniforms.pads", i, padsLength)}; if (k < 0) { k = -k; } { let _2n_1 = 2 * (i32(${getElementAt("uniforms.x_shape", i, inputRank)}) - 1); k = k % _2n_1; if(k >= i32(${getElementAt("uniforms.x_shape", i, inputRank)})) { k = _2n_1 - k; } } offset += k * i32(${getElementAt("uniforms.x_strides", i, inputRank)}); `; } return ` var offset = 0; var k = 0; ${block} value = x[offset]; `; }; getPadEdge2 = (output, inputRank, padsLength) => { let block = ""; for (let i = inputRank - 1; i >= 0; --i) { block += ` k = i32(${output.indicesGet("indices", i)}) - ${getElementAt("uniforms.pads", i, padsLength)}; if (k < 0) { k = 0; } if (k >= i32(${getElementAt("uniforms.x_shape", i, inputRank)})) { k = i32(${getElementAt("uniforms.x_shape", i, inputRank)}) - 1; } offset += k * i32(${getElementAt("uniforms.x_strides", i, inputRank)}); `; } return ` var offset = 0; var k = 0; ${block} value = x[offset]; `; }; getPadWrap = (output, inputRank, padsLength) => { let block = ""; for (let i = inputRank - 1; i >= 0; --i) { block += ` k = i32(${output.indicesGet("indices", i)}) - ${getElementAt("uniforms.pads", i, padsLength)}; if (k < 0) { k += i32(${getElementAt("uniforms.x_shape", i, inputRank)}]); } if (k >= i32(${getElementAt("uniforms.x_shape", i, inputRank)})) { k -= i32(${getElementAt("uniforms.x_shape", i, inputRank)}); } offset += k * i32(${getElementAt("uniforms.x_strides", i, inputRank)}); `; } return ` var offset = 0; var k = 0; ${block} value = x[offset]; `; }; getPadSnippet = (output, inputRank, attributes) => { switch (attributes.mode) { case 0: return getPadConstant2(output, inputRank, attributes.pads.length); case 1: return getPadReflect2(output, inputRank, attributes.pads.length); case 2: return getPadEdge2(output, inputRank, attributes.pads.length); case 3: return getPadWrap(output, inputRank, attributes.pads.length); default: throw new Error("Invalid mode"); } }; createPadProgramInfo2 = (inputs, attributes) => { const outputShape = ShapeUtil2.padShape(inputs[0].dims.slice(), attributes.pads); const inputDims = inputs[0].dims; const outputSize = ShapeUtil2.size(outputShape); const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 6 /* int32 */, data: attributes.pads } ]; const isValueFromInput = inputs.length >= 3 && inputs[2].data; if (attributes.mode === 0) { programUniforms.push({ type: isValueFromInput ? inputs[2].dataType : 1 /* float */, data: attributes.value }); } programUniforms.push(...createTensorShapeVariables(inputs[0].dims, outputShape)); const inputDependencies = ["rank"]; const getShaderSource = (shaderHelper) => { const output = outputVariable("output", inputs[0].dataType, outputShape.length); const input = inputVariable("x", inputs[0].dataType, inputDims.length); const dataType = input.type.value; const padSnippet = getPadSnippet(output, inputDims.length, attributes); const uniforms = [ { name: "output_size", type: "u32" }, { name: "pads", type: "i32", length: attributes.pads.length } ]; if (attributes.mode === 0) { uniforms.push({ name: "constant_value", type: isValueFromInput ? dataType : "f32" }); } return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(input, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let indices = ${output.offsetToIndices("global_idx")}; var value = ${dataType}(0); ${padSnippet} output[global_idx] = value; }`; }; return { name: "Pad", shaderCache: { hint: `${attributes.mode}${isValueFromInput}`, inputDependencies }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( ShapeUtil2.size(outputShape) / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }; }; createPadAttributesFromInputs = (inputs, attributes) => { if (inputs.length > 1) { const bigInt64Pads = inputs[1].getBigInt64Array(); const value = inputs.length >= 3 && inputs[2].data ? inputs[2].dataType === 10 /* float16 */ ? inputs[2].getUint16Array()[0] : inputs[2].getFloat32Array()[0] : 0; const inputRank = inputs[0].dims.length; const updatePads = new Int32Array(2 * inputRank).fill(0); if (inputs.length >= 4) { const axes = inputs[3].getBigInt64Array(); for (let i = 0; i < axes.length; i++) { updatePads[Number(axes[i])] = Number(bigInt64Pads[i]); updatePads[Number(axes[i]) + inputRank] = Number(bigInt64Pads[i + axes.length]); } } else { bigInt64Pads.forEach((v, i) => updatePads[Number(i)] = Number(v)); } const pads = []; updatePads.forEach((v) => pads.push(v)); return { mode: attributes.mode, value, pads }; } else { return attributes; } }; pad = (context, attributes) => { validateInputs49(context.inputs); const updatedAttributes = createPadAttributesFromInputs(context.inputs, attributes); context.compute(createPadProgramInfo2(context.inputs, updatedAttributes), { inputs: [0] }); }; } }); // web/lib/wasm/jsep/webgpu/ops/pool.ts var validateInputs50, getAdjustedPoolAttributesAndOutputShape2, getUniformAndPadInfo, generatePoolingCode2, createShaderKeyFromAttributes, createAveragePoolShaderKeyFromAttributes, createMaxPoolShaderKeyFromAttributes, parsePoolCommonAttributes, createAveragePoolProgramInfo2, parseAveragePoolAttributes2, averagePool2, globalPoolAttributes, parseGlobalAveragePoolAttributes2, globalAveragePool2, createMaxPoolProgramInfo2, maxPool2, parseMaxPoolAttributes2, parseGlobalMaxPoolAttributes, globalMaxPool2; var init_pool2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/pool.ts"() { "use strict"; init_esm(); init_wasm_common(); init_util2(); init_common(); validateInputs50 = (inputs) => { if (env2.webgpu.validateInputContent && (!inputs || inputs.length !== 1)) { throw new Error("Pool ops requires 1 input."); } }; getAdjustedPoolAttributesAndOutputShape2 = (input, attributes, isGlobalOperator) => { const isChannelsLast = attributes.format === "NHWC"; const inputShapeAsChannelFirst = input.dims.slice(); if (isChannelsLast) { inputShapeAsChannelFirst.splice(1, 0, inputShapeAsChannelFirst.pop()); } 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(); PoolConvUtil2.adjustPoolAttributes(isGlobalOperator, inputShapeAsChannelFirst, kernelShape, strides, dilations, pads); const outputShapeAsChannelFirst = PoolConvUtil2.computePoolOutputShape( isGlobalOperator, inputShapeAsChannelFirst, 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 }); } const outputShapeAsChannelLast = outputShapeAsChannelFirst.slice(); outputShapeAsChannelLast.push(outputShapeAsChannelLast.splice(1, 1)[0]); return [newAttributes, isChannelsLast ? outputShapeAsChannelLast : outputShapeAsChannelFirst]; }; getUniformAndPadInfo = (outputShape, attributes) => { const isChannelsLast = attributes.format === "NHWC"; const outputSize = ShapeUtil2.size(outputShape); const kernelSize = ShapeUtil2.size(attributes.kernelShape); const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: kernelSize } ]; const uniforms = [ { name: "outputSize", type: "u32" }, { name: "kernelSize", type: "u32" } ]; 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 pwStartEndNotZero = !!(pwStart + pwEnd); programUniforms.push( { type: 12 /* uint32 */, data: kw }, { type: 12 /* uint32 */, data: sw }, { type: 12 /* uint32 */, data: pwStart }, { type: 12 /* uint32 */, data: pwEnd } ); uniforms.push( { name: "kw", type: "u32" }, { name: "sw", type: "u32" }, { name: "pwStart", type: "u32" }, { name: "pwEnd", type: "u32" } ); let phStartEndNotZero = false; 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]; phStartEndNotZero = !!(phStart + phEnd); programUniforms.push( { type: 12 /* uint32 */, data: kh }, { type: 12 /* uint32 */, data: sh }, { type: 12 /* uint32 */, data: phStart }, { type: 12 /* uint32 */, data: phEnd } ); uniforms.push( { name: "kh", type: "u32" }, { name: "sh", type: "u32" }, { name: "phStart", type: "u32" }, { name: "phEnd", type: "u32" } ); } return [programUniforms, uniforms, true, pwStartEndNotZero, phStartEndNotZero]; } else { if (isChannelsLast) { throw new Error("Pooling with kernelShape.length > 2 is not supported for NHWC format."); } const kernelStrides = ShapeUtil2.computeStrides(attributes.kernelShape); programUniforms.push( { type: 12 /* uint32 */, data: kernelStrides }, { type: 12 /* uint32 */, data: attributes.pads }, { type: 12 /* uint32 */, data: attributes.strides } ); uniforms.push( { name: "kernelStrides", type: "u32", length: kernelStrides.length }, { name: "pads", type: "u32", length: attributes.pads.length }, { name: "strides", type: "u32", length: attributes.strides.length } ); const hasPads = attributes.pads.reduce((sum2, cur) => sum2 + cur); return [programUniforms, uniforms, !!hasPads, false, false]; } }; generatePoolingCode2 = (shaderHelper, x, rank, outputShapeRank, attributes, op1, op2, start, uniforms, hasPads, pwStartEndNotZero, phStartEndNotZero) => { const isChannelsLast = attributes.format === "NHWC"; const dataType = x.type.value; const output = outputVariable("output", x.type.tensor, outputShapeRank); if (attributes.kernelShape.length <= 2) { let codeW = ""; let codeH = ""; let codeHEnd = ""; const dimIdxW = rank - (isChannelsLast ? 2 : 1); if (pwStartEndNotZero) { codeW = ` for (var i: u32 = 0u; i < uniforms.kw; i++) { xIndices[${dimIdxW}] = indices[${dimIdxW}] * uniforms.sw - uniforms.pwStart + i; if (xIndices[${dimIdxW}] < 0 || xIndices[${dimIdxW}] >= uniforms.x_shape[${dimIdxW}]) { pad++; continue; } let x_val = x[${x.indicesToOffset("xIndices")}]; ${op1} }`; } else { codeW = ` for (var i: u32 = 0u; i < uniforms.kw; i++) { xIndices[${dimIdxW}] = indices[${dimIdxW}] * uniforms.sw - uniforms.pwStart + i; let x_val = x[${x.indicesToOffset("xIndices")}]; ${op1} }`; } if (attributes.kernelShape.length === 2) { const dimIdxH = rank - (isChannelsLast ? 3 : 2); if (phStartEndNotZero) { codeH = ` for (var j: u32 = 0u; j < uniforms.kh; j++) { xIndices[${dimIdxH}] = indices[${dimIdxH}] * uniforms.sh - uniforms.phStart + j; if (xIndices[${dimIdxH}] < 0 || xIndices[${dimIdxH}] >= uniforms.x_shape[${dimIdxH}]) { pad += i32(uniforms.kw); continue; } `; } else { codeH = ` for (var j: u32 = 0u; j < uniforms.kh; j++) { xIndices[${dimIdxH}] = indices[${dimIdxH}] * uniforms.sh - uniforms.phStart + j; `; } codeHEnd = ` } `; } const poolingCode = ` ${shaderHelper.registerUniforms(uniforms).declareVariables(x, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} let indices = ${output.offsetToIndices("global_idx")}; var xIndices = ${output.offsetToIndices("global_idx")}; var value = ${dataType}(${start}); var pad = 0; ${codeH} ${codeW} ${codeHEnd} ${op2} output[global_idx] = value; }`; return poolingCode; } else { if (isChannelsLast) { throw new Error("Pooling with kernelShape.length > 2 is not supported for NHWC format."); } const stridesRank = attributes.kernelShape.length; const padsRank = attributes.pads.length; let padCode = ""; if (hasPads) { padCode = ` if (xIndices[j] >= uniforms.x_shape[j]) { pad++; isPad = true; break; } } if (!isPad) { let x_val = x[${x.indicesToOffset("xIndices")}]; ${op1} }`; } else { padCode = ` } let x_val = x[${x.indicesToOffset("xIndices")}]; ${op1} `; } const poolingCode = ` ${shaderHelper.registerUniforms(uniforms).declareVariables(x, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} let indices = ${output.offsetToIndices("global_idx")}; var xIndices = ${output.offsetToIndices("global_idx")}; var offsets: array; var value = ${dataType}(${start}); var pad = 0; var isPad = false; for (var i: u32 = 0u; i < uniforms.kernelSize; i++) { var offset = i; for (var j = 0u; j < ${stridesRank - 1}u; j++) { offsets[j] = offset / ${getElementAt("uniforms.kernelStrides", "j", stridesRank)}; offset -= offsets[j] * ${getElementAt("uniforms.kernelStrides", "j", stridesRank)}; } offsets[${stridesRank - 1}] = offset; isPad = false; for (var j = ${rank - stridesRank}u; j < ${rank}u; j++) { xIndices[j] = indices[j] * ${getElementAt( "uniforms.strides", `j - ${rank - stridesRank}u`, stridesRank )} + offsets[j - ${rank - stridesRank}u] - ${getElementAt("uniforms.pads", "j - 2u", padsRank)}; ${padCode} } ${op2} output[global_idx] = value; }`; return poolingCode; } }; createShaderKeyFromAttributes = (attributes) => `${attributes.format};${attributes.ceilMode};${attributes.autoPad};${attributes.kernelShape.length}`; createAveragePoolShaderKeyFromAttributes = (attributes) => `${createShaderKeyFromAttributes(attributes)};${attributes.countIncludePad}`; createMaxPoolShaderKeyFromAttributes = (attributes) => `${createShaderKeyFromAttributes(attributes)};${attributes.storageOrder};${attributes.dilations}`; parsePoolCommonAttributes = (attributes) => ({ format: attributes.format, autoPad: ["NOTSET", "VALID", "SAME_UPPER", "SAME_LOWER"][attributes.auto_pad], ceilMode: attributes.ceil_mode, kernelShape: attributes.kernel_shape, strides: attributes.strides, pads: attributes.pads }); createAveragePoolProgramInfo2 = (name2, input, isGlobalOperator, attributes) => { const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape2( input, attributes, isGlobalOperator ); const x = inputVariable("x", input.dataType, input.dims.length); const dataType = x.type.value; const op1 = "value += x_val;"; let op2 = ""; if (adjustedAttributes.countIncludePad) { op2 += `value /= ${dataType}(uniforms.kernelSize);`; } else { op2 += `value /= ${dataType}(i32(uniforms.kernelSize) - pad);`; } const [programUniforms, uniforms, hasPads, pwStartEndNotZero, phStartEndNotZero] = getUniformAndPadInfo( outputShape, adjustedAttributes ); programUniforms.push(...createTensorShapeVariables(input.dims, outputShape)); const inputDependencies = ["rank"]; return { name: name2, shaderCache: { hint: `${attributes.cacheKey};${hasPads};${pwStartEndNotZero};${phStartEndNotZero}`, inputDependencies }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: input.dataType }], dispatchGroup: { x: Math.ceil( ShapeUtil2.size(outputShape) / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource: (shaderHelper) => generatePoolingCode2( shaderHelper, x, input.dims.length, outputShape.length, adjustedAttributes, op1, op2, 0, uniforms, hasPads, pwStartEndNotZero, phStartEndNotZero ) }; }; parseAveragePoolAttributes2 = (attributes) => { const countIncludePad = attributes.count_include_pad === 0 ? false : true; const attr = parsePoolCommonAttributes(attributes); if (attr.ceilMode !== 0) { throw new Error("using ceil() in shape computation is not yet supported for AveragePool"); } const averagePoolAttributes = { countIncludePad, ...attr, cacheKey: "" }; return { ...averagePoolAttributes, cacheKey: createAveragePoolShaderKeyFromAttributes(averagePoolAttributes) }; }; averagePool2 = (context, attributes) => { validateInputs50(context.inputs); context.compute(createAveragePoolProgramInfo2("AveragePool", context.inputs[0], false, attributes)); }; globalPoolAttributes = { autoPad: "", ceilMode: 0, countIncludePad: false, kernelShape: [], strides: [], pads: [], storageOrder: 0, dilations: [] }; parseGlobalAveragePoolAttributes2 = (attributes) => { const format = attributes.format; return { format, ...globalPoolAttributes, cacheKey: format }; }; globalAveragePool2 = (context, attributes) => { validateInputs50(context.inputs); context.compute(createAveragePoolProgramInfo2("GlobalAveragePool", context.inputs[0], true, attributes)); }; createMaxPoolProgramInfo2 = (name2, input, isGlobalOperator, attributes) => { const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape2( input, attributes, isGlobalOperator ); const op1 = ` value = max(x_val, value); `; const op2 = ""; const x = inputVariable("x", input.dataType, input.dims.length); const inputDependencies = ["rank"]; const [programUniforms, uniforms, hasPads, pwStartEndNotZero, phStartEndNotZero] = getUniformAndPadInfo( outputShape, adjustedAttributes ); programUniforms.push(...createTensorShapeVariables(input.dims, outputShape)); return { name: name2, shaderCache: { hint: `${attributes.cacheKey};${hasPads};${pwStartEndNotZero};${phStartEndNotZero}`, inputDependencies }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: input.dataType }], dispatchGroup: { x: Math.ceil( ShapeUtil2.size(outputShape) / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource: (shaderHelper) => generatePoolingCode2( shaderHelper, x, input.dims.length, outputShape.length, adjustedAttributes, op1, op2, input.dataType === 10 /* float16 */ ? -65504 : -1e5, uniforms, hasPads, pwStartEndNotZero, phStartEndNotZero ) }; }; maxPool2 = (context, attributes) => { validateInputs50(context.inputs); context.compute(createMaxPoolProgramInfo2("MaxPool", context.inputs[0], false, attributes)); }; parseMaxPoolAttributes2 = (attributes) => { const storageOrder = attributes.storage_order; const dilations = attributes.dilations; const attr = parsePoolCommonAttributes(attributes); if (storageOrder !== 0) { throw new Error("column major storage order is not yet supported for MaxPool"); } if (attr.ceilMode !== 0) { throw new Error("using ceil() in shape computation is not yet supported for MaxPool"); } const maxPoolAttributes = { storageOrder, dilations, ...attr, cacheKey: "" }; return { ...maxPoolAttributes, cacheKey: createMaxPoolShaderKeyFromAttributes(maxPoolAttributes) }; }; parseGlobalMaxPoolAttributes = (attributes) => { const format = attributes.format; return { format, ...globalPoolAttributes, cacheKey: format }; }; globalMaxPool2 = (context, attributes) => { validateInputs50(context.inputs); context.compute(createMaxPoolProgramInfo2("GlobalMaxPool", context.inputs[0], true, attributes)); }; } }); // web/lib/wasm/jsep/webgpu/ops/quantize-linear.ts var validateInputs51, createDequantizeLinearProgramInfo, dequantizeLinear, parseDequantizeLinearAttributes; var init_quantize_linear = __esm({ "web/lib/wasm/jsep/webgpu/ops/quantize-linear.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateInputs51 = (inputs, attributes) => { if (inputs.length < 2 || inputs.length > 3) { throw new Error("DequantizeLinear requires 2 or 3 inputs."); } if (inputs.length === 3 && inputs[1].dims === inputs[2].dims) { throw new Error("x-scale and x-zero-point must have the same shape."); } if (inputs.length === 3 && inputs[0].dataType !== inputs[2].dataType) { throw new Error("x and x-zero-point must have the same data type."); } if (inputs[1].dims.length !== 0 && inputs[1].dims.length !== 1 && inputs[1].dims.length !== inputs[0].dims.length) { throw new Error("scale input must be a scalar, a 1D tensor, or have the same rank as the input tensor."); } if (inputs.length > 2) { if (inputs[0].dataType !== inputs[2].dataType) { throw new Error("x and x-zero-point must have the same data type."); } if (inputs[1].dims.length !== inputs[2].dims.length) { throw new Error("scale and zero-point inputs must have the same rank."); } if (!inputs[1].dims.map((d, i) => d === inputs[2].dims[i]).reduce((a, b) => a && b, true)) { throw new Error("scale and zero-point inputs must have the same shape."); } } if (attributes.blockSize > 0) { if (inputs[1].dims.length === 0 || inputs[1].dims.length === 1 && inputs[1].dims[0] === 1) { throw new Error("blockSize must be set only for block quantization."); } if (!inputs[1].dims.map((d, i) => i === attributes.axis || d === inputs[0].dims[i]).reduce((a, b) => a && b, true)) { throw new Error("For block qunatization, scale input shape to match the input shape except for the axis"); } if (inputs[1].dims.length !== inputs[0].dims.length) { throw new Error("For block qunatization the scale input rank must be the same as the x rank."); } const dI = inputs[0].dims[attributes.axis]; const si = inputs[1].dims[attributes.axis]; if (attributes.blockSize < Math.ceil(dI / si) || attributes.blockSize > Math.ceil(dI / (si - 1) - 1)) { throw new Error("blockSize must be with in the range [ceil(dI / Si), ceil(dI / (Si - 1) - 1)]."); } } }; createDequantizeLinearProgramInfo = (inputs, attributes) => { const axis = ShapeUtil2.normalizeAxis(attributes.axis, inputs[0].dims.length); const inputType = inputs[0].dataType; const isSigned = inputType === 3 /* int8 */; const outputShape = inputs[0].dims; const dataType = inputs[1].dataType; const outputSize = ShapeUtil2.size(outputShape); const isPacked = inputType === 3 /* int8 */ || inputType === 2 /* uint8 */; const inputShape = isPacked ? [Math.ceil(ShapeUtil2.size(inputs[0].dims) / 4)] : inputs[0].dims; const scaleShape = inputs[1].dims; const zeroPointInput = inputs.length > 2 ? inputs[2] : void 0; const zeroPointShape = zeroPointInput ? isPacked ? [Math.ceil(ShapeUtil2.size(zeroPointInput.dims) / 4)] : zeroPointInput.dims : void 0; const perLayerQuantization = scaleShape.length === 0 || scaleShape.length === 1 && scaleShape[0] === 1; const perAxisQuantization = perLayerQuantization === false && scaleShape.length === 1; const maxComponents = getMaxComponents(outputSize); const useComponents = perLayerQuantization && (!isPacked || maxComponents === 4); const components = useComponents ? maxComponents : 1; const inputComponent = useComponents && !isPacked ? maxComponents : 1; const input = inputVariable("input", isPacked ? 12 /* uint32 */ : inputType, inputShape.length, inputComponent); const scale = inputVariable("scale", dataType, scaleShape.length); const zeroPoint = zeroPointInput ? inputVariable("zero_point", isPacked ? 12 /* uint32 */ : inputType, zeroPointShape.length) : void 0; const output = outputVariable("output", dataType, outputShape.length, components); const inputVariables = [input, scale]; if (zeroPoint) { inputVariables.push(zeroPoint); } const inputShapes = [inputShape, scaleShape]; if (zeroPointInput) { inputShapes.push(zeroPointShape); } const programUniforms = [ { type: 12 /* uint32 */, data: outputSize / components }, { type: 12 /* uint32 */, data: axis }, { type: 12 /* uint32 */, data: attributes.blockSize }, ...createTensorShapeVariables(...inputShapes, outputShape) ]; const getShaderSource = (shaderHelper) => { const uniforms = [ { name: "output_size", type: "u32" }, { name: "axis", type: "u32" }, { name: "block_size", type: "u32" } ]; return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVariables, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let output_indices = ${output.offsetToIndices("global_idx")}; // Set input x ${(() => { if (isPacked) { return ` let input = ${input.getByOffset("global_idx / 4")}; let x_vec = ${isSigned ? "unpack4xI8(input)" : "unpack4xU8(input)"}; let x_value = ${components === 1 ? "x_vec[global_idx % 4]" : "x_vec"};`; } else { return `let x_value = ${input.getByOffset("global_idx")};`; } })()}; // Set scale input ${(() => { if (perLayerQuantization) { return `let scale_value= ${scale.getByOffset("0")}`; } else if (perAxisQuantization) { return ` let scale_index = ${output.indicesGet("output_indices", "uniforms.axis")}; let scale_value= ${scale.getByOffset("scale_index")};`; } else { return ` var scale_indices: ${scale.type.indices} = output_indices; let index = ${scale.indicesGet("scale_indices", "uniforms.axis")} / uniforms.block_size; ${scale.indicesSet("scale_indices", "uniforms.axis", "index")}; let scale_value= ${scale.getByIndices("scale_indices")};`; } })()}; // Set zero-point input ${(() => { if (zeroPoint) { if (perLayerQuantization) { if (isPacked) { return ` let zero_point_input = ${zeroPoint.getByOffset("0")}; let zero_point_vec = ${isSigned ? "unpack4xI8(zero_point_input)" : "unpack4xU8(zero_point_input)"}; let zero_point_value= zero_point_vec[0]`; } else { return `let zero_point_value = ${zeroPoint.getByOffset("0")}`; } } else if (perAxisQuantization) { if (isPacked) { return ` let zero_point_index = ${output.indicesGet("output_indices", "uniforms.axis")}; let zero_point_input = ${zeroPoint.getByOffset("zero_point_index / 4")}; let zero_point_vec = ${isSigned ? "unpack4xI8(zero_point_input)" : "unpack4xU8(zero_point_input)"}; let zero_point_value = zero_point_vec[zero_point_index % 4]`; } else { return ` let zero_point_index = ${output.indicesGet("output_indices", "uniforms.axis")}; let zero_point_value = ${zeroPoint.getByOffset("zero_point_index")};`; } } else { if (isPacked) { return ` let zero_point_offset = ${scale.indicesToOffset("scale_indices")}; let zero_point_input = ${zeroPoint.getByOffset("zero_point_offset / 4")}; let zero_point_vec = ${isSigned ? "unpack4xI8(zero_point_input)" : "unpack4xU8(zero_point_input)"}; let zero_point_value = zero_point_vec[zero_point_offset % 4];`; } else { return `let zero_point_value = ${zeroPoint.getByIndices("scale_indices")};`; } } } else { return `let zero_point_value = ${isPacked ? isSigned ? "i32" : "u32" : input.type.value}(0);`; } })()}; // Compute and write output ${output.setByOffset("global_idx", `${output.type.value}(x_value - zero_point_value) * scale_value`)}; }`; }; return { name: "DequantizeLinear", shaderCache: { hint: attributes.cacheKey, inputDependencies: zeroPoint ? ["rank", "rank", "rank"] : ["rank", "rank"] }, getShaderSource, getRunData: () => ({ outputs: [{ dims: outputShape, dataType }], dispatchGroup: { x: Math.ceil(outputSize / components / 64), y: 1, z: 1 }, programUniforms }) }; }; dequantizeLinear = (context, attributes) => { validateInputs51(context.inputs, attributes); context.compute(createDequantizeLinearProgramInfo(context.inputs, attributes)); }; parseDequantizeLinearAttributes = (attributes) => createAttributeWithCacheKey2({ axis: attributes.axis, blockSize: attributes.blockSize }); } }); // web/lib/wasm/jsep/webgpu/ops/range.ts var validateInputsContent, createRangeProgramInfo, range; var init_range = __esm({ "web/lib/wasm/jsep/webgpu/ops/range.ts"() { "use strict"; init_esm(); init_wasm_common(); init_common(); validateInputsContent = (start, limit, delta) => { const sameStartLimit = start === limit; const increasingRangeNegativeStep = start < limit && delta < 0; const decreasingRangePositiveStep = start > limit && delta > 0; if (sameStartLimit || increasingRangeNegativeStep || decreasingRangePositiveStep) { throw new Error("Range these inputs' contents are invalid."); } }; createRangeProgramInfo = (start, limit, delta, dataType) => { const numElements = Math.abs(Math.ceil((limit - start) / delta)); const outputShape = [numElements]; const outputSize = numElements; const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: dataType, data: start }, { type: dataType, data: delta }, ...createTensorShapeVariables(outputShape) ]; const getShaderSource = (shaderHelper) => { const output = outputVariable("output", dataType, outputShape.length); const wgslType = output.type.value; const uniforms = [ { name: "outputSize", type: "u32" }, { name: "start", type: wgslType }, { name: "delta", type: wgslType } ]; return ` ${shaderHelper.registerUniforms(uniforms).declareVariables(output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} output[global_idx] = uniforms.start + ${wgslType}(global_idx) * uniforms.delta; }`; }; return { name: "Range", shaderCache: { hint: `${dataType}` }, getShaderSource, getRunData: () => ({ outputs: [{ dims: outputShape, dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }) }; }; range = (context) => { let start = 0; let limit = 0; let delta = 0; if (context.inputs[0].dataType === 6 /* int32 */) { start = context.inputs[0].getInt32Array()[0]; limit = context.inputs[1].getInt32Array()[0]; delta = context.inputs[2].getInt32Array()[0]; } else if (context.inputs[0].dataType === 1 /* float */) { start = context.inputs[0].getFloat32Array()[0]; limit = context.inputs[1].getFloat32Array()[0]; delta = context.inputs[2].getFloat32Array()[0]; } if (env2.webgpu.validateInputContent) { validateInputsContent(start, limit, delta); } context.compute(createRangeProgramInfo(start, limit, delta, context.inputs[0].dataType), { inputs: [] }); }; } }); // web/lib/wasm/jsep/webgpu/ops/scatter-nd.ts var atomicReductionSnippet, createScatterNDProgramInfo, parseScatterNDAttributes, scatterND; var init_scatter_nd = __esm({ "web/lib/wasm/jsep/webgpu/ops/scatter-nd.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); atomicReductionSnippet = (reduction, ptr, v, type) => { if (reduction !== "none" && type !== "i32" && type !== "u32" && type !== "f32") { throw new Error(`Input ${type} is not supported with reduction ${reduction}.`); } const floatStart = `{ var oldValue = 0; loop { let newValueF32 =`; const floatEnd = `; let newValue = bitcast(newValueF32); let res = atomicCompareExchangeWeak(&${ptr}, oldValue, newValue); if res.exchanged { break; } oldValue = res.old_value; } }`; switch (reduction) { case "none": return `${ptr}=${v};`; case "add": if (type === "i32" || type === "u32") { return `atomicAdd(&${ptr}, bitcast<${type}>(${v}));`; } else { return ` ${floatStart}bitcast<${type}>(oldValue) + (${v})${floatEnd}`; } case "max": if (type === "i32" || type === "u32") { return `atomicMax(&${ptr}, bitcast<${type}>(${v}));`; } else { return ` ${floatStart}max(bitcast(oldValue), (${v}))${floatEnd}`; } case "min": if (type === "i32" || type === "u32") { return `atomicMin(&${ptr}, bitcast<${type}>(${v}));`; } else { return `${floatStart}min(bitcast<${type}>(oldValue), (${v}))${floatEnd}`; } case "mul": return `${floatStart}(bitcast<${type}>(oldValue) * (${v}))${floatEnd}`; default: throw new Error(`Reduction ${reduction} is not supported.`); } }; createScatterNDProgramInfo = (inputs, attributes) => { const inputShape = inputs[0].dims; const indicesShape = inputs[1].dims; const outputShape = inputShape; const components = 1; const outputSize = Math.ceil(ShapeUtil2.sizeToDimension(indicesShape, indicesShape.length - 1) / components); const lastIndexDimension = indicesShape[indicesShape.length - 1]; const numUpdatesElements = ShapeUtil2.sizeFromDimension(inputShape, lastIndexDimension); const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: lastIndexDimension }, { type: 12 /* uint32 */, data: numUpdatesElements }, ...createTensorShapeVariables(inputs[1].dims, inputs[2].dims, outputShape) ]; const getShaderSource = (shaderHelper) => { const indices = inputVariable("indices", inputs[1].dataType, inputs[1].dims.length); const updates = inputVariable("updates", inputs[2].dataType, inputs[2].dims.length, components); const output = attributes.reduction !== "none" && attributes.reduction !== "" ? atomicOutputVariable("output", inputs[0].dataType, outputShape.length) : outputVariable("output", inputs[0].dataType, outputShape.length, components); return ` ${shaderHelper.registerUniform("output_size", "u32").registerUniform("last_index_dimension", "u32").registerUniform("num_updates_elements", "u32").declareVariables(indices, updates, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} var data_offset = 0u; let indices_start = uniforms.last_index_dimension * global_idx; let indices_end = indices_start + uniforms.last_index_dimension; for (var i = indices_start; i < indices_end; i++) { var index = i32(indices[i].x); ${inputs[0].dims.length === 1 ? ` let element_count_dim = uniforms.output_strides; let dim_value = uniforms.output_shape;` : ` let element_count_dim = uniforms.output_strides[i - indices_start]; let dim_value = uniforms.output_shape[i - indices_start];`} if (index >= 0) { if (index >= i32(dim_value)) { index = i32(dim_value - 1); } } else { if (index < -i32(dim_value)) { index = 0; } else { index += i32(dim_value); } } data_offset += u32((u32(index) * element_count_dim)); } for (var i = 0u; i < uniforms.num_updates_elements; i++) { let value = updates[uniforms.num_updates_elements * global_idx + i]; ${atomicReductionSnippet( attributes.reduction, "output[data_offset + i]", "value", output.type.value )} } }`; }; return { name: "ScatterND", shaderCache: { hint: `${attributes.cacheKey}_${attributes.reduction}`, inputDependencies: ["rank", "rank"] }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms }), getShaderSource }; }; parseScatterNDAttributes = (attributes) => createAttributeWithCacheKey2({ reduction: attributes.reduction }); scatterND = (context, attributes) => { context.compute(createScatterNDProgramInfo(context.inputs, attributes), { inputs: [context.inputs[1], context.inputs[2]], outputs: [] }); }; } }); // web/lib/wasm/jsep/webgpu/ops/resize.ts var validateScales, updateScales, validateInputs52, getSafeIntegerDivision, getOriginalCoordinateFromResizedCoordinate, getNearestPixelFromOriginal, updateRoI, initOutputShape, adjustOutputShape, calculateOriginalIndicesFromOutputIndices, calculateInputIndicesFromOutputIndices, checkInputIndices, setChannelAndBatchIndices, bilinearInterpolation, bicubicInterpolation, trilinearInterpolation, createResizeProgramInfo, getOpsetVersionFromCustomDataBuffer, resize2, parseResizeAttributes; var init_resize = __esm({ "web/lib/wasm/jsep/webgpu/ops/resize.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateScales = (scales, attributes) => { scales.every( (value) => value > 0 || (() => { throw new Error("Resize requires scales input values to be positive"); }) ); if (scales.length > 0) { if (attributes.mode === "linear") { if (!(scales.length === 2 || scales.length === 3 || scales.length === 4 && scales[0] === 1 && scales[1] === 1 || scales.length === 4 && scales[0] === 1 && scales[3] === 1 || scales.length === 5 && scales[0] === 1 && scales[1] === 1)) { throw new Error( `For linear mode, Resize requires scales to be 2D, 3D, 4D with either two outermost or one innermost and one outermost scale values equal to 1, or 5D with two outermost scale values equal to 1` ); } } else if (attributes.mode === "cubic") { if (!(scales.length === 2 || scales.length === 4 && scales[0] === 1 && scales[1] === 1 || scales.length === 4 && scales[0] === 1 && scales[3] === 1)) { throw new Error("Resize requires scales input size to be 2 or 4 for cubic mode"); } } } }; updateScales = (scales, axes, rank) => { axes.every( (value) => value >= 0 && value < rank || (() => { throw new Error("Resize requires axes input values to be positive and less than rank"); }) ); const newScales = new Array(rank).fill(1); axes.forEach((value, index) => newScales[value] = scales[index]); return newScales; }; validateInputs52 = (inputs, attributes, opsetVersion, scales, sizes, roi) => { const [roiInputIndex, scalesInputIndex, sizesInputIndex] = opsetVersion > 10 ? [1, 2, 3] : [-1, inputs.length > 1 ? 1 : -1, -1]; const rank = inputs[0].dims.length; if (roiInputIndex > 0 && inputs.length > roiInputIndex && inputs[roiInputIndex].dims.length > 0) { inputs[roiInputIndex].getFloat32Array().forEach((value) => roi.push(value)); } else if (attributes.coordinateTransformMode === "tf_crop_and_resize") { throw new Error("Resize requires RoI input to be specified when coordinateTransformMode is tfCropAndResize"); } if (scalesInputIndex > 0 && inputs.length > scalesInputIndex && inputs[scalesInputIndex].dims.length === 1 && inputs[scalesInputIndex].dims[0] > 0) { inputs[scalesInputIndex].getFloat32Array().forEach((value) => scales.push(value)); if (scales.length !== 0 && scales.length !== rank && opsetVersion >= 18 && scales.length !== attributes.axes.length) { throw new Error("Resize requires scales input size to be same as input rank or axes size for opset 18 and up"); } validateScales(scales, attributes); if (attributes.axes.length > 0) { updateScales(scales, attributes.axes, rank).forEach((value, index) => scales[index] = value); } } if (sizesInputIndex > 0 && inputs.length > sizesInputIndex && inputs[sizesInputIndex].dims.length === 1 && inputs[sizesInputIndex].dims[0] > 0) { inputs[sizesInputIndex].getBigInt64Array().forEach((value) => sizes.push(Number(value))); if (sizes.length !== 0 && sizes.length !== rank && opsetVersion >= 18 && sizes.length !== attributes.axes.length) { throw new Error("Resize requires sizes input size to be same as input rank or axes size for opset 18 and up"); } } if (attributes.axes.length > 0) { if (scales.length !== 0 && scales.length !== attributes.axes.length) { throw new Error('Resize requires "scales" input size to be of axes rank when axes attributes is specified'); } if (sizes.length !== 0 && sizes.length !== attributes.axes.length) { throw new Error('Resize requires "sizes" input size to be of rank axes rank when axes attributes is specified'); } } if (typeof scales !== "undefined" && typeof sizes !== "undefined" && scales.length > 0 && sizes.length > rank) { throw new Error("Resize requires only of scales or sizes to be specified"); } }; getSafeIntegerDivision = (a, b, c, dType) => ` // The whole part and the fractional part are calculated separately due to inaccuracy of floating // point division. As an example, f32(21) / f32(7) may evaluate to 2.99... instead of 3, causing an // offset-by-one error later in floor(). let big = (${a}) * (${b}); let whole = ${dType}(big / (${c})); let fract = ${dType}(big % (${c})) / ${dType}(${c}); return whole + fract; `; getOriginalCoordinateFromResizedCoordinate = (coordinateTransferMode, dType) => `fn getOriginalCoordinateFromResizedCoordinate(xResized: u32, xScale: f32, lengthResized: u32, lengthOriginal: u32, roiStart: f32, roiEnd: f32) -> ${dType} { ` + (() => { switch (coordinateTransferMode) { case "asymmetric": return ` if (xScale < 1.0 || floor(xScale) != xScale) { return ${dType}(xResized) / ${dType}(xScale); } else { ${getSafeIntegerDivision("xResized", "lengthOriginal", "lengthResized", dType)} } `; case "pytorch_half_pixel": return `if (lengthResized > 1) { return (${dType}(xResized) + 0.5) / ${dType}(xScale) - 0.5; } else { return 0.0; }`; case "tf_half_pixel_for_nn": return `return (${dType}(xResized) + 0.5) / ${dType}(xScale);`; case "align_corners": return `if (lengthResized == 1) { return 0.0; } else { ${getSafeIntegerDivision("xResized", "lengthOriginal - 1", "lengthResized - 1", dType)} }`; case "tf_crop_and_resize": return `if (lengthResized > 1) { return ${dType}(roiStart) * ${dType}(lengthOriginal - 1) + (${dType}(xResized) * ${dType}(roiEnd - roiStart) * ${dType}(lengthOriginal - 1)) / ${dType}(lengthResized - 1); } else { return 0.5 * ${dType}(roiStart + roiEnd) * ${dType}(lengthOriginal - 1); }`; case "half_pixel_symmetric": return `const outputWidth = ${dType}xScale * ${dType}(lengthResized); const adjustment = ${dType}(lengthResized) / outputWidth; const center = ${dType}(lengthOriginal) / 2; const offset = center * (1 - adjustment); return offset + ((${dType}(xResized) + 0.5) / ${dType}(xScale)) - 0.5;`; case "half_pixel": return `return ((${dType}(xResized) + 0.5) / ${dType}(xScale)) - 0.5;`; default: throw new Error(`Coordinate transform mode ${coordinateTransferMode} is not supported`); } })() + "}"; getNearestPixelFromOriginal = (nearestMode, opsetVersion, dType) => `fn getNearestPixelFromOriginal(xOriginal: ${dType}, isDownSample: bool) -> ${dType} {` + (() => { switch (nearestMode) { case "round_prefer_ceil": return "if (fract(xOriginal) == 0.5) { return ceil(xOriginal); } else { return round(xOriginal); }"; case "floor": return "return floor(xOriginal);"; case "ceil": return "return ceil(xOriginal);"; case "round_prefer_floor": return "if (fract(xOriginal) == 0.5) { return floor(xOriginal); } else { return round(xOriginal); }"; case "simple": default: if (opsetVersion < 11) { return "if (isDownSample) { return ceil(xOriginal); } else { return xOriginal; }"; } throw new Error(`Nearest mode ${nearestMode} is not supported`); } })() + "}"; updateRoI = (roi, axes, rank) => { const roiTmp = new Array(rank).fill(0).concat(new Array(rank).fill(1)); const roiLocal = roi.length === 0 ? roiTmp : roi.slice(); if (axes.length > 0) { axes.forEach((v, i) => { roiTmp[v] = roiLocal[i]; roiTmp[i + rank] = roiLocal[axes.length + i]; }); return roiTmp; } return roiLocal; }; initOutputShape = (inputShape, scales, sizes, axes) => { let outputShape = []; if (sizes.length > 0) { if (axes.length > 0) { inputShape.forEach((v) => outputShape.push(v)); if (Math.max(...axes) > inputShape.length) { throw new Error("axes is out of bound"); } axes.forEach((v, i) => outputShape[v] = sizes[i]); } else { sizes.forEach((v) => outputShape.push(v)); } } else { if (scales.length === 0) { throw new Error("Resize requires either scales or sizes."); } else { outputShape = inputShape.map((value, index) => Math.round(value * scales[index])); } } return outputShape; }; adjustOutputShape = (inputShape, scales, attributes) => { const scaleInPolicy = (() => { switch (attributes.keepAspectRatioPolicy) { case "not_larger": return attributes.axes.length > 0 ? Math.min(...attributes.axes.map((i) => scales[i]), Number.MAX_VALUE) : Math.min(...scales, Number.MAX_VALUE); case "not_smaller": return attributes.axes.length > 0 ? Math.max(...attributes.axes.map((i) => scales[i]), Number.MIN_VALUE) : Math.max(...scales, Number.MIN_VALUE); default: throw new Error(`Keep aspect ratio policy ${attributes.keepAspectRatioPolicy} is not supported`); } })(); scales.fill(1, 0, scales.length); const adjustedOutputShape = inputShape.slice(); if (attributes.axes.length > 0) { attributes.axes.forEach((v) => scales[v] = scaleInPolicy); attributes.axes.forEach((v) => adjustedOutputShape[v] = Math.round(inputShape[v] * scales[v])); } else { scales.fill(scaleInPolicy, 0, scales.length); adjustedOutputShape.forEach((v, i) => adjustedOutputShape[i] = Math.round(v * scales[i])); } return adjustedOutputShape; }; calculateOriginalIndicesFromOutputIndices = (output, inputShape, outputShape, scalesLength, roiLength) => ` fn calculateOriginalIndicesFromOutputIndices(output_indices: ${output.type.indices}) -> array<${output.type.value}, ${outputShape.length}> { var original_indices: array<${output.type.value}, ${outputShape.length}>; for (var i:u32 = 0; i < ${outputShape.length}; i++) { var output_index = ${output.indicesGet("output_indices", "i")}; var scale = ${getElementAt("uniforms.scales", "i", scalesLength)}; var roi_low = ${getElementAt("uniforms.roi", "i", roiLength)}; var roi_hi = ${getElementAt("uniforms.roi", `i + ${inputShape.length}`, roiLength)}; if (scale == 1.0) { original_indices[i] = ${output.type.value}(output_index); } else { var input_shape_i = ${getElementAt("uniforms.input_shape", "i", inputShape.length)}; var output_shape_i = ${getElementAt("uniforms.output_shape", "i", outputShape.length)}; original_indices[i] = getOriginalCoordinateFromResizedCoordinate(output_index, scale, output_shape_i, input_shape_i, roi_low, roi_hi); } } return original_indices; }`; calculateInputIndicesFromOutputIndices = (input, output, inputShape, outputShape, scalesLength, roiLength, useExtrapolation) => ` fn calculateInputIndicesFromOutputIndices(output_indices: ${output.type.indices}) -> ${input.type.indices} { var input_indices: ${input.type.indices}; for (var i:u32 = 0; i < ${outputShape.length}; i++) { var output_index = ${output.indicesGet("output_indices", "i")}; var input_index: u32; var scale = ${getElementAt("uniforms.scales", "i", scalesLength)}; if (scale == 1.0) { input_index = output_index; } else { var roi_low = ${getElementAt("uniforms.roi", "i", roiLength)}; var roi_hi = ${getElementAt("uniforms.roi", `i + ${inputShape.length}`, roiLength)}; var input_shape_i = ${getElementAt("uniforms.input_shape", "i", inputShape.length)}; var output_shape_i = ${getElementAt("uniforms.output_shape", "i", outputShape.length)}; var original_idx = getOriginalCoordinateFromResizedCoordinate(output_index, scale, output_shape_i, input_shape_i, roi_low, roi_hi); if (!${useExtrapolation} || (original_idx >= 0 && original_idx < ${output.type.value}(input_shape_i))) { if (original_idx < 0) { input_index = 0; } else if (original_idx > ${output.type.value}(input_shape_i - 1)) { input_index = input_shape_i - 1; } else { input_index = u32(getNearestPixelFromOriginal(original_idx, scale < 1)); } } else { input_index = u32(original_idx); } } ${input.indicesSet("input_indices", "i", "input_index")} } return input_indices; }`; checkInputIndices = (input, inputShape) => ` fn checkInputIndices(input_indices: ${input.type.indices}) -> bool { for (var i:u32 = 0; i < ${inputShape.length}; i++) { var input_index = ${input.indicesGet("input_indices", "i")}; if (input_index < 0 || input_index >= ${getElementAt("uniforms.input_shape", "i", inputShape.length)}) { return false; } } return true; }`; setChannelAndBatchIndices = (input, channelIdx, batchIdx, spacialDims) => input.rank > spacialDims ? ` ${input.indicesSet("input_indices", channelIdx, "channel")}; ${input.indicesSet("input_indices", batchIdx, "batch")}; ` : ""; bilinearInterpolation = (input, output, inputShape, useExtrapolation, extrapolationValue) => { const isNchw = true; const [batchIdx, heightIdx, widthIdx, channelIdx] = inputShape.length === 2 ? [-1, 0, 1, -1] : isNchw ? [0, 2, 3, 1] : [0, 1, 2, 3]; const dType = input.type.value; return ` fn getInputValue(batch: u32, channel: u32, row: u32, col: u32) -> ${dType} { var input_indices: ${input.type.indices}; ${input.indicesSet("input_indices", heightIdx, `max(0, min(row, ${inputShape[heightIdx]} - 1))`)}; ${input.indicesSet("input_indices", widthIdx, `max(0, min(col, ${inputShape[widthIdx]} - 1))`)}; ${setChannelAndBatchIndices(input, channelIdx, batchIdx, 2)} return ${input.getByIndices("input_indices")}; } fn bilinearInterpolation(output_indices: ${output.type.indices}) -> ${dType} { var originalIndices = calculateOriginalIndicesFromOutputIndices(output_indices); var row:${dType} = originalIndices[${heightIdx}]; var col:${dType} = originalIndices[${widthIdx}]; ${useExtrapolation ? `if (row < 0 || row > (${inputShape[heightIdx]} - 1) || col < 0 || col > (${inputShape[widthIdx]} - 1)) { return ${extrapolationValue}; }` : ""}; row = max(0, min(row, ${inputShape[heightIdx]} - 1)); col = max(0, min(col, ${inputShape[widthIdx]} - 1)); var row1: u32 = u32(row); var col1: u32 = u32(col); var row2: u32 = u32(row + 1); var col2: u32 = u32(col + 1); var channel: u32 = ${inputShape.length > 2 ? `u32(originalIndices[${channelIdx}])` : "0"}; var batch: u32 = ${inputShape.length > 2 ? `u32(originalIndices[${batchIdx}])` : "0"}; var x11: ${dType} = getInputValue(batch, channel, row1, col1); var x12: ${dType} = getInputValue(batch, channel, row1, col2); var x21: ${dType} = getInputValue(batch, channel, row2, col1); var x22: ${dType} = getInputValue(batch, channel, row2, col2); var dx1: ${dType} = abs(row - ${dType}(row1)); var dx2: ${dType} = abs(${dType}(row2) - row); var dy1: ${dType} = abs(col - ${dType}(col1)); var dy2: ${dType} = abs(${dType}(col2) - col); if (row1 == row2) { dx1 = 0.5; dx2 = 0.5; } if (col1 == col2) { dy1 = 0.5; dy2 = 0.5; } return (x11 * dx2 * dy2 + x12 * dx2 * dy1 + x21 * dx1 * dy2 + x22 * dx1 * dy1); }`; }; bicubicInterpolation = (input, output, inputShape, outputShape, scales, roi, cubicCoeffA, useExtrapolation, extrapolationValue, excludeOutside) => { const is2D = inputShape.length === 2; const isNchw = true; const [heightIdx, widthIdx] = is2D ? [0, 1] : isNchw ? [2, 3] : [1, 2]; const dType = input.type.value; const createCubicInterpolationFunction = (idx) => { const direction = idx === heightIdx ? "row" : "col"; return ` fn ${direction}CubicInterpolation(input_indices: ${input.type.indices}, output_indices: ${output.type.indices}) -> ${dType} { var output_index = ${output.indicesGet("output_indices", idx)}; var originalIdx: ${dType} = getOriginalCoordinateFromResizedCoordinate(output_index, ${scales[idx]}, ${outputShape[idx]}, ${inputShape[idx]}, ${roi[idx]}, ${roi[idx]} + ${inputShape.length}); var fractOriginalIdx: ${dType} = originalIdx - floor(originalIdx); var coefs = getCubicInterpolationCoefs(fractOriginalIdx); if (${useExtrapolation} && (originalIdx < 0 || originalIdx > (${inputShape[idx]} - 1))) { return ${extrapolationValue}; } var data: array<${dType}, 4> = array<${dType}, 4>(0.0, 0.0, 0.0, 0.0); for (var i: i32 = -1; i < 3; i++) { var ${direction}: ${dType} = originalIdx + ${dType}(i); if (${direction} < 0 || ${direction} >= ${inputShape[idx]}) { ${(() => { if (excludeOutside) { return `coefs[i + 1] = 0.0; continue;`; } else if (useExtrapolation) { return `return ${extrapolationValue};`; } else { return `${direction} = max(0, min(${direction}, ${inputShape[idx]} - 1));`; } })()}; } var input_indices_copy: ${input.type.indices} = input_indices; ${input.indicesSet("input_indices_copy", idx, `u32(${direction})`)}; data[i + 1] = ${idx === heightIdx ? input.getByIndices("input_indices_copy") : "rowCubicInterpolation(input_indices_copy, output_indices)"}; } return cubicInterpolation1D(data, coefs); }`; }; return ` ${createCubicInterpolationFunction(heightIdx)}; ${createCubicInterpolationFunction(widthIdx)}; fn getCubicInterpolationCoefs(s: ${dType}) -> array<${dType}, 4> { var absS = abs(s); var coeffs: array<${dType}, 4> = array<${dType}, 4>(0.0, 0.0, 0.0, 0.0); var oneMinusAbsS: ${dType} = 1.0 - absS; var twoMinusAbsS: ${dType} = 2.0 - absS; var onePlusAbsS: ${dType} = 1.0 + absS; coeffs[0] = ((${cubicCoeffA} * onePlusAbsS - 5 * ${cubicCoeffA}) * onePlusAbsS + 8 * ${cubicCoeffA}) * onePlusAbsS - 4 * ${cubicCoeffA}; coeffs[1] = ((${cubicCoeffA} + 2) * absS - (${cubicCoeffA} + 3)) * absS * absS + 1; coeffs[2] = ((${cubicCoeffA} + 2) * oneMinusAbsS - (${cubicCoeffA} + 3)) * oneMinusAbsS * oneMinusAbsS + 1; coeffs[3] = ((${cubicCoeffA} * twoMinusAbsS - 5 * ${cubicCoeffA}) * twoMinusAbsS + 8 * ${cubicCoeffA}) * twoMinusAbsS - 4 * ${cubicCoeffA}; return coeffs; } fn cubicInterpolation1D(x: array<${dType}, 4>, coefs: array<${dType}, 4>) -> ${dType} { var coefsSum: ${dType} = coefs[0] + coefs[1] + coefs[2] + coefs[3]; return (x[0] * coefs[0] + x[1] * coefs[1]+ x[2] * coefs[2]+ x[3] * coefs[3]) / coefsSum; } fn bicubicInterpolation(output_indices: ${output.type.indices}) -> ${dType} { var input_indices: ${input.type.indices} = output_indices; return colCubicInterpolation(input_indices, output_indices); } `; }; trilinearInterpolation = (input, output, inputShape, useExtrapolation, extrapolationValue) => { const isNchw = true; const [batchIdx, depthIdx, heightIdx, widthIdx, channelIdx] = inputShape.length === 3 ? [-1, 0, 1, 2, -1] : isNchw ? [0, 2, 3, 4, 1] : [0, 1, 2, 3, 4]; const dType = input.type.value; return ` fn getInputValue(batch: u32, channel: u32, depth:u32, height: u32, width: u32) -> ${dType} { var input_indices: ${input.type.indices}; ${input.indicesSet("input_indices", depthIdx, `max(0, min(depth, ${inputShape[depthIdx]} - 1))`)}; ${input.indicesSet("input_indices", heightIdx, `max(0, min(height, ${inputShape[heightIdx]} - 1))`)}; ${input.indicesSet("input_indices", widthIdx, `max(0, min(width, ${inputShape[widthIdx]} - 1))`)}; ${setChannelAndBatchIndices(input, channelIdx, batchIdx, 3)} return ${input.getByIndices("input_indices")}; } fn trilinearInterpolation(output_indices: ${output.type.indices}) -> ${dType} { var originalIndices = calculateOriginalIndicesFromOutputIndices(output_indices); var depth:${dType} = originalIndices[${depthIdx}]; var height:${dType} = originalIndices[${heightIdx}]; var width:${dType} = originalIndices[${widthIdx}]; ${useExtrapolation ? `if (depth < 0 || depth > (${inputShape[depthIdx]} - 1) || height < 0 || height > (${inputShape[heightIdx]} - 1) || width < 0 || (width > ${inputShape[widthIdx]} - 1)) { return ${extrapolationValue}; }` : ""}; depth = max(0, min(depth, ${inputShape[depthIdx]} - 1)); height = max(0, min(height, ${inputShape[heightIdx]} - 1)); width = max(0, min(width, ${inputShape[widthIdx]} - 1)); var depth1: u32 = u32(depth); var height1: u32 = u32(height); var width1: u32 = u32(width); var depth2: u32 = u32(depth + 1); var height2: u32 = u32(height + 1); var width2: u32 = u32(width + 1); var channel: u32 = ${inputShape.length > 3 ? `u32(originalIndices[${channelIdx}])` : "0"}; var batch: u32 = ${inputShape.length > 3 ? `u32(originalIndices[${batchIdx}])` : "0"}; var x111: ${dType} = getInputValue(batch, channel, depth1, height1, width1); var x112: ${dType} = getInputValue(batch, channel, depth1, height1, width2); var x121: ${dType} = getInputValue(batch, channel, depth1, height2, width1); var x122: ${dType} = getInputValue(batch, channel, depth1, height2, width2); var x211: ${dType} = getInputValue(batch, channel, depth2, height1, width1); var x212: ${dType} = getInputValue(batch, channel, depth2, height1, width2); var x221: ${dType} = getInputValue(batch, channel, depth2, height2, width1); var x222: ${dType} = getInputValue(batch, channel, depth2, height2, width2); var dx1: ${dType} = abs(depth - ${dType}(depth1)); var dx2: ${dType} = abs(${dType}(depth2) - depth); var dy1: ${dType} = abs(height - ${dType}(height1)); var dy2: ${dType} = abs(${dType}(height2) - height); var dz1: ${dType} = abs(width - ${dType}(width1)); var dz2: ${dType} = abs(${dType}(width2) - width); if (depth1 == depth2) { dx1 = 0.5; dx2 = 0.5; } if (height1 == height2) { dy1 = 0.5; dy2 = 0.5; } if (width1 == width2) { dz1 = 0.5; dz2 = 0.5; } return (x111 * dx2 * dy2 * dz2 + x112 * dx2 * dy2 * dz1 + x121 * dx2 * dy1 *dz2 + x122 * dx2 * dy1 * dz1 + x211 * dx1 * dy2 * dz2 + x212 * dx1 * dy2 * dz1 + x221 * dx1 * dy1 *dz2 + x222 * dx1 * dy1 * dz1); }`; }; createResizeProgramInfo = (inputTensor, attributes, opsetVersion, scalesInput, sizes, roiInput) => { const inputShape = inputTensor.dims; const roi = updateRoI(roiInput, attributes.axes, inputShape.length); let outputShape = initOutputShape(inputShape, scalesInput, sizes, attributes.axes); let scales = scalesInput.slice(); if (scalesInput.length === 0) { scales = inputShape.map((value, index) => value === 0 ? 1 : outputShape[index] / value); if (attributes.keepAspectRatioPolicy !== "stretch") { outputShape = adjustOutputShape(inputShape, scales, attributes); } } const output = outputVariable("output", inputTensor.dataType, outputShape.length); const input = inputVariable("input", inputTensor.dataType, inputShape.length); const outputSize = ShapeUtil2.size(outputShape); const noScale = inputShape.length === outputShape.length && inputShape.every((d, i) => d === outputShape[i]); const useExtrapolation = attributes.coordinateTransformMode === "tf_crop_and_resize"; const extrapolationValue = attributes.extrapolationValue; const dataType = input.type.value; const getShaderSource = (shaderHelper) => ` ${noScale ? "" : ` ${getOriginalCoordinateFromResizedCoordinate(attributes.coordinateTransformMode, dataType)}; ${(() => { switch (attributes.mode) { case "nearest": return ` ${checkInputIndices(input, inputShape)}; ${getNearestPixelFromOriginal(attributes.nearestMode, opsetVersion, dataType)}; ${calculateInputIndicesFromOutputIndices( input, output, inputShape, outputShape, scales.length, roi.length, useExtrapolation )}; `; case "linear": return ` ${calculateOriginalIndicesFromOutputIndices(output, inputShape, outputShape, scales.length, roi.length)}; ${(() => { if (inputShape.length === 2 || inputShape.length === 4) { return `${bilinearInterpolation(input, output, inputShape, useExtrapolation, extrapolationValue)}`; } else if (inputShape.length === 3 || inputShape.length === 5) { return `${trilinearInterpolation(input, output, inputShape, useExtrapolation, extrapolationValue)}`; } else { throw Error("Linear mode only supports input dims 2, 3, 4 and 5 are supported in linear mode."); } })()}; `; case "cubic": return ` ${(() => { if (inputShape.length === 2 || inputShape.length === 4) { return `${bicubicInterpolation( input, output, inputShape, outputShape, scales, roi, attributes.cubicCoeffA, useExtrapolation, attributes.extrapolationValue, attributes.excludeOutside )}`; } else { throw Error("Cubic mode only supports input dims 2 and 4 are supported in linear mode."); } })()}; `; default: throw Error("Invalid resize mode"); } })()}; `} ${shaderHelper.registerUniform("output_size", "u32").registerUniform("scales", "f32", scales.length).registerUniform("roi", "f32", roi.length).declareVariables(input, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} ${noScale ? "output[global_idx] = input[global_idx];" : ` let output_indices = ${output.offsetToIndices("global_idx")}; var input_indices: ${input.type.indices}; ${(() => { switch (attributes.mode) { case "nearest": return `input_indices = calculateInputIndicesFromOutputIndices(output_indices); if (checkInputIndices(input_indices)) { output[global_idx] = ${input.getByIndices("input_indices")}; } else { output[global_idx] = ${attributes.extrapolationValue}; }`; case "linear": return `output[global_idx] = ${inputShape.length === 2 || inputShape.length === 4 ? "bilinearInterpolation" : "trilinearInterpolation"}(output_indices);`; case "cubic": return "output[global_idx] = bicubicInterpolation(output_indices);"; default: throw Error(`Unsupported resize mode: ${attributes.mode}`); } })()}; `} }`; return { name: "Resize", shaderCache: { hint: `${attributes.cacheKey}|${opsetVersion}|${scales.length > 0 ? attributes.mode === "cubic" ? scales : scales.length : ""}|${sizes.length > 0 ? sizes : ""}|${roi.length > 0 ? roi : ""}|${noScale}|${attributes.mode === "nearest" ? inputShape.length : inputShape}`, inputDependencies: ["rank"] }, getShaderSource, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputTensor.dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms: [ { type: 12 /* uint32 */, data: outputSize }, { type: 1 /* float */, data: scales }, { type: 1 /* float */, data: roi }, ...createTensorShapeVariables(inputShape, outputShape) ] }) }; }; getOpsetVersionFromCustomDataBuffer = (context) => { const customDataBuffer = context.customDataBuffer; const customDataBuffer32 = new Uint32Array(customDataBuffer, customDataBuffer.byteOffset, 1); const opsetVersion = customDataBuffer32[0]; return opsetVersion; }; resize2 = (context, attributes) => { const scales = []; const sizes = []; const roi = []; const opsetVersion = getOpsetVersionFromCustomDataBuffer(context); if (attributes.antialias !== 0) { throw Error("Only default value (0) for Antialias attribute is supported"); } validateInputs52(context.inputs, attributes, opsetVersion, scales, sizes, roi); context.compute(createResizeProgramInfo(context.inputs[0], attributes, opsetVersion, scales, sizes, roi), { inputs: [0] }); }; parseResizeAttributes = (attributes) => { const antialias = attributes.antialias; const axes = attributes.axes; const coordinateTransformMode = attributes.coordinateTransformMode; const cubicCoeffA = attributes.cubicCoeffA; const excludeOutside = attributes.excludeOutside !== 0; const extrapolationValue = attributes.extrapolationValue; const keepAspectRatioPolicy = attributes.keepAspectRatioPolicy; const mode = attributes.mode; const nearestMode = attributes.nearestMode === "" ? "simple" : attributes.nearestMode; return createAttributeWithCacheKey2({ antialias, axes, coordinateTransformMode, cubicCoeffA, excludeOutside, extrapolationValue, keepAspectRatioPolicy, mode, nearestMode }); }; } }); // web/lib/wasm/jsep/webgpu/ops/skip-layer-norm.ts var validateInputs53, createSkipLayerNormProgramInfo, skipLayerNorm; var init_skip_layer_norm = __esm({ "web/lib/wasm/jsep/webgpu/ops/skip-layer-norm.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); validateInputs53 = (inputs) => { if (!inputs || inputs.length < 3) { throw new Error("layerNorm requires at least 3 inputs."); } const input = inputs[0]; const skip = inputs[1]; const gamma = inputs[2]; if (input.dataType !== skip.dataType || input.dataType !== gamma.dataType) { throw new Error("All inputs must have the same data type"); } if (input.dims.length !== 3 && input.dims.length !== 2) { throw new Error("Input must be 2D or 3D"); } if (skip.dims.length !== 3 && skip.dims.length !== 2) { throw new Error("Skip must be 2D or 3D"); } const hiddenSize = input.dims[input.dims.length - 1]; const sequenceLength = input.dims[input.dims.length - 2]; if (skip.dims[skip.dims.length - 1] !== hiddenSize) { throw new Error("Skip must have the same hidden size as input"); } if (skip.dims[skip.dims.length - 2] !== sequenceLength) { throw new Error("Skip must have the same sequence length as input"); } if (gamma.dims.length !== 1) { throw new Error("Gamma must be 1D"); } if (gamma.dims[gamma.dims.length - 1] !== hiddenSize) { throw new Error("Gamma must have the same hidden size as input"); } if (inputs.length > 3) { const beta = inputs[3]; if (beta.dims.length !== 1) { throw new Error("Beta must be 1D"); } if (beta.dims[beta.dims.length - 1] !== hiddenSize) { throw new Error("Beta must have the same hidden size as input"); } } if (inputs.length > 4) { const bias = inputs[4]; if (bias.dims.length !== 1) { throw new Error("Bias must be 1D"); } if (bias.dims[bias.dims.length - 1] !== hiddenSize) { throw new Error("Bias must have the same hidden size as input"); } } }; createSkipLayerNormProgramInfo = (inputs, attributes, outputCount, isTraining) => { const simplified = attributes.simplified; const inputShape = inputs[0].dims; const inputSize = ShapeUtil2.size(inputShape); const outputShape = inputShape; const outputSize = inputSize; const hiddenSize = inputShape.slice(-1)[0]; const meanInvStdDevDim = isTraining ? inputShape.slice(0, -1).concat(1) : []; const hasBetaInput = !simplified && inputs.length > 3; const hasBiasInput = inputs.length > 4; const hasMeanOutput = isTraining && outputCount > 1; const hasInvStdDevOutput = isTraining && outputCount > 2; const hasInputSkipBiasSumOutput = outputCount > 3; const workgroupSize = 64; const components = getMaxComponents(hiddenSize); const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: components }, { type: 12 /* uint32 */, data: hiddenSize }, { type: 1 /* float */, data: attributes.epsilon } ]; const getShaderSource = (shaderHelper) => { const uniformsArray = [ { name: "output_size", type: "u32" }, { name: "components", type: "u32" }, { name: "hidden_size", type: "u32" }, { name: "epsilon", type: "f32" } ]; const variables = [ inputVariable("x", inputs[0].dataType, inputs[0].dims, components), inputVariable("skip", inputs[1].dataType, inputs[1].dims, components), inputVariable("gamma", inputs[2].dataType, inputs[2].dims, components) ]; if (hasBetaInput) { variables.push(inputVariable("beta", inputs[3].dataType, inputs[3].dims, components)); } if (hasBiasInput) { variables.push(inputVariable("bias", inputs[4].dataType, inputs[4].dims, components)); } variables.push(outputVariable("output", inputs[0].dataType, outputShape, components)); if (hasMeanOutput) { variables.push(outputVariable("mean_output", 1 /* float */, meanInvStdDevDim)); } if (hasInvStdDevOutput) { variables.push(outputVariable("inv_std_output", 1 /* float */, meanInvStdDevDim)); } if (hasInputSkipBiasSumOutput) { variables.push(outputVariable("input_skip_bias_sum", inputs[0].dataType, outputShape, components)); } const dataType = tensorTypeToWsglStorageType(inputs[0].dataType); const vecDataType = tensorTypeToWsglStorageType(1 /* float */, components); return ` ${shaderHelper.registerUniforms(uniformsArray).declareVariables(...variables)} var sum_shared : array<${vecDataType}, ${workgroupSize}>; var sum_squared_shared : array<${vecDataType}, ${workgroupSize}>; ${shaderHelper.mainStart([workgroupSize, 1, 1])} let ix = local_id.x; let iy = global_id.x / ${workgroupSize}; let hidden_size_vectorized: u32 = uniforms.hidden_size / uniforms.components; var stride = hidden_size_vectorized / ${workgroupSize}; let offset = ix * stride + iy * hidden_size_vectorized; let offset1d = stride * ix; if (ix == ${workgroupSize - 1}) { stride = hidden_size_vectorized - stride * ix; } for (var i: u32 = 0; i < stride; i++) { let skip_value = skip[offset + i]; let bias_value = ${hasBiasInput ? "bias[offset1d + i]" : dataType + "(0.0)"}; let input_value = x[offset + i]; let value = input_value + skip_value + bias_value; ${hasInputSkipBiasSumOutput ? "input_skip_bias_sum[offset + i] = value;" : ""} output[offset + i] = value; let f32_value = ${castToF32(dataType, components, "value")}; sum_shared[ix] += f32_value; sum_squared_shared[ix] += f32_value * f32_value; } workgroupBarrier(); var reduce_size : u32 = ${workgroupSize}; for (var curr_size = reduce_size >> 1; curr_size > 0; curr_size = reduce_size >> 1) { reduce_size = curr_size + (reduce_size & 1); if (ix < curr_size) { sum_shared[ix] += sum_shared[ix + reduce_size]; sum_squared_shared[ix] += sum_squared_shared[ix + reduce_size]; } workgroupBarrier(); } let sum = sum_shared[0]; let square_sum = sum_squared_shared[0]; let mean = ${sumVector("sum", components)} / f32(uniforms.hidden_size); let inv_std_dev = inverseSqrt(${sumVector("square_sum", components)} / f32(uniforms.hidden_size) ${simplified ? "" : "- mean * mean"} + uniforms.epsilon); ${hasMeanOutput ? "mean_output[global_idx] = mean;" : ""} ${hasInvStdDevOutput ? "inv_std_output[global_idx] = inv_std_dev;" : ""} for (var i: u32 = 0; i < stride; i++) { output[offset + i] = (output[offset + i] ${simplified ? "" : `- ${dataType}(mean)`}) * ${dataType}(inv_std_dev) * gamma[offset1d + i] ${hasBetaInput ? "+ beta[offset1d + i]" : ""}; } }`; }; const outputs = [{ dims: outputShape, dataType: inputs[0].dataType }]; if (outputCount > 1) { outputs.push({ dims: meanInvStdDevDim, dataType: 1 /* float */ }); } if (outputCount > 2) { outputs.push({ dims: meanInvStdDevDim, dataType: 1 /* float */ }); } if (outputCount > 3) { outputs.push({ dims: inputShape, dataType: inputs[0].dataType }); } return { name: "SkipLayerNormalization", shaderCache: { hint: `${components};${hasMeanOutput};${hasInvStdDevOutput};${hasInputSkipBiasSumOutput}`, inputDependencies: inputs.map((_input, _index) => "type") }, getShaderSource, getRunData: () => ({ outputs, dispatchGroup: { x: Math.ceil(outputSize / hiddenSize) }, programUniforms }) }; }; skipLayerNorm = (context, attributes) => { const isTraining = false; validateInputs53(context.inputs); const outputs = [0]; if (context.outputCount > 1) { outputs.push(isTraining ? 1 : -3); } if (context.outputCount > 2) { outputs.push(isTraining ? 2 : -3); } if (context.outputCount > 3) { outputs.push(3); } context.compute(createSkipLayerNormProgramInfo(context.inputs, attributes, context.outputCount, isTraining), { outputs }); }; } }); // web/lib/wasm/jsep/webgpu/ops/slice.ts var validateInputs54, readInput, createSliceAttributesFromInputs, fixStartEndValues, calculateInputIndicesImpl, createSliceProgramInfo2, slice2, parseSliceAttributes2; var init_slice2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/slice.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_common(); validateInputs54 = (inputs, attributes) => { if (!inputs || inputs.length < 1) { throw new Error("too few inputs"); } if (attributes.axes.length !== 0) { if (attributes.axes.length !== attributes.starts.length || attributes.axes.length !== attributes.ends.length) { throw new Error("axes, starts and ends must have the same length"); } } else if (attributes.starts.length !== attributes.ends.length) { throw new Error("starts and ends must have the same length"); } inputs.slice(1).forEach((_, idx) => { if (inputs[idx + 1].dataType !== 6 /* int32 */ && inputs[idx + 1].dataType !== 7 /* int64 */) { throw new Error(`Input ${idx} must be an array of int32 or int64`); } }); }; readInput = (inputs, idx) => { const input = []; if (inputs.length > idx) { if (inputs[idx].dataType === 7 /* int64 */) { inputs[idx].getBigInt64Array().forEach((v) => input.push(Number(v))); } else if (inputs[idx].dataType === 6 /* int32 */) { inputs[idx].getInt32Array().forEach((v) => input.push(Number(v))); } else { throw new Error(`Input ${idx} must be an array of int32 or int64`); } } return input; }; createSliceAttributesFromInputs = (inputs, attributes) => { if (inputs.length > 1) { const starts = readInput(inputs, 1); const ends = readInput(inputs, 2); let axes = readInput(inputs, 3); if (axes.length === 0) { axes = [...Array(inputs[0].dims.length).keys()]; } return createAttributeWithCacheKey2({ starts, ends, axes }); } else { return attributes; } }; fixStartEndValues = (value, index, inputShape, axes, steps) => { let newValue = value; if (value < 0) { newValue += inputShape[axes[index]]; } if (steps[index] < 0) { return Math.max(0, Math.min(newValue, inputShape[axes[index]] - 1)); } else { return Math.max(0, Math.min(newValue, inputShape[axes[index]])); } }; calculateInputIndicesImpl = (input, output, inputShape) => `fn calculateInputIndices(output_indices: ${output.type.indices}) -> ${input.type.indices} { var input_indices: ${input.type.indices}; var carry = 0u; for (var i = ${inputShape.length - 1}; i >= 0; i--) { let input_shape_i = ${getElementAt("uniforms.input_shape", "i", inputShape.length)}; let steps_i = ${getElementAt("uniforms.steps", "i", inputShape.length)}; let signs_i = ${getElementAt("uniforms.signs", "i", inputShape.length)}; let starts_i = ${getElementAt("uniforms.starts", "i", inputShape.length)}; var output_index = ${output.indicesGet("output_indices", "i")}; var input_index = output_index * steps_i + starts_i + carry; carry = input_index / input_shape_i; input_index = input_index % input_shape_i; if (signs_i < 0) { input_index = input_shape_i - input_index - 1u + starts_i; } ${input.indicesSet("input_indices", "i", "input_index")}; } return input_indices; }`; createSliceProgramInfo2 = (inputs, attributes) => { const inputShape = inputs[0].dims; const inputSize = ShapeUtil2.size(inputShape); const axes = attributes.axes.length > 0 ? ShapeUtil2.normalizeAxes(attributes.axes, inputShape.length) : [...Array(inputShape.length).keys()]; let steps = readInput(inputs, 4); steps.forEach( (step) => step !== 0 || (() => { throw new Error("step cannot be 0"); }) ); if (steps.length === 0) { steps = Array(axes.length).fill(1); } const starts = attributes.starts.map((start, i) => fixStartEndValues(start, i, inputShape, axes, steps)); const ends = attributes.ends.map((end, i) => fixStartEndValues(end, i, inputShape, axes, steps)); if (axes.length !== starts.length || axes.length !== ends.length) { throw new Error("start, ends and axes should have the same number of elements"); } if (axes.length !== inputShape.length) { for (let i = 0; i < inputShape.length; ++i) { if (!axes.includes(i)) { starts.splice(i, 0, 0); ends.splice(i, 0, inputShape[i]); steps.splice(i, 0, 1); } } } const signs = steps.map((step) => Math.sign(step)); steps.forEach((step, i, array) => { if (step < 0) { const numSteps = (ends[i] - starts[i]) / step; const newEnd = starts[i]; const newStart = newEnd + numSteps * steps[i]; starts[i] = newStart; ends[i] = newEnd; array[i] = -step; } }); const outputShape = inputShape.slice(0); axes.forEach((axis, _) => { outputShape[axis] = Math.ceil((ends[axis] - starts[axis]) / steps[axis]); }); const outputTensorInfo = { dims: outputShape, dataType: inputs[0].dataType }; const output = outputVariable("output", inputs[0].dataType, outputShape.length); const input = inputVariable("input", inputs[0].dataType, inputs[0].dims.length); const outputSize = ShapeUtil2.size(outputShape); const uniforms = [ { name: "outputSize", type: "u32" }, { name: "starts", type: "u32", length: starts.length }, { name: "signs", type: "i32", length: signs.length }, { name: "steps", type: "u32", length: steps.length } ]; const programUniforms = [ { type: 12 /* uint32 */, data: outputSize }, { type: 12 /* uint32 */, data: starts }, { type: 6 /* int32 */, data: signs }, { type: 12 /* uint32 */, data: steps }, ...createTensorShapeVariables(inputs[0].dims, outputShape) ]; const getShaderSource = (shaderHelper) => ` ${shaderHelper.registerUniforms(uniforms).declareVariables(input, output)} ${calculateInputIndicesImpl(input, output, inputShape)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} let output_indices = ${output.offsetToIndices("global_idx")}; let input_indices = calculateInputIndices(output_indices); ${output.setByOffset("global_idx", input.getByIndices("input_indices"))} }`; return { name: "Slice", shaderCache: { hint: `${signs.length}_${starts.length}_${steps.length}`, inputDependencies: ["rank"] }, getShaderSource, getRunData: () => ({ outputs: [outputTensorInfo], dispatchGroup: { x: Math.ceil( inputSize / 64 /* workgroup size */ ) }, programUniforms }) }; }; slice2 = (context, attributes) => { validateInputs54(context.inputs, attributes); const updatedAttributes = createSliceAttributesFromInputs(context.inputs, attributes); context.compute(createSliceProgramInfo2(context.inputs, updatedAttributes), { inputs: [0] }); }; parseSliceAttributes2 = (attributes) => { const starts = attributes.starts; const ends = attributes.ends; const axes = attributes.axes; return createAttributeWithCacheKey2({ starts, ends, axes }); }; } }); // web/lib/wasm/jsep/webgpu/ops/softmax.ts var validateInputs55, createSoftmaxProgramInfo, softmax2, parseSoftmaxAttributes2; var init_softmax2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/softmax.ts"() { "use strict"; init_wasm_common(); init_util2(); init_attribute_with_cache_key2(); init_transpose2(); init_common(); validateInputs55 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("Softmax op requires 1 input."); } }; createSoftmaxProgramInfo = (context, attributes) => { const input = context.inputs[0]; const inputShape = input.dims; const outputSize = ShapeUtil2.size(inputShape); const inputRank = inputShape.length; const axis = ShapeUtil2.normalizeAxis(attributes.axis, inputRank); const isTransposeRequired = axis < inputShape.length - 1; let transposedInput; let perm = []; if (isTransposeRequired) { perm = Array.from({ length: inputRank }, (_, i) => i); perm[axis] = inputRank - 1; perm[inputRank - 1] = axis; transposedInput = context.compute(createTransposeProgramInfo2(input, perm), { inputs: [input], outputs: [-1] })[0]; } else { transposedInput = input; } const transposedInputShape = transposedInput.dims; const cols = transposedInputShape[inputRank - 1]; const rows = outputSize / cols; const components = getMaxComponents(cols); const packedCols = cols / components; let WG = 64; if (rows === 1) { WG = 256; } const maxVector = (name2, components2) => { if (components2 === 4) { return `max(max(${name2}.x, ${name2}.y), max(${name2}.z, ${name2}.w))`; } else if (components2 === 2) { return `max(${name2}.x, ${name2}.y)`; } else if (components2 === 3) { return `max(max(${name2}.x, ${name2}.y), ${name2}.z)`; } return name2; }; const x = inputVariable("x", transposedInput.dataType, transposedInput.dims, components); const output = outputVariable("result", transposedInput.dataType, transposedInput.dims, components); const valueType = x.type.value; const threadMaxDecl = tensorTypeToWsglStorageType(transposedInput.dataType) === "f32" ? `var threadMax = ${valueType}(-3.4028234663852886e+38f);` : `var threadMax = ${valueType}(-65504.0h);`; const getShaderSource = (shaderHelper) => ` var rowMaxShared : ${valueType}; var rowSumShared : ${valueType}; var threadShared : array<${valueType}, ${WG}>; fn getValue(row: i32, col: i32, row_stride: i32) -> ${valueType} { let index = row * row_stride + col; return x[index]; } fn setValue(row: i32, col: i32, row_stride: i32, value: ${valueType}) { let index = row * row_stride + col; result[index] = value; } ${shaderHelper.registerUniform("packedCols", "i32").declareVariables(x, output)} ${shaderHelper.mainStart(WG)} let gindex = i32(global_idx); let lindex = i32(local_idx); const wg = ${WG}; let row = gindex / wg; let cols = uniforms.packedCols; let row_stride : i32 = uniforms.packedCols; // find the rows max ${threadMaxDecl} for (var col = lindex; col < cols; col += wg) { let value = getValue(row, col, row_stride); threadMax = max(threadMax, value); } if (lindex < cols) { threadShared[lindex] = threadMax; } workgroupBarrier(); var reduceSize = min(cols, wg); for (var currSize = reduceSize >> 1; currSize > 0; currSize = reduceSize >> 1) { reduceSize = currSize + (reduceSize & 1); if (lindex < currSize) { threadShared[lindex] = max(threadShared[lindex], threadShared[lindex + reduceSize]); } workgroupBarrier(); } if (lindex == 0) { rowMaxShared = ${valueType}(${maxVector("threadShared[0]", components)}); } workgroupBarrier(); // find the rows sum var threadSum = ${valueType}(0.0); for (var col = lindex; col < cols; col += wg) { let subExp = exp(getValue(row, col, row_stride) - rowMaxShared); threadSum += subExp; } threadShared[lindex] = threadSum; workgroupBarrier(); for (var currSize = wg >> 1; currSize > 0; currSize = currSize >> 1) { if (lindex < currSize) { threadShared[lindex] = threadShared[lindex] + threadShared[lindex + currSize]; } workgroupBarrier(); } if (lindex == 0) { rowSumShared = ${valueType}(${sumVector("threadShared[0]", components)}); } workgroupBarrier(); // calculate final value for each element in the row for (var col = lindex; col < cols; col += wg) { var value = exp(getValue(row, col, row_stride) - rowMaxShared) / rowSumShared; // max operation protects against NaN since all values should be >=0 value = max(value, ${valueType}(0.0)); setValue(row, col, row_stride, value); } }`; const result = context.compute( { name: "Softmax", // Note that in JSEP, WG size is not included in cache by default, but WebGPU EP it is. shaderCache: { hint: `${components};${WG}`, inputDependencies: ["type"] }, getRunData: () => ({ outputs: [{ dims: transposedInputShape, dataType: transposedInput.dataType }], dispatchGroup: { x: rows }, programUniforms: [{ type: 6 /* int32 */, data: packedCols }] }), getShaderSource }, { inputs: [transposedInput], outputs: [isTransposeRequired ? -1 : 0] } )[0]; if (isTransposeRequired) { context.compute(createTransposeProgramInfo2(result, perm), { inputs: [result] }); } }; softmax2 = (context, attributes) => { validateInputs55(context.inputs); createSoftmaxProgramInfo(context, attributes); }; parseSoftmaxAttributes2 = (attributes) => createAttributeWithCacheKey2({ axis: attributes.axis }); } }); // web/lib/wasm/jsep/webgpu/ops/tile.ts var getRepeats, validateInputs56, getOutputShape3, createTileProgramInfo2, tile2; var init_tile2 = __esm({ "web/lib/wasm/jsep/webgpu/ops/tile.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); getRepeats = (repeatsTensorView) => Array.from(repeatsTensorView.getBigInt64Array(), Number); validateInputs56 = (inputs) => { if (!inputs || inputs.length !== 2) { throw new Error("Tile requires 2 inputs."); } if (inputs[0].dataType !== 1 /* float */ && inputs[0].dataType !== 10 /* float16 */ && inputs[0].dataType !== 6 /* int32 */ && inputs[0].dataType !== 12 /* uint32 */) { throw new Error("Tile only support float, float16, int32, and uint32 data types"); } if (inputs[1].dataType !== 7 /* int64 */) { throw new Error("Tile `repeats` input should be of int64 data type"); } if (inputs[1].dims.length !== 1) { throw new Error("Tile `repeats` input should be 1-D"); } const repeats = getRepeats(inputs[1]); if (repeats.length !== inputs[0].dims.length) { throw new Error("Tile `repeats` input should have same number of elements as rank of input data tensor"); } }; getOutputShape3 = (inputShape, repeats) => { const outputShape = []; for (let i = 0; i < inputShape.length; ++i) { outputShape.push(inputShape[i] * repeats[i]); } return outputShape; }; createTileProgramInfo2 = (inputs, shape2) => { const inputShape = inputs[0].dims; const repeats = shape2 == null ? getRepeats(inputs[1]) : shape2; const outputShape = getOutputShape3(inputShape, repeats); const outputSize = ShapeUtil2.size(outputShape); const dataType = inputs[0].dataType; const input = inputVariable("input", dataType, inputShape.length); const output = outputVariable("output", dataType, outputShape.length); const getShaderSource = (shaderHelper) => ` const inputShape = ${input.indices(...inputShape)}; ${shaderHelper.registerUniform("output_size", "u32").declareVariables(input, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} let output_indices = ${output.offsetToIndices("global_idx")}; var input_indices: ${input.type.indices}; for (var i = 0; i < ${inputShape.length}; i++) { let input_dim_i = ${input.indicesGet("uniforms.input_shape", "i")}; let input_dim_value = ${output.indicesGet("output_indices", "i")} % input_dim_i; ${input.indicesSet("input_indices", "i", "input_dim_value")} } ${output.setByOffset("global_idx", input.getByIndices("input_indices"))} }`; return { name: "Tile", shaderCache: { hint: `${repeats}`, inputDependencies: ["rank"] }, getRunData: () => ({ outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 /* workgroup size */ ) }, programUniforms: [ { type: 12 /* uint32 */, data: outputSize }, ...createTensorShapeVariables(inputs[0].dims, outputShape) ] }), getShaderSource }; }; tile2 = (context) => { validateInputs56(context.inputs); context.compute(createTileProgramInfo2(context.inputs), { inputs: [0] }); }; } }); // web/lib/wasm/jsep/webgpu/ops/where.ts var createWhereOpProgramShader, createWhereOpProgramInfo, where; var init_where = __esm({ "web/lib/wasm/jsep/webgpu/ops/where.ts"() { "use strict"; init_wasm_common(); init_util2(); init_common(); createWhereOpProgramShader = (shaderHelper, inputs, dimsOutput, isBroadcast, typeOutput) => { const output = outputVariable("output_data", typeOutput, dimsOutput.length, 4); const a = inputVariable("a_data", inputs[1].dataType, inputs[1].dims.length, 4); const b = inputVariable("b_data", inputs[2].dataType, inputs[2].dims.length, 4); const c = inputVariable("c_data", inputs[0].dataType, inputs[0].dims.length, 4); let assignment; const expression = (a2, b2, c2) => `select(${b2}, ${a2}, ${c2})`; if (!isBroadcast) { assignment = output.setByOffset( "global_idx", expression(a.getByOffset("global_idx"), b.getByOffset("global_idx"), c.getByOffset("global_idx")) ); } else { const singleAssignment = (resStr, x, typeCast = "") => { const expressionA = `a_data[index_a${x}][component_a${x}]`; const expressionB = `b_data[index_b${x}][component_b${x}]`; const expressionC = `bool(c_data[index_c${x}] & (0xffu << (component_c${x} * 8)))`; return ` let output_indices${x} = ${output.offsetToIndices(`global_idx * 4u + ${x}u`)}; let offset_a${x} = ${a.broadcastedIndicesToOffset(`output_indices${x}`, output)}; let offset_b${x} = ${b.broadcastedIndicesToOffset(`output_indices${x}`, output)}; let offset_c${x} = ${c.broadcastedIndicesToOffset(`output_indices${x}`, output)}; let index_a${x} = offset_a${x} / 4u; let index_b${x} = offset_b${x} / 4u; let index_c${x} = offset_c${x} / 4u; let component_a${x} = offset_a${x} % 4u; let component_b${x} = offset_b${x} % 4u; let component_c${x} = offset_c${x} % 4u; ${resStr}[${x}] = ${typeCast}(${expression(expressionA, expressionB, expressionC)}); `; }; if (typeOutput === 9 /* bool */) { assignment = ` var data = vec4(0); ${singleAssignment("data", 0, "u32")} ${singleAssignment("data", 1, "u32")} ${singleAssignment("data", 2, "u32")} ${singleAssignment("data", 3, "u32")} output_data[global_idx] = dot(vec4(0x1, 0x100, 0x10000, 0x1000000), vec4(data));`; } else { assignment = ` ${singleAssignment("output_data[global_idx]", 0)} ${singleAssignment("output_data[global_idx]", 1)} ${singleAssignment("output_data[global_idx]", 2)} ${singleAssignment("output_data[global_idx]", 3)} `; } } return ` ${shaderHelper.registerUniform("vec_size", "u32").declareVariables(c, a, b, output)} ${shaderHelper.mainStart()} ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.vec_size")} ${assignment} }`; }; createWhereOpProgramInfo = (inputs) => { const dimsA = inputs[1].dims; const dimsB = inputs[2].dims; const dimsC = inputs[0].dims; const outputDataType = inputs[1].dataType; const isBroadcast = !(ShapeUtil2.areEqual(dimsA, dimsB) && ShapeUtil2.areEqual(dimsB, dimsC)); let outputShape = dimsA; let outputSize = ShapeUtil2.size(dimsA); if (isBroadcast) { const calculatedShape = BroadcastUtil2.calcShape(BroadcastUtil2.calcShape(dimsA, dimsB, false), dimsC, false); if (!calculatedShape) { throw new Error("Can't perform where op on the given tensors"); } outputShape = calculatedShape; outputSize = ShapeUtil2.size(outputShape); } const vecSize = Math.ceil(outputSize / 4); return { name: "Where", shaderCache: { inputDependencies: ["rank", "rank", "rank"] }, getShaderSource: (shaderHelper) => createWhereOpProgramShader(shaderHelper, inputs, outputShape, isBroadcast, outputDataType), getRunData: () => ({ outputs: [{ dims: outputShape, dataType: outputDataType }], dispatchGroup: { x: Math.ceil( outputSize / 64 / 4 /* vec size */ ) }, programUniforms: [ { type: 12 /* uint32 */, data: vecSize }, ...createTensorShapeVariables(dimsC, dimsA, dimsB, outputShape) ] }) }; }; where = (context) => { context.compute(createWhereOpProgramInfo(context.inputs)); }; } }); // web/lib/wasm/jsep/webgpu/op-resolve-rules.ts var WEBGPU_OP_RESOLVE_RULES; var init_op_resolve_rules2 = __esm({ "web/lib/wasm/jsep/webgpu/op-resolve-rules.ts"() { "use strict"; init_argminmax(); init_attention(); init_batch_norm(); init_bias_add(); init_bias_split_gelu(); init_binary_op2(); init_concat2(); init_conv2(); init_conv_transpose2(); init_cumsum(); init_depth_to_space2(); init_einsum(); init_expand(); init_fast_gelu(); init_gather2(); init_gather_nd(); init_gather_block_quantized(); init_gather_elements(); init_gemm2(); init_grid_sample(); init_group_query_attention(); init_instance_norm(); init_layer_norm(); init_matmul2(); init_matmulnbits(); init_multihead_attention(); init_pad2(); init_pool2(); init_quantize_linear(); init_range(); init_scatter_nd(); init_reduce2(); init_resize(); init_rotary_embedding(); init_skip_layer_norm(); init_slice2(); init_softmax2(); init_split2(); init_tile2(); init_transpose2(); init_unary_op2(); init_where(); WEBGPU_OP_RESOLVE_RULES = /* @__PURE__ */ new Map([ ["Abs", [abs2]], ["Acos", [acos2]], ["Acosh", [acosh]], ["Add", [add3]], ["ArgMax", [argMax, parseArgMinMaxAttributes]], ["ArgMin", [argMin, parseArgMinMaxAttributes]], ["Asin", [asin2]], ["Asinh", [asinh]], ["Atan", [atan2]], ["Atanh", [atanh]], ["Attention", [attention]], // TODO: support new attributes for AveragePool-10 ["AveragePool", [averagePool2, parseAveragePoolAttributes2]], ["BatchNormalization", [batchNorm]], ["BiasAdd", [biasAdd]], ["BiasSplitGelu", [biasSplitGelu]], ["Cast", [cast2, parseCastAttributes2]], ["Ceil", [ceil2]], ["Clip", [clip2]], ["Concat", [concat2, parseConcatAttributes2]], ["Conv", [conv2, parseConvAttributes2]], ["ConvTranspose", [convTranspose2, parseConvTransposeAttributes2]], ["Cos", [cos2]], ["Cosh", [cosh]], ["CumSum", [cumsum, parseCumSumAttributes]], ["DepthToSpace", [depthToSpace2, parseDepthToSpaceAttributes2]], ["DequantizeLinear", [dequantizeLinear, parseDequantizeLinearAttributes]], ["Div", [div2]], ["Einsum", [einsum, parseEinsumAttributes]], ["Elu", [elu2, parseAlphaAttributes]], ["Equal", [equal2]], ["Erf", [erf]], ["Exp", [exp2]], ["Expand", [expand]], ["FastGelu", [fastGelu2]], ["Floor", [floor2]], ["FusedConv", [conv2, parseConvAttributes2]], ["Gather", [gather2, parseGatherAttributes2]], ["GatherElements", [gatherElements, parseGatherElementsAttributes]], ["GatherBlockQuantized", [gatherBlockQuantized, parseGatherBlockQuantizedAttributes]], ["GatherND", [gatherND, parseGatherNDAttributes]], ["Gelu", [gelu]], ["Gemm", [gemm2, parseGemmAttributes2]], ["GlobalAveragePool", [globalAveragePool2, parseGlobalAveragePoolAttributes2]], ["GlobalMaxPool", [globalMaxPool2, parseGlobalMaxPoolAttributes]], ["Greater", [greater2]], ["GreaterOrEqual", [greaterOrEqual]], ["GridSample", [gridSample, parseGridSampleAttributes]], ["GroupQueryAttention", [groupQueryAttention]], ["HardSigmoid", [hardSigmoid, parseHardSigmoidAttributes]], ["InstanceNormalization", [instanceNorm]], ["LayerNormalization", [layerNorm]], ["LeakyRelu", [leakyRelu2, parseAlphaAttributes]], ["Less", [less2]], ["LessOrEqual", [lessOrEqual]], ["Log", [log3]], ["MatMul", [matMul2]], ["MatMulNBits", [matMulNBits, parseMatMulNBitsAttributes]], // TODO: support new attributes for MaxPool-8 and MaxPool-10 ["MaxPool", [maxPool2, parseMaxPoolAttributes2]], ["Mul", [mul2]], ["MultiHeadAttention", [multiHeadAttention, parseMultiHeadAttentionAttributes]], ["Neg", [neg2]], ["Not", [not3]], ["Pad", [pad]], ["Pow", [pow2]], ["QuickGelu", [quickgelu, parseAlphaAttributes]], ["Range", [range]], ["Reciprocal", [reciprocal]], ["ReduceMin", [reduceMin2]], ["ReduceMean", [reduceMean2]], ["ReduceMax", [reduceMax2]], ["ReduceSum", [reduceSum2]], ["ReduceProd", [reduceProd2]], ["ReduceL1", [reduceL1]], ["ReduceL2", [reduceL2]], ["ReduceLogSum", [reduceLogSum2]], ["ReduceLogSumExp", [reduceLogSumExp]], ["ReduceSumSquare", [reduceSumSquare]], ["Relu", [relu2]], ["Resize", [resize2, parseResizeAttributes]], ["RotaryEmbedding", [rotaryEmbedding]], ["ScatterND", [scatterND, parseScatterNDAttributes]], ["Sigmoid", [sigmoid2]], ["Sin", [sin2]], ["Sinh", [sinh]], ["Slice", [slice2, parseSliceAttributes2]], ["SkipLayerNormalization", [skipLayerNorm]], ["Split", [split2, parseSplitAttributes2]], ["Sqrt", [sqrt2]], ["Softmax", [softmax2, parseSoftmaxAttributes2]], ["Sub", [sub2]], ["Tan", [tan2]], ["Tanh", [tanh2]], ["ThresholdedRelu", [thresholdedRelu, parseAlphaAttributes]], ["Tile", [tile2]], ["Transpose", [transpose2, parseTransposeAttributes2]], ["Where", [where]] ]); } }); // web/lib/wasm/jsep/webgpu/program-manager.ts var ProgramManager2; var init_program_manager2 = __esm({ "web/lib/wasm/jsep/webgpu/program-manager.ts"() { "use strict"; init_esm(); init_log(); init_common(); ProgramManager2 = class { constructor(backend2) { this.backend = backend2; 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, outputs, dispatchGroup, uniformBufferBinding) { TRACE_FUNC_BEGIN(buildArtifact.programInfo.name); const device = this.backend.device; const computePassEncoder = this.backend.getComputePassEncoder(); this.backend.writeTimestamp(this.backend.pendingDispatchNumber * 2); const entries = []; for (const input of inputs) { entries.push({ binding: entries.length, resource: { buffer: input.buffer } }); } for (const output of outputs) { entries.push({ binding: entries.length, resource: { buffer: output.buffer } }); } if (uniformBufferBinding) { entries.push({ binding: entries.length, resource: uniformBufferBinding }); } const bindGroup = device.createBindGroup({ layout: buildArtifact.computePipeline.getBindGroupLayout(0), entries, label: buildArtifact.programInfo.name }); if (this.backend.sessionStatus === "capturing") { const commandInfo = { kernelId: this.backend.currentKernelId, computePipeline: buildArtifact.computePipeline, bindGroup, dispatchGroup }; const sessionCommandList = this.backend.capturedCommandList.get(this.backend.currentSessionId); sessionCommandList.push(commandInfo); } computePassEncoder.setPipeline(buildArtifact.computePipeline); computePassEncoder.setBindGroup(0, bindGroup); computePassEncoder.dispatchWorkgroups(...dispatchGroup); this.backend.writeTimestamp(this.backend.pendingDispatchNumber * 2 + 1); this.backend.pendingDispatchNumber++; if (this.backend.pendingDispatchNumber >= this.backend.maxDispatchNumber || this.backend.queryType === "at-passes") { this.backend.endComputePass(); } if (this.backend.pendingDispatchNumber >= this.backend.maxDispatchNumber) { this.backend.flush(); } TRACE_FUNC_END(buildArtifact.programInfo.name); } dispose() { } build(programInfo, normalizedDispatchGroupSize) { TRACE_FUNC_BEGIN(programInfo.name); const device = this.backend.device; const enableDirectives = []; const extensionsInfo = [ { feature: "shader-f16", extension: "f16" }, { feature: "subgroups", extension: "subgroups" } ]; extensionsInfo.forEach((info) => { if (device.features.has(info.feature)) { enableDirectives.push(`enable ${info.extension};`); } }); const shaderHelper = createShaderHelper(normalizedDispatchGroupSize, this.backend.device.limits); const userCode = programInfo.getShaderSource(shaderHelper); const code = `${enableDirectives.join("\n")} ${shaderHelper.additionalImplementations} ${userCode}`; const shaderModule = device.createShaderModule({ code, label: programInfo.name }); LOG_DEBUG("verbose", () => `[WebGPU] ${programInfo.name} shader code: ${code}`); const computePipeline = device.createComputePipeline({ compute: { module: shaderModule, entryPoint: "main" }, layout: "auto", label: programInfo.name }); TRACE_FUNC_END(programInfo.name); return { programInfo, computePipeline, uniformVariablesInfo: shaderHelper.variablesInfo }; } normalizeDispatchGroupSize(dispatchGroup) { const x = typeof dispatchGroup === "number" ? dispatchGroup : dispatchGroup.x; const y = typeof dispatchGroup === "number" ? 1 : dispatchGroup.y || 1; const z = typeof dispatchGroup === "number" ? 1 : dispatchGroup.z || 1; const limitPerDimension = this.backend.device.limits.maxComputeWorkgroupsPerDimension; if (x <= limitPerDimension && y <= limitPerDimension && z <= limitPerDimension) { return [x, y, z]; } const size = x * y * z; let dispatchAverage = Math.ceil(Math.sqrt(size)); if (dispatchAverage > limitPerDimension) { dispatchAverage = Math.ceil(Math.cbrt(size)); if (dispatchAverage > limitPerDimension) { throw new Error("Total dispatch size exceeds WebGPU maximum."); } return [dispatchAverage, dispatchAverage, dispatchAverage]; } else { return [dispatchAverage, dispatchAverage, 1]; } } }; } }); // web/lib/wasm/jsep/backend-webgpu.ts var backend_webgpu_exports = {}; __export(backend_webgpu_exports, { WebGpuBackend: () => WebGpuBackend }); var getProgramInputTensorInfoDependencyKey, getProgramInfoUniqueKey2, AdapterInfoImpl, WebGpuBackend; var init_backend_webgpu = __esm({ "web/lib/wasm/jsep/backend-webgpu.ts"() { "use strict"; init_esm(); init_wasm_common(); init_log(); init_tensor_view(); init_gpu_data_manager(); init_op_resolve_rules2(); init_program_manager2(); getProgramInputTensorInfoDependencyKey = (inputTensors, inputDependencies) => { if (inputDependencies.length !== inputTensors.length) { throw new Error( `inputDependencies length ${inputDependencies.length} is not equal to inputTensors length ${inputTensors.length}.` ); } const inputInfos = []; for (let i = 0; i < inputTensors.length; ++i) { const type = inputTensors[i].dataType; switch (inputDependencies[i]) { case "none": { inputInfos.push(""); break; } case "type": { inputInfos.push(`${type}`); break; } case "rank": { const rank = inputTensors[i].dims.length; inputInfos.push(`${type};${rank}`); break; } case "dims": { const dims = inputTensors[i].dims.join(","); inputInfos.push(`${type};${dims}`); break; } default: throw new Error(`unsupported input dependency: ${inputDependencies[i]}`); } } return inputInfos.join("|"); }; getProgramInfoUniqueKey2 = (programInfo, inputTensors, is1DimensionDispatch) => { let key = programInfo.name; if (programInfo.shaderCache?.hint) { key += "[" + programInfo.shaderCache.hint + "]"; } key += ":" + is1DimensionDispatch + `:${getProgramInputTensorInfoDependencyKey( inputTensors, programInfo.shaderCache?.inputDependencies ?? new Array(inputTensors.length).fill("dims") )}`; return key; }; AdapterInfoImpl = class { constructor(adapterInfo) { if (adapterInfo) { this.architecture = adapterInfo.architecture; this.vendor = adapterInfo.vendor; } } isArchitecture(architecture) { return this.architecture === architecture; } isVendor(vendor) { return this.vendor === vendor; } }; WebGpuBackend = class { constructor() { /** * representing the session ID of which is currently being run. * `null` means no session is being run. * only valid when session.run is executed. */ this.currentSessionId = null; /** * representing the kernel ID of which is currently being computed (CPU code perspective). * `null` means no kernel is being computed. * only one kernel can be computed at a moment. */ this.currentKernelId = null; this.commandEncoder = null; this.computePassEncoder = null; this.maxDispatchNumber = 16; this.pendingDispatchNumber = 0; // info of kernels pending submission for a single batch this.pendingKernels = []; // queryReadBuffer -> pendingKernels mapping for all the batches this.pendingQueries = /* @__PURE__ */ new Map(); this.sessionStatus = "default"; /** * a SessionID -> CommandInfo[] mapping. It's used to record all GPU commands for corresponding session. */ this.capturedCommandList = /* @__PURE__ */ new Map(); /** * a SessionID -> PendingKernelInfo[] mapping for profiling. */ this.capturedPendingKernels = /* @__PURE__ */ new Map(); /** * a SessionID -> a Map of (InputOutputIndex -> [ID, GPUBuffer]) mapping. */ this.sessionExternalDataMapping = /* @__PURE__ */ new Map(); } /** * get the custom data of the current kernel */ get currentKernelCustomData() { if (this.currentKernelId === null) { throw new Error("currentKernelCustomData(): currentKernelId is null. (should not happen)"); } let data = this.kernelCustomData.get(this.currentKernelId); if (!data) { data = {}; this.kernelCustomData.set(this.currentKernelId, data); } return data; } async initialize(env3, adapter) { this.env = env3; const requiredFeatures = []; const deviceDescriptor = { requiredLimits: { maxComputeWorkgroupStorageSize: adapter.limits.maxComputeWorkgroupStorageSize, maxComputeWorkgroupsPerDimension: adapter.limits.maxComputeWorkgroupsPerDimension, maxStorageBufferBindingSize: adapter.limits.maxStorageBufferBindingSize, maxBufferSize: adapter.limits.maxBufferSize, maxComputeInvocationsPerWorkgroup: adapter.limits.maxComputeInvocationsPerWorkgroup, maxComputeWorkgroupSizeX: adapter.limits.maxComputeWorkgroupSizeX, maxComputeWorkgroupSizeY: adapter.limits.maxComputeWorkgroupSizeY, maxComputeWorkgroupSizeZ: adapter.limits.maxComputeWorkgroupSizeZ }, requiredFeatures }; const requireFeatureIfAvailable = (feature) => adapter.features.has(feature) && requiredFeatures.push(feature) && true; if (!requireFeatureIfAvailable("chromium-experimental-timestamp-query-inside-passes")) { requireFeatureIfAvailable("timestamp-query"); } requireFeatureIfAvailable("shader-f16"); requireFeatureIfAvailable("subgroups"); this.device = await adapter.requestDevice(deviceDescriptor); this.adapterInfo = new AdapterInfoImpl(adapter.info || await adapter.requestAdapterInfo()); this.gpuDataManager = createGpuDataManager(this); this.programManager = new ProgramManager2(this); this.kernels = /* @__PURE__ */ new Map(); this.kernelPersistentData = /* @__PURE__ */ new Map(); this.kernelCustomData = /* @__PURE__ */ new Map(); configureLogger(env3.logLevel, !!env3.debug); this.device.onuncapturederror = (ev) => { if (ev.error instanceof GPUValidationError) { console.error(`An uncaught WebGPU validation error was raised: ${ev.error.message}`); } }; Object.defineProperty(this.env.webgpu, "device", { value: this.device, writable: false, enumerable: true, configurable: true // Allow deletion when device is destroyed }); Object.defineProperty(this.env.webgpu, "adapter", { value: adapter, writable: false, enumerable: true, configurable: false }); this.setQueryType(); } dispose() { if (typeof this.querySet !== "undefined") { this.querySet.destroy(); } this.gpuDataManager.dispose(); if (this.device && this.env?.webgpu) { void this.device.lost.then(() => { delete this.env.webgpu.device; }); } } getCommandEncoder() { if (!this.commandEncoder) { this.commandEncoder = this.device.createCommandEncoder(); } return this.commandEncoder; } getComputePassEncoder() { if (!this.computePassEncoder) { const commandEncoder = this.getCommandEncoder(); const computePassDescriptor = {}; if (this.queryType === "at-passes") { computePassDescriptor.timestampWrites = { querySet: this.querySet, beginningOfPassWriteIndex: this.pendingDispatchNumber * 2, endOfPassWriteIndex: this.pendingDispatchNumber * 2 + 1 }; } this.computePassEncoder = commandEncoder.beginComputePass(computePassDescriptor); } return this.computePassEncoder; } endComputePass() { if (this.computePassEncoder) { this.computePassEncoder.end(); this.computePassEncoder = null; } } flush() { if (!this.commandEncoder) { return; } TRACE_FUNC_BEGIN(); this.endComputePass(); let queryReadBuffer; if (this.queryType !== "none") { this.commandEncoder.resolveQuerySet( this.querySet, 0, this.pendingDispatchNumber * 2, this.queryResolveBuffer, 0 ); queryReadBuffer = this.device.createBuffer( // eslint-disable-next-line no-bitwise { size: this.pendingDispatchNumber * 2 * 8, usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST } ); this.pendingQueries.set(queryReadBuffer, this.pendingKernels); this.pendingKernels = []; this.commandEncoder.copyBufferToBuffer( this.queryResolveBuffer, 0, queryReadBuffer, 0, this.pendingDispatchNumber * 2 * 8 ); } this.device.queue.submit([this.commandEncoder.finish()]); this.gpuDataManager.refreshPendingBuffers(); this.commandEncoder = null; this.pendingDispatchNumber = 0; if (this.queryType !== "none") { void queryReadBuffer.mapAsync(GPUMapMode.READ).then(() => { const mappedData = new BigUint64Array(queryReadBuffer.getMappedRange()); const pendingKernels = this.pendingQueries.get(queryReadBuffer); for (let i = 0; i < mappedData.length / 2; i++) { const pendingKernelInfo = pendingKernels[i]; const kernelId = pendingKernelInfo.kernelId; const kernelInfo = this.kernels.get(kernelId); const kernelType = kernelInfo.kernelType; const kernelName = kernelInfo.kernelName; const programName = pendingKernelInfo.programName; const inputTensorViews = pendingKernelInfo.inputTensorViews; const outputTensorViews = pendingKernelInfo.outputTensorViews; const startTimeU64 = mappedData[i * 2]; const endTimeU64 = mappedData[i * 2 + 1]; if (typeof this.queryTimeBase === "undefined") { this.queryTimeBase = startTimeU64; } const startTime = Number(startTimeU64 - this.queryTimeBase); const endTime = Number(endTimeU64 - this.queryTimeBase); if (!Number.isSafeInteger(startTime) || !Number.isSafeInteger(endTime)) { throw new RangeError("incorrect timestamp range"); } if (this.env.webgpu.profiling?.ondata) { this.env.webgpu.profiling.ondata({ version: 1, inputsMetadata: inputTensorViews.map((value) => ({ dims: value.dims, dataType: tensorDataTypeEnumToString(value.dataType) })), outputsMetadata: outputTensorViews.map((value) => ({ dims: value.dims, dataType: tensorDataTypeEnumToString(value.dataType) })), kernelId, kernelType, kernelName, programName, startTime, endTime }); } else { let inputShapes = ""; inputTensorViews.forEach((value, i2) => { inputShapes += `input[${i2}]: [${value.dims}] | ${tensorDataTypeEnumToString(value.dataType)}, `; }); let outputShapes = ""; outputTensorViews.forEach((value, i2) => { outputShapes += `output[${i2}]: [${value.dims}] | ${tensorDataTypeEnumToString(value.dataType)}, `; }); console.log( `[profiling] kernel "${kernelId}|${kernelType}|${kernelName}|${programName}" ${inputShapes}${outputShapes}start time: ${startTime} ns, execution time: ${endTime - startTime} ns` ); } TRACE("GPU", `${programName}::${startTimeU64}::${endTimeU64}`); } queryReadBuffer.unmap(); this.pendingQueries.delete(queryReadBuffer); }); } TRACE_FUNC_END(); } /** * run a WebGPU program. * @param program a ProgramInfo instance * @param inputTensorViews a TensorView array. each element represents a value already exists in GPU. * @param outputIndices an indices array. each element can be either -1 (temporary data), -2 (persistent data) or an * index to the kernel's output. * @param createKernelOutput a callback function that create a value to kernel's output with the given index * @param createIntermediateOutput a callback function that create a value as a intermediate value, either temporary * or persistent (owned by the current kernel) * @returns a TensorView array representing the result. */ run(program, inputTensorViews, outputIndices, createKernelOutput, createIntermediateOutput, outputCount) { TRACE_FUNC_BEGIN(program.name); const inputDatas = []; for (let i = 0; i < inputTensorViews.length; ++i) { const data = inputTensorViews[i].data; if (data === 0) { continue; } const gpuData = this.gpuDataManager.get(data); if (!gpuData) { throw new Error(`no GPU data for input: ${data}`); } inputDatas.push(gpuData); } const { outputs, dispatchGroup, programUniforms } = program.getRunData(inputTensorViews); const validatedOutputIndices = outputIndices.length === 0 ? outputs.map((_, i) => i) : outputIndices; if (validatedOutputIndices.length !== outputs.length) { throw new Error(`Output size ${validatedOutputIndices.length} must be equal to ${outputs.length}.`); } const outputTensorViews = []; const outputDatas = []; for (let i = 0; i < outputs.length; ++i) { if (!Number.isInteger(validatedOutputIndices[i]) || validatedOutputIndices[i] < -3 || validatedOutputIndices[i] >= outputCount) { throw new Error(`Invalid output index: ${validatedOutputIndices[i]}`); } if (validatedOutputIndices[i] === -3) { continue; } const isTemporary = validatedOutputIndices[i] === -1; const isPersistent = validatedOutputIndices[i] === -2; const tensorView = isTemporary || isPersistent ? createIntermediateOutput(outputs[i].dataType, outputs[i].dims) : createKernelOutput(validatedOutputIndices[i], outputs[i].dataType, outputs[i].dims); outputTensorViews.push(tensorView); if (tensorView.data === 0) { continue; } const gpuData = this.gpuDataManager.get(tensorView.data); if (!gpuData) { throw new Error(`no GPU data for output: ${tensorView.data}`); } if (isTemporary) { this.temporaryData.push(gpuData); } if (isPersistent) { let persistentData = this.kernelPersistentData.get(this.currentKernelId); if (!persistentData) { persistentData = []; this.kernelPersistentData.set(this.currentKernelId, persistentData); } persistentData.push(gpuData); } outputDatas.push(gpuData); } if (inputDatas.length !== inputTensorViews.length || outputDatas.length !== outputTensorViews.length) { if (outputDatas.length === 0) { TRACE_FUNC_END(program.name); return outputTensorViews; } throw new Error( `Program ${program.name} has zero-sized tensor(s) in inputs or outputs. This is not supported now.` ); } let uniformBufferBinding; if (programUniforms) { let currentOffset = 0; const offsets = []; programUniforms.forEach((v) => { const data = typeof v.data === "number" ? [v.data] : v.data; if (data.length === 0) { return; } const sizeOfElement = v.type === 10 /* float16 */ ? 2 : 4; let sizeOfVecOrMat; let baseAlignment; if (v.type === 10 /* float16 */) { baseAlignment = data.length > 4 ? 16 : data.length > 2 ? 8 : data.length * sizeOfElement; sizeOfVecOrMat = data.length > 4 ? 16 : sizeOfElement * data.length; } else { baseAlignment = data.length <= 2 ? data.length * sizeOfElement : 16; sizeOfVecOrMat = 16; } currentOffset = Math.ceil(currentOffset / baseAlignment) * baseAlignment; offsets.push(currentOffset); const elementPerVecOrMat = v.type === 10 /* float16 */ ? 8 : 4; currentOffset += data.length > 4 ? Math.ceil(data.length / elementPerVecOrMat) * sizeOfVecOrMat : data.length * sizeOfElement; }); const maxAlignmentOfField = 16; currentOffset = Math.ceil(currentOffset / maxAlignmentOfField) * maxAlignmentOfField; const arrayBuffer = new ArrayBuffer(currentOffset); programUniforms.forEach((v, i) => { const offset = offsets[i]; const data = typeof v.data === "number" ? [v.data] : v.data; if (v.type === 6 /* int32 */) { new Int32Array(arrayBuffer, offset, data.length).set(data); } else if (v.type === 12 /* uint32 */) { new Uint32Array(arrayBuffer, offset, data.length).set(data); } else if (v.type === 10 /* float16 */) { new Uint16Array(arrayBuffer, offset, data.length).set(data); } else if (v.type === 1 /* float */) { new Float32Array(arrayBuffer, offset, data.length).set(data); } else { throw new Error(`Unsupported uniform type: ${tensorDataTypeEnumToString(v.type)}`); } }); const uniformBufferData = ( // eslint-disable-next-line no-bitwise this.gpuDataManager.create(currentOffset, GPUBufferUsage.COPY_DST | GPUBufferUsage.UNIFORM) ); this.device.queue.writeBuffer(uniformBufferData.buffer, 0, arrayBuffer, 0, currentOffset); this.gpuDataManager.release(uniformBufferData.id); uniformBufferBinding = { offset: 0, size: currentOffset, buffer: uniformBufferData.buffer }; } const normalizedDispatchGroup = this.programManager.normalizeDispatchGroupSize(dispatchGroup); const is1DimensionDispatch = normalizedDispatchGroup[1] === 1 && normalizedDispatchGroup[2] === 1; const key = getProgramInfoUniqueKey2(program, inputTensorViews, is1DimensionDispatch); let artifact = this.programManager.getArtifact(key); if (!artifact) { artifact = this.programManager.build(program, normalizedDispatchGroup); this.programManager.setArtifact(key, artifact); LOG_DEBUG("info", () => `[artifact] key: ${key}, programName: ${program.name}`); } if (programUniforms && artifact.uniformVariablesInfo) { if (programUniforms.length !== artifact.uniformVariablesInfo.length) { throw new Error( `Uniform variables count mismatch: expect ${artifact.uniformVariablesInfo.length}, got ${programUniforms.length} in program "${artifact.programInfo.name}".` ); } for (let i = 0; i < programUniforms.length; i++) { const uniform = programUniforms[i]; const actualType = uniform.type; const actualLength = typeof uniform.data === "number" ? 1 : uniform.data.length; const [type, length] = artifact.uniformVariablesInfo[i]; if (actualType !== type || actualLength !== length) { throw new Error( `Uniform variable ${i} mismatch: expect type ${type} with size ${length}, got type ${actualType} with size ${actualLength} in program "${artifact.programInfo.name}".` ); } } } LOG_DEBUG( "info", () => `[ProgramManager] run "${program.name}" (key=${key}) with ${normalizedDispatchGroup[0]}x${normalizedDispatchGroup[1]}x${normalizedDispatchGroup[2]}` ); if (this.queryType !== "none" || this.sessionStatus === "capturing") { const pendingKernelInfo = { kernelId: this.currentKernelId, programName: artifact.programInfo.name, inputTensorViews, outputTensorViews }; this.pendingKernels.push(pendingKernelInfo); if (this.sessionStatus === "capturing") { const sessionPendingKernels = this.capturedPendingKernels.get(this.currentSessionId); sessionPendingKernels.push(pendingKernelInfo); } } this.programManager.run(artifact, inputDatas, outputDatas, normalizedDispatchGroup, uniformBufferBinding); TRACE_FUNC_END(program.name); return outputTensorViews; } upload(gpuDataId, data) { this.gpuDataManager.upload(gpuDataId, data); } memcpy(src, dst) { this.gpuDataManager.memcpy(src, dst); } async download(gpuDataId, getTargetBuffer) { await this.gpuDataManager.download(gpuDataId, getTargetBuffer); } alloc(size) { return this.gpuDataManager.create(size).id; } free(ptr) { return this.gpuDataManager.release(ptr); } createKernel(kernelType, kernelId, attribute, kernelName) { const op = WEBGPU_OP_RESOLVE_RULES.get(kernelType); if (!op) { throw new Error(`kernel not implemented: ${kernelType}`); } const kernelInfo = { kernelType, kernelName, kernelEntry: op[0], attributes: [op[1], attribute] }; this.kernels.set(kernelId, kernelInfo); } releaseKernel(kernelId) { const persistentData = this.kernelPersistentData.get(kernelId); if (persistentData) { for (const data of persistentData) { this.gpuDataManager.release(data.id); } this.kernelPersistentData.delete(kernelId); } this.kernelCustomData.delete(kernelId); this.kernels.delete(kernelId); } computeKernel(kernelId, context, errors) { const kernel = this.kernels.get(kernelId); if (!kernel) { throw new Error(`kernel not created: ${kernelId}`); } const kernelType = kernel.kernelType; const kernelName = kernel.kernelName; const kernelEntry = kernel.kernelEntry; const attributes = kernel.attributes; if (this.currentKernelId !== null) { throw new Error(`kernel "[${kernelType}] ${kernelName}" is not allowed to be called recursively`); } this.currentKernelId = kernelId; if (attributes[0]) { attributes[1] = attributes[0](attributes[1]); attributes[0] = void 0; } LOG_DEBUG("info", () => `[WebGPU] Start to run kernel "[${kernelType}] ${kernelName}"...`); const useErrorScope = this.env.debug; this.temporaryData = []; try { if (useErrorScope) { this.device.pushErrorScope("validation"); } kernelEntry(context, attributes[1]); return 0; } catch (e) { errors.push(Promise.resolve(`[WebGPU] Kernel "[${kernelType}] ${kernelName}" failed. ${e}`)); return 1; } finally { if (useErrorScope) { errors.push( this.device.popErrorScope().then( (err) => err ? `GPU validation error for kernel "[${kernelType}] ${kernelName}": ${err.message}` : null ) ); } for (const data of this.temporaryData) { this.gpuDataManager.release(data.id); } this.temporaryData = []; this.currentKernelId = null; } } // #region external buffer registerBuffer(sessionId, index, buffer, size) { let sessionInputOutputMapping = this.sessionExternalDataMapping.get(sessionId); if (!sessionInputOutputMapping) { sessionInputOutputMapping = /* @__PURE__ */ new Map(); this.sessionExternalDataMapping.set(sessionId, sessionInputOutputMapping); } const previousBuffer = sessionInputOutputMapping.get(index); const id = this.gpuDataManager.registerExternalBuffer(buffer, size, previousBuffer); sessionInputOutputMapping.set(index, [id, buffer]); return id; } unregisterBuffers(sessionId) { const sessionInputOutputMapping = this.sessionExternalDataMapping.get(sessionId); if (sessionInputOutputMapping) { sessionInputOutputMapping.forEach((bufferInfo) => this.gpuDataManager.unregisterExternalBuffer(bufferInfo[0])); this.sessionExternalDataMapping.delete(sessionId); } } getBuffer(gpuDataId) { const gpuData = this.gpuDataManager.get(gpuDataId); if (!gpuData) { throw new Error(`no GPU data for buffer: ${gpuDataId}`); } return gpuData.buffer; } createDownloader(gpuBuffer, size, type) { return async () => { const data = await downloadGpuData(this, gpuBuffer, size); return createView2(data.buffer, type); }; } // #endregion writeTimestamp(index) { if (this.queryType !== "inside-passes") { return; } this.computePassEncoder.writeTimestamp(this.querySet, index); } setQueryType() { this.queryType = "none"; if (this.env.webgpu.profiling?.mode === "default" || (typeof this.env.trace === "undefined" ? this.env.wasm.trace : this.env.trace)) { if (this.device.features.has("chromium-experimental-timestamp-query-inside-passes")) { this.queryType = "inside-passes"; } else if (this.device.features.has("timestamp-query")) { this.queryType = "at-passes"; } if (this.queryType !== "none" && typeof this.querySet === "undefined") { this.querySet = this.device.createQuerySet({ type: "timestamp", count: this.maxDispatchNumber * 2 }); this.queryResolveBuffer = this.device.createBuffer( // eslint-disable-next-line no-bitwise { size: this.maxDispatchNumber * 2 * 8, usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.QUERY_RESOLVE } ); } } } captureBegin() { LOG_DEBUG("info", "captureBegin"); if (!this.capturedCommandList.get(this.currentSessionId)) { this.capturedCommandList.set(this.currentSessionId, []); } if (!this.capturedPendingKernels.get(this.currentSessionId)) { this.capturedPendingKernels.set(this.currentSessionId, []); } this.flush(); this.sessionStatus = "capturing"; } captureEnd() { LOG_DEBUG("info", "captureEnd"); this.flush(); this.sessionStatus = "default"; } replay() { LOG_DEBUG("info", "replay"); this.sessionStatus = "replaying"; const sessionCommandList = this.capturedCommandList.get(this.currentSessionId); const sessionPendingKernels = this.capturedPendingKernels.get(this.currentSessionId); const length = sessionCommandList.length; this.pendingKernels = []; for (let i = 0; i < length; i++) { const computePassEncoder = this.getComputePassEncoder(); const command = sessionCommandList[i]; this.writeTimestamp(this.pendingDispatchNumber * 2); computePassEncoder.setPipeline(command.computePipeline); computePassEncoder.setBindGroup(0, command.bindGroup); computePassEncoder.dispatchWorkgroups(...command.dispatchGroup); this.writeTimestamp(this.pendingDispatchNumber * 2 + 1); this.pendingDispatchNumber++; if (this.queryType !== "none") { this.pendingKernels.push(sessionPendingKernels[i]); } if (this.pendingDispatchNumber >= this.maxDispatchNumber || this.queryType === "at-passes") { this.endComputePass(); } if (this.pendingDispatchNumber >= this.maxDispatchNumber) { this.flush(); } } this.flush(); this.sessionStatus = "default"; } onCreateSession() { this.gpuDataManager.onCreateSession(); } onReleaseSession(sessionId) { this.unregisterBuffers(sessionId); if (this.capturedCommandList.has(sessionId)) { this.capturedCommandList.delete(sessionId); } if (this.capturedPendingKernels.has(sessionId)) { this.capturedPendingKernels.delete(sessionId); } this.gpuDataManager.onReleaseSession(sessionId); } onRunStart(sessionId) { this.currentSessionId = sessionId; this.setQueryType(); } }; } }); // web/lib/wasm/jsep/init.ts var init_exports = {}; __export(init_exports, { init: () => init }); var TensorViewImpl, ComputeContextImpl, init; var init_init = __esm({ "web/lib/wasm/jsep/init.ts"() { "use strict"; init_wasm_common(); init_log(); init_util2(); init_backend_webnn(); TensorViewImpl = class _TensorViewImpl { constructor(module2, dataType, data, dims) { this.module = module2; this.dataType = dataType; this.data = data; this.dims = dims; } getFloat32Array() { if (this.dataType !== 1 /* float */) { throw new Error("Invalid data type"); } const elementCount = ShapeUtil2.size(this.dims); return elementCount === 0 ? new Float32Array() : new Float32Array(this.module.HEAP8.buffer, this.data, elementCount); } getBigInt64Array() { if (this.dataType !== 7 /* int64 */) { throw new Error("Invalid data type"); } const elementCount = ShapeUtil2.size(this.dims); return elementCount === 0 ? new BigInt64Array() : new BigInt64Array(this.module.HEAP8.buffer, this.data, elementCount); } getInt32Array() { if (this.dataType !== 6 /* int32 */) { throw new Error("Invalid data type"); } const elementCount = ShapeUtil2.size(this.dims); return elementCount === 0 ? new Int32Array() : new Int32Array(this.module.HEAP8.buffer, this.data, elementCount); } getUint16Array() { if (this.dataType !== 10 /* float16 */ && this.dataType !== 4 /* uint16 */) { throw new Error("Invalid data type"); } const elementCount = ShapeUtil2.size(this.dims); return elementCount === 0 ? new Uint16Array() : new Uint16Array(this.module.HEAP8.buffer, this.data, elementCount); } reshape(newDims) { if (ShapeUtil2.size(newDims) !== ShapeUtil2.size(this.dims)) { throw new Error("Invalid new shape"); } return new _TensorViewImpl(this.module, this.dataType, this.data, newDims); } }; ComputeContextImpl = class { constructor(module2, backend2, contextDataOffset) { this.module = module2; this.backend = backend2; this.customDataOffset = 0; this.customDataSize = 0; this.adapterInfo = backend2.adapterInfo; const ptrSize = module2.PTR_SIZE; let dataIndex = contextDataOffset / module2.PTR_SIZE; const type = ptrSize === 4 ? "i32" : "i64"; this.opKernelContext = Number(module2.getValue(ptrSize * dataIndex++, type)); const inputCount = Number(module2.getValue(ptrSize * dataIndex++, type)); this.outputCount = Number(module2.getValue(ptrSize * dataIndex++, type)); this.customDataOffset = Number(module2.getValue(ptrSize * dataIndex++, "*")); this.customDataSize = Number(module2.getValue(ptrSize * dataIndex++, type)); const inputs = []; for (let i = 0; i < inputCount; i++) { const dataType = Number(module2.getValue(ptrSize * dataIndex++, type)); const data = Number(module2.getValue(ptrSize * dataIndex++, "*")); const dim = Number(module2.getValue(ptrSize * dataIndex++, type)); const dims = []; for (let d = 0; d < dim; d++) { dims.push(Number(module2.getValue(ptrSize * dataIndex++, type))); } inputs.push(new TensorViewImpl(module2, dataType, data, dims)); } this.inputs = inputs; } get kernelCustomData() { return this.backend.currentKernelCustomData; } get customDataBuffer() { return this.module.HEAPU8.subarray(this.customDataOffset, this.customDataOffset + this.customDataSize); } compute(program, inputsOutputsMapping) { const mappedInputs = inputsOutputsMapping?.inputs?.map((i) => typeof i === "number" ? this.inputs[i] : i) ?? this.inputs; const outputIndices = inputsOutputsMapping?.outputs ?? []; const createKernelOutput = (index, dataType, dims) => new TensorViewImpl(this.module, dataType, this.output(index, dims), dims); const createTemporaryOutput = (dataType, dims) => { const bufferSize = calculateTensorSizeInBytes(dataType, dims); if (!bufferSize) { throw new Error(`Unsupported data type: ${dataType}`); } const gpuDataId = bufferSize > 0 ? this.backend.gpuDataManager.create(bufferSize).id : 0; return new TensorViewImpl(this.module, dataType, gpuDataId, dims); }; return this.backend.run( program, mappedInputs, outputIndices, createKernelOutput, createTemporaryOutput, this.outputCount ); } output(index, dims) { const stack = this.module.stackSave(); try { const ptrSize = this.module.PTR_SIZE; const type = ptrSize === 4 ? "i32" : "i64"; const data = this.module.stackAlloc( (1 + dims.length) * ptrSize /* sizeof(size_t) */ ); this.module.setValue(data, dims.length, type); for (let i = 0; i < dims.length; i++) { this.module.setValue(data + ptrSize * (i + 1), dims[i], type); } return this.module._JsepOutput(this.opKernelContext, index, data); } catch (e) { throw new Error( `Failed to generate kernel's output[${index}] with dims [${dims}]. If you are running with pre-allocated output, please make sure the output type/dims are correct. Error: ${e}` ); } finally { this.module.stackRestore(stack); } } }; init = async (name2, module2, env3, gpuAdapter) => { const jsepInit = module2.jsepInit; if (!jsepInit) { throw new Error("Failed to initialize JSEP. The WebAssembly module is not built with JSEP support."); } if (name2 === "webgpu") { const webGpuBackendImpl = (init_backend_webgpu(), __toCommonJS(backend_webgpu_exports)).WebGpuBackend; const backend2 = new webGpuBackendImpl(); await backend2.initialize(env3, gpuAdapter); jsepInit("webgpu", [ // backend backend2, // jsepAlloc() (size) => backend2.alloc(Number(size)), // jsepFree() (ptr) => backend2.free(ptr), // jsepCopy(src, dst, size, isSourceGpu) (src, dst, size, isSourceGpu = false) => { if (isSourceGpu) { LOG_DEBUG( "verbose", () => `[WebGPU] jsepCopyGpuToGpu: src=${Number(src)}, dst=${Number(dst)}, size=${Number(size)}` ); backend2.memcpy(Number(src), Number(dst)); } else { LOG_DEBUG( "verbose", () => `[WebGPU] jsepCopyCpuToGpu: dataOffset=${Number(src)}, gpuDataId=${Number(dst)}, size=${Number(size)}` ); const data = module2.HEAPU8.subarray(Number(src >>> 0), Number(src >>> 0) + Number(size)); backend2.upload(Number(dst), data); } }, // jsepCopyAsync(src, dst, size) async (gpuDataId, dataOffset, size) => { LOG_DEBUG( "verbose", () => `[WebGPU] jsepCopyGpuToCpu: gpuDataId=${gpuDataId}, dataOffset=${dataOffset}, size=${size}` ); await backend2.download( Number(gpuDataId), () => module2.HEAPU8.subarray(Number(dataOffset) >>> 0, Number(dataOffset + size) >>> 0) ); }, // jsepCreateKernel (kernelType, kernelId, attribute) => backend2.createKernel( kernelType, Number(kernelId), attribute, module2.UTF8ToString(module2._JsepGetNodeName(Number(kernelId))) ), // jsepReleaseKernel (kernel) => backend2.releaseKernel(kernel), // jsepRun (kernel, contextDataOffset, sessionHandle, errors) => { LOG_DEBUG( "verbose", () => `[WebGPU] jsepRun: sessionHandle=${sessionHandle}, kernel=${kernel}, contextDataOffset=${contextDataOffset}` ); const context = new ComputeContextImpl(module2, backend2, Number(contextDataOffset)); return backend2.computeKernel(Number(kernel), context, errors); }, // jsepCaptureBegin () => backend2.captureBegin(), // jsepCaptureEnd () => backend2.captureEnd(), // jsepReplay () => backend2.replay() ]); } else { const backend2 = new WebNNBackend(env3); jsepInit("webnn", [ backend2, // webnnReserveTensorId () => backend2.reserveTensorId(), // webnnReleaseTensorId (tensorId) => backend2.releaseTensorId(tensorId), // webnnEnsureTensor async (sessionId, tensorId, onnxDataType, shape2, copyOld) => backend2.ensureTensor(sessionId, tensorId, onnxDataType, shape2, copyOld), // webnnUploadTensor (tensorId, data) => { backend2.uploadTensor(tensorId, data); }, // webnnDownloadTensor async (tensorId, dstBuffer) => backend2.downloadTensor(tensorId, dstBuffer), // webnnRegisterMLContext (sessionId, mlContext) => backend2.registerMLContext(sessionId, mlContext), // webnnEnableTraceEvent !!env3.trace ]); } }; } }); // web/lib/wasm/wasm-core-impl.ts var initOrt, initRuntime, initEp, activeSessions, getSessionInputOutputCount, getSessionInputOutputMetadata, copyFromExternalBuffer, createSession, releaseSession, prepareInputOutputTensor, run, endProfiling, extractTransferableBuffers; var init_wasm_core_impl = __esm({ "web/lib/wasm/wasm-core-impl.ts"() { "use strict"; init_esm(); init_run_options(); init_session_options(); init_wasm_common(); init_wasm_factory(); init_wasm_utils(); init_wasm_utils_load_file(); initOrt = (numThreads, loggingLevel) => { const errorCode = getInstance()._OrtInit(numThreads, loggingLevel); if (errorCode !== 0) { checkLastError("Can't initialize onnxruntime."); } }; initRuntime = async (env3) => { initOrt(env3.wasm.numThreads, logLevelStringToEnum(env3.logLevel)); }; initEp = async (env3, epName) => { getInstance().asyncInit?.(); let webgpuAdapter = env3.webgpu.adapter; if (epName === "webgpu") { if (typeof navigator === "undefined" || !navigator.gpu) { throw new Error("WebGPU is not supported in current environment"); } if (!webgpuAdapter) { const powerPreference = env3.webgpu.powerPreference; if (powerPreference !== void 0 && powerPreference !== "low-power" && powerPreference !== "high-performance") { throw new Error(`Invalid powerPreference setting: "${powerPreference}"`); } const forceFallbackAdapter = env3.webgpu.forceFallbackAdapter; if (forceFallbackAdapter !== void 0 && typeof forceFallbackAdapter !== "boolean") { throw new Error(`Invalid forceFallbackAdapter setting: "${forceFallbackAdapter}"`); } webgpuAdapter = await navigator.gpu.requestAdapter({ powerPreference, forceFallbackAdapter }); if (!webgpuAdapter) { throw new Error( 'Failed to get GPU adapter. You may need to enable flag "--enable-unsafe-webgpu" if you are using Chrome.' ); } } else { if (typeof webgpuAdapter.limits !== "object" || typeof webgpuAdapter.features !== "object" || typeof webgpuAdapter.requestDevice !== "function") { throw new Error("Invalid GPU adapter set in `env.webgpu.adapter`. It must be a GPUAdapter object."); } } } if (epName === "webnn") { if (typeof navigator === "undefined" || !navigator.ml) { throw new Error("WebNN is not supported in current environment"); } } if (true) { const initJsep = (init_init(), __toCommonJS(init_exports)).init; if (epName === "webgpu") { await initJsep("webgpu", getInstance(), env3, webgpuAdapter); } if (epName === "webnn") { await initJsep("webnn", getInstance(), env3); } } else { if (false) { getInstance().webgpuInit((device) => { env3.webgpu.device = device; }); } if (epName === "webnn") { const backend2 = new null.WebNNBackend(env3); getInstance().webnnInit([ backend2, // webnnReserveTensorId () => backend2.reserveTensorId(), // webnnReleaseTensorId, (tensorId) => backend2.releaseTensorId(tensorId), // webnnEnsureTensor async (sessionId, tensorId, onnxDataType, shape2, copyOld) => backend2.ensureTensor(sessionId, tensorId, onnxDataType, shape2, copyOld), // webnnUploadTensor (tensorId, data) => { backend2.uploadTensor(tensorId, data); }, // webnnDownloadTensor async (tensorId, dstBuffer) => backend2.downloadTensor(tensorId, dstBuffer), // webnnRegisterMLContext (sessionId, mlContext) => backend2.registerMLContext(sessionId, mlContext), // webnnEnableTraceEvent !!env3.trace ]); } } }; activeSessions = /* @__PURE__ */ new Map(); getSessionInputOutputCount = (sessionHandle) => { const wasm3 = getInstance(); const stack = wasm3.stackSave(); try { const ptrSize = wasm3.PTR_SIZE; const dataOffset = wasm3.stackAlloc(2 * ptrSize); const errorCode = wasm3._OrtGetInputOutputCount(sessionHandle, dataOffset, dataOffset + ptrSize); if (errorCode !== 0) { checkLastError("Can't get session input/output count."); } const type = ptrSize === 4 ? "i32" : "i64"; return [Number(wasm3.getValue(dataOffset, type)), Number(wasm3.getValue(dataOffset + ptrSize, type))]; } finally { wasm3.stackRestore(stack); } }; getSessionInputOutputMetadata = (sessionHandle, index) => { const wasm3 = getInstance(); const stack = wasm3.stackSave(); let metadataOffset = 0; try { const ptrSize = wasm3.PTR_SIZE; const dataOffset = wasm3.stackAlloc(2 * ptrSize); const errorCode = wasm3._OrtGetInputOutputMetadata(sessionHandle, index, dataOffset, dataOffset + ptrSize); if (errorCode !== 0) { checkLastError("Can't get session input/output metadata."); } const nameOffset = Number(wasm3.getValue(dataOffset, "*")); metadataOffset = Number(wasm3.getValue(dataOffset + ptrSize, "*")); const elementType = wasm3.HEAP32[metadataOffset / 4]; if (elementType === 0) { return [nameOffset, 0]; } const dimsCount = wasm3.HEAPU32[metadataOffset / 4 + 1]; const dims = []; for (let i = 0; i < dimsCount; i++) { const symbolicDimNameOffset = Number(wasm3.getValue(metadataOffset + 8 + i * ptrSize, "*")); dims.push( symbolicDimNameOffset !== 0 ? wasm3.UTF8ToString(symbolicDimNameOffset) : Number(wasm3.getValue(metadataOffset + 8 + (i + dimsCount) * ptrSize, "*")) ); } return [nameOffset, elementType, dims]; } finally { wasm3.stackRestore(stack); if (metadataOffset !== 0) { wasm3._OrtFree(metadataOffset); } } }; copyFromExternalBuffer = (model) => { const wasm3 = getInstance(); const modelDataOffset = wasm3._malloc(model.byteLength); if (modelDataOffset === 0) { throw new Error(`Can't create a session. failed to allocate a buffer of size ${model.byteLength}.`); } wasm3.HEAPU8.set(model, modelDataOffset); return [modelDataOffset, model.byteLength]; }; createSession = async (modelData, options) => { let modelDataOffset, modelDataLength; const wasm3 = getInstance(); if (Array.isArray(modelData)) { [modelDataOffset, modelDataLength] = modelData; } else if (modelData.buffer === wasm3.HEAPU8.buffer) { [modelDataOffset, modelDataLength] = [modelData.byteOffset, modelData.byteLength]; } else { [modelDataOffset, modelDataLength] = copyFromExternalBuffer(modelData); } let sessionHandle = 0; let sessionOptionsHandle = 0; let ioBindingHandle = 0; let allocs = []; const inputNamesUTF8Encoded = []; const outputNamesUTF8Encoded = []; try { [sessionOptionsHandle, allocs] = await setSessionOptions(options); if (options?.externalData && wasm3.mountExternalData) { const loadingPromises = []; for (const file of options.externalData) { const path = typeof file === "string" ? file : file.path; loadingPromises.push( loadFile(typeof file === "string" ? file : file.data).then((data) => { wasm3.mountExternalData(path, data); }) ); } await Promise.all(loadingPromises); } for (const provider of options?.executionProviders ?? []) { const providerName = typeof provider === "string" ? provider : provider.name; if (providerName === "webnn") { wasm3.shouldTransferToMLTensor = false; if (typeof provider !== "string") { const webnnOptions = provider; const context = webnnOptions?.context; const gpuDevice = webnnOptions?.gpuDevice; const deviceType = webnnOptions?.deviceType; const powerPreference = webnnOptions?.powerPreference; if (context) { wasm3.currentContext = context; } else if (gpuDevice) { wasm3.currentContext = await wasm3.webnnCreateMLContext(gpuDevice); } else { wasm3.currentContext = await wasm3.webnnCreateMLContext({ deviceType, powerPreference }); } } else { wasm3.currentContext = await wasm3.webnnCreateMLContext(); } break; } } sessionHandle = await wasm3._OrtCreateSession(modelDataOffset, modelDataLength, sessionOptionsHandle); wasm3.webgpuOnCreateSession?.(sessionHandle); if (sessionHandle === 0) { checkLastError("Can't create a session."); } wasm3.jsepOnCreateSession?.(); if (wasm3.currentContext) { wasm3.webnnRegisterMLContext(sessionHandle, wasm3.currentContext); wasm3.currentContext = void 0; wasm3.shouldTransferToMLTensor = true; } const [inputCount, outputCount] = getSessionInputOutputCount(sessionHandle); const enableGraphCapture = !!options?.enableGraphCapture; const inputNames = []; const outputNames = []; const inputMetadata = []; const outputMetadata = []; const outputPreferredLocations = []; for (let i = 0; i < inputCount; i++) { const [nameOffset, elementType, shape2] = getSessionInputOutputMetadata(sessionHandle, i); if (nameOffset === 0) { checkLastError("Can't get an input name."); } inputNamesUTF8Encoded.push(nameOffset); const name2 = wasm3.UTF8ToString(nameOffset); inputNames.push(name2); inputMetadata.push( elementType === 0 ? { name: name2, isTensor: false } : { name: name2, isTensor: true, type: tensorDataTypeEnumToString(elementType), shape: shape2 } ); } for (let i = 0; i < outputCount; i++) { const [nameOffset, elementType, shape2] = getSessionInputOutputMetadata(sessionHandle, i + inputCount); if (nameOffset === 0) { checkLastError("Can't get an output name."); } outputNamesUTF8Encoded.push(nameOffset); const nameString = wasm3.UTF8ToString(nameOffset); outputNames.push(nameString); outputMetadata.push( elementType === 0 ? { name: nameString, isTensor: false } : { name: nameString, isTensor: true, type: tensorDataTypeEnumToString(elementType), shape: shape2 } ); if (true) { if (enableGraphCapture && options?.preferredOutputLocation === void 0) { outputPreferredLocations.push("gpu-buffer"); continue; } const location2 = typeof options?.preferredOutputLocation === "string" ? options.preferredOutputLocation : options?.preferredOutputLocation?.[nameString] ?? "cpu"; const isGraphOutput = wasm3.webnnIsGraphOutput; if (location2 === "cpu" && isGraphOutput && isGraphOutput(sessionHandle, nameString)) { outputPreferredLocations.push("ml-tensor-cpu-output"); continue; } if (location2 !== "cpu" && location2 !== "cpu-pinned" && location2 !== "gpu-buffer" && location2 !== "ml-tensor") { throw new Error(`Not supported preferred output location: ${location2}.`); } if (enableGraphCapture && location2 !== "gpu-buffer") { throw new Error( `Not supported preferred output location: ${location2}. Only 'gpu-buffer' location is supported when enableGraphCapture is true.` ); } outputPreferredLocations.push(location2); } } let bindingState = null; if (outputPreferredLocations.some((l) => l === "gpu-buffer" || l === "ml-tensor" || l === "ml-tensor-cpu-output")) { ioBindingHandle = wasm3._OrtCreateBinding(sessionHandle); if (ioBindingHandle === 0) { checkLastError("Can't create IO binding."); } bindingState = { handle: ioBindingHandle, outputPreferredLocations, outputPreferredLocationsEncoded: outputPreferredLocations.map((l) => l === "ml-tensor-cpu-output" ? "ml-tensor" : l).map((l) => dataLocationStringToEnum(l)) }; } activeSessions.set(sessionHandle, [ sessionHandle, inputNamesUTF8Encoded, outputNamesUTF8Encoded, bindingState, enableGraphCapture, false ]); return [sessionHandle, inputNames, outputNames, inputMetadata, outputMetadata]; } catch (e) { inputNamesUTF8Encoded.forEach((buf) => wasm3._OrtFree(buf)); outputNamesUTF8Encoded.forEach((buf) => wasm3._OrtFree(buf)); if (ioBindingHandle !== 0) { if (wasm3._OrtReleaseBinding(ioBindingHandle) !== 0) { checkLastError("Can't release IO binding."); } } if (sessionHandle !== 0) { if (wasm3._OrtReleaseSession(sessionHandle) !== 0) { checkLastError("Can't release session."); } } throw e; } finally { wasm3._free(modelDataOffset); if (sessionOptionsHandle !== 0) { if (wasm3._OrtReleaseSessionOptions(sessionOptionsHandle) !== 0) { checkLastError("Can't release session options."); } } allocs.forEach((alloc) => wasm3._free(alloc)); wasm3.unmountExternalData?.(); } }; releaseSession = (sessionId) => { const wasm3 = getInstance(); const session = activeSessions.get(sessionId); if (!session) { throw new Error(`cannot release session. invalid session id: ${sessionId}`); } const [sessionHandle, inputNamesUTF8Encoded, outputNamesUTF8Encoded, ioBindingState, enableGraphCapture] = session; if (ioBindingState) { if (enableGraphCapture) { if (wasm3._OrtClearBoundOutputs(ioBindingState.handle) !== 0) { checkLastError("Can't clear bound outputs."); } } if (wasm3._OrtReleaseBinding(ioBindingState.handle) !== 0) { checkLastError("Can't release IO binding."); } } wasm3.jsepOnReleaseSession?.(sessionId); wasm3.webnnOnReleaseSession?.(sessionId); wasm3.webgpuOnReleaseSession?.(sessionId); inputNamesUTF8Encoded.forEach((buf) => wasm3._OrtFree(buf)); outputNamesUTF8Encoded.forEach((buf) => wasm3._OrtFree(buf)); if (wasm3._OrtReleaseSession(sessionHandle) !== 0) { checkLastError("Can't release session."); } activeSessions.delete(sessionId); }; prepareInputOutputTensor = async (tensor, tensorHandles, allocs, sessionId, tensorNameUTF8Encoded, index, enableGraphCapture = false) => { if (!tensor) { tensorHandles.push(0); return; } const wasm3 = getInstance(); const ptrSize = wasm3.PTR_SIZE; const dataType = tensor[0]; const dims = tensor[1]; const location2 = tensor[3]; let actualLocation = location2; let rawData; let dataByteLength; if (dataType === "string" && (location2 === "gpu-buffer" || location2 === "ml-tensor")) { throw new Error("String tensor is not supported on GPU."); } if (enableGraphCapture && location2 !== "gpu-buffer") { throw new Error( `External buffer must be provided for input/output index ${index} when enableGraphCapture is true.` ); } if (location2 === "gpu-buffer") { const gpuBuffer = tensor[2].gpuBuffer; dataByteLength = calculateTensorSizeInBytes(tensorDataTypeStringToEnum(dataType), dims); if (false) { const registerBuffer = wasm3.webgpuRegisterBuffer; if (!registerBuffer) { throw new Error('Tensor location "gpu-buffer" is not supported without using WebGPU.'); } rawData = registerBuffer(gpuBuffer, sessionId); } else { const registerBuffer = wasm3.jsepRegisterBuffer; if (!registerBuffer) { throw new Error('Tensor location "gpu-buffer" is not supported without using WebGPU.'); } rawData = registerBuffer(sessionId, index, gpuBuffer, dataByteLength); } } else if (location2 === "ml-tensor") { const mlTensor = tensor[2].mlTensor; dataByteLength = calculateTensorSizeInBytes(tensorDataTypeStringToEnum(dataType), dims); const registerMLTensor = wasm3.webnnRegisterMLTensor; if (!registerMLTensor) { throw new Error('Tensor location "ml-tensor" is not supported without using WebNN.'); } rawData = registerMLTensor(sessionId, mlTensor, tensorDataTypeStringToEnum(dataType), dims); } else { const data = tensor[2]; if (Array.isArray(data)) { dataByteLength = ptrSize * data.length; rawData = wasm3._malloc(dataByteLength); allocs.push(rawData); for (let i = 0; i < data.length; i++) { if (typeof data[i] !== "string") { throw new TypeError(`tensor data at index ${i} is not a string`); } wasm3.setValue(rawData + i * ptrSize, allocWasmString(data[i], allocs), "*"); } } else { const isGraphInput = wasm3.webnnIsGraphInput; const isGraphOutput = wasm3.webnnIsGraphOutput; if (dataType !== "string" && isGraphInput && isGraphOutput) { const tensorName = wasm3.UTF8ToString(tensorNameUTF8Encoded); if (isGraphInput(sessionId, tensorName) || isGraphOutput(sessionId, tensorName)) { const dataTypeEnum = tensorDataTypeStringToEnum(dataType); dataByteLength = calculateTensorSizeInBytes(dataTypeEnum, dims); actualLocation = "ml-tensor"; const createTemporaryTensor = wasm3.webnnCreateTemporaryTensor; const uploadTensor = wasm3.webnnUploadTensor; if (!createTemporaryTensor || !uploadTensor) { throw new Error('Tensor location "ml-tensor" is not supported without using WebNN.'); } const tensorId = await createTemporaryTensor(sessionId, dataTypeEnum, dims); uploadTensor(tensorId, new Uint8Array(data.buffer, data.byteOffset, data.byteLength)); rawData = tensorId; } else { dataByteLength = data.byteLength; rawData = wasm3._malloc(dataByteLength); allocs.push(rawData); wasm3.HEAPU8.set(new Uint8Array(data.buffer, data.byteOffset, dataByteLength), rawData); } } else { dataByteLength = data.byteLength; rawData = wasm3._malloc(dataByteLength); allocs.push(rawData); wasm3.HEAPU8.set(new Uint8Array(data.buffer, data.byteOffset, dataByteLength), rawData); } } } const stack = wasm3.stackSave(); const dimsOffset = wasm3.stackAlloc(4 * dims.length); try { dims.forEach((d, index2) => wasm3.setValue(dimsOffset + index2 * ptrSize, d, ptrSize === 4 ? "i32" : "i64")); const tensor2 = wasm3._OrtCreateTensor( tensorDataTypeStringToEnum(dataType), rawData, dataByteLength, dimsOffset, dims.length, dataLocationStringToEnum(actualLocation) ); if (tensor2 === 0) { checkLastError(`Can't create tensor for input/output. session=${sessionId}, index=${index}.`); } tensorHandles.push(tensor2); } finally { wasm3.stackRestore(stack); } }; run = async (sessionId, inputIndices, inputTensors, outputIndices, outputTensors, options) => { const wasm3 = getInstance(); const ptrSize = wasm3.PTR_SIZE; const session = activeSessions.get(sessionId); if (!session) { throw new Error(`cannot run inference. invalid session id: ${sessionId}`); } const sessionHandle = session[0]; const inputNamesUTF8Encoded = session[1]; const outputNamesUTF8Encoded = session[2]; const ioBindingState = session[3]; const enableGraphCapture = session[4]; const inputOutputBound = session[5]; const inputCount = inputIndices.length; const outputCount = outputIndices.length; let runOptionsHandle = 0; let runOptionsAllocs = []; const inputTensorHandles = []; const outputTensorHandles = []; const inputOutputAllocs = []; const preAllocatedOutputs = []; const beforeRunStack = wasm3.stackSave(); const inputValuesOffset = wasm3.stackAlloc(inputCount * ptrSize); const inputNamesOffset = wasm3.stackAlloc(inputCount * ptrSize); const outputValuesOffset = wasm3.stackAlloc(outputCount * ptrSize); const outputNamesOffset = wasm3.stackAlloc(outputCount * ptrSize); try { [runOptionsHandle, runOptionsAllocs] = setRunOptions(options); TRACE_EVENT_BEGIN("wasm prepareInputOutputTensor"); for (let i = 0; i < inputCount; i++) { await prepareInputOutputTensor( inputTensors[i], inputTensorHandles, inputOutputAllocs, sessionId, inputNamesUTF8Encoded[inputIndices[i]], inputIndices[i], enableGraphCapture ); } for (let i = 0; i < outputCount; i++) { await prepareInputOutputTensor( outputTensors[i], outputTensorHandles, inputOutputAllocs, sessionId, outputNamesUTF8Encoded[outputIndices[i]], inputCount + outputIndices[i], enableGraphCapture ); } TRACE_EVENT_END("wasm prepareInputOutputTensor"); for (let i = 0; i < inputCount; i++) { wasm3.setValue(inputValuesOffset + i * ptrSize, inputTensorHandles[i], "*"); wasm3.setValue(inputNamesOffset + i * ptrSize, inputNamesUTF8Encoded[inputIndices[i]], "*"); } for (let i = 0; i < outputCount; i++) { wasm3.setValue(outputValuesOffset + i * ptrSize, outputTensorHandles[i], "*"); wasm3.setValue(outputNamesOffset + i * ptrSize, outputNamesUTF8Encoded[outputIndices[i]], "*"); } if (ioBindingState && !inputOutputBound) { const { handle, outputPreferredLocations, outputPreferredLocationsEncoded } = ioBindingState; if (inputNamesUTF8Encoded.length !== inputCount) { throw new Error( `input count from feeds (${inputCount}) is expected to be always equal to model's input count (${inputNamesUTF8Encoded.length}).` ); } TRACE_EVENT_BEGIN("wasm bindInputsOutputs"); for (let i = 0; i < inputCount; i++) { const index = inputIndices[i]; const errorCode2 = await wasm3._OrtBindInput(handle, inputNamesUTF8Encoded[index], inputTensorHandles[i]); if (errorCode2 !== 0) { checkLastError(`Can't bind input[${i}] for session=${sessionId}.`); } } for (let i = 0; i < outputCount; i++) { const index = outputIndices[i]; const location2 = outputTensors[i]?.[3]; if (location2) { preAllocatedOutputs.push(outputTensorHandles[i]); const errorCode2 = wasm3._OrtBindOutput(handle, outputNamesUTF8Encoded[index], outputTensorHandles[i], 0); if (errorCode2 !== 0) { checkLastError(`Can't bind pre-allocated output[${i}] for session=${sessionId}.`); } } else { const errorCode2 = wasm3._OrtBindOutput( handle, outputNamesUTF8Encoded[index], 0, outputPreferredLocationsEncoded[index] ); if (errorCode2 !== 0) { checkLastError(`Can't bind output[${i}] to ${outputPreferredLocations[i]} for session=${sessionId}.`); } } } TRACE_EVENT_END("wasm bindInputsOutputs"); activeSessions.set(sessionId, [ sessionHandle, inputNamesUTF8Encoded, outputNamesUTF8Encoded, ioBindingState, enableGraphCapture, true ]); } wasm3.jsepOnRunStart?.(sessionHandle); wasm3.webnnOnRunStart?.(sessionHandle); let errorCode; if (ioBindingState) { errorCode = await wasm3._OrtRunWithBinding( sessionHandle, ioBindingState.handle, outputCount, outputValuesOffset, runOptionsHandle ); } else { errorCode = await wasm3._OrtRun( sessionHandle, inputNamesOffset, inputValuesOffset, inputCount, outputNamesOffset, outputCount, outputValuesOffset, runOptionsHandle ); } if (errorCode !== 0) { checkLastError("failed to call OrtRun()."); } const output = []; const outputPromises = []; TRACE_EVENT_BEGIN("wasm ProcessOutputTensor"); for (let i = 0; i < outputCount; i++) { const tensor = Number(wasm3.getValue(outputValuesOffset + i * ptrSize, "*")); if (tensor === outputTensorHandles[i] || preAllocatedOutputs.includes(outputTensorHandles[i])) { output.push(outputTensors[i]); if (tensor !== outputTensorHandles[i]) { if (wasm3._OrtReleaseTensor(tensor) !== 0) { checkLastError("Can't release tensor."); } } continue; } const beforeGetTensorDataStack = wasm3.stackSave(); const tensorDataOffset = wasm3.stackAlloc(4 * ptrSize); let keepOutputTensor = false; let type, dataOffset = 0; try { const errorCode2 = wasm3._OrtGetTensorData( tensor, tensorDataOffset, tensorDataOffset + ptrSize, tensorDataOffset + 2 * ptrSize, tensorDataOffset + 3 * ptrSize ); if (errorCode2 !== 0) { checkLastError(`Can't access output tensor data on index ${i}.`); } const valueType = ptrSize === 4 ? "i32" : "i64"; const dataType = Number(wasm3.getValue(tensorDataOffset, valueType)); dataOffset = wasm3.getValue(tensorDataOffset + ptrSize, "*"); const dimsOffset = wasm3.getValue(tensorDataOffset + ptrSize * 2, "*"); const dimsLength = Number(wasm3.getValue(tensorDataOffset + ptrSize * 3, valueType)); const dims = []; for (let i2 = 0; i2 < dimsLength; i2++) { dims.push(Number(wasm3.getValue(dimsOffset + i2 * ptrSize, valueType))); } if (wasm3._OrtFree(dimsOffset) !== 0) { checkLastError("Can't free memory for tensor dims."); } const size = dims.reduce((a, b) => a * b, 1); type = tensorDataTypeEnumToString(dataType); const preferredLocation = ioBindingState?.outputPreferredLocations[outputIndices[i]]; if (type === "string") { if (preferredLocation === "gpu-buffer" || preferredLocation === "ml-tensor") { throw new Error("String tensor is not supported on GPU."); } const stringData = []; for (let i2 = 0; i2 < size; i2++) { const offset = wasm3.getValue(dataOffset + i2 * ptrSize, "*"); const nextOffset = wasm3.getValue(dataOffset + (i2 + 1) * ptrSize, "*"); const maxBytesToRead = i2 === size - 1 ? void 0 : nextOffset - offset; stringData.push(wasm3.UTF8ToString(offset, maxBytesToRead)); } output.push([type, dims, stringData, "cpu"]); } else { if (preferredLocation === "gpu-buffer" && size > 0) { const getBuffer = false ? wasm3.webgpuGetBuffer : wasm3.jsepGetBuffer; if (!getBuffer) { throw new Error('preferredLocation "gpu-buffer" is not supported without using WebGPU.'); } const gpuBuffer = getBuffer(dataOffset); const bufferSize = calculateTensorSizeInBytes(dataType, size); if (bufferSize === void 0 || !isGpuBufferSupportedType(type)) { throw new Error(`Unsupported data type: ${type}`); } keepOutputTensor = true; if (false) { wasm3.webgpuRegisterBuffer(gpuBuffer, sessionId, dataOffset); const downloadDataFunction = wasm3.webgpuCreateDownloader(gpuBuffer, bufferSize, sessionId); output.push([ type, dims, { gpuBuffer, download: async () => { const arrayBuffer = await downloadDataFunction(); const data = new (tensorTypeToTypedArrayConstructor(type))(arrayBuffer); return data; }, dispose: () => { if (wasm3._OrtReleaseTensor(tensor) !== 0) { checkLastError("Can't release tensor."); } } }, "gpu-buffer" ]); } else { output.push([ type, dims, { gpuBuffer, download: wasm3.jsepCreateDownloader(gpuBuffer, bufferSize, type), dispose: () => { if (wasm3._OrtReleaseTensor(tensor) !== 0) { checkLastError("Can't release tensor."); } } }, "gpu-buffer" ]); } } else if (preferredLocation === "ml-tensor" && size > 0) { const ensureTensor = wasm3.webnnEnsureTensor; const isGraphInputOutputTypeSupported = wasm3.webnnIsGraphInputOutputTypeSupported; if (!ensureTensor || !isGraphInputOutputTypeSupported) { throw new Error('preferredLocation "ml-tensor" is not supported without using WebNN.'); } const tensorSize = calculateTensorSizeInBytes(dataType, size); if (tensorSize === void 0 || !isMLTensorSupportedType(type)) { throw new Error(`Unsupported data type: ${type}`); } if (!isGraphInputOutputTypeSupported(sessionId, type, false)) { throw new Error( `preferredLocation "ml-tensor" for ${type} output is not supported by current WebNN Context.` ); } const mlTensor = await ensureTensor(sessionId, dataOffset, dataType, dims, false); keepOutputTensor = true; output.push([ type, dims, { mlTensor, download: wasm3.webnnCreateMLTensorDownloader(dataOffset, type), dispose: () => { wasm3.webnnReleaseTensorId(dataOffset); wasm3._OrtReleaseTensor(tensor); } }, "ml-tensor" ]); } else if (preferredLocation === "ml-tensor-cpu-output" && size > 0) { const data = wasm3.webnnCreateMLTensorDownloader(dataOffset, type)(); const index = output.length; keepOutputTensor = true; outputPromises.push( (async () => { const result = [index, await data]; wasm3.webnnReleaseTensorId(dataOffset); wasm3._OrtReleaseTensor(tensor); return result; })() ); output.push([type, dims, [], "cpu"]); } else { const typedArrayConstructor = tensorTypeToTypedArrayConstructor(type); const data = new typedArrayConstructor(size); new Uint8Array(data.buffer, data.byteOffset, data.byteLength).set( wasm3.HEAPU8.subarray(dataOffset, dataOffset + data.byteLength) ); output.push([type, dims, data, "cpu"]); } } } finally { wasm3.stackRestore(beforeGetTensorDataStack); if (type === "string" && dataOffset) { wasm3._free(dataOffset); } if (!keepOutputTensor) { wasm3._OrtReleaseTensor(tensor); } } } if (ioBindingState && !enableGraphCapture) { if (wasm3._OrtClearBoundOutputs(ioBindingState.handle) !== 0) { checkLastError("Can't clear bound outputs."); } activeSessions.set(sessionId, [ sessionHandle, inputNamesUTF8Encoded, outputNamesUTF8Encoded, ioBindingState, enableGraphCapture, false ]); } for (const [index, data] of await Promise.all(outputPromises)) { output[index][2] = data; } TRACE_EVENT_END("wasm ProcessOutputTensor"); return output; } finally { wasm3.webnnOnRunEnd?.(sessionHandle); wasm3.stackRestore(beforeRunStack); if (false) { inputTensors.forEach((t) => { if (t && t[3] === "gpu-buffer") { wasm3.webgpuUnregisterBuffer(t[2].gpuBuffer); } }); outputTensors.forEach((t) => { if (t && t[3] === "gpu-buffer") { wasm3.webgpuUnregisterBuffer(t[2].gpuBuffer); } }); } inputTensorHandles.forEach((v) => wasm3._OrtReleaseTensor(v)); outputTensorHandles.forEach((v) => wasm3._OrtReleaseTensor(v)); inputOutputAllocs.forEach((p) => wasm3._free(p)); if (runOptionsHandle !== 0) { wasm3._OrtReleaseRunOptions(runOptionsHandle); } runOptionsAllocs.forEach((p) => wasm3._free(p)); } }; endProfiling = (sessionId) => { const wasm3 = getInstance(); const session = activeSessions.get(sessionId); if (!session) { throw new Error("invalid session id"); } const sessionHandle = session[0]; const profileFileName = wasm3._OrtEndProfiling(sessionHandle); if (profileFileName === 0) { checkLastError("Can't get an profile file name."); } wasm3._OrtFree(profileFileName); }; extractTransferableBuffers = (tensors) => { const buffers = []; for (const tensor of tensors) { const data = tensor[2]; if (!Array.isArray(data) && "buffer" in data) { buffers.push(data.buffer); } } return buffers; }; } }); // web/lib/wasm/proxy-wrapper.ts var isProxy, proxyWorker, initializing2, initialized2, aborted2, temporaryObjectUrl, initWasmCallbacks, queuedCallbacks, enqueueCallbacks, ensureWorker, onProxyWorkerMessage, initializeWebAssemblyAndOrtRuntime, initializeOrtEp, copyFromExternalBuffer2, createSession2, releaseSession2, run2, endProfiling2; var init_proxy_wrapper = __esm({ "web/lib/wasm/proxy-wrapper.ts"() { "use strict"; init_esm(); init_wasm_core_impl(); init_wasm_factory(); init_wasm_utils_import(); isProxy = () => !!env2.wasm.proxy && typeof document !== "undefined"; initializing2 = false; initialized2 = false; aborted2 = false; queuedCallbacks = /* @__PURE__ */ new Map(); enqueueCallbacks = (type, callbacks) => { const queue = queuedCallbacks.get(type); if (queue) { queue.push(callbacks); } else { queuedCallbacks.set(type, [callbacks]); } }; ensureWorker = () => { if (initializing2 || !initialized2 || aborted2 || !proxyWorker) { throw new Error("worker not ready"); } }; onProxyWorkerMessage = (ev) => { switch (ev.data.type) { case "init-wasm": initializing2 = false; if (ev.data.err) { aborted2 = true; initWasmCallbacks[1](ev.data.err); } else { initialized2 = true; initWasmCallbacks[0](); } if (temporaryObjectUrl) { URL.revokeObjectURL(temporaryObjectUrl); temporaryObjectUrl = void 0; } break; case "init-ep": case "copy-from": case "create": case "release": case "run": case "end-profiling": { const callbacks = queuedCallbacks.get(ev.data.type); if (ev.data.err) { callbacks.shift()[1](ev.data.err); } else { callbacks.shift()[0](ev.data.out); } break; } default: } }; initializeWebAssemblyAndOrtRuntime = async () => { if (initialized2) { return; } if (initializing2) { throw new Error("multiple calls to 'initWasm()' detected."); } if (aborted2) { throw new Error("previous call to 'initWasm()' failed."); } initializing2 = true; if (isProxy()) { return new Promise((resolve, reject) => { proxyWorker?.terminate(); void importProxyWorker().then(([objectUrl, worker]) => { try { proxyWorker = worker; proxyWorker.onerror = (ev) => reject(ev); proxyWorker.onmessage = onProxyWorkerMessage; initWasmCallbacks = [resolve, reject]; const message = { type: "init-wasm", in: env2 }; if (!message.in.wasm.wasmPaths && objectUrl) { const inferredWasmPathPrefix = inferWasmPathPrefixFromScriptSrc(); if (inferredWasmPathPrefix) { message.in.wasm.wasmPaths = inferredWasmPathPrefix; } } if (false) { message.in.wasm.wasmPaths = { wasm: true ? new URL("ort-wasm-simd-threaded.jsep.wasm", void 0).href : false ? new URL("ort-wasm-simd-threaded.jspi.wasm", void 0).href : false ? new URL("ort-wasm-simd-threaded.asyncify.wasm", void 0).href : new URL("ort-wasm-simd-threaded.wasm", void 0).href }; } proxyWorker.postMessage(message); temporaryObjectUrl = objectUrl; } catch (e) { reject(e); } }, reject); }); } else { try { await initializeWebAssembly(env2.wasm); await initRuntime(env2); initialized2 = true; } catch (e) { aborted2 = true; throw e; } finally { initializing2 = false; } } }; initializeOrtEp = async (epName) => { if (isProxy()) { ensureWorker(); return new Promise((resolve, reject) => { enqueueCallbacks("init-ep", [resolve, reject]); const message = { type: "init-ep", in: { epName, env: env2 } }; proxyWorker.postMessage(message); }); } else { await initEp(env2, epName); } }; copyFromExternalBuffer2 = async (buffer) => { if (isProxy()) { ensureWorker(); return new Promise((resolve, reject) => { enqueueCallbacks("copy-from", [resolve, reject]); const message = { type: "copy-from", in: { buffer } }; proxyWorker.postMessage(message, [buffer.buffer]); }); } else { return copyFromExternalBuffer(buffer); } }; createSession2 = async (model, options) => { if (isProxy()) { if (options?.preferredOutputLocation) { throw new Error('session option "preferredOutputLocation" is not supported for proxy.'); } ensureWorker(); return new Promise((resolve, reject) => { enqueueCallbacks("create", [resolve, reject]); const message = { type: "create", in: { model, options: { ...options } } }; const transferable = []; if (model instanceof Uint8Array) { transferable.push(model.buffer); } proxyWorker.postMessage(message, transferable); }); } else { return createSession(model, options); } }; releaseSession2 = async (sessionId) => { if (isProxy()) { ensureWorker(); return new Promise((resolve, reject) => { enqueueCallbacks("release", [resolve, reject]); const message = { type: "release", in: sessionId }; proxyWorker.postMessage(message); }); } else { releaseSession(sessionId); } }; run2 = async (sessionId, inputIndices, inputs, outputIndices, outputs, options) => { if (isProxy()) { if (inputs.some((t) => t[3] !== "cpu")) { throw new Error("input tensor on GPU is not supported for proxy."); } if (outputs.some((t) => t)) { throw new Error("pre-allocated output tensor is not supported for proxy."); } ensureWorker(); return new Promise((resolve, reject) => { enqueueCallbacks("run", [resolve, reject]); const serializableInputs = inputs; const message = { type: "run", in: { sessionId, inputIndices, inputs: serializableInputs, outputIndices, options } }; proxyWorker.postMessage(message, extractTransferableBuffers(serializableInputs)); }); } else { return run(sessionId, inputIndices, inputs, outputIndices, outputs, options); } }; endProfiling2 = async (sessionId) => { if (isProxy()) { ensureWorker(); return new Promise((resolve, reject) => { enqueueCallbacks("end-profiling", [resolve, reject]); const message = { type: "end-profiling", in: sessionId }; proxyWorker.postMessage(message); }); } else { endProfiling(sessionId); } }; } }); // web/lib/wasm/session-handler-inference.ts var encodeTensorMetadata, decodeTensorMetadata, OnnxruntimeWebAssemblySessionHandler; var init_session_handler_inference2 = __esm({ "web/lib/wasm/session-handler-inference.ts"() { "use strict"; init_esm(); init_proxy_wrapper(); init_wasm_common(); init_wasm_utils_env(); init_wasm_utils_load_file(); encodeTensorMetadata = (tensor, getName) => { switch (tensor.location) { case "cpu": return [tensor.type, tensor.dims, tensor.data, "cpu"]; case "gpu-buffer": return [tensor.type, tensor.dims, { gpuBuffer: tensor.gpuBuffer }, "gpu-buffer"]; case "ml-tensor": return [tensor.type, tensor.dims, { mlTensor: tensor.mlTensor }, "ml-tensor"]; default: throw new Error(`invalid data location: ${tensor.location} for ${getName()}`); } }; decodeTensorMetadata = (tensor) => { switch (tensor[3]) { case "cpu": return new Tensor2(tensor[0], tensor[2], tensor[1]); case "gpu-buffer": { const dataType = tensor[0]; if (!isGpuBufferSupportedType(dataType)) { throw new Error(`not supported data type: ${dataType} for deserializing GPU tensor`); } const { gpuBuffer, download, dispose } = tensor[2]; return Tensor2.fromGpuBuffer(gpuBuffer, { dataType, dims: tensor[1], download, dispose }); } case "ml-tensor": { const dataType = tensor[0]; if (!isMLTensorSupportedType(dataType)) { throw new Error(`not supported data type: ${dataType} for deserializing MLTensor tensor`); } const { mlTensor, download, dispose } = tensor[2]; return Tensor2.fromMLTensor(mlTensor, { dataType, dims: tensor[1], download, dispose }); } default: throw new Error(`invalid data location: ${tensor[3]}`); } }; OnnxruntimeWebAssemblySessionHandler = class { async fetchModelAndCopyToWasmMemory(path) { return copyFromExternalBuffer2(await loadFile(path)); } async loadModel(pathOrBuffer, options) { TRACE_FUNC_BEGIN(); let model; if (typeof pathOrBuffer === "string") { if (isNode) { model = await loadFile(pathOrBuffer); } else { model = await this.fetchModelAndCopyToWasmMemory(pathOrBuffer); } } else { model = pathOrBuffer; } [this.sessionId, this.inputNames, this.outputNames, this.inputMetadata, this.outputMetadata] = await createSession2( model, options ); TRACE_FUNC_END(); } async dispose() { return releaseSession2(this.sessionId); } async run(feeds, fetches, options) { TRACE_FUNC_BEGIN(); const inputArray = []; const inputIndices = []; Object.entries(feeds).forEach((kvp) => { const name2 = kvp[0]; const tensor = kvp[1]; const index = this.inputNames.indexOf(name2); if (index === -1) { throw new Error(`invalid input '${name2}'`); } inputArray.push(tensor); inputIndices.push(index); }); const outputArray = []; const outputIndices = []; Object.entries(fetches).forEach((kvp) => { const name2 = kvp[0]; const tensor = kvp[1]; const index = this.outputNames.indexOf(name2); if (index === -1) { throw new Error(`invalid output '${name2}'`); } outputArray.push(tensor); outputIndices.push(index); }); const inputs = inputArray.map( (t, i) => encodeTensorMetadata(t, () => `input "${this.inputNames[inputIndices[i]]}"`) ); const outputs = outputArray.map( (t, i) => t ? encodeTensorMetadata(t, () => `output "${this.outputNames[outputIndices[i]]}"`) : null ); const results = await run2(this.sessionId, inputIndices, inputs, outputIndices, outputs, options); const resultMap = {}; for (let i = 0; i < results.length; i++) { resultMap[this.outputNames[outputIndices[i]]] = outputArray[i] ?? decodeTensorMetadata(results[i]); } TRACE_FUNC_END(); return resultMap; } startProfiling() { } endProfiling() { void endProfiling2(this.sessionId); } }; } }); // web/lib/backend-wasm.ts var backend_wasm_exports = {}; __export(backend_wasm_exports, { OnnxruntimeWebAssemblyBackend: () => OnnxruntimeWebAssemblyBackend, initializeFlags: () => initializeFlags, wasmBackend: () => wasmBackend }); var initializeFlags, OnnxruntimeWebAssemblyBackend, wasmBackend; var init_backend_wasm = __esm({ "web/lib/backend-wasm.ts"() { "use strict"; init_esm(); init_proxy_wrapper(); init_session_handler_inference2(); initializeFlags = () => { if (typeof env2.wasm.initTimeout !== "number" || env2.wasm.initTimeout < 0) { env2.wasm.initTimeout = 0; } const simd = env2.wasm.simd; if (typeof simd !== "boolean" && simd !== void 0 && simd !== "fixed" && simd !== "relaxed") { console.warn( `Property "env.wasm.simd" is set to unknown value "${simd}". Reset it to \`false\` and ignore SIMD feature checking.` ); env2.wasm.simd = false; } if (typeof env2.wasm.proxy !== "boolean") { env2.wasm.proxy = false; } if (typeof env2.wasm.trace !== "boolean") { env2.wasm.trace = false; } if (typeof env2.wasm.numThreads !== "number" || !Number.isInteger(env2.wasm.numThreads) || env2.wasm.numThreads <= 0) { if (typeof self !== "undefined" && !self.crossOriginIsolated) { env2.wasm.numThreads = 1; } else { const numCpuLogicalCores = typeof navigator === "undefined" ? __require("node:os").cpus().length : navigator.hardwareConcurrency; env2.wasm.numThreads = Math.min(4, Math.ceil((numCpuLogicalCores || 1) / 2)); } } }; OnnxruntimeWebAssemblyBackend = class { /** * This function initializes the WebAssembly backend. * * This function will be called only once for each backend name. It will be called the first time when * `ort.InferenceSession.create()` is called with a registered backend name. * * @param backendName - the registered backend name. */ async init(backendName) { initializeFlags(); await initializeWebAssemblyAndOrtRuntime(); await initializeOrtEp(backendName); } async createInferenceSessionHandler(pathOrBuffer, options) { const handler = new OnnxruntimeWebAssemblySessionHandler(); await handler.loadModel(pathOrBuffer, options); return handler; } }; wasmBackend = new OnnxruntimeWebAssemblyBackend(); } }); // web/lib/index.ts var index_exports = {}; __export(index_exports, { InferenceSession: () => InferenceSession2, TRACE: () => TRACE, TRACE_EVENT_BEGIN: () => TRACE_EVENT_BEGIN, TRACE_EVENT_END: () => TRACE_EVENT_END, TRACE_FUNC_BEGIN: () => TRACE_FUNC_BEGIN, TRACE_FUNC_END: () => TRACE_FUNC_END, Tensor: () => Tensor2, default: () => index_default, env: () => env2, registerBackend: () => registerBackend }); init_esm(); init_esm(); init_esm(); // web/lib/version.ts var version2 = "1.26.0"; // web/lib/index.ts var index_default = esm_exports; if (true) { const onnxjsBackend2 = (init_backend_onnxjs(), __toCommonJS(backend_onnxjs_exports)).onnxjsBackend; registerBackend("webgl", onnxjsBackend2, -10); } if (false) { throw new Error( "The current build is specified to enable both JSEP and WebGPU EP. This is not a valid configuration. JSEP and WebGPU EPs cannot be enabled at the same time." ); } if (false) { throw new Error( "The current build is specified to enable WebNN EP without JSEP or WebGPU EP. This is not a valid configuration. WebNN EP requires either JSEP or WebGPU EP to be enabled." ); } if (true) { const wasmBackend2 = (init_backend_wasm(), __toCommonJS(backend_wasm_exports)).wasmBackend; if (true) { registerBackend("webgpu", wasmBackend2, 5); } if (true) { registerBackend("webnn", wasmBackend2, 5); } registerBackend("cpu", wasmBackend2, 10); registerBackend("wasm", wasmBackend2, 10); } Object.defineProperty(env2.versions, "web", { value: version2, enumerable: true }); return __toCommonJS(index_exports); })(); /** * @license * Copyright 2021 Google LLC. All Rights Reserved. * 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. * ============================================================================= */ /** * @license * Copyright 2020 Google LLC. All Rights Reserved. * 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. * ============================================================================= */ /** * @license * Copyright 2019 Google LLC. All Rights Reserved. * 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. * ============================================================================= */ /*! 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 *) */ typeof exports=="object"&&typeof module=="object"&&(module.exports=ort); //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vY29tbW9uL2xpYi9iYWNrZW5kLWltcGwudHMiLCAiLi4vLi4vY29tbW9uL2xpYi9iYWNrZW5kLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvdmVyc2lvbi50cyIsICIuLi8uLi9jb21tb24vbGliL2Vudi1pbXBsLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvZW52LnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvdGVuc29yLWNvbnZlcnNpb24taW1wbC50cyIsICIuLi8uLi9jb21tb24vbGliL3RlbnNvci1mYWN0b3J5LWltcGwudHMiLCAiLi4vLi4vY29tbW9uL2xpYi90ZW5zb3ItaW1wbC10eXBlLW1hcHBpbmcudHMiLCAiLi4vLi4vY29tbW9uL2xpYi90ZW5zb3ItdXRpbHMtaW1wbC50cyIsICIuLi8uLi9jb21tb24vbGliL3RlbnNvci1pbXBsLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvdGVuc29yLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvdHJhY2UudHMiLCAiLi4vLi4vY29tbW9uL2xpYi9pbmZlcmVuY2Utc2Vzc2lvbi1pbXBsLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvaW5mZXJlbmNlLXNlc3Npb24udHMiLCAiLi4vLi4vY29tbW9uL2xpYi90ZW5zb3ItY29udmVyc2lvbi50cyIsICIuLi8uLi9jb21tb24vbGliL3RlbnNvci1mYWN0b3J5LnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvb25ueC1tb2RlbC50cyIsICIuLi8uLi9jb21tb24vbGliL29ubngtdmFsdWUudHMiLCAiLi4vLi4vY29tbW9uL2xpYi9pbmRleC50cyIsICIuLi9saWIvb25ueGpzL2luc3RydW1lbnQudHMiLCAiLi4vbGliL29ubnhqcy9vcHNldC50cyIsICIuLi9ub2RlX21vZHVsZXMvZ3VpZC10eXBlc2NyaXB0L2Rpc3QvZ3VpZC5qcyIsICIuLi9ub2RlX21vZHVsZXMvbG9uZy9pbmRleC5qcyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2FyZy10eXBlLnRzIiwgIi4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy9jb25zdGFudHMuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2ZsYXRidWZmZXJzL2pzL3V0aWxzLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy9lbmNvZGluZy5qcyIsICIuLi9ub2RlX21vZHVsZXMvZmxhdGJ1ZmZlcnMvanMvYnl0ZS1idWZmZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2ZsYXRidWZmZXJzL2pzL2J1aWxkZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2ZsYXRidWZmZXJzL2pzL2ZsYXRidWZmZXJzLmpzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvYXJnLXR5cGUtYW5kLWluZGV4LnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvYXR0cmlidXRlLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ub2RlLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ub2RlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZWRnZS1lbmQudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ub2RlLWVkZ2UudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ub2Rlcy10by1vcHRpbWl6ZS1pbmRpY2VzLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvcnVudGltZS1vcHRpbWl6YXRpb24tcmVjb3JkLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvcnVudGltZS1vcHRpbWl6YXRpb24tcmVjb3JkLWNvbnRhaW5lci1lbnRyeS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9ucy50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3RlbnNvci1kYXRhLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy90ZW5zb3IudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9zcGFyc2UtdGVuc29yLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbWFwLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9zZXF1ZW5jZS10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZGltZW5zaW9uLXZhbHVlLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9kaW1lbnNpb24tdmFsdWUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9kaW1lbnNpb24udHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9zaGFwZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3RlbnNvci10eXBlLWFuZC1zaGFwZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3R5cGUtaW5mby12YWx1ZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3R5cGUtaW5mby50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3ZhbHVlLWluZm8udHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ncmFwaC50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2F0dHJpYnV0ZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQta2VybmVsLWNyZWF0ZS1pbmZvcy50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQtbm9kZS1pbmRleC1hbmQta2VybmVsLWRlZi1oYXNoLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZGVwcmVjYXRlZC1zdWItZ3JhcGgtc2Vzc2lvbi1zdGF0ZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQtc2Vzc2lvbi1zdGF0ZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2tlcm5lbC10eXBlLXN0ci1hcmdzLWVudHJ5LnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvb3AtaWQta2VybmVsLXR5cGUtc3RyLWFyZ3MtZW50cnkudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9rZXJuZWwtdHlwZS1zdHItcmVzb2x2ZXIudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9vcGVyYXRvci1zZXQtaWQudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9zdHJpbmctc3RyaW5nLWVudHJ5LnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbW9kZWwudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9pbmZlcmVuY2Utc2Vzc2lvbi50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkLnRzIiwgIi4uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy9hc3Byb21pc2UvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL2Jhc2U2NC9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvZXZlbnRlbWl0dGVyL2luZGV4LmpzIiwgIi4uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy9mbG9hdC9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvaW5xdWlyZS9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvdXRmOC9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvcG9vbC9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvdXRpbC9sb25nYml0cy5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvdXRpbC9taW5pbWFsLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy93cml0ZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3dyaXRlcl9idWZmZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3JlYWRlci5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvcmVhZGVyX2J1ZmZlci5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvcnBjL3NlcnZpY2UuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3JwYy5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvcm9vdHMuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL2luZGV4LW1pbmltYWwuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvbWluaW1hbC5qcyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvcHJvdG9idWYvb25ueC5qcyIsICIuLi9saWIvb25ueGpzL3V0aWwudHMiLCAiLi4vbGliL29ubnhqcy90ZW5zb3IudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLXNvdXJjZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3R5cGVzLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvdXRpbHMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcGFja2luZy11dGlscy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9wYWNrLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Jlc2hhcGUtcGFja2VkLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3VpbnQ4LWVuY29kZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy91bnBhY2sudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90ZXh0dXJlLWRhdGEtZW5jb2Rlci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3RleHR1cmUtbGF5b3V0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvaW5mZXJlbmNlLWhhbmRsZXIudHMiLCAiLi4vbGliL29ubnhqcy9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXkudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvYmF0Y2gtbm9ybWFsaXphdGlvbi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtZGVmaW5pdGlvbnMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvYmluYXJ5LW9wLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2Nhc3QudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29uY2F0LXBhY2tlZC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb25jYXQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdW5hcnktb3AudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZnVzZS11dGlscy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb252LWdyb3VwZWQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvaW0yY29sLXBhY2sudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvbWF0bXVsLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL21hdG11bC1wYWNrLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2NvbnYtcGFjay50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9pbTJjb2wudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZG90LXByb2R1Y3QudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29udi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb252LXRyYW5zcG9zZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy90cmFuc3Bvc2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZGVwdGgtdG8tc3BhY2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZmxhdHRlbi50cyIsICIuLi9saWIvb25ueGpzL29wZXJhdG9ycy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9nYXRoZXIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZ2VtbS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9pbWFnZS1zY2FsZXIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvaW5zdGFuY2Utbm9ybWFsaXphdGlvbi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9scm4udHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcGFkLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Bvb2wudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcmVkdWNlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Jlc2hhcGUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdXBzYW1wbGUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcmVzaXplLXBhY2tlZC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zaGFwZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zbGljZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zb2Z0bWF4LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3NwbGl0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3NxdWVlemUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc3VtLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3RpbGUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdW5zcXVlZXplLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3AtcmVzb2x2ZS1ydWxlcy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtZnVuY3Rpb24taW5saW5lci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1jb29yZGluYXRlLWxpYi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtZW5jb2RpbmctbGliLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1mcmFnY29sb3ItbGliLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1zaGFwZS11dGlscy1saWIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLXZlYy1saWIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLXJlZ2lzdGVyZWQtbGlicy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtcHJlcHJvY2Vzc29yLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvcHJvZ3JhbS1tYW5hZ2VyLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvdGV4dHVyZS1tYW5hZ2VyLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvc2Vzc2lvbi1oYW5kbGVyLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvd2ViZ2wtY29udGV4dC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3dlYmdsLWNvbnRleHQtZmFjdG9yeS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL2JhY2tlbmQtd2ViZ2wudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kLnRzIiwgIi4uL2xpYi9vbm54anMvZXhlY3V0aW9uLXBsYW4udHMiLCAiLi4vbGliL29ubnhqcy9hdHRyaWJ1dGUudHMiLCAiLi4vbGliL29ubnhqcy9ncmFwaC50cyIsICIuLi9saWIvb25ueGpzL21vZGVsLnRzIiwgIi4uL2xpYi9vbm54anMvc2Vzc2lvbi50cyIsICIuLi9saWIvb25ueGpzL3Nlc3Npb24taGFuZGxlci1pbmZlcmVuY2UudHMiLCAiLi4vbGliL2JhY2tlbmQtb25ueGpzLnRzIiwgIi4uL2xpYi93YXNtL3dhc20tdXRpbHMtZW52LnRzIiwgIi4uL2xpYi93YXNtL3Byb3h5LXdvcmtlci9tYWluLnRzIiwgIi4uL2xpYi93YXNtL3dhc20tdXRpbHMtaW1wb3J0LnRzIiwgIi4uL2xpYi93YXNtL3dhc20tZmFjdG9yeS50cyIsICIuLi9saWIvd2FzbS93YXNtLXV0aWxzLnRzIiwgIi4uL2xpYi93YXNtL3J1bi1vcHRpb25zLnRzIiwgIi4uL2xpYi93YXNtL3Nlc3Npb24tb3B0aW9ucy50cyIsICIuLi9saWIvd2FzbS93YXNtLWNvbW1vbi50cyIsICIuLi9saWIvd2FzbS93YXNtLXV0aWxzLWxvYWQtZmlsZS50cyIsICIuLi9saWIvd2FzbS9qc2VwL2xvZy50cyIsICIuLi9saWIvd2FzbS9qc2VwL3V0aWwudHMiLCAiLi4vbGliL3dhc20vanNlcC90ZW5zb3Itdmlldy50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYm5uL3RlbnNvci1tYW5hZ2VyLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvYmFja2VuZC13ZWJubi50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS90eXBlcy50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9ncHUtZGF0YS1tYW5hZ2VyLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvY29tbW9uLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy90cmFuc3Bvc2UudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL3JlZHVjZS1zaGFyZWQudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL3JlZHVjZS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvYXJnbWlubWF4LnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9hdHRlbnRpb24udHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2JhdGNoLW5vcm0udHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2JpYXMtYWRkLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy91bmFyeS1vcC50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvYmlhcy1zcGxpdC1nZWx1LnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9iaW5hcnktb3AudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2NvbmNhdC50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvZnVzZS11dGlscy50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvM3JkLXBhcnR5L2FjdGl2YXRpb25fdXRpbC50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvM3JkLXBhcnR5L2NvbnZfdXRpbC50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvbWF0bXVsLXNoYWRlcnMudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzLzNyZC1wYXJ0eS9tYXRtdWxfcGFja2VkX3dlYmdwdS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvM3JkLXBhcnR5L2NvbnYyZF9tbV93ZWJncHUudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzLzNyZC1wYXJ0eS9jb252M2RfbmFpdmVfd2ViZ3B1LnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9jb252LWdyb3VwZWQudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2NvbnYudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzLzNyZC1wYXJ0eS9jb252X2JhY2twcm9wX3dlYmdwdS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvY29udi10cmFuc3Bvc2UudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2N1bXN1bS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvZGVwdGgtdG8tc3BhY2UudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2VpbnN1bS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvZXhwYW5kLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9mYXN0LWdlbHUudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2dhdGhlci50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvZ2F0aGVyLW5kLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9nYXRoZXItYmxvY2stcXVhbnRpemVkLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9nYXRoZXItZWxlbWVudHMudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2dlbW0udHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2dyaWQtc2FtcGxlLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9tdWx0aWhlYWQtYXR0ZW50aW9uLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9zcGxpdC50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvcm90YXJ5LWVtYmVkZGluZy50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvZ3JvdXAtcXVlcnktYXR0ZW50aW9uLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9pbnN0YW5jZS1ub3JtLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9sYXllci1ub3JtLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9tYXRtdWwudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL21hdG11bG5iaXRzLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9wYWQudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL3Bvb2wudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL3F1YW50aXplLWxpbmVhci50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvcmFuZ2UudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL3NjYXR0ZXItbmQudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL3Jlc2l6ZS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvc2tpcC1sYXllci1ub3JtLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9zbGljZS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvc29mdG1heC50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvdGlsZS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvd2hlcmUudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3AtcmVzb2x2ZS1ydWxlcy50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9wcm9ncmFtLW1hbmFnZXIudHMiLCAiLi4vbGliL3dhc20vanNlcC9iYWNrZW5kLXdlYmdwdS50cyIsICIuLi9saWIvd2FzbS9qc2VwL2luaXQudHMiLCAiLi4vbGliL3dhc20vd2FzbS1jb3JlLWltcGwudHMiLCAiLi4vbGliL3dhc20vcHJveHktd3JhcHBlci50cyIsICIuLi9saWIvd2FzbS9zZXNzaW9uLWhhbmRsZXItaW5mZXJlbmNlLnRzIiwgIi4uL2xpYi9iYWNrZW5kLXdhc20udHMiLCAiLi4vbGliL2luZGV4LnRzIiwgIi4uL2xpYi92ZXJzaW9uLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQmFja2VuZCB9IGZyb20gJy4vYmFja2VuZC5qcyc7XG5pbXBvcnQgeyBJbmZlcmVuY2VTZXNzaW9uIH0gZnJvbSAnLi9pbmZlcmVuY2Utc2Vzc2lvbi5qcyc7XG5cbmludGVyZmFjZSBCYWNrZW5kSW5mbyB7XG4gIGJhY2tlbmQ6IEJhY2tlbmQ7XG4gIHByaW9yaXR5OiBudW1iZXI7XG5cbiAgaW5pdFByb21pc2U/OiBQcm9taXNlPHZvaWQ+O1xuICBpbml0aWFsaXplZD86IGJvb2xlYW47XG4gIGFib3J0ZWQ/OiBib29sZWFuO1xuICBlcnJvcj86IHN0cmluZztcbn1cblxuY29uc3QgYmFja2VuZHM6IE1hcDxzdHJpbmcsIEJhY2tlbmRJbmZvPiA9IG5ldyBNYXAoKTtcbmNvbnN0IGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eTogc3RyaW5nW10gPSBbXTtcblxuLyoqXG4gKiBSZWdpc3RlciBhIGJhY2tlbmQuXG4gKlxuICogQHBhcmFtIG5hbWUgLSB0aGUgbmFtZSBhcyBhIGtleSB0byBsb29rdXAgYXMgYW4gZXhlY3V0aW9uIHByb3ZpZGVyLlxuICogQHBhcmFtIGJhY2tlbmQgLSB0aGUgYmFja2VuZCBvYmplY3QuXG4gKiBAcGFyYW0gcHJpb3JpdHkgLSBhbiBpbnRlZ2VyIGluZGljYXRpbmcgdGhlIHByaW9yaXR5IG9mIHRoZSBiYWNrZW5kLiBIaWdoZXIgbnVtYmVyIG1lYW5zIGhpZ2hlciBwcmlvcml0eS4gaWYgcHJpb3JpdHlcbiAqIDwgMCwgaXQgd2lsbCBiZSBjb25zaWRlcmVkIGFzIGEgJ2JldGEnIHZlcnNpb24gYW5kIHdpbGwgbm90IGJlIHVzZWQgYXMgYSBmYWxsYmFjayBiYWNrZW5kIGJ5IGRlZmF1bHQuXG4gKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgY29uc3QgcmVnaXN0ZXJCYWNrZW5kID0gKG5hbWU6IHN0cmluZywgYmFja2VuZDogQmFja2VuZCwgcHJpb3JpdHk6IG51bWJlcik6IHZvaWQgPT4ge1xuICBpZiAoYmFja2VuZCAmJiB0eXBlb2YgYmFja2VuZC5pbml0ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBiYWNrZW5kLmNyZWF0ZUluZmVyZW5jZVNlc3Npb25IYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY29uc3QgY3VycmVudEJhY2tlbmQgPSBiYWNrZW5kcy5nZXQobmFtZSk7XG4gICAgaWYgKGN1cnJlbnRCYWNrZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGJhY2tlbmRzLnNldChuYW1lLCB7IGJhY2tlbmQsIHByaW9yaXR5IH0pO1xuICAgIH0gZWxzZSBpZiAoY3VycmVudEJhY2tlbmQucHJpb3JpdHkgPiBwcmlvcml0eSkge1xuICAgICAgLy8gc2FtZSBuYW1lIGlzIGFscmVhZHkgcmVnaXN0ZXJlZCB3aXRoIGEgaGlnaGVyIHByaW9yaXR5LiBza2lwIHJlZ2lzdGVyYXRpb24uXG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmIChjdXJyZW50QmFja2VuZC5wcmlvcml0eSA9PT0gcHJpb3JpdHkpIHtcbiAgICAgIGlmIChjdXJyZW50QmFja2VuZC5iYWNrZW5kICE9PSBiYWNrZW5kKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgY2Fubm90IHJlZ2lzdGVyIGJhY2tlbmQgXCIke25hbWV9XCIgdXNpbmcgcHJpb3JpdHkgJHtwcmlvcml0eX1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocHJpb3JpdHkgPj0gMCkge1xuICAgICAgY29uc3QgaSA9IGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eS5pbmRleE9mKG5hbWUpO1xuICAgICAgaWYgKGkgIT09IC0xKSB7XG4gICAgICAgIGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eS5zcGxpY2UoaSwgMSk7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChiYWNrZW5kcy5nZXQoYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5W2ldKSEucHJpb3JpdHkgPD0gcHJpb3JpdHkpIHtcbiAgICAgICAgICBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHkuc3BsaWNlKGksIDAsIG5hbWUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5LnB1c2gobmFtZSk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ25vdCBhIHZhbGlkIGJhY2tlbmQnKTtcbn07XG5cbi8qKlxuICogVHJ5IHRvIHJlc29sdmUgYW5kIGluaXRpYWxpemUgYSBiYWNrZW5kLlxuICpcbiAqIEBwYXJhbSBiYWNrZW5kTmFtZSAtIHRoZSBuYW1lIG9mIHRoZSBiYWNrZW5kLlxuICogQHJldHVybnMgdGhlIGJhY2tlbmQgaW5zdGFuY2UgaWYgcmVzb2x2ZWQgYW5kIGluaXRpYWxpemVkIHN1Y2Nlc3NmdWxseSwgb3IgYW4gZXJyb3IgbWVzc2FnZSBpZiBmYWlsZWQuXG4gKi9cbmNvbnN0IHRyeVJlc29sdmVBbmRJbml0aWFsaXplQmFja2VuZCA9IGFzeW5jIChiYWNrZW5kTmFtZTogc3RyaW5nKTogUHJvbWlzZTxCYWNrZW5kIHwgc3RyaW5nPiA9PiB7XG4gIGNvbnN0IGJhY2tlbmRJbmZvID0gYmFja2VuZHMuZ2V0KGJhY2tlbmROYW1lKTtcbiAgaWYgKCFiYWNrZW5kSW5mbykge1xuICAgIHJldHVybiAnYmFja2VuZCBub3QgZm91bmQuJztcbiAgfVxuXG4gIGlmIChiYWNrZW5kSW5mby5pbml0aWFsaXplZCkge1xuICAgIHJldHVybiBiYWNrZW5kSW5mby5iYWNrZW5kO1xuICB9IGVsc2UgaWYgKGJhY2tlbmRJbmZvLmFib3J0ZWQpIHtcbiAgICByZXR1cm4gYmFja2VuZEluZm8uZXJyb3IhO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGlzSW5pdGlhbGl6aW5nID0gISFiYWNrZW5kSW5mby5pbml0UHJvbWlzZTtcbiAgICB0cnkge1xuICAgICAgaWYgKCFpc0luaXRpYWxpemluZykge1xuICAgICAgICBiYWNrZW5kSW5mby5pbml0UHJvbWlzZSA9IGJhY2tlbmRJbmZvLmJhY2tlbmQuaW5pdChiYWNrZW5kTmFtZSk7XG4gICAgICB9XG4gICAgICBhd2FpdCBiYWNrZW5kSW5mby5pbml0UHJvbWlzZTtcbiAgICAgIGJhY2tlbmRJbmZvLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBiYWNrZW5kSW5mby5iYWNrZW5kO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmICghaXNJbml0aWFsaXppbmcpIHtcbiAgICAgICAgYmFja2VuZEluZm8uZXJyb3IgPSBgJHtlfWA7XG4gICAgICAgIGJhY2tlbmRJbmZvLmFib3J0ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhY2tlbmRJbmZvLmVycm9yITtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZGVsZXRlIGJhY2tlbmRJbmZvLmluaXRQcm9taXNlO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBSZXNvbHZlIGV4ZWN1dGlvbiBwcm92aWRlcnMgZnJvbSB0aGUgc3BlY2lmaWMgc2Vzc2lvbiBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gdGhlIHNlc3Npb24gb3B0aW9ucyBvYmplY3QuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHR1cGxlIG9mIGFuIGluaXRpYWxpemVkIGJhY2tlbmQgaW5zdGFuY2UgYW5kIGEgc2Vzc2lvbiBvcHRpb25zIG9iamVjdCB3aXRoXG4gKiBmaWx0ZXJlZCBFUCBsaXN0LlxuICpcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGNvbnN0IHJlc29sdmVCYWNrZW5kQW5kRXhlY3V0aW9uUHJvdmlkZXJzID0gYXN5bmMgKFxuICBvcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLFxuKTogUHJvbWlzZTxbYmFja2VuZDogQmFja2VuZCwgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9uc10+ID0+IHtcbiAgLy8gZXh0cmFjdCBiYWNrZW5kIGhpbnRzIGZyb20gc2Vzc2lvbiBvcHRpb25zXG4gIGNvbnN0IGVwcyA9IG9wdGlvbnMuZXhlY3V0aW9uUHJvdmlkZXJzIHx8IFtdO1xuICBjb25zdCBiYWNrZW5kSGludHMgPSBlcHMubWFwKChpKSA9PiAodHlwZW9mIGkgPT09ICdzdHJpbmcnID8gaSA6IGkubmFtZSkpO1xuICBjb25zdCBiYWNrZW5kTmFtZXMgPSBiYWNrZW5kSGludHMubGVuZ3RoID09PSAwID8gYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5IDogYmFja2VuZEhpbnRzO1xuXG4gIC8vIHRyeSB0byByZXNvbHZlIGFuZCBpbml0aWFsaXplIGFsbCByZXF1ZXN0ZWQgYmFja2VuZHNcbiAgbGV0IGJhY2tlbmQ6IEJhY2tlbmQgfCB1bmRlZmluZWQ7XG4gIGNvbnN0IGVycm9ycyA9IFtdO1xuICBjb25zdCBhdmFpbGFibGVCYWNrZW5kTmFtZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgZm9yIChjb25zdCBiYWNrZW5kTmFtZSBvZiBiYWNrZW5kTmFtZXMpIHtcbiAgICBjb25zdCByZXNvbHZlUmVzdWx0ID0gYXdhaXQgdHJ5UmVzb2x2ZUFuZEluaXRpYWxpemVCYWNrZW5kKGJhY2tlbmROYW1lKTtcbiAgICBpZiAodHlwZW9mIHJlc29sdmVSZXN1bHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlcnJvcnMucHVzaCh7IG5hbWU6IGJhY2tlbmROYW1lLCBlcnI6IHJlc29sdmVSZXN1bHQgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghYmFja2VuZCkge1xuICAgICAgICBiYWNrZW5kID0gcmVzb2x2ZVJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGlmIChiYWNrZW5kID09PSByZXNvbHZlUmVzdWx0KSB7XG4gICAgICAgIGF2YWlsYWJsZUJhY2tlbmROYW1lcy5hZGQoYmFja2VuZE5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGlmIG5vIGJhY2tlbmQgaXMgYXZhaWxhYmxlLCB0aHJvdyBlcnJvci5cbiAgaWYgKCFiYWNrZW5kKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBubyBhdmFpbGFibGUgYmFja2VuZCBmb3VuZC4gRVJSOiAke2Vycm9ycy5tYXAoKGUpID0+IGBbJHtlLm5hbWV9XSAke2UuZXJyfWApLmpvaW4oJywgJyl9YCk7XG4gIH1cblxuICAvLyBmb3IgZWFjaCBleHBsaWNpdGx5IHJlcXVlc3RlZCBiYWNrZW5kLCBpZiBpdCdzIG5vdCBhdmFpbGFibGUsIG91dHB1dCB3YXJuaW5nIG1lc3NhZ2UuXG4gIGZvciAoY29uc3QgeyBuYW1lLCBlcnIgfSBvZiBlcnJvcnMpIHtcbiAgICBpZiAoYmFja2VuZEhpbnRzLmluY2x1ZGVzKG5hbWUpKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgcmVtb3ZpbmcgcmVxdWVzdGVkIGV4ZWN1dGlvbiBwcm92aWRlciBcIiR7bmFtZX1cIiBmcm9tIHNlc3Npb24gb3B0aW9ucyBiZWNhdXNlIGl0IGlzIG5vdCBhdmFpbGFibGU6ICR7ZXJyfWAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGZpbHRlcmVkRXBzID0gZXBzLmZpbHRlcigoaSkgPT4gYXZhaWxhYmxlQmFja2VuZE5hbWVzLmhhcyh0eXBlb2YgaSA9PT0gJ3N0cmluZycgPyBpIDogaS5uYW1lKSk7XG5cbiAgcmV0dXJuIFtcbiAgICBiYWNrZW5kLFxuICAgIG5ldyBQcm94eShvcHRpb25zLCB7XG4gICAgICBnZXQ6ICh0YXJnZXQsIHByb3ApID0+IHtcbiAgICAgICAgaWYgKHByb3AgPT09ICdleGVjdXRpb25Qcm92aWRlcnMnKSB7XG4gICAgICAgICAgcmV0dXJuIGZpbHRlcmVkRXBzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3ApO1xuICAgICAgfSxcbiAgICB9KSxcbiAgXTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb24gfSBmcm9tICcuL2luZmVyZW5jZS1zZXNzaW9uLmpzJztcbmltcG9ydCB7IE9ubnhWYWx1ZSB9IGZyb20gJy4vb25ueC12YWx1ZS5qcyc7XG5cbi8qKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgU2Vzc2lvbkhhbmRsZXIge1xuICB0eXBlIEZlZWRzVHlwZSA9IHsgW25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZSB9O1xuICB0eXBlIEZldGNoZXNUeXBlID0geyBbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlIHwgbnVsbCB9O1xuICB0eXBlIFJldHVyblR5cGUgPSB7IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIHNoYXJlZCBTZXNzaW9uSGFuZGxlciBmdW5jdGlvbmFsaXR5XG4gKlxuICogQGlnbm9yZVxuICovXG5pbnRlcmZhY2UgU2Vzc2lvbkhhbmRsZXIge1xuICBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD47XG5cbiAgcmVhZG9ubHkgaW5wdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG4gIHJlYWRvbmx5IG91dHB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcblxuICByZWFkb25seSBpbnB1dE1ldGFkYXRhOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXTtcbiAgcmVhZG9ubHkgb3V0cHV0TWV0YWRhdGE6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb24uVmFsdWVNZXRhZGF0YVtdO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudCBhIGhhbmRsZXIgaW5zdGFuY2Ugb2YgYW4gaW5mZXJlbmNlIHNlc3Npb24uXG4gKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEluZmVyZW5jZVNlc3Npb25IYW5kbGVyIGV4dGVuZHMgU2Vzc2lvbkhhbmRsZXIge1xuICBzdGFydFByb2ZpbGluZygpOiB2b2lkO1xuICBlbmRQcm9maWxpbmcoKTogdm9pZDtcblxuICBydW4oXG4gICAgZmVlZHM6IFNlc3Npb25IYW5kbGVyLkZlZWRzVHlwZSxcbiAgICBmZXRjaGVzOiBTZXNzaW9uSGFuZGxlci5GZXRjaGVzVHlwZSxcbiAgICBvcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMsXG4gICk6IFByb21pc2U8U2Vzc2lvbkhhbmRsZXIuUmV0dXJuVHlwZT47XG59XG5cbi8qKlxuICogUmVwcmVzZW50IGEgYmFja2VuZCB0aGF0IHByb3ZpZGVzIGltcGxlbWVudGF0aW9uIG9mIG1vZGVsIGluZmVyZW5jaW5nLlxuICpcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBCYWNrZW5kIHtcbiAgLyoqXG4gICAqIEluaXRpYWxpemUgdGhlIGJhY2tlbmQgYXN5bmNocm9ub3VzbHkuIFNob3VsZCB0aHJvdyB3aGVuIGZhaWxlZC5cbiAgICovXG4gIGluaXQoYmFja2VuZE5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG5cbiAgY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIoXG4gICAgdXJpT3JCdWZmZXI6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMsXG4gICk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXI+O1xufVxuXG5leHBvcnQgeyByZWdpc3RlckJhY2tlbmQgfSBmcm9tICcuL2JhY2tlbmQtaW1wbC5qcyc7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8vIFRoaXMgZmlsZSBpcyBnZW5lcmF0ZWQgYnkgL2pzL3NjcmlwdHMvdXBkYXRlLXZlcnNpb24udHNcbi8vIERvIG5vdCBtb2RpZnkgZmlsZSBjb250ZW50IG1hbnVhbGx5LlxuXG5leHBvcnQgY29uc3QgdmVyc2lvbiA9ICcxLjI2LjAnO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBFbnYgfSBmcm9tICcuL2Vudi5qcyc7XG5pbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSAnLi92ZXJzaW9uLmpzJztcblxudHlwZSBMb2dMZXZlbFR5cGUgPSBFbnZbJ2xvZ0xldmVsJ107XG5cbmxldCBsb2dMZXZlbFZhbHVlOiBSZXF1aXJlZDxMb2dMZXZlbFR5cGU+ID0gJ3dhcm5pbmcnO1xuXG5leHBvcnQgY29uc3QgZW52OiBFbnYgPSB7XG4gIHdhc206IHt9IGFzIEVudi5XZWJBc3NlbWJseUZsYWdzLFxuICB3ZWJnbDoge30gYXMgRW52LldlYkdMRmxhZ3MsXG4gIHdlYmdwdToge30gYXMgRW52LldlYkdwdUZsYWdzLFxuICB2ZXJzaW9uczogeyBjb21tb246IHZlcnNpb24gfSxcblxuICBzZXQgbG9nTGV2ZWwodmFsdWU6IExvZ0xldmVsVHlwZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnIHx8IFsndmVyYm9zZScsICdpbmZvJywgJ3dhcm5pbmcnLCAnZXJyb3InLCAnZmF0YWwnXS5pbmRleE9mKHZhbHVlKSA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgbG9nZ2luZyBsZXZlbDogJHt2YWx1ZX1gKTtcbiAgICB9XG4gICAgbG9nTGV2ZWxWYWx1ZSA9IHZhbHVlO1xuICB9LFxuICBnZXQgbG9nTGV2ZWwoKTogUmVxdWlyZWQ8TG9nTGV2ZWxUeXBlPiB7XG4gICAgcmV0dXJuIGxvZ0xldmVsVmFsdWU7XG4gIH0sXG59O1xuXG4vLyBzZXQgcHJvcGVydHkgJ2xvZ0xldmVsJyBzbyB0aGF0IHRoZXkgY2FuIGJlIGNvcnJlY3RseSB0cmFuc2ZlcnJlZCB0byB3b3JrZXIgYnkgYHBvc3RNZXNzYWdlKClgLlxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGVudiwgJ2xvZ0xldmVsJywgeyBlbnVtZXJhYmxlOiB0cnVlIH0pO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBlbnYgYXMgZW52SW1wbCB9IGZyb20gJy4vZW52LWltcGwuanMnO1xuaW1wb3J0IHsgVHJ5R2V0R2xvYmFsVHlwZSB9IGZyb20gJy4vdHlwZS1oZWxwZXIuanMnO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgRW52IHtcbiAgZXhwb3J0IHR5cGUgV2FzbVBhdGhQcmVmaXggPSBzdHJpbmc7XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2FzbUZpbGVQYXRocyB7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgb3ZlcnJpZGUgcGF0aCBmb3IgdGhlIG1haW4gLndhc20gZmlsZS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGF0aCBzaG91bGQgYmUgYW4gYWJzb2x1dGUgcGF0aC5cbiAgICAgKlxuICAgICAqIElmIG5vdCBtb2RpZmllZCwgdGhlIGZpbGVuYW1lIG9mIHRoZSAud2FzbSBmaWxlIGlzOlxuICAgICAqIC0gYG9ydC13YXNtLXNpbWQtdGhyZWFkZWQud2FzbWAgZm9yIGRlZmF1bHQgYnVpbGRcbiAgICAgKiAtIGBvcnQtd2FzbS1zaW1kLXRocmVhZGVkLmpzZXAud2FzbWAgZm9yIEpTRVAgYnVpbGQgKHdpdGggV2ViR1BVIGFuZCBXZWJOTilcbiAgICAgKiAtIGBvcnQtd2FzbS1zaW1kLXRocmVhZGVkLmFzeW5jaWZ5Lndhc21gIGZvciBXZWJHUFUgYnVpbGQgd2l0aCBBc3luY2lmeSAod2l0aCBXZWJOTilcbiAgICAgKiAtIGBvcnQtd2FzbS1zaW1kLXRocmVhZGVkLmpzcGkud2FzbWAgZm9yIFdlYkdQVSBidWlsZCB3aXRoIEpTUEkgc3VwcG9ydCAod2l0aCBXZWJOTilcbiAgICAgKi9cbiAgICB3YXNtPzogVVJMIHwgc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgdGhlIG92ZXJyaWRlIHBhdGggZm9yIHRoZSBtYWluIC5tanMgZmlsZS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGF0aCBzaG91bGQgYmUgYW4gYWJzb2x1dGUgcGF0aC5cbiAgICAgKlxuICAgICAqIElmIG5vdCBtb2RpZmllZCwgdGhlIGZpbGVuYW1lIG9mIHRoZSAubWpzIGZpbGUgaXM6XG4gICAgICogLSBgb3J0LXdhc20tc2ltZC10aHJlYWRlZC5tanNgIGZvciBkZWZhdWx0IGJ1aWxkXG4gICAgICogLSBgb3J0LXdhc20tc2ltZC10aHJlYWRlZC5qc2VwLm1qc2AgZm9yIEpTRVAgYnVpbGQgKHdpdGggV2ViR1BVIGFuZCBXZWJOTilcbiAgICAgKiAtIGBvcnQtd2FzbS1zaW1kLXRocmVhZGVkLmFzeW5jaWZ5Lm1qc2AgZm9yIFdlYkdQVSBidWlsZCB3aXRoIEFzeW5jaWZ5ICh3aXRoIFdlYk5OKVxuICAgICAqIC0gYG9ydC13YXNtLXNpbWQtdGhyZWFkZWQuanNwaS5tanNgIGZvciBXZWJHUFUgYnVpbGQgd2l0aCBKU1BJIHN1cHBvcnQgKHdpdGggV2ViTk4pXG4gICAgICovXG4gICAgbWpzPzogVVJMIHwgc3RyaW5nO1xuICB9XG4gIGV4cG9ydCB0eXBlIFdhc21QcmVmaXhPckZpbGVQYXRocyA9IFdhc21QYXRoUHJlZml4IHwgV2FzbUZpbGVQYXRocztcbiAgZXhwb3J0IGludGVyZmFjZSBXZWJBc3NlbWJseUZsYWdzIHtcbiAgICAvKipcbiAgICAgKiBzZXQgb3IgZ2V0IG51bWJlciBvZiB0aHJlYWQocykuIElmIG9taXR0ZWQgb3Igc2V0IHRvIDAsIG51bWJlciBvZiB0aHJlYWQocykgd2lsbCBiZSBkZXRlcm1pbmVkIGJ5IHN5c3RlbS4gSWYgc2V0XG4gICAgICogdG8gMSwgbm8gd29ya2VyIHRocmVhZCB3aWxsIGJlIHNwYXduZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgd2hlbiBXZWJBc3NlbWJseSBtdWx0aXRocmVhZCBmZWF0dXJlIGlzIGF2YWlsYWJsZSBpbiBjdXJyZW50IGNvbnRleHQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGAwYFxuICAgICAqL1xuICAgIG51bVRocmVhZHM/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBzZXQgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gZW5hYmxlIFNJTUQuXG4gICAgICpcbiAgICAgKiBPTk5YIFJ1bnRpbWUgd2lsbCBwZXJmb3JtIGZlYXR1cmUgZGV0ZWN0aW9uIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5LiBTcGVjaWZpY2FsbHksIHdoZW4gdGhlIHZhbHVlIGlzXG4gICAgICogc2V0IHRvOlxuICAgICAqIC0gYHVuZGVmaW5lZGAsIGB0cnVlYCBvciBgXCJmaXhlZFwiYDogd2lsbCBjaGVjayBhdmFpbGFiaWxpdHkgb2YgRml4ZWQtd2lkdGggU0lNRC5cbiAgICAgKiAtIGBcInJlbGF4ZWRcImA6IHdpbGwgY2hlY2sgYXZhaWxhYmlsaXR5IG9mIFJlbGF4ZWQgU0lNRC5cbiAgICAgKiAtIGBmYWxzZWA6IHdpbGwgbm90IHBlcmZvcm0gU0lNRCBmZWF0dXJlIGNoZWNraW5nLlxuICAgICAqXG4gICAgICogU2V0dGluZyB0aGlzIHByb3BlcnR5IGRvZXMgbm90IG1ha2UgT05OWCBSdW50aW1lIHRvIHN3aXRjaCB0byB0aGUgY29ycmVzcG9uZGluZyBydW50aW1lIGF1dG9tYXRpY2FsbHkuIFVzZXIgbmVlZFxuICAgICAqIHRvIHNldCBgd2FzbVBhdGhzYCBvciBgd2FzbUJpbmFyeWAgcHJvcGVydHkgdG8gbG9hZCB0aGUgY29ycmVzcG9uZGluZyBydW50aW1lLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IHdoZW4gV2ViQXNzZW1ibHkgU0lNRCBmZWF0dXJlIGlzIGF2YWlsYWJsZSBpbiBjdXJyZW50IGNvbnRleHQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGB0cnVlYFxuICAgICAqL1xuICAgIHNpbWQ/OiBib29sZWFuIHwgJ2ZpeGVkJyB8ICdyZWxheGVkJztcblxuICAgIC8qKlxuICAgICAqIHNldCBvciBnZXQgYSBib29sZWFuIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0byBlbmFibGUgdHJhY2UuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICAgKlxuICAgICAqIEBkZXByZWNhdGVkIFVzZSBgZW52LnRyYWNlYCBpbnN0ZWFkLiBJZiBgZW52LnRyYWNlYCBpcyBzZXQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZSBpZ25vcmVkLlxuICAgICAqL1xuICAgIHRyYWNlPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgYSBudW1iZXIgc3BlY2lmeWluZyB0aGUgdGltZW91dCBmb3IgaW5pdGlhbGl6YXRpb24gb2YgV2ViQXNzZW1ibHkgYmFja2VuZCwgaW4gbWlsbGlzZWNvbmRzLiBBIHplcm9cbiAgICAgKiB2YWx1ZSBpbmRpY2F0ZXMgbm8gdGltZW91dCBpcyBzZXQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGAwYFxuICAgICAqL1xuICAgIGluaXRUaW1lb3V0PzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogU2V0IGEgY3VzdG9tIFVSTCBwcmVmaXggdG8gdGhlIC53YXNtLy5tanMgZmlsZXMsIG9yIGFuIG9iamVjdCBvZiBvdmVycmlkZXMgZm9yIGJvdGggLndhc20vLm1qcyBmaWxlLiBUaGUgb3ZlcnJpZGVcbiAgICAgKiBwYXRoIHNob3VsZCBiZSBhbiBhYnNvbHV0ZSBwYXRoLlxuICAgICAqL1xuICAgIHdhc21QYXRocz86IFdhc21QcmVmaXhPckZpbGVQYXRocztcblxuICAgIC8qKlxuICAgICAqIFNldCBhIGN1c3RvbSBidWZmZXIgd2hpY2ggY29udGFpbnMgdGhlIFdlYkFzc2VtYmx5IGJpbmFyeS4gSWYgdGhpcyBwcm9wZXJ0eSBpcyBzZXQsIHRoZSBgd2FzbVBhdGhzYCBwcm9wZXJ0eSB3aWxsXG4gICAgICogYmUgaWdub3JlZC5cbiAgICAgKi9cbiAgICB3YXNtQmluYXJ5PzogQXJyYXlCdWZmZXJMaWtlIHwgVWludDhBcnJheTtcblxuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgYSBib29sZWFuIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0byBwcm94eSB0aGUgZXhlY3V0aW9uIG9mIG1haW4gdGhyZWFkIHRvIGEgd29ya2VyIHRocmVhZC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgICAqL1xuICAgIHByb3h5PzogYm9vbGVhbjtcbiAgfVxuXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR0xGbGFncyB7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgV2ViR0wgQ29udGV4dCBJRCAod2ViZ2wgb3Igd2ViZ2wyKS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYCd3ZWJnbDInYFxuICAgICAqL1xuICAgIGNvbnRleHRJZD86ICd3ZWJnbCcgfCAnd2ViZ2wyJztcbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIFdlYkdMIHJlbmRlcmluZyBjb250ZXh0LlxuICAgICAqL1xuICAgIHJlYWRvbmx5IGNvbnRleHQ6IFdlYkdMUmVuZGVyaW5nQ29udGV4dDtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBtYXhpbXVtIGJhdGNoIHNpemUgZm9yIG1hdG11bC4gMCBtZWFucyB0byBkaXNhYmxlIGJhdGNoaW5nLlxuICAgICAqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBtYXRtdWxNYXhCYXRjaFNpemU/OiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgdGV4dHVyZSBjYWNoZSBtb2RlLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgJ2Z1bGwnYFxuICAgICAqL1xuICAgIHRleHR1cmVDYWNoZU1vZGU/OiAnaW5pdGlhbGl6ZXJPbmx5JyB8ICdmdWxsJztcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBwYWNrZWQgdGV4dHVyZSBtb2RlXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICAgKi9cbiAgICBwYWNrPzogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHdoZXRoZXIgZW5hYmxlIGFzeW5jIGRvd25sb2FkLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAgICovXG4gICAgYXN5bmM/OiBib29sZWFuO1xuICB9XG5cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHcHVQcm9maWxpbmdEYXRhVjFUZW5zb3JNZXRhZGF0YSB7XG4gICAgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG4gICAgZGF0YVR5cGU6IHN0cmluZztcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkdwdVByb2ZpbGluZ0RhdGFWMSB7XG4gICAgdmVyc2lvbjogMTtcbiAgICBpbnB1dHNNZXRhZGF0YTogcmVhZG9ubHkgV2ViR3B1UHJvZmlsaW5nRGF0YVYxVGVuc29yTWV0YWRhdGFbXTtcbiAgICBvdXRwdXRzTWV0YWRhdGE6IHJlYWRvbmx5IFdlYkdwdVByb2ZpbGluZ0RhdGFWMVRlbnNvck1ldGFkYXRhW107XG4gICAga2VybmVsSWQ6IG51bWJlcjtcbiAgICBrZXJuZWxUeXBlOiBzdHJpbmc7XG4gICAga2VybmVsTmFtZTogc3RyaW5nO1xuICAgIHByb2dyYW1OYW1lOiBzdHJpbmc7XG4gICAgc3RhcnRUaW1lOiBudW1iZXI7XG4gICAgZW5kVGltZTogbnVtYmVyO1xuICB9XG5cbiAgZXhwb3J0IHR5cGUgV2ViR3B1UHJvZmlsaW5nRGF0YSA9IFdlYkdwdVByb2ZpbGluZ0RhdGFWMTtcblxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkdwdUZsYWdzIHtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBwcm9maWxpbmcgbW9kZS5cbiAgICAgKlxuICAgICAqIEBkZXByZWNhdGVkIFVzZSBgZW52LndlYmdwdS5wcm9maWxpbmcubW9kZWAgaW5zdGVhZC4gSWYgYGVudi53ZWJncHUucHJvZmlsaW5nLm1vZGVgIGlzIHNldCwgdGhpcyBwcm9wZXJ0eSB3aWxsIGJlXG4gICAgICogaWdub3JlZC5cbiAgICAgKi9cbiAgICBwcm9maWxpbmdNb2RlPzogJ29mZicgfCAnZGVmYXVsdCc7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgcHJvZmlsaW5nIGNvbmZpZ3VyYXRpb24uXG4gICAgICovXG4gICAgcHJvZmlsaW5nOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNldCBvciBnZXQgdGhlIHByb2ZpbGluZyBtb2RlLlxuICAgICAgICpcbiAgICAgICAqIEBkZWZhdWx0VmFsdWUgYCdvZmYnYFxuICAgICAgICovXG4gICAgICBtb2RlPzogJ29mZicgfCAnZGVmYXVsdCc7XG5cbiAgICAgIC8qKlxuICAgICAgICogU2V0IG9yIGdldCBhIGNhbGxiYWNrIGZ1bmN0aW9uIHdoZW4gYSBwcm9maWxpbmcgZGF0YSBpcyByZWNlaXZlZC4gSWYgbm90IHNldCwgdGhlIHByb2ZpbGluZyBkYXRhIHdpbGwgYmVcbiAgICAgICAqIHByaW50ZWQgdG8gY29uc29sZS5cbiAgICAgICAqL1xuICAgICAgb25kYXRhPzogKGRhdGE6IFdlYkdwdVByb2ZpbGluZ0RhdGEpID0+IHZvaWQ7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBwb3dlciBwcmVmZXJlbmNlLlxuICAgICAqXG4gICAgICogU2V0dGluZyB0aGlzIHByb3BlcnR5IG9ubHkgaGFzIGVmZmVjdCBiZWZvcmUgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBUaGUgdmFsdWUgd2lsbCBiZVxuICAgICAqIHVzZWQgYXMgb3B0aW9ucyBmb3IgYG5hdmlnYXRvci5ncHUucmVxdWVzdEFkYXB0ZXIoKWAuXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIGh0dHBzOi8vZ3B1d2ViLmdpdGh1Yi5pby9ncHV3ZWIvI2RpY3RkZWYtZ3B1cmVxdWVzdGFkYXB0ZXJvcHRpb25zfSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgdW5kZWZpbmVkYFxuICAgICAqXG4gICAgICogQGRlcHJlY2F0ZWQgQ3JlYXRlIHlvdXIgb3duIEdQVUFkYXB0ZXIsIHVzZSBpdCB0byBjcmVhdGUgYSBHUFVEZXZpY2UgaW5zdGFuY2UgYW5kIHNldCB7QGxpbmsgZGV2aWNlfSBwcm9wZXJ0eSBpZlxuICAgICAqIHlvdSB3YW50IHRvIHVzZSBhIHNwZWNpZmljIHBvd2VyIHByZWZlcmVuY2UuXG4gICAgICovXG4gICAgcG93ZXJQcmVmZXJlbmNlPzogJ2xvdy1wb3dlcicgfCAnaGlnaC1wZXJmb3JtYW5jZSc7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgZm9yY2UgZmFsbGJhY2sgYWRhcHRlciBmbGFnLlxuICAgICAqXG4gICAgICogU2V0dGluZyB0aGlzIHByb3BlcnR5IG9ubHkgaGFzIGVmZmVjdCBiZWZvcmUgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBUaGUgdmFsdWUgd2lsbCBiZVxuICAgICAqIHVzZWQgYXMgb3B0aW9ucyBmb3IgYG5hdmlnYXRvci5ncHUucmVxdWVzdEFkYXB0ZXIoKWAuXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIGh0dHBzOi8vZ3B1d2ViLmdpdGh1Yi5pby9ncHV3ZWIvI2RpY3RkZWYtZ3B1cmVxdWVzdGFkYXB0ZXJvcHRpb25zfSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgdW5kZWZpbmVkYFxuICAgICAqXG4gICAgICogQGRlcHJlY2F0ZWQgQ3JlYXRlIHlvdXIgb3duIEdQVUFkYXB0ZXIsIHVzZSBpdCB0byBjcmVhdGUgYSBHUFVEZXZpY2UgaW5zdGFuY2UgYW5kIHNldCB7QGxpbmsgZGV2aWNlfSBwcm9wZXJ0eSBpZlxuICAgICAqIHlvdSB3YW50IHRvIHVzZSBhIHNwZWNpZmljIGZhbGxiYWNrIG9wdGlvbi5cbiAgICAgKi9cbiAgICBmb3JjZUZhbGxiYWNrQWRhcHRlcj86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgYWRhcHRlciBmb3IgV2ViR1BVLlxuICAgICAqXG4gICAgICogU2V0dGluZyB0aGlzIHByb3BlcnR5IG9ubHkgaGFzIGVmZmVjdCBiZWZvcmUgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBUaGUgdmFsdWUgd2lsbCBiZVxuICAgICAqIHVzZWQgYXMgdGhlIEdQVSBhZGFwdGVyIGZvciB0aGUgdW5kZXJseWluZyBXZWJHUFUgYmFja2VuZCB0byBjcmVhdGUgR1BVIGRldmljZS5cbiAgICAgKlxuICAgICAqIElmIHRoaXMgcHJvcGVydHkgaXMgbm90IHNldCwgaXQgd2lsbCBiZSBhdmFpbGFibGUgdG8gZ2V0IGFmdGVyIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhlXG4gICAgICogdmFsdWUgd2lsbCBiZSB0aGUgR1BVIGFkYXB0ZXIgdGhhdCBjcmVhdGVkIGJ5IHRoZSB1bmRlcmx5aW5nIFdlYkdQVSBiYWNrZW5kLlxuICAgICAqXG4gICAgICogV2hlbiB1c2Ugd2l0aCBUeXBlU2NyaXB0LCB0aGUgdHlwZSBvZiB0aGlzIHByb3BlcnR5IGlzIGBHUFVBZGFwdGVyYCBkZWZpbmVkIGluIFwiQHdlYmdwdS90eXBlc1wiLlxuICAgICAqXG4gICAgICogQGRlcHJlY2F0ZWQgSXQgaXMgbm8gbG9uZ2VyIHJlY29tbWVuZGVkIHRvIHVzZSB0aGlzIHByb3BlcnR5LiBUaGUgbGF0ZXN0IFdlYkdQVSBzcGVjIGFkZHMgYEdQVURldmljZS5hZGFwdGVySW5mb2BcbiAgICAgKiAoaHR0cHM6Ly93d3cudzMub3JnL1RSL3dlYmdwdS8jZG9tLWdwdWRldmljZS1hZGFwdGVyaW5mbyksIHdoaWNoIGFsbG93cyB0byBnZXQgdGhlIGFkYXB0ZXIgaW5mb3JtYXRpb24gZnJvbSB0aGVcbiAgICAgKiBkZXZpY2UuIFdoZW4gaXQncyBhdmFpbGFibGUsIHRoZXJlIGlzIG5vIG5lZWQgdG8gc2V0L2dldCB0aGUge0BsaW5rIGFkYXB0ZXJ9IHByb3BlcnR5LlxuICAgICAqL1xuICAgIGFkYXB0ZXI6IFRyeUdldEdsb2JhbFR5cGU8J0dQVUFkYXB0ZXInPjtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBHUFUgZGV2aWNlIGZvciBXZWJHUFUuXG4gICAgICpcbiAgICAgKiBUaGVyZSBhcmUgMyB2YWxpZCBzY2VuYXJpb3Mgb2YgYWNjZXNzaW5nIHRoaXMgcHJvcGVydHk6XG4gICAgICogLSBTZXQgYSB2YWx1ZSBiZWZvcmUgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBUaGUgdmFsdWUgd2lsbCBiZSB1c2VkIGJ5IHRoZSBXZWJHUFUgYmFja2VuZFxuICAgICAqIHRvIHBlcmZvcm0gY2FsY3VsYXRpb25zLiBJZiB0aGUgdmFsdWUgaXMgbm90IGEgYEdQVURldmljZWAgb2JqZWN0LCBhbiBlcnJvciB3aWxsIGJlIHRocm93bi5cbiAgICAgKiAtIEdldCB0aGUgdmFsdWUgYmVmb3JlIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhpcyB3aWxsIHRyeSB0byBjcmVhdGUgYSBuZXcgR1BVRGV2aWNlXG4gICAgICogaW5zdGFuY2UuIFJldHVybnMgYSBgUHJvbWlzZWAgdGhhdCByZXNvbHZlcyB0byBhIGBHUFVEZXZpY2VgIG9iamVjdC5cbiAgICAgKiAtIEdldCB0aGUgdmFsdWUgYWZ0ZXIgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBSZXR1cm5zIGEgcmVzb2x2ZWQgYFByb21pc2VgIHRvIHRoZVxuICAgICAqIGBHUFVEZXZpY2VgIG9iamVjdCB1c2VkIGJ5IHRoZSBXZWJHUFUgYmFja2VuZC5cbiAgICAgKi9cbiAgICBnZXQgZGV2aWNlKCk6IFByb21pc2U8VHJ5R2V0R2xvYmFsVHlwZTwnR1BVRGV2aWNlJz4+O1xuICAgIHNldCBkZXZpY2UodmFsdWU6IFRyeUdldEdsb2JhbFR5cGU8J0dQVURldmljZSc+KTtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHdoZXRoZXIgdmFsaWRhdGUgaW5wdXQgY29udGVudC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgICAqL1xuICAgIHZhbGlkYXRlSW5wdXRDb250ZW50PzogYm9vbGVhbjtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEVudiB7XG4gIC8qKlxuICAgKiBzZXQgdGhlIHNldmVyaXR5IGxldmVsIGZvciBsb2dnaW5nLlxuICAgKlxuICAgKiBAZGVmYXVsdFZhbHVlIGAnd2FybmluZydgXG4gICAqL1xuICBsb2dMZXZlbD86ICd2ZXJib3NlJyB8ICdpbmZvJyB8ICd3YXJuaW5nJyB8ICdlcnJvcicgfCAnZmF0YWwnO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZSB3aGV0aGVyIHJ1biBpbiBkZWJ1ZyBtb2RlLlxuICAgKlxuICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICovXG4gIGRlYnVnPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogc2V0IG9yIGdldCBhIGJvb2xlYW4gdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRvIGVuYWJsZSB0cmFjZS5cbiAgICpcbiAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAqL1xuICB0cmFjZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEdldCB2ZXJzaW9uIG9mIHRoZSBjdXJyZW50IHBhY2thZ2UuXG4gICAqL1xuICByZWFkb25seSB2ZXJzaW9uczoge1xuICAgIHJlYWRvbmx5IGNvbW1vbjogc3RyaW5nO1xuICAgIHJlYWRvbmx5IHdlYj86IHN0cmluZztcbiAgICByZWFkb25seSBub2RlPzogc3RyaW5nO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbiAgICByZWFkb25seSAncmVhY3QtbmF0aXZlJz86IHN0cmluZztcbiAgfTtcblxuICAvKipcbiAgICogUmVwcmVzZW50IGEgc2V0IG9mIGZsYWdzIGZvciBXZWJBc3NlbWJseVxuICAgKi9cbiAgcmVhZG9ubHkgd2FzbTogRW52LldlYkFzc2VtYmx5RmxhZ3M7XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudCBhIHNldCBvZiBmbGFncyBmb3IgV2ViR0xcbiAgICovXG4gIHJlYWRvbmx5IHdlYmdsOiBFbnYuV2ViR0xGbGFncztcblxuICAvKipcbiAgICogUmVwcmVzZW50IGEgc2V0IG9mIGZsYWdzIGZvciBXZWJHUFVcbiAgICovXG4gIHJlYWRvbmx5IHdlYmdwdTogRW52LldlYkdwdUZsYWdzO1xuXG4gIFtuYW1lOiBzdHJpbmddOiB1bmtub3duO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudCBhIHNldCBvZiBmbGFncyBhcyBhIGdsb2JhbCBzaW5nbGV0b24uXG4gKi9cbmV4cG9ydCBjb25zdCBlbnY6IEVudiA9IGVudkltcGw7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvclRvRGF0YVVybE9wdGlvbnMsIFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyB9IGZyb20gJy4vdGVuc29yLWNvbnZlcnNpb24uanMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3IuanMnO1xuXG4vKipcbiAqIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvci50b0RhdGFVUkwoKVxuICovXG5leHBvcnQgY29uc3QgdGVuc29yVG9EYXRhVVJMID0gKHRlbnNvcjogVGVuc29yLCBvcHRpb25zPzogVGVuc29yVG9EYXRhVXJsT3B0aW9ucyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGNhbnZhcyA9IHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKSA6IG5ldyBPZmZzY3JlZW5DYW52YXMoMSwgMSk7XG4gIGNhbnZhcy53aWR0aCA9IHRlbnNvci5kaW1zWzNdO1xuICBjYW52YXMuaGVpZ2h0ID0gdGVuc29yLmRpbXNbMl07XG4gIGNvbnN0IHBpeGVsczJEQ29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpIGFzXG4gICAgfCBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkRcbiAgICB8IE9mZnNjcmVlbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRFxuICAgIHwgbnVsbDtcblxuICBpZiAocGl4ZWxzMkRDb250ZXh0ICE9IG51bGwpIHtcbiAgICAvLyBEZWZhdWx0IHZhbHVlcyBmb3IgaGVpZ2h0IGFuZCB3aWR0aCAmIGZvcm1hdFxuICAgIGxldCB3aWR0aDogbnVtYmVyO1xuICAgIGxldCBoZWlnaHQ6IG51bWJlcjtcbiAgICBpZiAob3B0aW9ucz8udGVuc29yTGF5b3V0ICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy50ZW5zb3JMYXlvdXQgPT09ICdOSFdDJykge1xuICAgICAgd2lkdGggPSB0ZW5zb3IuZGltc1syXTtcbiAgICAgIGhlaWdodCA9IHRlbnNvci5kaW1zWzNdO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWZhdWx0IGxheW91dCBpcyBOQ1dIXG4gICAgICB3aWR0aCA9IHRlbnNvci5kaW1zWzNdO1xuICAgICAgaGVpZ2h0ID0gdGVuc29yLmRpbXNbMl07XG4gICAgfVxuXG4gICAgY29uc3QgaW5wdXRmb3JtYXQgPSBvcHRpb25zPy5mb3JtYXQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZm9ybWF0IDogJ1JHQic7XG5cbiAgICBjb25zdCBub3JtID0gb3B0aW9ucz8ubm9ybTtcbiAgICBsZXQgbm9ybU1lYW46IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIGxldCBub3JtQmlhczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgaWYgKG5vcm0gPT09IHVuZGVmaW5lZCB8fCBub3JtLm1lYW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgbm9ybU1lYW4gPSBbMjU1LCAyNTUsIDI1NSwgMjU1XTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiBub3JtLm1lYW4gPT09ICdudW1iZXInKSB7XG4gICAgICAgIG5vcm1NZWFuID0gW25vcm0ubWVhbiwgbm9ybS5tZWFuLCBub3JtLm1lYW4sIG5vcm0ubWVhbl07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub3JtTWVhbiA9IFtub3JtLm1lYW5bMF0sIG5vcm0ubWVhblsxXSwgbm9ybS5tZWFuWzJdLCAwXTtcbiAgICAgICAgaWYgKG5vcm0ubWVhblszXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbm9ybU1lYW5bM10gPSBub3JtLm1lYW5bM107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG5vcm0gPT09IHVuZGVmaW5lZCB8fCBub3JtLmJpYXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgbm9ybUJpYXMgPSBbMCwgMCwgMCwgMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2Ygbm9ybS5iaWFzID09PSAnbnVtYmVyJykge1xuICAgICAgICBub3JtQmlhcyA9IFtub3JtLmJpYXMsIG5vcm0uYmlhcywgbm9ybS5iaWFzLCBub3JtLmJpYXNdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbm9ybUJpYXMgPSBbbm9ybS5iaWFzWzBdLCBub3JtLmJpYXNbMV0sIG5vcm0uYmlhc1syXSwgMF07XG4gICAgICAgIGlmIChub3JtLmJpYXNbM10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG5vcm1CaWFzWzNdID0gbm9ybS5iaWFzWzNdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc3RyaWRlID0gaGVpZ2h0ICogd2lkdGg7XG4gICAgLy8gRGVmYXVsdCBwb2ludGVyIGFzc2lnbm1lbnRzXG4gICAgbGV0IHJUZW5zb3JQb2ludGVyID0gMCxcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlLFxuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyLFxuICAgICAgYVRlbnNvclBvaW50ZXIgPSAtMTtcblxuICAgIC8vIFVwZGF0aW5nIHRoZSBwb2ludGVyIGFzc2lnbm1lbnRzIGJhc2VkIG9uIHRoZSBpbnB1dCBpbWFnZSBmb3JtYXRcbiAgICBpZiAoaW5wdXRmb3JtYXQgPT09ICdSR0JBJykge1xuICAgICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gICAgICBhVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDM7XG4gICAgfSBlbHNlIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JHQicpIHtcbiAgICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICAgIH0gZWxzZSBpZiAoaW5wdXRmb3JtYXQgPT09ICdSQkcnKSB7XG4gICAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhlaWdodDsgaSsrKSB7XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHdpZHRoOyBqKyspIHtcbiAgICAgICAgY29uc3QgUiA9ICgodGVuc29yLmRhdGFbclRlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzBdKSAqIG5vcm1NZWFuWzBdOyAvLyBSIHZhbHVlXG4gICAgICAgIGNvbnN0IEcgPSAoKHRlbnNvci5kYXRhW2dUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1sxXSkgKiBub3JtTWVhblsxXTsgLy8gRyB2YWx1ZVxuICAgICAgICBjb25zdCBCID0gKCh0ZW5zb3IuZGF0YVtiVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbMl0pICogbm9ybU1lYW5bMl07IC8vIEIgdmFsdWVcbiAgICAgICAgY29uc3QgQSA9IGFUZW5zb3JQb2ludGVyID09PSAtMSA/IDI1NSA6ICgodGVuc29yLmRhdGFbYVRlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzNdKSAqIG5vcm1NZWFuWzNdOyAvLyBBIHZhbHVlXG5cbiAgICAgICAgcGl4ZWxzMkRDb250ZXh0LmZpbGxTdHlsZSA9ICdyZ2JhKCcgKyBSICsgJywnICsgRyArICcsJyArIEIgKyAnLCcgKyBBICsgJyknO1xuICAgICAgICBwaXhlbHMyRENvbnRleHQuZmlsbFJlY3QoaiwgaSwgMSwgMSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICgndG9EYXRhVVJMJyBpbiBjYW52YXMpIHtcbiAgICAgIHJldHVybiBjYW52YXMudG9EYXRhVVJMKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndG9EYXRhVVJMIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gbm90IGFjY2VzcyBpbWFnZSBkYXRhJyk7XG4gIH1cbn07XG5cbi8qKlxuICogaW1wbGVtZW50YXRpb24gb2YgVGVuc29yLnRvSW1hZ2VEYXRhKClcbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvclRvSW1hZ2VEYXRhID0gKHRlbnNvcjogVGVuc29yLCBvcHRpb25zPzogVGVuc29yVG9JbWFnZURhdGFPcHRpb25zKTogSW1hZ2VEYXRhID0+IHtcbiAgY29uc3QgcGl4ZWxzMkRDb250ZXh0ID1cbiAgICB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnXG4gICAgICA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJylcbiAgICAgIDogKG5ldyBPZmZzY3JlZW5DYW52YXMoMSwgMSkuZ2V0Q29udGV4dCgnMmQnKSBhcyBPZmZzY3JlZW5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQpO1xuICBsZXQgaW1hZ2U6IEltYWdlRGF0YTtcbiAgaWYgKHBpeGVsczJEQ29udGV4dCAhPSBudWxsKSB7XG4gICAgLy8gRGVmYXVsdCB2YWx1ZXMgZm9yIGhlaWdodCBhbmQgd2lkdGggJiBmb3JtYXRcbiAgICBsZXQgd2lkdGg6IG51bWJlcjtcbiAgICBsZXQgaGVpZ2h0OiBudW1iZXI7XG4gICAgbGV0IGNoYW5uZWxzOiBudW1iZXI7XG4gICAgaWYgKG9wdGlvbnM/LnRlbnNvckxheW91dCAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMudGVuc29yTGF5b3V0ID09PSAnTkhXQycpIHtcbiAgICAgIHdpZHRoID0gdGVuc29yLmRpbXNbMl07XG4gICAgICBoZWlnaHQgPSB0ZW5zb3IuZGltc1sxXTtcbiAgICAgIGNoYW5uZWxzID0gdGVuc29yLmRpbXNbM107XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZmF1bHQgbGF5b3V0IGlzIE5DV0hcbiAgICAgIHdpZHRoID0gdGVuc29yLmRpbXNbM107XG4gICAgICBoZWlnaHQgPSB0ZW5zb3IuZGltc1syXTtcbiAgICAgIGNoYW5uZWxzID0gdGVuc29yLmRpbXNbMV07XG4gICAgfVxuICAgIGNvbnN0IGlucHV0Zm9ybWF0ID0gb3B0aW9ucyAhPT0gdW5kZWZpbmVkID8gKG9wdGlvbnMuZm9ybWF0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmZvcm1hdCA6ICdSR0InKSA6ICdSR0InO1xuXG4gICAgY29uc3Qgbm9ybSA9IG9wdGlvbnM/Lm5vcm07XG4gICAgbGV0IG5vcm1NZWFuOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgICBsZXQgbm9ybUJpYXM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIGlmIChub3JtID09PSB1bmRlZmluZWQgfHwgbm9ybS5tZWFuID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG5vcm1NZWFuID0gWzI1NSwgMjU1LCAyNTUsIDI1NV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2Ygbm9ybS5tZWFuID09PSAnbnVtYmVyJykge1xuICAgICAgICBub3JtTWVhbiA9IFtub3JtLm1lYW4sIG5vcm0ubWVhbiwgbm9ybS5tZWFuLCBub3JtLm1lYW5dO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbm9ybU1lYW4gPSBbbm9ybS5tZWFuWzBdLCBub3JtLm1lYW5bMV0sIG5vcm0ubWVhblsyXSwgMjU1XTtcbiAgICAgICAgaWYgKG5vcm0ubWVhblszXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbm9ybU1lYW5bM10gPSBub3JtLm1lYW5bM107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG5vcm0gPT09IHVuZGVmaW5lZCB8fCBub3JtLmJpYXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgbm9ybUJpYXMgPSBbMCwgMCwgMCwgMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2Ygbm9ybS5iaWFzID09PSAnbnVtYmVyJykge1xuICAgICAgICBub3JtQmlhcyA9IFtub3JtLmJpYXMsIG5vcm0uYmlhcywgbm9ybS5iaWFzLCBub3JtLmJpYXNdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbm9ybUJpYXMgPSBbbm9ybS5iaWFzWzBdLCBub3JtLmJpYXNbMV0sIG5vcm0uYmlhc1syXSwgMF07XG4gICAgICAgIGlmIChub3JtLmJpYXNbM10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG5vcm1CaWFzWzNdID0gbm9ybS5iaWFzWzNdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc3RyaWRlID0gaGVpZ2h0ICogd2lkdGg7XG4gICAgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKFxuICAgICAgICAob3B0aW9ucy5mb3JtYXQgIT09IHVuZGVmaW5lZCAmJiBjaGFubmVscyA9PT0gNCAmJiBvcHRpb25zLmZvcm1hdCAhPT0gJ1JHQkEnKSB8fFxuICAgICAgICAoY2hhbm5lbHMgPT09IDMgJiYgb3B0aW9ucy5mb3JtYXQgIT09ICdSR0InICYmIG9wdGlvbnMuZm9ybWF0ICE9PSAnQkdSJylcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUZW5zb3IgZm9ybWF0IGRvZXNuJ3QgbWF0Y2ggaW5wdXQgdGVuc29yIGRpbXNcIik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRGVmYXVsdCBwb2ludGVyIGFzc2lnbm1lbnRzXG4gICAgY29uc3Qgc3RlcCA9IDQ7XG4gICAgbGV0IHJJbWFnZVBvaW50ZXIgPSAwLFxuICAgICAgZ0ltYWdlUG9pbnRlciA9IDEsXG4gICAgICBiSW1hZ2VQb2ludGVyID0gMixcbiAgICAgIGFJbWFnZVBvaW50ZXIgPSAzO1xuICAgIGxldCByVGVuc29yUG9pbnRlciA9IDAsXG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZSxcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMixcbiAgICAgIGFUZW5zb3JQb2ludGVyID0gLTE7XG5cbiAgICAvLyBVcGRhdGluZyB0aGUgcG9pbnRlciBhc3NpZ25tZW50cyBiYXNlZCBvbiB0aGUgaW5wdXQgaW1hZ2UgZm9ybWF0XG4gICAgaWYgKGlucHV0Zm9ybWF0ID09PSAnUkdCQScpIHtcbiAgICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICAgICAgYVRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAzO1xuICAgIH0gZWxzZSBpZiAoaW5wdXRmb3JtYXQgPT09ICdSR0InKSB7XG4gICAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgICB9IGVsc2UgaWYgKGlucHV0Zm9ybWF0ID09PSAnUkJHJykge1xuICAgICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gICAgfVxuXG4gICAgaW1hZ2UgPSBwaXhlbHMyRENvbnRleHQuY3JlYXRlSW1hZ2VEYXRhKHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgZm9yIChcbiAgICAgIGxldCBpID0gMDtcbiAgICAgIGkgPCBoZWlnaHQgKiB3aWR0aDtcbiAgICAgIHJJbWFnZVBvaW50ZXIgKz0gc3RlcCwgZ0ltYWdlUG9pbnRlciArPSBzdGVwLCBiSW1hZ2VQb2ludGVyICs9IHN0ZXAsIGFJbWFnZVBvaW50ZXIgKz0gc3RlcCwgaSsrXG4gICAgKSB7XG4gICAgICBpbWFnZS5kYXRhW3JJbWFnZVBvaW50ZXJdID0gKCh0ZW5zb3IuZGF0YVtyVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbMF0pICogbm9ybU1lYW5bMF07IC8vIFIgdmFsdWVcbiAgICAgIGltYWdlLmRhdGFbZ0ltYWdlUG9pbnRlcl0gPSAoKHRlbnNvci5kYXRhW2dUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1sxXSkgKiBub3JtTWVhblsxXTsgLy8gRyB2YWx1ZVxuICAgICAgaW1hZ2UuZGF0YVtiSW1hZ2VQb2ludGVyXSA9ICgodGVuc29yLmRhdGFbYlRlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzJdKSAqIG5vcm1NZWFuWzJdOyAvLyBCIHZhbHVlXG4gICAgICBpbWFnZS5kYXRhW2FJbWFnZVBvaW50ZXJdID1cbiAgICAgICAgYVRlbnNvclBvaW50ZXIgPT09IC0xID8gMjU1IDogKCh0ZW5zb3IuZGF0YVthVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbM10pICogbm9ybU1lYW5bM107IC8vIEEgdmFsdWVcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gbm90IGFjY2VzcyBpbWFnZSBkYXRhJyk7XG4gIH1cbiAgcmV0dXJuIGltYWdlO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtcbiAgT3B0aW9uc0RpbWVuc2lvbnMsXG4gIE9wdGlvbnNGb3JtYXQsXG4gIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyxcbiAgT3B0aW9uc1RlbnNvckZvcm1hdCxcbiAgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgVGVuc29yRnJvbUdwdUJ1ZmZlck9wdGlvbnMsXG4gIFRlbnNvckZyb21JbWFnZUJpdG1hcE9wdGlvbnMsXG4gIFRlbnNvckZyb21JbWFnZURhdGFPcHRpb25zLFxuICBUZW5zb3JGcm9tSW1hZ2VFbGVtZW50T3B0aW9ucyxcbiAgVGVuc29yRnJvbU1MVGVuc29yT3B0aW9ucyxcbiAgVGVuc29yRnJvbVRleHR1cmVPcHRpb25zLFxuICBUZW5zb3JGcm9tVXJsT3B0aW9ucyxcbn0gZnJvbSAnLi90ZW5zb3ItZmFjdG9yeS5qcyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvci1pbXBsLmpzJztcbmltcG9ydCB7IFRlbnNvciBhcyBUZW5zb3JJbnRlcmZhY2UgfSBmcm9tICcuL3RlbnNvci5qcyc7XG5cbmludGVyZmFjZSBCdWZmZXJUb1RlbnNvck9wdGlvbnNcbiAgZXh0ZW5kcyBPcHRpb25zRGltZW5zaW9ucyxcbiAgICBPcHRpb25zVGVuc29yTGF5b3V0LFxuICAgIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyxcbiAgICBPcHRpb25zRm9ybWF0LFxuICAgIE9wdGlvbnNUZW5zb3JGb3JtYXQge31cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIGltYWdlIG9iamVjdFxuICpcbiAqIEBwYXJhbSBidWZmZXIgLSBFeHRyYWN0ZWQgaW1hZ2UgYnVmZmVyIGRhdGEgLSBhc3N1bWluZyBSR0JBIGZvcm1hdFxuICogQHBhcmFtIGltYWdlRm9ybWF0IC0gaW5wdXQgaW1hZ2UgY29uZmlndXJhdGlvbiAtIHJlcXVpcmVkIGNvbmZpZ3VyYXRpb25zIGhlaWdodCwgd2lkdGgsIGZvcm1hdFxuICogQHBhcmFtIHRlbnNvckZvcm1hdCAtIG91dHB1dCB0ZW5zb3IgY29uZmlndXJhdGlvbiAtIERlZmF1bHQgaXMgUkdCIGZvcm1hdFxuICovXG5leHBvcnQgY29uc3QgYnVmZmVyVG9UZW5zb3IgPSAoYnVmZmVyOiBVaW50OENsYW1wZWRBcnJheSB8IHVuZGVmaW5lZCwgb3B0aW9uczogQnVmZmVyVG9UZW5zb3JPcHRpb25zKTogVGVuc29yID0+IHtcbiAgaWYgKGJ1ZmZlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbWFnZSBidWZmZXIgbXVzdCBiZSBkZWZpbmVkJyk7XG4gIH1cbiAgaWYgKG9wdGlvbnMuaGVpZ2h0ID09PSB1bmRlZmluZWQgfHwgb3B0aW9ucy53aWR0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbWFnZSBoZWlnaHQgYW5kIHdpZHRoIG11c3QgYmUgZGVmaW5lZCcpO1xuICB9XG4gIGlmIChvcHRpb25zLnRlbnNvckxheW91dCA9PT0gJ05IV0MnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdOSFdDIFRlbnNvciBsYXlvdXQgaXMgbm90IHN1cHBvcnRlZCB5ZXQnKTtcbiAgfVxuXG4gIGNvbnN0IHsgaGVpZ2h0LCB3aWR0aCB9ID0gb3B0aW9ucztcblxuICBjb25zdCBub3JtID0gb3B0aW9ucy5ub3JtID8/IHsgbWVhbjogMjU1LCBiaWFzOiAwIH07XG4gIGxldCBub3JtTWVhbjogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIGxldCBub3JtQmlhczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG5cbiAgaWYgKHR5cGVvZiBub3JtLm1lYW4gPT09ICdudW1iZXInKSB7XG4gICAgbm9ybU1lYW4gPSBbbm9ybS5tZWFuLCBub3JtLm1lYW4sIG5vcm0ubWVhbiwgbm9ybS5tZWFuXTtcbiAgfSBlbHNlIHtcbiAgICBub3JtTWVhbiA9IFtub3JtLm1lYW4hWzBdLCBub3JtLm1lYW4hWzFdLCBub3JtLm1lYW4hWzJdLCBub3JtLm1lYW4hWzNdID8/IDI1NV07XG4gIH1cblxuICBpZiAodHlwZW9mIG5vcm0uYmlhcyA9PT0gJ251bWJlcicpIHtcbiAgICBub3JtQmlhcyA9IFtub3JtLmJpYXMsIG5vcm0uYmlhcywgbm9ybS5iaWFzLCBub3JtLmJpYXNdO1xuICB9IGVsc2Uge1xuICAgIG5vcm1CaWFzID0gW25vcm0uYmlhcyFbMF0sIG5vcm0uYmlhcyFbMV0sIG5vcm0uYmlhcyFbMl0sIG5vcm0uYmlhcyFbM10gPz8gMF07XG4gIH1cblxuICBjb25zdCBpbnB1dGZvcm1hdCA9IG9wdGlvbnMuZm9ybWF0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmZvcm1hdCA6ICdSR0JBJztcbiAgLy8gZGVmYXVsdCB2YWx1ZSBpcyBSR0JBIHNpbmNlIGltYWdlZGF0YSBhbmQgSFRNTEltYWdlRWxlbWVudCB1c2VzIGl0XG5cbiAgY29uc3Qgb3V0cHV0Zm9ybWF0ID1cbiAgICBvcHRpb25zLnRlbnNvckZvcm1hdCAhPT0gdW5kZWZpbmVkID8gKG9wdGlvbnMudGVuc29yRm9ybWF0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnRlbnNvckZvcm1hdCA6ICdSR0InKSA6ICdSR0InO1xuICBjb25zdCBzdHJpZGUgPSBoZWlnaHQgKiB3aWR0aDtcbiAgY29uc3QgZmxvYXQzMkRhdGEgPSBvdXRwdXRmb3JtYXQgPT09ICdSR0JBJyA/IG5ldyBGbG9hdDMyQXJyYXkoc3RyaWRlICogNCkgOiBuZXcgRmxvYXQzMkFycmF5KHN0cmlkZSAqIDMpO1xuXG4gIC8vIERlZmF1bHQgcG9pbnRlciBhc3NpZ25tZW50c1xuICBsZXQgc3RlcCA9IDQsXG4gICAgckltYWdlUG9pbnRlciA9IDAsXG4gICAgZ0ltYWdlUG9pbnRlciA9IDEsXG4gICAgYkltYWdlUG9pbnRlciA9IDIsXG4gICAgYUltYWdlUG9pbnRlciA9IDM7XG4gIGxldCByVGVuc29yUG9pbnRlciA9IDAsXG4gICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGUsXG4gICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyLFxuICAgIGFUZW5zb3JQb2ludGVyID0gLTE7XG5cbiAgLy8gVXBkYXRpbmcgdGhlIHBvaW50ZXIgYXNzaWdubWVudHMgYmFzZWQgb24gdGhlIGlucHV0IGltYWdlIGZvcm1hdFxuICBpZiAoaW5wdXRmb3JtYXQgPT09ICdSR0InKSB7XG4gICAgc3RlcCA9IDM7XG4gICAgckltYWdlUG9pbnRlciA9IDA7XG4gICAgZ0ltYWdlUG9pbnRlciA9IDE7XG4gICAgYkltYWdlUG9pbnRlciA9IDI7XG4gICAgYUltYWdlUG9pbnRlciA9IC0xO1xuICB9XG5cbiAgLy8gVXBkYXRpbmcgdGhlIHBvaW50ZXIgYXNzaWdubWVudHMgYmFzZWQgb24gdGhlIG91dHB1dCB0ZW5zb3IgZm9ybWF0XG4gIGlmIChvdXRwdXRmb3JtYXQgPT09ICdSR0JBJykge1xuICAgIGFUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMztcbiAgfSBlbHNlIGlmIChvdXRwdXRmb3JtYXQgPT09ICdSQkcnKSB7XG4gICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgfSBlbHNlIGlmIChvdXRwdXRmb3JtYXQgPT09ICdCR1InKSB7XG4gICAgYlRlbnNvclBvaW50ZXIgPSAwO1xuICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgIHJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgfVxuXG4gIGZvciAoXG4gICAgbGV0IGkgPSAwO1xuICAgIGkgPCBzdHJpZGU7XG4gICAgaSsrLCBySW1hZ2VQb2ludGVyICs9IHN0ZXAsIGJJbWFnZVBvaW50ZXIgKz0gc3RlcCwgZ0ltYWdlUG9pbnRlciArPSBzdGVwLCBhSW1hZ2VQb2ludGVyICs9IHN0ZXBcbiAgKSB7XG4gICAgZmxvYXQzMkRhdGFbclRlbnNvclBvaW50ZXIrK10gPSAoYnVmZmVyW3JJbWFnZVBvaW50ZXJdICsgbm9ybUJpYXNbMF0pIC8gbm9ybU1lYW5bMF07XG4gICAgZmxvYXQzMkRhdGFbZ1RlbnNvclBvaW50ZXIrK10gPSAoYnVmZmVyW2dJbWFnZVBvaW50ZXJdICsgbm9ybUJpYXNbMV0pIC8gbm9ybU1lYW5bMV07XG4gICAgZmxvYXQzMkRhdGFbYlRlbnNvclBvaW50ZXIrK10gPSAoYnVmZmVyW2JJbWFnZVBvaW50ZXJdICsgbm9ybUJpYXNbMl0pIC8gbm9ybU1lYW5bMl07XG4gICAgaWYgKGFUZW5zb3JQb2ludGVyICE9PSAtMSAmJiBhSW1hZ2VQb2ludGVyICE9PSAtMSkge1xuICAgICAgZmxvYXQzMkRhdGFbYVRlbnNvclBvaW50ZXIrK10gPSAoYnVmZmVyW2FJbWFnZVBvaW50ZXJdICsgbm9ybUJpYXNbM10pIC8gbm9ybU1lYW5bM107XG4gICAgfVxuICB9XG5cbiAgLy8gRmxvYXQzMkFycmF5IC0+IG9ydC5UZW5zb3JcbiAgY29uc3Qgb3V0cHV0VGVuc29yID1cbiAgICBvdXRwdXRmb3JtYXQgPT09ICdSR0JBJ1xuICAgICAgPyBuZXcgVGVuc29yKCdmbG9hdDMyJywgZmxvYXQzMkRhdGEsIFsxLCA0LCBoZWlnaHQsIHdpZHRoXSlcbiAgICAgIDogbmV3IFRlbnNvcignZmxvYXQzMicsIGZsb2F0MzJEYXRhLCBbMSwgMywgaGVpZ2h0LCB3aWR0aF0pO1xuICByZXR1cm4gb3V0cHV0VGVuc29yO1xufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IuZnJvbUltYWdlKCkuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JGcm9tSW1hZ2UgPSBhc3luYyAoXG4gIGltYWdlOiBJbWFnZURhdGEgfCBIVE1MSW1hZ2VFbGVtZW50IHwgSW1hZ2VCaXRtYXAgfCBzdHJpbmcsXG4gIG9wdGlvbnM/OlxuICAgIHwgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnNcbiAgICB8IFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zXG4gICAgfCBUZW5zb3JGcm9tSW1hZ2VCaXRtYXBPcHRpb25zXG4gICAgfCBUZW5zb3JGcm9tVXJsT3B0aW9ucyxcbik6IFByb21pc2U8VGVuc29yPiA9PiB7XG4gIC8vIGNoZWNraW5nIHRoZSB0eXBlIG9mIGltYWdlIG9iamVjdFxuICBjb25zdCBpc0hUTUxJbWFnZUVsZSA9IHR5cGVvZiBIVE1MSW1hZ2VFbGVtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBpbWFnZSBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnQ7XG4gIGNvbnN0IGlzSW1hZ2VEYXRhRWxlID0gdHlwZW9mIEltYWdlRGF0YSAhPT0gJ3VuZGVmaW5lZCcgJiYgaW1hZ2UgaW5zdGFuY2VvZiBJbWFnZURhdGE7XG4gIGNvbnN0IGlzSW1hZ2VCaXRtYXAgPSB0eXBlb2YgSW1hZ2VCaXRtYXAgIT09ICd1bmRlZmluZWQnICYmIGltYWdlIGluc3RhbmNlb2YgSW1hZ2VCaXRtYXA7XG4gIGNvbnN0IGlzU3RyaW5nID0gdHlwZW9mIGltYWdlID09PSAnc3RyaW5nJztcblxuICBsZXQgZGF0YTogVWludDhDbGFtcGVkQXJyYXkgfCB1bmRlZmluZWQ7XG4gIGxldCBidWZmZXJUb1RlbnNvck9wdGlvbnM6IEJ1ZmZlclRvVGVuc29yT3B0aW9ucyA9IG9wdGlvbnMgPz8ge307XG5cbiAgY29uc3QgY3JlYXRlQ2FudmFzID0gKCkgPT4ge1xuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgT2Zmc2NyZWVuQ2FudmFzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIG5ldyBPZmZzY3JlZW5DYW52YXMoMSwgMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2FudmFzIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH07XG4gIGNvbnN0IGNyZWF0ZUNhbnZhc0NvbnRleHQgPSAoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IE9mZnNjcmVlbkNhbnZhcykgPT4ge1xuICAgIGlmICh0eXBlb2YgSFRNTENhbnZhc0VsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIGNhbnZhcyBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KSB7XG4gICAgICByZXR1cm4gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgfSBlbHNlIGlmIChjYW52YXMgaW5zdGFuY2VvZiBPZmZzY3JlZW5DYW52YXMpIHtcbiAgICAgIHJldHVybiBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhcyBPZmZzY3JlZW5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfTtcbiAgLy8gZmlsbGluZyBhbmQgY2hlY2tpbmcgaW1hZ2UgY29uZmlndXJhdGlvbiBvcHRpb25zXG4gIGlmIChpc0hUTUxJbWFnZUVsZSkge1xuICAgIC8vIEhUTUxJbWFnZUVsZW1lbnQgLSBpbWFnZSBvYmplY3QgLSBmb3JtYXQgaXMgUkdCQSBieSBkZWZhdWx0XG4gICAgY29uc3QgY2FudmFzID0gY3JlYXRlQ2FudmFzKCk7XG4gICAgY2FudmFzLndpZHRoID0gaW1hZ2Uud2lkdGg7XG4gICAgY2FudmFzLmhlaWdodCA9IGltYWdlLmhlaWdodDtcbiAgICBjb25zdCBwaXhlbHMyRENvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0KGNhbnZhcyk7XG5cbiAgICBpZiAocGl4ZWxzMkRDb250ZXh0ICE9IG51bGwpIHtcbiAgICAgIGxldCBoZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XG4gICAgICBsZXQgd2lkdGggPSBpbWFnZS53aWR0aDtcbiAgICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy5yZXNpemVkSGVpZ2h0ICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy5yZXNpemVkV2lkdGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBoZWlnaHQgPSBvcHRpb25zLnJlc2l6ZWRIZWlnaHQ7XG4gICAgICAgIHdpZHRoID0gb3B0aW9ucy5yZXNpemVkV2lkdGg7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgaWYgKG9wdGlvbnMudGVuc29yRm9ybWF0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltYWdlIGlucHV0IGNvbmZpZyBmb3JtYXQgbXVzdCBiZSBSR0JBIGZvciBIVE1MSW1hZ2VFbGVtZW50Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLnRlbnNvckZvcm1hdCA9ICdSR0JBJztcbiAgICAgICAgfVxuICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMud2lkdGggPSB3aWR0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy50ZW5zb3JGb3JtYXQgPSAnUkdCQSc7XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy53aWR0aCA9IHdpZHRoO1xuICAgICAgfVxuXG4gICAgICBwaXhlbHMyRENvbnRleHQuZHJhd0ltYWdlKGltYWdlLCAwLCAwKTtcbiAgICAgIGRhdGEgPSBwaXhlbHMyRENvbnRleHQuZ2V0SW1hZ2VEYXRhKDAsIDAsIHdpZHRoLCBoZWlnaHQpLmRhdGE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBhY2Nlc3MgaW1hZ2UgZGF0YScpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc0ltYWdlRGF0YUVsZSkge1xuICAgIGxldCBoZWlnaHQ6IG51bWJlcjtcbiAgICBsZXQgd2lkdGg6IG51bWJlcjtcblxuICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy5yZXNpemVkV2lkdGggIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnJlc2l6ZWRIZWlnaHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaGVpZ2h0ID0gb3B0aW9ucy5yZXNpemVkSGVpZ2h0O1xuICAgICAgd2lkdGggPSBvcHRpb25zLnJlc2l6ZWRXaWR0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuICAgICAgd2lkdGggPSBpbWFnZS53aWR0aDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMgPSBvcHRpb25zO1xuICAgIH1cbiAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMuZm9ybWF0ID0gJ1JHQkEnO1xuICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLndpZHRoID0gd2lkdGg7XG5cbiAgICBpZiAob3B0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCB0ZW1wQ2FudmFzID0gY3JlYXRlQ2FudmFzKCk7XG5cbiAgICAgIHRlbXBDYW52YXMud2lkdGggPSB3aWR0aDtcbiAgICAgIHRlbXBDYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXG4gICAgICBjb25zdCBwaXhlbHMyRENvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0KHRlbXBDYW52YXMpO1xuXG4gICAgICBpZiAocGl4ZWxzMkRDb250ZXh0ICE9IG51bGwpIHtcbiAgICAgICAgcGl4ZWxzMkRDb250ZXh0LnB1dEltYWdlRGF0YShpbWFnZSwgMCwgMCk7XG4gICAgICAgIGRhdGEgPSBwaXhlbHMyRENvbnRleHQuZ2V0SW1hZ2VEYXRhKDAsIDAsIHdpZHRoLCBoZWlnaHQpLmRhdGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBub3QgYWNjZXNzIGltYWdlIGRhdGEnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YSA9IGltYWdlLmRhdGE7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzSW1hZ2VCaXRtYXApIHtcbiAgICAvLyBJbWFnZUJpdG1hcCAtIGltYWdlIG9iamVjdCAtIGZvcm1hdCBtdXN0IGJlIHByb3ZpZGVkIGJ5IHVzZXJcbiAgICBpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIGltYWdlIGNvbmZpZyB3aXRoIGZvcm1hdCBmb3IgSW1hZ2ViaXRtYXAnKTtcbiAgICB9XG5cbiAgICBjb25zdCBjYW52YXMgPSBjcmVhdGVDYW52YXMoKTtcbiAgICBjYW52YXMud2lkdGggPSBpbWFnZS53aWR0aDtcbiAgICBjYW52YXMuaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuICAgIGNvbnN0IHBpeGVsczJEQ29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQoY2FudmFzKTtcblxuICAgIGlmIChwaXhlbHMyRENvbnRleHQgIT0gbnVsbCkge1xuICAgICAgY29uc3QgaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuICAgICAgY29uc3Qgd2lkdGggPSBpbWFnZS53aWR0aDtcbiAgICAgIHBpeGVsczJEQ29udGV4dC5kcmF3SW1hZ2UoaW1hZ2UsIDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuICAgICAgZGF0YSA9IHBpeGVsczJEQ29udGV4dC5nZXRJbWFnZURhdGEoMCwgMCwgd2lkdGgsIGhlaWdodCkuZGF0YTtcbiAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMud2lkdGggPSB3aWR0aDtcbiAgICAgIHJldHVybiBidWZmZXJUb1RlbnNvcihkYXRhLCBidWZmZXJUb1RlbnNvck9wdGlvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBub3QgYWNjZXNzIGltYWdlIGRhdGEnKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNTdHJpbmcpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgY2FudmFzID0gY3JlYXRlQ2FudmFzKCk7XG4gICAgICBjb25zdCBjb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dChjYW52YXMpO1xuICAgICAgaWYgKCFpbWFnZSB8fCAhY29udGV4dCkge1xuICAgICAgICByZXR1cm4gcmVqZWN0KCk7XG4gICAgICB9XG4gICAgICBjb25zdCBuZXdJbWFnZSA9IG5ldyBJbWFnZSgpO1xuICAgICAgbmV3SW1hZ2UuY3Jvc3NPcmlnaW4gPSAnQW5vbnltb3VzJztcbiAgICAgIG5ld0ltYWdlLnNyYyA9IGltYWdlO1xuICAgICAgbmV3SW1hZ2Uub25sb2FkID0gKCkgPT4ge1xuICAgICAgICBjYW52YXMud2lkdGggPSBuZXdJbWFnZS53aWR0aDtcbiAgICAgICAgY2FudmFzLmhlaWdodCA9IG5ld0ltYWdlLmhlaWdodDtcbiAgICAgICAgY29udGV4dC5kcmF3SW1hZ2UobmV3SW1hZ2UsIDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XG4gICAgICAgIGNvbnN0IGltZyA9IGNvbnRleHQuZ2V0SW1hZ2VEYXRhKDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XG5cbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLmhlaWdodCA9IGNhbnZhcy5oZWlnaHQ7XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy53aWR0aCA9IGNhbnZhcy53aWR0aDtcbiAgICAgICAgcmVzb2x2ZShidWZmZXJUb1RlbnNvcihpbWcuZGF0YSwgYnVmZmVyVG9UZW5zb3JPcHRpb25zKSk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgZGF0YSBwcm92aWRlZCBpcyBub3Qgc3VwcG9ydGVkIC0gYWJvcnRlZCB0ZW5zb3IgY3JlYXRpb24nKTtcbiAgfVxuXG4gIGlmIChkYXRhICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gYnVmZmVyVG9UZW5zb3IoZGF0YSwgYnVmZmVyVG9UZW5zb3JPcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGRhdGEgcHJvdmlkZWQgaXMgbm90IHN1cHBvcnRlZCAtIGFib3J0ZWQgdGVuc29yIGNyZWF0aW9uJyk7XG4gIH1cbn07XG5cbi8qKlxuICogaW1wbGVtZW50YXRpb24gb2YgVGVuc29yLmZyb21UZXh0dXJlKCkuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JGcm9tVGV4dHVyZSA9IDxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLlRleHR1cmVEYXRhVHlwZXM+KFxuICB0ZXh0dXJlOiBUZW5zb3JJbnRlcmZhY2UuVGV4dHVyZVR5cGUsXG4gIG9wdGlvbnM6IFRlbnNvckZyb21UZXh0dXJlT3B0aW9uczxUPixcbik6IFRlbnNvciA9PiB7XG4gIGNvbnN0IHsgd2lkdGgsIGhlaWdodCwgZG93bmxvYWQsIGRpc3Bvc2UgfSA9IG9wdGlvbnM7XG4gIC8vIEFsd2F5cyBhc3N1bWUgUkdCQUYzMi4gVE9ETzogc3VwcG9ydCBkaWZmZXJlbnQgdGV4dHVyZSBmb3JtYXRcbiAgY29uc3QgZGltcyA9IFsxLCBoZWlnaHQsIHdpZHRoLCA0XTtcbiAgcmV0dXJuIG5ldyBUZW5zb3IoeyBsb2NhdGlvbjogJ3RleHR1cmUnLCB0eXBlOiAnZmxvYXQzMicsIHRleHR1cmUsIGRpbXMsIGRvd25sb2FkLCBkaXNwb3NlIH0pO1xufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IuZnJvbUdwdUJ1ZmZlcigpLlxuICovXG5leHBvcnQgY29uc3QgdGVuc29yRnJvbUdwdUJ1ZmZlciA9IDxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLkdwdUJ1ZmZlckRhdGFUeXBlcz4oXG4gIGdwdUJ1ZmZlcjogVGVuc29ySW50ZXJmYWNlLkdwdUJ1ZmZlclR5cGUsXG4gIG9wdGlvbnM6IFRlbnNvckZyb21HcHVCdWZmZXJPcHRpb25zPFQ+LFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgeyBkYXRhVHlwZSwgZGltcywgZG93bmxvYWQsIGRpc3Bvc2UgfSA9IG9wdGlvbnM7XG4gIHJldHVybiBuZXcgVGVuc29yKHsgbG9jYXRpb246ICdncHUtYnVmZmVyJywgdHlwZTogZGF0YVR5cGUgPz8gJ2Zsb2F0MzInLCBncHVCdWZmZXIsIGRpbXMsIGRvd25sb2FkLCBkaXNwb3NlIH0pO1xufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IuZnJvbU1MVGVuc29yKCkuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JGcm9tTUxUZW5zb3IgPSA8VCBleHRlbmRzIFRlbnNvckludGVyZmFjZS5NTFRlbnNvckRhdGFUeXBlcz4oXG4gIG1sVGVuc29yOiBUZW5zb3JJbnRlcmZhY2UuTUxUZW5zb3JUeXBlLFxuICBvcHRpb25zOiBUZW5zb3JGcm9tTUxUZW5zb3JPcHRpb25zPFQ+LFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgeyBkYXRhVHlwZSwgZGltcywgZG93bmxvYWQsIGRpc3Bvc2UgfSA9IG9wdGlvbnM7XG4gIHJldHVybiBuZXcgVGVuc29yKHsgbG9jYXRpb246ICdtbC10ZW5zb3InLCB0eXBlOiBkYXRhVHlwZSA/PyAnZmxvYXQzMicsIG1sVGVuc29yLCBkaW1zLCBkb3dubG9hZCwgZGlzcG9zZSB9KTtcbn07XG5cbi8qKlxuICogaW1wbGVtZW50YXRpb24gb2YgVGVuc29yLmZyb21QaW5uZWRCdWZmZXIoKS5cbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvckZyb21QaW5uZWRCdWZmZXIgPSA8VCBleHRlbmRzIFRlbnNvckludGVyZmFjZS5DcHVQaW5uZWREYXRhVHlwZXM+KFxuICB0eXBlOiBULFxuICBidWZmZXI6IFRlbnNvckludGVyZmFjZS5EYXRhVHlwZU1hcFtUXSxcbiAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuKTogVGVuc29yID0+IG5ldyBUZW5zb3IoeyBsb2NhdGlvbjogJ2NwdS1waW5uZWQnLCB0eXBlLCBkYXRhOiBidWZmZXIsIGRpbXM6IGRpbXMgPz8gW2J1ZmZlci5sZW5ndGhdIH0pO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvci5qcyc7XG5cbmV4cG9ydCB0eXBlIFN1cHBvcnRlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcnMgPVxuICB8IEZsb2F0MzJBcnJheUNvbnN0cnVjdG9yXG4gIHwgVWludDhBcnJheUNvbnN0cnVjdG9yXG4gIHwgSW50OEFycmF5Q29uc3RydWN0b3JcbiAgfCBVaW50MTZBcnJheUNvbnN0cnVjdG9yXG4gIHwgSW50MTZBcnJheUNvbnN0cnVjdG9yXG4gIHwgSW50MzJBcnJheUNvbnN0cnVjdG9yXG4gIHwgQmlnSW50NjRBcnJheUNvbnN0cnVjdG9yXG4gIHwgVWludDhBcnJheUNvbnN0cnVjdG9yXG4gIHwgRmxvYXQ2NEFycmF5Q29uc3RydWN0b3JcbiAgfCBVaW50MzJBcnJheUNvbnN0cnVjdG9yXG4gIHwgQmlnVWludDY0QXJyYXlDb25zdHJ1Y3RvcjtcbmV4cG9ydCB0eXBlIFN1cHBvcnRlZFR5cGVkQXJyYXkgPSBJbnN0YW5jZVR5cGU8U3VwcG9ydGVkVHlwZWRBcnJheUNvbnN0cnVjdG9ycz47XG5cbi8vIGEgcnVudGltZSBtYXAgdGhhdCBtYXBzIHR5cGUgc3RyaW5nIHRvIFR5cGVkQXJyYXkgY29uc3RydWN0b3IuIFNob3VsZCBtYXRjaCBUZW5zb3IuRGF0YVR5cGVNYXAuXG5leHBvcnQgY29uc3QgTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUCA9IG5ldyBNYXA8c3RyaW5nLCBTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzPihbXG4gIFsnZmxvYXQzMicsIEZsb2F0MzJBcnJheV0sXG4gIFsndWludDgnLCBVaW50OEFycmF5XSxcbiAgWydpbnQ4JywgSW50OEFycmF5XSxcbiAgWyd1aW50MTYnLCBVaW50MTZBcnJheV0sXG4gIFsnaW50MTYnLCBJbnQxNkFycmF5XSxcbiAgWydpbnQzMicsIEludDMyQXJyYXldLFxuICBbJ2Jvb2wnLCBVaW50OEFycmF5XSxcbiAgWydmbG9hdDY0JywgRmxvYXQ2NEFycmF5XSxcbiAgWyd1aW50MzInLCBVaW50MzJBcnJheV0sXG4gIFsnaW50NCcsIFVpbnQ4QXJyYXldLFxuICBbJ3VpbnQ0JywgVWludDhBcnJheV0sXG5dKTtcblxuLy8gYSBydW50aW1lIG1hcCB0aGF0IG1hcHMgdHlwZSBzdHJpbmcgdG8gVHlwZWRBcnJheSBjb25zdHJ1Y3Rvci4gU2hvdWxkIG1hdGNoIFRlbnNvci5EYXRhVHlwZU1hcC5cbmV4cG9ydCBjb25zdCBOVU1FUklDX1RFTlNPUl9UWVBFREFSUkFZX1RPX1RZUEVfTUFQID0gbmV3IE1hcDxTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzLCBUZW5zb3IuVHlwZT4oW1xuICBbRmxvYXQzMkFycmF5LCAnZmxvYXQzMiddLFxuICBbVWludDhBcnJheSwgJ3VpbnQ4J10sXG4gIFtJbnQ4QXJyYXksICdpbnQ4J10sXG4gIFtVaW50MTZBcnJheSwgJ3VpbnQxNiddLFxuICBbSW50MTZBcnJheSwgJ2ludDE2J10sXG4gIFtJbnQzMkFycmF5LCAnaW50MzInXSxcbiAgW0Zsb2F0NjRBcnJheSwgJ2Zsb2F0NjQnXSxcbiAgW1VpbnQzMkFycmF5LCAndWludDMyJ10sXG5dKTtcblxuLy8gdGhlIGZvbGxvd2luZyBjb2RlIGFsbG93cyBkZWxheWluZyBleGVjdXRpb24gb2YgQmlnSW50L0Zsb2F0MTZBcnJheSBjaGVja2luZy4gVGhpcyBhbGxvd3MgbGF6eSBpbml0aWFsaXphdGlvbiBmb3Jcbi8vIE5VTUVSSUNfVEVOU09SX1RZUEVfVE9fVFlQRURBUlJBWV9NQVAgYW5kIE5VTUVSSUNfVEVOU09SX1RZUEVEQVJSQVlfVE9fVFlQRV9NQVAsIHdoaWNoIGFsbG93cyBCaWdJbnQvRmxvYXQxNkFycmF5XG4vLyBwb2x5ZmlsbCBpZiBhdmFpbGFibGUuXG5sZXQgaXNUeXBlZEFycmF5Q2hlY2tlZCA9IGZhbHNlO1xuZXhwb3J0IGNvbnN0IGNoZWNrVHlwZWRBcnJheSA9ICgpID0+IHtcbiAgaWYgKCFpc1R5cGVkQXJyYXlDaGVja2VkKSB7XG4gICAgaXNUeXBlZEFycmF5Q2hlY2tlZCA9IHRydWU7XG4gICAgY29uc3QgaXNCaWdJbnQ2NEFycmF5QXZhaWxhYmxlID0gdHlwZW9mIEJpZ0ludDY0QXJyYXkgIT09ICd1bmRlZmluZWQnICYmIEJpZ0ludDY0QXJyYXkuZnJvbTtcbiAgICBjb25zdCBpc0JpZ1VpbnQ2NEFycmF5QXZhaWxhYmxlID0gdHlwZW9mIEJpZ1VpbnQ2NEFycmF5ICE9PSAndW5kZWZpbmVkJyAmJiBCaWdVaW50NjRBcnJheS5mcm9tO1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiwgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IEZsb2F0MTZBcnJheSA9IChnbG9iYWxUaGlzIGFzIGFueSkuRmxvYXQxNkFycmF5O1xuICAgIGNvbnN0IGlzRmxvYXQxNkFycmF5QXZhaWxhYmxlID0gdHlwZW9mIEZsb2F0MTZBcnJheSAhPT0gJ3VuZGVmaW5lZCcgJiYgRmxvYXQxNkFycmF5LmZyb207XG5cbiAgICBpZiAoaXNCaWdJbnQ2NEFycmF5QXZhaWxhYmxlKSB7XG4gICAgICBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQLnNldCgnaW50NjQnLCBCaWdJbnQ2NEFycmF5KTtcbiAgICAgIE5VTUVSSUNfVEVOU09SX1RZUEVEQVJSQVlfVE9fVFlQRV9NQVAuc2V0KEJpZ0ludDY0QXJyYXksICdpbnQ2NCcpO1xuICAgIH1cbiAgICBpZiAoaXNCaWdVaW50NjRBcnJheUF2YWlsYWJsZSkge1xuICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUC5zZXQoJ3VpbnQ2NCcsIEJpZ1VpbnQ2NEFycmF5KTtcbiAgICAgIE5VTUVSSUNfVEVOU09SX1RZUEVEQVJSQVlfVE9fVFlQRV9NQVAuc2V0KEJpZ1VpbnQ2NEFycmF5LCAndWludDY0Jyk7XG4gICAgfVxuICAgIGlmIChpc0Zsb2F0MTZBcnJheUF2YWlsYWJsZSkge1xuICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUC5zZXQoJ2Zsb2F0MTYnLCBGbG9hdDE2QXJyYXkpO1xuICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRURBUlJBWV9UT19UWVBFX01BUC5zZXQoRmxvYXQxNkFycmF5LCAnZmxvYXQxNicpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBpZiBGbG9hdDE2QXJyYXkgaXMgbm90IGF2YWlsYWJsZSwgdXNlICdVaW50MTZBcnJheScgdG8gc3RvcmUgdGhlIGRhdGEuXG4gICAgICBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQLnNldCgnZmxvYXQxNicsIFVpbnQxNkFycmF5KTtcbiAgICB9XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7XG4gIENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVycyxcbiAgR3B1QnVmZmVyQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxuICBNTFRlbnNvckNvbnN0cnVjdG9yUGFyYW1ldGVycyxcbiAgVGV4dHVyZUNvbnN0cnVjdG9yUGFyYW1ldGVycyxcbn0gZnJvbSAnLi90ZW5zb3ItZmFjdG9yeS5qcyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvci1pbXBsLmpzJztcblxuLyoqXG4gKiBjYWxjdWxhdGUgc2l6ZSBmcm9tIGRpbXMuXG4gKlxuICogQHBhcmFtIGRpbXMgdGhlIGRpbXMgYXJyYXkuIE1heSBiZSBhbiBpbGxlZ2FsIGlucHV0LlxuICovXG5leHBvcnQgY29uc3QgY2FsY3VsYXRlU2l6ZSA9IChkaW1zOiByZWFkb25seSB1bmtub3duW10pOiBudW1iZXIgPT4ge1xuICBsZXQgc2l6ZSA9IDE7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGltcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGRpbSA9IGRpbXNbaV07XG4gICAgaWYgKHR5cGVvZiBkaW0gIT09ICdudW1iZXInIHx8ICFOdW1iZXIuaXNTYWZlSW50ZWdlcihkaW0pKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBkaW1zWyR7aX1dIG11c3QgYmUgYW4gaW50ZWdlciwgZ290OiAke2RpbX1gKTtcbiAgICB9XG4gICAgaWYgKGRpbSA8IDApIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBkaW1zWyR7aX1dIG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50ZWdlciwgZ290OiAke2RpbX1gKTtcbiAgICB9XG4gICAgc2l6ZSAqPSBkaW07XG4gIH1cbiAgcmV0dXJuIHNpemU7XG59O1xuXG4vKipcbiAqIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvci5yZXNoYXBlKClcbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvclJlc2hhcGUgPSAodGVuc29yOiBUZW5zb3IsIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yID0+IHtcbiAgc3dpdGNoICh0ZW5zb3IubG9jYXRpb24pIHtcbiAgICBjYXNlICdjcHUnOlxuICAgICAgcmV0dXJuIG5ldyBUZW5zb3IodGVuc29yLnR5cGUsIHRlbnNvci5kYXRhLCBkaW1zKTtcbiAgICBjYXNlICdjcHUtcGlubmVkJzpcbiAgICAgIHJldHVybiBuZXcgVGVuc29yKHtcbiAgICAgICAgbG9jYXRpb246ICdjcHUtcGlubmVkJyxcbiAgICAgICAgZGF0YTogdGVuc29yLmRhdGEgYXMgQ3B1UGlubmVkQ29uc3RydWN0b3JQYXJhbWV0ZXJzWydkYXRhJ10sXG4gICAgICAgIHR5cGU6IHRlbnNvci50eXBlIGFzIENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVyc1sndHlwZSddLFxuICAgICAgICBkaW1zLFxuICAgICAgfSk7XG4gICAgY2FzZSAndGV4dHVyZSc6XG4gICAgICByZXR1cm4gbmV3IFRlbnNvcih7XG4gICAgICAgIGxvY2F0aW9uOiAndGV4dHVyZScsXG4gICAgICAgIHRleHR1cmU6IHRlbnNvci50ZXh0dXJlLFxuICAgICAgICB0eXBlOiB0ZW5zb3IudHlwZSBhcyBUZXh0dXJlQ29uc3RydWN0b3JQYXJhbWV0ZXJzWyd0eXBlJ10sXG4gICAgICAgIGRpbXMsXG4gICAgICB9KTtcbiAgICBjYXNlICdncHUtYnVmZmVyJzpcbiAgICAgIHJldHVybiBuZXcgVGVuc29yKHtcbiAgICAgICAgbG9jYXRpb246ICdncHUtYnVmZmVyJyxcbiAgICAgICAgZ3B1QnVmZmVyOiB0ZW5zb3IuZ3B1QnVmZmVyLFxuICAgICAgICB0eXBlOiB0ZW5zb3IudHlwZSBhcyBHcHVCdWZmZXJDb25zdHJ1Y3RvclBhcmFtZXRlcnNbJ3R5cGUnXSxcbiAgICAgICAgZGltcyxcbiAgICAgIH0pO1xuICAgIGNhc2UgJ21sLXRlbnNvcic6XG4gICAgICByZXR1cm4gbmV3IFRlbnNvcih7XG4gICAgICAgIGxvY2F0aW9uOiAnbWwtdGVuc29yJyxcbiAgICAgICAgbWxUZW5zb3I6IHRlbnNvci5tbFRlbnNvcixcbiAgICAgICAgdHlwZTogdGVuc29yLnR5cGUgYXMgTUxUZW5zb3JDb25zdHJ1Y3RvclBhcmFtZXRlcnNbJ3R5cGUnXSxcbiAgICAgICAgZGltcyxcbiAgICAgIH0pO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHRlbnNvclJlc2hhcGU6IHRlbnNvciBsb2NhdGlvbiAke3RlbnNvci5sb2NhdGlvbn0gaXMgbm90IHN1cHBvcnRlZGApO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyB0ZW5zb3JUb0RhdGFVUkwsIHRlbnNvclRvSW1hZ2VEYXRhIH0gZnJvbSAnLi90ZW5zb3ItY29udmVyc2lvbi1pbXBsLmpzJztcbmltcG9ydCB7IFRlbnNvclRvRGF0YVVybE9wdGlvbnMsIFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyB9IGZyb20gJy4vdGVuc29yLWNvbnZlcnNpb24uanMnO1xuaW1wb3J0IHtcbiAgdGVuc29yRnJvbUdwdUJ1ZmZlcixcbiAgdGVuc29yRnJvbUltYWdlLFxuICB0ZW5zb3JGcm9tTUxUZW5zb3IsXG4gIHRlbnNvckZyb21QaW5uZWRCdWZmZXIsXG4gIHRlbnNvckZyb21UZXh0dXJlLFxufSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LWltcGwuanMnO1xuaW1wb3J0IHtcbiAgQ3B1UGlubmVkQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxuICBHcHVCdWZmZXJDb25zdHJ1Y3RvclBhcmFtZXRlcnMsXG4gIE1MVGVuc29yQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxuICBUZW5zb3JGcm9tR3B1QnVmZmVyT3B0aW9ucyxcbiAgVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9ucyxcbiAgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnMsXG4gIFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zLFxuICBUZW5zb3JGcm9tTUxUZW5zb3JPcHRpb25zLFxuICBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnMsXG4gIFRlbnNvckZyb21VcmxPcHRpb25zLFxuICBUZXh0dXJlQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxufSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcbmltcG9ydCB7XG4gIGNoZWNrVHlwZWRBcnJheSxcbiAgTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUCxcbiAgTlVNRVJJQ19URU5TT1JfVFlQRURBUlJBWV9UT19UWVBFX01BUCxcbiAgU3VwcG9ydGVkVHlwZWRBcnJheSxcbiAgU3VwcG9ydGVkVHlwZWRBcnJheUNvbnN0cnVjdG9ycyxcbn0gZnJvbSAnLi90ZW5zb3ItaW1wbC10eXBlLW1hcHBpbmcuanMnO1xuaW1wb3J0IHsgY2FsY3VsYXRlU2l6ZSwgdGVuc29yUmVzaGFwZSB9IGZyb20gJy4vdGVuc29yLXV0aWxzLWltcGwuanMnO1xuaW1wb3J0IHsgVGVuc29yIGFzIFRlbnNvckludGVyZmFjZSB9IGZyb20gJy4vdGVuc29yLmpzJztcblxuLy8gdHlwZSBhbGlhc2VzIGZvciB0aG9zZSBleHBvcnRlZCBmcm9tIFRlbnNvciBpbnRlcmZhY2VcblxudHlwZSBUZW5zb3JUeXBlID0gVGVuc29ySW50ZXJmYWNlLlR5cGU7XG50eXBlIFRlbnNvckRhdGFUeXBlID0gVGVuc29ySW50ZXJmYWNlLkRhdGFUeXBlO1xudHlwZSBUZW5zb3JEYXRhTG9jYXRpb24gPSBUZW5zb3JJbnRlcmZhY2UuRGF0YUxvY2F0aW9uO1xudHlwZSBUZW5zb3JUZXh0dXJlVHlwZSA9IFRlbnNvckludGVyZmFjZS5UZXh0dXJlVHlwZTtcbnR5cGUgVGVuc29yR3B1QnVmZmVyVHlwZSA9IFRlbnNvckludGVyZmFjZS5HcHVCdWZmZXJUeXBlO1xudHlwZSBUZW5zb3JNTFRlbnNvclR5cGUgPSBUZW5zb3JJbnRlcmZhY2UuTUxUZW5zb3JUeXBlO1xuXG4vKipcbiAqIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IgaW50ZXJmYWNlLlxuICpcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGNsYXNzIFRlbnNvciBpbXBsZW1lbnRzIFRlbnNvckludGVyZmFjZSB7XG4gIC8vICNyZWdpb24gY29uc3RydWN0b3JzXG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBDUFUgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB0eXBlLCBkYXRhIGFuZCBkaW1zLlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgdHlwZTogVGVuc29yVHlwZSxcbiAgICBkYXRhOiBUZW5zb3JEYXRhVHlwZSB8IFVpbnQ4Q2xhbXBlZEFycmF5IHwgcmVhZG9ubHkgc3RyaW5nW10gfCByZWFkb25seSBudW1iZXJbXSB8IHJlYWRvbmx5IGJvb2xlYW5bXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgQ1BVIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy4gVHlwZSBpcyBpbmZlcnJlZCBmcm9tIGRhdGEuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBkYXRhOiBUZW5zb3JEYXRhVHlwZSB8IFVpbnQ4Q2xhbXBlZEFycmF5IHwgcmVhZG9ubHkgc3RyaW5nW10gfCByZWFkb25seSBib29sZWFuW10sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApO1xuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgcGlubmVkIENQVSBkYXRhIHdpdGggdGhlIGdpdmVuIHR5cGUgYW5kIGRpbXMuXG4gICAqXG4gICAqIFRlbnNvcidzIGxvY2F0aW9uIHdpbGwgYmUgc2V0IHRvICdjcHUtcGlubmVkJy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFNwZWNpZnkgdGhlIHBhcmFtZXRlcnMgdG8gY29uc3RydWN0IHRoZSB0ZW5zb3IuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihwYXJhbXM6IENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVycyk7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBXZWJHTCB0ZXh0dXJlIHdpdGggdGhlIGdpdmVuIHR5cGUgYW5kIGRpbXMuXG4gICAqXG4gICAqIFRlbnNvcidzIGxvY2F0aW9uIHdpbGwgYmUgc2V0IHRvICd0ZXh0dXJlJy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFNwZWNpZnkgdGhlIHBhcmFtZXRlcnMgdG8gY29uc3RydWN0IHRoZSB0ZW5zb3IuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihwYXJhbXM6IFRleHR1cmVDb25zdHJ1Y3RvclBhcmFtZXRlcnMpO1xuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgV2ViR1BVIGJ1ZmZlciB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBkaW1zLlxuICAgKlxuICAgKiBUZW5zb3IncyBsb2NhdGlvbiB3aWxsIGJlIHNldCB0byAnZ3B1LWJ1ZmZlcicuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBTcGVjaWZ5IHRoZSBwYXJhbWV0ZXJzIHRvIGNvbnN0cnVjdCB0aGUgdGVuc29yLlxuICAgKi9cbiAgY29uc3RydWN0b3IocGFyYW1zOiBHcHVCdWZmZXJDb25zdHJ1Y3RvclBhcmFtZXRlcnMpO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBXZWJOTiBNTFRlbnNvciB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBkaW1zLlxuICAgKlxuICAgKiBUZW5zb3IncyBsb2NhdGlvbiB3aWxsIGJlIHNldCB0byAnbWwtdGVuc29yJy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFNwZWNpZnkgdGhlIHBhcmFtZXRlcnMgdG8gY29uc3RydWN0IHRoZSB0ZW5zb3IuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihwYXJhbXM6IE1MVGVuc29yQ29uc3RydWN0b3JQYXJhbWV0ZXJzKTtcblxuICAvKipcbiAgICogaW1wbGVtZW50YXRpb24uXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBhcmcwOlxuICAgICAgfCBUZW5zb3JUeXBlXG4gICAgICB8IFRlbnNvckRhdGFUeXBlXG4gICAgICB8IFVpbnQ4Q2xhbXBlZEFycmF5XG4gICAgICB8IHJlYWRvbmx5IHN0cmluZ1tdXG4gICAgICB8IHJlYWRvbmx5IGJvb2xlYW5bXVxuICAgICAgfCBDcHVQaW5uZWRDb25zdHJ1Y3RvclBhcmFtZXRlcnNcbiAgICAgIHwgVGV4dHVyZUNvbnN0cnVjdG9yUGFyYW1ldGVyc1xuICAgICAgfCBHcHVCdWZmZXJDb25zdHJ1Y3RvclBhcmFtZXRlcnNcbiAgICAgIHwgTUxUZW5zb3JDb25zdHJ1Y3RvclBhcmFtZXRlcnMsXG4gICAgYXJnMT86IFRlbnNvckRhdGFUeXBlIHwgVWludDhDbGFtcGVkQXJyYXkgfCByZWFkb25seSBudW1iZXJbXSB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgcmVhZG9ubHkgYm9vbGVhbltdLFxuICAgIGFyZzI/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKSB7XG4gICAgLy8gcGVyZm9ybSBvbmUtdGltZSBjaGVjayBmb3IgQmlnSW50L0Zsb2F0MTZBcnJheSBzdXBwb3J0XG4gICAgY2hlY2tUeXBlZEFycmF5KCk7XG5cbiAgICBsZXQgdHlwZTogVGVuc29yVHlwZTtcbiAgICBsZXQgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgICBpZiAodHlwZW9mIGFyZzAgPT09ICdvYmplY3QnICYmICdsb2NhdGlvbicgaW4gYXJnMCkge1xuICAgICAgLy9cbiAgICAgIC8vIGNvbnN0cnVjdGluZyB0ZW5zb3IgZnJvbSBzcGVjaWZpYyBsb2NhdGlvblxuICAgICAgLy9cbiAgICAgIHRoaXMuZGF0YUxvY2F0aW9uID0gYXJnMC5sb2NhdGlvbjtcbiAgICAgIHR5cGUgPSBhcmcwLnR5cGU7XG4gICAgICBkaW1zID0gYXJnMC5kaW1zO1xuICAgICAgc3dpdGNoIChhcmcwLmxvY2F0aW9uKSB7XG4gICAgICAgIGNhc2UgJ2NwdS1waW5uZWQnOiB7XG4gICAgICAgICAgY29uc3QgZXhwZWN0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3IgPSBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQLmdldCh0eXBlKTtcbiAgICAgICAgICBpZiAoIWV4cGVjdGVkVHlwZWRBcnJheUNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGB1bnN1cHBvcnRlZCB0eXBlIFwiJHt0eXBlfVwiIHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbSBwaW5uZWQgYnVmZmVyYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghKGFyZzAuZGF0YSBpbnN0YW5jZW9mIGV4cGVjdGVkVHlwZWRBcnJheUNvbnN0cnVjdG9yKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgYnVmZmVyIHNob3VsZCBiZSBvZiB0eXBlICR7ZXhwZWN0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3IubmFtZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5jcHVEYXRhID0gYXJnMC5kYXRhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ3RleHR1cmUnOiB7XG4gICAgICAgICAgaWYgKHR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdW5zdXBwb3J0ZWQgdHlwZSBcIiR7dHlwZX1cIiB0byBjcmVhdGUgdGVuc29yIGZyb20gdGV4dHVyZWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmdwdVRleHR1cmVEYXRhID0gYXJnMC50ZXh0dXJlO1xuICAgICAgICAgIHRoaXMuZG93bmxvYWRlciA9IGFyZzAuZG93bmxvYWQ7XG4gICAgICAgICAgdGhpcy5kaXNwb3NlciA9IGFyZzAuZGlzcG9zZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdncHUtYnVmZmVyJzoge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGUgIT09ICdmbG9hdDMyJyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2Zsb2F0MTYnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnaW50MzInICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnaW50NjQnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAndWludDMyJyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ3VpbnQ4JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2Jvb2wnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAndWludDQnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnaW50NCdcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYHVuc3VwcG9ydGVkIHR5cGUgXCIke3R5cGV9XCIgdG8gY3JlYXRlIHRlbnNvciBmcm9tIGdwdSBidWZmZXJgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5ncHVCdWZmZXJEYXRhID0gYXJnMC5ncHVCdWZmZXI7XG4gICAgICAgICAgdGhpcy5kb3dubG9hZGVyID0gYXJnMC5kb3dubG9hZDtcbiAgICAgICAgICB0aGlzLmRpc3Bvc2VyID0gYXJnMC5kaXNwb3NlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ21sLXRlbnNvcic6IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlICE9PSAnZmxvYXQzMicgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdmbG9hdDE2JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2ludDMyJyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2ludDY0JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ3VpbnQzMicgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICd1aW50NjQnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnaW50OCcgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICd1aW50OCcgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdib29sJyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ3VpbnQ0JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2ludDQnXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGB1bnN1cHBvcnRlZCB0eXBlIFwiJHt0eXBlfVwiIHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbSBNTFRlbnNvcmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLm1sVGVuc29yRGF0YSA9IGFyZzAubWxUZW5zb3I7XG4gICAgICAgICAgdGhpcy5kb3dubG9hZGVyID0gYXJnMC5kb3dubG9hZDtcbiAgICAgICAgICB0aGlzLmRpc3Bvc2VyID0gYXJnMC5kaXNwb3NlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW5zb3IgY29uc3RydWN0b3I6IHVuc3VwcG9ydGVkIGxvY2F0aW9uICcke3RoaXMuZGF0YUxvY2F0aW9ufSdgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy9cbiAgICAgIC8vIGNvbnN0cnVjdGluZyB0ZW5zb3Igb2YgbG9jYXRpb24gJ2NwdSdcbiAgICAgIC8vXG4gICAgICBsZXQgZGF0YTogVGVuc29yRGF0YVR5cGU7XG4gICAgICBsZXQgbWF5YmVEaW1zOiB0eXBlb2YgYXJnMSB8IHR5cGVvZiBhcmcyO1xuICAgICAgLy8gY2hlY2sgd2hldGhlciBhcmcwIGlzIHR5cGUgb3IgZGF0YVxuICAgICAgaWYgKHR5cGVvZiBhcmcwID09PSAnc3RyaW5nJykge1xuICAgICAgICAvL1xuICAgICAgICAvLyBPdmVycmlkZTogY29uc3RydWN0b3IodHlwZSwgZGF0YSwgLi4uKVxuICAgICAgICAvL1xuICAgICAgICB0eXBlID0gYXJnMDtcbiAgICAgICAgbWF5YmVEaW1zID0gYXJnMjtcbiAgICAgICAgaWYgKGFyZzAgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgLy8gc3RyaW5nIHRlbnNvclxuICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcmcxKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkEgc3RyaW5nIHRlbnNvcidzIGRhdGEgbXVzdCBiZSBhIHN0cmluZyBhcnJheS5cIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHdlIGRvbid0IGNoZWNrIHdoZXRoZXIgZXZlcnkgZWxlbWVudCBpbiB0aGUgYXJyYXkgaXMgc3RyaW5nOyB0aGlzIGlzIHRvbyBzbG93LiB3ZSBhc3N1bWUgaXQncyBjb3JyZWN0IGFuZFxuICAgICAgICAgIC8vIGVycm9yIHdpbGwgYmUgcG9wdWxhdGVkIGF0IGluZmVyZW5jZVxuICAgICAgICAgIGRhdGEgPSBhcmcxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIG51bWVyaWMgdGVuc29yXG4gICAgICAgICAgY29uc3QgdHlwZWRBcnJheUNvbnN0cnVjdG9yID0gTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUC5nZXQoYXJnMCk7XG4gICAgICAgICAgaWYgKHR5cGVkQXJyYXlDb25zdHJ1Y3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBVbnN1cHBvcnRlZCB0ZW5zb3IgdHlwZTogJHthcmcwfS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXJnMSkpIHtcbiAgICAgICAgICAgIGlmICgoYXJnMCA9PT0gJ2Zsb2F0MTYnICYmIHR5cGVkQXJyYXlDb25zdHJ1Y3RvciA9PT0gVWludDE2QXJyYXkpIHx8IGFyZzAgPT09ICd1aW50NCcgfHwgYXJnMCA9PT0gJ2ludDQnKSB7XG4gICAgICAgICAgICAgIC8vIC0gJ2Zsb2F0MTYnOlxuICAgICAgICAgICAgICAvLyAgIFdoZW4gbm8gRmxvYXQxNkFycmF5IHBvbHlmaWxsIGlzIHVzZWQsIHdlIGNhbm5vdCBjcmVhdGUgJ2Zsb2F0MTYnIHRlbnNvciBmcm9tIG51bWJlciBhcnJheS5cbiAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgLy8gICBUaHJvdyBlcnJvciBoZXJlIGJlY2F1c2Ugd2hlbiB1c2VyIHRyeSB0byB1c2UgbnVtYmVyIGFycmF5IGFzIGRhdGEsXG4gICAgICAgICAgICAgIC8vICAgZS5nLiBuZXcgVGVuc29yKCdmbG9hdDE2JywgWzEsIDIsIDMsIDRdLCBkaW1zKSksIGl0IHdpbGwgYWN0dWFsbHkgY2FsbFxuICAgICAgICAgICAgICAvLyAgIFVpbnQxNkFycmF5LmZyb20oYXJnMSkgd2hpY2ggZ2VuZXJhdGVzIHdyb25nIGRhdGEuXG4gICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgIC8vIC0gJ3VpbnQ0JyBhbmQgJ2ludDQnOlxuICAgICAgICAgICAgICAvLyAgIFVpbnQ4QXJyYXkuZnJvbShhcmcxKSB3aWxsIGdlbmVyYXRlIHdyb25nIGRhdGEgZm9yICd1aW50NCcgYW5kICdpbnQ0JyB0ZW5zb3IuXG4gICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICAgICAgYENyZWF0aW5nIGEgJHthcmcwfSB0ZW5zb3IgZnJvbSBudW1iZXIgYXJyYXkgaXMgbm90IHN1cHBvcnRlZC4gUGxlYXNlIHVzZSAke3R5cGVkQXJyYXlDb25zdHJ1Y3Rvci5uYW1lfSBhcyBkYXRhLmAsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFyZzAgPT09ICd1aW50NjQnIHx8IGFyZzAgPT09ICdpbnQ2NCcpIHtcbiAgICAgICAgICAgICAgLy8gdXNlICdhcyBhbnknIGhlcmUgYmVjYXVzZTpcbiAgICAgICAgICAgICAgLy8gMS4gVHlwZVNjcmlwdCdzIGNoZWNrIG9uIHR5cGUgb2YgJ0FycmF5LmlzQXJyYXkoKScgZG9lcyBub3Qgd29yayB3aXRoIHJlYWRvbmx5IGFycmF5cy5cbiAgICAgICAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvVHlwZVNjcmlwdC9pc3N1ZXMvMTcwMDJcbiAgICAgICAgICAgICAgLy8gMi4gVHlwZVNjcmlwdCdzIGNoZWNrIG9uIHVuaW9uIHR5cGUgb2YgJyhCaWdJbnQ2NEFycmF5Q29uc3RydWN0b3J8QmlnVWludDY0QXJyYXlDb25zdHJ1Y3RvcikuZnJvbSgpJ1xuICAgICAgICAgICAgICAvLyBkb2VzIG5vdCBhY2NlcHQgcGFyYW1ldGVyIG1hcEZuLlxuICAgICAgICAgICAgICAvLyAzLiBwYXJhbWV0ZXJzIG9mICdTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzLmZyb20oKScgZG9lcyBub3QgbWF0Y2ggdGhlIHJlcXVpcmVtZW50IG9mIHRoZSB1bmlvblxuICAgICAgICAgICAgICAvLyB0eXBlLlxuXG4gICAgICAgICAgICAgIC8vIGFzc3VtZSAnYXJnMScgaXMgb2YgdHlwZSBcInJlYWRvbmx5IG51bWJlcltdfHJlYWRvbmx5IGJpZ2ludFtdXCIgaGVyZS5cblxuICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAgICAgICBkYXRhID0gKHR5cGVkQXJyYXlDb25zdHJ1Y3RvciBhcyBhbnkpLmZyb20oYXJnMSwgQmlnSW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIGFzc3VtZSAnYXJnMScgaXMgb2YgdHlwZSBcInJlYWRvbmx5IG51bWJlcltdXCIgaGVyZS5cbiAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgICAgICAgZGF0YSA9ICh0eXBlZEFycmF5Q29uc3RydWN0b3IgYXMgYW55KS5mcm9tKGFyZzEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoYXJnMSBpbnN0YW5jZW9mIHR5cGVkQXJyYXlDb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgZGF0YSA9IGFyZzE7XG4gICAgICAgICAgfSBlbHNlIGlmIChhcmcxIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXkpIHtcbiAgICAgICAgICAgIGlmIChhcmcwID09PSAndWludDgnKSB7XG4gICAgICAgICAgICAgIGRhdGEgPSBVaW50OEFycmF5LmZyb20oYXJnMSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBBIFVpbnQ4Q2xhbXBlZEFycmF5IHRlbnNvcidzIGRhdGEgbXVzdCBiZSB0eXBlIG9mIHVpbnQ4YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChhcmcwID09PSAnZmxvYXQxNicgJiYgYXJnMSBpbnN0YW5jZW9mIFVpbnQxNkFycmF5ICYmIHR5cGVkQXJyYXlDb25zdHJ1Y3RvciAhPT0gVWludDE2QXJyYXkpIHtcbiAgICAgICAgICAgIC8vIHdoZW4gRmxvYXQxNkFycmF5IGlzIGF2YWlsYWJsZSBhbmQgZGF0YSBpcyBvZiB0eXBlIFVpbnQxNkFycmF5LlxuICAgICAgICAgICAgLy8gV2UgYWxsb3cgVWludDE2QXJyYXkgdG8gYmUgcGFzc2VkIGluIGFzIGRhdGEgZm9yICdmbG9hdDE2JyB0ZW5zb3IgdW50aWwgRmxvYXQxNkFycmF5IGlzIGdlbmVyYWxseVxuICAgICAgICAgICAgLy8gc3VwcG9ydGVkIGluIEphdmFTY3JpcHQgZW52aXJvbm1lbnQuXG5cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgICBkYXRhID0gbmV3IChnbG9iYWxUaGlzIGFzIGFueSkuRmxvYXQxNkFycmF5KGFyZzEuYnVmZmVyLCBhcmcxLmJ5dGVPZmZzZXQsIGFyZzEubGVuZ3RoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgQSAke3R5cGV9IHRlbnNvcidzIGRhdGEgbXVzdCBiZSB0eXBlIG9mICR7dHlwZWRBcnJheUNvbnN0cnVjdG9yfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy9cbiAgICAgICAgLy8gT3ZlcnJpZGU6IGNvbnN0cnVjdG9yKGRhdGEsIC4uLilcbiAgICAgICAgLy9cbiAgICAgICAgbWF5YmVEaW1zID0gYXJnMTtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXJnMCkpIHtcbiAgICAgICAgICAvLyBvbmx5IGJvb2xlYW5bXSBhbmQgc3RyaW5nW10gaXMgc3VwcG9ydGVkXG4gICAgICAgICAgaWYgKGFyZzAubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUZW5zb3IgdHlwZSBjYW5ub3QgYmUgaW5mZXJyZWQgZnJvbSBhbiBlbXB0eSBhcnJheS4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgZmlyc3RFbGVtZW50VHlwZSA9IHR5cGVvZiBhcmcwWzBdO1xuICAgICAgICAgIGlmIChmaXJzdEVsZW1lbnRUeXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdHlwZSA9ICdzdHJpbmcnO1xuICAgICAgICAgICAgZGF0YSA9IGFyZzA7XG4gICAgICAgICAgfSBlbHNlIGlmIChmaXJzdEVsZW1lbnRUeXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHR5cGUgPSAnYm9vbCc7XG4gICAgICAgICAgICAvLyAnYXJnMCcgaXMgb2YgdHlwZSAnYm9vbGVhbltdJy4gVWludDhBcnJheS5mcm9tKGJvb2xlYW5bXSkgYWN0dWFsbHkgd29ya3MsIGJ1dCB0eXBlc2NyaXB0IHRoaW5rcyB0aGlzIGlzXG4gICAgICAgICAgICAvLyB3cm9uZyB0eXBlLiBXZSB1c2UgJ2FzIGFueScgdG8gbWFrZSBpdCBoYXBweS5cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgICBkYXRhID0gVWludDhBcnJheS5mcm9tKGFyZzAgYXMgYW55W10pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIGVsZW1lbnQgdHlwZSBvZiBkYXRhIGFycmF5OiAke2ZpcnN0RWxlbWVudFR5cGV9LmApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChhcmcwIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXkpIHtcbiAgICAgICAgICB0eXBlID0gJ3VpbnQ4JztcbiAgICAgICAgICBkYXRhID0gVWludDhBcnJheS5mcm9tKGFyZzApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGdldCB0ZW5zb3IgdHlwZSBmcm9tIFR5cGVkQXJyYXlcbiAgICAgICAgICBjb25zdCBtYXBwZWRUeXBlID0gTlVNRVJJQ19URU5TT1JfVFlQRURBUlJBWV9UT19UWVBFX01BUC5nZXQoXG4gICAgICAgICAgICBhcmcwLmNvbnN0cnVjdG9yIGFzIFN1cHBvcnRlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcnMsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAobWFwcGVkVHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBVbnN1cHBvcnRlZCB0eXBlIGZvciB0ZW5zb3IgZGF0YTogJHthcmcwLmNvbnN0cnVjdG9yfS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdHlwZSA9IG1hcHBlZFR5cGU7XG4gICAgICAgICAgZGF0YSA9IGFyZzAgYXMgU3VwcG9ydGVkVHlwZWRBcnJheTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyB0eXBlIGFuZCBkYXRhIGlzIHByb2Nlc3NlZCwgbm93IHByb2Nlc3NpbmcgZGltc1xuICAgICAgaWYgKG1heWJlRGltcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIGFzc3VtZSAxLUQgdGVuc29yIGlmIGRpbXMgb21pdHRlZFxuICAgICAgICBtYXliZURpbXMgPSBbZGF0YS5sZW5ndGhdO1xuICAgICAgfSBlbHNlIGlmICghQXJyYXkuaXNBcnJheShtYXliZURpbXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJBIHRlbnNvcidzIGRpbXMgbXVzdCBiZSBhIG51bWJlciBhcnJheVwiKTtcbiAgICAgIH1cbiAgICAgIGRpbXMgPSBtYXliZURpbXMgYXMgcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgICAgIHRoaXMuY3B1RGF0YSA9IGRhdGE7XG4gICAgICB0aGlzLmRhdGFMb2NhdGlvbiA9ICdjcHUnO1xuICAgIH1cblxuICAgIC8vIHBlcmZvcm0gY2hlY2sgb24gZGltc1xuICAgIGNvbnN0IHNpemUgPSBjYWxjdWxhdGVTaXplKGRpbXMpO1xuICAgIC8vIGlmIGRhdGEgaXMgb24gQ1BVLCBjaGVjayB3aGV0aGVyIGRhdGEgbGVuZ3RoIG1hdGNoZXMgdGVuc29yIHNpemVcbiAgICBpZiAodGhpcy5jcHVEYXRhICYmIHNpemUgIT09IHRoaXMuY3B1RGF0YS5sZW5ndGgpIHtcbiAgICAgIGlmICgodHlwZSA9PT0gJ3VpbnQ0JyB8fCB0eXBlID09PSAnaW50NCcpICYmIE1hdGguY2VpbChzaXplIC8gMikgPT09IHRoaXMuY3B1RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgLy8gZm9yICh1KWludDQsIHRoZSBkYXRhIGxlbmd0aCBpcyBoYWxmIG9mIHRoZSB0ZW5zb3Igc2l6ZS4gU28gd2UgY2hlY2sgdGhpcyBzcGVjaWFsIGNhc2Ugd2hlbiBzaXplIGlzIG9kZC5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVGVuc29yJ3Mgc2l6ZSgke3NpemV9KSBkb2VzIG5vdCBtYXRjaCBkYXRhIGxlbmd0aCgke3RoaXMuY3B1RGF0YS5sZW5ndGh9KS5gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMuZGltcyA9IGRpbXM7XG4gICAgdGhpcy5zaXplID0gc2l6ZTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBmYWN0b3J5XG4gIHN0YXRpYyBhc3luYyBmcm9tSW1hZ2UoXG4gICAgaW1hZ2U6IEltYWdlRGF0YSB8IEhUTUxJbWFnZUVsZW1lbnQgfCBJbWFnZUJpdG1hcCB8IHN0cmluZyxcbiAgICBvcHRpb25zPzpcbiAgICAgIHwgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnNcbiAgICAgIHwgVGVuc29yRnJvbUltYWdlRWxlbWVudE9wdGlvbnNcbiAgICAgIHwgVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9uc1xuICAgICAgfCBUZW5zb3JGcm9tVXJsT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxUZW5zb3JJbnRlcmZhY2U+IHtcbiAgICByZXR1cm4gdGVuc29yRnJvbUltYWdlKGltYWdlLCBvcHRpb25zKTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tVGV4dHVyZTxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLlRleHR1cmVEYXRhVHlwZXM+KFxuICAgIHRleHR1cmU6IFRlbnNvclRleHR1cmVUeXBlLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21UZXh0dXJlT3B0aW9uczxUPixcbiAgKTogVGVuc29ySW50ZXJmYWNlIHtcbiAgICByZXR1cm4gdGVuc29yRnJvbVRleHR1cmUodGV4dHVyZSwgb3B0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgZnJvbUdwdUJ1ZmZlcjxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLkdwdUJ1ZmZlckRhdGFUeXBlcz4oXG4gICAgZ3B1QnVmZmVyOiBUZW5zb3JHcHVCdWZmZXJUeXBlLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21HcHVCdWZmZXJPcHRpb25zPFQ+LFxuICApOiBUZW5zb3JJbnRlcmZhY2Uge1xuICAgIHJldHVybiB0ZW5zb3JGcm9tR3B1QnVmZmVyKGdwdUJ1ZmZlciwgb3B0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgZnJvbU1MVGVuc29yPFQgZXh0ZW5kcyBUZW5zb3JJbnRlcmZhY2UuTUxUZW5zb3JEYXRhVHlwZXM+KFxuICAgIG1sVGVuc29yOiBUZW5zb3JNTFRlbnNvclR5cGUsXG4gICAgb3B0aW9uczogVGVuc29yRnJvbU1MVGVuc29yT3B0aW9uczxUPixcbiAgKTogVGVuc29ySW50ZXJmYWNlIHtcbiAgICByZXR1cm4gdGVuc29yRnJvbU1MVGVuc29yKG1sVGVuc29yLCBvcHRpb25zKTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tUGlubmVkQnVmZmVyPFQgZXh0ZW5kcyBUZW5zb3JJbnRlcmZhY2UuQ3B1UGlubmVkRGF0YVR5cGVzPihcbiAgICB0eXBlOiBULFxuICAgIGJ1ZmZlcjogVGVuc29ySW50ZXJmYWNlLkRhdGFUeXBlTWFwW1RdLFxuICAgIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogVGVuc29yIHtcbiAgICByZXR1cm4gdGVuc29yRnJvbVBpbm5lZEJ1ZmZlcih0eXBlLCBidWZmZXIsIGRpbXMpO1xuICB9XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gY29udmVyc2lvbnNcbiAgdG9EYXRhVVJMKG9wdGlvbnM/OiBUZW5zb3JUb0RhdGFVcmxPcHRpb25zKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGVuc29yVG9EYXRhVVJMKHRoaXMsIG9wdGlvbnMpO1xuICB9XG5cbiAgdG9JbWFnZURhdGEob3B0aW9ucz86IFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyk6IEltYWdlRGF0YSB7XG4gICAgcmV0dXJuIHRlbnNvclRvSW1hZ2VEYXRhKHRoaXMsIG9wdGlvbnMpO1xuICB9XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHB1YmxpYyBmaWVsZHNcbiAgcmVhZG9ubHkgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHR5cGU6IFRlbnNvclR5cGU7XG4gIHJlYWRvbmx5IHNpemU6IG51bWJlcjtcbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcHJpdmF0ZSBmaWVsZHNcblxuICAvKipcbiAgICogc3RvcmVzIHRoZSBsb2NhdGlvbiBvZiB0aGUgZGF0YS5cbiAgICovXG4gIHByaXZhdGUgZGF0YUxvY2F0aW9uOiBUZW5zb3JEYXRhTG9jYXRpb247XG5cbiAgLyoqXG4gICAqIHN0b3JlcyB0aGUgZGF0YSBvbiBDUFUsIGlmIGxvY2F0aW9uIGlzICdjcHUnIG9yICdjcHUtcGlubmVkJy4gb3RoZXJ3aXNlIGVtcHR5LlxuICAgKi9cbiAgcHJpdmF0ZSBjcHVEYXRhPzogVGVuc29yRGF0YVR5cGU7XG5cbiAgLyoqXG4gICAqIHN0b3JlcyB0aGUgdW5kZXJseWluZyB0ZXh0dXJlIHdoZW4gbG9jYXRpb24gaXMgJ3RleHR1cmUnLiBvdGhlcndpc2UgZW1wdHkuXG4gICAqL1xuICBwcml2YXRlIGdwdVRleHR1cmVEYXRhPzogVGVuc29yVGV4dHVyZVR5cGU7XG5cbiAgLyoqXG4gICAqIHN0b3JlcyB0aGUgdW5kZXJseWluZyBHUFUgYnVmZmVyIHdoZW4gbG9jYXRpb24gaXMgJ2dwdS1idWZmZXInLiBvdGhlcndpc2UgZW1wdHkuXG4gICAqL1xuICBwcml2YXRlIGdwdUJ1ZmZlckRhdGE/OiBUZW5zb3JHcHVCdWZmZXJUeXBlO1xuXG4gIC8qKlxuICAgKiBzdG9yZXMgdGhlIHVuZGVybHlpbmcgV2ViTk4gTUxUZW5zb3Igd2hlbiBsb2NhdGlvbiBpcyAnbWwtdGVuc29yJy4gb3RoZXJ3aXNlIGVtcHR5LlxuICAgKi9cbiAgcHJpdmF0ZSBtbFRlbnNvckRhdGE/OiBUZW5zb3JNTFRlbnNvclR5cGU7XG5cbiAgLyoqXG4gICAqIHN0b3JlcyBhbiBvcHRpb25hbCBkb3dubG9hZGVyIGZ1bmN0aW9uIHRvIGRvd25sb2FkIGRhdGEgZnJvbSBHUFUgdG8gQ1BVLlxuICAgKi9cbiAgcHJpdmF0ZSBkb3dubG9hZGVyPygpOiBQcm9taXNlPFRlbnNvckRhdGFUeXBlPjtcblxuICAvKipcbiAgICogYSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGUgZGF0YSBpcyBiZWluZyBkb3dubG9hZGVkIGZyb20gR1BVIHRvIENQVS5cbiAgICovXG4gIHByaXZhdGUgaXNEb3dubG9hZGluZz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIHN0b3JlcyBhbiBvcHRpb25hbCBkaXNwb3NlciBmdW5jdGlvbiB0byBkaXNwb3NlIHRoZSB1bmRlcmx5aW5nIGRhdGEuXG4gICAqL1xuICBwcml2YXRlIGRpc3Bvc2VyPygpOiB2b2lkO1xuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBwcm9wZXJ0aWVzXG4gIGdldCBkYXRhKCk6IFRlbnNvckRhdGFUeXBlIHtcbiAgICB0aGlzLmVuc3VyZVZhbGlkKCk7XG4gICAgaWYgKCF0aGlzLmNwdURhdGEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1RoZSBkYXRhIGlzIG5vdCBvbiBDUFUuIFVzZSBgZ2V0RGF0YSgpYCB0byBkb3dubG9hZCBHUFUgZGF0YSB0byBDUFUsICcgK1xuICAgICAgICAgICdvciB1c2UgYHRleHR1cmVgIG9yIGBncHVCdWZmZXJgIHByb3BlcnR5IHRvIGFjY2VzcyB0aGUgR1BVIGRhdGEgZGlyZWN0bHkuJyxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNwdURhdGE7XG4gIH1cblxuICBnZXQgbG9jYXRpb24oKTogVGVuc29yRGF0YUxvY2F0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhTG9jYXRpb247XG4gIH1cblxuICBnZXQgdGV4dHVyZSgpOiBUZW5zb3JUZXh0dXJlVHlwZSB7XG4gICAgdGhpcy5lbnN1cmVWYWxpZCgpO1xuICAgIGlmICghdGhpcy5ncHVUZXh0dXJlRGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZGF0YSBpcyBub3Qgc3RvcmVkIGFzIGEgV2ViR0wgdGV4dHVyZS4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ3B1VGV4dHVyZURhdGE7XG4gIH1cblxuICBnZXQgZ3B1QnVmZmVyKCk6IFRlbnNvckdwdUJ1ZmZlclR5cGUge1xuICAgIHRoaXMuZW5zdXJlVmFsaWQoKTtcbiAgICBpZiAoIXRoaXMuZ3B1QnVmZmVyRGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZGF0YSBpcyBub3Qgc3RvcmVkIGFzIGEgV2ViR1BVIGJ1ZmZlci4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ3B1QnVmZmVyRGF0YTtcbiAgfVxuXG4gIGdldCBtbFRlbnNvcigpOiBUZW5zb3JNTFRlbnNvclR5cGUge1xuICAgIHRoaXMuZW5zdXJlVmFsaWQoKTtcbiAgICBpZiAoIXRoaXMubWxUZW5zb3JEYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBkYXRhIGlzIG5vdCBzdG9yZWQgYXMgYSBXZWJOTiBNTFRlbnNvci4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubWxUZW5zb3JEYXRhO1xuICB9XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIG1ldGhvZHNcblxuICBhc3luYyBnZXREYXRhKHJlbGVhc2VEYXRhPzogYm9vbGVhbik6IFByb21pc2U8VGVuc29yRGF0YVR5cGU+IHtcbiAgICB0aGlzLmVuc3VyZVZhbGlkKCk7XG4gICAgc3dpdGNoICh0aGlzLmRhdGFMb2NhdGlvbikge1xuICAgICAgY2FzZSAnY3B1JzpcbiAgICAgIGNhc2UgJ2NwdS1waW5uZWQnOlxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhO1xuICAgICAgY2FzZSAndGV4dHVyZSc6XG4gICAgICBjYXNlICdncHUtYnVmZmVyJzpcbiAgICAgIGNhc2UgJ21sLXRlbnNvcic6IHtcbiAgICAgICAgaWYgKCF0aGlzLmRvd25sb2FkZXIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjdXJyZW50IHRlbnNvciBpcyBub3QgY3JlYXRlZCB3aXRoIGEgc3BlY2lmaWVkIGRhdGEgZG93bmxvYWRlci4nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5pc0Rvd25sb2FkaW5nKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgY3VycmVudCB0ZW5zb3IgaXMgYmVpbmcgZG93bmxvYWRlZC4nKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuaXNEb3dubG9hZGluZyA9IHRydWU7XG4gICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuZG93bmxvYWRlcigpO1xuICAgICAgICAgIHRoaXMuZG93bmxvYWRlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB0aGlzLmRhdGFMb2NhdGlvbiA9ICdjcHUnO1xuICAgICAgICAgIHRoaXMuY3B1RGF0YSA9IGRhdGE7XG5cbiAgICAgICAgICBpZiAocmVsZWFzZURhdGEgJiYgdGhpcy5kaXNwb3Nlcikge1xuICAgICAgICAgICAgdGhpcy5kaXNwb3NlcigpO1xuICAgICAgICAgICAgdGhpcy5kaXNwb3NlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICB0aGlzLmlzRG93bmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgZ2V0IGRhdGEgZnJvbSBsb2NhdGlvbjogJHt0aGlzLmRhdGFMb2NhdGlvbn1gKTtcbiAgICB9XG4gIH1cblxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzRG93bmxvYWRpbmcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGN1cnJlbnQgdGVuc29yIGlzIGJlaW5nIGRvd25sb2FkZWQuJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZGlzcG9zZXIpIHtcbiAgICAgIHRoaXMuZGlzcG9zZXIoKTtcbiAgICAgIHRoaXMuZGlzcG9zZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuY3B1RGF0YSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmdwdVRleHR1cmVEYXRhID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZ3B1QnVmZmVyRGF0YSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1sVGVuc29yRGF0YSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmRvd25sb2FkZXIgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5pc0Rvd25sb2FkaW5nID0gdW5kZWZpbmVkO1xuXG4gICAgdGhpcy5kYXRhTG9jYXRpb24gPSAnbm9uZSc7XG4gIH1cblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiB0ZW5zb3IgdXRpbGl0aWVzXG4gIHByaXZhdGUgZW5zdXJlVmFsaWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGF0YUxvY2F0aW9uID09PSAnbm9uZScpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIHRlbnNvciBpcyBkaXNwb3NlZC4nKTtcbiAgICB9XG4gIH1cblxuICByZXNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29ySW50ZXJmYWNlIHtcbiAgICB0aGlzLmVuc3VyZVZhbGlkKCk7XG4gICAgaWYgKHRoaXMuZG93bmxvYWRlciB8fCB0aGlzLmRpc3Bvc2VyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCByZXNoYXBlIGEgdGVuc29yIHRoYXQgb3ducyBHUFUgcmVzb3VyY2UuJyk7XG4gICAgfVxuICAgIHJldHVybiB0ZW5zb3JSZXNoYXBlKHRoaXMsIGRpbXMpO1xuICB9XG4gIC8vICNlbmRyZWdpb25cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yRmFjdG9yeSB9IGZyb20gJy4vdGVuc29yLWZhY3RvcnkuanMnO1xuaW1wb3J0IHsgVGVuc29yIGFzIFRlbnNvckltcGwgfSBmcm9tICcuL3RlbnNvci1pbXBsLmpzJztcbmltcG9ydCB7IFR5cGVkVGVuc29yVXRpbHMgfSBmcm9tICcuL3RlbnNvci11dGlscy5qcyc7XG5pbXBvcnQgeyBUcnlHZXRHbG9iYWxUeXBlIH0gZnJvbSAnLi90eXBlLWhlbHBlci5qcyc7XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmUgKi9cblxuLyoqXG4gKiByZXByZXNlbnQgYSBiYXNpYyB0ZW5zb3Igd2l0aCBzcGVjaWZpZWQgZGltZW5zaW9ucyBhbmQgZGF0YSB0eXBlLlxuICovXG5pbnRlcmZhY2UgVHlwZWRUZW5zb3JCYXNlPFQgZXh0ZW5kcyBUZW5zb3IuVHlwZT4ge1xuICAvKipcbiAgICogR2V0IHRoZSBkaW1lbnNpb25zIG9mIHRoZSB0ZW5zb3IuXG4gICAqL1xuICByZWFkb25seSBkaW1zOiByZWFkb25seSBudW1iZXJbXTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAqL1xuICByZWFkb25seSB0eXBlOiBUO1xuICAvKipcbiAgICogR2V0IHRoZSBidWZmZXIgZGF0YSBvZiB0aGUgdGVuc29yLlxuICAgKlxuICAgKiBJZiB0aGUgZGF0YSBpcyBub3Qgb24gQ1BVIChlZy4gaXQncyBpbiB0aGUgZm9ybSBvZiBXZWJHTCB0ZXh0dXJlIG9yIFdlYkdQVSBidWZmZXIpLCB0aHJvdyBlcnJvci5cbiAgICovXG4gIHJlYWRvbmx5IGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFtUXTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbG9jYXRpb24gb2YgdGhlIGRhdGEuXG4gICAqL1xuICByZWFkb25seSBsb2NhdGlvbjogVGVuc29yLkRhdGFMb2NhdGlvbjtcbiAgLyoqXG4gICAqIEdldCB0aGUgV2ViR0wgdGV4dHVyZSB0aGF0IGhvbGRzIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICpcbiAgICogSWYgdGhlIGRhdGEgaXMgbm90IG9uIEdQVSBhcyBXZWJHTCB0ZXh0dXJlLCB0aHJvdyBlcnJvci5cbiAgICovXG4gIHJlYWRvbmx5IHRleHR1cmU6IFRlbnNvci5UZXh0dXJlVHlwZTtcbiAgLyoqXG4gICAqIEdldCB0aGUgV2ViR1BVIGJ1ZmZlciB0aGF0IGhvbGRzIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICpcbiAgICogSWYgdGhlIGRhdGEgaXMgbm90IG9uIEdQVSBhcyBXZWJHUFUgYnVmZmVyLCB0aHJvdyBlcnJvci5cbiAgICovXG4gIHJlYWRvbmx5IGdwdUJ1ZmZlcjogVGVuc29yLkdwdUJ1ZmZlclR5cGU7XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgV2ViTk4gTUxUZW5zb3IgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqXG4gICAqIElmIHRoZSBkYXRhIGlzIG5vdCBpbiBhIFdlYk5OIE1MVGVuc29yLCB0aHJvdyBlcnJvci5cbiAgICovXG4gIHJlYWRvbmx5IG1sVGVuc29yOiBUZW5zb3IuTUxUZW5zb3JUeXBlO1xuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGJ1ZmZlciBkYXRhIG9mIHRoZSB0ZW5zb3IuXG4gICAqXG4gICAqIElmIHRoZSBkYXRhIGlzIG9uIENQVSwgcmV0dXJucyB0aGUgZGF0YSBpbW1lZGlhdGVseS5cbiAgICogSWYgdGhlIGRhdGEgaXMgb24gR1BVLCBkb3dubG9hZHMgdGhlIGRhdGEgYW5kIHJldHVybnMgdGhlIHByb21pc2UuXG4gICAqXG4gICAqIEBwYXJhbSByZWxlYXNlRGF0YSAtIHdoZXRoZXIgcmVsZWFzZSB0aGUgZGF0YSBvbiBHUFUuIElnbm9yZSBpZiBkYXRhIGlzIGFscmVhZHkgb24gQ1BVLlxuICAgKi9cbiAgZ2V0RGF0YShyZWxlYXNlRGF0YT86IGJvb2xlYW4pOiBQcm9taXNlPFRlbnNvci5EYXRhVHlwZU1hcFtUXT47XG5cbiAgLyoqXG4gICAqIERpc3Bvc2UgdGhlIHRlbnNvciBkYXRhLlxuICAgKlxuICAgKiBJZiB0aGUgZGF0YSBpcyBvbiBDUFUsIHJlbW92ZSBpdHMgaW50ZXJuYWwgcmVmZXJlbmNlIHRvIHRoZSB1bmRlcmx5aW5nIGRhdGEuXG4gICAqIElmIHRoZSBkYXRhIGlzIG9uIEdQVSwgcmVsZWFzZSB0aGUgZGF0YSBvbiBHUFUuXG4gICAqXG4gICAqIEFmdGVyIGNhbGxpbmcgdGhpcyBmdW5jdGlvbiwgdGhlIHRlbnNvciBpcyBjb25zaWRlcmVkIG5vIGxvbmdlciB2YWxpZC4gSXRzIGxvY2F0aW9uIHdpbGwgYmUgc2V0IHRvICdub25lJy5cbiAgICovXG4gIGRpc3Bvc2UoKTogdm9pZDtcbn1cblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIFRlbnNvciB7XG4gIGludGVyZmFjZSBEYXRhVHlwZU1hcCB7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuICAgIHVpbnQ4OiBVaW50OEFycmF5O1xuICAgIGludDg6IEludDhBcnJheTtcbiAgICB1aW50MTY6IFVpbnQxNkFycmF5O1xuICAgIGludDE2OiBJbnQxNkFycmF5O1xuICAgIGludDMyOiBJbnQzMkFycmF5O1xuICAgIGludDY0OiBCaWdJbnQ2NEFycmF5O1xuICAgIHN0cmluZzogc3RyaW5nW107XG4gICAgYm9vbDogVWludDhBcnJheTtcbiAgICBmbG9hdDE2OiBVaW50MTZBcnJheTsgLy8gS2VlcCB1c2luZyBVaW50MTZBcnJheSB1bnRpbCB3ZSBoYXZlIGEgY29uY3JldGUgc29sdXRpb24gZm9yIGZsb2F0IDE2LlxuICAgIGZsb2F0NjQ6IEZsb2F0NjRBcnJheTtcbiAgICB1aW50MzI6IFVpbnQzMkFycmF5O1xuICAgIHVpbnQ2NDogQmlnVWludDY0QXJyYXk7XG4gICAgLy8gY29tcGxleDY0OiBuZXZlcjtcbiAgICAvLyBjb21wbGV4MTI4OiBuZXZlcjtcbiAgICAvLyBiZmxvYXQxNjogbmV2ZXI7XG4gICAgdWludDQ6IFVpbnQ4QXJyYXk7XG4gICAgaW50NDogSW50OEFycmF5O1xuICB9XG5cbiAgaW50ZXJmYWNlIEVsZW1lbnRUeXBlTWFwIHtcbiAgICBmbG9hdDMyOiBudW1iZXI7XG4gICAgdWludDg6IG51bWJlcjtcbiAgICBpbnQ4OiBudW1iZXI7XG4gICAgdWludDE2OiBudW1iZXI7XG4gICAgaW50MTY6IG51bWJlcjtcbiAgICBpbnQzMjogbnVtYmVyO1xuICAgIGludDY0OiBiaWdpbnQ7XG4gICAgc3RyaW5nOiBzdHJpbmc7XG4gICAgYm9vbDogYm9vbGVhbjtcbiAgICBmbG9hdDE2OiBudW1iZXI7IC8vIEtlZXAgdXNpbmcgVWludDE2QXJyYXkgdW50aWwgd2UgaGF2ZSBhIGNvbmNyZXRlIHNvbHV0aW9uIGZvciBmbG9hdCAxNi5cbiAgICBmbG9hdDY0OiBudW1iZXI7XG4gICAgdWludDMyOiBudW1iZXI7XG4gICAgdWludDY0OiBiaWdpbnQ7XG4gICAgLy8gY29tcGxleDY0OiBuZXZlcjtcbiAgICAvLyBjb21wbGV4MTI4OiBuZXZlcjtcbiAgICAvLyBiZmxvYXQxNjogbmV2ZXI7XG4gICAgdWludDQ6IG51bWJlcjtcbiAgICBpbnQ0OiBudW1iZXI7XG4gIH1cblxuICB0eXBlIERhdGFUeXBlID0gRGF0YVR5cGVNYXBbVHlwZV07XG4gIHR5cGUgRWxlbWVudFR5cGUgPSBFbGVtZW50VHlwZU1hcFtUeXBlXTtcblxuICAvKipcbiAgICogc3VwcG9ydGVkIGRhdGEgdHlwZXMgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgcGlubmVkIENQVSBidWZmZXJcbiAgICovXG4gIGV4cG9ydCB0eXBlIENwdVBpbm5lZERhdGFUeXBlcyA9IEV4Y2x1ZGU8VGVuc29yLlR5cGUsICdzdHJpbmcnPjtcblxuICAvKipcbiAgICogdHlwZSBhbGlhcyBmb3IgV2ViR0wgdGV4dHVyZVxuICAgKi9cbiAgZXhwb3J0IHR5cGUgVGV4dHVyZVR5cGUgPSBXZWJHTFRleHR1cmU7XG5cbiAgLyoqXG4gICAqIHN1cHBvcnRlZCBkYXRhIHR5cGVzIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIFdlYkdMIHRleHR1cmVcbiAgICovXG4gIGV4cG9ydCB0eXBlIFRleHR1cmVEYXRhVHlwZXMgPSAnZmxvYXQzMic7XG5cbiAgdHlwZSBHcHVCdWZmZXJUeXBlRmFsbGJhY2sgPSB7IHNpemU6IG51bWJlcjsgbWFwU3RhdGU6ICd1bm1hcHBlZCcgfCAncGVuZGluZycgfCAnbWFwcGVkJyB9O1xuICAvKipcbiAgICogdHlwZSBhbGlhcyBmb3IgV2ViR1BVIGJ1ZmZlclxuICAgKi9cbiAgZXhwb3J0IHR5cGUgR3B1QnVmZmVyVHlwZSA9IFRyeUdldEdsb2JhbFR5cGU8J0dQVUJ1ZmZlcicsIEdwdUJ1ZmZlclR5cGVGYWxsYmFjaz47XG5cbiAgdHlwZSBNTFRlbnNvclR5cGVGYWxsYmFjayA9IHsgZGVzdHJveSgpOiB2b2lkIH07XG4gIC8qKlxuICAgKiB0eXBlIGFsaWFzIGZvciBXZWJOTiBNTFRlbnNvclxuICAgKlxuICAgKiBUaGUgc3BlY2lmaWNhdGlvbiBmb3IgV2ViTk4ncyBNTFRlbnNvciBpcyBjdXJyZW50bHkgaW4gZmx1eC5cbiAgICovXG4gIGV4cG9ydCB0eXBlIE1MVGVuc29yVHlwZSA9IFRyeUdldEdsb2JhbFR5cGU8J01MVGVuc29yJywgTUxUZW5zb3JUeXBlRmFsbGJhY2s+O1xuXG4gIC8qKlxuICAgKiBzdXBwb3J0ZWQgZGF0YSB0eXBlcyBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBXZWJHUFUgYnVmZmVyXG4gICAqL1xuICBleHBvcnQgdHlwZSBHcHVCdWZmZXJEYXRhVHlwZXMgPSAnZmxvYXQzMicgfCAnZmxvYXQxNicgfCAnaW50MzInIHwgJ2ludDY0JyB8ICd1aW50MzInIHwgJ3VpbnQ4JyB8ICdib29sJztcblxuICAvKipcbiAgICogc3VwcG9ydGVkIGRhdGEgdHlwZXMgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgV2ViTk4gTUxUZW5zb3JcbiAgICovXG4gIGV4cG9ydCB0eXBlIE1MVGVuc29yRGF0YVR5cGVzID1cbiAgICB8ICdmbG9hdDMyJ1xuICAgIHwgJ2Zsb2F0MTYnXG4gICAgfCAnaW50OCdcbiAgICB8ICd1aW50OCdcbiAgICB8ICdpbnQzMidcbiAgICB8ICd1aW50MzInXG4gICAgfCAnaW50NjQnXG4gICAgfCAndWludDY0J1xuICAgIHwgJ2Jvb2wnXG4gICAgfCAndWludDQnXG4gICAgfCAnaW50NCc7XG5cbiAgLyoqXG4gICAqIHJlcHJlc2VudCB3aGVyZSB0aGUgdGVuc29yIGRhdGEgaXMgc3RvcmVkXG4gICAqL1xuICBleHBvcnQgdHlwZSBEYXRhTG9jYXRpb24gPSAnbm9uZScgfCAnY3B1JyB8ICdjcHUtcGlubmVkJyB8ICd0ZXh0dXJlJyB8ICdncHUtYnVmZmVyJyB8ICdtbC10ZW5zb3InO1xuXG4gIC8qKlxuICAgKiByZXByZXNlbnQgdGhlIGRhdGEgdHlwZSBvZiBhIHRlbnNvclxuICAgKi9cbiAgZXhwb3J0IHR5cGUgVHlwZSA9IGtleW9mIERhdGFUeXBlTWFwO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudCBtdWx0aS1kaW1lbnNpb25hbCBhcnJheXMgdG8gZmVlZCB0byBvciBmZXRjaCBmcm9tIG1vZGVsIGluZmVyZW5jaW5nLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFR5cGVkVGVuc29yPFQgZXh0ZW5kcyBUZW5zb3IuVHlwZT4gZXh0ZW5kcyBUeXBlZFRlbnNvckJhc2U8VD4sIFR5cGVkVGVuc29yVXRpbHM8VD4ge31cbi8qKlxuICogUmVwcmVzZW50IG11bHRpLWRpbWVuc2lvbmFsIGFycmF5cyB0byBmZWVkIHRvIG9yIGZldGNoIGZyb20gbW9kZWwgaW5mZXJlbmNpbmcuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yIGV4dGVuZHMgVHlwZWRUZW5zb3JCYXNlPFRlbnNvci5UeXBlPiwgVHlwZWRUZW5zb3JVdGlsczxUZW5zb3IuVHlwZT4ge31cblxuLyoqXG4gKiB0eXBlIFRlbnNvckNvbnN0cnVjdG9yIGRlZmluZXMgdGhlIGNvbnN0cnVjdG9ycyBvZiAnVGVuc29yJyB0byBjcmVhdGUgQ1BVIHRlbnNvciBpbnN0YW5jZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yQ29uc3RydWN0b3IgZXh0ZW5kcyBUZW5zb3JGYWN0b3J5IHtcbiAgLy8gI3JlZ2lvbiBDUFUgdGVuc29yIC0gc3BlY2lmeSBlbGVtZW50IHR5cGVcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBzdHJpbmcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB0eXBlLCBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFNwZWNpZnkgdGhlIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChcbiAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICBkYXRhOiBUZW5zb3IuRGF0YVR5cGVNYXBbJ3N0cmluZyddIHwgcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApOiBUeXBlZFRlbnNvcjwnc3RyaW5nJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBib29sIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gdHlwZSwgZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSBTcGVjaWZ5IHRoZSBlbGVtZW50IHR5cGUuXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoXG4gICAgdHlwZTogJ2Jvb2wnLFxuICAgIGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFsnYm9vbCddIHwgcmVhZG9ubHkgYm9vbGVhbltdLFxuICAgIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogVHlwZWRUZW5zb3I8J2Jvb2wnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHVpbnQ4IHRlbnNvciBvYmplY3QgZnJvbSBhIFVpbnQ4Q2xhbXBlZEFycmF5LCBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFNwZWNpZnkgdGhlIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3ICh0eXBlOiAndWludDgnLCBkYXRhOiBVaW50OENsYW1wZWRBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3VpbnQ4Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyA2NC1iaXQgaW50ZWdlciB0eXBlZCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIHR5cGUsIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gU3BlY2lmeSB0aGUgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgPFQgZXh0ZW5kcyAndWludDY0JyB8ICdpbnQ2NCc+KFxuICAgIHR5cGU6IFQsXG4gICAgZGF0YTogVGVuc29yLkRhdGFUeXBlTWFwW1RdIHwgcmVhZG9ubHkgYmlnaW50W10gfCByZWFkb25seSBudW1iZXJbXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IFR5cGVkVGVuc29yPFQ+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgbnVtZXJpYyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIHR5cGUsIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gU3BlY2lmeSB0aGUgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgPFQgZXh0ZW5kcyBFeGNsdWRlPFRlbnNvci5UeXBlLCAnc3RyaW5nJyB8ICdib29sJyB8ICd1aW50NjQnIHwgJ2ludDY0Jz4+KFxuICAgIHR5cGU6IFQsXG4gICAgZGF0YTogVGVuc29yLkRhdGFUeXBlTWFwW1RdIHwgcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApOiBUeXBlZFRlbnNvcjxUPjtcbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gQ1BVIHRlbnNvciAtIGluZmVyIGVsZW1lbnQgdHlwZXNcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGZsb2F0MzIgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IEZsb2F0MzJBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2Zsb2F0MzInPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGludDggdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IEludDhBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2ludDgnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHVpbnQ4IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBVaW50OEFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwndWludDgnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHVpbnQ4IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBVaW50OENsYW1wZWRBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3VpbnQ4Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB1aW50MTYgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IFVpbnQxNkFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwndWludDE2Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBpbnQxNiB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogSW50MTZBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2ludDE2Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBpbnQzMiB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogSW50MzJBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2ludDMyJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBpbnQ2NCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogQmlnSW50NjRBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2ludDY0Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBzdHJpbmcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IHJlYWRvbmx5IHN0cmluZ1tdLCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwnc3RyaW5nJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBib29sIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiByZWFkb25seSBib29sZWFuW10sIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdib29sJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBmbG9hdDY0IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBGbG9hdDY0QXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdmbG9hdDY0Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB1aW50MzIgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IFVpbnQzMkFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwndWludDMyJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB1aW50NjQgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IEJpZ1VpbnQ2NEFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwndWludDY0Jz47XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gQ1BVIHRlbnNvciAtIGZhbGwgYmFjayB0byBub24tZ2VuZXJpYyB0ZW5zb3IgdHlwZSBkZWNsYXJhdGlvblxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB0eXBlLCBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFNwZWNpZnkgdGhlIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChcbiAgICB0eXBlOiBUZW5zb3IuVHlwZSxcbiAgICBkYXRhOiBUZW5zb3IuRGF0YVR5cGUgfCByZWFkb25seSBudW1iZXJbXSB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgcmVhZG9ubHkgYmlnaW50W10gfCByZWFkb25seSBib29sZWFuW10sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApOiBUZW5zb3I7XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogVGVuc29yLkRhdGFUeXBlLCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3I7XG4gIC8vICNlbmRyZWdpb25cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZXhwb3J0IGNvbnN0IFRlbnNvciA9IFRlbnNvckltcGwgYXMgVGVuc29yQ29uc3RydWN0b3I7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiB9IGZyb20gJy4vZW52LWltcGwuanMnO1xuXG4vKipcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGNvbnN0IFRSQUNFID0gKGRldmljZVR5cGU6IHN0cmluZywgbGFiZWw6IHN0cmluZykgPT4ge1xuICBpZiAodHlwZW9mIGVudi50cmFjZSA9PT0gJ3VuZGVmaW5lZCcgPyAhZW52Lndhc20udHJhY2UgOiAhZW52LnRyYWNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gIGNvbnNvbGUudGltZVN0YW1wKGAke2RldmljZVR5cGV9OjpPUlQ6OiR7bGFiZWx9YCk7XG59O1xuXG5jb25zdCBUUkFDRV9GVU5DID0gKG1zZzogc3RyaW5nLCBleHRyYU1zZz86IHN0cmluZykgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBFcnJvcigpLnN0YWNrPy5zcGxpdCgvXFxyXFxufFxccnxcXG4vZykgfHwgW107XG4gIGxldCBoYXNUcmFjZUZ1bmMgPSBmYWxzZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdGFjay5sZW5ndGg7IGkrKykge1xuICAgIGlmIChoYXNUcmFjZUZ1bmMgJiYgIXN0YWNrW2ldLmluY2x1ZGVzKCdUUkFDRV9GVU5DJykpIHtcbiAgICAgIGxldCBsYWJlbCA9IGBGVU5DXyR7bXNnfTo6JHtzdGFja1tpXS50cmltKCkuc3BsaXQoJyAnKVsxXX1gO1xuICAgICAgaWYgKGV4dHJhTXNnKSB7XG4gICAgICAgIGxhYmVsICs9IGA6OiR7ZXh0cmFNc2d9YDtcbiAgICAgIH1cbiAgICAgIFRSQUNFKCdDUFUnLCBsYWJlbCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChzdGFja1tpXS5pbmNsdWRlcygnVFJBQ0VfRlVOQycpKSB7XG4gICAgICBoYXNUcmFjZUZ1bmMgPSB0cnVlO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCBUUkFDRV9GVU5DX0JFR0lOID0gKGV4dHJhTXNnPzogc3RyaW5nKSA9PiB7XG4gIGlmICh0eXBlb2YgZW52LnRyYWNlID09PSAndW5kZWZpbmVkJyA/ICFlbnYud2FzbS50cmFjZSA6ICFlbnYudHJhY2UpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgVFJBQ0VfRlVOQygnQkVHSU4nLCBleHRyYU1zZyk7XG59O1xuXG4vKipcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGNvbnN0IFRSQUNFX0ZVTkNfRU5EID0gKGV4dHJhTXNnPzogc3RyaW5nKSA9PiB7XG4gIGlmICh0eXBlb2YgZW52LnRyYWNlID09PSAndW5kZWZpbmVkJyA/ICFlbnYud2FzbS50cmFjZSA6ICFlbnYudHJhY2UpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgVFJBQ0VfRlVOQygnRU5EJywgZXh0cmFNc2cpO1xufTtcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCBUUkFDRV9FVkVOVF9CRUdJTiA9IChleHRyYU1zZz86IHN0cmluZykgPT4ge1xuICBpZiAodHlwZW9mIGVudi50cmFjZSA9PT0gJ3VuZGVmaW5lZCcgPyAhZW52Lndhc20udHJhY2UgOiAhZW52LnRyYWNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gIGNvbnNvbGUudGltZShgT1JUOjoke2V4dHJhTXNnfWApO1xufTtcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCBUUkFDRV9FVkVOVF9FTkQgPSAoZXh0cmFNc2c/OiBzdHJpbmcpID0+IHtcbiAgaWYgKHR5cGVvZiBlbnYudHJhY2UgPT09ICd1bmRlZmluZWQnID8gIWVudi53YXNtLnRyYWNlIDogIWVudi50cmFjZSkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLnRpbWVFbmQoYE9SVDo6JHtleHRyYU1zZ31gKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IHJlc29sdmVCYWNrZW5kQW5kRXhlY3V0aW9uUHJvdmlkZXJzIH0gZnJvbSAnLi9iYWNrZW5kLWltcGwuanMnO1xuaW1wb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuL2JhY2tlbmQuanMnO1xuaW1wb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbiBhcyBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlIH0gZnJvbSAnLi9pbmZlcmVuY2Utc2Vzc2lvbi5qcyc7XG5pbXBvcnQgeyBPbm54VmFsdWUgfSBmcm9tICcuL29ubngtdmFsdWUuanMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3IuanMnO1xuaW1wb3J0IHsgVFJBQ0VfRlVOQ19CRUdJTiwgVFJBQ0VfRlVOQ19FTkQsIFRSQUNFX0VWRU5UX0JFR0lOLCBUUkFDRV9FVkVOVF9FTkQgfSBmcm9tICcuL3RyYWNlLmpzJztcblxudHlwZSBTZXNzaW9uT3B0aW9ucyA9IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuU2Vzc2lvbk9wdGlvbnM7XG50eXBlIFJ1bk9wdGlvbnMgPSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLlJ1bk9wdGlvbnM7XG50eXBlIEZlZWRzVHlwZSA9IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuRmVlZHNUeXBlO1xudHlwZSBGZXRjaGVzVHlwZSA9IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuRmV0Y2hlc1R5cGU7XG50eXBlIFJldHVyblR5cGUgPSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLlJldHVyblR5cGU7XG5cbmV4cG9ydCBjbGFzcyBJbmZlcmVuY2VTZXNzaW9uIGltcGxlbWVudHMgSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZSB7XG4gIHByaXZhdGUgY29uc3RydWN0b3IoaGFuZGxlcjogSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIpIHtcbiAgICB0aGlzLmhhbmRsZXIgPSBoYW5kbGVyO1xuICB9XG4gIHJ1bihmZWVkczogRmVlZHNUeXBlLCBvcHRpb25zPzogUnVuT3B0aW9ucyk6IFByb21pc2U8UmV0dXJuVHlwZT47XG4gIHJ1bihmZWVkczogRmVlZHNUeXBlLCBmZXRjaGVzOiBGZXRjaGVzVHlwZSwgb3B0aW9ucz86IFJ1bk9wdGlvbnMpOiBQcm9taXNlPFJldHVyblR5cGU+O1xuICBhc3luYyBydW4oZmVlZHM6IEZlZWRzVHlwZSwgYXJnMT86IEZldGNoZXNUeXBlIHwgUnVuT3B0aW9ucywgYXJnMj86IFJ1bk9wdGlvbnMpOiBQcm9taXNlPFJldHVyblR5cGU+IHtcbiAgICBUUkFDRV9GVU5DX0JFR0lOKCk7XG4gICAgVFJBQ0VfRVZFTlRfQkVHSU4oJ0luZmVyZW5jZVNlc3Npb24ucnVuJyk7XG4gICAgY29uc3QgZmV0Y2hlczogeyBbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlIHwgbnVsbCB9ID0ge307XG4gICAgbGV0IG9wdGlvbnM6IFJ1bk9wdGlvbnMgPSB7fTtcbiAgICAvLyBjaGVjayBpbnB1dHNcbiAgICBpZiAodHlwZW9mIGZlZWRzICE9PSAnb2JqZWN0JyB8fCBmZWVkcyA9PT0gbnVsbCB8fCBmZWVkcyBpbnN0YW5jZW9mIFRlbnNvciB8fCBBcnJheS5pc0FycmF5KGZlZWRzKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgXCInZmVlZHMnIG11c3QgYmUgYW4gb2JqZWN0IHRoYXQgdXNlIGlucHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cIixcbiAgICAgICk7XG4gICAgfVxuXG4gICAgbGV0IGlzRmV0Y2hlc0VtcHR5ID0gdHJ1ZTtcbiAgICAvLyBkZXRlcm1pbmUgd2hpY2ggb3ZlcnJpZGUgaXMgYmVpbmcgdXNlZFxuICAgIGlmICh0eXBlb2YgYXJnMSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChhcmcxID09PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1VuZXhwZWN0ZWQgYXJndW1lbnRbMV06IGNhbm5vdCBiZSBudWxsLicpO1xuICAgICAgfVxuICAgICAgaWYgKGFyZzEgaW5zdGFuY2VvZiBUZW5zb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidmZXRjaGVzJyBjYW5ub3QgYmUgYSBUZW5zb3JcIik7XG4gICAgICB9XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGFyZzEpKSB7XG4gICAgICAgIGlmIChhcmcxLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInZmV0Y2hlcycgY2Fubm90IGJlIGFuIGVtcHR5IGFycmF5LlwiKTtcbiAgICAgICAgfVxuICAgICAgICBpc0ZldGNoZXNFbXB0eSA9IGZhbHNlO1xuICAgICAgICAvLyBvdXRwdXQgbmFtZXNcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIGFyZzEpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ2ZldGNoZXMnIG11c3QgYmUgYSBzdHJpbmcgYXJyYXkgb3IgYW4gb2JqZWN0LlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHRoaXMub3V0cHV0TmFtZXMuaW5kZXhPZihuYW1lKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAnZmV0Y2hlcycgY29udGFpbnMgaW52YWxpZCBvdXRwdXQgbmFtZTogJHtuYW1lfS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZmV0Y2hlc1tuYW1lXSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGFyZzIgPT09ICdvYmplY3QnICYmIGFyZzIgIT09IG51bGwpIHtcbiAgICAgICAgICBvcHRpb25zID0gYXJnMjtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ29wdGlvbnMnIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZGVjaWRlIHdoZXRoZXIgYXJnMSBpcyBmZXRjaGVzIG9yIG9wdGlvbnNcbiAgICAgICAgLy8gaWYgYW55IG91dHB1dCBuYW1lIGlzIHByZXNlbnQgYW5kIGl0cyB2YWx1ZSBpcyB2YWxpZCBPbm54VmFsdWUsIHdlIGNvbnNpZGVyIGl0IGZldGNoZXNcbiAgICAgICAgbGV0IGlzRmV0Y2hlcyA9IGZhbHNlO1xuICAgICAgICBjb25zdCBhcmcxS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGFyZzEpO1xuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgdGhpcy5vdXRwdXROYW1lcykge1xuICAgICAgICAgIGlmIChhcmcxS2V5cy5pbmRleE9mKG5hbWUpICE9PSAtMSkge1xuICAgICAgICAgICAgY29uc3QgdiA9IChhcmcxIGFzIEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuTnVsbGFibGVPbm54VmFsdWVNYXBUeXBlKVtuYW1lXTtcbiAgICAgICAgICAgIGlmICh2ID09PSBudWxsIHx8IHYgaW5zdGFuY2VvZiBUZW5zb3IpIHtcbiAgICAgICAgICAgICAgaXNGZXRjaGVzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgaXNGZXRjaGVzRW1wdHkgPSBmYWxzZTtcbiAgICAgICAgICAgICAgZmV0Y2hlc1tuYW1lXSA9IHY7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzRmV0Y2hlcykge1xuICAgICAgICAgIGlmICh0eXBlb2YgYXJnMiA9PT0gJ29iamVjdCcgJiYgYXJnMiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IGFyZzI7XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInb3B0aW9ucycgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvcHRpb25zID0gYXJnMSBhcyBSdW5PcHRpb25zO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJVbmV4cGVjdGVkIGFyZ3VtZW50WzFdOiBtdXN0IGJlICdmZXRjaGVzJyBvciAnb3B0aW9ucycuXCIpO1xuICAgIH1cblxuICAgIC8vIGNoZWNrIGlmIGFsbCBpbnB1dHMgYXJlIGluIGZlZWRcbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgdGhpcy5pbnB1dE5hbWVzKSB7XG4gICAgICBpZiAodHlwZW9mIGZlZWRzW25hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0ICcke25hbWV9JyBpcyBtaXNzaW5nIGluICdmZWVkcycuYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gaWYgbm8gZmV0Y2hlcyBpcyBzcGVjaWZpZWQsIHdlIHVzZSB0aGUgZnVsbCBvdXRwdXQgbmFtZXMgbGlzdFxuICAgIGlmIChpc0ZldGNoZXNFbXB0eSkge1xuICAgICAgZm9yIChjb25zdCBuYW1lIG9mIHRoaXMub3V0cHV0TmFtZXMpIHtcbiAgICAgICAgZmV0Y2hlc1tuYW1lXSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZmVlZHMsIGZldGNoZXMgYW5kIG9wdGlvbnMgYXJlIHByZXBhcmVkXG5cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5oYW5kbGVyLnJ1bihmZWVkcywgZmV0Y2hlcywgb3B0aW9ucyk7XG4gICAgY29uc3QgcmV0dXJuVmFsdWU6IHsgW25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZSB9ID0ge307XG4gICAgZm9yIChjb25zdCBrZXkgaW4gcmVzdWx0cykge1xuICAgICAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdHMsIGtleSkpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcmVzdWx0c1trZXldO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgVGVuc29yKSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVba2V5XSA9IHJlc3VsdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVtrZXldID0gbmV3IFRlbnNvcihyZXN1bHQudHlwZSwgcmVzdWx0LmRhdGEsIHJlc3VsdC5kaW1zKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBUUkFDRV9FVkVOVF9FTkQoJ0luZmVyZW5jZVNlc3Npb24ucnVuJyk7XG4gICAgVFJBQ0VfRlVOQ19FTkQoKTtcbiAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gIH1cblxuICBhc3luYyByZWxlYXNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIuZGlzcG9zZSgpO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZShwYXRoOiBzdHJpbmcsIG9wdGlvbnM/OiBTZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZT47XG4gIHN0YXRpYyBjcmVhdGUoYnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsIG9wdGlvbnM/OiBTZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZT47XG4gIHN0YXRpYyBjcmVhdGUoXG4gICAgYnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsXG4gICAgYnl0ZU9mZnNldDogbnVtYmVyLFxuICAgIGJ5dGVMZW5ndGg/OiBudW1iZXIsXG4gICAgb3B0aW9ucz86IFNlc3Npb25PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2U+O1xuICBzdGF0aWMgY3JlYXRlKGJ1ZmZlcjogVWludDhBcnJheSwgb3B0aW9ucz86IFNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlPjtcbiAgc3RhdGljIGFzeW5jIGNyZWF0ZShcbiAgICBhcmcwOiBzdHJpbmcgfCBBcnJheUJ1ZmZlckxpa2UgfCBVaW50OEFycmF5LFxuICAgIGFyZzE/OiBTZXNzaW9uT3B0aW9ucyB8IG51bWJlcixcbiAgICBhcmcyPzogbnVtYmVyLFxuICAgIGFyZzM/OiBTZXNzaW9uT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlPiB7XG4gICAgVFJBQ0VfRlVOQ19CRUdJTigpO1xuICAgIFRSQUNFX0VWRU5UX0JFR0lOKCdJbmZlcmVuY2VTZXNzaW9uLmNyZWF0ZScpO1xuICAgIC8vIGVpdGhlciBsb2FkIGZyb20gYSBmaWxlIG9yIGJ1ZmZlclxuICAgIGxldCBmaWxlUGF0aE9yVWludDhBcnJheTogc3RyaW5nIHwgVWludDhBcnJheTtcbiAgICBsZXQgb3B0aW9uczogU2Vzc2lvbk9wdGlvbnMgPSB7fTtcblxuICAgIGlmICh0eXBlb2YgYXJnMCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGZpbGVQYXRoT3JVaW50OEFycmF5ID0gYXJnMDtcbiAgICAgIGlmICh0eXBlb2YgYXJnMSA9PT0gJ29iamVjdCcgJiYgYXJnMSAhPT0gbnVsbCkge1xuICAgICAgICBvcHRpb25zID0gYXJnMTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInb3B0aW9ucycgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYXJnMCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgIGZpbGVQYXRoT3JVaW50OEFycmF5ID0gYXJnMDtcbiAgICAgIGlmICh0eXBlb2YgYXJnMSA9PT0gJ29iamVjdCcgJiYgYXJnMSAhPT0gbnVsbCkge1xuICAgICAgICBvcHRpb25zID0gYXJnMTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInb3B0aW9ucycgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXG4gICAgICBhcmcwIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIgfHxcbiAgICAgICh0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIGFyZzAgaW5zdGFuY2VvZiBTaGFyZWRBcnJheUJ1ZmZlcilcbiAgICApIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IGFyZzA7XG4gICAgICBsZXQgYnl0ZU9mZnNldCA9IDA7XG4gICAgICBsZXQgYnl0ZUxlbmd0aCA9IGFyZzAuYnl0ZUxlbmd0aDtcbiAgICAgIGlmICh0eXBlb2YgYXJnMSA9PT0gJ29iamVjdCcgJiYgYXJnMSAhPT0gbnVsbCkge1xuICAgICAgICBvcHRpb25zID0gYXJnMTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgPT09ICdudW1iZXInKSB7XG4gICAgICAgIGJ5dGVPZmZzZXQgPSBhcmcxO1xuICAgICAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGJ5dGVPZmZzZXQpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInYnl0ZU9mZnNldCcgbXVzdCBiZSBhbiBpbnRlZ2VyLlwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYnl0ZU9mZnNldCA+PSBidWZmZXIuYnl0ZUxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAnYnl0ZU9mZnNldCcgaXMgb3V0IG9mIHJhbmdlIFswLCAke2J1ZmZlci5ieXRlTGVuZ3RofSkuYCk7XG4gICAgICAgIH1cbiAgICAgICAgYnl0ZUxlbmd0aCA9IGFyZzAuYnl0ZUxlbmd0aCAtIGJ5dGVPZmZzZXQ7XG4gICAgICAgIGlmICh0eXBlb2YgYXJnMiA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICBieXRlTGVuZ3RoID0gYXJnMjtcbiAgICAgICAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGJ5dGVMZW5ndGgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIidieXRlTGVuZ3RoJyBtdXN0IGJlIGFuIGludGVnZXIuXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYnl0ZUxlbmd0aCA8PSAwIHx8IGJ5dGVPZmZzZXQgKyBieXRlTGVuZ3RoID4gYnVmZmVyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAnYnl0ZUxlbmd0aCcgaXMgb3V0IG9mIHJhbmdlICgwLCAke2J1ZmZlci5ieXRlTGVuZ3RoIC0gYnl0ZU9mZnNldH1dLmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHlwZW9mIGFyZzMgPT09ICdvYmplY3QnICYmIGFyZzMgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBhcmczO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ29wdGlvbnMnIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidieXRlTGVuZ3RoJyBtdXN0IGJlIGEgbnVtYmVyLlwiKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidvcHRpb25zJyBtdXN0IGJlIGFuIG9iamVjdC5cIik7XG4gICAgICB9XG4gICAgICBmaWxlUGF0aE9yVWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJVbmV4cGVjdGVkIGFyZ3VtZW50WzBdOiBtdXN0IGJlICdwYXRoJyBvciAnYnVmZmVyJy5cIik7XG4gICAgfVxuXG4gICAgLy8gcmVzb2x2ZSBiYWNrZW5kLCB1cGRhdGUgc2Vzc2lvbiBvcHRpb25zIHdpdGggdmFsaWRhdGVkIEVQcywgYW5kIGNyZWF0ZSBzZXNzaW9uIGhhbmRsZXJcbiAgICBjb25zdCBbYmFja2VuZCwgb3B0aW9uc1dpdGhWYWxpZGF0ZWRFUHNdID0gYXdhaXQgcmVzb2x2ZUJhY2tlbmRBbmRFeGVjdXRpb25Qcm92aWRlcnMob3B0aW9ucyk7XG4gICAgY29uc3QgaGFuZGxlciA9IGF3YWl0IGJhY2tlbmQuY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIoZmlsZVBhdGhPclVpbnQ4QXJyYXksIG9wdGlvbnNXaXRoVmFsaWRhdGVkRVBzKTtcbiAgICBUUkFDRV9FVkVOVF9FTkQoJ0luZmVyZW5jZVNlc3Npb24uY3JlYXRlJyk7XG4gICAgVFJBQ0VfRlVOQ19FTkQoKTtcbiAgICByZXR1cm4gbmV3IEluZmVyZW5jZVNlc3Npb24oaGFuZGxlcik7XG4gIH1cblxuICBzdGFydFByb2ZpbGluZygpOiB2b2lkIHtcbiAgICB0aGlzLmhhbmRsZXIuc3RhcnRQcm9maWxpbmcoKTtcbiAgfVxuICBlbmRQcm9maWxpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5oYW5kbGVyLmVuZFByb2ZpbGluZygpO1xuICB9XG5cbiAgZ2V0IGlucHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIuaW5wdXROYW1lcztcbiAgfVxuICBnZXQgb3V0cHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIub3V0cHV0TmFtZXM7XG4gIH1cblxuICBnZXQgaW5wdXRNZXRhZGF0YSgpOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLlZhbHVlTWV0YWRhdGFbXSB7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlci5pbnB1dE1ldGFkYXRhO1xuICB9XG5cbiAgZ2V0IG91dHB1dE1ldGFkYXRhKCk6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuVmFsdWVNZXRhZGF0YVtdIHtcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVyLm91dHB1dE1ldGFkYXRhO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVyOiBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcjtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbiBhcyBJbmZlcmVuY2VTZXNzaW9uSW1wbCB9IGZyb20gJy4vaW5mZXJlbmNlLXNlc3Npb24taW1wbC5qcyc7XG5pbXBvcnQgeyBPbm54TW9kZWxPcHRpb25zIH0gZnJvbSAnLi9vbm54LW1vZGVsLmpzJztcbmltcG9ydCB7IE9ubnhWYWx1ZSwgT25ueFZhbHVlRGF0YUxvY2F0aW9uIH0gZnJvbSAnLi9vbm54LXZhbHVlLmpzJztcbmltcG9ydCB0eXBlIHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3IuanMnO1xuaW1wb3J0IHsgVHJ5R2V0R2xvYmFsVHlwZSB9IGZyb20gJy4vdHlwZS1oZWxwZXIuanMnO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlICovXG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgLy8gI3JlZ2lvbiBpbnB1dC9vdXRwdXQgdHlwZXNcblxuICB0eXBlIE9ubnhWYWx1ZU1hcFR5cGUgPSB7IHJlYWRvbmx5IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfTtcbiAgdHlwZSBOdWxsYWJsZU9ubnhWYWx1ZU1hcFR5cGUgPSB7IHJlYWRvbmx5IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfCBudWxsIH07XG5cbiAgLyoqXG4gICAqIEEgZmVlZHMgKG1vZGVsIGlucHV0cykgaXMgYW4gb2JqZWN0IHRoYXQgdXNlcyBpbnB1dCBuYW1lcyBhcyBrZXlzIGFuZCBPbm54VmFsdWUgYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAqL1xuICB0eXBlIEZlZWRzVHlwZSA9IE9ubnhWYWx1ZU1hcFR5cGU7XG5cbiAgLyoqXG4gICAqIEEgZmV0Y2hlcyAobW9kZWwgb3V0cHV0cykgY291bGQgYmUgb25lIG9mIHRoZSBmb2xsb3dpbmc6XG4gICAqXG4gICAqIC0gT21pdHRlZC4gVXNlIG1vZGVsJ3Mgb3V0cHV0IG5hbWVzIGRlZmluaXRpb24uXG4gICAqIC0gQW4gYXJyYXkgb2Ygc3RyaW5nIGluZGljYXRpbmcgdGhlIG91dHB1dCBuYW1lcy5cbiAgICogLSBBbiBvYmplY3QgdGhhdCB1c2Ugb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBvciBudWxsIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcmVtYXJrXG4gICAqIGRpZmZlcmVudCBmcm9tIGlucHV0IGFyZ3VtZW50LCBpbiBvdXRwdXQsIE9ubnhWYWx1ZSBpcyBvcHRpb25hbC4gSWYgYW4gT25ueFZhbHVlIGlzIHByZXNlbnQgaXQgd2lsbCBiZVxuICAgKiB1c2VkIGFzIGEgcHJlLWFsbG9jYXRlZCB2YWx1ZSBieSB0aGUgaW5mZXJlbmNlIGVuZ2luZTsgaWYgb21pdHRlZCwgaW5mZXJlbmNlIGVuZ2luZSB3aWxsIGFsbG9jYXRlIGJ1ZmZlclxuICAgKiBpbnRlcm5hbGx5LlxuICAgKi9cbiAgdHlwZSBGZXRjaGVzVHlwZSA9IHJlYWRvbmx5IHN0cmluZ1tdIHwgTnVsbGFibGVPbm54VmFsdWVNYXBUeXBlO1xuXG4gIC8qKlxuICAgKiBBIGluZmVyZW5jaW5nIHJldHVybiB0eXBlIGlzIGFuIG9iamVjdCB0aGF0IHVzZXMgb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICovXG4gIHR5cGUgUmV0dXJuVHlwZSA9IE9ubnhWYWx1ZU1hcFR5cGU7XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gc2Vzc2lvbiBvcHRpb25zXG5cbiAgLyoqXG4gICAqIEEgc2V0IG9mIGNvbmZpZ3VyYXRpb25zIGZvciBzZXNzaW9uIGJlaGF2aW9yLlxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBTZXNzaW9uT3B0aW9ucyBleHRlbmRzIE9ubnhNb2RlbE9wdGlvbnMge1xuICAgIC8qKlxuICAgICAqIEFuIGFycmF5IG9mIGV4ZWN1dGlvbiBwcm92aWRlciBvcHRpb25zLlxuICAgICAqXG4gICAgICogQW4gZXhlY3V0aW9uIHByb3ZpZGVyIG9wdGlvbiBjYW4gYmUgYSBzdHJpbmcgaW5kaWNhdGluZyB0aGUgbmFtZSBvZiB0aGUgZXhlY3V0aW9uIHByb3ZpZGVyLFxuICAgICAqIG9yIGFuIG9iamVjdCBvZiBjb3JyZXNwb25kaW5nIHR5cGUuXG4gICAgICovXG4gICAgZXhlY3V0aW9uUHJvdmlkZXJzPzogcmVhZG9ubHkgRXhlY3V0aW9uUHJvdmlkZXJDb25maWdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBpbnRyYSBPUCB0aHJlYWRzIG51bWJlci5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIGludHJhT3BOdW1UaHJlYWRzPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGludGVyIE9QIHRocmVhZHMgbnVtYmVyLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkuXG4gICAgICovXG4gICAgaW50ZXJPcE51bVRocmVhZHM/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZnJlZSBkaW1lbnNpb24gb3ZlcnJpZGUuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgZnJlZURpbWVuc2lvbk92ZXJyaWRlcz86IHsgcmVhZG9ubHkgW2RpbWVuc2lvbk5hbWU6IHN0cmluZ106IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wdGltaXphdGlvbiBsZXZlbC5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBncmFwaE9wdGltaXphdGlvbkxldmVsPzogJ2Rpc2FibGVkJyB8ICdiYXNpYycgfCAnZXh0ZW5kZWQnIHwgJ2xheW91dCcgfCAnYWxsJztcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgZW5hYmxlIENQVSBtZW1vcnkgYXJlbmEuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgZW5hYmxlQ3B1TWVtQXJlbmE/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciBlbmFibGUgbWVtb3J5IHBhdHRlcm4uXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgZW5hYmxlTWVtUGF0dGVybj86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRpb24gbW9kZS5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBleGVjdXRpb25Nb2RlPzogJ3NlcXVlbnRpYWwnIHwgJ3BhcmFsbGVsJztcblxuICAgIC8qKlxuICAgICAqIE9wdGltaXplZCBtb2RlbCBmaWxlIHBhdGguXG4gICAgICpcbiAgICAgKiBJZiB0aGlzIHNldHRpbmcgaXMgc3BlY2lmaWVkLCB0aGUgb3B0aW1pemVkIG1vZGVsIHdpbGwgYmUgZHVtcGVkLiBJbiBicm93c2VyLCBhIGJsb2Igd2lsbCBiZSBjcmVhdGVkXG4gICAgICogd2l0aCBhIHBvcC11cCB3aW5kb3cuXG4gICAgICovXG4gICAgb3B0aW1pemVkTW9kZWxGaWxlUGF0aD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgZW5hYmxlIHByb2ZpbGluZy5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhIHBsYWNlaG9sZGVyIGZvciBhIGZ1dHVyZSB1c2UuXG4gICAgICovXG4gICAgZW5hYmxlUHJvZmlsaW5nPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIEZpbGUgcHJlZml4IGZvciBwcm9maWxpbmcuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYSBwbGFjZWhvbGRlciBmb3IgYSBmdXR1cmUgdXNlLlxuICAgICAqL1xuICAgIHByb2ZpbGVGaWxlUHJlZml4Pzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogTG9nIElELlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGxvZ0lkPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogTG9nIHNldmVyaXR5IGxldmVsLiBTZWVcbiAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L29ubnhydW50aW1lL2Jsb2IvbWFpbi9pbmNsdWRlL29ubnhydW50aW1lL2NvcmUvY29tbW9uL2xvZ2dpbmcvc2V2ZXJpdHkuaFxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGxvZ1NldmVyaXR5TGV2ZWw/OiAwIHwgMSB8IDIgfCAzIHwgNDtcblxuICAgIC8qKlxuICAgICAqIExvZyB2ZXJib3NpdHkgbGV2ZWwuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gV2ViQXNzZW1ibHkgYmFja2VuZC4gV2lsbCBzdXBwb3J0IE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlIGxhdGVyXG4gICAgICovXG4gICAgbG9nVmVyYm9zaXR5TGV2ZWw/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHN0cmluZyBhcyBhIHByZWZlcnJlZCBkYXRhIGxvY2F0aW9uIGZvciBhbGwgb3V0cHV0cywgb3IgYW4gb2JqZWN0IHRoYXQgdXNlIG91dHB1dCBuYW1lcyBhcyBrZXlzIGFuZCBhXG4gICAgICogcHJlZmVycmVkIGRhdGEgbG9jYXRpb24gYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgV2ViIGZvciBXZWJHTCBhbmQgV2ViR1BVIEVQLlxuICAgICAqL1xuICAgIHByZWZlcnJlZE91dHB1dExvY2F0aW9uPzogT25ueFZhbHVlRGF0YUxvY2F0aW9uIHwgeyByZWFkb25seSBbb3V0cHV0TmFtZTogc3RyaW5nXTogT25ueFZhbHVlRGF0YUxvY2F0aW9uIH07XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIGVuYWJsZSBncmFwaCBjYXB0dXJlLlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSBXZWIgZm9yIFdlYkdQVSBFUC5cbiAgICAgKi9cbiAgICBlbmFibGVHcmFwaENhcHR1cmU/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogU3RvcmUgY29uZmlndXJhdGlvbnMgZm9yIGEgc2Vzc2lvbi4gU2VlXG4gICAgICogaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS9ibG9iL21haW4vaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL3Nlc3Npb24vXG4gICAgICogb25ueHJ1bnRpbWVfc2Vzc2lvbl9vcHRpb25zX2NvbmZpZ19rZXlzLmhcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBXZWJBc3NlbWJseSBiYWNrZW5kLiBXaWxsIHN1cHBvcnQgTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUgbGF0ZXJcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBleHRyYToge1xuICAgICAqICAgc2Vzc2lvbjoge1xuICAgICAqICAgICBzZXRfZGVub3JtYWxfYXNfemVybzogXCIxXCIsXG4gICAgICogICAgIGRpc2FibGVfcHJlcGFja2luZzogXCIxXCJcbiAgICAgKiAgIH0sXG4gICAgICogICBvcHRpbWl6YXRpb246IHtcbiAgICAgKiAgICAgZW5hYmxlX2dlbHVfYXBwcm94aW1hdGlvbjogXCIxXCJcbiAgICAgKiAgIH1cbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZXh0cmE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgfVxuXG4gIC8vICNyZWdpb24gZXhlY3V0aW9uIHByb3ZpZGVyc1xuXG4gIC8vIEN1cnJlbnRseSwgd2UgaGF2ZSB0aGUgZm9sbG93aW5nIGJhY2tlbmRzIHRvIHN1cHBvcnQgZXhlY3V0aW9uIHByb3ZpZGVyczpcbiAgLy8gQmFja2VuZCBOb2RlLmpzIGJpbmRpbmc6IHN1cHBvcnRzICdjcHUnLCAnZG1sJyAod2luMzIpLCAnY29yZW1sJyAobWFjT1MpIGFuZCAnY3VkYScgKGxpbnV4KS5cbiAgLy8gQmFja2VuZCBXZWJBc3NlbWJseTogc3VwcG9ydHMgJ2NwdScsICd3YXNtJywgJ3dlYmdwdScgYW5kICd3ZWJubicuXG4gIC8vIEJhY2tlbmQgT05OWC5qczogc3VwcG9ydHMgJ3dlYmdsJy5cbiAgLy8gQmFja2VuZCBSZWFjdCBOYXRpdmU6IHN1cHBvcnRzICdjcHUnLCAneG5ucGFjaycsICdjb3JlbWwnIChpT1MpLCAnbm5hcGknIChBbmRyb2lkKS5cbiAgaW50ZXJmYWNlIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uTWFwIHtcbiAgICBjb3JlbWw6IENvcmVNTEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIGNwdTogQ3B1RXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgY3VkYTogQ3VkYUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIGRtbDogRG1sRXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgbm5hcGk6IE5uYXBpRXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgdGVuc29ycnQ6IFRlbnNvclJ0RXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgd2FzbTogV2ViQXNzZW1ibHlFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICB3ZWJnbDogV2ViR0xFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICB3ZWJncHU6IFdlYkdwdUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHdlYm5uOiBXZWJOTkV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHFubjogUW5uRXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgeG5ucGFjazogWG5ucGFja0V4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICB9XG5cbiAgdHlwZSBFeGVjdXRpb25Qcm92aWRlck5hbWUgPSBrZXlvZiBFeGVjdXRpb25Qcm92aWRlck9wdGlvbk1hcDtcbiAgdHlwZSBFeGVjdXRpb25Qcm92aWRlckNvbmZpZyA9XG4gICAgfCBFeGVjdXRpb25Qcm92aWRlck9wdGlvbk1hcFtFeGVjdXRpb25Qcm92aWRlck5hbWVdXG4gICAgfCBFeGVjdXRpb25Qcm92aWRlck9wdGlvblxuICAgIHwgRXhlY3V0aW9uUHJvdmlkZXJOYW1lXG4gICAgfCBzdHJpbmc7XG5cbiAgZXhwb3J0IGludGVyZmFjZSBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ3B1RXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ2NwdSc7XG4gICAgdXNlQXJlbmE/OiBib29sZWFuO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ3VkYUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdjdWRhJztcbiAgICBkZXZpY2VJZD86IG51bWJlcjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIERtbEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdkbWwnO1xuICAgIGRldmljZUlkPzogbnVtYmVyO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgVGVuc29yUnRFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAndGVuc29ycnQnO1xuICAgIGRldmljZUlkPzogbnVtYmVyO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViQXNzZW1ibHlFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnd2FzbSc7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHTEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICd3ZWJnbCc7XG4gICAgLy8gVE9ETzogYWRkIGZsYWdzXG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBYbm5wYWNrRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3hubnBhY2snO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR3B1RXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3dlYmdwdSc7XG5cbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHRoZSBwcmVmZXJyZWQgbGF5b3V0IHdoZW4gcnVubmluZyBsYXlvdXQgc2Vuc2l0aXZlIG9wZXJhdG9ycy5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0ICdOQ0hXJ1xuICAgICAqL1xuICAgIHByZWZlcnJlZExheW91dD86ICdOQ0hXJyB8ICdOSFdDJztcblxuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgYSBsaXN0IG9mIG5vZGUgbmFtZXMgdGhhdCBzaG91bGQgYmUgZXhlY3V0ZWQgb24gQ1BVIGV2ZW4gd2hlbiBXZWJHUFUgRVAgaXMgdXNlZC5cbiAgICAgKi9cbiAgICBmb3JjZUNwdU5vZGVOYW1lcz86IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgdmFsaWRhdGlvbiBtb2RlIGZvciBXZWJHUFUgZXhlY3V0aW9uIHByb3ZpZGVyLlxuICAgICAqIC0gJ2Rpc2FibGVkJzogRGlzYWJsZSBhbGwgdmFsaWRhdGlvbi5cbiAgICAgKiBXaGVuIHVzZWQgaW4gTm9kZS5qcywgZGlzYWJsZSB2YWxpZGF0aW9uIG1heSBjYXVzZSBwcm9jZXNzIGNyYXNoIGlmIFdlYkdQVSBlcnJvcnMgb2NjdXIuIEJlIGNhdXRpb3VzIHdoZW4gdXNpbmdcbiAgICAgKiB0aGlzIG1vZGUuXG4gICAgICogV2hlbiB1c2VkIGluIHdlYiwgdGhpcyBtb2RlIGlzIGVxdWl2YWxlbnQgdG8gJ3dncHVPbmx5Jy5cbiAgICAgKiAtICd3Z3B1T25seSc6IFBlcmZvcm0gV2ViR1BVIGludGVybmFsIHZhbGlkYXRpb24gb25seS5cbiAgICAgKiAtICdiYXNpYyc6IFBlcmZvcm0gYmFzaWMgdmFsaWRhdGlvbiBpbmNsdWRpbmcgV2ViR1BVIGludGVybmFsIHZhbGlkYXRpb24uIFRoaXMgaXMgdGhlIGRlZmF1bHQgbW9kZS5cbiAgICAgKiAtICdmdWxsJzogUGVyZm9ybSBmdWxsIHZhbGlkYXRpb24uIFRoaXMgbW9kZSBtYXkgaGF2ZSBwZXJmb3JtYW5jZSBpbXBhY3QuIFVzZSBpdCBmb3IgZGVidWdnaW5nIHB1cnBvc2UuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCAnYmFzaWMnXG4gICAgICovXG4gICAgdmFsaWRhdGlvbk1vZGU/OiAnZGlzYWJsZWQnIHwgJ3dncHVPbmx5JyB8ICdiYXNpYycgfCAnZnVsbCc7XG5cbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IGFuIG9wdGlvbmFsIFdlYkdQVSBkZXZpY2UgdG8gYmUgdXNlZCBieSB0aGUgV2ViR1BVIGV4ZWN1dGlvbiBwcm92aWRlci5cbiAgICAgKi9cbiAgICBkZXZpY2U/OiBUcnlHZXRHbG9iYWxUeXBlPCdHUFVEZXZpY2UnPjtcbiAgfVxuXG4gIC8vICNyZWdpb24gV2ViTk4gb3B0aW9uc1xuXG4gIGludGVyZmFjZSBXZWJOTkV4ZWN1dGlvblByb3ZpZGVyTmFtZSBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnd2Vibm4nO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgYSBzZXQgb2Ygb3B0aW9ucyBmb3IgY3JlYXRpbmcgYSBXZWJOTiBNTENvbnRleHQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSL3dlYm5uLyNkaWN0ZGVmLW1sY29udGV4dG9wdGlvbnNcbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViTk5Db250ZXh0T3B0aW9ucyB7XG4gICAgZGV2aWNlVHlwZT86ICdjcHUnIHwgJ2dwdScgfCAnbnB1JztcbiAgICBudW1UaHJlYWRzPzogbnVtYmVyO1xuICAgIHBvd2VyUHJlZmVyZW5jZT86ICdkZWZhdWx0JyB8ICdsb3ctcG93ZXInIHwgJ2hpZ2gtcGVyZm9ybWFuY2UnO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgYSBzZXQgb2Ygb3B0aW9ucyBmb3IgV2ViTk4gZXhlY3V0aW9uIHByb3ZpZGVyIHdpdGhvdXQgTUxDb250ZXh0LlxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJOTk9wdGlvbnNXaXRob3V0TUxDb250ZXh0IGV4dGVuZHMgV2ViTk5FeGVjdXRpb25Qcm92aWRlck5hbWUsIFdlYk5OQ29udGV4dE9wdGlvbnMge1xuICAgIGNvbnRleHQ/OiBuZXZlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIGEgc2V0IG9mIG9wdGlvbnMgZm9yIFdlYk5OIGV4ZWN1dGlvbiBwcm92aWRlciB3aXRoIE1MQ29udGV4dC5cbiAgICpcbiAgICogV2hlbiBNTENvbnRleHQgaXMgcHJvdmlkZWQsIHRoZSBkZXZpY2VUeXBlIGlzIGFsc28gcmVxdWlyZWQgc28gdGhhdCB0aGUgV2ViTk4gRVAgY2FuIGRldGVybWluZSB0aGUgcHJlZmVycmVkXG4gICAqIGNoYW5uZWwgbGF5b3V0LlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi93ZWJubi8jZG9tLW1sLWNyZWF0ZWNvbnRleHRcbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViTk5PcHRpb25zV2l0aE1MQ29udGV4dFxuICAgIGV4dGVuZHMgV2ViTk5FeGVjdXRpb25Qcm92aWRlck5hbWUsXG4gICAgICBPbWl0PFdlYk5OQ29udGV4dE9wdGlvbnMsICdkZXZpY2VUeXBlJz4sXG4gICAgICBSZXF1aXJlZDxQaWNrPFdlYk5OQ29udGV4dE9wdGlvbnMsICdkZXZpY2VUeXBlJz4+IHtcbiAgICBjb250ZXh0OiBUcnlHZXRHbG9iYWxUeXBlPCdNTENvbnRleHQnPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIGEgc2V0IG9mIG9wdGlvbnMgZm9yIFdlYk5OIGV4ZWN1dGlvbiBwcm92aWRlciB3aXRoIE1MQ29udGV4dCB3aGljaCBpcyBjcmVhdGVkIGZyb20gR1BVRGV2aWNlLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi93ZWJubi8jZG9tLW1sLWNyZWF0ZWNvbnRleHQtZ3B1ZGV2aWNlXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFdlYk5OT3B0aW9uc1dlYkdwdSBleHRlbmRzIFdlYk5ORXhlY3V0aW9uUHJvdmlkZXJOYW1lIHtcbiAgICBjb250ZXh0OiBUcnlHZXRHbG9iYWxUeXBlPCdNTENvbnRleHQnPjtcbiAgICBncHVEZXZpY2U6IFRyeUdldEdsb2JhbFR5cGU8J0dQVURldmljZSc+O1xuICB9XG5cbiAgLyoqXG4gICAqIE9wdGlvbnMgZm9yIFdlYk5OIGV4ZWN1dGlvbiBwcm92aWRlci5cbiAgICovXG4gIGV4cG9ydCB0eXBlIFdlYk5ORXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gPVxuICAgIHwgV2ViTk5PcHRpb25zV2l0aG91dE1MQ29udGV4dFxuICAgIHwgV2ViTk5PcHRpb25zV2l0aE1MQ29udGV4dFxuICAgIHwgV2ViTk5PcHRpb25zV2ViR3B1O1xuXG4gIC8vICNlbmRyZWdpb25cblxuICBleHBvcnQgaW50ZXJmYWNlIFFubkV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdxbm4nO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgdGhlIFFOTiBiYWNrZW5kIHR5cGUuIEUuZy4sICdjcHUnIG9yICdodHAnLlxuICAgICAqIE11dHVhbGx5IGV4Y2x1c2l2ZSB3aXRoIGBiYWNrZW5kUGF0aGAuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCAnaHRwJ1xuICAgICAqL1xuICAgIGJhY2tlbmRUeXBlPzogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgYSBwYXRoIHRvIHRoZSBRTk4gYmFja2VuZCBsaWJyYXJ5LlxuICAgICAqIE11dHVhbGx5IGV4Y2x1c2l2ZSB3aXRoIGBiYWNrZW5kVHlwZWAuXG4gICAgICovXG4gICAgYmFja2VuZFBhdGg/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB3aGV0aGVyIHRvIGVuYWJsZSBIVFAgRlAxNiBwcmVjaXNpb24uXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICovXG4gICAgZW5hYmxlRnAxNlByZWNpc2lvbj86IGJvb2xlYW47XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBDb3JlTUxFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnY29yZW1sJztcbiAgICAvKipcbiAgICAgKiBUaGUgYml0IGZsYWdzIGZvciBDb3JlTUwgZXhlY3V0aW9uIHByb3ZpZGVyLlxuICAgICAqXG4gICAgICogYGBgXG4gICAgICogQ09SRU1MX0ZMQUdfVVNFX0NQVV9PTkxZID0gMHgwMDFcbiAgICAgKiBDT1JFTUxfRkxBR19FTkFCTEVfT05fU1VCR1JBUEggPSAweDAwMlxuICAgICAqIENPUkVNTF9GTEFHX09OTFlfRU5BQkxFX0RFVklDRV9XSVRIX0FORSA9IDB4MDA0XG4gICAgICogQ09SRU1MX0ZMQUdfT05MWV9BTExPV19TVEFUSUNfSU5QVVRfU0hBUEVTID0gMHgwMDhcbiAgICAgKiBDT1JFTUxfRkxBR19DUkVBVEVfTUxQUk9HUkFNID0gMHgwMTBcbiAgICAgKiBDT1JFTUxfRkxBR19VU0VfQ1BVX0FORF9HUFUgPSAweDAyMFxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogU2VlIGluY2x1ZGUvb25ueHJ1bnRpbWUvY29yZS9wcm92aWRlcnMvY29yZW1sL2NvcmVtbF9wcm92aWRlcl9mYWN0b3J5LmggZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIFRoaXMgZmxhZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nKS5cbiAgICAgKi9cbiAgICBjb3JlTWxGbGFncz86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHdoZXRoZXIgdG8gdXNlIENQVSBvbmx5IGluIENvcmVNTCBFUC5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAocmVhY3QtbmF0aXZlKS5cbiAgICAgKi9cbiAgICB1c2VDUFVPbmx5PzogYm9vbGVhbjtcbiAgICB1c2VDUFVBbmRHUFU/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgd2hldGhlciB0byBlbmFibGUgQ29yZU1MIEVQIG9uIHN1YmdyYXBoLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChyZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIGVuYWJsZU9uU3ViZ3JhcGg/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgd2hldGhlciB0byBvbmx5IGVuYWJsZSBDb3JlTUwgRVAgZm9yIEFwcGxlIGRldmljZXMgd2l0aCBBTkUgKEFwcGxlIE5ldXJhbCBFbmdpbmUpLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChyZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIG9ubHlFbmFibGVEZXZpY2VXaXRoQU5FPzogYm9vbGVhbjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIE5uYXBpRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ25uYXBpJztcbiAgICB1c2VGUDE2PzogYm9vbGVhbjtcbiAgICB1c2VOQ0hXPzogYm9vbGVhbjtcbiAgICBjcHVEaXNhYmxlZD86IGJvb2xlYW47XG4gICAgY3B1T25seT86IGJvb2xlYW47XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHJ1biBvcHRpb25zXG5cbiAgLyoqXG4gICAqIEEgc2V0IG9mIGNvbmZpZ3VyYXRpb25zIGZvciBpbmZlcmVuY2UgcnVuIGJlaGF2aW9yXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFJ1bk9wdGlvbnMge1xuICAgIC8qKlxuICAgICAqIExvZyBzZXZlcml0eSBsZXZlbC4gU2VlXG4gICAgICogaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS9ibG9iL21haW4vaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL2NvbW1vbi9sb2dnaW5nL3NldmVyaXR5LmhcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBsb2dTZXZlcml0eUxldmVsPzogMCB8IDEgfCAyIHwgMyB8IDQ7XG5cbiAgICAvKipcbiAgICAgKiBMb2cgdmVyYm9zaXR5IGxldmVsLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIFdlYkFzc2VtYmx5IGJhY2tlbmQuIFdpbGwgc3VwcG9ydCBOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSBsYXRlclxuICAgICAqL1xuICAgIGxvZ1ZlcmJvc2l0eUxldmVsPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogVGVybWluYXRlIGFsbCBpbmNvbXBsZXRlIE9ydFJ1biBjYWxscyBhcyBzb29uIGFzIHBvc3NpYmxlIGlmIHRydWVcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBXZWJBc3NlbWJseSBiYWNrZW5kLiBXaWxsIHN1cHBvcnQgTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUgbGF0ZXJcbiAgICAgKi9cbiAgICB0ZXJtaW5hdGU/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogQSB0YWcgZm9yIHRoZSBSdW4oKSBjYWxscyB1c2luZyB0aGlzXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgdGFnPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogU2V0IGEgc2luZ2xlIHJ1biBjb25maWd1cmF0aW9uIGVudHJ5LiBTZWVcbiAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L29ubnhydW50aW1lL2Jsb2IvbWFpbi9pbmNsdWRlL29ubnhydW50aW1lL2NvcmUvc2Vzc2lvbi9cbiAgICAgKiBvbm54cnVudGltZV9ydW5fb3B0aW9uc19jb25maWdfa2V5cy5oXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gV2ViQXNzZW1ibHkgYmFja2VuZC4gV2lsbCBzdXBwb3J0IE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlIGxhdGVyXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBleHRyYToge1xuICAgICAqICAgbWVtb3J5OiB7XG4gICAgICogICAgIGVuYWJsZV9tZW1vcnlfYXJlbmFfc2hyaW5rYWdlOiBcIjFcIixcbiAgICAgKiAgIH1cbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZXh0cmE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHZhbHVlIG1ldGFkYXRhXG5cbiAgLyoqXG4gICAqIFRoZSBjb21tb24gcGFydCBvZiB0aGUgdmFsdWUgbWV0YWRhdGEgdHlwZSBmb3IgYm90aCB0ZW5zb3IgYW5kIG5vbi10ZW5zb3IgdmFsdWVzLlxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBWYWx1ZU1ldGFkYXRhQmFzZSB7XG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHNwZWNpZmllZCBpbnB1dCBvciBvdXRwdXQuXG4gICAgICovXG4gICAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgdGhlIG1ldGFkYXRhIG9mIGEgbm9uLXRlbnNvciB2YWx1ZS5cbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgTm9uVGVuc29yVmFsdWVNZXRhZGF0YSBleHRlbmRzIFZhbHVlTWV0YWRhdGFCYXNlIHtcbiAgICAvKipcbiAgICAgKiBHZXQgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHZhbHVlIGlzIGEgdGVuc29yLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IGlzVGVuc29yOiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIHRoZSBtZXRhZGF0YSBvZiBhIHRlbnNvciB2YWx1ZS5cbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgVGVuc29yVmFsdWVNZXRhZGF0YSBleHRlbmRzIFZhbHVlTWV0YWRhdGFCYXNlIHtcbiAgICAvKipcbiAgICAgKiBHZXQgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHZhbHVlIGlzIGEgdGVuc29yLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IGlzVGVuc29yOiB0cnVlO1xuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAgICovXG4gICAgcmVhZG9ubHkgdHlwZTogVGVuc29yLlR5cGU7XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBzaGFwZSBvZiB0aGUgdGVuc29yLlxuICAgICAqXG4gICAgICogSWYgdGhlIHNoYXBlIGlzIG5vdCBkZWZpbmVkLCB0aGUgdmFsdWUgd2lsbCBhbiBlbXB0eSBhcnJheS4gT3RoZXJ3aXNlLCBpdCB3aWxsIGJlIGFuIGFycmF5IHJlcHJlc2VudGluZyB0aGUgc2hhcGVcbiAgICAgKiBvZiB0aGUgdGVuc29yLiBFYWNoIGVsZW1lbnQgaW4gdGhlIGFycmF5IGNhbiBiZSBhIG51bWJlciBvciBhIHN0cmluZy4gSWYgdGhlIGVsZW1lbnQgaXMgYSBudW1iZXIsIGl0IHJlcHJlc2VudHNcbiAgICAgKiB0aGUgY29ycmVzcG9uZGluZyBkaW1lbnNpb24gc2l6ZS4gSWYgdGhlIGVsZW1lbnQgaXMgYSBzdHJpbmcsIGl0IHJlcHJlc2VudHMgYSBzeW1ib2xpYyBkaW1lbnNpb24uXG4gICAgICovXG4gICAgcmVhZG9ubHkgc2hhcGU6IFJlYWRvbmx5QXJyYXk8bnVtYmVyIHwgc3RyaW5nPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIHRoZSBtZXRhZGF0YSBvZiBhIHZhbHVlLlxuICAgKi9cbiAgZXhwb3J0IHR5cGUgVmFsdWVNZXRhZGF0YSA9IE5vblRlbnNvclZhbHVlTWV0YWRhdGEgfCBUZW5zb3JWYWx1ZU1ldGFkYXRhO1xuXG4gIC8vICNlbmRyZWdpb25cbn1cblxuLyoqXG4gKiBSZXByZXNlbnQgYSBydW50aW1lIGluc3RhbmNlIG9mIGFuIE9OTlggbW9kZWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5mZXJlbmNlU2Vzc2lvbiB7XG4gIC8vICNyZWdpb24gcnVuKClcblxuICAvKipcbiAgICogRXhlY3V0ZSB0aGUgbW9kZWwgYXN5bmNocm9ub3VzbHkgd2l0aCB0aGUgZ2l2ZW4gZmVlZHMgYW5kIG9wdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBmZWVkcyAtIFJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RlbCBpbnB1dC4gU2VlIHR5cGUgZGVzY3JpcHRpb24gb2YgYEluZmVyZW5jZVNlc3Npb24uSW5wdXRUeXBlYCBmb3IgZGV0YWlsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsLiBBIHNldCBvZiBvcHRpb25zIHRoYXQgY29udHJvbHMgdGhlIGJlaGF2aW9yIG9mIG1vZGVsIGluZmVyZW5jZS5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBtYXAsIHdoaWNoIHVzZXMgb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICovXG4gIHJ1bihmZWVkczogSW5mZXJlbmNlU2Vzc2lvbi5GZWVkc1R5cGUsIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24uUmV0dXJuVHlwZT47XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgdGhlIG1vZGVsIGFzeW5jaHJvbm91c2x5IHdpdGggdGhlIGdpdmVuIGZlZWRzLCBmZXRjaGVzIGFuZCBvcHRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0gZmVlZHMgLSBSZXByZXNlbnRhdGlvbiBvZiB0aGUgbW9kZWwgaW5wdXQuIFNlZSB0eXBlIGRlc2NyaXB0aW9uIG9mIGBJbmZlcmVuY2VTZXNzaW9uLklucHV0VHlwZWAgZm9yIGRldGFpbC5cbiAgICogQHBhcmFtIGZldGNoZXMgLSBSZXByZXNlbnRhdGlvbiBvZiB0aGUgbW9kZWwgb3V0cHV0LiBTZWUgdHlwZSBkZXNjcmlwdGlvbiBvZiBgSW5mZXJlbmNlU2Vzc2lvbi5PdXRwdXRUeXBlYCBmb3JcbiAgICogZGV0YWlsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsLiBBIHNldCBvZiBvcHRpb25zIHRoYXQgY29udHJvbHMgdGhlIGJlaGF2aW9yIG9mIG1vZGVsIGluZmVyZW5jZS5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBtYXAsIHdoaWNoIHVzZXMgb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICovXG4gIHJ1bihcbiAgICBmZWVkczogSW5mZXJlbmNlU2Vzc2lvbi5GZWVkc1R5cGUsXG4gICAgZmV0Y2hlczogSW5mZXJlbmNlU2Vzc2lvbi5GZXRjaGVzVHlwZSxcbiAgICBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24uUmV0dXJuVHlwZT47XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcmVsZWFzZSgpXG5cbiAgLyoqXG4gICAqIFJlbGVhc2UgdGhlIGluZmVyZW5jZSBzZXNzaW9uIGFuZCB0aGUgdW5kZXJseWluZyByZXNvdXJjZXMuXG4gICAqL1xuICByZWxlYXNlKCk6IFByb21pc2U8dm9pZD47XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcHJvZmlsaW5nXG5cbiAgLyoqXG4gICAqIFN0YXJ0IHByb2ZpbGluZy5cbiAgICovXG4gIHN0YXJ0UHJvZmlsaW5nKCk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIEVuZCBwcm9maWxpbmcuXG4gICAqL1xuICBlbmRQcm9maWxpbmcoKTogdm9pZDtcblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBtZXRhZGF0YVxuXG4gIC8qKlxuICAgKiBHZXQgaW5wdXQgbmFtZXMgb2YgdGhlIGxvYWRlZCBtb2RlbC5cbiAgICovXG4gIHJlYWRvbmx5IGlucHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBHZXQgb3V0cHV0IG5hbWVzIG9mIHRoZSBsb2FkZWQgbW9kZWwuXG4gICAqL1xuICByZWFkb25seSBvdXRwdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEdldCBpbnB1dCBtZXRhZGF0YSBvZiB0aGUgbG9hZGVkIG1vZGVsLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5wdXRNZXRhZGF0YTogcmVhZG9ubHkgSW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhW107XG5cbiAgLyoqXG4gICAqIEdldCBvdXRwdXQgbWV0YWRhdGEgb2YgdGhlIGxvYWRlZCBtb2RlbC5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dE1ldGFkYXRhOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXTtcblxuICAvLyAjZW5kcmVnaW9uXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5mZXJlbmNlU2Vzc2lvbkZhY3Rvcnkge1xuICAvLyAjcmVnaW9uIGNyZWF0ZSgpXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbiBhbmQgbG9hZCBtb2RlbCBhc3luY2hyb25vdXNseSBmcm9tIGFuIE9OTlggbW9kZWwgZmlsZS5cbiAgICpcbiAgICogQHBhcmFtIHVyaSAtIFRoZSBVUkkgb3IgZmlsZSBwYXRoIG9mIHRoZSBtb2RlbCB0byBsb2FkLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIHNwZWNpZnkgY29uZmlndXJhdGlvbiBmb3IgY3JlYXRpbmcgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24uXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEluZmVyZW5jZVNlc3Npb24gb2JqZWN0LlxuICAgKi9cbiAgY3JlYXRlKHVyaTogc3RyaW5nLCBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbj47XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbiBhbmQgbG9hZCBtb2RlbCBhc3luY2hyb25vdXNseSBmcm9tIGFuIGFycmF5IGJ1ZmVyLlxuICAgKlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gQW4gQXJyYXlCdWZmZXIgcmVwcmVzZW50YXRpb24gb2YgYW4gT05OWCBtb2RlbC5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBzcGVjaWZ5IGNvbmZpZ3VyYXRpb24gZm9yIGNyZWF0aW5nIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBJbmZlcmVuY2VTZXNzaW9uIG9iamVjdC5cbiAgICovXG4gIGNyZWF0ZShidWZmZXI6IEFycmF5QnVmZmVyTGlrZSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24+O1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24gYW5kIGxvYWQgbW9kZWwgYXN5bmNocm9ub3VzbHkgZnJvbSBzZWdtZW50IG9mIGFuIGFycmF5IGJ1ZmVyLlxuICAgKlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gQW4gQXJyYXlCdWZmZXIgcmVwcmVzZW50YXRpb24gb2YgYW4gT05OWCBtb2RlbC5cbiAgICogQHBhcmFtIGJ5dGVPZmZzZXQgLSBUaGUgYmVnaW5uaW5nIG9mIHRoZSBzcGVjaWZpZWQgcG9ydGlvbiBvZiB0aGUgYXJyYXkgYnVmZmVyLlxuICAgKiBAcGFyYW0gYnl0ZUxlbmd0aCAtIFRoZSBsZW5ndGggaW4gYnl0ZXMgb2YgdGhlIGFycmF5IGJ1ZmZlci5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBzcGVjaWZ5IGNvbmZpZ3VyYXRpb24gZm9yIGNyZWF0aW5nIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBJbmZlcmVuY2VTZXNzaW9uIG9iamVjdC5cbiAgICovXG4gIGNyZWF0ZShcbiAgICBidWZmZXI6IEFycmF5QnVmZmVyTGlrZSxcbiAgICBieXRlT2Zmc2V0OiBudW1iZXIsXG4gICAgYnl0ZUxlbmd0aD86IG51bWJlcixcbiAgICBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uPjtcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uIGFuZCBsb2FkIG1vZGVsIGFzeW5jaHJvbm91c2x5IGZyb20gYSBVaW50OEFycmF5LlxuICAgKlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gQSBVaW50OEFycmF5IHJlcHJlc2VudGF0aW9uIG9mIGFuIE9OTlggbW9kZWwuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gc3BlY2lmeSBjb25maWd1cmF0aW9uIGZvciBjcmVhdGluZyBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gSW5mZXJlbmNlU2Vzc2lvbiBvYmplY3QuXG4gICAqL1xuICBjcmVhdGUoYnVmZmVyOiBVaW50OEFycmF5LCBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbj47XG5cbiAgLy8gI2VuZHJlZ2lvblxufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG5leHBvcnQgY29uc3QgSW5mZXJlbmNlU2Vzc2lvbjogSW5mZXJlbmNlU2Vzc2lvbkZhY3RvcnkgPSBJbmZlcmVuY2VTZXNzaW9uSW1wbDtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgT3B0aW9uc0Zvcm1hdCwgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzLCBPcHRpb25zVGVuc29yTGF5b3V0IH0gZnJvbSAnLi90ZW5zb3ItZmFjdG9yeS5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yVG9EYXRhVXJsT3B0aW9ucyBleHRlbmRzIE9wdGlvbnNUZW5zb3JMYXlvdXQsIE9wdGlvbnNGb3JtYXQsIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyBleHRlbmRzIE9wdGlvbnNUZW5zb3JMYXlvdXQsIE9wdGlvbnNGb3JtYXQsIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZlcnNpb25VdGlscyB7XG4gIC8qKlxuICAgKiBjcmVhdGVzIGEgRGF0YVVSTCBpbnN0YW5jZSBmcm9tIHRlbnNvclxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgYSBEYXRhVVJMIGluc3RhbmNlIGZyb20gdGhlIHRlbnNvci5cbiAgICpcbiAgICogVGhlIGZvbGxvd2luZyBkZWZhdWx0IHNldHRpbmdzIHdpbGwgYmUgYXBwbGllZDpcbiAgICogLSBgZm9ybWF0YDogYCdSR0InYFxuICAgKiAtIGB0ZW5zb3JMYXlvdXRgOiBgJ05DSFcnYFxuICAgKiBAcmV0dXJucyBhIERhdGFVUkwgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgaW1hZ2UgY29udmVydGVkIGZyb20gdGVuc29yIGRhdGFcbiAgICovXG4gIHRvRGF0YVVSTChvcHRpb25zPzogVGVuc29yVG9EYXRhVXJsT3B0aW9ucyk6IHN0cmluZztcblxuICAvKipcbiAgICogY3JlYXRlcyBhbiBJbWFnZURhdGEgaW5zdGFuY2UgZnJvbSB0ZW5zb3JcbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIGFuIEltYWdlRGF0YSBpbnN0YW5jZSBmcm9tIHRoZSB0ZW5zb3IuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYGZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogQHJldHVybnMgYW4gSW1hZ2VEYXRhIGluc3RhbmNlIHJlcHJlc2VudGluZyB0aGUgaW1hZ2UgY29udmVydGVkIGZyb20gdGVuc29yIGRhdGFcbiAgICovXG4gIHRvSW1hZ2VEYXRhKG9wdGlvbnM/OiBUZW5zb3JUb0ltYWdlRGF0YU9wdGlvbnMpOiBJbWFnZURhdGE7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciwgVHlwZWRUZW5zb3IgfSBmcm9tICcuL3RlbnNvci5qcyc7XG5cbmV4cG9ydCB0eXBlIEltYWdlRm9ybWF0ID0gJ1JHQicgfCAnUkdCQScgfCAnQkdSJyB8ICdSQkcnO1xuZXhwb3J0IHR5cGUgSW1hZ2VUZW5zb3JMYXlvdXQgPSAnTkhXQycgfCAnTkNIVyc7XG5cbi8vIHRoZSBmb2xsb3dpbmcgcmVnaW9uIGNvbnRhaW5zIHR5cGUgZGVmaW5pdGlvbnMgZm9yIGNvbnN0cnVjdGluZyB0ZW5zb3IgZnJvbSBhIHNwZWNpZmljIGxvY2F0aW9uLlxuXG4vLyAjcmVnaW9uIHR5cGVzIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIHNwZWNpZmljIGxvY2F0aW9uXG5cbi8qKlxuICogcmVwcmVzZW50IGNvbW1vbiBwcm9wZXJ0aWVzIG9mIHRoZSBwYXJhbWV0ZXIgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgc3BlY2lmaWMgbG9jYXRpb24uXG4gKi9cbmludGVyZmFjZSBDb21tb25Db25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4gZXh0ZW5kcyBQaWNrPFRlbnNvciwgJ2RpbXMnPiB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIHJlYWRvbmx5IHR5cGU6IFQ7XG59XG5cbi8qKlxuICogcmVwcmVzZW50IHRoZSBwYXJhbWV0ZXIgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgR1BVIHJlc291cmNlLlxuICovXG5pbnRlcmZhY2UgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VCBleHRlbmRzIFRlbnNvci5UeXBlPiB7XG4gIC8qKlxuICAgKiBhbiBvcHRpb25hbCBjYWxsYmFjayBmdW5jdGlvbiB0byBkb3dubG9hZCBkYXRhIGZyb20gR1BVIHRvIENQVS5cbiAgICpcbiAgICogSWYgbm90IHByb3ZpZGVkLCB0aGUgdGVuc29yIHRyZWF0IHRoZSBHUFUgZGF0YSBhcyBleHRlcm5hbCByZXNvdXJjZS5cbiAgICovXG4gIGRvd25sb2FkPygpOiBQcm9taXNlPFRlbnNvci5EYXRhVHlwZU1hcFtUXT47XG5cbiAgLyoqXG4gICAqIGFuIG9wdGlvbmFsIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUgdGVuc29yIGlzIGRpc3Bvc2VkLlxuICAgKlxuICAgKiBJZiBub3QgcHJvdmlkZWQsIHRoZSB0ZW5zb3IgdHJlYXQgdGhlIEdQVSBkYXRhIGFzIGV4dGVybmFsIHJlc291cmNlLlxuICAgKi9cbiAgZGlzcG9zZT8oKTogdm9pZDtcbn1cblxuLyoqXG4gKiByZXByZXNlbnQgdGhlIHBhcmFtZXRlciBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBwaW5uZWQgQ1BVIGJ1ZmZlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLkNwdVBpbm5lZERhdGFUeXBlcyA9IFRlbnNvci5DcHVQaW5uZWREYXRhVHlwZXM+XG4gIGV4dGVuZHMgQ29tbW9uQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIHRvIGJlICdjcHUtcGlubmVkJy5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiAnY3B1LXBpbm5lZCc7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBDUFUgcGlubmVkIGJ1ZmZlciB0aGF0IGhvbGRzIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICovXG4gIHJlYWRvbmx5IGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFtUXTtcbn1cblxuLyoqXG4gKiByZXByZXNlbnQgdGhlIHBhcmFtZXRlciBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBXZWJHTCB0ZXh0dXJlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dHVyZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLlRleHR1cmVEYXRhVHlwZXMgPSBUZW5zb3IuVGV4dHVyZURhdGFUeXBlcz5cbiAgZXh0ZW5kcyBDb21tb25Db25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4sXG4gICAgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4ge1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgbG9jYXRpb24gb2YgdGhlIGRhdGEgdG8gYmUgJ3RleHR1cmUnLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9jYXRpb246ICd0ZXh0dXJlJztcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIFdlYkdMIHRleHR1cmUgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqL1xuICByZWFkb25seSB0ZXh0dXJlOiBUZW5zb3IuVGV4dHVyZVR5cGU7XG59XG5cbi8qKlxuICogcmVwcmVzZW50IHRoZSBwYXJhbWV0ZXIgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgV2ViR1BVIGJ1ZmZlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdwdUJ1ZmZlckNvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLkdwdUJ1ZmZlckRhdGFUeXBlcyA9IFRlbnNvci5HcHVCdWZmZXJEYXRhVHlwZXM+XG4gIGV4dGVuZHMgQ29tbW9uQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+LFxuICAgIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIHRvIGJlICdncHUtYnVmZmVyJy5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiAnZ3B1LWJ1ZmZlcic7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBXZWJHUFUgYnVmZmVyIHRoYXQgaG9sZHMgdGhlIHRlbnNvciBkYXRhLlxuICAgKi9cbiAgcmVhZG9ubHkgZ3B1QnVmZmVyOiBUZW5zb3IuR3B1QnVmZmVyVHlwZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNTFRlbnNvckNvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLk1MVGVuc29yRGF0YVR5cGVzID0gVGVuc29yLk1MVGVuc29yRGF0YVR5cGVzPlxuICBleHRlbmRzIENvbW1vbkNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPixcbiAgICBHcHVSZXNvdXJjZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBsb2NhdGlvbiBvZiB0aGUgZGF0YSB0byBiZSAnbWwtdGVuc29yJy5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiAnbWwtdGVuc29yJztcblxuICAvKipcbiAgICogU3BlY2lmeSB0aGUgV2ViTk4gTUxUZW5zb3IgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqL1xuICByZWFkb25seSBtbFRlbnNvcjogVGVuc29yLk1MVGVuc29yVHlwZTtcbn1cblxuLy8gI2VuZHJlZ2lvblxuXG4vLyB0aGUgZm9sbG93aW5nIHJlZ2lvbiBjb250YWlucyB0eXBlIGRlZmluaXRpb25zIG9mIGVhY2ggaW5kaXZpZHVhbCBvcHRpb25zLlxuLy8gdGhlIHRlbnNvciBmYWN0b3J5IGZ1bmN0aW9ucyB1c2UgYSBjb21wb3NpdGlvbiBvZiB0aG9zZSBvcHRpb25zIGFzIHRoZSBwYXJhbWV0ZXIgdHlwZS5cblxuLy8gI3JlZ2lvbiBPcHRpb25zIGZpZWxkc1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNGb3JtYXQge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBpbWFnZSBmb3JtYXQgcmVwcmVzZW50ZWQgaW4gUkdCQSBjb2xvciBzcGFjZS5cbiAgICovXG4gIGZvcm1hdD86IEltYWdlRm9ybWF0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNUZW5zb3JGb3JtYXQge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBpbWFnZSBmb3JtYXQgb2YgdGhlIHRlbnNvci5cbiAgICpcbiAgICogTk9URTogdGhpcyBpcyBkaWZmZXJlbnQgZnJvbSBvcHRpb24gJ2Zvcm1hdCcuIFdoaWxlIG9wdGlvbiAnZm9ybWF0JyByZXByZXNlbnRzIHRoZSBvcmlnaW5hbCBpbWFnZSwgJ3RlbnNvckZvcm1hdCdcbiAgICogcmVwcmVzZW50cyB0aGUgdGFyZ2V0IGZvcm1hdCBvZiB0aGUgdGVuc29yLiBBIHRyYW5zcG9zZSB3aWxsIGJlIHBlcmZvcm1lZCBpZiB0aGV5IGFyZSBkaWZmZXJlbnQuXG4gICAqL1xuICB0ZW5zb3JGb3JtYXQ/OiBJbWFnZUZvcm1hdDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zVGVuc29yRGF0YVR5cGUge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIGRhdGFUeXBlPzogJ2Zsb2F0MzInIHwgJ3VpbnQ4Jztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zVGVuc29yTGF5b3V0IHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgdGVuc29yIGxheW91dCB3aGVuIHJlcHJlc2VudGluZyBkYXRhIG9mIG9uZSBvciBtb3JlIGltYWdlKHMpLlxuICAgKi9cbiAgdGVuc29yTGF5b3V0PzogSW1hZ2VUZW5zb3JMYXlvdXQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9uc0RpbWVuc2lvbnMge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBpbWFnZSBoZWlnaHQgaW4gcGl4ZWxcbiAgICovXG4gIGhlaWdodD86IG51bWJlcjtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgaW1hZ2Ugd2lkdGggaW4gcGl4ZWxcbiAgICovXG4gIHdpZHRoPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zIHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgcmVzaXplZCBoZWlnaHQuIElmIG9taXR0ZWQsIG9yaWdpbmFsIGhlaWdodCB3aWxsIGJlIHVzZWQuXG4gICAqL1xuICByZXNpemVkSGVpZ2h0PzogbnVtYmVyO1xuICAvKipcbiAgICogRGVzY3JpYmVzIHJlc2l6ZWQgd2lkdGggLSBjYW4gYmUgYWNjZXNzZWQgdmlhIHRlbnNvciBkaW1lbnNpb25zIGFzIHdlbGxcbiAgICovXG4gIHJlc2l6ZWRXaWR0aD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMge1xuICAvKipcbiAgICogRGVzY3JpYmVzIG5vcm1hbGl6YXRpb24gcGFyYW1ldGVycyB3aGVuIHByZXByb2Nlc3NpbmcgdGhlIGltYWdlIGFzIG1vZGVsIGlucHV0LlxuICAgKlxuICAgKiBEYXRhIGVsZW1lbnQgYXJlIHJhbmdlZCBmcm9tIDAgdG8gMjU1LlxuICAgKi9cbiAgbm9ybT86IHtcbiAgICAvKipcbiAgICAgKiBUaGUgJ2JpYXMnIHZhbHVlIGZvciBpbWFnZSBub3JtYWxpemF0aW9uLlxuICAgICAqIC0gSWYgb21pdHRlZCwgdXNlIGRlZmF1bHQgdmFsdWUgMC5cbiAgICAgKiAtIElmIGl0J3MgYSBzaW5nbGUgbnVtYmVyLCBhcHBseSB0byBlYWNoIGNoYW5uZWxcbiAgICAgKiAtIElmIGl0J3MgYW4gYXJyYXkgb2YgMyBvciA0IG51bWJlcnMsIGFwcGx5IGVsZW1lbnQtd2lzZS4gTnVtYmVyIG9mIGVsZW1lbnRzIG5lZWQgdG8gbWF0Y2ggdGhlIG51bWJlciBvZiBjaGFubmVsc1xuICAgICAqIGZvciB0aGUgY29ycmVzcG9uZGluZyBpbWFnZSBmb3JtYXRcbiAgICAgKi9cbiAgICBiaWFzPzogbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgLyoqXG4gICAgICogVGhlICdtZWFuJyB2YWx1ZSBmb3IgaW1hZ2Ugbm9ybWFsaXphdGlvbi5cbiAgICAgKiAtIElmIG9taXR0ZWQsIHVzZSBkZWZhdWx0IHZhbHVlIDI1NS5cbiAgICAgKiAtIElmIGl0J3MgYSBzaW5nbGUgbnVtYmVyLCBhcHBseSB0byBlYWNoIGNoYW5uZWxcbiAgICAgKiAtIElmIGl0J3MgYW4gYXJyYXkgb2YgMyBvciA0IG51bWJlcnMsIGFwcGx5IGVsZW1lbnQtd2lzZS4gTnVtYmVyIG9mIGVsZW1lbnRzIG5lZWQgdG8gbWF0Y2ggdGhlIG51bWJlciBvZiBjaGFubmVsc1xuICAgICAqIGZvciB0aGUgY29ycmVzcG9uZGluZyBpbWFnZSBmb3JtYXRcbiAgICAgKi9cbiAgICBtZWFuPzogbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIH07XG59XG5cbi8vICNlbmRyZWdpb25cblxuLy8gI3JlZ2lvbiBPcHRpb25zIGNvbXBvc2l0aW9uXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnNcbiAgZXh0ZW5kcyBPcHRpb25SZXNpemVkRGltZW5zaW9ucyxcbiAgICBPcHRpb25zVGVuc29yRm9ybWF0LFxuICAgIE9wdGlvbnNUZW5zb3JMYXlvdXQsXG4gICAgT3B0aW9uc1RlbnNvckRhdGFUeXBlLFxuICAgIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zXG4gIGV4dGVuZHMgT3B0aW9uUmVzaXplZERpbWVuc2lvbnMsXG4gICAgT3B0aW9uc1RlbnNvckZvcm1hdCxcbiAgICBPcHRpb25zVGVuc29yTGF5b3V0LFxuICAgIE9wdGlvbnNUZW5zb3JEYXRhVHlwZSxcbiAgICBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMge31cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tVXJsT3B0aW9uc1xuICBleHRlbmRzIE9wdGlvbnNEaW1lbnNpb25zLFxuICAgIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zLFxuICAgIE9wdGlvbnNUZW5zb3JGb3JtYXQsXG4gICAgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgICBPcHRpb25zVGVuc29yRGF0YVR5cGUsXG4gICAgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9uc1xuICBleHRlbmRzIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zLFxuICAgIE9wdGlvbnNUZW5zb3JGb3JtYXQsXG4gICAgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgICBPcHRpb25zVGVuc29yRGF0YVR5cGUsXG4gICAgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbVRleHR1cmVPcHRpb25zPFQgZXh0ZW5kcyBUZW5zb3IuVGV4dHVyZURhdGFUeXBlcz5cbiAgZXh0ZW5kcyBSZXF1aXJlZDxPcHRpb25zRGltZW5zaW9ucz4sXG4gICAgT3B0aW9uc0Zvcm1hdCxcbiAgICBHcHVSZXNvdXJjZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiAvKiBUT0RPOiBhZGQgbW9yZSAqLyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZyb21HcHVCdWZmZXJPcHRpb25zPFQgZXh0ZW5kcyBUZW5zb3IuR3B1QnVmZmVyRGF0YVR5cGVzPlxuICBleHRlbmRzIFBpY2s8VGVuc29yLCAnZGltcyc+LFxuICAgIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAqL1xuICBkYXRhVHlwZT86IFQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbU1MVGVuc29yT3B0aW9uczxUIGV4dGVuZHMgVGVuc29yLk1MVGVuc29yRGF0YVR5cGVzPlxuICBleHRlbmRzIFBpY2s8VGVuc29yLCAnZGltcyc+LFxuICAgIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAqL1xuICBkYXRhVHlwZT86IFQ7XG59XG5cbi8vICNlbmRyZWdpb25cblxuLyoqXG4gKiB0eXBlIFRlbnNvckZhY3RvcnkgZGVmaW5lcyB0aGUgZmFjdG9yeSBmdW5jdGlvbnMgb2YgJ1RlbnNvcicgdG8gY3JlYXRlIHRlbnNvciBpbnN0YW5jZXMgZnJvbSBleGlzdGluZyBkYXRhIG9yXG4gKiByZXNvdXJjZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRmFjdG9yeSB7XG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhbiBJbWFnZURhdGEgb2JqZWN0XG4gICAqXG4gICAqIEBwYXJhbSBpbWFnZURhdGEgLSB0aGUgSW1hZ2VEYXRhIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIEltYWdlRGF0YS5cbiAgICpcbiAgICogVGhlIGZvbGxvd2luZyBkZWZhdWx0IHNldHRpbmdzIHdpbGwgYmUgYXBwbGllZDpcbiAgICogLSBgdGVuc29yRm9ybWF0YDogYCdSR0InYFxuICAgKiAtIGB0ZW5zb3JMYXlvdXRgOiBgJ05DSFcnYFxuICAgKiAtIGBkYXRhVHlwZWA6IGAnZmxvYXQzMidgXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbUltYWdlKFxuICAgIGltYWdlRGF0YTogSW1hZ2VEYXRhLFxuICAgIG9wdGlvbnM/OiBUZW5zb3JGcm9tSW1hZ2VEYXRhT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxUeXBlZFRlbnNvcjwnZmxvYXQzMic+IHwgVHlwZWRUZW5zb3I8J3VpbnQ4Jz4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhIEhUTUxJbWFnZUVsZW1lbnQgb2JqZWN0XG4gICAqXG4gICAqIEBwYXJhbSBpbWFnZUVsZW1lbnQgLSB0aGUgSFRNTEltYWdlRWxlbWVudCBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBIVE1MSW1hZ2VFbGVtZW50LlxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGRlZmF1bHQgc2V0dGluZ3Mgd2lsbCBiZSBhcHBsaWVkOlxuICAgKiAtIGB0ZW5zb3JGb3JtYXRgOiBgJ1JHQidgXG4gICAqIC0gYHRlbnNvckxheW91dGA6IGAnTkNIVydgXG4gICAqIC0gYGRhdGFUeXBlYDogYCdmbG9hdDMyJ2BcbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tSW1hZ2UoXG4gICAgaW1hZ2VFbGVtZW50OiBIVE1MSW1hZ2VFbGVtZW50LFxuICAgIG9wdGlvbnM/OiBUZW5zb3JGcm9tSW1hZ2VFbGVtZW50T3B0aW9ucyxcbiAgKTogUHJvbWlzZTxUeXBlZFRlbnNvcjwnZmxvYXQzMic+IHwgVHlwZWRUZW5zb3I8J3VpbnQ4Jz4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBVUkxcbiAgICpcbiAgICogQHBhcmFtIHVybFNvdXJjZSAtIGEgc3RyaW5nIGFzIGEgVVJMIHRvIHRoZSBpbWFnZSBvciBhIGRhdGEgVVJMIGNvbnRhaW5pbmcgdGhlIGltYWdlIGRhdGEuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBVUkwuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYHRlbnNvckZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogLSBgZGF0YVR5cGVgOiBgJ2Zsb2F0MzInYFxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21JbWFnZSh1cmxTb3VyY2U6IHN0cmluZywgb3B0aW9ucz86IFRlbnNvckZyb21VcmxPcHRpb25zKTogUHJvbWlzZTxUeXBlZFRlbnNvcjwnZmxvYXQzMic+IHwgVHlwZWRUZW5zb3I8J3VpbnQ4Jz4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhbiBJbWFnZUJpdG1hcCBvYmplY3RcbiAgICpcbiAgICogQHBhcmFtIGJpdG1hcCAtIHRoZSBJbWFnZUJpdG1hcCBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBVUkwuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYHRlbnNvckZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogLSBgZGF0YVR5cGVgOiBgJ2Zsb2F0MzInYFxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21JbWFnZShcbiAgICBiaXRtYXA6IEltYWdlQml0bWFwLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21JbWFnZUJpdG1hcE9wdGlvbnMsXG4gICk6IFByb21pc2U8VHlwZWRUZW5zb3I8J2Zsb2F0MzInPiB8IFR5cGVkVGVuc29yPCd1aW50OCc+PjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBXZWJHTCB0ZXh0dXJlXG4gICAqXG4gICAqIEBwYXJhbSB0ZXh0dXJlIC0gdGhlIFdlYkdMVGV4dHVyZSBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBXZWJHTCB0ZXh0dXJlLlxuICAgKlxuICAgKiBUaGUgb3B0aW9ucyBpbmNsdWRlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICAgKiAtIGB3aWR0aGA6IHRoZSB3aWR0aCBvZiB0aGUgdGV4dHVyZS4gUmVxdWlyZWQuXG4gICAqIC0gYGhlaWdodGA6IHRoZSBoZWlnaHQgb2YgdGhlIHRleHR1cmUuIFJlcXVpcmVkLlxuICAgKiAtIGBmb3JtYXRgOiB0aGUgZm9ybWF0IG9mIHRoZSB0ZXh0dXJlLiBJZiBvbWl0dGVkLCBhc3N1bWUgJ1JHQkEnLlxuICAgKiAtIGBkb3dubG9hZGA6IGFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGRvd25sb2FkIHRoZSB0ZW5zb3IgZGF0YSBmcm9tIEdQVSB0byBDUFUuIElmIG9taXR0ZWQsIHRoZSBHUFUgZGF0YVxuICAgKiB3aWxsIG5vdCBiZSBhYmxlIHRvIGRvd25sb2FkLiBVc3VhbGx5LCB0aGlzIGlzIHByb3ZpZGVkIGJ5IGEgR1BVIGJhY2tlbmQgZm9yIHRoZSBpbmZlcmVuY2Ugb3V0cHV0cy4gVXNlcnMgZG9uJ3RcbiAgICogbmVlZCB0byBwcm92aWRlIHRoaXMgZnVuY3Rpb24uXG4gICAqIC0gYGRpc3Bvc2VgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkaXNwb3NlIHRoZSB0ZW5zb3IgZGF0YSBvbiBHUFUuIElmIG9taXR0ZWQsIHRoZSBHUFUgZGF0YSB3aWxsIG5vdCBiZSBkaXNwb3NlZC5cbiAgICogVXN1YWxseSwgdGhpcyBpcyBwcm92aWRlZCBieSBhIEdQVSBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuIFVzZXJzIGRvbid0IG5lZWQgdG8gcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21UZXh0dXJlPFQgZXh0ZW5kcyBUZW5zb3IuVGV4dHVyZURhdGFUeXBlcyA9ICdmbG9hdDMyJz4oXG4gICAgdGV4dHVyZTogVGVuc29yLlRleHR1cmVUeXBlLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21UZXh0dXJlT3B0aW9uczxUPixcbiAgKTogVHlwZWRUZW5zb3I8J2Zsb2F0MzInPjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBXZWJHUFUgYnVmZmVyXG4gICAqXG4gICAqIEBwYXJhbSBidWZmZXIgLSB0aGUgR1BVQnVmZmVyIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIFdlYkdQVSBidWZmZXIuXG4gICAqXG4gICAqIFRoZSBvcHRpb25zIGluY2x1ZGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gICAqIC0gYGRhdGFUeXBlYDogdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhc3N1bWUgJ2Zsb2F0MzInLlxuICAgKiAtIGBkaW1zYDogdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBSZXF1aXJlZC5cbiAgICogLSBgZG93bmxvYWRgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkb3dubG9hZCB0aGUgdGVuc29yIGRhdGEgZnJvbSBHUFUgdG8gQ1BVLiBJZiBvbWl0dGVkLCB0aGUgR1BVIGRhdGFcbiAgICogd2lsbCBub3QgYmUgYWJsZSB0byBkb3dubG9hZC4gVXN1YWxseSwgdGhpcyBpcyBwcm92aWRlZCBieSBhIEdQVSBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuIFVzZXJzIGRvbid0XG4gICAqIG5lZWQgdG8gcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKiAtIGBkaXNwb3NlYDogYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZGlzcG9zZSB0aGUgdGVuc29yIGRhdGEgb24gR1BVLiBJZiBvbWl0dGVkLCB0aGUgR1BVIGRhdGEgd2lsbCBub3QgYmUgZGlzcG9zZWQuXG4gICAqIFVzdWFsbHksIHRoaXMgaXMgcHJvdmlkZWQgYnkgYSBHUFUgYmFja2VuZCBmb3IgdGhlIGluZmVyZW5jZSBvdXRwdXRzLiBVc2VycyBkb24ndCBuZWVkIHRvIHByb3ZpZGUgdGhpcyBmdW5jdGlvbi5cbiAgICpcbiAgICogQHJldHVybnMgYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tR3B1QnVmZmVyPFQgZXh0ZW5kcyBUZW5zb3IuR3B1QnVmZmVyRGF0YVR5cGVzPihcbiAgICBidWZmZXI6IFRlbnNvci5HcHVCdWZmZXJUeXBlLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21HcHVCdWZmZXJPcHRpb25zPFQ+LFxuICApOiBUeXBlZFRlbnNvcjxUPjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBXZWJOTiBNTFRlbnNvclxuICAgKlxuICAgKiBAcGFyYW0gdGVuc29yIC0gdGhlIE1MVGVuc29yIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIGEgV2ViTk4gTUxUZW5zb3IuXG4gICAqXG4gICAqIFRoZSBvcHRpb25zIGluY2x1ZGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gICAqIC0gYGRhdGFUeXBlYDogdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhc3N1bWUgJ2Zsb2F0MzInLlxuICAgKiAtIGBkaW1zYDogdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBSZXF1aXJlZC5cbiAgICogLSBgZG93bmxvYWRgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkb3dubG9hZCB0aGUgdGVuc29yIGRhdGEgZnJvbSB0aGUgTUxUZW5zb3IgdG8gQ1BVLiBJZiBvbWl0dGVkLCB0aGUgTUxUZW5zb3JcbiAgICogZGF0YSB3aWxsIG5vdCBiZSBhYmxlIHRvIGRvd25sb2FkLiBVc3VhbGx5LCB0aGlzIGlzIHByb3ZpZGVkIGJ5IHRoZSBXZWJOTiBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuXG4gICAqIFVzZXJzIGRvbid0IG5lZWQgdG8gcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKiAtIGBkaXNwb3NlYDogYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZGlzcG9zZSB0aGUgdGVuc29yIGRhdGEgb24gdGhlIFdlYk5OIE1MVGVuc29yLiBJZiBvbWl0dGVkLCB0aGUgTUxUZW5zb3Igd2lsbFxuICAgKiBub3QgYmUgZGlzcG9zZWQuIFVzdWFsbHksIHRoaXMgaXMgcHJvdmlkZWQgYnkgdGhlIFdlYk5OIGJhY2tlbmQgZm9yIHRoZSBpbmZlcmVuY2Ugb3V0cHV0cy4gVXNlcnMgZG9uJ3QgbmVlZCB0b1xuICAgKiBwcm92aWRlIHRoaXMgZnVuY3Rpb24uXG4gICAqXG4gICAqIEByZXR1cm5zIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbU1MVGVuc29yPFQgZXh0ZW5kcyBUZW5zb3IuTUxUZW5zb3JEYXRhVHlwZXM+KFxuICAgIHRlbnNvcjogVGVuc29yLk1MVGVuc29yVHlwZSxcbiAgICBvcHRpb25zOiBUZW5zb3JGcm9tTUxUZW5zb3JPcHRpb25zPFQ+LFxuICApOiBUeXBlZFRlbnNvcjxUPjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBwcmUtYWxsb2NhdGVkIGJ1ZmZlci4gVGhlIGJ1ZmZlciB3aWxsIGJlIHVzZWQgYXMgYSBwaW5uZWQgYnVmZmVyLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIHRoZSB0ZW5zb3IgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gYSBUeXBlZEFycmF5IGNvcnJlc3BvbmRpbmcgdG8gdGhlIHR5cGUuXG4gICAqIEBwYXJhbSBkaW1zIC0gc3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21QaW5uZWRCdWZmZXI8VCBleHRlbmRzIEV4Y2x1ZGU8VGVuc29yLlR5cGUsICdzdHJpbmcnPj4oXG4gICAgdHlwZTogVCxcbiAgICBidWZmZXI6IFRlbnNvci5EYXRhVHlwZU1hcFtUXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IFR5cGVkVGVuc29yPFQ+O1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vKipcbiAqIEEgc3RyaW5nIHRoYXQgcmVwcmVzZW50cyBhIGZpbGUncyBVUkwgb3IgcGF0aC5cbiAqXG4gKiBQYXRoIGlzIHZhaWxhYmxlIG9ubHkgaW4gb25ueHJ1bnRpbWUtbm9kZSBvciBvbm54cnVudGltZS13ZWIgcnVubmluZyBpbiBOb2RlLmpzLlxuICovXG5leHBvcnQgdHlwZSBGaWxlVXJsT3JQYXRoID0gc3RyaW5nO1xuXG4vKipcbiAqIEEgQmxvYiBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgZmlsZS5cbiAqL1xuZXhwb3J0IHR5cGUgRmlsZUJsb2IgPSBCbG9iO1xuXG4vKipcbiAqIEEgVWludDhBcnJheSwgQXJyYXlCdWZmZXIgb3IgU2hhcmVkQXJyYXlCdWZmZXIgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhIGZpbGUgY29udGVudC5cbiAqXG4gKiBXaGVuIGl0IGlzIGFuIEFycmF5QnVmZmVyIG9yIFNoYXJlZEFycmF5QnVmZmVyLCB0aGUgd2hvbGUgYnVmZmVyIGlzIGFzc3VtZWQgdG8gYmUgdGhlIGZpbGUgY29udGVudC5cbiAqL1xuZXhwb3J0IHR5cGUgRmlsZURhdGEgPSBVaW50OEFycmF5IHwgQXJyYXlCdWZmZXJMaWtlO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBmaWxlIHRoYXQgY2FuIGJlIGxvYWRlZCBieSB0aGUgT05OWCBSdW50aW1lIEphdmFTY3JpcHQgQVBJLlxuICovXG5leHBvcnQgdHlwZSBGaWxlVHlwZSA9IEZpbGVVcmxPclBhdGggfCBGaWxlQmxvYiB8IEZpbGVEYXRhO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gZXh0ZXJuYWwgZGF0YSBmaWxlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVybmFsRGF0YUZpbGVEZXNjcmlwdGlvbiB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBleHRlcm5hbCBkYXRhIGZpbGUuXG4gICAqL1xuICBkYXRhOiBGaWxlVHlwZTtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGZpbGUgcGF0aC5cbiAgICovXG4gIHBhdGg6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIGV4dGVybmFsIGRhdGEgZmlsZS5cbiAqXG4gKiBXaGVuIHVzaW5nIGEgc3RyaW5nLCBpdCBzaG91bGQgYmUgYSBmaWxlIFVSTCBvciBwYXRoIHRoYXQgaW4gdGhlIHNhbWUgZGlyZWN0b3J5IGFzIHRoZSBtb2RlbCBmaWxlLlxuICovXG5leHBvcnQgdHlwZSBFeHRlcm5hbERhdGFGaWxlVHlwZSA9IEV4dGVybmFsRGF0YUZpbGVEZXNjcmlwdGlvbiB8IEZpbGVVcmxPclBhdGg7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgbW9kZWwgbG9hZGluZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPbm54TW9kZWxPcHRpb25zIHtcbiAgLyoqXG4gICAqIFNwZWNpZnlpbmcgYSBsaXN0IG9mIGZpbGVzIHRoYXQgcmVwcmVzZW50cyB0aGUgZXh0ZXJuYWwgZGF0YS5cbiAgICovXG4gIGV4dGVybmFsRGF0YT86IHJlYWRvbmx5IEV4dGVybmFsRGF0YUZpbGVUeXBlW107XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yLmpzJztcblxuZXhwb3J0IHR5cGUgTm9uVGVuc29yVHlwZSA9IG5ldmVyO1xuXG4vKipcbiAqIFR5cGUgT25ueFZhbHVlIFJlcHJlc2VudHMgYm90aCB0ZW5zb3JzIGFuZCBub24tdGVuc29ycyB2YWx1ZSBmb3IgbW9kZWwncyBpbnB1dHMvb3V0cHV0cy5cbiAqXG4gKiBOT1RFOiBjdXJyZW50bHkgbm90IHN1cHBvcnQgbm9uLXRlbnNvclxuICovXG5leHBvcnQgdHlwZSBPbm54VmFsdWUgPSBUZW5zb3IgfCBOb25UZW5zb3JUeXBlO1xuXG4vKipcbiAqIFR5cGUgT25ueFZhbHVlRGF0YUxvY2F0aW9uIHJlcHJlc2VudHMgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIG9mIGFuIE9ubnhWYWx1ZS5cbiAqL1xuZXhwb3J0IHR5cGUgT25ueFZhbHVlRGF0YUxvY2F0aW9uID0gVGVuc29yLkRhdGFMb2NhdGlvbjtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLyoqXG4gKiAjIE9OTlggUnVudGltZSBKYXZhU2NyaXB0IEFQSVxuICpcbiAqIE9OTlggUnVudGltZSBKYXZhU2NyaXB0IEFQSSBpcyBhIHVuaWZpZWQgQVBJIGZvciBhbGwgSmF2YVNjcmlwdCB1c2FnZXMsIGluY2x1ZGluZyB0aGUgZm9sbG93aW5nIE5QTSBwYWNrYWdlczpcbiAqXG4gKiAtIFtvbm54cnVudGltZS1ub2RlXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9vbm54cnVudGltZS1ub2RlKVxuICogLSBbb25ueHJ1bnRpbWUtd2ViXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9vbm54cnVudGltZS13ZWIpXG4gKiAtIFtvbm54cnVudGltZS1yZWFjdC1uYXRpdmVdKGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL29ubnhydW50aW1lLXJlYWN0LW5hdGl2ZSlcbiAqXG4gKiBTZWUgYWxzbzpcbiAqIC0gW0dldCBTdGFydGVkXShodHRwczovL29ubnhydW50aW1lLmFpL2RvY3MvZ2V0LXN0YXJ0ZWQvd2l0aC1qYXZhc2NyaXB0LylcbiAqIC0gW0luZmVyZW5jZSBleGFtcGxlc10oaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS1pbmZlcmVuY2UtZXhhbXBsZXMvdHJlZS9tYWluL2pzKVxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vYmFja2VuZC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2Vudi5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2luZmVyZW5jZS1zZXNzaW9uLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdGVuc29yLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdGVuc29yLWNvbnZlcnNpb24uanMnO1xuZXhwb3J0ICogZnJvbSAnLi90ZW5zb3ItZmFjdG9yeS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3RyYWNlLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vb25ueC1tb2RlbC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL29ubngtdmFsdWUuanMnO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBFbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL2JhY2tlbmRzL3dlYmdsL3dlYmdsLWNvbnRleHQnO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgTG9nZ2VyIHtcbiAgZXhwb3J0IGludGVyZmFjZSBTZXZlcml0eVR5cGVNYXAge1xuICAgIHZlcmJvc2U6ICd2JztcbiAgICBpbmZvOiAnaSc7XG4gICAgd2FybmluZzogJ3cnO1xuICAgIGVycm9yOiAnZSc7XG4gICAgZmF0YWw6ICdmJztcbiAgfVxuXG4gIGV4cG9ydCB0eXBlIFNldmVyaXR5ID0ga2V5b2YgU2V2ZXJpdHlUeXBlTWFwO1xuXG4gIGV4cG9ydCB0eXBlIFByb3ZpZGVyID0gJ25vbmUnIHwgJ2NvbnNvbGUnO1xuXG4gIC8qKlxuICAgKiBMb2dnaW5nIGNvbmZpZyB0aGF0IHVzZWQgdG8gY29udHJvbCB0aGUgYmVoYXZpb3Igb2YgbG9nZ2VyXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIENvbmZpZyB7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgbG9nZ2luZyBwcm92aWRlci4gJ2NvbnNvbGUnIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBwcm92aWRlcj86IFByb3ZpZGVyO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgdGhlIG1pbmltYWwgbG9nZ2VyIHNldmVyaXR5LiAnd2FybmluZycgYnkgZGVmYXVsdFxuICAgICAqL1xuICAgIG1pbmltYWxTZXZlcml0eT86IExvZ2dlci5TZXZlcml0eTtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRvIG91dHB1dCBkYXRlIHRpbWUgaW4gbG9nLiB0cnVlIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBsb2dEYXRlVGltZT86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0byBvdXRwdXQgc291cmNlIGluZm9ybWF0aW9uIChOb3QgeWV0IHN1cHBvcnRlZCkuIGZhbHNlIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBsb2dTb3VyY2VMb2NhdGlvbj86IGJvb2xlYW47XG4gIH1cblxuICBleHBvcnQgaW50ZXJmYWNlIENhdGVnb3JpemVkTG9nZ2VyIHtcbiAgICB2ZXJib3NlKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gICAgaW5mbyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICAgIHdhcm5pbmcoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgICBlcnJvcihjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICAgIGZhdGFsKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIH1cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmVcbmV4cG9ydCBpbnRlcmZhY2UgTG9nZ2VyIHtcbiAgKGNhdGVnb3J5OiBzdHJpbmcpOiBMb2dnZXIuQ2F0ZWdvcml6ZWRMb2dnZXI7XG5cbiAgdmVyYm9zZShjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB2ZXJib3NlKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGluZm8oY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgaW5mbyhjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB3YXJuaW5nKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIHdhcm5pbmcoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXJyb3IoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXJyb3IoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZmF0YWwoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZmF0YWwoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcblxuICAvKipcbiAgICogUmVzZXQgdGhlIGxvZ2dlciBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0gY29uZmlnIHNwZWNpZnkgYW4gb3B0aW9uYWwgZGVmYXVsdCBjb25maWdcbiAgICovXG4gIHJlc2V0KGNvbmZpZz86IExvZ2dlci5Db25maWcpOiB2b2lkO1xuICAvKipcbiAgICogU2V0IHRoZSBsb2dnZXIncyBiZWhhdmlvciBvbiB0aGUgZ2l2ZW4gY2F0ZWdvcnlcbiAgICogQHBhcmFtIGNhdGVnb3J5IHNwZWNpZnkgYSBjYXRlZ29yeSBzdHJpbmcuIElmICcqJyBpcyBzcGVjaWZpZWQsIGFsbCBwcmV2aW91cyBjb25maWd1cmF0aW9uIHdpbGwgYmUgb3ZlcndyaXR0ZW4uIElmXG4gICAqICcnIGlzIHNwZWNpZmllZCwgdGhlIGRlZmF1bHQgYmVoYXZpb3Igd2lsbCBiZSB1cGRhdGVkLlxuICAgKiBAcGFyYW0gY29uZmlnIHRoZSBjb25maWcgb2JqZWN0IHRvIGluZGljYXRlIHRoZSBsb2dnZXIncyBiZWhhdmlvclxuICAgKi9cbiAgc2V0KGNhdGVnb3J5OiBzdHJpbmcsIGNvbmZpZzogTG9nZ2VyLkNvbmZpZyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgbG9nZ2VyJ3MgYmVoYXZpb3IgZnJvbSBvcnQtY29tbW9uIGVudlxuICAgKiBAcGFyYW0gZW52IHRoZSBlbnYgdXNlZCB0byBzZXQgbG9nZ2VyLiBDdXJyZW50bHkgb25seSBzZXR0aW5nIGxvZ2xldmVsIGlzIHN1cHBvcnRlZCB0aHJvdWdoIEVudi5cbiAgICovXG4gIHNldFdpdGhFbnYoZW52OiBFbnYpOiB2b2lkO1xufVxuXG5pbnRlcmZhY2UgTG9nZ2VyUHJvdmlkZXIge1xuICBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgY29udGVudDogc3RyaW5nLCBjYXRlZ29yeT86IHN0cmluZyk6IHZvaWQ7XG59XG5jbGFzcyBOb09wTG9nZ2VyUHJvdmlkZXIgaW1wbGVtZW50cyBMb2dnZXJQcm92aWRlciB7XG4gIGxvZyhfc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgX2NvbnRlbnQ6IHN0cmluZywgX2NhdGVnb3J5Pzogc3RyaW5nKSB7XG4gICAgLy8gZG8gbm90aGluZ1xuICB9XG59XG5jbGFzcyBDb25zb2xlTG9nZ2VyUHJvdmlkZXIgaW1wbGVtZW50cyBMb2dnZXJQcm92aWRlciB7XG4gIGxvZyhzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjb250ZW50OiBzdHJpbmcsIGNhdGVnb3J5Pzogc3RyaW5nKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBjb25zb2xlLmxvZyhgJHt0aGlzLmNvbG9yKHNldmVyaXR5KX0gJHtjYXRlZ29yeSA/ICdcXHgxYlszNW0nICsgY2F0ZWdvcnkgKyAnXFx4MWJbMG0gJyA6ICcnfSR7Y29udGVudH1gKTtcbiAgfVxuXG4gIHByaXZhdGUgY29sb3Ioc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSkge1xuICAgIHN3aXRjaCAoc2V2ZXJpdHkpIHtcbiAgICAgIGNhc2UgJ3ZlcmJvc2UnOlxuICAgICAgICByZXR1cm4gJ1xceDFiWzM0OzQwbXZcXHgxYlswbSc7XG4gICAgICBjYXNlICdpbmZvJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlszMm1pXFx4MWJbMG0nO1xuICAgICAgY2FzZSAnd2FybmluZyc6XG4gICAgICAgIHJldHVybiAnXFx4MWJbMzA7NDNtd1xceDFiWzBtJztcbiAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlszMTs0MG1lXFx4MWJbMG0nO1xuICAgICAgY2FzZSAnZmF0YWwnOlxuICAgICAgICByZXR1cm4gJ1xceDFiWzEwMW1mXFx4MWJbMG0nO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBzZXZlcml0eTogJHtzZXZlcml0eX1gKTtcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgU0VWRVJJVFlfVkFMVUUgPSB7XG4gIHZlcmJvc2U6IDEwMDAsXG4gIGluZm86IDIwMDAsXG4gIHdhcm5pbmc6IDQwMDAsXG4gIGVycm9yOiA1MDAwLFxuICBmYXRhbDogNjAwMCxcbn07XG5cbmNvbnN0IExPR0dFUl9QUk9WSURFUl9NQVA6IHsgcmVhZG9ubHkgW3Byb3ZpZGVyOiBzdHJpbmddOiBSZWFkb25seTxMb2dnZXJQcm92aWRlcj4gfSA9IHtcbiAgWydub25lJ106IG5ldyBOb09wTG9nZ2VyUHJvdmlkZXIoKSxcbiAgWydjb25zb2xlJ106IG5ldyBDb25zb2xlTG9nZ2VyUHJvdmlkZXIoKSxcbn07XG5jb25zdCBMT0dHRVJfREVGQVVMVF9DT05GSUcgPSB7XG4gIHByb3ZpZGVyOiAnY29uc29sZScsXG4gIG1pbmltYWxTZXZlcml0eTogJ3dhcm5pbmcnLFxuICBsb2dEYXRlVGltZTogdHJ1ZSxcbiAgbG9nU291cmNlTG9jYXRpb246IGZhbHNlLFxufTtcbmxldCBMT0dHRVJfQ09ORklHX01BUDogeyBbY2F0ZWdvcnk6IHN0cmluZ106IFJlYWRvbmx5PFJlcXVpcmVkPExvZ2dlci5Db25maWc+PiB9ID0ge1xuICBbJyddOiBMT0dHRVJfREVGQVVMVF9DT05GSUcgYXMgUmVxdWlyZWQ8TG9nZ2VyLkNvbmZpZz4sXG59O1xuXG5mdW5jdGlvbiBsb2coY2F0ZWdvcnk6IHN0cmluZyk6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlcjtcbmZ1bmN0aW9uIGxvZyhzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuZnVuY3Rpb24gbG9nKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG5mdW5jdGlvbiBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgYXJnMTogc3RyaW5nLCBhcmcyPzogc3RyaW5nKTogdm9pZDtcbmZ1bmN0aW9uIGxvZyhcbiAgYXJnMDogc3RyaW5nIHwgTG9nZ2VyLlNldmVyaXR5LFxuICBhcmcxPzogc3RyaW5nLFxuICBhcmcyPzogc3RyaW5nIHwgbnVtYmVyLFxuICBhcmczPzogbnVtYmVyLFxuKTogTG9nZ2VyLkNhdGVnb3JpemVkTG9nZ2VyIHwgdm9pZCB7XG4gIGlmIChhcmcxID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBsb2coY2F0ZWdvcnk6IHN0cmluZyk6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlcjtcbiAgICByZXR1cm4gY3JlYXRlQ2F0ZWdvcml6ZWRMb2dnZXIoYXJnMCk7XG4gIH0gZWxzZSBpZiAoYXJnMiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gbG9nKHNldmVyaXR5LCBjb250ZW50KTtcbiAgICBsb2dJbnRlcm5hbChhcmcwIGFzIExvZ2dlci5TZXZlcml0eSwgYXJnMSwgMSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgPT09ICdudW1iZXInICYmIGFyZzMgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGxvZyhzZXZlcml0eSwgY29udGVudCwgc3RhY2spXG4gICAgbG9nSW50ZXJuYWwoYXJnMCBhcyBMb2dnZXIuU2V2ZXJpdHksIGFyZzEsIGFyZzIpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyID09PSAnc3RyaW5nJyAmJiBhcmczID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBsb2coc2V2ZXJpdHksIGNhdGVnb3J5LCBjb250ZW50KVxuICAgIGxvZ0ludGVybmFsKGFyZzAgYXMgTG9nZ2VyLlNldmVyaXR5LCBhcmcyLCAxLCBhcmcxKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiA9PT0gJ3N0cmluZycgJiYgdHlwZW9mIGFyZzMgPT09ICdudW1iZXInKSB7XG4gICAgLy8gbG9nKHNldmVyaXR5LCBjYXRlZ29yeSwgY29udGVudCwgc3RhY2spXG4gICAgbG9nSW50ZXJuYWwoYXJnMCBhcyBMb2dnZXIuU2V2ZXJpdHksIGFyZzIsIGFyZzMsIGFyZzEpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2lucHV0IGlzIHZhbGlkJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2F0ZWdvcml6ZWRMb2dnZXIoY2F0ZWdvcnk6IHN0cmluZyk6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlciB7XG4gIHJldHVybiB7XG4gICAgdmVyYm9zZTogbG9nLnZlcmJvc2UuYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgaW5mbzogbG9nLmluZm8uYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgd2FybmluZzogbG9nLndhcm5pbmcuYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgZXJyb3I6IGxvZy5lcnJvci5iaW5kKG51bGwsIGNhdGVnb3J5KSxcbiAgICBmYXRhbDogbG9nLmZhdGFsLmJpbmQobnVsbCwgY2F0ZWdvcnkpLFxuICB9O1xufVxuXG4vLyBOT1RFOiBhcmd1bWVudCAnY2F0ZWdvcnknIGlzIHB1dCB0aGUgbGFzdCBwYXJhbWV0ZXIgYmVjYXVzZSB0eXBlc2NyaXB0XG4vLyBkb2Vzbid0IGFsbG93IG9wdGlvbmFsIGFyZ3VtZW50IHB1dCBpbiBmcm9udCBvZiByZXF1aXJlZCBhcmd1bWVudC4gVGhpc1xuLy8gb3JkZXIgaXMgZGlmZmVyZW50IGZyb20gYSB1c3VhbCBsb2dnaW5nIEFQSS5cbmZ1bmN0aW9uIGxvZ0ludGVybmFsKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGNvbnRlbnQ6IHN0cmluZywgX3N0YWNrOiBudW1iZXIsIGNhdGVnb3J5Pzogc3RyaW5nKSB7XG4gIGNvbnN0IGNvbmZpZyA9IExPR0dFUl9DT05GSUdfTUFQW2NhdGVnb3J5IHx8ICcnXSB8fCBMT0dHRVJfQ09ORklHX01BUFsnJ107XG4gIGlmIChTRVZFUklUWV9WQUxVRVtzZXZlcml0eV0gPCBTRVZFUklUWV9WQUxVRVtjb25maWcubWluaW1hbFNldmVyaXR5XSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChjb25maWcubG9nRGF0ZVRpbWUpIHtcbiAgICBjb250ZW50ID0gYCR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfXwke2NvbnRlbnR9YDtcbiAgfVxuXG4gIGlmIChjb25maWcubG9nU291cmNlTG9jYXRpb24pIHtcbiAgICAvLyBUT0RPOiBjYWxjdWxhdGUgc291cmNlIGxvY2F0aW9uIGZyb20gJ3N0YWNrJ1xuICB9XG5cbiAgTE9HR0VSX1BST1ZJREVSX01BUFtjb25maWcucHJvdmlkZXJdLmxvZyhzZXZlcml0eSwgY29udGVudCwgY2F0ZWdvcnkpO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5hbWVzcGFjZVxubmFtZXNwYWNlIGxvZyB7XG4gIGV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygndmVyYm9zZScsIGFyZzAsIGFyZzEpO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiBpbmZvKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBpbmZvKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBpbmZvKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygnaW5mbycsIGFyZzAsIGFyZzEpO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiB3YXJuaW5nKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiB3YXJuaW5nKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiB3YXJuaW5nKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygnd2FybmluZycsIGFyZzAsIGFyZzEpO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiBlcnJvcihjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gZXJyb3IoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIGVycm9yKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygnZXJyb3InLCBhcmcwLCBhcmcxKTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gZmF0YWwoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIGZhdGFsKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBmYXRhbChhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ2ZhdGFsJywgYXJnMCwgYXJnMSk7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gcmVzZXQoY29uZmlnPzogTG9nZ2VyLkNvbmZpZyk6IHZvaWQge1xuICAgIExPR0dFUl9DT05GSUdfTUFQID0ge307XG4gICAgc2V0KCcnLCBjb25maWcgfHwge30pO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiBzZXQoY2F0ZWdvcnk6IHN0cmluZywgY29uZmlnOiBMb2dnZXIuQ29uZmlnKTogdm9pZCB7XG4gICAgaWYgKGNhdGVnb3J5ID09PSAnKicpIHtcbiAgICAgIHJlc2V0KGNvbmZpZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHByZXZpb3VzQ29uZmlnID0gTE9HR0VSX0NPTkZJR19NQVBbY2F0ZWdvcnldIHx8IExPR0dFUl9ERUZBVUxUX0NPTkZJRztcbiAgICAgIExPR0dFUl9DT05GSUdfTUFQW2NhdGVnb3J5XSA9IHtcbiAgICAgICAgcHJvdmlkZXI6IGNvbmZpZy5wcm92aWRlciB8fCBwcmV2aW91c0NvbmZpZy5wcm92aWRlcixcbiAgICAgICAgbWluaW1hbFNldmVyaXR5OiBjb25maWcubWluaW1hbFNldmVyaXR5IHx8IHByZXZpb3VzQ29uZmlnLm1pbmltYWxTZXZlcml0eSxcbiAgICAgICAgbG9nRGF0ZVRpbWU6IGNvbmZpZy5sb2dEYXRlVGltZSA9PT0gdW5kZWZpbmVkID8gcHJldmlvdXNDb25maWcubG9nRGF0ZVRpbWUgOiBjb25maWcubG9nRGF0ZVRpbWUsXG4gICAgICAgIGxvZ1NvdXJjZUxvY2F0aW9uOlxuICAgICAgICAgIGNvbmZpZy5sb2dTb3VyY2VMb2NhdGlvbiA9PT0gdW5kZWZpbmVkID8gcHJldmlvdXNDb25maWcubG9nU291cmNlTG9jYXRpb24gOiBjb25maWcubG9nU291cmNlTG9jYXRpb24sXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFRPRE86IHdlIHdhbnQgdG8gc3VwcG9ydCB3aWxkY2FyZCBvciByZWdleD9cbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBzZXRXaXRoRW52KGVudjogRW52KTogdm9pZCB7XG4gICAgY29uc3QgY29uZmlnOiBMb2dnZXIuQ29uZmlnID0ge307XG4gICAgaWYgKGVudi5sb2dMZXZlbCkge1xuICAgICAgY29uZmlnLm1pbmltYWxTZXZlcml0eSA9IGVudi5sb2dMZXZlbCBhcyBMb2dnZXIuU2V2ZXJpdHk7XG4gICAgfVxuICAgIHNldCgnJywgY29uZmlnKTtcbiAgfVxufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZSwgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG5leHBvcnQgY29uc3QgTG9nZ2VyOiBMb2dnZXIgPSBsb2c7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBQcm9maWxlciB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnIHtcbiAgICBtYXhOdW1iZXJFdmVudHM/OiBudW1iZXI7XG4gICAgZmx1c2hCYXRjaFNpemU/OiBudW1iZXI7XG4gICAgZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzPzogbnVtYmVyO1xuICB9XG5cbiAgZXhwb3J0IHR5cGUgRXZlbnRDYXRlZ29yeSA9ICdzZXNzaW9uJyB8ICdub2RlJyB8ICdvcCcgfCAnYmFja2VuZCc7XG5cbiAgZXhwb3J0IGludGVyZmFjZSBFdmVudCB7XG4gICAgZW5kKCk6IHZvaWQgfCBQcm9taXNlPHZvaWQ+O1xuICB9XG59XG4vLyBUT0RPXG4vLyBjbGFzcyBXZWJHTEV2ZW50IGltcGxlbWVudHMgUHJvZmlsZXIuRXZlbnQge31cblxuY2xhc3MgRXZlbnQgaW1wbGVtZW50cyBQcm9maWxlci5FdmVudCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSxcbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nLFxuICAgIHB1YmxpYyBzdGFydFRpbWU6IG51bWJlcixcbiAgICBwcml2YXRlIGVuZENhbGxiYWNrOiAoZTogRXZlbnQpID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+LFxuICAgIHB1YmxpYyB0aW1lcj86IFdlYkdMUXVlcnksXG4gICAgcHVibGljIGN0eD86IFdlYkdMQ29udGV4dCxcbiAgKSB7fVxuXG4gIGFzeW5jIGVuZCgpIHtcbiAgICByZXR1cm4gdGhpcy5lbmRDYWxsYmFjayh0aGlzKTtcbiAgfVxuXG4gIGFzeW5jIGNoZWNrVGltZXIoKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBpZiAodGhpcy5jdHggPT09IHVuZGVmaW5lZCB8fCB0aGlzLnRpbWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gd2ViZ2wgdGltZXIgZm91bmQnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jdHguZW5kVGltZXIoKTtcbiAgICAgIHJldHVybiB0aGlzLmN0eC53YWl0Rm9yUXVlcnlBbmRHZXRUaW1lKHRoaXMudGltZXIpO1xuICAgIH1cbiAgfVxufVxuXG5jbGFzcyBFdmVudFJlY29yZCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSxcbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nLFxuICAgIHB1YmxpYyBzdGFydFRpbWU6IG51bWJlcixcbiAgICBwdWJsaWMgZW5kVGltZTogbnVtYmVyLFxuICApIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBQcm9maWxlciB7XG4gIHN0YXRpYyBjcmVhdGUoY29uZmlnPzogUHJvZmlsZXIuQ29uZmlnKTogUHJvZmlsZXIge1xuICAgIGlmIChjb25maWcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIG5ldyB0aGlzKCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgdGhpcyhjb25maWcubWF4TnVtYmVyRXZlbnRzLCBjb25maWcuZmx1c2hCYXRjaFNpemUsIGNvbmZpZy5mbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihtYXhOdW1iZXJFdmVudHM/OiBudW1iZXIsIGZsdXNoQmF0Y2hTaXplPzogbnVtYmVyLCBmbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHM/OiBudW1iZXIpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2U7XG4gICAgdGhpcy5fbWF4TnVtYmVyRXZlbnRzID0gbWF4TnVtYmVyRXZlbnRzID09PSB1bmRlZmluZWQgPyAxMDAwMCA6IG1heE51bWJlckV2ZW50cztcbiAgICB0aGlzLl9mbHVzaEJhdGNoU2l6ZSA9IGZsdXNoQmF0Y2hTaXplID09PSB1bmRlZmluZWQgPyAxMCA6IGZsdXNoQmF0Y2hTaXplO1xuICAgIHRoaXMuX2ZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcyA9IGZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcyA9PT0gdW5kZWZpbmVkID8gNTAwMCA6IGZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcztcbiAgfVxuXG4gIC8vIHN0YXJ0IHByb2ZpbGluZ1xuICBzdGFydCgpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gdHJ1ZTtcbiAgICB0aGlzLl90aW1pbmdFdmVudHMgPSBbXTtcbiAgICB0aGlzLl9mbHVzaFRpbWUgPSBub3coKTtcbiAgICB0aGlzLl9mbHVzaFBvaW50ZXIgPSAwO1xuICB9XG5cbiAgLy8gc3RvcCBwcm9maWxpbmdcbiAgc3RvcCgpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2U7XG4gICAgZm9yICg7IHRoaXMuX2ZsdXNoUG9pbnRlciA8IHRoaXMuX3RpbWluZ0V2ZW50cy5sZW5ndGg7IHRoaXMuX2ZsdXNoUG9pbnRlcisrKSB7XG4gICAgICB0aGlzLmxvZ09uZUV2ZW50KHRoaXMuX3RpbWluZ0V2ZW50c1t0aGlzLl9mbHVzaFBvaW50ZXJdKTtcbiAgICB9XG4gIH1cblxuICAvLyBjcmVhdGUgYW4gZXZlbnQgc2NvcGUgZm9yIHRoZSBzcGVjaWZpYyBmdW5jdGlvblxuICBldmVudDxUPihjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSwgbmFtZTogc3RyaW5nLCBmdW5jOiAoKSA9PiBULCBjdHg/OiBXZWJHTENvbnRleHQpOiBUO1xuICBldmVudDxUPihjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSwgbmFtZTogc3RyaW5nLCBmdW5jOiAoKSA9PiBQcm9taXNlPFQ+LCBjdHg/OiBXZWJHTENvbnRleHQpOiBQcm9taXNlPFQ+O1xuXG4gIGV2ZW50PFQ+KFxuICAgIGNhdGVnb3J5OiBQcm9maWxlci5FdmVudENhdGVnb3J5LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBmdW5jOiAoKSA9PiBUIHwgUHJvbWlzZTxUPixcbiAgICBjdHg/OiBXZWJHTENvbnRleHQsXG4gICk6IFQgfCBQcm9taXNlPFQ+IHtcbiAgICBjb25zdCBldmVudCA9IHRoaXMuX3N0YXJ0ZWQgPyB0aGlzLmJlZ2luKGNhdGVnb3J5LCBuYW1lLCBjdHgpIDogdW5kZWZpbmVkO1xuICAgIGxldCBpc1Byb21pc2UgPSBmYWxzZTtcblxuICAgIGNvbnN0IHJlcyA9IGZ1bmMoKTtcblxuICAgIC8vIHdlIGNvbnNpZGVyIGEgdGhlbi1hYmxlIG9iamVjdCBpcyBhIHByb21pc2VcbiAgICBpZiAocmVzICYmIHR5cGVvZiAocmVzIGFzIFByb21pc2U8VD4pLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlzUHJvbWlzZSA9IHRydWU7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2U8VD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAocmVzIGFzIFByb21pc2U8VD4pLnRoZW4oXG4gICAgICAgICAgYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAvLyBmdWxmaWxsZWRcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICBhd2FpdCBldmVudC5lbmQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmUodmFsdWUpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgYXN5bmMgKHJlYXNvbikgPT4ge1xuICAgICAgICAgICAgLy8gcmVqZWN0ZWRcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICBhd2FpdCBldmVudC5lbmQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlamVjdChyZWFzb24pO1xuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKCFpc1Byb21pc2UgJiYgZXZlbnQpIHtcbiAgICAgIGNvbnN0IGV2ZW50UmVzID0gZXZlbnQuZW5kKCk7XG4gICAgICBpZiAoZXZlbnRSZXMgJiYgdHlwZW9mIGV2ZW50UmVzLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICBldmVudFJlcy50aGVuKFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAvLyBmdWxmaWxsZWRcbiAgICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChyZWFzb24pID0+IHtcbiAgICAgICAgICAgICAgLy8gcmVqZWN0ZWRcbiAgICAgICAgICAgICAgcmVqZWN0KHJlYXNvbik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgLy8gYmVnaW4gYW4gZXZlbnRcbiAgYmVnaW4oY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksIG5hbWU6IHN0cmluZywgY3R4PzogV2ViR0xDb250ZXh0KTogRXZlbnQge1xuICAgIGlmICghdGhpcy5fc3RhcnRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdwcm9maWxlciBpcyBub3Qgc3RhcnRlZCB5ZXQnKTtcbiAgICB9XG4gICAgaWYgKGN0eCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBzdGFydFRpbWUgPSBub3coKTtcbiAgICAgIHRoaXMuZmx1c2goc3RhcnRUaW1lKTtcbiAgICAgIHJldHVybiBuZXcgRXZlbnQoY2F0ZWdvcnksIG5hbWUsIHN0YXJ0VGltZSwgKGUpID0+IHRoaXMuZW5kU3luYyhlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRpbWVyOiBXZWJHTFF1ZXJ5ID0gY3R4LmJlZ2luVGltZXIoKTtcbiAgICAgIHJldHVybiBuZXcgRXZlbnQoY2F0ZWdvcnksIG5hbWUsIDAsIGFzeW5jIChlKSA9PiB0aGlzLmVuZChlKSwgdGltZXIsIGN0eCk7XG4gICAgfVxuICB9XG5cbiAgLy8gZW5kIHRoZSBzcGVjaWZpYyBldmVudFxuICBwcml2YXRlIGFzeW5jIGVuZChldmVudDogRXZlbnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBlbmRUaW1lOiBudW1iZXIgPSBhd2FpdCBldmVudC5jaGVja1RpbWVyKCk7XG4gICAgaWYgKHRoaXMuX3RpbWluZ0V2ZW50cy5sZW5ndGggPCB0aGlzLl9tYXhOdW1iZXJFdmVudHMpIHtcbiAgICAgIHRoaXMuX3RpbWluZ0V2ZW50cy5wdXNoKG5ldyBFdmVudFJlY29yZChldmVudC5jYXRlZ29yeSwgZXZlbnQubmFtZSwgZXZlbnQuc3RhcnRUaW1lLCBlbmRUaW1lKSk7XG4gICAgICB0aGlzLmZsdXNoKGVuZFRpbWUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZW5kU3luYyhldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBlbmRUaW1lOiBudW1iZXIgPSBub3coKTtcbiAgICBpZiAodGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aCA8IHRoaXMuX21heE51bWJlckV2ZW50cykge1xuICAgICAgdGhpcy5fdGltaW5nRXZlbnRzLnB1c2gobmV3IEV2ZW50UmVjb3JkKGV2ZW50LmNhdGVnb3J5LCBldmVudC5uYW1lLCBldmVudC5zdGFydFRpbWUsIGVuZFRpbWUpKTtcbiAgICAgIHRoaXMuZmx1c2goZW5kVGltZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBsb2dPbmVFdmVudChldmVudDogRXZlbnRSZWNvcmQpIHtcbiAgICBMb2dnZXIudmVyYm9zZShcbiAgICAgIGBQcm9maWxlci4ke2V2ZW50LmNhdGVnb3J5fWAsXG4gICAgICBgJHsoZXZlbnQuZW5kVGltZSAtIGV2ZW50LnN0YXJ0VGltZSkudG9GaXhlZCgyKX1tcyBvbiBldmVudCAnJHtldmVudC5uYW1lfScgYXQgJHtldmVudC5lbmRUaW1lLnRvRml4ZWQoMil9YCxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBmbHVzaChjdXJyZW50VGltZTogbnVtYmVyKSB7XG4gICAgaWYgKFxuICAgICAgdGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aCAtIHRoaXMuX2ZsdXNoUG9pbnRlciA+PSB0aGlzLl9mbHVzaEJhdGNoU2l6ZSB8fFxuICAgICAgY3VycmVudFRpbWUgLSB0aGlzLl9mbHVzaFRpbWUgPj0gdGhpcy5fZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzXG4gICAgKSB7XG4gICAgICAvLyBzaG91bGQgZmx1c2ggd2hlbiBlaXRoZXIgYmF0Y2ggc2l6ZSBhY2N1bXVsYXRlZCBvciBpbnRlcnZhbCBlbGVwc2VkXG5cbiAgICAgIGZvciAoXG4gICAgICAgIGNvbnN0IHByZXZpb3VzUG9pbnRlciA9IHRoaXMuX2ZsdXNoUG9pbnRlcjtcbiAgICAgICAgdGhpcy5fZmx1c2hQb2ludGVyIDwgcHJldmlvdXNQb2ludGVyICsgdGhpcy5fZmx1c2hCYXRjaFNpemUgJiYgdGhpcy5fZmx1c2hQb2ludGVyIDwgdGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5fZmx1c2hQb2ludGVyKytcbiAgICAgICkge1xuICAgICAgICB0aGlzLmxvZ09uZUV2ZW50KHRoaXMuX3RpbWluZ0V2ZW50c1t0aGlzLl9mbHVzaFBvaW50ZXJdKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fZmx1c2hUaW1lID0gbm93KCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHN0YXJ0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXJ0ZWQ7XG4gIH1cbiAgcHJpdmF0ZSBfc3RhcnRlZCA9IGZhbHNlO1xuICBwcml2YXRlIF90aW1pbmdFdmVudHM6IEV2ZW50UmVjb3JkW107XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfbWF4TnVtYmVyRXZlbnRzOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZmx1c2hCYXRjaFNpemU6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBfZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSBfZmx1c2hUaW1lOiBudW1iZXI7XG4gIHByaXZhdGUgX2ZsdXNoUG9pbnRlciA9IDA7XG59XG5cbi8qKlxuICogcmV0dXJucyBhIG51bWJlciB0byByZXByZXNlbnQgdGhlIGN1cnJlbnQgdGltZXN0YW1wIGluIGEgcmVzb2x1dGlvbiBhcyBoaWdoIGFzIHBvc3NpYmxlLlxuICovXG5leHBvcnQgY29uc3Qgbm93ID0gdHlwZW9mIHBlcmZvcm1hbmNlICE9PSAndW5kZWZpbmVkJyAmJiBwZXJmb3JtYW5jZS5ub3cgPyAoKSA9PiBwZXJmb3JtYW5jZS5ub3coKSA6IERhdGUubm93O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4vb3BlcmF0b3JzJztcblxuZXhwb3J0IGludGVyZmFjZSBPcFNldCB7XG4gIGRvbWFpbjogc3RyaW5nO1xuICB2ZXJzaW9uOiBudW1iZXI7XG59XG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgT3BTZXQge1xuICAvKipcbiAgICogRG9tYWluIG9mIGFuIG9wc2V0LCBpdCBjYW4gYmUgYW4gZW1wdHkgc3RyaW5nKGRlZmF1bHQgdmFsdWUsIHJlcHJlc2VudCBmb3IgYWkub25ueCksIG9yICdhaS5vbm54Lm1sJ1xuICAgKi9cbiAgdHlwZSBEb21haW4gPSAnJyB8ICdhaS5vbm54Lm1sJyB8ICdjb20ubWljcm9zb2Z0JztcbiAgLyoqXG4gICAqIEEgcmVzb2x2ZSBydWxlIGNvbnNpc3RzIG9mIDQgb3IgNSBpdGVtczogb3BUeXBlLCBvcFNldERvbWFpbiwgdmVyc2lvblNlbGVjdG9yLCBvcGVyYXRvckltcGxlbWVudGF0aW9uIGFuZFxuICAgKiBvcGVyYXRvckluaXRpYWxpemF0aW9uIChvcHRpb25hbClcbiAgICovXG4gIHR5cGUgUmVzb2x2ZVJ1bGUgPVxuICAgIHwgW3N0cmluZywgRG9tYWluLCBzdHJpbmcsIE9wZXJhdG9ySW1wbGVtZW50YXRpb248R3JhcGguTm9kZT5dXG4gICAgfCBbc3RyaW5nLCBEb21haW4sIHN0cmluZywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjx1bmtub3duPiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbjx1bmtub3duPl07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlT3BlcmF0b3Iobm9kZTogR3JhcGguTm9kZSwgb3BzZXRzOiByZWFkb25seSBPcFNldFtdLCBydWxlczogcmVhZG9ubHkgT3BTZXQuUmVzb2x2ZVJ1bGVbXSkge1xuICBmb3IgKGNvbnN0IHJ1bGUgb2YgcnVsZXMpIHtcbiAgICBjb25zdCBvcFR5cGUgPSBydWxlWzBdO1xuICAgIGNvbnN0IGRvbWFpbiA9IHJ1bGVbMV07XG4gICAgY29uc3QgdmVyc2lvblNlbGVjdG9yID0gcnVsZVsyXTtcbiAgICBjb25zdCBvcEltcGwgPSBydWxlWzNdO1xuICAgIGNvbnN0IG9wSW5pdCA9IHJ1bGVbNF07XG5cbiAgICBpZiAobm9kZS5vcFR5cGUgPT09IG9wVHlwZSkge1xuICAgICAgLy8gb3BlcmF0b3IgdHlwZSBtYXRjaGVzXG4gICAgICBmb3IgKGNvbnN0IG9wc2V0IG9mIG9wc2V0cykge1xuICAgICAgICAvLyBvcHNldCAnJyBhbmQgJ2FpLm9ubngnIGFyZSBjb25zaWRlcmVkIHRoZSBzYW1lLlxuICAgICAgICBpZiAob3BzZXQuZG9tYWluID09PSBkb21haW4gfHwgKG9wc2V0LmRvbWFpbiA9PT0gJ2FpLm9ubngnICYmIGRvbWFpbiA9PT0gJycpKSB7XG4gICAgICAgICAgLy8gb3BzZXQgZG9tYWluIGZvdW5kXG4gICAgICAgICAgaWYgKG1hdGNoU2VsZWN0b3Iob3BzZXQudmVyc2lvbiwgdmVyc2lvblNlbGVjdG9yKSkge1xuICAgICAgICAgICAgcmV0dXJuIHsgb3BJbXBsLCBvcEluaXQgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgIGBjYW5ub3QgcmVzb2x2ZSBvcGVyYXRvciAnJHtub2RlLm9wVHlwZX0nIHdpdGggb3BzZXRzOiAke29wc2V0c1xuICAgICAgLm1hcCgoc2V0KSA9PiBgJHtzZXQuZG9tYWluIHx8ICdhaS5vbm54J30gdiR7c2V0LnZlcnNpb259YClcbiAgICAgIC5qb2luKCcsICcpfWAsXG4gICk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoU2VsZWN0b3IodmVyc2lvbjogbnVtYmVyLCBzZWxlY3Rvcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChzZWxlY3Rvci5lbmRzV2l0aCgnKycpKSB7XG4gICAgLy8gbWluaW11bSB2ZXJzaW9uIG1hdGNoICgnNysnIGV4cGVjdHMgdmVyc2lvbj49NylcbiAgICBjb25zdCByYW5nZVN0YXJ0ID0gTnVtYmVyLnBhcnNlSW50KHNlbGVjdG9yLnN1YnN0cmluZygwLCBzZWxlY3Rvci5sZW5ndGggLSAxKSwgMTApO1xuICAgIHJldHVybiAhaXNOYU4ocmFuZ2VTdGFydCkgJiYgcmFuZ2VTdGFydCA8PSB2ZXJzaW9uO1xuICB9IGVsc2UgaWYgKHNlbGVjdG9yLnNwbGl0KCctJykubGVuZ3RoID09PSAyKSB7XG4gICAgLy8gcmFuZ2UgbWF0Y2ggKCc2LTgnIGV4cGVjdHMgNjw9dmVyc2lvbjw9OClcbiAgICBjb25zdCBwYWlyID0gc2VsZWN0b3Iuc3BsaXQoJy0nKTtcbiAgICBjb25zdCByYW5nZVN0YXJ0ID0gTnVtYmVyLnBhcnNlSW50KHBhaXJbMF0sIDEwKTtcbiAgICBjb25zdCByYW5nZUVuZCA9IE51bWJlci5wYXJzZUludChwYWlyWzFdLCAxMCk7XG4gICAgcmV0dXJuICFpc05hTihyYW5nZVN0YXJ0KSAmJiAhaXNOYU4ocmFuZ2VFbmQpICYmIHJhbmdlU3RhcnQgPD0gdmVyc2lvbiAmJiB2ZXJzaW9uIDw9IHJhbmdlRW5kO1xuICB9IGVsc2Uge1xuICAgIC8vIGV4YWN0IG1hdGNoICgnNycgZXhwZWN0cyB2ZXJzaW9uPT09NylcbiAgICByZXR1cm4gTnVtYmVyLnBhcnNlSW50KHNlbGVjdG9yLCAxMCkgPT09IHZlcnNpb247XG4gIH1cbn1cbiIsICJcInVzZSBzdHJpY3RcIjtcclxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcclxudmFyIEd1aWQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBHdWlkKGd1aWQpIHtcclxuICAgICAgICBpZiAoIWd1aWQpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXJndW1lbnQ7IGB2YWx1ZWAgaGFzIG5vIHZhbHVlLlwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52YWx1ZSA9IEd1aWQuRU1QVFk7XHJcbiAgICAgICAgaWYgKGd1aWQgJiYgR3VpZC5pc0d1aWQoZ3VpZCkpIHtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IGd1aWQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgR3VpZC5pc0d1aWQgPSBmdW5jdGlvbiAoZ3VpZCkge1xyXG4gICAgICAgIHZhciB2YWx1ZSA9IGd1aWQudG9TdHJpbmcoKTtcclxuICAgICAgICByZXR1cm4gZ3VpZCAmJiAoZ3VpZCBpbnN0YW5jZW9mIEd1aWQgfHwgR3VpZC52YWxpZGF0b3IudGVzdCh2YWx1ZSkpO1xyXG4gICAgfTtcclxuICAgIEd1aWQuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgR3VpZChbR3VpZC5nZW4oMiksIEd1aWQuZ2VuKDEpLCBHdWlkLmdlbigxKSwgR3VpZC5nZW4oMSksIEd1aWQuZ2VuKDMpXS5qb2luKFwiLVwiKSk7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5jcmVhdGVFbXB0eSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEd1aWQoXCJlbXB0eWd1aWRcIik7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5wYXJzZSA9IGZ1bmN0aW9uIChndWlkKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBHdWlkKGd1aWQpO1xyXG4gICAgfTtcclxuICAgIEd1aWQucmF3ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBbR3VpZC5nZW4oMiksIEd1aWQuZ2VuKDEpLCBHdWlkLmdlbigxKSwgR3VpZC5nZW4oMSksIEd1aWQuZ2VuKDMpXS5qb2luKFwiLVwiKTtcclxuICAgIH07XHJcbiAgICBHdWlkLmdlbiA9IGZ1bmN0aW9uIChjb3VudCkge1xyXG4gICAgICAgIHZhciBvdXQgPSBcIlwiO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xyXG4gICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYml0d2lzZVxyXG4gICAgICAgICAgICBvdXQgKz0gKCgoMSArIE1hdGgucmFuZG9tKCkpICogMHgxMDAwMCkgfCAwKS50b1N0cmluZygxNikuc3Vic3RyaW5nKDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb3V0O1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xyXG4gICAgICAgIC8vIENvbXBhcmluZyBzdHJpbmcgYHZhbHVlYCBhZ2FpbnN0IHByb3ZpZGVkIGBndWlkYCB3aWxsIGF1dG8tY2FsbFxyXG4gICAgICAgIC8vIHRvU3RyaW5nIG9uIGBndWlkYCBmb3IgY29tcGFyaXNvblxyXG4gICAgICAgIHJldHVybiBHdWlkLmlzR3VpZChvdGhlcikgJiYgdGhpcy52YWx1ZSA9PT0gb3RoZXIudG9TdHJpbmcoKTtcclxuICAgIH07XHJcbiAgICBHdWlkLnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlID09PSBHdWlkLkVNUFRZO1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZVxyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG4gICAgR3VpZC52YWxpZGF0b3IgPSBuZXcgUmVnRXhwKFwiXlthLXowLTldezh9LVthLXowLTldezR9LVthLXowLTldezR9LVthLXowLTldezR9LVthLXowLTldezEyfSRcIiwgXCJpXCIpO1xyXG4gICAgR3VpZC5FTVBUWSA9IFwiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCI7XHJcbiAgICByZXR1cm4gR3VpZDtcclxufSgpKTtcclxuZXhwb3J0cy5HdWlkID0gR3VpZDtcclxuIiwgIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDA5IFRoZSBDbG9zdXJlIExpYnJhcnkgQXV0aG9yc1xuICogQ29weXJpZ2h0IDIwMjAgRGFuaWVsIFdpcnR6IC8gVGhlIGxvbmcuanMgQXV0aG9ycy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuXG4vLyBXZWJBc3NlbWJseSBvcHRpbWl6YXRpb25zIHRvIGRvIG5hdGl2ZSBpNjQgbXVsdGlwbGljYXRpb24gYW5kIGRpdmlkZVxudmFyIHdhc20gPSBudWxsO1xudHJ5IHtcbiAgd2FzbSA9IG5ldyBXZWJBc3NlbWJseS5JbnN0YW5jZShuZXcgV2ViQXNzZW1ibHkuTW9kdWxlKG5ldyBVaW50OEFycmF5KFtcbiAgICAwLCA5NywgMTE1LCAxMDksIDEsIDAsIDAsIDAsIDEsIDEzLCAyLCA5NiwgMCwgMSwgMTI3LCA5NiwgNCwgMTI3LCAxMjcsIDEyNywgMTI3LCAxLCAxMjcsIDMsIDcsIDYsIDAsIDEsIDEsIDEsIDEsIDEsIDYsIDYsIDEsIDEyNywgMSwgNjUsIDAsIDExLCA3LCA1MCwgNiwgMywgMTA5LCAxMTcsIDEwOCwgMCwgMSwgNSwgMTAwLCAxMDUsIDExOCwgOTUsIDExNSwgMCwgMiwgNSwgMTAwLCAxMDUsIDExOCwgOTUsIDExNywgMCwgMywgNSwgMTE0LCAxMDEsIDEwOSwgOTUsIDExNSwgMCwgNCwgNSwgMTE0LCAxMDEsIDEwOSwgOTUsIDExNywgMCwgNSwgOCwgMTAzLCAxMDEsIDExNiwgOTUsIDEwNCwgMTA1LCAxMDMsIDEwNCwgMCwgMCwgMTAsIDE5MSwgMSwgNiwgNCwgMCwgMzUsIDAsIDExLCAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLCAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMjYsIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCwgMzIsIDQsIDE2NywgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEyNywgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMSwgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI4LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LCAxNjcsIDExLCAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLCAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMjksIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCwgMzIsIDQsIDE2NywgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEzMCwgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMVxuICBdKSksIHt9KS5leHBvcnRzO1xufSBjYXRjaCAoZSkge1xuICAvLyBubyB3YXNtIHN1cHBvcnQgOihcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgNjQgYml0IHR3bydzLWNvbXBsZW1lbnQgaW50ZWdlciwgZ2l2ZW4gaXRzIGxvdyBhbmQgaGlnaCAzMiBiaXQgdmFsdWVzIGFzICpzaWduZWQqIGludGVnZXJzLlxuICogIFNlZSB0aGUgZnJvbSogZnVuY3Rpb25zIGJlbG93IGZvciBtb3JlIGNvbnZlbmllbnQgd2F5cyBvZiBjb25zdHJ1Y3RpbmcgTG9uZ3MuXG4gKiBAZXhwb3J0cyBMb25nXG4gKiBAY2xhc3MgQSBMb25nIGNsYXNzIGZvciByZXByZXNlbnRpbmcgYSA2NCBiaXQgdHdvJ3MtY29tcGxlbWVudCBpbnRlZ2VyIHZhbHVlLlxuICogQHBhcmFtIHtudW1iZXJ9IGxvdyBUaGUgbG93IChzaWduZWQpIDMyIGJpdHMgb2YgdGhlIGxvbmdcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoIFRoZSBoaWdoIChzaWduZWQpIDMyIGJpdHMgb2YgdGhlIGxvbmdcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBMb25nKGxvdywgaGlnaCwgdW5zaWduZWQpIHtcblxuICAvKipcbiAgICogVGhlIGxvdyAzMiBiaXRzIGFzIGEgc2lnbmVkIHZhbHVlLlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgdGhpcy5sb3cgPSBsb3cgfCAwO1xuXG4gIC8qKlxuICAgKiBUaGUgaGlnaCAzMiBiaXRzIGFzIGEgc2lnbmVkIHZhbHVlLlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgdGhpcy5oaWdoID0gaGlnaCB8IDA7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LlxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICovXG4gIHRoaXMudW5zaWduZWQgPSAhIXVuc2lnbmVkO1xufVxuXG4vLyBUaGUgaW50ZXJuYWwgcmVwcmVzZW50YXRpb24gb2YgYSBsb25nIGlzIHRoZSB0d28gZ2l2ZW4gc2lnbmVkLCAzMi1iaXQgdmFsdWVzLlxuLy8gV2UgdXNlIDMyLWJpdCBwaWVjZXMgYmVjYXVzZSB0aGVzZSBhcmUgdGhlIHNpemUgb2YgaW50ZWdlcnMgb24gd2hpY2hcbi8vIEphdmFzY3JpcHQgcGVyZm9ybXMgYml0LW9wZXJhdGlvbnMuICBGb3Igb3BlcmF0aW9ucyBsaWtlIGFkZGl0aW9uIGFuZFxuLy8gbXVsdGlwbGljYXRpb24sIHdlIHNwbGl0IGVhY2ggbnVtYmVyIGludG8gMTYgYml0IHBpZWNlcywgd2hpY2ggY2FuIGVhc2lseSBiZVxuLy8gbXVsdGlwbGllZCB3aXRoaW4gSmF2YXNjcmlwdCdzIGZsb2F0aW5nLXBvaW50IHJlcHJlc2VudGF0aW9uIHdpdGhvdXQgb3ZlcmZsb3dcbi8vIG9yIGNoYW5nZSBpbiBzaWduLlxuLy9cbi8vIEluIHRoZSBhbGdvcml0aG1zIGJlbG93LCB3ZSBmcmVxdWVudGx5IHJlZHVjZSB0aGUgbmVnYXRpdmUgY2FzZSB0byB0aGVcbi8vIHBvc2l0aXZlIGNhc2UgYnkgbmVnYXRpbmcgdGhlIGlucHV0KHMpIGFuZCB0aGVuIHBvc3QtcHJvY2Vzc2luZyB0aGUgcmVzdWx0LlxuLy8gTm90ZSB0aGF0IHdlIG11c3QgQUxXQVlTIGNoZWNrIHNwZWNpYWxseSB3aGV0aGVyIHRob3NlIHZhbHVlcyBhcmUgTUlOX1ZBTFVFXG4vLyAoLTJeNjMpIGJlY2F1c2UgLU1JTl9WQUxVRSA9PSBNSU5fVkFMVUUgKHNpbmNlIDJeNjMgY2Fubm90IGJlIHJlcHJlc2VudGVkIGFzXG4vLyBhIHBvc2l0aXZlIG51bWJlciwgaXQgb3ZlcmZsb3dzIGJhY2sgaW50byBhIG5lZ2F0aXZlKS4gIE5vdCBoYW5kbGluZyB0aGlzXG4vLyBjYXNlIHdvdWxkIG9mdGVuIHJlc3VsdCBpbiBpbmZpbml0ZSByZWN1cnNpb24uXG4vL1xuLy8gQ29tbW9uIGNvbnN0YW50IHZhbHVlcyBaRVJPLCBPTkUsIE5FR19PTkUsIGV0Yy4gYXJlIGRlZmluZWQgYmVsb3cgdGhlIGZyb20qXG4vLyBtZXRob2RzIG9uIHdoaWNoIHRoZXkgZGVwZW5kLlxuXG4vKipcbiAqIEFuIGluZGljYXRvciB1c2VkIHRvIHJlbGlhYmx5IGRldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBMb25nIG9yIG5vdC5cbiAqIEB0eXBlIHtib29sZWFufVxuICogQGNvbnN0XG4gKiBAcHJpdmF0ZVxuICovXG5Mb25nLnByb3RvdHlwZS5fX2lzTG9uZ19fO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoTG9uZy5wcm90b3R5cGUsIFwiX19pc0xvbmdfX1wiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHsqfSBvYmogT2JqZWN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqIEBpbm5lclxuICovXG5mdW5jdGlvbiBpc0xvbmcob2JqKSB7XG4gIHJldHVybiAob2JqICYmIG9ialtcIl9faXNMb25nX19cIl0pID09PSB0cnVlO1xufVxuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHsqfSB2YWx1ZSBudW1iZXJcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gY3R6MzIodmFsdWUpIHtcbiAgdmFyIGMgPSBNYXRoLmNsejMyKHZhbHVlICYgLXZhbHVlKTtcbiAgcmV0dXJuIHZhbHVlID8gMzEgLSBjIDogYztcbn1cblxuLyoqXG4gKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBhIExvbmcuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7Kn0gb2JqIE9iamVjdFxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmcuaXNMb25nID0gaXNMb25nO1xuXG4vKipcbiAqIEEgY2FjaGUgb2YgdGhlIExvbmcgcmVwcmVzZW50YXRpb25zIG9mIHNtYWxsIGludGVnZXIgdmFsdWVzLlxuICogQHR5cGUgeyFPYmplY3R9XG4gKiBAaW5uZXJcbiAqL1xudmFyIElOVF9DQUNIRSA9IHt9O1xuXG4vKipcbiAqIEEgY2FjaGUgb2YgdGhlIExvbmcgcmVwcmVzZW50YXRpb25zIG9mIHNtYWxsIHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLlxuICogQHR5cGUgeyFPYmplY3R9XG4gKiBAaW5uZXJcbiAqL1xudmFyIFVJTlRfQ0FDSEUgPSB7fTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gZnJvbUludCh2YWx1ZSwgdW5zaWduZWQpIHtcbiAgdmFyIG9iaiwgY2FjaGVkT2JqLCBjYWNoZTtcbiAgaWYgKHVuc2lnbmVkKSB7XG4gICAgdmFsdWUgPj4+PSAwO1xuICAgIGlmIChjYWNoZSA9ICgwIDw9IHZhbHVlICYmIHZhbHVlIDwgMjU2KSkge1xuICAgICAgY2FjaGVkT2JqID0gVUlOVF9DQUNIRVt2YWx1ZV07XG4gICAgICBpZiAoY2FjaGVkT2JqKVxuICAgICAgICByZXR1cm4gY2FjaGVkT2JqO1xuICAgIH1cbiAgICBvYmogPSBmcm9tQml0cyh2YWx1ZSwgMCwgdHJ1ZSk7XG4gICAgaWYgKGNhY2hlKVxuICAgICAgVUlOVF9DQUNIRVt2YWx1ZV0gPSBvYmo7XG4gICAgcmV0dXJuIG9iajtcbiAgfSBlbHNlIHtcbiAgICB2YWx1ZSB8PSAwO1xuICAgIGlmIChjYWNoZSA9ICgtMTI4IDw9IHZhbHVlICYmIHZhbHVlIDwgMTI4KSkge1xuICAgICAgY2FjaGVkT2JqID0gSU5UX0NBQ0hFW3ZhbHVlXTtcbiAgICAgIGlmIChjYWNoZWRPYmopXG4gICAgICAgIHJldHVybiBjYWNoZWRPYmo7XG4gICAgfVxuICAgIG9iaiA9IGZyb21CaXRzKHZhbHVlLCB2YWx1ZSA8IDAgPyAtMSA6IDAsIGZhbHNlKTtcbiAgICBpZiAoY2FjaGUpXG4gICAgICBJTlRfQ0FDSEVbdmFsdWVdID0gb2JqO1xuICAgIHJldHVybiBvYmo7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIGdpdmVuIDMyIGJpdCBpbnRlZ2VyIHZhbHVlLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVGhlIDMyIGJpdCBpbnRlZ2VyIGluIHF1ZXN0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tSW50ID0gZnJvbUludDtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gZnJvbU51bWJlcih2YWx1ZSwgdW5zaWduZWQpIHtcbiAgaWYgKGlzTmFOKHZhbHVlKSlcbiAgICByZXR1cm4gdW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XG4gIGlmICh1bnNpZ25lZCkge1xuICAgIGlmICh2YWx1ZSA8IDApXG4gICAgICByZXR1cm4gVVpFUk87XG4gICAgaWYgKHZhbHVlID49IFRXT19QV1JfNjRfREJMKVxuICAgICAgcmV0dXJuIE1BWF9VTlNJR05FRF9WQUxVRTtcbiAgfSBlbHNlIHtcbiAgICBpZiAodmFsdWUgPD0gLVRXT19QV1JfNjNfREJMKVxuICAgICAgcmV0dXJuIE1JTl9WQUxVRTtcbiAgICBpZiAodmFsdWUgKyAxID49IFRXT19QV1JfNjNfREJMKVxuICAgICAgcmV0dXJuIE1BWF9WQUxVRTtcbiAgfVxuICBpZiAodmFsdWUgPCAwKVxuICAgIHJldHVybiBmcm9tTnVtYmVyKC12YWx1ZSwgdW5zaWduZWQpLm5lZygpO1xuICByZXR1cm4gZnJvbUJpdHMoKHZhbHVlICUgVFdPX1BXUl8zMl9EQkwpIHwgMCwgKHZhbHVlIC8gVFdPX1BXUl8zMl9EQkwpIHwgMCwgdW5zaWduZWQpO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gdmFsdWUsIHByb3ZpZGVkIHRoYXQgaXQgaXMgYSBmaW5pdGUgbnVtYmVyLiBPdGhlcndpc2UsIHplcm8gaXMgcmV0dXJuZWQuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgbnVtYmVyIGluIHF1ZXN0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tTnVtYmVyID0gZnJvbU51bWJlcjtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gbG93Qml0c1xuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbmZ1bmN0aW9uIGZyb21CaXRzKGxvd0JpdHMsIGhpZ2hCaXRzLCB1bnNpZ25lZCkge1xuICByZXR1cm4gbmV3IExvbmcobG93Qml0cywgaGlnaEJpdHMsIHVuc2lnbmVkKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIDY0IGJpdCBpbnRlZ2VyIHRoYXQgY29tZXMgYnkgY29uY2F0ZW5hdGluZyB0aGUgZ2l2ZW4gbG93IGFuZCBoaWdoIGJpdHMuIEVhY2ggaXNcbiAqICBhc3N1bWVkIHRvIHVzZSAzMiBiaXRzLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gbG93Qml0cyBUaGUgbG93IDMyIGJpdHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoQml0cyBUaGUgaGlnaCAzMiBiaXRzXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tQml0cyA9IGZyb21CaXRzO1xuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IGJhc2VcbiAqIEBwYXJhbSB7bnVtYmVyfSBleHBvbmVudFxuICogQHJldHVybnMge251bWJlcn1cbiAqIEBpbm5lclxuICovXG52YXIgcG93X2RibCA9IE1hdGgucG93OyAvLyBVc2VkIDQgdGltZXMgKDQqOCB0byAxNSs0KVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEBwYXJhbSB7KGJvb2xlYW58bnVtYmVyKT19IHVuc2lnbmVkXG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4XG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gZnJvbVN0cmluZyhzdHIsIHVuc2lnbmVkLCByYWRpeCkge1xuICBpZiAoc3RyLmxlbmd0aCA9PT0gMClcbiAgICB0aHJvdyBFcnJvcignZW1wdHkgc3RyaW5nJyk7XG4gIGlmICh0eXBlb2YgdW5zaWduZWQgPT09ICdudW1iZXInKSB7XG4gICAgLy8gRm9yIGdvb2cubWF0aC5sb25nIGNvbXBhdGliaWxpdHlcbiAgICByYWRpeCA9IHVuc2lnbmVkO1xuICAgIHVuc2lnbmVkID0gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgdW5zaWduZWQgPSAhIXVuc2lnbmVkO1xuICB9XG4gIGlmIChzdHIgPT09IFwiTmFOXCIgfHwgc3RyID09PSBcIkluZmluaXR5XCIgfHwgc3RyID09PSBcIitJbmZpbml0eVwiIHx8IHN0ciA9PT0gXCItSW5maW5pdHlcIilcbiAgICByZXR1cm4gdW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XG4gIHJhZGl4ID0gcmFkaXggfHwgMTA7XG4gIGlmIChyYWRpeCA8IDIgfHwgMzYgPCByYWRpeClcbiAgICB0aHJvdyBSYW5nZUVycm9yKCdyYWRpeCcpO1xuXG4gIHZhciBwO1xuICBpZiAoKHAgPSBzdHIuaW5kZXhPZignLScpKSA+IDApXG4gICAgdGhyb3cgRXJyb3IoJ2ludGVyaW9yIGh5cGhlbicpO1xuICBlbHNlIGlmIChwID09PSAwKSB7XG4gICAgcmV0dXJuIGZyb21TdHJpbmcoc3RyLnN1YnN0cmluZygxKSwgdW5zaWduZWQsIHJhZGl4KS5uZWcoKTtcbiAgfVxuXG4gIC8vIERvIHNldmVyYWwgKDgpIGRpZ2l0cyBlYWNoIHRpbWUgdGhyb3VnaCB0aGUgbG9vcCwgc28gYXMgdG9cbiAgLy8gbWluaW1pemUgdGhlIGNhbGxzIHRvIHRoZSB2ZXJ5IGV4cGVuc2l2ZSBlbXVsYXRlZCBkaXYuXG4gIHZhciByYWRpeFRvUG93ZXIgPSBmcm9tTnVtYmVyKHBvd19kYmwocmFkaXgsIDgpKTtcblxuICB2YXIgcmVzdWx0ID0gWkVSTztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpICs9IDgpIHtcbiAgICB2YXIgc2l6ZSA9IE1hdGgubWluKDgsIHN0ci5sZW5ndGggLSBpKSxcbiAgICAgIHZhbHVlID0gcGFyc2VJbnQoc3RyLnN1YnN0cmluZyhpLCBpICsgc2l6ZSksIHJhZGl4KTtcbiAgICBpZiAoc2l6ZSA8IDgpIHtcbiAgICAgIHZhciBwb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgc2l6ZSkpO1xuICAgICAgcmVzdWx0ID0gcmVzdWx0Lm11bChwb3dlcikuYWRkKGZyb21OdW1iZXIodmFsdWUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0ID0gcmVzdWx0Lm11bChyYWRpeFRvUG93ZXIpO1xuICAgICAgcmVzdWx0ID0gcmVzdWx0LmFkZChmcm9tTnVtYmVyKHZhbHVlKSk7XG4gICAgfVxuICB9XG4gIHJlc3VsdC51bnNpZ25lZCA9IHVuc2lnbmVkO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBzdHJpbmcsIHdyaXR0ZW4gdXNpbmcgdGhlIHNwZWNpZmllZCByYWRpeC5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciBUaGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgTG9uZ1xuICogQHBhcmFtIHsoYm9vbGVhbnxudW1iZXIpPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQHBhcmFtIHtudW1iZXI9fSByYWRpeCBUaGUgcmFkaXggaW4gd2hpY2ggdGhlIHRleHQgaXMgd3JpdHRlbiAoMi0zNiksIGRlZmF1bHRzIHRvIDEwXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tU3RyaW5nID0gZnJvbVN0cmluZztcblxuLyoqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ3whe2xvdzogbnVtYmVyLCBoaWdoOiBudW1iZXIsIHVuc2lnbmVkOiBib29sZWFufX0gdmFsXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbmZ1bmN0aW9uIGZyb21WYWx1ZSh2YWwsIHVuc2lnbmVkKSB7XG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJylcbiAgICByZXR1cm4gZnJvbU51bWJlcih2YWwsIHVuc2lnbmVkKTtcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKVxuICAgIHJldHVybiBmcm9tU3RyaW5nKHZhbCwgdW5zaWduZWQpO1xuICAvLyBUaHJvd3MgZm9yIG5vbi1vYmplY3RzLCBjb252ZXJ0cyBub24taW5zdGFuY2VvZiBMb25nOlxuICByZXR1cm4gZnJvbUJpdHModmFsLmxvdywgdmFsLmhpZ2gsIHR5cGVvZiB1bnNpZ25lZCA9PT0gJ2Jvb2xlYW4nID8gdW5zaWduZWQgOiB2YWwudW5zaWduZWQpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgdmFsdWUgdG8gYSBMb25nIHVzaW5nIHRoZSBhcHByb3ByaWF0ZSBmcm9tKiBmdW5jdGlvbiBmb3IgaXRzIHR5cGUuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ3whe2xvdzogbnVtYmVyLCBoaWdoOiBudW1iZXIsIHVuc2lnbmVkOiBib29sZWFufX0gdmFsIFZhbHVlXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKi9cbkxvbmcuZnJvbVZhbHVlID0gZnJvbVZhbHVlO1xuXG4vLyBOT1RFOiB0aGUgY29tcGlsZXIgc2hvdWxkIGlubGluZSB0aGVzZSBjb25zdGFudCB2YWx1ZXMgYmVsb3cgYW5kIHRoZW4gcmVtb3ZlIHRoZXNlIHZhcmlhYmxlcywgc28gdGhlcmUgc2hvdWxkIGJlXG4vLyBubyBydW50aW1lIHBlbmFsdHkgZm9yIHRoZXNlLlxuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqIEBpbm5lclxuICovXG52YXIgVFdPX1BXUl8xNl9EQkwgPSAxIDw8IDE2O1xuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqIEBpbm5lclxuICovXG52YXIgVFdPX1BXUl8yNF9EQkwgPSAxIDw8IDI0O1xuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqIEBpbm5lclxuICovXG52YXIgVFdPX1BXUl8zMl9EQkwgPSBUV09fUFdSXzE2X0RCTCAqIFRXT19QV1JfMTZfREJMO1xuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqIEBpbm5lclxuICovXG52YXIgVFdPX1BXUl82NF9EQkwgPSBUV09fUFdSXzMyX0RCTCAqIFRXT19QV1JfMzJfREJMO1xuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqIEBpbm5lclxuICovXG52YXIgVFdPX1BXUl82M19EQkwgPSBUV09fUFdSXzY0X0RCTCAvIDI7XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGNvbnN0XG4gKiBAaW5uZXJcbiAqL1xudmFyIFRXT19QV1JfMjQgPSBmcm9tSW50KFRXT19QV1JfMjRfREJMKTtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIFpFUk8gPSBmcm9tSW50KDApO1xuXG4vKipcbiAqIFNpZ25lZCB6ZXJvLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLlpFUk8gPSBaRVJPO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgVVpFUk8gPSBmcm9tSW50KDAsIHRydWUpO1xuXG4vKipcbiAqIFVuc2lnbmVkIHplcm8uXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuVVpFUk8gPSBVWkVSTztcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIE9ORSA9IGZyb21JbnQoMSk7XG5cbi8qKlxuICogU2lnbmVkIG9uZS5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5PTkUgPSBPTkU7XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbnZhciBVT05FID0gZnJvbUludCgxLCB0cnVlKTtcblxuLyoqXG4gKiBVbnNpZ25lZCBvbmUuXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuVU9ORSA9IFVPTkU7XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbnZhciBORUdfT05FID0gZnJvbUludCgtMSk7XG5cbi8qKlxuICogU2lnbmVkIG5lZ2F0aXZlIG9uZS5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5ORUdfT05FID0gTkVHX09ORTtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIE1BWF9WQUxVRSA9IGZyb21CaXRzKDB4RkZGRkZGRkYgfCAwLCAweDdGRkZGRkZGIHwgMCwgZmFsc2UpO1xuXG4vKipcbiAqIE1heGltdW0gc2lnbmVkIHZhbHVlLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLk1BWF9WQUxVRSA9IE1BWF9WQUxVRTtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIE1BWF9VTlNJR05FRF9WQUxVRSA9IGZyb21CaXRzKDB4RkZGRkZGRkYgfCAwLCAweEZGRkZGRkZGIHwgMCwgdHJ1ZSk7XG5cbi8qKlxuICogTWF4aW11bSB1bnNpZ25lZCB2YWx1ZS5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5NQVhfVU5TSUdORURfVkFMVUUgPSBNQVhfVU5TSUdORURfVkFMVUU7XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbnZhciBNSU5fVkFMVUUgPSBmcm9tQml0cygwLCAweDgwMDAwMDAwIHwgMCwgZmFsc2UpO1xuXG4vKipcbiAqIE1pbmltdW0gc2lnbmVkIHZhbHVlLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLk1JTl9WQUxVRSA9IE1JTl9WQUxVRTtcblxuLyoqXG4gKiBAYWxpYXMgTG9uZy5wcm90b3R5cGVcbiAqIEBpbm5lclxuICovXG52YXIgTG9uZ1Byb3RvdHlwZSA9IExvbmcucHJvdG90eXBlO1xuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgMzIgYml0IGludGVnZXIsIGFzc3VtaW5nIGl0IGlzIGEgMzIgYml0IGludGVnZXIuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLnRvSW50ID0gZnVuY3Rpb24gdG9JbnQoKSB7XG4gIHJldHVybiB0aGlzLnVuc2lnbmVkID8gdGhpcy5sb3cgPj4+IDAgOiB0aGlzLmxvdztcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhlIExvbmcgdG8gYSB0aGUgbmVhcmVzdCBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHZhbHVlIChkb3VibGUsIDUzIGJpdCBtYW50aXNzYSkuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLnRvTnVtYmVyID0gZnVuY3Rpb24gdG9OdW1iZXIoKSB7XG4gIGlmICh0aGlzLnVuc2lnbmVkKVxuICAgIHJldHVybiAoKHRoaXMuaGlnaCA+Pj4gMCkgKiBUV09fUFdSXzMyX0RCTCkgKyAodGhpcy5sb3cgPj4+IDApO1xuICByZXR1cm4gdGhpcy5oaWdoICogVFdPX1BXUl8zMl9EQkwgKyAodGhpcy5sb3cgPj4+IDApO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgTG9uZyB0byBhIHN0cmluZyB3cml0dGVuIGluIHRoZSBzcGVjaWZpZWQgcmFkaXguXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4IFJhZGl4ICgyLTM2KSwgZGVmYXVsdHMgdG8gMTBcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKiBAb3ZlcnJpZGVcbiAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGByYWRpeGAgaXMgb3V0IG9mIHJhbmdlXG4gKi9cbkxvbmdQcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyhyYWRpeCkge1xuICByYWRpeCA9IHJhZGl4IHx8IDEwO1xuICBpZiAocmFkaXggPCAyIHx8IDM2IDwgcmFkaXgpXG4gICAgdGhyb3cgUmFuZ2VFcnJvcigncmFkaXgnKTtcbiAgaWYgKHRoaXMuaXNaZXJvKCkpXG4gICAgcmV0dXJuICcwJztcbiAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7IC8vIFVuc2lnbmVkIExvbmdzIGFyZSBuZXZlciBuZWdhdGl2ZVxuICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHtcbiAgICAgIC8vIFdlIG5lZWQgdG8gY2hhbmdlIHRoZSBMb25nIHZhbHVlIGJlZm9yZSBpdCBjYW4gYmUgbmVnYXRlZCwgc28gd2UgcmVtb3ZlXG4gICAgICAvLyB0aGUgYm90dG9tLW1vc3QgZGlnaXQgaW4gdGhpcyBiYXNlIGFuZCB0aGVuIHJlY3Vyc2UgdG8gZG8gdGhlIHJlc3QuXG4gICAgICB2YXIgcmFkaXhMb25nID0gZnJvbU51bWJlcihyYWRpeCksXG4gICAgICAgIGRpdiA9IHRoaXMuZGl2KHJhZGl4TG9uZyksXG4gICAgICAgIHJlbTEgPSBkaXYubXVsKHJhZGl4TG9uZykuc3ViKHRoaXMpO1xuICAgICAgcmV0dXJuIGRpdi50b1N0cmluZyhyYWRpeCkgKyByZW0xLnRvSW50KCkudG9TdHJpbmcocmFkaXgpO1xuICAgIH0gZWxzZVxuICAgICAgcmV0dXJuICctJyArIHRoaXMubmVnKCkudG9TdHJpbmcocmFkaXgpO1xuICB9XG5cbiAgLy8gRG8gc2V2ZXJhbCAoNikgZGlnaXRzIGVhY2ggdGltZSB0aHJvdWdoIHRoZSBsb29wLCBzbyBhcyB0b1xuICAvLyBtaW5pbWl6ZSB0aGUgY2FsbHMgdG8gdGhlIHZlcnkgZXhwZW5zaXZlIGVtdWxhdGVkIGRpdi5cbiAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgNiksIHRoaXMudW5zaWduZWQpLFxuICAgIHJlbSA9IHRoaXM7XG4gIHZhciByZXN1bHQgPSAnJztcbiAgd2hpbGUgKHRydWUpIHtcbiAgICB2YXIgcmVtRGl2ID0gcmVtLmRpdihyYWRpeFRvUG93ZXIpLFxuICAgICAgaW50dmFsID0gcmVtLnN1YihyZW1EaXYubXVsKHJhZGl4VG9Qb3dlcikpLnRvSW50KCkgPj4+IDAsXG4gICAgICBkaWdpdHMgPSBpbnR2YWwudG9TdHJpbmcocmFkaXgpO1xuICAgIHJlbSA9IHJlbURpdjtcbiAgICBpZiAocmVtLmlzWmVybygpKVxuICAgICAgcmV0dXJuIGRpZ2l0cyArIHJlc3VsdDtcbiAgICBlbHNlIHtcbiAgICAgIHdoaWxlIChkaWdpdHMubGVuZ3RoIDwgNilcbiAgICAgICAgZGlnaXRzID0gJzAnICsgZGlnaXRzO1xuICAgICAgcmVzdWx0ID0gJycgKyBkaWdpdHMgKyByZXN1bHQ7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIGhpZ2ggMzIgYml0cyBhcyBhIHNpZ25lZCBpbnRlZ2VyLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge251bWJlcn0gU2lnbmVkIGhpZ2ggYml0c1xuICovXG5Mb25nUHJvdG90eXBlLmdldEhpZ2hCaXRzID0gZnVuY3Rpb24gZ2V0SGlnaEJpdHMoKSB7XG4gIHJldHVybiB0aGlzLmhpZ2g7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIGhpZ2ggMzIgYml0cyBhcyBhbiB1bnNpZ25lZCBpbnRlZ2VyLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge251bWJlcn0gVW5zaWduZWQgaGlnaCBiaXRzXG4gKi9cbkxvbmdQcm90b3R5cGUuZ2V0SGlnaEJpdHNVbnNpZ25lZCA9IGZ1bmN0aW9uIGdldEhpZ2hCaXRzVW5zaWduZWQoKSB7XG4gIHJldHVybiB0aGlzLmhpZ2ggPj4+IDA7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIGxvdyAzMiBiaXRzIGFzIGEgc2lnbmVkIGludGVnZXIuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgbG93IGJpdHNcbiAqL1xuTG9uZ1Byb3RvdHlwZS5nZXRMb3dCaXRzID0gZnVuY3Rpb24gZ2V0TG93Qml0cygpIHtcbiAgcmV0dXJuIHRoaXMubG93O1xufTtcblxuLyoqXG4gKiBHZXRzIHRoZSBsb3cgMzIgYml0cyBhcyBhbiB1bnNpZ25lZCBpbnRlZ2VyLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge251bWJlcn0gVW5zaWduZWQgbG93IGJpdHNcbiAqL1xuTG9uZ1Byb3RvdHlwZS5nZXRMb3dCaXRzVW5zaWduZWQgPSBmdW5jdGlvbiBnZXRMb3dCaXRzVW5zaWduZWQoKSB7XG4gIHJldHVybiB0aGlzLmxvdyA+Pj4gMDtcbn07XG5cbi8qKlxuICogR2V0cyB0aGUgbnVtYmVyIG9mIGJpdHMgbmVlZGVkIHRvIHJlcHJlc2VudCB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhpcyBMb25nLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5nZXROdW1CaXRzQWJzID0gZnVuY3Rpb24gZ2V0TnVtQml0c0FicygpIHtcbiAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSAvLyBVbnNpZ25lZCBMb25ncyBhcmUgbmV2ZXIgbmVnYXRpdmVcbiAgICByZXR1cm4gdGhpcy5lcShNSU5fVkFMVUUpID8gNjQgOiB0aGlzLm5lZygpLmdldE51bUJpdHNBYnMoKTtcbiAgdmFyIHZhbCA9IHRoaXMuaGlnaCAhPSAwID8gdGhpcy5oaWdoIDogdGhpcy5sb3c7XG4gIGZvciAodmFyIGJpdCA9IDMxOyBiaXQgPiAwOyBiaXQtLSlcbiAgICBpZiAoKHZhbCAmICgxIDw8IGJpdCkpICE9IDApXG4gICAgICBicmVhaztcbiAgcmV0dXJuIHRoaXMuaGlnaCAhPSAwID8gYml0ICsgMzMgOiBiaXQgKyAxO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgemVyby5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmlzWmVybyA9IGZ1bmN0aW9uIGlzWmVybygpIHtcbiAgcmV0dXJuIHRoaXMuaGlnaCA9PT0gMCAmJiB0aGlzLmxvdyA9PT0gMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHplcm8uIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjaXNaZXJvfS5cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmVxeiA9IExvbmdQcm90b3R5cGUuaXNaZXJvO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIG5lZ2F0aXZlLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuaXNOZWdhdGl2ZSA9IGZ1bmN0aW9uIGlzTmVnYXRpdmUoKSB7XG4gIHJldHVybiAhdGhpcy51bnNpZ25lZCAmJiB0aGlzLmhpZ2ggPCAwO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBwb3NpdGl2ZSBvciB6ZXJvLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuaXNQb3NpdGl2ZSA9IGZ1bmN0aW9uIGlzUG9zaXRpdmUoKSB7XG4gIHJldHVybiB0aGlzLnVuc2lnbmVkIHx8IHRoaXMuaGlnaCA+PSAwO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBvZGQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5pc09kZCA9IGZ1bmN0aW9uIGlzT2RkKCkge1xuICByZXR1cm4gKHRoaXMubG93ICYgMSkgPT09IDE7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGV2ZW4uXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5pc0V2ZW4gPSBmdW5jdGlvbiBpc0V2ZW4oKSB7XG4gIHJldHVybiAodGhpcy5sb3cgJiAxKSA9PT0gMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHRoZSBzcGVjaWZpZWQncy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyhvdGhlcikge1xuICBpZiAoIWlzTG9uZyhvdGhlcikpXG4gICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICBpZiAodGhpcy51bnNpZ25lZCAhPT0gb3RoZXIudW5zaWduZWQgJiYgKHRoaXMuaGlnaCA+Pj4gMzEpID09PSAxICYmIChvdGhlci5oaWdoID4+PiAzMSkgPT09IDEpXG4gICAgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gdGhpcy5oaWdoID09PSBvdGhlci5oaWdoICYmIHRoaXMubG93ID09PSBvdGhlci5sb3c7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZXF1YWxzfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuZXEgPSBMb25nUHJvdG90eXBlLmVxdWFscztcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBkaWZmZXJzIGZyb20gdGhlIHNwZWNpZmllZCdzLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubm90RXF1YWxzID0gZnVuY3Rpb24gbm90RXF1YWxzKG90aGVyKSB7XG4gIHJldHVybiAhdGhpcy5lcSgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBkaWZmZXJzIGZyb20gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI25vdEVxdWFsc30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLm5lcSA9IExvbmdQcm90b3R5cGUubm90RXF1YWxzO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbm90RXF1YWxzfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubmUgPSBMb25nUHJvdG90eXBlLm5vdEVxdWFscztcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCdzLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubGVzc1RoYW4gPSBmdW5jdGlvbiBsZXNzVGhhbihvdGhlcikge1xuICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPCAwO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2xlc3NUaGFufS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubHQgPSBMb25nUHJvdG90eXBlLmxlc3NUaGFuO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWwgPSBmdW5jdGlvbiBsZXNzVGhhbk9yRXF1YWwob3RoZXIpIHtcbiAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpIDw9IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbGVzc1RoYW5PckVxdWFsfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubHRlID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWw7XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNsZXNzVGhhbk9yRXF1YWx9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5sZSA9IExvbmdQcm90b3R5cGUubGVzc1RoYW5PckVxdWFsO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbiA9IGZ1bmN0aW9uIGdyZWF0ZXJUaGFuKG90aGVyKSB7XG4gIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA+IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW59LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5ndCA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW47XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuT3JFcXVhbCA9IGZ1bmN0aW9uIGdyZWF0ZXJUaGFuT3JFcXVhbChvdGhlcikge1xuICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPj0gMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNncmVhdGVyVGhhbk9yRXF1YWx9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5ndGUgPSBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuT3JFcXVhbDtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2dyZWF0ZXJUaGFuT3JFcXVhbH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmdlID0gTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWw7XG5cbi8qKlxuICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7bnVtYmVyfSAwIGlmIHRoZXkgYXJlIHRoZSBzYW1lLCAxIGlmIHRoZSB0aGlzIGlzIGdyZWF0ZXIgYW5kIC0xXG4gKiAgaWYgdGhlIGdpdmVuIG9uZSBpcyBncmVhdGVyXG4gKi9cbkxvbmdQcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUob3RoZXIpIHtcbiAgaWYgKCFpc0xvbmcob3RoZXIpKVxuICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcbiAgaWYgKHRoaXMuZXEob3RoZXIpKVxuICAgIHJldHVybiAwO1xuICB2YXIgdGhpc05lZyA9IHRoaXMuaXNOZWdhdGl2ZSgpLFxuICAgIG90aGVyTmVnID0gb3RoZXIuaXNOZWdhdGl2ZSgpO1xuICBpZiAodGhpc05lZyAmJiAhb3RoZXJOZWcpXG4gICAgcmV0dXJuIC0xO1xuICBpZiAoIXRoaXNOZWcgJiYgb3RoZXJOZWcpXG4gICAgcmV0dXJuIDE7XG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHNpZ24gYml0cyBhcmUgdGhlIHNhbWVcbiAgaWYgKCF0aGlzLnVuc2lnbmVkKVxuICAgIHJldHVybiB0aGlzLnN1YihvdGhlcikuaXNOZWdhdGl2ZSgpID8gLTEgOiAxO1xuICAvLyBCb3RoIGFyZSBwb3NpdGl2ZSBpZiBhdCBsZWFzdCBvbmUgaXMgdW5zaWduZWRcbiAgcmV0dXJuIChvdGhlci5oaWdoID4+PiAwKSA+ICh0aGlzLmhpZ2ggPj4+IDApIHx8IChvdGhlci5oaWdoID09PSB0aGlzLmhpZ2ggJiYgKG90aGVyLmxvdyA+Pj4gMCkgPiAodGhpcy5sb3cgPj4+IDApKSA/IC0xIDogMTtcbn07XG5cbi8qKlxuICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjY29tcGFyZX0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IDAgaWYgdGhleSBhcmUgdGhlIHNhbWUsIDEgaWYgdGhlIHRoaXMgaXMgZ3JlYXRlciBhbmQgLTFcbiAqICBpZiB0aGUgZ2l2ZW4gb25lIGlzIGdyZWF0ZXJcbiAqL1xuTG9uZ1Byb3RvdHlwZS5jb21wID0gTG9uZ1Byb3RvdHlwZS5jb21wYXJlO1xuXG4vKipcbiAqIE5lZ2F0ZXMgdGhpcyBMb25nJ3MgdmFsdWUuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IUxvbmd9IE5lZ2F0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLm5lZ2F0ZSA9IGZ1bmN0aW9uIG5lZ2F0ZSgpIHtcbiAgaWYgKCF0aGlzLnVuc2lnbmVkICYmIHRoaXMuZXEoTUlOX1ZBTFVFKSlcbiAgICByZXR1cm4gTUlOX1ZBTFVFO1xuICByZXR1cm4gdGhpcy5ub3QoKS5hZGQoT05FKTtcbn07XG5cbi8qKlxuICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNuZWdhdGV9LlxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7IUxvbmd9IE5lZ2F0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLm5lZyA9IExvbmdQcm90b3R5cGUubmVnYXRlO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHN1bSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGFkZGVuZCBBZGRlbmRcbiAqIEByZXR1cm5zIHshTG9uZ30gU3VtXG4gKi9cbkxvbmdQcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkKGFkZGVuZCkge1xuICBpZiAoIWlzTG9uZyhhZGRlbmQpKVxuICAgIGFkZGVuZCA9IGZyb21WYWx1ZShhZGRlbmQpO1xuXG4gIC8vIERpdmlkZSBlYWNoIG51bWJlciBpbnRvIDQgY2h1bmtzIG9mIDE2IGJpdHMsIGFuZCB0aGVuIHN1bSB0aGUgY2h1bmtzLlxuXG4gIHZhciBhNDggPSB0aGlzLmhpZ2ggPj4+IDE2O1xuICB2YXIgYTMyID0gdGhpcy5oaWdoICYgMHhGRkZGO1xuICB2YXIgYTE2ID0gdGhpcy5sb3cgPj4+IDE2O1xuICB2YXIgYTAwID0gdGhpcy5sb3cgJiAweEZGRkY7XG5cbiAgdmFyIGI0OCA9IGFkZGVuZC5oaWdoID4+PiAxNjtcbiAgdmFyIGIzMiA9IGFkZGVuZC5oaWdoICYgMHhGRkZGO1xuICB2YXIgYjE2ID0gYWRkZW5kLmxvdyA+Pj4gMTY7XG4gIHZhciBiMDAgPSBhZGRlbmQubG93ICYgMHhGRkZGO1xuXG4gIHZhciBjNDggPSAwLCBjMzIgPSAwLCBjMTYgPSAwLCBjMDAgPSAwO1xuICBjMDAgKz0gYTAwICsgYjAwO1xuICBjMTYgKz0gYzAwID4+PiAxNjtcbiAgYzAwICY9IDB4RkZGRjtcbiAgYzE2ICs9IGExNiArIGIxNjtcbiAgYzMyICs9IGMxNiA+Pj4gMTY7XG4gIGMxNiAmPSAweEZGRkY7XG4gIGMzMiArPSBhMzIgKyBiMzI7XG4gIGM0OCArPSBjMzIgPj4+IDE2O1xuICBjMzIgJj0gMHhGRkZGO1xuICBjNDggKz0gYTQ4ICsgYjQ4O1xuICBjNDggJj0gMHhGRkZGO1xuICByZXR1cm4gZnJvbUJpdHMoKGMxNiA8PCAxNikgfCBjMDAsIChjNDggPDwgMTYpIHwgYzMyLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZGlmZmVyZW5jZSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IHN1YnRyYWhlbmQgU3VidHJhaGVuZFxuICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXG4gKi9cbkxvbmdQcm90b3R5cGUuc3VidHJhY3QgPSBmdW5jdGlvbiBzdWJ0cmFjdChzdWJ0cmFoZW5kKSB7XG4gIGlmICghaXNMb25nKHN1YnRyYWhlbmQpKVxuICAgIHN1YnRyYWhlbmQgPSBmcm9tVmFsdWUoc3VidHJhaGVuZCk7XG4gIHJldHVybiB0aGlzLmFkZChzdWJ0cmFoZW5kLm5lZygpKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZGlmZmVyZW5jZSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc3VidHJhY3R9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IHN1YnRyYWhlbmQgU3VidHJhaGVuZFxuICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXG4gKi9cbkxvbmdQcm90b3R5cGUuc3ViID0gTG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBwcm9kdWN0IG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gbXVsdGlwbGllciBNdWx0aXBsaWVyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFByb2R1Y3RcbiAqL1xuTG9uZ1Byb3RvdHlwZS5tdWx0aXBseSA9IGZ1bmN0aW9uIG11bHRpcGx5KG11bHRpcGxpZXIpIHtcbiAgaWYgKHRoaXMuaXNaZXJvKCkpXG4gICAgcmV0dXJuIHRoaXM7XG4gIGlmICghaXNMb25nKG11bHRpcGxpZXIpKVxuICAgIG11bHRpcGxpZXIgPSBmcm9tVmFsdWUobXVsdGlwbGllcik7XG5cbiAgLy8gdXNlIHdhc20gc3VwcG9ydCBpZiBwcmVzZW50XG4gIGlmICh3YXNtKSB7XG4gICAgdmFyIGxvdyA9IHdhc21bXCJtdWxcIl0odGhpcy5sb3csXG4gICAgICB0aGlzLmhpZ2gsXG4gICAgICBtdWx0aXBsaWVyLmxvdyxcbiAgICAgIG11bHRpcGxpZXIuaGlnaCk7XG4gICAgcmV0dXJuIGZyb21CaXRzKGxvdywgd2FzbVtcImdldF9oaWdoXCJdKCksIHRoaXMudW5zaWduZWQpO1xuICB9XG5cbiAgaWYgKG11bHRpcGxpZXIuaXNaZXJvKCkpXG4gICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XG4gIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpXG4gICAgcmV0dXJuIG11bHRpcGxpZXIuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XG4gIGlmIChtdWx0aXBsaWVyLmVxKE1JTl9WQUxVRSkpXG4gICAgcmV0dXJuIHRoaXMuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XG5cbiAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7XG4gICAgaWYgKG11bHRpcGxpZXIuaXNOZWdhdGl2ZSgpKVxuICAgICAgcmV0dXJuIHRoaXMubmVnKCkubXVsKG11bHRpcGxpZXIubmVnKCkpO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiB0aGlzLm5lZygpLm11bChtdWx0aXBsaWVyKS5uZWcoKTtcbiAgfSBlbHNlIGlmIChtdWx0aXBsaWVyLmlzTmVnYXRpdmUoKSlcbiAgICByZXR1cm4gdGhpcy5tdWwobXVsdGlwbGllci5uZWcoKSkubmVnKCk7XG5cbiAgLy8gSWYgYm90aCBsb25ncyBhcmUgc21hbGwsIHVzZSBmbG9hdCBtdWx0aXBsaWNhdGlvblxuICBpZiAodGhpcy5sdChUV09fUFdSXzI0KSAmJiBtdWx0aXBsaWVyLmx0KFRXT19QV1JfMjQpKVxuICAgIHJldHVybiBmcm9tTnVtYmVyKHRoaXMudG9OdW1iZXIoKSAqIG11bHRpcGxpZXIudG9OdW1iZXIoKSwgdGhpcy51bnNpZ25lZCk7XG5cbiAgLy8gRGl2aWRlIGVhY2ggbG9uZyBpbnRvIDQgY2h1bmtzIG9mIDE2IGJpdHMsIGFuZCB0aGVuIGFkZCB1cCA0eDQgcHJvZHVjdHMuXG4gIC8vIFdlIGNhbiBza2lwIHByb2R1Y3RzIHRoYXQgd291bGQgb3ZlcmZsb3cuXG5cbiAgdmFyIGE0OCA9IHRoaXMuaGlnaCA+Pj4gMTY7XG4gIHZhciBhMzIgPSB0aGlzLmhpZ2ggJiAweEZGRkY7XG4gIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XG4gIHZhciBhMDAgPSB0aGlzLmxvdyAmIDB4RkZGRjtcblxuICB2YXIgYjQ4ID0gbXVsdGlwbGllci5oaWdoID4+PiAxNjtcbiAgdmFyIGIzMiA9IG11bHRpcGxpZXIuaGlnaCAmIDB4RkZGRjtcbiAgdmFyIGIxNiA9IG11bHRpcGxpZXIubG93ID4+PiAxNjtcbiAgdmFyIGIwMCA9IG11bHRpcGxpZXIubG93ICYgMHhGRkZGO1xuXG4gIHZhciBjNDggPSAwLCBjMzIgPSAwLCBjMTYgPSAwLCBjMDAgPSAwO1xuICBjMDAgKz0gYTAwICogYjAwO1xuICBjMTYgKz0gYzAwID4+PiAxNjtcbiAgYzAwICY9IDB4RkZGRjtcbiAgYzE2ICs9IGExNiAqIGIwMDtcbiAgYzMyICs9IGMxNiA+Pj4gMTY7XG4gIGMxNiAmPSAweEZGRkY7XG4gIGMxNiArPSBhMDAgKiBiMTY7XG4gIGMzMiArPSBjMTYgPj4+IDE2O1xuICBjMTYgJj0gMHhGRkZGO1xuICBjMzIgKz0gYTMyICogYjAwO1xuICBjNDggKz0gYzMyID4+PiAxNjtcbiAgYzMyICY9IDB4RkZGRjtcbiAgYzMyICs9IGExNiAqIGIxNjtcbiAgYzQ4ICs9IGMzMiA+Pj4gMTY7XG4gIGMzMiAmPSAweEZGRkY7XG4gIGMzMiArPSBhMDAgKiBiMzI7XG4gIGM0OCArPSBjMzIgPj4+IDE2O1xuICBjMzIgJj0gMHhGRkZGO1xuICBjNDggKz0gYTQ4ICogYjAwICsgYTMyICogYjE2ICsgYTE2ICogYjMyICsgYTAwICogYjQ4O1xuICBjNDggJj0gMHhGRkZGO1xuICByZXR1cm4gZnJvbUJpdHMoKGMxNiA8PCAxNikgfCBjMDAsIChjNDggPDwgMTYpIHwgYzMyLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgcHJvZHVjdCBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbXVsdGlwbHl9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG11bHRpcGxpZXIgTXVsdGlwbGllclxuICogQHJldHVybnMgeyFMb25nfSBQcm9kdWN0XG4gKi9cbkxvbmdQcm90b3R5cGUubXVsID0gTG9uZ1Byb3RvdHlwZS5tdWx0aXBseTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBkaXZpZGVkIGJ5IHRoZSBzcGVjaWZpZWQuIFRoZSByZXN1bHQgaXMgc2lnbmVkIGlmIHRoaXMgTG9uZyBpcyBzaWduZWQgb3JcbiAqICB1bnNpZ25lZCBpZiB0aGlzIExvbmcgaXMgdW5zaWduZWQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxuICogQHJldHVybnMgeyFMb25nfSBRdW90aWVudFxuICovXG5Mb25nUHJvdG90eXBlLmRpdmlkZSA9IGZ1bmN0aW9uIGRpdmlkZShkaXZpc29yKSB7XG4gIGlmICghaXNMb25nKGRpdmlzb3IpKVxuICAgIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XG4gIGlmIChkaXZpc29yLmlzWmVybygpKVxuICAgIHRocm93IEVycm9yKCdkaXZpc2lvbiBieSB6ZXJvJyk7XG5cbiAgLy8gdXNlIHdhc20gc3VwcG9ydCBpZiBwcmVzZW50XG4gIGlmICh3YXNtKSB7XG4gICAgLy8gZ3VhcmQgYWdhaW5zdCBzaWduZWQgZGl2aXNpb24gb3ZlcmZsb3c6IHRoZSBsYXJnZXN0XG4gICAgLy8gbmVnYXRpdmUgbnVtYmVyIC8gLTEgd291bGQgYmUgMSBsYXJnZXIgdGhhbiB0aGUgbGFyZ2VzdFxuICAgIC8vIHBvc2l0aXZlIG51bWJlciwgZHVlIHRvIHR3bydzIGNvbXBsZW1lbnQuXG4gICAgaWYgKCF0aGlzLnVuc2lnbmVkICYmXG4gICAgICB0aGlzLmhpZ2ggPT09IC0weDgwMDAwMDAwICYmXG4gICAgICBkaXZpc29yLmxvdyA9PT0gLTEgJiYgZGl2aXNvci5oaWdoID09PSAtMSkge1xuICAgICAgLy8gYmUgY29uc2lzdGVudCB3aXRoIG5vbi13YXNtIGNvZGUgcGF0aFxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHZhciBsb3cgPSAodGhpcy51bnNpZ25lZCA/IHdhc21bXCJkaXZfdVwiXSA6IHdhc21bXCJkaXZfc1wiXSkoXG4gICAgICB0aGlzLmxvdyxcbiAgICAgIHRoaXMuaGlnaCxcbiAgICAgIGRpdmlzb3IubG93LFxuICAgICAgZGl2aXNvci5oaWdoXG4gICAgKTtcbiAgICByZXR1cm4gZnJvbUJpdHMobG93LCB3YXNtW1wiZ2V0X2hpZ2hcIl0oKSwgdGhpcy51bnNpZ25lZCk7XG4gIH1cblxuICBpZiAodGhpcy5pc1plcm8oKSlcbiAgICByZXR1cm4gdGhpcy51bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcbiAgdmFyIGFwcHJveCwgcmVtLCByZXM7XG4gIGlmICghdGhpcy51bnNpZ25lZCkge1xuICAgIC8vIFRoaXMgc2VjdGlvbiBpcyBvbmx5IHJlbGV2YW50IGZvciBzaWduZWQgbG9uZ3MgYW5kIGlzIGRlcml2ZWQgZnJvbSB0aGVcbiAgICAvLyBjbG9zdXJlIGxpYnJhcnkgYXMgYSB3aG9sZS5cbiAgICBpZiAodGhpcy5lcShNSU5fVkFMVUUpKSB7XG4gICAgICBpZiAoZGl2aXNvci5lcShPTkUpIHx8IGRpdmlzb3IuZXEoTkVHX09ORSkpXG4gICAgICAgIHJldHVybiBNSU5fVkFMVUU7ICAvLyByZWNhbGwgdGhhdCAtTUlOX1ZBTFVFID09IE1JTl9WQUxVRVxuICAgICAgZWxzZSBpZiAoZGl2aXNvci5lcShNSU5fVkFMVUUpKVxuICAgICAgICByZXR1cm4gT05FO1xuICAgICAgZWxzZSB7XG4gICAgICAgIC8vIEF0IHRoaXMgcG9pbnQsIHdlIGhhdmUgfG90aGVyfCA+PSAyLCBzbyB8dGhpcy9vdGhlcnwgPCB8TUlOX1ZBTFVFfC5cbiAgICAgICAgdmFyIGhhbGZUaGlzID0gdGhpcy5zaHIoMSk7XG4gICAgICAgIGFwcHJveCA9IGhhbGZUaGlzLmRpdihkaXZpc29yKS5zaGwoMSk7XG4gICAgICAgIGlmIChhcHByb3guZXEoWkVSTykpIHtcbiAgICAgICAgICByZXR1cm4gZGl2aXNvci5pc05lZ2F0aXZlKCkgPyBPTkUgOiBORUdfT05FO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlbSA9IHRoaXMuc3ViKGRpdmlzb3IubXVsKGFwcHJveCkpO1xuICAgICAgICAgIHJlcyA9IGFwcHJveC5hZGQocmVtLmRpdihkaXZpc29yKSk7XG4gICAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZGl2aXNvci5lcShNSU5fVkFMVUUpKVxuICAgICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XG4gICAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7XG4gICAgICBpZiAoZGl2aXNvci5pc05lZ2F0aXZlKCkpXG4gICAgICAgIHJldHVybiB0aGlzLm5lZygpLmRpdihkaXZpc29yLm5lZygpKTtcbiAgICAgIHJldHVybiB0aGlzLm5lZygpLmRpdihkaXZpc29yKS5uZWcoKTtcbiAgICB9IGVsc2UgaWYgKGRpdmlzb3IuaXNOZWdhdGl2ZSgpKVxuICAgICAgcmV0dXJuIHRoaXMuZGl2KGRpdmlzb3IubmVnKCkpLm5lZygpO1xuICAgIHJlcyA9IFpFUk87XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhlIGFsZ29yaXRobSBiZWxvdyBoYXMgbm90IGJlZW4gbWFkZSBmb3IgdW5zaWduZWQgbG9uZ3MuIEl0J3MgdGhlcmVmb3JlXG4gICAgLy8gcmVxdWlyZWQgdG8gdGFrZSBzcGVjaWFsIGNhcmUgb2YgdGhlIE1TQiBwcmlvciB0byBydW5uaW5nIGl0LlxuICAgIGlmICghZGl2aXNvci51bnNpZ25lZClcbiAgICAgIGRpdmlzb3IgPSBkaXZpc29yLnRvVW5zaWduZWQoKTtcbiAgICBpZiAoZGl2aXNvci5ndCh0aGlzKSlcbiAgICAgIHJldHVybiBVWkVSTztcbiAgICBpZiAoZGl2aXNvci5ndCh0aGlzLnNocnUoMSkpKSAvLyAxNSA+Pj4gMSA9IDcgOyB3aXRoIGRpdmlzb3IgPSA4IDsgdHJ1ZVxuICAgICAgcmV0dXJuIFVPTkU7XG4gICAgcmVzID0gVVpFUk87XG4gIH1cblxuICAvLyBSZXBlYXQgdGhlIGZvbGxvd2luZyB1bnRpbCB0aGUgcmVtYWluZGVyIGlzIGxlc3MgdGhhbiBvdGhlcjogIGZpbmQgYVxuICAvLyBmbG9hdGluZy1wb2ludCB0aGF0IGFwcHJveGltYXRlcyByZW1haW5kZXIgLyBvdGhlciAqZnJvbSBiZWxvdyosIGFkZCB0aGlzXG4gIC8vIGludG8gdGhlIHJlc3VsdCwgYW5kIHN1YnRyYWN0IGl0IGZyb20gdGhlIHJlbWFpbmRlci4gIEl0IGlzIGNyaXRpY2FsIHRoYXRcbiAgLy8gdGhlIGFwcHJveGltYXRlIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgcmVhbCB2YWx1ZSBzbyB0aGF0IHRoZVxuICAvLyByZW1haW5kZXIgbmV2ZXIgYmVjb21lcyBuZWdhdGl2ZS5cbiAgcmVtID0gdGhpcztcbiAgd2hpbGUgKHJlbS5ndGUoZGl2aXNvcikpIHtcbiAgICAvLyBBcHByb3hpbWF0ZSB0aGUgcmVzdWx0IG9mIGRpdmlzaW9uLiBUaGlzIG1heSBiZSBhIGxpdHRsZSBncmVhdGVyIG9yXG4gICAgLy8gc21hbGxlciB0aGFuIHRoZSBhY3R1YWwgdmFsdWUuXG4gICAgYXBwcm94ID0gTWF0aC5tYXgoMSwgTWF0aC5mbG9vcihyZW0udG9OdW1iZXIoKSAvIGRpdmlzb3IudG9OdW1iZXIoKSkpO1xuXG4gICAgLy8gV2Ugd2lsbCB0d2VhayB0aGUgYXBwcm94aW1hdGUgcmVzdWx0IGJ5IGNoYW5naW5nIGl0IGluIHRoZSA0OC10aCBkaWdpdCBvclxuICAgIC8vIHRoZSBzbWFsbGVzdCBub24tZnJhY3Rpb25hbCBkaWdpdCwgd2hpY2hldmVyIGlzIGxhcmdlci5cbiAgICB2YXIgbG9nMiA9IE1hdGguY2VpbChNYXRoLmxvZyhhcHByb3gpIC8gTWF0aC5MTjIpLFxuICAgICAgZGVsdGEgPSAobG9nMiA8PSA0OCkgPyAxIDogcG93X2RibCgyLCBsb2cyIC0gNDgpLFxuXG4gICAgICAvLyBEZWNyZWFzZSB0aGUgYXBwcm94aW1hdGlvbiB1bnRpbCBpdCBpcyBzbWFsbGVyIHRoYW4gdGhlIHJlbWFpbmRlci4gIE5vdGVcbiAgICAgIC8vIHRoYXQgaWYgaXQgaXMgdG9vIGxhcmdlLCB0aGUgcHJvZHVjdCBvdmVyZmxvd3MgYW5kIGlzIG5lZ2F0aXZlLlxuICAgICAgYXBwcm94UmVzID0gZnJvbU51bWJlcihhcHByb3gpLFxuICAgICAgYXBwcm94UmVtID0gYXBwcm94UmVzLm11bChkaXZpc29yKTtcbiAgICB3aGlsZSAoYXBwcm94UmVtLmlzTmVnYXRpdmUoKSB8fCBhcHByb3hSZW0uZ3QocmVtKSkge1xuICAgICAgYXBwcm94IC09IGRlbHRhO1xuICAgICAgYXBwcm94UmVzID0gZnJvbU51bWJlcihhcHByb3gsIHRoaXMudW5zaWduZWQpO1xuICAgICAgYXBwcm94UmVtID0gYXBwcm94UmVzLm11bChkaXZpc29yKTtcbiAgICB9XG5cbiAgICAvLyBXZSBrbm93IHRoZSBhbnN3ZXIgY2FuJ3QgYmUgemVyby4uLiBhbmQgYWN0dWFsbHksIHplcm8gd291bGQgY2F1c2VcbiAgICAvLyBpbmZpbml0ZSByZWN1cnNpb24gc2luY2Ugd2Ugd291bGQgbWFrZSBubyBwcm9ncmVzcy5cbiAgICBpZiAoYXBwcm94UmVzLmlzWmVybygpKVxuICAgICAgYXBwcm94UmVzID0gT05FO1xuXG4gICAgcmVzID0gcmVzLmFkZChhcHByb3hSZXMpO1xuICAgIHJlbSA9IHJlbS5zdWIoYXBwcm94UmVtKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBkaXZpZGVkIGJ5IHRoZSBzcGVjaWZpZWQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZGl2aWRlfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcbiAqIEByZXR1cm5zIHshTG9uZ30gUXVvdGllbnRcbiAqL1xuTG9uZ1Byb3RvdHlwZS5kaXYgPSBMb25nUHJvdG90eXBlLmRpdmlkZTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJlbWFpbmRlclxuICovXG5Mb25nUHJvdG90eXBlLm1vZHVsbyA9IGZ1bmN0aW9uIG1vZHVsbyhkaXZpc29yKSB7XG4gIGlmICghaXNMb25nKGRpdmlzb3IpKVxuICAgIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XG5cbiAgLy8gdXNlIHdhc20gc3VwcG9ydCBpZiBwcmVzZW50XG4gIGlmICh3YXNtKSB7XG4gICAgdmFyIGxvdyA9ICh0aGlzLnVuc2lnbmVkID8gd2FzbVtcInJlbV91XCJdIDogd2FzbVtcInJlbV9zXCJdKShcbiAgICAgIHRoaXMubG93LFxuICAgICAgdGhpcy5oaWdoLFxuICAgICAgZGl2aXNvci5sb3csXG4gICAgICBkaXZpc29yLmhpZ2hcbiAgICApO1xuICAgIHJldHVybiBmcm9tQml0cyhsb3csIHdhc21bXCJnZXRfaGlnaFwiXSgpLCB0aGlzLnVuc2lnbmVkKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLnN1Yih0aGlzLmRpdihkaXZpc29yKS5tdWwoZGl2aXNvcikpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNtb2R1bG99LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxuICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcbiAqL1xuTG9uZ1Byb3RvdHlwZS5tb2QgPSBMb25nUHJvdG90eXBlLm1vZHVsbztcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNtb2R1bG99LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxuICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcbiAqL1xuTG9uZ1Byb3RvdHlwZS5yZW0gPSBMb25nUHJvdG90eXBlLm1vZHVsbztcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIE5PVCBvZiB0aGlzIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKi9cbkxvbmdQcm90b3R5cGUubm90ID0gZnVuY3Rpb24gbm90KCkge1xuICByZXR1cm4gZnJvbUJpdHMofnRoaXMubG93LCB+dGhpcy5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBjb3VudCBsZWFkaW5nIHplcm9zIG9mIHRoaXMgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshbnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLmNvdW50TGVhZGluZ1plcm9zID0gZnVuY3Rpb24gY291bnRMZWFkaW5nWmVyb3MoKSB7XG4gIHJldHVybiB0aGlzLmhpZ2ggPyBNYXRoLmNsejMyKHRoaXMuaGlnaCkgOiBNYXRoLmNsejMyKHRoaXMubG93KSArIDMyO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGNvdW50IGxlYWRpbmcgemVyb3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjY291bnRMZWFkaW5nWmVyb3N9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfVxuICogQHJldHVybnMgeyFudW1iZXJ9XG4gKi9cbkxvbmdQcm90b3R5cGUuY2x6ID0gTG9uZ1Byb3RvdHlwZS5jb3VudExlYWRpbmdaZXJvcztcblxuLyoqXG4gKiBSZXR1cm5zIGNvdW50IHRyYWlsaW5nIHplcm9zIG9mIHRoaXMgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshbnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLmNvdW50VHJhaWxpbmdaZXJvcyA9IGZ1bmN0aW9uIGNvdW50VHJhaWxpbmdaZXJvcygpIHtcbiAgcmV0dXJuIHRoaXMubG93ID8gY3R6MzIodGhpcy5sb3cpIDogY3R6MzIodGhpcy5oaWdoKSArIDMyO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGNvdW50IHRyYWlsaW5nIHplcm9zLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2NvdW50VHJhaWxpbmdaZXJvc30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IW51bWJlcn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5jdHogPSBMb25nUHJvdG90eXBlLmNvdW50VHJhaWxpbmdaZXJvcztcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIEFORCBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqL1xuTG9uZ1Byb3RvdHlwZS5hbmQgPSBmdW5jdGlvbiBhbmQob3RoZXIpIHtcbiAgaWYgKCFpc0xvbmcob3RoZXIpKVxuICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcbiAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93ICYgb3RoZXIubG93LCB0aGlzLmhpZ2ggJiBvdGhlci5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgYml0d2lzZSBPUiBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqL1xuTG9uZ1Byb3RvdHlwZS5vciA9IGZ1bmN0aW9uIG9yKG90aGVyKSB7XG4gIGlmICghaXNMb25nKG90aGVyKSlcbiAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XG4gIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyB8IG90aGVyLmxvdywgdGhpcy5oaWdoIHwgb3RoZXIuaGlnaCwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGJpdHdpc2UgWE9SIG9mIHRoaXMgTG9uZyBhbmQgdGhlIGdpdmVuIG9uZS5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgTG9uZ1xuICogQHJldHVybnMgeyFMb25nfVxuICovXG5Mb25nUHJvdG90eXBlLnhvciA9IGZ1bmN0aW9uIHhvcihvdGhlcikge1xuICBpZiAoIWlzTG9uZyhvdGhlcikpXG4gICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgXiBvdGhlci5sb3csIHRoaXMuaGlnaCBeIG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgc2hpZnRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hpZnRMZWZ0ID0gZnVuY3Rpb24gc2hpZnRMZWZ0KG51bUJpdHMpIHtcbiAgaWYgKGlzTG9uZyhudW1CaXRzKSlcbiAgICBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xuICBpZiAoKG51bUJpdHMgJj0gNjMpID09PSAwKVxuICAgIHJldHVybiB0aGlzO1xuICBlbHNlIGlmIChudW1CaXRzIDwgMzIpXG4gICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93IDw8IG51bUJpdHMsICh0aGlzLmhpZ2ggPDwgbnVtQml0cykgfCAodGhpcy5sb3cgPj4+ICgzMiAtIG51bUJpdHMpKSwgdGhpcy51bnNpZ25lZCk7XG4gIGVsc2VcbiAgICByZXR1cm4gZnJvbUJpdHMoMCwgdGhpcy5sb3cgPDwgKG51bUJpdHMgLSAzMiksIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgc2hpZnRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3NoaWZ0TGVmdH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnNobCA9IExvbmdQcm90b3R5cGUuc2hpZnRMZWZ0O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBhcml0aG1ldGljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hpZnRSaWdodCA9IGZ1bmN0aW9uIHNoaWZ0UmlnaHQobnVtQml0cykge1xuICBpZiAoaXNMb25nKG51bUJpdHMpKVxuICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XG4gIGlmICgobnVtQml0cyAmPSA2MykgPT09IDApXG4gICAgcmV0dXJuIHRoaXM7XG4gIGVsc2UgaWYgKG51bUJpdHMgPCAzMilcbiAgICByZXR1cm4gZnJvbUJpdHMoKHRoaXMubG93ID4+PiBudW1CaXRzKSB8ICh0aGlzLmhpZ2ggPDwgKDMyIC0gbnVtQml0cykpLCB0aGlzLmhpZ2ggPj4gbnVtQml0cywgdGhpcy51bnNpZ25lZCk7XG4gIGVsc2VcbiAgICByZXR1cm4gZnJvbUJpdHModGhpcy5oaWdoID4+IChudW1CaXRzIC0gMzIpLCB0aGlzLmhpZ2ggPj0gMCA/IDAgOiAtMSwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBhcml0aG1ldGljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3NoaWZ0UmlnaHR9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zaHIgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHQ7XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGxvZ2ljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hpZnRSaWdodFVuc2lnbmVkID0gZnVuY3Rpb24gc2hpZnRSaWdodFVuc2lnbmVkKG51bUJpdHMpIHtcbiAgaWYgKGlzTG9uZyhudW1CaXRzKSkgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMCkgcmV0dXJuIHRoaXM7XG4gIGlmIChudW1CaXRzIDwgMzIpIHJldHVybiBmcm9tQml0cygodGhpcy5sb3cgPj4+IG51bUJpdHMpIHwgKHRoaXMuaGlnaCA8PCAoMzIgLSBudW1CaXRzKSksIHRoaXMuaGlnaCA+Pj4gbnVtQml0cywgdGhpcy51bnNpZ25lZCk7XG4gIGlmIChudW1CaXRzID09PSAzMikgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCwgMCwgdGhpcy51bnNpZ25lZCk7XG4gIHJldHVybiBmcm9tQml0cyh0aGlzLmhpZ2ggPj4+IChudW1CaXRzIC0gMzIpLCAwLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGxvZ2ljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3NoaWZ0UmlnaHRVbnNpZ25lZH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnNocnUgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodFVuc2lnbmVkfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hyX3UgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgcm90YXRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gUm90YXRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUucm90YXRlTGVmdCA9IGZ1bmN0aW9uIHJvdGF0ZUxlZnQobnVtQml0cykge1xuICB2YXIgYjtcbiAgaWYgKGlzTG9uZyhudW1CaXRzKSkgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMCkgcmV0dXJuIHRoaXM7XG4gIGlmIChudW1CaXRzID09PSAzMikgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCwgdGhpcy5sb3csIHRoaXMudW5zaWduZWQpO1xuICBpZiAobnVtQml0cyA8IDMyKSB7XG4gICAgYiA9ICgzMiAtIG51bUJpdHMpO1xuICAgIHJldHVybiBmcm9tQml0cygoKHRoaXMubG93IDw8IG51bUJpdHMpIHwgKHRoaXMuaGlnaCA+Pj4gYikpLCAoKHRoaXMuaGlnaCA8PCBudW1CaXRzKSB8ICh0aGlzLmxvdyA+Pj4gYikpLCB0aGlzLnVuc2lnbmVkKTtcbiAgfVxuICBudW1CaXRzIC09IDMyO1xuICBiID0gKDMyIC0gbnVtQml0cyk7XG4gIHJldHVybiBmcm9tQml0cygoKHRoaXMuaGlnaCA8PCBudW1CaXRzKSB8ICh0aGlzLmxvdyA+Pj4gYikpLCAoKHRoaXMubG93IDw8IG51bUJpdHMpIHwgKHRoaXMuaGlnaCA+Pj4gYikpLCB0aGlzLnVuc2lnbmVkKTtcbn1cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHJvdGF0ZWQgdG8gdGhlIGxlZnQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNyb3RhdGVMZWZ0fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gUm90YXRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUucm90bCA9IExvbmdQcm90b3R5cGUucm90YXRlTGVmdDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgcm90YXRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJvdGF0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnJvdGF0ZVJpZ2h0ID0gZnVuY3Rpb24gcm90YXRlUmlnaHQobnVtQml0cykge1xuICB2YXIgYjtcbiAgaWYgKGlzTG9uZyhudW1CaXRzKSkgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMCkgcmV0dXJuIHRoaXM7XG4gIGlmIChudW1CaXRzID09PSAzMikgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCwgdGhpcy5sb3csIHRoaXMudW5zaWduZWQpO1xuICBpZiAobnVtQml0cyA8IDMyKSB7XG4gICAgYiA9ICgzMiAtIG51bUJpdHMpO1xuICAgIHJldHVybiBmcm9tQml0cygoKHRoaXMuaGlnaCA8PCBiKSB8ICh0aGlzLmxvdyA+Pj4gbnVtQml0cykpLCAoKHRoaXMubG93IDw8IGIpIHwgKHRoaXMuaGlnaCA+Pj4gbnVtQml0cykpLCB0aGlzLnVuc2lnbmVkKTtcbiAgfVxuICBudW1CaXRzIC09IDMyO1xuICBiID0gKDMyIC0gbnVtQml0cyk7XG4gIHJldHVybiBmcm9tQml0cygoKHRoaXMubG93IDw8IGIpIHwgKHRoaXMuaGlnaCA+Pj4gbnVtQml0cykpLCAoKHRoaXMuaGlnaCA8PCBiKSB8ICh0aGlzLmxvdyA+Pj4gbnVtQml0cykpLCB0aGlzLnVuc2lnbmVkKTtcbn1cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHJvdGF0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjcm90YXRlUmlnaHR9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBSb3RhdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5yb3RyID0gTG9uZ1Byb3RvdHlwZS5yb3RhdGVSaWdodDtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gc2lnbmVkLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFMb25nfSBTaWduZWQgbG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnRvU2lnbmVkID0gZnVuY3Rpb24gdG9TaWduZWQoKSB7XG4gIGlmICghdGhpcy51bnNpZ25lZClcbiAgICByZXR1cm4gdGhpcztcbiAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93LCB0aGlzLmhpZ2gsIGZhbHNlKTtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBMb25nIHRvIHVuc2lnbmVkLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFMb25nfSBVbnNpZ25lZCBsb25nXG4gKi9cbkxvbmdQcm90b3R5cGUudG9VbnNpZ25lZCA9IGZ1bmN0aW9uIHRvVW5zaWduZWQoKSB7XG4gIGlmICh0aGlzLnVuc2lnbmVkKVxuICAgIHJldHVybiB0aGlzO1xuICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3csIHRoaXMuaGlnaCwgdHJ1ZSk7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBpdHMgYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IGxlIFdoZXRoZXIgbGl0dGxlIG9yIGJpZyBlbmRpYW4sIGRlZmF1bHRzIHRvIGJpZyBlbmRpYW5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshQXJyYXkuPG51bWJlcj59IEJ5dGUgcmVwcmVzZW50YXRpb25cbiAqL1xuTG9uZ1Byb3RvdHlwZS50b0J5dGVzID0gZnVuY3Rpb24gdG9CeXRlcyhsZSkge1xuICByZXR1cm4gbGUgPyB0aGlzLnRvQnl0ZXNMRSgpIDogdGhpcy50b0J5dGVzQkUoKTtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBsaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBMaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cbiAqL1xuTG9uZ1Byb3RvdHlwZS50b0J5dGVzTEUgPSBmdW5jdGlvbiB0b0J5dGVzTEUoKSB7XG4gIHZhciBoaSA9IHRoaXMuaGlnaCxcbiAgICBsbyA9IHRoaXMubG93O1xuICByZXR1cm4gW1xuICAgIGxvICYgMHhmZixcbiAgICBsbyA+Pj4gOCAmIDB4ZmYsXG4gICAgbG8gPj4+IDE2ICYgMHhmZixcbiAgICBsbyA+Pj4gMjQsXG4gICAgaGkgJiAweGZmLFxuICAgIGhpID4+PiA4ICYgMHhmZixcbiAgICBoaSA+Pj4gMTYgJiAweGZmLFxuICAgIGhpID4+PiAyNFxuICBdO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gaXRzIGJpZyBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshQXJyYXkuPG51bWJlcj59IEJpZyBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvblxuICovXG5Mb25nUHJvdG90eXBlLnRvQnl0ZXNCRSA9IGZ1bmN0aW9uIHRvQnl0ZXNCRSgpIHtcbiAgdmFyIGhpID0gdGhpcy5oaWdoLFxuICAgIGxvID0gdGhpcy5sb3c7XG4gIHJldHVybiBbXG4gICAgaGkgPj4+IDI0LFxuICAgIGhpID4+PiAxNiAmIDB4ZmYsXG4gICAgaGkgPj4+IDggJiAweGZmLFxuICAgIGhpICYgMHhmZixcbiAgICBsbyA+Pj4gMjQsXG4gICAgbG8gPj4+IDE2ICYgMHhmZixcbiAgICBsbyA+Pj4gOCAmIDB4ZmYsXG4gICAgbG8gJiAweGZmXG4gIF07XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBMb25nIGZyb20gaXRzIGJ5dGUgcmVwcmVzZW50YXRpb24uXG4gKiBAcGFyYW0geyFBcnJheS48bnVtYmVyPn0gYnl0ZXMgQnl0ZSByZXByZXNlbnRhdGlvblxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQHBhcmFtIHtib29sZWFuPX0gbGUgV2hldGhlciBsaXR0bGUgb3IgYmlnIGVuZGlhbiwgZGVmYXVsdHMgdG8gYmlnIGVuZGlhblxuICogQHJldHVybnMge0xvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tQnl0ZXMgPSBmdW5jdGlvbiBmcm9tQnl0ZXMoYnl0ZXMsIHVuc2lnbmVkLCBsZSkge1xuICByZXR1cm4gbGUgPyBMb25nLmZyb21CeXRlc0xFKGJ5dGVzLCB1bnNpZ25lZCkgOiBMb25nLmZyb21CeXRlc0JFKGJ5dGVzLCB1bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBMb25nIGZyb20gaXRzIGxpdHRsZSBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBieXRlcyBMaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEByZXR1cm5zIHtMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gKi9cbkxvbmcuZnJvbUJ5dGVzTEUgPSBmdW5jdGlvbiBmcm9tQnl0ZXNMRShieXRlcywgdW5zaWduZWQpIHtcbiAgcmV0dXJuIG5ldyBMb25nKFxuICAgIGJ5dGVzWzBdIHxcbiAgICBieXRlc1sxXSA8PCA4IHxcbiAgICBieXRlc1syXSA8PCAxNiB8XG4gICAgYnl0ZXNbM10gPDwgMjQsXG4gICAgYnl0ZXNbNF0gfFxuICAgIGJ5dGVzWzVdIDw8IDggfFxuICAgIGJ5dGVzWzZdIDw8IDE2IHxcbiAgICBieXRlc1s3XSA8PCAyNCxcbiAgICB1bnNpZ25lZFxuICApO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgTG9uZyBmcm9tIGl0cyBiaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXG4gKiBAcGFyYW0geyFBcnJheS48bnVtYmVyPn0gYnl0ZXMgQmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7TG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxuICovXG5Mb25nLmZyb21CeXRlc0JFID0gZnVuY3Rpb24gZnJvbUJ5dGVzQkUoYnl0ZXMsIHVuc2lnbmVkKSB7XG4gIHJldHVybiBuZXcgTG9uZyhcbiAgICBieXRlc1s0XSA8PCAyNCB8XG4gICAgYnl0ZXNbNV0gPDwgMTYgfFxuICAgIGJ5dGVzWzZdIDw8IDggfFxuICAgIGJ5dGVzWzddLFxuICAgIGJ5dGVzWzBdIDw8IDI0IHxcbiAgICBieXRlc1sxXSA8PCAxNiB8XG4gICAgYnl0ZXNbMl0gPDwgOCB8XG4gICAgYnl0ZXNbM10sXG4gICAgdW5zaWduZWRcbiAgKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IExvbmc7XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5leHBvcnQgZW51bSBBcmdUeXBlIHtcbiAgSU5QVVQgPSAwLFxuICBPVVRQVVQgPSAxLFxufVxuIiwgIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5TSVpFX1BSRUZJWF9MRU5HVEggPSBleHBvcnRzLkZJTEVfSURFTlRJRklFUl9MRU5HVEggPSBleHBvcnRzLlNJWkVPRl9JTlQgPSBleHBvcnRzLlNJWkVPRl9TSE9SVCA9IHZvaWQgMDtcbmV4cG9ydHMuU0laRU9GX1NIT1JUID0gMjtcbmV4cG9ydHMuU0laRU9GX0lOVCA9IDQ7XG5leHBvcnRzLkZJTEVfSURFTlRJRklFUl9MRU5HVEggPSA0O1xuZXhwb3J0cy5TSVpFX1BSRUZJWF9MRU5HVEggPSA0O1xuIiwgIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5pc0xpdHRsZUVuZGlhbiA9IGV4cG9ydHMuZmxvYXQ2NCA9IGV4cG9ydHMuZmxvYXQzMiA9IGV4cG9ydHMuaW50MzIgPSB2b2lkIDA7XG5leHBvcnRzLmludDMyID0gbmV3IEludDMyQXJyYXkoMik7XG5leHBvcnRzLmZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KGV4cG9ydHMuaW50MzIuYnVmZmVyKTtcbmV4cG9ydHMuZmxvYXQ2NCA9IG5ldyBGbG9hdDY0QXJyYXkoZXhwb3J0cy5pbnQzMi5idWZmZXIpO1xuZXhwb3J0cy5pc0xpdHRsZUVuZGlhbiA9IG5ldyBVaW50MTZBcnJheShuZXcgVWludDhBcnJheShbMSwgMF0pLmJ1ZmZlcilbMF0gPT09IDE7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkVuY29kaW5nID0gdm9pZCAwO1xudmFyIEVuY29kaW5nO1xuKGZ1bmN0aW9uIChFbmNvZGluZykge1xuICAgIEVuY29kaW5nW0VuY29kaW5nW1wiVVRGOF9CWVRFU1wiXSA9IDFdID0gXCJVVEY4X0JZVEVTXCI7XG4gICAgRW5jb2RpbmdbRW5jb2RpbmdbXCJVVEYxNl9TVFJJTkdcIl0gPSAyXSA9IFwiVVRGMTZfU1RSSU5HXCI7XG59KShFbmNvZGluZyB8fCAoZXhwb3J0cy5FbmNvZGluZyA9IEVuY29kaW5nID0ge30pKTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQnl0ZUJ1ZmZlciA9IHZvaWQgMDtcbmNvbnN0IGNvbnN0YW50c19qc18xID0gcmVxdWlyZShcIi4vY29uc3RhbnRzLmpzXCIpO1xuY29uc3QgdXRpbHNfanNfMSA9IHJlcXVpcmUoXCIuL3V0aWxzLmpzXCIpO1xuY29uc3QgZW5jb2RpbmdfanNfMSA9IHJlcXVpcmUoXCIuL2VuY29kaW5nLmpzXCIpO1xuY2xhc3MgQnl0ZUJ1ZmZlciB7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IEJ5dGVCdWZmZXIgd2l0aCBhIGdpdmVuIGFycmF5IG9mIGJ5dGVzIChgVWludDhBcnJheWApXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoYnl0ZXNfKSB7XG4gICAgICAgIHRoaXMuYnl0ZXNfID0gYnl0ZXNfO1xuICAgICAgICB0aGlzLnBvc2l0aW9uXyA9IDA7XG4gICAgICAgIHRoaXMudGV4dF9kZWNvZGVyXyA9IG5ldyBUZXh0RGVjb2RlcigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW5kIGFsbG9jYXRlIGEgbmV3IEJ5dGVCdWZmZXIgd2l0aCBhIGdpdmVuIHNpemUuXG4gICAgICovXG4gICAgc3RhdGljIGFsbG9jYXRlKGJ5dGVfc2l6ZSkge1xuICAgICAgICByZXR1cm4gbmV3IEJ5dGVCdWZmZXIobmV3IFVpbnQ4QXJyYXkoYnl0ZV9zaXplKSk7XG4gICAgfVxuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLnBvc2l0aW9uXyA9IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdW5kZXJseWluZyBgVWludDhBcnJheWAuXG4gICAgICovXG4gICAgYnl0ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ5dGVzXztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBidWZmZXIncyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBwb3NpdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zaXRpb25fO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGJ1ZmZlcidzIHBvc2l0aW9uLlxuICAgICAqL1xuICAgIHNldFBvc2l0aW9uKHBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMucG9zaXRpb25fID0gcG9zaXRpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgYnVmZmVyJ3MgY2FwYWNpdHkuXG4gICAgICovXG4gICAgY2FwYWNpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ5dGVzXy5sZW5ndGg7XG4gICAgfVxuICAgIHJlYWRJbnQ4KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkVWludDgob2Zmc2V0KSA8PCAyNCA+PiAyNDtcbiAgICB9XG4gICAgcmVhZFVpbnQ4KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ieXRlc19bb2Zmc2V0XTtcbiAgICB9XG4gICAgcmVhZEludDE2KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkVWludDE2KG9mZnNldCkgPDwgMTYgPj4gMTY7XG4gICAgfVxuICAgIHJlYWRVaW50MTYob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ5dGVzX1tvZmZzZXRdIHwgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMV0gPDwgODtcbiAgICB9XG4gICAgcmVhZEludDMyKG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ieXRlc19bb2Zmc2V0XSB8IHRoaXMuYnl0ZXNfW29mZnNldCArIDFdIDw8IDggfCB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAyXSA8PCAxNiB8IHRoaXMuYnl0ZXNfW29mZnNldCArIDNdIDw8IDI0O1xuICAgIH1cbiAgICByZWFkVWludDMyKG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkSW50MzIob2Zmc2V0KSA+Pj4gMDtcbiAgICB9XG4gICAgcmVhZEludDY0KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gQmlnSW50LmFzSW50Tig2NCwgQmlnSW50KHRoaXMucmVhZFVpbnQzMihvZmZzZXQpKSArIChCaWdJbnQodGhpcy5yZWFkVWludDMyKG9mZnNldCArIDQpKSA8PCBCaWdJbnQoMzIpKSk7XG4gICAgfVxuICAgIHJlYWRVaW50NjQob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBCaWdJbnQuYXNVaW50Tig2NCwgQmlnSW50KHRoaXMucmVhZFVpbnQzMihvZmZzZXQpKSArIChCaWdJbnQodGhpcy5yZWFkVWludDMyKG9mZnNldCArIDQpKSA8PCBCaWdJbnQoMzIpKSk7XG4gICAgfVxuICAgIHJlYWRGbG9hdDMyKG9mZnNldCkge1xuICAgICAgICB1dGlsc19qc18xLmludDMyWzBdID0gdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbiAgICAgICAgcmV0dXJuIHV0aWxzX2pzXzEuZmxvYXQzMlswXTtcbiAgICB9XG4gICAgcmVhZEZsb2F0NjQob2Zmc2V0KSB7XG4gICAgICAgIHV0aWxzX2pzXzEuaW50MzJbdXRpbHNfanNfMS5pc0xpdHRsZUVuZGlhbiA/IDAgOiAxXSA9IHRoaXMucmVhZEludDMyKG9mZnNldCk7XG4gICAgICAgIHV0aWxzX2pzXzEuaW50MzJbdXRpbHNfanNfMS5pc0xpdHRsZUVuZGlhbiA/IDEgOiAwXSA9IHRoaXMucmVhZEludDMyKG9mZnNldCArIDQpO1xuICAgICAgICByZXR1cm4gdXRpbHNfanNfMS5mbG9hdDY0WzBdO1xuICAgIH1cbiAgICB3cml0ZUludDgob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgfVxuICAgIHdyaXRlVWludDgob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgfVxuICAgIHdyaXRlSW50MTYob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgICAgIHRoaXMuYnl0ZXNfW29mZnNldCArIDFdID0gdmFsdWUgPj4gODtcbiAgICB9XG4gICAgd3JpdGVVaW50MTYob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgICAgIHRoaXMuYnl0ZXNfW29mZnNldCArIDFdID0gdmFsdWUgPj4gODtcbiAgICB9XG4gICAgd3JpdGVJbnQzMihvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYnl0ZXNfW29mZnNldF0gPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMV0gPSB2YWx1ZSA+PiA4O1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAyXSA9IHZhbHVlID4+IDE2O1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAzXSA9IHZhbHVlID4+IDI0O1xuICAgIH1cbiAgICB3cml0ZVVpbnQzMihvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYnl0ZXNfW29mZnNldF0gPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMV0gPSB2YWx1ZSA+PiA4O1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAyXSA9IHZhbHVlID4+IDE2O1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAzXSA9IHZhbHVlID4+IDI0O1xuICAgIH1cbiAgICB3cml0ZUludDY0KG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKG9mZnNldCwgTnVtYmVyKEJpZ0ludC5hc0ludE4oMzIsIHZhbHVlKSkpO1xuICAgICAgICB0aGlzLndyaXRlSW50MzIob2Zmc2V0ICsgNCwgTnVtYmVyKEJpZ0ludC5hc0ludE4oMzIsIHZhbHVlID4+IEJpZ0ludCgzMikpKSk7XG4gICAgfVxuICAgIHdyaXRlVWludDY0KG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy53cml0ZVVpbnQzMihvZmZzZXQsIE51bWJlcihCaWdJbnQuYXNVaW50TigzMiwgdmFsdWUpKSk7XG4gICAgICAgIHRoaXMud3JpdGVVaW50MzIob2Zmc2V0ICsgNCwgTnVtYmVyKEJpZ0ludC5hc1VpbnROKDMyLCB2YWx1ZSA+PiBCaWdJbnQoMzIpKSkpO1xuICAgIH1cbiAgICB3cml0ZUZsb2F0MzIob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB1dGlsc19qc18xLmZsb2F0MzJbMF0gPSB2YWx1ZTtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKG9mZnNldCwgdXRpbHNfanNfMS5pbnQzMlswXSk7XG4gICAgfVxuICAgIHdyaXRlRmxvYXQ2NChvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIHV0aWxzX2pzXzEuZmxvYXQ2NFswXSA9IHZhbHVlO1xuICAgICAgICB0aGlzLndyaXRlSW50MzIob2Zmc2V0LCB1dGlsc19qc18xLmludDMyW3V0aWxzX2pzXzEuaXNMaXR0bGVFbmRpYW4gPyAwIDogMV0pO1xuICAgICAgICB0aGlzLndyaXRlSW50MzIob2Zmc2V0ICsgNCwgdXRpbHNfanNfMS5pbnQzMlt1dGlsc19qc18xLmlzTGl0dGxlRW5kaWFuID8gMSA6IDBdKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBmaWxlIGlkZW50aWZpZXIuICAgQmVoYXZpb3IgaXMgdW5kZWZpbmVkIGZvciBGbGF0QnVmZmVycyB3aG9zZVxuICAgICAqIHNjaGVtYSBkb2VzIG5vdCBpbmNsdWRlIGEgZmlsZV9pZGVudGlmaWVyIChsaWtlbHkgcG9pbnRzIGF0IHBhZGRpbmcgb3IgdGhlXG4gICAgICogc3RhcnQgb2YgYSB0aGUgcm9vdCB2dGFibGUpLlxuICAgICAqL1xuICAgIGdldEJ1ZmZlcklkZW50aWZpZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLmJ5dGVzXy5sZW5ndGggPCB0aGlzLnBvc2l0aW9uXyArIGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQgK1xuICAgICAgICAgICAgY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogQnl0ZUJ1ZmZlciBpcyB0b28gc2hvcnQgdG8gY29udGFpbiBhbiBpZGVudGlmaWVyLicpO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXN1bHQgPSBcIlwiO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEg7IGkrKykge1xuICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5yZWFkSW50OCh0aGlzLnBvc2l0aW9uXyArIGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQgKyBpKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTG9vayB1cCBhIGZpZWxkIGluIHRoZSB2dGFibGUsIHJldHVybiBhbiBvZmZzZXQgaW50byB0aGUgb2JqZWN0LCBvciAwIGlmIHRoZVxuICAgICAqIGZpZWxkIGlzIG5vdCBwcmVzZW50LlxuICAgICAqL1xuICAgIF9fb2Zmc2V0KGJiX3BvcywgdnRhYmxlX29mZnNldCkge1xuICAgICAgICBjb25zdCB2dGFibGUgPSBiYl9wb3MgLSB0aGlzLnJlYWRJbnQzMihiYl9wb3MpO1xuICAgICAgICByZXR1cm4gdnRhYmxlX29mZnNldCA8IHRoaXMucmVhZEludDE2KHZ0YWJsZSkgPyB0aGlzLnJlYWRJbnQxNih2dGFibGUgKyB2dGFibGVfb2Zmc2V0KSA6IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgYW55IFRhYmxlLWRlcml2ZWQgdHlwZSB0byBwb2ludCB0byB0aGUgdW5pb24gYXQgdGhlIGdpdmVuIG9mZnNldC5cbiAgICAgKi9cbiAgICBfX3VuaW9uKHQsIG9mZnNldCkge1xuICAgICAgICB0LmJiX3BvcyA9IG9mZnNldCArIHRoaXMucmVhZEludDMyKG9mZnNldCk7XG4gICAgICAgIHQuYmIgPSB0aGlzO1xuICAgICAgICByZXR1cm4gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgSmF2YVNjcmlwdCBzdHJpbmcgZnJvbSBVVEYtOCBkYXRhIHN0b3JlZCBpbnNpZGUgdGhlIEZsYXRCdWZmZXIuXG4gICAgICogVGhpcyBhbGxvY2F0ZXMgYSBuZXcgc3RyaW5nIGFuZCBjb252ZXJ0cyB0byB3aWRlIGNoYXJzIHVwb24gZWFjaCBhY2Nlc3MuXG4gICAgICpcbiAgICAgKiBUbyBhdm9pZCB0aGUgY29udmVyc2lvbiB0byBzdHJpbmcsIHBhc3MgRW5jb2RpbmcuVVRGOF9CWVRFUyBhcyB0aGVcbiAgICAgKiBcIm9wdGlvbmFsRW5jb2RpbmdcIiBhcmd1bWVudC4gVGhpcyBpcyB1c2VmdWwgZm9yIGF2b2lkaW5nIGNvbnZlcnNpb24gd2hlblxuICAgICAqIHRoZSBkYXRhIHdpbGwganVzdCBiZSBwYWNrYWdlZCBiYWNrIHVwIGluIGFub3RoZXIgRmxhdEJ1ZmZlciBsYXRlciBvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBvZmZzZXRcbiAgICAgKiBAcGFyYW0gb3B0X2VuY29kaW5nIERlZmF1bHRzIHRvIFVURjE2X1NUUklOR1xuICAgICAqL1xuICAgIF9fc3RyaW5nKG9mZnNldCwgb3B0X2VuY29kaW5nKSB7XG4gICAgICAgIG9mZnNldCArPSB0aGlzLnJlYWRJbnQzMihvZmZzZXQpO1xuICAgICAgICBjb25zdCBsZW5ndGggPSB0aGlzLnJlYWRJbnQzMihvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgKz0gY29uc3RhbnRzX2pzXzEuU0laRU9GX0lOVDtcbiAgICAgICAgY29uc3QgdXRmOGJ5dGVzID0gdGhpcy5ieXRlc18uc3ViYXJyYXkob2Zmc2V0LCBvZmZzZXQgKyBsZW5ndGgpO1xuICAgICAgICBpZiAob3B0X2VuY29kaW5nID09PSBlbmNvZGluZ19qc18xLkVuY29kaW5nLlVURjhfQllURVMpXG4gICAgICAgICAgICByZXR1cm4gdXRmOGJ5dGVzO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50ZXh0X2RlY29kZXJfLmRlY29kZSh1dGY4Ynl0ZXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgdW5pb25zIHRoYXQgY2FuIGNvbnRhaW4gc3RyaW5nIGFzIGl0cyBtZW1iZXIsIGlmIGEgVGFibGUtZGVyaXZlZCB0eXBlIHRoZW4gaW5pdGlhbGl6ZSBpdCxcbiAgICAgKiBpZiBhIHN0cmluZyB0aGVuIHJldHVybiBhIG5ldyBvbmVcbiAgICAgKlxuICAgICAqIFdBUk5JTkc6IHN0cmluZ3MgYXJlIGltbXV0YWJsZSBpbiBKUyBzbyB3ZSBjYW4ndCBjaGFuZ2UgdGhlIHN0cmluZyB0aGF0IHRoZSB1c2VyIGdhdmUgdXMsIHRoaXNcbiAgICAgKiBtYWtlcyB0aGUgYmVoYXZpb3VyIG9mIF9fdW5pb25fd2l0aF9zdHJpbmcgZGlmZmVyZW50IGNvbXBhcmVkIHRvIF9fdW5pb25cbiAgICAgKi9cbiAgICBfX3VuaW9uX3dpdGhfc3RyaW5nKG8sIG9mZnNldCkge1xuICAgICAgICBpZiAodHlwZW9mIG8gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fX3N0cmluZyhvZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9fdW5pb24obywgb2Zmc2V0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmUgdGhlIHJlbGF0aXZlIG9mZnNldCBzdG9yZWQgYXQgXCJvZmZzZXRcIlxuICAgICAqL1xuICAgIF9faW5kaXJlY3Qob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyB0aGlzLnJlYWRJbnQzMihvZmZzZXQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHN0YXJ0IG9mIGRhdGEgb2YgYSB2ZWN0b3Igd2hvc2Ugb2Zmc2V0IGlzIHN0b3JlZCBhdCBcIm9mZnNldFwiIGluIHRoaXMgb2JqZWN0LlxuICAgICAqL1xuICAgIF9fdmVjdG9yKG9mZnNldCkge1xuICAgICAgICByZXR1cm4gb2Zmc2V0ICsgdGhpcy5yZWFkSW50MzIob2Zmc2V0KSArIGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQ7IC8vIGRhdGEgc3RhcnRzIGFmdGVyIHRoZSBsZW5ndGhcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBsZW5ndGggb2YgYSB2ZWN0b3Igd2hvc2Ugb2Zmc2V0IGlzIHN0b3JlZCBhdCBcIm9mZnNldFwiIGluIHRoaXMgb2JqZWN0LlxuICAgICAqL1xuICAgIF9fdmVjdG9yX2xlbihvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZEludDMyKG9mZnNldCArIHRoaXMucmVhZEludDMyKG9mZnNldCkpO1xuICAgIH1cbiAgICBfX2hhc19pZGVudGlmaWVyKGlkZW50KSB7XG4gICAgICAgIGlmIChpZGVudC5sZW5ndGggIT0gY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogZmlsZSBpZGVudGlmaWVyIG11c3QgYmUgbGVuZ3RoICcgK1xuICAgICAgICAgICAgICAgIGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoaWRlbnQuY2hhckNvZGVBdChpKSAhPSB0aGlzLnJlYWRJbnQ4KHRoaXMucG9zaXRpb24oKSArIGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQgKyBpKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBoZWxwZXIgZnVuY3Rpb24gZm9yIGdlbmVyYXRpbmcgbGlzdCBmb3Igb2JqIGFwaVxuICAgICAqL1xuICAgIGNyZWF0ZVNjYWxhckxpc3QobGlzdEFjY2Vzc29yLCBsaXN0TGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHJldCA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RMZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgY29uc3QgdmFsID0gbGlzdEFjY2Vzc29yKGkpO1xuICAgICAgICAgICAgaWYgKHZhbCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldC5wdXNoKHZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBoZWxwZXIgZnVuY3Rpb24gZm9yIGdlbmVyYXRpbmcgbGlzdCBmb3Igb2JqIGFwaVxuICAgICAqIEBwYXJhbSBsaXN0QWNjZXNzb3IgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIGFuIGluZGV4IGFuZCByZXR1cm4gZGF0YSBhdCB0aGF0IGluZGV4XG4gICAgICogQHBhcmFtIGxpc3RMZW5ndGggbGlzdExlbmd0aFxuICAgICAqIEBwYXJhbSByZXMgcmVzdWx0IGxpc3RcbiAgICAgKi9cbiAgICBjcmVhdGVPYmpMaXN0KGxpc3RBY2Nlc3NvciwgbGlzdExlbmd0aCkge1xuICAgICAgICBjb25zdCByZXQgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0TGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbCA9IGxpc3RBY2Nlc3NvcihpKTtcbiAgICAgICAgICAgIGlmICh2YWwgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXQucHVzaCh2YWwudW5wYWNrKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxufVxuZXhwb3J0cy5CeXRlQnVmZmVyID0gQnl0ZUJ1ZmZlcjtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQnVpbGRlciA9IHZvaWQgMDtcbmNvbnN0IGJ5dGVfYnVmZmVyX2pzXzEgPSByZXF1aXJlKFwiLi9ieXRlLWJ1ZmZlci5qc1wiKTtcbmNvbnN0IGNvbnN0YW50c19qc18xID0gcmVxdWlyZShcIi4vY29uc3RhbnRzLmpzXCIpO1xuY2xhc3MgQnVpbGRlciB7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgRmxhdEJ1ZmZlckJ1aWxkZXIuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0X2luaXRpYWxfc2l6ZSkge1xuICAgICAgICAvKiogTWluaW11bSBhbGlnbm1lbnQgZW5jb3VudGVyZWQgc28gZmFyLiAqL1xuICAgICAgICB0aGlzLm1pbmFsaWduID0gMTtcbiAgICAgICAgLyoqIFRoZSB2dGFibGUgZm9yIHRoZSBjdXJyZW50IHRhYmxlLiAqL1xuICAgICAgICB0aGlzLnZ0YWJsZSA9IG51bGw7XG4gICAgICAgIC8qKiBUaGUgYW1vdW50IG9mIGZpZWxkcyB3ZSdyZSBhY3R1YWxseSB1c2luZy4gKi9cbiAgICAgICAgdGhpcy52dGFibGVfaW5fdXNlID0gMDtcbiAgICAgICAgLyoqIFdoZXRoZXIgd2UgYXJlIGN1cnJlbnRseSBzZXJpYWxpemluZyBhIHRhYmxlLiAqL1xuICAgICAgICB0aGlzLmlzTmVzdGVkID0gZmFsc2U7XG4gICAgICAgIC8qKiBTdGFydGluZyBvZmZzZXQgb2YgdGhlIGN1cnJlbnQgc3RydWN0L3RhYmxlLiAqL1xuICAgICAgICB0aGlzLm9iamVjdF9zdGFydCA9IDA7XG4gICAgICAgIC8qKiBMaXN0IG9mIG9mZnNldHMgb2YgYWxsIHZ0YWJsZXMuICovXG4gICAgICAgIHRoaXMudnRhYmxlcyA9IFtdO1xuICAgICAgICAvKiogRm9yIHRoZSBjdXJyZW50IHZlY3RvciBiZWluZyBidWlsdC4gKi9cbiAgICAgICAgdGhpcy52ZWN0b3JfbnVtX2VsZW1zID0gMDtcbiAgICAgICAgLyoqIEZhbHNlIG9taXRzIGRlZmF1bHQgdmFsdWVzIGZyb20gdGhlIHNlcmlhbGl6ZWQgZGF0YSAqL1xuICAgICAgICB0aGlzLmZvcmNlX2RlZmF1bHRzID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RyaW5nX21hcHMgPSBudWxsO1xuICAgICAgICB0aGlzLnRleHRfZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpO1xuICAgICAgICBsZXQgaW5pdGlhbF9zaXplO1xuICAgICAgICBpZiAoIW9wdF9pbml0aWFsX3NpemUpIHtcbiAgICAgICAgICAgIGluaXRpYWxfc2l6ZSA9IDEwMjQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpbml0aWFsX3NpemUgPSBvcHRfaW5pdGlhbF9zaXplO1xuICAgICAgICB9XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAdHlwZSB7Qnl0ZUJ1ZmZlcn1cbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuYmIgPSBieXRlX2J1ZmZlcl9qc18xLkJ5dGVCdWZmZXIuYWxsb2NhdGUoaW5pdGlhbF9zaXplKTtcbiAgICAgICAgdGhpcy5zcGFjZSA9IGluaXRpYWxfc2l6ZTtcbiAgICB9XG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuYmIuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5zcGFjZSA9IHRoaXMuYmIuY2FwYWNpdHkoKTtcbiAgICAgICAgdGhpcy5taW5hbGlnbiA9IDE7XG4gICAgICAgIHRoaXMudnRhYmxlID0gbnVsbDtcbiAgICAgICAgdGhpcy52dGFibGVfaW5fdXNlID0gMDtcbiAgICAgICAgdGhpcy5pc05lc3RlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLm9iamVjdF9zdGFydCA9IDA7XG4gICAgICAgIHRoaXMudnRhYmxlcyA9IFtdO1xuICAgICAgICB0aGlzLnZlY3Rvcl9udW1fZWxlbXMgPSAwO1xuICAgICAgICB0aGlzLmZvcmNlX2RlZmF1bHRzID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RyaW5nX21hcHMgPSBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbiBvcmRlciB0byBzYXZlIHNwYWNlLCBmaWVsZHMgdGhhdCBhcmUgc2V0IHRvIHRoZWlyIGRlZmF1bHQgdmFsdWVcbiAgICAgKiBkb24ndCBnZXQgc2VyaWFsaXplZCBpbnRvIHRoZSBidWZmZXIuIEZvcmNpbmcgZGVmYXVsdHMgcHJvdmlkZXMgYVxuICAgICAqIHdheSB0byBtYW51YWxseSBkaXNhYmxlIHRoaXMgb3B0aW1pemF0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIGZvcmNlRGVmYXVsdHMgdHJ1ZSBhbHdheXMgc2VyaWFsaXplcyBkZWZhdWx0IHZhbHVlc1xuICAgICAqL1xuICAgIGZvcmNlRGVmYXVsdHMoZm9yY2VEZWZhdWx0cykge1xuICAgICAgICB0aGlzLmZvcmNlX2RlZmF1bHRzID0gZm9yY2VEZWZhdWx0cztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBCeXRlQnVmZmVyIHJlcHJlc2VudGluZyB0aGUgRmxhdEJ1ZmZlci4gT25seSBjYWxsIHRoaXMgYWZ0ZXIgeW91J3ZlXG4gICAgICogY2FsbGVkIGZpbmlzaCgpLiBUaGUgYWN0dWFsIGRhdGEgc3RhcnRzIGF0IHRoZSBCeXRlQnVmZmVyJ3MgY3VycmVudCBwb3NpdGlvbixcbiAgICAgKiBub3QgbmVjZXNzYXJpbHkgYXQgMC5cbiAgICAgKi9cbiAgICBkYXRhQnVmZmVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5iYjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBieXRlcyByZXByZXNlbnRpbmcgdGhlIEZsYXRCdWZmZXIuIE9ubHkgY2FsbCB0aGlzIGFmdGVyIHlvdSd2ZVxuICAgICAqIGNhbGxlZCBmaW5pc2goKS5cbiAgICAgKi9cbiAgICBhc1VpbnQ4QXJyYXkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJiLmJ5dGVzKCkuc3ViYXJyYXkodGhpcy5iYi5wb3NpdGlvbigpLCB0aGlzLmJiLnBvc2l0aW9uKCkgKyB0aGlzLm9mZnNldCgpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHJlcGFyZSB0byB3cml0ZSBhbiBlbGVtZW50IG9mIGBzaXplYCBhZnRlciBgYWRkaXRpb25hbF9ieXRlc2AgaGF2ZSBiZWVuXG4gICAgICogd3JpdHRlbiwgZS5nLiBpZiB5b3Ugd3JpdGUgYSBzdHJpbmcsIHlvdSBuZWVkIHRvIGFsaWduIHN1Y2ggdGhlIGludCBsZW5ndGhcbiAgICAgKiBmaWVsZCBpcyBhbGlnbmVkIHRvIDQgYnl0ZXMsIGFuZCB0aGUgc3RyaW5nIGRhdGEgZm9sbG93cyBpdCBkaXJlY3RseS4gSWYgYWxsXG4gICAgICogeW91IG5lZWQgdG8gZG8gaXMgYWxpZ25tZW50LCBgYWRkaXRpb25hbF9ieXRlc2Agd2lsbCBiZSAwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNpemUgVGhpcyBpcyB0aGUgb2YgdGhlIG5ldyBlbGVtZW50IHRvIHdyaXRlXG4gICAgICogQHBhcmFtIGFkZGl0aW9uYWxfYnl0ZXMgVGhlIHBhZGRpbmcgc2l6ZVxuICAgICAqL1xuICAgIHByZXAoc2l6ZSwgYWRkaXRpb25hbF9ieXRlcykge1xuICAgICAgICAvLyBUcmFjayB0aGUgYmlnZ2VzdCB0aGluZyB3ZSd2ZSBldmVyIGFsaWduZWQgdG8uXG4gICAgICAgIGlmIChzaXplID4gdGhpcy5taW5hbGlnbikge1xuICAgICAgICAgICAgdGhpcy5taW5hbGlnbiA9IHNpemU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRmluZCB0aGUgYW1vdW50IG9mIGFsaWdubWVudCBuZWVkZWQgc3VjaCB0aGF0IGBzaXplYCBpcyBwcm9wZXJseVxuICAgICAgICAvLyBhbGlnbmVkIGFmdGVyIGBhZGRpdGlvbmFsX2J5dGVzYFxuICAgICAgICBjb25zdCBhbGlnbl9zaXplID0gKCh+KHRoaXMuYmIuY2FwYWNpdHkoKSAtIHRoaXMuc3BhY2UgKyBhZGRpdGlvbmFsX2J5dGVzKSkgKyAxKSAmIChzaXplIC0gMSk7XG4gICAgICAgIC8vIFJlYWxsb2NhdGUgdGhlIGJ1ZmZlciBpZiBuZWVkZWQuXG4gICAgICAgIHdoaWxlICh0aGlzLnNwYWNlIDwgYWxpZ25fc2l6ZSArIHNpemUgKyBhZGRpdGlvbmFsX2J5dGVzKSB7XG4gICAgICAgICAgICBjb25zdCBvbGRfYnVmX3NpemUgPSB0aGlzLmJiLmNhcGFjaXR5KCk7XG4gICAgICAgICAgICB0aGlzLmJiID0gQnVpbGRlci5ncm93Qnl0ZUJ1ZmZlcih0aGlzLmJiKTtcbiAgICAgICAgICAgIHRoaXMuc3BhY2UgKz0gdGhpcy5iYi5jYXBhY2l0eSgpIC0gb2xkX2J1Zl9zaXplO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGFkKGFsaWduX3NpemUpO1xuICAgIH1cbiAgICBwYWQoYnl0ZV9zaXplKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZV9zaXplOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMuYmIud3JpdGVJbnQ4KC0tdGhpcy5zcGFjZSwgMCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgd3JpdGVJbnQ4KHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYmIud3JpdGVJbnQ4KHRoaXMuc3BhY2UgLT0gMSwgdmFsdWUpO1xuICAgIH1cbiAgICB3cml0ZUludDE2KHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYmIud3JpdGVJbnQxNih0aGlzLnNwYWNlIC09IDIsIHZhbHVlKTtcbiAgICB9XG4gICAgd3JpdGVJbnQzMih2YWx1ZSkge1xuICAgICAgICB0aGlzLmJiLndyaXRlSW50MzIodGhpcy5zcGFjZSAtPSA0LCB2YWx1ZSk7XG4gICAgfVxuICAgIHdyaXRlSW50NjQodmFsdWUpIHtcbiAgICAgICAgdGhpcy5iYi53cml0ZUludDY0KHRoaXMuc3BhY2UgLT0gOCwgdmFsdWUpO1xuICAgIH1cbiAgICB3cml0ZUZsb2F0MzIodmFsdWUpIHtcbiAgICAgICAgdGhpcy5iYi53cml0ZUZsb2F0MzIodGhpcy5zcGFjZSAtPSA0LCB2YWx1ZSk7XG4gICAgfVxuICAgIHdyaXRlRmxvYXQ2NCh2YWx1ZSkge1xuICAgICAgICB0aGlzLmJiLndyaXRlRmxvYXQ2NCh0aGlzLnNwYWNlIC09IDgsIHZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIGBpbnQ4YCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGBpbnQ4YCB0byBhZGQgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBhZGRJbnQ4KHZhbHVlKSB7XG4gICAgICAgIHRoaXMucHJlcCgxLCAwKTtcbiAgICAgICAgdGhpcy53cml0ZUludDgodmFsdWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYW4gYGludDE2YCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGBpbnQxNmAgdG8gYWRkIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgYWRkSW50MTYodmFsdWUpIHtcbiAgICAgICAgdGhpcy5wcmVwKDIsIDApO1xuICAgICAgICB0aGlzLndyaXRlSW50MTYodmFsdWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYW4gYGludDMyYCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGBpbnQzMmAgdG8gYWRkIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgYWRkSW50MzIodmFsdWUpIHtcbiAgICAgICAgdGhpcy5wcmVwKDQsIDApO1xuICAgICAgICB0aGlzLndyaXRlSW50MzIodmFsdWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYW4gYGludDY0YCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGBpbnQ2NGAgdG8gYWRkIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgYWRkSW50NjQodmFsdWUpIHtcbiAgICAgICAgdGhpcy5wcmVwKDgsIDApO1xuICAgICAgICB0aGlzLndyaXRlSW50NjQodmFsdWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYSBgZmxvYXQzMmAgdG8gdGhlIGJ1ZmZlciwgcHJvcGVybHkgYWxpZ25lZCwgYW5kIGdyb3dzIHRoZSBidWZmZXIgKGlmIG5lY2Vzc2FyeSkuXG4gICAgICogQHBhcmFtIHZhbHVlIFRoZSBgZmxvYXQzMmAgdG8gYWRkIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgYWRkRmxvYXQzMih2YWx1ZSkge1xuICAgICAgICB0aGlzLnByZXAoNCwgMCk7XG4gICAgICAgIHRoaXMud3JpdGVGbG9hdDMyKHZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgYGZsb2F0NjRgIHRvIHRoZSBidWZmZXIsIHByb3Blcmx5IGFsaWduZWQsIGFuZCBncm93cyB0aGUgYnVmZmVyIChpZiBuZWNlc3NhcnkpLlxuICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYGZsb2F0NjRgIHRvIGFkZCB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGFkZEZsb2F0NjQodmFsdWUpIHtcbiAgICAgICAgdGhpcy5wcmVwKDgsIDApO1xuICAgICAgICB0aGlzLndyaXRlRmxvYXQ2NCh2YWx1ZSk7XG4gICAgfVxuICAgIGFkZEZpZWxkSW50OCh2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRJbnQ4KHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRGaWVsZEludDE2KHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgdmFsdWUgIT0gZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmFkZEludDE2KHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRGaWVsZEludDMyKHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgdmFsdWUgIT0gZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmFkZEludDMyKHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRGaWVsZEludDY0KHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgdmFsdWUgIT09IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRJbnQ2NCh2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLnNsb3Qodm9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkRmllbGRGbG9hdDMyKHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgdmFsdWUgIT0gZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmFkZEZsb2F0MzIodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFkZEZpZWxkRmxvYXQ2NCh2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRGbG9hdDY0KHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRGaWVsZE9mZnNldCh2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRPZmZzZXQodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0cnVjdHMgYXJlIHN0b3JlZCBpbmxpbmUsIHNvIG5vdGhpbmcgYWRkaXRpb25hbCBpcyBiZWluZyBhZGRlZC4gYGRgIGlzIGFsd2F5cyAwLlxuICAgICAqL1xuICAgIGFkZEZpZWxkU3RydWN0KHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgaWYgKHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5uZXN0ZWQodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0cnVjdHVyZXMgYXJlIGFsd2F5cyBzdG9yZWQgaW5saW5lLCB0aGV5IG5lZWQgdG8gYmUgY3JlYXRlZCByaWdodFxuICAgICAqIHdoZXJlIHRoZXkncmUgdXNlZC4gIFlvdSdsbCBnZXQgdGhpcyBhc3NlcnRpb24gZmFpbHVyZSBpZiB5b3VcbiAgICAgKiBjcmVhdGVkIGl0IGVsc2V3aGVyZS5cbiAgICAgKi9cbiAgICBuZXN0ZWQob2JqKSB7XG4gICAgICAgIGlmIChvYmogIT0gdGhpcy5vZmZzZXQoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRmxhdEJ1ZmZlcnM6IHN0cnVjdCBtdXN0IGJlIHNlcmlhbGl6ZWQgaW5saW5lLicpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNob3VsZCBub3QgYmUgY3JlYXRpbmcgYW55IG90aGVyIG9iamVjdCwgc3RyaW5nIG9yIHZlY3RvclxuICAgICAqIHdoaWxlIGFuIG9iamVjdCBpcyBiZWluZyBjb25zdHJ1Y3RlZFxuICAgICAqL1xuICAgIG5vdE5lc3RlZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNOZXN0ZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZsYXRCdWZmZXJzOiBvYmplY3Qgc2VyaWFsaXphdGlvbiBtdXN0IG5vdCBiZSBuZXN0ZWQuJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBjdXJyZW50IHZ0YWJsZSBhdCBgdm9mZnNldGAgdG8gdGhlIGN1cnJlbnQgbG9jYXRpb24gaW4gdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBzbG90KHZvZmZzZXQpIHtcbiAgICAgICAgaWYgKHRoaXMudnRhYmxlICE9PSBudWxsKVxuICAgICAgICAgICAgdGhpcy52dGFibGVbdm9mZnNldF0gPSB0aGlzLm9mZnNldCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBPZmZzZXQgcmVsYXRpdmUgdG8gdGhlIGVuZCBvZiB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIG9mZnNldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmIuY2FwYWNpdHkoKSAtIHRoaXMuc3BhY2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERvdWJsZXMgdGhlIHNpemUgb2YgdGhlIGJhY2tpbmcgQnl0ZUJ1ZmZlciBhbmQgY29waWVzIHRoZSBvbGQgZGF0YSB0b3dhcmRzXG4gICAgICogdGhlIGVuZCBvZiB0aGUgbmV3IGJ1ZmZlciAoc2luY2Ugd2UgYnVpbGQgdGhlIGJ1ZmZlciBiYWNrd2FyZHMpLlxuICAgICAqXG4gICAgICogQHBhcmFtIGJiIFRoZSBjdXJyZW50IGJ1ZmZlciB3aXRoIHRoZSBleGlzdGluZyBkYXRhXG4gICAgICogQHJldHVybnMgQSBuZXcgYnl0ZSBidWZmZXIgd2l0aCB0aGUgb2xkIGRhdGEgY29waWVkXG4gICAgICogdG8gaXQuIFRoZSBkYXRhIGlzIGxvY2F0ZWQgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyLlxuICAgICAqXG4gICAgICogdWludDhBcnJheS5zZXQoKSBmb3JtYWxseSB0YWtlcyB7QXJyYXk8bnVtYmVyPnxBcnJheUJ1ZmZlclZpZXd9LCBzbyB0byBwYXNzXG4gICAgICogaXQgYSB1aW50OEFycmF5IHdlIG5lZWQgdG8gc3VwcHJlc3MgdGhlIHR5cGUgY2hlY2s6XG4gICAgICogQHN1cHByZXNzIHtjaGVja1R5cGVzfVxuICAgICAqL1xuICAgIHN0YXRpYyBncm93Qnl0ZUJ1ZmZlcihiYikge1xuICAgICAgICBjb25zdCBvbGRfYnVmX3NpemUgPSBiYi5jYXBhY2l0eSgpO1xuICAgICAgICAvLyBFbnN1cmUgd2UgZG9uJ3QgZ3JvdyBiZXlvbmQgd2hhdCBmaXRzIGluIGFuIGludC5cbiAgICAgICAgaWYgKG9sZF9idWZfc2l6ZSAmIDB4QzAwMDAwMDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmxhdEJ1ZmZlcnM6IGNhbm5vdCBncm93IGJ1ZmZlciBiZXlvbmQgMiBnaWdhYnl0ZXMuJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3X2J1Zl9zaXplID0gb2xkX2J1Zl9zaXplIDw8IDE7XG4gICAgICAgIGNvbnN0IG5iYiA9IGJ5dGVfYnVmZmVyX2pzXzEuQnl0ZUJ1ZmZlci5hbGxvY2F0ZShuZXdfYnVmX3NpemUpO1xuICAgICAgICBuYmIuc2V0UG9zaXRpb24obmV3X2J1Zl9zaXplIC0gb2xkX2J1Zl9zaXplKTtcbiAgICAgICAgbmJiLmJ5dGVzKCkuc2V0KGJiLmJ5dGVzKCksIG5ld19idWZfc2l6ZSAtIG9sZF9idWZfc2l6ZSk7XG4gICAgICAgIHJldHVybiBuYmI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZHMgb24gb2Zmc2V0LCByZWxhdGl2ZSB0byB3aGVyZSBpdCB3aWxsIGJlIHdyaXR0ZW4uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgdG8gYWRkLlxuICAgICAqL1xuICAgIGFkZE9mZnNldChvZmZzZXQpIHtcbiAgICAgICAgdGhpcy5wcmVwKGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQsIDApOyAvLyBFbnN1cmUgYWxpZ25tZW50IGlzIGFscmVhZHkgZG9uZS5cbiAgICAgICAgdGhpcy53cml0ZUludDMyKHRoaXMub2Zmc2V0KCkgLSBvZmZzZXQgKyBjb25zdGFudHNfanNfMS5TSVpFT0ZfSU5UKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgZW5jb2RpbmcgYSBuZXcgb2JqZWN0IGluIHRoZSBidWZmZXIuICBVc2VycyB3aWxsIG5vdCB1c3VhbGx5IG5lZWQgdG9cbiAgICAgKiBjYWxsIHRoaXMgZGlyZWN0bHkuIFRoZSBGbGF0QnVmZmVycyBjb21waWxlciB3aWxsIGdlbmVyYXRlIGhlbHBlciBtZXRob2RzXG4gICAgICogdGhhdCBjYWxsIHRoaXMgbWV0aG9kIGludGVybmFsbHkuXG4gICAgICovXG4gICAgc3RhcnRPYmplY3QobnVtZmllbGRzKSB7XG4gICAgICAgIHRoaXMubm90TmVzdGVkKCk7XG4gICAgICAgIGlmICh0aGlzLnZ0YWJsZSA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnZ0YWJsZSA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudnRhYmxlX2luX3VzZSA9IG51bWZpZWxkcztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1maWVsZHM7IGkrKykge1xuICAgICAgICAgICAgdGhpcy52dGFibGVbaV0gPSAwOyAvLyBUaGlzIHdpbGwgcHVzaCBhZGRpdGlvbmFsIGVsZW1lbnRzIGFzIG5lZWRlZFxuICAgICAgICB9XG4gICAgICAgIHRoaXMuaXNOZXN0ZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLm9iamVjdF9zdGFydCA9IHRoaXMub2Zmc2V0KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmlzaCBvZmYgd3JpdGluZyB0aGUgb2JqZWN0IHRoYXQgaXMgdW5kZXIgY29uc3RydWN0aW9uLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIG9mZnNldCB0byB0aGUgb2JqZWN0IGluc2lkZSBgZGF0YUJ1ZmZlcmBcbiAgICAgKi9cbiAgICBlbmRPYmplY3QoKSB7XG4gICAgICAgIGlmICh0aGlzLnZ0YWJsZSA9PSBudWxsIHx8ICF0aGlzLmlzTmVzdGVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXRCdWZmZXJzOiBlbmRPYmplY3QgY2FsbGVkIHdpdGhvdXQgc3RhcnRPYmplY3QnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFkZEludDMyKDApO1xuICAgICAgICBjb25zdCB2dGFibGVsb2MgPSB0aGlzLm9mZnNldCgpO1xuICAgICAgICAvLyBUcmltIHRyYWlsaW5nIHplcm9lcy5cbiAgICAgICAgbGV0IGkgPSB0aGlzLnZ0YWJsZV9pbl91c2UgLSAxO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZW1wdHlcbiAgICAgICAgZm9yICg7IGkgPj0gMCAmJiB0aGlzLnZ0YWJsZVtpXSA9PSAwOyBpLS0pIHsgfVxuICAgICAgICBjb25zdCB0cmltbWVkX3NpemUgPSBpICsgMTtcbiAgICAgICAgLy8gV3JpdGUgb3V0IHRoZSBjdXJyZW50IHZ0YWJsZS5cbiAgICAgICAgZm9yICg7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAvLyBPZmZzZXQgcmVsYXRpdmUgdG8gdGhlIHN0YXJ0IG9mIHRoZSB0YWJsZS5cbiAgICAgICAgICAgIHRoaXMuYWRkSW50MTYodGhpcy52dGFibGVbaV0gIT0gMCA/IHZ0YWJsZWxvYyAtIHRoaXMudnRhYmxlW2ldIDogMCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhbmRhcmRfZmllbGRzID0gMjsgLy8gVGhlIGZpZWxkcyBiZWxvdzpcbiAgICAgICAgdGhpcy5hZGRJbnQxNih2dGFibGVsb2MgLSB0aGlzLm9iamVjdF9zdGFydCk7XG4gICAgICAgIGNvbnN0IGxlbiA9ICh0cmltbWVkX3NpemUgKyBzdGFuZGFyZF9maWVsZHMpICogY29uc3RhbnRzX2pzXzEuU0laRU9GX1NIT1JUO1xuICAgICAgICB0aGlzLmFkZEludDE2KGxlbik7XG4gICAgICAgIC8vIFNlYXJjaCBmb3IgYW4gZXhpc3RpbmcgdnRhYmxlIHRoYXQgbWF0Y2hlcyB0aGUgY3VycmVudCBvbmUuXG4gICAgICAgIGxldCBleGlzdGluZ192dGFibGUgPSAwO1xuICAgICAgICBjb25zdCB2dDEgPSB0aGlzLnNwYWNlO1xuICAgICAgICBvdXRlcl9sb29wOiBmb3IgKGkgPSAwOyBpIDwgdGhpcy52dGFibGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCB2dDIgPSB0aGlzLmJiLmNhcGFjaXR5KCkgLSB0aGlzLnZ0YWJsZXNbaV07XG4gICAgICAgICAgICBpZiAobGVuID09IHRoaXMuYmIucmVhZEludDE2KHZ0MikpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gY29uc3RhbnRzX2pzXzEuU0laRU9GX1NIT1JUOyBqIDwgbGVuOyBqICs9IGNvbnN0YW50c19qc18xLlNJWkVPRl9TSE9SVCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5iYi5yZWFkSW50MTYodnQxICsgaikgIT0gdGhpcy5iYi5yZWFkSW50MTYodnQyICsgaikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyX2xvb3A7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZXhpc3RpbmdfdnRhYmxlID0gdGhpcy52dGFibGVzW2ldO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChleGlzdGluZ192dGFibGUpIHtcbiAgICAgICAgICAgIC8vIEZvdW5kIGEgbWF0Y2g6XG4gICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGN1cnJlbnQgdnRhYmxlLlxuICAgICAgICAgICAgdGhpcy5zcGFjZSA9IHRoaXMuYmIuY2FwYWNpdHkoKSAtIHZ0YWJsZWxvYztcbiAgICAgICAgICAgIC8vIFBvaW50IHRhYmxlIHRvIGV4aXN0aW5nIHZ0YWJsZS5cbiAgICAgICAgICAgIHRoaXMuYmIud3JpdGVJbnQzMih0aGlzLnNwYWNlLCBleGlzdGluZ192dGFibGUgLSB2dGFibGVsb2MpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gTm8gbWF0Y2g6XG4gICAgICAgICAgICAvLyBBZGQgdGhlIGxvY2F0aW9uIG9mIHRoZSBjdXJyZW50IHZ0YWJsZSB0byB0aGUgbGlzdCBvZiB2dGFibGVzLlxuICAgICAgICAgICAgdGhpcy52dGFibGVzLnB1c2godGhpcy5vZmZzZXQoKSk7XG4gICAgICAgICAgICAvLyBQb2ludCB0YWJsZSB0byBjdXJyZW50IHZ0YWJsZS5cbiAgICAgICAgICAgIHRoaXMuYmIud3JpdGVJbnQzMih0aGlzLmJiLmNhcGFjaXR5KCkgLSB2dGFibGVsb2MsIHRoaXMub2Zmc2V0KCkgLSB2dGFibGVsb2MpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaXNOZXN0ZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHZ0YWJsZWxvYztcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluYWxpemUgYSBidWZmZXIsIHBvaXRpbmcgdG8gdGhlIGdpdmVuIGByb290X3RhYmxlYC5cbiAgICAgKi9cbiAgICBmaW5pc2gocm9vdF90YWJsZSwgb3B0X2ZpbGVfaWRlbnRpZmllciwgb3B0X3NpemVfcHJlZml4KSB7XG4gICAgICAgIGNvbnN0IHNpemVfcHJlZml4ID0gb3B0X3NpemVfcHJlZml4ID8gY29uc3RhbnRzX2pzXzEuU0laRV9QUkVGSVhfTEVOR1RIIDogMDtcbiAgICAgICAgaWYgKG9wdF9maWxlX2lkZW50aWZpZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVfaWRlbnRpZmllciA9IG9wdF9maWxlX2lkZW50aWZpZXI7XG4gICAgICAgICAgICB0aGlzLnByZXAodGhpcy5taW5hbGlnbiwgY29uc3RhbnRzX2pzXzEuU0laRU9GX0lOVCArXG4gICAgICAgICAgICAgICAgY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSCArIHNpemVfcHJlZml4KTtcbiAgICAgICAgICAgIGlmIChmaWxlX2lkZW50aWZpZXIubGVuZ3RoICE9IGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGbGF0QnVmZmVyczogZmlsZSBpZGVudGlmaWVyIG11c3QgYmUgbGVuZ3RoICcgK1xuICAgICAgICAgICAgICAgICAgICBjb25zdGFudHNfanNfMS5GSUxFX0lERU5USUZJRVJfTEVOR1RIKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBjb25zdGFudHNfanNfMS5GSUxFX0lERU5USUZJRVJfTEVOR1RIIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLndyaXRlSW50OChmaWxlX2lkZW50aWZpZXIuY2hhckNvZGVBdChpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wcmVwKHRoaXMubWluYWxpZ24sIGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQgKyBzaXplX3ByZWZpeCk7XG4gICAgICAgIHRoaXMuYWRkT2Zmc2V0KHJvb3RfdGFibGUpO1xuICAgICAgICBpZiAoc2l6ZV9wcmVmaXgpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkSW50MzIodGhpcy5iYi5jYXBhY2l0eSgpIC0gdGhpcy5zcGFjZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5iYi5zZXRQb3NpdGlvbih0aGlzLnNwYWNlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluYWxpemUgYSBzaXplIHByZWZpeGVkIGJ1ZmZlciwgcG9pbnRpbmcgdG8gdGhlIGdpdmVuIGByb290X3RhYmxlYC5cbiAgICAgKi9cbiAgICBmaW5pc2hTaXplUHJlZml4ZWQocm9vdF90YWJsZSwgb3B0X2ZpbGVfaWRlbnRpZmllcikge1xuICAgICAgICB0aGlzLmZpbmlzaChyb290X3RhYmxlLCBvcHRfZmlsZV9pZGVudGlmaWVyLCB0cnVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhpcyBjaGVja3MgYSByZXF1aXJlZCBmaWVsZCBoYXMgYmVlbiBzZXQgaW4gYSBnaXZlbiB0YWJsZSB0aGF0IGhhc1xuICAgICAqIGp1c3QgYmVlbiBjb25zdHJ1Y3RlZC5cbiAgICAgKi9cbiAgICByZXF1aXJlZEZpZWxkKHRhYmxlLCBmaWVsZCkge1xuICAgICAgICBjb25zdCB0YWJsZV9zdGFydCA9IHRoaXMuYmIuY2FwYWNpdHkoKSAtIHRhYmxlO1xuICAgICAgICBjb25zdCB2dGFibGVfc3RhcnQgPSB0YWJsZV9zdGFydCAtIHRoaXMuYmIucmVhZEludDMyKHRhYmxlX3N0YXJ0KTtcbiAgICAgICAgY29uc3Qgb2sgPSBmaWVsZCA8IHRoaXMuYmIucmVhZEludDE2KHZ0YWJsZV9zdGFydCkgJiZcbiAgICAgICAgICAgIHRoaXMuYmIucmVhZEludDE2KHZ0YWJsZV9zdGFydCArIGZpZWxkKSAhPSAwO1xuICAgICAgICAvLyBJZiB0aGlzIGZhaWxzLCB0aGUgY2FsbGVyIHdpbGwgc2hvdyB3aGF0IGZpZWxkIG5lZWRzIHRvIGJlIHNldC5cbiAgICAgICAgaWYgKCFvaykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRmxhdEJ1ZmZlcnM6IGZpZWxkICcgKyBmaWVsZCArICcgbXVzdCBiZSBzZXQnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCBhIG5ldyBhcnJheS92ZWN0b3Igb2Ygb2JqZWN0cy4gIFVzZXJzIHVzdWFsbHkgd2lsbCBub3QgY2FsbFxuICAgICAqIHRoaXMgZGlyZWN0bHkuIFRoZSBGbGF0QnVmZmVycyBjb21waWxlciB3aWxsIGNyZWF0ZSBhIHN0YXJ0L2VuZFxuICAgICAqIG1ldGhvZCBmb3IgdmVjdG9yIHR5cGVzIGluIGdlbmVyYXRlZCBjb2RlLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVsZW1fc2l6ZSBUaGUgc2l6ZSBvZiBlYWNoIGVsZW1lbnQgaW4gdGhlIGFycmF5XG4gICAgICogQHBhcmFtIG51bV9lbGVtcyBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBhcnJheVxuICAgICAqIEBwYXJhbSBhbGlnbm1lbnQgVGhlIGFsaWdubWVudCBvZiB0aGUgYXJyYXlcbiAgICAgKi9cbiAgICBzdGFydFZlY3RvcihlbGVtX3NpemUsIG51bV9lbGVtcywgYWxpZ25tZW50KSB7XG4gICAgICAgIHRoaXMubm90TmVzdGVkKCk7XG4gICAgICAgIHRoaXMudmVjdG9yX251bV9lbGVtcyA9IG51bV9lbGVtcztcbiAgICAgICAgdGhpcy5wcmVwKGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQsIGVsZW1fc2l6ZSAqIG51bV9lbGVtcyk7XG4gICAgICAgIHRoaXMucHJlcChhbGlnbm1lbnQsIGVsZW1fc2l6ZSAqIG51bV9lbGVtcyk7IC8vIEp1c3QgaW4gY2FzZSBhbGlnbm1lbnQgPiBpbnQuXG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmlzaCBvZmYgdGhlIGNyZWF0aW9uIG9mIGFuIGFycmF5IGFuZCBhbGwgaXRzIGVsZW1lbnRzLiBUaGUgYXJyYXkgbXVzdCBiZVxuICAgICAqIGNyZWF0ZWQgd2l0aCBgc3RhcnRWZWN0b3JgLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIG9mZnNldCBhdCB3aGljaCB0aGUgbmV3bHkgY3JlYXRlZCBhcnJheVxuICAgICAqIHN0YXJ0cy5cbiAgICAgKi9cbiAgICBlbmRWZWN0b3IoKSB7XG4gICAgICAgIHRoaXMud3JpdGVJbnQzMih0aGlzLnZlY3Rvcl9udW1fZWxlbXMpO1xuICAgICAgICByZXR1cm4gdGhpcy5vZmZzZXQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRW5jb2RlIHRoZSBzdHJpbmcgYHNgIGluIHRoZSBidWZmZXIgdXNpbmcgVVRGLTguIElmIHRoZSBzdHJpbmcgcGFzc2VkIGhhc1xuICAgICAqIGFscmVhZHkgYmVlbiBzZWVuLCB3ZSByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgYWxyZWFkeSB3cml0dGVuIHN0cmluZ1xuICAgICAqXG4gICAgICogQHBhcmFtIHMgVGhlIHN0cmluZyB0byBlbmNvZGVcbiAgICAgKiBAcmV0dXJuIFRoZSBvZmZzZXQgaW4gdGhlIGJ1ZmZlciB3aGVyZSB0aGUgZW5jb2RlZCBzdHJpbmcgc3RhcnRzXG4gICAgICovXG4gICAgY3JlYXRlU2hhcmVkU3RyaW5nKHMpIHtcbiAgICAgICAgaWYgKCFzKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuc3RyaW5nX21hcHMpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyaW5nX21hcHMgPSBuZXcgTWFwKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RyaW5nX21hcHMuaGFzKHMpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdHJpbmdfbWFwcy5nZXQocyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5jcmVhdGVTdHJpbmcocyk7XG4gICAgICAgIHRoaXMuc3RyaW5nX21hcHMuc2V0KHMsIG9mZnNldCk7XG4gICAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVuY29kZSB0aGUgc3RyaW5nIGBzYCBpbiB0aGUgYnVmZmVyIHVzaW5nIFVURi04LiBJZiBhIFVpbnQ4QXJyYXkgaXMgcGFzc2VkXG4gICAgICogaW5zdGVhZCBvZiBhIHN0cmluZywgaXQgaXMgYXNzdW1lZCB0byBjb250YWluIHZhbGlkIFVURi04IGVuY29kZWQgZGF0YS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzIFRoZSBzdHJpbmcgdG8gZW5jb2RlXG4gICAgICogQHJldHVybiBUaGUgb2Zmc2V0IGluIHRoZSBidWZmZXIgd2hlcmUgdGhlIGVuY29kZWQgc3RyaW5nIHN0YXJ0c1xuICAgICAqL1xuICAgIGNyZWF0ZVN0cmluZyhzKSB7XG4gICAgICAgIGlmIChzID09PSBudWxsIHx8IHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHV0Zjg7XG4gICAgICAgIGlmIChzIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgICAgICAgICAgdXRmOCA9IHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB1dGY4ID0gdGhpcy50ZXh0X2VuY29kZXIuZW5jb2RlKHMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYWRkSW50OCgwKTtcbiAgICAgICAgdGhpcy5zdGFydFZlY3RvcigxLCB1dGY4Lmxlbmd0aCwgMSk7XG4gICAgICAgIHRoaXMuYmIuc2V0UG9zaXRpb24odGhpcy5zcGFjZSAtPSB1dGY4Lmxlbmd0aCk7XG4gICAgICAgIHRoaXMuYmIuYnl0ZXMoKS5zZXQodXRmOCwgdGhpcy5zcGFjZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVuZFZlY3RvcigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBieXRlIHZlY3Rvci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2IFRoZSBieXRlcyB0byBhZGRcbiAgICAgKiBAcmV0dXJucyBUaGUgb2Zmc2V0IGluIHRoZSBidWZmZXIgd2hlcmUgdGhlIGJ5dGUgdmVjdG9yIHN0YXJ0c1xuICAgICAqL1xuICAgIGNyZWF0ZUJ5dGVWZWN0b3Iodikge1xuICAgICAgICBpZiAodiA9PT0gbnVsbCB8fCB2ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RhcnRWZWN0b3IoMSwgdi5sZW5ndGgsIDEpO1xuICAgICAgICB0aGlzLmJiLnNldFBvc2l0aW9uKHRoaXMuc3BhY2UgLT0gdi5sZW5ndGgpO1xuICAgICAgICB0aGlzLmJiLmJ5dGVzKCkuc2V0KHYsIHRoaXMuc3BhY2UpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbmRWZWN0b3IoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gcGFjayBhbiBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIG9mZnNldCBvZiBvYmpcbiAgICAgKi9cbiAgICBjcmVhdGVPYmplY3RPZmZzZXQob2JqKSB7XG4gICAgICAgIGlmIChvYmogPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlU3RyaW5nKG9iaik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqLnBhY2sodGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gcGFjayBhIGxpc3Qgb2Ygb2JqZWN0XG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBsaXN0IG9mIG9mZnNldHMgb2YgZWFjaCBub24gbnVsbCBvYmplY3RcbiAgICAgKi9cbiAgICBjcmVhdGVPYmplY3RPZmZzZXRMaXN0KGxpc3QpIHtcbiAgICAgICAgY29uc3QgcmV0ID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgY29uc3QgdmFsID0gbGlzdFtpXTtcbiAgICAgICAgICAgIGlmICh2YWwgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXQucHVzaCh0aGlzLmNyZWF0ZU9iamVjdE9mZnNldCh2YWwpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZsYXRCdWZmZXJzOiBBcmd1bWVudCBmb3IgY3JlYXRlT2JqZWN0T2Zmc2V0TGlzdCBjYW5ub3QgY29udGFpbiBudWxsLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICAgIGNyZWF0ZVN0cnVjdE9mZnNldExpc3QobGlzdCwgc3RhcnRGdW5jKSB7XG4gICAgICAgIHN0YXJ0RnVuYyh0aGlzLCBsaXN0Lmxlbmd0aCk7XG4gICAgICAgIHRoaXMuY3JlYXRlT2JqZWN0T2Zmc2V0TGlzdChsaXN0LnNsaWNlKCkucmV2ZXJzZSgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5kVmVjdG9yKCk7XG4gICAgfVxufVxuZXhwb3J0cy5CdWlsZGVyID0gQnVpbGRlcjtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQnl0ZUJ1ZmZlciA9IGV4cG9ydHMuQnVpbGRlciA9IGV4cG9ydHMuRW5jb2RpbmcgPSBleHBvcnRzLmlzTGl0dGxlRW5kaWFuID0gZXhwb3J0cy5mbG9hdDY0ID0gZXhwb3J0cy5mbG9hdDMyID0gZXhwb3J0cy5pbnQzMiA9IGV4cG9ydHMuU0laRV9QUkVGSVhfTEVOR1RIID0gZXhwb3J0cy5GSUxFX0lERU5USUZJRVJfTEVOR1RIID0gZXhwb3J0cy5TSVpFT0ZfSU5UID0gZXhwb3J0cy5TSVpFT0ZfU0hPUlQgPSB2b2lkIDA7XG52YXIgY29uc3RhbnRzX2pzXzEgPSByZXF1aXJlKFwiLi9jb25zdGFudHMuanNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJTSVpFT0ZfU0hPUlRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbnN0YW50c19qc18xLlNJWkVPRl9TSE9SVDsgfSB9KTtcbnZhciBjb25zdGFudHNfanNfMiA9IHJlcXVpcmUoXCIuL2NvbnN0YW50cy5qc1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlNJWkVPRl9JTlRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbnN0YW50c19qc18yLlNJWkVPRl9JTlQ7IH0gfSk7XG52YXIgY29uc3RhbnRzX2pzXzMgPSByZXF1aXJlKFwiLi9jb25zdGFudHMuanNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJGSUxFX0lERU5USUZJRVJfTEVOR1RIXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdGFudHNfanNfMy5GSUxFX0lERU5USUZJRVJfTEVOR1RIOyB9IH0pO1xudmFyIGNvbnN0YW50c19qc180ID0gcmVxdWlyZShcIi4vY29uc3RhbnRzLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiU0laRV9QUkVGSVhfTEVOR1RIXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdGFudHNfanNfNC5TSVpFX1BSRUZJWF9MRU5HVEg7IH0gfSk7XG52YXIgdXRpbHNfanNfMSA9IHJlcXVpcmUoXCIuL3V0aWxzLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiaW50MzJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHV0aWxzX2pzXzEuaW50MzI7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJmbG9hdDMyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB1dGlsc19qc18xLmZsb2F0MzI7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJmbG9hdDY0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB1dGlsc19qc18xLmZsb2F0NjQ7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpc0xpdHRsZUVuZGlhblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdXRpbHNfanNfMS5pc0xpdHRsZUVuZGlhbjsgfSB9KTtcbnZhciBlbmNvZGluZ19qc18xID0gcmVxdWlyZShcIi4vZW5jb2RpbmcuanNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFbmNvZGluZ1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZW5jb2RpbmdfanNfMS5FbmNvZGluZzsgfSB9KTtcbnZhciBidWlsZGVyX2pzXzEgPSByZXF1aXJlKFwiLi9idWlsZGVyLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQnVpbGRlclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYnVpbGRlcl9qc18xLkJ1aWxkZXI7IH0gfSk7XG52YXIgYnl0ZV9idWZmZXJfanNfMSA9IHJlcXVpcmUoXCIuL2J5dGUtYnVmZmVyLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQnl0ZUJ1ZmZlclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYnl0ZV9idWZmZXJfanNfMS5CeXRlQnVmZmVyOyB9IH0pO1xuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBBcmdUeXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2FyZy10eXBlLmpzJztcblxuZXhwb3J0IGNsYXNzIEFyZ1R5cGVBbmRJbmRleCB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogQXJnVHlwZUFuZEluZGV4IHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc0FyZ1R5cGVBbmRJbmRleChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogQXJnVHlwZUFuZEluZGV4KTogQXJnVHlwZUFuZEluZGV4IHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgQXJnVHlwZUFuZEluZGV4KCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzQXJnVHlwZUFuZEluZGV4KGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBBcmdUeXBlQW5kSW5kZXgpOiBBcmdUeXBlQW5kSW5kZXgge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBBcmdUeXBlQW5kSW5kZXgoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGFyZ1R5cGUoKTogQXJnVHlwZSB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50OCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBBcmdUeXBlLklOUFVUO1xuICB9XG5cbiAgaW5kZXgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEFyZ1R5cGVBbmRJbmRleChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRBcmdUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGFyZ1R5cGU6IEFyZ1R5cGUpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50OCgwLCBhcmdUeXBlLCBBcmdUeXBlLklOUFVUKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRJbmRleChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbmRleDogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDEsIGluZGV4LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRBcmdUeXBlQW5kSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUFyZ1R5cGVBbmRJbmRleChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBhcmdUeXBlOiBBcmdUeXBlLCBpbmRleDogbnVtYmVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBBcmdUeXBlQW5kSW5kZXguc3RhcnRBcmdUeXBlQW5kSW5kZXgoYnVpbGRlcik7XG4gICAgQXJnVHlwZUFuZEluZGV4LmFkZEFyZ1R5cGUoYnVpbGRlciwgYXJnVHlwZSk7XG4gICAgQXJnVHlwZUFuZEluZGV4LmFkZEluZGV4KGJ1aWxkZXIsIGluZGV4KTtcbiAgICByZXR1cm4gQXJnVHlwZUFuZEluZGV4LmVuZEFyZ1R5cGVBbmRJbmRleChidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuZXhwb3J0IGVudW0gQXR0cmlidXRlVHlwZSB7XG4gIFVOREVGSU5FRCA9IDAsXG4gIEZMT0FUID0gMSxcbiAgSU5UID0gMixcbiAgU1RSSU5HID0gMyxcbiAgVEVOU09SID0gNCxcbiAgR1JBUEggPSA1LFxuICBGTE9BVFMgPSA2LFxuICBJTlRTID0gNyxcbiAgU1RSSU5HUyA9IDgsXG4gIFRFTlNPUlMgPSA5LFxuICBHUkFQSFMgPSAxMCxcbiAgU1BBUlNFX1RFTlNPUiA9IDExLFxuICBTUEFSU0VfVEVOU09SUyA9IDEyLFxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuZXhwb3J0IGVudW0gTm9kZVR5cGUge1xuICBQcmltaXRpdmUgPSAwLFxuICBGdXNlZCA9IDEsXG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IEF0dHJpYnV0ZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9hdHRyaWJ1dGUuanMnO1xuaW1wb3J0IHsgTm9kZVR5cGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvbm9kZS10eXBlLmpzJztcblxuZXhwb3J0IGNsYXNzIE5vZGUge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IE5vZGUge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzTm9kZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTm9kZSk6IE5vZGUge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzTm9kZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTm9kZSk6IE5vZGUge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBuYW1lKCk6IHN0cmluZyB8IG51bGw7XG4gIG5hbWUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgbmFtZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGRvY1N0cmluZygpOiBzdHJpbmcgfCBudWxsO1xuICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgZG9tYWluKCk6IHN0cmluZyB8IG51bGw7XG4gIGRvbWFpbihvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBkb21haW4ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBzaW5jZVZlcnNpb24oKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGluZGV4KCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZFVpbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgb3BUeXBlKCk6IHN0cmluZyB8IG51bGw7XG4gIG9wVHlwZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBvcFR5cGUob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgdHlwZSgpOiBOb2RlVHlwZSB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IE5vZGVUeXBlLlByaW1pdGl2ZTtcbiAgfVxuXG4gIGV4ZWN1dGlvblByb3ZpZGVyVHlwZSgpOiBzdHJpbmcgfCBudWxsO1xuICBleGVjdXRpb25Qcm92aWRlclR5cGUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZXhlY3V0aW9uUHJvdmlkZXJUeXBlKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGlucHV0cyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICBpbnB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5O1xuICBpbnB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGlucHV0c0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgb3V0cHV0cyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICBvdXRwdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheTtcbiAgb3V0cHV0cyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgb3V0cHV0c0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgYXR0cmlidXRlcyhpbmRleDogbnVtYmVyLCBvYmo/OiBBdHRyaWJ1dGUpOiBBdHRyaWJ1dGUgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjQpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgQXR0cmlidXRlKCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIGF0dHJpYnV0ZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGlucHV0QXJnQ291bnRzKGluZGV4OiBudW1iZXIpOiBudW1iZXIgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSA6IDA7XG4gIH1cblxuICBpbnB1dEFyZ0NvdW50c0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgaW5wdXRBcmdDb3VudHNBcnJheSgpOiBJbnQzMkFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IG5ldyBJbnQzMkFycmF5KFxuICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnVmZmVyLFxuICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnl0ZU9mZnNldCArIHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgICB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBpbXBsaWNpdElucHV0cyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICBpbXBsaWNpdElucHV0cyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gIGltcGxpY2l0SW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBpbXBsaWNpdElucHV0c0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0Tm9kZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgxMyk7XG4gIH1cblxuICBzdGF0aWMgYWRkTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG5hbWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREb21haW4oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9tYWluT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDIsIGRvbWFpbk9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkU2luY2VWZXJzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHNpbmNlVmVyc2lvbjogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDMsIHNpbmNlVmVyc2lvbiwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaW5kZXg6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMig0LCBpbmRleCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkT3BUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG9wVHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg1LCBvcFR5cGVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZFR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdHlwZTogTm9kZVR5cGUpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoNiwgdHlwZSwgTm9kZVR5cGUuUHJpbWl0aXZlKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRFeGVjdXRpb25Qcm92aWRlclR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZXhlY3V0aW9uUHJvdmlkZXJUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDcsIGV4ZWN1dGlvblByb3ZpZGVyVHlwZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW5wdXRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGlucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg4LCBpbnB1dHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUlucHV0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbnB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZE91dHB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3V0cHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg5LCBvdXRwdXRzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVPdXRwdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE91dHB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZEF0dHJpYnV0ZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgYXR0cmlidXRlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxMCwgYXR0cmlidXRlc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlQXR0cmlidXRlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRBdHRyaWJ1dGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRJbnB1dEFyZ0NvdW50cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnB1dEFyZ0NvdW50c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxMSwgaW5wdXRBcmdDb3VudHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUlucHV0QXJnQ291bnRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdIHwgSW50MzJBcnJheSk6IGZsYXRidWZmZXJzLk9mZnNldDtcbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFRoaXMgVWludDhBcnJheSBvdmVybG9hZCB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIGZ1dHVyZS5cbiAgICovXG4gIHN0YXRpYyBjcmVhdGVJbnB1dEFyZ0NvdW50c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBudW1iZXJbXSB8IFVpbnQ4QXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQ7XG4gIHN0YXRpYyBjcmVhdGVJbnB1dEFyZ0NvdW50c1ZlY3RvcihcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIGRhdGE6IG51bWJlcltdIHwgSW50MzJBcnJheSB8IFVpbnQ4QXJyYXksXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkSW50MzIoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydElucHV0QXJnQ291bnRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRJbXBsaWNpdElucHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbXBsaWNpdElucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxMiwgaW1wbGljaXRJbnB1dHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUltcGxpY2l0SW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEltcGxpY2l0SW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmROb2RlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVOb2RlKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGRvY1N0cmluZ09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGRvbWFpbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIHNpbmNlVmVyc2lvbjogbnVtYmVyLFxuICAgIGluZGV4OiBudW1iZXIsXG4gICAgb3BUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgdHlwZTogTm9kZVR5cGUsXG4gICAgZXhlY3V0aW9uUHJvdmlkZXJUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgaW5wdXRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgb3V0cHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGF0dHJpYnV0ZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBpbnB1dEFyZ0NvdW50c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGltcGxpY2l0SW5wdXRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgTm9kZS5zdGFydE5vZGUoYnVpbGRlcik7XG4gICAgTm9kZS5hZGROYW1lKGJ1aWxkZXIsIG5hbWVPZmZzZXQpO1xuICAgIE5vZGUuYWRkRG9jU3RyaW5nKGJ1aWxkZXIsIGRvY1N0cmluZ09mZnNldCk7XG4gICAgTm9kZS5hZGREb21haW4oYnVpbGRlciwgZG9tYWluT2Zmc2V0KTtcbiAgICBOb2RlLmFkZFNpbmNlVmVyc2lvbihidWlsZGVyLCBzaW5jZVZlcnNpb24pO1xuICAgIE5vZGUuYWRkSW5kZXgoYnVpbGRlciwgaW5kZXgpO1xuICAgIE5vZGUuYWRkT3BUeXBlKGJ1aWxkZXIsIG9wVHlwZU9mZnNldCk7XG4gICAgTm9kZS5hZGRUeXBlKGJ1aWxkZXIsIHR5cGUpO1xuICAgIE5vZGUuYWRkRXhlY3V0aW9uUHJvdmlkZXJUeXBlKGJ1aWxkZXIsIGV4ZWN1dGlvblByb3ZpZGVyVHlwZU9mZnNldCk7XG4gICAgTm9kZS5hZGRJbnB1dHMoYnVpbGRlciwgaW5wdXRzT2Zmc2V0KTtcbiAgICBOb2RlLmFkZE91dHB1dHMoYnVpbGRlciwgb3V0cHV0c09mZnNldCk7XG4gICAgTm9kZS5hZGRBdHRyaWJ1dGVzKGJ1aWxkZXIsIGF0dHJpYnV0ZXNPZmZzZXQpO1xuICAgIE5vZGUuYWRkSW5wdXRBcmdDb3VudHMoYnVpbGRlciwgaW5wdXRBcmdDb3VudHNPZmZzZXQpO1xuICAgIE5vZGUuYWRkSW1wbGljaXRJbnB1dHMoYnVpbGRlciwgaW1wbGljaXRJbnB1dHNPZmZzZXQpO1xuICAgIHJldHVybiBOb2RlLmVuZE5vZGUoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuZXhwb3J0IGNsYXNzIEVkZ2VFbmQge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IEVkZ2VFbmQge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBub2RlSW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5iYiEucmVhZFVpbnQzMih0aGlzLmJiX3Bvcyk7XG4gIH1cblxuICBzcmNBcmdJbmRleCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyA0KTtcbiAgfVxuXG4gIGRzdEFyZ0luZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIDgpO1xuICB9XG5cbiAgc3RhdGljIHNpemVPZigpOiBudW1iZXIge1xuICAgIHJldHVybiAxMjtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVFZGdlRW5kKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgbm9kZV9pbmRleDogbnVtYmVyLFxuICAgIHNyY19hcmdfaW5kZXg6IG51bWJlcixcbiAgICBkc3RfYXJnX2luZGV4OiBudW1iZXIsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5wcmVwKDQsIDEyKTtcbiAgICBidWlsZGVyLndyaXRlSW50MzIoZHN0X2FyZ19pbmRleCk7XG4gICAgYnVpbGRlci53cml0ZUludDMyKHNyY19hcmdfaW5kZXgpO1xuICAgIGJ1aWxkZXIud3JpdGVJbnQzMihub2RlX2luZGV4KTtcbiAgICByZXR1cm4gYnVpbGRlci5vZmZzZXQoKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBFZGdlRW5kIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2VkZ2UtZW5kLmpzJztcblxuZXhwb3J0IGNsYXNzIE5vZGVFZGdlIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBOb2RlRWRnZSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNOb2RlRWRnZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTm9kZUVkZ2UpOiBOb2RlRWRnZSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE5vZGVFZGdlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzTm9kZUVkZ2UoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE5vZGVFZGdlKTogTm9kZUVkZ2Uge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlRWRnZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgbm9kZUluZGV4KCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBpbnB1dEVkZ2VzKGluZGV4OiBudW1iZXIsIG9iaj86IEVkZ2VFbmQpOiBFZGdlRW5kIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgRWRnZUVuZCgpKS5fX2luaXQodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiAxMiwgdGhpcy5iYiEpXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBpbnB1dEVkZ2VzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG91dHB1dEVkZ2VzKGluZGV4OiBudW1iZXIsIG9iaj86IEVkZ2VFbmQpOiBFZGdlRW5kIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgRWRnZUVuZCgpKS5fX2luaXQodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiAxMiwgdGhpcy5iYiEpXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBvdXRwdXRFZGdlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnROb2RlRWRnZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgzKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGROb2RlSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUluZGV4OiBudW1iZXIpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMCwgbm9kZUluZGV4LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRJbnB1dEVkZ2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGlucHV0RWRnZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgaW5wdXRFZGdlc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbnB1dEVkZ2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDEyLCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkT3V0cHV0RWRnZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3V0cHV0RWRnZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgb3V0cHV0RWRnZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0T3V0cHV0RWRnZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoMTIsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmROb2RlRWRnZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlTm9kZUVkZ2UoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBub2RlSW5kZXg6IG51bWJlcixcbiAgICBpbnB1dEVkZ2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgb3V0cHV0RWRnZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBOb2RlRWRnZS5zdGFydE5vZGVFZGdlKGJ1aWxkZXIpO1xuICAgIE5vZGVFZGdlLmFkZE5vZGVJbmRleChidWlsZGVyLCBub2RlSW5kZXgpO1xuICAgIE5vZGVFZGdlLmFkZElucHV0RWRnZXMoYnVpbGRlciwgaW5wdXRFZGdlc09mZnNldCk7XG4gICAgTm9kZUVkZ2UuYWRkT3V0cHV0RWRnZXMoYnVpbGRlciwgb3V0cHV0RWRnZXNPZmZzZXQpO1xuICAgIHJldHVybiBOb2RlRWRnZS5lbmROb2RlRWRnZShidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG4vKipcbiAqIG5vZGVzIHRvIGNvbnNpZGVyIGZvciBhIHJ1bnRpbWUgb3B0aW1pemF0aW9uXG4gKiBzZWUgY29ycmVzcG9uZGluZyB0eXBlIGluIG9ubnhydW50aW1lL2NvcmUvZ3JhcGgvcnVudGltZV9vcHRpbWl6YXRpb25fcmVjb3JkLmhcbiAqL1xuZXhwb3J0IGNsYXNzIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IE5vZGVzVG9PcHRpbWl6ZUluZGljZXMge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzTm9kZXNUb09wdGltaXplSW5kaWNlcyhcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzLFxuICApOiBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgTm9kZXNUb09wdGltaXplSW5kaWNlcygpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc05vZGVzVG9PcHRpbWl6ZUluZGljZXMoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogTm9kZXNUb09wdGltaXplSW5kaWNlcyxcbiAgKTogTm9kZXNUb09wdGltaXplSW5kaWNlcyB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIG5vZGVJbmRpY2VzKGluZGV4OiBudW1iZXIpOiBudW1iZXIgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSA6IDA7XG4gIH1cblxuICBub2RlSW5kaWNlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBub2RlSW5kaWNlc0FycmF5KCk6IFVpbnQzMkFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gbmV3IFVpbnQzMkFycmF5KFxuICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnVmZmVyLFxuICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnl0ZU9mZnNldCArIHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgICB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBudW1JbnB1dHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG51bU91dHB1dHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGhhc1ZhcmlhZGljSW5wdXQoKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gISF0aGlzLmJiIS5yZWFkSW50OCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBmYWxzZTtcbiAgfVxuXG4gIGhhc1ZhcmlhZGljT3V0cHV0KCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMik7XG4gICAgcmV0dXJuIG9mZnNldCA/ICEhdGhpcy5iYiEucmVhZEludDgodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogZmFsc2U7XG4gIH1cblxuICBudW1WYXJpYWRpY0lucHV0cygpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG51bVZhcmlhZGljT3V0cHV0cygpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoNyk7XG4gIH1cblxuICBzdGF0aWMgYWRkTm9kZUluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgbm9kZUluZGljZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU5vZGVJbmRpY2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdIHwgVWludDMyQXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQ7XG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBUaGlzIFVpbnQ4QXJyYXkgb3ZlcmxvYWQgd2lsbCBiZSByZW1vdmVkIGluIHRoZSBmdXR1cmUuXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlTm9kZUluZGljZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW10gfCBVaW50OEFycmF5KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0O1xuICBzdGF0aWMgY3JlYXRlTm9kZUluZGljZXNWZWN0b3IoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBkYXRhOiBudW1iZXJbXSB8IFVpbnQzMkFycmF5IHwgVWludDhBcnJheSxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRJbnQzMihkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0Tm9kZUluZGljZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZE51bUlucHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1JbnB1dHM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMigxLCBudW1JbnB1dHMsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZE51bU91dHB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtT3V0cHV0czogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDIsIG51bU91dHB1dHMsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZEhhc1ZhcmlhZGljSW5wdXQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaGFzVmFyaWFkaWNJbnB1dDogYm9vbGVhbikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ4KDMsICtoYXNWYXJpYWRpY0lucHV0LCArZmFsc2UpO1xuICB9XG5cbiAgc3RhdGljIGFkZEhhc1ZhcmlhZGljT3V0cHV0KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGhhc1ZhcmlhZGljT3V0cHV0OiBib29sZWFuKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDgoNCwgK2hhc1ZhcmlhZGljT3V0cHV0LCArZmFsc2UpO1xuICB9XG5cbiAgc3RhdGljIGFkZE51bVZhcmlhZGljSW5wdXRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bVZhcmlhZGljSW5wdXRzOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoNSwgbnVtVmFyaWFkaWNJbnB1dHMsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZE51bVZhcmlhZGljT3V0cHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1WYXJpYWRpY091dHB1dHM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMig2LCBudW1WYXJpYWRpY091dHB1dHMsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU5vZGVzVG9PcHRpbWl6ZUluZGljZXMoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBub2RlSW5kaWNlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIG51bUlucHV0czogbnVtYmVyLFxuICAgIG51bU91dHB1dHM6IG51bWJlcixcbiAgICBoYXNWYXJpYWRpY0lucHV0OiBib29sZWFuLFxuICAgIGhhc1ZhcmlhZGljT3V0cHV0OiBib29sZWFuLFxuICAgIG51bVZhcmlhZGljSW5wdXRzOiBudW1iZXIsXG4gICAgbnVtVmFyaWFkaWNPdXRwdXRzOiBudW1iZXIsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgTm9kZXNUb09wdGltaXplSW5kaWNlcy5zdGFydE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoYnVpbGRlcik7XG4gICAgTm9kZXNUb09wdGltaXplSW5kaWNlcy5hZGROb2RlSW5kaWNlcyhidWlsZGVyLCBub2RlSW5kaWNlc09mZnNldCk7XG4gICAgTm9kZXNUb09wdGltaXplSW5kaWNlcy5hZGROdW1JbnB1dHMoYnVpbGRlciwgbnVtSW5wdXRzKTtcbiAgICBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzLmFkZE51bU91dHB1dHMoYnVpbGRlciwgbnVtT3V0cHV0cyk7XG4gICAgTm9kZXNUb09wdGltaXplSW5kaWNlcy5hZGRIYXNWYXJpYWRpY0lucHV0KGJ1aWxkZXIsIGhhc1ZhcmlhZGljSW5wdXQpO1xuICAgIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMuYWRkSGFzVmFyaWFkaWNPdXRwdXQoYnVpbGRlciwgaGFzVmFyaWFkaWNPdXRwdXQpO1xuICAgIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMuYWRkTnVtVmFyaWFkaWNJbnB1dHMoYnVpbGRlciwgbnVtVmFyaWFkaWNJbnB1dHMpO1xuICAgIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMuYWRkTnVtVmFyaWFkaWNPdXRwdXRzKGJ1aWxkZXIsIG51bVZhcmlhZGljT3V0cHV0cyk7XG4gICAgcmV0dXJuIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMuZW5kTm9kZXNUb09wdGltaXplSW5kaWNlcyhidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL25vZGVzLXRvLW9wdGltaXplLWluZGljZXMuanMnO1xuXG4vKipcbiAqIGEgc2luZ2xlIHJ1bnRpbWUgb3B0aW1pemF0aW9uXG4gKiBzZWUgY29ycmVzcG9uZGluZyB0eXBlIGluIG9ubnhydW50aW1lL2NvcmUvZ3JhcGgvcnVudGltZV9vcHRpbWl6YXRpb25fcmVjb3JkLmhcbiAqL1xuZXhwb3J0IGNsYXNzIFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzUnVudGltZU9wdGltaXphdGlvblJlY29yZChcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkLFxuICApOiBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgUnVudGltZU9wdGltaXphdGlvblJlY29yZCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1J1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogUnVudGltZU9wdGltaXphdGlvblJlY29yZCxcbiAgKTogUnVudGltZU9wdGltaXphdGlvblJlY29yZCB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGFjdGlvbklkKCk6IHN0cmluZyB8IG51bGw7XG4gIGFjdGlvbklkKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGFjdGlvbklkKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgbm9kZXNUb09wdGltaXplSW5kaWNlcyhvYmo/OiBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzKTogTm9kZXNUb09wdGltaXplSW5kaWNlcyB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISlcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHByb2R1Y2VkT3BJZHMoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgcHJvZHVjZWRPcElkcyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gIHByb2R1Y2VkT3BJZHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHByb2R1Y2VkT3BJZHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkQWN0aW9uSWQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgYWN0aW9uSWRPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgYWN0aW9uSWRPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZXNUb09wdGltaXplSW5kaWNlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBub2Rlc1RvT3B0aW1pemVJbmRpY2VzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRQcm9kdWNlZE9wSWRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHByb2R1Y2VkT3BJZHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMywgcHJvZHVjZWRPcElkc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlUHJvZHVjZWRPcElkc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRQcm9kdWNlZE9wSWRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9uLXJlY29yZC5qcyc7XG5cbmV4cG9ydCBjbGFzcyBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5LFxuICApOiBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkoKSkuX19pbml0KFxuICAgICAgYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSxcbiAgICAgIGJiLFxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSxcbiAgKTogUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5IHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KCkpLl9faW5pdChcbiAgICAgIGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksXG4gICAgICBiYixcbiAgICApO1xuICB9XG5cbiAgb3B0aW1pemVyTmFtZSgpOiBzdHJpbmcgfCBudWxsO1xuICBvcHRpbWl6ZXJOYW1lKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIG9wdGltaXplck5hbWUob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBydW50aW1lT3B0aW1pemF0aW9uUmVjb3JkcyhpbmRleDogbnVtYmVyLCBvYmo/OiBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkKTogUnVudGltZU9wdGltaXphdGlvblJlY29yZCB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQoKSkuX19pbml0KFxuICAgICAgICAgIHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSxcbiAgICAgICAgICB0aGlzLmJiISxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgcnVudGltZU9wdGltaXphdGlvblJlY29yZHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0UnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDIpO1xuICB9XG5cbiAgc3RhdGljIGFkZE9wdGltaXplck5hbWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3B0aW1pemVyTmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBvcHRpbWl6ZXJOYW1lT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkcyhcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIHJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgcnVudGltZU9wdGltaXphdGlvblJlY29yZHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRzVmVjdG9yKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10sXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRSdW50aW1lT3B0aW1pemF0aW9uUmVjb3Jkc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgYnVpbGRlci5yZXF1aXJlZEZpZWxkKG9mZnNldCwgNCk7IC8vIG9wdGltaXplcl9uYW1lXG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBvcHRpbWl6ZXJOYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgcnVudGltZU9wdGltaXphdGlvblJlY29yZHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkuc3RhcnRSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkoYnVpbGRlcik7XG4gICAgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5LmFkZE9wdGltaXplck5hbWUoYnVpbGRlciwgb3B0aW1pemVyTmFtZU9mZnNldCk7XG4gICAgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5LmFkZFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRzKGJ1aWxkZXIsIHJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRzT2Zmc2V0KTtcbiAgICByZXR1cm4gUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5LmVuZFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeShidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvcnVudGltZS1vcHRpbWl6YXRpb24tcmVjb3JkLWNvbnRhaW5lci1lbnRyeS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBSdW50aW1lT3B0aW1pemF0aW9ucyB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogUnVudGltZU9wdGltaXphdGlvbnMge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzUnVudGltZU9wdGltaXphdGlvbnMoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFJ1bnRpbWVPcHRpbWl6YXRpb25zKTogUnVudGltZU9wdGltaXphdGlvbnMge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBSdW50aW1lT3B0aW1pemF0aW9ucygpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1J1bnRpbWVPcHRpbWl6YXRpb25zKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IFJ1bnRpbWVPcHRpbWl6YXRpb25zLFxuICApOiBSdW50aW1lT3B0aW1pemF0aW9ucyB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFJ1bnRpbWVPcHRpbWl6YXRpb25zKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICAvKipcbiAgICogbWFwcGluZyBmcm9tIG9wdGltaXplciBuYW1lIHRvIFtSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkXVxuICAgKi9cbiAgcmVjb3JkcyhcbiAgICBpbmRleDogbnVtYmVyLFxuICAgIG9iaj86IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSxcbiAgKTogUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHJlY29yZHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0UnVudGltZU9wdGltaXphdGlvbnMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMSk7XG4gIH1cblxuICBzdGF0aWMgYWRkUmVjb3JkcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCByZWNvcmRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIHJlY29yZHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVJlY29yZHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0UmVjb3Jkc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kUnVudGltZU9wdGltaXphdGlvbnMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVJ1bnRpbWVPcHRpbWl6YXRpb25zKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgcmVjb3Jkc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIFJ1bnRpbWVPcHRpbWl6YXRpb25zLnN0YXJ0UnVudGltZU9wdGltaXphdGlvbnMoYnVpbGRlcik7XG4gICAgUnVudGltZU9wdGltaXphdGlvbnMuYWRkUmVjb3JkcyhidWlsZGVyLCByZWNvcmRzT2Zmc2V0KTtcbiAgICByZXR1cm4gUnVudGltZU9wdGltaXphdGlvbnMuZW5kUnVudGltZU9wdGltaXphdGlvbnMoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmV4cG9ydCBlbnVtIFRlbnNvckRhdGFUeXBlIHtcbiAgVU5ERUZJTkVEID0gMCxcbiAgRkxPQVQgPSAxLFxuICBVSU5UOCA9IDIsXG4gIElOVDggPSAzLFxuICBVSU5UMTYgPSA0LFxuICBJTlQxNiA9IDUsXG4gIElOVDMyID0gNixcbiAgSU5UNjQgPSA3LFxuICBTVFJJTkcgPSA4LFxuICBCT09MID0gOSxcbiAgRkxPQVQxNiA9IDEwLFxuICBET1VCTEUgPSAxMSxcbiAgVUlOVDMyID0gMTIsXG4gIFVJTlQ2NCA9IDEzLFxuICBDT01QTEVYNjQgPSAxNCxcbiAgQ09NUExFWDEyOCA9IDE1LFxuICBCRkxPQVQxNiA9IDE2LFxuICBGTE9BVDhFNE0zRk4gPSAxNyxcbiAgRkxPQVQ4RTRNM0ZOVVogPSAxOCxcbiAgRkxPQVQ4RTVNMiA9IDE5LFxuICBGTE9BVDhFNU0yRk5VWiA9IDIwLFxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBUZW5zb3JEYXRhVHlwZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy90ZW5zb3ItZGF0YS10eXBlLmpzJztcblxuZXhwb3J0IGNsYXNzIFRlbnNvciB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogVGVuc29yIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc1RlbnNvcihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVGVuc29yKTogVGVuc29yIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgVGVuc29yKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzVGVuc29yKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBUZW5zb3IpOiBUZW5zb3Ige1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBUZW5zb3IoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIG5hbWUoKTogc3RyaW5nIHwgbnVsbDtcbiAgbmFtZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBuYW1lKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgZG9jU3RyaW5nKCk6IHN0cmluZyB8IG51bGw7XG4gIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBkaW1zKGluZGV4OiBudW1iZXIpOiBiaWdpbnQgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDgpIDogQmlnSW50KDApO1xuICB9XG5cbiAgZGltc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBkYXRhVHlwZSgpOiBUZW5zb3JEYXRhVHlwZSB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IFRlbnNvckRhdGFUeXBlLlVOREVGSU5FRDtcbiAgfVxuXG4gIHJhd0RhdGEoaW5kZXg6IG51bWJlcik6IG51bWJlciB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50OCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCkgOiAwO1xuICB9XG5cbiAgcmF3RGF0YUxlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgcmF3RGF0YUFycmF5KCk6IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gbmV3IFVpbnQ4QXJyYXkoXG4gICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5idWZmZXIsXG4gICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5ieXRlT2Zmc2V0ICsgdGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICAgIHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCksXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHN0cmluZ0RhdGEoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgc3RyaW5nRGF0YShpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gIHN0cmluZ0RhdGEoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHN0cmluZ0RhdGFMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGV4dGVybmFsRGF0YU9mZnNldCgpOiBiaWdpbnQge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBCaWdJbnQoJy0xJyk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRUZW5zb3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoNyk7XG4gIH1cblxuICBzdGF0aWMgYWRkTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG5hbWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREaW1zKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRpbXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgZGltc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRGltc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBiaWdpbnRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig4LCBkYXRhLmxlbmd0aCwgOCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkSW50NjQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydERpbXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgbnVtRWxlbXMsIDgpO1xuICB9XG5cbiAgc3RhdGljIGFkZERhdGFUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGFUeXBlOiBUZW5zb3JEYXRhVHlwZSkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMigzLCBkYXRhVHlwZSwgVGVuc29yRGF0YVR5cGUuVU5ERUZJTkVEKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRSYXdEYXRhKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHJhd0RhdGFPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNCwgcmF3RGF0YU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlUmF3RGF0YVZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBudW1iZXJbXSB8IFVpbnQ4QXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoMSwgZGF0YS5sZW5ndGgsIDEpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZEludDgoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFJhd0RhdGFWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoMSwgbnVtRWxlbXMsIDEpO1xuICB9XG5cbiAgc3RhdGljIGFkZFN0cmluZ0RhdGEoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgc3RyaW5nRGF0YU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg1LCBzdHJpbmdEYXRhT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVTdHJpbmdEYXRhVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFN0cmluZ0RhdGFWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZEV4dGVybmFsRGF0YU9mZnNldChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBleHRlcm5hbERhdGFPZmZzZXQ6IGJpZ2ludCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ2NCg2LCBleHRlcm5hbERhdGFPZmZzZXQsIEJpZ0ludCgnLTEnKSk7XG4gIH1cblxuICBzdGF0aWMgZW5kVGVuc29yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVUZW5zb3IoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgZGltc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGRhdGFUeXBlOiBUZW5zb3JEYXRhVHlwZSxcbiAgICByYXdEYXRhT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgc3RyaW5nRGF0YU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGV4dGVybmFsRGF0YU9mZnNldDogYmlnaW50LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIFRlbnNvci5zdGFydFRlbnNvcihidWlsZGVyKTtcbiAgICBUZW5zb3IuYWRkTmFtZShidWlsZGVyLCBuYW1lT2Zmc2V0KTtcbiAgICBUZW5zb3IuYWRkRG9jU3RyaW5nKGJ1aWxkZXIsIGRvY1N0cmluZ09mZnNldCk7XG4gICAgVGVuc29yLmFkZERpbXMoYnVpbGRlciwgZGltc09mZnNldCk7XG4gICAgVGVuc29yLmFkZERhdGFUeXBlKGJ1aWxkZXIsIGRhdGFUeXBlKTtcbiAgICBUZW5zb3IuYWRkUmF3RGF0YShidWlsZGVyLCByYXdEYXRhT2Zmc2V0KTtcbiAgICBUZW5zb3IuYWRkU3RyaW5nRGF0YShidWlsZGVyLCBzdHJpbmdEYXRhT2Zmc2V0KTtcbiAgICBUZW5zb3IuYWRkRXh0ZXJuYWxEYXRhT2Zmc2V0KGJ1aWxkZXIsIGV4dGVybmFsRGF0YU9mZnNldCk7XG4gICAgcmV0dXJuIFRlbnNvci5lbmRUZW5zb3IoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3RlbnNvci5qcyc7XG5cbmV4cG9ydCBjbGFzcyBTcGFyc2VUZW5zb3Ige1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFNwYXJzZVRlbnNvciB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNTcGFyc2VUZW5zb3IoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFNwYXJzZVRlbnNvcik6IFNwYXJzZVRlbnNvciB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFNwYXJzZVRlbnNvcigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1NwYXJzZVRlbnNvcihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogU3BhcnNlVGVuc29yKTogU3BhcnNlVGVuc29yIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgU3BhcnNlVGVuc29yKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICB2YWx1ZXMob2JqPzogVGVuc29yKTogVGVuc29yIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBUZW5zb3IoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOiBudWxsO1xuICB9XG5cbiAgaW5kaWNlcyhvYmo/OiBUZW5zb3IpOiBUZW5zb3IgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IFRlbnNvcigpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBkaW1zKGluZGV4OiBudW1iZXIpOiBiaWdpbnQgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDgpIDogQmlnSW50KDApO1xuICB9XG5cbiAgZGltc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRTcGFyc2VUZW5zb3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMyk7XG4gIH1cblxuICBzdGF0aWMgYWRkVmFsdWVzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHZhbHVlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCB2YWx1ZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZEluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaW5kaWNlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBpbmRpY2VzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREaW1zKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRpbXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgZGltc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRGltc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBiaWdpbnRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig4LCBkYXRhLmxlbmd0aCwgOCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkSW50NjQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydERpbXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgbnVtRWxlbXMsIDgpO1xuICB9XG5cbiAgc3RhdGljIGVuZFNwYXJzZVRlbnNvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgVGVuc29yRGF0YVR5cGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvdGVuc29yLWRhdGEtdHlwZS5qcyc7XG5pbXBvcnQgeyBUeXBlSW5mbyB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy90eXBlLWluZm8uanMnO1xuXG5leHBvcnQgY2xhc3MgTWFwVHlwZSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogTWFwVHlwZSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNNYXBUeXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBNYXBUeXBlKTogTWFwVHlwZSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE1hcFR5cGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNNYXBUeXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBNYXBUeXBlKTogTWFwVHlwZSB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE1hcFR5cGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGtleVR5cGUoKTogVGVuc29yRGF0YVR5cGUge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IFRlbnNvckRhdGFUeXBlLlVOREVGSU5FRDtcbiAgfVxuXG4gIHZhbHVlVHlwZShvYmo/OiBUeXBlSW5mbyk6IFR5cGVJbmZvIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBUeXBlSW5mbygpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRNYXBUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDIpO1xuICB9XG5cbiAgc3RhdGljIGFkZEtleVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwga2V5VHlwZTogVGVuc29yRGF0YVR5cGUpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMCwga2V5VHlwZSwgVGVuc29yRGF0YVR5cGUuVU5ERUZJTkVEKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRWYWx1ZVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIHZhbHVlVHlwZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kTWFwVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgVHlwZUluZm8gfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvdHlwZS1pbmZvLmpzJztcblxuZXhwb3J0IGNsYXNzIFNlcXVlbmNlVHlwZSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogU2VxdWVuY2VUeXBlIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc1NlcXVlbmNlVHlwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogU2VxdWVuY2VUeXBlKTogU2VxdWVuY2VUeXBlIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgU2VxdWVuY2VUeXBlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzU2VxdWVuY2VUeXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTZXF1ZW5jZVR5cGUpOiBTZXF1ZW5jZVR5cGUge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBTZXF1ZW5jZVR5cGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGVsZW1UeXBlKG9iaj86IFR5cGVJbmZvKTogVHlwZUluZm8gfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IFR5cGVJbmZvKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDogbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFNlcXVlbmNlVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgxKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRFbGVtVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBlbGVtVHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBlbGVtVHlwZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kU2VxdWVuY2VUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVTZXF1ZW5jZVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZWxlbVR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgU2VxdWVuY2VUeXBlLnN0YXJ0U2VxdWVuY2VUeXBlKGJ1aWxkZXIpO1xuICAgIFNlcXVlbmNlVHlwZS5hZGRFbGVtVHlwZShidWlsZGVyLCBlbGVtVHlwZU9mZnNldCk7XG4gICAgcmV0dXJuIFNlcXVlbmNlVHlwZS5lbmRTZXF1ZW5jZVR5cGUoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmV4cG9ydCBlbnVtIERpbWVuc2lvblZhbHVlVHlwZSB7XG4gIFVOS05PV04gPSAwLFxuICBWQUxVRSA9IDEsXG4gIFBBUkFNID0gMixcbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgRGltZW5zaW9uVmFsdWVUeXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2RpbWVuc2lvbi12YWx1ZS10eXBlLmpzJztcblxuZXhwb3J0IGNsYXNzIERpbWVuc2lvblZhbHVlIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEaW1lbnNpb25WYWx1ZSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNEaW1lbnNpb25WYWx1ZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogRGltZW5zaW9uVmFsdWUpOiBEaW1lbnNpb25WYWx1ZSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERpbWVuc2lvblZhbHVlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzRGltZW5zaW9uVmFsdWUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IERpbWVuc2lvblZhbHVlKTogRGltZW5zaW9uVmFsdWUge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBEaW1lbnNpb25WYWx1ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgZGltVHlwZSgpOiBEaW1lbnNpb25WYWx1ZVR5cGUge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDgodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogRGltZW5zaW9uVmFsdWVUeXBlLlVOS05PV047XG4gIH1cblxuICBkaW1WYWx1ZSgpOiBiaWdpbnQge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IEJpZ0ludCgnMCcpO1xuICB9XG5cbiAgZGltUGFyYW0oKTogc3RyaW5nIHwgbnVsbDtcbiAgZGltUGFyYW0ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZGltUGFyYW0ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnREaW1lbnNpb25WYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgzKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREaW1UeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRpbVR5cGU6IERpbWVuc2lvblZhbHVlVHlwZSkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ4KDAsIGRpbVR5cGUsIERpbWVuc2lvblZhbHVlVHlwZS5VTktOT1dOKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREaW1WYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1WYWx1ZTogYmlnaW50KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDEsIGRpbVZhbHVlLCBCaWdJbnQoJzAnKSk7XG4gIH1cblxuICBzdGF0aWMgYWRkRGltUGFyYW0oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGltUGFyYW1PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgZGltUGFyYW1PZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZERpbWVuc2lvblZhbHVlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVEaW1lbnNpb25WYWx1ZShcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIGRpbVR5cGU6IERpbWVuc2lvblZhbHVlVHlwZSxcbiAgICBkaW1WYWx1ZTogYmlnaW50LFxuICAgIGRpbVBhcmFtT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgRGltZW5zaW9uVmFsdWUuc3RhcnREaW1lbnNpb25WYWx1ZShidWlsZGVyKTtcbiAgICBEaW1lbnNpb25WYWx1ZS5hZGREaW1UeXBlKGJ1aWxkZXIsIGRpbVR5cGUpO1xuICAgIERpbWVuc2lvblZhbHVlLmFkZERpbVZhbHVlKGJ1aWxkZXIsIGRpbVZhbHVlKTtcbiAgICBEaW1lbnNpb25WYWx1ZS5hZGREaW1QYXJhbShidWlsZGVyLCBkaW1QYXJhbU9mZnNldCk7XG4gICAgcmV0dXJuIERpbWVuc2lvblZhbHVlLmVuZERpbWVuc2lvblZhbHVlKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IERpbWVuc2lvblZhbHVlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2RpbWVuc2lvbi12YWx1ZS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBEaW1lbnNpb24ge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IERpbWVuc2lvbiB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNEaW1lbnNpb24oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IERpbWVuc2lvbik6IERpbWVuc2lvbiB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERpbWVuc2lvbigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0RpbWVuc2lvbihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogRGltZW5zaW9uKTogRGltZW5zaW9uIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGltZW5zaW9uKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICB2YWx1ZShvYmo/OiBEaW1lbnNpb25WYWx1ZSk6IERpbWVuc2lvblZhbHVlIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBEaW1lbnNpb25WYWx1ZSgpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBkZW5vdGF0aW9uKCk6IHN0cmluZyB8IG51bGw7XG4gIGRlbm90YXRpb24ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZGVub3RhdGlvbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydERpbWVuc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRWYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB2YWx1ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCB2YWx1ZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkRGVub3RhdGlvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkZW5vdGF0aW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGRlbm90YXRpb25PZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZERpbWVuc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRGltZW5zaW9uKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgdmFsdWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBkZW5vdGF0aW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgRGltZW5zaW9uLnN0YXJ0RGltZW5zaW9uKGJ1aWxkZXIpO1xuICAgIERpbWVuc2lvbi5hZGRWYWx1ZShidWlsZGVyLCB2YWx1ZU9mZnNldCk7XG4gICAgRGltZW5zaW9uLmFkZERlbm90YXRpb24oYnVpbGRlciwgZGVub3RhdGlvbk9mZnNldCk7XG4gICAgcmV0dXJuIERpbWVuc2lvbi5lbmREaW1lbnNpb24oYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgRGltZW5zaW9uIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2RpbWVuc2lvbi5qcyc7XG5cbmV4cG9ydCBjbGFzcyBTaGFwZSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogU2hhcGUge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzU2hhcGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFNoYXBlKTogU2hhcGUge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBTaGFwZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1NoYXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTaGFwZSk6IFNoYXBlIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgU2hhcGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGRpbShpbmRleDogbnVtYmVyLCBvYmo/OiBEaW1lbnNpb24pOiBEaW1lbnNpb24gfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBEaW1lbnNpb24oKSkuX19pbml0KFxuICAgICAgICAgIHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSxcbiAgICAgICAgICB0aGlzLmJiISxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgZGltTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFNoYXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDEpO1xuICB9XG5cbiAgc3RhdGljIGFkZERpbShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgZGltT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVEaW1WZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0RGltVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRTaGFwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlU2hhcGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGltT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIFNoYXBlLnN0YXJ0U2hhcGUoYnVpbGRlcik7XG4gICAgU2hhcGUuYWRkRGltKGJ1aWxkZXIsIGRpbU9mZnNldCk7XG4gICAgcmV0dXJuIFNoYXBlLmVuZFNoYXBlKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IFNoYXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3NoYXBlLmpzJztcbmltcG9ydCB7IFRlbnNvckRhdGFUeXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3RlbnNvci1kYXRhLXR5cGUuanMnO1xuXG5leHBvcnQgY2xhc3MgVGVuc29yVHlwZUFuZFNoYXBlIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBUZW5zb3JUeXBlQW5kU2hhcGUge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzVGVuc29yVHlwZUFuZFNoYXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBUZW5zb3JUeXBlQW5kU2hhcGUpOiBUZW5zb3JUeXBlQW5kU2hhcGUge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBUZW5zb3JUeXBlQW5kU2hhcGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNUZW5zb3JUeXBlQW5kU2hhcGUoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogVGVuc29yVHlwZUFuZFNoYXBlLFxuICApOiBUZW5zb3JUeXBlQW5kU2hhcGUge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBUZW5zb3JUeXBlQW5kU2hhcGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGVsZW1UeXBlKCk6IFRlbnNvckRhdGFUeXBlIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBUZW5zb3JEYXRhVHlwZS5VTkRFRklORUQ7XG4gIH1cblxuICBzaGFwZShvYmo/OiBTaGFwZSk6IFNoYXBlIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBTaGFwZSgpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRUZW5zb3JUeXBlQW5kU2hhcGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gIH1cblxuICBzdGF0aWMgYWRkRWxlbVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZWxlbVR5cGU6IFRlbnNvckRhdGFUeXBlKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDAsIGVsZW1UeXBlLCBUZW5zb3JEYXRhVHlwZS5VTkRFRklORUQpO1xuICB9XG5cbiAgc3RhdGljIGFkZFNoYXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHNoYXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIHNoYXBlT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRUZW5zb3JUeXBlQW5kU2hhcGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgeyBNYXBUeXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL21hcC10eXBlLmpzJztcbmltcG9ydCB7IFNlcXVlbmNlVHlwZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9zZXF1ZW5jZS10eXBlLmpzJztcbmltcG9ydCB7IFRlbnNvclR5cGVBbmRTaGFwZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy90ZW5zb3ItdHlwZS1hbmQtc2hhcGUuanMnO1xuXG5leHBvcnQgZW51bSBUeXBlSW5mb1ZhbHVlIHtcbiAgTk9ORSA9IDAsXG4gIHRlbnNvcl90eXBlID0gMSxcbiAgc2VxdWVuY2VfdHlwZSA9IDIsXG4gIG1hcF90eXBlID0gMyxcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVuaW9uVG9UeXBlSW5mb1ZhbHVlKFxuICB0eXBlOiBUeXBlSW5mb1ZhbHVlLFxuICBhY2Nlc3NvcjogKG9iajogTWFwVHlwZSB8IFNlcXVlbmNlVHlwZSB8IFRlbnNvclR5cGVBbmRTaGFwZSkgPT4gTWFwVHlwZSB8IFNlcXVlbmNlVHlwZSB8IFRlbnNvclR5cGVBbmRTaGFwZSB8IG51bGwsXG4pOiBNYXBUeXBlIHwgU2VxdWVuY2VUeXBlIHwgVGVuc29yVHlwZUFuZFNoYXBlIHwgbnVsbCB7XG4gIHN3aXRjaCAoVHlwZUluZm9WYWx1ZVt0eXBlXSkge1xuICAgIGNhc2UgJ05PTkUnOlxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgY2FzZSAndGVuc29yX3R5cGUnOlxuICAgICAgcmV0dXJuIGFjY2Vzc29yKG5ldyBUZW5zb3JUeXBlQW5kU2hhcGUoKSkhIGFzIFRlbnNvclR5cGVBbmRTaGFwZTtcbiAgICBjYXNlICdzZXF1ZW5jZV90eXBlJzpcbiAgICAgIHJldHVybiBhY2Nlc3NvcihuZXcgU2VxdWVuY2VUeXBlKCkpISBhcyBTZXF1ZW5jZVR5cGU7XG4gICAgY2FzZSAnbWFwX3R5cGUnOlxuICAgICAgcmV0dXJuIGFjY2Vzc29yKG5ldyBNYXBUeXBlKCkpISBhcyBNYXBUeXBlO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdW5pb25MaXN0VG9UeXBlSW5mb1ZhbHVlKFxuICB0eXBlOiBUeXBlSW5mb1ZhbHVlLFxuICBhY2Nlc3NvcjogKFxuICAgIGluZGV4OiBudW1iZXIsXG4gICAgb2JqOiBNYXBUeXBlIHwgU2VxdWVuY2VUeXBlIHwgVGVuc29yVHlwZUFuZFNoYXBlLFxuICApID0+IE1hcFR5cGUgfCBTZXF1ZW5jZVR5cGUgfCBUZW5zb3JUeXBlQW5kU2hhcGUgfCBudWxsLFxuICBpbmRleDogbnVtYmVyLFxuKTogTWFwVHlwZSB8IFNlcXVlbmNlVHlwZSB8IFRlbnNvclR5cGVBbmRTaGFwZSB8IG51bGwge1xuICBzd2l0Y2ggKFR5cGVJbmZvVmFsdWVbdHlwZV0pIHtcbiAgICBjYXNlICdOT05FJzpcbiAgICAgIHJldHVybiBudWxsO1xuICAgIGNhc2UgJ3RlbnNvcl90eXBlJzpcbiAgICAgIHJldHVybiBhY2Nlc3NvcihpbmRleCwgbmV3IFRlbnNvclR5cGVBbmRTaGFwZSgpKSEgYXMgVGVuc29yVHlwZUFuZFNoYXBlO1xuICAgIGNhc2UgJ3NlcXVlbmNlX3R5cGUnOlxuICAgICAgcmV0dXJuIGFjY2Vzc29yKGluZGV4LCBuZXcgU2VxdWVuY2VUeXBlKCkpISBhcyBTZXF1ZW5jZVR5cGU7XG4gICAgY2FzZSAnbWFwX3R5cGUnOlxuICAgICAgcmV0dXJuIGFjY2Vzc29yKGluZGV4LCBuZXcgTWFwVHlwZSgpKSEgYXMgTWFwVHlwZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgVHlwZUluZm9WYWx1ZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy90eXBlLWluZm8tdmFsdWUuanMnO1xuXG5leHBvcnQgY2xhc3MgVHlwZUluZm8ge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFR5cGVJbmZvIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc1R5cGVJbmZvKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBUeXBlSW5mbyk6IFR5cGVJbmZvIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgVHlwZUluZm8oKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNUeXBlSW5mbyhiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVHlwZUluZm8pOiBUeXBlSW5mbyB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFR5cGVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBkZW5vdGF0aW9uKCk6IHN0cmluZyB8IG51bGw7XG4gIGRlbm90YXRpb24ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZGVub3RhdGlvbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHZhbHVlVHlwZSgpOiBUeXBlSW5mb1ZhbHVlIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50OCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBUeXBlSW5mb1ZhbHVlLk5PTkU7XG4gIH1cblxuICB2YWx1ZShvYmo6IGFueSk6IGFueSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX191bmlvbihvYmosIHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRUeXBlSW5mbyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgzKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREZW5vdGF0aW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRlbm90YXRpb25PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgZGVub3RhdGlvbk9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkVmFsdWVUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHZhbHVlVHlwZTogVHlwZUluZm9WYWx1ZSkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ4KDEsIHZhbHVlVHlwZSwgVHlwZUluZm9WYWx1ZS5OT05FKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRWYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB2YWx1ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgyLCB2YWx1ZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kVHlwZUluZm8oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVR5cGVJbmZvKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgZGVub3RhdGlvbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIHZhbHVlVHlwZTogVHlwZUluZm9WYWx1ZSxcbiAgICB2YWx1ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIFR5cGVJbmZvLnN0YXJ0VHlwZUluZm8oYnVpbGRlcik7XG4gICAgVHlwZUluZm8uYWRkRGVub3RhdGlvbihidWlsZGVyLCBkZW5vdGF0aW9uT2Zmc2V0KTtcbiAgICBUeXBlSW5mby5hZGRWYWx1ZVR5cGUoYnVpbGRlciwgdmFsdWVUeXBlKTtcbiAgICBUeXBlSW5mby5hZGRWYWx1ZShidWlsZGVyLCB2YWx1ZU9mZnNldCk7XG4gICAgcmV0dXJuIFR5cGVJbmZvLmVuZFR5cGVJbmZvKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IFR5cGVJbmZvIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3R5cGUtaW5mby5qcyc7XG5cbmV4cG9ydCBjbGFzcyBWYWx1ZUluZm8ge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFZhbHVlSW5mbyB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNWYWx1ZUluZm8oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFZhbHVlSW5mbyk6IFZhbHVlSW5mbyB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFZhbHVlSW5mbygpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1ZhbHVlSW5mbyhiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVmFsdWVJbmZvKTogVmFsdWVJbmZvIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgVmFsdWVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBuYW1lKCk6IHN0cmluZyB8IG51bGw7XG4gIG5hbWUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgbmFtZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGRvY1N0cmluZygpOiBzdHJpbmcgfCBudWxsO1xuICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgdHlwZShvYmo/OiBUeXBlSW5mbyk6IFR5cGVJbmZvIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBUeXBlSW5mbygpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRWYWx1ZUluZm8oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMyk7XG4gIH1cblxuICBzdGF0aWMgYWRkTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG5hbWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgdHlwZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kVmFsdWVJbmZvKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL25vZGUuanMnO1xuaW1wb3J0IHsgTm9kZUVkZ2UgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvbm9kZS1lZGdlLmpzJztcbmltcG9ydCB7IFJ1bnRpbWVPcHRpbWl6YXRpb25zIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9ucy5qcyc7XG5pbXBvcnQgeyBTcGFyc2VUZW5zb3IgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvc3BhcnNlLXRlbnNvci5qcyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvdGVuc29yLmpzJztcbmltcG9ydCB7IFZhbHVlSW5mbyB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy92YWx1ZS1pbmZvLmpzJztcblxuZXhwb3J0IGNsYXNzIEdyYXBoIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBHcmFwaCB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNHcmFwaChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogR3JhcGgpOiBHcmFwaCB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IEdyYXBoKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzR3JhcGgoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEdyYXBoKTogR3JhcGgge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBHcmFwaCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgaW5pdGlhbGl6ZXJzKGluZGV4OiBudW1iZXIsIG9iaj86IFRlbnNvcik6IFRlbnNvciB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IFRlbnNvcigpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISlcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIGluaXRpYWxpemVyc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBub2RlQXJncyhpbmRleDogbnVtYmVyLCBvYmo/OiBWYWx1ZUluZm8pOiBWYWx1ZUluZm8gfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBWYWx1ZUluZm8oKSkuX19pbml0KFxuICAgICAgICAgIHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSxcbiAgICAgICAgICB0aGlzLmJiISxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgbm9kZUFyZ3NMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgbm9kZXMoaW5kZXg6IG51bWJlciwgb2JqPzogTm9kZSk6IE5vZGUgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBOb2RlKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgbm9kZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgbWF4Tm9kZUluZGV4KCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZFVpbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgbm9kZUVkZ2VzKGluZGV4OiBudW1iZXIsIG9iaj86IE5vZGVFZGdlKTogTm9kZUVkZ2UgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgTm9kZUVkZ2UoKSkuX19pbml0KFxuICAgICAgICAgIHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSxcbiAgICAgICAgICB0aGlzLmJiISxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgbm9kZUVkZ2VzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBpbnB1dHMoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgaW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheTtcbiAgaW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBpbnB1dHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG91dHB1dHMoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgb3V0cHV0cyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gIG91dHB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIG91dHB1dHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHNwYXJzZUluaXRpYWxpemVycyhpbmRleDogbnVtYmVyLCBvYmo/OiBTcGFyc2VUZW5zb3IpOiBTcGFyc2VUZW5zb3IgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTgpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgU3BhcnNlVGVuc29yKCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHNwYXJzZUluaXRpYWxpemVyc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgcnVudGltZU9wdGltaXphdGlvbnMob2JqPzogUnVudGltZU9wdGltaXphdGlvbnMpOiBSdW50aW1lT3B0aW1pemF0aW9ucyB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMCk7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBSdW50aW1lT3B0aW1pemF0aW9ucygpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0R3JhcGgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoOSk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW5pdGlhbGl6ZXJzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGluaXRpYWxpemVyc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBpbml0aWFsaXplcnNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUluaXRpYWxpemVyc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbml0aWFsaXplcnNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZE5vZGVBcmdzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVBcmdzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIG5vZGVBcmdzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVOb2RlQXJnc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnROb2RlQXJnc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkTm9kZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgbm9kZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU5vZGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE5vZGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRNYXhOb2RlSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbWF4Tm9kZUluZGV4OiBudW1iZXIpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMywgbWF4Tm9kZUluZGV4LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGROb2RlRWRnZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUVkZ2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDQsIG5vZGVFZGdlc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlTm9kZUVkZ2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE5vZGVFZGdlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW5wdXRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGlucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg1LCBpbnB1dHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUlucHV0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbnB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZE91dHB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3V0cHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg2LCBvdXRwdXRzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVPdXRwdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE91dHB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZFNwYXJzZUluaXRpYWxpemVycyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBzcGFyc2VJbml0aWFsaXplcnNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNywgc3BhcnNlSW5pdGlhbGl6ZXJzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVTcGFyc2VJbml0aWFsaXplcnNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0U3BhcnNlSW5pdGlhbGl6ZXJzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRSdW50aW1lT3B0aW1pemF0aW9ucyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBydW50aW1lT3B0aW1pemF0aW9uc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg4LCBydW50aW1lT3B0aW1pemF0aW9uc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kR3JhcGgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IEF0dHJpYnV0ZVR5cGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvYXR0cmlidXRlLXR5cGUuanMnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvZ3JhcGguanMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3RlbnNvci5qcyc7XG5cbmV4cG9ydCBjbGFzcyBBdHRyaWJ1dGUge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IEF0dHJpYnV0ZSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNBdHRyaWJ1dGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEF0dHJpYnV0ZSk6IEF0dHJpYnV0ZSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IEF0dHJpYnV0ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0F0dHJpYnV0ZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogQXR0cmlidXRlKTogQXR0cmlidXRlIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgQXR0cmlidXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBuYW1lKCk6IHN0cmluZyB8IG51bGw7XG4gIG5hbWUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgbmFtZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGRvY1N0cmluZygpOiBzdHJpbmcgfCBudWxsO1xuICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgdHlwZSgpOiBBdHRyaWJ1dGVUeXBlIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBBdHRyaWJ1dGVUeXBlLlVOREVGSU5FRDtcbiAgfVxuXG4gIGYoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkRmxvYXQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwLjA7XG4gIH1cblxuICBpKCk6IGJpZ2ludCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IEJpZ0ludCgnMCcpO1xuICB9XG5cbiAgcygpOiBzdHJpbmcgfCBudWxsO1xuICBzKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIHMob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgdChvYmo/OiBUZW5zb3IpOiBUZW5zb3IgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBUZW5zb3IoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOiBudWxsO1xuICB9XG5cbiAgZyhvYmo/OiBHcmFwaCk6IEdyYXBoIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgR3JhcGgoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOiBudWxsO1xuICB9XG5cbiAgZmxvYXRzKGluZGV4OiBudW1iZXIpOiBudW1iZXIgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkRmxvYXQzMih0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpIDogMDtcbiAgfVxuXG4gIGZsb2F0c0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgZmxvYXRzQXJyYXkoKTogRmxvYXQzMkFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDIwKTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IG5ldyBGbG9hdDMyQXJyYXkoXG4gICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5idWZmZXIsXG4gICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5ieXRlT2Zmc2V0ICsgdGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICAgIHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCksXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIGludHMoaW5kZXg6IG51bWJlcik6IGJpZ2ludCB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDgpIDogQmlnSW50KDApO1xuICB9XG5cbiAgaW50c0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RyaW5ncyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICBzdHJpbmdzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheTtcbiAgc3RyaW5ncyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgc3RyaW5nc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgdGVuc29ycyhpbmRleDogbnVtYmVyLCBvYmo/OiBUZW5zb3IpOiBUZW5zb3IgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjYpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgVGVuc29yKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgdGVuc29yc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgZ3JhcGhzKGluZGV4OiBudW1iZXIsIG9iaj86IEdyYXBoKTogR3JhcGggfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjgpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgR3JhcGgoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSwgdGhpcy5iYiEpXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBncmFwaHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEF0dHJpYnV0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgxMyk7XG4gIH1cblxuICBzdGF0aWMgYWRkTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG5hbWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHR5cGU6IEF0dHJpYnV0ZVR5cGUpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMiwgdHlwZSwgQXR0cmlidXRlVHlwZS5VTkRFRklORUQpO1xuICB9XG5cbiAgc3RhdGljIGFkZEYoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZjogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEZsb2F0MzIoMywgZiwgMC4wKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRJKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGk6IGJpZ2ludCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ2NCg0LCBpLCBCaWdJbnQoJzAnKSk7XG4gIH1cblxuICBzdGF0aWMgYWRkUyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDUsIHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZFQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg2LCB0T2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRHKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNywgZ09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkRmxvYXRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGZsb2F0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg4LCBmbG9hdHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUZsb2F0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBudW1iZXJbXSB8IEZsb2F0MzJBcnJheSk6IGZsYXRidWZmZXJzLk9mZnNldDtcbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFRoaXMgVWludDhBcnJheSBvdmVybG9hZCB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIGZ1dHVyZS5cbiAgICovXG4gIHN0YXRpYyBjcmVhdGVGbG9hdHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW10gfCBVaW50OEFycmF5KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0O1xuICBzdGF0aWMgY3JlYXRlRmxvYXRzVmVjdG9yKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgZGF0YTogbnVtYmVyW10gfCBGbG9hdDMyQXJyYXkgfCBVaW50OEFycmF5LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZEZsb2F0MzIoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEZsb2F0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW50cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDksIGludHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUludHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogYmlnaW50W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgZGF0YS5sZW5ndGgsIDgpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZEludDY0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbnRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIG51bUVsZW1zLCA4KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRTdHJpbmdzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHN0cmluZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMTAsIHN0cmluZ3NPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVN0cmluZ3NWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0U3RyaW5nc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkVGVuc29ycyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB0ZW5zb3JzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDExLCB0ZW5zb3JzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVUZW5zb3JzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFRlbnNvcnNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZEdyYXBocyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBncmFwaHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMTIsIGdyYXBoc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlR3JhcGhzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEdyYXBoc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kQXR0cmlidXRlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG4vKipcbiAqIGRlcHJlY2F0ZWQ6IG5vIGxvbmdlciB1c2luZyBrZXJuZWwgZGVmIGhhc2hlc1xuICovXG5leHBvcnQgY2xhc3MgRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3Mge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyxcbiAgKTogRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyxcbiAgKTogRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBub2RlSW5kaWNlcyhpbmRleDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCkgOiAwO1xuICB9XG5cbiAgbm9kZUluZGljZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgbm9kZUluZGljZXNBcnJheSgpOiBVaW50MzJBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IG5ldyBVaW50MzJBcnJheShcbiAgICAgICAgICB0aGlzLmJiIS5ieXRlcygpLmJ1ZmZlcixcbiAgICAgICAgICB0aGlzLmJiIS5ieXRlcygpLmJ5dGVPZmZzZXQgKyB0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCksXG4gICAgICAgICAgdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAga2VybmVsRGVmSGFzaGVzKGluZGV4OiBudW1iZXIpOiBiaWdpbnQgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50NjQodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA4KSA6IEJpZ0ludCgwKTtcbiAgfVxuXG4gIGtlcm5lbERlZkhhc2hlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnREZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gIH1cblxuICBzdGF0aWMgYWRkTm9kZUluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgbm9kZUluZGljZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU5vZGVJbmRpY2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdIHwgVWludDMyQXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQ7XG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBUaGlzIFVpbnQ4QXJyYXkgb3ZlcmxvYWQgd2lsbCBiZSByZW1vdmVkIGluIHRoZSBmdXR1cmUuXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlTm9kZUluZGljZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW10gfCBVaW50OEFycmF5KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0O1xuICBzdGF0aWMgY3JlYXRlTm9kZUluZGljZXNWZWN0b3IoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBkYXRhOiBudW1iZXJbXSB8IFVpbnQzMkFycmF5IHwgVWludDhBcnJheSxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRJbnQzMihkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0Tm9kZUluZGljZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZEtlcm5lbERlZkhhc2hlcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBrZXJuZWxEZWZIYXNoZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwga2VybmVsRGVmSGFzaGVzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVLZXJuZWxEZWZIYXNoZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogYmlnaW50W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgZGF0YS5sZW5ndGgsIDgpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZEludDY0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRLZXJuZWxEZWZIYXNoZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgbnVtRWxlbXMsIDgpO1xuICB9XG5cbiAgc3RhdGljIGVuZERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgbm9kZUluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBrZXJuZWxEZWZIYXNoZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3Muc3RhcnREZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MoYnVpbGRlcik7XG4gICAgRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zLmFkZE5vZGVJbmRpY2VzKGJ1aWxkZXIsIG5vZGVJbmRpY2VzT2Zmc2V0KTtcbiAgICBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MuYWRkS2VybmVsRGVmSGFzaGVzKGJ1aWxkZXIsIGtlcm5lbERlZkhhc2hlc09mZnNldCk7XG4gICAgcmV0dXJuIERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcy5lbmREZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuLyoqXG4gKiBkZXByZWNhdGVkOiBubyBsb25nZXIgdXNpbmcga2VybmVsIGRlZiBoYXNoZXNcbiAqL1xuZXhwb3J0IGNsYXNzIERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaChcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCxcbiAgKTogRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2gge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0RlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoLFxuICApOiBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBub2RlSW5kZXgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGtlcm5lbERlZkhhc2goKTogYmlnaW50IHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50NjQodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogQmlnSW50KCcwJyk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnREZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGROb2RlSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUluZGV4OiBudW1iZXIpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMCwgbm9kZUluZGV4LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRLZXJuZWxEZWZIYXNoKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbERlZkhhc2g6IGJpZ2ludCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ2NCgxLCBrZXJuZWxEZWZIYXNoLCBCaWdJbnQoJzAnKSk7XG4gIH1cblxuICBzdGF0aWMgZW5kRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2goYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZURlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgbm9kZUluZGV4OiBudW1iZXIsXG4gICAga2VybmVsRGVmSGFzaDogYmlnaW50LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoLnN0YXJ0RGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2goYnVpbGRlcik7XG4gICAgRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2guYWRkTm9kZUluZGV4KGJ1aWxkZXIsIG5vZGVJbmRleCk7XG4gICAgRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2guYWRkS2VybmVsRGVmSGFzaChidWlsZGVyLCBrZXJuZWxEZWZIYXNoKTtcbiAgICByZXR1cm4gRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2guZW5kRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2goYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9kZXByZWNhdGVkLXNlc3Npb24tc3RhdGUuanMnO1xuXG4vKipcbiAqIGRlcHJlY2F0ZWQ6IG5vIGxvbmdlciB1c2luZyBrZXJuZWwgZGVmIGhhc2hlc1xuICovXG5leHBvcnQgY2xhc3MgRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSxcbiAgKTogRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSxcbiAgKTogRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBncmFwaElkKCk6IHN0cmluZyB8IG51bGw7XG4gIGdyYXBoSWQob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZ3JhcGhJZChvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHNlc3Npb25TdGF0ZShvYmo/OiBEZXByZWNhdGVkU2Vzc2lvblN0YXRlKTogRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISlcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRHcmFwaElkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGdyYXBoSWRPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgZ3JhcGhJZE9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkU2Vzc2lvblN0YXRlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHNlc3Npb25TdGF0ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBzZXNzaW9uU3RhdGVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIGJ1aWxkZXIucmVxdWlyZWRGaWVsZChvZmZzZXQsIDQpOyAvLyBncmFwaF9pZFxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQta2VybmVsLWNyZWF0ZS1pbmZvcy5qcyc7XG5pbXBvcnQgeyBEZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvZGVwcmVjYXRlZC1zdWItZ3JhcGgtc2Vzc2lvbi1zdGF0ZS5qcyc7XG5cbi8qKlxuICogZGVwcmVjYXRlZDogbm8gbG9uZ2VyIHVzaW5nIGtlcm5lbCBkZWYgaGFzaGVzXG4gKi9cbmV4cG9ydCBjbGFzcyBEZXByZWNhdGVkU2Vzc2lvblN0YXRlIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEZXByZWNhdGVkU2Vzc2lvblN0YXRlIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc0RlcHJlY2F0ZWRTZXNzaW9uU3RhdGUoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSxcbiAgKTogRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNEZXByZWNhdGVkU2Vzc2lvblN0YXRlKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUsXG4gICk6IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBEZXByZWNhdGVkU2Vzc2lvblN0YXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBrZXJuZWxzKG9iaj86IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyk6IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcygpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgc3ViR3JhcGhTZXNzaW9uU3RhdGVzKGluZGV4OiBudW1iZXIsIG9iaj86IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSk6IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSgpKS5fX2luaXQoXG4gICAgICAgICAgdGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLFxuICAgICAgICAgIHRoaXMuYmIhLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBzdWJHcmFwaFNlc3Npb25TdGF0ZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0RGVwcmVjYXRlZFNlc3Npb25TdGF0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRLZXJuZWxzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwga2VybmVsc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkU3ViR3JhcGhTZXNzaW9uU3RhdGVzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHN1YkdyYXBoU2Vzc2lvblN0YXRlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBzdWJHcmFwaFNlc3Npb25TdGF0ZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVN1YkdyYXBoU2Vzc2lvblN0YXRlc1ZlY3RvcihcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdLFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0U3ViR3JhcGhTZXNzaW9uU3RhdGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmREZXByZWNhdGVkU2Vzc2lvblN0YXRlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVEZXByZWNhdGVkU2Vzc2lvblN0YXRlKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAga2VybmVsc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIHN1YkdyYXBoU2Vzc2lvblN0YXRlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUuc3RhcnREZXByZWNhdGVkU2Vzc2lvblN0YXRlKGJ1aWxkZXIpO1xuICAgIERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUuYWRkS2VybmVscyhidWlsZGVyLCBrZXJuZWxzT2Zmc2V0KTtcbiAgICBEZXByZWNhdGVkU2Vzc2lvblN0YXRlLmFkZFN1YkdyYXBoU2Vzc2lvblN0YXRlcyhidWlsZGVyLCBzdWJHcmFwaFNlc3Npb25TdGF0ZXNPZmZzZXQpO1xuICAgIHJldHVybiBEZXByZWNhdGVkU2Vzc2lvblN0YXRlLmVuZERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgQXJnVHlwZUFuZEluZGV4IH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2FyZy10eXBlLWFuZC1pbmRleC5qcyc7XG5cbmV4cG9ydCBjbGFzcyBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc0tlcm5lbFR5cGVTdHJBcmdzRW50cnkoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSxcbiAgKTogS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IEtlcm5lbFR5cGVTdHJBcmdzRW50cnksXG4gICk6IEtlcm5lbFR5cGVTdHJBcmdzRW50cnkge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBrZXJuZWxUeXBlU3RyKCk6IHN0cmluZyB8IG51bGw7XG4gIGtlcm5lbFR5cGVTdHIob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAga2VybmVsVHlwZVN0cihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGFyZ3MoaW5kZXg6IG51bWJlciwgb2JqPzogQXJnVHlwZUFuZEluZGV4KTogQXJnVHlwZUFuZEluZGV4IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgQXJnVHlwZUFuZEluZGV4KCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIGFyZ3NMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0S2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRLZXJuZWxUeXBlU3RyKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbFR5cGVTdHJPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwga2VybmVsVHlwZVN0ck9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkQXJncyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBhcmdzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGFyZ3NPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUFyZ3NWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0QXJnc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIGJ1aWxkZXIucmVxdWlyZWRGaWVsZChvZmZzZXQsIDQpOyAvLyBrZXJuZWxfdHlwZV9zdHJcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUtlcm5lbFR5cGVTdHJBcmdzRW50cnkoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBrZXJuZWxUeXBlU3RyT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgYXJnc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIEtlcm5lbFR5cGVTdHJBcmdzRW50cnkuc3RhcnRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KGJ1aWxkZXIpO1xuICAgIEtlcm5lbFR5cGVTdHJBcmdzRW50cnkuYWRkS2VybmVsVHlwZVN0cihidWlsZGVyLCBrZXJuZWxUeXBlU3RyT2Zmc2V0KTtcbiAgICBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5LmFkZEFyZ3MoYnVpbGRlciwgYXJnc09mZnNldCk7XG4gICAgcmV0dXJuIEtlcm5lbFR5cGVTdHJBcmdzRW50cnkuZW5kS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2tlcm5lbC10eXBlLXN0ci1hcmdzLWVudHJ5LmpzJztcblxuZXhwb3J0IGNsYXNzIE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSxcbiAgKTogT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc09wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5LFxuICApOiBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBvcElkKCk6IHN0cmluZyB8IG51bGw7XG4gIG9wSWQob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgb3BJZChvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGtlcm5lbFR5cGVTdHJBcmdzKGluZGV4OiBudW1iZXIsIG9iaj86IEtlcm5lbFR5cGVTdHJBcmdzRW50cnkpOiBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSgpKS5fX2luaXQoXG4gICAgICAgICAgdGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLFxuICAgICAgICAgIHRoaXMuYmIhLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBrZXJuZWxUeXBlU3RyQXJnc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRPcElkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG9wSWRPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgb3BJZE9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkS2VybmVsVHlwZVN0ckFyZ3MoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwga2VybmVsVHlwZVN0ckFyZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwga2VybmVsVHlwZVN0ckFyZ3NPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUtlcm5lbFR5cGVTdHJBcmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEtlcm5lbFR5cGVTdHJBcmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIGJ1aWxkZXIucmVxdWlyZWRGaWVsZChvZmZzZXQsIDQpOyAvLyBvcF9pZFxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBvcElkT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAga2VybmVsVHlwZVN0ckFyZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeS5zdGFydE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KGJ1aWxkZXIpO1xuICAgIE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5LmFkZE9wSWQoYnVpbGRlciwgb3BJZE9mZnNldCk7XG4gICAgT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkuYWRkS2VybmVsVHlwZVN0ckFyZ3MoYnVpbGRlciwga2VybmVsVHlwZVN0ckFyZ3NPZmZzZXQpO1xuICAgIHJldHVybiBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeS5lbmRPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9vcC1pZC1rZXJuZWwtdHlwZS1zdHItYXJncy1lbnRyeS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IEtlcm5lbFR5cGVTdHJSZXNvbHZlciB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNLZXJuZWxUeXBlU3RyUmVzb2x2ZXIoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogS2VybmVsVHlwZVN0clJlc29sdmVyLFxuICApOiBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNLZXJuZWxUeXBlU3RyUmVzb2x2ZXIoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogS2VybmVsVHlwZVN0clJlc29sdmVyLFxuICApOiBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIG9wS2VybmVsVHlwZVN0ckFyZ3MoaW5kZXg6IG51bWJlciwgb2JqPzogT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkpOiBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIG9wS2VybmVsVHlwZVN0ckFyZ3NMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0S2VybmVsVHlwZVN0clJlc29sdmVyKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDEpO1xuICB9XG5cbiAgc3RhdGljIGFkZE9wS2VybmVsVHlwZVN0ckFyZ3MoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3BLZXJuZWxUeXBlU3RyQXJnc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBvcEtlcm5lbFR5cGVTdHJBcmdzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVPcEtlcm5lbFR5cGVTdHJBcmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE9wS2VybmVsVHlwZVN0ckFyZ3NWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGVuZEtlcm5lbFR5cGVTdHJSZXNvbHZlcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlS2VybmVsVHlwZVN0clJlc29sdmVyKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgb3BLZXJuZWxUeXBlU3RyQXJnc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIEtlcm5lbFR5cGVTdHJSZXNvbHZlci5zdGFydEtlcm5lbFR5cGVTdHJSZXNvbHZlcihidWlsZGVyKTtcbiAgICBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIuYWRkT3BLZXJuZWxUeXBlU3RyQXJncyhidWlsZGVyLCBvcEtlcm5lbFR5cGVTdHJBcmdzT2Zmc2V0KTtcbiAgICByZXR1cm4gS2VybmVsVHlwZVN0clJlc29sdmVyLmVuZEtlcm5lbFR5cGVTdHJSZXNvbHZlcihidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5leHBvcnQgY2xhc3MgT3BlcmF0b3JTZXRJZCB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogT3BlcmF0b3JTZXRJZCB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNPcGVyYXRvclNldElkKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBPcGVyYXRvclNldElkKTogT3BlcmF0b3JTZXRJZCB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE9wZXJhdG9yU2V0SWQoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNPcGVyYXRvclNldElkKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBPcGVyYXRvclNldElkKTogT3BlcmF0b3JTZXRJZCB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE9wZXJhdG9yU2V0SWQoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGRvbWFpbigpOiBzdHJpbmcgfCBudWxsO1xuICBkb21haW4ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZG9tYWluKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgdmVyc2lvbigpOiBiaWdpbnQge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IEJpZ0ludCgnMCcpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0T3BlcmF0b3JTZXRJZChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREb21haW4oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9tYWluT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGRvbWFpbk9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkVmVyc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB2ZXJzaW9uOiBiaWdpbnQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50NjQoMSwgdmVyc2lvbiwgQmlnSW50KCcwJykpO1xuICB9XG5cbiAgc3RhdGljIGVuZE9wZXJhdG9yU2V0SWQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU9wZXJhdG9yU2V0SWQoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBkb21haW5PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICB2ZXJzaW9uOiBiaWdpbnQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgT3BlcmF0b3JTZXRJZC5zdGFydE9wZXJhdG9yU2V0SWQoYnVpbGRlcik7XG4gICAgT3BlcmF0b3JTZXRJZC5hZGREb21haW4oYnVpbGRlciwgZG9tYWluT2Zmc2V0KTtcbiAgICBPcGVyYXRvclNldElkLmFkZFZlcnNpb24oYnVpbGRlciwgdmVyc2lvbik7XG4gICAgcmV0dXJuIE9wZXJhdG9yU2V0SWQuZW5kT3BlcmF0b3JTZXRJZChidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5leHBvcnQgY2xhc3MgU3RyaW5nU3RyaW5nRW50cnkge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFN0cmluZ1N0cmluZ0VudHJ5IHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc1N0cmluZ1N0cmluZ0VudHJ5KGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTdHJpbmdTdHJpbmdFbnRyeSk6IFN0cmluZ1N0cmluZ0VudHJ5IHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgU3RyaW5nU3RyaW5nRW50cnkoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNTdHJpbmdTdHJpbmdFbnRyeShcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBTdHJpbmdTdHJpbmdFbnRyeSxcbiAgKTogU3RyaW5nU3RyaW5nRW50cnkge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBTdHJpbmdTdHJpbmdFbnRyeSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAga2V5KCk6IHN0cmluZyB8IG51bGw7XG4gIGtleShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBrZXkob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICB2YWx1ZSgpOiBzdHJpbmcgfCBudWxsO1xuICB2YWx1ZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICB2YWx1ZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFN0cmluZ1N0cmluZ0VudHJ5KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDIpO1xuICB9XG5cbiAgc3RhdGljIGFkZEtleShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBrZXlPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwga2V5T2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRWYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB2YWx1ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCB2YWx1ZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kU3RyaW5nU3RyaW5nRW50cnkoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVN0cmluZ1N0cmluZ0VudHJ5KFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAga2V5T2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgdmFsdWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBTdHJpbmdTdHJpbmdFbnRyeS5zdGFydFN0cmluZ1N0cmluZ0VudHJ5KGJ1aWxkZXIpO1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5LmFkZEtleShidWlsZGVyLCBrZXlPZmZzZXQpO1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5LmFkZFZhbHVlKGJ1aWxkZXIsIHZhbHVlT2Zmc2V0KTtcbiAgICByZXR1cm4gU3RyaW5nU3RyaW5nRW50cnkuZW5kU3RyaW5nU3RyaW5nRW50cnkoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvZ3JhcGguanMnO1xuaW1wb3J0IHsgT3BlcmF0b3JTZXRJZCB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9vcGVyYXRvci1zZXQtaWQuanMnO1xuaW1wb3J0IHsgU3RyaW5nU3RyaW5nRW50cnkgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvc3RyaW5nLXN0cmluZy1lbnRyeS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBNb2RlbCB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogTW9kZWwge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzTW9kZWwoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE1vZGVsKTogTW9kZWwge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBNb2RlbCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc01vZGVsKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBNb2RlbCk6IE1vZGVsIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgTW9kZWwoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGlyVmVyc2lvbigpOiBiaWdpbnQge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IEJpZ0ludCgnMCcpO1xuICB9XG5cbiAgb3BzZXRJbXBvcnQoaW5kZXg6IG51bWJlciwgb2JqPzogT3BlcmF0b3JTZXRJZCk6IE9wZXJhdG9yU2V0SWQgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBPcGVyYXRvclNldElkKCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIG9wc2V0SW1wb3J0TGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHByb2R1Y2VyTmFtZSgpOiBzdHJpbmcgfCBudWxsO1xuICBwcm9kdWNlck5hbWUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgcHJvZHVjZXJOYW1lKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgcHJvZHVjZXJWZXJzaW9uKCk6IHN0cmluZyB8IG51bGw7XG4gIHByb2R1Y2VyVmVyc2lvbihvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBwcm9kdWNlclZlcnNpb24ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgZG9tYWluKCk6IHN0cmluZyB8IG51bGw7XG4gIGRvbWFpbihvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBkb21haW4ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgbW9kZWxWZXJzaW9uKCk6IGJpZ2ludCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IEJpZ0ludCgnMCcpO1xuICB9XG5cbiAgZG9jU3RyaW5nKCk6IHN0cmluZyB8IG51bGw7XG4gIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgZ3JhcGgob2JqPzogR3JhcGgpOiBHcmFwaCB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IEdyYXBoKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDogbnVsbDtcbiAgfVxuXG4gIGdyYXBoRG9jU3RyaW5nKCk6IHN0cmluZyB8IG51bGw7XG4gIGdyYXBoRG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGdyYXBoRG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDIwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIG1ldGFkYXRhUHJvcHMoaW5kZXg6IG51bWJlciwgb2JqPzogU3RyaW5nU3RyaW5nRW50cnkpOiBTdHJpbmdTdHJpbmdFbnRyeSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBTdHJpbmdTdHJpbmdFbnRyeSgpKS5fX2luaXQoXG4gICAgICAgICAgdGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLFxuICAgICAgICAgIHRoaXMuYmIhLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBtZXRhZGF0YVByb3BzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDIyKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRNb2RlbChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgxMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSXJWZXJzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGlyVmVyc2lvbjogYmlnaW50KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDAsIGlyVmVyc2lvbiwgQmlnSW50KCcwJykpO1xuICB9XG5cbiAgc3RhdGljIGFkZE9wc2V0SW1wb3J0KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG9wc2V0SW1wb3J0T2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIG9wc2V0SW1wb3J0T2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVPcHNldEltcG9ydFZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRPcHNldEltcG9ydFZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkUHJvZHVjZXJOYW1lKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHByb2R1Y2VyTmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgyLCBwcm9kdWNlck5hbWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZFByb2R1Y2VyVmVyc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBwcm9kdWNlclZlcnNpb25PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMywgcHJvZHVjZXJWZXJzaW9uT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREb21haW4oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9tYWluT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDQsIGRvbWFpbk9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkTW9kZWxWZXJzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG1vZGVsVmVyc2lvbjogYmlnaW50KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDUsIG1vZGVsVmVyc2lvbiwgQmlnSW50KCcwJykpO1xuICB9XG5cbiAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNiwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRHcmFwaChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBncmFwaE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg3LCBncmFwaE9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkR3JhcGhEb2NTdHJpbmcoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZ3JhcGhEb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoOCwgZ3JhcGhEb2NTdHJpbmdPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZE1ldGFkYXRhUHJvcHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbWV0YWRhdGFQcm9wc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg5LCBtZXRhZGF0YVByb3BzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVNZXRhZGF0YVByb3BzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE1ldGFkYXRhUHJvcHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGVuZE1vZGVsKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMva2VybmVsLXR5cGUtc3RyLXJlc29sdmVyLmpzJztcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL21vZGVsLmpzJztcblxuZXhwb3J0IGNsYXNzIEluZmVyZW5jZVNlc3Npb24ge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IEluZmVyZW5jZVNlc3Npb24ge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzSW5mZXJlbmNlU2Vzc2lvbihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogSW5mZXJlbmNlU2Vzc2lvbik6IEluZmVyZW5jZVNlc3Npb24ge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBJbmZlcmVuY2VTZXNzaW9uKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzSW5mZXJlbmNlU2Vzc2lvbihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogSW5mZXJlbmNlU2Vzc2lvbik6IEluZmVyZW5jZVNlc3Npb24ge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBJbmZlcmVuY2VTZXNzaW9uKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgYnVmZmVySGFzSWRlbnRpZmllcihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBiYi5fX2hhc19pZGVudGlmaWVyKCdPUlRNJyk7XG4gIH1cblxuICBvcnRWZXJzaW9uKCk6IHN0cmluZyB8IG51bGw7XG4gIG9ydFZlcnNpb24ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgb3J0VmVyc2lvbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIG1vZGVsKG9iaj86IE1vZGVsKTogTW9kZWwgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IE1vZGVsKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDogbnVsbDtcbiAgfVxuXG4gIGtlcm5lbFR5cGVTdHJSZXNvbHZlcihvYmo/OiBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIpOiBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgS2VybmVsVHlwZVN0clJlc29sdmVyKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbmZlcmVuY2VTZXNzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZE9ydFZlcnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3J0VmVyc2lvbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBvcnRWZXJzaW9uT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRNb2RlbChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBtb2RlbE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBtb2RlbE9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkS2VybmVsVHlwZVN0clJlc29sdmVyKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbFR5cGVTdHJSZXNvbHZlck9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgzLCBrZXJuZWxUeXBlU3RyUmVzb2x2ZXJPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZEluZmVyZW5jZVNlc3Npb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGZpbmlzaEluZmVyZW5jZVNlc3Npb25CdWZmZXIoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmZpbmlzaChvZmZzZXQsICdPUlRNJyk7XG4gIH1cblxuICBzdGF0aWMgZmluaXNoU2l6ZVByZWZpeGVkSW5mZXJlbmNlU2Vzc2lvbkJ1ZmZlcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuZmluaXNoKG9mZnNldCwgJ09SVE0nLCB0cnVlKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuZXhwb3J0IHsgQXJnVHlwZSB9IGZyb20gJy4vZmJzL2FyZy10eXBlLmpzJztcbmV4cG9ydCB7IEFyZ1R5cGVBbmRJbmRleCB9IGZyb20gJy4vZmJzL2FyZy10eXBlLWFuZC1pbmRleC5qcyc7XG5leHBvcnQgeyBBdHRyaWJ1dGUgfSBmcm9tICcuL2Zicy9hdHRyaWJ1dGUuanMnO1xuZXhwb3J0IHsgQXR0cmlidXRlVHlwZSB9IGZyb20gJy4vZmJzL2F0dHJpYnV0ZS10eXBlLmpzJztcbmV4cG9ydCB7IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyB9IGZyb20gJy4vZmJzL2RlcHJlY2F0ZWQta2VybmVsLWNyZWF0ZS1pbmZvcy5qcyc7XG5leHBvcnQgeyBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCB9IGZyb20gJy4vZmJzL2RlcHJlY2F0ZWQtbm9kZS1pbmRleC1hbmQta2VybmVsLWRlZi1oYXNoLmpzJztcbmV4cG9ydCB7IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUgfSBmcm9tICcuL2Zicy9kZXByZWNhdGVkLXNlc3Npb24tc3RhdGUuanMnO1xuZXhwb3J0IHsgRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlIH0gZnJvbSAnLi9mYnMvZGVwcmVjYXRlZC1zdWItZ3JhcGgtc2Vzc2lvbi1zdGF0ZS5qcyc7XG5leHBvcnQgeyBEaW1lbnNpb24gfSBmcm9tICcuL2Zicy9kaW1lbnNpb24uanMnO1xuZXhwb3J0IHsgRGltZW5zaW9uVmFsdWUgfSBmcm9tICcuL2Zicy9kaW1lbnNpb24tdmFsdWUuanMnO1xuZXhwb3J0IHsgRGltZW5zaW9uVmFsdWVUeXBlIH0gZnJvbSAnLi9mYnMvZGltZW5zaW9uLXZhbHVlLXR5cGUuanMnO1xuZXhwb3J0IHsgRWRnZUVuZCB9IGZyb20gJy4vZmJzL2VkZ2UtZW5kLmpzJztcbmV4cG9ydCB7IEdyYXBoIH0gZnJvbSAnLi9mYnMvZ3JhcGguanMnO1xuZXhwb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbiB9IGZyb20gJy4vZmJzL2luZmVyZW5jZS1zZXNzaW9uLmpzJztcbmV4cG9ydCB7IEtlcm5lbFR5cGVTdHJBcmdzRW50cnkgfSBmcm9tICcuL2Zicy9rZXJuZWwtdHlwZS1zdHItYXJncy1lbnRyeS5qcyc7XG5leHBvcnQgeyBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIgfSBmcm9tICcuL2Zicy9rZXJuZWwtdHlwZS1zdHItcmVzb2x2ZXIuanMnO1xuZXhwb3J0IHsgTWFwVHlwZSB9IGZyb20gJy4vZmJzL21hcC10eXBlLmpzJztcbmV4cG9ydCB7IE1vZGVsIH0gZnJvbSAnLi9mYnMvbW9kZWwuanMnO1xuZXhwb3J0IHsgTm9kZSB9IGZyb20gJy4vZmJzL25vZGUuanMnO1xuZXhwb3J0IHsgTm9kZUVkZ2UgfSBmcm9tICcuL2Zicy9ub2RlLWVkZ2UuanMnO1xuZXhwb3J0IHsgTm9kZVR5cGUgfSBmcm9tICcuL2Zicy9ub2RlLXR5cGUuanMnO1xuZXhwb3J0IHsgTm9kZXNUb09wdGltaXplSW5kaWNlcyB9IGZyb20gJy4vZmJzL25vZGVzLXRvLW9wdGltaXplLWluZGljZXMuanMnO1xuZXhwb3J0IHsgT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkgfSBmcm9tICcuL2Zicy9vcC1pZC1rZXJuZWwtdHlwZS1zdHItYXJncy1lbnRyeS5qcyc7XG5leHBvcnQgeyBPcGVyYXRvclNldElkIH0gZnJvbSAnLi9mYnMvb3BlcmF0b3Itc2V0LWlkLmpzJztcbmV4cG9ydCB7IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQgfSBmcm9tICcuL2Zicy9ydW50aW1lLW9wdGltaXphdGlvbi1yZWNvcmQuanMnO1xuZXhwb3J0IHsgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5IH0gZnJvbSAnLi9mYnMvcnVudGltZS1vcHRpbWl6YXRpb24tcmVjb3JkLWNvbnRhaW5lci1lbnRyeS5qcyc7XG5leHBvcnQgeyBSdW50aW1lT3B0aW1pemF0aW9ucyB9IGZyb20gJy4vZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9ucy5qcyc7XG5leHBvcnQgeyBTZXF1ZW5jZVR5cGUgfSBmcm9tICcuL2Zicy9zZXF1ZW5jZS10eXBlLmpzJztcbmV4cG9ydCB7IFNoYXBlIH0gZnJvbSAnLi9mYnMvc2hhcGUuanMnO1xuZXhwb3J0IHsgU3BhcnNlVGVuc29yIH0gZnJvbSAnLi9mYnMvc3BhcnNlLXRlbnNvci5qcyc7XG5leHBvcnQgeyBTdHJpbmdTdHJpbmdFbnRyeSB9IGZyb20gJy4vZmJzL3N0cmluZy1zdHJpbmctZW50cnkuanMnO1xuZXhwb3J0IHsgVGVuc29yIH0gZnJvbSAnLi9mYnMvdGVuc29yLmpzJztcbmV4cG9ydCB7IFRlbnNvckRhdGFUeXBlIH0gZnJvbSAnLi9mYnMvdGVuc29yLWRhdGEtdHlwZS5qcyc7XG5leHBvcnQgeyBUZW5zb3JUeXBlQW5kU2hhcGUgfSBmcm9tICcuL2Zicy90ZW5zb3ItdHlwZS1hbmQtc2hhcGUuanMnO1xuZXhwb3J0IHsgVHlwZUluZm8gfSBmcm9tICcuL2Zicy90eXBlLWluZm8uanMnO1xuZXhwb3J0IHsgVHlwZUluZm9WYWx1ZSB9IGZyb20gJy4vZmJzL3R5cGUtaW5mby12YWx1ZS5qcyc7XG5leHBvcnQgeyBWYWx1ZUluZm8gfSBmcm9tICcuL2Zicy92YWx1ZS1pbmZvLmpzJztcbiIsICJleHBvcnQgKiBmcm9tICcuL29ubnhydW50aW1lL2Zicyc7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XHJcbm1vZHVsZS5leHBvcnRzID0gYXNQcm9taXNlO1xyXG5cclxuLyoqXHJcbiAqIENhbGxiYWNrIGFzIHVzZWQgYnkge0BsaW5rIHV0aWwuYXNQcm9taXNlfS5cclxuICogQHR5cGVkZWYgYXNQcm9taXNlQ2FsbGJhY2tcclxuICogQHR5cGUge2Z1bmN0aW9ufVxyXG4gKiBAcGFyYW0ge0Vycm9yfG51bGx9IGVycm9yIEVycm9yLCBpZiBhbnlcclxuICogQHBhcmFtIHsuLi4qfSBwYXJhbXMgQWRkaXRpb25hbCBhcmd1bWVudHNcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIHByb21pc2UgZnJvbSBhIG5vZGUtc3R5bGUgY2FsbGJhY2sgZnVuY3Rpb24uXHJcbiAqIEBtZW1iZXJvZiB1dGlsXHJcbiAqIEBwYXJhbSB7YXNQcm9taXNlQ2FsbGJhY2t9IGZuIEZ1bmN0aW9uIHRvIGNhbGxcclxuICogQHBhcmFtIHsqfSBjdHggRnVuY3Rpb24gY29udGV4dFxyXG4gKiBAcGFyYW0gey4uLip9IHBhcmFtcyBGdW5jdGlvbiBhcmd1bWVudHNcclxuICogQHJldHVybnMge1Byb21pc2U8Kj59IFByb21pc2lmaWVkIGZ1bmN0aW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBhc1Byb21pc2UoZm4sIGN0eC8qLCB2YXJhcmdzICovKSB7XHJcbiAgICB2YXIgcGFyYW1zICA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSksXHJcbiAgICAgICAgb2Zmc2V0ICA9IDAsXHJcbiAgICAgICAgaW5kZXggICA9IDIsXHJcbiAgICAgICAgcGVuZGluZyA9IHRydWU7XHJcbiAgICB3aGlsZSAoaW5kZXggPCBhcmd1bWVudHMubGVuZ3RoKVxyXG4gICAgICAgIHBhcmFtc1tvZmZzZXQrK10gPSBhcmd1bWVudHNbaW5kZXgrK107XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gZXhlY3V0b3IocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgcGFyYW1zW29mZnNldF0gPSBmdW5jdGlvbiBjYWxsYmFjayhlcnIvKiwgdmFyYXJncyAqLykge1xyXG4gICAgICAgICAgICBpZiAocGVuZGluZykge1xyXG4gICAgICAgICAgICAgICAgcGVuZGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycilcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJhbXMgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChvZmZzZXQgPCBwYXJhbXMubGVuZ3RoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXNbb2Zmc2V0KytdID0gYXJndW1lbnRzW29mZnNldF07XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZS5hcHBseShudWxsLCBwYXJhbXMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBmbi5hcHBseShjdHggfHwgbnVsbCwgcGFyYW1zKTtcclxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgaWYgKHBlbmRpbmcpIHtcclxuICAgICAgICAgICAgICAgIHBlbmRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbn1cclxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5cclxuLyoqXHJcbiAqIEEgbWluaW1hbCBiYXNlNjQgaW1wbGVtZW50YXRpb24gZm9yIG51bWJlciBhcnJheXMuXHJcbiAqIEBtZW1iZXJvZiB1dGlsXHJcbiAqIEBuYW1lc3BhY2VcclxuICovXHJcbnZhciBiYXNlNjQgPSBleHBvcnRzO1xyXG5cclxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIGJ5dGUgbGVuZ3RoIG9mIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIEJhc2U2NCBlbmNvZGVkIHN0cmluZ1xyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBCeXRlIGxlbmd0aFxyXG4gKi9cclxuYmFzZTY0Lmxlbmd0aCA9IGZ1bmN0aW9uIGxlbmd0aChzdHJpbmcpIHtcclxuICAgIHZhciBwID0gc3RyaW5nLmxlbmd0aDtcclxuICAgIGlmICghcClcclxuICAgICAgICByZXR1cm4gMDtcclxuICAgIHZhciBuID0gMDtcclxuICAgIHdoaWxlICgtLXAgJSA0ID4gMSAmJiBzdHJpbmcuY2hhckF0KHApID09PSBcIj1cIilcclxuICAgICAgICArK247XHJcbiAgICByZXR1cm4gTWF0aC5jZWlsKHN0cmluZy5sZW5ndGggKiAzKSAvIDQgLSBuO1xyXG59O1xyXG5cclxuLy8gQmFzZTY0IGVuY29kaW5nIHRhYmxlXHJcbnZhciBiNjQgPSBuZXcgQXJyYXkoNjQpO1xyXG5cclxuLy8gQmFzZTY0IGRlY29kaW5nIHRhYmxlXHJcbnZhciBzNjQgPSBuZXcgQXJyYXkoMTIzKTtcclxuXHJcbi8vIDY1Li45MCwgOTcuLjEyMiwgNDguLjU3LCA0MywgNDdcclxuZm9yICh2YXIgaSA9IDA7IGkgPCA2NDspXHJcbiAgICBzNjRbYjY0W2ldID0gaSA8IDI2ID8gaSArIDY1IDogaSA8IDUyID8gaSArIDcxIDogaSA8IDYyID8gaSAtIDQgOiBpIC0gNTkgfCA0M10gPSBpKys7XHJcblxyXG4vKipcclxuICogRW5jb2RlcyBhIGJ1ZmZlciB0byBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZy5cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWZmZXIgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgU291cmNlIHN0YXJ0XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgU291cmNlIGVuZFxyXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBCYXNlNjQgZW5jb2RlZCBzdHJpbmdcclxuICovXHJcbmJhc2U2NC5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoYnVmZmVyLCBzdGFydCwgZW5kKSB7XHJcbiAgICB2YXIgcGFydHMgPSBudWxsLFxyXG4gICAgICAgIGNodW5rID0gW107XHJcbiAgICB2YXIgaSA9IDAsIC8vIG91dHB1dCBpbmRleFxyXG4gICAgICAgIGogPSAwLCAvLyBnb3RvIGluZGV4XHJcbiAgICAgICAgdDsgICAgIC8vIHRlbXBvcmFyeVxyXG4gICAgd2hpbGUgKHN0YXJ0IDwgZW5kKSB7XHJcbiAgICAgICAgdmFyIGIgPSBidWZmZXJbc3RhcnQrK107XHJcbiAgICAgICAgc3dpdGNoIChqKSB7XHJcbiAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgIGNodW5rW2krK10gPSBiNjRbYiA+PiAyXTtcclxuICAgICAgICAgICAgICAgIHQgPSAoYiAmIDMpIDw8IDQ7XHJcbiAgICAgICAgICAgICAgICBqID0gMTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICBjaHVua1tpKytdID0gYjY0W3QgfCBiID4+IDRdO1xyXG4gICAgICAgICAgICAgICAgdCA9IChiICYgMTUpIDw8IDI7XHJcbiAgICAgICAgICAgICAgICBqID0gMjtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICBjaHVua1tpKytdID0gYjY0W3QgfCBiID4+IDZdO1xyXG4gICAgICAgICAgICAgICAgY2h1bmtbaSsrXSA9IGI2NFtiICYgNjNdO1xyXG4gICAgICAgICAgICAgICAgaiA9IDA7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGkgPiA4MTkxKSB7XHJcbiAgICAgICAgICAgIChwYXJ0cyB8fCAocGFydHMgPSBbXSkpLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNodW5rKSk7XHJcbiAgICAgICAgICAgIGkgPSAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChqKSB7XHJcbiAgICAgICAgY2h1bmtbaSsrXSA9IGI2NFt0XTtcclxuICAgICAgICBjaHVua1tpKytdID0gNjE7XHJcbiAgICAgICAgaWYgKGogPT09IDEpXHJcbiAgICAgICAgICAgIGNodW5rW2krK10gPSA2MTtcclxuICAgIH1cclxuICAgIGlmIChwYXJ0cykge1xyXG4gICAgICAgIGlmIChpKVxyXG4gICAgICAgICAgICBwYXJ0cy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaHVuay5zbGljZSgwLCBpKSkpO1xyXG4gICAgICAgIHJldHVybiBwYXJ0cy5qb2luKFwiXCIpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaHVuay5zbGljZSgwLCBpKSk7XHJcbn07XHJcblxyXG52YXIgaW52YWxpZEVuY29kaW5nID0gXCJpbnZhbGlkIGVuY29kaW5nXCI7XHJcblxyXG4vKipcclxuICogRGVjb2RlcyBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZyB0byBhIGJ1ZmZlci5cclxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBTb3VyY2Ugc3RyaW5nXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmZmVyIERlc3RpbmF0aW9uIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IERlc3RpbmF0aW9uIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2YgYnl0ZXMgd3JpdHRlblxyXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgZW5jb2RpbmcgaXMgaW52YWxpZFxyXG4gKi9cclxuYmFzZTY0LmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShzdHJpbmcsIGJ1ZmZlciwgb2Zmc2V0KSB7XHJcbiAgICB2YXIgc3RhcnQgPSBvZmZzZXQ7XHJcbiAgICB2YXIgaiA9IDAsIC8vIGdvdG8gaW5kZXhcclxuICAgICAgICB0OyAgICAgLy8gdGVtcG9yYXJ5XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7KSB7XHJcbiAgICAgICAgdmFyIGMgPSBzdHJpbmcuY2hhckNvZGVBdChpKyspO1xyXG4gICAgICAgIGlmIChjID09PSA2MSAmJiBqID4gMSlcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgaWYgKChjID0gczY0W2NdKSA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihpbnZhbGlkRW5jb2RpbmcpO1xyXG4gICAgICAgIHN3aXRjaCAoaikge1xyXG4gICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICB0ID0gYztcclxuICAgICAgICAgICAgICAgIGogPSAxO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSB0IDw8IDIgfCAoYyAmIDQ4KSA+PiA0O1xyXG4gICAgICAgICAgICAgICAgdCA9IGM7XHJcbiAgICAgICAgICAgICAgICBqID0gMjtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gKHQgJiAxNSkgPDwgNCB8IChjICYgNjApID4+IDI7XHJcbiAgICAgICAgICAgICAgICB0ID0gYztcclxuICAgICAgICAgICAgICAgIGogPSAzO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSAodCAmIDMpIDw8IDYgfCBjO1xyXG4gICAgICAgICAgICAgICAgaiA9IDA7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoaiA9PT0gMSlcclxuICAgICAgICB0aHJvdyBFcnJvcihpbnZhbGlkRW5jb2RpbmcpO1xyXG4gICAgcmV0dXJuIG9mZnNldCAtIHN0YXJ0O1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFwcGVhcnMgdG8gYmUgYmFzZTY0IGVuY29kZWQuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgU3RyaW5nIHRvIHRlc3RcclxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiBwcm9iYWJseSBiYXNlNjQgZW5jb2RlZCwgb3RoZXJ3aXNlIGZhbHNlXHJcbiAqL1xyXG5iYXNlNjQudGVzdCA9IGZ1bmN0aW9uIHRlc3Qoc3RyaW5nKSB7XHJcbiAgICByZXR1cm4gL14oPzpbQS1aYS16MC05Ky9dezR9KSooPzpbQS1aYS16MC05Ky9dezJ9PT18W0EtWmEtejAtOSsvXXszfT0pPyQvLnRlc3Qoc3RyaW5nKTtcclxufTtcclxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcclxuXHJcbi8qKlxyXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IGV2ZW50IGVtaXR0ZXIgaW5zdGFuY2UuXHJcbiAqIEBjbGFzc2Rlc2MgQSBtaW5pbWFsIGV2ZW50IGVtaXR0ZXIuXHJcbiAqIEBtZW1iZXJvZiB1dGlsXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKi9cclxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVnaXN0ZXJlZCBsaXN0ZW5lcnMuXHJcbiAgICAgKiBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsKj59XHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB0aGlzLl9saXN0ZW5lcnMgPSB7fTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lci5cclxuICogQHBhcmFtIHtzdHJpbmd9IGV2dCBFdmVudCBuYW1lXHJcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGZuIExpc3RlbmVyXHJcbiAqIEBwYXJhbSB7Kn0gW2N0eF0gTGlzdGVuZXIgY29udGV4dFxyXG4gKiBAcmV0dXJucyB7dXRpbC5FdmVudEVtaXR0ZXJ9IGB0aGlzYFxyXG4gKi9cclxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIG9uKGV2dCwgZm4sIGN0eCkge1xyXG4gICAgKHRoaXMuX2xpc3RlbmVyc1tldnRdIHx8ICh0aGlzLl9saXN0ZW5lcnNbZXZ0XSA9IFtdKSkucHVzaCh7XHJcbiAgICAgICAgZm4gIDogZm4sXHJcbiAgICAgICAgY3R4IDogY3R4IHx8IHRoaXNcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogUmVtb3ZlcyBhbiBldmVudCBsaXN0ZW5lciBvciBhbnkgbWF0Y2hpbmcgbGlzdGVuZXJzIGlmIGFyZ3VtZW50cyBhcmUgb21pdHRlZC5cclxuICogQHBhcmFtIHtzdHJpbmd9IFtldnRdIEV2ZW50IG5hbWUuIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBpZiBvbWl0dGVkLlxyXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBbZm5dIExpc3RlbmVyIHRvIHJlbW92ZS4gUmVtb3ZlcyBhbGwgbGlzdGVuZXJzIG9mIGBldnRgIGlmIG9taXR0ZWQuXHJcbiAqIEByZXR1cm5zIHt1dGlsLkV2ZW50RW1pdHRlcn0gYHRoaXNgXHJcbiAqL1xyXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIG9mZihldnQsIGZuKSB7XHJcbiAgICBpZiAoZXZ0ID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgdGhpcy5fbGlzdGVuZXJzID0ge307XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBpZiAoZm4gPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzW2V2dF0gPSBbXTtcclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVyc1tldnRdO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7KVxyXG4gICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyc1tpXS5mbiA9PT0gZm4pXHJcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpLCAxKTtcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICArK2k7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogRW1pdHMgYW4gZXZlbnQgYnkgY2FsbGluZyBpdHMgbGlzdGVuZXJzIHdpdGggdGhlIHNwZWNpZmllZCBhcmd1bWVudHMuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBldnQgRXZlbnQgbmFtZVxyXG4gKiBAcGFyYW0gey4uLip9IGFyZ3MgQXJndW1lbnRzXHJcbiAqIEByZXR1cm5zIHt1dGlsLkV2ZW50RW1pdHRlcn0gYHRoaXNgXHJcbiAqL1xyXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiBlbWl0KGV2dCkge1xyXG4gICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVyc1tldnRdO1xyXG4gICAgaWYgKGxpc3RlbmVycykge1xyXG4gICAgICAgIHZhciBhcmdzID0gW10sXHJcbiAgICAgICAgICAgIGkgPSAxO1xyXG4gICAgICAgIGZvciAoOyBpIDwgYXJndW1lbnRzLmxlbmd0aDspXHJcbiAgICAgICAgICAgIGFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XHJcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7KVxyXG4gICAgICAgICAgICBsaXN0ZW5lcnNbaV0uZm4uYXBwbHkobGlzdGVuZXJzW2krK10uY3R4LCBhcmdzKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG59O1xyXG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoZmFjdG9yeSk7XHJcblxyXG4vKipcclxuICogUmVhZHMgLyB3cml0ZXMgZmxvYXRzIC8gZG91YmxlcyBmcm9tIC8gdG8gYnVmZmVycy5cclxuICogQG5hbWUgdXRpbC5mbG9hdFxyXG4gKiBAbmFtZXNwYWNlXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFdyaXRlcyBhIDMyIGJpdCBmbG9hdCB0byBhIGJ1ZmZlciB1c2luZyBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQud3JpdGVGbG9hdExFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsIFZhbHVlIHRvIHdyaXRlXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmIFRhcmdldCBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHBvcyBUYXJnZXQgYnVmZmVyIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBXcml0ZXMgYSAzMiBiaXQgZmxvYXQgdG8gYSBidWZmZXIgdXNpbmcgYmlnIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LndyaXRlRmxvYXRCRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBUYXJnZXQgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgVGFyZ2V0IGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogUmVhZHMgYSAzMiBiaXQgZmxvYXQgZnJvbSBhIGJ1ZmZlciB1c2luZyBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQucmVhZEZsb2F0TEVcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmIFNvdXJjZSBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHBvcyBTb3VyY2UgYnVmZmVyIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFJlYWRzIGEgMzIgYml0IGZsb2F0IGZyb20gYSBidWZmZXIgdXNpbmcgYmlnIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LnJlYWRGbG9hdEJFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBTb3VyY2UgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgU291cmNlIGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBXcml0ZXMgYSA2NCBiaXQgZG91YmxlIHRvIGEgYnVmZmVyIHVzaW5nIGxpdHRsZSBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC53cml0ZURvdWJsZUxFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsIFZhbHVlIHRvIHdyaXRlXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmIFRhcmdldCBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHBvcyBUYXJnZXQgYnVmZmVyIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBXcml0ZXMgYSA2NCBiaXQgZG91YmxlIHRvIGEgYnVmZmVyIHVzaW5nIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC53cml0ZURvdWJsZUJFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsIFZhbHVlIHRvIHdyaXRlXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmIFRhcmdldCBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHBvcyBUYXJnZXQgYnVmZmVyIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBSZWFkcyBhIDY0IGJpdCBkb3VibGUgZnJvbSBhIGJ1ZmZlciB1c2luZyBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQucmVhZERvdWJsZUxFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBTb3VyY2UgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgU291cmNlIGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBSZWFkcyBhIDY0IGJpdCBkb3VibGUgZnJvbSBhIGJ1ZmZlciB1c2luZyBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQucmVhZERvdWJsZUJFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBTb3VyY2UgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgU291cmNlIGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gKi9cclxuXHJcbi8vIEZhY3RvcnkgZnVuY3Rpb24gZm9yIHRoZSBwdXJwb3NlIG9mIG5vZGUtYmFzZWQgdGVzdGluZyBpbiBtb2RpZmllZCBnbG9iYWwgZW52aXJvbm1lbnRzXHJcbmZ1bmN0aW9uIGZhY3RvcnkoZXhwb3J0cykge1xyXG5cclxuICAgIC8vIGZsb2F0OiB0eXBlZCBhcnJheVxyXG4gICAgaWYgKHR5cGVvZiBGbG9hdDMyQXJyYXkgIT09IFwidW5kZWZpbmVkXCIpIChmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIGYzMiA9IG5ldyBGbG9hdDMyQXJyYXkoWyAtMCBdKSxcclxuICAgICAgICAgICAgZjhiID0gbmV3IFVpbnQ4QXJyYXkoZjMyLmJ1ZmZlciksXHJcbiAgICAgICAgICAgIGxlICA9IGY4YlszXSA9PT0gMTI4O1xyXG5cclxuICAgICAgICBmdW5jdGlvbiB3cml0ZUZsb2F0X2YzMl9jcHkodmFsLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmMzJbMF0gPSB2YWw7XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgICAgXSA9IGY4YlswXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDFdID0gZjhiWzFdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMl0gPSBmOGJbMl07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAzXSA9IGY4YlszXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHdyaXRlRmxvYXRfZjMyX3Jldih2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGYzMlswXSA9IHZhbDtcclxuICAgICAgICAgICAgYnVmW3BvcyAgICBdID0gZjhiWzNdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMV0gPSBmOGJbMl07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAyXSA9IGY4YlsxXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDNdID0gZjhiWzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLndyaXRlRmxvYXRMRSA9IGxlID8gd3JpdGVGbG9hdF9mMzJfY3B5IDogd3JpdGVGbG9hdF9mMzJfcmV2O1xyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy53cml0ZUZsb2F0QkUgPSBsZSA/IHdyaXRlRmxvYXRfZjMyX3JldiA6IHdyaXRlRmxvYXRfZjMyX2NweTtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gcmVhZEZsb2F0X2YzMl9jcHkoYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjhiWzBdID0gYnVmW3BvcyAgICBdO1xyXG4gICAgICAgICAgICBmOGJbMV0gPSBidWZbcG9zICsgMV07XHJcbiAgICAgICAgICAgIGY4YlsyXSA9IGJ1Zltwb3MgKyAyXTtcclxuICAgICAgICAgICAgZjhiWzNdID0gYnVmW3BvcyArIDNdO1xyXG4gICAgICAgICAgICByZXR1cm4gZjMyWzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gcmVhZEZsb2F0X2YzMl9yZXYoYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjhiWzNdID0gYnVmW3BvcyAgICBdO1xyXG4gICAgICAgICAgICBmOGJbMl0gPSBidWZbcG9zICsgMV07XHJcbiAgICAgICAgICAgIGY4YlsxXSA9IGJ1Zltwb3MgKyAyXTtcclxuICAgICAgICAgICAgZjhiWzBdID0gYnVmW3BvcyArIDNdO1xyXG4gICAgICAgICAgICByZXR1cm4gZjMyWzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLnJlYWRGbG9hdExFID0gbGUgPyByZWFkRmxvYXRfZjMyX2NweSA6IHJlYWRGbG9hdF9mMzJfcmV2O1xyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRmxvYXRCRSA9IGxlID8gcmVhZEZsb2F0X2YzMl9yZXYgOiByZWFkRmxvYXRfZjMyX2NweTtcclxuXHJcbiAgICAvLyBmbG9hdDogaWVlZTc1NFxyXG4gICAgfSkoKTsgZWxzZSAoZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHdyaXRlRmxvYXRfaWVlZTc1NCh3cml0ZVVpbnQsIHZhbCwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgdmFyIHNpZ24gPSB2YWwgPCAwID8gMSA6IDA7XHJcbiAgICAgICAgICAgIGlmIChzaWduKVxyXG4gICAgICAgICAgICAgICAgdmFsID0gLXZhbDtcclxuICAgICAgICAgICAgaWYgKHZhbCA9PT0gMClcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgxIC8gdmFsID4gMCA/IC8qIHBvc2l0aXZlICovIDAgOiAvKiBuZWdhdGl2ZSAwICovIDIxNDc0ODM2NDgsIGJ1ZiwgcG9zKTtcclxuICAgICAgICAgICAgZWxzZSBpZiAoaXNOYU4odmFsKSlcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgyMTQzMjg5MzQ0LCBidWYsIHBvcyk7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbCA+IDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpIC8vICstSW5maW5pdHlcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgoc2lnbiA8PCAzMSB8IDIxMzkwOTUwNDApID4+PiAwLCBidWYsIHBvcyk7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbCA8IDEuMTc1NDk0MzUwODIyMjg3NWUtMzgpIC8vIGRlbm9ybWFsXHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoKHNpZ24gPDwgMzEgfCBNYXRoLnJvdW5kKHZhbCAvIDEuNDAxMjk4NDY0MzI0ODE3ZS00NSkpID4+PiAwLCBidWYsIHBvcyk7XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdmFyIGV4cG9uZW50ID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWwpIC8gTWF0aC5MTjIpLFxyXG4gICAgICAgICAgICAgICAgICAgIG1hbnRpc3NhID0gTWF0aC5yb3VuZCh2YWwgKiBNYXRoLnBvdygyLCAtZXhwb25lbnQpICogODM4ODYwOCkgJiA4Mzg4NjA3O1xyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KChzaWduIDw8IDMxIHwgZXhwb25lbnQgKyAxMjcgPDwgMjMgfCBtYW50aXNzYSkgPj4+IDAsIGJ1ZiwgcG9zKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZXhwb3J0cy53cml0ZUZsb2F0TEUgPSB3cml0ZUZsb2F0X2llZWU3NTQuYmluZChudWxsLCB3cml0ZVVpbnRMRSk7XHJcbiAgICAgICAgZXhwb3J0cy53cml0ZUZsb2F0QkUgPSB3cml0ZUZsb2F0X2llZWU3NTQuYmluZChudWxsLCB3cml0ZVVpbnRCRSk7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHJlYWRGbG9hdF9pZWVlNzU0KHJlYWRVaW50LCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICB2YXIgdWludCA9IHJlYWRVaW50KGJ1ZiwgcG9zKSxcclxuICAgICAgICAgICAgICAgIHNpZ24gPSAodWludCA+PiAzMSkgKiAyICsgMSxcclxuICAgICAgICAgICAgICAgIGV4cG9uZW50ID0gdWludCA+Pj4gMjMgJiAyNTUsXHJcbiAgICAgICAgICAgICAgICBtYW50aXNzYSA9IHVpbnQgJiA4Mzg4NjA3O1xyXG4gICAgICAgICAgICByZXR1cm4gZXhwb25lbnQgPT09IDI1NVxyXG4gICAgICAgICAgICAgICAgPyBtYW50aXNzYVxyXG4gICAgICAgICAgICAgICAgPyBOYU5cclxuICAgICAgICAgICAgICAgIDogc2lnbiAqIEluZmluaXR5XHJcbiAgICAgICAgICAgICAgICA6IGV4cG9uZW50ID09PSAwIC8vIGRlbm9ybWFsXHJcbiAgICAgICAgICAgICAgICA/IHNpZ24gKiAxLjQwMTI5ODQ2NDMyNDgxN2UtNDUgKiBtYW50aXNzYVxyXG4gICAgICAgICAgICAgICAgOiBzaWduICogTWF0aC5wb3coMiwgZXhwb25lbnQgLSAxNTApICogKG1hbnRpc3NhICsgODM4ODYwOCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBleHBvcnRzLnJlYWRGbG9hdExFID0gcmVhZEZsb2F0X2llZWU3NTQuYmluZChudWxsLCByZWFkVWludExFKTtcclxuICAgICAgICBleHBvcnRzLnJlYWRGbG9hdEJFID0gcmVhZEZsb2F0X2llZWU3NTQuYmluZChudWxsLCByZWFkVWludEJFKTtcclxuXHJcbiAgICB9KSgpO1xyXG5cclxuICAgIC8vIGRvdWJsZTogdHlwZWQgYXJyYXlcclxuICAgIGlmICh0eXBlb2YgRmxvYXQ2NEFycmF5ICE9PSBcInVuZGVmaW5lZFwiKSAoZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBmNjQgPSBuZXcgRmxvYXQ2NEFycmF5KFstMF0pLFxyXG4gICAgICAgICAgICBmOGIgPSBuZXcgVWludDhBcnJheShmNjQuYnVmZmVyKSxcclxuICAgICAgICAgICAgbGUgID0gZjhiWzddID09PSAxMjg7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHdyaXRlRG91YmxlX2Y2NF9jcHkodmFsLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmNjRbMF0gPSB2YWw7XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgICAgXSA9IGY4YlswXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDFdID0gZjhiWzFdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMl0gPSBmOGJbMl07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAzXSA9IGY4YlszXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDRdID0gZjhiWzRdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgNV0gPSBmOGJbNV07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA2XSA9IGY4Yls2XTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDddID0gZjhiWzddO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gd3JpdGVEb3VibGVfZjY0X3Jldih2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGY2NFswXSA9IHZhbDtcclxuICAgICAgICAgICAgYnVmW3BvcyAgICBdID0gZjhiWzddO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMV0gPSBmOGJbNl07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAyXSA9IGY4Yls1XTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDNdID0gZjhiWzRdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgNF0gPSBmOGJbM107XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA1XSA9IGY4YlsyXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDZdID0gZjhiWzFdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgN10gPSBmOGJbMF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgICAgIGV4cG9ydHMud3JpdGVEb3VibGVMRSA9IGxlID8gd3JpdGVEb3VibGVfZjY0X2NweSA6IHdyaXRlRG91YmxlX2Y2NF9yZXY7XHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLndyaXRlRG91YmxlQkUgPSBsZSA/IHdyaXRlRG91YmxlX2Y2NF9yZXYgOiB3cml0ZURvdWJsZV9mNjRfY3B5O1xyXG5cclxuICAgICAgICBmdW5jdGlvbiByZWFkRG91YmxlX2Y2NF9jcHkoYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjhiWzBdID0gYnVmW3BvcyAgICBdO1xyXG4gICAgICAgICAgICBmOGJbMV0gPSBidWZbcG9zICsgMV07XHJcbiAgICAgICAgICAgIGY4YlsyXSA9IGJ1Zltwb3MgKyAyXTtcclxuICAgICAgICAgICAgZjhiWzNdID0gYnVmW3BvcyArIDNdO1xyXG4gICAgICAgICAgICBmOGJbNF0gPSBidWZbcG9zICsgNF07XHJcbiAgICAgICAgICAgIGY4Yls1XSA9IGJ1Zltwb3MgKyA1XTtcclxuICAgICAgICAgICAgZjhiWzZdID0gYnVmW3BvcyArIDZdO1xyXG4gICAgICAgICAgICBmOGJbN10gPSBidWZbcG9zICsgN107XHJcbiAgICAgICAgICAgIHJldHVybiBmNjRbMF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiByZWFkRG91YmxlX2Y2NF9yZXYoYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjhiWzddID0gYnVmW3BvcyAgICBdO1xyXG4gICAgICAgICAgICBmOGJbNl0gPSBidWZbcG9zICsgMV07XHJcbiAgICAgICAgICAgIGY4Yls1XSA9IGJ1Zltwb3MgKyAyXTtcclxuICAgICAgICAgICAgZjhiWzRdID0gYnVmW3BvcyArIDNdO1xyXG4gICAgICAgICAgICBmOGJbM10gPSBidWZbcG9zICsgNF07XHJcbiAgICAgICAgICAgIGY4YlsyXSA9IGJ1Zltwb3MgKyA1XTtcclxuICAgICAgICAgICAgZjhiWzFdID0gYnVmW3BvcyArIDZdO1xyXG4gICAgICAgICAgICBmOGJbMF0gPSBidWZbcG9zICsgN107XHJcbiAgICAgICAgICAgIHJldHVybiBmNjRbMF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgICAgIGV4cG9ydHMucmVhZERvdWJsZUxFID0gbGUgPyByZWFkRG91YmxlX2Y2NF9jcHkgOiByZWFkRG91YmxlX2Y2NF9yZXY7XHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLnJlYWREb3VibGVCRSA9IGxlID8gcmVhZERvdWJsZV9mNjRfcmV2IDogcmVhZERvdWJsZV9mNjRfY3B5O1xyXG5cclxuICAgIC8vIGRvdWJsZTogaWVlZTc1NFxyXG4gICAgfSkoKTsgZWxzZSAoZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHdyaXRlRG91YmxlX2llZWU3NTQod3JpdGVVaW50LCBvZmYwLCBvZmYxLCB2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIHZhciBzaWduID0gdmFsIDwgMCA/IDEgOiAwO1xyXG4gICAgICAgICAgICBpZiAoc2lnbilcclxuICAgICAgICAgICAgICAgIHZhbCA9IC12YWw7XHJcbiAgICAgICAgICAgIGlmICh2YWwgPT09IDApIHtcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgwLCBidWYsIHBvcyArIG9mZjApO1xyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KDEgLyB2YWwgPiAwID8gLyogcG9zaXRpdmUgKi8gMCA6IC8qIG5lZ2F0aXZlIDAgKi8gMjE0NzQ4MzY0OCwgYnVmLCBwb3MgKyBvZmYxKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc05hTih2YWwpKSB7XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMCwgYnVmLCBwb3MgKyBvZmYwKTtcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgyMTQ2OTU5MzYwLCBidWYsIHBvcyArIG9mZjEpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbCA+IDEuNzk3NjkzMTM0ODYyMzE1N2UrMzA4KSB7IC8vICstSW5maW5pdHlcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgwLCBidWYsIHBvcyArIG9mZjApO1xyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KChzaWduIDw8IDMxIHwgMjE0NjQzNTA3MikgPj4+IDAsIGJ1ZiwgcG9zICsgb2ZmMSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbWFudGlzc2E7XHJcbiAgICAgICAgICAgICAgICBpZiAodmFsIDwgMi4yMjUwNzM4NTg1MDcyMDE0ZS0zMDgpIHsgLy8gZGVub3JtYWxcclxuICAgICAgICAgICAgICAgICAgICBtYW50aXNzYSA9IHZhbCAvIDVlLTMyNDtcclxuICAgICAgICAgICAgICAgICAgICB3cml0ZVVpbnQobWFudGlzc2EgPj4+IDAsIGJ1ZiwgcG9zICsgb2ZmMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVVaW50KChzaWduIDw8IDMxIHwgbWFudGlzc2EgLyA0Mjk0OTY3Mjk2KSA+Pj4gMCwgYnVmLCBwb3MgKyBvZmYxKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGV4cG9uZW50ID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWwpIC8gTWF0aC5MTjIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChleHBvbmVudCA9PT0gMTAyNClcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwb25lbnQgPSAxMDIzO1xyXG4gICAgICAgICAgICAgICAgICAgIG1hbnRpc3NhID0gdmFsICogTWF0aC5wb3coMiwgLWV4cG9uZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB3cml0ZVVpbnQobWFudGlzc2EgKiA0NTAzNTk5NjI3MzcwNDk2ID4+PiAwLCBidWYsIHBvcyArIG9mZjApO1xyXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlVWludCgoc2lnbiA8PCAzMSB8IGV4cG9uZW50ICsgMTAyMyA8PCAyMCB8IG1hbnRpc3NhICogMTA0ODU3NiAmIDEwNDg1NzUpID4+PiAwLCBidWYsIHBvcyArIG9mZjEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBleHBvcnRzLndyaXRlRG91YmxlTEUgPSB3cml0ZURvdWJsZV9pZWVlNzU0LmJpbmQobnVsbCwgd3JpdGVVaW50TEUsIDAsIDQpO1xyXG4gICAgICAgIGV4cG9ydHMud3JpdGVEb3VibGVCRSA9IHdyaXRlRG91YmxlX2llZWU3NTQuYmluZChudWxsLCB3cml0ZVVpbnRCRSwgNCwgMCk7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHJlYWREb3VibGVfaWVlZTc1NChyZWFkVWludCwgb2ZmMCwgb2ZmMSwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgdmFyIGxvID0gcmVhZFVpbnQoYnVmLCBwb3MgKyBvZmYwKSxcclxuICAgICAgICAgICAgICAgIGhpID0gcmVhZFVpbnQoYnVmLCBwb3MgKyBvZmYxKTtcclxuICAgICAgICAgICAgdmFyIHNpZ24gPSAoaGkgPj4gMzEpICogMiArIDEsXHJcbiAgICAgICAgICAgICAgICBleHBvbmVudCA9IGhpID4+PiAyMCAmIDIwNDcsXHJcbiAgICAgICAgICAgICAgICBtYW50aXNzYSA9IDQyOTQ5NjcyOTYgKiAoaGkgJiAxMDQ4NTc1KSArIGxvO1xyXG4gICAgICAgICAgICByZXR1cm4gZXhwb25lbnQgPT09IDIwNDdcclxuICAgICAgICAgICAgICAgID8gbWFudGlzc2FcclxuICAgICAgICAgICAgICAgID8gTmFOXHJcbiAgICAgICAgICAgICAgICA6IHNpZ24gKiBJbmZpbml0eVxyXG4gICAgICAgICAgICAgICAgOiBleHBvbmVudCA9PT0gMCAvLyBkZW5vcm1hbFxyXG4gICAgICAgICAgICAgICAgPyBzaWduICogNWUtMzI0ICogbWFudGlzc2FcclxuICAgICAgICAgICAgICAgIDogc2lnbiAqIE1hdGgucG93KDIsIGV4cG9uZW50IC0gMTA3NSkgKiAobWFudGlzc2EgKyA0NTAzNTk5NjI3MzcwNDk2KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGV4cG9ydHMucmVhZERvdWJsZUxFID0gcmVhZERvdWJsZV9pZWVlNzU0LmJpbmQobnVsbCwgcmVhZFVpbnRMRSwgMCwgNCk7XHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRG91YmxlQkUgPSByZWFkRG91YmxlX2llZWU3NTQuYmluZChudWxsLCByZWFkVWludEJFLCA0LCAwKTtcclxuXHJcbiAgICB9KSgpO1xyXG5cclxuICAgIHJldHVybiBleHBvcnRzO1xyXG59XHJcblxyXG4vLyB1aW50IGhlbHBlcnNcclxuXHJcbmZ1bmN0aW9uIHdyaXRlVWludExFKHZhbCwgYnVmLCBwb3MpIHtcclxuICAgIGJ1Zltwb3MgICAgXSA9ICB2YWwgICAgICAgICYgMjU1O1xyXG4gICAgYnVmW3BvcyArIDFdID0gIHZhbCA+Pj4gOCAgJiAyNTU7XHJcbiAgICBidWZbcG9zICsgMl0gPSAgdmFsID4+PiAxNiAmIDI1NTtcclxuICAgIGJ1Zltwb3MgKyAzXSA9ICB2YWwgPj4+IDI0O1xyXG59XHJcblxyXG5mdW5jdGlvbiB3cml0ZVVpbnRCRSh2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICBidWZbcG9zICAgIF0gPSAgdmFsID4+PiAyNDtcclxuICAgIGJ1Zltwb3MgKyAxXSA9ICB2YWwgPj4+IDE2ICYgMjU1O1xyXG4gICAgYnVmW3BvcyArIDJdID0gIHZhbCA+Pj4gOCAgJiAyNTU7XHJcbiAgICBidWZbcG9zICsgM10gPSAgdmFsICAgICAgICAmIDI1NTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVhZFVpbnRMRShidWYsIHBvcykge1xyXG4gICAgcmV0dXJuIChidWZbcG9zICAgIF1cclxuICAgICAgICAgIHwgYnVmW3BvcyArIDFdIDw8IDhcclxuICAgICAgICAgIHwgYnVmW3BvcyArIDJdIDw8IDE2XHJcbiAgICAgICAgICB8IGJ1Zltwb3MgKyAzXSA8PCAyNCkgPj4+IDA7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlYWRVaW50QkUoYnVmLCBwb3MpIHtcclxuICAgIHJldHVybiAoYnVmW3BvcyAgICBdIDw8IDI0XHJcbiAgICAgICAgICB8IGJ1Zltwb3MgKyAxXSA8PCAxNlxyXG4gICAgICAgICAgfCBidWZbcG9zICsgMl0gPDwgOFxyXG4gICAgICAgICAgfCBidWZbcG9zICsgM10pID4+PiAwO1xyXG59XHJcbiIsICJcInVzZSBzdHJpY3RcIjtcclxubW9kdWxlLmV4cG9ydHMgPSBpbnF1aXJlO1xyXG5cclxuLyoqXHJcbiAqIFJlcXVpcmVzIGEgbW9kdWxlIG9ubHkgaWYgYXZhaWxhYmxlLlxyXG4gKiBAbWVtYmVyb2YgdXRpbFxyXG4gKiBAcGFyYW0ge3N0cmluZ30gbW9kdWxlTmFtZSBNb2R1bGUgdG8gcmVxdWlyZVxyXG4gKiBAcmV0dXJucyB7P09iamVjdH0gUmVxdWlyZWQgbW9kdWxlIGlmIGF2YWlsYWJsZSBhbmQgbm90IGVtcHR5LCBvdGhlcndpc2UgYG51bGxgXHJcbiAqL1xyXG5mdW5jdGlvbiBpbnF1aXJlKG1vZHVsZU5hbWUpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgdmFyIG1vZCA9IGV2YWwoXCJxdWlyZVwiLnJlcGxhY2UoL14vLFwicmVcIikpKG1vZHVsZU5hbWUpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWV2YWxcclxuICAgICAgICBpZiAobW9kICYmIChtb2QubGVuZ3RoIHx8IE9iamVjdC5rZXlzKG1vZCkubGVuZ3RoKSlcclxuICAgICAgICAgICAgcmV0dXJuIG1vZDtcclxuICAgIH0gY2F0Y2ggKGUpIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tZW1wdHlcclxuICAgIHJldHVybiBudWxsO1xyXG59XHJcbiIsICJcInVzZSBzdHJpY3RcIjtcclxuXHJcbi8qKlxyXG4gKiBBIG1pbmltYWwgVVRGOCBpbXBsZW1lbnRhdGlvbiBmb3IgbnVtYmVyIGFycmF5cy5cclxuICogQG1lbWJlcm9mIHV0aWxcclxuICogQG5hbWVzcGFjZVxyXG4gKi9cclxudmFyIHV0ZjggPSBleHBvcnRzO1xyXG5cclxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIFVURjggYnl0ZSBsZW5ndGggb2YgYSBzdHJpbmcuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgU3RyaW5nXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IEJ5dGUgbGVuZ3RoXHJcbiAqL1xyXG51dGY4Lmxlbmd0aCA9IGZ1bmN0aW9uIHV0ZjhfbGVuZ3RoKHN0cmluZykge1xyXG4gICAgdmFyIGxlbiA9IDAsXHJcbiAgICAgICAgYyA9IDA7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7ICsraSkge1xyXG4gICAgICAgIGMgPSBzdHJpbmcuY2hhckNvZGVBdChpKTtcclxuICAgICAgICBpZiAoYyA8IDEyOClcclxuICAgICAgICAgICAgbGVuICs9IDE7XHJcbiAgICAgICAgZWxzZSBpZiAoYyA8IDIwNDgpXHJcbiAgICAgICAgICAgIGxlbiArPSAyO1xyXG4gICAgICAgIGVsc2UgaWYgKChjICYgMHhGQzAwKSA9PT0gMHhEODAwICYmIChzdHJpbmcuY2hhckNvZGVBdChpICsgMSkgJiAweEZDMDApID09PSAweERDMDApIHtcclxuICAgICAgICAgICAgKytpO1xyXG4gICAgICAgICAgICBsZW4gKz0gNDtcclxuICAgICAgICB9IGVsc2VcclxuICAgICAgICAgICAgbGVuICs9IDM7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGVuO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJlYWRzIFVURjggYnl0ZXMgYXMgYSBzdHJpbmcuXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmZmVyIFNvdXJjZSBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFNvdXJjZSBzdGFydFxyXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIFNvdXJjZSBlbmRcclxuICogQHJldHVybnMge3N0cmluZ30gU3RyaW5nIHJlYWRcclxuICovXHJcbnV0ZjgucmVhZCA9IGZ1bmN0aW9uIHV0ZjhfcmVhZChidWZmZXIsIHN0YXJ0LCBlbmQpIHtcclxuICAgIHZhciBsZW4gPSBlbmQgLSBzdGFydDtcclxuICAgIGlmIChsZW4gPCAxKVxyXG4gICAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgdmFyIHBhcnRzID0gbnVsbCxcclxuICAgICAgICBjaHVuayA9IFtdLFxyXG4gICAgICAgIGkgPSAwLCAvLyBjaGFyIG9mZnNldFxyXG4gICAgICAgIHQ7ICAgICAvLyB0ZW1wb3JhcnlcclxuICAgIHdoaWxlIChzdGFydCA8IGVuZCkge1xyXG4gICAgICAgIHQgPSBidWZmZXJbc3RhcnQrK107XHJcbiAgICAgICAgaWYgKHQgPCAxMjgpXHJcbiAgICAgICAgICAgIGNodW5rW2krK10gPSB0O1xyXG4gICAgICAgIGVsc2UgaWYgKHQgPiAxOTEgJiYgdCA8IDIyNClcclxuICAgICAgICAgICAgY2h1bmtbaSsrXSA9ICh0ICYgMzEpIDw8IDYgfCBidWZmZXJbc3RhcnQrK10gJiA2MztcclxuICAgICAgICBlbHNlIGlmICh0ID4gMjM5ICYmIHQgPCAzNjUpIHtcclxuICAgICAgICAgICAgdCA9ICgodCAmIDcpIDw8IDE4IHwgKGJ1ZmZlcltzdGFydCsrXSAmIDYzKSA8PCAxMiB8IChidWZmZXJbc3RhcnQrK10gJiA2MykgPDwgNiB8IGJ1ZmZlcltzdGFydCsrXSAmIDYzKSAtIDB4MTAwMDA7XHJcbiAgICAgICAgICAgIGNodW5rW2krK10gPSAweEQ4MDAgKyAodCA+PiAxMCk7XHJcbiAgICAgICAgICAgIGNodW5rW2krK10gPSAweERDMDAgKyAodCAmIDEwMjMpO1xyXG4gICAgICAgIH0gZWxzZVxyXG4gICAgICAgICAgICBjaHVua1tpKytdID0gKHQgJiAxNSkgPDwgMTIgfCAoYnVmZmVyW3N0YXJ0KytdICYgNjMpIDw8IDYgfCBidWZmZXJbc3RhcnQrK10gJiA2MztcclxuICAgICAgICBpZiAoaSA+IDgxOTEpIHtcclxuICAgICAgICAgICAgKHBhcnRzIHx8IChwYXJ0cyA9IFtdKSkucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY2h1bmspKTtcclxuICAgICAgICAgICAgaSA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHBhcnRzKSB7XHJcbiAgICAgICAgaWYgKGkpXHJcbiAgICAgICAgICAgIHBhcnRzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNodW5rLnNsaWNlKDAsIGkpKSk7XHJcbiAgICAgICAgcmV0dXJuIHBhcnRzLmpvaW4oXCJcIik7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNodW5rLnNsaWNlKDAsIGkpKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBXcml0ZXMgYSBzdHJpbmcgYXMgVVRGOCBieXRlcy5cclxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBTb3VyY2Ugc3RyaW5nXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmZmVyIERlc3RpbmF0aW9uIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IERlc3RpbmF0aW9uIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBCeXRlcyB3cml0dGVuXHJcbiAqL1xyXG51dGY4LndyaXRlID0gZnVuY3Rpb24gdXRmOF93cml0ZShzdHJpbmcsIGJ1ZmZlciwgb2Zmc2V0KSB7XHJcbiAgICB2YXIgc3RhcnQgPSBvZmZzZXQsXHJcbiAgICAgICAgYzEsIC8vIGNoYXJhY3RlciAxXHJcbiAgICAgICAgYzI7IC8vIGNoYXJhY3RlciAyXHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7ICsraSkge1xyXG4gICAgICAgIGMxID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XHJcbiAgICAgICAgaWYgKGMxIDwgMTI4KSB7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMTtcclxuICAgICAgICB9IGVsc2UgaWYgKGMxIDwgMjA0OCkge1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gNiAgICAgICB8IDE5MjtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxICAgICAgICYgNjMgfCAxMjg7XHJcbiAgICAgICAgfSBlbHNlIGlmICgoYzEgJiAweEZDMDApID09PSAweEQ4MDAgJiYgKChjMiA9IHN0cmluZy5jaGFyQ29kZUF0KGkgKyAxKSkgJiAweEZDMDApID09PSAweERDMDApIHtcclxuICAgICAgICAgICAgYzEgPSAweDEwMDAwICsgKChjMSAmIDB4MDNGRikgPDwgMTApICsgKGMyICYgMHgwM0ZGKTtcclxuICAgICAgICAgICAgKytpO1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gMTggICAgICB8IDI0MDtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxID4+IDEyICYgNjMgfCAxMjg7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSA+PiA2ICAmIDYzIHwgMTI4O1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgICAgICAgJiA2MyB8IDEyODtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gMTIgICAgICB8IDIyNDtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxID4+IDYgICYgNjMgfCAxMjg7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSAgICAgICAmIDYzIHwgMTI4O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBvZmZzZXQgLSBzdGFydDtcclxufTtcclxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5tb2R1bGUuZXhwb3J0cyA9IHBvb2w7XHJcblxyXG4vKipcclxuICogQW4gYWxsb2NhdG9yIGFzIHVzZWQgYnkge0BsaW5rIHV0aWwucG9vbH0uXHJcbiAqIEB0eXBlZGVmIFBvb2xBbGxvY2F0b3JcclxuICogQHR5cGUge2Z1bmN0aW9ufVxyXG4gKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBCdWZmZXIgc2l6ZVxyXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gQnVmZmVyXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEEgc2xpY2VyIGFzIHVzZWQgYnkge0BsaW5rIHV0aWwucG9vbH0uXHJcbiAqIEB0eXBlZGVmIFBvb2xTbGljZXJcclxuICogQHR5cGUge2Z1bmN0aW9ufVxyXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgU3RhcnQgb2Zmc2V0XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gQnVmZmVyIHNsaWNlXHJcbiAqIEB0aGlzIHtVaW50OEFycmF5fVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBBIGdlbmVyYWwgcHVycG9zZSBidWZmZXIgcG9vbC5cclxuICogQG1lbWJlcm9mIHV0aWxcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7UG9vbEFsbG9jYXRvcn0gYWxsb2MgQWxsb2NhdG9yXHJcbiAqIEBwYXJhbSB7UG9vbFNsaWNlcn0gc2xpY2UgU2xpY2VyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT04MTkyXSBTbGFiIHNpemVcclxuICogQHJldHVybnMge1Bvb2xBbGxvY2F0b3J9IFBvb2xlZCBhbGxvY2F0b3JcclxuICovXHJcbmZ1bmN0aW9uIHBvb2woYWxsb2MsIHNsaWNlLCBzaXplKSB7XHJcbiAgICB2YXIgU0laRSAgID0gc2l6ZSB8fCA4MTkyO1xyXG4gICAgdmFyIE1BWCAgICA9IFNJWkUgPj4+IDE7XHJcbiAgICB2YXIgc2xhYiAgID0gbnVsbDtcclxuICAgIHZhciBvZmZzZXQgPSBTSVpFO1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIHBvb2xfYWxsb2Moc2l6ZSkge1xyXG4gICAgICAgIGlmIChzaXplIDwgMSB8fCBzaXplID4gTUFYKVxyXG4gICAgICAgICAgICByZXR1cm4gYWxsb2Moc2l6ZSk7XHJcbiAgICAgICAgaWYgKG9mZnNldCArIHNpemUgPiBTSVpFKSB7XHJcbiAgICAgICAgICAgIHNsYWIgPSBhbGxvYyhTSVpFKTtcclxuICAgICAgICAgICAgb2Zmc2V0ID0gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGJ1ZiA9IHNsaWNlLmNhbGwoc2xhYiwgb2Zmc2V0LCBvZmZzZXQgKz0gc2l6ZSk7XHJcbiAgICAgICAgaWYgKG9mZnNldCAmIDcpIC8vIGFsaWduIHRvIDMyIGJpdFxyXG4gICAgICAgICAgICBvZmZzZXQgPSAob2Zmc2V0IHwgNykgKyAxO1xyXG4gICAgICAgIHJldHVybiBidWY7XHJcbiAgICB9O1xyXG59XHJcbiIsICJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gTG9uZ0JpdHM7XG5cbnZhciB1dGlsID0gcmVxdWlyZShcIi4uL3V0aWwvbWluaW1hbFwiKTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIG5ldyBsb25nIGJpdHMuXG4gKiBAY2xhc3NkZXNjIEhlbHBlciBjbGFzcyBmb3Igd29ya2luZyB3aXRoIHRoZSBsb3cgYW5kIGhpZ2ggYml0cyBvZiBhIDY0IGJpdCB2YWx1ZS5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7bnVtYmVyfSBsbyBMb3cgMzIgYml0cywgdW5zaWduZWRcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaSBIaWdoIDMyIGJpdHMsIHVuc2lnbmVkXG4gKi9cbmZ1bmN0aW9uIExvbmdCaXRzKGxvLCBoaSkge1xuXG4gICAgLy8gbm90ZSB0aGF0IHRoZSBjYXN0cyBiZWxvdyBhcmUgdGhlb3JldGljYWxseSB1bm5lY2Vzc2FyeSBhcyBvZiB0b2RheSwgYnV0IG9sZGVyIHN0YXRpY2FsbHlcbiAgICAvLyBnZW5lcmF0ZWQgY29udmVydGVyIGNvZGUgbWlnaHQgc3RpbGwgY2FsbCB0aGUgY3RvciB3aXRoIHNpZ25lZCAzMmJpdHMuIGtlcHQgZm9yIGNvbXBhdC5cblxuICAgIC8qKlxuICAgICAqIExvdyBiaXRzLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5sbyA9IGxvID4+PiAwO1xuXG4gICAgLyoqXG4gICAgICogSGlnaCBiaXRzLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5oaSA9IGhpID4+PiAwO1xufVxuXG4vKipcbiAqIFplcm8gYml0cy5cbiAqIEBtZW1iZXJvZiB1dGlsLkxvbmdCaXRzXG4gKiBAdHlwZSB7dXRpbC5Mb25nQml0c31cbiAqL1xudmFyIHplcm8gPSBMb25nQml0cy56ZXJvID0gbmV3IExvbmdCaXRzKDAsIDApO1xuXG56ZXJvLnRvTnVtYmVyID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuemVyby56ekVuY29kZSA9IHplcm8uenpEZWNvZGUgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH07XG56ZXJvLmxlbmd0aCA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMTsgfTtcblxuLyoqXG4gKiBaZXJvIGhhc2guXG4gKiBAbWVtYmVyb2YgdXRpbC5Mb25nQml0c1xuICogQHR5cGUge3N0cmluZ31cbiAqL1xudmFyIHplcm9IYXNoID0gTG9uZ0JpdHMuemVyb0hhc2ggPSBcIlxcMFxcMFxcMFxcMFxcMFxcMFxcMFxcMFwiO1xuXG4vKipcbiAqIENvbnN0cnVjdHMgbmV3IGxvbmcgYml0cyBmcm9tIHRoZSBzcGVjaWZpZWQgbnVtYmVyLlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlXG4gKiBAcmV0dXJucyB7dXRpbC5Mb25nQml0c30gSW5zdGFuY2VcbiAqL1xuTG9uZ0JpdHMuZnJvbU51bWJlciA9IGZ1bmN0aW9uIGZyb21OdW1iZXIodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgPT09IDApXG4gICAgICAgIHJldHVybiB6ZXJvO1xuICAgIHZhciBzaWduID0gdmFsdWUgPCAwO1xuICAgIGlmIChzaWduKVxuICAgICAgICB2YWx1ZSA9IC12YWx1ZTtcbiAgICB2YXIgbG8gPSB2YWx1ZSA+Pj4gMCxcbiAgICAgICAgaGkgPSAodmFsdWUgLSBsbykgLyA0Mjk0OTY3Mjk2ID4+PiAwO1xuICAgIGlmIChzaWduKSB7XG4gICAgICAgIGhpID0gfmhpID4+PiAwO1xuICAgICAgICBsbyA9IH5sbyA+Pj4gMDtcbiAgICAgICAgaWYgKCsrbG8gPiA0Mjk0OTY3Mjk1KSB7XG4gICAgICAgICAgICBsbyA9IDA7XG4gICAgICAgICAgICBpZiAoKytoaSA+IDQyOTQ5NjcyOTUpXG4gICAgICAgICAgICAgICAgaGkgPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXcgTG9uZ0JpdHMobG8sIGhpKTtcbn07XG5cbi8qKlxuICogQ29uc3RydWN0cyBuZXcgbG9uZyBiaXRzIGZyb20gYSBudW1iZXIsIGxvbmcgb3Igc3RyaW5nLlxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlXG4gKiBAcmV0dXJucyB7dXRpbC5Mb25nQml0c30gSW5zdGFuY2VcbiAqL1xuTG9uZ0JpdHMuZnJvbSA9IGZ1bmN0aW9uIGZyb20odmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiKVxuICAgICAgICByZXR1cm4gTG9uZ0JpdHMuZnJvbU51bWJlcih2YWx1ZSk7XG4gICAgaWYgKHV0aWwuaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICAgIGlmICh1dGlsLkxvbmcpXG4gICAgICAgICAgICB2YWx1ZSA9IHV0aWwuTG9uZy5mcm9tU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIExvbmdCaXRzLmZyb21OdW1iZXIocGFyc2VJbnQodmFsdWUsIDEwKSk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZS5sb3cgfHwgdmFsdWUuaGlnaCA/IG5ldyBMb25nQml0cyh2YWx1ZS5sb3cgPj4+IDAsIHZhbHVlLmhpZ2ggPj4+IDApIDogemVybztcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBsb25nIGJpdHMgdG8gYSBwb3NzaWJseSB1bnNhZmUgSmF2YVNjcmlwdCBudW1iZXIuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFt1bnNpZ25lZD1mYWxzZV0gV2hldGhlciB1bnNpZ25lZCBvciBub3RcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFBvc3NpYmx5IHVuc2FmZSBudW1iZXJcbiAqL1xuTG9uZ0JpdHMucHJvdG90eXBlLnRvTnVtYmVyID0gZnVuY3Rpb24gdG9OdW1iZXIodW5zaWduZWQpIHtcbiAgICBpZiAoIXVuc2lnbmVkICYmIHRoaXMuaGkgPj4+IDMxKSB7XG4gICAgICAgIHZhciBsbyA9IH50aGlzLmxvICsgMSA+Pj4gMCxcbiAgICAgICAgICAgIGhpID0gfnRoaXMuaGkgICAgID4+PiAwO1xuICAgICAgICBpZiAoIWxvKVxuICAgICAgICAgICAgaGkgPSBoaSArIDEgPj4+IDA7XG4gICAgICAgIHJldHVybiAtKGxvICsgaGkgKiA0Mjk0OTY3Mjk2KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubG8gKyB0aGlzLmhpICogNDI5NDk2NzI5Njtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBsb25nIGJpdHMgdG8gYSBsb25nLlxuICogQHBhcmFtIHtib29sZWFufSBbdW5zaWduZWQ9ZmFsc2VdIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90XG4gKiBAcmV0dXJucyB7TG9uZ30gTG9uZ1xuICovXG5Mb25nQml0cy5wcm90b3R5cGUudG9Mb25nID0gZnVuY3Rpb24gdG9Mb25nKHVuc2lnbmVkKSB7XG4gICAgcmV0dXJuIHV0aWwuTG9uZ1xuICAgICAgICA/IG5ldyB1dGlsLkxvbmcodGhpcy5sbyB8IDAsIHRoaXMuaGkgfCAwLCBCb29sZWFuKHVuc2lnbmVkKSlcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgOiB7IGxvdzogdGhpcy5sbyB8IDAsIGhpZ2g6IHRoaXMuaGkgfCAwLCB1bnNpZ25lZDogQm9vbGVhbih1bnNpZ25lZCkgfTtcbn07XG5cbnZhciBjaGFyQ29kZUF0ID0gU3RyaW5nLnByb3RvdHlwZS5jaGFyQ29kZUF0O1xuXG4vKipcbiAqIENvbnN0cnVjdHMgbmV3IGxvbmcgYml0cyBmcm9tIHRoZSBzcGVjaWZpZWQgOCBjaGFyYWN0ZXJzIGxvbmcgaGFzaC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBoYXNoIEhhc2hcbiAqIEByZXR1cm5zIHt1dGlsLkxvbmdCaXRzfSBCaXRzXG4gKi9cbkxvbmdCaXRzLmZyb21IYXNoID0gZnVuY3Rpb24gZnJvbUhhc2goaGFzaCkge1xuICAgIGlmIChoYXNoID09PSB6ZXJvSGFzaClcbiAgICAgICAgcmV0dXJuIHplcm87XG4gICAgcmV0dXJuIG5ldyBMb25nQml0cyhcbiAgICAgICAgKCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgMClcbiAgICAgICAgfCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgMSkgPDwgOFxuICAgICAgICB8IGNoYXJDb2RlQXQuY2FsbChoYXNoLCAyKSA8PCAxNlxuICAgICAgICB8IGNoYXJDb2RlQXQuY2FsbChoYXNoLCAzKSA8PCAyNCkgPj4+IDBcbiAgICAsXG4gICAgICAgICggY2hhckNvZGVBdC5jYWxsKGhhc2gsIDQpXG4gICAgICAgIHwgY2hhckNvZGVBdC5jYWxsKGhhc2gsIDUpIDw8IDhcbiAgICAgICAgfCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgNikgPDwgMTZcbiAgICAgICAgfCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgNykgPDwgMjQpID4+PiAwXG4gICAgKTtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBsb25nIGJpdHMgdG8gYSA4IGNoYXJhY3RlcnMgbG9uZyBoYXNoLlxuICogQHJldHVybnMge3N0cmluZ30gSGFzaFxuICovXG5Mb25nQml0cy5wcm90b3R5cGUudG9IYXNoID0gZnVuY3Rpb24gdG9IYXNoKCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKFxuICAgICAgICB0aGlzLmxvICAgICAgICAmIDI1NSxcbiAgICAgICAgdGhpcy5sbyA+Pj4gOCAgJiAyNTUsXG4gICAgICAgIHRoaXMubG8gPj4+IDE2ICYgMjU1LFxuICAgICAgICB0aGlzLmxvID4+PiAyNCAgICAgICxcbiAgICAgICAgdGhpcy5oaSAgICAgICAgJiAyNTUsXG4gICAgICAgIHRoaXMuaGkgPj4+IDggICYgMjU1LFxuICAgICAgICB0aGlzLmhpID4+PiAxNiAmIDI1NSxcbiAgICAgICAgdGhpcy5oaSA+Pj4gMjRcbiAgICApO1xufTtcblxuLyoqXG4gKiBaaWctemFnIGVuY29kZXMgdGhpcyBsb25nIGJpdHMuXG4gKiBAcmV0dXJucyB7dXRpbC5Mb25nQml0c30gYHRoaXNgXG4gKi9cbkxvbmdCaXRzLnByb3RvdHlwZS56ekVuY29kZSA9IGZ1bmN0aW9uIHp6RW5jb2RlKCkge1xuICAgIHZhciBtYXNrID0gICB0aGlzLmhpID4+IDMxO1xuICAgIHRoaXMuaGkgID0gKCh0aGlzLmhpIDw8IDEgfCB0aGlzLmxvID4+PiAzMSkgXiBtYXNrKSA+Pj4gMDtcbiAgICB0aGlzLmxvICA9ICggdGhpcy5sbyA8PCAxICAgICAgICAgICAgICAgICAgIF4gbWFzaykgPj4+IDA7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFppZy16YWcgZGVjb2RlcyB0aGlzIGxvbmcgYml0cy5cbiAqIEByZXR1cm5zIHt1dGlsLkxvbmdCaXRzfSBgdGhpc2BcbiAqL1xuTG9uZ0JpdHMucHJvdG90eXBlLnp6RGVjb2RlID0gZnVuY3Rpb24genpEZWNvZGUoKSB7XG4gICAgdmFyIG1hc2sgPSAtKHRoaXMubG8gJiAxKTtcbiAgICB0aGlzLmxvICA9ICgodGhpcy5sbyA+Pj4gMSB8IHRoaXMuaGkgPDwgMzEpIF4gbWFzaykgPj4+IDA7XG4gICAgdGhpcy5oaSAgPSAoIHRoaXMuaGkgPj4+IDEgICAgICAgICAgICAgICAgICBeIG1hc2spID4+PiAwO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBsZW5ndGggb2YgdGhpcyBsb25nYml0cyB3aGVuIGVuY29kZWQgYXMgYSB2YXJpbnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBMZW5ndGhcbiAqL1xuTG9uZ0JpdHMucHJvdG90eXBlLmxlbmd0aCA9IGZ1bmN0aW9uIGxlbmd0aCgpIHtcbiAgICB2YXIgcGFydDAgPSAgdGhpcy5sbyxcbiAgICAgICAgcGFydDEgPSAodGhpcy5sbyA+Pj4gMjggfCB0aGlzLmhpIDw8IDQpID4+PiAwLFxuICAgICAgICBwYXJ0MiA9ICB0aGlzLmhpID4+PiAyNDtcbiAgICByZXR1cm4gcGFydDIgPT09IDBcbiAgICAgICAgID8gcGFydDEgPT09IDBcbiAgICAgICAgICAgPyBwYXJ0MCA8IDE2Mzg0XG4gICAgICAgICAgICAgPyBwYXJ0MCA8IDEyOCA/IDEgOiAyXG4gICAgICAgICAgICAgOiBwYXJ0MCA8IDIwOTcxNTIgPyAzIDogNFxuICAgICAgICAgICA6IHBhcnQxIDwgMTYzODRcbiAgICAgICAgICAgICA/IHBhcnQxIDwgMTI4ID8gNSA6IDZcbiAgICAgICAgICAgICA6IHBhcnQxIDwgMjA5NzE1MiA/IDcgOiA4XG4gICAgICAgICA6IHBhcnQyIDwgMTI4ID8gOSA6IDEwO1xufTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbnZhciB1dGlsID0gZXhwb3J0cztcblxuLy8gdXNlZCB0byByZXR1cm4gYSBQcm9taXNlIHdoZXJlIGNhbGxiYWNrIGlzIG9taXR0ZWRcbnV0aWwuYXNQcm9taXNlID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL2FzcHJvbWlzZVwiKTtcblxuLy8gY29udmVydHMgdG8gLyBmcm9tIGJhc2U2NCBlbmNvZGVkIHN0cmluZ3NcbnV0aWwuYmFzZTY0ID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL2Jhc2U2NFwiKTtcblxuLy8gYmFzZSBjbGFzcyBvZiBycGMuU2VydmljZVxudXRpbC5FdmVudEVtaXR0ZXIgPSByZXF1aXJlKFwiQHByb3RvYnVmanMvZXZlbnRlbWl0dGVyXCIpO1xuXG4vLyBmbG9hdCBoYW5kbGluZyBhY2Nyb3NzIGJyb3dzZXJzXG51dGlsLmZsb2F0ID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL2Zsb2F0XCIpO1xuXG4vLyByZXF1aXJlcyBtb2R1bGVzIG9wdGlvbmFsbHkgYW5kIGhpZGVzIHRoZSBjYWxsIGZyb20gYnVuZGxlcnNcbnV0aWwuaW5xdWlyZSA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy9pbnF1aXJlXCIpO1xuXG4vLyBjb252ZXJ0cyB0byAvIGZyb20gdXRmOCBlbmNvZGVkIHN0cmluZ3NcbnV0aWwudXRmOCA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy91dGY4XCIpO1xuXG4vLyBwcm92aWRlcyBhIG5vZGUtbGlrZSBidWZmZXIgcG9vbCBpbiB0aGUgYnJvd3NlclxudXRpbC5wb29sID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL3Bvb2xcIik7XG5cbi8vIHV0aWxpdHkgdG8gd29yayB3aXRoIHRoZSBsb3cgYW5kIGhpZ2ggYml0cyBvZiBhIDY0IGJpdCB2YWx1ZVxudXRpbC5Mb25nQml0cyA9IHJlcXVpcmUoXCIuL2xvbmdiaXRzXCIpO1xuXG4vKipcbiAqIFdoZXRoZXIgcnVubmluZyB3aXRoaW4gbm9kZSBvciBub3QuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQHR5cGUge2Jvb2xlYW59XG4gKi9cbnV0aWwuaXNOb2RlID0gQm9vbGVhbih0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiXG4gICAgICAgICAgICAgICAgICAgJiYgZ2xvYmFsXG4gICAgICAgICAgICAgICAgICAgJiYgZ2xvYmFsLnByb2Nlc3NcbiAgICAgICAgICAgICAgICAgICAmJiBnbG9iYWwucHJvY2Vzcy52ZXJzaW9uc1xuICAgICAgICAgICAgICAgICAgICYmIGdsb2JhbC5wcm9jZXNzLnZlcnNpb25zLm5vZGUpO1xuXG4vKipcbiAqIEdsb2JhbCBvYmplY3QgcmVmZXJlbmNlLlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEB0eXBlIHtPYmplY3R9XG4gKi9cbnV0aWwuZ2xvYmFsID0gdXRpbC5pc05vZGUgJiYgZ2xvYmFsXG4gICAgICAgICAgIHx8IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiYgd2luZG93XG4gICAgICAgICAgIHx8IHR5cGVvZiBzZWxmICAgIT09IFwidW5kZWZpbmVkXCIgJiYgc2VsZlxuICAgICAgICAgICB8fCB0aGlzOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWludmFsaWQtdGhpc1xuXG4vKipcbiAqIEFuIGltbXVhYmxlIGVtcHR5IGFycmF5LlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEB0eXBlIHtBcnJheS48Kj59XG4gKiBAY29uc3RcbiAqL1xudXRpbC5lbXB0eUFycmF5ID0gT2JqZWN0LmZyZWV6ZSA/IE9iamVjdC5mcmVlemUoW10pIDogLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gW107IC8vIHVzZWQgb24gcHJvdG90eXBlc1xuXG4vKipcbiAqIEFuIGltbXV0YWJsZSBlbXB0eSBvYmplY3QuXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQGNvbnN0XG4gKi9cbnV0aWwuZW1wdHlPYmplY3QgPSBPYmplY3QuZnJlZXplID8gT2JqZWN0LmZyZWV6ZSh7fSkgOiAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyB7fTsgLy8gdXNlZCBvbiBwcm90b3R5cGVzXG5cbi8qKlxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhbiBpbnRlZ2VyLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIHZhbHVlIGlzIGFuIGludGVnZXJcbiAqL1xudXRpbC5pc0ludGVnZXIgPSBOdW1iZXIuaXNJbnRlZ2VyIHx8IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIGZ1bmN0aW9uIGlzSW50ZWdlcih2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgaXNGaW5pdGUodmFsdWUpICYmIE1hdGguZmxvb3IodmFsdWUpID09PSB2YWx1ZTtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIHN0cmluZy5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgdmFsdWUgaXMgYSBzdHJpbmdcbiAqL1xudXRpbC5pc1N0cmluZyA9IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiB8fCB2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZztcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIG5vbi1udWxsIG9iamVjdC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgdmFsdWUgaXMgYSBub24tbnVsbCBvYmplY3RcbiAqL1xudXRpbC5pc09iamVjdCA9IGZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIjtcbn07XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgcHJvcGVydHkgb24gYSBtZXNzYWdlIGlzIGNvbnNpZGVyZWQgdG8gYmUgcHJlc2VudC5cbiAqIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIHV0aWwuaXNTZXR9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFBsYWluIG9iamVjdCBvciBtZXNzYWdlIGluc3RhbmNlXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcCBQcm9wZXJ0eSBuYW1lXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIGNvbnNpZGVyZWQgdG8gYmUgcHJlc2VudCwgb3RoZXJ3aXNlIGBmYWxzZWBcbiAqL1xudXRpbC5pc3NldCA9XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgcHJvcGVydHkgb24gYSBtZXNzYWdlIGlzIGNvbnNpZGVyZWQgdG8gYmUgcHJlc2VudC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogUGxhaW4gb2JqZWN0IG9yIG1lc3NhZ2UgaW5zdGFuY2VcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wIFByb3BlcnR5IG5hbWVcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgY29uc2lkZXJlZCB0byBiZSBwcmVzZW50LCBvdGhlcndpc2UgYGZhbHNlYFxuICovXG51dGlsLmlzU2V0ID0gZnVuY3Rpb24gaXNTZXQob2JqLCBwcm9wKSB7XG4gICAgdmFyIHZhbHVlID0gb2JqW3Byb3BdO1xuICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIG9iai5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXEsIG5vLXByb3RvdHlwZS1idWlsdGluc1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiIHx8IChBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlLmxlbmd0aCA6IE9iamVjdC5rZXlzKHZhbHVlKS5sZW5ndGgpID4gMDtcbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG4vKipcbiAqIEFueSBjb21wYXRpYmxlIEJ1ZmZlciBpbnN0YW5jZS5cbiAqIFRoaXMgaXMgYSBtaW5pbWFsIHN0YW5kLWFsb25lIGRlZmluaXRpb24gb2YgYSBCdWZmZXIgaW5zdGFuY2UuIFRoZSBhY3R1YWwgdHlwZSBpcyB0aGF0IGV4cG9ydGVkIGJ5IG5vZGUncyB0eXBpbmdzLlxuICogQGludGVyZmFjZSBCdWZmZXJcbiAqIEBleHRlbmRzIFVpbnQ4QXJyYXlcbiAqL1xuXG4vKipcbiAqIE5vZGUncyBCdWZmZXIgY2xhc3MgaWYgYXZhaWxhYmxlLlxuICogQHR5cGUge0NvbnN0cnVjdG9yPEJ1ZmZlcj59XG4gKi9cbnV0aWwuQnVmZmVyID0gKGZ1bmN0aW9uKCkge1xuICAgIHRyeSB7XG4gICAgICAgIHZhciBCdWZmZXIgPSB1dGlsLmlucXVpcmUoXCJidWZmZXJcIikuQnVmZmVyO1xuICAgICAgICAvLyByZWZ1c2UgdG8gdXNlIG5vbi1ub2RlIGJ1ZmZlcnMgaWYgbm90IGV4cGxpY2l0bHkgYXNzaWduZWQgKHBlcmYgcmVhc29ucyk6XG4gICAgICAgIHJldHVybiBCdWZmZXIucHJvdG90eXBlLnV0ZjhXcml0ZSA/IEJ1ZmZlciA6IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIG51bGw7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG59KSgpO1xuXG4vLyBJbnRlcm5hbCBhbGlhcyBvZiBvciBwb2x5ZnVsbCBmb3IgQnVmZmVyLmZyb20uXG51dGlsLl9CdWZmZXJfZnJvbSA9IG51bGw7XG5cbi8vIEludGVybmFsIGFsaWFzIG9mIG9yIHBvbHlmaWxsIGZvciBCdWZmZXIuYWxsb2NVbnNhZmUuXG51dGlsLl9CdWZmZXJfYWxsb2NVbnNhZmUgPSBudWxsO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgYnVmZmVyIG9mIHdoYXRldmVyIHR5cGUgc3VwcG9ydGVkIGJ5IHRoZSBlbnZpcm9ubWVudC5cbiAqIEBwYXJhbSB7bnVtYmVyfG51bWJlcltdfSBbc2l6ZU9yQXJyYXk9MF0gQnVmZmVyIHNpemUgb3IgbnVtYmVyIGFycmF5XG4gKiBAcmV0dXJucyB7VWludDhBcnJheXxCdWZmZXJ9IEJ1ZmZlclxuICovXG51dGlsLm5ld0J1ZmZlciA9IGZ1bmN0aW9uIG5ld0J1ZmZlcihzaXplT3JBcnJheSkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgcmV0dXJuIHR5cGVvZiBzaXplT3JBcnJheSA9PT0gXCJudW1iZXJcIlxuICAgICAgICA/IHV0aWwuQnVmZmVyXG4gICAgICAgICAgICA/IHV0aWwuX0J1ZmZlcl9hbGxvY1Vuc2FmZShzaXplT3JBcnJheSlcbiAgICAgICAgICAgIDogbmV3IHV0aWwuQXJyYXkoc2l6ZU9yQXJyYXkpXG4gICAgICAgIDogdXRpbC5CdWZmZXJcbiAgICAgICAgICAgID8gdXRpbC5fQnVmZmVyX2Zyb20oc2l6ZU9yQXJyYXkpXG4gICAgICAgICAgICA6IHR5cGVvZiBVaW50OEFycmF5ID09PSBcInVuZGVmaW5lZFwiXG4gICAgICAgICAgICAgICAgPyBzaXplT3JBcnJheVxuICAgICAgICAgICAgICAgIDogbmV3IFVpbnQ4QXJyYXkoc2l6ZU9yQXJyYXkpO1xufTtcblxuLyoqXG4gKiBBcnJheSBpbXBsZW1lbnRhdGlvbiB1c2VkIGluIHRoZSBicm93c2VyLiBgVWludDhBcnJheWAgaWYgc3VwcG9ydGVkLCBvdGhlcndpc2UgYEFycmF5YC5cbiAqIEB0eXBlIHtDb25zdHJ1Y3RvcjxVaW50OEFycmF5Pn1cbiAqL1xudXRpbC5BcnJheSA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSBcInVuZGVmaW5lZFwiID8gVWludDhBcnJheSAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyA6IEFycmF5O1xuXG4vKipcbiAqIEFueSBjb21wYXRpYmxlIExvbmcgaW5zdGFuY2UuXG4gKiBUaGlzIGlzIGEgbWluaW1hbCBzdGFuZC1hbG9uZSBkZWZpbml0aW9uIG9mIGEgTG9uZyBpbnN0YW5jZS4gVGhlIGFjdHVhbCB0eXBlIGlzIHRoYXQgZXhwb3J0ZWQgYnkgbG9uZy5qcy5cbiAqIEBpbnRlcmZhY2UgTG9uZ1xuICogQHByb3BlcnR5IHtudW1iZXJ9IGxvdyBMb3cgYml0c1xuICogQHByb3BlcnR5IHtudW1iZXJ9IGhpZ2ggSGlnaCBiaXRzXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90XG4gKi9cblxuLyoqXG4gKiBMb25nLmpzJ3MgTG9uZyBjbGFzcyBpZiBhdmFpbGFibGUuXG4gKiBAdHlwZSB7Q29uc3RydWN0b3I8TG9uZz59XG4gKi9cbnV0aWwuTG9uZyA9IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIHV0aWwuZ2xvYmFsLmRjb2RlSU8gJiYgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gdXRpbC5nbG9iYWwuZGNvZGVJTy5Mb25nXG4gICAgICAgICB8fCAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyB1dGlsLmdsb2JhbC5Mb25nXG4gICAgICAgICB8fCB1dGlsLmlucXVpcmUoXCJsb25nXCIpO1xuXG4vKipcbiAqIFJlZ3VsYXIgZXhwcmVzc2lvbiB1c2VkIHRvIHZlcmlmeSAyIGJpdCAoYGJvb2xgKSBtYXAga2V5cy5cbiAqIEB0eXBlIHtSZWdFeHB9XG4gKiBAY29uc3RcbiAqL1xudXRpbC5rZXkyUmUgPSAvXnRydWV8ZmFsc2V8MHwxJC87XG5cbi8qKlxuICogUmVndWxhciBleHByZXNzaW9uIHVzZWQgdG8gdmVyaWZ5IDMyIGJpdCAoYGludDMyYCBldGMuKSBtYXAga2V5cy5cbiAqIEB0eXBlIHtSZWdFeHB9XG4gKiBAY29uc3RcbiAqL1xudXRpbC5rZXkzMlJlID0gL14tPyg/OjB8WzEtOV1bMC05XSopJC87XG5cbi8qKlxuICogUmVndWxhciBleHByZXNzaW9uIHVzZWQgdG8gdmVyaWZ5IDY0IGJpdCAoYGludDY0YCBldGMuKSBtYXAga2V5cy5cbiAqIEB0eXBlIHtSZWdFeHB9XG4gKiBAY29uc3RcbiAqL1xudXRpbC5rZXk2NFJlID0gL14oPzpbXFxcXHgwMC1cXFxceGZmXXs4fXwtPyg/OjB8WzEtOV1bMC05XSopKSQvO1xuXG4vKipcbiAqIENvbnZlcnRzIGEgbnVtYmVyIG9yIGxvbmcgdG8gYW4gOCBjaGFyYWN0ZXJzIGxvbmcgaGFzaCBzdHJpbmcuXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byBjb252ZXJ0XG4gKiBAcmV0dXJucyB7c3RyaW5nfSBIYXNoXG4gKi9cbnV0aWwubG9uZ1RvSGFzaCA9IGZ1bmN0aW9uIGxvbmdUb0hhc2godmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgPyB1dGlsLkxvbmdCaXRzLmZyb20odmFsdWUpLnRvSGFzaCgpXG4gICAgICAgIDogdXRpbC5Mb25nQml0cy56ZXJvSGFzaDtcbn07XG5cbi8qKlxuICogQ29udmVydHMgYW4gOCBjaGFyYWN0ZXJzIGxvbmcgaGFzaCBzdHJpbmcgdG8gYSBsb25nIG9yIG51bWJlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBoYXNoIEhhc2hcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Vuc2lnbmVkPWZhbHNlXSBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdFxuICogQHJldHVybnMge0xvbmd8bnVtYmVyfSBPcmlnaW5hbCB2YWx1ZVxuICovXG51dGlsLmxvbmdGcm9tSGFzaCA9IGZ1bmN0aW9uIGxvbmdGcm9tSGFzaChoYXNoLCB1bnNpZ25lZCkge1xuICAgIHZhciBiaXRzID0gdXRpbC5Mb25nQml0cy5mcm9tSGFzaChoYXNoKTtcbiAgICBpZiAodXRpbC5Mb25nKVxuICAgICAgICByZXR1cm4gdXRpbC5Mb25nLmZyb21CaXRzKGJpdHMubG8sIGJpdHMuaGksIHVuc2lnbmVkKTtcbiAgICByZXR1cm4gYml0cy50b051bWJlcihCb29sZWFuKHVuc2lnbmVkKSk7XG59O1xuXG4vKipcbiAqIE1lcmdlcyB0aGUgcHJvcGVydGllcyBvZiB0aGUgc291cmNlIG9iamVjdCBpbnRvIHRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gZHN0IERlc3RpbmF0aW9uIG9iamVjdFxuICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gc3JjIFNvdXJjZSBvYmplY3RcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lmTm90U2V0PWZhbHNlXSBNZXJnZXMgb25seSBpZiB0aGUga2V5IGlzIG5vdCBhbHJlYWR5IHNldFxuICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBEZXN0aW5hdGlvbiBvYmplY3RcbiAqL1xuZnVuY3Rpb24gbWVyZ2UoZHN0LCBzcmMsIGlmTm90U2V0KSB7IC8vIHVzZWQgYnkgY29udmVydGVyc1xuICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhzcmMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgIGlmIChkc3Rba2V5c1tpXV0gPT09IHVuZGVmaW5lZCB8fCAhaWZOb3RTZXQpXG4gICAgICAgICAgICBkc3Rba2V5c1tpXV0gPSBzcmNba2V5c1tpXV07XG4gICAgcmV0dXJuIGRzdDtcbn1cblxudXRpbC5tZXJnZSA9IG1lcmdlO1xuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgYSBzdHJpbmcgdG8gbG93ZXIgY2FzZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNvbnZlcnRcbiAqIEByZXR1cm5zIHtzdHJpbmd9IENvbnZlcnRlZCBzdHJpbmdcbiAqL1xudXRpbC5sY0ZpcnN0ID0gZnVuY3Rpb24gbGNGaXJzdChzdHIpIHtcbiAgICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpICsgc3RyLnN1YnN0cmluZygxKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGN1c3RvbSBlcnJvciBjb25zdHJ1Y3Rvci5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBFcnJvciBuYW1lXG4gKiBAcmV0dXJucyB7Q29uc3RydWN0b3I8RXJyb3I+fSBDdXN0b20gZXJyb3IgY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gbmV3RXJyb3IobmFtZSkge1xuXG4gICAgZnVuY3Rpb24gQ3VzdG9tRXJyb3IobWVzc2FnZSwgcHJvcGVydGllcykge1xuXG4gICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDdXN0b21FcnJvcikpXG4gICAgICAgICAgICByZXR1cm4gbmV3IEN1c3RvbUVycm9yKG1lc3NhZ2UsIHByb3BlcnRpZXMpO1xuXG4gICAgICAgIC8vIEVycm9yLmNhbGwodGhpcywgbWVzc2FnZSk7XG4gICAgICAgIC8vIF4ganVzdCByZXR1cm5zIGEgbmV3IGVycm9yIGluc3RhbmNlIGJlY2F1c2UgdGhlIGN0b3IgY2FuIGJlIGNhbGxlZCBhcyBhIGZ1bmN0aW9uXG5cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIFwibWVzc2FnZVwiLCB7IGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtZXNzYWdlOyB9IH0pO1xuXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkgLy8gbm9kZVxuICAgICAgICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgQ3VzdG9tRXJyb3IpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJzdGFja1wiLCB7IHZhbHVlOiBuZXcgRXJyb3IoKS5zdGFjayB8fCBcIlwiIH0pO1xuXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgbWVyZ2UodGhpcywgcHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgQ3VzdG9tRXJyb3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShFcnJvci5wcm90b3R5cGUsIHtcbiAgICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgICAgIHZhbHVlOiBDdXN0b21FcnJvcixcbiAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIG5hbWU6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgeyByZXR1cm4gbmFtZTsgfSxcbiAgICAgICAgICAgIHNldDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAvLyBjb25maWd1cmFibGU6IGZhbHNlIHdvdWxkIGFjY3VyYXRlbHkgcHJlc2VydmUgdGhlIGJlaGF2aW9yIG9mXG4gICAgICAgICAgICAvLyB0aGUgb3JpZ2luYWwsIGJ1dCBJJ20gZ3Vlc3NpbmcgdGhhdCB3YXMgbm90IGludGVudGlvbmFsLlxuICAgICAgICAgICAgLy8gRm9yIGFuIGFjdHVhbCBlcnJvciBzdWJjbGFzcywgdGhpcyBwcm9wZXJ0eSB3b3VsZFxuICAgICAgICAgICAgLy8gYmUgY29uZmlndXJhYmxlLlxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICB0b1N0cmluZzoge1xuICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKCkgeyByZXR1cm4gdGhpcy5uYW1lICsgXCI6IFwiICsgdGhpcy5tZXNzYWdlOyB9LFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICB9KTtcblxuICAgIHJldHVybiBDdXN0b21FcnJvcjtcbn1cblxudXRpbC5uZXdFcnJvciA9IG5ld0Vycm9yO1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgcHJvdG9jb2wgZXJyb3IuXG4gKiBAY2xhc3NkZXNjIEVycm9yIHN1YmNsYXNzIGluZGljYXRpbmcgYSBwcm90b2NvbCBzcGVjaWZjIGVycm9yLlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEBleHRlbmRzIEVycm9yXG4gKiBAdGVtcGxhdGUgVCBleHRlbmRzIE1lc3NhZ2U8VD5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgRXJyb3IgbWVzc2FnZVxuICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gW3Byb3BlcnRpZXNdIEFkZGl0aW9uYWwgcHJvcGVydGllc1xuICogQGV4YW1wbGVcbiAqIHRyeSB7XG4gKiAgICAgTXlNZXNzYWdlLmRlY29kZShzb21lQnVmZmVyKTsgLy8gdGhyb3dzIGlmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICogfSBjYXRjaCAoZSkge1xuICogICAgIGlmIChlIGluc3RhbmNlb2YgUHJvdG9jb2xFcnJvciAmJiBlLmluc3RhbmNlKVxuICogICAgICAgICBjb25zb2xlLmxvZyhcImRlY29kZWQgc28gZmFyOiBcIiArIEpTT04uc3RyaW5naWZ5KGUuaW5zdGFuY2UpKTtcbiAqIH1cbiAqL1xudXRpbC5Qcm90b2NvbEVycm9yID0gbmV3RXJyb3IoXCJQcm90b2NvbEVycm9yXCIpO1xuXG4vKipcbiAqIFNvIGZhciBkZWNvZGVkIG1lc3NhZ2UgaW5zdGFuY2UuXG4gKiBAbmFtZSB1dGlsLlByb3RvY29sRXJyb3IjaW5zdGFuY2VcbiAqIEB0eXBlIHtNZXNzYWdlPFQ+fVxuICovXG5cbi8qKlxuICogQSBPbmVPZiBnZXR0ZXIgYXMgcmV0dXJuZWQgYnkge0BsaW5rIHV0aWwub25lT2ZHZXR0ZXJ9LlxuICogQHR5cGVkZWYgT25lT2ZHZXR0ZXJcbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEByZXR1cm5zIHtzdHJpbmd8dW5kZWZpbmVkfSBTZXQgZmllbGQgbmFtZSwgaWYgYW55XG4gKi9cblxuLyoqXG4gKiBCdWlsZHMgYSBnZXR0ZXIgZm9yIGEgb25lb2YncyBwcmVzZW50IGZpZWxkIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBmaWVsZE5hbWVzIEZpZWxkIG5hbWVzXG4gKiBAcmV0dXJucyB7T25lT2ZHZXR0ZXJ9IFVuYm91bmQgZ2V0dGVyXG4gKi9cbnV0aWwub25lT2ZHZXR0ZXIgPSBmdW5jdGlvbiBnZXRPbmVPZihmaWVsZE5hbWVzKSB7XG4gICAgdmFyIGZpZWxkTWFwID0ge307XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWVsZE5hbWVzLmxlbmd0aDsgKytpKVxuICAgICAgICBmaWVsZE1hcFtmaWVsZE5hbWVzW2ldXSA9IDE7XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfHVuZGVmaW5lZH0gU2V0IGZpZWxkIG5hbWUsIGlmIGFueVxuICAgICAqIEB0aGlzIE9iamVjdFxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHRoaXMpLCBpID0ga2V5cy5sZW5ndGggLSAxOyBpID4gLTE7IC0taSlcbiAgICAgICAgICAgIGlmIChmaWVsZE1hcFtrZXlzW2ldXSA9PT0gMSAmJiB0aGlzW2tleXNbaV1dICE9PSB1bmRlZmluZWQgJiYgdGhpc1trZXlzW2ldXSAhPT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4ga2V5c1tpXTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBBIE9uZU9mIHNldHRlciBhcyByZXR1cm5lZCBieSB7QGxpbmsgdXRpbC5vbmVPZlNldHRlcn0uXG4gKiBAdHlwZWRlZiBPbmVPZlNldHRlclxuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSB2YWx1ZSBGaWVsZCBuYW1lXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICovXG5cbi8qKlxuICogQnVpbGRzIGEgc2V0dGVyIGZvciBhIG9uZW9mJ3MgcHJlc2VudCBmaWVsZCBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmdbXX0gZmllbGROYW1lcyBGaWVsZCBuYW1lc1xuICogQHJldHVybnMge09uZU9mU2V0dGVyfSBVbmJvdW5kIHNldHRlclxuICovXG51dGlsLm9uZU9mU2V0dGVyID0gZnVuY3Rpb24gc2V0T25lT2YoZmllbGROYW1lcykge1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgRmllbGQgbmFtZVxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gICAgICogQHRoaXMgT2JqZWN0XG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIHJldHVybiBmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZmllbGROYW1lcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgIGlmIChmaWVsZE5hbWVzW2ldICE9PSBuYW1lKVxuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzW2ZpZWxkTmFtZXNbaV1dO1xuICAgIH07XG59O1xuXG4vKipcbiAqIERlZmF1bHQgY29udmVyc2lvbiBvcHRpb25zIHVzZWQgZm9yIHtAbGluayBNZXNzYWdlI3RvSlNPTn0gaW1wbGVtZW50YXRpb25zLlxuICpcbiAqIFRoZXNlIG9wdGlvbnMgYXJlIGNsb3NlIHRvIHByb3RvMydzIEpTT04gbWFwcGluZyB3aXRoIHRoZSBleGNlcHRpb24gdGhhdCBpbnRlcm5hbCB0eXBlcyBsaWtlIEFueSBhcmUgaGFuZGxlZCBqdXN0IGxpa2UgbWVzc2FnZXMuIE1vcmUgcHJlY2lzZWx5OlxuICpcbiAqIC0gTG9uZ3MgYmVjb21lIHN0cmluZ3NcbiAqIC0gRW51bXMgYmVjb21lIHN0cmluZyBrZXlzXG4gKiAtIEJ5dGVzIGJlY29tZSBiYXNlNjQgZW5jb2RlZCBzdHJpbmdzXG4gKiAtIChTdWItKU1lc3NhZ2VzIGJlY29tZSBwbGFpbiBvYmplY3RzXG4gKiAtIE1hcHMgYmVjb21lIHBsYWluIG9iamVjdHMgd2l0aCBhbGwgc3RyaW5nIGtleXNcbiAqIC0gUmVwZWF0ZWQgZmllbGRzIGJlY29tZSBhcnJheXNcbiAqIC0gTmFOIGFuZCBJbmZpbml0eSBmb3IgZmxvYXQgYW5kIGRvdWJsZSBmaWVsZHMgYmVjb21lIHN0cmluZ3NcbiAqXG4gKiBAdHlwZSB7SUNvbnZlcnNpb25PcHRpb25zfVxuICogQHNlZSBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzL2RvY3MvcHJvdG8zP2hsPWVuI2pzb25cbiAqL1xudXRpbC50b0pTT05PcHRpb25zID0ge1xuICAgIGxvbmdzOiBTdHJpbmcsXG4gICAgZW51bXM6IFN0cmluZyxcbiAgICBieXRlczogU3RyaW5nLFxuICAgIGpzb246IHRydWVcbn07XG5cbi8vIFNldHMgdXAgYnVmZmVyIHV0aWxpdHkgYWNjb3JkaW5nIHRvIHRoZSBlbnZpcm9ubWVudCAoY2FsbGVkIGluIGluZGV4LW1pbmltYWwpXG51dGlsLl9jb25maWd1cmUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgQnVmZmVyID0gdXRpbC5CdWZmZXI7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKCFCdWZmZXIpIHtcbiAgICAgICAgdXRpbC5fQnVmZmVyX2Zyb20gPSB1dGlsLl9CdWZmZXJfYWxsb2NVbnNhZmUgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGJlY2F1c2Ugbm9kZSA0LnggYnVmZmVycyBhcmUgaW5jb21wYXRpYmxlICYgaW1tdXRhYmxlXG4gICAgLy8gc2VlOiBodHRwczovL2dpdGh1Yi5jb20vZGNvZGVJTy9wcm90b2J1Zi5qcy9wdWxsLzY2NVxuICAgIHV0aWwuX0J1ZmZlcl9mcm9tID0gQnVmZmVyLmZyb20gIT09IFVpbnQ4QXJyYXkuZnJvbSAmJiBCdWZmZXIuZnJvbSB8fFxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBmdW5jdGlvbiBCdWZmZXJfZnJvbSh2YWx1ZSwgZW5jb2RpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQnVmZmVyKHZhbHVlLCBlbmNvZGluZyk7XG4gICAgICAgIH07XG4gICAgdXRpbC5fQnVmZmVyX2FsbG9jVW5zYWZlID0gQnVmZmVyLmFsbG9jVW5zYWZlIHx8XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGZ1bmN0aW9uIEJ1ZmZlcl9hbGxvY1Vuc2FmZShzaXplKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcihzaXplKTtcbiAgICAgICAgfTtcbn07XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IFdyaXRlcjtcblxudmFyIHV0aWwgICAgICA9IHJlcXVpcmUoXCIuL3V0aWwvbWluaW1hbFwiKTtcblxudmFyIEJ1ZmZlcldyaXRlcjsgLy8gY3ljbGljXG5cbnZhciBMb25nQml0cyAgPSB1dGlsLkxvbmdCaXRzLFxuICAgIGJhc2U2NCAgICA9IHV0aWwuYmFzZTY0LFxuICAgIHV0ZjggICAgICA9IHV0aWwudXRmODtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IHdyaXRlciBvcGVyYXRpb24gaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIFNjaGVkdWxlZCB3cml0ZXIgb3BlcmF0aW9uLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCosIFVpbnQ4QXJyYXksIG51bWJlcil9IGZuIEZ1bmN0aW9uIHRvIGNhbGxcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW4gVmFsdWUgYnl0ZSBsZW5ndGhcbiAqIEBwYXJhbSB7Kn0gdmFsIFZhbHVlIHRvIHdyaXRlXG4gKiBAaWdub3JlXG4gKi9cbmZ1bmN0aW9uIE9wKGZuLCBsZW4sIHZhbCkge1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gdG8gY2FsbC5cbiAgICAgKiBAdHlwZSB7ZnVuY3Rpb24oVWludDhBcnJheSwgbnVtYmVyLCAqKX1cbiAgICAgKi9cbiAgICB0aGlzLmZuID0gZm47XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBieXRlIGxlbmd0aC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMubGVuID0gbGVuO1xuXG4gICAgLyoqXG4gICAgICogTmV4dCBvcGVyYXRpb24uXG4gICAgICogQHR5cGUge1dyaXRlci5PcHx1bmRlZmluZWR9XG4gICAgICovXG4gICAgdGhpcy5uZXh0ID0gdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVmFsdWUgdG8gd3JpdGUuXG4gICAgICogQHR5cGUgeyp9XG4gICAgICovXG4gICAgdGhpcy52YWwgPSB2YWw7IC8vIHR5cGUgdmFyaWVzXG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBub29wKCkge30gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1lbXB0eS1mdW5jdGlvblxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgd3JpdGVyIHN0YXRlIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBDb3BpZWQgd3JpdGVyIHN0YXRlLlxuICogQG1lbWJlcm9mIFdyaXRlclxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge1dyaXRlcn0gd3JpdGVyIFdyaXRlciB0byBjb3B5IHN0YXRlIGZyb21cbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gU3RhdGUod3JpdGVyKSB7XG5cbiAgICAvKipcbiAgICAgKiBDdXJyZW50IGhlYWQuXG4gICAgICogQHR5cGUge1dyaXRlci5PcH1cbiAgICAgKi9cbiAgICB0aGlzLmhlYWQgPSB3cml0ZXIuaGVhZDtcblxuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgdGFpbC5cbiAgICAgKiBAdHlwZSB7V3JpdGVyLk9wfVxuICAgICAqL1xuICAgIHRoaXMudGFpbCA9IHdyaXRlci50YWlsO1xuXG4gICAgLyoqXG4gICAgICogQ3VycmVudCBidWZmZXIgbGVuZ3RoLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5sZW4gPSB3cml0ZXIubGVuO1xuXG4gICAgLyoqXG4gICAgICogTmV4dCBzdGF0ZS5cbiAgICAgKiBAdHlwZSB7U3RhdGV8bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLm5leHQgPSB3cml0ZXIuc3RhdGVzO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgd3JpdGVyIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBXaXJlIGZvcm1hdCB3cml0ZXIgdXNpbmcgYFVpbnQ4QXJyYXlgIGlmIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIGBBcnJheWAuXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gV3JpdGVyKCkge1xuXG4gICAgLyoqXG4gICAgICogQ3VycmVudCBsZW5ndGguXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmxlbiA9IDA7XG5cbiAgICAvKipcbiAgICAgKiBPcGVyYXRpb25zIGhlYWQuXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKi9cbiAgICB0aGlzLmhlYWQgPSBuZXcgT3Aobm9vcCwgMCwgMCk7XG5cbiAgICAvKipcbiAgICAgKiBPcGVyYXRpb25zIHRhaWxcbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqL1xuICAgIHRoaXMudGFpbCA9IHRoaXMuaGVhZDtcblxuICAgIC8qKlxuICAgICAqIExpbmtlZCBmb3JrZWQgc3RhdGVzLlxuICAgICAqIEB0eXBlIHtPYmplY3R8bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLnN0YXRlcyA9IG51bGw7XG5cbiAgICAvLyBXaGVuIGEgdmFsdWUgaXMgd3JpdHRlbiwgdGhlIHdyaXRlciBjYWxjdWxhdGVzIGl0cyBieXRlIGxlbmd0aCBhbmQgcHV0cyBpdCBpbnRvIGEgbGlua2VkXG4gICAgLy8gbGlzdCBvZiBvcGVyYXRpb25zIHRvIHBlcmZvcm0gd2hlbiBmaW5pc2goKSBpcyBjYWxsZWQuIFRoaXMgYm90aCBhbGxvd3MgdXMgdG8gYWxsb2NhdGVcbiAgICAvLyBidWZmZXJzIG9mIHRoZSBleGFjdCByZXF1aXJlZCBzaXplIGFuZCByZWR1Y2VzIHRoZSBhbW91bnQgb2Ygd29yayB3ZSBoYXZlIHRvIGRvIGNvbXBhcmVkXG4gICAgLy8gdG8gZmlyc3QgY2FsY3VsYXRpbmcgb3ZlciBvYmplY3RzIGFuZCB0aGVuIGVuY29kaW5nIG92ZXIgb2JqZWN0cy4gSW4gb3VyIGNhc2UsIHRoZSBlbmNvZGluZ1xuICAgIC8vIHBhcnQgaXMganVzdCBhIGxpbmtlZCBsaXN0IHdhbGsgY2FsbGluZyBvcGVyYXRpb25zIHdpdGggYWxyZWFkeSBwcmVwYXJlZCB2YWx1ZXMuXG59XG5cbnZhciBjcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gICAgcmV0dXJuIHV0aWwuQnVmZmVyXG4gICAgICAgID8gZnVuY3Rpb24gY3JlYXRlX2J1ZmZlcl9zZXR1cCgpIHtcbiAgICAgICAgICAgIHJldHVybiAoV3JpdGVyLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZV9idWZmZXIoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXJXcml0ZXIoKTtcbiAgICAgICAgICAgIH0pKCk7XG4gICAgICAgIH1cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgOiBmdW5jdGlvbiBjcmVhdGVfYXJyYXkoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFdyaXRlcigpO1xuICAgICAgICB9O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHdyaXRlci5cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0J1ZmZlcldyaXRlcnxXcml0ZXJ9IEEge0BsaW5rIEJ1ZmZlcldyaXRlcn0gd2hlbiBCdWZmZXJzIGFyZSBzdXBwb3J0ZWQsIG90aGVyd2lzZSBhIHtAbGluayBXcml0ZXJ9XG4gKi9cbldyaXRlci5jcmVhdGUgPSBjcmVhdGUoKTtcblxuLyoqXG4gKiBBbGxvY2F0ZXMgYSBidWZmZXIgb2YgdGhlIHNwZWNpZmllZCBzaXplLlxuICogQHBhcmFtIHtudW1iZXJ9IHNpemUgQnVmZmVyIHNpemVcbiAqIEByZXR1cm5zIHtVaW50OEFycmF5fSBCdWZmZXJcbiAqL1xuV3JpdGVyLmFsbG9jID0gZnVuY3Rpb24gYWxsb2Moc2l6ZSkge1xuICAgIHJldHVybiBuZXcgdXRpbC5BcnJheShzaXplKTtcbn07XG5cbi8vIFVzZSBVaW50OEFycmF5IGJ1ZmZlciBwb29sIGluIHRoZSBicm93c2VyLCBqdXN0IGxpa2Ugbm9kZSBkb2VzIHdpdGggYnVmZmVyc1xuLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbmlmICh1dGlsLkFycmF5ICE9PSBBcnJheSlcbiAgICBXcml0ZXIuYWxsb2MgPSB1dGlsLnBvb2woV3JpdGVyLmFsbG9jLCB1dGlsLkFycmF5LnByb3RvdHlwZS5zdWJhcnJheSk7XG5cbi8qKlxuICogUHVzaGVzIGEgbmV3IG9wZXJhdGlvbiB0byB0aGUgcXVldWUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFVpbnQ4QXJyYXksIG51bWJlciwgKil9IGZuIEZ1bmN0aW9uIHRvIGNhbGxcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW4gVmFsdWUgYnl0ZSBsZW5ndGhcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWwgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICogQHByaXZhdGVcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5fcHVzaCA9IGZ1bmN0aW9uIHB1c2goZm4sIGxlbiwgdmFsKSB7XG4gICAgdGhpcy50YWlsID0gdGhpcy50YWlsLm5leHQgPSBuZXcgT3AoZm4sIGxlbiwgdmFsKTtcbiAgICB0aGlzLmxlbiArPSBsZW47XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiB3cml0ZUJ5dGUodmFsLCBidWYsIHBvcykge1xuICAgIGJ1Zltwb3NdID0gdmFsICYgMjU1O1xufVxuXG5mdW5jdGlvbiB3cml0ZVZhcmludDMyKHZhbCwgYnVmLCBwb3MpIHtcbiAgICB3aGlsZSAodmFsID4gMTI3KSB7XG4gICAgICAgIGJ1Zltwb3MrK10gPSB2YWwgJiAxMjcgfCAxMjg7XG4gICAgICAgIHZhbCA+Pj49IDc7XG4gICAgfVxuICAgIGJ1Zltwb3NdID0gdmFsO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgdmFyaW50IHdyaXRlciBvcGVyYXRpb24gaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIFNjaGVkdWxlZCB2YXJpbnQgd3JpdGVyIG9wZXJhdGlvbi5cbiAqIEBleHRlbmRzIE9wXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW4gVmFsdWUgYnl0ZSBsZW5ndGhcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWwgVmFsdWUgdG8gd3JpdGVcbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gVmFyaW50T3AobGVuLCB2YWwpIHtcbiAgICB0aGlzLmxlbiA9IGxlbjtcbiAgICB0aGlzLm5leHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy52YWwgPSB2YWw7XG59XG5cblZhcmludE9wLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoT3AucHJvdG90eXBlKTtcblZhcmludE9wLnByb3RvdHlwZS5mbiA9IHdyaXRlVmFyaW50MzI7XG5cbi8qKlxuICogV3JpdGVzIGFuIHVuc2lnbmVkIDMyIGJpdCB2YWx1ZSBhcyBhIHZhcmludC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUudWludDMyID0gZnVuY3Rpb24gd3JpdGVfdWludDMyKHZhbHVlKSB7XG4gICAgLy8gaGVyZSwgdGhlIGNhbGwgdG8gdGhpcy5wdXNoIGhhcyBiZWVuIGlubGluZWQgYW5kIGEgdmFyaW50IHNwZWNpZmljIE9wIHN1YmNsYXNzIGlzIHVzZWQuXG4gICAgLy8gdWludDMyIGlzIGJ5IGZhciB0aGUgbW9zdCBmcmVxdWVudGx5IHVzZWQgb3BlcmF0aW9uIGFuZCBiZW5lZml0cyBzaWduaWZpY2FudGx5IGZyb20gdGhpcy5cbiAgICB0aGlzLmxlbiArPSAodGhpcy50YWlsID0gdGhpcy50YWlsLm5leHQgPSBuZXcgVmFyaW50T3AoXG4gICAgICAgICh2YWx1ZSA9IHZhbHVlID4+PiAwKVxuICAgICAgICAgICAgICAgIDwgMTI4ICAgICAgID8gMVxuICAgICAgICA6IHZhbHVlIDwgMTYzODQgICAgID8gMlxuICAgICAgICA6IHZhbHVlIDwgMjA5NzE1MiAgID8gM1xuICAgICAgICA6IHZhbHVlIDwgMjY4NDM1NDU2ID8gNFxuICAgICAgICA6ICAgICAgICAgICAgICAgICAgICAgNSxcbiAgICB2YWx1ZSkpLmxlbjtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgc2lnbmVkIDMyIGJpdCB2YWx1ZSBhcyBhIHZhcmludC5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5pbnQzMiA9IGZ1bmN0aW9uIHdyaXRlX2ludDMyKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlIDwgMFxuICAgICAgICA/IHRoaXMuX3B1c2god3JpdGVWYXJpbnQ2NCwgMTAsIExvbmdCaXRzLmZyb21OdW1iZXIodmFsdWUpKSAvLyAxMCBieXRlcyBwZXIgc3BlY1xuICAgICAgICA6IHRoaXMudWludDMyKHZhbHVlKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgMzIgYml0IHZhbHVlIGFzIGEgdmFyaW50LCB6aWctemFnIGVuY29kZWQuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLnNpbnQzMiA9IGZ1bmN0aW9uIHdyaXRlX3NpbnQzMih2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLnVpbnQzMigodmFsdWUgPDwgMSBeIHZhbHVlID4+IDMxKSA+Pj4gMCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZVZhcmludDY0KHZhbCwgYnVmLCBwb3MpIHtcbiAgICB3aGlsZSAodmFsLmhpKSB7XG4gICAgICAgIGJ1Zltwb3MrK10gPSB2YWwubG8gJiAxMjcgfCAxMjg7XG4gICAgICAgIHZhbC5sbyA9ICh2YWwubG8gPj4+IDcgfCB2YWwuaGkgPDwgMjUpID4+PiAwO1xuICAgICAgICB2YWwuaGkgPj4+PSA3O1xuICAgIH1cbiAgICB3aGlsZSAodmFsLmxvID4gMTI3KSB7XG4gICAgICAgIGJ1Zltwb3MrK10gPSB2YWwubG8gJiAxMjcgfCAxMjg7XG4gICAgICAgIHZhbC5sbyA9IHZhbC5sbyA+Pj4gNztcbiAgICB9XG4gICAgYnVmW3BvcysrXSA9IHZhbC5sbztcbn1cblxuLyoqXG4gKiBXcml0ZXMgYW4gdW5zaWduZWQgNjQgYml0IHZhbHVlIGFzIGEgdmFyaW50LlxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUudWludDY0ID0gZnVuY3Rpb24gd3JpdGVfdWludDY0KHZhbHVlKSB7XG4gICAgdmFyIGJpdHMgPSBMb25nQml0cy5mcm9tKHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZVZhcmludDY0LCBiaXRzLmxlbmd0aCgpLCBiaXRzKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgc2lnbmVkIDY0IGJpdCB2YWx1ZSBhcyBhIHZhcmludC5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUuaW50NjQgPSBXcml0ZXIucHJvdG90eXBlLnVpbnQ2NDtcblxuLyoqXG4gKiBXcml0ZXMgYSBzaWduZWQgNjQgYml0IHZhbHVlIGFzIGEgdmFyaW50LCB6aWctemFnIGVuY29kZWQuXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfHN0cmluZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgdmFsdWVgIGlzIGEgc3RyaW5nIGFuZCBubyBsb25nIGxpYnJhcnkgaXMgcHJlc2VudC5cbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5zaW50NjQgPSBmdW5jdGlvbiB3cml0ZV9zaW50NjQodmFsdWUpIHtcbiAgICB2YXIgYml0cyA9IExvbmdCaXRzLmZyb20odmFsdWUpLnp6RW5jb2RlKCk7XG4gICAgcmV0dXJuIHRoaXMuX3B1c2god3JpdGVWYXJpbnQ2NCwgYml0cy5sZW5ndGgoKSwgYml0cyk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIGJvb2xpc2ggdmFsdWUgYXMgYSB2YXJpbnQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5ib29sID0gZnVuY3Rpb24gd3JpdGVfYm9vbCh2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLl9wdXNoKHdyaXRlQnl0ZSwgMSwgdmFsdWUgPyAxIDogMCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZUZpeGVkMzIodmFsLCBidWYsIHBvcykge1xuICAgIGJ1Zltwb3MgICAgXSA9ICB2YWwgICAgICAgICAmIDI1NTtcbiAgICBidWZbcG9zICsgMV0gPSAgdmFsID4+PiA4ICAgJiAyNTU7XG4gICAgYnVmW3BvcyArIDJdID0gIHZhbCA+Pj4gMTYgICYgMjU1O1xuICAgIGJ1Zltwb3MgKyAzXSA9ICB2YWwgPj4+IDI0O1xufVxuXG4vKipcbiAqIFdyaXRlcyBhbiB1bnNpZ25lZCAzMiBiaXQgdmFsdWUgYXMgZml4ZWQgMzIgYml0cy5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuZml4ZWQzMiA9IGZ1bmN0aW9uIHdyaXRlX2ZpeGVkMzIodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZUZpeGVkMzIsIDQsIHZhbHVlID4+PiAwKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgc2lnbmVkIDMyIGJpdCB2YWx1ZSBhcyBmaXhlZCAzMiBiaXRzLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLnNmaXhlZDMyID0gV3JpdGVyLnByb3RvdHlwZS5maXhlZDMyO1xuXG4vKipcbiAqIFdyaXRlcyBhbiB1bnNpZ25lZCA2NCBiaXQgdmFsdWUgYXMgZml4ZWQgNjQgYml0cy5cbiAqIEBwYXJhbSB7TG9uZ3xudW1iZXJ8c3RyaW5nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGB2YWx1ZWAgaXMgYSBzdHJpbmcgYW5kIG5vIGxvbmcgbGlicmFyeSBpcyBwcmVzZW50LlxuICovXG5Xcml0ZXIucHJvdG90eXBlLmZpeGVkNjQgPSBmdW5jdGlvbiB3cml0ZV9maXhlZDY0KHZhbHVlKSB7XG4gICAgdmFyIGJpdHMgPSBMb25nQml0cy5mcm9tKHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZUZpeGVkMzIsIDQsIGJpdHMubG8pLl9wdXNoKHdyaXRlRml4ZWQzMiwgNCwgYml0cy5oaSk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIHNpZ25lZCA2NCBiaXQgdmFsdWUgYXMgZml4ZWQgNjQgYml0cy5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUuc2ZpeGVkNjQgPSBXcml0ZXIucHJvdG90eXBlLmZpeGVkNjQ7XG5cbi8qKlxuICogV3JpdGVzIGEgZmxvYXQgKDMyIGJpdCkuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuZmxvYXQgPSBmdW5jdGlvbiB3cml0ZV9mbG9hdCh2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLl9wdXNoKHV0aWwuZmxvYXQud3JpdGVGbG9hdExFLCA0LCB2YWx1ZSk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIGRvdWJsZSAoNjQgYml0IGZsb2F0KS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5kb3VibGUgPSBmdW5jdGlvbiB3cml0ZV9kb3VibGUodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh1dGlsLmZsb2F0LndyaXRlRG91YmxlTEUsIDgsIHZhbHVlKTtcbn07XG5cbnZhciB3cml0ZUJ5dGVzID0gdXRpbC5BcnJheS5wcm90b3R5cGUuc2V0XG4gICAgPyBmdW5jdGlvbiB3cml0ZUJ5dGVzX3NldCh2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgICAgIGJ1Zi5zZXQodmFsLCBwb3MpOyAvLyBhbHNvIHdvcmtzIGZvciBwbGFpbiBhcnJheSB2YWx1ZXNcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICA6IGZ1bmN0aW9uIHdyaXRlQnl0ZXNfZm9yKHZhbCwgYnVmLCBwb3MpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWwubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBidWZbcG9zICsgaV0gPSB2YWxbaV07XG4gICAgfTtcblxuLyoqXG4gKiBXcml0ZXMgYSBzZXF1ZW5jZSBvZiBieXRlcy5cbiAqIEBwYXJhbSB7VWludDhBcnJheXxzdHJpbmd9IHZhbHVlIEJ1ZmZlciBvciBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmJ5dGVzID0gZnVuY3Rpb24gd3JpdGVfYnl0ZXModmFsdWUpIHtcbiAgICB2YXIgbGVuID0gdmFsdWUubGVuZ3RoID4+PiAwO1xuICAgIGlmICghbGVuKVxuICAgICAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZUJ5dGUsIDEsIDApO1xuICAgIGlmICh1dGlsLmlzU3RyaW5nKHZhbHVlKSkge1xuICAgICAgICB2YXIgYnVmID0gV3JpdGVyLmFsbG9jKGxlbiA9IGJhc2U2NC5sZW5ndGgodmFsdWUpKTtcbiAgICAgICAgYmFzZTY0LmRlY29kZSh2YWx1ZSwgYnVmLCAwKTtcbiAgICAgICAgdmFsdWUgPSBidWY7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnVpbnQzMihsZW4pLl9wdXNoKHdyaXRlQnl0ZXMsIGxlbiwgdmFsdWUpO1xufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBzdHJpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLnN0cmluZyA9IGZ1bmN0aW9uIHdyaXRlX3N0cmluZyh2YWx1ZSkge1xuICAgIHZhciBsZW4gPSB1dGY4Lmxlbmd0aCh2YWx1ZSk7XG4gICAgcmV0dXJuIGxlblxuICAgICAgICA/IHRoaXMudWludDMyKGxlbikuX3B1c2godXRmOC53cml0ZSwgbGVuLCB2YWx1ZSlcbiAgICAgICAgOiB0aGlzLl9wdXNoKHdyaXRlQnl0ZSwgMSwgMCk7XG59O1xuXG4vKipcbiAqIEZvcmtzIHRoaXMgd3JpdGVyJ3Mgc3RhdGUgYnkgcHVzaGluZyBpdCB0byBhIHN0YWNrLlxuICogQ2FsbGluZyB7QGxpbmsgV3JpdGVyI3Jlc2V0fHJlc2V0fSBvciB7QGxpbmsgV3JpdGVyI2xkZWxpbXxsZGVsaW19IHJlc2V0cyB0aGUgd3JpdGVyIHRvIHRoZSBwcmV2aW91cyBzdGF0ZS5cbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmZvcmsgPSBmdW5jdGlvbiBmb3JrKCkge1xuICAgIHRoaXMuc3RhdGVzID0gbmV3IFN0YXRlKHRoaXMpO1xuICAgIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG5ldyBPcChub29wLCAwLCAwKTtcbiAgICB0aGlzLmxlbiA9IDA7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlc2V0cyB0aGlzIGluc3RhbmNlIHRvIHRoZSBsYXN0IHN0YXRlLlxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbiByZXNldCgpIHtcbiAgICBpZiAodGhpcy5zdGF0ZXMpIHtcbiAgICAgICAgdGhpcy5oZWFkICAgPSB0aGlzLnN0YXRlcy5oZWFkO1xuICAgICAgICB0aGlzLnRhaWwgICA9IHRoaXMuc3RhdGVzLnRhaWw7XG4gICAgICAgIHRoaXMubGVuICAgID0gdGhpcy5zdGF0ZXMubGVuO1xuICAgICAgICB0aGlzLnN0YXRlcyA9IHRoaXMuc3RhdGVzLm5leHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbmV3IE9wKG5vb3AsIDAsIDApO1xuICAgICAgICB0aGlzLmxlbiAgPSAwO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVzZXRzIHRvIHRoZSBsYXN0IHN0YXRlIGFuZCBhcHBlbmRzIHRoZSBmb3JrIHN0YXRlJ3MgY3VycmVudCB3cml0ZSBsZW5ndGggYXMgYSB2YXJpbnQgZm9sbG93ZWQgYnkgaXRzIG9wZXJhdGlvbnMuXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5sZGVsaW0gPSBmdW5jdGlvbiBsZGVsaW0oKSB7XG4gICAgdmFyIGhlYWQgPSB0aGlzLmhlYWQsXG4gICAgICAgIHRhaWwgPSB0aGlzLnRhaWwsXG4gICAgICAgIGxlbiAgPSB0aGlzLmxlbjtcbiAgICB0aGlzLnJlc2V0KCkudWludDMyKGxlbik7XG4gICAgaWYgKGxlbikge1xuICAgICAgICB0aGlzLnRhaWwubmV4dCA9IGhlYWQubmV4dDsgLy8gc2tpcCBub29wXG4gICAgICAgIHRoaXMudGFpbCA9IHRhaWw7XG4gICAgICAgIHRoaXMubGVuICs9IGxlbjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEZpbmlzaGVzIHRoZSB3cml0ZSBvcGVyYXRpb24uXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gRmluaXNoZWQgYnVmZmVyXG4gKi9cbldyaXRlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gZmluaXNoKCkge1xuICAgIHZhciBoZWFkID0gdGhpcy5oZWFkLm5leHQsIC8vIHNraXAgbm9vcFxuICAgICAgICBidWYgID0gdGhpcy5jb25zdHJ1Y3Rvci5hbGxvYyh0aGlzLmxlbiksXG4gICAgICAgIHBvcyAgPSAwO1xuICAgIHdoaWxlIChoZWFkKSB7XG4gICAgICAgIGhlYWQuZm4oaGVhZC52YWwsIGJ1ZiwgcG9zKTtcbiAgICAgICAgcG9zICs9IGhlYWQubGVuO1xuICAgICAgICBoZWFkID0gaGVhZC5uZXh0O1xuICAgIH1cbiAgICAvLyB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBudWxsO1xuICAgIHJldHVybiBidWY7XG59O1xuXG5Xcml0ZXIuX2NvbmZpZ3VyZSA9IGZ1bmN0aW9uKEJ1ZmZlcldyaXRlcl8pIHtcbiAgICBCdWZmZXJXcml0ZXIgPSBCdWZmZXJXcml0ZXJfO1xuICAgIFdyaXRlci5jcmVhdGUgPSBjcmVhdGUoKTtcbiAgICBCdWZmZXJXcml0ZXIuX2NvbmZpZ3VyZSgpO1xufTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gQnVmZmVyV3JpdGVyO1xuXG4vLyBleHRlbmRzIFdyaXRlclxudmFyIFdyaXRlciA9IHJlcXVpcmUoXCIuL3dyaXRlclwiKTtcbihCdWZmZXJXcml0ZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShXcml0ZXIucHJvdG90eXBlKSkuY29uc3RydWN0b3IgPSBCdWZmZXJXcml0ZXI7XG5cbnZhciB1dGlsID0gcmVxdWlyZShcIi4vdXRpbC9taW5pbWFsXCIpO1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgYnVmZmVyIHdyaXRlciBpbnN0YW5jZS5cbiAqIEBjbGFzc2Rlc2MgV2lyZSBmb3JtYXQgd3JpdGVyIHVzaW5nIG5vZGUgYnVmZmVycy5cbiAqIEBleHRlbmRzIFdyaXRlclxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIEJ1ZmZlcldyaXRlcigpIHtcbiAgICBXcml0ZXIuY2FsbCh0aGlzKTtcbn1cblxuQnVmZmVyV3JpdGVyLl9jb25maWd1cmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogQWxsb2NhdGVzIGEgYnVmZmVyIG9mIHRoZSBzcGVjaWZpZWQgc2l6ZS5cbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBCdWZmZXIgc2l6ZVxuICAgICAqIEByZXR1cm5zIHtCdWZmZXJ9IEJ1ZmZlclxuICAgICAqL1xuICAgIEJ1ZmZlcldyaXRlci5hbGxvYyA9IHV0aWwuX0J1ZmZlcl9hbGxvY1Vuc2FmZTtcblxuICAgIEJ1ZmZlcldyaXRlci53cml0ZUJ5dGVzQnVmZmVyID0gdXRpbC5CdWZmZXIgJiYgdXRpbC5CdWZmZXIucHJvdG90eXBlIGluc3RhbmNlb2YgVWludDhBcnJheSAmJiB1dGlsLkJ1ZmZlci5wcm90b3R5cGUuc2V0Lm5hbWUgPT09IFwic2V0XCJcbiAgICAgICAgPyBmdW5jdGlvbiB3cml0ZUJ5dGVzQnVmZmVyX3NldCh2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgICAgICAgYnVmLnNldCh2YWwsIHBvcyk7IC8vIGZhc3RlciB0aGFuIGNvcHkgKHJlcXVpcmVzIG5vZGUgPj0gNCB3aGVyZSBCdWZmZXJzIGV4dGVuZCBVaW50OEFycmF5IGFuZCBzZXQgaXMgcHJvcGVybHkgaW5oZXJpdGVkKVxuICAgICAgICAgIC8vIGFsc28gd29ya3MgZm9yIHBsYWluIGFycmF5IHZhbHVlc1xuICAgICAgICB9XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIDogZnVuY3Rpb24gd3JpdGVCeXRlc0J1ZmZlcl9jb3B5KHZhbCwgYnVmLCBwb3MpIHtcbiAgICAgICAgICBpZiAodmFsLmNvcHkpIC8vIEJ1ZmZlciB2YWx1ZXNcbiAgICAgICAgICAgIHZhbC5jb3B5KGJ1ZiwgcG9zLCAwLCB2YWwubGVuZ3RoKTtcbiAgICAgICAgICBlbHNlIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsLmxlbmd0aDspIC8vIHBsYWluIGFycmF5IHZhbHVlc1xuICAgICAgICAgICAgYnVmW3BvcysrXSA9IHZhbFtpKytdO1xuICAgICAgICB9O1xufTtcblxuXG4vKipcbiAqIEBvdmVycmlkZVxuICovXG5CdWZmZXJXcml0ZXIucHJvdG90eXBlLmJ5dGVzID0gZnVuY3Rpb24gd3JpdGVfYnl0ZXNfYnVmZmVyKHZhbHVlKSB7XG4gICAgaWYgKHV0aWwuaXNTdHJpbmcodmFsdWUpKVxuICAgICAgICB2YWx1ZSA9IHV0aWwuX0J1ZmZlcl9mcm9tKHZhbHVlLCBcImJhc2U2NFwiKTtcbiAgICB2YXIgbGVuID0gdmFsdWUubGVuZ3RoID4+PiAwO1xuICAgIHRoaXMudWludDMyKGxlbik7XG4gICAgaWYgKGxlbilcbiAgICAgICAgdGhpcy5fcHVzaChCdWZmZXJXcml0ZXIud3JpdGVCeXRlc0J1ZmZlciwgbGVuLCB2YWx1ZSk7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiB3cml0ZVN0cmluZ0J1ZmZlcih2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgaWYgKHZhbC5sZW5ndGggPCA0MCkgLy8gcGxhaW4ganMgaXMgZmFzdGVyIGZvciBzaG9ydCBzdHJpbmdzIChwcm9iYWJseSBkdWUgdG8gcmVkdW5kYW50IGFzc2VydGlvbnMpXG4gICAgICAgIHV0aWwudXRmOC53cml0ZSh2YWwsIGJ1ZiwgcG9zKTtcbiAgICBlbHNlIGlmIChidWYudXRmOFdyaXRlKVxuICAgICAgICBidWYudXRmOFdyaXRlKHZhbCwgcG9zKTtcbiAgICBlbHNlXG4gICAgICAgIGJ1Zi53cml0ZSh2YWwsIHBvcyk7XG59XG5cbi8qKlxuICogQG92ZXJyaWRlXG4gKi9cbkJ1ZmZlcldyaXRlci5wcm90b3R5cGUuc3RyaW5nID0gZnVuY3Rpb24gd3JpdGVfc3RyaW5nX2J1ZmZlcih2YWx1ZSkge1xuICAgIHZhciBsZW4gPSB1dGlsLkJ1ZmZlci5ieXRlTGVuZ3RoKHZhbHVlKTtcbiAgICB0aGlzLnVpbnQzMihsZW4pO1xuICAgIGlmIChsZW4pXG4gICAgICAgIHRoaXMuX3B1c2god3JpdGVTdHJpbmdCdWZmZXIsIGxlbiwgdmFsdWUpO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuXG4vKipcbiAqIEZpbmlzaGVzIHRoZSB3cml0ZSBvcGVyYXRpb24uXG4gKiBAbmFtZSBCdWZmZXJXcml0ZXIjZmluaXNoXG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtCdWZmZXJ9IEZpbmlzaGVkIGJ1ZmZlclxuICovXG5cbkJ1ZmZlcldyaXRlci5fY29uZmlndXJlKCk7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IFJlYWRlcjtcblxudmFyIHV0aWwgICAgICA9IHJlcXVpcmUoXCIuL3V0aWwvbWluaW1hbFwiKTtcblxudmFyIEJ1ZmZlclJlYWRlcjsgLy8gY3ljbGljXG5cbnZhciBMb25nQml0cyAgPSB1dGlsLkxvbmdCaXRzLFxuICAgIHV0ZjggICAgICA9IHV0aWwudXRmODtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIGluZGV4T3V0T2ZSYW5nZShyZWFkZXIsIHdyaXRlTGVuZ3RoKSB7XG4gICAgcmV0dXJuIFJhbmdlRXJyb3IoXCJpbmRleCBvdXQgb2YgcmFuZ2U6IFwiICsgcmVhZGVyLnBvcyArIFwiICsgXCIgKyAod3JpdGVMZW5ndGggfHwgMSkgKyBcIiA+IFwiICsgcmVhZGVyLmxlbik7XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyByZWFkZXIgaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBidWZmZXIuXG4gKiBAY2xhc3NkZXNjIFdpcmUgZm9ybWF0IHJlYWRlciB1c2luZyBgVWludDhBcnJheWAgaWYgYXZhaWxhYmxlLCBvdGhlcndpc2UgYEFycmF5YC5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWZmZXIgQnVmZmVyIHRvIHJlYWQgZnJvbVxuICovXG5mdW5jdGlvbiBSZWFkZXIoYnVmZmVyKSB7XG5cbiAgICAvKipcbiAgICAgKiBSZWFkIGJ1ZmZlci5cbiAgICAgKiBAdHlwZSB7VWludDhBcnJheX1cbiAgICAgKi9cbiAgICB0aGlzLmJ1ZiA9IGJ1ZmZlcjtcblxuICAgIC8qKlxuICAgICAqIFJlYWQgYnVmZmVyIHBvc2l0aW9uLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5wb3MgPSAwO1xuXG4gICAgLyoqXG4gICAgICogUmVhZCBidWZmZXIgbGVuZ3RoLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5sZW4gPSBidWZmZXIubGVuZ3RoO1xufVxuXG52YXIgY3JlYXRlX2FycmF5ID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09IFwidW5kZWZpbmVkXCJcbiAgICA/IGZ1bmN0aW9uIGNyZWF0ZV90eXBlZF9hcnJheShidWZmZXIpIHtcbiAgICAgICAgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkgfHwgQXJyYXkuaXNBcnJheShidWZmZXIpKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWFkZXIoYnVmZmVyKTtcbiAgICAgICAgdGhyb3cgRXJyb3IoXCJpbGxlZ2FsIGJ1ZmZlclwiKTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICA6IGZ1bmN0aW9uIGNyZWF0ZV9hcnJheShidWZmZXIpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYnVmZmVyKSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVhZGVyKGJ1ZmZlcik7XG4gICAgICAgIHRocm93IEVycm9yKFwiaWxsZWdhbCBidWZmZXJcIik7XG4gICAgfTtcblxudmFyIGNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICByZXR1cm4gdXRpbC5CdWZmZXJcbiAgICAgICAgPyBmdW5jdGlvbiBjcmVhdGVfYnVmZmVyX3NldHVwKGJ1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIChSZWFkZXIuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlX2J1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdXRpbC5CdWZmZXIuaXNCdWZmZXIoYnVmZmVyKVxuICAgICAgICAgICAgICAgICAgICA/IG5ldyBCdWZmZXJSZWFkZXIoYnVmZmVyKVxuICAgICAgICAgICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAgICAgICAgICAgICA6IGNyZWF0ZV9hcnJheShidWZmZXIpO1xuICAgICAgICAgICAgfSkoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICA6IGNyZWF0ZV9hcnJheTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyByZWFkZXIgdXNpbmcgdGhlIHNwZWNpZmllZCBidWZmZXIuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7VWludDhBcnJheXxCdWZmZXJ9IGJ1ZmZlciBCdWZmZXIgdG8gcmVhZCBmcm9tXG4gKiBAcmV0dXJucyB7UmVhZGVyfEJ1ZmZlclJlYWRlcn0gQSB7QGxpbmsgQnVmZmVyUmVhZGVyfSBpZiBgYnVmZmVyYCBpcyBhIEJ1ZmZlciwgb3RoZXJ3aXNlIGEge0BsaW5rIFJlYWRlcn1cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiBgYnVmZmVyYCBpcyBub3QgYSB2YWxpZCBidWZmZXJcbiAqL1xuUmVhZGVyLmNyZWF0ZSA9IGNyZWF0ZSgpO1xuXG5SZWFkZXIucHJvdG90eXBlLl9zbGljZSA9IHV0aWwuQXJyYXkucHJvdG90eXBlLnN1YmFycmF5IHx8IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIHV0aWwuQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuXG4vKipcbiAqIFJlYWRzIGEgdmFyaW50IGFzIGFuIHVuc2lnbmVkIDMyIGJpdCB2YWx1ZS5cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLnVpbnQzMiA9IChmdW5jdGlvbiByZWFkX3VpbnQzMl9zZXR1cCgpIHtcbiAgICB2YXIgdmFsdWUgPSA0Mjk0OTY3Mjk1OyAvLyBvcHRpbWl6ZXIgdHlwZS1oaW50LCB0ZW5kcyB0byBkZW9wdCBvdGhlcndpc2UgKD8hKVxuICAgIHJldHVybiBmdW5jdGlvbiByZWFkX3VpbnQzMigpIHtcbiAgICAgICAgdmFsdWUgPSAoICAgICAgICAgdGhpcy5idWZbdGhpcy5wb3NdICYgMTI3ICAgICAgICkgPj4+IDA7IGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOCkgcmV0dXJuIHZhbHVlO1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8ICA3KSA+Pj4gMDsgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KSByZXR1cm4gdmFsdWU7XG4gICAgICAgIHZhbHVlID0gKHZhbHVlIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPDwgMTQpID4+PiAwOyBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpIHJldHVybiB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSAodmFsdWUgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA8PCAyMSkgPj4+IDA7IGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOCkgcmV0dXJuIHZhbHVlO1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAgMTUpIDw8IDI4KSA+Pj4gMDsgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KSByZXR1cm4gdmFsdWU7XG5cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgIGlmICgodGhpcy5wb3MgKz0gNSkgPiB0aGlzLmxlbikge1xuICAgICAgICAgICAgdGhpcy5wb3MgPSB0aGlzLmxlbjtcbiAgICAgICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCAxMCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG59KSgpO1xuXG4vKipcbiAqIFJlYWRzIGEgdmFyaW50IGFzIGEgc2lnbmVkIDMyIGJpdCB2YWx1ZS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5pbnQzMiA9IGZ1bmN0aW9uIHJlYWRfaW50MzIoKSB7XG4gICAgcmV0dXJuIHRoaXMudWludDMyKCkgfCAwO1xufTtcblxuLyoqXG4gKiBSZWFkcyBhIHppZy16YWcgZW5jb2RlZCB2YXJpbnQgYXMgYSBzaWduZWQgMzIgYml0IHZhbHVlLlxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLnNpbnQzMiA9IGZ1bmN0aW9uIHJlYWRfc2ludDMyKCkge1xuICAgIHZhciB2YWx1ZSA9IHRoaXMudWludDMyKCk7XG4gICAgcmV0dXJuIHZhbHVlID4+PiAxIF4gLSh2YWx1ZSAmIDEpIHwgMDtcbn07XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLWludmFsaWQtdGhpcyAqL1xuXG5mdW5jdGlvbiByZWFkTG9uZ1ZhcmludCgpIHtcbiAgICAvLyB0ZW5kcyB0byBkZW9wdCB3aXRoIGxvY2FsIHZhcnMgZm9yIG9jdGV0IGV0Yy5cbiAgICB2YXIgYml0cyA9IG5ldyBMb25nQml0cygwLCAwKTtcbiAgICB2YXIgaSA9IDA7XG4gICAgaWYgKHRoaXMubGVuIC0gdGhpcy5wb3MgPiA0KSB7IC8vIGZhc3Qgcm91dGUgKGxvKVxuICAgICAgICBmb3IgKDsgaSA8IDQ7ICsraSkge1xuICAgICAgICAgICAgLy8gMXN0Li40dGhcbiAgICAgICAgICAgIGJpdHMubG8gPSAoYml0cy5sbyB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IGkgKiA3KSA+Pj4gMDtcbiAgICAgICAgICAgIGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOClcbiAgICAgICAgICAgICAgICByZXR1cm4gYml0cztcbiAgICAgICAgfVxuICAgICAgICAvLyA1dGhcbiAgICAgICAgYml0cy5sbyA9IChiaXRzLmxvIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPDwgMjgpID4+PiAwO1xuICAgICAgICBiaXRzLmhpID0gKGJpdHMuaGkgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA+PiAgNCkgPj4+IDA7XG4gICAgICAgIGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOClcbiAgICAgICAgICAgIHJldHVybiBiaXRzO1xuICAgICAgICBpID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKDsgaSA8IDM7ICsraSkge1xuICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICBpZiAodGhpcy5wb3MgPj0gdGhpcy5sZW4pXG4gICAgICAgICAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMpO1xuICAgICAgICAgICAgLy8gMXN0Li4zdGhcbiAgICAgICAgICAgIGJpdHMubG8gPSAoYml0cy5sbyB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IGkgKiA3KSA+Pj4gMDtcbiAgICAgICAgICAgIGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOClcbiAgICAgICAgICAgICAgICByZXR1cm4gYml0cztcbiAgICAgICAgfVxuICAgICAgICAvLyA0dGhcbiAgICAgICAgYml0cy5sbyA9IChiaXRzLmxvIHwgKHRoaXMuYnVmW3RoaXMucG9zKytdICYgMTI3KSA8PCBpICogNykgPj4+IDA7XG4gICAgICAgIHJldHVybiBiaXRzO1xuICAgIH1cbiAgICBpZiAodGhpcy5sZW4gLSB0aGlzLnBvcyA+IDQpIHsgLy8gZmFzdCByb3V0ZSAoaGkpXG4gICAgICAgIGZvciAoOyBpIDwgNTsgKytpKSB7XG4gICAgICAgICAgICAvLyA2dGguLjEwdGhcbiAgICAgICAgICAgIGJpdHMuaGkgPSAoYml0cy5oaSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IGkgKiA3ICsgMykgPj4+IDA7XG4gICAgICAgICAgICBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpdHM7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKDsgaSA8IDU7ICsraSkge1xuICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICBpZiAodGhpcy5wb3MgPj0gdGhpcy5sZW4pXG4gICAgICAgICAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMpO1xuICAgICAgICAgICAgLy8gNnRoLi4xMHRoXG4gICAgICAgICAgICBiaXRzLmhpID0gKGJpdHMuaGkgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA8PCBpICogNyArIDMpID4+PiAwO1xuICAgICAgICAgICAgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KVxuICAgICAgICAgICAgICAgIHJldHVybiBiaXRzO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgdGhyb3cgRXJyb3IoXCJpbnZhbGlkIHZhcmludCBlbmNvZGluZ1wiKTtcbn1cblxuLyogZXNsaW50LWVuYWJsZSBuby1pbnZhbGlkLXRoaXMgKi9cblxuLyoqXG4gKiBSZWFkcyBhIHZhcmludCBhcyBhIHNpZ25lZCA2NCBiaXQgdmFsdWUuXG4gKiBAbmFtZSBSZWFkZXIjaW50NjRcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0xvbmd9IFZhbHVlIHJlYWRcbiAqL1xuXG4vKipcbiAqIFJlYWRzIGEgdmFyaW50IGFzIGFuIHVuc2lnbmVkIDY0IGJpdCB2YWx1ZS5cbiAqIEBuYW1lIFJlYWRlciN1aW50NjRcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0xvbmd9IFZhbHVlIHJlYWRcbiAqL1xuXG4vKipcbiAqIFJlYWRzIGEgemlnLXphZyBlbmNvZGVkIHZhcmludCBhcyBhIHNpZ25lZCA2NCBiaXQgdmFsdWUuXG4gKiBAbmFtZSBSZWFkZXIjc2ludDY0XG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtMb25nfSBWYWx1ZSByZWFkXG4gKi9cblxuLyoqXG4gKiBSZWFkcyBhIHZhcmludCBhcyBhIGJvb2xlYW4uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLmJvb2wgPSBmdW5jdGlvbiByZWFkX2Jvb2woKSB7XG4gICAgcmV0dXJuIHRoaXMudWludDMyKCkgIT09IDA7XG59O1xuXG5mdW5jdGlvbiByZWFkRml4ZWQzMl9lbmQoYnVmLCBlbmQpIHsgLy8gbm90ZSB0aGF0IHRoaXMgdXNlcyBgZW5kYCwgbm90IGBwb3NgXG4gICAgcmV0dXJuIChidWZbZW5kIC0gNF1cbiAgICAgICAgICB8IGJ1ZltlbmQgLSAzXSA8PCA4XG4gICAgICAgICAgfCBidWZbZW5kIC0gMl0gPDwgMTZcbiAgICAgICAgICB8IGJ1ZltlbmQgLSAxXSA8PCAyNCkgPj4+IDA7XG59XG5cbi8qKlxuICogUmVhZHMgZml4ZWQgMzIgYml0cyBhcyBhbiB1bnNpZ25lZCAzMiBiaXQgaW50ZWdlci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5maXhlZDMyID0gZnVuY3Rpb24gcmVhZF9maXhlZDMyKCkge1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHRoaXMucG9zICsgNCA+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgNCk7XG5cbiAgICByZXR1cm4gcmVhZEZpeGVkMzJfZW5kKHRoaXMuYnVmLCB0aGlzLnBvcyArPSA0KTtcbn07XG5cbi8qKlxuICogUmVhZHMgZml4ZWQgMzIgYml0cyBhcyBhIHNpZ25lZCAzMiBiaXQgaW50ZWdlci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5zZml4ZWQzMiA9IGZ1bmN0aW9uIHJlYWRfc2ZpeGVkMzIoKSB7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodGhpcy5wb3MgKyA0ID4gdGhpcy5sZW4pXG4gICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCA0KTtcblxuICAgIHJldHVybiByZWFkRml4ZWQzMl9lbmQodGhpcy5idWYsIHRoaXMucG9zICs9IDQpIHwgMDtcbn07XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLWludmFsaWQtdGhpcyAqL1xuXG5mdW5jdGlvbiByZWFkRml4ZWQ2NCgvKiB0aGlzOiBSZWFkZXIgKi8pIHtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICh0aGlzLnBvcyArIDggPiB0aGlzLmxlbilcbiAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMsIDgpO1xuXG4gICAgcmV0dXJuIG5ldyBMb25nQml0cyhyZWFkRml4ZWQzMl9lbmQodGhpcy5idWYsIHRoaXMucG9zICs9IDQpLCByZWFkRml4ZWQzMl9lbmQodGhpcy5idWYsIHRoaXMucG9zICs9IDQpKTtcbn1cblxuLyogZXNsaW50LWVuYWJsZSBuby1pbnZhbGlkLXRoaXMgKi9cblxuLyoqXG4gKiBSZWFkcyBmaXhlZCA2NCBiaXRzLlxuICogQG5hbWUgUmVhZGVyI2ZpeGVkNjRcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0xvbmd9IFZhbHVlIHJlYWRcbiAqL1xuXG4vKipcbiAqIFJlYWRzIHppZy16YWcgZW5jb2RlZCBmaXhlZCA2NCBiaXRzLlxuICogQG5hbWUgUmVhZGVyI3NmaXhlZDY0XG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtMb25nfSBWYWx1ZSByZWFkXG4gKi9cblxuLyoqXG4gKiBSZWFkcyBhIGZsb2F0ICgzMiBiaXQpIGFzIGEgbnVtYmVyLlxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuZmxvYXQgPSBmdW5jdGlvbiByZWFkX2Zsb2F0KCkge1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHRoaXMucG9zICsgNCA+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgNCk7XG5cbiAgICB2YXIgdmFsdWUgPSB1dGlsLmZsb2F0LnJlYWRGbG9hdExFKHRoaXMuYnVmLCB0aGlzLnBvcyk7XG4gICAgdGhpcy5wb3MgKz0gNDtcbiAgICByZXR1cm4gdmFsdWU7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgZG91YmxlICg2NCBiaXQgZmxvYXQpIGFzIGEgbnVtYmVyLlxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuZG91YmxlID0gZnVuY3Rpb24gcmVhZF9kb3VibGUoKSB7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodGhpcy5wb3MgKyA4ID4gdGhpcy5sZW4pXG4gICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCA0KTtcblxuICAgIHZhciB2YWx1ZSA9IHV0aWwuZmxvYXQucmVhZERvdWJsZUxFKHRoaXMuYnVmLCB0aGlzLnBvcyk7XG4gICAgdGhpcy5wb3MgKz0gODtcbiAgICByZXR1cm4gdmFsdWU7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgc2VxdWVuY2Ugb2YgYnl0ZXMgcHJlY2VlZGVkIGJ5IGl0cyBsZW5ndGggYXMgYSB2YXJpbnQuXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLmJ5dGVzID0gZnVuY3Rpb24gcmVhZF9ieXRlcygpIHtcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy51aW50MzIoKSxcbiAgICAgICAgc3RhcnQgID0gdGhpcy5wb3MsXG4gICAgICAgIGVuZCAgICA9IHRoaXMucG9zICsgbGVuZ3RoO1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKGVuZCA+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgbGVuZ3RoKTtcblxuICAgIHRoaXMucG9zICs9IGxlbmd0aDtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLmJ1ZikpIC8vIHBsYWluIGFycmF5XG4gICAgICAgIHJldHVybiB0aGlzLmJ1Zi5zbGljZShzdGFydCwgZW5kKTtcblxuICAgIGlmIChzdGFydCA9PT0gZW5kKSB7IC8vIGZpeCBmb3IgSUUgMTAvV2luOCBhbmQgb3RoZXJzJyBzdWJhcnJheSByZXR1cm5pbmcgYXJyYXkgb2Ygc2l6ZSAxXG4gICAgICAgIHZhciBuYXRpdmVCdWZmZXIgPSB1dGlsLkJ1ZmZlcjtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUJ1ZmZlclxuICAgICAgICAgICAgPyBuYXRpdmVCdWZmZXIuYWxsb2MoMClcbiAgICAgICAgICAgIDogbmV3IHRoaXMuYnVmLmNvbnN0cnVjdG9yKDApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc2xpY2UuY2FsbCh0aGlzLmJ1Ziwgc3RhcnQsIGVuZCk7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgc3RyaW5nIHByZWNlZWRlZCBieSBpdHMgYnl0ZSBsZW5ndGggYXMgYSB2YXJpbnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuc3RyaW5nID0gZnVuY3Rpb24gcmVhZF9zdHJpbmcoKSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy5ieXRlcygpO1xuICAgIHJldHVybiB1dGY4LnJlYWQoYnl0ZXMsIDAsIGJ5dGVzLmxlbmd0aCk7XG59O1xuXG4vKipcbiAqIFNraXBzIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzIGlmIHNwZWNpZmllZCwgb3RoZXJ3aXNlIHNraXBzIGEgdmFyaW50LlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIExlbmd0aCBpZiBrbm93biwgb3RoZXJ3aXNlIGEgdmFyaW50IGlzIGFzc3VtZWRcbiAqIEByZXR1cm5zIHtSZWFkZXJ9IGB0aGlzYFxuICovXG5SZWFkZXIucHJvdG90eXBlLnNraXAgPSBmdW5jdGlvbiBza2lwKGxlbmd0aCkge1xuICAgIGlmICh0eXBlb2YgbGVuZ3RoID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICBpZiAodGhpcy5wb3MgKyBsZW5ndGggPiB0aGlzLmxlbilcbiAgICAgICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB0aGlzLnBvcyArPSBsZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZG8ge1xuICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICBpZiAodGhpcy5wb3MgPj0gdGhpcy5sZW4pXG4gICAgICAgICAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMpO1xuICAgICAgICB9IHdoaWxlICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSAmIDEyOCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTa2lwcyB0aGUgbmV4dCBlbGVtZW50IG9mIHRoZSBzcGVjaWZpZWQgd2lyZSB0eXBlLlxuICogQHBhcmFtIHtudW1iZXJ9IHdpcmVUeXBlIFdpcmUgdHlwZSByZWNlaXZlZFxuICogQHJldHVybnMge1JlYWRlcn0gYHRoaXNgXG4gKi9cblJlYWRlci5wcm90b3R5cGUuc2tpcFR5cGUgPSBmdW5jdGlvbih3aXJlVHlwZSkge1xuICAgIHN3aXRjaCAod2lyZVR5cGUpIHtcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgdGhpcy5za2lwKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgdGhpcy5za2lwKDgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgIHRoaXMuc2tpcCh0aGlzLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICB3aGlsZSAoKHdpcmVUeXBlID0gdGhpcy51aW50MzIoKSAmIDcpICE9PSA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5za2lwVHlwZSh3aXJlVHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgdGhpcy5za2lwKDQpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiaW52YWxpZCB3aXJlIHR5cGUgXCIgKyB3aXJlVHlwZSArIFwiIGF0IG9mZnNldCBcIiArIHRoaXMucG9zKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5SZWFkZXIuX2NvbmZpZ3VyZSA9IGZ1bmN0aW9uKEJ1ZmZlclJlYWRlcl8pIHtcbiAgICBCdWZmZXJSZWFkZXIgPSBCdWZmZXJSZWFkZXJfO1xuICAgIFJlYWRlci5jcmVhdGUgPSBjcmVhdGUoKTtcbiAgICBCdWZmZXJSZWFkZXIuX2NvbmZpZ3VyZSgpO1xuXG4gICAgdmFyIGZuID0gdXRpbC5Mb25nID8gXCJ0b0xvbmdcIiA6IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIFwidG9OdW1iZXJcIjtcbiAgICB1dGlsLm1lcmdlKFJlYWRlci5wcm90b3R5cGUsIHtcblxuICAgICAgICBpbnQ2NDogZnVuY3Rpb24gcmVhZF9pbnQ2NCgpIHtcbiAgICAgICAgICAgIHJldHVybiByZWFkTG9uZ1ZhcmludC5jYWxsKHRoaXMpW2ZuXShmYWxzZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgdWludDY0OiBmdW5jdGlvbiByZWFkX3VpbnQ2NCgpIHtcbiAgICAgICAgICAgIHJldHVybiByZWFkTG9uZ1ZhcmludC5jYWxsKHRoaXMpW2ZuXSh0cnVlKTtcbiAgICAgICAgfSxcblxuICAgICAgICBzaW50NjQ6IGZ1bmN0aW9uIHJlYWRfc2ludDY0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlYWRMb25nVmFyaW50LmNhbGwodGhpcykuenpEZWNvZGUoKVtmbl0oZmFsc2UpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpeGVkNjQ6IGZ1bmN0aW9uIHJlYWRfZml4ZWQ2NCgpIHtcbiAgICAgICAgICAgIHJldHVybiByZWFkRml4ZWQ2NC5jYWxsKHRoaXMpW2ZuXSh0cnVlKTtcbiAgICAgICAgfSxcblxuICAgICAgICBzZml4ZWQ2NDogZnVuY3Rpb24gcmVhZF9zZml4ZWQ2NCgpIHtcbiAgICAgICAgICAgIHJldHVybiByZWFkRml4ZWQ2NC5jYWxsKHRoaXMpW2ZuXShmYWxzZSk7XG4gICAgICAgIH1cblxuICAgIH0pO1xufTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gQnVmZmVyUmVhZGVyO1xuXG4vLyBleHRlbmRzIFJlYWRlclxudmFyIFJlYWRlciA9IHJlcXVpcmUoXCIuL3JlYWRlclwiKTtcbihCdWZmZXJSZWFkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShSZWFkZXIucHJvdG90eXBlKSkuY29uc3RydWN0b3IgPSBCdWZmZXJSZWFkZXI7XG5cbnZhciB1dGlsID0gcmVxdWlyZShcIi4vdXRpbC9taW5pbWFsXCIpO1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgYnVmZmVyIHJlYWRlciBpbnN0YW5jZS5cbiAqIEBjbGFzc2Rlc2MgV2lyZSBmb3JtYXQgcmVhZGVyIHVzaW5nIG5vZGUgYnVmZmVycy5cbiAqIEBleHRlbmRzIFJlYWRlclxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0J1ZmZlcn0gYnVmZmVyIEJ1ZmZlciB0byByZWFkIGZyb21cbiAqL1xuZnVuY3Rpb24gQnVmZmVyUmVhZGVyKGJ1ZmZlcikge1xuICAgIFJlYWRlci5jYWxsKHRoaXMsIGJ1ZmZlcik7XG5cbiAgICAvKipcbiAgICAgKiBSZWFkIGJ1ZmZlci5cbiAgICAgKiBAbmFtZSBCdWZmZXJSZWFkZXIjYnVmXG4gICAgICogQHR5cGUge0J1ZmZlcn1cbiAgICAgKi9cbn1cblxuQnVmZmVyUmVhZGVyLl9jb25maWd1cmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAodXRpbC5CdWZmZXIpXG4gICAgICAgIEJ1ZmZlclJlYWRlci5wcm90b3R5cGUuX3NsaWNlID0gdXRpbC5CdWZmZXIucHJvdG90eXBlLnNsaWNlO1xufTtcblxuXG4vKipcbiAqIEBvdmVycmlkZVxuICovXG5CdWZmZXJSZWFkZXIucHJvdG90eXBlLnN0cmluZyA9IGZ1bmN0aW9uIHJlYWRfc3RyaW5nX2J1ZmZlcigpIHtcbiAgICB2YXIgbGVuID0gdGhpcy51aW50MzIoKTsgLy8gbW9kaWZpZXMgcG9zXG4gICAgcmV0dXJuIHRoaXMuYnVmLnV0ZjhTbGljZVxuICAgICAgICA/IHRoaXMuYnVmLnV0ZjhTbGljZSh0aGlzLnBvcywgdGhpcy5wb3MgPSBNYXRoLm1pbih0aGlzLnBvcyArIGxlbiwgdGhpcy5sZW4pKVxuICAgICAgICA6IHRoaXMuYnVmLnRvU3RyaW5nKFwidXRmLThcIiwgdGhpcy5wb3MsIHRoaXMucG9zID0gTWF0aC5taW4odGhpcy5wb3MgKyBsZW4sIHRoaXMubGVuKSk7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgc2VxdWVuY2Ugb2YgYnl0ZXMgcHJlY2VlZGVkIGJ5IGl0cyBsZW5ndGggYXMgYSB2YXJpbnQuXG4gKiBAbmFtZSBCdWZmZXJSZWFkZXIjYnl0ZXNcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0J1ZmZlcn0gVmFsdWUgcmVhZFxuICovXG5cbkJ1ZmZlclJlYWRlci5fY29uZmlndXJlKCk7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IFNlcnZpY2U7XG5cbnZhciB1dGlsID0gcmVxdWlyZShcIi4uL3V0aWwvbWluaW1hbFwiKTtcblxuLy8gRXh0ZW5kcyBFdmVudEVtaXR0ZXJcbihTZXJ2aWNlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUodXRpbC5FdmVudEVtaXR0ZXIucHJvdG90eXBlKSkuY29uc3RydWN0b3IgPSBTZXJ2aWNlO1xuXG4vKipcbiAqIEEgc2VydmljZSBtZXRob2QgY2FsbGJhY2sgYXMgdXNlZCBieSB7QGxpbmsgcnBjLlNlcnZpY2VNZXRob2R8U2VydmljZU1ldGhvZH0uXG4gKlxuICogRGlmZmVycyBmcm9tIHtAbGluayBSUENJbXBsQ2FsbGJhY2t9IGluIHRoYXQgaXQgaXMgYW4gYWN0dWFsIGNhbGxiYWNrIG9mIGEgc2VydmljZSBtZXRob2Qgd2hpY2ggbWF5IG5vdCByZXR1cm4gYHJlc3BvbnNlID0gbnVsbGAuXG4gKiBAdHlwZWRlZiBycGMuU2VydmljZU1ldGhvZENhbGxiYWNrXG4gKiBAdGVtcGxhdGUgVFJlcyBleHRlbmRzIE1lc3NhZ2U8VFJlcz5cbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEBwYXJhbSB7RXJyb3J8bnVsbH0gZXJyb3IgRXJyb3IsIGlmIGFueVxuICogQHBhcmFtIHtUUmVzfSBbcmVzcG9uc2VdIFJlc3BvbnNlIG1lc3NhZ2VcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gKi9cblxuLyoqXG4gKiBBIHNlcnZpY2UgbWV0aG9kIHBhcnQgb2YgYSB7QGxpbmsgcnBjLlNlcnZpY2V9IGFzIGNyZWF0ZWQgYnkge0BsaW5rIFNlcnZpY2UuY3JlYXRlfS5cbiAqIEB0eXBlZGVmIHJwYy5TZXJ2aWNlTWV0aG9kXG4gKiBAdGVtcGxhdGUgVFJlcSBleHRlbmRzIE1lc3NhZ2U8VFJlcT5cbiAqIEB0ZW1wbGF0ZSBUUmVzIGV4dGVuZHMgTWVzc2FnZTxUUmVzPlxuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHBhcmFtIHtUUmVxfFByb3BlcnRpZXM8VFJlcT59IHJlcXVlc3QgUmVxdWVzdCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdFxuICogQHBhcmFtIHtycGMuU2VydmljZU1ldGhvZENhbGxiYWNrPFRSZXM+fSBbY2FsbGJhY2tdIE5vZGUtc3R5bGUgY2FsbGJhY2sgY2FsbGVkIHdpdGggdGhlIGVycm9yLCBpZiBhbnksIGFuZCB0aGUgcmVzcG9uc2UgbWVzc2FnZVxuICogQHJldHVybnMge1Byb21pc2U8TWVzc2FnZTxUUmVzPj59IFByb21pc2UgaWYgYGNhbGxiYWNrYCBoYXMgYmVlbiBvbWl0dGVkLCBvdGhlcndpc2UgYHVuZGVmaW5lZGBcbiAqL1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgUlBDIHNlcnZpY2UgaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIEFuIFJQQyBzZXJ2aWNlIGFzIHJldHVybmVkIGJ5IHtAbGluayBTZXJ2aWNlI2NyZWF0ZX0uXG4gKiBAZXhwb3J0cyBycGMuU2VydmljZVxuICogQGV4dGVuZHMgdXRpbC5FdmVudEVtaXR0ZXJcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtSUENJbXBsfSBycGNJbXBsIFJQQyBpbXBsZW1lbnRhdGlvblxuICogQHBhcmFtIHtib29sZWFufSBbcmVxdWVzdERlbGltaXRlZD1mYWxzZV0gV2hldGhlciByZXF1ZXN0cyBhcmUgbGVuZ3RoLWRlbGltaXRlZFxuICogQHBhcmFtIHtib29sZWFufSBbcmVzcG9uc2VEZWxpbWl0ZWQ9ZmFsc2VdIFdoZXRoZXIgcmVzcG9uc2VzIGFyZSBsZW5ndGgtZGVsaW1pdGVkXG4gKi9cbmZ1bmN0aW9uIFNlcnZpY2UocnBjSW1wbCwgcmVxdWVzdERlbGltaXRlZCwgcmVzcG9uc2VEZWxpbWl0ZWQpIHtcblxuICAgIGlmICh0eXBlb2YgcnBjSW1wbCAhPT0gXCJmdW5jdGlvblwiKVxuICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJycGNJbXBsIG11c3QgYmUgYSBmdW5jdGlvblwiKTtcblxuICAgIHV0aWwuRXZlbnRFbWl0dGVyLmNhbGwodGhpcyk7XG5cbiAgICAvKipcbiAgICAgKiBSUEMgaW1wbGVtZW50YXRpb24uIEJlY29tZXMgYG51bGxgIG9uY2UgdGhlIHNlcnZpY2UgaXMgZW5kZWQuXG4gICAgICogQHR5cGUge1JQQ0ltcGx8bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLnJwY0ltcGwgPSBycGNJbXBsO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciByZXF1ZXN0cyBhcmUgbGVuZ3RoLWRlbGltaXRlZC5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICB0aGlzLnJlcXVlc3REZWxpbWl0ZWQgPSBCb29sZWFuKHJlcXVlc3REZWxpbWl0ZWQpO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciByZXNwb25zZXMgYXJlIGxlbmd0aC1kZWxpbWl0ZWQuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5yZXNwb25zZURlbGltaXRlZCA9IEJvb2xlYW4ocmVzcG9uc2VEZWxpbWl0ZWQpO1xufVxuXG4vKipcbiAqIENhbGxzIGEgc2VydmljZSBtZXRob2QgdGhyb3VnaCB7QGxpbmsgcnBjLlNlcnZpY2UjcnBjSW1wbHxycGNJbXBsfS5cbiAqIEBwYXJhbSB7TWV0aG9kfHJwYy5TZXJ2aWNlTWV0aG9kPFRSZXEsVFJlcz59IG1ldGhvZCBSZWZsZWN0ZWQgb3Igc3RhdGljIG1ldGhvZFxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxUUmVxPn0gcmVxdWVzdEN0b3IgUmVxdWVzdCBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxUUmVzPn0gcmVzcG9uc2VDdG9yIFJlc3BvbnNlIGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge1RSZXF8UHJvcGVydGllczxUUmVxPn0gcmVxdWVzdCBSZXF1ZXN0IG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0XG4gKiBAcGFyYW0ge3JwYy5TZXJ2aWNlTWV0aG9kQ2FsbGJhY2s8VFJlcz59IGNhbGxiYWNrIFNlcnZpY2UgY2FsbGJhY2tcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gKiBAdGVtcGxhdGUgVFJlcSBleHRlbmRzIE1lc3NhZ2U8VFJlcT5cbiAqIEB0ZW1wbGF0ZSBUUmVzIGV4dGVuZHMgTWVzc2FnZTxUUmVzPlxuICovXG5TZXJ2aWNlLnByb3RvdHlwZS5ycGNDYWxsID0gZnVuY3Rpb24gcnBjQ2FsbChtZXRob2QsIHJlcXVlc3RDdG9yLCByZXNwb25zZUN0b3IsIHJlcXVlc3QsIGNhbGxiYWNrKSB7XG5cbiAgICBpZiAoIXJlcXVlc3QpXG4gICAgICAgIHRocm93IFR5cGVFcnJvcihcInJlcXVlc3QgbXVzdCBiZSBzcGVjaWZpZWRcIik7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgaWYgKCFjYWxsYmFjaylcbiAgICAgICAgcmV0dXJuIHV0aWwuYXNQcm9taXNlKHJwY0NhbGwsIHNlbGYsIG1ldGhvZCwgcmVxdWVzdEN0b3IsIHJlc3BvbnNlQ3RvciwgcmVxdWVzdCk7XG5cbiAgICBpZiAoIXNlbGYucnBjSW1wbCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBjYWxsYmFjayhFcnJvcihcImFscmVhZHkgZW5kZWRcIikpOyB9LCAwKTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gc2VsZi5ycGNJbXBsKFxuICAgICAgICAgICAgbWV0aG9kLFxuICAgICAgICAgICAgcmVxdWVzdEN0b3Jbc2VsZi5yZXF1ZXN0RGVsaW1pdGVkID8gXCJlbmNvZGVEZWxpbWl0ZWRcIiA6IFwiZW5jb2RlXCJdKHJlcXVlc3QpLmZpbmlzaCgpLFxuICAgICAgICAgICAgZnVuY3Rpb24gcnBjQ2FsbGJhY2soZXJyLCByZXNwb25zZSkge1xuXG4gICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmVtaXQoXCJlcnJvclwiLCBlcnIsIG1ldGhvZCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmVuZCgvKiBlbmRlZEJ5UlBDICovIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghKHJlc3BvbnNlIGluc3RhbmNlb2YgcmVzcG9uc2VDdG9yKSkge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSByZXNwb25zZUN0b3Jbc2VsZi5yZXNwb25zZURlbGltaXRlZCA/IFwiZGVjb2RlRGVsaW1pdGVkXCIgOiBcImRlY29kZVwiXShyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0KFwiZXJyb3JcIiwgZXJyLCBtZXRob2QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBzZWxmLmVtaXQoXCJkYXRhXCIsIHJlc3BvbnNlLCBtZXRob2QpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCByZXNwb25zZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHNlbGYuZW1pdChcImVycm9yXCIsIGVyciwgbWV0aG9kKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsgY2FsbGJhY2soZXJyKTsgfSwgMCk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxufTtcblxuLyoqXG4gKiBFbmRzIHRoaXMgc2VydmljZSBhbmQgZW1pdHMgdGhlIGBlbmRgIGV2ZW50LlxuICogQHBhcmFtIHtib29sZWFufSBbZW5kZWRCeVJQQz1mYWxzZV0gV2hldGhlciB0aGUgc2VydmljZSBoYXMgYmVlbiBlbmRlZCBieSB0aGUgUlBDIGltcGxlbWVudGF0aW9uLlxuICogQHJldHVybnMge3JwYy5TZXJ2aWNlfSBgdGhpc2BcbiAqL1xuU2VydmljZS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gZW5kKGVuZGVkQnlSUEMpIHtcbiAgICBpZiAodGhpcy5ycGNJbXBsKSB7XG4gICAgICAgIGlmICghZW5kZWRCeVJQQykgLy8gc2lnbmFsIGVuZCB0byBycGNJbXBsXG4gICAgICAgICAgICB0aGlzLnJwY0ltcGwobnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgICAgIHRoaXMucnBjSW1wbCA9IG51bGw7XG4gICAgICAgIHRoaXMuZW1pdChcImVuZFwiKS5vZmYoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuIiwgIlwidXNlIHN0cmljdFwiO1xuXG4vKipcbiAqIFN0cmVhbWluZyBSUEMgaGVscGVycy5cbiAqIEBuYW1lc3BhY2VcbiAqL1xudmFyIHJwYyA9IGV4cG9ydHM7XG5cbi8qKlxuICogUlBDIGltcGxlbWVudGF0aW9uIHBhc3NlZCB0byB7QGxpbmsgU2VydmljZSNjcmVhdGV9IHBlcmZvcm1pbmcgYSBzZXJ2aWNlIHJlcXVlc3Qgb24gbmV0d29yayBsZXZlbCwgaS5lLiBieSB1dGlsaXppbmcgaHR0cCByZXF1ZXN0cyBvciB3ZWJzb2NrZXRzLlxuICogQHR5cGVkZWYgUlBDSW1wbFxuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHBhcmFtIHtNZXRob2R8cnBjLlNlcnZpY2VNZXRob2Q8TWVzc2FnZTx7fT4sTWVzc2FnZTx7fT4+fSBtZXRob2QgUmVmbGVjdGVkIG9yIHN0YXRpYyBtZXRob2QgYmVpbmcgY2FsbGVkXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHJlcXVlc3REYXRhIFJlcXVlc3QgZGF0YVxuICogQHBhcmFtIHtSUENJbXBsQ2FsbGJhY2t9IGNhbGxiYWNrIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICogQGV4YW1wbGVcbiAqIGZ1bmN0aW9uIHJwY0ltcGwobWV0aG9kLCByZXF1ZXN0RGF0YSwgY2FsbGJhY2spIHtcbiAqICAgICBpZiAocHJvdG9idWYudXRpbC5sY0ZpcnN0KG1ldGhvZC5uYW1lKSAhPT0gXCJteU1ldGhvZFwiKSAvLyBjb21wYXRpYmxlIHdpdGggc3RhdGljIGNvZGVcbiAqICAgICAgICAgdGhyb3cgRXJyb3IoXCJubyBzdWNoIG1ldGhvZFwiKTtcbiAqICAgICBhc3luY2hyb25vdXNseU9idGFpbkFSZXNwb25zZShyZXF1ZXN0RGF0YSwgZnVuY3Rpb24oZXJyLCByZXNwb25zZURhdGEpIHtcbiAqICAgICAgICAgY2FsbGJhY2soZXJyLCByZXNwb25zZURhdGEpO1xuICogICAgIH0pO1xuICogfVxuICovXG5cbi8qKlxuICogTm9kZS1zdHlsZSBjYWxsYmFjayBhcyB1c2VkIGJ5IHtAbGluayBSUENJbXBsfS5cbiAqIEB0eXBlZGVmIFJQQ0ltcGxDYWxsYmFja1xuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHBhcmFtIHtFcnJvcnxudWxsfSBlcnJvciBFcnJvciwgaWYgYW55LCBvdGhlcndpc2UgYG51bGxgXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl8bnVsbH0gW3Jlc3BvbnNlXSBSZXNwb25zZSBkYXRhIG9yIGBudWxsYCB0byBzaWduYWwgZW5kIG9mIHN0cmVhbSwgaWYgdGhlcmUgaGFzbid0IGJlZW4gYW4gZXJyb3JcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gKi9cblxucnBjLlNlcnZpY2UgPSByZXF1aXJlKFwiLi9ycGMvc2VydmljZVwiKTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0ge307XG5cbi8qKlxuICogTmFtZWQgcm9vdHMuXG4gKiBUaGlzIGlzIHdoZXJlIHBianMgc3RvcmVzIGdlbmVyYXRlZCBzdHJ1Y3R1cmVzICh0aGUgb3B0aW9uIGAtciwgLS1yb290YCBzcGVjaWZpZXMgYSBuYW1lKS5cbiAqIENhbiBhbHNvIGJlIHVzZWQgbWFudWFsbHkgdG8gbWFrZSByb290cyBhdmFpbGFibGUgYWNyb3NzIG1vZHVsZXMuXG4gKiBAbmFtZSByb290c1xuICogQHR5cGUge09iamVjdC48c3RyaW5nLFJvb3Q+fVxuICogQGV4YW1wbGVcbiAqIC8vIHBianMgLXIgbXlyb290IC1vIGNvbXBpbGVkLmpzIC4uLlxuICpcbiAqIC8vIGluIGFub3RoZXIgbW9kdWxlOlxuICogcmVxdWlyZShcIi4vY29tcGlsZWQuanNcIik7XG4gKlxuICogLy8gaW4gYW55IHN1YnNlcXVlbnQgbW9kdWxlOlxuICogdmFyIHJvb3QgPSBwcm90b2J1Zi5yb290c1tcIm15cm9vdFwiXTtcbiAqL1xuIiwgIlwidXNlIHN0cmljdFwiO1xudmFyIHByb3RvYnVmID0gZXhwb3J0cztcblxuLyoqXG4gKiBCdWlsZCB0eXBlLCBvbmUgb2YgYFwiZnVsbFwiYCwgYFwibGlnaHRcImAgb3IgYFwibWluaW1hbFwiYC5cbiAqIEBuYW1lIGJ1aWxkXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGNvbnN0XG4gKi9cbnByb3RvYnVmLmJ1aWxkID0gXCJtaW5pbWFsXCI7XG5cbi8vIFNlcmlhbGl6YXRpb25cbnByb3RvYnVmLldyaXRlciAgICAgICA9IHJlcXVpcmUoXCIuL3dyaXRlclwiKTtcbnByb3RvYnVmLkJ1ZmZlcldyaXRlciA9IHJlcXVpcmUoXCIuL3dyaXRlcl9idWZmZXJcIik7XG5wcm90b2J1Zi5SZWFkZXIgICAgICAgPSByZXF1aXJlKFwiLi9yZWFkZXJcIik7XG5wcm90b2J1Zi5CdWZmZXJSZWFkZXIgPSByZXF1aXJlKFwiLi9yZWFkZXJfYnVmZmVyXCIpO1xuXG4vLyBVdGlsaXR5XG5wcm90b2J1Zi51dGlsICAgICAgICAgPSByZXF1aXJlKFwiLi91dGlsL21pbmltYWxcIik7XG5wcm90b2J1Zi5ycGMgICAgICAgICAgPSByZXF1aXJlKFwiLi9ycGNcIik7XG5wcm90b2J1Zi5yb290cyAgICAgICAgPSByZXF1aXJlKFwiLi9yb290c1wiKTtcbnByb3RvYnVmLmNvbmZpZ3VyZSAgICA9IGNvbmZpZ3VyZTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbi8qKlxuICogUmVjb25maWd1cmVzIHRoZSBsaWJyYXJ5IGFjY29yZGluZyB0byB0aGUgZW52aXJvbm1lbnQuXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBjb25maWd1cmUoKSB7XG4gICAgcHJvdG9idWYudXRpbC5fY29uZmlndXJlKCk7XG4gICAgcHJvdG9idWYuV3JpdGVyLl9jb25maWd1cmUocHJvdG9idWYuQnVmZmVyV3JpdGVyKTtcbiAgICBwcm90b2J1Zi5SZWFkZXIuX2NvbmZpZ3VyZShwcm90b2J1Zi5CdWZmZXJSZWFkZXIpO1xufVxuXG4vLyBTZXQgdXAgYnVmZmVyIHV0aWxpdHkgYWNjb3JkaW5nIHRvIHRoZSBlbnZpcm9ubWVudFxuY29uZmlndXJlKCk7XG4iLCAiLy8gbWluaW1hbCBsaWJyYXJ5IGVudHJ5IHBvaW50LlxuXG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vc3JjL2luZGV4LW1pbmltYWxcIik7XG4iLCAiLyplc2xpbnQtZGlzYWJsZSBibG9jay1zY29wZWQtdmFyLCBpZC1sZW5ndGgsIG5vLWNvbnRyb2wtcmVnZXgsIG5vLW1hZ2ljLW51bWJlcnMsIG5vLXByb3RvdHlwZS1idWlsdGlucywgbm8tcmVkZWNsYXJlLCBuby1zaGFkb3csIG5vLXZhciwgc29ydC12YXJzKi9cbid1c2Ugc3RyaWN0JztcblxudmFyICRwcm90b2J1ZiA9IHJlcXVpcmUoJ3Byb3RvYnVmanMvbWluaW1hbCcpO1xuXG4vLyBDb21tb24gYWxpYXNlc1xudmFyICRSZWFkZXIgPSAkcHJvdG9idWYuUmVhZGVyLFxuICAkV3JpdGVyID0gJHByb3RvYnVmLldyaXRlcixcbiAgJHV0aWwgPSAkcHJvdG9idWYudXRpbDtcblxuLy8gRXhwb3J0ZWQgcm9vdCBuYW1lc3BhY2VcbnZhciAkcm9vdCA9ICRwcm90b2J1Zi5yb290c1snZGVmYXVsdCddIHx8ICgkcHJvdG9idWYucm9vdHNbJ2RlZmF1bHQnXSA9IHt9KTtcblxuJHJvb3Qub25ueCA9IChmdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBOYW1lc3BhY2Ugb25ueC5cbiAgICogQGV4cG9ydHMgb25ueFxuICAgKiBAbmFtZXNwYWNlXG4gICAqL1xuICB2YXIgb25ueCA9IHt9O1xuXG4gIC8qKlxuICAgKiBWZXJzaW9uIGVudW0uXG4gICAqIEBuYW1lIG9ubnguVmVyc2lvblxuICAgKiBAZW51bSB7bnVtYmVyfVxuICAgKiBAcHJvcGVydHkge251bWJlcn0gX1NUQVJUX1ZFUlNJT049MCBfU1RBUlRfVkVSU0lPTiB2YWx1ZVxuICAgKiBAcHJvcGVydHkge251bWJlcn0gSVJfVkVSU0lPTl8yMDE3XzEwXzEwPTEgSVJfVkVSU0lPTl8yMDE3XzEwXzEwIHZhbHVlXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OXzIwMTdfMTBfMzA9MiBJUl9WRVJTSU9OXzIwMTdfMTBfMzAgdmFsdWVcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAxN18xMV8zPTMgSVJfVkVSU0lPTl8yMDE3XzExXzMgdmFsdWVcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAxOV8xXzIyPTQgSVJfVkVSU0lPTl8yMDE5XzFfMjIgdmFsdWVcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAxOV8zXzE4PTUgSVJfVkVSU0lPTl8yMDE5XzNfMTggdmFsdWVcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAxOV85XzE5PTYgSVJfVkVSU0lPTl8yMDE5XzlfMTkgdmFsdWVcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAyMF81Xzg9NyBJUl9WRVJTSU9OXzIwMjBfNV84IHZhbHVlXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OXzIwMjFfN18zMD04IElSX1ZFUlNJT05fMjAyMV83XzMwIHZhbHVlXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OPTkgSVJfVkVSU0lPTiB2YWx1ZVxuICAgKi9cbiAgb25ueC5WZXJzaW9uID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWVzQnlJZCA9IHt9LFxuICAgICAgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMF0gPSAnX1NUQVJUX1ZFUlNJT04nKV0gPSAwO1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxXSA9ICdJUl9WRVJTSU9OXzIwMTdfMTBfMTAnKV0gPSAxO1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFsyXSA9ICdJUl9WRVJTSU9OXzIwMTdfMTBfMzAnKV0gPSAyO1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFszXSA9ICdJUl9WRVJTSU9OXzIwMTdfMTFfMycpXSA9IDM7XG4gICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzRdID0gJ0lSX1ZFUlNJT05fMjAxOV8xXzIyJyldID0gNDtcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbNV0gPSAnSVJfVkVSU0lPTl8yMDE5XzNfMTgnKV0gPSA1O1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFs2XSA9ICdJUl9WRVJTSU9OXzIwMTlfOV8xOScpXSA9IDY7XG4gICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzddID0gJ0lSX1ZFUlNJT05fMjAyMF81XzgnKV0gPSA3O1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFs4XSA9ICdJUl9WRVJTSU9OXzIwMjFfN18zMCcpXSA9IDg7XG4gICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzldID0gJ0lSX1ZFUlNJT04nKV0gPSA5O1xuICAgIHJldHVybiB2YWx1ZXM7XG4gIH0pKCk7XG5cbiAgb25ueC5BdHRyaWJ1dGVQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhbiBBdHRyaWJ1dGVQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSUF0dHJpYnV0ZVByb3RvXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW25hbWVdIEF0dHJpYnV0ZVByb3RvIG5hbWVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbcmVmQXR0ck5hbWVdIEF0dHJpYnV0ZVByb3RvIHJlZkF0dHJOYW1lXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvY1N0cmluZ10gQXR0cmlidXRlUHJvdG8gZG9jU3RyaW5nXG4gICAgICogQHByb3BlcnR5IHtvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGV8bnVsbH0gW3R5cGVdIEF0dHJpYnV0ZVByb3RvIHR5cGVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcnxudWxsfSBbZl0gQXR0cmlidXRlUHJvdG8gZlxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfExvbmd8bnVsbH0gW2ldIEF0dHJpYnV0ZVByb3RvIGlcbiAgICAgKiBAcHJvcGVydHkge1VpbnQ4QXJyYXl8bnVsbH0gW3NdIEF0dHJpYnV0ZVByb3RvIHNcbiAgICAgKiBAcHJvcGVydHkge29ubnguSVRlbnNvclByb3RvfG51bGx9IFt0XSBBdHRyaWJ1dGVQcm90byB0XG4gICAgICogQHByb3BlcnR5IHtvbm54LklHcmFwaFByb3RvfG51bGx9IFtnXSBBdHRyaWJ1dGVQcm90byBnXG4gICAgICogQHByb3BlcnR5IHtvbm54LklTcGFyc2VUZW5zb3JQcm90b3xudWxsfSBbc3BhcnNlVGVuc29yXSBBdHRyaWJ1dGVQcm90byBzcGFyc2VUZW5zb3JcbiAgICAgKiBAcHJvcGVydHkge29ubnguSVR5cGVQcm90b3xudWxsfSBbdHBdIEF0dHJpYnV0ZVByb3RvIHRwXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyPnxudWxsfSBbZmxvYXRzXSBBdHRyaWJ1dGVQcm90byBmbG9hdHNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXJ8TG9uZz58bnVsbH0gW2ludHNdIEF0dHJpYnV0ZVByb3RvIGludHNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxVaW50OEFycmF5PnxudWxsfSBbc3RyaW5nc10gQXR0cmlidXRlUHJvdG8gc3RyaW5nc1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVRlbnNvclByb3RvPnxudWxsfSBbdGVuc29yc10gQXR0cmlidXRlUHJvdG8gdGVuc29yc1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSUdyYXBoUHJvdG8+fG51bGx9IFtncmFwaHNdIEF0dHJpYnV0ZVByb3RvIGdyYXBoc1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVNwYXJzZVRlbnNvclByb3RvPnxudWxsfSBbc3BhcnNlVGVuc29yc10gQXR0cmlidXRlUHJvdG8gc3BhcnNlVGVuc29yc1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVR5cGVQcm90bz58bnVsbH0gW3R5cGVQcm90b3NdIEF0dHJpYnV0ZVByb3RvIHR5cGVQcm90b3NcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgQXR0cmlidXRlUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYW4gQXR0cmlidXRlUHJvdG8uXG4gICAgICogQGltcGxlbWVudHMgSUF0dHJpYnV0ZVByb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklBdHRyaWJ1dGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEF0dHJpYnV0ZVByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgIHRoaXMuZmxvYXRzID0gW107XG4gICAgICB0aGlzLmludHMgPSBbXTtcbiAgICAgIHRoaXMuc3RyaW5ncyA9IFtdO1xuICAgICAgdGhpcy50ZW5zb3JzID0gW107XG4gICAgICB0aGlzLmdyYXBocyA9IFtdO1xuICAgICAgdGhpcy5zcGFyc2VUZW5zb3JzID0gW107XG4gICAgICB0aGlzLnR5cGVQcm90b3MgPSBbXTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byBuYW1lLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLm5hbWUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIHJlZkF0dHJOYW1lLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gcmVmQXR0ck5hbWVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5yZWZBdHRyTmFtZSA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gZG9jU3RyaW5nLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9jU3RyaW5nXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuZG9jU3RyaW5nID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byB0eXBlLlxuICAgICAqIEBtZW1iZXIge29ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZX0gdHlwZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnR5cGUgPSAwO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gZi5cbiAgICAgKiBAbWVtYmVyIHtudW1iZXJ9IGZcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5mID0gMDtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIGkuXG4gICAgICogQG1lbWJlciB7bnVtYmVyfExvbmd9IGlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5pID0gJHV0aWwuTG9uZyA/ICR1dGlsLkxvbmcuZnJvbUJpdHMoMCwgMCwgZmFsc2UpIDogMDtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIHMuXG4gICAgICogQG1lbWJlciB7VWludDhBcnJheX0gc1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnMgPSAkdXRpbC5uZXdCdWZmZXIoW10pO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gdC5cbiAgICAgKiBAbWVtYmVyIHtvbm54LklUZW5zb3JQcm90b3xudWxsfHVuZGVmaW5lZH0gdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnQgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gZy5cbiAgICAgKiBAbWVtYmVyIHtvbm54LklHcmFwaFByb3RvfG51bGx8dW5kZWZpbmVkfSBnXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuZyA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byBzcGFyc2VUZW5zb3IuXG4gICAgICogQG1lbWJlciB7b25ueC5JU3BhcnNlVGVuc29yUHJvdG98bnVsbHx1bmRlZmluZWR9IHNwYXJzZVRlbnNvclxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnNwYXJzZVRlbnNvciA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byB0cC5cbiAgICAgKiBAbWVtYmVyIHtvbm54LklUeXBlUHJvdG98bnVsbHx1bmRlZmluZWR9IHRwXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUudHAgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gZmxvYXRzLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXI+fSBmbG9hdHNcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5mbG9hdHMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gaW50cy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyfExvbmc+fSBpbnRzXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuaW50cyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byBzdHJpbmdzLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxVaW50OEFycmF5Pn0gc3RyaW5nc1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnN0cmluZ3MgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gdGVuc29ycy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVGVuc29yUHJvdG8+fSB0ZW5zb3JzXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUudGVuc29ycyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byBncmFwaHMuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSUdyYXBoUHJvdG8+fSBncmFwaHNcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5ncmFwaHMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gc3BhcnNlVGVuc29ycy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JU3BhcnNlVGVuc29yUHJvdG8+fSBzcGFyc2VUZW5zb3JzXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuc3BhcnNlVGVuc29ycyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byB0eXBlUHJvdG9zLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklUeXBlUHJvdG8+fSB0eXBlUHJvdG9zXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUudHlwZVByb3RvcyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IEF0dHJpYnV0ZVByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklBdHRyaWJ1dGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54LkF0dHJpYnV0ZVByb3RvfSBBdHRyaWJ1dGVQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZVByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgQXR0cmlidXRlUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5BdHRyaWJ1dGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklBdHRyaWJ1dGVQcm90b30gbWVzc2FnZSBBdHRyaWJ1dGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ25hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuc3RyaW5nKG1lc3NhZ2UubmFtZSk7XG4gICAgICBpZiAobWVzc2FnZS5mICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2YnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSA1ID0qLyAyMSkuZmxvYXQobWVzc2FnZS5mKTtcbiAgICAgIGlmIChtZXNzYWdlLmkgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnaScpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDAgPSovIDI0KS5pbnQ2NChtZXNzYWdlLmkpO1xuICAgICAgaWYgKG1lc3NhZ2UucyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdzJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNCwgd2lyZVR5cGUgMiA9Ki8gMzQpLmJ5dGVzKG1lc3NhZ2Uucyk7XG4gICAgICBpZiAobWVzc2FnZS50ICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3QnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JQcm90by5lbmNvZGUobWVzc2FnZS50LCB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDIgPSovIDQyKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdnJykpXG4gICAgICAgICRyb290Lm9ubnguR3JhcGhQcm90by5lbmNvZGUobWVzc2FnZS5nLCB3cml0ZXIudWludDMyKC8qIGlkIDYsIHdpcmVUeXBlIDIgPSovIDUwKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZmxvYXRzICE9IG51bGwgJiYgbWVzc2FnZS5mbG9hdHMubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNywgd2lyZVR5cGUgMiA9Ki8gNTgpLmZvcmsoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmZsb2F0cy5sZW5ndGg7ICsraSkgd3JpdGVyLmZsb2F0KG1lc3NhZ2UuZmxvYXRzW2ldKTtcbiAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaW50cyAhPSBudWxsICYmIG1lc3NhZ2UuaW50cy5sZW5ndGgpIHtcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA4LCB3aXJlVHlwZSAyID0qLyA2NikuZm9yaygpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW50cy5sZW5ndGg7ICsraSkgd3JpdGVyLmludDY0KG1lc3NhZ2UuaW50c1tpXSk7XG4gICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnN0cmluZ3MgIT0gbnVsbCAmJiBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uuc3RyaW5ncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDksIHdpcmVUeXBlIDIgPSovIDc0KS5ieXRlcyhtZXNzYWdlLnN0cmluZ3NbaV0pO1xuICAgICAgaWYgKG1lc3NhZ2UudGVuc29ycyAhPSBudWxsICYmIG1lc3NhZ2UudGVuc29ycy5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS50ZW5zb3JzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguVGVuc29yUHJvdG8uZW5jb2RlKG1lc3NhZ2UudGVuc29yc1tpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxMCwgd2lyZVR5cGUgMiA9Ki8gODIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5ncmFwaHMgIT0gbnVsbCAmJiBtZXNzYWdlLmdyYXBocy5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5ncmFwaHMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5HcmFwaFByb3RvLmVuY29kZShtZXNzYWdlLmdyYXBoc1tpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxMSwgd2lyZVR5cGUgMiA9Ki8gOTApLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZG9jU3RyaW5nJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTMsIHdpcmVUeXBlIDIgPSovIDEwNikuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgIGlmIChtZXNzYWdlLnRwICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3RwJykpXG4gICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLmVuY29kZShtZXNzYWdlLnRwLCB3cml0ZXIudWludDMyKC8qIGlkIDE0LCB3aXJlVHlwZSAyID0qLyAxMTQpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS50eXBlUHJvdG9zICE9IG51bGwgJiYgbWVzc2FnZS50eXBlUHJvdG9zLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnR5cGVQcm90b3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS50eXBlUHJvdG9zW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxNSwgd2lyZVR5cGUgMiA9Ki8gMTIyKS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLnR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAndHlwZScpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIwLCB3aXJlVHlwZSAwID0qLyAxNjApLmludDMyKG1lc3NhZ2UudHlwZSk7XG4gICAgICBpZiAobWVzc2FnZS5yZWZBdHRyTmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdyZWZBdHRyTmFtZScpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIxLCB3aXJlVHlwZSAyID0qLyAxNzApLnN0cmluZyhtZXNzYWdlLnJlZkF0dHJOYW1lKTtcbiAgICAgIGlmIChtZXNzYWdlLnNwYXJzZVRlbnNvciAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdzcGFyc2VUZW5zb3InKSlcbiAgICAgICAgJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5lbmNvZGUoXG4gICAgICAgICAgbWVzc2FnZS5zcGFyc2VUZW5zb3IsXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyMiwgd2lyZVR5cGUgMiA9Ki8gMTc4KS5mb3JrKCksXG4gICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VUZW5zb3JzICE9IG51bGwgJiYgbWVzc2FnZS5zcGFyc2VUZW5zb3JzLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnNwYXJzZVRlbnNvcnMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvcnNbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIzLCB3aXJlVHlwZSAyID0qLyAxODYpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguQXR0cmlidXRlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JQXR0cmlidXRlUHJvdG99IG1lc3NhZ2UgQXR0cmlidXRlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGFuIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguQXR0cmlidXRlUHJvdG99IEF0dHJpYnV0ZVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDIxOiB7XG4gICAgICAgICAgICBtZXNzYWdlLnJlZkF0dHJOYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTM6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjA6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS5mID0gcmVhZGVyLmZsb2F0KCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAzOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmkgPSByZWFkZXIuaW50NjQoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDQ6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UucyA9IHJlYWRlci5ieXRlcygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgbWVzc2FnZS50ID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNjoge1xuICAgICAgICAgICAgbWVzc2FnZS5nID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAyMjoge1xuICAgICAgICAgICAgbWVzc2FnZS5zcGFyc2VUZW5zb3IgPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxNDoge1xuICAgICAgICAgICAgbWVzc2FnZS50cCA9ICRyb290Lm9ubnguVHlwZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA3OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmZsb2F0cyAmJiBtZXNzYWdlLmZsb2F0cy5sZW5ndGgpKSBtZXNzYWdlLmZsb2F0cyA9IFtdO1xuICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMikgbWVzc2FnZS5mbG9hdHMucHVzaChyZWFkZXIuZmxvYXQoKSk7XG4gICAgICAgICAgICB9IGVsc2UgbWVzc2FnZS5mbG9hdHMucHVzaChyZWFkZXIuZmxvYXQoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA4OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmludHMgJiYgbWVzc2FnZS5pbnRzLmxlbmd0aCkpIG1lc3NhZ2UuaW50cyA9IFtdO1xuICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMikgbWVzc2FnZS5pbnRzLnB1c2gocmVhZGVyLmludDY0KCkpO1xuICAgICAgICAgICAgfSBlbHNlIG1lc3NhZ2UuaW50cy5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDk6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uuc3RyaW5ncyAmJiBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoKSkgbWVzc2FnZS5zdHJpbmdzID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnN0cmluZ3MucHVzaChyZWFkZXIuYnl0ZXMoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMDoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS50ZW5zb3JzICYmIG1lc3NhZ2UudGVuc29ycy5sZW5ndGgpKSBtZXNzYWdlLnRlbnNvcnMgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UudGVuc29ycy5wdXNoKCRyb290Lm9ubnguVGVuc29yUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5ncmFwaHMgJiYgbWVzc2FnZS5ncmFwaHMubGVuZ3RoKSkgbWVzc2FnZS5ncmFwaHMgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuZ3JhcGhzLnB1c2goJHJvb3Qub25ueC5HcmFwaFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjM6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uuc3BhcnNlVGVuc29ycyAmJiBtZXNzYWdlLnNwYXJzZVRlbnNvcnMubGVuZ3RoKSkgbWVzc2FnZS5zcGFyc2VUZW5zb3JzID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvcnMucHVzaCgkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTU6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UudHlwZVByb3RvcyAmJiBtZXNzYWdlLnR5cGVQcm90b3MubGVuZ3RoKSkgbWVzc2FnZS50eXBlUHJvdG9zID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnR5cGVQcm90b3MucHVzaCgkcm9vdC5vbm54LlR5cGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGFuIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LkF0dHJpYnV0ZVByb3RvfSBBdHRyaWJ1dGVQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhbiBBdHRyaWJ1dGVQcm90byBtZXNzYWdlLlxuICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCduYW1lJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5uYW1lKSkgcmV0dXJuICduYW1lOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UucmVmQXR0ck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdyZWZBdHRyTmFtZScpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UucmVmQXR0ck5hbWUpKSByZXR1cm4gJ3JlZkF0dHJOYW1lOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpKSByZXR1cm4gJ2RvY1N0cmluZzogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLnR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0eXBlJykpXG4gICAgICAgIHN3aXRjaCAobWVzc2FnZS50eXBlKSB7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiAndHlwZTogZW51bSB2YWx1ZSBleHBlY3RlZCc7XG4gICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgY2FzZSAxMTpcbiAgICAgICAgICBjYXNlIDEzOlxuICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgY2FzZSA4OlxuICAgICAgICAgIGNhc2UgOTpcbiAgICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgIGNhc2UgMTI6XG4gICAgICAgICAgY2FzZSAxNDpcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5mICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZicpKVxuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuZiAhPT0gJ251bWJlcicpIHJldHVybiAnZjogbnVtYmVyIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmkgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpJykpXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaSkgJiZcbiAgICAgICAgICAhKG1lc3NhZ2UuaSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaS5oaWdoKSlcbiAgICAgICAgKVxuICAgICAgICAgIHJldHVybiAnaTogaW50ZWdlcnxMb25nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLnMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzJykpXG4gICAgICAgIGlmICghKChtZXNzYWdlLnMgJiYgdHlwZW9mIG1lc3NhZ2Uucy5sZW5ndGggPT09ICdudW1iZXInKSB8fCAkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnMpKSlcbiAgICAgICAgICByZXR1cm4gJ3M6IGJ1ZmZlciBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS50ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndCcpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udmVyaWZ5KG1lc3NhZ2UudCk7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuICd0LicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdnJykpIHtcbiAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnZlcmlmeShtZXNzYWdlLmcpO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnZy4nICsgZXJyb3I7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VUZW5zb3IgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzcGFyc2VUZW5zb3InKSkge1xuICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLnZlcmlmeShtZXNzYWdlLnNwYXJzZVRlbnNvcik7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdzcGFyc2VUZW5zb3IuJyArIGVycm9yO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudHAgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0cCcpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLnZlcmlmeShtZXNzYWdlLnRwKTtcbiAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3RwLicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmZsb2F0cyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2Zsb2F0cycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmZsb2F0cykpIHJldHVybiAnZmxvYXRzOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5mbG9hdHMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmZsb2F0c1tpXSAhPT0gJ251bWJlcicpIHJldHVybiAnZmxvYXRzOiBudW1iZXJbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5pbnRzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaW50cycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmludHMpKSByZXR1cm4gJ2ludHM6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmludHMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludHNbaV0pICYmXG4gICAgICAgICAgICAhKG1lc3NhZ2UuaW50c1tpXSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pbnRzW2ldLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaW50c1tpXS5oaWdoKSlcbiAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gJ2ludHM6IGludGVnZXJ8TG9uZ1tdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnN0cmluZ3MgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzdHJpbmdzJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uuc3RyaW5ncykpIHJldHVybiAnc3RyaW5nczogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uuc3RyaW5ncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhKFxuICAgICAgICAgICAgICAobWVzc2FnZS5zdHJpbmdzW2ldICYmIHR5cGVvZiBtZXNzYWdlLnN0cmluZ3NbaV0ubGVuZ3RoID09PSAnbnVtYmVyJykgfHxcbiAgICAgICAgICAgICAgJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5zdHJpbmdzW2ldKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiAnc3RyaW5nczogYnVmZmVyW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudGVuc29ycyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3RlbnNvcnMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS50ZW5zb3JzKSkgcmV0dXJuICd0ZW5zb3JzOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS50ZW5zb3JzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS50ZW5zb3JzW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAndGVuc29ycy4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmdyYXBocyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2dyYXBocycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmdyYXBocykpIHJldHVybiAnZ3JhcGhzOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5ncmFwaHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udmVyaWZ5KG1lc3NhZ2UuZ3JhcGhzW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnZ3JhcGhzLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlVGVuc29ycyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NwYXJzZVRlbnNvcnMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5zcGFyc2VUZW5zb3JzKSkgcmV0dXJuICdzcGFyc2VUZW5zb3JzOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5zcGFyc2VUZW5zb3JzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS5zcGFyc2VUZW5zb3JzW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnc3BhcnNlVGVuc29ycy4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnR5cGVQcm90b3MgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0eXBlUHJvdG9zJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudHlwZVByb3RvcykpIHJldHVybiAndHlwZVByb3RvczogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudHlwZVByb3Rvcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLnZlcmlmeShtZXNzYWdlLnR5cGVQcm90b3NbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICd0eXBlUHJvdG9zLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gQXR0cmlidXRlUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54LkF0dHJpYnV0ZVByb3RvfSBBdHRyaWJ1dGVQcm90b1xuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvKCk7XG4gICAgICBpZiAob2JqZWN0Lm5hbWUgIT0gbnVsbCkgbWVzc2FnZS5uYW1lID0gU3RyaW5nKG9iamVjdC5uYW1lKTtcbiAgICAgIGlmIChvYmplY3QucmVmQXR0ck5hbWUgIT0gbnVsbCkgbWVzc2FnZS5yZWZBdHRyTmFtZSA9IFN0cmluZyhvYmplY3QucmVmQXR0ck5hbWUpO1xuICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbCkgbWVzc2FnZS5kb2NTdHJpbmcgPSBTdHJpbmcob2JqZWN0LmRvY1N0cmluZyk7XG4gICAgICBzd2l0Y2ggKG9iamVjdC50eXBlKSB7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IG9iamVjdC50eXBlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdVTkRFRklORUQnOlxuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gMDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnRkxPQVQnOlxuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnSU5UJzpcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1NUUklORyc6XG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAzO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdURU5TT1InOlxuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gNDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnR1JBUEgnOlxuICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gNTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnU1BBUlNFX1RFTlNPUic6XG4gICAgICAgIGNhc2UgMTE6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gMTE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1RZUEVfUFJPVE8nOlxuICAgICAgICBjYXNlIDEzOlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDEzO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdGTE9BVFMnOlxuICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gNjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnSU5UUyc6XG4gICAgICAgIGNhc2UgNzpcbiAgICAgICAgICBtZXNzYWdlLnR5cGUgPSA3O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdTVFJJTkdTJzpcbiAgICAgICAgY2FzZSA4OlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDg7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1RFTlNPUlMnOlxuICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gOTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnR1JBUEhTJzpcbiAgICAgICAgY2FzZSAxMDpcbiAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAxMDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnU1BBUlNFX1RFTlNPUlMnOlxuICAgICAgICBjYXNlIDEyOlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDEyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdUWVBFX1BST1RPUyc6XG4gICAgICAgIGNhc2UgMTQ6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gMTQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmYgIT0gbnVsbCkgbWVzc2FnZS5mID0gTnVtYmVyKG9iamVjdC5mKTtcbiAgICAgIGlmIChvYmplY3QuaSAhPSBudWxsKVxuICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuaSA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5pKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pID09PSAnc3RyaW5nJykgbWVzc2FnZS5pID0gcGFyc2VJbnQob2JqZWN0LmksIDEwKTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pID09PSAnbnVtYmVyJykgbWVzc2FnZS5pID0gb2JqZWN0Lmk7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgbWVzc2FnZS5pID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC5pLmxvdyA+Pj4gMCwgb2JqZWN0LmkuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgIGlmIChvYmplY3QucyAhPSBudWxsKVxuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zID09PSAnc3RyaW5nJylcbiAgICAgICAgICAkdXRpbC5iYXNlNjQuZGVjb2RlKG9iamVjdC5zLCAobWVzc2FnZS5zID0gJHV0aWwubmV3QnVmZmVyKCR1dGlsLmJhc2U2NC5sZW5ndGgob2JqZWN0LnMpKSksIDApO1xuICAgICAgICBlbHNlIGlmIChvYmplY3Qucy5sZW5ndGggPj0gMCkgbWVzc2FnZS5zID0gb2JqZWN0LnM7XG4gICAgICBpZiAob2JqZWN0LnQgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC50ICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by50OiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS50ID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC50KTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZyAhPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmcgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLmc6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmcgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZyk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnNwYXJzZVRlbnNvciAhPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnNwYXJzZVRlbnNvciAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by5zcGFyc2VUZW5zb3I6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvciA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3Quc3BhcnNlVGVuc29yKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QudHAgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC50cCAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguQXR0cmlidXRlUHJvdG8udHA6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnRwID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZnJvbU9iamVjdChvYmplY3QudHApO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5mbG9hdHMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5mbG9hdHMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLmZsb2F0czogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5mbG9hdHMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZmxvYXRzLmxlbmd0aDsgKytpKSBtZXNzYWdlLmZsb2F0c1tpXSA9IE51bWJlcihvYmplY3QuZmxvYXRzW2ldKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuaW50cykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmludHMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLmludHM6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuaW50cyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbnRzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSAobWVzc2FnZS5pbnRzW2ldID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmludHNbaV0pKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaW50c1tpXSA9PT0gJ3N0cmluZycpIG1lc3NhZ2UuaW50c1tpXSA9IHBhcnNlSW50KG9iamVjdC5pbnRzW2ldLCAxMCk7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pbnRzW2ldID09PSAnbnVtYmVyJykgbWVzc2FnZS5pbnRzW2ldID0gb2JqZWN0LmludHNbaV07XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pbnRzW2ldID09PSAnb2JqZWN0JylcbiAgICAgICAgICAgIG1lc3NhZ2UuaW50c1tpXSA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuaW50c1tpXS5sb3cgPj4+IDAsIG9iamVjdC5pbnRzW2ldLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnN0cmluZ3MpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5zdHJpbmdzKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by5zdHJpbmdzOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnN0cmluZ3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Quc3RyaW5ncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zdHJpbmdzW2ldID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICR1dGlsLmJhc2U2NC5kZWNvZGUoXG4gICAgICAgICAgICAgIG9iamVjdC5zdHJpbmdzW2ldLFxuICAgICAgICAgICAgICAobWVzc2FnZS5zdHJpbmdzW2ldID0gJHV0aWwubmV3QnVmZmVyKCR1dGlsLmJhc2U2NC5sZW5ndGgob2JqZWN0LnN0cmluZ3NbaV0pKSksXG4gICAgICAgICAgICAgIDAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIGVsc2UgaWYgKG9iamVjdC5zdHJpbmdzW2ldLmxlbmd0aCA+PSAwKSBtZXNzYWdlLnN0cmluZ3NbaV0gPSBvYmplY3Quc3RyaW5nc1tpXTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QudGVuc29ycykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnRlbnNvcnMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLnRlbnNvcnM6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UudGVuc29ycyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC50ZW5zb3JzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudGVuc29yc1tpXSAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguQXR0cmlidXRlUHJvdG8udGVuc29yczogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS50ZW5zb3JzW2ldID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC50ZW5zb3JzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5ncmFwaHMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5ncmFwaHMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLmdyYXBoczogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5ncmFwaHMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZ3JhcGhzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZ3JhcGhzW2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by5ncmFwaHM6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuZ3JhcGhzW2ldID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmZyb21PYmplY3Qob2JqZWN0LmdyYXBoc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Quc3BhcnNlVGVuc29ycykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnNwYXJzZVRlbnNvcnMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLnNwYXJzZVRlbnNvcnM6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29ycyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5zcGFyc2VUZW5zb3JzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3BhcnNlVGVuc29yc1tpXSAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLnNwYXJzZVRlbnNvcnM6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29yc1tpXSA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3Quc3BhcnNlVGVuc29yc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QudHlwZVByb3Rvcykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnR5cGVQcm90b3MpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLnR5cGVQcm90b3M6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UudHlwZVByb3RvcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC50eXBlUHJvdG9zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudHlwZVByb3Rvc1tpXSAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLnR5cGVQcm90b3M6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UudHlwZVByb3Rvc1tpXSA9ICRyb290Lm9ubnguVHlwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LnR5cGVQcm90b3NbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGFuIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguQXR0cmlidXRlUHJvdG99IG1lc3NhZ2UgQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QuZmxvYXRzID0gW107XG4gICAgICAgIG9iamVjdC5pbnRzID0gW107XG4gICAgICAgIG9iamVjdC5zdHJpbmdzID0gW107XG4gICAgICAgIG9iamVjdC50ZW5zb3JzID0gW107XG4gICAgICAgIG9iamVjdC5ncmFwaHMgPSBbXTtcbiAgICAgICAgb2JqZWN0LnR5cGVQcm90b3MgPSBbXTtcbiAgICAgICAgb2JqZWN0LnNwYXJzZVRlbnNvcnMgPSBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5uYW1lID0gJyc7XG4gICAgICAgIG9iamVjdC5mID0gMDtcbiAgICAgICAgaWYgKCR1dGlsLkxvbmcpIHtcbiAgICAgICAgICB2YXIgbG9uZyA9IG5ldyAkdXRpbC5Mb25nKDAsIDAsIGZhbHNlKTtcbiAgICAgICAgICBvYmplY3QuaSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgIH0gZWxzZSBvYmplY3QuaSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICcwJyA6IDA7XG4gICAgICAgIGlmIChvcHRpb25zLmJ5dGVzID09PSBTdHJpbmcpIG9iamVjdC5zID0gJyc7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIG9iamVjdC5zID0gW107XG4gICAgICAgICAgaWYgKG9wdGlvbnMuYnl0ZXMgIT09IEFycmF5KSBvYmplY3QucyA9ICR1dGlsLm5ld0J1ZmZlcihvYmplY3Qucyk7XG4gICAgICAgIH1cbiAgICAgICAgb2JqZWN0LnQgPSBudWxsO1xuICAgICAgICBvYmplY3QuZyA9IG51bGw7XG4gICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSAnJztcbiAgICAgICAgb2JqZWN0LnRwID0gbnVsbDtcbiAgICAgICAgb2JqZWN0LnR5cGUgPSBvcHRpb25zLmVudW1zID09PSBTdHJpbmcgPyAnVU5ERUZJTkVEJyA6IDA7XG4gICAgICAgIG9iamVjdC5yZWZBdHRyTmFtZSA9ICcnO1xuICAgICAgICBvYmplY3Quc3BhcnNlVGVuc29yID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCduYW1lJykpIG9iamVjdC5uYW1lID0gbWVzc2FnZS5uYW1lO1xuICAgICAgaWYgKG1lc3NhZ2UuZiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2YnKSlcbiAgICAgICAgb2JqZWN0LmYgPSBvcHRpb25zLmpzb24gJiYgIWlzRmluaXRlKG1lc3NhZ2UuZikgPyBTdHJpbmcobWVzc2FnZS5mKSA6IG1lc3NhZ2UuZjtcbiAgICAgIGlmIChtZXNzYWdlLmkgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpJykpXG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5pID09PSAnbnVtYmVyJykgb2JqZWN0LmkgPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS5pKSA6IG1lc3NhZ2UuaTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIG9iamVjdC5pID1cbiAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZ1xuICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5pKVxuICAgICAgICAgICAgICA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlclxuICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuaS5sb3cgPj4+IDAsIG1lc3NhZ2UuaS5oaWdoID4+PiAwKS50b051bWJlcigpXG4gICAgICAgICAgICAgICAgOiBtZXNzYWdlLmk7XG4gICAgICBpZiAobWVzc2FnZS5zICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncycpKVxuICAgICAgICBvYmplY3QucyA9XG4gICAgICAgICAgb3B0aW9ucy5ieXRlcyA9PT0gU3RyaW5nXG4gICAgICAgICAgICA/ICR1dGlsLmJhc2U2NC5lbmNvZGUobWVzc2FnZS5zLCAwLCBtZXNzYWdlLnMubGVuZ3RoKVxuICAgICAgICAgICAgOiBvcHRpb25zLmJ5dGVzID09PSBBcnJheVxuICAgICAgICAgICAgICA/IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG1lc3NhZ2UucylcbiAgICAgICAgICAgICAgOiBtZXNzYWdlLnM7XG4gICAgICBpZiAobWVzc2FnZS50ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndCcpKVxuICAgICAgICBvYmplY3QudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS50LCBvcHRpb25zKTtcbiAgICAgIGlmIChtZXNzYWdlLmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdnJykpXG4gICAgICAgIG9iamVjdC5nID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZywgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS5mbG9hdHMgJiYgbWVzc2FnZS5mbG9hdHMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5mbG9hdHMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmZsb2F0cy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuZmxvYXRzW2pdID1cbiAgICAgICAgICAgIG9wdGlvbnMuanNvbiAmJiAhaXNGaW5pdGUobWVzc2FnZS5mbG9hdHNbal0pID8gU3RyaW5nKG1lc3NhZ2UuZmxvYXRzW2pdKSA6IG1lc3NhZ2UuZmxvYXRzW2pdO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaW50cyAmJiBtZXNzYWdlLmludHMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5pbnRzID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbnRzLmxlbmd0aDsgKytqKVxuICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5pbnRzW2pdID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgIG9iamVjdC5pbnRzW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuaW50c1tqXSkgOiBtZXNzYWdlLmludHNbal07XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgb2JqZWN0LmludHNbal0gPVxuICAgICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5pbnRzW2pdKVxuICAgICAgICAgICAgICAgIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyXG4gICAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmludHNbal0ubG93ID4+PiAwLCBtZXNzYWdlLmludHNbal0uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgICAgOiBtZXNzYWdlLmludHNbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zdHJpbmdzICYmIG1lc3NhZ2Uuc3RyaW5ncy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnN0cmluZ3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnN0cmluZ3Nbal0gPVxuICAgICAgICAgICAgb3B0aW9ucy5ieXRlcyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgID8gJHV0aWwuYmFzZTY0LmVuY29kZShtZXNzYWdlLnN0cmluZ3Nbal0sIDAsIG1lc3NhZ2Uuc3RyaW5nc1tqXS5sZW5ndGgpXG4gICAgICAgICAgICAgIDogb3B0aW9ucy5ieXRlcyA9PT0gQXJyYXlcbiAgICAgICAgICAgICAgICA/IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG1lc3NhZ2Uuc3RyaW5nc1tqXSlcbiAgICAgICAgICAgICAgICA6IG1lc3NhZ2Uuc3RyaW5nc1tqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnRlbnNvcnMgJiYgbWVzc2FnZS50ZW5zb3JzLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QudGVuc29ycyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UudGVuc29ycy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QudGVuc29yc1tqXSA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS50ZW5zb3JzW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmdyYXBocyAmJiBtZXNzYWdlLmdyYXBocy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmdyYXBocyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZ3JhcGhzLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5ncmFwaHNbal0gPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udG9PYmplY3QobWVzc2FnZS5ncmFwaHNbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpIG9iamVjdC5kb2NTdHJpbmcgPSBtZXNzYWdlLmRvY1N0cmluZztcbiAgICAgIGlmIChtZXNzYWdlLnRwICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndHAnKSlcbiAgICAgICAgb2JqZWN0LnRwID0gJHJvb3Qub25ueC5UeXBlUHJvdG8udG9PYmplY3QobWVzc2FnZS50cCwgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS50eXBlUHJvdG9zICYmIG1lc3NhZ2UudHlwZVByb3Rvcy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnR5cGVQcm90b3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnR5cGVQcm90b3MubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnR5cGVQcm90b3Nbal0gPSAkcm9vdC5vbm54LlR5cGVQcm90by50b09iamVjdChtZXNzYWdlLnR5cGVQcm90b3Nbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3R5cGUnKSlcbiAgICAgICAgb2JqZWN0LnR5cGUgPVxuICAgICAgICAgIG9wdGlvbnMuZW51bXMgPT09IFN0cmluZ1xuICAgICAgICAgICAgPyAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGVbbWVzc2FnZS50eXBlXSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gbWVzc2FnZS50eXBlXG4gICAgICAgICAgICAgIDogJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlW21lc3NhZ2UudHlwZV1cbiAgICAgICAgICAgIDogbWVzc2FnZS50eXBlO1xuICAgICAgaWYgKG1lc3NhZ2UucmVmQXR0ck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdyZWZBdHRyTmFtZScpKVxuICAgICAgICBvYmplY3QucmVmQXR0ck5hbWUgPSBtZXNzYWdlLnJlZkF0dHJOYW1lO1xuICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlVGVuc29yICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc3BhcnNlVGVuc29yJykpXG4gICAgICAgIG9iamVjdC5zcGFyc2VUZW5zb3IgPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uuc3BhcnNlVGVuc29yLCBvcHRpb25zKTtcbiAgICAgIGlmIChtZXNzYWdlLnNwYXJzZVRlbnNvcnMgJiYgbWVzc2FnZS5zcGFyc2VUZW5zb3JzLmxlbmd0aCkge1xuICAgICAgICBvYmplY3Quc3BhcnNlVGVuc29ycyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uuc3BhcnNlVGVuc29ycy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3Quc3BhcnNlVGVuc29yc1tqXSA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS5zcGFyc2VUZW5zb3JzW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgQXR0cmlidXRlUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBBdHRyaWJ1dGVQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5BdHRyaWJ1dGVQcm90byc7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVR5cGUgZW51bS5cbiAgICAgKiBAbmFtZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGVcbiAgICAgKiBAZW51bSB7bnVtYmVyfVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBVTkRFRklORUQ9MCBVTkRFRklORUQgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ9MSBGTE9BVCB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJTlQ9MiBJTlQgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gU1RSSU5HPTMgU1RSSU5HIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFRFTlNPUj00IFRFTlNPUiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBHUkFQSD01IEdSQVBIIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFNQQVJTRV9URU5TT1I9MTEgU1BBUlNFX1RFTlNPUiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBUWVBFX1BST1RPPTEzIFRZUEVfUFJPVE8gdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVRTPTYgRkxPQVRTIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IElOVFM9NyBJTlRTIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFNUUklOR1M9OCBTVFJJTkdTIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFRFTlNPUlM9OSBURU5TT1JTIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IEdSQVBIUz0xMCBHUkFQSFMgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gU1BBUlNFX1RFTlNPUlM9MTIgU1BBUlNFX1RFTlNPUlMgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gVFlQRV9QUk9UT1M9MTQgVFlQRV9QUk9UT1MgdmFsdWVcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciB2YWx1ZXNCeUlkID0ge30sXG4gICAgICAgIHZhbHVlcyA9IE9iamVjdC5jcmVhdGUodmFsdWVzQnlJZCk7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMF0gPSAnVU5ERUZJTkVEJyldID0gMDtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxXSA9ICdGTE9BVCcpXSA9IDE7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMl0gPSAnSU5UJyldID0gMjtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFszXSA9ICdTVFJJTkcnKV0gPSAzO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzRdID0gJ1RFTlNPUicpXSA9IDQ7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbNV0gPSAnR1JBUEgnKV0gPSA1O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzExXSA9ICdTUEFSU0VfVEVOU09SJyldID0gMTE7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTNdID0gJ1RZUEVfUFJPVE8nKV0gPSAxMztcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFs2XSA9ICdGTE9BVFMnKV0gPSA2O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzddID0gJ0lOVFMnKV0gPSA3O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzhdID0gJ1NUUklOR1MnKV0gPSA4O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzldID0gJ1RFTlNPUlMnKV0gPSA5O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzEwXSA9ICdHUkFQSFMnKV0gPSAxMDtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxMl0gPSAnU1BBUlNFX1RFTlNPUlMnKV0gPSAxMjtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxNF0gPSAnVFlQRV9QUk9UT1MnKV0gPSAxNDtcbiAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfSkoKTtcblxuICAgIHJldHVybiBBdHRyaWJ1dGVQcm90bztcbiAgfSkoKTtcblxuICBvbm54LlZhbHVlSW5mb1Byb3RvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgVmFsdWVJbmZvUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElWYWx1ZUluZm9Qcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtuYW1lXSBWYWx1ZUluZm9Qcm90byBuYW1lXG4gICAgICogQHByb3BlcnR5IHtvbm54LklUeXBlUHJvdG98bnVsbH0gW3R5cGVdIFZhbHVlSW5mb1Byb3RvIHR5cGVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9jU3RyaW5nXSBWYWx1ZUluZm9Qcm90byBkb2NTdHJpbmdcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgVmFsdWVJbmZvUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBWYWx1ZUluZm9Qcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29ubnguSVZhbHVlSW5mb1Byb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICovXG4gICAgZnVuY3Rpb24gVmFsdWVJbmZvUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFZhbHVlSW5mb1Byb3RvIG5hbWUuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBuYW1lXG4gICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBWYWx1ZUluZm9Qcm90by5wcm90b3R5cGUubmFtZSA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogVmFsdWVJbmZvUHJvdG8gdHlwZS5cbiAgICAgKiBAbWVtYmVyIHtvbm54LklUeXBlUHJvdG98bnVsbHx1bmRlZmluZWR9IHR5cGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLnByb3RvdHlwZS50eXBlID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFZhbHVlSW5mb1Byb3RvIGRvY1N0cmluZy5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8ucHJvdG90eXBlLmRvY1N0cmluZyA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBWYWx1ZUluZm9Qcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVmFsdWVJbmZvUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5WYWx1ZUluZm9Qcm90b30gVmFsdWVJbmZvUHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBWYWx1ZUluZm9Qcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBWYWx1ZUluZm9Qcm90byhwcm9wZXJ0aWVzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVmFsdWVJbmZvUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVmFsdWVJbmZvUHJvdG99IG1lc3NhZ2UgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICduYW1lJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgaWYgKG1lc3NhZ2UudHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICd0eXBlJykpXG4gICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLmVuY29kZShtZXNzYWdlLnR5cGUsIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZG9jU3RyaW5nJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMywgd2lyZVR5cGUgMiA9Ki8gMjYpLnN0cmluZyhtZXNzYWdlLmRvY1N0cmluZyk7XG4gICAgICByZXR1cm4gd3JpdGVyO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5WYWx1ZUluZm9Qcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklWYWx1ZUluZm9Qcm90b30gbWVzc2FnZSBWYWx1ZUluZm9Qcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBWYWx1ZUluZm9Qcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlZhbHVlSW5mb1Byb3RvfSBWYWx1ZUluZm9Qcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8oKTtcbiAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMzoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LlZhbHVlSW5mb1Byb3RvfSBWYWx1ZUluZm9Qcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm5hbWUpKSByZXR1cm4gJ25hbWU6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS50eXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndHlwZScpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLnZlcmlmeShtZXNzYWdlLnR5cGUpO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAndHlwZS4nICsgZXJyb3I7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvY1N0cmluZykpIHJldHVybiAnZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBWYWx1ZUluZm9Qcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguVmFsdWVJbmZvUHJvdG99IFZhbHVlSW5mb1Byb3RvXG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QubmFtZSAhPSBudWxsKSBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgaWYgKG9iamVjdC50eXBlICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudHlwZSAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguVmFsdWVJbmZvUHJvdG8udHlwZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UudHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LnR5cGUpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbCkgbWVzc2FnZS5kb2NTdHJpbmcgPSBTdHJpbmcob2JqZWN0LmRvY1N0cmluZyk7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5WYWx1ZUluZm9Qcm90b30gbWVzc2FnZSBWYWx1ZUluZm9Qcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5uYW1lID0gJyc7XG4gICAgICAgIG9iamVjdC50eXBlID0gbnVsbDtcbiAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9ICcnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSkgb2JqZWN0Lm5hbWUgPSBtZXNzYWdlLm5hbWU7XG4gICAgICBpZiAobWVzc2FnZS50eXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndHlwZScpKVxuICAgICAgICBvYmplY3QudHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudHlwZSwgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSkgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBWYWx1ZUluZm9Qcm90byB0byBKU09OLlxuICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBWYWx1ZUluZm9Qcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFZhbHVlSW5mb1Byb3RvXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlZhbHVlSW5mb1Byb3RvJztcbiAgICB9O1xuXG4gICAgcmV0dXJuIFZhbHVlSW5mb1Byb3RvO1xuICB9KSgpO1xuXG4gIG9ubnguTm9kZVByb3RvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgTm9kZVByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGludGVyZmFjZSBJTm9kZVByb3RvXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48c3RyaW5nPnxudWxsfSBbaW5wdXRdIE5vZGVQcm90byBpbnB1dFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPHN0cmluZz58bnVsbH0gW291dHB1dF0gTm9kZVByb3RvIG91dHB1dFxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtuYW1lXSBOb2RlUHJvdG8gbmFtZVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtvcFR5cGVdIE5vZGVQcm90byBvcFR5cGVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9tYWluXSBOb2RlUHJvdG8gZG9tYWluXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JQXR0cmlidXRlUHJvdG8+fG51bGx9IFthdHRyaWJ1dGVdIE5vZGVQcm90byBhdHRyaWJ1dGVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9jU3RyaW5nXSBOb2RlUHJvdG8gZG9jU3RyaW5nXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE5vZGVQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIE5vZGVQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJTm9kZVByb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklOb2RlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBOb2RlUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5pbnB1dCA9IFtdO1xuICAgICAgdGhpcy5vdXRwdXQgPSBbXTtcbiAgICAgIHRoaXMuYXR0cmlidXRlID0gW107XG4gICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTm9kZVByb3RvIGlucHV0LlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxzdHJpbmc+fSBpbnB1dFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE5vZGVQcm90by5wcm90b3R5cGUuaW5wdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogTm9kZVByb3RvIG91dHB1dC5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48c3RyaW5nPn0gb3V0cHV0XG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTm9kZVByb3RvLnByb3RvdHlwZS5vdXRwdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogTm9kZVByb3RvIG5hbWUuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBuYW1lXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTm9kZVByb3RvLnByb3RvdHlwZS5uYW1lID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBOb2RlUHJvdG8gb3BUeXBlLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gb3BUeXBlXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTm9kZVByb3RvLnByb3RvdHlwZS5vcFR5cGUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIE5vZGVQcm90byBkb21haW4uXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkb21haW5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8ucHJvdG90eXBlLmRvbWFpbiA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogTm9kZVByb3RvIGF0dHJpYnV0ZS5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JQXR0cmlidXRlUHJvdG8+fSBhdHRyaWJ1dGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8ucHJvdG90eXBlLmF0dHJpYnV0ZSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBOb2RlUHJvdG8gZG9jU3RyaW5nLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9jU3RyaW5nXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTm9kZVByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSAnJztcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgTm9kZVByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JTm9kZVByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguTm9kZVByb3RvfSBOb2RlUHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgTm9kZVByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgTm9kZVByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguTm9kZVByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklOb2RlUHJvdG99IG1lc3NhZ2UgTm9kZVByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5wdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuc3RyaW5nKG1lc3NhZ2UuaW5wdXRbaV0pO1xuICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICE9IG51bGwgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLnN0cmluZyhtZXNzYWdlLm91dHB1dFtpXSk7XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ25hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAzLCB3aXJlVHlwZSAyID0qLyAyNikuc3RyaW5nKG1lc3NhZ2UubmFtZSk7XG4gICAgICBpZiAobWVzc2FnZS5vcFR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnb3BUeXBlJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNCwgd2lyZVR5cGUgMiA9Ki8gMzQpLnN0cmluZyhtZXNzYWdlLm9wVHlwZSk7XG4gICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGUgIT0gbnVsbCAmJiBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZVtpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki8gNDIpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RvY1N0cmluZycpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDYsIHdpcmVUeXBlIDIgPSovIDUwKS5zdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RvbWFpbicpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDcsIHdpcmVUeXBlIDIgPSovIDU4KS5zdHJpbmcobWVzc2FnZS5kb21haW4pO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE5vZGVQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54Lk5vZGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JTm9kZVByb3RvfSBtZXNzYWdlIE5vZGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgTm9kZVByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgTm9kZVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54Lk5vZGVQcm90b30gTm9kZVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguTm9kZVByb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkpIG1lc3NhZ2UuaW5wdXQgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXQucHVzaChyZWFkZXIuc3RyaW5nKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSkgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0LnB1c2gocmVhZGVyLnN0cmluZygpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDM6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDQ6IHtcbiAgICAgICAgICAgIG1lc3NhZ2Uub3BUeXBlID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNzoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb21haW4gPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA1OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmF0dHJpYnV0ZSAmJiBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGgpKSBtZXNzYWdlLmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGUucHVzaCgkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNjoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIE5vZGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHJldHVybnMge29ubnguTm9kZVByb3RvfSBOb2RlUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIE5vZGVQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWVzIGEgTm9kZVByb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIE5vZGVQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2lucHV0JykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuaW5wdXQpKSByZXR1cm4gJ2lucHV0OiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuaW5wdXRbaV0pKSByZXR1cm4gJ2lucHV0OiBzdHJpbmdbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5vdXRwdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdvdXRwdXQnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5vdXRwdXQpKSByZXR1cm4gJ291dHB1dDogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5vdXRwdXRbaV0pKSByZXR1cm4gJ291dHB1dDogc3RyaW5nW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm5hbWUpKSByZXR1cm4gJ25hbWU6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5vcFR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdvcFR5cGUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm9wVHlwZSkpIHJldHVybiAnb3BUeXBlOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9tYWluJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb21haW4pKSByZXR1cm4gJ2RvbWFpbjogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmF0dHJpYnV0ZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2F0dHJpYnV0ZScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmF0dHJpYnV0ZSkpIHJldHVybiAnYXR0cmlidXRlOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLnZlcmlmeShtZXNzYWdlLmF0dHJpYnV0ZVtpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2F0dHJpYnV0ZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSkgcmV0dXJuICdkb2NTdHJpbmc6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIE5vZGVQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54Lk5vZGVQcm90b30gTm9kZVByb3RvXG4gICAgICovXG4gICAgTm9kZVByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguTm9kZVByb3RvKSByZXR1cm4gb2JqZWN0O1xuICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5Ob2RlUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QuaW5wdXQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5pbnB1dCkpIHRocm93IFR5cGVFcnJvcignLm9ubnguTm9kZVByb3RvLmlucHV0OiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmlucHV0Lmxlbmd0aDsgKytpKSBtZXNzYWdlLmlucHV0W2ldID0gU3RyaW5nKG9iamVjdC5pbnB1dFtpXSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0Lm91dHB1dCkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0Lm91dHB1dCkpIHRocm93IFR5cGVFcnJvcignLm9ubnguTm9kZVByb3RvLm91dHB1dDogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Qub3V0cHV0Lmxlbmd0aDsgKytpKSBtZXNzYWdlLm91dHB1dFtpXSA9IFN0cmluZyhvYmplY3Qub3V0cHV0W2ldKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QubmFtZSAhPSBudWxsKSBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgaWYgKG9iamVjdC5vcFR5cGUgIT0gbnVsbCkgbWVzc2FnZS5vcFR5cGUgPSBTdHJpbmcob2JqZWN0Lm9wVHlwZSk7XG4gICAgICBpZiAob2JqZWN0LmRvbWFpbiAhPSBudWxsKSBtZXNzYWdlLmRvbWFpbiA9IFN0cmluZyhvYmplY3QuZG9tYWluKTtcbiAgICAgIGlmIChvYmplY3QuYXR0cmlidXRlKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuYXR0cmlidXRlKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Ob2RlUHJvdG8uYXR0cmlidXRlOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5hdHRyaWJ1dGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5hdHRyaWJ1dGVbaV0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54Lk5vZGVQcm90by5hdHRyaWJ1dGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuYXR0cmlidXRlW2ldID0gJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC5hdHRyaWJ1dGVbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKSBtZXNzYWdlLmRvY1N0cmluZyA9IFN0cmluZyhvYmplY3QuZG9jU3RyaW5nKTtcbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBOb2RlUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguTm9kZVByb3RvfSBtZXNzYWdlIE5vZGVQcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgTm9kZVByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QuaW5wdXQgPSBbXTtcbiAgICAgICAgb2JqZWN0Lm91dHB1dCA9IFtdO1xuICAgICAgICBvYmplY3QuYXR0cmlidXRlID0gW107XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QubmFtZSA9ICcnO1xuICAgICAgICBvYmplY3Qub3BUeXBlID0gJyc7XG4gICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSAnJztcbiAgICAgICAgb2JqZWN0LmRvbWFpbiA9ICcnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgJiYgbWVzc2FnZS5pbnB1dC5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmlucHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraikgb2JqZWN0LmlucHV0W2pdID0gbWVzc2FnZS5pbnB1dFtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm91dHB1dCAmJiBtZXNzYWdlLm91dHB1dC5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0Lm91dHB1dCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytqKSBvYmplY3Qub3V0cHV0W2pdID0gbWVzc2FnZS5vdXRwdXRbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpKSBvYmplY3QubmFtZSA9IG1lc3NhZ2UubmFtZTtcbiAgICAgIGlmIChtZXNzYWdlLm9wVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ29wVHlwZScpKSBvYmplY3Qub3BUeXBlID0gbWVzc2FnZS5vcFR5cGU7XG4gICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGUgJiYgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuYXR0cmlidXRlW2pdID0gJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by50b09iamVjdChtZXNzYWdlLmF0dHJpYnV0ZVtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSkgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9tYWluJykpIG9iamVjdC5kb21haW4gPSBtZXNzYWdlLmRvbWFpbjtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgTm9kZVByb3RvIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBOb2RlUHJvdG9cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIE5vZGVQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5Ob2RlUHJvdG8nO1xuICAgIH07XG5cbiAgICByZXR1cm4gTm9kZVByb3RvO1xuICB9KSgpO1xuXG4gIG9ubnguVHJhaW5pbmdJbmZvUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYSBUcmFpbmluZ0luZm9Qcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSVRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQHByb3BlcnR5IHtvbm54LklHcmFwaFByb3RvfG51bGx9IFtpbml0aWFsaXphdGlvbl0gVHJhaW5pbmdJbmZvUHJvdG8gaW5pdGlhbGl6YXRpb25cbiAgICAgKiBAcHJvcGVydHkge29ubnguSUdyYXBoUHJvdG98bnVsbH0gW2FsZ29yaXRobV0gVHJhaW5pbmdJbmZvUHJvdG8gYWxnb3JpdGhtXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz58bnVsbH0gW2luaXRpYWxpemF0aW9uQmluZGluZ10gVHJhaW5pbmdJbmZvUHJvdG8gaW5pdGlhbGl6YXRpb25CaW5kaW5nXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz58bnVsbH0gW3VwZGF0ZUJpbmRpbmddIFRyYWluaW5nSW5mb1Byb3RvIHVwZGF0ZUJpbmRpbmdcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgVHJhaW5pbmdJbmZvUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBUcmFpbmluZ0luZm9Qcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29ubnguSVRyYWluaW5nSW5mb1Byb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICovXG4gICAgZnVuY3Rpb24gVHJhaW5pbmdJbmZvUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5pbml0aWFsaXphdGlvbkJpbmRpbmcgPSBbXTtcbiAgICAgIHRoaXMudXBkYXRlQmluZGluZyA9IFtdO1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyYWluaW5nSW5mb1Byb3RvIGluaXRpYWxpemF0aW9uLlxuICAgICAqIEBtZW1iZXIge29ubnguSUdyYXBoUHJvdG98bnVsbHx1bmRlZmluZWR9IGluaXRpYWxpemF0aW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by5wcm90b3R5cGUuaW5pdGlhbGl6YXRpb24gPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVHJhaW5pbmdJbmZvUHJvdG8gYWxnb3JpdGhtLlxuICAgICAqIEBtZW1iZXIge29ubnguSUdyYXBoUHJvdG98bnVsbHx1bmRlZmluZWR9IGFsZ29yaXRobVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8ucHJvdG90eXBlLmFsZ29yaXRobSA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBUcmFpbmluZ0luZm9Qcm90byBpbml0aWFsaXphdGlvbkJpbmRpbmcuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fSBpbml0aWFsaXphdGlvbkJpbmRpbmdcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRyYWluaW5nSW5mb1Byb3RvLnByb3RvdHlwZS5pbml0aWFsaXphdGlvbkJpbmRpbmcgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogVHJhaW5pbmdJbmZvUHJvdG8gdXBkYXRlQmluZGluZy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz59IHVwZGF0ZUJpbmRpbmdcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRyYWluaW5nSW5mb1Byb3RvLnByb3RvdHlwZS51cGRhdGVCaW5kaW5nID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgVHJhaW5pbmdJbmZvUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVRyYWluaW5nSW5mb1Byb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguVHJhaW5pbmdJbmZvUHJvdG99IFRyYWluaW5nSW5mb1Byb3RvIGluc3RhbmNlXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgVHJhaW5pbmdJbmZvUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRyYWluaW5nSW5mb1Byb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVRyYWluaW5nSW5mb1Byb3RvfSBtZXNzYWdlIFRyYWluaW5nSW5mb1Byb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemF0aW9uICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2luaXRpYWxpemF0aW9uJykpXG4gICAgICAgICRyb290Lm9ubnguR3JhcGhQcm90by5lbmNvZGUobWVzc2FnZS5pbml0aWFsaXphdGlvbiwgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmFsZ29yaXRobSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdhbGdvcml0aG0nKSlcbiAgICAgICAgJHJvb3Qub25ueC5HcmFwaFByb3RvLmVuY29kZShtZXNzYWdlLmFsZ29yaXRobSwgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLyAxOCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZyAhPSBudWxsICYmIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmdbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDIgPSovIDI2KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLnVwZGF0ZUJpbmRpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudXBkYXRlQmluZGluZy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS51cGRhdGVCaW5kaW5nW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA0LCB3aXJlVHlwZSAyID0qLyAzNCkuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICByZXR1cm4gd3JpdGVyO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UcmFpbmluZ0luZm9Qcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUcmFpbmluZ0luZm9Qcm90b30gbWVzc2FnZSBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRyYWluaW5nSW5mb1Byb3RvfSBUcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHJhaW5pbmdJbmZvUHJvdG8oKTtcbiAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmluaXRpYWxpemF0aW9uID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmFsZ29yaXRobSA9ICRyb290Lm9ubnguR3JhcGhQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMzoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcgJiYgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcubGVuZ3RoKSlcbiAgICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLnB1c2goJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNDoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS51cGRhdGVCaW5kaW5nICYmIG1lc3NhZ2UudXBkYXRlQmluZGluZy5sZW5ndGgpKSBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UudXBkYXRlQmluZGluZy5wdXNoKCRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHJldHVybnMge29ubnguVHJhaW5pbmdJbmZvUHJvdG99IFRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWVzIGEgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXphdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2luaXRpYWxpemF0aW9uJykpIHtcbiAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnZlcmlmeShtZXNzYWdlLmluaXRpYWxpemF0aW9uKTtcbiAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2luaXRpYWxpemF0aW9uLicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmFsZ29yaXRobSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2FsZ29yaXRobScpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguR3JhcGhQcm90by52ZXJpZnkobWVzc2FnZS5hbGdvcml0aG0pO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnYWxnb3JpdGhtLicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2luaXRpYWxpemF0aW9uQmluZGluZycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZykpIHJldHVybiAnaW5pdGlhbGl6YXRpb25CaW5kaW5nOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5KG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnaW5pdGlhbGl6YXRpb25CaW5kaW5nLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudXBkYXRlQmluZGluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3VwZGF0ZUJpbmRpbmcnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS51cGRhdGVCaW5kaW5nKSkgcmV0dXJuICd1cGRhdGVCaW5kaW5nOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS51cGRhdGVCaW5kaW5nLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnZlcmlmeShtZXNzYWdlLnVwZGF0ZUJpbmRpbmdbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICd1cGRhdGVCaW5kaW5nLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguVHJhaW5pbmdJbmZvUHJvdG99IFRyYWluaW5nSW5mb1Byb3RvXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHJhaW5pbmdJbmZvUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QuaW5pdGlhbGl6YXRpb24gIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5pbml0aWFsaXphdGlvbiAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UcmFpbmluZ0luZm9Qcm90by5pbml0aWFsaXphdGlvbjogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb24gPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZnJvbU9iamVjdChvYmplY3QuaW5pdGlhbGl6YXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5hbGdvcml0aG0gIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5hbGdvcml0aG0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmFsZ29yaXRobTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuYWxnb3JpdGhtID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmZyb21PYmplY3Qob2JqZWN0LmFsZ29yaXRobSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZykpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UcmFpbmluZ0luZm9Qcm90by5pbml0aWFsaXphdGlvbkJpbmRpbmc6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZ1tpXSAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmluaXRpYWxpemF0aW9uQmluZGluZzogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmdbaV0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZnJvbU9iamVjdChcbiAgICAgICAgICAgIG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmdbaV0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC51cGRhdGVCaW5kaW5nKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QudXBkYXRlQmluZGluZykpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UcmFpbmluZ0luZm9Qcm90by51cGRhdGVCaW5kaW5nOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QudXBkYXRlQmluZGluZy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnVwZGF0ZUJpbmRpbmdbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UcmFpbmluZ0luZm9Qcm90by51cGRhdGVCaW5kaW5nOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLnVwZGF0ZUJpbmRpbmdbaV0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZnJvbU9iamVjdChvYmplY3QudXBkYXRlQmluZGluZ1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LlRyYWluaW5nSW5mb1Byb3RvfSBtZXNzYWdlIFRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZyA9IFtdO1xuICAgICAgICBvYmplY3QudXBkYXRlQmluZGluZyA9IFtdO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0LmluaXRpYWxpemF0aW9uID0gbnVsbDtcbiAgICAgICAgb2JqZWN0LmFsZ29yaXRobSA9IG51bGw7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXphdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2luaXRpYWxpemF0aW9uJykpXG4gICAgICAgIG9iamVjdC5pbml0aWFsaXphdGlvbiA9ICRyb290Lm9ubnguR3JhcGhQcm90by50b09iamVjdChtZXNzYWdlLmluaXRpYWxpemF0aW9uLCBvcHRpb25zKTtcbiAgICAgIGlmIChtZXNzYWdlLmFsZ29yaXRobSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2FsZ29yaXRobScpKVxuICAgICAgICBvYmplY3QuYWxnb3JpdGhtID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuYWxnb3JpdGhtLCBvcHRpb25zKTtcbiAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZyAmJiBtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmdbal0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udG9PYmplY3QoXG4gICAgICAgICAgICBtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZ1tqXSxcbiAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnVwZGF0ZUJpbmRpbmcgJiYgbWVzc2FnZS51cGRhdGVCaW5kaW5nLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QudXBkYXRlQmluZGluZyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UudXBkYXRlQmluZGluZy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QudXBkYXRlQmluZGluZ1tqXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by50b09iamVjdChtZXNzYWdlLnVwZGF0ZUJpbmRpbmdbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBUcmFpbmluZ0luZm9Qcm90byB0byBKU09OLlxuICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIFRyYWluaW5nSW5mb1Byb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlRyYWluaW5nSW5mb1Byb3RvJztcbiAgICB9O1xuXG4gICAgcmV0dXJuIFRyYWluaW5nSW5mb1Byb3RvO1xuICB9KSgpO1xuXG4gIG9ubnguTW9kZWxQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhIE1vZGVsUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElNb2RlbFByb3RvXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbaXJWZXJzaW9uXSBNb2RlbFByb3RvIGlyVmVyc2lvblxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSU9wZXJhdG9yU2V0SWRQcm90bz58bnVsbH0gW29wc2V0SW1wb3J0XSBNb2RlbFByb3RvIG9wc2V0SW1wb3J0XG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW3Byb2R1Y2VyTmFtZV0gTW9kZWxQcm90byBwcm9kdWNlck5hbWVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbcHJvZHVjZXJWZXJzaW9uXSBNb2RlbFByb3RvIHByb2R1Y2VyVmVyc2lvblxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb21haW5dIE1vZGVsUHJvdG8gZG9tYWluXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbbW9kZWxWZXJzaW9uXSBNb2RlbFByb3RvIG1vZGVsVmVyc2lvblxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb2NTdHJpbmddIE1vZGVsUHJvdG8gZG9jU3RyaW5nXG4gICAgICogQHByb3BlcnR5IHtvbm54LklHcmFwaFByb3RvfG51bGx9IFtncmFwaF0gTW9kZWxQcm90byBncmFwaFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fG51bGx9IFttZXRhZGF0YVByb3BzXSBNb2RlbFByb3RvIG1ldGFkYXRhUHJvcHNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklUcmFpbmluZ0luZm9Qcm90bz58bnVsbH0gW3RyYWluaW5nSW5mb10gTW9kZWxQcm90byB0cmFpbmluZ0luZm9cbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklGdW5jdGlvblByb3RvPnxudWxsfSBbZnVuY3Rpb25zXSBNb2RlbFByb3RvIGZ1bmN0aW9uc1xuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBNb2RlbFByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgTW9kZWxQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJTW9kZWxQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JTW9kZWxQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIE1vZGVsUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgdGhpcy5tZXRhZGF0YVByb3BzID0gW107XG4gICAgICB0aGlzLnRyYWluaW5nSW5mbyA9IFtdO1xuICAgICAgdGhpcy5mdW5jdGlvbnMgPSBbXTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIGlyVmVyc2lvbi5cbiAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ30gaXJWZXJzaW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLmlyVmVyc2lvbiA9ICR1dGlsLkxvbmcgPyAkdXRpbC5Mb25nLmZyb21CaXRzKDAsIDAsIGZhbHNlKSA6IDA7XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIG9wc2V0SW1wb3J0LlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklPcGVyYXRvclNldElkUHJvdG8+fSBvcHNldEltcG9ydFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5vcHNldEltcG9ydCA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIHByb2R1Y2VyTmFtZS5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IHByb2R1Y2VyTmFtZVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5wcm9kdWNlck5hbWUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIE1vZGVsUHJvdG8gcHJvZHVjZXJWZXJzaW9uLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gcHJvZHVjZXJWZXJzaW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLnByb2R1Y2VyVmVyc2lvbiA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogTW9kZWxQcm90byBkb21haW4uXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkb21haW5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTW9kZWxQcm90by5wcm90b3R5cGUuZG9tYWluID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIG1vZGVsVmVyc2lvbi5cbiAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ30gbW9kZWxWZXJzaW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLm1vZGVsVmVyc2lvbiA9ICR1dGlsLkxvbmcgPyAkdXRpbC5Mb25nLmZyb21CaXRzKDAsIDAsIGZhbHNlKSA6IDA7XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIGRvY1N0cmluZy5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSAnJztcblxuICAgIC8qKlxuICAgICAqIE1vZGVsUHJvdG8gZ3JhcGguXG4gICAgICogQG1lbWJlciB7b25ueC5JR3JhcGhQcm90b3xudWxsfHVuZGVmaW5lZH0gZ3JhcGhcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTW9kZWxQcm90by5wcm90b3R5cGUuZ3JhcGggPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogTW9kZWxQcm90byBtZXRhZGF0YVByb3BzLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPn0gbWV0YWRhdGFQcm9wc1xuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5tZXRhZGF0YVByb3BzID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIE1vZGVsUHJvdG8gdHJhaW5pbmdJbmZvLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklUcmFpbmluZ0luZm9Qcm90bz59IHRyYWluaW5nSW5mb1xuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS50cmFpbmluZ0luZm8gPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogTW9kZWxQcm90byBmdW5jdGlvbnMuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSUZ1bmN0aW9uUHJvdG8+fSBmdW5jdGlvbnNcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTW9kZWxQcm90by5wcm90b3R5cGUuZnVuY3Rpb25zID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgTW9kZWxQcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklNb2RlbFByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguTW9kZWxQcm90b30gTW9kZWxQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgTW9kZWxQcm90byhwcm9wZXJ0aWVzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE1vZGVsUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5Nb2RlbFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JTW9kZWxQcm90b30gbWVzc2FnZSBNb2RlbFByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuaXJWZXJzaW9uICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2lyVmVyc2lvbicpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDAgPSovIDgpLmludDY0KG1lc3NhZ2UuaXJWZXJzaW9uKTtcbiAgICAgIGlmIChtZXNzYWdlLnByb2R1Y2VyTmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdwcm9kdWNlck5hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLyAxOCkuc3RyaW5nKG1lc3NhZ2UucHJvZHVjZXJOYW1lKTtcbiAgICAgIGlmIChtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdwcm9kdWNlclZlcnNpb24nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAzLCB3aXJlVHlwZSAyID0qLyAyNikuc3RyaW5nKG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb21haW4nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA0LCB3aXJlVHlwZSAyID0qLyAzNCkuc3RyaW5nKG1lc3NhZ2UuZG9tYWluKTtcbiAgICAgIGlmIChtZXNzYWdlLm1vZGVsVmVyc2lvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdtb2RlbFZlcnNpb24nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA1LCB3aXJlVHlwZSAwID0qLyA0MCkuaW50NjQobWVzc2FnZS5tb2RlbFZlcnNpb24pO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RvY1N0cmluZycpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDYsIHdpcmVUeXBlIDIgPSovIDUwKS5zdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpO1xuICAgICAgaWYgKG1lc3NhZ2UuZ3JhcGggIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZ3JhcGgnKSlcbiAgICAgICAgJHJvb3Qub25ueC5HcmFwaFByb3RvLmVuY29kZShtZXNzYWdlLmdyYXBoLCB3cml0ZXIudWludDMyKC8qIGlkIDcsIHdpcmVUeXBlIDIgPSovIDU4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2Uub3BzZXRJbXBvcnQgIT0gbnVsbCAmJiBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2Uub3BzZXRJbXBvcnRbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDgsIHdpcmVUeXBlIDIgPSovIDY2KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLm1ldGFkYXRhUHJvcHMgIT0gbnVsbCAmJiBtZXNzYWdlLm1ldGFkYXRhUHJvcHMubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5tZXRhZGF0YVByb3BzW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxNCwgd2lyZVR5cGUgMiA9Ki8gMTE0KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLnRyYWluaW5nSW5mbyAhPSBudWxsICYmIG1lc3NhZ2UudHJhaW5pbmdJbmZvLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnRyYWluaW5nSW5mby5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UudHJhaW5pbmdJbmZvW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyMCwgd2lyZVR5cGUgMiA9Ki8gMTYyKS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmZ1bmN0aW9ucyAhPSBudWxsICYmIG1lc3NhZ2UuZnVuY3Rpb25zLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmZ1bmN0aW9ucy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LkZ1bmN0aW9uUHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5mdW5jdGlvbnNbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDI1LCB3aXJlVHlwZSAyID0qLyAyMDIpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE1vZGVsUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5Nb2RlbFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JTW9kZWxQcm90b30gbWVzc2FnZSBNb2RlbFByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgTW9kZWxQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguTW9kZWxQcm90b30gTW9kZWxQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgTW9kZWxQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5Nb2RlbFByb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgbWVzc2FnZS5pclZlcnNpb24gPSByZWFkZXIuaW50NjQoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDg6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uub3BzZXRJbXBvcnQgJiYgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGgpKSBtZXNzYWdlLm9wc2V0SW1wb3J0ID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLm9wc2V0SW1wb3J0LnB1c2goJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICBtZXNzYWdlLnByb2R1Y2VyTmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDM6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNDoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb21haW4gPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA1OiB7XG4gICAgICAgICAgICBtZXNzYWdlLm1vZGVsVmVyc2lvbiA9IHJlYWRlci5pbnQ2NCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNjoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA3OiB7XG4gICAgICAgICAgICBtZXNzYWdlLmdyYXBoID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxNDoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5tZXRhZGF0YVByb3BzICYmIG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5sZW5ndGgpKSBtZXNzYWdlLm1ldGFkYXRhUHJvcHMgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5wdXNoKCRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDIwOiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLnRyYWluaW5nSW5mbyAmJiBtZXNzYWdlLnRyYWluaW5nSW5mby5sZW5ndGgpKSBtZXNzYWdlLnRyYWluaW5nSW5mbyA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS50cmFpbmluZ0luZm8ucHVzaCgkcm9vdC5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjU6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZnVuY3Rpb25zICYmIG1lc3NhZ2UuZnVuY3Rpb25zLmxlbmd0aCkpIG1lc3NhZ2UuZnVuY3Rpb25zID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmZ1bmN0aW9ucy5wdXNoKCRyb290Lm9ubnguRnVuY3Rpb25Qcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgTW9kZWxQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54Lk1vZGVsUHJvdG99IE1vZGVsUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIE1vZGVsUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIE1vZGVsUHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuaXJWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaXJWZXJzaW9uJykpXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaXJWZXJzaW9uKSAmJlxuICAgICAgICAgICEobWVzc2FnZS5pclZlcnNpb24gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaXJWZXJzaW9uLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaXJWZXJzaW9uLmhpZ2gpKVxuICAgICAgICApXG4gICAgICAgICAgcmV0dXJuICdpclZlcnNpb246IGludGVnZXJ8TG9uZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5vcHNldEltcG9ydCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ29wc2V0SW1wb3J0JykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uub3BzZXRJbXBvcnQpKSByZXR1cm4gJ29wc2V0SW1wb3J0OiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLnZlcmlmeShtZXNzYWdlLm9wc2V0SW1wb3J0W2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnb3BzZXRJbXBvcnQuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5wcm9kdWNlck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdwcm9kdWNlck5hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnByb2R1Y2VyTmFtZSkpIHJldHVybiAncHJvZHVjZXJOYW1lOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncHJvZHVjZXJWZXJzaW9uJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5wcm9kdWNlclZlcnNpb24pKSByZXR1cm4gJ3Byb2R1Y2VyVmVyc2lvbjogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvbWFpbicpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9tYWluKSkgcmV0dXJuICdkb21haW46IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5tb2RlbFZlcnNpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdtb2RlbFZlcnNpb24nKSlcbiAgICAgICAgaWYgKFxuICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5tb2RlbFZlcnNpb24pICYmXG4gICAgICAgICAgIShcbiAgICAgICAgICAgIG1lc3NhZ2UubW9kZWxWZXJzaW9uICYmXG4gICAgICAgICAgICAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5tb2RlbFZlcnNpb24ubG93KSAmJlxuICAgICAgICAgICAgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UubW9kZWxWZXJzaW9uLmhpZ2gpXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICAgICAgcmV0dXJuICdtb2RlbFZlcnNpb246IGludGVnZXJ8TG9uZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvY1N0cmluZykpIHJldHVybiAnZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuZ3JhcGggIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdncmFwaCcpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguR3JhcGhQcm90by52ZXJpZnkobWVzc2FnZS5ncmFwaCk7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdncmFwaC4nICsgZXJyb3I7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5tZXRhZGF0YVByb3BzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbWV0YWRhdGFQcm9wcycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm1ldGFkYXRhUHJvcHMpKSByZXR1cm4gJ21ldGFkYXRhUHJvcHM6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm1ldGFkYXRhUHJvcHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5KG1lc3NhZ2UubWV0YWRhdGFQcm9wc1tpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ21ldGFkYXRhUHJvcHMuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS50cmFpbmluZ0luZm8gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0cmFpbmluZ0luZm8nKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS50cmFpbmluZ0luZm8pKSByZXR1cm4gJ3RyYWluaW5nSW5mbzogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudHJhaW5pbmdJbmZvLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90by52ZXJpZnkobWVzc2FnZS50cmFpbmluZ0luZm9baV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICd0cmFpbmluZ0luZm8uJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5mdW5jdGlvbnMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdmdW5jdGlvbnMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5mdW5jdGlvbnMpKSByZXR1cm4gJ2Z1bmN0aW9uczogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZnVuY3Rpb25zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5GdW5jdGlvblByb3RvLnZlcmlmeShtZXNzYWdlLmZ1bmN0aW9uc1tpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2Z1bmN0aW9ucy4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgTW9kZWxQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5Nb2RlbFByb3RvfSBNb2RlbFByb3RvXG4gICAgICovXG4gICAgTW9kZWxQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54Lk1vZGVsUHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54Lk1vZGVsUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QuaXJWZXJzaW9uICE9IG51bGwpXG4gICAgICAgIGlmICgkdXRpbC5Mb25nKSAobWVzc2FnZS5pclZlcnNpb24gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuaXJWZXJzaW9uKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pclZlcnNpb24gPT09ICdzdHJpbmcnKSBtZXNzYWdlLmlyVmVyc2lvbiA9IHBhcnNlSW50KG9iamVjdC5pclZlcnNpb24sIDEwKTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pclZlcnNpb24gPT09ICdudW1iZXInKSBtZXNzYWdlLmlyVmVyc2lvbiA9IG9iamVjdC5pclZlcnNpb247XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaXJWZXJzaW9uID09PSAnb2JqZWN0JylcbiAgICAgICAgICBtZXNzYWdlLmlyVmVyc2lvbiA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuaXJWZXJzaW9uLmxvdyA+Pj4gMCwgb2JqZWN0LmlyVmVyc2lvbi5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgaWYgKG9iamVjdC5vcHNldEltcG9ydCkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0Lm9wc2V0SW1wb3J0KSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLm9wc2V0SW1wb3J0OiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLm9wc2V0SW1wb3J0ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm9wc2V0SW1wb3J0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Qub3BzZXRJbXBvcnRbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLm9wc2V0SW1wb3J0OiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLm9wc2V0SW1wb3J0W2ldID0gJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8uZnJvbU9iamVjdChvYmplY3Qub3BzZXRJbXBvcnRbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnByb2R1Y2VyTmFtZSAhPSBudWxsKSBtZXNzYWdlLnByb2R1Y2VyTmFtZSA9IFN0cmluZyhvYmplY3QucHJvZHVjZXJOYW1lKTtcbiAgICAgIGlmIChvYmplY3QucHJvZHVjZXJWZXJzaW9uICE9IG51bGwpIG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uID0gU3RyaW5nKG9iamVjdC5wcm9kdWNlclZlcnNpb24pO1xuICAgICAgaWYgKG9iamVjdC5kb21haW4gIT0gbnVsbCkgbWVzc2FnZS5kb21haW4gPSBTdHJpbmcob2JqZWN0LmRvbWFpbik7XG4gICAgICBpZiAob2JqZWN0Lm1vZGVsVmVyc2lvbiAhPSBudWxsKVxuICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UubW9kZWxWZXJzaW9uID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0Lm1vZGVsVmVyc2lvbikpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QubW9kZWxWZXJzaW9uID09PSAnc3RyaW5nJykgbWVzc2FnZS5tb2RlbFZlcnNpb24gPSBwYXJzZUludChvYmplY3QubW9kZWxWZXJzaW9uLCAxMCk7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QubW9kZWxWZXJzaW9uID09PSAnbnVtYmVyJykgbWVzc2FnZS5tb2RlbFZlcnNpb24gPSBvYmplY3QubW9kZWxWZXJzaW9uO1xuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0Lm1vZGVsVmVyc2lvbiA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgbWVzc2FnZS5tb2RlbFZlcnNpb24gPSBuZXcgJHV0aWwuTG9uZ0JpdHMoXG4gICAgICAgICAgICBvYmplY3QubW9kZWxWZXJzaW9uLmxvdyA+Pj4gMCxcbiAgICAgICAgICAgIG9iamVjdC5tb2RlbFZlcnNpb24uaGlnaCA+Pj4gMCxcbiAgICAgICAgICApLnRvTnVtYmVyKCk7XG4gICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKSBtZXNzYWdlLmRvY1N0cmluZyA9IFN0cmluZyhvYmplY3QuZG9jU3RyaW5nKTtcbiAgICAgIGlmIChvYmplY3QuZ3JhcGggIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5ncmFwaCAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguTW9kZWxQcm90by5ncmFwaDogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuZ3JhcGggPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZ3JhcGgpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5tZXRhZGF0YVByb3BzKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QubWV0YWRhdGFQcm9wcykpIHRocm93IFR5cGVFcnJvcignLm9ubnguTW9kZWxQcm90by5tZXRhZGF0YVByb3BzOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLm1ldGFkYXRhUHJvcHMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubWV0YWRhdGFQcm9wcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm1ldGFkYXRhUHJvcHNbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLm1ldGFkYXRhUHJvcHM6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UubWV0YWRhdGFQcm9wc1tpXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5mcm9tT2JqZWN0KG9iamVjdC5tZXRhZGF0YVByb3BzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC50cmFpbmluZ0luZm8pIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC50cmFpbmluZ0luZm8pKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54Lk1vZGVsUHJvdG8udHJhaW5pbmdJbmZvOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnRyYWluaW5nSW5mbyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC50cmFpbmluZ0luZm8ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC50cmFpbmluZ0luZm9baV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLnRyYWluaW5nSW5mbzogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS50cmFpbmluZ0luZm9baV0gPSAkcm9vdC5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmZyb21PYmplY3Qob2JqZWN0LnRyYWluaW5nSW5mb1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZnVuY3Rpb25zKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZnVuY3Rpb25zKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLmZ1bmN0aW9uczogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5mdW5jdGlvbnMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZnVuY3Rpb25zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZnVuY3Rpb25zW2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLmZ1bmN0aW9uczogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5mdW5jdGlvbnNbaV0gPSAkcm9vdC5vbm54LkZ1bmN0aW9uUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZnVuY3Rpb25zW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIE1vZGVsUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54Lk1vZGVsUHJvdG99IG1lc3NhZ2UgTW9kZWxQcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgTW9kZWxQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0Lm9wc2V0SW1wb3J0ID0gW107XG4gICAgICAgIG9iamVjdC5tZXRhZGF0YVByb3BzID0gW107XG4gICAgICAgIG9iamVjdC50cmFpbmluZ0luZm8gPSBbXTtcbiAgICAgICAgb2JqZWN0LmZ1bmN0aW9ucyA9IFtdO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgaWYgKCR1dGlsLkxvbmcpIHtcbiAgICAgICAgICB2YXIgbG9uZyA9IG5ldyAkdXRpbC5Mb25nKDAsIDAsIGZhbHNlKTtcbiAgICAgICAgICBvYmplY3QuaXJWZXJzaW9uID1cbiAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgIH0gZWxzZSBvYmplY3QuaXJWZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJzAnIDogMDtcbiAgICAgICAgb2JqZWN0LnByb2R1Y2VyTmFtZSA9ICcnO1xuICAgICAgICBvYmplY3QucHJvZHVjZXJWZXJzaW9uID0gJyc7XG4gICAgICAgIG9iamVjdC5kb21haW4gPSAnJztcbiAgICAgICAgaWYgKCR1dGlsLkxvbmcpIHtcbiAgICAgICAgICB2YXIgbG9uZyA9IG5ldyAkdXRpbC5Mb25nKDAsIDAsIGZhbHNlKTtcbiAgICAgICAgICBvYmplY3QubW9kZWxWZXJzaW9uID1cbiAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgIH0gZWxzZSBvYmplY3QubW9kZWxWZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJzAnIDogMDtcbiAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9ICcnO1xuICAgICAgICBvYmplY3QuZ3JhcGggPSBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaXJWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaXJWZXJzaW9uJykpXG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5pclZlcnNpb24gPT09ICdudW1iZXInKVxuICAgICAgICAgIG9iamVjdC5pclZlcnNpb24gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS5pclZlcnNpb24pIDogbWVzc2FnZS5pclZlcnNpb247XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBvYmplY3QuaXJWZXJzaW9uID1cbiAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZ1xuICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5pclZlcnNpb24pXG4gICAgICAgICAgICAgIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyXG4gICAgICAgICAgICAgICAgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS5pclZlcnNpb24ubG93ID4+PiAwLCBtZXNzYWdlLmlyVmVyc2lvbi5oaWdoID4+PiAwKS50b051bWJlcigpXG4gICAgICAgICAgICAgICAgOiBtZXNzYWdlLmlyVmVyc2lvbjtcbiAgICAgIGlmIChtZXNzYWdlLnByb2R1Y2VyTmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3Byb2R1Y2VyTmFtZScpKVxuICAgICAgICBvYmplY3QucHJvZHVjZXJOYW1lID0gbWVzc2FnZS5wcm9kdWNlck5hbWU7XG4gICAgICBpZiAobWVzc2FnZS5wcm9kdWNlclZlcnNpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdwcm9kdWNlclZlcnNpb24nKSlcbiAgICAgICAgb2JqZWN0LnByb2R1Y2VyVmVyc2lvbiA9IG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9tYWluJykpIG9iamVjdC5kb21haW4gPSBtZXNzYWdlLmRvbWFpbjtcbiAgICAgIGlmIChtZXNzYWdlLm1vZGVsVmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ21vZGVsVmVyc2lvbicpKVxuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UubW9kZWxWZXJzaW9uID09PSAnbnVtYmVyJylcbiAgICAgICAgICBvYmplY3QubW9kZWxWZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UubW9kZWxWZXJzaW9uKSA6IG1lc3NhZ2UubW9kZWxWZXJzaW9uO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgb2JqZWN0Lm1vZGVsVmVyc2lvbiA9XG4gICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UubW9kZWxWZXJzaW9uKVxuICAgICAgICAgICAgICA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlclxuICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UubW9kZWxWZXJzaW9uLmxvdyA+Pj4gMCwgbWVzc2FnZS5tb2RlbFZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgIDogbWVzc2FnZS5tb2RlbFZlcnNpb247XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSkgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgaWYgKG1lc3NhZ2UuZ3JhcGggIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdncmFwaCcpKVxuICAgICAgICBvYmplY3QuZ3JhcGggPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udG9PYmplY3QobWVzc2FnZS5ncmFwaCwgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS5vcHNldEltcG9ydCAmJiBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aCkge1xuICAgICAgICBvYmplY3Qub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5vcHNldEltcG9ydFtqXSA9ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uub3BzZXRJbXBvcnRbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubWV0YWRhdGFQcm9wcyAmJiBtZXNzYWdlLm1ldGFkYXRhUHJvcHMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5tZXRhZGF0YVByb3BzID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5tZXRhZGF0YVByb3BzLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5tZXRhZGF0YVByb3BzW2pdID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UubWV0YWRhdGFQcm9wc1tqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS50cmFpbmluZ0luZm8gJiYgbWVzc2FnZS50cmFpbmluZ0luZm8ubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC50cmFpbmluZ0luZm8gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnRyYWluaW5nSW5mby5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QudHJhaW5pbmdJbmZvW2pdID0gJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90by50b09iamVjdChtZXNzYWdlLnRyYWluaW5nSW5mb1tqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5mdW5jdGlvbnMgJiYgbWVzc2FnZS5mdW5jdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5mdW5jdGlvbnMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmZ1bmN0aW9ucy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuZnVuY3Rpb25zW2pdID0gJHJvb3Qub25ueC5GdW5jdGlvblByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZnVuY3Rpb25zW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgTW9kZWxQcm90byB0byBKU09OLlxuICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBNb2RlbFByb3RvXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICovXG4gICAgTW9kZWxQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5Nb2RlbFByb3RvJztcbiAgICB9O1xuXG4gICAgcmV0dXJuIE1vZGVsUHJvdG87XG4gIH0pKCk7XG5cbiAgb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBba2V5XSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIGtleVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFt2YWx1ZV0gU3RyaW5nU3RyaW5nRW50cnlQcm90byB2YWx1ZVxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ocHJvcGVydGllcykge1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ga2V5LlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30ga2V5XG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ucHJvdG90eXBlLmtleSA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogU3RyaW5nU3RyaW5nRW50cnlQcm90byB2YWx1ZS5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IHZhbHVlXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ucHJvdG90eXBlLnZhbHVlID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IG1lc3NhZ2UgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLmtleSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdrZXknKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuc3RyaW5nKG1lc3NhZ2Uua2V5KTtcbiAgICAgIGlmIChtZXNzYWdlLnZhbHVlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3ZhbHVlJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLnN0cmluZyhtZXNzYWdlLnZhbHVlKTtcbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IG1lc3NhZ2UgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIG1lc3NhZ2Uua2V5ID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS52YWx1ZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2Uua2V5ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgna2V5JykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5rZXkpKSByZXR1cm4gJ2tleTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLnZhbHVlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnZhbHVlKSkgcmV0dXJuICd2YWx1ZTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvfSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICovXG4gICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3Qua2V5ICE9IG51bGwpIG1lc3NhZ2Uua2V5ID0gU3RyaW5nKG9iamVjdC5rZXkpO1xuICAgICAgaWYgKG9iamVjdC52YWx1ZSAhPSBudWxsKSBtZXNzYWdlLnZhbHVlID0gU3RyaW5nKG9iamVjdC52YWx1ZSk7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b30gbWVzc2FnZSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3Qua2V5ID0gJyc7XG4gICAgICAgIG9iamVjdC52YWx1ZSA9ICcnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uua2V5ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgna2V5JykpIG9iamVjdC5rZXkgPSBtZXNzYWdlLmtleTtcbiAgICAgIGlmIChtZXNzYWdlLnZhbHVlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWUnKSkgb2JqZWN0LnZhbHVlID0gbWVzc2FnZS52YWx1ZTtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgU3RyaW5nU3RyaW5nRW50cnlQcm90byB0byBKU09OLlxuICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBTdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICovXG4gICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvJztcbiAgICB9O1xuXG4gICAgcmV0dXJuIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG87XG4gIH0pKCk7XG5cbiAgb25ueC5UZW5zb3JBbm5vdGF0aW9uID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgVGVuc29yQW5ub3RhdGlvbi5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSVRlbnNvckFubm90YXRpb25cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbdGVuc29yTmFtZV0gVGVuc29yQW5ub3RhdGlvbiB0ZW5zb3JOYW1lXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz58bnVsbH0gW3F1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNdIFRlbnNvckFubm90YXRpb24gcXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1xuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBUZW5zb3JBbm5vdGF0aW9uLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgVGVuc29yQW5ub3RhdGlvbi5cbiAgICAgKiBAaW1wbGVtZW50cyBJVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yQW5ub3RhdGlvbj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIFRlbnNvckFubm90YXRpb24ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGVuc29yQW5ub3RhdGlvbiB0ZW5zb3JOYW1lLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gdGVuc29yTmFtZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JBbm5vdGF0aW9uLnByb3RvdHlwZS50ZW5zb3JOYW1lID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JBbm5vdGF0aW9uIHF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fSBxdWFudFBhcmFtZXRlclRlbnNvck5hbWVzXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24ucHJvdG90eXBlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBUZW5zb3JBbm5vdGF0aW9uIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvckFubm90YXRpb249fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JBbm5vdGF0aW9ufSBUZW5zb3JBbm5vdGF0aW9uIGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yQW5ub3RhdGlvbi5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBUZW5zb3JBbm5vdGF0aW9uKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yQW5ub3RhdGlvbiBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvckFubm90YXRpb24udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JBbm5vdGF0aW9ufSBtZXNzYWdlIFRlbnNvckFubm90YXRpb24gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS50ZW5zb3JOYW1lICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3RlbnNvck5hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuc3RyaW5nKG1lc3NhZ2UudGVuc29yTmFtZSk7XG4gICAgICBpZiAobWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzICE9IG51bGwgJiYgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvckFubm90YXRpb24gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JBbm5vdGF0aW9uLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yQW5ub3RhdGlvbn0gbWVzc2FnZSBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBUZW5zb3JBbm5vdGF0aW9uLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVGVuc29yQW5ub3RhdGlvbiBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yQW5ub3RhdGlvbn0gVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVGVuc29yQW5ub3RhdGlvbi5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgbWVzc2FnZS50ZW5zb3JOYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzICYmIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5sZW5ndGgpKVxuICAgICAgICAgICAgICBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5wdXNoKCRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVGVuc29yQW5ub3RhdGlvbiBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvckFubm90YXRpb259IFRlbnNvckFubm90YXRpb25cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIFRlbnNvckFubm90YXRpb24gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UudGVuc29yTmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3RlbnNvck5hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnRlbnNvck5hbWUpKSByZXR1cm4gJ3RlbnNvck5hbWU6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMpKSByZXR1cm4gJ3F1YW50UGFyYW1ldGVyVGVuc29yTmFtZXM6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5KG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3F1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFRlbnNvckFubm90YXRpb24gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yQW5ub3RhdGlvbn0gVGVuc29yQW5ub3RhdGlvblxuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uKSByZXR1cm4gb2JqZWN0O1xuICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uKCk7XG4gICAgICBpZiAob2JqZWN0LnRlbnNvck5hbWUgIT0gbnVsbCkgbWVzc2FnZS50ZW5zb3JOYW1lID0gU3RyaW5nKG9iamVjdC50ZW5zb3JOYW1lKTtcbiAgICAgIGlmIChvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMpKVxuICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yQW5ub3RhdGlvbi5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JBbm5vdGF0aW9uLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXM6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tpXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5mcm9tT2JqZWN0KFxuICAgICAgICAgICAgb2JqZWN0LnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNbaV0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFRlbnNvckFubm90YXRpb24gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LlRlbnNvckFubm90YXRpb259IG1lc3NhZ2UgVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgVGVuc29yQW5ub3RhdGlvbi50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykgb2JqZWN0LnRlbnNvck5hbWUgPSAnJztcbiAgICAgIGlmIChtZXNzYWdlLnRlbnNvck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0ZW5zb3JOYW1lJykpIG9iamVjdC50ZW5zb3JOYW1lID0gbWVzc2FnZS50ZW5zb3JOYW1lO1xuICAgICAgaWYgKG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyAmJiBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzW2pdID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnRvT2JqZWN0KFxuICAgICAgICAgICAgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzW2pdLFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBUZW5zb3JBbm5vdGF0aW9uIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgVGVuc29yQW5ub3RhdGlvbi5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFRlbnNvckFubm90YXRpb25cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBUZW5zb3JBbm5vdGF0aW9uLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlRlbnNvckFubm90YXRpb24nO1xuICAgIH07XG5cbiAgICByZXR1cm4gVGVuc29yQW5ub3RhdGlvbjtcbiAgfSkoKTtcblxuICBvbm54LkdyYXBoUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYSBHcmFwaFByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGludGVyZmFjZSBJR3JhcGhQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSU5vZGVQcm90bz58bnVsbH0gW25vZGVdIEdyYXBoUHJvdG8gbm9kZVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtuYW1lXSBHcmFwaFByb3RvIG5hbWVcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklUZW5zb3JQcm90bz58bnVsbH0gW2luaXRpYWxpemVyXSBHcmFwaFByb3RvIGluaXRpYWxpemVyXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JU3BhcnNlVGVuc29yUHJvdG8+fG51bGx9IFtzcGFyc2VJbml0aWFsaXplcl0gR3JhcGhQcm90byBzcGFyc2VJbml0aWFsaXplclxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb2NTdHJpbmddIEdyYXBoUHJvdG8gZG9jU3RyaW5nXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JVmFsdWVJbmZvUHJvdG8+fG51bGx9IFtpbnB1dF0gR3JhcGhQcm90byBpbnB1dFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPnxudWxsfSBbb3V0cHV0XSBHcmFwaFByb3RvIG91dHB1dFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPnxudWxsfSBbdmFsdWVJbmZvXSBHcmFwaFByb3RvIHZhbHVlSW5mb1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVRlbnNvckFubm90YXRpb24+fG51bGx9IFtxdWFudGl6YXRpb25Bbm5vdGF0aW9uXSBHcmFwaFByb3RvIHF1YW50aXphdGlvbkFubm90YXRpb25cbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgR3JhcGhQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIEdyYXBoUHJvdG8uXG4gICAgICogQGltcGxlbWVudHMgSUdyYXBoUHJvdG9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29ubnguSUdyYXBoUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBHcmFwaFByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgIHRoaXMubm9kZSA9IFtdO1xuICAgICAgdGhpcy5pbml0aWFsaXplciA9IFtdO1xuICAgICAgdGhpcy5zcGFyc2VJbml0aWFsaXplciA9IFtdO1xuICAgICAgdGhpcy5pbnB1dCA9IFtdO1xuICAgICAgdGhpcy5vdXRwdXQgPSBbXTtcbiAgICAgIHRoaXMudmFsdWVJbmZvID0gW107XG4gICAgICB0aGlzLnF1YW50aXphdGlvbkFubm90YXRpb24gPSBbXTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHcmFwaFByb3RvIG5vZGUuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSU5vZGVQcm90bz59IG5vZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUubm9kZSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBHcmFwaFByb3RvIG5hbWUuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBuYW1lXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLm5hbWUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIEdyYXBoUHJvdG8gaW5pdGlhbGl6ZXIuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVRlbnNvclByb3RvPn0gaW5pdGlhbGl6ZXJcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUuaW5pdGlhbGl6ZXIgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogR3JhcGhQcm90byBzcGFyc2VJbml0aWFsaXplci5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JU3BhcnNlVGVuc29yUHJvdG8+fSBzcGFyc2VJbml0aWFsaXplclxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLnByb3RvdHlwZS5zcGFyc2VJbml0aWFsaXplciA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBHcmFwaFByb3RvIGRvY1N0cmluZy5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSAnJztcblxuICAgIC8qKlxuICAgICAqIEdyYXBoUHJvdG8gaW5wdXQuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPn0gaW5wdXRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUuaW5wdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogR3JhcGhQcm90byBvdXRwdXQuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPn0gb3V0cHV0XG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLm91dHB1dCA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBHcmFwaFByb3RvIHZhbHVlSW5mby5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVmFsdWVJbmZvUHJvdG8+fSB2YWx1ZUluZm9cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUudmFsdWVJbmZvID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIEdyYXBoUHJvdG8gcXVhbnRpemF0aW9uQW5ub3RhdGlvbi5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVGVuc29yQW5ub3RhdGlvbj59IHF1YW50aXphdGlvbkFubm90YXRpb25cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUucXVhbnRpemF0aW9uQW5ub3RhdGlvbiA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IEdyYXBoUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JR3JhcGhQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54LkdyYXBoUHJvdG99IEdyYXBoUHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IEdyYXBoUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBHcmFwaFByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguR3JhcGhQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSUdyYXBoUHJvdG99IG1lc3NhZ2UgR3JhcGhQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgR3JhcGhQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLm5vZGUgIT0gbnVsbCAmJiBtZXNzYWdlLm5vZGUubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uubm9kZS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54Lk5vZGVQcm90by5lbmNvZGUobWVzc2FnZS5ub2RlW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovIDEwKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICduYW1lJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgaWYgKG1lc3NhZ2UuaW5pdGlhbGl6ZXIgIT0gbnVsbCAmJiBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguVGVuc29yUHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXplcltpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki8gNDIpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RvY1N0cmluZycpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEwLCB3aXJlVHlwZSAyID0qLyA4Mikuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgIGlmIChtZXNzYWdlLmlucHV0ICE9IG51bGwgJiYgbWVzc2FnZS5pbnB1dC5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXRbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDExLCB3aXJlVHlwZSAyID0qLyA5MCkuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5vdXRwdXQgIT0gbnVsbCAmJiBtZXNzYWdlLm91dHB1dC5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLm91dHB1dFtpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTIsIHdpcmVUeXBlIDIgPSovIDk4KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLnZhbHVlSW5mbyAhPSBudWxsICYmIG1lc3NhZ2UudmFsdWVJbmZvLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UudmFsdWVJbmZvW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMywgd2lyZVR5cGUgMiA9Ki8gMTA2KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbi5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvckFubm90YXRpb24uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxNCwgd2lyZVR5cGUgMiA9Ki8gMTE0KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyICE9IG51bGwgJiYgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplci5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplci5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXJbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDE1LCB3aXJlVHlwZSAyID0qLyAxMjIpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIEdyYXBoUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5HcmFwaFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JR3JhcGhQcm90b30gbWVzc2FnZSBHcmFwaFByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgR3JhcGhQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguR3JhcGhQcm90b30gR3JhcGhQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgR3JhcGhQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5HcmFwaFByb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5ub2RlICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpKSBtZXNzYWdlLm5vZGUgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uubm9kZS5wdXNoKCRyb290Lm9ubnguTm9kZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS5uYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbml0aWFsaXplciAmJiBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aCkpIG1lc3NhZ2UuaW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6ZXIucHVzaCgkcm9vdC5vbm54LlRlbnNvclByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTU6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXIgJiYgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplci5sZW5ndGgpKSBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyLnB1c2goJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDEwOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmRvY1N0cmluZyA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDExOiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmlucHV0ICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKSkgbWVzc2FnZS5pbnB1dCA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5pbnB1dC5wdXNoKCRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMjoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSkgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0LnB1c2goJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDEzOiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLnZhbHVlSW5mbyAmJiBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGgpKSBtZXNzYWdlLnZhbHVlSW5mbyA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS52YWx1ZUluZm8ucHVzaCgkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTQ6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiAmJiBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoKSlcbiAgICAgICAgICAgICAgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ucHVzaCgkcm9vdC5vbm54LlRlbnNvckFubm90YXRpb24uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIEdyYXBoUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcmV0dXJucyB7b25ueC5HcmFwaFByb3RvfSBHcmFwaFByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYSBHcmFwaFByb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLm5vZGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdub2RlJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uubm9kZSkpIHJldHVybiAnbm9kZTogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uubm9kZS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguTm9kZVByb3RvLnZlcmlmeShtZXNzYWdlLm5vZGVbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdub2RlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm5hbWUpKSByZXR1cm4gJ25hbWU6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXplciAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2luaXRpYWxpemVyJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuaW5pdGlhbGl6ZXIpKSByZXR1cm4gJ2luaXRpYWxpemVyOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbml0aWFsaXplci5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udmVyaWZ5KG1lc3NhZ2UuaW5pdGlhbGl6ZXJbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdpbml0aWFsaXplci4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc3BhcnNlSW5pdGlhbGl6ZXInKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5zcGFyc2VJbml0aWFsaXplcikpIHJldHVybiAnc3BhcnNlSW5pdGlhbGl6ZXI6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS5zcGFyc2VJbml0aWFsaXplcltpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3NwYXJzZUluaXRpYWxpemVyLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpKSByZXR1cm4gJ2RvY1N0cmluZzogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmlucHV0ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaW5wdXQnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnB1dCkpIHJldHVybiAnaW5wdXQ6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by52ZXJpZnkobWVzc2FnZS5pbnB1dFtpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2lucHV0LicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnb3V0cHV0JykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uub3V0cHV0KSkgcmV0dXJuICdvdXRwdXQ6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm91dHB1dC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udmVyaWZ5KG1lc3NhZ2Uub3V0cHV0W2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnb3V0cHV0LicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudmFsdWVJbmZvICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWVJbmZvJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudmFsdWVJbmZvKSkgcmV0dXJuICd2YWx1ZUluZm86IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udmVyaWZ5KG1lc3NhZ2UudmFsdWVJbmZvW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAndmFsdWVJbmZvLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3F1YW50aXphdGlvbkFubm90YXRpb24nKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uKSkgcmV0dXJuICdxdWFudGl6YXRpb25Bbm5vdGF0aW9uOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uLnZlcmlmeShtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb25baV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdxdWFudGl6YXRpb25Bbm5vdGF0aW9uLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBHcmFwaFByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54LkdyYXBoUHJvdG99IEdyYXBoUHJvdG9cbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguR3JhcGhQcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguR3JhcGhQcm90bygpO1xuICAgICAgaWYgKG9iamVjdC5ub2RlKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Qubm9kZSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguR3JhcGhQcm90by5ub2RlOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLm5vZGUgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Qubm9kZS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm5vZGVbaV0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8ubm9kZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5ub2RlW2ldID0gJHJvb3Qub25ueC5Ob2RlUHJvdG8uZnJvbU9iamVjdChvYmplY3Qubm9kZVtpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QubmFtZSAhPSBudWxsKSBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgaWYgKG9iamVjdC5pbml0aWFsaXplcikge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmluaXRpYWxpemVyKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLmluaXRpYWxpemVyOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmluaXRpYWxpemVyID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmluaXRpYWxpemVyLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5pdGlhbGl6ZXJbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLmluaXRpYWxpemVyOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLmluaXRpYWxpemVyW2ldID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC5pbml0aWFsaXplcltpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXIpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5zcGFyc2VJbml0aWFsaXplcikpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLnNwYXJzZUluaXRpYWxpemVyOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LnNwYXJzZUluaXRpYWxpemVyLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXJbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLnNwYXJzZUluaXRpYWxpemVyOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyW2ldID0gJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC5zcGFyc2VJbml0aWFsaXplcltpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZG9jU3RyaW5nICE9IG51bGwpIG1lc3NhZ2UuZG9jU3RyaW5nID0gU3RyaW5nKG9iamVjdC5kb2NTdHJpbmcpO1xuICAgICAgaWYgKG9iamVjdC5pbnB1dCkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmlucHV0KSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLmlucHV0OiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmlucHV0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5wdXRbaV0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8uaW5wdXQ6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuaW5wdXRbaV0gPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmZyb21PYmplY3Qob2JqZWN0LmlucHV0W2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5vdXRwdXQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5vdXRwdXQpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8ub3V0cHV0OiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLm91dHB1dCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5vdXRwdXQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5vdXRwdXRbaV0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8ub3V0cHV0OiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLm91dHB1dFtpXSA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZnJvbU9iamVjdChvYmplY3Qub3V0cHV0W2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC52YWx1ZUluZm8pIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC52YWx1ZUluZm8pKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8udmFsdWVJbmZvOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnZhbHVlSW5mbyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC52YWx1ZUluZm8ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC52YWx1ZUluZm9baV0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8udmFsdWVJbmZvOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLnZhbHVlSW5mb1tpXSA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZnJvbU9iamVjdChvYmplY3QudmFsdWVJbmZvW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QucXVhbnRpemF0aW9uQW5ub3RhdGlvbikpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLnF1YW50aXphdGlvbkFubm90YXRpb246IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QucXVhbnRpemF0aW9uQW5ub3RhdGlvbltpXSAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8ucXVhbnRpemF0aW9uQW5ub3RhdGlvbjogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2ldID0gJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uLmZyb21PYmplY3Qob2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb25baV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgR3JhcGhQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguR3JhcGhQcm90b30gbWVzc2FnZSBHcmFwaFByb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3Qubm9kZSA9IFtdO1xuICAgICAgICBvYmplY3QuaW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgICAgb2JqZWN0LmlucHV0ID0gW107XG4gICAgICAgIG9iamVjdC5vdXRwdXQgPSBbXTtcbiAgICAgICAgb2JqZWN0LnZhbHVlSW5mbyA9IFtdO1xuICAgICAgICBvYmplY3QucXVhbnRpemF0aW9uQW5ub3RhdGlvbiA9IFtdO1xuICAgICAgICBvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5uYW1lID0gJyc7XG4gICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSAnJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm5vZGUgJiYgbWVzc2FnZS5ub2RlLmxlbmd0aCkge1xuICAgICAgICBvYmplY3Qubm9kZSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uubm9kZS5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3Qubm9kZVtqXSA9ICRyb290Lm9ubnguTm9kZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uubm9kZVtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpKSBvYmplY3QubmFtZSA9IG1lc3NhZ2UubmFtZTtcbiAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemVyICYmIG1lc3NhZ2UuaW5pdGlhbGl6ZXIubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5pbml0aWFsaXplciA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW5pdGlhbGl6ZXIubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LmluaXRpYWxpemVyW2pdID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by50b09iamVjdChtZXNzYWdlLmluaXRpYWxpemVyW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKSBvYmplY3QuZG9jU3RyaW5nID0gbWVzc2FnZS5kb2NTdHJpbmc7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuaW5wdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5pbnB1dFtqXSA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udG9PYmplY3QobWVzc2FnZS5pbnB1dFtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5vdXRwdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLm91dHB1dC5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3Qub3V0cHV0W2pdID0gJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by50b09iamVjdChtZXNzYWdlLm91dHB1dFtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS52YWx1ZUluZm8gJiYgbWVzc2FnZS52YWx1ZUluZm8ubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC52YWx1ZUluZm8gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QudmFsdWVJbmZvW2pdID0gJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by50b09iamVjdChtZXNzYWdlLnZhbHVlSW5mb1tqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uICYmIG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbi5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb24gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb25bal0gPSAkcm9vdC5vbm54LlRlbnNvckFubm90YXRpb24udG9PYmplY3QoXG4gICAgICAgICAgICBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb25bal0sXG4gICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VJbml0aWFsaXplciAmJiBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyLmxlbmd0aCkge1xuICAgICAgICBvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5zcGFyc2VJbml0aWFsaXplcltqXSA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS5zcGFyc2VJbml0aWFsaXplcltqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIEdyYXBoUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgR3JhcGhQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIEdyYXBoUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguR3JhcGhQcm90byc7XG4gICAgfTtcblxuICAgIHJldHVybiBHcmFwaFByb3RvO1xuICB9KSgpO1xuXG4gIG9ubnguVGVuc29yUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYSBUZW5zb3JQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSVRlbnNvclByb3RvXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyfExvbmc+fG51bGx9IFtkaW1zXSBUZW5zb3JQcm90byBkaW1zXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ8bnVsbH0gW2RhdGFUeXBlXSBUZW5zb3JQcm90byBkYXRhVHlwZVxuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UZW5zb3JQcm90by5JU2VnbWVudHxudWxsfSBbc2VnbWVudF0gVGVuc29yUHJvdG8gc2VnbWVudFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcj58bnVsbH0gW2Zsb2F0RGF0YV0gVGVuc29yUHJvdG8gZmxvYXREYXRhXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyPnxudWxsfSBbaW50MzJEYXRhXSBUZW5zb3JQcm90byBpbnQzMkRhdGFcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxVaW50OEFycmF5PnxudWxsfSBbc3RyaW5nRGF0YV0gVGVuc29yUHJvdG8gc3RyaW5nRGF0YVxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcnxMb25nPnxudWxsfSBbaW50NjREYXRhXSBUZW5zb3JQcm90byBpbnQ2NERhdGFcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbbmFtZV0gVGVuc29yUHJvdG8gbmFtZVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb2NTdHJpbmddIFRlbnNvclByb3RvIGRvY1N0cmluZ1xuICAgICAqIEBwcm9wZXJ0eSB7VWludDhBcnJheXxudWxsfSBbcmF3RGF0YV0gVGVuc29yUHJvdG8gcmF3RGF0YVxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fG51bGx9IFtleHRlcm5hbERhdGFdIFRlbnNvclByb3RvIGV4dGVybmFsRGF0YVxuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UZW5zb3JQcm90by5EYXRhTG9jYXRpb258bnVsbH0gW2RhdGFMb2NhdGlvbl0gVGVuc29yUHJvdG8gZGF0YUxvY2F0aW9uXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyPnxudWxsfSBbZG91YmxlRGF0YV0gVGVuc29yUHJvdG8gZG91YmxlRGF0YVxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcnxMb25nPnxudWxsfSBbdWludDY0RGF0YV0gVGVuc29yUHJvdG8gdWludDY0RGF0YVxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBUZW5zb3JQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFRlbnNvclByb3RvLlxuICAgICAqIEBpbXBsZW1lbnRzIElUZW5zb3JQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBUZW5zb3JQcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLmRpbXMgPSBbXTtcbiAgICAgIHRoaXMuZmxvYXREYXRhID0gW107XG4gICAgICB0aGlzLmludDMyRGF0YSA9IFtdO1xuICAgICAgdGhpcy5zdHJpbmdEYXRhID0gW107XG4gICAgICB0aGlzLmludDY0RGF0YSA9IFtdO1xuICAgICAgdGhpcy5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgIHRoaXMuZG91YmxlRGF0YSA9IFtdO1xuICAgICAgdGhpcy51aW50NjREYXRhID0gW107XG4gICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gZGltcy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyfExvbmc+fSBkaW1zXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuZGltcyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBkYXRhVHlwZS5cbiAgICAgKiBAbWVtYmVyIHtudW1iZXJ9IGRhdGFUeXBlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuZGF0YVR5cGUgPSAwO1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gc2VnbWVudC5cbiAgICAgKiBAbWVtYmVyIHtvbm54LlRlbnNvclByb3RvLklTZWdtZW50fG51bGx8dW5kZWZpbmVkfSBzZWdtZW50XG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuc2VnbWVudCA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBmbG9hdERhdGEuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcj59IGZsb2F0RGF0YVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmZsb2F0RGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBpbnQzMkRhdGEuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcj59IGludDMyRGF0YVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmludDMyRGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBzdHJpbmdEYXRhLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxVaW50OEFycmF5Pn0gc3RyaW5nRGF0YVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLnN0cmluZ0RhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gaW50NjREYXRhLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXJ8TG9uZz59IGludDY0RGF0YVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmludDY0RGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBuYW1lLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLm5hbWUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIFRlbnNvclByb3RvIGRvY1N0cmluZy5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmRvY1N0cmluZyA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gcmF3RGF0YS5cbiAgICAgKiBAbWVtYmVyIHtVaW50OEFycmF5fSByYXdEYXRhXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5wcm90b3R5cGUucmF3RGF0YSA9ICR1dGlsLm5ld0J1ZmZlcihbXSk7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBleHRlcm5hbERhdGEuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fSBleHRlcm5hbERhdGFcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5leHRlcm5hbERhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gZGF0YUxvY2F0aW9uLlxuICAgICAqIEBtZW1iZXIge29ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9ufSBkYXRhTG9jYXRpb25cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5kYXRhTG9jYXRpb24gPSAwO1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gZG91YmxlRGF0YS5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyPn0gZG91YmxlRGF0YVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmRvdWJsZURhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gdWludDY0RGF0YS5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyfExvbmc+fSB1aW50NjREYXRhXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5wcm90b3R5cGUudWludDY0RGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IFRlbnNvclByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvfSBUZW5zb3JQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IFRlbnNvclByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JQcm90b30gbWVzc2FnZSBUZW5zb3JQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS5kaW1zICE9IG51bGwgJiYgbWVzc2FnZS5kaW1zLmxlbmd0aCkge1xuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovIDEwKS5mb3JrKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5kaW1zLmxlbmd0aDsgKytpKSB3cml0ZXIuaW50NjQobWVzc2FnZS5kaW1zW2ldKTtcbiAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZGF0YVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZGF0YVR5cGUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAwID0qLyAxNikuaW50MzIobWVzc2FnZS5kYXRhVHlwZSk7XG4gICAgICBpZiAobWVzc2FnZS5zZWdtZW50ICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3NlZ21lbnQnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JQcm90by5TZWdtZW50LmVuY29kZShcbiAgICAgICAgICBtZXNzYWdlLnNlZ21lbnQsXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAzLCB3aXJlVHlwZSAyID0qLyAyNikuZm9yaygpLFxuICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZmxvYXREYXRhICE9IG51bGwgJiYgbWVzc2FnZS5mbG9hdERhdGEubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNCwgd2lyZVR5cGUgMiA9Ki8gMzQpLmZvcmsoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmZsb2F0RGF0YS5sZW5ndGg7ICsraSkgd3JpdGVyLmZsb2F0KG1lc3NhZ2UuZmxvYXREYXRhW2ldKTtcbiAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaW50MzJEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5pbnQzMkRhdGEubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki8gNDIpLmZvcmsoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmludDMyRGF0YS5sZW5ndGg7ICsraSkgd3JpdGVyLmludDMyKG1lc3NhZ2UuaW50MzJEYXRhW2ldKTtcbiAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uuc3RyaW5nRGF0YSAhPSBudWxsICYmIG1lc3NhZ2Uuc3RyaW5nRGF0YS5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5zdHJpbmdEYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNiwgd2lyZVR5cGUgMiA9Ki8gNTApLmJ5dGVzKG1lc3NhZ2Uuc3RyaW5nRGF0YVtpXSk7XG4gICAgICBpZiAobWVzc2FnZS5pbnQ2NERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmludDY0RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA3LCB3aXJlVHlwZSAyID0qLyA1OCkuZm9yaygpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW50NjREYXRhLmxlbmd0aDsgKytpKSB3cml0ZXIuaW50NjQobWVzc2FnZS5pbnQ2NERhdGFbaV0pO1xuICAgICAgICB3cml0ZXIubGRlbGltKCk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ25hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA4LCB3aXJlVHlwZSAyID0qLyA2Nikuc3RyaW5nKG1lc3NhZ2UubmFtZSk7XG4gICAgICBpZiAobWVzc2FnZS5yYXdEYXRhICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3Jhd0RhdGEnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA5LCB3aXJlVHlwZSAyID0qLyA3NCkuYnl0ZXMobWVzc2FnZS5yYXdEYXRhKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvdWJsZURhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTAsIHdpcmVUeXBlIDIgPSovIDgyKS5mb3JrKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5kb3VibGVEYXRhLmxlbmd0aDsgKytpKSB3cml0ZXIuZG91YmxlKG1lc3NhZ2UuZG91YmxlRGF0YVtpXSk7XG4gICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnVpbnQ2NERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLnVpbnQ2NERhdGEubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTEsIHdpcmVUeXBlIDIgPSovIDkwKS5mb3JrKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS51aW50NjREYXRhLmxlbmd0aDsgKytpKSB3cml0ZXIudWludDY0KG1lc3NhZ2UudWludDY0RGF0YVtpXSk7XG4gICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb2NTdHJpbmcnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMiwgd2lyZVR5cGUgMiA9Ki8gOTgpLnN0cmluZyhtZXNzYWdlLmRvY1N0cmluZyk7XG4gICAgICBpZiAobWVzc2FnZS5leHRlcm5hbERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmV4dGVybmFsRGF0YS5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5leHRlcm5hbERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMywgd2lyZVR5cGUgMiA9Ki8gMTA2KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmRhdGFMb2NhdGlvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkYXRhTG9jYXRpb24nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxNCwgd2lyZVR5cGUgMCA9Ki8gMTEyKS5pbnQzMihtZXNzYWdlLmRhdGFMb2NhdGlvbik7XG4gICAgICByZXR1cm4gd3JpdGVyO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JQcm90b30gbWVzc2FnZSBUZW5zb3JQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBUZW5zb3JQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvfSBUZW5zb3JQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yUHJvdG8oKTtcbiAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmRpbXMgJiYgbWVzc2FnZS5kaW1zLmxlbmd0aCkpIG1lc3NhZ2UuZGltcyA9IFtdO1xuICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMikgbWVzc2FnZS5kaW1zLnB1c2gocmVhZGVyLmludDY0KCkpO1xuICAgICAgICAgICAgfSBlbHNlIG1lc3NhZ2UuZGltcy5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZGF0YVR5cGUgPSByZWFkZXIuaW50MzIoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDM6IHtcbiAgICAgICAgICAgIG1lc3NhZ2Uuc2VnbWVudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudC5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNDoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5mbG9hdERhdGEgJiYgbWVzc2FnZS5mbG9hdERhdGEubGVuZ3RoKSkgbWVzc2FnZS5mbG9hdERhdGEgPSBbXTtcbiAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpIG1lc3NhZ2UuZmxvYXREYXRhLnB1c2gocmVhZGVyLmZsb2F0KCkpO1xuICAgICAgICAgICAgfSBlbHNlIG1lc3NhZ2UuZmxvYXREYXRhLnB1c2gocmVhZGVyLmZsb2F0KCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbnQzMkRhdGEgJiYgbWVzc2FnZS5pbnQzMkRhdGEubGVuZ3RoKSkgbWVzc2FnZS5pbnQzMkRhdGEgPSBbXTtcbiAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpIG1lc3NhZ2UuaW50MzJEYXRhLnB1c2gocmVhZGVyLmludDMyKCkpO1xuICAgICAgICAgICAgfSBlbHNlIG1lc3NhZ2UuaW50MzJEYXRhLnB1c2gocmVhZGVyLmludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNjoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5zdHJpbmdEYXRhICYmIG1lc3NhZ2Uuc3RyaW5nRGF0YS5sZW5ndGgpKSBtZXNzYWdlLnN0cmluZ0RhdGEgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uuc3RyaW5nRGF0YS5wdXNoKHJlYWRlci5ieXRlcygpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDc6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuaW50NjREYXRhICYmIG1lc3NhZ2UuaW50NjREYXRhLmxlbmd0aCkpIG1lc3NhZ2UuaW50NjREYXRhID0gW107XG4gICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgIHZhciBlbmQyID0gcmVhZGVyLnVpbnQzMigpICsgcmVhZGVyLnBvcztcbiAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKSBtZXNzYWdlLmludDY0RGF0YS5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgIH0gZWxzZSBtZXNzYWdlLmludDY0RGF0YS5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDg6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDEyOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmRvY1N0cmluZyA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDk6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UucmF3RGF0YSA9IHJlYWRlci5ieXRlcygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTM6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZXh0ZXJuYWxEYXRhICYmIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhLmxlbmd0aCkpIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmV4dGVybmFsRGF0YS5wdXNoKCRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDE0OiB7XG4gICAgICAgICAgICBtZXNzYWdlLmRhdGFMb2NhdGlvbiA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTA6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZG91YmxlRGF0YSAmJiBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoKSkgbWVzc2FnZS5kb3VibGVEYXRhID0gW107XG4gICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgIHZhciBlbmQyID0gcmVhZGVyLnVpbnQzMigpICsgcmVhZGVyLnBvcztcbiAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKSBtZXNzYWdlLmRvdWJsZURhdGEucHVzaChyZWFkZXIuZG91YmxlKCkpO1xuICAgICAgICAgICAgfSBlbHNlIG1lc3NhZ2UuZG91YmxlRGF0YS5wdXNoKHJlYWRlci5kb3VibGUoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS51aW50NjREYXRhICYmIG1lc3NhZ2UudWludDY0RGF0YS5sZW5ndGgpKSBtZXNzYWdlLnVpbnQ2NERhdGEgPSBbXTtcbiAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpIG1lc3NhZ2UudWludDY0RGF0YS5wdXNoKHJlYWRlci51aW50NjQoKSk7XG4gICAgICAgICAgICB9IGVsc2UgbWVzc2FnZS51aW50NjREYXRhLnB1c2gocmVhZGVyLnVpbnQ2NCgpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVGVuc29yUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yUHJvdG99IFRlbnNvclByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWVzIGEgVGVuc29yUHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5kaW1zICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZGltcycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmRpbXMpKSByZXR1cm4gJ2RpbXM6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRpbXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbXNbaV0pICYmXG4gICAgICAgICAgICAhKG1lc3NhZ2UuZGltc1tpXSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kaW1zW2ldLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltc1tpXS5oaWdoKSlcbiAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gJ2RpbXM6IGludGVnZXJ8TG9uZ1tdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRhdGFUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZGF0YVR5cGUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kYXRhVHlwZSkpIHJldHVybiAnZGF0YVR5cGU6IGludGVnZXIgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2Uuc2VnbWVudCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NlZ21lbnQnKSkge1xuICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQudmVyaWZ5KG1lc3NhZ2Uuc2VnbWVudCk7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdzZWdtZW50LicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmZsb2F0RGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2Zsb2F0RGF0YScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmZsb2F0RGF0YSkpIHJldHVybiAnZmxvYXREYXRhOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5mbG9hdERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmZsb2F0RGF0YVtpXSAhPT0gJ251bWJlcicpIHJldHVybiAnZmxvYXREYXRhOiBudW1iZXJbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5pbnQzMkRhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpbnQzMkRhdGEnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnQzMkRhdGEpKSByZXR1cm4gJ2ludDMyRGF0YTogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW50MzJEYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaW50MzJEYXRhW2ldKSkgcmV0dXJuICdpbnQzMkRhdGE6IGludGVnZXJbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zdHJpbmdEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc3RyaW5nRGF0YScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnN0cmluZ0RhdGEpKSByZXR1cm4gJ3N0cmluZ0RhdGE6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnN0cmluZ0RhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIShcbiAgICAgICAgICAgICAgKG1lc3NhZ2Uuc3RyaW5nRGF0YVtpXSAmJiB0eXBlb2YgbWVzc2FnZS5zdHJpbmdEYXRhW2ldLmxlbmd0aCA9PT0gJ251bWJlcicpIHx8XG4gICAgICAgICAgICAgICR1dGlsLmlzU3RyaW5nKG1lc3NhZ2Uuc3RyaW5nRGF0YVtpXSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gJ3N0cmluZ0RhdGE6IGJ1ZmZlcltdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmludDY0RGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2ludDY0RGF0YScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmludDY0RGF0YSkpIHJldHVybiAnaW50NjREYXRhOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnQ2NERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludDY0RGF0YVtpXSkgJiZcbiAgICAgICAgICAgICEoXG4gICAgICAgICAgICAgIG1lc3NhZ2UuaW50NjREYXRhW2ldICYmXG4gICAgICAgICAgICAgICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludDY0RGF0YVtpXS5sb3cpICYmXG4gICAgICAgICAgICAgICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludDY0RGF0YVtpXS5oaWdoKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiAnaW50NjREYXRhOiBpbnRlZ2VyfExvbmdbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UubmFtZSkpIHJldHVybiAnbmFtZTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSkgcmV0dXJuICdkb2NTdHJpbmc6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5yYXdEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncmF3RGF0YScpKVxuICAgICAgICBpZiAoISgobWVzc2FnZS5yYXdEYXRhICYmIHR5cGVvZiBtZXNzYWdlLnJhd0RhdGEubGVuZ3RoID09PSAnbnVtYmVyJykgfHwgJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5yYXdEYXRhKSkpXG4gICAgICAgICAgcmV0dXJuICdyYXdEYXRhOiBidWZmZXIgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuZXh0ZXJuYWxEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZXh0ZXJuYWxEYXRhJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuZXh0ZXJuYWxEYXRhKSkgcmV0dXJuICdleHRlcm5hbERhdGE6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmV4dGVybmFsRGF0YS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by52ZXJpZnkobWVzc2FnZS5leHRlcm5hbERhdGFbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdleHRlcm5hbERhdGEuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kYXRhTG9jYXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkYXRhTG9jYXRpb24nKSlcbiAgICAgICAgc3dpdGNoIChtZXNzYWdlLmRhdGFMb2NhdGlvbikge1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gJ2RhdGFMb2NhdGlvbjogZW51bSB2YWx1ZSBleHBlY3RlZCc7XG4gICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb3VibGVEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG91YmxlRGF0YScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmRvdWJsZURhdGEpKSByZXR1cm4gJ2RvdWJsZURhdGE6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmRvdWJsZURhdGFbaV0gIT09ICdudW1iZXInKSByZXR1cm4gJ2RvdWJsZURhdGE6IG51bWJlcltdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnVpbnQ2NERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd1aW50NjREYXRhJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudWludDY0RGF0YSkpIHJldHVybiAndWludDY0RGF0YTogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudWludDY0RGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UudWludDY0RGF0YVtpXSkgJiZcbiAgICAgICAgICAgICEoXG4gICAgICAgICAgICAgIG1lc3NhZ2UudWludDY0RGF0YVtpXSAmJlxuICAgICAgICAgICAgICAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS51aW50NjREYXRhW2ldLmxvdykgJiZcbiAgICAgICAgICAgICAgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UudWludDY0RGF0YVtpXS5oaWdoKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiAndWludDY0RGF0YTogaW50ZWdlcnxMb25nW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBUZW5zb3JQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yUHJvdG99IFRlbnNvclByb3RvXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UZW5zb3JQcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QuZGltcykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmRpbXMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRlbnNvclByb3RvLmRpbXM6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuZGltcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5kaW1zLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSAobWVzc2FnZS5kaW1zW2ldID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmRpbXNbaV0pKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltc1tpXSA9PT0gJ3N0cmluZycpIG1lc3NhZ2UuZGltc1tpXSA9IHBhcnNlSW50KG9iamVjdC5kaW1zW2ldLCAxMCk7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5kaW1zW2ldID09PSAnbnVtYmVyJykgbWVzc2FnZS5kaW1zW2ldID0gb2JqZWN0LmRpbXNbaV07XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5kaW1zW2ldID09PSAnb2JqZWN0JylcbiAgICAgICAgICAgIG1lc3NhZ2UuZGltc1tpXSA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuZGltc1tpXS5sb3cgPj4+IDAsIG9iamVjdC5kaW1zW2ldLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmRhdGFUeXBlICE9IG51bGwpIG1lc3NhZ2UuZGF0YVR5cGUgPSBvYmplY3QuZGF0YVR5cGUgfCAwO1xuICAgICAgaWYgKG9iamVjdC5zZWdtZW50ICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc2VnbWVudCAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yUHJvdG8uc2VnbWVudDogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2Uuc2VnbWVudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudC5mcm9tT2JqZWN0KG9iamVjdC5zZWdtZW50KTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZmxvYXREYXRhKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZmxvYXREYXRhKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JQcm90by5mbG9hdERhdGE6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuZmxvYXREYXRhID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmZsb2F0RGF0YS5sZW5ndGg7ICsraSkgbWVzc2FnZS5mbG9hdERhdGFbaV0gPSBOdW1iZXIob2JqZWN0LmZsb2F0RGF0YVtpXSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmludDMyRGF0YSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmludDMyRGF0YSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yUHJvdG8uaW50MzJEYXRhOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmludDMyRGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbnQzMkRhdGEubGVuZ3RoOyArK2kpIG1lc3NhZ2UuaW50MzJEYXRhW2ldID0gb2JqZWN0LmludDMyRGF0YVtpXSB8IDA7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnN0cmluZ0RhdGEpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5zdHJpbmdEYXRhKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JQcm90by5zdHJpbmdEYXRhOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnN0cmluZ0RhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Quc3RyaW5nRGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zdHJpbmdEYXRhW2ldID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICR1dGlsLmJhc2U2NC5kZWNvZGUoXG4gICAgICAgICAgICAgIG9iamVjdC5zdHJpbmdEYXRhW2ldLFxuICAgICAgICAgICAgICAobWVzc2FnZS5zdHJpbmdEYXRhW2ldID0gJHV0aWwubmV3QnVmZmVyKCR1dGlsLmJhc2U2NC5sZW5ndGgob2JqZWN0LnN0cmluZ0RhdGFbaV0pKSksXG4gICAgICAgICAgICAgIDAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIGVsc2UgaWYgKG9iamVjdC5zdHJpbmdEYXRhW2ldLmxlbmd0aCA+PSAwKSBtZXNzYWdlLnN0cmluZ0RhdGFbaV0gPSBvYmplY3Quc3RyaW5nRGF0YVtpXTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuaW50NjREYXRhKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuaW50NjREYXRhKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JQcm90by5pbnQ2NERhdGE6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuaW50NjREYXRhID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmludDY0RGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuaW50NjREYXRhW2ldID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmludDY0RGF0YVtpXSkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pbnQ2NERhdGFbaV0gPT09ICdzdHJpbmcnKSBtZXNzYWdlLmludDY0RGF0YVtpXSA9IHBhcnNlSW50KG9iamVjdC5pbnQ2NERhdGFbaV0sIDEwKTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmludDY0RGF0YVtpXSA9PT0gJ251bWJlcicpIG1lc3NhZ2UuaW50NjREYXRhW2ldID0gb2JqZWN0LmludDY0RGF0YVtpXTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmludDY0RGF0YVtpXSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBtZXNzYWdlLmludDY0RGF0YVtpXSA9IG5ldyAkdXRpbC5Mb25nQml0cyhcbiAgICAgICAgICAgICAgb2JqZWN0LmludDY0RGF0YVtpXS5sb3cgPj4+IDAsXG4gICAgICAgICAgICAgIG9iamVjdC5pbnQ2NERhdGFbaV0uaGlnaCA+Pj4gMCxcbiAgICAgICAgICAgICkudG9OdW1iZXIoKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QubmFtZSAhPSBudWxsKSBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbCkgbWVzc2FnZS5kb2NTdHJpbmcgPSBTdHJpbmcob2JqZWN0LmRvY1N0cmluZyk7XG4gICAgICBpZiAob2JqZWN0LnJhd0RhdGEgIT0gbnVsbClcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QucmF3RGF0YSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgJHV0aWwuYmFzZTY0LmRlY29kZShcbiAgICAgICAgICAgIG9iamVjdC5yYXdEYXRhLFxuICAgICAgICAgICAgKG1lc3NhZ2UucmF3RGF0YSA9ICR1dGlsLm5ld0J1ZmZlcigkdXRpbC5iYXNlNjQubGVuZ3RoKG9iamVjdC5yYXdEYXRhKSkpLFxuICAgICAgICAgICAgMCxcbiAgICAgICAgICApO1xuICAgICAgICBlbHNlIGlmIChvYmplY3QucmF3RGF0YS5sZW5ndGggPj0gMCkgbWVzc2FnZS5yYXdEYXRhID0gb2JqZWN0LnJhd0RhdGE7XG4gICAgICBpZiAob2JqZWN0LmV4dGVybmFsRGF0YSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmV4dGVybmFsRGF0YSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yUHJvdG8uZXh0ZXJuYWxEYXRhOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmV4dGVybmFsRGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5leHRlcm5hbERhdGEubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5leHRlcm5hbERhdGFbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JQcm90by5leHRlcm5hbERhdGE6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2ldID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmZyb21PYmplY3Qob2JqZWN0LmV4dGVybmFsRGF0YVtpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN3aXRjaCAob2JqZWN0LmRhdGFMb2NhdGlvbikge1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmRhdGFMb2NhdGlvbiA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZGF0YUxvY2F0aW9uID0gb2JqZWN0LmRhdGFMb2NhdGlvbjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnREVGQVVMVCc6XG4gICAgICAgIGNhc2UgMDpcbiAgICAgICAgICBtZXNzYWdlLmRhdGFMb2NhdGlvbiA9IDA7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0VYVEVSTkFMJzpcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIG1lc3NhZ2UuZGF0YUxvY2F0aW9uID0gMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZG91YmxlRGF0YSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmRvdWJsZURhdGEpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRlbnNvclByb3RvLmRvdWJsZURhdGE6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuZG91YmxlRGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5kb3VibGVEYXRhLmxlbmd0aDsgKytpKSBtZXNzYWdlLmRvdWJsZURhdGFbaV0gPSBOdW1iZXIob2JqZWN0LmRvdWJsZURhdGFbaV0pO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC51aW50NjREYXRhKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QudWludDY0RGF0YSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yUHJvdG8udWludDY0RGF0YTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS51aW50NjREYXRhID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LnVpbnQ2NERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKCR1dGlsLkxvbmcpIChtZXNzYWdlLnVpbnQ2NERhdGFbaV0gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QudWludDY0RGF0YVtpXSkpLnVuc2lnbmVkID0gdHJ1ZTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LnVpbnQ2NERhdGFbaV0gPT09ICdzdHJpbmcnKSBtZXNzYWdlLnVpbnQ2NERhdGFbaV0gPSBwYXJzZUludChvYmplY3QudWludDY0RGF0YVtpXSwgMTApO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QudWludDY0RGF0YVtpXSA9PT0gJ251bWJlcicpIG1lc3NhZ2UudWludDY0RGF0YVtpXSA9IG9iamVjdC51aW50NjREYXRhW2ldO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QudWludDY0RGF0YVtpXSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBtZXNzYWdlLnVpbnQ2NERhdGFbaV0gPSBuZXcgJHV0aWwuTG9uZ0JpdHMoXG4gICAgICAgICAgICAgIG9iamVjdC51aW50NjREYXRhW2ldLmxvdyA+Pj4gMCxcbiAgICAgICAgICAgICAgb2JqZWN0LnVpbnQ2NERhdGFbaV0uaGlnaCA+Pj4gMCxcbiAgICAgICAgICAgICkudG9OdW1iZXIodHJ1ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgVGVuc29yUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JQcm90b30gbWVzc2FnZSBUZW5zb3JQcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgVGVuc29yUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIGlmIChvcHRpb25zLmFycmF5cyB8fCBvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5kaW1zID0gW107XG4gICAgICAgIG9iamVjdC5mbG9hdERhdGEgPSBbXTtcbiAgICAgICAgb2JqZWN0LmludDMyRGF0YSA9IFtdO1xuICAgICAgICBvYmplY3Quc3RyaW5nRGF0YSA9IFtdO1xuICAgICAgICBvYmplY3QuaW50NjREYXRhID0gW107XG4gICAgICAgIG9iamVjdC5kb3VibGVEYXRhID0gW107XG4gICAgICAgIG9iamVjdC51aW50NjREYXRhID0gW107XG4gICAgICAgIG9iamVjdC5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5kYXRhVHlwZSA9IDA7XG4gICAgICAgIG9iamVjdC5zZWdtZW50ID0gbnVsbDtcbiAgICAgICAgb2JqZWN0Lm5hbWUgPSAnJztcbiAgICAgICAgaWYgKG9wdGlvbnMuYnl0ZXMgPT09IFN0cmluZykgb2JqZWN0LnJhd0RhdGEgPSAnJztcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgb2JqZWN0LnJhd0RhdGEgPSBbXTtcbiAgICAgICAgICBpZiAob3B0aW9ucy5ieXRlcyAhPT0gQXJyYXkpIG9iamVjdC5yYXdEYXRhID0gJHV0aWwubmV3QnVmZmVyKG9iamVjdC5yYXdEYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gJyc7XG4gICAgICAgIG9iamVjdC5kYXRhTG9jYXRpb24gPSBvcHRpb25zLmVudW1zID09PSBTdHJpbmcgPyAnREVGQVVMVCcgOiAwO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZGltcyAmJiBtZXNzYWdlLmRpbXMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5kaW1zID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5kaW1zLmxlbmd0aDsgKytqKVxuICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5kaW1zW2pdID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgIG9iamVjdC5kaW1zW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuZGltc1tqXSkgOiBtZXNzYWdlLmRpbXNbal07XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgb2JqZWN0LmRpbXNbal0gPVxuICAgICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5kaW1zW2pdKVxuICAgICAgICAgICAgICAgIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyXG4gICAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmRpbXNbal0ubG93ID4+PiAwLCBtZXNzYWdlLmRpbXNbal0uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgICAgOiBtZXNzYWdlLmRpbXNbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kYXRhVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RhdGFUeXBlJykpIG9iamVjdC5kYXRhVHlwZSA9IG1lc3NhZ2UuZGF0YVR5cGU7XG4gICAgICBpZiAobWVzc2FnZS5zZWdtZW50ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc2VnbWVudCcpKVxuICAgICAgICBvYmplY3Quc2VnbWVudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudC50b09iamVjdChtZXNzYWdlLnNlZ21lbnQsIG9wdGlvbnMpO1xuICAgICAgaWYgKG1lc3NhZ2UuZmxvYXREYXRhICYmIG1lc3NhZ2UuZmxvYXREYXRhLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuZmxvYXREYXRhID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5mbG9hdERhdGEubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LmZsb2F0RGF0YVtqXSA9XG4gICAgICAgICAgICBvcHRpb25zLmpzb24gJiYgIWlzRmluaXRlKG1lc3NhZ2UuZmxvYXREYXRhW2pdKSA/IFN0cmluZyhtZXNzYWdlLmZsb2F0RGF0YVtqXSkgOiBtZXNzYWdlLmZsb2F0RGF0YVtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmludDMyRGF0YSAmJiBtZXNzYWdlLmludDMyRGF0YS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmludDMyRGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW50MzJEYXRhLmxlbmd0aDsgKytqKSBvYmplY3QuaW50MzJEYXRhW2pdID0gbWVzc2FnZS5pbnQzMkRhdGFbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zdHJpbmdEYXRhICYmIG1lc3NhZ2Uuc3RyaW5nRGF0YS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnN0cmluZ0RhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnN0cmluZ0RhdGEubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnN0cmluZ0RhdGFbal0gPVxuICAgICAgICAgICAgb3B0aW9ucy5ieXRlcyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgID8gJHV0aWwuYmFzZTY0LmVuY29kZShtZXNzYWdlLnN0cmluZ0RhdGFbal0sIDAsIG1lc3NhZ2Uuc3RyaW5nRGF0YVtqXS5sZW5ndGgpXG4gICAgICAgICAgICAgIDogb3B0aW9ucy5ieXRlcyA9PT0gQXJyYXlcbiAgICAgICAgICAgICAgICA/IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG1lc3NhZ2Uuc3RyaW5nRGF0YVtqXSlcbiAgICAgICAgICAgICAgICA6IG1lc3NhZ2Uuc3RyaW5nRGF0YVtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmludDY0RGF0YSAmJiBtZXNzYWdlLmludDY0RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmludDY0RGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW50NjREYXRhLmxlbmd0aDsgKytqKVxuICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5pbnQ2NERhdGFbal0gPT09ICdudW1iZXInKVxuICAgICAgICAgICAgb2JqZWN0LmludDY0RGF0YVtqXSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmludDY0RGF0YVtqXSkgOiBtZXNzYWdlLmludDY0RGF0YVtqXTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBvYmplY3QuaW50NjREYXRhW2pdID1cbiAgICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuaW50NjREYXRhW2pdKVxuICAgICAgICAgICAgICAgIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyXG4gICAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmludDY0RGF0YVtqXS5sb3cgPj4+IDAsIG1lc3NhZ2UuaW50NjREYXRhW2pdLmhpZ2ggPj4+IDApLnRvTnVtYmVyKClcbiAgICAgICAgICAgICAgICAgIDogbWVzc2FnZS5pbnQ2NERhdGFbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpKSBvYmplY3QubmFtZSA9IG1lc3NhZ2UubmFtZTtcbiAgICAgIGlmIChtZXNzYWdlLnJhd0RhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdyYXdEYXRhJykpXG4gICAgICAgIG9iamVjdC5yYXdEYXRhID1cbiAgICAgICAgICBvcHRpb25zLmJ5dGVzID09PSBTdHJpbmdcbiAgICAgICAgICAgID8gJHV0aWwuYmFzZTY0LmVuY29kZShtZXNzYWdlLnJhd0RhdGEsIDAsIG1lc3NhZ2UucmF3RGF0YS5sZW5ndGgpXG4gICAgICAgICAgICA6IG9wdGlvbnMuYnl0ZXMgPT09IEFycmF5XG4gICAgICAgICAgICAgID8gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwobWVzc2FnZS5yYXdEYXRhKVxuICAgICAgICAgICAgICA6IG1lc3NhZ2UucmF3RGF0YTtcbiAgICAgIGlmIChtZXNzYWdlLmRvdWJsZURhdGEgJiYgbWVzc2FnZS5kb3VibGVEYXRhLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuZG91YmxlRGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZG91YmxlRGF0YS5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuZG91YmxlRGF0YVtqXSA9XG4gICAgICAgICAgICBvcHRpb25zLmpzb24gJiYgIWlzRmluaXRlKG1lc3NhZ2UuZG91YmxlRGF0YVtqXSkgPyBTdHJpbmcobWVzc2FnZS5kb3VibGVEYXRhW2pdKSA6IG1lc3NhZ2UuZG91YmxlRGF0YVtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnVpbnQ2NERhdGEgJiYgbWVzc2FnZS51aW50NjREYXRhLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QudWludDY0RGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UudWludDY0RGF0YS5sZW5ndGg7ICsrailcbiAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UudWludDY0RGF0YVtqXSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICBvYmplY3QudWludDY0RGF0YVtqXSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLnVpbnQ2NERhdGFbal0pIDogbWVzc2FnZS51aW50NjREYXRhW2pdO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIG9iamVjdC51aW50NjREYXRhW2pdID1cbiAgICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UudWludDY0RGF0YVtqXSlcbiAgICAgICAgICAgICAgICA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlclxuICAgICAgICAgICAgICAgICAgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS51aW50NjREYXRhW2pdLmxvdyA+Pj4gMCwgbWVzc2FnZS51aW50NjREYXRhW2pdLmhpZ2ggPj4+IDApLnRvTnVtYmVyKHRydWUpXG4gICAgICAgICAgICAgICAgICA6IG1lc3NhZ2UudWludDY0RGF0YVtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKSBvYmplY3QuZG9jU3RyaW5nID0gbWVzc2FnZS5kb2NTdHJpbmc7XG4gICAgICBpZiAobWVzc2FnZS5leHRlcm5hbERhdGEgJiYgbWVzc2FnZS5leHRlcm5hbERhdGEubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmV4dGVybmFsRGF0YS5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuZXh0ZXJuYWxEYXRhW2pdID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRhdGFMb2NhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RhdGFMb2NhdGlvbicpKVxuICAgICAgICBvYmplY3QuZGF0YUxvY2F0aW9uID1cbiAgICAgICAgICBvcHRpb25zLmVudW1zID09PSBTdHJpbmdcbiAgICAgICAgICAgID8gJHJvb3Qub25ueC5UZW5zb3JQcm90by5EYXRhTG9jYXRpb25bbWVzc2FnZS5kYXRhTG9jYXRpb25dID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgPyBtZXNzYWdlLmRhdGFMb2NhdGlvblxuICAgICAgICAgICAgICA6ICRyb290Lm9ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9uW21lc3NhZ2UuZGF0YUxvY2F0aW9uXVxuICAgICAgICAgICAgOiBtZXNzYWdlLmRhdGFMb2NhdGlvbjtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgVGVuc29yUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBUZW5zb3JQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UZW5zb3JQcm90byc7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERhdGFUeXBlIGVudW0uXG4gICAgICogQG5hbWUgb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZVxuICAgICAqIEBlbnVtIHtudW1iZXJ9XG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVOREVGSU5FRD0wIFVOREVGSU5FRCB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGTE9BVD0xIEZMT0FUIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVJTlQ4PTIgVUlOVDggdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UOD0zIElOVDggdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gVUlOVDE2PTQgVUlOVDE2IHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IElOVDE2PTUgSU5UMTYgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UMzI9NiBJTlQzMiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJTlQ2ND03IElOVDY0IHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFNUUklORz04IFNUUklORyB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBCT09MPTkgQk9PTCB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGTE9BVDE2PTEwIEZMT0FUMTYgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRE9VQkxFPTExIERPVUJMRSB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBVSU5UMzI9MTIgVUlOVDMyIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVJTlQ2ND0xMyBVSU5UNjQgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gQ09NUExFWDY0PTE0IENPTVBMRVg2NCB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBDT01QTEVYMTI4PTE1IENPTVBMRVgxMjggdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gQkZMT0FUMTY9MTYgQkZMT0FUMTYgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ4RTRNM0ZOPTE3IEZMT0FUOEU0TTNGTiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGTE9BVDhFNE0zRk5VWj0xOCBGTE9BVDhFNE0zRk5VWiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGTE9BVDhFNU0yPTE5IEZMT0FUOEU1TTIgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ4RTVNMkZOVVo9MjAgRkxPQVQ4RTVNMkZOVVogdmFsdWVcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5EYXRhVHlwZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsdWVzQnlJZCA9IHt9LFxuICAgICAgICB2YWx1ZXMgPSBPYmplY3QuY3JlYXRlKHZhbHVlc0J5SWQpO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzBdID0gJ1VOREVGSU5FRCcpXSA9IDA7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMV0gPSAnRkxPQVQnKV0gPSAxO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzJdID0gJ1VJTlQ4JyldID0gMjtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFszXSA9ICdJTlQ4JyldID0gMztcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFs0XSA9ICdVSU5UMTYnKV0gPSA0O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzVdID0gJ0lOVDE2JyldID0gNTtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFs2XSA9ICdJTlQzMicpXSA9IDY7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbN10gPSAnSU5UNjQnKV0gPSA3O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzhdID0gJ1NUUklORycpXSA9IDg7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbOV0gPSAnQk9PTCcpXSA9IDk7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTBdID0gJ0ZMT0FUMTYnKV0gPSAxMDtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxMV0gPSAnRE9VQkxFJyldID0gMTE7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTJdID0gJ1VJTlQzMicpXSA9IDEyO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzEzXSA9ICdVSU5UNjQnKV0gPSAxMztcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxNF0gPSAnQ09NUExFWDY0JyldID0gMTQ7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTVdID0gJ0NPTVBMRVgxMjgnKV0gPSAxNTtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxNl0gPSAnQkZMT0FUMTYnKV0gPSAxNjtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxN10gPSAnRkxPQVQ4RTRNM0ZOJyldID0gMTc7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMThdID0gJ0ZMT0FUOEU0TTNGTlVaJyldID0gMTg7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTldID0gJ0ZMT0FUOEU1TTInKV0gPSAxOTtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsyMF0gPSAnRkxPQVQ4RTVNMkZOVVonKV0gPSAyMDtcbiAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfSkoKTtcblxuICAgIFRlbnNvclByb3RvLlNlZ21lbnQgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgLyoqXG4gICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgU2VnbWVudC5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgKiBAaW50ZXJmYWNlIElTZWdtZW50XG4gICAgICAgKiBAcHJvcGVydHkge251bWJlcnxMb25nfG51bGx9IFtiZWdpbl0gU2VnbWVudCBiZWdpblxuICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbZW5kXSBTZWdtZW50IGVuZFxuICAgICAgICovXG5cbiAgICAgIC8qKlxuICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBTZWdtZW50LlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFNlZ21lbnQuXG4gICAgICAgKiBAaW1wbGVtZW50cyBJU2VnbWVudFxuICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnQ9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24gU2VnbWVudChwcm9wZXJ0aWVzKSB7XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICB9XG5cbiAgICAgIC8qKlxuICAgICAgICogU2VnbWVudCBiZWdpbi5cbiAgICAgICAqIEBtZW1iZXIge251bWJlcnxMb25nfSBiZWdpblxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQucHJvdG90eXBlLmJlZ2luID0gJHV0aWwuTG9uZyA/ICR1dGlsLkxvbmcuZnJvbUJpdHMoMCwgMCwgZmFsc2UpIDogMDtcblxuICAgICAgLyoqXG4gICAgICAgKiBTZWdtZW50IGVuZC5cbiAgICAgICAqIEBtZW1iZXIge251bWJlcnxMb25nfSBlbmRcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBTZWdtZW50LnByb3RvdHlwZS5lbmQgPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLCAwLCBmYWxzZSkgOiAwO1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBuZXcgU2VnbWVudCBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnQ9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvLlNlZ21lbnR9IFNlZ21lbnQgaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICByZXR1cm4gbmV3IFNlZ21lbnQocHJvcGVydGllcyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTZWdtZW50IG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudC52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JQcm90by5JU2VnbWVudH0gbWVzc2FnZSBTZWdtZW50IG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuYmVnaW4gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnYmVnaW4nKSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDAgPSovIDgpLmludDY0KG1lc3NhZ2UuYmVnaW4pO1xuICAgICAgICBpZiAobWVzc2FnZS5lbmQgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZW5kJykpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAwID0qLyAxNikuaW50NjQobWVzc2FnZS5lbmQpO1xuICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU2VnbWVudCBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclByb3RvLlNlZ21lbnQudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnR9IG1lc3NhZ2UgU2VnbWVudCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICovXG4gICAgICBTZWdtZW50LmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBTZWdtZW50IG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JQcm90by5TZWdtZW50fSBTZWdtZW50XG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudCgpO1xuICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgICBtZXNzYWdlLmJlZ2luID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UuZW5kID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBTZWdtZW50IG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvLlNlZ21lbnR9IFNlZ21lbnRcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBWZXJpZmllcyBhIFNlZ21lbnQgbWVzc2FnZS5cbiAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgICAgaWYgKG1lc3NhZ2UuYmVnaW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdiZWdpbicpKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5iZWdpbikgJiZcbiAgICAgICAgICAgICEobWVzc2FnZS5iZWdpbiAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5iZWdpbi5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmJlZ2luLmhpZ2gpKVxuICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiAnYmVnaW46IGludGVnZXJ8TG9uZyBleHBlY3RlZCc7XG4gICAgICAgIGlmIChtZXNzYWdlLmVuZCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2VuZCcpKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5lbmQpICYmXG4gICAgICAgICAgICAhKG1lc3NhZ2UuZW5kICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmVuZC5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmVuZC5oaWdoKSlcbiAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gJ2VuZDogaW50ZWdlcnxMb25nIGV4cGVjdGVkJztcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBTZWdtZW50IG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JQcm90by5TZWdtZW50fSBTZWdtZW50XG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQuZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQpIHJldHVybiBvYmplY3Q7XG4gICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudCgpO1xuICAgICAgICBpZiAob2JqZWN0LmJlZ2luICE9IG51bGwpXG4gICAgICAgICAgaWYgKCR1dGlsLkxvbmcpIChtZXNzYWdlLmJlZ2luID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmJlZ2luKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmJlZ2luID09PSAnc3RyaW5nJykgbWVzc2FnZS5iZWdpbiA9IHBhcnNlSW50KG9iamVjdC5iZWdpbiwgMTApO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuYmVnaW4gPT09ICdudW1iZXInKSBtZXNzYWdlLmJlZ2luID0gb2JqZWN0LmJlZ2luO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuYmVnaW4gPT09ICdvYmplY3QnKVxuICAgICAgICAgICAgbWVzc2FnZS5iZWdpbiA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuYmVnaW4ubG93ID4+PiAwLCBvYmplY3QuYmVnaW4uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgICAgaWYgKG9iamVjdC5lbmQgIT0gbnVsbClcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuZW5kID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmVuZCkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5lbmQgPT09ICdzdHJpbmcnKSBtZXNzYWdlLmVuZCA9IHBhcnNlSW50KG9iamVjdC5lbmQsIDEwKTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmVuZCA9PT0gJ251bWJlcicpIG1lc3NhZ2UuZW5kID0gb2JqZWN0LmVuZDtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmVuZCA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBtZXNzYWdlLmVuZCA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuZW5kLmxvdyA+Pj4gMCwgb2JqZWN0LmVuZC5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgU2VnbWVudCBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JQcm90by5TZWdtZW50fSBtZXNzYWdlIFNlZ21lbnRcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykge1xuICAgICAgICAgICAgdmFyIGxvbmcgPSBuZXcgJHV0aWwuTG9uZygwLCAwLCBmYWxzZSk7XG4gICAgICAgICAgICBvYmplY3QuYmVnaW4gPVxuICAgICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBsb25nLnRvU3RyaW5nKCkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBsb25nLnRvTnVtYmVyKCkgOiBsb25nO1xuICAgICAgICAgIH0gZWxzZSBvYmplY3QuYmVnaW4gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyAnMCcgOiAwO1xuICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSB7XG4gICAgICAgICAgICB2YXIgbG9uZyA9IG5ldyAkdXRpbC5Mb25nKDAsIDAsIGZhbHNlKTtcbiAgICAgICAgICAgIG9iamVjdC5lbmQgPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBsb25nLnRvU3RyaW5nKCkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBsb25nLnRvTnVtYmVyKCkgOiBsb25nO1xuICAgICAgICAgIH0gZWxzZSBvYmplY3QuZW5kID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJzAnIDogMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5iZWdpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2JlZ2luJykpXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmJlZ2luID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgIG9iamVjdC5iZWdpbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmJlZ2luKSA6IG1lc3NhZ2UuYmVnaW47XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgb2JqZWN0LmJlZ2luID1cbiAgICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuYmVnaW4pXG4gICAgICAgICAgICAgICAgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXJcbiAgICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuYmVnaW4ubG93ID4+PiAwLCBtZXNzYWdlLmJlZ2luLmhpZ2ggPj4+IDApLnRvTnVtYmVyKClcbiAgICAgICAgICAgICAgICAgIDogbWVzc2FnZS5iZWdpbjtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZW5kICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZW5kJykpXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmVuZCA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICBvYmplY3QuZW5kID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuZW5kKSA6IG1lc3NhZ2UuZW5kO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIG9iamVjdC5lbmQgPVxuICAgICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5lbmQpXG4gICAgICAgICAgICAgICAgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXJcbiAgICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuZW5kLmxvdyA+Pj4gMCwgbWVzc2FnZS5lbmQuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgICAgOiBtZXNzYWdlLmVuZDtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ29udmVydHMgdGhpcyBTZWdtZW50IHRvIEpTT04uXG4gICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgU2VnbWVudFxuICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlRlbnNvclByb3RvLlNlZ21lbnQnO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIFNlZ21lbnQ7XG4gICAgfSkoKTtcblxuICAgIC8qKlxuICAgICAqIERhdGFMb2NhdGlvbiBlbnVtLlxuICAgICAqIEBuYW1lIG9ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9uXG4gICAgICogQGVudW0ge251bWJlcn1cbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gREVGQVVMVD0wIERFRkFVTFQgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRVhURVJOQUw9MSBFWFRFUk5BTCB2YWx1ZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLkRhdGFMb2NhdGlvbiA9IChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsdWVzQnlJZCA9IHt9LFxuICAgICAgICB2YWx1ZXMgPSBPYmplY3QuY3JlYXRlKHZhbHVlc0J5SWQpO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzBdID0gJ0RFRkFVTFQnKV0gPSAwO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzFdID0gJ0VYVEVSTkFMJyldID0gMTtcbiAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfSkoKTtcblxuICAgIHJldHVybiBUZW5zb3JQcm90bztcbiAgfSkoKTtcblxuICBvbm54LlNwYXJzZVRlbnNvclByb3RvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgU3BhcnNlVGVuc29yUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElTcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVGVuc29yUHJvdG98bnVsbH0gW3ZhbHVlc10gU3BhcnNlVGVuc29yUHJvdG8gdmFsdWVzXG4gICAgICogQHByb3BlcnR5IHtvbm54LklUZW5zb3JQcm90b3xudWxsfSBbaW5kaWNlc10gU3BhcnNlVGVuc29yUHJvdG8gaW5kaWNlc1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcnxMb25nPnxudWxsfSBbZGltc10gU3BhcnNlVGVuc29yUHJvdG8gZGltc1xuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBTcGFyc2VUZW5zb3JQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFNwYXJzZVRlbnNvclByb3RvLlxuICAgICAqIEBpbXBsZW1lbnRzIElTcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JU3BhcnNlVGVuc29yUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBTcGFyc2VUZW5zb3JQcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLmRpbXMgPSBbXTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTcGFyc2VUZW5zb3JQcm90byB2YWx1ZXMuXG4gICAgICogQG1lbWJlciB7b25ueC5JVGVuc29yUHJvdG98bnVsbHx1bmRlZmluZWR9IHZhbHVlc1xuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8ucHJvdG90eXBlLnZhbHVlcyA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBTcGFyc2VUZW5zb3JQcm90byBpbmRpY2VzLlxuICAgICAqIEBtZW1iZXIge29ubnguSVRlbnNvclByb3RvfG51bGx8dW5kZWZpbmVkfSBpbmRpY2VzXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5wcm90b3R5cGUuaW5kaWNlcyA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBTcGFyc2VUZW5zb3JQcm90byBkaW1zLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXJ8TG9uZz59IGRpbXNcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFNwYXJzZVRlbnNvclByb3RvLnByb3RvdHlwZS5kaW1zID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgU3BhcnNlVGVuc29yUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVNwYXJzZVRlbnNvclByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguU3BhcnNlVGVuc29yUHJvdG99IFNwYXJzZVRlbnNvclByb3RvIGluc3RhbmNlXG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgU3BhcnNlVGVuc29yUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlNwYXJzZVRlbnNvclByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVNwYXJzZVRlbnNvclByb3RvfSBtZXNzYWdlIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLnZhbHVlcyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICd2YWx1ZXMnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JQcm90by5lbmNvZGUobWVzc2FnZS52YWx1ZXMsIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5pbmRpY2VzICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2luZGljZXMnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JQcm90by5lbmNvZGUobWVzc2FnZS5pbmRpY2VzLCB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovIDE4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZGltcyAhPSBudWxsICYmIG1lc3NhZ2UuZGltcy5sZW5ndGgpIHtcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAzLCB3aXJlVHlwZSAyID0qLyAyNikuZm9yaygpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZGltcy5sZW5ndGg7ICsraSkgd3JpdGVyLmludDY0KG1lc3NhZ2UuZGltc1tpXSk7XG4gICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlNwYXJzZVRlbnNvclByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVNwYXJzZVRlbnNvclByb3RvfSBtZXNzYWdlIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguU3BhcnNlVGVuc29yUHJvdG99IFNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UudmFsdWVzID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS5pbmRpY2VzID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMzoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5kaW1zICYmIG1lc3NhZ2UuZGltcy5sZW5ndGgpKSBtZXNzYWdlLmRpbXMgPSBbXTtcbiAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpIG1lc3NhZ2UuZGltcy5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgIH0gZWxzZSBtZXNzYWdlLmRpbXMucHVzaChyZWFkZXIuaW50NjQoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LlNwYXJzZVRlbnNvclByb3RvfSBTcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UudmFsdWVzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWVzJykpIHtcbiAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS52YWx1ZXMpO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAndmFsdWVzLicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmluZGljZXMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpbmRpY2VzJykpIHtcbiAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS5pbmRpY2VzKTtcbiAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2luZGljZXMuJyArIGVycm9yO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZGltcyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RpbXMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5kaW1zKSkgcmV0dXJuICdkaW1zOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5kaW1zLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kaW1zW2ldKSAmJlxuICAgICAgICAgICAgIShtZXNzYWdlLmRpbXNbaV0gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltc1tpXS5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbXNbaV0uaGlnaCkpXG4gICAgICAgICAgKVxuICAgICAgICAgICAgcmV0dXJuICdkaW1zOiBpbnRlZ2VyfExvbmdbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5TcGFyc2VUZW5zb3JQcm90b30gU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvKSByZXR1cm4gb2JqZWN0O1xuICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90bygpO1xuICAgICAgaWYgKG9iamVjdC52YWx1ZXMgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC52YWx1ZXMgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlNwYXJzZVRlbnNvclByb3RvLnZhbHVlczogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UudmFsdWVzID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC52YWx1ZXMpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5pbmRpY2VzICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5kaWNlcyAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguU3BhcnNlVGVuc29yUHJvdG8uaW5kaWNlczogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuaW5kaWNlcyA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3QuaW5kaWNlcyk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmRpbXMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5kaW1zKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5TcGFyc2VUZW5zb3JQcm90by5kaW1zOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmRpbXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZGltcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuZGltc1tpXSA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5kaW1zW2ldKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmRpbXNbaV0gPT09ICdzdHJpbmcnKSBtZXNzYWdlLmRpbXNbaV0gPSBwYXJzZUludChvYmplY3QuZGltc1tpXSwgMTApO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltc1tpXSA9PT0gJ251bWJlcicpIG1lc3NhZ2UuZGltc1tpXSA9IG9iamVjdC5kaW1zW2ldO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltc1tpXSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBtZXNzYWdlLmRpbXNbaV0gPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmRpbXNbaV0ubG93ID4+PiAwLCBvYmplY3QuZGltc1tpXS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguU3BhcnNlVGVuc29yUHJvdG99IG1lc3NhZ2UgU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIFNwYXJzZVRlbnNvclByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykgb2JqZWN0LmRpbXMgPSBbXTtcbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC52YWx1ZXMgPSBudWxsO1xuICAgICAgICBvYmplY3QuaW5kaWNlcyA9IG51bGw7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS52YWx1ZXMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd2YWx1ZXMnKSlcbiAgICAgICAgb2JqZWN0LnZhbHVlcyA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS52YWx1ZXMsIG9wdGlvbnMpO1xuICAgICAgaWYgKG1lc3NhZ2UuaW5kaWNlcyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2luZGljZXMnKSlcbiAgICAgICAgb2JqZWN0LmluZGljZXMgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuaW5kaWNlcywgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS5kaW1zICYmIG1lc3NhZ2UuZGltcy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmRpbXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmRpbXMubGVuZ3RoOyArK2opXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmRpbXNbal0gPT09ICdudW1iZXInKVxuICAgICAgICAgICAgb2JqZWN0LmRpbXNbal0gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS5kaW1zW2pdKSA6IG1lc3NhZ2UuZGltc1tqXTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBvYmplY3QuZGltc1tqXSA9XG4gICAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZ1xuICAgICAgICAgICAgICAgID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLmRpbXNbal0pXG4gICAgICAgICAgICAgICAgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXJcbiAgICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuZGltc1tqXS5sb3cgPj4+IDAsIG1lc3NhZ2UuZGltc1tqXS5oaWdoID4+PiAwKS50b051bWJlcigpXG4gICAgICAgICAgICAgICAgICA6IG1lc3NhZ2UuZGltc1tqXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgU3BhcnNlVGVuc29yUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBTcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5TcGFyc2VUZW5zb3JQcm90byc7XG4gICAgfTtcblxuICAgIHJldHVybiBTcGFyc2VUZW5zb3JQcm90bztcbiAgfSkoKTtcblxuICBvbm54LlRlbnNvclNoYXBlUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYSBUZW5zb3JTaGFwZVByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGludGVyZmFjZSBJVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguVGVuc29yU2hhcGVQcm90by5JRGltZW5zaW9uPnxudWxsfSBbZGltXSBUZW5zb3JTaGFwZVByb3RvIGRpbVxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBUZW5zb3JTaGFwZVByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgVGVuc29yU2hhcGVQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yU2hhcGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIFRlbnNvclNoYXBlUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5kaW0gPSBbXTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JTaGFwZVByb3RvIGRpbS5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5UZW5zb3JTaGFwZVByb3RvLklEaW1lbnNpb24+fSBkaW1cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yU2hhcGVQcm90by5wcm90b3R5cGUuZGltID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgVGVuc29yU2hhcGVQcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JTaGFwZVByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90b30gVGVuc29yU2hhcGVQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclNoYXBlUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgVGVuc29yU2hhcGVQcm90byhwcm9wZXJ0aWVzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JTaGFwZVByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yU2hhcGVQcm90b30gbWVzc2FnZSBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBUZW5zb3JTaGFwZVByb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZGltICE9IG51bGwgJiYgbWVzc2FnZS5kaW0ubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZGltLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5kaW1baV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovIDEwKS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yU2hhcGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvclNoYXBlUHJvdG99IG1lc3NhZ2UgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVGVuc29yU2hhcGVQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclNoYXBlUHJvdG99IFRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFRlbnNvclNoYXBlUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZGltICYmIG1lc3NhZ2UuZGltLmxlbmd0aCkpIG1lc3NhZ2UuZGltID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmRpbS5wdXNoKCRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JTaGFwZVByb3RvfSBUZW5zb3JTaGFwZVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBUZW5zb3JTaGFwZVByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYSBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBUZW5zb3JTaGFwZVByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmRpbSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RpbScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmRpbSkpIHJldHVybiAnZGltOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5kaW0ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLnZlcmlmeShtZXNzYWdlLmRpbVtpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2RpbS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JTaGFwZVByb3RvfSBUZW5zb3JTaGFwZVByb3RvXG4gICAgICovXG4gICAgVGVuc29yU2hhcGVQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QuZGltKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZGltKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JTaGFwZVByb3RvLmRpbTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5kaW0gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZGltLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZGltW2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JTaGFwZVByb3RvLmRpbTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5kaW1baV0gPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLmZyb21PYmplY3Qob2JqZWN0LmRpbVtpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvfSBtZXNzYWdlIFRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIFRlbnNvclNoYXBlUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIGlmIChvcHRpb25zLmFycmF5cyB8fCBvcHRpb25zLmRlZmF1bHRzKSBvYmplY3QuZGltID0gW107XG4gICAgICBpZiAobWVzc2FnZS5kaW0gJiYgbWVzc2FnZS5kaW0ubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5kaW0gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmRpbS5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuZGltW2pdID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbi50b09iamVjdChtZXNzYWdlLmRpbVtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIFRlbnNvclNoYXBlUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBUZW5zb3JTaGFwZVByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIFRlbnNvclNoYXBlUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguVGVuc29yU2hhcGVQcm90byc7XG4gICAgfTtcblxuICAgIFRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogUHJvcGVydGllcyBvZiBhIERpbWVuc2lvbi5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAqIEBpbnRlcmZhY2UgSURpbWVuc2lvblxuICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbZGltVmFsdWVdIERpbWVuc2lvbiBkaW1WYWx1ZVxuICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RpbVBhcmFtXSBEaW1lbnNpb24gZGltUGFyYW1cbiAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkZW5vdGF0aW9uXSBEaW1lbnNpb24gZGVub3RhdGlvblxuICAgICAgICovXG5cbiAgICAgIC8qKlxuICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBEaW1lbnNpb24uXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBEaW1lbnNpb24uXG4gICAgICAgKiBAaW1wbGVtZW50cyBJRGltZW5zaW9uXG4gICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvLklEaW1lbnNpb249fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24gRGltZW5zaW9uKHByb3BlcnRpZXMpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBEaW1lbnNpb24gZGltVmFsdWUuXG4gICAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ3xudWxsfHVuZGVmaW5lZH0gZGltVmFsdWVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLnByb3RvdHlwZS5kaW1WYWx1ZSA9IG51bGw7XG5cbiAgICAgIC8qKlxuICAgICAgICogRGltZW5zaW9uIGRpbVBhcmFtLlxuICAgICAgICogQG1lbWJlciB7c3RyaW5nfG51bGx8dW5kZWZpbmVkfSBkaW1QYXJhbVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBEaW1lbnNpb24ucHJvdG90eXBlLmRpbVBhcmFtID0gbnVsbDtcblxuICAgICAgLyoqXG4gICAgICAgKiBEaW1lbnNpb24gZGVub3RhdGlvbi5cbiAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gZGVub3RhdGlvblxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBEaW1lbnNpb24ucHJvdG90eXBlLmRlbm90YXRpb24gPSAnJztcblxuICAgICAgLy8gT25lT2YgZmllbGQgbmFtZXMgYm91bmQgdG8gdmlydHVhbCBnZXR0ZXJzIGFuZCBzZXR0ZXJzXG4gICAgICB2YXIgJG9uZU9mRmllbGRzO1xuXG4gICAgICAvKipcbiAgICAgICAqIERpbWVuc2lvbiB2YWx1ZS5cbiAgICAgICAqIEBtZW1iZXIge1wiZGltVmFsdWVcInxcImRpbVBhcmFtXCJ8dW5kZWZpbmVkfSB2YWx1ZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRGltZW5zaW9uLnByb3RvdHlwZSwgJ3ZhbHVlJywge1xuICAgICAgICBnZXQ6ICR1dGlsLm9uZU9mR2V0dGVyKCgkb25lT2ZGaWVsZHMgPSBbJ2RpbVZhbHVlJywgJ2RpbVBhcmFtJ10pKSxcbiAgICAgICAgc2V0OiAkdXRpbC5vbmVPZlNldHRlcigkb25lT2ZGaWVsZHMpLFxuICAgICAgfSk7XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIG5ldyBEaW1lbnNpb24gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvLklEaW1lbnNpb249fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9ufSBEaW1lbnNpb24gaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGltZW5zaW9uKHByb3BlcnRpZXMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgRGltZW5zaW9uIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uSURpbWVuc2lvbn0gbWVzc2FnZSBEaW1lbnNpb24gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgIGlmIChtZXNzYWdlLmRpbVZhbHVlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RpbVZhbHVlJykpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAwID0qLyA4KS5pbnQ2NChtZXNzYWdlLmRpbVZhbHVlKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZGltUGFyYW0gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZGltUGFyYW0nKSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovIDE4KS5zdHJpbmcobWVzc2FnZS5kaW1QYXJhbSk7XG4gICAgICAgIGlmIChtZXNzYWdlLmRlbm90YXRpb24gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZGVub3RhdGlvbicpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMywgd2lyZVR5cGUgMiA9Ki8gMjYpLnN0cmluZyhtZXNzYWdlLmRlbm90YXRpb24pO1xuICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgRGltZW5zaW9uIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uSURpbWVuc2lvbn0gbWVzc2FnZSBEaW1lbnNpb24gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBEaW1lbnNpb24gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbn0gRGltZW5zaW9uXG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIERpbWVuc2lvbi5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbigpO1xuICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgICBtZXNzYWdlLmRpbVZhbHVlID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UuZGltUGFyYW0gPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAzOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UuZGVub3RhdGlvbiA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRGVjb2RlcyBhIERpbWVuc2lvbiBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb259IERpbWVuc2lvblxuICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICovXG4gICAgICBEaW1lbnNpb24uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogVmVyaWZpZXMgYSBEaW1lbnNpb24gbWVzc2FnZS5cbiAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgKi9cbiAgICAgIERpbWVuc2lvbi52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZGltVmFsdWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkaW1WYWx1ZScpKSB7XG4gICAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbVZhbHVlKSAmJlxuICAgICAgICAgICAgIShtZXNzYWdlLmRpbVZhbHVlICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbVZhbHVlLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltVmFsdWUuaGlnaCkpXG4gICAgICAgICAgKVxuICAgICAgICAgICAgcmV0dXJuICdkaW1WYWx1ZTogaW50ZWdlcnxMb25nIGV4cGVjdGVkJztcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5kaW1QYXJhbSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RpbVBhcmFtJykpIHtcbiAgICAgICAgICBpZiAocHJvcGVydGllcy52YWx1ZSA9PT0gMSkgcmV0dXJuICd2YWx1ZTogbXVsdGlwbGUgdmFsdWVzJztcbiAgICAgICAgICBwcm9wZXJ0aWVzLnZhbHVlID0gMTtcbiAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZGltUGFyYW0pKSByZXR1cm4gJ2RpbVBhcmFtOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXNzYWdlLmRlbm90YXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkZW5vdGF0aW9uJykpXG4gICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRlbm90YXRpb24pKSByZXR1cm4gJ2Rlbm90YXRpb246IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgRGltZW5zaW9uIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb259IERpbWVuc2lvblxuICAgICAgICovXG4gICAgICBEaW1lbnNpb24uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uKSByZXR1cm4gb2JqZWN0O1xuICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uKCk7XG4gICAgICAgIGlmIChvYmplY3QuZGltVmFsdWUgIT0gbnVsbClcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuZGltVmFsdWUgPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuZGltVmFsdWUpKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltVmFsdWUgPT09ICdzdHJpbmcnKSBtZXNzYWdlLmRpbVZhbHVlID0gcGFyc2VJbnQob2JqZWN0LmRpbVZhbHVlLCAxMCk7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5kaW1WYWx1ZSA9PT0gJ251bWJlcicpIG1lc3NhZ2UuZGltVmFsdWUgPSBvYmplY3QuZGltVmFsdWU7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5kaW1WYWx1ZSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBtZXNzYWdlLmRpbVZhbHVlID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC5kaW1WYWx1ZS5sb3cgPj4+IDAsIG9iamVjdC5kaW1WYWx1ZS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICBpZiAob2JqZWN0LmRpbVBhcmFtICE9IG51bGwpIG1lc3NhZ2UuZGltUGFyYW0gPSBTdHJpbmcob2JqZWN0LmRpbVBhcmFtKTtcbiAgICAgICAgaWYgKG9iamVjdC5kZW5vdGF0aW9uICE9IG51bGwpIG1lc3NhZ2UuZGVub3RhdGlvbiA9IFN0cmluZyhvYmplY3QuZGVub3RhdGlvbik7XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBEaW1lbnNpb24gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9ufSBtZXNzYWdlIERpbWVuc2lvblxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICovXG4gICAgICBEaW1lbnNpb24udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSBvYmplY3QuZGVub3RhdGlvbiA9ICcnO1xuICAgICAgICBpZiAobWVzc2FnZS5kaW1WYWx1ZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RpbVZhbHVlJykpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuZGltVmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgb2JqZWN0LmRpbVZhbHVlID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuZGltVmFsdWUpIDogbWVzc2FnZS5kaW1WYWx1ZTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBvYmplY3QuZGltVmFsdWUgPVxuICAgICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5kaW1WYWx1ZSlcbiAgICAgICAgICAgICAgICA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlclxuICAgICAgICAgICAgICAgICAgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS5kaW1WYWx1ZS5sb3cgPj4+IDAsIG1lc3NhZ2UuZGltVmFsdWUuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgICAgOiBtZXNzYWdlLmRpbVZhbHVlO1xuICAgICAgICAgIGlmIChvcHRpb25zLm9uZW9mcykgb2JqZWN0LnZhbHVlID0gJ2RpbVZhbHVlJztcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5kaW1QYXJhbSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RpbVBhcmFtJykpIHtcbiAgICAgICAgICBvYmplY3QuZGltUGFyYW0gPSBtZXNzYWdlLmRpbVBhcmFtO1xuICAgICAgICAgIGlmIChvcHRpb25zLm9uZW9mcykgb2JqZWN0LnZhbHVlID0gJ2RpbVBhcmFtJztcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5kZW5vdGF0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZGVub3RhdGlvbicpKSBvYmplY3QuZGVub3RhdGlvbiA9IG1lc3NhZ2UuZGVub3RhdGlvbjtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ29udmVydHMgdGhpcyBEaW1lbnNpb24gdG8gSlNPTi5cbiAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBEaW1lbnNpb25cbiAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICovXG4gICAgICBEaW1lbnNpb24uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbic7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gRGltZW5zaW9uO1xuICAgIH0pKCk7XG5cbiAgICByZXR1cm4gVGVuc29yU2hhcGVQcm90bztcbiAgfSkoKTtcblxuICBvbm54LlR5cGVQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhIFR5cGVQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSVR5cGVQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UeXBlUHJvdG8uSVRlbnNvcnxudWxsfSBbdGVuc29yVHlwZV0gVHlwZVByb3RvIHRlbnNvclR5cGVcbiAgICAgKiBAcHJvcGVydHkge29ubnguVHlwZVByb3RvLklTZXF1ZW5jZXxudWxsfSBbc2VxdWVuY2VUeXBlXSBUeXBlUHJvdG8gc2VxdWVuY2VUeXBlXG4gICAgICogQHByb3BlcnR5IHtvbm54LlR5cGVQcm90by5JTWFwfG51bGx9IFttYXBUeXBlXSBUeXBlUHJvdG8gbWFwVHlwZVxuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UeXBlUHJvdG8uSU9wdGlvbmFsfG51bGx9IFtvcHRpb25hbFR5cGVdIFR5cGVQcm90byBvcHRpb25hbFR5cGVcbiAgICAgKiBAcHJvcGVydHkge29ubnguVHlwZVByb3RvLklTcGFyc2VUZW5zb3J8bnVsbH0gW3NwYXJzZVRlbnNvclR5cGVdIFR5cGVQcm90byBzcGFyc2VUZW5zb3JUeXBlXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2Rlbm90YXRpb25dIFR5cGVQcm90byBkZW5vdGF0aW9uXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFR5cGVQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFR5cGVQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJVHlwZVByb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklUeXBlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBUeXBlUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFR5cGVQcm90byB0ZW5zb3JUeXBlLlxuICAgICAqIEBtZW1iZXIge29ubnguVHlwZVByb3RvLklUZW5zb3J8bnVsbHx1bmRlZmluZWR9IHRlbnNvclR5cGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8ucHJvdG90eXBlLnRlbnNvclR5cGUgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVHlwZVByb3RvIHNlcXVlbmNlVHlwZS5cbiAgICAgKiBAbWVtYmVyIHtvbm54LlR5cGVQcm90by5JU2VxdWVuY2V8bnVsbHx1bmRlZmluZWR9IHNlcXVlbmNlVHlwZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFR5cGVQcm90by5wcm90b3R5cGUuc2VxdWVuY2VUeXBlID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFR5cGVQcm90byBtYXBUeXBlLlxuICAgICAqIEBtZW1iZXIge29ubnguVHlwZVByb3RvLklNYXB8bnVsbHx1bmRlZmluZWR9IG1hcFR5cGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8ucHJvdG90eXBlLm1hcFR5cGUgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVHlwZVByb3RvIG9wdGlvbmFsVHlwZS5cbiAgICAgKiBAbWVtYmVyIHtvbm54LlR5cGVQcm90by5JT3B0aW9uYWx8bnVsbHx1bmRlZmluZWR9IG9wdGlvbmFsVHlwZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFR5cGVQcm90by5wcm90b3R5cGUub3B0aW9uYWxUeXBlID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFR5cGVQcm90byBzcGFyc2VUZW5zb3JUeXBlLlxuICAgICAqIEBtZW1iZXIge29ubnguVHlwZVByb3RvLklTcGFyc2VUZW5zb3J8bnVsbHx1bmRlZmluZWR9IHNwYXJzZVRlbnNvclR5cGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8ucHJvdG90eXBlLnNwYXJzZVRlbnNvclR5cGUgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVHlwZVByb3RvIGRlbm90YXRpb24uXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkZW5vdGF0aW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVHlwZVByb3RvLnByb3RvdHlwZS5kZW5vdGF0aW9uID0gJyc7XG5cbiAgICAvLyBPbmVPZiBmaWVsZCBuYW1lcyBib3VuZCB0byB2aXJ0dWFsIGdldHRlcnMgYW5kIHNldHRlcnNcbiAgICB2YXIgJG9uZU9mRmllbGRzO1xuXG4gICAgLyoqXG4gICAgICogVHlwZVByb3RvIHZhbHVlLlxuICAgICAqIEBtZW1iZXIge1widGVuc29yVHlwZVwifFwic2VxdWVuY2VUeXBlXCJ8XCJtYXBUeXBlXCJ8XCJvcHRpb25hbFR5cGVcInxcInNwYXJzZVRlbnNvclR5cGVcInx1bmRlZmluZWR9IHZhbHVlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFR5cGVQcm90by5wcm90b3R5cGUsICd2YWx1ZScsIHtcbiAgICAgIGdldDogJHV0aWwub25lT2ZHZXR0ZXIoXG4gICAgICAgICgkb25lT2ZGaWVsZHMgPSBbJ3RlbnNvclR5cGUnLCAnc2VxdWVuY2VUeXBlJywgJ21hcFR5cGUnLCAnb3B0aW9uYWxUeXBlJywgJ3NwYXJzZVRlbnNvclR5cGUnXSksXG4gICAgICApLFxuICAgICAgc2V0OiAkdXRpbC5vbmVPZlNldHRlcigkb25lT2ZGaWVsZHMpLFxuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBUeXBlUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUeXBlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG99IFR5cGVQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIFR5cGVQcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBUeXBlUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUeXBlUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVR5cGVQcm90b30gbWVzc2FnZSBUeXBlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFR5cGVQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLnRlbnNvclR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAndGVuc29yVHlwZScpKVxuICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IuZW5jb2RlKFxuICAgICAgICAgIG1lc3NhZ2UudGVuc29yVHlwZSxcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovIDEwKS5mb3JrKCksXG4gICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5zZXF1ZW5jZVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnc2VxdWVuY2VUeXBlJykpXG4gICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLmVuY29kZShcbiAgICAgICAgICBtZXNzYWdlLnNlcXVlbmNlVHlwZSxcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDQsIHdpcmVUeXBlIDIgPSovIDM0KS5mb3JrKCksXG4gICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5tYXBUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ21hcFR5cGUnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uTWFwLmVuY29kZShtZXNzYWdlLm1hcFR5cGUsIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki8gNDIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5kZW5vdGF0aW9uICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2Rlbm90YXRpb24nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA2LCB3aXJlVHlwZSAyID0qLyA1MCkuc3RyaW5nKG1lc3NhZ2UuZGVub3RhdGlvbik7XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VUZW5zb3JUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3NwYXJzZVRlbnNvclR5cGUnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yLmVuY29kZShcbiAgICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvclR5cGUsXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA4LCB3aXJlVHlwZSAyID0qLyA2NikuZm9yaygpLFxuICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2Uub3B0aW9uYWxUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ29wdGlvbmFsVHlwZScpKVxuICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5PcHRpb25hbC5lbmNvZGUoXG4gICAgICAgICAgbWVzc2FnZS5vcHRpb25hbFR5cGUsXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA5LCB3aXJlVHlwZSAyID0qLyA3NCkuZm9yaygpLFxuICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFR5cGVQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVHlwZVByb3RvfSBtZXNzYWdlIFR5cGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVHlwZVByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVHlwZVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90b30gVHlwZVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgbWVzc2FnZS50ZW5zb3JUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA0OiB7XG4gICAgICAgICAgICBtZXNzYWdlLnNlcXVlbmNlVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA1OiB7XG4gICAgICAgICAgICBtZXNzYWdlLm1hcFR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5NYXAuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDk6IHtcbiAgICAgICAgICAgIG1lc3NhZ2Uub3B0aW9uYWxUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uT3B0aW9uYWwuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDg6IHtcbiAgICAgICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvci5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNjoge1xuICAgICAgICAgICAgbWVzc2FnZS5kZW5vdGF0aW9uID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBUeXBlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90b30gVHlwZVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIFR5cGVQcm90byBtZXNzYWdlLlxuICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcbiAgICAgIGlmIChtZXNzYWdlLnRlbnNvclR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0ZW5zb3JUeXBlJykpIHtcbiAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IudmVyaWZ5KG1lc3NhZ2UudGVuc29yVHlwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3RlbnNvclR5cGUuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zZXF1ZW5jZVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzZXF1ZW5jZVR5cGUnKSkge1xuICAgICAgICBpZiAocHJvcGVydGllcy52YWx1ZSA9PT0gMSkgcmV0dXJuICd2YWx1ZTogbXVsdGlwbGUgdmFsdWVzJztcbiAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by5TZXF1ZW5jZS52ZXJpZnkobWVzc2FnZS5zZXF1ZW5jZVR5cGUpO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdzZXF1ZW5jZVR5cGUuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5tYXBUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbWFwVHlwZScpKSB7XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnZhbHVlID09PSAxKSByZXR1cm4gJ3ZhbHVlOiBtdWx0aXBsZSB2YWx1ZXMnO1xuICAgICAgICBwcm9wZXJ0aWVzLnZhbHVlID0gMTtcbiAgICAgICAge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLk1hcC52ZXJpZnkobWVzc2FnZS5tYXBUeXBlKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnbWFwVHlwZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm9wdGlvbmFsVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ29wdGlvbmFsVHlwZScpKSB7XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnZhbHVlID09PSAxKSByZXR1cm4gJ3ZhbHVlOiBtdWx0aXBsZSB2YWx1ZXMnO1xuICAgICAgICBwcm9wZXJ0aWVzLnZhbHVlID0gMTtcbiAgICAgICAge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLk9wdGlvbmFsLnZlcmlmeShtZXNzYWdlLm9wdGlvbmFsVHlwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ29wdGlvbmFsVHlwZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnNwYXJzZVRlbnNvclR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzcGFyc2VUZW5zb3JUeXBlJykpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMudmFsdWUgPT09IDEpIHJldHVybiAndmFsdWU6IG11bHRpcGxlIHZhbHVlcyc7XG4gICAgICAgIHByb3BlcnRpZXMudmFsdWUgPSAxO1xuICAgICAgICB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yLnZlcmlmeShtZXNzYWdlLnNwYXJzZVRlbnNvclR5cGUpO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdzcGFyc2VUZW5zb3JUeXBlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZGVub3RhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2Rlbm90YXRpb24nKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRlbm90YXRpb24pKSByZXR1cm4gJ2Rlbm90YXRpb246IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFR5cGVQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90b30gVHlwZVByb3RvXG4gICAgICovXG4gICAgVHlwZVByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVHlwZVByb3RvKSByZXR1cm4gb2JqZWN0O1xuICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QudGVuc29yVHlwZSAhPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnRlbnNvclR5cGUgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlR5cGVQcm90by50ZW5zb3JUeXBlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS50ZW5zb3JUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yLmZyb21PYmplY3Qob2JqZWN0LnRlbnNvclR5cGUpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5zZXF1ZW5jZVR5cGUgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zZXF1ZW5jZVR5cGUgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlR5cGVQcm90by5zZXF1ZW5jZVR5cGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnNlcXVlbmNlVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLmZyb21PYmplY3Qob2JqZWN0LnNlcXVlbmNlVHlwZSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0Lm1hcFR5cGUgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5tYXBUeXBlICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8ubWFwVHlwZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UubWFwVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLk1hcC5mcm9tT2JqZWN0KG9iamVjdC5tYXBUeXBlKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Qub3B0aW9uYWxUeXBlICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Qub3B0aW9uYWxUeXBlICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8ub3B0aW9uYWxUeXBlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5vcHRpb25hbFR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5PcHRpb25hbC5mcm9tT2JqZWN0KG9iamVjdC5vcHRpb25hbFR5cGUpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5zcGFyc2VUZW5zb3JUeXBlICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3BhcnNlVGVuc29yVHlwZSAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8uc3BhcnNlVGVuc29yVHlwZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvci5mcm9tT2JqZWN0KG9iamVjdC5zcGFyc2VUZW5zb3JUeXBlKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZGVub3RhdGlvbiAhPSBudWxsKSBtZXNzYWdlLmRlbm90YXRpb24gPSBTdHJpbmcob2JqZWN0LmRlbm90YXRpb24pO1xuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFR5cGVQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG99IG1lc3NhZ2UgVHlwZVByb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSBvYmplY3QuZGVub3RhdGlvbiA9ICcnO1xuICAgICAgaWYgKG1lc3NhZ2UudGVuc29yVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3RlbnNvclR5cGUnKSkge1xuICAgICAgICBvYmplY3QudGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlRlbnNvci50b09iamVjdChtZXNzYWdlLnRlbnNvclR5cGUsIG9wdGlvbnMpO1xuICAgICAgICBpZiAob3B0aW9ucy5vbmVvZnMpIG9iamVjdC52YWx1ZSA9ICd0ZW5zb3JUeXBlJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnNlcXVlbmNlVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NlcXVlbmNlVHlwZScpKSB7XG4gICAgICAgIG9iamVjdC5zZXF1ZW5jZVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5TZXF1ZW5jZS50b09iamVjdChtZXNzYWdlLnNlcXVlbmNlVHlwZSwgb3B0aW9ucyk7XG4gICAgICAgIGlmIChvcHRpb25zLm9uZW9mcykgb2JqZWN0LnZhbHVlID0gJ3NlcXVlbmNlVHlwZSc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5tYXBUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbWFwVHlwZScpKSB7XG4gICAgICAgIG9iamVjdC5tYXBUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uTWFwLnRvT2JqZWN0KG1lc3NhZ2UubWFwVHlwZSwgb3B0aW9ucyk7XG4gICAgICAgIGlmIChvcHRpb25zLm9uZW9mcykgb2JqZWN0LnZhbHVlID0gJ21hcFR5cGUnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZGVub3RhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2Rlbm90YXRpb24nKSkgb2JqZWN0LmRlbm90YXRpb24gPSBtZXNzYWdlLmRlbm90YXRpb247XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VUZW5zb3JUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc3BhcnNlVGVuc29yVHlwZScpKSB7XG4gICAgICAgIG9iamVjdC5zcGFyc2VUZW5zb3JUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yLnRvT2JqZWN0KG1lc3NhZ2Uuc3BhcnNlVGVuc29yVHlwZSwgb3B0aW9ucyk7XG4gICAgICAgIGlmIChvcHRpb25zLm9uZW9mcykgb2JqZWN0LnZhbHVlID0gJ3NwYXJzZVRlbnNvclR5cGUnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uub3B0aW9uYWxUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnb3B0aW9uYWxUeXBlJykpIHtcbiAgICAgICAgb2JqZWN0Lm9wdGlvbmFsVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLk9wdGlvbmFsLnRvT2JqZWN0KG1lc3NhZ2Uub3B0aW9uYWxUeXBlLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKG9wdGlvbnMub25lb2ZzKSBvYmplY3QudmFsdWUgPSAnb3B0aW9uYWxUeXBlJztcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgVHlwZVByb3RvIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBUeXBlUHJvdG9cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIFR5cGVQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UeXBlUHJvdG8nO1xuICAgIH07XG5cbiAgICBUeXBlUHJvdG8uVGVuc29yID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogUHJvcGVydGllcyBvZiBhIFRlbnNvci5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGludGVyZmFjZSBJVGVuc29yXG4gICAgICAgKiBAcHJvcGVydHkge251bWJlcnxudWxsfSBbZWxlbVR5cGVdIFRlbnNvciBlbGVtVHlwZVxuICAgICAgICogQHByb3BlcnR5IHtvbm54LklUZW5zb3JTaGFwZVByb3RvfG51bGx9IFtzaGFwZV0gVGVuc29yIHNoYXBlXG4gICAgICAgKi9cblxuICAgICAgLyoqXG4gICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFRlbnNvci5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgVGVuc29yLlxuICAgICAgICogQGltcGxlbWVudHMgSVRlbnNvclxuICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklUZW5zb3I9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24gVGVuc29yKHByb3BlcnRpZXMpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBUZW5zb3IgZWxlbVR5cGUuXG4gICAgICAgKiBAbWVtYmVyIHtudW1iZXJ9IGVsZW1UeXBlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgVGVuc29yLnByb3RvdHlwZS5lbGVtVHlwZSA9IDA7XG5cbiAgICAgIC8qKlxuICAgICAgICogVGVuc29yIHNoYXBlLlxuICAgICAgICogQG1lbWJlciB7b25ueC5JVGVuc29yU2hhcGVQcm90b3xudWxsfHVuZGVmaW5lZH0gc2hhcGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBUZW5zb3IucHJvdG90eXBlLnNoYXBlID0gbnVsbDtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgbmV3IFRlbnNvciBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklUZW5zb3I9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5UZW5zb3J9IFRlbnNvciBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBUZW5zb3IuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZW5zb3IocHJvcGVydGllcyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3IgbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8uVGVuc29yLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JVGVuc29yfSBtZXNzYWdlIFRlbnNvciBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICovXG4gICAgICBUZW5zb3IuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZWxlbVR5cGUnKSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDAgPSovIDgpLmludDMyKG1lc3NhZ2UuZWxlbVR5cGUpO1xuICAgICAgICBpZiAobWVzc2FnZS5zaGFwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdzaGFwZScpKVxuICAgICAgICAgICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5lbmNvZGUobWVzc2FnZS5zaGFwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLyAxOCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvciBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5UZW5zb3IudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklUZW5zb3J9IG1lc3NhZ2UgVGVuc29yIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIFRlbnNvci5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGEgVGVuc29yIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uVGVuc29yfSBUZW5zb3JcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgVGVuc29yLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IoKTtcbiAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgbWVzc2FnZS5lbGVtVHlwZSA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgICBtZXNzYWdlLnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBUZW5zb3IgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlRlbnNvcn0gVGVuc29yXG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIFRlbnNvci5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBWZXJpZmllcyBhIFRlbnNvciBtZXNzYWdlLlxuICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICovXG4gICAgICBUZW5zb3IudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZWxlbVR5cGUnKSlcbiAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmVsZW1UeXBlKSkgcmV0dXJuICdlbGVtVHlwZTogaW50ZWdlciBleHBlY3RlZCc7XG4gICAgICAgIGlmIChtZXNzYWdlLnNoYXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc2hhcGUnKSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by52ZXJpZnkobWVzc2FnZS5zaGFwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3NoYXBlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIFRlbnNvciBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlRlbnNvcn0gVGVuc29yXG4gICAgICAgKi9cbiAgICAgIFRlbnNvci5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVHlwZVByb3RvLlRlbnNvcikgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yKCk7XG4gICAgICAgIGlmIChvYmplY3QuZWxlbVR5cGUgIT0gbnVsbCkgbWVzc2FnZS5lbGVtVHlwZSA9IG9iamVjdC5lbGVtVHlwZSB8IDA7XG4gICAgICAgIGlmIChvYmplY3Quc2hhcGUgIT0gbnVsbCkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnNoYXBlICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8uVGVuc29yLnNoYXBlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LnNoYXBlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgVGVuc29yIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5UZW5zb3J9IG1lc3NhZ2UgVGVuc29yXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIFRlbnNvci50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICBvYmplY3QuZWxlbVR5cGUgPSAwO1xuICAgICAgICAgIG9iamVjdC5zaGFwZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdlbGVtVHlwZScpKSBvYmplY3QuZWxlbVR5cGUgPSBtZXNzYWdlLmVsZW1UeXBlO1xuICAgICAgICBpZiAobWVzc2FnZS5zaGFwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NoYXBlJykpXG4gICAgICAgICAgb2JqZWN0LnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uuc2hhcGUsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDb252ZXJ0cyB0aGlzIFRlbnNvciB0byBKU09OLlxuICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIFRlbnNvci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgVGVuc29yXG4gICAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICovXG4gICAgICBUZW5zb3IuZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UeXBlUHJvdG8uVGVuc29yJztcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBUZW5zb3I7XG4gICAgfSkoKTtcblxuICAgIFR5cGVQcm90by5TZXF1ZW5jZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAvKipcbiAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBTZXF1ZW5jZS5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGludGVyZmFjZSBJU2VxdWVuY2VcbiAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVHlwZVByb3RvfG51bGx9IFtlbGVtVHlwZV0gU2VxdWVuY2UgZWxlbVR5cGVcbiAgICAgICAqL1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgU2VxdWVuY2UuXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFNlcXVlbmNlLlxuICAgICAgICogQGltcGxlbWVudHMgSVNlcXVlbmNlXG4gICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNlcXVlbmNlPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKi9cbiAgICAgIGZ1bmN0aW9uIFNlcXVlbmNlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBTZXF1ZW5jZSBlbGVtVHlwZS5cbiAgICAgICAqIEBtZW1iZXIge29ubnguSVR5cGVQcm90b3xudWxsfHVuZGVmaW5lZH0gZWxlbVR5cGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIFNlcXVlbmNlLnByb3RvdHlwZS5lbGVtVHlwZSA9IG51bGw7XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIG5ldyBTZXF1ZW5jZSBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNlcXVlbmNlPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uU2VxdWVuY2V9IFNlcXVlbmNlIGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIFNlcXVlbmNlLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2VxdWVuY2UocHJvcGVydGllcyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTZXF1ZW5jZSBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5TZXF1ZW5jZS52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JU2VxdWVuY2V9IG1lc3NhZ2UgU2VxdWVuY2UgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgU2VxdWVuY2UuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZWxlbVR5cGUnKSlcbiAgICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5lbmNvZGUobWVzc2FnZS5lbGVtVHlwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFNlcXVlbmNlIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklTZXF1ZW5jZX0gbWVzc2FnZSBTZXF1ZW5jZSBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICovXG4gICAgICBTZXF1ZW5jZS5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGEgU2VxdWVuY2UgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlNlcXVlbmNlfSBTZXF1ZW5jZVxuICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICovXG4gICAgICBTZXF1ZW5jZS5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uU2VxdWVuY2UoKTtcbiAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgbWVzc2FnZS5lbGVtVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBTZXF1ZW5jZSBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5TZXF1ZW5jZX0gU2VxdWVuY2VcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgU2VxdWVuY2UuZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogVmVyaWZpZXMgYSBTZXF1ZW5jZSBtZXNzYWdlLlxuICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgKi9cbiAgICAgIFNlcXVlbmNlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2VsZW1UeXBlJykpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by52ZXJpZnkobWVzc2FnZS5lbGVtVHlwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2VsZW1UeXBlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIFNlcXVlbmNlIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5TZXF1ZW5jZX0gU2VxdWVuY2VcbiAgICAgICAqL1xuICAgICAgU2VxdWVuY2UuZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlR5cGVQcm90by5TZXF1ZW5jZSkgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uU2VxdWVuY2UoKTtcbiAgICAgICAgaWYgKG9iamVjdC5lbGVtVHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZWxlbVR5cGUgIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8uU2VxdWVuY2UuZWxlbVR5cGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuZWxlbVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC5lbGVtVHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFNlcXVlbmNlIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLlNlcXVlbmNlfSBtZXNzYWdlIFNlcXVlbmNlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIFNlcXVlbmNlLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykgb2JqZWN0LmVsZW1UeXBlID0gbnVsbDtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdlbGVtVHlwZScpKVxuICAgICAgICAgIG9iamVjdC5lbGVtVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZWxlbVR5cGUsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDb252ZXJ0cyB0aGlzIFNlcXVlbmNlIHRvIEpTT04uXG4gICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICovXG4gICAgICBTZXF1ZW5jZS5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgU2VxdWVuY2VcbiAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAqL1xuICAgICAgU2VxdWVuY2UuZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UeXBlUHJvdG8uU2VxdWVuY2UnO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIFNlcXVlbmNlO1xuICAgIH0pKCk7XG5cbiAgICBUeXBlUHJvdG8uTWFwID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogUHJvcGVydGllcyBvZiBhIE1hcC5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGludGVyZmFjZSBJTWFwXG4gICAgICAgKiBAcHJvcGVydHkge251bWJlcnxudWxsfSBba2V5VHlwZV0gTWFwIGtleVR5cGVcbiAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVHlwZVByb3RvfG51bGx9IFt2YWx1ZVR5cGVdIE1hcCB2YWx1ZVR5cGVcbiAgICAgICAqL1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgTWFwLlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBNYXAuXG4gICAgICAgKiBAaW1wbGVtZW50cyBJTWFwXG4gICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU1hcD19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICovXG4gICAgICBmdW5jdGlvbiBNYXAocHJvcGVydGllcykge1xuICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgfVxuXG4gICAgICAvKipcbiAgICAgICAqIE1hcCBrZXlUeXBlLlxuICAgICAgICogQG1lbWJlciB7bnVtYmVyfSBrZXlUeXBlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgTWFwLnByb3RvdHlwZS5rZXlUeXBlID0gMDtcblxuICAgICAgLyoqXG4gICAgICAgKiBNYXAgdmFsdWVUeXBlLlxuICAgICAgICogQG1lbWJlciB7b25ueC5JVHlwZVByb3RvfG51bGx8dW5kZWZpbmVkfSB2YWx1ZVR5cGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBNYXAucHJvdG90eXBlLnZhbHVlVHlwZSA9IG51bGw7XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIG5ldyBNYXAgaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JTWFwPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uTWFwfSBNYXAgaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgTWFwLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHJldHVybiBuZXcgTWFwKHByb3BlcnRpZXMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgTWFwIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLk1hcC52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU1hcH0gbWVzc2FnZSBNYXAgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgTWFwLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgIGlmIChtZXNzYWdlLmtleVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAna2V5VHlwZScpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMCA9Ki8gOCkuaW50MzIobWVzc2FnZS5rZXlUeXBlKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UudmFsdWVUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3ZhbHVlVHlwZScpKVxuICAgICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLmVuY29kZShtZXNzYWdlLnZhbHVlVHlwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLyAxOCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE1hcCBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5NYXAudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklNYXB9IG1lc3NhZ2UgTWFwIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIE1hcC5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGEgTWFwIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uTWFwfSBNYXBcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgTWFwLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5NYXAoKTtcbiAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgbWVzc2FnZS5rZXlUeXBlID0gcmVhZGVyLmludDMyKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UudmFsdWVUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRGVjb2RlcyBhIE1hcCBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uTWFwfSBNYXBcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgTWFwLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIFZlcmlmaWVzIGEgTWFwIG1lc3NhZ2UuXG4gICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgKi9cbiAgICAgIE1hcC52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgICAgaWYgKG1lc3NhZ2Uua2V5VHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2tleVR5cGUnKSlcbiAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmtleVR5cGUpKSByZXR1cm4gJ2tleVR5cGU6IGludGVnZXIgZXhwZWN0ZWQnO1xuICAgICAgICBpZiAobWVzc2FnZS52YWx1ZVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd2YWx1ZVR5cGUnKSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLnZlcmlmeShtZXNzYWdlLnZhbHVlVHlwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3ZhbHVlVHlwZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBNYXAgbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5NYXB9IE1hcFxuICAgICAgICovXG4gICAgICBNYXAuZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlR5cGVQcm90by5NYXApIHJldHVybiBvYmplY3Q7XG4gICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLk1hcCgpO1xuICAgICAgICBpZiAob2JqZWN0LmtleVR5cGUgIT0gbnVsbCkgbWVzc2FnZS5rZXlUeXBlID0gb2JqZWN0LmtleVR5cGUgfCAwO1xuICAgICAgICBpZiAob2JqZWN0LnZhbHVlVHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudmFsdWVUeXBlICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8uTWFwLnZhbHVlVHlwZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS52YWx1ZVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC52YWx1ZVR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBNYXAgbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLk1hcH0gbWVzc2FnZSBNYXBcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgTWFwLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgIG9iamVjdC5rZXlUeXBlID0gMDtcbiAgICAgICAgICBvYmplY3QudmFsdWVUeXBlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5rZXlUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgna2V5VHlwZScpKSBvYmplY3Qua2V5VHlwZSA9IG1lc3NhZ2Uua2V5VHlwZTtcbiAgICAgICAgaWYgKG1lc3NhZ2UudmFsdWVUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWVUeXBlJykpXG4gICAgICAgICAgb2JqZWN0LnZhbHVlVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudmFsdWVUeXBlLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ29udmVydHMgdGhpcyBNYXAgdG8gSlNPTi5cbiAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICovXG4gICAgICBNYXAucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIE1hcFxuICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAqL1xuICAgICAgTWFwLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguVHlwZVByb3RvLk1hcCc7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gTWFwO1xuICAgIH0pKCk7XG5cbiAgICBUeXBlUHJvdG8uT3B0aW9uYWwgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgLyoqXG4gICAgICAgKiBQcm9wZXJ0aWVzIG9mIGFuIE9wdGlvbmFsLlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgKiBAaW50ZXJmYWNlIElPcHRpb25hbFxuICAgICAgICogQHByb3BlcnR5IHtvbm54LklUeXBlUHJvdG98bnVsbH0gW2VsZW1UeXBlXSBPcHRpb25hbCBlbGVtVHlwZVxuICAgICAgICovXG5cbiAgICAgIC8qKlxuICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBPcHRpb25hbC5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGFuIE9wdGlvbmFsLlxuICAgICAgICogQGltcGxlbWVudHMgSU9wdGlvbmFsXG4gICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU9wdGlvbmFsPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKi9cbiAgICAgIGZ1bmN0aW9uIE9wdGlvbmFsKHByb3BlcnRpZXMpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBPcHRpb25hbCBlbGVtVHlwZS5cbiAgICAgICAqIEBtZW1iZXIge29ubnguSVR5cGVQcm90b3xudWxsfHVuZGVmaW5lZH0gZWxlbVR5cGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLnByb3RvdHlwZS5lbGVtVHlwZSA9IG51bGw7XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIG5ldyBPcHRpb25hbCBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU9wdGlvbmFsPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uT3B0aW9uYWx9IE9wdGlvbmFsIGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHJldHVybiBuZXcgT3B0aW9uYWwocHJvcGVydGllcyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBPcHRpb25hbCBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5PcHRpb25hbC52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JT3B0aW9uYWx9IG1lc3NhZ2UgT3B0aW9uYWwgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgT3B0aW9uYWwuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZWxlbVR5cGUnKSlcbiAgICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5lbmNvZGUobWVzc2FnZS5lbGVtVHlwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE9wdGlvbmFsIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklPcHRpb25hbH0gbWVzc2FnZSBPcHRpb25hbCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICovXG4gICAgICBPcHRpb25hbC5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGFuIE9wdGlvbmFsIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5PcHRpb25hbH0gT3B0aW9uYWxcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgT3B0aW9uYWwuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLk9wdGlvbmFsKCk7XG4gICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UuZWxlbVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGFuIE9wdGlvbmFsIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLk9wdGlvbmFsfSBPcHRpb25hbFxuICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICovXG4gICAgICBPcHRpb25hbC5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBWZXJpZmllcyBhbiBPcHRpb25hbCBtZXNzYWdlLlxuICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2VsZW1UeXBlJykpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by52ZXJpZnkobWVzc2FnZS5lbGVtVHlwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2VsZW1UeXBlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhbiBPcHRpb25hbCBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uT3B0aW9uYWx9IE9wdGlvbmFsXG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UeXBlUHJvdG8uT3B0aW9uYWwpIHJldHVybiBvYmplY3Q7XG4gICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLk9wdGlvbmFsKCk7XG4gICAgICAgIGlmIChvYmplY3QuZWxlbVR5cGUgIT0gbnVsbCkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmVsZW1UeXBlICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguVHlwZVByb3RvLk9wdGlvbmFsLmVsZW1UeXBlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLmVsZW1UeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZWxlbVR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYW4gT3B0aW9uYWwgbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uT3B0aW9uYWx9IG1lc3NhZ2UgT3B0aW9uYWxcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgT3B0aW9uYWwudG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSBvYmplY3QuZWxlbVR5cGUgPSBudWxsO1xuICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2VsZW1UeXBlJykpXG4gICAgICAgICAgb2JqZWN0LmVsZW1UeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8udG9PYmplY3QobWVzc2FnZS5lbGVtVHlwZSwgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnZlcnRzIHRoaXMgT3B0aW9uYWwgdG8gSlNPTi5cbiAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBPcHRpb25hbFxuICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICovXG4gICAgICBPcHRpb25hbC5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlR5cGVQcm90by5PcHRpb25hbCc7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gT3B0aW9uYWw7XG4gICAgfSkoKTtcblxuICAgIFR5cGVQcm90by5TcGFyc2VUZW5zb3IgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgLyoqXG4gICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgU3BhcnNlVGVuc29yLlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgKiBAaW50ZXJmYWNlIElTcGFyc2VUZW5zb3JcbiAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfG51bGx9IFtlbGVtVHlwZV0gU3BhcnNlVGVuc29yIGVsZW1UeXBlXG4gICAgICAgKiBAcHJvcGVydHkge29ubnguSVRlbnNvclNoYXBlUHJvdG98bnVsbH0gW3NoYXBlXSBTcGFyc2VUZW5zb3Igc2hhcGVcbiAgICAgICAqL1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgU3BhcnNlVGVuc29yLlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBTcGFyc2VUZW5zb3IuXG4gICAgICAgKiBAaW1wbGVtZW50cyBJU3BhcnNlVGVuc29yXG4gICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNwYXJzZVRlbnNvcj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICovXG4gICAgICBmdW5jdGlvbiBTcGFyc2VUZW5zb3IocHJvcGVydGllcykge1xuICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgfVxuXG4gICAgICAvKipcbiAgICAgICAqIFNwYXJzZVRlbnNvciBlbGVtVHlwZS5cbiAgICAgICAqIEBtZW1iZXIge251bWJlcn0gZWxlbVR5cGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBTcGFyc2VUZW5zb3IucHJvdG90eXBlLmVsZW1UeXBlID0gMDtcblxuICAgICAgLyoqXG4gICAgICAgKiBTcGFyc2VUZW5zb3Igc2hhcGUuXG4gICAgICAgKiBAbWVtYmVyIHtvbm54LklUZW5zb3JTaGFwZVByb3RvfG51bGx8dW5kZWZpbmVkfSBzaGFwZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvclxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci5wcm90b3R5cGUuc2hhcGUgPSBudWxsO1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBuZXcgU3BhcnNlVGVuc29yIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNwYXJzZVRlbnNvcj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcn0gU3BhcnNlVGVuc29yIGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICByZXR1cm4gbmV3IFNwYXJzZVRlbnNvcihwcm9wZXJ0aWVzKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFNwYXJzZVRlbnNvciBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3IudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklTcGFyc2VUZW5zb3J9IG1lc3NhZ2UgU3BhcnNlVGVuc29yIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdlbGVtVHlwZScpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMCA9Ki8gOCkuaW50MzIobWVzc2FnZS5lbGVtVHlwZSk7XG4gICAgICAgIGlmIChtZXNzYWdlLnNoYXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3NoYXBlJykpXG4gICAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLmVuY29kZShtZXNzYWdlLnNoYXBlLCB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovIDE4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU3BhcnNlVGVuc29yIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvci52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNwYXJzZVRlbnNvcn0gbWVzc2FnZSBTcGFyc2VUZW5zb3IgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgU3BhcnNlVGVuc29yLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBTcGFyc2VUZW5zb3IgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3J9IFNwYXJzZVRlbnNvclxuICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICovXG4gICAgICBTcGFyc2VUZW5zb3IuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcigpO1xuICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgICBtZXNzYWdlLmVsZW1UeXBlID0gcmVhZGVyLmludDMyKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2Uuc2hhcGUgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRGVjb2RlcyBhIFNwYXJzZVRlbnNvciBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yfSBTcGFyc2VUZW5zb3JcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgU3BhcnNlVGVuc29yLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIFZlcmlmaWVzIGEgU3BhcnNlVGVuc29yIG1lc3NhZ2UuXG4gICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdlbGVtVHlwZScpKVxuICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZWxlbVR5cGUpKSByZXR1cm4gJ2VsZW1UeXBlOiBpbnRlZ2VyIGV4cGVjdGVkJztcbiAgICAgICAgaWYgKG1lc3NhZ2Uuc2hhcGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzaGFwZScpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLnZlcmlmeShtZXNzYWdlLnNoYXBlKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnc2hhcGUuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgU3BhcnNlVGVuc29yIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yfSBTcGFyc2VUZW5zb3JcbiAgICAgICAqL1xuICAgICAgU3BhcnNlVGVuc29yLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yKSByZXR1cm4gb2JqZWN0O1xuICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3IoKTtcbiAgICAgICAgaWYgKG9iamVjdC5lbGVtVHlwZSAhPSBudWxsKSBtZXNzYWdlLmVsZW1UeXBlID0gb2JqZWN0LmVsZW1UeXBlIHwgMDtcbiAgICAgICAgaWYgKG9iamVjdC5zaGFwZSAhPSBudWxsKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc2hhcGUgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3Iuc2hhcGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2Uuc2hhcGUgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uZnJvbU9iamVjdChvYmplY3Quc2hhcGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBTcGFyc2VUZW5zb3IgbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcn0gbWVzc2FnZSBTcGFyc2VUZW5zb3JcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgU3BhcnNlVGVuc29yLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgIG9iamVjdC5lbGVtVHlwZSA9IDA7XG4gICAgICAgICAgb2JqZWN0LnNoYXBlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2VsZW1UeXBlJykpIG9iamVjdC5lbGVtVHlwZSA9IG1lc3NhZ2UuZWxlbVR5cGU7XG4gICAgICAgIGlmIChtZXNzYWdlLnNoYXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc2hhcGUnKSlcbiAgICAgICAgICBvYmplY3Quc2hhcGUgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8udG9PYmplY3QobWVzc2FnZS5zaGFwZSwgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnZlcnRzIHRoaXMgU3BhcnNlVGVuc29yIHRvIEpTT04uXG4gICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgU3BhcnNlVGVuc29yLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBTcGFyc2VUZW5zb3JcbiAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3InO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIFNwYXJzZVRlbnNvcjtcbiAgICB9KSgpO1xuXG4gICAgcmV0dXJuIFR5cGVQcm90bztcbiAgfSkoKTtcblxuICBvbm54Lk9wZXJhdG9yU2V0SWRQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhbiBPcGVyYXRvclNldElkUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElPcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9tYWluXSBPcGVyYXRvclNldElkUHJvdG8gZG9tYWluXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbdmVyc2lvbl0gT3BlcmF0b3JTZXRJZFByb3RvIHZlcnNpb25cbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgT3BlcmF0b3JTZXRJZFByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGFuIE9wZXJhdG9yU2V0SWRQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklPcGVyYXRvclNldElkUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBPcGVyYXRvclNldElkUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9wZXJhdG9yU2V0SWRQcm90byBkb21haW4uXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkb21haW5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBPcGVyYXRvclNldElkUHJvdG8ucHJvdG90eXBlLmRvbWFpbiA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogT3BlcmF0b3JTZXRJZFByb3RvIHZlcnNpb24uXG4gICAgICogQG1lbWJlciB7bnVtYmVyfExvbmd9IHZlcnNpb25cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBPcGVyYXRvclNldElkUHJvdG8ucHJvdG90eXBlLnZlcnNpb24gPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLCAwLCBmYWxzZSkgOiAwO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBPcGVyYXRvclNldElkUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklPcGVyYXRvclNldElkUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5PcGVyYXRvclNldElkUHJvdG99IE9wZXJhdG9yU2V0SWRQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBPcGVyYXRvclNldElkUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5PcGVyYXRvclNldElkUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSU9wZXJhdG9yU2V0SWRQcm90b30gbWVzc2FnZSBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb21haW4nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuc3RyaW5nKG1lc3NhZ2UuZG9tYWluKTtcbiAgICAgIGlmIChtZXNzYWdlLnZlcnNpb24gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAndmVyc2lvbicpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDAgPSovIDE2KS5pbnQ2NChtZXNzYWdlLnZlcnNpb24pO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54Lk9wZXJhdG9yU2V0SWRQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvfSBtZXNzYWdlIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgT3BlcmF0b3JTZXRJZFByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGFuIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5PcGVyYXRvclNldElkUHJvdG99IE9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgT3BlcmF0b3JTZXRJZFByb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZG9tYWluID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS52ZXJzaW9uID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhbiBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54Lk9wZXJhdG9yU2V0SWRQcm90b30gT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBPcGVyYXRvclNldElkUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhbiBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgT3BlcmF0b3JTZXRJZFByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvbWFpbicpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9tYWluKSkgcmV0dXJuICdkb21haW46IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS52ZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmVyc2lvbicpKVxuICAgICAgICBpZiAoXG4gICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLnZlcnNpb24pICYmXG4gICAgICAgICAgIShtZXNzYWdlLnZlcnNpb24gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UudmVyc2lvbi5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLnZlcnNpb24uaGlnaCkpXG4gICAgICAgIClcbiAgICAgICAgICByZXR1cm4gJ3ZlcnNpb246IGludGVnZXJ8TG9uZyBleHBlY3RlZCc7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5PcGVyYXRvclNldElkUHJvdG99IE9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvKCk7XG4gICAgICBpZiAob2JqZWN0LmRvbWFpbiAhPSBudWxsKSBtZXNzYWdlLmRvbWFpbiA9IFN0cmluZyhvYmplY3QuZG9tYWluKTtcbiAgICAgIGlmIChvYmplY3QudmVyc2lvbiAhPSBudWxsKVxuICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UudmVyc2lvbiA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC52ZXJzaW9uKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC52ZXJzaW9uID09PSAnc3RyaW5nJykgbWVzc2FnZS52ZXJzaW9uID0gcGFyc2VJbnQob2JqZWN0LnZlcnNpb24sIDEwKTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC52ZXJzaW9uID09PSAnbnVtYmVyJykgbWVzc2FnZS52ZXJzaW9uID0gb2JqZWN0LnZlcnNpb247XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QudmVyc2lvbiA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgbWVzc2FnZS52ZXJzaW9uID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC52ZXJzaW9uLmxvdyA+Pj4gMCwgb2JqZWN0LnZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYW4gT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54Lk9wZXJhdG9yU2V0SWRQcm90b30gbWVzc2FnZSBPcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0LmRvbWFpbiA9ICcnO1xuICAgICAgICBpZiAoJHV0aWwuTG9uZykge1xuICAgICAgICAgIHZhciBsb25nID0gbmV3ICR1dGlsLkxvbmcoMCwgMCwgZmFsc2UpO1xuICAgICAgICAgIG9iamVjdC52ZXJzaW9uID1cbiAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgIH0gZWxzZSBvYmplY3QudmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICcwJyA6IDA7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb21haW4nKSkgb2JqZWN0LmRvbWFpbiA9IG1lc3NhZ2UuZG9tYWluO1xuICAgICAgaWYgKG1lc3NhZ2UudmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3ZlcnNpb24nKSlcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLnZlcnNpb24gPT09ICdudW1iZXInKVxuICAgICAgICAgIG9iamVjdC52ZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UudmVyc2lvbikgOiBtZXNzYWdlLnZlcnNpb247XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBvYmplY3QudmVyc2lvbiA9XG4gICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UudmVyc2lvbilcbiAgICAgICAgICAgICAgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXJcbiAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLnZlcnNpb24ubG93ID4+PiAwLCBtZXNzYWdlLnZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgIDogbWVzc2FnZS52ZXJzaW9uO1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBPcGVyYXRvclNldElkUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIE9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICovXG4gICAgT3BlcmF0b3JTZXRJZFByb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54Lk9wZXJhdG9yU2V0SWRQcm90byc7XG4gICAgfTtcblxuICAgIHJldHVybiBPcGVyYXRvclNldElkUHJvdG87XG4gIH0pKCk7XG5cbiAgLyoqXG4gICAqIE9wZXJhdG9yU3RhdHVzIGVudW0uXG4gICAqIEBuYW1lIG9ubnguT3BlcmF0b3JTdGF0dXNcbiAgICogQGVudW0ge251bWJlcn1cbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IEVYUEVSSU1FTlRBTD0wIEVYUEVSSU1FTlRBTCB2YWx1ZVxuICAgKiBAcHJvcGVydHkge251bWJlcn0gU1RBQkxFPTEgU1RBQkxFIHZhbHVlXG4gICAqL1xuICBvbm54Lk9wZXJhdG9yU3RhdHVzID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWVzQnlJZCA9IHt9LFxuICAgICAgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMF0gPSAnRVhQRVJJTUVOVEFMJyldID0gMDtcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMV0gPSAnU1RBQkxFJyldID0gMTtcbiAgICByZXR1cm4gdmFsdWVzO1xuICB9KSgpO1xuXG4gIG9ubnguRnVuY3Rpb25Qcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhIEZ1bmN0aW9uUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElGdW5jdGlvblByb3RvXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW25hbWVdIEZ1bmN0aW9uUHJvdG8gbmFtZVxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPHN0cmluZz58bnVsbH0gW2lucHV0XSBGdW5jdGlvblByb3RvIGlucHV0XG4gICAgICogQHByb3BlcnR5IHtBcnJheS48c3RyaW5nPnxudWxsfSBbb3V0cHV0XSBGdW5jdGlvblByb3RvIG91dHB1dFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPHN0cmluZz58bnVsbH0gW2F0dHJpYnV0ZV0gRnVuY3Rpb25Qcm90byBhdHRyaWJ1dGVcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklBdHRyaWJ1dGVQcm90bz58bnVsbH0gW2F0dHJpYnV0ZVByb3RvXSBGdW5jdGlvblByb3RvIGF0dHJpYnV0ZVByb3RvXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JTm9kZVByb3RvPnxudWxsfSBbbm9kZV0gRnVuY3Rpb25Qcm90byBub2RlXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvY1N0cmluZ10gRnVuY3Rpb25Qcm90byBkb2NTdHJpbmdcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklPcGVyYXRvclNldElkUHJvdG8+fG51bGx9IFtvcHNldEltcG9ydF0gRnVuY3Rpb25Qcm90byBvcHNldEltcG9ydFxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb21haW5dIEZ1bmN0aW9uUHJvdG8gZG9tYWluXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEZ1bmN0aW9uUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBGdW5jdGlvblByb3RvLlxuICAgICAqIEBpbXBsZW1lbnRzIElGdW5jdGlvblByb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklGdW5jdGlvblByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICovXG4gICAgZnVuY3Rpb24gRnVuY3Rpb25Qcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLmlucHV0ID0gW107XG4gICAgICB0aGlzLm91dHB1dCA9IFtdO1xuICAgICAgdGhpcy5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgIHRoaXMuYXR0cmlidXRlUHJvdG8gPSBbXTtcbiAgICAgIHRoaXMubm9kZSA9IFtdO1xuICAgICAgdGhpcy5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uUHJvdG8gbmFtZS5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUubmFtZSA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb25Qcm90byBpbnB1dC5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48c3RyaW5nPn0gaW5wdXRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUuaW5wdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb25Qcm90byBvdXRwdXQuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPHN0cmluZz59IG91dHB1dFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5vdXRwdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb25Qcm90byBhdHRyaWJ1dGUuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPHN0cmluZz59IGF0dHJpYnV0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5hdHRyaWJ1dGUgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb25Qcm90byBhdHRyaWJ1dGVQcm90by5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JQXR0cmlidXRlUHJvdG8+fSBhdHRyaWJ1dGVQcm90b1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5hdHRyaWJ1dGVQcm90byA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvblByb3RvIG5vZGUuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSU5vZGVQcm90bz59IG5vZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUubm9kZSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvblByb3RvIGRvY1N0cmluZy5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSAnJztcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uUHJvdG8gb3BzZXRJbXBvcnQuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSU9wZXJhdG9yU2V0SWRQcm90bz59IG9wc2V0SW1wb3J0XG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLm9wc2V0SW1wb3J0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uUHJvdG8gZG9tYWluLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9tYWluXG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLmRvbWFpbiA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBGdW5jdGlvblByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSUZ1bmN0aW9uUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5GdW5jdGlvblByb3RvfSBGdW5jdGlvblByb3RvIGluc3RhbmNlXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBGdW5jdGlvblByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgRnVuY3Rpb25Qcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LkZ1bmN0aW9uUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklGdW5jdGlvblByb3RvfSBtZXNzYWdlIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ25hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuc3RyaW5nKG1lc3NhZ2UubmFtZSk7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5wdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA0LCB3aXJlVHlwZSAyID0qLyAzNCkuc3RyaW5nKG1lc3NhZ2UuaW5wdXRbaV0pO1xuICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICE9IG51bGwgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki8gNDIpLnN0cmluZyhtZXNzYWdlLm91dHB1dFtpXSk7XG4gICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGUgIT0gbnVsbCAmJiBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoOyArK2kpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA2LCB3aXJlVHlwZSAyID0qLyA1MCkuc3RyaW5nKG1lc3NhZ2UuYXR0cmlidXRlW2ldKTtcbiAgICAgIGlmIChtZXNzYWdlLm5vZGUgIT0gbnVsbCAmJiBtZXNzYWdlLm5vZGUubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uubm9kZS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54Lk5vZGVQcm90by5lbmNvZGUobWVzc2FnZS5ub2RlW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDcsIHdpcmVUeXBlIDIgPSovIDU4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RvY1N0cmluZycpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDgsIHdpcmVUeXBlIDIgPSovIDY2KS5zdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpO1xuICAgICAgaWYgKG1lc3NhZ2Uub3BzZXRJbXBvcnQgIT0gbnVsbCAmJiBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2Uub3BzZXRJbXBvcnRbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDksIHdpcmVUeXBlIDIgPSovIDc0KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb21haW4nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMCwgd2lyZVR5cGUgMiA9Ki8gODIpLnN0cmluZyhtZXNzYWdlLmRvbWFpbik7XG4gICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGVQcm90byAhPSBudWxsICYmIG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8ubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8ubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMSwgd2lyZVR5cGUgMiA9Ki8gOTApLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5GdW5jdGlvblByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JRnVuY3Rpb25Qcm90b30gbWVzc2FnZSBGdW5jdGlvblByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgRnVuY3Rpb25Qcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguRnVuY3Rpb25Qcm90b30gRnVuY3Rpb25Qcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5GdW5jdGlvblByb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgbWVzc2FnZS5uYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNDoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkpIG1lc3NhZ2UuaW5wdXQgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXQucHVzaChyZWFkZXIuc3RyaW5nKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSkgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0LnB1c2gocmVhZGVyLnN0cmluZygpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDY6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuYXR0cmlidXRlICYmIG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aCkpIG1lc3NhZ2UuYXR0cmlidXRlID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZS5wdXNoKHJlYWRlci5zdHJpbmcoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5hdHRyaWJ1dGVQcm90byAmJiBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvLmxlbmd0aCkpIG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8gPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8ucHVzaCgkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNzoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5ub2RlICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpKSBtZXNzYWdlLm5vZGUgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uubm9kZS5wdXNoKCRyb290Lm9ubnguTm9kZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgODoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA5OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLm9wc2V0SW1wb3J0ICYmIG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoKSkgbWVzc2FnZS5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydC5wdXNoKCRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTA6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZG9tYWluID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBGdW5jdGlvblByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHJldHVybnMge29ubnguRnVuY3Rpb25Qcm90b30gRnVuY3Rpb25Qcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWVzIGEgRnVuY3Rpb25Qcm90byBtZXNzYWdlLlxuICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UubmFtZSkpIHJldHVybiAnbmFtZTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmlucHV0ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaW5wdXQnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnB1dCkpIHJldHVybiAnaW5wdXQ6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5pbnB1dFtpXSkpIHJldHVybiAnaW5wdXQ6IHN0cmluZ1tdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm91dHB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ291dHB1dCcpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm91dHB1dCkpIHJldHVybiAnb3V0cHV0OiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm91dHB1dFtpXSkpIHJldHVybiAnb3V0cHV0OiBzdHJpbmdbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdhdHRyaWJ1dGUnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5hdHRyaWJ1dGUpKSByZXR1cm4gJ2F0dHJpYnV0ZTogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5hdHRyaWJ1dGVbaV0pKSByZXR1cm4gJ2F0dHJpYnV0ZTogc3RyaW5nW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdhdHRyaWJ1dGVQcm90bycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmF0dHJpYnV0ZVByb3RvKSkgcmV0dXJuICdhdHRyaWJ1dGVQcm90bzogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLnZlcmlmeShtZXNzYWdlLmF0dHJpYnV0ZVByb3RvW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnYXR0cmlidXRlUHJvdG8uJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5ub2RlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbm9kZScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm5vZGUpKSByZXR1cm4gJ25vZGU6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm5vZGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54Lk5vZGVQcm90by52ZXJpZnkobWVzc2FnZS5ub2RlW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnbm9kZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSkgcmV0dXJuICdkb2NTdHJpbmc6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5vcHNldEltcG9ydCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ29wc2V0SW1wb3J0JykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uub3BzZXRJbXBvcnQpKSByZXR1cm4gJ29wc2V0SW1wb3J0OiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLnZlcmlmeShtZXNzYWdlLm9wc2V0SW1wb3J0W2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnb3BzZXRJbXBvcnQuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb21haW4nKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvbWFpbikpIHJldHVybiAnZG9tYWluOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGdW5jdGlvblByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54LkZ1bmN0aW9uUHJvdG99IEZ1bmN0aW9uUHJvdG9cbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguRnVuY3Rpb25Qcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguRnVuY3Rpb25Qcm90bygpO1xuICAgICAgaWYgKG9iamVjdC5uYW1lICE9IG51bGwpIG1lc3NhZ2UubmFtZSA9IFN0cmluZyhvYmplY3QubmFtZSk7XG4gICAgICBpZiAob2JqZWN0LmlucHV0KSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuaW5wdXQpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkZ1bmN0aW9uUHJvdG8uaW5wdXQ6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuaW5wdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuaW5wdXQubGVuZ3RoOyArK2kpIG1lc3NhZ2UuaW5wdXRbaV0gPSBTdHJpbmcob2JqZWN0LmlucHV0W2ldKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Qub3V0cHV0KSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Qub3V0cHV0KSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5GdW5jdGlvblByb3RvLm91dHB1dDogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Qub3V0cHV0Lmxlbmd0aDsgKytpKSBtZXNzYWdlLm91dHB1dFtpXSA9IFN0cmluZyhvYmplY3Qub3V0cHV0W2ldKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuYXR0cmlidXRlKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuYXR0cmlidXRlKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5GdW5jdGlvblByb3RvLmF0dHJpYnV0ZTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuYXR0cmlidXRlLmxlbmd0aDsgKytpKSBtZXNzYWdlLmF0dHJpYnV0ZVtpXSA9IFN0cmluZyhvYmplY3QuYXR0cmlidXRlW2ldKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuYXR0cmlidXRlUHJvdG8pIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5hdHRyaWJ1dGVQcm90bykpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5GdW5jdGlvblByb3RvLmF0dHJpYnV0ZVByb3RvOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmF0dHJpYnV0ZVByb3RvLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuYXR0cmlidXRlUHJvdG9baV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5GdW5jdGlvblByb3RvLmF0dHJpYnV0ZVByb3RvOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvW2ldID0gJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC5hdHRyaWJ1dGVQcm90b1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Qubm9kZSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0Lm5vZGUpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkZ1bmN0aW9uUHJvdG8ubm9kZTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5ub2RlID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm5vZGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5ub2RlW2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5GdW5jdGlvblByb3RvLm5vZGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2Uubm9kZVtpXSA9ICRyb290Lm9ubnguTm9kZVByb3RvLmZyb21PYmplY3Qob2JqZWN0Lm5vZGVbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKSBtZXNzYWdlLmRvY1N0cmluZyA9IFN0cmluZyhvYmplY3QuZG9jU3RyaW5nKTtcbiAgICAgIGlmIChvYmplY3Qub3BzZXRJbXBvcnQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5vcHNldEltcG9ydCkpIHRocm93IFR5cGVFcnJvcignLm9ubnguRnVuY3Rpb25Qcm90by5vcHNldEltcG9ydDogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5vcHNldEltcG9ydC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm9wc2V0SW1wb3J0W2ldICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguRnVuY3Rpb25Qcm90by5vcHNldEltcG9ydDogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydFtpXSA9ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmZyb21PYmplY3Qob2JqZWN0Lm9wc2V0SW1wb3J0W2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5kb21haW4gIT0gbnVsbCkgbWVzc2FnZS5kb21haW4gPSBTdHJpbmcob2JqZWN0LmRvbWFpbik7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgRnVuY3Rpb25Qcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguRnVuY3Rpb25Qcm90b30gbWVzc2FnZSBGdW5jdGlvblByb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QuaW5wdXQgPSBbXTtcbiAgICAgICAgb2JqZWN0Lm91dHB1dCA9IFtdO1xuICAgICAgICBvYmplY3QuYXR0cmlidXRlID0gW107XG4gICAgICAgIG9iamVjdC5ub2RlID0gW107XG4gICAgICAgIG9iamVjdC5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICBvYmplY3QuYXR0cmlidXRlUHJvdG8gPSBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5uYW1lID0gJyc7XG4gICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSAnJztcbiAgICAgICAgb2JqZWN0LmRvbWFpbiA9ICcnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSkgb2JqZWN0Lm5hbWUgPSBtZXNzYWdlLm5hbWU7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuaW5wdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytqKSBvYmplY3QuaW5wdXRbal0gPSBtZXNzYWdlLmlucHV0W2pdO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aCkge1xuICAgICAgICBvYmplY3Qub3V0cHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2opIG9iamVjdC5vdXRwdXRbal0gPSBtZXNzYWdlLm91dHB1dFtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmF0dHJpYnV0ZSAmJiBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aDsgKytqKSBvYmplY3QuYXR0cmlidXRlW2pdID0gbWVzc2FnZS5hdHRyaWJ1dGVbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5ub2RlICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0Lm5vZGUgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLm5vZGUubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0Lm5vZGVbal0gPSAkcm9vdC5vbm54Lk5vZGVQcm90by50b09iamVjdChtZXNzYWdlLm5vZGVbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpIG9iamVjdC5kb2NTdHJpbmcgPSBtZXNzYWdlLmRvY1N0cmluZztcbiAgICAgIGlmIChtZXNzYWdlLm9wc2V0SW1wb3J0ICYmIG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0Lm9wc2V0SW1wb3J0W2pdID0gJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8udG9PYmplY3QobWVzc2FnZS5vcHNldEltcG9ydFtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb21haW4nKSkgb2JqZWN0LmRvbWFpbiA9IG1lc3NhZ2UuZG9tYWluO1xuICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8gJiYgbWVzc2FnZS5hdHRyaWJ1dGVQcm90by5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmF0dHJpYnV0ZVByb3RvID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5hdHRyaWJ1dGVQcm90by5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuYXR0cmlidXRlUHJvdG9bal0gPSAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuYXR0cmlidXRlUHJvdG9bal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBGdW5jdGlvblByb3RvIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIEZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LkZ1bmN0aW9uUHJvdG8nO1xuICAgIH07XG5cbiAgICByZXR1cm4gRnVuY3Rpb25Qcm90bztcbiAgfSkoKTtcblxuICByZXR1cm4gb25ueDtcbn0pKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gJHJvb3Q7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCBMb25nIGZyb20gJ2xvbmcnO1xuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0ICogYXMgb3J0RmJzIGZyb20gJy4vb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkJztcbmltcG9ydCB7IG9ubnggfSBmcm9tICcuL29ydC1zY2hlbWEvcHJvdG9idWYvb25ueCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvcic7XG5cbi8vIGNoZWNrIHRoZSBpbnB1dHMgc2hhcGUgYmVmb3JlIHJ1bm5pbmcgYW4gT1AuXG4vLyByZXR1cm4gdHJ1ZSB3aGVuIHRoZSBpbnB1dHMgcGFzcyB0aGUgY2hlY2tcbi8vIHJldHVybiBmYWxzZSB3aGVuIHRoZSBpbnB1dHMgZG8gbm90IGZpdCB0aGUgcmVxdWlyZW1lbnRcbi8vIHRocm93IGV4Y2VwdGlvbiB3aGVuIGZhdGFsIGVycm9yIG9yIG5vdCBpbXBsZW1lbnRlZFxuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrSW5wdXRzU2hhcGUoaW5wdXRzOiBUZW5zb3JbXSwgLi4uZXhwZWN0ZWREaW1lbnNpb25zOiBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSBleHBlY3RlZERpbWVuc2lvbnMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCFpbnB1dHNbaV0uZGltcyB8fCBpbnB1dHNbaV0uZGltcy5sZW5ndGggIT09IGV4cGVjdGVkRGltZW5zaW9uc1tpXSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLy8gRXZhbHVhdGVzIHRoZSBnaXZlbiBleHByZXNzaW9uIGFuZCBhc3NlcnRzIGVycm9yIG1lc3NhZ2UgaWYgY29uZGl0aW9uIGlzIHVubWV0LlxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydChleHByOiBib29sZWFuLCBtc2c6ICgpID0+IHN0cmluZykge1xuICBpZiAoIWV4cHIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IodHlwZW9mIG1zZyA9PT0gJ3N0cmluZycgPyBtc2cgOiBtc2coKSk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEFycmF5VXRpbCB7XG4gIC8qKlxuICAgKiBWZXJpZmllcyBpZiAyIGlucHV0IGFycmF5cyBjb250YWluIHRoZSBzYW1lIGVsZW1lbnRzLlxuICAgKiBAcGFyYW0gbjEgQXJyYXkgMVxuICAgKiBAcGFyYW0gbjIgQXJyYXkgMlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZXNlIDIgYXJlIGVxdWFsXG4gICAqL1xuICBzdGF0aWMgYXJyYXlzRXF1YWwoXG4gICAgbjE6XG4gICAgICB8IHJlYWRvbmx5IG51bWJlcltdXG4gICAgICB8IEludDhBcnJheVxuICAgICAgfCBVaW50OEFycmF5XG4gICAgICB8IEludDE2QXJyYXlcbiAgICAgIHwgVWludDE2QXJyYXlcbiAgICAgIHwgSW50MzJBcnJheVxuICAgICAgfCBVaW50MzJBcnJheVxuICAgICAgfCBVaW50OENsYW1wZWRBcnJheVxuICAgICAgfCBGbG9hdDMyQXJyYXlcbiAgICAgIHwgRmxvYXQ2NEFycmF5LFxuICAgIG4yOlxuICAgICAgfCByZWFkb25seSBudW1iZXJbXVxuICAgICAgfCBJbnQ4QXJyYXlcbiAgICAgIHwgVWludDhBcnJheVxuICAgICAgfCBJbnQxNkFycmF5XG4gICAgICB8IFVpbnQxNkFycmF5XG4gICAgICB8IEludDMyQXJyYXlcbiAgICAgIHwgVWludDMyQXJyYXlcbiAgICAgIHwgVWludDhDbGFtcGVkQXJyYXlcbiAgICAgIHwgRmxvYXQzMkFycmF5XG4gICAgICB8IEZsb2F0NjRBcnJheSxcbiAgKSB7XG4gICAgaWYgKG4xLmxlbmd0aCAhPT0gbjIubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChuMVtpXSAhPT0gbjJbaV0pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTWF0TXVsVXRpbCB7XG4gIC8qKlxuICAgKiBGaXggdGhlIGlucHV0IHNoYXBlcyBmb3IgTWF0TXVsIG9wZXJhdGlvbiBpZiB0aGV5IG5lZWQgZml4aW5nXG4gICAqIEBwYXJhbSBkaW1zQSBUaGUgc2hhcGUgb2YgdGVuc29yIEEuIFNob3VsZCBiZSBhbiBhcnJheSBvZiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gZGltc0IgVGhlIHNoYXBlIG9mIHRlbnNvciBCLiBTaG91bGQgYmUgYW4gYXJyYXkgb2YgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHJldHVybnMgQSB0dXBsZSBjb250YWluaW5nIHRoZSBwcmVwcm9jZXNzZWQgaW5wdXQgc2hhcGVzIGFzIHJlcXVpcmVkIGJ5IE9OTlggc3BlY2lmaWNhdGlvbnNcbiAgICovXG4gIHN0YXRpYyBwcmVwcm9jZXNzSW5wdXRTaGFwZXMoXG4gICAgZGltc0E6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGRpbXNCOiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogW3JlYWRvbmx5IG51bWJlcltdLCByZWFkb25seSBudW1iZXJbXV0ge1xuICAgIC8vIElmIHRoZSBmaXJzdCBhcmd1bWVudCBpcyAxLUQsIGl0IGlzIHByb21vdGVkIHRvIGEgbWF0cml4IGJ5IHByZXBlbmRpbmdcbiAgICAvLyBhIDEgdG8gaXRzIGRpbWVuc2lvbnMuIEFmdGVyIG1hdHJpeCBtdWx0aXBsaWNhdGlvbiB0aGUgcHJlcGVuZGVkIDEgaXNcbiAgICAvLyByZW1vdmVkLlxuICAgIGNvbnN0IGEgPSBkaW1zQS5sZW5ndGggPT09IDEgPyBbMSwgZGltc0FbMF1dIDogZGltc0E7XG5cbiAgICAvLyBJZiB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIDEtRCwgaXQgaXMgcHJvbW90ZWQgdG8gYSBtYXRyaXggYnkgYXBwZW5kaW5nXG4gICAgLy8gYSAxIHRvIGl0cyBkaW1lbnNpb25zLiBBZnRlciBtYXRyaXggbXVsdGlwbGljYXRpb24gdGhlIGFwcGVuZGVkIDEgaXNcbiAgICAvLyByZW1vdmVkLlxuICAgIGNvbnN0IGIgPSBkaW1zQi5sZW5ndGggPT09IDEgPyBbZGltc0JbMF0sIDFdIDogZGltc0I7XG5cbiAgICByZXR1cm4gW2EsIGJdO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpeCB0aGUgb3V0cHV0IHNoYXBlIGNvbXB1dGVkIGZvciBNYXRNdWwgb3BlcmF0aW9uIGlmIGl0IG5lZWRzIGZpeGluZ1xuICAgKiBAcGFyYW0gb3V0cHV0U2hhcGUgVGhlIGNvbXB1dGVkIG91dHB1dFNoYXBlLiBTaG91bGQgYmUgYW4gYXJyYXkgKGF0IGxlYXN0IG9mIGxlbmd0aCAyKSBvZiBwb3NpdGl2ZSBpbnRlZ2Vycy5cbiAgICogVGhpcyB3aWxsIGJlIG11dGF0ZWQuXG4gICAqIEBwYXJhbSBhUmFuayBUaGUgcmFuayBvZiB0ZW5zb3IgQS5cbiAgICogQHBhcmFtIGJSYW5rIFRoZSByYW5rIG9mIHRlbnNvciBCLlxuICAgKi9cbiAgc3RhdGljIHBvc3Rwcm9jZXNzT3V0cHV0U2hhcGUob3V0cHV0U2hhcGU6IG51bWJlcltdLCBhUmFuazogbnVtYmVyLCBiUmFuazogbnVtYmVyKSB7XG4gICAgLy8gUmVtb3ZlIHByZXBlbmRlZCBkaW1lbnNpb24gaWYgZmlyc3QgaW5wdXQgaXMgMWRcbiAgICBpZiAoYVJhbmsgPT09IDEpIHtcbiAgICAgIC8vIG91dHB1dFNoYXBlID0gb3V0cHV0U2hhcGUuc2xpY2UoMCwgb3V0cHV0U2hhcGUubGVuZ3RoIC0gMikuY29uY2F0KG91dHB1dFNoYXBlLnNsaWNlKG91dHB1dFNoYXBlLmxlbmd0aCAtIDEpKTtcbiAgICAgIG91dHB1dFNoYXBlLnNwbGljZShvdXRwdXRTaGFwZS5sZW5ndGggLSAyLCAxKTtcbiAgICB9XG4gICAgLy8gUmVtb3ZlIGFwcGVuZGVkIGRpbWVuc2lvbiBpZiBzZWNvbmQgaW5wdXQgaXMgMWRcbiAgICBpZiAoYlJhbmsgPT09IDEpIHtcbiAgICAgIG91dHB1dFNoYXBlLnBvcCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHNoYXBlIHdoZW4gbWF0cml4IG11bHRpcGxpY2F0aW9uXG4gICAqIEBwYXJhbSBhIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQS4gU2hvdWxkIGJlIGEgdHVwbGUgb2YgMiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gYiBUaGUgc2hhcGUgb2YgdGVuc29yIEIuIFNob3VsZCBiZSBhIHR1cGxlIG9mIDIgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHJldHVybnMgVGhlIGV4cGVjdGVkIHNoYXBlIG9mIHRoZSByZXN1bHQsIG9yIHVuZGVmaW5lZCBpZiBOL0FcbiAgICovXG4gIHN0YXRpYyBjYWxjTWF0TXVsU2hhcGUoYTogW251bWJlciwgbnVtYmVyXSwgYjogW251bWJlciwgbnVtYmVyXSk6IFtudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBhWzFdICE9PSBiWzBdID8gdW5kZWZpbmVkIDogW2FbMF0sIGJbMV1dO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBCcm9hZGNhc3RVdGlsIHtcbiAgLyoqXG4gICAqIENhbGN1bGF0ZSB0aGUgZXhwZWN0ZWQgc2hhcGUgd2hlbiBicm9hZGNhc3RpbmcgMiB0ZW5zb3JzXG4gICAqIEBwYXJhbSBhIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQS4gU2hvdWxkIGJlIGFuIGFycmF5IG9mIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEBwYXJhbSBiIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQi4gU2hvdWxkIGJlIGFuIGFycmF5IG9mIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEBwYXJhbSBpc01hdE11bCBXaGV0aGVyIHRoZSBvcGVyYXRpb24gaXMgTWF0TXVsXG4gICAqIEByZXR1cm5zIFRoZSBleHBlY3RlZCBzaGFwZSBvZiB0aGUgcmVzdWx0LCBvciB1bmRlZmluZWQgaWYgTi9BXG4gICAqL1xuICBzdGF0aWMgY2FsY1NoYXBlKFxuICAgIGFkaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBiZGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgaXNNYXRNdWwgPSBmYWxzZSxcbiAgKTogcmVhZG9ubHkgbnVtYmVyW10gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGFyYW5rID0gYWRpbXMubGVuZ3RoO1xuICAgIGNvbnN0IGJyYW5rID0gYmRpbXMubGVuZ3RoO1xuICAgIGlmIChhcmFuayA9PT0gMCkge1xuICAgICAgcmV0dXJuIGJkaW1zO1xuICAgIH1cbiAgICBpZiAoYnJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBhZGltcztcbiAgICB9XG4gICAgY29uc3QgY3JhbmsgPSBNYXRoLm1heChhZGltcy5sZW5ndGgsIGJkaW1zLmxlbmd0aCk7XG4gICAgY29uc3QgY2RpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPihjcmFuayk7XG5cbiAgICAvLyBjYWxjdWxhdGUgdGhlIGxhc3QgMiBkaW1lbnNpb24gaWYgaXQgaXMgTWF0TXVsXG4gICAgaWYgKGlzTWF0TXVsKSB7XG4gICAgICBpZiAoYXJhbmsgPCAyIHx8IGJyYW5rIDwgMikge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY29uc3QgY1NoYXBlTWF0TXVsID0gTWF0TXVsVXRpbC5jYWxjTWF0TXVsU2hhcGUoXG4gICAgICAgIFthZGltc1thcmFuayAtIDJdLCBhZGltc1thcmFuayAtIDFdXSxcbiAgICAgICAgW2JkaW1zW2JyYW5rIC0gMl0sIGJkaW1zW2JyYW5rIC0gMV1dLFxuICAgICAgKTtcbiAgICAgIGlmIChjU2hhcGVNYXRNdWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgW2NkaW1zW2NyYW5rIC0gMl0sIGNkaW1zW2NyYW5rIC0gMV1dID0gY1NoYXBlTWF0TXVsO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSBpc01hdE11bCA/IDMgOiAxOyBpIDw9IGNyYW5rOyBpKyspIHtcbiAgICAgIGNvbnN0IGFMZW4gPSBhcmFuayAtIGkgPCAwID8gMSA6IGFkaW1zW2FyYW5rIC0gaV07XG4gICAgICBjb25zdCBiTGVuID0gYnJhbmsgLSBpIDwgMCA/IDEgOiBiZGltc1ticmFuayAtIGldO1xuXG4gICAgICBpZiAoYUxlbiAhPT0gYkxlbiAmJiBhTGVuID4gMSAmJiBiTGVuID4gMSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY2RpbXNbY3JhbmsgLSBpXSA9IE1hdGgubWF4KGFMZW4sIGJMZW4pO1xuICAgIH1cblxuICAgIHJldHVybiBjZGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiB0aGUgaW5kaWNlcyBvZiBhIGJyb2FkY2FzdGVkIHRlbnNvciwgY2FsY3VsYXRlIHRoZSBvcmlnaW5hbCBpbmRpY2VzXG4gICAqIEBwYXJhbSBicm9hZGNhc3RlZEluZGljZXMgVGhlIGdpdmVuIGluZGljZXMgb2YgdGhlIGJyb2FkY2FzdGVkIHRlbnNvci5cbiAgICogQHBhcmFtIG9yaWdpbmFsU2hhcGUgVGhlIG9yaWdpbmFsIHNoYXBlIG9mIHRoZSB0ZW5zb3IgYmVmb3JlIGJyb2FkY2FzdFxuICAgKiBAcmV0dXJucyBUaGUgY2FsY3VsYXRlZCBpbmRpY2VzIHRoYXQgbWFwcyB0byB0aGUgb3JpZ2luYWwgdGVuc29yLlxuICAgKi9cbiAgc3RhdGljIGluZGV4KGJyb2FkY2FzdGVkSW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sIG9yaWdpbmFsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyW10ge1xuICAgIC8vIE5PVEUgMTogd2UgYXNzdW1lIHRoZSBwYXJhbWV0ZXIgYnJvYWRjYXN0ZWRJbmRpY2VzIGlzIHZhbGlkLiBpZS4gaXQgc2hvdWxkIGhhdmUgdGhlIHNhbWVcbiAgICAvLyBsZW5ndGggYXMgdGhlIGJyb2FkY2FzdGVkIHNoYXBlLCBhbmQgZm9yIGVhY2ggZGltZW5zaW9uIHRoZSBpbmRleCBzaG91bGRcbiAgICAvLyBub3QgYmUgb3V0IG9mIHJhbmdlLlxuICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlcyA9IG5ldyBBcnJheShvcmlnaW5hbFNoYXBlLmxlbmd0aCk7XG4gICAgQnJvYWRjYXN0VXRpbC5maWxsSW5kZXgoYnJvYWRjYXN0ZWRJbmRpY2VzLCBvcmlnaW5hbFNoYXBlLCBvcmlnaW5hbEluZGljZXMpO1xuICAgIHJldHVybiBvcmlnaW5hbEluZGljZXM7XG4gIH1cblxuICAvKipcbiAgICogR2l2ZW4gdGhlIGluZGljZXMgb2YgYSBicm9hZGNhc3RlZCB0ZW5zb3IsIGNhbGN1bGF0ZSB0aGUgb3JpZ2luYWwgaW5kaWNlc1xuICAgKiBAcGFyYW0gYnJvYWRjYXN0ZWRJbmRpY2VzIFRoZSBnaXZlbiBpbmRpY2VzIG9mIHRoZSBicm9hZGNhc3RlZCB0ZW5zb3IuXG4gICAqIEBwYXJhbSBvcmlnaW5hbFNoYXBlIFRoZSBvcmlnaW5hbCBzaGFwZSBvZiB0aGUgdGVuc29yIGJlZm9yZSBicm9hZGNhc3RcbiAgICogQHBhcmFtIG9yaWdpbmFsSW5kaWNlcyBUaGUgbWFwcGluZyBvZiBicm9hZGNhc3RlZEluZGljZXMgdG8gdGhlIG9yaWdpbmFsSW5kaWNlcyAob3V0cHV0IHBhcmFtZXRlciAtIHdpbGwgYmVcbiAgICogICAgIG11dGF0ZWQpLlxuICAgKi9cbiAgc3RhdGljIGZpbGxJbmRleChicm9hZGNhc3RlZEluZGljZXM6IHJlYWRvbmx5IG51bWJlcltdLCBvcmlnaW5hbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgb3JpZ2luYWxJbmRpY2VzOiBudW1iZXJbXSkge1xuICAgIC8vIE5PVEUgMTogd2UgYXNzdW1lIHRoZSBwYXJhbWV0ZXIgYnJvYWRjYXN0ZWRJbmRpY2VzIGlzIHZhbGlkLiBpZS4gaXQgc2hvdWxkIGhhdmUgdGhlIHNhbWUgbGVuZ3RoIGFzIHRoZVxuICAgIC8vIGJyb2FkY2FzdGVkIHNoYXBlLCBhbmQgZm9yIGVhY2ggZGltZW5zaW9uIHRoZSBpbmRleCBzaG91bGQgbm90IGJlIG91dCBvZiByYW5nZS5cbiAgICAvLyBOT1RFIDI6IHdlIGFzc3VtZSB0aGUgcGFyYW1ldGVyIG9yaWdpbmFsSW5kaWNlcyBoYXMgdGhlIHNhbWUgbGVuZ3RoIGFzIHRoZSBvcmlnaW5hbFNoYXBlXG4gICAgY29uc3QgZGltT2Zmc2V0ID0gYnJvYWRjYXN0ZWRJbmRpY2VzLmxlbmd0aCAtIG9yaWdpbmFsU2hhcGUubGVuZ3RoO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JpZ2luYWxTaGFwZS5sZW5ndGg7IGkrKykge1xuICAgICAgb3JpZ2luYWxJbmRpY2VzW2ldID0gYnJvYWRjYXN0ZWRJbmRpY2VzW2RpbU9mZnNldCArIGldICUgb3JpZ2luYWxTaGFwZVtpXTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybSB0aGUgYnJvYWRjYXN0aW5nIG9wZXJhdGlvbiBvbiB0aGUgc3BlY2lmaWMgb3BlcmF0b3JcbiAgICogQHBhcmFtIGEgVGhlIGlucHV0IHRlbnNvciBBXG4gICAqIEBwYXJhbSBiIFRoZSBpbnB1dCB0ZW5zb3IgQlxuICAgKiBAcGFyYW0gb3AgVGhlIG9wZXJhdG9yIGxhbWJkYSBmdW5jdGlvblxuICAgKiBAcGFyYW0gaW5wbGFjZSBXaGV0aGVyIHRvIHdyaXRlIHRoZSByZXN1bHQgYmFjayB0byBBLlxuICAgKiBAcmV0dXJucyBUaGUgcmVzdWx0IHRlbnNvciwgb3IgdW5kZWZpbmVkIGlmIGlucHV0IG5vdCBicm9hZGNhc3RhYmxlLlxuICAgKi9cbiAgc3RhdGljIGNhbGMoXG4gICAgYTogVGVuc29yLFxuICAgIGI6IFRlbnNvcixcbiAgICBvcDogKGE6IHN0cmluZyB8IG51bWJlciwgYjogc3RyaW5nIHwgbnVtYmVyKSA9PiBzdHJpbmcgfCBudW1iZXIsXG4gICAgaW5wbGFjZTogYm9vbGVhbixcbiAgICByZXN1bHRUeXBlPzogVGVuc29yLkRhdGFUeXBlLFxuICApOiBUZW5zb3IgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG91dHB1dFNoYXBlID0gQnJvYWRjYXN0VXRpbC5jYWxjU2hhcGUoYS5kaW1zLCBiLmRpbXMpO1xuXG4gICAgaWYgKG91dHB1dFNoYXBlKSB7XG4gICAgICBpZiAoaW5wbGFjZSAmJiAhU2hhcGVVdGlsLmFyZUVxdWFsKG91dHB1dFNoYXBlLCBhLmRpbXMpKSB7XG4gICAgICAgIC8vIEIgaXMgbm90IGJyb2FkY2FzdGFibGUgdG8gQSwgZmFpbGVkIHRvIGNhbGN1bGF0ZSBpbnBsYWNlLlxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICAgICAgY29uc3QgYyA9IGlucGxhY2UgPyBhIDogbmV3IFRlbnNvcihvdXRwdXRTaGFwZSwgcmVzdWx0VHlwZSB8fCBhLnR5cGUpO1xuXG4gICAgICAvLyBib3RoIGlucHV0cyBhcmUgc2NhbGFyc1xuICAgICAgaWYgKG91dHB1dFNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjLnNldChbXSwgb3AoYS5nZXQoW10pIGFzIG51bWJlciwgYi5nZXQoW10pIGFzIG51bWJlcikpO1xuICAgICAgfVxuXG4gICAgICAvLyBhdCBsZWFzdCBvbmUgaW5wdXQgaXMgYSBub24tc2NhbGFyXG4gICAgICBlbHNlIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0SW5kaWNlcyA9IG5ldyBBcnJheTxudW1iZXI+KG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlc0EgPSBuZXcgQXJyYXkoYS5kaW1zLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlc0IgPSBuZXcgQXJyYXkoYi5kaW1zLmxlbmd0aCk7XG4gICAgICAgIGxldCB2YWxBOiBzdHJpbmcgfCBudW1iZXIgPSAwO1xuICAgICAgICBsZXQgdmFsQjogc3RyaW5nIHwgbnVtYmVyID0gMDtcbiAgICAgICAgbGV0IGlzQVNjYWxhciA9IGZhbHNlO1xuICAgICAgICBsZXQgaXNCU2NhbGFyID0gZmFsc2U7XG4gICAgICAgIGlmIChhLmRpbXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdmFsQSA9IGEuZ2V0KFtdKSBhcyBudW1iZXI7XG4gICAgICAgICAgaXNBU2NhbGFyID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYi5kaW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHZhbEIgPSBiLmdldChbXSkgYXMgbnVtYmVyO1xuICAgICAgICAgIGlzQlNjYWxhciA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlc3Q6IG51bWJlcjtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgICAgICAvLyB0cmF2ZXJzYWwgaW5kaWNlc1xuICAgICAgICAgIHJlc3QgPSBpO1xuICAgICAgICAgIGZvciAobGV0IGogPSBvdXRwdXRTaGFwZS5sZW5ndGggLSAxOyBqID49IDA7IGotLSkge1xuICAgICAgICAgICAgb3V0cHV0SW5kaWNlc1tqXSA9IHJlc3QgJSBvdXRwdXRTaGFwZVtqXTtcbiAgICAgICAgICAgIHJlc3QgPSBNYXRoLmZsb29yKHJlc3QgLyBvdXRwdXRTaGFwZVtqXSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFpc0FTY2FsYXIpIHtcbiAgICAgICAgICAgIC8vIG1hcCBvdXRwdXRJbmRpY2VzICh3aGljaCBpcyBhY3R1YWxseSBicm9hZGNhc3RlZCkgdG8gdGhlIG9yaWdpbmFsSW5kaWNlc1xuICAgICAgICAgICAgQnJvYWRjYXN0VXRpbC5maWxsSW5kZXgob3V0cHV0SW5kaWNlcywgYS5kaW1zLCBvcmlnaW5hbEluZGljZXNBKTtcbiAgICAgICAgICAgIHZhbEEgPSBhLmdldChvcmlnaW5hbEluZGljZXNBKSBhcyBudW1iZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghaXNCU2NhbGFyKSB7XG4gICAgICAgICAgICBCcm9hZGNhc3RVdGlsLmZpbGxJbmRleChvdXRwdXRJbmRpY2VzLCBiLmRpbXMsIG9yaWdpbmFsSW5kaWNlc0IpO1xuICAgICAgICAgICAgdmFsQiA9IGIuZ2V0KG9yaWdpbmFsSW5kaWNlc0IpIGFzIG51bWJlcjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjLnNldChvdXRwdXRJbmRpY2VzLCBvcCh2YWxBLCB2YWxCKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgaWYgYSBzaGFwZSBpcyB1bmlkaXJlY3Rpb25hbCBicm9hZGNhc3RhYmxlIHRvIGFub3RoZXIgc2hhcGVcbiAgICogQHBhcmFtIHNoYXBlIFRoZSBpbnB1dCBzaGFwZVxuICAgKiBAcGFyYW0gZmluYWxTaGFwZSBUaGUgZGVzaXJlZCBzaGFwZSBhZnRlciBicm9hZGNhc3RpbmdcbiAgICovXG4gIHN0YXRpYyBpc1ZhbGlkQnJvYWRjYXN0KHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgZmluYWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiBib29sZWFuIHtcbiAgICAvLyBhbGlnbiBzaGFwZSB0byB0aGUgcmlnaHRcbiAgICBjb25zdCBpbnB1dFJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgZmluYWxSYW5rID0gZmluYWxTaGFwZS5sZW5ndGg7XG4gICAgaWYgKGlucHV0UmFuayA+IGZpbmFsUmFuaykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSBpbnB1dFJhbms7IGkrKykge1xuICAgICAgaWYgKHNoYXBlW2lucHV0UmFuayAtIGldICE9PSAxICYmIHNoYXBlW2lucHV0UmFuayAtIGldICE9PSBmaW5hbFNoYXBlW2ZpbmFsUmFuayAtIGldKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIHRoZSBicm9hZGNhc3RlZCBkaW1zIGluIGlucHV0IHNoYXBlIGJhc2VkIG9uIHRoZSBnaXZlbiBvdXRwdXQgc2hhcGUuXG4gICAqIE5vdGUgdGhhdCB0aGlzIGZ1bmN0aW9uIG9ubHkgcmV0dXJucyB0aGUgYnJvYWRjYXN0ZWQgZGltcy5cbiAgICogQHBhcmFtIGlucHV0U2hhcGUgVGhlIGlucHV0IHNoYXBlXG4gICAqIEBwYXJhbSBvdXRwdXRTaGFwZSBUaGUgb3V0cHV0IHNoYXBlXG4gICAqIEByZXR1cm5zIFRoZSBicm9hZGNhc3RlZCBkaW1zIGluIGlucHV0IHNoYXBlLlxuICAgKi9cbiAgc3RhdGljIGdldEJyb2FkY2FzdERpbXMoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlcltdIHtcbiAgICBjb25zdCBpblJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBkaW1zOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5SYW5rOyBpKyspIHtcbiAgICAgIGNvbnN0IGRpbSA9IGluUmFuayAtIDEgLSBpO1xuICAgICAgY29uc3QgYSA9IGlucHV0U2hhcGVbZGltXSB8fCAxO1xuICAgICAgY29uc3QgYiA9IG91dHB1dFNoYXBlW291dHB1dFNoYXBlLmxlbmd0aCAtIDEgLSBpXSB8fCAxO1xuICAgICAgaWYgKGIgPiAxICYmIGEgPT09IDEpIHtcbiAgICAgICAgZGltcy51bnNoaWZ0KGRpbSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkaW1zO1xuICB9XG59XG5cbi8vIGNvcHkgYXJyYXkgaGVscGVyXG4vLyBtaW1pY3MgbWVtY3B5IGFzIG11Y2ggYXMgcG9zc2libGVcbmV4cG9ydCBmdW5jdGlvbiBhcnJheUNvcHlIZWxwZXIoXG4gIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgc291cmNlOiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICB0YXJnZXRJbmRleDogbnVtYmVyLFxuICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICBibG9ja1NpemU6IG51bWJlcixcbikge1xuICBpZiAoc291cmNlSW5kZXggPCAwIHx8IHNvdXJjZUluZGV4ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgfVxuICBpZiAodGFyZ2V0SW5kZXggPCAwIHx8IHRhcmdldEluZGV4ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgfVxuICBpZiAoc291cmNlSW5kZXggKyBibG9ja1NpemUgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gIH1cbiAgaWYgKHRhcmdldEluZGV4ICsgYmxvY2tTaXplID4gdGFyZ2V0Lmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICB9XG5cbiAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYmxvY2tTaXplOyBvZmZzZXQrKykge1xuICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gPSBzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBHZW1tVXRpbCB7XG4gIC8vIHdpbGwgbWFrZSBzdXJlIGlucHV0IHNoYXBlcyBhcmUgY29tcGF0aWJsZSBmb3IgdGhpcyBvcFxuICAvLyBhbmQgcmV0dXJuIGJhY2sgdGhlIHNoYXBlIG9mIHRoZSBvdXRwdXQgaW4gdGhlIGZvcm0gb2YgYSB0dXBsZVxuICAvLyB3aWxsIHRocm93IGV4Y2VwdGlvbiBpZiB0aGUgaW5wdXQgc2hhcGVzIGFyZSBub3QgY29tcGF0aWJsZVxuICBzdGF0aWMgZ2V0U2hhcGVPZkdlbW1SZXN1bHQoXG4gICAgbGVmdFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgICB0cmFuc0xlZnQ6IGJvb2xlYW4sXG4gICAgcmlnaHRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgdHJhbnNSaWdodDogYm9vbGVhbixcbiAgICBiaWFzU2hhcGU/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmIChsZWZ0U2hhcGUubGVuZ3RoICE9PSAyIHx8IHJpZ2h0U2hhcGUubGVuZ3RoICE9PSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NoYXBlIG5lZWQgdG8gYmUgb2Ygc2l6ZSAyJyk7XG4gICAgfVxuXG4gICAgbGV0IE06IG51bWJlcjtcbiAgICBsZXQgSzogbnVtYmVyO1xuICAgIGxldCBOOiBudW1iZXI7XG5cbiAgICBpZiAodHJhbnNMZWZ0KSB7XG4gICAgICBNID0gbGVmdFNoYXBlWzFdO1xuICAgICAgSyA9IGxlZnRTaGFwZVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgTSA9IGxlZnRTaGFwZVswXTtcbiAgICAgIEsgPSBsZWZ0U2hhcGVbMV07XG4gICAgfVxuXG4gICAgbGV0IGtEaW0gPSAtMTtcblxuICAgIGlmICh0cmFuc1JpZ2h0KSB7XG4gICAgICBOID0gcmlnaHRTaGFwZVswXTtcbiAgICAgIGtEaW0gPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBOID0gcmlnaHRTaGFwZVsxXTtcbiAgICAgIGtEaW0gPSAwO1xuICAgIH1cblxuICAgIGlmIChyaWdodFNoYXBlW2tEaW1dICE9PSBLKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RpbWVuc2lvbiBtaXNtYXRjaCcpO1xuICAgIH1cblxuICAgIGlmIChNIDw9IDAgfHwgTiA8PSAwIHx8IEsgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNoYXBlIHNwZWNpZmllZCcpO1xuICAgIH1cblxuICAgIGlmIChiaWFzU2hhcGUgJiYgIUJyb2FkY2FzdFV0aWwuaXNWYWxpZEJyb2FkY2FzdChiaWFzU2hhcGUsIFtNLCBOXSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ2VtbTogaW52YWxpZCBiaWFzIHNoYXBlIGZvciBicm9hZGNhc3QnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW00sIE4sIEtdO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQcm90b1V0aWwge1xuICBzdGF0aWMgdGVuc29yRGF0YVR5cGVGcm9tUHJvdG8odHlwZVByb3RvOiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlIHwgb3J0RmJzLlRlbnNvckRhdGFUeXBlKTogVGVuc29yLkRhdGFUeXBlIHtcbiAgICBzd2l0Y2ggKHR5cGVQcm90bykge1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg6XG4gICAgICAgIHJldHVybiAnaW50OCc7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDg6XG4gICAgICAgIHJldHVybiAndWludDgnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w6XG4gICAgICAgIHJldHVybiAnYm9vbCc7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMTY6XG4gICAgICAgIHJldHVybiAnaW50MTYnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjpcbiAgICAgICAgcmV0dXJuICd1aW50MTYnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDMyOlxuICAgICAgICByZXR1cm4gJ2ludDMyJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI6XG4gICAgICAgIHJldHVybiAndWludDMyJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDpcbiAgICAgICAgcmV0dXJuICdmbG9hdDMyJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU6XG4gICAgICAgIHJldHVybiAnZmxvYXQ2NCc7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuU1RSSU5HOlxuICAgICAgICByZXR1cm4gJ3N0cmluZyc7XG5cbiAgICAgIC8vIEZvciBJTlQ2NC9VSU5UNjQsIHJlZHVjZSB0aGVpciB2YWx1ZSB0byAzMi1iaXRzLlxuICAgICAgLy8gU2hvdWxkIHRocm93IGV4Y2VwdGlvbiB3aGVuIG92ZXJmbG93XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQ6XG4gICAgICAgIHJldHVybiAnaW50MzInO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDpcbiAgICAgICAgcmV0dXJuICd1aW50MzInO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGRhdGEgdHlwZTogJHtvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlW3R5cGVQcm90b119YCk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHRlbnNvckRhdGFUeXBlU3RyaW5nVG9FbnVtKHR5cGU6IHN0cmluZyk6IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg7XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ4O1xuICAgICAgY2FzZSAnYm9vbCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w7XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDE2O1xuICAgICAgY2FzZSAndWludDE2JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDE2O1xuICAgICAgY2FzZSAnaW50MzInOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjtcbiAgICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMjtcbiAgICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDtcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU7XG4gICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5TVFJJTkc7XG4gICAgICBjYXNlICdpbnQ2NCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0O1xuICAgICAgY2FzZSAndWludDY0JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDY0O1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGRhdGEgdHlwZTogJHt0eXBlfWApO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB0ZW5zb3JEaW1zRnJvbVByb3RvKGRpbXM6IEFycmF5PG51bWJlciB8IExvbmc+KTogbnVtYmVyW10ge1xuICAgIC8vIGdldCByaWQgb2YgTG9uZyB0eXBlIGZvciBkaW1zXG4gICAgcmV0dXJuIGRpbXMubWFwKChkKSA9PiAoTG9uZy5pc0xvbmcoZCkgPyBkLnRvTnVtYmVyKCkgOiBkKSk7XG4gIH1cblxuICBzdGF0aWMgdGVuc29yVmFsdWVUeXBlRnJvbVByb3RvKHZhbHVlVHlwZTogb25ueC5UeXBlUHJvdG8uSVRlbnNvcik6IEdyYXBoLlZhbHVlVHlwZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRlbnNvclR5cGU6IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byh2YWx1ZVR5cGUuZWxlbVR5cGUhKSxcbiAgICAgIHNoYXBlOiB7IGRpbXM6IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbVByb3RvKHZhbHVlVHlwZS5zaGFwZSEuZGltIS5tYXAoKGQpID0+IGQuZGltVmFsdWUhKSkgfSxcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIHRlbnNvckRpbXNGcm9tT1JURm9ybWF0KHRlbnNvcjogb3J0RmJzLlRlbnNvcikge1xuICAgIGNvbnN0IGRpbXMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRlbnNvci5kaW1zTGVuZ3RoKCk7IGkrKykge1xuICAgICAgZGltcy5wdXNoKExvbmdVdGlsLmxvbmdUb051bWJlcih0ZW5zb3IuZGltcyhpKSEpKTtcbiAgICB9XG4gICAgcmV0dXJuIGRpbXM7XG4gIH1cblxuICBzdGF0aWMgdGVuc29yQXR0cmlidXRlc0Zyb21PUlRGb3JtYXQobm9kZTogb3J0RmJzLk5vZGUpIHtcbiAgICBjb25zdCBhdHRyaWJ1dGVzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2RlLmF0dHJpYnV0ZXNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICBhdHRyaWJ1dGVzLnB1c2gobm9kZS5hdHRyaWJ1dGVzKGkpISk7XG4gICAgfVxuICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBMb25nVXRpbCB7XG4gIC8vIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHRvIGdldCBhIG51bWJlciBmcm9tIGxvbmcgdHlwZSBvZiBkYXRhIGZvciBhdHRyaWJ1dGUsIGRpbSwgYW5kIGlyIHZlcnNpb24sXG4gIC8vIHdoaWNoIHZhbHVlcyBhcmUgc2lnbmVkIGludGVnZXJzLlxuICAvLyBUbyBtYWtlIGl0IG1vcmUgZ2VuZXJpYywgYWRkIGFuIG9wdGlvbmFsIHBhcmFtZXRlciB0byBjb252ZXJ0IHRvIGEgdW5zaWduZWQgbnVtYmVyLlxuICBzdGF0aWMgbG9uZ1RvTnVtYmVyKG46IExvbmcgfCBiaWdpbnQgfCBudW1iZXIpIHtcbiAgICBpZiAoTG9uZy5pc0xvbmcobikpIHtcbiAgICAgIHJldHVybiBuLnRvTnVtYmVyKCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbiA9PT0gJ2JpZ2ludCcpIHtcbiAgICAgIHJldHVybiBOdW1iZXIobik7XG4gICAgfVxuICAgIHJldHVybiBuO1xuICB9XG4gIHN0YXRpYyBpc0xvbmcobjogdW5rbm93bikge1xuICAgIHJldHVybiBMb25nLmlzTG9uZyhuKSB8fCB0eXBlb2YgbiA9PT0gJ2JpZ2ludCc7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNoYXBlVXRpbCB7XG4gIHN0YXRpYyBzaXplKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyIHtcbiAgICByZXR1cm4gU2hhcGVVdGlsLmdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltcywgMCwgZGltcy5sZW5ndGgpO1xuICB9XG5cbiAgLy8gYGF4aXNgIGluY2x1c2l2ZVxuICBzdGF0aWMgc2l6ZUZyb21EaW1lbnNpb24oZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPCAwIHx8IGF4aXMgPiBkaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIGRpbWVuc2lvbiBvZiAke2F4aXN9IGZvciBzaXplRnJvbURpbWVuc2lvbiBhcyBUZW5zb3IgaGFzICR7ZGltcy5sZW5ndGh9IGRpbWVuc2lvbnMuYCk7XG4gICAgfVxuICAgIHJldHVybiBTaGFwZVV0aWwuZ2V0U2l6ZUZyb21EaW1lbnNpb25SYW5nZShkaW1zLCBheGlzLCBkaW1zLmxlbmd0aCk7XG4gIH1cblxuICAvLyBgYXhpc2AgZXhjbHVzaXZlXG4gIHN0YXRpYyBzaXplVG9EaW1lbnNpb24oZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPCAwIHx8IGF4aXMgPiBkaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIGRpbWVuc2lvbiBvZiAke2F4aXN9IGZvciBzaXplVG9EaW1lbnNpb24gYXMgVGVuc29yIGhhcyAke2RpbXMubGVuZ3RofSBkaW1lbnNpb25zLmApO1xuICAgIH1cbiAgICByZXR1cm4gU2hhcGVVdGlsLmdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltcywgMCwgYXhpcyk7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZUZyb21EaW1lbnNpb25SYW5nZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBzaXplID0gMTtcbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgLy8gc2FmZXR5IGNoZWNrIGFzIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSBtdWx0aXBsZSBvdGhlciBtZXRob2RzIHJlcXVpcmluZyBzaXplLlxuICAgICAgLy8gc2l6ZSBjYW5ub3QgYmUgMCBvciBuZWdhdGl2ZS5cbiAgICAgIGlmIChkaW1zW2ldIDw9IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdjYW5ub3QgZ2V0IHZhbGlkIHNpemUgZnJvbSBzcGVjaWZpZWQgZGltZW5zaW9uIHJhbmdlLiBNb3N0IGxpa2VseSB0aGUgcmFuZ2UgY29udGFpbnMgMCBvciBuZWdhdGl2ZSB2YWx1ZXMgaW4gdGhlbS4nLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgc2l6ZSAqPSBkaW1zW2ldO1xuICAgIH1cbiAgICByZXR1cm4gc2l6ZTtcbiAgfVxuXG4gIHN0YXRpYyBjb21wdXRlU3RyaWRlcyhkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCByYW5rID0gZGltcy5sZW5ndGg7XG4gICAgaWYgKHJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9IGVsc2UgaWYgKHJhbmsgPT09IDEpIHtcbiAgICAgIHJldHVybiBbMV07XG4gICAgfVxuICAgIGNvbnN0IHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMV0gPSAxO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gZGltc1tyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogZGltc1tpICsgMV07XG4gICAgfVxuICAgIHJldHVybiBzdHJpZGVzO1xuICB9XG5cbiAgc3RhdGljIHRyYW5zcG9zZShkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCBjb3B5ID0gZGltcy5zbGljZSgpO1xuICAgIHJldHVybiBjb3B5LnJldmVyc2UoKTtcbiAgfVxuXG4gIHN0YXRpYyBpbmRpY2VzVG9PZmZzZXQoaW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzPzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoYXhpcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBheGlzID0gaW5kaWNlcy5sZW5ndGg7XG4gICAgfVxuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXhpczsgKytpKSB7XG4gICAgICBvZmZzZXQgKz0gc3RyaWRlc1tpXSAqIGluZGljZXNbaV07XG4gICAgfVxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgb2Zmc2V0VG9JbmRpY2VzKG9mZnNldDogbnVtYmVyLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCByYW5rID0gc3RyaWRlcy5sZW5ndGg7XG4gICAgaWYgKHJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9IGVsc2UgaWYgKHJhbmsgPT09IDEpIHtcbiAgICAgIHJldHVybiBbb2Zmc2V0ICogc3RyaWRlc1swXV07XG4gICAgfVxuICAgIGNvbnN0IGluZGljZXM6IG51bWJlcltdID0gbmV3IEFycmF5KHN0cmlkZXMubGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluZGljZXMubGVuZ3RoIC0gMTsgKytpKSB7XG4gICAgICBpbmRpY2VzW2ldID0gTWF0aC5mbG9vcihvZmZzZXQgLyBzdHJpZGVzW2ldKTtcbiAgICAgIG9mZnNldCAtPSBpbmRpY2VzW2ldICogc3RyaWRlc1tpXTtcbiAgICB9XG4gICAgaW5kaWNlc1tpbmRpY2VzLmxlbmd0aCAtIDFdID0gb2Zmc2V0O1xuICAgIHJldHVybiBpbmRpY2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIG5vcm1hbGl6ZSBheGlzIG9mIHJhbmdlIFstciwgcikgaW50byBbMCwgcikuXG4gICAqL1xuICBzdGF0aWMgbm9ybWFsaXplQXhpcyhheGlzOiBudW1iZXIsIHRlbnNvclJhbms6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPCAtdGVuc29yUmFuayAmJiBheGlzID49IHRlbnNvclJhbmspIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5zdXBwb3J0ZWQgYXhpcyBmb3IgdGhpcyBvcGVyYXRpb24uJyk7XG4gICAgfVxuICAgIHJldHVybiBheGlzIDwgMCA/IGF4aXMgKyB0ZW5zb3JSYW5rIDogYXhpcztcbiAgfVxuXG4gIHN0YXRpYyBub3JtYWxpemVBeGVzKGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdLCB0ZW5zb3JSYW5rOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIGF4ZXMubWFwKCh4KSA9PiB0aGlzLm5vcm1hbGl6ZUF4aXMoeCwgdGVuc29yUmFuaykpO1xuICB9XG5cbiAgLy8gSW5jcmVtZW50IGFuIGluZGV4IGludG8gYSB0ZW5zb3IgKGluIGxleGljb2dyYXBoaWNcbiAgLy8gb3JkZXJpbmcpLCB3cmFwcGluZyBhcm91bmQgdGhlIHNwZWNpZmllZCB1cHBlcl9ib3VuZC5cbiAgLyoqXG4gICAqIEluY3JlbWVudCBhbiBpbmRleCBpbnRvIGEgdGVuc29yIChpbiBsZXhpY29ncmFwaGljIG9yZGVyaW5nKSwgd3JhcHBpbmcgYXJvdW5kIHRoZSBzcGVjaWZpZWQgdXBwZXJfYm91bmQuXG4gICAqIEBwYXJhbSBpbmRleCBHaXZlbiBpbmRleCB0byBpbmNyZW1lbnQgKFdpbGwgYmUgbXV0YXRlZClcbiAgICogQHBhcmFtIGRpbXMgVGhlIGRpbWVuc2lvbnMgb2YgdGhlIHRlbnNvciBmb3Igd2hpY2ggdGhlIGdpdmVuIGluZGV4IGNvcnJlc3BvbmRzIHRvXG4gICAqIEBwYXJhbSBheGlzVG9JbmNyZW1lbnRPbiBUaGUgMS1pbmRleGVkIGF4aXMgdG8gaW5jcmVtZW50IG9uLiBJZiB1bmRlZmluZWQsIGF4aXNUb0luY3JlbWVudE9uID09IHJhbmtcbiAgICovXG4gIHN0YXRpYyBpbmNyZW1lbnRJbmRleChpbmRleDogbnVtYmVyW10sIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzVG9JbmNyZW1lbnRPbj86IG51bWJlcikge1xuICAgIGlmIChkaW1zLmxlbmd0aCA9PT0gMCB8fCBpbmRleC5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5kZXggaW5jcmVtZW50aW5nIHVuc3VwcG9ydGVkIGZvciBzY2FsYXIgVGVuc29yJyk7XG4gICAgfVxuICAgIGlmIChheGlzVG9JbmNyZW1lbnRPbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBheGlzVG9JbmNyZW1lbnRPbiA9IGRpbXMubGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoYXhpc1RvSW5jcmVtZW50T24gPD0gMCB8fCBheGlzVG9JbmNyZW1lbnRPbiA+IGRpbXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5jb3JyZWN0IGF4aXMgdG8gaW5jcmVtZW50IG9uJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgayA9IGF4aXNUb0luY3JlbWVudE9uIC0gMTsgayA+PSAwOyAtLWspIHtcbiAgICAgIGluZGV4W2tdKys7XG4gICAgICBpZiAoaW5kZXhba10gPCBkaW1zW2tdKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaW5kZXhba10gPSAwO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9kdWNlcyBhIG5ldyBkaW1lbnNpb25zIGFycmF5IGJhc2VkIG9uIHRoZSB2YWx1ZXMgaW4gdGhlICdvcmlnaW5hbERpbWVuc2lvbnMnIGFuZCAnc2hhcGUnIGFycmF5XG4gICAqIFVzZWQgaW4gUmVzaGFwZVxuICAgKiBAcGFyYW0gb3JpZ2luYWxEaW1zIE9yaWdpbmFsIFNoYXBlIGFycmF5XG4gICAqIEBwYXJhbSBzaGFwZUhpbnRzIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIHRvIGNvbXB1dGUgdGhlIG5ldyBkaW1lbnNpb25zXG4gICAqIEZvciBleGFtcGxlOlxuICAgKiBvcmlnaW5hbERpbXMgPSBbMiwyXSBhbmQgc2hhcGVIaW50cyA9IFswLC0xXSB3aWxsIHJldHVybiBbMiwyXVxuICAgKiBvcmlnaW5hbERpbXMgPSBbMiwyXSBhbmQgc2hhcGVIaW50cyA9IFs0XSB3aWxsIHJldHVybiBbNF1cbiAgICogb3JpZ2luYWxEaW1zID0gWzIsMl0gYW5kIHNoYXBlSGludHMgPSBbNV0gd2lsbCB0aHJvdyBhbiBleGNlcHRpb25cbiAgICogaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjUmVzaGFwZVxuICAgKi9cblxuICBzdGF0aWMgY2FsY3VsYXRlUmVzaGFwZWREaW1zKG9yaWdpbmFsRGltczogcmVhZG9ubHkgbnVtYmVyW10sIHNoYXBlSGludHM6IEFycmF5TGlrZTxudW1iZXI+KTogbnVtYmVyW10ge1xuICAgIC8vIHJlc2hhcGUgdG8gYSBTY2FsYXIgVGVuc29yXG4gICAgaWYgKHNoYXBlSGludHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBpZiAob3JpZ2luYWxEaW1zLmxlbmd0aCA9PT0gMCB8fCBTaGFwZVV0aWwuc2l6ZShvcmlnaW5hbERpbXMpID09PSAxKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IHJlc2hhcGUgdG8gYSBzY2FsYXIgVGVuc29yJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbkRpbXMgPSBzaGFwZUhpbnRzLmxlbmd0aDtcbiAgICBjb25zdCByZXNoYXBlZERpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPihuRGltcyk7XG4gICAgbGV0IHVua25vd25EaW1lbnNpb24gPSAtMTtcbiAgICBsZXQgbmV3VGVuc29yU2l6ZSA9IDE7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuRGltczsgaSsrKSB7XG4gICAgICBpZiAoc2hhcGVIaW50c1tpXSA8IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYSBkaW1lbnNpb24gaW4gc2hhcGUgaGludHMgY2Fubm90IGJlIGxlc3MgdGhhbiAtMScpO1xuICAgICAgfVxuICAgICAgaWYgKHNoYXBlSGludHNbaV0gPT09IC0xKSB7XG4gICAgICAgIGlmICh1bmtub3duRGltZW5zaW9uICE9PSAtMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignYXQgbW9zdCBvbmUgZGltZW5zaW9uIGluIHNoYXBlIGhpbnRzIGNhbiBiZSAtMScpO1xuICAgICAgICB9XG4gICAgICAgIHVua25vd25EaW1lbnNpb24gPSBpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHNoYXBlSGludHNbaV0gPT09IDApIHtcbiAgICAgICAgICBpZiAoaSA+PSBvcmlnaW5hbERpbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RoZSBkaW1lbnNpb24gd2l0aCB2YWx1ZSB6ZXJvIGV4Y2VlZHMgdGhlIGRpbWVuc2lvbiBzaXplIG9mIHRoZSBpbnB1dCB0ZW5zb3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzaGFwZWREaW1zW2ldID0gb3JpZ2luYWxEaW1zW2ldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc2hhcGVkRGltc1tpXSA9IHNoYXBlSGludHNbaV07XG4gICAgICAgIH1cbiAgICAgICAgbmV3VGVuc29yU2l6ZSAqPSByZXNoYXBlZERpbXNbaV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgb2xkVGVuc29yU2l6ZSA9IFNoYXBlVXRpbC5zaXplKG9yaWdpbmFsRGltcyk7XG4gICAgaWYgKHVua25vd25EaW1lbnNpb24gIT09IC0xKSB7XG4gICAgICBpZiAob2xkVGVuc29yU2l6ZSAlIG5ld1RlbnNvclNpemUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGB0aGUgaW5wdXQgdGVuc29yIGNhbm5vdCBiZSByZXNoYXBlZCB0byB0aGUgcmVxdWVzdGVkIHNoYXBlLiBJbnB1dCBzaGFwZTogWyR7XG4gICAgICAgICAgICBvcmlnaW5hbERpbXNcbiAgICAgICAgICB9XSBPdXRwdXQgc2hhcGU6IFske3NoYXBlSGludHN9XWAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXNoYXBlZERpbXNbdW5rbm93bkRpbWVuc2lvbl0gPSBvbGRUZW5zb3JTaXplIC8gbmV3VGVuc29yU2l6ZTtcbiAgICB9XG4gICAgLy8gdmFsaWRhdGUgc2l6ZXMgZnJvbSBvcmlnaW5hbERpbXMgYW5kIHJlc2hhcGVkRGltcyBtYXRjaFxuICAgIGVsc2Uge1xuICAgICAgaWYgKG5ld1RlbnNvclNpemUgIT09IG9sZFRlbnNvclNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwicmVzaGFwZWREaW1zIGFuZCBvcmlnaW5hbERpbXMgZG9uJ3QgaGF2ZSBtYXRjaGluZyBzaXplc1wiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc2hhcGVkRGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTb3J0cyBhIGdpdmVuIGFycmF5IGJhc2VkIG9uIHRoZSBpbmRpY2VzIGluIHRoZSBQZXJtIGFycmF5XG4gICAqIFVzZWQgaW4gVHJhbnNwb3NlXG4gICAqIEBwYXJhbSBhIEFycmF5IHRvIGJlIHNvcnRlZCBzdWNoIGFzIGRpbXMgb3Igc3RyaWRlc1xuICAgKiBAcGFyYW0gcGVybSBQZXJtIGdpdmVuOyBpZiBudWxsIGEgd2lsbCBiZSByZXZlcnNlZFxuICAgKi9cbiAgc3RhdGljIHNvcnRCYXNlZE9uUGVybShhOiByZWFkb25seSBudW1iZXJbXSwgcGVybT86IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmIChwZXJtKSB7XG4gICAgICByZXR1cm4gcGVybS5tYXAoKHYpID0+IGFbdl0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYS5zbGljZSgpLnJldmVyc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGFkcyBhIGdpdmVuIHNoYXBlIGFjY29yZGluZyB0byB0aGUgcGFkZGluZyB2YWx1ZXNcbiAgICogQHBhcmFtIGRpbXMgc2hhcGUgb2YgdGhlIFRlbnNvciB0byBiZSBwYWRkZWRcbiAgICogQHBhcmFtIHBhZCBwYWQgdmFsdWVzXG4gICAqL1xuICBzdGF0aWMgcGFkU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHBhZDogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3QgcmFuayA9IGRpbXMubGVuZ3RoO1xuICAgIHJldHVybiBkaW1zLm1hcCgodiwgaSkgPT4gdiArIHBhZFtpXSArIHBhZFtpICsgcmFua10pO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgaWYgdGhlIHR3byBzaGFwZXMgYXJlIGlkZW50aWNhbFxuICAgKiBAcGFyYW0gc2hhcGUxXG4gICAqIEBwYXJhbSBzaGFwZTJcbiAgICovXG4gIHN0YXRpYyBhcmVFcXVhbChzaGFwZTE6IHJlYWRvbmx5IG51bWJlcltdLCBzaGFwZTI6IHJlYWRvbmx5IG51bWJlcltdKTogYm9vbGVhbiB7XG4gICAgaWYgKHNoYXBlMS5sZW5ndGggIT09IHNoYXBlMi5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHNoYXBlMS5ldmVyeSgodiwgaSkgPT4gdiA9PT0gc2hhcGUyW2ldKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgaWYgdGhlIGdpdmVuIGBkaW1zYCBvciBgc2hhcGVgIGlzIHZhbGlkIGluIE9OTlguanMgY29udGV4dCBhbmQgcmV0dXJucyBkYXRhIHNpemVcbiAgICogQHBhcmFtIGRpbXMgLSBpbnB1dCBgZGltc2AgdGhhdCBuZWVkcyB0byBiZSBjaGVja2VkXG4gICAqL1xuICBzdGF0aWMgdmFsaWRhdGVEaW1zQW5kQ2FsY1NpemUoZGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBudW1iZXIge1xuICAgIGlmIChkaW1zLmxlbmd0aCA+IDYpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ09ubHkgcmFuayAwIHRvIDYgaXMgc3VwcG9ydGVkIGZvciB0ZW5zb3Igc2hhcGUuJyk7XG4gICAgfVxuICAgIGxldCBzaXplID0gMTtcbiAgICBmb3IgKGNvbnN0IG4gb2YgZGltcykge1xuICAgICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKG4pKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgc2hhcGU6ICR7bn0gaXMgbm90IGFuIGludGVnZXJgKTtcbiAgICAgIH1cbiAgICAgIGlmIChuIDwgMCB8fCBuID4gMjE0NzQ4MzY0Nykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIHNoYXBlOiBsZW5ndGggJHtufSBpcyBub3QgYWxsb3dlZGApO1xuICAgICAgfVxuICAgICAgc2l6ZSAqPSBuO1xuICAgIH1cbiAgICByZXR1cm4gc2l6ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHRoZSBzaGFwZSBvZiBvdXRwdXQgdGVuc29yIHkgPSBmbGF0dGVuKHgsIGF4aXMpXG4gICAqIEBwYXJhbSBkaW1zIC0gc2hhcGUgb2YgaW5wdXQgdGVuc29yXG4gICAqIEBwYXJhbSBheGlzIC0gZmxhdHRlbiBheGlzLCBpbiB0aGUgcmFuZ2UgWy1yLCByXVxuICAgKi9cbiAgc3RhdGljIGZsYXR0ZW5TaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhpczogbnVtYmVyKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmIChheGlzIDwgMCkge1xuICAgICAgYXhpcyArPSBkaW1zLmxlbmd0aDtcbiAgICB9XG4gICAgY29uc3QgdG90YWwgPSBkaW1zLnJlZHVjZSgoeCwgeSkgPT4geCAqIHksIDEpO1xuICAgIGNvbnN0IHJpZ2h0ID0gZGltcy5zbGljZShheGlzKS5yZWR1Y2UoKHgsIHkpID0+IHggKiB5LCAxKTtcbiAgICBjb25zdCBvdXRwdXREaW1zID0gW3RvdGFsIC8gcmlnaHQsIHJpZ2h0XTtcblxuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgdGhlIHNoYXBlIG9mIG91dHB1dCB0ZW5zb3IgeSA9IHNxdWVlemUoeCwgYXhlcylcbiAgICogQHBhcmFtIGRpbXMgLSBzaGFwZSBvZiBpbnB1dCB0ZW5zb3JcbiAgICogQHBhcmFtIGF4ZXMgLSBzcXVlZXplIGF4ZXNcbiAgICovXG4gIHN0YXRpYyBzcXVlZXplU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IG91dHB1dERpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXG4gICAgLy8gc2FuaXR5IGNoZWNrXG4gICAgYXhlcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGVzKGF4ZXMsIGRpbXMubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGltcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgaW5TcXVlZXplTGlzdCA9IGF4ZXMuaW5kZXhPZihpKSA+PSAwO1xuICAgICAgaWYgKGluU3F1ZWV6ZUxpc3QgJiYgZGltc1tpXSAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NxdWVlemUgYW4gYXhpcyBvZiBzaXplIGRpZmZlcmVudCB0aGFuIDEnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKChheGVzLmxlbmd0aCA9PT0gMCAmJiBkaW1zW2ldID4gMSkgfHwgKGF4ZXMubGVuZ3RoID4gMCAmJiAhaW5TcXVlZXplTGlzdCkpIHtcbiAgICAgICAgb3V0cHV0RGltcy5wdXNoKGRpbXNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgdGhlIHNoYXBlIG9mIG91dHB1dCB0ZW5zb3IgeSA9IHVuc3F1ZWV6ZSh4LCBheGVzKVxuICAgKiBAcGFyYW0gZGltcyAtIHNoYXBlIG9mIGlucHV0IHRlbnNvclxuICAgKiBAcGFyYW0gYXhlcyAtIHVuc3F1ZWV6ZSBheGVzXG4gICAqL1xuICBzdGF0aWMgdW5zcXVlZXplU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IG91dHB1dERpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPihkaW1zLmxlbmd0aCArIGF4ZXMubGVuZ3RoKTtcblxuICAgIC8vIGluaXRpYWxpemUgdGhlIGFycmF5IGVsZW1lbnRzIHRvIDBcbiAgICBvdXRwdXREaW1zLmZpbGwoMCk7XG5cbiAgICAvLyBzZXQgYWxsIGF4ZXMgaW5kaWNlcyB0byAxIGluIG91dHB1dERpbXMgYW5kIGNoZWNrIGZvciBkdXBsaWNhdGVzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBheGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXhlc1tpXSwgb3V0cHV0RGltcy5sZW5ndGgpO1xuICAgICAgaWYgKGF4aXMgPj0gb3V0cHV0RGltcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiJ2F4ZXMnIGhhcyBhbiBvdXQgb2YgcmFuZ2UgYXhpc1wiKTtcbiAgICAgIH1cbiAgICAgIGlmIChvdXRwdXREaW1zW2F4aXNdICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIidheGVzJyBoYXMgYSBkdXBsaWNhdGUgYXhpc1wiKTtcbiAgICAgIH1cblxuICAgICAgb3V0cHV0RGltc1theGlzXSA9IDE7XG4gICAgfVxuXG4gICAgLy8gZmlsbCBpbiB0aGUgemVybyBlbnRyaWVzIG9mIG91dHB1dERpbXMgd2l0aCB0aGUgaW5wdXQgdGVuc29yJ3Mgc2hhcGVcbiAgICBsZXQgaW5wdXREaW1zSXRlcmF0b3IgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0RGltcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG91dHB1dERpbXNbaV0gPT09IDApIHtcbiAgICAgICAgb3V0cHV0RGltc1tpXSA9IGRpbXNbaW5wdXREaW1zSXRlcmF0b3IrK107XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2FuaXR5IGNoZWNrIGFzc2VydGlvbi4gJ2lucHV0RGltc0l0ZXJhdG9yJ1xuICAgIC8vIHNob3VsZCBiZSBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mICdkaW1zJ1xuICAgIGlmIChpbnB1dERpbXNJdGVyYXRvciAhPT0gZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIHVuc3F1ZWV6ZWQgZGltZW5zaW9uIGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG59XG5cbi8vIGJ1bmNoIG9mIGhlbHBlciBtZXRob2RzIHRoYXQgZG8gYSB2YXJpZXR5IG9mIG1hdGggb3BlcmF0aW9uc1xuZXhwb3J0IGNsYXNzIE1hdGhVdGlsIHtcbiAgLy8geSA9ICh4KngpICsgeVxuICBzdGF0aWMgc3FyKFxuICAgIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBzb3VyY2U6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGFyZ2V0SW5kZXg6IG51bWJlcixcbiAgICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgIGJsb2NrU2l6ZTogbnVtYmVyLFxuICApIHtcbiAgICBpZiAoc291cmNlSW5kZXggPCAwIHx8IHNvdXJjZUluZGV4ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlSW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggPCAwIHx8IHRhcmdldEluZGV4ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0SW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAoc291cmNlSW5kZXggKyBibG9ja1NpemUgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSBpbmRpY2VzIHRvIGJlIGNvcGllZCBhcmUgb3V0c2lkZSBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4ICsgYmxvY2tTaXplID4gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXQgYXJyYXkgaXMgdG9vIHNtYWxsIHRvIGhvbGQgcmVzdWx0Jyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYmxvY2tTaXplOyBvZmZzZXQrKykge1xuICAgICAgdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XSArPSBNYXRoLnBvdyhzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdLCAyKTtcbiAgICB9XG4gIH1cblxuICAvLyB5ID0gYXggKyB5XG4gIHN0YXRpYyBheHB5KFxuICAgIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBzb3VyY2U6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGFyZ2V0SW5kZXg6IG51bWJlcixcbiAgICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgIGJsb2NrU2l6ZTogbnVtYmVyLFxuICAgIGFscGhhOiBudW1iZXIsXG4gICkge1xuICAgIGlmIChzb3VyY2VJbmRleCA8IDAgfHwgc291cmNlSW5kZXggPj0gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCA8IDAgfHwgdGFyZ2V0SW5kZXggPj0gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmIChzb3VyY2VJbmRleCArIGJsb2NrU2l6ZSA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGluZGljZXMgdG8gYmUgY29waWVkIGFyZSBvdXRzaWRlIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggKyBibG9ja1NpemUgPiB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldCBhcnJheSBpcyB0b28gc21hbGwgdG8gaG9sZCByZXN1bHQnKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBibG9ja1NpemU7IG9mZnNldCsrKSB7XG4gICAgICB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdICs9IGFscGhhICogc291cmNlW3NvdXJjZUluZGV4ICsgb2Zmc2V0XTtcbiAgICB9XG4gIH1cblxuICAvLyB5ID0gcG93KHgsIGIpXG4gIHN0YXRpYyBwb3d4KFxuICAgIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBzb3VyY2U6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGFyZ2V0SW5kZXg6IG51bWJlcixcbiAgICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgIGJsb2NrU2l6ZTogbnVtYmVyLFxuICAgIGI6IG51bWJlcixcbiAgKSB7XG4gICAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICAgIH1cblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gPSBNYXRoLnBvdyhzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdLCBiKTtcbiAgICB9XG4gIH1cblxuICAvLyB5ID0geCAqIHlcbiAgc3RhdGljIG11bChcbiAgICB0YXJnZXQ6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgc291cmNlOiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHRhcmdldEluZGV4OiBudW1iZXIsXG4gICAgc291cmNlSW5kZXg6IG51bWJlcixcbiAgICBibG9ja1NpemU6IG51bWJlcixcbiAgKSB7XG4gICAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICAgIH1cblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gPSBzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdICogdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNwbGl0VXRpbCB7XG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIG5ldyBTaGFwZXMgZnJvbSBleGlzdGluZyBvbmUgYW5kIHRoZSBzcGxpdHMgZ2l2ZW4gYWxvbmcgdGhlIGF4aXMgcHJvdmlkZXNcbiAgICogQHBhcmFtIGRpbXMgU2hhcGUgb2YgdGhlIFRlbnNvciB0byBiZSBzcGxpdHRlZCBpbnRvIHR3byBvciBtb3JlIFNoYXBlc1xuICAgKiBAcGFyYW0gYXhpcyBUaGUgZGltZW5zaW9uIGFsb25nIHdoaWNoIHRoZSBUZW5zb3Igd2lsbCBiZSBzcGxpdFxuICAgKiBAcGFyYW0gc3BsaXRzIE9mZnNldHMgZm9yIHRoZSBzdGFydCBvZiBlYWNoIHNwbGl0XG4gICAqL1xuICBzdGF0aWMgc3BsaXRTaGFwZShcbiAgICBkaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBheGlzOiBudW1iZXIsXG4gICAgc3BsaXQ6IG51bWJlcltdLFxuICAgIG51bU91dHB1dHM/OiBudW1iZXIsXG4gICk6IFtudW1iZXJbXVtdLCBudW1iZXJbXV0ge1xuICAgIGlmIChzcGxpdC5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmICghbnVtT3V0cHV0cykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJuZWVkIHRvIGtub3cgbnVtYmVyIG9mIG91dHB1dHMgd2hlbiB0aGUgJ3NwbGl0JyBhdHRyaWJ1dGUgaXMgbm90IHNwZWNpZmllZFwiKTtcbiAgICAgIH1cbiAgICAgIFNwbGl0VXRpbC5kZXRlcm1pbmVTcGxpdChkaW1zW2F4aXNdLCBudW1PdXRwdXRzLCBzcGxpdCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2hhcGVzOiBudW1iZXJbXVtdID0gW107XG4gICAgY29uc3Qgb2Zmc2V0cyA9IFswXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNwbGl0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBpZiAoaSAhPT0gMCkge1xuICAgICAgICBvZmZzZXRzLnB1c2gob2Zmc2V0c1tpIC0gMV0gKyBzcGxpdFtpIC0gMV0pO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2hhcGUgPSBkaW1zLnNsaWNlKCk7XG4gICAgICBzaGFwZVtheGlzXSA9IHNwbGl0W2ldO1xuICAgICAgc2hhcGVzLnB1c2goc2hhcGUpO1xuICAgIH1cbiAgICByZXR1cm4gW3NoYXBlcywgb2Zmc2V0c107XG4gIH1cblxuICBzdGF0aWMgZGV0ZXJtaW5lU3BsaXQobnVtRWxlbWVudHNBbG9uZ0F4aXM6IG51bWJlciwgbnVtT3V0cHV0czogbnVtYmVyLCBzcGxpdDogbnVtYmVyW10pIHtcbiAgICAvLyBJZiAnc3BsaXQnIGlzIG5vdCBzcGVjaWZpZWQgYnkgdGhlIHVzZXIsIHdlIG5lZWQgdG8gcGFydGl0aW9uIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgZXF1YWxseSBhbW9uZyB0aGUgb3V0cHV0c1xuICAgIGlmIChudW1FbGVtZW50c0Fsb25nQXhpcyAlIG51bU91dHB1dHMgIT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IHNwbGl0IHRlbnNvciB0byBlcXVhbCBzaXplZCBwYXJ0cycpO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bU91dHB1dHM7ICsraSkge1xuICAgICAgc3BsaXQucHVzaChudW1FbGVtZW50c0Fsb25nQXhpcyAvIG51bU91dHB1dHMpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUmVkdWNlVXRpbCB7XG4gIC8qKlxuICAgKiBQZXJmb3JtIHJlZHVjZSBvcGVyYXRpb25zIG9uIHRoZSBzcGVjaWZpYyBvcGVyYXRvclxuICAgKiBAcGFyYW0gYSBJbnB1dCB0ZW5zb3IgZGF0YVxuICAgKiBAcGFyYW0gYXhlcyBUaGUgZGltZW5zaW9ucyBhbG9uZyB3aGljaCB0aGUgVGVuc29yIHdpbGwgYmUgcmVkdWNlZFxuICAgKiBAcGFyYW0ga2VlcGRpbXMgSWYgc2V0IHRvIHRydWUsIHRoZSBheGVzIHdoaWNoIGFyZSByZWR1Y2VkIGFyZSBsZWZ0IGluIHRoZVxuICAgKiAgICByZXN1bHQgYXMgZGltZW5zaW9ucyB3aXRoIHNpemUgb25lLlxuICAgKiBAcGFyYW0gb3AxIFRoZSBvcGVyYXRpb24gdG8gYmUgcGVyZm9ybWVkIG9uIGVhY2ggZWxlbWVudCBpbiB0aGUgdGVuc29yXG4gICAqIEBwYXJhbSBvcDIgVGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgYmV0d2VlbiBlbGVtZW50cyBpbiB0aGUgdGVuc29yXG4gICAqL1xuICBzdGF0aWMgY2FsY1JlZHVjZShcbiAgICBhOiBUZW5zb3IsXG4gICAgYXhlczogbnVtYmVyW10sXG4gICAga2VlcGRpbXM6IGJvb2xlYW4sXG4gICAgb3AxOiAoYjogbnVtYmVyKSA9PiBudW1iZXIsXG4gICAgb3AyOiAoYTogbnVtYmVyLCBiOiBudW1iZXIpID0+IG51bWJlcixcbiAgKTogVGVuc29yIHtcbiAgICBjb25zdCBkaW1zID0gYS5kaW1zLnNsaWNlKDApO1xuICAgIC8vIGlmIGF4ZXMgaXMgbm90IHNldCwgcGVyZm9ybSByZWR1Y2Ugb24gYWxsIGF4ZXNcbiAgICBpZiAoYXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGRpbXMuZm9yRWFjaCgoX2QsIGluZCkgPT4gYXhlcy5wdXNoKGluZCkpO1xuICAgIH1cbiAgICAvLyBnZXQgYSB0ZW1wb3JhcnkgYnJvYWRjYXN0YWJsZSBvdXRwdXQgc2hhcGVcbiAgICBjb25zdCBvdXRwdXREaW1zID0gUmVkdWNlVXRpbC5jYWxjUmVkdWNlU2hhcGUoZGltcywgYXhlcywgdHJ1ZSk7XG5cbiAgICAvLyBsb29wIHRocm91Z2ggdGhlIG91dHB1dCBhbmQgY2FsY3VsYXRlIHJlc3VsdCBvbmUgYnkgb25lXG4gICAgY29uc3Qgc2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dERpbXMpO1xuICAgIGNvbnN0IHkgPSBuZXcgVGVuc29yKG91dHB1dERpbXMsIGEudHlwZSk7XG4gICAgY29uc3Qgc3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhvdXRwdXREaW1zKTtcbiAgICBjb25zdCBpbnB1dFN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoZGltcyk7XG4gICAgY29uc3QgaW5kaWNlc1kgPSBuZXcgQXJyYXkoZGltcy5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRpY2VzID0gU2hhcGVVdGlsLm9mZnNldFRvSW5kaWNlcyhpLCBzdHJpZGVzKTtcbiAgICAgIC8vIG1hcCBpbmRleFxuICAgICAgQnJvYWRjYXN0VXRpbC5maWxsSW5kZXgoaW5kaWNlcywgZGltcywgaW5kaWNlc1kpO1xuICAgICAgeS5zZXQoXG4gICAgICAgIGluZGljZXMsXG4gICAgICAgIFJlZHVjZVV0aWwuY2FsY1JlZHVjZUJ5QXhpcyhcbiAgICAgICAgICBhLm51bWJlckRhdGEsXG4gICAgICAgICAgYXhlcyxcbiAgICAgICAgICBkaW1zLFxuICAgICAgICAgIDAsXG4gICAgICAgICAgU2hhcGVVdGlsLmluZGljZXNUb09mZnNldChpbmRpY2VzWSwgaW5wdXRTdHJpZGVzKSxcbiAgICAgICAgICBvcDEsXG4gICAgICAgICAgb3AyLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoa2VlcGRpbXMpIHtcbiAgICAgIHJldHVybiB5O1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBrZWVwZGltcyA9PSAwLCBjYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHNoYXBlXG4gICAgICByZXR1cm4gbmV3IFRlbnNvcihcbiAgICAgICAgUmVkdWNlVXRpbC5jYWxjUmVkdWNlU2hhcGUoZGltcywgYXhlcywga2VlcGRpbXMpLFxuICAgICAgICB5LnR5cGUsXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICB5LmRhdGEsXG4gICAgICAgIHkuZGF0YUlkLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybSByZWR1Y2Ugb3BlcmF0aW9ucyBvbiB0aGUgc3BlY2lmaWMgb3BlcmF0b3Igb24gc3BlY2lmaWMgYXhlc1xuICAgKiBAcGFyYW0gYSBJbnB1dCB0ZW5zb3IgZGF0YVxuICAgKiBAcGFyYW0gYXhlcyBUaGUgZGltZW5zaW9ucyBhbG9uZyB3aGljaCB0aGUgVGVuc29yIHdpbGwgYmUgcmVkdWNlZFxuICAgKiBAcGFyYW0gZGltcyBUaGUgaW5wdXQgZGltZW5zaW9uLlxuICAgKiBAcGFyYW0gY3VyQXhpc0luZCBJbmRleCBpbiBheGVzIHNwZWNpZnlpbmcgdGhlIGN1cnJlbnQgZGltZW5zaW9uIGFsb25nXG4gICAqICAgICAgd2hpY2ggdGhlIHRlbnNvciB3aWxsIGJlIHJlZHVjZWRcbiAgICogQHBhcmFtIHBvcyBUaGUgY3VycmVudCBpbmRleCBvZiBlbGVtZW50IHRvIHBlcmZvcm0gb3BlcmF0aW9uXG4gICAqIEBwYXJhbSBvcDEgVGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgb24gZWFjaCBlbGVtZW50IGluIHRoZSB0ZW5zb3JcbiAgICogQHBhcmFtIG9wMiBUaGUgb3BlcmF0aW9uIHRvIGJlIHBlcmZvcm1lZCBiZXR3ZWVuIGVsZW1lbnRzIGluIHRoZSB0ZW5zb3JcbiAgICovXG4gIHN0YXRpYyBjYWxjUmVkdWNlQnlBeGlzKFxuICAgIGlucHV0OiBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBheGVzOiBudW1iZXJbXSxcbiAgICBkaW1zOiBudW1iZXJbXSxcbiAgICBjdXJBeGlzSW5kOiBudW1iZXIsXG4gICAgcG9zOiBudW1iZXIsXG4gICAgb3AxOiAoYjogbnVtYmVyKSA9PiBudW1iZXIsXG4gICAgb3AyOiAoYTogbnVtYmVyLCBiOiBudW1iZXIpID0+IG51bWJlcixcbiAgKTogbnVtYmVyIHtcbiAgICBsZXQgcmVzID0gMDtcbiAgICBpZiAoY3VyQXhpc0luZCA+PSBheGVzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIG9wMShpbnB1dFtwb3NdKTtcbiAgICB9XG4gICAgY29uc3QgYXhpcyA9IGF4ZXNbY3VyQXhpc0luZF07XG4gICAgY29uc3Qgc3RlcCA9IGF4aXMgPj0gZGltcy5sZW5ndGggPyAxIDogU2hhcGVVdGlsLnNpemUoZGltcy5zbGljZShheGlzICsgMSkpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGltc1theGlzXTsgaSsrKSB7XG4gICAgICByZXMgPVxuICAgICAgICBpID09PSAwXG4gICAgICAgICAgPyBSZWR1Y2VVdGlsLmNhbGNSZWR1Y2VCeUF4aXMoaW5wdXQsIGF4ZXMsIGRpbXMsIGN1ckF4aXNJbmQgKyAxLCBwb3MsIG9wMSwgb3AyKVxuICAgICAgICAgIDogb3AyKHJlcywgUmVkdWNlVXRpbC5jYWxjUmVkdWNlQnlBeGlzKGlucHV0LCBheGVzLCBkaW1zLCBjdXJBeGlzSW5kICsgMSwgcG9zLCBvcDEsIG9wMikpO1xuICAgICAgcG9zICs9IHN0ZXA7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBleHBlY3RlZCBzaGFwZSBvZiBhIHJlZHVjZSBvcGVyYXRpb25cbiAgICogQHBhcmFtIGRpbXMgVGhlIGlucHV0IHRlbnNvciBkaW1lbnNpb25cbiAgICogQHBhcmFtIGF4ZXMgVGhlIGRpbWVuc2lvbnMgYWxvbmcgd2hpY2ggdGhlIFRlbnNvciB3aWxsIGJlIHJlZHVjZWRcbiAgICogQHBhcmFtIGtlZXBkaW1zIElmIHNldCB0byB0cnVlLCB0aGUgYXhlcyB3aGljaCBhcmUgcmVkdWNlZCBhcmUgbGVmdCBpbiB0aGVcbiAgICogICAgcmVzdWx0IGFzIGRpbWVuc2lvbnMgd2l0aCBzaXplIG9uZS5cbiAgICovXG4gIHN0YXRpYyBjYWxjUmVkdWNlU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdLCBrZWVwRGltczogYm9vbGVhbik6IG51bWJlcltdIHtcbiAgICBjb25zdCBvdXRwdXREaW1zID0gZGltcy5zbGljZSgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXhlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGtlZXBEaW1zKSB7XG4gICAgICAgIG91dHB1dERpbXNbYXhlc1tpXV0gPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0RGltc1theGVzW2ldXSA9IDA7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXREaW1zLmZpbHRlcigoZGltKSA9PiBkaW0gIT09IDApO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQb29sQ29udlV0aWwge1xuICAvKipcbiAgICogQWRqdXN0IHRoZSBrZXJuZWwsIHN0cmlkZXMsIHBhZHMgdG8gY29ycmVjdCByYW5rLiBTZXQgdG8gZGVmYXVsdCB2YWx1ZSBpZiBub3QgcHJlc2VudFxuICAgKiBAcGFyYW0gaXNHbG9iYWxPcGVyYXRvciBJZiB0cnVlLCBwZXJmb3JtIGdsb2JhbCBwb29saW5nLlxuICAgKiBAcGFyYW0gaW5wdXREaW1zIFRoZSBpbnB1dCB0ZW5zb3IgZGltZW5zaW9uLlxuICAgKiBAcGFyYW0ga2VybmVsU2hhcGUgVGhlIHNpemUgb2YgdGhlIGtlcm5lbCBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBzdHJpZGVzIFN0cmlkZSBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBkaWxhdGlvbnMgRGlsYXRpb24gYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gcGFkcyBQYWRkaW5nIGZvciB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgYWxvbmcgZWFjaCBheGlzLlxuICAgKi9cbiAgc3RhdGljIGFkanVzdFBvb2xBdHRyaWJ1dGVzKFxuICAgIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gICAgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogbnVtYmVyW10sXG4gICAgc3RyaWRlczogbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiBudW1iZXJbXSxcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgKSB7XG4gICAgaWYgKCFpc0dsb2JhbE9wZXJhdG9yICYmIGtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXREaW1zLmxlbmd0aCAtIDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHNwZWNpZmllZCBrZXJuZWwgc2hhcGVzIHNob3VsZCBiZSAyIGxlc3MgdGhhbiBsZW5ndGggb2YgaW5wdXQgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGlmIChpc0dsb2JhbE9wZXJhdG9yKSB7XG4gICAgICAvLyBhZGp1c3Qga2VybmVsIHNoYXBlIHRvIGNvdmVyIHRoZSBpbnB1dCBkaW1zXG4gICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgICAgaWYgKGRpbSA+PSBrZXJuZWxTaGFwZS5sZW5ndGgpIHtcbiAgICAgICAgICBrZXJuZWxTaGFwZS5wdXNoKGlucHV0RGltc1tkaW0gKyAyXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAga2VybmVsU2hhcGVbZGltXSA9IGlucHV0RGltc1tkaW0gKyAyXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkanVzdCBzdHJpZGVzIGxlbmd0aCB0byBtYXRjaCBrZXJuZWwgc2hhcGUgbGVuZ3RoXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoOyBkaW0rKykge1xuICAgICAgaWYgKGRpbSA8IHN0cmlkZXMubGVuZ3RoKSB7XG4gICAgICAgIGlmIChzdHJpZGVzW2RpbV0gPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdHJpZGVzIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHJpZGVzLnB1c2goMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYWRqdXN0IGRpbGF0aW9uIHZhbHVlXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoOyBkaW0rKykge1xuICAgICAgaWYgKGRpbSA8IGRpbGF0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKGRpbGF0aW9uc1tkaW1dIDwgMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZGlsYXRpb25zIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaWxhdGlvbnMucHVzaCgxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhZGp1c3QgcGFkcyBsZW5ndGggdG8gbWF0Y2ggMiAqIGtlcm5lbCBzaGFwZSBsZW5ndGhcbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBrZXJuZWxTaGFwZS5sZW5ndGggKiAyOyBkaW0rKykge1xuICAgICAgaWYgKGRpbSA8IHBhZHMubGVuZ3RoKSB7XG4gICAgICAgIGlmIChwYWRzW2RpbV0gPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwYWQgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhZHMucHVzaCgwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzYW5pdHkgY2hlY2tzIGZvciB2YWx1ZXMgaW4ga2VybmVsIHNoYXBlcyBhbmQgcGFkc1xuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGtlcm5lbFNoYXBlLmxlbmd0aDsgZGltKyspIHtcbiAgICAgIGlmIChrZXJuZWxTaGFwZVtkaW1dIDw9IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdrZXJuZWwgc2hhcGVzIG5lZWQgdG8gYmUgZ3JlYXRlciB0aGFuIDAnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhZHNbZGltXSA+PSBrZXJuZWxTaGFwZVtkaW1dIHx8IHBhZHNbZGltICsga2VybmVsU2hhcGUubGVuZ3RoXSA+PSBrZXJuZWxTaGFwZVtkaW1dKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncGFkcyBzaG91bGQgYmUgc21hbGxlciB0aGFuIGtlcm5lbCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGFkanVzdCBwYWQgdmFsdWVzIGJhc2VkIG9uICdhdXRvUGFkJyBhdHRyaWJ1dGVcbiAgc3RhdGljIGFkanVzdFBhZHNCYXNlZE9uQXV0b1BhZChcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICAgIGF1dG9QYWQ/OiBzdHJpbmcsXG4gICkge1xuICAgIGlmICghYXV0b1BhZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwYWRzLmxlbmd0aCAhPT0gMiAqIChpbnB1dERpbXMubGVuZ3RoIC0gMikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHBhZHMgc2hvdWxkIGJlIHR3aWNlIHRoZSBsZW5ndGggb2YgZGF0YSBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgaWYgKHN0cmlkZXMubGVuZ3RoICE9PSBpbnB1dERpbXMubGVuZ3RoIC0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2Ygc3RyaWRlcyBzaG91bGQgYmUgdGhlIGxlbmd0aCBvZiBkYXRhIGRpbWVuc2lvbnMnKTtcbiAgICB9XG5cbiAgICBpZiAoa2VybmVsU2hhcGUubGVuZ3RoICE9PSBpbnB1dERpbXMubGVuZ3RoIC0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2Yga2VybmVsIHNoYXBlcyBzaG91bGQgYmUgdGhlIGxlbmd0aCBvZiBkYXRhIGRpbWVuc2lvbnMnKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgIFBvb2xDb252VXRpbC5hZGp1c3RQYWRBbmRSZXR1cm5TaGFwZShcbiAgICAgICAgaW5wdXREaW1zW2RpbSArIDJdLFxuICAgICAgICBzdHJpZGVzW2RpbV0sXG4gICAgICAgIGRpbGF0aW9uc1tkaW1dLFxuICAgICAgICBrZXJuZWxTaGFwZVtkaW1dLFxuICAgICAgICBwYWRzLFxuICAgICAgICBkaW0sXG4gICAgICAgIGRpbSArIGlucHV0RGltcy5sZW5ndGggLSAyLFxuICAgICAgICBhdXRvUGFkLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBvdXRwdXQgc2hhcGUgZm9yIFBvb2wgb3BzIGJhc2VkIG9uIGlucHV0IGF0dHJpYnV0ZXMuIChTaG91bGQgYmUgdXNlZCBvbmx5IGZvciBQb29sIG9wcylcbiAgICogQHBhcmFtIGlzR2xvYmFsT3BlcmF0b3IgSWYgdHJ1ZSwgcGVyZm9ybSBnbG9iYWwgcG9vbGluZy5cbiAgICogQHBhcmFtIGlucHV0RGltcyBUaGUgaW5wdXQgdGVuc29yIGRpbWVuc2lvbi4gKGlucHV0c1swXS5kaW1zKVxuICAgKiBAcGFyYW0gc3RyaWRlcyBTdHJpZGUgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gZGlsYXRpb25zIERpbGF0aW9uIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGtlcm5lbFNoYXBlIFRoZSBzaXplIG9mIHRoZSBrZXJuZWwgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gcGFkcyBQYWRkaW5nIGZvciB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gYXV0b1BhZCBERVBSRUNBVEVEIGF0dHJpYnV0ZSBzdXBwb3J0ZWQgZm9yIGxlZ2FjeSBtb2RlbHMuIFNwZWNpZmllcyBob3cgdG8gaW1wbGljaXRseSBjYWxjdWxhdGUgcGFkcyBpbiBlYWNoXG4gICAqICAgICBkaW1lbnNpb24uIENhbiB0YWtlIHZhbHVlcyBOT1RTRVQsIFNBTUVfVVBQRVIsIFNBTUVfTE9XRVIsIG9yIFZBTElELlxuICAgKi9cbiAgc3RhdGljIGNvbXB1dGVQb29sT3V0cHV0U2hhcGUoXG4gICAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHN0cmlkZXM6IG51bWJlcltdLFxuICAgIGRpbGF0aW9uczogbnVtYmVyW10sXG4gICAga2VybmVsU2hhcGU6IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICAgIGF1dG9QYWQ/OiBzdHJpbmcsXG4gICk6IG51bWJlcltdIHtcbiAgICBpZiAoaW5wdXREaW1zLmxlbmd0aCA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHNoYXBlIG11c3QgYmUgb2Ygc2l6ZSBncmVhdGVyIHRoYW4gMCcpO1xuICAgIH1cblxuICAgIC8vIEFkZCBiYXRjaCBzaXplIGFuZCBudW1iZXIgb2YgY2hhbm5lbHMgb2Ygb3V0cHV0XG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IFtpbnB1dERpbXNbMF0sIGlucHV0RGltc1sxXV07XG5cbiAgICBQb29sQ29udlV0aWwuY29tcHV0ZVNoYXBlSGVscGVyKFxuICAgICAgaXNHbG9iYWxPcGVyYXRvcixcbiAgICAgIGlucHV0RGltcyxcbiAgICAgIG91dHB1dERpbXMsXG4gICAgICBzdHJpZGVzLFxuICAgICAgZGlsYXRpb25zLFxuICAgICAga2VybmVsU2hhcGUsXG4gICAgICBwYWRzLFxuICAgICAgYXV0b1BhZCxcbiAgICApO1xuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSB0aGUgb3V0cHV0IHNoYXBlIGZvciBDb252IG9wIGJhc2VkIG9uIGlucHV0IGF0dHJpYnV0ZXMuIChTaG91bGQgYmUgdXNlZCBvbmx5IGZvciBDb252IG9wKVxuICAgKiBAcGFyYW0gaW5wdXREaW1zIFRoZSBpbnB1dCB0ZW5zb3IgZGltZW5zaW9uLiAoaW5wdXRzWzBdLmRpbXMpXG4gICAqIEBwYXJhbSBmaWx0ZXJEaW1zIFRoZSBmaWx0ZXIgdGVuc29yIGRpbWVuc2lvbi4gKGlucHV0c1sxXS5kaW1zKVxuICAgKiBAcGFyYW0gc3RyaWRlcyBTdHJpZGUgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0ga2VybmVsU2hhcGUgVGhlIHNpemUgb2YgdGhlIGtlcm5lbCBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBwYWRzIFBhZGRpbmcgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZGluZyBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBhdXRvUGFkIERFUFJFQ0FURUQgYXR0cmlidXRlIHN1cHBvcnRlZCBmb3IgbGVnYWN5IG1vZGVscy4gU3BlY2lmaWVzIGhvdyB0byBpbXBsaWNpdGx5IGNhbGN1bGF0ZSBwYWRzIGluIGVhY2hcbiAgICogICAgIGRpbWVuc2lvbi4gQ2FuIHRha2UgdmFsdWVzIE5PVFNFVCwgU0FNRV9VUFBFUiwgU0FNRV9MT1dFUiwgb3IgVkFMSUQuXG4gICAqL1xuICBzdGF0aWMgY29tcHV0ZUNvbnZPdXRwdXRTaGFwZShcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGZpbHRlckRpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHN0cmlkZXM6IG51bWJlcltdLFxuICAgIGRpbGF0aW9uczogbnVtYmVyW10sXG4gICAga2VybmVsU2hhcGU6IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICAgIGF1dG9QYWQ/OiBzdHJpbmcsXG4gICk6IG51bWJlcltdIHtcbiAgICBpZiAoaW5wdXREaW1zLmxlbmd0aCA8PSAwIHx8IGZpbHRlckRpbXMubGVuZ3RoIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCB0ZW5zb3IgZGltcyBvciBpbnZhbGlkIGZpbHRlciB0ZW5zb3IgZGltcycpO1xuICAgIH1cblxuICAgIC8vIEFkZCBiYXRjaCBzaXplIGFuZCBudW1iZXIgb2YgY2hhbm5lbHMgb2Ygb3V0cHV0XG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IFtpbnB1dERpbXNbMF0sIGZpbHRlckRpbXNbMF1dO1xuXG4gICAgUG9vbENvbnZVdGlsLmNvbXB1dGVTaGFwZUhlbHBlcihmYWxzZSwgaW5wdXREaW1zLCBvdXRwdXREaW1zLCBzdHJpZGVzLCBkaWxhdGlvbnMsIGtlcm5lbFNoYXBlLCBwYWRzLCBhdXRvUGFkKTtcbiAgICByZXR1cm4gb3V0cHV0RGltcztcbiAgfVxuXG4gIC8vIHdpbGwgY29tcHV0ZSBvdXRwdXQgc2hhcGVzIGZvciBkYXRhIGRpbWVuc2lvbnMgT05MWSAoaS5lLikgbm8gYmF0Y2ggc2l6ZSBhbmQgY2hhbm5lbHNcbiAgLy8gY2FsbGVkIGJ5IGNvbXB1dGVQb29sT3V0cHV0U2hhcGUoKSBhbmQgY29tcHV0ZUNvbnZPdXRwdXRTaGFwZSgpXG4gIC8vIGFkanVzdCBwYWRzIGJhc2VkIG9uICdhdXRvUGFkJyBhdHRyaWJ1dGUgcHJpb3IgdG8gc2hhcGUgY29tcHV0YXRpb25cbiAgcHJpdmF0ZSBzdGF0aWMgY29tcHV0ZVNoYXBlSGVscGVyKFxuICAgIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gICAgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBvdXRwdXREaW1zOiBudW1iZXJbXSxcbiAgICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgICBhdXRvUGFkPzogc3RyaW5nLFxuICApIHtcbiAgICBpZiAoaXNHbG9iYWxPcGVyYXRvcikge1xuICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgaW5wdXREaW1zLmxlbmd0aCAtIDI7IGRpbSsrKSB7XG4gICAgICAgIG91dHB1dERpbXMucHVzaCgxKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgaW5wdXREaW1zLmxlbmd0aCAtIDI7IGRpbSsrKSB7XG4gICAgICAgIG91dHB1dERpbXMucHVzaChcbiAgICAgICAgICBQb29sQ29udlV0aWwuYWRqdXN0UGFkQW5kUmV0dXJuU2hhcGUoXG4gICAgICAgICAgICBpbnB1dERpbXNbZGltICsgMl0sXG4gICAgICAgICAgICBzdHJpZGVzW2RpbV0sXG4gICAgICAgICAgICBkaWxhdGlvbnNbZGltXSxcbiAgICAgICAgICAgIGtlcm5lbFNoYXBlW2RpbV0sXG4gICAgICAgICAgICBwYWRzLFxuICAgICAgICAgICAgZGltLFxuICAgICAgICAgICAgZGltICsgaW5wdXREaW1zLmxlbmd0aCAtIDIsXG4gICAgICAgICAgICBhdXRvUGFkLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gaGVscGVyIGZvciBjb21wdXRlU2hhcGVIZWxwZXIoKSBhbmQgYWRqdXN0UGFkc0Jhc2VkT25BdXRvUGFkKClcbiAgLy8gYWRqdXN0cyBwYWQgdmFsdWUgZm9yIGdpdmVuICdhdXRvUGFkJyBzdHJpbmcgYW5kIGNvbXB1dGVzIG91dHB1dCBzaGFwZSBhbG9uZyBhIHBhcnRpY3VsYXIgZGltZW5zaW9uXG4gIHByaXZhdGUgc3RhdGljIGFkanVzdFBhZEFuZFJldHVyblNoYXBlKFxuICAgIGluU2l6ZTogbnVtYmVyLFxuICAgIHN0cmlkZTogbnVtYmVyLFxuICAgIGRpbGF0aW9uOiBudW1iZXIsXG4gICAga2VybmVsOiBudW1iZXIsXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgcGFkSGVhZEluZGV4OiBudW1iZXIsXG4gICAgcGFkVGFpbEluZGV4OiBudW1iZXIsXG4gICAgYXV0b1BhZD86IHN0cmluZyxcbiAgKTogbnVtYmVyIHtcbiAgICBjb25zdCBka2VybmVsID0gZGlsYXRpb24gKiAoa2VybmVsIC0gMSkgKyAxO1xuICAgIGlmIChhdXRvUGFkICYmIGF1dG9QYWQgIT09ICdOT1RTRVQnKSB7XG4gICAgICBzd2l0Y2ggKGF1dG9QYWQpIHtcbiAgICAgICAgY2FzZSAnVkFMSUQnOlxuICAgICAgICAgIHBhZHNbcGFkSGVhZEluZGV4XSA9IDA7XG4gICAgICAgICAgcGFkc1twYWRUYWlsSW5kZXhdID0gMDtcbiAgICAgICAgICByZXR1cm4gTWF0aC5mbG9vcigoaW5TaXplIC0gZGtlcm5lbCkgLyBzdHJpZGUgKyAxKTtcbiAgICAgICAgY2FzZSAnU0FNRV9MT1dFUic6XG4gICAgICAgIGNhc2UgJ1NBTUVfVVBQRVInOlxuICAgICAgICAgIGlmIChkaWxhdGlvbiAhPT0gMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEaWxhdGlvbiBub3Qgc3VwcG9ydGVkIGZvciBTQU1FX1VQUEVSIG9yIFNBTUVfTE9XRVInKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgbGVnYWN5VGFyZ2V0U2l6ZSA9IChpblNpemUgKyBzdHJpZGUgLSAxKSAvIHN0cmlkZTtcbiAgICAgICAgICAgIGNvbnN0IHBhZE5lZWRlZCA9IChsZWdhY3lUYXJnZXRTaXplIC0gMSkgKiBzdHJpZGUgKyBrZXJuZWwgLSBpblNpemU7XG4gICAgICAgICAgICBwYWRzW3BhZEhlYWRJbmRleF0gPSBhdXRvUGFkID09PSAnU0FNRV9MT1dFUicgPyBNYXRoLmZsb29yKChwYWROZWVkZWQgKyAxKSAvIDIpIDogTWF0aC5mbG9vcihwYWROZWVkZWQgLyAyKTtcbiAgICAgICAgICAgIHBhZHNbcGFkVGFpbEluZGV4XSA9IHBhZE5lZWRlZCAtIHBhZHNbcGFkSGVhZEluZGV4XTtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKChpblNpemUgKyBwYWROZWVkZWQgLSBrZXJuZWwpIC8gc3RyaWRlICsgMSk7XG4gICAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgQXV0b1BhZCB0eXBlJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBNYXRoLmZsb29yKChpblNpemUgKyBwYWRzW3BhZEhlYWRJbmRleF0gKyBwYWRzW3BhZFRhaWxJbmRleF0gLSBka2VybmVsKSAvIHN0cmlkZSArIDEpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgTUlOX0NMSVAgPSAtMy40MDI4MjM0NjYzODUyODg2ZTM4O1xuZXhwb3J0IGNvbnN0IE1BWF9DTElQID0gMy40MDI4MjM0NjYzODUyODg2ZTM4O1xuXG5leHBvcnQgZnVuY3Rpb24gZGVjb2RlVXRmOFN0cmluZyhidWZmZXI6IFVpbnQ4QXJyYXkpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKGJ1ZmZlcik7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEd1aWQgfSBmcm9tICdndWlkLXR5cGVzY3JpcHQnO1xuaW1wb3J0IExvbmcgZnJvbSAnbG9uZyc7XG5cbmltcG9ydCAqIGFzIG9ydEZicyBmcm9tICcuL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQgeyBvbm54IH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHsgZGVjb2RlVXRmOFN0cmluZywgUHJvdG9VdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgVGVuc29yIHtcbiAgZXhwb3J0IGludGVyZmFjZSBEYXRhVHlwZU1hcCB7XG4gICAgYm9vbDogVWludDhBcnJheTtcbiAgICBmbG9hdDMyOiBGbG9hdDMyQXJyYXk7XG4gICAgZmxvYXQ2NDogRmxvYXQ2NEFycmF5O1xuICAgIHN0cmluZzogc3RyaW5nW107XG4gICAgaW50ODogSW50OEFycmF5O1xuICAgIHVpbnQ4OiBVaW50OEFycmF5O1xuICAgIGludDE2OiBJbnQxNkFycmF5O1xuICAgIHVpbnQxNjogVWludDE2QXJyYXk7XG4gICAgaW50MzI6IEludDMyQXJyYXk7XG4gICAgdWludDMyOiBVaW50MzJBcnJheTtcbiAgICBpbnQ2NDogQmlnSW50NjRBcnJheTtcbiAgfVxuXG4gIGV4cG9ydCB0eXBlIERhdGFUeXBlID0ga2V5b2YgRGF0YVR5cGVNYXA7XG5cbiAgZXhwb3J0IHR5cGUgU3RyaW5nVHlwZSA9IFRlbnNvci5EYXRhVHlwZU1hcFsnc3RyaW5nJ107XG4gIGV4cG9ydCB0eXBlIEJvb2xlYW5UeXBlID0gVGVuc29yLkRhdGFUeXBlTWFwWydib29sJ107XG4gIGV4cG9ydCB0eXBlIEludGVnZXJUeXBlID1cbiAgICB8IFRlbnNvci5EYXRhVHlwZU1hcFsnaW50OCddXG4gICAgfCBUZW5zb3IuRGF0YVR5cGVNYXBbJ3VpbnQ4J11cbiAgICB8IFRlbnNvci5EYXRhVHlwZU1hcFsnaW50MTYnXVxuICAgIHwgVGVuc29yLkRhdGFUeXBlTWFwWyd1aW50MTYnXVxuICAgIHwgVGVuc29yLkRhdGFUeXBlTWFwWydpbnQzMiddXG4gICAgfCBUZW5zb3IuRGF0YVR5cGVNYXBbJ3VpbnQzMiddO1xuICBleHBvcnQgdHlwZSBGbG9hdFR5cGUgPSBUZW5zb3IuRGF0YVR5cGVNYXBbJ2Zsb2F0MzInXSB8IFRlbnNvci5EYXRhVHlwZU1hcFsnZmxvYXQ2NCddO1xuICBleHBvcnQgdHlwZSBOdW1iZXJUeXBlID0gQm9vbGVhblR5cGUgfCBJbnRlZ2VyVHlwZSB8IEZsb2F0VHlwZTtcblxuICBleHBvcnQgdHlwZSBJZCA9IEd1aWQ7XG59XG5cbnR5cGUgVGVuc29yRGF0YSA9IFRlbnNvci5EYXRhVHlwZU1hcFtUZW5zb3IuRGF0YVR5cGVdO1xuXG50eXBlIERhdGFQcm92aWRlciA9IChpZDogVGVuc29yLklkKSA9PiBUZW5zb3JEYXRhO1xudHlwZSBBc3luY0RhdGFQcm92aWRlciA9IChpZDogVGVuc29yLklkKSA9PiBQcm9taXNlPFRlbnNvckRhdGE+O1xuXG5leHBvcnQgY2xhc3MgVGVuc29yIHtcbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyB0ZW5zb3IgZGF0YVxuICAgKi9cbiAgZ2V0IGRhdGEoKTogVGVuc29yRGF0YSB7XG4gICAgaWYgKHRoaXMuY2FjaGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZGF0YVByb3ZpZGVyISh0aGlzLmRhdGFJZCk7XG4gICAgICBpZiAoZGF0YS5sZW5ndGggIT09IHRoaXMuc2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0xlbmd0aCBvZiBkYXRhIHByb3ZpZGVkIGJ5IHRoZSBEYXRhIFByb3ZpZGVyIGlzIGluY29uc2lzdGVudCB3aXRoIHRoZSBkaW1zIG9mIHRoaXMgVGVuc29yLicpO1xuICAgICAgfVxuICAgICAgdGhpcy5jYWNoZSA9IGRhdGE7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNhY2hlO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyBzdHJpbmcgdGVuc29yIGRhdGEuIFNob3VsZCBvbmx5IHVzZSB3aGVuIHR5cGUgaXMgU1RSSU5HXG4gICAqL1xuICBnZXQgc3RyaW5nRGF0YSgpIHtcbiAgICBpZiAodGhpcy50eXBlICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZGF0YSB0eXBlIGlzIG5vdCBzdHJpbmcnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5kYXRhIGFzIFRlbnNvci5TdHJpbmdUeXBlO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyBpbnRlZ2VyIHRlbnNvciBkYXRhLiBTaG91bGQgb25seSB1c2Ugd2hlbiB0eXBlIGlzIG9uZSBvZiB0aGUgZm9sbG93aW5nOiAoVUlOVDgsIElOVDgsIFVJTlQxNixcbiAgICogSU5UMTYsIElOVDMyLCBVSU5UMzIsIEJPT0wpXG4gICAqL1xuICBnZXQgaW50ZWdlckRhdGEoKSB7XG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgIGNhc2UgJ2ludDgnOlxuICAgICAgY2FzZSAndWludDE2JzpcbiAgICAgIGNhc2UgJ2ludDE2JzpcbiAgICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICBjYXNlICdib29sJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YSBhcyBUZW5zb3IuSW50ZWdlclR5cGU7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2RhdGEgdHlwZSBpcyBub3QgaW50ZWdlciAodWludDgsIGludDgsIHVpbnQxNiwgaW50MTYsIGludDMyLCB1aW50MzIsIGJvb2wpJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyBmbG9hdCB0ZW5zb3IgZGF0YS4gU2hvdWxkIG9ubHkgdXNlIHdoZW4gdHlwZSBpcyBvbmUgb2YgdGhlIGZvbGxvd2luZzogKEZMT0FULCBET1VCTEUpXG4gICAqL1xuICBnZXQgZmxvYXREYXRhKCkge1xuICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhIGFzIFRlbnNvci5GbG9hdFR5cGU7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2RhdGEgdHlwZSBpcyBub3QgZmxvYXQgKGZsb2F0MzIsIGZsb2F0NjQpJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyBudW1iZXIgdGVuc29yIGRhdGEuIFNob3VsZCBvbmx5IHVzZSB3aGVuIHR5cGUgaXMgb25lIG9mIHRoZSBmb2xsb3dpbmc6IChVSU5UOCwgSU5UOCwgVUlOVDE2LFxuICAgKiBJTlQxNiwgSU5UMzIsIFVJTlQzMiwgQk9PTCwgRkxPQVQsIERPVUJMRSlcbiAgICovXG4gIGdldCBudW1iZXJEYXRhKCkge1xuICAgIGlmICh0aGlzLnR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gdGhpcy5kYXRhIGFzIFRlbnNvci5OdW1iZXJUeXBlO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0eXBlIGNhbm5vdCBiZSBub24tbnVtYmVyIChzdHJpbmcpJyk7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHZhbHVlIG9mIGFuIGVsZW1lbnQgYXQgdGhlIGdpdmVuIGluZGljZXNcbiAgICovXG4gIGdldChpbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSk6IFRlbnNvci5EYXRhVHlwZU1hcFtUZW5zb3IuRGF0YVR5cGVdW251bWJlcl0ge1xuICAgIHJldHVybiB0aGlzLmRhdGFbU2hhcGVVdGlsLmluZGljZXNUb09mZnNldChpbmRpY2VzLCB0aGlzLnN0cmlkZXMpXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBzZXQgdmFsdWUgb2YgYW4gZWxlbWVudCBhdCB0aGUgZ2l2ZW4gaW5kaWNlc1xuICAgKi9cbiAgc2V0KGluZGljZXM6IHJlYWRvbmx5IG51bWJlcltdLCB2YWx1ZTogVGVuc29yLkRhdGFUeXBlTWFwW1RlbnNvci5EYXRhVHlwZV1bbnVtYmVyXSkge1xuICAgIHRoaXMuZGF0YVtTaGFwZVV0aWwuaW5kaWNlc1RvT2Zmc2V0KGluZGljZXMsIHRoaXMuc3RyaWRlcyldID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSB1bmRlcmx5aW5nIHRlbnNvciBkYXRhIGFzeW5jaHJvbm91c2x5XG4gICAqL1xuICBhc3luYyBnZXREYXRhKCk6IFByb21pc2U8VGVuc29yRGF0YT4ge1xuICAgIGlmICh0aGlzLmNhY2hlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuY2FjaGUgPSBhd2FpdCB0aGlzLmFzeW5jRGF0YVByb3ZpZGVyISh0aGlzLmRhdGFJZCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNhY2hlO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSB0ZW5zb3JcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzaXplOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSBfc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW107XG4gIC8qKlxuICAgKiBnZXQgdGhlIHN0cmlkZXMgZm9yIGVhY2ggZGltZW5zaW9uXG4gICAqL1xuICBnZXQgc3RyaWRlcygpOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgaWYgKCF0aGlzLl9zdHJpZGVzKSB7XG4gICAgICB0aGlzLl9zdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHRoaXMuZGltcyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9zdHJpZGVzO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgICogZ2V0IHRoZSBkaW1lbnNpb25zIG9mIHRoZSB0ZW5zb3JcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgZGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgLyoqXG4gICAgICogZ2V0IHRoZSB0eXBlIG9mIHRoZSB0ZW5zb3JcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdHlwZTogVGVuc29yLkRhdGFUeXBlLFxuICAgIHByaXZhdGUgZGF0YVByb3ZpZGVyPzogRGF0YVByb3ZpZGVyLFxuICAgIHByaXZhdGUgYXN5bmNEYXRhUHJvdmlkZXI/OiBBc3luY0RhdGFQcm92aWRlcixcbiAgICBwcml2YXRlIGNhY2hlPzogVGVuc29yRGF0YSxcbiAgICAvKipcbiAgICAgKiBnZXQgdGhlIGRhdGEgSUQgdGhhdCB1c2VkIHRvIG1hcCB0byBhIHRlbnNvciBkYXRhXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGRhdGFJZDogR3VpZCA9IEd1aWQuY3JlYXRlKCksXG4gICkge1xuICAgIHRoaXMuc2l6ZSA9IFNoYXBlVXRpbC52YWxpZGF0ZURpbXNBbmRDYWxjU2l6ZShkaW1zKTtcbiAgICBjb25zdCBzaXplID0gdGhpcy5zaXplO1xuICAgIGNvbnN0IGVtcHR5ID0gZGF0YVByb3ZpZGVyID09PSB1bmRlZmluZWQgJiYgYXN5bmNEYXRhUHJvdmlkZXIgPT09IHVuZGVmaW5lZCAmJiBjYWNoZSA9PT0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGNhY2hlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChjYWNoZS5sZW5ndGggIT09IHNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnB1dCBkaW1zIGRvZXNuJ3QgbWF0Y2ggZGF0YSBsZW5ndGguXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKGNhY2hlICE9PSB1bmRlZmluZWQgJiYgKCFBcnJheS5pc0FycmF5KGNhY2hlKSB8fCAhY2FjaGUuZXZlcnkoKGkpID0+IHR5cGVvZiBpID09PSAnc3RyaW5nJykpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2NhY2hlIHNob3VsZCBiZSBhIHN0cmluZyBhcnJheScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZW1wdHkpIHtcbiAgICAgICAgdGhpcy5jYWNoZSA9IG5ldyBBcnJheTxzdHJpbmc+KHNpemUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoY2FjaGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBjb25zdHJ1Y3RvciA9IGRhdGF2aWV3Q29uc3RydWN0b3IodHlwZSk7XG4gICAgICAgIGlmICghKGNhY2hlIGluc3RhbmNlb2YgY29uc3RydWN0b3IpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgY2FjaGUgc2hvdWxkIGJlIHR5cGUgJHtjb25zdHJ1Y3Rvci5uYW1lfWApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChlbXB0eSkge1xuICAgICAgICBjb25zdCBidWYgPSBuZXcgQXJyYXlCdWZmZXIoc2l6ZSAqIHNpemVvZih0eXBlKSk7XG4gICAgICAgIHRoaXMuY2FjaGUgPSBjcmVhdGVWaWV3KGJ1ZiwgdHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBuZXcgVGVuc29yIGZyb20gYSBPTk5YIFRlbnNvciBvYmplY3RcbiAgICogQHBhcmFtIHRlbnNvclByb3RvIHRoZSBPTk5YIFRlbnNvclxuICAgKi9cbiAgc3RhdGljIGZyb21Qcm90byh0ZW5zb3JQcm90bzogb25ueC5JVGVuc29yUHJvdG8pOiBUZW5zb3Ige1xuICAgIGlmICghdGVuc29yUHJvdG8pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGNvbnN0cnVjdCBWYWx1ZSBmcm9tIGFuIGVtcHR5IHRlbnNvcicpO1xuICAgIH1cbiAgICBjb25zdCB0eXBlID0gUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKHRlbnNvclByb3RvLmRhdGFUeXBlISk7XG4gICAgY29uc3QgZGltcyA9IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbVByb3RvKHRlbnNvclByb3RvLmRpbXMhKTtcblxuICAgIGNvbnN0IHZhbHVlID0gbmV3IFRlbnNvcihkaW1zLCB0eXBlKTtcblxuICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gV2hlbiBpdCdzIFNUUklORyB0eXBlLCB0aGUgdmFsdWUgc2hvdWxkIGFsd2F5cyBiZSBzdG9yZWQgaW4gZmllbGRcbiAgICAgIC8vICdzdHJpbmdEYXRhJ1xuICAgICAgdGVuc29yUHJvdG8uc3RyaW5nRGF0YSEuZm9yRWFjaCgoc3RyLCBpKSA9PiB7XG4gICAgICAgIHZhbHVlLmRhdGFbaV0gPSBkZWNvZGVVdGY4U3RyaW5nKHN0cik7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdGVuc29yUHJvdG8ucmF3RGF0YSAmJlxuICAgICAgdHlwZW9mIHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZUxlbmd0aCA9PT0gJ251bWJlcicgJiZcbiAgICAgIHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZUxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIC8vIE5PVCBjb25zaWRlcmluZyBzZWdtZW50IGZvciBub3cgKElNUE9SVEFOVClcblxuICAgICAgLy8gcG9wdWxhdGUgdmFsdWUgZnJvbSByYXdEYXRhXG4gICAgICBjb25zdCBkYXRhRGVzdCA9IHZhbHVlLmRhdGE7XG4gICAgICBjb25zdCBkYXRhU291cmNlID0gbmV3IERhdGFWaWV3KFxuICAgICAgICB0ZW5zb3JQcm90by5yYXdEYXRhLmJ1ZmZlcixcbiAgICAgICAgdGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlT2Zmc2V0LFxuICAgICAgICB0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVMZW5ndGgsXG4gICAgICApO1xuICAgICAgY29uc3QgZWxlbWVudFNpemUgPSBzaXplb2ZQcm90byh0ZW5zb3JQcm90by5kYXRhVHlwZSEpO1xuICAgICAgY29uc3QgbGVuZ3RoID0gdGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlTGVuZ3RoIC8gZWxlbWVudFNpemU7XG5cbiAgICAgIGlmICh0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVMZW5ndGggJSBlbGVtZW50U2l6ZSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYnVmZmVyIGxlbmd0aCcpO1xuICAgICAgfVxuICAgICAgaWYgKGRhdGFEZXN0Lmxlbmd0aCAhPT0gbGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYnVmZmVyIGxlbmd0aCBtaXNtYXRjaCcpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG4gPSByZWFkUHJvdG8oZGF0YVNvdXJjZSwgdGVuc29yUHJvdG8uZGF0YVR5cGUhLCBpICogZWxlbWVudFNpemUpO1xuICAgICAgICBkYXRhRGVzdFtpXSA9IG47XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHBvcHVsYXRlIHZhbHVlIGZyb20gYXJyYXlcbiAgICAgIGxldCBhcnJheTogQXJyYXk8bnVtYmVyIHwgTG9uZz47XG4gICAgICBzd2l0Y2ggKHRlbnNvclByb3RvLmRhdGFUeXBlKSB7XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDpcbiAgICAgICAgICBhcnJheSA9IHRlbnNvclByb3RvLmZsb2F0RGF0YSE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDE2OlxuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDE2OlxuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UODpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ4OlxuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuQk9PTDpcbiAgICAgICAgICBhcnJheSA9IHRlbnNvclByb3RvLmludDMyRGF0YSE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ2NDpcbiAgICAgICAgICBhcnJheSA9IHRlbnNvclByb3RvLmludDY0RGF0YSE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by5kb3VibGVEYXRhITtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMjpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDpcbiAgICAgICAgICBhcnJheSA9IHRlbnNvclByb3RvLnVpbnQ2NERhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBydW4gaGVyZVxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndW5zcGVjaWZpYyBlcnJvcicpO1xuICAgICAgfVxuXG4gICAgICBpZiAoYXJyYXkgPT09IG51bGwgfHwgYXJyYXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZhaWxlZCB0byBwb3B1bGF0ZSBkYXRhIGZyb20gYSB0ZW5zb3Jwcm90byB2YWx1ZScpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkYXRhID0gdmFsdWUuZGF0YTtcbiAgICAgIGlmIChkYXRhLmxlbmd0aCAhPT0gYXJyYXkubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYXJyYXkgbGVuZ3RoIG1pc21hdGNoJyk7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGFycmF5W2ldO1xuICAgICAgICBpZiAoTG9uZy5pc0xvbmcoZWxlbWVudCkpIHtcbiAgICAgICAgICBkYXRhW2ldID0gbG9uZ1RvTnVtYmVyKGVsZW1lbnQsIHRlbnNvclByb3RvLmRhdGFUeXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkYXRhW2ldID0gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgbmV3IFRlbnNvciBmcm9tIHJhdyBkYXRhXG4gICAqIEBwYXJhbSBkYXRhIHRoZSByYXcgZGF0YSBvYmplY3QuIFNob3VsZCBiZSBhIHN0cmluZyBhcnJheSBmb3IgJ3N0cmluZycgdGVuc29yLCBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgdHlwZWQgYXJyYXlcbiAgICogZm9yIG90aGVyIHR5cGVzIG9mIHRlbnNvci5cbiAgICogQHBhcmFtIGRpbXMgdGhlIGRpbWVuc2lvbnMgb2YgdGhlIHRlbnNvclxuICAgKiBAcGFyYW0gdHlwZSB0aGUgdHlwZSBvZiB0aGUgdGVuc29yXG4gICAqL1xuICBzdGF0aWMgZnJvbURhdGEoZGF0YTogVGVuc29yLkRhdGFUeXBlTWFwW1RlbnNvci5EYXRhVHlwZV0sIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCB0eXBlOiBUZW5zb3IuRGF0YVR5cGUpIHtcbiAgICByZXR1cm4gbmV3IFRlbnNvcihkaW1zLCB0eXBlLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgZGF0YSk7XG4gIH1cblxuICBzdGF0aWMgZnJvbU9ydFRlbnNvcihvcnRUZW5zb3I6IG9ydEZicy5UZW5zb3IpIHtcbiAgICBpZiAoIW9ydFRlbnNvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3QgY29uc3RydWN0IFZhbHVlIGZyb20gYW4gZW1wdHkgdGVuc29yJyk7XG4gICAgfVxuICAgIGNvbnN0IGRpbXMgPSBQcm90b1V0aWwudGVuc29yRGltc0Zyb21PUlRGb3JtYXQob3J0VGVuc29yKTtcbiAgICBjb25zdCB0eXBlID0gUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKG9ydFRlbnNvci5kYXRhVHlwZSgpKTtcblxuICAgIGNvbnN0IHZhbHVlID0gbmV3IFRlbnNvcihkaW1zLCB0eXBlKTtcblxuICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gV2hlbiBpdCdzIFNUUklORyB0eXBlLCB0aGUgdmFsdWUgc2hvdWxkIGFsd2F5cyBiZSBzdG9yZWQgaW4gZmllbGRcbiAgICAgIC8vICdzdHJpbmdEYXRhJ1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcnRUZW5zb3Iuc3RyaW5nRGF0YUxlbmd0aCgpOyBpKyspIHtcbiAgICAgICAgdmFsdWUuZGF0YVtpXSA9IG9ydFRlbnNvci5zdHJpbmdEYXRhKGkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXG4gICAgICBvcnRUZW5zb3IucmF3RGF0YUFycmF5KCkgJiZcbiAgICAgIHR5cGVvZiBvcnRUZW5zb3IucmF3RGF0YUxlbmd0aCgpID09PSAnbnVtYmVyJyAmJlxuICAgICAgb3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSA+IDBcbiAgICApIHtcbiAgICAgIC8vIE5PVCBjb25zaWRlcmluZyBzZWdtZW50IGZvciBub3cgKElNUE9SVEFOVClcblxuICAgICAgLy8gcG9wdWxhdGUgdmFsdWUgZnJvbSByYXdEYXRhXG4gICAgICBjb25zdCBkYXRhRGVzdCA9IHZhbHVlLmRhdGE7XG4gICAgICBjb25zdCBkYXRhU291cmNlID0gbmV3IERhdGFWaWV3KFxuICAgICAgICBvcnRUZW5zb3IucmF3RGF0YUFycmF5KCkhLmJ1ZmZlcixcbiAgICAgICAgb3J0VGVuc29yLnJhd0RhdGFBcnJheSgpIS5ieXRlT2Zmc2V0LFxuICAgICAgICBvcnRUZW5zb3IucmF3RGF0YUxlbmd0aCgpLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGVsZW1lbnRTaXplID0gc2l6ZW9mUHJvdG8ob3J0VGVuc29yLmRhdGFUeXBlKCkpO1xuICAgICAgY29uc3QgbGVuZ3RoID0gb3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSAvIGVsZW1lbnRTaXplO1xuXG4gICAgICBpZiAob3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSAlIGVsZW1lbnRTaXplICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBidWZmZXIgbGVuZ3RoJyk7XG4gICAgICB9XG4gICAgICBpZiAoZGF0YURlc3QubGVuZ3RoICE9PSBsZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdidWZmZXIgbGVuZ3RoIG1pc21hdGNoJyk7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgbiA9IHJlYWRQcm90byhkYXRhU291cmNlLCBvcnRUZW5zb3IuZGF0YVR5cGUoKSwgaSAqIGVsZW1lbnRTaXplKTtcbiAgICAgICAgZGF0YURlc3RbaV0gPSBuO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2l6ZW9mKHR5cGU6IFRlbnNvci5EYXRhVHlwZSk6IG51bWJlciB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ2Jvb2wnOlxuICAgIGNhc2UgJ2ludDgnOlxuICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgIHJldHVybiAxO1xuICAgIGNhc2UgJ2ludDE2JzpcbiAgICBjYXNlICd1aW50MTYnOlxuICAgICAgcmV0dXJuIDI7XG4gICAgY2FzZSAnaW50MzInOlxuICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICByZXR1cm4gNDtcbiAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgIHJldHVybiA4O1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCBjYWxjdWxhdGUgc2l6ZW9mKCkgb24gdHlwZSAke3R5cGV9YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2l6ZW9mUHJvdG8odHlwZTogb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZSB8IG9ydEZicy5UZW5zb3JEYXRhVHlwZSk6IG51bWJlciB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UODpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuQk9PTDpcbiAgICAgIHJldHVybiAxO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMTY6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDE2OlxuICAgICAgcmV0dXJuIDI7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkZMT0FUOlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyOlxuICAgICAgcmV0dXJuIDQ7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0OlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDpcbiAgICAgIHJldHVybiA4O1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCBjYWxjdWxhdGUgc2l6ZW9mKCkgb24gdHlwZSAke29ubnguVGVuc29yUHJvdG8uRGF0YVR5cGVbdHlwZV19YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlVmlldyhkYXRhQnVmZmVyOiBBcnJheUJ1ZmZlciwgdHlwZTogVGVuc29yLkRhdGFUeXBlKSB7XG4gIHJldHVybiBuZXcgKGRhdGF2aWV3Q29uc3RydWN0b3IodHlwZSkpKGRhdGFCdWZmZXIpO1xufVxuXG5mdW5jdGlvbiBkYXRhdmlld0NvbnN0cnVjdG9yKHR5cGU6IFRlbnNvci5EYXRhVHlwZSkge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdib29sJzpcbiAgICBjYXNlICd1aW50OCc6XG4gICAgICByZXR1cm4gVWludDhBcnJheTtcbiAgICBjYXNlICdpbnQ4JzpcbiAgICAgIHJldHVybiBJbnQ4QXJyYXk7XG4gICAgY2FzZSAnaW50MTYnOlxuICAgICAgcmV0dXJuIEludDE2QXJyYXk7XG4gICAgY2FzZSAndWludDE2JzpcbiAgICAgIHJldHVybiBVaW50MTZBcnJheTtcbiAgICBjYXNlICdpbnQzMic6XG4gICAgICByZXR1cm4gSW50MzJBcnJheTtcbiAgICBjYXNlICd1aW50MzInOlxuICAgICAgcmV0dXJuIFVpbnQzMkFycmF5O1xuICAgIGNhc2UgJ2ludDY0JzpcbiAgICAgIHJldHVybiBCaWdJbnQ2NEFycmF5O1xuICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgcmV0dXJuIEZsb2F0MzJBcnJheTtcbiAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgIHJldHVybiBGbG9hdDY0QXJyYXk7XG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIHNob3VsZCBuZXZlciBydW4gdG8gaGVyZVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bnNwZWNpZmllZCBlcnJvcicpO1xuICB9XG59XG5cbi8vIGNvbnZlcnQgYSBsb25nIG51bWJlciB0byBhIDMyLWJpdCBpbnRlZ2VyIChjYXN0LWRvd24pXG5mdW5jdGlvbiBsb25nVG9OdW1iZXIoaTogTG9uZywgdHlwZTogb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZSB8IG9ydEZicy5UZW5zb3JEYXRhVHlwZSk6IG51bWJlciB7XG4gIC8vIElOVDY0LCBVSU5UMzIsIFVJTlQ2NFxuICBpZiAodHlwZSA9PT0gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ2NCB8fCB0eXBlID09PSBvcnRGYnMuVGVuc29yRGF0YVR5cGUuSU5UNjQpIHtcbiAgICBpZiAoaS5ncmVhdGVyVGhhbk9yRXF1YWwoMjE0NzQ4MzY0OCkgfHwgaS5sZXNzVGhhbigtMjE0NzQ4MzY0OCkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludDY0IGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoXG4gICAgdHlwZSA9PT0gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzIgfHxcbiAgICB0eXBlID09PSBvcnRGYnMuVGVuc29yRGF0YVR5cGUuVUlOVDMyIHx8XG4gICAgdHlwZSA9PT0gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQgfHxcbiAgICB0eXBlID09PSBvcnRGYnMuVGVuc29yRGF0YVR5cGUuVUlOVDY0XG4gICkge1xuICAgIGlmIChpLmdyZWF0ZXJUaGFuT3JFcXVhbCg0Mjk0OTY3Mjk2KSB8fCBpLmxlc3NUaGFuKDApKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd1aW50NjQgaXMgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBub3QgYSBMT05HIHR5cGU6ICR7b25ueC5UZW5zb3JQcm90by5EYXRhVHlwZVt0eXBlXX1gKTtcbiAgfVxuXG4gIHJldHVybiBpLnRvTnVtYmVyKCk7XG59XG5cbi8vIHJlYWQgb25lIHZhbHVlIGZyb20gVGVuc29yUHJvdG9cbmZ1bmN0aW9uIHJlYWRQcm90byhcbiAgdmlldzogRGF0YVZpZXcsXG4gIHR5cGU6IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUgfCBvcnRGYnMuVGVuc29yRGF0YVR5cGUsXG4gIGJ5dGVPZmZzZXQ6IG51bWJlcixcbik6IG51bWJlciB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5CT09MOlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODpcbiAgICAgIHJldHVybiB2aWV3LmdldFVpbnQ4KGJ5dGVPZmZzZXQpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ4OlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0SW50OChieXRlT2Zmc2V0KTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDE2OlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0VWludDE2KGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjpcbiAgICAgIHJldHVybiB2aWV3LmdldEludDE2KGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDpcbiAgICAgIHJldHVybiB2aWV3LmdldEZsb2F0MzIoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDMyOlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0SW50MzIoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMjpcbiAgICAgIHJldHVybiB2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQ6XG4gICAgICByZXR1cm4gbG9uZ1RvTnVtYmVyKFxuICAgICAgICBMb25nLmZyb21CaXRzKHZpZXcuZ2V0VWludDMyKGJ5dGVPZmZzZXQsIHRydWUpLCB2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0ICsgNCwgdHJ1ZSksIGZhbHNlKSxcbiAgICAgICAgdHlwZSxcbiAgICAgICk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkRPVUJMRTpcbiAgICAgIHJldHVybiB2aWV3LmdldEZsb2F0NjQoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDpcbiAgICAgIHJldHVybiBsb25nVG9OdW1iZXIoXG4gICAgICAgIExvbmcuZnJvbUJpdHModmlldy5nZXRVaW50MzIoYnl0ZU9mZnNldCwgdHJ1ZSksIHZpZXcuZ2V0VWludDMyKGJ5dGVPZmZzZXQgKyA0LCB0cnVlKSwgdHJ1ZSksXG4gICAgICAgIHR5cGUsXG4gICAgICApO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCByZWFkIGZyb20gRGF0YVZpZXcgZm9yIHR5cGUgJHtvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlW3R5cGVdfWApO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8qKlxuICogcmVwcmVzZW50IGEgdmVyc2lvbiBpcnJlbGV2YW50IGFic3RyYWN0aW9uIG9mIGZvciBHTFNMIHNvdXJjZSBjb2RlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR2xzbCB7XG4gIHJlYWRvbmx5IHZlcnNpb246IHN0cmluZztcbiAgcmVhZG9ubHkgYXR0cmlidXRlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZhcnlpbmdWZXJ0ZXg6IHN0cmluZztcbiAgcmVhZG9ubHkgdmFyeWluZ0ZyYWc6IHN0cmluZztcbiAgcmVhZG9ubHkgdGV4dHVyZTJEOiBzdHJpbmc7XG4gIHJlYWRvbmx5IG91dHB1dDogc3RyaW5nO1xuICByZWFkb25seSBvdXRwdXREZWNsYXJhdGlvbjogc3RyaW5nO1xufVxuXG5jb25zdCBHTFNMX0VTXzJfMDogR2xzbCA9IHtcbiAgdmVyc2lvbjogJycsXG4gIGF0dHJpYnV0ZTogJ2F0dHJpYnV0ZScsXG4gIHZhcnlpbmdWZXJ0ZXg6ICd2YXJ5aW5nJyxcbiAgdmFyeWluZ0ZyYWc6ICd2YXJ5aW5nJyxcbiAgdGV4dHVyZTJEOiAndGV4dHVyZTJEJyxcbiAgb3V0cHV0OiAnZ2xfRnJhZ0NvbG9yJyxcbiAgb3V0cHV0RGVjbGFyYXRpb246ICcnLFxufTtcbmNvbnN0IEdMU0xfRVNfM18wOiBHbHNsID0ge1xuICB2ZXJzaW9uOiAnI3ZlcnNpb24gMzAwIGVzJyxcbiAgYXR0cmlidXRlOiAnaW4nLFxuICB2YXJ5aW5nVmVydGV4OiAnb3V0JyxcbiAgdmFyeWluZ0ZyYWc6ICdpbicsXG4gIHRleHR1cmUyRDogJ3RleHR1cmUnLFxuICBvdXRwdXQ6ICdvdXRwdXRDb2xvcicsXG4gIG91dHB1dERlY2xhcmF0aW9uOiAnb3V0IHZlYzQgb3V0cHV0Q29sb3I7Jyxcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRHbHNsKHZlcnNpb246IDEgfCAyKSB7XG4gIHJldHVybiB2ZXJzaW9uID09PSAxID8gR0xTTF9FU18yXzAgOiBHTFNMX0VTXzNfMDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZlcnRleFNoYWRlclNvdXJjZSh2ZXJzaW9uOiAxIHwgMik6IHN0cmluZyB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHZlcnNpb24pO1xuICByZXR1cm4gYCR7Z2xzbC52ZXJzaW9ufVxuICAgICAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0O1xuICAgICAgJHtnbHNsLmF0dHJpYnV0ZX0gdmVjMyBwb3NpdGlvbjtcbiAgICAgICR7Z2xzbC5hdHRyaWJ1dGV9IHZlYzIgdGV4dHVyZUNvb3JkO1xuXG4gICAgICAke2dsc2wudmFyeWluZ1ZlcnRleH0gdmVjMiBUZXhDb29yZHM7XG5cbiAgICAgIHZvaWQgbWFpbigpXG4gICAgICB7XG4gICAgICAgICAgZ2xfUG9zaXRpb24gPSB2ZWM0KHBvc2l0aW9uLCAxLjApO1xuICAgICAgICAgIFRleENvb3JkcyA9IHRleHR1cmVDb29yZDtcbiAgICAgIH1gO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnJhZ1NoYWRlclByZWFtYmxlKHZlcnNpb246IDEgfCAyKTogc3RyaW5nIHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2wodmVyc2lvbik7XG4gIHJldHVybiBgJHtnbHNsLnZlcnNpb259XG4gICAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0O1xuICAgIHByZWNpc2lvbiBoaWdocCBpbnQ7XG4gICAgcHJlY2lzaW9uIGhpZ2hwIHNhbXBsZXIyRDtcbiAgICAke2dsc2wudmFyeWluZ0ZyYWd9IHZlYzIgVGV4Q29vcmRzO1xuICAgICR7Z2xzbC5vdXRwdXREZWNsYXJhdGlvbn1cbiAgICBjb25zdCB2ZWMyIGhhbGZDUiA9IHZlYzIoMC41LCAwLjUpO1xuXG4gICAgLy8gQ3VzdG9tIHZlY3RvciB0eXBlcyB0byBoYW5kbGUgaGlnaGVyIGRpbWVuYWxpdGllcy5cbiAgICBzdHJ1Y3QgaXZlYzVcbiAgICB7XG4gICAgICBpbnQgeDtcbiAgICAgIGludCB5O1xuICAgICAgaW50IHo7XG4gICAgICBpbnQgdztcbiAgICAgIGludCB1O1xuICAgIH07XG5cbiAgICBzdHJ1Y3QgaXZlYzZcbiAgICB7XG4gICAgICBpbnQgeDtcbiAgICAgIGludCB5O1xuICAgICAgaW50IHo7XG4gICAgICBpbnQgdztcbiAgICAgIGludCB1O1xuICAgICAgaW50IHY7XG4gICAgfTtcblxuICAgIGludCBpbW9kKGludCB4LCBpbnQgeSkge1xuICAgICAgcmV0dXJuIHggLSB5ICogKHggLyB5KTtcbiAgICB9XG5cbiAgICBgO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVmYXVsdEZyYWdTaGFkZXJNYWluKHZlcnNpb246IDEgfCAyLCBvdXRwdXRTaGFwZUxlbmd0aDogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2wodmVyc2lvbik7XG4gIHJldHVybiBgXG4gIHZvaWQgbWFpbigpIHtcbiAgICBpbnQgaW5kaWNlc1ske291dHB1dFNoYXBlTGVuZ3RofV07XG4gICAgdG9WZWMoVGV4Q29vcmRzLCBpbmRpY2VzKTtcbiAgICB2ZWM0IHJlc3VsdCA9IHZlYzQocHJvY2VzcyhpbmRpY2VzKSk7XG4gICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gIH1cbiAgYDtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vdGVuc29yJztcblxuLyoqXG4gKiBMYXlvdXQgaW5mbyBpcyB1c2VkIGZvciBtYXBwaW5nIG4tZGltZW5zaW9uYWwgYXJyYXkgdG8gMkQgdGV4dHVyZXNcbiAqIFRoZSBsYXlvdXQgaXMgY3JlYXRlZCBieSB0aGUgVGV4dHVyZUxheW91dFN0cmF0ZWd5IGJhc2VkIG9uXG4gKiB0aGUgVGVuc29yJ3MgZGltZW5zaW9ucyBhbmQgc3RyaWRlc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFRleHR1cmVMYXlvdXQge1xuICB3aWR0aDogbnVtYmVyO1xuICBoZWlnaHQ6IG51bWJlcjtcbiAgLyoqXG4gICAqIHNwZWNpZnkgdGhlIG51bWJlciBvZiB2YWx1ZSB0aGF0IGVuY29kZWQgaW4gYSBzaW5nbGUgcGl4ZWxcbiAgICovXG4gIGNoYW5uZWxzOiAxIHwgMiB8IDMgfCA0O1xuICAvKipcbiAgICogd2hldGhlciBpbiBwYWNrZWQgbW9kZSBvciBub3RcbiAgICovXG4gIGlzUGFja2VkPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIHRoZSBub3JtYWxpemVkIHNoYXBlXG4gICAqL1xuICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG4gIC8qKlxuICAgKiB0aGUgc3RyaWRlIG9mIGVhY2ggZGltZW5zaW9ucywgY2FsY3VsYXRlZCBhY2NvcmRpbmcgdG8gc2hhcGVcbiAgICovXG4gIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICAvKipcbiAgICogdGhlIG9yaWdpbmFsIHNoYXBlKGRpbXMpIG9mIHRoZSBjb3JyZXNwb25kaW5nIHRlbnNvclxuICAgKi9cbiAgdW5wYWNrZWRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgcmV2ZXJzZWRXSD86IGJvb2xlYW47XG59XG5leHBvcnQgaW50ZXJmYWNlIFRleHR1cmVEYXRhIGV4dGVuZHMgVGV4dHVyZUxheW91dCB7XG4gIHRlbnNvcjogVGVuc29yO1xuICB0ZXh0dXJlOiBXZWJHTFRleHR1cmU7XG59XG5cbmV4cG9ydCBlbnVtIFRleHR1cmVUeXBlIHtcbiAgdW5wYWNrZWQsIC8vIDwtLSBub3JtYWwgdW5wYWNrZWQgdGV4dHVyZVxuICB1bnBhY2tlZFJldmVyc2VkLCAvLyA8LS0gdW5wYWNrZWQgdGV4dHVyZSB1c2VkIGluIG9sZCBPTk5YLmpzIGltcGxlbWVudGF0aW9uIChkZXByZWNhdGVkKVxuICBwYWNrZWQsIC8vIDwtLSBub3JtYWwgcGFja2VkIHRleHR1cmVcbiAgZG93bmxvYWRVaW50OEFzRmxvYXQsIC8vIDwtLSBPTkxZIHVzZWQgaW4gdGV4dHVyZSBkb3dubG9hZGluZyBmb3IgaU9TIGRldmljZXNcbiAgcGFja2VkTGFzdERpbWVuc2lvbiwgLy8gPC0tIE9OTFkgdXNlZCBpbiBvbGQgT05OWC5qcyBDb252IGltcGxlbWVudGF0aW9uIGZvciBpbnB1dCBXIChkZXByZWNhdGVkKVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckluZm8ge1xuICBpZD86IFRlbnNvci5JZDtcbiAgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHR5cGU6IFRlbnNvci5EYXRhVHlwZTtcbiAgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFByb2dyYW1WYXJpYWJsZSB7XG4gIHR5cGU6ICdmbG9hdCcgfCAnaW50JztcbiAgbmFtZTogc3RyaW5nO1xuICBhcnJheUxlbmd0aD86IG51bWJlcjtcbiAgZGF0YTogbnVtYmVyIHwgbnVtYmVyW107XG59XG5cbi8qKlxuICogQSBzZXQgb2YgbWV0YWRhdGEgb2YgYSBzaGFkZXIgcHJvZ3JhbS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtTWV0YWRhdGEge1xuICAvKipcbiAgICogdGhlIG5hbWUgb2YgdGhlIHByb2dyYW0uIHVzZWQgZm9yIGRlYnVnZ2luZyBhbmQgcHJvZmlsaW5nXG4gICAqL1xuICBuYW1lOiBzdHJpbmc7XG4gIC8qKlxuICAgKiB0ZXh0dXJlIHR5cGVzIGZvciBlYWNoIGlucHV0XG4gICAqL1xuICBpbnB1dFR5cGVzOiBUZXh0dXJlVHlwZVtdO1xuICAvKipcbiAgICogbmFtZXMgb2YgZWFjaCBpbnB1dFxuICAgKi9cbiAgaW5wdXROYW1lczogc3RyaW5nW107XG4gIC8qKlxuICAgKiBhbiBvcHRpb25hbCBzdHJpbmcgYXMgYSBjYWNoZSBoaW50IGluIHRoZSBhcnRpZmFjdCBjYWNoZVxuICAgKi9cbiAgY2FjaGVIaW50Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgUHJvZ3JhbUluZm9Mb2FkZXIgYWxsb3dzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbUluZm9Mb2FkZXIgZXh0ZW5kcyBQcm9ncmFtTWV0YWRhdGEge1xuICAvKipcbiAgICogYSBmdW5jdGlvbiB0byBnZXQgdGhlIHByb2dyYW0gaW5mb1xuICAgKi9cbiAgZ2V0KCk6IFByb2dyYW1JbmZvO1xufVxuXG4vKipcbiAqIEEgc2V0IG9mIGRhdGEgdGhhdCByZXByZXNlbnQgYSBzaGFkZXIgcHJvZ3JhbVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb2dyYW1JbmZvIGV4dGVuZHMgUHJvZ3JhbU1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIGluZm9ybWF0aW9uIG9mIHVuaWZvcm0gdmFyaWFibGVzXG4gICAqL1xuICB2YXJpYWJsZXM/OiBQcm9ncmFtVmFyaWFibGVbXTtcbiAgLyoqXG4gICAqIHRlbnNvciBpbmZvIGZvciBvdXRwdXRcbiAgICovXG4gIG91dHB1dDogVGVuc29ySW5mbztcbiAgLyoqXG4gICAqIHRoZSBzaGFkZXIncyBwcm9jZXNzaW5nIHNvdXJjZSBjb2RlXG4gICAqL1xuICBzaGFkZXJTb3VyY2U6IHN0cmluZztcbiAgLyoqXG4gICAqIHdoZXRoZXIgdGhlIHNoYWRlciBzb3VyY2UgY29udGFpbnMgYSBjdXN0b21pemVkIG1haW4gZnVuY3Rpb24gaW1wbGVtZW50YXRpb25cbiAgICovXG4gIGhhc01haW4/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZhcmlhYmxlSW5mbyB7XG4gIHR5cGU6ICdmbG9hdCcgfCAnaW50JztcbiAgbmFtZTogc3RyaW5nO1xuICBhcnJheUxlbmd0aD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtVmFyaWFibGUge1xuICB0eXBlOiAnZmxvYXQnIHwgJ2ludCc7XG4gIG5hbWU6IHN0cmluZztcbiAgYXJyYXlMZW5ndGg/OiBudW1iZXI7XG4gIGRhdGE6IG51bWJlciB8IG51bWJlcltdO1xufVxuXG4vKipcbiAqIEluZm9ybWF0aW9uIG9mIHVuaWZvcm1zIHRoYXQgc2hhZGVyIHVzZXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVbmlmb3JtSW5mbyB7XG4gIHR5cGU6ICdzYW1wbGVyMkQnIHwgVmFyaWFibGVJbmZvWyd0eXBlJ107XG4gIG5hbWU6IHN0cmluZztcbiAgYXJyYXlMZW5ndGg/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVW5pZm9ybUxvY2F0aW9uIGV4dGVuZHMgVW5pZm9ybUluZm8ge1xuICBsb2NhdGlvbjogV2ViR0xVbmlmb3JtTG9jYXRpb247XG59XG5cbi8qKlxuICogQXJ0aWZhY3QgaXMgdGhlIHJlc3VsdCBvZiBjb21waWxhdGlvblxuICogSXQgZG9lcyBub3QgY29udGFpbiBpbnB1dCBvZiBvdXRwdXQgZGF0YVxuICogSG93ZXZlciBhbnl0aGluZyB0aGF0IGNvdWxkIGJlIHJ1biBhcyBhIFwicHJvZ3JhbVwiXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXJ0aWZhY3Qge1xuICBwcm9ncmFtSW5mbzogUHJvZ3JhbUluZm87XG4gIHByb2dyYW06IFdlYkdMUHJvZ3JhbTtcbiAgdW5pZm9ybUxvY2F0aW9uczogVW5pZm9ybUxvY2F0aW9uW107XG4gIGF0dHJpYkxvY2F0aW9uczogeyBwb3NpdGlvbjogbnVtYmVyOyB0ZXh0dXJlQ29vcmQ6IG51bWJlciB9O1xufVxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIEFydGlmYWN0IHtcbiAgdHlwZSBVbmlmb3JtTG9jYXRpb25zID0gQXJ0aWZhY3RbJ3VuaWZvcm1Mb2NhdGlvbnMnXTtcbiAgdHlwZSBBdHRyaWJMb2NhdGlvbnMgPSBBcnRpZmFjdFsnYXR0cmliTG9jYXRpb25zJ107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVW5pZm9ybURhdGEge1xuICBbbmFtZTogc3RyaW5nXTogbnVtYmVyIHwgbnVtYmVyW107XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuLyoqXG4gKiBHaXZlbiBhIG5vbiBSR0JBIHNoYXBlIGNhbGN1bGF0ZSB0aGUgUiB2ZXJzaW9uXG4gKiBJdCBpcyBhc3N1bWVkIHRoYXQgdGhlIGRpbWVuc2lvbnMgYXJlIG11bHRpcGxlcyBvZiBnaXZlbiBjaGFubmVsc1xuICogTk9URTogaXQgaXMgYWx3YXlzIHRoZSBsYXN0IGRpbSB0aGF0IGdldHMgcGFja2VkLlxuICogQHBhcmFtIHVucGFja2VkU2hhcGUgb3JpZ2luYWwgc2hhcGUgdG8gY3JlYXRlIGEgcGFja2VkIHZlcnNpb24gZnJvbVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGFja2VkU2hhcGUodW5wYWNrZWRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gIGNvbnN0IGxlbiA9IHVucGFja2VkU2hhcGUubGVuZ3RoO1xuICByZXR1cm4gdW5wYWNrZWRTaGFwZS5zbGljZSgwLCBsZW4gLSAxKS5jb25jYXQodW5wYWNrZWRTaGFwZVtsZW4gLSAxXSAvIDQpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVwZWF0ZWRUcnkoXG4gIGNoZWNrRm46ICgpID0+IGJvb2xlYW4sXG4gIGRlbGF5Rm4gPSAoX2NvdW50ZXI6IG51bWJlcikgPT4gMCxcbiAgbWF4Q291bnRlcj86IG51bWJlcixcbik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGxldCB0cnlDb3VudCA9IDA7XG5cbiAgICBjb25zdCB0cnlGbiA9ICgpID0+IHtcbiAgICAgIGlmIChjaGVja0ZuKCkpIHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRyeUNvdW50Kys7XG5cbiAgICAgIGNvbnN0IG5leHRCYWNrb2ZmID0gZGVsYXlGbih0cnlDb3VudCk7XG5cbiAgICAgIGlmIChtYXhDb3VudGVyICE9IG51bGwgJiYgdHJ5Q291bnQgPj0gbWF4Q291bnRlcikge1xuICAgICAgICByZWplY3QoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2V0VGltZW91dCh0cnlGbiwgbmV4dEJhY2tvZmYpO1xuICAgIH07XG5cbiAgICB0cnlGbigpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgdGhlIGZ1bmN0aW9uIG5hbWUgZnJvbSBhbiBpbnB1dCBzYW1wbGVyIG5hbWUuXG4gKiBAcGFyYW0gc2FtcGxlck5hbWUgTmFtZSBvZiB0aGUgc2FtcGxlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZShzYW1wbGVyTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0KHR5cGVvZiBzYW1wbGVyTmFtZSAhPT0gJ3VuZGVmaW5lZCcgJiYgc2FtcGxlck5hbWUubGVuZ3RoICE9PSAwLCAoKSA9PiAnZW1wdHkgc3RyaW5nIGZvdW5kIGZvciBzYW1wbGVyIG5hbWUnKTtcbiAgcmV0dXJuICdnZXQnICsgc2FtcGxlck5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzYW1wbGVyTmFtZS5zbGljZSgxKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgdGhlIGZ1bmN0aW9uIG5hbWUgZnJvbSBhbiBpbnB1dCBzYW1wbGVyIG5hbWUgYXQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHNhbXBsZXJOYW1lIE5hbWUgb2YgdGhlIHNhbXBsZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWVBdE91dENvb3JkcyhzYW1wbGVyTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0KHR5cGVvZiBzYW1wbGVyTmFtZSAhPT0gJ3VuZGVmaW5lZCcgJiYgc2FtcGxlck5hbWUubGVuZ3RoICE9PSAwLCAoKSA9PiAnZW1wdHkgc3RyaW5nIGZvdW5kIGZvciBzYW1wbGVyIG5hbWUnKTtcbiAgcmV0dXJuICdnZXQnICsgc2FtcGxlck5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzYW1wbGVyTmFtZS5zbGljZSgxKSArICdBdE91dENvb3Jkcyc7XG59XG5cbi8qKiBSZXR1cm5zIGEgbmV3IGlucHV0IHNoYXBlIChhIGNvcHkpIHRoYXQgaGFzIGEgc3F1ZWV6ZWQgbG9naWNhbCBzaGFwZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzcXVlZXplSW5wdXRTaGFwZShpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgc3F1ZWV6ZWRTaGFwZTogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gIC8vIERlZXAgY29weS5cbiAgbGV0IG5ld0lucHV0U2hhcGU6IG51bWJlcltdID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dFNoYXBlKSk7XG4gIG5ld0lucHV0U2hhcGUgPSBzcXVlZXplZFNoYXBlO1xuICByZXR1cm4gbmV3SW5wdXRTaGFwZTtcbn1cblxuLyoqIFJldHVybnMgYSBsaXN0IG9mIHNxdWVlemVkIHBhcmFtZXRlcnMgZm9yIHNoYWRlciBmdW5jdGlvbnMgKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXM6IHN0cmluZ1tdLCBrZXB0RGltczogbnVtYmVyW10pOiBzdHJpbmcge1xuICByZXR1cm4ga2VwdERpbXMubWFwKChkKSA9PiBwYXJhbXNbZF0pLmpvaW4oJywgJyk7XG59XG5cbi8qKiBSZXR1cm5zIHRoZSBkYXRhIHR5cGUgZm9yIGRpZmZlcmVudCByYW5rcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb29yZHNEYXRhVHlwZShyYW5rOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAocmFuayA8PSAxKSB7XG4gICAgcmV0dXJuICdpbnQnO1xuICB9IGVsc2UgaWYgKHJhbmsgPT09IDIpIHtcbiAgICByZXR1cm4gJ2l2ZWMyJztcbiAgfSBlbHNlIGlmIChyYW5rID09PSAzKSB7XG4gICAgcmV0dXJuICdpdmVjMyc7XG4gIH0gZWxzZSBpZiAocmFuayA9PT0gNCkge1xuICAgIHJldHVybiAnaXZlYzQnO1xuICB9IGVsc2UgaWYgKHJhbmsgPT09IDUpIHtcbiAgICByZXR1cm4gJ2l2ZWM1JztcbiAgfSBlbHNlIGlmIChyYW5rID09PSA2KSB7XG4gICAgcmV0dXJuICdpdmVjNic7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgRXJyb3IoYEdQVSBmb3IgcmFuayAke3Jhbmt9IGlzIG5vdCB5ZXQgc3VwcG9ydGVkYCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEdsQ2hhbm5lbHMocmFuayA9IDYpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBbJ3gnLCAneScsICd6JywgJ3cnLCAndScsICd2J10uc2xpY2UoMCwgcmFuayk7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGdldEdsQ2hhbm5lbHMgfSBmcm9tICcuLi91dGlscyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRWZWNDaGFubmVscyhuYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlcik6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIGdldEdsQ2hhbm5lbHMocmFuaykubWFwKChkKSA9PiBgJHtuYW1lfS4ke2R9YCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGFubmVscyhuYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlcik6IHN0cmluZ1tdIHtcbiAgaWYgKHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gW25hbWVdO1xuICB9XG4gIHJldHVybiBnZXRWZWNDaGFubmVscyhuYW1lLCByYW5rKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVucGFja0Zyb21DaGFubmVsKCk6IHN0cmluZyB7XG4gIHJldHVybiBgXG4gICAgZmxvYXQgZ2V0Q2hhbm5lbCh2ZWM0IGZyYWcsIGludCBkaW0pIHtcbiAgICAgIGludCBtb2RDb29yZCA9IGltb2QoZGltLCAyKTtcbiAgICAgIHJldHVybiBtb2RDb29yZCA9PSAwID8gZnJhZy5yIDogZnJhZy5nO1xuICAgIH1cblxuICAgIGZsb2F0IGdldENoYW5uZWwodmVjNCBmcmFnLCB2ZWMyIGlubmVyRGltcykge1xuICAgICAgdmVjMiBtb2RDb29yZCA9IG1vZChpbm5lckRpbXMsIDIuKTtcbiAgICAgIHJldHVybiBtb2RDb29yZC54ID09IDAuID9cbiAgICAgICAgKG1vZENvb3JkLnkgPT0gMC4gPyBmcmFnLnIgOiBmcmFnLmcpIDpcbiAgICAgICAgKG1vZENvb3JkLnkgPT0gMC4gPyBmcmFnLmIgOiBmcmFnLmEpO1xuICAgIH1cbiAgYDtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29vcmRzRGF0YVR5cGUgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IGdldENoYW5uZWxzIH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgcGFja1Byb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ3BhY2snLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkUmV2ZXJzZWRdLFxufTtcblxuY29uc3QgY3JlYXRlUGFja1Byb2dyYW1JbmZvID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXQuZGltcztcblxuICBjb25zdCBpbnB1dFJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgLy8gY3JlYXRlVGV4dHVyZUxheW91dEZyb21TaGFwZSB3b24ndCBjaGFuZ2Ugb3V0cHV0IHJhbmsuIE5lZWQgdG8gdmVyaWZ5IGJ5IHJ1bm5pbmcgdGVzdHNcbiAgY29uc3Qgb3V0cHV0UmFuayA9IGlucHV0LmRpbXMubGVuZ3RoO1xuXG4gIGNvbnN0IGNvb3Jkc0RhdGFUeXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0cHV0UmFuayk7XG4gIGNvbnN0IGNoYW5uZWxzID0gZ2V0Q2hhbm5lbHMoJ3JjJywgb3V0cHV0UmFuayk7XG4gIGNvbnN0IHNldHVwID0gZ2V0U2V0dXAob3V0cHV0UmFuaywgY2hhbm5lbHMsIGlucHV0U2hhcGVbaW5wdXRTaGFwZS5sZW5ndGggLSAyXSwgaW5wdXRTaGFwZVtpbnB1dFNoYXBlLmxlbmd0aCAtIDFdKTtcblxuICBsZXQgcmV2ZXJzZWRJbnB1dFdIO1xuICBpZiAoaW5wdXRSYW5rID09PSAwKSB7XG4gICAgcmV2ZXJzZWRJbnB1dFdIID0gWzEsIDFdO1xuICB9IGVsc2UgaWYgKGlucHV0UmFuayA9PT0gMSkge1xuICAgIHJldmVyc2VkSW5wdXRXSCA9IFtpbnB1dFNoYXBlWzBdLCAxXTtcbiAgfSBlbHNlIHtcbiAgICByZXZlcnNlZElucHV0V0ggPSBbaW5wdXRTaGFwZVtvdXRwdXRSYW5rIC0gMV0sIGlucHV0U2hhcGVbb3V0cHV0UmFuayAtIDJdXTtcbiAgfVxuICBjb25zdCBvdXRPZkJvdW5kc0NvbmRpdGlvbiA9IGdldE91dE9mQm91bmRzQ29uZGl0aW9uKG91dHB1dFJhbmssIHJldmVyc2VkSW5wdXRXSCwgY2hhbm5lbHMpO1xuICBjb25zdCBvdXRwdXQgPSBnZXRPdXRwdXQoaW5wdXRTaGFwZSwgY2hhbm5lbHMpO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICAgICR7Y29vcmRzRGF0YVR5cGV9IHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG5cbiAgICAgICAgICBpZigke291dE9mQm91bmRzQ29uZGl0aW9ufSkge1xuICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KDApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAke3NldHVwfVxuXG4gICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQoJHtvdXRwdXR9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4ucGFja1Byb2dyYW1NZXRhZGF0YSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dC5kaW1zLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tQcm9ncmFtSW5mb0xvYWRlciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IpOiBQcm9ncmFtSW5mb0xvYWRlciA9PiAoe1xuICAuLi5wYWNrUHJvZ3JhbU1ldGFkYXRhLFxuICBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tQcm9ncmFtSW5mbyhoYW5kbGVyLCBpbnB1dCksXG59KTtcblxuLyoqXG4gKiBjaGVjayBvdXRwdXQgY29vcmRpbmF0ZSBsb2NhdGlvbiBhbmQgcmV0dXJuIGZhbHNlIGlmIGl0IGlzIG91dHNpZGUgaW5wdXQncyB3aWR0aC9oZWlnaHQgYm91bmRhcnlcbiAqL1xuZnVuY3Rpb24gZ2V0T3V0T2ZCb3VuZHNDb25kaXRpb24ocmFuazogbnVtYmVyLCBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGRpbXM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgaWYgKHJhbmsgPT09IDApIHtcbiAgICByZXR1cm4gJ2ZhbHNlJztcbiAgfVxuICBpZiAocmFuayA9PT0gMSkge1xuICAgIHJldHVybiBgcmMgPiAke3NoYXBlWzBdfWA7XG4gIH1cblxuICBsZXQgY29uZCA9ICcnO1xuICBmb3IgKGxldCBpID0gcmFuayAtIDI7IGkgPCByYW5rOyBpKyspIHtcbiAgICBjb25kICs9IGAke2RpbXNbaV19ID49ICR7c2hhcGVbaSAtIHJhbmsgKyAyXX1gO1xuICAgIGlmIChpIDwgcmFuayAtIDEpIHtcbiAgICAgIGNvbmQgKz0gJ3x8JztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY29uZDtcbn1cblxuLyoqXG4gKiBjb2RlIHNuaXBwZXQgdG8gc2FtcGxlIGlucHV0IHRleHR1cmUgd2l0aCBvdXRwdXQgY29vcmRpbmF0ZXNcbiAqL1xuZnVuY3Rpb24gZ2V0T3V0cHV0KHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgZGltczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gIGlmIChyYW5rID09PSAwKSB7XG4gICAgcmV0dXJuICdnZXRBKCksIDAsIDAsIDAnO1xuICB9XG5cbiAgaWYgKHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gYGdldEEocmMpLFxuICAgICAgICAgICAgcmMgKyAxID49ICR7c2hhcGVbMF19ID8gMC4gOiBnZXRBKHJjICsgMSksXG4gICAgICAgICAgICAwLCAwYDtcbiAgfVxuXG4gIGNvbnN0IGNvb3JkMDAgPSAnciwgYyc7XG4gIGNvbnN0IGNvb3JkMDEgPSAnciwgY3AxJztcbiAgY29uc3QgY29vcmQxMCA9ICdycDEsIGMnO1xuICBjb25zdCBjb29yZDExID0gJ3JwMSwgY3AxJztcbiAgbGV0IEQgPSAnJztcbiAgaWYgKHJhbmsgPiAyKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMjsgKytpKSB7XG4gICAgICBEID0gRCArIGAke2RpbXNbaV19LGA7XG4gICAgfVxuICB9XG4gIHJldHVybiBgZ2V0QSgke0R9JHtjb29yZDAwfSksXG4gICAgICAgICAgckVkZ2UgPyAwLiA6IGdldEEoJHtEfSR7Y29vcmQxMH0pLFxuICAgICAgICAgIGNFZGdlID8gMC4gOiBnZXRBKCR7RH0ke2Nvb3JkMDF9KSxcbiAgICAgICAgICByRWRnZSB8fCBjRWRnZSA/IDAuIDogZ2V0QSgke0R9JHtjb29yZDExfSlgO1xufVxuXG4vKipcbiAqIGNvZGUgc25pcHBldCB0byBzZXR1cCA0IGNvb3JkaW5hdGVzIGFuZCBlZGdlIGNvbmRpdGlvbnNcbiAqL1xuZnVuY3Rpb24gZ2V0U2V0dXAocmFuazogbnVtYmVyLCBkaW1zOiBzdHJpbmdbXSwgcm93czogbnVtYmVyLCBjb2xzOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAocmFuayA9PT0gMCB8fCByYW5rID09PSAxKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIC8vIHJhbmsgPj0gMiBmb3Igd2lkdGgraGVpZ2h0IHBhY2suXG4gIGVsc2Uge1xuICAgIGNvbnN0IHNldHVwID0gYFxuICAgIGludCByID0gJHtkaW1zW3JhbmsgLSAyXX07XG4gICAgaW50IGMgPSAke2RpbXNbcmFuayAtIDFdfTtcbiAgICBpbnQgcnAxID0gJHtkaW1zW3JhbmsgLSAyXX0gKyAxO1xuICAgIGludCBjcDEgPSAke2RpbXNbcmFuayAtIDFdfSArIDE7XG4gICAgYm9vbCByRWRnZSA9IHJwMSA+PSAke2NvbHN9O1xuICAgIGJvb2wgY0VkZ2UgPSBjcDEgPj0gJHtyb3dzfTtcbiAgICBgO1xuICAgIHJldHVybiBzZXR1cDtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyB1bnBhY2tGcm9tQ2hhbm5lbCB9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1NZXRhZGF0YSA9IChvdXRwdXRTaGFwZTNEOiByZWFkb25seSBudW1iZXJbXSkgPT4gKHtcbiAgbmFtZTogJ1Jlc2hhcGUgKHBhY2tlZCknLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUucGFja2VkXSxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGNhY2hlSGludDogYCR7b3V0cHV0U2hhcGUzRH1gLFxufSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0M0Q6IFRlbnNvcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgb3V0cHV0U2hhcGUzRDogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUzRCA9IGlucHV0M0QuZGltcyBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIGNvbnN0IHNxdWVlemVkT3V0cHV0U2hhcGUgPSBvdXRwdXRTaGFwZTNEIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcblxuICBsZXQgbWFpbkxvb3AgPSAnJztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICBsZXQgb3V0cHV0Q29vcmRzID0gJyc7XG4gICAgc3dpdGNoIChpKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIG91dHB1dENvb3JkcyA9ICdvdXRwdXRDb29yZHMgPSByYzsnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgb3V0cHV0Q29vcmRzID0gJ291dHB1dENvb3JkcyA9IGl2ZWMzKHJjLngsIHJjLnkrMSwgcmMueik7JztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIG91dHB1dENvb3JkcyA9ICdvdXRwdXRDb29yZHMgPSBpdmVjMyhyYy54LCByYy55LCByYy56KzEpOyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBvdXRwdXRDb29yZHMgPSAnb3V0cHV0Q29vcmRzID0gaXZlYzMocmMueCwgcmMueSsxLCByYy56KzEpOyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgfVxuXG4gICAgbWFpbkxvb3AgKz0gYFxuICAgICAgICAke291dHB1dENvb3Jkc31cbiAgICAgICAgJHtpID4gMCA/ICdpZihvdXRwdXRDb29yZHMueSA8IHJvd3MgJiYgb3V0cHV0Q29vcmRzLnogPCBjb2xzKXsnIDogJyd9XG4gICAgICAgICAgaW50IGZsYXR0ZW5lZEluZGV4ID0gZ2V0RmxhdHRlbmVkSW5kZXgob3V0cHV0Q29vcmRzKTtcblxuICAgICAgICAgIGl2ZWMzIGlucHV0UkMgPSBpbnB1dENvb3Jkc0Zyb21SZXNoYXBlZE91dENvb3JkcyhmbGF0dGVuZWRJbmRleCk7XG4gICAgICAgICAgdmVjMiBpbm5lckRpbXMgPSB2ZWMyKGZsb2F0KGlucHV0UkMueSksZmxvYXQoaW5wdXRSQy56KSk7XG5cbiAgICAgICAgICByZXN1bHRbJHtpfV0gPSBnZXRDaGFubmVsKGdldEEoaW5wdXRSQy54LCBpbnB1dFJDLnksIGlucHV0UkMueiksIGlubmVyRGltcyk7XG5cbiAgICAgICAgJHtpID4gMCA/ICd9JyA6ICcnfVxuICAgICAgYDtcbiAgfVxuICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtnZXRSZXNoYXBlZElucHV0Q29vcmRzKGlucHV0U2hhcGUzRCl9XG4gICAgICAke2dldEZsYXR0ZW5lZEluZGV4RnJvbTNEKHNxdWVlemVkT3V0cHV0U2hhcGUpfVxuICAgICAgJHt1bnBhY2tGcm9tQ2hhbm5lbCgpfVxuXG4gICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgIGl2ZWMzIHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG5cbiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuMCk7XG5cbiAgICAgICAgaXZlYzMgb3V0cHV0Q29vcmRzO1xuICAgICAgICBpbnQgcm93cyA9ICR7c3F1ZWV6ZWRPdXRwdXRTaGFwZVsyXX07XG4gICAgICAgIGludCBjb2xzID0gJHtzcXVlZXplZE91dHB1dFNoYXBlWzFdfTtcblxuICAgICAgICAke21haW5Mb29wfVxuICAgICAgICAke2dsc2wub3V0cHV0fSA9IHJlc3VsdDtcbiAgICAgIH1cbiAgICBgO1xuXG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IHNxdWVlemVkT3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0M0QudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0M0Q6IFRlbnNvcixcbiAgb3V0cHV0U2hhcGUzRDogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbU1ldGFkYXRhKG91dHB1dFNoYXBlM0QpO1xuICByZXR1cm4geyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtSW5mbyhoYW5kbGVyLCBpbnB1dDNELCBtZXRhZGF0YSwgb3V0cHV0U2hhcGUzRCkgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwcm9jZXNzRGltczNEKHNoYXBlOiBBcnJheUxpa2U8bnVtYmVyPik6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gIGlmIChzaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gWzEsIDEsIDFdO1xuICB9XG4gIC8vIFRPRE86IHNxdWVlemUgb3RoZXIgc2hhcGVzIHRvIDJEIGNhc2VcbiAgbGV0IGJhdGNoID0gMTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaGFwZS5sZW5ndGggLSAyOyArK2kpIHtcbiAgICBiYXRjaCAqPSBzaGFwZVtpXTtcbiAgfVxuICByZXR1cm4gW2JhdGNoLCBzaGFwZS5sZW5ndGggPiAxID8gc2hhcGVbc2hhcGUubGVuZ3RoIC0gMl0gOiAxLCBzaGFwZVtzaGFwZS5sZW5ndGggLSAxXV07XG59XG5cbi8vIEZvciBwYWNrZWQgcmVzaGFwZSwgd2UgbmVlZCB0byByZS1hcnJhbmdlIHRleGVsIGRhdGEgZm9yIG91dHB1dCBzaGFwZS5cbi8vIE91ciBwYWNrIGlzIGRlc2lnbmVkIHRvIHBhY2sgYSAyeDIgdGlsZSBpbiBsYXN0IGggYW5kIHcgZGltZW5zaW9uLCBzb1xuLy8gZm9yIHRoZSByZXNoYXBlZCBuZXcgdGVuc29yLCB3ZSBqdXN0IG5lZWQgdG8gcmUtYXJyYW5nZSB0aGUgbGFzdCBoIGFuZFxuLy8gdyBkaW1lbnNpb24uIEZvciBhbnkgc2hhcGUgdGhhdCBpcyBub3QgaW4gM0QsIGkuZS4gW2JhdGNoLCBXLCBIXSwgd2Vcbi8vIGZpcnN0IGNvbnZlcnQgaXQgdG8gM0QgYnkgY29sbGFwc2luZyBvdGhlciBkaW1lbnNpb24gdG8gYmF0Y2ggZGltLCB0aGVuXG4vLyBwcm9jZXNzIHdpdGggdGhlIGxhc3QgdHdvIGRpbWVuc2lvbnMuXG4vLyBOb3RlOiB3ZSBvbmx5IG5lZWQgdGhlIHNoYXBlIHRlbnNvciB0byBjYWxjdWxhdGUgb3V0cHV0IHNoYXBlLCBzbyB0aGVcbi8vIGNvbnRlbnQgaW4gc2hhcGUgdGVuc29yIGlzIG5ldmVyIHVwbG9hZGVkIHRvIEdQVS4gSXQgaXMgYWx3YXlzIGtlcHQgaW4gQ1BVLlxuLy8gVE9ETzogb3B0aW1pemUgdGhlIGFsZ29yaXRobSAtLSBpbiBzb21lIGNhc2VzLCBpZiB0aGUgbGFzdCB0d28gZGltcyBhcmVcbi8vIHRoZSBzYW1lIGJldHdlZW4gaW5wdXQgc2hhcGUgYW5kIG91dHB1dCBzaGFwZSwgdGhlIHBhY2tlZCByZXNoYXBlIGNhbiBiZVxuLy8gdHJlYXRlZCBhcyBuby1vcC5cbmV4cG9ydCBmdW5jdGlvbiBpc1Jlc2hhcGVDaGVhcChkaW1zOiByZWFkb25seSBudW1iZXJbXSwgcmVzaGFwZWREaW1zOiByZWFkb25seSBudW1iZXJbXSkge1xuICBsZXQgaXNDaGVhcFJlc2hhcGUgPSBmYWxzZTtcbiAgaWYgKGRpbXMubGVuZ3RoID09PSAwIHx8IHJlc2hhcGVkRGltcy5sZW5ndGggPT09IDApIHtcbiAgICAvLyBzY2FsYXJcbiAgICBpc0NoZWFwUmVzaGFwZSA9IHRydWU7XG4gIH0gZWxzZSBpZiAoZGltcy5sZW5ndGggPCAyIHx8IHJlc2hhcGVkRGltcy5sZW5ndGggPCAyKSB7XG4gICAgLy8gMURcbiAgICBpc0NoZWFwUmVzaGFwZSA9IGRpbXNbZGltcy5sZW5ndGggLSAxXSA9PT0gcmVzaGFwZWREaW1zW3Jlc2hhcGVkRGltcy5sZW5ndGggLSAxXTtcbiAgfSBlbHNlIHtcbiAgICAvLyAyRCArXG4gICAgaXNDaGVhcFJlc2hhcGUgPVxuICAgICAgZGltc1tkaW1zLmxlbmd0aCAtIDFdID09PSByZXNoYXBlZERpbXNbcmVzaGFwZWREaW1zLmxlbmd0aCAtIDFdICYmXG4gICAgICBkaW1zW2RpbXMubGVuZ3RoIC0gMl0gPT09IHJlc2hhcGVkRGltc1tyZXNoYXBlZERpbXMubGVuZ3RoIC0gMl07XG4gIH1cblxuICByZXR1cm4gaXNDaGVhcFJlc2hhcGU7XG59XG5cbmZ1bmN0aW9uIGdldFJlc2hhcGVkSW5wdXRDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSk6IHN0cmluZyB7XG4gIGNvbnN0IHN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoc2hhcGUpO1xuICBjb25zdCBjb29yZHMgPSBbJ2InLCAncicsICdjJ107XG4gIGNvbnN0IGluZGV4ID0gJ2luZGV4JztcbiAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9IHN0cmlkZXNcbiAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgIGNvbnN0IGxpbmUxID0gYGludCAke2Nvb3Jkc1tpXX0gPSAke2luZGV4fSAvICR7c3RyaWRlfWA7XG4gICAgICBjb25zdCBsaW5lMiA9XG4gICAgICAgIGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMVxuICAgICAgICAgID8gYGludCAke2Nvb3Jkc1tpICsgMV19ID0gJHtpbmRleH0gLSAke2Nvb3Jkc1tpXX0gKiAke3N0cmlkZX1gXG4gICAgICAgICAgOiBgaW5kZXggLT0gJHtjb29yZHNbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgfSlcbiAgICAuam9pbignJyk7XG5cbiAgcmV0dXJuIGBcbiAgICBpdmVjMyBpbnB1dENvb3Jkc0Zyb21SZXNoYXBlZE91dENvb3JkcyhpbnQgaW5kZXgpIHtcbiAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgIHJldHVybiBpdmVjMyhiLCByLCBjKTtcbiAgICB9XG4gIGA7XG59XG5cbmZ1bmN0aW9uIGdldEZsYXR0ZW5lZEluZGV4RnJvbTNEKHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0pOiBzdHJpbmcge1xuICBjb25zdCBzdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHNoYXBlKTtcblxuICByZXR1cm4gYFxuICBpbnQgZ2V0RmxhdHRlbmVkSW5kZXgoaXZlYzMgY29vcmRzKSB7XG4gICAgLy8gcmV2ZXJzZSB5LCB6IG9yZGVyXG4gICAgcmV0dXJuIGNvb3Jkcy54ICogJHtzdHJpZGVzWzBdfSArIGNvb3Jkcy56ICogJHtzdHJpZGVzWzFdfSArIGNvb3Jkcy55O1xuICB9XG5gO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgVGV4dHVyZURhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgY29uc3QgZW5jb2RlQXNVaW50OCA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZXh0dXJlRGF0YSk6IFRleHR1cmVEYXRhID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dC5zaGFwZTtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAvKipcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL3RlbnNvcmZsb3cvdGZqcy1jb3JlL2Jsb2IvbWFzdGVyL3NyYy9rZXJuZWxzL3dlYmdsL2VuY29kZV9mbG9hdF9ncHUudHNcbiAgICovXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICBjb25zdCBmbG9hdCBGTE9BVF9NQVggPSAxLjcwMTQxMTg0ZTM4O1xuICAgIGNvbnN0IGZsb2F0IEZMT0FUX01JTiA9IDEuMTc1NDk0MzVlLTM4O1xuXG4gICAgYm9vbCBpc05hTihmbG9hdCB2YWwpIHtcbiAgICAgIHJldHVybiAodmFsIDwgMS4wIHx8IDAuMCA8IHZhbCB8fCB2YWwgPT0gMC4wKSA/IGZhbHNlIDogdHJ1ZTtcbiAgICB9XG5cbiAgICBoaWdocCB2ZWM0IGVuY29kZUFzVWludDgoaGlnaHAgZmxvYXQgdikge1xuICAgICAgaWYgKGlzTmFOKHYpKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KDI1NSwgMjU1LCAyNTUsIDI1NSk7XG4gICAgICB9XG5cbiAgICAgIGhpZ2hwIGZsb2F0IGF2ID0gYWJzKHYpO1xuXG4gICAgICBpZihhdiA8IEZMT0FUX01JTikge1xuICAgICAgICByZXR1cm4gdmVjNCgwLjAsIDAuMCwgMC4wLCAwLjApO1xuICAgICAgfSBlbHNlIGlmKHYgPiBGTE9BVF9NQVgpIHtcbiAgICAgICAgcmV0dXJuIHZlYzQoMC4wLCAwLjAsIDEyOC4wLCAxMjcuMCkgLyAyNTUuMDtcbiAgICAgIH0gZWxzZSBpZih2IDwgLUZMT0FUX01BWCkge1xuICAgICAgICByZXR1cm4gdmVjNCgwLjAsIDAuMCwgIDEyOC4wLCAyNTUuMCkgLyAyNTUuMDtcbiAgICAgIH1cblxuICAgICAgaGlnaHAgdmVjNCBjID0gdmVjNCgwLDAsMCwwKTtcblxuICAgICAgaGlnaHAgZmxvYXQgZSA9IGZsb29yKGxvZzIoYXYpKTtcbiAgICAgIGhpZ2hwIGZsb2F0IG0gPSBleHAyKGZyYWN0KGxvZzIoYXYpKSkgLSAxLjA7XG5cbiAgICAgIGNbMl0gPSBmbG9vcigxMjguMCAqIG0pO1xuICAgICAgbSAtPSBjWzJdIC8gMTI4LjA7XG4gICAgICBjWzFdID0gZmxvb3IoMzI3NjguMCAqIG0pO1xuICAgICAgbSAtPSBjWzFdIC8gMzI3NjguMDtcbiAgICAgIGNbMF0gPSBmbG9vcig4Mzg4NjA4LjAgKiBtKTtcblxuICAgICAgaGlnaHAgZmxvYXQgZWJpYXMgPSBlICsgMTI3LjA7XG4gICAgICBjWzNdID0gZmxvb3IoZWJpYXMgLyAyLjApO1xuICAgICAgZWJpYXMgLT0gY1szXSAqIDIuMDtcbiAgICAgIGNbMl0gKz0gZmxvb3IoZWJpYXMpICogMTI4LjA7XG5cbiAgICAgIGNbM10gKz0gMTI4LjAgKiBzdGVwKDAuMCwgLXYpO1xuXG4gICAgICByZXR1cm4gYyAvIDI1NS4wO1xuICAgIH1cblxuICAgIHZvaWQgbWFpbigpIHtcbiAgICAgIGZsb2F0IHZhbHVlID0gJHtnbHNsLnRleHR1cmUyRH0oWCxUZXhDb29yZHMpLnI7XG4gICAgICAke2dsc2wub3V0cHV0fSA9IGVuY29kZUFzVWludDgodmFsdWUpO1xuICAgIH1gO1xuICBjb25zdCBwcm9ncmFtSW5mbyA9IHtcbiAgICBuYW1lOiAnVWludDhFbmNvZGUnLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgaW5wdXROYW1lczogWydYJ10sXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50ZW5zb3IudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLmRvd25sb2FkVWludDhBc0Zsb2F0IH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG4gIHJldHVybiBpbmZlcmVuY2VIYW5kbGVyLmV4ZWN1dGVQcm9ncmFtKHByb2dyYW1JbmZvLCBbaW5wdXQudGVuc29yXSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRDb29yZHNEYXRhVHlwZSB9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHsgZ2V0Q2hhbm5lbHMsIHVucGFja0Zyb21DaGFubmVsIH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgdW5wYWNrUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAndW5wYWNrJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVVucGFja1Byb2dyYW1JbmZvID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgcmFuayA9IGlucHV0LmRpbXMubGVuZ3RoO1xuXG4gIGNvbnN0IGNoYW5uZWxzID0gZ2V0Q2hhbm5lbHMoJ3JjJywgcmFuayk7XG4gIGNvbnN0IGlubmVyRGltcyA9IGNoYW5uZWxzLnNsaWNlKC0yKTtcbiAgY29uc3QgY29vcmRzRGF0YVR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShyYW5rKTtcbiAgY29uc3QgdW5wYWNrQ2hhbm5lbCA9IHVucGFja0Zyb21DaGFubmVsKCk7XG4gIGNvbnN0IGlzU2NhbGFyID0gaW5wdXQuZGltcy5sZW5ndGggPT09IDA7XG4gIGNvbnN0IHNvdXJjZUNvb3JkcyA9IGlzU2NhbGFyID8gJycgOiBnZXRTb3VyY2VDb29yZHMocmFuaywgY2hhbm5lbHMpO1xuICBjb25zdCBjb29yZHMgPSByYW5rIDw9IDEgPyAncmMnIDogYHZlYzIoJHtpbm5lckRpbXMuam9pbignLCcpfSlgO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAke3VucGFja0NoYW5uZWx9XG4gICAgdm9pZCBtYWluKCkge1xuICAgICAgJHtjb29yZHNEYXRhVHlwZX0gcmMgPSBnZXRPdXRwdXRDb29yZHMoKTtcblxuICAgICAgIC8vIFNhbXBsZSB0aGUgdGV4dHVyZSB3aXRoIHRoZSBjb29yZHMgdG8gZ2V0IHRoZSByZ2JhIGNoYW5uZWwgdmFsdWUuXG4gICAgICAgdmVjNCBwYWNrZWRJbnB1dCA9IGdldEEoJHtzb3VyY2VDb29yZHN9KTtcblxuICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNChnZXRDaGFubmVsKHBhY2tlZElucHV0LCAke2Nvb3Jkc30pLCAwLCAwLCAwKTtcbiAgICAgfVxuICAgYDtcblxuICByZXR1cm4ge1xuICAgIC4uLnVucGFja1Byb2dyYW1NZXRhZGF0YSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dC5kaW1zLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVW5wYWNrUHJvZ3JhbUluZm9Mb2FkZXIgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4gKHtcbiAgLi4udW5wYWNrUHJvZ3JhbU1ldGFkYXRhLFxuICBnZXQ6ICgpID0+IGNyZWF0ZVVucGFja1Byb2dyYW1JbmZvKGhhbmRsZXIsIGlucHV0KSxcbn0pO1xuXG5mdW5jdGlvbiBnZXRTb3VyY2VDb29yZHMocmFuazogbnVtYmVyLCBkaW1zOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIGlmIChyYW5rID09PSAxKSB7XG4gICAgcmV0dXJuICdyYyc7XG4gIH1cblxuICBsZXQgY29vcmRzID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgaSsrKSB7XG4gICAgY29vcmRzICs9IGRpbXNbaV07XG4gICAgaWYgKGkgPCByYW5rIC0gMSkge1xuICAgICAgY29vcmRzICs9ICcsJztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNvb3Jkcztcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBFbmNvZGVyIHtcbiAgZXhwb3J0IGludGVyZmFjZSBEYXRhVHlwZU1hcCB7XG4gICAgZmxvYXQ6IEZsb2F0MzJBcnJheTtcbiAgICBieXRlOiBVaW50OEFycmF5O1xuICAgIGludDogVWludDMyQXJyYXk7XG4gIH1cbiAgZXhwb3J0IHR5cGUgRGF0YVR5cGUgPSBrZXlvZiBEYXRhVHlwZU1hcDtcbiAgdHlwZSBEYXRhQXJyYXlUeXBlID0gRGF0YVR5cGVNYXBbRGF0YVR5cGVdO1xufVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cbmV4cG9ydCBjb25zdCBlbnVtIEVuY29kZXJVc2FnZSB7XG4gIERlZmF1bHQgPSAwLFxuICBVcGxvYWRPbmx5LFxuICBEb3dubG9hZDRCeXRlc0FzRmxvYXQzMixcbn1cbi8qIGVzbGludC1lbmFibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXG5cbi8qKlxuICogQWJzdHJhY3Rpb24gZm9yIG1hcHBpbmcgZGF0YSB0eXBlcyB0byB0ZXh0dXJlIHRleGxldHNcbiAqIEVuY29kaW5nIG1lYW5zIGhvdyBhIEZsb2F0MzIgaXMgbWFwcGVkIHRvIDEgb3IgNCBjaGFubmVscyBmb3IgZWFjaCB0ZXhsZXRcbiAqIERlY29kaW5nIG1lYW5zIGhvdyBhIHRleGxldCdzIGNoYW5uZWxzIGFyZSBtYXBwZWQgdG8gYSByZXN1bHRpbmcgRmxvYXQzMlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERhdGFFbmNvZGVyIHtcbiAgaW50ZXJuYWxGb3JtYXQ6IG51bWJlcjtcbiAgZm9ybWF0OiBudW1iZXI7XG4gIHRleHR1cmVUeXBlOiBudW1iZXI7XG4gIGNoYW5uZWxTaXplOiBudW1iZXI7XG4gIGVuY29kZShzcmM6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgdGV4dHVyZVNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZTtcbiAgYWxsb2NhdGUoc2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlO1xuICBkZWNvZGUoYnVmZmVyOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUsIGRhdGFTaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGU7XG59XG4vKipcbiAqIFdlYkdMMiBkYXRhIGVuY29kZXJcbiAqIFVzZXMgUjMyRiBhcyB0aGUgZm9ybWF0IGZvciB0ZXhsZXRcbiAqL1xuZXhwb3J0IGNsYXNzIFJlZEZsb2F0MzJEYXRhRW5jb2RlciBpbXBsZW1lbnRzIERhdGFFbmNvZGVyIHtcbiAgaW50ZXJuYWxGb3JtYXQ6IG51bWJlcjtcbiAgZm9ybWF0OiBudW1iZXI7XG4gIHRleHR1cmVUeXBlOiBudW1iZXI7XG4gIGNoYW5uZWxTaXplOiBudW1iZXI7XG4gIGNvbnN0cnVjdG9yKGdsOiBXZWJHTDJSZW5kZXJpbmdDb250ZXh0LCBjaGFubmVscyA9IDEpIHtcbiAgICBpZiAoY2hhbm5lbHMgPT09IDEpIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5SMzJGO1xuICAgICAgdGhpcy5mb3JtYXQgPSBnbC5SRUQ7XG4gICAgICB0aGlzLnRleHR1cmVUeXBlID0gZ2wuRkxPQVQ7XG4gICAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgfSBlbHNlIGlmIChjaGFubmVscyA9PT0gNCkge1xuICAgICAgdGhpcy5pbnRlcm5hbEZvcm1hdCA9IGdsLlJHQkEzMkY7XG4gICAgICB0aGlzLmZvcm1hdCA9IGdsLlJHQkE7XG4gICAgICB0aGlzLnRleHR1cmVUeXBlID0gZ2wuRkxPQVQ7XG4gICAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBudW1iZXIgb2YgY2hhbm5lbHM6ICR7Y2hhbm5lbHN9YCk7XG4gICAgfVxuICB9XG4gIGVuY29kZShzcmM6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgdGV4dHVyZVNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgbGV0IHJlc3VsdDogRmxvYXQzMkFycmF5O1xuICAgIGxldCBzb3VyY2U6IEZsb2F0MzJBcnJheTtcbiAgICBpZiAoc3JjLmNvbnN0cnVjdG9yICE9PSBGbG9hdDMyQXJyYXkpIHtcbiAgICAgIExvZ2dlci53YXJuaW5nKCdFbmNvZGVyJywgJ2RhdGEgd2FzIG5vdCBvZiB0eXBlIEZsb2F0MzI7IGNyZWF0aW5nIG5ldyBGbG9hdDMyQXJyYXknKTtcbiAgICAgIHNvdXJjZSA9IG5ldyBGbG9hdDMyQXJyYXkoc3JjKTtcbiAgICB9XG4gICAgaWYgKHRleHR1cmVTaXplICogdGhpcy5jaGFubmVsU2l6ZSA+IHNyYy5sZW5ndGgpIHtcbiAgICAgIExvZ2dlci53YXJuaW5nKCdFbmNvZGVyJywgJ1NvdXJjZSBkYXRhIHRvbyBzbWFsbC4gQWxsb2NhdGluZyBsYXJnZXIgYXJyYXknKTtcbiAgICAgIHNvdXJjZSA9IHNyYyBhcyBGbG9hdDMyQXJyYXk7XG4gICAgICByZXN1bHQgPSB0aGlzLmFsbG9jYXRlKHRleHR1cmVTaXplICogdGhpcy5jaGFubmVsU2l6ZSkgYXMgRmxvYXQzMkFycmF5O1xuICAgICAgc291cmNlLmZvckVhY2goKHYsIGkpID0+IChyZXN1bHRbaV0gPSB2KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNvdXJjZSA9IHNyYyBhcyBGbG9hdDMyQXJyYXk7XG4gICAgICByZXN1bHQgPSBzb3VyY2U7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgYWxsb2NhdGUoc2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShzaXplICogNCk7XG4gIH1cbiAgZGVjb2RlKGJ1ZmZlcjogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCBkYXRhU2l6ZTogbnVtYmVyKTogRmxvYXQzMkFycmF5IHtcbiAgICBpZiAodGhpcy5jaGFubmVsU2l6ZSA9PT0gMSkge1xuICAgICAgY29uc3QgZmlsdGVyZWREYXRhID0gKGJ1ZmZlciBhcyBGbG9hdDMyQXJyYXkpLmZpbHRlcigoX3ZhbHVlLCBpbmRleCkgPT4gaW5kZXggJSA0ID09PSAwKS5zdWJhcnJheSgwLCBkYXRhU2l6ZSk7XG4gICAgICByZXR1cm4gZmlsdGVyZWREYXRhO1xuICAgIH1cbiAgICByZXR1cm4gYnVmZmVyLnN1YmFycmF5KDAsIGRhdGFTaXplKSBhcyBGbG9hdDMyQXJyYXk7XG4gIH1cbn1cbi8qKlxuICogRGF0YSBlbmNvZGVyIGZvciBXZWJHTCAxIHdpdGggc3VwcG9ydCBmb3IgZmxvYXRpbmcgcG9pbnQgdGV4dHVyZVxuICovXG5leHBvcnQgY2xhc3MgUkdCQUZsb2F0RGF0YUVuY29kZXIgaW1wbGVtZW50cyBEYXRhRW5jb2RlciB7XG4gIGludGVybmFsRm9ybWF0OiBudW1iZXI7XG4gIGZvcm1hdDogbnVtYmVyO1xuICB0ZXh0dXJlVHlwZTogbnVtYmVyO1xuICBjaGFubmVsU2l6ZTogbnVtYmVyO1xuICBjb25zdHJ1Y3RvcihnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCBjaGFubmVscyA9IDEsIHRleHR1cmVUeXBlPzogbnVtYmVyKSB7XG4gICAgaWYgKGNoYW5uZWxzICE9PSAxICYmIGNoYW5uZWxzICE9PSA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgbnVtYmVyIG9mIGNoYW5uZWxzOiAke2NoYW5uZWxzfWApO1xuICAgIH1cbiAgICB0aGlzLmludGVybmFsRm9ybWF0ID0gZ2wuUkdCQTtcbiAgICB0aGlzLmZvcm1hdCA9IGdsLlJHQkE7XG4gICAgdGhpcy5jaGFubmVsU2l6ZSA9IGNoYW5uZWxzO1xuICAgIHRoaXMudGV4dHVyZVR5cGUgPSB0ZXh0dXJlVHlwZSB8fCBnbC5GTE9BVDtcbiAgfVxuICBlbmNvZGUoc3JjOiBGbG9hdDMyQXJyYXksIHRleHR1cmVTaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIGxldCBkZXN0ID0gc3JjO1xuICAgIGlmICh0aGlzLmNoYW5uZWxTaXplID09PSAxKSB7XG4gICAgICBMb2dnZXIudmVyYm9zZSgnRW5jb2RlcicsICdFeHBsb2RpbmcgaW50byBhIGxhcmdlciBhcnJheScpO1xuICAgICAgZGVzdCA9IHRoaXMuYWxsb2NhdGUodGV4dHVyZVNpemUpIGFzIEZsb2F0MzJBcnJheTtcbiAgICAgIHNyYy5mb3JFYWNoKCh2LCBpKSA9PiAoZGVzdFtpICogNF0gPSB2KSk7XG4gICAgfVxuICAgIHJldHVybiBkZXN0O1xuICB9XG4gIGFsbG9jYXRlKHNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoc2l6ZSAqIDQpO1xuICB9XG4gIGRlY29kZShidWZmZXI6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgZGF0YVNpemU6IG51bWJlcik6IEZsb2F0MzJBcnJheSB7XG4gICAgaWYgKHRoaXMuY2hhbm5lbFNpemUgPT09IDEpIHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkRGF0YSA9IChidWZmZXIgYXMgRmxvYXQzMkFycmF5KS5maWx0ZXIoKF92YWx1ZSwgaW5kZXgpID0+IGluZGV4ICUgNCA9PT0gMCkuc3ViYXJyYXkoMCwgZGF0YVNpemUpO1xuICAgICAgcmV0dXJuIGZpbHRlcmVkRGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1ZmZlci5zdWJhcnJheSgwLCBkYXRhU2l6ZSkgYXMgRmxvYXQzMkFycmF5O1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBVaW50OERhdGFFbmNvZGVyIGltcGxlbWVudHMgRGF0YUVuY29kZXIge1xuICBpbnRlcm5hbEZvcm1hdDogbnVtYmVyO1xuICBmb3JtYXQ6IG51bWJlcjtcbiAgdGV4dHVyZVR5cGU6IG51bWJlcjtcbiAgY2hhbm5lbFNpemUgPSA0O1xuICBjb25zdHJ1Y3RvcihnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCBjaGFubmVscyA9IDEpIHtcbiAgICBpZiAoY2hhbm5lbHMgPT09IDEpIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5BTFBIQTtcbiAgICAgIHRoaXMuZm9ybWF0ID0gZ2wuQUxQSEE7IC8vIG5vdCB0ZXN0ZWRcbiAgICAgIHRoaXMudGV4dHVyZVR5cGUgPSBnbC5VTlNJR05FRF9CWVRFO1xuICAgICAgdGhpcy5jaGFubmVsU2l6ZSA9IGNoYW5uZWxzO1xuICAgIH0gZWxzZSBpZiAoY2hhbm5lbHMgPT09IDQpIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5SR0JBO1xuICAgICAgdGhpcy5mb3JtYXQgPSBnbC5SR0JBO1xuICAgICAgdGhpcy50ZXh0dXJlVHlwZSA9IGdsLlVOU0lHTkVEX0JZVEU7XG4gICAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBudW1iZXIgb2YgY2hhbm5lbHM6ICR7Y2hhbm5lbHN9YCk7XG4gICAgfVxuICB9XG4gIGVuY29kZShzcmM6IFVpbnQ4QXJyYXksIF90ZXh0dXJlU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoc3JjLmJ1ZmZlciwgc3JjLmJ5dGVPZmZzZXQsIHNyYy5ieXRlTGVuZ3RoKTtcbiAgfVxuICBhbGxvY2F0ZShzaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheShzaXplICogdGhpcy5jaGFubmVsU2l6ZSk7XG4gIH1cbiAgZGVjb2RlKGJ1ZmZlcjogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCBkYXRhU2l6ZTogbnVtYmVyKTogVWludDhBcnJheSB7XG4gICAgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgIHJldHVybiBidWZmZXIuc3ViYXJyYXkoMCwgZGF0YVNpemUpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYXJyYXkgdHlwZTogJHtidWZmZXIuY29uc3RydWN0b3J9YCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmltcG9ydCB7IFRleHR1cmVMYXlvdXRTdHJhdGVneSwgV2lkdGhIZWlnaHRQcmVmcyB9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgVGV4dHVyZUxheW91dCwgVGV4dHVyZVR5cGUgfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUgPSAoXG4gIHRleHR1cmVMYXlvdXRTdHJhdGVneTogVGV4dHVyZUxheW91dFN0cmF0ZWd5LFxuICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZSxcbik6IFRleHR1cmVMYXlvdXQgPT4ge1xuICBjb25zdCBjaGFubmVsID0gdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnVucGFja2VkIHx8IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS51bnBhY2tlZFJldmVyc2VkID8gMSA6IDQ7XG4gIGNvbnN0IGlzUGFja2VkID0gdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZDtcbiAgY29uc3QgcmV2ZXJzZVdIID0gdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnVucGFja2VkUmV2ZXJzZWQgfHwgdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZDtcbiAgY29uc3QgYnJlYWtBeGlzID0gdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24gPyBzaGFwZS5sZW5ndGggLSAxIDogdW5kZWZpbmVkO1xuICBjb25zdCB1bnBhY2tlZFNoYXBlID1cbiAgICB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvblxuICAgICAgPyBzaGFwZS5tYXAoKGQsIGkpID0+IChpID09PSBzaGFwZS5sZW5ndGggLSAxID8gZCAqIDQgOiBkKSlcbiAgICAgIDogdW5kZWZpbmVkO1xuICByZXR1cm4gY3JlYXRlVGV4dHVyZUxheW91dEZyb21TaGFwZSh0ZXh0dXJlTGF5b3V0U3RyYXRlZ3ksIHNoYXBlLCBjaGFubmVsLCB1bnBhY2tlZFNoYXBlLCB7XG4gICAgaXNQYWNrZWQsXG4gICAgcmV2ZXJzZVdILFxuICAgIGJyZWFrQXhpcyxcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0ID0gKFxuICB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSxcbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUsXG4pOiBbbnVtYmVyLCBudW1iZXJdID0+IHtcbiAgY29uc3QgbGF5b3V0ID0gY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZSh0ZXh0dXJlTGF5b3V0U3RyYXRlZ3ksIHNoYXBlLCB0ZXh0dXJlVHlwZSk7XG4gIHJldHVybiBbbGF5b3V0LndpZHRoLCBsYXlvdXQuaGVpZ2h0XTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgVGV4dHVyZUxheW91dCBvYmplY3QgZnJvbSBzaGFwZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUgPSAoXG4gIHRleHR1cmVMYXlvdXRTdHJhdGVneTogVGV4dHVyZUxheW91dFN0cmF0ZWd5LFxuICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGNoYW5uZWxzOiAxIHwgNCA9IDEsXG4gIHVucGFja2VkU2hhcGU/OiByZWFkb25seSBudW1iZXJbXSxcbiAgcHJlZnM/OiBXaWR0aEhlaWdodFByZWZzLFxuKTogVGV4dHVyZUxheW91dCA9PiB7XG4gIGNvbnN0IGlzUGFja2VkID0gISEocHJlZnMgJiYgcHJlZnMuaXNQYWNrZWQpO1xuICBjb25zdCBbd2lkdGgsIGhlaWdodF0gPSB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3kuY29tcHV0ZVRleHR1cmVXSChpc1BhY2tlZCA/IHVucGFja2VkU2hhcGUgfHwgc2hhcGUgOiBzaGFwZSwgcHJlZnMpO1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICBsZXQgaW5mZXJyZWREaW1zID0gc2hhcGUuc2xpY2UoMCk7XG4gIGlmIChyYW5rID09PSAwKSB7XG4gICAgaW5mZXJyZWREaW1zID0gWzFdO1xuICB9XG4gIGlmIChjaGFubmVscyA9PT0gMSkge1xuICAgIC8vIHVucGFja2VkU2hhcGUgd2lsbCB0YWtlIGBzaGFwZWAgYW5kIG5vdCBgaW5mZXJyZWREaW1zYCBzbyBhcyB0byBjcmVhdGUgYSBzY2FsYXIgVGVuc29yIGlmIG5lZWQgYmVcbiAgICB1bnBhY2tlZFNoYXBlID0gc2hhcGU7XG4gIH0gZWxzZSBpZiAoaXNQYWNrZWQpIHtcbiAgICBpZiAoY2hhbm5lbHMgIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYSBwYWNrZWQgdGV4dHVyZSBtdXN0IGJlIDQtY2hhbm5lbCcpO1xuICAgIH1cbiAgICB1bnBhY2tlZFNoYXBlID0gc2hhcGU7XG4gICAgaWYgKHJhbmsgPiAwKSB7XG4gICAgICBpbmZlcnJlZERpbXNbcmFuayAtIDFdID0gTWF0aC5jZWlsKGluZmVycmVkRGltc1tyYW5rIC0gMV0gLyAyKTtcbiAgICB9XG4gICAgaWYgKHJhbmsgPiAxKSB7XG4gICAgICBpbmZlcnJlZERpbXNbcmFuayAtIDJdID0gTWF0aC5jZWlsKGluZmVycmVkRGltc1tyYW5rIC0gMl0gLyAyKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIXVucGFja2VkU2hhcGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1VucGFja2VkIHNoYXBlIGlzIG5lZWRlZCB3aGVuIHVzaW5nIGNoYW5uZWxzID4gMScpO1xuICB9XG4gIHJldHVybiB7XG4gICAgd2lkdGgsXG4gICAgaGVpZ2h0LFxuICAgIGNoYW5uZWxzLFxuICAgIGlzUGFja2VkLFxuICAgIHNoYXBlOiBpbmZlcnJlZERpbXMsXG4gICAgc3RyaWRlczogU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGluZmVycmVkRGltcyksXG4gICAgdW5wYWNrZWRTaGFwZSxcbiAgICByZXZlcnNlZFdIOiBwcmVmcyAmJiBwcmVmcy5yZXZlcnNlV0gsXG4gIH07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vLi4vYmFja2VuZCc7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcblxuaW1wb3J0IHsgY3JlYXRlUGFja1Byb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9vcHMvcGFjayc7XG5pbXBvcnQgeyBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtSW5mb0xvYWRlciwgaXNSZXNoYXBlQ2hlYXAsIHByb2Nlc3NEaW1zM0QgfSBmcm9tICcuL29wcy9yZXNoYXBlLXBhY2tlZCc7XG5pbXBvcnQgeyBlbmNvZGVBc1VpbnQ4IH0gZnJvbSAnLi9vcHMvdWludDgtZW5jb2RlJztcbmltcG9ydCB7IGNyZWF0ZVVucGFja1Byb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9vcHMvdW5wYWNrJztcbmltcG9ydCB7IFdlYkdMU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuL3Nlc3Npb24taGFuZGxlcic7XG5pbXBvcnQgeyBFbmNvZGVyVXNhZ2UgfSBmcm9tICcuL3RleHR1cmUtZGF0YS1lbmNvZGVyJztcbmltcG9ydCB7XG4gIGNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodCxcbiAgY3JlYXRlVGV4dHVyZUxheW91dEZyb21TaGFwZSxcbiAgY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZSxcbn0gZnJvbSAnLi90ZXh0dXJlLWxheW91dCc7XG5pbXBvcnQgeyBBcnRpZmFjdCwgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBUZXh0dXJlRGF0YSwgVGV4dHVyZUxheW91dCwgVGV4dHVyZVR5cGUgfSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgZ2V0UHJvZ3JhbUluZm9VbmlxdWVLZXkgPSAoXG4gIHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbyB8IFByb2dyYW1JbmZvTG9hZGVyLFxuICBpbnB1dFRleHR1cmVEYXRhczogVGV4dHVyZURhdGFbXSxcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGlucHV0cyA9IGlucHV0VGV4dHVyZURhdGFzXG4gICAgLm1hcCgodGV4dHVyZSkgPT4gYCR7dGV4dHVyZS51bnBhY2tlZFNoYXBlLmpvaW4oJywnKX07JHt0ZXh0dXJlLndpZHRofXgke3RleHR1cmUuaGVpZ2h0fWApXG4gICAgLmpvaW4oJ18nKTtcbiAgbGV0IGtleSA9IHByb2dyYW1JbmZvLm5hbWU7XG4gIGlmIChwcm9ncmFtSW5mby5jYWNoZUhpbnQpIHtcbiAgICBrZXkgKz0gJ1snICsgcHJvZ3JhbUluZm8uY2FjaGVIaW50ICsgJ10nO1xuICB9XG4gIGtleSArPSAnOicgKyBpbnB1dHM7XG4gIHJldHVybiBrZXk7XG59O1xuXG5leHBvcnQgY2xhc3MgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIGltcGxlbWVudHMgSW5mZXJlbmNlSGFuZGxlciB7XG4gIHByaXZhdGUgcGFja2VkVGV4dHVyZURhdGFDYWNoZTogTWFwPFRlbnNvci5JZCwgVGV4dHVyZURhdGE+O1xuICBwcml2YXRlIHVucGFja2VkVGV4dHVyZURhdGFDYWNoZTogTWFwPFRlbnNvci5JZCwgVGV4dHVyZURhdGE+O1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgc2Vzc2lvbjogV2ViR0xTZXNzaW9uSGFuZGxlcikge1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyBbd2lkdGgsIGhlaWdodF1cbiAgICovXG4gIGNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZSk6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIHJldHVybiBjYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQodGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LCBzaGFwZSwgdGV4dHVyZVR5cGUpO1xuICB9XG5cbiAgZXhlY3V0ZVByb2dyYW0ocHJvZ3JhbTogUHJvZ3JhbUluZm8gfCBQcm9ncmFtSW5mb0xvYWRlciwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSk6IFRleHR1cmVEYXRhIHtcbiAgICBpZiAoaW5wdXRzLmxlbmd0aCA8IHByb2dyYW0uaW5wdXROYW1lcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgc2l6ZSBtdXN0bid0IGJlIGxlc3MgdGhhbiAke3Byb2dyYW0uaW5wdXROYW1lcy5sZW5ndGh9LmApO1xuICAgIH1cbiAgICBpZiAocHJvZ3JhbS5pbnB1dE5hbWVzLmxlbmd0aCAhPT0gcHJvZ3JhbS5pbnB1dFR5cGVzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCBuYW1lcyBzaXplIGRvZXMgbm90IG1hdGNoIGlucHV0IHR5cGVzJyk7XG4gICAgfVxuXG4gICAgLy8gY3JlYXRlIHRleHR1cmUgaW5mbyBmb3IgaW5wdXRcbiAgICBjb25zdCBpbnB1dFRleHR1cmVEYXRhczogVGV4dHVyZURhdGFbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvZ3JhbS5pbnB1dE5hbWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICBpbnB1dFRleHR1cmVEYXRhc1tpXSA9IHRoaXMuZ2V0T3JDcmVhdGVUZXh0dXJlRGF0YShpbnB1dHNbaV0sIHByb2dyYW0uaW5wdXRUeXBlc1tpXSk7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5ID0gZ2V0UHJvZ3JhbUluZm9VbmlxdWVLZXkocHJvZ3JhbSwgaW5wdXRUZXh0dXJlRGF0YXMpO1xuICAgIGxldCBhcnRpZmFjdCA9IHRoaXMuc2Vzc2lvbi5wcm9ncmFtTWFuYWdlci5nZXRBcnRpZmFjdChrZXkpO1xuICAgIGNvbnN0IHByb2dyYW1JbmZvID0gYXJ0aWZhY3RcbiAgICAgID8gYXJ0aWZhY3QucHJvZ3JhbUluZm9cbiAgICAgIDogdHlwZW9mIChwcm9ncmFtIGFzIFByb2dyYW1JbmZvTG9hZGVyKS5nZXQgPT09ICdmdW5jdGlvbidcbiAgICAgICAgPyAocHJvZ3JhbSBhcyBQcm9ncmFtSW5mb0xvYWRlcikuZ2V0KClcbiAgICAgICAgOiAocHJvZ3JhbSBhcyBQcm9ncmFtSW5mbyk7XG5cbiAgICAvLyBjcmVhdGUgdGV4dHVyZSBpbmZvIGZvciBvdXRwdXRcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlTGF5b3V0ID0gY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZShcbiAgICAgIHRoaXMuc2Vzc2lvbi5sYXlvdXRTdHJhdGVneSxcbiAgICAgIHByb2dyYW1JbmZvLm91dHB1dC5kaW1zLFxuICAgICAgcHJvZ3JhbUluZm8ub3V0cHV0LnRleHR1cmVUeXBlLFxuICAgICk7XG4gICAgY29uc3Qgb3V0cHV0VGV4dHVyZURhdGEgPSB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhKG91dHB1dFRleHR1cmVMYXlvdXQsIHByb2dyYW1JbmZvLm91dHB1dC50eXBlKTtcblxuICAgIGlmICghYXJ0aWZhY3QpIHtcbiAgICAgIGFydGlmYWN0ID0gdGhpcy5zZXNzaW9uLnByb2dyYW1NYW5hZ2VyLmJ1aWxkKHByb2dyYW1JbmZvLCBpbnB1dFRleHR1cmVEYXRhcywgb3V0cHV0VGV4dHVyZURhdGEpO1xuICAgICAgdGhpcy5zZXNzaW9uLnByb2dyYW1NYW5hZ2VyLnNldEFydGlmYWN0KGtleSwgYXJ0aWZhY3QpO1xuICAgIH1cblxuICAgIHRoaXMucnVuUHJvZ3JhbShhcnRpZmFjdCwgaW5wdXRUZXh0dXJlRGF0YXMsIG91dHB1dFRleHR1cmVEYXRhKTtcbiAgICByZXR1cm4gb3V0cHV0VGV4dHVyZURhdGE7XG4gIH1cblxuICBydW4ocHJvZ3JhbTogUHJvZ3JhbUluZm9Mb2FkZXIsIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10pOiBUZW5zb3Ige1xuICAgIGNvbnN0IG91dHB1dFRleHR1cmVEYXRhID0gdGhpcy5leGVjdXRlUHJvZ3JhbShwcm9ncmFtLCBpbnB1dHMpO1xuICAgIHJldHVybiBvdXRwdXRUZXh0dXJlRGF0YS50ZW5zb3I7XG4gIH1cblxuICBwcml2YXRlIHJ1blByb2dyYW0oYXJ0aWZhY3Q6IEFydGlmYWN0LCBpbnB1dHM6IFRleHR1cmVEYXRhW10sIG91dHB1dDogVGV4dHVyZURhdGEpOiB2b2lkIHtcbiAgICAvLyBpbnB1dCBzaG91bGQgbWF0Y2hcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7ICsraSkge1xuICAgICAgaWYgKCEhaW5wdXRzW2ldLmlzUGFja2VkICE9PSAoYXJ0aWZhY3QucHJvZ3JhbUluZm8uaW5wdXRUeXBlc1tpXSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0WyR7aX1dIHByb3BlcnR5IHBhY2tlZCBpbmNvbnNpc3RlbnRgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBvdXRwdXQgc2hvdWxkIG1hdGNoXG4gICAgaWYgKCEhb3V0cHV0LmlzUGFja2VkICE9PSAoYXJ0aWZhY3QucHJvZ3JhbUluZm8ub3V0cHV0LnRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ291dHB1dCBwcm9wZXJ0eSBwYWNrZWQgaW5jb25zaXN0ZW50Jyk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXNzaW9uLnByb2dyYW1NYW5hZ2VyLnJ1bihhcnRpZmFjdCwgaW5wdXRzLCBvdXRwdXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIFRleHR1cmVEYXRhIG9iamVjdCBmcm9tIGEgdGVuc29yLlxuICAgKiBVc2FnZSA9IEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5LlxuICAgKiBJZiBhIHJlbGF0ZWQgdGV4dHVyZSBkYXRhIGlzIGZvdW5kIGluIGNhY2hlLCByZXR1cm5zIGl0O1xuICAgKiBPdGhlcndpc2U6XG4gICAqICAgQ3JlYXRlcyBhIG5ldyB0ZXh0dXJlIGxheW91dCBpZiBub3QgcHJvdmlkZWQ7XG4gICAqICAgQ3JlYXRlcyBXZWJHTFRleHR1cmUgd2l0aCB0aGUgbGF5b3V0O1xuICAgKiAgIFVwbG9hZCB0ZW5zb3IgZGF0YSB0byB0aGUgdGV4dHVyZTtcbiAgICogICBDcmVhdGVzIGEgdGV4dHVyZSBkYXRhIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIHRlbnNvci5cbiAgICogQHBhcmFtIHRlbnNvciB0aGUgdGVuc29yIHdpdGggZGF0YSB0byB1cGxvYWRcbiAgICovXG4gIHByaXZhdGUgZ2V0T3JDcmVhdGVUZXh0dXJlRGF0YSh0ZW5zb3I6IFRlbnNvciwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlKSB7XG4gICAgbGV0IHRkID0gdGhpcy5nZXRUZXh0dXJlRGF0YSh0ZW5zb3IuZGF0YUlkLCB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKTtcblxuICAgIGlmICghdGQpIHtcbiAgICAgIC8vIGNoZWNrIGlmIHdlIGhhdmUgdGV4dHVyZSBkYXRhIGluIGRpZmZlcmVudCB0eXBlXG4gICAgICB0ZCA9IHRoaXMuZ2V0VGV4dHVyZURhdGEodGVuc29yLmRhdGFJZCwgdGV4dHVyZVR5cGUgIT09IFRleHR1cmVUeXBlLnBhY2tlZCk7XG4gICAgICBpZiAodGQpIHtcbiAgICAgICAgaWYgKHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wYWNrKHRkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy51bnBhY2sodGQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF0ZCkge1xuICAgICAgY29uc3QgbGF5b3V0ID0gY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZSh0aGlzLnNlc3Npb24ubGF5b3V0U3RyYXRlZ3ksIHRlbnNvci5kaW1zLCB0ZXh0dXJlVHlwZSk7XG5cbiAgICAgIGlmICh0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbikge1xuICAgICAgICBjb25zdCBncm91cCA9IDE7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxzID0gNDtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSB0ZW5zb3IuZGltcztcbiAgICAgICAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gNCkge1xuICAgICAgICAgIC8vIHByZS1wcm9jZXNzaW5nIGZvciBrZXJuZWwgZGF0YSBvZiBDb252LlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gVE9ETzogY3VycmVudGx5IHRoaXMgaXMgYSBoYWNraW5nIHRvIG92ZXJ3cml0ZSBDb252J3Mgd2VpZ2h0LiBUaGUgY29ycmVjdCB3YXkgdG8gZG8gdGhpcyBzaG91bGQgYmU6XG4gICAgICAgICAgLy8gMS4gaW1wbGVtZW50IHRleHR1cmUgYmFzZWQgY29uc3QtZm9sZGluZ1xuICAgICAgICAgIC8vIDIuIGNyZWF0ZSBhIFdlYkdMIHByb2dyYW0gXCJwcmVwcm9jZXNzQ29udldlaWdodFwiIHRvIGRvIHRoZSBzYW1lIHdvcmsgYXMgYmVsb3dcbiAgICAgICAgICAvLyAzLiBydW4gdGhlIHByb2dyYW0gYmVmb3JlIGRvdFByb2R1Y3QuXG4gICAgICAgICAgLy9cbiAgICAgICAgICBjb25zdCBhZGp1c3RlZEtlcm5lbFNoYXBlID0gW3NoYXBlWzBdLCBNYXRoLmNlaWwoKHNoYXBlWzFdICogc2hhcGVbMl0gKiBzaGFwZVszXSkgLyBjaGFubmVscyldO1xuICAgICAgICAgIGNvbnN0IGFkanVzdGVkTGF5b3V0ID0gY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZShcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5sYXlvdXRTdHJhdGVneSxcbiAgICAgICAgICAgIGFkanVzdGVkS2VybmVsU2hhcGUsXG4gICAgICAgICAgICB0ZXh0dXJlVHlwZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGxldCBidWZmZXIgPSB0ZW5zb3IubnVtYmVyRGF0YTtcbiAgICAgICAgICBpZiAoKHNoYXBlWzFdICogc2hhcGVbMl0gKiBzaGFwZVszXSkgJSBjaGFubmVscyAhPT0gMCkge1xuICAgICAgICAgICAgY29uc3QgbnVtRmVhdHVyZU1hcHMgPSBzaGFwZVswXTtcbiAgICAgICAgICAgIGNvbnN0IG9sZFJvd1NpemUgPSBzaGFwZVsxXSAqIHNoYXBlWzJdICogc2hhcGVbM107XG4gICAgICAgICAgICBjb25zdCBuZXdSb3dTaXplID0gTWF0aC5jZWlsKChvbGRSb3dTaXplICogZ3JvdXApIC8gY2hhbm5lbHMpICogY2hhbm5lbHM7XG4gICAgICAgICAgICBjb25zdCBuZXdTaXplID0gbnVtRmVhdHVyZU1hcHMgKiBuZXdSb3dTaXplO1xuICAgICAgICAgICAgYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShuZXdTaXplKTtcbiAgICAgICAgICAgIGZvciAobGV0IGYgPSAwOyBmIDwgbnVtRmVhdHVyZU1hcHM7ICsrZikge1xuICAgICAgICAgICAgICBjb25zdCBvbGRPZmZzZXQgPSBmICogb2xkUm93U2l6ZTtcbiAgICAgICAgICAgICAgY29uc3QgbmV3T2Zmc2V0ID0gZiAqIG5ld1Jvd1NpemUgKyAoZiAlIGdyb3VwKSAqIG9sZFJvd1NpemU7XG4gICAgICAgICAgICAgIGJ1ZmZlci5zZXQodGVuc29yLm51bWJlckRhdGEuc3ViYXJyYXkob2xkT2Zmc2V0LCBvbGRPZmZzZXQgKyBvbGRSb3dTaXplKSwgbmV3T2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlVGV4dHVyZURhdGEoYWRqdXN0ZWRMYXlvdXQsIHRlbnNvci50eXBlLCBidWZmZXIsIHRlbnNvciwgRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKSB7XG4gICAgICAgIGNvbnN0IHVucGFja2VkVGV4dHVyZUxheW91dCA9IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUodGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LCB0ZW5zb3IuZGltcywgMSwgW10sIHtcbiAgICAgICAgICByZXZlcnNlV0g6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB1bnBhY2tlZFRleHR1cmVEYXRhID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YShcbiAgICAgICAgICB1bnBhY2tlZFRleHR1cmVMYXlvdXQsXG4gICAgICAgICAgdGVuc29yLnR5cGUsXG4gICAgICAgICAgdGVuc29yLm51bWJlckRhdGEsXG4gICAgICAgICAgdGVuc29yLFxuICAgICAgICAgIEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5LFxuICAgICAgICApO1xuICAgICAgICB0ZCA9IHRoaXMucGFjayh1bnBhY2tlZFRleHR1cmVEYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRkID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YShsYXlvdXQsIHRlbnNvci50eXBlLCB0ZW5zb3IubnVtYmVyRGF0YSwgdGVuc29yLCBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0ZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBUZXh0dXJlRGF0YSBvYmplY3QgdXNpbmcgdGhlIGdpdmVuIGRhdGEgYW5kIGJpbmQgdG8gdGhlIGdpdmVuIHRlbnNvci5cbiAgICogVXNhZ2UgPSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seS5cbiAgICogTk9URTogdGhpcyBmdW5jdGlvbiBpcyBhIGhhY2sgZm9yIENvbnYgaW1wbGVtZW50YXRpb24uIHNob3VsZCByZW1vdmUgdGhpcyBmdW5jdGlvbiwgYWZ0ZXIgcmV3cml0aW5nIENvbnZcbiAgICogaW1wbGVtZW50YXRpb24gYnkgR3JhcGguVHJhbnNmb3JtZXJcbiAgICogQHBhcmFtIGRhdGFUeXBlIHRoZSB0ZW5zb3IgZGF0YSB0eXBlXG4gICAqIEBwYXJhbSBkYXRhIHRoZSBhY3R1YWwgZGF0YSB0byB1cGxvYWRcbiAgICogQHBhcmFtIHRlbnNvciB0aGUgdGVuc29yIHRvIGJpbmQuIHRlbnNvcidzIGRhdGEgaXMgaWdub3JlZC5cbiAgICovXG4gIGNyZWF0ZVRleHR1cmVEYXRhRnJvbUxheW91dEJpbmRUZW5zb3IoXG4gICAgbGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsXG4gICAgZGF0YTogVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGVuc29yOiBUZW5zb3IsXG4gICk6IFRleHR1cmVEYXRhIHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YShsYXlvdXQsIGRhdGFUeXBlLCBkYXRhLCB0ZW5zb3IsIEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVGV4dHVyZURhdGEoXG4gICAgbGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsXG4gICAgZGF0YT86IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHRlbnNvcj86IFRlbnNvcixcbiAgICB1c2FnZT86IEVuY29kZXJVc2FnZSxcbiAgKTogVGV4dHVyZURhdGEge1xuICAgIExvZ2dlci52ZXJib3NlKCdJbmZlcmVuY2VIYW5kbGVyJywgYENyZWF0aW5nIFRleHR1cmVEYXRhOiBsYXlvdXQ6WyR7SlNPTi5zdHJpbmdpZnkobGF5b3V0KX1dYCk7XG4gICAgY29uc3QgdGV4dHVyZSA9IHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5jcmVhdGVUZXh0dXJlRnJvbUxheW91dChkYXRhVHlwZSwgbGF5b3V0LCBkYXRhLCB1c2FnZSk7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShsYXlvdXQsIGRhdGFUeXBlLCB0ZXh0dXJlLCB0ZW5zb3IpO1xuICB9XG5cbiAgcmVzaGFwZVVucGFja2VkKGlucHV0OiBUZW5zb3IsIHJlc2hhcGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3Ige1xuICAgIGNvbnN0IGlucHV0VEQgPSB0aGlzLmdldE9yQ3JlYXRlVGV4dHVyZURhdGEoaW5wdXQsIFRleHR1cmVUeXBlLnVucGFja2VkKTtcbiAgICBjb25zdCBuZXdUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0ge1xuICAgICAgY2hhbm5lbHM6IGlucHV0VEQuY2hhbm5lbHMsXG4gICAgICBoZWlnaHQ6IGlucHV0VEQuaGVpZ2h0LFxuICAgICAgd2lkdGg6IGlucHV0VEQud2lkdGgsXG4gICAgICAvLyBoYW5kbGUgcmVzaGFwaW5nIGludG8gc2NhbGFyIFRlbnNvcnNcbiAgICAgIHNoYXBlOiByZXNoYXBlZERpbXMubGVuZ3RoICE9PSAwID8gcmVzaGFwZWREaW1zIDogWzFdLFxuICAgICAgc3RyaWRlczogU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHJlc2hhcGVkRGltcyksXG4gICAgICB1bnBhY2tlZFNoYXBlOiByZXNoYXBlZERpbXMsXG4gICAgfTtcbiAgICBjb25zdCBuZXdUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShuZXdUZXh0dXJlTGF5b3V0LCBpbnB1dC50eXBlLCBpbnB1dFRELnRleHR1cmUpO1xuICAgIHJldHVybiBuZXdUZXh0dXJlRGF0YS50ZW5zb3I7XG4gIH1cblxuICByZXNoYXBlUGFja2VkKGlucHV0OiBUZW5zb3IsIHJlc2hhcGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3Ige1xuICAgIGNvbnN0IGlucHV0VEQgPSB0aGlzLmdldE9yQ3JlYXRlVGV4dHVyZURhdGEoaW5wdXQsIFRleHR1cmVUeXBlLnBhY2tlZCk7XG5cbiAgICAvLyBjaGVjayBpZiB0aGUgcmVzaGFwZSBpcyAnY2hlYXAnXG4gICAgaWYgKGlzUmVzaGFwZUNoZWFwKGlucHV0LmRpbXMsIHJlc2hhcGVkRGltcykpIHtcbiAgICAgIGNvbnN0IG5ld1RleHR1cmVMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSB7XG4gICAgICAgIGNoYW5uZWxzOiBpbnB1dFRELmNoYW5uZWxzLFxuICAgICAgICBoZWlnaHQ6IGlucHV0VEQuaGVpZ2h0LFxuICAgICAgICB3aWR0aDogaW5wdXRURC53aWR0aCxcbiAgICAgICAgLy8gaGFuZGxlIHJlc2hhcGluZyBpbnRvIHNjYWxhciBUZW5zb3JzXG4gICAgICAgIHNoYXBlOiByZXNoYXBlZERpbXMubGVuZ3RoICE9PSAwID8gcmVzaGFwZWREaW1zIDogWzFdLFxuICAgICAgICBzdHJpZGVzOiBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMocmVzaGFwZWREaW1zKSxcbiAgICAgICAgdW5wYWNrZWRTaGFwZTogcmVzaGFwZWREaW1zLFxuICAgICAgICBpc1BhY2tlZDogdHJ1ZSxcbiAgICAgIH07XG4gICAgICBjb25zdCBuZXdUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShuZXdUZXh0dXJlTGF5b3V0LCBpbnB1dC50eXBlLCBpbnB1dFRELnRleHR1cmUpO1xuICAgICAgcmV0dXJuIG5ld1RleHR1cmVEYXRhLnRlbnNvcjtcbiAgICB9XG5cbiAgICBjb25zdCBzcXVlZXplZElucHV0U2hhcGUgPSBwcm9jZXNzRGltczNEKGlucHV0LmRpbXMpO1xuICAgIGNvbnN0IHNxdWVlemVkT3V0cHV0U2hhcGUgPSBwcm9jZXNzRGltczNEKHJlc2hhcGVkRGltcyk7XG5cbiAgICBjb25zdCBzcXVlZXplZElucHV0VGVuc29yID0gdGhpcy5yZXNoYXBlUGFja2VkKGlucHV0LCBzcXVlZXplZElucHV0U2hhcGUpO1xuICAgIGNvbnN0IHNxdWVlemVkT3V0cHV0VGVuc29yID0gdGhpcy5ydW4oXG4gICAgICBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtSW5mb0xvYWRlcih0aGlzLCBzcXVlZXplZElucHV0VGVuc29yLCBzcXVlZXplZE91dHB1dFNoYXBlKSxcbiAgICAgIFtzcXVlZXplZElucHV0VGVuc29yXSxcbiAgICApO1xuICAgIGNvbnN0IG91dHB1dFRlbnNvciA9IHRoaXMucmVzaGFwZVBhY2tlZChzcXVlZXplZE91dHB1dFRlbnNvciwgcmVzaGFwZWREaW1zKTtcbiAgICByZXR1cm4gb3V0cHV0VGVuc29yO1xuICB9XG5cbiAgY2FzdChpbnB1dDogVGVuc29yLCB0eXBlOiBUZW5zb3IuRGF0YVR5cGUpOiBUZW5zb3Ige1xuICAgIGNvbnN0IGlucHV0VEQgPSB0aGlzLmdldE9yQ3JlYXRlVGV4dHVyZURhdGEoaW5wdXQsIFRleHR1cmVUeXBlLnVucGFja2VkKTtcbiAgICBjb25zdCBuZXdUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShpbnB1dFREIGFzIFRleHR1cmVMYXlvdXQsIHR5cGUsIGlucHV0VEQudGV4dHVyZSk7XG4gICAgcmV0dXJuIG5ld1RleHR1cmVEYXRhLnRlbnNvcjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShcbiAgICBsYXlvdXQ6IFRleHR1cmVMYXlvdXQsXG4gICAgZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSxcbiAgICB0ZXh0dXJlOiBXZWJHTFRleHR1cmUsXG4gICAgdGVuc29yPzogVGVuc29yLFxuICAgIHRlbnNvcklkPzogVGVuc29yLklkLFxuICApIHtcbiAgICBjb25zdCB0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEgPSB7XG4gICAgICAuLi5sYXlvdXQsXG4gICAgICB0ZW5zb3I6XG4gICAgICAgIHRlbnNvciB8fFxuICAgICAgICBuZXcgVGVuc29yKFxuICAgICAgICAgIGxheW91dC51bnBhY2tlZFNoYXBlLFxuICAgICAgICAgIGRhdGFUeXBlLFxuICAgICAgICAgIChfaWQ6IFRlbnNvci5JZCkgPT4gdGhpcy5yZWFkVGV4dHVyZSh0ZXh0dXJlRGF0YSksXG4gICAgICAgICAgYXN5bmMgKF9pZDogVGVuc29yLklkKSA9PiB0aGlzLnJlYWRUZXh0dXJlQXN5bmModGV4dHVyZURhdGEpLFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICB0ZW5zb3JJZCxcbiAgICAgICAgKSxcbiAgICAgIHRleHR1cmUsXG4gICAgfTtcbiAgICB0aGlzLnNldFRleHR1cmVEYXRhKHRleHR1cmVEYXRhLnRlbnNvci5kYXRhSWQsIHRleHR1cmVEYXRhLCBsYXlvdXQuaXNQYWNrZWQpO1xuICAgIHJldHVybiB0ZXh0dXJlRGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VGV4dHVyZURhdGEodGVuc29ySWQ6IFRlbnNvci5JZCwgaXNQYWNrZWQgPSBmYWxzZSk6IFRleHR1cmVEYXRhIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIodGVuc29ySWQpXG4gICAgICA/IHRoaXMuc2Vzc2lvbi5nZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZCwgaXNQYWNrZWQpXG4gICAgICA6IGlzUGFja2VkXG4gICAgICAgID8gdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmdldCh0ZW5zb3JJZClcbiAgICAgICAgOiB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZS5nZXQodGVuc29ySWQpO1xuICB9XG4gIHNldFRleHR1cmVEYXRhKHRlbnNvcklkOiBUZW5zb3IuSWQsIHRkOiBUZXh0dXJlRGF0YSwgaXNQYWNrZWQgPSBmYWxzZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNlc3Npb24uaXNJbml0aWFsaXplcih0ZW5zb3JJZCkpIHtcbiAgICAgIHRoaXMuc2Vzc2lvbi5zZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZCwgdGQsIGlzUGFja2VkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgKGlzUGFja2VkID8gdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlIDogdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUpLnNldCh0ZW5zb3JJZCwgdGQpO1xuICAgIH1cbiAgfVxuICBpc1RleHR1cmVMYXlvdXRDYWNoZWQodGVuc29yOiBUZW5zb3IsIGlzUGFja2VkID0gZmFsc2UpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmdldFRleHR1cmVEYXRhKHRlbnNvci5kYXRhSWQsIGlzUGFja2VkKTtcbiAgfVxuXG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLmNsZWFyQWN0aXZlVGV4dHVyZXMoKTtcbiAgICB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZm9yRWFjaCgodGQpID0+IHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCkpO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZS5mb3JFYWNoKCh0ZCkgPT4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlbGVhc2VUZXh0dXJlKHRkKSk7XG4gICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gIH1cblxuICByZWFkVGV4dHVyZSh0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEpOiBUZW5zb3IuTnVtYmVyVHlwZSB7XG4gICAgaWYgKHRleHR1cmVEYXRhLmlzUGFja2VkKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWFkVGV4dHVyZSh0aGlzLnVucGFjayh0ZXh0dXJlRGF0YSkpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC5pc0Zsb2F0MzJEb3dubG9hZFN1cHBvcnRlZCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWFkVWludDhUZXh0dXJlQXNGbG9hdChlbmNvZGVBc1VpbnQ4KHRoaXMsIHRleHR1cmVEYXRhKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVhZFRleHR1cmUodGV4dHVyZURhdGEsIHRleHR1cmVEYXRhLnRlbnNvci50eXBlLCB0ZXh0dXJlRGF0YS5jaGFubmVscyk7XG4gIH1cblxuICBhc3luYyByZWFkVGV4dHVyZUFzeW5jKHRleHR1cmVEYXRhOiBUZXh0dXJlRGF0YSk6IFByb21pc2U8VGVuc29yLk51bWJlclR5cGU+IHtcbiAgICBpZiAodGV4dHVyZURhdGEuaXNQYWNrZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlYWRUZXh0dXJlQXN5bmModGhpcy51bnBhY2sodGV4dHVyZURhdGEpKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQuaXNGbG9hdDMyRG93bmxvYWRTdXBwb3J0ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVhZFVpbnQ4VGV4dHVyZUFzRmxvYXQoZW5jb2RlQXNVaW50OCh0aGlzLCB0ZXh0dXJlRGF0YSkpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlYWRUZXh0dXJlQXN5bmModGV4dHVyZURhdGEsIHRleHR1cmVEYXRhLnRlbnNvci50eXBlLCB0ZXh0dXJlRGF0YS5jaGFubmVscyk7XG4gIH1cblxuICBwYWNrKGlucHV0OiBUZXh0dXJlRGF0YSk6IFRleHR1cmVEYXRhIHtcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlRGF0YSA9IHRoaXMuZXhlY3V0ZVByb2dyYW0oY3JlYXRlUGFja1Byb2dyYW1JbmZvTG9hZGVyKHRoaXMsIGlucHV0LnRlbnNvciksIFtpbnB1dC50ZW5zb3JdKTtcbiAgICByZXR1cm4gb3V0cHV0VGV4dHVyZURhdGE7XG4gIH1cblxuICB1bnBhY2soaW5wdXQ6IFRleHR1cmVEYXRhKTogVGV4dHVyZURhdGEge1xuICAgIGNvbnN0IG91dHB1dFRleHR1cmVEYXRhID0gdGhpcy5leGVjdXRlUHJvZ3JhbShjcmVhdGVVbnBhY2tQcm9ncmFtSW5mb0xvYWRlcih0aGlzLCBpbnB1dC50ZW5zb3IpLCBbaW5wdXQudGVuc29yXSk7XG4gICAgcmV0dXJuIG91dHB1dFRleHR1cmVEYXRhO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmNsYXNzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleUltcGwge1xuICBjb25zdHJ1Y3RvcihhdHRyaWJ1dGU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBhdHRyaWJ1dGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBrZXk6IHN0cmluZztcbiAgcHVibGljIGdldCBjYWNoZUtleSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5rZXkpIHtcbiAgICAgIHRoaXMua2V5ID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGhpcylcbiAgICAgICAgLnNvcnQoKVxuICAgICAgICAubWFwKChuYW1lKSA9PiBgJHsodGhpcyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbbmFtZV19YClcbiAgICAgICAgLmpvaW4oJzsnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMua2V5O1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgY2FjaGVLZXk6IHN0cmluZztcbn1cblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KFxuICBhdHRyaWJ1dGU6IFQsXG4pOiBUICYgQXR0cmlidXRlV2l0aENhY2hlS2V5ID0+IG5ldyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXlJbXBsKGF0dHJpYnV0ZSkgYXMgdW5rbm93biBhcyBUICYgQXR0cmlidXRlV2l0aENhY2hlS2V5O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIGVwc2lsb246IG51bWJlcjtcbiAgbW9tZW50dW06IG51bWJlcjtcbiAgc3BhdGlhbDogbnVtYmVyO1xufVxuXG5jb25zdCBiYXRjaE5vcm1hbGl6YXRpb25Qcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdCYXRjaE5vcm1hbGl6YXRpb24nLFxuICBpbnB1dE5hbWVzOiBbJ0EnLCAnU2NhbGUnLCAnQicsICdNZWFuJywgJ1ZhcmlhbmNlJ10sXG4gIGlucHV0VHlwZXM6IFtcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgXSxcbn07XG5cbmV4cG9ydCBjb25zdCBiYXRjaE5vcm1hbGl6YXRpb246IE9wZXJhdG9ySW1wbGVtZW50YXRpb248QmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4uYmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVCYXRjaE5vcm1hbGl6YXRpb25Qcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGVwc2lsb24gPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2Vwc2lsb24nLCAxZS01KTtcbiAgY29uc3QgbW9tZW50dW0gPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ21vbWVudHVtJywgMC45KTtcbiAgY29uc3Qgc3BhdGlhbCA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3NwYXRpYWwnLCAxKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGVwc2lsb24sIG1vbWVudHVtLCBzcGF0aWFsIH0pO1xufTtcblxuY29uc3QgY3JlYXRlQmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCByYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoO1xuICBjb25zdCBbc2NhbGVXaWR0aCwgc2NhbGVIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgaW5wdXRzWzFdLmRpbXMsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICk7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgIHZlYzIgcG9zaXRpb24gPSBvZmZzZXRUb0Nvb3JkcyhpbmRpY2VzWzFdLCAke3NjYWxlV2lkdGh9LCAke3NjYWxlSGVpZ2h0fSk7XG4gICAgZmxvYXQgc2NhbGUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oU2NhbGUsIHBvc2l0aW9uKSk7XG4gICAgZmxvYXQgbWVhbiA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShNZWFuLCBwb3NpdGlvbikpO1xuICAgIGZsb2F0IHZhcmlhbmNlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KFZhcmlhbmNlLCBwb3NpdGlvbikpO1xuICAgIGZsb2F0IGIgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQiwgcG9zaXRpb24pKTtcblxuICAgIHJldHVybiBzY2FsZSAqICggKF9BKGluZGljZXMpIC0gbWVhbikgLyBzcXJ0KHZhcmlhbmNlICsgZmxvYXQoJHthdHRyaWJ1dGVzLmVwc2lsb259KSkgKSArIGI7XG4gIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLmJhdGNoTm9ybWFsaXphdGlvblByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW5wdXRzWzBdLmRpbXMsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0JhdGNoTm9ybWFsaXphdGlvbiByZXF1aXJlcyA1IGlucHV0cy4nKTtcbiAgfVxuXG4gIGNvbnN0IFggPSBpbnB1dHNbMF07XG4gIGNvbnN0IHNjYWxlID0gaW5wdXRzWzFdO1xuICBjb25zdCBCID0gaW5wdXRzWzJdO1xuICBjb25zdCBtZWFuID0gaW5wdXRzWzNdO1xuICBjb25zdCB2YXJfID0gaW5wdXRzWzRdO1xuXG4gIC8vIGlucHV0IHNob3VsZCBhdGxlYXN0IGhhdmUgdGhyZWUgZGltZW5zaW9ucyAtIE4sQyxkaW0xLC4uLixkaW1uXG4gIC8vIG90aGVyIGlucHV0cyBjYW4gaGF2ZSBvbmx5IG9uZSBkaW1lbnNpb25zXG4gIGlmIChcbiAgICBYLmRpbXMubGVuZ3RoIDwgMyB8fFxuICAgIHNjYWxlLmRpbXMubGVuZ3RoICE9PSAxIHx8XG4gICAgQi5kaW1zLmxlbmd0aCAhPT0gMSB8fFxuICAgIG1lYW4uZGltcy5sZW5ndGggIT09IDEgfHxcbiAgICB2YXJfLmRpbXMubGVuZ3RoICE9PSAxXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoXG4gICAgc2NhbGUuZGltc1swXSAhPT0gWC5kaW1zWzFdIHx8XG4gICAgQi5kaW1zWzBdICE9PSBYLmRpbXNbMV0gfHxcbiAgICBtZWFuLmRpbXNbMF0gIT09IFguZGltc1sxXSB8fFxuICAgIHZhcl8uZGltc1swXSAhPT0gWC5kaW1zWzFdXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoXG4gICAgKFgudHlwZSAhPT0gJ2Zsb2F0MzInICYmIFgudHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChzY2FsZS50eXBlICE9PSAnZmxvYXQzMicgJiYgc2NhbGUudHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChCLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBCLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAobWVhbi50eXBlICE9PSAnZmxvYXQzMicgJiYgbWVhbi50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKHZhcl8udHlwZSAhPT0gJ2Zsb2F0MzInICYmIHZhcl8udHlwZSAhPT0gJ2Zsb2F0NjQnKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgdGVuc29yIHR5cGVzLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZUxheW91dCB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgV2ViR0xDb250ZXh0IH0gZnJvbSAnLi93ZWJnbC1jb250ZXh0JztcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXG5leHBvcnQgZW51bSBGdW5jdGlvblR5cGUge1xuICBWYWx1ZUJhc2VkLFxuICBQb3NpdGlvbmFsLFxufVxuZXhwb3J0IGludGVyZmFjZSBHbHNsRnVuY3Rpb248VCBleHRlbmRzIEZ1bmN0aW9uVHlwZT4ge1xuICBib2R5OiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbiAgdHlwZTogVDtcbn1cbmV4cG9ydCB0eXBlIEdsc2xWYWx1ZUZ1bmN0aW9uID0gR2xzbEZ1bmN0aW9uPEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkPjtcbmV4cG9ydCBpbnRlcmZhY2UgR2xzbFBvc2l0aW9uYWxGdW5jdGlvbiBleHRlbmRzIEdsc2xGdW5jdGlvbjxGdW5jdGlvblR5cGUuUG9zaXRpb25hbD4ge1xuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5leHBvcnQgY2xhc3MgR2xzbENvbnRleHQge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQsXG4gICAgcHVibGljIHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbyxcbiAgICBwdWJsaWMgaW5wdXRUZXh0dXJlTGF5b3V0czogVGV4dHVyZUxheW91dFtdLFxuICAgIHB1YmxpYyBvdXRwdXRUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICApIHt9XG59XG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgR2xzbExpYiB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBjb250ZXh0OiBHbHNsQ29udGV4dCkge31cbiAgYWJzdHJhY3QgZ2V0RnVuY3Rpb25zKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH07XG4gIGFic3RyYWN0IGdldEN1c3RvbVR5cGVzKCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9O1xufVxuXG4vLyBhYnN0cmFjdGlvbiB0byByZXByZXNlbnQgYSBHTFNMIGxpYnJhcnkgcm91dGluZSBhbmQgaXQncyBkZXBlbmRlbmNpZXNcbmV4cG9ydCBjbGFzcyBHbHNsTGliUm91dGluZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByb3V0aW5lQm9keTogc3RyaW5nLFxuICAgIHB1YmxpYyBkZXBlbmRlbmNpZXM/OiBzdHJpbmdbXSxcbiAgKSB7fVxufVxuXG4vLyBhYnN0cmFjdGlvbiB0byByZXByZXNlbnQgYSBHTFNMIGxpYnJhcnkgcm91dGluZSBhbmQgaXQncyBkZXBlbmRlbmNpZXMgQVMgR1JBUEggTm9kZXNcbi8vIHRoaXMgbGV2ZWwgb2YgYWJzdHJhY3Rpb24gaXMgdXNlZCB0byB0b3BvbG9naWNhbGx5IHNvcnQgcm91dGluZXMgYmVmb3JlIGZyYWdtZW50IHNoYWRlIGluY2x1c2lvblxuZXhwb3J0IGNsYXNzIEdsc2xMaWJSb3V0aW5lTm9kZSB7XG4gIGRlcGVuZGVuY2llczogR2xzbExpYlJvdXRpbmVOb2RlW107XG4gIHJvdXRpbmVCb2R5OiBzdHJpbmc7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBuYW1lOiBzdHJpbmcsXG4gICAgcm91dGluZUJvZHk/OiBzdHJpbmcsXG4gICAgZGVwZW5kZW5jaWVzPzogR2xzbExpYlJvdXRpbmVOb2RlW10sXG4gICkge1xuICAgIGlmIChkZXBlbmRlbmNpZXMpIHtcbiAgICAgIHRoaXMuZGVwZW5kZW5jaWVzID0gZGVwZW5kZW5jaWVzO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlcGVuZGVuY2llcyA9IFtdO1xuICAgIH1cblxuICAgIGlmIChyb3V0aW5lQm9keSkge1xuICAgICAgdGhpcy5yb3V0aW5lQm9keSA9IHJvdXRpbmVCb2R5O1xuICAgIH1cbiAgfVxuICBhZGREZXBlbmRlbmN5KG5vZGU6IEdsc2xMaWJSb3V0aW5lTm9kZSkge1xuICAgIGlmIChub2RlKSB7XG4gICAgICB0aGlzLmRlcGVuZGVuY2llcy5wdXNoKG5vZGUpO1xuICAgIH1cbiAgfVxufVxuXG4vLyB0b3BvbG9naWNhbGx5IHNvcnQgR0xTTCBsaWJyYXJ5IHJvdXRpbmVzIChncmFwaCBub2RlcyBhYnN0cmFjdGlvbikgYmVmb3JlIHNoYWRlciBzY3JpcHQgaW5jbHVzaW9uXG5leHBvcnQgY2xhc3MgVG9wb2xvZ2ljYWxTb3J0R2xzbFJvdXRpbmVzIHtcbiAgc3RhdGljIHJldHVybk9yZGVyZWROb2Rlcyhub2RlczogR2xzbExpYlJvdXRpbmVOb2RlW10pOiBHbHNsTGliUm91dGluZU5vZGVbXSB7XG4gICAgaWYgKCFub2RlcyB8fCBub2Rlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBpZiAobm9kZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gbm9kZXM7XG4gICAgfVxuXG4gICAgY29uc3QgY3ljbGVDaGVjayA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IGFscmVhZHlUcmF2ZXJzZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgQXJyYXk8R2xzbExpYlJvdXRpbmVOb2RlPigpO1xuXG4gICAgdGhpcy5jcmVhdGVPcmRlcmVkTm9kZXMobm9kZXMsIGN5Y2xlQ2hlY2ssIGFscmVhZHlUcmF2ZXJzZWQsIHJlc3VsdCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGNyZWF0ZU9yZGVyZWROb2RlcyhcbiAgICBncmFwaE5vZGVzOiBHbHNsTGliUm91dGluZU5vZGVbXSxcbiAgICBjeWNsZUNoZWNrOiBTZXQ8c3RyaW5nPixcbiAgICBhbHJlYWR5VHJhdmVyc2VkOiBTZXQ8c3RyaW5nPixcbiAgICByZXN1bHQ6IEdsc2xMaWJSb3V0aW5lTm9kZVtdLFxuICApIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoTm9kZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHRoaXMuZGZzVHJhdmVyc2UoZ3JhcGhOb2Rlc1tpXSwgY3ljbGVDaGVjaywgYWxyZWFkeVRyYXZlcnNlZCwgcmVzdWx0KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBkZnNUcmF2ZXJzZShcbiAgICByb290OiBHbHNsTGliUm91dGluZU5vZGUsXG4gICAgY3ljbGVDaGVjazogU2V0PHN0cmluZz4sXG4gICAgYWxyZWFkeVRyYXZlcnNlZDogU2V0PHN0cmluZz4sXG4gICAgcmVzdWx0OiBHbHNsTGliUm91dGluZU5vZGVbXSxcbiAgKSB7XG4gICAgLy8gaWYgdGhpcyByb290IGhhcyBhbHJlYWR5IGJlZW4gdHJhdmVyc2VkIHJldHVyblxuICAgIGlmICghcm9vdCB8fCBhbHJlYWR5VHJhdmVyc2VkLmhhcyhyb290Lm5hbWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gY3ljbGljIGRlcGVuZGVuY3kgaGFzIGJlZW4gZGV0ZWN0ZWRcbiAgICBpZiAoY3ljbGVDaGVjay5oYXMocm9vdC5uYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ3ljbGljIGRlcGVuZGVuY3kgZGV0ZWN0ZWQuIENhbid0IHRvcG9sb2dpY2FsbHkgc29ydCByb3V0aW5lcyBuZWVkZWQgZm9yIHNoYWRlci5cIik7XG4gICAgfVxuXG4gICAgLy8gaG9sZCB0aGlzIG5vZGUgdG8gZGV0ZWN0IGN5Y2xlcyBpZiBhbnlcbiAgICBjeWNsZUNoZWNrLmFkZChyb290Lm5hbWUpO1xuXG4gICAgLy8gdHJhdmVyc2UgY2hpbGRyZW4gaW4gYSBkZnMgZmFzaGlvblxuICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IHJvb3QuZGVwZW5kZW5jaWVzO1xuICAgIGlmIChkZXBlbmRlbmNpZXMgJiYgZGVwZW5kZW5jaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVwZW5kZW5jaWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHRoaXMuZGZzVHJhdmVyc2UoZGVwZW5kZW5jaWVzW2ldLCBjeWNsZUNoZWNrLCBhbHJlYWR5VHJhdmVyc2VkLCByZXN1bHQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkZCB0byByZXN1bHQgaG9sZGVyXG4gICAgcmVzdWx0LnB1c2gocm9vdCk7XG5cbiAgICAvLyBtYXJrIHRoaXMgbm9kZSBhcyB0cmF2ZXJzZWQgc28gdGhhdCB3ZSBkb24ndCB0cmF2ZXJzZSBmcm9tIHRoaXMgYWdhaW5cbiAgICBhbHJlYWR5VHJhdmVyc2VkLmFkZChyb290Lm5hbWUpO1xuXG4gICAgLy8gcmVsZWFzZSB0aGUgaG9sZFxuICAgIGN5Y2xlQ2hlY2suZGVsZXRlKHJvb3QubmFtZSk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IEJyb2FkY2FzdFV0aWwsIFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgRnVuY3Rpb25UeXBlLCBHbHNsVmFsdWVGdW5jdGlvbiB9IGZyb20gJy4uL2dsc2wtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQWRkKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdhZGRfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGEgKyBiO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHYxICsgdjI7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsRGl2KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdkaXZfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGEgLyBiO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHYxIC8gdjI7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTXVsKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdtdWxfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGEgKiBiO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHYxICogdjI7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsU3ViKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdzdWJfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGEgLSBiO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHYxIC0gdjI7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsRXF1YWwoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2VxdWFsXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdChhID09IGIpO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHZlYzQoZXF1YWwodjEsIHYyKSk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsR3JlYXRlcigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnZ3JlYXRlcl8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoYSA+IGIpO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHZlYzQoIHYxLnIgPiB2Mi5yICxcbiAgICAgIHYxLmcgPiB2Mi5nLFxuICAgICAgdjEuYiA+IHYyLmIsXG4gICAgICB2MS5hID4gdjIuYSApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbExlc3MoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2xlc3NfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KGEgPCBiKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2ZWM0KCB2MS5yIDwgdjIuciAsXG4gICAgICAgICAgICAgICAgdjEuZyA8IHYyLmcsXG4gICAgICAgICAgICAgICAgdjEuYiA8IHYyLmIsXG4gICAgICAgICAgICAgICAgdjEuYSA8IHYyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBbmQoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2FuZF8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoIGJvb2woYSkgJiYgYm9vbChiKSApO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgYnZlYzQgYjEgPSBidmVjNCh2MSk7XG4gICAgYnZlYzQgYjIgPSBidmVjNCh2Mik7XG4gICAgcmV0dXJuIHZlYzQoIGIxLnIgJiYgYjIuciAsXG4gICAgICAgICAgICAgICAgYjEuZyAmJiBiMi5nLFxuICAgICAgICAgICAgICAgIGIxLmIgJiYgYjIuYixcbiAgICAgICAgICAgICAgICBiMS5hICYmIGIyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xPcigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnb3JfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KCBib29sKGEpIHx8IGJvb2woYikgKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIGJ2ZWM0IGIxID0gYnZlYzQodjEpO1xuICAgIGJ2ZWM0IGIyID0gYnZlYzQodjIpO1xuICAgIHJldHVybiB2ZWM0KCBiMS5yIHx8IGIyLnIgLFxuICAgICAgICAgICAgICAgIGIxLmcgfHwgYjIuZyxcbiAgICAgICAgICAgICAgICBiMS5iIHx8IGIyLmIsXG4gICAgICAgICAgICAgICAgYjEuYSB8fCBiMi5hICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsWG9yKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICd4b3JfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KCBib29sKGEpIF5eIGJvb2woYikgKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIGJ2ZWM0IGIxID0gYnZlYzQodjEpO1xuICAgIGJ2ZWM0IGIyID0gYnZlYzQodjIpO1xuICAgIHJldHVybiB2ZWM0KCBiMS5yIF5eIGIyLnIgLFxuICAgICAgICAgICAgICAgIGIxLmcgXl4gYjIuZyxcbiAgICAgICAgICAgICAgICBiMS5iIF5eIGIyLmIsXG4gICAgICAgICAgICAgICAgYjEuYSBeXiBiMi5hICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsUG93KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluQmluYXJ5KCdwb3cnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsUFJlbHUoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3ByZWx1Xyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhIDwgMC4wID8gYSAqIGI6IGE7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdmVjNChcbiAgICAgIHYxLnIgPCAwLjAgPyB2MS5yICogdjIucjogdjEucixcbiAgICAgIHYxLmcgPCAwLjAgPyB2MS5nICogdjIuZzogdjEuZyxcbiAgICAgIHYxLmIgPCAwLjAgPyB2MS5iICogdjIuYjogdjEuYixcbiAgICAgIHYxLmEgPCAwLjAgPyB2MS5hICogdjIuYTogdjEuYVxuICAgICAgKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuXG5mdW5jdGlvbiBnbHNsQnVpbHRpbkJpbmFyeShmbmFtZTogc3RyaW5nKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gYCR7Zm5hbWV9X2A7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiAke2ZuYW1lfShhLCBiKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiAke2ZuYW1lfSh2MSwgdjIpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5cbmNvbnN0IGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGdsc2xGdW5jOiBHbHNsVmFsdWVGdW5jdGlvbixcbiAgb3V0cHV0VGVuc29yVHlwZTogVGVuc29yLkRhdGFUeXBlID0gaW5wdXRzWzBdLnR5cGUsXG4gIGNhY2hlS2V5Pzogc3RyaW5nLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCB0ZXh0dXJlVHlwZSA9IGhhbmRsZXIuc2Vzc2lvbi5wYWNrID8gVGV4dHVyZVR5cGUucGFja2VkIDogVGV4dHVyZVR5cGUudW5wYWNrZWQ7XG4gIHJldHVybiB7XG4gICAgbmFtZTogZ2xzbEZ1bmMubmFtZSxcbiAgICBpbnB1dE5hbWVzOiBbJ0EnLCAnQiddLFxuICAgIGlucHV0VHlwZXM6IFt0ZXh0dXJlVHlwZSwgdGV4dHVyZVR5cGVdLFxuICAgIGNhY2hlSGludDogY2FjaGVLZXksXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVCaW5hcnlQcm9ncmFtSW5mbyhoYW5kbGVyLCBpbnB1dHMsIGdsc2xGdW5jLCBvdXRwdXRUZW5zb3JUeXBlKSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGdsc2xGdW5jOiBHbHNsVmFsdWVGdW5jdGlvbixcbiAgb3V0cHV0VGVuc29yVHlwZTogVGVuc29yLkRhdGFUeXBlID0gaW5wdXRzWzBdLnR5cGUsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHRleHR1cmVUeXBlID0gaGFuZGxlci5zZXNzaW9uLnBhY2sgPyBUZXh0dXJlVHlwZS5wYWNrZWQgOiBUZXh0dXJlVHlwZS51bnBhY2tlZDtcbiAgY29uc3QgaXNCcm9hZGNhc3QgPSAhU2hhcGVVdGlsLmFyZUVxdWFsKGlucHV0c1swXS5kaW1zLCBpbnB1dHNbMV0uZGltcyk7XG4gIGxldCBvdXRwdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuXG4gIGNvbnN0IHVzZVBhY2tlZFRleHR1cmUgPSBoYW5kbGVyLnNlc3Npb24ucGFjaztcblxuICBpZiAoaXNCcm9hZGNhc3QpIHtcbiAgICBjb25zdCBjYWxjdWxhdGVkU2hhcGUgPSBCcm9hZGNhc3RVdGlsLmNhbGNTaGFwZShpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmRpbXMsIGZhbHNlKTtcbiAgICBpZiAoIWNhbGN1bGF0ZWRTaGFwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgcGVyZm9ybSBiaW5hcnkgb3Agb24gdGhlIGdpdmVuIHRlbnNvcnNcIik7XG4gICAgfVxuICAgIG91dHB1dFNoYXBlID0gY2FsY3VsYXRlZFNoYXBlO1xuICAgIGNvbnN0IG91dHB1dFJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgYVJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDAgPyBpbnB1dHNbMF0uZGltcy5sZW5ndGggOiAxO1xuICAgIGNvbnN0IGJSYW5rID0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSAwID8gaW5wdXRzWzFdLmRpbXMubGVuZ3RoIDogMTtcbiAgICBjb25zdCBhQmNhc3QgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDAgPyAnYmNhc3RJbmRpY2VzX0EoaW5kaWNlcywgYWluZGljZXMpOycgOiAnYWluZGljZXNbMF0gPSAwOyc7XG4gICAgY29uc3QgYkJjYXN0ID0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSAwID8gJ2JjYXN0SW5kaWNlc19CKGluZGljZXMsIGJpbmRpY2VzKTsnIDogJ2JpbmRpY2VzWzBdID0gMDsnO1xuXG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IHVzZVBhY2tlZFRleHR1cmVcbiAgICAgID8gYFxuICAgICAgJHtnbHNsRnVuYy5ib2R5fVxuICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICB2ZWM0IGEgPSBnZXRBQXRPdXRDb29yZHMoKTtcbiAgICAgICAgdmVjNCBiID0gZ2V0QkF0T3V0Q29vcmRzKCk7XG4gICAgICAgIHZlYzQgcmVzdWx0ID0gJHtnbHNsRnVuYy5uYW1lfShhLCBiKTtcbiAgICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgICB9YFxuICAgICAgOiBgXG4gICAgICAke2dsc2xGdW5jLmJvZHl9XG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7b3V0cHV0UmFua31dKSB7XG4gICAgICAgIGludCBhaW5kaWNlc1ske2FSYW5rfV07XG4gICAgICAgIGludCBiaW5kaWNlc1ske2JSYW5rfV07XG4gICAgICAgICR7YUJjYXN0fVxuICAgICAgICAke2JCY2FzdH1cbiAgICAgICAgcmV0dXJuICR7Z2xzbEZ1bmMubmFtZX0oX0EoYWluZGljZXMpLCBfQihiaW5kaWNlcykpO1xuICAgICAgfWA7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogZ2xzbEZ1bmMubmFtZSxcbiAgICAgIGlucHV0TmFtZXM6IFsnQScsICdCJ10sXG4gICAgICBpbnB1dFR5cGVzOiBbdGV4dHVyZVR5cGUsIHRleHR1cmVUeXBlXSxcbiAgICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogb3V0cHV0VGVuc29yVHlwZSwgdGV4dHVyZVR5cGUgfSxcbiAgICAgIHNoYWRlclNvdXJjZSxcbiAgICAgIGhhc01haW46IHVzZVBhY2tlZFRleHR1cmUsXG4gICAgfTtcbiAgfVxuICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAke2dsc2xGdW5jLmJvZHl9XG4gICAgdm9pZCBtYWluKCkge1xuICAgICAgdmVjNCB2MSA9ICR7Z2xzbC50ZXh0dXJlMkR9KEEsIFRleENvb3Jkcyk7XG4gICAgICB2ZWM0IHYyID0gJHtnbHNsLnRleHR1cmUyRH0oQiwgVGV4Q29vcmRzKTtcbiAgICAgIHZlYzQgcmVzdWx0ID0gJHtnbHNsRnVuYy5uYW1lfSh2MSwgdjIpO1xuICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgfVxuICAgIGA7XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBnbHNsRnVuYy5uYW1lLFxuICAgIGlucHV0TmFtZXM6IFsnQScsICdCJ10sXG4gICAgaW5wdXRUeXBlczogW3RleHR1cmVUeXBlLCB0ZXh0dXJlVHlwZV0sXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0c1swXS5kaW1zLCB0eXBlOiBvdXRwdXRUZW5zb3JUeXBlLCB0ZXh0dXJlVHlwZSB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGFkZCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbEFkZCgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBhbmQgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xBbmQoKSwgJ2Jvb2wnKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBkaXYgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xEaXYoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgZXF1YWwgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xFcXVhbCgpLCAnYm9vbCcpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGdyZWF0ZXIgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xHcmVhdGVyKCksICdib29sJyksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgbGVzcyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbExlc3MoKSwgJ2Jvb2wnKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBtdWwgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xNdWwoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3Qgb3IgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xPcigpLCAnYm9vbCcpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHBvdyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbFBvdygpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBwUmVsdSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbFBSZWx1KCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHN1YiA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbFN1YigpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCB4b3IgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xYb3IoKSwgJ2Jvb2wnKSwgaW5wdXRzKSxcbl07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgUHJvdG9VdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCBjYXN0OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFRlbnNvci5EYXRhVHlwZT4gPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgdG86IFRlbnNvci5EYXRhVHlwZSxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgcmV0dXJuIFtoYW5kbGVyLmNhc3QoaW5wdXRzWzBdLCB0byldO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ2FzdEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VGVuc29yLkRhdGFUeXBlPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogVGVuc29yLkRhdGFUeXBlID0+XG4gIFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byhub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCd0bycpKTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYXN0IHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29vcmRzRGF0YVR5cGUsIGdldEdsQ2hhbm5lbHMgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IENvbmNhdEF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbmNhdCc7XG5pbXBvcnQgeyBnZXRDaGFubmVscywgdW5wYWNrRnJvbUNoYW5uZWwgfSBmcm9tICcuL3BhY2tpbmctdXRpbHMnO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtTWV0YWRhdGEgPSAoaW5wdXRDb3VudDogbnVtYmVyLCBjYWNoZUhpbnQ6IHN0cmluZykgPT4gKHtcbiAgbmFtZTogJ0NvbmNhdCAocGFja2VkKScsXG4gIGlucHV0TmFtZXM6IEFycmF5LmZyb20oeyBsZW5ndGg6IGlucHV0Q291bnQgfSwgKF92LCBpKSA9PiBgWCR7aX1gKSxcbiAgaW5wdXRUeXBlczogQXJyYXkoaW5wdXRDb3VudCkuZmlsbChUZXh0dXJlVHlwZS5wYWNrZWQpLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm8gPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhpczogbnVtYmVyLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgaWYgKGF4aXMgPj0gaW5wdXRTaGFwZS5sZW5ndGggfHwgYXhpcyA8IC0xICogaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJheGlzIHNwZWNpZmllZCBmb3IgY29uY2F0IGRvZXNuJ3QgbWF0Y2ggaW5wdXQgZGltZW5zaW9uYWxpdHlcIik7XG4gIH1cbiAgaWYgKGF4aXMgPCAwKSB7XG4gICAgYXhpcyA9IGlucHV0U2hhcGUubGVuZ3RoICsgYXhpcztcbiAgfVxuICAvLyBlbnN1cmUgYWxsIG9mIHRoZSBub24tY29uY2F0ZW5hdGVkIGF4ZXMgbWF0Y2ggZWFjaCBvdGhlclxuICAvLyBjYWxjdWxhdGUgdGhlIHNoYXBlIG9mIHRoZSBvdXRwdXQgdGVuc29yIHdoaWxlIHdlIGRvIHRoYXRcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNoYXBlLnNsaWNlKDApO1xuICBmb3IgKGxldCBpID0gMTsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGRhdGFOU2hhcGUgPSBpbnB1dHNbaV0uZGltcy5zbGljZSgpO1xuICAgIGZvciAobGV0IGF4aXNJbmRleCA9IDA7IGF4aXNJbmRleCA8IGlucHV0U2hhcGUubGVuZ3RoOyBheGlzSW5kZXgrKykge1xuICAgICAgLy8gYWRkIHRvIHRoZSBwbGFjZWhvbGRlciBmb3IgY29tcHV0aW5nIG91dHB1dCBzaGFwZVxuICAgICAgaWYgKGF4aXNJbmRleCA9PT0gYXhpcykge1xuICAgICAgICBvdXRwdXRTaGFwZVtheGlzXSArPSBkYXRhTlNoYXBlW2F4aXNJbmRleF07XG4gICAgICB9XG4gICAgICAvLyBlbnN1cmUgYWxsIG5vbi1jYW5jYXRlbmF0ZWQgYXhlcyBtYXRjaCBlYWNoIG90aGVyXG4gICAgICBlbHNlIGlmIChpbnB1dFNoYXBlW2F4aXNJbmRleF0gIT09IGRhdGFOU2hhcGVbYXhpc0luZGV4XSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vbiBjb25jYXQgZGltZW5zaW9ucyBtdXN0IG1hdGNoJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgY29vcmRzID0gZ2V0Q2hhbm5lbHMoJ2Nvb3JkcycsIHJhbmspO1xuICBjb25zdCBkdHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKHJhbmspO1xuICBjb25zdCB1bnBhY2tDaGFubmVsID0gdW5wYWNrRnJvbUNoYW5uZWwoKTtcblxuICBjb25zdCBzaGFwZXMgPSBpbnB1dHMubWFwKChpKSA9PiBpLmRpbXMpO1xuICBjb25zdCBjaGFubmVscyA9IGdldEdsQ2hhbm5lbHMocmFuayk7XG4gIGNvbnN0IG9mZnNldHM6IG51bWJlcltdID0gbmV3IEFycmF5KHNoYXBlcy5sZW5ndGggLSAxKTtcblxuICBvZmZzZXRzWzBdID0gc2hhcGVzWzBdW2F4aXNdO1xuICBmb3IgKGxldCBpID0gMTsgaSA8IG9mZnNldHMubGVuZ3RoOyBpKyspIHtcbiAgICBvZmZzZXRzW2ldID0gb2Zmc2V0c1tpIC0gMV0gKyBzaGFwZXNbaV1bYXhpc107XG4gIH1cblxuICBjb25zdCBjaGFubmVsID0gY2hhbm5lbHNbYXhpc107XG4gIGNvbnN0IGxhc3RDaGFubmVscyA9IGNoYW5uZWxzLnNsaWNlKC0yKTtcbiAgY29uc3QgYWxsQ2hhbm5lbHMgPSBjaGFubmVscy5qb2luKCk7XG5cbiAgbGV0IGdldFZhbHVlU25pcHBldCA9IGBpZiAoJHtjaGFubmVsfSA8ICR7b2Zmc2V0c1swXX0pIHtcbiAgICAgICAgcmV0dXJuIGdldENoYW5uZWwoXG4gICAgICAgICAgICBnZXRYMCgke2FsbENoYW5uZWxzfSksIHZlYzIoJHtsYXN0Q2hhbm5lbHMuam9pbigpfSkpO1xuICAgICAgICB9YDtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBvZmZzZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgc2hpZnQgPSBvZmZzZXRzW2kgLSAxXTtcbiAgICBnZXRWYWx1ZVNuaXBwZXQgKz0gYFxuICAgICAgICAgICAgaWYgKCR7Y2hhbm5lbH0gPCAke29mZnNldHNbaV19ICAmJiAke2NoYW5uZWx9ID49ICR7b2Zmc2V0c1tpIC0gMV19KSB7XG4gICAgICAgICAgICAgIHJldHVybiBnZXRDaGFubmVsKFxuICAgICAgICAgICAgICAgIGdldFgke2l9KCR7Z2V0U2hpZnRlZENoYW5uZWxzU25pcHBldChjaGFubmVscywgY2hhbm5lbCwgc2hpZnQpfSksXG4gICAgICAgICAgICAgICAgdmVjMigke2dldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQobGFzdENoYW5uZWxzLCBjaGFubmVsLCBzaGlmdCl9KSk7XG4gICAgICAgICAgICB9YDtcbiAgfVxuICBjb25zdCBsYXN0SW5kZXggPSBvZmZzZXRzLmxlbmd0aDtcbiAgY29uc3Qgc2hpZnQgPSBvZmZzZXRzW29mZnNldHMubGVuZ3RoIC0gMV07XG4gIGdldFZhbHVlU25pcHBldCArPSBgXG4gICAgICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChcbiAgICAgICAgICAgICAgZ2V0WCR7bGFzdEluZGV4fSgke2dldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQoY2hhbm5lbHMsIGNoYW5uZWwsIHNoaWZ0KX0pLFxuICAgICAgICAgICAgICB2ZWMyKCR7Z2V0U2hpZnRlZENoYW5uZWxzU25pcHBldChsYXN0Q2hhbm5lbHMsIGNoYW5uZWwsIHNoaWZ0KX0pKTtgO1xuXG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICAgJHt1bnBhY2tDaGFubmVsfVxuICAgICAgICAgIGZsb2F0IGdldFZhbHVlKCR7Y2hhbm5lbHMubWFwKCh4KSA9PiAnaW50ICcgKyB4KX0pIHtcbiAgICAgICAgICAgICR7Z2V0VmFsdWVTbmlwcGV0fVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgICAgICR7ZHR5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAgICAgICAgICAgaW50IGxhc3REaW0gPSBjb29yZHMuJHtjaGFubmVsc1tyYW5rIC0gMV19O1xuICAgICAgICAgICAgY29vcmRzLiR7Y2hhbm5lbHNbcmFuayAtIDFdfSA9IGNvb3Jkcy4ke2NoYW5uZWxzW3JhbmsgLSAyXX07XG4gICAgICAgICAgICBjb29yZHMuJHtjaGFubmVsc1tyYW5rIC0gMl19ID0gbGFzdERpbTtcblxuICAgICAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KGdldFZhbHVlKCR7Y29vcmRzfSksIDAuLCAwLiwgMC4pO1xuXG4gICAgICAgICAgICAke2Nvb3Jkc1tyYW5rIC0gMV19ID0gJHtjb29yZHNbcmFuayAtIDFdfSArIDE7XG4gICAgICAgICAgICBpZiAoJHtjb29yZHNbcmFuayAtIDFdfSA8ICR7b3V0cHV0U2hhcGVbcmFuayAtIDFdfSkge1xuICAgICAgICAgICAgICByZXN1bHQuZyA9IGdldFZhbHVlKCR7Y29vcmRzfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICR7Y29vcmRzW3JhbmsgLSAyXX0gPSAke2Nvb3Jkc1tyYW5rIC0gMl19ICsgMTtcbiAgICAgICAgICAgIGlmICgke2Nvb3Jkc1tyYW5rIC0gMl19IDwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMl19KSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5hID0gZ2V0VmFsdWUoJHtjb29yZHN9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgJHtjb29yZHNbcmFuayAtIDFdfSA9ICR7Y29vcmRzW3JhbmsgLSAxXX0gLSAxO1xuICAgICAgICAgICAgaWYgKCR7Y29vcmRzW3JhbmsgLSAyXX0gPCAke291dHB1dFNoYXBlW3JhbmsgLSAyXX0gJiZcbiAgICAgICAgICAgICAgICAke2Nvb3Jkc1tyYW5rIC0gMV19IDwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMV19KSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5iID0gZ2V0VmFsdWUoJHtjb29yZHN9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcblxuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb25jYXRBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgYXR0cmlidXRlcy5heGlzKSB9O1xufTtcblxuY29uc3QgZ2V0U2hpZnRlZENoYW5uZWxzU25pcHBldCA9IChjaGFubmVsczogc3RyaW5nW10sIGNoYW5uZWw6IHN0cmluZywgc2hpZnQ6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGNoYW5uZWxJZHggPSBjaGFubmVscy5pbmRleE9mKGNoYW5uZWwpO1xuICBjb25zdCByZXMgPSBjaGFubmVscy5tYXAoKGMsIGlkeCkgPT4ge1xuICAgIGlmIChpZHggPT09IGNoYW5uZWxJZHgpIHtcbiAgICAgIHJldHVybiBgJHtjfSAtICR7c2hpZnR9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGM7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlcy5qb2luKCk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL2NvbmNhdC1wYWNrZWQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbmNhdEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBjb25jYXQ6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29uY2F0QXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29uY2F0QXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgaWYgKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5wYWNrICYmIGlucHV0c1swXS5kaW1zLmxlbmd0aCA+IDEpIHtcbiAgICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgIGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gICAgICBpbnB1dHMsXG4gICAgKTtcbiAgICByZXR1cm4gW291dHB1dF07XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gICAgICBpbnB1dHMsXG4gICAgKTtcbiAgICByZXR1cm4gW291dHB1dF07XG4gIH1cbn07XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbU1ldGFkYXRhID0gKGlucHV0Q291bnQ6IG51bWJlciwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdDb25jYXQnLFxuICBpbnB1dE5hbWVzOiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBpbnB1dENvdW50IH0sIChfdiwgaSkgPT4gYFgke2l9YCksXG4gIGlucHV0VHlwZXM6IEFycmF5KGlucHV0Q291bnQpLmZpbGwoVGV4dHVyZVR5cGUudW5wYWNrZWQpLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtSW5mbyA9IChcbiAgX2hhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhpczogbnVtYmVyLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgaWYgKGF4aXMgPj0gaW5wdXRTaGFwZS5sZW5ndGggfHwgYXhpcyA8IC0xICogaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJheGlzIHNwZWNpZmllZCBmb3IgY29uY2F0IGRvZXNuJ3QgbWF0Y2ggaW5wdXQgZGltZW5zaW9uYWxpdHlcIik7XG4gIH1cbiAgaWYgKGF4aXMgPCAwKSB7XG4gICAgYXhpcyA9IGlucHV0U2hhcGUubGVuZ3RoICsgYXhpcztcbiAgfVxuICAvLyBlbnN1cmUgYWxsIG9mIHRoZSBub24tY29uY2F0ZW5hdGVkIGF4ZXMgbWF0Y2ggZWFjaCBvdGhlclxuICAvLyBjYWxjdWxhdGUgdGhlIHNoYXBlIG9mIHRoZSBvdXRwdXQgdGVuc29yIHdoaWxlIHdlIGRvIHRoYXRcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNoYXBlLnNsaWNlKDApO1xuICBmb3IgKGxldCBpID0gMTsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGRhdGFOU2hhcGUgPSBpbnB1dHNbaV0uZGltcy5zbGljZSgpO1xuICAgIGZvciAobGV0IGF4aXNJbmRleCA9IDA7IGF4aXNJbmRleCA8IGlucHV0U2hhcGUubGVuZ3RoOyBheGlzSW5kZXgrKykge1xuICAgICAgLy8gYWRkIHRvIHRoZSBwbGFjZWhvbGRlciBmb3IgY29tcHV0aW5nIG91dHB1dCBzaGFwZVxuICAgICAgaWYgKGF4aXNJbmRleCA9PT0gYXhpcykge1xuICAgICAgICBvdXRwdXRTaGFwZVtheGlzXSArPSBkYXRhTlNoYXBlW2F4aXNJbmRleF07XG4gICAgICB9XG4gICAgICAvLyBlbnN1cmUgYWxsIG5vbi1jYW5jYXRlbmF0ZWQgYXhlcyBtYXRjaCBlYWNoIG90aGVyXG4gICAgICBlbHNlIGlmIChpbnB1dFNoYXBlW2F4aXNJbmRleF0gIT09IGRhdGFOU2hhcGVbYXhpc0luZGV4XSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vbiBjb25jYXQgZGltZW5zaW9ucyBtdXN0IG1hdGNoJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcblxuICBjb25zdCBzaXplSW5Db25jYXRBeGlzID0gbmV3IEFycmF5PG51bWJlcj4oaW5wdXRzLmxlbmd0aCk7XG4gIGxldCBwcmV2aW91c1N1bSA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZUluQ29uY2F0QXhpcy5sZW5ndGg7ICsraSkge1xuICAgIHByZXZpb3VzU3VtICs9IGlucHV0c1tpXS5kaW1zW2F4aXNdO1xuICAgIHNpemVJbkNvbmNhdEF4aXNbaV0gPSBwcmV2aW91c1N1bTtcbiAgfVxuXG4gIGxldCBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTWV0aG9kID0gJyc7XG4gIC8vIGluIG1vc3QgY2FzZXMgbGluZWFyIHNlYXJjaCBpcyBzdWZmaWNpZW50LCBhcyBpbiBtb3N0IHNjZW5hcmlvcywgb25seSAyIHRlbnNvcnMgYXJlIGNvbmNhdGVuYXRlZFxuICBpZiAoaW5wdXRzLmxlbmd0aCA8IDUpIHtcbiAgICBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTWV0aG9kID0gZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc0xpbmVhclNlYXJjaChzaXplSW5Db25jYXRBeGlzKTtcbiAgfSBlbHNlIHtcbiAgICBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTWV0aG9kID0gZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc0JpbmFyeVNlYXJjaChzaXplSW5Db25jYXRBeGlzKTtcbiAgfVxuXG4gIGNvbnN0IGZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZU1ldGhvZCA9IGdldEZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZU1ldGhvZChpbnB1dHMubGVuZ3RoLCByYW5rKTtcbiAgY29uc3QgZ2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4TWV0aG9kID0gZ2V0R2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4TWV0aG9kKHNpemVJbkNvbmNhdEF4aXMpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICR7ZmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlTWV0aG9kfVxuICAgICAgICAke2dldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleE1ldGhvZH1cbiAgICAgICAgJHtnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTWV0aG9kfVxuICAgICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IHRleHR1cmVJbmRleCA9IGdldFRleHR1cmVXaGVyZURhdGFSZXNpZGVzIChpbmRpY2VzWyR7YXhpc31dKTtcblxuICAgICAgICAgIGlmKHRleHR1cmVJbmRleCAhPSAwKSB7XG4gICAgICAgICAgICBpbmRpY2VzWyR7YXhpc31dID0gaW5kaWNlc1ske2F4aXN9XSAtIGludChnZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXgodGV4dHVyZUluZGV4LWludCgxKSkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBmZXRjaERhdGFGcm9tQ29ycmVjdFRleHR1cmUodGV4dHVyZUluZGV4LCBpbmRpY2VzKTtcbiAgICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb25jYXRBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGgsIGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICByZXR1cm4geyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1JbmZvKGhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGF0dHJpYnV0ZXMuYXhpcykgfTtcbn07XG5cbmNvbnN0IGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNMaW5lYXJTZWFyY2ggPSAoc2l6ZUluQ29uY2F0QXhpczogbnVtYmVyW10pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBzZWFyY2hBeGlzID0gc2l6ZUluQ29uY2F0QXhpcy5tYXAoXG4gICAgKHNpemUsIGkpID0+IGBpZihpbmRleDwke3NpemV9KSB7cmV0dXJuICR7aX07fVxuYCxcbiAgKTtcbiAgcmV0dXJuIGBpbnQgZ2V0VGV4dHVyZVdoZXJlRGF0YVJlc2lkZXMoaW50IGluZGV4KSB7XG4gICAgICAke3NlYXJjaEF4aXMuam9pbignJyl9XG4gICAgfWA7XG59O1xuXG4vLyBUT0RPOiBJbXBsZW1lbnQgQmluYXJ5U2VhcmNoIGluIEdMU0xcbmNvbnN0IGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNCaW5hcnlTZWFyY2ggPSAoc2l6ZUluQ29uY2F0QXhpczogbnVtYmVyW10pOiBzdHJpbmcgPT5cbiAgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc0xpbmVhclNlYXJjaChzaXplSW5Db25jYXRBeGlzKTtcblxuY29uc3QgZ2V0RmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlTWV0aG9kID0gKG51bWJlck9mVGVuc29yczogbnVtYmVyLCB0ZW5zb3JSYW5rOiBudW1iZXIpID0+IHtcbiAgY29uc3QgY29kZUxpbmVzOiBzdHJpbmdbXSA9IFtgZmxvYXQgZmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlKGludCB0ZXh0dXJlSW5kZXgsIGludCBpbmRpY2VzWyR7dGVuc29yUmFua31dKSB7YF07XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZUZW5zb3JzOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyBgaWYgKHRleHR1cmVJbmRleCA9PSAke2l9KSB7IHJldHVybiBfWCR7aX0oaW5kaWNlcyk7IH1gKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IG51bWJlck9mVGVuc29ycyAtIDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGVsc2UgeyByZXR1cm4gX1gke2l9KGluZGljZXMpOyB9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGVsc2UgaWYgKHRleHR1cmVJbmRleCA9PSAke2l9KSB7IHJldHVybiBfWCR7aX0oaW5kaWNlcyk7IH1gKTtcbiAgICB9XG4gIH1cbiAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyAnfScpO1xuICByZXR1cm4gY29kZUxpbmVzLmpvaW4oJ1xcbicpO1xufTtcblxuY29uc3QgZ2V0R2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4TWV0aG9kID0gKHNpemVJbkNvbmNhdEF4aXM6IG51bWJlcltdKTogc3RyaW5nID0+IHtcbiAgY29uc3QgY29kZUxpbmVzOiBzdHJpbmdbXSA9IFsnaW50IGdldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleChpbnQgaW5kZXgpIHsnXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplSW5Db25jYXRBeGlzLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGlmIChpbmRleCA9PSAke2l9KSB7IHJldHVybiAke3NpemVJbkNvbmNhdEF4aXNbaV19OyB9YCk7XG4gICAgfSBlbHNlIGlmIChpID09PSBzaXplSW5Db25jYXRBeGlzLmxlbmd0aCAtIDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGVsc2UgeyByZXR1cm4gJHtzaXplSW5Db25jYXRBeGlzW2ldfTsgfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBlbHNlIGlmIChpbmRleCA9PSAke2l9KSB7IHJldHVybiAke3NpemVJbkNvbmNhdEF4aXNbaV19OyB9YCk7XG4gICAgfVxuICB9XG4gIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgJ30nKTtcblxuICByZXR1cm4gY29kZUxpbmVzLmpvaW4oJ1xcbicpO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ29uY2F0QXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxDb25jYXRBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogQ29uY2F0QXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGlzOiBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdheGlzJykgfSk7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3RvbyBmZXcgaW5wdXRzJyk7XG4gIH1cblxuICBjb25zdCBpbnB1dFR5cGUgPSBpbnB1dHNbMF0udHlwZTtcbiAgY29uc3QgaW5wdXREaW1lbnNpb25hbGl0eSA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcblxuICAvLyBUT0RPOiBTdXBwb3J0IHN0cmluZyBjb25jYXRcbiAgaWYgKGlucHV0VHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0cmluZyB0ZW5zb3IgaXMgbm90IHN1cHBvcnRlZCB5ZXQnKTtcbiAgfVxuXG4gIGZvciAoY29uc3QgaW5wdXQgb2YgaW5wdXRzKSB7XG4gICAgLy8gbWFrZSBzdXJlIHR5cGVzIG9mIGFsbCBpbnB1dHMgbWF0Y2hcbiAgICBpZiAoaW5wdXQudHlwZSAhPT0gaW5wdXRUeXBlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHRlbnNvcnMgc2hvdWxkIGJlIG9uZSB0eXBlJyk7XG4gICAgfVxuXG4gICAgLy8gbWFrZSBzdXJlIHRoZSBkaW1lbnNpb25hbGl0eSBvZiBhbGwgaW5wdXRzIGFyZSB0aGUgc2FtZVxuICAgIGlmIChpbnB1dC5kaW1zLmxlbmd0aCAhPT0gaW5wdXREaW1lbnNpb25hbGl0eSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCB0ZW5zb3JzIHNob3VsZCBoYXZlIHRoZSBzYW1lIHNoYXBlJyk7XG4gICAgfVxuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBNQVhfQ0xJUCwgTUlOX0NMSVAgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IEZ1bmN0aW9uVHlwZSwgR2xzbFZhbHVlRnVuY3Rpb24gfSBmcm9tICcuLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQWJzKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2FicycpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBY29zKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2Fjb3MnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQXNpbigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdhc2luJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEF0YW4oKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnYXRhbicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xDZWlsKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2NlaWwnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQ29zKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2NvcycpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xFbHUoYWxwaGE6IG51bWJlcik6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdlbHUnO1xuICBjb25zdCBib2R5ID0gYFxuICBjb25zdCBmbG9hdCBhbHBoYSA9IGZsb2F0KCR7YWxwaGF9KTtcblxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGEgPj0gMC4wID8gYTogKGV4cChhKSAtIDEuMCkgKiBhbHBoYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiB2ZWM0KCR7bmFtZX1fKHYueCksICR7bmFtZX1fKHYueSksICR7bmFtZX1fKHYueiksICR7bmFtZX1fKHYudykpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEV4cCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdleHAnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsRmxvb3IoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnZmxvb3InKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQ2xpcChtaW46IG51bWJlciwgbWF4OiBudW1iZXIpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnY2xpcCc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGNvbnN0IGZsb2F0IG1pbiA9IGZsb2F0KCR7bWlufSk7XG4gIGNvbnN0IGZsb2F0IG1heCA9IGZsb2F0KCR7bWF4fSk7XG5cbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBjbGFtcChhLCBtaW4sIG1heCk7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gY2xhbXAodiwgbWluLCBtYXgpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbElkZW50aXR5KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdpbmRlbnRpdHknO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGE7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gdjtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xMZWFreVJlbHUoYWxwaGE6IG51bWJlcik6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdsZWFreVJlbHUnO1xuICBjb25zdCBib2R5ID0gYFxuICBjb25zdCBmbG9hdCBhbHBoYSA9IGZsb2F0KCR7YWxwaGF9KTtcblxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGEgPCAwLjAgPyBhICogYWxwaGEgOiBhO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIHZlYzQoJHtuYW1lfV8odi54KSwgJHtuYW1lfV8odi55KSwgJHtuYW1lfV8odi56KSwgJHtuYW1lfV8odi53KSk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTG9nKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2xvZycpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xOZWcoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ25lZyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gLWE7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gLXY7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTm90KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdub3QnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGZsb2F0KCAhIGJvb2woYSkgKTtcbiAgfVxuICBib29sICR7bmFtZX1fKGJvb2wgYSkge1xuICAgIHJldHVybiAhYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiB2ZWM0KCFib29sKHYueCksICFib29sKHYueSksICFib29sKHYueiksICFib29sKHYudykpO1xuICB9XG4gIGJ2ZWM0ICR7bmFtZX1fKGJ2ZWM0IHYpIHtcbiAgICByZXR1cm4gYnZlYzQoIXYueCwgIXYueSwgIXYueiwgIXYudyk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsU2luKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ3NpbicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xSZWx1KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdyZWx1JztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBtYXgoIGEsIDAuMCApO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIG1heCggdiwgMC4wICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsU2lnbW9pZCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnc2lnbW9pZCc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gMS4wIC8gKDEuMCArIGV4cCgtYSkpO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIDEuMCAvICgxLjAgKyBleHAoLXYpKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xTcXJ0KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ3NxcnQnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsVGFuKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ3RhbicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xUYW5oKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICd0YW5oJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIGEgPSBjbGFtcChhLCAtMTAuLCAxMC4pO1xuICAgIGEgPSBleHAoMi4qYSk7XG4gICAgcmV0dXJuIChhIC0gMS4pIC8gKGEgKyAxLik7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICB2ID0gY2xhbXAodiwgLTEwLiwgMTAuKTtcbiAgICB2ID0gZXhwKDIuKnYpO1xuICAgIHJldHVybiAodiAtIDEuKSAvICh2ICsgMS4pO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5mdW5jdGlvbiBnbHNsQnVpbHRpblVuYXJ5KG5hbWU6IHN0cmluZyk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiAke25hbWV9KGEpO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuICR7bmFtZX0odik7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cblxuLy8vLy9cbi8vLy8vXG4vLy8vL1xuXG5jb25zdCBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGdsc2xGdW5jOiBHbHNsVmFsdWVGdW5jdGlvbixcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgdGV4dHVyZVR5cGUgPSBoYW5kbGVyLnNlc3Npb24ucGFjayA/IFRleHR1cmVUeXBlLnBhY2tlZCA6IFRleHR1cmVUeXBlLnVucGFja2VkO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0LmRpbXMsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlIH0sXG4gICAgc2hhZGVyU291cmNlOiBgXG4gICAgICR7Z2xzbEZ1bmMuYm9keX1cbiAgICAgdm9pZCBtYWluKCkge1xuICAgICAgIHZlYzQgdiA9ICR7Z2xzbC50ZXh0dXJlMkR9KEEsIFRleENvb3Jkcyk7XG4gICAgICAgdiA9ICR7Z2xzbEZ1bmMubmFtZX1fKHYpO1xuICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdjtcbiAgICAgfVxuICAgICBgLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGdsc2xGdW5jOiBHbHNsVmFsdWVGdW5jdGlvbixcbiAgY2FjaGVLZXk/OiBzdHJpbmcsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IHRleHR1cmVUeXBlID0gaGFuZGxlci5zZXNzaW9uLnBhY2sgPyBUZXh0dXJlVHlwZS5wYWNrZWQgOiBUZXh0dXJlVHlwZS51bnBhY2tlZDtcbiAgY29uc3QgbWV0YWRhdGEgPSB7IG5hbWU6IGdsc2xGdW5jLm5hbWUsIGlucHV0VHlwZXM6IFt0ZXh0dXJlVHlwZV0sIGlucHV0TmFtZXM6IFsnQSddLCBjYWNoZUhpbnQ6IGNhY2hlS2V5IH07XG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0LCBnbHNsRnVuYykgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBhYnMgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbEFicygpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBhY29zID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBY29zKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGFzaW4gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbEFzaW4oKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgYXRhbiA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQXRhbigpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xpcEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBtaW46IG51bWJlcjtcbiAgcmVhZG9ubHkgbWF4OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBjbGlwID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQ2xpcEF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoXG4gICAgICBoYW5kbGVyLFxuICAgICAgaW5wdXRzWzBdLFxuICAgICAgZ2xzbENsaXAoYXR0cmlidXRlcy5taW4sIGF0dHJpYnV0ZXMubWF4KSxcbiAgICAgIGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgKSxcbiAgICBpbnB1dHMsXG4gICksXG5dO1xuXG5leHBvcnQgY29uc3QgcGFyc2VDbGlwQXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlKTogQ2xpcEF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBtaW46IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnbWluJywgTUlOX0NMSVApLFxuICAgIG1heDogbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtYXgnLCBNQVhfQ0xJUCksXG4gIH0pO1xuXG5leHBvcnQgY29uc3QgY2xpcFYxMSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSBnZW5lcmF0ZUNsaXBBdHRyaWJ1dGVzRnJvbUlucHV0cyhoYW5kbGVyLCBpbnB1dHMpO1xuICByZXR1cm4gY2xpcChoYW5kbGVyLCBbaW5wdXRzWzBdXSwgYXR0cmlidXRlcyk7XG59O1xuXG5jb25zdCBnZW5lcmF0ZUNsaXBBdHRyaWJ1dGVzRnJvbUlucHV0cyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBDbGlwQXR0cmlidXRlcyA9PiB7XG4gIGlmIChcbiAgICBpbnB1dHMubGVuZ3RoID49IDMgJiZcbiAgICAoIWhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1sxXS5kYXRhSWQpIHx8ICFoYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMl0uZGF0YUlkKSlcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkeW5hbWljIGNsaXAgYXR0cmlidXRlcyBhcmUgbm90IGFsbG93ZWQnKTtcbiAgfVxuXG4gIGNvbnN0IG1pbiA9IGlucHV0cy5sZW5ndGggPj0gMyA/IGlucHV0c1sxXS5udW1iZXJEYXRhWzBdIDogTUlOX0NMSVA7XG4gIGNvbnN0IG1heCA9IGlucHV0cy5sZW5ndGggPj0gMyA/IGlucHV0c1syXS5udW1iZXJEYXRhWzBdIDogTUFYX0NMSVA7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBtaW4sIG1heCB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBjZWlsID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xDZWlsKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGNvcyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQ29zKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGludGVyZmFjZSBFbHVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYWxwaGE6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGVsdSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEVsdUF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsRWx1KGF0dHJpYnV0ZXMuYWxwaGEpLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KSxcbiAgICBpbnB1dHMsXG4gICksXG5dO1xuXG5leHBvcnQgY29uc3QgcGFyc2VFbHVBdHRyaWJ1dGVzID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBFbHVBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGFscGhhOiBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2FscGhhJywgMS4wKSB9KTtcblxuZXhwb3J0IGNvbnN0IGV4cCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsRXhwKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGZsb29yID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xGbG9vcigpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBpZGVudGl0eSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsSWRlbnRpdHkoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgaW50ZXJmYWNlIExlYWt5UmVsdUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBhbHBoYTogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgbGVha3lSZWx1ID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IExlYWt5UmVsdUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsTGVha3lSZWx1KGF0dHJpYnV0ZXMuYWxwaGEpLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KSxcbiAgICBpbnB1dHMsXG4gICksXG5dO1xuXG5leHBvcnQgY29uc3QgcGFyc2VMZWFreVJlbHVBdHRyaWJ1dGVzID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBMZWFreVJlbHVBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGFscGhhOiBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2FscGhhJywgMC4wMSkgfSk7XG5cbmV4cG9ydCBjb25zdCBsb2cgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbExvZygpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBuZWcgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbE5lZygpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBub3QgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbE5vdCgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCByZWx1ID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xSZWx1KCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHNpZ21vaWQgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFNpZ21vaWQoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3Qgc2luID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xTaW4oKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3Qgc3FydCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsU3FydCgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCB0YW4gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFRhbigpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCB0YW5oID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xUYW5oKCkpLCBpbnB1dHMpLFxuXTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlIH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlJztcbmltcG9ydCB7IE1BWF9DTElQLCBNSU5fQ0xJUCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgR2xzbFZhbHVlRnVuY3Rpb24gfSBmcm9tICcuLi9nbHNsLWRlZmluaXRpb25zJztcblxuaW1wb3J0IHsgZ2xzbENsaXAsIGdsc2xSZWx1LCBnbHNsU2lnbW9pZCB9IGZyb20gJy4vdW5hcnktb3AnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMge1xuICByZWFkb25seSBhY3RpdmF0aW9uOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNsaXBNaW4/OiBudW1iZXI7XG4gIHJlYWRvbmx5IGNsaXBNYXg/OiBudW1iZXI7XG4gIHJlYWRvbmx5IGFjdGl2YXRpb25DYWNoZUtleTogc3RyaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcykge1xuICBsZXQgZnVuYzogR2xzbFZhbHVlRnVuY3Rpb247XG4gIHN3aXRjaCAoYXR0cmlidXRlcy5hY3RpdmF0aW9uKSB7XG4gICAgY2FzZSAnUmVsdSc6XG4gICAgICBmdW5jID0gZ2xzbFJlbHUoKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ1NpZ21vaWQnOlxuICAgICAgZnVuYyA9IGdsc2xTaWdtb2lkKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdDbGlwJzpcbiAgICAgIGZ1bmMgPSBnbHNsQ2xpcChhdHRyaWJ1dGVzLmNsaXBNaW4hLCBhdHRyaWJ1dGVzLmNsaXBNYXghKTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIFRPRE86IGFkZGluZyBvdGhlciBhY3RpdmF0aW9ucyB0aGF0IGNhbiBiZSBmdXNlZC5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHsgYWN0aXZhdGlvbkZ1bmN0aW9uOiAnJywgYXBwbHlBY3RpdmF0aW9uOiAnJyB9O1xuICB9XG5cbiAgY29uc3QgYWN0aXZhdGlvbk5hbWUgPSBmdW5jLm5hbWU7XG4gIGNvbnN0IGFjdGl2YXRpb25GdW5jdGlvbiA9IGZ1bmMuYm9keTtcbiAgY29uc3QgYXBwbHlBY3RpdmF0aW9uID0gYHZhbHVlID0gJHthY3RpdmF0aW9uTmFtZX1fKHZhbHVlKTtgO1xuICByZXR1cm4geyBhY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbiB9O1xufVxuXG5leHBvcnQgY29uc3QgcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZSk6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhY3RpdmF0aW9uID0gYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2FjdGl2YXRpb24nLCAnJyk7XG5cbiAgaWYgKGFjdGl2YXRpb24gPT09ICdDbGlwJykge1xuICAgIGNvbnN0IFtjbGlwTWluLCBjbGlwTWF4XSA9IGF0dHJpYnV0ZXMuZ2V0RmxvYXRzKCdhY3RpdmF0aW9uX3BhcmFtcycsIFtNSU5fQ0xJUCwgTUFYX0NMSVBdKTtcbiAgICByZXR1cm4geyBhY3RpdmF0aW9uLCBjbGlwTWF4LCBjbGlwTWluLCBhY3RpdmF0aW9uQ2FjaGVLZXk6IGAke2FjdGl2YXRpb259OiR7Y2xpcE1pbn0sJHtjbGlwTWF4fWAgfTtcbiAgfVxuICByZXR1cm4geyBhY3RpdmF0aW9uLCBhY3RpdmF0aW9uQ2FjaGVLZXk6IGFjdGl2YXRpb24gfTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4uLy4uLy4uL2luc3RydW1lbnQnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNhbGN1bGF0ZU91dHB1dFNoYXBlLCBDb252QXR0cmlidXRlcyB9IGZyb20gJy4vY29udic7XG5pbXBvcnQgeyBnZXRBY3RpdmF0aW9uU25pcHBldCB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtTWV0YWRhdGEgPSAoaGFzQmlhczogYm9vbGVhbiwgY2FjaGVIaW50OiBzdHJpbmcpOiBQcm9ncmFtTWV0YWRhdGEgPT4gKHtcbiAgbmFtZTogJ0dyb3VwZWRDb252JyxcbiAgaW5wdXROYW1lczogaGFzQmlhcyA/IFsnWCcsICdXJywgJ0JpYXMnXSA6IFsnWCcsICdXJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXNcbiAgICA/IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXVxuICAgIDogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgY29uc3QgcHJvY2Vzc0JpYXMgPSBoYXNCaWFzID8gJ3ZhbHVlICs9IGdldEJpYXMob3V0cHV0X2NoYW5uZWwpOycgOiAnJztcbiAgY29uc3QgeFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3Qgd1NoYXBlID0gaW5wdXRzWzFdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3Qgb3V0cHV0Q2hhbm5lbHNQZXJHcm91cCA9IHdTaGFwZVswXSAvIGF0dHJpYnV0ZXMuZ3JvdXA7XG4gIExvZ2dlci52ZXJib3NlKFxuICAgICdHcm91cGVkQ29udicsXG4gICAgYGF1dHBQYWQ6JHthdHRyaWJ1dGVzLmF1dG9QYWR9LCBkaWxhdGlvbnM6JHthdHRyaWJ1dGVzLmRpbGF0aW9uc30sIGdyb3VwOiR7YXR0cmlidXRlcy5ncm91cH0sIGtlcm5lbFNoYXBlOiR7XG4gICAgICBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlXG4gICAgfSwgcGFkczoke2F0dHJpYnV0ZXMucGFkc30sIHN0cmlkZXM6JHthdHRyaWJ1dGVzLnN0cmlkZXN9YCxcbiAgKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVPdXRwdXRTaGFwZSh4U2hhcGUsIHdTaGFwZSwgYXR0cmlidXRlcy5kaWxhdGlvbnMsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy5zdHJpZGVzKTtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCB7IGFjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9uIH0gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhdHRyaWJ1dGVzKTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gIGNvbnN0IGl2ZWMyIHN0cmlkZXMgPSBpdmVjMigke2F0dHJpYnV0ZXMuc3RyaWRlc1swXX0sICR7YXR0cmlidXRlcy5zdHJpZGVzWzFdfSk7XG4gIGNvbnN0IGl2ZWMyIHBhZHMgPSBpdmVjMigke2F0dHJpYnV0ZXMucGFkc1swXX0sICR7YXR0cmlidXRlcy5wYWRzWzFdfSk7XG4gICR7YWN0aXZhdGlvbkZ1bmN0aW9ufVxuICB2b2lkIG1haW4oKSB7XG4gICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgaW50IGJhdGNoID0gY29vcmRzLng7XG4gICAgaW50IG91dHB1dF9jaGFubmVsID0gY29vcmRzLnk7XG4gICAgaXZlYzIgeFJDQ29ybmVyID0gY29vcmRzLnp3ICogc3RyaWRlcyAtIHBhZHM7XG4gICAgaW50IGdyb3VwX2lkID0gb3V0cHV0X2NoYW5uZWwgLyAke291dHB1dENoYW5uZWxzUGVyR3JvdXB9O1xuXG4gICAgZmxvYXQgdmFsdWUgPSAwLjA7XG4gICAgZm9yIChpbnQgd0luQ2hhbm5lbCA9IDA7IHdJbkNoYW5uZWwgPCAke3dTaGFwZVsxXX07IHdJbkNoYW5uZWwrKykge1xuICAgICAgaW50IGlucHV0X2NoYW5uZWwgPSBncm91cF9pZCAqICR7d1NoYXBlWzFdfSArIHdJbkNoYW5uZWw7XG4gICAgICBmb3IgKGludCB3SGVpZ2h0ID0gMDsgd0hlaWdodCA8ICR7d1NoYXBlWzJdfTsgd0hlaWdodCsrKSB7XG4gICAgICAgIGludCB4SGVpZ2h0ID0geFJDQ29ybmVyLnggKyB3SGVpZ2h0ICogJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1swXX07XG5cbiAgICAgICAgaWYgKHhIZWlnaHQgPCAwIHx8IHhIZWlnaHQgPj0gJHt4U2hhcGVbMl19KSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGludCB3V2lkdGggPSAwOyB3V2lkdGggPCAke3dTaGFwZVszXX07IHdXaWR0aCsrKSB7XG4gICAgICAgICAgaW50IHhXaWR0aCA9IHhSQ0Nvcm5lci55ICsgd1dpZHRoICogJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXX07XG4gICAgICAgICAgaWYgKHhXaWR0aCA8IDAgfHwgeFdpZHRoID49ICR7eFNoYXBlWzNdfSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZmxvYXQgeFZhbCA9IGdldFgoYmF0Y2gsIGlucHV0X2NoYW5uZWwsIHhXaWR0aCwgeEhlaWdodCk7XG4gICAgICAgICAgZmxvYXQgd1ZhbCA9IGdldFcob3V0cHV0X2NoYW5uZWwsIHdJbkNoYW5uZWwsIHdXaWR0aCwgd0hlaWdodCk7XG4gICAgICAgICAgdmFsdWUgKz0geFZhbCp3VmFsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgICR7cHJvY2Vzc0JpYXN9XG4gICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KHZhbHVlLCAuMCwgLjAsIC4wKTtcbiAgfVxuYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoID4gMiwgYXR0cmlidXRlcy5jYWNoZUtleSk7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBtZXRhZGF0YSwgYXR0cmlidXRlcyksXG4gIH07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbnYnO1xuaW1wb3J0IHsgdW5wYWNrRnJvbUNoYW5uZWwgfSBmcm9tICcuL3BhY2tpbmctdXRpbHMnO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtTWV0YWRhdGEgPSAoY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdJbTJDb2wgKHBhY2tlZCknLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICB4OiBUZW5zb3IsXG4gIHc6IFRlbnNvcixcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgeHNoYXBlID0geC5kaW1zO1xuICBjb25zdCB3c2hhcGUgPSB3LmRpbXM7XG4gIGNvbnN0IHJvd0RpbSA9IDI7XG4gIGNvbnN0IGNvbERpbSA9IDM7XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGltMmNvbFNoYXBlID0gW3dzaGFwZVsxXSAqIHdzaGFwZVsyXSAqIHdzaGFwZVszXSwgb3V0cHV0U2hhcGVbMl0gKiBvdXRwdXRTaGFwZVszXV07XG4gIGNvbnN0IGtlcm5lbFNpemUgPSB3c2hhcGVbMl0gKiB3c2hhcGVbM107XG4gIGNvbnN0IHVucGFja0NoYW5uZWwgPSB1bnBhY2tGcm9tQ2hhbm5lbCgpO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGxldCB1bnJvbGxlZCA9ICcnO1xuXG4gIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8PSAxOyByb3crKykge1xuICAgIGZvciAobGV0IGNvbCA9IDA7IGNvbCA8PSAxOyBjb2wrKykge1xuICAgICAgdW5yb2xsZWQgKz0gYFxuICAgICAgICAgICAgYmxvY2tJbmRleCA9IHJjLnggKyAke2NvbH07XG4gICAgICAgICAgICBwb3MgPSByYy55ICsgJHtyb3d9O1xuXG4gICAgICAgICAgICBpZihibG9ja0luZGV4IDwgJHtpbTJjb2xTaGFwZVsxXX0gJiYgcG9zIDwgJHtpbTJjb2xTaGFwZVswXX0pIHtcbiAgICAgICAgICAgICAgb2Zmc2V0WSA9IGludChibG9ja0luZGV4IC8gKCR7b3V0cHV0U2hhcGVbcmFuayAtIDFdfSkpICogJHthdHRyaWJ1dGVzLnN0cmlkZXNbMF19IC1cbiAgICAgICAgICAgICAgICAke2F0dHJpYnV0ZXMucGFkc1swXX07XG4gICAgICAgICAgICAgIGQwID0gb2Zmc2V0WSArICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMF19ICogKGltb2QocG9zLCAke2tlcm5lbFNpemV9KSAvICR7d3NoYXBlWzJdfSk7XG5cbiAgICAgICAgICAgICAgaWYoZDAgPCAke3hzaGFwZVtyb3dEaW1dfSAmJiBkMCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0WCA9IGltb2QoYmxvY2tJbmRleCwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMV19KSAqICR7YXR0cmlidXRlcy5zdHJpZGVzWzFdfSAtXG4gICAgICAgICAgICAgICAgICAke2F0dHJpYnV0ZXMucGFkc1sxXX07XG4gICAgICAgICAgICAgICAgZDEgPSBvZmZzZXRYICsgJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXX0gKiBpbW9kKGltb2QocG9zLCAke2tlcm5lbFNpemV9KSwgJHt3c2hhcGVbMl19KTtcblxuICAgICAgICAgICAgICAgIGlmKGQxIDwgJHt4c2hhcGVbY29sRGltXX0gJiYgZDEgPj0gMCkge1xuXG4gICAgICAgICAgICAgICAgICBjaCA9IGludChmbG9hdChwb3MpLyAke2tlcm5lbFNpemV9Lik7XG4gICAgICAgICAgICAgICAgICAgIGlubmVyRGltcyA9IHZlYzIoZDAsIGQxKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0WyR7cm93ICogMiArIGNvbH1dID0gZ2V0Q2hhbm5lbChcbiAgICAgICAgICAgICAgICAgICAgICBnZXRBKDAsIGNoLCBpbnQoaW5uZXJEaW1zLngpLFxuICAgICAgICAgICAgICAgICAgICAgIGludChpbm5lckRpbXMueSkpLCBpbm5lckRpbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgYDtcbiAgICB9XG4gIH1cblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke3VucGFja0NoYW5uZWx9XG5cbiAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgaXZlYzIgcmMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMC4wKTtcbiAgICAgICAgICBpbnQgYmxvY2tJbmRleCwgcG9zLCBvZmZzZXRZLCBkMCwgb2Zmc2V0WCwgZDEsIGNoO1xuICAgICAgICAgIHZlYzIgaW5uZXJEaW1zO1xuICAgICAgICAgICR7dW5yb2xsZWR9XG4gICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgICB9XG4gICAgICAgICAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbTJjb2xTaGFwZSwgdHlwZTogeC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgeDogVGVuc29yLFxuICB3OiBUZW5zb3IsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbU1ldGFkYXRhKGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIHgsIHcsIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKSxcbiAgfTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgQnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRDb29yZHNEYXRhVHlwZSwgZ2V0R2xDaGFubmVscyB9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHsgZ2V0QWN0aXZhdGlvblNuaXBwZXQsIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsIHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQgeyBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vbWF0bXVsLXBhY2snO1xuXG5leHBvcnQgY29uc3QgbWF0TXVsOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgaWYgKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5wYWNrKSB7XG4gICAgcmV0dXJuIFtpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW2luZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvTG9hZGVyKGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyldO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VNYXRNdWxBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyA9PiBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMobm9kZS5hdHRyaWJ1dGVzKTtcblxuY29uc3QgY3JlYXRlTWF0bXVsUHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnTWF0TXVsJyxcbiAgaW5wdXROYW1lczogaGFzQmlhcyA/IFsnQScsICdCJywgJ0JpYXMnXSA6IFsnQScsICdCJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXNcbiAgICA/IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXVxuICAgIDogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5mdW5jdGlvbiBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mbyhcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyB7XG4gIGNvbnN0IGFTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBiU2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBCcm9hZGNhc3RVdGlsLmNhbGNTaGFwZShhU2hhcGUsIGJTaGFwZSwgdHJ1ZSk7XG4gIGlmICghb3V0cHV0U2hhcGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCB1c2UgbWF0bXVsIG9uIHRoZSBnaXZlbiB0ZW5zb3JzXCIpO1xuICB9XG4gIGNvbnN0IGNvb3Jkc0RhdGFUeXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3QgYWxsR2xDaGFubmVscyA9IGdldEdsQ2hhbm5lbHMoKTtcbiAgY29uc3QgeyBhY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbiB9ID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYWN0aXZhdGlvbkF0dHJpYnV0ZXMpO1xuXG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgY29uc3QgcHJvY2Vzc0JpYXMgPSBoYXNCaWFzID8gJ3ZhbHVlICs9IGdldEJpYXNGb3JNYXRtdWwoKTsnIDogJyc7XG4gIGNvbnN0IGdldEJpYXNGb3JNYXRtdWxTbmlwcGV0ID0gaGFzQmlhc1xuICAgID8gYCR7Z2V0Qmlhc0Zvck1hdG11bChjb29yZHNEYXRhVHlwZSwgYWxsR2xDaGFubmVscywgaW5wdXRzWzJdLmRpbXMsIG91dHB1dFNoYXBlLCBmYWxzZSl9YFxuICAgIDogJyc7XG5cbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgYXJhbmsgPSBhU2hhcGUubGVuZ3RoO1xuICBjb25zdCBicmFuayA9IGJTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHNoYXJlZERpbSA9IGFTaGFwZVthU2hhcGUubGVuZ3RoIC0gMV07XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAke2FjdGl2YXRpb25GdW5jdGlvbn1cbiAgICAke2dldEJpYXNGb3JNYXRtdWxTbmlwcGV0fVxuICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IGFbJHthcmFua31dO1xuICAgICAgICBpbnQgYlske2JyYW5rfV07XG4gICAgICAgIGJjYXN0TWF0bXVsSW5kaWNlc19BKGluZGljZXMsIGEpO1xuICAgICAgICBiY2FzdE1hdG11bEluZGljZXNfQihpbmRpY2VzLCBiKTtcblxuICAgICAgICBmbG9hdCB2YWx1ZTtcbiAgICAgICAgZm9yIChpbnQgaz0wOyBrPCR7c2hhcmVkRGltfTsgKytrKSB7XG4gICAgICAgICAgICBhWyR7YXJhbmsgLSAxfV0gPSBrO1xuICAgICAgICAgICAgYlske2JyYW5rIC0gMn1dID0gaztcbiAgICAgICAgICAgIHZhbHVlICs9IF9BKGEpICogX0IoYik7XG4gICAgICAgIH1cbiAgICAgICAgJHtwcm9jZXNzQmlhc31cbiAgICAgICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlTWF0bXVsUHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGggPiAyLCBhY3RpdmF0aW9uQXR0cmlidXRlcy5hY3RpdmF0aW9uQ2FjaGVLZXkpO1xuICByZXR1cm4geyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mbyhtZXRhZGF0YSwgaW5wdXRzLCBhY3RpdmF0aW9uQXR0cmlidXRlcykgfTtcbn1cblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNYXRNdWwgcmVxdWlyZXMgMiBpbnB1dHMuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLmRpbXNbaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMV0gIT09IGlucHV0c1sxXS5kaW1zW2lucHV0c1sxXS5kaW1zLmxlbmd0aCAtIDJdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzaGFyZWQgZGltZW5zaW9uIGRvZXMgbm90IG1hdGNoLicpO1xuICB9XG5cbiAgaWYgKFxuICAgIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDY0JylcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dHMgc2hvdWxkIGJlIGZsb2F0IHR5cGUnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gaW5wdXRzWzFdLnR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0cyB0eXBlcyBzaG91bGQgbWF0Y2gnKTtcbiAgfVxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJpYXNGb3JNYXRtdWwoXG4gIGNvb3Jkc0RhdGFUeXBlOiBzdHJpbmcsXG4gIGFsbEdsQ2hhbm5lbHM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuICBpblNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgb3V0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBpc1BhY2tlZDogYm9vbGVhbixcbik6IHN0cmluZyB7XG4gIGxldCB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSAnJztcbiAgY29uc3QgaW5SYW5rID0gaW5TaGFwZS5sZW5ndGg7XG4gIGNvbnN0IG91dFJhbmsgPSBvdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHJhbmtEaWZmID0gb3V0UmFuayAtIGluUmFuaztcbiAgaWYgKG91dFJhbmsgPCAyICYmIGluUmFuayA+IDApIHtcbiAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSAnY29vcmRzJztcbiAgfSBlbHNlIHtcbiAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSBpblNoYXBlLm1hcCgoX3MsIGkpID0+IGBjb29yZHMuJHthbGxHbENoYW5uZWxzW2kgKyByYW5rRGlmZl19YCkuam9pbignLCAnKTtcbiAgfVxuICBjb25zdCBicm9hZGNhc3REaW1zID0gQnJvYWRjYXN0VXRpbC5nZXRCcm9hZGNhc3REaW1zKGluU2hhcGUsIG91dFNoYXBlKTtcbiAgY29uc3QgY29vcmRzU25pcHBldCA9IGJyb2FkY2FzdERpbXMubWFwKChkKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tkICsgcmFua0RpZmZdfSA9IDA7YCkuam9pbignXFxuJyk7XG4gIGNvbnN0IGluU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGluU2hhcGUpO1xuICBjb25zdCBpc0lucHV0U2NhbGFyID0gaW5TaXplID09PSAxO1xuICBsZXQgb3V0cHV0ID0gJ3ZlYzQob3V0cHV0VmFsdWUueHgsIG91dHB1dFZhbHVlLnl5KSc7XG4gIGlmIChpc0lucHV0U2NhbGFyKSB7XG4gICAgb3V0cHV0ID0gJ3ZlYzQob3V0cHV0VmFsdWUueCknO1xuICB9XG4gIGNvbnN0IGdldEJpYXNGb3JNYXRtdWxTb3VyY2UgPSBpc1BhY2tlZFxuICAgID8gYFxudmVjNCBnZXRCaWFzRm9yTWF0bXVsKCkge1xuICAke2Nvb3Jkc0RhdGFUeXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgJHtjb29yZHNTbmlwcGV0fVxuICB2ZWM0IG91dHB1dFZhbHVlID0gZ2V0Qmlhcygke3VucGFja2VkQ29vcmRzU25pcHBldH0pO1xuICByZXR1cm4gJHtvdXRwdXR9O1xufWBcbiAgICA6IGBcbmZsb2F0IGdldEJpYXNGb3JNYXRtdWwoKSB7XG4gICR7Y29vcmRzRGF0YVR5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAke2Nvb3Jkc1NuaXBwZXR9XG4gIHJldHVybiBnZXRCaWFzKGNvb3Jkcy54KTtcbn1gO1xuXG4gIHJldHVybiBnZXRCaWFzRm9yTWF0bXVsU291cmNlO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgQnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29vcmRzRGF0YVR5cGUsIGdldEdsQ2hhbm5lbHMgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IGdldEFjdGl2YXRpb25TbmlwcGV0LCBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9mdXNlLXV0aWxzJztcbmltcG9ydCB7IGdldEJpYXNGb3JNYXRtdWwgfSBmcm9tICcuL21hdG11bCc7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1NZXRhZGF0YSA9IChoYXNCaWFzOiBib29sZWFuLCBjYWNoZUhpbnQ6IHN0cmluZykgPT4gKHtcbiAgbmFtZTogJ01hdE11bCAocGFja2VkKScsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ0EnLCAnQicsICdCaWFzJ10gOiBbJ0EnLCAnQiddLFxuICBpbnB1dFR5cGVzOiBoYXNCaWFzXG4gICAgPyBbVGV4dHVyZVR5cGUucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZF1cbiAgICA6IFtUZXh0dXJlVHlwZS5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhY3RpdmF0aW9uQXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPiAyO1xuICBjb25zdCBwcm9jZXNzQmlhcyA9IGhhc0JpYXMgPyAndmFsdWUgKz0gZ2V0Qmlhc0Zvck1hdG11bCgpOycgOiAnJztcbiAgY29uc3QgYVNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGJTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IEJyb2FkY2FzdFV0aWwuY2FsY1NoYXBlKGFTaGFwZSwgYlNoYXBlLCB0cnVlKTtcbiAgY29uc3QgaXNCcm9hZGNhc3QgPSAhU2hhcGVVdGlsLmFyZUVxdWFsKGlucHV0c1swXS5kaW1zLCBpbnB1dHNbMV0uZGltcyk7XG5cbiAgaWYgKCFvdXRwdXRTaGFwZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IHVzZSBtYXRtdWwgb24gdGhlIGdpdmVuIHRlbnNvcnNcIik7XG4gIH1cbiAgY29uc3Qgc2hhcmVkRGltID0gYVNoYXBlW2FTaGFwZS5sZW5ndGggLSAxXTtcbiAgY29uc3Qgc2hhcmVkRGltSW5kZXggPSBNYXRoLmNlaWwoc2hhcmVkRGltIC8gMik7XG4gIGNvbnN0IGFSYW5rID0gYVNoYXBlLmxlbmd0aDtcbiAgY29uc3QgYlJhbmsgPSBiU2hhcGUubGVuZ3RoO1xuXG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgY29vcmRzRGF0YVR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBvdXRSYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBhbGxHbENoYW5uZWxzID0gZ2V0R2xDaGFubmVscygpO1xuICBjb25zdCB7IGFjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9uIH0gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhY3RpdmF0aW9uQXR0cmlidXRlcyk7XG5cbiAgY29uc3QgZ2V0Qmlhc0Zvck1hdG11bFNuaXBwZXQgPSBoYXNCaWFzXG4gICAgPyBgJHtnZXRCaWFzRm9yTWF0bXVsKGNvb3Jkc0RhdGFUeXBlLCBhbGxHbENoYW5uZWxzLCBpbnB1dHNbMl0uZGltcywgb3V0cHV0U2hhcGUsIHRydWUpfWBcbiAgICA6ICcnO1xuXG4gIGNvbnN0IGdldEJjYXN0ZWRTYW1wbGVyRm9yTWF0bXVsU25pcHBldCA9IGlzQnJvYWRjYXN0XG4gICAgPyBgJHtnZXRCY2FzdFNhbXBsZXJGb3JNYXRtdWwoY29vcmRzRGF0YVR5cGUsIGFsbEdsQ2hhbm5lbHMsIGlucHV0cywgb3V0cHV0U2hhcGUpfWBcbiAgICA6ICcnO1xuXG4gIGNvbnN0IGdldFNhbXBsZXJBSW5Mb29wU25pcHBldCA9IGlzQnJvYWRjYXN0ID8gJ2dldEFBdE91dENvb3Jkc01hdG11bChpKScgOiBgZ2V0QSgke2dldEEoYWxsR2xDaGFubmVscywgYVJhbmspfSlgO1xuICBjb25zdCBnZXRTYW1wbGVyQkluTG9vcFNuaXBwZXQgPSBpc0Jyb2FkY2FzdCA/ICdnZXRCQXRPdXRDb29yZHNNYXRtdWwoaSknIDogYGdldEIoJHtnZXRCKGFsbEdsQ2hhbm5lbHMsIGJSYW5rKX0pYDtcbiAgY29uc3QgZ2V0T3V0cHV0Q29vcmRzU25pcHBldCA9IGlzQnJvYWRjYXN0XG4gICAgPyAnJ1xuICAgIDogYCR7Y29vcmRzRGF0YVR5cGV9IHJjID1cbiAgICAgICAgICBnZXRPdXRwdXRDb29yZHMoKTsgaW50IGxhc3REaW0gPSByYy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDFdfTsgcmMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAxXX0gPVxuICAgICAgICAgIHJjLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMl19OyByYy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDJdfSA9IGxhc3REaW07XG4gICAgICBgO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICAgICAke2dldEJjYXN0ZWRTYW1wbGVyRm9yTWF0bXVsU25pcHBldH1cbiAgICAgICAgICAgICR7Z2V0Qmlhc0Zvck1hdG11bFNuaXBwZXR9XG4gICAgICAgICAgICAke2FjdGl2YXRpb25GdW5jdGlvbn1cbiAgICAgICAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgICAgICAgJHtnZXRPdXRwdXRDb29yZHNTbmlwcGV0fVxuXG4gICAgICAgICAgICAgIHZlYzQgdmFsdWUgPSB2ZWM0KDApO1xuICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7c2hhcmVkRGltSW5kZXh9OyBpKyspIHtcbiAgICAgICAgICAgICAgICB2ZWM0IGEgPSAke2dldFNhbXBsZXJBSW5Mb29wU25pcHBldH07XG4gICAgICAgICAgICAgICAgdmVjNCBiID0gJHtnZXRTYW1wbGVyQkluTG9vcFNuaXBwZXR9O1xuXG4gICAgICAgICAgICAgICAgdmFsdWUgKz0gKGEucnJiYiAqIGIucmdyZyk7XG4gICAgICAgICAgICAgICAgdmFsdWUgKz0gKGEuZ2dhYSAqIGIuYmFiYSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgJHtwcm9jZXNzQmlhc31cbiAgICAgICAgICAgICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmFsdWU7XG4gICAgICAgICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGggPiAyLCBhY3RpdmF0aW9uQXR0cmlidXRlcy5hY3RpdmF0aW9uQ2FjaGVLZXkpO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgYWN0aXZhdGlvbkF0dHJpYnV0ZXMpLFxuICB9O1xufTtcblxuZnVuY3Rpb24gZ2V0QmNhc3RTYW1wbGVyRm9yTWF0bXVsKFxuICBjb29yZHNEYXRhVHlwZTogc3RyaW5nLFxuICBhbGxHbENoYW5uZWxzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgb3V0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogc3RyaW5nIHtcbiAgbGV0IHVucGFja2VkQUNvb3Jkc1NuaXBwZXQgPSBbXTtcbiAgbGV0IHVucGFja2VkQkNvb3Jkc1NuaXBwZXQgPSBbXTtcblxuICBjb25zdCBpbkFTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbkJTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuXG4gIGNvbnN0IGluQVJhbmsgPSBpbkFTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGluQlJhbmsgPSBpbkJTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3Qgb3V0UmFuayA9IG91dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgcmFua0FEaWZmID0gb3V0UmFuayAtIGluQVJhbms7XG4gIGNvbnN0IHJhbmtCRGlmZiA9IG91dFJhbmsgLSBpbkJSYW5rO1xuXG4gIHVucGFja2VkQUNvb3Jkc1NuaXBwZXQgPSBpbkFTaGFwZS5tYXAoKF9zLCBpKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tpICsgcmFua0FEaWZmXX1gKTtcbiAgdW5wYWNrZWRBQ29vcmRzU25pcHBldFtpbkFSYW5rIC0gMV0gPSAnaSoyJztcbiAgdW5wYWNrZWRBQ29vcmRzU25pcHBldC5qb2luKCcsICcpO1xuICB1bnBhY2tlZEJDb29yZHNTbmlwcGV0ID0gaW5CU2hhcGUubWFwKChfcywgaSkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbaSArIHJhbmtCRGlmZl19YCk7XG4gIHVucGFja2VkQkNvb3Jkc1NuaXBwZXRbaW5CUmFuayAtIDJdID0gJ2kqMic7XG4gIHVucGFja2VkQkNvb3Jkc1NuaXBwZXQuam9pbignLCAnKTtcblxuICBjb25zdCBicm9hZGNhc3RBRGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpbkFTaGFwZSwgb3V0U2hhcGUpO1xuICBjb25zdCBicm9hZGNhc3RCRGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpbkJTaGFwZSwgb3V0U2hhcGUpO1xuXG4gIGNvbnN0IGNvb3Jkc0FTbmlwcGV0ID0gYnJvYWRjYXN0QURpbXMubWFwKChkKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tkICsgcmFua0FEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICBjb25zdCBjb29yZHNCU25pcHBldCA9IGJyb2FkY2FzdEJEaW1zLm1hcCgoZCkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbZCArIHJhbmtCRGlmZl19ID0gMDtgKS5qb2luKCdcXG4nKTtcbiAgY29uc3Qgc3dhcERpbVNuaXBwZXQgPSBgaW50IGxhc3REaW0gPSBjb29yZHMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAxXX07XG4gIGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDFdfSA9IGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDJdfTtcbiAgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMl19ID0gbGFzdERpbTtgO1xuXG4gIGNvbnN0IGdldEJjYXN0U2FtcGxlck1hdG11bFNvdXJjZSA9IGBcbnZlYzQgZ2V0QUF0T3V0Q29vcmRzTWF0bXVsKGludCBpKSB7XG4gICR7Y29vcmRzRGF0YVR5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAke3N3YXBEaW1TbmlwcGV0fVxuICAke2Nvb3Jkc0FTbmlwcGV0fVxuICB2ZWM0IG91dHB1dFZhbHVlID0gZ2V0QSgke3VucGFja2VkQUNvb3Jkc1NuaXBwZXR9KTtcbiAgcmV0dXJuIG91dHB1dFZhbHVlO1xufVxuXG52ZWM0IGdldEJBdE91dENvb3Jkc01hdG11bChpbnQgaSkge1xuICAke2Nvb3Jkc0RhdGFUeXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgJHtzd2FwRGltU25pcHBldH1cbiAgJHtjb29yZHNCU25pcHBldH1cbiAgdmVjNCBvdXRwdXRWYWx1ZSA9IGdldEIoJHt1bnBhY2tlZEJDb29yZHNTbmlwcGV0fSk7XG4gIHJldHVybiBvdXRwdXRWYWx1ZTtcbn1gO1xuXG4gIHJldHVybiBnZXRCY2FzdFNhbXBsZXJNYXRtdWxTb3VyY2U7XG59XG5cbmZ1bmN0aW9uIGdldEEoYWxsR2xDaGFubmVsczogc3RyaW5nW10sIHJhbms6IG51bWJlcik6IHN0cmluZyB7XG4gIGxldCByZXMgPSAnJztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMjsgaSsrKSB7XG4gICAgcmVzICs9IGByYy4ke2FsbEdsQ2hhbm5lbHNbaV19LCBgO1xuICB9XG4gIHJlcyArPSBgcmMuJHthbGxHbENoYW5uZWxzW3JhbmsgLSAyXX0sIGAgKyAnaSoyJztcbiAgcmV0dXJuIHJlcztcbn1cblxuZnVuY3Rpb24gZ2V0QihhbGxHbENoYW5uZWxzOiBzdHJpbmdbXSwgcmFuazogbnVtYmVyKTogc3RyaW5nIHtcbiAgbGV0IHJlcyA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAyOyBpKyspIHtcbiAgICByZXMgKz0gYHJjLiR7YWxsR2xDaGFubmVsc1tpXX0sIGA7XG4gIH1cbiAgcmVzICs9ICdpKjIsICcgKyBgcmMuJHthbGxHbENoYW5uZWxzW3JhbmsgLSAxXX1gO1xuICByZXR1cm4gcmVzO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5pbXBvcnQgeyBjYWxjdWxhdGVPdXRwdXRTaGFwZSwgQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbnYnO1xuaW1wb3J0IHsgY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL2ltMmNvbC1wYWNrJztcbmltcG9ydCB7IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9tYXRtdWwtcGFjayc7XG5cbmV4cG9ydCBjb25zdCBjb252MkRQYWNrZWRQb2ludHdpc2UgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCB4c2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gY2FsY3VsYXRlT3V0cHV0U2hhcGUoeHNoYXBlLCBrc2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gIGNvbnN0IHJlc2hhcGVkWCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVBhY2tlZChpbnB1dHNbMF0sIFt4c2hhcGVbMV0sIHhzaGFwZVsyXSAqIHhzaGFwZVszXV0pO1xuICBjb25zdCByZXNoYXBlZEsgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVQYWNrZWQoaW5wdXRzWzFdLCBba3NoYXBlWzBdLCBrc2hhcGVbMV1dKTtcblxuICBjb25zdCBtYXRtdWxJbnB1dHMgPSBpbnB1dHMubGVuZ3RoID4gMiA/IFtyZXNoYXBlZEssIHJlc2hhcGVkWCwgaW5wdXRzWzJdXSA6IFtyZXNoYXBlZEssIHJlc2hhcGVkWF07XG4gIGNvbnN0IG1hdG11bE91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIG1hdG11bElucHV0cywgYXR0cmlidXRlcyksXG4gICAgbWF0bXVsSW5wdXRzLFxuICApO1xuICByZXR1cm4gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlUGFja2VkKG1hdG11bE91dHB1dCwgb3V0cHV0U2hhcGUpO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbnYyRFBhY2tlZCA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFRlbnNvciA9PiB7XG4gIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBrc2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVPdXRwdXRTaGFwZSh4c2hhcGUsIGtzaGFwZSwgYXR0cmlidXRlcy5kaWxhdGlvbnMsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy5zdHJpZGVzKTtcblxuICAvLyBydW4gaW0yY29sXG4gIGNvbnN0IGltMmNvbE91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgaW5wdXRzWzFdLCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcyksXG4gICAgW2lucHV0c1swXV0sXG4gICk7XG5cbiAgLy8gcmVzaGFwZSBrZXJuZWxcbiAgY29uc3Qga2VybmVsUmVzaGFwZWQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVQYWNrZWQoaW5wdXRzWzFdLCBba3NoYXBlWzBdLCBrc2hhcGVbMV0gKiBrc2hhcGVbMl0gKiBrc2hhcGVbM11dKTtcblxuICAvLyBydW4gbWF0bXVsXG4gIGNvbnN0IG1hdG11bElucHV0cyA9IGlucHV0cy5sZW5ndGggPT09IDMgPyBba2VybmVsUmVzaGFwZWQsIGltMmNvbE91dHB1dCwgaW5wdXRzWzJdXSA6IFtrZXJuZWxSZXNoYXBlZCwgaW0yY29sT3V0cHV0XTtcbiAgY29uc3QgbWF0bXVsT3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgbWF0bXVsSW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICBtYXRtdWxJbnB1dHMsXG4gICk7XG5cbiAgLy8gcmVzaGFwZSBvdXRwdXRcbiAgY29uc3Qgb3V0cHV0UmVzaGFwZWQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVQYWNrZWQobWF0bXVsT3V0cHV0LCBvdXRwdXRTaGFwZSk7XG4gIHJldHVybiBvdXRwdXRSZXNoYXBlZDtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IENvbnZBdHRyaWJ1dGVzIH0gZnJvbSAnLi9jb252JztcblxuY29uc3QgY3JlYXRlSW0yQ29sUHJvZ3JhbU1ldGFkYXRhID0gKGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnSW0yQ29sJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVJbTJDb2xQcm9ncmFtSW5mbyA9IChcbiAgX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgeDogVGVuc29yLFxuICB3OiBUZW5zb3IsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHhzaGFwZSA9IHguZGltcztcbiAgY29uc3Qgd3NoYXBlID0gdy5kaW1zO1xuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGltMmNvbERpbXMgPSBjYWxjdWxhdGVJbTJDb2xEaW1zKHhzaGFwZSwgd3NoYXBlLCBvdXRwdXRTaGFwZSwgNCk7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICBjb25zdCBpbnQgWEMgPSAke3hzaGFwZVsxXX07XG4gICAgICAgIGNvbnN0IGludCBYSCA9ICR7eHNoYXBlWzJdfTtcbiAgICAgICAgY29uc3QgaW50IFhXID0gJHt4c2hhcGVbM119O1xuICAgICAgICBjb25zdCBpbnQgS0ggPSAke2F0dHJpYnV0ZXMua2VybmVsU2hhcGVbMF19O1xuICAgICAgICBjb25zdCBpbnQgS1cgPSAke2F0dHJpYnV0ZXMua2VybmVsU2hhcGVbMV19O1xuICAgICAgICBjb25zdCBpbnQgZGlsYXRpb25IID0gJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1swXX07XG4gICAgICAgIGNvbnN0IGludCBkaWxhdGlvblcgPSAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzFdfTtcbiAgICAgICAgY29uc3QgaW50IHN0cmlkZUggPSAke2F0dHJpYnV0ZXMuc3RyaWRlc1swXX07XG4gICAgICAgIGNvbnN0IGludCBzdHJpZGVXID0gJHthdHRyaWJ1dGVzLnN0cmlkZXNbMV19O1xuICAgICAgICBjb25zdCBpbnQgcGFkSCA9ICR7YXR0cmlidXRlcy5wYWRzWzBdfTtcbiAgICAgICAgY29uc3QgaW50IHBhZFcgPSAke2F0dHJpYnV0ZXMucGFkc1sxXX07XG4gICAgICAgIGNvbnN0IGludCBLSEtXID0gS0gqS1c7XG4gICAgICAgIGNvbnN0IGludCBYQ0tIS1cgPSBYQyAqIEtIS1c7XG4gICAgICAgIGNvbnN0IGludCBvdXRwdXRDaGFubmVscyA9IDQ7XG4gICAgICAgIHZlYzQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBiICA9IGluZGljZXNbMF07IC8vIGJhdGNoIHNpemVcbiAgICAgICAgICBpbnQgb2ggPSBpbmRpY2VzWzFdICogc3RyaWRlSCAtIHBhZEg7IC8vb3V0cHV0IGhlaWdodFxuICAgICAgICAgIGludCBvdyA9IGluZGljZXNbMl0gKiBzdHJpZGVXIC0gcGFkVzsgLy9vdXRwdXQgd2lkdGhcbiAgICAgICAgICBpbnQgcCA9IGluZGljZXNbM10gKiBvdXRwdXRDaGFubmVsczsgLy9wYXRjaFxuICAgICAgICAgIHZlYzQgdmFsdWUgPSB2ZWM0KDAuMCk7XG4gICAgICAgICAgZm9yKGludCBpPTA7IGkgPCBvdXRwdXRDaGFubmVsczsgKytpKSB7XG4gICAgICAgICAgICBpZihwIDwgWENLSEtXKSB7XG4gICAgICAgICAgICAgIGludCBwYXRjaEMgPSBwIC8gS0hLVztcbiAgICAgICAgICAgICAgaW50IHBhdGNoSCA9IChwIC0gcGF0Y2hDKktIS1cpIC8gS1c7XG4gICAgICAgICAgICAgIGludCBwYXRjaFcgPSAocCAtIHBhdGNoQypLSEtXKSAtIHBhdGNoSCAqIEtXO1xuICAgICAgICAgICAgICBpbnQgeGgyID0gb2ggKyBwYXRjaEggKiBkaWxhdGlvbkg7XG4gICAgICAgICAgICAgIGludCB4dzIgPSBvdyArIHBhdGNoVyAqIGRpbGF0aW9uVztcbiAgICAgICAgICAgICAgaW50IHhbJHt4c2hhcGUubGVuZ3RofV07XG4gICAgICAgICAgICAgIHhbMF0gPSBiO1xuICAgICAgICAgICAgICB4WzFdID0gcGF0Y2hDO1xuICAgICAgICAgICAgICB4WzJdID0geGgyO1xuICAgICAgICAgICAgICB4WzNdID0geHcyO1xuICAgICAgICAgICAgICBpZih4aDIgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgeGgyIDwgWEggJiZcbiAgICAgICAgICAgICAgICAgIHh3MiA+PSAwICYmXG4gICAgICAgICAgICAgICAgICB4dzIgPCBYVykge1xuICAgICAgICAgICAgICAgIHZhbHVlW2ldID0gX1goeCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICsrcDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGltMmNvbERpbXMsIHR5cGU6IHgudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24gfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgeDogVGVuc29yLFxuICB3OiBUZW5zb3IsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlSW0yQ29sUHJvZ3JhbU1ldGFkYXRhKGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIHgsIHcsIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjYWxjdWxhdGVJbTJDb2xEaW1zID0gKFxuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGNoYW5uZWxzID0gNCxcbik6IG51bWJlcltdID0+IFtcbiAgb3V0cHV0U2hhcGVbMF0sXG4gIG91dHB1dFNoYXBlWzJdLFxuICBvdXRwdXRTaGFwZVszXSxcbiAgTWF0aC5jZWlsKChpbnB1dFNoYXBlWzFdICoga2VybmVsU2hhcGVbMl0gKiBrZXJuZWxTaGFwZVszXSkgLyBjaGFubmVscyksXG5dO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBnZXRBY3RpdmF0aW9uU25pcHBldCwgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQgeyBjYWxjdWxhdGVJbTJDb2xEaW1zIH0gZnJvbSAnLi9pbTJjb2wnO1xuXG5jb25zdCBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMpID0+ICh7XG4gIG5hbWU6ICdDb252RG90UHJvZHVjdCcsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ0ltMkNvbCcsICdLJywgJ0InXSA6IFsnSW0yQ29sJywgJ0snXSxcbiAgaW5wdXRUeXBlczogaGFzQmlhc1xuICAgID8gW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uLCBUZXh0dXJlVHlwZS51bnBhY2tlZF1cbiAgICA6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbl0sXG4gIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmFjdGl2YXRpb25DYWNoZUtleSxcbn0pO1xuXG5jb25zdCBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuICBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCB4c2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IGFkanVzdGVkS2VybmVsU2hhcGUgPSBba3NoYXBlWzBdLCBNYXRoLmNlaWwoKHhzaGFwZVsxXSAqIGtzaGFwZVsyXSAqIGtzaGFwZVszXSkgLyA0KV07XG4gIGNvbnN0IGltMmNvbFNoYXBlID0gY2FsY3VsYXRlSW0yQ29sRGltcyh4c2hhcGUsIGtzaGFwZSwgb3V0cHV0U2hhcGUpO1xuICBjb25zdCBba1dpZHRoLCBrSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGFkanVzdGVkS2VybmVsU2hhcGUsXG4gICAgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbixcbiAgKTtcblxuICBjb25zdCBpbTJjb2xTdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGltMmNvbFNoYXBlKTtcbiAgY29uc3QgW2ltMmNvbFdpZHRoLCBpbTJjb2xIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgaW0yY29sU2hhcGUsXG4gICAgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbixcbiAgKTtcbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcblxuICBjb25zdCBpbml0VmFsdWUgPSBpbnB1dHMubGVuZ3RoIDwgMyA/ICcwLjAnIDogJ19CKGIpJztcbiAgY29uc3Qgc2hhcmVkRGltID0gTWF0aC5jZWlsKCh4c2hhcGVbMV0gKiBrc2hhcGVbMl0gKiBrc2hhcGVbM10pIC8gNCk7XG4gIGNvbnN0IHsgYWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb24gfSA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXMpO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiR7YWN0aXZhdGlvbkZ1bmN0aW9ufVxuZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICBpbnQgYlsxXTtcbiAgYlswXSA9IGluZGljZXNbMV07XG4gIGludCBpbTJjb2xbNF07XG4gIGltMmNvbFswXSA9IGluZGljZXNbMF07XG4gIGltMmNvbFsxXSA9IGluZGljZXNbMl07XG4gIGltMmNvbFsyXSA9IGluZGljZXNbM107XG4gIGludCBpbTJjb2xPZmZzZXQgPSBpbTJjb2xbMF0gKiAke2ltMmNvbFN0cmlkZXNbMF19ICsgaW0yY29sWzFdICogJHtpbTJjb2xTdHJpZGVzWzFdfSArIGltMmNvbFsyXSAqICR7XG4gICAgaW0yY29sU3RyaWRlc1syXVxuICB9O1xuICBpbnQga2VybmVsT2Zmc2V0ID0gaW5kaWNlc1sxXSAqICR7YWRqdXN0ZWRLZXJuZWxTaGFwZVsxXX07XG4gIGZsb2F0IHZhbHVlID0gJHtpbml0VmFsdWV9O1xuICBmb3IgKGludCBpID0gMDsgaSA8ICR7c2hhcmVkRGltfTsgKytpKSB7XG4gICAgdmVjMiBpbTJjb2xDb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhpbTJjb2xPZmZzZXQsICR7aW0yY29sV2lkdGh9LCAke2ltMmNvbEhlaWdodH0pO1xuICAgIHZlYzIga2VybmVsQ29vcmRzID0gb2Zmc2V0VG9Db29yZHMoa2VybmVsT2Zmc2V0LCAke2tXaWR0aH0sICR7a0hlaWdodH0pO1xuICAgIHZhbHVlICs9IGRvdCgke2dsc2wudGV4dHVyZTJEfShJbTJDb2wsIGltMmNvbENvb3JkcyksICR7Z2xzbC50ZXh0dXJlMkR9KEssIGtlcm5lbENvb3JkcykpO1xuICAgICsraW0yY29sT2Zmc2V0O1xuICAgICsra2VybmVsT2Zmc2V0O1xuICB9XG4gICR7YXBwbHlBY3RpdmF0aW9ufVxuICByZXR1cm4gdmFsdWU7XG59YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIG91dHB1dFNoYXBlOiBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGggPiAyLCBhdHRyaWJ1dGVzKTtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBnZXQ6ICgpID0+IGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcyksXG4gIH07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vLi4vLi4vYmFja2VuZCc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFBvb2xDb252VXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5pbXBvcnQgeyBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL2NvbnYtZ3JvdXBlZCc7XG5pbXBvcnQgeyBjb252MkRQYWNrZWQgfSBmcm9tICcuL2NvbnYtcGFjayc7XG5pbXBvcnQgeyBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL2RvdC1wcm9kdWN0JztcbmltcG9ydCB7IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsIHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQgeyBjcmVhdGVJbTJDb2xQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vaW0yY29sJztcbmltcG9ydCB7IGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9tYXRtdWwnO1xuXG5leHBvcnQgY29uc3QgY2FsY3VsYXRlT3V0cHV0U2hhcGUgPSAoXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGFkanVzdFBhZHM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbik6IG51bWJlcltdID0+IHtcbiAgY29uc3QgYmF0Y2hTaXplID0gaW5wdXRTaGFwZVswXTtcbiAgY29uc3QgaW5wdXRTcGF0aWFsU2hhcGUgPSBpbnB1dFNoYXBlLnNsaWNlKDIpO1xuICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0U3BhdGlhbFNoYXBlLmxlbmd0aDtcbiAgY29uc3Qgb3V0Q2hhbm5lbHMgPSBrZXJuZWxTaGFwZVswXTtcbiAgY29uc3Qga2VybmVsU3BhdGlhbFNoYXBlID0ga2VybmVsU2hhcGUuc2xpY2UoMik7XG4gIGNvbnN0IGRpbGF0ZWRLZXJuZWxTaGFwZSA9IGtlcm5lbFNwYXRpYWxTaGFwZS5tYXAoKHYsIGkpID0+IHYgKyAodiAtIDEpICogKGRpbGF0aW9uc1tpXSAtIDEpKTtcbiAgY29uc3QgaW5wdXRTcGF0aWFsU2hhcGVXaXRoUGFkID0gaW5wdXRTcGF0aWFsU2hhcGUubWFwKCh2LCBpKSA9PiB2ICsgYWRqdXN0UGFkc1tpXSArIGFkanVzdFBhZHNbaSArIHNwYXRpYWxSYW5rXSk7XG4gIGNvbnN0IG91dHB1dFNwYXRpYWxTaGFwZSA9IGlucHV0U3BhdGlhbFNoYXBlV2l0aFBhZC5tYXAoKHYsIGkpID0+XG4gICAgTWF0aC5mbG9vcigodiAtIGRpbGF0ZWRLZXJuZWxTaGFwZVtpXSArIHN0cmlkZXNbaV0pIC8gc3RyaWRlc1tpXSksXG4gICk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW2JhdGNoU2l6ZSwgb3V0Q2hhbm5lbHNdLmNvbmNhdCguLi5vdXRwdXRTcGF0aWFsU2hhcGUpO1xuICByZXR1cm4gb3V0cHV0U2hhcGU7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZBdHRyaWJ1dGVzIGV4dGVuZHMgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcywgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXV0b1BhZDogc3RyaW5nO1xuICByZWFkb25seSBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBncm91cDogbnVtYmVyO1xuICByZWFkb25seSBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHBhZHM6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGNvbnN0IGNvbnY6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29udkF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTsgLy8gY3VycmVudGx5IHdpbGwgZmFpbCBpZiBub3QgY29udjJEXG4gIHJldHVybiBjb252MmQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbn07XG5cbmNvbnN0IGNvbnYyZDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxDb252QXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IGFkanVzdGVkQXR0cmlidXRlcyA9IGdldEFkanVzdGVkQ29udkF0dHJpYnV0ZXMoYXR0cmlidXRlcywgaW5wdXRzKTtcbiAgY29uc3QgcGFja01vZGUgPSBpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24ucGFjaztcbiAgY29uc3QgaXNQb2ludHdpc2UgPSBhZGp1c3RlZEF0dHJpYnV0ZXMua2VybmVsU2hhcGVbMF0gPT09IDEgJiYgYWRqdXN0ZWRBdHRyaWJ1dGVzLmtlcm5lbFNoYXBlWzFdID09PSAxO1xuICBpZiAoYWRqdXN0ZWRBdHRyaWJ1dGVzLmdyb3VwID4gMSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKSxcbiAgICAgIGlucHV0cyxcbiAgICApO1xuICAgIHJldHVybiBbcmVzdWx0XTtcbiAgfSBlbHNlIGlmIChpc1BvaW50d2lzZSAmJiBwYWNrTW9kZSkge1xuICAgIHJldHVybiBbY29udjJEVW5wYWNrZWRQb2ludHdpc2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMpXTtcbiAgfSBlbHNlIGlmIChwYWNrTW9kZSAmJiBpbnB1dHNbMF0uZGltcy5sZW5ndGggPT09IDQgJiYgaW5wdXRzWzBdLmRpbXNbMF0gPT09IDEgJiYgIWlzUG9pbnR3aXNlKSB7XG4gICAgcmV0dXJuIFtjb252MkRQYWNrZWQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMpXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW2NvbnYyRFVucGFja2VkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKV07XG4gIH1cbn07XG5cbmNvbnN0IGNvbnYyRFVucGFja2VkUG9pbnR3aXNlID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgeHNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGtzaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGNhbGN1bGF0ZU91dHB1dFNoYXBlKHhzaGFwZSwga3NoYXBlLCBhdHRyaWJ1dGVzLmRpbGF0aW9ucywgYXR0cmlidXRlcy5wYWRzLCBhdHRyaWJ1dGVzLnN0cmlkZXMpO1xuICBjb25zdCByZXNoYXBlZFggPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIFt4c2hhcGVbMV0sIHhzaGFwZVsyXSAqIHhzaGFwZVszXV0pO1xuICBjb25zdCByZXNoYXBlZEsgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMV0sIFtrc2hhcGVbMF0sIGtzaGFwZVsxXV0pO1xuXG4gIGNvbnN0IG1hdG11bElucHV0cyA9IGlucHV0cy5sZW5ndGggPiAyID8gW3Jlc2hhcGVkSywgcmVzaGFwZWRYLCBpbnB1dHNbMl1dIDogW3Jlc2hhcGVkSywgcmVzaGFwZWRYXTtcbiAgY29uc3QgbWF0bXVsT3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIobWF0bXVsSW5wdXRzLCBhdHRyaWJ1dGVzKSwgbWF0bXVsSW5wdXRzKTtcbiAgcmV0dXJuIGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKG1hdG11bE91dHB1dCwgb3V0cHV0U2hhcGUpO1xufTtcblxuY29uc3QgY29udjJEVW5wYWNrZWQgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCB4c2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gY2FsY3VsYXRlT3V0cHV0U2hhcGUoeHNoYXBlLCBrc2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gIGNvbnN0IHhJbTJDb2wgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVJbTJDb2xQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGlucHV0c1sxXSwgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLFxuICAgIFtpbnB1dHNbMF1dLFxuICApO1xuXG4gIGNvbnN0IGRvdFByb2R1Y3RJbnB1dHMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gW3hJbTJDb2wsIGlucHV0c1sxXSwgaW5wdXRzWzJdXSA6IFt4SW0yQ29sLCBpbnB1dHNbMV1dO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcyksXG4gICAgZG90UHJvZHVjdElucHV0cyxcbiAgKTtcbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbmNvbnN0IGdldEFkanVzdGVkQ29udkF0dHJpYnV0ZXMgPSA8VCBleHRlbmRzIENvbnZBdHRyaWJ1dGVzPihhdHRyaWJ1dGVzOiBULCBpbnB1dHM6IFRlbnNvcltdKTogVCA9PiB7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5zbGljZSgpO1xuICAvLyBpZiBrZXJuZWxTaGFwZSBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgb3AsIGluZmVyIGl0IGZyb20gdGhlIHdlaWdodCB0ZW5zb3IgZGltc1xuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICBmb3IgKGxldCBpID0gMjsgaSA8IGlucHV0c1sxXS5kaW1zLmxlbmd0aDsgKytpKSB7XG4gICAgICBrZXJuZWxTaGFwZS5wdXNoKGlucHV0c1sxXS5kaW1zW2ldKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMucGFkcy5zbGljZSgpO1xuICBQb29sQ29udlV0aWwuYWRqdXN0UGFkc0Jhc2VkT25BdXRvUGFkKFxuICAgIGlucHV0c1swXS5kaW1zLFxuICAgIGF0dHJpYnV0ZXMuc3RyaWRlcyxcbiAgICBhdHRyaWJ1dGVzLmRpbGF0aW9ucyxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBwYWRzLFxuICAgIGF0dHJpYnV0ZXMuYXV0b1BhZCxcbiAgKTtcblxuICAvLyBhbHdheXMgcmV0dXJuIGEgbmV3IG9iamVjdCBzbyBkb2VzIG5vdCBtb2RpZnkgdGhlIG9yaWdpbmFsIGF0dHJpYnV0ZXNcbiAgY29uc3QgbmV3QXR0cmlidXRlczogVCA9IE9iamVjdC5hc3NpZ24oe30sIGF0dHJpYnV0ZXMpO1xuICBPYmplY3QuYXNzaWduKG5ld0F0dHJpYnV0ZXMsIHsga2VybmVsU2hhcGUsIHBhZHMsIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH0pO1xuICByZXR1cm4gbmV3QXR0cmlidXRlcztcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNvbnZBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPENvbnZBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogQ29udkF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhdHRyaWJ1dGVzID0gbm9kZS5hdHRyaWJ1dGVzO1xuICBjb25zdCBhY3RpdmF0aW9uQXR0cmlidXRlcyA9IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTtcbiAgLy8gVE9ETyA6IE1ha2UgdGhpcyBnZW5lcmljIGVub3VnaCB0byBjb21wdXRlIGRlZmF1bHQgYXR0cmlidXRlcyBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICBjb25zdCBhdXRvUGFkID0gYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2F1dG9fcGFkJywgJ05PVFNFVCcpO1xuICBjb25zdCBkaWxhdGlvbnMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ2RpbGF0aW9ucycsIFsxLCAxXSk7XG4gIGNvbnN0IGdyb3VwID0gYXR0cmlidXRlcy5nZXRJbnQoJ2dyb3VwJywgMSk7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5nZXRJbnRzKCdrZXJuZWxfc2hhcGUnLCBbXSk7XG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnLCBbMCwgMCwgMCwgMF0pO1xuICBjb25zdCBzdHJpZGVzID0gYXR0cmlidXRlcy5nZXRJbnRzKCdzdHJpZGVzJywgWzEsIDFdKTtcblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBhdXRvUGFkLFxuICAgIGRpbGF0aW9ucyxcbiAgICBncm91cCxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBwYWRzLFxuICAgIHN0cmlkZXMsXG4gICAgLi4uYWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4gIH0pO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgLy8gUmVmZXIgdG8gdGhlIGJlbG93IGxpbmsgZm9yIGFsbCBpbnB1dCBjaGVja3NcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjQ29udlxuICBpZiAoIWlucHV0cyB8fCAoaW5wdXRzLmxlbmd0aCAhPT0gMiAmJiBpbnB1dHMubGVuZ3RoICE9PSAzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udiByZXF1aXJlcyAyIG9yIDMgaW5wdXRzJyk7XG4gIH1cblxuICAvLyBUT0RPIDogTmVlZCB0byBhZGQgc3VwcG9ydCBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0IHx8IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY3VycmVudGx5IG9ubHkgc3VwcG9ydCAyLWRpbWVuc2lvbmFsIGNvbnYnKTtcbiAgfVxuXG4gIC8vIEZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUxcbiAgY29uc3QgZGF0YUNoYW5uZWwgPSBpbnB1dHNbMF0uZGltc1sxXTtcbiAgY29uc3QgZmlsdGVySW5DaGFubmVsID0gaW5wdXRzWzFdLmRpbXNbMV0gKiBhdHRyaWJ1dGVzLmdyb3VwO1xuICBpZiAoZGF0YUNoYW5uZWwgIT09IGZpbHRlckluQ2hhbm5lbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRklMVEVSX0lOX0NIQU5ORUwgc2hvdWxkIGJlIGVxdWFsIHRvIERBVEFfQ0hBTk5FTCcpO1xuICB9XG5cbiAgLy8gaWYgYmlhcyBpcyBwcm92aWRlZCBpdCBzaG91bGQgYmUgMUQgYW5kIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgc2hvdWxkIGJlIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgZmVhdHVyZSBtYXBzXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIChpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDEgfHwgaW5wdXRzWzFdLmRpbXNbMF0gIT09IGlucHV0c1syXS5kaW1zWzBdKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBiaWFzJyk7XG4gIH1cblxuICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDI7XG4gIC8vIHdyb25nIGRpbGF0aW9ucyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMuZGlsYXRpb25zLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGRpbGF0aW9ucyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBzdHJpZGVzIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5zdHJpZGVzLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHN0cmlkZXMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3JvbmcgcGFkcyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMucGFkcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rICogMikge1xuICAgIHRocm93IG5ldyBFcnJvcihgcGFkcyBzaG91bGQgYmUgJHtzcGF0aWFsUmFuayAqIDJ9RGApO1xuICB9XG5cbiAgLy8gaWYga2VybmVsU2hhcGUgaXMgc3BlY2lmaWVkLCBpdCdzIGRhdGEgbGVuZ3RoIG11c3QgYmUgMiBsZXNzIHRoYW4gZGltcyBsZW5ndGggb2YgdGhlIHdlaWdodHMgdGVuc29yXG4gIC8vICh0aGUgZmlyc3QgMiBkaW1zIGFyZSBiYXRjaF9zaXplIGFuZCBjaGFubmVscylcbiAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoICE9PSAwICYmIGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoICE9PSBpbnB1dHNbMV0uZGltcy5sZW5ndGggLSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGtlcm5lbCBzaGFwZScpO1xuICB9XG5cbiAgLy8gVE9ETyA6IE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIGZsb2F0NjRcbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgfHwgaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udiBpbnB1dChYLFcpIHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxuXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1syXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnYgaW5wdXQoYmlhcykgc2hvdWxkIGJlIGZsb2F0IHRlbnNvcicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uLy4uLy4uL2JhY2tlbmQnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBDb252QXR0cmlidXRlcyB9IGZyb20gJy4vY29udic7XG5pbXBvcnQgeyBnZXRBY3RpdmF0aW9uU25pcHBldCwgcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9mdXNlLXV0aWxzJztcblxuY29uc3QgY29tcHV0ZVRvdGFsUGFkID0gKFxuICBpbkRpbTogbnVtYmVyLFxuICBzdHJpZGU6IG51bWJlcixcbiAgYWRqOiBudW1iZXIsXG4gIGtlcm5lbDogbnVtYmVyLFxuICBkaWxhdGlvbjogbnVtYmVyLFxuICBvdXRTaXplOiBudW1iZXIsXG4pID0+IChpbkRpbSAtIDEpICogc3RyaWRlICsgYWRqICsgKGtlcm5lbCAtIDEpICogZGlsYXRpb24gKyAxIC0gb3V0U2l6ZTtcblxuY29uc3QgZGlzdHJpYnV0ZVBhZGRpbmcgPSAodG90YWxQYWQ6IG51bWJlciwgYXV0b1BhZDogc3RyaW5nLCBwYWRzOiBudW1iZXJbXSwgaGVhZDogbnVtYmVyLCB0YWlsOiBudW1iZXIpID0+IHtcbiAgY29uc3Qgc21hbGxQYWQgPSBNYXRoLmZsb29yKHRvdGFsUGFkIC8gMik7XG4gIGlmIChhdXRvUGFkID09PSAnU0FNRV9VUFBFUicpIHtcbiAgICBwYWRzW2hlYWRdID0gc21hbGxQYWQ7XG4gICAgcGFkc1t0YWlsXSA9IHRvdGFsUGFkIC0gc21hbGxQYWQ7XG4gIH0gZWxzZSBpZiAoYXV0b1BhZCA9PT0gJ1NBTUVfTE9XRVInKSB7XG4gICAgcGFkc1toZWFkXSA9IHRvdGFsUGFkIC0gc21hbGxQYWQ7XG4gICAgcGFkc1t0YWlsXSA9IHNtYWxsUGFkO1xuICB9XG59O1xuXG5jb25zdCBjYWxjdWxhdGVPdXRwdXRTaGFwZUFuZFBhZHMgPSAoXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGF1dG9QYWQ6IHN0cmluZyxcbiAgcGFkczogbnVtYmVyW10sXG4gIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRwdXRQYWRkaW5nOiByZWFkb25seSBudW1iZXJbXSxcbiAgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuKSA9PiB7XG4gIGNvbnN0IHNwYXRpYWxSYW5rID0gaW5wdXRTaGFwZS5sZW5ndGggLSAyO1xuICBjb25zdCB1cGRhdGVTaGFwZSA9IG91dHB1dFNoYXBlLmxlbmd0aCA9PT0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzcGF0aWFsUmFuazsgKytpKSB7XG4gICAgY29uc3Qgb3V0U2l6ZSA9IHVwZGF0ZVNoYXBlID8gaW5wdXRTaGFwZVtpICsgMl0gKiBzdHJpZGVzW2ldIDogb3V0cHV0U2hhcGVbaV07XG4gICAgY29uc3QgdG90YWxQYWQgPSBjb21wdXRlVG90YWxQYWQoaW5wdXRTaGFwZVtpICsgMl0sIHN0cmlkZXNbaV0sIHBhZHNbaV0sIGtlcm5lbFNoYXBlW2ldLCBkaWxhdGlvbnNbaV0sIG91dFNpemUpO1xuICAgIGRpc3RyaWJ1dGVQYWRkaW5nKHRvdGFsUGFkLCBhdXRvUGFkLCBwYWRzLCBpLCBpICsgc3BhdGlhbFJhbmspO1xuICAgIGlmICh1cGRhdGVTaGFwZSkge1xuICAgICAgb3V0cHV0U2hhcGUucHVzaChcbiAgICAgICAgc3RyaWRlc1tpXSAqIChpbnB1dFNoYXBlW2kgKyAyXSAtIDEpICtcbiAgICAgICAgICBvdXRwdXRQYWRkaW5nW2ldICtcbiAgICAgICAgICAoa2VybmVsU2hhcGVbaV0gLSAxKSAqIGRpbGF0aW9uc1tpXSArXG4gICAgICAgICAgMSAtXG4gICAgICAgICAgcGFkc1tpXSAtXG4gICAgICAgICAgcGFkc1tpICsgc3BhdGlhbFJhbmtdLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMgZXh0ZW5kcyBDb252QXR0cmlidXRlcyB7XG4gIHJlYWRvbmx5IG91dHB1dFBhZGRpbmc6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBjb252VHJhbnNwb3NlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7IC8vIGN1cnJlbnRseSB3aWxsIGZhaWwgaWYgbm90IGNvbnZUcmFuc3Bvc2UyRFxuICByZXR1cm4gY29udlRyYW5zcG9zZTJkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyk7XG59O1xuXG5jb25zdCBjb252VHJhbnNwb3NlMmQ6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29udlRyYW5zcG9zZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCBhZGp1c3RlZEF0dHJpYnV0ZXMgPSBnZXRBZGp1c3RlZENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMsIGlucHV0cyk7XG4gIHJldHVybiBbY29udlRyYW5zcG9zZTJEVW5wYWNrZWQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMpXTtcbn07XG5cbmNvbnN0IGNyZWF0ZUNvbnZUcmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEgPSAoaGFzQmlhczogYm9vbGVhbiwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdDb252VHJhbnNwb3NlJyxcbiAgaW5wdXROYW1lczogaGFzQmlhcyA/IFsnWCcsICdXJywgJ0InXSA6IFsnWCcsICdXJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXNcbiAgICA/IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXVxuICAgIDogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZENvbnZUcmFuc3Bvc2VQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPiAyO1xuICBjb25zdCB2YWx1ZUluaXQgPSBoYXNCaWFzID8gJ2dldEIob3V0cHV0X2NoYW5uZWwpJyA6ICcwLjAnO1xuICBjb25zdCB4U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qgd1NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dENoYW5uZWxzUGVyR3JvdXAgPSB3U2hhcGVbMV07XG4gIGNvbnN0IGlucHV0Q2hhbm5lbHNQZXJHcm91cCA9IHdTaGFwZVswXSAvIGF0dHJpYnV0ZXMuZ3JvdXA7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW2lucHV0c1swXS5kaW1zWzBdLCBpbnB1dHNbMV0uZGltc1sxXSAqIGF0dHJpYnV0ZXMuZ3JvdXAsIC4uLmF0dHJpYnV0ZXMub3V0cHV0U2hhcGVdO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IHsgYWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb24gfSA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXMpO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgY29uc3QgaXZlYzIgc3RyaWRlcyA9IGl2ZWMyKCR7YXR0cmlidXRlcy5zdHJpZGVzWzBdfSwgJHthdHRyaWJ1dGVzLnN0cmlkZXNbMV19KTtcbiAgY29uc3QgaXZlYzIgcGFkcyA9IGl2ZWMyKCR7YXR0cmlidXRlcy5wYWRzWzBdfSwgJHthdHRyaWJ1dGVzLnBhZHNbMV19KTtcbiAgJHthY3RpdmF0aW9uRnVuY3Rpb259XG4gIHZvaWQgbWFpbigpIHtcbiAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICBpbnQgYmF0Y2ggPSBjb29yZHMueDtcbiAgICBpbnQgb3V0cHV0X2NoYW5uZWwgPSBjb29yZHMueTtcblxuICAgIGl2ZWMyIGxvYyA9IGNvb3Jkcy56dyArIHBhZHM7XG5cbiAgICBpbnQgZ3JvdXBfaWQgPSBvdXRwdXRfY2hhbm5lbCAvICR7b3V0cHV0Q2hhbm5lbHNQZXJHcm91cH07XG4gICAgaW50IHdPdXRDaGFubmVsID0gb3V0cHV0X2NoYW5uZWwgLSBncm91cF9pZCAqICR7b3V0cHV0Q2hhbm5lbHNQZXJHcm91cH07XG5cbiAgICBmbG9hdCB2YWx1ZSA9ICR7dmFsdWVJbml0fTtcbiAgICBmb3IgKGludCBpbkNoYW5uZWxPZmZzZXQgPSAwOyBpbkNoYW5uZWxPZmZzZXQgPCAke2lucHV0Q2hhbm5lbHNQZXJHcm91cH07IGluQ2hhbm5lbE9mZnNldCsrKSB7XG4gICAgICBpbnQgaW5wdXRfY2hhbm5lbCA9IGdyb3VwX2lkICogJHtpbnB1dENoYW5uZWxzUGVyR3JvdXB9ICsgaW5DaGFubmVsT2Zmc2V0O1xuICAgICAgZm9yIChpbnQgd1dPZmYgPSAwOyB3V09mZiA8ICR7d1NoYXBlWzJdfTsgd1dPZmYrKykge1xuICAgICAgICBmb3IgKGludCB3SE9mZiA9IDA7IHdIT2ZmIDwgJHt3U2hhcGVbM119OyB3SE9mZisrKSB7XG4gICAgICAgICAgaXZlYzIgd09mZiA9IGl2ZWMyKHdXT2ZmICogJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1swXX0sIHdIT2ZmICogJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXX0pO1xuICAgICAgICAgIGl2ZWMyIHdMb2MgPSBsb2MgLSB3T2ZmO1xuICAgICAgICAgIGl2ZWMyIHdMb2NJbiA9IHdMb2MgLyBzdHJpZGVzO1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHdMb2NJbiAqIHN0cmlkZXMgPT0gd0xvYyAmJlxuICAgICAgICAgICAgd0xvY0luLnggPj0gMCAmJiB3TG9jSW4ueCA8ICR7eFNoYXBlWzJdfSAmJlxuICAgICAgICAgICAgd0xvY0luLnkgPj0gMCAmJiB3TG9jSW4ueSA8ICR7eFNoYXBlWzNdfVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgZmxvYXQgeFZhbCA9IGdldFgoYmF0Y2gsIGlucHV0X2NoYW5uZWwsIHdMb2NJbi55LCB3TG9jSW4ueCk7XG4gICAgICAgICAgICBmbG9hdCB3VmFsID0gZ2V0VyhpbnB1dF9jaGFubmVsLCB3T3V0Q2hhbm5lbCwgd0hPZmYsIHdXT2ZmKTtcbiAgICAgICAgICAgIHZhbHVlICs9IHhWYWwgKiB3VmFsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQodmFsdWUsIC4wLCAuMCwgLjApO1xuICB9XG5gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRDb252VHJhbnNwb3NlUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlQ29udlRyYW5zcG9zZVByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoID4gMiwgYXR0cmlidXRlcy5jYWNoZUtleSk7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVVbnBhY2tlZENvbnZUcmFuc3Bvc2VQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIG1ldGFkYXRhLCBhdHRyaWJ1dGVzKSxcbiAgfTtcbn07XG5cbmNvbnN0IGNvbnZUcmFuc3Bvc2UyRFVucGFja2VkID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgcmVzdWx0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgY3JlYXRlVW5wYWNrZWRDb252VHJhbnNwb3NlUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5jb25zdCBnZXRBZGp1c3RlZENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzID0gPFQgZXh0ZW5kcyBDb252VHJhbnNwb3NlQXR0cmlidXRlcz4oYXR0cmlidXRlczogVCwgaW5wdXRzOiBUZW5zb3JbXSk6IFQgPT4ge1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGUuc2xpY2UoKTtcbiAgLy8gaWYga2VybmVsU2hhcGUgaXMgbm90IHNwZWNpZmllZCBpbiB0aGUgYXR0cmlidXRlcyBvZiB0aGlzIG9wLCBpbmZlciBpdCBmcm9tIHRoZSB3ZWlnaHQgdGVuc29yIGRpbXNcbiAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChsZXQgaSA9IDI7IGkgPCBpbnB1dHNbMV0uZGltcy5sZW5ndGg7ICsraSkge1xuICAgICAga2VybmVsU2hhcGUucHVzaChpbnB1dHNbMV0uZGltc1tpXSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMucGFkcy5zbGljZSgpO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGF0dHJpYnV0ZXMub3V0cHV0U2hhcGUuc2xpY2UoKTtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICAvLyBJZiBvdXRwdXRTaGFwZSBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgb3AsIGluZmVyIGl0IGZyb20gdGhlIHBhcmFtZXRlcnNcbiAgLy8gU2ltaWxhcmx5LCBhdXRvbWF0aWNhbGx5IGluZmVyIHBhZHMgaWYgbm90IHNwZWNpZmllZFxuICBjYWxjdWxhdGVPdXRwdXRTaGFwZUFuZFBhZHMoXG4gICAgaW5wdXRTaGFwZSxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBhdHRyaWJ1dGVzLmRpbGF0aW9ucyxcbiAgICBhdHRyaWJ1dGVzLmF1dG9QYWQsXG4gICAgcGFkcyxcbiAgICBhdHRyaWJ1dGVzLnN0cmlkZXMsXG4gICAgYXR0cmlidXRlcy5vdXRwdXRQYWRkaW5nLFxuICAgIG91dHB1dFNoYXBlLFxuICApO1xuXG4gIC8vIGFsd2F5cyByZXR1cm4gYSBuZXcgb2JqZWN0IHNvIGRvZXMgbm90IG1vZGlmeSB0aGUgb3JpZ2luYWwgYXR0cmlidXRlc1xuICBjb25zdCBuZXdBdHRyaWJ1dGVzOiBUID0gT2JqZWN0LmFzc2lnbih7fSwgYXR0cmlidXRlcyk7XG4gIE9iamVjdC5hc3NpZ24obmV3QXR0cmlidXRlcywgeyBrZXJuZWxTaGFwZSwgcGFkcywgb3V0cHV0U2hhcGUsIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH0pO1xuICByZXR1cm4gbmV3QXR0cmlidXRlcztcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXR0cmlidXRlcyA9IG5vZGUuYXR0cmlidXRlcztcbiAgY29uc3QgYWN0aXZhdGlvbkF0dHJpYnV0ZXMgPSBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMoYXR0cmlidXRlcyk7XG4gIC8vIFRPRE8gOiBNYWtlIHRoaXMgZ2VuZXJpYyBlbm91Z2ggdG8gY29tcHV0ZSBkZWZhdWx0IGF0dHJpYnV0ZXMgZm9yIG11bHRpLWRpbWVuc2lvbmFsIGNvbnZcbiAgY29uc3QgYXV0b1BhZCA9IGF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdhdXRvX3BhZCcsICdOT1RTRVQnKTtcbiAgY29uc3QgZGlsYXRpb25zID0gYXR0cmlidXRlcy5nZXRJbnRzKCdkaWxhdGlvbnMnLCBbMSwgMV0pO1xuICBjb25zdCBncm91cCA9IGF0dHJpYnV0ZXMuZ2V0SW50KCdncm91cCcsIDEpO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMuZ2V0SW50cygna2VybmVsX3NoYXBlJywgW10pO1xuICBjb25zdCBvdXRwdXRQYWRkaW5nID0gYXR0cmlidXRlcy5nZXRJbnRzKCdvdXRwdXRfcGFkZGluZycsIFswLCAwXSk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gYXR0cmlidXRlcy5nZXRJbnRzKCdvdXRwdXRfc2hhcGUnLCBbXSk7XG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnLCBbMCwgMCwgMCwgMF0pO1xuICBjb25zdCBzdHJpZGVzID0gYXR0cmlidXRlcy5nZXRJbnRzKCdzdHJpZGVzJywgWzEsIDFdKTtcblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBhdXRvUGFkLFxuICAgIGRpbGF0aW9ucyxcbiAgICBncm91cCxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBvdXRwdXRQYWRkaW5nLFxuICAgIG91dHB1dFNoYXBlLFxuICAgIHBhZHMsXG4gICAgc3RyaWRlcyxcbiAgICAuLi5hY3RpdmF0aW9uQXR0cmlidXRlcyxcbiAgfSk7XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICAvLyBSZWZlciB0byB0aGUgYmVsb3cgbGluayBmb3IgYWxsIGlucHV0IGNoZWNrc1xuICAvLyBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFpbi9kb2NzL09wZXJhdG9ycy5tZCNDb252XG4gIGlmICghaW5wdXRzIHx8IChpbnB1dHMubGVuZ3RoICE9PSAyICYmIGlucHV0cy5sZW5ndGggIT09IDMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252IHJlcXVpcmVzIDIgb3IgMyBpbnB1dHMnKTtcbiAgfVxuXG4gIC8vIFRPRE8gOiBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBtdWx0aS1kaW1lbnNpb25hbCBjb252XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQgfHwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgb25seSBzdXBwb3J0IDItZGltZW5zaW9uYWwgY29udicpO1xuICB9XG5cbiAgLy8gRklMVEVSX0lOX0NIQU5ORUwgc2hvdWxkIGJlIGVxdWFsIHRvIERBVEFfQ0hBTk5FTFxuICBjb25zdCBkYXRhQ2hhbm5lbCA9IGlucHV0c1swXS5kaW1zWzFdO1xuICBjb25zdCBmaWx0ZXJJbkNoYW5uZWwgPSBpbnB1dHNbMV0uZGltc1swXTtcbiAgaWYgKGRhdGFDaGFubmVsICE9PSBmaWx0ZXJJbkNoYW5uZWwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUwnKTtcbiAgfVxuXG4gIGNvbnN0IGZlYXR1cmVNYXBzID0gaW5wdXRzWzFdLmRpbXNbMV0gKiBhdHRyaWJ1dGVzLmdyb3VwO1xuXG4gIC8vIGlmIGJpYXMgaXMgcHJvdmlkZWQgaXQgc2hvdWxkIGJlIDFEIGFuZCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHNob3VsZCBiZSBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGZlYXR1cmUgbWFwc1xuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiAoaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAxIHx8IGlucHV0c1syXS5kaW1zWzBdICE9PSBmZWF0dXJlTWFwcykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYmlhcycpO1xuICB9XG5cbiAgY29uc3Qgc3BhdGlhbFJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAyO1xuICAvLyB3cm9uZyBkaWxhdGlvbnMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLmRpbGF0aW9ucy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBkaWxhdGlvbnMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3Jvbmcgc3RyaWRlcyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBzdHJpZGVzIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIHBhZHMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoICE9PSBzcGF0aWFsUmFuayAqIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHBhZHMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmsgKiAyfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIG91dHB1dCBwYWRkaW5nIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5vdXRwdXRQYWRkaW5nLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG91dHB1dF9wYWRkaW5nIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIHNwZWNpZmllZCwgaXQncyBkYXRhIGxlbmd0aCBtdXN0IGJlIDIgbGVzcyB0aGFuIGRpbXMgbGVuZ3RoIG9mIHRoZSB3ZWlnaHRzIHRlbnNvclxuICAvLyAodGhlIGZpcnN0IDIgZGltcyBhcmUgYmF0Y2hfc2l6ZSBhbmQgY2hhbm5lbHMpXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gMCAmJiBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBrZXJuZWwgc2hhcGUnKTtcbiAgfVxuXG4gIC8vIGFzIHdpdGgga2VybmVsU2hhcGUsIG11c3QgaGF2ZSBzYW1lIG51bWJlciBvZiBzcGF0aWFsIGRpbXMgYXMgaW5wdXRcbiAgaWYgKGF0dHJpYnV0ZXMub3V0cHV0U2hhcGUubGVuZ3RoICE9PSAwICYmIGF0dHJpYnV0ZXMub3V0cHV0U2hhcGUubGVuZ3RoICE9PSBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIG91dHB1dCBzaGFwZScpO1xuICB9XG5cbiAgLy8gVE9ETyA6IE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIGZsb2F0NjRcbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgfHwgaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udlRyYW5zcG9zZSBpbnB1dChYLFcpIHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxuXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1syXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnZUcmFuc3Bvc2UgaW5wdXQoYmlhcykgc2hvdWxkIGJlIGZsb2F0IHRlbnNvcicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zcG9zZUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBwZXJtOiBudW1iZXJbXTtcbn1cblxuY29uc3QgdHJhbnNwb3NlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnVHJhbnNwb3NlJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3QgdHJhbnNwb3NlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFRyYW5zcG9zZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFRyYW5zcG9zZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnRyYW5zcG9zZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBhdHRyaWJ1dGVzLnBlcm0pLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFRyYW5zcG9zZUF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogVHJhbnNwb3NlQXR0cmlidXRlcyA9PiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBwZXJtOiBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygncGVybScsIFtdKSB9KTtcblxuY29uc3QgY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8gPSAoXG4gIF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIHBlcm06IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXQuZGltcztcbiAgcGVybSA9IGdldEFkanVzdGVkUGVybShpbnB1dFNoYXBlLCBwZXJtKTtcbiAgY29uc3QgdW5wYWNrZWRPdXRwdXRTaGFwZSA9IGdldE91dHB1dFNoYXBlKGlucHV0U2hhcGUsIHBlcm0pO1xuICBjb25zdCByYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gIC8vIEEgZGltcz1bJHtpbnB1dHNbMF0uZGltcy50b1N0cmluZygpfV1cbiAgLy8gb3V0IERpbXM9WyR7dW5wYWNrZWRPdXRwdXRTaGFwZS50b1N0cmluZygpfV1cbiAgLy8gYmFzZWQgb24gcGVybT1bJHtwZXJtLnRvU3RyaW5nKCl9XVxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke2dldFBlcm1GdW5jdGlvbkJvZHkoJ3Blcm0nLCBwZXJtLCByYW5rKX1cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IGFbJHtyYW5rfV07XG4gICAgICAgIHBlcm0oYSwgaW5kaWNlcyk7XG4gICAgICAgIHJldHVybiBfQShhKTtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLnRyYW5zcG9zZVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogdW5wYWNrZWRPdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRQZXJtID0gKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwZXJtOiBudW1iZXJbXSk6IG51bWJlcltdID0+IHtcbiAgaWYgKHBlcm0gJiYgcGVybS5sZW5ndGggIT09IGlucHV0U2hhcGUubGVuZ3RoKSB7XG4gICAgcGVybSA9IFsuLi5pbnB1dFNoYXBlLmtleXMoKV0ucmV2ZXJzZSgpO1xuICB9XG4gIHJldHVybiBwZXJtO1xufTtcblxuY29uc3QgZ2V0T3V0cHV0U2hhcGUgPSAoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHBlcm06IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10gPT4ge1xuICBwZXJtID0gZ2V0QWRqdXN0ZWRQZXJtKGlucHV0U2hhcGUsIHBlcm0pO1xuICByZXR1cm4gU2hhcGVVdGlsLnNvcnRCYXNlZE9uUGVybShpbnB1dFNoYXBlLCBwZXJtKTtcbn07XG5cbmNvbnN0IGdldFBlcm1GdW5jdGlvbkJvZHkgPSAobmFtZTogc3RyaW5nLCBwZXJtOiBudW1iZXJbXSwgcmFuazogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmV2ZXJzZUZ1bmMgPSBbXTtcbiAgcmV2ZXJzZUZ1bmMucHVzaChgdm9pZCAke25hbWV9KG91dCBpbnQgYVske3Jhbmt9XSwgaW50IHNyY1ske3Jhbmt9XSkge2ApO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7ICsraSkge1xuICAgIHJldmVyc2VGdW5jLnB1c2goYFxcdGFbJHtwZXJtW2ldfV09c3JjWyR7aX1dO2ApO1xuICB9XG4gIHJldmVyc2VGdW5jLnB1c2goJ1xcdH0nKTtcbiAgcmV0dXJuIHJldmVyc2VGdW5jLmpvaW4oJ1xcbicpO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUcmFuc3Bvc2UgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmltcG9ydCB7IHRyYW5zcG9zZSwgVHJhbnNwb3NlQXR0cmlidXRlcyB9IGZyb20gJy4vdHJhbnNwb3NlJztcblxuZXhwb3J0IGludGVyZmFjZSBEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzIHtcbiAgbW9kZTogJ0RDUicgfCAnQ1JEJztcbiAgYmxvY2tzaXplOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBkZXB0aFRvU3BhY2U6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248RGVwdGhUb1NwYWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogRGVwdGhUb1NwYWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3QgYmxvY2tzaXplID0gYXR0cmlidXRlcy5ibG9ja3NpemU7XG4gIGNvbnN0IGJsb2Nrc2l6ZVNxciA9IGJsb2Nrc2l6ZSAqIGJsb2Nrc2l6ZTtcbiAgY29uc3QgdHJhbnNwb3NlUGVybSA9IGF0dHJpYnV0ZXMubW9kZSA9PT0gJ0RDUicgPyBbMCwgMywgNCwgMSwgNSwgMl0gOiBbMCwgMSwgNCwgMiwgNSwgM107XG4gIGNvbnN0IGZpcnN0UmVzaGFwZVNoYXBlID1cbiAgICBhdHRyaWJ1dGVzLm1vZGUgPT09ICdEQ1InXG4gICAgICA/IFtcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1swXSxcbiAgICAgICAgICBibG9ja3NpemUsXG4gICAgICAgICAgYmxvY2tzaXplLFxuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzFdIC8gYmxvY2tzaXplU3FyLFxuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzJdLFxuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzNdLFxuICAgICAgICBdXG4gICAgICA6IFtcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1swXSxcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1sxXSAvIGJsb2Nrc2l6ZVNxcixcbiAgICAgICAgICBibG9ja3NpemUsXG4gICAgICAgICAgYmxvY2tzaXplLFxuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzJdLFxuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzNdLFxuICAgICAgICBdO1xuXG4gIC8vIGNvbnN0IHRyYW5zcG9zZSA9IG5ldyBXZWJHTFRyYW5zcG9zZSgpO1xuICAvLyBjb25zdCBhdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZSh1bmRlZmluZWQpO1xuICAvLyBhdHRyaWJ1dGVzLnNldCgncGVybScsICdpbnRzJywgdHJhbnNwb3NlUGVybSk7XG4gIC8vIHRyYW5zcG9zZS5pbml0aWFsaXplKGF0dHJpYnV0ZXMpO1xuXG4gIC8vIEZpcnN0IHJlc2hhcGVcbiAgY29uc3QgZmlyc3RSZXNoYXBlZFRlbnNvciA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgZmlyc3RSZXNoYXBlU2hhcGUpO1xuXG4gIC8vIHRyYW5zcG9zZVxuICBjb25zdCB0cmFuc3Bvc2VBdHRyaWJ1dGVzOiBUcmFuc3Bvc2VBdHRyaWJ1dGVzID0geyBwZXJtOiB0cmFuc3Bvc2VQZXJtLCBjYWNoZUtleTogYCR7dHJhbnNwb3NlUGVybX1gIH07XG4gIGNvbnN0IFt0cmFuc3Bvc2VPdXRwdXRdID0gdHJhbnNwb3NlKGluZmVyZW5jZUhhbmRsZXIsIFtmaXJzdFJlc2hhcGVkVGVuc29yXSwgdHJhbnNwb3NlQXR0cmlidXRlcyk7XG5cbiAgLy8gU2Vjb25kIHJlc2hhcGVcbiAgY29uc3Qgc2Vjb25kUmVzaGFwZVNoYXBlID0gW1xuICAgIGlucHV0c1swXS5kaW1zWzBdLFxuICAgIGlucHV0c1swXS5kaW1zWzFdIC8gYmxvY2tzaXplU3FyLFxuICAgIGlucHV0c1swXS5kaW1zWzJdICogYmxvY2tzaXplLFxuICAgIGlucHV0c1swXS5kaW1zWzNdICogYmxvY2tzaXplLFxuICBdO1xuICBjb25zdCByZXN1bHQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZCh0cmFuc3Bvc2VPdXRwdXQsIHNlY29uZFJlc2hhcGVTaGFwZSk7XG4gIHJldHVybiBbcmVzdWx0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZURlcHRoVG9TcGFjZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248RGVwdGhUb1NwYWNlQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzID0+IHtcbiAgLy8gcHJvY2Vzc2luZyBub2RlIGF0dHJpYnV0ZXNcbiAgY29uc3QgYmxvY2tzaXplID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYmxvY2tzaXplJyk7XG4gIGlmIChibG9ja3NpemUgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBibG9ja3NpemUgbXVzdCBiZSA+PSAxLCBidXQgZ290IDogJHtibG9ja3NpemV9IGZvciBEZXB0aFRvU3BhY2VgKTtcbiAgfVxuICBjb25zdCBtb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbW9kZScsICdEQ1InKTtcbiAgaWYgKG1vZGUgIT09ICdEQ1InICYmIG1vZGUgIT09ICdDUkQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlY29nbml6ZWQgbW9kZTogJHttb2RlfSBmb3IgRGVwdGhUb1NwYWNlYCk7XG4gIH1cbiAgcmV0dXJuIHsgbW9kZSwgYmxvY2tzaXplIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmIChpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBEZXB0aFRvU3BhY2UgZXhwZWN0IDEgaW5wdXRzLCBidXQgZ290ICR7aW5wdXRzLmxlbmd0aH1gKTtcbiAgfVxuXG4gIC8vIElucHV0IGhhcyB0byBiZSBhIDQtRCB0ZW5zb3JcbiAgLy8gVE9ETzogU3VwcG9ydCBzdHJpbmcgZGVwdGgtdG8tc3BhY2UuXG4gIGlmIChpbnB1dHNbMF0udHlwZSA9PT0gJ3N0cmluZycgfHwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRGVwdGhUb1NwYWNlIGlucHV0IHNob3VsZCBiZSBhIDQtRCBudW1lcmljIHRlbnNvcicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3QgZmxhdHRlbjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxudW1iZXI+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF4aXM6IG51bWJlcixcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBheGlzKTtcblxuICBjb25zdCBvdXRwdXREaW1zID0gU2hhcGVVdGlsLmZsYXR0ZW5TaGFwZShpbnB1dHNbMF0uZGltcywgYXhpcyk7XG4gIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBvdXRwdXREaW1zKV07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VGbGF0dGVuQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxudW1iZXI+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBudW1iZXIgPT5cbiAgbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIDEpOyAvLyBkZWZhdWx0IGF4aXMgaXMgMVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBheGlzOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRmxhdHRlbiByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgY29uc3QgciA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgaWYgKHIgPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NjYWxhciB0ZW5zb3IgaXMgbm90IHN1cHBvcnRlZC4nKTtcbiAgfVxuXG4gIGlmIChheGlzIDwgLXIgfHwgYXhpcyA+IHIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXhpcycpO1xuICB9XG5cbiAgLy8gVE9ETzogU3VwcG9ydCBzdHJpbmcgdHlwZVxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzdHJpbmcgdGVuc29yIGlzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuL2JhY2tlbmQnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yJztcblxuZXhwb3J0IHR5cGUgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxUPiA9IChpbmZlcmVuY2VIYW5kbGVyOiBJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBjb250ZXh0OiBUKSA9PiBUZW5zb3JbXTtcbmV4cG9ydCB0eXBlIE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VD4gPSAobm9kZTogR3JhcGguTm9kZSwgZ3JhcGg6IEdyYXBoKSA9PiBUO1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wZXJhdG9yIHtcbiAgcmVhZG9ubHkgaW1wbDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjx1bmtub3duPjtcbiAgcmVhZG9ubHkgY29udGV4dDogR3JhcGguTm9kZSB8IHVua25vd247XG59XG5cbmV4cG9ydCBjb25zdCBOVU1CRVJfVFlQRVM6IHJlYWRvbmx5IFRlbnNvci5EYXRhVHlwZVtdID0gW1xuICAnZmxvYXQzMicsXG4gICdmbG9hdDY0JyxcbiAgJ2ludDMyJyxcbiAgJ2ludDE2JyxcbiAgJ2ludDgnLFxuICAndWludDE2JyxcbiAgJ3VpbnQzMicsXG4gICd1aW50OCcsXG5dO1xuZXhwb3J0IGNvbnN0IElOVF9UWVBFUzogcmVhZG9ubHkgVGVuc29yLkRhdGFUeXBlW10gPSBbJ2ludDMyJywgJ2ludDE2JywgJ2ludDgnLCAndWludDE2JywgJ3VpbnQzMicsICd1aW50OCddO1xuZXhwb3J0IGNvbnN0IEZMT0FUX1RZUEVTOiByZWFkb25seSBUZW5zb3IuRGF0YVR5cGVbXSA9IFsnZmxvYXQzMicsICdmbG9hdDY0J107XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgTlVNQkVSX1RZUEVTLCBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW50ZXJmYWNlIEdhdGhlckF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBnYXRoZXI6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248R2F0aGVyQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogR2F0aGVyQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzLmF4aXMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVHYXRoZXJQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VHYXRoZXJBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEdhdGhlckF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBHYXRoZXJBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF4aXM6IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnLCAwKSB9KTtcblxuY29uc3QgZ2F0aGVyUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnR2F0aGVyJyxcbiAgaW5wdXROYW1lczogWydBJywgJ0InXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVHYXRoZXJQcm9ncmFtSW5mbyA9IChcbiAgX2hhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhpczogbnVtYmVyLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgaW5kZXhEYXRhU2hhcGUgPSBpbnB1dHNbMV0uZGltcy5zbGljZSgpO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IG5ldyBBcnJheShpbnB1dFNoYXBlLmxlbmd0aCArIGluZGV4RGF0YVNoYXBlLmxlbmd0aCAtIDEpO1xuXG4gIGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhheGlzLCBpbnB1dFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IGluZGV4Q29weU9wczogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRTaGFwZS5sZW5ndGg7IGkrKykge1xuICAgIC8vIG91dHB1dFNoYXBlIGlzIGRpdmlkZWQgaW50byB0aHJlZSBwYXJ0czogQSwgQiwgQ1xuICAgIC8vIHwwICAgICAgICBheGlzfCAgYXhpcyArIGluZGV4RGF0YVNoYXBlLmxlbmd0aCB8ICAgICAgICAgIGVuZHxcbiAgICAvLyB8ICAgICBBICAgICAgIHwgICAgICAgICAgICAgQiAgICAgICAgICAgICAgICAgfCAgICAgIEMgICAgICB8XG4gICAgLy9cbiAgICAvLyBpbnB1dElkeDogW0EsIGlucHV0c1sxXVtCXSwgQ11cbiAgICBpZiAoaSA8IGF4aXMpIHtcbiAgICAgIC8vIEFcbiAgICAgIG91dHB1dFNoYXBlW2ldID0gaW5wdXRTaGFwZVtpXTtcbiAgICAgIGluZGV4Q29weU9wcy5wdXNoKGBpbnB1dElkeFske2l9XSA9IG91dHB1dElkeFske2l9XTtgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGkgPCBheGlzICsgaW5kZXhEYXRhU2hhcGUubGVuZ3RoKSB7XG4gICAgICAgIC8vIEJcbiAgICAgICAgb3V0cHV0U2hhcGVbaV0gPSBpbmRleERhdGFTaGFwZVtpIC0gYXhpc107XG4gICAgICAgIGluZGV4Q29weU9wcy5wdXNoKGBpbmRleERhdGFJZHhbJHtpIC0gYXhpc31dID0gb3V0cHV0SWR4WyR7aX1dO2ApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ1xuICAgICAgICBvdXRwdXRTaGFwZVtpXSA9IGlucHV0U2hhcGVbaSAtIGluZGV4RGF0YVNoYXBlLmxlbmd0aCArIDFdOyAvLyBza2lwIDEgZm9yIGF4aXNcbiAgICAgICAgaW5kZXhDb3B5T3BzLnB1c2goYGlucHV0SWR4WyR7aSAtIGluZGV4RGF0YVNoYXBlLmxlbmd0aCArIDF9XSA9IG91dHB1dElkeFske2l9XTtgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBvcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aCB8fCAxO1xuICBjb25zdCBpcmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBpRHJhbmsgPSBpbmRleERhdGFTaGFwZS5sZW5ndGggfHwgMTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgb3V0cHV0SWR4WyR7b3Jhbmt9XSkge1xuICAgICAgICBpbnQgaW5wdXRJZHhbJHtpcmFua31dO1xuICAgICAgICBpbnQgaW5kZXhEYXRhSWR4WyR7aURyYW5rfV07XG4gICAgICAgIGluZGV4RGF0YUlkeFswXSA9IDA7XG4gICAgICAgICR7aW5kZXhDb3B5T3BzLmpvaW4oJ1xcbiAgICAgICAgJyl9XG4gICAgICAgIGludCBpZHggPSBpbnQoX0IoaW5kZXhEYXRhSWR4KSk7XG4gICAgICAgIGlucHV0SWR4WyR7YXhpc31dID0gaWR4IDwgMCA/IGlkeCArICR7aW5wdXRTaGFwZVtheGlzXX0gOiBpZHg7XG4gICAgICAgIHJldHVybiBfQShpbnB1dElkeCk7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVHYXRoZXJQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBHYXRoZXJBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IHsgLi4uZ2F0aGVyUHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXkgfTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgYXR0cmlidXRlcy5heGlzKSB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhpczogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dhdGhlciByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxuICBjb25zdCB0ZW5zb3JSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoO1xuICBpZiAodGVuc29yUmFuayA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKGF4aXMgPCAtdGVuc29yUmFuayB8fCBheGlzID4gdGVuc29yUmFuayAtIDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXhpcy4nKTtcbiAgfVxuICBpZiAoTlVNQkVSX1RZUEVTLmluZGV4T2YoaW5wdXRzWzBdLnR5cGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInICYmIGlucHV0c1sxXS50eXBlICE9PSAnaW50MTYnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBHZW1tVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEdlbW1BdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgdHJhbnNBOiBib29sZWFuO1xuICB0cmFuc0I6IGJvb2xlYW47XG4gIGFscGhhOiBudW1iZXI7XG4gIGJldGE6IG51bWJlcjtcbiAgaXNPcHRpb25hbEM6IGJvb2xlYW47IC8vIGluIG9wc2V0IDExLCBDIGJlY29tZXMgb3B0aW9uYWxcbn1cblxuZXhwb3J0IGNvbnN0IGdlbW06IE9wZXJhdG9ySW1wbGVtZW50YXRpb248R2VtbUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEdlbW1BdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVHZW1tUHJvZ3JhbUluZm9Mb2FkZXIoaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgcGFyc2VHZW1tQXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlLCBpc09wdGlvbmFsQzogYm9vbGVhbik6IEdlbW1BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgdHJhbnNBID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgndHJhbnNBJywgMCkgIT09IDA7XG4gIGNvbnN0IHRyYW5zQiA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3RyYW5zQicsIDApICE9PSAwO1xuICBjb25zdCBhbHBoYSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYWxwaGEnLCAxLjApO1xuICBjb25zdCBiZXRhID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdiZXRhJywgMS4wKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IHRyYW5zQSwgdHJhbnNCLCBhbHBoYSwgYmV0YSwgaXNPcHRpb25hbEMgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VHZW1tQXR0cmlidXRlc1Y3OiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEdlbW1BdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogR2VtbUF0dHJpYnV0ZXMgPT5cbiAgcGFyc2VHZW1tQXR0cmlidXRlcyhub2RlLCBmYWxzZSk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdlbW1BdHRyaWJ1dGVzVjExOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEdlbW1BdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogR2VtbUF0dHJpYnV0ZXMgPT5cbiAgcGFyc2VHZW1tQXR0cmlidXRlcyhub2RlLCB0cnVlKTtcblxuY29uc3QgY3JlYXRlR2VtbVByb2dyYW1JbmZvTG9hZGVyID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEdlbW1BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IHtcbiAgICBuYW1lOiAnR2VtbScsXG4gICAgaW5wdXROYW1lczogaW5wdXRzLmxlbmd0aCA9PT0gMyA/IFsnQScsICdCJywgJ0MnXSA6IFsnQScsICdCJ10sXG4gICAgaW5wdXRUeXBlczpcbiAgICAgIGlucHV0cy5sZW5ndGggPT09IDNcbiAgICAgICAgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF1cbiAgICAgICAgOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgICBrZXk6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gIH07XG5cbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlR2VtbVByb2dyYW1JbmZvKG1ldGFkYXRhLCBpbnB1dHMsIGF0dHJpYnV0ZXMpIH07XG59O1xuXG5jb25zdCBjcmVhdGVHZW1tUHJvZ3JhbUluZm8gPSAoXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEdlbW1BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBiU2hhcGUgPSBpbnB1dHNbMV0uZGltcy5zbGljZSgpO1xuICBjb25zdCBbTSwgTl0gPSBHZW1tVXRpbC5nZXRTaGFwZU9mR2VtbVJlc3VsdChcbiAgICBhU2hhcGUsXG4gICAgYXR0cmlidXRlcy50cmFuc0EsXG4gICAgYlNoYXBlLFxuICAgIGF0dHJpYnV0ZXMudHJhbnNCLFxuICAgIGlucHV0cy5sZW5ndGggPT09IDMgPyBpbnB1dHNbMl0uZGltcyA6IHVuZGVmaW5lZCxcbiAgKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBbTSwgTl07XG4gIGlmICghb3V0cHV0U2hhcGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCB1c2UgZ2VtbSBvbiB0aGUgZ2l2ZW4gdGVuc29yc1wiKTtcbiAgfVxuICBsZXQgc2hhcmVkRGltID0gYVNoYXBlW2FTaGFwZS5sZW5ndGggLSAxXTtcbiAgbGV0IGxpbmUgPSAnJztcbiAgaWYgKGF0dHJpYnV0ZXMudHJhbnNBKSB7XG4gICAgc2hhcmVkRGltID0gYVNoYXBlWzBdO1xuICB9XG4gIGlmIChhdHRyaWJ1dGVzLnRyYW5zQSAmJiBhdHRyaWJ1dGVzLnRyYW5zQikge1xuICAgIGxpbmUgPSAndmFsdWUgKz0gX0FfVChhKSAqIF9CX1QoYik7JztcbiAgfSBlbHNlIGlmIChhdHRyaWJ1dGVzLnRyYW5zQSAmJiAhYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICBsaW5lID0gJ3ZhbHVlICs9IF9BX1QoYSkgKiBfQihiKTsnO1xuICB9IGVsc2UgaWYgKCFhdHRyaWJ1dGVzLnRyYW5zQSAmJiBhdHRyaWJ1dGVzLnRyYW5zQikge1xuICAgIGxpbmUgPSAndmFsdWUgKz0gX0EoYSkgKiBfQl9UKGIpOyc7XG4gIH0gZWxzZSBpZiAoIWF0dHJpYnV0ZXMudHJhbnNBICYmICFhdHRyaWJ1dGVzLnRyYW5zQikge1xuICAgIGxpbmUgPSAndmFsdWUgKz0gX0EoYSkgKiBfQihiKTsnO1xuICB9XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGRlY2xhcmVDID0gaW5wdXRzLmxlbmd0aCA9PT0gMyA/IGBpbnQgY1ske2lucHV0c1syXS5kaW1zLmxlbmd0aH1dO2AgOiAnJztcbiAgY29uc3QgYnJvYWRjYXN0QyA9IGlucHV0cy5sZW5ndGggPT09IDMgPyAnYmNhc3RJbmRpY2VzX0MoaW5kaWNlcywgYyk7JyA6ICcnO1xuICBjb25zdCBjYWxjdWxhdGVDID0gaW5wdXRzLmxlbmd0aCA9PT0gMyA/ICd2YWx1ZSArPSBiZXRhICogX0MoYyk7JyA6ICcnO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IGFbJHtyYW5rfV07XG4gICAgICAgICAgaW50IGJbJHtyYW5rfV07XG4gICAgICAgICAgJHtkZWNsYXJlQ31cblxuICAgICAgICAgIGNvcHlWZWMoaW5kaWNlcywgYSk7XG4gICAgICAgICAgY29weVZlYyhpbmRpY2VzLCBiKTtcbiAgICAgICAgICAke2Jyb2FkY2FzdEN9XG5cbiAgICAgICAgICBmbG9hdCB2YWx1ZSA9IDAuMDtcbiAgICAgICAgICBmb3IgKGludCBrPTA7IGs8JHtzaGFyZWREaW19OyArK2spIHtcbiAgICAgICAgICAgICAgYVske3JhbmsgLSAxfV0gPSBrO1xuICAgICAgICAgICAgICBiWyR7cmFuayAtIDJ9XSA9IGs7XG4gICAgICAgICAgICAgICR7bGluZX1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlICogYWxwaGE7XG4gICAgICAgICAgJHtjYWxjdWxhdGVDfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHZhcmlhYmxlczogW1xuICAgICAgeyBuYW1lOiAnYWxwaGEnLCB0eXBlOiAnZmxvYXQnLCBkYXRhOiBhdHRyaWJ1dGVzLmFscGhhIH0sXG4gICAgICB7IG5hbWU6ICdiZXRhJywgdHlwZTogJ2Zsb2F0JywgZGF0YTogYXR0cmlidXRlcy5iZXRhIH0sXG4gICAgXSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBHZW1tQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgaXMgbWlzc2luZycpO1xuICB9XG4gIGlmIChhdHRyaWJ1dGVzLmlzT3B0aW9uYWxDICYmIChpbnB1dHMubGVuZ3RoIDwgMiB8fCBpbnB1dHMubGVuZ3RoID4gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoIWF0dHJpYnV0ZXMuaXNPcHRpb25hbEMgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMykge1xuICAgIHRocm93IG5ldyBFcnJvcignR2VtbSByZXF1aXJlcyAzIGlucHV0cycpO1xuICB9XG5cbiAgLy8gJ0MnIGNhbiBiZSBvZiBkaW1lbnNpb25hbGl0eSAxIG9yIDIgb25seVxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDEgJiYgaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlIG9mIEMnKTtcbiAgfVxuXG4gIGlmIChcbiAgICAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChpbnB1dHNbMV0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgaW5wdXRzWzJdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMl0udHlwZSAhPT0gJ2Zsb2F0NjQnKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gaW5wdXRzWzFdLnR5cGUgfHwgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgaW5wdXRzWzBdLnR5cGUgIT09IGlucHV0c1syXS50eXBlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgdHlwZXMgYXJlIG1pc21hdGNoZWQnKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgc2NhbGU6IG51bWJlcjtcbiAgYmlhczogbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBpbWFnZVNjYWxlcjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxJbWFnZVNjYWxlckF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEltYWdlU2NhbGVyQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlSW1hZ2VTY2FsZXJQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VJbWFnZVNjYWxlckF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248SW1hZ2VTY2FsZXJBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IEltYWdlU2NhbGVyQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IHNjYWxlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdzY2FsZScpO1xuICBjb25zdCBiaWFzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0cygnYmlhcycpO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgc2NhbGUsIGJpYXMgfSk7XG59O1xuXG5jb25zdCBpbWFnZVNjYWxlclByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0ltYWdlU2NhbGVyJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVJbWFnZVNjYWxlclByb2dyYW1JbmZvID0gKFxuICBfaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBJbWFnZVNjYWxlckF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgZ2V0Qmlhc01ldGhvZCA9IGNyZWF0ZUdldEJpYXNNZXRob2QoYXR0cmlidXRlcy5iaWFzLmxlbmd0aCk7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICR7Z2V0Qmlhc01ldGhvZH1cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgcmV0dXJuIF9YKGluZGljZXMpICogc2NhbGUgKyBnZXRCaWFzKGJpYXMsIGluZGljZXNbMV0pO1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgdmFyaWFibGVzOiBbXG4gICAgICB7IG5hbWU6ICdiaWFzJywgdHlwZTogJ2Zsb2F0JywgYXJyYXlMZW5ndGg6IGF0dHJpYnV0ZXMuYmlhcy5sZW5ndGgsIGRhdGE6IGF0dHJpYnV0ZXMuYmlhcyB9LFxuICAgICAgeyBuYW1lOiAnc2NhbGUnLCB0eXBlOiAnZmxvYXQnLCBkYXRhOiBhdHRyaWJ1dGVzLnNjYWxlIH0sXG4gICAgXSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVJbWFnZVNjYWxlclByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEltYWdlU2NhbGVyQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSB7IC4uLmltYWdlU2NhbGVyUHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXkgfTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlSW1hZ2VTY2FsZXJQcm9ncmFtSW5mbyhoYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBhdHRyaWJ1dGVzKSB9O1xufTtcblxuY29uc3QgY3JlYXRlR2V0Qmlhc01ldGhvZCA9IChudW1DaGFubmVsczogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3QgY29kZUxpbmVzOiBzdHJpbmdbXSA9IFtgZmxvYXQgZ2V0QmlhcyhmbG9hdCBiaWFzWyR7bnVtQ2hhbm5lbHN9XSwgaW50IGNoYW5uZWwpIHtgXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1DaGFubmVsczsgKytpKSB7XG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGlmIChjaGFubmVsID09ICR7aX0pIHsgcmV0dXJuIGJpYXNbJHtpfV07IH1gKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IG51bUNoYW5uZWxzIC0gMSkge1xuICAgICAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyBgZWxzZSB7IHJldHVybiBiaWFzWyR7aX1dOyB9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGVsc2UgaWYgKGNoYW5uZWwgPT0gJHtpfSkgeyByZXR1cm4gYmlhc1ske2l9XTsgfWApO1xuICAgIH1cbiAgfVxuICBjb2RlTGluZXMucHVzaCgnXFx0JyArICd9Jyk7XG4gIHJldHVybiBjb2RlTGluZXMuam9pbignXFxuJyk7XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltYWdlU2NhbGVyIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IGluc3RhbmNlTm9ybWFsaXphdGlvbjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxudW1iZXI+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGVwc2lsb246IG51bWJlcixcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCBtZWFuQW5kVmFyaWFuY2UgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVNZWFuQW5kVmFyaWFuY2VQcm9ncmFtSW5mb0xvYWRlcihpbnB1dHNbMF0pLCBpbnB1dHMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVDb21wdXRlT3V0cHV0UHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBlcHNpbG9uLCBtZWFuQW5kVmFyaWFuY2UuZGltcyksXG4gICAgW2lucHV0c1swXSwgbWVhbkFuZFZhcmlhbmNlLCBpbnB1dHNbMV0sIGlucHV0c1syXV0sXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUluc3RhbmNlTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248bnVtYmVyPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogbnVtYmVyID0+XG4gIG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnZXBzaWxvbicsIDFlLTUpO1xuXG5jb25zdCBtZWFuQW5kVmFyaWFuY2VQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdJbnN0YW5jZU5vcm1hbGl6YXRpb25fTWVhbkFuZFZhcmlhbmNlJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVNZWFuQW5kVmFyaWFuY2VQcm9ncmFtSW5mbyA9IChtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLCBpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCB4RGltcyA9IGlucHV0LmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgY2hhbm5lbCA9IHhEaW1zWzFdO1xuICBjb25zdCBjaGFubmVsU2l6ZSA9IHhEaW1zWzJdICogeERpbXNbM107XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW3hEaW1zWzBdLCBjaGFubmVsXTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICB2ZWM0IHByb2Nlc3MoaW50WzJdIGluZGljZXMpIHtcbiAgICAgICAgdmVjNCB2ID0gdmVjNCgwLjApO1xuICAgICAgICBpbnQgYVs0XTtcbiAgICAgICAgYVswXSA9IGluZGljZXNbMF07XG4gICAgICAgIGFbMV0gPSBpbmRpY2VzWzFdO1xuICAgICAgICBmbG9hdCB0ZW1wID0gMC4wO1xuICAgICAgICBmb3IoaW50IGEyPTA7IGEyPCR7eERpbXNbMl19OyBhMisrKSB7XG4gICAgICAgICAgYVsyXSA9IGEyO1xuICAgICAgICAgIGZvcihpbnQgYTM9MDsgYTM8JHt4RGltc1szXX07IGEzKyspIHtcbiAgICAgICAgICAgIGFbM10gPSBhMztcbiAgICAgICAgICAgIGZsb2F0IHggPSBfWChhKTtcbiAgICAgICAgICAgIHRlbXAgKz0geDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZmxvYXQgbWVhbiA9IHRlbXAgLyBmbG9hdCgke2NoYW5uZWxTaXplfSk7XG4gICAgICAgIHRlbXAgPSAwLjA7XG4gICAgICAgIGZvcihpbnQgYTI9MDsgYTI8JHt4RGltc1syXX07IGEyKyspIHtcbiAgICAgICAgICBhWzJdID0gYTI7XG4gICAgICAgICAgZm9yKGludCBhMz0wOyBhMzwke3hEaW1zWzNdfTsgYTMrKykge1xuICAgICAgICAgICAgYVszXSA9IGEzO1xuICAgICAgICAgICAgZmxvYXQgeCA9IF9YKGEpO1xuICAgICAgICAgICAgdGVtcCArPSAoeCAtIG1lYW4pICogKHggLSBtZWFuKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdi5yID0gbWVhbjtcbiAgICAgICAgdi5nID0gdGVtcCAvIGZsb2F0KCR7Y2hhbm5lbFNpemV9KTtcblxuICAgICAgICByZXR1cm4gdjtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24gfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVNZWFuQW5kVmFyaWFuY2VQcm9ncmFtSW5mb0xvYWRlciA9IChpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4gKHtcbiAgLi4ubWVhbkFuZFZhcmlhbmNlUHJvZ3JhbU1ldGFkYXRhLFxuICBnZXQ6ICgpID0+IGNyZWF0ZU1lYW5BbmRWYXJpYW5jZVByb2dyYW1JbmZvKG1lYW5BbmRWYXJpYW5jZVByb2dyYW1NZXRhZGF0YSwgaW5wdXQpLFxufSk7XG5cbmNvbnN0IGNvbXB1dGVPdXRwdXRQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdJbnN0YW5jZU5vcm1hbGl6YXRpb25fQ29tcHV0ZU91dHB1dCcsXG4gIGlucHV0TmFtZXM6IFsnWCcsICdNZWFuQW5kVmFyaWFuY2UnLCAnU2NhbGUnLCAnQiddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24sIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVDb21wdXRlT3V0cHV0UHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXQ6IFRlbnNvcixcbiAgZXBzaWxvbjogbnVtYmVyLFxuICBtZWFuQW5kVmFyaWFuY2VTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgW3RleHR1cmVXaWR0aCwgdGV4dHVyZUhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBtZWFuQW5kVmFyaWFuY2VTaGFwZSxcbiAgICBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uLFxuICApO1xuICBjb25zdCBbbWVhbkFuZFZhcmlhbmNlV2lkdGgsIG1lYW5BbmRWYXJpYW5jZUhlaWdodF0gPSBbdGV4dHVyZVdpZHRoIC8gNCwgdGV4dHVyZUhlaWdodF07XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIHZlYzQgZ2V0X01lYW5BbmRWYXJpYW5jZShpbnRbMl0gbXYpIHtcbiAgICAgICAgaW50IG9mZnNldCA9IGluZGljZXNUb09mZnNldF9NZWFuQW5kVmFyaWFuY2UobXYpO1xuICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHttZWFuQW5kVmFyaWFuY2VXaWR0aH0sICR7bWVhbkFuZFZhcmlhbmNlSGVpZ2h0fSk7XG4gICAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfShNZWFuQW5kVmFyaWFuY2UsIGNvb3Jkcyk7XG4gICAgICB9XG5cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50WzRdIGluZGljZXMpIHtcbiAgICAgICAgaW50IG12WzJdO1xuICAgICAgICBtdlswXSA9IGluZGljZXNbMF07XG4gICAgICAgIG12WzFdID0gaW5kaWNlc1sxXTtcbiAgICAgICAgdmVjNCBtZWFuX2FuZF92YXJpYW5jZSA9IGdldF9NZWFuQW5kVmFyaWFuY2UobXYpO1xuICAgICAgICBmbG9hdCBtZWFuID0gbWVhbl9hbmRfdmFyaWFuY2UucjtcbiAgICAgICAgZmxvYXQgdmFyaWFuY2UgPSBtZWFuX2FuZF92YXJpYW5jZS5nO1xuXG4gICAgICAgIGludCBzYlsxXTtcbiAgICAgICAgc2JbMF0gPSBpbmRpY2VzWzFdO1xuICAgICAgICBmbG9hdCBzY2FsZSA9IF9TY2FsZShzYik7XG4gICAgICAgIGZsb2F0IGIgPSBfQihzYik7XG5cbiAgICAgICAgcmV0dXJuIHNjYWxlICogKF9YKGluZGljZXMpIC0gbWVhbikgLyBzcXJ0KHZhcmlhbmNlICsgZXBzaWxvbikgKyBiO1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0LmRpbXMsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHZhcmlhYmxlczogW3sgbmFtZTogJ2Vwc2lsb24nLCB0eXBlOiAnZmxvYXQnLCBkYXRhOiBlcHNpbG9uIH1dLFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZUNvbXB1dGVPdXRwdXRQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBlcHNpbG9uOiBudW1iZXIsXG4gIG1lYW5BbmRWYXJpYW5jZVNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSB7IC4uLmNvbXB1dGVPdXRwdXRQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYCR7ZXBzaWxvbn1gIH07XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVDb21wdXRlT3V0cHV0UHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIGlucHV0LCBlcHNpbG9uLCBtZWFuQW5kVmFyaWFuY2VTaGFwZSksXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0luc3RhbmNlTm9ybWFsaXphdGlvbiByZXF1aXJlcyAzIGlucHV0cy4nKTtcbiAgfVxuXG4gIGNvbnN0IFggPSBpbnB1dHNbMF07XG4gIGNvbnN0IHNjYWxlID0gaW5wdXRzWzFdO1xuICBjb25zdCBCID0gaW5wdXRzWzJdO1xuXG4gIC8vIGlucHV0IHNob3VsZCBhdCBsZWFzdCBoYXZlIHRocmVlIGRpbWVuc2lvbnMgLSBOLEMsZGltMSwuLi4sZGltblxuICAvLyBvdGhlciBpbnB1dHMgY2FuIGhhdmUgb25seSBvbmUgZGltZW5zaW9uc1xuICBpZiAoWC5kaW1zLmxlbmd0aCA8IDMgfHwgc2NhbGUuZGltcy5sZW5ndGggIT09IDEgfHwgQi5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoc2NhbGUuZGltc1swXSAhPT0gWC5kaW1zWzFdIHx8IEIuZGltc1swXSAhPT0gWC5kaW1zWzFdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBzaGFwZXMgYXJlIG1pc21hdGNoZWQuJyk7XG4gIH1cbiAgaWYgKFxuICAgIChYLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBYLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAoc2NhbGUudHlwZSAhPT0gJ2Zsb2F0MzInICYmIHNjYWxlLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAoQi50eXBlICE9PSAnZmxvYXQzMicgJiYgQi50eXBlICE9PSAnZmxvYXQ2NCcpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ09ubHkgc3VwcG9ydCA0LUQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBMcm5BdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgYWxwaGE6IG51bWJlcjtcbiAgYmV0YTogbnVtYmVyO1xuICBiaWFzOiBudW1iZXI7XG4gIHNpemU6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGxybjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxMcm5BdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBMcm5BdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIC8vIGlmIChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24ucGFjaykge1xuICAvLyAgIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlUGFja2VkTHJuUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgLy8gICBpbnB1dHMpXTtcbiAgLy8gfSBlbHNlIHtcbiAgcmV0dXJuIFtpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVMcm5Qcm9ncmFtSW5mb0xvYWRlcihpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpXTtcbiAgLy99XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VMcm5BdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPExybkF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBMcm5BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYWxwaGEgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2FscGhhJywgMC4wMDAxKTtcbiAgY29uc3QgYmV0YSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYmV0YScsIDAuNzUpO1xuICBjb25zdCBiaWFzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdiaWFzJywgMS4wKTtcbiAgY29uc3Qgc2l6ZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3NpemUnKTtcblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYWxwaGEsIGJldGEsIGJpYXMsIHNpemUgfSk7XG59O1xuXG5jb25zdCBscm5Qcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdMUk4nLFxuICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZUxyblByb2dyYW1JbmZvKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IExybkF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyB7XG4gIGNvbnN0IEMgPSBpbnB1dHNbMF0uZGltc1sxXTtcbiAgY29uc3QgcmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgY29uc3QgZnJvbSA9IC1NYXRoLmZsb29yKChhdHRyaWJ1dGVzLnNpemUgLSAxKSAvIDIpO1xuICBjb25zdCB0byA9IE1hdGguY2VpbCgoYXR0cmlidXRlcy5zaXplIC0gMSkgLyAyKTtcbiAgY29uc3QgYWxwaGEgPSBgZmxvYXQoJHthdHRyaWJ1dGVzLmFscGhhfSkgLyBmbG9hdCgke2F0dHJpYnV0ZXMuc2l6ZX0pYDtcbiAgY29uc3QgYmlhcyA9IGBmbG9hdCgke2F0dHJpYnV0ZXMuYmlhc30pYDtcbiAgY29uc3QgYmV0YSA9IGBmbG9hdCgke2F0dHJpYnV0ZXMuYmV0YX0pYDtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICBpbnQgYyA9IGluZGljZXNbMV07XG4gICAgICAgIGZsb2F0IHggPSBfWChpbmRpY2VzKTtcbiAgICAgICAgZmxvYXQgc3F1YXJlX3N1bSA9IDAuMDtcblxuICAgICAgICBmb3IgKGludCBpID0gJHtmcm9tfTsgaSA8PSAke3RvfTsgaSsrKSB7XG4gICAgICAgICAgaW50IGlkeCA9IGMgKyBpO1xuICAgICAgICAgIGlmIChjID49IDAgJiYgYyA8ICR7Q30pIHtcbiAgICAgICAgICAgIGluZGljZXNbMV0gPSBpZHg7XG4gICAgICAgICAgICBmbG9hdCBqID0gX1goaW5kaWNlcyk7XG4gICAgICAgICAgICBzcXVhcmVfc3VtICs9IGogKiBqO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCAvIHBvdygke2JpYXN9ICsgJHthbHBoYX0gKiBzcXVhcmVfc3VtLCAke2JldGF9KTtcbiAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5scm5Qcm9ncmFtTWV0YWRhdGEsXG4gICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dHNbMF0uZGltcywgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUxyblByb2dyYW1JbmZvTG9hZGVyKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IExybkF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mb0xvYWRlciB7XG4gIHJldHVybiB7IC4uLmxyblByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LCBnZXQ6ICgpID0+IGNyZWF0ZUxyblByb2dyYW1JbmZvKGlucHV0cywgYXR0cmlidXRlcykgfTtcbn1cblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdMUk4gcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgb25seSBzdXBwb3J0IExSTiBmb3IgaW5wdXQgd2l0aCBcIk5DSFdcIiBmb3JtYXQnKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgc2hvdWxkIGJlIGZsb2F0IHR5cGUnKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IGdldEdsc2wsIEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFkQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IG1vZGU6IHN0cmluZztcbiAgcmVhZG9ubHkgcGFkczogbnVtYmVyW107XG4gIHJlYWRvbmx5IHZhbHVlOiBudW1iZXI7XG59XG5cbmNvbnN0IHBhZFByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1BhZCcsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHBhZFYyOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFBhZEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFBhZEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzVjIoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4ucGFkUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVQYWRQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGF0dHJpYnV0ZXMpLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VQYWRBdHRyaWJ1dGVzVjI6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248UGFkQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IFBhZEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBtb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbW9kZScsICdjb25zdGFudCcpO1xuICBjb25zdCB2YWx1ZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgndmFsdWUnLCAwLjApO1xuICBjb25zdCBwYWRzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IG1vZGUsIHZhbHVlLCBwYWRzIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhZFYxMTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxzdHJpbmc+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIG1vZGU6IHN0cmluZyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHNWMTEoaW5wdXRzKTtcbiAgY29uc3QgYXR0cnVidXRlcyA9IGdlbmVyYXRlUGFkQXR0cmlidXRlc0Zyb21JbnB1dHMoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBtb2RlKTtcbiAgcmV0dXJuIHBhZFYyKGluZmVyZW5jZUhhbmRsZXIsIFtpbnB1dHNbMF1dLCBhdHRydWJ1dGVzKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVBhZEF0dHJpYnV0ZXNWMTE6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248c3RyaW5nPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogc3RyaW5nID0+XG4gIG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ21vZGUnLCAnY29uc3RhbnQnKTtcblxuY29uc3QgZ2VuZXJhdGVQYWRBdHRyaWJ1dGVzRnJvbUlucHV0cyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBtb2RlOiBzdHJpbmcsXG4pOiBQYWRBdHRyaWJ1dGVzID0+IHtcbiAgaWYgKFxuICAgICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMV0uZGF0YUlkKSB8fFxuICAgIChpbnB1dHMubGVuZ3RoID49IDMgJiYgIWluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1syXS5kYXRhSWQpKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2R5bmFtaWMgcGFkIGF0dHJpYnV0ZXMgYXJlIG5vdCBhbGxvd2VkJyk7XG4gIH1cblxuICBjb25zdCBwYWRzID0gQXJyYXkuZnJvbShpbnB1dHNbMV0uaW50ZWdlckRhdGEpO1xuICBjb25zdCB2YWx1ZSA9IGlucHV0cy5sZW5ndGggPj0gMyA/IGlucHV0c1syXS5mbG9hdERhdGFbMF0gOiAwLjA7XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IG1vZGUsIHBhZHMsIHZhbHVlIH0pO1xufTtcblxuY29uc3QgY3JlYXRlUGFkUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgYXR0cmlidXRlczogUGFkQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBTaGFwZVV0aWwucGFkU2hhcGUoaW5wdXQuZGltcy5zbGljZSgpLCBhdHRyaWJ1dGVzLnBhZHMpO1xuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBwYWRGdW5jdGlvbiA9IGdldFBhZEZ1bmN0aW9uKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0LCBhdHRyaWJ1dGVzKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtwYWRGdW5jdGlvbn1cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50WyR7cmFua31dIGluZGljZXMpIHtcbiAgICAgICAgICByZXR1cm4gcGFkQShpbmRpY2VzKTtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdQYWQnLFxuICAgIGlucHV0TmFtZXM6IFsnQSddLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0c1YyID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUGFkIHJlcXVpcmVzIDEgaW5wdXQnKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzVjExID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgKGlucHV0cy5sZW5ndGggIT09IDIgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhZCByZXF1aXJlcyAyIG9yIDMgaW5wdXRzJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0cy5sZW5ndGggPj0gMyAmJiBpbnB1dHNbMl0udHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcblxuY29uc3QgZ2V0UGFkRnVuY3Rpb24gPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yLCBhdHRyaWJ1dGVzOiBQYWRBdHRyaWJ1dGVzKTogc3RyaW5nID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBbd2lkdGgsIGhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChpbnB1dC5kaW1zLCBUZXh0dXJlVHlwZS51bnBhY2tlZCk7XG4gIGNvbnN0IHN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoaW5wdXQuZGltcyk7XG5cbiAgc3dpdGNoIChhdHRyaWJ1dGVzLm1vZGUpIHtcbiAgICBjYXNlICdjb25zdGFudCc6XG4gICAgICByZXR1cm4gZ2V0UGFkQ29uc3RhbnQoZ2xzbCwgaW5wdXQuZGltcywgc3RyaWRlcywgd2lkdGgsIGhlaWdodCwgYXR0cmlidXRlcy5wYWRzLCBhdHRyaWJ1dGVzLnZhbHVlKTtcbiAgICBjYXNlICdyZWZsZWN0JzpcbiAgICAgIHJldHVybiBnZXRQYWRSZWZsZWN0KGdsc2wsIGlucHV0LmRpbXMsIHN0cmlkZXMsIHdpZHRoLCBoZWlnaHQsIGF0dHJpYnV0ZXMucGFkcyk7XG4gICAgY2FzZSAnZWRnZSc6XG4gICAgICByZXR1cm4gZ2V0UGFkRWRnZShnbHNsLCBpbnB1dC5kaW1zLCBzdHJpZGVzLCB3aWR0aCwgaGVpZ2h0LCBhdHRyaWJ1dGVzLnBhZHMpO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgbW9kZScpO1xuICB9XG59O1xuXG5jb25zdCBnZXRQYWRDb25zdGFudCA9IChcbiAgZ2xzbDogR2xzbCxcbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgd2lkdGg6IG51bWJlcixcbiAgaGVpZ2h0OiBudW1iZXIsXG4gIHBhZHM6IG51bWJlcltdLFxuICB2YWx1ZTogbnVtYmVyLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgbGV0IGJsb2NrID0gJyc7XG4gIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICBibG9jayArPSBgXG4gICAgICAgIGsgPSBtWyR7aX1dIC0gJHtwYWRzW2ldfTtcbiAgICAgICAgaWYgKGsgPCAwKSAgcmV0dXJuIGNvbnN0YW50O1xuICAgICAgICBpZiAoayA+PSAke3NoYXBlW2ldfSkgcmV0dXJuIGNvbnN0YW50O1xuICAgICAgICBvZmZzZXQgKz0gayAqICR7c3RyaWRlc1tpXX07XG4gICAgICAgIGA7XG4gIH1cbiAgcmV0dXJuIGBcbiAgICAgIGZsb2F0IHBhZEEoaW50IG1bJHtyYW5rfV0pIHtcbiAgICAgICAgY29uc3QgZmxvYXQgY29uc3RhbnQgPSBmbG9hdCgke3ZhbHVlfSk7XG4gICAgICAgIGludCBvZmZzZXQgPSAwO1xuICAgICAgICBpbnQgayA9IDA7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgZmxvYXQgdmFsdWUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgY29vcmRzKSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGA7XG59O1xuXG5jb25zdCBnZXRQYWRSZWZsZWN0ID0gKFxuICBnbHNsOiBHbHNsLFxuICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICB3aWR0aDogbnVtYmVyLFxuICBoZWlnaHQ6IG51bWJlcixcbiAgcGFkczogbnVtYmVyW10sXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gIGxldCBibG9jayA9ICcnO1xuICBmb3IgKGxldCBpID0gcmFuayAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICBrID0gbVske2l9XSAtICR7cGFkc1tpXX07XG4gICAgICAgIGlmIChrIDwgMCkgeyBrID0gLWs7IH1cbiAgICAgICAge1xuICAgICAgICAgIGNvbnN0IGludCBfMm5fMSA9ICR7MiAqIChzaGFwZVtpXSAtIDEpfTtcbiAgICAgICAgICBrID0gaW50KCBtb2QoIGZsb2F0KGspLCBmbG9hdChfMm5fMSkgKSApIDtcbiAgICAgICAgICBpZihrID49ICR7c2hhcGVbaV19KSB7IGsgPSBfMm5fMSAtIGs7IH1cbiAgICAgICAgfVxuICAgICAgICBvZmZzZXQgKz0gayAqICR7c3RyaWRlc1tpXX07XG4gICAgICAgIGA7XG4gIH1cbiAgcmV0dXJuIGBcbiAgICAgIGZsb2F0IHBhZEEoaW50IG1bJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IG9mZnNldCA9IDA7XG4gICAgICAgIGludCBrID0gMDtcbiAgICAgICAgJHtibG9ja31cbiAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhvZmZzZXQsICR7d2lkdGh9LCAke2hlaWdodH0pO1xuICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShBLCBjb29yZHMpKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgYDtcbn07XG5cbmNvbnN0IGdldFBhZEVkZ2UgPSAoXG4gIGdsc2w6IEdsc2wsXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHdpZHRoOiBudW1iZXIsXG4gIGhlaWdodDogbnVtYmVyLFxuICBwYWRzOiBudW1iZXJbXSxcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgbGV0IGJsb2NrID0gJyc7XG4gIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICBibG9jayArPSBgXG4gICAgICAgIGsgPSBtWyR7aX1dIC0gJHtwYWRzW2ldfTtcbiAgICAgICAgaWYgKGsgPCAwKSAgayA9IDA7XG4gICAgICAgIGlmIChrID49ICR7c2hhcGVbaV19KSBrID0gJHtzaGFwZVtpXSAtIDF9O1xuICAgICAgICBvZmZzZXQgKz0gayAqICR7c3RyaWRlc1tpXX07XG4gICAgICBgO1xuICB9XG4gIHJldHVybiBgXG4gICAgICBmbG9hdCBwYWRBKGludCBtWyR7cmFua31dKSB7XG4gICAgICAgIGludCBvZmZzZXQgPSAwO1xuICAgICAgICBpbnQgayA9IDA7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgZmxvYXQgdmFsdWUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgY29vcmRzKSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGA7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFBvb2xDb252VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBhdXRvUGFkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNlaWxNb2RlOiBudW1iZXI7XG4gIHJlYWRvbmx5IGNvdW50SW5jbHVkZVBhZDogYm9vbGVhbjtcbiAgcmVhZG9ubHkga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgcGFkczogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBhdmVyYWdlUG9vbDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3QgbWV0YWRhdGEgPSB7XG4gICAgbmFtZTogJ0F2ZXJhZ2VQb29sJyxcbiAgICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgfTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVBdmVyYWdlUG9vbFByb2dyYW1JbmZvKGlucHV0cywgbWV0YWRhdGEsIGZhbHNlLCBhdHRyaWJ1dGVzKSB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQXZlcmFnZVBvb2xBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEF2ZXJhZ2VQb29sQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhdXRvUGFkID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnYXV0b19wYWQnLCAnTk9UU0VUJyk7XG4gIGNvbnN0IGNlaWxNb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnY2VpbF9tb2RlJywgMCk7XG4gIGNvbnN0IGNvdW50SW5jbHVkZVBhZCA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2NvdW50X2luY2x1ZGVfcGFkJywgMCkgPT09IDAgPyBmYWxzZSA6IHRydWU7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2tlcm5lbF9zaGFwZScpO1xuICBjb25zdCBzdHJpZGVzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3N0cmlkZXMnLCBbXSk7XG4gIGNvbnN0IHBhZHMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygncGFkcycsIFtdKTtcblxuICAvLyBUT0RPOiBzdXBwb3J0IGF0dHJpYnV0ZSAnY2VpbF9tb2RlJ1xuICBpZiAoY2VpbE1vZGUgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzaW5nIGNlaWwoKSBpbiBzaGFwZSBjb21wdXRhdGlvbiBpcyBub3QgeWV0IHN1cHBvcnRlZCBmb3IgQXZlcmFnZVBvb2wnKTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBhdXRvUGFkLCBjZWlsTW9kZSwgY291bnRJbmNsdWRlUGFkLCBrZXJuZWxTaGFwZSwgc3RyaWRlcywgcGFkcyB9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZUF2ZXJhZ2VQb29sUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogVGVuc29yW10sXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW2FkanVzdGVkQXR0cmlidXRlcywgb3V0cHV0U2hhcGVdID0gZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlKFxuICAgIGlucHV0cyxcbiAgICBhdHRyaWJ1dGVzLFxuICAgIGlzR2xvYmFsT3BlcmF0b3IsXG4gICk7XG4gIGNvbnN0IGtlcm5lbFNpemUgPSBTaGFwZVV0aWwuc2l6ZShhZGp1c3RlZEF0dHJpYnV0ZXMua2VybmVsU2hhcGUpO1xuICBjb25zdCBvcDEgPSAndmFsdWUgKz0gX1goeCk7JztcbiAgbGV0IG9wMiA9ICcnO1xuICBpZiAoYWRqdXN0ZWRBdHRyaWJ1dGVzLmNvdW50SW5jbHVkZVBhZCkge1xuICAgIG9wMiArPSBgdmFsdWUgLz0gZmxvYXQoJHtrZXJuZWxTaXplfSk7YDtcbiAgfSBlbHNlIHtcbiAgICBvcDIgKz0gYHZhbHVlIC89IGZsb2F0KCR7a2VybmVsU2l6ZX0gLSBwYWQpO2A7XG4gIH1cbiAgY29uc3QgcG9vbGluZ0NvZGUgPSBnZW5lcmF0ZVBvb2xpbmdDb2RlKGlucHV0c1swXS5kaW1zLCBhZGp1c3RlZEF0dHJpYnV0ZXMsIG9wMSwgb3AyLCAnMC4wJyk7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgJHtwb29saW5nQ29kZX1cbiAgICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGdsb2JhbEF2ZXJhZ2VQb29sOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEF2ZXJhZ2VQb29sQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBtZXRhZGF0YSA9IHtcbiAgICBuYW1lOiAnR2xvYmFsQXZlcmFnZVBvb2wnLFxuICAgIGlucHV0TmFtZXM6IFsnWCddLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgY2FjaGVIaW50OiBgJHthdHRyaWJ1dGVzLmNvdW50SW5jbHVkZVBhZH1gLFxuICB9O1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUF2ZXJhZ2VQb29sUHJvZ3JhbUluZm8oaW5wdXRzLCBtZXRhZGF0YSwgdHJ1ZSwgYXR0cmlidXRlcykgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdsb2JhbEF2ZXJhZ2VQb29sQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgY291bnRJbmNsdWRlUGFkID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnY291bnRfaW5jbHVkZV9wYWQnLCAwKSA9PT0gMCA/IGZhbHNlIDogdHJ1ZTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgYXV0b1BhZDogJycsXG4gICAgY2VpbE1vZGU6IDAsXG4gICAgY291bnRJbmNsdWRlUGFkLFxuICAgIGtlcm5lbFNoYXBlOiBbXSxcbiAgICBzdHJpZGVzOiBbXSxcbiAgICBwYWRzOiBbXSxcbiAgfSk7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIE1heFBvb2xBdHRyaWJ1dGVzIGV4dGVuZHMgQXZlcmFnZVBvb2xBdHRyaWJ1dGVzIHtcbiAgcmVhZG9ubHkgc3RvcmFnZU9yZGVyOiBudW1iZXI7XG4gIHJlYWRvbmx5IGRpbGF0aW9uczogbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBtYXhQb29sOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPE1heFBvb2xBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBNYXhQb29sQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3QgbWV0YWRhdGEgPSB7XG4gICAgbmFtZTogJ01heFBvb2wnLFxuICAgIGlucHV0TmFtZXM6IFsnWCddLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICB9O1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZU1heFBvb2xQcm9ncmFtSW5mbyhpbnB1dHMsIG1ldGFkYXRhLCBmYWxzZSwgYXR0cmlidXRlcykgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZU1heFBvb2xBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPE1heFBvb2xBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IE1heFBvb2xBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXV0b1BhZCA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2F1dG9fcGFkJywgJ05PVFNFVCcpO1xuICBjb25zdCBjZWlsTW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2NlaWxfbW9kZScsIDApO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdrZXJuZWxfc2hhcGUnKTtcbiAgY29uc3Qgc3RyaWRlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdzdHJpZGVzJywgW10pO1xuICBjb25zdCBwYWRzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnLCBbXSk7XG4gIGNvbnN0IHN0b3JhZ2VPcmRlciA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3N0b3JhZ2Vfb3JkZXInLCAwKTtcbiAgY29uc3QgZGlsYXRpb25zID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2RpbGF0aW9ucycsIFtdKTtcblxuICAvLyBUT0RPOiBzdXBwb3J0IGF0dHJpYnV0ZSAnY2VpbF9tb2RlJyBhbmQgJ3N0b3JhZ2Vfb3JkZXInXG4gIGlmIChzdG9yYWdlT3JkZXIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvbHVtbiBtYWpvciBzdG9yYWdlIG9yZGVyIGlzIG5vdCB5ZXQgc3VwcG9ydGVkIGZvciBNYXhQb29sJyk7XG4gIH1cbiAgaWYgKGNlaWxNb2RlICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1c2luZyBjZWlsKCkgaW4gc2hhcGUgY29tcHV0YXRpb24gaXMgbm90IHlldCBzdXBwb3J0ZWQgZm9yIE1heFBvb2wnKTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe1xuICAgIGF1dG9QYWQsXG4gICAgY2VpbE1vZGUsXG4gICAgY291bnRJbmNsdWRlUGFkOiBmYWxzZSxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBzdHJpZGVzLFxuICAgIHBhZHMsXG4gICAgc3RvcmFnZU9yZGVyLFxuICAgIGRpbGF0aW9ucyxcbiAgfSk7XG59O1xuXG5jb25zdCBjcmVhdGVNYXhQb29sUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogVGVuc29yW10sXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gIGF0dHJpYnV0ZXM6IE1heFBvb2xBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBbYWRqdXN0ZWRBdHRyaWJ1dGVzLCBvdXRwdXRTaGFwZV0gPSBnZXRBZGp1c3RlZFBvb2xBdHRyaWJ1dGVzQW5kT3V0cHV0U2hhcGUoXG4gICAgaW5wdXRzLFxuICAgIGF0dHJpYnV0ZXMsXG4gICAgaXNHbG9iYWxPcGVyYXRvcixcbiAgKTtcbiAgY29uc3Qgb3AxID0gYFxuICAgICAgdmFsdWUgPSBtYXgoX1goeCksIHZhbHVlKTtcbiAgICBgO1xuICBjb25zdCBvcDIgPSAnJztcbiAgY29uc3QgcG9vbGluZ0NvZGUgPSBnZW5lcmF0ZVBvb2xpbmdDb2RlKGlucHV0c1swXS5kaW1zLCBhZGp1c3RlZEF0dHJpYnV0ZXMsIG9wMSwgb3AyLCAnLTFlNScpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke3Bvb2xpbmdDb2RlfVxuICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlID0gKFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgfCBNYXhQb29sQXR0cmlidXRlcyxcbiAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbik6IFtBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgfCBNYXhQb29sQXR0cmlidXRlcywgbnVtYmVyW11dID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IGhhc0RpbGF0aW9ucyA9IE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJpYnV0ZXMsICdkaWxhdGlvbnMnKTtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLnNsaWNlKCk7XG4gIGNvbnN0IHN0cmlkZXMgPSBhdHRyaWJ1dGVzLnN0cmlkZXMuc2xpY2UoKTtcbiAgY29uc3QgZGlsYXRpb25zOiBudW1iZXJbXSA9IGhhc0RpbGF0aW9ucyA/IChhdHRyaWJ1dGVzIGFzIE1heFBvb2xBdHRyaWJ1dGVzKS5kaWxhdGlvbnMuc2xpY2UoKSA6IFtdO1xuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5wYWRzLnNsaWNlKCk7XG4gIFBvb2xDb252VXRpbC5hZGp1c3RQb29sQXR0cmlidXRlcyhpc0dsb2JhbE9wZXJhdG9yLCBpbnB1dFNoYXBlLCBrZXJuZWxTaGFwZSwgc3RyaWRlcywgZGlsYXRpb25zLCBwYWRzKTtcblxuICBjb25zdCBvdXRwdXRTaGFwZSA9IFBvb2xDb252VXRpbC5jb21wdXRlUG9vbE91dHB1dFNoYXBlKFxuICAgIGlzR2xvYmFsT3BlcmF0b3IsXG4gICAgaW5wdXRTaGFwZSxcbiAgICBzdHJpZGVzLFxuICAgIGRpbGF0aW9ucyxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBwYWRzLFxuICAgIGF0dHJpYnV0ZXMuYXV0b1BhZCxcbiAgKTtcblxuICBjb25zdCBuZXdBdHRyaWJ1dGVzID0gT2JqZWN0LmFzc2lnbih7fSwgYXR0cmlidXRlcyk7XG4gIGlmIChoYXNEaWxhdGlvbnMpIHtcbiAgICBPYmplY3QuYXNzaWduKG5ld0F0dHJpYnV0ZXMsIHsga2VybmVsU2hhcGUsIHN0cmlkZXMsIHBhZHMsIGRpbGF0aW9ucywgY2FjaGVLZXk6IGF0dHJpYnV0ZXMuY2FjaGVLZXkgfSk7XG4gIH0gZWxzZSB7XG4gICAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7IGtlcm5lbFNoYXBlLCBzdHJpZGVzLCBwYWRzLCBjYWNoZUtleTogYXR0cmlidXRlcy5jYWNoZUtleSB9KTtcbiAgfVxuICByZXR1cm4gW25ld0F0dHJpYnV0ZXMsIG91dHB1dFNoYXBlXTtcbn07XG5cbmNvbnN0IGdsb2JhbE1heFBvb2xBdHRyaWJ1dGVzID0ge1xuICBhdXRvUGFkOiAnJyxcbiAgY2VpbE1vZGU6IDAsXG4gIGNvdW50SW5jbHVkZVBhZDogZmFsc2UsXG4gIGtlcm5lbFNoYXBlOiBbXSxcbiAgc3RyaWRlczogW10sXG4gIHBhZHM6IFtdLFxuICBzdG9yYWdlT3JkZXI6IDAsXG4gIGRpbGF0aW9uczogW10sXG4gIGNhY2hlS2V5OiAnJyxcbn07XG5cbmNvbnN0IGdsb2JhbE1heFBvb2xNZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0dsb2JhbE1heFBvb2wnLFxuICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCBnbG9iYWxNYXhQb29sID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4uZ2xvYmFsTWF4UG9vbE1ldGFkYXRhLFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVNYXhQb29sUHJvZ3JhbUluZm8oaW5wdXRzLCBnbG9iYWxNYXhQb29sTWV0YWRhdGEsIHRydWUsIGdsb2JhbE1heFBvb2xBdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQb29sIG9wcyByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcblxuY29uc3QgZ2VuZXJhdGVQb29saW5nQ29kZSA9IChcbiAgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzLFxuICBvcDE6IHN0cmluZyxcbiAgb3AyOiBzdHJpbmcsXG4gIHN0YXJ0OiBzdHJpbmcsXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCByYW5rID0gaW5wdXREaW1zLmxlbmd0aDtcbiAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoIDw9IDIpIHtcbiAgICBjb25zdCBrdyA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGVbYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggLSAxXTtcbiAgICBjb25zdCBzdyA9IGF0dHJpYnV0ZXMuc3RyaWRlc1thdHRyaWJ1dGVzLnN0cmlkZXMubGVuZ3RoIC0gMV07XG4gICAgY29uc3QgcHdTdGFydCA9IGF0dHJpYnV0ZXMucGFkc1thdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIC8gMiAtIDFdO1xuICAgIGNvbnN0IHB3RW5kID0gYXR0cmlidXRlcy5wYWRzW2F0dHJpYnV0ZXMucGFkcy5sZW5ndGggLSAxXTtcbiAgICBjb25zdCBkaW1XID0gaW5wdXREaW1zW3JhbmsgLSAxXTtcbiAgICBsZXQgY29kZVcgPSAnJztcbiAgICBsZXQgY29kZUggPSAnJztcbiAgICBsZXQgY29kZUhFbmQgPSAnJztcbiAgICBpZiAocHdTdGFydCArIHB3RW5kICE9PSAwKSB7XG4gICAgICBjb2RlVyA9IGBcbiAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7a3d9OyBpKyspIHtcbiAgICAgICAgICAgIHhbJHtyYW5rfSAtIDFdID0gaW5kaWNlc1ske3Jhbmt9IC0gMV0gKiAke3N3fSAtICR7cHdTdGFydH0gKyBpO1xuICAgICAgICAgICAgaWYgKHhbJHtyYW5rfSAtIDFdIDwgMCB8fCB4WyR7cmFua30gLSAxXSA+PSAke2RpbVd9KSB7XG4gICAgICAgICAgICAgIHBhZCsrO1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICR7b3AxfVxuICAgICAgICAgIH1gO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlVyA9IGBcbiAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7a3d9OyBpKyspIHtcbiAgICAgICAgICAgIHhbJHtyYW5rfSAtIDFdID0gaW5kaWNlc1ske3Jhbmt9IC0gMV0gKiAke3N3fSAtICR7cHdTdGFydH0gKyBpO1xuICAgICAgICAgICAgJHtvcDF9XG4gICAgICAgICAgfWA7XG4gICAgfVxuXG4gICAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoID09PSAyKSB7XG4gICAgICBjb25zdCBraCA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGVbYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggLSAyXTtcbiAgICAgIGNvbnN0IHNoID0gYXR0cmlidXRlcy5zdHJpZGVzW2F0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggLSAyXTtcbiAgICAgIGNvbnN0IHBoU3RhcnQgPSBhdHRyaWJ1dGVzLnBhZHNbYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAvIDIgLSAyXTtcbiAgICAgIGNvbnN0IHBoRW5kID0gYXR0cmlidXRlcy5wYWRzW2F0dHJpYnV0ZXMucGFkcy5sZW5ndGggLSAyXTtcbiAgICAgIGNvbnN0IGRpbUggPSBpbnB1dERpbXNbcmFuayAtIDJdO1xuICAgICAgaWYgKHBoU3RhcnQgKyBwaEVuZCAhPT0gMCkge1xuICAgICAgICBjb2RlSCA9IGBcbiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgJHtraH07IGorKykge1xuICAgICAgICAgICAgICB4WyR7cmFua30gLSAyXSA9IGluZGljZXNbJHtyYW5rfSAtIDJdICogJHtzaH0gLSAke3BoU3RhcnR9ICsgajtcbiAgICAgICAgICAgICAgaWYgKHhbJHtyYW5rfSAtIDJdIDwgMCB8fCB4WyR7cmFua30gLSAyXSA+PSAke2RpbUh9KSB7XG4gICAgICAgICAgICAgICAgcGFkKz0gJHtrd307XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICBgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29kZUggPSBgXG4gICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8ICR7a2h9OyBqKyspIHtcbiAgICAgICAgICAgICAgeFske3Jhbmt9IC0gMl0gPSBpbmRpY2VzWyR7cmFua30gLSAyXSAqICR7c2h9IC0gJHtwaFN0YXJ0fSArIGo7XG4gICAgICAgICAgICBgO1xuICAgICAgfVxuICAgICAgY29kZUhFbmQgPSBgXG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgIH1cblxuICAgIGNvbnN0IHBvb2xpbmdDb2RlID0gYFxuICAgICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IHhbJHtyYW5rfV07XG4gICAgICAgICAgY29weVZlYyhpbmRpY2VzLCB4KTtcblxuICAgICAgICAgIGZsb2F0IHZhbHVlID0gJHtzdGFydH07XG4gICAgICAgICAgaW50IHBhZCA9IDA7XG4gICAgICAgICAgJHtjb2RlSH1cbiAgICAgICAgICAke2NvZGVXfVxuICAgICAgICAgICR7Y29kZUhFbmR9XG4gICAgICAgICAgJHtvcDJ9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBwb29saW5nQ29kZTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBrZXJuZWxTaXplID0gU2hhcGVVdGlsLnNpemUoYXR0cmlidXRlcy5rZXJuZWxTaGFwZSk7XG4gICAgY29uc3Qga2VybmVsU3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlKTtcbiAgICBjb25zdCBzdHJpZGVzUmFuayA9IGtlcm5lbFN0cmlkZXMubGVuZ3RoO1xuICAgIGNvbnN0IHBhZHNSYW5rID0gYXR0cmlidXRlcy5wYWRzLmxlbmd0aDtcbiAgICBjb25zdCBvZmZzZXRUb0luZGljZXNGdW5jdGlvbiA9IG9mZnNldFRvSW5kaWNlcyhzdHJpZGVzUmFuayk7XG4gICAgY29uc3QgY29weUlucHV0RGltcyA9IGNvcHlBcnJheShpbnB1dERpbXMsICdpbnB1dERpbXMnKTtcbiAgICBjb25zdCBjb3B5UGFkcyA9IGNvcHlBcnJheShhdHRyaWJ1dGVzLnBhZHMsICdwYWRzJyk7XG4gICAgY29uc3QgY29weUtlcm5lbFN0cmlkZXMgPSBjb3B5QXJyYXkoa2VybmVsU3RyaWRlcywgJ2tlcm5lbFN0cmlkZXMnKTtcbiAgICBjb25zdCBjb3B5U3RyaWRlcyA9IGNvcHlBcnJheShhdHRyaWJ1dGVzLnN0cmlkZXMsICdzdHJpZGVzJyk7XG4gICAgY29uc3QgaGFzUGFkcyA9IGF0dHJpYnV0ZXMucGFkcy5yZWR1Y2UoKHN1bSwgY3VyKSA9PiBzdW0gKyBjdXIpO1xuICAgIGxldCBwYWRDb2RlID0gJyc7XG4gICAgaWYgKGhhc1BhZHMpIHtcbiAgICAgIHBhZENvZGUgPSBgXG4gICAgICAgICAgICBpZiAoeFtqXSA+PSBpbnB1dERpbXNbal0gfHwgeFtqXSA8IDApIHtcbiAgICAgICAgICAgICAgcGFkKys7XG4gICAgICAgICAgICAgIGlzUGFkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghaXNQYWQpIHtcbiAgICAgICAgICAgICR7b3AxfVxuICAgICAgICAgIH1gO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYWRDb2RlID0gYFxuICAgICAgICAgIH1cbiAgICAgICAgICAke29wMX1cbiAgICAgICAgYDtcbiAgICB9XG4gICAgY29uc3QgcG9vbGluZ0NvZGUgPSBgXG4gICAgICAgICR7b2Zmc2V0VG9JbmRpY2VzRnVuY3Rpb259XG4gICAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgeFske3Jhbmt9XTtcbiAgICAgICAgICBjb3B5VmVjKGluZGljZXMsIHgpO1xuICAgICAgICAgIGludCBvZmZzZXRbJHtzdHJpZGVzUmFua31dO1xuICAgICAgICAgIGludCBwYWRzWyR7cGFkc1Jhbmt9XTtcbiAgICAgICAgICBpbnQgaW5wdXREaW1zWyR7cmFua31dO1xuICAgICAgICAgIGludCBrZXJuZWxTdHJpZGVzWyR7c3RyaWRlc1Jhbmt9XTtcbiAgICAgICAgICBpbnQgc3RyaWRlc1ske3N0cmlkZXNSYW5rfV07XG4gICAgICAgICAgJHtjb3B5UGFkc31cbiAgICAgICAgICAke2NvcHlJbnB1dERpbXN9XG4gICAgICAgICAgJHtjb3B5U3RyaWRlc31cbiAgICAgICAgICAke2NvcHlLZXJuZWxTdHJpZGVzfVxuXG4gICAgICAgICAgZmxvYXQgdmFsdWUgPSAke3N0YXJ0fTtcbiAgICAgICAgICBpbnQgcGFkID0gMDtcbiAgICAgICAgICBib29sIGlzUGFkID0gZmFsc2U7XG4gICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke2tlcm5lbFNpemV9OyBpKyspIHtcbiAgICAgICAgICAgIG9mZnNldFRvSW5kaWNlcyhpLCBrZXJuZWxTdHJpZGVzLCBvZmZzZXQpO1xuICAgICAgICAgICAgaXNQYWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGZvciAoaW50IGogPSAke3Jhbmt9IC0gJHtzdHJpZGVzUmFua307IGogPCAke3Jhbmt9OyBqKyspIHtcbiAgICAgICAgICAgICAgeFtqXSA9IGluZGljZXNbal0gKiBzdHJpZGVzW2ogLSAke3Jhbmt9ICsgJHtzdHJpZGVzUmFua31dXG4gICAgICAgICAgICAgICAgKyBvZmZzZXRbaiAtICR7cmFua30gKyAke3N0cmlkZXNSYW5rfV0gLSBwYWRzW2ogLSAyXTtcbiAgICAgICAgICAgICAgJHtwYWRDb2RlfVxuICAgICAgICAgIH1cbiAgICAgICAgICAke29wMn1cblxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gcG9vbGluZ0NvZGU7XG4gIH1cbn07XG5cbmNvbnN0IGNvcHlBcnJheSA9IChhcnJheTogcmVhZG9ubHkgbnVtYmVyW10sIGFycmF5TmFtZTogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgbGV0IGJsb2NrID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICBibG9jayArPSBgXG4gICAgICAke2FycmF5TmFtZX1bJHtpfV0gPSAke2FycmF5W2ldfTtcbiAgICBgO1xuICB9XG4gIHJldHVybiBibG9jaztcbn07XG5cbmNvbnN0IG9mZnNldFRvSW5kaWNlcyA9IChyYW5rOiBudW1iZXIpOiBzdHJpbmcgPT4gYFxuICB2b2lkIG9mZnNldFRvSW5kaWNlcyhpbnQgb2Zmc2V0LCBpbnRbJHtyYW5rfV0gc3RyaWRlcywgb3V0IGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG4gICAgaWYgKCR7cmFua30gPT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7cmFua30gLSAxOyArK2kpIHtcbiAgICAgIGluZGljZXNbaV0gPSBvZmZzZXQgLyBzdHJpZGVzW2ldO1xuICAgICAgb2Zmc2V0IC09IGluZGljZXNbaV0gKiBzdHJpZGVzW2ldO1xuICAgIH1cbiAgICBpbmRpY2VzWyR7cmFua30gLSAxXSA9IG9mZnNldDtcbiAgfWA7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgTlVNQkVSX1RZUEVTLCBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlZHVjZUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGVzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkga2VlcERpbXM6IGJvb2xlYW47XG59XG5cbi8vIHJldHVybiBbaW5pdCBvcHMsIHJlZHVjZSBvcHMsIGZpbmFsIG9wc11cbnR5cGUgUmVkdWNlT3AgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pID0+IHN0cmluZ1tdO1xuXG5jb25zdCByZWR1Y2UgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbiAgbmFtZTogc3RyaW5nLFxuICByZWR1Y2VPcDogUmVkdWNlT3AsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3QgcmVkdWNlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICAgIG5hbWUsXG4gICAgaW5wdXROYW1lczogWydBJ10sXG4gICAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgfTtcblxuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi5yZWR1Y2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZVJlZHVjZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgbmFtZSwgcmVkdWNlT3AsIHJlZHVjZVByb2dyYW1NZXRhZGF0YSksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IFJlZHVjZUF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBheGVzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2F4ZXMnLCBbXSk7XG4gIGNvbnN0IGtlZXBEaW1zID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgna2VlcGRpbXMnLCAxKSA9PT0gMTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF4ZXMsIGtlZXBEaW1zIH0pO1xufTtcblxuY29uc3QgY3JlYXRlUmVkdWNlUHJvZ3JhbUluZm8gPSAoXG4gIF9oYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4gIF9uYW1lOiBzdHJpbmcsXG4gIHJlZHVjZU9wOiBSZWR1Y2VPcCxcbiAgcmVkdWNlUHJvZ3JhbU1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IG91dHB1dFNoYXBlOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBpUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCB8fCAxO1xuXG4gIGNvbnN0IGlkeENvcHkgPSBbXTsgLy8gY29weSBvdXRwdXQgaW5kZXhlcyB0byBpbnB1dCBpbmRleGVzXG5cbiAgY29uc3QgYXhlcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGVzKGF0dHJpYnV0ZXMuYXhlcywgaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgY29uc3Qgb3BzID0gcmVkdWNlT3AoaW5wdXRzLCBheGVzKTtcbiAgbGV0IHJlZHVjZU9wcyA9IG9wc1sxXTtcblxuICBmb3IgKGxldCBrID0gMDsgayA8IGlucHV0c1swXS5kaW1zLmxlbmd0aDsgaysrKSB7XG4gICAgLy8gaWYgdGhpcyBheGlzIGlzIHJlZHVjZWRcbiAgICBpZiAoYXhlcy5pbmRleE9mKGspID49IDAgfHwgYXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmIChhdHRyaWJ1dGVzLmtlZXBEaW1zKSB7XG4gICAgICAgIG91dHB1dFNoYXBlLnB1c2goMSk7XG4gICAgICB9IC8vIGVsc2UgeyByZW1vdmUgdGhlIGF4aXMgZnJvbSBvdXRwdXRTaGFwZTsgfVxuXG4gICAgICAvLyBsb29wIG92ZXIgdGhlIGQtdGggYXhpc1xuICAgICAgcmVkdWNlT3BzID0gYFxuICAgICAgICAgIGZvcihpbnQgaiR7a30gPSAwOyBqJHtrfSA8ICR7aW5wdXRzWzBdLmRpbXNba119OyBqJHtrfSsrKSB7XG4gICAgICAgICAgICBpbnB1dElkeFske2t9XSA9IGoke2t9O1xuICAgICAgICAgICAgJHtyZWR1Y2VPcHN9XG4gICAgICAgICAgfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlkeENvcHkucHVzaChgaW5wdXRJZHhbJHtrfV0gPSBvdXRwdXRJZHhbJHtvdXRwdXRTaGFwZS5sZW5ndGh9XTtgKTtcblxuICAgICAgb3V0cHV0U2hhcGUucHVzaChpbnB1dHNbMF0uZGltc1trXSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgb1JhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGggfHwgMTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBvdXRwdXRJZHhbJHtvUmFua31dKSB7XG4gICAgICAgIGZsb2F0IHZhbHVlOyAgICAgICAgICAgICAgICAgLy8gZmluYWwgcmVzdWx0XG4gICAgICAgIGludCBpbnB1dElkeFske2lSYW5rfV07ICAgICAgLy8gYWRkcmVzc2luZyBpbnB1dCBkYXRhXG4gICAgICAgICR7aWR4Q29weS5qb2luKCdcXG4nKX1cbiAgICAgICAgJHtvcHNbMF19ICAgICAgIC8vIGluaXQgb3BzIGZvciByZWR1Y2UgbWF4L21pblxuICAgICAgICAke3JlZHVjZU9wc31cbiAgICAgICAgJHtvcHNbMl19ICAgICAgIC8vIGZpbmFsIGNvbXB1dGF0aW9uIGZvciByZWR1Y2UgbWVhblxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9YDtcblxuICByZXR1cm4ge1xuICAgIC4uLnJlZHVjZVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIC8vIFRPRE86IHN1cHBvcnQgUmVkdWNlKiBvcGVyYXRvcnMgd2l0aCAyIGlucHV0cy5cbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUmVkdWNlIG9wIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoTlVNQkVSX1RZUEVTLmluZGV4T2YoaW5wdXRzWzBdLnR5cGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlU3VtOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9ICgpOiBzdHJpbmdbXSA9PiBbJ3ZhbHVlID0gMC4wOycsICd2YWx1ZSArPSBfQShpbnB1dElkeCk7JywgJyddO1xuICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZVN1bScsIHJlZHVjZU9wKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VNZWFuOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dHM6IFRlbnNvcltdLCBheGVzOiBudW1iZXJbXSk6IHN0cmluZ1tdID0+IHtcbiAgICBsZXQgc2l6ZSA9IDEuMDtcbiAgICBmb3IgKGxldCBrID0gMDsgayA8IGlucHV0c1swXS5kaW1zLmxlbmd0aDsgaysrKSB7XG4gICAgICBpZiAoYXhlcy5pbmRleE9mKGspID49IDAgfHwgYXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgc2l6ZSAqPSBpbnB1dHNbMF0uZGltc1trXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gWyd2YWx1ZSA9IDAuMDsnLCAndmFsdWUgKz0gX0EoaW5wdXRJZHgpOycsIGB2YWx1ZSAvPSAke3NpemV9LjtgXTsgLy8gZW5zdXJlIHJlYWwgbnVtYmVyIHdpdGggYC5gXG4gIH07XG4gIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlTWVhbicsIHJlZHVjZU9wKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VNYXg6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKGlucHV0czogVGVuc29yW10sIGF4ZXM6IG51bWJlcltdKTogc3RyaW5nW10gPT4ge1xuICAgIGNvbnN0IGlkeFplcm8gPSBbXTtcbiAgICBmb3IgKGxldCBrID0gMDsgayA8IGlucHV0c1swXS5kaW1zLmxlbmd0aDsgaysrKSB7XG4gICAgICBpZiAoYXhlcy5pbmRleE9mKGspID49IDAgfHwgYXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaWR4WmVyby5wdXNoKGBpbnB1dElkeFske2t9XSA9IDA7YCk7IC8vIGZpcnN0IGVsZW1lbnRcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gW2Ake2lkeFplcm8uam9pbignXFxuJyl9XFxudmFsdWUgPSBfQShpbnB1dElkeCk7YCwgJ3ZhbHVlID0gbWF4KHZhbHVlLCBfQShpbnB1dElkeCkpOycsICcnXTtcbiAgfTtcbiAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VNYXgnLCByZWR1Y2VPcCk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWluOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dHM6IFRlbnNvcltdLCBheGVzOiBudW1iZXJbXSk6IHN0cmluZ1tdID0+IHtcbiAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dHNbMF0uZGltcy5sZW5ndGg7IGsrKykge1xuICAgICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGlkeFplcm8ucHVzaChgaW5wdXRJZHhbJHtrfV0gPSAwO2ApOyAvLyBmaXJzdCBlbGVtZW50XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFtgJHtpZHhaZXJvLmpvaW4oJ1xcbicpfVxcbnZhbHVlID0gX0EoaW5wdXRJZHgpO2AsICd2YWx1ZSA9IG1pbih2YWx1ZSwgX0EoaW5wdXRJZHgpKTsnLCAnJ107XG4gIH07XG4gIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlTWluJywgcmVkdWNlT3ApO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZVByb2Q6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKCk6IHN0cmluZ1tdID0+IFsndmFsdWUgPSAxLjA7JywgJ3ZhbHVlICo9IF9BKGlucHV0SWR4KTsnLCAnJ107XG4gIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlUHJvZCcsIHJlZHVjZU9wKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VMb2dTdW06IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKCk6IHN0cmluZ1tdID0+IFsndmFsdWUgPSAwLjA7JywgJ3ZhbHVlICs9IF9BKGlucHV0SWR4KTsnLCAndmFsdWUgPSBsb2codmFsdWUpOyddO1xuICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZUxvZ1N1bScsIHJlZHVjZU9wKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VMb2dTdW1TcXVhcmU6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKCk6IHN0cmluZ1tdID0+IFsnZmxvYXQgdDsgdmFsdWUgPSAwLjA7JywgJ3QgPSBfQShpbnB1dElkeCk7IHZhbHVlICs9IHQgKiB0OycsICcnXTtcbiAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VMb2dTdW1TcXVhcmUnLCByZWR1Y2VPcCk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCByZXNoYXBlID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVzaGFwZWREaW1zID0gU2hhcGVVdGlsLmNhbGN1bGF0ZVJlc2hhcGVkRGltcyhpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmludGVnZXJEYXRhKTtcbiAgaWYgKGhhbmRsZXIuc2Vzc2lvbi5wYWNrKSB7XG4gICAgcmV0dXJuIFtoYW5kbGVyLnJlc2hhcGVQYWNrZWQoaW5wdXRzWzBdLCByZXNoYXBlZERpbXMpXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW2hhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgcmVzaGFwZWREaW1zKV07XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBVcHNhbXBsZUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBvcHNldDogbnVtYmVyO1xuICByZWFkb25seSBpc1Jlc2l6ZTogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbW9kZTogc3RyaW5nO1xuICByZWFkb25seSBzY2FsZXM6IG51bWJlcltdO1xuICByZWFkb25seSBleHRyYXBvbGF0aW9uVmFsdWU6IG51bWJlcjtcbiAgcmVhZG9ubHkgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGU6IHN0cmluZztcbiAgcmVhZG9ubHkgdXNlRXh0cmFwb2xhdGlvbjogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbmVlZFJvaUlucHV0OiBib29sZWFuO1xuICByZWFkb25seSBuZWFyZXN0TW9kZTogc3RyaW5nO1xuICByZWFkb25seSBjdWJpY0NvZWZmaWNpZW50QTogbnVtYmVyO1xuICByZWFkb25seSBleGNsdWRlT3V0c2lkZTogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdXNlTmVhcmVzdDJ4T3B0aW1pemF0aW9uOiBib29sZWFuO1xuICByZWFkb25seSByb2lJbnB1dElkeDogbnVtYmVyO1xuICByZWFkb25seSBzY2FsZXNJbnB1dElkeDogbnVtYmVyO1xuICByZWFkb25seSBzaXplc0lucHV0SWR4OiBudW1iZXI7XG59XG5cbmNvbnN0IHVwc2FtcGxlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnVXBzYW1wbGUnLFxuICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCB1cHNhbXBsZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxVcHNhbXBsZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4udXBzYW1wbGVQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZVVwc2FtcGxlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjc6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyhub2RlLCA3KTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjk6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyhub2RlLCA5KTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzID0gKG5vZGU6IEdyYXBoLk5vZGUsIG9wc2V0OiBudW1iZXIpOiBVcHNhbXBsZUF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBpc1Jlc2l6ZSA9IG9wc2V0ID49IDEwO1xuXG4gIC8vIHByb2Nlc3Npbmcgbm9kZSBhdHRyaWJ1dGVzXG4gIGNvbnN0IG1vZGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdtb2RlJywgJ25lYXJlc3QnKTtcbiAgaWYgKG1vZGUgIT09ICduZWFyZXN0JyAmJiBtb2RlICE9PSAnbGluZWFyJyAmJiAob3BzZXQgPCAxMSB8fCBtb2RlICE9PSAnY3ViaWMnKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgdW5yZWNvZ25pemVkIG1vZGU6ICR7bW9kZX1gKTtcbiAgfVxuXG4gIGxldCBzY2FsZXM6IG51bWJlcltdID0gW107XG4gIGlmIChvcHNldCA8IDkpIHtcbiAgICBzY2FsZXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXRzKCdzY2FsZXMnKTtcbiAgICBzY2FsZXNWYWxpZGF0aW9uKHNjYWxlcywgbW9kZSwgaXNSZXNpemUpO1xuICB9XG5cbiAgY29uc3QgZXh0cmFwb2xhdGlvblZhbHVlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdleHRyYXBvbGF0aW9uX3ZhbHVlJywgMC4wKTtcblxuICBjb25zdCBjb29yZGluYXRlVHJhbnNmb3JtTW9kZSA9XG4gICAgb3BzZXQgPiAxMCA/IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2Nvb3JkaW5hdGVfdHJhbnNmb3JtYXRpb25fbW9kZScsICdoYWxmX3BpeGVsJykgOiAnYXN5bW1ldHJpYyc7XG4gIGlmIChcbiAgICBbXG4gICAgICAnYXN5bW1ldHJpYycsXG4gICAgICAncHl0b3JjaF9oYWxmX3BpeGVsJyxcbiAgICAgICd0Zl9oYWxmX3BpeGVsX2Zvcl9ubicsXG4gICAgICAnYWxpZ25fY29ybmVycycsXG4gICAgICAndGZfY3JvcF9hbmRfcmVzaXplJyxcbiAgICAgICdoYWxmX3BpeGVsJyxcbiAgICBdLmluZGV4T2YoY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUpID09PSAtMVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGNvb3JkaW5hdGVfdHJhbnNmb3JtX21vZGUgJyR7Y29vcmRpbmF0ZVRyYW5zZm9ybU1vZGV9JyBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gIH1cbiAgY29uc3QgbmVlZFJvaUlucHV0ID0gY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPT09ICd0Zl9jcm9wX2FuZF9yZXNpemUnO1xuICBjb25zdCB1c2VFeHRyYXBvbGF0aW9uID0gbmVlZFJvaUlucHV0O1xuXG4gIGNvbnN0IG5lYXJlc3RNb2RlID1cbiAgICBtb2RlID09PSAnbmVhcmVzdCcgJiYgb3BzZXQgPj0gMTEgPyBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCduZWFyZXN0X21vZGUnLCAncm91bmRfcHJlZmVyX2Zsb29yJykgOiAnJztcbiAgaWYgKFsncm91bmRfcHJlZmVyX2Zsb29yJywgJ3JvdW5kX3ByZWZlcl9jZWlsJywgJ2Zsb29yJywgJ2NlaWwnLCAnJ10uaW5kZXhPZihuZWFyZXN0TW9kZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBuZWFyZXN0X21vZGUgJyR7bmVhcmVzdE1vZGV9JyBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gIH1cblxuICBjb25zdCBjdWJpY0NvZWZmaWNpZW50QSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnY3ViaWNfY29lZmZfYScsIC0wLjc1KTtcbiAgY29uc3QgZXhjbHVkZU91dHNpZGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdleGNsdWRlX291dHNpZGUnLCAwKSAhPT0gMDtcbiAgaWYgKGV4Y2x1ZGVPdXRzaWRlICYmIG1vZGUgIT09ICdjdWJpYycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4Y2x1ZGVfb3V0c2lkZSBjYW4gYmUgc2V0IHRvIDEgb25seSB3aGVuIG1vZGUgaXMgQ1VCSUMuJyk7XG4gIH1cblxuICBjb25zdCB1c2VOZWFyZXN0MnhPcHRpbWl6YXRpb24gPVxuICAgIG9wc2V0IDwgMTEgPyB0cnVlIDogbW9kZSA9PT0gJ25lYXJlc3QnICYmIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlID09PSAnYXN5bW1ldHJpYycgJiYgbmVhcmVzdE1vZGUgPT09ICdmbG9vcic7XG5cbiAgbGV0IHJvaUlucHV0SWR4ID0gMDtcbiAgbGV0IHNjYWxlc0lucHV0SWR4ID0gMDtcbiAgbGV0IHNpemVzSW5wdXRJZHggPSAwO1xuXG4gIGlmIChvcHNldCA+IDEwKSB7XG4gICAgLy8gaGFuZGxlIHdoZW4gcm9pSW5wdXQgaXMgbm90IGdpdmVuXG4gICAgaWYgKG5vZGUuaW5wdXRzLmxlbmd0aCA+IDIpIHtcbiAgICAgIHJvaUlucHV0SWR4ID0gMTtcbiAgICAgIHNjYWxlc0lucHV0SWR4ID0gMjtcbiAgICAgIHNpemVzSW5wdXRJZHggPSAzO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZXNJbnB1dElkeCA9IDE7XG4gICAgICBzaXplc0lucHV0SWR4ID0gMjtcbiAgICB9XG4gIH0gZWxzZSBpZiAob3BzZXQgPT09IDkpIHtcbiAgICBzY2FsZXNJbnB1dElkeCA9IDE7XG4gIH1cblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBvcHNldCxcbiAgICBpc1Jlc2l6ZSxcbiAgICBtb2RlLFxuICAgIHNjYWxlcyxcbiAgICBleHRyYXBvbGF0aW9uVmFsdWUsXG4gICAgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUsXG4gICAgdXNlRXh0cmFwb2xhdGlvbixcbiAgICBuZWVkUm9pSW5wdXQsXG4gICAgbmVhcmVzdE1vZGUsXG4gICAgY3ViaWNDb2VmZmljaWVudEEsXG4gICAgZXhjbHVkZU91dHNpZGUsXG4gICAgdXNlTmVhcmVzdDJ4T3B0aW1pemF0aW9uLFxuICAgIHJvaUlucHV0SWR4LFxuICAgIHNjYWxlc0lucHV0SWR4LFxuICAgIHNpemVzSW5wdXRJZHgsXG4gIH0pO1xufTtcblxuY29uc3QgY3JlYXRlVXBzYW1wbGVQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgW2lucHV0V2lkdGgsIGlucHV0SGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGlucHV0c1swXS5kaW1zLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICApO1xuXG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMubWFwKChkaW0sIGkpID0+IE1hdGguZmxvb3IoZGltICogYXR0cmlidXRlcy5zY2FsZXNbaV0pKTtcbiAgY29uc3QgW291dHB1dFdpZHRoLCBvdXRwdXRIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgb3V0cHV0U2hhcGUsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICk7XG4gIGNvbnN0IGRpbSA9IG91dHB1dFNoYXBlLmxlbmd0aDtcblxuICBjb25zdCBvdXRwdXRQaXRjaGVzID0gbmV3IEFycmF5PG51bWJlcj4oZGltKTtcbiAgY29uc3QgaW5wdXRQaXRjaGVzID0gbmV3IEFycmF5PG51bWJlcj4oZGltKTtcbiAgbGV0IHByZWNhbGN1bGF0ZWRQaXRjaGVzID0gYFxuICAgICAgaW50IG91dHB1dF9waXRjaGVzWyR7ZGltfV07XG4gICAgICBpbnQgaW5wdXRfcGl0Y2hlc1ske2RpbX1dO1xuICAgICAgYDtcbiAgZm9yIChsZXQgZCA9IGRpbSAtIDE7IGQgPj0gMDsgZC0tKSB7XG4gICAgb3V0cHV0UGl0Y2hlc1tkXSA9IGQgPT09IGRpbSAtIDEgPyAxIDogb3V0cHV0UGl0Y2hlc1tkICsgMV0gKiBvdXRwdXRTaGFwZVtkICsgMV07XG4gICAgaW5wdXRQaXRjaGVzW2RdID0gZCA9PT0gZGltIC0gMSA/IDEgOiBpbnB1dFBpdGNoZXNbZCArIDFdICogaW5wdXRzWzBdLmRpbXNbZCArIDFdO1xuXG4gICAgcHJlY2FsY3VsYXRlZFBpdGNoZXMgKz0gYFxuICAgICAgICBvdXRwdXRfcGl0Y2hlc1ske2R9XSA9ICR7b3V0cHV0UGl0Y2hlc1tkXX07XG4gICAgICAgIGlucHV0X3BpdGNoZXNbJHtkfV0gPSAke2lucHV0UGl0Y2hlc1tkXX07XG4gICAgICAgIGA7XG4gIH1cbiAgY29uc3QgZ2V0SW5wdXRGbG9hdEZ1bmN0aW9uID0gYFxuICAgICAgZmxvYXQgZ2V0SW5wdXRGbG9hdChpbnQgaW5kZXgpIHtcbiAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhpbmRleCwgJHtpbnB1dFdpZHRofSwgJHtpbnB1dEhlaWdodH0pO1xuICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShYLCBjb29yZHMpKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgYDtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPVxuICAgIGF0dHJpYnV0ZXMubW9kZSA9PT0gJ25lYXJlc3QnXG4gICAgICA/IC8vIG5lYXJlc3RcbiAgICAgICAgYFxuICAgICR7Z2V0SW5wdXRGbG9hdEZ1bmN0aW9ufVxuICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtkaW19XSkge1xuICAgICAgaW50IGlucHV0X2luZGV4ID0gMDtcbiAgICAgIGludCBvdXRwdXRfaW5kZXggPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7b3V0cHV0V2lkdGh9LCAke291dHB1dEhlaWdodH0pO1xuXG4gICAgICAke3ByZWNhbGN1bGF0ZWRQaXRjaGVzfVxuXG4gICAgICBpbnQgZCwgbTtcbiAgICAgIGZvciAoaW50IGRpbSA9IDA7IGRpbSA8ICR7ZGltfTsgKytkaW0pIHtcbiAgICAgICAgZCA9IG91dHB1dF9pbmRleCAvIG91dHB1dF9waXRjaGVzW2RpbV07XG4gICAgICAgIG0gPSBvdXRwdXRfaW5kZXggLSBkICogb3V0cHV0X3BpdGNoZXNbZGltXTtcbiAgICAgICAgb3V0cHV0X2luZGV4ID0gbTtcblxuICAgICAgICBpZiAoc2NhbGVzW2RpbV0gIT0gMSAmJiBkID4gMCkge1xuICAgICAgICAgIGludCBkMiA9IGQgLyBzY2FsZXNbZGltXTtcbiAgICAgICAgICBtID0gZCAtIGQyICogc2NhbGVzW2RpbV07XG4gICAgICAgICAgZCA9IGQyO1xuICAgICAgICB9XG4gICAgICAgIGlucHV0X2luZGV4ICs9IGlucHV0X3BpdGNoZXNbZGltXSAqIGQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4KTtcbiAgICB9YFxuICAgICAgOiBkaW0gPT09IDRcbiAgICAgICAgPyAvLyBiaWxpbmVhciA0RFxuICAgICAgICAgIGBcbiAgICAke2dldElucHV0RmxvYXRGdW5jdGlvbn1cbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWzRdKSB7XG4gICAgICBpbnQgaW5wdXRfaW5kZXggPSAwO1xuICAgICAgaW50IG91dHB1dF9pbmRleCA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHtvdXRwdXRXaWR0aH0sICR7b3V0cHV0SGVpZ2h0fSk7XG5cbiAgICAgICR7cHJlY2FsY3VsYXRlZFBpdGNoZXN9XG5cbiAgICAgIGludCBtO1xuICAgICAgaW50IGluZGV4X29mX2RpbTAsIGluZGV4X29mX2RpbTEsIGluZGV4X29mX2RpbTIsIGluZGV4X29mX2RpbTM7XG4gICAgICBpbmRleF9vZl9kaW0wID0gb3V0cHV0X2luZGV4IC8gb3V0cHV0X3BpdGNoZXNbMF07XG4gICAgICBtID0gb3V0cHV0X2luZGV4IC0gaW5kZXhfb2ZfZGltMCAqIG91dHB1dF9waXRjaGVzWzBdO1xuICAgICAgaW5kZXhfb2ZfZGltMSA9IG0gLyBvdXRwdXRfcGl0Y2hlc1sxXTtcbiAgICAgIG0gPSBtIC0gaW5kZXhfb2ZfZGltMSAqIG91dHB1dF9waXRjaGVzWzFdO1xuICAgICAgaW5kZXhfb2ZfZGltMiA9IG0gLyBvdXRwdXRfcGl0Y2hlc1syXTtcbiAgICAgIG0gPSBtIC0gaW5kZXhfb2ZfZGltMiAqIG91dHB1dF9waXRjaGVzWzJdO1xuICAgICAgaW5kZXhfb2ZfZGltMyA9IG07XG5cbiAgICAgIGludCBpbmRleF9vZl9pbnB1dF9kaW0yLCBpbmRleF9vZl9pbnB1dF9kaW0zLCB4X29mZnNldCwgeV9vZmZzZXQ7XG4gICAgICBpbmRleF9vZl9pbnB1dF9kaW0yID0gaW5kZXhfb2ZfZGltMiAvIHNjYWxlc1syXTtcbiAgICAgIHlfb2Zmc2V0ID0gaW5kZXhfb2ZfZGltMiAtIGluZGV4X29mX2lucHV0X2RpbTIgKiBzY2FsZXNbMl07XG4gICAgICBpbmRleF9vZl9pbnB1dF9kaW0zID0gaW5kZXhfb2ZfZGltMyAvIHNjYWxlc1szXTtcbiAgICAgIHhfb2Zmc2V0ID0gaW5kZXhfb2ZfZGltMyAtIGluZGV4X29mX2lucHV0X2RpbTMgKiBzY2FsZXNbM107XG5cbiAgICAgIGlucHV0X2luZGV4ID0gaW5kZXhfb2ZfZGltMCAqIGlucHV0X3BpdGNoZXNbMF0gK1xuICAgICAgICAgICAgaW5kZXhfb2ZfZGltMSAqIGlucHV0X3BpdGNoZXNbMV0gK1xuICAgICAgICAgICAgaW5kZXhfb2ZfaW5wdXRfZGltMiAqIGlucHV0X3BpdGNoZXNbMl0gK1xuICAgICAgICAgICAgaW5kZXhfb2ZfaW5wdXRfZGltMztcblxuICAgICAgZmxvYXQgeDAwID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCk7XG4gICAgICBmbG9hdCB4MTAsIHgwMSwgeDExO1xuXG4gICAgICBib29sIGVuZF9vZl9kaW0yID0gZmFsc2U7XG4gICAgICBpZiAoaW5kZXhfb2ZfaW5wdXRfZGltMiA9PSAoJHtpbnB1dHNbMF0uZGltc1syXX0gLSAxKSkge1xuICAgICAgICAvLyBJdCdzIHRoZSBlbmQgaW4gZGltZW5zaW9uIDJcbiAgICAgICAgeDAxID0geDAwO1xuICAgICAgICBlbmRfb2ZfZGltMiA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB4MDEgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgaW5wdXRfcGl0Y2hlc1syXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbmRleF9vZl9pbnB1dF9kaW0zID09IChpbnB1dF9waXRjaGVzWzJdIC0gMSkpIHtcbiAgICAgICAgLy8gSXQncyB0aGUgZW5kIGluIGRpbWVuc2lvbiAzXG4gICAgICAgIHgxMCA9IHgwMDtcbiAgICAgICAgeDExID0geDAxO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHgxMCA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyAxKTtcbiAgICAgICAgeDExID0gZW5kX29mX2RpbTIgPyB4MTAgOiBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgaW5wdXRfcGl0Y2hlc1syXSArIDEpO1xuICAgICAgfVxuXG4gICAgICBmbG9hdCB5MCA9IHgwMCArIGZsb2F0KHlfb2Zmc2V0KSAqICh4MDEgLSB4MDApIC8gZmxvYXQoc2NhbGVzWzJdKTtcbiAgICAgIGZsb2F0IHkxID0geDEwICsgZmxvYXQoeV9vZmZzZXQpICogKHgxMSAtIHgxMCkgLyBmbG9hdChzY2FsZXNbMl0pO1xuICAgICAgcmV0dXJuIHkwICsgZmxvYXQoeF9vZmZzZXQpICogKHkxIC0geTApIC8gZmxvYXQoc2NhbGVzWzNdKTtcbiAgICB9YFxuICAgICAgICA6IC8vIGJpbGluZWFyIDJEXG4gICAgICAgICAgYFxuICAgICR7Z2V0SW5wdXRGbG9hdEZ1bmN0aW9ufVxuICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbMl0pIHtcbiAgICAgIGludCBpbnB1dF9pbmRleCA9IDA7XG4gICAgICBpbnQgb3V0cHV0X2luZGV4ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke291dHB1dFdpZHRofSwgJHtvdXRwdXRIZWlnaHR9KTtcblxuICAgICAgJHtwcmVjYWxjdWxhdGVkUGl0Y2hlc31cblxuICAgICAgaW50IG07XG4gICAgICBpbnQgaW5kZXhfb2ZfZGltMCwgaW5kZXhfb2ZfZGltMTtcbiAgICAgIGluZGV4X29mX2RpbTAgPSBvdXRwdXRfaW5kZXggLyBvdXRwdXRfcGl0Y2hlc1swXTtcbiAgICAgIG0gPSBvdXRwdXRfaW5kZXggLSBpbmRleF9vZl9kaW0wICogb3V0cHV0X3BpdGNoZXNbMF07XG4gICAgICBpbmRleF9vZl9kaW0xID0gbTtcblxuICAgICAgaW50IGluZGV4X29mX2lucHV0X2RpbTAsIGluZGV4X29mX2lucHV0X2RpbTEsIHhfb2Zmc2V0LCB5X29mZnNldDtcbiAgICAgIGluZGV4X29mX2lucHV0X2RpbTAgPSBpbmRleF9vZl9kaW0wIC8gc2NhbGVzWzBdO1xuICAgICAgeV9vZmZzZXQgPSBpbmRleF9vZl9kaW0wIC0gaW5kZXhfb2ZfaW5wdXRfZGltMCAqIHNjYWxlc1swXTtcbiAgICAgIGluZGV4X29mX2lucHV0X2RpbTEgPSBpbmRleF9vZl9kaW0xIC8gc2NhbGVzWzFdO1xuICAgICAgeF9vZmZzZXQgPSBpbmRleF9vZl9kaW0xIC0gaW5kZXhfb2ZfaW5wdXRfZGltMSAqIHNjYWxlc1sxXTtcblxuICAgICAgaW5wdXRfaW5kZXggPSBpbmRleF9vZl9pbnB1dF9kaW0wICogaW5wdXRfcGl0Y2hlc1swXSArIGluZGV4X29mX2lucHV0X2RpbTE7XG5cbiAgICAgIGZsb2F0IHgwMCA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXgpO1xuICAgICAgZmxvYXQgeDEwLCB4MDEsIHgxMTtcblxuICAgICAgYm9vbCBlbmRfb2ZfZGltMCA9IGZhbHNlO1xuICAgICAgaWYgKGluZGV4X29mX2lucHV0X2RpbTAgPT0gKCR7aW5wdXRzWzBdLmRpbXNbMF19IC0gMSkpIHtcbiAgICAgICAgLy8gSXQncyB0aGUgZW5kIGluIGRpbWVuc2lvbiAwXG4gICAgICAgIHgwMSA9IHgwMDtcbiAgICAgICAgZW5kX29mX2RpbTAgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeDAxID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIGlucHV0X3BpdGNoZXNbMF0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5kZXhfb2ZfaW5wdXRfZGltMSA9PSAoaW5wdXRfcGl0Y2hlc1swXSAtIDEpKSB7XG4gICAgICAgIC8vIEl0J3MgdGhlIGVuZCBpbiBkaW1lbnNpb24gMVxuICAgICAgICB4MTAgPSB4MDA7XG4gICAgICAgIHgxMSA9IHgwMTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB4MTAgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgMSk7XG4gICAgICAgIHgxMSA9IGVuZF9vZl9kaW0wID8geDEwIDogZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIGlucHV0X3BpdGNoZXNbMF0gKyAxKTtcbiAgICAgIH1cblxuICAgICAgZmxvYXQgeTAgPSB4MDAgKyBmbG9hdCh5X29mZnNldCkgKiAoeDAxIC0geDAwKSAvIGZsb2F0KHNjYWxlc1swXSk7XG4gICAgICBmbG9hdCB5MSA9IHgxMCArIGZsb2F0KHlfb2Zmc2V0KSAqICh4MTEgLSB4MTApIC8gZmxvYXQoc2NhbGVzWzBdKTtcbiAgICAgIHJldHVybiB5MCArIGZsb2F0KHhfb2Zmc2V0KSAqICh5MSAtIHkwKSAvIGZsb2F0KHNjYWxlc1sxXSk7XG4gICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4udXBzYW1wbGVQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIHZhcmlhYmxlczogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnc2NhbGVzJyxcbiAgICAgICAgdHlwZTogJ2ludCcsXG4gICAgICAgIGFycmF5TGVuZ3RoOiBhdHRyaWJ1dGVzLnNjYWxlcy5sZW5ndGgsXG4gICAgICAgIGRhdGE6IGF0dHJpYnV0ZXMuc2NhbGVzLm1hcCgoeCkgPT4gTWF0aC5jZWlsKHgpKSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGU6IFVwc2FtcGxlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAoXG4gICAgIWlucHV0cyB8fFxuICAgIChhdHRyaWJ1dGUub3BzZXQgPCA5ICYmIGlucHV0cy5sZW5ndGggIT09IDEpIHx8XG4gICAgKGF0dHJpYnV0ZS5vcHNldCA+PSA5ICYmIGF0dHJpYnV0ZS5vcHNldCA8IDExICYmIGlucHV0cy5sZW5ndGggIT09IDIpIHx8XG4gICAgKGF0dHJpYnV0ZS5vcHNldCA+PSAxMSAmJiBpbnB1dHMubGVuZ3RoIDwgMilcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChhdHRyaWJ1dGUuc2NhbGVzLmxlbmd0aCA+IDAgJiYgaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSBhdHRyaWJ1dGUuc2NhbGVzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdGVuc29yIHR5cGVzLicpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2NhbGVzVmFsaWRhdGlvbiA9IChzY2FsZXM6IG51bWJlcltdLCBtb2RlOiBzdHJpbmcsIGlzUmVzaXplOiBib29sZWFuKTogdm9pZCA9PiB7XG4gIGlmICghaXNSZXNpemUpIHtcbiAgICBmb3IgKGNvbnN0IHNjYWxlIG9mIHNjYWxlcykge1xuICAgICAgaWYgKHNjYWxlIDwgMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NjYWxlIHZhbHVlIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMS4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZm9yIChjb25zdCBzY2FsZSBvZiBzY2FsZXMpIHtcbiAgICAgIGlmIChzY2FsZSA8PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignU2NhbGUgdmFsdWUgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiAwLicpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAobW9kZSA9PT0gJ2xpbmVhcicgfHwgbW9kZSA9PT0gJ2N1YmljJykge1xuICAgIGlmIChzY2FsZXMubGVuZ3RoICE9PSAyICYmIChzY2FsZXMubGVuZ3RoICE9PSA0IHx8IHNjYWxlc1swXSAhPT0gMSB8fCBzY2FsZXNbMV0gIT09IDEpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCdMaW5lYXInIG1vZGUgYW5kICdDdWJpYycgbW9kZSBvbmx5IHN1cHBvcnQgMi1EIGlucHV0cyAoJ0JpbGluZWFyJywgJ0JpY3ViaWMnKSBcXFxuICAgICAgICBvciA0LUQgaW5wdXRzIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgb3V0ZXJtb3N0IDIgc2NhbGUgdmFsdWVzIGJlaW5nIDEgXFxcbiAgICAgICAgaW4gdGhlICR7aXNSZXNpemUgPyAnUmVzaXplJyA6ICdVcHNhbXBsZSd9IG9wZWFydG9yLmApO1xuICAgIH1cbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29vcmRzRGF0YVR5cGUgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IHVucGFja0Zyb21DaGFubmVsIH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcbmltcG9ydCB7IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzLCBzY2FsZXNWYWxpZGF0aW9uLCBVcHNhbXBsZUF0dHJpYnV0ZXMsIHZhbGlkYXRlSW5wdXRzIH0gZnJvbSAnLi91cHNhbXBsZSc7XG5cbmNvbnN0IHJlc2l6ZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1Jlc2l6ZScsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCByZXNpemU6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnJlc2l6ZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlUGFja2VkUmVzaXplUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMDogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxVcHNhbXBsZUF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogVXBzYW1wbGVBdHRyaWJ1dGVzID0+IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzKG5vZGUsIDEwKTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMTogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxVcHNhbXBsZUF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogVXBzYW1wbGVBdHRyaWJ1dGVzID0+IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzKG5vZGUsIDExKTtcblxuY29uc3QgY3JlYXRlUGFja2VkUmVzaXplUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IFtzY2FsZXMsIG91dHB1dFNoYXBlXSA9IHByZXBhcmVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcblxuICBjb25zdCBpc1NhbWUgPSBzY2FsZXMuZXZlcnkoKHM6IG51bWJlcikgPT4gcyA9PT0gMSkgJiYgYXR0cmlidXRlcy5jb29yZGluYXRlVHJhbnNmb3JtTW9kZSAhPT0gJ3RmX2Nyb3BfYW5kX3Jlc2l6ZSc7XG4gIGlmIChpc1NhbWUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4ucmVzaXplUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgICAgaGFzTWFpbjogdHJ1ZSxcbiAgICAgIHNoYWRlclNvdXJjZTogYHZvaWQgbWFpbigpIHtcbiAgICAgICAgICAgICAgICAgICAgdmVjNCB2ID0gJHtnbHNsLnRleHR1cmUyRH0oWCwgVGV4Q29vcmRzKTtcbiAgICAgICAgICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2O1xuICAgICAgICAgICAgICAgIH1gLFxuICAgIH07XG4gIH1cblxuICBjb25zdCBkaW0gPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGlmIChkaW0gPCAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXQgZGltZW5zaW9uIHNob3VsZCBiZSBhdCBsZWFzdCAyLCBidXQgZ290ICR7ZGltfWApO1xuICB9XG5cbiAgY29uc3Qgb3V0cHV0SGVpZ2h0ID0gb3V0cHV0U2hhcGVbZGltIC0gMl07XG4gIGNvbnN0IG91dHB1dFdpZHRoID0gb3V0cHV0U2hhcGVbZGltIC0gMV07XG5cbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBpZiAoZGltICE9PSBpbnB1dFNoYXBlLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgb3V0cHV0IGRpbWVuc2lvbiBzaG91bGQgbWF0Y2ggaW5wdXQgJHtpbnB1dFNoYXBlLmxlbmd0aH0sIGJ1dCBnb3QgJHtkaW19YCk7XG4gIH1cbiAgY29uc3QgaW5wdXRIZWlnaHQgPSBpbnB1dFNoYXBlW2RpbSAtIDJdO1xuICBjb25zdCBpbnB1dFdpZHRoID0gaW5wdXRTaGFwZVtkaW0gLSAxXTtcblxuICBjb25zdCBzY2FsZXNIZWlnaHQgPSBzY2FsZXNbZGltIC0gMl07XG4gIGNvbnN0IHNjYWxlc1dpZHRoID0gc2NhbGVzW2RpbSAtIDFdO1xuXG4gIGxldCBnZXRTb3VyY2VGcmFjSW5kZXggPSAnJztcblxuICBpZiAoYXR0cmlidXRlcy5tb2RlICE9PSAnbGluZWFyJykge1xuICAgIC8vIFRPRE86IHN1cHBvcnQgb3RoZXIgbW9kZXNcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHJlc2l6ZSAocGFja2VkKSBkb2VzIG5vdCBzdXBwb3J0IG1vZGU6ICcke2F0dHJpYnV0ZXMubW9kZX0nYCk7XG4gIH1cbiAgc3dpdGNoIChhdHRyaWJ1dGVzLmNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlKSB7XG4gICAgY2FzZSAnYXN5bW1ldHJpYyc6XG4gICAgICBnZXRTb3VyY2VGcmFjSW5kZXggPSBgXG4gICAgICAgICAgICAgICAgICAgIHZlYzQgZ2V0U291cmNlRnJhY0luZGV4KGl2ZWM0IGNvb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZlYzQoY29vcmRzKSAvIHNjYWxlV0hXSDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGA7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdoYWxmX3BpeGVsJzpcbiAgICAgIGdldFNvdXJjZUZyYWNJbmRleCA9IGBcbiAgICAgICAgICAgICAgICAgICAgdmVjNCBnZXRTb3VyY2VGcmFjSW5kZXgoaXZlYzQgY29vcmRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHZlYzQoY29vcmRzKSArIDAuNSkgLyBzY2FsZVdIV0ggLSAwLjU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAncHl0b3JjaF9oYWxmX3BpeGVsJzpcbiAgICAgIGdldFNvdXJjZUZyYWNJbmRleCA9IGBcbiAgICAgICAgICAgICAgICAgICAgdmVjNCBnZXRTb3VyY2VGcmFjSW5kZXgoaXZlYzQgY29vcmRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZWM0IGZjb29yZHMgPSB2ZWM0KGNvb3Jkcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmVjNChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke291dHB1dFdpZHRofS4wID4gMS4wID8gKGZjb29yZHMueCArIDAuNSkgLyBzY2FsZVdIV0gueCAtIDAuNSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke291dHB1dEhlaWdodH0uMCA+IDEuMCA/IChmY29vcmRzLnkgKyAwLjUpIC8gc2NhbGVXSFdILnkgLSAwLjUgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRXaWR0aH0uMCA+IDEuMCA/IChmY29vcmRzLnogKyAwLjUpIC8gc2NhbGVXSFdILnogLSAwLjUgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRIZWlnaHR9LjAgPiAxLjAgPyAoZmNvb3Jkcy53ICsgMC41KSAvIHNjYWxlV0hXSC53IC0gMC41IDogMC4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnYWxpZ25fY29ybmVycyc6XG4gICAgICBnZXRTb3VyY2VGcmFjSW5kZXggPSBgXG4gICAgICAgICAgICAgICAgICAgIHZlYzQgZ2V0U291cmNlRnJhY0luZGV4KGl2ZWM0IGNvb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVjNCByZXNpemVkID0gdmVjNCgke291dHB1dFdpZHRofS4wIC0gMS4wLCAke291dHB1dEhlaWdodH0uMCAtIDEuMCwgJHtvdXRwdXRXaWR0aH0uMCAtIDEuMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke291dHB1dEhlaWdodH0uMCAtIDEuMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZWM0IG9yaWdpbmFsID0gdmVjNCgke2lucHV0V2lkdGh9LjAgLSAxLjAsICR7aW5wdXRIZWlnaHR9LjAgLSAxLjAsICR7aW5wdXRXaWR0aH0uMCAtIDEuMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2lucHV0SGVpZ2h0fS4wIC0gMS4wKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlYzQgbmV3X3NjYWxlID0gb3JpZ2luYWwgLyByZXNpemVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZlYzQoY29vcmRzKSAqIG5ld19zY2FsZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGA7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgLy8gVE9ETzpzdXBwb3J0aW5nIG90aGVyIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2Rlc1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGByZXNpemUgKHBhY2tlZCkgZG9lcyBub3Qgc3VwcG9ydCBjb29yZGluYXRlVHJhbnNmb3JtTW9kZTogXFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyR7YXR0cmlidXRlcy5jb29yZGluYXRlVHJhbnNmb3JtTW9kZX0nYCk7XG4gIH1cblxuICBjb25zdCBjb29yZHNEYXRhVHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKGRpbSk7XG4gIGNvbnN0IHVucGFja0NoYW5uZWwgPSB1bnBhY2tGcm9tQ2hhbm5lbCgpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICAgICBjb25zdCB2ZWMyIGlucHV0V0ggPSB2ZWMyKCR7aW5wdXRIZWlnaHR9LjAsICR7aW5wdXRXaWR0aH0uMCk7XG4gICAgICAgICAgICBjb25zdCB2ZWM0IHNjYWxlV0hXSCA9IHZlYzQoZmxvYXQoJHtzY2FsZXNIZWlnaHR9KSwgZmxvYXQoJHtzY2FsZXNXaWR0aH0pLCBmbG9hdCgke3NjYWxlc0hlaWdodH0pLCBmbG9hdCgke1xuICAgICAgICAgICAgICBzY2FsZXNXaWR0aFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgJHt1bnBhY2tDaGFubmVsfVxuICAgICAgICAgICAgJHtnZXRTb3VyY2VGcmFjSW5kZXh9XG4gICAgICAgICAgICBmbG9hdCBnZXRBVmFsdWUoaW50IHgxMCwgaW50IHIsIGludCBjLCBpbnQgZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnZXRDaGFubmVsKGdldEEoeDEwLCByLCBjLCBkKSwgdmVjMihjLCBkKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgICAgICAgJHtjb29yZHNEYXRhVHlwZX0gcmMgPSBnZXRPdXRwdXRDb29yZHMoKTtcblxuICAgICAgICAgICAgICAgIGludCBiYXRjaCA9IHJjWzBdO1xuICAgICAgICAgICAgICAgIGludCBkZXB0aCA9IHJjWzFdO1xuXG4gICAgICAgICAgICAgICAgLy8gcmV0cmlldmUgdGhlIDQgY29vcmRpbmF0ZXMgdGhhdCBpcyB1c2VkIGluIHRoZSA0IHBhY2tlZCBvdXRwdXQgdmFsdWVzLlxuICAgICAgICAgICAgICAgIGl2ZWM0IGNvb3JkcyA9IGl2ZWM0KHJjLnd6LCByYy53ICsgMSwgcmMueiArIDEpO1xuXG4gICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSBzb3VyY2UgaW5kZXggaW4gZnJhY3Rpb25cbiAgICAgICAgICAgICAgICB2ZWM0IHNvdXJjZUZyYWMgPSBnZXRTb3VyY2VGcmFjSW5kZXgoY29vcmRzKTtcblxuICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgbG93ZXIgYW5kIHVwcGVyIGJvdW5kIG9mIHRoZSA0IHZhbHVlcyB0aGF0IHdpbGwgYmUgcGFja2VkIGludG8gb25lIHRleGVsLlxuICAgICAgICAgICAgICAgIGl2ZWM0IHgwMCA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnh5LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnh5KSkpO1xuICAgICAgICAgICAgICAgIGl2ZWM0IHgwMSA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnh3LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnh3KSkpO1xuICAgICAgICAgICAgICAgIGl2ZWM0IHgxMCA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnp5LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnp5KSkpO1xuICAgICAgICAgICAgICAgIGl2ZWM0IHgxMSA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnp3LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnp3KSkpO1xuXG4gICAgICAgICAgICAgICAgYm9vbCBoYXNOZXh0Um93ID0gcmMudyA8ICR7b3V0cHV0SGVpZ2h0IC0gMX07XG4gICAgICAgICAgICAgICAgYm9vbCBoYXNOZXh0Q29sID0gcmMueiA8ICR7b3V0cHV0V2lkdGggLSAxfTtcblxuICAgICAgICAgICAgICAgIC8vIHBhY2sgeDAwLCB4MDEsIHgxMCwgeDExJ3MgdG9wLWxlZnQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCB0b3BMZWZ0ID0gdmVjNChcbiAgICAgICAgICAgICAgICAgICAgZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAwLngsIHgwMC55KSxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMS54LCB4MDEueSkgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTAueCwgeDEwLnkpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMS54LCB4MTEueSkgOiAwLjApO1xuXG4gICAgICAgICAgICAgICAgLy8gcGFjayB4MDAsIHgwMSwgeDEwLCB4MTEncyB0b3AtcmlnaHQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCB0b3BSaWdodCA9IHZlYzQoXG4gICAgICAgICAgICAgICAgICAgIGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMC54LCB4MDAudyksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDEueCwgeDAxLncpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDEwLngsIHgxMC53KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTEueCwgeDExLncpIDogMC4wKTtcblxuICAgICAgICAgICAgICAgIC8vIHBhY2sgeDAwLCB4MDEsIHgxMCwgeDExJ3MgYm90dG9tLWxlZnQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCBib3R0b21MZWZ0ID0gdmVjNChcbiAgICAgICAgICAgICAgICAgICAgZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAwLnosIHgwMC55KSxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMS56LCB4MDEueSkgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTAueiwgeDEwLnkpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMS56LCB4MTEueSkgOiAwLjApO1xuXG4gICAgICAgICAgICAgICAgLy8gcGFjayB4MDAsIHgwMSwgeDEwLCB4MTEncyBib3R0b20tcmlnaHQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCBib3R0b21SaWdodCA9IHZlYzQoXG4gICAgICAgICAgICAgICAgICAgIGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMC56LCB4MDAudyksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDEueiwgeDAxLncpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDEwLnosIHgxMC53KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTEueiwgeDExLncpIDogMC4wKTtcblxuICAgICAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgaW50ZXJwb2xhdGlvbiBmcmFjdGlvbiBvbiB1IGFuZCB2IGRpcmVjdGlvblxuICAgICAgICAgICAgICAgIHZlYzQgZnJhYyA9IHZlYzQoc291cmNlRnJhYykgLSBmbG9vcihzb3VyY2VGcmFjKTtcbiAgICAgICAgICAgICAgICB2ZWM0IGNsYW1wRnJhYyA9IGNsYW1wKGZyYWMsIHZlYzQoMC4wKSwgdmVjNCgxLjApKTtcblxuICAgICAgICAgICAgICAgIHZlYzQgdG9wID0gbWl4KHRvcExlZnQsIHRvcFJpZ2h0LCBjbGFtcEZyYWMueXd5dyk7XG4gICAgICAgICAgICAgICAgdmVjNCBib3R0b20gPSBtaXgoYm90dG9tTGVmdCwgYm90dG9tUmlnaHQsIGNsYW1wRnJhYy55d3l3KTtcbiAgICAgICAgICAgICAgICB2ZWM0IG5ld1ZhbHVlID0gbWl4KHRvcCwgYm90dG9tLCBjbGFtcEZyYWMueHh6eik7XG5cbiAgICAgICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQobmV3VmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLnJlc2l6ZVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkIH0sXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBwcmVwYXJlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcyk6IFtyZWFkb25seSBudW1iZXJbXSwgcmVhZG9ubHkgbnVtYmVyW11dID0+IHtcbiAgY29uc3QgeCA9IGlucHV0c1swXTtcbiAgY29uc3QgeERpbXMgPSB4LmRpbXM7XG5cbiAgbGV0IHNjYWxlcyA9IGF0dHJpYnV0ZXMuc2NhbGVzO1xuICBsZXQgb3V0cHV0U2l6ZXM6IG51bWJlcltdIHwgdW5kZWZpbmVkO1xuICBpZiAoc2NhbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIGNvbnN0IHNjYWxlc1RlbnNvciA9IGlucHV0c1thdHRyaWJ1dGVzLnNjYWxlc0lucHV0SWR4XTtcbiAgICBpZiAoc2NhbGVzVGVuc29yICYmIHNjYWxlc1RlbnNvci5zaXplICE9PSAwKSB7XG4gICAgICBpZiAoaW5wdXRzW2F0dHJpYnV0ZXMuc2l6ZXNJbnB1dElkeF0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IG9uZSBvZiBzY2FsZXMgb3Igc2l6ZXMgbXVzdCBiZSBwcm92aWRlZCBhcyBpbnB1dC4nKTtcbiAgICAgIH1cbiAgICAgIHNjYWxlcyA9IHBhcnNlU2NhbGVzRGF0YShzY2FsZXNUZW5zb3IsIGF0dHJpYnV0ZXMubW9kZSwgYXR0cmlidXRlcy5pc1Jlc2l6ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHNpemVzVGVuc29yID0gaW5wdXRzW2F0dHJpYnV0ZXMuc2l6ZXNJbnB1dElkeF07XG4gICAgICBpZiAoIXNpemVzVGVuc29yIHx8IHNpemVzVGVuc29yLnNpemUgPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFaXRoZXIgc2NhbGVzIG9yIHNpemVzIE1VU1QgYmUgcHJvdmlkZWQgYXMgaW5wdXQuJyk7XG4gICAgICB9XG5cbiAgICAgIG91dHB1dFNpemVzID0gQXJyYXkuZnJvbShzaXplc1RlbnNvci5pbnRlZ2VyRGF0YSk7XG4gICAgICBzY2FsZXMgPSBwYXJzZVNjYWxlc0RhdGFGcm9tT3V0cHV0U2l6ZShvdXRwdXRTaXplcywgeERpbXMsIGF0dHJpYnV0ZXMubW9kZSwgYXR0cmlidXRlcy5pc1Jlc2l6ZSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChpbnB1dHNbYXR0cmlidXRlcy5zaXplc0lucHV0SWR4XSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IG9uZSBvZiBzY2FsZXMgb3Igc2l6ZXMgbXVzdCBiZSBwcm92aWRlZCBhcyBpbnB1dC4nKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCB5RGltcyA9IG91dHB1dFNpemVzIHx8IHhEaW1zLm1hcCgoZGltLCBpKSA9PiBNYXRoLmZsb29yKGRpbSAqIHNjYWxlc1tpXSkpO1xuXG4gIHJldHVybiBbc2NhbGVzLCB5RGltc107XG59O1xuXG5jb25zdCBwYXJzZVNjYWxlc0RhdGEgPSAoc2NhbGU6IFRlbnNvciwgbW9kZTogc3RyaW5nLCBpc1Jlc2l6ZTogYm9vbGVhbik6IG51bWJlcltdID0+IHtcbiAgY29uc3Qgc2NhbGVzID0gQXJyYXkuZnJvbShzY2FsZS5mbG9hdERhdGEpO1xuICBzY2FsZXNWYWxpZGF0aW9uKHNjYWxlcywgbW9kZSwgaXNSZXNpemUpO1xuICByZXR1cm4gc2NhbGVzO1xufTtcblxuY29uc3QgcGFyc2VTY2FsZXNEYXRhRnJvbU91dHB1dFNpemUgPSAoXG4gIHlEaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgeERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBtb2RlOiBzdHJpbmcsXG4gIGlzUmVzaXplOiBib29sZWFuLFxuKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCBsZW5ndGggPSB4RGltcy5sZW5ndGg7XG4gIGNvbnN0IHNjYWxlcyA9IG5ldyBBcnJheTxudW1iZXI+KGxlbmd0aCk7XG5cbiAgZm9yIChsZXQgaSA9IDAsIGVuZCA9IGxlbmd0aDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgaWYgKHhEaW1zW2ldID09PSAwKSB7XG4gICAgICBpZiAoeURpbXNbaV0gIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBkaW0gaXMgemVybyBidXQgcmVxdWlyZWQgb3V0cHV0IGRpbSBpcyBub24temVyby4nKTtcbiAgICAgIH1cbiAgICAgIHNjYWxlc1tpXSA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjYWxlc1tpXSA9IHlEaW1zW2ldIC8geERpbXNbaV07XG4gICAgfVxuICB9XG4gIHNjYWxlc1ZhbGlkYXRpb24oc2NhbGVzLCBtb2RlLCBpc1Jlc2l6ZSk7XG4gIHJldHVybiBzY2FsZXM7XG59O1xuXG4vLyByb2kgZGF0YSBpcyBub3QgdXNlZCB5ZXQuIGJ1dCBsZWF2ZSBoZXJlIGZvciBmdXR1cmUgdXNhZ2UuXG4vLyBjb25zdCBnZXRSb2kgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzKSA6IG51bWJlcltdID0+IHtcbi8vICAgICBsZXQgcm9pOiBudW1iZXJbXSA9IFtdO1xuLy8gICAgIGlmIChhdHRyaWJ1dGVzLm5lZWRSb2lJbnB1dCkge1xuLy8gICAgICAgICBpZiAoYXR0cmlidXRlcy5yb2lJbnB1dElkeCA8PSAwKSB7XG4vLyAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcm9pIGlucHV0IGluZGV4LicpO1xuLy8gICAgICAgICB9XG4vLyAgICAgICAgIGNvbnN0IHJvaVRlbnNvciA9IGlucHV0c1thdHRyaWJ1dGVzLnJvaUlucHV0SWR4XTtcbi8vICAgICAgICAgcm9pID0gcm9pVGVuc29yLnNpemUgPiAwID8gQXJyYXkuZnJvbShyb2lUZW5zb3IuZmxvYXREYXRhKSA6IFtdO1xuLy8gICAgIH0gZWxzZSB7XG4vLyAgICAgICAgIHJvaSA9IG5ldyBBcnJheShpbnB1dHNbMF0uZGltcy5sZW5ndGggKiAyKS5maWxsKDApO1xuLy8gICAgIH1cbi8vICAgICByZXR1cm4gcm9pO1xuLy8gfTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuZXhwb3J0IGNvbnN0IHNoYXBlID0gKF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIHJldHVybiBbbmV3IFRlbnNvcihbaW5wdXRzWzBdLmRpbXMubGVuZ3RoXSwgJ2ludDMyJywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIG5ldyBJbnQzMkFycmF5KGlucHV0c1swXS5kaW1zKSldO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaGFwZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE5VTUJFUl9UWVBFUywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2xpY2VBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhlczogbnVtYmVyW107XG4gIHJlYWRvbmx5IGVuZHM6IG51bWJlcltdO1xuICByZWFkb25seSBzdGFydHM6IG51bWJlcltdO1xufVxuXG5jb25zdCBzbGljZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1NsaWNlJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3Qgc2xpY2U6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248U2xpY2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBTbGljZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnNsaWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVTbGljZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcyksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNsaWNlQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxTbGljZUF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBTbGljZUF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBzdGFydHMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnc3RhcnRzJyk7XG4gIGNvbnN0IGVuZHMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnZW5kcycpO1xuICBjb25zdCBheGVzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2F4ZXMnLCBbXSk7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBzdGFydHMsIGVuZHMsIGF4ZXMgfSk7XG59O1xuXG5jb25zdCBjcmVhdGVTbGljZVByb2dyYW1JbmZvID0gKFxuICBfaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBhdHRyaWJ1dGVzOiBTbGljZUF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGF4ZXMgPSBhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoID09PSAwID8gaW5wdXQuZGltcy5zbGljZSgwKS5tYXAoKF92YWwsIGkpID0+IGkpIDogYXR0cmlidXRlcy5heGVzO1xuICBjb25zdCBub3JtYWxpemVkQXhlcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGVzKGF4ZXMsIGlucHV0LmRpbXMubGVuZ3RoKTtcbiAgY29uc3Qgc3RhcnRzID0gYXR0cmlidXRlcy5zdGFydHMubWFwKChzdGFydCwgaSkgPT4ge1xuICAgIGlmIChzdGFydCA+IGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dIC0gMSkge1xuICAgICAgcmV0dXJuIGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dO1xuICAgIH1cbiAgICByZXR1cm4gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoc3RhcnQsIGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dKTtcbiAgfSk7XG4gIGNvbnN0IGVuZHMgPSBhdHRyaWJ1dGVzLmVuZHMubWFwKChlbmQsIGkpID0+IHtcbiAgICBpZiAoZW5kID4gaW5wdXQuZGltc1tub3JtYWxpemVkQXhlc1tpXV0gLSAxKSB7XG4gICAgICByZXR1cm4gaW5wdXQuZGltc1tub3JtYWxpemVkQXhlc1tpXV07XG4gICAgfVxuICAgIHJldHVybiBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhlbmQsIGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dKTtcbiAgfSk7XG5cbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dC5kaW1zLnNsaWNlKCk7XG5cbiAgY29uc3Qgc2xpY2VPcHM6IHN0cmluZ1tdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbm9ybWFsaXplZEF4ZXMubGVuZ3RoOyBpKyspIHtcbiAgICBvdXRwdXRTaGFwZVtub3JtYWxpemVkQXhlc1tpXV0gPSBlbmRzW2ldIC0gc3RhcnRzW2ldO1xuICAgIGlmIChzdGFydHNbaV0gPiAwKSB7XG4gICAgICBzbGljZU9wcy5wdXNoKGBvdXRwdXRJZHhbJHtub3JtYWxpemVkQXhlc1tpXX1dICs9ICR7c3RhcnRzW2ldfTtgKTtcbiAgICB9IC8vIGVsc2UgeyBzbGljZU9wcy5wdXNoKGBvdXRwdXRJZHhbJHtub3JtYWxpemVkQXhlc1tpXX1dICs9IDA7YCk7IH1cbiAgfVxuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IG91dHB1dElkeFske3Jhbmt9XSkge1xuICAgICAgICAke3NsaWNlT3BzLmpvaW4oJ1xcbiAgICAgICcpfVxuICAgICAgICByZXR1cm4gX0Eob3V0cHV0SWR4KTtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLnNsaWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTbGljZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG4gIGlmIChOVU1CRVJfVFlQRVMuaW5kZXhPZihpbnB1dHNbMF0udHlwZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzbGljZVYxMCA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzVjEwKGlucHV0cyk7XG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSBnZW5lcmF0ZVNsaWNlQXR0cmlidXRlc0Zyb21JbnB1dHMoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4uc2xpY2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZVNsaWNlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBhdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIFtpbnB1dHNbMF1dLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5jb25zdCBnZW5lcmF0ZVNsaWNlQXR0cmlidXRlc0Zyb21JbnB1dHMgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbik6IFNsaWNlQXR0cmlidXRlcyA9PiB7XG4gIGlmIChcbiAgICAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzFdLmRhdGFJZCkgfHxcbiAgICAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzJdLmRhdGFJZCkgfHxcbiAgICAoaW5wdXRzLmxlbmd0aCA+PSA0ICYmICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbM10uZGF0YUlkKSkgfHxcbiAgICAoaW5wdXRzLmxlbmd0aCA+PSA1ICYmICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbNF0uZGF0YUlkKSlcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkeW5hbWljIHNsaWNlIGF0dHJpYnV0ZXMgYXJlIG5vdCBhbGxvd2VkJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzLmxlbmd0aCA+PSA1ICYmIGlucHV0c1s0XS5pbnRlZ2VyRGF0YS5zb21lKChpOiBudW1iZXIpID0+IGkgIT09IDEpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgbm9uLTEgc3RlcHMgaXMgbm90IHN1cHBvcnRlZCBmb3IgU2xpY2UnKTtcbiAgfVxuXG4gIGNvbnN0IHN0YXJ0cyA9IEFycmF5LmZyb20oaW5wdXRzWzFdLmludGVnZXJEYXRhKTtcbiAgY29uc3QgZW5kcyA9IEFycmF5LmZyb20oaW5wdXRzWzJdLmludGVnZXJEYXRhKTtcbiAgY29uc3QgYXhlcyA9IGlucHV0cy5sZW5ndGggPj0gNCA/IEFycmF5LmZyb20oaW5wdXRzWzNdLmludGVnZXJEYXRhKSA6IFtdO1xuICBjb25zdCBjYWNoZUtleSA9IGAke2F4ZXN9OyR7c3RhcnRzfTske2VuZHN9YDtcbiAgcmV0dXJuIHsgc3RhcnRzLCBlbmRzLCBheGVzLCBjYWNoZUtleSB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMTAgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoIDwgMyB8fCBpbnB1dHMubGVuZ3RoID4gNSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBudW1iZXIuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInIHx8IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMl0udHlwZSAhPT0gJ2ludDMyJyB8fCBpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzLmxlbmd0aCA+PSA0ICYmIChpbnB1dHNbM10udHlwZSAhPT0gJ2ludDMyJyB8fCBpbnB1dHNbM10uZGltcy5sZW5ndGggIT09IDEpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0cy5sZW5ndGggPj0gNSAmJiAoaW5wdXRzWzRdLnR5cGUgIT09ICdpbnQzMicgfHwgaW5wdXRzWzRdLmRpbXMubGVuZ3RoICE9PSAxKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgdHJhbnNwb3NlLCBUcmFuc3Bvc2VBdHRyaWJ1dGVzIH0gZnJvbSAnLi90cmFuc3Bvc2UnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNvZnRtYXhBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xufVxuXG5jb25zdCBzb2Z0bWF4Q29tcHV0ZU1heFByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1NvZnRtYXhDb21wdXRlTWF4JyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBzb2Z0bWF4Q29tcHV0ZVNjYWxlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnU29mdG1heENvbXB1dGVTY2FsZScsXG4gIGlucHV0TmFtZXM6IFsnQScsICdNYXgnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBzb2Z0bWF4UHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnU29mdE1heCcsXG4gIGlucHV0TmFtZXM6IFsnQScsICdNYXgnLCAnTm9ybSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3Qgc29mdG1heDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxTb2Z0bWF4QXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogU29mdG1heEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3QgbG9naWNhbFJvd0NvdW50ID0gU2hhcGVVdGlsLnNpemVUb0RpbWVuc2lvbihpbnB1dFNoYXBlLCBheGlzKTtcbiAgY29uc3QgZmVhdHVyZUNvdW50ID0gU2hhcGVVdGlsLnNpemVGcm9tRGltZW5zaW9uKGlucHV0U2hhcGUsIGF4aXMpO1xuXG4gIGNvbnN0IG91dHB1dCA9IGNvbXB1dGVTb2Z0bWF4KGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgbG9naWNhbFJvd0NvdW50LCBmZWF0dXJlQ291bnQpO1xuICByZXR1cm4gb3V0cHV0O1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlU29mdG1heEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248U29mdG1heEF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogU29mdG1heEF0dHJpYnV0ZXMgPT4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpczogbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIDEpIH0pO1xuXG5leHBvcnQgY29uc3QgcGFyc2VTb2Z0bWF4QXR0cmlidXRlc1YxMzogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxTb2Z0bWF4QXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBTb2Z0bWF4QXR0cmlidXRlcyA9PiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGlzOiBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdheGlzJywgLTEpIH0pO1xuXG4vLyBUaGUgXCJzZW1hbnRpY1wiIG1lYW5pbmcgb2YgYXhpcyBoYXMgY2hhbmdlZCBpbiBvcHNldC0xMy5cbi8vIFBsZWFzZSBjb21wYXJlOiBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFpbi9kb2NzL09wZXJhdG9ycy5tZCNTb2Z0bWF4XG4vLyB3aXRoIGh0dHBzOi8vZ2l0aHViLmNvbS9vbm54L29ubngvYmxvYi9tYWluL2RvY3MvQ2hhbmdlbG9nLm1kI1NvZnRtYXgtMTEgZm9yIGRldGFpbGVkIGV4cGxhbmF0aW9uc1xuLy8gVG8gYWNjb3VudCBmb3IgdGhlIG9wc2V0LTEzIGJlaGF2aW9yLCBvdXIgcGxhbiB3aWxsIGJlIHRvIHRyYW5zcG9zZSB0aGUgXCJheGlzXCIgZGltIHRvIHRoZSBpbm5lcm1vc3QgZGltXG4vLyBhbmQgcGVyZm9ybSBzb2Z0bWF4IGFuZCB0aGVuIHJldmVyc2UgdGhlIHRyYW5zcG9zZS4gV2UgY2FuIHNraXAgdGhlIHRyYW5zcG9zaW5nIGFzcGVjdCBpZiB0aGUgYXhpcyBpcyBhbHJlYWR5XG4vLyB0aGUgaW5uZXJtb3N0IGRpbVxuZXhwb3J0IGNvbnN0IHNvZnRtYXhWMTM6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248U29mdG1heEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFNvZnRtYXhBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXR0cmlidXRlcy5heGlzLCBpbnB1dFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IHJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcblxuICBjb25zdCBpc1RyYW5zcG9zZVJlcXVpcmVkID0gYXhpcyAhPT0gcmFuayAtIDEgPyB0cnVlIDogZmFsc2U7XG4gIGNvbnN0IHRyYW5zcG9zZWRJbnB1dFNoYXBlOiBudW1iZXJbXSA9IFtdO1xuICBsZXQgcGVybTogbnVtYmVyW10gPSBbXTtcbiAgbGV0IHRyYW5zcG9zZWRJbnB1dHM6IFRlbnNvcltdID0gW107XG4gIGxldCB0cmFuc3Bvc2VBdHRyaWJ1dGU6IFRyYW5zcG9zZUF0dHJpYnV0ZXM7XG5cbiAgaWYgKGlzVHJhbnNwb3NlUmVxdWlyZWQpIHtcbiAgICBwZXJtID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogcmFuayB9KS5tYXAoKF8sIGkpID0+IGkpO1xuXG4gICAgLy8gc3dhcCB0aGUgaW5uZXJtb3N0IGRpbSB3aXRoIHRoZSBkaW0gY29ycmVzcG9uZGluZyB0byBheGlzXG4gICAgcGVybVtheGlzXSA9IHJhbmsgLSAxO1xuICAgIHBlcm1bcmFuayAtIDFdID0gYXhpcztcblxuICAgIHBlcm0ubWFwKChwKSA9PiB0cmFuc3Bvc2VkSW5wdXRTaGFwZS5wdXNoKGlucHV0U2hhcGVbcF0pKTtcblxuICAgIHRyYW5zcG9zZUF0dHJpYnV0ZSA9IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IHBlcm0gfSk7XG4gICAgdHJhbnNwb3NlZElucHV0cyA9IHRyYW5zcG9zZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIHRyYW5zcG9zZUF0dHJpYnV0ZSk7XG4gIH1cblxuICBjb25zdCBsb2dpY2FsUm93Q291bnQgPSBpc1RyYW5zcG9zZVJlcXVpcmVkXG4gICAgPyBTaGFwZVV0aWwuc2l6ZVRvRGltZW5zaW9uKHRyYW5zcG9zZWRJbnB1dFNoYXBlLCByYW5rIC0gMSlcbiAgICA6IFNoYXBlVXRpbC5zaXplVG9EaW1lbnNpb24oaW5wdXRTaGFwZSwgcmFuayAtIDEpO1xuICBjb25zdCBmZWF0dXJlQ291bnQgPSBpc1RyYW5zcG9zZVJlcXVpcmVkXG4gICAgPyBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24odHJhbnNwb3NlZElucHV0U2hhcGUsIHJhbmsgLSAxKVxuICAgIDogU2hhcGVVdGlsLnNpemVGcm9tRGltZW5zaW9uKGlucHV0U2hhcGUsIHJhbmsgLSAxKTtcblxuICBjb25zdCBvdXRwdXQgPSBjb21wdXRlU29mdG1heChcbiAgICBpbmZlcmVuY2VIYW5kbGVyLFxuICAgIGlzVHJhbnNwb3NlUmVxdWlyZWQgPyB0cmFuc3Bvc2VkSW5wdXRzIDogaW5wdXRzLFxuICAgIGF0dHJpYnV0ZXMsXG4gICAgbG9naWNhbFJvd0NvdW50LFxuICAgIGZlYXR1cmVDb3VudCxcbiAgKTtcblxuICBpZiAoaXNUcmFuc3Bvc2VSZXF1aXJlZCkge1xuICAgIGNvbnN0IHJldmVyc2VkT3V0cHV0ID0gdHJhbnNwb3NlKGluZmVyZW5jZUhhbmRsZXIsIG91dHB1dCwgdHJhbnNwb3NlQXR0cmlidXRlISk7XG4gICAgcmV0dXJuIHJldmVyc2VkT3V0cHV0O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbn07XG5cbmNvbnN0IGNvbXB1dGVTb2Z0bWF4ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFNvZnRtYXhBdHRyaWJ1dGVzLFxuICBsb2dpY2FsUm93Q291bnQ6IG51bWJlcixcbiAgZmVhdHVyZUNvdW50OiBudW1iZXIsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IGNvbXB1dGVNYXhQcm9ncmFtSW5mbyA9IGNyZWF0ZUNvbXB1dGVNYXhQcm9ncmFtSW5mbyhcbiAgICBpbmZlcmVuY2VIYW5kbGVyLFxuICAgIGlucHV0c1swXSxcbiAgICBsb2dpY2FsUm93Q291bnQsXG4gICAgZmVhdHVyZUNvdW50LFxuICAgIFtsb2dpY2FsUm93Q291bnRdLFxuICApO1xuICBjb25zdCBtYXggPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLnNvZnRtYXhDb21wdXRlTWF4UHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGdldDogKCkgPT4gY29tcHV0ZU1heFByb2dyYW1JbmZvIH0sXG4gICAgaW5wdXRzLFxuICApO1xuXG4gIGNvbnN0IGNvbXB1dGVTY2FsZVByb2dyYW1JbmZvID0gY3JlYXRlQ29tcHV0U2NhbGVQcm9ncmFtSW5mbyhcbiAgICBpbmZlcmVuY2VIYW5kbGVyLFxuICAgIGlucHV0c1swXSxcbiAgICBsb2dpY2FsUm93Q291bnQsXG4gICAgZmVhdHVyZUNvdW50LFxuICAgIGNvbXB1dGVNYXhQcm9ncmFtSW5mby5vdXRwdXQuZGltcyxcbiAgICBbbG9naWNhbFJvd0NvdW50XSxcbiAgKTtcbiAgY29uc3Qgc2NhbGUgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLnNvZnRtYXhDb21wdXRlU2NhbGVQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgZ2V0OiAoKSA9PiBjb21wdXRlU2NhbGVQcm9ncmFtSW5mbyB9LFxuICAgIFtpbnB1dHNbMF0sIG1heF0sXG4gICk7XG5cbiAgY29uc3Qgc29mdE1heFByb2dyYW1JbmZvID0gY3JlYXRlU29mdE1heFByb2dyYW1JbmZvKFxuICAgIGluZmVyZW5jZUhhbmRsZXIsXG4gICAgaW5wdXRzWzBdLFxuICAgIGxvZ2ljYWxSb3dDb3VudCxcbiAgICBmZWF0dXJlQ291bnQsXG4gICAgY29tcHV0ZU1heFByb2dyYW1JbmZvLm91dHB1dC5kaW1zLFxuICAgIGNvbXB1dGVTY2FsZVByb2dyYW1JbmZvLm91dHB1dC5kaW1zLFxuICApO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLnNvZnRtYXhQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgZ2V0OiAoKSA9PiBzb2Z0TWF4UHJvZ3JhbUluZm8gfSxcbiAgICBbaW5wdXRzWzBdLCBtYXgsIHNjYWxlXSxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuLyoqXG4gKiBDcmVhdGUgYSB0ZXh0dXJlIHRoYXQgY29udGFpbnMgdGhlIG1heGltdW0gdmFsdWUgb2YgZWFjaCBvZiB0aGUgJ04nIHJvd3NcbiAqL1xuY29uc3QgY3JlYXRlQ29tcHV0ZU1heFByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGxvZ2ljYWxSb3dDb3VudDogbnVtYmVyLFxuICBmZWF0dXJlQ291bnQ6IG51bWJlcixcbiAgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBbdGV4dHVyZVdpZHRoLCB0ZXh0dXJlSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGlucHV0LmRpbXMsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICk7XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgaWYgKGxvZ2ljYWxSb3dDb3VudCA8IDEgfHwgZmVhdHVyZUNvdW50IDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTG9naWNhbCByb3cgY291bnQgTiBhbmQgZmVhdHVyZSBjb3VudCBEIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgfVxuXG4gIGlmIChvdXRwdXRTaGFwZS5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbWVuc2lvbmFsaXR5IG9mIHRoZSBvdXRwdXQgc2hvdWxkIGJlIDEnKTtcbiAgfVxuXG4gIGlmIChvdXRwdXRTaGFwZVswXSAhPT0gbG9naWNhbFJvd0NvdW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaGFwZSBvZiB0aGUgb3V0cHV0IHNob3VsZCBiZSBlcXVhbCB0byBsb2dpY2FsIHJvdyBjb3VudCcpO1xuICB9XG5cbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG4gICAgICAgIGludCBsb2dpY2FsX3Jvd19zdGFydF9vZmZzZXQgPSBpbmRpY2VzWzBdICogJHtmZWF0dXJlQ291bnR9O1xuXG4gICAgICAgIGZsb2F0IG1heCA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShBLCBvZmZzZXRUb0Nvb3Jkcyhsb2dpY2FsX3Jvd19zdGFydF9vZmZzZXQsICR7dGV4dHVyZVdpZHRofSxcbiAgICAgICAgJHt0ZXh0dXJlSGVpZ2h0fSApKSk7XG4gICAgICAgIGZvcihpbnQgaT0xOyBpPCR7ZmVhdHVyZUNvdW50fTsgKytpKVxuICAgICAgICB7XG4gICAgICAgICAgZmxvYXQgY3VycmVudCA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShBLCBvZmZzZXRUb0Nvb3Jkcyhsb2dpY2FsX3Jvd19zdGFydF9vZmZzZXQgKyBpLFxuICAgICAgICAgICAgJHt0ZXh0dXJlV2lkdGh9LCAke3RleHR1cmVIZWlnaHR9KSkpO1xuICAgICAgICAgIGlmKGN1cnJlbnQgPiBtYXgpXG4gICAgICAgICAgbWF4ID0gY3VycmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtYXg7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zb2Z0bWF4Q29tcHV0ZU1heFByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgdGV4dHVyZSB0aGF0IGNvbnRhaW5zIHRoZSBub3JtYWxpemF0aW9uIGZhY3RvciBmb3IgZWFjaCBvZiB0aGUgJ04nIHJvd3NcbiAqL1xuY29uc3QgY3JlYXRlQ29tcHV0U2NhbGVQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBsb2dpY2FsUm93Q291bnQ6IG51bWJlcixcbiAgZmVhdHVyZUNvdW50OiBudW1iZXIsXG4gIG1heEVsZW1lbnRQZXJMb2dpY2FsUm93OiByZWFkb25seSBudW1iZXJbXSxcbiAgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBbdGV4dHVyZVdpZHRoLCB0ZXh0dXJlSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGlucHV0LmRpbXMsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICk7XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgaWYgKGxvZ2ljYWxSb3dDb3VudCA8IDEgfHwgZmVhdHVyZUNvdW50IDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTG9naWNhbCByb3cgY291bnQgTiBhbmQgZmVhdHVyZSBjb3VudCBEIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgfVxuXG4gIGlmIChvdXRwdXRTaGFwZS5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbWVuc2lvbmFsaXR5IG9mIHRoZSBvdXRwdXQgc2hvdWxkIGJlIDEnKTtcbiAgfVxuXG4gIGlmIChvdXRwdXRTaGFwZVswXSAhPT0gbG9naWNhbFJvd0NvdW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaGFwZSBvZiB0aGUgb3V0cHV0IHNob3VsZCBiZSBlcXVhbCB0byBsb2dpY2FsIHJvdyBjb3VudCcpO1xuICB9XG5cbiAgaWYgKG1heEVsZW1lbnRQZXJMb2dpY2FsUm93Lmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRGltZW5zaW9uYWxpdHkgb2YgdGhlIGludGVybWVkaWF0ZSByZXN1bHRzIHNob3VsZCBiZSAxJyk7XG4gIH1cblxuICBpZiAobWF4RWxlbWVudFBlckxvZ2ljYWxSb3dbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgb2YgdGhlIGludGVybWVkaWF0ZSByZXN1bHRzIHNob3VsZCBiZSBlcXVhbCB0byBsb2dpY2FsIHJvdyBjb3VudCcpO1xuICB9XG5cbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG4gICAgICAgIGludCBsb2dpY2FsX3Jvd19zdGFydF9vZmZzZXQgPSBpbmRpY2VzWzBdICogJHtmZWF0dXJlQ291bnR9O1xuXG4gICAgICAgIGZsb2F0IG5vcm1fZmFjdG9yID0gMC4wO1xuICAgICAgICBmbG9hdCBtYXggPSBfTWF4KGluZGljZXMpO1xuICAgICAgICBmb3IoaW50IGk9MDsgaTwke2ZlYXR1cmVDb3VudH07ICsraSlcbiAgICAgICAge1xuICAgICAgICAgIG5vcm1fZmFjdG9yICs9IGV4cChnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgb2Zmc2V0VG9Db29yZHMobG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0ICsgaSxcbiAgICAgICAgICAgICR7dGV4dHVyZVdpZHRofSwgJHt0ZXh0dXJlSGVpZ2h0fSkpKSAtIG1heCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9ybV9mYWN0b3I7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zb2Z0bWF4Q29tcHV0ZVNjYWxlUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlU29mdE1heFByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGxvZ2ljYWxSb3dDb3VudDogbnVtYmVyLFxuICBmZWF0dXJlQ291bnQ6IG51bWJlcixcbiAgbWF4RWxlbWVudFBlckxvZ2ljYWxSb3c6IHJlYWRvbmx5IG51bWJlcltdLFxuICBub3JtYWxpemF0aW9uUGVyTG9naWNhbFJvdzogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IFt0ZXh0dXJlV2lkdGgsIHRleHR1cmVIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgaW5wdXQuZGltcyxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgKTtcbiAgY29uc3QgcmFuayA9IGlucHV0LmRpbXMubGVuZ3RoO1xuXG4gIGlmIChsb2dpY2FsUm93Q291bnQgPCAxIHx8IGZlYXR1cmVDb3VudCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvZ2ljYWwgcm93IGNvdW50IE4gYW5kIGZlYXR1cmUgY291bnQgRCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gIH1cblxuICBpZiAobWF4RWxlbWVudFBlckxvZ2ljYWxSb3cubGVuZ3RoICE9PSAxIHx8IG5vcm1hbGl6YXRpb25QZXJMb2dpY2FsUm93Lmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRGltZW5zaW9uYWxpdHkgb2YgdGhlIGludGVybWVkaWF0ZSByZXN1bHRzIHNob3VsZCBiZSAxJyk7XG4gIH1cblxuICBpZiAobWF4RWxlbWVudFBlckxvZ2ljYWxSb3dbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCB8fCBub3JtYWxpemF0aW9uUGVyTG9naWNhbFJvd1swXSAhPT0gbG9naWNhbFJvd0NvdW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaGFwZSBvZiB0aGUgaW50ZXJtZWRpYXRlIHJlc3VsdHMgc2hvdWxkIGJlIGVxdWFsIHRvIGxvZ2ljYWwgcm93IGNvdW50Jyk7XG4gIH1cblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG5cbiAgICAgIC8vIGdldCBvZmZzZXQgb2YgY3VycmVudCBsb2dpY2FsIHRlbnNvciBpbmRleCBmcm9tIHRoZSAyLUQgdGV4dHVyZSBjb29yZGluYXRlcyAoVGV4Q29vcmRzKVxuICAgICAgaW50IG9mZnNldCA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXh0dXJlV2lkdGh9LCAke3RleHR1cmVIZWlnaHR9KTtcblxuICAgICAgLy9kZXRlcm1pbmUgdGhlIGxvZ2ljYWwgcm93IGZvciB0aGlzIGluZGV4XG4gICAgICBpbnQgbG9naWNhbF9yb3dfaW5kZXhbMV07XG4gICAgICBsb2dpY2FsX3Jvd19pbmRleFswXSA9IG9mZnNldCAvICR7ZmVhdHVyZUNvdW50fTtcblxuICAgICAgZmxvYXQgbm9ybV9mYWN0b3IgPSBfTm9ybShsb2dpY2FsX3Jvd19pbmRleCk7XG5cbiAgICAgIC8vIGF2b2lkIHBvc3NpYmxlIGRpdmlzaW9uIGJ5IDBcbiAgICAgIC8vIGlmIG5vcm1fZmFjb3IgaXMgMCwgYWxsIGVsZW1lbnRzIGFyZSB6ZXJvXG4gICAgICAvLyBpZiBzbywgcmV0dXJuIDBcbiAgICAgIGlmKG5vcm1fZmFjdG9yID09IDAuMClcbiAgICAgICAgcmV0dXJuIDAuMDtcblxuICAgICAgcmV0dXJuIGV4cChfQShpbmRpY2VzKSAtIF9NYXgobG9naWNhbF9yb3dfaW5kZXgpKSAvIG5vcm1fZmFjdG9yO1xuICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLnNvZnRtYXhQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0LmRpbXMsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU29mdG1heCByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsLCBTcGxpdFV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBTcGxpdEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG4gIHJlYWRvbmx5IHNwbGl0OiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgbnVtT3V0cHV0czogbnVtYmVyO1xufVxuXG5jb25zdCBzcGxpdFByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1NwbGl0JyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3Qgc3BsaXQ6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248U3BsaXRBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBTcGxpdEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgY29uc3QgY291bnQgPSBnZXRQcm9ncmFtQ291bnQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBheGlzLCBhdHRyaWJ1dGVzKTtcbiAgY29uc3Qgb3V0cHV0OiBUZW5zb3JbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyArK2kpIHtcbiAgICBvdXRwdXQucHVzaChcbiAgICAgIGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICB7XG4gICAgICAgICAgLi4uc3BsaXRQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgICAgY2FjaGVIaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fTske2l9YCxcbiAgICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZVNwbGl0UHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBhdHRyaWJ1dGVzLCBheGlzLCBpKSxcbiAgICAgICAgfSxcbiAgICAgICAgaW5wdXRzLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNwbGl0QXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxTcGxpdEF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBTcGxpdEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBheGlzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIDApO1xuICBjb25zdCBzcGxpdCA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdzcGxpdCcsIFtdKTtcbiAgY29uc3QgbnVtT3V0cHV0cyA9IG5vZGUub3V0cHV0cy5sZW5ndGg7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGlzLCBzcGxpdCwgbnVtT3V0cHV0cyB9KTtcbn07XG5cbmNvbnN0IGdldFByb2dyYW1Db3VudCA9IChcbiAgX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhpczogbnVtYmVyLFxuICBhdHRyaWJ1dGVzOiBTcGxpdEF0dHJpYnV0ZXMsXG4pOiBudW1iZXIgPT4ge1xuICBjb25zdCBbLCBvZmZzZXRzXSA9IFNwbGl0VXRpbC5zcGxpdFNoYXBlKGlucHV0c1swXS5kaW1zLCBheGlzLCBhdHRyaWJ1dGVzLnNwbGl0LCBhdHRyaWJ1dGVzLm51bU91dHB1dHMpO1xuICByZXR1cm4gb2Zmc2V0cy5sZW5ndGg7XG59O1xuXG5jb25zdCBjcmVhdGVTcGxpdFByb2dyYW1JbmZvID0gKFxuICBfaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBhdHRyaWJ1dGVzOiBTcGxpdEF0dHJpYnV0ZXMsXG4gIGF4aXM6IG51bWJlcixcbiAgaW5kZXg6IG51bWJlcixcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW3NoYXBlcywgb2Zmc2V0c10gPSBTcGxpdFV0aWwuc3BsaXRTaGFwZShpbnB1dC5kaW1zLCBheGlzLCBhdHRyaWJ1dGVzLnNwbGl0LCBhdHRyaWJ1dGVzLm51bU91dHB1dHMpO1xuICBjb25zdCBvZmZzZXQgPSBvZmZzZXRzW2luZGV4XTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBzaGFwZXNbaW5kZXhdO1xuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIGluZGljZXNbJHtheGlzfV0gKz0gJHtvZmZzZXR9O1xuICAgICAgICByZXR1cm4gX0EoaW5kaWNlcyk7XG4gICAgICB9XG4gICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zcGxpdFByb2dyYW1NZXRhZGF0YSxcbiAgICBjYWNoZUhpbnQ6IGAke2F0dHJpYnV0ZXMuY2FjaGVLZXl9OiR7aW5kZXh9YCxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU3BsaXQgcmVxdWlyZXMgb25lIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKFxuICAgIGlucHV0c1swXS50eXBlICE9PSAnaW50OCcgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ3VpbnQ4JyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAnaW50MTYnICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICd1aW50MTYnICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICdpbnQzMicgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ3VpbnQzMicgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0JyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAnYm9vbCdcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCBzcXVlZXplOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPG51bWJlcltdPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBheGVzOiBudW1iZXJbXSxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBTaGFwZVV0aWwuc3F1ZWV6ZVNoYXBlKGlucHV0c1swXS5kaW1zLCBheGVzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBvdXRwdXRTaGFwZSk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBzcXVlZXplVjEzID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHNWMTMoaW5wdXRzKTtcbiAgcmV0dXJuIHNxdWVlemUoaW5mZXJlbmNlSGFuZGxlciwgW2lucHV0c1swXV0sIEFycmF5LmZyb20oaW5wdXRzWzFdLmludGVnZXJEYXRhKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTcXVlZXplQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxudW1iZXJbXT4gPSAobm9kZTogR3JhcGguTm9kZSk6IG51bWJlcltdID0+XG4gIG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdheGVzJyk7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU3F1ZWV6ZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCB0ZW5zb3IgdHlwZXMuJyk7XG4gIH1cbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzVjEzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignU3F1ZWV6ZSByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgY29uc3Qgc3VtID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCBzdW1Qcm9ncmFtTWV0YWRhdGEgPSB7XG4gICAgbmFtZTogJ1N1bScsXG4gICAgaW5wdXROYW1lczogaW5wdXRzLm1hcCgoX3YsIGkpID0+IGBYJHtpfWApLFxuICAgIGlucHV0VHlwZXM6IG5ldyBBcnJheShpbnB1dHMubGVuZ3RoKS5maWxsKFRleHR1cmVUeXBlLnVucGFja2VkKSxcbiAgfTtcblxuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLnN1bVByb2dyYW1NZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVTdW1Qcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIHN1bVByb2dyYW1NZXRhZGF0YSkgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmNvbnN0IGNyZWF0ZVN1bVByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIHN1bVByb2dyYW1NZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3Qgc3VtTGluZSA9IGlucHV0cy5tYXAoKF92LCBpKSA9PiBgJHtnbHNsLnRleHR1cmUyRH0oWCR7aX0sVGV4Q29vcmRzKWApLmpvaW4oJyArICcpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgIHZlYzQgcmVzdWx0ID0gJHtzdW1MaW5lfTtcbiAgICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgICB9XG4gICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zdW1Qcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1N1bSByZXF1aXJlcyBpbnB1dHMuJyk7XG4gIH1cblxuICBjb25zdCBsZW5ndGggPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGxlbmd0aCAhPT0gaW5wdXRzW2ldLmRpbXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHNoYXBlcyBhcmUgbWlzbWF0Y2hlZC4nKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGxlbmd0aDsgaisrKSB7XG4gICAgICBpZiAoaW5wdXRzWzBdLmRpbXNbal0gIT09IGlucHV0c1tpXS5kaW1zW2pdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgc2hhcGVzIGFyZSBub3QgbWF0Y2hlZC4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09IGlucHV0c1tpXS50eXBlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHR5cGVzIGFyZSBub3QgbWF0Y2hlZC4nKTtcbiAgICB9XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IE5VTUJFUl9UWVBFUyB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCB0aWxlID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCB0aWxlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdUaWxlJyxcbiAgICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICB9O1xuXG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHsgLi4udGlsZVByb2dyYW1NZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVUaWxlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCB0aWxlUHJvZ3JhbU1ldGFkYXRhKSB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgY3JlYXRlVGlsZVByb2dyYW1JbmZvID0gKFxuICBfaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICB0aWxlUHJvZ3JhbU1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IG5ldyBBcnJheShpbnB1dFNoYXBlLmxlbmd0aCk7XG5cbiAgY29uc3QgdGlsZU9wczogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dFNoYXBlLmxlbmd0aDsgaSsrKSB7XG4gICAgb3V0cHV0U2hhcGVbaV0gPSBpbnB1dFNoYXBlW2ldICogaW5wdXRzWzFdLm51bWJlckRhdGFbaV07XG4gICAgdGlsZU9wcy5wdXNoKGBpbnB1dElkeFske2l9XSA9IGludChtb2QoZmxvYXQob3V0cHV0SWR4WyR7aX1dKSwgJHtpbnB1dFNoYXBlW2ldfS4pKTtgKTtcbiAgfVxuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IG91dHB1dElkeFske3Jhbmt9XSkge1xuICAgICAgICBpbnQgaW5wdXRJZHhbJHtyYW5rfV07XG4gICAgICAgICR7dGlsZU9wcy5qb2luKCdcXG4nKX1cbiAgICAgICAgcmV0dXJuIF9BKGlucHV0SWR4KTtcbiAgICAgIH1cbiAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLnRpbGVQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaWxlIHJlcXVpcmVzIDIgaW5wdXQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVGhlIHNlY29uZCBpbnB1dCBzaGFwZSBtdXN0IDEgZGltZW5zaW9uLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0uZGltc1swXSAhPT0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmIChOVU1CRVJfVFlQRVMuaW5kZXhPZihpbnB1dHNbMF0udHlwZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInICYmIGlucHV0c1sxXS50eXBlICE9PSAnaW50MTYnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHJlcGVhdCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3QgdW5zcXVlZXplOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPG51bWJlcltdPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBheGVzOiBudW1iZXJbXSxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBTaGFwZVV0aWwudW5zcXVlZXplU2hhcGUoaW5wdXRzWzBdLmRpbXMsIGF4ZXMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIG91dHB1dFNoYXBlKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHVuc3F1ZWV6ZVYxMyA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzVjEzKGlucHV0cyk7XG4gIHJldHVybiB1bnNxdWVlemUoaW5mZXJlbmNlSGFuZGxlciwgW2lucHV0c1swXV0sIEFycmF5LmZyb20oaW5wdXRzWzFdLmludGVnZXJEYXRhKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VVbnNxdWVlemVBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPG51bWJlcltdPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogbnVtYmVyW10gPT5cbiAgbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2F4ZXMnKTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnNxdWVlemUgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgdGVuc29yIHR5cGVzLicpO1xuICB9XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0c1YxMyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3F1ZWV6ZSByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBPcFNldCB9IGZyb20gJy4uLy4uL29wc2V0JztcblxuaW1wb3J0IHsgYmF0Y2hOb3JtYWxpemF0aW9uLCBwYXJzZUJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9iYXRjaC1ub3JtYWxpemF0aW9uJztcbmltcG9ydCAqIGFzIGJpbmFyeU9wcyBmcm9tICcuL29wcy9iaW5hcnktb3AnO1xuaW1wb3J0IHsgY2FzdCwgcGFyc2VDYXN0QXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2Nhc3QnO1xuaW1wb3J0IHsgY29uY2F0LCBwYXJzZUNvbmNhdEF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9jb25jYXQnO1xuaW1wb3J0IHsgY29udiwgcGFyc2VDb252QXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2NvbnYnO1xuaW1wb3J0IHsgY29udlRyYW5zcG9zZSwgcGFyc2VDb252VHJhbnNwb3NlQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2NvbnYtdHJhbnNwb3NlJztcbmltcG9ydCB7IGRlcHRoVG9TcGFjZSwgcGFyc2VEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvZGVwdGgtdG8tc3BhY2UnO1xuaW1wb3J0IHsgZmxhdHRlbiwgcGFyc2VGbGF0dGVuQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2ZsYXR0ZW4nO1xuaW1wb3J0IHsgZ2F0aGVyLCBwYXJzZUdhdGhlckF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9nYXRoZXInO1xuaW1wb3J0IHsgZ2VtbSwgcGFyc2VHZW1tQXR0cmlidXRlc1YxMSwgcGFyc2VHZW1tQXR0cmlidXRlc1Y3IH0gZnJvbSAnLi9vcHMvZ2VtbSc7XG5pbXBvcnQgeyBpbWFnZVNjYWxlciwgcGFyc2VJbWFnZVNjYWxlckF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9pbWFnZS1zY2FsZXInO1xuaW1wb3J0IHsgaW5zdGFuY2VOb3JtYWxpemF0aW9uLCBwYXJzZUluc3RhbmNlTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9pbnN0YW5jZS1ub3JtYWxpemF0aW9uJztcbmltcG9ydCB7IGxybiwgcGFyc2VMcm5BdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvbHJuJztcbmltcG9ydCB7IG1hdE11bCwgcGFyc2VNYXRNdWxBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvbWF0bXVsJztcbmltcG9ydCB7IHBhZFYxMSwgcGFkVjIsIHBhcnNlUGFkQXR0cmlidXRlc1YxMSwgcGFyc2VQYWRBdHRyaWJ1dGVzVjIgfSBmcm9tICcuL29wcy9wYWQnO1xuaW1wb3J0IHtcbiAgYXZlcmFnZVBvb2wsXG4gIGdsb2JhbEF2ZXJhZ2VQb29sLFxuICBnbG9iYWxNYXhQb29sLFxuICBtYXhQb29sLFxuICBwYXJzZUF2ZXJhZ2VQb29sQXR0cmlidXRlcyxcbiAgcGFyc2VHbG9iYWxBdmVyYWdlUG9vbEF0dHJpYnV0ZXMsXG4gIHBhcnNlTWF4UG9vbEF0dHJpYnV0ZXMsXG59IGZyb20gJy4vb3BzL3Bvb2wnO1xuaW1wb3J0IHtcbiAgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzLFxuICByZWR1Y2VMb2dTdW0sXG4gIHJlZHVjZUxvZ1N1bVNxdWFyZSxcbiAgcmVkdWNlTWF4LFxuICByZWR1Y2VNZWFuLFxuICByZWR1Y2VNaW4sXG4gIHJlZHVjZVByb2QsXG4gIHJlZHVjZVN1bSxcbn0gZnJvbSAnLi9vcHMvcmVkdWNlJztcbmltcG9ydCB7IHJlc2hhcGUgfSBmcm9tICcuL29wcy9yZXNoYXBlJztcbmltcG9ydCB7IHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMCwgcGFyc2VSZXNpemVBdHRyaWJ1dGVzVjExLCByZXNpemUgfSBmcm9tICcuL29wcy9yZXNpemUtcGFja2VkJztcbmltcG9ydCB7IHNoYXBlIH0gZnJvbSAnLi9vcHMvc2hhcGUnO1xuaW1wb3J0IHsgcGFyc2VTbGljZUF0dHJpYnV0ZXMsIHNsaWNlLCBzbGljZVYxMCB9IGZyb20gJy4vb3BzL3NsaWNlJztcbmltcG9ydCB7IHBhcnNlU29mdG1heEF0dHJpYnV0ZXMsIHBhcnNlU29mdG1heEF0dHJpYnV0ZXNWMTMsIHNvZnRtYXgsIHNvZnRtYXhWMTMgfSBmcm9tICcuL29wcy9zb2Z0bWF4JztcbmltcG9ydCB7IHBhcnNlU3BsaXRBdHRyaWJ1dGVzLCBzcGxpdCB9IGZyb20gJy4vb3BzL3NwbGl0JztcbmltcG9ydCB7IHBhcnNlU3F1ZWV6ZUF0dHJpYnV0ZXMsIHNxdWVlemUsIHNxdWVlemVWMTMgfSBmcm9tICcuL29wcy9zcXVlZXplJztcbmltcG9ydCB7IHN1bSB9IGZyb20gJy4vb3BzL3N1bSc7XG5pbXBvcnQgeyB0aWxlIH0gZnJvbSAnLi9vcHMvdGlsZSc7XG5pbXBvcnQgeyBwYXJzZVRyYW5zcG9zZUF0dHJpYnV0ZXMsIHRyYW5zcG9zZSB9IGZyb20gJy4vb3BzL3RyYW5zcG9zZSc7XG5pbXBvcnQgKiBhcyB1bmFyeU9wcyBmcm9tICcuL29wcy91bmFyeS1vcCc7XG5pbXBvcnQgeyBwYXJzZVVuc3F1ZWV6ZUF0dHJpYnV0ZXMsIHVuc3F1ZWV6ZSwgdW5zcXVlZXplVjEzIH0gZnJvbSAnLi9vcHMvdW5zcXVlZXplJztcbmltcG9ydCB7IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjcsIHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjksIHVwc2FtcGxlIH0gZnJvbSAnLi9vcHMvdXBzYW1wbGUnO1xuXG5leHBvcnQgY29uc3QgV0VCR0xfT1BfUkVTT0xWRV9SVUxFUzogcmVhZG9ubHkgT3BTZXQuUmVzb2x2ZVJ1bGVbXSA9IFtcbiAgWydBYnMnLCAnJywgJzYrJywgdW5hcnlPcHMuYWJzXSxcbiAgWydBY29zJywgJycsICc3KycsIHVuYXJ5T3BzLmFjb3NdLFxuICBbJ0FkZCcsICcnLCAnNysnLCBiaW5hcnlPcHMuYWRkXSxcbiAgWydBbmQnLCAnJywgJzcrJywgYmluYXJ5T3BzLmFuZF0sXG4gIFsnQXNpbicsICcnLCAnNysnLCB1bmFyeU9wcy5hc2luXSxcbiAgWydBdGFuJywgJycsICc3KycsIHVuYXJ5T3BzLmF0YW5dLFxuICAvLyBUT0RPOiBzdXBwb3J0IG5ldyBhdHRyaWJ1dGVzIGZvciBBdmVyYWdlUG9vbC0xMFxuICBbJ0F2ZXJhZ2VQb29sJywgJycsICc3KycsIGF2ZXJhZ2VQb29sLCBwYXJzZUF2ZXJhZ2VQb29sQXR0cmlidXRlc10sXG4gIFsnQmF0Y2hOb3JtYWxpemF0aW9uJywgJycsICc3KycsIGJhdGNoTm9ybWFsaXphdGlvbiwgcGFyc2VCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzXSxcbiAgWydDYXN0JywgJycsICc2KycsIGNhc3QsIHBhcnNlQ2FzdEF0dHJpYnV0ZXNdLFxuICBbJ0NlaWwnLCAnJywgJzYrJywgdW5hcnlPcHMuY2VpbF0sXG4gIFsnQ2xpcCcsICcnLCAnNi0xMCcsIHVuYXJ5T3BzLmNsaXAsIHVuYXJ5T3BzLnBhcnNlQ2xpcEF0dHJpYnV0ZXNdLFxuICBbJ0NsaXAnLCAnJywgJzExKycsIHVuYXJ5T3BzLmNsaXBWMTFdLFxuICBbJ0NvbmNhdCcsICcnLCAnNCsnLCBjb25jYXQsIHBhcnNlQ29uY2F0QXR0cmlidXRlc10sXG4gIFsnQ29udicsICcnLCAnMSsnLCBjb252LCBwYXJzZUNvbnZBdHRyaWJ1dGVzXSxcbiAgWydDb252VHJhbnNwb3NlJywgJycsICcxKycsIGNvbnZUcmFuc3Bvc2UsIHBhcnNlQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXNdLFxuICBbJ0NvcycsICcnLCAnNysnLCB1bmFyeU9wcy5jb3NdLFxuICBbJ0RpdicsICcnLCAnNysnLCBiaW5hcnlPcHMuZGl2XSxcbiAgWydEcm9wb3V0JywgJycsICc3KycsIHVuYXJ5T3BzLmlkZW50aXR5XSxcbiAgWydEZXB0aFRvU3BhY2UnLCAnJywgJzErJywgZGVwdGhUb1NwYWNlLCBwYXJzZURlcHRoVG9TcGFjZUF0dHJpYnV0ZXNdLFxuICBbJ0VxdWFsJywgJycsICc3KycsIGJpbmFyeU9wcy5lcXVhbF0sXG4gIFsnRWx1JywgJycsICc2KycsIHVuYXJ5T3BzLmVsdSwgdW5hcnlPcHMucGFyc2VFbHVBdHRyaWJ1dGVzXSxcbiAgWydFeHAnLCAnJywgJzYrJywgdW5hcnlPcHMuZXhwXSxcbiAgWydGbGF0dGVuJywgJycsICcxKycsIGZsYXR0ZW4sIHBhcnNlRmxhdHRlbkF0dHJpYnV0ZXNdLFxuICBbJ0Zsb29yJywgJycsICc2KycsIHVuYXJ5T3BzLmZsb29yXSxcbiAgWydGdXNlZENvbnYnLCAnY29tLm1pY3Jvc29mdCcsICcxKycsIGNvbnYsIHBhcnNlQ29udkF0dHJpYnV0ZXNdLFxuICBbJ0dhdGhlcicsICcnLCAnMSsnLCBnYXRoZXIsIHBhcnNlR2F0aGVyQXR0cmlidXRlc10sXG4gIFsnR2VtbScsICcnLCAnNy0xMCcsIGdlbW0sIHBhcnNlR2VtbUF0dHJpYnV0ZXNWN10sXG4gIFsnR2VtbScsICcnLCAnMTErJywgZ2VtbSwgcGFyc2VHZW1tQXR0cmlidXRlc1YxMV0sXG4gIFsnR2xvYmFsQXZlcmFnZVBvb2wnLCAnJywgJzErJywgZ2xvYmFsQXZlcmFnZVBvb2wsIHBhcnNlR2xvYmFsQXZlcmFnZVBvb2xBdHRyaWJ1dGVzXSxcbiAgWydHbG9iYWxNYXhQb29sJywgJycsICcxKycsIGdsb2JhbE1heFBvb2xdLFxuICBbJ0dyZWF0ZXInLCAnJywgJzcrJywgYmluYXJ5T3BzLmdyZWF0ZXJdLFxuICBbJ0lkZW50aXR5JywgJycsICcxKycsIHVuYXJ5T3BzLmlkZW50aXR5XSxcbiAgWydJbWFnZVNjYWxlcicsICcnLCAnMSsnLCBpbWFnZVNjYWxlciwgcGFyc2VJbWFnZVNjYWxlckF0dHJpYnV0ZXNdLFxuICBbJ0luc3RhbmNlTm9ybWFsaXphdGlvbicsICcnLCAnNisnLCBpbnN0YW5jZU5vcm1hbGl6YXRpb24sIHBhcnNlSW5zdGFuY2VOb3JtYWxpemF0aW9uQXR0cmlidXRlc10sXG4gIFsnTGVha3lSZWx1JywgJycsICc2KycsIHVuYXJ5T3BzLmxlYWt5UmVsdSwgdW5hcnlPcHMucGFyc2VMZWFreVJlbHVBdHRyaWJ1dGVzXSxcbiAgWydMZXNzJywgJycsICc3KycsIGJpbmFyeU9wcy5sZXNzXSxcbiAgWydMUk4nLCAnJywgJzErJywgbHJuLCBwYXJzZUxybkF0dHJpYnV0ZXNdLFxuICBbJ0xvZycsICcnLCAnNisnLCB1bmFyeU9wcy5sb2ddLFxuICBbJ01hdE11bCcsICcnLCAnMSsnLCBtYXRNdWwsIHBhcnNlTWF0TXVsQXR0cmlidXRlc10sXG4gIC8vIFRPRE86IHN1cHBvcnQgbmV3IGF0dHJpYnV0ZXMgZm9yIE1heFBvb2wtOCBhbmQgTWF4UG9vbC0xMFxuICBbJ01heFBvb2wnLCAnJywgJzErJywgbWF4UG9vbCwgcGFyc2VNYXhQb29sQXR0cmlidXRlc10sXG4gIFsnTXVsJywgJycsICc3KycsIGJpbmFyeU9wcy5tdWxdLFxuICBbJ05lZycsICcnLCAnNisnLCB1bmFyeU9wcy5uZWddLFxuICBbJ05vdCcsICcnLCAnMSsnLCB1bmFyeU9wcy5ub3RdLFxuICBbJ09yJywgJycsICc3KycsIGJpbmFyeU9wcy5vcl0sXG4gIFsnUGFkJywgJycsICcyLTEwJywgcGFkVjIsIHBhcnNlUGFkQXR0cmlidXRlc1YyXSxcbiAgWydQYWQnLCAnJywgJzExKycsIHBhZFYxMSwgcGFyc2VQYWRBdHRyaWJ1dGVzVjExXSxcbiAgWydQb3cnLCAnJywgJzcrJywgYmluYXJ5T3BzLnBvd10sXG4gIFsnUFJlbHUnLCAnJywgJzcrJywgYmluYXJ5T3BzLnBSZWx1XSxcbiAgWydSZWR1Y2VMb2dTdW0nLCAnJywgJzErJywgcmVkdWNlTG9nU3VtLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZU1heCcsICcnLCAnMSsnLCByZWR1Y2VNYXgsIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlTWVhbicsICcnLCAnMSsnLCByZWR1Y2VNZWFuLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZU1pbicsICcnLCAnMSsnLCByZWR1Y2VNaW4sIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlUHJvZCcsICcnLCAnMSsnLCByZWR1Y2VQcm9kLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZVN1bScsICcnLCAnMS0xMicsIHJlZHVjZVN1bSwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VTdW1TcXVhcmUnLCAnJywgJzErJywgcmVkdWNlTG9nU3VtU3F1YXJlLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlbHUnLCAnJywgJzYrJywgdW5hcnlPcHMucmVsdV0sXG4gIFsnUmVzaGFwZScsICcnLCAnNSsnLCByZXNoYXBlXSxcbiAgWydSZXNpemUnLCAnJywgJzEwJywgcmVzaXplLCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTBdLFxuICBbJ1Jlc2l6ZScsICcnLCAnMTErJywgcmVzaXplLCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTFdLFxuICBbJ1NoYXBlJywgJycsICcxKycsIHNoYXBlXSxcbiAgWydTaWdtb2lkJywgJycsICc2KycsIHVuYXJ5T3BzLnNpZ21vaWRdLFxuICBbJ1NpbicsICcnLCAnNysnLCB1bmFyeU9wcy5zaW5dLFxuICBbJ1NsaWNlJywgJycsICcxMCsnLCBzbGljZVYxMF0sIC8vIFRPRE86IHN1cHBvcnQgJ3N0ZXBzJyBmb3IgU2xpY2UtMTBcbiAgWydTbGljZScsICcnLCAnMS05Jywgc2xpY2UsIHBhcnNlU2xpY2VBdHRyaWJ1dGVzXSxcbiAgLy8gVGhlIFwic2VtYW50aWNcIiBtZWFuaW5nIG9mIGF4aXMgaGFzIGNoYW5nZWQgaW4gb3BzZXQtMTMuXG4gIFsnU29mdG1heCcsICcnLCAnMS0xMicsIHNvZnRtYXgsIHBhcnNlU29mdG1heEF0dHJpYnV0ZXNdLFxuICBbJ1NvZnRtYXgnLCAnJywgJzEzKycsIHNvZnRtYXhWMTMsIHBhcnNlU29mdG1heEF0dHJpYnV0ZXNWMTNdLFxuICAvLyAnU3BsaXQnIG9wZXJhdG9yIGhhcyBhbiBvcHRpb25hbCBhdHRyaWJ1dGUgJ3NwbGl0J1xuICAvLyB0aGlzIGF0dHJpYnV0ZSBkZXRlcm1pbmVzIGhvdyB0aGUgc3BlY2lmaWVkIGF4aXMgb2YgaW5wdXQgZGF0YSBpcyBzcGxpdC5cbiAgLy8gV2hlbiB0aGUgYXR0cmlidXRlIGlzIG1pc3NpbmcsIHdlIG5lZWQgdGhlIGNvdW50IG9mIG51bWJlciBvZiBvdXRwdXRzXG4gIC8vIHNvIHRoYXQgd2UgY2FuIGRldGVybWluZSB0aGUgJ3NwbGl0JyBhdHRyaWJ1dGUgZnJvbSB0aGUgcnVudGltZSBpbnB1dCB0byB0aGUgT3BlcmF0b3JcbiAgWydTcGxpdCcsICcnLCAnMi0xMicsIHNwbGl0LCBwYXJzZVNwbGl0QXR0cmlidXRlc10sXG4gIFsnU3FydCcsICcnLCAnNisnLCB1bmFyeU9wcy5zcXJ0XSxcbiAgWydTcXVlZXplJywgJycsICcxLTEyJywgc3F1ZWV6ZSwgcGFyc2VTcXVlZXplQXR0cmlidXRlc10sXG4gIFsnU3F1ZWV6ZScsICcnLCAnMTMrJywgc3F1ZWV6ZVYxM10sXG4gIFsnU3ViJywgJycsICc3KycsIGJpbmFyeU9wcy5zdWJdLFxuICBbJ1N1bScsICcnLCAnNisnLCBzdW1dLFxuICBbJ1RhbicsICcnLCAnNysnLCB1bmFyeU9wcy50YW5dLFxuICBbJ1RhbmgnLCAnJywgJzYrJywgdW5hcnlPcHMudGFuaF0sXG4gIFsnVGlsZScsICcnLCAnNisnLCB0aWxlXSxcbiAgWydUcmFuc3Bvc2UnLCAnJywgJzErJywgdHJhbnNwb3NlLCBwYXJzZVRyYW5zcG9zZUF0dHJpYnV0ZXNdLFxuICBbJ1Vwc2FtcGxlJywgJycsICc3LTgnLCB1cHNhbXBsZSwgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWN10sXG4gIFsnVXBzYW1wbGUnLCAnJywgJzknLCB1cHNhbXBsZSwgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWOV0sXG4gIFsnVW5zcXVlZXplJywgJycsICcxLTEyJywgdW5zcXVlZXplLCBwYXJzZVVuc3F1ZWV6ZUF0dHJpYnV0ZXNdLFxuICBbJ1Vuc3F1ZWV6ZScsICcnLCAnMTMrJywgdW5zcXVlZXplVjEzXSxcbiAgWydYb3InLCAnJywgJzcrJywgYmluYXJ5T3BzLnhvcl0sXG5dO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5jb25zdCBJTkxJTkVfRlVOQ19ERUZfUkVHRVggPSAvQGlubGluZVtcXHNcXG5cXHJdKyhcXHcrKVtcXHNcXG5cXHJdKyhbMC05YS16QS1aX10rKVxccypcXCgoW14pXSopXFwpXFxzKnsoKFtefV18W1xcblxccl0pKil9L2dtO1xuY29uc3QgRlVOQ19DQUxMX1JFR0VYID0gJyhcXFxcdyspP1xcXFxzKyhbXzAtOWEtekEtWl0rKVxcXFxzKz1cXFxccytfX0ZVTkNfX1xcXFwoKC4qKVxcXFwpXFxcXHMqOyc7XG4vKipcbiAqIEdMU0wgcHJlcHJvY2Vzc29yIHJlc3BvbnNpYmxlIGZvciByZXNvbHZpbmcgQGlubGluZSBkaXJlY3RpdmVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXBsYWNlSW5saW5lcyhzY3JpcHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGlubGluZURlZnM6IHsgW25hbWU6IHN0cmluZ106IHsgcGFyYW1zOiBBcnJheTx7IHR5cGU6IHN0cmluZzsgbmFtZTogc3RyaW5nIH0gfCBudWxsPjsgYm9keTogc3RyaW5nIH0gfSA9IHt9O1xuICBsZXQgbWF0Y2g7XG4gIHdoaWxlICgobWF0Y2ggPSBJTkxJTkVfRlVOQ19ERUZfUkVHRVguZXhlYyhzY3JpcHQpKSAhPT0gbnVsbCkge1xuICAgIGNvbnN0IHBhcmFtcyA9IG1hdGNoWzNdXG4gICAgICAuc3BsaXQoJywnKVxuICAgICAgLm1hcCgocykgPT4ge1xuICAgICAgICBjb25zdCB0b2tlbnMgPSBzLnRyaW0oKS5zcGxpdCgnICcpO1xuICAgICAgICBpZiAodG9rZW5zICYmIHRva2Vucy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICByZXR1cm4geyB0eXBlOiB0b2tlbnNbMF0sIG5hbWU6IHRva2Vuc1sxXSB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKHYpID0+IHYgIT09IG51bGwpO1xuICAgIGlubGluZURlZnNbbWF0Y2hbMl1dID0geyBwYXJhbXMsIGJvZHk6IG1hdGNoWzRdIH07XG4gIH1cbiAgZm9yIChjb25zdCBuYW1lIGluIGlubGluZURlZnMpIHtcbiAgICBjb25zdCByZWdleFN0cmluZyA9IEZVTkNfQ0FMTF9SRUdFWC5yZXBsYWNlKCdfX0ZVTkNfXycsIG5hbWUpO1xuICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChyZWdleFN0cmluZywgJ2dtJyk7XG4gICAgd2hpbGUgKChtYXRjaCA9IHJlZ2V4LmV4ZWMoc2NyaXB0KSkgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IHR5cGUgPSBtYXRjaFsxXTtcbiAgICAgIGNvbnN0IHZhcmlhYmxlID0gbWF0Y2hbMl07XG4gICAgICBjb25zdCBwYXJhbXMgPSBtYXRjaFszXS5zcGxpdCgnLCcpO1xuICAgICAgY29uc3QgZGVjbExpbmUgPSB0eXBlID8gYCR7dHlwZX0gJHt2YXJpYWJsZX07YCA6ICcnO1xuICAgICAgbGV0IG5ld0JvZHk6IHN0cmluZyA9IGlubGluZURlZnNbbmFtZV0uYm9keTtcbiAgICAgIGxldCBwYXJhbVJlZGVjTGluZSA9ICcnO1xuICAgICAgaW5saW5lRGVmc1tuYW1lXS5wYXJhbXMuZm9yRWFjaCgodiwgaSkgPT4ge1xuICAgICAgICBpZiAodikge1xuICAgICAgICAgIHBhcmFtUmVkZWNMaW5lICs9IGAke3YudHlwZX0gJHt2Lm5hbWV9ID0gJHtwYXJhbXNbaV19O1xcbmA7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgbmV3Qm9keSA9IGAke3BhcmFtUmVkZWNMaW5lfVxcbiAke25ld0JvZHl9YDtcbiAgICAgIG5ld0JvZHkgPSBuZXdCb2R5LnJlcGxhY2UoJ3JldHVybicsIGAke3ZhcmlhYmxlfSA9IGApO1xuICAgICAgY29uc3QgcmVwbGFjZW1lbnQgPSBgXG4gICAgICAke2RlY2xMaW5lfVxuICAgICAge1xuICAgICAgICAke25ld0JvZHl9XG4gICAgICB9XG4gICAgICBgO1xuICAgICAgc2NyaXB0ID0gc2NyaXB0LnJlcGxhY2UobWF0Y2hbMF0sIHJlcGxhY2VtZW50KTtcbiAgICB9XG4gIH1cbiAgc2NyaXB0ID0gc2NyaXB0LnJlcGxhY2UoSU5MSU5FX0ZVTkNfREVGX1JFR0VYLCAnJyk7XG4gIHJldHVybiBzY3JpcHQ7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4uLy4uL2luc3RydW1lbnQnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbi8qKiBMYXlvdXQgcHJlZmVyZW5jZXMgKi9cbmV4cG9ydCBpbnRlcmZhY2UgV2lkdGhIZWlnaHRQcmVmcyB7XG4gIGJyZWFrQXhpcz86IG51bWJlcjtcbiAgaXNQYWNrZWQ/OiBib29sZWFuO1xuICByZXZlcnNlV0g/OiBib29sZWFuO1xufVxuLyoqXG4gKiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kgaXMgYW4gYWJzdHJhY3Rpb24gZm9yIGRpZmZlcmVudCBwbGFuc1xuICogZm9yIG1hcHBpbmcgbi1kaW1lbnNpb25hbCBhcnJheXMgdG8gMkQgdGV4dHVyZXMgKGFuZCBiYWNrKVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRleHR1cmVMYXlvdXRTdHJhdGVneSB7XG4gIGNvbXB1dGVUZXh0dXJlV0goc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMpOiBbbnVtYmVyLCBudW1iZXJdO1xufVxuXG4vKipcbiAqIFRoaXMgc3RyYXRlZ3kgdHJ5IHRvIGZpbmQgdGhlIG1pbmltYWwgbWF4KFcsSCkgdGhhdCBmdWxmaWxscyAoVyAqIEggPT0gdG90YWxTaXplKVxuICovXG5leHBvcnQgY2xhc3MgQWx3YXlzS2VlcE9yaWdpbmFsU2l6ZVN0cmF0ZWd5IGltcGxlbWVudHMgVGV4dHVyZUxheW91dFN0cmF0ZWd5IHtcbiAgY29uc3RydWN0b3IocHVibGljIG1heFRleHR1cmVTaXplOiBudW1iZXIpIHt9XG4gIGNvbXB1dGVUZXh0dXJlV0goc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICAvLyBzY2FsYXIgdGVuc29yXG4gICAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFsxLCAxXTtcbiAgICB9XG4gICAgY29uc3QgbWF4VGV4dHVyZVNpemUgPSB0aGlzLm1heFRleHR1cmVTaXplO1xuICAgIGlmIChwcmVmcyAmJiBwcmVmcy5icmVha0F4aXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gY2hlY2sgdG8gc2VlIGlmIGRpbXMgZml0XG4gICAgICBjb25zdCB3c2l6ZSA9IHByZWZzLmJyZWFrQXhpcyA+PSBzaGFwZS5sZW5ndGggPyAxIDogc2hhcGUuc2xpY2UocHJlZnMuYnJlYWtBeGlzKS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcbiAgICAgIGNvbnN0IGhzaXplID0gcHJlZnMuYnJlYWtBeGlzIDw9IDAgPyAxIDogc2hhcGUuc2xpY2UoMCwgcHJlZnMuYnJlYWtBeGlzKS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcbiAgICAgIGlmICh3c2l6ZSA+IG1heFRleHR1cmVTaXplIHx8IGhzaXplID4gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgICAgLy8gaWdub3JlIHByZWZlcmVuY2VzXG4gICAgICAgIC8vIGNvbnRpbnVlIHdpdGggZGVmYXVsdCBsYXlvdXRcbiAgICAgICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICAgJ1RleHR1cmVMYXlvdXQnLFxuICAgICAgICAgIGBHaXZlbiB3aWR0aC9oZWlnaHQgcHJlZmVyZW5jZXMgd2VyZSB1bmF0dGFpbmFibGU6IHNoYXBlOiR7c2hhcGV9LCBicmVha0F4aXM6JHtwcmVmcy5icmVha0F4aXN9YCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbd3NpemUsIGhzaXplXTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgdG90YWxTaXplID0gc2hhcGUucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG5cbiAgICBsZXQgd2lkdGggPSBNYXRoLmZsb29yKE1hdGguc3FydCh0b3RhbFNpemUpKTtcblxuICAgIGZvciAoOyB3aWR0aCA8IG1heFRleHR1cmVTaXplICYmIHdpZHRoIDwgdG90YWxTaXplOyB3aWR0aCsrKSB7XG4gICAgICBpZiAodG90YWxTaXplICUgd2lkdGggPT09IDApIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdpZHRoID49IG1heFRleHR1cmVTaXplIHx8IHRvdGFsU2l6ZSAlIHdpZHRoICE9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBnaXZlbiBkaW1lbnNpb25zIGFyZSBvdXRzaWRlIHRoaXMgR1BVJ3MgYm91bmRhcmllczogJHtzaGFwZX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIFt3aWR0aCwgdG90YWxTaXplIC8gd2lkdGhdO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQcmVmZXJMb2dpY2FsU3RyYXRlZ3kgaW1wbGVtZW50cyBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgbWF4VGV4dHVyZVNpemU6IG51bWJlcikge31cbiAgY29tcHV0ZVRleHR1cmVXSChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHByZWZzPzogV2lkdGhIZWlnaHRQcmVmcyk6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGNvbnN0IHdoID0gdGhpcy5jb21wdXRlVGV4dHVyZShzaGFwZSwgcHJlZnMpO1xuICAgIGlmIChwcmVmcyAmJiBwcmVmcy5pc1BhY2tlZCkge1xuICAgICAgd2hbMF0gLz0gMjtcbiAgICAgIHdoWzFdIC89IDI7XG4gICAgfVxuICAgIGlmIChwcmVmcyAmJiBwcmVmcy5yZXZlcnNlV0gpIHtcbiAgICAgIHJldHVybiBbd2hbMV0sIHdoWzBdXTtcbiAgICB9XG4gICAgcmV0dXJuIHdoO1xuICB9XG5cbiAgY29tcHV0ZVRleHR1cmUoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICBjb25zdCBpc1BhY2tlZCA9IHByZWZzICYmIHByZWZzLmlzUGFja2VkO1xuICAgIC8vIHNjYWxhciB0ZW5zb3JcbiAgICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gaXNQYWNrZWQgPyBbMiwgMl0gOiBbMSwgMV07XG4gICAgfVxuICAgIGxldCBtYXhUZXh0dXJlU2l6ZSA9IHRoaXMubWF4VGV4dHVyZVNpemU7XG4gICAgaWYgKHByZWZzICYmIHByZWZzLmJyZWFrQXhpcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBjaGVjayB0byBzZWUgaWYgZGltcyBmaXRcbiAgICAgIGNvbnN0IHdzaXplID0gcHJlZnMuYnJlYWtBeGlzID49IHNoYXBlLmxlbmd0aCA/IDEgOiBzaGFwZS5zbGljZShwcmVmcy5icmVha0F4aXMpLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuICAgICAgY29uc3QgaHNpemUgPSBwcmVmcy5icmVha0F4aXMgPD0gMCA/IDEgOiBzaGFwZS5zbGljZSgwLCBwcmVmcy5icmVha0F4aXMpLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuICAgICAgaWYgKHdzaXplID4gbWF4VGV4dHVyZVNpemUgfHwgaHNpemUgPiBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgICAvLyBpZ25vcmUgcHJlZmVyZW5jZXNcbiAgICAgICAgLy8gY29udGludWUgd2l0aCBkZWZhdWx0IGxheW91dFxuICAgICAgICBMb2dnZXIudmVyYm9zZShcbiAgICAgICAgICAnVGV4dHVyZUxheW91dCcsXG4gICAgICAgICAgYEdpdmVuIHdpZHRoL2hlaWdodCBwcmVmZXJlbmNlcyB3ZXJlIHVuYXR0YWluYWJsZTogc2hhcGU6JHtzaGFwZX0sIGJyZWFrQXhpczoke3ByZWZzLmJyZWFrQXhpc31gLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFt3c2l6ZSwgaHNpemVdO1xuICAgICAgfVxuICAgIH1cbiAgICBsZXQgbG9nU2hhcGUgPSBzaGFwZS5zbGljZSgwKTtcbiAgICBpZiAoaXNQYWNrZWQpIHtcbiAgICAgIG1heFRleHR1cmVTaXplID0gbWF4VGV4dHVyZVNpemUgKiAyO1xuXG4gICAgICAvLyBUaGlzIGxvZ2ljIGVuc3VyZXMgd2UgYWNjdXJhdGVseSBjb3VudCB0aGUgbnVtYmVyIG9mIHBhY2tlZCB0ZXhlbHMgbmVlZGVkXG4gICAgICAvLyB0byBhY2NvbW1vZGF0ZSB0aGUgdGVuc29yLiBXZSBjYW4gb25seSBwYWNrIHZhbHVlcyBpbiB0aGUgc2FtZSB0ZXhlbCBpZlxuICAgICAgLy8gdGhleSBhcmUgZnJvbSBhZGphY2VudCBwYWlycyBvZiByb3dzL2NvbHMgd2l0aGluIHRoZSBzYW1lIGJhdGNoLiBTbyBpZiBhXG4gICAgICAvLyB0ZW5zb3IgaGFzIDMgcm93cywgd2UgcHJldGVuZCBpdCBoYXMgNCByb3dzIGluIG9yZGVyIHRvIGFjY291bnQgZm9yIHRoZVxuICAgICAgLy8gZmFjdCB0aGF0IHRoZSB0ZXhlbHMgY29udGFpbmluZyB0aGUgdGhpcmQgcm93IGFyZSBoYWxmIGVtcHR5LlxuICAgICAgbG9nU2hhcGUgPSBsb2dTaGFwZS5tYXAoKF9kLCBpKSA9PlxuICAgICAgICBpID49IGxvZ1NoYXBlLmxlbmd0aCAtIDIgPyAobG9nU2hhcGVbaV0gJSAyID09PSAwID8gbG9nU2hhcGVbaV0gOiBsb2dTaGFwZVtpXSArIDEpIDogbG9nU2hhcGVbaV0sXG4gICAgICApO1xuXG4gICAgICAvLyBQYWNrZWQgdGV4dHVyZSBoZWlnaHQgaXMgYXQgbGVhc3QgMiAodGhlIGNoYW5uZWwgaGVpZ2h0IG9mIGEgc2luZ2xlXG4gICAgICAvLyB0ZXhlbCkuXG4gICAgICBpZiAobG9nU2hhcGUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGxvZ1NoYXBlID0gWzIsIGxvZ1NoYXBlWzBdXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiBsb2dpY2FsIHNoYXBlIGlzIDIsIHdlIGRvbid0IHNxdWVlemUsIHNpbmNlIHdlIHdhbnQgdG8gbWF0Y2ggcGh5c2ljYWwuXG4gICAgaWYgKGxvZ1NoYXBlLmxlbmd0aCAhPT0gMikge1xuICAgICAgY29uc3Qgc3F1ZWV6ZVJlc3VsdCA9IHNxdWVlemVTaGFwZShsb2dTaGFwZSk7XG4gICAgICBsb2dTaGFwZSA9IHNxdWVlemVSZXN1bHQubmV3U2hhcGU7XG4gICAgfVxuXG4gICAgY29uc3Qgc2l6ZSA9IHNpemVGcm9tU2hhcGUobG9nU2hhcGUpO1xuICAgIGlmIChsb2dTaGFwZS5sZW5ndGggPD0gMSAmJiBzaXplIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gWzEsIHNpemVdO1xuICAgIH0gZWxzZSBpZiAobG9nU2hhcGUubGVuZ3RoID09PSAyICYmIGxvZ1NoYXBlWzBdIDw9IG1heFRleHR1cmVTaXplICYmIGxvZ1NoYXBlWzFdIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gbG9nU2hhcGUgYXMgW251bWJlciwgbnVtYmVyXTtcbiAgICB9IGVsc2UgaWYgKGxvZ1NoYXBlLmxlbmd0aCA9PT0gMyAmJiBsb2dTaGFwZVswXSAqIGxvZ1NoYXBlWzFdIDw9IG1heFRleHR1cmVTaXplICYmIGxvZ1NoYXBlWzJdIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gW2xvZ1NoYXBlWzBdICogbG9nU2hhcGVbMV0sIGxvZ1NoYXBlWzJdXTtcbiAgICB9IGVsc2UgaWYgKGxvZ1NoYXBlLmxlbmd0aCA9PT0gMyAmJiBsb2dTaGFwZVswXSA8PSBtYXhUZXh0dXJlU2l6ZSAmJiBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gW2xvZ1NoYXBlWzBdLCBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdXTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgbG9nU2hhcGUubGVuZ3RoID09PSA0ICYmXG4gICAgICBsb2dTaGFwZVswXSAqIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl0gPD0gbWF4VGV4dHVyZVNpemUgJiZcbiAgICAgIGxvZ1NoYXBlWzNdIDw9IG1heFRleHR1cmVTaXplXG4gICAgKSB7XG4gICAgICByZXR1cm4gW2xvZ1NoYXBlWzBdICogbG9nU2hhcGVbMV0gKiBsb2dTaGFwZVsyXSwgbG9nU2hhcGVbM11dO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBsb2dTaGFwZS5sZW5ndGggPT09IDQgJiZcbiAgICAgIGxvZ1NoYXBlWzBdIDw9IG1heFRleHR1cmVTaXplICYmXG4gICAgICBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdICogbG9nU2hhcGVbM10gPD0gbWF4VGV4dHVyZVNpemVcbiAgICApIHtcbiAgICAgIHJldHVybiBbbG9nU2hhcGVbMF0sIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl0gKiBsb2dTaGFwZVszXV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpc1BhY2tlZCkge1xuICAgICAgICAvLyBGb3IgcGFja2VkIHRleHR1cmVzIHNpemUgZXF1YWxzIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMgcmVxdWlyZWQgdG9cbiAgICAgICAgLy8gYWNjb21tb2RhdGUgdGhlIHRleHR1cmUgZGF0YS4gSG93ZXZlciBpbiBvcmRlciB0byBzcXVhcmlmeSBzdWNoIHRoYXRcbiAgICAgICAgLy8gaW5uZXIgZGltZW5zaW9ucyBzdGF5IGV2ZW4sIHdlIHJld3JpdGUgc2l6ZSB0byBlcXVhbCB0aGUgbnVtYmVyIG9mXG4gICAgICAgIC8vIHRleGVscy4gVGhlbiBpbiB0aGUgcmV0dXJuIHN0YXRlbWVudCB3ZSByZWh5ZHJhdGUgdGhlIHNxdWFyaWZpZWRcbiAgICAgICAgLy8gZGltZW5zaW9ucyB0byBjaGFubmVsIHVuaXRzLlxuICAgICAgICByZXR1cm4gc2l6ZVRvU3F1YXJpc2hTaGFwZShzaXplIC8gNCkubWFwKChkKSA9PiBkICogMikgYXMgW251bWJlciwgbnVtYmVyXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzaXplVG9TcXVhcmlzaFNoYXBlKHNpemUpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc3F1ZWV6ZVNoYXBlKHNoYXBlOiBudW1iZXJbXSwgYXhpcz86IG51bWJlcltdKTogeyBuZXdTaGFwZTogbnVtYmVyW107IGtlcHREaW1zOiBudW1iZXJbXSB9IHtcbiAgY29uc3QgbmV3U2hhcGU6IG51bWJlcltdID0gW107XG4gIGNvbnN0IGtlcHREaW1zOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBpc0VtcHR5QXJyYXkgPSBheGlzICE9IG51bGwgJiYgQXJyYXkuaXNBcnJheShheGlzKSAmJiBheGlzLmxlbmd0aCA9PT0gMDtcbiAgY29uc3QgYXhlcyA9IGF4aXMgPT0gbnVsbCB8fCBpc0VtcHR5QXJyYXkgPyBudWxsIDogcGFyc2VBeGlzUGFyYW0oYXhpcywgc2hhcGUpLnNvcnQoKTtcbiAgbGV0IGogPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNoYXBlLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGF4ZXMgIT0gbnVsbCkge1xuICAgICAgaWYgKGF4ZXNbal0gPT09IGkgJiYgc2hhcGVbaV0gIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW4ndCBzcXVlZXplIGF4aXMgJHtpfSBzaW5jZSBpdHMgZGltICcke3NoYXBlW2ldfScgaXMgbm90IDFgKTtcbiAgICAgIH1cbiAgICAgIGlmICgoYXhlc1tqXSA9PSBudWxsIHx8IGF4ZXNbal0gPiBpKSAmJiBzaGFwZVtpXSA9PT0gMSkge1xuICAgICAgICBuZXdTaGFwZS5wdXNoKHNoYXBlW2ldKTtcbiAgICAgICAga2VwdERpbXMucHVzaChpKTtcbiAgICAgIH1cbiAgICAgIGlmIChheGVzW2pdIDw9IGkpIHtcbiAgICAgICAgaisrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc2hhcGVbaV0gIT09IDEpIHtcbiAgICAgIG5ld1NoYXBlLnB1c2goc2hhcGVbaV0pO1xuICAgICAga2VwdERpbXMucHVzaChpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHsgbmV3U2hhcGUsIGtlcHREaW1zIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUF4aXNQYXJhbShheGlzOiBudW1iZXIgfCBudW1iZXJbXSwgc2hhcGU6IG51bWJlcltdKTogbnVtYmVyW10ge1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gIC8vIE5vcm1hbGl6ZSBpbnB1dFxuICBheGlzID0gYXhpcyA9PSBudWxsID8gc2hhcGUubWFwKChfcywgaSkgPT4gaSkgOiAoW10gYXMgbnVtYmVyW10pLmNvbmNhdChheGlzKTtcblxuICAvLyBDaGVjayBmb3IgdmFsaWQgcmFuZ2VcbiAgYXNzZXJ0KFxuICAgIGF4aXMuZXZlcnkoKGF4KSA9PiBheCA+PSAtcmFuayAmJiBheCA8IHJhbmspLFxuICAgICgpID0+IGBBbGwgdmFsdWVzIGluIGF4aXMgcGFyYW0gbXVzdCBiZSBpbiByYW5nZSBbLSR7cmFua30sICR7cmFua30pIGJ1dCBgICsgYGdvdCBheGlzICR7YXhpc31gLFxuICApO1xuXG4gIC8vIENoZWNrIGZvciBvbmx5IGludGVnZXJzXG4gIGFzc2VydChheGlzLmV2ZXJ5KGlzSW50KSwgKCkgPT4gJ0FsbCB2YWx1ZXMgaW4gYXhpcyBwYXJhbSBtdXN0IGJlIGludGVnZXJzIGJ1dCAnICsgYGdvdCBheGlzICR7YXhpc31gKTtcblxuICAvLyBIYW5kbGUgbmVnYXRpdmUgYXhpcy5cbiAgcmV0dXJuIGF4aXMubWFwKChhKSA9PiAoYSA8IDAgPyByYW5rICsgYSA6IGEpKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBpc0ludChhOiBudW1iZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIGEgJSAxID09PSAwO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHNpemVGcm9tU2hhcGUoc2hhcGU6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIFNjYWxhci5cbiAgICByZXR1cm4gMTtcbiAgfVxuICBsZXQgc2l6ZSA9IHNoYXBlWzBdO1xuICBmb3IgKGxldCBpID0gMTsgaSA8IHNoYXBlLmxlbmd0aDsgaSsrKSB7XG4gICAgc2l6ZSAqPSBzaGFwZVtpXTtcbiAgfVxuICByZXR1cm4gc2l6ZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRSb3dzQ29scyhzaGFwZTogbnVtYmVyW10pOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IEVycm9yKCdDYW5ub3QgZ2V0IHJvd3MgYW5kIGNvbHVtbnMgb2YgYW4gZW1wdHkgc2hhcGUgYXJyYXkuJyk7XG4gIH1cblxuICByZXR1cm4gW3NoYXBlLmxlbmd0aCA+IDEgPyBzaGFwZVtzaGFwZS5sZW5ndGggLSAyXSA6IDEsIHNoYXBlW3NoYXBlLmxlbmd0aCAtIDFdXTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzaXplVG9TcXVhcmlzaFNoYXBlKHNpemU6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl0ge1xuICBjb25zdCB3aWR0aCA9IE1hdGguY2VpbChNYXRoLnNxcnQoc2l6ZSkpO1xuICByZXR1cm4gW3dpZHRoLCBNYXRoLmNlaWwoc2l6ZSAvIHdpZHRoKV07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0QmF0Y2hEaW0oc2hhcGU6IG51bWJlcltdLCBkaW1zVG9Ta2lwID0gMik6IG51bWJlciB7XG4gIHJldHVybiBzaXplRnJvbVNoYXBlKHNoYXBlLnNsaWNlKDAsIHNoYXBlLmxlbmd0aCAtIGRpbXNUb1NraXApKTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXJyYXlVdGlsLCBCcm9hZGNhc3RVdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcblxuaW1wb3J0IHsgR2xzbENvbnRleHQsIEdsc2xMaWIsIEdsc2xMaWJSb3V0aW5lIH0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuL2dsc2wtc291cmNlJztcbmltcG9ydCB7IHNxdWVlemVTaGFwZSB9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgVGV4dHVyZUxheW91dCB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHtcbiAgZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lLFxuICBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWVBdE91dENvb3JkcyxcbiAgZ2V0Q29vcmRzRGF0YVR5cGUsXG4gIGdldEdsQ2hhbm5lbHMsXG4gIGdldFNxdWVlemVkUGFyYW1zLFxuICBzcXVlZXplSW5wdXRTaGFwZSxcbn0gZnJvbSAnLi91dGlscyc7XG5cbi8qKlxuICogR0xTTCBMaWJyYXJ5IHJlc3BvbnNpYmxlIGZvciBkYXRhIHR5cGVzIGFuZCByb3V0aW5lcyBmb3IgbWFuaXB1bGF0aW5nXG4gKiBjb29yZGluYXRlcyBhbmQgbWFwcGluZyB0by9mcm9tIHRlbnNvciBpbmRpY2VzXG4gKi9cbmV4cG9ydCBjbGFzcyBDb29yZHNHbHNsTGliIGV4dGVuZHMgR2xzbExpYiB7XG4gIHJldHVyblR5cGU6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBHbHNsQ29udGV4dCkge1xuICAgIHN1cGVyKGNvbnRleHQpO1xuICB9XG4gIGdldEZ1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5vZmZzZXRUb0Nvb3JkcygpLFxuICAgICAgLi4udGhpcy5jb29yZHNUb09mZnNldCgpLFxuICAgICAgLi4udGhpcy50b1ZlYygpLFxuICAgICAgLi4udGhpcy52YWx1ZUZyb20oKSxcbiAgICAgIC8vIFRPRE8gcmV0dXJuIHRoZXNlIG9ubHkgd2hlbiBwYWNraW5nIGlzIGVuYWJsZWQuXG4gICAgICAuLi50aGlzLmdldENvbW1vblV0aWxGdW5jcygpLFxuICAgICAgLi4udGhpcy5nZXRJbnB1dHNTYW1wbGluZ1NuaXBwZXRzKCksXG4gICAgICAuLi50aGlzLmdldE91dHB1dFNhbXBsaW5nU25pcHBldCgpLFxuICAgIH07XG4gIH1cbiAgZ2V0Q3VzdG9tVHlwZXMoKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIC8qKlxuICAgKiBQcm9kdWNlcyBhIGZ1bmN0aW9uIHRoYXQgY2FuIG1hcCBmcm9tXG4gICAqIDJEIG5vcm1hbHppZWQgY29vcmRpbmF0ZXMgKHMsdCkgdG8gYSBmbGF0IG9mZnNldFxuICAgKi9cbiAgcHJvdGVjdGVkIG9mZnNldFRvQ29vcmRzKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IGZ1bmNOYW1lID0gJ29mZnNldFRvQ29vcmRzJztcbiAgICByZXR1cm4ge1xuICAgICAgb2Zmc2V0VG9Db29yZHM6IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICB2ZWMyICR7ZnVuY05hbWV9KGludCBvZmZzZXQsIGludCB3aWR0aCwgaW50IGhlaWdodCkge1xuICAgICAgICBpbnQgdCA9IG9mZnNldCAvIHdpZHRoO1xuICAgICAgICBpbnQgcyA9IG9mZnNldCAtIHQqd2lkdGg7XG4gICAgICAgIHZlYzIgY29vcmRzID0gKHZlYzIocyx0KSArIHZlYzIoMC41LDAuNSkpIC8gdmVjMih3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgcmV0dXJuIGNvb3JkcztcbiAgICAgIH1cbiAgICAgIGApLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUHJvZHVjZXMgYSBmdW5jdGlvbiB0aGF0IGNhbiBtYXAgZnJvbVxuICAgKiAyRCBub3JtYWx6aWVkIGNvb3JkaW5hdGVzIChzLHQpIHRvIGEgZmxhdCBvZmZzZXRcbiAgICovXG4gIHByb3RlY3RlZCBjb29yZHNUb09mZnNldCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBmdW5jTmFtZSA9ICdjb29yZHNUb09mZnNldCc7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvb3Jkc1RvT2Zmc2V0OiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgaW50ICR7ZnVuY05hbWV9KHZlYzIgY29vcmRzLCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHtcbiAgICAgICAgZmxvYXQgcyA9IGNvb3Jkcy5zICogZmxvYXQod2lkdGgpO1xuICAgICAgICBmbG9hdCB0ID0gY29vcmRzLnQgKiBmbG9hdChoZWlnaHQpO1xuICAgICAgICBpbnQgb2Zmc2V0ID0gaW50KHQpICogd2lkdGggKyBpbnQocyk7XG4gICAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgICB9XG4gICAgICBgKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBjb2RlIGZvciBvdXRwdXQgc2FtcGxlci5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldE91dHB1dFNhbXBsaW5nU25pcHBldCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBpZiAob3V0cHV0TGF5b3V0LmlzUGFja2VkKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRQYWNrZWRPdXRwdXRTYW1wbGluZ1NuaXBwZXQob3V0cHV0TGF5b3V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRPdXRwdXRTYW1wbGluZ1NuaXBwZXQob3V0cHV0TGF5b3V0KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGNvZGUgZm9yIHBhY2tlZCBvdXRwdXQgc2FtcGxlci5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRPdXRwdXRTYW1wbGluZ1NuaXBwZXQob3V0cHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0U2hhcGUgPSBvdXRwdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBvdXRUZXhTaGFwZSA9IFtvdXRwdXRMYXlvdXQud2lkdGgsIG91dHB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIGNvbnN0IGZ1bmNOYW1lID0gJ2dldE91dHB1dENvb3Jkcyc7XG4gICAgc3dpdGNoIChvdXRTaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0U2NhbGFyQ29vcmRzKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRQYWNrZWQxRENvb3JkcyhvdXRTaGFwZSBhcyBbbnVtYmVyXSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRQYWNrZWQyRENvb3JkcyhvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFBhY2tlZDNEQ29vcmRzKFxuICAgICAgICAgIG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICApO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFBhY2tlZE5EQ29vcmRzKG91dFNoYXBlLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICB9XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAvLyBUT0RPIHdlIG5lZWQgdGhpcyB0byBwcm9wZXJseSByZXR1cm4gYSBwYWNrZWQgdmVjNCBmcm9tIGtlcm5lbHMuXG4gICAgLy8gUmVwbGFjZSBhbGwgJ3tnbHNsLm91dHB1dH0gPSByZXN1bHQnIHdpdGggJ3NldE91dHB1dChyZXN1bHQpJyBpbiBhbGwga2VybmVscy5cbiAgICBjb25zdCBmbG9hdFRleHR1cmVTZXRSR0JBU291cmNlID0gYFxuICAgICAgdm9pZCBzZXRPdXRwdXQodmVjNCB2YWwpIHtcbiAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2YWw7XG4gICAgICB9XG4gICAgYDtcbiAgICBjb25zdCBmbG9hdFRleHR1cmVTZXRSR0JBRnVuY05hbWUgPSAnZmxvYXRUZXh0dXJlU2V0UkdCQSc7XG4gICAgcmVzdWx0W2Zsb2F0VGV4dHVyZVNldFJHQkFGdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoZmxvYXRUZXh0dXJlU2V0UkdCQVNvdXJjZSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgY29kZSBmb3IgdW5wYWNrZWQgb3V0cHV0IHNhbXBsZXIuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRPdXRwdXRTYW1wbGluZ1NuaXBwZXQob3V0cHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0U2hhcGUgPSBvdXRwdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBvdXRUZXhTaGFwZSA9IFtvdXRwdXRMYXlvdXQud2lkdGgsIG91dHB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIGNvbnN0IGZ1bmNOYW1lID0gJ2dldE91dHB1dENvb3Jkcyc7XG4gICAgc3dpdGNoIChvdXRTaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0U2NhbGFyQ29vcmRzKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDFEQ29vcmRzKG91dFNoYXBlIGFzIFtudW1iZXJdLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkMkRDb29yZHMoXG4gICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICApO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0VW5wYWNrZWQzRENvb3JkcyhcbiAgICAgICAgICBvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkNERDb29yZHMoXG4gICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDU6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkNURDb29yZHMoXG4gICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICApO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNjpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0VW5wYWNrZWQ2RENvb3JkcyhcbiAgICAgICAgICBvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIG91dHB1dCBkaW1lbnNpb25hbGl0eTogJHtvdXRTaGFwZS5sZW5ndGh9YCk7XG4gICAgfVxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgLy8gVE9ETyB3ZSBuZWVkIHRoaXMgdG8gcHJvcGVybHkgcmV0dXJuIGEgcGFja2VkIHZlYzQgZnJvbSBrZXJuZWxzLlxuICAgIC8vIFJlcGxhY2UgYWxsICd7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0JyB3aXRoICdzZXRPdXRwdXQocmVzdWx0KScgaW4gYWxsIGtlcm5lbHMuXG4gICAgY29uc3QgZmxvYXRUZXh0dXJlU2V0UlNvdXJjZSA9IGBcbiAgICAgICAgdm9pZCBzZXRPdXRwdXQoZmxvYXQgdmFsKSB7XG4gICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KHZhbCwgMCwgMCwgMCk7XG4gICAgICAgIH1cbiAgICBgO1xuICAgIGNvbnN0IGZsb2F0VGV4dHVyZVNldFJGdW5jTmFtZSA9ICdmbG9hdFRleHR1cmVTZXRSJztcbiAgICByZXN1bHRbZmxvYXRUZXh0dXJlU2V0UkZ1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShmbG9hdFRleHR1cmVTZXRSU291cmNlKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIFNjYWxhciBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0U2NhbGFyQ29vcmRzKCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgIGApO1xuICB9XG5cbiAgLyoqXG4gICAqIDFEIHBhY2tlZCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0UGFja2VkMURDb29yZHMoX3NoYXBlOiBbbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSB0ZXhTaGFwZTtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgaWYgKHBhY2tlZFRleFNoYXBlWzBdID09PSAxKSB7XG4gICAgICBzb3VyY2UgPSBgXG4gICAgICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICAgIHJldHVybiAyICogaW50KFRleENvb3Jkcy55ICogJHtwYWNrZWRUZXhTaGFwZVsxXX0uMCk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICAgIH1cblxuICAgIGlmIChwYWNrZWRUZXhTaGFwZVsxXSA9PT0gMSkge1xuICAgICAgc291cmNlID0gYFxuICAgICAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgICByZXR1cm4gMiAqIGludChUZXhDb29yZHMueCAqICR7cGFja2VkVGV4U2hhcGVbMF19LjApO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgICB9XG5cbiAgICBzb3VyY2UgPSBgXG4gICAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICByZXR1cm4gMiAqIChyZXNUZXhSQy55ICogJHtwYWNrZWRUZXhTaGFwZVswXX0gKyByZXNUZXhSQy54KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogMkQgcGFja2VkIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRQYWNrZWQyRENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGlmIChBcnJheVV0aWwuYXJyYXlzRXF1YWwoc2hhcGUsIHRleFNoYXBlKSkge1xuICAgICAgc291cmNlID0gYFxuICAgICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgcmV0dXJuIDIgKiBpdmVjMihUZXhDb29yZHMueHkgKiB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICAgIH1cblxuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gdGV4U2hhcGU7XG4gICAgLy8gdGV4ZWxzIG5lZWRlZCB0byBhY2NvbW1vZGF0ZSBhIGxvZ2ljYWwgcm93XG4gICAgY29uc3QgdGV4ZWxzSW5Mb2dpY2FsUm93ID0gTWF0aC5jZWlsKHNoYXBlWzFdIC8gMik7XG5cbiAgICAvKipcbiAgICAgKiBnZXRPdXRwdXRDb29yZHNcbiAgICAgKlxuICAgICAqIHJlc1RleFJDOiBUaGUgcm93cyBhbmQgY29sdW1ucyBvZiB0aGUgdGV4ZWxzLiBJZiB5b3UgbW92ZSBvdmVyIG9uZVxuICAgICAqIHRleGVsIHRvIHRoZSByaWdodCBpbiB0aGUgcGFja2VkIHRleHR1cmUsIHlvdSBhcmUgbW92aW5nIG92ZXIgb25lIGNvbHVtblxuICAgICAqIChub3QgdHdvKS5cbiAgICAgKlxuICAgICAqIGluZGV4OiBUaGUgdGV4ZWwgaW5kZXhcbiAgICAgKi9cbiAgICBzb3VyY2UgPSBgXG4gICAgICAgIGl2ZWMyIGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHtwYWNrZWRUZXhTaGFwZVswXX0sICR7cGFja2VkVGV4U2hhcGVbMV19KSk7XG5cbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHtwYWNrZWRUZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuXG4gICAgICAgICAgLy8gcmV2ZXJzZSByIGFuZCBjIG9yZGVyIGZvciBwYWNrZWQgdGV4dHVyZVxuICAgICAgICAgIGludCByID0gaW1vZChpbmRleCwgJHt0ZXhlbHNJbkxvZ2ljYWxSb3d9KSAqIDI7XG4gICAgICAgICAgaW50IGMgPSAyICogKGluZGV4IC8gJHt0ZXhlbHNJbkxvZ2ljYWxSb3d9KTtcblxuICAgICAgICAgIHJldHVybiBpdmVjMihyLCBjKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogM0QgcGFja2VkIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRQYWNrZWQzRENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVswXSwgdGV4U2hhcGVbMV1dO1xuICAgIGNvbnN0IHRleGVsc0luTG9naWNhbFJvdyA9IE1hdGguY2VpbChzaGFwZVsyXSAvIDIpO1xuICAgIGNvbnN0IHRleGVsc0luQmF0Y2ggPSB0ZXhlbHNJbkxvZ2ljYWxSb3cgKiBNYXRoLmNlaWwoc2hhcGVbMV0gLyAyKTtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGl2ZWMzIGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHtwYWNrZWRUZXhTaGFwZVswXX0sICR7cGFja2VkVGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7cGFja2VkVGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcblxuICAgICAgICAgIGludCBiID0gaW5kZXggLyAke3RleGVsc0luQmF0Y2h9O1xuICAgICAgICAgIGluZGV4IC09IGIgKiAke3RleGVsc0luQmF0Y2h9O1xuXG4gICAgICAgICAgLy8gcmV2ZXJzZSByIGFuZCBjIG9yZGVyIGZvciBwYWNrZWQgdGV4dHVyZVxuICAgICAgICAgIGludCByID0gaW1vZChpbmRleCwgJHt0ZXhlbHNJbkxvZ2ljYWxSb3d9KSAqIDI7XG4gICAgICAgICAgaW50IGMgPSAyICogKGluZGV4IC8gJHt0ZXhlbHNJbkxvZ2ljYWxSb3d9KTtcblxuICAgICAgICAgIHJldHVybiBpdmVjMyhiLCByLCBjKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogTkQgcGFja2VkIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRQYWNrZWRORENvb3JkcyhzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzBdLCB0ZXhTaGFwZVsxXV07XG5cbiAgICBjb25zdCB0ZXhlbHNJbkxvZ2ljYWxSb3cgPSBNYXRoLmNlaWwoc2hhcGVbc2hhcGUubGVuZ3RoIC0gMV0gLyAyKTtcbiAgICBjb25zdCB0ZXhlbHNJbkJhdGNoID0gdGV4ZWxzSW5Mb2dpY2FsUm93ICogTWF0aC5jZWlsKHNoYXBlW3NoYXBlLmxlbmd0aCAtIDJdIC8gMik7XG4gICAgbGV0IHRleGVsc0luQmF0Y2hOID0gdGV4ZWxzSW5CYXRjaDtcbiAgICBsZXQgYmF0Y2hlcyA9ICcnO1xuICAgIGxldCBjb29yZHMgPSAnYiwgciwgYyc7XG5cbiAgICBmb3IgKGxldCBiID0gMjsgYiA8IHNoYXBlLmxlbmd0aCAtIDE7IGIrKykge1xuICAgICAgdGV4ZWxzSW5CYXRjaE4gKj0gc2hhcGVbc2hhcGUubGVuZ3RoIC0gYiAtIDFdO1xuICAgICAgYmF0Y2hlcyA9XG4gICAgICAgIGBcbiAgICAgIGludCBiJHtifSA9IGluZGV4IC8gJHt0ZXhlbHNJbkJhdGNoTn07XG4gICAgICBpbmRleCAtPSBiJHtifSAqICR7dGV4ZWxzSW5CYXRjaE59O1xuICAgIGAgKyBiYXRjaGVzO1xuICAgICAgY29vcmRzID0gYGIke2J9LCBgICsgY29vcmRzO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICBpdmVjJHtzaGFwZS5sZW5ndGh9IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7cGFja2VkVGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcblxuICAgICAgICAke2JhdGNoZXN9XG5cbiAgICAgICAgaW50IGIgPSBpbmRleCAvICR7dGV4ZWxzSW5CYXRjaH07XG4gICAgICAgIGluZGV4IC09IGIgKiAke3RleGVsc0luQmF0Y2h9O1xuXG4gICAgICAgIC8vIHJldmVyc2UgciBhbmQgYyBvcmRlciBmb3IgcGFja2VkIHRleHR1cmVcbiAgICAgICAgaW50IHIgPSBpbW9kKGluZGV4LCAke3RleGVsc0luTG9naWNhbFJvd30pICogMjtcbiAgICAgICAgaW50IGMgPSAyICogKGluZGV4IC8gJHt0ZXhlbHNJbkxvZ2ljYWxSb3d9KTtcblxuICAgICAgICByZXR1cm4gaXZlYyR7c2hhcGUubGVuZ3RofSgke2Nvb3Jkc30pO1xuICAgICAgfVxuICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDFEIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDFEQ29vcmRzKF9zaGFwZTogW251bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgcmV0dXJuIHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDJEIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDJEQ29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGl2ZWMyIGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7dGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcbiAgICAgICAgICBpbnQgciA9IGluZGV4IC8gJHtzaGFwZVsxXX07XG4gICAgICAgICAgaW50IGMgPSBpbmRleCAtIHIgKiAke3NoYXBlWzFdfTtcbiAgICAgICAgICByZXR1cm4gaXZlYzIociwgYyk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDNEIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDNEQ29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gICAgbGV0IHN0cmlkZXMgPSBudWxsO1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgc3RyaWRlcyA9IFtdO1xuICAgIH1cblxuICAgIHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayAtIDEpO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gc2hhcGVbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIHNoYXBlW2kgKyAxXTtcbiAgICB9XG4gICAgY29uc3QgY29vcmRzVG9Db21wdXRlID0gWydyJywgJ2MnLCAnZCddO1xuICAgIGNvbnN0IGNvb3Jkc0Zyb21JbmRleFNuaXBwZXQgPSBzdHJpZGVzXG4gICAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgICAgY29uc3QgbGluZTEgPSBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2ldfSA9IGluZGV4IC8gJHtzdHJpZGV9YDtcbiAgICAgICAgY29uc3QgbGluZTIgPVxuICAgICAgICAgIGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMVxuICAgICAgICAgICAgPyBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2kgKyAxXX0gPSBpbmRleCAtICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWBcbiAgICAgICAgICAgIDogYGluZGV4IC09ICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJycpO1xuXG4gICAgc291cmNlID0gYFxuICAgICAgICBpdmVjMyBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAgJHtjb29yZHNGcm9tSW5kZXhTbmlwcGV0fVxuICAgICAgICAgIHJldHVybiBpdmVjMyhyLCBjLCBkKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgNEQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkNERDb29yZHMoXG4gICAgc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdLFxuICApOiBHbHNsTGliUm91dGluZSB7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgICBsZXQgc3RyaWRlcyA9IG51bGw7XG4gICAgaWYgKHJhbmsgPCAyKSB7XG4gICAgICBzdHJpZGVzID0gW107XG4gICAgfVxuXG4gICAgc3RyaWRlcyA9IG5ldyBBcnJheShyYW5rIC0gMSk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMl0gPSBzaGFwZVtyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogc2hhcGVbaSArIDFdO1xuICAgIH1cbiAgICBjb25zdCBjb29yZHNUb0NvbXB1dGUgPSBbJ3InLCAnYycsICdkJywgJ2QyJ107XG4gICAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9IHN0cmlkZXNcbiAgICAgIC5tYXAoKHN0cmlkZSwgaSkgPT4ge1xuICAgICAgICBjb25zdCBsaW5lMSA9IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaV19ID0gaW5kZXggLyAke3N0cmlkZX1gO1xuICAgICAgICBjb25zdCBsaW5lMiA9XG4gICAgICAgICAgaSA9PT0gc3RyaWRlcy5sZW5ndGggLSAxXG4gICAgICAgICAgICA/IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaSArIDFdfSA9IGluZGV4IC0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YFxuICAgICAgICAgICAgOiBgaW5kZXggLT0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgICAgcmV0dXJuIGAke2xpbmUxfTsgJHtsaW5lMn07YDtcbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG5cbiAgICBzb3VyY2UgPSBgXG4gICAgICBpdmVjNCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAgJHtjb29yZHNGcm9tSW5kZXhTbmlwcGV0fVxuICAgICAgICAgIHJldHVybiBpdmVjNChyLCBjLCBkLCBkMik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDVEIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDVEQ29vcmRzKFxuICAgIHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdLFxuICApOiBHbHNsTGliUm91dGluZSB7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgICBsZXQgc3RyaWRlcyA9IG51bGw7XG4gICAgaWYgKHJhbmsgPCAyKSB7XG4gICAgICBzdHJpZGVzID0gW107XG4gICAgfVxuXG4gICAgc3RyaWRlcyA9IG5ldyBBcnJheShyYW5rIC0gMSk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMl0gPSBzaGFwZVtyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogc2hhcGVbaSArIDFdO1xuICAgIH1cbiAgICBjb25zdCBjb29yZHNUb0NvbXB1dGUgPSBbJ3InLCAnYycsICdkJywgJ2QyJywgJ2QzJ107XG4gICAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9IHN0cmlkZXNcbiAgICAgIC5tYXAoKHN0cmlkZSwgaSkgPT4ge1xuICAgICAgICBjb25zdCBsaW5lMSA9IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaV19ID0gaW5kZXggLyAke3N0cmlkZX1gO1xuICAgICAgICBjb25zdCBsaW5lMiA9XG4gICAgICAgICAgaSA9PT0gc3RyaWRlcy5sZW5ndGggLSAxXG4gICAgICAgICAgICA/IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaSArIDFdfSA9IGluZGV4IC0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YFxuICAgICAgICAgICAgOiBgaW5kZXggLT0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgICAgcmV0dXJuIGAke2xpbmUxfTsgJHtsaW5lMn07YDtcbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG5cbiAgICBzb3VyY2UgPSBgXG4gICAgICBpdmVjNSBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAgJHtjb29yZHNGcm9tSW5kZXhTbmlwcGV0fVxuICAgICAgICAgIHJldHVybiBpdmVjNShyLCBjLCBkLCBkMiwgZDMpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA2RCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQ2RENvb3JkcyhcbiAgICBzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdLFxuICApOiBHbHNsTGliUm91dGluZSB7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgICBsZXQgc3RyaWRlcyA9IG51bGw7XG4gICAgaWYgKHJhbmsgPCAyKSB7XG4gICAgICBzdHJpZGVzID0gW107XG4gICAgfVxuXG4gICAgc3RyaWRlcyA9IG5ldyBBcnJheShyYW5rIC0gMSk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMl0gPSBzaGFwZVtyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogc2hhcGVbaSArIDFdO1xuICAgIH1cbiAgICBjb25zdCBjb29yZHNUb0NvbXB1dGUgPSBbJ3InLCAnYycsICdkJywgJ2QyJywgJ2QzJywgJ2Q0J107XG4gICAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9IHN0cmlkZXNcbiAgICAgIC5tYXAoKHN0cmlkZSwgaSkgPT4ge1xuICAgICAgICBjb25zdCBsaW5lMSA9IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaV19ID0gaW5kZXggLyAke3N0cmlkZX1gO1xuICAgICAgICBjb25zdCBsaW5lMiA9XG4gICAgICAgICAgaSA9PT0gc3RyaWRlcy5sZW5ndGggLSAxXG4gICAgICAgICAgICA/IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaSArIDFdfSA9IGluZGV4IC0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YFxuICAgICAgICAgICAgOiBgaW5kZXggLT0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgICAgcmV0dXJuIGAke2xpbmUxfTsgJHtsaW5lMn07YDtcbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG5cbiAgICBzb3VyY2UgPSBgXG4gICAgIGl2ZWM2IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7dGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcbiAgICAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgICAgIHJldHVybiBpdmVjNihyLCBjLCBkLCBkMiwgZDMsIGQ0KTtcbiAgICAgICB9XG4gICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBjb2RlIGZvciBjb21tb24gVVYgY29vcmRzIGNvbXB1dGF0aW9uIHV0aWxpdHkgZnVuY3Rpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldENvbW1vblV0aWxGdW5jcygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICBsZXQgZnVuY05hbWUgPSAndXZGcm9tRmxhdCc7XG4gICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgdmVjMiB1dkZyb21GbGF0KGludCB0ZXhOdW1SLCBpbnQgdGV4TnVtQywgaW50IGluZGV4KSB7XG4gICAgICBpbnQgdGV4QyA9IGluZGV4IC8gdGV4TnVtUjtcbiAgICAgIGludCB0ZXhSID0gaW5kZXggLSB0ZXhDICogdGV4TnVtUjtcbiAgICAgIC8vIFRPRE86IHN3YXAgdGV4UiwgdGV4QyBvcmRlciBpbiBmb2xsb3dpbmcgZnVuY3Rpb24gc28gcm93IGlzIGNvcnJlc3BvbmRpbmcgdG8gdSBhbmQgY29sdW1uIGlzIGNvcnJlc3BvbmRpbmcgdG9cbiAgICAgIC8vICAgICAgIHYuXG4gICAgICByZXR1cm4gKHZlYzIodGV4UiwgdGV4QykgKyBoYWxmQ1IpIC8gdmVjMih0ZXhOdW1SLCB0ZXhOdW1DKTtcbiAgICB9XG4gICAgYCk7XG4gICAgZnVuY05hbWUgPSAncGFja2VkVVZmcm9tMUQnO1xuICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgdmVjMiBwYWNrZWRVVmZyb20xRChpbnQgdGV4TnVtUiwgaW50IHRleE51bUMsIGludCBpbmRleCkge1xuICAgICAgICBpbnQgdGV4ZWxJbmRleCA9IGluZGV4IC8gMjtcbiAgICAgICAgaW50IHRleFIgPSB0ZXhlbEluZGV4IC8gdGV4TnVtQztcbiAgICAgICAgaW50IHRleEMgPSB0ZXhlbEluZGV4IC0gdGV4UiAqIHRleE51bUM7XG4gICAgICAgIHJldHVybiAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLyB2ZWMyKHRleE51bUMsIHRleE51bVIpO1xuICAgICAgfVxuICAgICAgYCk7XG4gICAgZnVuY05hbWUgPSAncGFja2VkVVZmcm9tMkQnO1xuICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgdmVjMiBwYWNrZWRVVmZyb20yRChpbnQgdGV4TnVtUiwgaW50IHRleE51bUMsIGludCB0ZXhlbHNJbkxvZ2ljYWxSb3csIGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgaW50IHRleGVsSW5kZXggPSAocm93IC8gMikgKiB0ZXhlbHNJbkxvZ2ljYWxSb3cgKyAoY29sIC8gMik7XG4gICAgICAgIGludCB0ZXhSID0gdGV4ZWxJbmRleCAvIHRleE51bUM7XG4gICAgICAgIGludCB0ZXhDID0gdGV4ZWxJbmRleCAtIHRleFIgKiB0ZXhOdW1DO1xuICAgICAgICByZXR1cm4gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMih0ZXhOdW1DLCB0ZXhOdW1SKTtcbiAgICAgIH1cbiAgICAgIGApO1xuICAgIGZ1bmNOYW1lID0gJ3BhY2tlZFVWZnJvbTNEJztcbiAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIHZlYzIgcGFja2VkVVZmcm9tM0QoaW50IHRleE51bVIsIGludCB0ZXhOdW1DLFxuICAgICAgICAgIGludCB0ZXhlbHNJbkJhdGNoLCBpbnQgdGV4ZWxzSW5Mb2dpY2FsUm93LCBpbnQgYixcbiAgICAgICAgICBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgIGludCBpbmRleCA9IGIgKiB0ZXhlbHNJbkJhdGNoICsgKHJvdyAvIDIpICogdGV4ZWxzSW5Mb2dpY2FsUm93ICsgKGNvbCAvIDIpO1xuICAgICAgICBpbnQgdGV4UiA9IGluZGV4IC8gdGV4TnVtQztcbiAgICAgICAgaW50IHRleEMgPSBpbmRleCAtIHRleFIgKiB0ZXhOdW1DO1xuICAgICAgICByZXR1cm4gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMih0ZXhOdW1DLCB0ZXhOdW1SKTtcbiAgICAgIH1cbiAgICAgIGApO1xuICAgIGZ1bmNOYW1lID0gJ3NhbXBsZVRleHR1cmUnO1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICAgIGZsb2F0IHNhbXBsZVRleHR1cmUoc2FtcGxlcjJEIHRleHR1cmVTYW1wbGVyLCB2ZWMyIHV2KSB7XG4gICAgICAgICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0odGV4dHVyZVNhbXBsZXIsIHV2KS5yO1xuICAgICAgICB9YCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIGlucHV0c1xuICAgKi9cbiAgcHJvdGVjdGVkIGdldElucHV0c1NhbXBsaW5nU25pcHBldHMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgoc2FtcGxlck5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IGlucHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV07XG4gICAgICBjb25zdCBmdW5jTmFtZSA9IGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZShzYW1wbGVyTmFtZSk7XG4gICAgICBpZiAoaW5wdXRMYXlvdXQuaXNQYWNrZWQpIHtcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0UGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgc2FtcGxlck5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgc2FtcGxlck5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb3V0Q29vcmRGdW5jTmFtZSA9IGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZUF0T3V0Q29vcmRzKHNhbXBsZXJOYW1lKTtcbiAgICAgIGlmIChpbnB1dExheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aCA8PSBvdXRwdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGgpIHtcbiAgICAgICAgaWYgKGlucHV0TGF5b3V0LmlzUGFja2VkKSB7XG4gICAgICAgICAgcmVzdWx0W291dENvb3JkRnVuY05hbWVdID0gdGhpcy5nZXRQYWNrZWRTYW1wbGVyQXRPdXRwdXRDb29yZHMoXG4gICAgICAgICAgICBvdXRDb29yZEZ1bmNOYW1lLFxuICAgICAgICAgICAgaW5wdXRMYXlvdXQsXG4gICAgICAgICAgICBvdXRwdXRMYXlvdXQsXG4gICAgICAgICAgICBzYW1wbGVyTmFtZSxcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdFtvdXRDb29yZEZ1bmNOYW1lXSA9IHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyQXRPdXRwdXRDb29yZHMoXG4gICAgICAgICAgICBvdXRDb29yZEZ1bmNOYW1lLFxuICAgICAgICAgICAgaW5wdXRMYXlvdXQsXG4gICAgICAgICAgICBvdXRwdXRMYXlvdXQsXG4gICAgICAgICAgICBzYW1wbGVyTmFtZSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdGluZyBzbmlwcGV0cyBmb3Igb3V0cHV0IGNvb3JkaW5hdGVzIG9mIHNhbXBsZXJzXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKFxuICAgIGZ1bmNOYW1lOiBzdHJpbmcsXG4gICAgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQsXG4gICAgb3V0cHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IGluU2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IG91dFNoYXBlID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgdGV4TmFtZSA9IG5hbWU7XG4gICAgY29uc3QgdGV4RnVuY1NuaXBwZXQgPSBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWUodGV4TmFtZSk7XG5cbiAgICBjb25zdCBpblJhbmsgPSBpblNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBvdXRSYW5rID0gb3V0U2hhcGUubGVuZ3RoO1xuXG4gICAgY29uc3QgYnJvYWRjYXN0RGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpblNoYXBlLCBvdXRTaGFwZSk7XG5cbiAgICBjb25zdCB0eXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0UmFuayk7XG4gICAgY29uc3QgcmFua0RpZmYgPSBvdXRSYW5rIC0gaW5SYW5rO1xuICAgIGxldCBjb29yZHNTbmlwcGV0OiBzdHJpbmc7XG4gICAgY29uc3QgZmllbGRzID0gZ2V0R2xDaGFubmVscygpO1xuXG4gICAgaWYgKGluUmFuayA9PT0gMCkge1xuICAgICAgY29vcmRzU25pcHBldCA9ICcnO1xuICAgIH0gZWxzZSBpZiAob3V0UmFuayA8IDIgJiYgYnJvYWRjYXN0RGltcy5sZW5ndGggPj0gMSkge1xuICAgICAgY29vcmRzU25pcHBldCA9ICdjb29yZHMgPSAwOyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSBicm9hZGNhc3REaW1zLm1hcCgoZCkgPT4gYGNvb3Jkcy4ke2ZpZWxkc1tkICsgcmFua0RpZmZdfSA9IDA7YCkuam9pbignXFxuJyk7XG4gICAgfVxuICAgIGxldCB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSAnJztcbiAgICBpZiAob3V0UmFuayA8IDIgJiYgaW5SYW5rID4gMCkge1xuICAgICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJ2Nvb3Jkcyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9IGluU2hhcGUubWFwKChfcywgaSkgPT4gYGNvb3Jkcy4ke2ZpZWxkc1tpICsgcmFua0RpZmZdfWApLmpvaW4oJywgJyk7XG4gICAgfVxuXG4gICAgbGV0IG91dHB1dCA9ICdyZXR1cm4gb3V0cHV0VmFsdWU7JztcbiAgICBjb25zdCBpblNpemUgPSBTaGFwZVV0aWwuc2l6ZShpblNoYXBlKTtcbiAgICBjb25zdCBpc0lucHV0U2NhbGFyID0gaW5TaXplID09PSAxO1xuICAgIGNvbnN0IG91dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRTaGFwZSk7XG4gICAgY29uc3QgaXNPdXRwdXRTY2FsYXIgPSBvdXRTaXplID09PSAxO1xuXG4gICAgaWYgKGluUmFuayA9PT0gMSAmJiAhaXNJbnB1dFNjYWxhciAmJiAhaXNPdXRwdXRTY2FsYXIpIHtcbiAgICAgIG91dHB1dCA9IGBcbiAgICAgICAgcmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueHksIG91dHB1dFZhbHVlLnh5KTtcbiAgICAgIGA7XG4gICAgfSBlbHNlIGlmIChpc0lucHV0U2NhbGFyICYmICFpc091dHB1dFNjYWxhcikge1xuICAgICAgaWYgKG91dFJhbmsgPT09IDEpIHtcbiAgICAgICAgb3V0cHV0ID0gYFxuICAgICAgICAgIHJldHVybiB2ZWM0KG91dHB1dFZhbHVlLngsIG91dHB1dFZhbHVlLngsIDAuLCAwLik7XG4gICAgICAgIGA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQgPSBgXG4gICAgICAgICAgcmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCk7XG4gICAgICAgIGA7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChicm9hZGNhc3REaW1zLmxlbmd0aCkge1xuICAgICAgY29uc3Qgcm93cyA9IGluUmFuayAtIDI7XG4gICAgICBjb25zdCBjb2xzID0gaW5SYW5rIC0gMTtcblxuICAgICAgaWYgKGJyb2FkY2FzdERpbXMuaW5kZXhPZihyb3dzKSA+IC0xICYmIGJyb2FkY2FzdERpbXMuaW5kZXhPZihjb2xzKSA+IC0xKSB7XG4gICAgICAgIG91dHB1dCA9ICdyZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54KTsnO1xuICAgICAgfSBlbHNlIGlmIChicm9hZGNhc3REaW1zLmluZGV4T2Yocm93cykgPiAtMSkge1xuICAgICAgICBvdXRwdXQgPSAncmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCwgb3V0cHV0VmFsdWUueSwgJyArICdvdXRwdXRWYWx1ZS54LCBvdXRwdXRWYWx1ZS55KTsnO1xuICAgICAgfSBlbHNlIGlmIChicm9hZGNhc3REaW1zLmluZGV4T2YoY29scykgPiAtMSkge1xuICAgICAgICBvdXRwdXQgPSAncmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueHgsIG91dHB1dFZhbHVlLnp6KTsnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN3YXBMYXN0RGltc1NuaXBwZXQgPSBgXG4gICAgICAgIGludCBsYXN0RGltID0gY29vcmRzLiR7ZmllbGRzW291dFJhbmsgLSAxXX07XG4gICAgICAgIGNvb3Jkcy4ke2ZpZWxkc1tvdXRSYW5rIC0gMV19ID0gY29vcmRzLiR7ZmllbGRzW291dFJhbmsgLSAyXX07XG4gICAgICAgIGNvb3Jkcy4ke2ZpZWxkc1tvdXRSYW5rIC0gMl19ID0gbGFzdERpbTtcbiAgICAgIGA7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgdmVjNCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgJHt0eXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICAgICAgJHtzd2FwTGFzdERpbXNTbmlwcGV0fVxuICAgICAgICAke2Nvb3Jkc1NuaXBwZXR9XG4gICAgICAgIHZlYzQgb3V0cHV0VmFsdWUgPSAke3RleEZ1bmNTbmlwcGV0fSgke3VucGFja2VkQ29vcmRzU25pcHBldH0pO1xuICAgICAgICAke291dHB1dH1cbiAgICAgIH1cbiAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLmdldE91dHB1dENvb3JkcyddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIHVucGFja2VkIG91dHB1dCBjb29yZGluYXRlcyBvZiBzYW1wbGVyc1xuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKFxuICAgIGZ1bmNOYW1lOiBzdHJpbmcsXG4gICAgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQsXG4gICAgb3V0cHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IG91dFRleFNoYXBlID0gW291dHB1dExheW91dC53aWR0aCwgb3V0cHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgaW5UZXhTaGFwZSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCBpblJhbmsgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBvdXRSYW5rID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IGluU2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IG91dFNoYXBlID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgdGV4RnVuY1NuaXBwZXQgPSBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWUobmFtZSk7XG5cbiAgICBpZiAoaW5SYW5rID09PSBvdXRSYW5rICYmIEFycmF5VXRpbC5hcnJheXNFcXVhbChpblRleFNoYXBlLCBvdXRUZXhTaGFwZSkpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIFRleENvb3Jkcyk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBjb25zdCB0eXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0UmFuayk7XG4gICAgY29uc3QgYnJvYWRjYXN0RGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpblNoYXBlLCBvdXRTaGFwZSk7XG4gICAgY29uc3QgcmFua0RpZmYgPSBvdXRSYW5rIC0gaW5SYW5rO1xuICAgIGxldCBjb29yZHNTbmlwcGV0OiBzdHJpbmc7XG4gICAgY29uc3QgZmllbGRzID0gZ2V0R2xDaGFubmVscygpO1xuXG4gICAgaWYgKGluUmFuayA9PT0gMCkge1xuICAgICAgY29vcmRzU25pcHBldCA9ICcnO1xuICAgIH0gZWxzZSBpZiAob3V0UmFuayA8IDIgJiYgYnJvYWRjYXN0RGltcy5sZW5ndGggPj0gMSkge1xuICAgICAgY29vcmRzU25pcHBldCA9ICdjb29yZHMgPSAwOyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSBicm9hZGNhc3REaW1zLm1hcCgoZCkgPT4gYGNvb3Jkcy4ke2ZpZWxkc1tkICsgcmFua0RpZmZdfSA9IDA7YCkuam9pbignXFxuJyk7XG4gICAgfVxuICAgIGxldCB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSAnJztcbiAgICBpZiAob3V0UmFuayA8IDIgJiYgaW5SYW5rID4gMCkge1xuICAgICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJ2Nvb3Jkcyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGUubWFwKChfcywgaSkgPT4gYGNvb3Jkcy4ke2ZpZWxkc1tpICsgcmFua0RpZmZdfWApLmpvaW4oJywgJyk7XG4gICAgfVxuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICAgJHt0eXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICAgICAgICAke2Nvb3Jkc1NuaXBwZXR9XG4gICAgICAgICAgcmV0dXJuICR7dGV4RnVuY1NuaXBwZXR9KCR7dW5wYWNrZWRDb29yZHNTbmlwcGV0fSk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuZ2V0T3V0cHV0Q29vcmRzJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdGluZyBzbmlwcGV0cyBmb3IgcGFja2VkIG9wZXJhdGlvbnMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIHN3aXRjaCAoaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlclNjYWxhcihmdW5jTmFtZSwgbmFtZSk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZFNhbXBsZXIxRChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYWNrZWRTYW1wbGVyMkQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYWNrZWRTYW1wbGVyTkQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0aW5nIHNuaXBwZXRzIGZvciB1bnBhY2tlZCBvcGVyYXRpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBzd2l0Y2ggKHNoYXBlLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJTY2FsYXIoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyMUQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyMkQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyM0QoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgNDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyNEQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgNTpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyNUQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgNjpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyNkQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIC8vIFRPRE8gc3VwcG9ydCBtb3JlIGRpbWVuc2lvbmFsaXRpZXNcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkaW1lbnNpb24gJHtzaGFwZS5sZW5ndGh9LURgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGFja2VkIHNjYWxhciBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJTY2FsYXIoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIHZlYzQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgaGFsZkNSKTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhY2tlZCAxRCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXIxRChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzFdLCB0ZXhTaGFwZVswXV07XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICAgIGNvbnN0IHBhY2tlZFNhbXBsZXIgPSBgdmVjNCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgIHZlYzIgdXYgPSBwYWNrZWRVVmZyb20xRChcbiAgICAgICR7cGFja2VkVGV4U2hhcGVbMF19LCAke3BhY2tlZFRleFNoYXBlWzFdfSwgaW5kZXgpO1xuICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIHV2KTtcbiAgICB9YDtcbiAgICBjb25zdCBzb3VyY2UgPSBwYWNrZWRTYW1wbGVyO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnBhY2tlZFVWZnJvbTFEJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhY2tlZCAyRCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXIyRChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCB0ZXhTaGFwZSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIGNvbnN0IHRleE51bVIgPSB0ZXhTaGFwZVswXTtcbiAgICBjb25zdCB0ZXhOdW1DID0gdGV4U2hhcGVbMV07XG5cbiAgICBpZiAodGV4U2hhcGUgIT0gbnVsbCAmJiBBcnJheVV0aWwuYXJyYXlzRXF1YWwoc2hhcGUsIHRleFNoYXBlKSkge1xuICAgICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGB2ZWM0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgdmVjMiB1diA9ICh2ZWMyKGNvbCwgcm93KSArIGhhbGZDUikgLyB2ZWMyKCR7dGV4TnVtQ30uMCwgJHt0ZXhOdW1SfS4wKTtcbiAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIHV2KTtcbiAgICAgIH1gO1xuXG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHBhY2tlZFNhbXBsZXIpO1xuICAgIH1cbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IHRleFNoYXBlO1xuICAgIGNvbnN0IHZhbHVlc1BlclJvdyA9IE1hdGguY2VpbChzaGFwZVsxXSAvIDIpO1xuICAgIGNvbnN0IHBhY2tlZFNhbXBsZXIgPSBgdmVjNCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tMkQoJHtwYWNrZWRUZXhTaGFwZVsxXX0sICR7cGFja2VkVGV4U2hhcGVbMF19LCAke3ZhbHVlc1BlclJvd30sIHJvdywgY29sKTtcbiAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7XG4gICAgfWA7XG4gICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5wYWNrZWRVVmZyb20yRCddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYWNrZWQgM0Qgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyM0QoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSBbdGV4U2hhcGVbMF0sIHRleFNoYXBlWzFdXTtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuXG4gICAgaWYgKHNoYXBlWzBdID09PSAxKSB7XG4gICAgICBjb25zdCBzcXVlZXplZFNoYXBlID0gc2hhcGUuc2xpY2UoMSk7XG4gICAgICBjb25zdCBrZXB0RGltcyA9IFsxLCAyXTtcbiAgICAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgc3F1ZWV6ZWRTaGFwZSk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBbJ2InLCAncm93JywgJ2NvbCddO1xuICAgICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcbiAgICAgIGNvbnN0IHNhbXBsZXJSb3V0aW5lID0gdGhpcy5nZXRQYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCk7XG4gICAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYCR7c2FtcGxlclJvdXRpbmUucm91dGluZUJvZHl9XG4gICAgICB2ZWM0ICR7ZnVuY05hbWV9KGludCBiLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgIHJldHVybiAke2Z1bmNOYW1lfSgke2dldFNxdWVlemVkUGFyYW1zKHBhcmFtcywga2VwdERpbXMpfSk7XG4gICAgICB9IGA7XG4gICAgICBjb25zdCBzb3VyY2UgPSBwYWNrZWRTYW1wbGVyO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIHNhbXBsZXJSb3V0aW5lLmRlcGVuZGVuY2llcyk7XG4gICAgfVxuICAgIGNvbnN0IHRleE51bVIgPSBwYWNrZWRUZXhTaGFwZVswXTtcbiAgICBjb25zdCB0ZXhOdW1DID0gcGFja2VkVGV4U2hhcGVbMV07XG5cbiAgICBjb25zdCB2YWx1ZXNQZXJSb3cgPSBNYXRoLmNlaWwoc2hhcGVbMl0gLyAyKTtcbiAgICBjb25zdCB0ZXhlbHNJbkJhdGNoID0gdmFsdWVzUGVyUm93ICogTWF0aC5jZWlsKHNoYXBlWzFdIC8gMik7XG5cbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oaW50IGIsIGludCByb3csIGludCBjb2wpIHtcbiAgICAgIHZlYzIgdXYgPSBwYWNrZWRVVmZyb20zRChcbiAgICAgICAgJHt0ZXhOdW1DfSwgJHt0ZXhOdW1SfSwgJHt0ZXhlbHNJbkJhdGNofSwgJHt2YWx1ZXNQZXJSb3d9LCBiLCByb3csIGNvbCk7XG4gICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgdXYpO31gO1xuICAgIGNvbnN0IHNvdXJjZSA9IHBhY2tlZFNhbXBsZXI7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMucGFja2VkVVZmcm9tM0QnXSk7XG4gIH1cbiAgLypcbiAgICogUGFja2VkIE5EIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlck5EKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzBdLCB0ZXhTaGFwZVsxXV07XG4gICAgY29uc3QgdGV4TnVtUiA9IHBhY2tlZFRleFNoYXBlWzFdO1xuICAgIGNvbnN0IHRleE51bUMgPSBwYWNrZWRUZXhTaGFwZVswXTtcbiAgICBjb25zdCB2YWx1ZXNQZXJSb3cgPSBNYXRoLmNlaWwoc2hhcGVbcmFuayAtIDFdIC8gMik7XG4gICAgbGV0IHRleGVsc0luQmF0Y2ggPSB2YWx1ZXNQZXJSb3cgKiBNYXRoLmNlaWwoc2hhcGVbcmFuayAtIDJdIC8gMik7XG4gICAgbGV0IHBhcmFtcyA9ICdpbnQgYiwgaW50IHJvdywgaW50IGNvbCc7XG4gICAgbGV0IGluZGV4ID0gYGIgKiAke3RleGVsc0luQmF0Y2h9ICsgKHJvdyAvIDIpICogJHt2YWx1ZXNQZXJSb3d9ICsgKGNvbCAvIDIpYDtcbiAgICBmb3IgKGxldCBiID0gMjsgYiA8IHJhbmsgLSAxOyBiKyspIHtcbiAgICAgIHBhcmFtcyA9IGBpbnQgYiR7Yn0sIGAgKyBwYXJhbXM7XG4gICAgICB0ZXhlbHNJbkJhdGNoICo9IHNoYXBlW3JhbmsgLSBiIC0gMV07XG4gICAgICBpbmRleCA9IGBiJHtifSAqICR7dGV4ZWxzSW5CYXRjaH0gKyBgICsgaW5kZXg7XG4gICAgfVxuICAgIGNvbnN0IHBhY2tlZFNhbXBsZXIgPSBgdmVjNCAke2Z1bmNOYW1lfSgke3BhcmFtc30pIHtcbiAgICAgIGludCBpbmRleCA9ICR7aW5kZXh9O1xuICAgICAgaW50IHRleFIgPSBpbmRleCAvICR7dGV4TnVtQ307XG4gICAgICBpbnQgdGV4QyA9IGluZGV4IC0gdGV4UiAqICR7dGV4TnVtQ307XG4gICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMigke3RleE51bUN9LCAke3RleE51bVJ9KTtcbiAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7XG4gICAgfWA7XG4gICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgc2NhbGFyIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyU2NhbGFyKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgW3RleE51bVIsIHRleE51bUNdID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGlmICh0ZXhOdW1SID09PSAxICYmIHRleE51bUMgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIGhhbGZDUik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAgIGludCBvZmZzZXRfJHtuYW1lfSA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSk7XG4gICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgb2Zmc2V0XyR7bmFtZX0pO1xuICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgW1xuICAgICAgJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLFxuICAgICAgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLFxuICAgICAgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0JyxcbiAgICBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAxRCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjFEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgdE51bVIgPSBpbnB1dExheW91dC53aWR0aDtcbiAgICBjb25zdCB0TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcblxuICAgIGlmICh0TnVtQyA9PT0gMSAmJiB0TnVtUiA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCBoYWxmQ1IpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBpZiAodE51bUMgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKChmbG9hdChpbmRleCkgKyAwLjUpIC8gJHt0TnVtUn0uMCwgMC41KTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cbiAgICBpZiAodE51bVIgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKDAuNSwgKGZsb2F0KGluZGV4KSArIDAuNSkgLyAke3ROdW1DfS4wKTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCBpbmRleCkge1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dE51bVJ9LCAke3ROdW1DfSwgaW5kZXgpO1xuICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy51dkZyb21GbGF0JywgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgMkQgc25pcHBldC5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuXG4gICAgLy8gVE9ETzogbW9kaWZ5IHJvdy9jb2wgb3JkZXIgZm9yIG90aGVyIGRpbWVuc2lvbnMuXG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQuaGVpZ2h0LCBpbnB1dExheW91dC53aWR0aF07XG5cbiAgICBpZiAodGV4U2hhcGUgIT0gbnVsbCAmJiBBcnJheVV0aWwuYXJyYXlzRXF1YWwoc2hhcGUsIHRleFNoYXBlKSkge1xuICAgICAgY29uc3QgdGV4TnVtUiA9IHRleFNoYXBlWzFdO1xuICAgICAgY29uc3QgdGV4TnVtQyA9IHRleFNoYXBlWzBdO1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIHZlYzIgdXYgPSAodmVjMihyb3csIGNvbCkgKyBoYWxmQ1IpIC8gdmVjMigke3RleE51bVJ9LjAsICR7dGV4TnVtQ30uMCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IG5ld1NoYXBlLCBrZXB0RGltcyB9ID0gc3F1ZWV6ZVNoYXBlKHNoYXBlIGFzIG51bWJlcltdKTtcbiAgICBjb25zdCBzcXVlZXplZFNoYXBlID0gbmV3U2hhcGU7XG4gICAgaWYgKHNxdWVlemVkU2hhcGUubGVuZ3RoIDwgc2hhcGUubGVuZ3RoKSB7XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIHNxdWVlemVkU2hhcGUpO1xuICAgICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcblxuICAgICAgY29uc3QgcGFyYW1zID0gWydjb2wnLCAncm93J107XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgJHt0aGlzLmdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgbmFtZSwgbmV3SW5wdXRMYXlvdXQpLnJvdXRpbmVCb2R5fVxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIHJldHVybiAke2Z1bmNOYW1lfSgke2dldFNxdWVlemVkUGFyYW1zKHBhcmFtcywga2VwdERpbXMpfSk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gdGV4U2hhcGVbMV07XG4gICAgY29uc3QgdGV4TnVtQyA9IHRleFNoYXBlWzBdO1xuICAgIGlmICh0ZXhOdW1DID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICAgICAgaW50IG9mZnNldF8ke25hbWV9ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke3RleE51bVJ9LCAke3RleE51bUN9KTtcbiAgICAgICAgICAgIGZsb2F0IGluZGV4ID0gZG90KHZlYzMocm93LCBjb2wsIG9mZnNldF8ke25hbWV9KSwgdmVjMygke3NoYXBlWzFdfSwgMSwgMSkpO1xuICAgICAgICAgICAgdmVjMiB1diA9IHZlYzIoMC41LCAoaW5kZXggKyAwLjUpIC8gJHt0ZXhOdW1SfS4wKTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0J10pO1xuICAgIH1cblxuICAgIGlmICh0ZXhOdW1SID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICAgICAgaW50IG9mZnNldF8ke25hbWV9ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke3RleE51bVJ9LCAke3RleE51bUN9KTtcbiAgICAgICAgICAgIGZsb2F0IGluZGV4ID0gZG90KHZlYzMocm93LCBjb2wsIG9mZnNldF8ke25hbWV9KSwgdmVjMygke3NoYXBlWzFdfSwgMSwgMSkpO1xuICAgICAgICAgICAgdmVjMiB1diA9IHZlYzIoKGluZGV4ICsgMC41KSAvICR7dGV4TnVtQ30uMCwgMC41KTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0J10pO1xuICAgIH1cblxuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICAgIGludCBpbmRleCA9IGNvbCAqICR7c2hhcGVbMV19ICsgcm93O1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFtcbiAgICAgICdjb29yZGluYXRlcy51dkZyb21GbGF0JyxcbiAgICAgICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJyxcbiAgICAgICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCcsXG4gICAgXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgM0Qgc25pcHBldC5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHN0cmlkZTAgPSBzaGFwZVsxXSAqIHNoYXBlWzJdO1xuICAgIGNvbnN0IHN0cmlkZTEgPSBzaGFwZVsyXTtcblxuICAgIGNvbnN0IHsgbmV3U2hhcGUsIGtlcHREaW1zIH0gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIGNvbnN0IHNxdWVlemVkU2hhcGUgPSBuZXdTaGFwZTtcbiAgICBpZiAoc3F1ZWV6ZWRTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgc3F1ZWV6ZWRTaGFwZSk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBbJ2JhdGNoJywgJ2NvbCcsICdyb3cnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG4gICAgICBjb25zdCByb3V0aW5lID0gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KTtcbiAgICAgIC8vIFRPRE86IHJldmlzaXQgdGhlIGxvZ2ljIGhlcmUgdG8gbWFrZSBpdCBzaW1wbGVyXG4gICAgICBjb25zdCByZXZEaW1zID0ga2VwdERpbXMucmV2ZXJzZSgpO1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgICR7cm91dGluZS5yb3V0aW5lQm9keX1cbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgYmF0Y2gsIGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIHJldHVybiAke2Z1bmNOYW1lfSgke2dldFNxdWVlemVkUGFyYW1zKHBhcmFtcywgcmV2RGltcyl9KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgcm91dGluZS5kZXBlbmRlbmNpZXMpO1xuICAgIH1cblxuICAgIGNvbnN0IHRleE51bVIgPSBpbnB1dExheW91dC53aWR0aDtcbiAgICBjb25zdCB0ZXhOdW1DID0gaW5wdXRMYXlvdXQuaGVpZ2h0O1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgZGVwdGgsIGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIC8vIEV4cGxpY2l0bHkgdXNlIGludGVnZXIgb3BlcmF0aW9ucyBhcyBkb3QoKSBvbmx5IHdvcmtzIG9uIGZsb2F0cy5cbiAgICAgICAgICAgIGludCBpbmRleCA9IGRlcHRoICogJHtzdHJpZGUwfSArIGNvbCAqICR7c3RyaWRlMX0gKyByb3c7XG4gICAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RleE51bVJ9LCAke3RleE51bUN9LCBpbmRleCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgW1xuICAgICAgJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLFxuICAgICAgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLFxuICAgICAgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0JyxcbiAgICBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA0RCBzbmlwcGV0LlxuICAgKi9cblxuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyNEQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlMiA9IHNoYXBlWzNdO1xuICAgIGNvbnN0IHN0cmlkZTEgPSBzaGFwZVsyXSAqIHN0cmlkZTI7XG4gICAgY29uc3Qgc3RyaWRlMCA9IHNoYXBlWzFdICogc3RyaWRlMTtcblxuICAgIC8vXG4gICAgLy8gVE9ETzogcmUtZW5hYmxlIHRoaXMgc2hvcnRjdXQgb25jZSB0aGUgaW5kZXggY2FsY3VsYXRpb24gYnVnIGlzIGZpeGVkLlxuICAgIC8vXG4gICAgLy8gY29uc3Qge25ld1NoYXBlLCBrZXB0RGltc30gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIC8vIGlmIChuZXdTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAvLyAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgbmV3U2hhcGUpO1xuICAgIC8vICAgY29uc3QgcGFyYW1zID0gWydyb3cnLCAnY29sJywgJ2RlcHRoJywgJ2RlcHRoMiddO1xuICAgIC8vICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgIC8vICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgLy8gICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcbiAgICAvLyAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAvLyAgICAgICAke3RoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCkucm91dGluZUJvZHl9XG4gICAgLy8gICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyKSB7XG4gICAgLy8gICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgIC8vICAgICAgIH1cbiAgICAvLyAgICAgYDtcbiAgICAvLyAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgLy8gICAgICAgc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLCAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgICAvLyB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMikge1xuICAgICAgICAgIGludCBpbmRleCA9IHJvdyAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICtcbiAgICAgICAgICAgICAgZGVwdGgyICogJHtzdHJpZGUyfSArIGRlcHRoO1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDVEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyNUQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlMyA9IHNoYXBlWzRdO1xuICAgIGNvbnN0IHN0cmlkZTIgPSBzaGFwZVszXSAqIHN0cmlkZTM7XG4gICAgY29uc3Qgc3RyaWRlMSA9IHNoYXBlWzJdICogc3RyaWRlMjtcbiAgICBjb25zdCBzdHJpZGUwID0gc2hhcGVbMV0gKiBzdHJpZGUxO1xuXG4gICAgY29uc3QgeyBuZXdTaGFwZSwga2VwdERpbXMgfSA9IHNxdWVlemVTaGFwZShzaGFwZSBhcyBudW1iZXJbXSk7XG4gICAgaWYgKG5ld1NoYXBlLmxlbmd0aCA8IHNoYXBlLmxlbmd0aCkge1xuICAgICAgY29uc3QgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVJbnB1dFNoYXBlKHNoYXBlLCBuZXdTaGFwZSk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBbJ3JvdycsICdjb2wnLCAnZGVwdGgnLCAnZGVwdGgyJywgJ2RlcHRoMyddO1xuICAgICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcblxuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgICR7dGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KS5yb3V0aW5lQm9keX1cbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIsIGludCBkZXB0aDMpIHtcbiAgICAgICAgICAgIHJldHVybiAke2Z1bmNOYW1lfSgke2dldFNxdWVlemVkUGFyYW1zKHBhcmFtcywga2VwdERpbXMpfSk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy51dkZyb21GbGF0J10pO1xuICAgIH1cblxuICAgIGNvbnN0IHRleE51bVIgPSBpbnB1dExheW91dC53aWR0aDtcbiAgICBjb25zdCB0ZXhOdW1DID0gaW5wdXRMYXlvdXQuaGVpZ2h0O1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzKSB7XG4gICAgICAgICAgaW50IGluZGV4ID0gcm93ICogJHtzdHJpZGUwfSArIGNvbCAqICR7c3RyaWRlMX0gKyBkZXB0aCAqICR7c3RyaWRlMn0gK1xuICAgICAgICAgIGRlcHRoMyAqICR7c3RyaWRlM30gKyBkZXB0aDI7XG4gICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgaW5kZXgpO1xuICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgNkQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXI2RChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBzdHJpZGU0ID0gc2hhcGVbNV07XG4gICAgY29uc3Qgc3RyaWRlMyA9IHNoYXBlWzRdICogc3RyaWRlNDtcbiAgICBjb25zdCBzdHJpZGUyID0gc2hhcGVbM10gKiBzdHJpZGUzO1xuICAgIGNvbnN0IHN0cmlkZTEgPSBzaGFwZVsyXSAqIHN0cmlkZTI7XG4gICAgY29uc3Qgc3RyaWRlMCA9IHNoYXBlWzFdICogc3RyaWRlMTtcblxuICAgIGNvbnN0IHsgbmV3U2hhcGUsIGtlcHREaW1zIH0gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIGlmIChuZXdTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgbmV3U2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydyb3cnLCAnY29sJywgJ2RlcHRoJywgJ2RlcHRoMicsICdkZXB0aDMnLCAnZGVwdGg0J107XG4gICAgICAvLyBEZWVwIGNvcHkgb2YgaW5wdXQgdGV4dHVyZSBsYXlvdXQuXG4gICAgICBjb25zdCBuZXdJbnB1dExheW91dDogVGV4dHVyZUxheW91dCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaW5wdXRMYXlvdXQpKTtcbiAgICAgIG5ld0lucHV0TGF5b3V0LnVucGFja2VkU2hhcGUgPSBuZXdJbnB1dFNoYXBlO1xuXG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgICAke3RoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCkucm91dGluZUJvZHl9XG4gICAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsXG4gICAgICAgICAgICAgIGludCBkZXB0aDIsIGludCBkZXB0aDMsIGludCBkZXB0aDQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuICR7ZnVuY05hbWV9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMocGFyYW1zLCBrZXB0RGltcyl9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy51dkZyb21GbGF0J10pO1xuICAgIH1cblxuICAgIGNvbnN0IHRleE51bVIgPSBpbnB1dExheW91dC53aWR0aDtcbiAgICBjb25zdCB0ZXhOdW1DID0gaW5wdXRMYXlvdXQuaGVpZ2h0O1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsXG4gICAgICAgICAgICBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzLCBpbnQgZGVwdGg0KSB7XG4gICAgICAgICAgICBpbnQgaW5kZXggPSByb3cgKiAke3N0cmlkZTB9ICsgY29sICogJHtzdHJpZGUxfSArIGRlcHRoICogJHtzdHJpZGUyfSArXG4gICAgICAgICAgICBkZXB0aDIgKiAke3N0cmlkZTN9ICsgZGVwdGgzICogJHtzdHJpZGU0fSArIGRlcHRoNDtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFtcbiAgICAgICdjb29yZGluYXRlcy51dkZyb21GbGF0JyxcbiAgICAgICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJyxcbiAgICAgICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCcsXG4gICAgXSk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyB0aGUgbWFpbiBmdW5jdGlvbiB0byBtYXAgZnJvbSB0aGUgZ2l2ZW4gdGV4dHVyZSBjb29yZGluYXRlcyAocyx0KVxuICAgKiB0byBsb2dpY2FsIGluZGljZXMgZm9yIHRoZSBvdXRwdXRcbiAgICogVGhlcmUgd2lsbCBvbmx5IGJlIG9uZSBzaW5nbGUgdmFyaWF0aW9uIG9mIHRoaXNcbiAgICogQWxzbyBzZWUgY29vcmRzVG9PZmZzZXQgYW5kIG9mZnNldFRvSW5kaWNlcyBmb3IgaW5wdXQtc3BlY2lmaWMgdmVyc2lvbnNcbiAgICovXG4gIHByb3RlY3RlZCB0b1ZlYygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBjb25zdCByYW5rID0gb3V0cHV0LnNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBzdHJpZGVzID0gb3V0cHV0LnN0cmlkZXM7XG4gICAgY29uc3QgeFNjYWxlID0gb3V0cHV0LndpZHRoO1xuICAgIGNvbnN0IHlTY2FsZSA9IG91dHB1dC5oZWlnaHQ7XG5cbiAgICBjb25zdCBzdHJpZGVzQmxvY2sgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAxOyArK2kpIHtcbiAgICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgICAgY1ske2l9XSA9IG9mZnNldCAvICR7c3RyaWRlc1tpXX07YCk7XG4gICAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICAgIG9mZnNldCAtPSBjWyR7aX1dICogJHtzdHJpZGVzW2ldfTtgKTtcbiAgICB9XG4gICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgICBjWyR7cmFuayAtIDF9XSA9IG9mZnNldDtgKTtcbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgdm9pZCB0b1ZlYyh2ZWMyIHRleENvb3Jkcywgb3V0IGludCBjWyR7cmFua31dKSB7XG4gICAgICAgIGludCBvZmZzZXQgPSBjb29yZHNUb09mZnNldCh0ZXhDb29yZHMsICR7eFNjYWxlfSwgJHt5U2NhbGV9KTtcbiAgICAgICAgJHtzdHJpZGVzQmxvY2suam9pbignJyl9XG4gICAgICB9XG4gICAgICB2b2lkIHRvVmVjKGludCBvZmZzZXQsIG91dCBpbnQgY1ske3Jhbmt9XSkge1xuICAgICAgICAke3N0cmlkZXNCbG9jay5qb2luKCcnKX1cbiAgICAgIH1cbiAgICBgO1xuICAgIHJldHVybiB7IHRvVmVjOiBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSwgWydjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKSB9O1xuICB9XG4gIC8qKlxuICAgKiBUaGVzZSBhcmUgdmFsdWUgZ2V0dGVyIGZ1bmN0aW9ucyBnZW5lcmF0ZWQgZm9yIGVhY2ggaW5wdXRcbiAgICogRWFjaCBmdW5jdGlvbiBpcyBoYXJkd2lyZWQgdG8gdGhlIG5hbWUgYW5kIGRpbWVuc2lvbnMgb2YgdGhlIGlucHV0XG4gICAqIEFuICdfVCcgdmFyaWF0aW9uIGlzIGFsc28gcHJvZHVjZWQgd2hpY2ggYWNjZXNzZXMgdmFsdWVzIGFzIGlmIHRoZVxuICAgKiBpbnB1dCB3YXMgdHJhbnNwb3NlZFxuICAgKi9cbiAgcHJvdGVjdGVkIHZhbHVlRnJvbSgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBsYXlvdXQgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXTtcbiAgICAgIGNvbnN0IHNoYXBlID0gbGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoID4gMCA/IGxheW91dC51bnBhY2tlZFNoYXBlIDogbGF5b3V0LnNoYXBlO1xuICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgIGxldCBmdW5jTmFtZSA9IGBfJHtuYW1lfWA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKHRoaXMuZ2V0VmFsdWVGcm9tU2luZ2xlKG5hbWUsIHJhbmssIGxheW91dC53aWR0aCwgbGF5b3V0LmhlaWdodCwgZmFsc2UpLCBbXG4gICAgICAgIGBzaGFwZVV0aWxzLmluZGljZXNUb09mZnNldCR7ZnVuY05hbWV9YCxcbiAgICAgICAgJ2Nvb3JkaW5hdGVzLm9mZnNldFRvQ29vcmRzJyxcbiAgICAgICAgJ2ZyYWdjb2xvci5nZXRDb2xvckFzRmxvYXQnLFxuICAgICAgXSk7XG4gICAgICBmdW5jTmFtZSA9IGZ1bmNOYW1lICsgJ19UJztcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUodGhpcy5nZXRWYWx1ZUZyb21TaW5nbGUobmFtZSwgcmFuaywgbGF5b3V0LndpZHRoLCBsYXlvdXQuaGVpZ2h0LCB0cnVlKSwgW1xuICAgICAgICBgc2hhcGVVdGlscy5pbmRpY2VzVG9PZmZzZXQke2Z1bmNOYW1lfWAsXG4gICAgICAgICdjb29yZGluYXRlcy5vZmZzZXRUb0Nvb3JkcycsXG4gICAgICAgICdmcmFnY29sb3IuZ2V0Q29sb3JBc0Zsb2F0JyxcbiAgICAgIF0pO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgLyoqXG4gICAqIFByb2R1Y2VzIG9uZSB2YWx1ZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIHRoZSBuYW1lIGFuZCByYW5rIGdpdmVuXG4gICAqIElmIGEgdHJhbnNwb3NlIGlzIHNldCBwcm9wZXIgb2Zmc2V0VG9Db29yZHMgbWFwcGluZyB3aWxsIGJlIHVzZWRcbiAgICogQHBhcmFtIG5hbWUgbmFtZSBvZiB0aGUgZnVuY3Rpb25cbiAgICogQHBhcmFtIHJhbmsgcmFuayBvZiB0aGUgaW5wdXRcbiAgICogQHBhcmFtIHRyYW5zcG9zZSB3aGV0aGVyIG9yIG5vdCBzaG91bGQgZ2VuZXJhdGUgYSB0cmFuc3Bvc2UgdmFyaWF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VmFsdWVGcm9tU2luZ2xlKFxuICAgIHZhck5hbWU6IHN0cmluZyxcbiAgICByYW5rOiBudW1iZXIsXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICB0cmFuc3Bvc2U6IGJvb2xlYW4sXG4gICk6IHN0cmluZyB7XG4gICAgbGV0IG5hbWUgPSBgXyR7dmFyTmFtZX1gO1xuICAgIGlmICh0cmFuc3Bvc2UpIHtcbiAgICAgIG5hbWUgPSBuYW1lICsgJ19UJztcbiAgICB9XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICByZXR1cm4gYFxuICAgICAgICBmbG9hdCAke25hbWV9KGludCBtWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IG9mZnNldCA9IGluZGljZXNUb09mZnNldCR7bmFtZX0obSk7XG4gICAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhvZmZzZXQsICR7d2lkdGh9LCAke2hlaWdodH0pO1xuICAgICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KCR7dmFyTmFtZX0sIGNvb3JkcykpO1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBgO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2R1Y2VzIGEgcGFja2VkIHZhbHVlIGdldHRlciBmdW5jdGlvbiBmb3IgdGhlIG5hbWUgYW5kIHJhbmsgZ2l2ZW5cbiAgICogSWYgYSB0cmFuc3Bvc2UgaXMgc2V0IHByb3BlciBvZmZzZXRUb0Nvb3JkcyBtYXBwaW5nIHdpbGwgYmUgdXNlZFxuICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9mIHRoZSBmdW5jdGlvblxuICAgKiBAcGFyYW0gcmFuayByYW5rIG9mIHRoZSBpbnB1dFxuICAgKiBAcGFyYW0gdHJhbnNwb3NlIHdoZXRoZXIgb3Igbm90IHNob3VsZCBnZW5lcmF0ZSBhIHRyYW5zcG9zZSB2YXJpYXRpb25cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRWYWx1ZUZyb20oXG4gICAgdmFyTmFtZTogc3RyaW5nLFxuICAgIHJhbms6IG51bWJlcixcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIHRyYW5zcG9zZTogYm9vbGVhbixcbiAgKTogc3RyaW5nIHtcbiAgICBsZXQgbmFtZSA9IGBfJHt2YXJOYW1lfV9QYWNrYDtcbiAgICBpZiAodHJhbnNwb3NlKSB7XG4gICAgICBuYW1lID0gbmFtZSArICdfVCc7XG4gICAgfVxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgcmV0dXJuIGBcbiAgICAgICAgdmVjNCAke25hbWV9KGludCBtWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IG9mZnNldCA9IGluZGljZXNUb09mZnNldF8ke3Zhck5hbWV9KG0pO1xuICAgICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHt2YXJOYW1lfSwgY29vcmRzKTtcbiAgICAgICAgfVxuICAgICAgICBgO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZSB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5cbi8qKlxuICogVGhpcyBHTFNMIGxpYnJhcnkgaGFuZGxlcyByb3V0aW5lcyBjb252ZXJ0aW5nXG4gKiBmbG9hdDMyIHRvL2Zyb20gVW5zaWduZWQgYnl0ZSBvciBmbG9hdCAxNlxuICovXG5leHBvcnQgY2xhc3MgRW5jb2RpbmdHbHNsTGliIGV4dGVuZHMgR2xzbExpYiB7XG4gIGNvbnN0cnVjdG9yKGNvbnRleHQ6IEdsc2xDb250ZXh0KSB7XG4gICAgc3VwZXIoY29udGV4dCk7XG4gIH1cbiAgZ2V0RnVuY3Rpb25zKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7IC4uLnRoaXMuZW5jb2RlRmxvYXQzMigpLCAuLi50aGlzLmRlY29kZUZsb2F0MzIoKSB9O1xuICB9XG4gIGdldEN1c3RvbVR5cGVzKCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgcHJvdGVjdGVkIGVuY29kZUZsb2F0MzIoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVuY29kZTogbmV3IEdsc2xMaWJSb3V0aW5lKGBoaWdocCB2ZWM0IGVuY29kZShoaWdocCBmbG9hdCBmKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KGYsIDAuMCwgMC4wLCAwLjApO1xuICAgICAgfVxuICAgICAgICBgKSxcbiAgICB9O1xuICB9XG4gIHByb3RlY3RlZCBkZWNvZGVGbG9hdDMyKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7XG4gICAgICBkZWNvZGU6IG5ldyBHbHNsTGliUm91dGluZShgaGlnaHAgZmxvYXQgZGVjb2RlKGhpZ2hwIHZlYzQgcmdiYSkge1xuICAgICAgICByZXR1cm4gcmdiYS5yO1xuICAgICAgfVxuICAgICAgICBgKSxcbiAgICB9O1xuICB9XG4gIC8qKlxuICAgKiByZXR1cm5zIHRoZSByb3V0aW5lIHRvIGVuY29kZSBlbmNvZGUgYSAzMmJpdCBmbG9hdCB0byBhIHZlYzQgKG9mIHVuc2lnbmVkIGJ5dGVzKVxuICAgKiBAY3JlZGl0OiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy83MDU5OTYyL2hvdy1kby1pLWNvbnZlcnQtYS12ZWM0LXJnYmEtdmFsdWUtdG8tYS1mbG9hdFxuICAgKi9cbiAgcHJvdGVjdGVkIGVuY29kZVVpbnQ4KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IGVuZGlhbm5lc3MgPSBFbmNvZGluZ0dsc2xMaWIuaXNMaXR0bGVFbmRpYW4oKSA/ICdyZ2JhLnJnYmE9cmdiYS5hYmdyOycgOiAnJztcbiAgICByZXR1cm4ge1xuICAgICAgZW5jb2RlOiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgaGlnaHAgdmVjNCBlbmNvZGUoaGlnaHAgZmxvYXQgZikge1xuICAgICAgICBoaWdocCBmbG9hdCBGID0gYWJzKGYpO1xuICAgICAgICBoaWdocCBmbG9hdCBTaWduID0gc3RlcCgwLjAsLWYpO1xuICAgICAgICBoaWdocCBmbG9hdCBFeHBvbmVudCA9IGZsb29yKGxvZzIoRikpO1xuICAgICAgICBoaWdocCBmbG9hdCBNYW50aXNzYSA9IChleHAyKC0gRXhwb25lbnQpICogRik7XG4gICAgICAgIEV4cG9uZW50ID0gZmxvb3IobG9nMihGKSArIDEyNy4wKSArIGZsb29yKGxvZzIoTWFudGlzc2EpKTtcbiAgICAgICAgaGlnaHAgdmVjNCByZ2JhO1xuICAgICAgICByZ2JhWzBdID0gMTI4LjAgKiBTaWduICArIGZsb29yKEV4cG9uZW50KmV4cDIoLTEuMCkpO1xuICAgICAgICByZ2JhWzFdID0gMTI4LjAgKiBtb2QoRXhwb25lbnQsMi4wKSArIG1vZChmbG9vcihNYW50aXNzYSoxMjguMCksMTI4LjApO1xuICAgICAgICByZ2JhWzJdID0gZmxvb3IobW9kKGZsb29yKE1hbnRpc3NhKmV4cDIoMjMuMCAtOC4wKSksZXhwMig4LjApKSk7XG4gICAgICAgIHJnYmFbM10gPSBmbG9vcihleHAyKDIzLjApKm1vZChNYW50aXNzYSxleHAyKC0xNS4wKSkpO1xuICAgICAgICAke2VuZGlhbm5lc3N9XG4gICAgICAgIHJnYmEgPSByZ2JhIC8gMjU1LjA7IC8vIHZhbHVlcyBuZWVkIHRvIGJlIG5vcm1hbGl6ZWQgdG8gWzAsMV1cbiAgICAgICAgcmV0dXJuIHJnYmE7XG4gICAgfVxuICAgICAgICBgKSxcbiAgICB9O1xuICB9XG4gIC8qKlxuICAgKiByZXR1cm5zIHRoZSByb3V0aW5lIHRvIGVuY29kZSBhIHZlYzQgb2YgdW5zaWduZWQgYnl0ZXMgdG8gZmxvYXQzMlxuICAgKiBAY3JlZGl0OiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy83MDU5OTYyL2hvdy1kby1pLWNvbnZlcnQtYS12ZWM0LXJnYmEtdmFsdWUtdG8tYS1mbG9hdFxuICAgKi9cbiAgcHJvdGVjdGVkIGRlY29kZVVpbnQ4KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IGVuZGlhbm5lc3MgPSBFbmNvZGluZ0dsc2xMaWIuaXNMaXR0bGVFbmRpYW4oKSA/ICdyZ2JhLnJnYmE9cmdiYS5hYmdyOycgOiAnJztcbiAgICByZXR1cm4ge1xuICAgICAgZGVjb2RlOiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgICBoaWdocCBmbG9hdCBkZWNvZGUoaGlnaHAgdmVjNCByZ2JhKSB7XG4gICAgICAgICAgcmdiYSA9IHJnYmEgKiAyNTUuMDsgLy8gdmFsdWVzIG5lZWQgdG8gYmUgZGUtbm9ybWFsaXplZCBmcm9tIFswLDFdIHRvIFswLDI1NV1cbiAgICAgICAgICAke2VuZGlhbm5lc3N9XG4gICAgICAgICAgaGlnaHAgZmxvYXQgU2lnbiA9IDEuMCAtIHN0ZXAoMTI4LjAscmdiYVswXSkqMi4wO1xuICAgICAgICAgIGhpZ2hwIGZsb2F0IEV4cG9uZW50ID0gMi4wICogbW9kKHJnYmFbMF0sMTI4LjApICsgc3RlcCgxMjguMCxyZ2JhWzFdKSAtIDEyNy4wO1xuICAgICAgICAgIGhpZ2hwIGZsb2F0IE1hbnRpc3NhID0gbW9kKHJnYmFbMV0sMTI4LjApKjY1NTM2LjAgKyByZ2JhWzJdKjI1Ni4wICtyZ2JhWzNdICsgZmxvYXQoMHg4MDAwMDApO1xuICAgICAgICAgIGhpZ2hwIGZsb2F0IFJlc3VsdCA9ICBTaWduICogZXhwMihFeHBvbmVudCkgKiAoTWFudGlzc2EgKiBleHAyKC0yMy4wICkpO1xuICAgICAgICAgIHJldHVybiBSZXN1bHQ7XG4gICAgICB9XG4gICAgICAgIGApLFxuICAgIH07XG4gIH1cbiAgLyoqXG4gICAqIERldGVybWluZXMgaWYgdGhlIG1hY2hpbmUgaXMgbGl0dGxlIGVuZGlhbiBvciBub3RcbiAgICogQGNyZWRpdDogaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vVG9vVGFsbE5hdGUvNDc1MDk1M1xuICAgKi9cbiAgc3RhdGljIGlzTGl0dGxlRW5kaWFuKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGIgPSBuZXcgQXJyYXlCdWZmZXIoNCk7XG4gICAgY29uc3QgYSA9IG5ldyBVaW50MzJBcnJheShiKTtcbiAgICBjb25zdCBjID0gbmV3IFVpbnQ4QXJyYXkoYik7XG4gICAgYVswXSA9IDB4ZGVhZGJlZWY7XG4gICAgaWYgKGNbMF0gPT09IDB4ZWYpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoY1swXSA9PT0gMHhkZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gZW5kaWFubmVzcycpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZSB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi9nbHNsLXNvdXJjZSc7XG5cbi8qKlxuICogVGhpcyBHTFNMIGxpYnJhcnkgaGFuZGxlcyByb3V0aW5lcyBhcm91bmQgcmVhZGluZyBhIHRleGxldCBhbmQgd3JpdGluZyB0byBpdFxuICogUmVhZGluZyBhbmQgd3JpdGluZyBjb3VsZCBiZSBtb3JlIHRoYW4ganVzdCBkZWFsaW5nIHdpdGggb25lIGNoYW5uZWxcbiAqIEl0IG1heSByZXF1aXJlIGVuY29kaW5nL2RlY29kaW5nIHRvL2Zyb20gNCBjaGFubmVscyBpbnRvIG9uZVxuICovXG5leHBvcnQgY2xhc3MgRnJhZ0NvbG9yR2xzbExpYiBleHRlbmRzIEdsc2xMaWIge1xuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBHbHNsQ29udGV4dCkge1xuICAgIHN1cGVyKGNvbnRleHQpO1xuICB9XG4gIGdldEZ1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4geyAuLi50aGlzLnNldEZyYWdDb2xvcigpLCAuLi50aGlzLmdldENvbG9yQXNGbG9hdCgpIH07XG4gIH1cbiAgZ2V0Q3VzdG9tVHlwZXMoKTogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBwcm90ZWN0ZWQgc2V0RnJhZ0NvbG9yKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldEZyYWdDb2xvcjogbmV3IEdsc2xMaWJSb3V0aW5lKFxuICAgICAgICBgXG4gICAgICAgIHZvaWQgc2V0RnJhZ0NvbG9yKGZsb2F0IHZhbHVlKSB7XG4gICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IGVuY29kZSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgYCxcbiAgICAgICAgWydlbmNvZGluZy5lbmNvZGUnXSxcbiAgICAgICksXG4gICAgfTtcbiAgfVxuICBwcm90ZWN0ZWQgZ2V0Q29sb3JBc0Zsb2F0KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7XG4gICAgICBnZXRDb2xvckFzRmxvYXQ6IG5ldyBHbHNsTGliUm91dGluZShcbiAgICAgICAgYFxuICAgICAgICBmbG9hdCBnZXRDb2xvckFzRmxvYXQodmVjNCBjb2xvcikge1xuICAgICAgICAgICAgcmV0dXJuIGRlY29kZShjb2xvcik7XG4gICAgICAgIH1cbiAgICAgICAgYCxcbiAgICAgICAgWydlbmNvZGluZy5kZWNvZGUnXSxcbiAgICAgICksXG4gICAgfTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmUgfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuXG4vKipcbiAqIEdMU0wgTGlicmFyeSByZXNwb25zaWJsZSBmb3IgZGF0YSB0eXBlcyBhbmQgcm91dGluZXMgZm9yIG1hbmlwdWxhdGluZ1xuICogY29vcmRpbmF0ZXMgYW5kIG1hcHBpbmcgdG8vZnJvbSB0ZW5zb3IgaW5kaWNlc1xuICovXG5leHBvcnQgY2xhc3MgU2hhcGVVdGlsc0dsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuYmNhc3RJbmRleCgpLFxuICAgICAgLi4udGhpcy5iY2FzdE1hdG11bEluZGV4KCksXG4gICAgICAuLi50aGlzLm9mZnNldFRvSW5kaWNlcygpLFxuICAgICAgLi4udGhpcy5pbmRpY2VzVG9PZmZzZXQoKSxcbiAgICAgIC4uLnRoaXMuaW5jcmVtZW50SW5kaWNlcygpLFxuICAgIH07XG4gIH1cbiAgZ2V0Q3VzdG9tVHlwZXMoKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIHByb3RlY3RlZCBiY2FzdEluZGV4KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dHB1dFJhbmsgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3Qgc2hhcGUgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS51bnBhY2tlZFNoYXBlO1xuICAgICAgaWYgKHNoYXBlLmxlbmd0aCA8PSBvdXRwdXRSYW5rKSB7XG4gICAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGRpbU9mZnNldCA9IG91dHB1dFJhbmsgLSByYW5rO1xuICAgICAgICBjb25zdCBmdW5jTmFtZSA9IGBiY2FzdEluZGljZXNfJHtuYW1lfWA7XG4gICAgICAgIGxldCBibG9jayA9ICcnO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7ICsraSkge1xuICAgICAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgICByZWFsSW5kaWNlc1ske2l9XSA9IGludCggbW9kKGZsb2F0KGJjYXN0ZWRJbmRpY2VzWyR7ZGltT2Zmc2V0ICsgaX1dKSwgJHtzaGFwZVtpXX0uMCkgKTtcbiAgICAgICAgICBgO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICAgIHZvaWQgJHtmdW5jTmFtZX0gKGludCBiY2FzdGVkSW5kaWNlc1ske291dHB1dFJhbmt9XSwgb3V0IGludCByZWFsSW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgICR7YmxvY2t9XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShib2R5KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHByb3RlY3RlZCBiY2FzdE1hdG11bEluZGV4KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dHB1dFJhbmsgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3Qgc2hhcGUgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS5zaGFwZTtcbiAgICAgIGlmICghKHNoYXBlLmxlbmd0aCA8IDIgfHwgc2hhcGUubGVuZ3RoID4gb3V0cHV0UmFuaykpIHtcbiAgICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgICAgY29uc3QgZGltT2Zmc2V0ID0gb3V0cHV0UmFuayAtIHJhbms7XG4gICAgICAgIGNvbnN0IGZ1bmNOYW1lID0gYGJjYXN0TWF0bXVsSW5kaWNlc18ke25hbWV9YDtcbiAgICAgICAgbGV0IGJsb2NrID0gJyc7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDI7ICsraSkge1xuICAgICAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgICByZWFsSW5kaWNlc1ske2l9XSA9IGludCggbW9kKGZsb2F0KGJjYXN0ZWRJbmRpY2VzWyR7ZGltT2Zmc2V0ICsgaX1dKSwgJHtzaGFwZVtpXX0uMCkgKTtcbiAgICAgICAgICBgO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICAgIHZvaWQgJHtmdW5jTmFtZX0oaW50IGJjYXN0ZWRJbmRpY2VzWyR7b3V0cHV0UmFua31dLCBvdXQgaW50IHJlYWxJbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgJHtibG9ja31cbiAgICAgICAgICByZWFsSW5kaWNlc1ske3JhbmsgLSAxfV0gPSBiY2FzdGVkSW5kaWNlc1ske291dHB1dFJhbmsgLSAxfV07XG4gICAgICAgICAgcmVhbEluZGljZXNbJHtyYW5rIC0gMn1dID0gYmNhc3RlZEluZGljZXNbJHtvdXRwdXRSYW5rIC0gMn1dO1xuICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBwcm90ZWN0ZWQgaW5kaWNlc1RvT2Zmc2V0KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc2hhcGU7XG4gICAgICBjb25zdCBzdHJpZGVzID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc3RyaWRlcztcbiAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICBsZXQgZnVuY05hbWUgPSBgaW5kaWNlc1RvT2Zmc2V0XyR7bmFtZX1gO1xuICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShTaGFwZVV0aWxzR2xzbExpYi5pbmRleFRvT2Zmc2V0U2luZ2xlKGZ1bmNOYW1lLCByYW5rLCBzdHJpZGVzKSk7XG4gICAgICBmdW5jTmFtZSA9IGBpbmRpY2VzVG9PZmZzZXRfJHtuYW1lfV9UYDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgIFNoYXBlVXRpbHNHbHNsTGliLmluZGV4VG9PZmZzZXRTaW5nbGUoZnVuY05hbWUsIHJhbmssIHN0cmlkZXMuc2xpY2UoKS5yZXZlcnNlKCkpLFxuICAgICAgKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHN0YXRpYyBpbmRleFRvT2Zmc2V0U2luZ2xlKG5hbWU6IHN0cmluZywgcmFuazogbnVtYmVyLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSk6IHN0cmluZyB7XG4gICAgbGV0IGJsb2NrID0gJyc7XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBvZmZzZXQgKz0gaW5kaWNlc1ske2l9XSAqICR7c3RyaWRlc1tpXX07XG4gICAgICAgIGA7XG4gICAgfVxuICAgIHJldHVybiBgXG4gICAgICBpbnQgJHtuYW1lfShpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICBpbnQgb2Zmc2V0ID0gMDtcbiAgICAgICAgJHtibG9ja31cbiAgICAgICAgcmV0dXJuIG9mZnNldDtcbiAgICAgIH1cbiAgICAgIGA7XG4gIH1cbiAgcHJvdGVjdGVkIG9mZnNldFRvSW5kaWNlcygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnNoYXBlO1xuICAgICAgY29uc3Qgc3RyaWRlcyA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnN0cmlkZXM7XG4gICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgbGV0IGZ1bmNOYW1lID0gYG9mZnNldFRvSW5kaWNlc18ke25hbWV9YDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoU2hhcGVVdGlsc0dsc2xMaWIub2Zmc2V0VG9JbmRpY2VzU2luZ2xlKGZ1bmNOYW1lLCByYW5rLCBzdHJpZGVzKSk7XG4gICAgICBmdW5jTmFtZSA9IGBvZmZzZXRUb0luZGljZXNfJHtuYW1lfV9UYDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgIFNoYXBlVXRpbHNHbHNsTGliLm9mZnNldFRvSW5kaWNlc1NpbmdsZShmdW5jTmFtZSwgcmFuaywgc3RyaWRlcy5zbGljZSgpLnJldmVyc2UoKSksXG4gICAgICApO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgc3RhdGljIG9mZnNldFRvSW5kaWNlc1NpbmdsZShuYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlciwgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10pOiBzdHJpbmcge1xuICAgIGNvbnN0IHN0cmlkZXNCbG9jayA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgaW5kaWNlc1ske2l9XSA9IG9mZnNldCAvICR7c3RyaWRlc1tpXX07YCk7XG4gICAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICAgIG9mZnNldCAtPSBpbmRpY2VzWyR7aX1dICogJHtzdHJpZGVzW2ldfTtgKTtcbiAgICB9XG4gICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgaW5kaWNlc1ske3JhbmsgLSAxfV0gPSBvZmZzZXQ7YCk7XG4gICAgcmV0dXJuIGBcbiAgICAgIHZvaWQgJHtuYW1lfShpbnQgb2Zmc2V0LCBvdXQgaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgJHtzdHJpZGVzQmxvY2suam9pbignJyl9XG4gICAgICB9XG4gICAgICBgO1xuICB9XG4gIHByb3RlY3RlZCBpbmNyZW1lbnRJbmRpY2VzKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc2hhcGU7XG4gICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgY29uc3QgZnVuY05hbWUgPSBgaW5jcmVtZW50SW5kaWNlc18ke25hbWV9YDtcbiAgICAgIGxldCBzaGFwZUluaXQgPSAnJztcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgICAgIHNoYXBlSW5pdCArPSBgXG4gICAgICAgIHNoYXBlWyR7aX1dID0gJHtzaGFwZVtpXX07YDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICAgIHZvaWQgJHtmdW5jTmFtZX0oaW50IGF4aXMsIG91dCBpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBzaGFwZVske3Jhbmt9XTtcbiAgICAgICAgICAke3NoYXBlSW5pdH07XG4gICAgICAgICAgZm9yKGludCBpID0gJHtyYW5rfSAtMSA7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICBpZihpID4gYXhpcykgY29udGludWU7XG4gICAgICAgICAgICBpbmRpY2VzW2ldICs9IDE7XG4gICAgICAgICAgICBpZihpbmRpY2VzW2ldIDwgc2hhcGVbaV0pIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbmRpY2VzW2ldID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmUgfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuXG4vKipcbiAqIEdMU0wgTGlicmFyeSByZXNwb25zaWJsZSBmb3IgdmVjIHJvdXRpbmVzXG4gKiBWZWMgaXMgYW4gdmFyaWFibGUgbGVuZ3RoIGludCBhcnJheS4gVGhlIGxlbmd0aCBpcyBmaXhlZCBhdCB0aGUgdGltZSBvZlxuICogZ2VuZXJhdGluZyB0aGUgbGlicmFyeSBmdW5jdGlvbnMgZnJvbSB0aGUgZGltZW5zaW9ucyBvZiB0aGUgb3V0cHV0LlxuICovXG5leHBvcnQgY2xhc3MgVmVjR2xzbExpYiBleHRlbmRzIEdsc2xMaWIge1xuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBHbHNsQ29udGV4dCkge1xuICAgIHN1cGVyKGNvbnRleHQpO1xuICB9XG4gIGdldEN1c3RvbVR5cGVzKCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgZ2V0RnVuY3Rpb25zKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7IC4uLnRoaXMuYmluYXJ5VmVjRnVuY3Rpb25zKCksIC4uLnRoaXMuY29weVZlYygpLCAuLi50aGlzLnNldFZlY0l0ZW0oKSwgLi4udGhpcy5nZXRWZWNJdGVtKCkgfTtcbiAgfVxuICBwcm90ZWN0ZWQgYmluYXJ5VmVjRnVuY3Rpb25zKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IG5hbWVPcDogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH0gPSB7IGFkZDogJys9Jywgc3ViOiAnLT0nLCBtdWw6ICcqPScsIGRpdjogJy89JyB9O1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIGZvciAoY29uc3QgbmFtZSBpbiBuYW1lT3ApIHtcbiAgICAgIGNvbnN0IGZuYW1lID0gYCR7bmFtZX1WZWNgO1xuICAgICAgbGV0IGFzc2lnbm1lbnRCbG9jayA9ICcnO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICAgICAgYXNzaWdubWVudEJsb2NrICs9IGBcbiAgICAgICAgICBkZXN0WyR7aX1dICR7bmFtZU9wW25hbWVdfSBzcmNbJHtpfV07XG4gICAgICAgICAgYDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICAgIHZvaWQgJHtmbmFtZX0oaW50IHNyY1ske3Jhbmt9XSwgb3V0IGludCBkZXN0WyR7cmFua31dKSB7XG4gICAgICAgICAgJHthc3NpZ25tZW50QmxvY2t9XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJlc3VsdFtmbmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBwcm90ZWN0ZWQgY29weVZlYygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBjb25zdCByYW5rID0gb3V0cHV0TGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBsZXQgYXNzaWdubWVudEJsb2NrID0gJyc7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICAgIGFzc2lnbm1lbnRCbG9jayArPSBgXG4gICAgICAgIGRlc3RbJHtpfV0gPSBzcmNbJHtpfV07XG4gICAgICAgIGA7XG4gICAgfVxuICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICB2b2lkIGNvcHlWZWMoaW50IHNyY1ske3Jhbmt9XSwgb3V0IGludCBkZXN0WyR7cmFua31dKSB7XG4gICAgICAgICR7YXNzaWdubWVudEJsb2NrfVxuICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4geyBjb3B5VmVjOiBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSkgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzZXRWZWNJdGVtKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGxldCBibG9jayA9IGBcbiAgICAgICAgaWYoaW5kZXggPCAwKVxuICAgICAgICAgICAgaW5kZXggPSR7cmFua30gKyBpbmRleDtcbiAgICAgICAgaWYgKGluZGV4ID09IDApXG4gICAgICAgICAgICBtWzBdID0gdmFsdWU7XG4gICAgICAgIGA7XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCByYW5rIC0gMTsgKytpKSB7XG4gICAgICBibG9jayArPSBgXG4gICAgICAgIGVsc2UgaWYgKGluZGV4ID09ICR7aX0pXG4gICAgICAgICAgICBtWyR7aX1dID0gdmFsdWU7XG4gICAgICAgICAgICBgO1xuICAgIH1cbiAgICBibG9jayArPSBgXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIG1bJHtyYW5rIC0gMX1dID0gdmFsdWU7XG4gICAgICAgIGA7XG4gICAgY29uc3QgYm9keSA9IGBcbiAgICAgIHZvaWQgc2V0VmVjSXRlbShvdXQgaW50IG1bJHtyYW5rfV0sIGludCBpbmRleCwgaW50IHZhbHVlKSB7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICB9XG4gICAgICAgIGA7XG4gICAgcmV0dXJuIHsgc2V0VmVjSXRlbTogbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpIH07XG4gIH1cbiAgcHJvdGVjdGVkIGdldFZlY0l0ZW0oKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgY29uc3QgcmFuayA9IG91dHB1dExheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgbGV0IGJsb2NrID0gYFxuICAgICAgICBpZihpbmRleCA8IDApXG4gICAgICAgICAgICBpbmRleCA9ICR7cmFua30gKyBpbmRleDtcbiAgICAgICAgaWYgKGluZGV4ID09IDApXG4gICAgICAgICAgICByZXR1cm4gbVswXTtcbiAgICAgIGA7XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCByYW5rIC0gMTsgKytpKSB7XG4gICAgICBibG9jayArPSBgXG4gICAgICAgIGVsc2UgaWYgKGluZGV4ID09ICR7aX0pXG4gICAgICAgICAgICByZXR1cm4gbVske2l9XTtcbiAgICAgIGA7XG4gICAgfVxuICAgIGJsb2NrICs9IGBcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIG1bJHtyYW5rIC0gMX1dO1xuICAgICAgICBgO1xuICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICBpbnQgZ2V0VmVjSXRlbShpbnQgbVske3Jhbmt9XSwgaW50IGluZGV4KSB7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICB9XG4gICAgYDtcbiAgICByZXR1cm4geyBnZXRWZWNJdGVtOiBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSkgfTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBDb29yZHNHbHNsTGliIH0gZnJvbSAnLi9nbHNsLWNvb3JkaW5hdGUtbGliJztcbmltcG9ydCB7IEdsc2xDb250ZXh0LCBHbHNsTGliIH0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7IEVuY29kaW5nR2xzbExpYiB9IGZyb20gJy4vZ2xzbC1lbmNvZGluZy1saWInO1xuaW1wb3J0IHsgRnJhZ0NvbG9yR2xzbExpYiB9IGZyb20gJy4vZ2xzbC1mcmFnY29sb3ItbGliJztcbmltcG9ydCB7IFNoYXBlVXRpbHNHbHNsTGliIH0gZnJvbSAnLi9nbHNsLXNoYXBlLXV0aWxzLWxpYic7XG5pbXBvcnQgeyBWZWNHbHNsTGliIH0gZnJvbSAnLi9nbHNsLXZlYy1saWInO1xuXG5leHBvcnQgY29uc3QgZ2xzbFJlZ2lzdHJ5OiB7IFtuYW1lOiBzdHJpbmddOiBuZXcgKGNvbnRleHQ6IEdsc2xDb250ZXh0KSA9PiBHbHNsTGliIH0gPSB7XG4gIGVuY29kaW5nOiBFbmNvZGluZ0dsc2xMaWIsXG4gIGZyYWdjb2xvcjogRnJhZ0NvbG9yR2xzbExpYixcbiAgdmVjOiBWZWNHbHNsTGliLFxuICBzaGFwZVV0aWxzOiBTaGFwZVV0aWxzR2xzbExpYixcbiAgY29vcmRpbmF0ZXM6IENvb3Jkc0dsc2xMaWIsXG4gIC8vICAnYXJyYXlzJzogQXJyYXlHbHNsU0xpYlxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR2xzbENvbnRleHQsIEdsc2xMaWIsIEdsc2xMaWJSb3V0aW5lTm9kZSwgVG9wb2xvZ2ljYWxTb3J0R2xzbFJvdXRpbmVzIH0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7IHJlcGxhY2VJbmxpbmVzIH0gZnJvbSAnLi9nbHNsLWZ1bmN0aW9uLWlubGluZXInO1xuaW1wb3J0IHsgZ2xzbFJlZ2lzdHJ5IH0gZnJvbSAnLi9nbHNsLXJlZ2lzdGVyZWQtbGlicyc7XG5pbXBvcnQgeyBnZXREZWZhdWx0RnJhZ1NoYWRlck1haW4sIGdldEZyYWdTaGFkZXJQcmVhbWJsZSB9IGZyb20gJy4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVMYXlvdXQsIFZhcmlhYmxlSW5mbyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgV2ViR0xDb250ZXh0IH0gZnJvbSAnLi93ZWJnbC1jb250ZXh0JztcblxuLyoqXG4gKiBQcmVwcm9jZXNzb3IgZm9yIHRoZSBhZGRpdGlvbnMgdG8gdGhlIEdMU0wgbGFuZ3VhZ2VcbiAqIEl0IGRlYWxzIHdpdGg6XG4gKiAgQGluY2x1ZGUgZGlyZWN0aXZlc1xuICogIEBpbmxpbmVcbiAqICBMb29wIHVucm9sbGluZyAobm90IGltcGxlbWVudGVkKVxuICogIE1hY3JvIHJlc29sdXRpb24gKG5vdCBpbXBsZW1lbnRlZClcbiAqL1xuZXhwb3J0IGNsYXNzIEdsc2xQcmVwcm9jZXNzb3Ige1xuICByZWFkb25seSBjb250ZXh0OiBHbHNsQ29udGV4dDtcbiAgcmVhZG9ubHkgbGliczogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYiB9ID0ge307XG4gIHJlYWRvbmx5IGdsc2xMaWJSb3V0aW5lRGVwZW5kZW5jeUdyYXBoOiB7IFtyb3V0aW5lTmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmVOb2RlIH0gPSB7fTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBnbENvbnRleHQ6IFdlYkdMQ29udGV4dCxcbiAgICBwcm9ncmFtSW5mbzogUHJvZ3JhbUluZm8sXG4gICAgaW5wdXRUZXh0dXJlTGF5b3V0czogVGV4dHVyZUxheW91dFtdLFxuICAgIG91dHB1dFRleHR1cmVMYXlvdXQ6IFRleHR1cmVMYXlvdXQsXG4gICkge1xuICAgIHRoaXMuY29udGV4dCA9IG5ldyBHbHNsQ29udGV4dChnbENvbnRleHQsIHByb2dyYW1JbmZvLCBpbnB1dFRleHR1cmVMYXlvdXRzLCBvdXRwdXRUZXh0dXJlTGF5b3V0KTtcblxuICAgIC8vIGNvbnN0cnVjdCBHbHNsTGlic1xuICAgIE9iamVjdC5rZXlzKGdsc2xSZWdpc3RyeSkuZm9yRWFjaCgobmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBsaWIgPSBuZXcgZ2xzbFJlZ2lzdHJ5W25hbWVdKHRoaXMuY29udGV4dCk7XG4gICAgICB0aGlzLmxpYnNbbmFtZV0gPSBsaWI7XG4gICAgfSk7XG5cbiAgICAvLyBjb25zdHJ1Y3QgR2xzbFJvdXRpbmVEZXBlbmRlbmN5R3JhcGhcbiAgICBjb25zdCBtYXAgPSB0aGlzLmdsc2xMaWJSb3V0aW5lRGVwZW5kZW5jeUdyYXBoO1xuICAgIGZvciAoY29uc3QgbGliTmFtZSBpbiB0aGlzLmxpYnMpIHtcbiAgICAgIGNvbnN0IGxpYiA9IHRoaXMubGlic1tsaWJOYW1lXTtcbiAgICAgIGNvbnN0IHJvdXRpbmVzSW5MaWIgPSBsaWIuZ2V0RnVuY3Rpb25zKCk7XG4gICAgICBmb3IgKGNvbnN0IHJvdXRpbmUgaW4gcm91dGluZXNJbkxpYikge1xuICAgICAgICBjb25zdCBrZXkgPSBsaWJOYW1lICsgJy4nICsgcm91dGluZTtcbiAgICAgICAgbGV0IGN1cnJlbnROb2RlOiBHbHNsTGliUm91dGluZU5vZGU7XG4gICAgICAgIGlmIChtYXBba2V5XSkge1xuICAgICAgICAgIGN1cnJlbnROb2RlID0gbWFwW2tleV07XG4gICAgICAgICAgY3VycmVudE5vZGUucm91dGluZUJvZHkgPSByb3V0aW5lc0luTGliW3JvdXRpbmVdLnJvdXRpbmVCb2R5O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGN1cnJlbnROb2RlID0gbmV3IEdsc2xMaWJSb3V0aW5lTm9kZShrZXksIHJvdXRpbmVzSW5MaWJbcm91dGluZV0ucm91dGluZUJvZHkpO1xuICAgICAgICAgIG1hcFtrZXldID0gY3VycmVudE5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGVwZW5kZW5jaWVzID0gcm91dGluZXNJbkxpYltyb3V0aW5lXS5kZXBlbmRlbmNpZXM7XG4gICAgICAgIGlmIChkZXBlbmRlbmNpZXMpIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRlcGVuZGVuY2llcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgaWYgKCFtYXBbZGVwZW5kZW5jaWVzW2ldXSkge1xuICAgICAgICAgICAgICBjb25zdCBub2RlID0gbmV3IEdsc2xMaWJSb3V0aW5lTm9kZShkZXBlbmRlbmNpZXNbaV0pO1xuICAgICAgICAgICAgICBtYXBbZGVwZW5kZW5jaWVzW2ldXSA9IG5vZGU7XG4gICAgICAgICAgICAgIGN1cnJlbnROb2RlLmFkZERlcGVuZGVuY3kobm9kZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjdXJyZW50Tm9kZS5hZGREZXBlbmRlbmN5KG1hcFtkZXBlbmRlbmNpZXNbaV1dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcmVwcm9jZXNzKCk6IHN0cmluZyB7XG4gICAgY29uc3QgcHJvZ3JhbUluZm8gPSB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm87XG4gICAgbGV0IHNvdXJjZSA9IHByb2dyYW1JbmZvLnNoYWRlclNvdXJjZTtcblxuICAgIC8vIGFwcGVuZCBtYWluKCkgZnVuY3Rpb25cbiAgICBpZiAoIXRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5oYXNNYWluKSB7XG4gICAgICBzb3VyY2UgPSBgJHtzb3VyY2V9XG4gICAgICAke2dldERlZmF1bHRGcmFnU2hhZGVyTWFpbih0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24sIHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0LnNoYXBlLmxlbmd0aCl9YDtcbiAgICB9XG4gICAgLy8gcmVwbGFjZSBpbmxpbmVzXG4gICAgc291cmNlID0gcmVwbGFjZUlubGluZXMoc291cmNlKTtcblxuICAgIC8vIGNvbmNhdCBmaW5hbCBzb3VyY2Ugc3RyaW5nXG4gICAgcmV0dXJuIGAke2dldEZyYWdTaGFkZXJQcmVhbWJsZSh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pfVxuICAgICR7dGhpcy5nZXRVbmlmb3Jtcyhwcm9ncmFtSW5mby5pbnB1dE5hbWVzLCBwcm9ncmFtSW5mby52YXJpYWJsZXMpfVxuICAgICR7dGhpcy5nZXRJbXBvcnRzKHNvdXJjZSl9XG4gICAgJHtzb3VyY2V9YDtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRJbXBvcnRzKHNjcmlwdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCByb3V0aW5lc0luY2x1ZGVkID0gdGhpcy5zZWxlY3RHbHNsTGliUm91dGluZXNUb0JlSW5jbHVkZWQoc2NyaXB0KTtcblxuICAgIGlmIChyb3V0aW5lc0luY2x1ZGVkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIGxldCByb3V0aW5lcyA9ICcnO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm91dGluZXNJbmNsdWRlZC5sZW5ndGg7ICsraSkge1xuICAgICAgaWYgKHJvdXRpbmVzSW5jbHVkZWRbaV0ucm91dGluZUJvZHkpIHtcbiAgICAgICAgcm91dGluZXMgKz0gcm91dGluZXNJbmNsdWRlZFtpXS5yb3V0aW5lQm9keSArICdcXG4nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaXNzaW5nIGJvZHkgZm9yIHRoZSBHbHNsIExpYnJhcnkgcm91dGluZTogJHtyb3V0aW5lc0luY2x1ZGVkW2ldLm5hbWV9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJvdXRpbmVzO1xuICB9XG4gIHByaXZhdGUgc2VsZWN0R2xzbExpYlJvdXRpbmVzVG9CZUluY2x1ZGVkKHNjcmlwdDogc3RyaW5nKTogR2xzbExpYlJvdXRpbmVOb2RlW10ge1xuICAgIGNvbnN0IG5vZGVzOiBHbHNsTGliUm91dGluZU5vZGVbXSA9IFtdO1xuXG4gICAgT2JqZWN0LmtleXModGhpcy5nbHNsTGliUm91dGluZURlcGVuZGVuY3lHcmFwaCkuZm9yRWFjaCgoY2xhc3NBbmRSb3V0aW5lKSA9PiB7XG4gICAgICBjb25zdCByb3V0aW5lID0gY2xhc3NBbmRSb3V0aW5lLnNwbGl0KCcuJylbMV07XG4gICAgICBpZiAoc2NyaXB0LmluZGV4T2Yocm91dGluZSkgIT09IC0xKSB7XG4gICAgICAgIG5vZGVzLnB1c2godGhpcy5nbHNsTGliUm91dGluZURlcGVuZGVuY3lHcmFwaFtjbGFzc0FuZFJvdXRpbmVdKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBUb3BvbG9naWNhbFNvcnRHbHNsUm91dGluZXMucmV0dXJuT3JkZXJlZE5vZGVzKG5vZGVzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRVbmlmb3JtcyhzYW1wbGVycz86IHN0cmluZ1tdLCB2YXJpYWJsZXM/OiBWYXJpYWJsZUluZm9bXSk6IHN0cmluZyB7XG4gICAgY29uc3QgdW5pZm9ybUxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGlmIChzYW1wbGVycykge1xuICAgICAgZm9yIChjb25zdCBzYW1wbGVyIG9mIHNhbXBsZXJzKSB7XG4gICAgICAgIHVuaWZvcm1MaW5lcy5wdXNoKGB1bmlmb3JtIHNhbXBsZXIyRCAke3NhbXBsZXJ9O2ApO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodmFyaWFibGVzKSB7XG4gICAgICBmb3IgKGNvbnN0IHZhcmlhYmxlIG9mIHZhcmlhYmxlcykge1xuICAgICAgICB1bmlmb3JtTGluZXMucHVzaChcbiAgICAgICAgICBgdW5pZm9ybSAke3ZhcmlhYmxlLnR5cGV9ICR7dmFyaWFibGUubmFtZX0ke3ZhcmlhYmxlLmFycmF5TGVuZ3RoID8gYFske3ZhcmlhYmxlLmFycmF5TGVuZ3RofV1gIDogJyd9O2AsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1bmlmb3JtTGluZXMuam9pbignXFxuJyk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZW52IH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHsgTG9nZ2VyLCBQcm9maWxlciB9IGZyb20gJy4uLy4uL2luc3RydW1lbnQnO1xuXG5pbXBvcnQgeyBHbHNsUHJlcHJvY2Vzc29yIH0gZnJvbSAnLi9nbHNsLXByZXByb2Nlc3Nvcic7XG5pbXBvcnQgeyBnZXRWZXJ0ZXhTaGFkZXJTb3VyY2UgfSBmcm9tICcuL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFRleHR1cmVMYXlvdXRTdHJhdGVneSB9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgQXJ0aWZhY3QsIFByb2dyYW1JbmZvLCBQcm9ncmFtVmFyaWFibGUsIFRleHR1cmVEYXRhLCBUZXh0dXJlTGF5b3V0LCBWYXJpYWJsZUluZm8gfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbi8qKlxuICogUHJvZ3JhbU1hbmFnZXIgaXMgdGhlIG1haW4gY2xhc3MgYmVoaW5kIHJ1bm5pbmcgY29tcHV0YXRpb25zXG4gKiBJdCBidWlsZHMgUHJvZ3JhbUluZm8ncyBpbnRvIEFydGlmYWN0c1xuICogSXQgY29tcGlsZXMgZ2l2ZW4gUHJvZ3JhbUluZm8ncyBpbnRvIFdlYkdMIFByb3JhbXMgKGNhY2hlZCBhcyBBcnRpZmFjdHMpXG4gKiBVc2VzIHRoZSBhcnRpZmFjdCB0byBydW4gdGhlIGNvbXB1dGF0aW9uIGJ5IGNhbGxpbmcgRHJhdyBvblxuICogdGhlIFdlYkdMIGRyYXdpbmcgYnVmZmVyXG4gKiBQcm9ncmFtTWFuYWdlciBhdXRvbWF0aWNhbGx5IG1hcHMgKGJpbmRzKSBpbnB1dCB2YXJpYWJsZXMgdG8gdGhlaXJcbiAqIGNvcnJlc3BvbmRpbmcgTG9jYXRpb24ncyBpbiB0aGUgYmluYXJ5IHByb2dyYW1cbiAqL1xuZXhwb3J0IGNsYXNzIFByb2dyYW1NYW5hZ2VyIHtcbiAgcmVwbzogTWFwPHVua25vd24sIEFydGlmYWN0PjsgLy8gdGhpcyBzaG91bGQgYmUgcGVyLXNlc3Npb24gb2JqZWN0XG4gIHZlcnRleFNoYWRlcjogV2ViR0xTaGFkZXI7XG4gIGF0dHJpYnV0ZXNCb3VuZDogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgcHJvZmlsZXI6IFJlYWRvbmx5PFByb2ZpbGVyPixcbiAgICBwdWJsaWMgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQsXG4gICAgcHVibGljIHRleHR1cmVMYXlvdXRTdHJhdGVneTogVGV4dHVyZUxheW91dFN0cmF0ZWd5LFxuICApIHtcbiAgICB0aGlzLnJlcG8gPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5hdHRyaWJ1dGVzQm91bmQgPSBmYWxzZTtcbiAgfVxuICBnZXRBcnRpZmFjdChrZXk6IHVua25vd24pOiBBcnRpZmFjdCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMucmVwby5nZXQoa2V5KTtcbiAgfVxuICBzZXRBcnRpZmFjdChrZXk6IHVua25vd24sIGFydGlmYWN0OiBBcnRpZmFjdCk6IHZvaWQge1xuICAgIHRoaXMucmVwby5zZXQoa2V5LCBhcnRpZmFjdCk7XG4gIH1cbiAgcnVuKGJ1aWxkQXJ0aWZhY3Q6IEFydGlmYWN0LCBpbnB1dHM6IFRleHR1cmVEYXRhW10sIG91dHB1dDogVGV4dHVyZURhdGEpOiB2b2lkIHtcbiAgICB0aGlzLnByb2ZpbGVyLmV2ZW50KFxuICAgICAgJ29wJyxcbiAgICAgIGBQcm9ncmFtTWFuYWdlci5ydW4gJHtidWlsZEFydGlmYWN0LnByb2dyYW1JbmZvLm5hbWUgPz8gJ3Vua25vd24ga2VybmVsJ31gLFxuICAgICAgKCkgPT4ge1xuICAgICAgICBjb25zdCBnbCA9IHRoaXMuZ2xDb250ZXh0LmdsO1xuICAgICAgICBjb25zdCBwcm9ncmFtID0gYnVpbGRBcnRpZmFjdC5wcm9ncmFtO1xuICAgICAgICBnbC51c2VQcm9ncmFtKHByb2dyYW0pO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuYmluZE91dHB1dChvdXRwdXQpO1xuICAgICAgICAgIGlmICghdGhpcy5hdHRyaWJ1dGVzQm91bmQpIHtcbiAgICAgICAgICAgIHRoaXMuYmluZEF0dHJpYnV0ZXMoYnVpbGRBcnRpZmFjdC5hdHRyaWJMb2NhdGlvbnMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmJpbmRVbmlmb3JtcyhidWlsZEFydGlmYWN0LnVuaWZvcm1Mb2NhdGlvbnMsIGJ1aWxkQXJ0aWZhY3QucHJvZ3JhbUluZm8udmFyaWFibGVzID8/IFtdLCBpbnB1dHMpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBMb2dnZXIuZXJyb3IoJ1Byb2dyYW1NYW5hZ2VyJywgYnVpbGRBcnRpZmFjdC5wcm9ncmFtSW5mby5zaGFkZXJTb3VyY2UpO1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByb2ZpbGVyLmV2ZW50KCdiYWNrZW5kJywgJ0dsQ29udGV4dC5kcmF3KCknLCAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5nbENvbnRleHQuZHJhdygpO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICB0aGlzLmdsQ29udGV4dCxcbiAgICApO1xuICB9XG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudmVydGV4U2hhZGVyKSB7XG4gICAgICB0aGlzLmdsQ29udGV4dC5kZWxldGVTaGFkZXIodGhpcy52ZXJ0ZXhTaGFkZXIpO1xuICAgIH1cbiAgICB0aGlzLnJlcG8uZm9yRWFjaCgoYSkgPT4gdGhpcy5nbENvbnRleHQuZGVsZXRlUHJvZ3JhbShhLnByb2dyYW0pKTtcbiAgfVxuICBidWlsZChwcm9ncmFtSW5mbzogUHJvZ3JhbUluZm8sIGlucHV0VGV4dHVyZUxheW91dHM6IFRleHR1cmVMYXlvdXRbXSwgb3V0cHV0VGV4dHVyZUxheW91dDogVGV4dHVyZUxheW91dCk6IEFydGlmYWN0IHtcbiAgICByZXR1cm4gdGhpcy5wcm9maWxlci5ldmVudCgnYmFja2VuZCcsICdQcm9ncmFtTWFuYWdlci5idWlsZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHByZXByb2Nlc3NvciA9IG5ldyBHbHNsUHJlcHJvY2Vzc29yKHRoaXMuZ2xDb250ZXh0LCBwcm9ncmFtSW5mbywgaW5wdXRUZXh0dXJlTGF5b3V0cywgb3V0cHV0VGV4dHVyZUxheW91dCk7XG4gICAgICBjb25zdCBmcmFnU2NyaXB0ID0gcHJlcHJvY2Vzc29yLnByZXByb2Nlc3MoKTtcbiAgICAgIGNvbnN0IHByb2dyYW0gPSB0aGlzLmNvbXBpbGUoZnJhZ1NjcmlwdCk7XG4gICAgICBjb25zdCBhcnRpZmFjdCA9IHtcbiAgICAgICAgcHJvZ3JhbUluZm8sXG4gICAgICAgIHByb2dyYW0sXG4gICAgICAgIHVuaWZvcm1Mb2NhdGlvbnM6IHRoaXMuZ2V0VW5pZm9ybUxvY2F0aW9ucyhcbiAgICAgICAgICBwcm9ncmFtLFxuICAgICAgICAgIHByZXByb2Nlc3Nvci5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMsXG4gICAgICAgICAgcHJlcHJvY2Vzc29yLmNvbnRleHQucHJvZ3JhbUluZm8udmFyaWFibGVzLFxuICAgICAgICApLFxuICAgICAgICBhdHRyaWJMb2NhdGlvbnM6IHRoaXMuZ2V0QXR0cmliTG9jYXRpb25zKHByb2dyYW0pLFxuICAgICAgfTtcbiAgICAgIHJldHVybiBhcnRpZmFjdDtcbiAgICB9KTtcbiAgfVxuICBwcm90ZWN0ZWQgY29tcGlsZShmcmFnU2hhZGVyU2NyaXB0OiBzdHJpbmcpOiBXZWJHTFByb2dyYW0ge1xuICAgIGlmICghdGhpcy52ZXJ0ZXhTaGFkZXIpIHtcbiAgICAgIExvZ2dlci52ZXJib3NlKCdQcm9yZ3JhbU1hbmFnZXInLCAnQ29tcGlsaW5nIGFuZCBjYWNoaW5nIFZlcnRleCBzaGFkZXIgZm9yIHRoZSBmaXJzdCB0aW1lJyk7XG4gICAgICBjb25zdCB2ZXJ0ZXhTaGFkZXJTY3JpcHQgPSBnZXRWZXJ0ZXhTaGFkZXJTb3VyY2UodGhpcy5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICB0aGlzLnZlcnRleFNoYWRlciA9IHRoaXMuZ2xDb250ZXh0LmNvbXBpbGVTaGFkZXIodmVydGV4U2hhZGVyU2NyaXB0LCB0aGlzLmdsQ29udGV4dC5nbC5WRVJURVhfU0hBREVSKTtcbiAgICB9XG4gICAgaWYgKGVudi5kZWJ1Zykge1xuICAgICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICdQcm9yZ3JhbU1hbmFnZXInLFxuICAgICAgICBgRnJhZ1NoYWRlcjpcbiR7ZnJhZ1NoYWRlclNjcmlwdH1cbmAsXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBmcmFnU2hhZGVyID0gdGhpcy5nbENvbnRleHQuY29tcGlsZVNoYWRlcihmcmFnU2hhZGVyU2NyaXB0LCB0aGlzLmdsQ29udGV4dC5nbC5GUkFHTUVOVF9TSEFERVIpO1xuICAgIGNvbnN0IHByb2dyYW0gPSB0aGlzLmdsQ29udGV4dC5jcmVhdGVQcm9ncmFtKHRoaXMudmVydGV4U2hhZGVyLCBmcmFnU2hhZGVyKTtcbiAgICB0aGlzLmdsQ29udGV4dC5kZWxldGVTaGFkZXIoZnJhZ1NoYWRlcik7XG4gICAgcmV0dXJuIHByb2dyYW07XG4gIH1cbiAgYmluZE91dHB1dCh0ZDogVGV4dHVyZURhdGEpOiB2b2lkIHtcbiAgICBjb25zdCB3aWR0aCA9IHRkLndpZHRoO1xuICAgIGNvbnN0IGhlaWdodCA9IHRkLmhlaWdodDtcbiAgICBMb2dnZXIudmVyYm9zZShcbiAgICAgICdQcm9yZ3JhbU1hbmFnZXInLFxuICAgICAgYEJpbmRpbmcgb3V0cHV0IHRleHR1cmUgdG8gRnJhbWVidWZmZXI6IHcvaD0ke3dpZHRofS8ke2hlaWdodH0sIHNoYXBlPSR7dGQuc2hhcGV9LCB0eXBlPSR7dGQudGVuc29yLnR5cGV9YCxcbiAgICApO1xuICAgIHRoaXMuZ2xDb250ZXh0LmF0dGFjaEZyYW1lYnVmZmVyKHRkLnRleHR1cmUsIHdpZHRoLCBoZWlnaHQpO1xuICB9XG4gIGJpbmRBdHRyaWJ1dGVzKGF0dHJpYkxvY2F0aW9uczogQXJ0aWZhY3QuQXR0cmliTG9jYXRpb25zKTogdm9pZCB7XG4gICAgY29uc3QgcG9zaXRpb25IYW5kbGUgPSBhdHRyaWJMb2NhdGlvbnMucG9zaXRpb247XG4gICAgY29uc3QgdGV4dHVyZUNvb3JkSGFuZGxlID0gYXR0cmliTG9jYXRpb25zLnRleHR1cmVDb29yZDtcbiAgICB0aGlzLmdsQ29udGV4dC5zZXRWZXJ0ZXhBdHRyaWJ1dGVzKHBvc2l0aW9uSGFuZGxlLCB0ZXh0dXJlQ29vcmRIYW5kbGUpO1xuICAgIHRoaXMuYXR0cmlidXRlc0JvdW5kID0gdHJ1ZTtcbiAgfVxuICBiaW5kVW5pZm9ybXMoXG4gICAgdW5pZm9ybUxvY2F0aW9uczogQXJ0aWZhY3QuVW5pZm9ybUxvY2F0aW9ucyxcbiAgICB2YXJpYWJsZXM6IFByb2dyYW1WYXJpYWJsZVtdLFxuICAgIHRleHR1cmVzOiBUZXh0dXJlRGF0YVtdLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2xDb250ZXh0LmdsO1xuICAgIGxldCB0ZXh0dXJlUG9zaXRpb24gPSAwO1xuICAgIGZvciAoY29uc3QgeyBuYW1lLCB0eXBlLCBsb2NhdGlvbiwgYXJyYXlMZW5ndGggfSBvZiB1bmlmb3JtTG9jYXRpb25zKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHZhcmlhYmxlcy5maW5kKCh2KSA9PiB2Lm5hbWUgPT09IG5hbWUpPy5kYXRhO1xuICAgICAgaWYgKHR5cGUgIT09ICdzYW1wbGVyMkQnICYmICF2YWx1ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHZhcmlhYmxlICcke25hbWV9JyBkb2VzIG5vdCBoYXZlIGRhdGEgZGVmaW5lZCBpbiBwcm9ncmFtIGluZm9gKTtcbiAgICAgIH1cbiAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlICdzYW1wbGVyMkQnOlxuICAgICAgICAgIHRoaXMuYmluZFRleHR1cmUodGV4dHVyZXNbdGV4dHVyZVBvc2l0aW9uXSwgbG9jYXRpb24sIHRleHR1cmVQb3NpdGlvbik7XG4gICAgICAgICAgdGV4dHVyZVBvc2l0aW9uKys7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2Zsb2F0JzpcbiAgICAgICAgICBpZiAoYXJyYXlMZW5ndGgpIHtcbiAgICAgICAgICAgIGdsLnVuaWZvcm0xZnYobG9jYXRpb24sIHZhbHVlIGFzIG51bWJlcltdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2wudW5pZm9ybTFmKGxvY2F0aW9uLCB2YWx1ZSBhcyBudW1iZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnaW50JzpcbiAgICAgICAgICBpZiAoYXJyYXlMZW5ndGgpIHtcbiAgICAgICAgICAgIGdsLnVuaWZvcm0xaXYobG9jYXRpb24sIHZhbHVlIGFzIG51bWJlcltdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2wudW5pZm9ybTFpKGxvY2F0aW9uLCB2YWx1ZSBhcyBudW1iZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuaWZvcm0gbm90IGltcGxlbWVudGVkOiAke3R5cGV9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGJpbmRUZXh0dXJlKHRkOiBUZXh0dXJlRGF0YSwgdW5pZm9ybUhhbmRsZTogV2ViR0xVbmlmb3JtTG9jYXRpb24sIHBvc2l0aW9uOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmdsQ29udGV4dC5iaW5kVGV4dHVyZVRvVW5pZm9ybSh0ZC50ZXh0dXJlLCBwb3NpdGlvbiwgdW5pZm9ybUhhbmRsZSk7XG4gIH1cbiAgZ2V0QXR0cmliTG9jYXRpb25zKHByb2dyYW06IFdlYkdMUHJvZ3JhbSk6IEFydGlmYWN0LkF0dHJpYkxvY2F0aW9ucyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHBvc2l0aW9uOiB0aGlzLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sICdwb3NpdGlvbicpLFxuICAgICAgdGV4dHVyZUNvb3JkOiB0aGlzLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sICd0ZXh0dXJlQ29vcmQnKSxcbiAgICB9O1xuICB9XG4gIGdldFVuaWZvcm1Mb2NhdGlvbnMoXG4gICAgcHJvZ3JhbTogV2ViR0xQcm9ncmFtLFxuICAgIHNhbXBsZXJzPzogc3RyaW5nW10sXG4gICAgdmFyaWFibGVzPzogVmFyaWFibGVJbmZvW10sXG4gICk6IEFydGlmYWN0LlVuaWZvcm1Mb2NhdGlvbnMge1xuICAgIGNvbnN0IHVuaWZvcm1Mb2NhdGlvbnM6IEFydGlmYWN0LlVuaWZvcm1Mb2NhdGlvbnMgPSBbXTtcbiAgICBpZiAoc2FtcGxlcnMpIHtcbiAgICAgIGZvciAoY29uc3Qgc2FtcGxlciBvZiBzYW1wbGVycykge1xuICAgICAgICB1bmlmb3JtTG9jYXRpb25zLnB1c2goe1xuICAgICAgICAgIG5hbWU6IHNhbXBsZXIsXG4gICAgICAgICAgdHlwZTogJ3NhbXBsZXIyRCcsXG4gICAgICAgICAgbG9jYXRpb246IHRoaXMuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sIHNhbXBsZXIpLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHZhcmlhYmxlcykge1xuICAgICAgZm9yIChjb25zdCB2YXJpYWJsZSBvZiB2YXJpYWJsZXMpIHtcbiAgICAgICAgdW5pZm9ybUxvY2F0aW9ucy5wdXNoKHsgLi4udmFyaWFibGUsIGxvY2F0aW9uOiB0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCB2YXJpYWJsZS5uYW1lKSB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuaWZvcm1Mb2NhdGlvbnM7XG4gIH1cbiAgZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW06IFdlYkdMUHJvZ3JhbSwgbmFtZTogc3RyaW5nKTogV2ViR0xVbmlmb3JtTG9jYXRpb24ge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbENvbnRleHQuZ2w7XG4gICAgY29uc3QgcmVmZXJlbmNlID0gZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sIG5hbWUpO1xuICAgIGlmIChyZWZlcmVuY2UgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5pZm9ybSAke25hbWV9IG5vdCBmb3VuZC5gKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlZmVyZW5jZTtcbiAgfVxuICBnZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtOiBXZWJHTFByb2dyYW0sIG5hbWU6IHN0cmluZyk6IG51bWJlciB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsQ29udGV4dC5nbDtcbiAgICBjb25zdCBhdHRyaWJ1dGVMb2NhdGlvbjogbnVtYmVyID0gZ2wuZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbSwgbmFtZSk7XG4gICAgcmV0dXJuIGF0dHJpYnV0ZUxvY2F0aW9uO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IExvZ2dlciwgUHJvZmlsZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uL3RlbnNvcic7XG5cbmltcG9ydCB7IEVuY29kZXIsIEVuY29kZXJVc2FnZSB9IGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHsgVGV4dHVyZUxheW91dFN0cmF0ZWd5IH0gZnJvbSAnLi90ZXh0dXJlLWxheW91dC1zdHJhdGVneSc7XG5pbXBvcnQgeyBUZXh0dXJlRGF0YSwgVGV4dHVyZUxheW91dCB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgV2ViR0xDb250ZXh0IH0gZnJvbSAnLi93ZWJnbC1jb250ZXh0JztcblxuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlTWFuYWdlckNvbmZpZyB7XG4gIHJldXNlVGV4dHVyZXM/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFRleHR1cmVNYW5hZ2VyIGlzIHRoZSBtYWlubHkgcmVzcG9uc2libGUgZm9yIGNhY2hpbmcgVGV4dHVyZXNcbiAqIFRleHR1cmVzIGFyZSBjYWNoZWQgaW4gMiBsZXZlbHM6XG4gKiAgIDEuIHRoZSB0ZXh0dXJlcyB3aGljaCBhcmUgYXNzb2NpYXRlZCB3aXRoIGEgZGF0YUlkIChmcm9tIFRlbnNvcilcbiAqICAgIENhY2hpbmcgdGhlc2UgaXMgY3J1Y2lhbCB0byBwZXJmb3JtYW5jZS4gVGhlc2UgYXJlIEluLXVzZSBUZXh0dXJlc1xuICogICAyLiB0ZXh0dXJlcyB3aGljaCBhcmUgbm90IGluIHVzZSBieSBhbnkgY3VycmVudCBQcm9ncmFtSW5mby9UZW5zb3JcbiAqICAgICBUaGVzZSBhcmUgY2FsbGVkIEZyZWUgVGV4dHVyZXNcbiAqIFRleHR1cmVNYW5hZ2VyIGlzIGFsc28gdXNlZCB0byBoZWxwIGNyZWF0aW5nIHRleHR1cmVzLiBGb3IgdGhpcyBpdFxuICogdXNlcyBXZWJHTENvbnRleHQgYW5kIFRleHR1cmVMYXlvdXRTdHJhdGVneVxuICovXG5leHBvcnQgY2xhc3MgVGV4dHVyZU1hbmFnZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGluVXNlVGV4dHVyZXM6IE1hcDxzdHJpbmcsIFdlYkdMVGV4dHVyZVtdPjtcbiAgcHJpdmF0ZSByZWFkb25seSBpZGxlVGV4dHVyZXM6IE1hcDxzdHJpbmcsIFdlYkdMVGV4dHVyZVtdPjtcbiAgcHJpdmF0ZSByZWFkb25seSB0ZXh0dXJlTG9va3VwOiBNYXA8V2ViR0xUZXh0dXJlLCBzdHJpbmc+O1xuICBwcml2YXRlIHJlYWRvbmx5IHBlbmRpbmdSZWFkOiBNYXA8VGVuc29yLklkLCBBcnJheTwoYXJyOiBUZW5zb3IuTnVtYmVyVHlwZSkgPT4gdm9pZD4+ID0gbmV3IE1hcCgpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBnbENvbnRleHQ6IFdlYkdMQ29udGV4dCxcbiAgICBwdWJsaWMgbGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSxcbiAgICBwdWJsaWMgcHJvZmlsZXI6IFJlYWRvbmx5PFByb2ZpbGVyPixcbiAgICBwcml2YXRlIGNvbmZpZzogVGV4dHVyZU1hbmFnZXJDb25maWcsXG4gICkge1xuICAgIGlmIChjb25maWcucmV1c2VUZXh0dXJlcykge1xuICAgICAgdGhpcy5pblVzZVRleHR1cmVzID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy5pZGxlVGV4dHVyZXMgPSBuZXcgTWFwKCk7XG4gICAgICB0aGlzLnRleHR1cmVMb29rdXAgPSBuZXcgTWFwKCk7XG4gICAgfVxuICB9XG4gIGNyZWF0ZVRleHR1cmVGcm9tTGF5b3V0KFxuICAgIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsXG4gICAgbGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIGRhdGE/OiBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICB1c2FnZT86IEVuY29kZXJVc2FnZSxcbiAgKSB7XG4gICAgY29uc3QgdGV4dHVyZURhdGFUeXBlID0gdGhpcy50b0VuY29kZXJUeXBlKGRhdGFUeXBlKTtcblxuICAgIGNvbnN0IGVuY29kZXIgPSB0aGlzLmdsQ29udGV4dC5nZXRFbmNvZGVyKHRleHR1cmVEYXRhVHlwZSwgbGF5b3V0LmNoYW5uZWxzIHx8IDEsIHVzYWdlKTtcbiAgICBpZiAobGF5b3V0LmlzUGFja2VkICYmIHVzYWdlID09PSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG4gICAgY29uc3Qgd2lkdGggPSBsYXlvdXQud2lkdGg7XG4gICAgY29uc3QgaGVpZ2h0ID0gbGF5b3V0LmhlaWdodDtcblxuICAgIGxldCBrZXk6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBsZXQgaW5Vc2VUZXh0dXJlczogV2ViR0xUZXh0dXJlW10gfCB1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMuY29uZmlnLnJldXNlVGV4dHVyZXMpIHtcbiAgICAgIGtleSA9IGAke3dpZHRofXgke2hlaWdodH1fJHtlbmNvZGVyLmZvcm1hdH1fJHtlbmNvZGVyLmludGVybmFsRm9ybWF0fV8ke2VuY29kZXIudGV4dHVyZVR5cGV9YDtcbiAgICAgIGluVXNlVGV4dHVyZXMgPSB0aGlzLmluVXNlVGV4dHVyZXMuZ2V0KGtleSk7XG4gICAgICBpZiAoIWluVXNlVGV4dHVyZXMpIHtcbiAgICAgICAgaW5Vc2VUZXh0dXJlcyA9IFtdO1xuICAgICAgICB0aGlzLmluVXNlVGV4dHVyZXMuc2V0KGtleSwgaW5Vc2VUZXh0dXJlcyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGlkbGVUZXh0dXJlcyA9IHRoaXMuaWRsZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgaWYgKGlkbGVUZXh0dXJlcyAmJiBpZGxlVGV4dHVyZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCB0ZXh0dXJlID0gaWRsZVRleHR1cmVzLnBvcCgpITtcbiAgICAgICAgaW5Vc2VUZXh0dXJlcy5wdXNoKHRleHR1cmUpO1xuICAgICAgICBpZiAodXNhZ2UgPT09IEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5KSB7XG4gICAgICAgICAgdGhpcy5nbENvbnRleHQudXBkYXRlVGV4dHVyZSh0ZXh0dXJlLCB3aWR0aCwgaGVpZ2h0LCBlbmNvZGVyLCB0aGlzLnRvVGV4dHVyZURhdGEoZGF0YVR5cGUsIGRhdGEpISk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRleHR1cmU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgTG9nZ2VyLnZlcmJvc2UoJ1RleHR1cmVNYW5hZ2VyJywgYENyZWF0aW5nIG5ldyB0ZXh0dXJlIG9mIHNpemUgJHtsYXlvdXQud2lkdGh9eCR7bGF5b3V0LmhlaWdodH1gKTtcbiAgICBjb25zdCB0ZXh0dXJlID0gdGhpcy5nbENvbnRleHQuYWxsb2NhdGVUZXh0dXJlKHdpZHRoLCBoZWlnaHQsIGVuY29kZXIsIHRoaXMudG9UZXh0dXJlRGF0YShkYXRhVHlwZSwgZGF0YSkpO1xuXG4gICAgaWYgKHRoaXMuY29uZmlnLnJldXNlVGV4dHVyZXMpIHtcbiAgICAgIGluVXNlVGV4dHVyZXMhLnB1c2godGV4dHVyZSk7XG4gICAgICB0aGlzLnRleHR1cmVMb29rdXAuc2V0KHRleHR1cmUsIGtleSEpO1xuICAgIH1cbiAgICByZXR1cm4gdGV4dHVyZTtcbiAgfVxuICByZWFkVGV4dHVyZSh0ZDogVGV4dHVyZURhdGEsIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsIGNoYW5uZWxzPzogbnVtYmVyKTogVGVuc29yLk51bWJlclR5cGUge1xuICAgIGlmICghY2hhbm5lbHMpIHtcbiAgICAgIGNoYW5uZWxzID0gMTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnVGV4dHVyZU1hbmFnZXIucmVhZFRleHR1cmUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBkYXRhU2l6ZSA9IHRkLnNoYXBlLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpICogY2hhbm5lbHMhO1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZ2xDb250ZXh0LnJlYWRUZXh0dXJlKFxuICAgICAgICB0ZC50ZXh0dXJlLFxuICAgICAgICB0ZC53aWR0aCxcbiAgICAgICAgdGQuaGVpZ2h0LFxuICAgICAgICBkYXRhU2l6ZSxcbiAgICAgICAgdGhpcy50b0VuY29kZXJUeXBlKGRhdGFUeXBlKSxcbiAgICAgICAgY2hhbm5lbHMhLFxuICAgICAgKTtcbiAgICAgIHJldHVybiB0aGlzLnRvVGVuc29yRGF0YShkYXRhVHlwZSwgZGF0YSk7XG4gICAgfSk7XG4gIH1cbiAgYXN5bmMgcmVhZFRleHR1cmVBc3luYyh0ZDogVGV4dHVyZURhdGEsIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsIGNoYW5uZWxzPzogbnVtYmVyKTogUHJvbWlzZTxUZW5zb3IuTnVtYmVyVHlwZT4ge1xuICAgIGNvbnN0IGRhdGFJZCA9IHRkLnRlbnNvci5kYXRhSWQ7XG4gICAgaWYgKCFjaGFubmVscykge1xuICAgICAgY2hhbm5lbHMgPSAxO1xuICAgIH1cbiAgICBpZiAodGhpcy5wZW5kaW5nUmVhZC5oYXMoZGF0YUlkKSkge1xuICAgICAgY29uc3Qgc3Vic2NyaWJlcnMgPSB0aGlzLnBlbmRpbmdSZWFkLmdldChkYXRhSWQpO1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFRlbnNvci5OdW1iZXJUeXBlPigocmVzb2x2ZSkgPT4gc3Vic2NyaWJlcnM/LnB1c2gocmVzb2x2ZSkpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wcm9maWxlci5ldmVudCgnYmFja2VuZCcsICdUZXh0dXJlTWFuYWdlci5yZWFkVGV4dHVyZUFzeW5jJywgYXN5bmMgKCkgPT4ge1xuICAgICAgdGhpcy5wZW5kaW5nUmVhZC5zZXQoZGF0YUlkLCBbXSk7XG4gICAgICBjb25zdCBkYXRhU2l6ZSA9IHRkLnNoYXBlLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpICogY2hhbm5lbHMhO1xuICAgICAgLy8gYWRkIGEgZmVuY2Ugd2FpdGluZyBmb3IgdGhlIGRhdGEgdG8gYmUgcmVhZHlcbiAgICAgIGF3YWl0IHRoaXMuZ2xDb250ZXh0LmNyZWF0ZUFuZFdhaXRGb3JGZW5jZSgpO1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZ2xDb250ZXh0LnJlYWRUZXh0dXJlKFxuICAgICAgICB0ZC50ZXh0dXJlLFxuICAgICAgICB0ZC53aWR0aCxcbiAgICAgICAgdGQuaGVpZ2h0LFxuICAgICAgICBkYXRhU2l6ZSxcbiAgICAgICAgdGhpcy50b0VuY29kZXJUeXBlKGRhdGFUeXBlKSxcbiAgICAgICAgY2hhbm5lbHMhLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHRlbnNvckRhdGEgPSB0aGlzLnRvVGVuc29yRGF0YShkYXRhVHlwZSwgZGF0YSk7XG4gICAgICBjb25zdCBzdWJzY3JpYmVycyA9IHRoaXMucGVuZGluZ1JlYWQuZ2V0KGRhdGFJZCk7XG4gICAgICB0aGlzLnBlbmRpbmdSZWFkLmRlbGV0ZShkYXRhSWQpO1xuICAgICAgc3Vic2NyaWJlcnM/LmZvckVhY2goKHJlc29sdmUpID0+IHJlc29sdmUodGVuc29yRGF0YSkpO1xuICAgICAgcmV0dXJuIHRlbnNvckRhdGE7XG4gICAgfSk7XG4gIH1cbiAgcmVhZFVpbnQ4VGV4dHVyZUFzRmxvYXQodGQ6IFRleHR1cmVEYXRhKTogRmxvYXQzMkFycmF5IHtcbiAgICByZXR1cm4gdGhpcy5wcm9maWxlci5ldmVudCgnYmFja2VuZCcsICdUZXh0dXJlTWFuYWdlci5yZWFkVWludDhUZXh0dXJlQXNGbG9hdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGRhdGFTaXplID0gdGQuc2hhcGUucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5nbENvbnRleHQucmVhZFRleHR1cmUodGQudGV4dHVyZSwgdGQud2lkdGgsIHRkLmhlaWdodCwgZGF0YVNpemUgKiA0LCAnYnl0ZScsIDQpO1xuICAgICAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoZGF0YS5idWZmZXIsIGRhdGEuYnl0ZU9mZnNldCwgZGF0YVNpemUpO1xuICAgIH0pO1xuICB9XG4gIHJlbGVhc2VUZXh0dXJlKHRleHR1cmVEYXRhOiBUZXh0dXJlRGF0YSwgZGVsZXRlVGV4dHVyZT86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBsZXQga2V5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMuY29uZmlnLnJldXNlVGV4dHVyZXMpIHtcbiAgICAgIGtleSA9IHRoaXMudGV4dHVyZUxvb2t1cC5nZXQodGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgICBpZiAoa2V5KSB7XG4gICAgICAgIGlmIChkZWxldGVUZXh0dXJlKSB7XG4gICAgICAgICAgdGhpcy50ZXh0dXJlTG9va3VwLmRlbGV0ZShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGluVXNlVGV4dHVyZXMgPSB0aGlzLmluVXNlVGV4dHVyZXMuZ2V0KGtleSk7XG4gICAgICAgIGlmIChpblVzZVRleHR1cmVzKSB7XG4gICAgICAgICAgY29uc3QgaW5kZXggPSBpblVzZVRleHR1cmVzLmluZGV4T2YodGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgaW5Vc2VUZXh0dXJlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgbGV0IGlkbGVUZXh0dXJlcyA9IHRoaXMuaWRsZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgICAgICAgaWYgKCFpZGxlVGV4dHVyZXMpIHtcbiAgICAgICAgICAgICAgaWRsZVRleHR1cmVzID0gW107XG4gICAgICAgICAgICAgIHRoaXMuaWRsZVRleHR1cmVzLnNldChrZXksIGlkbGVUZXh0dXJlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZGxlVGV4dHVyZXMucHVzaCh0ZXh0dXJlRGF0YS50ZXh0dXJlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWtleSB8fCBkZWxldGVUZXh0dXJlKSB7XG4gICAgICBMb2dnZXIudmVyYm9zZSgnVGV4dHVyZU1hbmFnZXInLCBgRGVsZXRpbmcgdGV4dHVyZSBvZiBzaXplICR7dGV4dHVyZURhdGEud2lkdGh9eCR7dGV4dHVyZURhdGEuaGVpZ2h0fWApO1xuICAgICAgdGhpcy5nbENvbnRleHQuZGVsZXRlVGV4dHVyZSh0ZXh0dXJlRGF0YS50ZXh0dXJlKTtcbiAgICB9XG4gIH1cbiAgdG9UZW5zb3JEYXRhKGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsIGRhdGE6IEVuY29kZXIuRGF0YUFycmF5VHlwZSk6IFRlbnNvci5OdW1iZXJUeXBlIHtcbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgSW50MTZBcnJheSA/IGRhdGEgOiBJbnQxNkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgSW50MzJBcnJheSA/IGRhdGEgOiBJbnQzMkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBJbnQ4QXJyYXkgPyBkYXRhIDogSW50OEFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICd1aW50MTYnOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIFVpbnQxNkFycmF5ID8gZGF0YSA6IFVpbnQxNkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIFVpbnQzMkFycmF5ID8gZGF0YSA6IFVpbnQzMkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICBjYXNlICdib29sJzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5ID8gZGF0YSA6IFVpbnQ4QXJyYXkuZnJvbShkYXRhKTtcbiAgICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSA/IGRhdGEgOiBGbG9hdDMyQXJyYXkuZnJvbShkYXRhKTtcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSA/IGRhdGEgOiBGbG9hdDY0QXJyYXkuZnJvbShkYXRhKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVGVuc29yRGF0YSB0eXBlICR7ZGF0YVR5cGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICB9XG4gIH1cbiAgdG9UZXh0dXJlRGF0YShfZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSwgZGF0YTogVGVuc29yLk51bWJlclR5cGUgfCB1bmRlZmluZWQpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUgfCB1bmRlZmluZWQge1xuICAgIGlmICghZGF0YSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyBkYXRhIDogbmV3IEZsb2F0MzJBcnJheShkYXRhKTtcbiAgICAvKlxuICAgIHN3aXRjaCAoZGF0YVR5cGUpIHtcbiAgICAgIGNhc2UgJ2ludDE2JzpcbiAgICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgICByZXR1cm4gKGRhdGEuY29uc3RydWN0b3IgPT09IFVpbnQzMkFycmF5KSA/IGRhdGEgYXMgVWludDMyQXJyYXkgOiBuZXcgVWludDMyQXJyYXkoZGF0YSk7XG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgIGNhc2UgJ2Jvb2wnOlxuICAgICAgICByZXR1cm4gKGRhdGEuY29uc3RydWN0b3IgPT09IFVpbnQ4QXJyYXkpID8gZGF0YSBhcyBVaW50OEFycmF5IDogbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gKGRhdGEuY29uc3RydWN0b3IgPT09IEZsb2F0MzJBcnJheSkgPyBkYXRhIGFzIEZsb2F0MzJBcnJheSA6IG5ldyBGbG9hdDMyQXJyYXkoZGF0YSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlbnNvckRhdGEgdHlwZSAke2RhdGFUeXBlfSBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gICAgfVxuICAgICovXG4gIH1cbiAgdG9FbmNvZGVyVHlwZShfZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSk6IEVuY29kZXIuRGF0YVR5cGUge1xuICAgIHJldHVybiAnZmxvYXQnO1xuICAgIC8vIHN3aXRjaCAoZGF0YVR5cGUpIHtcbiAgICAvLyAgIGNhc2UgJ2ludDE2JzpcbiAgICAvLyAgIGNhc2UgJ2ludDMyJzpcbiAgICAvLyAgIGNhc2UgJ3VpbnQxNic6XG4gICAgLy8gICBjYXNlICd1aW50MzInOlxuICAgIC8vICAgICByZXR1cm4gJ2ludCc7XG4gICAgLy8gICBjYXNlICd1aW50OCc6XG4gICAgLy8gICBjYXNlICdib29sJzpcbiAgICAvLyAgICAgcmV0dXJuICdieXRlJztcbiAgICAvLyAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgIC8vICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgLy8gICAgIHJldHVybiAnZmxvYXQnO1xuICAgIC8vICAgZGVmYXVsdDpcbiAgICAvLyAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW5zb3JEYXRhIHR5cGUgJHtkYXRhVHlwZX0gaXMgbm90IHN1cHBvcnRlZGApO1xuICAgIC8vIH1cbiAgfVxuICBjbGVhckFjdGl2ZVRleHR1cmVzKCk6IHZvaWQge1xuICAgIHRoaXMuZ2xDb250ZXh0LmNsZWFyQWN0aXZlVGV4dHVyZXMoKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBTZXNzaW9uSGFuZGxlciB9IGZyb20gJy4uLy4uL2JhY2tlbmQnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IE9wU2V0LCByZXNvbHZlT3BlcmF0b3IgfSBmcm9tICcuLi8uLi9vcHNldCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vc2Vzc2lvbic7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xCYWNrZW5kIH0gZnJvbSAnLi4vYmFja2VuZC13ZWJnbCc7XG5cbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgV0VCR0xfT1BfUkVTT0xWRV9SVUxFUyB9IGZyb20gJy4vb3AtcmVzb2x2ZS1ydWxlcyc7XG5pbXBvcnQgeyBQcm9ncmFtTWFuYWdlciB9IGZyb20gJy4vcHJvZ3JhbS1tYW5hZ2VyJztcbmltcG9ydCB7IFByZWZlckxvZ2ljYWxTdHJhdGVneSwgVGV4dHVyZUxheW91dFN0cmF0ZWd5IH0gZnJvbSAnLi90ZXh0dXJlLWxheW91dC1zdHJhdGVneSc7XG5pbXBvcnQgeyBUZXh0dXJlTWFuYWdlciB9IGZyb20gJy4vdGV4dHVyZS1tYW5hZ2VyJztcbmltcG9ydCB7IFRleHR1cmVEYXRhIH0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBXZWJHTFNlc3Npb25IYW5kbGVyIGltcGxlbWVudHMgU2Vzc2lvbkhhbmRsZXIge1xuICBwcm9ncmFtTWFuYWdlcjogUHJvZ3JhbU1hbmFnZXI7XG4gIHRleHR1cmVNYW5hZ2VyOiBUZXh0dXJlTWFuYWdlcjtcbiAgbGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneTtcbiAgcGFja2VkVGV4dHVyZURhdGFDYWNoZTogTWFwPFRlbnNvci5JZCwgVGV4dHVyZURhdGE+O1xuICB1bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGU6IE1hcDxUZW5zb3IuSWQsIFRleHR1cmVEYXRhPjtcbiAgcGFjazJ1bnBhY2tNYXA6IE1hcDxUZW5zb3IuSWQsIFRlbnNvci5JZD47XG4gIHVucGFjazJwYWNrTWFwOiBNYXA8VGVuc29yLklkLCBUZW5zb3IuSWQ+O1xuICBpbml0aWFsaXplcnM6IFNldDxUZW5zb3IuSWQ+O1xuICBwYWNrPzogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgcmVhZG9ubHkgYmFja2VuZDogV2ViR0xCYWNrZW5kLFxuICAgIHB1YmxpYyByZWFkb25seSBjb250ZXh0OiBTZXNzaW9uLkNvbnRleHQsXG4gICkge1xuICAgIHRoaXMubGF5b3V0U3RyYXRlZ3kgPSBuZXcgUHJlZmVyTG9naWNhbFN0cmF0ZWd5KGJhY2tlbmQuZ2xDb250ZXh0Lm1heFRleHR1cmVTaXplKTtcbiAgICB0aGlzLnByb2dyYW1NYW5hZ2VyID0gbmV3IFByb2dyYW1NYW5hZ2VyKHRoaXMuY29udGV4dC5wcm9maWxlciwgYmFja2VuZC5nbENvbnRleHQsIHRoaXMubGF5b3V0U3RyYXRlZ3kpO1xuICAgIHRoaXMudGV4dHVyZU1hbmFnZXIgPSBuZXcgVGV4dHVyZU1hbmFnZXIoYmFja2VuZC5nbENvbnRleHQsIHRoaXMubGF5b3V0U3RyYXRlZ3ksIHRoaXMuY29udGV4dC5wcm9maWxlciwge1xuICAgICAgcmV1c2VUZXh0dXJlczogYmFja2VuZC50ZXh0dXJlQ2FjaGVNb2RlID09PSAnZnVsbCcsXG4gICAgfSk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMucGFjayA9IGJhY2tlbmQucGFjaztcbiAgICB0aGlzLnBhY2sydW5wYWNrTWFwID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrMnBhY2tNYXAgPSBuZXcgTWFwKCk7XG4gIH1cblxuICBjcmVhdGVJbmZlcmVuY2VIYW5kbGVyKCkge1xuICAgIHJldHVybiBuZXcgV2ViR0xJbmZlcmVuY2VIYW5kbGVyKHRoaXMpO1xuICB9XG4gIG9uR3JhcGhJbml0aWFsaXplZChncmFwaDogR3JhcGgpOiB2b2lkIHtcbiAgICBjb25zdCBpbml0aWFsaXplcnMgPSBncmFwaFxuICAgICAgLmdldFZhbHVlcygpXG4gICAgICAuZmlsdGVyKCh2KSA9PiB2LmZyb20gPT09IC0xICYmIHYudGVuc29yKVxuICAgICAgLm1hcCgodikgPT4gdi50ZW5zb3IhLmRhdGFJZCk7XG4gICAgdGhpcy5pbml0aWFsaXplcnMgPSBuZXcgU2V0KGluaXRpYWxpemVycyk7XG4gIH1cbiAgaXNJbml0aWFsaXplcih0ZW5zb3JJZDogVGVuc29yLklkKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaW5pdGlhbGl6ZXJzID8gdGhpcy5pbml0aWFsaXplcnMuaGFzKHRlbnNvcklkKSA6IGZhbHNlO1xuICB9XG4gIGFkZEluaXRpYWxpemVyKHRlbnNvcklkOiBUZW5zb3IuSWQpOiB2b2lkIHtcbiAgICB0aGlzLmluaXRpYWxpemVycy5hZGQodGVuc29ySWQpO1xuICB9XG4gIGdldFRleHR1cmVEYXRhKHRlbnNvcklkOiBUZW5zb3IuSWQsIGlzUGFja2VkOiBib29sZWFuKTogVGV4dHVyZURhdGEgfCB1bmRlZmluZWQge1xuICAgIGlmIChpc1BhY2tlZCkge1xuICAgICAgcmV0dXJuIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5nZXQodGVuc29ySWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZ2V0KHRlbnNvcklkKTtcbiAgICB9XG4gIH1cbiAgc2V0VGV4dHVyZURhdGEodGVuc29ySWQ6IFRlbnNvci5JZCwgdGV4dHVyZURhdGE6IFRleHR1cmVEYXRhLCBpc1BhY2tlZCA9IGZhbHNlKTogdm9pZCB7XG4gICAgTG9nZ2VyLnZlcmJvc2UoJ1dlYkdMU2Vzc2lvbkhhbmRsZXInLCAnU3RvcmluZyBUZXh0dXJlIGRhdGEgaW4gY2FjaGUnKTtcbiAgICBpZiAoaXNQYWNrZWQpIHtcbiAgICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5zZXQodGVuc29ySWQsIHRleHR1cmVEYXRhKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuc2V0KHRlbnNvcklkLCB0ZXh0dXJlRGF0YSk7XG4gICAgfVxuICB9XG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5wcm9ncmFtTWFuYWdlci5kaXNwb3NlKCk7XG4gICAgdGhpcy50ZXh0dXJlTWFuYWdlci5jbGVhckFjdGl2ZVRleHR1cmVzKCk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmZvckVhY2goKHRkKSA9PiB0aGlzLnRleHR1cmVNYW5hZ2VyLnJlbGVhc2VUZXh0dXJlKHRkLCB0cnVlKSk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmZvckVhY2goKHRkKSA9PiB0aGlzLnRleHR1cmVNYW5hZ2VyLnJlbGVhc2VUZXh0dXJlKHRkLCB0cnVlKSk7XG4gICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gIH1cbiAgcmVzb2x2ZShub2RlOiBHcmFwaC5Ob2RlLCBvcHNldHM6IHJlYWRvbmx5IE9wU2V0W10sIGdyYXBoOiBHcmFwaCk6IE9wZXJhdG9yIHtcbiAgICBjb25zdCBvcCA9IHJlc29sdmVPcGVyYXRvcihub2RlLCBvcHNldHMsIFdFQkdMX09QX1JFU09MVkVfUlVMRVMpO1xuICAgIHJldHVybiB7IGltcGw6IG9wLm9wSW1wbCwgY29udGV4dDogb3Aub3BJbml0ID8gb3Aub3BJbml0KG5vZGUsIGdyYXBoKSA6IG5vZGUgfTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBlbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgKiBhcyBEYXRhRW5jb2RlcnMgZnJvbSAnLi90ZXh0dXJlLWRhdGEtZW5jb2Rlcic7XG5pbXBvcnQgeyBEYXRhRW5jb2RlciwgRW5jb2RlciwgRW5jb2RlclVzYWdlIH0gZnJvbSAnLi90ZXh0dXJlLWRhdGEtZW5jb2Rlcic7XG5pbXBvcnQgeyByZXBlYXRlZFRyeSB9IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZlbmNlQ29udGV4dCB7XG4gIHF1ZXJ5OiBXZWJHTFN5bmMgfCBudWxsO1xuICBpc0ZlbmNlUGFzc2VkKCk6IGJvb2xlYW47XG59XG5cbnR5cGUgUG9sbEl0ZW0gPSB7XG4gIGlzRG9uZUZuOiAoKSA9PiBib29sZWFuO1xuICByZXNvbHZlRm46ICgpID0+IHZvaWQ7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gbGluZWFyU2VhcmNoTGFzdFRydWUoYXJyOiBBcnJheTwoKSA9PiBib29sZWFuPik6IG51bWJlciB7XG4gIGxldCBpID0gMDtcbiAgZm9yICg7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHtcbiAgICBjb25zdCBpc0RvbmUgPSBhcnJbaV0oKTtcbiAgICBpZiAoIWlzRG9uZSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBpIC0gMTtcbn1cblxuLyoqXG4gKiBBYnN0cmFjdGlvbiBhbmQgd3JhcHBlciBhcm91bmQgV2ViR0xSZW5kZXJpbmdDb250ZXh0IGFuZCBpdHMgb3BlcmF0aW9uc1xuICovXG5leHBvcnQgY2xhc3MgV2ViR0xDb250ZXh0IHtcbiAgZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dDtcbiAgdmVyc2lvbjogMSB8IDI7XG5cbiAgcHJpdmF0ZSB2ZXJ0ZXhidWZmZXI6IFdlYkdMQnVmZmVyO1xuICBwcml2YXRlIGZyYW1lYnVmZmVyOiBXZWJHTEZyYW1lYnVmZmVyO1xuXG4gIC8vIFdlYkdMIGZsYWdzIGFuZCB2aXRhbCBwYXJhbWV0ZXJzXG4gIHByaXZhdGUgaXNGbG9hdFRleHR1cmVBdHRhY2hhYmxlVG9GcmFtZUJ1ZmZlcjogYm9vbGVhbjtcbiAgaXNGbG9hdDMyRG93bmxvYWRTdXBwb3J0ZWQ6IGJvb2xlYW47XG4gIGlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZDogYm9vbGVhbjtcbiAgaXNCbGVuZFN1cHBvcnRlZDogYm9vbGVhbjtcbiAgbWF4VGV4dHVyZVNpemU6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBtYXhDb21iaW5lZFRleHR1cmVJbWFnZVVuaXRzOiBudW1iZXI7XG4gIHByaXZhdGUgbWF4VGV4dHVyZUltYWdlVW5pdHM6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBtYXhDdWJlTWFwVGV4dHVyZVNpemU6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBzaGFkaW5nTGFuZ3VhZ2VWZXJzaW9uOiBzdHJpbmc7XG4gIC8vIHByaXZhdGUgd2ViZ2xWZW5kb3I6IHN0cmluZztcbiAgLy8gcHJpdmF0ZSB3ZWJnbFZlcnNpb246IHN0cmluZztcblxuICAvLyBXZWJHTDIgZmxhZ3MgYW5kIHZpdGFsIHBhcmFtZXRlcnNcbiAgLy8gcHJpdmF0ZSBtYXgzRFRleHR1cmVTaXplOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4QXJyYXlUZXh0dXJlTGF5ZXJzOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4Q29sb3JBdHRhY2htZW50czogbnVtYmVyO1xuICAvLyBwcml2YXRlIG1heERyYXdCdWZmZXJzOiBudW1iZXI7XG5cbiAgLy8gV2ViR0wgZXh0ZW5zaW9uc1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2FtZWxjYXNlXG4gIHRleHR1cmVGbG9hdEV4dGVuc2lvbjogT0VTX3RleHR1cmVfZmxvYXQgfCBudWxsO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2FtZWxjYXNlXG4gIHRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb246IE9FU190ZXh0dXJlX2hhbGZfZmxvYXQgfCBudWxsO1xuXG4gIC8vIFdlYkdMMiBleHRlbnNpb25zXG4gIGNvbG9yQnVmZmVyRmxvYXRFeHRlbnNpb246IHVua25vd24gfCBudWxsO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG4gIGRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbjogeyBUSU1FX0VMQVBTRURfRVhUOiBHTGVudW07IEdQVV9ESVNKT0lOVF9FWFQ6IEdMZW51bSB9IHwgbnVsbDtcblxuICBwcml2YXRlIGRpc3Bvc2VkOiBib29sZWFuO1xuICBwcml2YXRlIGZyYW1lQnVmZmVyQm91bmQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCB2ZXJzaW9uOiAxIHwgMikge1xuICAgIHRoaXMuZ2wgPSBnbDtcbiAgICB0aGlzLnZlcnNpb24gPSB2ZXJzaW9uO1xuXG4gICAgdGhpcy5nZXRFeHRlbnNpb25zKCk7XG4gICAgdGhpcy52ZXJ0ZXhidWZmZXIgPSB0aGlzLmNyZWF0ZVZlcnRleGJ1ZmZlcigpO1xuICAgIHRoaXMuZnJhbWVidWZmZXIgPSB0aGlzLmNyZWF0ZUZyYW1lYnVmZmVyKCk7XG4gICAgdGhpcy5xdWVyeVZpdGFsUGFyYW1ldGVycygpO1xuICB9XG5cbiAgYWxsb2NhdGVUZXh0dXJlKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBlbmNvZGVyOiBEYXRhRW5jb2RlciwgZGF0YT86IEVuY29kZXIuRGF0YUFycmF5VHlwZSk6IFdlYkdMVGV4dHVyZSB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIC8vIGNyZWF0ZSB0aGUgdGV4dHVyZVxuICAgIGNvbnN0IHRleHR1cmUgPSBnbC5jcmVhdGVUZXh0dXJlKCk7XG4gICAgLy8gYmluZCB0aGUgdGV4dHVyZSBzbyB0aGUgZm9sbG93aW5nIG1ldGhvZHMgZWZmZWN0IHRoaXMgdGV4dHVyZS5cbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfTUlOX0ZJTFRFUiwgZ2wuTkVBUkVTVCk7XG4gICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01BR19GSUxURVIsIGdsLk5FQVJFU1QpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1MsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1QsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgIGNvbnN0IGJ1ZmZlciA9IGRhdGEgPyBlbmNvZGVyLmVuY29kZShkYXRhLCB3aWR0aCAqIGhlaWdodCkgOiBudWxsO1xuICAgIGdsLnRleEltYWdlMkQoXG4gICAgICBnbC5URVhUVVJFXzJELFxuICAgICAgMCwgLy8gTGV2ZWwgb2YgZGV0YWlsLlxuICAgICAgZW5jb2Rlci5pbnRlcm5hbEZvcm1hdCxcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgMCwgLy8gQWx3YXlzIDAgaW4gT3BlbkdMIEVTLlxuICAgICAgZW5jb2Rlci5mb3JtYXQsXG4gICAgICBlbmNvZGVyLnRleHR1cmVUeXBlLFxuICAgICAgYnVmZmVyLFxuICAgICk7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgcmV0dXJuIHRleHR1cmUgYXMgV2ViR0xUZXh0dXJlO1xuICB9XG4gIHVwZGF0ZVRleHR1cmUoXG4gICAgdGV4dHVyZTogV2ViR0xUZXh0dXJlLFxuICAgIHdpZHRoOiBudW1iZXIsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICAgZW5jb2RlcjogRGF0YUVuY29kZXIsXG4gICAgZGF0YTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgY29uc3QgYnVmZmVyID0gZW5jb2Rlci5lbmNvZGUoZGF0YSwgd2lkdGggKiBoZWlnaHQpO1xuICAgIGdsLnRleFN1YkltYWdlMkQoXG4gICAgICBnbC5URVhUVVJFXzJELFxuICAgICAgMCwgLy8gbGV2ZWxcbiAgICAgIDAsIC8vIHhvZmZzZXRcbiAgICAgIDAsIC8vIHlvZmZzZXRcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgZW5jb2Rlci5mb3JtYXQsXG4gICAgICBlbmNvZGVyLnRleHR1cmVUeXBlLFxuICAgICAgYnVmZmVyLFxuICAgICk7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gIH1cbiAgYXR0YWNoRnJhbWVidWZmZXIodGV4dHVyZTogV2ViR0xUZXh0dXJlLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAvLyBNYWtlIGl0IHRoZSB0YXJnZXQgZm9yIGZyYW1lYnVmZmVyIG9wZXJhdGlvbnMgLSBpbmNsdWRpbmcgcmVuZGVyaW5nLlxuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgdGhpcy5mcmFtZWJ1ZmZlcik7XG4gICAgZ2wuZnJhbWVidWZmZXJUZXh0dXJlMkQoZ2wuRlJBTUVCVUZGRVIsIGdsLkNPTE9SX0FUVEFDSE1FTlQwLCBnbC5URVhUVVJFXzJELCB0ZXh0dXJlLCAwKTsgLy8gMCwgd2UgYXJlbid0IHVzaW5nIE1JUE1BUHNcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICBnbC52aWV3cG9ydCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICBnbC5zY2lzc29yKDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuICB9XG4gIHJlYWRUZXh0dXJlKFxuICAgIHRleHR1cmU6IFdlYkdMVGV4dHVyZSxcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIGRhdGFTaXplOiBudW1iZXIsXG4gICAgZGF0YVR5cGU6IEVuY29kZXIuRGF0YVR5cGUsXG4gICAgY2hhbm5lbHM6IG51bWJlcixcbiAgKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgaWYgKCFjaGFubmVscykge1xuICAgICAgY2hhbm5lbHMgPSAxO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuZnJhbWVCdWZmZXJCb3VuZCkge1xuICAgICAgdGhpcy5hdHRhY2hGcmFtZWJ1ZmZlcih0ZXh0dXJlLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICB9XG4gICAgY29uc3QgZW5jb2RlciA9IHRoaXMuZ2V0RW5jb2RlcihkYXRhVHlwZSwgY2hhbm5lbHMpO1xuICAgIGNvbnN0IGJ1ZmZlciA9IGVuY29kZXIuYWxsb2NhdGUod2lkdGggKiBoZWlnaHQpO1xuICAgIC8vIGJpbmQgdGV4dHVyZSB0byBmcmFtZWJ1ZmZlclxuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSwgMCk7IC8vIDAsIHdlIGFyZW4ndCB1c2luZyBNSVBNQVBzXG4gICAgLy8gVE9ETzogQ2hlY2sgaWYgZnJhbWVidWZmZXIgaXMgcmVhZHlcbiAgICBnbC5yZWFkUGl4ZWxzKDAsIDAsIHdpZHRoLCBoZWlnaHQsIGdsLlJHQkEsIGVuY29kZXIudGV4dHVyZVR5cGUsIGJ1ZmZlcik7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgLy8gdW5iaW5kIEZCXG4gICAgcmV0dXJuIGVuY29kZXIuZGVjb2RlKGJ1ZmZlciwgZGF0YVNpemUpO1xuICB9XG5cbiAgaXNGcmFtZWJ1ZmZlclJlYWR5KCk6IGJvb2xlYW4ge1xuICAgIC8vIFRPRE86IEltcGxlbWVudCBsb2dpYyB0byBjaGVjayBpZiB0aGUgZnJhbWVidWZmZXIgaXMgcmVhZHlcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBnZXRBY3RpdmVUZXh0dXJlKCk6IHN0cmluZyB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGNvbnN0IG4gPSBnbC5nZXRQYXJhbWV0ZXIodGhpcy5nbC5BQ1RJVkVfVEVYVFVSRSk7XG4gICAgcmV0dXJuIGBURVhUVVJFJHtuIC0gZ2wuVEVYVFVSRTB9YDtcbiAgfVxuICBnZXRUZXh0dXJlQmluZGluZygpOiBXZWJHTFRleHR1cmUge1xuICAgIHJldHVybiB0aGlzLmdsLmdldFBhcmFtZXRlcih0aGlzLmdsLlRFWFRVUkVfQklORElOR18yRCk7XG4gIH1cbiAgZ2V0RnJhbWVidWZmZXJCaW5kaW5nKCk6IFdlYkdMRnJhbWVidWZmZXIge1xuICAgIHJldHVybiB0aGlzLmdsLmdldFBhcmFtZXRlcih0aGlzLmdsLkZSQU1FQlVGRkVSX0JJTkRJTkcpO1xuICB9XG4gIHNldFZlcnRleEF0dHJpYnV0ZXMocG9zaXRpb25IYW5kbGU6IG51bWJlciwgdGV4dHVyZUNvb3JkSGFuZGxlOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcihwb3NpdGlvbkhhbmRsZSwgMywgZ2wuRkxPQVQsIGZhbHNlLCAyMCwgMCk7XG4gICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkocG9zaXRpb25IYW5kbGUpO1xuICAgIGlmICh0ZXh0dXJlQ29vcmRIYW5kbGUgIT09IC0xKSB7XG4gICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHRleHR1cmVDb29yZEhhbmRsZSwgMiwgZ2wuRkxPQVQsIGZhbHNlLCAyMCwgMTIpO1xuICAgICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkodGV4dHVyZUNvb3JkSGFuZGxlKTtcbiAgICB9XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gIH1cbiAgY3JlYXRlUHJvZ3JhbSh2ZXJ0ZXhTaGFkZXI6IFdlYkdMU2hhZGVyLCBmcmFnU2hhZGVyOiBXZWJHTFNoYWRlcik6IFdlYkdMUHJvZ3JhbSB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGNvbnN0IHByb2dyYW0gPSBnbC5jcmVhdGVQcm9ncmFtKCkhO1xuXG4gICAgLy8gdGhlIHByb2dyYW0gY29uc2lzdHMgb2Ygb3VyIHNoYWRlcnNcbiAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgdmVydGV4U2hhZGVyKTtcbiAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgZnJhZ1NoYWRlcik7XG4gICAgZ2wubGlua1Byb2dyYW0ocHJvZ3JhbSk7XG4gICAgcmV0dXJuIHByb2dyYW07XG4gIH1cbiAgY29tcGlsZVNoYWRlcihzaGFkZXJTb3VyY2U6IHN0cmluZywgc2hhZGVyVHlwZTogbnVtYmVyKTogV2ViR0xTaGFkZXIge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBzaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoc2hhZGVyVHlwZSk7XG4gICAgaWYgKCFzaGFkZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgY3JlYXRlU2hhZGVyKCkgcmV0dXJuZWQgbnVsbCB3aXRoIHR5cGUgJHtzaGFkZXJUeXBlfWApO1xuICAgIH1cblxuICAgIGdsLnNoYWRlclNvdXJjZShzaGFkZXIsIHNoYWRlclNvdXJjZSk7XG4gICAgZ2wuY29tcGlsZVNoYWRlcihzaGFkZXIpO1xuICAgIGlmIChnbC5nZXRTaGFkZXJQYXJhbWV0ZXIoc2hhZGVyLCBnbC5DT01QSUxFX1NUQVRVUykgPT09IGZhbHNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBjb21waWxlIHNoYWRlcjogJHtnbC5nZXRTaGFkZXJJbmZvTG9nKHNoYWRlcil9XG5TaGFkZXIgc291cmNlOlxuJHtzaGFkZXJTb3VyY2V9YCk7XG4gICAgfVxuICAgIHJldHVybiBzaGFkZXI7XG4gIH1cbiAgZGVsZXRlU2hhZGVyKHNoYWRlcjogV2ViR0xTaGFkZXIpOiB2b2lkIHtcbiAgICB0aGlzLmdsLmRlbGV0ZVNoYWRlcihzaGFkZXIpO1xuICB9XG4gIGJpbmRUZXh0dXJlVG9Vbmlmb3JtKHRleHR1cmU6IFdlYkdMVGV4dHVyZSwgcG9zaXRpb246IG51bWJlciwgdW5pZm9ybUhhbmRsZTogV2ViR0xVbmlmb3JtTG9jYXRpb24pOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZ2wuYWN0aXZlVGV4dHVyZShnbC5URVhUVVJFMCArIHBvc2l0aW9uKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICBnbC51bmlmb3JtMWkodW5pZm9ybUhhbmRsZSwgcG9zaXRpb24pO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGRyYXcoKTogdm9pZCB7XG4gICAgdGhpcy5nbC5kcmF3QXJyYXlzKHRoaXMuZ2wuVFJJQU5HTEVfU1RSSVAsIDAsIDQpO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGNoZWNrRXJyb3IoKTogdm9pZCB7XG4gICAgaWYgKGVudi5kZWJ1Zykge1xuICAgICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgICAgY29uc3QgZXJyb3IgPSBnbC5nZXRFcnJvcigpO1xuICAgICAgbGV0IGxhYmVsID0gJyc7XG4gICAgICBzd2l0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNhc2UgZ2wuTk9fRVJST1I6XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjYXNlIGdsLklOVkFMSURfRU5VTTpcbiAgICAgICAgICBsYWJlbCA9ICdJTlZBTElEX0VOVU0nO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIGdsLklOVkFMSURfVkFMVUU6XG4gICAgICAgICAgbGFiZWwgPSAnSU5WQUxJRF9WQUxVRSc7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgZ2wuSU5WQUxJRF9PUEVSQVRJT046XG4gICAgICAgICAgbGFiZWwgPSAnSU5WQUxJRF9PUEVSQVRJT04nO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIGdsLklOVkFMSURfRlJBTUVCVUZGRVJfT1BFUkFUSU9OOlxuICAgICAgICAgIGxhYmVsID0gJ0lOVkFMSURfRlJBTUVCVUZGRVJfT1BFUkFUSU9OJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBnbC5PVVRfT0ZfTUVNT1JZOlxuICAgICAgICAgIGxhYmVsID0gJ09VVF9PRl9NRU1PUlknO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIGdsLkNPTlRFWFRfTE9TVF9XRUJHTDpcbiAgICAgICAgICBsYWJlbCA9ICdDT05URVhUX0xPU1RfV0VCR0wnO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGxhYmVsID0gYFVua25vd24gV2ViR0wgRXJyb3I6ICR7ZXJyb3IudG9TdHJpbmcoMTYpfWA7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IobGFiZWwpO1xuICAgIH1cbiAgfVxuICBkZWxldGVUZXh0dXJlKHRleHR1cmU6IFdlYkdMVGV4dHVyZSk6IHZvaWQge1xuICAgIHRoaXMuZ2wuZGVsZXRlVGV4dHVyZSh0ZXh0dXJlKTtcbiAgfVxuICBkZWxldGVQcm9ncmFtKHByb2dyYW06IFdlYkdMUHJvZ3JhbSk6IHZvaWQge1xuICAgIHRoaXMuZ2wuZGVsZXRlUHJvZ3JhbShwcm9ncmFtKTtcbiAgfVxuICBnZXRFbmNvZGVyKGRhdGFUeXBlOiBFbmNvZGVyLkRhdGFUeXBlLCBjaGFubmVsczogbnVtYmVyLCB1c2FnZTogRW5jb2RlclVzYWdlID0gRW5jb2RlclVzYWdlLkRlZmF1bHQpOiBEYXRhRW5jb2RlciB7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikge1xuICAgICAgcmV0dXJuIG5ldyBEYXRhRW5jb2RlcnMuUmVkRmxvYXQzMkRhdGFFbmNvZGVyKHRoaXMuZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dCwgY2hhbm5lbHMpO1xuICAgIH1cblxuICAgIHN3aXRjaCAoZGF0YVR5cGUpIHtcbiAgICAgIGNhc2UgJ2Zsb2F0JzpcbiAgICAgICAgaWYgKHVzYWdlID09PSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSB8fCB0aGlzLmlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZCkge1xuICAgICAgICAgIHJldHVybiBuZXcgRGF0YUVuY29kZXJzLlJHQkFGbG9hdERhdGFFbmNvZGVyKHRoaXMuZ2wsIGNoYW5uZWxzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbmV3IERhdGFFbmNvZGVycy5SR0JBRmxvYXREYXRhRW5jb2RlcihcbiAgICAgICAgICAgIHRoaXMuZ2wsXG4gICAgICAgICAgICBjaGFubmVscyxcbiAgICAgICAgICAgIHRoaXMudGV4dHVyZUhhbGZGbG9hdEV4dGVuc2lvbiEuSEFMRl9GTE9BVF9PRVMsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgY2FzZSAnaW50JzpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKTtcbiAgICAgIGNhc2UgJ2J5dGUnOlxuICAgICAgICByZXR1cm4gbmV3IERhdGFFbmNvZGVycy5VaW50OERhdGFFbmNvZGVyKHRoaXMuZ2wsIGNoYW5uZWxzKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkYXRhVHlwZTogJHtkYXRhVHlwZX1gKTtcbiAgICB9XG4gIH1cbiAgY2xlYXJBY3RpdmVUZXh0dXJlcygpOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZm9yIChsZXQgdW5pdCA9IDA7IHVuaXQgPCB0aGlzLm1heFRleHR1cmVJbWFnZVVuaXRzOyArK3VuaXQpIHtcbiAgICAgIGdsLmFjdGl2ZVRleHR1cmUoZ2wuVEVYVFVSRTAgKyB1bml0KTtcbiAgICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIG51bGwpO1xuICAgIH1cbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc3Bvc2VkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIG51bGwpO1xuICAgIGdsLmRlbGV0ZUZyYW1lYnVmZmVyKHRoaXMuZnJhbWVidWZmZXIpO1xuICAgIGdsLmJpbmRCdWZmZXIoZ2wuQVJSQVlfQlVGRkVSLCBudWxsKTtcbiAgICBnbC5kZWxldGVCdWZmZXIodGhpcy52ZXJ0ZXhidWZmZXIpO1xuICAgIGdsLmJpbmRCdWZmZXIoZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVIsIG51bGwpO1xuICAgIGdsLmZpbmlzaCgpO1xuICAgIHRoaXMuZGlzcG9zZWQgPSB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVEZWZhdWx0R2VvbWV0cnkoKTogRmxvYXQzMkFycmF5IHtcbiAgICAvLyBTZXRzIG9mIHgseSx6KD0wKSxzLHQgY29vcmRpbmF0ZXMuXG4gICAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoW1xuICAgICAgLTEuMCxcbiAgICAgIDEuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDEuMCwgLy8gdXBwZXIgbGVmdFxuICAgICAgLTEuMCxcbiAgICAgIC0xLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjAsIC8vIGxvd2VyIGxlZnRcbiAgICAgIDEuMCxcbiAgICAgIDEuMCxcbiAgICAgIDAuMCxcbiAgICAgIDEuMCxcbiAgICAgIDEuMCwgLy8gdXBwZXIgcmlnaHRcbiAgICAgIDEuMCxcbiAgICAgIC0xLjAsXG4gICAgICAwLjAsXG4gICAgICAxLjAsXG4gICAgICAwLjAsIC8vIGxvd2VyIHJpZ2h0XG4gICAgXSk7XG4gIH1cbiAgcHJpdmF0ZSBjcmVhdGVWZXJ0ZXhidWZmZXIoKTogV2ViR0xCdWZmZXIge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBidWZmZXIgPSBnbC5jcmVhdGVCdWZmZXIoKTtcbiAgICBpZiAoIWJ1ZmZlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjcmVhdGVCdWZmZXIoKSByZXR1cm5lZCBudWxsJyk7XG4gICAgfVxuICAgIGNvbnN0IGdlb21ldHJ5ID0gdGhpcy5jcmVhdGVEZWZhdWx0R2VvbWV0cnkoKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgYnVmZmVyKTtcbiAgICBnbC5idWZmZXJEYXRhKGdsLkFSUkFZX0JVRkZFUiwgZ2VvbWV0cnksIGdsLlNUQVRJQ19EUkFXKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICByZXR1cm4gYnVmZmVyO1xuICB9XG4gIHByaXZhdGUgY3JlYXRlRnJhbWVidWZmZXIoKTogV2ViR0xGcmFtZWJ1ZmZlciB7XG4gICAgY29uc3QgZmIgPSB0aGlzLmdsLmNyZWF0ZUZyYW1lYnVmZmVyKCk7XG4gICAgaWYgKCFmYikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjcmVhdGVGcmFtZWJ1ZmZlciByZXR1cm5lZCBudWxsJyk7XG4gICAgfVxuICAgIHJldHVybiBmYjtcbiAgfVxuXG4gIHByaXZhdGUgcXVlcnlWaXRhbFBhcmFtZXRlcnMoKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuXG4gICAgdGhpcy5pc0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyID0gdGhpcy5jaGVja0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyKCk7XG4gICAgdGhpcy5pc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQgPSB0aGlzLmNoZWNrUmVuZGVyRmxvYXQzMigpO1xuICAgIHRoaXMuaXNGbG9hdDMyRG93bmxvYWRTdXBwb3J0ZWQgPSB0aGlzLmNoZWNrRmxvYXQzMkRvd25sb2FkKCk7XG5cbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAxICYmICF0aGlzLnRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb24gJiYgIXRoaXMuaXNSZW5kZXJGbG9hdDMyU3VwcG9ydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2JvdGggZmxvYXQzMiBhbmQgZmxvYXQxNiBUZXh0dXJlVHlwZSBhcmUgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cblxuICAgIHRoaXMuaXNCbGVuZFN1cHBvcnRlZCA9ICF0aGlzLmlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZCB8fCB0aGlzLmNoZWNrRmxvYXQzMkJsZW5kKCk7XG5cbiAgICAvLyB0aGlzLm1heENvbWJpbmVkVGV4dHVyZUltYWdlVW5pdHMgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX0NPTUJJTkVEX1RFWFRVUkVfSU1BR0VfVU5JVFMpO1xuICAgIHRoaXMubWF4VGV4dHVyZVNpemUgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX1RFWFRVUkVfU0laRSk7XG4gICAgdGhpcy5tYXhUZXh0dXJlSW1hZ2VVbml0cyA9IGdsLmdldFBhcmFtZXRlcihnbC5NQVhfVEVYVFVSRV9JTUFHRV9VTklUUyk7XG4gICAgLy8gdGhpcy5tYXhDdWJlTWFwVGV4dHVyZVNpemUgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX0NVQkVfTUFQX1RFWFRVUkVfU0laRSk7XG4gICAgLy8gdGhpcy5zaGFkaW5nTGFuZ3VhZ2VWZXJzaW9uID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLlNIQURJTkdfTEFOR1VBR0VfVkVSU0lPTik7XG4gICAgLy8gdGhpcy53ZWJnbFZlbmRvciA9IGdsLmdldFBhcmFtZXRlcihnbC5WRU5ET1IpO1xuICAgIC8vIHRoaXMud2ViZ2xWZXJzaW9uID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLlZFUlNJT04pO1xuXG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikge1xuICAgICAgLy8gdGhpcy5tYXgzRFRleHR1cmVTaXplID0gZ2wuZ2V0UGFyYW1ldGVyKFdlYkdMMlJlbmRlcmluZ0NvbnRleHQuTUFYXzNEX1RFWFRVUkVfU0laRSk7XG4gICAgICAvLyB0aGlzLm1heEFycmF5VGV4dHVyZUxheWVycyA9IGdsLmdldFBhcmFtZXRlcihXZWJHTDJSZW5kZXJpbmdDb250ZXh0Lk1BWF9BUlJBWV9URVhUVVJFX0xBWUVSUyk7XG4gICAgICAvLyB0aGlzLm1heENvbG9yQXR0YWNobWVudHMgPSBnbC5nZXRQYXJhbWV0ZXIoV2ViR0wyUmVuZGVyaW5nQ29udGV4dC5NQVhfQ09MT1JfQVRUQUNITUVOVFMpO1xuICAgICAgLy8gdGhpcy5tYXhEcmF3QnVmZmVycyA9IGdsLmdldFBhcmFtZXRlcihXZWJHTDJSZW5kZXJpbmdDb250ZXh0Lk1BWF9EUkFXX0JVRkZFUlMpO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIGdldEV4dGVuc2lvbnMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikge1xuICAgICAgdGhpcy5jb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uID0gdGhpcy5nbC5nZXRFeHRlbnNpb24oJ0VYVF9jb2xvcl9idWZmZXJfZmxvYXQnKTtcbiAgICAgIHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uID0gdGhpcy5nbC5nZXRFeHRlbnNpb24oJ0VYVF9kaXNqb2ludF90aW1lcl9xdWVyeV93ZWJnbDInKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50ZXh0dXJlRmxvYXRFeHRlbnNpb24gPSB0aGlzLmdsLmdldEV4dGVuc2lvbignT0VTX3RleHR1cmVfZmxvYXQnKTtcbiAgICAgIHRoaXMudGV4dHVyZUhhbGZGbG9hdEV4dGVuc2lvbiA9IHRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0Jyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyKCk6IGJvb2xlYW4ge1xuICAgIC8vIHRlc3Qgd2hldGhlciBGbG9hdDMyIHRleHR1cmUgaXMgc3VwcG9ydGVkOlxuICAgIC8vIFNURVAuMSBjcmVhdGUgYSBmbG9hdCB0ZXh0dXJlXG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGNvbnN0IHRleHR1cmUgPSBnbC5jcmVhdGVUZXh0dXJlKCk7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuICAgIGNvbnN0IGludGVybmFsRm9ybWF0ID0gdGhpcy52ZXJzaW9uID09PSAyID8gKGdsIGFzIHVua25vd24gYXMgeyBSR0JBMzJGOiBudW1iZXIgfSkuUkdCQTMyRiA6IGdsLlJHQkE7XG4gICAgZ2wudGV4SW1hZ2UyRChnbC5URVhUVVJFXzJELCAwLCBpbnRlcm5hbEZvcm1hdCwgMSwgMSwgMCwgZ2wuUkdCQSwgZ2wuRkxPQVQsIG51bGwpO1xuICAgIC8vIFNURVAuMiBiaW5kIGEgZnJhbWUgYnVmZmVyXG4gICAgY29uc3QgZnJhbWVCdWZmZXIgPSBnbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgZnJhbWVCdWZmZXIpO1xuICAgIC8vIFNURVAuMyBhdHRhY2ggdGV4dHVyZSB0byBmcmFtZWJ1ZmZlclxuICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSwgMCk7XG4gICAgLy8gU1RFUC40IHRlc3Qgd2hldGhlciBmcmFtZWJ1ZmZlciBpcyBjb21wbGV0ZVxuICAgIGNvbnN0IGlzQ29tcGxldGUgPSBnbC5jaGVja0ZyYW1lYnVmZmVyU3RhdHVzKGdsLkZSQU1FQlVGRkVSKSA9PT0gZ2wuRlJBTUVCVUZGRVJfQ09NUExFVEU7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgbnVsbCk7XG4gICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBudWxsKTtcbiAgICBnbC5kZWxldGVUZXh0dXJlKHRleHR1cmUpO1xuICAgIGdsLmRlbGV0ZUZyYW1lYnVmZmVyKGZyYW1lQnVmZmVyKTtcbiAgICByZXR1cm4gaXNDb21wbGV0ZTtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tSZW5kZXJGbG9hdDMyKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIGlmICghdGhpcy5jb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCF0aGlzLnRleHR1cmVGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzRmxvYXRUZXh0dXJlQXR0YWNoYWJsZVRvRnJhbWVCdWZmZXI7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrRmxvYXQzMkRvd25sb2FkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIGlmICghdGhpcy5jb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCF0aGlzLnRleHR1cmVGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdXRUJHTF9jb2xvcl9idWZmZXJfZmxvYXQnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzRmxvYXRUZXh0dXJlQXR0YWNoYWJsZVRvRnJhbWVCdWZmZXI7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgd2hldGhlciBHTF9CTEVORCBpcyBzdXBwb3J0ZWRcbiAgICovXG4gIHByaXZhdGUgY2hlY2tGbG9hdDMyQmxlbmQoKTogYm9vbGVhbiB7XG4gICAgLy8gaXQgbG9va3MgbGlrZSBjdXJyZW50bHkgKDIwMTktMDUtMDgpIHRoZXJlIGlzIG5vIGVhc3kgd2F5IHRvIGRldGVjdCB3aGV0aGVyIEJMRU5EIGlzIHN1cHBvcnRlZFxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvb25ueGpzL2lzc3Vlcy8xNDVcblxuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcblxuICAgIGxldCB0ZXh0dXJlOiBXZWJHTFRleHR1cmUgfCBudWxsIHwgdW5kZWZpbmVkO1xuICAgIGxldCBmcmFtZUJ1ZmZlcjogV2ViR0xGcmFtZWJ1ZmZlciB8IG51bGwgfCB1bmRlZmluZWQ7XG4gICAgbGV0IHZlcnRleFNoYWRlcjogV2ViR0xTaGFkZXIgfCBudWxsIHwgdW5kZWZpbmVkO1xuICAgIGxldCBmcmFnbWVudFNoYWRlcjogV2ViR0xTaGFkZXIgfCBudWxsIHwgdW5kZWZpbmVkO1xuICAgIGxldCBwcm9ncmFtOiBXZWJHTFByb2dyYW0gfCBudWxsIHwgdW5kZWZpbmVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIHRleHR1cmUgPSBnbC5jcmVhdGVUZXh0dXJlKCk7XG4gICAgICBmcmFtZUJ1ZmZlciA9IGdsLmNyZWF0ZUZyYW1lYnVmZmVyKCk7XG4gICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcblxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuICAgICAgY29uc3QgaW50ZXJuYWxGb3JtYXQgPSB0aGlzLnZlcnNpb24gPT09IDIgPyAoZ2wgYXMgdW5rbm93biBhcyB7IFJHQkEzMkY6IG51bWJlciB9KS5SR0JBMzJGIDogZ2wuUkdCQTtcbiAgICAgIGdsLnRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgaW50ZXJuYWxGb3JtYXQsIDEsIDEsIDAsIGdsLlJHQkEsIGdsLkZMT0FULCBudWxsKTtcblxuICAgICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBmcmFtZUJ1ZmZlcik7XG4gICAgICBnbC5mcmFtZWJ1ZmZlclRleHR1cmUyRChnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRleHR1cmUsIDApO1xuXG4gICAgICBnbC5lbmFibGUoZ2wuQkxFTkQpO1xuXG4gICAgICB2ZXJ0ZXhTaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoZ2wuVkVSVEVYX1NIQURFUik7XG4gICAgICBpZiAoIXZlcnRleFNoYWRlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBnbC5zaGFkZXJTb3VyY2UodmVydGV4U2hhZGVyLCAndm9pZCBtYWluKCl7fScpO1xuICAgICAgZ2wuY29tcGlsZVNoYWRlcih2ZXJ0ZXhTaGFkZXIpO1xuXG4gICAgICBmcmFnbWVudFNoYWRlciA9IGdsLmNyZWF0ZVNoYWRlcihnbC5GUkFHTUVOVF9TSEFERVIpO1xuICAgICAgaWYgKCFmcmFnbWVudFNoYWRlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBnbC5zaGFkZXJTb3VyY2UoZnJhZ21lbnRTaGFkZXIsICdwcmVjaXNpb24gaGlnaHAgZmxvYXQ7dm9pZCBtYWluKCl7Z2xfRnJhZ0NvbG9yPXZlYzQoMC41KTt9Jyk7XG4gICAgICBnbC5jb21waWxlU2hhZGVyKGZyYWdtZW50U2hhZGVyKTtcblxuICAgICAgcHJvZ3JhbSA9IGdsLmNyZWF0ZVByb2dyYW0oKTtcbiAgICAgIGlmICghcHJvZ3JhbSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgdmVydGV4U2hhZGVyKTtcbiAgICAgIGdsLmF0dGFjaFNoYWRlcihwcm9ncmFtLCBmcmFnbWVudFNoYWRlcik7XG4gICAgICBnbC5saW5rUHJvZ3JhbShwcm9ncmFtKTtcbiAgICAgIGdsLnVzZVByb2dyYW0ocHJvZ3JhbSk7XG5cbiAgICAgIGdsLmRyYXdBcnJheXMoZ2wuUE9JTlRTLCAwLCAxKTtcbiAgICAgIHJldHVybiBnbC5nZXRFcnJvcigpID09PSBnbC5OT19FUlJPUjtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZ2wuZGlzYWJsZShnbC5CTEVORCk7XG5cbiAgICAgIGlmIChwcm9ncmFtKSB7XG4gICAgICAgIGdsLmRlbGV0ZVByb2dyYW0ocHJvZ3JhbSk7XG4gICAgICB9XG4gICAgICBpZiAodmVydGV4U2hhZGVyKSB7XG4gICAgICAgIGdsLmRlbGV0ZVNoYWRlcih2ZXJ0ZXhTaGFkZXIpO1xuICAgICAgfVxuICAgICAgaWYgKGZyYWdtZW50U2hhZGVyKSB7XG4gICAgICAgIGdsLmRlbGV0ZVNoYWRlcihmcmFnbWVudFNoYWRlcik7XG4gICAgICB9XG4gICAgICBpZiAoZnJhbWVCdWZmZXIpIHtcbiAgICAgICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBudWxsKTtcbiAgICAgICAgZ2wuZGVsZXRlRnJhbWVidWZmZXIoZnJhbWVCdWZmZXIpO1xuICAgICAgfVxuICAgICAgaWYgKHRleHR1cmUpIHtcbiAgICAgICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgbnVsbCk7XG4gICAgICAgIGdsLmRlbGV0ZVRleHR1cmUodGV4dHVyZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYmVnaW5UaW1lcigpOiBXZWJHTFF1ZXJ5IHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyICYmIHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uKSB7XG4gICAgICBjb25zdCBnbDIgPSB0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ7XG4gICAgICBjb25zdCBleHQgPSB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbjtcblxuICAgICAgY29uc3QgcXVlcnkgPSBnbDIuY3JlYXRlUXVlcnkoKSBhcyBXZWJHTFF1ZXJ5O1xuICAgICAgZ2wyLmJlZ2luUXVlcnkoZXh0LlRJTUVfRUxBUFNFRF9FWFQsIHF1ZXJ5KTtcbiAgICAgIHJldHVybiBxdWVyeTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVE9ETzogYWRkIHdlYmdsIDEgaGFuZGxpbmcuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMMSBwcm9maWxpbmcgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgfVxuICB9XG5cbiAgZW5kVGltZXIoKSB7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMiAmJiB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbikge1xuICAgICAgY29uc3QgZ2wyID0gdGhpcy5nbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0O1xuICAgICAgY29uc3QgZXh0ID0gdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb247XG4gICAgICBnbDIuZW5kUXVlcnkoZXh0LlRJTUVfRUxBUFNFRF9FWFQpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUT0RPOiBhZGQgd2ViZ2wgMSBoYW5kbGluZy5cbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViR0wxIHByb2ZpbGluZyBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgfVxuXG4gIGlzVGltZXJSZXN1bHRBdmFpbGFibGUocXVlcnk6IFdlYkdMUXVlcnkpOiBib29sZWFuIHtcbiAgICBsZXQgYXZhaWxhYmxlID0gZmFsc2UsXG4gICAgICBkaXNqb2ludCA9IGZhbHNlO1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIgJiYgdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb24pIHtcbiAgICAgIGNvbnN0IGdsMiA9IHRoaXMuZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dDtcbiAgICAgIGNvbnN0IGV4dCA9IHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uO1xuXG4gICAgICBhdmFpbGFibGUgPSBnbDIuZ2V0UXVlcnlQYXJhbWV0ZXIocXVlcnksIGdsMi5RVUVSWV9SRVNVTFRfQVZBSUxBQkxFKTtcbiAgICAgIGRpc2pvaW50ID0gZ2wyLmdldFBhcmFtZXRlcihleHQuR1BVX0RJU0pPSU5UX0VYVCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRPRE86IGFkZCB3ZWJnbCAxIGhhbmRsaW5nLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJHTDEgcHJvZmlsaW5nIGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF2YWlsYWJsZSAmJiAhZGlzam9pbnQ7XG4gIH1cblxuICBnZXRUaW1lclJlc3VsdChxdWVyeTogV2ViR0xRdWVyeSk6IG51bWJlciB7XG4gICAgbGV0IHRpbWVFbGFwc2VkID0gMDtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICBjb25zdCBnbDIgPSB0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ7XG4gICAgICB0aW1lRWxhcHNlZCA9IGdsMi5nZXRRdWVyeVBhcmFtZXRlcihxdWVyeSwgZ2wyLlFVRVJZX1JFU1VMVCk7XG4gICAgICBnbDIuZGVsZXRlUXVlcnkocXVlcnkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUT0RPOiBhZGQgd2ViZ2wgMSBoYW5kbGluZy5cbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViR0wxIHByb2ZpbGluZyBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgICAvLyByZXR1cm4gbWlsbGlzZWNvbmRzXG4gICAgcmV0dXJuIHRpbWVFbGFwc2VkIC8gMTAwMDAwMDtcbiAgfVxuXG4gIGFzeW5jIHdhaXRGb3JRdWVyeUFuZEdldFRpbWUocXVlcnk6IFdlYkdMUXVlcnkpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGF3YWl0IHJlcGVhdGVkVHJ5KCgpID0+IHRoaXMuaXNUaW1lclJlc3VsdEF2YWlsYWJsZShxdWVyeSkpO1xuICAgIHJldHVybiB0aGlzLmdldFRpbWVyUmVzdWx0KHF1ZXJ5KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBjcmVhdGVBbmRXYWl0Rm9yRmVuY2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZmVuY2VDb250ZXh0ID0gdGhpcy5jcmVhdGVGZW5jZSh0aGlzLmdsKTtcbiAgICByZXR1cm4gdGhpcy5wb2xsRmVuY2UoZmVuY2VDb250ZXh0KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRmVuY2UoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCk6IEZlbmNlQ29udGV4dCB7XG4gICAgbGV0IGlzRmVuY2VQYXNzZWQ6ICgpID0+IGJvb2xlYW47XG4gICAgY29uc3QgZ2wyID0gZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dDtcbiAgICBjb25zdCBxdWVyeSA9IGdsMi5mZW5jZVN5bmMoZ2wyLlNZTkNfR1BVX0NPTU1BTkRTX0NPTVBMRVRFLCAwKTtcbiAgICBnbC5mbHVzaCgpO1xuICAgIGlmIChxdWVyeSA9PT0gbnVsbCkge1xuICAgICAgaXNGZW5jZVBhc3NlZCA9ICgpID0+IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlzRmVuY2VQYXNzZWQgPSAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IGdsMi5jbGllbnRXYWl0U3luYyhxdWVyeSwgMCwgMCk7XG4gICAgICAgIHJldHVybiBzdGF0dXMgPT09IGdsMi5BTFJFQURZX1NJR05BTEVEIHx8IHN0YXR1cyA9PT0gZ2wyLkNPTkRJVElPTl9TQVRJU0ZJRUQ7XG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4geyBxdWVyeSwgaXNGZW5jZVBhc3NlZCB9O1xuICB9XG5cbiAgYXN5bmMgcG9sbEZlbmNlKGZlbmNlQ29udGV4dDogRmVuY2VDb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICB2b2lkIHRoaXMuYWRkSXRlbVRvUG9sbChcbiAgICAgICAgKCkgPT4gZmVuY2VDb250ZXh0LmlzRmVuY2VQYXNzZWQoKSxcbiAgICAgICAgKCkgPT4gcmVzb2x2ZSgpLFxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaXRlbXNUb1BvbGw6IFBvbGxJdGVtW10gPSBbXTtcblxuICBwb2xsSXRlbXMoKTogdm9pZCB7XG4gICAgLy8gRmluZCB0aGUgbGFzdCBxdWVyeSB0aGF0IGhhcyBmaW5pc2hlZC5cbiAgICBjb25zdCBpbmRleCA9IGxpbmVhclNlYXJjaExhc3RUcnVlKHRoaXMuaXRlbXNUb1BvbGwubWFwKCh4KSA9PiB4LmlzRG9uZUZuKSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gaW5kZXg7ICsraSkge1xuICAgICAgY29uc3QgeyByZXNvbHZlRm4gfSA9IHRoaXMuaXRlbXNUb1BvbGxbaV07XG4gICAgICByZXNvbHZlRm4oKTtcbiAgICB9XG4gICAgdGhpcy5pdGVtc1RvUG9sbCA9IHRoaXMuaXRlbXNUb1BvbGwuc2xpY2UoaW5kZXggKyAxKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYWRkSXRlbVRvUG9sbChpc0RvbmVGbjogKCkgPT4gYm9vbGVhbiwgcmVzb2x2ZUZuOiAoKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5pdGVtc1RvUG9sbC5wdXNoKHsgaXNEb25lRm4sIHJlc29sdmVGbiB9KTtcbiAgICBpZiAodGhpcy5pdGVtc1RvUG9sbC5sZW5ndGggPiAxKSB7XG4gICAgICAvLyBXZSBhbHJlYWR5IGhhdmUgYSBydW5uaW5nIGxvb3AgdGhhdCBwb2xscy5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gU3RhcnQgYSBuZXcgbG9vcCB0aGF0IHBvbGxzLlxuICAgIGF3YWl0IHJlcGVhdGVkVHJ5KCgpID0+IHtcbiAgICAgIHRoaXMucG9sbEl0ZW1zKCk7XG4gICAgICAvLyBFbmQgdGhlIGxvb3AgaWYgbm8gbW9yZSBpdGVtcyB0byBwb2xsLlxuICAgICAgcmV0dXJuIHRoaXMuaXRlbXNUb1BvbGwubGVuZ3RoID09PSAwO1xuICAgIH0pO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4uLy4uL2luc3RydW1lbnQnO1xuXG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsLWNvbnRleHQnO1xuXG5jb25zdCBjYWNoZTogeyBbY29udGV4dElkOiBzdHJpbmddOiBXZWJHTENvbnRleHQgfSA9IHt9O1xuXG4vKipcbiAqIFRoaXMgZmFjdG9yeSBmdW5jdGlvbiBjcmVhdGVzIHByb3BlciBXZWJHTFJlbmRlcmluZ0NvbnRleHQgYmFzZWQgb25cbiAqIHRoZSBjdXJyZW50IGJyb3dzZXJzIGNhcGFiaWxpdGllc1xuICogVGhlIG9yZGVyIGlzIGZyb20gaGlnaGVyL21vc3QgcmVjZW50IHZlcnNpb25zIHRvIG1vc3QgYmFzaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVdlYkdMQ29udGV4dChjb250ZXh0SWQ/OiAnd2ViZ2wnIHwgJ3dlYmdsMicpOiBXZWJHTENvbnRleHQge1xuICBsZXQgY29udGV4dDogV2ViR0xDb250ZXh0IHwgdW5kZWZpbmVkO1xuICBpZiAoKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wyJykgJiYgJ3dlYmdsMicgaW4gY2FjaGUpIHtcbiAgICBjb250ZXh0ID0gY2FjaGUud2ViZ2wyO1xuICB9IGVsc2UgaWYgKCghY29udGV4dElkIHx8IGNvbnRleHRJZCA9PT0gJ3dlYmdsJykgJiYgJ3dlYmdsJyBpbiBjYWNoZSkge1xuICAgIGNvbnRleHQgPSBjYWNoZS53ZWJnbDtcbiAgfVxuXG4gIGlmICghY29udGV4dCkge1xuICAgIHRyeSB7XG4gICAgICAvLyB0cnkgdG8gY3JlYXRlIHdlYmdsIGNvbnRleHQgZnJvbSBhbiBvZmZzY3JlZW4gY2FudmFzXG4gICAgICBjb25zdCBvZmZzY3JlZW5DYW52YXMgPSBjcmVhdGVPZmZzY3JlZW5DYW52YXMoKTtcbiAgICAgIGNvbnRleHQgPSBjcmVhdGVOZXdXZWJHTENvbnRleHQob2Zmc2NyZWVuQ2FudmFzLCBjb250ZXh0SWQpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gaWYgZmFpbGVkLCBmYWxsYmFjayB0byB0cnkgdG8gdXNlIGEgbm9ybWFsIGNhbnZhcyBlbGVtZW50XG4gICAgICBjb25zdCBjYW52YXMgPSBjcmVhdGVDYW52YXMoKTtcbiAgICAgIGNvbnRleHQgPSBjcmVhdGVOZXdXZWJHTENvbnRleHQoY2FudmFzLCBjb250ZXh0SWQpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnRleHRJZCA9IGNvbnRleHRJZCB8fCBjb250ZXh0LnZlcnNpb24gPT09IDEgPyAnd2ViZ2wnIDogJ3dlYmdsMic7XG4gIGNvbnN0IGdsID0gY29udGV4dC5nbDtcblxuICBjYWNoZVtjb250ZXh0SWRdID0gY29udGV4dDtcblxuICBpZiAoZ2wuaXNDb250ZXh0TG9zdCgpKSB7XG4gICAgZGVsZXRlIGNhY2hlW2NvbnRleHRJZF07XG4gICAgcmV0dXJuIGNyZWF0ZVdlYkdMQ29udGV4dChjb250ZXh0SWQpO1xuICB9XG5cbiAgZ2wuZGlzYWJsZShnbC5ERVBUSF9URVNUKTtcbiAgZ2wuZGlzYWJsZShnbC5TVEVOQ0lMX1RFU1QpO1xuICBnbC5kaXNhYmxlKGdsLkJMRU5EKTtcbiAgZ2wuZGlzYWJsZShnbC5ESVRIRVIpO1xuICBnbC5kaXNhYmxlKGdsLlBPTFlHT05fT0ZGU0VUX0ZJTEwpO1xuICBnbC5kaXNhYmxlKGdsLlNBTVBMRV9DT1ZFUkFHRSk7XG4gIGdsLmVuYWJsZShnbC5TQ0lTU09SX1RFU1QpO1xuICBnbC5lbmFibGUoZ2wuQ1VMTF9GQUNFKTtcbiAgZ2wuY3VsbEZhY2UoZ2wuQkFDSyk7XG5cbiAgcmV0dXJuIGNvbnRleHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVOZXdXZWJHTENvbnRleHQoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCwgY29udGV4dElkPzogJ3dlYmdsJyB8ICd3ZWJnbDInKTogV2ViR0xDb250ZXh0IHtcbiAgY29uc3QgY29udGV4dEF0dHJpYnV0ZXM6IFdlYkdMQ29udGV4dEF0dHJpYnV0ZXMgPSB7XG4gICAgYWxwaGE6IGZhbHNlLFxuICAgIGRlcHRoOiBmYWxzZSxcbiAgICBhbnRpYWxpYXM6IGZhbHNlLFxuICAgIHN0ZW5jaWw6IGZhbHNlLFxuICAgIHByZXNlcnZlRHJhd2luZ0J1ZmZlcjogZmFsc2UsXG4gICAgcHJlbXVsdGlwbGllZEFscGhhOiBmYWxzZSxcbiAgICBmYWlsSWZNYWpvclBlcmZvcm1hbmNlQ2F2ZWF0OiBmYWxzZSxcbiAgfTtcbiAgbGV0IGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQgfCBudWxsO1xuICBjb25zdCBjYSA9IGNvbnRleHRBdHRyaWJ1dGVzO1xuICBpZiAoIWNvbnRleHRJZCB8fCBjb250ZXh0SWQgPT09ICd3ZWJnbDInKSB7XG4gICAgZ2wgPSBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wyJywgY2EpO1xuICAgIGlmIChnbCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBXZWJHTENvbnRleHQoZ2wsIDIpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIExvZ2dlci53YXJuaW5nKCdHbENvbnRleHRGYWN0b3J5JywgYGZhaWxlZCB0byBjcmVhdGUgV2ViR0xDb250ZXh0IHVzaW5nIGNvbnRleHRJZCAnd2ViZ2wyJy4gRXJyb3I6ICR7ZXJyfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoIWNvbnRleHRJZCB8fCBjb250ZXh0SWQgPT09ICd3ZWJnbCcpIHtcbiAgICBnbCA9IGNhbnZhcy5nZXRDb250ZXh0KCd3ZWJnbCcsIGNhKSB8fCAoY2FudmFzLmdldENvbnRleHQoJ2V4cGVyaW1lbnRhbC13ZWJnbCcsIGNhKSBhcyBXZWJHTFJlbmRlcmluZ0NvbnRleHQpO1xuICAgIGlmIChnbCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBXZWJHTENvbnRleHQoZ2wsIDEpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIExvZ2dlci53YXJuaW5nKFxuICAgICAgICAgICdHbENvbnRleHRGYWN0b3J5JyxcbiAgICAgICAgICBgZmFpbGVkIHRvIGNyZWF0ZSBXZWJHTENvbnRleHQgdXNpbmcgY29udGV4dElkICd3ZWJnbCcgb3IgJ2V4cGVyaW1lbnRhbC13ZWJnbCcuIEVycm9yOiAke2Vycn1gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignV2ViR0wgaXMgbm90IHN1cHBvcnRlZCcpO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG5kZWNsYXJlIGxldCBPZmZzY3JlZW5DYW52YXM6IHsgbmV3ICh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IEhUTUxDYW52YXNFbGVtZW50IH07XG5cbmZ1bmN0aW9uIGNyZWF0ZUNhbnZhcygpOiBIVE1MQ2FudmFzRWxlbWVudCB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZmFpbGVkIHRvIGNyZWF0ZSBjYW52YXM6IGRvY3VtZW50IGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgfVxuICBjb25zdCBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gIGNhbnZhcy53aWR0aCA9IDE7XG4gIGNhbnZhcy5oZWlnaHQgPSAxO1xuICByZXR1cm4gY2FudmFzO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVPZmZzY3JlZW5DYW52YXMoKTogSFRNTENhbnZhc0VsZW1lbnQge1xuICBpZiAodHlwZW9mIE9mZnNjcmVlbkNhbnZhcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdmYWlsZWQgdG8gY3JlYXRlIG9mZnNjcmVlbiBjYW52YXM6IE9mZnNjcmVlbkNhbnZhcyBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gIH1cbiAgcmV0dXJuIG5ldyBPZmZzY3JlZW5DYW52YXMoMSwgMSk7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IEJhY2tlbmQsIFNlc3Npb25IYW5kbGVyIH0gZnJvbSAnLi4vYmFja2VuZCc7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi9zZXNzaW9uJztcblxuaW1wb3J0IHsgV2ViR0xTZXNzaW9uSGFuZGxlciB9IGZyb20gJy4vd2ViZ2wvc2Vzc2lvbi1oYW5kbGVyJztcbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vd2ViZ2wvd2ViZ2wtY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsL3dlYmdsLWNvbnRleHQtZmFjdG9yeSc7XG5cbi8qKlxuICogV2ViR0xCYWNrZW5kIGlzIHRoZSBlbnRyeSBwb2ludCBmb3IgYWxsIFdlYkdMIG9wZXJhdGlvbnNcbiAqIFdoZW4gaXQgc3RhcnRzIGl0IGNyZWF0ZWQgdGhlIFdlYkdMUmVuZGVyaW5nQ29udGV4dFxuICogYW5kIG90aGVyIG1haW4gZnJhbWV3b3JrIGNvbXBvbmVudHMgc3VjaCBhcyBQcm9ncmFtIGFuZCBUZXh0dXJlIE1hbmFnZXJzXG4gKi9cbmV4cG9ydCBjbGFzcyBXZWJHTEJhY2tlbmQgaW1wbGVtZW50cyBCYWNrZW5kIHtcbiAgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQ7XG5cbiAgZ2V0IGNvbnRleHRJZCgpOiAnd2ViZ2wnIHwgJ3dlYmdsMicgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBlbnYud2ViZ2wuY29udGV4dElkO1xuICB9XG4gIHNldCBjb250ZXh0SWQodmFsdWU6ICd3ZWJnbCcgfCAnd2ViZ2wyJyB8IHVuZGVmaW5lZCkge1xuICAgIGVudi53ZWJnbC5jb250ZXh0SWQgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBtYXRtdWxNYXhCYXRjaFNpemUoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLm1hdG11bE1heEJhdGNoU2l6ZTtcbiAgfVxuICBzZXQgbWF0bXVsTWF4QmF0Y2hTaXplKHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wubWF0bXVsTWF4QmF0Y2hTaXplID0gdmFsdWU7XG4gIH1cblxuICBnZXQgdGV4dHVyZUNhY2hlTW9kZSgpOiAnaW5pdGlhbGl6ZXJPbmx5JyB8ICdmdWxsJyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGVudi53ZWJnbC50ZXh0dXJlQ2FjaGVNb2RlO1xuICB9XG4gIHNldCB0ZXh0dXJlQ2FjaGVNb2RlKHZhbHVlOiAnaW5pdGlhbGl6ZXJPbmx5JyB8ICdmdWxsJyB8IHVuZGVmaW5lZCkge1xuICAgIGVudi53ZWJnbC50ZXh0dXJlQ2FjaGVNb2RlID0gdmFsdWU7XG4gIH1cblxuICBnZXQgcGFjaygpOiBib29sZWFuIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLnBhY2s7XG4gIH1cbiAgc2V0IHBhY2sodmFsdWU6IGJvb2xlYW4gfCB1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wucGFjayA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IGFzeW5jKCk6IGJvb2xlYW4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBlbnYud2ViZ2wuYXN5bmM7XG4gIH1cbiAgc2V0IGFzeW5jKHZhbHVlOiBib29sZWFuIHwgdW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLmFzeW5jID0gdmFsdWU7XG4gIH1cblxuICBpbml0aWFsaXplKCk6IGJvb2xlYW4ge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLmdsQ29udGV4dCA9IGNyZWF0ZVdlYkdMQ29udGV4dCh0aGlzLmNvbnRleHRJZCk7XG4gICAgICBpZiAodHlwZW9mIHRoaXMubWF0bXVsTWF4QmF0Y2hTaXplICE9PSAnbnVtYmVyJykge1xuICAgICAgICB0aGlzLm1hdG11bE1heEJhdGNoU2l6ZSA9IDE2O1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB0aGlzLnRleHR1cmVDYWNoZU1vZGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMudGV4dHVyZUNhY2hlTW9kZSA9ICdmdWxsJztcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdGhpcy5wYWNrICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhpcy5wYWNrID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHRoaXMuYXN5bmMgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aGlzLmFzeW5jID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIExvZ2dlci5zZXRXaXRoRW52KGVudik7XG5cbiAgICAgIGlmICghZW52LndlYmdsLmNvbnRleHQpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVudi53ZWJnbCwgJ2NvbnRleHQnLCB7IHZhbHVlOiB0aGlzLmdsQ29udGV4dC5nbCB9KTtcbiAgICAgIH1cblxuICAgICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICdXZWJHTEJhY2tlbmQnLFxuICAgICAgICBgQ3JlYXRlZCBXZWJHTENvbnRleHQ6ICR7dHlwZW9mIHRoaXMuZ2xDb250ZXh0fSB3aXRoIG1hdG11bE1heEJhdGNoU2l6ZTogJHtcbiAgICAgICAgICB0aGlzLm1hdG11bE1heEJhdGNoU2l6ZVxuICAgICAgICB9OyB0ZXh0dXJlQ2FjaGVNb2RlOiAke3RoaXMudGV4dHVyZUNhY2hlTW9kZX07IHBhY2s6ICR7dGhpcy5wYWNrfTsgYXN5bmM6ICR7dGhpcy5hc3luY30uYCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBMb2dnZXIud2FybmluZygnV2ViR0xCYWNrZW5kJywgYFVuYWJsZSB0byBpbml0aWFsaXplIFdlYkdMQmFja2VuZC4gJHtlfWApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICBjcmVhdGVTZXNzaW9uSGFuZGxlcihjb250ZXh0OiBTZXNzaW9uLkNvbnRleHQpOiBTZXNzaW9uSGFuZGxlciB7XG4gICAgcmV0dXJuIG5ldyBXZWJHTFNlc3Npb25IYW5kbGVyKHRoaXMsIGNvbnRleHQpO1xuICB9XG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5nbENvbnRleHQuZGlzcG9zZSgpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFdlYkdMQmFja2VuZCB9IGZyb20gJy4vYmFja2VuZHMvYmFja2VuZC13ZWJnbCc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3IgfSBmcm9tICcuL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBPcFNldCB9IGZyb20gJy4vb3BzZXQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vc2Vzc2lvbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5mZXJlbmNlSGFuZGxlciB7XG4gIC8qKlxuICAgKiBkaXNwb3NlIHRoZSBpbmZlcmVuY2UgaGFuZGxlci4gaXQgd2lsbCBiZSBjYWxsZWQgYXMgdGhlIGxhc3Qgc3RlcCBpbiBTZXNzaW9uLnJ1bigpXG4gICAqL1xuICBkaXNwb3NlKCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2Vzc2lvbkhhbmRsZXIge1xuICAvKipcbiAgICogdHJhbnNmb3JtIHRoZSBncmFwaCBhdCBpbml0aWFsaXphdGlvbiB0aW1lXG4gICAqIEBwYXJhbSBncmFwaFRyYW5zZm9ybWVyIHRoZSBncmFwaCB0cmFuc2Zvcm1lciB0byBtYW5pcHVsYXRlIHRoZSBtb2RlbCBncmFwaFxuICAgKi9cbiAgdHJhbnNmb3JtR3JhcGg/KGdyYXBoVHJhbnNmb3JtZXI6IEdyYXBoLlRyYW5zZm9ybWVyKTogdm9pZDtcblxuICAvKipcbiAgICogY3JlYXRlIGFuIGluc3RhbmNlIG9mIEluZmVyZW5jZUhhbmRsZXIgdG8gdXNlIGluIGEgU2Vzc2lvbi5ydW4oKSBjYWxsXG4gICAqL1xuICBjcmVhdGVJbmZlcmVuY2VIYW5kbGVyKCk6IEluZmVyZW5jZUhhbmRsZXI7XG5cbiAgLyoqXG4gICAqIGRpc3Bvc2UgdGhlIHNlc3Npb24gaGFuZGxlci4gaXQgd2lsbCBiZSBjYWxsZWQgd2hlbiBhIHNlc3Npb24gaXMgYmVpbmcgZGlzcG9zZWQgZXhwbGljaXRseVxuICAgKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgb3BlcmF0b3IgZnJvbSB0aGUgbmFtZSBhbmQgb3BzZXQgdmVyc2lvbjsgYmFja2VuZCBzcGVjaWZpY1xuICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSB0byByZXNvbHZlXG4gICAqIEBwYXJhbSBvcHNldHMgYSBsaXN0IG9mIG9wc2V0cyB0aGF0IGV4cG9ydGVkIGZyb20gdGhlIG1vZGVsXG4gICAqIEBwYXJhbSBncmFwaCB0aGUgY29tcGxldGVseSBpbml0aWFsaXplZCBncmFwaFxuICAgKi9cbiAgcmVzb2x2ZShub2RlOiBHcmFwaC5Ob2RlLCBvcHNldHM6IHJlYWRvbmx5IE9wU2V0W10sIGdyYXBoOiBHcmFwaCk6IE9wZXJhdG9yO1xuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBsZXQncyB0aGUgc2Vzc2lvbkhhbmRsZXIga25vdyB0aGF0IHRoZSBncmFwaCBpbml0aWFsaXphdGlvbiBpcyBjb21wbGV0ZVxuICAgKiBAcGFyYW0gZ3JhcGggdGhlIGNvbXBsZXRlbHkgaW5pdGlhbGl6ZWQgZ3JhcGhcbiAgICovXG4gIG9uR3JhcGhJbml0aWFsaXplZD8oZ3JhcGg6IEdyYXBoKTogdm9pZDtcblxuICAvKipcbiAgICogYSByZWZlcmVuY2UgdG8gdGhlIGNvcnJlc3BvbmRpbmcgYmFja2VuZFxuICAgKi9cbiAgcmVhZG9ubHkgYmFja2VuZDogQmFja2VuZDtcblxuICAvKipcbiAgICogYSByZWZlcmVuY2UgdG8gdGhlIHNlc3Npb24gY29udGV4dFxuICAgKi9cbiAgcmVhZG9ubHkgY29udGV4dDogU2Vzc2lvbi5Db250ZXh0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhY2tlbmQge1xuICAvKipcbiAgICogaW5pdGlhbGl6ZSB0aGUgYmFja2VuZC4gd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLCB3aGVuIHRoZSBmaXJzdCB0aW1lIHRoZVxuICAgKiBiYWNrZW5kIGl0IHRvIGJlIHVzZWRcbiAgICovXG4gIGluaXRpYWxpemUoKTogYm9vbGVhbiB8IFByb21pc2U8Ym9vbGVhbj47XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiBTZXNzaW9uSGFuZGxlciB0byB1c2UgaW4gYSBTZXNzaW9uIG9iamVjdCdzIGxpZmVjeWNsZVxuICAgKi9cbiAgY3JlYXRlU2Vzc2lvbkhhbmRsZXIoY29udGV4dDogU2Vzc2lvbi5Db250ZXh0KTogU2Vzc2lvbkhhbmRsZXI7XG5cbiAgLyoqXG4gICAqIGRpc3Bvc2UgdGhlIGJhY2tlbmQuIGN1cnJlbnRseSB0aGlzIHdpbGwgbm90IGJlIGNhbGxlZFxuICAgKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xufVxuXG4vLyBjYWNoZXMgYWxsIGluaXRpYWxpemVkIGJhY2tlbmQgaW5zdGFuY2VzXG5jb25zdCBiYWNrZW5kc0NhY2hlOiBNYXA8c3RyaW5nLCBCYWNrZW5kPiA9IG5ldyBNYXAoKTtcblxuZXhwb3J0IGNvbnN0IGJhY2tlbmQ6IHsgW25hbWU6IHN0cmluZ106IEJhY2tlbmQgfSA9IHtcbiAgd2ViZ2w6IG5ldyBXZWJHTEJhY2tlbmQoKSxcbn07XG5cbi8qKlxuICogUmVzb2x2ZSBhIHJlZmVyZW5jZSB0byB0aGUgYmFja2VuZC4gSWYgYSBoaW50IGlzIHNwZWNpZmllZCwgdGhlIGNvcnJlc3BvbmRpbmdcbiAqIGJhY2tlbmQgd2lsbCBiZSB1c2VkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUJhY2tlbmQoaGludD86IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTxCYWNrZW5kPiB7XG4gIGlmICghaGludCkge1xuICAgIHJldHVybiByZXNvbHZlQmFja2VuZChbJ3dlYmdsJ10pO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGhpbnRzID0gdHlwZW9mIGhpbnQgPT09ICdzdHJpbmcnID8gW2hpbnRdIDogaGludDtcblxuICAgIGZvciAoY29uc3QgYmFja2VuZEhpbnQgb2YgaGludHMpIHtcbiAgICAgIGNvbnN0IGNhY2hlID0gYmFja2VuZHNDYWNoZS5nZXQoYmFja2VuZEhpbnQpO1xuICAgICAgaWYgKGNhY2hlKSB7XG4gICAgICAgIHJldHVybiBjYWNoZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYmFja2VuZCA9IGF3YWl0IHRyeUxvYWRCYWNrZW5kKGJhY2tlbmRIaW50KTtcbiAgICAgIGlmIChiYWNrZW5kKSB7XG4gICAgICAgIHJldHVybiBiYWNrZW5kO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignbm8gYXZhaWxhYmxlIGJhY2tlbmQgdG8gdXNlJyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRyeUxvYWRCYWNrZW5kKGJhY2tlbmRIaW50OiBzdHJpbmcpOiBQcm9taXNlPEJhY2tlbmQgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgYmFja2VuZE9iaiA9IGJhY2tlbmQ7XG5cbiAgaWYgKHR5cGVvZiBiYWNrZW5kT2JqW2JhY2tlbmRIaW50XSAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNCYWNrZW5kKGJhY2tlbmRPYmpbYmFja2VuZEhpbnRdKSkge1xuICAgIGNvbnN0IGJhY2tlbmQgPSBiYWNrZW5kT2JqW2JhY2tlbmRIaW50XTtcbiAgICBsZXQgaW5pdCA9IGJhY2tlbmQuaW5pdGlhbGl6ZSgpO1xuICAgIGlmICh0eXBlb2YgaW5pdCA9PT0gJ29iamVjdCcgJiYgJ3RoZW4nIGluIGluaXQpIHtcbiAgICAgIGluaXQgPSBhd2FpdCBpbml0O1xuICAgIH1cbiAgICBpZiAoaW5pdCkge1xuICAgICAgYmFja2VuZHNDYWNoZS5zZXQoYmFja2VuZEhpbnQsIGJhY2tlbmQpO1xuICAgICAgcmV0dXJuIGJhY2tlbmQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaXNCYWNrZW5kKG9iajogdW5rbm93bikge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBjb25zdCBvID0gb2JqIGFzIGFueTtcblxuICAvLyBjaGVjayBpZiBhbiBvYmplY3QgaXMgYSBCYWNrZW5kIGluc3RhbmNlXG4gIGlmIChcbiAgICAnaW5pdGlhbGl6ZScgaW4gbyAmJlxuICAgIHR5cGVvZiBvLmluaXRpYWxpemUgPT09ICdmdW5jdGlvbicgJiYgLy8gaW5pdGlhbGl6ZSgpXG4gICAgJ2NyZWF0ZVNlc3Npb25IYW5kbGVyJyBpbiBvICYmXG4gICAgdHlwZW9mIG8uY3JlYXRlU2Vzc2lvbkhhbmRsZXIgPT09ICdmdW5jdGlvbicgJiYgLy8gY3JlYXRlU2Vzc2lvbkhhbmRsZXIoKVxuICAgICdkaXNwb3NlJyBpbiBvICYmXG4gICAgdHlwZW9mIG8uZGlzcG9zZSA9PT0gJ2Z1bmN0aW9uJyAvLyBkaXNwb3NlKClcbiAgKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCB0eXBlIEJhY2tlbmRUeXBlID0gQmFja2VuZDtcbmV4cG9ydCB0eXBlIFNlc3Npb25IYW5kbGVyVHlwZSA9IFJldHVyblR5cGU8QmFja2VuZFR5cGVbJ2NyZWF0ZVNlc3Npb25IYW5kbGVyJ10+O1xuZXhwb3J0IHR5cGUgSW5mZXJlbmNlSGFuZGxlclR5cGUgPSBSZXR1cm5UeXBlPFNlc3Npb25IYW5kbGVyVHlwZVsnY3JlYXRlSW5mZXJlbmNlSGFuZGxlciddPjtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuL2JhY2tlbmQnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7IExvZ2dlciwgUHJvZmlsZXIgfSBmcm9tICcuL2luc3RydW1lbnQnO1xuaW1wb3J0IHsgT3BlcmF0b3IgfSBmcm9tICcuL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvcic7XG5cbmNsYXNzIEtlcm5lbE9wIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIG9wOiBPcGVyYXRvcixcbiAgICBwdWJsaWMgbm9kZTogR3JhcGguTm9kZSxcbiAgKSB7fVxufVxuXG5leHBvcnQgY2xhc3MgRXhlY3V0aW9uUGxhbiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZ3JhcGg6IEdyYXBoLFxuICAgIG9wczogT3BlcmF0b3JbXSxcbiAgICBwcml2YXRlIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj4sXG4gICkge1xuICAgIHRoaXMuaW5pdGlhbGl6ZShvcHMpO1xuICB9XG5cbiAgaW5pdGlhbGl6ZShvcHM6IE9wZXJhdG9yW10pIHtcbiAgICB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ0V4ZWN1dGlvblBsYW4uaW5pdGlhbGl6ZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGdyYXBoTm9kZXMgPSB0aGlzLmdyYXBoLmdldE5vZGVzKCk7XG4gICAgICBpZiAoZ3JhcGhOb2Rlcy5sZW5ndGggIT09IG9wcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgc2l6ZSBvZiBub2RlcyBhbmQgT1BzIGRvIG5vdCBtYXRjaC4nKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fb3BzID0gb3BzLm1hcCgob3AsIGkpID0+IG5ldyBLZXJuZWxPcChvcCwgZ3JhcGhOb2Rlc1tpXSkpO1xuICAgICAgdGhpcy5yZXNldCgpO1xuXG4gICAgICAvLyBsb29rIGZvciBzdGFydGVyIG5vZGUocylcbiAgICAgIHRoaXMuX3N0YXJ0ZXIgPSBbXTtcbiAgICAgIHRoaXMuX29wcy5mb3JFYWNoKChvcCwgaSkgPT4ge1xuICAgICAgICBsZXQgcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICBmb3IgKGNvbnN0IGlucHV0IG9mIG9wLm5vZGUuaW5wdXRzKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIXRoaXMuX3ZhbHVlc1tpbnB1dF0gJiYgLy8gbm90IGFuIGluaXRpYWxpemVkIGlucHV0XG4gICAgICAgICAgICB0aGlzLmdyYXBoLmdldElucHV0SW5kaWNlcygpLmluZGV4T2YoaW5wdXQpID09PSAtMSAvLyBub3QgbW9kZWwgaW5wdXRcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJlc29sdmVkID0gZmFsc2U7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc29sdmVkKSB7XG4gICAgICAgICAgdGhpcy5fc3RhcnRlci5wdXNoKGkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHJlc2V0KCkge1xuICAgIHRoaXMuX3ZhbHVlcyA9IHRoaXMuZ3JhcGguZ2V0VmFsdWVzKCkubWFwKChpKSA9PiBpLnRlbnNvcik7XG4gIH1cblxuICBhc3luYyBleGVjdXRlKHNlc3Npb25IYW5kbGVyOiBTZXNzaW9uSGFuZGxlciwgbW9kZWxJbnB1dHM6IFRlbnNvcltdKTogUHJvbWlzZTxUZW5zb3JbXT4ge1xuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ0V4ZWN1dGlvblBsYW4uZXhlY3V0ZScsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIHJlc2V0IG1lZGllbSByZXN1bHRcbiAgICAgIHRoaXMucmVzZXQoKTtcblxuICAgICAgLy8gY3JlYXRlIGluZmVyZW5jZSBoYW5kbGVyXG4gICAgICBjb25zdCBpbmZlcmVuY2VIYW5kbGVyID0gc2Vzc2lvbkhhbmRsZXIuY3JlYXRlSW5mZXJlbmNlSGFuZGxlcigpO1xuXG4gICAgICAvLyBwb3B1bGF0ZSBpbnB1dHMgdmFsdWVcbiAgICAgIGNvbnN0IGdyYXBoSW5wdXRzID0gdGhpcy5ncmFwaC5nZXRJbnB1dEluZGljZXMoKTtcbiAgICAgIGlmIChtb2RlbElucHV0cy5sZW5ndGggIT09IGdyYXBoSW5wdXRzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYG51bWJlciBvZiBpbnB1dCB0ZW5zb3JzIGRvbid0IG1hdGNoIHRoZSBudW1iZXIgb2YgaW5wdXRzIHRvIHRoZSBtb2RlbDogYWN0dWFsOiAke1xuICAgICAgICAgICAgbW9kZWxJbnB1dHMubGVuZ3RoXG4gICAgICAgICAgfSBleHBlY3RlZDogJHtncmFwaElucHV0cy5sZW5ndGh9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgbW9kZWxJbnB1dHMuZm9yRWFjaCgoaW5wdXQsIGkpID0+IHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBncmFwaElucHV0c1tpXTtcbiAgICAgICAgdGhpcy5fdmFsdWVzW2luZGV4XSA9IGlucHV0O1xuICAgICAgfSk7XG5cbiAgICAgIC8vIHByZXBhcmUgcnVubmluZyBzZXF1ZW5jZVxuICAgICAgY29uc3Qgc2VxdWVuY2U6IG51bWJlcltdID0gdGhpcy5fc3RhcnRlci5zbGljZSgwKTtcblxuICAgICAgLy8gZXhlY3V0aW9uIGl0ZXJhdGlvbnNcbiAgICAgIGNvbnN0IGdyYXBoVmFsdWVzID0gdGhpcy5ncmFwaC5nZXRWYWx1ZXMoKTtcbiAgICAgIGNvbnN0IGdyYXBoTm9kZXMgPSB0aGlzLmdyYXBoLmdldE5vZGVzKCk7XG5cbiAgICAgIGxldCByZWFyID0gMDtcbiAgICAgIHdoaWxlIChyZWFyIDwgc2VxdWVuY2UubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHRoaXNPcEluZGV4ID0gc2VxdWVuY2VbcmVhcisrXTtcbiAgICAgICAgY29uc3QgdGhpc09wID0gdGhpcy5fb3BzW3RoaXNPcEluZGV4XTtcblxuICAgICAgICAvLyBjaGVjayBpbnB1dFxuICAgICAgICBjb25zdCBpbnB1dExpc3QgPSB0aGlzT3Aubm9kZS5pbnB1dHMubWFwKChpKSA9PiB0aGlzLl92YWx1ZXNbaV0pO1xuICAgICAgICBpZiAoaW5wdXRMaXN0LmluZGV4T2YodW5kZWZpbmVkKSAhPT0gLTEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVzb2x2ZWQgaW5wdXQgZGV0ZWN0ZWQ6IG9wOiAke3RoaXNPcC5ub2RlfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcnVuXG4gICAgICAgIGNvbnN0IGlucHV0VGVuc29ycyA9IGlucHV0TGlzdCBhcyBUZW5zb3JbXTtcbiAgICAgICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICAgJ0V4ZWNQbGFuJyxcbiAgICAgICAgICBgUnVubmluZyBvcDoke3RoaXNPcC5ub2RlLm5hbWV9ICgke2lucHV0VGVuc29yc1xuICAgICAgICAgICAgLm1hcCgodCwgaSkgPT4gYCcke3RoaXNPcC5ub2RlLmlucHV0c1tpXX0nOiAke3QudHlwZX1bJHt0LmRpbXMuam9pbignLCcpfV1gKVxuICAgICAgICAgICAgLmpvaW4oJywgJyl9KWAsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3Qgb3V0cHV0TGlzdCA9IGF3YWl0IHRoaXMucHJvZmlsZXIuZXZlbnQoJ25vZGUnLCB0aGlzT3Aubm9kZS5uYW1lLCBhc3luYyAoKSA9PlxuICAgICAgICAgIHRoaXNPcC5vcC5pbXBsKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0VGVuc29ycywgdGhpc09wLm9wLmNvbnRleHQpLFxuICAgICAgICApO1xuXG4gICAgICAgIC8vIGNoZWNrIG91dHB1dFxuICAgICAgICBpZiAob3V0cHV0TGlzdC5sZW5ndGggIT09IHRoaXNPcC5ub2RlLm91dHB1dHMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgc2l6ZSBvZiBvdXRwdXQgZG9lcyBub3QgbWF0Y2ggbW9kZWwgZGVmaW5pdGlvbi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZpbGwgdmFsdWVcbiAgICAgICAgb3V0cHV0TGlzdC5mb3JFYWNoKChvdXRwdXQsIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBqID0gdGhpc09wLm5vZGUub3V0cHV0c1tpXTtcbiAgICAgICAgICBpZiAodGhpcy5fdmFsdWVzW2pdKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG91dHB1dCBbJHtqfV0gYWxyZWFkeSBoYXMgdmFsdWU6IG9wOiR7dGhpc09wLm5vZGUubmFtZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5fdmFsdWVzW2pdID0gb3V0cHV0O1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyByZXNvbHZlIGRvd25zdHJlYW0gbm9kZXNcbiAgICAgICAgY29uc3QgZG93bnN0cmVhbU5vZGVzID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgICAgIG91dHB1dExpc3QuZm9yRWFjaCgoX291dHB1dCwgaSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGogPSB0aGlzT3Aubm9kZS5vdXRwdXRzW2ldO1xuICAgICAgICAgIGZvciAoY29uc3QgY3VycmVudERvd25zdHJlYW1Ob2RlSW5kZXggb2YgZ3JhcGhWYWx1ZXNbal0udG8pIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnREb3duc3RyZWFtTm9kZSA9IGdyYXBoTm9kZXNbY3VycmVudERvd25zdHJlYW1Ob2RlSW5kZXhdO1xuICAgICAgICAgICAgbGV0IHJlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgayBvZiBjdXJyZW50RG93bnN0cmVhbU5vZGUuaW5wdXRzKSB7XG4gICAgICAgICAgICAgIGlmICghdGhpcy5fdmFsdWVzW2tdKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJlc29sdmVkKSB7XG4gICAgICAgICAgICAgIGRvd25zdHJlYW1Ob2Rlcy5hZGQoY3VycmVudERvd25zdHJlYW1Ob2RlSW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHNlcXVlbmNlLnB1c2goLi4uZG93bnN0cmVhbU5vZGVzKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb3V0cHV0OiBUZW5zb3JbXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmdyYXBoLmdldE91dHB1dEluZGljZXMoKS5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBvdXRwdXRJbmRleCA9IHRoaXMuZ3JhcGguZ2V0T3V0cHV0SW5kaWNlcygpW2ldO1xuICAgICAgICBjb25zdCBvdXRwdXRUZW5zb3IgPSB0aGlzLl92YWx1ZXNbb3V0cHV0SW5kZXhdO1xuICAgICAgICBpZiAob3V0cHV0VGVuc29yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHJlcXVpcmVkIG91dHB1dCBbJHtvdXRwdXRJbmRleH1dIGRvZXMgbm90IGhhdmUgdmFsdWVgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3V0cHV0SW5kZXggPT09IDApIHtcbiAgICAgICAgICBhd2FpdCBvdXRwdXRUZW5zb3IuZ2V0RGF0YSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZvaWQgb3V0cHV0VGVuc29yLmRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgb3V0cHV0LnB1c2gob3V0cHV0VGVuc29yKTtcbiAgICAgIH1cbiAgICAgIExvZ2dlci52ZXJib3NlKCdFeGVjUGxhbicsICdkaXNwb3Npbmcgb2YgaW5mZXJlbmNlSGFuZGxlcicpO1xuICAgICAgaW5mZXJlbmNlSGFuZGxlci5kaXNwb3NlKCk7XG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH0pO1xuICB9XG5cbiAgX3ZhbHVlczogQXJyYXk8VGVuc29yIHwgdW5kZWZpbmVkPjtcbiAgX29wczogS2VybmVsT3BbXTtcbiAgX3N0YXJ0ZXI6IG51bWJlcltdO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgTG9uZyBmcm9tICdsb25nJztcblxuaW1wb3J0ICogYXMgb3J0RmJzIGZyb20gJy4vb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkJztcbmltcG9ydCB7IG9ubnggfSBmcm9tICcuL29ydC1zY2hlbWEvcHJvdG9idWYvb25ueCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvcic7XG5pbXBvcnQgeyBkZWNvZGVVdGY4U3RyaW5nLCBMb25nVXRpbCB9IGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBBdHRyaWJ1dGUge1xuICBleHBvcnQgaW50ZXJmYWNlIERhdGFUeXBlTWFwIHtcbiAgICBmbG9hdDogbnVtYmVyO1xuICAgIGludDogbnVtYmVyO1xuICAgIHN0cmluZzogc3RyaW5nO1xuICAgIHRlbnNvcjogVGVuc29yO1xuICAgIGZsb2F0czogbnVtYmVyW107XG4gICAgaW50czogbnVtYmVyW107XG4gICAgc3RyaW5nczogc3RyaW5nW107XG4gICAgdGVuc29yczogVGVuc29yW107XG4gIH1cblxuICBleHBvcnQgdHlwZSBEYXRhVHlwZSA9IGtleW9mIERhdGFUeXBlTWFwO1xufVxuXG50eXBlIFZhbHVlVHlwZXMgPSBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbQXR0cmlidXRlLkRhdGFUeXBlXTtcblxudHlwZSBWYWx1ZSA9IFtWYWx1ZVR5cGVzLCBBdHRyaWJ1dGUuRGF0YVR5cGVdO1xuXG5leHBvcnQgY2xhc3MgQXR0cmlidXRlIHtcbiAgY29uc3RydWN0b3IoYXR0cmlidXRlczogb25ueC5JQXR0cmlidXRlUHJvdG9bXSB8IG9ydEZicy5BdHRyaWJ1dGVbXSB8IG51bGwgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLl9hdHRyaWJ1dGVzID0gbmV3IE1hcCgpO1xuICAgIGlmIChhdHRyaWJ1dGVzICE9PSBudWxsICYmIGF0dHJpYnV0ZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZm9yIChjb25zdCBhdHRyIG9mIGF0dHJpYnV0ZXMpIHtcbiAgICAgICAgaWYgKGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgICAgdGhpcy5fYXR0cmlidXRlcy5zZXQoYXR0ci5uYW1lLCBbQXR0cmlidXRlLmdldFZhbHVlKGF0dHIpLCBBdHRyaWJ1dGUuZ2V0VHlwZShhdHRyKV0pO1xuICAgICAgICB9IGVsc2UgaWYgKGF0dHIgaW5zdGFuY2VvZiBvcnRGYnMuQXR0cmlidXRlKSB7XG4gICAgICAgICAgdGhpcy5fYXR0cmlidXRlcy5zZXQoYXR0ci5uYW1lKCkhLCBbQXR0cmlidXRlLmdldFZhbHVlKGF0dHIpLCBBdHRyaWJ1dGUuZ2V0VHlwZShhdHRyKV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5fYXR0cmlidXRlcy5zaXplIDwgYXR0cmlidXRlcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkdXBsaWNhdGVkIGF0dHJpYnV0ZSBuYW1lcycpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNldChrZXk6IHN0cmluZywgdHlwZTogQXR0cmlidXRlLkRhdGFUeXBlLCB2YWx1ZTogVmFsdWVUeXBlcyk6IHZvaWQge1xuICAgIHRoaXMuX2F0dHJpYnV0ZXMuc2V0KGtleSwgW3ZhbHVlLCB0eXBlXSk7XG4gIH1cbiAgZGVsZXRlKGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5fYXR0cmlidXRlcy5kZWxldGUoa2V5KTtcbiAgfVxuICBnZXRGbG9hdChrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydmbG9hdCddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ2Zsb2F0JywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldEludChrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydpbnQnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdpbnQnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0U3RyaW5nKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ3N0cmluZyddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ3N0cmluZycsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRUZW5zb3Ioa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsndGVuc29yJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAndGVuc29yJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldEZsb2F0cyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydmbG9hdHMnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdmbG9hdHMnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0SW50cyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydpbnRzJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnaW50cycsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRTdHJpbmdzKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ3N0cmluZ3MnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdzdHJpbmdzJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldFRlbnNvcnMoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsndGVuc29ycyddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ3RlbnNvcnMnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQ8ViBleHRlbmRzIEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFtBdHRyaWJ1dGUuRGF0YVR5cGVdPihcbiAgICBrZXk6IHN0cmluZyxcbiAgICB0eXBlOiBBdHRyaWJ1dGUuRGF0YVR5cGUsXG4gICAgZGVmYXVsdFZhbHVlPzogVixcbiAgKTogViB7XG4gICAgY29uc3QgdmFsdWVBbmRUeXBlID0gdGhpcy5fYXR0cmlidXRlcy5nZXQoa2V5KTtcbiAgICBpZiAodmFsdWVBbmRUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChkZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGByZXF1aXJlZCBhdHRyaWJ1dGUgbm90IGZvdW5kOiAke2tleX1gKTtcbiAgICB9XG4gICAgaWYgKHZhbHVlQW5kVHlwZVsxXSAhPT0gdHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGB0eXBlIG1pc21hdGNoOiBleHBlY3RlZCAke3R5cGV9IGJ1dCBnb3QgJHt2YWx1ZUFuZFR5cGVbMV19YCk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZUFuZFR5cGVbMF0gYXMgVjtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFR5cGUoYXR0cjogb25ueC5JQXR0cmlidXRlUHJvdG8gfCBvcnRGYnMuQXR0cmlidXRlKTogQXR0cmlidXRlLkRhdGFUeXBlIHtcbiAgICBjb25zdCB0eXBlID0gYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8gPyBhdHRyLnR5cGUgOiAoYXR0ciBhcyBvcnRGYnMuQXR0cmlidXRlKS50eXBlKCk7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5GTE9BVDpcbiAgICAgICAgcmV0dXJuICdmbG9hdCc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlQ6XG4gICAgICAgIHJldHVybiAnaW50JztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklORzpcbiAgICAgICAgcmV0dXJuICdzdHJpbmcnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SOlxuICAgICAgICByZXR1cm4gJ3RlbnNvcic7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5GTE9BVFM6XG4gICAgICAgIHJldHVybiAnZmxvYXRzJztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVFM6XG4gICAgICAgIHJldHVybiAnaW50cyc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkdTOlxuICAgICAgICByZXR1cm4gJ3N0cmluZ3MnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SUzpcbiAgICAgICAgcmV0dXJuICd0ZW5zb3JzJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgYXR0cmlidXRlIHR5cGUgaXMgbm90IHN1cHBvcnRlZCB5ZXQ6ICR7b25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlW3R5cGVdfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFZhbHVlKGF0dHI6IG9ubnguSUF0dHJpYnV0ZVByb3RvIHwgb3J0RmJzLkF0dHJpYnV0ZSkge1xuICAgIGNvbnN0IGF0dHJUeXBlID0gYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8gPyBhdHRyLnR5cGUgOiAoYXR0ciBhcyBvcnRGYnMuQXR0cmlidXRlKS50eXBlKCk7XG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuR1JBUEggfHwgYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5HUkFQSFMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ3JhcGggYXR0cmlidXRlIGlzIG5vdCBzdXBwb3J0ZWQgeWV0Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldFZhbHVlTm9DaGVjayhhdHRyKTtcblxuICAgIC8vIGNhc3QgTE9ORyB0byBudW1iZXJcbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlQgJiYgTG9uZ1V0aWwuaXNMb25nKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIExvbmdVdGlsLmxvbmdUb051bWJlcih2YWx1ZSBhcyBiaWdpbnQgfCBMb25nKTtcbiAgICB9XG5cbiAgICAvLyBjYXN0IExPTkdbXSB0byBudW1iZXJbXVxuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVFMpIHtcbiAgICAgIGNvbnN0IGFyciA9IHZhbHVlIGFzIEFycmF5PG51bWJlciB8IExvbmcgfCBiaWdpbnQ+O1xuICAgICAgY29uc3QgbnVtYmVyVmFsdWU6IG51bWJlcltdID0gbmV3IEFycmF5PG51bWJlcj4oYXJyLmxlbmd0aCk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG1heWJlTG9uZyA9IGFycltpXTtcbiAgICAgICAgbnVtYmVyVmFsdWVbaV0gPSBMb25nVXRpbC5sb25nVG9OdW1iZXIobWF5YmVMb25nKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bWJlclZhbHVlO1xuICAgIH1cblxuICAgIC8vIGNhc3Qgb25ueC5UZW5zb3JQcm90byB0byBvbm54anMuVGVuc29yXG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SKSB7XG4gICAgICByZXR1cm4gYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgPyBUZW5zb3IuZnJvbVByb3RvKHZhbHVlIGFzIG9ubnguSVRlbnNvclByb3RvKVxuICAgICAgICA6IFRlbnNvci5mcm9tT3J0VGVuc29yKHZhbHVlIGFzIG9ydEZicy5UZW5zb3IpO1xuICAgIH1cblxuICAgIC8vIGNhc3Qgb25ueC5UZW5zb3JQcm90b1tdIHRvIG9ubnhqcy5UZW5zb3JbXVxuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUlMpIHtcbiAgICAgIGlmIChhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90bykge1xuICAgICAgICBjb25zdCB0ZW5zb3JQcm90b3MgPSB2YWx1ZSBhcyBvbm54LklUZW5zb3JQcm90b1tdO1xuICAgICAgICByZXR1cm4gdGVuc29yUHJvdG9zLm1hcCgodmFsdWUpID0+IFRlbnNvci5mcm9tUHJvdG8odmFsdWUpKTtcbiAgICAgIH0gZWxzZSBpZiAoYXR0ciBpbnN0YW5jZW9mIG9ydEZicy5BdHRyaWJ1dGUpIHtcbiAgICAgICAgY29uc3QgdGVuc29yUHJvdG9zID0gdmFsdWUgYXMgb3J0RmJzLlRlbnNvcltdO1xuICAgICAgICByZXR1cm4gdGVuc29yUHJvdG9zLm1hcCgodmFsdWUpID0+IFRlbnNvci5mcm9tT3J0VGVuc29yKHZhbHVlKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2FzdCBVaW50OEFycmF5IHRvIHN0cmluZ1xuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklORykge1xuICAgICAgLy8gc3RyaW5nIGluIG9ubnggYXR0cmlidXRlIGlzIG9mIHVpbnQ4YXJyYXkgdHlwZSwgc28gd2UgbmVlZCB0byBjb252ZXJ0IGl0IHRvIHN0cmluZyBiZWxvdy4gV2hpbGUgaW4gb3J0IGZvcm1hdCxcbiAgICAgIC8vIHN0cmluZyBhdHRyaWJ1dGVzIGFyZSByZXR1cm5lZCBhcyBzdHJpbmcsIHNvIG5vIGNvbnZlcnNpb24gaXMgbmVlZGVkLlxuICAgICAgaWYgKGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgIGNvbnN0IHV0ZjhTdHJpbmcgPSB2YWx1ZSBhcyBVaW50OEFycmF5O1xuICAgICAgICByZXR1cm4gZGVjb2RlVXRmOFN0cmluZyh1dGY4U3RyaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjYXN0IFVpbnQ4QXJyYXlbXSB0byBzdHJpbmdbXVxuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklOR1MpIHtcbiAgICAgIC8vIHN0cmluZ3MgaW4gb25ueCBhdHRyaWJ1dGUgaXMgcmV0dXJuZWQgYXMgdWludDhhcnJheVtdLCBzbyB3ZSBuZWVkIHRvIGNvbnZlcnQgaXQgdG8gc3RyaW5nW10gYmVsb3cuIFdoaWxlIGluIG9ydFxuICAgICAgLy8gZm9ybWF0IHN0cmluZ3MgYXR0cmlidXRlcyBhcmUgcmV0dXJuZWQgYXMgc3RyaW5nW10sIHNvIG5vIGNvbnZlcnNpb24gaXMgbmVlZGVkLlxuICAgICAgaWYgKGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgIGNvbnN0IHV0ZjhTdHJpbmdzID0gdmFsdWUgYXMgVWludDhBcnJheVtdO1xuICAgICAgICByZXR1cm4gdXRmOFN0cmluZ3MubWFwKGRlY29kZVV0ZjhTdHJpbmcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZSBhcyBWYWx1ZVR5cGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VmFsdWVOb0NoZWNrKGF0dHI6IG9ubnguSUF0dHJpYnV0ZVByb3RvIHwgb3J0RmJzLkF0dHJpYnV0ZSkge1xuICAgIHJldHVybiBhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgPyB0aGlzLmdldFZhbHVlTm9DaGVja0Zyb21Pbm54Rm9ybWF0KGF0dHIpXG4gICAgICA6IHRoaXMuZ2V0VmFsdWVOb0NoZWNrRnJvbU9ydEZvcm1hdChhdHRyIGFzIG9ydEZicy5BdHRyaWJ1dGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VmFsdWVOb0NoZWNrRnJvbU9ubnhGb3JtYXQoYXR0cjogb25ueC5JQXR0cmlidXRlUHJvdG8pIHtcbiAgICBzd2l0Y2ggKGF0dHIudHlwZSEpIHtcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkZMT0FUOlxuICAgICAgICByZXR1cm4gYXR0ci5mO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UOlxuICAgICAgICByZXR1cm4gYXR0ci5pO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuU1RSSU5HOlxuICAgICAgICByZXR1cm4gYXR0ci5zO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SOlxuICAgICAgICByZXR1cm4gYXR0ci50O1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuR1JBUEg6XG4gICAgICAgIHJldHVybiBhdHRyLmc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5GTE9BVFM6XG4gICAgICAgIHJldHVybiBhdHRyLmZsb2F0cztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVFM6XG4gICAgICAgIHJldHVybiBhdHRyLmludHM7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkdTOlxuICAgICAgICByZXR1cm4gYXR0ci5zdHJpbmdzO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SUzpcbiAgICAgICAgcmV0dXJuIGF0dHIudGVuc29ycztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkdSQVBIUzpcbiAgICAgICAgcmV0dXJuIGF0dHIuZ3JhcGhzO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBhdHRyaWJ1dGUgdHlwZTogJHtvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGVbYXR0ci50eXBlIV19YCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VmFsdWVOb0NoZWNrRnJvbU9ydEZvcm1hdChhdHRyOiBvcnRGYnMuQXR0cmlidXRlKSB7XG4gICAgc3dpdGNoIChhdHRyLnR5cGUoKSkge1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5GTE9BVDpcbiAgICAgICAgcmV0dXJuIGF0dHIuZigpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5JTlQ6XG4gICAgICAgIHJldHVybiBhdHRyLmkoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuU1RSSU5HOlxuICAgICAgICByZXR1cm4gYXR0ci5zKCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLlRFTlNPUjpcbiAgICAgICAgcmV0dXJuIGF0dHIudCgpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5HUkFQSDpcbiAgICAgICAgcmV0dXJuIGF0dHIuZygpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5GTE9BVFM6XG4gICAgICAgIHJldHVybiBhdHRyLmZsb2F0c0FycmF5KCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLklOVFM6IHtcbiAgICAgICAgY29uc3QgaW50cyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHIuaW50c0xlbmd0aCgpOyBpKyspIHtcbiAgICAgICAgICBpbnRzLnB1c2goYXR0ci5pbnRzKGkpISk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGludHM7XG4gICAgICB9XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLlNUUklOR1M6IHtcbiAgICAgICAgY29uc3Qgc3RyaW5ncyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHIuc3RyaW5nc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgICAgICBzdHJpbmdzLnB1c2goYXR0ci5zdHJpbmdzKGkpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RyaW5ncztcbiAgICAgIH1cbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuVEVOU09SUzoge1xuICAgICAgICBjb25zdCB0ZW5zb3JzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0ci50ZW5zb3JzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgICAgIHRlbnNvcnMucHVzaChhdHRyLnRlbnNvcnMoaSkhKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGVuc29ycztcbiAgICAgIH1cbiAgICAgIC8vIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuR1JBUEhTOlxuICAgICAgLy8gVE9ETzogU3ViZ3JhcGggbm90IHN1cHBvcnRlZCB5ZXQuXG4gICAgICAvLyBjb25zdCBncmFwaHMgPSBbXTtcbiAgICAgIC8vIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0ci5ncmFwaHNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICAvLyAgIGdyYXBocy5wdXNoKGF0dHIuZ3JhcGhzKGkpISk7XG4gICAgICAvLyB9XG4gICAgICAvLyByZXR1cm4gZ3JhcGhzO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBhdHRyaWJ1dGUgdHlwZTogJHtvcnRGYnMuQXR0cmlidXRlVHlwZVthdHRyLnR5cGUoKV19YCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF9hdHRyaWJ1dGVzOiBNYXA8c3RyaW5nLCBWYWx1ZT47XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZSB9IGZyb20gJy4vYXR0cmlidXRlJztcbmltcG9ydCAqIGFzIG9ydEZicyBmcm9tICcuL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQgeyBvbm54IH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuaW1wb3J0IHsgTG9uZ1V0aWwsIE1BWF9DTElQLCBNSU5fQ0xJUCwgUHJvdG9VdGlsIH0gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIEdyYXBoIHtcbiAgZXhwb3J0IGludGVyZmFjZSBTaGFwZSB7XG4gICAgcmVhZG9ubHkgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBWYWx1ZVR5cGUge1xuICAgIHJlYWRvbmx5IHRlbnNvclR5cGU6IFRlbnNvci5EYXRhVHlwZTtcbiAgICByZWFkb25seSBzaGFwZTogU2hhcGU7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBWYWx1ZSB7XG4gICAgLy8gdGhlIHRlbnNvciBkYXRhLiBlbXB0eSBmb3Igbm9uLWluaXRpYWxpemVkIGlucHV0c1xuICAgIHJlYWRvbmx5IHRlbnNvcj86IFRlbnNvcjtcblxuICAgIC8vIGluZGV4IHRvIHRoZSBOb2RlIHdoZXJlIHRoZSB2YWx1ZSBjb21lcyBmcm9tLiAtMSBmb3IgaW5pdGlhbGl6ZXIuXG4gICAgcmVhZG9ubHkgZnJvbTogbnVtYmVyO1xuXG4gICAgLy8gaW5kaWNlcyB0byB0aGUgTm9kZXMgd2hlcmUgdGhlIHZhbHVlcyBnbyB0by5cbiAgICByZWFkb25seSB0bzogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgICAvLyB2YWx1ZSB0eXBlIHNwZWNpZmljYXRpb24uIGVtcHR5IGZvciBub24taW5wdXQgdmFsdWVzLlxuICAgIHJlYWRvbmx5IHR5cGU/OiBWYWx1ZVR5cGU7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBOb2RlIHtcbiAgICAvLyBuYW1lIG9mIHRoZSBub2RlXG4gICAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuXG4gICAgLy8gdGhlIG9wZXJhdG9yIHR5cGVcbiAgICByZWFkb25seSBvcFR5cGU6IHN0cmluZztcblxuICAgIC8vIGluZGljZXMgdG8gdGhlIFZhbHVlcyB3aGVyZSB0aGUgaW5wdXRzIGNvbWUgZnJvbS5cbiAgICByZWFkb25seSBpbnB1dHM6IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gICAgLy8gaW5kaWNlcyB0byB0aGUgVmFsdWVzIHdoZXJlIHRoZSBvdXRwdXMgZ28gdG8uXG4gICAgcmVhZG9ubHkgb3V0cHV0czogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgICAvLyB0aGUgYXR0cmlidXRlcyB0aGF0IHVzZWQgYnkgdGhlIG9wZXJhdG9yXG4gICAgcmVhZG9ubHkgYXR0cmlidXRlczogQXR0cmlidXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIGEgVHJhbnNmb3JtZXIgaXMgYW4gaW5zdGFuY2UgdGhhdCBhbGxvd3MgYWxsIHBvc3NpYmxlIHRyYW5zZm9ybWF0aW9uIG9wZXJhdGlvbnMgdGhhdCBhcHBsaWVkIHRvIGEgZ3JhcGhcbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgVHJhbnNmb3JtZXIge1xuICAgIHJlbW92ZUFsbElkZW50aXR5Tm9kZXMoKTogdm9pZDtcbiAgICByZW1vdmVBbGxEcm9wb3V0Tm9kZXMoKTogdm9pZDtcbiAgICBmdXNlQ29udkFjdGl2YXRpb25Ob2RlcygpOiB2b2lkO1xuICAgIC8vIFRPRE86IGFkZCBnZW5lcmljIGZ1bmN0aW9ucyB0byBtYW5pcHVsYXRlIHRoZSBncmFwaFxuICB9XG5cbiAgLy8gYW4gaW5pdGlhbGl6ZXIgY2FuIHVzZSB0cmFuc2Zvcm1lciB0byB0cmFuc2Zvcm0gdGhlIGdyYXBoXG4gIGV4cG9ydCBpbnRlcmZhY2UgSW5pdGlhbGl6ZXIge1xuICAgIHRyYW5zZm9ybUdyYXBoKHRyYW5zZm9ybWVyOiBUcmFuc2Zvcm1lcik6IHZvaWQ7XG4gIH1cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmVcbmV4cG9ydCBpbnRlcmZhY2UgR3JhcGgge1xuICBnZXRJbnB1dEluZGljZXMoKTogcmVhZG9ubHkgbnVtYmVyW107XG4gIGdldElucHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW107XG4gIGdldE91dHB1dEluZGljZXMoKTogcmVhZG9ubHkgbnVtYmVyW107XG4gIGdldE91dHB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICBnZXRWYWx1ZXMoKTogcmVhZG9ubHkgR3JhcGguVmFsdWVbXTtcbiAgZ2V0Tm9kZXMoKTogcmVhZG9ubHkgR3JhcGguTm9kZVtdO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlXG5leHBvcnQgY29uc3QgR3JhcGggPSB7XG4gIC8qKlxuICAgKiBjb25zdHJ1Y3QgYSBncmFwaCBmcm9tIGEgZ3JhcGggcHJvdG9idWYgdHlwZVxuICAgKi9cbiAgZnJvbTogKGdyYXBoUHJvdG86IG9ubnguSUdyYXBoUHJvdG8gfCBvcnRGYnMuR3JhcGgsIGluaXRpYWxpemVyPzogR3JhcGguSW5pdGlhbGl6ZXIpID0+XG4gICAgbmV3IEdyYXBoSW1wbChncmFwaFByb3RvLCBpbml0aWFsaXplciksXG59O1xuXG5jbGFzcyBWYWx1ZSBpbXBsZW1lbnRzIEdyYXBoLlZhbHVlIHtcbiAgY29uc3RydWN0b3IodmFsdWVJbmZvPzogb25ueC5JVmFsdWVJbmZvUHJvdG8pIHtcbiAgICB0aGlzLl9mcm9tID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3RvID0gW107XG4gICAgdGhpcy50ZW5zb3IgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy50eXBlID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKHZhbHVlSW5mbykge1xuICAgICAgdGhpcy50eXBlID0gUHJvdG9VdGlsLnRlbnNvclZhbHVlVHlwZUZyb21Qcm90byh2YWx1ZUluZm8udHlwZSEudGVuc29yVHlwZSEpO1xuICAgIH1cbiAgfVxuXG4gIF9mcm9tPzogbnVtYmVyOyAvLyAtMSByZXByZXNlbnQgZnJvbSBpbml0aWFsaXplclxuICBnZXQgZnJvbSgpIHtcbiAgICByZXR1cm4gdGhpcy5fZnJvbSE7XG4gIH1cbiAgX3RvOiBudW1iZXJbXTtcbiAgZ2V0IHRvKCkge1xuICAgIHJldHVybiB0aGlzLl90bztcbiAgfVxuICB0eXBlPzogR3JhcGguVmFsdWVUeXBlO1xuICB0ZW5zb3I/OiBUZW5zb3I7XG59XG5cbmNsYXNzIE5vZGUgaW1wbGVtZW50cyBHcmFwaC5Ob2RlIHtcbiAgY29uc3RydWN0b3IoX25vZGVQcm90bzogb25ueC5JTm9kZVByb3RvIHwgb3J0RmJzLk5vZGUsIG5hbWU/OiBzdHJpbmcpIHtcbiAgICBpZiAoX25vZGVQcm90byBpbnN0YW5jZW9mIG9ubnguTm9kZVByb3RvKSB7XG4gICAgICB0aGlzLm5hbWUgPSBfbm9kZVByb3RvLm5hbWU7XG4gICAgICB0aGlzLm9wVHlwZSA9IF9ub2RlUHJvdG8ub3BUeXBlO1xuICAgICAgdGhpcy5hdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZShfbm9kZVByb3RvLmF0dHJpYnV0ZSk7XG4gICAgfSBlbHNlIGlmIChfbm9kZVByb3RvIGluc3RhbmNlb2Ygb3J0RmJzLk5vZGUpIHtcbiAgICAgIHRoaXMubmFtZSA9IG5hbWUgPz8gX25vZGVQcm90by5uYW1lKCkhO1xuICAgICAgdGhpcy5vcFR5cGUgPSBfbm9kZVByb3RvLm9wVHlwZSgpITtcbiAgICAgIHRoaXMuYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGUoUHJvdG9VdGlsLnRlbnNvckF0dHJpYnV0ZXNGcm9tT1JURm9ybWF0KF9ub2RlUHJvdG8pKTtcbiAgICB9XG5cbiAgICB0aGlzLmlucHV0cyA9IFtdO1xuICAgIHRoaXMub3V0cHV0cyA9IFtdO1xuICAgIHRoaXMuZXhlY3V0ZU5vZGUgPSB0cnVlO1xuICB9XG5cbiAgbmFtZTogc3RyaW5nO1xuICBvcFR5cGU6IHN0cmluZztcbiAgaW5wdXRzOiBudW1iZXJbXTtcbiAgb3V0cHV0czogbnVtYmVyW107XG4gIGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZTtcbiAgZXhlY3V0ZU5vZGU6IGJvb2xlYW47XG59XG5cbmNsYXNzIEdyYXBoSW1wbCBpbXBsZW1lbnRzIEdyYXBoLCBHcmFwaC5UcmFuc2Zvcm1lciB7XG4gIHByaXZhdGUgX2FsbERhdGE6IFZhbHVlW107XG5cbiAgcHJpdmF0ZSBfYWxsSW5wdXRJbmRpY2VzOiBudW1iZXJbXTtcbiAgcHJpdmF0ZSBfYWxsSW5wdXROYW1lczogc3RyaW5nW107XG5cbiAgcHJpdmF0ZSBfYWxsT3V0cHV0SW5kaWNlczogbnVtYmVyW107XG4gIHByaXZhdGUgX2FsbE91dHB1dE5hbWVzOiBzdHJpbmdbXTtcblxuICBwcml2YXRlIF9ub2RlczogTm9kZVtdO1xuXG4gIGNvbnN0cnVjdG9yKGdyYXBoOiBvbm54LklHcmFwaFByb3RvIHwgb3J0RmJzLkdyYXBoLCBncmFwaEluaXRpYWxpemVyPzogR3JhcGguSW5pdGlhbGl6ZXIpIHtcbiAgICBpZiAoIWdyYXBoKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdncmFwaCBpcyBlbXB0eScpO1xuICAgIH1cblxuICAgIC8vIGJ1aWxkIHRoZSBncmFwaCAtIHdpbGwgdGhyb3cgZXhjZXB0aW9ucyBpZiBzb21ldGhpbmcgZmF0YWwgaXMgZGV0ZWN0ZWRcbiAgICB0aGlzLmJ1aWxkR3JhcGgoZ3JhcGgpO1xuXG4gICAgLy8gZXhlY3V0ZSBhbnkgdHJhbnNmb3JtYXRpb24gbG9naWMgZm9yIHRoZSBncmFwaCAoaWYgYXBwbGljYWJsZSlcbiAgICB0aGlzLnRyYW5zZm9ybUdyYXBoKGdyYXBoSW5pdGlhbGl6ZXIpO1xuXG4gICAgLy8gY2hlY2sgZm9yIGN5Y2xlcyBhbmQgb3RoZXIgaW5jb25zaXN0ZW5jaWVzIC0gd2lsbCB0aHJvdyBleGNlcHRpb25zIGlmIHNvbWV0aGluZyBmYXRhbCBpcyBkZXRlY3RlZFxuICAgIHRoaXMuY2hlY2tJc0FjeWNsaWMoKTtcbiAgfVxuXG4gIGdldElucHV0SW5kaWNlcygpOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsbElucHV0SW5kaWNlcztcbiAgfVxuXG4gIGdldElucHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxJbnB1dE5hbWVzO1xuICB9XG5cbiAgZ2V0T3V0cHV0SW5kaWNlcygpOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsbE91dHB1dEluZGljZXM7XG4gIH1cblxuICBnZXRPdXRwdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsbE91dHB1dE5hbWVzO1xuICB9XG5cbiAgZ2V0VmFsdWVzKCk6IHJlYWRvbmx5IEdyYXBoLlZhbHVlW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxEYXRhO1xuICB9XG5cbiAgZ2V0Tm9kZXMoKTogcmVhZG9ubHkgR3JhcGguTm9kZVtdIHtcbiAgICByZXR1cm4gdGhpcy5fbm9kZXM7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkR3JhcGgoZ3JhcGg6IG9ubnguSUdyYXBoUHJvdG8gfCBvcnRGYnMuR3JhcGgpIHtcbiAgICAvLyBidWlsZCB0aGUgZ3JhcGggLSB3aWxsIHRocm93IGV4Y2VwdGlvbnMgaWYgc29tZXRoaW5nIGZhdGFsIGlzIGRldGVjdGVkXG4gICAgaWYgKGdyYXBoIGluc3RhbmNlb2Ygb25ueC5HcmFwaFByb3RvKSB7XG4gICAgICB0aGlzLmJ1aWxkR3JhcGhGcm9tT25ueEZvcm1hdChncmFwaCk7XG4gICAgfSBlbHNlIGlmIChncmFwaCBpbnN0YW5jZW9mIG9ydEZicy5HcmFwaCkge1xuICAgICAgdGhpcy5idWlsZEdyYXBoRnJvbU9ydEZvcm1hdChncmFwaCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0dyYXBoIHR5cGUgaXMgbm90IHN1cHBvcnRlZC4nKTtcbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSBidWlsZEdyYXBoRnJvbU9ubnhGb3JtYXQoZ3JhcGg6IG9ubnguSUdyYXBoUHJvdG8pIHtcbiAgICBjb25zdCBkYXRhSW5kaWNlcyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gICAgdGhpcy5fYWxsRGF0YSA9IFtdO1xuXG4gICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzID0gW107XG4gICAgdGhpcy5fYWxsSW5wdXROYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5fYWxsT3V0cHV0SW5kaWNlcyA9IFtdO1xuICAgIHRoaXMuX2FsbE91dHB1dE5hbWVzID0gW107XG5cbiAgICB0aGlzLl9ub2RlcyA9IFtdO1xuXG4gICAgY29uc3Qgbm9kZXNJbmRpY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcblxuICAgIC8vIHNjYW4gYWxsIGlucHV0c1xuICAgIGlmICghZ3JhcGguaW5wdXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBpbmZvcm1hdGlvbiBpbiBncmFwaDogaW5wdXQnKTtcbiAgICB9XG4gICAgY29uc3QgaW5wdXRWYWx1ZU5hbWVzID0gW107XG4gICAgZm9yIChjb25zdCBpIG9mIGdyYXBoLmlucHV0KSB7XG4gICAgICBpZiAoZGF0YUluZGljZXMuaGFzKGkubmFtZSEpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBpbnB1dCBuYW1lOiAke2kubmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaChuZXcgVmFsdWUoaSkpIC0gMTtcbiAgICAgIGRhdGFJbmRpY2VzLnNldChpLm5hbWUhLCBjdXJyZW50SW5kZXgpO1xuICAgICAgaW5wdXRWYWx1ZU5hbWVzLnB1c2goaS5uYW1lISk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgaW5pdGlhbGl6ZXJzXG4gICAgaWYgKCFncmFwaC5pbml0aWFsaXplcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGluZm9ybWF0aW9uIGluIGdyYXBoOiBpbml0aWFsaXplcicpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGkgb2YgZ3JhcGguaW5pdGlhbGl6ZXIpIHtcbiAgICAgIGxldCBpbmRleCA9IGRhdGFJbmRpY2VzLmdldChpLm5hbWUhKTtcbiAgICAgIGlmIChpbmRleCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gbmV3IFZhbHVlKCk7XG4gICAgICAgIHZhbHVlLnR5cGUgPSB7XG4gICAgICAgICAgc2hhcGU6IHsgZGltczogUHJvdG9VdGlsLnRlbnNvckRpbXNGcm9tUHJvdG8oaS5kaW1zISkgfSxcbiAgICAgICAgICB0ZW5zb3JUeXBlOiBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8oaS5kYXRhVHlwZSEpLFxuICAgICAgICB9O1xuICAgICAgICBpbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaCh2YWx1ZSkgLSAxO1xuICAgICAgICBkYXRhSW5kaWNlcy5zZXQoaS5uYW1lISwgaW5kZXgpO1xuICAgICAgfVxuICAgICAgdGhpcy5fYWxsRGF0YVtpbmRleF0uX2Zyb20gPSAtMTtcbiAgICAgIHRoaXMuX2FsbERhdGFbaW5kZXhdLnRlbnNvciA9IFRlbnNvci5mcm9tUHJvdG8oaSk7XG4gICAgfVxuXG4gICAgLy8gZmlsdGVyIG91dCBpbnB1dCBpbmRpY2VzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hbGxEYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIXRoaXMuX2FsbERhdGFbaV0udGVuc29yKSB7XG4gICAgICAgIHRoaXMuX2FsbElucHV0SW5kaWNlcy5wdXNoKGkpO1xuICAgICAgICB0aGlzLl9hbGxJbnB1dE5hbWVzLnB1c2goaW5wdXRWYWx1ZU5hbWVzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBvdXRwdXRzXG4gICAgaWYgKCFncmFwaC5vdXRwdXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBpbmZvcm1hdGlvbiBpbiBncmFwaDogb3V0cHV0Jyk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgaSBvZiBncmFwaC5vdXRwdXQpIHtcbiAgICAgIGlmIChkYXRhSW5kaWNlcy5oYXMoaS5uYW1lISkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBkdXBsaWNhdGVkIG91dHB1dCBuYW1lOiAke2kubmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaChuZXcgVmFsdWUoaSkpIC0gMTtcbiAgICAgIGRhdGFJbmRpY2VzLnNldChpLm5hbWUhLCBjdXJyZW50SW5kZXgpO1xuICAgICAgdGhpcy5fYWxsT3V0cHV0SW5kaWNlcy5wdXNoKGN1cnJlbnRJbmRleCk7XG4gICAgICB0aGlzLl9hbGxPdXRwdXROYW1lcy5wdXNoKGkubmFtZSEpO1xuICAgIH1cblxuICAgIC8vIHNjYW4gYWxsIG5vZGVzXG4gICAgaWYgKCFncmFwaC5ub2RlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgaW5mb3JtYXRpb24gaW4gZ3JhcGg6IG5vZGUnKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBub2RlUHJvdG8gb2YgZ3JhcGgubm9kZSkge1xuICAgICAgaWYgKCFub2RlUHJvdG8ubmFtZSkge1xuICAgICAgICAvLyBhc3NpZ24gYSBuYW1lIHRvIHRoZSBub2RlIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmVcbiAgICAgICAgZm9yIChsZXQgcGljayA9IDA7IDsgcGljaysrKSB7XG4gICAgICAgICAgY29uc3QgbmFtZSA9IGB1bm5hbWVkXyR7bm9kZVByb3RvLm9wVHlwZX1fJHtwaWNrfWA7XG4gICAgICAgICAgaWYgKCFub2Rlc0luZGljZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICBub2RlUHJvdG8ubmFtZSA9IG5hbWU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGVzSW5kaWNlcy5oYXMobm9kZVByb3RvLm5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBub2RlIG5hbWU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9ub2Rlcy5wdXNoKG5ldyBOb2RlKG5vZGVQcm90bykpIC0gMTtcbiAgICAgIG5vZGVzSW5kaWNlcy5zZXQobm9kZVByb3RvLm5hbWUsIGN1cnJlbnRJbmRleCk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBub2RlJ3Mgb3V0cHV0c1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2Rlc1tpXTtcbiAgICAgIGNvbnN0IG5vZGVQcm90byA9IGdyYXBoLm5vZGVbaV07XG4gICAgICBpZiAoIW5vZGVQcm90by5vdXRwdXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIG91dHB1dCBmb3Igbm9kZTogJHtub2RlUHJvdG8ubmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIG5vZGVQcm90by5vdXRwdXQpIHtcbiAgICAgICAgbGV0IGRhdGFJbmRleCA9IGRhdGFJbmRpY2VzLmdldChvdXRwdXQpO1xuICAgICAgICBpZiAodHlwZW9mIGRhdGFJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBkYXRhSW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2gobmV3IFZhbHVlKCkpIC0gMTtcbiAgICAgICAgICBkYXRhSW5kaWNlcy5zZXQob3V0cHV0LCBkYXRhSW5kZXgpO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUub3V0cHV0cy5wdXNoKGRhdGFJbmRleCk7XG5cbiAgICAgICAgaWYgKHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtdWx0aXBsZSBub2RlcyBvdXRwdXQgdG8gb25lIGRhdGEgdmFsdWU6ICR7ZGF0YUluZGV4fWApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSA9IGk7XG5cbiAgICAgICAgLy8gZm9yIHRoZSAnQ29uc3RhbnQnIG9wZXJhdG9yLCBqdXN0IGNyZWF0ZSBhIG5ldyBlZGdlIGluIHRoZSBncmFwaCBjb3JyZXNwb25kaW5nIHRvIHRoZSAnb3V0cHV0JyBvZiB0aGVcbiAgICAgICAgLy8gb3BlcmF0b3IgYW5kIGlnbm9yZSB0aGUgbm9kZSBmcm9tIHRoZSBncmFwaFxuICAgICAgICBpZiAobm9kZVByb3RvLm9wVHlwZSA9PT0gJ0NvbnN0YW50Jykge1xuICAgICAgICAgIGlmICghbm9kZVByb3RvLmF0dHJpYnV0ZSB8fCBub2RlUHJvdG8uYXR0cmlidXRlLmxlbmd0aCAhPT0gMSB8fCAhbm9kZVByb3RvLmF0dHJpYnV0ZVswXS50KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgYXR0cmlidXRlcyBvciBtaXNzaW5nIHRlbnNvciB2YWx1ZSBpbiBhdHRyaWJ1dGVzIGZvciB0aGlzIENvbnN0YW50IG9wZXJhdG9yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghbm9kZVByb3RvLm91dHB1dCB8fCBub2RlUHJvdG8ub3V0cHV0Lmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIG91dHB1dCBvciBpbmNvcnJlY3QgbnVtYmVyIG9mIG91dHB1dHMgZm9yIHRoaXMgQ29uc3RhbnQgb3BlcmF0b3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbm9kZS5vdXRwdXRzLnBvcCgpO1xuICAgICAgICAgIG5vZGUuZXhlY3V0ZU5vZGUgPSBmYWxzZTtcblxuICAgICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSA9IC0xO1xuICAgICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS50ZW5zb3IgPSBUZW5zb3IuZnJvbVByb3RvKG5vZGVQcm90by5hdHRyaWJ1dGVbMF0udCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzY2FuIG5vZGUncyBpbnB1dHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICBjb25zdCBub2RlUHJvdG8gPSBncmFwaC5ub2RlW2ldO1xuXG4gICAgICBpZiAoIW5vZGVQcm90by5pbnB1dCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG1pc3NpbmcgaW5wdXQgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGlucHV0IG9mIG5vZGVQcm90by5pbnB1dCkge1xuICAgICAgICBjb25zdCBkYXRhSW5kZXggPSBkYXRhSW5kaWNlcy5nZXQoaW5wdXQpO1xuICAgICAgICBpZiAodHlwZW9mIGRhdGFJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAvLyBoYW5kbGUgZXhjZXB0aW9uIHdoZW4gb3BzZXQgPiA5IGFuZCByb2kgLyBzY2FsZXMgbm90IGdpdmVuXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgaW5wdXQgPT09ICcnICYmXG4gICAgICAgICAgICAobm9kZVByb3RvLmlucHV0Lmxlbmd0aCA9PT0gMyB8fCBub2RlUHJvdG8uaW5wdXQubGVuZ3RoID09PSA0KSAmJlxuICAgICAgICAgICAgbm9kZVByb3RvLm9wVHlwZSA9PT0gJ1Jlc2l6ZSdcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVjb2duaXplZCBpbnB1dCAnJHtpbnB1dH0nIGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUuaW5wdXRzLnB1c2goZGF0YUluZGV4KTtcblxuICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX3RvLnB1c2goaSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkR3JhcGhGcm9tT3J0Rm9ybWF0KGdyYXBoOiBvcnRGYnMuR3JhcGgpIHtcbiAgICBjb25zdCBkYXRhSW5kaWNlcyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gICAgdGhpcy5fYWxsRGF0YSA9IFtdO1xuXG4gICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzID0gW107XG4gICAgdGhpcy5fYWxsSW5wdXROYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5fYWxsT3V0cHV0SW5kaWNlcyA9IFtdO1xuICAgIHRoaXMuX2FsbE91dHB1dE5hbWVzID0gW107XG5cbiAgICB0aGlzLl9ub2RlcyA9IFtdO1xuXG4gICAgY29uc3Qgbm9kZXNJbmRpY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcblxuICAgIC8vIHNjYW4gYWxsIGlucHV0c1xuICAgIGNvbnN0IGlucHV0VmFsdWVOYW1lcyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ3JhcGguaW5wdXRzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3QgaW5wdXROYW1lID0gZ3JhcGguaW5wdXRzKGkpO1xuICAgICAgaWYgKGRhdGFJbmRpY2VzLmhhcyhpbnB1dE5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBpbnB1dCBuYW1lOiAke2lucHV0TmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIC8vIEZpbmQgdGhlIGlucHV0IHR5cGVJbmZvIGZyb20gbm9kZWFyZ3NcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgZ3JhcGgubm9kZUFyZ3NMZW5ndGgoKTsgaisrKSB7XG4gICAgICAgIGlmIChncmFwaC5ub2RlQXJncyhqKT8ubmFtZSgpID09PSBpbnB1dE5hbWUpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyBWYWx1ZSgpO1xuICAgICAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IGdyYXBoLm5vZGVBcmdzKGopPy50eXBlKCk/LnZhbHVlVHlwZSgpO1xuICAgICAgICAgIGlmICh2YWx1ZVR5cGUgIT09IG9ydEZicy5UeXBlSW5mb1ZhbHVlLnRlbnNvcl90eXBlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgdmFsdWUgdHlwZSBmb3IgdGhlIG5vZGVBcmcuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHZhbHVlSW5mbyA9IGdyYXBoLm5vZGVBcmdzKGopIS50eXBlKCkhLnZhbHVlKG5ldyBvcnRGYnMuVGVuc29yVHlwZUFuZFNoYXBlKCkpITtcbiAgICAgICAgICBjb25zdCB0eXBlID0gUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKHZhbHVlSW5mby5lbGVtVHlwZSgpKTtcbiAgICAgICAgICBjb25zdCBzaGFwZSA9IHZhbHVlSW5mby5zaGFwZSgpITtcbiAgICAgICAgICBjb25zdCBkaW1zID0gW107XG4gICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBzaGFwZS5kaW1MZW5ndGgoKSE7IGsrKykge1xuICAgICAgICAgICAgZGltcy5wdXNoKExvbmdVdGlsLmxvbmdUb051bWJlcihzaGFwZS5kaW0oaykhLnZhbHVlKCkhLmRpbVZhbHVlKCkhKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhbHVlLnR5cGUgPSB7IHNoYXBlOiB7IGRpbXMgfSwgdGVuc29yVHlwZTogdHlwZSB9O1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaCh2YWx1ZSkgLSAxO1xuICAgICAgICAgIGRhdGFJbmRpY2VzLnNldChpbnB1dE5hbWUsIGN1cnJlbnRJbmRleCk7XG4gICAgICAgICAgaW5wdXRWYWx1ZU5hbWVzLnB1c2goaW5wdXROYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBjaGVjayBpbml0aWFsaXplcnNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoLmluaXRpYWxpemVyc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IGluaXRpYWxpemVyID0gZ3JhcGguaW5pdGlhbGl6ZXJzKGkpITtcbiAgICAgIGxldCBpbmRleCA9IGRhdGFJbmRpY2VzLmdldChpbml0aWFsaXplci5uYW1lKCkhKTtcbiAgICAgIGlmIChpbmRleCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gbmV3IFZhbHVlKCk7XG4gICAgICAgIGNvbnN0IGRpbXMgPSBQcm90b1V0aWwudGVuc29yRGltc0Zyb21PUlRGb3JtYXQoaW5pdGlhbGl6ZXIpO1xuICAgICAgICBjb25zdCB0eXBlID0gUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKGluaXRpYWxpemVyLmRhdGFUeXBlKCkpO1xuICAgICAgICB2YWx1ZS50eXBlID0geyBzaGFwZTogeyBkaW1zIH0sIHRlbnNvclR5cGU6IHR5cGUgfTtcbiAgICAgICAgaW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2godmFsdWUpIC0gMTtcbiAgICAgICAgZGF0YUluZGljZXMuc2V0KGluaXRpYWxpemVyLm5hbWUoKSEsIGluZGV4KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2FsbERhdGFbaW5kZXhdLl9mcm9tID0gLTE7XG4gICAgICB0aGlzLl9hbGxEYXRhW2luZGV4XS50ZW5zb3IgPSBUZW5zb3IuZnJvbU9ydFRlbnNvcihpbml0aWFsaXplcik7XG4gICAgfVxuXG4gICAgLy8gZmlsdGVyIG91dCBpbnB1dCBpbmRpY2VzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hbGxEYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIXRoaXMuX2FsbERhdGFbaV0udGVuc29yKSB7XG4gICAgICAgIHRoaXMuX2FsbElucHV0SW5kaWNlcy5wdXNoKGkpO1xuICAgICAgICB0aGlzLl9hbGxJbnB1dE5hbWVzLnB1c2goaW5wdXRWYWx1ZU5hbWVzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBvdXRwdXRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaC5vdXRwdXRzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3Qgb3V0cHV0TmFtZSA9IGdyYXBoLm91dHB1dHMoaSk7XG4gICAgICBpZiAoZGF0YUluZGljZXMuaGFzKG91dHB1dE5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBvdXRwdXQgbmFtZTogJHtvdXRwdXROYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZSgpKSAtIDE7XG4gICAgICBkYXRhSW5kaWNlcy5zZXQob3V0cHV0TmFtZSwgY3VycmVudEluZGV4KTtcbiAgICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXMucHVzaChjdXJyZW50SW5kZXgpO1xuICAgICAgdGhpcy5fYWxsT3V0cHV0TmFtZXMucHVzaChvdXRwdXROYW1lKTtcbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBub2Rlc1xuICAgIGlmICghZ3JhcGgubm9kZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBpbmZvcm1hdGlvbiBpbiBncmFwaDogbm9kZScpO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoLm5vZGVzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZVByb3RvID0gZ3JhcGgubm9kZXMoaSk7XG4gICAgICBsZXQgbmFtZSA9IG5vZGVQcm90byEubmFtZSgpO1xuICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgIC8vIGFzc2lnbiBhIG5hbWUgdG8gdGhlIG5vZGUgaWYgaXQgZG9lc24ndCBoYXZlIG9uZVxuICAgICAgICBmb3IgKGxldCBwaWNrID0gMDsgOyBwaWNrKyspIHtcbiAgICAgICAgICBuYW1lID0gYHVubmFtZWRfJHtub2RlUHJvdG8hLm9wVHlwZSgpfV8ke3BpY2t9YDtcbiAgICAgICAgICBpZiAoIW5vZGVzSW5kaWNlcy5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgIC8vIGFuIHVuaXF1ZSBuYW1lIGlzIGZvdW5kLiBicmVhay5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAobm9kZXNJbmRpY2VzLmhhcyhuYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgbm9kZSBuYW1lOiAke25hbWV9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9ub2Rlcy5wdXNoKG5ldyBOb2RlKG5vZGVQcm90byEsIG5hbWUpKSAtIDE7XG4gICAgICBub2Rlc0luZGljZXMuc2V0KG5hbWUsIGN1cnJlbnRJbmRleCk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBub2RlJ3Mgb3V0cHV0c1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2Rlc1tpXTtcbiAgICAgIGNvbnN0IG5vZGVQcm90byA9IGdyYXBoLm5vZGVzKGkpO1xuICAgICAgaWYgKG5vZGVQcm90byA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gbm9kZSBleGlzdHMgYXQgaW5kZXggJHtpfWApO1xuICAgICAgfVxuICAgICAgaWYgKG5vZGVQcm90bz8ub3V0cHV0c0xlbmd0aCgpID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBvdXRwdXQgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG5vZGVQcm90bz8ub3V0cHV0c0xlbmd0aCgpOyBqKyspIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gbm9kZVByb3RvPy5vdXRwdXRzKGopO1xuICAgICAgICBsZXQgZGF0YUluZGV4ID0gZGF0YUluZGljZXMuZ2V0KG91dHB1dCk7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YUluZGV4ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGRhdGFJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaChuZXcgVmFsdWUoKSkgLSAxO1xuICAgICAgICAgIGRhdGFJbmRpY2VzLnNldChvdXRwdXQsIGRhdGFJbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZS5vdXRwdXRzLnB1c2goZGF0YUluZGV4KTtcblxuICAgICAgICBpZiAodGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl9mcm9tICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG11bHRpcGxlIG5vZGVzIG91dHB1dCB0byBvbmUgZGF0YSB2YWx1ZTogJHtkYXRhSW5kZXh9YCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl9mcm9tID0gaTtcblxuICAgICAgICAvLyBmb3IgdGhlICdDb25zdGFudCcgb3BlcmF0b3IsIGp1c3QgY3JlYXRlIGEgbmV3IGVkZ2UgaW4gdGhlIGdyYXBoIGNvcnJlc3BvbmRpbmcgdG8gdGhlICdvdXRwdXQnIG9mIHRoZVxuICAgICAgICAvLyBvcGVyYXRvciBhbmQgaWdub3JlIHRoZSBub2RlIGZyb20gdGhlIGdyYXBoXG4gICAgICAgIGlmIChub2RlUHJvdG8ub3BUeXBlKCkgPT09ICdDb25zdGFudCcpIHtcbiAgICAgICAgICBpZiAobm9kZVByb3RvLmF0dHJpYnV0ZXNMZW5ndGgoKSAhPT0gMSB8fCAhbm9kZVByb3RvLmF0dHJpYnV0ZXMoMCkhLnQoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGF0dHJpYnV0ZXMgb3IgbWlzc2luZyB0ZW5zb3IgdmFsdWUgaW4gYXR0cmlidXRlcyBmb3IgdGhpcyBDb25zdGFudCBvcGVyYXRvcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobm9kZVByb3RvLm91dHB1dHNMZW5ndGgoKSAhPT0gMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIG91dHB1dCBvciBpbmNvcnJlY3QgbnVtYmVyIG9mIG91dHB1dHMgZm9yIHRoaXMgQ29uc3RhbnQgb3BlcmF0b3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbm9kZS5vdXRwdXRzLnBvcCgpO1xuICAgICAgICAgIG5vZGUuZXhlY3V0ZU5vZGUgPSBmYWxzZTtcblxuICAgICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSA9IC0xO1xuICAgICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS50ZW5zb3IgPSBUZW5zb3IuZnJvbU9ydFRlbnNvcihub2RlUHJvdG8uYXR0cmlidXRlcygwKSEudCgpISk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzY2FuIG5vZGUncyBpbnB1dHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICBjb25zdCBub2RlUHJvdG8gPSBncmFwaC5ub2RlcyhpKSE7XG5cbiAgICAgIGlmIChub2RlUHJvdG8uaW5wdXRzTGVuZ3RoKCkgPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIGlucHV0IGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBub2RlUHJvdG8uaW5wdXRzTGVuZ3RoKCkhOyBqKyspIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBub2RlUHJvdG8uaW5wdXRzKGopITtcbiAgICAgICAgY29uc3QgZGF0YUluZGV4ID0gZGF0YUluZGljZXMuZ2V0KGlucHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlY29nbml6ZWQgaW5wdXQgJyR7aW5wdXR9JyBmb3Igbm9kZTogJHtub2RlUHJvdG8hLm5hbWUoKX1gKTtcbiAgICAgICAgfVxuICAgICAgICBub2RlLmlucHV0cy5wdXNoKGRhdGFJbmRleCk7XG5cbiAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl90by5wdXNoKGkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tJc0FjeWNsaWMoKSB7XG4gICAgLy8gZ28gdGhyb3VnaCB0aGUgZ3JhcGggYW5kIGNoZWNrIGZvciBjeWNsZXMgb3Igb3RoZXIgZmF0YWwgaW5jb25zaXN0ZW5jaWVzXG4gICAgY29uc3Qgc3RhcnRlcnM6IFNldDxudW1iZXI+ID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzLmZvckVhY2goKGkpID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9hbGxEYXRhW2ldO1xuICAgICAgZGF0YS5fdG8uZm9yRWFjaCgoaikgPT4ge1xuICAgICAgICBzdGFydGVycy5hZGQoaik7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIEl0ZXJhdGl2ZSBERlMgdG8gY2hlY2sgZm9yIGN5Y2xlc1xuICAgIGNvbnN0IG5vZGVzU3RhY2sgPSBBcnJheS5mcm9tKHN0YXJ0ZXJzKTtcbiAgICBjb25zdCBub2Rlc1N0YXRlID0gbmV3IEFycmF5PHN0cmluZz4odGhpcy5fbm9kZXMubGVuZ3RoKS5maWxsKCd3aGl0ZScpO1xuXG4gICAgd2hpbGUgKG5vZGVzU3RhY2subGVuZ3RoID4gMCkge1xuICAgICAgY29uc3Qgbm9kZUluZGV4ID0gbm9kZXNTdGFjay5wb3AoKSE7XG4gICAgICAvLyB0aGlzIG5vZGUgaGFzIG5vdyBiZWVuIHByb2Nlc3NlZCBjb21wbGV0ZWx5LiBNYXJrIHRoaXMgbm9kZSAnYmxhY2snIHRvIGRlbm90ZSB0aGlzLlxuICAgICAgaWYgKG5vZGVzU3RhdGVbbm9kZUluZGV4XSA9PT0gJ2dyYXknKSB7XG4gICAgICAgIG5vZGVzU3RhdGVbbm9kZUluZGV4XSA9ICdibGFjayc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyB0aGlzIG5vZGUgaXMgdW5kZXIgcHJvY2Vzc2luZyBzdGFnZS4gbWFyayB0aGlzIG5vZGUgJ2dyYXknIHRvIGRlbm90ZSB0aGlzLlxuICAgICAgICBub2Rlc1N0YWNrLnB1c2gobm9kZUluZGV4KTtcbiAgICAgICAgbm9kZXNTdGF0ZVtub2RlSW5kZXhdID0gJ2dyYXknO1xuXG4gICAgICAgIHRoaXMuX25vZGVzW25vZGVJbmRleF0ub3V0cHV0cy5mb3JFYWNoKChvdXRnb2luZ0VkZ2VJbmRleCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9hbGxEYXRhW291dGdvaW5nRWRnZUluZGV4XTtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudGVuc29yICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub2RlIG91dHB1dHMgc2hvdWxkIG5vdCBiZSBpbml0aWFsaXplZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZGF0YS5fZnJvbSAhPT0gbm9kZUluZGV4KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJmcm9tIHByb3BlcnR5IG9mIHRoZSBWYWx1ZSBvYmplY3QgZG9lc24ndCBtYXRjaCBpbmRleCBvZiBOb2RlIGJlaW5nIHByb2Nlc3NlZFwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGF0YS5fdG8uZm9yRWFjaCgoZG93bnN0cmVhbU5vZGVJbmRleCkgPT4ge1xuICAgICAgICAgICAgLy8gYmFjayBlZGdlIGZvdW5kIC0gY3ljbGljXG4gICAgICAgICAgICBpZiAobm9kZXNTdGF0ZVtkb3duc3RyZWFtTm9kZUluZGV4XSA9PT0gJ2dyYXknKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbW9kZWwgZ3JhcGggaXMgY3ljbGljJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyB0cmVlIGVkZ2UgZm91bmQgLSBjb250aW51ZSBwcm9jZXNzaW5nIGJ5IGFkZGluZyBpdCB0byBzdGFja1xuICAgICAgICAgICAgZWxzZSBpZiAobm9kZXNTdGF0ZVtkb3duc3RyZWFtTm9kZUluZGV4XSA9PT0gJ3doaXRlJykge1xuICAgICAgICAgICAgICBub2Rlc1N0YWNrLnB1c2goZG93bnN0cmVhbU5vZGVJbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdHJhbnNmb3JtR3JhcGgoZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKTogdm9pZCB7XG4gICAgLy8gYXBwbHkgY29tbW9uIHRyYW5zZm9ybVxuICAgIHRoaXMucmVtb3ZlQWxsSWRlbnRpdHlOb2RlcygpO1xuICAgIHRoaXMucmVtb3ZlQWxsRHJvcG91dE5vZGVzKCk7XG4gICAgdGhpcy5mdXNlQ29udkFjdGl2YXRpb25Ob2RlcygpO1xuICAgIC8vIGFwcGx5IGluaXRpYWxpemVyIHNwZWNpZmljIHRyYW5zZm9ybVxuICAgIGlmIChncmFwaEluaXRpYWxpemVyKSB7XG4gICAgICBncmFwaEluaXRpYWxpemVyLnRyYW5zZm9ybUdyYXBoKHRoaXMpO1xuICAgIH1cblxuICAgIC8vIGZpbmFsaXplIGdyYXBoXG4gICAgdGhpcy5maW5hbGl6ZUdyYXBoKCk7XG4gIH1cblxuICAvKipcbiAgICogZmluYWxpemUgdGhlIGdyYXBoLlxuICAgKlxuICAgKiB0aGlzIGZ1bmN0aW9uIHNob3VsZCBiZSBjYWxsZWQgYWZ0ZXIgYWxsIHRoZSB0cmFuc2Zvcm1hdGlvbiBjb21wbGV0ZWQuXG4gICAqIHRoaXMgZnVuY3Rpb24gcmVtb3ZlcyBhbGwgdW5uZWNlc3Nhcnkgbm9kZXMgYW5kIHZhbHVlcyBmcm9tIHRoZSBncmFwaFxuICAgKi9cbiAgZmluYWxpemVHcmFwaCgpIHtcbiAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICAvLyBkZWxldGUgYWxsIG5vZGVzIHRoYXQgYXJlIG5vdCBiZWluZyBleGVjdXRlZFxuICAgIC8vIFRoZSBncmFwaCBpcyByZXByZXNlbnRlZCB1c2luZyB0aGVzZSB0d28gYXJyYXlzXG4gICAgLy8gdGhpcy5fbm9kZXMgLSBBcnJheSBob2xkaW5nIHRoZSBrZXJuZWxzIHRvIGV4ZWN1dGUgLSBlYWNoIGVudHJ5IGlzIGEga2VybmVsIHBvaW50aW5nIHRvIHRoaXMuX2FsbERhdGFcbiAgICAvLyB0aGlzLl9hbGxEYXRhIC0gaG9sZCAyIGZpZWxkcyAtIHRvIFtdICYgZnJvbSAtIHRoZXNlIGZlaWxlZHMgaG9sZCB0aGUgZ3JhcGggbWFwIGZvciBpbnB1dHMgYW5kIG91dHB1dHMgcGVyIG5vZGVcbiAgICAvLyBuZXdJbmRpY2VzIC0gcmVtYXBwaW5nIHRoZSBncmFwaCBhZnRlciByZWFkaW5nIHRoZSBmbGFnICdleGVjdXRlTm9kZSdcbiAgICBjb25zdCBuZXdJbmRpY2VzID0gbmV3IEFycmF5PG51bWJlcj4odGhpcy5fbm9kZXMubGVuZ3RoLCAwKTtcbiAgICBsZXQgbm9kZVBvc3NpdGlvbiA9IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBnaXZpbmcgbmV3IGluZGV4ZXMgdG8gdGhlIG5vZGVzIGJhc2VkIG9uIGV4ZWN1dGlvbiBmbGFnXG4gICAgICBuZXdJbmRpY2VzW2ldID0gbm9kZVBvc3NpdGlvbjtcbiAgICAgIGlmICh0aGlzLl9ub2Rlc1tpXS5leGVjdXRlTm9kZSkge1xuICAgICAgICBpZiAobm9kZVBvc3NpdGlvbiAhPT0gaSkge1xuICAgICAgICAgIHRoaXMuX25vZGVzW25vZGVQb3NzaXRpb25dID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICAgIH1cbiAgICAgICAgbm9kZVBvc3NpdGlvbisrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZGVsZXRlIGFsbCBvdXRwdXQgdmFsdWVzXG4gICAgICAgIHRoaXMuX25vZGVzW2ldLm91dHB1dHMuZm9yRWFjaCgoaW5kKSA9PiB7XG4gICAgICAgICAgdGhpcy5fYWxsRGF0YVtpbmRdLl9mcm9tID0gLTI7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHJlbW92aW5nIHRoZSB1bnVzZWQgbm9kZXNcbiAgICB0aGlzLl9ub2Rlcy5zcGxpY2Uobm9kZVBvc3NpdGlvbiwgdGhpcy5fbm9kZXMubGVuZ3RoIC0gbm9kZVBvc3NpdGlvbik7XG5cbiAgICAvLyBVcGRhdGluZyB0aGlzLl9hbGxEYXRhIGFjY29yZGluZyB0byB0aGUgbmV3IHRoaXMuX25vZGVzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hbGxEYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBjdXJyZW50RGF0YSA9IHRoaXMuX2FsbERhdGFbaV07XG4gICAgICBpZiAoY3VycmVudERhdGEuX2Zyb20gIT09IHVuZGVmaW5lZCAmJiBjdXJyZW50RGF0YS5fZnJvbSAhPT0gLTEgJiYgY3VycmVudERhdGEuX2Zyb20gIT09IC0yKSB7XG4gICAgICAgIGN1cnJlbnREYXRhLl9mcm9tID0gbmV3SW5kaWNlc1tjdXJyZW50RGF0YS5fZnJvbV07XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY3VycmVudERhdGEuX3RvLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChjdXJyZW50RGF0YS5fdG9bal0gPj0gMCkge1xuICAgICAgICAgIGN1cnJlbnREYXRhLl90b1tqXSA9IG5ld0luZGljZXNbY3VycmVudERhdGEuX3RvW2pdXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyeWluZyB0byB1cGRhdGUgYSByZW1vdmVkIG5vZGUnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIG9mZnNldCA9IDA7XG4gICAgLy8gZGVsZXRlIGFsbCB2YWx1ZXMgdGhhdCBhcmUgbm90IGJlaW5nIHJlZmVyZW5jZWRcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2FsbERhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIC8vIGlmIGN1cnJlbnQgdmFsdWUgaXMgbmVpdGhlciBsaW5rZWQgdG8gbmV4dCBub2RlLCBub3IgYW4gb3V0cHV0IHZhbHVlLCByZW1vdmUgaXQuXG4gICAgICBpZiAodGhpcy5fYWxsRGF0YVtpXS5mcm9tID09PSAtMiAmJiB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLmluZGV4T2YoaSArIG9mZnNldCkgPT09IC0xKSB7XG4gICAgICAgIG9mZnNldCsrO1xuICAgICAgICB0aGlzLl9hbGxEYXRhLnNwbGljZShpLCAxKTtcbiAgICAgICAgaS0tO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChvZmZzZXQgPiAwKSB7XG4gICAgICAgIGxldCBpbmQgPSAtMTtcbiAgICAgICAgLy8gaWYgY3VycmVudCB2YWx1ZSBpcyBuZWl0aGVyIGFuIGlucHV0IHZhbHVlIG5vciBhbiBpbml0aWFsaXplciwgZmluZCB0aGUgbm9kZSBpdCdzXG4gICAgICAgIC8vIGNvbWluZyBmcm9tIGFuZCB1cGRhdGUgdGhlIGNvcnJlc3BvbmRpbmcgbm9kZSBvdXRwdXRcbiAgICAgICAgaWYgKHRoaXMuX2FsbERhdGFbaV0uZnJvbSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuX2FsbERhdGFbaV0uZnJvbSAhPT0gLTEpIHtcbiAgICAgICAgICBpbmQgPSB0aGlzLl9ub2Rlc1t0aGlzLl9hbGxEYXRhW2ldLmZyb21dLm91dHB1dHMuaW5kZXhPZihpICsgb2Zmc2V0KTtcbiAgICAgICAgICBpZiAoaW5kICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fbm9kZXNbdGhpcy5fYWxsRGF0YVtpXS5mcm9tXS5vdXRwdXRzW2luZF0gPSBpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBpZiBjdXJyZW50IHZhbHVlIGlzIGFuIGlucHV0IHZhbHVlLCB1cGRhdGUgaXRzIHJlZmVyZW5jZSBpbiBpbnB1dEluZGljZXNcbiAgICAgICAgICBpbmQgPSB0aGlzLl9hbGxJbnB1dEluZGljZXMuaW5kZXhPZihpICsgb2Zmc2V0KTtcbiAgICAgICAgICBpZiAoaW5kICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzW2luZF0gPSBpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZpbmQgdGhlIG5vZGUgdGhhdCB0aGUgY3VycmVudCB2YWx1ZSBpcyBsaW5raW5nIHRvIGFuZCB1cGRhdGUgaXRzIGlucHV0IHJlZmVyZW5jZVxuICAgICAgICB0aGlzLl9hbGxEYXRhW2ldLnRvLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgICAgICBpbmQgPSB0aGlzLl9ub2Rlc1tub2RlXS5pbnB1dHMuaW5kZXhPZihpICsgb2Zmc2V0KTtcbiAgICAgICAgICBpZiAoaW5kICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fbm9kZXNbbm9kZV0uaW5wdXRzW2luZF0gPSBpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2ldLnRvLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIC8vIGlmIGN1cnJlbnQgdmFsdWUgaXMgYSBncmFwaCBvdXRwdXQsIHVwZGF0ZSBpdHMgcmVmZXJlbmNlIGluIG91dHB1dEluZGljZXNcbiAgICAgICAgICBpbmQgPSB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLmluZGV4T2YoaSArIG9mZnNldCk7XG4gICAgICAgICAgaWYgKGluZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXNbaW5kXSA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSB0aGUgc3BlY2lmaWVkIG5vZGUuIEFzc3VtZSB0aGUgbm9kZSBoYXMgb25lIGluY29taW5nIGlucHV0IGFuZCB0aGUgZmlyc3Qgb3V0cHV0IGNvbm5lY3RlZCB0byBvdGhlciBub2Rlcy5cbiAgICogQW4gaW5wdXQgdmFsaWRhdGlvbiBtdXN0IGJlIGRvbmUgYmVmb3JlIGNhbGxpbmcgdGhpcyBmdW5jdGlvbi5cbiAgICogQHBhcmFtIG5vZGVJbmRleCBUaGUgaW5kZXggb2Ygbm9kZSB0byBiZSBkZWxldGVkXG4gICAqL1xuICBwcml2YXRlIGRlbGV0ZU5vZGUobm9kZUluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbbm9kZUluZGV4XTtcbiAgICBpZiAobm9kZS5vdXRwdXRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgbm9kZS5vdXRwdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW25vZGUub3V0cHV0c1tpXV0udG8ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm9kZSBkZWxldGlvbiB3aXRoIG1vcmUgdGhhbiBvbmUgb3V0cHV0IGNvbm5lY3RlZCB0byBvdGhlciBub2RlcyBpcyBub3Qgc3VwcG9ydGVkLiAnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHRoaXMgbm9kZSB3aWwgbm90IGJlIGV4ZWN1dGVkXG4gICAgbm9kZS5leGVjdXRlTm9kZSA9IGZhbHNlO1xuICAgIGNvbnN0IGlucHV0VmFsdWVJbmRleCA9IG5vZGUuaW5wdXRzWzBdO1xuICAgIGNvbnN0IG91dHB1dFZhbHVlSW5kZXggPSBub2RlLm91dHB1dHNbMF07XG4gICAgY29uc3Qgbm9kZXNDb25zdW1pbmdPdXRwdXQgPSB0aGlzLl9hbGxEYXRhW291dHB1dFZhbHVlSW5kZXhdLnRvO1xuXG4gICAgLy8gcmVtb3ZlIHRoaXMgbm9kZSBmcm9tIHRoZSB0byBwcm9wZXJ0eSBvZiB0aGUgaW5wdXQgVmFsdWVcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGUuaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBkZWxJbmRleCA9IHRoaXMuX2FsbERhdGFbbm9kZS5pbnB1dHNbaV1dLnRvLmluZGV4T2Yobm9kZUluZGV4KTtcbiAgICAgIC8vIHNob3VsZCBub3QgaGFwcGVuXG4gICAgICBpZiAoZGVsSW5kZXggPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBWYWx1ZSBvYmplY3QgZG9lc24ndCBoYXZlIHRoZSBjdXJyZW50IE5vZGUgaW4gaXQncyAndG8nIHByb3BlcnR5IFwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2FsbERhdGFbbm9kZS5pbnB1dHNbaV1dLnRvLnNwbGljZShkZWxJbmRleCwgMSk7XG4gICAgfVxuXG4gICAgLy8gY2xlYXIgbm9kZSBpbmRpY2VzIGNvbnN1bWluZyB0aGlzIG91dHB1dCBWYWx1ZVxuICAgIHRoaXMuX2FsbERhdGFbb3V0cHV0VmFsdWVJbmRleF0uX3RvID0gW107XG5cbiAgICAvLyBpZiB0aGUgb3V0cHV0IG9mIHRoaXMgbm9kZSBpcyBhIGdyYXBoIG91dHB1dCwgYWRqdXN0IHRoZSBpbmRleCBhcHByb3ByaWF0ZWx5XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLmluZGV4T2Yob3V0cHV0VmFsdWVJbmRleCk7XG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgdGhpcy5fYWxsT3V0cHV0SW5kaWNlc1tpbmRleF0gPSBpbnB1dFZhbHVlSW5kZXg7XG4gICAgfVxuXG4gICAgLy8gb3ZlcnJpZGUgdGhlIGlucHV0cyBmb3Igbm9kZXMgY29uc3VtaW5nIHRoaXMgbm9kZSdzIG91dHB1dCB3aXRoIHRoZSBpbnB1dCB0byB0aGlzIG5vZGVcbiAgICBpZiAobm9kZXNDb25zdW1pbmdPdXRwdXQgJiYgbm9kZXNDb25zdW1pbmdPdXRwdXQubGVuZ3RoID4gMCkge1xuICAgICAgZm9yIChjb25zdCBub2RlSW5kZXggb2Ygbm9kZXNDb25zdW1pbmdPdXRwdXQpIHtcbiAgICAgICAgY29uc3QgcmVwbGFjZUluZGV4ID0gdGhpcy5fbm9kZXNbbm9kZUluZGV4XS5pbnB1dHMuaW5kZXhPZihvdXRwdXRWYWx1ZUluZGV4KTtcbiAgICAgICAgLy8gc2hvdWxkIG5vdCBoYXBwZW5cbiAgICAgICAgaWYgKHJlcGxhY2VJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgTm9kZSBvYmplY3QgZG9lc24ndCBoYXZlIHRoZSBvdXRwdXQgVmFsdWUgaW4gaXQncyAnaW5wdXRzJyBwcm9wZXJ0eSBcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbm9kZXNbbm9kZUluZGV4XS5pbnB1dHNbcmVwbGFjZUluZGV4XSA9IGlucHV0VmFsdWVJbmRleDtcbiAgICAgICAgdGhpcy5fYWxsRGF0YVtpbnB1dFZhbHVlSW5kZXhdLnRvLnB1c2gobm9kZUluZGV4KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZW1vdmVBbGxEcm9wb3V0Tm9kZXMoKSB7XG4gICAgbGV0IG5vZGVJbmRleCA9IDA7XG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMuX25vZGVzKSB7XG4gICAgICAvLyB3ZWVkIG91dCAnRHJvcG91dCcgbm9kZXMgc28gdGhhdCBubyB0aW1lIGlzIHdhc3RlZCBpbiBleGVjdXRpb25cbiAgICAgIGlmIChub2RlLm9wVHlwZSA9PT0gJ0Ryb3BvdXQnKSB7XG4gICAgICAgIC8vIHRoZSBub2RlIHNob3VsZCBoYXZlIGV4YWN0bHkgMSBpbnB1dCBhbmQgMSBvciAyIG91dHB1dHNcbiAgICAgICAgaWYgKG5vZGUuaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRHJvcG91dCBub2RlcyBzaG91bGQgb25seSBjb250YWluIG9uZSBpbnB1dC4gJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5vZGUub3V0cHV0cy5sZW5ndGggIT09IDEgJiYgbm9kZS5vdXRwdXRzLmxlbmd0aCAhPT0gMikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRHJvcG91dCBub2RlcyBzaG91bGQgY29udGFpbiBlaXRoZXIgMSBvciAyIG91dHB1dChzKScpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRoZSBzZWNvbmQgb3V0cHV0IHNob3VsZCBub3QgYmUgcmVmZXJlbmNlZCBieSBhbnkgb3RoZXIgbm9kZVxuICAgICAgICBpZiAobm9kZS5vdXRwdXRzLmxlbmd0aCA9PT0gMiAmJiB0aGlzLl9hbGxEYXRhW25vZGUub3V0cHV0c1sxXV0uX3RvLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkRyb3BvdXQgbm9kZXMncyBzZWNvbmQgb3V0cHV0IHNob3VsZCBub3QgYmUgcmVmZXJlbmNlZCBieSBvdGhlciBub2Rlc1wiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlbGV0ZU5vZGUobm9kZUluZGV4KTtcbiAgICAgIH1cbiAgICAgIG5vZGVJbmRleCsrO1xuICAgIH1cbiAgfVxuXG4gIHJlbW92ZUFsbElkZW50aXR5Tm9kZXMoKSB7XG4gICAgbGV0IG5vZGVJbmRleCA9IDA7XG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMuX25vZGVzKSB7XG4gICAgICAvLyB3ZWVkIG91dCAnSWRlbnRpdHknIG5vZGVzIHNvIHRoYXQgbm8gdGltZSBpcyB3YXN0ZWQgaW4gZXhlY3V0aW9uXG4gICAgICBpZiAobm9kZS5vcFR5cGUgPT09ICdJZGVudGl0eScpIHtcbiAgICAgICAgdGhpcy5kZWxldGVOb2RlKG5vZGVJbmRleCk7XG4gICAgICB9XG4gICAgICBub2RlSW5kZXgrKztcbiAgICB9XG4gIH1cblxuICBpc0FjdGl2YXRpb24objogTm9kZSk6IGJvb2xlYW4ge1xuICAgIHN3aXRjaCAobi5vcFR5cGUpIHtcbiAgICAgIC8vIFRPRE86IGFkZCBvdGhlciBhY3RpdmF0aW9uIG1ldGhvZHNcbiAgICAgIGNhc2UgJ1JlbHUnOlxuICAgICAgY2FzZSAnU2lnbW9pZCc6XG4gICAgICBjYXNlICdDbGlwJzpcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgZnVzZUNvbnZBY3RpdmF0aW9uTm9kZXMoKSB7XG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMuX25vZGVzKSB7XG4gICAgICBpZiAobm9kZS5vcFR5cGUgPT09ICdDb252Jykge1xuICAgICAgICBjb25zdCBuZXh0ID0gdGhpcy5fYWxsRGF0YVtub2RlLm91dHB1dHNbMF1dLl90bztcbiAgICAgICAgaWYgKG5leHQubGVuZ3RoID09PSAxICYmIHRoaXMuaXNBY3RpdmF0aW9uKHRoaXMuX25vZGVzW25leHRbMF1dKSkge1xuICAgICAgICAgIGNvbnN0IGNoaWxkID0gdGhpcy5fbm9kZXNbbmV4dFswXV07XG4gICAgICAgICAgaWYgKGNoaWxkLm9wVHlwZSA9PT0gJ0NsaXAnKSB7XG4gICAgICAgICAgICBpZiAoY2hpbGQuaW5wdXRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5zZXQoJ2FjdGl2YXRpb25fcGFyYW1zJywgJ2Zsb2F0cycsIFtcbiAgICAgICAgICAgICAgICAgIGNoaWxkLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ21pbicpLFxuICAgICAgICAgICAgICAgICAgY2hpbGQuYXR0cmlidXRlcy5nZXRGbG9hdCgnbWF4JyksXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5zZXQoJ2FjdGl2YXRpb25fcGFyYW1zJywgJ2Zsb2F0cycsIFtNSU5fQ0xJUCwgTUFYX0NMSVBdKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgY2hpbGQuaW5wdXRzLmxlbmd0aCA+PSAzICYmXG4gICAgICAgICAgICAgIHRoaXMuX2FsbERhdGFbY2hpbGQuaW5wdXRzWzFdXS50ZW5zb3IgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICB0aGlzLl9hbGxEYXRhW2NoaWxkLmlucHV0c1syXV0udGVuc29yICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBub2RlLmF0dHJpYnV0ZXMuc2V0KCdhY3RpdmF0aW9uX3BhcmFtcycsICdmbG9hdHMnLCBbXG4gICAgICAgICAgICAgICAgdGhpcy5fYWxsRGF0YVtjaGlsZC5pbnB1dHNbMV1dLnRlbnNvciEuZmxvYXREYXRhWzBdLFxuICAgICAgICAgICAgICAgIHRoaXMuX2FsbERhdGFbY2hpbGQuaW5wdXRzWzJdXS50ZW5zb3IhLmZsb2F0RGF0YVswXSxcbiAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBTa2lwIGZ1c2lvbiB3aXRoIGNsaXAgbm9kZSBzaW5jZSBjbGlwIG1pbiBhbmQgY2xpcCBtYXggYXJlIG5vdCBjb21pbmcgZnJvbSBpbml0aWFsaXplclxuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgbm9kZS5hdHRyaWJ1dGVzLnNldCgnYWN0aXZhdGlvbicsICdzdHJpbmcnLCBjaGlsZC5vcFR5cGUpO1xuICAgICAgICAgIHRoaXMuZGVsZXRlTm9kZShuZXh0WzBdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQgeyBPcFNldCB9IGZyb20gJy4vb3BzZXQnO1xuaW1wb3J0ICogYXMgb3J0RmJzIGZyb20gJy4vb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkJztcbmltcG9ydCB7IG9ubnggfSBmcm9tICcuL29ydC1zY2hlbWEvcHJvdG9idWYvb25ueCc7XG5pbXBvcnQgeyBMb25nVXRpbCB9IGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBjbGFzcyBNb2RlbCB7XG4gIC8vIGVtcHR5IG1vZGVsXG4gIGNvbnN0cnVjdG9yKCkge31cblxuICBsb2FkKGJ1ZjogVWludDhBcnJheSwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyLCBpc09ydEZvcm1hdD86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBsZXQgb25ueEVycm9yOiBFcnJvciB8IHVuZGVmaW5lZDtcbiAgICBpZiAoIWlzT3J0Rm9ybWF0KSB7XG4gICAgICAvLyBpc09ydEZvcm1hdCA9PT0gZmFsc2UgfHwgaXNPcnRGb3JtYXQgPT09IHVuZGVmaW5lZFxuICAgICAgdHJ5IHtcbiAgICAgICAgdGhpcy5sb2FkRnJvbU9ubnhGb3JtYXQoYnVmLCBncmFwaEluaXRpYWxpemVyKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoaXNPcnRGb3JtYXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgICAgb25ueEVycm9yID0gZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5sb2FkRnJvbU9ydEZvcm1hdChidWYsIGdyYXBoSW5pdGlhbGl6ZXIpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChpc09ydEZvcm1hdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgICAvLyBUcmllZCBib3RoIGZvcm1hdHMgYW5kIGZhaWxlZCAod2hlbiBpc09ydEZvcm1hdCA9PT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gbG9hZCBtb2RlbCBhcyBPTk5YIGZvcm1hdDogJHtvbm54RXJyb3J9XFxuYXMgT1JUIGZvcm1hdDogJHtlfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbG9hZEZyb21Pbm54Rm9ybWF0KGJ1ZjogVWludDhBcnJheSwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKTogdm9pZCB7XG4gICAgY29uc3QgbW9kZWxQcm90byA9IG9ubnguTW9kZWxQcm90by5kZWNvZGUoYnVmKTtcbiAgICBjb25zdCBpclZlcnNpb24gPSBMb25nVXRpbC5sb25nVG9OdW1iZXIobW9kZWxQcm90by5pclZlcnNpb24pO1xuICAgIGlmIChpclZlcnNpb24gPCAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29ubHkgc3VwcG9ydCBPTk5YIG1vZGVsIHdpdGggSVJfVkVSU0lPTj49MycpO1xuICAgIH1cblxuICAgIHRoaXMuX29wc2V0cyA9IG1vZGVsUHJvdG8ub3BzZXRJbXBvcnQubWFwKChpKSA9PiAoe1xuICAgICAgZG9tYWluOiBpLmRvbWFpbiBhcyBzdHJpbmcsXG4gICAgICB2ZXJzaW9uOiBMb25nVXRpbC5sb25nVG9OdW1iZXIoaS52ZXJzaW9uISksXG4gICAgfSkpO1xuXG4gICAgdGhpcy5fZ3JhcGggPSBHcmFwaC5mcm9tKG1vZGVsUHJvdG8uZ3JhcGghLCBncmFwaEluaXRpYWxpemVyKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEZyb21PcnRGb3JtYXQoYnVmOiBVaW50OEFycmF5LCBncmFwaEluaXRpYWxpemVyPzogR3JhcGguSW5pdGlhbGl6ZXIpOiB2b2lkIHtcbiAgICBjb25zdCBmYiA9IG5ldyBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKGJ1Zik7XG4gICAgY29uc3Qgb3J0TW9kZWwgPSBvcnRGYnMuSW5mZXJlbmNlU2Vzc2lvbi5nZXRSb290QXNJbmZlcmVuY2VTZXNzaW9uKGZiKS5tb2RlbCgpITtcbiAgICBjb25zdCBpclZlcnNpb24gPSBMb25nVXRpbC5sb25nVG9OdW1iZXIob3J0TW9kZWwuaXJWZXJzaW9uKCkpO1xuICAgIGlmIChpclZlcnNpb24gPCAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29ubHkgc3VwcG9ydCBPTk5YIG1vZGVsIHdpdGggSVJfVkVSU0lPTj49MycpO1xuICAgIH1cbiAgICB0aGlzLl9vcHNldHMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9ydE1vZGVsLm9wc2V0SW1wb3J0TGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3Qgb3BzZXRJZCA9IG9ydE1vZGVsLm9wc2V0SW1wb3J0KGkpITtcbiAgICAgIHRoaXMuX29wc2V0cy5wdXNoKHsgZG9tYWluOiBvcHNldElkPy5kb21haW4oKSBhcyBzdHJpbmcsIHZlcnNpb246IExvbmdVdGlsLmxvbmdUb051bWJlcihvcHNldElkLnZlcnNpb24oKSEpIH0pO1xuICAgIH1cblxuICAgIHRoaXMuX2dyYXBoID0gR3JhcGguZnJvbShvcnRNb2RlbC5ncmFwaCgpISwgZ3JhcGhJbml0aWFsaXplcik7XG4gIH1cblxuICBwcml2YXRlIF9ncmFwaDogR3JhcGg7XG4gIGdldCBncmFwaCgpOiBHcmFwaCB7XG4gICAgcmV0dXJuIHRoaXMuX2dyYXBoO1xuICB9XG5cbiAgcHJpdmF0ZSBfb3BzZXRzOiBPcFNldFtdO1xuICBnZXQgb3BzZXRzKCk6IHJlYWRvbmx5IE9wU2V0W10ge1xuICAgIHJldHVybiB0aGlzLl9vcHNldHM7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgcmVzb2x2ZUJhY2tlbmQsIFNlc3Npb25IYW5kbGVyVHlwZSB9IGZyb20gJy4vYmFja2VuZCc7XG5pbXBvcnQgeyBFeGVjdXRpb25QbGFuIH0gZnJvbSAnLi9leGVjdXRpb24tcGxhbic7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHsgUHJvZmlsZXIgfSBmcm9tICcuL2luc3RydW1lbnQnO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tICcuL21vZGVsJztcbmltcG9ydCB7IE9wZXJhdG9yIH0gZnJvbSAnLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgU2Vzc2lvbiB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnIHtcbiAgICBiYWNrZW5kSGludD86IHN0cmluZztcbiAgICBwcm9maWxlcj86IFByb2ZpbGVyLkNvbmZpZztcbiAgfVxuXG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29udGV4dCB7XG4gICAgcHJvZmlsZXI6IFJlYWRvbmx5PFByb2ZpbGVyPjtcbiAgICBncmFwaElucHV0VHlwZXM/OiBUZW5zb3IuRGF0YVR5cGVbXTtcbiAgICBncmFwaElucHV0RGltcz86IEFycmF5PHJlYWRvbmx5IG51bWJlcltdPjtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogU2Vzc2lvbi5Db25maWcgPSB7fSkge1xuICAgIHRoaXMuX2luaXRpYWxpemVkID0gZmFsc2U7XG4gICAgdGhpcy5iYWNrZW5kSGludCA9IGNvbmZpZy5iYWNrZW5kSGludDtcbiAgICB0aGlzLnByb2ZpbGVyID0gUHJvZmlsZXIuY3JlYXRlKGNvbmZpZy5wcm9maWxlcik7XG4gICAgdGhpcy5jb250ZXh0ID0geyBwcm9maWxlcjogdGhpcy5wcm9maWxlciwgZ3JhcGhJbnB1dFR5cGVzOiBbXSwgZ3JhcGhJbnB1dERpbXM6IFtdIH07XG4gIH1cblxuICBnZXQgaW5wdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuX21vZGVsLmdyYXBoLmdldElucHV0TmFtZXMoKTtcbiAgfVxuICBnZXQgb3V0cHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9tb2RlbC5ncmFwaC5nZXRPdXRwdXROYW1lcygpO1xuICB9XG5cbiAgc3RhcnRQcm9maWxpbmcoKSB7XG4gICAgdGhpcy5wcm9maWxlci5zdGFydCgpO1xuICB9XG5cbiAgZW5kUHJvZmlsaW5nKCkge1xuICAgIHRoaXMucHJvZmlsZXIuc3RvcCgpO1xuICB9XG5cbiAgYXN5bmMgbG9hZE1vZGVsKHVyaTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPjtcbiAgYXN5bmMgbG9hZE1vZGVsKGJ1ZmZlcjogQXJyYXlCdWZmZXIsIGJ5dGVPZmZzZXQ/OiBudW1iZXIsIGxlbmd0aD86IG51bWJlcik6IFByb21pc2U8dm9pZD47XG4gIGFzeW5jIGxvYWRNb2RlbChidWZmZXI6IFVpbnQ4QXJyYXkpOiBQcm9taXNlPHZvaWQ+O1xuICBhc3luYyBsb2FkTW9kZWwoYXJnOiBzdHJpbmcgfCBBcnJheUJ1ZmZlciB8IFVpbnQ4QXJyYXksIGJ5dGVPZmZzZXQ/OiBudW1iZXIsIGxlbmd0aD86IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMucHJvZmlsZXIuZXZlbnQoJ3Nlc3Npb24nLCAnU2Vzc2lvbi5sb2FkTW9kZWwnLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyByZXNvbHZlIGJhY2tlbmQgYW5kIHNlc3Npb24gaGFuZGxlclxuICAgICAgY29uc3QgYmFja2VuZCA9IGF3YWl0IHJlc29sdmVCYWNrZW5kKHRoaXMuYmFja2VuZEhpbnQpO1xuICAgICAgdGhpcy5zZXNzaW9uSGFuZGxlciA9IGJhY2tlbmQuY3JlYXRlU2Vzc2lvbkhhbmRsZXIodGhpcy5jb250ZXh0KTtcblxuICAgICAgdGhpcy5fbW9kZWwgPSBuZXcgTW9kZWwoKTtcbiAgICAgIGlmICh0eXBlb2YgYXJnID09PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zdCBpc09ydEZvcm1hdCA9IGFyZy5lbmRzV2l0aCgnLm9ydCcpO1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHByb2Nlc3MudmVyc2lvbnMgJiYgcHJvY2Vzcy52ZXJzaW9ucy5ub2RlKSB7XG4gICAgICAgICAgLy8gbm9kZVxuICAgICAgICAgIGNvbnN0IHsgcmVhZEZpbGUgfSA9IHJlcXVpcmUoJ25vZGU6ZnMvcHJvbWlzZXMnKTtcbiAgICAgICAgICBjb25zdCBidWYgPSBhd2FpdCByZWFkRmlsZShhcmcpO1xuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZShidWYsIGlzT3J0Rm9ybWF0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBicm93c2VyXG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChhcmcpO1xuICAgICAgICAgIGNvbnN0IGJ1ZiA9IGF3YWl0IHJlc3BvbnNlLmFycmF5QnVmZmVyKCk7XG4gICAgICAgICAgdGhpcy5pbml0aWFsaXplKG5ldyBVaW50OEFycmF5KGJ1ZiksIGlzT3J0Rm9ybWF0KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghQXJyYXlCdWZmZXIuaXNWaWV3KGFyZykpIHtcbiAgICAgICAgLy8gbG9hZCBtb2RlbCBmcm9tIEFycmF5QnVmZmVyXG4gICAgICAgIGNvbnN0IGFyciA9IG5ldyBVaW50OEFycmF5KGFyZywgYnl0ZU9mZnNldCB8fCAwLCBsZW5ndGggfHwgYXJnLmJ5dGVMZW5ndGgpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemUoYXJyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGxvYWQgbW9kZWwgZnJvbSBVaW50OGFycmF5XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZShhcmcpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplKG1vZGVsUHJvdG9CbG9iOiBVaW50OEFycmF5LCBpc09ydEZvcm1hdD86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5faW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYWxyZWFkeSBpbml0aWFsaXplZCcpO1xuICAgIH1cblxuICAgIHRoaXMucHJvZmlsZXIuZXZlbnQoJ3Nlc3Npb24nLCAnU2Vzc2lvbi5pbml0aWFsaXplJywgKCkgPT4ge1xuICAgICAgLy8gbG9hZCBncmFwaFxuICAgICAgY29uc3QgZ3JhcGhJbml0aWFsaXplciA9IHRoaXMuc2Vzc2lvbkhhbmRsZXIudHJhbnNmb3JtR3JhcGhcbiAgICAgICAgPyAodGhpcy5zZXNzaW9uSGFuZGxlciBhcyBHcmFwaC5Jbml0aWFsaXplcilcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICB0aGlzLl9tb2RlbC5sb2FkKG1vZGVsUHJvdG9CbG9iLCBncmFwaEluaXRpYWxpemVyLCBpc09ydEZvcm1hdCk7XG5cbiAgICAgIC8vIGdyYXBoIGlzIGNvbXBsZXRlbHkgaW5pdGlhbHppZWQgYXQgdGhpcyBzdGFnZSAsIGxldCB0aGUgaW50ZXJlc3RlZCBoYW5kbGVycyBrbm93XG4gICAgICBpZiAodGhpcy5zZXNzaW9uSGFuZGxlci5vbkdyYXBoSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uSGFuZGxlci5vbkdyYXBoSW5pdGlhbGl6ZWQodGhpcy5fbW9kZWwuZ3JhcGgpO1xuICAgICAgfVxuICAgICAgLy8gaW5pdGlhbGl6ZSBlYWNoIG9wZXJhdG9yIGluIHRoZSBncmFwaFxuICAgICAgdGhpcy5pbml0aWFsaXplT3BzKHRoaXMuX21vZGVsLmdyYXBoKTtcblxuICAgICAgLy8gaW5zdGFudGlhdGUgYW4gRXhlY3V0aW9uUGxhbiBvYmplY3QgdG8gYmUgdXNlZCBieSB0aGUgU2Vzc2lvbiBvYmplY3RcbiAgICAgIHRoaXMuX2V4ZWN1dGlvblBsYW4gPSBuZXcgRXhlY3V0aW9uUGxhbih0aGlzLl9tb2RlbC5ncmFwaCwgdGhpcy5fb3BzLCB0aGlzLnByb2ZpbGVyKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX2luaXRpYWxpemVkID0gdHJ1ZTtcbiAgfVxuXG4gIGFzeW5jIHJ1bihpbnB1dHM6IE1hcDxzdHJpbmcsIFRlbnNvcj4gfCBUZW5zb3JbXSk6IFByb21pc2U8TWFwPHN0cmluZywgVGVuc29yPj4ge1xuICAgIGlmICghdGhpcy5faW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc2Vzc2lvbiBub3QgaW5pdGlhbGl6ZWQgeWV0Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ3Nlc3Npb24nLCAnU2Vzc2lvbi5ydW4nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBpbnB1dFRlbnNvcnMgPSB0aGlzLm5vcm1hbGl6ZUFuZFZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgICAgIGNvbnN0IG91dHB1dFRlbnNvcnMgPSBhd2FpdCB0aGlzLl9leGVjdXRpb25QbGFuLmV4ZWN1dGUodGhpcy5zZXNzaW9uSGFuZGxlciwgaW5wdXRUZW5zb3JzKTtcblxuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlT3V0cHV0KG91dHB1dFRlbnNvcnMpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBub3JtYWxpemVBbmRWYWxpZGF0ZUlucHV0cyhpbnB1dHM6IE1hcDxzdHJpbmcsIFRlbnNvcj4gfCBUZW5zb3JbXSk6IFRlbnNvcltdIHtcbiAgICBjb25zdCBtb2RlbElucHV0TmFtZXMgPSB0aGlzLl9tb2RlbC5ncmFwaC5nZXRJbnB1dE5hbWVzKCk7XG5cbiAgICAvLyBub3JtYWxpemUgaW5wdXRzXG4gICAgLy8gaW5wdXRzOiBUZW5zb3JbXVxuICAgIGlmIChBcnJheS5pc0FycmF5KGlucHV0cykpIHtcbiAgICAgIGlmIChpbnB1dHMubGVuZ3RoICE9PSBtb2RlbElucHV0TmFtZXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW5jb3JyZWN0IGlucHV0IGFycmF5IGxlbmd0aDogZXhwZWN0ZWQgJHttb2RlbElucHV0TmFtZXMubGVuZ3RofSBidXQgZ290ICR7aW5wdXRzLmxlbmd0aH1gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gY29udmVydCBtYXAgdG8gYXJyYXlcbiAgICAvLyBpbnB1dHM6IE1hcDxzdHJpbmcsIFRlbnNvcj5cbiAgICBlbHNlIHtcbiAgICAgIGlmIChpbnB1dHMuc2l6ZSAhPT0gbW9kZWxJbnB1dE5hbWVzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGluY29ycmVjdCBpbnB1dCBtYXAgc2l6ZTogZXhwZWN0ZWQgJHttb2RlbElucHV0TmFtZXMubGVuZ3RofSBidXQgZ290ICR7aW5wdXRzLnNpemV9YCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNvcnRlZElucHV0cyA9IG5ldyBBcnJheTxUZW5zb3I+KGlucHV0cy5zaXplKTtcbiAgICAgIGxldCBzb3J0ZWRJbnB1dHNJbmRleCA9IDA7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1vZGVsSW5wdXROYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICBjb25zdCB0ZW5zb3IgPSBpbnB1dHMuZ2V0KG1vZGVsSW5wdXROYW1lc1tpXSk7XG4gICAgICAgIGlmICghdGVuc29yKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIGlucHV0IHRlbnNvciBmb3I6ICcke25hbWV9J2ApO1xuICAgICAgICB9XG4gICAgICAgIHNvcnRlZElucHV0c1tzb3J0ZWRJbnB1dHNJbmRleCsrXSA9IHRlbnNvcjtcbiAgICAgIH1cblxuICAgICAgaW5wdXRzID0gc29ydGVkSW5wdXRzO1xuICAgIH1cblxuICAgIC8vIHZhbGlkYXRlIGRpbXMgcmVxdWlyZW1lbnRzXG4gICAgLy8gRmlyc3Qgc2Vzc2lvbiBydW4gLSBncmFwaCBpbnB1dCBkYXRhIGlzIG5vdCBjYWNoZWQgZm9yIHRoZSBzZXNzaW9uXG4gICAgaWYgKFxuICAgICAgIXRoaXMuY29udGV4dC5ncmFwaElucHV0VHlwZXMgfHxcbiAgICAgIHRoaXMuY29udGV4dC5ncmFwaElucHV0VHlwZXMubGVuZ3RoID09PSAwIHx8XG4gICAgICAhdGhpcy5jb250ZXh0LmdyYXBoSW5wdXREaW1zIHx8XG4gICAgICB0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dERpbXMubGVuZ3RoID09PSAwXG4gICAgKSB7XG4gICAgICBjb25zdCBtb2RlbElucHV0SW5kaWNlcyA9IHRoaXMuX21vZGVsLmdyYXBoLmdldElucHV0SW5kaWNlcygpO1xuICAgICAgY29uc3QgbW9kZWxWYWx1ZXMgPSB0aGlzLl9tb2RlbC5ncmFwaC5nZXRWYWx1ZXMoKTtcblxuICAgICAgY29uc3QgZ3JhcGhJbnB1dERpbXMgPSBuZXcgQXJyYXk8cmVhZG9ubHkgbnVtYmVyW10+KG1vZGVsSW5wdXRJbmRpY2VzLmxlbmd0aCk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbW9kZWxJbnB1dEluZGljZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgY29uc3QgZ3JhcGhJbnB1dCA9IG1vZGVsVmFsdWVzW21vZGVsSW5wdXRJbmRpY2VzW2ldXTtcbiAgICAgICAgZ3JhcGhJbnB1dERpbXNbaV0gPSBncmFwaElucHV0LnR5cGUhLnNoYXBlLmRpbXM7XG5cbiAgICAgICAgLy8gY2FjaGVkIGZvciBzZWNvbmQgYW5kIHN1YnNlcXVlbnQgcnVucy5cbiAgICAgICAgLy8gU29tZSBwYXJ0cyBvZiB0aGUgZnJhbWV3b3JrIHdvcmtzIG9uIHRoZSBhc3N1bXB0aW9uIHRoYXQgdGhlIGdyYXBoIGFuZCB0eXBlcyBhbmQgc2hhcGVzIGFyZSBzdGF0aWNcbiAgICAgICAgdGhpcy5jb250ZXh0LmdyYXBoSW5wdXRUeXBlcyEucHVzaChncmFwaElucHV0LnR5cGUhLnRlbnNvclR5cGUpO1xuICAgICAgICB0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dERpbXMhLnB1c2goaW5wdXRzW2ldLmRpbXMpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnZhbGlkYXRlSW5wdXRUZW5zb3JEaW1zKGdyYXBoSW5wdXREaW1zLCBpbnB1dHMsIHRydWUpO1xuICAgIH1cblxuICAgIC8vIFNlY29uZCBhbmQgc3Vic2VxdWVudCBzZXNzaW9uIHJ1bnMgLSBncmFwaCBpbnB1dCBkYXRhIGlzIGNhY2hlZCBmb3IgdGhlIHNlc3Npb25cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMudmFsaWRhdGVJbnB1dFRlbnNvckRpbXModGhpcy5jb250ZXh0LmdyYXBoSW5wdXREaW1zLCBpbnB1dHMsIGZhbHNlKTtcbiAgICB9XG5cbiAgICAvLyB2YWxpZGF0ZSB0eXBlcyByZXF1aXJlbWVudFxuICAgIHRoaXMudmFsaWRhdGVJbnB1dFRlbnNvclR5cGVzKHRoaXMuY29udGV4dC5ncmFwaElucHV0VHlwZXMhLCBpbnB1dHMpO1xuXG4gICAgcmV0dXJuIGlucHV0cztcbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVJbnB1dFRlbnNvclR5cGVzKGdyYXBoSW5wdXRUeXBlczogVGVuc29yLkRhdGFUeXBlW10sIGdpdmVuSW5wdXRzOiBUZW5zb3JbXSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ2l2ZW5JbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IGdyYXBoSW5wdXRUeXBlc1tpXTtcbiAgICAgIGNvbnN0IGFjdHVhbFR5cGUgPSBnaXZlbklucHV0c1tpXS50eXBlO1xuICAgICAgaWYgKGV4cGVjdGVkVHlwZSAhPT0gYWN0dWFsVHlwZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0IHRlbnNvclske2l9XSBjaGVjayBmYWlsZWQ6IGV4cGVjdGVkIHR5cGUgJyR7ZXhwZWN0ZWRUeXBlfScgYnV0IGdvdCAke2FjdHVhbFR5cGV9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUlucHV0VGVuc29yRGltcyhcbiAgICBncmFwaElucHV0RGltczogQXJyYXk8cmVhZG9ubHkgbnVtYmVyW10+LFxuICAgIGdpdmVuSW5wdXRzOiBUZW5zb3JbXSxcbiAgICBub25lRGltU3VwcG9ydGVkOiBib29sZWFuLFxuICApIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdpdmVuSW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBleHBlY3RlZERpbXMgPSBncmFwaElucHV0RGltc1tpXTtcbiAgICAgIGNvbnN0IGFjdHVhbERpbXMgPSBnaXZlbklucHV0c1tpXS5kaW1zO1xuICAgICAgaWYgKCF0aGlzLmNvbXBhcmVUZW5zb3JEaW1zKGV4cGVjdGVkRGltcywgYWN0dWFsRGltcywgbm9uZURpbVN1cHBvcnRlZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBpbnB1dCB0ZW5zb3JbJHtpfV0gY2hlY2sgZmFpbGVkOiBleHBlY3RlZCBzaGFwZSAnWyR7ZXhwZWN0ZWREaW1zLmpvaW4oJywnKX1dJyBidXQgZ290IFske2FjdHVhbERpbXMuam9pbihcbiAgICAgICAgICAgICcsJyxcbiAgICAgICAgICApfV1gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY29tcGFyZVRlbnNvckRpbXMoXG4gICAgZXhwZWN0ZWREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBhY3R1YWxEaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBub25lRGltU3VwcG9ydGVkOiBib29sZWFuLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoZXhwZWN0ZWREaW1zLmxlbmd0aCAhPT0gYWN0dWFsRGltcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkRGltcy5sZW5ndGg7ICsraSkge1xuICAgICAgaWYgKGV4cGVjdGVkRGltc1tpXSAhPT0gYWN0dWFsRGltc1tpXSAmJiAoIW5vbmVEaW1TdXBwb3J0ZWQgfHwgZXhwZWN0ZWREaW1zW2ldICE9PSAwKSkge1xuICAgICAgICAvLyBkYXRhIHNoYXBlIG1pc21hdGNoIEFORCBub3QgYSAnTm9uZScgZGltZW5zaW9uLlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZU91dHB1dChvdXRwdXRUZW5zb3JzOiBUZW5zb3JbXSk6IE1hcDxzdHJpbmcsIFRlbnNvcj4ge1xuICAgIGNvbnN0IG1vZGVsT3V0cHV0TmFtZXMgPSB0aGlzLl9tb2RlbC5ncmFwaC5nZXRPdXRwdXROYW1lcygpO1xuICAgIGlmIChvdXRwdXRUZW5zb3JzLmxlbmd0aCAhPT0gbW9kZWxPdXRwdXROYW1lcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZXhwZWN0ZWQgbnVtYmVyIG9mIG91dHB1dHMgZG8gbm90IG1hdGNoIG51bWJlciBvZiBnZW5lcmF0ZWQgb3V0cHV0cycpO1xuICAgIH1cblxuICAgIGNvbnN0IG91dHB1dCA9IG5ldyBNYXA8c3RyaW5nLCBUZW5zb3I+KCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtb2RlbE91dHB1dE5hbWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICBvdXRwdXQuc2V0KG1vZGVsT3V0cHV0TmFtZXNbaV0sIG91dHB1dFRlbnNvcnNbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVPcHMoZ3JhcGg6IEdyYXBoKTogdm9pZCB7XG4gICAgY29uc3Qgbm9kZXMgPSBncmFwaC5nZXROb2RlcygpO1xuICAgIHRoaXMuX29wcyA9IG5ldyBBcnJheShub2Rlcy5sZW5ndGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5fb3BzW2ldID0gdGhpcy5zZXNzaW9uSGFuZGxlci5yZXNvbHZlKG5vZGVzW2ldLCB0aGlzLl9tb2RlbC5vcHNldHMsIGdyYXBoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9tb2RlbDogTW9kZWw7XG4gIHByaXZhdGUgX2luaXRpYWxpemVkOiBib29sZWFuO1xuXG4gIHByaXZhdGUgX29wczogT3BlcmF0b3JbXTtcbiAgcHJpdmF0ZSBfZXhlY3V0aW9uUGxhbjogRXhlY3V0aW9uUGxhbjtcblxuICBwcml2YXRlIGJhY2tlbmRIaW50Pzogc3RyaW5nO1xuXG4gIHByaXZhdGUgc2Vzc2lvbkhhbmRsZXI6IFNlc3Npb25IYW5kbGVyVHlwZTtcbiAgcHJpdmF0ZSBjb250ZXh0OiBTZXNzaW9uLkNvbnRleHQ7XG4gIHByaXZhdGUgcHJvZmlsZXI6IFJlYWRvbmx5PFByb2ZpbGVyPjtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbiwgSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIsIFNlc3Npb25IYW5kbGVyLCBUZW5zb3IgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9zZXNzaW9uJztcbmltcG9ydCB7IFRlbnNvciBhcyBPbm54anNUZW5zb3IgfSBmcm9tICcuL3RlbnNvcic7XG5cbmV4cG9ydCBjbGFzcyBPbm54anNTZXNzaW9uSGFuZGxlciBpbXBsZW1lbnRzIEluZmVyZW5jZVNlc3Npb25IYW5kbGVyIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzZXNzaW9uOiBTZXNzaW9uKSB7XG4gICAgdGhpcy5pbnB1dE5hbWVzID0gdGhpcy5zZXNzaW9uLmlucHV0TmFtZXM7XG4gICAgdGhpcy5vdXRwdXROYW1lcyA9IHRoaXMuc2Vzc2lvbi5vdXRwdXROYW1lcztcbiAgfVxuXG4gIGdldCBpbnB1dE1ldGFkYXRhKCk6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb24uVmFsdWVNZXRhZGF0YVtdIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dldHRpbmcgbW9kZWwgbWV0YWRhdGEgaXMgbm90IHN1cHBvcnRlZCBpbiB3ZWJnbCBiYWNrZW5kLicpO1xuICB9XG5cbiAgZ2V0IG91dHB1dE1ldGFkYXRhKCk6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb24uVmFsdWVNZXRhZGF0YVtdIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dldHRpbmcgbW9kZWwgbWV0YWRhdGEgaXMgbm90IHN1cHBvcnRlZCBpbiB3ZWJnbCBiYWNrZW5kLicpO1xuICB9XG5cbiAgYXN5bmMgZGlzcG9zZSgpOiBQcm9taXNlPHZvaWQ+IHt9XG4gIGlucHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICBvdXRwdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG4gIGFzeW5jIHJ1bihcbiAgICBmZWVkczogU2Vzc2lvbkhhbmRsZXIuRmVlZHNUeXBlLFxuICAgIF9mZXRjaGVzOiBTZXNzaW9uSGFuZGxlci5GZXRjaGVzVHlwZSxcbiAgICBfb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zLFxuICApOiBQcm9taXNlPFNlc3Npb25IYW5kbGVyLlJldHVyblR5cGU+IHtcbiAgICBjb25zdCBpbnB1dE1hcCA9IG5ldyBNYXA8c3RyaW5nLCBPbm54anNUZW5zb3I+KCk7XG4gICAgZm9yIChjb25zdCBuYW1lIGluIGZlZWRzKSB7XG4gICAgICBpZiAoT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwoZmVlZHMsIG5hbWUpKSB7XG4gICAgICAgIGNvbnN0IGZlZWQgPSBmZWVkc1tuYW1lXTtcbiAgICAgICAgaW5wdXRNYXAuc2V0KFxuICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgbmV3IE9ubnhqc1RlbnNvcihcbiAgICAgICAgICAgIGZlZWQuZGltcyxcbiAgICAgICAgICAgIGZlZWQudHlwZSBhcyBPbm54anNUZW5zb3IuRGF0YVR5cGUsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICBmZWVkLmRhdGEgYXMgT25ueGpzVGVuc29yLk51bWJlclR5cGUsXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3Qgb3V0cHV0TWFwID0gYXdhaXQgdGhpcy5zZXNzaW9uLnJ1bihpbnB1dE1hcCk7XG4gICAgY29uc3Qgb3V0cHV0OiBTZXNzaW9uSGFuZGxlci5SZXR1cm5UeXBlID0ge307XG4gICAgb3V0cHV0TWFwLmZvckVhY2goKHRlbnNvciwgbmFtZSkgPT4ge1xuICAgICAgb3V0cHV0W25hbWVdID0gbmV3IFRlbnNvcih0ZW5zb3IudHlwZSwgdGVuc29yLmRhdGEsIHRlbnNvci5kaW1zKTtcbiAgICB9KTtcbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG4gIHN0YXJ0UHJvZmlsaW5nKCk6IHZvaWQge1xuICAgIHRoaXMuc2Vzc2lvbi5zdGFydFByb2ZpbGluZygpO1xuICB9XG4gIGVuZFByb2ZpbGluZygpOiB2b2lkIHtcbiAgICB0aGlzLnNlc3Npb24uZW5kUHJvZmlsaW5nKCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQmFja2VuZCwgSW5mZXJlbmNlU2Vzc2lvbiwgSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9vbm54anMvc2Vzc2lvbic7XG5pbXBvcnQgeyBPbm54anNTZXNzaW9uSGFuZGxlciB9IGZyb20gJy4vb25ueGpzL3Nlc3Npb24taGFuZGxlci1pbmZlcmVuY2UnO1xuXG5jbGFzcyBPbm54anNCYWNrZW5kIGltcGxlbWVudHMgQmFja2VuZCB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktZnVuY3Rpb25cbiAgYXN5bmMgaW5pdCgpOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgYXN5bmMgY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIoXG4gICAgcGF0aE9yQnVmZmVyOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25IYW5kbGVyPiB7XG4gICAgLy8gTk9URTogU2Vzc2lvbi5Db25maWcoZnJvbSBvbm54LmpzKSBpcyBub3QgY29tcGF0aWJsZSB3aXRoIEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMoZnJvbVxuICAgIC8vIG9ubnhydW50aW1lLWNvbW1vbikuXG4gICAgLy8gICAgICAgSW4gZnV0dXJlIHdlIHNob3VsZCByZW1vdmUgU2Vzc2lvbi5Db25maWcgYW5kIHVzZSBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLlxuICAgIC8vICAgICAgIEN1cnJlbnRseSB3ZSBhbGxvdyB0aGlzIHRvIGhhcHBlbiB0byBtYWtlIHRlc3QgcnVubmVyIHdvcmsuXG4gICAgY29uc3Qgc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKG9wdGlvbnMgYXMgdW5rbm93biBhcyBTZXNzaW9uLkNvbmZpZyk7XG5cbiAgICAvLyB0eXBlc2NyaXB0IGNhbm5vdCBtZXJnZSBtZXRob2Qgb3ZlcnJpZGUgY29ycmVjdGx5IChzbyBmYXIgaW4gNC4yLjMpLiBuZWVkIGlmLWVsc2UgdG8gY2FsbCB0aGUgbWV0aG9kLlxuICAgIGlmICh0eXBlb2YgcGF0aE9yQnVmZmVyID09PSAnc3RyaW5nJykge1xuICAgICAgYXdhaXQgc2Vzc2lvbi5sb2FkTW9kZWwocGF0aE9yQnVmZmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgc2Vzc2lvbi5sb2FkTW9kZWwocGF0aE9yQnVmZmVyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE9ubnhqc1Nlc3Npb25IYW5kbGVyKHNlc3Npb24pO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBvbm54anNCYWNrZW5kID0gbmV3IE9ubnhqc0JhY2tlbmQoKTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuZXhwb3J0IGNvbnN0IGlzTm9kZSA9ICEhKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb25zICYmIHByb2Nlc3MudmVyc2lvbnMubm9kZSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8vLyA8cmVmZXJlbmNlIGxpYj1cIndlYndvcmtlclwiIC8+XG5cbi8vXG4vLyAqIHR5cGUgaGFjayBmb3IgXCJIVE1MSW1hZ2VFbGVtZW50XCJcbi8vXG4vLyBpbiB0eXBlc2NyaXB0LCB0aGUgdHlwZSBvZiBcIkhUTUxJbWFnZUVsZW1lbnRcIiBpcyBkZWZpbmVkIGluIGxpYi5kb20uZC50cywgd2hpY2ggaXMgY29uZmxpY3Qgd2l0aCBsaWIud2Vid29ya2VyLmQudHMuXG4vLyB3aGVuIHdlIHVzZSB3ZWJ3b3JrZXIsIHRoZSBsaWIud2Vid29ya2VyLmQudHMgd2lsbCBiZSB1c2VkLCB3aGljaCBkb2VzIG5vdCBoYXZlIEhUTUxJbWFnZUVsZW1lbnQgZGVmaW5lZC5cbi8vXG4vLyB3ZSB3aWxsIGdldCB0aGUgZm9sbG93aW5nIGVycm9ycyBjb21wbGFpbmluZyB0aGF0IEhUTUxJbWFnZUVsZW1lbnQgaXMgbm90IGRlZmluZWQ6XG4vL1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vXG4vLyAuLi9jb21tb24vZGlzdC9janMvdGVuc29yLWZhY3RvcnkuZC50czoxODc6MjkgLSBlcnJvciBUUzI1NTI6IENhbm5vdCBmaW5kIG5hbWUgJ0hUTUxJbWFnZUVsZW1lbnQnLiBEaWQgeW91IG1lYW5cbi8vICdIVE1MTElFbGVtZW50Jz9cbi8vXG4vLyAxODcgICAgIGZyb21JbWFnZShpbWFnZUVsZW1lbnQ6IEhUTUxJbWFnZUVsZW1lbnQsIG9wdGlvbnM/OiBUZW5zb3JGcm9tSW1hZ2VFbGVtZW50T3B0aW9ucyk6XG4vLyBQcm9taXNlPFR5cGVkVGVuc29yPCdmbG9hdDMyJz4gfCBUeXBlZFRlbnNvcjwndWludDgnPj47XG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH5+fn5+fn5+fn5+fn5+fn5cbi8vXG4vLyBub2RlX21vZHVsZXMvQHdlYmdwdS90eXBlcy9kaXN0L2luZGV4LmQudHM6ODM6NyAtIGVycm9yIFRTMjU1MjogQ2Fubm90IGZpbmQgbmFtZSAnSFRNTEltYWdlRWxlbWVudCcuIERpZCB5b3UgbWVhblxuLy8gJ0hUTUxMSUVsZW1lbnQnP1xuLy9cbi8vIDgzICAgICB8IEhUTUxJbWFnZUVsZW1lbnRcbi8vICAgICAgICAgIH5+fn5+fn5+fn5+fn5+fn5cbi8vXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy9cbi8vIGBIVE1MSW1hZ2VFbGVtZW50YCBpcyBvbmx5IHVzZWQgaW4gdHlwZSBkZWNsYXJhdGlvbiBhbmQgbm90IGluIHJlYWwgY29kZS4gU28gd2UgZGVmaW5lIGl0IGFzIGB1bmtub3duYCBoZXJlIHRvXG4vLyBieXBhc3MgdGhlIHR5cGUgY2hlY2suXG5cbi8vXG4vLyAqIHR5cGUgaGFjayBmb3IgXCJkb2N1bWVudFwiXG4vL1xuLy8gaW4gdHlwZXNjcmlwdCwgdGhlIHR5cGUgb2YgXCJkb2N1bWVudFwiIGlzIGRlZmluZWQgaW4gbGliLmRvbS5kLnRzLCBzbyBpdCdzIG5vdCBhdmFpbGFibGUgaW4gd2Vid29ya2VyLlxuLy9cbi8vIHdlIHdpbGwgZ2V0IHRoZSBmb2xsb3dpbmcgZXJyb3JzIGNvbXBsYWluaW5nIHRoYXQgZG9jdW1lbnQgaXMgbm90IGRlZmluZWQ6XG4vL1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vXG4vLyBsaWIvd2FzbS93YXNtLXV0aWxzLWltcG9ydC50czo3OjMzIC0gZXJyb3IgVFMyNTg0OiBDYW5ub3QgZmluZCBuYW1lICdkb2N1bWVudCcuIERvIHlvdSBuZWVkIHRvIGNoYW5nZSB5b3VyIHRhcmdldFxuLy8gbGlicmFyeT8gVHJ5IGNoYW5naW5nIHRoZSAnbGliJyBjb21waWxlciBvcHRpb24gdG8gaW5jbHVkZSAnZG9tJy5cbi8vXG4vLyA3IGV4cG9ydCBjb25zdCBzY3JpcHRTcmMgPSB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnID8gKGRvY3VtZW50Py5jdXJyZW50U2NyaXB0IGFzIEhUTUxTY3JpcHRFbGVtZW50KT8uc3JjIDpcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+fn5+fn5+flxuLy9cbi8vIGxpYi93YXNtL3dhc20tdXRpbHMtaW1wb3J0LnRzOjc6NjEgLSBlcnJvciBUUzI1ODQ6IENhbm5vdCBmaW5kIG5hbWUgJ2RvY3VtZW50Jy4gRG8geW91IG5lZWQgdG8gY2hhbmdlIHlvdXIgdGFyZ2V0XG4vLyBsaWJyYXJ5PyBUcnkgY2hhbmdpbmcgdGhlICdsaWInIGNvbXBpbGVyIG9wdGlvbiB0byBpbmNsdWRlICdkb20nLlxuLy9cbi8vIDcgZXhwb3J0IGNvbnN0IHNjcmlwdFNyYyA9IHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgPyAoZG9jdW1lbnQ/LmN1cnJlbnRTY3JpcHQgYXMgSFRNTFNjcmlwdEVsZW1lbnQpPy5zcmMgOlxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+fn5+fn5+flxuLy9cbi8vIGxpYi93YXNtL3dhc20tdXRpbHMtaW1wb3J0LnRzOjc6ODggLSBlcnJvciBUUzI1NTI6IENhbm5vdCBmaW5kIG5hbWUgJ0hUTUxTY3JpcHRFbGVtZW50Jy4gRGlkIHlvdSBtZWFuXG4vLyAnSFRNTExJRWxlbWVudCc/XG4vL1xuLy8gNyBleHBvcnQgY29uc3Qgc2NyaXB0U3JjID0gdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyA/IChkb2N1bWVudD8uY3VycmVudFNjcmlwdCBhcyBIVE1MU2NyaXB0RWxlbWVudCk/LnNyYyA6XG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH5+fn5+fn5+fn5+fn5+fn5+XG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy9cbi8vIGBkb2N1bWVudGAgaXMgdXNlZCB0byBnZXQgdGhlIGN1cnJlbnQgc2NyaXB0IFVSTCwgd2hpY2ggaXMgbm90IGF2YWlsYWJsZSBpbiB3ZWJ3b3JrZXIuIFRoaXMgZmlsZSBpcyBzZXJ2ZWQgYXMgYVxuLy8gXCJkdWFsXCIgZmlsZSBmb3IgZW50cmllcyBvZiBib3RoIHdlYndvcmtlciBhbmQgdGhlIGVzbSBtb2R1bGUuXG4vL1xuZGVjbGFyZSBnbG9iYWwge1xuICB0eXBlIEhUTUxJbWFnZUVsZW1lbnQgPSB1bmtub3duO1xuICB0eXBlIEhUTUxTY3JpcHRFbGVtZW50ID0geyBzcmM/OiBzdHJpbmcgfTtcbiAgY29uc3QgZG9jdW1lbnQ6IHVuZGVmaW5lZCB8IHsgY3VycmVudFNjcmlwdD86IEhUTUxTY3JpcHRFbGVtZW50IH07XG59XG5cbi8qKlxuICogQHN1bW1hcnlcbiAqXG4gKiBUaGlzIGZpbGUgaXMgc2VydmVkIGFzIGEgXCJkdWFsXCIgZmlsZSBmb3IgYm90aCBlbnRyaWVzIG9mIHRoZSBmb2xsb3dpbmc6XG4gKiAtIFRoZSBwcm94eSB3b3JrZXIgaXRzZWxmLlxuICogICAtIFdoZW4gdXNlZCBhcyBhIHdvcmtlciwgaXQgbGlzdGVucyB0byB0aGUgbWVzc2FnZXMgZnJvbSB0aGUgbWFpbiB0aHJlYWQgYW5kIHBlcmZvcm1zIHRoZSBjb3JyZXNwb25kaW5nIG9wZXJhdGlvbnMuXG4gKiAgIC0gU2hvdWxkIGJlIGltcG9ydGVkIGRpcmVjdGx5IHVzaW5nIGBuZXcgV29ya2VyKClgIGluIHRoZSBtYWluIHRocmVhZC5cbiAqXG4gKiAtIFRoZSBFU00gbW9kdWxlIHRoYXQgY3JlYXRlcyB0aGUgcHJveHkgd29ya2VyIChhcyBhIHdvcmtlciBsYXVuY2hlcikuXG4gKiAgIC0gV2hlbiB1c2VkIGFzIGEgd29ya2VyIGxhdW5jaGVyLCBpdCBjcmVhdGVzIHRoZSBwcm94eSB3b3JrZXIgYW5kIHJldHVybnMgaXQuXG4gKiAgIC0gU2hvdWxkIGJlIGltcG9ydGVkIHVzaW5nIGBpbXBvcnQoKWAgaW4gdGhlIG1haW4gdGhyZWFkLCB3aXRoIHRoZSBxdWVyeSBwYXJhbWV0ZXIgYGltcG9ydD0xYC5cbiAqXG4gKiBUaGlzIGZpbGUgd2lsbCBiZSBhbHdheXMgY29tcGlsaW5nIGludG8gRVNNIGZvcm1hdC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IE9ydFdhc21NZXNzYWdlLCBTZXJpYWxpemFibGVUZW5zb3JNZXRhZGF0YSB9IGZyb20gJy4uL3Byb3h5LW1lc3NhZ2VzLmpzJztcbmltcG9ydCB7XG4gIGNyZWF0ZVNlc3Npb24sXG4gIGNvcHlGcm9tRXh0ZXJuYWxCdWZmZXIsXG4gIGVuZFByb2ZpbGluZyxcbiAgZXh0cmFjdFRyYW5zZmVyYWJsZUJ1ZmZlcnMsXG4gIGluaXRFcCxcbiAgaW5pdFJ1bnRpbWUsXG4gIHJlbGVhc2VTZXNzaW9uLFxuICBydW4sXG59IGZyb20gJy4uL3dhc20tY29yZS1pbXBsLmpzJztcbmltcG9ydCB7IGluaXRpYWxpemVXZWJBc3NlbWJseSB9IGZyb20gJy4uL3dhc20tZmFjdG9yeS5qcyc7XG5pbXBvcnQgeyBzY3JpcHRTcmMgfSBmcm9tICcuLi93YXNtLXV0aWxzLWltcG9ydC5qcyc7XG5cbmNvbnN0IFdPUktFUl9OQU1FID0gJ29ydC13YXNtLXByb3h5LXdvcmtlcic7XG5jb25zdCBpc1Byb3h5V29ya2VyID0gZ2xvYmFsVGhpcy5zZWxmPy5uYW1lID09PSBXT1JLRVJfTkFNRTtcblxuaWYgKGlzUHJveHlXb3JrZXIpIHtcbiAgLy8gV29ya2VyIHRocmVhZFxuICBzZWxmLm9ubWVzc2FnZSA9IChldjogTWVzc2FnZUV2ZW50PE9ydFdhc21NZXNzYWdlPik6IHZvaWQgPT4ge1xuICAgIGNvbnN0IHsgdHlwZSwgaW46IG1lc3NhZ2UgfSA9IGV2LmRhdGE7XG4gICAgdHJ5IHtcbiAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlICdpbml0LXdhc20nOlxuICAgICAgICAgIGluaXRpYWxpemVXZWJBc3NlbWJseShtZXNzYWdlIS53YXNtKS50aGVuKFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICBpbml0UnVudGltZShtZXNzYWdlISkudGhlbihcbiAgICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGUgfSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGUsIGVyciB9KTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UoeyB0eXBlLCBlcnIgfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2luaXQtZXAnOiB7XG4gICAgICAgICAgY29uc3QgeyBlcE5hbWUsIGVudiB9ID0gbWVzc2FnZSE7XG4gICAgICAgICAgaW5pdEVwKGVudiwgZXBOYW1lKS50aGVuKFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGUgfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgKGVycikgPT4ge1xuICAgICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGUsIGVyciB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdjb3B5LWZyb20nOiB7XG4gICAgICAgICAgY29uc3QgeyBidWZmZXIgfSA9IG1lc3NhZ2UhO1xuICAgICAgICAgIGNvbnN0IGJ1ZmZlckRhdGEgPSBjb3B5RnJvbUV4dGVybmFsQnVmZmVyKGJ1ZmZlcik7XG4gICAgICAgICAgcG9zdE1lc3NhZ2UoeyB0eXBlLCBvdXQ6IGJ1ZmZlckRhdGEgfSBhcyBPcnRXYXNtTWVzc2FnZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnY3JlYXRlJzoge1xuICAgICAgICAgIGNvbnN0IHsgbW9kZWwsIG9wdGlvbnMgfSA9IG1lc3NhZ2UhO1xuICAgICAgICAgIGNyZWF0ZVNlc3Npb24obW9kZWwsIG9wdGlvbnMpLnRoZW4oXG4gICAgICAgICAgICAoc2Vzc2lvbk1ldGFkYXRhKSA9PiB7XG4gICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZSwgb3V0OiBzZXNzaW9uTWV0YWRhdGEgfSBhcyBPcnRXYXNtTWVzc2FnZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgKGVycikgPT4ge1xuICAgICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGUsIGVyciB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdyZWxlYXNlJzpcbiAgICAgICAgICByZWxlYXNlU2Vzc2lvbihtZXNzYWdlISk7XG4gICAgICAgICAgcG9zdE1lc3NhZ2UoeyB0eXBlIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdydW4nOiB7XG4gICAgICAgICAgY29uc3QgeyBzZXNzaW9uSWQsIGlucHV0SW5kaWNlcywgaW5wdXRzLCBvdXRwdXRJbmRpY2VzLCBvcHRpb25zIH0gPSBtZXNzYWdlITtcbiAgICAgICAgICBydW4oc2Vzc2lvbklkLCBpbnB1dEluZGljZXMsIGlucHV0cywgb3V0cHV0SW5kaWNlcywgbmV3IEFycmF5KG91dHB1dEluZGljZXMubGVuZ3RoKS5maWxsKG51bGwpLCBvcHRpb25zKS50aGVuKFxuICAgICAgICAgICAgKG91dHB1dHMpID0+IHtcbiAgICAgICAgICAgICAgaWYgKG91dHB1dHMuc29tZSgobykgPT4gb1szXSAhPT0gJ2NwdScpKSB7XG4gICAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UoeyB0eXBlLCBlcnI6ICdQcm94eSBkb2VzIG5vdCBzdXBwb3J0IG5vbi1jcHUgdGVuc29yIGxvY2F0aW9uLicgfSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UoXG4gICAgICAgICAgICAgICAgICB7IHR5cGUsIG91dDogb3V0cHV0cyB9IGFzIE9ydFdhc21NZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgZXh0cmFjdFRyYW5zZmVyYWJsZUJ1ZmZlcnMoWy4uLmlucHV0cywgLi4ub3V0cHV0c10gYXMgU2VyaWFsaXphYmxlVGVuc29yTWV0YWRhdGFbXSksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UoeyB0eXBlLCBlcnIgfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnZW5kLXByb2ZpbGluZyc6XG4gICAgICAgICAgZW5kUHJvZmlsaW5nKG1lc3NhZ2UhKTtcbiAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGUgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBwb3N0TWVzc2FnZSh7IHR5cGUsIGVyciB9IGFzIE9ydFdhc21NZXNzYWdlKTtcbiAgICB9XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGlzUHJveHlXb3JrZXJcbiAgPyBudWxsXG4gIDogKHVybE92ZXJyaWRlPzogc3RyaW5nKSA9PlxuICAgICAgbmV3IFdvcmtlcih1cmxPdmVycmlkZSA/PyBzY3JpcHRTcmMhLCB7IHR5cGU6IEJVSUxEX0RFRlMuSVNfRVNNID8gJ21vZHVsZScgOiAnY2xhc3NpYycsIG5hbWU6IFdPUktFUl9OQU1FIH0pO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgdHlwZSB7IE9ydFdhc21Nb2R1bGUgfSBmcm9tICcuL3dhc20tdHlwZXMnO1xuaW1wb3J0IHsgaXNOb2RlIH0gZnJvbSAnLi93YXNtLXV0aWxzLWVudic7XG5cbi8qKlxuICogVGhlIG9yaWdpbiBvZiB0aGUgY3VycmVudCBsb2NhdGlvbi5cbiAqXG4gKiBJbiBOb2RlLmpzLCB0aGlzIGlzIHVuZGVmaW5lZC5cbiAqL1xuY29uc3Qgb3JpZ2luID0gaXNOb2RlIHx8IHR5cGVvZiBsb2NhdGlvbiA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBsb2NhdGlvbi5vcmlnaW47XG5cbi8qKlxuICogU29tZSBidW5kbGVycyAoZWcuIFdlYnBhY2spIHdpbGwgcmV3cml0ZSBgaW1wb3J0Lm1ldGEudXJsYCB0byBhIGZpbGUgVVJMIGF0IGNvbXBpbGUgdGltZS5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGNoZWNrcyBpZiBgaW1wb3J0Lm1ldGEudXJsYCBzdGFydHMgd2l0aCBgZmlsZTpgLCBidXQgdXNpbmcgdGhlIGA+YCBhbmQgYDxgIG9wZXJhdG9ycyBpbnN0ZWFkIG9mXG4gKiBgc3RhcnRzV2l0aGAgZnVuY3Rpb24gc28gdGhhdCBjb2RlIG1pbmltaXplcnMgY2FuIHJlbW92ZSB0aGUgZGVhZCBjb2RlIGNvcnJlY3RseS5cbiAqXG4gKiBGb3IgZXhhbXBsZSwgaWYgd2UgdXNlIHRlcnNlciB0byBtaW5pZnkgdGhlIGZvbGxvd2luZyBjb2RlOlxuICogYGBganNcbiAqIGlmIChcImZpbGU6Ly9oYXJkLWNvZGVkLWZpbGVuYW1lXCIuc3RhcnRzV2l0aChcImZpbGU6XCIpKSB7XG4gKiAgIGNvbnNvbGUubG9nKDEpXG4gKiB9IGVsc2Uge1xuICogICBjb25zb2xlLmxvZygyKVxuICogfVxuICpcbiAqIGlmIChcImZpbGU6Ly9oYXJkLWNvZGVkLWZpbGVuYW1lXCIgPiBcImZpbGU6XCIgJiYgXCJmaWxlOi8vaGFyZC1jb2RlZC1maWxlbmFtZVwiIDwgXCJmaWxlO1wiKSB7XG4gKiAgIGNvbnNvbGUubG9nKDMpXG4gKiB9IGVsc2Uge1xuICogICBjb25zb2xlLmxvZyg0KVxuICogfVxuICogYGBgXG4gKlxuICogVGhlIG1pbmlmaWVkIGNvZGUgd2lsbCBiZTpcbiAqIGBgYGpzXG4gKiBcImZpbGU6Ly9oYXJkLWNvZGVkLWZpbGVuYW1lXCIuc3RhcnRzV2l0aChcImZpbGU6XCIpP2NvbnNvbGUubG9nKDEpOmNvbnNvbGUubG9nKDIpLGNvbnNvbGUubG9nKDMpO1xuICogYGBgXG4gKlxuICogKHVzZSBUZXJzZXIgNS4zOS4wIHdpdGggZGVmYXVsdCBvcHRpb25zLCBodHRwczovL3RyeS50ZXJzZXIub3JnLylcbiAqXG4gKiBAcmV0dXJucyB0cnVlIGlmIHRoZSBpbXBvcnQubWV0YS51cmwgaXMgaGFyZGNvZGVkIGFzIGEgZmlsZSBVUkkuXG4gKi9cbmV4cG9ydCBjb25zdCBpc0VzbUltcG9ydE1ldGFVcmxIYXJkY29kZWRBc0ZpbGVVcmkgPVxuICBCVUlMRF9ERUZTLklTX0VTTSAmJiBCVUlMRF9ERUZTLkVTTV9JTVBPUlRfTUVUQV9VUkwhID4gJ2ZpbGU6JyAmJiBCVUlMRF9ERUZTLkVTTV9JTVBPUlRfTUVUQV9VUkwhIDwgJ2ZpbGU7JztcblxuY29uc3QgZ2V0U2NyaXB0U3JjID0gKCk6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIC8vIGlmIE5vZGVqcywgcmV0dXJuIHVuZGVmaW5lZFxuICBpZiAoaXNOb2RlKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICAvLyBpZiBJdCdzIEVTTSwgdXNlIGltcG9ydC5tZXRhLnVybFxuICBpZiAoQlVJTERfREVGUy5JU19FU00pIHtcbiAgICAvLyBGb3IgRVNNLCBpZiB0aGUgaW1wb3J0Lm1ldGEudXJsIGlzIGEgZmlsZSBVUkwsIHRoaXMgdXN1YWxseSBtZWFucyB0aGUgYnVuZGxlciByZXdyaXRlcyBgaW1wb3J0Lm1ldGEudXJsYCB0b1xuICAgIC8vIHRoZSBmaWxlIHBhdGggYXQgY29tcGlsZSB0aW1lLiBJbiB0aGlzIGNhc2UsIHRoaXMgZmlsZSBwYXRoIGNhbm5vdCBiZSB1c2VkIHRvIGRldGVybWluZSB0aGUgcnVudGltZSBVUkwuXG4gICAgLy9cbiAgICAvLyBXZSBuZWVkIHRvIHVzZSB0aGUgVVJMIGNvbnN0cnVjdG9yIGxpa2UgdGhpczpcbiAgICAvLyBgYGBqc1xuICAgIC8vIG5ldyBVUkwoJ2FjdHVhbC1idW5kbGUtbmFtZS5qcycsIGltcG9ydC5tZXRhLnVybCkuaHJlZlxuICAgIC8vIGBgYFxuICAgIC8vIFNvIHRoYXQgYnVuZGxlciBjYW4gcHJlcHJvY2VzcyB0aGUgVVJMIGNvcnJlY3RseS5cbiAgICBpZiAoaXNFc21JbXBvcnRNZXRhVXJsSGFyZGNvZGVkQXNGaWxlVXJpKSB7XG4gICAgICAvLyBpZiB0aGUgcmV3cml0dGVuIFVSTCBpcyBhIHJlbGF0aXZlIHBhdGgsIHdlIG5lZWQgdG8gdXNlIHRoZSBvcmlnaW4gdG8gcmVzb2x2ZSB0aGUgVVJMLlxuXG4gICAgICAvLyBUaGUgZm9sbG93aW5nIGlzIGEgd29ya2Fyb3VuZCBmb3IgVml0ZS5cbiAgICAgIC8vXG4gICAgICAvLyBWaXRlIHVzZXMgYSBidW5kbGVyKHJvbGx1cC9yb2xsZG93bikgdGhhdCBkb2VzIG5vdCByZXdyaXRlIGBpbXBvcnQubWV0YS51cmxgIHRvIGEgZmlsZSBVUkwuIFNvIGluIHRoZW9yeSwgdGhpc1xuICAgICAgLy8gY29kZSBwYXRoIHNob3VsZCBub3QgYmUgZXhlY3V0ZWQgaW4gVml0ZS4gSG93ZXZlciwgdGhlIGJ1bmRsZXIgZG9lcyBub3Qga25vdyBpdCBhbmQgaXQgc3RpbGwgdHJ5IHRvIGxvYWQgdGhlXG4gICAgICAvLyBmb2xsb3dpbmcgcGF0dGVybjpcbiAgICAgIC8vIC0gYHJldHVybiBuZXcgVVJMKCdmaWxlbmFtZScsIGltcG9ydC5tZXRhLnVybCkuaHJlZmBcbiAgICAgIC8vXG4gICAgICAvLyBCeSByZXBsYWNpbmcgdGhlIHBhdHRlcm4gYWJvdmUgd2l0aCB0aGUgZm9sbG93aW5nIGNvZGUsIHdlIGNhbiBza2lwIHRoZSByZXNvdXJjZSBsb2FkaW5nIGJlaGF2aW9yOlxuICAgICAgLy8gLSBgY29uc3QgVVJMMiA9IFVSTDsgcmV0dXJuIG5ldyBVUkwyKCdmaWxlbmFtZScsIGltcG9ydC5tZXRhLnVybCkuaHJlZjtgXG4gICAgICAvL1xuICAgICAgLy8gQW5kIGl0IHN0aWxsIHdvcmtzIGluIFdlYnBhY2suXG4gICAgICBjb25zdCBVUkwyID0gVVJMO1xuICAgICAgcmV0dXJuIG5ldyBVUkwobmV3IFVSTDIoQlVJTERfREVGUy5CVU5ETEVfRklMRU5BTUUsIEJVSUxEX0RFRlMuRVNNX0lNUE9SVF9NRVRBX1VSTCkuaHJlZiwgb3JpZ2luKS5ocmVmO1xuICAgIH1cblxuICAgIHJldHVybiBCVUlMRF9ERUZTLkVTTV9JTVBPUlRfTUVUQV9VUkw7XG4gIH1cblxuICByZXR1cm4gdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJ1xuICAgID8gKGRvY3VtZW50LmN1cnJlbnRTY3JpcHQgYXMgSFRNTFNjcmlwdEVsZW1lbnQpPy5zcmNcbiAgICA6IC8vIHVzZSBgc2VsZi5sb2NhdGlvbi5ocmVmYCBpZiBhdmFpbGFibGVcbiAgICAgIHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJ1xuICAgICAgPyBzZWxmLmxvY2F0aW9uPy5ocmVmXG4gICAgICA6IHVuZGVmaW5lZDtcbn07XG5cbi8qKlxuICogVGhlIGNsYXNzaWMgc2NyaXB0IHNvdXJjZSBVUkwuIFRoaXMgaXMgbm90IGFsd2F5cyBhdmFpbGFibGUgaW4gbm9uIEVTTW9kdWxlIGVudmlyb25tZW50cy5cbiAqXG4gKiBJbiBOb2RlLmpzLCB0aGlzIGlzIHVuZGVmaW5lZC5cbiAqL1xuZXhwb3J0IGNvbnN0IHNjcmlwdFNyYyA9IGdldFNjcmlwdFNyYygpO1xuXG4vKipcbiAqIEluZmVyIHRoZSB3YXNtIHBhdGggcHJlZml4IGZyb20gdGhlIHNjcmlwdCBzb3VyY2UgVVJMLlxuICpcbiAqIEByZXR1cm5zIFRoZSBpbmZlcnJlZCB3YXNtIHBhdGggcHJlZml4LCBvciB1bmRlZmluZWQgaWYgdGhlIHNjcmlwdCBzb3VyY2UgVVJMIGlzIG5vdCBhdmFpbGFibGUgb3IgaXMgYSBibG9iIFVSTC5cbiAqL1xuZXhwb3J0IGNvbnN0IGluZmVyV2FzbVBhdGhQcmVmaXhGcm9tU2NyaXB0U3JjID0gKCk6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChzY3JpcHRTcmMgJiYgIXNjcmlwdFNyYy5zdGFydHNXaXRoKCdibG9iOicpKSB7XG4gICAgcmV0dXJuIHNjcmlwdFNyYy5zdWJzdHJpbmcoMCwgc2NyaXB0U3JjLmxhc3RJbmRleE9mKCcvJykgKyAxKTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiB0aGUgZ2l2ZW4gZmlsZW5hbWUgd2l0aCBwcmVmaXggaXMgZnJvbSB0aGUgc2FtZSBvcmlnaW4uXG4gKi9cbmNvbnN0IGlzU2FtZU9yaWdpbiA9IChmaWxlbmFtZTogc3RyaW5nLCBwcmVmaXhPdmVycmlkZT86IHN0cmluZykgPT4ge1xuICB0cnkge1xuICAgIGNvbnN0IGJhc2VVcmwgPSBwcmVmaXhPdmVycmlkZSA/PyBzY3JpcHRTcmM7XG4gICAgY29uc3QgdXJsID0gYmFzZVVybCA/IG5ldyBVUkwoZmlsZW5hbWUsIGJhc2VVcmwpIDogbmV3IFVSTChmaWxlbmFtZSk7XG4gICAgcmV0dXJuIHVybC5vcmlnaW4gPT09IG9yaWdpbjtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG4vKipcbiAqIE5vcm1hbGl6ZSB0aGUgaW5wdXRzIHRvIGFuIGFic29sdXRlIFVSTCB3aXRoIHRoZSBnaXZlbiBwcmVmaXggb3ZlcnJpZGUuIElmIGZhaWxlZCwgcmV0dXJuIHVuZGVmaW5lZC5cbiAqL1xuY29uc3Qgbm9ybWFsaXplVXJsID0gKGZpbGVuYW1lOiBzdHJpbmcsIHByZWZpeE92ZXJyaWRlPzogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IGJhc2VVcmwgPSBwcmVmaXhPdmVycmlkZSA/PyBzY3JpcHRTcmM7XG4gIHRyeSB7XG4gICAgY29uc3QgdXJsID0gYmFzZVVybCA/IG5ldyBVUkwoZmlsZW5hbWUsIGJhc2VVcmwpIDogbmV3IFVSTChmaWxlbmFtZSk7XG4gICAgcmV0dXJuIHVybC5ocmVmO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIGZhbGxiYWNrIFVSTCBpZiBhbiBhYnNvbHV0ZSBVUkwgY2Fubm90IGJlIGNyZWF0ZWQgYnkgdGhlIG5vcm1hbGl6ZVVybCBmdW5jdGlvbi5cbiAqL1xuY29uc3QgZmFsbGJhY2tVcmwgPSAoZmlsZW5hbWU6IHN0cmluZywgcHJlZml4T3ZlcnJpZGU/OiBzdHJpbmcpID0+IGAke3ByZWZpeE92ZXJyaWRlID8/ICcuLyd9JHtmaWxlbmFtZX1gO1xuXG4vKipcbiAqIFRoaXMgaGVscGVyIGZ1bmN0aW9uIGlzIHVzZWQgdG8gcHJlbG9hZCBhIG1vZHVsZSBmcm9tIGEgVVJMLlxuICpcbiAqIElmIHRoZSBvcmlnaW4gb2YgdGhlIHdvcmtlciBVUkwgaXMgZGlmZmVyZW50IGZyb20gdGhlIGN1cnJlbnQgb3JpZ2luLCB0aGUgd29ya2VyIGNhbm5vdCBiZSBsb2FkZWQgZGlyZWN0bHkuXG4gKiBTZWUgZGlzY3Vzc2lvbnMgaW4gaHR0cHM6Ly9naXRodWIuY29tL3dlYnBhY2stY29udHJpYi93b3JrZXItbG9hZGVyL2lzc3Vlcy8xNTRcbiAqXG4gKiBJbiB0aGlzIGNhc2UsIHdlIHdpbGwgZmV0Y2ggdGhlIHdvcmtlciBVUkwgYW5kIGNyZWF0ZSBhIG5ldyBCbG9iIFVSTCB3aXRoIHRoZSBzYW1lIG9yaWdpbiBhcyBhIHdvcmthcm91bmQuXG4gKlxuICogQHBhcmFtIGFic29sdXRlVXJsIC0gVGhlIGFic29sdXRlIFVSTCB0byBwcmVsb2FkLlxuICpcbiAqIEByZXR1cm5zIC0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBuZXcgQmxvYiBVUkxcbiAqL1xuY29uc3QgcHJlbG9hZCA9IGFzeW5jIChhYnNvbHV0ZVVybDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChhYnNvbHV0ZVVybCwgeyBjcmVkZW50aWFsczogJ3NhbWUtb3JpZ2luJyB9KTtcbiAgY29uc3QgYmxvYiA9IGF3YWl0IHJlc3BvbnNlLmJsb2IoKTtcbiAgcmV0dXJuIFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG59O1xuXG4vKipcbiAqIFRoaXMgaGVscGVyIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZHluYW1pY2FsbHkgaW1wb3J0IGEgbW9kdWxlIGZyb20gYSBVUkwuXG4gKlxuICogVGhlIGJ1aWxkIHNjcmlwdCBoYXMgc3BlY2lhbCBoYW5kbGluZyBmb3IgdGhpcyBmdW5jdGlvbiB0byBlbnN1cmUgdGhhdCB0aGUgVVJMIGlzIG5vdCBidW5kbGVkIGludG8gdGhlIGZpbmFsIG91dHB1dC5cbiAqXG4gKiBAcGFyYW0gdXJsIC0gVGhlIFVSTCB0byBpbXBvcnQuXG4gKlxuICogQHJldHVybnMgLSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgZGVmYXVsdCBleHBvcnQgb2YgdGhlIG1vZHVsZS5cbiAqL1xuY29uc3QgZHluYW1pY0ltcG9ydERlZmF1bHQgPSBhc3luYyA8VD4odXJsOiBzdHJpbmcpOiBQcm9taXNlPFQ+ID0+XG4gIChhd2FpdCBpbXBvcnQoLyogd2VicGFja0lnbm9yZTogdHJ1ZSAqLyAvKiBAdml0ZS1pZ25vcmUgKi8gdXJsKSkuZGVmYXVsdDtcblxuLyoqXG4gKiBUaGUgcHJveHkgd29ya2VyIGZhY3RvcnkgaW1wb3J0ZWQgZnJvbSB0aGUgcHJveHkgd29ya2VyIG1vZHVsZS5cbiAqXG4gKiBUaGlzIGlzIG9ubHkgYXZhaWxhYmxlIHdoZW4gdGhlIFdlYkFzc2VtYmx5IHByb3h5IGlzIG5vdCBkaXNhYmxlZC5cbiAqL1xuY29uc3QgY3JlYXRlUHJveHlXb3JrZXI6ICgodXJsT3ZlcnJpZGU/OiBzdHJpbmcpID0+IFdvcmtlcikgfCB1bmRlZmluZWQgPVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cywgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlc1xuICBCVUlMRF9ERUZTLkRJU0FCTEVfV0FTTV9QUk9YWSA/IHVuZGVmaW5lZCA6IHJlcXVpcmUoJy4vcHJveHktd29ya2VyL21haW4nKS5kZWZhdWx0O1xuXG4vKipcbiAqIEltcG9ydCB0aGUgcHJveHkgd29ya2VyLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBwZXJmb3JtIHRoZSBmb2xsb3dpbmcgc3RlcHM6XG4gKiAxLiBJZiBhIHByZWxvYWQgaXMgbmVlZGVkLCBpdCB3aWxsIHByZWxvYWQgdGhlIG1vZHVsZSBhbmQgcmV0dXJuIHRoZSBvYmplY3QgVVJMLlxuICogMi4gVXNlIHRoZSBwcm94eSB3b3JrZXIgZmFjdG9yeSB0byBjcmVhdGUgdGhlIHByb3h5IHdvcmtlci5cbiAqXG4gKiBAcmV0dXJucyAtIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgdHVwbGUgb2YgMiBlbGVtZW50czpcbiAqICAgICAgICAgICAgLSBUaGUgb2JqZWN0IFVSTCBvZiB0aGUgcHJlbG9hZGVkIG1vZHVsZSwgb3IgdW5kZWZpbmVkIGlmIG5vIHByZWxvYWQgaXMgbmVlZGVkLlxuICogICAgICAgICAgICAtIFRoZSBwcm94eSB3b3JrZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBpbXBvcnRQcm94eVdvcmtlciA9IGFzeW5jICgpOiBQcm9taXNlPFt1bmRlZmluZWQgfCBzdHJpbmcsIFdvcmtlcl0+ID0+IHtcbiAgaWYgKCFzY3JpcHRTcmMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBsb2FkIHByb3h5IHdvcmtlcjogY2Fubm90IGRldGVybWluZSB0aGUgc2NyaXB0IHNvdXJjZSBVUkwuJyk7XG4gIH1cblxuICAvLyBJZiB0aGUgc2NyaXB0IHNvdXJjZSBpcyBmcm9tIHRoZSBzYW1lIG9yaWdpbiwgd2UgY2FuIHVzZSB0aGUgZW1iZWRkZWQgcHJveHkgbW9kdWxlIGRpcmVjdGx5LlxuICBpZiAoaXNTYW1lT3JpZ2luKHNjcmlwdFNyYykpIHtcbiAgICByZXR1cm4gW3VuZGVmaW5lZCwgY3JlYXRlUHJveHlXb3JrZXIhKCldO1xuICB9XG5cbiAgLy8gT3RoZXJ3aXNlLCBuZWVkIHRvIHByZWxvYWRcbiAgY29uc3QgdXJsID0gYXdhaXQgcHJlbG9hZChzY3JpcHRTcmMpO1xuICByZXR1cm4gW3VybCwgY3JlYXRlUHJveHlXb3JrZXIhKHVybCldO1xufTtcblxuLyoqXG4gKiBUaGUgZW1iZWRkZWQgV2ViQXNzZW1ibHkgbW9kdWxlLlxuICpcbiAqIFRoaXMgaXMgb25seSBhdmFpbGFibGUgaW4gRVNNIGFuZCB3aGVuIGVtYmVkZGluZyBpcyBub3QgZGlzYWJsZWQuXG4gKi9cbmNvbnN0IGVtYmVkZGVkV2FzbU1vZHVsZTogRW1zY3JpcHRlbk1vZHVsZUZhY3Rvcnk8T3J0V2FzbU1vZHVsZT4gfCB1bmRlZmluZWQgPVxuICBCVUlMRF9ERUZTLklTX0VTTSAmJiBCVUlMRF9ERUZTLkVOQUJMRV9CVU5ETEVfV0FTTV9KU1xuICAgID8gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMsIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXNcbiAgICAgIHJlcXVpcmUoXG4gICAgICAgICFCVUlMRF9ERUZTLkRJU0FCTEVfSlNFUFxuICAgICAgICAgID8gJy4uLy4uL2Rpc3Qvb3J0LXdhc20tc2ltZC10aHJlYWRlZC5qc2VwLm1qcydcbiAgICAgICAgICA6IEJVSUxEX0RFRlMuRU5BQkxFX0pTUElcbiAgICAgICAgICAgID8gJy4uLy4uL2Rpc3Qvb3J0LXdhc20tc2ltZC10aHJlYWRlZC5qc3BpLm1qcydcbiAgICAgICAgICAgIDogIUJVSUxEX0RFRlMuRElTQUJMRV9XRUJHUFVcbiAgICAgICAgICAgICAgPyAnLi4vLi4vZGlzdC9vcnQtd2FzbS1zaW1kLXRocmVhZGVkLmFzeW5jaWZ5Lm1qcydcbiAgICAgICAgICAgICAgOiAnLi4vLi4vZGlzdC9vcnQtd2FzbS1zaW1kLXRocmVhZGVkLm1qcycsXG4gICAgICApLmRlZmF1bHRcbiAgICA6IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBJbXBvcnQgdGhlIFdlYkFzc2VtYmx5IG1vZHVsZS5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgcGVyZm9ybSB0aGUgZm9sbG93aW5nIHN0ZXBzOlxuICogMS4gSWYgdGhlIGVtYmVkZGVkIG1vZHVsZSBleGlzdHMgYW5kIG5vIGN1c3RvbSBVUkwgaXMgc3BlY2lmaWVkLCB1c2UgdGhlIGVtYmVkZGVkIG1vZHVsZS5cbiAqIDIuIElmIGEgcHJlbG9hZCBpcyBuZWVkZWQsIGl0IHdpbGwgcHJlbG9hZCB0aGUgbW9kdWxlIGFuZCByZXR1cm4gdGhlIG9iamVjdCBVUkwuXG4gKiAzLiBPdGhlcndpc2UsIGl0IHdpbGwgcGVyZm9ybSBhIGR5bmFtaWMgaW1wb3J0IG9mIHRoZSBtb2R1bGUuXG4gKlxuICogQHJldHVybnMgLSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHR1cGxlIG9mIDIgZWxlbWVudHM6XG4gKiAgICAgICAgICAgIC0gVGhlIG9iamVjdCBVUkwgb2YgdGhlIHByZWxvYWRlZCBtb2R1bGUsIG9yIHVuZGVmaW5lZCBpZiBubyBwcmVsb2FkIGlzIG5lZWRlZC5cbiAqICAgICAgICAgICAgLSBUaGUgZGVmYXVsdCBleHBvcnQgb2YgdGhlIG1vZHVsZSwgd2hpY2ggaXMgYSBmYWN0b3J5IGZ1bmN0aW9uIHRvIGNyZWF0ZSB0aGUgV2ViQXNzZW1ibHkgbW9kdWxlLlxuICovXG5leHBvcnQgY29uc3QgaW1wb3J0V2FzbU1vZHVsZSA9IGFzeW5jIChcbiAgdXJsT3ZlcnJpZGU6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgcHJlZml4T3ZlcnJpZGU6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgaXNNdWx0aVRocmVhZGVkOiBib29sZWFuLFxuICBpc1dhc21PdmVycmlkZGVuOiBib29sZWFuLFxuKTogUHJvbWlzZTxbdW5kZWZpbmVkIHwgc3RyaW5nLCBFbXNjcmlwdGVuTW9kdWxlRmFjdG9yeTxPcnRXYXNtTW9kdWxlPl0+ID0+IHtcbiAgLy9cbiAgLy8gQ2hlY2sgaWYgd2Ugc2hvdWxkIHVzZSB0aGUgZW1iZWRkZWQgbW9kdWxlLlxuICAvL1xuXG4gIC8vIFRvIHVzZSB0aGUgZW1iZWRkZWQgbW9kdWxlLCBpdCBzaG91bGQgYmUgYXZhaWxhYmxlLCBhbmQgbm8gVVJMIG92ZXJyaWRlIG9yIHByZWZpeCBvdmVycmlkZSBzaG91bGQgYmUgc3BlY2lmaWVkLlxuICBsZXQgdXNlRW1iZWRkZWRNb2R1bGUgPSBlbWJlZGRlZFdhc21Nb2R1bGUgJiYgISh1cmxPdmVycmlkZSB8fCBwcmVmaXhPdmVycmlkZSk7XG4gIGlmICh1c2VFbWJlZGRlZE1vZHVsZSkge1xuICAgIGlmICghc2NyaXB0U3JjKSB7XG4gICAgICAvLyBubyBVUkwgaW5mbyBhdmFpbGFibGUuXG4gICAgICAvL1xuICAgICAgLy8gTm90ZTogd2hlbiB0aGUgZW1iZWRkZWQgbW9kdWxlIGlzIGF2YWlsYWJsZSwgaXQgbWVhbnMgdGhlIGN1cnJlbnQgc2NyaXB0IGlzIEVTTS4gVXN1YWxseSwgaW4gRVNNLCB0aGVcbiAgICAgIC8vIGBpbXBvcnQubWV0YS51cmxgIGlzIGF2YWlsYWJsZS4gQnV0IGluIHNvbWUgY2FzZXMgKGVnLiBDbG91ZGZsYXJlIFdvcmtlcnMpLCB0aGUgdmFsdWUgb2YgYGltcG9ydC5tZXRhLnVybGBcbiAgICAgIC8vIGNhbiBiZSBgbnVsbGAgb3IgYHVuZGVmaW5lZGAuIEluIHRoaXMgY2FzZSwgd2UgY2FuIG9ubHkgbG9hZCB0aGUgZW1iZWRkZWQgbW9kdWxlIHdoZW46XG4gICAgICAvL1xuICAgICAgLy8gMS4gVGhlIFdlYkFzc2VtYmx5IG1vZHVsZSBiaW5hcnkgaXMgb3ZlcnJpZGRlbjpcbiAgICAgIC8vICAgIGBgYGpzXG4gICAgICAvLyAgICBlbnYud2FzbS53YXNtUGF0aHMgPSB1bmRlZmluZWQ7ICAvLyBvciBub3Qgc3BlY2lmaWVkXG4gICAgICAvLyAgICBlbnYud2FzbS53YXNtQmluYXJ5ID0gLyogYSBVaW50OEFycmF5IGNvbnRhaW5pbmcgdGhlIFdlYkFzc2VtYmx5IGJpbmFyeSAqLztcbiAgICAgIC8vICAgIGBgYFxuICAgICAgLy9cbiAgICAgIC8vIDIuIFRoZSBcIi53YXNtXCIgb25seSBpcyBvdmVycmlkZGVuLlxuICAgICAgLy8gICAgYGBganNcbiAgICAgIC8vICAgIGVudi53YXNtLndhc21QYXRocyA9IHsgd2FzbTogLyogVVJMIG9mIHRoZSAud2FzbSBmaWxlICovIH07XG4gICAgICAvLyAgICBgYGBcbiAgICAgIC8vXG4gICAgICBpZiAoaXNXYXNtT3ZlcnJpZGRlbiAmJiAhaXNNdWx0aVRocmVhZGVkKSB7XG4gICAgICAgIHVzZUVtYmVkZGVkTW9kdWxlID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGRldGVybWluZSB0aGUgc2NyaXB0IHNvdXJjZSBVUkwuJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGlmIHRoZSBzY3JpcHQgc291cmNlIGlzIGF2YWlsYWJsZSwgd2UgY2FuIGNoZWNrIGlmIGl0IGlzIGZyb20gdGhlIHNhbWUgb3JpZ2luLlxuICAgICAgLy8gQWxzbyB1c2UgdGhlIGVtYmVkZGVkIG1vZHVsZSB3aGVuIHdhc21CaW5hcnkgaXMgcHJvdmlkZWQgYW5kIHNpbmdsZS10aHJlYWRlZCAoZWcuIEJsb2IgVVJMIHdvcmtlcnNcbiAgICAgIC8vIHdoZXJlIGlzU2FtZU9yaWdpbiBmYWlscyBidXQgbm8gZmlsZSByZXNvbHV0aW9uIG9yIHdvcmtlciBzcGF3bmluZyBpcyBuZWVkZWQpLlxuICAgICAgdXNlRW1iZWRkZWRNb2R1bGUgPSBpc1NhbWVPcmlnaW4oc2NyaXB0U3JjKSB8fCAoaXNXYXNtT3ZlcnJpZGRlbiAmJiAhaXNNdWx0aVRocmVhZGVkKTtcbiAgICB9XG4gIH1cbiAgaWYgKHVzZUVtYmVkZGVkTW9kdWxlKSB7XG4gICAgcmV0dXJuIFt1bmRlZmluZWQsIGVtYmVkZGVkV2FzbU1vZHVsZSFdO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IHdhc21Nb2R1bGVGaWxlbmFtZSA9ICFCVUlMRF9ERUZTLkRJU0FCTEVfSlNFUFxuICAgICAgPyAnb3J0LXdhc20tc2ltZC10aHJlYWRlZC5qc2VwLm1qcydcbiAgICAgIDogQlVJTERfREVGUy5FTkFCTEVfSlNQSVxuICAgICAgICA/ICdvcnQtd2FzbS1zaW1kLXRocmVhZGVkLmpzcGkubWpzJ1xuICAgICAgICA6ICFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR1BVXG4gICAgICAgICAgPyAnb3J0LXdhc20tc2ltZC10aHJlYWRlZC5hc3luY2lmeS5tanMnXG4gICAgICAgICAgOiAnb3J0LXdhc20tc2ltZC10aHJlYWRlZC5tanMnO1xuICAgIGNvbnN0IHdhc21Nb2R1bGVVcmwgPSB1cmxPdmVycmlkZSA/PyBub3JtYWxpemVVcmwod2FzbU1vZHVsZUZpbGVuYW1lLCBwcmVmaXhPdmVycmlkZSk7XG4gICAgLy8gbmVlZCB0byBwcmVsb2FkIGlmIGFsbCBvZiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAgICAvLyAxLiBub3QgaW4gTm9kZS5qcy5cbiAgICAvLyAgICAtIE5vZGUuanMgZG9lcyBub3QgaGF2ZSB0aGUgc2FtZSBvcmlnaW4gcG9saWN5IGZvciBjcmVhdGluZyB3b3JrZXJzLlxuICAgIC8vIDIuIG11bHRpLXRocmVhZGVkIGlzIGVuYWJsZWQuXG4gICAgLy8gICAgLSBJZiBtdWx0aS10aHJlYWRlZCBpcyBkaXNhYmxlZCwgbm8gd29ya2VyIHdpbGwgYmUgY3JlYXRlZC4gU28gd2UgZG9uJ3QgbmVlZCB0byBwcmVsb2FkIHRoZSBtb2R1bGUuXG4gICAgLy8gMy4gdGhlIGFic29sdXRlIFVSTCBpcyBhdmFpbGFibGUuXG4gICAgLy8gICAgLSBJZiB0aGUgYWJzb2x1dGUgVVJMIGlzIGZhaWxlZCB0byBiZSBjcmVhdGVkLCB0aGUgb3JpZ2luIGNhbm5vdCBiZSBkZXRlcm1pbmVkLiBJbiB0aGlzIGNhc2UsIHdlIHdpbGwgbm90XG4gICAgLy8gICAgcHJlbG9hZCB0aGUgbW9kdWxlLlxuICAgIC8vIDQuIHRoZSB3b3JrZXIgVVJMIGlzIG5vdCBmcm9tIHRoZSBzYW1lIG9yaWdpbi5cbiAgICAvLyAgICAtIElmIHRoZSB3b3JrZXIgVVJMIGlzIGZyb20gdGhlIHNhbWUgb3JpZ2luLCB3ZSBjYW4gY3JlYXRlIHRoZSB3b3JrZXIgZGlyZWN0bHkuXG4gICAgY29uc3QgbmVlZFByZWxvYWQgPSAhaXNOb2RlICYmIGlzTXVsdGlUaHJlYWRlZCAmJiB3YXNtTW9kdWxlVXJsICYmICFpc1NhbWVPcmlnaW4od2FzbU1vZHVsZVVybCwgcHJlZml4T3ZlcnJpZGUpO1xuICAgIGNvbnN0IHVybCA9IG5lZWRQcmVsb2FkXG4gICAgICA/IGF3YWl0IHByZWxvYWQod2FzbU1vZHVsZVVybClcbiAgICAgIDogKHdhc21Nb2R1bGVVcmwgPz8gZmFsbGJhY2tVcmwod2FzbU1vZHVsZUZpbGVuYW1lLCBwcmVmaXhPdmVycmlkZSkpO1xuICAgIHJldHVybiBbbmVlZFByZWxvYWQgPyB1cmwgOiB1bmRlZmluZWQsIGF3YWl0IGR5bmFtaWNJbXBvcnREZWZhdWx0PEVtc2NyaXB0ZW5Nb2R1bGVGYWN0b3J5PE9ydFdhc21Nb2R1bGU+Pih1cmwpXTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRW52IH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHR5cGUgeyBPcnRXYXNtTW9kdWxlIH0gZnJvbSAnLi93YXNtLXR5cGVzJztcbmltcG9ydCB7IGltcG9ydFdhc21Nb2R1bGUsIGluZmVyV2FzbVBhdGhQcmVmaXhGcm9tU2NyaXB0U3JjIH0gZnJvbSAnLi93YXNtLXV0aWxzLWltcG9ydCc7XG5cbmxldCB3YXNtOiBPcnRXYXNtTW9kdWxlIHwgdW5kZWZpbmVkO1xubGV0IGluaXRpYWxpemVkID0gZmFsc2U7XG5sZXQgaW5pdGlhbGl6aW5nID0gZmFsc2U7XG5sZXQgYWJvcnRlZCA9IGZhbHNlO1xuXG5jb25zdCBpc011bHRpVGhyZWFkU3VwcG9ydGVkID0gKCk6IGJvb2xlYW4gPT4ge1xuICAvLyBJZiAnU2hhcmVkQXJyYXlCdWZmZXInIGlzIG5vdCBhdmFpbGFibGUsIFdlYkFzc2VtYmx5IHRocmVhZHMgd2lsbCBub3Qgd29yay5cbiAgaWYgKHR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB0cnkge1xuICAgIC8vIFRlc3QgZm9yIHRyYW5zZmVyYWJpbGl0eSBvZiBTQUJzIChmb3IgYnJvd3NlcnMuIG5lZWRlZCBmb3IgRmlyZWZveClcbiAgICAvLyBodHRwczovL2dyb3Vwcy5nb29nbGUuY29tL2ZvcnVtLyMhbXNnL21vemlsbGEuZGV2LnBsYXRmb3JtL0lIa0JabEhFVHBBL2R3c01OY2hXRVFBSlxuICAgIGlmICh0eXBlb2YgTWVzc2FnZUNoYW5uZWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBuZXcgTWVzc2FnZUNoYW5uZWwoKS5wb3J0MS5wb3N0TWVzc2FnZShuZXcgU2hhcmVkQXJyYXlCdWZmZXIoMSkpO1xuICAgIH1cblxuICAgIC8vIFRlc3QgZm9yIFdlYkFzc2VtYmx5IHRocmVhZHMgY2FwYWJpbGl0eSAoZm9yIGJvdGggYnJvd3NlcnMgYW5kIE5vZGUuanMpXG4gICAgLy8gVGhpcyB0eXBlZCBhcnJheSBpcyBhIFdlYkFzc2VtYmx5IHByb2dyYW0gY29udGFpbmluZyB0aHJlYWRlZCBpbnN0cnVjdGlvbnMuXG4gICAgcmV0dXJuIFdlYkFzc2VtYmx5LnZhbGlkYXRlKFxuICAgICAgbmV3IFVpbnQ4QXJyYXkoW1xuICAgICAgICAwLCA5NywgMTE1LCAxMDksIDEsIDAsIDAsIDAsIDEsIDQsIDEsIDk2LCAwLCAwLCAzLCAyLCAxLCAwLCA1LCA0LCAxLCAzLCAxLCAxLCAxMCwgMTEsIDEsIDksIDAsIDY1LCAwLCAyNTQsIDE2LFxuICAgICAgICAyLCAwLCAyNiwgMTEsXG4gICAgICBdKSxcbiAgICApO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbmNvbnN0IGlzU2ltZFN1cHBvcnRlZCA9ICgpOiBib29sZWFuID0+IHtcbiAgdHJ5IHtcbiAgICAvLyBUZXN0IGZvciBXZWJBc3NlbWJseSBTSU1EIGNhcGFiaWxpdHkgKGZvciBib3RoIGJyb3dzZXJzIGFuZCBOb2RlLmpzKVxuICAgIC8vIFRoaXMgdHlwZWQgYXJyYXkgaXMgYSBXZWJBc3NlbWJseSBwcm9ncmFtIGNvbnRhaW5pbmcgU0lNRCBpbnN0cnVjdGlvbnMuXG5cbiAgICAvLyBUaGUgYmluYXJ5IGRhdGEgaXMgZ2VuZXJhdGVkIGZyb20gdGhlIGZvbGxvd2luZyBjb2RlIGJ5IHdhdDJ3YXNtOlxuICAgIC8vXG4gICAgLy8gKG1vZHVsZVxuICAgIC8vICAgKHR5cGUgJHQwIChmdW5jKSlcbiAgICAvLyAgIChmdW5jICRmMCAodHlwZSAkdDApXG4gICAgLy8gICAgIChkcm9wXG4gICAgLy8gICAgICAgKGkzMng0LmRvdF9pMTZ4OF9zXG4gICAgLy8gICAgICAgICAoaTh4MTYuc3BsYXRcbiAgICAvLyAgICAgICAgICAgKGkzMi5jb25zdCAwKSlcbiAgICAvLyAgICAgICAgICh2MTI4LmNvbnN0IGkzMng0IDB4MDAwMDAwMDAgMHgwMDAwMDAwMCAweDAwMDAwMDAwIDB4MDAwMDAwMDApKSkpKVxuXG4gICAgcmV0dXJuIFdlYkFzc2VtYmx5LnZhbGlkYXRlKFxuICAgICAgbmV3IFVpbnQ4QXJyYXkoW1xuICAgICAgICAwLCA5NywgMTE1LCAxMDksIDEsIDAsIDAsIDAsIDEsIDQsIDEsIDk2LCAwLCAwLCAzLCAyLCAxLCAwLCAxMCwgMzAsIDEsIDI4LCAwLCA2NSwgMCwgMjUzLCAxNSwgMjUzLCAxMiwgMCwgMCwgMCxcbiAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMjUzLCAxODYsIDEsIDI2LCAxMSxcbiAgICAgIF0pLFxuICAgICk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuY29uc3QgaXNSZWxheGVkU2ltZFN1cHBvcnRlZCA9ICgpOiBib29sZWFuID0+IHtcbiAgdHJ5IHtcbiAgICAvLyBUZXN0IGZvciBXZWJBc3NlbWJseSBSZWxheGVkIFNJTUQgY2FwYWJpbGl0eSAoZm9yIGJvdGggYnJvd3NlcnMgYW5kIE5vZGUuanMpXG4gICAgLy8gVGhpcyB0eXBlZCBhcnJheSBpcyBhIFdlYkFzc2VtYmx5IHByb2dyYW0gY29udGFpbmluZyBSZWxheGVkIFNJTUQgaW5zdHJ1Y3Rpb25zLlxuXG4gICAgLy8gVGhlIGJpbmFyeSBkYXRhIGlzIGdlbmVyYXRlZCBmcm9tIHRoZSBmb2xsb3dpbmcgY29kZSBieSB3YXQyd2FzbTpcbiAgICAvLyAobW9kdWxlXG4gICAgLy8gICAoZnVuYyAocmVzdWx0IHYxMjgpXG4gICAgLy8gICAgICBpMzIuY29uc3QgMVxuICAgIC8vICAgICAgaTh4MTYuc3BsYXRcbiAgICAvLyAgICAgIGkzMi5jb25zdCAyXG4gICAgLy8gICAgICBpOHgxNi5zcGxhdFxuICAgIC8vICAgICAgaTMyLmNvbnN0IDNcbiAgICAvLyAgICAgIGk4eDE2LnNwbGF0XG4gICAgLy8gICAgICBpMzJ4NC5yZWxheGVkX2RvdF9pOHgxNl9pN3gxNl9hZGRfc1xuICAgIC8vICAgKVxuICAgIC8vICApXG4gICAgcmV0dXJuIFdlYkFzc2VtYmx5LnZhbGlkYXRlKFxuICAgICAgbmV3IFVpbnQ4QXJyYXkoW1xuICAgICAgICAwLCA5NywgMTE1LCAxMDksIDEsIDAsIDAsIDAsIDEsIDUsIDEsIDk2LCAwLCAxLCAxMjMsIDMsIDIsIDEsIDAsIDEwLCAxOSwgMSwgMTcsIDAsIDY1LCAxLCAyNTMsIDE1LCA2NSwgMiwgMjUzLFxuICAgICAgICAxNSwgNjUsIDMsIDI1MywgMTUsIDI1MywgMTQ3LCAyLCAxMSxcbiAgICAgIF0pLFxuICAgICk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGluaXRpYWxpemVXZWJBc3NlbWJseSA9IGFzeW5jIChmbGFnczogRW52LldlYkFzc2VtYmx5RmxhZ3MpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgaWYgKGluaXRpYWxpemVkKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIGlmIChpbml0aWFsaXppbmcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJtdWx0aXBsZSBjYWxscyB0byAnaW5pdGlhbGl6ZVdlYkFzc2VtYmx5KCknIGRldGVjdGVkLlwiKTtcbiAgfVxuICBpZiAoYWJvcnRlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcInByZXZpb3VzIGNhbGwgdG8gJ2luaXRpYWxpemVXZWJBc3NlbWJseSgpJyBmYWlsZWQuXCIpO1xuICB9XG5cbiAgaW5pdGlhbGl6aW5nID0gdHJ1ZTtcblxuICAvLyB3YXNtIGZsYWdzIGFyZSBhbHJlYWR5IGluaXRpYWxpemVkXG4gIGNvbnN0IHRpbWVvdXQgPSBmbGFncy5pbml0VGltZW91dCE7XG4gIGxldCBudW1UaHJlYWRzID0gZmxhZ3MubnVtVGhyZWFkcyE7XG5cbiAgLy8gZW5zdXJlIFNJTUQgaXMgc3VwcG9ydGVkXG4gIGlmIChmbGFncy5zaW1kID09PSBmYWxzZSkge1xuICAgIC8vIHNraXAgU0lNRCBmZWF0dXJlIGNoZWNraW5nIGFzIGl0IGlzIGRpc2FibGVkIGV4cGxpY2l0bHkgYnkgdXNlclxuICB9IGVsc2UgaWYgKGZsYWdzLnNpbWQgPT09ICdyZWxheGVkJykge1xuICAgIC8vIGNoZWNrIGlmIHJlbGF4ZWQgU0lNRCBpcyBzdXBwb3J0ZWRcbiAgICBpZiAoIWlzUmVsYXhlZFNpbWRTdXBwb3J0ZWQoKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZWxheGVkIFdlYkFzc2VtYmx5IFNJTUQgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgY3VycmVudCBlbnZpcm9ubWVudC4nKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIWlzU2ltZFN1cHBvcnRlZCgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdXZWJBc3NlbWJseSBTSU1EIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuJyk7XG4gIH1cblxuICBpZiAoQlVJTERfREVGUy5FTkFCTEVfSlNQSSkge1xuICAgIGlmICghKCdTdXNwZW5kaW5nJyBpbiBXZWJBc3NlbWJseSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViQXNzZW1ibHkgSlNQSSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IGVudmlyb25tZW50LicpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGNoZWNrIGlmIG11bHRpLXRocmVhZGluZyBpcyBzdXBwb3J0ZWRcbiAgY29uc3QgbXVsdGlUaHJlYWRTdXBwb3J0ZWQgPSBpc011bHRpVGhyZWFkU3VwcG9ydGVkKCk7XG4gIGlmIChudW1UaHJlYWRzID4gMSAmJiAhbXVsdGlUaHJlYWRTdXBwb3J0ZWQpIHtcbiAgICBpZiAodHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnICYmICFzZWxmLmNyb3NzT3JpZ2luSXNvbGF0ZWQpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICdlbnYud2FzbS5udW1UaHJlYWRzIGlzIHNldCB0byAnICtcbiAgICAgICAgICBudW1UaHJlYWRzICtcbiAgICAgICAgICAnLCBidXQgdGhpcyB3aWxsIG5vdCB3b3JrIHVubGVzcyB5b3UgZW5hYmxlIGNyb3NzT3JpZ2luSXNvbGF0ZWQgbW9kZS4gJyArXG4gICAgICAgICAgJ1NlZSBodHRwczovL3dlYi5kZXYvY3Jvc3Mtb3JpZ2luLWlzb2xhdGlvbi1ndWlkZS8gZm9yIG1vcmUgaW5mby4nLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgIGNvbnNvbGUud2FybihcbiAgICAgICdXZWJBc3NlbWJseSBtdWx0aS10aHJlYWRpbmcgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgY3VycmVudCBlbnZpcm9ubWVudC4gJyArICdGYWxsaW5nIGJhY2sgdG8gc2luZ2xlLXRocmVhZGluZy4nLFxuICAgICk7XG5cbiAgICAvLyBzZXQgZmxhZ3MubnVtVGhyZWFkcyB0byAxIHNvIHRoYXQgT3J0SW5pdCgpIHdpbGwgbm90IGNyZWF0ZSBhIGdsb2JhbCB0aHJlYWQgcG9vbC5cbiAgICBmbGFncy5udW1UaHJlYWRzID0gbnVtVGhyZWFkcyA9IDE7XG4gIH1cblxuICBjb25zdCB3YXNtUGF0aHMgPSBmbGFncy53YXNtUGF0aHM7XG4gIGNvbnN0IHdhc21QcmVmaXhPdmVycmlkZSA9IHR5cGVvZiB3YXNtUGF0aHMgPT09ICdzdHJpbmcnID8gd2FzbVBhdGhzIDogdW5kZWZpbmVkO1xuICBjb25zdCBtanNQYXRoT3ZlcnJpZGVGbGFnID0gKHdhc21QYXRocyBhcyBFbnYuV2FzbUZpbGVQYXRocyk/Lm1qcztcbiAgY29uc3QgbWpzUGF0aE92ZXJyaWRlID0gKG1qc1BhdGhPdmVycmlkZUZsYWcgYXMgVVJMKT8uaHJlZiA/PyBtanNQYXRoT3ZlcnJpZGVGbGFnO1xuICBjb25zdCB3YXNtUGF0aE92ZXJyaWRlRmxhZyA9ICh3YXNtUGF0aHMgYXMgRW52Lldhc21GaWxlUGF0aHMpPy53YXNtO1xuICBjb25zdCB3YXNtUGF0aE92ZXJyaWRlID0gKHdhc21QYXRoT3ZlcnJpZGVGbGFnIGFzIFVSTCk/LmhyZWYgPz8gd2FzbVBhdGhPdmVycmlkZUZsYWc7XG4gIGNvbnN0IHdhc21CaW5hcnlPdmVycmlkZSA9IGZsYWdzLndhc21CaW5hcnk7XG5cbiAgY29uc3QgW29iamVjdFVybCwgb3J0V2FzbUZhY3RvcnldID0gYXdhaXQgaW1wb3J0V2FzbU1vZHVsZShcbiAgICBtanNQYXRoT3ZlcnJpZGUsXG4gICAgd2FzbVByZWZpeE92ZXJyaWRlLFxuICAgIG51bVRocmVhZHMgPiAxLFxuICAgICEhd2FzbUJpbmFyeU92ZXJyaWRlIHx8ICEhd2FzbVBhdGhPdmVycmlkZSxcbiAgKTtcblxuICBsZXQgaXNUaW1lb3V0ID0gZmFsc2U7XG5cbiAgY29uc3QgdGFza3M6IEFycmF5PFByb21pc2U8dm9pZD4+ID0gW107XG5cbiAgLy8gcHJvbWlzZSBmb3IgdGltZW91dFxuICBpZiAodGltZW91dCA+IDApIHtcbiAgICB0YXNrcy5wdXNoKFxuICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgaXNUaW1lb3V0ID0gdHJ1ZTtcbiAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH0sIHRpbWVvdXQpO1xuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIC8vIHByb21pc2UgZm9yIG1vZHVsZSBpbml0aWFsaXphdGlvblxuICB0YXNrcy5wdXNoKFxuICAgIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZzogUGFydGlhbDxPcnRXYXNtTW9kdWxlPiA9IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBudW1iZXIgb2YgdGhyZWFkcy4gV2ViQXNzZW1ibHkgd2lsbCBjcmVhdGUgKE1vZHVsZS5udW1UaHJlYWRzIC0gMSkgd29ya2Vycy4gSWYgaXQgaXMgMSwgbm8gd29ya2VyIHdpbGwgYmVcbiAgICAgICAgICogY3JlYXRlZC5cbiAgICAgICAgICovXG4gICAgICAgIG51bVRocmVhZHMsXG4gICAgICB9O1xuXG4gICAgICBpZiAod2FzbUJpbmFyeU92ZXJyaWRlKSB7XG4gICAgICAgIC8vIFNldCBhIGN1c3RvbSBidWZmZXIgd2hpY2ggY29udGFpbnMgdGhlIFdlYkFzc2VtYmx5IGJpbmFyeS4gVGhpcyB3aWxsIHNraXAgdGhlIHdhc20gZmlsZSBmZXRjaGluZy5cbiAgICAgICAgY29uZmlnLndhc21CaW5hcnkgPSB3YXNtQmluYXJ5T3ZlcnJpZGU7XG5cbiAgICAgICAgLy8gT2ZmZXIgYW4gaW1wbGVtZW50YXRpb24gb2YgbG9jYXRlRmlsZSgpIHRoYXQgcmV0dXJucyB0aGUgZmlsZSBuYW1lIGRpcmVjdGx5LiBUaGlzIGhlbHBzIHRvIGF2b2lkIGFuIGVycm9yXG4gICAgICAgIC8vIHRocm93biBsYXRlciBmcm9tIHRoZSBmb2xsb3dpbmcgY29kZSB3aGVuIGBpbXBvcnQubWV0YS51cmxgIGlzIGEgYmxvYiBVUkw6XG4gICAgICAgIC8vIGBgYFxuICAgICAgICAvLyAgIHJldHVybiBuZXcgVVJMKFwib3J0LXdhc20tc2ltZC10aHJlYWRlZC5qc2VwLndhc21cIiwgaW1wb3J0Lm1ldGEudXJsKS5ocmVmO1xuICAgICAgICAvLyBgYGBcbiAgICAgICAgY29uZmlnLmxvY2F0ZUZpbGUgPSAoZmlsZU5hbWUpID0+IGZpbGVOYW1lO1xuICAgICAgfSBlbHNlIGlmICh3YXNtUGF0aE92ZXJyaWRlIHx8IHdhc21QcmVmaXhPdmVycmlkZSkge1xuICAgICAgICAvLyBBIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGxvY2F0ZSB0aGUgV2ViQXNzZW1ibHkgZmlsZS4gVGhlIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gdGhlIGZ1bGwgcGF0aCBvZiB0aGUgZmlsZS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gU2luY2UgRW1zY3JpcHRlbiAzLjEuNTgsIHRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWQgZm9yIHRoZSAud2FzbSBmaWxlLlxuICAgICAgICBjb25maWcubG9jYXRlRmlsZSA9IChmaWxlTmFtZSkgPT4gd2FzbVBhdGhPdmVycmlkZSA/PyB3YXNtUHJlZml4T3ZlcnJpZGUgKyBmaWxlTmFtZTtcbiAgICAgIH0gZWxzZSBpZiAobWpzUGF0aE92ZXJyaWRlICYmIG1qc1BhdGhPdmVycmlkZS5pbmRleE9mKCdibG9iOicpICE9PSAwKSB7XG4gICAgICAgIC8vIGlmIG1qcyBwYXRoIGlzIHNwZWNpZmllZCwgdXNlIGl0IGFzIHRoZSBiYXNlIHBhdGggZm9yIHRoZSAud2FzbSBmaWxlLlxuICAgICAgICBjb25maWcubG9jYXRlRmlsZSA9IChmaWxlTmFtZSkgPT4gbmV3IFVSTChmaWxlTmFtZSwgbWpzUGF0aE92ZXJyaWRlKS5ocmVmO1xuICAgICAgfSBlbHNlIGlmIChvYmplY3RVcmwpIHtcbiAgICAgICAgY29uc3QgaW5mZXJyZWRXYXNtUGF0aFByZWZpeCA9IGluZmVyV2FzbVBhdGhQcmVmaXhGcm9tU2NyaXB0U3JjKCk7XG4gICAgICAgIGlmIChpbmZlcnJlZFdhc21QYXRoUHJlZml4KSB7XG4gICAgICAgICAgLy8gaWYgdGhlIHdhc20gbW9kdWxlIGlzIHByZWxvYWRlZCwgdXNlIHRoZSBpbmZlcnJlZCB3YXNtIHBhdGggYXMgdGhlIGJhc2UgcGF0aCBmb3IgdGhlIC53YXNtIGZpbGUuXG4gICAgICAgICAgY29uZmlnLmxvY2F0ZUZpbGUgPSAoZmlsZU5hbWUpID0+IGluZmVycmVkV2FzbVBhdGhQcmVmaXggKyBmaWxlTmFtZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBvcnRXYXNtRmFjdG9yeShjb25maWcpLnRoZW4oXG4gICAgICAgIC8vIHdhc20gbW9kdWxlIGluaXRpYWxpemVkIHN1Y2Nlc3NmdWxseVxuICAgICAgICAobW9kdWxlKSA9PiB7XG4gICAgICAgICAgaW5pdGlhbGl6aW5nID0gZmFsc2U7XG4gICAgICAgICAgaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgICAgIHdhc20gPSBtb2R1bGU7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIGlmIChvYmplY3RVcmwpIHtcbiAgICAgICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwob2JqZWN0VXJsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIC8vIHdhc20gbW9kdWxlIGZhaWxlZCB0byBpbml0aWFsaXplXG4gICAgICAgICh3aGF0KSA9PiB7XG4gICAgICAgICAgaW5pdGlhbGl6aW5nID0gZmFsc2U7XG4gICAgICAgICAgYWJvcnRlZCA9IHRydWU7XG4gICAgICAgICAgcmVqZWN0KHdoYXQpO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9KSxcbiAgKTtcblxuICBhd2FpdCBQcm9taXNlLnJhY2UodGFza3MpO1xuXG4gIGlmIChpc1RpbWVvdXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFdlYkFzc2VtYmx5IGJhY2tlbmQgaW5pdGlhbGl6aW5nIGZhaWxlZCBkdWUgdG8gdGltZW91dDogJHt0aW1lb3V0fW1zYCk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBnZXRJbnN0YW5jZSA9ICgpOiBPcnRXYXNtTW9kdWxlID0+IHtcbiAgaWYgKGluaXRpYWxpemVkICYmIHdhc20pIHtcbiAgICByZXR1cm4gd2FzbTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignV2ViQXNzZW1ibHkgaXMgbm90IGluaXRpYWxpemVkIHlldC4nKTtcbn07XG5cbmV4cG9ydCBjb25zdCBkaXNwb3NlID0gKCk6IHZvaWQgPT4ge1xuICBpZiAoaW5pdGlhbGl6ZWQgJiYgIWluaXRpYWxpemluZyAmJiAhYWJvcnRlZCkge1xuICAgIC8vIFRPRE86IGN1cnJlbnRseSBcIlBUaHJlYWQudGVybWluYXRlQWxsVGhyZWFkcygpXCIgaXMgbm90IGV4cG9zZWQgaW4gdGhlIHdhc20gbW9kdWxlLlxuICAgIC8vICAgICAgIEFuZCB0aGlzIGZ1bmN0aW9uIGlzIG5vdCB5ZXQgY2FsbGVkIGJ5IGFueSBjb2RlLlxuICAgIC8vICAgICAgIElmIGl0IGlzIG5lZWRlZCBpbiB0aGUgZnV0dXJlLCB3ZSBzaG91bGQgZXhwb3NlIGl0IGluIHRoZSB3YXNtIG1vZHVsZSBhbmQgdW5jb21tZW50IHRoZSBmb2xsb3dpbmcgbGluZS5cblxuICAgIC8vIHdhc20/LlBUaHJlYWQ/LnRlcm1pbmF0ZUFsbFRocmVhZHMoKTtcbiAgICB3YXNtID0gdW5kZWZpbmVkO1xuXG4gICAgaW5pdGlhbGl6aW5nID0gZmFsc2U7XG4gICAgaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICBhYm9ydGVkID0gdHJ1ZTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZ2V0SW5zdGFuY2UgfSBmcm9tICcuL3dhc20tZmFjdG9yeSc7XG5cbmV4cG9ydCBjb25zdCBhbGxvY1dhc21TdHJpbmcgPSAoZGF0YTogc3RyaW5nLCBhbGxvY3M6IG51bWJlcltdKTogbnVtYmVyID0+IHtcbiAgY29uc3Qgd2FzbSA9IGdldEluc3RhbmNlKCk7XG5cbiAgY29uc3QgZGF0YUxlbmd0aCA9IHdhc20ubGVuZ3RoQnl0ZXNVVEY4KGRhdGEpICsgMTtcbiAgY29uc3QgZGF0YU9mZnNldCA9IHdhc20uX21hbGxvYyhkYXRhTGVuZ3RoKTtcbiAgd2FzbS5zdHJpbmdUb1VURjgoZGF0YSwgZGF0YU9mZnNldCwgZGF0YUxlbmd0aCk7XG4gIGFsbG9jcy5wdXNoKGRhdGFPZmZzZXQpO1xuXG4gIHJldHVybiBkYXRhT2Zmc2V0O1xufTtcblxuaW50ZXJmYWNlIEV4dHJhT3B0aW9uc0hhbmRsZXIge1xuICAobmFtZTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogdm9pZDtcbn1cblxuZXhwb3J0IGNvbnN0IGl0ZXJhdGVFeHRyYU9wdGlvbnMgPSAoXG4gIG9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBwcmVmaXg6IHN0cmluZyxcbiAgc2VlbjogV2Vha1NldDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sXG4gIGhhbmRsZXI6IEV4dHJhT3B0aW9uc0hhbmRsZXIsXG4pOiB2b2lkID0+IHtcbiAgaWYgKHR5cGVvZiBvcHRpb25zID09ICdvYmplY3QnICYmIG9wdGlvbnMgIT09IG51bGwpIHtcbiAgICBpZiAoc2Vlbi5oYXMob3B0aW9ucykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2lyY3VsYXIgcmVmZXJlbmNlIGluIG9wdGlvbnMnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2Vlbi5hZGQob3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgT2JqZWN0LmVudHJpZXMob3B0aW9ucykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgY29uc3QgbmFtZSA9IHByZWZpeCA/IHByZWZpeCArIGtleSA6IGtleTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgaXRlcmF0ZUV4dHJhT3B0aW9ucyh2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgbmFtZSArICcuJywgc2VlbiwgaGFuZGxlcik7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIGhhbmRsZXIobmFtZSwgdmFsdWUudG9TdHJpbmcoKSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgaGFuZGxlcihuYW1lLCB2YWx1ZSA/ICcxJyA6ICcwJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuJ3QgaGFuZGxlIGV4dHJhIGNvbmZpZyB0eXBlOiAke3R5cGVvZiB2YWx1ZX1gKTtcbiAgICB9XG4gIH0pO1xufTtcblxuLyoqXG4gKiBjaGVjayB3ZWIgYXNzZW1ibHkgQVBJJ3MgbGFzdCBlcnJvciBhbmQgdGhyb3cgZXJyb3IgaWYgYW55IGVycm9yIG9jY3VycmVkLlxuICogQHBhcmFtIG1lc3NhZ2UgYSBtZXNzYWdlIHVzZWQgd2hlbiBhbiBlcnJvciBvY2N1cnJlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IGNoZWNrTGFzdEVycm9yID0gKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQgPT4ge1xuICBjb25zdCB3YXNtID0gZ2V0SW5zdGFuY2UoKTtcblxuICBjb25zdCBzdGFjayA9IHdhc20uc3RhY2tTYXZlKCk7XG4gIHRyeSB7XG4gICAgY29uc3QgcHRyU2l6ZSA9IHdhc20uUFRSX1NJWkU7XG4gICAgY29uc3QgcGFyYW1zT2Zmc2V0ID0gd2FzbS5zdGFja0FsbG9jKDIgKiBwdHJTaXplKTtcbiAgICB3YXNtLl9PcnRHZXRMYXN0RXJyb3IocGFyYW1zT2Zmc2V0LCBwYXJhbXNPZmZzZXQgKyBwdHJTaXplKTtcbiAgICBjb25zdCBlcnJvckNvZGUgPSBOdW1iZXIod2FzbS5nZXRWYWx1ZShwYXJhbXNPZmZzZXQsIHB0clNpemUgPT09IDQgPyAnaTMyJyA6ICdpNjQnKSk7XG4gICAgY29uc3QgZXJyb3JNZXNzYWdlUG9pbnRlciA9IHdhc20uZ2V0VmFsdWUocGFyYW1zT2Zmc2V0ICsgcHRyU2l6ZSwgJyonKTtcbiAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvck1lc3NhZ2VQb2ludGVyID8gd2FzbS5VVEY4VG9TdHJpbmcoZXJyb3JNZXNzYWdlUG9pbnRlcikgOiAnJztcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bWVzc2FnZX0gRVJST1JfQ09ERTogJHtlcnJvckNvZGV9LCBFUlJPUl9NRVNTQUdFOiAke2Vycm9yTWVzc2FnZX1gKTtcbiAgfSBmaW5hbGx5IHtcbiAgICB3YXNtLnN0YWNrUmVzdG9yZShzdGFjayk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb24gfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBnZXRJbnN0YW5jZSB9IGZyb20gJy4vd2FzbS1mYWN0b3J5JztcbmltcG9ydCB7IGFsbG9jV2FzbVN0cmluZywgY2hlY2tMYXN0RXJyb3IsIGl0ZXJhdGVFeHRyYU9wdGlvbnMgfSBmcm9tICcuL3dhc20tdXRpbHMnO1xuXG5leHBvcnQgY29uc3Qgc2V0UnVuT3B0aW9ucyA9IChvcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMpOiBbbnVtYmVyLCBudW1iZXJbXV0gPT4ge1xuICBjb25zdCB3YXNtID0gZ2V0SW5zdGFuY2UoKTtcbiAgbGV0IHJ1bk9wdGlvbnNIYW5kbGUgPSAwO1xuICBjb25zdCBhbGxvY3M6IG51bWJlcltdID0gW107XG5cbiAgY29uc3QgcnVuT3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB0cnkge1xuICAgIGlmIChvcHRpb25zPy5sb2dTZXZlcml0eUxldmVsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJ1bk9wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbCA9IDI7IC8vIERlZmF1bHQgdG8gd2FybmluZ1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0eXBlb2Ygb3B0aW9ucy5sb2dTZXZlcml0eUxldmVsICE9PSAnbnVtYmVyJyB8fFxuICAgICAgIU51bWJlci5pc0ludGVnZXIob3B0aW9ucy5sb2dTZXZlcml0eUxldmVsKSB8fFxuICAgICAgb3B0aW9ucy5sb2dTZXZlcml0eUxldmVsIDwgMCB8fFxuICAgICAgb3B0aW9ucy5sb2dTZXZlcml0eUxldmVsID4gNFxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBsb2cgc2V2ZXJpdHkgbGV2ZWwgaXMgbm90IHZhbGlkOiAke29wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbH1gKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucz8ubG9nVmVyYm9zaXR5TGV2ZWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcnVuT3B0aW9ucy5sb2dWZXJib3NpdHlMZXZlbCA9IDA7IC8vIERlZmF1bHQgdG8gMFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMubG9nVmVyYm9zaXR5TGV2ZWwgIT09ICdudW1iZXInIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKG9wdGlvbnMubG9nVmVyYm9zaXR5TGV2ZWwpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGxvZyB2ZXJib3NpdHkgbGV2ZWwgaXMgbm90IHZhbGlkOiAke29wdGlvbnMubG9nVmVyYm9zaXR5TGV2ZWx9YCk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnM/LnRlcm1pbmF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBydW5PcHRpb25zLnRlcm1pbmF0ZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIGxldCB0YWdEYXRhT2Zmc2V0ID0gMDtcbiAgICBpZiAob3B0aW9ucz8udGFnICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRhZ0RhdGFPZmZzZXQgPSBhbGxvY1dhc21TdHJpbmcob3B0aW9ucy50YWcsIGFsbG9jcyk7XG4gICAgfVxuXG4gICAgcnVuT3B0aW9uc0hhbmRsZSA9IHdhc20uX09ydENyZWF0ZVJ1bk9wdGlvbnMoXG4gICAgICBydW5PcHRpb25zLmxvZ1NldmVyaXR5TGV2ZWwhLFxuICAgICAgcnVuT3B0aW9ucy5sb2dWZXJib3NpdHlMZXZlbCEsXG4gICAgICAhIXJ1bk9wdGlvbnMudGVybWluYXRlISxcbiAgICAgIHRhZ0RhdGFPZmZzZXQsXG4gICAgKTtcbiAgICBpZiAocnVuT3B0aW9uc0hhbmRsZSA9PT0gMCkge1xuICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCBjcmVhdGUgcnVuIG9wdGlvbnMuXCIpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zPy5leHRyYSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpdGVyYXRlRXh0cmFPcHRpb25zKG9wdGlvbnMuZXh0cmEsICcnLCBuZXcgV2Vha1NldDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oKSwgKGtleSwgdmFsdWUpID0+IHtcbiAgICAgICAgY29uc3Qga2V5RGF0YU9mZnNldCA9IGFsbG9jV2FzbVN0cmluZyhrZXksIGFsbG9jcyk7XG4gICAgICAgIGNvbnN0IHZhbHVlRGF0YU9mZnNldCA9IGFsbG9jV2FzbVN0cmluZyh2YWx1ZSwgYWxsb2NzKTtcblxuICAgICAgICBpZiAod2FzbS5fT3J0QWRkUnVuQ29uZmlnRW50cnkocnVuT3B0aW9uc0hhbmRsZSwga2V5RGF0YU9mZnNldCwgdmFsdWVEYXRhT2Zmc2V0KSAhPT0gMCkge1xuICAgICAgICAgIGNoZWNrTGFzdEVycm9yKGBDYW4ndCBzZXQgYSBydW4gY29uZmlnIGVudHJ5OiAke2tleX0gLSAke3ZhbHVlfS5gKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFtydW5PcHRpb25zSGFuZGxlLCBhbGxvY3NdO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKHJ1bk9wdGlvbnNIYW5kbGUgIT09IDApIHtcbiAgICAgIHdhc20uX09ydFJlbGVhc2VSdW5PcHRpb25zKHJ1bk9wdGlvbnNIYW5kbGUpO1xuICAgIH1cbiAgICBhbGxvY3MuZm9yRWFjaCgoYWxsb2MpID0+IHdhc20uX2ZyZWUoYWxsb2MpKTtcbiAgICB0aHJvdyBlO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgdHlwZSB7IEluZmVyZW5jZVNlc3Npb24gfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBnZXRJbnN0YW5jZSB9IGZyb20gJy4vd2FzbS1mYWN0b3J5JztcbmltcG9ydCB7IGFsbG9jV2FzbVN0cmluZywgY2hlY2tMYXN0RXJyb3IsIGl0ZXJhdGVFeHRyYU9wdGlvbnMgfSBmcm9tICcuL3dhc20tdXRpbHMnO1xuXG5jb25zdCBnZXRHcmFwaE9wdGltemF0aW9uTGV2ZWwgPSAoZ3JhcGhPcHRpbWl6YXRpb25MZXZlbDogc3RyaW5nIHwgdW5rbm93bik6IG51bWJlciA9PiB7XG4gIHN3aXRjaCAoZ3JhcGhPcHRpbWl6YXRpb25MZXZlbCkge1xuICAgIGNhc2UgJ2Rpc2FibGVkJzpcbiAgICAgIHJldHVybiAwO1xuICAgIGNhc2UgJ2Jhc2ljJzpcbiAgICAgIHJldHVybiAxO1xuICAgIGNhc2UgJ2V4dGVuZGVkJzpcbiAgICAgIHJldHVybiAyO1xuICAgIGNhc2UgJ2xheW91dCc6XG4gICAgICByZXR1cm4gMztcbiAgICBjYXNlICdhbGwnOlxuICAgICAgcmV0dXJuIDk5O1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGdyYXBoIG9wdGltaXphdGlvbiBsZXZlbDogJHtncmFwaE9wdGltaXphdGlvbkxldmVsfWApO1xuICB9XG59O1xuXG5jb25zdCBnZXRFeGVjdXRpb25Nb2RlID0gKGV4ZWN1dGlvbk1vZGU6ICdzZXF1ZW50aWFsJyB8ICdwYXJhbGxlbCcpOiBudW1iZXIgPT4ge1xuICBzd2l0Y2ggKGV4ZWN1dGlvbk1vZGUpIHtcbiAgICBjYXNlICdzZXF1ZW50aWFsJzpcbiAgICAgIHJldHVybiAwO1xuICAgIGNhc2UgJ3BhcmFsbGVsJzpcbiAgICAgIHJldHVybiAxO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGV4ZWN1dGlvbiBtb2RlOiAke2V4ZWN1dGlvbk1vZGV9YCk7XG4gIH1cbn07XG5cbmNvbnN0IGFwcGVuZERlZmF1bHRPcHRpb25zID0gKG9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOiB2b2lkID0+IHtcbiAgaWYgKCFvcHRpb25zLmV4dHJhKSB7XG4gICAgb3B0aW9ucy5leHRyYSA9IHt9O1xuICB9XG4gIGlmICghb3B0aW9ucy5leHRyYS5zZXNzaW9uKSB7XG4gICAgb3B0aW9ucy5leHRyYS5zZXNzaW9uID0ge307XG4gIH1cbiAgY29uc3Qgc2Vzc2lvbiA9IG9wdGlvbnMuZXh0cmEuc2Vzc2lvbiBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICBpZiAoIXNlc3Npb24udXNlX29ydF9tb2RlbF9ieXRlc19kaXJlY3RseSkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjYW1lbGNhc2VcbiAgICBzZXNzaW9uLnVzZV9vcnRfbW9kZWxfYnl0ZXNfZGlyZWN0bHkgPSAnMSc7XG4gIH1cblxuICAvLyBpZiB1c2luZyBKU0VQIHdpdGggV2ViR1BVLCBhbHdheXMgZGlzYWJsZSBtZW1vcnkgcGF0dGVyblxuICBpZiAoXG4gICAgb3B0aW9ucy5leGVjdXRpb25Qcm92aWRlcnMgJiZcbiAgICBvcHRpb25zLmV4ZWN1dGlvblByb3ZpZGVycy5zb21lKChlcCkgPT4gKHR5cGVvZiBlcCA9PT0gJ3N0cmluZycgPyBlcCA6IGVwLm5hbWUpID09PSAnd2ViZ3B1JylcbiAgKSB7XG4gICAgb3B0aW9ucy5lbmFibGVNZW1QYXR0ZXJuID0gZmFsc2U7XG4gIH1cbn07XG5cbmNvbnN0IGFwcGVuZFNlc3Npb25Db25maWcgPSAoc2Vzc2lvbk9wdGlvbnNIYW5kbGU6IG51bWJlciwga2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcsIGFsbG9jczogbnVtYmVyW10pOiB2b2lkID0+IHtcbiAgY29uc3Qga2V5RGF0YU9mZnNldCA9IGFsbG9jV2FzbVN0cmluZyhrZXksIGFsbG9jcyk7XG4gIGNvbnN0IHZhbHVlRGF0YU9mZnNldCA9IGFsbG9jV2FzbVN0cmluZyh2YWx1ZSwgYWxsb2NzKTtcbiAgaWYgKGdldEluc3RhbmNlKCkuX09ydEFkZFNlc3Npb25Db25maWdFbnRyeShzZXNzaW9uT3B0aW9uc0hhbmRsZSwga2V5RGF0YU9mZnNldCwgdmFsdWVEYXRhT2Zmc2V0KSAhPT0gMCkge1xuICAgIGNoZWNrTGFzdEVycm9yKGBDYW4ndCBzZXQgYSBzZXNzaW9uIGNvbmZpZyBlbnRyeTogJHtrZXl9IC0gJHt2YWx1ZX0uYCk7XG4gIH1cbn07XG5cbmNvbnN0IGFwcGVuZEVwT3B0aW9uID0gKGVwT3B0aW9uczogQXJyYXk8W251bWJlciwgbnVtYmVyXT4sIGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBhbGxvY3M6IG51bWJlcltdKTogdm9pZCA9PiB7XG4gIGNvbnN0IGtleURhdGFPZmZzZXQgPSBhbGxvY1dhc21TdHJpbmcoa2V5LCBhbGxvY3MpO1xuICBjb25zdCB2YWx1ZURhdGFPZmZzZXQgPSBhbGxvY1dhc21TdHJpbmcodmFsdWUsIGFsbG9jcyk7XG4gIGVwT3B0aW9ucy5wdXNoKFtrZXlEYXRhT2Zmc2V0LCB2YWx1ZURhdGFPZmZzZXRdKTtcbn07XG5cbmNvbnN0IHNldEV4ZWN1dGlvblByb3ZpZGVycyA9IGFzeW5jIChcbiAgc2Vzc2lvbk9wdGlvbnNIYW5kbGU6IG51bWJlcixcbiAgc2Vzc2lvbk9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMsXG4gIGFsbG9jczogbnVtYmVyW10sXG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgY29uc3QgZXhlY3V0aW9uUHJvdmlkZXJzID0gc2Vzc2lvbk9wdGlvbnMuZXhlY3V0aW9uUHJvdmlkZXJzITtcbiAgZm9yIChjb25zdCBlcCBvZiBleGVjdXRpb25Qcm92aWRlcnMpIHtcbiAgICBsZXQgZXBOYW1lID0gdHlwZW9mIGVwID09PSAnc3RyaW5nJyA/IGVwIDogZXAubmFtZTtcbiAgICBjb25zdCBlcE9wdGlvbnM6IEFycmF5PFtudW1iZXIsIG51bWJlcl0+ID0gW107XG5cbiAgICAvLyBjaGVjayBFUCBuYW1lXG4gICAgc3dpdGNoIChlcE5hbWUpIHtcbiAgICAgIGNhc2UgJ3dlYm5uJzpcbiAgICAgICAgZXBOYW1lID0gJ1dFQk5OJztcbiAgICAgICAgLy8gRGlzYWJsZSBRRFEgZnVzaW9uIHNvIERRL1Egbm9kZXMgYXJlIHByZXNlcnZlZCBhcyBpbmRpdmlkdWFsIG9wcyBmb3IgV2ViTk4gRVAuXG4gICAgICAgIGFwcGVuZFNlc3Npb25Db25maWcoc2Vzc2lvbk9wdGlvbnNIYW5kbGUsICdzZXNzaW9uLmRpc2FibGVfcXVhbnRfcWRxJywgJzEnLCBhbGxvY3MpO1xuICAgICAgICAvLyBGb3JjaWJseSBwcmV2ZW50IGNvbnN0YW50IGZvbGRpbmcgZnJvbSByZXBsYWNpbmcgRFEgbm9kZXMgd2l0aCBjb25zdGFudHMuXG4gICAgICAgIGFwcGVuZFNlc3Npb25Db25maWcoc2Vzc2lvbk9wdGlvbnNIYW5kbGUsICdzZXNzaW9uLmRpc2FibGVfcWRxX2NvbnN0YW50X2ZvbGRpbmcnLCAnMScsIGFsbG9jcyk7XG4gICAgICAgIGlmICh0eXBlb2YgZXAgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgY29uc3Qgd2Vibm5PcHRpb25zID0gZXAgYXMgSW5mZXJlbmNlU2Vzc2lvbi5XZWJOTkV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgICAgICAgIC8vIGNvbnN0IGNvbnRleHQgPSAod2Vibm5PcHRpb25zIGFzIEluZmVyZW5jZVNlc3Npb24uV2ViTk5PcHRpb25zV2l0aE1MQ29udGV4dCk/LmNvbnRleHQ7XG4gICAgICAgICAgY29uc3QgZGV2aWNlVHlwZSA9ICh3ZWJubk9wdGlvbnMgYXMgSW5mZXJlbmNlU2Vzc2lvbi5XZWJOTkNvbnRleHRPcHRpb25zKT8uZGV2aWNlVHlwZTtcbiAgICAgICAgICBpZiAoZGV2aWNlVHlwZSkge1xuICAgICAgICAgICAgYXBwZW5kU2Vzc2lvbkNvbmZpZyhzZXNzaW9uT3B0aW9uc0hhbmRsZSwgJ2RldmljZVR5cGUnLCBkZXZpY2VUeXBlLCBhbGxvY3MpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3dlYmdwdSc6XG4gICAgICAgIGlmICghQlVJTERfREVGUy5ESVNBQkxFX1dFQkdQVSkge1xuICAgICAgICAgIGVwTmFtZSA9ICdXZWJHUFUnO1xuICAgICAgICAgIGxldCBjdXN0b21EZXZpY2U6IEdQVURldmljZSB8IHVuZGVmaW5lZDtcblxuICAgICAgICAgIGlmICh0eXBlb2YgZXAgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCB3ZWJncHVPcHRpb25zID0gZXAgYXMgSW5mZXJlbmNlU2Vzc2lvbi5XZWJHcHVFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcblxuICAgICAgICAgICAgLy8gc2V0IGN1c3RvbSBHUFUgZGV2aWNlXG4gICAgICAgICAgICBpZiAod2ViZ3B1T3B0aW9ucy5kZXZpY2UpIHtcbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBHUFVEZXZpY2UgIT09ICd1bmRlZmluZWQnICYmIHdlYmdwdU9wdGlvbnMuZGV2aWNlIGluc3RhbmNlb2YgR1BVRGV2aWNlKSB7XG4gICAgICAgICAgICAgICAgY3VzdG9tRGV2aWNlID0gd2ViZ3B1T3B0aW9ucy5kZXZpY2U7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIEdQVSBkZXZpY2Ugc2V0IGluIFdlYkdQVSBFUCBvcHRpb25zLicpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHNldCBncmFwaCBjYXB0dXJlIG9wdGlvbiBmcm9tIHNlc3Npb24gb3B0aW9uc1xuICAgICAgICAgICAgY29uc3QgeyBlbmFibGVHcmFwaENhcHR1cmUgfSA9IHNlc3Npb25PcHRpb25zO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmFibGVHcmFwaENhcHR1cmUgPT09ICdib29sZWFuJyAmJiBlbmFibGVHcmFwaENhcHR1cmUpIHtcbiAgICAgICAgICAgICAgYXBwZW5kRXBPcHRpb24oZXBPcHRpb25zLCAnZW5hYmxlR3JhcGhDYXB0dXJlJywgJzEnLCBhbGxvY3MpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBzZXQgbGF5b3V0IG9wdGlvblxuICAgICAgICAgICAgaWYgKHR5cGVvZiB3ZWJncHVPcHRpb25zLnByZWZlcnJlZExheW91dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgYXBwZW5kRXBPcHRpb24oZXBPcHRpb25zLCAncHJlZmVycmVkTGF5b3V0Jywgd2ViZ3B1T3B0aW9ucy5wcmVmZXJyZWRMYXlvdXQsIGFsbG9jcyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHNldCBmb3JjZSBDUFUgZmFsbGJhY2sgbm9kZXNcbiAgICAgICAgICAgIGlmICh3ZWJncHVPcHRpb25zLmZvcmNlQ3B1Tm9kZU5hbWVzKSB7XG4gICAgICAgICAgICAgIGNvbnN0IG5hbWVzID0gQXJyYXkuaXNBcnJheSh3ZWJncHVPcHRpb25zLmZvcmNlQ3B1Tm9kZU5hbWVzKVxuICAgICAgICAgICAgICAgID8gd2ViZ3B1T3B0aW9ucy5mb3JjZUNwdU5vZGVOYW1lc1xuICAgICAgICAgICAgICAgIDogW3dlYmdwdU9wdGlvbnMuZm9yY2VDcHVOb2RlTmFtZXNdO1xuXG4gICAgICAgICAgICAgIGFwcGVuZEVwT3B0aW9uKGVwT3B0aW9ucywgJ2ZvcmNlQ3B1Tm9kZU5hbWVzJywgbmFtZXMuam9pbignXFxuJyksIGFsbG9jcyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHNldCB2YWxpZGF0aW9uIG1vZGVcbiAgICAgICAgICAgIGlmICh3ZWJncHVPcHRpb25zLnZhbGlkYXRpb25Nb2RlKSB7XG4gICAgICAgICAgICAgIGFwcGVuZEVwT3B0aW9uKGVwT3B0aW9ucywgJ3ZhbGlkYXRpb25Nb2RlJywgd2ViZ3B1T3B0aW9ucy52YWxpZGF0aW9uTW9kZSwgYWxsb2NzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBpbmZvID0gZ2V0SW5zdGFuY2UoKS53ZWJncHVSZWdpc3RlckRldmljZSEoY3VzdG9tRGV2aWNlKTtcbiAgICAgICAgICBpZiAoaW5mbykge1xuICAgICAgICAgICAgY29uc3QgW2RldmljZUlkLCBpbnN0YW5jZUhhbmRsZSwgZGV2aWNlSGFuZGxlXSA9IGluZm87XG4gICAgICAgICAgICBhcHBlbmRFcE9wdGlvbihlcE9wdGlvbnMsICdkZXZpY2VJZCcsIGRldmljZUlkLnRvU3RyaW5nKCksIGFsbG9jcyk7XG4gICAgICAgICAgICBhcHBlbmRFcE9wdGlvbihlcE9wdGlvbnMsICd3ZWJncHVJbnN0YW5jZScsIGluc3RhbmNlSGFuZGxlLnRvU3RyaW5nKCksIGFsbG9jcyk7XG4gICAgICAgICAgICBhcHBlbmRFcE9wdGlvbihlcE9wdGlvbnMsICd3ZWJncHVEZXZpY2UnLCBkZXZpY2VIYW5kbGUudG9TdHJpbmcoKSwgYWxsb2NzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXBOYW1lID0gJ0pTJztcbiAgICAgICAgICBpZiAodHlwZW9mIGVwICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uc3Qgd2ViZ3B1T3B0aW9ucyA9IGVwIGFzIEluZmVyZW5jZVNlc3Npb24uV2ViR3B1RXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgICAgICAgICBpZiAod2ViZ3B1T3B0aW9ucz8ucHJlZmVycmVkTGF5b3V0KSB7XG4gICAgICAgICAgICAgIGlmICh3ZWJncHVPcHRpb25zLnByZWZlcnJlZExheW91dCAhPT0gJ05DSFcnICYmIHdlYmdwdU9wdGlvbnMucHJlZmVycmVkTGF5b3V0ICE9PSAnTkhXQycpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHByZWZlcnJlZExheW91dCBtdXN0IGJlIGVpdGhlciAnTkNIVycgb3IgJ05IV0MnOiAke3dlYmdwdU9wdGlvbnMucHJlZmVycmVkTGF5b3V0fWApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGFwcGVuZFNlc3Npb25Db25maWcoc2Vzc2lvbk9wdGlvbnNIYW5kbGUsICdwcmVmZXJyZWRMYXlvdXQnLCB3ZWJncHVPcHRpb25zLnByZWZlcnJlZExheW91dCwgYWxsb2NzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd3YXNtJzpcbiAgICAgIGNhc2UgJ2NwdSc6XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBub3Qgc3VwcG9ydGVkIGV4ZWN1dGlvbiBwcm92aWRlcjogJHtlcE5hbWV9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgZXBOYW1lRGF0YU9mZnNldCA9IGFsbG9jV2FzbVN0cmluZyhlcE5hbWUsIGFsbG9jcyk7XG4gICAgY29uc3QgZXBPcHRpb25zQ291bnQgPSBlcE9wdGlvbnMubGVuZ3RoO1xuICAgIGxldCBrZXlzT2Zmc2V0ID0gMDtcbiAgICBsZXQgdmFsdWVzT2Zmc2V0ID0gMDtcbiAgICBpZiAoZXBPcHRpb25zQ291bnQgPiAwKSB7XG4gICAgICBrZXlzT2Zmc2V0ID0gZ2V0SW5zdGFuY2UoKS5fbWFsbG9jKGVwT3B0aW9uc0NvdW50ICogZ2V0SW5zdGFuY2UoKS5QVFJfU0laRSk7XG4gICAgICBhbGxvY3MucHVzaChrZXlzT2Zmc2V0KTtcbiAgICAgIHZhbHVlc09mZnNldCA9IGdldEluc3RhbmNlKCkuX21hbGxvYyhlcE9wdGlvbnNDb3VudCAqIGdldEluc3RhbmNlKCkuUFRSX1NJWkUpO1xuICAgICAgYWxsb2NzLnB1c2godmFsdWVzT2Zmc2V0KTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXBPcHRpb25zQ291bnQ7IGkrKykge1xuICAgICAgICBnZXRJbnN0YW5jZSgpLnNldFZhbHVlKGtleXNPZmZzZXQgKyBpICogZ2V0SW5zdGFuY2UoKS5QVFJfU0laRSwgZXBPcHRpb25zW2ldWzBdLCAnKicpO1xuICAgICAgICBnZXRJbnN0YW5jZSgpLnNldFZhbHVlKHZhbHVlc09mZnNldCArIGkgKiBnZXRJbnN0YW5jZSgpLlBUUl9TSVpFLCBlcE9wdGlvbnNbaV1bMV0sICcqJyk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChcbiAgICAgIChhd2FpdCBnZXRJbnN0YW5jZSgpLl9PcnRBcHBlbmRFeGVjdXRpb25Qcm92aWRlcihcbiAgICAgICAgc2Vzc2lvbk9wdGlvbnNIYW5kbGUsXG4gICAgICAgIGVwTmFtZURhdGFPZmZzZXQsXG4gICAgICAgIGtleXNPZmZzZXQsXG4gICAgICAgIHZhbHVlc09mZnNldCxcbiAgICAgICAgZXBPcHRpb25zQ291bnQsXG4gICAgICApKSAhPT0gMFxuICAgICkge1xuICAgICAgY2hlY2tMYXN0RXJyb3IoYENhbid0IGFwcGVuZCBleGVjdXRpb24gcHJvdmlkZXI6ICR7ZXBOYW1lfS5gKTtcbiAgICB9XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzZXRTZXNzaW9uT3B0aW9ucyA9IGFzeW5jIChvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8W251bWJlciwgbnVtYmVyW11dPiA9PiB7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICBsZXQgc2Vzc2lvbk9wdGlvbnNIYW5kbGUgPSAwO1xuICBjb25zdCBhbGxvY3M6IG51bWJlcltdID0gW107XG5cbiAgY29uc3Qgc2Vzc2lvbk9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBhcHBlbmREZWZhdWx0T3B0aW9ucyhzZXNzaW9uT3B0aW9ucyk7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBncmFwaE9wdGltaXphdGlvbkxldmVsID0gZ2V0R3JhcGhPcHRpbXphdGlvbkxldmVsKHNlc3Npb25PcHRpb25zLmdyYXBoT3B0aW1pemF0aW9uTGV2ZWwgPz8gJ2FsbCcpO1xuICAgIGNvbnN0IGV4ZWN1dGlvbk1vZGUgPSBnZXRFeGVjdXRpb25Nb2RlKHNlc3Npb25PcHRpb25zLmV4ZWN1dGlvbk1vZGUgPz8gJ3NlcXVlbnRpYWwnKTtcbiAgICBjb25zdCBsb2dJZERhdGFPZmZzZXQgPVxuICAgICAgdHlwZW9mIHNlc3Npb25PcHRpb25zLmxvZ0lkID09PSAnc3RyaW5nJyA/IGFsbG9jV2FzbVN0cmluZyhzZXNzaW9uT3B0aW9ucy5sb2dJZCwgYWxsb2NzKSA6IDA7XG5cbiAgICBjb25zdCBsb2dTZXZlcml0eUxldmVsID0gc2Vzc2lvbk9wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbCA/PyAyOyAvLyBEZWZhdWx0IHRvIDIgLSB3YXJuaW5nXG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGxvZ1NldmVyaXR5TGV2ZWwpIHx8IGxvZ1NldmVyaXR5TGV2ZWwgPCAwIHx8IGxvZ1NldmVyaXR5TGV2ZWwgPiA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGxvZyBzZXZlcml0eSBsZXZlbCBpcyBub3QgdmFsaWQ6ICR7bG9nU2V2ZXJpdHlMZXZlbH1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBsb2dWZXJib3NpdHlMZXZlbCA9IHNlc3Npb25PcHRpb25zLmxvZ1ZlcmJvc2l0eUxldmVsID8/IDA7IC8vIERlZmF1bHQgdG8gMCAtIHZlcmJvc2VcbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIobG9nVmVyYm9zaXR5TGV2ZWwpIHx8IGxvZ1ZlcmJvc2l0eUxldmVsIDwgMCB8fCBsb2dWZXJib3NpdHlMZXZlbCA+IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgbG9nIHZlcmJvc2l0eSBsZXZlbCBpcyBub3QgdmFsaWQ6ICR7bG9nVmVyYm9zaXR5TGV2ZWx9YCk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3B0aW1pemVkTW9kZWxGaWxlUGF0aE9mZnNldCA9XG4gICAgICB0eXBlb2Ygc2Vzc2lvbk9wdGlvbnMub3B0aW1pemVkTW9kZWxGaWxlUGF0aCA9PT0gJ3N0cmluZydcbiAgICAgICAgPyBhbGxvY1dhc21TdHJpbmcoc2Vzc2lvbk9wdGlvbnMub3B0aW1pemVkTW9kZWxGaWxlUGF0aCwgYWxsb2NzKVxuICAgICAgICA6IDA7XG5cbiAgICBzZXNzaW9uT3B0aW9uc0hhbmRsZSA9IHdhc20uX09ydENyZWF0ZVNlc3Npb25PcHRpb25zKFxuICAgICAgZ3JhcGhPcHRpbWl6YXRpb25MZXZlbCxcbiAgICAgICEhc2Vzc2lvbk9wdGlvbnMuZW5hYmxlQ3B1TWVtQXJlbmEsXG4gICAgICAhIXNlc3Npb25PcHRpb25zLmVuYWJsZU1lbVBhdHRlcm4sXG4gICAgICBleGVjdXRpb25Nb2RlLFxuICAgICAgISFzZXNzaW9uT3B0aW9ucy5lbmFibGVQcm9maWxpbmcsXG4gICAgICAwLFxuICAgICAgbG9nSWREYXRhT2Zmc2V0LFxuICAgICAgbG9nU2V2ZXJpdHlMZXZlbCxcbiAgICAgIGxvZ1ZlcmJvc2l0eUxldmVsLFxuICAgICAgb3B0aW1pemVkTW9kZWxGaWxlUGF0aE9mZnNldCxcbiAgICApO1xuICAgIGlmIChzZXNzaW9uT3B0aW9uc0hhbmRsZSA9PT0gMCkge1xuICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCBjcmVhdGUgc2Vzc2lvbiBvcHRpb25zLlwiKTtcbiAgICB9XG5cbiAgICBpZiAoc2Vzc2lvbk9wdGlvbnMuZXhlY3V0aW9uUHJvdmlkZXJzKSB7XG4gICAgICBhd2FpdCBzZXRFeGVjdXRpb25Qcm92aWRlcnMoc2Vzc2lvbk9wdGlvbnNIYW5kbGUsIHNlc3Npb25PcHRpb25zLCBhbGxvY3MpO1xuICAgIH1cblxuICAgIGlmIChzZXNzaW9uT3B0aW9ucy5lbmFibGVHcmFwaENhcHR1cmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHR5cGVvZiBzZXNzaW9uT3B0aW9ucy5lbmFibGVHcmFwaENhcHR1cmUgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGVuYWJsZUdyYXBoQ2FwdHVyZSBtdXN0IGJlIGEgYm9vbGVhbiB2YWx1ZTogJHtzZXNzaW9uT3B0aW9ucy5lbmFibGVHcmFwaENhcHR1cmV9YCk7XG4gICAgICB9XG4gICAgICBhcHBlbmRTZXNzaW9uQ29uZmlnKFxuICAgICAgICBzZXNzaW9uT3B0aW9uc0hhbmRsZSxcbiAgICAgICAgJ2VuYWJsZUdyYXBoQ2FwdHVyZScsXG4gICAgICAgIHNlc3Npb25PcHRpb25zLmVuYWJsZUdyYXBoQ2FwdHVyZS50b1N0cmluZygpLFxuICAgICAgICBhbGxvY3MsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChzZXNzaW9uT3B0aW9ucy5mcmVlRGltZW5zaW9uT3ZlcnJpZGVzKSB7XG4gICAgICBmb3IgKGNvbnN0IFtuYW1lLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoc2Vzc2lvbk9wdGlvbnMuZnJlZURpbWVuc2lvbk92ZXJyaWRlcykpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZnJlZSBkaW1lbnNpb24gb3ZlcnJpZGUgbmFtZSBtdXN0IGJlIGEgc3RyaW5nOiAke25hbWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgfHwgIU51bWJlci5pc0ludGVnZXIodmFsdWUpIHx8IHZhbHVlIDwgMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZnJlZSBkaW1lbnNpb24gb3ZlcnJpZGUgdmFsdWUgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyOiAke3ZhbHVlfWApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hbWVPZmZzZXQgPSBhbGxvY1dhc21TdHJpbmcobmFtZSwgYWxsb2NzKTtcbiAgICAgICAgaWYgKHdhc20uX09ydEFkZEZyZWVEaW1lbnNpb25PdmVycmlkZShzZXNzaW9uT3B0aW9uc0hhbmRsZSwgbmFtZU9mZnNldCwgdmFsdWUpICE9PSAwKSB7XG4gICAgICAgICAgY2hlY2tMYXN0RXJyb3IoYENhbid0IHNldCBhIGZyZWUgZGltZW5zaW9uIG92ZXJyaWRlOiAke25hbWV9IC0gJHt2YWx1ZX0uYCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2Vzc2lvbk9wdGlvbnMuZXh0cmEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaXRlcmF0ZUV4dHJhT3B0aW9ucyhzZXNzaW9uT3B0aW9ucy5leHRyYSwgJycsIG5ldyBXZWFrU2V0PFJlY29yZDxzdHJpbmcsIHVua25vd24+PigpLCAoa2V5LCB2YWx1ZSkgPT4ge1xuICAgICAgICBhcHBlbmRTZXNzaW9uQ29uZmlnKHNlc3Npb25PcHRpb25zSGFuZGxlLCBrZXksIHZhbHVlLCBhbGxvY3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFtzZXNzaW9uT3B0aW9uc0hhbmRsZSwgYWxsb2NzXTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChzZXNzaW9uT3B0aW9uc0hhbmRsZSAhPT0gMCkge1xuICAgICAgaWYgKHdhc20uX09ydFJlbGVhc2VTZXNzaW9uT3B0aW9ucyhzZXNzaW9uT3B0aW9uc0hhbmRsZSkgIT09IDApIHtcbiAgICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCByZWxlYXNlIHNlc3Npb24gb3B0aW9ucy5cIik7XG4gICAgICB9XG4gICAgfVxuICAgIGFsbG9jcy5mb3JFYWNoKChhbGxvYykgPT4gd2FzbS5fZnJlZShhbGxvYykpO1xuICAgIHRocm93IGU7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbi8vIGEgZHVtbXkgdHlwZSBkZWNsYXJhdGlvbiBmb3IgRmxvYXQxNkFycmF5IGluIGNhc2UgYW55IHBvbHlmaWxsIGlzIGF2YWlsYWJsZS5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiwgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBjb25zdCBGbG9hdDE2QXJyYXk6IGFueTtcbn1cblxuLy8gVGhpcyBmaWxlIGluY2x1ZGVzIGNvbW1vbiBkZWZpbml0aW9ucy4gVGhleSBkbyBOT1QgaGF2ZSBkZXBlbmRlbmN5IG9uIHRoZSBXZWJBc3NlbWJseSBpbnN0YW5jZS5cblxuLyoqXG4gKiBDb3BpZWQgZnJvbSBPTk5YIGRlZmluaXRpb24uIFVzZSB0aGlzIHRvIGRyb3AgZGVwZW5kZW5jeSAnb25ueF9wcm90bycgdG8gZGVjcmVhc2UgY29tcGlsZWQgLmpzIGZpbGUgc2l6ZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGVudW0gRGF0YVR5cGUge1xuICB1bmRlZmluZWQgPSAwLFxuICBmbG9hdCA9IDEsXG4gIHVpbnQ4ID0gMixcbiAgaW50OCA9IDMsXG4gIHVpbnQxNiA9IDQsXG4gIGludDE2ID0gNSxcbiAgaW50MzIgPSA2LFxuICBpbnQ2NCA9IDcsXG4gIHN0cmluZyA9IDgsXG4gIGJvb2wgPSA5LFxuICBmbG9hdDE2ID0gMTAsXG4gIGRvdWJsZSA9IDExLFxuICB1aW50MzIgPSAxMixcbiAgdWludDY0ID0gMTMsXG4gIGNvbXBsZXg2NCA9IDE0LFxuICBjb21wbGV4MTI4ID0gMTUsXG4gIGJmbG9hdDE2ID0gMTYsXG5cbiAgLy8gNC1iaXQgZGF0YS10eXBlc1xuICB1aW50NCA9IDIxLFxuICBpbnQ0ID0gMjIsXG59XG5cbi8qKlxuICogTWFwIHN0cmluZyB0ZW5zb3IgZGF0YSB0byBlbnVtIHZhbHVlXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JEYXRhVHlwZVN0cmluZ1RvRW51bSA9ICh0eXBlOiBzdHJpbmcpOiBEYXRhVHlwZSA9PiB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ2ludDgnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLmludDg7XG4gICAgY2FzZSAndWludDgnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLnVpbnQ4O1xuICAgIGNhc2UgJ2Jvb2wnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLmJvb2w7XG4gICAgY2FzZSAnaW50MTYnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLmludDE2O1xuICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICByZXR1cm4gRGF0YVR5cGUudWludDE2O1xuICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgIHJldHVybiBEYXRhVHlwZS5pbnQzMjtcbiAgICBjYXNlICd1aW50MzInOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLnVpbnQzMjtcbiAgICBjYXNlICdmbG9hdDE2JzpcbiAgICAgIHJldHVybiBEYXRhVHlwZS5mbG9hdDE2O1xuICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLmZsb2F0O1xuICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLmRvdWJsZTtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLnN0cmluZztcbiAgICBjYXNlICdpbnQ2NCc6XG4gICAgICByZXR1cm4gRGF0YVR5cGUuaW50NjQ7XG4gICAgY2FzZSAndWludDY0JzpcbiAgICAgIHJldHVybiBEYXRhVHlwZS51aW50NjQ7XG4gICAgY2FzZSAnaW50NCc6XG4gICAgICByZXR1cm4gRGF0YVR5cGUuaW50NDtcbiAgICBjYXNlICd1aW50NCc6XG4gICAgICByZXR1cm4gRGF0YVR5cGUudWludDQ7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7dHlwZX1gKTtcbiAgfVxufTtcblxuLyoqXG4gKiBNYXAgZW51bSB2YWx1ZSB0byBzdHJpbmcgdGVuc29yIGRhdGFcbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvckRhdGFUeXBlRW51bVRvU3RyaW5nID0gKHR5cGVQcm90bzogRGF0YVR5cGUpOiBUZW5zb3IuVHlwZSA9PiB7XG4gIHN3aXRjaCAodHlwZVByb3RvKSB7XG4gICAgY2FzZSBEYXRhVHlwZS5pbnQ4OlxuICAgICAgcmV0dXJuICdpbnQ4JztcbiAgICBjYXNlIERhdGFUeXBlLnVpbnQ4OlxuICAgICAgcmV0dXJuICd1aW50OCc7XG4gICAgY2FzZSBEYXRhVHlwZS5ib29sOlxuICAgICAgcmV0dXJuICdib29sJztcbiAgICBjYXNlIERhdGFUeXBlLmludDE2OlxuICAgICAgcmV0dXJuICdpbnQxNic7XG4gICAgY2FzZSBEYXRhVHlwZS51aW50MTY6XG4gICAgICByZXR1cm4gJ3VpbnQxNic7XG4gICAgY2FzZSBEYXRhVHlwZS5pbnQzMjpcbiAgICAgIHJldHVybiAnaW50MzInO1xuICAgIGNhc2UgRGF0YVR5cGUudWludDMyOlxuICAgICAgcmV0dXJuICd1aW50MzInO1xuICAgIGNhc2UgRGF0YVR5cGUuZmxvYXQxNjpcbiAgICAgIHJldHVybiAnZmxvYXQxNic7XG4gICAgY2FzZSBEYXRhVHlwZS5mbG9hdDpcbiAgICAgIHJldHVybiAnZmxvYXQzMic7XG4gICAgY2FzZSBEYXRhVHlwZS5kb3VibGU6XG4gICAgICByZXR1cm4gJ2Zsb2F0NjQnO1xuICAgIGNhc2UgRGF0YVR5cGUuc3RyaW5nOlxuICAgICAgcmV0dXJuICdzdHJpbmcnO1xuICAgIGNhc2UgRGF0YVR5cGUuaW50NjQ6XG4gICAgICByZXR1cm4gJ2ludDY0JztcbiAgICBjYXNlIERhdGFUeXBlLnVpbnQ2NDpcbiAgICAgIHJldHVybiAndWludDY0JztcbiAgICBjYXNlIERhdGFUeXBlLmludDQ6XG4gICAgICByZXR1cm4gJ2ludDQnO1xuICAgIGNhc2UgRGF0YVR5cGUudWludDQ6XG4gICAgICByZXR1cm4gJ3VpbnQ0JztcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGRhdGEgdHlwZTogJHt0eXBlUHJvdG99YCk7XG4gIH1cbn07XG5cbi8qKlxuICogZ2V0IHRlbnNvciBzaXplIGluIGJ5dGVzIGJ5IHRoZSBnaXZlbiBkYXRhIHR5cGUgYW5kIGRpbWVuc2lvbnNcbiAqIEByZXR1cm5zIHNpemUgaW4gaW50ZWdlciBvciB1bmRlZmluZWQgaWYgdGhlIGRhdGEgdHlwZSBpcyBub3Qgc3VwcG9ydGVkXG4gKi9cbmV4cG9ydCBjb25zdCBjYWxjdWxhdGVUZW5zb3JTaXplSW5CeXRlcyA9IChcbiAgZGF0ZVR5cGU6IG51bWJlcixcbiAgZGltc09yU2l6ZTogcmVhZG9ubHkgbnVtYmVyW10gfCBudW1iZXIsXG4pOiBudW1iZXIgfCB1bmRlZmluZWQgPT4ge1xuICBjb25zdCBlbGVtZW50U2l6ZSA9IFtcbiAgICAtMSwgLy8gdW5kZWZpbmVkID0gMFxuICAgIDQsIC8vIGZsb2F0ID0gMVxuICAgIDEsIC8vIHVpbnQ4ID0gMlxuICAgIDEsIC8vIGludDggPSAzXG4gICAgMiwgLy8gdWludDE2ID0gNFxuICAgIDIsIC8vIGludDE2ID0gNVxuICAgIDQsIC8vIGludDMyID0gNlxuICAgIDgsIC8vIGludDY0ID0gN1xuICAgIC0xLCAvLyBzdHJpbmcgPSA4XG4gICAgMSwgLy8gYm9vbCA9IDlcbiAgICAyLCAvLyBmbG9hdDE2ID0gMTBcbiAgICA4LCAvLyBkb3VibGUgPSAxMVxuICAgIDQsIC8vIHVpbnQzMiA9IDEyXG4gICAgOCwgLy8gdWludDY0ID0gMTNcbiAgICAtMSwgLy8gY29tcGxleDY0ID0gMTRcbiAgICAtMSwgLy8gY29tcGxleDEyOCA9IDE1XG4gICAgLTEsIC8vIGJmbG9hdDE2ID0gMTZcbiAgICAtMSwgLy8gRkxPQVQ4RTRNM0ZOID0gMTdcbiAgICAtMSwgLy8gRkxPQVQ4RTRNM0ZOVVogPSAxOFxuICAgIC0xLCAvLyBGTE9BVDhFNU0yID0gMTlcbiAgICAtMSwgLy8gRkxPQVQ4RTVNMkZOVVogPSAyMFxuICAgIDAuNSwgLy8gdWludDQgPSAyMVxuICAgIDAuNSwgLy8gaW50NCA9IDIyXG4gIF1bZGF0ZVR5cGVdO1xuXG4gIGNvbnN0IHNpemUgPSB0eXBlb2YgZGltc09yU2l6ZSA9PT0gJ251bWJlcicgPyBkaW1zT3JTaXplIDogZGltc09yU2l6ZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiLCAxKTtcbiAgcmV0dXJuIGVsZW1lbnRTaXplID4gMCA/IE1hdGguY2VpbChzaXplICogZWxlbWVudFNpemUpIDogdW5kZWZpbmVkO1xufTtcblxuLyoqXG4gKiBnZXQgdHlwZWQgYXJyYXkgY29uc3RydWN0b3IgYnkgdGhlIGdpdmVuIHRlbnNvciB0eXBlXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JUeXBlVG9UeXBlZEFycmF5Q29uc3RydWN0b3IgPSAoXG4gIHR5cGU6IFRlbnNvci5UeXBlLFxuKTpcbiAgfCBGbG9hdDMyQXJyYXlDb25zdHJ1Y3RvclxuICB8IFVpbnQ4QXJyYXlDb25zdHJ1Y3RvclxuICB8IEludDhBcnJheUNvbnN0cnVjdG9yXG4gIHwgVWludDE2QXJyYXlDb25zdHJ1Y3RvclxuICB8IEludDE2QXJyYXlDb25zdHJ1Y3RvclxuICB8IEludDMyQXJyYXlDb25zdHJ1Y3RvclxuICB8IEJpZ0ludDY0QXJyYXlDb25zdHJ1Y3RvclxuICB8IFVpbnQ4QXJyYXlDb25zdHJ1Y3RvclxuICB8IEZsb2F0NjRBcnJheUNvbnN0cnVjdG9yXG4gIHwgVWludDMyQXJyYXlDb25zdHJ1Y3RvclxuICB8IEJpZ1VpbnQ2NEFycmF5Q29uc3RydWN0b3IgPT4ge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdmbG9hdDE2JzpcbiAgICAgIC8vIGFsbG93IEZsb2F0MTZBcnJheSBwb2x5ZmlsbC5cbiAgICAgIHJldHVybiB0eXBlb2YgRmxvYXQxNkFycmF5ICE9PSAndW5kZWZpbmVkJyAmJiBGbG9hdDE2QXJyYXkuZnJvbSA/IEZsb2F0MTZBcnJheSA6IFVpbnQxNkFycmF5O1xuICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgcmV0dXJuIEZsb2F0MzJBcnJheTtcbiAgICBjYXNlICd1aW50OCc6XG4gICAgICByZXR1cm4gVWludDhBcnJheTtcbiAgICBjYXNlICdpbnQ4JzpcbiAgICAgIHJldHVybiBJbnQ4QXJyYXk7XG4gICAgY2FzZSAndWludDE2JzpcbiAgICAgIHJldHVybiBVaW50MTZBcnJheTtcbiAgICBjYXNlICdpbnQxNic6XG4gICAgICByZXR1cm4gSW50MTZBcnJheTtcbiAgICBjYXNlICdpbnQzMic6XG4gICAgICByZXR1cm4gSW50MzJBcnJheTtcbiAgICBjYXNlICdib29sJzpcbiAgICAgIHJldHVybiBVaW50OEFycmF5O1xuICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgcmV0dXJuIEZsb2F0NjRBcnJheTtcbiAgICBjYXNlICd1aW50MzInOlxuICAgICAgcmV0dXJuIFVpbnQzMkFycmF5O1xuICAgIGNhc2UgJ2ludDY0JzpcbiAgICAgIHJldHVybiBCaWdJbnQ2NEFycmF5O1xuICAgIGNhc2UgJ3VpbnQ2NCc6XG4gICAgICByZXR1cm4gQmlnVWludDY0QXJyYXk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgdHlwZTogJHt0eXBlfWApO1xuICB9XG59O1xuXG4vKipcbiAqIE1hcCBzdHJpbmcgbG9nIGxldmVsIHRvIGludGVnZXIgdmFsdWVcbiAqL1xuZXhwb3J0IGNvbnN0IGxvZ0xldmVsU3RyaW5nVG9FbnVtID0gKGxvZ0xldmVsPzogJ3ZlcmJvc2UnIHwgJ2luZm8nIHwgJ3dhcm5pbmcnIHwgJ2Vycm9yJyB8ICdmYXRhbCcpOiBudW1iZXIgPT4ge1xuICBzd2l0Y2ggKGxvZ0xldmVsKSB7XG4gICAgY2FzZSAndmVyYm9zZSc6XG4gICAgICByZXR1cm4gMDtcbiAgICBjYXNlICdpbmZvJzpcbiAgICAgIHJldHVybiAxO1xuICAgIGNhc2UgJ3dhcm5pbmcnOlxuICAgICAgcmV0dXJuIDI7XG4gICAgY2FzZSAnZXJyb3InOlxuICAgICAgcmV0dXJuIDM7XG4gICAgY2FzZSAnZmF0YWwnOlxuICAgICAgcmV0dXJuIDQ7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgbG9nZ2luZyBsZXZlbDogJHtsb2dMZXZlbH1gKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIHRoZSBnaXZlbiB0ZW5zb3IgdHlwZSBpcyBzdXBwb3J0ZWQgYnkgR1BVIGJ1ZmZlclxuICovXG5leHBvcnQgY29uc3QgaXNHcHVCdWZmZXJTdXBwb3J0ZWRUeXBlID0gKHR5cGU6IFRlbnNvci5UeXBlKTogdHlwZSBpcyBUZW5zb3IuR3B1QnVmZmVyRGF0YVR5cGVzID0+XG4gIHR5cGUgPT09ICdmbG9hdDMyJyB8fFxuICB0eXBlID09PSAnZmxvYXQxNicgfHxcbiAgdHlwZSA9PT0gJ2ludDMyJyB8fFxuICB0eXBlID09PSAnaW50NjQnIHx8XG4gIHR5cGUgPT09ICd1aW50MzInIHx8XG4gIHR5cGUgPT09ICd1aW50OCcgfHxcbiAgdHlwZSA9PT0gJ2Jvb2wnIHx8XG4gIHR5cGUgPT09ICd1aW50NCcgfHxcbiAgdHlwZSA9PT0gJ2ludDQnO1xuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgdGhlIGdpdmVuIHRlbnNvciB0eXBlIGlzIHN1cHBvcnRlZCBieSBXZWJOTiBNTFRlbnNvclxuICovXG5leHBvcnQgY29uc3QgaXNNTFRlbnNvclN1cHBvcnRlZFR5cGUgPSAodHlwZTogVGVuc29yLlR5cGUpOiB0eXBlIGlzIFRlbnNvci5NTFRlbnNvckRhdGFUeXBlcyA9PlxuICB0eXBlID09PSAnZmxvYXQzMicgfHxcbiAgdHlwZSA9PT0gJ2Zsb2F0MTYnIHx8XG4gIHR5cGUgPT09ICdpbnQzMicgfHxcbiAgdHlwZSA9PT0gJ2ludDY0JyB8fFxuICB0eXBlID09PSAndWludDMyJyB8fFxuICB0eXBlID09PSAndWludDY0JyB8fFxuICB0eXBlID09PSAnaW50OCcgfHxcbiAgdHlwZSA9PT0gJ3VpbnQ4JyB8fFxuICB0eXBlID09PSAnYm9vbCcgfHxcbiAgdHlwZSA9PT0gJ3VpbnQ0JyB8fFxuICB0eXBlID09PSAnaW50NCc7XG5cbi8qKlxuICogTWFwIHN0cmluZyBkYXRhIGxvY2F0aW9uIHRvIGludGVnZXIgdmFsdWVcbiAqL1xuZXhwb3J0IGNvbnN0IGRhdGFMb2NhdGlvblN0cmluZ1RvRW51bSA9IChsb2NhdGlvbjogVGVuc29yLkRhdGFMb2NhdGlvbik6IG51bWJlciA9PiB7XG4gIHN3aXRjaCAobG9jYXRpb24pIHtcbiAgICBjYXNlICdub25lJzpcbiAgICAgIHJldHVybiAwO1xuICAgIGNhc2UgJ2NwdSc6XG4gICAgICByZXR1cm4gMTtcbiAgICBjYXNlICdjcHUtcGlubmVkJzpcbiAgICAgIHJldHVybiAyO1xuICAgIGNhc2UgJ3RleHR1cmUnOlxuICAgICAgcmV0dXJuIDM7XG4gICAgY2FzZSAnZ3B1LWJ1ZmZlcic6XG4gICAgICByZXR1cm4gNDtcbiAgICBjYXNlICdtbC10ZW5zb3InOlxuICAgICAgcmV0dXJuIDU7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgZGF0YSBsb2NhdGlvbjogJHtsb2NhdGlvbn1gKTtcbiAgfVxufTtcblxuLyoqXG4gKiBNYXAgaW50ZWdlciBkYXRhIGxvY2F0aW9uIHRvIHN0cmluZyB2YWx1ZVxuICovXG5leHBvcnQgY29uc3QgZGF0YUxvY2F0aW9uRW51bVRvU3RyaW5nID0gKGxvY2F0aW9uOiBudW1iZXIpOiBUZW5zb3IuRGF0YUxvY2F0aW9uIHwgdW5kZWZpbmVkID0+XG4gIChbJ25vbmUnLCAnY3B1JywgJ2NwdS1waW5uZWQnLCAndGV4dHVyZScsICdncHUtYnVmZmVyJywgJ21sLXRlbnNvciddIGFzIGNvbnN0KVtsb2NhdGlvbl07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGlzTm9kZSB9IGZyb20gJy4vd2FzbS11dGlscy1lbnYnO1xuXG4vKipcbiAqIExvYWQgYSBmaWxlIGludG8gYSBVaW50OEFycmF5LlxuICpcbiAqIEBwYXJhbSBmaWxlIC0gdGhlIGZpbGUgdG8gbG9hZC4gQ2FuIGJlIGEgVVJML3BhdGgsIGEgQmxvYiwgYW4gQXJyYXlCdWZmZXIsIG9yIGEgVWludDhBcnJheS5cbiAqIEByZXR1cm5zIGEgVWludDhBcnJheSBjb250YWluaW5nIHRoZSBmaWxlIGRhdGEuXG4gKi9cbmV4cG9ydCBjb25zdCBsb2FkRmlsZSA9IGFzeW5jIChmaWxlOiBzdHJpbmcgfCBCbG9iIHwgQXJyYXlCdWZmZXJMaWtlIHwgVWludDhBcnJheSk6IFByb21pc2U8VWludDhBcnJheT4gPT4ge1xuICBpZiAodHlwZW9mIGZpbGUgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKGlzTm9kZSkge1xuICAgICAgLy8gbG9hZCBmaWxlIGludG8gQXJyYXlCdWZmZXIgaW4gTm9kZS5qc1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyByZWFkRmlsZSB9ID0gcmVxdWlyZSgnbm9kZTpmcy9wcm9taXNlcycpO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYXdhaXQgcmVhZEZpbGUoZmlsZSkpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoZS5jb2RlID09PSAnRVJSX0ZTX0ZJTEVfVE9PX0xBUkdFJykge1xuICAgICAgICAgIC8vIGZpbGUgaXMgdG9vIGxhcmdlLCB1c2UgZnMuY3JlYXRlUmVhZFN0cmVhbSBpbnN0ZWFkXG4gICAgICAgICAgY29uc3QgeyBjcmVhdGVSZWFkU3RyZWFtIH0gPSByZXF1aXJlKCdub2RlOmZzJyk7XG4gICAgICAgICAgY29uc3Qgc3RyZWFtID0gY3JlYXRlUmVhZFN0cmVhbShmaWxlKTtcbiAgICAgICAgICBjb25zdCBjaHVua3M6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2Ygc3RyZWFtKSB7XG4gICAgICAgICAgICBjaHVua3MucHVzaChjaHVuayk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShCdWZmZXIuY29uY2F0KGNodW5rcykpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGxvYWQgZmlsZSBpbnRvIEFycmF5QnVmZmVyIGluIGJyb3dzZXJzXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGZpbGUpO1xuICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGZhaWxlZCB0byBsb2FkIGV4dGVybmFsIGRhdGEgZmlsZTogJHtmaWxlfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY29udGVudExlbmd0aEhlYWRlciA9IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdDb250ZW50LUxlbmd0aCcpO1xuICAgICAgY29uc3QgZmlsZVNpemUgPSBjb250ZW50TGVuZ3RoSGVhZGVyID8gcGFyc2VJbnQoY29udGVudExlbmd0aEhlYWRlciwgMTApIDogMDtcbiAgICAgIGlmIChmaWxlU2l6ZSA8IDEwNzM3NDE4MjQgLyogMUdCICovKSB7XG4gICAgICAgIC8vIHdoZW4gQ29udGVudC1MZW5ndGggaGVhZGVyIGlzIG5vdCBzZXQsIHdlIGNhbm5vdCBkZXRlcm1pbmUgdGhlIGZpbGUgc2l6ZS4gV2UgYXNzdW1lIGl0IGlzIHNtYWxsIGVub3VnaCB0b1xuICAgICAgICAvLyBsb2FkIGludG8gbWVtb3J5LlxuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBmaWxlIGlzIHRvbyBsYXJnZSwgdXNlIHN0cmVhbSBpbnN0ZWFkXG4gICAgICAgIGlmICghcmVzcG9uc2UuYm9keSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZmFpbGVkIHRvIGxvYWQgZXh0ZXJuYWwgZGF0YSBmaWxlOiAke2ZpbGV9LCBubyByZXNwb25zZSBib2R5LmApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRlciA9IHJlc3BvbnNlLmJvZHkuZ2V0UmVhZGVyKCk7XG5cbiAgICAgICAgbGV0IGJ1ZmZlcjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyB0cnkgdG8gY3JlYXRlIEFycmF5QnVmZmVyIGRpcmVjdGx5XG4gICAgICAgICAgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKGZpbGVTaXplKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgUmFuZ2VFcnJvcikge1xuICAgICAgICAgICAgLy8gdXNlIFdlYkFzc2VtYmx5IE1lbW9yeSB0byBhbGxvY2F0ZSBsYXJnZXIgQXJyYXlCdWZmZXJcbiAgICAgICAgICAgIGNvbnN0IHBhZ2VzID0gTWF0aC5jZWlsKGZpbGVTaXplIC8gNjU1MzYpO1xuICAgICAgICAgICAgYnVmZmVyID0gbmV3IFdlYkFzc2VtYmx5Lk1lbW9yeSh7IGluaXRpYWw6IHBhZ2VzLCBtYXhpbXVtOiBwYWdlcyB9KS5idWZmZXI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG9mZnNldCA9IDA7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcbiAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGNodW5rU2l6ZSA9IHZhbHVlLmJ5dGVMZW5ndGg7XG4gICAgICAgICAgY29uc3QgY2h1bmsgPSBuZXcgVWludDhBcnJheShidWZmZXIsIG9mZnNldCwgY2h1bmtTaXplKTtcbiAgICAgICAgICBjaHVuay5zZXQodmFsdWUpO1xuICAgICAgICAgIG9mZnNldCArPSBjaHVua1NpemU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGJ1ZmZlciwgMCwgZmlsZVNpemUpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChmaWxlIGluc3RhbmNlb2YgQmxvYikge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheShhd2FpdCBmaWxlLmFycmF5QnVmZmVyKCkpO1xuICB9IGVsc2UgaWYgKGZpbGUgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgcmV0dXJuIGZpbGU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGZpbGUpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBFbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBsb2dMZXZlbFN0cmluZ1RvRW51bSB9IGZyb20gJy4uL3dhc20tY29tbW9uJztcblxudHlwZSBMb2dMZXZlbCA9IE5vbk51bGxhYmxlPEVudlsnbG9nTGV2ZWwnXT47XG50eXBlIE1lc3NhZ2VTdHJpbmcgPSBzdHJpbmc7XG50eXBlIE1lc3NhZ2VGdW5jdGlvbiA9ICgpID0+IHN0cmluZztcbnR5cGUgTWVzc2FnZSA9IE1lc3NhZ2VTdHJpbmcgfCBNZXNzYWdlRnVuY3Rpb247XG5cbmNvbnN0IGxvZ0xldmVsUHJlZml4ID0gWydWJywgJ0knLCAnVycsICdFJywgJ0YnXTtcblxuY29uc3QgZG9Mb2cgPSAobGV2ZWw6IG51bWJlciwgbWVzc2FnZTogc3RyaW5nKTogdm9pZCA9PiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gIGNvbnNvbGUubG9nKGBbJHtsb2dMZXZlbFByZWZpeFtsZXZlbF19LCR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfV0ke21lc3NhZ2V9YCk7XG59O1xuXG5sZXQgY29uZmlnTG9nTGV2ZWw6IExvZ0xldmVsIHwgdW5kZWZpbmVkO1xubGV0IGRlYnVnOiBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG5leHBvcnQgY29uc3QgY29uZmlndXJlTG9nZ2VyID0gKCRjb25maWdMb2dMZXZlbDogTG9nTGV2ZWwsICRkZWJ1ZzogYm9vbGVhbik6IHZvaWQgPT4ge1xuICBjb25maWdMb2dMZXZlbCA9ICRjb25maWdMb2dMZXZlbDtcbiAgZGVidWcgPSAkZGVidWc7XG59O1xuXG4vKipcbiAqIEEgc2ltcGxlIGxvZ2dpbmcgdXRpbGl0eSB0byBsb2cgbWVzc2FnZXMgdG8gdGhlIGNvbnNvbGUuXG4gKi9cbmV4cG9ydCBjb25zdCBMT0cgPSAobG9nTGV2ZWw6IExvZ0xldmVsLCBtc2c6IE1lc3NhZ2UpOiB2b2lkID0+IHtcbiAgY29uc3QgbWVzc2FnZUxldmVsID0gbG9nTGV2ZWxTdHJpbmdUb0VudW0obG9nTGV2ZWwpO1xuICBjb25zdCBjb25maWdMZXZlbCA9IGxvZ0xldmVsU3RyaW5nVG9FbnVtKGNvbmZpZ0xvZ0xldmVsKTtcbiAgaWYgKG1lc3NhZ2VMZXZlbCA+PSBjb25maWdMZXZlbCkge1xuICAgIGRvTG9nKG1lc3NhZ2VMZXZlbCwgdHlwZW9mIG1zZyA9PT0gJ2Z1bmN0aW9uJyA/IG1zZygpIDogbXNnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBBIHNpbXBsZSBsb2dnaW5nIHV0aWxpdHkgdG8gbG9nIG1lc3NhZ2VzIHRvIHRoZSBjb25zb2xlLiBPbmx5IGxvZ3Mgd2hlbiBkZWJ1ZyBpcyBlbmFibGVkLlxuICovXG5leHBvcnQgY29uc3QgTE9HX0RFQlVHOiB0eXBlb2YgTE9HID0gKC4uLmFyZ3M6IFBhcmFtZXRlcnM8dHlwZW9mIExPRz4pID0+IHtcbiAgaWYgKGRlYnVnKSB7XG4gICAgTE9HKC4uLmFyZ3MpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wYXJhbS1yZWFzc2lnbiAqL1xuXG5leHBvcnQgY2xhc3MgTWF0TXVsVXRpbCB7XG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHNoYXBlIHdoZW4gbWF0cml4IG11bHRpcGxpY2F0aW9uXG4gICAqIEBwYXJhbSBhIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQS4gU2hvdWxkIGJlIGEgdHVwbGUgb2YgMiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gYiBUaGUgc2hhcGUgb2YgdGVuc29yIEIuIFNob3VsZCBiZSBhIHR1cGxlIG9mIDIgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHJldHVybnMgVGhlIGV4cGVjdGVkIHNoYXBlIG9mIHRoZSByZXN1bHQsIG9yIHVuZGVmaW5lZCBpZiBOL0FcbiAgICovXG4gIHN0YXRpYyBjYWxjTWF0TXVsU2hhcGUoYTogW251bWJlciwgbnVtYmVyXSwgYjogW251bWJlciwgbnVtYmVyXSk6IFtudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBhWzFdICE9PSBiWzBdID8gdW5kZWZpbmVkIDogW2FbMF0sIGJbMV1dO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBCcm9hZGNhc3RVdGlsIHtcbiAgLyoqXG4gICAqIENhbGN1bGF0ZSB0aGUgZXhwZWN0ZWQgc2hhcGUgd2hlbiBicm9hZGNhc3RpbmcgMiB0ZW5zb3JzXG4gICAqIEBwYXJhbSBhIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQS4gU2hvdWxkIGJlIGFuIGFycmF5IG9mIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEBwYXJhbSBiIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQi4gU2hvdWxkIGJlIGFuIGFycmF5IG9mIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEBwYXJhbSBpc01hdE11bCBXaGV0aGVyIHRoZSBvcGVyYXRpb24gaXMgTWF0TXVsXG4gICAqIEByZXR1cm5zIFRoZSBleHBlY3RlZCBzaGFwZSBvZiB0aGUgcmVzdWx0LCBvciB1bmRlZmluZWQgaWYgTi9BXG4gICAqL1xuICBzdGF0aWMgY2FsY1NoYXBlKFxuICAgIGFkaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBiZGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgaXNNYXRNdWwgPSBmYWxzZSxcbiAgKTogcmVhZG9ubHkgbnVtYmVyW10gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGFyYW5rID0gYWRpbXMubGVuZ3RoO1xuICAgIGNvbnN0IGJyYW5rID0gYmRpbXMubGVuZ3RoO1xuICAgIGlmIChhcmFuayA9PT0gMCkge1xuICAgICAgcmV0dXJuIGJkaW1zO1xuICAgIH1cbiAgICBpZiAoYnJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBhZGltcztcbiAgICB9XG4gICAgY29uc3QgY3JhbmsgPSBNYXRoLm1heChhZGltcy5sZW5ndGgsIGJkaW1zLmxlbmd0aCk7XG4gICAgY29uc3QgY2RpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPihjcmFuayk7XG5cbiAgICAvLyBjYWxjdWxhdGUgdGhlIGxhc3QgMiBkaW1lbnNpb24gaWYgaXQgaXMgTWF0TXVsXG4gICAgaWYgKGlzTWF0TXVsKSB7XG4gICAgICBpZiAoYXJhbmsgPCAyIHx8IGJyYW5rIDwgMikge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY29uc3QgY1NoYXBlTWF0TXVsID0gTWF0TXVsVXRpbC5jYWxjTWF0TXVsU2hhcGUoXG4gICAgICAgIFthZGltc1thcmFuayAtIDJdLCBhZGltc1thcmFuayAtIDFdXSxcbiAgICAgICAgW2JkaW1zW2JyYW5rIC0gMl0sIGJkaW1zW2JyYW5rIC0gMV1dLFxuICAgICAgKTtcbiAgICAgIGlmIChjU2hhcGVNYXRNdWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgW2NkaW1zW2NyYW5rIC0gMl0sIGNkaW1zW2NyYW5rIC0gMV1dID0gY1NoYXBlTWF0TXVsO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSBpc01hdE11bCA/IDMgOiAxOyBpIDw9IGNyYW5rOyBpKyspIHtcbiAgICAgIGNvbnN0IGFMZW4gPSBhcmFuayAtIGkgPCAwID8gMSA6IGFkaW1zW2FyYW5rIC0gaV07XG4gICAgICBjb25zdCBiTGVuID0gYnJhbmsgLSBpIDwgMCA/IDEgOiBiZGltc1ticmFuayAtIGldO1xuXG4gICAgICBpZiAoYUxlbiAhPT0gYkxlbiAmJiBhTGVuID4gMSAmJiBiTGVuID4gMSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY29uc3QgbWF4ID0gTWF0aC5tYXgoYUxlbiwgYkxlbik7XG4gICAgICBpZiAoYUxlbiAmJiBiTGVuKSB7XG4gICAgICAgIGNkaW1zW2NyYW5rIC0gaV0gPSBNYXRoLm1heChhTGVuLCBiTGVuKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHdoZW4gZWl0aGVyIGFMZW4gb3IgYkxlbiBpcyAwLCB0aGUgb3RoZXIgc2hvdWxkIGJlIGVpdGhlciAwIG9yIDEsIG90aGVyd2lzZSBpdCBpcyBub3QgYnJvYWRjYXN0YWJsZS5cbiAgICAgICAgaWYgKG1heCA+IDEpIHtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIGNkaW1zW2NyYW5rIC0gaV0gPSAwO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjZGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgaWYgYSBzaGFwZSBpcyB1bmlkaXJlY3Rpb25hbCBicm9hZGNhc3RhYmxlIHRvIGFub3RoZXIgc2hhcGVcbiAgICogQHBhcmFtIHNoYXBlIFRoZSBpbnB1dCBzaGFwZVxuICAgKiBAcGFyYW0gZmluYWxTaGFwZSBUaGUgZGVzaXJlZCBzaGFwZSBhZnRlciBicm9hZGNhc3RpbmdcbiAgICovXG4gIHN0YXRpYyBpc1ZhbGlkQnJvYWRjYXN0KHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgZmluYWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiBib29sZWFuIHtcbiAgICAvLyBhbGlnbiBzaGFwZSB0byB0aGUgcmlnaHRcbiAgICBjb25zdCBpbnB1dFJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgZmluYWxSYW5rID0gZmluYWxTaGFwZS5sZW5ndGg7XG4gICAgaWYgKGlucHV0UmFuayA+IGZpbmFsUmFuaykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSBpbnB1dFJhbms7IGkrKykge1xuICAgICAgaWYgKHNoYXBlW2lucHV0UmFuayAtIGldICE9PSAxICYmIHNoYXBlW2lucHV0UmFuayAtIGldICE9PSBmaW5hbFNoYXBlW2ZpbmFsUmFuayAtIGldKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNoYXBlVXRpbCB7XG4gIC8qKlxuICAgKiBjYWxjdWxhdGUgdGhlIHNpemUgKG51bWJlciBvZiBlbGVtZW50cylcbiAgICovXG4gIHN0YXRpYyBzaXplKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyIHtcbiAgICByZXR1cm4gU2hhcGVVdGlsLmdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltcywgMCwgZGltcy5sZW5ndGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIGNvbnZlcnQgZGltcyBjb3JyZXNwb25kaW5nIHRvIHR5cGUgY2hhbmdlIHRvIHBhY2suIGV4LiB1aW50OCBkYXRhIHRvIHVpbnQzMlxuICAgKi9cbiAgc3RhdGljIGNvbnZlcnRTaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgc2l6ZSA9IDQpOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3QgcmFuayA9IGRpbXMubGVuZ3RoO1xuICAgIGlmIChyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IG5ld0RpbXMgPSBuZXcgQXJyYXkocmFuayk7XG4gICAgbGV0IGkgPSByYW5rIC0gMTtcbiAgICB3aGlsZSAoaSA+PSAwKSB7XG4gICAgICBpZiAoZGltc1tpXSAlIHNpemUgPT09IDApIHtcbiAgICAgICAgbmV3RGltc1tpXSA9IGRpbXNbaV0gLyBzaXplO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChzaXplICUgZGltc1tpXSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBjb252ZXJ0IHNoYXBlJyk7XG4gICAgICB9XG4gICAgICBuZXdEaW1zW2ldID0gMTtcbiAgICAgIHNpemUgLz0gZGltc1tpXTtcbiAgICAgIGktLTtcbiAgICB9XG4gICAgZm9yIChpLS07IGkgPj0gMDsgaS0tKSB7XG4gICAgICBuZXdEaW1zW2ldID0gZGltc1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIG5ld0RpbXM7XG4gIH1cblxuICAvKipcbiAgICogY2FsY3VsYXRlIHRoZSBzaXplIChudW1iZXIgb2YgZWxlbWVudHMpIGZyb20gdGhlIGdpdmVuIGF4aXMgKGluY2x1c2l2ZSlcbiAgICovXG4gIHN0YXRpYyBzaXplRnJvbURpbWVuc2lvbihkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhpczogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoYXhpcyA8IDAgfHwgYXhpcyA+IGRpbXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgZGltZW5zaW9uIG9mICR7YXhpc30gZm9yIHNpemVGcm9tRGltZW5zaW9uIGFzIFRlbnNvciBoYXMgJHtkaW1zLmxlbmd0aH0gZGltZW5zaW9ucy5gKTtcbiAgICB9XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5nZXRTaXplRnJvbURpbWVuc2lvblJhbmdlKGRpbXMsIGF4aXMsIGRpbXMubGVuZ3RoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBjYWxjdWxhdGUgdGhlIHNpemUgKG51bWJlciBvZiBlbGVtZW50cykgdG8gdGhlIGdpdmVuIGF4aXMgKGV4Y2x1c2l2ZSlcbiAgICovXG4gIHN0YXRpYyBzaXplVG9EaW1lbnNpb24oZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPCAwIHx8IGF4aXMgPiBkaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIGRpbWVuc2lvbiBvZiAke2F4aXN9IGZvciBzaXplVG9EaW1lbnNpb24gYXMgVGVuc29yIGhhcyAke2RpbXMubGVuZ3RofSBkaW1lbnNpb25zLmApO1xuICAgIH1cbiAgICByZXR1cm4gU2hhcGVVdGlsLmdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltcywgMCwgYXhpcyk7XG4gIH1cblxuICAvKipcbiAgICogY2FsY3VsYXRlIHRoZSBzaXplIChudW1iZXIgb2YgZWxlbWVudHMpIGZyb20gYW5kIHRvIHRoZSBnaXZlbiBheGlzIFtzdGFydCwgZW5kKVxuICAgKi9cbiAgc3RhdGljIGdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgc2l6ZSA9IDE7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgIC8vIHNhZmV0eSBjaGVjayBhcyB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgbXVsdGlwbGUgb3RoZXIgbWV0aG9kcyByZXF1aXJpbmcgc2l6ZS5cbiAgICAgIC8vIHNpemUgY2Fubm90IGJlIG5lZ2F0aXZlLlxuICAgICAgaWYgKGRpbXNbaV0gPCAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAnY2Fubm90IGdldCB2YWxpZCBzaXplIGZyb20gc3BlY2lmaWVkIGRpbWVuc2lvbiByYW5nZS4gTW9zdCBsaWtlbHkgdGhlIHJhbmdlIGNvbnRhaW5zIG5lZ2F0aXZlIHZhbHVlcyBpbiB0aGVtLicsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBzaXplICo9IE51bWJlcihkaW1zW2ldKTtcbiAgICB9XG4gICAgcmV0dXJuIHNpemU7XG4gIH1cblxuICBzdGF0aWMgY29tcHV0ZVN0cmlkZXMoZGltczogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3QgcmFuayA9IGRpbXMubGVuZ3RoO1xuICAgIGlmIChyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfSBlbHNlIGlmIChyYW5rID09PSAxKSB7XG4gICAgICByZXR1cm4gWzFdO1xuICAgIH1cbiAgICBjb25zdCBzdHJpZGVzID0gbmV3IEFycmF5KHJhbmspO1xuICAgIHN0cmlkZXNbcmFuayAtIDFdID0gMTtcbiAgICBzdHJpZGVzW3JhbmsgLSAyXSA9IGRpbXNbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIGRpbXNbaSArIDFdO1xuICAgIH1cbiAgICByZXR1cm4gc3RyaWRlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBub3JtYWxpemUgYXhpcyBvZiByYW5nZSBbLXIsIHIpIGludG8gWzAsIHIpLlxuICAgKi9cbiAgc3RhdGljIG5vcm1hbGl6ZUF4aXMoYXhpczogbnVtYmVyLCB0ZW5zb3JSYW5rOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChheGlzIDwgLXRlbnNvclJhbmsgJiYgYXhpcyA+PSB0ZW5zb3JSYW5rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc3VwcG9ydGVkIGF4aXMgZm9yIHRoaXMgb3BlcmF0aW9uLicpO1xuICAgIH1cbiAgICByZXR1cm4gYXhpcyA8IDAgPyBheGlzICsgdGVuc29yUmFuayA6IGF4aXM7XG4gIH1cblxuICBzdGF0aWMgbm9ybWFsaXplQXhlcyhheGVzOiByZWFkb25seSBudW1iZXJbXSwgdGVuc29yUmFuaz86IG51bWJlcik6IG51bWJlcltdIHtcbiAgICByZXR1cm4gYXhlcy5tYXAoKHgpID0+IHRoaXMubm9ybWFsaXplQXhpcyh4LCB0ZW5zb3JSYW5rID8/IGF4ZXMubGVuZ3RoKSk7XG4gIH1cblxuICAvKipcbiAgICogU29ydHMgYSBnaXZlbiBhcnJheSBiYXNlZCBvbiB0aGUgaW5kaWNlcyBpbiB0aGUgUGVybSBhcnJheVxuICAgKiBVc2VkIGluIFRyYW5zcG9zZVxuICAgKiBAcGFyYW0gYSBBcnJheSB0byBiZSBzb3J0ZWQgc3VjaCBhcyBkaW1zIG9yIHN0cmlkZXNcbiAgICogQHBhcmFtIHBlcm0gUGVybSBnaXZlbjsgaWYgbnVsbCBhIHdpbGwgYmUgcmV2ZXJzZWRcbiAgICovXG4gIHN0YXRpYyBzb3J0QmFzZWRPblBlcm0oYTogcmVhZG9ubHkgbnVtYmVyW10sIHBlcm0/OiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBpZiAocGVybSkge1xuICAgICAgcmV0dXJuIHBlcm0ubWFwKCh2KSA9PiBhW3ZdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGEuc2xpY2UoKS5yZXZlcnNlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhZHMgYSBnaXZlbiBzaGFwZSBhY2NvcmRpbmcgdG8gdGhlIHBhZGRpbmcgdmFsdWVzXG4gICAqIEBwYXJhbSBkaW1zIHNoYXBlIG9mIHRoZSBUZW5zb3IgdG8gYmUgcGFkZGVkXG4gICAqIEBwYXJhbSBwYWQgcGFkIHZhbHVlc1xuICAgKi9cbiAgc3RhdGljIHBhZFNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBwYWQ6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IHJhbmsgPSBkaW1zLmxlbmd0aDtcbiAgICByZXR1cm4gZGltcy5tYXAoKHYsIGkpID0+IHYgKyBwYWRbaV0gKyBwYWRbaSArIHJhbmtdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIGlmIHRoZSB0d28gc2hhcGVzIGFyZSBpZGVudGljYWxcbiAgICogQHBhcmFtIHNoYXBlMVxuICAgKiBAcGFyYW0gc2hhcGUyXG4gICAqL1xuICBzdGF0aWMgYXJlRXF1YWwoc2hhcGUxOiByZWFkb25seSBudW1iZXJbXSwgc2hhcGUyOiByZWFkb25seSBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICAgIGlmIChzaGFwZTEubGVuZ3RoICE9PSBzaGFwZTIubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBzaGFwZTEuZXZlcnkoKHYsIGkpID0+IHYgPT09IHNoYXBlMltpXSk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFBvb2xDb252VXRpbCB7XG4gIC8qKlxuICAgKiBBZGp1c3QgdGhlIGtlcm5lbCwgc3RyaWRlcywgcGFkcyB0byBjb3JyZWN0IHJhbmsuIFNldCB0byBkZWZhdWx0IHZhbHVlIGlmIG5vdCBwcmVzZW50XG4gICAqIEBwYXJhbSBpc0dsb2JhbE9wZXJhdG9yIElmIHRydWUsIHBlcmZvcm0gZ2xvYmFsIHBvb2xpbmcuXG4gICAqIEBwYXJhbSBpbnB1dERpbXMgVGhlIGlucHV0IHRlbnNvciBkaW1lbnNpb24uXG4gICAqIEBwYXJhbSBrZXJuZWxTaGFwZSBUaGUgc2l6ZSBvZiB0aGUga2VybmVsIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIHN0cmlkZXMgU3RyaWRlIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGRpbGF0aW9ucyBEaWxhdGlvbiBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBwYWRzIFBhZGRpbmcgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZGluZyBhbG9uZyBlYWNoIGF4aXMuXG4gICAqL1xuICBzdGF0aWMgYWRqdXN0UG9vbEF0dHJpYnV0ZXMoXG4gICAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGtlcm5lbFNoYXBlOiBudW1iZXJbXSxcbiAgICBzdHJpZGVzOiBudW1iZXJbXSxcbiAgICBkaWxhdGlvbnM6IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICApOiB2b2lkIHtcbiAgICBpZiAoIWlzR2xvYmFsT3BlcmF0b3IgJiYga2VybmVsU2hhcGUubGVuZ3RoICE9PSBpbnB1dERpbXMubGVuZ3RoIC0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2Ygc3BlY2lmaWVkIGtlcm5lbCBzaGFwZXMgc2hvdWxkIGJlIDIgbGVzcyB0aGFuIGxlbmd0aCBvZiBpbnB1dCBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgaWYgKGlzR2xvYmFsT3BlcmF0b3IpIHtcbiAgICAgIC8vIGFkanVzdCBrZXJuZWwgc2hhcGUgdG8gY292ZXIgdGhlIGlucHV0IGRpbXNcbiAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGlucHV0RGltcy5sZW5ndGggLSAyOyBkaW0rKykge1xuICAgICAgICBpZiAoZGltID49IGtlcm5lbFNoYXBlLmxlbmd0aCkge1xuICAgICAgICAgIGtlcm5lbFNoYXBlLnB1c2goaW5wdXREaW1zW2RpbSArIDJdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBrZXJuZWxTaGFwZVtkaW1dID0gaW5wdXREaW1zW2RpbSArIDJdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYWRqdXN0IHN0cmlkZXMgbGVuZ3RoIHRvIG1hdGNoIGtlcm5lbCBzaGFwZSBsZW5ndGhcbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBrZXJuZWxTaGFwZS5sZW5ndGg7IGRpbSsrKSB7XG4gICAgICBpZiAoZGltIDwgc3RyaWRlcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHN0cmlkZXNbZGltXSA8IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0cmlkZXMgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0cmlkZXMucHVzaCgxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhZGp1c3QgZGlsYXRpb24gdmFsdWVcbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBrZXJuZWxTaGFwZS5sZW5ndGg7IGRpbSsrKSB7XG4gICAgICBpZiAoZGltIDwgZGlsYXRpb25zLmxlbmd0aCkge1xuICAgICAgICBpZiAoZGlsYXRpb25zW2RpbV0gPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkaWxhdGlvbnMgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRpbGF0aW9ucy5wdXNoKDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkanVzdCBwYWRzIGxlbmd0aCB0byBtYXRjaCAyICoga2VybmVsIHNoYXBlIGxlbmd0aFxuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGtlcm5lbFNoYXBlLmxlbmd0aCAqIDI7IGRpbSsrKSB7XG4gICAgICBpZiAoZGltIDwgcGFkcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHBhZHNbZGltXSA8IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhZCBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFkcy5wdXNoKDApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNhbml0eSBjaGVja3MgZm9yIHZhbHVlcyBpbiBrZXJuZWwgc2hhcGVzIGFuZCBwYWRzXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoOyBkaW0rKykge1xuICAgICAgaWYgKGtlcm5lbFNoYXBlW2RpbV0gPD0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2tlcm5lbCBzaGFwZXMgbmVlZCB0byBiZSBncmVhdGVyIHRoYW4gMCcpO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFkc1tkaW1dID49IGtlcm5lbFNoYXBlW2RpbV0gfHwgcGFkc1tkaW0gKyBrZXJuZWxTaGFwZS5sZW5ndGhdID49IGtlcm5lbFNoYXBlW2RpbV0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwYWRzIHNob3VsZCBiZSBzbWFsbGVyIHRoYW4ga2VybmVsJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gYWRqdXN0IHBhZCB2YWx1ZXMgYmFzZWQgb24gJ2F1dG9QYWQnIGF0dHJpYnV0ZVxuICBzdGF0aWMgYWRqdXN0UGFkc0Jhc2VkT25BdXRvUGFkKFxuICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgaXNDaGFubmVsTGFzdDogYm9vbGVhbixcbiAgICBhdXRvUGFkPzogc3RyaW5nLFxuICApOiB2b2lkIHtcbiAgICBpZiAoIWF1dG9QYWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocGFkcy5sZW5ndGggIT09IDIgKiAoaW5wdXREaW1zLmxlbmd0aCAtIDIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2xlbmd0aCBvZiBwYWRzIHNob3VsZCBiZSB0d2ljZSB0aGUgbGVuZ3RoIG9mIGRhdGEgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGlmIChzdHJpZGVzLmxlbmd0aCAhPT0gaW5wdXREaW1zLmxlbmd0aCAtIDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHN0cmlkZXMgc2hvdWxkIGJlIHRoZSBsZW5ndGggb2YgZGF0YSBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgaWYgKGtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXREaW1zLmxlbmd0aCAtIDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIGtlcm5lbCBzaGFwZXMgc2hvdWxkIGJlIHRoZSBsZW5ndGggb2YgZGF0YSBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgaW5wdXREaW1zLmxlbmd0aCAtIDI7IGRpbSsrKSB7XG4gICAgICBQb29sQ29udlV0aWwuYWRqdXN0UGFkQW5kUmV0dXJuU2hhcGUoXG4gICAgICAgIGlucHV0RGltc1tkaW0gKyAoaXNDaGFubmVsTGFzdCA/IDEgOiAyKV0sXG4gICAgICAgIHN0cmlkZXNbZGltXSxcbiAgICAgICAgZGlsYXRpb25zW2RpbV0sXG4gICAgICAgIGtlcm5lbFNoYXBlW2RpbV0sXG4gICAgICAgIHBhZHMsXG4gICAgICAgIGRpbSxcbiAgICAgICAgZGltICsgaW5wdXREaW1zLmxlbmd0aCAtIDIsXG4gICAgICAgIGF1dG9QYWQsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIG91dHB1dCBzaGFwZSBmb3IgUG9vbCBvcHMgYmFzZWQgb24gaW5wdXQgYXR0cmlidXRlcy4gKFNob3VsZCBiZSB1c2VkIG9ubHkgZm9yIFBvb2wgb3BzKVxuICAgKiBAcGFyYW0gaXNHbG9iYWxPcGVyYXRvciBJZiB0cnVlLCBwZXJmb3JtIGdsb2JhbCBwb29saW5nLlxuICAgKiBAcGFyYW0gaW5wdXREaW1zIFRoZSBpbnB1dCB0ZW5zb3IgZGltZW5zaW9uLiAoaW5wdXRzWzBdLmRpbXMpXG4gICAqIEBwYXJhbSBzdHJpZGVzIFN0cmlkZSBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBkaWxhdGlvbnMgRGlsYXRpb24gYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0ga2VybmVsU2hhcGUgVGhlIHNpemUgb2YgdGhlIGtlcm5lbCBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBwYWRzIFBhZGRpbmcgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZGluZyBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBhdXRvUGFkIERFUFJFQ0FURUQgYXR0cmlidXRlIHN1cHBvcnRlZCBmb3IgbGVnYWN5IG1vZGVscy4gU3BlY2lmaWVzIGhvdyB0byBpbXBsaWNpdGx5IGNhbGN1bGF0ZSBwYWRzIGluIGVhY2hcbiAgICogICAgIGRpbWVuc2lvbi4gQ2FuIHRha2UgdmFsdWVzIE5PVFNFVCwgU0FNRV9VUFBFUiwgU0FNRV9MT1dFUiwgb3IgVkFMSUQuXG4gICAqL1xuICBzdGF0aWMgY29tcHV0ZVBvb2xPdXRwdXRTaGFwZShcbiAgICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgc3RyaWRlczogbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogbnVtYmVyW10sXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgYXV0b1BhZD86IHN0cmluZyxcbiAgKTogbnVtYmVyW10ge1xuICAgIGlmIChpbnB1dERpbXMubGVuZ3RoIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgc2hhcGUgbXVzdCBiZSBvZiBzaXplIGdyZWF0ZXIgdGhhbiAwJyk7XG4gICAgfVxuXG4gICAgLy8gQWRkIGJhdGNoIHNpemUgYW5kIG51bWJlciBvZiBjaGFubmVscyBvZiBvdXRwdXRcbiAgICBjb25zdCBvdXRwdXREaW1zID0gW2lucHV0RGltc1swXSwgaW5wdXREaW1zWzFdXTtcblxuICAgIFBvb2xDb252VXRpbC5jb21wdXRlU2hhcGVIZWxwZXIoXG4gICAgICBpc0dsb2JhbE9wZXJhdG9yLFxuICAgICAgaW5wdXREaW1zLFxuICAgICAgb3V0cHV0RGltcyxcbiAgICAgIHN0cmlkZXMsXG4gICAgICBkaWxhdGlvbnMsXG4gICAgICBrZXJuZWxTaGFwZSxcbiAgICAgIHBhZHMsXG4gICAgICBhdXRvUGFkLFxuICAgICk7XG4gICAgcmV0dXJuIG91dHB1dERpbXM7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBvdXRwdXQgc2hhcGUgZm9yIENvbnYgb3AgYmFzZWQgb24gaW5wdXQgYXR0cmlidXRlcy4gKFNob3VsZCBiZSB1c2VkIG9ubHkgZm9yIENvbnYgb3ApXG4gICAqIEBwYXJhbSBpbnB1dERpbXMgVGhlIGlucHV0IHRlbnNvciBkaW1lbnNpb24uIChpbnB1dHNbMF0uZGltcylcbiAgICogQHBhcmFtIGZpbHRlckRpbXMgVGhlIGZpbHRlciB0ZW5zb3IgZGltZW5zaW9uLiAoaW5wdXRzWzFdLmRpbXMpXG4gICAqIEBwYXJhbSBzdHJpZGVzIFN0cmlkZSBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBrZXJuZWxTaGFwZSBUaGUgc2l6ZSBvZiB0aGUga2VybmVsIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIHBhZHMgUGFkZGluZyBmb3IgdGhlIGJlZ2lubmluZyBhbmQgZW5kaW5nIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGF1dG9QYWQgREVQUkVDQVRFRCBhdHRyaWJ1dGUgc3VwcG9ydGVkIGZvciBsZWdhY3kgbW9kZWxzLiBTcGVjaWZpZXMgaG93IHRvIGltcGxpY2l0bHkgY2FsY3VsYXRlIHBhZHMgaW4gZWFjaFxuICAgKiAgICAgZGltZW5zaW9uLiBDYW4gdGFrZSB2YWx1ZXMgTk9UU0VULCBTQU1FX1VQUEVSLCBTQU1FX0xPV0VSLCBvciBWQUxJRC5cbiAgICovXG4gIHN0YXRpYyBjb21wdXRlQ29udk91dHB1dFNoYXBlKFxuICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgZmlsdGVyRGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgc3RyaWRlczogbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogbnVtYmVyW10sXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgYXV0b1BhZD86IHN0cmluZyxcbiAgKTogbnVtYmVyW10ge1xuICAgIGlmIChpbnB1dERpbXMubGVuZ3RoIDw9IDAgfHwgZmlsdGVyRGltcy5sZW5ndGggPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciBkaW1zIG9yIGludmFsaWQgZmlsdGVyIHRlbnNvciBkaW1zJyk7XG4gICAgfVxuXG4gICAgLy8gQWRkIGJhdGNoIHNpemUgYW5kIG51bWJlciBvZiBjaGFubmVscyBvZiBvdXRwdXRcbiAgICBjb25zdCBvdXRwdXREaW1zID0gW2lucHV0RGltc1swXSwgZmlsdGVyRGltc1swXV07XG5cbiAgICBQb29sQ29udlV0aWwuY29tcHV0ZVNoYXBlSGVscGVyKGZhbHNlLCBpbnB1dERpbXMsIG91dHB1dERpbXMsIHN0cmlkZXMsIGRpbGF0aW9ucywga2VybmVsU2hhcGUsIHBhZHMsIGF1dG9QYWQpO1xuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLy8gd2lsbCBjb21wdXRlIG91dHB1dCBzaGFwZXMgZm9yIGRhdGEgZGltZW5zaW9ucyBPTkxZIChpLmUuKSBubyBiYXRjaCBzaXplIGFuZCBjaGFubmVsc1xuICAvLyBjYWxsZWQgYnkgY29tcHV0ZVBvb2xPdXRwdXRTaGFwZSgpIGFuZCBjb21wdXRlQ29udk91dHB1dFNoYXBlKClcbiAgLy8gYWRqdXN0IHBhZHMgYmFzZWQgb24gJ2F1dG9QYWQnIGF0dHJpYnV0ZSBwcmlvciB0byBzaGFwZSBjb21wdXRhdGlvblxuICBwcml2YXRlIHN0YXRpYyBjb21wdXRlU2hhcGVIZWxwZXIoXG4gICAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIG91dHB1dERpbXM6IG51bWJlcltdLFxuICAgIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICAgIGF1dG9QYWQ/OiBzdHJpbmcsXG4gICkge1xuICAgIGlmIChpc0dsb2JhbE9wZXJhdG9yKSB7XG4gICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgICAgb3V0cHV0RGltcy5wdXNoKDEpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgICAgb3V0cHV0RGltcy5wdXNoKFxuICAgICAgICAgIFBvb2xDb252VXRpbC5hZGp1c3RQYWRBbmRSZXR1cm5TaGFwZShcbiAgICAgICAgICAgIGlucHV0RGltc1tkaW0gKyAyXSxcbiAgICAgICAgICAgIHN0cmlkZXNbZGltXSxcbiAgICAgICAgICAgIGRpbGF0aW9uc1tkaW1dLFxuICAgICAgICAgICAga2VybmVsU2hhcGVbZGltXSxcbiAgICAgICAgICAgIHBhZHMsXG4gICAgICAgICAgICBkaW0sXG4gICAgICAgICAgICBkaW0gKyBpbnB1dERpbXMubGVuZ3RoIC0gMixcbiAgICAgICAgICAgIGF1dG9QYWQsXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBoZWxwZXIgZm9yIGNvbXB1dGVTaGFwZUhlbHBlcigpIGFuZCBhZGp1c3RQYWRzQmFzZWRPbkF1dG9QYWQoKVxuICAvLyBhZGp1c3RzIHBhZCB2YWx1ZSBmb3IgZ2l2ZW4gJ2F1dG9QYWQnIHN0cmluZyBhbmQgY29tcHV0ZXMgb3V0cHV0IHNoYXBlIGFsb25nIGEgcGFydGljdWxhciBkaW1lbnNpb25cbiAgcHJpdmF0ZSBzdGF0aWMgYWRqdXN0UGFkQW5kUmV0dXJuU2hhcGUoXG4gICAgaW5TaXplOiBudW1iZXIsXG4gICAgc3RyaWRlOiBudW1iZXIsXG4gICAgZGlsYXRpb246IG51bWJlcixcbiAgICBrZXJuZWw6IG51bWJlcixcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgICBwYWRIZWFkSW5kZXg6IG51bWJlcixcbiAgICBwYWRUYWlsSW5kZXg6IG51bWJlcixcbiAgICBhdXRvUGFkPzogc3RyaW5nLFxuICApOiBudW1iZXIge1xuICAgIGNvbnN0IGRrZXJuZWwgPSBkaWxhdGlvbiAqIChrZXJuZWwgLSAxKSArIDE7XG4gICAgaWYgKGF1dG9QYWQgJiYgYXV0b1BhZCAhPT0gJ05PVFNFVCcpIHtcbiAgICAgIHN3aXRjaCAoYXV0b1BhZCkge1xuICAgICAgICBjYXNlICdWQUxJRCc6XG4gICAgICAgICAgcGFkc1twYWRIZWFkSW5kZXhdID0gMDtcbiAgICAgICAgICBwYWRzW3BhZFRhaWxJbmRleF0gPSAwO1xuICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKChpblNpemUgLSBka2VybmVsKSAvIHN0cmlkZSArIDEpO1xuICAgICAgICBjYXNlICdTQU1FX0xPV0VSJzpcbiAgICAgICAgY2FzZSAnU0FNRV9VUFBFUic6XG4gICAgICAgICAgaWYgKGRpbGF0aW9uICE9PSAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbGF0aW9uIG5vdCBzdXBwb3J0ZWQgZm9yIFNBTUVfVVBQRVIgb3IgU0FNRV9MT1dFUicpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBsZWdhY3lUYXJnZXRTaXplID0gKGluU2l6ZSArIHN0cmlkZSAtIDEpIC8gc3RyaWRlO1xuICAgICAgICAgICAgY29uc3QgcGFkTmVlZGVkID0gKGxlZ2FjeVRhcmdldFNpemUgLSAxKSAqIHN0cmlkZSArIGtlcm5lbCAtIGluU2l6ZTtcbiAgICAgICAgICAgIHBhZHNbcGFkSGVhZEluZGV4XSA9IGF1dG9QYWQgPT09ICdTQU1FX0xPV0VSJyA/IE1hdGguZmxvb3IoKHBhZE5lZWRlZCArIDEpIC8gMikgOiBNYXRoLmZsb29yKHBhZE5lZWRlZCAvIDIpO1xuICAgICAgICAgICAgcGFkc1twYWRUYWlsSW5kZXhdID0gcGFkTmVlZGVkIC0gcGFkc1twYWRIZWFkSW5kZXhdO1xuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKGluU2l6ZSArIHBhZE5lZWRlZCAtIGtlcm5lbCkgLyBzdHJpZGUgKyAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBBdXRvUGFkIHR5cGUnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKGluU2l6ZSArIHBhZHNbcGFkSGVhZEluZGV4XSArIHBhZHNbcGFkVGFpbEluZGV4XSAtIGRrZXJuZWwpIC8gc3RyaWRlICsgMSk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBHZW1tVXRpbCB7XG4gIC8vIHdpbGwgbWFrZSBzdXJlIGlucHV0IHNoYXBlcyBhcmUgY29tcGF0aWJsZSBmb3IgdGhpcyBvcFxuICAvLyBhbmQgcmV0dXJuIGJhY2sgdGhlIHNoYXBlIG9mIHRoZSBvdXRwdXQgaW4gdGhlIGZvcm0gb2YgYSB0dXBsZVxuICAvLyB3aWxsIHRocm93IGV4Y2VwdGlvbiBpZiB0aGUgaW5wdXQgc2hhcGVzIGFyZSBub3QgY29tcGF0aWJsZVxuICBzdGF0aWMgZ2V0U2hhcGVPZkdlbW1SZXN1bHQoXG4gICAgbGVmdFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgICB0cmFuc0xlZnQ6IGJvb2xlYW4sXG4gICAgcmlnaHRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgdHJhbnNSaWdodDogYm9vbGVhbixcbiAgICBiaWFzU2hhcGU/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmIChsZWZ0U2hhcGUubGVuZ3RoICE9PSAyIHx8IHJpZ2h0U2hhcGUubGVuZ3RoICE9PSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NoYXBlIG5lZWQgdG8gYmUgb2Ygc2l6ZSAyJyk7XG4gICAgfVxuXG4gICAgbGV0IE06IG51bWJlcjtcbiAgICBsZXQgSzogbnVtYmVyO1xuICAgIGxldCBOOiBudW1iZXI7XG5cbiAgICBpZiAodHJhbnNMZWZ0KSB7XG4gICAgICBNID0gbGVmdFNoYXBlWzFdO1xuICAgICAgSyA9IGxlZnRTaGFwZVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgTSA9IGxlZnRTaGFwZVswXTtcbiAgICAgIEsgPSBsZWZ0U2hhcGVbMV07XG4gICAgfVxuXG4gICAgbGV0IGtEaW0gPSAtMTtcblxuICAgIGlmICh0cmFuc1JpZ2h0KSB7XG4gICAgICBOID0gcmlnaHRTaGFwZVswXTtcbiAgICAgIGtEaW0gPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBOID0gcmlnaHRTaGFwZVsxXTtcbiAgICAgIGtEaW0gPSAwO1xuICAgIH1cblxuICAgIGlmIChyaWdodFNoYXBlW2tEaW1dICE9PSBLKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RpbWVuc2lvbiBtaXNtYXRjaCcpO1xuICAgIH1cblxuICAgIGlmIChNIDw9IDAgfHwgTiA8PSAwIHx8IEsgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNoYXBlIHNwZWNpZmllZCcpO1xuICAgIH1cblxuICAgIGlmIChiaWFzU2hhcGUgJiYgIUJyb2FkY2FzdFV0aWwuaXNWYWxpZEJyb2FkY2FzdChiaWFzU2hhcGUsIFtNLCBOXSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ2VtbTogaW52YWxpZCBiaWFzIHNoYXBlIGZvciBicm9hZGNhc3QnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW00sIE4sIEtdO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBNSU5fQ0xJUCA9IC0zLjQwMjgyMzQ2NjM4NTI4ODZlMzg7XG5leHBvcnQgY29uc3QgTUFYX0NMSVAgPSAzLjQwMjgyMzQ2NjM4NTI4ODZlMzg7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IHRlbnNvclR5cGVUb1R5cGVkQXJyYXlDb25zdHJ1Y3RvciB9IGZyb20gJy4uL3dhc20tY29tbW9uJztcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVZpZXcgPSAoXG4gIGRhdGFCdWZmZXI6IEFycmF5QnVmZmVyLFxuICB0eXBlOiBUZW5zb3IuVHlwZSxcbik6XG4gIHwgSW50MzJBcnJheVxuICB8IFVpbnQzMkFycmF5XG4gIHwgQmlnSW50NjRBcnJheVxuICB8IEJpZ1VpbnQ2NEFycmF5XG4gIHwgVWludDhBcnJheVxuICB8IEZsb2F0MzJBcnJheVxuICB8IEZsb2F0NjRBcnJheVxuICB8IEludDhBcnJheVxuICB8IEludDE2QXJyYXlcbiAgfCBVaW50MTZBcnJheSA9PiBuZXcgKHRlbnNvclR5cGVUb1R5cGVkQXJyYXlDb25zdHJ1Y3Rvcih0eXBlKSkoZGF0YUJ1ZmZlcik7XG5cbi8qKlxuICogYSBUZW5zb3JWaWV3IGRvZXMgbm90IG93biB0aGUgZGF0YS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JWaWV3IHtcbiAgcmVhZG9ubHkgZGF0YTogbnVtYmVyO1xuICByZWFkb25seSBkYXRhVHlwZTogbnVtYmVyO1xuICByZWFkb25seSBkaW1zOiByZWFkb25seSBudW1iZXJbXTtcblxuICAvKipcbiAgICogZ2V0IGEgRmxvYXQxNkFycmF5IGRhdGEgdmlldyBvZiB0aGUgdGVuc29yIGRhdGEuIHRlbnNvciBkYXRhIG11c3QgYmUgb24gQ1BVLlxuICAgKi9cbiAgZ2V0VWludDE2QXJyYXkoKTogVWludDE2QXJyYXk7XG5cbiAgLyoqXG4gICAqIGdldCBhIEZsb2F0MzJBcnJheSBkYXRhIHZpZXcgb2YgdGhlIHRlbnNvciBkYXRhLiB0ZW5zb3IgZGF0YSBtdXN0IGJlIG9uIENQVS5cbiAgICovXG4gIGdldEZsb2F0MzJBcnJheSgpOiBGbG9hdDMyQXJyYXk7XG5cbiAgLyoqXG4gICAqIGdldCBhIEJpZ0ludDY0QXJyYXkgZGF0YSB2aWV3IG9mIHRoZSB0ZW5zb3IgZGF0YS4gdGVuc29yIGRhdGEgbXVzdCBiZSBvbiBDUFUuXG4gICAqL1xuICBnZXRCaWdJbnQ2NEFycmF5KCk6IEJpZ0ludDY0QXJyYXk7XG5cbiAgLyoqXG4gICAqIGdldCBhIEludDMyQXJyYXkgZGF0YSB2aWV3IG9mIHRoZSB0ZW5zb3IgZGF0YS4gdGVuc29yIGRhdGEgbXVzdCBiZSBvbiBDUFUuXG4gICAqL1xuICBnZXRJbnQzMkFycmF5KCk6IEludDMyQXJyYXk7XG5cbiAgLyoqXG4gICAqIGdldCBhIFVpbnQxNkFycmF5IGRhdGEgdmlldyBvZiB0aGUgdGVuc29yIGRhdGEuIHRlbnNvciBkYXRhIG11c3QgYmUgb24gQ1BVLlxuICAgKi9cbiAgZ2V0VWludDE2QXJyYXkoKTogVWludDE2QXJyYXk7XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhIG5ldyB0ZW5zb3IgdmlldyB3aXRoIHRoZSBzYW1lIGRhdGEgYnV0IGRpZmZlcmVudCBkaW1lbnNpb25zLlxuICAgKi9cbiAgcmVzaGFwZShuZXdEaW1zOiByZWFkb25seSBudW1iZXJbXSk6IFRlbnNvclZpZXc7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFdlYk5OQmFja2VuZCB9IGZyb20gJy4uL2JhY2tlbmQtd2Vibm4nO1xuaW1wb3J0IHsgdGVuc29yVHlwZVRvVHlwZWRBcnJheUNvbnN0cnVjdG9yIH0gZnJvbSAnLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgTE9HX0RFQlVHIH0gZnJvbSAnLi4vbG9nJztcblxuLy8gV2ViTk4gQVBJIGN1cnJlbnRseSBkb2VzIG5vdCBoYXZlIGEgVHlwZVNjcmlwdCBkZWZpbml0aW9uIGZpbGUuIFRoaXMgZmlsZSBpcyBhIHdvcmthcm91bmQgd2l0aCB0eXBlcyBnZW5lcmF0ZWQgZnJvbVxuLy8gV2ViTk4gQVBJIHNwZWNpZmljYXRpb24uXG4vLyBodHRwczovL2dpdGh1Yi5jb20vd2VibWFjaGluZWxlYXJuaW5nL3dlYm5uL2lzc3Vlcy82Nzdcbi8vLyA8cmVmZXJlbmNlIHBhdGg9XCJ3ZWJubi5kLnRzXCIgLz5cblxuLyoqXG4gKiBNYXAgZnJvbSBNTE9wZXJhbmREYXRhVHlwZSB0byBzaXplIGluIGJpdHMuIFVzaW5nIGJpdHMgaW5zdGVhZCBvZiBieXRlcyB0byBhdm9pZCBwb3NzaWJsZSBwcmVjaXNpb24gbG9zcyBvbiBpbnQ0IGFuZCB1aW50NC5cbiAqL1xuY29uc3Qgd2Vibm5EYXRhVHlwZVRvU2l6ZSA9IG5ldyBNYXA8TUxPcGVyYW5kRGF0YVR5cGUsIG51bWJlcj4oW1xuICBbJ2Zsb2F0MzInLCAzMl0sXG4gIFsnZmxvYXQxNicsIDE2XSxcbiAgWydpbnQzMicsIDMyXSxcbiAgWyd1aW50MzInLCAzMl0sXG4gIFsnaW50NjQnLCA2NF0sXG4gIFsndWludDY0JywgNjRdLFxuICBbJ2ludDgnLCA4XSxcbiAgWyd1aW50OCcsIDhdLFxuICBbJ2ludDQnLCA0XSxcbiAgWyd1aW50NCcsIDRdLFxuXSk7XG5cbi8vIENvbnZlcnQgaW50ZWdlciBkYXRhIHRvIGFuIEludDMyQXJyYXkgYnVmZmVyLlxuLy8gU3VwcG9ydHMgY29udmVyc2lvbiBmcm9tIGludDY0LCB1aW50NjQsIHVpbnQzMiwgaW50OCBhbmQgdWludDggdG8gaW50MzIuXG5leHBvcnQgY29uc3QgY29udmVydERhdGFUb0ludDMyID0gKGRhdGE6IFVpbnQ4QXJyYXksIGRhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZSk6IFVpbnQ4QXJyYXkgPT4ge1xuICBpZiAoZGF0YVR5cGUgPT09ICdpbnQzMicpIHtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIGNvbnN0IGRhdGFUeXBlU2l6ZSA9IHdlYm5uRGF0YVR5cGVUb1NpemUuZ2V0KGRhdGFUeXBlKTtcbiAgaWYgKCFkYXRhVHlwZVNpemUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFdlYk5OIGJhY2tlbmQgZG9lcyBub3Qgc3VwcG9ydCBkYXRhIHR5cGU6ICR7ZGF0YVR5cGV9YCk7XG4gIH1cbiAgY29uc3QgYnl0ZXNQZXJFbGVtZW50ID0gZGF0YVR5cGVTaXplIC8gODtcbiAgLy8gTWFrZSBzdXJlIHRoZSBkYXRhIGxlbmd0aCBpcyBhIG11bHRpcGxlIG9mIHRoZSBkYXRhIHR5cGUgc2l6ZS5cbiAgaWYgKGRhdGEuYnl0ZUxlbmd0aCAlIGJ5dGVzUGVyRWxlbWVudCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBVaW50OEFycmF5IGxlbmd0aCAtIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAke2J5dGVzUGVyRWxlbWVudH0uYCk7XG4gIH1cblxuICAvLyBDb252ZXJ0IFVpbnQ4QXJyYXkgdG8gb3JpZ2luYWwgdHlwZWQgYXJyYXkuXG4gIGNvbnN0IG51bUVsZW1lbnRzID0gZGF0YS5ieXRlTGVuZ3RoIC8gYnl0ZXNQZXJFbGVtZW50O1xuICBjb25zdCBvcmlnaW5hbEFycmF5ID0gbmV3ICh0ZW5zb3JUeXBlVG9UeXBlZEFycmF5Q29uc3RydWN0b3IoZGF0YVR5cGUpKShkYXRhLmJ1ZmZlciwgZGF0YS5ieXRlT2Zmc2V0LCBudW1FbGVtZW50cyk7XG5cbiAgc3dpdGNoIChkYXRhVHlwZSkge1xuICAgIGNhc2UgJ2ludDY0JzpcbiAgICBjYXNlICd1aW50NjQnOiB7XG4gICAgICAvLyBDb252ZXJ0IG9yaWdpbmFsIHR5cGVkIGFycmF5IHRvIEludDMyQXJyYXkuXG4gICAgICBjb25zdCBpbnQzMkFycmF5ID0gbmV3IEludDMyQXJyYXkobnVtRWxlbWVudHMpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1FbGVtZW50czsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gb3JpZ2luYWxBcnJheVtpXTtcblxuICAgICAgICAvLyBDaGVjayBmb3Igb3ZlcmZsb3cuXG4gICAgICAgIGlmICh2YWx1ZSA+IDIxNDc0ODM2NDduIHx8IHZhbHVlIDwgLTIxNDc0ODM2NDhuKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW4gbm90IGNvbnZlcnQgaW50NjQgZGF0YSB0byBpbnQzMiAtIHZhbHVlIG91dCBvZiByYW5nZS5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGludDMyQXJyYXlbaV0gPSBOdW1iZXIodmFsdWUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoaW50MzJBcnJheS5idWZmZXIpO1xuICAgIH1cbiAgICBjYXNlICdpbnQ4JzpcbiAgICBjYXNlICd1aW50OCc6XG4gICAgY2FzZSAndWludDMyJzoge1xuICAgICAgLy8gQ2hlY2sgZm9yIG92ZXJmbG93LlxuICAgICAgaWYgKGRhdGFUeXBlID09PSAndWludDMyJykge1xuICAgICAgICBpZiAob3JpZ2luYWxBcnJheS5zb21lKCh2YWx1ZSkgPT4gdmFsdWUgPiAyMTQ3NDgzNjQ3KSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuIG5vdCBjb252ZXJ0IHVpbnQzMiBkYXRhIHRvIGludDMyIC0gdmFsdWUgb3V0IG9mIHJhbmdlLmApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBDb252ZXJ0IG9yaWdpbmFsIHR5cGVkIGFycmF5IHRvIEludDMyQXJyYXkuXG4gICAgICBjb25zdCBpbnQzMkFycmF5ID0gSW50MzJBcnJheS5mcm9tKG9yaWdpbmFsQXJyYXksIE51bWJlcik7XG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoaW50MzJBcnJheS5idWZmZXIpO1xuICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkYXRhIGNvbnZlcnNpb24gZnJvbSAke2RhdGFUeXBlfSB0byAnaW50MzInYCk7XG4gIH1cbn07XG5cbi8vIENvbnZlcnQgSW50MzJBcnJheSBkYXRhIHRvIG9yaWdpbmFsIGludGVnZXIgZGF0YSBidWZmZXIuXG4vLyBTdXBwb3J0cyBjb252ZXJzaW9uIGZyb20gaW50MzIgdG8gaW50NjQsIHVpbnQ2NCwgdWludDMyLCBpbnQ4IGFuZCB1aW50OC5cbmV4cG9ydCBjb25zdCBjb252ZXJ0SW50MzJUb0RhdGEgPSAoZGF0YTogVWludDhBcnJheSwgZGF0YVR5cGU6IE1MT3BlcmFuZERhdGFUeXBlKTogVWludDhBcnJheSA9PiB7XG4gIGlmIChkYXRhVHlwZSA9PT0gJ2ludDMyJykge1xuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgLy8gTWFrZSBzdXJlIHRoZSBkYXRhIGxlbmd0aCBpcyBhIG11bHRpcGxlIG9mIDQgYnl0ZXMgKEludDMyQXJyYXkpLlxuICBpZiAoZGF0YS5ieXRlTGVuZ3RoICUgNCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBVaW50OEFycmF5IGxlbmd0aCAtIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0IChpbnQzMikuJyk7XG4gIH1cblxuICAvLyBDb252ZXJ0IFVpbnQ4QXJyYXkgdG8gSW50MzJBcnJheS5cbiAgY29uc3QgbnVtRWxlbWVudHMgPSBkYXRhLmJ5dGVMZW5ndGggLyA0O1xuICBjb25zdCBpbnQzMkFycmF5ID0gbmV3IEludDMyQXJyYXkoZGF0YS5idWZmZXIsIGRhdGEuYnl0ZU9mZnNldCwgbnVtRWxlbWVudHMpO1xuXG4gIHN3aXRjaCAoZGF0YVR5cGUpIHtcbiAgICBjYXNlICdpbnQ2NCc6IHtcbiAgICAgIGNvbnN0IGJpZ0ludDY0QXJyYXkgPSBCaWdJbnQ2NEFycmF5LmZyb20oaW50MzJBcnJheSwgQmlnSW50KTtcbiAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShiaWdJbnQ2NEFycmF5LmJ1ZmZlcik7XG4gICAgfVxuICAgIGNhc2UgJ3VpbnQ2NCc6IHtcbiAgICAgIGlmIChpbnQzMkFycmF5LnNvbWUoKHZhbHVlKSA9PiB2YWx1ZSA8IDApKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBjb252ZXJ0IGludDMyIGRhdGEgdG8gdWluNjQgLSBuZWdhdGl2ZSB2YWx1ZSBmb3VuZC4nKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJpZ1VpbnQ2NEFycmF5ID0gQmlnVWludDY0QXJyYXkuZnJvbShpbnQzMkFycmF5LCBCaWdJbnQpO1xuICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGJpZ1VpbnQ2NEFycmF5LmJ1ZmZlcik7XG4gICAgfVxuICAgIGNhc2UgJ2ludDgnOiB7XG4gICAgICBpZiAoaW50MzJBcnJheS5zb21lKCh2YWx1ZSkgPT4gdmFsdWUgPCAtMTI4IHx8IHZhbHVlID4gMTI3KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBub3QgY29udmVydCBpbnQzMiBkYXRhIHRvIGludDggLSB2YWx1ZSBvdXQgb2YgcmFuZ2UuJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBpbnQ4QXJyYXkgPSBJbnQ4QXJyYXkuZnJvbShpbnQzMkFycmF5LCBOdW1iZXIpO1xuICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGludDhBcnJheS5idWZmZXIpO1xuICAgIH1cbiAgICBjYXNlICd1aW50OCc6IHtcbiAgICAgIGlmIChpbnQzMkFycmF5LnNvbWUoKHZhbHVlKSA9PiB2YWx1ZSA8IDAgfHwgdmFsdWUgPiAyNTUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBjb252ZXJ0IGludDMyIGRhdGEgdG8gdWludDggLSB2YWx1ZSBvdXQgb2YgcmFuZ2UuJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gVWludDhBcnJheS5mcm9tKGludDMyQXJyYXksIE51bWJlcik7XG4gICAgfVxuICAgIGNhc2UgJ3VpbnQzMic6IHtcbiAgICAgIGlmIChpbnQzMkFycmF5LnNvbWUoKHZhbHVlKSA9PiB2YWx1ZSA8IDApKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBjb252ZXJ0IGludDMyIGRhdGEgdG8gdWludDMyIC0gbmVnYXRpdmUgdmFsdWUgZm91bmQuJyk7XG4gICAgICB9XG4gICAgICBjb25zdCB1aW50MzJBcnJheSA9IFVpbnQzMkFycmF5LmZyb20oaW50MzJBcnJheSwgTnVtYmVyKTtcbiAgICAgIHJldHVybiBuZXcgVWludDhBcnJheSh1aW50MzJBcnJheS5idWZmZXIpO1xuICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkYXRhIGNvbnZlcnNpb24gZnJvbSAnaW50MzInIHRvICR7ZGF0YVR5cGV9YCk7XG4gIH1cbn07XG5cbmV4cG9ydCB0eXBlIFRlbnNvcklkID0gbnVtYmVyO1xuXG4vKipcbiAqIE1hbmFnZXMgVGVuc29ySWQgdG8gTUxUZW5zb3IgbWFwcGluZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JNYW5hZ2VyIHtcbiAgLyoqXG4gICAqIFJlc2VydmUgYSBuZXcgVGVuc29ySWQuXG4gICAqL1xuICByZXNlcnZlVGVuc29ySWQoKTogVGVuc29ySWQ7XG4gIC8qKlxuICAgKiBSZWxlYXNlIGEgVGVuc29ySWQuXG4gICAqL1xuICByZWxlYXNlVGVuc29ySWQodGVuc29ySWQ6IFRlbnNvcklkKTogdm9pZDtcbiAgLyoqXG4gICAqIEVuc3VyZSBhIE1MVGVuc29yIGlzIGNyZWF0ZWQgZm9yIHRoZSBUZW5zb3JJZC5cbiAgICovXG4gIGVuc3VyZVRlbnNvcihcbiAgICBzZXNzaW9uSWQ6IG51bWJlcixcbiAgICB0ZW5zb3JJZDogVGVuc29ySWQsXG4gICAgZGF0YVR5cGU6IE1MT3BlcmFuZERhdGFUeXBlLFxuICAgIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBjb3B5T2xkOiBib29sZWFuLFxuICApOiBQcm9taXNlPE1MVGVuc29yPjtcbiAgLyoqXG4gICAqIFVwbG9hZCBkYXRhIHRvIGEgTUxUZW5zb3IuXG4gICAqL1xuICB1cGxvYWQodGVuc29ySWQ6IFRlbnNvcklkLCBkYXRhOiBVaW50OEFycmF5KTogdm9pZDtcbiAgLyoqXG4gICAqIERvd25sb2FkIGRhdGEgZnJvbSBhIE1MVGVuc29yLlxuICAgKi9cbiAgZG93bmxvYWQodGVuc29ySWQ6IFRlbnNvcklkKTogUHJvbWlzZTxBcnJheUJ1ZmZlcj47XG4gIGRvd25sb2FkKHRlbnNvcklkOiBUZW5zb3JJZCwgZHN0VGVuc29yOiBBcnJheUJ1ZmZlclZpZXcgfCBBcnJheUJ1ZmZlcik6IFByb21pc2U8dW5kZWZpbmVkPjtcbiAgLyoqXG4gICAqIFJlbGVhc2UgYWxsIHRlbnNvcnMgZm9yIGEgZ2l2ZW4gc2Vzc2lvbi5cbiAgICovXG4gIHJlbGVhc2VUZW5zb3JzRm9yU2Vzc2lvbihzZXNzaW9uOiBudW1iZXIpOiB2b2lkO1xuICAvKipcbiAgICogUmVnaXN0ZXIgYW4gZXh0ZXJuYWxseSBjcmVhdGVkIE1MVGVuc29yIHdpdGggYSBnaXZlbiBzZXNzaW9uIGlkIGFuZCByZXR1cm4gYSBUZW5zb3JJZC5cbiAgICovXG4gIHJlZ2lzdGVyVGVuc29yKHNlc3Npb25JZDogbnVtYmVyLCBtbFRlbnNvcjogTUxUZW5zb3IsIGRhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZSwgc2hhcGU6IG51bWJlcltdKTogVGVuc29ySWQ7XG59XG5cbmxldCB0ZW5zb3JHdWlkID0gMTtcbmNvbnN0IGNyZWF0ZU5ld1RlbnNvcklkID0gKCk6IFRlbnNvcklkID0+IHRlbnNvckd1aWQrKztcblxuLyoqXG4gKiBNYXAgZnJvbSBkYXRhIHR5cGUgdG8gZmFsbGJhY2sgZGF0YSB0eXBlLlxuICogV2hlbiB0aGUgY29udGV4dCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBvcmlnaW5hbCBkYXRhIHR5cGUsIHVzZSBmYWxsYmFjayBkYXRhIHR5cGUgYXMgd29ya2Fyb3VuZC5cbiAqIE5vdGU6IEN1cnJlbnRseSwgd2Ugb25seSBzdXBwb3J0IGZhbGxiYWNrIHRvIGludDMyIGZvciBjZXJ0YWluIGludGVnZXIgZGF0YSB0eXBlcy5cbiAqL1xuY29uc3Qgd2Vibm5EYXRhVHlwZVRvRmFsbGJhY2sgPSBuZXcgTWFwPE1MT3BlcmFuZERhdGFUeXBlLCBNTE9wZXJhbmREYXRhVHlwZT4oW1xuICBbJ2ludDgnLCAnaW50MzInXSxcbiAgWyd1aW50OCcsICdpbnQzMiddLFxuICBbJ3VpbnQzMicsICdpbnQzMiddLFxuICBbJ2ludDY0JywgJ2ludDMyJ10sXG5dKTtcblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIGJ5dGUgbGVuZ3RoIG9mIGEgdGVuc29yIHdpdGggdGhlIGdpdmVuIGRhdGEgdHlwZSBhbmQgc2hhcGUuXG4gKi9cbmNvbnN0IGNhbGN1bGF0ZUJ5dGVMZW5ndGggPSAoZGF0YVR5cGU6IE1MT3BlcmFuZERhdGFUeXBlLCBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiBudW1iZXIgPT4ge1xuICBjb25zdCBkYXRhVHlwZVNpemUgPSB3ZWJubkRhdGFUeXBlVG9TaXplLmdldChkYXRhVHlwZSk7XG4gIGlmICghZGF0YVR5cGVTaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBXZWJOTiBiYWNrZW5kIGRvZXMgbm90IHN1cHBvcnQgZGF0YSB0eXBlOiAke2RhdGFUeXBlfWApO1xuICB9XG4gIHJldHVybiBzaGFwZS5sZW5ndGggPiAwID8gTWF0aC5jZWlsKChzaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKSAqIGRhdGFUeXBlU2l6ZSkgLyA4KSA6IDA7XG59O1xuXG4vKipcbiAqIFRlbnNvcldyYXBwZXIgd3JhcHMgYW4gTUxUZW5zb3IgYW5kIHByb3ZpZGVzIGEgd2F5IHRvIHRyYWNrIHRoZSBsYXN0IHNlc3Npb24gdGhhdCB1c2VkIGl0LlxuICovXG5jbGFzcyBUZW5zb3JXcmFwcGVyIHtcbiAgLy8gVGhlIGlkIG9mIHRoZSBsYXN0IHNlc3Npb24gdGhhdCB1c2VkIHRoaXMgdGVuc29yLlxuICBwdWJsaWMgc2Vzc2lvbklkOiBudW1iZXI7XG4gIC8vIFRoaXMgZmxhZyBpcyB1c2VkIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlIGRhdGEgaGFzIGJlZW4gY29udmVydGVkIHRvIGZhbGxiYWNrIGRhdGEgdHlwZS5cbiAgcHVibGljIGlzRGF0YUNvbnZlcnRlZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgbWxDb250ZXh0OiBNTENvbnRleHQ7XG4gIHByaXZhdGUgbWxUZW5zb3I6IE1MVGVuc29yO1xuICBwcml2YXRlIGRhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZTtcbiAgLy8gRmFsbGJhY2sgZGF0YSB0eXBlIHRvIHVzZSB3aGVuIHRoZSBjb250ZXh0IGRvZXMgbm90IHN1cHBvcnQgdGhlIG9yaWdpbmFsIGRhdGEgdHlwZS5cbiAgcHJpdmF0ZSBmYWxsYmFja0RhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSB0ZW5zb3JTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgY29uc3RydWN0b3IoZGVzY3JpcHRvcjoge1xuICAgIHNlc3Npb25JZDogbnVtYmVyO1xuICAgIGNvbnRleHQ6IE1MQ29udGV4dDtcbiAgICB0ZW5zb3I6IE1MVGVuc29yO1xuICAgIGRhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZTtcbiAgICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG4gICAgZmFsbGJhY2tEYXRhVHlwZT86IE1MT3BlcmFuZERhdGFUeXBlO1xuICB9KSB7XG4gICAgY29uc3QgeyBzZXNzaW9uSWQsIGNvbnRleHQsIHRlbnNvciwgZGF0YVR5cGUsIHNoYXBlLCBmYWxsYmFja0RhdGFUeXBlIH0gPSBkZXNjcmlwdG9yO1xuICAgIHRoaXMuc2Vzc2lvbklkID0gc2Vzc2lvbklkO1xuICAgIHRoaXMubWxDb250ZXh0ID0gY29udGV4dDtcbiAgICB0aGlzLm1sVGVuc29yID0gdGVuc29yO1xuICAgIHRoaXMuZGF0YVR5cGUgPSBkYXRhVHlwZTtcbiAgICB0aGlzLnRlbnNvclNoYXBlID0gc2hhcGU7XG4gICAgdGhpcy5mYWxsYmFja0RhdGFUeXBlID0gZmFsbGJhY2tEYXRhVHlwZTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdGVuc29yKCk6IE1MVGVuc29yIHtcbiAgICByZXR1cm4gdGhpcy5tbFRlbnNvcjtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdHlwZSgpOiBNTE9wZXJhbmREYXRhVHlwZSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVR5cGU7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGZhbGxiYWNrVHlwZSgpOiBNTE9wZXJhbmREYXRhVHlwZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZmFsbGJhY2tEYXRhVHlwZTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgc2hhcGUoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLnRlbnNvclNoYXBlO1xuICB9XG5cbiAgcHVibGljIGdldCBieXRlTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIGNhbGN1bGF0ZUJ5dGVMZW5ndGgodGhpcy5kYXRhVHlwZSwgdGhpcy50ZW5zb3JTaGFwZSk7XG4gIH1cblxuICBwdWJsaWMgZGVzdHJveSgpOiB2b2lkIHtcbiAgICBMT0dfREVCVUcoJ3ZlcmJvc2UnLCAoKSA9PiAnW1dlYk5OXSBUZW5zb3JXcmFwcGVyLmRlc3Ryb3knKTtcbiAgICB0aGlzLm1sVGVuc29yLmRlc3Ryb3koKTtcbiAgfVxuXG4gIHB1YmxpYyB3cml0ZShkYXRhOiBVaW50OEFycmF5KTogdm9pZCB7XG4gICAgdGhpcy5tbENvbnRleHQud3JpdGVUZW5zb3IodGhpcy5tbFRlbnNvciwgZGF0YSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcmVhZCgpOiBQcm9taXNlPEFycmF5QnVmZmVyPjtcbiAgcHVibGljIGFzeW5jIHJlYWQoZHN0QnVmZmVyPzogQXJyYXlCdWZmZXJWaWV3IHwgQXJyYXlCdWZmZXIpOiBQcm9taXNlPEFycmF5QnVmZmVyIHwgdW5kZWZpbmVkPjtcbiAgcHVibGljIGFzeW5jIHJlYWQoZHN0QnVmZmVyPzogQXJyYXlCdWZmZXJWaWV3IHwgQXJyYXlCdWZmZXIpOiBQcm9taXNlPEFycmF5QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgaWYgKHRoaXMuZmFsbGJhY2tEYXRhVHlwZSkge1xuICAgICAgLy8gVGhpcyB0ZW5zb3IgaGFzIGJlZW4gZmFsbGJhY2sgdG8gaW50MzIgYXMgd29ya2Fyb3VuZCwgd2UgbmVlZCB0byByZWFkIGl0IGFzIGl0cyBvcmlnaW5hbCBpbnRlZ2VyIGRhdGEgdHlwZS5cbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLm1sQ29udGV4dC5yZWFkVGVuc29yKHRoaXMubWxUZW5zb3IpO1xuICAgICAgY29uc3Qgb3JpZ2luYWxEYXRhID0gY29udmVydEludDMyVG9EYXRhKG5ldyBVaW50OEFycmF5KGRhdGEpLCB0aGlzLmRhdGFUeXBlKTtcblxuICAgICAgaWYgKGRzdEJ1ZmZlcikge1xuICAgICAgICBjb25zdCB0YXJnZXRCdWZmZXIgPVxuICAgICAgICAgIGRzdEJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyXG4gICAgICAgICAgICA/IG5ldyBVaW50OEFycmF5KGRzdEJ1ZmZlcilcbiAgICAgICAgICAgIDogbmV3IFVpbnQ4QXJyYXkoZHN0QnVmZmVyLmJ1ZmZlciwgZHN0QnVmZmVyLmJ5dGVPZmZzZXQsIGRzdEJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgdGFyZ2V0QnVmZmVyLnNldChvcmlnaW5hbERhdGEpO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsRGF0YS5idWZmZXI7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBkc3RCdWZmZXIgPyB0aGlzLm1sQ29udGV4dC5yZWFkVGVuc29yKHRoaXMubWxUZW5zb3IsIGRzdEJ1ZmZlcikgOiB0aGlzLm1sQ29udGV4dC5yZWFkVGVuc29yKHRoaXMubWxUZW5zb3IpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjYW5SZXVzZVRlbnNvcihjb250ZXh0OiBNTENvbnRleHQsIGRhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZSwgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMubWxDb250ZXh0ID09PSBjb250ZXh0ICYmXG4gICAgICB0aGlzLmRhdGFUeXBlID09PSBkYXRhVHlwZSAmJlxuICAgICAgdGhpcy50ZW5zb3JTaGFwZS5sZW5ndGggPT09IHNoYXBlLmxlbmd0aCAmJlxuICAgICAgdGhpcy50ZW5zb3JTaGFwZS5ldmVyeSgodiwgaSkgPT4gdiA9PT0gc2hhcGVbaV0pXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRJc0RhdGFDb252ZXJ0ZWQoaXNDb252ZXJ0ZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmlzRGF0YUNvbnZlcnRlZCA9IGlzQ29udmVydGVkO1xuICB9XG59XG5cbi8qKlxuICogVGVuc29yVHJhY2tlciB0cmFja3MgdGhlIE1MVGVuc29yIGFuZCBwZW5kaW5nIHVwbG9hZCBkYXRhLlxuICpcbiAqIFdlIG5lZWQgdG8gdHJhY2sgdGhlIE1MVGVuc29yIGFuZCBwZW5kaW5nIHVwbG9hZCBkYXRhIGJlY2F1c2Ugd2UgZGVsYXkgdGhlIGNyZWF0aW9uIG9mIE1MVGVuc29yIHVudGlsXG4gKiB3ZSBrbm93IHRoZSBkYXRhIHR5cGUgYW5kIHNoYXBlLiBUaGlzIGlzIGJlY2F1c2UgV2ViTk4gb25seSBzdXBwb3J0IGNyZWF0aW5nIE1MVGVuc29ycyB3aXRoIGRhdGFUeXBlcyBhbmQgc2hhcGUuXG4gKi9cbmNsYXNzIFRlbnNvcklkVHJhY2tlciB7XG4gIHByaXZhdGUgYWN0aXZlVXBsb2FkPzogVWludDhBcnJheTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHRlbnNvck1hbmFnZXI6IFRlbnNvck1hbmFnZXJJbXBsLFxuICAgIHByaXZhdGUgd3JhcHBlcj86IFRlbnNvcldyYXBwZXIsXG4gICkge31cblxuICBwdWJsaWMgZ2V0IHRlbnNvcldyYXBwZXIoKTogVGVuc29yV3JhcHBlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMud3JhcHBlcjtcbiAgfVxuXG4gIHB1YmxpYyByZWxlYXNlVGVuc29yKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnRlbnNvcldyYXBwZXIpIHtcbiAgICAgIHRoaXMudGVuc29yTWFuYWdlci5yZWxlYXNlVGVuc29yKHRoaXMudGVuc29yV3JhcHBlcik7XG4gICAgICB0aGlzLndyYXBwZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGVuc3VyZVRlbnNvcihcbiAgICBzZXNzaW9uSWQ6IG51bWJlcixcbiAgICBkYXRhVHlwZTogTUxPcGVyYW5kRGF0YVR5cGUsXG4gICAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGNvcHlPbGQ6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8TUxUZW5zb3I+IHtcbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcy50ZW5zb3JNYW5hZ2VyLmdldE1MQ29udGV4dChzZXNzaW9uSWQpO1xuICAgIGNvbnN0IG9wTGltaXRzID0gdGhpcy50ZW5zb3JNYW5hZ2VyLmdldE1MT3BTdXBwb3J0TGltaXRzKHNlc3Npb25JZCk7XG4gICAgbGV0IGZhbGxiYWNrRGF0YVR5cGU6IE1MT3BlcmFuZERhdGFUeXBlIHwgdW5kZWZpbmVkO1xuICAgIC8vIENoZWNrIGlmIHRoZSBjb250ZXh0IHN1cHBvcnRzIHRoZSBkYXRhIHR5cGUuIElmIG5vdCwgdHJ5IHRvIHVzZSB0aGUgZmFsbGJhY2sgZGF0YSB0eXBlLlxuICAgIGlmICghb3BMaW1pdHM/LmlucHV0LmRhdGFUeXBlcy5pbmNsdWRlcyhkYXRhVHlwZSkpIHtcbiAgICAgIGZhbGxiYWNrRGF0YVR5cGUgPSB3ZWJubkRhdGFUeXBlVG9GYWxsYmFjay5nZXQoZGF0YVR5cGUpO1xuICAgICAgaWYgKCFmYWxsYmFja0RhdGFUeXBlIHx8IG9wTGltaXRzPy5pbnB1dC5kYXRhVHlwZXMuaW5jbHVkZXMoZmFsbGJhY2tEYXRhVHlwZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBXZWJOTiBiYWNrZW5kIGRvZXMgbm90IHN1cHBvcnQgZGF0YSB0eXBlOiAke2RhdGFUeXBlfWApO1xuICAgICAgfVxuICAgICAgTE9HX0RFQlVHKFxuICAgICAgICAndmVyYm9zZScsXG4gICAgICAgICgpID0+IGBbV2ViTk5dIFRlbnNvcklkVHJhY2tlci5lbnN1cmVUZW5zb3I6IGZhbGxiYWNrIGRhdGFUeXBlIGZyb20gJHtkYXRhVHlwZX0gdG8gJHtmYWxsYmFja0RhdGFUeXBlfWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLndyYXBwZXIpIHtcbiAgICAgIGlmICh0aGlzLndyYXBwZXIuY2FuUmV1c2VUZW5zb3IoY29udGV4dCwgZGF0YVR5cGUsIHNoYXBlKSkge1xuICAgICAgICByZXR1cm4gdGhpcy53cmFwcGVyLnRlbnNvcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChjb3B5T2xkKSB7XG4gICAgICAgICAgaWYgKHRoaXMud3JhcHBlci5ieXRlTGVuZ3RoICE9PSBjYWxjdWxhdGVCeXRlTGVuZ3RoKGRhdGFUeXBlLCBzaGFwZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGNvcHkgZGF0YSB0byB0ZW5zb3Igd2l0aCBkaWZmZXJlbnQgc2l6ZS4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5hY3RpdmVVcGxvYWQgPSBuZXcgVWludDhBcnJheShhd2FpdCB0aGlzLndyYXBwZXIucmVhZCgpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRlbnNvck1hbmFnZXIucmVsZWFzZVRlbnNvcih0aGlzLndyYXBwZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgY29uc3QgdXNhZ2UgPSB0eXBlb2YgTUxUZW5zb3JVc2FnZSA9PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IE1MVGVuc29yVXNhZ2UuUkVBRCB8IE1MVGVuc29yVXNhZ2UuV1JJVEU7XG4gICAgdGhpcy53cmFwcGVyID0gYXdhaXQgdGhpcy50ZW5zb3JNYW5hZ2VyLmdldENhY2hlZFRlbnNvcihcbiAgICAgIHNlc3Npb25JZCxcbiAgICAgIGRhdGFUeXBlLFxuICAgICAgc2hhcGUsXG4gICAgICB1c2FnZSxcbiAgICAgIHRydWUsXG4gICAgICB0cnVlLFxuICAgICAgZmFsbGJhY2tEYXRhVHlwZSxcbiAgICApO1xuXG4gICAgaWYgKGNvcHlPbGQgJiYgdGhpcy5hY3RpdmVVcGxvYWQpIHtcbiAgICAgIC8vIFdlIGRvbid0IG5lZWQgdG8gY29udmVydCB0aGUgb3JpZ2luYWwgaW50ZWdlciBkYXRhIHRvIGludDMyLFxuICAgICAgLy8gYmVjYXVzZSBpdCBoYXMgYmVlbiBjb252ZXJ0ZWQgd2hlbiBpdCB3YXMgdXBsb2FkZWQuXG4gICAgICB0aGlzLndyYXBwZXIud3JpdGUodGhpcy5hY3RpdmVVcGxvYWQpO1xuICAgICAgdGhpcy5hY3RpdmVVcGxvYWQgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMud3JhcHBlci50ZW5zb3I7XG4gIH1cblxuICBwdWJsaWMgdXBsb2FkKGRhdGE6IFVpbnQ4QXJyYXkpOiB2b2lkIHtcbiAgICBsZXQgbmV3RGF0YSA9IGRhdGE7XG4gICAgaWYgKHRoaXMud3JhcHBlcikge1xuICAgICAgaWYgKHRoaXMud3JhcHBlci5mYWxsYmFja1R5cGUpIHtcbiAgICAgICAgaWYgKHRoaXMud3JhcHBlci5mYWxsYmFja1R5cGUgPT09ICdpbnQzMicpIHtcbiAgICAgICAgICAvLyBDb252ZXJ0IG9yaWdpbmFsIGludGVnZXIgZGF0YSB0byBpbnQzMi5cbiAgICAgICAgICBuZXdEYXRhID0gY29udmVydERhdGFUb0ludDMyKGRhdGEsIHRoaXMud3JhcHBlci50eXBlKTtcbiAgICAgICAgICB0aGlzLndyYXBwZXIuc2V0SXNEYXRhQ29udmVydGVkKHRydWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZmFsbGJhY2sgZGF0YSB0eXBlOiAke3RoaXMud3JhcHBlci5mYWxsYmFja1R5cGV9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgaWYgdGhlIGRhdGEgc2l6ZSBtYXRjaGVzIHRoZSB0ZW5zb3Igc2l6ZS5cbiAgICAgIGlmIChkYXRhLmJ5dGVMZW5ndGggPT09IHRoaXMud3JhcHBlci5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIC8vIFdyaXRlIHRoZSBuZXdEYXRhIHRvIHRoZSB0ZW5zb3IuXG4gICAgICAgIHRoaXMud3JhcHBlci53cml0ZShuZXdEYXRhKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgTE9HX0RFQlVHKCd2ZXJib3NlJywgKCkgPT4gJ0RhdGEgc2l6ZSBkb2VzIG5vdCBtYXRjaCB0ZW5zb3Igc2l6ZS4gUmVsZWFzaW5nIHRlbnNvci4nKTtcbiAgICAgICAgdGhpcy5yZWxlYXNlVGVuc29yKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYWN0aXZlVXBsb2FkKSB7XG4gICAgICB0aGlzLmFjdGl2ZVVwbG9hZC5zZXQobmV3RGF0YSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYWN0aXZlVXBsb2FkID0gbmV3IFVpbnQ4QXJyYXkobmV3RGF0YSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGRvd25sb2FkKGRzdEJ1ZmZlcj86IEFycmF5QnVmZmVyVmlldyB8IEFycmF5QnVmZmVyKTogUHJvbWlzZTxBcnJheUJ1ZmZlciB8IHVuZGVmaW5lZD4ge1xuICAgIGlmICh0aGlzLmFjdGl2ZVVwbG9hZCkge1xuICAgICAgLy8gSWYgdGhpcy5hY3RpdmVVcGxvYWQgaGFzIGJlZW4gY29udmVydGVkIHRvIGludDMyLCB3ZSBuZWVkIHRvIGNvbnZlcnQgaXQgYmFjayB0byBvcmlnaW5hbCBpbnRlZ2VyIGRhdGEgdHlwZS5cbiAgICAgIGNvbnN0IGRzdERhdGEgPSB0aGlzLndyYXBwZXI/LmlzRGF0YUNvbnZlcnRlZFxuICAgICAgICA/IGNvbnZlcnRJbnQzMlRvRGF0YSh0aGlzLmFjdGl2ZVVwbG9hZCwgdGhpcy53cmFwcGVyPy50eXBlKVxuICAgICAgICA6IHRoaXMuYWN0aXZlVXBsb2FkO1xuXG4gICAgICBpZiAoZHN0QnVmZmVyKSB7XG4gICAgICAgIGlmIChkc3RCdWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgICAgIG5ldyBVaW50OEFycmF5KGRzdEJ1ZmZlcikuc2V0KGRzdERhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ldyBVaW50OEFycmF5KGRzdEJ1ZmZlci5idWZmZXIsIGRzdEJ1ZmZlci5ieXRlT2Zmc2V0LCBkc3RCdWZmZXIuYnl0ZUxlbmd0aCkuc2V0KGRzdERhdGEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkc3REYXRhLmJ1ZmZlcjtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCF0aGlzLndyYXBwZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGVuc29yIGhhcyBub3QgYmVlbiBjcmVhdGVkLicpO1xuICAgIH1cblxuICAgIGlmICghZHN0QnVmZmVyKSB7XG4gICAgICByZXR1cm4gdGhpcy53cmFwcGVyLnJlYWQoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMud3JhcHBlci5yZWFkKGRzdEJ1ZmZlcik7XG4gIH1cbn1cblxuY2xhc3MgVGVuc29yTWFuYWdlckltcGwgaW1wbGVtZW50cyBUZW5zb3JNYW5hZ2VyIHtcbiAgcHJpdmF0ZSB0ZW5zb3JUcmFja2Vyc0J5SWQ6IE1hcDxUZW5zb3JJZCwgVGVuc29ySWRUcmFja2VyPiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBmcmVlVGVuc29yczogVGVuc29yV3JhcHBlcltdID0gW107XG4gIHByaXZhdGUgZXh0ZXJuYWxUZW5zb3JzOiBTZXQ8VGVuc29yV3JhcHBlcj4gPSBuZXcgU2V0KCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBiYWNrZW5kOiBXZWJOTkJhY2tlbmQpIHt9XG5cbiAgcHVibGljIGdldE1MQ29udGV4dChzZXNzaW9uSWQ6IG51bWJlcik6IE1MQ29udGV4dCB7XG4gICAgY29uc3QgY29udGV4dCA9IHRoaXMuYmFja2VuZC5nZXRNTENvbnRleHQoc2Vzc2lvbklkKTtcbiAgICBpZiAoIWNvbnRleHQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTUxDb250ZXh0IG5vdCBmb3VuZCBmb3Igc2Vzc2lvbi4nKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRleHQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0TUxPcFN1cHBvcnRMaW1pdHMoc2Vzc2lvbklkOiBudW1iZXIpOiBNTE9wU3VwcG9ydExpbWl0cyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuYmFja2VuZC5nZXRNTE9wU3VwcG9ydExpbWl0cyhzZXNzaW9uSWQpO1xuICB9XG5cbiAgcHVibGljIHJlc2VydmVUZW5zb3JJZCgpOiBUZW5zb3JJZCB7XG4gICAgY29uc3QgdGVuc29ySWQgPSBjcmVhdGVOZXdUZW5zb3JJZCgpO1xuICAgIHRoaXMudGVuc29yVHJhY2tlcnNCeUlkLnNldCh0ZW5zb3JJZCwgbmV3IFRlbnNvcklkVHJhY2tlcih0aGlzKSk7XG4gICAgcmV0dXJuIHRlbnNvcklkO1xuICB9XG5cbiAgcHVibGljIHJlbGVhc2VUZW5zb3JJZCh0ZW5zb3JJZDogVGVuc29ySWQpOiB2b2lkIHtcbiAgICBjb25zdCB0ZW5zb3JUcmFja2VyID0gdGhpcy50ZW5zb3JUcmFja2Vyc0J5SWQuZ2V0KHRlbnNvcklkKTtcbiAgICBpZiAoIXRlbnNvclRyYWNrZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy50ZW5zb3JUcmFja2Vyc0J5SWQuZGVsZXRlKHRlbnNvcklkKTtcbiAgICBpZiAodGVuc29yVHJhY2tlci50ZW5zb3JXcmFwcGVyKSB7XG4gICAgICB0aGlzLnJlbGVhc2VUZW5zb3IodGVuc29yVHJhY2tlci50ZW5zb3JXcmFwcGVyKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZW5zdXJlVGVuc29yKFxuICAgIHNlc3Npb25JZDogbnVtYmVyLFxuICAgIHRlbnNvcklkOiBUZW5zb3JJZCxcbiAgICBkYXRhVHlwZTogTUxPcGVyYW5kRGF0YVR5cGUsXG4gICAgc2hhcGU6IG51bWJlcltdLFxuICAgIGNvcHlPbGQ6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8TUxUZW5zb3I+IHtcbiAgICBMT0dfREVCVUcoXG4gICAgICAndmVyYm9zZScsXG4gICAgICAoKSA9PlxuICAgICAgICBgW1dlYk5OXSBUZW5zb3JNYW5hZ2VyLmVuc3VyZVRlbnNvciB7dGVuc29ySWQ6ICR7dGVuc29ySWR9LCBkYXRhVHlwZTogJHtcbiAgICAgICAgICBkYXRhVHlwZVxuICAgICAgICB9LCBzaGFwZTogJHtzaGFwZX0sIGNvcHlPbGQ6ICR7Y29weU9sZH19YCxcbiAgICApO1xuICAgIGNvbnN0IHRlbnNvciA9IHRoaXMudGVuc29yVHJhY2tlcnNCeUlkLmdldCh0ZW5zb3JJZCk7XG4gICAgaWYgKCF0ZW5zb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGVuc29yIG5vdCBmb3VuZC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRlbnNvci5lbnN1cmVUZW5zb3Ioc2Vzc2lvbklkLCBkYXRhVHlwZSwgc2hhcGUsIGNvcHlPbGQpO1xuICB9XG5cbiAgcHVibGljIHVwbG9hZCh0ZW5zb3JJZDogVGVuc29ySWQsIGRhdGE6IFVpbnQ4QXJyYXkpOiB2b2lkIHtcbiAgICBjb25zdCB0ZW5zb3IgPSB0aGlzLnRlbnNvclRyYWNrZXJzQnlJZC5nZXQodGVuc29ySWQpO1xuICAgIGlmICghdGVuc29yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RlbnNvciBub3QgZm91bmQuJyk7XG4gICAgfVxuICAgIHRlbnNvci51cGxvYWQoZGF0YSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZG93bmxvYWQodGVuc29ySWQ6IFRlbnNvcklkKTogUHJvbWlzZTxBcnJheUJ1ZmZlcj47XG4gIHB1YmxpYyBhc3luYyBkb3dubG9hZCh0ZW5zb3JJZDogVGVuc29ySWQsIGRzdEJ1ZmZlcjogQXJyYXlCdWZmZXJWaWV3IHwgQXJyYXlCdWZmZXIpOiBQcm9taXNlPHVuZGVmaW5lZD47XG4gIGFzeW5jIGRvd25sb2FkKHRlbnNvcklkOiBUZW5zb3JJZCwgZHN0QnVmZmVyPzogQXJyYXlCdWZmZXJWaWV3IHwgQXJyYXlCdWZmZXIpOiBQcm9taXNlPEFycmF5QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgTE9HX0RFQlVHKFxuICAgICAgJ3ZlcmJvc2UnLFxuICAgICAgKCkgPT4gYFtXZWJOTl0gVGVuc29yTWFuYWdlci5kb3dubG9hZCB7dGVuc29ySWQ6ICR7dGVuc29ySWR9LCBkc3RCdWZmZXI6ICR7ZHN0QnVmZmVyPy5ieXRlTGVuZ3RofX1gLFxuICAgICk7XG4gICAgY29uc3QgdGVuc29yVHJhY2tlciA9IHRoaXMudGVuc29yVHJhY2tlcnNCeUlkLmdldCh0ZW5zb3JJZCk7XG4gICAgaWYgKCF0ZW5zb3JUcmFja2VyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RlbnNvciBub3QgZm91bmQuJyk7XG4gICAgfVxuICAgIHJldHVybiB0ZW5zb3JUcmFja2VyLmRvd25sb2FkKGRzdEJ1ZmZlcik7XG4gIH1cblxuICBwdWJsaWMgcmVsZWFzZVRlbnNvcnNGb3JTZXNzaW9uKHNlc3Npb25JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCB0ZW5zb3Igb2YgdGhpcy5mcmVlVGVuc29ycykge1xuICAgICAgaWYgKHRlbnNvci5zZXNzaW9uSWQgPT09IHNlc3Npb25JZCkge1xuICAgICAgICB0ZW5zb3IuZGVzdHJveSgpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmZyZWVUZW5zb3JzID0gdGhpcy5mcmVlVGVuc29ycy5maWx0ZXIoKHRlbnNvcikgPT4gdGVuc29yLnNlc3Npb25JZCAhPT0gc2Vzc2lvbklkKTtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3RlclRlbnNvcihcbiAgICBzZXNzaW9uSWQ6IG51bWJlcixcbiAgICBtbFRlbnNvcjogTUxUZW5zb3IsXG4gICAgZGF0YVR5cGU6IE1MT3BlcmFuZERhdGFUeXBlLFxuICAgIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogVGVuc29ySWQge1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmdldE1MQ29udGV4dChzZXNzaW9uSWQpO1xuICAgIGNvbnN0IHRlbnNvcklkID0gY3JlYXRlTmV3VGVuc29ySWQoKTtcbiAgICAvLyBEZWZhdWx0aW5nIHRvIFJFQUQgfCBXUklURSBpZiB1c2FnZSBpcyBub3QgcHJvdmlkZWQuXG4gICAgY29uc3Qgd3JhcHBlciA9IG5ldyBUZW5zb3JXcmFwcGVyKHtcbiAgICAgIHNlc3Npb25JZCxcbiAgICAgIGNvbnRleHQsXG4gICAgICB0ZW5zb3I6IG1sVGVuc29yLFxuICAgICAgZGF0YVR5cGUsXG4gICAgICBzaGFwZSxcbiAgICB9KTtcbiAgICB0aGlzLnRlbnNvclRyYWNrZXJzQnlJZC5zZXQodGVuc29ySWQsIG5ldyBUZW5zb3JJZFRyYWNrZXIodGhpcywgd3JhcHBlcikpO1xuICAgIHRoaXMuZXh0ZXJuYWxUZW5zb3JzLmFkZCh3cmFwcGVyKTtcbiAgICByZXR1cm4gdGVuc29ySWQ7XG4gIH1cblxuICAvKipcbiAgICogR2V0IG9yIGNyZWF0ZSBhbiBNTFRlbnNvciB3aXRoIHRoZSBnaXZlbiBkYXRhIHR5cGUgYW5kIHNoYXBlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGdldENhY2hlZFRlbnNvcihcbiAgICBzZXNzaW9uSWQ6IG51bWJlcixcbiAgICBkYXRhVHlwZTogTUxPcGVyYW5kRGF0YVR5cGUsXG4gICAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHVzYWdlOiBNTFRlbnNvclVzYWdlRmxhZ3MgfCB1bmRlZmluZWQsXG4gICAgd3JpdGFibGU6IGJvb2xlYW4sXG4gICAgcmVhZGFibGU6IGJvb2xlYW4sXG4gICAgZmFsbGJhY2tEYXRhVHlwZT86IE1MT3BlcmFuZERhdGFUeXBlLFxuICApOiBQcm9taXNlPFRlbnNvcldyYXBwZXI+IHtcbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5nZXRNTENvbnRleHQoc2Vzc2lvbklkKTtcbiAgICBmb3IgKGNvbnN0IFtpbmRleCwgdGVuc29yXSBvZiB0aGlzLmZyZWVUZW5zb3JzLmVudHJpZXMoKSkge1xuICAgICAgaWYgKHRlbnNvci5jYW5SZXVzZVRlbnNvcihjb250ZXh0LCBkYXRhVHlwZSwgc2hhcGUpKSB7XG4gICAgICAgIExPR19ERUJVRyhcbiAgICAgICAgICAndmVyYm9zZScsXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIGBbV2ViTk5dIFJldXNpbmcgdGVuc29yIHtkYXRhVHlwZTogJHtkYXRhVHlwZX0sICR7XG4gICAgICAgICAgICAgIGZhbGxiYWNrRGF0YVR5cGUgPyBgZmFsbGJhY2tEYXRhVHlwZTogJHtmYWxsYmFja0RhdGFUeXBlfSxgIDogJydcbiAgICAgICAgICAgIH0gc2hhcGU6ICR7c2hhcGV9YCxcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qgd3JhcHBlciA9IHRoaXMuZnJlZVRlbnNvcnMuc3BsaWNlKGluZGV4LCAxKVswXTtcbiAgICAgICAgd3JhcHBlci5zZXNzaW9uSWQgPSBzZXNzaW9uSWQ7XG4gICAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgICAgfVxuICAgIH1cbiAgICBMT0dfREVCVUcoXG4gICAgICAndmVyYm9zZScsXG4gICAgICAoKSA9PlxuICAgICAgICBgW1dlYk5OXSBNTENvbnRleHQuY3JlYXRlVGVuc29yIHtkYXRhVHlwZTogJHtkYXRhVHlwZX0sICR7XG4gICAgICAgICAgZmFsbGJhY2tEYXRhVHlwZSA/IGBmYWxsYmFja0RhdGFUeXBlOiAke2ZhbGxiYWNrRGF0YVR5cGV9LGAgOiAnJ1xuICAgICAgICB9IHNoYXBlOiAke3NoYXBlfX1gLFxuICAgICk7XG4gICAgY29uc3QgdGVuc29yID0gYXdhaXQgY29udGV4dC5jcmVhdGVUZW5zb3Ioe1xuICAgICAgZGF0YVR5cGU6IGZhbGxiYWNrRGF0YVR5cGUgPz8gZGF0YVR5cGUsIC8vIElmIGZhbGxiYWNrIGRhdGEgdHlwZSBpcyBwcm92aWRlZCwgdXNlIGl0LlxuICAgICAgc2hhcGUsXG4gICAgICBkaW1lbnNpb25zOiBzaGFwZSxcbiAgICAgIHVzYWdlLFxuICAgICAgd3JpdGFibGUsXG4gICAgICByZWFkYWJsZSxcbiAgICB9KTtcbiAgICByZXR1cm4gbmV3IFRlbnNvcldyYXBwZXIoeyBzZXNzaW9uSWQsIGNvbnRleHQsIHRlbnNvciwgZGF0YVR5cGUsIHNoYXBlLCBmYWxsYmFja0RhdGFUeXBlIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGVhc2UgdGVuc29yIGZvciByZXVzZSB1bmxlc3MgZXh0ZXJuYWwuXG4gICAqL1xuICBwdWJsaWMgcmVsZWFzZVRlbnNvcih0ZW5zb3JXcmFwcGVyOiBUZW5zb3JXcmFwcGVyKSB7XG4gICAgaWYgKHRoaXMuZXh0ZXJuYWxUZW5zb3JzLmhhcyh0ZW5zb3JXcmFwcGVyKSkge1xuICAgICAgdGhpcy5leHRlcm5hbFRlbnNvcnMuZGVsZXRlKHRlbnNvcldyYXBwZXIpO1xuICAgIH1cbiAgICB0aGlzLmZyZWVUZW5zb3JzLnB1c2godGVuc29yV3JhcHBlcik7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVRlbnNvck1hbmFnZXIgPSAoLi4uYXJnczogQ29uc3RydWN0b3JQYXJhbWV0ZXJzPHR5cGVvZiBUZW5zb3JNYW5hZ2VySW1wbD4pOiBUZW5zb3JNYW5hZ2VyID0+XG4gIG5ldyBUZW5zb3JNYW5hZ2VySW1wbCguLi5hcmdzKTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLy8gV2ViTk4gQVBJIGN1cnJlbnRseSBkb2VzIG5vdCBoYXZlIGEgVHlwZVNjcmlwdCBkZWZpbml0aW9uIGZpbGUuIFRoaXMgZmlsZSBpcyBhIHdvcmthcm91bmQgd2l0aCB0eXBlcyBnZW5lcmF0ZWQgZnJvbVxuLy8gV2ViTk4gQVBJIHNwZWNpZmljYXRpb24uXG4vLyBodHRwczovL2dpdGh1Yi5jb20vd2VibWFjaGluZWxlYXJuaW5nL3dlYm5uL2lzc3Vlcy82Nzdcbi8vLyA8cmVmZXJlbmNlIHBhdGg9XCJ3ZWJubi93ZWJubi5kLnRzXCIgLz5cblxuaW1wb3J0IHsgRW52LCBUZW5zb3IgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBEYXRhVHlwZSwgdGVuc29yRGF0YVR5cGVTdHJpbmdUb0VudW0gfSBmcm9tICcuLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBnZXRJbnN0YW5jZSB9IGZyb20gJy4uL3dhc20tZmFjdG9yeSc7XG5cbmltcG9ydCB7IGNyZWF0ZVZpZXcgfSBmcm9tICcuL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFRlbnNvcklkLCBjcmVhdGVUZW5zb3JNYW5hZ2VyLCBjb252ZXJ0RGF0YVRvSW50MzIgfSBmcm9tICcuL3dlYm5uL3RlbnNvci1tYW5hZ2VyJztcbmltcG9ydCB7IGNvbmZpZ3VyZUxvZ2dlciwgTE9HX0RFQlVHIH0gZnJvbSAnLi9sb2cnO1xuXG4vKlxuICogVGVuc29yUHJvdG86OmRhdGFfdHlwZSB0byBXZWJOTiBPcGVyYW5kVHlwZSBtYXBwaW5nLlxuICovXG5jb25zdCBvbm54RGF0YVR5cGVUb1dlYm5uRGF0YVR5cGUgPSBuZXcgTWFwPERhdGFUeXBlLCBNTE9wZXJhbmREYXRhVHlwZT4oW1xuICBbRGF0YVR5cGUuZmxvYXQsICdmbG9hdDMyJ10sXG4gIFtEYXRhVHlwZS5mbG9hdDE2LCAnZmxvYXQxNiddLFxuICBbRGF0YVR5cGUuaW50MzIsICdpbnQzMiddLFxuICBbRGF0YVR5cGUudWludDMyLCAndWludDMyJ10sXG4gIFtEYXRhVHlwZS5pbnQ2NCwgJ2ludDY0J10sXG4gIFtEYXRhVHlwZS51aW50NjQsICd1aW50NjQnXSxcbiAgW0RhdGFUeXBlLmludDQsICdpbnQ0J10sXG4gIFtEYXRhVHlwZS51aW50NCwgJ3VpbnQ0J10sXG4gIFtEYXRhVHlwZS5pbnQ4LCAnaW50OCddLFxuICBbRGF0YVR5cGUudWludDgsICd1aW50OCddLFxuICBbRGF0YVR5cGUuYm9vbCwgJ3VpbnQ4J10sXG5dKTtcblxudHlwZSBNTENvbnRleHRFbnRyeSA9IHtcbiAgZ3B1RGV2aWNlPzogR1BVRGV2aWNlO1xuICBvcHRpb25zPzogTUxDb250ZXh0T3B0aW9ucztcbiAgbWxDb250ZXh0OiBNTENvbnRleHQ7XG59O1xuXG5jb25zdCBjb21wYXJlTUxDb250ZXh0T3B0aW9ucyA9IChhPzogTUxDb250ZXh0T3B0aW9ucywgYj86IE1MQ29udGV4dE9wdGlvbnMpOiBib29sZWFuID0+IHtcbiAgaWYgKGEgPT09IGIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoYSA9PT0gdW5kZWZpbmVkIHx8IGIgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCBhS2V5cyA9IE9iamVjdC5rZXlzKGEpLnNvcnQoKSBhcyBBcnJheTxrZXlvZiB0eXBlb2YgYT47XG4gIGNvbnN0IGJLZXlzID0gT2JqZWN0LmtleXMoYikuc29ydCgpIGFzIEFycmF5PGtleW9mIHR5cGVvZiBiPjtcbiAgcmV0dXJuIGFLZXlzLmxlbmd0aCA9PT0gYktleXMubGVuZ3RoICYmIGFLZXlzLmV2ZXJ5KChrZXksIGluZGV4KSA9PiBrZXkgPT09IGJLZXlzW2luZGV4XSAmJiBhW2tleV0gPT09IGJba2V5XSk7XG59O1xuXG4vKipcbiAqIFdlYk5OIGJhY2tlbmQgaW1wbGVtZW50YXRpb24uIFRoaXMgY2xhc3MgaXMgdXNlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBNTFRlbnNvcnMgY3JlYXRlZCBieSB0aGUgYmFja2VuZCBhbmQga2VlcCB0cmFja1xuICogb2YgdGhlIGN1cnJlbnQgTUxDb250ZXh0IGJlaW5nIHVzZWQgYnkgdGhlIHNlc3Npb25zLlxuICovXG5leHBvcnQgY2xhc3MgV2ViTk5CYWNrZW5kIHtcbiAgLyoqXG4gICAqIFRlbnNvciBtYW5hZ2VycyBmb3IgZWFjaCBzZXNzaW9uLlxuICAgKi9cbiAgcHJpdmF0ZSB0ZW5zb3JNYW5hZ2VyID0gY3JlYXRlVGVuc29yTWFuYWdlcih0aGlzKTtcbiAgLyoqXG4gICAqIE1hcHMgZnJvbSBzZXNzaW9uIGlkIHRvIE1MQ29udGV4dHMuXG4gICAqL1xuICBwcml2YXRlIG1sQ29udGV4dEJ5U2Vzc2lvbklkID0gbmV3IE1hcDxudW1iZXIsIE1MQ29udGV4dD4oKTtcbiAgLyoqXG4gICAqIE1hcHMgZnJvbSBNTENvbnRleHQgdG8gc2Vzc2lvbiBpZHMuXG4gICAqL1xuICBwcml2YXRlIHNlc3Npb25JZHNCeU1MQ29udGV4dCA9IG5ldyBNYXA8TUxDb250ZXh0LCBTZXQ8bnVtYmVyPj4oKTtcbiAgLyoqXG4gICAqIENhY2hlIG9mIE1MQ29udGV4dHMuXG4gICAqL1xuICBwcml2YXRlIG1sQ29udGV4dENhY2hlOiBNTENvbnRleHRFbnRyeVtdID0gW107XG4gIC8qKlxuICAgKiBDdXJyZW50IHNlc3Npb24gaWQuXG4gICAqL1xuICBwcml2YXRlIGFjdGl2ZVNlc3Npb25JZD86IG51bWJlcjtcbiAgLyoqXG4gICAqIE1hcHMgZnJvbSBzZXNzaW9uIGlkIHRvIGxpc3Qgb2YgZ3JhcGggaW5wdXRzLlxuICAgKi9cbiAgcHJpdmF0ZSBzZXNzaW9uR3JhcGhJbnB1dHM6IE1hcDxudW1iZXIsIHN0cmluZ1tdPiA9IG5ldyBNYXAoKTtcbiAgLyoqXG4gICAqIE1hcHMgZnJvbSBzZXNzaW9uIGlkIHRvIGxpc3Qgb2YgZ3JhcGggb3V0cHV0cy5cbiAgICovXG4gIHByaXZhdGUgc2Vzc2lvbkdyYXBoT3V0cHV0czogTWFwPG51bWJlciwgc3RyaW5nW10+ID0gbmV3IE1hcCgpO1xuICAvKipcbiAgICogVGVtcG9yYXJ5IGdyYXBoIGlucHV0cyBmb3IgdGhlIGN1cnJlbnQgc2Vzc2lvbi5cbiAgICogVGhlc2UgaW5wdXRzIHdpbGwgYmUgcmVnaXN0ZXJlZCB3aGVuIHRoZSBzZXNzaW9uIGlzIGNyZWF0ZWQuXG4gICAqL1xuICBwcml2YXRlIHRlbXBvcmFyeUdyYXBoSW5wdXRzOiBzdHJpbmdbXSA9IFtdO1xuICAvKipcbiAgICogVGVtcG9yYXJ5IGdyYXBoIG91dHB1dHMgZm9yIHRoZSBjdXJyZW50IHNlc3Npb24uXG4gICAqIFRoZXNlIG91dHB1dHMgd2lsbCBiZSByZWdpc3RlcmVkIHdoZW4gdGhlIHNlc3Npb24gaXMgY3JlYXRlZC5cbiAgICovXG4gIHByaXZhdGUgdGVtcG9yYXJ5R3JhcGhPdXRwdXRzOiBzdHJpbmdbXSA9IFtdO1xuICAvKipcbiAgICogVGVtcG9yYXJ5IHRlbnNvcnMgZm9yIHRoZSBjdXJyZW50IHNlc3Npb24uXG4gICAqL1xuICBwcml2YXRlIHRlbXBvcmFyeVNlc3Npb25UZW5zb3JJZHM6IE1hcDxudW1iZXIsIFRlbnNvcklkW10+ID0gbmV3IE1hcCgpO1xuICAvKipcbiAgICogTWFwcyBmcm9tIHNlc3Npb24gaWQgdG8gTUxPcFN1cHBvcnRMaW1pdHMuXG4gICAqL1xuICBwcml2YXRlIG1sT3BTdXBwb3J0TGltaXRzQnlTZXNzaW9uSWQgPSBuZXcgTWFwPG51bWJlciwgTUxPcFN1cHBvcnRMaW1pdHM+KCk7XG5cbiAgY29uc3RydWN0b3IoZW52OiBFbnYpIHtcbiAgICBjb25maWd1cmVMb2dnZXIoZW52LmxvZ0xldmVsISwgISFlbnYuZGVidWcpO1xuICB9XG5cbiAgcHVibGljIGdldCBjdXJyZW50U2Vzc2lvbklkKCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuYWN0aXZlU2Vzc2lvbklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gYWN0aXZlIHNlc3Npb24nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlU2Vzc2lvbklkO1xuICB9XG5cbiAgcHVibGljIG9uUnVuU3RhcnQoc2Vzc2lvbklkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBMT0dfREVCVUcoJ3ZlcmJvc2UnLCAoKSA9PiBgW1dlYk5OXSBvblJ1blN0YXJ0IHtzZXNzaW9uSWQ6ICR7c2Vzc2lvbklkfX1gKTtcbiAgICB0aGlzLmFjdGl2ZVNlc3Npb25JZCA9IHNlc3Npb25JZDtcbiAgfVxuXG4gIHB1YmxpYyBvblJ1bkVuZChzZXNzaW9uSWQ6IG51bWJlcik6IHZvaWQge1xuICAgIExPR19ERUJVRygndmVyYm9zZScsICgpID0+IGBbV2ViTk5dIG9uUnVuRW5kIHtzZXNzaW9uSWQ6ICR7c2Vzc2lvbklkfX1gKTtcbiAgICBjb25zdCB0ZW5zb3JJZHMgPSB0aGlzLnRlbXBvcmFyeVNlc3Npb25UZW5zb3JJZHMuZ2V0KHNlc3Npb25JZCk7XG4gICAgaWYgKCF0ZW5zb3JJZHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCB0ZW5zb3JJZCBvZiB0ZW5zb3JJZHMpIHtcbiAgICAgIExPR19ERUJVRygndmVyYm9zZScsICgpID0+IGBbV2ViTk5dIHJlbGVhc2luZyB0ZW1wb3JhcnkgdGVuc29yIHt0ZW5zb3JJZDogJHt0ZW5zb3JJZH19YCk7XG4gICAgICB0aGlzLnRlbnNvck1hbmFnZXIucmVsZWFzZVRlbnNvcklkKHRlbnNvcklkKTtcbiAgICB9XG4gICAgdGhpcy50ZW1wb3JhcnlTZXNzaW9uVGVuc29ySWRzLmRlbGV0ZShzZXNzaW9uSWQpO1xuICAgIHRoaXMuYWN0aXZlU2Vzc2lvbklkID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGNyZWF0ZU1MQ29udGV4dChvcHRpb25zT3JEZXZpY2U/OiBNTENvbnRleHRPcHRpb25zIHwgR1BVRGV2aWNlKTogUHJvbWlzZTxNTENvbnRleHQ+IHtcbiAgICBpZiAob3B0aW9uc09yRGV2aWNlIGluc3RhbmNlb2YgR1BVRGV2aWNlKSB7XG4gICAgICBjb25zdCBtbENvbnRleHRJbmRleCA9IHRoaXMubWxDb250ZXh0Q2FjaGUuZmluZEluZGV4KChlbnRyeSkgPT4gZW50cnkuZ3B1RGV2aWNlID09PSBvcHRpb25zT3JEZXZpY2UpO1xuICAgICAgaWYgKG1sQ29udGV4dEluZGV4ICE9PSAtMSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tbENvbnRleHRDYWNoZVttbENvbnRleHRJbmRleF0ubWxDb250ZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbWxDb250ZXh0ID0gYXdhaXQgbmF2aWdhdG9yLm1sLmNyZWF0ZUNvbnRleHQob3B0aW9uc09yRGV2aWNlKTtcbiAgICAgICAgdGhpcy5tbENvbnRleHRDYWNoZS5wdXNoKHsgZ3B1RGV2aWNlOiBvcHRpb25zT3JEZXZpY2UsIG1sQ29udGV4dCB9KTtcbiAgICAgICAgcmV0dXJuIG1sQ29udGV4dDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9wdGlvbnNPckRldmljZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBtbENvbnRleHRJbmRleCA9IHRoaXMubWxDb250ZXh0Q2FjaGUuZmluZEluZGV4KFxuICAgICAgICAoZW50cnkpID0+IGVudHJ5Lm9wdGlvbnMgPT09IHVuZGVmaW5lZCAmJiBlbnRyeS5ncHVEZXZpY2UgPT09IHVuZGVmaW5lZCxcbiAgICAgICk7XG4gICAgICBpZiAobWxDb250ZXh0SW5kZXggIT09IC0xKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1sQ29udGV4dENhY2hlW21sQ29udGV4dEluZGV4XS5tbENvbnRleHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBtbENvbnRleHQgPSBhd2FpdCBuYXZpZ2F0b3IubWwuY3JlYXRlQ29udGV4dCgpO1xuICAgICAgICB0aGlzLm1sQ29udGV4dENhY2hlLnB1c2goeyBtbENvbnRleHQgfSk7XG4gICAgICAgIHJldHVybiBtbENvbnRleHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbWxDb250ZXh0SW5kZXggPSB0aGlzLm1sQ29udGV4dENhY2hlLmZpbmRJbmRleCgoZW50cnkpID0+XG4gICAgICBjb21wYXJlTUxDb250ZXh0T3B0aW9ucyhlbnRyeS5vcHRpb25zLCBvcHRpb25zT3JEZXZpY2UpLFxuICAgICk7XG4gICAgaWYgKG1sQ29udGV4dEluZGV4ICE9PSAtMSkge1xuICAgICAgcmV0dXJuIHRoaXMubWxDb250ZXh0Q2FjaGVbbWxDb250ZXh0SW5kZXhdLm1sQ29udGV4dDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbWxDb250ZXh0ID0gYXdhaXQgbmF2aWdhdG9yLm1sLmNyZWF0ZUNvbnRleHQob3B0aW9uc09yRGV2aWNlKTtcbiAgICAgIHRoaXMubWxDb250ZXh0Q2FjaGUucHVzaCh7IG9wdGlvbnM6IG9wdGlvbnNPckRldmljZSwgbWxDb250ZXh0IH0pO1xuICAgICAgcmV0dXJuIG1sQ29udGV4dDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcmVnaXN0ZXJNTENvbnRleHQoc2Vzc2lvbklkOiBudW1iZXIsIG1sQ29udGV4dDogTUxDb250ZXh0KTogdm9pZCB7XG4gICAgdGhpcy5tbENvbnRleHRCeVNlc3Npb25JZC5zZXQoc2Vzc2lvbklkLCBtbENvbnRleHQpO1xuICAgIGxldCBzZXNzaW9uSWRzID0gdGhpcy5zZXNzaW9uSWRzQnlNTENvbnRleHQuZ2V0KG1sQ29udGV4dCk7XG4gICAgaWYgKCFzZXNzaW9uSWRzKSB7XG4gICAgICBzZXNzaW9uSWRzID0gbmV3IFNldCgpO1xuICAgICAgdGhpcy5zZXNzaW9uSWRzQnlNTENvbnRleHQuc2V0KG1sQ29udGV4dCwgc2Vzc2lvbklkcyk7XG4gICAgfVxuICAgIHNlc3Npb25JZHMuYWRkKHNlc3Npb25JZCk7XG5cbiAgICBpZiAoIXRoaXMubWxPcFN1cHBvcnRMaW1pdHNCeVNlc3Npb25JZC5oYXMoc2Vzc2lvbklkKSkge1xuICAgICAgdGhpcy5tbE9wU3VwcG9ydExpbWl0c0J5U2Vzc2lvbklkLnNldChzZXNzaW9uSWQsIG1sQ29udGV4dC5vcFN1cHBvcnRMaW1pdHMoKSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGVtcG9yYXJ5R3JhcGhJbnB1dHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5zZXNzaW9uR3JhcGhJbnB1dHMuc2V0KHNlc3Npb25JZCwgdGhpcy50ZW1wb3JhcnlHcmFwaElucHV0cyk7XG4gICAgICB0aGlzLnRlbXBvcmFyeUdyYXBoSW5wdXRzID0gW107XG4gICAgfVxuICAgIGlmICh0aGlzLnRlbXBvcmFyeUdyYXBoT3V0cHV0cy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNlc3Npb25HcmFwaE91dHB1dHMuc2V0KHNlc3Npb25JZCwgdGhpcy50ZW1wb3JhcnlHcmFwaE91dHB1dHMpO1xuICAgICAgdGhpcy50ZW1wb3JhcnlHcmFwaE91dHB1dHMgPSBbXTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgb25SZWxlYXNlU2Vzc2lvbihzZXNzaW9uSWQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuc2Vzc2lvbkdyYXBoSW5wdXRzLmRlbGV0ZShzZXNzaW9uSWQpO1xuICAgIHRoaXMuc2Vzc2lvbkdyYXBoT3V0cHV0cy5kZWxldGUoc2Vzc2lvbklkKTtcbiAgICBjb25zdCBtbENvbnRleHQgPSB0aGlzLm1sQ29udGV4dEJ5U2Vzc2lvbklkLmdldChzZXNzaW9uSWQpITtcbiAgICBpZiAoIW1sQ29udGV4dCkge1xuICAgICAgLy8gQ3VycmVudCBzZXNzaW9uIGlzIG5vdCBhIFdlYk5OIHNlc3Npb24uXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudGVuc29yTWFuYWdlci5yZWxlYXNlVGVuc29yc0ZvclNlc3Npb24oc2Vzc2lvbklkKTtcbiAgICB0aGlzLm1sQ29udGV4dEJ5U2Vzc2lvbklkLmRlbGV0ZShzZXNzaW9uSWQpO1xuICAgIHRoaXMubWxPcFN1cHBvcnRMaW1pdHNCeVNlc3Npb25JZC5kZWxldGUoc2Vzc2lvbklkKTtcbiAgICBjb25zdCBzZXNzaW9uSWRzID0gdGhpcy5zZXNzaW9uSWRzQnlNTENvbnRleHQuZ2V0KG1sQ29udGV4dCkhO1xuICAgIHNlc3Npb25JZHMuZGVsZXRlKHNlc3Npb25JZCk7XG4gICAgaWYgKHNlc3Npb25JZHMuc2l6ZSA9PT0gMCkge1xuICAgICAgdGhpcy5zZXNzaW9uSWRzQnlNTENvbnRleHQuZGVsZXRlKG1sQ29udGV4dCk7XG4gICAgICBjb25zdCBtbENvbnRleHRJbmRleCA9IHRoaXMubWxDb250ZXh0Q2FjaGUuZmluZEluZGV4KChlbnRyeSkgPT4gZW50cnkubWxDb250ZXh0ID09PSBtbENvbnRleHQpO1xuICAgICAgaWYgKG1sQ29udGV4dEluZGV4ICE9PSAtMSkge1xuICAgICAgICB0aGlzLm1sQ29udGV4dENhY2hlLnNwbGljZShtbENvbnRleHRJbmRleCwgMSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldE1MQ29udGV4dChzZXNzaW9uSWQ6IG51bWJlcik6IE1MQ29udGV4dCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMubWxDb250ZXh0QnlTZXNzaW9uSWQuZ2V0KHNlc3Npb25JZCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0TUxPcFN1cHBvcnRMaW1pdHMoc2Vzc2lvbklkOiBudW1iZXIpOiBNTE9wU3VwcG9ydExpbWl0cyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMubWxPcFN1cHBvcnRMaW1pdHNCeVNlc3Npb25JZC5nZXQoc2Vzc2lvbklkKTtcbiAgfVxuXG4gIHB1YmxpYyByZXNlcnZlVGVuc29ySWQoKTogVGVuc29ySWQge1xuICAgIHJldHVybiB0aGlzLnRlbnNvck1hbmFnZXIucmVzZXJ2ZVRlbnNvcklkKCk7XG4gIH1cblxuICBwdWJsaWMgcmVsZWFzZVRlbnNvcklkKHRlbnNvcklkOiBUZW5zb3JJZCk6IHZvaWQge1xuICAgIExPR19ERUJVRygndmVyYm9zZScsICgpID0+IGBbV2ViTk5dIHJlbGVhc2VUZW5zb3JJZCB7dGVuc29ySWQ6ICR7dGVuc29ySWR9fWApO1xuICAgIHRoaXMudGVuc29yTWFuYWdlci5yZWxlYXNlVGVuc29ySWQodGVuc29ySWQpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGVuc3VyZVRlbnNvcihcbiAgICBzZXNzaW9uSWQ6IG51bWJlciB8IHVuZGVmaW5lZCxcbiAgICB0ZW5zb3JJZDogVGVuc29ySWQsXG4gICAgb25ueERhdGFUeXBlOiBEYXRhVHlwZSxcbiAgICBkaW1lbnNpb25zOiBudW1iZXJbXSxcbiAgICBjb3B5T2xkOiBib29sZWFuLFxuICApOiBQcm9taXNlPE1MVGVuc29yPiB7XG4gICAgY29uc3Qgd2Vibm5EYXRhVHlwZSA9IG9ubnhEYXRhVHlwZVRvV2Vibm5EYXRhVHlwZS5nZXQob25ueERhdGFUeXBlKTtcbiAgICBpZiAoIXdlYm5uRGF0YVR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgT05OWCBkYXRhIHR5cGU6ICR7b25ueERhdGFUeXBlfWApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy50ZW5zb3JNYW5hZ2VyLmVuc3VyZVRlbnNvcihcbiAgICAgIHNlc3Npb25JZCA/PyB0aGlzLmN1cnJlbnRTZXNzaW9uSWQsXG4gICAgICB0ZW5zb3JJZCxcbiAgICAgIHdlYm5uRGF0YVR5cGUsXG4gICAgICBkaW1lbnNpb25zLFxuICAgICAgY29weU9sZCxcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGNyZWF0ZVRlbXBvcmFyeVRlbnNvcihcbiAgICBzZXNzaW9uSWQ6IG51bWJlcixcbiAgICBvbm54RGF0YVR5cGU6IERhdGFUeXBlLFxuICAgIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogUHJvbWlzZTxUZW5zb3JJZD4ge1xuICAgIExPR19ERUJVRygndmVyYm9zZScsICgpID0+IGBbV2ViTk5dIGNyZWF0ZVRlbXBvcmFyeVRlbnNvciB7b25ueERhdGFUeXBlOiAke29ubnhEYXRhVHlwZX0sIHNoYXBlOiAke3NoYXBlfX1gKTtcbiAgICBjb25zdCBkYXRhVHlwZSA9IG9ubnhEYXRhVHlwZVRvV2Vibm5EYXRhVHlwZS5nZXQob25ueERhdGFUeXBlKTtcbiAgICBpZiAoIWRhdGFUeXBlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIE9OTlggZGF0YSB0eXBlOiAke29ubnhEYXRhVHlwZX1gKTtcbiAgICB9XG4gICAgY29uc3QgdGVuc29ySWQgPSB0aGlzLnRlbnNvck1hbmFnZXIucmVzZXJ2ZVRlbnNvcklkKCk7XG4gICAgYXdhaXQgdGhpcy50ZW5zb3JNYW5hZ2VyLmVuc3VyZVRlbnNvcihzZXNzaW9uSWQsIHRlbnNvcklkLCBkYXRhVHlwZSwgc2hhcGUsIGZhbHNlKTtcbiAgICBjb25zdCB0ZW5zb3JJZHMgPSB0aGlzLnRlbXBvcmFyeVNlc3Npb25UZW5zb3JJZHMuZ2V0KHNlc3Npb25JZCk7XG4gICAgaWYgKCF0ZW5zb3JJZHMpIHtcbiAgICAgIHRoaXMudGVtcG9yYXJ5U2Vzc2lvblRlbnNvcklkcy5zZXQoc2Vzc2lvbklkLCBbdGVuc29ySWRdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGVuc29ySWRzLnB1c2godGVuc29ySWQpO1xuICAgIH1cbiAgICByZXR1cm4gdGVuc29ySWQ7XG4gIH1cblxuICBwdWJsaWMgdXBsb2FkVGVuc29yKHRlbnNvcklkOiBUZW5zb3JJZCwgZGF0YTogVWludDhBcnJheSk6IHZvaWQge1xuICAgIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICAgIGlmICghd2FzbS5zaG91bGRUcmFuc2ZlclRvTUxUZW5zb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVHJ5aW5nIHRvIHVwbG9hZCB0byBhIE1MVGVuc29yIHdoaWxlIHNob3VsZFRyYW5zZmVyVG9NTFRlbnNvciBpcyBmYWxzZScpO1xuICAgIH1cbiAgICBMT0dfREVCVUcoJ3ZlcmJvc2UnLCAoKSA9PiBgW1dlYk5OXSB1cGxvYWRUZW5zb3Ige3RlbnNvcklkOiAke3RlbnNvcklkfSwgZGF0YTogJHtkYXRhLmJ5dGVMZW5ndGh9fWApO1xuICAgIHRoaXMudGVuc29yTWFuYWdlci51cGxvYWQodGVuc29ySWQsIGRhdGEpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGRvd25sb2FkVGVuc29yKHRlbnNvcklkOiBUZW5zb3JJZCwgZHN0QnVmZmVyOiBBcnJheUJ1ZmZlclZpZXcgfCBBcnJheUJ1ZmZlcik6IFByb21pc2U8dW5kZWZpbmVkPiB7XG4gICAgcmV0dXJuIHRoaXMudGVuc29yTWFuYWdlci5kb3dubG9hZCh0ZW5zb3JJZCwgZHN0QnVmZmVyKTtcbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVNTFRlbnNvckRvd25sb2FkZXIodGVuc29ySWQ6IFRlbnNvcklkLCB0eXBlOiBUZW5zb3IuTUxUZW5zb3JEYXRhVHlwZXMpOiAoKSA9PiBQcm9taXNlPFRlbnNvci5EYXRhVHlwZT4ge1xuICAgIHJldHVybiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy50ZW5zb3JNYW5hZ2VyLmRvd25sb2FkKHRlbnNvcklkKTtcbiAgICAgIHJldHVybiBjcmVhdGVWaWV3KGRhdGEsIHR5cGUpO1xuICAgIH07XG4gIH1cblxuICBwdWJsaWMgcmVnaXN0ZXJNTFRlbnNvcihzZXNzaW9uSWQ6IG51bWJlciwgdGVuc29yOiBNTFRlbnNvciwgb25ueERhdGFUeXBlOiBEYXRhVHlwZSwgZGltZW5zaW9uczogbnVtYmVyW10pOiBUZW5zb3JJZCB7XG4gICAgY29uc3Qgd2Vibm5EYXRhVHlwZSA9IG9ubnhEYXRhVHlwZVRvV2Vibm5EYXRhVHlwZS5nZXQob25ueERhdGFUeXBlKTtcbiAgICBpZiAoIXdlYm5uRGF0YVR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgT05OWCBkYXRhIHR5cGU6ICR7b25ueERhdGFUeXBlfWApO1xuICAgIH1cblxuICAgIGNvbnN0IGlkID0gdGhpcy50ZW5zb3JNYW5hZ2VyLnJlZ2lzdGVyVGVuc29yKHNlc3Npb25JZCwgdGVuc29yLCB3ZWJubkRhdGFUeXBlLCBkaW1lbnNpb25zKTtcbiAgICBMT0dfREVCVUcoXG4gICAgICAndmVyYm9zZScsXG4gICAgICAoKSA9PlxuICAgICAgICBgW1dlYk5OXSByZWdpc3Rlck1MVGVuc29yIHt0ZW5zb3I6ICR7dGVuc29yfSwgZGF0YVR5cGU6ICR7d2Vibm5EYXRhVHlwZX0sIGRpbWVuc2lvbnM6ICR7XG4gICAgICAgICAgZGltZW5zaW9uc1xuICAgICAgICB9fSAtPiB7dGVuc29ySWQ6ICR7aWR9fWAsXG4gICAgKTtcbiAgICByZXR1cm4gaWQ7XG4gIH1cblxuICAvLyBSZWdpc3RlciBhIFdlYk5OIENvbnN0YW50IG9wZXJhbmQgZnJvbSBleHRlcm5hbCBkYXRhLlxuICBwdWJsaWMgcmVnaXN0ZXJNTENvbnN0YW50KFxuICAgIGV4dGVybmFsRmlsZVBhdGg6IHN0cmluZyxcbiAgICBkYXRhT2Zmc2V0OiBudW1iZXIsXG4gICAgZGF0YUxlbmd0aDogbnVtYmVyLFxuICAgIGJ1aWxkZXI6IE1MR3JhcGhCdWlsZGVyLFxuICAgIGRlc2M6IE1MT3BlcmFuZERlc2NyaXB0b3IsXG4gICAgbW91bnRlZEZpbGVzOiBNYXA8c3RyaW5nLCBVaW50OEFycmF5PiB8IHVuZGVmaW5lZCxcbiAgICBzaG91bGRDb252ZXJ0SW50NjRUb0ludDMyID0gZmFsc2UsXG4gICk6IE1MT3BlcmFuZCB7XG4gICAgLy8gSWYgYXZhaWxhYmxlLCBcIk1vZHVsZS5Nb3VudGVkRmlsZXNcIiBpcyBhIE1hcCBmb3IgYWxsIHByZWxvYWRlZCBmaWxlcy5cbiAgICBpZiAoIW1vdW50ZWRGaWxlcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHRlcm5hbCBtb3VudGVkIGZpbGVzIGFyZSBub3QgYXZhaWxhYmxlLicpO1xuICAgIH1cblxuICAgIGxldCBmaWxlUGF0aCA9IGV4dGVybmFsRmlsZVBhdGg7XG4gICAgaWYgKGV4dGVybmFsRmlsZVBhdGguc3RhcnRzV2l0aCgnLi8nKSkge1xuICAgICAgZmlsZVBhdGggPSBleHRlcm5hbEZpbGVQYXRoLnN1YnN0cmluZygyKTtcbiAgICB9XG4gICAgY29uc3QgZmlsZURhdGEgPSBtb3VudGVkRmlsZXMuZ2V0KGZpbGVQYXRoKTtcbiAgICBpZiAoIWZpbGVEYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZpbGUgd2l0aCBuYW1lICR7ZmlsZVBhdGh9IG5vdCBmb3VuZCBpbiBwcmVsb2FkZWQgZmlsZXMuYCk7XG4gICAgfVxuXG4gICAgaWYgKGRhdGFPZmZzZXQgKyBkYXRhTGVuZ3RoID4gZmlsZURhdGEuYnl0ZUxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdPdXQgb2YgYm91bmRzOiBkYXRhIG9mZnNldCBhbmQgbGVuZ3RoIGV4Y2VlZCB0aGUgZXh0ZXJuYWwgZmlsZSBkYXRhIHNpemUuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgYnVmZmVyID0gZmlsZURhdGEuc2xpY2UoZGF0YU9mZnNldCwgZGF0YU9mZnNldCArIGRhdGFMZW5ndGgpLmJ1ZmZlcjtcbiAgICBsZXQgYnVmZmVyVmlldzogQXJyYXlCdWZmZXJWaWV3O1xuICAgIHN3aXRjaCAoZGVzYy5kYXRhVHlwZSkge1xuICAgICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICAgIGJ1ZmZlclZpZXcgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZmxvYXQxNic6XG4gICAgICAgIGJ1ZmZlclZpZXcgPVxuICAgICAgICAgIHR5cGVvZiBGbG9hdDE2QXJyYXkgIT09ICd1bmRlZmluZWQnICYmIEZsb2F0MTZBcnJheS5mcm9tID8gbmV3IEZsb2F0MTZBcnJheShidWZmZXIpIDogbmV3IFVpbnQxNkFycmF5KGJ1ZmZlcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW50MzInOlxuICAgICAgICBidWZmZXJWaWV3ID0gbmV3IEludDMyQXJyYXkoYnVmZmVyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgICBidWZmZXJWaWV3ID0gbmV3IFVpbnQzMkFycmF5KGJ1ZmZlcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW50NjQnOlxuICAgICAgICBpZiAoc2hvdWxkQ29udmVydEludDY0VG9JbnQzMikge1xuICAgICAgICAgIC8vIEludDY0IGlzIG5vdCBzdXBwb3J0ZWQgYnkgY3VycmVudCBjb250ZXh0LCB1c2UgaW50MzIgaW5zdGVhZC5cbiAgICAgICAgICBjb25zdCBpbnQzMkJ1ZmZlciA9IGNvbnZlcnREYXRhVG9JbnQzMihuZXcgVWludDhBcnJheShidWZmZXIpLCAnaW50NjQnKTtcbiAgICAgICAgICBidWZmZXJWaWV3ID0gbmV3IEludDMyQXJyYXkoaW50MzJCdWZmZXIuYnVmZmVyKTtcbiAgICAgICAgICBkZXNjLmRhdGFUeXBlID0gJ2ludDMyJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBidWZmZXJWaWV3ID0gbmV3IEJpZ0ludDY0QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3VpbnQ2NCc6XG4gICAgICAgIGJ1ZmZlclZpZXcgPSBuZXcgQmlnVWludDY0QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgICAgYnVmZmVyVmlldyA9IG5ldyBJbnQ4QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbnQ0JzpcbiAgICAgIGNhc2UgJ3VpbnQ0JzpcbiAgICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgICAgYnVmZmVyVmlldyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7ZGVzYy5kYXRhVHlwZX0gaW4gY3JlYXRpbmcgV2ViTk4gQ29uc3RhbnQgZnJvbSBleHRlcm5hbCBkYXRhLmApO1xuICAgIH1cblxuICAgIExPR19ERUJVRyhcbiAgICAgICd2ZXJib3NlJyxcbiAgICAgICgpID0+XG4gICAgICAgIGBbV2ViTk5dIHJlZ2lzdGVyTUxDb25zdGFudCB7ZGF0YVR5cGU6ICR7ZGVzYy5kYXRhVHlwZX0sIHNoYXBlOiAke2Rlc2Muc2hhcGV9fX0gJHtcbiAgICAgICAgICBzaG91bGRDb252ZXJ0SW50NjRUb0ludDMyID8gJyhOb3RlOiBpdCB3YXMgaW50NjQgZGF0YSB0eXBlIGFuZCByZWdpc3RlcmVkIHRvIGludDMyIGFzIHdvcmthcm91bmQpJyA6ICcnXG4gICAgICAgIH1gLFxuICAgICk7XG5cbiAgICByZXR1cm4gYnVpbGRlci5jb25zdGFudChkZXNjLCBidWZmZXJWaWV3KTtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3RlckdyYXBoSW5wdXQoaW5wdXROYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnRlbXBvcmFyeUdyYXBoSW5wdXRzLnB1c2goaW5wdXROYW1lKTtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3RlckdyYXBoT3V0cHV0KG91dHB1dE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMudGVtcG9yYXJ5R3JhcGhPdXRwdXRzLnB1c2gob3V0cHV0TmFtZSk7XG4gIH1cblxuICBwdWJsaWMgaXNHcmFwaElucHV0KHNlc3Npb25JZDogbnVtYmVyLCBpbnB1dE5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGlucHV0TmFtZXMgPSB0aGlzLnNlc3Npb25HcmFwaElucHV0cy5nZXQoc2Vzc2lvbklkKTtcbiAgICBpZiAoIWlucHV0TmFtZXMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGlucHV0TmFtZXMuaW5jbHVkZXMoaW5wdXROYW1lKTtcbiAgfVxuXG4gIHB1YmxpYyBpc0dyYXBoT3V0cHV0KHNlc3Npb25JZDogbnVtYmVyLCBvdXRwdXROYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBvdXRwdXROYW1lcyA9IHRoaXMuc2Vzc2lvbkdyYXBoT3V0cHV0cy5nZXQoc2Vzc2lvbklkKTtcbiAgICBpZiAoIW91dHB1dE5hbWVzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXROYW1lcy5pbmNsdWRlcyhvdXRwdXROYW1lKTtcbiAgfVxuXG4gIHB1YmxpYyBpc0dyYXBoSW5wdXRPdXRwdXRUeXBlU3VwcG9ydGVkKHNlc3Npb25JZDogbnVtYmVyLCB0eXBlOiBUZW5zb3IuVHlwZSwgaXNJbnB1dCA9IHRydWUpOiBib29sZWFuIHtcbiAgICBjb25zdCBkYXRhVHlwZSA9IG9ubnhEYXRhVHlwZVRvV2Vibm5EYXRhVHlwZS5nZXQodGVuc29yRGF0YVR5cGVTdHJpbmdUb0VudW0odHlwZSkpO1xuICAgIGNvbnN0IG9wTGltaXRzID0gdGhpcy5tbE9wU3VwcG9ydExpbWl0c0J5U2Vzc2lvbklkLmdldChzZXNzaW9uSWQpO1xuXG4gICAgaWYgKHR5cGVvZiBkYXRhVHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoaXNJbnB1dCkge1xuICAgICAgcmV0dXJuICEhb3BMaW1pdHM/LmlucHV0LmRhdGFUeXBlcy5pbmNsdWRlcyhkYXRhVHlwZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAhIW9wTGltaXRzPy5vdXRwdXQuZGF0YVR5cGVzLmluY2x1ZGVzKGRhdGFUeXBlKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZmx1c2goKTogdm9pZCB7XG4gICAgLy8gVW5saWtlIHRoZSBXZWJHUFUgYmFja2VuZCwgdGhlIFdlYk5OIGJhY2tlbmQgZG9lcyBub3QgbmVlZCB0byBmbHVzaCBhbnkgcGVuZGluZyBvcGVyYXRpb25zLlxuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uL3RlbnNvci12aWV3JztcblxuaW1wb3J0IHsgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9vcHMvY29tbW9uJztcblxuZXhwb3J0IHR5cGUgU2Vzc2lvblN0YXRlID0gJ2RlZmF1bHQnIHwgJ2NhcHR1cmluZycgfCAncmVwbGF5aW5nJztcblxuZXhwb3J0IGVudW0gR3B1RGF0YVR5cGUge1xuICBkZWZhdWx0ID0gMCxcbiAgdXBsb2FkID0gMSxcbiAgcHJvZmlsZSA9IDIsXG59XG5leHBvcnQgdHlwZSBHcHVEYXRhSWQgPSBudW1iZXI7XG5cbmV4cG9ydCB0eXBlIEdwdUFyY2hpdGVjdHVyZSA9ICdhbXBlcmUnIHwgJ2dlbi0xMmxwJztcbmV4cG9ydCB0eXBlIEdwdVZlbmRvciA9ICdhbWQnIHwgJ2ludGVsJyB8ICdudmlkaWEnO1xuZXhwb3J0IGludGVyZmFjZSBBZGFwdGVySW5mbyB7XG4gIGlzQXJjaGl0ZWN0dXJlOiAoYXJjaGl0ZWN0dXJlOiBHcHVBcmNoaXRlY3R1cmUpID0+IGJvb2xlYW47XG4gIGlzVmVuZG9yOiAodmVuZG9yOiBHcHVWZW5kb3IpID0+IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3B1RGF0YSB7XG4gIHR5cGU6IEdwdURhdGFUeXBlO1xuICBpZDogR3B1RGF0YUlkO1xuICBidWZmZXI6IEdQVUJ1ZmZlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JJbmZvIHtcbiAgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG4gIGRhdGFUeXBlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbVVuaWZvcm0ge1xuICB0eXBlOiBEYXRhVHlwZTtcbiAgZGF0YTogbnVtYmVyIHwgcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmV4cG9ydCB0eXBlIFByb2dyYW1Vbmlmb3JtVmFyaWFibGVJbmZvID0gW3R5cGU6IERhdGFUeXBlLCBsZW5ndGg6IG51bWJlcl07XG5cbi8qKlxuICogUmVwcmVzZW50IHRoZSBkZXBlbmRlbmN5IG9mIGEgcHJvZ3JhbSBvbiBhIHNwZWNpZmljIGlucHV0IHRlbnNvci5cbiAqXG4gKiAtICdub25lJzogdGhlIHNoYWRlci91bmlmb3JtIGRvZXMgbm90IGRlcGVuZCBvbiB0aGlzIGlucHV0J3MgaW5mb1xuICogLSAndHlwZSc6IHRoZSBzaGFkZXIvdW5pZm9ybSBkZXBlbmRzIG9uIGRhdGEgdHlwZSBvZiB0aGlzIGlucHV0XG4gKiAtICdyYW5rJzogdGhlIHNoYWRlci91bmlmb3JtIGRlcGVuZHMgb24gZGF0YSB0eXBlIGFuZCB0aGUgcmFuayBvZiB0aGlzIGlucHV0XG4gKiAtICdkaW1zJzogdGhlIHNoYWRlci91bmlmb3JtIGRlcGVuZHMgb24gZGF0YSB0eXBlIGFuZCB0aGUgZGltcyBvZiB0aGlzIGlucHV0XG4gKiAtICdkYXRhJzogdGhlIHNoYWRlci91bmlmb3JtIGRlcGVuZHMgb24gZGF0YSB0eXBlLCB0aGUgZGltcyBhbmQgdGhlIGRhdGEgb2YgdGhpcyBpbnB1dFxuICovXG5leHBvcnQgdHlwZSBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeSA9ICdub25lJyB8ICd0eXBlJyB8ICdyYW5rJyB8ICdkaW1zJyB8ICdkYXRhJztcblxuLyoqXG4gKiBSZXByZXNlbnQgaW5mb3JtYXRpb24gYWJvdXQgYSBwcm9ncmFtJ3MgY2FjaGUgZm9yIHNoYWRlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtU2hhZGVyQ2FjaGVJbmZvIHtcbiAgLyoqXG4gICAqIGFuIG9wdGlvbmFsIHN0cmluZyBhcyBhIGNhY2hlIGhpbnQgaW4gdGhlIGFydGlmYWN0IGNhY2hlLiBJZiB0aGlzIGlzIG5vdCBzcGVjaWZpZWQsIHRoZSBjYWNoZSBoaW50IHdpbGwgYmUgZW1wdHkuXG4gICAqXG4gICAqIFRoaXMgaGludCBzdHJpbmcgc2hvdWxkIG9ubHkgY29udGFpbnMgaW5pdGlhbGl6aW5nLXRpbWUgaW5mb3JtYXRpb24sIHN1Y2ggYXMgdGhlIGF0dHJpYnV0ZXMgb3IgYW55IGluZm9ybWF0aW9uIG9mXG4gICAqIGluaXRpYWxpemVycy4gSXQgc2hvdWxkIE5PVCBjb250YWluIGFueSBydW50aW1lIGluZm9ybWF0aW9uLCBzdWNoIGFzIHRoZSBzaGFwZSBvZiBpbnB1dHMuXG4gICAqL1xuICBoaW50Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBhbiBvcHRpb25hbCBsaXN0IG9mIGRlcGVuZGVuY2llcyBvZiB0aGUgcHJvZ3JhbSBvbiB0aGUgaW5wdXQgdGVuc29ycy4gSWYgdGhpcyBpcyBub3Qgc3BlY2lmaWVkLCB0aGUgcHJvZ3JhbSBkZXBlbmRzXG4gICAqIG9uICdkaW1zJyBvZiBhbGwgaW5wdXRzLlxuICAgKi9cbiAgaW5wdXREZXBlbmRlbmNpZXM/OiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudCBpbmZvcm1hdGlvbiBhYm91dCBhIHByb2dyYW0ncyBjYWNoZSBmb3IgdW5pZm9ybS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtVW5pZm9ybUNhY2hlSW5mbyB7XG4gIC8qKlxuICAgKiBhbiBvcHRpb25hbCBzdHJpbmcgYXMgYSBjYWNoZSBoaW50IGluIHRoZSB1bmlmb3JtIGNhY2hlLiBJZiB0aGlzIGlzIG5vdCBzcGVjaWZpZWQsIHRoZSBjYWNoZSBoaW50IHdpbGwgYmUgZW1wdHkuXG4gICAqXG4gICAqIFRoaXMgaGludCBzdHJpbmcgc2hvdWxkIG9ubHkgY29udGFpbnMgcnVudGltZSBpbmZvcm1hdGlvbiwgc3VjaCBhcyB0aGUgc2hhcGUgb2YgaW5wdXRzLlxuICAgKi9cbiAgaGludD86IHN0cmluZztcblxuICAvKipcbiAgICogYW4gb3B0aW9uYWwgbGlzdCBvZiBkZXBlbmRlbmNpZXMgb2YgdGhlIHByb2dyYW0gb24gdGhlIGlucHV0IHRlbnNvcnMuIElmIHRoaXMgaXMgbm90IHNwZWNpZmllZCwgdGhlIHByb2dyYW0gZGVwZW5kc1xuICAgKiBvbiAnbm9uZScgb2YgYWxsIGlucHV0cy5cbiAgICovXG4gIGlucHV0RGVwZW5kZW5jaWVzPzogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXTtcbn1cblxuLyoqXG4gKiBBIHNldCBvZiBkYXRhIHRoYXQgcmVwcmVzZW50IGEgc2hhZGVyIHByb2dyYW1cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtSW5mbyB7XG4gIC8qKlxuICAgKiB0aGUgbmFtZSBvZiB0aGUgcHJvZ3JhbS4gdXNlZCBmb3IgZGVidWdnaW5nIGFuZCBwcm9maWxpbmdcbiAgICovXG4gIG5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogYW4gb3B0aW9uYWwgb2JqZWN0IGRlc2NyaWJpbmcgdGhlIGNhY2hlIGluZm9ybWF0aW9uIG9mIHRoZSBwcm9ncmFtIHNoYWRlci5cbiAgICpcbiAgICogSWYgdGhpcyBpcyBub3Qgc3BlY2lmaWVkLCBhc3N1bWUgaGludCBpcyBlbXB0eSBhbmQgaW5wdXREZXBlbmRlbmNpZXMgYXJlIFsnZGltcyddIGZvciBhbGwgaW5wdXRzLlxuICAgKi9cbiAgc2hhZGVyQ2FjaGU/OiBQcm9ncmFtU2hhZGVyQ2FjaGVJbmZvO1xuXG4gIC8qKlxuICAgKiB0aGUgc2hhZGVyJ3MgcHJvY2Vzc2luZyBzb3VyY2UgY29kZS5cbiAgICpcbiAgICogVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCB3aGVuIHNoYWRlciBjYWNoZSBtaXNzZWQuXG4gICAqL1xuICBnZXRTaGFkZXJTb3VyY2U6IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIGZ1bmN0aW9uIHRvIGdldCBydW4gZGF0YSByZXF1aXJlZCB0byBydW4gdGhlIHByb2dyYW0uXG4gICAqXG4gICAqIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgZXZlcnkgdGltZSB0aGUgcHJvZ3JhbSBpcyBleGVjdXRlZC4gU2hvdWxkIGtlZXAgdGhpcyBmdW5jdGlvbiBhcyBzaW1wbGUgYXMgcG9zc2libGUuXG4gICAqL1xuICBnZXRSdW5EYXRhOiAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pID0+IHtcbiAgICBvdXRwdXRzOiByZWFkb25seSBUZW5zb3JJbmZvW107XG4gICAgZGlzcGF0Y2hHcm91cDogeyB4OiBudW1iZXI7IHk/OiBudW1iZXI7IHo/OiBudW1iZXIgfTtcbiAgICBwcm9ncmFtVW5pZm9ybXM/OiByZWFkb25seSBQcm9ncmFtVW5pZm9ybVtdO1xuICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFydGlmYWN0IHtcbiAgcHJvZ3JhbUluZm86IFByb2dyYW1JbmZvO1xuICBjb21wdXRlUGlwZWxpbmU6IEdQVUNvbXB1dGVQaXBlbGluZTtcbiAgdW5pZm9ybVZhcmlhYmxlc0luZm86IHJlYWRvbmx5IFByb2dyYW1Vbmlmb3JtVmFyaWFibGVJbmZvW10gfCB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcHV0ZUNvbnRleHRJbnB1dHNPdXRwdXRzTWFwcGluZyB7XG4gIC8qKlxuICAgKiBzcGVjaWZ5IHRoZSBtYXBwaW5nIHRvIHRoZSBwcm9ncmFtJ3MgaW5wdXRzLiB0aGUgdmFsdWUgY2FuIGJlIGEgbnVtYmVyIG9yIGEgdGVuc29yIHZpZXcuXG4gICAqIC0gaWYgaXQncyBhIG51bWJlciwgaXQncyB0aGUgaW5kZXggb2YgdGhlIGtlcm5lbCdzIGlucHV0XG4gICAqIC0gaWYgaXQncyBhIHRlbnNvciB2aWV3LCBpdCdzIGFuIGV4aXN0aW5nIHRlbnNvciB2aWV3IHRoYXQgd2lsbCBiZSB1c2VkIGFzIHRoZSBpbnB1dFxuICAgKlxuICAgKiBpZiBpbnB1dHMgaXMgbm90IHNwZWNpZmllZCwgdGhlIG1hcHBpbmcgd2lsbCBiZSB0aGUga2VybmVsJ3MgaW5wdXRzIGluIG9yZGVyLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5wdXRzPzogUmVhZG9ubHlBcnJheTxUZW5zb3JWaWV3IHwgbnVtYmVyPjtcbiAgLyoqXG4gICAqIHNwZWNpZnkgdGhlIG1hcHBpbmcgdG8gdGhlIHByb2dyYW0ncyBvdXRwdXRzLiB0aGUgdmFsdWUgbXVzdCBiZSBhIG51bWJlci5cbiAgICogLSBpZiBpdCdzIGEgbm9uLW5lZ2F0aXZlIG51bWJlciwgaXQncyB0aGUgaW5kZXggb2YgdGhlIGtlcm5lbCdzIG91dHB1dFxuICAgKiAtIGlmIGl0J3MgLTEsIGl0J3MgYW4gb3V0cHV0IHRoYXQgd2lsbCBiZSBjcmVhdGVkIGFzIGEgdGVtcG9yYXJ5IHZhbHVlLiB0aGlzIHZhbHVlIHdpbGwgYmUgcmVsZWFzZWQgYWZ0ZXJcbiAgICogdGhlIGtlcm5lbCBpcyBleGVjdXRlZC5cbiAgICogLSBpZiBpdCdzIC0yLCBpdCdzIGFuIG91dHB1dCB0aGF0IHdpbGwgYmUgY3JlYXRlZCBhcyBhIHBlcnNpc3RlbnQgdmFsdWUuIHRoaXMgdmFsdWUgd2lsbCBiZSByZWxlYXNlZCB3aGVuIHRoZVxuICAgKiBrZXJuZWwgaXMgcmVsZWFzZWQuXG4gICAqXG4gICAqIGlmIG91dHB1dHMgaXMgbm90IHNwZWNpZmllZCwgdGhlIG1hcHBpbmcgd2lsbCBiZSB0aGUga2VybmVsJ3Mgb3V0cHV0cyBpbiBvcmRlci5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dHM/OiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuLyoqXG4gKiBBIENvbXB1dGVDb250ZXh0IGluc3RhbmNlIGNhcnJpZXMgdGhlIHN0YXRlcyB0aGF0IHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBydW5uaW5nIG9mIGEga2VybmVsLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXB1dGVDb250ZXh0IHtcbiAgLyoqXG4gICAqIGdwdSBhZGFwdGVyIGluZm9cbiAgICovXG4gIHJlYWRvbmx5IGFkYXB0ZXJJbmZvOiBBZGFwdGVySW5mbztcblxuICAvKipcbiAgICogc3RvcmVzIHRoZSBwb2ludGVyIHRvIE9wS2VybmVsQ29udGV4dFxuICAgKi9cbiAgcmVhZG9ubHkgb3BLZXJuZWxDb250ZXh0OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIGEgbGlzdCBvZiBpbnB1dHMsIGVhY2ggaW5wdXQgaXMgYW4gaW5zdGFuY2Ugb2YgVGVuc29yVmlld1xuICAgKi9cbiAgcmVhZG9ubHkgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W107XG5cbiAgLyoqXG4gICAqIGEgY3VzdG9tIGRhdGEgb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gc3RvcmUgYW55IGRhdGEgdGhhdCBpcyBuZWVkZWQgYnkgdGhlIGtlcm5lbFxuICAgKi9cbiAgcmVhZG9ubHkga2VybmVsQ3VzdG9tRGF0YTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH07XG5cbiAgLyoqXG4gICAqIGEgYnVmZmVyIHRoYXQgY2FuIGJlIHVzZWQgdG8gYWNjZXNzIGN1c3RvbSBkYXRhIGNyZWF0ZWQgZWFjaCB0aW1lIHRoZSBrZXJuZWwgaXMgZXhlY3V0ZWRcbiAgICovXG4gIHJlYWRvbmx5IGN1c3RvbURhdGFCdWZmZXI6IFVpbnQ4QXJyYXk7XG5cbiAgLyoqXG4gICAqIGEgbnVtYmVyIG9mIG91dHB1dHMgZm9yIHRoZSBub2RlXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRDb3VudDogbnVtYmVyO1xuXG4gIGNvbXB1dGUocHJvZ3JhbTogUHJvZ3JhbUluZm8sIGlucHV0c091dHB1dHNNYXBwaW5nPzogQ29tcHV0ZUNvbnRleHRJbnB1dHNPdXRwdXRzTWFwcGluZyk6IFRlbnNvclZpZXdbXTtcbiAgb3V0cHV0KGluZGV4OiBudW1iZXIsIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyO1xufVxuXG5leHBvcnQgdHlwZSBUaW1lc3RhbXBRdWVyeSA9ICdub25lJyB8ICdpbnNpZGUtcGFzc2VzJyB8ICdhdC1wYXNzZXMnO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBXZWJHcHVCYWNrZW5kIH0gZnJvbSAnLi4vYmFja2VuZC13ZWJncHUnO1xuaW1wb3J0IHsgTE9HX0RFQlVHIH0gZnJvbSAnLi4vbG9nJztcblxuaW1wb3J0IHsgR3B1RGF0YSwgR3B1RGF0YUlkLCBHcHVEYXRhVHlwZSB9IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIG1hbmFnZXMgR3B1RGF0YUlkIC0+IEdwdUJ1ZmZlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdwdURhdGFNYW5hZ2VyIHtcbiAgLyoqXG4gICAqIGNvcHkgZGF0YSBmcm9tIENQVSB0byBHUFUuXG4gICAqL1xuICB1cGxvYWQoaWQ6IEdwdURhdGFJZCwgZGF0YTogVWludDhBcnJheSk6IHZvaWQ7XG4gIC8qKlxuICAgKiBjb3B5IGRhdGEgZnJvbSBHUFUgdG8gR1BVLlxuICAgKi9cbiAgbWVtY3B5KHNvdXJjZUlkOiBHcHVEYXRhSWQsIGRlc3RpbmF0aW9uSWQ6IEdwdURhdGFJZCk6IHZvaWQ7XG4gIC8qKlxuICAgKiBjcmVhdGUgbmV3IGRhdGEgb24gR1BVLlxuICAgKi9cbiAgY3JlYXRlKHNpemU6IG51bWJlciwgdXNhZ2U/OiBudW1iZXIpOiBHcHVEYXRhO1xuICAvKipcbiAgICogZ2V0IEdQVSBkYXRhIGJ5IElELlxuICAgKi9cbiAgZ2V0KGlkOiBHcHVEYXRhSWQpOiBHcHVEYXRhIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogcmVsZWFzZSB0aGUgZGF0YSBvbiBHUFUgYnkgSUQuXG4gICAqXG4gICAqIEByZXR1cm4gc2l6ZSBvZiB0aGUgZGF0YSByZWxlYXNlZFxuICAgKi9cbiAgcmVsZWFzZShpZDogR3B1RGF0YUlkKTogbnVtYmVyO1xuICAvKipcbiAgICogY29weSBkYXRhIGZyb20gR1BVIHRvIENQVS5cbiAgICovXG4gIGRvd25sb2FkKGlkOiBHcHVEYXRhSWQsIGdldFRhcmdldEJ1ZmZlcjogKCkgPT4gVWludDhBcnJheSk6IFByb21pc2U8dm9pZD47XG5cbiAgLyoqXG4gICAqIHJlZnJlc2ggdGhlIGJ1ZmZlcnMgdGhhdCBtYXJrZWQgZm9yIHJlbGVhc2UuXG4gICAqXG4gICAqIHdoZW4gcmVsZWFzZSgpIGlzIGNhbGxlZCwgdGhlIGJ1ZmZlciBpcyBub3QgcmVsZWFzZWQgaW1tZWRpYXRlbHkuIHRoaXMgaXMgYmVjYXVzZSB3ZSBuZWVkIHRvIHdhaXQgZm9yIHRoZSBjb21tYW5kc1xuICAgKiB0byBiZSBzdWJtaXR0ZWQgdG8gdGhlIEdQVS4gdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYWZ0ZXIgdGhlIGNvbW1hbmRzIGFyZSBzdWJtaXR0ZWQgc28gdGhhdCB0aGUgYnVmZmVycyBjYW4gYmVcbiAgICogYWN0dWFsbHkgcmVsZWFzZWQuXG4gICAqL1xuICByZWZyZXNoUGVuZGluZ0J1ZmZlcnMoKTogdm9pZDtcblxuICAvKipcbiAgICogcmVnaXN0ZXIgYW4gZXh0ZXJuYWwgYnVmZmVyIGZvciBJTyBCaW5kaW5nLiBJZiB0aGUgYnVmZmVyIGlzIGFscmVhZHkgcmVnaXN0ZXJlZCwgcmV0dXJuIHRoZSBleGlzdGluZyBHUFUgZGF0YSBJRC5cbiAgICpcbiAgICogR1BVIGRhdGEgbWFuYWdlciBvbmx5IG1hbmFnZXMgYSBtYXBwaW5nIGJldHdlZW4gdGhlIGJ1ZmZlciBhbmQgdGhlIEdQVSBkYXRhIElELiBJdCB3aWxsIG5vdCBtYW5hZ2UgdGhlIGxpZmVjeWNsZSBvZlxuICAgKiB0aGUgZXh0ZXJuYWwgYnVmZmVyLlxuICAgKi9cbiAgcmVnaXN0ZXJFeHRlcm5hbEJ1ZmZlcihidWZmZXI6IEdQVUJ1ZmZlciwgb3JpZ2luYWxTaXplOiBudW1iZXIsIHByZXZpb3VzPzogW0dwdURhdGFJZCwgR1BVQnVmZmVyXSk6IG51bWJlcjtcblxuICAvKipcbiAgICogdW5yZWdpc3RlciBhbiBleHRlcm5hbCBidWZmZXIgZm9yIElPIEJpbmRpbmcuXG4gICAqL1xuICB1bnJlZ2lzdGVyRXh0ZXJuYWxCdWZmZXIoaWQ6IEdwdURhdGFJZCk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIGRlc3Ryb3kgYWxsIGdwdSBidWZmZXJzLlxuICAgKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgc2Vzc2lvbiByZWxhdGVkIGRhdGEuXG4gICAqL1xuICBvbkNyZWF0ZVNlc3Npb24oKTogdm9pZDtcblxuICAvKipcbiAgICogcmVsZWFzZSBzZXNzaW9uIHJlbGF0ZWQgZGF0YS5cbiAgICogQHBhcmFtIHNlc3Npb25JZCAtIHNwZWNpZnkgdGhlIHNlc3Npb24gSUQuXG4gICAqL1xuICBvblJlbGVhc2VTZXNzaW9uKHNlc3Npb25JZDogbnVtYmVyKTogdm9pZDtcbn1cblxuaW50ZXJmYWNlIFN0b3JhZ2VDYWNoZVZhbHVlIHtcbiAgZ3B1RGF0YTogR3B1RGF0YTtcbiAgb3JpZ2luYWxTaXplOiBudW1iZXI7XG59XG5cbmNvbnN0IGJ1Y2tldEZyZWVsaXN0OiBNYXA8bnVtYmVyLCBudW1iZXI+ID0gbmV3IE1hcChbXG4gIFs2NCwgMjUwXSxcbiAgWzEyOCwgMjAwXSxcbiAgWzI1NiwgMjAwXSxcbiAgWzUxMiwgMjAwXSxcbiAgWzIwNDgsIDIzMF0sXG4gIFs0MDk2LCAyMDBdLFxuICBbODE5MiwgNTBdLFxuICBbMTYzODQsIDUwXSxcbiAgWzMyNzY4LCA1MF0sXG4gIFs2NTUzNiwgNTBdLFxuICBbMTMxMDcyLCA1MF0sXG4gIFsyNjIxNDQsIDUwXSxcbiAgWzUyNDI4OCwgNTBdLFxuICBbMTA0ODU3NiwgNTBdLFxuICBbMjA5NzE1MiwgMzBdLFxuICBbNDE5NDMwNCwgMjBdLFxuICBbODM4ODYwOCwgMTBdLFxuICBbMTI1ODI5MTIsIDEwXSxcbiAgWzE2Nzc3MjE2LCAxMF0sXG4gIFsyNjIxNDQwMCwgMTVdLFxuICBbMzM1NTQ0MzIsIDIyXSxcbiAgWzQ0MjM2ODAwLCAyXSxcbiAgWzU4OTgyNDAwLCA2XSxcbiAgLy8gd2UgZG9uJ3Qgd2FudCB0byBjYWNoZSB0aGUgYnVja2V0IHNpemVzIGJlbG93IGJ1dCBub3QgY2FjaGluZyB0aGVtXG4gIC8vIHJlc3VsdHMgaW4gc29tZSBtYWpvciBwZXJmb3JtYW5jZSBoaXRzIGZvciBtb2RlbHMgbGlrZSBzZC10dXJiby5cbiAgWzY3MTA4ODY0LCA2XSxcbiAgWzEzNDIxNzcyOCwgNl0sXG4gIFsxNjc3NzIxNjAsIDZdLFxuXSk7XG5cbmNvbnN0IGJ1Y2tldEFycjogbnVtYmVyW10gPSBbXTtcblxuLyoqXG4gKiBub3JtYWxpemUgdGhlIGJ1ZmZlciBzaXplIHNvIHRoYXQgaXQgZml0cyB0aGUgMTI4LWJpdHMgKDE2IGJ5dGVzKSBhbGlnbm1lbnQuXG4gKi9cbmNvbnN0IGNhbGNOb3JtYWxpemVkQnVmZmVyU2l6ZSA9IChzaXplOiBudW1iZXIpID0+IE1hdGguY2VpbChOdW1iZXIoc2l6ZSkgLyAxNikgKiAxNjtcblxuLyoqXG4gKiBjYWxjdWxhdGUgdGhlIGJ1ZmZlciBzaXplIHNvIHRoYXQgaXQgZml0cyBpbnRvIGJ1Y2tldHMuXG4gKi9cbmNvbnN0IGNhbGNCdWNrZXRCdWZmZXJTaXplID0gKHNpemU6IG51bWJlcikgPT4ge1xuICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCBidWNrZXRBcnIubGVuZ3RoOyBpZHgrKykge1xuICAgIGNvbnN0IHNpemVGb3JCdWNrZXQgPSBidWNrZXRBcnJbaWR4XTtcbiAgICBpZiAoc2l6ZSA8PSBzaXplRm9yQnVja2V0KSB7XG4gICAgICByZXR1cm4gc2l6ZUZvckJ1Y2tldDtcbiAgICB9XG4gIH1cbiAgLy8gbm90IGluIGJ1Y2tldCBsaXN0IC0+IGNhbGxlciB3aWxsIG5vdCBjYWNoZSwgcm91bmQgdXAgdG8gMTYuXG4gIHJldHVybiBNYXRoLmNlaWwoc2l6ZSAvIDE2KSAqIDE2O1xufTtcblxubGV0IGd1aWQgPSAxO1xuY29uc3QgY3JlYXRlTmV3R3B1RGF0YUlkID0gKCkgPT4gZ3VpZCsrO1xuXG4vKipcbiAqIGV4cG9ydGVkIHN0YW5kYXJkIGRvd25sb2FkIGZ1bmN0aW9uLiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgYnkgdGhlIHNlc3Npb24gdG8gZG93bmxvYWQgdGhlIGRhdGEgZnJvbSBHUFUsIGFuZCBhbHNvIGJ5XG4gKiBmYWN0b3J5IHRvIGNyZWF0ZSBHUFUgdGVuc29ycyB3aXRoIHRoZSBjYXBhY2l0eSBvZiBkb3dubG9hZGluZyBkYXRhIGZyb20gR1BVLlxuICpcbiAqIEBwYXJhbSBiYWNrZW5kIC0gdGhlIFdlYkdQVSBiYWNrZW5kXG4gKiBAcGFyYW0gZ3B1QnVmZmVyIC0gdGhlIEdQVSBidWZmZXIgdG8gZG93bmxvYWRcbiAqIEBwYXJhbSBvcmlnaW5hbFNpemUgLSB0aGUgb3JpZ2luYWwgc2l6ZSBvZiB0aGUgZGF0YVxuICogQHBhcmFtIGdldFRhcmdldEJ1ZmZlciAtIG9wdGlvbmFsLiBJZiBwcm92aWRlZCwgdGhlIGRhdGEgd2lsbCBiZSBjb3BpZWQgdG8gdGhlIHRhcmdldCBidWZmZXIuIE90aGVyd2lzZSwgYSBuZXcgYnVmZmVyXG4gKiB3aWxsIGJlIGNyZWF0ZWQgYW5kIHJldHVybmVkLlxuICovXG5leHBvcnQgY29uc3QgZG93bmxvYWRHcHVEYXRhID0gYXN5bmMgKFxuICBiYWNrZW5kOiBXZWJHcHVCYWNrZW5kLFxuICBncHVCdWZmZXI6IEdQVUJ1ZmZlcixcbiAgb3JpZ2luYWxTaXplOiBudW1iZXIsXG4gIGdldFRhcmdldEJ1ZmZlcj86ICgpID0+IFVpbnQ4QXJyYXksXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXk+ID0+IHtcbiAgY29uc3QgYnVmZmVyU2l6ZSA9IGNhbGNOb3JtYWxpemVkQnVmZmVyU2l6ZShvcmlnaW5hbFNpemUpO1xuICBjb25zdCBncHVSZWFkQnVmZmVyID0gYmFja2VuZC5kZXZpY2UuY3JlYXRlQnVmZmVyKFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgeyBzaXplOiBidWZmZXJTaXplLCB1c2FnZTogR1BVQnVmZmVyVXNhZ2UuQ09QWV9EU1QgfCBHUFVCdWZmZXJVc2FnZS5NQVBfUkVBRCB9LFxuICApO1xuICB0cnkge1xuICAgIGNvbnN0IGNvbW1hbmRFbmNvZGVyID0gYmFja2VuZC5nZXRDb21tYW5kRW5jb2RlcigpO1xuICAgIGJhY2tlbmQuZW5kQ29tcHV0ZVBhc3MoKTtcbiAgICBjb21tYW5kRW5jb2Rlci5jb3B5QnVmZmVyVG9CdWZmZXIoXG4gICAgICBncHVCdWZmZXIgLyogc291cmNlIGJ1ZmZlciAqLyxcbiAgICAgIDAgLyogc291cmNlIG9mZnNldCAqLyxcbiAgICAgIGdwdVJlYWRCdWZmZXIgLyogZGVzdGluYXRpb24gYnVmZmVyICovLFxuICAgICAgMCAvKiBkZXN0aW5hdGlvbiBvZmZzZXQgKi8sXG4gICAgICBidWZmZXJTaXplIC8qIHNpemUgKi8sXG4gICAgKTtcbiAgICBiYWNrZW5kLmZsdXNoKCk7XG5cbiAgICBhd2FpdCBncHVSZWFkQnVmZmVyLm1hcEFzeW5jKEdQVU1hcE1vZGUuUkVBRCk7XG5cbiAgICBjb25zdCBhcnJheUJ1ZmZlciA9IGdwdVJlYWRCdWZmZXIuZ2V0TWFwcGVkUmFuZ2UoKTtcbiAgICBpZiAoZ2V0VGFyZ2V0QnVmZmVyKSB7XG4gICAgICAvLyBpZiB3ZSBhbHJlYWR5IGhhdmUgYSBDUFUgYnVmZmVyIHRvIGFjY2VwdCB0aGUgZGF0YSwgbm8gbmVlZCB0byBjbG9uZSB0aGUgQXJyYXlCdWZmZXIuXG4gICAgICBjb25zdCB0YXJnZXRCdWZmZXIgPSBnZXRUYXJnZXRCdWZmZXIoKTtcbiAgICAgIHRhcmdldEJ1ZmZlci5zZXQobmV3IFVpbnQ4QXJyYXkoYXJyYXlCdWZmZXIsIDAsIG9yaWdpbmFsU2l6ZSkpO1xuICAgICAgcmV0dXJuIHRhcmdldEJ1ZmZlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gdGhlIG1hcHBlZCBBcnJheUJ1ZmZlciB3aWxsIGJlIHJlbGVhc2VkIHdoZW4gdGhlIEdQVSBidWZmZXIgaXMgZGVzdHJveWVkLiBOZWVkIHRvIGNsb25lIHRoZVxuICAgICAgLy8gQXJyYXlCdWZmZXIuXG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYXJyYXlCdWZmZXIuc2xpY2UoMCwgb3JpZ2luYWxTaXplKSk7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGdwdVJlYWRCdWZmZXIuZGVzdHJveSgpO1xuICB9XG59O1xuXG5jbGFzcyBHcHVEYXRhTWFuYWdlckltcGwgaW1wbGVtZW50cyBHcHVEYXRhTWFuYWdlciB7XG4gIC8vIEdQVSBEYXRhIElEID0+IEdQVSBEYXRhICggc3RvcmFnZSBidWZmZXIgKVxuICBwcml2YXRlIHN0b3JhZ2VDYWNoZTogTWFwPEdwdURhdGFJZCwgU3RvcmFnZUNhY2hlVmFsdWU+O1xuXG4gIC8vIHBlbmRpbmcgYnVmZmVycyBmb3IgY29tcHV0aW5nXG4gIHByaXZhdGUgYnVmZmVyc1BlbmRpbmc6IEdQVUJ1ZmZlcltdO1xuXG4gIC8vIFRoZSByZXVzYWJsZSBzdG9yYWdlIGJ1ZmZlcnMgZm9yIGNvbXB1dGluZy5cbiAgcHJpdmF0ZSBmcmVlQnVmZmVyczogTWFwPG51bWJlciwgR1BVQnVmZmVyW10+O1xuICAvLyBUaGUgcmV1c2FibGUgdW5pZm9ybSBidWZmZXJzXG4gIHByaXZhdGUgZnJlZVVuaWZvcm1CdWZmZXJzOiBNYXA8bnVtYmVyLCBHUFVCdWZmZXJbXT47XG5cbiAgLy8gVGhlIHBlbmRpbmdCdWZmZXJzIGZvciBjYXB0dXJlIGdyYXBoLlxuICAvLyBhIFNlc3Npb25JRCAtPiBHUFVCdWZmZXJbXSBtYXBwaW5nLlxuICBwcml2YXRlIGNhcHR1cmVkUGVuZGluZ0J1ZmZlcnM6IE1hcDxudW1iZXIsIEdQVUJ1ZmZlcltdPjtcblxuICAvLyBUaGUgc2Vzc2lvbiBjb3VudC5cbiAgcHJpdmF0ZSBzZXNzaW9uQ291bnQ6IG51bWJlcjtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGJhY2tlbmQ6IFdlYkdwdUJhY2tlbmQpIHtcbiAgICB0aGlzLnN0b3JhZ2VDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmZyZWVCdWZmZXJzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuZnJlZVVuaWZvcm1CdWZmZXJzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuYnVmZmVyc1BlbmRpbmcgPSBbXTtcbiAgICB0aGlzLmNhcHR1cmVkUGVuZGluZ0J1ZmZlcnMgPSBuZXcgTWFwKCk7XG5cbiAgICBmb3IgKGNvbnN0IFtrZXldIG9mIGJ1Y2tldEZyZWVsaXN0KSB7XG4gICAgICBidWNrZXRBcnIucHVzaChrZXkpO1xuICAgICAgdGhpcy5mcmVlQnVmZmVycy5zZXQoa2V5LCBbXSk7XG4gICAgICB0aGlzLmZyZWVVbmlmb3JtQnVmZmVycy5zZXQoa2V5LCBbXSk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXNzaW9uQ291bnQgPSAwO1xuICB9XG5cbiAgdXBsb2FkKGlkOiBHcHVEYXRhSWQsIGRhdGE6IFVpbnQ4QXJyYXkpOiB2b2lkIHtcbiAgICBjb25zdCBzcmNBcnJheUJ1ZmZlciA9IGRhdGEuYnVmZmVyO1xuICAgIGNvbnN0IHNyY09mZnNldCA9IGRhdGEuYnl0ZU9mZnNldDtcbiAgICBjb25zdCBzcmNMZW5ndGggPSBkYXRhLmJ5dGVMZW5ndGg7XG4gICAgY29uc3Qgc2l6ZSA9IGNhbGNOb3JtYWxpemVkQnVmZmVyU2l6ZShzcmNMZW5ndGgpO1xuXG4gICAgLy8gZ2V0IGRlc3RpbmF0aW9uIGdwdSBidWZmZXJcbiAgICBjb25zdCBncHVEYXRhQ2FjaGUgPSB0aGlzLnN0b3JhZ2VDYWNoZS5nZXQoaWQpO1xuICAgIGlmICghZ3B1RGF0YUNhY2hlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dwdSBkYXRhIGZvciB1cGxvYWRpbmcgZG9lcyBub3QgZXhpc3QnKTtcbiAgICB9XG4gICAgaWYgKE51bWJlcihncHVEYXRhQ2FjaGUub3JpZ2luYWxTaXplKSAhPT0gc3JjTGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGluY29uc2lzdGVudCBkYXRhIHNpemUuIGdwdSBkYXRhIHNpemU9JHtncHVEYXRhQ2FjaGUub3JpZ2luYWxTaXplfSwgZGF0YSBzaXplPSR7c3JjTGVuZ3RofWApO1xuICAgIH1cblxuICAgIC8vIGNyZWF0ZSBncHUgYnVmZmVyXG4gICAgY29uc3QgZ3B1QnVmZmVyRm9yVXBsb2FkaW5nID0gdGhpcy5iYWNrZW5kLmRldmljZS5jcmVhdGVCdWZmZXIoXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYml0d2lzZVxuICAgICAgeyBtYXBwZWRBdENyZWF0aW9uOiB0cnVlLCBzaXplLCB1c2FnZTogR1BVQnVmZmVyVXNhZ2UuTUFQX1dSSVRFIHwgR1BVQnVmZmVyVXNhZ2UuQ09QWV9TUkMgfSxcbiAgICApO1xuXG4gICAgLy8gY29weSAodXBsb2FkKSBkYXRhXG4gICAgY29uc3QgYXJyYXlCdWZmZXIgPSBncHVCdWZmZXJGb3JVcGxvYWRpbmcuZ2V0TWFwcGVkUmFuZ2UoKTtcbiAgICBuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlcikuc2V0KG5ldyBVaW50OEFycmF5KHNyY0FycmF5QnVmZmVyLCBzcmNPZmZzZXQsIHNyY0xlbmd0aCkpO1xuICAgIGdwdUJ1ZmZlckZvclVwbG9hZGluZy51bm1hcCgpO1xuXG4gICAgLy8gR1BVIGNvcHlcbiAgICBjb25zdCBjb21tYW5kRW5jb2RlciA9IHRoaXMuYmFja2VuZC5kZXZpY2UuY3JlYXRlQ29tbWFuZEVuY29kZXIoKTtcbiAgICBjb21tYW5kRW5jb2Rlci5jb3B5QnVmZmVyVG9CdWZmZXIoZ3B1QnVmZmVyRm9yVXBsb2FkaW5nLCAwLCBncHVEYXRhQ2FjaGUuZ3B1RGF0YS5idWZmZXIsIDAsIHNpemUpO1xuICAgIHRoaXMuYmFja2VuZC5kZXZpY2UucXVldWUuc3VibWl0KFtjb21tYW5kRW5jb2Rlci5maW5pc2goKV0pO1xuICAgIGdwdUJ1ZmZlckZvclVwbG9hZGluZy5kZXN0cm95KCk7XG5cbiAgICBMT0dfREVCVUcoJ3ZlcmJvc2UnLCAoKSA9PiBgW1dlYkdQVV0gR3B1RGF0YU1hbmFnZXIudXBsb2FkKGlkPSR7aWR9KWApO1xuICB9XG5cbiAgbWVtY3B5KHNvdXJjZUlkOiBHcHVEYXRhSWQsIGRlc3RpbmF0aW9uSWQ6IEdwdURhdGFJZCk6IHZvaWQge1xuICAgIC8vIGdldCBzb3VyY2UgZ3B1IGJ1ZmZlclxuICAgIGNvbnN0IHNvdXJjZUdwdURhdGFDYWNoZSA9IHRoaXMuc3RvcmFnZUNhY2hlLmdldChzb3VyY2VJZCk7XG4gICAgaWYgKCFzb3VyY2VHcHVEYXRhQ2FjaGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGdwdSBkYXRhIGZvciBtZW1jcHkgZG9lcyBub3QgZXhpc3QnKTtcbiAgICB9XG4gICAgLy8gZ2V0IGRlc3RpbmF0aW9uIGdwdSBidWZmZXJcbiAgICBjb25zdCBkZXN0aW5hdGlvbkdwdURhdGFDYWNoZSA9IHRoaXMuc3RvcmFnZUNhY2hlLmdldChkZXN0aW5hdGlvbklkKTtcbiAgICBpZiAoIWRlc3RpbmF0aW9uR3B1RGF0YUNhY2hlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Rlc3RpbmF0aW9uIGdwdSBkYXRhIGZvciBtZW1jcHkgZG9lcyBub3QgZXhpc3QnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUdwdURhdGFDYWNoZS5vcmlnaW5hbFNpemUgIT09IGRlc3RpbmF0aW9uR3B1RGF0YUNhY2hlLm9yaWdpbmFsU2l6ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbmNvbnNpc3RlbnQgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBncHUgZGF0YSBzaXplJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2l6ZSA9IGNhbGNOb3JtYWxpemVkQnVmZmVyU2l6ZShzb3VyY2VHcHVEYXRhQ2FjaGUub3JpZ2luYWxTaXplKTtcblxuICAgIC8vIEdQVSBjb3B5XG4gICAgY29uc3QgY29tbWFuZEVuY29kZXIgPSB0aGlzLmJhY2tlbmQuZ2V0Q29tbWFuZEVuY29kZXIoKTtcbiAgICB0aGlzLmJhY2tlbmQuZW5kQ29tcHV0ZVBhc3MoKTtcbiAgICBjb21tYW5kRW5jb2Rlci5jb3B5QnVmZmVyVG9CdWZmZXIoXG4gICAgICBzb3VyY2VHcHVEYXRhQ2FjaGUuZ3B1RGF0YS5idWZmZXIsXG4gICAgICAwLFxuICAgICAgZGVzdGluYXRpb25HcHVEYXRhQ2FjaGUuZ3B1RGF0YS5idWZmZXIsXG4gICAgICAwLFxuICAgICAgc2l6ZSxcbiAgICApO1xuICB9XG5cbiAgcmVnaXN0ZXJFeHRlcm5hbEJ1ZmZlcihidWZmZXI6IEdQVUJ1ZmZlciwgb3JpZ2luYWxTaXplOiBudW1iZXIsIHByZXZpb3VzPzogW0dwdURhdGFJZCwgR1BVQnVmZmVyXSk6IG51bWJlciB7XG4gICAgbGV0IGlkOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHByZXZpb3VzKSB7XG4gICAgICBpZCA9IHByZXZpb3VzWzBdO1xuICAgICAgaWYgKGJ1ZmZlciA9PT0gcHJldmlvdXNbMV0pIHtcbiAgICAgICAgTE9HX0RFQlVHKFxuICAgICAgICAgICd2ZXJib3NlJyxcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgYFtXZWJHUFVdIEdwdURhdGFNYW5hZ2VyLnJlZ2lzdGVyRXh0ZXJuYWxCdWZmZXIoc2l6ZT0ke29yaWdpbmFsU2l6ZX0pID0+IGlkPSR7aWR9LCBidWZmZXIgaXMgdGhlIHNhbWUsIHNraXAuYCxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIGlkO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmJhY2tlbmQuY2FwdHVyZWRDb21tYW5kTGlzdC5oYXModGhpcy5iYWNrZW5kLmN1cnJlbnRTZXNzaW9uSWQhKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlZ2lzdGVyaW5nIGEgZGlmZmVyZW50IGV4dGVybmFsIGJ1ZmZlciB1bmRlciBncmFwaCBjYXB0dXJlIG1vZGUgaXMgbm90IHN1cHBvcnRlZCB5ZXQuXG4gICAgICAgICAgICAgUGxlYXNlIHVzZSB0aGUgcHJldmlvdXMgZXh0ZXJuYWwgYnVmZmVyIWApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZCA9IGNyZWF0ZU5ld0dwdURhdGFJZCgpO1xuICAgIH1cblxuICAgIHRoaXMuc3RvcmFnZUNhY2hlLnNldChpZCwgeyBncHVEYXRhOiB7IGlkLCB0eXBlOiBHcHVEYXRhVHlwZS5kZWZhdWx0LCBidWZmZXIgfSwgb3JpZ2luYWxTaXplIH0pO1xuICAgIExPR19ERUJVRyhcbiAgICAgICd2ZXJib3NlJyxcbiAgICAgICgpID0+IGBbV2ViR1BVXSBHcHVEYXRhTWFuYWdlci5yZWdpc3RlckV4dGVybmFsQnVmZmVyKHNpemU9JHtvcmlnaW5hbFNpemV9KSA9PiBpZD0ke2lkfSwgcmVnaXN0ZXJlZC5gLFxuICAgICk7XG4gICAgcmV0dXJuIGlkO1xuICB9XG5cbiAgdW5yZWdpc3RlckV4dGVybmFsQnVmZmVyKGlkOiBHcHVEYXRhSWQpOiB2b2lkIHtcbiAgICBpZiAoaWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zdG9yYWdlQ2FjaGUuZGVsZXRlKGlkKTtcbiAgICAgIExPR19ERUJVRygndmVyYm9zZScsICgpID0+IGBbV2ViR1BVXSBHcHVEYXRhTWFuYWdlci51bnJlZ2lzdGVyRXh0ZXJuYWxCdWZmZXIoKSA9PiBpZD0ke2lkfWApO1xuICAgIH1cbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gIGNyZWF0ZShzaXplOiBudW1iZXIsIHVzYWdlID0gR1BVQnVmZmVyVXNhZ2UuU1RPUkFHRSB8IEdQVUJ1ZmZlclVzYWdlLkNPUFlfU1JDIHwgR1BVQnVmZmVyVXNhZ2UuQ09QWV9EU1QpOiBHcHVEYXRhIHtcbiAgICBjb25zdCBidWZmZXJTaXplID0gY2FsY0J1Y2tldEJ1ZmZlclNpemUoc2l6ZSk7XG5cbiAgICBsZXQgZ3B1QnVmZmVyO1xuICAgIC8vIEN1cnJlbnRseSwgb25seSBzdG9yYWdlIGJ1ZmZlcnMgYXJlIHJldXNlZC5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYml0d2lzZVxuICAgIGNvbnN0IGlzU3RvcmFnZSA9ICh1c2FnZSAmIEdQVUJ1ZmZlclVzYWdlLlNUT1JBR0UpID09PSBHUFVCdWZmZXJVc2FnZS5TVE9SQUdFO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgY29uc3QgaXNVbmlmb3JtID0gKHVzYWdlICYgR1BVQnVmZmVyVXNhZ2UuVU5JRk9STSkgPT09IEdQVUJ1ZmZlclVzYWdlLlVOSUZPUk07XG4gICAgaWYgKGlzU3RvcmFnZSB8fCBpc1VuaWZvcm0pIHtcbiAgICAgIGNvbnN0IGZyZWVCdWZmZXJzID0gaXNTdG9yYWdlID8gdGhpcy5mcmVlQnVmZmVycyA6IHRoaXMuZnJlZVVuaWZvcm1CdWZmZXJzO1xuICAgICAgY29uc3QgYnVmZmVycyA9IGZyZWVCdWZmZXJzLmdldChidWZmZXJTaXplKTtcbiAgICAgIGlmICghYnVmZmVycykge1xuICAgICAgICAvLyBubyBzdWNoIGJ1Y2tldC9mcmVlbGlzdCAtIGNyZWF0ZSBncHUgYnVmZmVyXG4gICAgICAgIGdwdUJ1ZmZlciA9IHRoaXMuYmFja2VuZC5kZXZpY2UuY3JlYXRlQnVmZmVyKHsgc2l6ZTogYnVmZmVyU2l6ZSwgdXNhZ2UgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoYnVmZmVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgLy8gaW4gZnJlZWxpc3QsIHVzZSBpdFxuICAgICAgICAgIGdwdUJ1ZmZlciA9IGJ1ZmZlcnMucG9wKCkgYXMgR1BVQnVmZmVyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGJ1Y2tldCBlbXB0eSwgY3JlYXRlIGdwdSBidWZmZXJcbiAgICAgICAgICBncHVCdWZmZXIgPSB0aGlzLmJhY2tlbmQuZGV2aWNlLmNyZWF0ZUJ1ZmZlcih7IHNpemU6IGJ1ZmZlclNpemUsIHVzYWdlIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGNyZWF0ZSBncHUgYnVmZmVyXG4gICAgICBncHVCdWZmZXIgPSB0aGlzLmJhY2tlbmQuZGV2aWNlLmNyZWF0ZUJ1ZmZlcih7IHNpemU6IGJ1ZmZlclNpemUsIHVzYWdlIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGdwdURhdGEgPSB7IGlkOiBjcmVhdGVOZXdHcHVEYXRhSWQoKSwgdHlwZTogR3B1RGF0YVR5cGUuZGVmYXVsdCwgYnVmZmVyOiBncHVCdWZmZXIgfTtcbiAgICB0aGlzLnN0b3JhZ2VDYWNoZS5zZXQoZ3B1RGF0YS5pZCwgeyBncHVEYXRhLCBvcmlnaW5hbFNpemU6IE51bWJlcihzaXplKSB9KTtcblxuICAgIExPR19ERUJVRygndmVyYm9zZScsICgpID0+IGBbV2ViR1BVXSBHcHVEYXRhTWFuYWdlci5jcmVhdGUoc2l6ZT0ke3NpemV9KSA9PiBpZD0ke2dwdURhdGEuaWR9YCk7XG4gICAgcmV0dXJuIGdwdURhdGE7XG4gIH1cblxuICBnZXQoaWQ6IEdwdURhdGFJZCk6IEdwdURhdGEgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnN0b3JhZ2VDYWNoZS5nZXQoaWQpPy5ncHVEYXRhO1xuICB9XG5cbiAgcmVsZWFzZShpZElucHV0OiBHcHVEYXRhSWQpOiBudW1iZXIge1xuICAgIGNvbnN0IGlkID0gdHlwZW9mIGlkSW5wdXQgPT09ICdiaWdpbnQnID8gTnVtYmVyKGlkSW5wdXQpIDogaWRJbnB1dDtcbiAgICBjb25zdCBjYWNoZWREYXRhID0gdGhpcy5zdG9yYWdlQ2FjaGUuZ2V0KGlkKTtcbiAgICBpZiAoIWNhY2hlZERhdGEpIHtcbiAgICAgIGlmICh0aGlzLnN0b3JhZ2VDYWNoZS5zaXplID09PSAwKSB7XG4gICAgICAgIC8vIGNhY2hlIHdhcyBwcmV2aW91c2x5IGNsZWFyZWQsIG5vIG5lZWQgdG8gcmVsZWFzZSBhbnl0aGluZy5cbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3JlbGVhc2luZyBkYXRhIGRvZXMgbm90IGV4aXN0Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgTE9HX0RFQlVHKCd2ZXJib3NlJywgKCkgPT4gYFtXZWJHUFVdIEdwdURhdGFNYW5hZ2VyLnJlbGVhc2UoaWQ9JHtpZH0pLCBncHVEYXRhSWQ9JHtjYWNoZWREYXRhLmdwdURhdGEuaWR9YCk7XG5cbiAgICB0aGlzLnN0b3JhZ2VDYWNoZS5kZWxldGUoaWQpO1xuICAgIHRoaXMuYnVmZmVyc1BlbmRpbmcucHVzaChjYWNoZWREYXRhLmdwdURhdGEuYnVmZmVyKTtcbiAgICAvLyBjYWNoZWREYXRhLmdwdURhdGEuYnVmZmVyLmRlc3Ryb3koKTtcblxuICAgIHJldHVybiBjYWNoZWREYXRhLm9yaWdpbmFsU2l6ZTtcbiAgfVxuXG4gIGFzeW5jIGRvd25sb2FkKGlkOiBHcHVEYXRhSWQsIGdldFRhcmdldEJ1ZmZlcjogKCkgPT4gVWludDhBcnJheSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNhY2hlZERhdGEgPSB0aGlzLnN0b3JhZ2VDYWNoZS5nZXQoTnVtYmVyKGlkKSk7XG4gICAgaWYgKCFjYWNoZWREYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGEgZG9lcyBub3QgZXhpc3QnKTtcbiAgICB9XG4gICAgYXdhaXQgZG93bmxvYWRHcHVEYXRhKHRoaXMuYmFja2VuZCwgY2FjaGVkRGF0YS5ncHVEYXRhLmJ1ZmZlciwgY2FjaGVkRGF0YS5vcmlnaW5hbFNpemUsIGdldFRhcmdldEJ1ZmZlcik7XG4gIH1cblxuICByZWZyZXNoUGVuZGluZ0J1ZmZlcnMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYnVmZmVyc1BlbmRpbmcubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYmFja2VuZC5zZXNzaW9uU3RhdHVzID09PSAnZGVmYXVsdCcpIHtcbiAgICAgIGZvciAoY29uc3QgYnVmZmVyIG9mIHRoaXMuYnVmZmVyc1BlbmRpbmcpIHtcbiAgICAgICAgY29uc3QgbWF4SW5GcmVlTGlzdCA9IGJ1Y2tldEZyZWVsaXN0LmdldChidWZmZXIuc2l6ZSk7XG5cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWJpdHdpc2VcbiAgICAgICAgaWYgKChidWZmZXIudXNhZ2UgJiBHUFVCdWZmZXJVc2FnZS5TVE9SQUdFKSA9PT0gR1BVQnVmZmVyVXNhZ2UuU1RPUkFHRSkge1xuICAgICAgICAgIC8vIFB1dCB0aGUgcGVuZGluZyBidWZmZXIgdG8gZnJlZUJ1ZmZlcnMgbGlzdCBpbnN0ZWFkIG9mIHJlYWxseSBkZXN0cm95aW5nIGl0IGZvciBidWZmZXIgcmV1c2luZy5cbiAgICAgICAgICBjb25zdCBmcmVlbGlzdCA9IHRoaXMuZnJlZUJ1ZmZlcnMuZ2V0KGJ1ZmZlci5zaXplKSB8fCBbXTtcbiAgICAgICAgICBpZiAobWF4SW5GcmVlTGlzdCA9PT0gdW5kZWZpbmVkIHx8IGZyZWVsaXN0Lmxlbmd0aCA+PSBtYXhJbkZyZWVMaXN0KSB7XG4gICAgICAgICAgICBidWZmZXIuZGVzdHJveSgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmcmVlbGlzdC5wdXNoKGJ1ZmZlcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgICAgIH0gZWxzZSBpZiAoKGJ1ZmZlci51c2FnZSAmIEdQVUJ1ZmZlclVzYWdlLlVOSUZPUk0pID09PSBHUFVCdWZmZXJVc2FnZS5VTklGT1JNKSB7XG4gICAgICAgICAgLy8gUHV0IHRoZSBwZW5kaW5nIGJ1ZmZlciB0byBmcmVlVW5pZm9ybUJ1ZmZlcnMgbGlzdCBpbnN0ZWFkIG9mIHJlYWxseSBkZXN0cm95aW5nIGl0IGZvciBidWZmZXIgcmV1c2luZy5cbiAgICAgICAgICBjb25zdCBmcmVlbGlzdCA9IHRoaXMuZnJlZVVuaWZvcm1CdWZmZXJzLmdldChidWZmZXIuc2l6ZSkgfHwgW107XG4gICAgICAgICAgaWYgKG1heEluRnJlZUxpc3QgPT09IHVuZGVmaW5lZCB8fCBmcmVlbGlzdC5sZW5ndGggPj0gbWF4SW5GcmVlTGlzdCkge1xuICAgICAgICAgICAgYnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZnJlZWxpc3QucHVzaChidWZmZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBidWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmJ1ZmZlcnNQZW5kaW5nID0gW107XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERvbid0IHJlbGVhc2UgaW50ZXJtZWRpYXRlIHRlbnNvcnMgaW4gbm9uLWRlZmF1bHQgbW9kZS5cbiAgICAgIC8vIFRPRE86IHJldXNlIHRoZSBzdG9yYWdlIGJ1ZmZlcnMgaW4gbm9uLWRlZmF1bHQgbW9kZS5cbiAgICAgIGxldCBjYXB0dXJlZEJ1ZmZlcnMgPSB0aGlzLmNhcHR1cmVkUGVuZGluZ0J1ZmZlcnMuZ2V0KHRoaXMuYmFja2VuZC5jdXJyZW50U2Vzc2lvbklkISk7XG4gICAgICBpZiAoIWNhcHR1cmVkQnVmZmVycykge1xuICAgICAgICBjYXB0dXJlZEJ1ZmZlcnMgPSBbXTtcbiAgICAgICAgdGhpcy5jYXB0dXJlZFBlbmRpbmdCdWZmZXJzLnNldCh0aGlzLmJhY2tlbmQuY3VycmVudFNlc3Npb25JZCEsIGNhcHR1cmVkQnVmZmVycyk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGJ1ZmZlciBvZiB0aGlzLmJ1ZmZlcnNQZW5kaW5nKSB7XG4gICAgICAgIGNhcHR1cmVkQnVmZmVycy5wdXNoKGJ1ZmZlcik7XG4gICAgICB9XG4gICAgICB0aGlzLmJ1ZmZlcnNQZW5kaW5nID0gW107XG4gICAgfVxuICB9XG5cbiAgZGlzcG9zZSgpIHtcbiAgICB0aGlzLmZyZWVCdWZmZXJzLmZvckVhY2goKGJ1ZmZlcnMpID0+IHtcbiAgICAgIGJ1ZmZlcnMuZm9yRWFjaCgoYnVmZmVyKSA9PiB7XG4gICAgICAgIGJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICB0aGlzLmZyZWVVbmlmb3JtQnVmZmVycy5mb3JFYWNoKChidWZmZXJzKSA9PiB7XG4gICAgICBidWZmZXJzLmZvckVhY2goKGJ1ZmZlcikgPT4ge1xuICAgICAgICBidWZmZXIuZGVzdHJveSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnN0b3JhZ2VDYWNoZS5mb3JFYWNoKChzdG9yYWdlKSA9PiB7XG4gICAgICBzdG9yYWdlLmdwdURhdGEuYnVmZmVyLmRlc3Ryb3koKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY2FwdHVyZWRQZW5kaW5nQnVmZmVycy5mb3JFYWNoKChidWZmZXJzKSA9PiB7XG4gICAgICBidWZmZXJzLmZvckVhY2goKGJ1ZmZlcikgPT4ge1xuICAgICAgICBidWZmZXIuZGVzdHJveSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgdGhpcy5zdG9yYWdlQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5mcmVlQnVmZmVycyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmZyZWVVbmlmb3JtQnVmZmVycyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmNhcHR1cmVkUGVuZGluZ0J1ZmZlcnMgPSBuZXcgTWFwKCk7XG4gIH1cblxuICBvbkNyZWF0ZVNlc3Npb24oKSB7XG4gICAgdGhpcy5zZXNzaW9uQ291bnQgKz0gMTtcbiAgfVxuXG4gIG9uUmVsZWFzZVNlc3Npb24oc2Vzc2lvbklkOiBudW1iZXIpIHtcbiAgICAvLyByZWxlYXNlIHRoZSBjYXB0dXJlZCBwZW5kaW5nIGJ1ZmZlcnMuXG4gICAgY29uc3QgcGVuZGluZ0J1ZmZlcnMgPSB0aGlzLmNhcHR1cmVkUGVuZGluZ0J1ZmZlcnMuZ2V0KHNlc3Npb25JZCk7XG4gICAgaWYgKHBlbmRpbmdCdWZmZXJzKSB7XG4gICAgICBwZW5kaW5nQnVmZmVycy5mb3JFYWNoKChidWZmZXIpID0+IHtcbiAgICAgICAgYnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5jYXB0dXJlZFBlbmRpbmdCdWZmZXJzLmRlbGV0ZShzZXNzaW9uSWQpO1xuICAgIH1cblxuICAgIC8vIHJlbGVhc2UgdGhlIHN0b3JhZ2UgY2FjaGUgaWYgbm8gYWN0aXZlIHNlc3Npb25zLlxuICAgIHRoaXMuc2Vzc2lvbkNvdW50IC09IDE7XG4gICAgaWYgKHRoaXMuc2Vzc2lvbkNvdW50ID09PSAwKSB7XG4gICAgICBMT0dfREVCVUcoJ3dhcm5pbmcnLCAoKSA9PiAnW1dlYkdQVV0gQ2xlYXJpbmcgd2ViZ3B1IGJ1ZmZlciBjYWNoZScpO1xuICAgICAgdGhpcy5zdG9yYWdlQ2FjaGUuZm9yRWFjaCgoc3RvcmFnZSkgPT4ge1xuICAgICAgICBzdG9yYWdlLmdwdURhdGEuYnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5zdG9yYWdlQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVHcHVEYXRhTWFuYWdlciA9ICguLi5hcmdzOiBDb25zdHJ1Y3RvclBhcmFtZXRlcnM8dHlwZW9mIEdwdURhdGFNYW5hZ2VySW1wbD4pOiBHcHVEYXRhTWFuYWdlciA9PlxuICBuZXcgR3B1RGF0YU1hbmFnZXJJbXBsKC4uLmFyZ3MpO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5jbGFzcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXlJbXBsIHtcbiAgY29uc3RydWN0b3IoYXR0cmlidXRlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcywgYXR0cmlidXRlKTtcbiAgfVxuXG4gIHByaXZhdGUga2V5OiBzdHJpbmc7XG4gIHB1YmxpYyBnZXQgY2FjaGVLZXkoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMua2V5KSB7XG4gICAgICB0aGlzLmtleSA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMpXG4gICAgICAgIC5zb3J0KClcbiAgICAgICAgLm1hcCgobmFtZSkgPT4gYCR7KHRoaXMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW25hbWVdfWApXG4gICAgICAgIC5qb2luKCc7Jyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmtleTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGNhY2hlS2V5OiBzdHJpbmc7XG59XG5cbi8qKlxuICogY3JlYXRlIGEgbmV3IG9iamVjdCBmcm9tIHRoZSBnaXZlbiBhdHRyaWJ1dGUsIGFuZCBhZGQgYSBjYWNoZUtleSBwcm9wZXJ0eSB0byBpdFxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5ID0gPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gIGF0dHJpYnV0ZTogVCxcbik6IFQgJiBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgPT4gbmV3IEF0dHJpYnV0ZVdpdGhDYWNoZUtleUltcGwoYXR0cmlidXRlKSBhcyB1bmtub3duIGFzIFQgJiBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBQcm9ncmFtVW5pZm9ybSwgUHJvZ3JhbVVuaWZvcm1WYXJpYWJsZUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbi8qKlxuICogY29uc3RhbnQgdmFsdWUgZm9yIGEgd29ya2dyb3VwIHNpemUuXG4gKlxuICogV2UgZGVmaW5pdGVseSBjYW4gZG8gZnVydGhlciBvcHRpbWl6YXRpb24gaW4gZnV0dXJlLCBidXQgZm9yIG5vdyB3ZSB1c2UgNjQuXG4gKlxuICogcnVsZSBvZiB0aHVtYjogVXNlIFthIHdvcmtncm91cCBzaXplIG9mXSA2NCB1bmxlc3MgeW91IGtub3cgd2hhdCBHUFUgeW91IGFyZSB0YXJnZXRpbmcgb3IgdGhhdCB5b3VyIHdvcmtsb2FkXG4gKiAgICAgICAgICAgICAgICBuZWVkcyBzb21ldGhpbmcgZGlmZmVyZW50LlxuICpcbiAqIGZyb206IGh0dHBzOi8vc3VybWEuZGV2L3RoaW5ncy93ZWJncHUvXG4gKiovXG5leHBvcnQgY29uc3QgV09SS0dST1VQX1NJWkUgPSA2NDtcblxuaW50ZXJmYWNlIEluZGljZXNIZWxwZXJUeXBlcyB7XG4gIC8qKlxuICAgKiBXR1NMIHR5cGUgb2YgaW5kaWNlcyBleHByZXNzaW9uXG4gICAqL1xuICByZWFkb25seSBpbmRpY2VzOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdHU0wgdHlwZSBvZiBhIHZhbHVlXG4gICAqL1xuICByZWFkb25seSB2YWx1ZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXR1NMIHR5cGUgb2Ygc3RvcmFnZSB0eXBlIHJlcHJlc2VudGluZyBhIHZhbHVlXG4gICAqXG4gICAqIFRoaXMgaXMgdXN1YWxseSB0aGUgc2FtZSB0byBgdmFsdWVgLCBidXQgZm9yIHNvbWUgdHlwZSAoZWcuIGJvb2wpLCB3ZSBuZWVkIHRvIHVzZSBgdTMyYCBhcyBzdG9yYWdlIHR5cGUgZm9yXG4gICAqIHZhbHVlIHR5cGUgYHZlYzQ8Ym9vbD5gXG4gICAqL1xuICByZWFkb25seSBzdG9yYWdlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIHRlbnNvciB0eXBlIGFzIHJlcHJlc2VudGVkIGluIFRlbnNvclZpZXdcbiAgICovXG4gIHJlYWRvbmx5IHRlbnNvcjogbnVtYmVyO1xufVxuXG4vKipcbiAqIEEgaGVscGVyIGNsYXNzIGZvciBnZW5lcmF0aW5nIFdHU0wgY29kZSBmb3IgbWFuaXB1bGF0aW5nIGluZGljZXMgYW5kIGRhdGEgZm9yIGEgc2hhZGVyJ3MgaW5wdXQgb3Igb3V0cHV0LlxuICpcbiAqIFRoaXMgY2xhc3MgaXMgZGVzaWduZWQgdG8gb2ZmZXIgYSB1bmlmaWVkIHdheSB0byBnZW5lcmF0ZSBXR1NMIGNvZGUgZm9yIG1hbmlwdWxhdGluZyBpbmRpY2VzIGFuZCBkYXRhIGZvciBhIHNoYWRlcidzXG4gKiBpbnB1dCBvciBvdXRwdXQuXG4gKlxuICogVGhlIGZvbGxvd2luZyBpcyBhIGxpc3Qgb2YgdGVybWlub2xvZ2llcyB1c2VkIGluIHRoaXMgY2xhc3M6XG4gKiAtIGBvZmZzZXRgOiBhIHVpbnQzMiB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIG9mZnNldCBvZiBhbiBlbGVtZW50IGluIHRoZSBkYXRhIGJ1ZmZlci5cbiAqIC0gYGluZGljZXNgOiBhbiBhYnN0cmFjdGlvbiBvZiBhIG11bHRpLWRpbWVuc2lvbmFsIGFycmF5J3MgaW5kaWNlcyByZXByZXNlbnRpbmcgdGhlIGRhdGEncyBpbmRleCBvbiBlYWNoIGRpbWVuc2lvbi5cbiAqIC0gYHZhbHVlYDogYSB2YWx1ZSBvZiBhIGRhdGEgZWxlbWVudC5cbiAqXG4gKiBVc2VycyBhcmUgZXhwZWN0ZWQgdG8gY3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZm9yIGVhY2ggc2hhZGVyJ3MgaW5wdXQgb3Igb3V0cHV0LCBhbmQgdXNlIHRoZSBpbnN0YW5jZSB0b1xuICogZ2VuZXJhdGUgV0dTTCBjb2RlIGZvciBtYW5pcHVsYXRpbmcgaW5kaWNlcyBhbmQgZGF0YS4gVGhlIGZvbGxvd2luZyAyIGV4cG9ydGVkIGZ1bmN0aW9ucyBhcmUgZm9yIHVzZXJzIHRvIGNhbGwgdG9cbiAqIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiBhbiBpbmRpY2VzIGhlbHBlcjpcbiAqIC0gYGlucHV0VmFyaWFibGUoKWA6IGNyZWF0ZSBhbiBpbmRpY2VzIGhlbHBlciBpbnN0YW5jZSBmb3IgYW4gaW5wdXQuXG4gKiAtIGBvdXRwdXRWYXJpYWJsZSgpYDogY3JlYXRlIGFuIGluZGljZXMgaGVscGVyIGluc3RhbmNlIGZvciBhbiBvdXRwdXQuXG4gKiAtIGBpbnRlcm5hbFZhcmlhYmxlKClgOiBjcmVhdGUgYW4gaW5kaWNlcyBoZWxwZXIgaW5zdGFuY2UgZm9yIGFuIGludGVybmFsIHZhcmlhYmxlLlxuICpcbiAqIEFuIGluZGljZXMgaGVscGVyIGluc3RhbmNlIGNvbnRhaW5zIGhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBmb2xsb3dpbmcgb3BlcmF0aW9uczpcbiAqIC0gYWNjZXNzIHJlYWRvbmx5IGJhc2ljIGluZm9ybWF0aW9uLCBpbmNsdWRpbmc6IGBuYW1lYCh0aGUgbmFtZSBvZiB0aGUgaW5wdXQgb3Igb3V0cHV0KSwgYHVzYWdlYCh3aGV0aGVyIGl0J3MgYW5cbiAqIGlucHV0LCBhbiBvdXRwdXQgb3IgYW4gaW50ZXJuYWwgdmFyaWFibGUpIGFuZCBgc2hhcGVgKHRoZSBwYXNzZWQgaW4gc2hhcGUpLlxuICogLSBgdHlwZWA6IGFjY2VzcyByZWFkb25seSB0eXBlIGluZm9ybWF0aW9uLCBpbmNsdWRpbmc6IGBpbmRpY2VzYCh0aGUgdHlwZSBvZiBpbmRpY2VzKSwgYHZhbHVlYCh0aGUgdHlwZSBvZiB2YWx1ZSBhdFxuICogcnVudGltZSksIGBzdG9yYWdlYCh0aGUgdHlwZSBvZiB2YWx1ZSBhdCBzdG9yYWdlKSBhbmQgYHRlbnNvcmAodGhlIHRlbnNvciB0eXBlIGFzIHJlcHJlc2VudGVkIGluIFRlbnNvclZpZXcpLlxuICogLSBnZW5lcmF0ZSBXR1NMIGNvZGUgZm9yIGdldHRpbmcgaW5kaWNlcyBmcm9tIG9mZnNldC4gVXNlIGBvZmZzZXRUb0luZGljZXMoKWAgZm9yIFdHU0wgY29kZSBzbmlwcGV0IHRvIGNhbGN1bGF0ZVxuICogaW5kaWNlcyBmcm9tIG9mZnNldCwgYW5kIHVzZSBgaW5kaWNlc1RvT2Zmc2V0KClgIGZvciBXR1NMIGNvZGUgc25pcHBldCB0byBjYWxjdWxhdGUgb2Zmc2V0IGZyb20gaW5kaWNlcy5cbiAqIC0gdG8gbWFuaXB1bGF0ZSBhbiBpbnN0YW5jZSBvZiBpbmRpY2VzLCB1c2UgYHNldEluZGljZXMoKWAgYW5kIGBnZXRJbmRpY2VzKClgIHRvIHNldCBhbmQgZ2V0IHRoZSBpbmRpY2VzIG9uIGFuXG4gKiBpbmRpY2VzIHZhcmlhYmxlLlxuICogLSB0byBtYW5pcHVsYXRlIGRhdGEsIHVzZSBgc2V0KClgL2BnZXQoKWAgdG8gYWNjZXNzIGRhdGEgYXQgdGhlIGdpdmVuIGluZGljZXMgZnJvbSBwYXJhbWV0ZXIgbGlzdCwgdXNlXG4gKiBgc2V0QnlJbmRpY2VzKClgL2BnZXRCeUluZGljZXMoKWAgdG8gYWNjZXNzIGRhdGEgYXQgdGhlIGdpdmVuIGluZGljZXMgZnJvbSBhbiBpbmRpY2VzIHZhcmlhYmxlLCBhbmQgdXNlXG4gKiBgc2V0QnlPZmZzZXQoKWAvYGdldEJ5T2Zmc2V0KClgIHRvIGFjY2VzcyBkYXRhIGF0IHRoZSBnaXZlbiBvZmZzZXQuXG4gKiAtIGBpbXBsYDogZ2V0IFdHU0wgY29kZSBvZiBmdW5jdGlvbiBpbXBsZW1lbnRhdGlvbiBmb3IgdGhlIHV0aWwgZnVuY3Rpb25zIG1lbnRpb25lZCBhYm92ZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbmRpY2VzSGVscGVyIHtcbiAgLyoqXG4gICAqIGdldCBXR1NMIGNvZGUgb2YgZnVuY3Rpb24gaW1wbGVtZW50YXRpb24gZm9yIHRoZSB1dGlsIGZ1bmN0aW9ucy5cbiAgICpcbiAgICovXG4gIHJlYWRvbmx5IGltcGw6ICgpID0+IHN0cmluZztcblxuICAvKipcbiAgICogZ2V0IHR5cGUgaW5mb1xuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogSW5kaWNlc0hlbHBlclR5cGVzO1xuXG4gIC8qKlxuICAgKiBXR1NMIGNvZGUgb2YgYSBleHByZXNzaW9uIGZvciBnZXR0aW5nIGluZGljZXMgZnJvbSBvZmZzZXQuXG4gICAqXG4gICAqIEBwYXJhbSB2YXJPZmZzZXQgLSBhIHUzMiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgb2Zmc2V0LlxuICAgKlxuICAgKiBAcmV0dXJucyBhbiBgdHlwZS5pbmRpY2VzYCBleHByZXNzaW9uXG4gICAqL1xuICByZWFkb25seSBvZmZzZXRUb0luZGljZXM6ICh2YXJPZmZzZXQ6IHN0cmluZykgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXR1NMIGNvZGUgb2YgYW4gYHUzMmAgZXhwcmVzc2lvbiBmb3IgZ2V0dGluZyBvZmZzZXQgZnJvbSBpbmRpY2VzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFySW5kaWNlcyAtIGEgYHR5cGUuaW5kaWNlc2AgZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGluZGljZXMuXG4gICAqXG4gICAqIEByZXR1cm5zIGFuIGB1MzJgIGV4cHJlc3Npb25cbiAgICovXG4gIHJlYWRvbmx5IGluZGljZXNUb09mZnNldDogKHZhckluZGljZXM6IHN0cmluZykgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXR1NMIGNvZGUgb2YgYW4gYHUzMmAgZXhwcmVzc2lvbiBmb3IgZ2V0dGluZyBvcmlnaW5hbCBvZmZzZXQgZnJvbSBicm9hZGNhc3RlZCBpbmRpY2VzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFySW5kaWNlcyAtIGEgYHR5cGUuaW5kaWNlc2AgZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIG91dHB1dCBpbmRpY2VzLlxuICAgKiBAcGFyYW0gb3V0cHV0IC0gb3V0cHV0IEluZGljZXNIZWxwZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIGFuIGB1MzJgIGV4cHJlc3Npb25cbiAgICovXG4gIHJlYWRvbmx5IGJyb2FkY2FzdGVkSW5kaWNlc1RvT2Zmc2V0OiAodmFySW5kaWNlczogc3RyaW5nLCBvdXRwdXQ6IEluZGljZXNIZWxwZXIpID0+IHN0cmluZztcblxuICAvKipcbiAgICogV0dTTCBjb2RlIG9mIGdlbmVyYXRpbmcgYW4gaW5kaWNlcyBsaXRlcmFsXG4gICAqXG4gICAqIEBwYXJhbSBpbml0IC0gaW5pdGlhbCB2YWx1ZS5cbiAgICovXG4gIHJlYWRvbmx5IGluZGljZXM6ICguLi5pbml0OiBSZWFkb25seUFycmF5PG51bWJlciB8IHN0cmluZz4pID0+IHN0cmluZztcblxuICAvKipcbiAgICogV0dTTCBjb2RlIG9mIGEgc3RhdGVtZW50IGZvciBzZXR0aW5nIGluZGljZXMuXG4gICAqXG4gICAqIEBwYXJhbSB2YXJJbmRpY2VzIC0gYSB2YXJpYWJsZSBuYW1lIGZvciB0aGUgaW5kaWNlcy5cbiAgICogQHBhcmFtIGlkeCAtIHRoZSBpbmRleCBvZiB0aGUgaW5kaWNlcyB0byBzZXQuIGNhbiBiZSBhIG51bWJlciBvciBhIHN0cmluZyAoV0dTTCBgdTMyYCBleHByZXNzaW9uKS5cbiAgICogQHBhcmFtIHZhbHVlIC0gdGhlIHZhbHVlIHRvIHNldC4gY2FuIGJlIGEgbnVtYmVyIG9yIGEgc3RyaW5nIChXR1NMIGB1MzJgIGV4cHJlc3Npb24pLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIFdHU0wgc3RhdGVtZW50XG4gICAqL1xuICByZWFkb25seSBpbmRpY2VzU2V0OiAodmFySW5kaWNlczogc3RyaW5nLCBpZHg6IG51bWJlciB8IHN0cmluZywgdmFsdWU6IG51bWJlciB8IHN0cmluZykgPT4gdm9pZDtcblxuICAvKipcbiAgICogV0dTTCBjb2RlIG9mIGFuIGB1MzJgIGV4cHJlc3Npb24gZm9yIGdldHRpbmcgaW5kaWNlcy5cbiAgICpcbiAgICogQHBhcmFtIHZhckluZGljZXMgLSBhIHZhcmlhYmxlIG5hbWUgZm9yIHRoZSBpbmRpY2VzLlxuICAgKiBAcGFyYW0gaWR4IC0gdGhlIGluZGV4IG9mIHRoZSBpbmRpY2VzIHRvIGdldC4gY2FuIGJlIGEgbnVtYmVyIG9yIGEgc3RyaW5nIChXR1NMIGB1MzJgIGV4cHJlc3Npb24pLlxuICAgKlxuICAgKiBAcmV0dXJucyBhbiBgdTMyYCBleHByZXNzaW9uXG4gICAqL1xuICByZWFkb25seSBpbmRpY2VzR2V0OiAodmFySW5kaWNlczogc3RyaW5nLCBpZHg6IG51bWJlciB8IHN0cmluZykgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXR1NMIGNvZGUgZm9yIGEgc3RhdGVtZW50IGZvciBzZXR0aW5nIGRhdGEgYXQgdGhlIGdpdmVuIGluZGljZXMuXG4gICAqXG4gICAqIEBwYXJhbSBpbmRpY2VzQW5kVmFsdWUgLSBhbiBhcnJheSBvZiBudW1iZXJzIG9yIHN0cmluZ3MgKFdHU0wgYHUzMmAgZXhwcmVzc2lvbikgcmVwcmVzZW50aW5nIHRoZSBpbmRpY2VzLCBmb2xsb3dlZFxuICAgKiAgICAgYnkgdGhlIHZhbHVlIHRvIHNldC4gVGhpcyBhcnJheSBzaG91bGQgaGF2ZSBleGFjdGx5IGBzaGFwZS5sZW5ndGggKyAxYCBlbGVtZW50cy5cbiAgICovXG4gIHJlYWRvbmx5IHNldDogKC4uLmluZGljZXNBbmRWYWx1ZTogUmVhZG9ubHlBcnJheTxudW1iZXIgfCBzdHJpbmc+KSA9PiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdHU0wgY29kZSBmb3IgYSBzdGF0ZW1lbnQgZm9yIHNldHRpbmcgZGF0YSBhdCB0aGUgZ2l2ZW4gaW5kaWNlcyB2YXJpYWJsZS5cbiAgICpcbiAgICogQHBhcmFtIHZhckluZGljZXMgLSBhIHZhcmlhYmxlIG5hbWUgZm9yIHRoZSBpbmRpY2VzLlxuICAgKiBAcGFyYW0gdmFsdWUgLSB0aGUgdmFsdWUgdG8gc2V0LiBzaG91bGQgYmUgYSBXR1NMIGV4cHJlc3Npb24uXG4gICAqL1xuICByZWFkb25seSBzZXRCeUluZGljZXM6ICh2YXJJbmRpY2VzOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpID0+IHN0cmluZztcblxuICAvKipcbiAgICogV0dTTCBjb2RlIGZvciBhIHN0YXRlbWVudCBmb3Igc2V0dGluZyBkYXRhIGF0IHRoZSBnaXZlbiBvZmZzZXQuXG4gICAqXG4gICAqIEBwYXJhbSBvZmZzZXQgLSBhIG51bWJlciBvciBhIHN0cmluZyAoV0dTTCBgdTMyYCBleHByZXNzaW9uKSByZXByZXNlbnRpbmcgdGhlIG9mZnNldC5cbiAgICogQHBhcmFtIHZhbHVlIC0gdGhlIHZhbHVlIHRvIHNldC4gc2hvdWxkIGJlIGEgV0dTTCBleHByZXNzaW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgc2V0QnlPZmZzZXQ6IChvZmZzZXQ6IG51bWJlciB8IHN0cmluZywgdmFsdWU6IHN0cmluZykgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXR1NMIGNvZGUgZm9yIGFuIGV4cHJlc3Npb24gZm9yIGdldHRpbmcgZGF0YSBhdCB0aGUgZ2l2ZW4gaW5kaWNlcy5cbiAgICpcbiAgICogQHBhcmFtIGluZGljZXMgLSBhbiBhcnJheSBvZiBudW1iZXJzIG9yIHN0cmluZ3MgKFdHU0wgYHUzMmAgZXhwcmVzc2lvbikgcmVwcmVzZW50aW5nIHRoZSBpbmRpY2VzLlxuICAgKi9cbiAgcmVhZG9ubHkgZ2V0OiAoLi4uaW5kaWNlczogUmVhZG9ubHlBcnJheTxudW1iZXIgfCBzdHJpbmc+KSA9PiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdHU0wgY29kZSBmb3IgYW4gZXhwcmVzc2lvbiBmb3IgZ2V0dGluZyBkYXRhIGF0IHRoZSBnaXZlbiBpbmRpY2VzIHZhcmlhYmxlLlxuICAgKlxuICAgKiBAcGFyYW0gdmFySW5kaWNlcyAtIGEgdmFyaWFibGUgbmFtZSBmb3IgdGhlIGluZGljZXMuXG4gICAqL1xuICByZWFkb25seSBnZXRCeUluZGljZXM6ICh2YXJJbmRpY2VzOiBzdHJpbmcpID0+IHN0cmluZztcblxuICAvKipcbiAgICogV0dTTCBjb2RlIGZvciBhbiBleHByZXNzaW9uIGZvciBnZXR0aW5nIGRhdGEgYXQgdGhlIGdpdmVuIG9mZnNldC5cbiAgICpcbiAgICogQHBhcmFtIG9mZnNldCAtIGEgbnVtYmVyIG9yIGEgc3RyaW5nIChXR1NMIGB1MzJgIGV4cHJlc3Npb24pIHJlcHJlc2VudGluZyB0aGUgb2Zmc2V0LlxuICAgKi9cbiAgcmVhZG9ubHkgZ2V0QnlPZmZzZXQ6IChvZmZzZXQ6IG51bWJlciB8IHN0cmluZykgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBuYW1lIG9mIHRoZSBkYXRhIHZhcmlhYmxlXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIHdoZXRoZXIgdGhlIGhlbHBlciBpcyBmb3IgYW4gaW5wdXQsIGFuIG91dHB1dCBvciBhbiBpbnRlcm5hbCB2YXJpYWJsZS5cbiAgICovXG4gIHJlYWRvbmx5IHVzYWdlOiAnaW5wdXQnIHwgJ291dHB1dCcgfCAnYXRvbWljT3V0cHV0JyB8ICdpbnRlcm5hbCc7XG5cbiAgLyoqXG4gICAqIHRoZSByYW5rIG9mIHRoZSBpbnB1dCBvciBvdXRwdXQuXG4gICAqL1xuICByZWFkb25seSByYW5rOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgdmFyaWFibGUgbmFtZSBmb3IgdGhlIHNoYXBlIG9mIHRoZSBpbnB1dCBvciBvdXRwdXQuXG4gICAqL1xuICByZWFkb25seSBzaGFwZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHZhcmlhYmxlIG5hbWUgZm9yIHRoZSBzdHJpZGVzIG9mIHRoZSBpbnB1dCBvciBvdXRwdXQuXG4gICAqL1xuICByZWFkb25seSBzdHJpZGVzOiBzdHJpbmc7XG59XG5cbmNvbnN0IGdldFdnc2xNYXBwZWRUeXBlID0gKHR5cGU6IG51bWJlciwgY29tcG9uZW50czogMSB8IDIgfCAzIHwgNCk6IHN0cmluZyB8IFtzdHJpbmcsIHN0cmluZ10gPT4ge1xuICBpZiAoY29tcG9uZW50cyA9PT0gMykge1xuICAgIHRocm93IG5ldyBFcnJvcigndmVjMyBoYXMgc2FtZSBhbGlnbm1lbnQgYXMgdmVjNCwgdXNlIHZlYzQgaW5zdGVhZCcpO1xuICB9XG5cbiAgLy8gcmV0dXJuIHR5cGUgaXMgWyBzdG9yYWdlIHR5cGUsIHJ1bnRpbWUgdHlwZSBdIG9yIGEgc2luZ2xlIHN0cmluZyBmb3IgYm90aFxuICBzd2l0Y2ggKE51bWJlcih0eXBlKSkge1xuICAgIGNhc2UgRGF0YVR5cGUuZmxvYXQxNjpcbiAgICAgIHJldHVybiBjb21wb25lbnRzID4gMSA/IGB2ZWMke2NvbXBvbmVudHN9PGYxNj5gIDogJ2YxNic7XG4gICAgY2FzZSBEYXRhVHlwZS5mbG9hdDpcbiAgICAgIHJldHVybiBjb21wb25lbnRzID4gMSA/IGB2ZWMke2NvbXBvbmVudHN9PGYzMj5gIDogJ2YzMic7XG4gICAgY2FzZSBEYXRhVHlwZS5pbnQzMjpcbiAgICAgIHJldHVybiBjb21wb25lbnRzID4gMSA/IGB2ZWMke2NvbXBvbmVudHN9PGkzMj5gIDogJ2kzMic7XG4gICAgY2FzZSBEYXRhVHlwZS51aW50MzI6XG4gICAgICByZXR1cm4gY29tcG9uZW50cyA+IDEgPyBgdmVjJHtjb21wb25lbnRzfTx1MzI+YCA6ICd1MzInO1xuICAgIGNhc2UgRGF0YVR5cGUuaW50NjQ6XG4gICAgICBpZiAoY29tcG9uZW50cyA+IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgbm90IHN1cHBvcnRlZCB2ZWNYIG9mIHVpbnQ2NCB5ZXQnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBbJ3ZlYzI8dTMyPicsICdpMzInXTtcbiAgICBjYXNlIERhdGFUeXBlLnVpbnQ2NDpcbiAgICAgIGlmIChjb21wb25lbnRzID4gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2N1cnJlbnRseSBub3Qgc3VwcG9ydGVkIHZlY1ggb2YgdWludDY0IHlldCcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFsndmVjMjx1MzI+JywgJ3UzMiddO1xuICAgIGNhc2UgRGF0YVR5cGUuYm9vbDpcbiAgICAgIGlmIChjb21wb25lbnRzICE9PSA0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYm9vbCBtdXN0IGJlIHZlYzQnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBbJ3UzMicsICd2ZWM0PGJvb2w+J107XG4gICAgY2FzZSBEYXRhVHlwZS5pbnQ0OlxuICAgICAgcmV0dXJuICdpMzInO1xuICAgIGNhc2UgRGF0YVR5cGUudWludDQ6XG4gICAgICByZXR1cm4gJ3UzMic7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBkYXRhIHR5cGU6ICR7dHlwZX1gKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZSA9ICh0eXBlOiBEYXRhVHlwZSwgY29tcG9uZW50czogMSB8IDIgfCAzIHwgNCA9IDEpID0+IHtcbiAgY29uc3QgbWFwcGVkVHlwZSA9IGdldFdnc2xNYXBwZWRUeXBlKHR5cGUsIGNvbXBvbmVudHMpO1xuICByZXR1cm4gdHlwZW9mIG1hcHBlZFR5cGUgPT09ICdzdHJpbmcnID8gbWFwcGVkVHlwZSA6IG1hcHBlZFR5cGVbMF07XG59O1xuXG5leHBvcnQgY29uc3QgdGVuc29yVHlwZVRvV3NnbFZhbHVlVHlwZSA9ICh0eXBlOiBEYXRhVHlwZSwgY29tcG9uZW50czogMSB8IDIgfCAzIHwgNCA9IDEpID0+IHtcbiAgY29uc3QgbWFwcGVkVHlwZSA9IGdldFdnc2xNYXBwZWRUeXBlKHR5cGUsIGNvbXBvbmVudHMpO1xuICByZXR1cm4gdHlwZW9mIG1hcHBlZFR5cGUgPT09ICdzdHJpbmcnID8gbWFwcGVkVHlwZSA6IG1hcHBlZFR5cGVbMV07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMgPSAoLi4uZGltczogUmVhZG9ubHlBcnJheTxyZWFkb25seSBudW1iZXJbXT4pOiBQcm9ncmFtVW5pZm9ybVtdID0+IHtcbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW107XG4gIGRpbXMuZm9yRWFjaCgoZGltKSA9PiB7XG4gICAgaWYgKGRpbS5sZW5ndGggIT09IDApIHtcbiAgICAgIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKFxuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogZGltIH0sXG4gICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoZGltKSB9LFxuICAgICAgKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcHJvZ3JhbVVuaWZvcm1zO1xufTtcblxuLyoqXG4gKiBBIGhlbHBlciBmdW5jdGlvbiB0byBnZXQgbWF4aW11bSB2ZWN0b3Igc2l6ZSBmb3Igc3BlY2lmaWVkIGRhdGEgbGVuZ3RoXG4gKiBAcGFyYW0gc2l6ZVxuICovXG5leHBvcnQgY29uc3QgZ2V0TWF4Q29tcG9uZW50cyA9IChzaXplOiBudW1iZXIpID0+IHtcbiAgLy8gd2UgY2Fubm90IHVzZSB2ZWMzIHR5cGUgc2luY2UgaXQgaGFzIGFsaWdubWVudCBvZiAxNiBieXRlc1xuICBpZiAoc2l6ZSAlIDQgPT09IDApIHtcbiAgICByZXR1cm4gNDtcbiAgfSBlbHNlIGlmIChzaXplICUgMiA9PT0gMCkge1xuICAgIHJldHVybiAyO1xuICB9XG5cbiAgcmV0dXJuIDE7XG59O1xuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRoYXQgaW5pdGlhbGl6ZXMgdmFyaWFibGUgYXMgYSBzY2FsYXIgb3IgdmVjdG9yLiBlLmcuIGYzMigwKSBvciB2ZWM0ZigwLDAsMCwwKVxuICogQHBhcmFtIGRhdGFUeXBlXG4gKiBAcGFyYW0gY29tcG9uZW50c1xuICogQHBhcmFtIHZhbHVlXG4gKi9cbmV4cG9ydCBjb25zdCBmaWxsVmVjdG9yID0gKGRhdGFUeXBlID0gJ2YzMicsIGNvbXBvbmVudHM/OiBudW1iZXIsIHZhbHVlID0gJzAnKSA9PiB7XG4gIGlmICghY29tcG9uZW50cyB8fCBjb21wb25lbnRzID09PSAxKSB7XG4gICAgcmV0dXJuIGAke2RhdGFUeXBlfSgke3ZhbHVlfSlgO1xuICB9XG5cbiAgcmV0dXJuIGB2ZWMke2NvbXBvbmVudHN9PCR7ZGF0YVR5cGV9Pigke3ZhbHVlfSlgO1xufTtcblxuLyoqXG4gKiBBIGhlbHBlciBmdW5jdGlvbiB0aGF0IGNhc3RzIHZhbHVlIG9yIHZlY3RvciB0byBmMzJcbiAqIEBwYXJhbSBkYXRhVHlwZVxuICogQHBhcmFtIGNvbXBvbmVudHNcbiAqIEBwYXJhbSB2YWx1ZVxuICovXG5leHBvcnQgY29uc3QgY2FzdFRvRjMyID0gKGRhdGFUeXBlOiBzdHJpbmcsIGNvbXBvbmVudHM6IG51bWJlciwgdmFsdWU6IHN0cmluZykgPT4ge1xuICBpZiAoZGF0YVR5cGUgPT09ICdmMzInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmIChjb21wb25lbnRzID09PSAxKSB7XG4gICAgcmV0dXJuIGBmMzIoJHt2YWx1ZX0pYDtcbiAgfVxuXG4gIHJldHVybiBgdmVjJHtjb21wb25lbnRzfTxmMzI+KCR7dmFsdWV9KWA7XG59O1xuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBzY2FsYXIgb3Igc3VtcyBhbGwgY29tcG9uZW50cyBvZiBhIHZlY3RvclxuICogQHBhcmFtIG5hbWVcbiAqIEBwYXJhbSBjb21wb25lbnRzXG4gKi9cbmV4cG9ydCBjb25zdCBzdW1WZWN0b3IgPSAobmFtZTogc3RyaW5nLCBjb21wb25lbnRzOiBudW1iZXIpID0+IHtcbiAgaWYgKGNvbXBvbmVudHMgPT09IDQpIHtcbiAgICByZXR1cm4gYCgke25hbWV9LnggKyAke25hbWV9LnkgKyAke25hbWV9LnogKyAke25hbWV9LncpYDtcbiAgfSBlbHNlIGlmIChjb21wb25lbnRzID09PSAyKSB7XG4gICAgcmV0dXJuIGAoJHtuYW1lfS54ICsgJHtuYW1lfS55KWA7XG4gIH0gZWxzZSBpZiAoY29tcG9uZW50cyA9PT0gMykge1xuICAgIHJldHVybiBgKCR7bmFtZX0ueCArICR7bmFtZX0ueSArICR7bmFtZX0ueilgO1xuICB9XG5cbiAgcmV0dXJuIG5hbWU7XG59O1xuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB2YXJpYWJsZSBlbGVtZW50IGF0IGluZGV4LlxuICogQHBhcmFtIG5hbWUgLSB0aGUgbmFtZSBvZiB2YXJpYWJsZS5cbiAqIEBwYXJhbSBpbmRleCAtIHRoZSBpbmRleCBvZiB2YXJpYWJsZSBlbGVtZW50LlxuICogQHBhcmFtIGxlbmd0aCAtIHRoZSBsZW5ndGggb2YgdmFyaWFibGUuXG4gKiBAcGFyYW0gdHlwZSAtIHRoZSB0eXBlIG9mIHZhcmlhYmxlLCBvcHRpb25hbC5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldEVsZW1lbnRBdCA9IChcbiAgbmFtZTogc3RyaW5nLFxuICBpbmRleDogbnVtYmVyIHwgc3RyaW5nLFxuICBsZW5ndGg6IG51bWJlcixcbiAgdHlwZT86IFVuaWZvcm1EYXRhRWxlbWVudFR5cGUsXG4pOiBzdHJpbmcgPT4ge1xuICBpZiAobmFtZS5zdGFydHNXaXRoKCd1bmlmb3Jtcy4nKSAmJiBsZW5ndGggPiA0KSB7XG4gICAgaWYgKHR5cGVvZiBpbmRleCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmICh0eXBlID09PSAnZjE2Jykge1xuICAgICAgICByZXR1cm4gYCR7bmFtZX1bKCR7aW5kZXh9KSAvIDhdWygke2luZGV4fSkgJSA4IC8gNF1bKCR7aW5kZXh9KSAlIDggJSA0XWA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gYCR7bmFtZX1bKCR7aW5kZXh9KSAvIDRdWygke2luZGV4fSkgJSA0XWA7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlID09PSAnZjE2Jykge1xuICAgICAgICByZXR1cm4gYCR7bmFtZX1bJHtNYXRoLmZsb29yKGluZGV4IC8gOCl9XVske01hdGguZmxvb3IoKGluZGV4ICUgOCkgLyA0KX1dWyR7KGluZGV4ICUgOCkgJSA0fV1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGAke25hbWV9WyR7TWF0aC5mbG9vcihpbmRleCAvIDQpfV1bJHtpbmRleCAlIDR9XWA7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBsZW5ndGggPiAxID8gYCR7bmFtZX1bJHtpbmRleH1dYCA6IG5hbWU7XG4gIH1cbn07XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IGEgSW5kaWNlc0hlbHBlciBmb3IgYSBnaXZlbiBpbnB1dCBvciBvdXRwdXQuXG4gKlxuICogQHBhcmFtIG5hbWUgLSB0aGUgbmFtZSBvZiB0aGUgaW5wdXQgb3Igb3V0cHV0LlxuICogQHBhcmFtIHRlbnNvclR5cGUgLSB0aGUgdGVuc29yIHR5cGUgb2YgdGhlIGlucHV0IG9yIG91dHB1dC5cbiAqIEBwYXJhbSBzaGFwZU9yUmFuayAtIHRoZSB0ZW5zb3Igc2hhcGUgb3IgdGhlIHJhbmsgb2YgdGhlIGlucHV0IG9yIG91dHB1dC5cbiAqIEBwYXJhbSB1c2FnZSAtIHRoZSB1c2FnZSBvZiB0aGUgaW5kaWNlcyBoZWxwZXIuXG4gKiBAcGFyYW0gY29tcG9uZW50cyAtIGluZGljYXRlcyB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgb2YgZWFjaCBlbGVtZW50LiAxIGZvciBzY2FsYXIsIDIgZm9yIHZlYzIsIDMgZm9yIHZlYzMsIDQgZm9yXG4gKiAgICB2ZWM0LlxuICovXG5jb25zdCBjcmVhdGVJbmRpY2VzSGVscGVyID0gKFxuICBuYW1lOiBzdHJpbmcsXG4gIHRlbnNvclR5cGU6IG51bWJlcixcbiAgc2hhcGVPclJhbms6IG51bWJlciB8IHJlYWRvbmx5IG51bWJlcltdLFxuICB1c2FnZTogSW5kaWNlc0hlbHBlclsndXNhZ2UnXSxcbiAgY29tcG9uZW50czogMSB8IDIgfCAzIHwgNCxcbik6IEluZGljZXNIZWxwZXIgPT4ge1xuICBjb25zdCB1c2VVbmlmb3JtID0gdHlwZW9mIHNoYXBlT3JSYW5rID09PSAnbnVtYmVyJztcbiAgY29uc3QgcmFuayA9IHVzZVVuaWZvcm0gPyBzaGFwZU9yUmFuayA6IHNoYXBlT3JSYW5rLmxlbmd0aDtcbiAgY29uc3QgcmFua0lkZW50aXR5ID0gWy4uLm5ldyBBcnJheShyYW5rKS5rZXlzKCldO1xuICBjb25zdCBpbmRpY2VzVHlwZSA9IHJhbmsgPCAyID8gJ3UzMicgOiByYW5rIDw9IDQgPyBgdmVjJHtyYW5rfTx1MzI+YCA6IGBhcnJheTx1MzIsICR7cmFua30+YDtcbiAgY29uc3QgbWFwcGVkVHlwZSA9IGdldFdnc2xNYXBwZWRUeXBlKHRlbnNvclR5cGUsIGNvbXBvbmVudHMpO1xuICBjb25zdCB2YWx1ZVR5cGUgPSB0eXBlb2YgbWFwcGVkVHlwZSA9PT0gJ3N0cmluZycgPyBtYXBwZWRUeXBlIDogbWFwcGVkVHlwZVsxXTtcbiAgY29uc3Qgc3RvcmFnZVR5cGUgPSB0eXBlb2YgbWFwcGVkVHlwZSA9PT0gJ3N0cmluZycgPyBtYXBwZWRUeXBlIDogbWFwcGVkVHlwZVswXTtcbiAgY29uc3QgdHlwZSA9IHsgaW5kaWNlczogaW5kaWNlc1R5cGUsIHZhbHVlOiB2YWx1ZVR5cGUsIHN0b3JhZ2U6IHN0b3JhZ2VUeXBlLCB0ZW5zb3I6IHRlbnNvclR5cGUgfTtcblxuICBjb25zdCBub3JtYWxpemVEaW0gPSAoZGltOiBudW1iZXIgfCBzdHJpbmcpOiBzdHJpbmcgPT4gKHR5cGVvZiBkaW0gPT09ICdzdHJpbmcnID8gZGltIDogYCR7ZGltfXVgKTtcblxuICBjb25zdCBpbXBsZW1lbnRhdGlvblVzZWQgPSB7XG4gICAgb2Zmc2V0VG9JbmRpY2VzOiBmYWxzZSxcbiAgICBpbmRpY2VzVG9PZmZzZXQ6IGZhbHNlLFxuICAgIGJyb2FkY2FzdGVkSW5kaWNlc1RvT2Zmc2V0OiBmYWxzZSxcbiAgICBzZXQ6IGZhbHNlLFxuICAgIHNldEJ5SW5kaWNlczogZmFsc2UsXG4gICAgZ2V0OiBmYWxzZSxcbiAgICBnZXRCeUluZGljZXM6IGZhbHNlLFxuICB9O1xuXG4gIGNvbnN0IHVuaWZvcm1QcmVmaXggPSB1c2VVbmlmb3JtID8gJ3VuaWZvcm1zLicgOiAnJztcbiAgY29uc3Qgc2hhcGUgPSBgJHt1bmlmb3JtUHJlZml4fSR7bmFtZX1fc2hhcGVgO1xuICBjb25zdCBzdHJpZGVzID0gYCR7dW5pZm9ybVByZWZpeH0ke25hbWV9X3N0cmlkZXNgO1xuXG4gIGxldCBvMmlTbmlwcGV0ID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDE7IGkrKykge1xuICAgIG8yaVNuaXBwZXQgKz0gYFxuICAgIGxldCBkaW0ke2l9ID0gY3VycmVudCAvICR7Z2V0RWxlbWVudEF0KHN0cmlkZXMsIGksIHJhbmspfTtcbiAgICBsZXQgcmVzdCR7aX0gPSBjdXJyZW50ICUgJHtnZXRFbGVtZW50QXQoc3RyaWRlcywgaSwgcmFuayl9O1xuICAgIGluZGljZXNbJHtpfV0gPSBkaW0ke2l9O1xuICAgIGN1cnJlbnQgPSByZXN0JHtpfTtcbiAgICBgO1xuICB9XG4gIG8yaVNuaXBwZXQgKz0gYGluZGljZXNbJHtyYW5rIC0gMX1dID0gY3VycmVudDtgO1xuXG4gIGNvbnN0IG9mZnNldFRvSW5kaWNlc0ltcGxlbWVudGF0aW9uID1cbiAgICByYW5rIDwgMlxuICAgICAgPyAnJ1xuICAgICAgOiBgXG4gIGZuIG8yaV8ke25hbWV9KG9mZnNldDogdTMyKSAtPiAke3R5cGUuaW5kaWNlc30ge1xuICAgIHZhciBpbmRpY2VzOiAke3R5cGUuaW5kaWNlc307XG4gICAgdmFyIGN1cnJlbnQgPSBvZmZzZXQ7XG4gICAgJHtvMmlTbmlwcGV0fVxuICAgIHJldHVybiBpbmRpY2VzO1xuICB9YDtcblxuICBjb25zdCBvZmZzZXRUb0luZGljZXMgPSAodmFyT2Zmc2V0OiBzdHJpbmcpID0+IHtcbiAgICBpbXBsZW1lbnRhdGlvblVzZWQub2Zmc2V0VG9JbmRpY2VzID0gdHJ1ZTtcbiAgICByZXR1cm4gcmFuayA8IDIgPyB2YXJPZmZzZXQgOiBgbzJpXyR7bmFtZX0oJHt2YXJPZmZzZXR9KWA7XG4gIH07XG5cbiAgY29uc3Qgb2Zmc2V0czogc3RyaW5nW10gPSBbXTtcbiAgaWYgKHJhbmsgPj0gMikge1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIG9mZnNldHMucHVzaChgJHtnZXRFbGVtZW50QXQoc3RyaWRlcywgaSwgcmFuayl9ICogKGluZGljZXNbJHtpfV0pYCk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgaW5kaWNlc1RvT2Zmc2V0SW1wbGVtZW50YXRpb24gPVxuICAgIHJhbmsgPCAyXG4gICAgICA/ICcnXG4gICAgICA6IGBcbiAgZm4gaTJvXyR7bmFtZX0oaW5kaWNlczogJHt0eXBlLmluZGljZXN9KSAtPiB1MzIge1xuICAgIHJldHVybiAke29mZnNldHMuam9pbignKycpfTtcbiAgfWA7XG5cbiAgY29uc3QgaW5kaWNlc1RvT2Zmc2V0ID0gKHZhckluZGljZXM6IHN0cmluZykgPT4ge1xuICAgIGltcGxlbWVudGF0aW9uVXNlZC5pbmRpY2VzVG9PZmZzZXQgPSB0cnVlO1xuICAgIHJldHVybiByYW5rIDwgMiA/IHZhckluZGljZXMgOiBgaTJvXyR7bmFtZX0oJHt2YXJJbmRpY2VzfSlgO1xuICB9O1xuXG4gIGNvbnN0IGluZGljZXMgPSAoLi4uaW5pdDogUmVhZG9ubHlBcnJheTxudW1iZXIgfCBzdHJpbmc+KSA9PlxuICAgIHJhbmsgPT09IDAgPyAnMHUnIDogYCR7dHlwZS5pbmRpY2VzfSgke2luaXQubWFwKG5vcm1hbGl6ZURpbSkuam9pbignLCcpfSlgO1xuXG4gIGNvbnN0IGluZGljZXNHZXQgPSAodmFySW5kaWNlczogc3RyaW5nLCBpZHg6IG51bWJlciB8IHN0cmluZykgPT4ge1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgcmV0dXJuIGAke3ZhckluZGljZXN9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGAke2dldEVsZW1lbnRBdCh2YXJJbmRpY2VzLCBpZHgsIHJhbmspfWA7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGluZGljZXNTZXQgPSAodmFySW5kaWNlczogc3RyaW5nLCBpZHg6IG51bWJlciB8IHN0cmluZywgdmFsdWU6IHN0cmluZykgPT4ge1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgcmV0dXJuIGAke3ZhckluZGljZXN9PSR7dmFsdWV9O2A7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBgJHtnZXRFbGVtZW50QXQodmFySW5kaWNlcywgaWR4LCByYW5rKX09JHt2YWx1ZX07YDtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXRJbXBsZW1lbnRhdGlvbjogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICBjb25zdCBicm9hZGNhc3RlZEluZGljZXNUb09mZnNldCA9ICh2YXJJbmRpY2VzOiBzdHJpbmcsIG91dHB1dDogSW5kaWNlc0hlbHBlcikgPT4ge1xuICAgIGltcGxlbWVudGF0aW9uVXNlZC5icm9hZGNhc3RlZEluZGljZXNUb09mZnNldCA9IHRydWU7XG4gICAgY29uc3QgaW1wbEtleSA9IGAke291dHB1dC5uYW1lfWJyb2FkY2FzdGVkSW5kaWNlc1RvJHtuYW1lfU9mZnNldGA7XG4gICAgaWYgKGltcGxLZXkgaW4gYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXRJbXBsZW1lbnRhdGlvbikge1xuICAgICAgcmV0dXJuIGAke2ltcGxLZXl9KCR7dmFySW5kaWNlc30pYDtcbiAgICB9XG4gICAgY29uc3Qgb2Zmc2V0cyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IGlkeCA9IG91dHB1dC5pbmRpY2VzR2V0KCdvdXRwdXRJbmRpY2VzJywgaSArIG91dHB1dC5yYW5rIC0gcmFuayk7XG4gICAgICBvZmZzZXRzLnB1c2goYCR7aW5kaWNlc0dldChzdHJpZGVzLCBpKX0gKiAoJHtpZHh9ICUgJHtpbmRpY2VzR2V0KHNoYXBlLCBpKX0pYCk7XG4gICAgfVxuICAgIGJyb2FkY2FzdGVkSW5kaWNlc1RvT2Zmc2V0SW1wbGVtZW50YXRpb25baW1wbEtleV0gPSBgZm4gJHtpbXBsS2V5fShvdXRwdXRJbmRpY2VzOiAke291dHB1dC50eXBlLmluZGljZXN9KSAtPiB1MzIge1xuICAgICAgICAgICAgIHJldHVybiAke29mZnNldHMubGVuZ3RoID4gMCA/IG9mZnNldHMuam9pbignKycpIDogJzB1J307XG4gICAgICAgICAgIH1gO1xuXG4gICAgcmV0dXJuIGAke2ltcGxLZXl9KCR7dmFySW5kaWNlc30pYDtcbiAgfTtcblxuICBjb25zdCBzZXRCeU9mZnNldCA9IChvZmZzZXQ6IG51bWJlciB8IHN0cmluZywgdmFsdWU6IHN0cmluZykgPT5cbiAgICAoKCkgPT4ge1xuICAgICAgaWYgKHR5cGUuc3RvcmFnZSA9PT0gdHlwZS52YWx1ZSkge1xuICAgICAgICByZXR1cm4gYCR7bmFtZX1bJHtvZmZzZXR9XT0ke3ZhbHVlfTtgO1xuICAgICAgfSBlbHNlIGlmICh0eXBlLnN0b3JhZ2UgPT09ICd2ZWMyPHUzMj4nICYmIHR5cGUudmFsdWUgPT09ICdpMzInKSB7XG4gICAgICAgIC8vIGludDY0LCBjb21wb25lbnRzID09PSAxXG4gICAgICAgIHJldHVybiBgJHtuYW1lfVske29mZnNldH1dPXZlYzI8dTMyPih1MzIoJHt2YWx1ZX0pLCBzZWxlY3QoMHUsIDB4RkZGRkZGRkZ1LCAke3ZhbHVlfSA8IDApKTtgO1xuICAgICAgfSBlbHNlIGlmICh0eXBlLnN0b3JhZ2UgPT09ICd2ZWMyPHUzMj4nICYmIHR5cGUudmFsdWUgPT09ICd1MzInKSB7XG4gICAgICAgIC8vIHVpbnQ2NCwgY29tcG9uZW50cyA9PT0gMVxuICAgICAgICByZXR1cm4gYCR7bmFtZX1bJHtvZmZzZXR9XT12ZWMyPHUzMj4odTMyKCR7dmFsdWV9KSwgMHUpO2A7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUuc3RvcmFnZSA9PT0gJ3UzMicgJiYgdHlwZS52YWx1ZSA9PT0gJ3ZlYzQ8Ym9vbD4nKSB7XG4gICAgICAgIC8vIGJvb2wsIGNvbXBvbmVudHMgPT09IDRcbiAgICAgICAgcmV0dXJuIGAke25hbWV9WyR7b2Zmc2V0fV09ZG90KHZlYzQ8dTMyPigweDEsIDB4MTAwLCAweDEwMDAwLCAweDEwMDAwMDApLCB2ZWM0PHUzMj4oJHt2YWx1ZX0pKTtgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBub3Qgc3VwcG9ydGVkIGNvbWJpbmF0aW9uIG9mIHN0b3JhZ2UgdHlwZSAke3R5cGUuc3RvcmFnZX0gYW5kIHZhbHVlIHR5cGUgJHt0eXBlLnZhbHVlfSB5ZXRgKTtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gIGNvbnN0IGdldEJ5T2Zmc2V0ID0gKG9mZnNldDogbnVtYmVyIHwgc3RyaW5nKSA9PlxuICAgICgoKSA9PiB7XG4gICAgICBpZiAodHlwZS5zdG9yYWdlID09PSB0eXBlLnZhbHVlKSB7XG4gICAgICAgIHJldHVybiBgJHtuYW1lfVske29mZnNldH1dYDtcbiAgICAgIH0gZWxzZSBpZiAodHlwZS5zdG9yYWdlID09PSAndmVjMjx1MzI+JyAmJiB0eXBlLnZhbHVlID09PSAnaTMyJykge1xuICAgICAgICAvLyBpbnQ2NCwgY29tcG9uZW50cyA9PT0gMVxuICAgICAgICByZXR1cm4gYGkzMigke25hbWV9WyR7b2Zmc2V0fV0ueClgO1xuICAgICAgfSBlbHNlIGlmICh0eXBlLnN0b3JhZ2UgPT09ICd2ZWMyPHUzMj4nICYmIHR5cGUudmFsdWUgPT09ICd1MzInKSB7XG4gICAgICAgIC8vIHVpbnQ2NCwgY29tcG9uZW50cyA9PT0gMVxuICAgICAgICByZXR1cm4gYHUzMigke25hbWV9WyR7b2Zmc2V0fV0ueClgO1xuICAgICAgfSBlbHNlIGlmICh0eXBlLnN0b3JhZ2UgPT09ICd1MzInICYmIHR5cGUudmFsdWUgPT09ICd2ZWM0PGJvb2w+Jykge1xuICAgICAgICAvLyBib29sLCBjb21wb25lbnRzID09PSA0XG4gICAgICAgIHJldHVybiBgdmVjNDxib29sPihib29sKCR7bmFtZX1bJHtvZmZzZXR9XSAmIDB4RkZ1KSwgYm9vbCgke25hbWV9WyR7b2Zmc2V0fV0gJiAweEZGMDB1KSwgYm9vbCgke25hbWV9WyR7XG4gICAgICAgICAgb2Zmc2V0XG4gICAgICAgIH1dICYgMHhGRjAwMDB1KSwgYm9vbCgke25hbWV9WyR7b2Zmc2V0fV0gJiAweEZGMDAwMDAwdSkpYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbm90IHN1cHBvcnRlZCBjb21iaW5hdGlvbiBvZiBzdG9yYWdlIHR5cGUgJHt0eXBlLnN0b3JhZ2V9IGFuZCB2YWx1ZSB0eXBlICR7dHlwZS52YWx1ZX0geWV0YCk7XG4gICAgICB9XG4gICAgfSkoKTtcblxuICBjb25zdCBnZXRCeUluZGljZXNJbXBsZW1lbnRhdGlvbiA9XG4gICAgcmFuayA8IDJcbiAgICAgID8gJydcbiAgICAgIDogYFxuICBmbiBnZXRfJHtuYW1lfUJ5SW5kaWNlcyhpbmRpY2VzOiAke3R5cGUuaW5kaWNlc30pIC0+ICR7dmFsdWVUeXBlfSB7XG4gICAgcmV0dXJuICR7Z2V0QnlPZmZzZXQoYGkyb18ke25hbWV9KGluZGljZXMpYCl9O1xuICB9YDtcblxuICBjb25zdCBnZXRJbXBsZW1lbnRhdGlvbiA9XG4gICAgcmFuayA8IDJcbiAgICAgID8gJydcbiAgICAgIDogKCgpID0+IHtcbiAgICAgICAgICBjb25zdCBmdW5jdGlvblBhcmFtcyA9IHJhbmtJZGVudGl0eS5tYXAoKGkpID0+IGBkJHtpfTogdTMyYCkuam9pbignLCAnKTtcbiAgICAgICAgICBjb25zdCBkaW1zUGFyYW1zID0gcmFua0lkZW50aXR5Lm1hcCgoaSkgPT4gYGQke2l9YCkuam9pbignLCAnKTtcbiAgICAgICAgICByZXR1cm4gYFxuICBmbiBnZXRfJHtuYW1lfSgke2Z1bmN0aW9uUGFyYW1zfSkgLT4gJHt2YWx1ZVR5cGV9IHtcbiAgICByZXR1cm4gZ2V0XyR7bmFtZX1CeUluZGljZXMoJHtpbmRpY2VzKGRpbXNQYXJhbXMpfSk7XG4gIH1gO1xuICAgICAgICB9KSgpO1xuXG4gIGNvbnN0IGdldCA9ICguLi5pbmRpY2VzOiBSZWFkb25seUFycmF5PG51bWJlciB8IHN0cmluZz4pID0+IHtcbiAgICBpZiAoaW5kaWNlcy5sZW5ndGggIT09IHJhbmspIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5kaWNlcyBsZW5ndGggbXVzdCBiZSAke3Jhbmt9YCk7XG4gICAgfVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZEluZGljZXMgPSBpbmRpY2VzLm1hcChub3JtYWxpemVEaW0pLmpvaW4oJywnKTtcblxuICAgIGlmIChyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gZ2V0QnlPZmZzZXQoJzB1Jyk7XG4gICAgfSBlbHNlIGlmIChyYW5rID09PSAxKSB7XG4gICAgICByZXR1cm4gZ2V0QnlPZmZzZXQobm9ybWFsaXplZEluZGljZXNbMF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbXBsZW1lbnRhdGlvblVzZWQuZ2V0ID0gdHJ1ZTtcbiAgICAgIGltcGxlbWVudGF0aW9uVXNlZC5nZXRCeUluZGljZXMgPSB0cnVlO1xuICAgICAgaW1wbGVtZW50YXRpb25Vc2VkLmluZGljZXNUb09mZnNldCA9IHRydWU7XG4gICAgICByZXR1cm4gYGdldF8ke25hbWV9KCR7bm9ybWFsaXplZEluZGljZXN9KWA7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGdldEJ5SW5kaWNlcyA9ICh2YXJJbmRpY2VzOiBzdHJpbmcpID0+IHtcbiAgICBpZiAocmFuayA8IDIpIHtcbiAgICAgIHJldHVybiBnZXRCeU9mZnNldCh2YXJJbmRpY2VzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW1wbGVtZW50YXRpb25Vc2VkLmdldEJ5SW5kaWNlcyA9IHRydWU7XG4gICAgICBpbXBsZW1lbnRhdGlvblVzZWQuaW5kaWNlc1RvT2Zmc2V0ID0gdHJ1ZTtcbiAgICAgIHJldHVybiBgZ2V0XyR7bmFtZX1CeUluZGljZXMoJHt2YXJJbmRpY2VzfSlgO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBzZXRCeUluZGljZXNJbXBsZW1lbnRhdGlvbiA9XG4gICAgcmFuayA8IDJcbiAgICAgID8gJydcbiAgICAgIDogYFxuICBmbiBzZXRfJHtuYW1lfUJ5SW5kaWNlcyhpbmRpY2VzOiAke3R5cGUuaW5kaWNlc30sIHZhbHVlOiAke3ZhbHVlVHlwZX0pIHtcbiAgICAke3NldEJ5T2Zmc2V0KGBpMm9fJHtuYW1lfShpbmRpY2VzKWAsICd2YWx1ZScpfVxuICB9YDtcblxuICBjb25zdCBzZXRJbXBsZW1lbnRhdGlvbiA9XG4gICAgcmFuayA8IDJcbiAgICAgID8gJydcbiAgICAgIDogKCgpID0+IHtcbiAgICAgICAgICBjb25zdCBmdW5jdGlvblBhcmFtcyA9IHJhbmtJZGVudGl0eS5tYXAoKGkpID0+IGBkJHtpfTogdTMyYCkuam9pbignLCAnKTtcbiAgICAgICAgICBjb25zdCBkaW1zUGFyYW1zID0gcmFua0lkZW50aXR5Lm1hcCgoaSkgPT4gYGQke2l9YCkuam9pbignLCAnKTtcbiAgICAgICAgICByZXR1cm4gYFxuICBmbiBzZXRfJHtuYW1lfSgke2Z1bmN0aW9uUGFyYW1zfSwgdmFsdWU6ICR7dmFsdWVUeXBlfSkge1xuICAgIHNldF8ke25hbWV9QnlJbmRpY2VzKCR7aW5kaWNlcyhkaW1zUGFyYW1zKX0sIHZhbHVlKTtcbiAgfWA7XG4gICAgICAgIH0pKCk7XG5cbiAgY29uc3Qgc2V0ID0gKC4uLmluZGljZXNBbmRWYWx1ZTogUmVhZG9ubHlBcnJheTxudW1iZXIgfCBzdHJpbmc+KSA9PiB7XG4gICAgaWYgKGluZGljZXNBbmRWYWx1ZS5sZW5ndGggIT09IHJhbmsgKyAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGluZGljZXMgbGVuZ3RoIG11c3QgYmUgJHtyYW5rfWApO1xuICAgIH1cbiAgICBjb25zdCB2YWx1ZSA9IGluZGljZXNBbmRWYWx1ZVtyYW5rXTtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd2YWx1ZSBtdXN0IGJlIHN0cmluZycpO1xuICAgIH1cblxuICAgIGNvbnN0IG5vcm1hbGl6ZWRJbmRpY2VzID0gaW5kaWNlc0FuZFZhbHVlLnNsaWNlKDAsIHJhbmspLm1hcChub3JtYWxpemVEaW0pLmpvaW4oJywnKTtcblxuICAgIGlmIChyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gc2V0QnlPZmZzZXQoJzB1JywgdmFsdWUpO1xuICAgIH0gZWxzZSBpZiAocmFuayA9PT0gMSkge1xuICAgICAgcmV0dXJuIHNldEJ5T2Zmc2V0KG5vcm1hbGl6ZWRJbmRpY2VzWzBdLCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGltcGxlbWVudGF0aW9uVXNlZC5zZXQgPSB0cnVlO1xuICAgICAgaW1wbGVtZW50YXRpb25Vc2VkLnNldEJ5SW5kaWNlcyA9IHRydWU7XG4gICAgICBpbXBsZW1lbnRhdGlvblVzZWQuaW5kaWNlc1RvT2Zmc2V0ID0gdHJ1ZTtcbiAgICAgIHJldHVybiBgc2V0XyR7bmFtZX0oJHtub3JtYWxpemVkSW5kaWNlc30sICR7dmFsdWV9KWA7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHNldEJ5SW5kaWNlcyA9ICh2YXJJbmRpY2VzOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICBpZiAocmFuayA8IDIpIHtcbiAgICAgIHJldHVybiBzZXRCeU9mZnNldCh2YXJJbmRpY2VzLCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGltcGxlbWVudGF0aW9uVXNlZC5zZXRCeUluZGljZXMgPSB0cnVlO1xuICAgICAgaW1wbGVtZW50YXRpb25Vc2VkLmluZGljZXNUb09mZnNldCA9IHRydWU7XG4gICAgICByZXR1cm4gYHNldF8ke25hbWV9QnlJbmRpY2VzKCR7dmFySW5kaWNlc30sICR7dmFsdWV9KTtgO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBpbXBsID0gKCkgPT4ge1xuICAgIGNvbnN0IGltcGxzID0gW107XG4gICAgbGV0IG5lZWRTaGFwZVN0cmlkZXMgPSBmYWxzZTtcbiAgICBpZiAoaW1wbGVtZW50YXRpb25Vc2VkLm9mZnNldFRvSW5kaWNlcykge1xuICAgICAgaW1wbHMucHVzaChvZmZzZXRUb0luZGljZXNJbXBsZW1lbnRhdGlvbik7XG4gICAgICBuZWVkU2hhcGVTdHJpZGVzID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGltcGxlbWVudGF0aW9uVXNlZC5pbmRpY2VzVG9PZmZzZXQpIHtcbiAgICAgIGltcGxzLnB1c2goaW5kaWNlc1RvT2Zmc2V0SW1wbGVtZW50YXRpb24pO1xuICAgICAgbmVlZFNoYXBlU3RyaWRlcyA9IHRydWU7XG4gICAgfVxuICAgIGlmIChpbXBsZW1lbnRhdGlvblVzZWQuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQpIHtcbiAgICAgIE9iamVjdC52YWx1ZXMoYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXRJbXBsZW1lbnRhdGlvbikuZm9yRWFjaCgoaW1wbCkgPT4gaW1wbHMucHVzaChpbXBsKSk7XG4gICAgICBuZWVkU2hhcGVTdHJpZGVzID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGltcGxlbWVudGF0aW9uVXNlZC5zZXQpIHtcbiAgICAgIGltcGxzLnB1c2goc2V0SW1wbGVtZW50YXRpb24pO1xuICAgICAgbmVlZFNoYXBlU3RyaWRlcyA9IHRydWU7XG4gICAgfVxuICAgIGlmIChpbXBsZW1lbnRhdGlvblVzZWQuc2V0QnlJbmRpY2VzKSB7XG4gICAgICBpbXBscy5wdXNoKHNldEJ5SW5kaWNlc0ltcGxlbWVudGF0aW9uKTtcbiAgICAgIG5lZWRTaGFwZVN0cmlkZXMgPSB0cnVlO1xuICAgIH1cbiAgICBpZiAoaW1wbGVtZW50YXRpb25Vc2VkLmdldCkge1xuICAgICAgaW1wbHMucHVzaChnZXRJbXBsZW1lbnRhdGlvbik7XG4gICAgICBuZWVkU2hhcGVTdHJpZGVzID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGltcGxlbWVudGF0aW9uVXNlZC5nZXRCeUluZGljZXMpIHtcbiAgICAgIGltcGxzLnB1c2goZ2V0QnlJbmRpY2VzSW1wbGVtZW50YXRpb24pO1xuICAgICAgbmVlZFNoYXBlU3RyaWRlcyA9IHRydWU7XG4gICAgfVxuICAgIGlmICghdXNlVW5pZm9ybSAmJiBuZWVkU2hhcGVTdHJpZGVzKSB7XG4gICAgICBpbXBscy51bnNoaWZ0KFxuICAgICAgICBgY29uc3QgJHtzaGFwZX0gPSAke3R5cGUuaW5kaWNlc30oJHtzaGFwZU9yUmFuay5qb2luKCcsJyl9KTtgLFxuICAgICAgICBgY29uc3QgJHtzdHJpZGVzfSA9ICR7dHlwZS5pbmRpY2VzfSgke1NoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhzaGFwZU9yUmFuaykuam9pbignLCcpfSk7YCxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBpbXBscy5qb2luKCdcXG4nKTtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIGltcGwsXG4gICAgdHlwZSxcbiAgICBvZmZzZXRUb0luZGljZXMsXG4gICAgaW5kaWNlc1RvT2Zmc2V0LFxuICAgIGJyb2FkY2FzdGVkSW5kaWNlc1RvT2Zmc2V0LFxuICAgIGluZGljZXMsXG4gICAgaW5kaWNlc0dldCxcbiAgICBpbmRpY2VzU2V0LFxuICAgIHNldCxcbiAgICBzZXRCeU9mZnNldCxcbiAgICBzZXRCeUluZGljZXMsXG4gICAgZ2V0LFxuICAgIGdldEJ5T2Zmc2V0LFxuICAgIGdldEJ5SW5kaWNlcyxcbiAgICAvLyBpc1ZlYzQsXG4gICAgdXNhZ2UsXG4gICAgbmFtZSxcbiAgICBzdHJpZGVzLFxuICAgIHNoYXBlLFxuICAgIHJhbmssXG4gIH07XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIEluZGljZXNIZWxwZXIgZm9yIGFuIGlucHV0LlxuICpcbiAqIEBwYXJhbSBuYW1lIC0gdGhlIG5hbWUgb2YgdGhlIGlucHV0LlxuICogQHBhcmFtIHR5cGUgLSB0aGUgdGVuc29yIHR5cGUgb2YgdGhlIGlucHV0LlxuICogQHBhcmFtIHNoYXBlT3JSYW5rIC0gdGhlIHRlbnNvciBzaGFwZSBvciB0aGUgcmFuayBvZiB0aGUgaW5wdXQuXG4gKiBAcGFyYW0gY29tcG9uZW50cyAtIHRoZSBudW1iZXIgb2YgY29tcG9uZW50cyBvZiB0aGUgaW5wdXQuIGF2YWlsYWJsZSB2YWx1ZXMgYXJlIDEsIDIsIDMsIDQuIGRlZmF1bHQgaXMgMS5cbiAqIEByZXR1cm5zIGFuIEluZGljZXNIZWxwZXIgZm9yIHRoZSBpbnB1dC5cbiAqL1xuZXhwb3J0IGNvbnN0IGlucHV0VmFyaWFibGUgPSAoXG4gIG5hbWU6IHN0cmluZyxcbiAgdHlwZTogbnVtYmVyLFxuICBzaGFwZU9yUmFuazogbnVtYmVyIHwgcmVhZG9ubHkgbnVtYmVyW10sXG4gIGNvbXBvbmVudHM6IDEgfCAyIHwgMyB8IDQgPSAxLFxuKTogSW5kaWNlc0hlbHBlciA9PiBjcmVhdGVJbmRpY2VzSGVscGVyKG5hbWUsIHR5cGUsIHNoYXBlT3JSYW5rLCAnaW5wdXQnLCBjb21wb25lbnRzKTtcblxuLyoqXG4gKiBDcmVhdGUgYSBJbmRpY2VzSGVscGVyIGZvciBhbiBvdXRwdXQuXG4gKlxuICogQHBhcmFtIG5hbWUgLSB0aGUgbmFtZSBvZiB0aGUgb3V0cHV0LlxuICogQHBhcmFtIHR5cGUgLSB0aGUgdGVuc29yIHR5cGUgb2YgdGhlIG91dHB1dC5cbiAqIEBwYXJhbSBzaGFwZU9yUmFuayAtIHRoZSB0ZW5zb3Igc2hhcGUgb3IgdGhlIHJhbmsgb2YgdGhlIG91dHB1dC5cbiAqIEBwYXJhbSBjb21wb25lbnRzIC0gdGhlIG51bWJlciBvZiBjb21wb25lbnRzIG9mIHRoZSBvdXRwdXQuIGF2YWlsYWJsZSB2YWx1ZXMgYXJlIDEsIDIsIDMsIDQuIGRlZmF1bHQgaXMgMS5cbiAqIEByZXR1cm5zIGFuIEluZGljZXNIZWxwZXIgZm9yIHRoZSBvdXRwdXQuXG4gKi9cbmV4cG9ydCBjb25zdCBvdXRwdXRWYXJpYWJsZSA9IChcbiAgbmFtZTogc3RyaW5nLFxuICB0eXBlOiBudW1iZXIsXG4gIHNoYXBlT3JSYW5rOiBudW1iZXIgfCByZWFkb25seSBudW1iZXJbXSxcbiAgY29tcG9uZW50czogMSB8IDIgfCAzIHwgNCA9IDEsXG4pOiBJbmRpY2VzSGVscGVyID0+IGNyZWF0ZUluZGljZXNIZWxwZXIobmFtZSwgdHlwZSwgc2hhcGVPclJhbmssICdvdXRwdXQnLCBjb21wb25lbnRzKTtcblxuLyoqXG4gKiBDcmVhdGUgYSBJbmRpY2VzSGVscGVyIGZvciBhbiBhdG9taWMgb3V0cHV0LlxuICpcbiAqIEBwYXJhbSBuYW1lIC0gdGhlIG5hbWUgb2YgdGhlIG91dHB1dC5cbiAqIEBwYXJhbSB0eXBlIC0gdGhlIHRlbnNvciB0eXBlIG9mIHRoZSBvdXRwdXQuXG4gKiBAcGFyYW0gc2hhcGVPclJhbmsgLSB0aGUgdGVuc29yIHNoYXBlIG9yIHRoZSByYW5rIG9mIHRoZSBvdXRwdXQuXG4gKiBAcmV0dXJucyBhbiBJbmRpY2VzSGVscGVyIGZvciB0aGUgb3V0cHV0LlxuICovXG5leHBvcnQgY29uc3QgYXRvbWljT3V0cHV0VmFyaWFibGUgPSAoXG4gIG5hbWU6IHN0cmluZyxcbiAgdHlwZTogbnVtYmVyLFxuICBzaGFwZU9yUmFuazogbnVtYmVyIHwgcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBJbmRpY2VzSGVscGVyID0+IGNyZWF0ZUluZGljZXNIZWxwZXIobmFtZSwgdHlwZSwgc2hhcGVPclJhbmssICdhdG9taWNPdXRwdXQnLCAxKTtcblxuLyoqXG4gKiBDcmVhdGUgYSBJbmRpY2VzSGVscGVyIGZvciBhbiBpbnRlcm5hbCB2YXJpYWJsZS5cbiAqXG4gKiBAcGFyYW0gbmFtZSAtIHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZS5cbiAqIEBwYXJhbSB0eXBlIC0gdGhlIHRlbnNvciB0eXBlIG9mIHRoZSB2YXJpYWJsZS5cbiAqIEBwYXJhbSBzaGFwZU9yUmFuayAtIHRoZSB0ZW5zb3Igc2hhcGUgb3IgdGhlIHJhbmsgb2YgdGhlIHZhcmlhYmxlLlxuICogQHBhcmFtIGNvbXBvbmVudHMgLSB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgb2YgdGhlIHZhcmlhYmxlLiBhdmFpbGFibGUgdmFsdWVzIGFyZSAxLCAyLCAzLCA0LiBkZWZhdWx0IGlzIDEuXG4gKiBAcmV0dXJucyBhbiBJbmRpY2VzSGVscGVyIGZvciB0aGUgdmFyaWFibGUuXG4gKi9cbmV4cG9ydCBjb25zdCBpbnRlcm5hbFZhcmlhYmxlID0gKFxuICBuYW1lOiBzdHJpbmcsXG4gIHR5cGU6IG51bWJlcixcbiAgc2hhcGVPclJhbms6IG51bWJlciB8IHJlYWRvbmx5IG51bWJlcltdLFxuICBjb21wb25lbnRzOiAxIHwgMiB8IDMgfCA0ID0gMSxcbik6IEluZGljZXNIZWxwZXIgPT4gY3JlYXRlSW5kaWNlc0hlbHBlcihuYW1lLCB0eXBlLCBzaGFwZU9yUmFuaywgJ2ludGVybmFsJywgY29tcG9uZW50cyk7XG5cbmV4cG9ydCB0eXBlIFVuaWZvcm1EYXRhRWxlbWVudFR5cGUgPSAndTMyJyB8ICdmMTYnIHwgJ2YzMicgfCAnaTMyJztcbmV4cG9ydCB0eXBlIFVuaWZvcm1zQXJyYXlUeXBlID0gQXJyYXk8eyBuYW1lOiBzdHJpbmc7IHR5cGU6IFVuaWZvcm1EYXRhRWxlbWVudFR5cGU7IGxlbmd0aD86IG51bWJlciB9PjtcblxuLyoqXG4gKiBBIFNoYWRlckhlbHBlciBpcyBhIGhlbHBlciBjbGFzcyBmb3IgZ2VuZXJhdGluZyBXR1NMIGNvZGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2hhZGVySGVscGVyIHtcbiAgLyoqXG4gICAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGdlbmVyYXRlIHRoZSBzdGFydCBvZiBtYWluIGZ1bmN0aW9uIGluIFdHU0wgc291cmNlIGNvZGUuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gYFxuICAgKiAgLi4uXG4gICAqXG4gICAqICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICogICAgLy8geW91ciBjb2RlIGhlcmUgaW5zaWRlIG1haW4oKSBmdW5jdGlvblxuICAgKiAgICAuLi5cbiAgICogIH1cbiAgICogYDtcbiAgICpcbiAgICogQHBhcmFtIHdvcmtncm91cFNpemUgLSBhbiBvcHRpb25hbCB3b3JrZ3JvdXAgc2l6ZS4gZGVmYXVsdCBpcyBXT1JLR1JPVVBfU0laRS5cbiAgICovXG4gIG1haW5TdGFydCh3b3JrZ3JvdXBTaXplPzogbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdKTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIGhlbHBlciBmdW5jdGlvbiB0byBnZW5lcmF0ZSB0aGUgY29kZSBzbmlwcGV0IGZvciBndWFyZGluZyBhZ2FpbnN0IG91dC1vZi1ib3VuZHMgc2l6ZS5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiBgXG4gICAqICAuLi5cbiAgICpcbiAgICogICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgKiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKG91dHB1dFNpemUpfVxuICAgKlxuICAgKiAgICAvLyB5b3VyIGNvZGUgaGVyZSBpbnNpZGUgbWFpbigpIGZ1bmN0aW9uXG4gICAqICAgIC4uLlxuICAgKiAgfVxuICAgKiBgO1xuICAgKlxuICAgKiBAcGFyYW0gc2l6ZSAtIHRoZSBzaXplIG9mIHRoZSBkYXRhIHRvIGd1YXJkIGFnYWluc3QuIGNhbiBiZSBhIG51bWJlciBvciBhIHN0cmluZyAoV0dTTCBgdTMyYCBleHByZXNzaW9uKS5cbiAgICovXG4gIGd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoc2l6ZTogdW5rbm93bik6IHN0cmluZztcblxuICAvKipcbiAgICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gZ2VuZXJhdGUgdGhlIGNvZGUgc25pcHBldCBmb3IgZGVjbGFyaW5nIG11bHRpcGxlIGlucHV0cyBvciBvdXRwdXRzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFyaWFibGVzIC0gYW4gYXJyYXkgb2YgSW5kaWNlc0hlbHBlciBmb3IgdGhlIHZhcmlhYmxlcy5cbiAgICovXG4gIGRlY2xhcmVWYXJpYWJsZXMoLi4udmFyaWFibGVzOiBJbmRpY2VzSGVscGVyW10pOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIHJlZ2lzdGVyIG9uZSB1bmlmb3JtLiBDYW4gYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzIHRvIHJlZ2lzdGVyIG11bHRpcGxlIHVuaWZvcm1zLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSAtIHRoZSBuYW1lIG9mIHRoZSB1bmlmb3JtLlxuICAgKiBAcGFyYW0gdHlwZSAtIHRoZSB0eXBlIG9mIHRoZSB1bmlmb3JtLlxuICAgKiBAcGFyYW0gbGVuZ3RoIC0gdGhlIGxlbmd0aCBvZiB0aGUgdW5pZm9ybSwgZGVmYXVsdCB0byAxIHdoZW4gaXQgaXMgbm90IHByb3ZpZGVkLlxuICAgKi9cbiAgcmVnaXN0ZXJVbmlmb3JtKG5hbWU6IHN0cmluZywgdHlwZTogc3RyaW5nLCBsZW5ndGg/OiBudW1iZXIpOiBTaGFkZXJIZWxwZXI7XG5cbiAgLyoqXG4gICAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIHJlZ2lzdGVyIG11bHRpcGxlIHVuaWZvcm1zLiBDYW4gYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzIHRvIHJlZ2lzdGVyIG11bHRpcGxlIHVuaWZvcm1zLlxuICAgKlxuICAgKiBAcGFyYW0gdW5pZm9ybXMgLSBhbiBhcnJheSBvZiB1bmlmb3Jtcy4gRWFjaCBlbGVtZW50IG9mIHRoZSBhcnJheSBpcyBhbiBvYmplY3Qgd2l0aCAyIHByb3BlcnRpZXM6IGBuYW1lYCBhbmRcbiAgICogICAgIGB0eXBlYC5cbiAgICovXG4gIHJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlKTogU2hhZGVySGVscGVyO1xuXG4gIC8qKlxuICAgKiBBIGhlbHBlciBmdW5jdGlvbiB0byByZWdpc3RlciBtdWx0aXBsZSBpbnRlcm5hbCB2YXJpYWJsZXMuIENhbiBiZSBjYWxsZWQgbXVsdGlwbGUgdGltZXMgdG8gcmVnaXN0ZXIgbXVsdGlwbGVcbiAgICogaW50ZXJuYWwgdmFyaWFibGVzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFyaWFibGVzIC0gYW4gYXJyYXkgb2YgSW5kaWNlc0hlbHBlciBmb3IgdGhlIHZhcmlhYmxlcy5cbiAgICovXG4gIHJlZ2lzdGVySW50ZXJuYWxWYXJpYWJsZXMoLi4udmFyaWFibGVzOiBJbmRpY2VzSGVscGVyW10pOiBTaGFkZXJIZWxwZXI7XG59XG5cbmNsYXNzIFNoYWRlckhlbHBlckltcGwgaW1wbGVtZW50cyBTaGFkZXJIZWxwZXIge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG5vcm1hbGl6ZWREaXNwYXRjaEdyb3VwOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgcHJpdmF0ZSBsaW1pdHM6IEdQVVN1cHBvcnRlZExpbWl0cyxcbiAgKSB7fVxuXG4gIGd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoc2l6ZTogbnVtYmVyIHwgc3RyaW5nKTogc3RyaW5nIHtcbiAgICAvLyBHdWFyZCBhZ2FpbnN0IG91dC1vZi1ib3VuZHMgd29yayBncm91cCBzaXplc1xuICAgIGNvbnN0IHNpemVJbkNvZGUgPSB0eXBlb2Ygc2l6ZSA9PT0gJ251bWJlcicgPyBgJHtzaXplfXVgIDogc2l6ZTtcbiAgICByZXR1cm4gYGlmIChnbG9iYWxfaWR4ID49ICR7c2l6ZUluQ29kZX0pIHsgcmV0dXJuOyB9YDtcbiAgfVxuXG4gIG1haW5TdGFydCh3b3JrZ3JvdXBTaXplOiBudW1iZXIgfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBXT1JLR1JPVVBfU0laRSkge1xuICAgIGNvbnN0IHdvcmtncm91cFNpemVYID0gdHlwZW9mIHdvcmtncm91cFNpemUgPT09ICdudW1iZXInID8gd29ya2dyb3VwU2l6ZSA6IHdvcmtncm91cFNpemVbMF07XG4gICAgY29uc3Qgd29ya2dyb3VwU2l6ZVkgPSB0eXBlb2Ygd29ya2dyb3VwU2l6ZSA9PT0gJ251bWJlcicgPyAxIDogd29ya2dyb3VwU2l6ZVsxXTtcbiAgICBjb25zdCB3b3JrZ3JvdXBTaXplWiA9IHR5cGVvZiB3b3JrZ3JvdXBTaXplID09PSAnbnVtYmVyJyA/IDEgOiB3b3JrZ3JvdXBTaXplWzJdO1xuXG4gICAgaWYgKFxuICAgICAgd29ya2dyb3VwU2l6ZVggPiB0aGlzLmxpbWl0cy5tYXhDb21wdXRlV29ya2dyb3VwU2l6ZVggfHxcbiAgICAgIHdvcmtncm91cFNpemVZID4gdGhpcy5saW1pdHMubWF4Q29tcHV0ZVdvcmtncm91cFNpemVZIHx8XG4gICAgICB3b3JrZ3JvdXBTaXplWiA+IHRoaXMubGltaXRzLm1heENvbXB1dGVXb3JrZ3JvdXBTaXplWlxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgd29ya2dyb3VwIHNpemUgWyR7d29ya2dyb3VwU2l6ZVh9LCAke3dvcmtncm91cFNpemVZfSwgJHtcbiAgICAgICAgICB3b3JrZ3JvdXBTaXplWlxuICAgICAgICB9XSBleGNlZWRzIHRoZSBtYXhpbXVtIHdvcmtncm91cCBzaXplIFske3RoaXMubGltaXRzLm1heENvbXB1dGVXb3JrZ3JvdXBTaXplWH0sICR7XG4gICAgICAgICAgdGhpcy5saW1pdHMubWF4Q29tcHV0ZVdvcmtncm91cFNpemVZXG4gICAgICAgIH0sICR7dGhpcy5saW1pdHMubWF4Q29tcHV0ZVdvcmtncm91cFNpemVafV0uYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHdvcmtncm91cFNpemVYICogd29ya2dyb3VwU2l6ZVkgKiB3b3JrZ3JvdXBTaXplWiA+IHRoaXMubGltaXRzLm1heENvbXB1dGVJbnZvY2F0aW9uc1Blcldvcmtncm91cCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgd29ya2dyb3VwIHNpemUgWyR7d29ya2dyb3VwU2l6ZVh9LCAke3dvcmtncm91cFNpemVZfSwgJHtcbiAgICAgICAgICB3b3JrZ3JvdXBTaXplWlxuICAgICAgICB9XSBleGNlZWRzIHRoZSBtYXhpbXVtIHdvcmtncm91cCBpbnZvY2F0aW9ucyAke3RoaXMubGltaXRzLm1heENvbXB1dGVJbnZvY2F0aW9uc1Blcldvcmtncm91cH0uYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgaXMxRGltZW5zaW9uRGlzcGF0Y2ggPSB0aGlzLm5vcm1hbGl6ZWREaXNwYXRjaEdyb3VwWzFdID09PSAxICYmIHRoaXMubm9ybWFsaXplZERpc3BhdGNoR3JvdXBbMl0gPT09IDE7XG4gICAgY29uc3QgcGFyYW1MaXN0ID0gaXMxRGltZW5zaW9uRGlzcGF0Y2hcbiAgICAgID8gYEBidWlsdGluKGdsb2JhbF9pbnZvY2F0aW9uX2lkKSBnbG9iYWxfaWQgOiB2ZWMzPHUzMj4sXG4gICAgQGJ1aWx0aW4od29ya2dyb3VwX2lkKSB3b3JrZ3JvdXBfaWQgOiB2ZWMzPHUzMj4sXG4gICAgQGJ1aWx0aW4obG9jYWxfaW52b2NhdGlvbl9pbmRleCkgbG9jYWxfaWR4IDogdTMyLFxuICAgIEBidWlsdGluKGxvY2FsX2ludm9jYXRpb25faWQpIGxvY2FsX2lkIDogdmVjMzx1MzI+YFxuICAgICAgOiBgQGJ1aWx0aW4oZ2xvYmFsX2ludm9jYXRpb25faWQpIGdsb2JhbF9pZCA6IHZlYzM8dTMyPixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBidWlsdGluKGxvY2FsX2ludm9jYXRpb25faWQpIGxvY2FsX2lkIDogdmVjMzx1MzI+LFxuICAgIEBidWlsdGluKGxvY2FsX2ludm9jYXRpb25faW5kZXgpIGxvY2FsX2lkeCA6IHUzMixcbiAgICBAYnVpbHRpbih3b3JrZ3JvdXBfaWQpIHdvcmtncm91cF9pZCA6IHZlYzM8dTMyPixcbiAgICBAYnVpbHRpbihudW1fd29ya2dyb3VwcykgbnVtX3dvcmtncm91cHMgOiB2ZWMzPHUzMj5gO1xuICAgIGNvbnN0IGdsb2JhbElkeERlZmluaXRpb24gPSBpczFEaW1lbnNpb25EaXNwYXRjaFxuICAgICAgPyBgbGV0IGdsb2JhbF9pZHggPSBnbG9iYWxfaWQueDtcbiAgICAgICAgIGxldCB3b3JrZ3JvdXBfaW5kZXggPSB3b3JrZ3JvdXBfaWQueDtgXG4gICAgICA6IGBsZXQgd29ya2dyb3VwX2luZGV4ID0gd29ya2dyb3VwX2lkLnogKiBudW1fd29ya2dyb3Vwc1swXSAqIG51bV93b3JrZ3JvdXBzWzFdICtcbiAgICAgICAgICAgICB3b3JrZ3JvdXBfaWQueSAqIG51bV93b3JrZ3JvdXBzWzBdICsgd29ya2dyb3VwX2lkLng7XG4gICAgICAgICBsZXQgZ2xvYmFsX2lkeCA9IHdvcmtncm91cF9pbmRleCAqICR7d29ya2dyb3VwU2l6ZVggKiB3b3JrZ3JvdXBTaXplWSAqIHdvcmtncm91cFNpemVafXUgKyBsb2NhbF9pZHg7YDtcblxuICAgIHJldHVybiBgQGNvbXB1dGUgQHdvcmtncm91cF9zaXplKCR7d29ya2dyb3VwU2l6ZVh9LCAke3dvcmtncm91cFNpemVZfSwgJHt3b3JrZ3JvdXBTaXplWn0pXG4gIGZuIG1haW4oJHtwYXJhbUxpc3R9KSB7XG4gICAgJHtnbG9iYWxJZHhEZWZpbml0aW9ufVxuICBgO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBlbmRWYXJpYWJsZVVuaWZvcm1zKHZhcmlhYmxlOiBJbmRpY2VzSGVscGVyKTogdm9pZCB7XG4gICAgaWYgKHZhcmlhYmxlLnJhbmsgIT09IDApIHtcbiAgICAgIGlmICh2YXJpYWJsZS5zaGFwZS5zdGFydHNXaXRoKCd1bmlmb3Jtcy4nKSkge1xuICAgICAgICB0aGlzLnVuaWZvcm1zLnB1c2goeyBuYW1lOiB2YXJpYWJsZS5zaGFwZS5yZXBsYWNlKCd1bmlmb3Jtcy4nLCAnJyksIHR5cGU6ICd1MzInLCBsZW5ndGg6IHZhcmlhYmxlLnJhbmsgfSk7XG4gICAgICB9XG4gICAgICBpZiAodmFyaWFibGUuc3RyaWRlcy5zdGFydHNXaXRoKCd1bmlmb3Jtcy4nKSkge1xuICAgICAgICB0aGlzLnVuaWZvcm1zLnB1c2goeyBuYW1lOiB2YXJpYWJsZS5zdHJpZGVzLnJlcGxhY2UoJ3VuaWZvcm1zLicsICcnKSwgdHlwZTogJ3UzMicsIGxlbmd0aDogdmFyaWFibGUucmFuayB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRlY2xhcmVWYXJpYWJsZSh2YXJpYWJsZTogSW5kaWNlc0hlbHBlciwgYmluZGluZ0luZGV4OiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGlmICh2YXJpYWJsZS51c2FnZSA9PT0gJ2ludGVybmFsJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3QgdXNlIGludGVybmFsIHZhcmlhYmxlIHdpdGggZGVjbGFyZVZhcmlhYmxlKCkuIHVzZSByZWdpc3RlckludGVybmFsVmFyaWFibGVzKCkgaW5zdGVhZC4nKTtcbiAgICB9XG4gICAgdGhpcy52YXJpYWJsZXMucHVzaCh2YXJpYWJsZSk7XG4gICAgdGhpcy5hcHBlbmRWYXJpYWJsZVVuaWZvcm1zKHZhcmlhYmxlKTtcbiAgICBjb25zdCBhY2Nlc3MgPSB2YXJpYWJsZS51c2FnZSA9PT0gJ2lucHV0JyA/ICdyZWFkJyA6ICdyZWFkX3dyaXRlJztcbiAgICBjb25zdCBzdG9yYWdlVHlwZSA9IHZhcmlhYmxlLnVzYWdlID09PSAnYXRvbWljT3V0cHV0JyA/IGBhdG9taWM8aTMyPmAgOiB2YXJpYWJsZS50eXBlLnN0b3JhZ2U7XG4gICAgcmV0dXJuIGBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtiaW5kaW5nSW5kZXh9KSB2YXI8c3RvcmFnZSwgJHthY2Nlc3N9PiAke3ZhcmlhYmxlLm5hbWV9OiBhcnJheTwke3N0b3JhZ2VUeXBlfT47YDtcbiAgfVxuXG4gIGRlY2xhcmVWYXJpYWJsZXMoLi4udmFyaWFibGVzOiBJbmRpY2VzSGVscGVyW10pOiBzdHJpbmcge1xuICAgIHJldHVybiB2YXJpYWJsZXMubWFwKCh2KSA9PiB0aGlzLmRlY2xhcmVWYXJpYWJsZSh2LCB0aGlzLnZhcmlhYmxlSW5kZXgrKykpLmpvaW4oJ1xcbicpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3RlckludGVybmFsVmFyaWFibGUodmFyaWFibGU6IEluZGljZXNIZWxwZXIpOiB2b2lkIHtcbiAgICBpZiAodmFyaWFibGUudXNhZ2UgIT09ICdpbnRlcm5hbCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ2Nhbm5vdCB1c2UgaW5wdXQgb3Igb3V0cHV0IHZhcmlhYmxlIHdpdGggcmVnaXN0ZXJJbnRlcm5hbFZhcmlhYmxlKCkuIHVzZSBkZWNsYXJlVmFyaWFibGVzKCkgaW5zdGVhZC4nLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmludGVybmFsVmFyaWFibGVzLnB1c2godmFyaWFibGUpO1xuICAgIHRoaXMuYXBwZW5kVmFyaWFibGVVbmlmb3Jtcyh2YXJpYWJsZSk7XG4gIH1cblxuICByZWdpc3RlckludGVybmFsVmFyaWFibGVzKC4uLnZhcmlhYmxlczogSW5kaWNlc0hlbHBlcltdKTogU2hhZGVySGVscGVyIHtcbiAgICB2YXJpYWJsZXMuZm9yRWFjaCgodikgPT4gdGhpcy5yZWdpc3RlckludGVybmFsVmFyaWFibGUodikpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmVnaXN0ZXJVbmlmb3JtKG5hbWU6IHN0cmluZywgdHlwZTogVW5pZm9ybURhdGFFbGVtZW50VHlwZSwgbGVuZ3RoID0gMSk6IFNoYWRlckhlbHBlciB7XG4gICAgdGhpcy51bmlmb3Jtcy5wdXNoKHsgbmFtZSwgdHlwZSwgbGVuZ3RoIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmVnaXN0ZXJVbmlmb3JtcyhhZGRpdGlvbmFsVW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlKTogU2hhZGVySGVscGVyIHtcbiAgICB0aGlzLnVuaWZvcm1zID0gdGhpcy51bmlmb3Jtcy5jb25jYXQoYWRkaXRpb25hbFVuaWZvcm1zKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHByaXZhdGUgaW50ZXJuYWxWYXJpYWJsZXM6IEluZGljZXNIZWxwZXJbXSA9IFtdO1xuICBwcml2YXRlIHZhcmlhYmxlczogSW5kaWNlc0hlbHBlcltdID0gW107XG4gIHByaXZhdGUgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW107XG4gIHByaXZhdGUgdW5pZm9ybURlY2xhcmF0aW9uKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMudW5pZm9ybXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgY29uc3QgdW5pZm9ybVNuaXBwZXRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgeyBuYW1lLCB0eXBlLCBsZW5ndGggfSBvZiB0aGlzLnVuaWZvcm1zKSB7XG4gICAgICBpZiAobGVuZ3RoICYmIGxlbmd0aCA+IDQpIHtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdmMTYnKSB7XG4gICAgICAgICAgdW5pZm9ybVNuaXBwZXRzLnB1c2goYEBhbGlnbigxNikgJHtuYW1lfTphcnJheTxtYXQyeDQ8JHt0eXBlfT4sICR7TWF0aC5jZWlsKGxlbmd0aCAvIDgpfT5gKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB1bmlmb3JtU25pcHBldHMucHVzaChgJHtuYW1lfTphcnJheTx2ZWM0PCR7dHlwZX0+LCAke01hdGguY2VpbChsZW5ndGggLyA0KX0+YCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHR5cGVUZW1wID0gbGVuZ3RoID09IG51bGwgfHwgbGVuZ3RoID09PSAxID8gdHlwZSA6IGB2ZWMke2xlbmd0aH08JHt0eXBlfT5gO1xuICAgICAgICB1bmlmb3JtU25pcHBldHMucHVzaChgJHtuYW1lfToke3R5cGVUZW1wfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBgXG4gICAgICBzdHJ1Y3QgVW5pZm9ybXMgeyAke3VuaWZvcm1TbmlwcGV0cy5qb2luKCcsICcpfSB9O1xuICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7dGhpcy52YXJpYWJsZUluZGV4fSkgdmFyPHVuaWZvcm0+IHVuaWZvcm1zOiBVbmlmb3JtcztgO1xuICB9XG4gIHByaXZhdGUgdmFyaWFibGVJbmRleCA9IDA7XG5cbiAgLyoqXG4gICAqIEdldCBhZGRpdGlvbmFsIGltcGxlbWVudGF0aW9uIHRoYXQgbmVlZHMgdG8gYmUgYWRkZWQgdG8gdGhlIHNoYWRlciBzb3VyY2UuXG4gICAqL1xuICBnZXQgYWRkaXRpb25hbEltcGxlbWVudGF0aW9ucygpOiBzdHJpbmcge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLnVuaWZvcm1EZWNsYXJhdGlvbigpICtcbiAgICAgIHRoaXMudmFyaWFibGVzLm1hcCgoaSkgPT4gaS5pbXBsKCkpLmpvaW4oJ1xcbicpICtcbiAgICAgIHRoaXMuaW50ZXJuYWxWYXJpYWJsZXMubWFwKChpKSA9PiBpLmltcGwoKSkuam9pbignXFxuJylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgdmFyaWFibGUgaW5mbyBvZiB0aGUgc2hhZGVyIHByb2dyYW0uXG4gICAqL1xuICBnZXQgdmFyaWFibGVzSW5mbygpOiBQcm9ncmFtVW5pZm9ybVZhcmlhYmxlSW5mb1tdIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodGhpcy51bmlmb3Jtcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgdW5pZm9ybVdnc2xUeXBlVG9EYXRhVHlwZSA9ICh0eXBlOiBVbmlmb3JtRGF0YUVsZW1lbnRUeXBlKSA9PlxuICAgICAgW0RhdGFUeXBlLnVpbnQzMiwgRGF0YVR5cGUuZmxvYXQxNiwgRGF0YVR5cGUuZmxvYXQsIERhdGFUeXBlLmludDMyXVtbJ3UzMicsICdmMTYnLCAnZjMyJywgJ2kzMiddLmluZGV4T2YodHlwZSldO1xuICAgIHJldHVybiB0aGlzLnVuaWZvcm1zLm1hcCgodSkgPT4gW3VuaWZvcm1XZ3NsVHlwZVRvRGF0YVR5cGUodS50eXBlKSwgdS5sZW5ndGggPz8gMV0pO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVTaGFkZXJIZWxwZXIgPSAoZGlzcGF0Y2hHcm91cDogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLCBsaW1pdHM6IEdQVVN1cHBvcnRlZExpbWl0cykgPT5cbiAgbmV3IFNoYWRlckhlbHBlckltcGwoZGlzcGF0Y2hHcm91cCwgbGltaXRzKTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBJbmRpY2VzSGVscGVyLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zcG9zZUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBwZXJtOiBudW1iZXJbXTtcbn1cblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIHBlcm06IHJlYWRvbmx5IG51bWJlcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zcG9zZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKHBlcm0ubGVuZ3RoICE9PSAwICYmIHBlcm0ubGVuZ3RoICE9PSBpbnB1dHNbMF0uZGltcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHBlcm0gc2l6ZSAke3Blcm0ubGVuZ3RofSBkb2VzIG5vdCBtYXRjaCBpbnB1dCByYW5rICR7aW5wdXRzWzBdLmRpbXMubGVuZ3RofWApO1xuICB9XG59O1xuXG5jb25zdCBnZXRBZGp1c3RlZFBlcm0gPSAoaW5wdXRSYW5rOiBudW1iZXIsIHBlcm06IG51bWJlcltdKTogbnVtYmVyW10gPT5cbiAgcGVybS5sZW5ndGggIT09IDAgPyBwZXJtIDogWy4uLm5ldyBBcnJheShpbnB1dFJhbmspLmtleXMoKV0ucmV2ZXJzZSgpO1xuXG5jb25zdCBnZXRPdXRwdXRTaGFwZSA9IChpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcGVybTogbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSA9PlxuICBTaGFwZVV0aWwuc29ydEJhc2VkT25QZXJtKGlucHV0U2hhcGUsIGdldEFkanVzdGVkUGVybShpbnB1dFNoYXBlLmxlbmd0aCwgcGVybSkpO1xuXG5jb25zdCBwZXJtRnVuY3Rpb25Cb2R5ID0gKHBlcm06IG51bWJlcltdLCByYW5rOiBudW1iZXIsIGlucHV0OiBJbmRpY2VzSGVscGVyLCBvdXRwdXQ6IEluZGljZXNIZWxwZXIpOiBzdHJpbmcgPT4ge1xuICBsZXQgcmV2ZXJzZUZ1bmMgPSBgZm4gcGVybShpOiAke291dHB1dC50eXBlLmluZGljZXN9KSAtPiAke2lucHV0LnR5cGUuaW5kaWNlc30ge1xuICAgIHZhciBhOiAke2lucHV0LnR5cGUuaW5kaWNlc307YDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICAvLyBpbnB1dCBpbmRpY2VzIGFuZCBvdXRwdXQgaW5kaWNlcyBzaG91bGQgYWx3YXlzIGJlIGxhcmdlciBvciBlcXVhbCB0byAyLFxuICAgIC8vIHNvIGluZGV4ZXIgaXMgYWx3YXlzIHZhbGlkIHRvIGJlIHVzZWQgb24gYGFgIGFuZCBgaWAuXG4gICAgcmV2ZXJzZUZ1bmMgKz0gYGFbJHtwZXJtW2ldfV09aVske2l9XTtgO1xuICB9XG4gIHJldHVybiAocmV2ZXJzZUZ1bmMgKz0gJ3JldHVybiBhO30nKTtcbn07XG5cbmNvbnN0IHNxdWVlemVTaGFwZSA9IChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGFkanVzdGVkUGVybTogbnVtYmVyW10pOiB7IG5ld1NoYXBlOiBudW1iZXJbXTsgbmV3UGVybTogbnVtYmVyW10gfSA9PiB7XG4gIGNvbnN0IG5ld1NoYXBlOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBuZXdQZXJtOiBudW1iZXJbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNoYXBlLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKHNoYXBlW2ldICE9PSAxKSB7XG4gICAgICBuZXdTaGFwZS5wdXNoKHNoYXBlW2ldKTtcbiAgICB9XG4gICAgaWYgKHNoYXBlW2FkanVzdGVkUGVybVtpXV0gIT09IDEpIHtcbiAgICAgIG5ld1Blcm0ucHVzaChhZGp1c3RlZFBlcm1baV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4geyBuZXdTaGFwZSwgbmV3UGVybSB9O1xufTtcblxuY29uc3QgaXNUcmFuc3Bvc2VSZXNoYXBlID0gKHBlcm06IG51bWJlcltdLCBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pID0+IHtcbiAgLy8gQXMgbG9uZyBhcyB0aGUgZGltcyB3aXRoIHZhbHVlcyA+IDEgc3RheSBpbiB0aGUgc2FtZSBvcmRlciwgaXQncyBhIHJlc2hhcGUuXG4gIC8vIEV4YW1wbGU6IFNoYXBlPSgxLDEsMTAyNCw0MDk2KSAtPiBwZXJtPSgyLDAsMywxKS5cbiAgbGV0IGxhc3RQZXJtdXRlZEF4aXMgPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHBlcm0ubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoc2hhcGVbcGVybVtpXV0gPT09IDEpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAocGVybVtpXSA8IGxhc3RQZXJtdXRlZEF4aXMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgbGFzdFBlcm11dGVkQXhpcyA9IHBlcm1baV07XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8gPSAoaW5wdXRUZW5zb3I6IFRlbnNvclZpZXcsIHBlcm1BdHRyOiBudW1iZXJbXSk6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXREYXRhVHlwZSA9IGlucHV0VGVuc29yLmRhdGFUeXBlO1xuICBjb25zdCBpbnB1dFJhbmsgPSBpbnB1dFRlbnNvci5kaW1zLmxlbmd0aDtcbiAgY29uc3QgcGVybSA9IGdldEFkanVzdGVkUGVybShpbnB1dFJhbmssIHBlcm1BdHRyKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBnZXRPdXRwdXRTaGFwZShpbnB1dFRlbnNvci5kaW1zLCBwZXJtKTtcbiAgbGV0IG5ld0lucHV0U2hhcGUgPSBpbnB1dFRlbnNvci5kaW1zO1xuICBsZXQgbmV3T3V0cHV0U2hhcGUgPSBvdXRwdXRTaGFwZTtcbiAgY29uc3QgdHJhbnNwb3NlQXNSZXNoYXBlID0gaW5wdXRSYW5rIDwgMiB8fCBpc1RyYW5zcG9zZVJlc2hhcGUocGVybSwgaW5wdXRUZW5zb3IuZGltcyk7XG4gIGxldCBnZXRTaGFkZXJTb3VyY2U7XG4gIGlmICh0cmFuc3Bvc2VBc1Jlc2hhcGUpIHtcbiAgICBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICAgIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnaW5wdXQnLCBpbnB1dERhdGFUeXBlLCBuZXdJbnB1dFNoYXBlLCA0KTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dERhdGFUeXBlLCBuZXdPdXRwdXRTaGFwZSwgNCk7XG4gICAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ291dHB1dF9zaXplJywgJ3UzMicpLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIG91dHB1dCl9XG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgb3V0cHV0W2dsb2JhbF9pZHhdID0gaW5wdXRbZ2xvYmFsX2lkeF07XG4gIH1gO1xuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogJ1RyYW5zcG9zZUNvcHknLFxuICAgICAgc2hhZGVyQ2FjaGU6IHsgaW5wdXREZXBlbmRlbmNpZXM6IFsndHlwZSddIH0sXG4gICAgICBnZXRSdW5EYXRhOiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dFRlbnNvci5kYXRhVHlwZSB9XSxcbiAgICAgICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8gLyA0IC8qIGNvbXBvbmVudHMgKi8pIH0sXG4gICAgICAgICAgcHJvZ3JhbVVuaWZvcm1zOiBbeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNCkgfV0sXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIH07XG4gIH1cbiAgY29uc3QgeyBuZXdTaGFwZSwgbmV3UGVybSB9ID0gc3F1ZWV6ZVNoYXBlKGlucHV0VGVuc29yLmRpbXMsIHBlcm0pO1xuICBjb25zdCBjaGFubmVsc0xhc3QgPSBTaGFwZVV0aWwuYXJlRXF1YWwobmV3UGVybSwgWzIsIDMsIDFdKTtcbiAgY29uc3QgY2hhbm5lbHNGaXJzdCA9IFNoYXBlVXRpbC5hcmVFcXVhbChuZXdQZXJtLCBbMywgMSwgMl0pO1xuICBjb25zdCB1c2VTaGFyZWQgPSBuZXdTaGFwZS5sZW5ndGggPT09IDIgfHwgY2hhbm5lbHNMYXN0IHx8IGNoYW5uZWxzRmlyc3Q7XG4gIGlmICh1c2VTaGFyZWQpIHtcbiAgICBuZXdJbnB1dFNoYXBlID0gY2hhbm5lbHNMYXN0XG4gICAgICA/IFtuZXdTaGFwZVswXSwgbmV3U2hhcGVbMV0gKiBuZXdTaGFwZVsyXV1cbiAgICAgIDogY2hhbm5lbHNGaXJzdFxuICAgICAgICA/IFtuZXdTaGFwZVswXSAqIG5ld1NoYXBlWzFdLCBuZXdTaGFwZVsyXV1cbiAgICAgICAgOiBuZXdTaGFwZTtcbiAgICBuZXdPdXRwdXRTaGFwZSA9IFtuZXdJbnB1dFNoYXBlWzFdLCBuZXdJbnB1dFNoYXBlWzBdXTtcbiAgICBjb25zdCB0aWxlU2l6ZSA9IDE2O1xuICAgIGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgICAgY29uc3QgaW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdhJywgaW5wdXREYXRhVHlwZSwgbmV3SW5wdXRTaGFwZS5sZW5ndGgpO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0RGF0YVR5cGUsIG5ld091dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ291dHB1dF9zaXplJywgJ3UzMicpLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIG91dHB1dCl9XG4gIHZhcjx3b3JrZ3JvdXA+IHRpbGUgOiBhcnJheTxhcnJheTwke291dHB1dC50eXBlLnZhbHVlfSwgJHt0aWxlU2l6ZSArIDF9PiwgJHt0aWxlU2l6ZX0+O1xuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoW3RpbGVTaXplLCB0aWxlU2l6ZSwgMV0pfVxuICAgIGxldCBzdHJpZGUgPSAodW5pZm9ybXMub3V0cHV0X3NoYXBlWzFdIC0gMSkgLyAke3RpbGVTaXplfSArIDE7XG4gICAgbGV0IHdvcmtncm91cF9pZF94ID0gd29ya2dyb3VwX2luZGV4ICUgc3RyaWRlO1xuICAgIGxldCB3b3JrZ3JvdXBfaWRfeSA9IHdvcmtncm91cF9pbmRleCAvIHN0cmlkZTtcbiAgICBsZXQgaW5wdXRfY29sID0gd29ya2dyb3VwX2lkX3kgKiAke3RpbGVTaXplfXUgKyBsb2NhbF9pZC54O1xuICAgIGxldCBpbnB1dF9yb3cgPSB3b3JrZ3JvdXBfaWRfeCAqICR7dGlsZVNpemV9dSArIGxvY2FsX2lkLnk7XG4gICAgaWYgKGlucHV0X3JvdyA8IHVuaWZvcm1zLmFfc2hhcGVbMF0gJiYgaW5wdXRfY29sIDwgdW5pZm9ybXMuYV9zaGFwZVsxXSkge1xuICAgICAgdGlsZVtsb2NhbF9pZC55XVtsb2NhbF9pZC54XSA9ICR7aW5wdXQuZ2V0QnlJbmRpY2VzKGAke2lucHV0LnR5cGUuaW5kaWNlc30oaW5wdXRfcm93LCBpbnB1dF9jb2wpYCl9O1xuICAgIH1cbiAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICBsZXQgb3V0cHV0X2NvbCA9IHdvcmtncm91cF9pZF94ICogJHt0aWxlU2l6ZX11ICsgbG9jYWxfaWQueDtcbiAgICBsZXQgb3V0cHV0X3JvdyA9IHdvcmtncm91cF9pZF95ICogJHt0aWxlU2l6ZX11ICsgbG9jYWxfaWQueTtcbiAgICBpZiAob3V0cHV0X3JvdyA8IHVuaWZvcm1zLm91dHB1dF9zaGFwZVswXSAmJiBvdXRwdXRfY29sIDwgdW5pZm9ybXMub3V0cHV0X3NoYXBlWzFdKSB7XG4gICAgICAke291dHB1dC5zZXRCeUluZGljZXMoYCR7b3V0cHV0LnR5cGUuaW5kaWNlc30ob3V0cHV0X3Jvdywgb3V0cHV0X2NvbClgLCAndGlsZVtsb2NhbF9pZC54XVtsb2NhbF9pZC55XScpfVxuICAgIH1cbiAgfWA7XG4gICAgfTtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogJ1RyYW5zcG9zZVNoYXJlZCcsXG4gICAgICBzaGFkZXJDYWNoZTogeyBpbnB1dERlcGVuZGVuY2llczogWyd0eXBlJ10gfSxcbiAgICAgIGdldFJ1bkRhdGE6ICgpID0+IHtcbiAgICAgICAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0VGVuc29yLmRhdGFUeXBlIH1dLFxuICAgICAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG5ld091dHB1dFNoYXBlWzFdIC8gdGlsZVNpemUpLCB5OiBNYXRoLmNlaWwobmV3T3V0cHV0U2hhcGVbMF0gLyB0aWxlU2l6ZSkgfSxcbiAgICAgICAgICBwcm9ncmFtVW5pZm9ybXM6IFtcbiAgICAgICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgICAgICAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhuZXdJbnB1dFNoYXBlLCBuZXdPdXRwdXRTaGFwZSksXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBnZXRTaGFkZXJTb3VyY2UsXG4gICAgfTtcbiAgfVxuXG4gIGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnYScsIGlucHV0RGF0YVR5cGUsIG5ld0lucHV0U2hhcGUubGVuZ3RoKTtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXREYXRhVHlwZSwgbmV3T3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ291dHB1dF9zaXplJywgJ3UzMicpLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIG91dHB1dCl9XG5cbiAgJHtwZXJtRnVuY3Rpb25Cb2R5KHBlcm0sIGlucHV0UmFuaywgaW5wdXQsIG91dHB1dCl9XG5cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX1cblxuICAgIGxldCBpbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuICAgIGxldCBhSW5kaWNlcyA9IHBlcm0oaW5kaWNlcyk7XG5cbiAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsIGlucHV0LmdldEJ5SW5kaWNlcygnYUluZGljZXMnKSl9XG4gIH1gO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdUcmFuc3Bvc2UnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke3Blcm1BdHRyfWAsIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnXSB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+IHtcbiAgICAgIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0VGVuc29yLmRhdGFUeXBlIH1dLFxuICAgICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICAgIHByb2dyYW1Vbmlmb3JtczogW1xuICAgICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgICAgICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMobmV3SW5wdXRTaGFwZSwgbmV3T3V0cHV0U2hhcGUpLFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCB0cmFuc3Bvc2UgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFRyYW5zcG9zZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMucGVybSk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgYXR0cmlidXRlcy5wZXJtKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogVHJhbnNwb3NlQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBwZXJtOiBhdHRyaWJ1dGVzLnBlcm0gYXMgbnVtYmVyW10gfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuaW1wb3J0IHsgY3JlYXRlUmVkdWNlQXR0cmlidXRlc0Zyb21JbnB1dHMsIFJlZHVjZUF0dHJpYnV0ZXMgfSBmcm9tICcuL3JlZHVjZSc7XG5pbXBvcnQgeyBjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyB9IGZyb20gJy4vdHJhbnNwb3NlJztcblxuY29uc3QgcmVkdWNlT3BzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICBtYXg6ICdzZWxlY3QoYmVzdFZhbHVlLCBjYW5kaWRhdGUsIGNhbmRpZGF0ZSA+IGJlc3RWYWx1ZSknLFxuICBtaW46ICdzZWxlY3QoYmVzdFZhbHVlLCBjYW5kaWRhdGUsIGNhbmRpZGF0ZSA8IGJlc3RWYWx1ZSknLFxuICBtZWFuOiAnYmVzdFZhbHVlICsgY2FuZGlkYXRlJyxcbiAgc3VtOiAnYmVzdFZhbHVlICsgY2FuZGlkYXRlJyxcbiAgcHJvZDogJ2Jlc3RWYWx1ZSAqIGNhbmRpZGF0ZScsXG4gIHN1bVNxdWFyZTogJ2Jlc3RWYWx1ZSArIGNhbmRpZGF0ZSAqIGNhbmRpZGF0ZScsXG4gIGxvZ1N1bUV4cDogJ2Jlc3RWYWx1ZSArIGV4cChjYW5kaWRhdGUpJyxcbiAgbDE6ICdiZXN0VmFsdWUgKyBhYnMoY2FuZGlkYXRlKScsXG4gIGwyOiAnYmVzdFZhbHVlICsgY2FuZGlkYXRlICogY2FuZGlkYXRlJyxcbiAgbG9nU3VtOiAnYmVzdFZhbHVlICsgY2FuZGlkYXRlJyxcbn07XG5cbmNvbnN0IHJlZHVjZVNoYXJlZE9wczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgbWF4OiAnc2VsZWN0KGJlc3RWYWx1ZSwgY2FuZGlkYXRlLCBjYW5kaWRhdGUgPiBiZXN0VmFsdWUpJyxcbiAgbWluOiAnc2VsZWN0KGJlc3RWYWx1ZSwgY2FuZGlkYXRlLCBjYW5kaWRhdGUgPCBiZXN0VmFsdWUpJyxcbiAgbWVhbjogJ2Jlc3RWYWx1ZSArIGNhbmRpZGF0ZScsXG4gIHN1bTogJ2Jlc3RWYWx1ZSArIGNhbmRpZGF0ZScsXG4gIHByb2Q6ICdiZXN0VmFsdWUgKiBjYW5kaWRhdGUnLFxuICBzdW1TcXVhcmU6ICdiZXN0VmFsdWUgKyBjYW5kaWRhdGUnLFxuICBsb2dTdW1FeHA6ICdiZXN0VmFsdWUgKyBjYW5kaWRhdGUnLFxuICBsMTogJ2Jlc3RWYWx1ZSArIGNhbmRpZGF0ZScsXG4gIGwyOiAnYmVzdFZhbHVlICsgY2FuZGlkYXRlJyxcbiAgbG9nU3VtOiAnYmVzdFZhbHVlICsgY2FuZGlkYXRlJyxcbn07XG5cbmNvbnN0IHJlZHVjZUluaXRWYWx1ZXM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gIG1heDogJ19BW29mZnNldF0nLFxuICBtaW46ICdfQVtvZmZzZXRdJyxcbiAgbWVhbjogJzAnLFxuICBzdW06ICcwJyxcbiAgcHJvZDogJzEnLFxuICBzdW1TcXVhcmU6ICcwJyxcbiAgbG9nU3VtRXhwOiAnMCcsXG4gIGwxOiAnMCcsXG4gIGwyOiAnMCcsXG4gIGxvZ1N1bTogJzAnLFxufTtcblxuY29uc3QgcmVkdWNlT3V0cHV0VmFsdWVzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICBtYXg6ICdiZXN0VmFsdWUnLFxuICBtaW46ICdiZXN0VmFsdWUnLFxuICBzdW06ICdiZXN0VmFsdWUnLFxuICBwcm9kOiAnYmVzdFZhbHVlJyxcbiAgc3VtU3F1YXJlOiAnYmVzdFZhbHVlJyxcbiAgbG9nU3VtRXhwOiAnbG9nKGJlc3RWYWx1ZSknLFxuICBsMTogJ2Jlc3RWYWx1ZScsXG4gIGwyOiAnc3FydChiZXN0VmFsdWUpJyxcbiAgbG9nU3VtOiAnbG9nKGJlc3RWYWx1ZSknLFxufTtcblxuY29uc3QgZ2V0SW5uZXJNb3N0QXhlcyA9IChudW1Jbm5lckF4ZXM6IG51bWJlciwgcmFuazogbnVtYmVyKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCByZXMgPSBbXTtcbiAgZm9yIChsZXQgaSA9IHJhbmsgLSBudW1Jbm5lckF4ZXM7IGkgPCByYW5rOyArK2kpIHtcbiAgICByZXMucHVzaChpKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufTtcblxuY29uc3QgY29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyA9IChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdKTogW251bWJlcltdLCBudW1iZXJbXV0gPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFtdO1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCByYW5rOyBkaW0rKykge1xuICAgIGlmIChheGVzLmluZGV4T2YoZGltKSA9PT0gLTEpIHtcbiAgICAgIG91dHB1dFNoYXBlLnB1c2goc2hhcGVbZGltXSk7XG4gICAgfVxuICB9XG4gIGNvbnN0IHJlZHVjZVNoYXBlID0gYXhlcy5tYXAoKGRpbSkgPT4gc2hhcGVbZGltXSk7XG4gIHJldHVybiBbb3V0cHV0U2hhcGUsIHJlZHVjZVNoYXBlXTtcbn07XG5cbmNvbnN0IGV4cGFuZFNoYXBlVG9LZWVwRGltID0gKHNoYXBlOiBudW1iZXJbXSwgYXhlczogbnVtYmVyW10pOiBudW1iZXJbXSA9PiB7XG4gIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGggKyBheGVzLmxlbmd0aDtcbiAgY29uc3QgZXhwYW5kU2hhcGUgPSBbXTtcbiAgbGV0IHNoYXBlSWR4ID0gMDtcbiAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgcmFuazsgZGltKyspIHtcbiAgICBpZiAoYXhlcy5pbmRleE9mKGRpbSkgPT09IC0xKSB7XG4gICAgICBleHBhbmRTaGFwZS5wdXNoKHNoYXBlW3NoYXBlSWR4KytdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhwYW5kU2hhcGUucHVzaCgxKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGV4cGFuZFNoYXBlO1xufTtcblxuY29uc3QgYXJlQXhlc0lubmVyTW9zdERpbXMgPSAoYXhlczogbnVtYmVyW10sIHJhbms6IG51bWJlcik6IGJvb2xlYW4gPT4ge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGF4ZXMubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoYXhlc1theGVzLmxlbmd0aCAtIGkgLSAxXSAhPT0gcmFuayAtIDEgLSBpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuY29uc3QgZ2V0QXhlc1Blcm11dGF0aW9uID0gKGF4ZXM6IG51bWJlcltdLCByYW5rOiBudW1iZXIpOiBudW1iZXJbXSA9PiB7XG4gIGNvbnN0IHJlcyA9IFtdO1xuICBpZiAoIWFyZUF4ZXNJbm5lck1vc3REaW1zKGF4ZXMsIHJhbmspKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaSkgPT09IC0xKSB7XG4gICAgICAgIHJlcy5wdXNoKGkpO1xuICAgICAgfVxuICAgIH1cbiAgICBheGVzLmZvckVhY2goKGF4aXMpID0+IHJlcy5wdXNoKGF4aXMpKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVJlZHVjZVNoYXJlZFByb2dyYW1JbmZvID0gKFxuICBuYW1lOiBzdHJpbmcsXG4gIGNhY2hlS2V5OiBzdHJpbmcsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICByZWR1Y2VUeXBlOiBzdHJpbmcsXG4gIG91dHB1dERhdGFUeXBlOiBEYXRhVHlwZSxcbiAgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuICByZWR1Y2VTaGFwZTogbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcblxuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICBjb25zdCByZWR1Y2VTaXplID0gU2hhcGVVdGlsLnNpemUocmVkdWNlU2hhcGUpO1xuXG4gIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnX0EnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0U2hhcGUpO1xuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0Jywgb3V0cHV0RGF0YVR5cGUsIG91dHB1dFNoYXBlKTtcblxuICBsZXQgd29ya2dyb3VwU2l6ZSA9IDY0O1xuICAvLyBJZiBvbmx5IG9uZSB3b3JrZ3JvdXAgaXMgZGlzcGF0Y2hlZCwgaW5jcmVhc2Ugd29ya2dyb3VwU2l6ZSB0byBpbXByb3ZlIHBhcmFsbGVsaXNtLlxuICBpZiAob3V0cHV0U2l6ZSA9PT0gMSkge1xuICAgIHdvcmtncm91cFNpemUgPSAyNTY7XG4gIH1cblxuICBjb25zdCBzaGFyZWRNZW1vcnlTbmlwcGV0ID0gYFxuICAgICAgICAgIHZhcjx3b3JrZ3JvdXA+IGFCZXN0VmFsdWVzIDogYXJyYXk8ZjMyLCAke3dvcmtncm91cFNpemV9PjtcbiAgICAgICBgO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gYFxuICAgICAgICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ3JlZHVjZVNpemUnLCAndTMyJykuZGVjbGFyZVZhcmlhYmxlcyhpbnB1dCwgb3V0cHV0KX1cbiAgICAgICAgJHtzaGFyZWRNZW1vcnlTbmlwcGV0fVxuICAgICAgICBmbiBESVZfQ0VJTChhIDogdTMyLCBiIDogdTMyKSAtPiB1MzIge1xuICAgICAgICAgIHJldHVybiAoKGEgLSAxdSkgLyBiICsgMXUpO1xuICAgICAgICAgfVxuICAgICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KHdvcmtncm91cFNpemUpfVxuXG4gICAgICAgICAgbGV0IG91dHB1dEluZGV4ID0gZ2xvYmFsX2lkeCAvICR7d29ya2dyb3VwU2l6ZX07XG4gICAgICAgICAgbGV0IG9mZnNldCA9IG91dHB1dEluZGV4ICogdW5pZm9ybXMucmVkdWNlU2l6ZTtcblxuICAgICAgICAgIHZhciBiZXN0VmFsdWUgPSBmMzIoJHtyZWR1Y2VJbml0VmFsdWVzW3JlZHVjZVR5cGVdfSk7XG4gICAgICAgICAgbGV0IExlbmd0aCA9IHVuaWZvcm1zLnJlZHVjZVNpemU7XG4gICAgICAgICAgZm9yICh2YXIgayA9IGxvY2FsX2lkeDsgayA8IExlbmd0aDsgayA9IGsgKyAke3dvcmtncm91cFNpemV9KSB7XG4gICAgICAgICAgIGxldCBjYW5kaWRhdGUgPSBmMzIoJHtpbnB1dC5nZXRCeU9mZnNldCgnb2Zmc2V0ICsgaycpfSk7XG4gICAgICAgICAgIGJlc3RWYWx1ZSA9ICR7cmVkdWNlT3BzW3JlZHVjZVR5cGVdfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYUJlc3RWYWx1ZXNbbG9jYWxfaWR4XSA9IGJlc3RWYWx1ZTtcbiAgICAgICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICAgICAgIHZhciByZWR1Y2VTaXplID0gbWluKExlbmd0aCwgJHt3b3JrZ3JvdXBTaXplfXUpO1xuICAgICAgICAgZm9yICh2YXIgY3VycmVudFNpemUgPSByZWR1Y2VTaXplIC8gMnU7IHJlZHVjZVNpemUgPiAxdTtcbiAgICAgICAgICAgICBjdXJyZW50U2l6ZSA9IHJlZHVjZVNpemUgLyAydSkge1xuICAgICAgICAgICBsZXQgaW50ZXJ2YWwgPSBESVZfQ0VJTChyZWR1Y2VTaXplLCAydSk7XG4gICAgICAgICAgIGlmIChsb2NhbF9pZHggPCBjdXJyZW50U2l6ZSkge1xuICAgICAgICAgICAgbGV0IGNhbmRpZGF0ZSA9IGFCZXN0VmFsdWVzW2xvY2FsX2lkeCArIGludGVydmFsXTtcbiAgICAgICAgICAgIGJlc3RWYWx1ZSA9ICR7cmVkdWNlU2hhcmVkT3BzW3JlZHVjZVR5cGVdfTtcbiAgICAgICAgICAgIGFCZXN0VmFsdWVzW2xvY2FsX2lkeF0gPSBiZXN0VmFsdWU7XG4gICAgICAgICAgIH1cbiAgICAgICAgICAgcmVkdWNlU2l6ZSA9IGludGVydmFsO1xuICAgICAgICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gICAgICAgICB9XG5cbiAgICAgICAgIGlmIChsb2NhbF9pZHggPT0gMHUpIHtcbiAgICAgICAgICAke291dHB1dC5zZXRCeU9mZnNldChcbiAgICAgICAgICAgICdvdXRwdXRJbmRleCcsXG4gICAgICAgICAgICBgJHtcbiAgICAgICAgICAgICAgcmVkdWNlVHlwZSA9PT0gJ21lYW4nXG4gICAgICAgICAgICAgICAgPyBgJHtvdXRwdXQudHlwZS5zdG9yYWdlfShiZXN0VmFsdWUgLyBmMzIodW5pZm9ybXMucmVkdWNlU2l6ZSkpYFxuICAgICAgICAgICAgICAgIDogYCR7b3V0cHV0LnR5cGUuc3RvcmFnZX0oJHtyZWR1Y2VPdXRwdXRWYWx1ZXNbcmVkdWNlVHlwZV19KWBcbiAgICAgICAgICAgIH1gLFxuICAgICAgICAgICl9O1xuICAgICAgICAgfVxuICAgICAgICB9YDtcblxuICAvLyBPbmUgd29yayBncm91cCBpcyByZXNwb25zaWJsZSBmb3Igb25seSBvbmUgZWxlbWVudCBvZiBvdXRwdXQuXG4gIHJldHVybiB7XG4gICAgbmFtZSxcbiAgICAvLyBOb3RlIHRoYXQgaW4gSlNFUCwgV0cgc2l6ZSBpcyBub3QgaW5jbHVkZWQgaW4gY2FjaGUgYnkgZGVmYXVsdCwgYnV0IFdlYkdQVSBFUCBpdCBpcy5cbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtjYWNoZUtleX07JHt3b3JrZ3JvdXBTaXplfWAsIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3R5cGUnXSB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBvdXRwdXREYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogb3V0cHV0U2l6ZSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zOiBbeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHJlZHVjZVNpemUgfV0sXG4gICAgfSksXG4gIH07XG59O1xuXG5jb25zdCByZWR1Y2VDb21tb24gPSAoXG4gIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LFxuICBuYW1lOiBzdHJpbmcsXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4gIHJlZHVjZVR5cGU6ICdzdW0nIHwgJ3N1bVNxdWFyZScgfCAncHJvZCcgfCAnbWluJyB8ICdtYXgnIHwgJ21lYW4nIHwgJ2xvZ1N1bUV4cCcgfCAnbDEnIHwgJ2wyJyB8ICdsb2dTdW0nLFxuKTogdm9pZCA9PiB7XG4gIGNvbnN0IHVwZGF0ZWRBdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzID1cbiAgICBjb250ZXh0LmlucHV0cy5sZW5ndGggPT09IDEgPyBhdHRyaWJ1dGVzIDogY3JlYXRlUmVkdWNlQXR0cmlidXRlc0Zyb21JbnB1dHMoY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpO1xuXG4gIGxldCB1cGRhdGVkQXhlcyA9IHVwZGF0ZWRBdHRyaWJ1dGVzLmF4ZXM7XG4gIGlmICh1cGRhdGVkQXhlcy5sZW5ndGggPT09IDAgJiYgIXVwZGF0ZWRBdHRyaWJ1dGVzLm5vb3BXaXRoRW1wdHlBeGVzKSB7XG4gICAgdXBkYXRlZEF4ZXMgPSBjb250ZXh0LmlucHV0c1swXS5kaW1zLm1hcCgoX2RpbSwgaSkgPT4gaSk7XG4gIH1cbiAgY29uc3Qgbm9ybWFsaXplQXhlcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGVzKHVwZGF0ZWRBeGVzLCBjb250ZXh0LmlucHV0c1swXS5kaW1zLmxlbmd0aCk7XG5cbiAgbGV0IGF4ZXMgPSBub3JtYWxpemVBeGVzO1xuICBsZXQgaW5wdXQgPSBjb250ZXh0LmlucHV0c1swXTtcbiAgY29uc3QgcGVybXV0ZWRBeGVzID0gZ2V0QXhlc1Blcm11dGF0aW9uKGF4ZXMsIGNvbnRleHQuaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgaWYgKHBlcm11dGVkQXhlcy5sZW5ndGggPiAwKSB7XG4gICAgaW5wdXQgPSBjb250ZXh0LmNvbXB1dGUoY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sIHBlcm11dGVkQXhlcyksIHtcbiAgICAgIGlucHV0czogWzBdLFxuICAgICAgb3V0cHV0czogWy0xXSxcbiAgICB9KVswXTtcbiAgICBheGVzID0gZ2V0SW5uZXJNb3N0QXhlcyhheGVzLmxlbmd0aCwgaW5wdXQuZGltcy5sZW5ndGgpO1xuICB9XG5cbiAgY29uc3QgW291dHB1dFNoYXBlLCByZWR1Y2VTaGFwZV0gPSBjb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzKGlucHV0LmRpbXMsIGF4ZXMpO1xuICBsZXQgZmluYWxPdXRwdXRTaGFwZSA9IG91dHB1dFNoYXBlO1xuICBpZiAodXBkYXRlZEF0dHJpYnV0ZXMua2VlcERpbXMpIHtcbiAgICBmaW5hbE91dHB1dFNoYXBlID0gZXhwYW5kU2hhcGVUb0tlZXBEaW0ob3V0cHV0U2hhcGUsIG5vcm1hbGl6ZUF4ZXMpO1xuICB9XG5cbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZVJlZHVjZVNoYXJlZFByb2dyYW1JbmZvKFxuICAgICAgbmFtZSxcbiAgICAgIHVwZGF0ZWRBdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgW2lucHV0XSxcbiAgICAgIHJlZHVjZVR5cGUsXG4gICAgICBjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSxcbiAgICAgIGZpbmFsT3V0cHV0U2hhcGUsXG4gICAgICByZWR1Y2VTaGFwZSxcbiAgICApLFxuICAgIHsgaW5wdXRzOiBbaW5wdXRdIH0sXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWVhblNoYXJlZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICByZWR1Y2VDb21tb24oY29udGV4dCwgJ1JlZHVjZU1lYW5TaGFyZWQnLCBhdHRyaWJ1dGVzLCAnbWVhbicpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZUwxU2hhcmVkID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHJlZHVjZUNvbW1vbihjb250ZXh0LCAnUmVkdWNlTDFTaGFyZWQnLCBhdHRyaWJ1dGVzLCAnbDEnKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VMMlNoYXJlZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICByZWR1Y2VDb21tb24oY29udGV4dCwgJ1JlZHVjZUwyU2hhcmVkJywgYXR0cmlidXRlcywgJ2wyJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtRXhwU2hhcmVkID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHJlZHVjZUNvbW1vbihjb250ZXh0LCAnUmVkdWNlTG9nU3VtRXhwU2hhcmVkJywgYXR0cmlidXRlcywgJ2xvZ1N1bUV4cCcpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZU1heFNoYXJlZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICByZWR1Y2VDb21tb24oY29udGV4dCwgJ1JlZHVjZU1heFNoYXJlZCcsIGF0dHJpYnV0ZXMsICdtYXgnKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VNaW5TaGFyZWQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgcmVkdWNlQ29tbW9uKGNvbnRleHQsICdSZWR1Y2VNaW5TaGFyZWQnLCBhdHRyaWJ1dGVzLCAnbWluJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlUHJvZFNoYXJlZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICByZWR1Y2VDb21tb24oY29udGV4dCwgJ1JlZHVjZVByb2RTaGFyZWQnLCBhdHRyaWJ1dGVzLCAncHJvZCcpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZVN1bVNoYXJlZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICByZWR1Y2VDb21tb24oY29udGV4dCwgJ1JlZHVjZVN1bVNoYXJlZCcsIGF0dHJpYnV0ZXMsICdzdW0nKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VTdW1TcXVhcmVTaGFyZWQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgcmVkdWNlQ29tbW9uKGNvbnRleHQsICdSZWR1Y2VTdW1TcXVhcmVTaGFyZWQnLCBhdHRyaWJ1dGVzLCAnc3VtU3F1YXJlJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtU2hhcmVkID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHJlZHVjZUNvbW1vbihjb250ZXh0LCAnUmVkdWNlTG9nU3VtU2hhcmVkJywgYXR0cmlidXRlcywgJ2xvZ1N1bScpO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1TaGFkZXJDYWNoZUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBJbmRpY2VzSGVscGVyLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuaW1wb3J0IHtcbiAgcmVkdWNlTDFTaGFyZWQsXG4gIHJlZHVjZUwyU2hhcmVkLFxuICByZWR1Y2VMb2dTdW1FeHBTaGFyZWQsXG4gIHJlZHVjZUxvZ1N1bVNoYXJlZCxcbiAgcmVkdWNlTWF4U2hhcmVkLFxuICByZWR1Y2VNZWFuU2hhcmVkLFxuICByZWR1Y2VNaW5TaGFyZWQsXG4gIHJlZHVjZVByb2RTaGFyZWQsXG4gIHJlZHVjZVN1bVNoYXJlZCxcbiAgcmVkdWNlU3VtU3F1YXJlU2hhcmVkLFxufSBmcm9tICcuL3JlZHVjZS1zaGFyZWQnO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoID09PSAwIHx8IGlucHV0cy5sZW5ndGggPiAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZWR1Y2Ugb3AgcmVxdWlyZXMgMSBvciAyIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAyICYmIGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBheGVzIGlucHV0IGRpbXMuJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVkdWNlQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIGtlZXBEaW1zOiBib29sZWFuO1xuICBub29wV2l0aEVtcHR5QXhlczogYm9vbGVhbjtcbiAgYXhlczogbnVtYmVyW107XG59XG5cbmV4cG9ydCB0eXBlIFJlZHVjZU9wID0gKFxuICBpbnB1dDogSW5kaWNlc0hlbHBlcixcbiAgb3V0cHV0OiBJbmRpY2VzSGVscGVyLFxuICBheGVzOiByZWFkb25seSBudW1iZXJbXSxcbikgPT4gW3N0cmluZywgc3RyaW5nLCBzdHJpbmcsIHN0cmluZywgLi4uc3RyaW5nW11dO1xuXG5jb25zdCBub09wOiBSZWR1Y2VPcCA9IChpbnB1dCkgPT4gWycnLCAnJywgYHZhciB2YWx1ZSA9ICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9O2AsICcnXTtcbmV4cG9ydCBjb25zdCBjcmVhdGVSZWR1Y2VQcm9ncmFtSW5mbyA9IChcbiAgbmFtZTogc3RyaW5nLFxuICBzaGFkZXJDYWNoZTogUHJvZ3JhbVNoYWRlckNhY2hlSW5mbyxcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIHJlZHVjZU9wOiBSZWR1Y2VPcCxcbiAgYXhlc0lucHV0OiBudW1iZXJbXSxcbiAgb3V0cHV0RGF0YVR5cGU6IERhdGFUeXBlLFxuICBrZWVwRGltcyA9IGZhbHNlLFxuICBub29wV2l0aEVtcHR5QXhlcyA9IGZhbHNlLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZTogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbnB1dFJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgYXhlcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGVzKGF4ZXNJbnB1dCwgaW5wdXRSYW5rKTtcbiAgY29uc3QgcmVkdWNlT25BbGxBeGVzID0gIW5vb3BXaXRoRW1wdHlBeGVzICYmIGF4ZXMubGVuZ3RoID09PSAwO1xuICBpbnB1dFNoYXBlLmZvckVhY2goKGQsIGkpID0+IHtcbiAgICBpZiAocmVkdWNlT25BbGxBeGVzIHx8IGF4ZXMuaW5kZXhPZihpKSA+PSAwKSB7XG4gICAgICBpZiAoa2VlcERpbXMpIHtcbiAgICAgICAgb3V0cHV0U2hhcGUucHVzaCgxKTtcbiAgICAgIH0gLy8gZWxzZSB7IC8vIHNraXAgdGhpcyBheGlzfVxuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXRTaGFwZS5wdXNoKGQpO1xuICAgIH1cbiAgfSk7XG4gIGNvbnN0IG91dHB1dFJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGlkeENvcHk6IHN0cmluZ1tdID0gW107IC8vIGNvcHkgb3V0cHV0IGluZGV4ZXMgdG8gaW5wdXQgaW5kZXhlc1xuXG4gICAgY29uc3QgaW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdfQScsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRSYW5rKTtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0Jywgb3V0cHV0RGF0YVR5cGUsIG91dHB1dFJhbmspO1xuICAgIGNvbnN0IG9wcyA9IHJlZHVjZU9wKGlucHV0LCBvdXRwdXQsIGF4ZXMpO1xuICAgIGxldCByZWR1Y2VPcHMgPSBvcHNbMl07XG5cbiAgICBmb3IgKGxldCBrID0gMCwgbCA9IDA7IGsgPCBpbnB1dFJhbms7IGsrKykge1xuICAgICAgLy8gaWYgdGhpcyBheGlzIGlzIHJlZHVjZWRcbiAgICAgIGlmIChyZWR1Y2VPbkFsbEF4ZXMgfHwgYXhlcy5pbmRleE9mKGspID49IDApIHtcbiAgICAgICAgaWYgKGtlZXBEaW1zKSB7XG4gICAgICAgICAgbCsrO1xuICAgICAgICB9XG4gICAgICAgIC8vIGxvb3Agb3ZlciB0aGUgZC10aCBheGlzXG4gICAgICAgIHJlZHVjZU9wcyA9IGBmb3IodmFyIGoke2t9OiB1MzIgPSAwOyBqJHtrfSA8ICR7aW5wdXRTaGFwZVtrXX07IGoke2t9KyspIHtcbiAgICAgICAgICAgICAgICAgICR7b3BzWzJdLmluY2x1ZGVzKCdsYXN0X2luZGV4JykgPyBgbGV0IGxhc3RfaW5kZXggPSBqJHtrfTtgIDogJyd9XG4gICAgICAgICAgICAgICAgICAke2lucHV0LmluZGljZXNTZXQoJ2lucHV0X2luZGljZXMnLCBrLCBgaiR7a31gKX1cbiAgICAgICAgICAgICAgICAgICR7cmVkdWNlT3BzfVxuICAgICAgICAgICAgICAgIH1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWR4Q29weS5wdXNoKGAke2lucHV0LmluZGljZXNTZXQoJ2lucHV0X2luZGljZXMnLCBrLCBvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCBsKSl9O2ApO1xuICAgICAgICBsKys7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBgXG5cbiAgICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3JtKCdvdXRwdXRfc2l6ZScsICd1MzInKS5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCBvdXRwdXQpfVxuXG4gICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgICAgICAgdmFyIGlucHV0X2luZGljZXM6ICR7aW5wdXQudHlwZS5pbmRpY2VzfTtcbiAgICAgICAgICBsZXQgb3V0cHV0X2luZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG5cbiAgICAgICAgICAke2lkeENvcHkuam9pbignXFxuJyl9XG4gICAgICAgICAgJHtvcHNbMF19ICAgICAgIC8vIGluaXQgb3BzIGZvciByZWR1Y2UgbWF4L21pblxuICAgICAgICAgICR7b3BzWzFdfVxuICAgICAgICAgICR7cmVkdWNlT3BzfVxuICAgICAgICAgICR7b3BzWzNdfVxuICAgICAgICAgICR7b3BzLmxlbmd0aCA9PT0gNCA/IG91dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICd2YWx1ZScpIDogb3BzLnNsaWNlKDQpLmpvaW4oJ1xcbicpfVxuICAgICAgICB9YDtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIG5hbWUsXG4gICAgc2hhZGVyQ2FjaGUsXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IG91dHB1dERhdGFUeXBlIH1dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zOiBbXG4gICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgICAgIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0U2hhcGUsIG91dHB1dFNoYXBlKSxcbiAgICAgIF0sXG4gICAgfSksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUmVkdWNlQXR0cmlidXRlc0Zyb21JbnB1dHMgPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuKTogUmVkdWNlQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF4ZXM6IG51bWJlcltdID0gW107XG4gIGlmIChpbnB1dHNbMV0uZGltc1swXSA+IDApIHtcbiAgICBpbnB1dHNbMV0uZ2V0QmlnSW50NjRBcnJheSgpLmZvckVhY2goKHYpID0+IGF4ZXMucHVzaChOdW1iZXIodikpKTtcbiAgfVxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBheGVzLFxuICAgIGtlZXBEaW1zOiBhdHRyaWJ1dGVzLmtlZXBEaW1zLFxuICAgIG5vb3BXaXRoRW1wdHlBeGVzOiBhdHRyaWJ1dGVzLm5vb3BXaXRoRW1wdHlBeGVzLFxuICB9KTtcbn07XG5cbmNvbnN0IHJ1blJlZHVjZVByb2dyYW0gPSAoXG4gIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LFxuICBuYW1lOiBzdHJpbmcsXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4gIHJlZHVjZU9wOiBSZWR1Y2VPcCxcbik6IHZvaWQgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBjb250ZXh0LmlucHV0cztcbiAgY29uc3QgdXBkYXRlZEF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMgPVxuICAgIGlucHV0cy5sZW5ndGggPT09IDEgPyBhdHRyaWJ1dGVzIDogY3JlYXRlUmVkdWNlQXR0cmlidXRlc0Zyb21JbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcblxuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlUmVkdWNlUHJvZ3JhbUluZm8oXG4gICAgICBuYW1lLFxuICAgICAgeyBoaW50OiB1cGRhdGVkQXR0cmlidXRlcy5jYWNoZUtleSwgaW5wdXREZXBlbmRlbmNpZXM6IFsncmFuayddIH0sXG4gICAgICBbaW5wdXRzWzBdXSxcbiAgICAgIHVwZGF0ZWRBdHRyaWJ1dGVzLm5vb3BXaXRoRW1wdHlBeGVzICYmIHVwZGF0ZWRBdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoID09PSAwID8gbm9PcCA6IHJlZHVjZU9wLFxuICAgICAgdXBkYXRlZEF0dHJpYnV0ZXMuYXhlcyxcbiAgICAgIGlucHV0c1swXS5kYXRhVHlwZSxcbiAgICAgIHVwZGF0ZWRBdHRyaWJ1dGVzLmtlZXBEaW1zLFxuICAgICAgdXBkYXRlZEF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMsXG4gICAgKSxcbiAgICB7IGlucHV0czogWzBdIH0sXG4gICk7XG59O1xuXG5jb25zdCByZWR1Y2VMb2dTdW1OYWl2ZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dCwgb3V0cHV0KSA9PiBbXG4gICAgYHZhciB2YWx1ZSA9ICR7b3V0cHV0LnR5cGUuc3RvcmFnZX0oMCk7YCxcbiAgICAnJyxcbiAgICBgdmFsdWUgKz0gJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX07YCxcbiAgICAndmFsdWUgPSBsb2codmFsdWUpOycsXG4gIF07XG4gIHJ1blJlZHVjZVByb2dyYW0oY29udGV4dCwgJ1JlZHVjZUxvZ1N1bScsIGF0dHJpYnV0ZXMsIHJlZHVjZU9wKTtcbn07XG5cbmNvbnN0IHJlZHVjZUwxTmFpdmUgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXQsIG91dHB1dCkgPT4gW1xuICAgIGB2YXIgdmFsdWUgPSAke291dHB1dC50eXBlLnN0b3JhZ2V9KDApO2AsXG4gICAgJycsXG4gICAgYHZhbHVlICs9IGFicygke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpfSk7YCxcbiAgICAnJyxcbiAgXTtcbiAgcnVuUmVkdWNlUHJvZ3JhbShjb250ZXh0LCAnUmVkdWNlTDEnLCBhdHRyaWJ1dGVzLCByZWR1Y2VPcCk7XG59O1xuXG5jb25zdCByZWR1Y2VMMk5haXZlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKGlucHV0LCBvdXRwdXQpID0+IFtcbiAgICBgdmFyIHQgPSAke291dHB1dC50eXBlLnZhbHVlfSgwKTsgdmFyIHZhbHVlID0gJHtvdXRwdXQudHlwZS52YWx1ZX0oMCk7YCxcbiAgICAnJyxcbiAgICBgdCA9ICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9OyB2YWx1ZSArPSAodCAqIHQpO2AsXG4gICAgJ3ZhbHVlID0gc3FydCh2YWx1ZSk7JyxcbiAgXTtcbiAgcnVuUmVkdWNlUHJvZ3JhbShjb250ZXh0LCAnUmVkdWNlTDInLCBhdHRyaWJ1dGVzLCByZWR1Y2VPcCk7XG59O1xuXG5jb25zdCByZWR1Y2VMb2dTdW1FeHBOYWl2ZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dCwgb3V0cHV0KSA9PiBbXG4gICAgYHZhciB2YWx1ZSA9ICR7b3V0cHV0LnR5cGUuc3RvcmFnZX0oMCk7YCxcbiAgICAnJyxcbiAgICBgdmFsdWUgKz0gZXhwKCR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9KTtgLFxuICAgICd2YWx1ZSA9IGxvZyh2YWx1ZSk7JyxcbiAgXTtcbiAgcnVuUmVkdWNlUHJvZ3JhbShjb250ZXh0LCAnUmVkdWNlTG9nU3VtRXhwJywgYXR0cmlidXRlcywgcmVkdWNlT3ApO1xufTtcblxuY29uc3QgcmVkdWNlTWF4TmFpdmUgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXQsIF9vdXRwdXQsIGF4ZXMpID0+IHtcbiAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dC5yYW5rOyBrKyspIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZHhaZXJvLnB1c2goaW5wdXQuaW5kaWNlc1NldCgnaW5wdXRfaW5kaWNlcycsIGssIDApKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gW1xuICAgICAgYCR7aWR4WmVyby5qb2luKCdcXG4nKX1gLFxuICAgICAgYHZhciB2YWx1ZSA9ICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9O2AsXG4gICAgICBgdmFsdWUgPSBtYXgodmFsdWUsICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9KTtgLFxuICAgICAgJycsXG4gICAgXTtcbiAgfTtcbiAgcnVuUmVkdWNlUHJvZ3JhbShjb250ZXh0LCAnUmVkdWNlTWF4JywgYXR0cmlidXRlcywgcmVkdWNlT3ApO1xufTtcblxuY29uc3QgcmVkdWNlTWVhbk5haXZlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKGlucHV0LCBvdXRwdXQsIGF4ZXMpID0+IHtcbiAgICBsZXQgc2l6ZSA9IDEuMDtcbiAgICBmb3IgKGxldCBrID0gMDsgayA8IGlucHV0LnJhbms7IGsrKykge1xuICAgICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIC8vIFRPRE86IHRoaXMgZGVwZW5kcyBvbiB0aGUgaW5wdXQgZGltcy4gSWYgd2Ugd2FudCB0byB1c2UgdW5pZm9ybSwgdGhpcyBuZWVkIHRvIGJlIHVwZGF0ZWQuXG4gICAgICAgIHNpemUgKj0gY29udGV4dC5pbnB1dHNbMF0uZGltc1trXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gW1xuICAgICAgJ3ZhciBzdW0gPSBmMzIoMCk7JyxcbiAgICAgICcnLFxuICAgICAgYHN1bSArPSBmMzIoJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX0pO2AsXG4gICAgICBgbGV0IHZhbHVlID0gJHtvdXRwdXQudHlwZS52YWx1ZX0oc3VtIC8gJHtzaXplfSk7YCxcbiAgICBdO1xuICB9O1xuICBydW5SZWR1Y2VQcm9ncmFtKGNvbnRleHQsICdSZWR1Y2VNZWFuJywgYXR0cmlidXRlcywgcmVkdWNlT3ApO1xufTtcblxuY29uc3QgcmVkdWNlTWluTmFpdmUgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXQsIF9vdXRwdXQsIGF4ZXMpID0+IHtcbiAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dC5yYW5rOyBrKyspIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZHhaZXJvLnB1c2goYGlucHV0X2luZGljZXNbJHtrfV0gPSAwO2ApOyAvLyBmaXJzdCBlbGVtZW50XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFtcbiAgICAgIGAke2lkeFplcm8uam9pbignXFxuJyl9YCxcbiAgICAgIGB2YXIgdmFsdWUgPSAke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpfTtgLFxuICAgICAgYHZhbHVlID0gbWluKHZhbHVlLCAke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpfSk7YCxcbiAgICAgICcnLFxuICAgIF07XG4gIH07XG4gIHJ1blJlZHVjZVByb2dyYW0oY29udGV4dCwgJ1JlZHVjZU1pbicsIGF0dHJpYnV0ZXMsIHJlZHVjZU9wKTtcbn07XG5cbmNvbnN0IHJlZHVjZVByb2ROYWl2ZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dCwgb3V0cHV0KSA9PiBbXG4gICAgYHZhciB2YWx1ZSA9ICR7b3V0cHV0LnR5cGUuc3RvcmFnZX0oMSk7YCxcbiAgICAnJyxcbiAgICBgdmFsdWUgKj0gJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX07YCxcbiAgICAnJyxcbiAgXTtcbiAgcnVuUmVkdWNlUHJvZ3JhbShjb250ZXh0LCAnUmVkdWNlUHJvZCcsIGF0dHJpYnV0ZXMsIHJlZHVjZU9wKTtcbn07XG5cbmNvbnN0IHJlZHVjZVN1bU5haXZlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKGlucHV0LCBvdXRwdXQpID0+IFtcbiAgICBgdmFyIHZhbHVlID0gJHtvdXRwdXQudHlwZS5zdG9yYWdlfSgwKTtgLFxuICAgICcnLFxuICAgIGB2YWx1ZSArPSAke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpfTtgLFxuICAgICcnLFxuICBdO1xuICBydW5SZWR1Y2VQcm9ncmFtKGNvbnRleHQsICdSZWR1Y2VTdW0nLCBhdHRyaWJ1dGVzLCByZWR1Y2VPcCk7XG59O1xuXG5jb25zdCByZWR1Y2VTdW1TcXVhcmVOYWl2ZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dCwgb3V0cHV0KSA9PiBbXG4gICAgYHZhciB0ID0gJHtvdXRwdXQudHlwZS52YWx1ZX0oMCk7IHZhciB2YWx1ZSA9ICR7b3V0cHV0LnR5cGUudmFsdWV9KDApO2AsXG4gICAgJycsXG4gICAgYHQgPSAke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpfTsgdmFsdWUgKz0gdCAqIHQ7YCxcbiAgICAnJyxcbiAgXTtcbiAgcnVuUmVkdWNlUHJvZ3JhbShjb250ZXh0LCAnUmVkdWNlU3VtU3F1YXJlJywgYXR0cmlidXRlcywgcmVkdWNlT3ApO1xufTtcblxuY29uc3QgdXNlTmFpdmVSZWR1Y2VNZXRob2QgPSAoXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXhlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG5vb3BXaXRoRW1wdHlBeGVzOiBib29sZWFuLFxuKTogYm9vbGVhbiA9PiB7XG4gIGlmIChheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBub29wV2l0aEVtcHR5QXhlcztcbiAgfVxuXG4gIGxldCBvdXRwdXRTaXplID0gMTtcbiAgbGV0IHJlZHVjZVNpemUgPSAxO1xuICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBheGVzLmxlbmd0aDsgZGltKyspIHtcbiAgICBpZiAoYXhlcy5pbmRleE9mKGRpbSkgPT09IC0xKSB7XG4gICAgICBvdXRwdXRTaXplICo9IHNoYXBlW2RpbV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlZHVjZVNpemUgKj0gc2hhcGVbZGltXTtcbiAgICB9XG4gIH1cblxuICAvLyBUaGUgY29uZGl0aW9uIGRhdGEgaXMgdmVyeSByb3VnaCwgYWx0aG91Z2ggY29uc2lkZXJpbmcgdGhlIGNvdW50IG9mIEV4ZWN1dGlvbiBVbml0IChFVSksIHRoZSBwb3RlbnRpYWxcbiAgLy8gd29yayBncm91cHMgaW4gYSBFVSBhbmQgdGhlIGNvdW50cyBvZiBsb29wcyBpbiB0aGUgbmFpdmUgYW5kIHNoYXJlZCBtZXRob2RzLCBhbHNvIGRvaW5nIGV4cGVyaW1lbnRzXG4gIC8vIG9uIHNvbWUgbWFjaGluZXMuXG4gIHJldHVybiByZWR1Y2VTaXplIDwgMzIgJiYgb3V0cHV0U2l6ZSA+IDEwMjQ7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWVhbiA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAodXNlTmFpdmVSZWR1Y2VNZXRob2QoY29udGV4dC5pbnB1dHNbMF0uZGltcywgYXR0cmlidXRlcy5heGVzLCBhdHRyaWJ1dGVzLm5vb3BXaXRoRW1wdHlBeGVzKSkge1xuICAgIHJlZHVjZU1lYW5OYWl2ZShjb250ZXh0LCBhdHRyaWJ1dGVzKTtcbiAgfSBlbHNlIHtcbiAgICByZWR1Y2VNZWFuU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTDEgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgaWYgKHVzZU5haXZlUmVkdWNlTWV0aG9kKGNvbnRleHQuaW5wdXRzWzBdLmRpbXMsIGF0dHJpYnV0ZXMuYXhlcywgYXR0cmlidXRlcy5ub29wV2l0aEVtcHR5QXhlcykpIHtcbiAgICByZWR1Y2VMMU5haXZlKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9IGVsc2Uge1xuICAgIHJlZHVjZUwxU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTDIgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgaWYgKHVzZU5haXZlUmVkdWNlTWV0aG9kKGNvbnRleHQuaW5wdXRzWzBdLmRpbXMsIGF0dHJpYnV0ZXMuYXhlcywgYXR0cmlidXRlcy5ub29wV2l0aEVtcHR5QXhlcykpIHtcbiAgICByZWR1Y2VMMk5haXZlKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9IGVsc2Uge1xuICAgIHJlZHVjZUwyU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtRXhwID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICh1c2VOYWl2ZVJlZHVjZU1ldGhvZChjb250ZXh0LmlucHV0c1swXS5kaW1zLCBhdHRyaWJ1dGVzLmF4ZXMsIGF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMpKSB7XG4gICAgcmVkdWNlTG9nU3VtRXhwTmFpdmUoY29udGV4dCwgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVkdWNlTG9nU3VtRXhwU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWF4ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICh1c2VOYWl2ZVJlZHVjZU1ldGhvZChjb250ZXh0LmlucHV0c1swXS5kaW1zLCBhdHRyaWJ1dGVzLmF4ZXMsIGF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMpKSB7XG4gICAgcmVkdWNlTWF4TmFpdmUoY29udGV4dCwgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVkdWNlTWF4U2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWluID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICh1c2VOYWl2ZVJlZHVjZU1ldGhvZChjb250ZXh0LmlucHV0c1swXS5kaW1zLCBhdHRyaWJ1dGVzLmF4ZXMsIGF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMpKSB7XG4gICAgcmVkdWNlTWluTmFpdmUoY29udGV4dCwgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVkdWNlTWluU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlUHJvZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAodXNlTmFpdmVSZWR1Y2VNZXRob2QoY29udGV4dC5pbnB1dHNbMF0uZGltcywgYXR0cmlidXRlcy5heGVzLCBhdHRyaWJ1dGVzLm5vb3BXaXRoRW1wdHlBeGVzKSkge1xuICAgIHJlZHVjZVByb2ROYWl2ZShjb250ZXh0LCBhdHRyaWJ1dGVzKTtcbiAgfSBlbHNlIHtcbiAgICByZWR1Y2VQcm9kU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlU3VtID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICh1c2VOYWl2ZVJlZHVjZU1ldGhvZChjb250ZXh0LmlucHV0c1swXS5kaW1zLCBhdHRyaWJ1dGVzLmF4ZXMsIGF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMpKSB7XG4gICAgcmVkdWNlU3VtTmFpdmUoY29udGV4dCwgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVkdWNlU3VtU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlU3VtU3F1YXJlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICh1c2VOYWl2ZVJlZHVjZU1ldGhvZChjb250ZXh0LmlucHV0c1swXS5kaW1zLCBhdHRyaWJ1dGVzLmF4ZXMsIGF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMpKSB7XG4gICAgcmVkdWNlU3VtU3F1YXJlTmFpdmUoY29udGV4dCwgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVkdWNlU3VtU3F1YXJlU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICh1c2VOYWl2ZVJlZHVjZU1ldGhvZChjb250ZXh0LmlucHV0c1swXS5kaW1zLCBhdHRyaWJ1dGVzLmF4ZXMsIGF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMpKSB7XG4gICAgcmVkdWNlTG9nU3VtTmFpdmUoY29udGV4dCwgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVkdWNlTG9nU3VtU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vLyBUT0RPOiB0aGlzIGlzIHRoZSBzYW1lIG5haXZlIGltcGxlbWVudGF0aW9uIHdlIHVzZSBmb3IgcmVkdWNlIHRoYXQgaGFzXG4vLyBwZXJmb3JtYW5jZSBsaW1pdGF0aW9ucyB3aGVuIHRoZSByZWR1Y2VkIGF4aXMgaXMgbG9uZy4gTmVlZCB0byBhZGRcbi8vIGEgb3B0aW1pemVkIGNvZGVwYXRoIGZvciB0aGlzLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgY3JlYXRlUmVkdWNlUHJvZ3JhbUluZm8sIFJlZHVjZU9wIH0gZnJvbSAnLi9yZWR1Y2UnO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoID09PSAwIHx8IGlucHV0cy5sZW5ndGggPiAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBcmdNaW5NYXhPcCBvcCByZXF1aXJlcyAxIG9yIDIgaW5wdXRzLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0uZGF0YVR5cGUgIT09IERhdGFUeXBlLmZsb2F0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXJnTWluTWF4QXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIGtlZXBEaW1zOiBib29sZWFuO1xuICBheGlzOiBudW1iZXI7XG4gIHNlbGVjdExhc3RJbmRleDogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgYXJnTWluID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBcmdNaW5NYXhBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgYXJnTWluTWF4T3A6IFJlZHVjZU9wID0gKGlucHV0LCBvdXRwdXQsIGF4ZXMpID0+IHtcbiAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dC5yYW5rOyBrKyspIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZHhaZXJvLnB1c2goYGlucHV0X2luZGljZXNbJHtrfV0gPSAwO2ApOyAvLyBmaXJzdCBlbGVtZW50XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBbXG4gICAgICBgJHtpZHhaZXJvLmpvaW4oJ1xcbicpfWAsXG4gICAgICBgdmFyIHZhbHVlID0gJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX07XFxudmFyIGJlc3RfaW5kZXggOiBpMzIgPSAwO2AsXG4gICAgICBgaWYgKCR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9ICR7YXR0cmlidXRlcy5zZWxlY3RMYXN0SW5kZXggPiAwID8gJzw9JyA6ICc8J30gdmFsdWUpIHtcbiAgICAgICAgIHZhbHVlID0gJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX07XG4gICAgICAgICBiZXN0X2luZGV4ID0gaTMyKGxhc3RfaW5kZXgpO1xuICAgICAgIH1gLFxuICAgICAgJycsXG4gICAgICBvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAnYmVzdF9pbmRleCcpLFxuICAgIF07XG4gIH07XG5cbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZVJlZHVjZVByb2dyYW1JbmZvKFxuICAgICAgJ0FyZ01pbicsXG4gICAgICB7IGhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnXSB9LFxuICAgICAgW2NvbnRleHQuaW5wdXRzWzBdXSxcbiAgICAgIGFyZ01pbk1heE9wLFxuICAgICAgW2F0dHJpYnV0ZXMuYXhpc10sXG4gICAgICBEYXRhVHlwZS5pbnQ2NCxcbiAgICAgIGF0dHJpYnV0ZXMua2VlcERpbXMsXG4gICAgKSxcbiAgICB7IGlucHV0czogWzBdIH0sXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgYXJnTWF4ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBcmdNaW5NYXhBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgYXJnTWluTWF4T3A6IFJlZHVjZU9wID0gKGlucHV0LCBvdXRwdXQsIGF4ZXMpID0+IHtcbiAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dC5yYW5rOyBrKyspIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZHhaZXJvLnB1c2goYGlucHV0X2luZGljZXNbJHtrfV0gPSAwO2ApOyAvLyBmaXJzdCBlbGVtZW50XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBbXG4gICAgICBgJHtpZHhaZXJvLmpvaW4oJ1xcbicpfWAsXG4gICAgICBgdmFyIHZhbHVlID0gJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX07XFxudmFyIGJlc3RfaW5kZXggOiBpMzIgPSAwO2AsXG4gICAgICBgaWYgKCR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9ICR7YXR0cmlidXRlcy5zZWxlY3RMYXN0SW5kZXggPiAwID8gJz49JyA6ICc+J30gdmFsdWUpIHtcbiAgICAgICAgIHZhbHVlID0gJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX07XG4gICAgICAgICBiZXN0X2luZGV4ID0gaTMyKGxhc3RfaW5kZXgpO1xuICAgICAgIH1gLFxuICAgICAgJycsXG4gICAgICBvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAnYmVzdF9pbmRleCcpLFxuICAgIF07XG4gIH07XG5cbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZVJlZHVjZVByb2dyYW1JbmZvKFxuICAgICAgJ2FyZ01heCcsXG4gICAgICB7IGhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnXSB9LFxuICAgICAgW2NvbnRleHQuaW5wdXRzWzBdXSxcbiAgICAgIGFyZ01pbk1heE9wLFxuICAgICAgW2F0dHJpYnV0ZXMuYXhpc10sXG4gICAgICBEYXRhVHlwZS5pbnQ2NCxcbiAgICAgIGF0dHJpYnV0ZXMua2VlcERpbXMsXG4gICAgKSxcbiAgICB7IGlucHV0czogWzBdIH0sXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VBcmdNaW5NYXhBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogQXJnTWluTWF4QXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoYXR0cmlidXRlcyBhcyBPbWl0PEFyZ01pbk1heEF0dHJpYnV0ZXMsIGtleW9mIEF0dHJpYnV0ZVdpdGhDYWNoZUtleT4pO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBHcHVEYXRhVHlwZSwgUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3ksIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQge1xuICBnZXRNYXhDb21wb25lbnRzLFxuICBJbmRpY2VzSGVscGVyLFxuICBpbnB1dFZhcmlhYmxlLFxuICBvdXRwdXRWYXJpYWJsZSxcbiAgU2hhZGVySGVscGVyLFxuICB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUsXG4gIHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUsXG4gIFVuaWZvcm1EYXRhRWxlbWVudFR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBjb25zdCBlbnVtIEF0dGVudGlvblFrdkZvcm1hdCB7XG4gIHVua25vd24sIC8vIGVudW0gdmFsdWUgbm90IHNldCwgb3IgZGVwZW5kcyBvbiBxa3YgcHJvamVjdGlvbiBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzXG4gIHFrdkJOU0gsIC8vIGZvciBub24tcGFja2VkIHFrdiwgcGVybXV0ZWRcbiAgcWt2QlNOSCwgLy8gZm9yIG5vbi1wYWNrZWQgcWt2LCBub3QgcGVybXV0ZWQsIHVzZWQgYnkgbWVtb3J5IGVmZmljaWVudCBhdHRlbnRpb24gb3IgTXVsdGlIZWFkQXR0ZW50aW9uXG4gIHFrdkJTTjNILCAvLyBmb3IgVFJUIGZ1c2VkIGF0dGVudGlvbiwgcWt2IGFyZSBwYWNrZWRcbiAgcWt2Qk5TSHFrdkJTM05ILCAvLyBmb3IgVFJUIGZ1c2VkIGNhdXNhbCBhdHRlbnRpb24sIGRhdGEgaGFzIHR3byBmb3JtYXRzIChxa3YgaXMgM0JOU0gsIGdlbW1fYnVmZmVyIGlzIEJTM05IKVxuICBxS3ZCU05IeEJTTjJILCAvLyBmb3IgVFJUIGZ1c2VkIGNyb3NzIGF0dGVudGlvbiwga3YgYXJlIHBhY2tlZFxuICBxa3ZUTkgsIC8vIGZvciBtZW1vcnkgZWZmaWNpZW50IGF0dGVudGlvbiwgcWt2IGFyZSBub3QgcGFja2VkLCBhbmQgcGFkZGluZ3MgYXJlIHJlbW92ZWQuXG4gIHFrdlROM0gsIC8vIGZvciBUUlQgZnVzZWQgYXR0ZW50aW9uLCBxa3YgYXJlIHBhY2tlZCBhbmQgcGFkZGluZ3MgYXJlIHJlbW92ZWRcbn1cblxuZXhwb3J0IGNvbnN0IGVudW0gQXR0ZW50aW9uTWFza1R5cGUge1xuICBub25lLCAvLyBObyBtYXNrXG4gIG1hc2sxZEtleVNlcUxlbiwgLy8gW2JhdGNoX3NpemVdLCBrZXkgc2VxdWVuY2UgbGVuZ3RoXG4gIG1hc2sxZEVuZFN0YXJ0LCAvLyBbMiAqIGJhdGNoX3NpemVdIHdpdGggZW5kIHBvc2l0aW9ucyBhbmQgc3RhcnQgcG9zaXRpb25zXG4gIG1hc2sxREtleVNlcUxlblN0YXJ0LCAvLyBbMyAqIGJhdGNoX3NpemUgKyAyXSB3aXRoIFtrZXlfbGVuWzBdLCAuLi4sIGtleV9sZW5bYmF0Y2hfc2l6ZSAtIDFdLCBxdWVyeV9zdGFydFswXSxcbiAgLy8gLi4uLCBxdWVyeV9zdGFydFtiYXRjaF9zaXplIC0gMV0sIHF1ZXJ5X2VuZFtiYXRjaF9zaXplIC0gMV0sIGtleV9zdGFydFswXSwgLi4uLFxuICAvLyBrZXlfc3RhcnRbYmF0Y2hfc2l6ZSAtIDFdLCBrZXlfZW5kW2JhdGNoX3NpemUgLSAxXV1cbiAgbWFzazJkRHVtbXksIC8vIGR1bW15IG1hc2sgd2l0aCBzaGFwZSBbMSwgMV0gb3IgW2JhdGNoX3NpemUsIDFdLiBJdCBoYXMgc2FtZSBlZmZlY3QgYXMgbm8gbWFzay5cbiAgbWFzazJkS2V5UGFkZGluZywgLy8gW2JhdGNoX3NpemUsIHRvdGFsX3NlcXVlbmNlX2xlbmd0aF1cbiAgbWFzazNkQXR0ZW50aW9uLCAvLyBbYmF0Y2hfc2l6ZSwgc2VxdWVuY2VfbGVuZ3RoLCB0b3RhbF9zZXF1ZW5jZV9sZW5ndGhdXG4gIG1hc2s0ZE1lZ2F0cm9uLCAvLyBNZWdhdHJvbiBjYXVzYWwgbWFzayB3aXRoIHNoYXBlIFtiYXRjaF9zaXplLCAxLCBtYXhfc2VxdWVuY2VfbGVuZ3RoLCBtYXhfc2VxdWVuY2VfbGVuZ3RoXVxuICBtYXNrVW5rbm93bixcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBdHRlbnRpb25QYXJhbWV0ZXJzIHtcbiAgYmF0Y2hTaXplOiBudW1iZXI7XG4gIHNlcXVlbmNlTGVuZ3RoOiBudW1iZXI7XG4gIHBhc3RTZXF1ZW5jZUxlbmd0aDogbnVtYmVyO1xuICBrdlNlcXVlbmNlTGVuZ3RoOiBudW1iZXI7XG4gIHRvdGFsU2VxdWVuY2VMZW5ndGg6IG51bWJlcjtcbiAgbWF4U2VxdWVuY2VMZW5ndGg6IG51bWJlcjtcbiAgaW5wdXRIaWRkZW5TaXplOiBudW1iZXI7XG4gIGhpZGRlblNpemU6IG51bWJlcjtcbiAgdkhpZGRlblNpemU6IG51bWJlcjtcbiAgaGVhZFNpemU6IG51bWJlcjtcbiAgdkhlYWRTaXplOiBudW1iZXI7XG4gIG51bUhlYWRzOiBudW1iZXI7XG4gIGt2TnVtSGVhZHM/OiBudW1iZXI7XG4gIG5SZXBzPzogbnVtYmVyO1xuICBpc1VuaWRpcmVjdGlvbmFsPzogYm9vbGVhbjtcbiAgcGFzdFByZXNlbnRTaGFyZUJ1ZmZlcjogYm9vbGVhbjtcbiAgbWFza0ZpbHRlclZhbHVlPzogbnVtYmVyO1xuICBtYXNrVHlwZTogQXR0ZW50aW9uTWFza1R5cGU7XG4gIHNjYWxlOiBudW1iZXI7XG4gIGJyb2FkY2FzdFJlc1Bvc0JpYXM6IGJvb2xlYW47XG4gIHBhc3NQYXN0SW5LdjogYm9vbGVhbjtcbiAgcWt2Rm9ybWF0OiBBdHRlbnRpb25Ra3ZGb3JtYXQ7XG4gIHNvZnRjYXA/OiBudW1iZXI7XG4gIGRvUm90YXJ5PzogbnVtYmVyO1xuICByb3RhcnlJbnRlckxlYXZlZD86IG51bWJlcjtcbiAgc29tbW9vdGhTb2Z0bWF4PzogbnVtYmVyO1xuICBsb2NhbFdpbmRvd3NTaXplPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF0dGVudGlvbkF0dHJzIHtcbiAgbnVtSGVhZHM6IG51bWJlcjtcbiAgaXNVbmlkaXJlY3Rpb25hbDogbnVtYmVyO1xuICBtYXNrRmlsdGVyVmFsdWU6IG51bWJlcjtcbiAgc2NhbGU6IG51bWJlcjtcbiAgZG9Sb3Rhcnk6IG51bWJlcjtcbiAgcWt2SGlkZGVuU2l6ZXM6IG51bWJlcltdO1xuICBwYXN0UHJlc2VudFNoYXJlQnVmZmVyOiBib29sZWFuO1xufVxuXG5jb25zdCB2YWxpZGF0ZUF0dGVudGlvbklucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogQXR0ZW50aW9uQXR0cnMpOiBBdHRlbnRpb25QYXJhbWV0ZXJzID0+IHtcbiAgLy8gQWJicmV2aWF0aW9uIGFuZCBNZWFuaW5nczpcbiAgLy8gICBCOiAgICBiYXRjaF9zaXplXG4gIC8vICAgUzogICAgc2VxdWVuY2VfbGVuZ3RoIChpbnB1dCBzZXF1ZW5jZSBsZW5ndGggb2YgcXVlcnkpXG4gIC8vICAgUDogICAgcGFzdF9zZXF1ZW5jZV9sZW5ndGggKHBhc3Qgc2VxdWVuY2UgbGVuZ3RoIG9mIGtleSBvciB2YWx1ZSlcbiAgLy8gICBMOiAgICBrdl9zZXF1ZW5jZV9sZW5ndGggKGlucHV0IHNlcXVlbmNlIGxlbmd0aCBvZiBrZXkgb3IgdmFsdWUpXG4gIC8vICAgTTogICAgbWF4X3NlcXVlbmNlX2xlbmd0aFxuICAvLyAgIFQ6ICAgIHRvdGFsX3NlcXVlbmNlX2xlbmd0aCA9IHBhc3Rfc2VxdWVuY2VfbGVuZ3RoICsga3Zfc2VxdWVuY2VfbGVuZ3RoXG4gIC8vICAgTjogICAgbnVtX2hlYWRzXG4gIC8vICAgSDogICAgaGVhZCBzaXplIGZvciBRIGFuZCBLLCBha2EgcV9oZWFkX3NpemUgb3Iga19oZWFkX3NpemUgb3IgcWtfaGVhZF9zaXplXG4gIC8vICAgSF92OiAgdl9oZWFkX3NpemVcbiAgLy8gICBEX2k6ICBpbnB1dCBoaWRkZW4gc2l6ZVxuICAvLyAgIEQ6ICAgIGhpZGRlbiBzaXplIGZvciBRIGFuZCBLIChEID0gTiAqIEgpLCBha2EgcV9oaWRkZW5fc2l6ZSBvciBrX2hpZGRlbl9zaXplIG9yIHFrX2hpZGRlbl9zaXplXG4gIC8vICAgRF92OiAgdl9oaWRkZW5fc2l6ZSA9IG51bV9oZWFkcyAqIHZfaGVhZF9zaXplXG5cbiAgLy8gV2hlbiBwYXN0IHN0YXRlIGlzIHVzZWQsIFEsIEsgYW5kIFYgc2hvdWxkIGhhdmUgc2FtZSBoaWRkZW4gc2l6ZSAodW5sZXNzIHdlIHNwbGl0IGl0IGludG8gcGFzdF9rZXkgYW5kIHBhc3RfdmFsdWUpLlxuXG4gIC8vIElucHV0IHNoYXBlczpcbiAgLy8gICBpbnB1dCAgICAgICAgKFEvSy9WKSAgICA6IChCLCBTLCBEX2kpXG4gIC8vICAgd2VpZ2h0cyAgICAgIChRL0svVikgICAgOiAoRF9pLCBEICsgRCArIERfdilcbiAgLy8gICBiaWFzICAgICAgICAgKFEvSy9WKSAgICA6IChEICsgRCArIERfdilcbiAgLy8gICBtYXNrX2luZGV4ICAgICAgICAgICAgICA6IHNlZSBiZWxvd1xuICAvLyAgIHBhc3QgICAgICAgICAoSy9WKSAgICAgIDogKDIsIEIsIE4sIFAsIEgpIG9yIE5VTExcbiAgLy8gICBhdHRlbnRpb25fYmlhcyAgICAgICAgICA6IChCLCBOLCBTLCBUKSBvciBOVUxMXG5cbiAgLy8gRm9yIG1hc2tfaW5kZXgsIHRoZSBmb2xsb3dpbmcgc2hhcGVzIGFyZSBzdXBwb3J0ZWQ6XG4gIC8vICAgICBOVUxMLCAoQiwgMSksICgxLCAxKVxuICAvLyAgICAgKEIpLCAoMiAqIEIpLCAoMyAqIEIgKyAyKVxuICAvLyAgICAgKEIsIFQpXG4gIC8vICAgICAoQiwgUywgVClcbiAgLy8gICAgIChCLCAxLCBNLCBNKVxuICAvL1xuICAvLyBXaGVuIGEgbW9kZWwgaXMgcHJ1bmVkIChsaWtlIHNvbWUgYXR0ZW50aW9uIGhlYWRzIGFyZSByZW1vdmVkIGluIFEvSy9WKSwgaW5wdXRfaGlkZGVuX3NpemUgY291bGQgYmUgbGFyZ2VyXG4gIC8vIHRoYW4gaGlkZGVuIGRpbWVuc2lvbiBvZiBRLCBLIGFuZCBWLlxuXG4gIGNvbnN0IGlucHV0ID0gaW5wdXRzWzBdO1xuICBjb25zdCB3ZWlnaHRzID0gaW5wdXRzWzFdO1xuICBjb25zdCBiaWFzID0gaW5wdXRzWzJdO1xuICBjb25zdCBtYXNrSW5kZXggPSBpbnB1dHNbM107XG4gIGNvbnN0IHBhc3QgPSBpbnB1dHNbNF07XG4gIGNvbnN0IGF0dGVudGlvbkJpYXMgPSBpbnB1dHNbNV07XG5cbiAgaWYgKHBhc3QgJiYgYXR0ZW50aW9uQmlhcykge1xuICAgIHRocm93IG5ldyBFcnJvcignQXR0ZW50aW9uIGNhbm5vdCBoYXZlIGJvdGggcGFzdCBhbmQgYXR0ZW50aW9uX2JpYXMnKTtcbiAgfVxuXG4gIGlmIChpbnB1dC5kaW1zLmxlbmd0aCAhPT0gMykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJpbnB1dFwiIG11c3QgaGF2ZSAzIGRpbWVuc2lvbnMnKTtcbiAgfVxuXG4gIGNvbnN0IGJhdGNoU2l6ZSA9IGlucHV0LmRpbXNbMF07XG4gIGNvbnN0IHNlcXVlbmNlTGVuZ3RoID0gaW5wdXQuZGltc1sxXTtcbiAgY29uc3QgaW5wdXRIaWRkZW5TaXplID0gaW5wdXQuZGltc1syXTtcblxuICBpZiAoYmlhcy5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJiaWFzXCIgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAxIGRpbWVuc2lvbnMnKTtcbiAgfVxuXG4gIGlmICh3ZWlnaHRzLmRpbXMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcIndlaWdodHNcIiBpcyBleHBlY3RlZCB0byBoYXZlIDIgZGltZW5zaW9ucycpO1xuICB9XG5cbiAgaWYgKHdlaWdodHMuZGltc1swXSAhPT0gaW5wdXRIaWRkZW5TaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCAxIGRpbWVuc2lvbiAwIHNob3VsZCBoYXZlIHNhbWUgbGVuZ3RoIGFzIGRpbWVuc2lvbiAyIG9mIGlucHV0IDAnKTtcbiAgfVxuXG4gIGlmIChiaWFzLmRpbXNbMF0gIT09IHdlaWdodHMuZGltc1sxXSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJiaWFzXCIgZGltZW5zaW9uIDAgc2hvdWxkIGhhdmUgc2FtZSBsZW5ndGggYXMgZGltZW5zaW9uIDEgb2YgaW5wdXQgXCJ3ZWlnaHRzXCInKTtcbiAgfVxuXG4gIGxldCBxSGlkZGVuU2l6ZSA9IGJpYXMuZGltc1swXSAvIDM7XG4gIGxldCBrSGlkZGVuU2l6ZSA9IHFIaWRkZW5TaXplO1xuICBsZXQgdkhpZGRlblNpemUgPSBrSGlkZGVuU2l6ZTtcbiAgaWYgKGF0dHJpYnV0ZXMucWt2SGlkZGVuU2l6ZXMubGVuZ3RoID4gMCkge1xuICAgIGlmIChhdHRyaWJ1dGVzLnFrdkhpZGRlblNpemVzLmxlbmd0aCAhPT0gMykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdxa3ZfaGlkZGVuX3NpemVzIGF0dHJpYnV0ZSBzaG91bGQgaGF2ZSAzIGVsZW1lbnRzJyk7XG4gICAgfVxuICAgIGZvciAoY29uc3Qgc3ogb2YgYXR0cmlidXRlcy5xa3ZIaWRkZW5TaXplcykge1xuICAgICAgaWYgKHN6ICUgYXR0cmlidXRlcy5udW1IZWFkcyAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Frdl9oaWRkZW5fc2l6ZXMgc2hvdWxkIGJlIGRpdmlzaWJsZSBieSBudW1faGVhZHMnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBxSGlkZGVuU2l6ZSA9IGF0dHJpYnV0ZXMucWt2SGlkZGVuU2l6ZXNbMF07XG4gICAga0hpZGRlblNpemUgPSBhdHRyaWJ1dGVzLnFrdkhpZGRlblNpemVzWzFdO1xuICAgIHZIaWRkZW5TaXplID0gYXR0cmlidXRlcy5xa3ZIaWRkZW5TaXplc1syXTtcbiAgfVxuXG4gIGNvbnN0IGt2U2VxdWVuY2VMZW5ndGggPSBzZXF1ZW5jZUxlbmd0aDtcblxuICBpZiAocUhpZGRlblNpemUgIT09IGtIaWRkZW5TaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdxa3ZfaGlkZGVuX3NpemVzIGZpcnN0IGVsZW1lbnQgc2hvdWxkIGJlIHNhbWUgYXMgdGhlIHNlY29uZCcpO1xuICB9XG5cbiAgaWYgKGJpYXMuZGltc1swXSAhPT0gcUhpZGRlblNpemUgKyBrSGlkZGVuU2l6ZSArIHZIaWRkZW5TaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcImJpYXNcIiBkaW1lbnNpb24gMCBzaG91bGQgaGF2ZSBzYW1lIGxlbmd0aCBhcyBzdW0gb2YgUS9LL1YgaGlkZGVuIHNpemVzJyk7XG4gIH1cblxuICBsZXQgcGFzdFNlcXVlbmNlTGVuZ3RoID0gMDtcbiAgaWYgKHBhc3QpIHtcbiAgICBpZiAoa0hpZGRlblNpemUgIT09IHZIaWRkZW5TaXplKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicGFzdFwiIGV4cGVjdCBrX2hpZGRlbl9zaXplID09IHZfaGlkZGVuX3NpemUnKTtcbiAgICB9XG4gICAgaWYgKHBhc3QuZGltcy5sZW5ndGggIT09IDUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0XCIgbXVzdCBoYXZlIDUgZGltZW5zaW9ucycpO1xuICAgIH1cbiAgICBpZiAocGFzdC5kaW1zWzBdICE9PSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicGFzdFwiIGZpcnN0IGRpbWVuc2lvbiBtdXN0IGJlIDInKTtcbiAgICB9XG4gICAgaWYgKHBhc3QuZGltc1sxXSAhPT0gYmF0Y2hTaXplKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicGFzdFwiIHNlY29uZCBkaW1lbnNpb24gbXVzdCBiZSBiYXRjaF9zaXplJyk7XG4gICAgfVxuICAgIGlmIChwYXN0LmRpbXNbMl0gIT09IGF0dHJpYnV0ZXMubnVtSGVhZHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0XCIgdGhpcmQgZGltZW5zaW9uIG11c3QgYmUgbnVtX2hlYWRzJyk7XG4gICAgfVxuICAgIGlmIChwYXN0LmRpbXNbNF0gIT09IGtIaWRkZW5TaXplIC8gYXR0cmlidXRlcy5udW1IZWFkcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcInBhc3RcIiBmaWZ0aCBkaW1lbnNpb24gbXVzdCBiZSBrX2hpZGRlbl9zaXplIC8gbnVtX2hlYWRzJyk7XG4gICAgfVxuXG4gICAgaWYgKCFhdHRyaWJ1dGVzLnBhc3RQcmVzZW50U2hhcmVCdWZmZXIpIHtcbiAgICAgIHBhc3RTZXF1ZW5jZUxlbmd0aCA9IHBhc3QuZGltc1szXTtcbiAgICB9XG4gICAgLy8gVE9ETzogaGFuZGxlIHBhc3Rfc2VxX2xlblxuICB9XG5cbiAgY29uc3QgdG90YWxTZXF1ZW5jZUxlbmd0aCA9IGt2U2VxdWVuY2VMZW5ndGggKyBwYXN0U2VxdWVuY2VMZW5ndGg7XG4gIGNvbnN0IG1heFNlcXVlbmNlTGVuZ3RoID0gLTE7XG5cbiAgY29uc3QgbWFza1R5cGUgPSBBdHRlbnRpb25NYXNrVHlwZS5ub25lO1xuICBpZiAobWFza0luZGV4KSB7XG4gICAgLy8gbWFza1R5cGUgPSBBdHRlbnRpb25NYXNrVHlwZS5NQVNLX1VOS05PV047XG4gICAgLy8gVE9ETzogaGFuZGxlIG1hc2tcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01hc2sgbm90IHN1cHBvcnRlZCcpO1xuICB9XG5cbiAgaWYgKHBhc3QpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Bhc3QgaXMgbm90IHN1cHBvcnRlZCcpO1xuICB9XG5cbiAgaWYgKGF0dGVudGlvbkJpYXMpIHtcbiAgICBpZiAoYXR0ZW50aW9uQmlhcy5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcImF0dGVudGlvbl9iaWFzXCIgbXVzdCBoYXZlIDQgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIC8vIFRPRE86IHN1cHBvcnQgYnJvYWRjYXN0aW5nIHRoZSBmaXJzdCBhbmQgc2Vjb25kIGRpbWVuc2lvbnMgb2YgYXR0ZW50aW9uX2JpYXNcbiAgICBpZiAoXG4gICAgICBhdHRlbnRpb25CaWFzLmRpbXNbMF0gIT09IGJhdGNoU2l6ZSB8fFxuICAgICAgYXR0ZW50aW9uQmlhcy5kaW1zWzFdICE9PSBhdHRyaWJ1dGVzLm51bUhlYWRzIHx8XG4gICAgICBhdHRlbnRpb25CaWFzLmRpbXNbMl0gIT09IHNlcXVlbmNlTGVuZ3RoIHx8XG4gICAgICBhdHRlbnRpb25CaWFzLmRpbXNbM10gIT09IHRvdGFsU2VxdWVuY2VMZW5ndGhcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0IFwiYXR0ZW50aW9uX2JpYXNcIiBzaGFwZSAoYmF0Y2hfc2l6ZSwgbnVtX2hlYWRzLCBzZXF1ZW5jZV9sZW5ndGgsIHRvdGFsX3NlcXVlbmNlX2xlbmd0aCknKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJhdGNoU2l6ZSxcbiAgICBzZXF1ZW5jZUxlbmd0aCxcbiAgICBwYXN0U2VxdWVuY2VMZW5ndGgsXG4gICAga3ZTZXF1ZW5jZUxlbmd0aCxcbiAgICB0b3RhbFNlcXVlbmNlTGVuZ3RoLFxuICAgIG1heFNlcXVlbmNlTGVuZ3RoLFxuICAgIGlucHV0SGlkZGVuU2l6ZSxcbiAgICBoaWRkZW5TaXplOiBxSGlkZGVuU2l6ZSxcbiAgICB2SGlkZGVuU2l6ZSxcbiAgICBoZWFkU2l6ZTogTWF0aC5mbG9vcihxSGlkZGVuU2l6ZSAvIGF0dHJpYnV0ZXMubnVtSGVhZHMpLFxuICAgIHZIZWFkU2l6ZTogTWF0aC5mbG9vcih2SGlkZGVuU2l6ZSAvIGF0dHJpYnV0ZXMubnVtSGVhZHMpLFxuICAgIG51bUhlYWRzOiBhdHRyaWJ1dGVzLm51bUhlYWRzLFxuICAgIGlzVW5pZGlyZWN0aW9uYWw6IGZhbHNlLFxuICAgIHBhc3RQcmVzZW50U2hhcmVCdWZmZXI6IGZhbHNlLFxuICAgIG1hc2tGaWx0ZXJWYWx1ZTogYXR0cmlidXRlcy5tYXNrRmlsdGVyVmFsdWUsXG4gICAgbWFza1R5cGUsXG4gICAgc2NhbGU6IGF0dHJpYnV0ZXMuc2NhbGUsXG4gICAgYnJvYWRjYXN0UmVzUG9zQmlhczogZmFsc2UsXG4gICAgcGFzc1Bhc3RJbkt2OiBmYWxzZSxcbiAgICBxa3ZGb3JtYXQ6IEF0dGVudGlvblFrdkZvcm1hdC5xa3ZCTlNILFxuICB9O1xufTtcblxuY29uc3QgaW5pdFZhclN0dWIgPSAoXG4gIHNlcUxlbnNJbnB1dDogSW5kaWNlc0hlbHBlciB8IHVuZGVmaW5lZCxcbiAgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0OiBJbmRpY2VzSGVscGVyIHwgdW5kZWZpbmVkLFxuICBpbml0UGFzdFNlcXVlbmNlTGVuZ3RoOiBib29sZWFuLFxuKSA9PiB7XG4gIC8vIEluIHRoZSBjYXNlIG9mIEdRQSwgcmVkZWZpbmUgdG90YWxfc2VxdWVuY2VfbGVuZ3RoLCBwcmVzZW50X3NlcXVlbmNlX2xlbmd0aCBhbmQgcGFzdF9zZXF1ZW5jZV9sZW5ndGggYmFzZWQgb24gc2VxbGVuX2sgaW5wdXRcbiAgaWYgKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCAmJiBzZXFMZW5zSW5wdXQpIHtcbiAgICByZXR1cm4gYFxuICAgICAgbGV0IHRvdGFsX3NlcXVlbmNlX2xlbmd0aF9pbnB1dCA9IHUzMigke3RvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dC5nZXRCeU9mZnNldCgnMCcpfSk7XG4gICAgICBsZXQgcHJlc2VudF9zZXF1ZW5jZV9sZW5ndGggPSBtYXgodG90YWxfc2VxdWVuY2VfbGVuZ3RoX2lucHV0LCB1bmlmb3Jtcy5wYXN0X3NlcXVlbmNlX2xlbmd0aCk7XG4gICAgICBsZXQgaXNfc3Vic2VxdWVudF9wcm9tcHQ6IGJvb2wgPSBzZXF1ZW5jZV9sZW5ndGggPiAxICYmIHNlcXVlbmNlX2xlbmd0aCAhPSB0b3RhbF9zZXF1ZW5jZV9sZW5ndGhfaW5wdXQ7XG4gICAgICBsZXQgaXNfZmlyc3RfcHJvbXB0OiBib29sID0gaXNfc3Vic2VxdWVudF9wcm9tcHQgPT0gZmFsc2UgJiYgc2VxdWVuY2VfbGVuZ3RoID09IHRvdGFsX3NlcXVlbmNlX2xlbmd0aF9pbnB1dDtcbiAgICAgIHRvdGFsX3NlcXVlbmNlX2xlbmd0aCA9IHUzMigke3NlcUxlbnNJbnB1dD8uZ2V0QnlPZmZzZXQoJ2JhdGNoSWR4Jyl9KSArIDE7XG4gICAgICB2YXIgcGFzdF9zZXF1ZW5jZV9sZW5ndGg6IHUzMiA9IDA7XG4gICAgICBpZiAoaXNfZmlyc3RfcHJvbXB0ID09IGZhbHNlKSB7XG4gICAgICAgIHBhc3Rfc2VxdWVuY2VfbGVuZ3RoID0gdG90YWxfc2VxdWVuY2VfbGVuZ3RoIC0gc2VxdWVuY2VfbGVuZ3RoO1xuICAgICAgfVxuICAgICAgIGA7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGBcbiAgICAke2luaXRQYXN0U2VxdWVuY2VMZW5ndGggPyAnbGV0IHBhc3Rfc2VxdWVuY2VfbGVuZ3RoID0gdW5pZm9ybXMucGFzdF9zZXF1ZW5jZV9sZW5ndGgnIDogJyd9O1xuICAgIGxldCBwcmVzZW50X3NlcXVlbmNlX2xlbmd0aCA9IHRvdGFsX3NlcXVlbmNlX2xlbmd0aDtcbiAgICBgO1xuICB9XG59O1xuXG5jb25zdCBjcmVhdGVJblBsYWNlU29mdG1heFByb2dyYW1JbmZvID0gKFxuICBpbnB1dDogVGVuc29yVmlldyxcbiAgYmF0Y2hTaXplOiBudW1iZXIsXG4gIG51bUhlYWRzOiBudW1iZXIsXG4gIHBhc3RTZXF1ZW5jZUxlbmd0aDogbnVtYmVyLFxuICBzZXF1ZW5jZUxlbmd0aDogbnVtYmVyLFxuICB0b3RhbFNlcXVlbmNlTGVuZ3RoOiBudW1iZXIsXG4gIHNlcUxlbnM6IFRlbnNvclZpZXcgfCB1bmRlZmluZWQsXG4gIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dDogVGVuc29yVmlldyB8IHVuZGVmaW5lZCxcbikgPT4ge1xuICAvLyBTZXQgY29tcG9uZW50cyB0byAxIGlmIHNlcUxlbnMgaXMgc3BlY2lmaWVkLCBpLmUuIEdyb3VwUXVlcnlBdHRlbnRpb24uXG4gIGNvbnN0IGNvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKHNlcUxlbnMgPyAxIDogdG90YWxTZXF1ZW5jZUxlbmd0aCk7XG4gIGxldCBXRyA9IDY0O1xuICBjb25zdCB0b3RhbFNlcXVlbmNlTGVuZ3RoQ29tcCA9IHRvdGFsU2VxdWVuY2VMZW5ndGggLyBjb21wb25lbnRzO1xuICBpZiAodG90YWxTZXF1ZW5jZUxlbmd0aENvbXAgPCBXRykge1xuICAgIFdHID0gMzI7XG4gIH1cbiAgY29uc3QgZWxlbWVudHNQZXJUaHJlYWQgPSBNYXRoLmNlaWwodG90YWxTZXF1ZW5jZUxlbmd0aCAvIGNvbXBvbmVudHMgLyBXRyk7XG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYmF0Y2hTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG51bUhlYWRzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHBhc3RTZXF1ZW5jZUxlbmd0aCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBzZXF1ZW5jZUxlbmd0aCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiB0b3RhbFNlcXVlbmNlTGVuZ3RoQ29tcCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBlbGVtZW50c1BlclRocmVhZCB9LFxuICBdO1xuICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZShpbnB1dC5kYXRhVHlwZSwgY29tcG9uZW50cyk7XG4gIGNvbnN0IGYzMlR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsVmFsdWVUeXBlKERhdGFUeXBlLmZsb2F0LCBjb21wb25lbnRzKTtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3R5cGUnXTtcbiAgaWYgKHNlcUxlbnMpIHtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCd0eXBlJyk7XG4gIH1cbiAgaWYgKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCkge1xuICAgIGlucHV0RGVwZW5kZW5jaWVzLnB1c2goJ3R5cGUnKTtcbiAgfVxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBpbnB1dEhlbHBlciA9IG91dHB1dFZhcmlhYmxlKCd4JywgaW5wdXQuZGF0YVR5cGUsIGlucHV0LmRpbXMsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGlucHV0SGVscGVycyA9IFtpbnB1dEhlbHBlcl07XG4gICAgY29uc3Qgc2VxTGVuc0lucHV0SGVscGVyID0gc2VxTGVucyA/IGlucHV0VmFyaWFibGUoJ3NlcV9sZW5zJywgc2VxTGVucy5kYXRhVHlwZSwgc2VxTGVucy5kaW1zKSA6IHVuZGVmaW5lZDtcbiAgICBpZiAoc2VxTGVuc0lucHV0SGVscGVyKSB7XG4gICAgICBpbnB1dEhlbHBlcnMucHVzaChzZXFMZW5zSW5wdXRIZWxwZXIpO1xuICAgIH1cblxuICAgIGNvbnN0IHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dEhlbHBlciA9IHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dFxuICAgICAgPyBpbnB1dFZhcmlhYmxlKCd0b3RhbF9zZXF1ZW5jZV9sZW5ndGhfaW5wdXQnLCB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQuZGF0YVR5cGUsIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dC5kaW1zKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gICAgaWYgKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dEhlbHBlcikge1xuICAgICAgaW5wdXRIZWxwZXJzLnB1c2godG90YWxTZXF1ZW5jZUxlbmd0aElucHV0SGVscGVyKTtcbiAgICB9XG4gICAgY29uc3QgZWxlbVZhbHVlVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoaW5wdXQuZGF0YVR5cGUpO1xuICAgIGNvbnN0IHVuaWZvcm1zOiBVbmlmb3Jtc0FycmF5VHlwZSA9IFtcbiAgICAgIHsgbmFtZTogJ2JhdGNoX3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnbnVtX2hlYWRzJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ3Bhc3Rfc2VxdWVuY2VfbGVuZ3RoJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ3NlcXVlbmNlX2xlbmd0aCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICd0b3RhbF9zZXF1ZW5jZV9sZW5ndGgnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnZWxlbWVudHNfcGVyX3RocmVhZCcsIHR5cGU6ICd1MzInIH0sXG4gICAgXTtcblxuICAgIHJldHVybiBgXG4gIHZhcjx3b3JrZ3JvdXA+IHRocmVhZF9tYXg6IGFycmF5PGYzMiwgJHtXR30+O1xuICB2YXI8d29ya2dyb3VwPiB0aHJlYWRfc3VtOiBhcnJheTxmMzIsICR7V0d9PjtcbiAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyguLi5pbnB1dEhlbHBlcnMpfVxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoW1dHLCAxLCAxXSl9XG4gICAgbGV0IGJhdGNoSWR4ID0gd29ya2dyb3VwX2lkLnogLyB1bmlmb3Jtcy5udW1faGVhZHM7XG4gICAgbGV0IGhlYWRJZHggPSB3b3JrZ3JvdXBfaWQueiAlIHVuaWZvcm1zLm51bV9oZWFkcztcbiAgICBsZXQgc2VxdWVuY2VfbGVuZ3RoID0gdW5pZm9ybXMuc2VxdWVuY2VfbGVuZ3RoO1xuICAgIHZhciB0b3RhbF9zZXF1ZW5jZV9sZW5ndGggPSB1bmlmb3Jtcy50b3RhbF9zZXF1ZW5jZV9sZW5ndGg7XG4gICAgJHtpbml0VmFyU3R1YihzZXFMZW5zSW5wdXRIZWxwZXIsIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dEhlbHBlciwgZmFsc2UpfVxuICAgIGxldCBsb2NhbF9vZmZzZXQgPSBsb2NhbF9pZHggKiB1bmlmb3Jtcy5lbGVtZW50c19wZXJfdGhyZWFkO1xuICAgIGxldCBvZmZzZXQgPSAoZ2xvYmFsX2lkeCAvICR7V0d9KSAqIHVuaWZvcm1zLnRvdGFsX3NlcXVlbmNlX2xlbmd0aCArIGxvY2FsX29mZnNldDtcbiAgICBsZXQgc2VxX2NhdXNhbF9sZW5ndGggPSAke3NlcUxlbnMgPyAndTMyKHBhc3Rfc2VxdWVuY2VfbGVuZ3RoICsgd29ya2dyb3VwX2lkLnkgKyAxKScgOiAndG90YWxfc2VxdWVuY2VfbGVuZ3RoJ307XG4gICAgdmFyIHRocmVhZF9tYXhfdmVjdG9yID0gJHtmMzJUeXBlfSgtMy40MDI4MjM0NjYzODUyODg2ZSszOGYpO1xuICAgIGZvciAodmFyIGk6IHUzMiA9IDA7IGkgPCB1bmlmb3Jtcy5lbGVtZW50c19wZXJfdGhyZWFkICYmIGkgKyBsb2NhbF9vZmZzZXQgPCBzZXFfY2F1c2FsX2xlbmd0aDsgaSsrKSB7XG4gICAgICB0aHJlYWRfbWF4X3ZlY3RvciA9IG1heCgke2YzMlR5cGV9KHhbb2Zmc2V0ICsgaV0pLCB0aHJlYWRfbWF4X3ZlY3Rvcik7XG4gICAgfVxuICAgIHRocmVhZF9tYXhbbG9jYWxfaWR4XSA9ICR7KCgpID0+IHtcbiAgICAgIHN3aXRjaCAoY29tcG9uZW50cykge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgcmV0dXJuICd0aHJlYWRfbWF4X3ZlY3Rvcic7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICByZXR1cm4gJ21heCh0aHJlYWRfbWF4X3ZlY3Rvci54LCB0aHJlYWRfbWF4X3ZlY3Rvci55KSc7XG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICByZXR1cm4gJ21heChtYXgodGhyZWFkX21heF92ZWN0b3IueCwgdGhyZWFkX21heF92ZWN0b3IueSksIG1heCh0aHJlYWRfbWF4X3ZlY3Rvci56LCB0aHJlYWRfbWF4X3ZlY3Rvci53KSknO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgY29tcG9uZW50czogJHtjb21wb25lbnRzfWApO1xuICAgICAgfVxuICAgIH0pKCl9O1xuICAgIHdvcmtncm91cEJhcnJpZXIoKTtcblxuICAgIHZhciBtYXhfdmFsdWUgPSAgZjMyKC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4Zik7XG4gICAgZm9yICh2YXIgaSA9IDB1OyBpIDwgJHtXR307IGkrKykge1xuICAgICAgbWF4X3ZhbHVlID0gbWF4KHRocmVhZF9tYXhbaV0sIG1heF92YWx1ZSk7XG4gICAgfVxuXG4gICAgdmFyIHN1bV92ZWN0b3IgPSAke2YzMlR5cGV9KDApO1xuICAgIGZvciAodmFyIGk6IHUzMiA9IDA7IGkgPCB1bmlmb3Jtcy5lbGVtZW50c19wZXJfdGhyZWFkICYmIGkgKyBsb2NhbF9vZmZzZXQgPCBzZXFfY2F1c2FsX2xlbmd0aDsgaSsrKSB7XG4gICAgICBzdW1fdmVjdG9yICs9IGV4cCgke2YzMlR5cGV9KHhbb2Zmc2V0ICsgaV0pIC0gbWF4X3ZhbHVlKTtcbiAgICB9XG4gICAgdGhyZWFkX3N1bVtsb2NhbF9pZHhdID0gJHsoKCkgPT4ge1xuICAgICAgc3dpdGNoIChjb21wb25lbnRzKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICByZXR1cm4gJ3N1bV92ZWN0b3InO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgcmV0dXJuICdzdW1fdmVjdG9yLnggKyBzdW1fdmVjdG9yLnknO1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgcmV0dXJuICdzdW1fdmVjdG9yLnggKyBzdW1fdmVjdG9yLnkgKyBzdW1fdmVjdG9yLnogKyBzdW1fdmVjdG9yLncnO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgY29tcG9uZW50czogJHtjb21wb25lbnRzfWApO1xuICAgICAgfVxuICAgIH0pKCl9O1xuICAgIHdvcmtncm91cEJhcnJpZXIoKTtcblxuICAgIHZhciBzdW06IGYzMiA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDB1OyBpIDwgJHtXR307IGkrKykge1xuICAgICAgc3VtICs9IHRocmVhZF9zdW1baV07XG4gICAgfVxuXG4gICAgaWYgKHN1bSA9PSAwKSB7XG4gICAgICBmb3IgKHZhciBpOiB1MzIgPSAwOyBpIDwgdW5pZm9ybXMuZWxlbWVudHNfcGVyX3RocmVhZCAmJiBpICsgbG9jYWxfb2Zmc2V0IDwgc2VxX2NhdXNhbF9sZW5ndGg7IGkrKykge1xuICAgICAgICB4W29mZnNldCArIGldID0gJHtpbnB1dEhlbHBlci50eXBlLnZhbHVlfSgke2VsZW1WYWx1ZVR5cGV9KDEuMCkgLyAke2VsZW1WYWx1ZVR5cGV9KHNlcV9jYXVzYWxfbGVuZ3RoKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAodmFyIGk6IHUzMiA9IDA7IGkgPCB1bmlmb3Jtcy5lbGVtZW50c19wZXJfdGhyZWFkICYmIGkgKyBsb2NhbF9vZmZzZXQgPCBzZXFfY2F1c2FsX2xlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBmMzJpbnB1dCA9ICR7ZjMyVHlwZX0oeFtvZmZzZXQgKyBpXSk7XG4gICAgICAgIHhbb2Zmc2V0ICsgaV0gPSAke2lucHV0SGVscGVyLnR5cGUudmFsdWV9KGV4cChmMzJpbnB1dCAtIG1heF92YWx1ZSkgLyBzdW0pO1xuICAgICAgfVxuICAgIH1cbiAgICAgICR7XG4gICAgICAgIHNlcUxlbnNcbiAgICAgICAgICA/IGBcbiAgICAgICAgZm9yICh2YXIgdG90YWxfc2VxX2lkOiB1MzIgPSBzZXFfY2F1c2FsX2xlbmd0aDsgdG90YWxfc2VxX2lkICsgbG9jYWxfb2Zmc2V0IDwgdW5pZm9ybXMudG90YWxfc2VxdWVuY2VfbGVuZ3RoOyB0b3RhbF9zZXFfaWQrKykge1xuICAgICAgICAgIHhbb2Zmc2V0ICsgdG90YWxfc2VxX2lkXSA9ICR7aW5wdXRIZWxwZXIudHlwZS52YWx1ZX0oJHtlbGVtVmFsdWVUeXBlfSgwKSk7XG4gICAgICAgIH1gXG4gICAgICAgICAgOiAnJ1xuICAgICAgfTtcbiAgfWA7XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnQXR0ZW50aW9uUHJvYnNTb2Z0bWF4JyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtXR307JHtkYXRhVHlwZX07JHtjb21wb25lbnRzfWAsIGlucHV0RGVwZW5kZW5jaWVzIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbXSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogMSwgeTogc2VxdWVuY2VMZW5ndGgsIHo6IGJhdGNoU2l6ZSAqIG51bUhlYWRzIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVBdHRlbnRpb25Qcm9ic1Byb2dyYW1JbmZvID0gKFxuICBvdXRwdXRDb3VudDogbnVtYmVyLFxuICBxOiBUZW5zb3JWaWV3LFxuICBrZXk6IFRlbnNvclZpZXcsXG4gIHBhc3RLZXk6IFRlbnNvclZpZXcgfCB1bmRlZmluZWQsXG4gIGF0dGVudGlvbkJpYXM6IFRlbnNvclZpZXcgfCB1bmRlZmluZWQsXG4gIHBhcmFtZXRlcnM6IEF0dGVudGlvblBhcmFtZXRlcnMsXG4gIHBhc3RTZXF1ZW5jZUxlbmd0aDogbnVtYmVyLFxuICBzZXFMZW5zOiBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkLFxuICB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQ6IFRlbnNvclZpZXcgfCB1bmRlZmluZWQsXG4pID0+IHtcbiAgY29uc3QgdG90YWxTZXF1ZW5jZUxlbmd0aCA9IHBhc3RTZXF1ZW5jZUxlbmd0aCArIHBhcmFtZXRlcnMua3ZTZXF1ZW5jZUxlbmd0aDtcbiAgY29uc3QgcHJvYnNTaGFwZSA9IFtwYXJhbWV0ZXJzLmJhdGNoU2l6ZSwgcGFyYW1ldGVycy5udW1IZWFkcywgcGFyYW1ldGVycy5zZXF1ZW5jZUxlbmd0aCwgdG90YWxTZXF1ZW5jZUxlbmd0aF07XG4gIGNvbnN0IHByZXNlbnRLZXkgPSBvdXRwdXRDb3VudCA+IDEgJiYgcGFzdEtleTtcbiAgY29uc3Qga3ZOdW1IZWFkcyA9IHBhcmFtZXRlcnMua3ZOdW1IZWFkcyA/IHBhcmFtZXRlcnMua3ZOdW1IZWFkcyA6IHBhcmFtZXRlcnMubnVtSGVhZHM7XG4gIGNvbnN0IHByZXNlbnRLZXlTaGFwZSA9IHByZXNlbnRLZXlcbiAgICA/IFtwYXJhbWV0ZXJzLmJhdGNoU2l6ZSwga3ZOdW1IZWFkcywgdG90YWxTZXF1ZW5jZUxlbmd0aCwgcGFyYW1ldGVycy5oZWFkU2l6ZV1cbiAgICA6IHVuZGVmaW5lZDtcbiAgY29uc3QgblJlcHMgPSBwYXJhbWV0ZXJzLm5SZXBzID8gcGFyYW1ldGVycy5uUmVwcyA6IDE7XG4gIC8vIFRPRE86IGhhbmRsZSBtYXNrXG5cbiAgY29uc3QgYWxwaGEgPSBwYXJhbWV0ZXJzLnNjYWxlID09PSAwID8gMS4wIC8gTWF0aC5zcXJ0KHBhcmFtZXRlcnMuaGVhZFNpemUpIDogcGFyYW1ldGVycy5zY2FsZTtcbiAgY29uc3QgY29tcG9uZW50cyA9IGdldE1heENvbXBvbmVudHMocGFyYW1ldGVycy5oZWFkU2l6ZSk7XG4gIGNvbnN0IHZlY3Rvcml6ZWRIZWFkU2l6ZSA9IHBhcmFtZXRlcnMuaGVhZFNpemUgLyBjb21wb25lbnRzO1xuICBjb25zdCBUSUxFX1NJWkUgPSAxMjtcbiAgY29uc3QgZGlzcGF0Y2ggPSB7XG4gICAgeDogTWF0aC5jZWlsKHRvdGFsU2VxdWVuY2VMZW5ndGggLyBUSUxFX1NJWkUpLFxuICAgIHk6IE1hdGguY2VpbChwYXJhbWV0ZXJzLnNlcXVlbmNlTGVuZ3RoIC8gVElMRV9TSVpFKSxcbiAgICB6OiBwYXJhbWV0ZXJzLmJhdGNoU2l6ZSAqIHBhcmFtZXRlcnMubnVtSGVhZHMsXG4gIH07XG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFyYW1ldGVycy5zZXF1ZW5jZUxlbmd0aCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiB2ZWN0b3JpemVkSGVhZFNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogdG90YWxTZXF1ZW5jZUxlbmd0aCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwYXJhbWV0ZXJzLm51bUhlYWRzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHBhcmFtZXRlcnMuaGVhZFNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmZsb2F0LCBkYXRhOiBhbHBoYSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwYXN0U2VxdWVuY2VMZW5ndGggfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFyYW1ldGVycy5rdlNlcXVlbmNlTGVuZ3RoIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG5SZXBzIH0sXG4gIF07XG4gIC8vIEZlZWQgcGFzdEtleSB0byB0aGUgc2hhZGVyLWNvZGUgb25seSBpZiBpdCBpcyBub24temVybyBhbmQgcHJlc2VudEtleSBpcyBiZWluZyBwcm9kdWNlZFxuICBjb25zdCBmZWVkUGFzdEtleSA9IHByZXNlbnRLZXkgJiYgcGFzdEtleSAmJiBTaGFwZVV0aWwuc2l6ZShwYXN0S2V5LmRpbXMpID4gMDtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3R5cGUnLCAndHlwZSddO1xuICBpZiAoZmVlZFBhc3RLZXkpIHtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCd0eXBlJyk7XG4gIH1cbiAgaWYgKGF0dGVudGlvbkJpYXMpIHtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCd0eXBlJyk7XG4gIH1cbiAgaWYgKHNlcUxlbnMpIHtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCd0eXBlJyk7XG4gIH1cbiAgaWYgKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCkge1xuICAgIGlucHV0RGVwZW5kZW5jaWVzLnB1c2goJ3R5cGUnKTtcbiAgfVxuICBjb25zdCBvdXRwdXRzID0gW3sgZGltczogcHJvYnNTaGFwZSwgZGF0YVR5cGU6IHEuZGF0YVR5cGUsIGdwdURhdGFUeXBlOiBHcHVEYXRhVHlwZS5kZWZhdWx0IH1dO1xuICBpZiAocHJlc2VudEtleSkge1xuICAgIG91dHB1dHMucHVzaCh7IGRpbXM6IHByZXNlbnRLZXlTaGFwZSEsIGRhdGFUeXBlOiBxLmRhdGFUeXBlLCBncHVEYXRhVHlwZTogR3B1RGF0YVR5cGUuZGVmYXVsdCB9KTtcbiAgfVxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBxSW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdxJywgcS5kYXRhVHlwZSwgcS5kaW1zLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBrSW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdrZXknLCBrZXkuZGF0YVR5cGUsIGtleS5kaW1zLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBpbnB1dFZhcnMgPSBbcUlucHV0LCBrSW5wdXRdO1xuICAgIGlmIChmZWVkUGFzdEtleSkge1xuICAgICAgY29uc3QgcGFzdEtleUlucHV0ID0gaW5wdXRWYXJpYWJsZSgncGFzdF9rZXknLCBwYXN0S2V5LmRhdGFUeXBlLCBwYXN0S2V5LmRpbXMsIGNvbXBvbmVudHMpO1xuICAgICAgaW5wdXRWYXJzLnB1c2gocGFzdEtleUlucHV0KTtcbiAgICB9XG4gICAgaWYgKGF0dGVudGlvbkJpYXMpIHtcbiAgICAgIGlucHV0VmFycy5wdXNoKGlucHV0VmFyaWFibGUoJ2F0dGVudGlvbl9iaWFzJywgYXR0ZW50aW9uQmlhcy5kYXRhVHlwZSwgYXR0ZW50aW9uQmlhcy5kaW1zKSk7XG4gICAgfVxuICAgIGNvbnN0IHNlcUxlbnNJbnB1dFZhcmlhYmxlID0gc2VxTGVucyA/IGlucHV0VmFyaWFibGUoJ3NlcV9sZW5zJywgc2VxTGVucy5kYXRhVHlwZSwgc2VxTGVucy5kaW1zKSA6IHVuZGVmaW5lZDtcbiAgICBpZiAoc2VxTGVuc0lucHV0VmFyaWFibGUpIHtcbiAgICAgIGlucHV0VmFycy5wdXNoKHNlcUxlbnNJbnB1dFZhcmlhYmxlKTtcbiAgICB9XG4gICAgY29uc3QgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0VmFyaWFibGUgPSB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXRcbiAgICAgID8gaW5wdXRWYXJpYWJsZSgndG90YWxfc2VxdWVuY2VfbGVuZ3RoX2lucHV0JywgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0LmRhdGFUeXBlLCB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQuZGltcylcbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIGlmICh0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXRWYXJpYWJsZSkge1xuICAgICAgaW5wdXRWYXJzLnB1c2godG90YWxTZXF1ZW5jZUxlbmd0aElucHV0VmFyaWFibGUpO1xuICAgIH1cbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgcS5kYXRhVHlwZSwgcHJvYnNTaGFwZSk7XG4gICAgY29uc3Qgb3V0cHV0VmFycyA9IFtvdXRwdXRdO1xuICAgIGlmIChwcmVzZW50S2V5KSB7XG4gICAgICBvdXRwdXRWYXJzLnB1c2gob3V0cHV0VmFyaWFibGUoJ3ByZXNlbnRfa2V5JywgcS5kYXRhVHlwZSwgcHJlc2VudEtleVNoYXBlISwgY29tcG9uZW50cykpO1xuICAgIH1cbiAgICBjb25zdCBmMzJUeXBlID0gdGVuc29yVHlwZVRvV3NnbFZhbHVlVHlwZShEYXRhVHlwZS5mbG9hdCwgY29tcG9uZW50cyk7XG5cbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdNJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ0snLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnTicsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdudW1faGVhZHMnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnaGVhZF9zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2FscGhhJywgdHlwZTogJ2YzMicgYXMgVW5pZm9ybURhdGFFbGVtZW50VHlwZSB9LFxuICAgICAgeyBuYW1lOiAncGFzdF9zZXF1ZW5jZV9sZW5ndGgnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAna3Zfc2VxdWVuY2VfbGVuZ3RoJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ25fcmVwcycsIHR5cGU6ICd1MzInIH0sXG4gICAgXTtcbiAgICByZXR1cm4gYFxuICBjb25zdCBUSUxFX1NJWkUgPSAke1RJTEVfU0laRX11O1xuXG4gIHZhcjx3b3JrZ3JvdXA+IHRpbGVROiBhcnJheTwke3FJbnB1dC50eXBlLnN0b3JhZ2V9LCAke1RJTEVfU0laRSAqIFRJTEVfU0laRX0+O1xuICB2YXI8d29ya2dyb3VwPiB0aWxlSzogYXJyYXk8JHtxSW5wdXQudHlwZS5zdG9yYWdlfSwgJHtUSUxFX1NJWkUgKiBUSUxFX1NJWkV9PjtcbiAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyguLi5pbnB1dFZhcnMsIC4uLm91dHB1dFZhcnMpfVxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoW1RJTEVfU0laRSwgVElMRV9TSVpFLCAxXSl9XG4gICAgLy8geCBob2xkcyB0aGUgTiBhbmQgeSBob2xkcyB0aGUgTVxuICAgIGxldCBoZWFkSWR4ID0gd29ya2dyb3VwX2lkLnogJSB1bmlmb3Jtcy5udW1faGVhZHM7XG4gICAgbGV0IGt2SGVhZElkeCA9ICR7blJlcHMgPT09IDEgPyAnaGVhZElkeCcgOiAnaGVhZElkeCAvIHVuaWZvcm1zLm5fcmVwcyd9O1xuICAgIGxldCBrdl9udW1faGVhZHMgPSAke25SZXBzID09PSAxID8gJ3VuaWZvcm1zLm51bV9oZWFkcycgOiAndW5pZm9ybXMubnVtX2hlYWRzIC8gdW5pZm9ybXMubl9yZXBzJ307XG4gICAgbGV0IGJhdGNoSWR4ID0gd29ya2dyb3VwX2lkLnogLyB1bmlmb3Jtcy5udW1faGVhZHM7XG4gICAgbGV0IG0gPSB3b3JrZ3JvdXBfaWQueSAqIFRJTEVfU0laRTtcbiAgICBsZXQgbiA9IHdvcmtncm91cF9pZC54ICogVElMRV9TSVpFO1xuICAgIGxldCBzZXF1ZW5jZV9sZW5ndGggPSB1bmlmb3Jtcy5NO1xuICAgIHZhciB0b3RhbF9zZXF1ZW5jZV9sZW5ndGggPSB1bmlmb3Jtcy5OO1xuICAgICR7aW5pdFZhclN0dWIoc2VxTGVuc0lucHV0VmFyaWFibGUsIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dFZhcmlhYmxlLCB0cnVlKX1cbiAgICBsZXQgYWJzS3ZIZWFkSWR4ID0gYmF0Y2hJZHggKiBrdl9udW1faGVhZHMgKyBrdkhlYWRJZHg7XG4gICAgbGV0IHFPZmZzZXQgPSB3b3JrZ3JvdXBfaWQueiAqIHVuaWZvcm1zLk0gKiB1bmlmb3Jtcy5LICsgbSAqIHVuaWZvcm1zLks7XG4gICAgJHtmZWVkUGFzdEtleSAmJiBwcmVzZW50S2V5ID8gJ2xldCBwYXN0S2V5T2Zmc2V0ID0gYWJzS3ZIZWFkSWR4ICogdW5pZm9ybXMucGFzdF9zZXF1ZW5jZV9sZW5ndGggKiB1bmlmb3Jtcy5LOycgOiAnJ307XG4gICAgbGV0IGtPZmZzZXQgPSBhYnNLdkhlYWRJZHggKiB1bmlmb3Jtcy5rdl9zZXF1ZW5jZV9sZW5ndGggKiB1bmlmb3Jtcy5LO1xuICAgICR7cHJlc2VudEtleSA/ICdsZXQgcHJlc2VudEtleU9mZnNldCA9IGFic0t2SGVhZElkeCAqIHVuaWZvcm1zLk4gKiB1bmlmb3Jtcy5LOycgOiAnJ31cbiAgICB2YXIgdmFsdWUgPSAke2YzMlR5cGV9KDApO1xuICAgIGZvciAodmFyIHc6IHUzMiA9IDB1OyB3IDwgdW5pZm9ybXMuSzsgdyArPSBUSUxFX1NJWkUpIHtcbiAgICAgIGlmIChnbG9iYWxfaWQueSA8IHVuaWZvcm1zLk0gJiYgdyArIGxvY2FsX2lkLnggPCB1bmlmb3Jtcy5LKSB7XG4gICAgICAgIHRpbGVRW1RJTEVfU0laRSAqIGxvY2FsX2lkLnkgKyBsb2NhbF9pZC54XSA9IHFbcU9mZnNldCArIGxvY2FsX2lkLnkgKiB1bmlmb3Jtcy5LICsgdyArIGxvY2FsX2lkLnhdO1xuICAgICAgfVxuICAgICAgaWYgKG4gKyBsb2NhbF9pZC55IDwgdW5pZm9ybXMuTiAmJiB3ICsgbG9jYWxfaWQueCA8IHVuaWZvcm1zLkspIHtcbiAgICAgICAgdmFyIGlkeCA9IFRJTEVfU0laRSAqIGxvY2FsX2lkLnkgKyBsb2NhbF9pZC54O1xuICAgICAgJHsoKCkgPT4ge1xuICAgICAgICBpZiAoZmVlZFBhc3RLZXkgJiYgcHJlc2VudEtleSkge1xuICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICAgIGlmIChuICsgbG9jYWxfaWQueSA8IHBhc3Rfc2VxdWVuY2VfbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGlsZUtbaWR4XSA9IHBhc3Rfa2V5W3Bhc3RLZXlPZmZzZXQgKyAobiArIGxvY2FsX2lkLnkpICogdW5pZm9ybXMuSyArIHcgKyBsb2NhbF9pZC54XTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChuICsgbG9jYWxfaWQueSAtIHBhc3Rfc2VxdWVuY2VfbGVuZ3RoIDwgdW5pZm9ybXMua3Zfc2VxdWVuY2VfbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGlsZUtbaWR4XSA9IGtleVtrT2Zmc2V0ICsgKG4gKyBsb2NhbF9pZC55IC0gcGFzdF9zZXF1ZW5jZV9sZW5ndGgpICogdW5pZm9ybXMuSyArIHcgKyBsb2NhbF9pZC54XTtcbiAgICAgICAgICAgICAgfWA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICBpZiAobiArIGxvY2FsX2lkLnkgPCB1bmlmb3Jtcy5rdl9zZXF1ZW5jZV9sZW5ndGgpIHtcbiAgICAgICAgICAgIHRpbGVLW2lkeF0gPSBrZXlba09mZnNldCArIChuICsgbG9jYWxfaWQueSkgKiB1bmlmb3Jtcy5LICsgdyArIGxvY2FsX2lkLnhdO1xuICAgICAgICAgIH1gO1xuICAgICAgICB9XG4gICAgICB9KSgpfVxuICAgICAgJHtcbiAgICAgICAgcHJlc2VudEtleVxuICAgICAgICAgID8gYGlmIChuICsgbG9jYWxfaWQueSA8IHByZXNlbnRfc2VxdWVuY2VfbGVuZ3RoKSB7XG4gICAgICAgIHByZXNlbnRfa2V5W3ByZXNlbnRLZXlPZmZzZXQgKyAobiArIGxvY2FsX2lkLnkpICogdW5pZm9ybXMuSyArIHcgKyBsb2NhbF9pZC54XSA9IHRpbGVLW2lkeF07XG4gICAgICB9YFxuICAgICAgICAgIDogJydcbiAgICAgIH1cbiAgICAgIH1cbiAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcblxuICAgICAgZm9yICh2YXIgazogdTMyID0gMHU7IGsgPCBUSUxFX1NJWkUgJiYgdytrIDwgdW5pZm9ybXMuSzsgaysrKSB7XG4gICAgICAgICAgdmFsdWUgKz0gJHtmMzJUeXBlfSh0aWxlUVtUSUxFX1NJWkUgKiBsb2NhbF9pZC55ICsga10gKiB0aWxlS1tUSUxFX1NJWkUgKiBsb2NhbF9pZC54ICsga10pO1xuICAgICAgfVxuXG4gICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gICAgfVxuXG4gICAgaWYgKGdsb2JhbF9pZC55IDwgdW5pZm9ybXMuTSAmJiBnbG9iYWxfaWQueCA8IHRvdGFsX3NlcXVlbmNlX2xlbmd0aCkge1xuICAgICAgbGV0IGhlYWRPZmZzZXQgPSB3b3JrZ3JvdXBfaWQueiAqIHVuaWZvcm1zLk0gKiB1bmlmb3Jtcy5OO1xuICAgICAgbGV0IG91dHB1dElkeCA9IGhlYWRPZmZzZXQgKyBnbG9iYWxfaWQueSAqIHVuaWZvcm1zLk4gKyBnbG9iYWxfaWQueDtcbiAgICAgIHZhciBzdW06IGYzMiA9ICR7KCgpID0+IHtcbiAgICAgICAgc3dpdGNoIChjb21wb25lbnRzKSB7XG4gICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgcmV0dXJuICd2YWx1ZSc7XG4gICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgcmV0dXJuICd2YWx1ZS54ICsgdmFsdWUueSc7XG4gICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgcmV0dXJuICd2YWx1ZS54ICsgdmFsdWUueSArIHZhbHVlLnogKyB2YWx1ZS53JztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBjb21wb25lbnRzOiAke2NvbXBvbmVudHN9YCk7XG4gICAgICAgIH1cbiAgICAgIH0pKCl9O1xuICAgICAgICBvdXRwdXRbb3V0cHV0SWR4XSA9ICR7b3V0cHV0LnR5cGUudmFsdWV9IChzdW0gKiB1bmlmb3Jtcy5hbHBoYSkgKyAke1xuICAgICAgICAgIGF0dGVudGlvbkJpYXMgPyAnYXR0ZW50aW9uX2JpYXNbb3V0cHV0SWR4XScgOiAnMC4wJ1xuICAgICAgICB9O1xuICAgIH1cbiAgfWA7XG4gIH07XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0F0dGVudGlvblByb2JzJyxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogYCR7Y29tcG9uZW50c307JHthdHRlbnRpb25CaWFzICE9PSB1bmRlZmluZWR9OyR7cGFzdEtleSAhPT0gdW5kZWZpbmVkfTske291dHB1dENvdW50fWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llcyxcbiAgICB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7IG91dHB1dHMsIGRpc3BhdGNoR3JvdXA6IGRpc3BhdGNoLCBwcm9ncmFtVW5pZm9ybXMgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlVnhBdHRlbnRpb25TY29yZVByb2dyYW1JbmZvID0gKFxuICBvdXRwdXRDb3VudDogbnVtYmVyLFxuICBwcm9iczogVGVuc29yVmlldyxcbiAgdjogVGVuc29yVmlldyxcbiAgcGFzdFZhbHVlOiBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkLFxuICBwYXJhbXM6IEF0dGVudGlvblBhcmFtZXRlcnMsXG4gIHBhc3RTZXF1ZW5jZUxlbmd0aDogbnVtYmVyLFxuICBzZXFMZW5zOiBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLFxuICB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQ6IFRlbnNvclZpZXcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4pID0+IHtcbiAgY29uc3QgdG90YWxTZXF1ZW5jZUxlbmd0aCA9IHBhc3RTZXF1ZW5jZUxlbmd0aCArIHBhcmFtcy5rdlNlcXVlbmNlTGVuZ3RoO1xuICBjb25zdCBuUmVwcyA9IHBhcmFtcy5uUmVwcyA/IHBhcmFtcy5uUmVwcyA6IDE7XG4gIGNvbnN0IHJlcGVhdGVkVkhpZGRlblNpemUgPSBwYXJhbXMudkhpZGRlblNpemUgKiBuUmVwcztcbiAgY29uc3QgcHJlc2VudFZhbHVlID0gb3V0cHV0Q291bnQgPiAxICYmIHBhc3RWYWx1ZTtcbiAgY29uc3Qga3ZOdW1IZWFkcyA9IHBhcmFtcy5rdk51bUhlYWRzID8gcGFyYW1zLmt2TnVtSGVhZHMgOiBwYXJhbXMubnVtSGVhZHM7XG4gIGNvbnN0IHByZXNlbnRWYWx1ZVNoYXBlID0gcHJlc2VudFZhbHVlXG4gICAgPyBbcGFyYW1zLmJhdGNoU2l6ZSwga3ZOdW1IZWFkcywgdG90YWxTZXF1ZW5jZUxlbmd0aCwgcGFyYW1zLmhlYWRTaXplXVxuICAgIDogdW5kZWZpbmVkO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFtwYXJhbXMuYmF0Y2hTaXplLCBwYXJhbXMuc2VxdWVuY2VMZW5ndGgsIHJlcGVhdGVkVkhpZGRlblNpemVdO1xuICBjb25zdCBUSUxFX1NJWkUgPSAxMjtcbiAgY29uc3QgZGlzcGF0Y2ggPSB7XG4gICAgeDogTWF0aC5jZWlsKHBhcmFtcy52SGVhZFNpemUgLyBUSUxFX1NJWkUpLFxuICAgIHk6IE1hdGguY2VpbChwYXJhbXMuc2VxdWVuY2VMZW5ndGggLyBUSUxFX1NJWkUpLFxuICAgIHo6IHBhcmFtcy5iYXRjaFNpemUgKiBwYXJhbXMubnVtSGVhZHMsXG4gIH07XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwYXJhbXMuc2VxdWVuY2VMZW5ndGggfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogdG90YWxTZXF1ZW5jZUxlbmd0aCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwYXJhbXMudkhlYWRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHBhcmFtcy5udW1IZWFkcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwYXJhbXMuaGVhZFNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcmVwZWF0ZWRWSGlkZGVuU2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwYXN0U2VxdWVuY2VMZW5ndGggfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFyYW1zLmt2U2VxdWVuY2VMZW5ndGggfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogblJlcHMgfSxcbiAgXTtcbiAgLy8gRmVlZCBwYXN0VmFsdWUgdG8gdGhlIHNoYWRlci1jb2RlIG9ubHkgaWYgaXQgaXMgbm9uLWVtcHR5IGFuZCBwcmVzZW50VmFsdWUgaXMgYmVpbmcgcHJvZHVjZWRcbiAgY29uc3QgZmVlZFBhc3RWYWx1ZSA9IHByZXNlbnRWYWx1ZSAmJiBwYXN0VmFsdWUgJiYgU2hhcGVVdGlsLnNpemUocGFzdFZhbHVlLmRpbXMpID4gMDtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3R5cGUnLCAndHlwZSddO1xuICBpZiAoZmVlZFBhc3RWYWx1ZSkge1xuICAgIGlucHV0RGVwZW5kZW5jaWVzLnB1c2goJ3R5cGUnKTtcbiAgfVxuICBpZiAoc2VxTGVucykge1xuICAgIGlucHV0RGVwZW5kZW5jaWVzLnB1c2goJ3R5cGUnKTtcbiAgfVxuICBpZiAodG90YWxTZXF1ZW5jZUxlbmd0aElucHV0KSB7XG4gICAgaW5wdXREZXBlbmRlbmNpZXMucHVzaCgndHlwZScpO1xuICB9XG4gIGNvbnN0IG91dHB1dHMgPSBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IHByb2JzLmRhdGFUeXBlLCBncHVEYXRhVHlwZTogR3B1RGF0YVR5cGUuZGVmYXVsdCB9XTtcbiAgaWYgKHByZXNlbnRWYWx1ZSkge1xuICAgIG91dHB1dHMucHVzaCh7IGRpbXM6IHByZXNlbnRWYWx1ZVNoYXBlISwgZGF0YVR5cGU6IHByb2JzLmRhdGFUeXBlLCBncHVEYXRhVHlwZTogR3B1RGF0YVR5cGUuZGVmYXVsdCB9KTtcbiAgfVxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBwcm9ic0hlbHBlciA9IGlucHV0VmFyaWFibGUoJ3Byb2JzJywgcHJvYnMuZGF0YVR5cGUsIHByb2JzLmRpbXMpO1xuICAgIGNvbnN0IHZIZWxwZXIgPSBpbnB1dFZhcmlhYmxlKCd2Jywgdi5kYXRhVHlwZSwgdi5kaW1zKTtcbiAgICBjb25zdCBpbnB1dFZhcnMgPSBbcHJvYnNIZWxwZXIsIHZIZWxwZXJdO1xuICAgIGlmIChmZWVkUGFzdFZhbHVlKSB7XG4gICAgICBpbnB1dFZhcnMucHVzaChpbnB1dFZhcmlhYmxlKCdwYXN0X3ZhbHVlJywgcGFzdFZhbHVlLmRhdGFUeXBlLCBwYXN0VmFsdWUuZGltcykpO1xuICAgIH1cbiAgICBjb25zdCBzZXFMZW5zSW5wdXRWYXJpYWJsZSA9IHNlcUxlbnMgPyBpbnB1dFZhcmlhYmxlKCdzZXFfbGVucycsIHNlcUxlbnMuZGF0YVR5cGUsIHNlcUxlbnMuZGltcykgOiB1bmRlZmluZWQ7XG4gICAgaWYgKHNlcUxlbnMpIHtcbiAgICAgIGlucHV0VmFycy5wdXNoKHNlcUxlbnNJbnB1dFZhcmlhYmxlISk7XG4gICAgfVxuICAgIGNvbnN0IHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dFZhcmlhYmxlID0gdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0XG4gICAgICA/IGlucHV0VmFyaWFibGUoJ3RvdGFsX3NlcXVlbmNlX2xlbmd0aF9pbnB1dCcsIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dC5kYXRhVHlwZSwgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0LmRpbXMpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICBpZiAodG90YWxTZXF1ZW5jZUxlbmd0aElucHV0KSB7XG4gICAgICBpbnB1dFZhcnMucHVzaCh0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXRWYXJpYWJsZSEpO1xuICAgIH1cbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgcHJvYnMuZGF0YVR5cGUsIG91dHB1dFNoYXBlKTtcbiAgICBjb25zdCBvdXRwdXRWYXJzID0gW291dHB1dF07XG4gICAgaWYgKHByZXNlbnRWYWx1ZSkge1xuICAgICAgb3V0cHV0VmFycy5wdXNoKG91dHB1dFZhcmlhYmxlKCdwcmVzZW50X3ZhbHVlJywgcHJvYnMuZGF0YVR5cGUsIHByZXNlbnRWYWx1ZVNoYXBlISkpO1xuICAgIH1cbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdNJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ0snLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnTicsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdudW1faGVhZHMnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnaGVhZF9zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ3ZfaGlkZGVuX3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAncGFzdF9zZXF1ZW5jZV9sZW5ndGgnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAna3Zfc2VxdWVuY2VfbGVuZ3RoJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ25fcmVwcycsIHR5cGU6ICd1MzInIH0sXG4gICAgXTtcbiAgICByZXR1cm4gYFxuICBjb25zdCBUSUxFX1NJWkUgPSAke1RJTEVfU0laRX11O1xuICB2YXI8d29ya2dyb3VwPiB0aWxlUTogYXJyYXk8JHtwcm9ic0hlbHBlci50eXBlLnZhbHVlfSwgJHtUSUxFX1NJWkUgKiBUSUxFX1NJWkV9PjtcbiAgdmFyPHdvcmtncm91cD4gdGlsZVY6IGFycmF5PCR7cHJvYnNIZWxwZXIudHlwZS52YWx1ZX0sICR7VElMRV9TSVpFICogVElMRV9TSVpFfT47XG4gICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJzLCAuLi5vdXRwdXRWYXJzKX1cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KFtUSUxFX1NJWkUsIFRJTEVfU0laRSwgMV0pfVxuICAgbGV0IGhlYWRJZHggPSB3b3JrZ3JvdXBfaWQueiAlIHVuaWZvcm1zLm51bV9oZWFkcztcbiAgIGxldCBiYXRjaElkeCA9IHdvcmtncm91cF9pZC56IC8gdW5pZm9ybXMubnVtX2hlYWRzO1xuICAgbGV0IGt2SGVhZElkeCA9ICR7blJlcHMgPT09IDEgPyAnaGVhZElkeCcgOiAnaGVhZElkeCAvIHVuaWZvcm1zLm5fcmVwcyd9O1xuICAgbGV0IGt2X251bV9oZWFkcyA9ICR7blJlcHMgPT09IDEgPyAndW5pZm9ybXMubnVtX2hlYWRzJyA6ICd1bmlmb3Jtcy5udW1faGVhZHMgLyB1bmlmb3Jtcy5uX3JlcHMnfTtcbiAgIGxldCBtID0gZ2xvYmFsX2lkLnk7XG4gICBsZXQgbiA9IGdsb2JhbF9pZC54O1xuICAgbGV0IHNlcXVlbmNlX2xlbmd0aCA9IHVuaWZvcm1zLk07XG4gICB2YXIgdG90YWxfc2VxdWVuY2VfbGVuZ3RoID0gdW5pZm9ybXMuSztcbiAgICR7aW5pdFZhclN0dWIoc2VxTGVuc0lucHV0VmFyaWFibGUsIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dFZhcmlhYmxlLCB0cnVlKX1cbiAgIGxldCBvZmZzZXRBID0gd29ya2dyb3VwX2lkLnogKiB1bmlmb3Jtcy5NICogdW5pZm9ybXMuSyArIG0gKiB1bmlmb3Jtcy5LO1xuICAgbGV0IGFic0t2SGVhZElkeCA9IGJhdGNoSWR4ICoga3ZfbnVtX2hlYWRzICsga3ZIZWFkSWR4OyAvLyBrdkhlYWRJZHggaXMgcmVsYXRpdmUgdG8gdGhlIGJhdGNoXG4gICAke2ZlZWRQYXN0VmFsdWUgJiYgcHJlc2VudFZhbHVlID8gJ2xldCBwYXN0VmFsdWVPZmZzZXQgPSBhYnNLdkhlYWRJZHggKiB1bmlmb3Jtcy5OICogdW5pZm9ybXMucGFzdF9zZXF1ZW5jZV9sZW5ndGggKyBuOycgOiAnJ307XG4gICBsZXQgdk9mZnNldCA9IGFic0t2SGVhZElkeCAqIHVuaWZvcm1zLk4gKiB1bmlmb3Jtcy5rdl9zZXF1ZW5jZV9sZW5ndGggKyBuO1xuICAgJHtwcmVzZW50VmFsdWUgPyAnbGV0IHByZXNlbnRWYWx1ZU9mZnNldCA9IGFic0t2SGVhZElkeCAqIHVuaWZvcm1zLk4gKiB1bmlmb3Jtcy5LICsgbjsnIDogJyd9XG4gICB2YXIgdmFsdWUgPSAke3Byb2JzSGVscGVyLnR5cGUuc3RvcmFnZX0oMCk7XG4gICBmb3IgKHZhciB3OiB1MzIgPSAwdTsgdyA8IHVuaWZvcm1zLks7IHcgKz0gVElMRV9TSVpFKSB7XG4gICAgICBpZiAobSA8IHVuaWZvcm1zLk0gJiYgdyArIGxvY2FsX2lkLnggPCB1bmlmb3Jtcy5LKSB7XG4gICAgICAgIHRpbGVRW1RJTEVfU0laRSAqIGxvY2FsX2lkLnkgKyBsb2NhbF9pZC54XSA9IHByb2JzW29mZnNldEEgKyB3ICsgbG9jYWxfaWQueF07XG4gICAgICB9XG4gICAgICBpZiAobiA8IHVuaWZvcm1zLk4gJiYgdyArIGxvY2FsX2lkLnkgPCB1bmlmb3Jtcy5LKSB7XG4gICAgICAgIHZhciBpZHggPSBUSUxFX1NJWkUgKiBsb2NhbF9pZC55ICsgbG9jYWxfaWQueDtcbiAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgIGlmIChmZWVkUGFzdFZhbHVlICYmIHByZXNlbnRWYWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgaWYgKHcgKyBsb2NhbF9pZC55IDwgcGFzdF9zZXF1ZW5jZV9sZW5ndGgpIHtcbiAgICAgICAgICB0aWxlVltpZHhdID0gcGFzdF92YWx1ZVtwYXN0VmFsdWVPZmZzZXQgKyAodyArIGxvY2FsX2lkLnkpICogdW5pZm9ybXMuTl07XG4gICAgICAgIH0gZWxzZSBpZiAodyArIGxvY2FsX2lkLnkgLSBwYXN0X3NlcXVlbmNlX2xlbmd0aCA8IHVuaWZvcm1zLmt2X3NlcXVlbmNlX2xlbmd0aCkge1xuICAgICAgICAgIHRpbGVWW2lkeF0gPSB2W3ZPZmZzZXQgKyAodyArIGxvY2FsX2lkLnkgLSBwYXN0X3NlcXVlbmNlX2xlbmd0aCkgKiB1bmlmb3Jtcy5OXTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICAgIGlmICh3ICsgbG9jYWxfaWQueSA8IHVuaWZvcm1zLmt2X3NlcXVlbmNlX2xlbmd0aCkge1xuICAgICAgICAgICAgICB0aWxlVltpZHhdID0gdlt2T2Zmc2V0ICsgKHcgKyBsb2NhbF9pZC55KSAqIHVuaWZvcm1zLk5dO1xuICAgICAgICAgICAgfWA7XG4gICAgICAgICAgfVxuICAgICAgICB9KSgpfVxuICAgICAgICAke1xuICAgICAgICAgIHByZXNlbnRWYWx1ZVxuICAgICAgICAgICAgPyBgXG4gICAgICAgICAgICBpZiAodyArIGxvY2FsX2lkLnkgPCBwcmVzZW50X3NlcXVlbmNlX2xlbmd0aCkge1xuICAgICAgICAgIHByZXNlbnRfdmFsdWVbcHJlc2VudFZhbHVlT2Zmc2V0ICsgKHcgKyBsb2NhbF9pZC55KSAqIHVuaWZvcm1zLk5dID0gdGlsZVZbaWR4XTtcbiAgICAgICAgfWBcbiAgICAgICAgICAgIDogJydcbiAgICAgICAgfVxuICAgICAgfVxuICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gICAgIGZvciAodmFyIGs6IHUzMiA9IDB1OyBrIDwgVElMRV9TSVpFICYmIHcrayA8IHRvdGFsX3NlcXVlbmNlX2xlbmd0aDsgaysrKSB7XG4gICAgICAgdmFsdWUgKz0gdGlsZVFbVElMRV9TSVpFICogbG9jYWxfaWQueSArIGtdICogdGlsZVZbVElMRV9TSVpFICogayArIGxvY2FsX2lkLnhdO1xuICAgICB9XG4gICAgIHdvcmtncm91cEJhcnJpZXIoKTtcbiAgIH1cblxuICAgLy8gd2UgbmVlZCB0byB0cmFuc3Bvc2Ugb3V0cHV0IGZyb20gQk5TSF92IHRvIEJTTkRfdlxuICAgaWYgKG0gPCB1bmlmb3Jtcy5NICYmIG4gPCB1bmlmb3Jtcy5OKSB7XG4gICAgIGxldCBvdXRwdXRJZHggPSBiYXRjaElkeCAqIHVuaWZvcm1zLk0gKiB1bmlmb3Jtcy52X2hpZGRlbl9zaXplICsgbSAqIHVuaWZvcm1zLnZfaGlkZGVuX3NpemVcbiAgICAgICArIGhlYWRJZHggKiB1bmlmb3Jtcy5OICsgbjtcbiAgICAgb3V0cHV0W291dHB1dElkeF0gPSB2YWx1ZTtcbiAgIH1cbiAgfWA7XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnQXR0ZW50aW9uU2NvcmUnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke3Bhc3RWYWx1ZSAhPT0gdW5kZWZpbmVkfTske291dHB1dENvdW50fWAsIGlucHV0RGVwZW5kZW5jaWVzIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHsgb3V0cHV0cywgZGlzcGF0Y2hHcm91cDogZGlzcGF0Y2gsIHByb2dyYW1Vbmlmb3JtcyB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgYXBwbHlBdHRlbnRpb24gPSAoXG4gIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LFxuICBxOiBUZW5zb3JWaWV3LFxuICBrOiBUZW5zb3JWaWV3LFxuICB2OiBUZW5zb3JWaWV3LFxuICBfbWFza0luZGV4OiBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkLFxuICBfcGFzdDogVGVuc29yVmlldyB8IHVuZGVmaW5lZCxcbiAgcGFzdEtleTogVGVuc29yVmlldyB8IHVuZGVmaW5lZCxcbiAgcGFzdFZhbHVlOiBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkLFxuICBhdHRlbnRpb25CaWFzSW5wdXQ6IFRlbnNvclZpZXcgfCB1bmRlZmluZWQsXG4gIHBhcmFtZXRlcnM6IEF0dGVudGlvblBhcmFtZXRlcnMsXG4gIHNlcUxlbnM6IFRlbnNvclZpZXcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4gIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dDogVGVuc29yVmlldyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZCxcbikgPT4ge1xuICAvLyBBc3N1bXB0aW9uIGlzIHRoYXQgcHJlc2VudEtleS9wcmVzZW50VmFsdWUgZXhpc3RzIG9ubHkgaWYgcGFzdEtleS9wYXN0VmFsdWUgZXhpc3RzLlxuICBjb25zdCBvdXRwdXRDb3VudCA9IE1hdGgubWluKGNvbnRleHQub3V0cHV0Q291bnQsIDEgKyAocGFzdEtleSA/IDEgOiAwKSArIChwYXN0VmFsdWUgPyAxIDogMCkpO1xuICAvLyBXaGVuIHRoZXJlIGFyZSBubyBwcmVzZW50IGtleS92YWx1ZSBvdXRwdXRzIChvdXRwdXRDb3VudCA8PSAxKSwgaWdub3JlIHBhc3QgdG8gbWF0Y2ggQ1BVIEVQIHNlbWFudGljcy5cbiAgY29uc3QgZWZmZWN0aXZlUGFzdEtleSA9IG91dHB1dENvdW50ID4gMSA/IHBhc3RLZXkgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IGVmZmVjdGl2ZVBhc3RWYWx1ZSA9IG91dHB1dENvdW50ID4gMSA/IHBhc3RWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgcGFzdFNlcXVlbmNlTGVuZ3RoID0gb3V0cHV0Q291bnQgPiAxID8gcGFyYW1ldGVycy5wYXN0U2VxdWVuY2VMZW5ndGggOiAwO1xuICBjb25zdCB0b3RhbFNlcXVlbmNlTGVuZ3RoID0gcGFzdFNlcXVlbmNlTGVuZ3RoICsgcGFyYW1ldGVycy5rdlNlcXVlbmNlTGVuZ3RoO1xuICBjb25zdCBhdHRlbnRpb25CaWFzID1cbiAgICBhdHRlbnRpb25CaWFzSW5wdXQgJiYgU2hhcGVVdGlsLnNpemUoYXR0ZW50aW9uQmlhc0lucHV0LmRpbXMpID4gMCA/IGF0dGVudGlvbkJpYXNJbnB1dCA6IHVuZGVmaW5lZDtcblxuICBjb25zdCBpbnB1dHNLID0gW3EsIGtdO1xuICBpZiAoZWZmZWN0aXZlUGFzdEtleSAmJiBTaGFwZVV0aWwuc2l6ZShlZmZlY3RpdmVQYXN0S2V5LmRpbXMpID4gMCkge1xuICAgIGlucHV0c0sucHVzaChlZmZlY3RpdmVQYXN0S2V5KTtcbiAgfVxuICBpZiAoYXR0ZW50aW9uQmlhcykge1xuICAgIGlucHV0c0sucHVzaChhdHRlbnRpb25CaWFzKTtcbiAgfVxuICBpZiAoc2VxTGVucykge1xuICAgIGlucHV0c0sucHVzaChzZXFMZW5zKTtcbiAgfVxuICBpZiAodG90YWxTZXF1ZW5jZUxlbmd0aElucHV0KSB7XG4gICAgaW5wdXRzSy5wdXNoKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCk7XG4gIH1cbiAgLy8gUnVuIEF0dGVudGlvblByb2JzXG4gIGNvbnN0IHByb2JzID0gY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZUF0dGVudGlvblByb2JzUHJvZ3JhbUluZm8oXG4gICAgICBvdXRwdXRDb3VudCxcbiAgICAgIHEsXG4gICAgICBrLFxuICAgICAgZWZmZWN0aXZlUGFzdEtleSxcbiAgICAgIGF0dGVudGlvbkJpYXMsXG4gICAgICBwYXJhbWV0ZXJzLFxuICAgICAgcGFzdFNlcXVlbmNlTGVuZ3RoLFxuICAgICAgc2VxTGVucyxcbiAgICAgIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCxcbiAgICApLFxuICAgIHsgaW5wdXRzOiBpbnB1dHNLLCBvdXRwdXRzOiBvdXRwdXRDb3VudCA+IDEgPyBbLTEsIDFdIDogWy0xXSB9LFxuICApWzBdO1xuXG4gIC8vIFJ1biBTb2Z0bWF4XG4gIGNvbnRleHQuY29tcHV0ZShcbiAgICBjcmVhdGVJblBsYWNlU29mdG1heFByb2dyYW1JbmZvKFxuICAgICAgcHJvYnMsXG4gICAgICBwYXJhbWV0ZXJzLmJhdGNoU2l6ZSxcbiAgICAgIHBhcmFtZXRlcnMubnVtSGVhZHMsXG4gICAgICBwYXN0U2VxdWVuY2VMZW5ndGgsXG4gICAgICBwYXJhbWV0ZXJzLnNlcXVlbmNlTGVuZ3RoLFxuICAgICAgdG90YWxTZXF1ZW5jZUxlbmd0aCxcbiAgICAgIHNlcUxlbnMsXG4gICAgICB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQsXG4gICAgKSxcbiAgICB7IGlucHV0czogc2VxTGVucyAmJiB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQgPyBbcHJvYnMsIHNlcUxlbnMsIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dF0gOiBbcHJvYnNdLCBvdXRwdXRzOiBbXSB9LFxuICApO1xuXG4gIC8vIFJ1biBBdHRlbnRpb25TY29yZVxuICBjb25zdCBpbnB1dHNWID0gW3Byb2JzLCB2XTtcbiAgaWYgKGVmZmVjdGl2ZVBhc3RWYWx1ZSAmJiBTaGFwZVV0aWwuc2l6ZShlZmZlY3RpdmVQYXN0VmFsdWUuZGltcykgPiAwKSB7XG4gICAgaW5wdXRzVi5wdXNoKGVmZmVjdGl2ZVBhc3RWYWx1ZSk7XG4gIH1cbiAgaWYgKHNlcUxlbnMpIHtcbiAgICBpbnB1dHNWLnB1c2goc2VxTGVucyk7XG4gIH1cbiAgaWYgKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCkge1xuICAgIGlucHV0c1YucHVzaCh0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQpO1xuICB9XG4gIGNvbnRleHQuY29tcHV0ZShcbiAgICBjcmVhdGVWeEF0dGVudGlvblNjb3JlUHJvZ3JhbUluZm8oXG4gICAgICBvdXRwdXRDb3VudCxcbiAgICAgIHByb2JzLFxuICAgICAgdixcbiAgICAgIGVmZmVjdGl2ZVBhc3RWYWx1ZSxcbiAgICAgIHBhcmFtZXRlcnMsXG4gICAgICBwYXN0U2VxdWVuY2VMZW5ndGgsXG4gICAgICBzZXFMZW5zLFxuICAgICAgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0LFxuICAgICksXG4gICAge1xuICAgICAgaW5wdXRzOiBpbnB1dHNWLFxuICAgICAgb3V0cHV0czogb3V0cHV0Q291bnQgPiAxID8gWzAsIDJdIDogWzBdLFxuICAgIH0sXG4gICk7XG59O1xuXG5jb25zdCBwcmVwYXJlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBwYXJhbWV0ZXJzOiBBdHRlbnRpb25QYXJhbWV0ZXJzKSA9PiB7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW3BhcmFtZXRlcnMuYmF0Y2hTaXplLCBwYXJhbWV0ZXJzLm51bUhlYWRzLCBwYXJhbWV0ZXJzLnNlcXVlbmNlTGVuZ3RoLCBwYXJhbWV0ZXJzLmhlYWRTaXplXTtcbiAgY29uc3QgTSA9IHBhcmFtZXRlcnMuc2VxdWVuY2VMZW5ndGg7XG4gIGNvbnN0IEsgPSBwYXJhbWV0ZXJzLmlucHV0SGlkZGVuU2l6ZTtcbiAgY29uc3QgTiA9IHBhcmFtZXRlcnMuaGVhZFNpemU7XG4gIGNvbnN0IFRJTEVfU0laRSA9IDEyO1xuICBjb25zdCBkaXNwYXRjaCA9IHtcbiAgICB4OiBNYXRoLmNlaWwocGFyYW1ldGVycy5oZWFkU2l6ZSAvIFRJTEVfU0laRSksXG4gICAgeTogTWF0aC5jZWlsKHBhcmFtZXRlcnMuc2VxdWVuY2VMZW5ndGggLyBUSUxFX1NJWkUpLFxuICAgIHo6IHBhcmFtZXRlcnMuYmF0Y2hTaXplICogcGFyYW1ldGVycy5udW1IZWFkcyxcbiAgfTtcbiAgY29uc3QgaW5wdXRzID0gW2NvbnRleHQuaW5wdXRzWzBdLCBjb250ZXh0LmlucHV0c1sxXSwgY29udGV4dC5pbnB1dHNbMl1dO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IE0gfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogSyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBOIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHBhcmFtZXRlcnMubnVtSGVhZHMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFyYW1ldGVycy5oZWFkU2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwYXJhbWV0ZXJzLmhpZGRlblNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFyYW1ldGVycy5oaWRkZW5TaXplICsgcGFyYW1ldGVycy5oaWRkZW5TaXplICsgcGFyYW1ldGVycy52SGlkZGVuU2l6ZSB9LFxuICBdO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IG91dHB1dFEgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0X3EnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlKTtcbiAgICBjb25zdCBvdXRwdXRLID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dF9rJywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZSk7XG4gICAgY29uc3Qgb3V0cHV0ViA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXRfdicsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUpO1xuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnaW5wdXQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0c1swXS5kaW1zKTtcbiAgICBjb25zdCB3ZWlnaHQgPSBpbnB1dFZhcmlhYmxlKCd3ZWlnaHQnLCBpbnB1dHNbMV0uZGF0YVR5cGUsIGlucHV0c1sxXS5kaW1zKTtcbiAgICBjb25zdCBiaWFzID0gaW5wdXRWYXJpYWJsZSgnYmlhcycsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMpO1xuICAgIGNvbnN0IGRhdGFUeXBlID0gaW5wdXQudHlwZS5zdG9yYWdlO1xuXG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnTScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdLJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ04nLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnbnVtX2hlYWRzJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2hlYWRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdoaWRkZW5fc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdsZGInLCB0eXBlOiAndTMyJyB9LFxuICAgIF07XG4gICAgcmV0dXJuIGBcbiAgY29uc3QgVElMRV9TSVpFID0gJHtUSUxFX1NJWkV9dTtcbiAgdmFyPHdvcmtncm91cD4gdGlsZUlucHV0OiBhcnJheTwke2RhdGFUeXBlfSwgJHtUSUxFX1NJWkUgKiBUSUxFX1NJWkV9PjtcbiAgdmFyPHdvcmtncm91cD4gdGlsZVdlaWdodFE6IGFycmF5PCR7ZGF0YVR5cGV9LCAke1RJTEVfU0laRSAqIFRJTEVfU0laRX0+O1xuICB2YXI8d29ya2dyb3VwPiB0aWxlV2VpZ2h0SzogYXJyYXk8JHtkYXRhVHlwZX0sICR7VElMRV9TSVpFICogVElMRV9TSVpFfT47XG4gIHZhcjx3b3JrZ3JvdXA+IHRpbGVXZWlnaHRWOiBhcnJheTwke2RhdGFUeXBlfSwgJHtUSUxFX1NJWkUgKiBUSUxFX1NJWkV9PjtcbiAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyhpbnB1dCwgd2VpZ2h0LCBiaWFzLCBvdXRwdXRRLCBvdXRwdXRLLCBvdXRwdXRWKX1cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KFtUSUxFX1NJWkUsIFRJTEVfU0laRSwgMV0pfVxuICAgIGxldCBiYXRjaEluZGV4ID0gd29ya2dyb3VwX2lkLnogLyB1bmlmb3Jtcy5udW1faGVhZHM7XG4gICAgbGV0IGhlYWROdW1iZXIgPSB3b3JrZ3JvdXBfaWQueiAlIHVuaWZvcm1zLm51bV9oZWFkcztcbiAgICBsZXQgbSA9IGdsb2JhbF9pZC55O1xuICAgIGxldCBuID0gZ2xvYmFsX2lkLng7XG5cbiAgICBsZXQgaW5wdXRPZmZzZXQgPSBiYXRjaEluZGV4ICogKHVuaWZvcm1zLk0gKiB1bmlmb3Jtcy5LKSArIG0gKiB1bmlmb3Jtcy5LO1xuICAgIGxldCBiaWFzT2Zmc2V0USA9IGhlYWROdW1iZXIgKiB1bmlmb3Jtcy5oZWFkX3NpemU7XG4gICAgbGV0IGJpYXNPZmZzZXRLID0gdW5pZm9ybXMuaGlkZGVuX3NpemUgKyBiaWFzT2Zmc2V0UTtcbiAgICBsZXQgYmlhc09mZnNldFYgPSB1bmlmb3Jtcy5oaWRkZW5fc2l6ZSArIGJpYXNPZmZzZXRLO1xuXG4gICAgdmFyIHZhbHVlUSA9ICR7ZGF0YVR5cGV9KDApO1xuICAgIHZhciB2YWx1ZUsgPSAke2RhdGFUeXBlfSgwKTtcbiAgICB2YXIgdmFsdWVWID0gJHtkYXRhVHlwZX0oMCk7XG4gICAgZm9yICh2YXIgdzogdTMyID0gMHU7IHcgPCB1bmlmb3Jtcy5LOyB3ICs9IFRJTEVfU0laRSkge1xuICAgICAgaWYgKG0gPCB1bmlmb3Jtcy5NICYmIHcgKyBsb2NhbF9pZC54IDwgdW5pZm9ybXMuSykge1xuICAgICAgICB0aWxlSW5wdXRbVElMRV9TSVpFICogbG9jYWxfaWQueSArIGxvY2FsX2lkLnhdID0gaW5wdXRbaW5wdXRPZmZzZXQgKyB3ICsgbG9jYWxfaWQueF07XG4gICAgICB9XG4gICAgICBpZiAobiA8IHVuaWZvcm1zLk4gJiYgdyArIGxvY2FsX2lkLnkgPCB1bmlmb3Jtcy5LKSB7XG4gICAgICAgIGxldCBvZmZzZXQgPSBuICsgKHcgKyBsb2NhbF9pZC55KSAqIHVuaWZvcm1zLmxkYjtcbiAgICAgICAgdGlsZVdlaWdodFFbVElMRV9TSVpFICogbG9jYWxfaWQueSArIGxvY2FsX2lkLnhdID0gd2VpZ2h0W2JpYXNPZmZzZXRRICsgb2Zmc2V0XTtcbiAgICAgICAgdGlsZVdlaWdodEtbVElMRV9TSVpFICogbG9jYWxfaWQueSArIGxvY2FsX2lkLnhdID0gd2VpZ2h0W2JpYXNPZmZzZXRLICsgb2Zmc2V0XTtcbiAgICAgICAgdGlsZVdlaWdodFZbVElMRV9TSVpFICogbG9jYWxfaWQueSArIGxvY2FsX2lkLnhdID0gd2VpZ2h0W2JpYXNPZmZzZXRWICsgb2Zmc2V0XTtcbiAgICAgIH1cbiAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcbiAgICAgIGZvciAodmFyIGs6IHUzMiA9IDB1OyBrPFRJTEVfU0laRSAmJiB3K2sgPCB1bmlmb3Jtcy5LOyBrKyspIHtcbiAgICAgICAgbGV0IGlucHV0VGlsZU9mZnNldCA9IFRJTEVfU0laRSAqIGxvY2FsX2lkLnkgKyBrO1xuICAgICAgICBsZXQgd2VpZ2h0VGlsZU9mZnNldCA9IFRJTEVfU0laRSAqIGsgKyBsb2NhbF9pZC54O1xuICAgICAgICB2YWx1ZVEgKz0gdGlsZUlucHV0W2lucHV0VGlsZU9mZnNldF0gKiB0aWxlV2VpZ2h0UVt3ZWlnaHRUaWxlT2Zmc2V0XTtcbiAgICAgICAgdmFsdWVLICs9IHRpbGVJbnB1dFtpbnB1dFRpbGVPZmZzZXRdICogdGlsZVdlaWdodEtbd2VpZ2h0VGlsZU9mZnNldF07XG4gICAgICAgIHZhbHVlViArPSB0aWxlSW5wdXRbaW5wdXRUaWxlT2Zmc2V0XSAqIHRpbGVXZWlnaHRWW3dlaWdodFRpbGVPZmZzZXRdO1xuICAgICAgfVxuXG4gICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gICAgfVxuXG4gICAgbGV0IGhlYWRPZmZzZXQgPSAobSAqIHVuaWZvcm1zLk4gKyBuKSAlIHVuaWZvcm1zLmhlYWRfc2l6ZTtcbiAgICB2YWx1ZVEgKz0gYmlhc1toZWFkT2Zmc2V0ICsgYmlhc09mZnNldFFdO1xuICAgIHZhbHVlSyArPSBiaWFzW2hlYWRPZmZzZXQgKyBiaWFzT2Zmc2V0S107XG4gICAgdmFsdWVWICs9IGJpYXNbaGVhZE9mZnNldCArIGJpYXNPZmZzZXRWXTtcblxuICAgIGxldCBvZmZzZXQgPSB3b3JrZ3JvdXBfaWQueiAqIHVuaWZvcm1zLk0gKiB1bmlmb3Jtcy5OO1xuICAgIGlmIChtIDwgdW5pZm9ybXMuTSAmJiBuIDwgdW5pZm9ybXMuTikge1xuICAgICAgbGV0IG91dHB1dElkeCA9IG9mZnNldCArIG0gKiB1bmlmb3Jtcy5OICsgbjtcbiAgICAgIG91dHB1dF9xW291dHB1dElkeF0gPSB2YWx1ZVE7XG4gICAgICBvdXRwdXRfa1tvdXRwdXRJZHhdID0gdmFsdWVLO1xuICAgICAgb3V0cHV0X3Zbb3V0cHV0SWR4XSA9IHZhbHVlVjtcbiAgICB9XG4gIH1gO1xuICB9O1xuXG4gIHJldHVybiBjb250ZXh0LmNvbXB1dGUoXG4gICAge1xuICAgICAgbmFtZTogJ0F0dGVudGlvblByZXBhcmUnLFxuICAgICAgc2hhZGVyQ2FjaGU6IHsgaW5wdXREZXBlbmRlbmNpZXM6IFsndHlwZScsICd0eXBlJywgJ3R5cGUnXSB9LFxuICAgICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHsgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSwgZ3B1RGF0YVR5cGU6IEdwdURhdGFUeXBlLmRlZmF1bHQgfSxcbiAgICAgICAgICB7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUsIGdwdURhdGFUeXBlOiBHcHVEYXRhVHlwZS5kZWZhdWx0IH0sXG4gICAgICAgICAgeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlLCBncHVEYXRhVHlwZTogR3B1RGF0YVR5cGUuZGVmYXVsdCB9LFxuICAgICAgICBdLFxuICAgICAgICBkaXNwYXRjaEdyb3VwOiBkaXNwYXRjaCxcbiAgICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgICAgfSksXG4gICAgICBnZXRTaGFkZXJTb3VyY2UsXG4gICAgfSxcbiAgICB7IGlucHV0cywgb3V0cHV0czogWy0xLCAtMSwgLTFdIH0sXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgYXR0ZW50aW9uID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBdHRlbnRpb25BdHRycyk6IHZvaWQgPT4ge1xuICBjb25zdCBwYXJhbXMgPSB2YWxpZGF0ZUF0dGVudGlvbklucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG5cbiAgY29uc3QgW3EsIGssIHZdID0gcHJlcGFyZShjb250ZXh0LCBwYXJhbXMpO1xuXG4gIHJldHVybiBhcHBseUF0dGVudGlvbihcbiAgICBjb250ZXh0LFxuICAgIHEsXG4gICAgayxcbiAgICB2LFxuICAgIGNvbnRleHQuaW5wdXRzWzRdLFxuICAgIHVuZGVmaW5lZCxcbiAgICB1bmRlZmluZWQsXG4gICAgdW5kZWZpbmVkLFxuICAgIGNvbnRleHQuaW5wdXRzWzVdLFxuICAgIHBhcmFtcyxcbiAgKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcywgZ2V0TWF4Q29tcG9uZW50cywgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciB9IGZyb20gJy4vY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBCYXRjaE5vcm1BdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgZXBzaWxvbjogbnVtYmVyO1xuICByZWFkb25seSBtb21lbnR1bTogbnVtYmVyO1xuICByZWFkb25seSBzcGF0aWFsOiBib29sZWFuO1xuICByZWFkb25seSB0cmFpbmluZ01vZGU6IGJvb2xlYW47XG4gIHJlYWRvbmx5IGZvcm1hdDogJ05IV0MnIHwgJ05DSFcnO1xuICByZWFkb25seSBvdXRwdXRDb3VudDogbnVtYmVyO1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogQmF0Y2hOb3JtQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSA1KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdCYXRjaE5vcm1hbGl6YXRpb24gcmVxdWlyZXMgNSBpbnB1dHMnKTtcbiAgfVxuXG4gIGNvbnN0IGNoZWNrU2hhcGVFcXVhbCA9IChhY3R1YWw6IHJlYWRvbmx5IG51bWJlcltdLCBleHBlY3RlZDogcmVhZG9ubHkgbnVtYmVyW10sIG1lc3NhZ2U6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IHIgPSBleHBlY3RlZC5sZW5ndGg7XG4gICAgaWYgKHIgIT09IGFjdHVhbC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHttZXNzYWdlfTogbnVtIGRpbWVuc2lvbnMgIT0gJHtyfWApO1xuICAgIH1cbiAgICBleHBlY3RlZC5mb3JFYWNoKCh2LCBpKSA9PiB7XG4gICAgICBpZiAodiAhPT0gYWN0dWFsW2ldKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHttZXNzYWdlfTogZGltWyR7aX1dIGRvIG5vdCBtYXRjaGApO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggPiAxKSB7XG4gICAgY29uc3Qgc2hhcGUgPVxuICAgICAgYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJ1xuICAgICAgICA/IGF0dHJpYnV0ZXMuc3BhdGlhbFxuICAgICAgICAgID8gaW5wdXRzWzBdLmRpbXMuc2xpY2UoLTEpXG4gICAgICAgICAgOiBpbnB1dHNbMF0uZGltcy5zbGljZSgtMSkuY29uY2F0KGlucHV0c1swXS5kaW1zLnNsaWNlKDEsIGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDEpKVxuICAgICAgICA6IGlucHV0c1swXS5kaW1zLnNsaWNlKDEsIGF0dHJpYnV0ZXMuc3BhdGlhbCA/IDIgOiB1bmRlZmluZWQpO1xuICAgIGNoZWNrU2hhcGVFcXVhbChpbnB1dHNbMV0uZGltcywgc2hhcGUsICdJbnZhbGlkIGlucHV0IHNjYWxlJyk7XG4gICAgY2hlY2tTaGFwZUVxdWFsKGlucHV0c1syXS5kaW1zLCBzaGFwZSwgJ0ludmFsaWQgaW5wdXQgQicpO1xuICAgIGNoZWNrU2hhcGVFcXVhbChpbnB1dHNbM10uZGltcywgc2hhcGUsICdJbnZhbGlkIGlucHV0IG1lYW4nKTtcbiAgICBjaGVja1NoYXBlRXF1YWwoaW5wdXRzWzRdLmRpbXMsIHNoYXBlLCAnSW52YWxpZCBpbnB1dCB2YXInKTtcbiAgfSBlbHNlIHtcbiAgICBjaGVja1NoYXBlRXF1YWwoaW5wdXRzWzFdLmRpbXMsIFsxXSwgJ0ludmFsaWQgaW5wdXQgc2NhbGUnKTtcbiAgICBjaGVja1NoYXBlRXF1YWwoaW5wdXRzWzJdLmRpbXMsIFsxXSwgJ0ludmFsaWQgaW5wdXQgQicpO1xuICAgIGNoZWNrU2hhcGVFcXVhbChpbnB1dHNbM10uZGltcywgWzFdLCAnSW52YWxpZCBpbnB1dCBtZWFuJyk7XG4gICAgY2hlY2tTaGFwZUVxdWFsKGlucHV0c1s0XS5kaW1zLCBbMV0sICdJbnZhbGlkIGlucHV0IHZhcicpO1xuICB9XG59O1xuXG5jb25zdCBjcmVhdGVCYXRjaE5vcm1JbmZlcmVuY2VQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IEJhdGNoTm9ybUF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHsgZXBzaWxvbiwgc3BhdGlhbCwgZm9ybWF0IH0gPSBhdHRyaWJ1dGVzO1xuICBjb25zdCB5U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgY29tcG9uZW50cyA9IHNwYXRpYWwgPyBnZXRNYXhDb21wb25lbnRzKHlTaGFwZVt5U2hhcGUubGVuZ3RoIC0gMV0pIDogMTtcbiAgY29uc3QgY0NvbXBvbmVudHMgPSBmb3JtYXQgPT09ICdOSFdDJyAmJiB5U2hhcGUubGVuZ3RoID4gMSA/IGNvbXBvbmVudHMgOiAxO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUoeVNoYXBlKSAvIGNvbXBvbmVudHM7XG4gIC8vIE9ubHkgc3VwcG9ydCB1bmlmb3JtcyBmb3Igb3BzZXQgdmVyc2lvbiA+PSA5IChzcGF0aWFsID0gdHJ1ZSkuXG4gIGNvbnN0IHVzZVNoYXBlc1VuaWZvcm1zID0gc3BhdGlhbDtcbiAgY29uc3Qgc2hhcGVPclJhbmsgPSB1c2VTaGFwZXNVbmlmb3JtcyA/IHlTaGFwZS5sZW5ndGggOiB5U2hhcGU7XG4gIGNvbnN0IHggPSBpbnB1dFZhcmlhYmxlKCd4JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dHNbMF0uZGltcywgY29tcG9uZW50cyk7XG4gIGNvbnN0IHNjYWxlID0gaW5wdXRWYXJpYWJsZSgnc2NhbGUnLCBpbnB1dHNbMV0uZGF0YVR5cGUsIGlucHV0c1sxXS5kaW1zLCBjQ29tcG9uZW50cyk7XG4gIGNvbnN0IGJpYXMgPSBpbnB1dFZhcmlhYmxlKCdiaWFzJywgaW5wdXRzWzJdLmRhdGFUeXBlLCBpbnB1dHNbMl0uZGltcywgY0NvbXBvbmVudHMpO1xuICBjb25zdCBpbnB1dE1lYW4gPSBpbnB1dFZhcmlhYmxlKCdpbnB1dE1lYW4nLCBpbnB1dHNbM10uZGF0YVR5cGUsIGlucHV0c1szXS5kaW1zLCBjQ29tcG9uZW50cyk7XG4gIGNvbnN0IGlucHV0VmFyID0gaW5wdXRWYXJpYWJsZSgnaW5wdXRWYXInLCBpbnB1dHNbNF0uZGF0YVR5cGUsIGlucHV0c1s0XS5kaW1zLCBjQ29tcG9uZW50cyk7XG4gIGNvbnN0IHkgPSBvdXRwdXRWYXJpYWJsZSgneScsIGlucHV0c1swXS5kYXRhVHlwZSwgc2hhcGVPclJhbmssIGNvbXBvbmVudHMpO1xuICAvLyBUT0RPOiBzdXBwb3J0IGlucHV0cyB3aXRoIGRpZmZlcmVudCBkYXRhIHR5cGUuIEN1cnJlbnQgd2UgbmVlZCB0byBtYWtlIHN1cmUgYWxsIGlucHV0cyBoYXZlIHRoZSBzYW1lIGRhdGEgdHlwZS5cbiAgLy8gT3RoZXJ3aXNlLCB0aGUgc2hhZGVyIGNvbXBpbGF0aW9uIHdpbGwgZmFpbC5cbiAgY29uc3QgY2FsY0NPZmZzZXQgPSAoKTogc3RyaW5nID0+IHtcbiAgICBsZXQgY09mZnNldCA9ICcnO1xuICAgIGlmIChzcGF0aWFsKSB7XG4gICAgICBjT2Zmc2V0ID0gYGxldCBjT2Zmc2V0ID0gJHtcbiAgICAgICAgeVNoYXBlLmxlbmd0aCA9PT0gMVxuICAgICAgICAgID8gJzB1J1xuICAgICAgICAgIDogZm9ybWF0ID09PSAnTkhXQydcbiAgICAgICAgICAgID8gYG91dHB1dEluZGljZXNbJHt5U2hhcGUubGVuZ3RoIC0gMX1dIC8gJHtjb21wb25lbnRzfWBcbiAgICAgICAgICAgIDogJ291dHB1dEluZGljZXNbMV0nXG4gICAgICB9O2A7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChmb3JtYXQgPT09ICdOQ0hXJykge1xuICAgICAgICBjT2Zmc2V0ID0gYFxuICAgICAgICAgICAgJHt5LmluZGljZXNTZXQoJ291dHB1dEluZGljZXMnLCAnMCcsICcwJyl9XG4gICAgICAgICAgICBsZXQgY09mZnNldCA9ICR7eS5pbmRpY2VzVG9PZmZzZXQoJ291dHB1dEluZGljZXMnKX07YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHVwZGF0ZSBDIGNoYW5uZWwuXG4gICAgICAgIGNPZmZzZXQgPSBgdmFyIGNJbmRpY2VzID0gJHtzY2FsZS50eXBlLmluZGljZXN9KDApO1xuICAgICAgICAgICAgICAgICAgICAgICBjSW5kaWNlc1swXSA9IG91dHB1dEluZGljZXNbJHt5U2hhcGUubGVuZ3RoIC0gMX1dO2A7XG4gICAgICAgIC8vIHVwZGF0ZSBEMSB4IC4uLiB4IERuIGNoYW5uZWxzLlxuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHNjYWxlLnJhbms7IGkrKykge1xuICAgICAgICAgIGNPZmZzZXQgKz0gYGNJbmRpY2VzWyR7aX1dID0gb3V0cHV0SW5kaWNlc1ske2l9XTtgO1xuICAgICAgICB9XG4gICAgICAgIGNPZmZzZXQgKz0gYGxldCBjT2Zmc2V0ID0gJHtzY2FsZS5pbmRpY2VzVG9PZmZzZXQoJ2NJbmRpY2VzJyl9O2A7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjT2Zmc2V0O1xuICB9O1xuICBjb25zdCBnZXRJbmZlcmVuY2VNb2RlU2hhZGVyU291cmNlID0gKGhlbHBlcjogU2hhZGVySGVscGVyKSA9PiBgXG4gIGNvbnN0IGVwc2lsb24gPSAke2Vwc2lsb259O1xuICAke2hlbHBlci5yZWdpc3RlclVuaWZvcm0oJ291dHB1dFNpemUnLCAndTMyJykuZGVjbGFyZVZhcmlhYmxlcyh4LCBzY2FsZSwgYmlhcywgaW5wdXRNZWFuLCBpbnB1dFZhciwgeSl9XG4gICR7aGVscGVyLm1haW5TdGFydCgpfVxuICAke2hlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRTaXplJyl9XG4gICAgdmFyIG91dHB1dEluZGljZXMgPSAke3kub2Zmc2V0VG9JbmRpY2VzKGBnbG9iYWxfaWR4ICogJHtjb21wb25lbnRzfWApfTtcbiAgICAke2NhbGNDT2Zmc2V0KCl9XG4gICAgbGV0IHNjYWxlID0gJHtzY2FsZS5nZXRCeU9mZnNldCgnY09mZnNldCcpfTtcbiAgICBsZXQgYmlhcyA9ICR7Ymlhcy5nZXRCeU9mZnNldCgnY09mZnNldCcpfTtcbiAgICBsZXQgaW5wdXRNZWFuID0gJHtpbnB1dE1lYW4uZ2V0QnlPZmZzZXQoJ2NPZmZzZXQnKX07XG4gICAgbGV0IGlucHV0VmFyID0gJHtpbnB1dFZhci5nZXRCeU9mZnNldCgnY09mZnNldCcpfTtcbiAgICBsZXQgeCA9ICR7eC5nZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcpfTtcbiAgICBsZXQgdmFsdWUgPSAoeCAtIGlucHV0TWVhbikgKiBpbnZlcnNlU3FydChpbnB1dFZhciArIGVwc2lsb24pICogc2NhbGUgKyBiaWFzO1xuICAgICR7eS5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICd2YWx1ZScpfVxuICB9YDtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnQmF0Y2hOb3JtYWxpemF0aW9uJyxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogYCR7YXR0cmlidXRlcy5lcHNpbG9ufV8ke2F0dHJpYnV0ZXMuZm9ybWF0fV8ke3NwYXRpYWx9XyR7Y29tcG9uZW50c31gLFxuICAgICAgaW5wdXREZXBlbmRlbmNpZXM6IHVzZVNoYXBlc1VuaWZvcm1zID8gWydyYW5rJywgJ3R5cGUnLCAndHlwZScsICd0eXBlJywgJ3R5cGUnXSA6IHVuZGVmaW5lZCxcbiAgICB9LFxuICAgIGdldFNoYWRlclNvdXJjZTogZ2V0SW5mZXJlbmNlTW9kZVNoYWRlclNvdXJjZSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogaW5wdXRzWzBdLmRpbXMsIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXM6IHVzZVNoYXBlc1VuaWZvcm1zXG4gICAgICAgID8gW3sgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKHlTaGFwZSldXG4gICAgICAgIDogW3sgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH1dLFxuICAgIH0pLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQmF0Y2hOb3JtQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEJhdGNoTm9ybUF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KGF0dHJpYnV0ZXMgYXMgT21pdDxCYXRjaE5vcm1BdHRyaWJ1dGVzLCBrZXlvZiBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXk+KTtcblxuZXhwb3J0IGNvbnN0IGJhdGNoTm9ybSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiB2b2lkID0+IHtcbiAgY29uc3QgeyBpbnB1dHMsIG91dHB1dENvdW50IH0gPSBjb250ZXh0O1xuICBjb25zdCB1cGRhdGVkQXR0cmlidXRlcyA9IHBhcnNlQmF0Y2hOb3JtQXR0cmlidXRlcyh7IC4uLmF0dHJpYnV0ZXMsIG91dHB1dENvdW50IH0pO1xuICBpZiAoZW52LndlYmdwdS52YWxpZGF0ZUlucHV0Q29udGVudCkge1xuICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgdXBkYXRlZEF0dHJpYnV0ZXMpO1xuICB9XG4gIGlmIChhdHRyaWJ1dGVzLnRyYWluaW5nTW9kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQmF0Y2hOb3JtYWxpemF0aW9uIHRyYWluaW5nTW9kZSBpcyBub3Qgc3VwcG9ydGVkIHlldC4nKTtcbiAgfSBlbHNlIHtcbiAgICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlQmF0Y2hOb3JtSW5mZXJlbmNlUHJvZ3JhbUluZm8oaW5wdXRzLCB1cGRhdGVkQXR0cmlidXRlcykpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGlucHV0VmFyaWFibGUsIG91dHB1dFZhcmlhYmxlLCBTaGFkZXJIZWxwZXIgfSBmcm9tICcuL2NvbW1vbic7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHNob3VsZCBoYXZlIDMgZGltZW5zaW9ucycpO1xuICB9XG5cbiAgaWYgKCFbMzIwLCA2NDAsIDEyODBdLmluY2x1ZGVzKGlucHV0c1swXS5kaW1zWzJdKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbnVtYmVyIG9mIGNoYW5uZWxzIHNob3VsZCBiZSAzMjAsIDY0MCBvciAxMjgwJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdiaWFzIGlzIGV4cGVjdGVkIHRvIGhhdmUgMSBkaW1lbnNpb25zJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLmRpbXNbMl0gIT09IGlucHV0c1sxXS5kaW1zWzBdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdsYXN0IGRpbWVuc2lvbiBvZiBpbnB1dCBhbmQgYmlhcyBhcmUgbm90IHRoZSBzYW1lJyk7XG4gIH1cbn07XG5cbmNvbnN0IGNyZWF0ZUJpYXNBZGRQcm9ncmFtSW5mbyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcblxuICBjb25zdCBjaGFubmVscyA9IGlucHV0c1swXS5kaW1zWzJdO1xuICAvLyBzaW5jZSBjaGFubmVsIG51bWJlciBjYW4gYmUgb25seSAzMjAvNjQwLzEyODAsIGl0J3MgYWx3YXlzIGRpdmlzaWJsZSBieSA0XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSkgLyA0O1xuXG4gIGNvbnN0IGRhdGFUeXBlID0gaW5wdXRzWzBdLmRhdGFUeXBlO1xuICBjb25zdCBpbnB1dCA9IGlucHV0VmFyaWFibGUoJ2lucHV0JywgZGF0YVR5cGUsIG91dHB1dFNoYXBlLCA0KTtcbiAgY29uc3QgYmlhcyA9IGlucHV0VmFyaWFibGUoJ2JpYXMnLCBkYXRhVHlwZSwgW2NoYW5uZWxzXSwgNCk7XG4gIGNvbnN0IHJlc2lkdWFsID0gaW5wdXRWYXJpYWJsZSgncmVzaWR1YWwnLCBkYXRhVHlwZSwgb3V0cHV0U2hhcGUsIDQpO1xuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgZGF0YVR5cGUsIG91dHB1dFNoYXBlLCA0KTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IGBcbiAgY29uc3QgY2hhbm5lbHMgPSAke2NoYW5uZWxzfXUgLyA0O1xuICAke3NoYWRlckhlbHBlci5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCBiaWFzLCByZXNpZHVhbCwgb3V0cHV0KX1cblxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKG91dHB1dFNpemUpfVxuICAgIGxldCB2YWx1ZSA9ICR7aW5wdXQuZ2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnKX1cbiAgICAgICsgJHtiaWFzLmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4ICUgY2hhbm5lbHMnKX0gKyAke3Jlc2lkdWFsLmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4Jyl9O1xuICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ3ZhbHVlJyl9XG4gIH1gO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0JpYXNBZGQnLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgYmlhc0FkZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVCaWFzQWRkUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMpKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvLCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbiAgdGVuc29yVHlwZVRvV3NnbFZhbHVlVHlwZSxcbiAgVW5pZm9ybURhdGFFbGVtZW50VHlwZSxcbiAgVW5pZm9ybXNBcnJheVR5cGUsXG59IGZyb20gJy4vY29tbW9uJztcblxudHlwZSBCdWlsdGluRnVuY3Rpb25OYW1lID0gc3RyaW5nO1xudHlwZSBFbGVtZW50d2lzZUN1c3RvbUV4cHJlc3Npb24gPSAoZXhwcmVzc2lvbjogc3RyaW5nKSA9PiBzdHJpbmc7XG50eXBlIEVsZW1lbnR3aXNlRnVuY3Rpb25DYWxsID0gQnVpbHRpbkZ1bmN0aW9uTmFtZSB8IEVsZW1lbnR3aXNlQ3VzdG9tRXhwcmVzc2lvbjtcblxuY29uc3QgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtU2hhZGVyID0gKFxuICBzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcixcbiAgZGF0YXNpemU6IG51bWJlcixcbiAgaW5wdXREYXRhVHlwZTogbnVtYmVyLFxuICBvdXRwdXREYXRhVHlwZTogbnVtYmVyLFxuICBmdW5jQ2FsbDogRWxlbWVudHdpc2VGdW5jdGlvbkNhbGwsXG4gIGFkZGl0aW9uYWxJbXBsZW1lbnRhdGlvbj86IHN0cmluZyxcbiAgYWRkaXRpb25hbFVuaWZvcm1zVHlwZT86IFVuaWZvcm1zQXJyYXlUeXBlLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgdmVjU2l6ZSA9IE1hdGguY2VpbChkYXRhc2l6ZSAvIDQpO1xuXG4gIGxldCBleHByZXNzaW9uID0gJyc7XG4gIGlmICh0eXBlb2YgZnVuY0NhbGwgPT09ICdzdHJpbmcnKSB7XG4gICAgZXhwcmVzc2lvbiA9IGAke2Z1bmNDYWxsfShhKWA7XG4gIH0gZWxzZSB7XG4gICAgZXhwcmVzc2lvbiA9IGZ1bmNDYWxsKCdhJyk7XG4gIH1cblxuICBjb25zdCBpbnB1dCA9IGlucHV0VmFyaWFibGUoJ2lucHV0RGF0YScsIGlucHV0RGF0YVR5cGUsIFt2ZWNTaXplXSwgNCk7XG4gIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXREYXRhJywgb3V0cHV0RGF0YVR5cGUsIFt2ZWNTaXplXSwgNCk7XG4gIGNvbnN0IHVuaWZvcm1zOiBVbmlmb3Jtc0FycmF5VHlwZSA9IFt7IG5hbWU6ICd2ZWNfc2l6ZScsIHR5cGU6ICd1MzInIH1dO1xuICBpZiAoYWRkaXRpb25hbFVuaWZvcm1zVHlwZSkge1xuICAgIHVuaWZvcm1zLnB1c2goLi4uYWRkaXRpb25hbFVuaWZvcm1zVHlwZSk7XG4gIH1cblxuICByZXR1cm4gYFxuICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyhpbnB1dCwgb3V0cHV0KX1cblxuICAke2FkZGl0aW9uYWxJbXBsZW1lbnRhdGlvbiA/PyAnJ31cblxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy52ZWNfc2l6ZScpfVxuXG4gICAgbGV0IGEgPSAke2lucHV0LmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4Jyl9O1xuICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgZXhwcmVzc2lvbil9XG4gIH1gO1xufTtcblxuY29uc3QgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXQ6IFRlbnNvclZpZXcsXG4gIG5hbWU6IHN0cmluZyxcbiAgZnVuY0NhbGw6IEVsZW1lbnR3aXNlRnVuY3Rpb25DYWxsLFxuICBhZGRpdGlvbmFsSW1wbGVtZW50YXRpb24/OiBzdHJpbmcsXG4gIGNhY2hlS2V5Pzogc3RyaW5nLFxuICBvdXRwdXREYXRhVHlwZTogbnVtYmVyID0gaW5wdXQuZGF0YVR5cGUsXG4gIGFkZGl0aW9uYWxVbmlmb3Jtcz86IFByb2dyYW1Vbmlmb3JtW10sXG4gIGFkZGl0aW9uYWxVbmlmb3Jtc1R5cGU/OiBVbmlmb3Jtc0FycmF5VHlwZSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBNYXRoLmNlaWwoU2hhcGVVdGlsLnNpemUoaW5wdXQuZGltcykgLyA0KSB9LFxuICBdO1xuICBpZiAoYWRkaXRpb25hbFVuaWZvcm1zKSB7XG4gICAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uYWRkaXRpb25hbFVuaWZvcm1zKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbmFtZSxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBjYWNoZUtleSwgaW5wdXREZXBlbmRlbmNpZXM6IFsndHlwZSddIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlOiAoc2hhZGVySGVscGVyKSA9PlxuICAgICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtU2hhZGVyKFxuICAgICAgICBzaGFkZXJIZWxwZXIsXG4gICAgICAgIFNoYXBlVXRpbC5zaXplKGlucHV0LmRpbXMpLFxuICAgICAgICBpbnB1dC5kYXRhVHlwZSxcbiAgICAgICAgb3V0cHV0RGF0YVR5cGUsXG4gICAgICAgIGZ1bmNDYWxsLFxuICAgICAgICBhZGRpdGlvbmFsSW1wbGVtZW50YXRpb24sXG4gICAgICAgIGFkZGl0aW9uYWxVbmlmb3Jtc1R5cGUsXG4gICAgICApLFxuICAgIGdldFJ1bkRhdGE6IChpbnB1dFRlbnNvcnMpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBpbnB1dC5kaW1zLCBkYXRhVHlwZTogb3V0cHV0RGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7XG4gICAgICAgIHg6IE1hdGguY2VpbChTaGFwZVV0aWwuc2l6ZShpbnB1dFRlbnNvcnNbMF0uZGltcykgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLyAvIDQgLyogdmVjIHNpemUgKi8pLFxuICAgICAgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBhYnMgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdBYnMnLCAnYWJzJykpO1xufTtcblxuZXhwb3J0IGNvbnN0IGFjb3MgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdBY29zJywgJ2Fjb3MnKSk7XG59O1xuXG5leHBvcnQgY29uc3QgYWNvc2ggPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdBY29zaCcsICdhY29zaCcpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBhc2luID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnQXNpbicsICdhc2luJykpO1xufTtcblxuZXhwb3J0IGNvbnN0IGFzaW5oID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnQXNpbmgnLCAnYXNpbmgnKSk7XG59O1xuXG5leHBvcnQgY29uc3QgYXRhbiA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ0F0YW4nLCAnYXRhbicpKTtcbn07XG5leHBvcnQgY29uc3QgYXRhbmggPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdBdGFuaCcsICdhdGFuaCcpKTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FzdEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSB0bzogbnVtYmVyO1xuICByZWFkb25seSBzYXR1cmF0ZT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNhc3RBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogQ2FzdEF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KGF0dHJpYnV0ZXMgYXMgeyB0bzogbnVtYmVyIH0pO1xuXG5leHBvcnQgY29uc3QgY2FzdCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogQ2FzdEF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgbGV0IGZ1bmM6IEVsZW1lbnR3aXNlRnVuY3Rpb25DYWxsO1xuICBzd2l0Y2ggKGF0dHJpYnV0ZXMudG8pIHtcbiAgICBjYXNlIERhdGFUeXBlLmZsb2F0MTY6XG4gICAgICBmdW5jID0gJ3ZlYzQ8ZjE2Pic7XG4gICAgICBicmVhaztcbiAgICBjYXNlIERhdGFUeXBlLmZsb2F0OlxuICAgICAgZnVuYyA9ICd2ZWM0PGYzMj4nO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBEYXRhVHlwZS51aW50MzI6XG4gICAgICBmdW5jID0gJ3ZlYzQ8dTMyPic7XG4gICAgICBicmVhaztcbiAgICBjYXNlIERhdGFUeXBlLmludDMyOlxuICAgICAgZnVuYyA9ICd2ZWM0PGkzMj4nO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBEYXRhVHlwZS5ib29sOlxuICAgICAgZnVuYyA9ICd2ZWM0PGJvb2w+JztcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgbm90IHN1cHBvcnRlZCB0eXBlIChzcGVjaWZpZWQgaW4gYXR0cmlidXRlICd0bycgZnJvbSAnQ2FzdCcgb3BlcmF0b3IpOiAke2F0dHJpYnV0ZXMudG99YCk7XG4gIH1cbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdDYXN0JywgZnVuYywgdW5kZWZpbmVkLCBhdHRyaWJ1dGVzLmNhY2hlS2V5LCBhdHRyaWJ1dGVzLnRvKSxcbiAgKTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xpcEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBtaW46IG51bWJlcjtcbiAgcmVhZG9ubHkgbWF4OiBudW1iZXI7XG59XG5cbmNvbnN0IGdlbmVyYXRlQ2xpcEF0dHJpYnV0ZXNGcm9tSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogQ2xpcEF0dHJpYnV0ZXMgPT4ge1xuICBsZXQgbWluOiBudW1iZXI7XG4gIGxldCBtYXg6IG51bWJlcjtcbiAgY29uc3QgaGFzTWluID0gaW5wdXRzLmxlbmd0aCA+PSAyICYmIGlucHV0c1sxXS5kYXRhICE9PSAwO1xuICBjb25zdCBoYXNNYXggPSBpbnB1dHMubGVuZ3RoID49IDMgJiYgaW5wdXRzWzJdLmRhdGEgIT09IDA7XG5cbiAgc3dpdGNoIChpbnB1dHNbMF0uZGF0YVR5cGUpIHtcbiAgICBjYXNlIERhdGFUeXBlLmZsb2F0OlxuICAgICAgbWluID0gaGFzTWluID8gaW5wdXRzWzFdLmdldEZsb2F0MzJBcnJheSgpWzBdIDogLTMuNDAyODIzNDY2Mzg1Mjg4NmUzODtcbiAgICAgIG1heCA9IGhhc01heCA/IGlucHV0c1syXS5nZXRGbG9hdDMyQXJyYXkoKVswXSA6IDMuNDAyODIzNDY2Mzg1Mjg4NmUzODtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgRGF0YVR5cGUuZmxvYXQxNjpcbiAgICAgIG1pbiA9IGhhc01pbiA/IGlucHV0c1sxXS5nZXRVaW50MTZBcnJheSgpWzBdIDogNjQ1MTE7IC8vIHVpbnQxNig2NDUxMSkgPC0+IGZsb2F0MTYoLTY1NTA0LjApXG4gICAgICBtYXggPSBoYXNNYXggPyBpbnB1dHNbMl0uZ2V0VWludDE2QXJyYXkoKVswXSA6IDMxNzQzOyAvLyB1aW50MTYoMzE3NDMpIDwtPiBmbG9hdDE2KDY1NTA0LjApXG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnQgZGF0YSB0eXBlJyk7XG4gIH1cblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgbWluLCBtYXggfSk7XG59O1xuXG5leHBvcnQgY29uc3QgY2xpcCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgY2xpcEF0dHJpYnV0ZXM6IENsaXBBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSBjbGlwQXR0cmlidXRlcyA/IGNsaXBBdHRyaWJ1dGVzIDogZ2VuZXJhdGVDbGlwQXR0cmlidXRlc0Zyb21JbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUpO1xuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhcbiAgICAgIGNvbnRleHQuaW5wdXRzWzBdLFxuICAgICAgJ0NsaXAnLFxuICAgICAgKGEpID0+IGBjbGFtcCgke2F9LCB2ZWM0PCR7ZGF0YVR5cGV9Pih1bmlmb3Jtcy5taW4pLCB2ZWM0PCR7ZGF0YVR5cGV9Pih1bmlmb3Jtcy5tYXgpKWAsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgW1xuICAgICAgICB7IHR5cGU6IGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlLCBkYXRhOiBhdHRyaWJ1dGVzLm1pbiB9LFxuICAgICAgICB7IHR5cGU6IGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlLCBkYXRhOiBhdHRyaWJ1dGVzLm1heCB9LFxuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgeyBuYW1lOiAnbWluJywgdHlwZTogZGF0YVR5cGUgYXMgVW5pZm9ybURhdGFFbGVtZW50VHlwZSB9LFxuICAgICAgICB7IG5hbWU6ICdtYXgnLCB0eXBlOiBkYXRhVHlwZSBhcyBVbmlmb3JtRGF0YUVsZW1lbnRUeXBlIH0sXG4gICAgICBdLFxuICAgICksXG4gICAgeyBpbnB1dHM6IFswXSB9LFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IGNlaWwgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdDZWlsJywgJ2NlaWwnKSk7XG59O1xuXG5leHBvcnQgY29uc3QgY29zID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnQ29zJywgJ2NvcycpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb3NoID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnQ29zaCcsICdjb3NoJykpO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBBbHBoYUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBhbHBoYTogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgcGFyc2VBbHBoYUF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBBbHBoYUF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KGF0dHJpYnV0ZXMgYXMgeyBhbHBoYTogbnVtYmVyIH0pO1xuXG5leHBvcnQgY29uc3QgZWx1ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBbHBoYUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsVmFsdWVUeXBlKGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlKTtcbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oXG4gICAgICBjb250ZXh0LmlucHV0c1swXSxcbiAgICAgICdFbHUnLFxuICAgICAgKGEpID0+IGBlbHVfdmYzMigke2F9KWAsXG4gICAgICBgXG4gIGNvbnN0IGVsdV9hbHBoYV8gPSAke2RhdGFUeXBlfSgke2F0dHJpYnV0ZXMuYWxwaGF9KTtcblxuICBmbiBlbHVfZjMyKGE6ICR7ZGF0YVR5cGV9KSAtPiAke2RhdGFUeXBlfSB7XG4gIHJldHVybiBzZWxlY3QoKGV4cChhKSAtIDEuMCkgKiBlbHVfYWxwaGFfLCBhLCBhID49IDAuMCk7XG4gIH1cblxuICBmbiBlbHVfdmYzMih2OiB2ZWM0PCR7ZGF0YVR5cGV9PikgLT4gdmVjNDwke2RhdGFUeXBlfT4ge1xuICByZXR1cm4gdmVjNChlbHVfZjMyKHYueCksIGVsdV9mMzIodi55KSwgZWx1X2YzMih2LnopLCBlbHVfZjMyKHYudykpO1xuICB9YCxcbiAgICAgIGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgKSxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBlcmZJbXBsID0gKHZhclR5cGUgPSAnZjMyJykgPT4gYFxuY29uc3QgcjA6ICR7dmFyVHlwZX0gPSAwLjMyNzU5MTE7XG5jb25zdCByMTogJHt2YXJUeXBlfSA9IDAuMjU0ODI5NTkyO1xuY29uc3QgcjI6ICR7dmFyVHlwZX0gPSAtMC4yODQ0OTY3MzY7XG5jb25zdCByMzogJHt2YXJUeXBlfSA9IDEuNDIxNDEzNzQxO1xuY29uc3QgcjQ6ICR7dmFyVHlwZX0gPSAtMS40NTMxNTIwMjc7XG5jb25zdCByNTogJHt2YXJUeXBlfSA9IDEuMDYxNDA1NDI5O1xuXG5mbiBlcmZfdmYzMih2OiB2ZWM0PCR7dmFyVHlwZX0+KSAtPiB2ZWM0PCR7dmFyVHlwZX0+IHtcbiAgbGV0IGFic3YgPSBhYnModik7XG4gIGxldCB4ID0gMS4wIC8gKDEuMCArIHIwICogYWJzdik7XG4gIHJldHVybiBzaWduKHYpICogKDEuMCAtICgoKChyNSAqIHggKyByNCkgKiB4ICsgcjMpICogeCArIHIyKSAqIHggKyByMSkgKiB4ICogZXhwKC1hYnN2ICogYWJzdikpO1xufWA7XG5cbmV4cG9ydCBjb25zdCBlcmYgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsVmFsdWVUeXBlKGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdFcmYnLCAoYSkgPT4gYGVyZl92ZjMyKCR7YX0pYCwgZXJmSW1wbChkYXRhVHlwZSkpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBleHAgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdFeHAnLCAnZXhwJykpO1xufTtcblxuZXhwb3J0IGNvbnN0IGZsb29yID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnRmxvb3InLCAnZmxvb3InKSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2VsdSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUpO1xuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhcbiAgICAgIGNvbnRleHQuaW5wdXRzWzBdLFxuICAgICAgJ0dlbHUnLFxuICAgICAgKGEpID0+IGAwLjUgKiAke2F9ICogKDEuMCArIGVyZl92ZjMyKCR7YX0gKiAwLjcwNzEwNjc4MTE4NjU0NzUpKWAsXG4gICAgICBlcmZJbXBsKGRhdGFUeXBlKSxcbiAgICApLFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IGxlYWt5UmVsdSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogQWxwaGFBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yVHlwZVRvV3NnbFZhbHVlVHlwZShjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSk7XG4gIGNvbnRleHQuY29tcHV0ZShcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKFxuICAgICAgY29udGV4dC5pbnB1dHNbMF0sXG4gICAgICAnTGVha3lSZWx1JyxcbiAgICAgIChhKSA9PiBgc2VsZWN0KGxlYWt5X3JlbHVfYWxwaGFfICogJHthfSwgJHthfSwgJHthfSA+PSB2ZWM0PCR7ZGF0YVR5cGV9PigwLjApKWAsXG4gICAgICBgY29uc3QgbGVha3lfcmVsdV9hbHBoYV8gPSAke2RhdGFUeXBlfSgke2F0dHJpYnV0ZXMuYWxwaGF9KTtgLFxuICAgICAgYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICApLFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IG5vdCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ05vdCcsIChhKSA9PiBgISR7YX1gKSk7XG59O1xuXG5leHBvcnQgY29uc3QgbmVnID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnTmVnJywgKGEpID0+IGAtJHthfWApKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWNpcHJvY2FsID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnUmVjaXByb2NhbCcsIChhKSA9PiBgMS4wLyR7YX1gKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVsdSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUpO1xuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhcbiAgICAgIGNvbnRleHQuaW5wdXRzWzBdLFxuICAgICAgJ1JlbHUnLFxuICAgICAgKGEpID0+IGBzZWxlY3QodmVjNDwke2RhdGFUeXBlfT4oMC4wKSwgJHthfSwgJHthfSA+IHZlYzQ8JHtkYXRhVHlwZX0+KDAuMCkpYCxcbiAgICApLFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IHNpZ21vaWQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdTaWdtb2lkJywgKGEpID0+IGAoMS4wIC8gKDEuMCArIGV4cCgtJHthfSkpKWApKTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgSGFyZFNpZ21vaWRBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYWxwaGE6IG51bWJlcjtcbiAgcmVhZG9ubHkgYmV0YTogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgcGFyc2VIYXJkU2lnbW9pZEF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBIYXJkU2lnbW9pZEF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KFxuICAgIGF0dHJpYnV0ZXMgYXMge1xuICAgICAgYWxwaGE6IG51bWJlcjtcbiAgICAgIGJldGE6IG51bWJlcjtcbiAgICB9LFxuICApO1xuXG5leHBvcnQgY29uc3QgaGFyZFNpZ21vaWQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEhhcmRTaWdtb2lkQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUpO1xuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhcbiAgICAgIGNvbnRleHQuaW5wdXRzWzBdLFxuICAgICAgJ0hhcmRTaWdtb2lkJyxcbiAgICAgIChhKSA9PlxuICAgICAgICBgbWF4KHZlYzQ8JHtkYXRhVHlwZX0+KDAuMCksIG1pbih2ZWM0PCR7ZGF0YVR5cGV9PigxLjApLCAke2F0dHJpYnV0ZXMuYWxwaGF9ICogJHthfSArIHZlYzQ8JHtkYXRhVHlwZX0+KCR7YXR0cmlidXRlcy5iZXRhfSkpKWAsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICksXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3Qgc2luID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnU2luJywgJ3NpbicpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaW5oID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnU2luaCcsICdzaW5oJykpO1xufTtcblxuZXhwb3J0IGNvbnN0IHNxcnQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdTcXJ0JywgJ3NxcnQnKSk7XG59O1xuXG5leHBvcnQgY29uc3QgdGFuID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnVGFuJywgJ3RhbicpKTtcbn07XG5cbmV4cG9ydCBjb25zdCB0YW5oRXhwcmVzc2lvbiA9IChhOiBzdHJpbmcpID0+IGBzaWduKCR7YX0pICogKDEgLSBleHAoLTIgKiBhYnMoJHthfSkpKSAvICgxICsgZXhwKC0yICogYWJzKCR7YX0pKSlgO1xuXG5leHBvcnQgY29uc3QgdGFuaCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICAvLyBUT0RPOiByZXZpc2l0IGFmdGVyIGh0dHBzOi8vZ2l0aHViLmNvbS9ncHV3ZWIvZ3B1d2ViL2lzc3Vlcy80NDU4IGlzIHJlc29sdmVkXG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnVGFuaCcsIHRhbmhFeHByZXNzaW9uKSk7XG59O1xuXG5leHBvcnQgY29uc3QgZmFzdEdlbHVJbXBsID0gKHZhclR5cGUgPSAnZjMyJykgPT4gYFxuY29uc3QgZmFzdF9nZWx1X2E6ICR7dmFyVHlwZX0gPSAwLjU7XG5jb25zdCBmYXN0X2dlbHVfYjogJHt2YXJUeXBlfSA9IDAuNzk3ODg0NTYwODAyODY1NDtcbmNvbnN0IGZhc3RfZ2VsdV9jOiAke3ZhclR5cGV9ID0gMC4wMzU2Nzc0MDgxMzYzMDAxMjU7XG5cbmZuIHRhbmhfdih2OiB2ZWM0PCR7dmFyVHlwZX0+KSAtPiB2ZWM0PCR7dmFyVHlwZX0+IHtcbiAgcmV0dXJuICR7dGFuaEV4cHJlc3Npb24oJ3YnKX07XG59XG5gO1xuXG5leHBvcnQgY29uc3QgZmFzdEdlbHVFeHByZXNzaW9uID0gKHg6IHN0cmluZykgPT5cbiAgYChmYXN0X2dlbHVfYSArIGZhc3RfZ2VsdV9hICogdGFuaF92KCR7eH0gKiAoZmFzdF9nZWx1X2MgKiAke3h9ICogJHt4fSArIGZhc3RfZ2VsdV9iKSkpICogJHt4fWA7XG5cbmV4cG9ydCBjb25zdCBmYXN0R2VsdSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUpO1xuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhcbiAgICAgIGNvbnRleHQuaW5wdXRzWzBdLFxuICAgICAgJ0Zhc3RHZWx1JyxcbiAgICAgIGZhc3RHZWx1RXhwcmVzc2lvbixcbiAgICAgIGZhc3RHZWx1SW1wbChkYXRhVHlwZSksXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSxcbiAgICApLFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IHRocmVzaG9sZGVkUmVsdSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogQWxwaGFBdHRyaWJ1dGVzKTogbnVtYmVyID0+IHtcbiAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsVmFsdWVUeXBlKGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlKTtcbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oXG4gICAgICBjb250ZXh0LmlucHV0c1swXSxcbiAgICAgICdUaHJlc2hvbGRlZFJlbHUnLFxuICAgICAgKGEpID0+IGBzZWxlY3QodmVjNDwke2RhdGFUeXBlfT4oMC4wKSwgJHthfSwgJHthfSA+IHRocmVzaG9sZGVkX3JlbHVfYWxwaGFfKWAsXG4gICAgICBgY29uc3QgdGhyZXNob2xkZWRfcmVsdV9hbHBoYV8gPSB2ZWM0PCR7ZGF0YVR5cGV9Pigke2F0dHJpYnV0ZXMuYWxwaGF9KTtgLFxuICAgICAgYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICApLFxuICApO1xuICByZXR1cm4gMDtcbn07XG5cbmV4cG9ydCBjb25zdCBsb2cgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdMb2cnLCAnbG9nJykpO1xufTtcblxuZXhwb3J0IGNvbnN0IHF1aWNrR2VsdUltcGwgPSAodmFyVHlwZTogc3RyaW5nLCBhbHBoYTogbnVtYmVyKSA9PiBgXG5jb25zdCBhbHBoYSA9IHZlYzQ8JHt2YXJUeXBlfT4oJHthbHBoYX0pO1xuY29uc3Qgb25lID0gJHt2YXJUeXBlfSgxLjApO1xuY29uc3QgemVybyA9ICR7dmFyVHlwZX0oMC4wKTtcblxuZm4gcXVpY2tfZ2VsdV9pbXBsKHg6IHZlYzQ8JHt2YXJUeXBlfT4pIC0+IHZlYzQ8JHt2YXJUeXBlfT4ge1xuICBsZXQgdiA9IHggKmFscGhhO1xuICB2YXIgeDEgOiB2ZWM0PCR7dmFyVHlwZX0+O1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkgPSBpICsgMSkge1xuICAgIGlmICh2W2ldID49IHplcm8pIHtcbiAgICAgIHgxW2ldID0gb25lIC8gKG9uZSArIGV4cCgtdltpXSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB4MVtpXSA9IG9uZSAtIG9uZSAvIChvbmUgKyBleHAodltpXSkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4geCAqIHgxO1xufVxuYDtcblxuZXhwb3J0IGNvbnN0IHF1aWNrR2VsdUV4cHJlc3Npb24gPSAoeDogc3RyaW5nKSA9PiBgcXVpY2tfZ2VsdV9pbXBsKCR7eH0pYDtcblxuZXhwb3J0IGNvbnN0IHF1aWNrZ2VsdSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogQWxwaGFBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGNvbnN0IGRUeXBlID0gdGVuc29yVHlwZVRvV3NnbFZhbHVlVHlwZShjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSk7XG4gIGNvbnRleHQuY29tcHV0ZShcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKFxuICAgICAgY29udGV4dC5pbnB1dHNbMF0sXG4gICAgICAnUXVpY2tHZWx1JyxcbiAgICAgIHF1aWNrR2VsdUV4cHJlc3Npb24sXG4gICAgICBxdWlja0dlbHVJbXBsKGRUeXBlLCBhdHRyaWJ1dGVzLmFscGhhKSxcbiAgICAgIGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSxcbiAgICApLFxuICApO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyLCB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUgfSBmcm9tICcuL2NvbW1vbic7XG5pbXBvcnQgeyBlcmZJbXBsIH0gZnJvbSAnLi91bmFyeS1vcCc7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHNob3VsZCBoYXZlIDMgZGltZW5zaW9ucycpO1xuICB9XG5cbiAgaWYgKCFbMjU2MCwgNTEyMCwgMTAyNDBdLmluY2x1ZGVzKGlucHV0c1swXS5kaW1zWzJdKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaGlkZGVuIHN0YXRlIHNob3VsZCBiZSAyNTYwLCA1MTIwIG9yIDEwMjQwJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdiaWFzIGlzIGV4cGVjdGVkIHRvIGhhdmUgMSBkaW1lbnNpb25zJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLmRpbXNbMl0gIT09IGlucHV0c1sxXS5kaW1zWzBdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdsYXN0IGRpbWVuc2lvbiBvZiBpbnB1dCBhbmQgYmlhcyBhcmUgbm90IHRoZSBzYW1lJyk7XG4gIH1cbn07XG5cbmNvbnN0IGNyZWF0ZUJpYXNTcGxpdEdlbHVQcm9ncmFtSW5mbyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBvdXRwdXRTaGFwZVsyXSA9IG91dHB1dFNoYXBlWzJdIC8gMjtcblxuICBjb25zdCBpbnB1dCA9IGlucHV0VmFyaWFibGUoJ2lucHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dHNbMF0uZGltcywgNCk7XG4gIGNvbnN0IGJpYXMgPSBpbnB1dFZhcmlhYmxlKCdiaWFzJywgaW5wdXRzWzBdLmRhdGFUeXBlLCBbaW5wdXRzWzBdLmRpbXNbMl1dLCA0KTtcbiAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUsIDQpO1xuXG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSkgLyA0O1xuICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZShpbnB1dHNbMF0uZGF0YVR5cGUpO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gYFxuICBjb25zdCBNX1NRUlQyID0gc3FydCgyLjApO1xuICBjb25zdCBoYWxmQ2hhbm5lbHMgPSAke2lucHV0c1swXS5kaW1zWzJdIC8gNCAvIDJ9dTtcblxuICAke3NoYWRlckhlbHBlci5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCBiaWFzLCBvdXRwdXQpfVxuXG4gICR7ZXJmSW1wbChkYXRhVHlwZSl9XG5cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcyhvdXRwdXRTaXplKX1cbiAgICBsZXQgYmlhc0lkeCA9IGdsb2JhbF9pZHggJSBoYWxmQ2hhbm5lbHM7XG4gICAgbGV0IGJhdGNoSW5kZXggPSBnbG9iYWxfaWR4IC8gaGFsZkNoYW5uZWxzO1xuICAgIGxldCBpbnB1dE9mZnNldCA9IGJpYXNJZHggKyBiYXRjaEluZGV4ICogaGFsZkNoYW5uZWxzICogMjtcbiAgICBsZXQgdmFsdWVMZWZ0ID0gaW5wdXRbaW5wdXRPZmZzZXRdICsgYmlhc1tiaWFzSWR4XTtcbiAgICBsZXQgdmFsdWVSaWdodCA9IGlucHV0W2lucHV0T2Zmc2V0ICsgaGFsZkNoYW5uZWxzXSArIGJpYXNbYmlhc0lkeCArIGhhbGZDaGFubmVsc107XG4gICAgbGV0IGdlbHVSaWdodCA9IHZhbHVlUmlnaHQgKiAwLjUgKiAoZXJmX3ZmMzIodmFsdWVSaWdodCAvIE1fU1FSVDIpICsgMSk7XG5cbiAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICd2YWx1ZUxlZnQgKiBnZWx1UmlnaHQnKX1cbiAgfWA7XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnQmlhc1NwbGl0R2VsdScsXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH1dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBiaWFzU3BsaXRHZWx1ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUJpYXNTcGxpdEdlbHVQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0cykpO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgQnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG50eXBlIEJ1aWx0aW5GdW5jdGlvbk5hbWUgPSBzdHJpbmc7XG50eXBlIEJpbmFyeUN1c3RvbUV4cHJlc3Npb24gPSAoZXhwcmVzc2lvbkE6IHN0cmluZywgZXhwcmVzc2lvbkI6IHN0cmluZykgPT4gc3RyaW5nO1xudHlwZSBCaW5hcnlGdW5jdGlvbkNhbGwgPVxuICB8IEJ1aWx0aW5GdW5jdGlvbk5hbWVcbiAgfCBCaW5hcnlDdXN0b21FeHByZXNzaW9uXG4gIHwge1xuICAgICAgc2NhbGFyOiBCaW5hcnlDdXN0b21FeHByZXNzaW9uO1xuICAgICAgdmVjdG9yOiBCaW5hcnlDdXN0b21FeHByZXNzaW9uO1xuICAgIH07XG5cbmNvbnN0IGNyZWF0ZUJpbmFyeU9wUHJvZ3JhbVNoYWRlciA9IChcbiAgc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIsXG4gIGRpbXNBOiByZWFkb25seSBudW1iZXJbXSxcbiAgZGltc0I6IHJlYWRvbmx5IG51bWJlcltdLFxuICBkaW1zT3V0cHV0OiByZWFkb25seSBudW1iZXJbXSxcbiAgdmVjdG9yaXplOiBib29sZWFuLFxuICBkb0Jyb2FkY2FzdDogYm9vbGVhbixcbiAgc2hhcmVkRGltZW5zaW9uRGl2aXNpYmxlQnk0OiBib29sZWFuLFxuICBmdW5jQ2FsbDogQmluYXJ5RnVuY3Rpb25DYWxsLFxuICB0eXBlQTogbnVtYmVyLFxuICB0eXBlQjogbnVtYmVyLFxuICB0eXBlT3V0cHV0OiBudW1iZXIsXG4gIGFkZGl0aW9uYWxJbXBsZW1lbnRhdGlvbj86IHN0cmluZyxcbikgPT4ge1xuICBsZXQgZXhwcmVzc2lvblNjYWxhcjogQmluYXJ5Q3VzdG9tRXhwcmVzc2lvbjtcbiAgbGV0IGV4cHJlc3Npb25WZWN0b3I6IEJpbmFyeUN1c3RvbUV4cHJlc3Npb247XG4gIGlmICh0eXBlb2YgZnVuY0NhbGwgPT09ICdzdHJpbmcnKSB7XG4gICAgZXhwcmVzc2lvblNjYWxhciA9IGV4cHJlc3Npb25WZWN0b3IgPSAoYSwgYikgPT4gYCR7ZnVuY0NhbGx9KCgke2F9KSwoJHtifSkpYDtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZnVuY0NhbGwgPT09ICdmdW5jdGlvbicpIHtcbiAgICBleHByZXNzaW9uU2NhbGFyID0gZXhwcmVzc2lvblZlY3RvciA9IGZ1bmNDYWxsO1xuICB9IGVsc2Uge1xuICAgIGV4cHJlc3Npb25TY2FsYXIgPSBmdW5jQ2FsbC5zY2FsYXI7XG4gICAgZXhwcmVzc2lvblZlY3RvciA9IGZ1bmNDYWxsLnZlY3RvcjtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXREYXRhJywgdHlwZU91dHB1dCwgZGltc091dHB1dC5sZW5ndGgsIDQpO1xuICBjb25zdCBhID0gaW5wdXRWYXJpYWJsZSgnYURhdGEnLCB0eXBlQSwgZGltc0EubGVuZ3RoLCA0KTtcbiAgY29uc3QgYiA9IGlucHV0VmFyaWFibGUoJ2JEYXRhJywgdHlwZUIsIGRpbXNCLmxlbmd0aCwgNCk7XG5cbiAgbGV0IGFzc2lnbm1lbnQ6IHN0cmluZztcbiAgaWYgKHZlY3Rvcml6ZSkge1xuICAgIGlmIChkb0Jyb2FkY2FzdCkge1xuICAgICAgY29uc3QgaXNBT25lRWxlbWVudCA9IFNoYXBlVXRpbC5zaXplKGRpbXNBKSA9PT0gMTtcbiAgICAgIGNvbnN0IGlzQk9uZUVsZW1lbnQgPSBTaGFwZVV0aWwuc2l6ZShkaW1zQikgPT09IDE7XG4gICAgICBjb25zdCBhTGFzdERpbURpdmlzaWJsZUJ5NCA9IGRpbXNBLmxlbmd0aCA+IDAgJiYgZGltc0FbZGltc0EubGVuZ3RoIC0gMV0gJSA0ID09PSAwO1xuICAgICAgY29uc3QgYkxhc3REaW1EaXZpc2libGVCeTQgPSBkaW1zQi5sZW5ndGggPiAwICYmIGRpbXNCW2RpbXNCLmxlbmd0aCAtIDFdICUgNCA9PT0gMDtcbiAgICAgIGlmIChpc0FPbmVFbGVtZW50IHx8IGlzQk9uZUVsZW1lbnQpIHtcbiAgICAgICAgYXNzaWdubWVudCA9IG91dHB1dC5zZXRCeU9mZnNldChcbiAgICAgICAgICAnZ2xvYmFsX2lkeCcsXG4gICAgICAgICAgZXhwcmVzc2lvblZlY3RvcihcbiAgICAgICAgICAgIGlzQU9uZUVsZW1lbnQgPyBgJHthLnR5cGUudmFsdWV9KCR7YS5nZXRCeU9mZnNldCgnMCcpfS54KWAgOiBhLmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JyksXG4gICAgICAgICAgICBpc0JPbmVFbGVtZW50ID8gYCR7Yi50eXBlLnZhbHVlfSgke2IuZ2V0QnlPZmZzZXQoJzAnKX0ueClgIDogYi5nZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcpLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhc3NpZ25tZW50ID0gYFxuICAgICAgICAgICAgbGV0IG91dHB1dEluZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHggKiA0dScpfTtcbiAgICAgICAgICAgIGxldCBvZmZzZXRBID0gJHthLmJyb2FkY2FzdGVkSW5kaWNlc1RvT2Zmc2V0KCdvdXRwdXRJbmRpY2VzJywgb3V0cHV0KX07XG4gICAgICAgICAgICBsZXQgb2Zmc2V0QiA9ICR7Yi5icm9hZGNhc3RlZEluZGljZXNUb09mZnNldCgnb3V0cHV0SW5kaWNlcycsIG91dHB1dCl9O1xuICAgICAgICAgICAgJHtvdXRwdXQuc2V0QnlPZmZzZXQoXG4gICAgICAgICAgICAgICdnbG9iYWxfaWR4JyxcbiAgICAgICAgICAgICAgZXhwcmVzc2lvblZlY3RvcihcbiAgICAgICAgICAgICAgICBzaGFyZWREaW1lbnNpb25EaXZpc2libGVCeTQgfHwgYUxhc3REaW1EaXZpc2libGVCeTRcbiAgICAgICAgICAgICAgICAgID8gYS5nZXRCeU9mZnNldCgnb2Zmc2V0QSAvIDR1JylcbiAgICAgICAgICAgICAgICAgIDogYCR7YS50eXBlLnZhbHVlfSgke2EuZ2V0QnlPZmZzZXQoJ29mZnNldEEgLyA0dScpfVtvZmZzZXRBICUgNHVdKWAsXG4gICAgICAgICAgICAgICAgc2hhcmVkRGltZW5zaW9uRGl2aXNpYmxlQnk0IHx8IGJMYXN0RGltRGl2aXNpYmxlQnk0XG4gICAgICAgICAgICAgICAgICA/IGIuZ2V0QnlPZmZzZXQoJ29mZnNldEIgLyA0dScpXG4gICAgICAgICAgICAgICAgICA6IGAke2IudHlwZS52YWx1ZX0oJHtiLmdldEJ5T2Zmc2V0KCdvZmZzZXRCIC8gNHUnKX1bb2Zmc2V0QiAlIDR1XSlgLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKX1cbiAgICAgICAgICBgO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBhc3NpZ25tZW50ID0gb3V0cHV0LnNldEJ5T2Zmc2V0KFxuICAgICAgICAnZ2xvYmFsX2lkeCcsXG4gICAgICAgIGV4cHJlc3Npb25WZWN0b3IoYS5nZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcpLCBiLmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JykpLFxuICAgICAgKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFkb0Jyb2FkY2FzdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBuZWNlc3NhcnkgdG8gdXNlIHNjYWxhciBpbXBsZW1lbnRhdGlvbiBmb3IgZWxlbWVudC13aXNlIGJpbmFyeSBvcCBpbXBsZW1lbnRhdGlvbi4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBzaW5nbGVBc3NpZ25tZW50ID0gKHJlc1N0cjogc3RyaW5nLCB4OiBudW1iZXIsIHR5cGVDYXN0ID0gJycpID0+IHtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb25BID0gYGFEYXRhW2luZGV4QSR7eH1dW2NvbXBvbmVudEEke3h9XWA7XG4gICAgICBjb25zdCBleHByZXNzaW9uQiA9IGBiRGF0YVtpbmRleEIke3h9XVtjb21wb25lbnRCJHt4fV1gO1xuICAgICAgcmV0dXJuIGBcbiAgICAgICAgICAgIGxldCBvdXRwdXRJbmRpY2VzJHt4fSA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcyhgZ2xvYmFsX2lkeCAqIDR1ICsgJHt4fXVgKX07XG4gICAgICAgICAgICBsZXQgb2Zmc2V0QSR7eH0gPSAke2EuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQoYG91dHB1dEluZGljZXMke3h9YCwgb3V0cHV0KX07XG4gICAgICAgICAgICBsZXQgb2Zmc2V0QiR7eH0gPSAke2IuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQoYG91dHB1dEluZGljZXMke3h9YCwgb3V0cHV0KX07XG4gICAgICAgICAgICBsZXQgaW5kZXhBJHt4fSA9IG9mZnNldEEke3h9IC8gNHU7XG4gICAgICAgICAgICBsZXQgaW5kZXhCJHt4fSA9IG9mZnNldEIke3h9IC8gNHU7XG4gICAgICAgICAgICBsZXQgY29tcG9uZW50QSR7eH0gPSBvZmZzZXRBJHt4fSAlIDR1O1xuICAgICAgICAgICAgbGV0IGNvbXBvbmVudEIke3h9ID0gb2Zmc2V0QiR7eH0gJSA0dTtcbiAgICAgICAgICAgICR7cmVzU3RyfVske3h9XSA9ICR7dHlwZUNhc3R9KCR7ZXhwcmVzc2lvblNjYWxhcihleHByZXNzaW9uQSwgZXhwcmVzc2lvbkIpfSk7XG4gICAgICAgICAgYDtcbiAgICB9O1xuICAgIGlmICh0eXBlT3V0cHV0ID09PSBEYXRhVHlwZS5ib29sKSB7XG4gICAgICBhc3NpZ25tZW50ID0gYFxuICAgICAgICAgICAgdmFyIGRhdGEgPSB2ZWM0PHUzMj4oMCk7XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ2RhdGEnLCAwLCAndTMyJyl9XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ2RhdGEnLCAxLCAndTMyJyl9XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ2RhdGEnLCAyLCAndTMyJyl9XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ2RhdGEnLCAzLCAndTMyJyl9XG4gICAgICAgICAgICBvdXRwdXREYXRhW2dsb2JhbF9pZHhdID0gZG90KHZlYzQ8dTMyPigweDEsIDB4MTAwLCAweDEwMDAwLCAweDEwMDAwMDApLCB2ZWM0PHUzMj4oZGF0YSkpO2A7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFzc2lnbm1lbnQgPSBgXG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ291dHB1dERhdGFbZ2xvYmFsX2lkeF0nLCAwKX1cbiAgICAgICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnb3V0cHV0RGF0YVtnbG9iYWxfaWR4XScsIDEpfVxuICAgICAgICAgICAgJHtzaW5nbGVBc3NpZ25tZW50KCdvdXRwdXREYXRhW2dsb2JhbF9pZHhdJywgMil9XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ291dHB1dERhdGFbZ2xvYmFsX2lkeF0nLCAzKX1cbiAgICAgICAgICBgO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBgXG4gICAgICAgICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybSgndmVjX3NpemUnLCAndTMyJykuZGVjbGFyZVZhcmlhYmxlcyhhLCBiLCBvdXRwdXQpfVxuXG4gICAgICAgICR7YWRkaXRpb25hbEltcGxlbWVudGF0aW9uID8/ICcnfVxuXG4gICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy52ZWNfc2l6ZScpfVxuICAgICAgICAke2Fzc2lnbm1lbnR9XG4gICAgICB9YDtcbn07XG5cbmNvbnN0IGNyZWF0ZUJpbmFyeU9wUHJvZ3JhbUluZm8gPSAoXG4gIG5hbWU6IHN0cmluZyxcbiAgY2FjaGVLZXk6IHN0cmluZyxcbiAgYTogVGVuc29yVmlldyxcbiAgYjogVGVuc29yVmlldyxcbiAgZnVuY0NhbGw6IEJpbmFyeUZ1bmN0aW9uQ2FsbCxcbiAgYWRkaXRpb25hbEltcGxlbWVudGF0aW9uPzogc3RyaW5nLFxuICBvdXRwdXREYXRhVHlwZTogbnVtYmVyID0gYS5kYXRhVHlwZSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgYURpbXMgPSBhLmRpbXMubWFwKE51bWJlcik7XG4gIGNvbnN0IGJEaW1zID0gYi5kaW1zLm1hcChOdW1iZXIpO1xuICBjb25zdCBpc0Jyb2FkY2FzdCA9ICFTaGFwZVV0aWwuYXJlRXF1YWwoYURpbXMsIGJEaW1zKTtcbiAgbGV0IG91dHB1dFNoYXBlID0gYURpbXM7XG4gIGxldCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUoYURpbXMpO1xuXG4gIGxldCB2ZWN0b3JpemUgPSBmYWxzZTtcbiAgbGV0IHNoYXJlZERpbWVuc2lvbkRpdmlzaWJsZUJ5NCA9IGZhbHNlO1xuXG4gIC8vIFRPRE86IGRlYWwgd2l0aCB6ZXJvLXNpemVkIHRlbnNvcnMgKGVnLiBkaW1zPVsxLDBdKVxuICBjb25zdCBjYWNoZUtleUF1eCA9IFtpc0Jyb2FkY2FzdF07XG4gIGlmIChpc0Jyb2FkY2FzdCkge1xuICAgIGNvbnN0IGNhbGN1bGF0ZWRTaGFwZSA9IEJyb2FkY2FzdFV0aWwuY2FsY1NoYXBlKGFEaW1zLCBiRGltcywgZmFsc2UpO1xuICAgIGlmICghY2FsY3VsYXRlZFNoYXBlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCBwZXJmb3JtIGJpbmFyeSBvcCBvbiB0aGUgZ2l2ZW4gdGVuc29yc1wiKTtcbiAgICB9XG4gICAgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVkU2hhcGUuc2xpY2UoKTtcbiAgICBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICAgIGNvbnN0IGlzQU9uZUVsZW1lbnQgPSBTaGFwZVV0aWwuc2l6ZShhRGltcykgPT09IDE7XG4gICAgY29uc3QgaXNCT25lRWxlbWVudCA9IFNoYXBlVXRpbC5zaXplKGJEaW1zKSA9PT0gMTtcbiAgICBjb25zdCBhTGFzdERpbURpdmlzaWJsZUJ5NCA9IGFEaW1zLmxlbmd0aCA+IDAgJiYgYURpbXNbYURpbXMubGVuZ3RoIC0gMV0gJSA0ID09PSAwO1xuICAgIGNvbnN0IGJMYXN0RGltRGl2aXNpYmxlQnk0ID0gYkRpbXMubGVuZ3RoID4gMCAmJiBiRGltc1tiRGltcy5sZW5ndGggLSAxXSAlIDQgPT09IDA7XG4gICAgY2FjaGVLZXlBdXgucHVzaChpc0FPbmVFbGVtZW50KTtcbiAgICBjYWNoZUtleUF1eC5wdXNoKGlzQk9uZUVsZW1lbnQpO1xuICAgIGNhY2hlS2V5QXV4LnB1c2goYUxhc3REaW1EaXZpc2libGVCeTQpO1xuICAgIGNhY2hlS2V5QXV4LnB1c2goYkxhc3REaW1EaXZpc2libGVCeTQpO1xuICAgIC8vIGNoZWNrIHdoZXRoZXIgdmVjdG9yaXplIGNhbiBiZSBlbmFibGVkXG4gICAgbGV0IHNoYXJlZERpbWVuc2lvbiA9IDE7XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBvdXRwdXRTaGFwZS5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZGltQSA9IGFEaW1zW2FEaW1zLmxlbmd0aCAtIGldO1xuICAgICAgY29uc3QgZGltQiA9IGJEaW1zW2JEaW1zLmxlbmd0aCAtIGldO1xuICAgICAgaWYgKGRpbUEgPT09IGRpbUIpIHtcbiAgICAgICAgc2hhcmVkRGltZW5zaW9uICo9IGRpbUE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNoYXJlZERpbWVuc2lvbiAlIDQgPT09IDApIHtcbiAgICAgIHNoYXJlZERpbWVuc2lvbkRpdmlzaWJsZUJ5NCA9IHRydWU7XG4gICAgICB2ZWN0b3JpemUgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoaXNBT25lRWxlbWVudCB8fCBpc0JPbmVFbGVtZW50IHx8IGFMYXN0RGltRGl2aXNpYmxlQnk0IHx8IGJMYXN0RGltRGl2aXNpYmxlQnk0KSB7XG4gICAgICB2ZWN0b3JpemUgPSB0cnVlO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBlbGVtZW50LXdpc2VcbiAgICB2ZWN0b3JpemUgPSB0cnVlO1xuICB9XG4gIGNhY2hlS2V5QXV4LnB1c2godmVjdG9yaXplKTtcblxuICByZXR1cm4ge1xuICAgIG5hbWUsXG4gICAgc2hhZGVyQ2FjaGU6IHtcbiAgICAgIGhpbnQ6IGNhY2hlS2V5ICsgY2FjaGVLZXlBdXgubWFwKCh4KSA9PiB4LnRvU3RyaW5nKCkpLmpvaW4oJ18nKSxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnLCAncmFuayddLFxuICAgIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlOiAoc2hhZGVySGVscGVyKSA9PlxuICAgICAgY3JlYXRlQmluYXJ5T3BQcm9ncmFtU2hhZGVyKFxuICAgICAgICBzaGFkZXJIZWxwZXIsXG4gICAgICAgIGFEaW1zLFxuICAgICAgICBiRGltcyxcbiAgICAgICAgb3V0cHV0U2hhcGUsXG4gICAgICAgIHZlY3Rvcml6ZSxcbiAgICAgICAgaXNCcm9hZGNhc3QsXG4gICAgICAgIHNoYXJlZERpbWVuc2lvbkRpdmlzaWJsZUJ5NCxcbiAgICAgICAgZnVuY0NhbGwsXG4gICAgICAgIGEuZGF0YVR5cGUsXG4gICAgICAgIGIuZGF0YVR5cGUsXG4gICAgICAgIG91dHB1dERhdGFUeXBlLFxuICAgICAgICBhZGRpdGlvbmFsSW1wbGVtZW50YXRpb24sXG4gICAgICApLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IG91dHB1dERhdGFUeXBlIH1dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovIC8gNCAvKiBjb21wb25lbnQgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtczogW1xuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogTWF0aC5jZWlsKFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKSAvIDQpIH0sXG4gICAgICAgIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGFEaW1zLCBiRGltcywgb3V0cHV0U2hhcGUpLFxuICAgICAgXSxcbiAgICB9KSxcbiAgfTtcbn07XG5cbmNvbnN0IHJ1bkJpbmFyeU9wID0gKFxuICBjb250ZXh0OiBDb21wdXRlQ29udGV4dCxcbiAgbmFtZTogc3RyaW5nLFxuICBmdW5jQ2FsbDogQmluYXJ5RnVuY3Rpb25DYWxsLFxuICBhZGRpdGlvbmFsSW1wbGVtZW50YXRpb24/OiBzdHJpbmcsXG4gIGNhY2hlS2V5Pzogc3RyaW5nLFxuICBvdXRwdXREYXRhVHlwZT86IG51bWJlcixcbik6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlQmluYXJ5T3BQcm9ncmFtSW5mbyhcbiAgICAgIG5hbWUsXG4gICAgICBjYWNoZUtleSA/PyAnJyxcbiAgICAgIGNvbnRleHQuaW5wdXRzWzBdLFxuICAgICAgY29udGV4dC5pbnB1dHNbMV0sXG4gICAgICBmdW5jQ2FsbCxcbiAgICAgIGFkZGl0aW9uYWxJbXBsZW1lbnRhdGlvbixcbiAgICAgIG91dHB1dERhdGFUeXBlLFxuICAgICksXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgYWRkID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIHJ1bkJpbmFyeU9wKGNvbnRleHQsICdBZGQnLCAoYSwgYikgPT4gYCR7YX0rJHtifWApO1xufTtcblxuZXhwb3J0IGNvbnN0IGRpdiA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBydW5CaW5hcnlPcChjb250ZXh0LCAnRGl2JywgKGEsIGIpID0+IGAke2F9LyR7Yn1gKTtcbn07XG5cbmV4cG9ydCBjb25zdCBlcXVhbCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBydW5CaW5hcnlPcChcbiAgICBjb250ZXh0LFxuICAgICdFcXVhbCcsXG4gICAgeyBzY2FsYXI6IChhLCBiKSA9PiBgdTMyKCR7YX09PSR7Yn0pYCwgdmVjdG9yOiAoYSwgYikgPT4gYHZlYzQ8dTMyPigke2F9PT0ke2J9KWAgfSxcbiAgICB1bmRlZmluZWQsXG4gICAgdW5kZWZpbmVkLFxuICAgIERhdGFUeXBlLmJvb2wsXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgbXVsID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIHJ1bkJpbmFyeU9wKGNvbnRleHQsICdNdWwnLCAoYSwgYikgPT4gYCR7YX0qJHtifWApO1xufTtcblxuZXhwb3J0IGNvbnN0IHBvdyA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb25zdCB0eXBlID0gaW5wdXRWYXJpYWJsZSgnaW5wdXQnLCBjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSwgY29udGV4dC5pbnB1dHNbMF0uZGltcykudHlwZS52YWx1ZTtcbiAgY29uc3Qgcm91bmRTdHIgPSB0eXBlID09PSAnaTMyJyA/ICdyb3VuZCcgOiAnJztcbiAgcnVuQmluYXJ5T3AoXG4gICAgY29udGV4dCxcbiAgICAnUG93JyxcbiAgICB7IHNjYWxhcjogKGEsIGIpID0+IGBwb3dfY3VzdG9tKCR7YX0sJHtifSlgLCB2ZWN0b3I6IChhLCBiKSA9PiBgcG93X3ZlY3Rvcl9jdXN0b20oJHthfSwke2J9KWAgfSxcbiAgICBgXG4gICAgZm4gcG93X2N1c3RvbShhIDogJHt0eXBlfSwgYiA6ICR7dHlwZX0pIC0+ICR7dHlwZX0ge1xuICAgICAgaWYgKGIgPT0gJHt0eXBlfSgwLjApKSB7XG4gICAgICAgIHJldHVybiAke3R5cGV9KDEuMCk7XG4gICAgICB9IGVsc2UgaWYgKGEgPCAke3R5cGV9KDAuMCkgJiYgZjMyKGIpICE9IGZsb29yKGYzMihiKSkpIHtcbiAgICAgICAgcmV0dXJuICR7dHlwZX0ocG93KGYzMihhKSwgZjMyKGIpKSk7IC8vIE5hTlxuICAgICAgfVxuICAgICAgcmV0dXJuIHNlbGVjdChzaWduKGEpLCAke3R5cGV9KDEuMCksIHJvdW5kKGYzMihhYnMoYikgJSAke3R5cGV9KDIuMCkpKSAhPSAxLjApICogJHt0eXBlfSgke3JvdW5kU3RyfShwb3coZjMyKGFicyhhKSksIGYzMihiKSkpKTtcbiAgICB9XG4gICAgZm4gcG93X3ZlY3Rvcl9jdXN0b20oYSA6IHZlYzQ8JHt0eXBlfT4sIGIgOiB2ZWM0PCR7dHlwZX0+KSAtPiB2ZWM0PCR7dHlwZX0+IHtcbiAgICAgIC8vIFRPRE86IGltcGxlbWVudCB2ZWN0b3JpemVkIHBvd1xuICAgICAgcmV0dXJuIHZlYzQ8JHt0eXBlfT4ocG93X2N1c3RvbShhLngsIGIueCksIHBvd19jdXN0b20oYS55LCBiLnkpLCBwb3dfY3VzdG9tKGEueiwgYi56KSwgcG93X2N1c3RvbShhLncsIGIudykpO1xuICAgIH1cbiAgICAgIGAsXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3Qgc3ViID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIHJ1bkJpbmFyeU9wKGNvbnRleHQsICdTdWInLCAoYSwgYikgPT4gYCR7YX0tJHtifWApO1xufTtcblxuZXhwb3J0IGNvbnN0IGdyZWF0ZXIgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgcnVuQmluYXJ5T3AoXG4gICAgY29udGV4dCxcbiAgICAnR3JlYXRlcicsXG4gICAgeyBzY2FsYXI6IChhLCBiKSA9PiBgdTMyKCR7YX0+JHtifSlgLCB2ZWN0b3I6IChhLCBiKSA9PiBgdmVjNDx1MzI+KCR7YX0+JHtifSlgIH0sXG4gICAgdW5kZWZpbmVkLFxuICAgIHVuZGVmaW5lZCxcbiAgICBEYXRhVHlwZS5ib29sLFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IGxlc3MgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgcnVuQmluYXJ5T3AoXG4gICAgY29udGV4dCxcbiAgICAnTGVzcycsXG4gICAgeyBzY2FsYXI6IChhLCBiKSA9PiBgdTMyKCR7YX08JHtifSlgLCB2ZWN0b3I6IChhLCBiKSA9PiBgdmVjNDx1MzI+KCR7YX08JHtifSlgIH0sXG4gICAgdW5kZWZpbmVkLFxuICAgIHVuZGVmaW5lZCxcbiAgICBEYXRhVHlwZS5ib29sLFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IGdyZWF0ZXJPckVxdWFsID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIHJ1bkJpbmFyeU9wKFxuICAgIGNvbnRleHQsXG4gICAgJ0dyZWF0ZXJPckVxdWFsJyxcbiAgICB7IHNjYWxhcjogKGEsIGIpID0+IGB1MzIoJHthfT49JHtifSlgLCB2ZWN0b3I6IChhLCBiKSA9PiBgdmVjNDx1MzI+KCR7YX0+PSR7Yn0pYCB9LFxuICAgIHVuZGVmaW5lZCxcbiAgICB1bmRlZmluZWQsXG4gICAgRGF0YVR5cGUuYm9vbCxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBsZXNzT3JFcXVhbCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBydW5CaW5hcnlPcChcbiAgICBjb250ZXh0LFxuICAgICdMZXNzT3JFcXVhbCcsXG4gICAgeyBzY2FsYXI6IChhLCBiKSA9PiBgdTMyKCR7YX08PSR7Yn0pYCwgdmVjdG9yOiAoYSwgYikgPT4gYHZlYzQ8dTMyPigke2F9PD0ke2J9KWAgfSxcbiAgICB1bmRlZmluZWQsXG4gICAgdW5kZWZpbmVkLFxuICAgIERhdGFUeXBlLmJvb2wsXG4gICk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3ksIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcywgSW5kaWNlc0hlbHBlciwgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciB9IGZyb20gJy4vY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBDb25jYXRBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXhpczogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0b28gZmV3IGlucHV0cycpO1xuICB9XG4gIGNvbnN0IHJlZmVyZW5jZUluZGV4ID0gMDtcbiAgY29uc3QgcmVmZXJlbmNlSW5wdXQgPSBpbnB1dHNbcmVmZXJlbmNlSW5kZXhdO1xuICBjb25zdCBpbnB1dFR5cGUgPSByZWZlcmVuY2VJbnB1dC5kYXRhVHlwZTtcbiAgY29uc3QgaW5wdXRSYW5rID0gcmVmZXJlbmNlSW5wdXQuZGltcy5sZW5ndGg7XG4gIGlucHV0cy5mb3JFYWNoKChpbnB1dCwgaSkgPT4ge1xuICAgIGlmIChpID09PSByZWZlcmVuY2VJbmRleCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBtYWtlIHN1cmUgdHlwZXMgb2YgYWxsIGlucHV0cyBtYXRjaFxuICAgIGlmIChpbnB1dC5kYXRhVHlwZSAhPT0gaW5wdXRUeXBlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHRlbnNvcnMgc2hvdWxkIGJlIG9uZSB0eXBlJyk7XG4gICAgfVxuICAgIC8vIG1ha2Ugc3VyZSB0aGUgZGltZW5zaW9uYWxpdHkgb2YgYWxsIGlucHV0cyBhcmUgdGhlIHNhbWVcbiAgICBpZiAoaW5wdXQuZGltcy5sZW5ndGggIT09IGlucHV0UmFuaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCB0ZW5zb3JzIHNob3VsZCBoYXZlIHRoZSBzYW1lIHNoYXBlJyk7XG4gICAgfVxuICAgIGlucHV0LmRpbXMuZm9yRWFjaCgoZGltLCBpKSA9PiB7XG4gICAgICBpZiAoaSAhPT0gYXhpcyAmJiBkaW0gIT09IHJlZmVyZW5jZUlucHV0LmRpbXNbaV0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub24gY29uY2F0IGRpbWVuc2lvbnMgbXVzdCBtYXRjaCcpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn07XG5cbmNvbnN0IGNhbGN1bGF0ZUlucHV0SW5kZXhJbXBsID0gKG51bWJlck9mVGVuc29yczogbnVtYmVyLCBzaXplSW5Db25jYXRBeGlzU3RyOiBzdHJpbmcpOiBzdHJpbmcgPT4gYFxuICBmbiBjYWxjdWxhdGVJbnB1dEluZGV4KGluZGV4OiB1MzIpIC0+IHUzMiB7XG4gICAgbGV0IHNpemVJbkNvbmNhdEF4aXMgPSBhcnJheTx1MzIsICR7bnVtYmVyT2ZUZW5zb3JzfXU+KCR7c2l6ZUluQ29uY2F0QXhpc1N0cn0pO1xuICAgIGZvciAodmFyIGk6IHUzMiA9IDB1OyBpIDwgJHtudW1iZXJPZlRlbnNvcnN9OyBpICs9IDF1ICkge1xuICAgICAgaWYgKGluZGV4IDwgc2l6ZUluQ29uY2F0QXhpc1tpXSkge1xuICAgICAgICByZXR1cm4gaTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICR7bnVtYmVyT2ZUZW5zb3JzfXU7XG4gIH1gO1xuXG5jb25zdCBhc3NpZ25PdXRwdXREYXRhID0gKGlucHV0czogcmVhZG9ubHkgSW5kaWNlc0hlbHBlcltdLCBvdXRwdXQ6IEluZGljZXNIZWxwZXIpID0+IHtcbiAgY29uc3QgbnVtYmVyT2ZUZW5zb3JzID0gaW5wdXRzLmxlbmd0aDtcblxuICBjb25zdCBjb2RlTGluZXM6IHN0cmluZ1tdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZUZW5zb3JzOyArK2kpIHtcbiAgICBjb25zdCByZXR1cm5TbmlwcGV0ID0gb3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgaW5wdXRzW2ldLmdldEJ5SW5kaWNlcygnaW5kaWNlcycpKTtcbiAgICBpZiAobnVtYmVyT2ZUZW5zb3JzID09PSAxKSB7XG4gICAgICBjb2RlTGluZXMucHVzaChyZXR1cm5TbmlwcGV0KTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IDApIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKGBpZiAoaW5wdXRJbmRleCA9PSAke2l9dSkgeyAke3JldHVyblNuaXBwZXR9IH1gKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IG51bWJlck9mVGVuc29ycyAtIDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKGBlbHNlIHsgJHtyZXR1cm5TbmlwcGV0fSB9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKGBlbHNlIGlmIChpbnB1dEluZGV4ID09ICR7aX0pIHsgJHtyZXR1cm5TbmlwcGV0fSB9YCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBjb2RlTGluZXMuam9pbignXFxuJyk7XG59O1xuXG5jb25zdCBjcmVhdGVDb25jYXRQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGFkanVzdGVkQXhpczogbnVtYmVyLFxuICBvdXRwdXRTaGFwZTogbnVtYmVyW10sXG4gIGRhdGFUeXBlOiBEYXRhVHlwZSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcblxuICBjb25zdCBzaXplSW5Db25jYXRBeGlzID0gbmV3IEFycmF5PG51bWJlcj4oaW5wdXRzLmxlbmd0aCk7XG4gIGNvbnN0IGlucHV0VmFycyA9IG5ldyBBcnJheTxJbmRpY2VzSGVscGVyPihpbnB1dHMubGVuZ3RoKTtcblxuICBsZXQgcHJldmlvdXNTdW0gPSAwO1xuICBjb25zdCBpbnB1dERlcGVuZGVuY2llczogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXSA9IFtdO1xuICBjb25zdCBpbnB1dFJhbmtzID0gW107XG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFt7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9XTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyArK2kpIHtcbiAgICBwcmV2aW91c1N1bSArPSBpbnB1dHNbaV0uZGltc1thZGp1c3RlZEF4aXNdO1xuICAgIHNpemVJbkNvbmNhdEF4aXNbaV0gPSBwcmV2aW91c1N1bTtcbiAgICBpbnB1dFJhbmtzLnB1c2goaW5wdXRzW2ldLmRpbXMubGVuZ3RoKTtcbiAgICBpbnB1dFZhcnNbaV0gPSBpbnB1dFZhcmlhYmxlKGBpbnB1dCR7aX1gLCBkYXRhVHlwZSwgaW5wdXRSYW5rc1tpXSk7XG4gICAgaW5wdXREZXBlbmRlbmNpZXMucHVzaCgncmFuaycpO1xuICAgIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBzaXplSW5Db25jYXRBeGlzW2ldIH0pO1xuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgKytpKSB7XG4gICAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRzW2ldLmRpbXMpKTtcbiAgfVxuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhvdXRwdXRTaGFwZSkpO1xuXG4gIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBkYXRhVHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3QgaW5kaWNlc0F4aXMgPSBvdXRwdXQuaW5kaWNlc0dldCgnaW5kaWNlcycsIGFkanVzdGVkQXhpcyk7XG4gIGNvbnN0IHNpemVJbkNvbmNhdEF4aXNTdHIgPSBBcnJheS5mcm9tKEFycmF5KHNpemVJbkNvbmNhdEF4aXMubGVuZ3RoKS5rZXlzKCkpXG4gICAgLm1hcCgoaSkgPT4gYHVuaWZvcm1zLnNpemVJbkNvbmNhdEF4aXMke2l9YClcbiAgICAuam9pbignLCcpO1xuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IGBcblxuICAkeygoKSA9PiB7XG4gICAgc2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0U2l6ZScsICd1MzInKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgc2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybShgc2l6ZUluQ29uY2F0QXhpcyR7aX1gLCAndTMyJyk7XG4gICAgfVxuICAgIHJldHVybiBzaGFkZXJIZWxwZXIuZGVjbGFyZVZhcmlhYmxlcyguLi5pbnB1dFZhcnMsIG91dHB1dCk7XG4gIH0pKCl9XG5cbiAgJHtjYWxjdWxhdGVJbnB1dEluZGV4SW1wbChzaXplSW5Db25jYXRBeGlzLmxlbmd0aCwgc2l6ZUluQ29uY2F0QXhpc1N0cil9XG5cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0U2l6ZScpfVxuXG4gICAgdmFyIGluZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG5cbiAgICBsZXQgaW5wdXRJbmRleCA9IGNhbGN1bGF0ZUlucHV0SW5kZXgoJHtpbmRpY2VzQXhpc30pO1xuICAgIGlmIChpbnB1dEluZGV4ICE9IDB1KSB7XG4gICAgICBsZXQgc2l6ZUluQ29uY2F0QXhpcyA9IGFycmF5PHUzMiwgJHtzaXplSW5Db25jYXRBeGlzLmxlbmd0aH11Pigke3NpemVJbkNvbmNhdEF4aXNTdHJ9KTtcbiAgICAgICR7aW5kaWNlc0F4aXN9IC09IHNpemVJbkNvbmNhdEF4aXNbaW5wdXRJbmRleCAtIDF1XTtcbiAgICB9XG5cbiAgICAke2Fzc2lnbk91dHB1dERhdGEoaW5wdXRWYXJzLCBvdXRwdXQpfVxuICB9YDtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdDb25jYXQnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke2FkanVzdGVkQXhpc31gLCBpbnB1dERlcGVuZGVuY2llcyB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbmNhdCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogQ29uY2F0QXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBjb250ZXh0LmlucHV0cztcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBhZGp1c3RlZEF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0U2hhcGUubGVuZ3RoKTtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhZGp1c3RlZEF4aXMpO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0U2hhcGUuc2xpY2UoKTtcbiAgb3V0cHV0U2hhcGVbYWRqdXN0ZWRBeGlzXSA9IGlucHV0cy5yZWR1Y2UoXG4gICAgKHN1bSwgaW5wdXQpID0+IHN1bSArIChpbnB1dC5kaW1zLmxlbmd0aCA+IGFkanVzdGVkQXhpcyA/IGlucHV0LmRpbXNbYWRqdXN0ZWRBeGlzXSA6IDApLFxuICAgIDAsXG4gICk7XG4gIC8vIDAgbGVuZ3RoIHRlbnNvcnMgYXJlIHZhbGlkIGZvciBjb25jYXQsIHJlbW92ZSB0aGVtXG4gIGNvbnN0IG5vbkVtcHR5SW5wdXRzID0gaW5wdXRzLmZpbHRlcigoaW5wdXQpID0+IFNoYXBlVXRpbC5zaXplKGlucHV0LmRpbXMpID4gMCk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVDb25jYXRQcm9ncmFtSW5mbyhub25FbXB0eUlucHV0cywgYWRqdXN0ZWRBeGlzLCBvdXRwdXRTaGFwZSwgaW5wdXRzWzBdLmRhdGFUeXBlKSwge1xuICAgIGlucHV0czogbm9uRW1wdHlJbnB1dHMsXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ29uY2F0QXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IENvbmNhdEF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpczogYXR0cmlidXRlcy5heGlzIGFzIG51bWJlciB9KTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBNQVhfQ0xJUCwgTUlOX0NMSVAgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBVbmlmb3Jtc0FycmF5VHlwZSB9IGZyb20gJy4vY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIHtcbiAgcmVhZG9ubHkgYWN0aXZhdGlvbjogc3RyaW5nO1xuICByZWFkb25seSBjbGlwTWluPzogbnVtYmVyO1xuICByZWFkb25seSBjbGlwTWF4PzogbnVtYmVyO1xuICByZWFkb25seSBhbHBoYT86IG51bWJlcjtcbiAgcmVhZG9ubHkgYmV0YT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGdldEFjdGl2YXRpb25TbmlwcGV0ID0gKFxuICBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuICB2YWx1ZVR5cGU6IHN0cmluZyxcbiAgYmFzZVR5cGUgPSAnZjMyJyxcbik6IHN0cmluZyA9PiB7XG4gIHN3aXRjaCAoYXR0cmlidXRlcy5hY3RpdmF0aW9uKSB7XG4gICAgY2FzZSAnUmVsdSc6XG4gICAgICByZXR1cm4gYHZhbHVlID0gbWF4KHZhbHVlLCAke3ZhbHVlVHlwZX0oMC4wKSk7YDtcbiAgICBjYXNlICdTaWdtb2lkJzpcbiAgICAgIHJldHVybiBgdmFsdWUgPSAoJHt2YWx1ZVR5cGV9KDEuMCkgLyAoJHt2YWx1ZVR5cGV9KDEuMCkgKyBleHAoLXZhbHVlKSkpO2A7XG4gICAgY2FzZSAnQ2xpcCc6XG4gICAgICByZXR1cm4gYHZhbHVlID0gY2xhbXAodmFsdWUsICR7dmFsdWVUeXBlfSgke2Jhc2VUeXBlfSh1bmlmb3Jtcy5jbGlwX21pbikpLCAke3ZhbHVlVHlwZX0oJHtcbiAgICAgICAgYmFzZVR5cGVcbiAgICAgIH0odW5pZm9ybXMuY2xpcF9tYXgpKSk7YDtcbiAgICBjYXNlICdIYXJkU2lnbW9pZCc6XG4gICAgICByZXR1cm4gYHZhbHVlID0gbWF4KCR7dmFsdWVUeXBlfSgwLjApLCBtaW4oJHt2YWx1ZVR5cGV9KDEuMCksICR7YmFzZVR5cGV9KHVuaWZvcm1zLmFscGhhKSAqIHZhbHVlICsgJHtcbiAgICAgICAgYmFzZVR5cGVcbiAgICAgIH0odW5pZm9ybXMuYmV0YSkpKTtgO1xuICAgIGNhc2UgJ0xlYWt5UmVsdSc6XG4gICAgICByZXR1cm4gYHZhbHVlID0gc2VsZWN0KCR7YmFzZVR5cGV9KHVuaWZvcm1zLmFscGhhKSAqIHZhbHVlLCB2YWx1ZSwgdmFsdWUgPj0gJHt2YWx1ZVR5cGV9KDAuMCkpO2A7XG4gICAgY2FzZSAnVGFuaCc6XG4gICAgICByZXR1cm4gYGxldCBlMnggPSBleHAoLTIuMCAqIGFicyh2YWx1ZSkpO1xuICAgICAgICAgICAgICB2YWx1ZSA9IHNpZ24odmFsdWUpICogKDEuMCAtIGUyeCkgLyAoMS4wICsgZTJ4KTtcbiAgICAgICAgYDtcbiAgICBjYXNlICcnOlxuICAgICAgcmV0dXJuICcnO1xuICAgIC8vIFRPRE86IGFkZGluZyBvdGhlciBhY3RpdmF0aW9ucyB0aGF0IGNhbiBiZSBmdXNlZC5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBhY3RpdmF0aW9uICR7YXR0cmlidXRlcy5hY3RpdmF0aW9ufWApO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zRGF0YSA9IChcbiAgYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbiAgcHJvZ3JhbVVuaWZvcm06IFByb2dyYW1Vbmlmb3JtW10sXG4pID0+IHtcbiAgaWYgKGF0dHJpYnV0ZXMuYWN0aXZhdGlvbiA9PT0gJ0NsaXAnKSB7XG4gICAgcHJvZ3JhbVVuaWZvcm0ucHVzaChcbiAgICAgIHsgdHlwZTogRGF0YVR5cGUuZmxvYXQsIGRhdGE6IGF0dHJpYnV0ZXMuY2xpcE1heCEgfSxcbiAgICAgIHsgdHlwZTogRGF0YVR5cGUuZmxvYXQsIGRhdGE6IGF0dHJpYnV0ZXMuY2xpcE1pbiEgfSxcbiAgICApO1xuICB9IGVsc2UgaWYgKGF0dHJpYnV0ZXMuYWN0aXZhdGlvbiA9PT0gJ0hhcmRTaWdtb2lkJykge1xuICAgIHByb2dyYW1Vbmlmb3JtLnB1c2goXG4gICAgICB7IHR5cGU6IERhdGFUeXBlLmZsb2F0LCBkYXRhOiBhdHRyaWJ1dGVzLmFscGhhISB9LFxuICAgICAgeyB0eXBlOiBEYXRhVHlwZS5mbG9hdCwgZGF0YTogYXR0cmlidXRlcy5iZXRhISB9LFxuICAgICk7XG4gIH0gZWxzZSBpZiAoYXR0cmlidXRlcy5hY3RpdmF0aW9uID09PSAnTGVha3lSZWx1Jykge1xuICAgIHByb2dyYW1Vbmlmb3JtLnB1c2goeyB0eXBlOiBEYXRhVHlwZS5mbG9hdCwgZGF0YTogYXR0cmlidXRlcy5hbHBoYSEgfSk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXMgPSAoYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcywgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlKSA9PiB7XG4gIGlmIChhdHRyaWJ1dGVzLmFjdGl2YXRpb24gPT09ICdDbGlwJykge1xuICAgIHVuaWZvcm1zLnB1c2goeyBuYW1lOiAnY2xpcF9tYXgnLCB0eXBlOiAnZjMyJyB9LCB7IG5hbWU6ICdjbGlwX21pbicsIHR5cGU6ICdmMzInIH0pO1xuICB9IGVsc2UgaWYgKGF0dHJpYnV0ZXMuYWN0aXZhdGlvbiA9PT0gJ0hhcmRTaWdtb2lkJykge1xuICAgIHVuaWZvcm1zLnB1c2goeyBuYW1lOiAnYWxwaGEnLCB0eXBlOiAnZjMyJyB9LCB7IG5hbWU6ICdiZXRhJywgdHlwZTogJ2YzMicgfSk7XG4gIH0gZWxzZSBpZiAoYXR0cmlidXRlcy5hY3RpdmF0aW9uID09PSAnTGVha3lSZWx1Jykge1xuICAgIHVuaWZvcm1zLnB1c2goeyBuYW1lOiAnYWxwaGEnLCB0eXBlOiAnZjMyJyB9KTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyA9IChcbiAgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQsXG4pOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYWN0aXZhdGlvbiA9IChhdHRyaWJ1dGVzPy5hY3RpdmF0aW9uIGFzIHN0cmluZykgfHwgJyc7XG4gIGlmIChhY3RpdmF0aW9uID09PSAnSGFyZFNpZ21vaWQnKSB7XG4gICAgY29uc3QgW2FscGhhLCBiZXRhXSA9IChhdHRyaWJ1dGVzPy5hY3RpdmF0aW9uX3BhcmFtcyBhcyBbbnVtYmVyLCBudW1iZXJdKSB8fCBbMC4yLCAwLjVdO1xuICAgIHJldHVybiB7IGFjdGl2YXRpb24sIGFscGhhLCBiZXRhIH07XG4gIH0gZWxzZSBpZiAoYWN0aXZhdGlvbiA9PT0gJ0NsaXAnKSB7XG4gICAgY29uc3QgW2NsaXBNaW4sIGNsaXBNYXhdID0gKGF0dHJpYnV0ZXM/LmFjdGl2YXRpb25fcGFyYW1zIGFzIFtudW1iZXIsIG51bWJlcl0pIHx8IFtNSU5fQ0xJUCwgTUFYX0NMSVBdO1xuICAgIHJldHVybiB7IGFjdGl2YXRpb24sIGNsaXBNYXgsIGNsaXBNaW4gfTtcbiAgfSBlbHNlIGlmIChhY3RpdmF0aW9uID09PSAnTGVha3lSZWx1Jykge1xuICAgIGNvbnN0IFthbHBoYV0gPSAoYXR0cmlidXRlcz8uYWN0aXZhdGlvbl9wYXJhbXMgYXMgW251bWJlcl0pIHx8IFswLjAxXTtcbiAgICByZXR1cm4geyBhY3RpdmF0aW9uLCBhbHBoYSB9O1xuICB9XG4gIHJldHVybiB7IGFjdGl2YXRpb24gfTtcbn07XG4iLCAiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vLyBzYW1wbGVkIGZyb20gW0B0ZW5zb3JmbG93L3RmanNdIHRmanMtYmFja2VuZC13ZWJncHUvc3JjL2FjdGl2YXRpb25fdXRpbC50c1xuLy9cbi8vIG1vZGlmaWVkIHRvIGZpdCB0aGUgbmVlZHMgb2YgdGhlIHByb2plY3RcblxuZXhwb3J0IGNvbnN0IHR5cGVTbmlwcGV0ID0gKGNvbXBvbmVudDogbnVtYmVyLCBkYXRhVHlwZTogc3RyaW5nKSA9PiB7XG4gIHN3aXRjaCAoY29tcG9uZW50KSB7XG4gICAgY2FzZSAxOlxuICAgICAgcmV0dXJuIGRhdGFUeXBlO1xuICAgIGNhc2UgMjpcbiAgICAgIHJldHVybiBgdmVjMjwke2RhdGFUeXBlfT5gO1xuICAgIGNhc2UgMzpcbiAgICAgIHJldHVybiBgdmVjMzwke2RhdGFUeXBlfT5gO1xuICAgIGNhc2UgNDpcbiAgICAgIHJldHVybiBgdmVjNDwke2RhdGFUeXBlfT5gO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29tcG9uZW50fS1jb21wb25lbnQgaXMgbm90IHN1cHBvcnRlZC5gKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGJpYXNTbmlwcGV0ID0gKGhhc0JpYXM6IGJvb2xlYW4pOiBzdHJpbmcgPT4gYFxuICAgICAgJHtoYXNCaWFzID8gJ3ZhbHVlID0gdmFsdWUgKyBnZXRCaWFzQnlPdXRwdXRDb29yZHMoY29vcmRzKTsnIDogJyd9XG4gICAgICBgO1xuIiwgIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuLy8gc2FtcGxlZCBmcm9tIFtAdGVuc29yZmxvdy90ZmpzXSB0ZmpzLWNvcmUvc3JjL29wcy9jb252X3V0aWwudHNcbi8vXG4vLyBtb2RpZmllZCB0byBmaXQgdGhlIG5lZWRzIG9mIHRoZSBwcm9qZWN0XG5cbmV4cG9ydCBjb25zdCB1dGlsRnVuY3Rpb25zID0gKHN0cmlkZVN0cjogc3RyaW5nKSA9PiBgXG5mbiBnZXRJbmRleEZyb21Db29yZHM0RChjb29yZHMgOiB2ZWM0PGkzMj4sIHNoYXBlIDogdmVjNDxpMzI+KSAtPiBpMzIge1xuICByZXR1cm4gZG90KGNvb3JkcywgdmVjNDxpMzI+KFxuICAgICAgc2hhcGUueSAqIHNoYXBlLnogKiBzaGFwZS53LCBzaGFwZS56ICogc2hhcGUudywgc2hhcGUudywgMSkpO1xufVxuZm4gZ2V0T3V0cHV0SW5kZXhGcm9tQ29vcmRzKGNvb3JkcyA6IHZlYzQ8aTMyPikgLT4gaTMyIHtcbiAgcmV0dXJuIGRvdChjb29yZHMsIHZlYzQ8aTMyPihcbiAgICBpMzIoJHtzdHJpZGVTdHJ9LngpLCBpMzIoJHtzdHJpZGVTdHJ9LnkpLCBpMzIoJHtzdHJpZGVTdHJ9LnopLCAxKSk7XG59XG5gO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIGdldEVsZW1lbnRBdCxcbiAgZ2V0TWF4Q29tcG9uZW50cyxcbiAgSW5kaWNlc0hlbHBlcixcbiAgaW5wdXRWYXJpYWJsZSxcbiAgaW50ZXJuYWxWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbiAgdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlLFxuICBVbmlmb3Jtc0FycmF5VHlwZSxcbn0gZnJvbSAnLi9jb21tb24nO1xuaW1wb3J0IHtcbiAgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zLFxuICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXNEYXRhLFxuICBnZXRBY3RpdmF0aW9uU25pcHBldCxcbiAgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbn0gZnJvbSAnLi9mdXNlLXV0aWxzJztcblxuLy8gSGVscGVyIHRoYXQgY29udmVydCBvdXRwdXQgYmF0Y2ggaW5kaWNlcyB0byBpbnB1dCBiYXRjaCBpbmRpY2VzIHVzaW5nIG9ubHkgdGhlIHJhbmsgYW5kXG4vLyB0aGUgc2hhcGUgaW5mb3JtYXRpb24gaW4gdW5pZm9ybVxuZXhwb3J0IGNvbnN0IGNvbnZlcnRPdXRwdXRCYXRjaEluZGljZXNUb0lucHV0QmF0Y2hJbmRpY2VzID0gKFxuICB0YXJnZXRJbmRpY2VzTmFtZTogc3RyaW5nLFxuICBpbnB1dFZhcmlhYmxlOiBJbmRpY2VzSGVscGVyLFxuICBpbnB1dEJhdGNoUmFuazogbnVtYmVyLFxuICBvdXRwdXRCYXRjaFJhbms6IG51bWJlcixcbiAgYmF0Y2hJbmRpY2VzTmFtZTogc3RyaW5nLFxuKSA9PiB7XG4gIC8vIEFzc3VtZSBvdXRwdXRCYXRjaFJhbmsgPj0gaW5wdXRCYXRjaFJhbmssIHRoZSBmaXJzdCBvdXRwdXRCYXRjaFJhbmsgLSBpbnB1dEJhdGNoUmFuayBvZlxuICAvLyBvdXRwdXRCYXRjaFJhbmsgc2hvdWxkIGJlIGlnbm9yZWQuXG4gIGNvbnN0IGV4dGVuZGluZ0lucHV0UmFuayA9IG91dHB1dEJhdGNoUmFuayAtIGlucHV0QmF0Y2hSYW5rO1xuICByZXR1cm4gYFxuICAgICAgJHtBcnJheS5mcm9tKHsgbGVuZ3RoOiBpbnB1dEJhdGNoUmFuayB9KVxuICAgICAgICAubWFwKFxuICAgICAgICAgIChfLCBpKSA9PiBgXG4gICAgICBpZiAoJHtnZXRFbGVtZW50QXQoaW5wdXRWYXJpYWJsZS5zaGFwZSwgaSwgaW5wdXRWYXJpYWJsZS5yYW5rKX0gIT0gMSkge1xuICAgICAgICAke2lucHV0VmFyaWFibGUuaW5kaWNlc1NldCh0YXJnZXRJbmRpY2VzTmFtZSwgaSwgZ2V0RWxlbWVudEF0KGJhdGNoSW5kaWNlc05hbWUsIGkgKyBleHRlbmRpbmdJbnB1dFJhbmssIG91dHB1dEJhdGNoUmFuaykpfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgJHtpbnB1dFZhcmlhYmxlLmluZGljZXNTZXQodGFyZ2V0SW5kaWNlc05hbWUsIGksIDApfVxuICAgICAgfWAsXG4gICAgICAgIClcbiAgICAgICAgLmpvaW4oJycpfVxuYDtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVOYWl2ZU1hdG11bFByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgcmVzaGFwZWRPdXRwdXRTaGFwZT86IHJlYWRvbmx5IG51bWJlcltdLFxuICBpc0NoYW5uZWxzTGFzdCA9IGZhbHNlIC8qIG9ubHkgdXNlZCBmb3IgY29udjJkQnlNYXRNdWwqLyxcbiAgc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24/OiAoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKSA9PiBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgYVNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGJTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuXG4gIGNvbnN0IE0gPSBhU2hhcGVbYVNoYXBlLmxlbmd0aCAtIDJdO1xuICBjb25zdCBOID0gYlNoYXBlW2JTaGFwZS5sZW5ndGggLSAxXTtcbiAgY29uc3QgSyA9IGFTaGFwZVthU2hhcGUubGVuZ3RoIC0gMV07XG4gIGNvbnN0IGNvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKE4pO1xuICBjb25zdCBhQ29tcG9uZW50cyA9IGdldE1heENvbXBvbmVudHMoSyk7XG4gIGNvbnN0IG91dHB1dE51bWJlciA9IGdldE1heENvbXBvbmVudHMoTSk7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSkgLyBjb21wb25lbnRzIC8gb3V0cHV0TnVtYmVyO1xuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gIGNvbnN0IG91dGVyRGltcyA9IHJlc2hhcGVkT3V0cHV0U2hhcGUgPyByZXNoYXBlZE91dHB1dFNoYXBlLnNsaWNlKDAsIC0yKSA6IG91dHB1dFNoYXBlLnNsaWNlKDAsIC0yKTtcbiAgY29uc3QgYmF0Y2hTaXplID0gU2hhcGVVdGlsLnNpemUob3V0ZXJEaW1zKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGVJblNoYWRlciA9IFtiYXRjaFNpemUsIE0sIE5dO1xuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBNIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IE4gfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogSyB9LFxuICBdO1xuICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXNEYXRhKGFjdGl2YXRpb25BdHRyaWJ1dGVzLCBwcm9ncmFtVW5pZm9ybXMpO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhvdXRlckRpbXMsIGFTaGFwZSwgYlNoYXBlKSk7XG4gIGlmIChoYXNCaWFzKSB7XG4gICAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRzWzJdLmRpbXMpKTtcbiAgfVxuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhvdXRwdXRTaGFwZUluU2hhZGVyKSk7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgYmF0Y2hEaW1zID0gaW50ZXJuYWxWYXJpYWJsZSgnYmF0Y2hfZGltcycsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0ZXJEaW1zLmxlbmd0aCk7XG4gICAgY29uc3QgYSA9IGlucHV0VmFyaWFibGUoJ2EnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGFTaGFwZS5sZW5ndGgsIGFDb21wb25lbnRzKTtcbiAgICBjb25zdCBiID0gaW5wdXRWYXJpYWJsZSgnYicsIGlucHV0c1sxXS5kYXRhVHlwZSwgYlNoYXBlLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGVJblNoYWRlci5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGJhc2VUeXBlID0gdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlKG91dHB1dC50eXBlLnRlbnNvcik7XG4gICAgY29uc3QgYXBwbHlBY3RpdmF0aW9uID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYWN0aXZhdGlvbkF0dHJpYnV0ZXMsIG91dHB1dC50eXBlLnZhbHVlLCBiYXNlVHlwZSk7XG4gICAgY29uc3QgaW5wdXRWYXJpYWJsZXMgPSBbYSwgYl07XG4gICAgbGV0IHByb2Nlc3NCaWFzID0gJyc7XG4gICAgaWYgKGhhc0JpYXMpIHtcbiAgICAgIGNvbnN0IGJpYXNDb21wb25lbnRzID0gaXNDaGFubmVsc0xhc3QgPyBjb21wb25lbnRzIDogMTtcbiAgICAgIGlucHV0VmFyaWFibGVzLnB1c2goaW5wdXRWYXJpYWJsZSgnYmlhcycsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoLCBiaWFzQ29tcG9uZW50cykpO1xuICAgICAgcHJvY2Vzc0JpYXMgPSBgJHtcbiAgICAgICAgaXNDaGFubmVsc0xhc3QgPyBgdmFsdWUgKz0gYmlhc1tjb2wgLyAke2JpYXNDb21wb25lbnRzfV07YCA6IGB2YWx1ZSArPSAke291dHB1dC50eXBlLnZhbHVlfShiaWFzW3JvdyArIGldKTtgXG4gICAgICB9YDtcbiAgICB9XG5cbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdNJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ04nLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnSycsIHR5cGU6ICd1MzInIH0sXG4gICAgXTtcbiAgICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXMoYWN0aXZhdGlvbkF0dHJpYnV0ZXMsIHVuaWZvcm1zKTtcblxuICAgIGNvbnN0IGNhbGNSZXN1bHQgPSAoKTogc3RyaW5nID0+IHtcbiAgICAgIGxldCBjYWxjU3RyID0gYHZhciBhX2RhdGE6ICR7YS50eXBlLnZhbHVlfTtgO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhQ29tcG9uZW50czsgaSsrKSB7XG4gICAgICAgIGNhbGNTdHIgKz0gYFxuICAgICAgICAgICAgICBsZXQgYl9kYXRhJHtpfSA9IGJbKGJfb2Zmc2V0ICsgKGsgKyAke2l9KSAqIHVuaWZvcm1zLk4gKyBjb2wpIC8gJHtjb21wb25lbnRzfV07YDtcbiAgICAgIH1cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0TnVtYmVyOyBpKyspIHtcbiAgICAgICAgY2FsY1N0ciArPSBgYV9kYXRhID0gYVsoYV9vZmZzZXQgKyAocm93ICsgJHtpfSkgKiB1bmlmb3Jtcy5LICsgaykgLyAke2FDb21wb25lbnRzfV07YDtcblxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGFDb21wb25lbnRzOyBqKyspIHtcbiAgICAgICAgICBjYWxjU3RyICs9IGBcbiAgICAgICAgICAgIHZhbHVlc1ske2l9XSA9IGZtYSgke2IudHlwZS52YWx1ZX0oYV9kYXRhJHthQ29tcG9uZW50cyA9PT0gMSA/ICcnIDogYFske2p9XWB9KSwgYl9kYXRhJHtqfSwgdmFsdWVzWyR7aX1dKTtcXG5gO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gY2FsY1N0cjtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGBcbiAgJHtzaGFkZXJIZWxwZXJcbiAgICAucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcylcbiAgICAucmVnaXN0ZXJJbnRlcm5hbFZhcmlhYmxlcyhiYXRjaERpbXMpXG4gICAgLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJpYWJsZXMsIG91dHB1dCl9XG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgbGV0IGNvbCA9IChnbG9iYWxfaWR4ICUgKHVuaWZvcm1zLk4gLyAke2NvbXBvbmVudHN9KSkgKiAke2NvbXBvbmVudHN9O1xuICAgIHZhciBpbmRleDEgPSBnbG9iYWxfaWR4IC8gKHVuaWZvcm1zLk4gLyAke2NvbXBvbmVudHN9KTtcbiAgICBsZXQgc3RyaWRlMSA9IHVuaWZvcm1zLk0gLyAke291dHB1dE51bWJlcn07XG4gICAgbGV0IHJvdyA9IChpbmRleDEgJSBzdHJpZGUxKSAqICR7b3V0cHV0TnVtYmVyfTtcbiAgICBsZXQgYmF0Y2ggPSBpbmRleDEgLyBzdHJpZGUxO1xuXG4gICAgJHtvdXRwdXRTaGFwZS5sZW5ndGggPT09IDIgPyAnJyA6IGBsZXQgYmF0Y2hfaW5kaWNlcyA9ICR7YmF0Y2hEaW1zLm9mZnNldFRvSW5kaWNlcygnYmF0Y2gnKX07YH1cblxuICAgIHZhciBhX2luZGljZXM6ICR7YS50eXBlLmluZGljZXN9O1xuICAgICR7Y29udmVydE91dHB1dEJhdGNoSW5kaWNlc1RvSW5wdXRCYXRjaEluZGljZXMoJ2FfaW5kaWNlcycsIGEsIGEucmFuayAtIDIsIGJhdGNoRGltcy5yYW5rLCAnYmF0Y2hfaW5kaWNlcycpfVxuICAgICR7YS5pbmRpY2VzU2V0KCdhX2luZGljZXMnLCBhLnJhbmsgLSAyLCAwKX1cbiAgICAke2EuaW5kaWNlc1NldCgnYV9pbmRpY2VzJywgYS5yYW5rIC0gMSwgMCl9XG4gICAgbGV0IGFfb2Zmc2V0ID0gJHthLmluZGljZXNUb09mZnNldCgnYV9pbmRpY2VzJyl9O1xuXG4gICAgdmFyIGJfaW5kaWNlczogJHtiLnR5cGUuaW5kaWNlc307XG4gICAgJHtjb252ZXJ0T3V0cHV0QmF0Y2hJbmRpY2VzVG9JbnB1dEJhdGNoSW5kaWNlcygnYl9pbmRpY2VzJywgYiwgYi5yYW5rIC0gMiwgYmF0Y2hEaW1zLnJhbmssICdiYXRjaF9pbmRpY2VzJyl9XG4gICAgJHtiLmluZGljZXNTZXQoJ2JfaW5kaWNlcycsIGIucmFuayAtIDIsIDApfVxuICAgICR7Yi5pbmRpY2VzU2V0KCdiX2luZGljZXMnLCBiLnJhbmsgLSAxLCAwKX1cbiAgICBsZXQgYl9vZmZzZXQgPSAke2IuaW5kaWNlc1RvT2Zmc2V0KCdiX2luZGljZXMnKX07XG4gICAgdmFyIHZhbHVlczogYXJyYXk8JHtvdXRwdXQudHlwZS52YWx1ZX0sICR7b3V0cHV0TnVtYmVyfT47XG4gICAgZm9yICh2YXIgazogdTMyID0gMHU7IGsgPCB1bmlmb3Jtcy5LOyBrID0gayArICR7YUNvbXBvbmVudHN9KSB7XG4gICAgICAke2NhbGNSZXN1bHQoKX1cbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDB1OyBpIDwgJHtvdXRwdXROdW1iZXJ9dTsgaSsrKSB7XG4gICAgICB2YXIgdmFsdWUgPSB2YWx1ZXNbaV07XG4gICAgICAke3Byb2Nlc3NCaWFzfVxuICAgICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgICBsZXQgY3VyX2luZGljZXMgPSAke291dHB1dC50eXBlLmluZGljZXN9KGJhdGNoLCByb3cgKyBpLCBjb2wpO1xuICAgICAgbGV0IG9mZnNldCA9ICR7b3V0cHV0LmluZGljZXNUb09mZnNldCgnY3VyX2luZGljZXMnKX07XG4gICAgICAke291dHB1dC5zZXRCeU9mZnNldChgb2Zmc2V0IC8gJHtjb21wb25lbnRzfWAsICd2YWx1ZScpfTtcbiAgICB9XG4gIH1cbiAgYDtcbiAgfTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnTWF0TXVsTmFpdmUnLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHthY3RpdmF0aW9uQXR0cmlidXRlcy5hY3RpdmF0aW9ufTske2NvbXBvbmVudHN9OyR7YUNvbXBvbmVudHN9OyR7b3V0cHV0TnVtYmVyfTske2lzQ2hhbm5lbHNMYXN0fWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llczogaGFzQmlhcyA/IFsncmFuaycsICdyYW5rJywgJ3JhbmsnXSA6IFsncmFuaycsICdyYW5rJ10sXG4gICAgfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW1xuICAgICAgICB7XG4gICAgICAgICAgZGltczogc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24gPyBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbihvdXRwdXRTaGFwZSkgOiBvdXRwdXRTaGFwZSxcbiAgICAgICAgICBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuIiwgIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuLy8gc2FtcGxlZCBmcm9tIFtAdGVuc29yZmxvdy90ZmpzXSB0ZmpzLWJhY2tlbmQtd2ViZ3B1L3NyYy9tYXRtdWxfcGFja2VkX3dlYmdwdS50c1xuLy9cbi8vIG1vZGlmaWVkIHRvIGZpdCB0aGUgbmVlZHMgb2YgdGhlIHByb2plY3RcblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3ksIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIEluZGljZXNIZWxwZXIsXG4gIGlucHV0VmFyaWFibGUsXG4gIGludGVybmFsVmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZSxcbiAgVW5pZm9ybXNBcnJheVR5cGUsXG59IGZyb20gJy4uL2NvbW1vbic7XG5pbXBvcnQge1xuICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXMsXG4gIGFwcGVuZEFjdGl2YXRpb25Vbmlmb3Jtc0RhdGEsXG4gIGdldEFjdGl2YXRpb25TbmlwcGV0LFxuICBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxufSBmcm9tICcuLi9mdXNlLXV0aWxzJztcbmltcG9ydCB7IGNvbnZlcnRPdXRwdXRCYXRjaEluZGljZXNUb0lucHV0QmF0Y2hJbmRpY2VzIH0gZnJvbSAnLi4vbWF0bXVsLXNoYWRlcnMnO1xuXG5pbXBvcnQgeyB0eXBlU25pcHBldCB9IGZyb20gJy4vYWN0aXZhdGlvbl91dGlsJztcblxuY29uc3Qgd3JpdGVEYXRhVG9TdWJBVmVjNFNuaXBwZXQgPSAodHJhbnNwb3NlOiBib29sZWFuLCBiYXRjaERpbXM/OiBJbmRpY2VzSGVscGVyKSA9PiB7XG4gIGlmICh0cmFuc3Bvc2UpIHtcbiAgICByZXR1cm4gYFxuICAgICAgICBtbV9Bc3ViW2lucHV0Um93XVtpbnB1dENvbF0gPSBtbV9yZWFkQShiYXRjaCxcbiAgICAgICAgICBrU3RhcnQgKyBpbnB1dFJvdyxcbiAgICAgICAgICBnbG9iYWxSb3dTdGFydCAvIGlubmVyRWxlbWVudFNpemUgKyBpbnB1dENvbCR7YmF0Y2hEaW1zID8gJywgYmF0Y2hJbmRpY2VzJyA6ICcnfSk7XG4gICAgICAgIGA7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGBcbiAgICAgICAgbW1fQXN1YltpbnB1dFJvd11baW5wdXRDb2xdID0gbW1fcmVhZEEoYmF0Y2gsXG4gICAgICAgICAgZ2xvYmFsUm93ICsgaW5uZXJSb3csXG4gICAgICAgICAga1N0YXJ0IC8gaW5uZXJFbGVtZW50U2l6ZSArIGlucHV0Q29sJHtiYXRjaERpbXMgPyAnLCBiYXRjaEluZGljZXMnIDogJyd9KTtcbiAgICAgICAgYDtcbiAgfVxufTtcblxuY29uc3QgY2FsY3VsYXRlUmVzdWx0U25pcHBldCA9ICh0cmFuc3Bvc2VBOiBib29sZWFuLCBpbm5lckVsZW1lbnRTaXplOiBudW1iZXIpID0+IHtcbiAgaWYgKHRyYW5zcG9zZUEpIHtcbiAgICByZXR1cm4gYFxuICAgICAgICBsZXQgQUNhY2hlZDAgPSBtbV9Bc3ViW2sgKiBpbm5lckVsZW1lbnRTaXplXVtsb2NhbFJvd107XG4gICAgICAgIGxldCBBQ2FjaGVkMSA9IG1tX0FzdWJbayAqIGlubmVyRWxlbWVudFNpemUgKyAxXVtsb2NhbFJvd107XG4gICAgICAgIGxldCBBQ2FjaGVkMiA9IG1tX0FzdWJbayAqIGlubmVyRWxlbWVudFNpemUgKyAyXVtsb2NhbFJvd107XG4gICAgICAgICR7aW5uZXJFbGVtZW50U2l6ZSA9PT0gMyA/ICcnIDogJ2xldCBBQ2FjaGVkMyA9IG1tX0FzdWJbayAqIGlubmVyRWxlbWVudFNpemUgKyAzXVtsb2NhbFJvd107J31cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByb3dQZXJUaHJlYWQ7IGkgPSBpICsgMSkge1xuICAgICAgICAgIGFjY1tpXSA9IEJDYWNoZWQwICogQUNhY2hlZDBbaV0gKyBhY2NbaV07XG4gICAgICAgICAgYWNjW2ldID0gQkNhY2hlZDEgKiBBQ2FjaGVkMVtpXSArIGFjY1tpXTtcbiAgICAgICAgICBhY2NbaV0gPSBCQ2FjaGVkMiAqIEFDYWNoZWQyW2ldICsgYWNjW2ldO1xuICAgICAgICAgICR7aW5uZXJFbGVtZW50U2l6ZSA9PT0gMyA/ICcnIDogJ2FjY1tpXSA9IEJDYWNoZWQzICogQUNhY2hlZDNbaV0gKyBhY2NbaV07J31cbiAgICAgICAgfWA7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGBcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByb3dQZXJUaHJlYWQ7IGkgPSBpICsgMSkge1xuICAgICAgICAgIGxldCBBQ2FjaGVkID0gbW1fQXN1Ylt0aWxlUm93ICsgaV1ba107XG4gICAgICAgICAgYWNjW2ldID0gQkNhY2hlZDAgKiBBQ2FjaGVkLnggKyBhY2NbaV07XG4gICAgICAgICAgYWNjW2ldID0gQkNhY2hlZDEgKiBBQ2FjaGVkLnkgKyBhY2NbaV07XG4gICAgICAgICAgYWNjW2ldID0gQkNhY2hlZDIgKiBBQ2FjaGVkLnogKyBhY2NbaV07XG4gICAgICAgICAgJHtpbm5lckVsZW1lbnRTaXplID09PSAzID8gJycgOiAnYWNjW2ldID0gQkNhY2hlZDMgKiBBQ2FjaGVkLncgKyBhY2NbaV07J31cbiAgICAgICAgfWA7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBtYWtlTWF0TXVsUGFja2VkVmVjNFNvdXJjZSA9IChcbiAgd29ya1BlclRocmVhZDogbnVtYmVyW10sXG4gIHdvcmtncm91cFNpemU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgdHlwZSA9ICdmMzInLFxuICBiYXRjaERpbXM/OiBJbmRpY2VzSGVscGVyLFxuICB0cmFuc3Bvc2VBID0gZmFsc2UsXG4gIHRpbGVJbm5lciA9IDMyLFxuICBzcGxpdEsgPSBmYWxzZSxcbiAgc3BsaXRlZERpbUlubmVyID0gMzIsXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCB0aWxlQU91dGVyID0gd29ya2dyb3VwU2l6ZVsxXSAqIHdvcmtQZXJUaHJlYWRbMV07XG4gIGNvbnN0IHRpbGVCT3V0ZXIgPSB3b3JrZ3JvdXBTaXplWzBdICogd29ya1BlclRocmVhZFswXTtcbiAgY29uc3QgdGlsZUFXaWR0aCA9IHRyYW5zcG9zZUEgPyB0aWxlQU91dGVyIDogdGlsZUlubmVyO1xuICBjb25zdCB0aWxlQUhpZ2h0ID0gdHJhbnNwb3NlQSA/IHRpbGVJbm5lciA6IHRpbGVBT3V0ZXI7XG4gIGNvbnN0IGlubmVyRWxlbWVudFNpemUgPSB0aWxlQVdpZHRoIC8gd29ya2dyb3VwU2l6ZVswXTtcbiAgY29uc3Qgcm93UGVyVGhyZWFkQiA9IHRpbGVJbm5lciAvIHdvcmtncm91cFNpemVbMV07XG5cbiAgaWYgKFxuICAgICEoXG4gICAgICAoKHRyYW5zcG9zZUEgJiYgaW5uZXJFbGVtZW50U2l6ZSA9PT0gNCAmJiB3b3JrUGVyVGhyZWFkWzFdID09PSA0KSB8fFxuICAgICAgICAoIXRyYW5zcG9zZUEgJiYgKGlubmVyRWxlbWVudFNpemUgPT09IDMgfHwgaW5uZXJFbGVtZW50U2l6ZSA9PT0gNCkpKSAmJlxuICAgICAgdGlsZUFXaWR0aCAlIHdvcmtncm91cFNpemVbMF0gPT09IDAgJiZcbiAgICAgIHRpbGVJbm5lciAlIHdvcmtncm91cFNpemVbMV0gPT09IDAgJiZcbiAgICAgIHdvcmtQZXJUaHJlYWRbMF0gPT09IDRcbiAgICApXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSWYgdHJhbnNwb3NlQSAke3RyYW5zcG9zZUF9IGlzIHRydWUsIGlubmVyRWxlbWVudFNpemUgJHtpbm5lckVsZW1lbnRTaXplfSBhbmQgd29ya1BlclRocmVhZFsxXSAke3dvcmtQZXJUaHJlYWRbMV19IG11c3QgYmUgNC5cbiAgICAgIE90aGVyd2lzZSwgaW5uZXJFbGVtZW50U2l6ZSAke2lubmVyRWxlbWVudFNpemV9IG11c3QgYmUgMyBvciA0LlxuICB0aWxlQVdpZHRoICR7dGlsZUFXaWR0aH0gbXVzdCBiZSBkaXZpc2libGUgYnkgd29ya2dyb3VwU2l6ZVswXSR7d29ya2dyb3VwU2l6ZVswXX0uIHRpbGVJbm5lciAke3RpbGVJbm5lcn0gbXVzdCBiZSBkaXZpc2libGUgYnkgd29ya2dyb3VwU2l6ZVsxXSAke3dvcmtncm91cFNpemVbMV19LiBjb2xQZXJUaHJlYWQgJHt3b3JrUGVyVGhyZWFkWzBdfSBtdXN0IGJlIDQuYCk7XG4gIH1cbiAgcmV0dXJuIGBcbnZhcjx3b3JrZ3JvdXA+IG1tX0FzdWI6IGFycmF5PGFycmF5PHZlYyR7aW5uZXJFbGVtZW50U2l6ZX08JHt0eXBlfT4sICR7dGlsZUFXaWR0aCAvIGlubmVyRWxlbWVudFNpemV9PiwgJHt0aWxlQUhpZ2h0fT47XG52YXI8d29ya2dyb3VwPiBtbV9Cc3ViOiBhcnJheTxhcnJheTx2ZWM0PCR7dHlwZX0+LCAke3RpbGVCT3V0ZXIgLyB3b3JrUGVyVGhyZWFkWzBdfT4sICR7dGlsZUlubmVyfT47XG5cbmNvbnN0IHJvd1BlclRocmVhZCA9ICR7d29ya1BlclRocmVhZFsxXX07XG5jb25zdCBjb2xQZXJUaHJlYWQgPSAke3dvcmtQZXJUaHJlYWRbMF19O1xuY29uc3QgaW5uZXJFbGVtZW50U2l6ZSA9ICR7aW5uZXJFbGVtZW50U2l6ZX07XG5jb25zdCB0aWxlSW5uZXIgPSAke3RpbGVJbm5lcn07XG5cbkBjb21wdXRlIEB3b3JrZ3JvdXBfc2l6ZSgke3dvcmtncm91cFNpemVbMF19LCAke3dvcmtncm91cFNpemVbMV19LCAke3dvcmtncm91cFNpemVbMl19KVxuZm4gbWFpbihAYnVpbHRpbihsb2NhbF9pbnZvY2F0aW9uX2lkKSBsb2NhbElkIDogdmVjMzx1MzI+LFxuICAgICAgICBAYnVpbHRpbihnbG9iYWxfaW52b2NhdGlvbl9pZCkgZ2xvYmFsSWQgOiB2ZWMzPHUzMj4sXG4gICAgICAgIEBidWlsdGluKHdvcmtncm91cF9pZCkgd29ya2dyb3VwSWQgOiB2ZWMzPHUzMj4pIHtcbiAgbGV0IGxvY2FsUm93ID0gaTMyKGxvY2FsSWQueSk7XG4gIGxldCB0aWxlUm93ID0gbG9jYWxSb3cgKiByb3dQZXJUaHJlYWQ7XG4gIGxldCB0aWxlQ29sID0gaTMyKGxvY2FsSWQueCk7XG5cbiAgbGV0IGdsb2JhbFJvdyA9aTMyKGdsb2JhbElkLnkpICogcm93UGVyVGhyZWFkO1xuICBsZXQgZ2xvYmFsQ29sID0gaTMyKGdsb2JhbElkLngpO1xuICBsZXQgYmF0Y2ggPSAke3NwbGl0SyA/ICcwJyA6ICdpMzIoZ2xvYmFsSWQueiknfTtcbiAgJHtiYXRjaERpbXMgPyBgbGV0IGJhdGNoSW5kaWNlcyA9ICR7YmF0Y2hEaW1zLm9mZnNldFRvSW5kaWNlcygndTMyKGJhdGNoKScpfTtgIDogJyd9XG4gIGxldCBnbG9iYWxSb3dTdGFydCA9IGkzMih3b3JrZ3JvdXBJZC55KSAqICR7dGlsZUFPdXRlcn07XG5cbiAgbGV0IG51bV90aWxlcyA9ICR7c3BsaXRLID8gYCR7TWF0aC5jZWlsKHNwbGl0ZWREaW1Jbm5lciAvIHRpbGVJbm5lcil9YCA6ICcodW5pZm9ybXMuZGltX2lubmVyIC0gMSkgLyB0aWxlSW5uZXIgKyAxJ307XG4gIHZhciBrU3RhcnQgPSAke3NwbGl0SyA/IGBpMzIoZ2xvYmFsSWQueikgKiAke3NwbGl0ZWREaW1Jbm5lcn1gIDogJzAnfTtcblxuICB2YXIgYWNjOiBhcnJheTx2ZWM0PCR7dHlwZX0+LCByb3dQZXJUaHJlYWQ+O1xuXG4gIC8vIExvb3Agb3ZlciBzaGFyZWQgZGltZW5zaW9uLlxuICBsZXQgdGlsZVJvd0IgPSBsb2NhbFJvdyAqICR7cm93UGVyVGhyZWFkQn07XG4gIGZvciAodmFyIHQgPSAwOyB0IDwgbnVtX3RpbGVzOyB0ID0gdCArIDEpIHtcbiAgICAgIC8vIExvYWQgb25lIHRpbGUgb2YgQSBpbnRvIGxvY2FsIG1lbW9yeS5cbiAgICAgIGZvciAodmFyIGlubmVyUm93ID0gMDsgaW5uZXJSb3cgPCByb3dQZXJUaHJlYWQ7IGlubmVyUm93ID0gaW5uZXJSb3cgKyAxKSB7XG4gICAgICAgICAgbGV0IGlucHV0Um93ID0gdGlsZVJvdyArIGlubmVyUm93O1xuICAgICAgICAgIGxldCBpbnB1dENvbCA9IHRpbGVDb2w7XG4gICAgICAgICAgJHt3cml0ZURhdGFUb1N1YkFWZWM0U25pcHBldCh0cmFuc3Bvc2VBLCBiYXRjaERpbXMpfVxuICAgICAgfVxuXG4gICAgICAvLyBMb2FkIG9uZSB0aWxlIG9mIEIgaW50byBsb2NhbCBtZW1vcnkuXG4gICAgICBmb3IgKHZhciBpbm5lclJvdyA9IDA7IGlubmVyUm93IDwgJHtyb3dQZXJUaHJlYWRCfTsgaW5uZXJSb3cgPSBpbm5lclJvdyArIDEpIHtcbiAgICAgICAgICBsZXQgaW5wdXRSb3cgPSB0aWxlUm93QiArIGlubmVyUm93O1xuICAgICAgICAgIGxldCBpbnB1dENvbCA9IHRpbGVDb2w7XG4gICAgICAgICAgbW1fQnN1YltpbnB1dFJvd11baW5wdXRDb2xdID0gbW1fcmVhZEIoYmF0Y2gsIGtTdGFydCArIGlucHV0Um93LCBnbG9iYWxDb2wke1xuICAgICAgICAgICAgYmF0Y2hEaW1zID8gJywgYmF0Y2hJbmRpY2VzJyA6ICcnXG4gICAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBrU3RhcnQgPSBrU3RhcnQgKyB0aWxlSW5uZXI7XG4gICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICAgIC8vIENvbXB1dGUgYWNjIHZhbHVlcyBmb3IgYSBzaW5nbGUgdGhyZWFkLlxuICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCB0aWxlSW5uZXIgLyBpbm5lckVsZW1lbnRTaXplOyBrID0gayArIDEpIHtcbiAgICAgICAgICBsZXQgQkNhY2hlZDAgPSBtbV9Cc3ViW2sgKiBpbm5lckVsZW1lbnRTaXplXVt0aWxlQ29sXTtcbiAgICAgICAgICBsZXQgQkNhY2hlZDEgPSBtbV9Cc3ViW2sgKiBpbm5lckVsZW1lbnRTaXplICsgMV1bdGlsZUNvbF07XG4gICAgICAgICAgbGV0IEJDYWNoZWQyID0gbW1fQnN1YltrICogaW5uZXJFbGVtZW50U2l6ZSArIDJdW3RpbGVDb2xdO1xuICAgICAgICAgICR7aW5uZXJFbGVtZW50U2l6ZSA9PT0gMyA/ICcnIDogJ2xldCBCQ2FjaGVkMyA9IG1tX0JzdWJbayAqIGlubmVyRWxlbWVudFNpemUgKyAzXVt0aWxlQ29sXTsnfVxuXG4gICAgICAgICAgJHtjYWxjdWxhdGVSZXN1bHRTbmlwcGV0KHRyYW5zcG9zZUEsIGlubmVyRWxlbWVudFNpemUpfVxuICAgICAgfVxuXG4gICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gIH1cblxuICBmb3IgKHZhciBpbm5lclJvdyA9IDA7IGlubmVyUm93IDwgcm93UGVyVGhyZWFkOyBpbm5lclJvdyA9IGlubmVyUm93ICsgMSkge1xuICAgICAgbW1fd3JpdGUoYmF0Y2gsIGdsb2JhbFJvdyArIGlubmVyUm93LCBnbG9iYWxDb2wsIGFjY1tpbm5lclJvd10pO1xuICB9XG59YDtcbn07XG5cbmNvbnN0IHdyaXRlRGF0YVRvU3ViQVNuaXBwZXQgPSAodHJhbnNwb3NlOiBib29sZWFuLCBiYXRjaERpbXM/OiBJbmRpY2VzSGVscGVyKSA9PiB7XG4gIGlmICh0cmFuc3Bvc2UpIHtcbiAgICByZXR1cm4gYFxuICAgICAgICAgICAgbW1fQXN1YltpbnB1dFJvd11baW5wdXRDb2xdID0gbW1fcmVhZEEoYmF0Y2gsXG4gICAgICAgICAgICAgIGtTdGFydCArIGlucHV0Um93LFxuICAgICAgICAgICAgICBnbG9iYWxSb3dTdGFydCArIGlucHV0Q29sJHtiYXRjaERpbXMgPyAnLCBiYXRjaEluZGljZXMnIDogJyd9KTtcbiAgICAgICAgICAgIGA7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGBcbiAgICAgICAgICAgIG1tX0FzdWJbaW5wdXRSb3ddW2lucHV0Q29sXSA9IG1tX3JlYWRBKGJhdGNoLFxuICAgICAgICAgICAgICBnbG9iYWxSb3dTdGFydCArIGlucHV0Um93LFxuICAgICAgICAgICAgICBrU3RhcnQgKyBpbnB1dENvbCR7YmF0Y2hEaW1zID8gJywgYmF0Y2hJbmRpY2VzJyA6ICcnfSk7XG4gICAgICAgICAgICBgO1xuICB9XG59O1xuXG5jb25zdCByZWFkRGF0YUZyb21TdWJBU25pcHBldCA9ICh0cmFuc3Bvc2VBOiBib29sZWFuKSA9PlxuICB0cmFuc3Bvc2VBID8gJ2xldCBBQ2FjaGVkID0gbW1fQXN1YltrXVt0aWxlUm93ICsgaW5uZXJSb3ddOycgOiAnbGV0IEFDYWNoZWQgPSBtbV9Bc3ViW3RpbGVSb3cgKyBpbm5lclJvd11ba107JztcblxuLy8gc2VxdWVudGlhbEFjY2Vzc0J5VGhyZWFkcyBtZWFucyBzZXF1ZW50aWFsIGRhdGEgaW4gbWVtb3J5IGlzIGFjY2Vzc2VkIGJ5XG4vLyB0aHJlYWRzLCBpbnN0ZWFkIG9mIGEgc2luZ2xlIHRocmVhZCAoZGVmYXVsdCBiZWhhdmlvcikuXG5leHBvcnQgY29uc3QgbWFrZU1hdE11bFBhY2tlZFNvdXJjZSA9IChcbiAgd29ya1BlclRocmVhZDogbnVtYmVyW10sXG4gIHdvcmtncm91cFNpemU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgdHlwZSA9ICdmMzInLFxuICBiYXRjaERpbXM/OiBJbmRpY2VzSGVscGVyLFxuICB0cmFuc3Bvc2VBID0gZmFsc2UsXG4gIHRpbGVJbm5lciA9IDMyLFxuICBzcGxpdEsgPSBmYWxzZSxcbiAgc3BsaXRlZERpbUlubmVyID0gMzIsXG4gIHNlcXVlbnRpYWxBY2Nlc3NCeVRocmVhZHMgPSBmYWxzZSxcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHRpbGVBT3V0ZXIgPSB3b3JrUGVyVGhyZWFkWzFdICogd29ya2dyb3VwU2l6ZVsxXTtcbiAgY29uc3QgdGlsZUJPdXRlciA9IHdvcmtQZXJUaHJlYWRbMF0gKiB3b3JrZ3JvdXBTaXplWzBdO1xuICBjb25zdCB0aWxlQVdpZHRoID0gdHJhbnNwb3NlQSA/IHRpbGVBT3V0ZXIgOiB0aWxlSW5uZXI7XG4gIGNvbnN0IHRpbGVBSGlnaHQgPSB0cmFuc3Bvc2VBID8gdGlsZUlubmVyIDogdGlsZUFPdXRlcjtcblxuICBpZiAoXG4gICAgISh0aWxlQUhpZ2h0ICUgd29ya2dyb3VwU2l6ZVsxXSA9PT0gMCAmJiB0aWxlQVdpZHRoICUgd29ya2dyb3VwU2l6ZVswXSA9PT0gMCAmJiB0aWxlSW5uZXIgJSB3b3JrZ3JvdXBTaXplWzFdID09PSAwKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgdGlsZUFIaWdodCAke3RpbGVBSGlnaHR9IG11c3QgYmUgZGl2aXNpYmxlIGJ5IHdvcmtncm91cFNpemVbMV0ke3dvcmtncm91cFNpemVbMV19LCB0aWxlQVdpZHRoICR7dGlsZUFXaWR0aH0gbXVzdCBiZSBkaXZpc2libGUgYnkgd29ya2dyb3VwU2l6ZVswXSR7d29ya2dyb3VwU2l6ZVswXX0sIHRpbGVJbm5lciAke3RpbGVJbm5lcn0gbXVzdCBiZSBkaXZpc2libGUgYnkgd29ya2dyb3VwU2l6ZVsxXSR7d29ya2dyb3VwU2l6ZVsxXX1gLFxuICAgICk7XG4gIH1cbiAgY29uc3Qgcm93UGVyVGhyZWFkQSA9IHRpbGVBSGlnaHQgLyB3b3JrZ3JvdXBTaXplWzFdO1xuICBjb25zdCBjb2xQZXJUaHJlYWRBID0gdGlsZUFXaWR0aCAvIHdvcmtncm91cFNpemVbMF07XG4gIGNvbnN0IHJvd1BlclRocmVhZEIgPSB0aWxlSW5uZXIgLyB3b3JrZ3JvdXBTaXplWzFdO1xuICBjb25zdCBtYXRtdWxTbmlwcGV0ID0gc2VxdWVudGlhbEFjY2Vzc0J5VGhyZWFkc1xuICAgID8gYFxuICAgIGxldCBsb2NhbFJvdyA9IGkzMihsb2NhbElkLnkpO1xuICAgIGxldCBsb2NhbENvbCA9IGkzMihsb2NhbElkLngpO1xuICAgIGxldCBnbG9iYWxSb3dTdGFydCA9IGkzMih3b3JrZ3JvdXBJZC55KSAqICR7dGlsZUFPdXRlcn07XG4gICAgbGV0IGdsb2JhbENvbFN0YXJ0ID0gaTMyKHdvcmtncm91cElkLngpICogJHt0aWxlQk91dGVyfTtcblxuICAgIC8vIExvb3Agb3ZlciBzaGFyZWQgZGltZW5zaW9uLlxuICAgIGZvciAodmFyIHQgPSAwOyB0IDwgbnVtX3RpbGVzOyB0ID0gdCArIDEpIHtcbiAgICAgIC8vIExvYWQgb25lIHRpbGUgb2YgQSBpbnRvIGxvY2FsIG1lbW9yeS5cbiAgICAgIGZvciAodmFyIGlucHV0Um93ID0gbG9jYWxSb3c7IGlucHV0Um93IDwgJHt0aWxlQUhpZ2h0fTsgaW5wdXRSb3cgPSBpbnB1dFJvdyArICR7d29ya2dyb3VwU2l6ZVsxXX0pIHtcbiAgICAgICAgZm9yICh2YXIgaW5wdXRDb2wgPSBsb2NhbENvbDsgaW5wdXRDb2wgPCAke3RpbGVBV2lkdGh9OyBpbnB1dENvbCA9IGlucHV0Q29sICsgJHt3b3JrZ3JvdXBTaXplWzBdfSkge1xuICAgICAgICAgICR7d3JpdGVEYXRhVG9TdWJBU25pcHBldCh0cmFuc3Bvc2VBLCBiYXRjaERpbXMpfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBMb2FkIG9uZSB0aWxlIG9mIEIgaW50byBsb2NhbCBtZW1vcnkuXG4gICAgICBmb3IgKHZhciBpbnB1dFJvdyA9IGxvY2FsUm93OyBpbnB1dFJvdyA8ICR7dGlsZUlubmVyfTsgaW5wdXRSb3cgPSBpbnB1dFJvdyArICR7d29ya2dyb3VwU2l6ZVsxXX0pIHtcbiAgICAgICAgICAgIGZvciAodmFyIGlucHV0Q29sID0gbG9jYWxDb2w7IGlucHV0Q29sIDwgJHt0aWxlQk91dGVyfTsgaW5wdXRDb2wgPSBpbnB1dENvbCArICR7d29ya2dyb3VwU2l6ZVswXX0pIHtcbiAgICAgICAgICBtbV9Cc3ViW2lucHV0Um93XVtpbnB1dENvbF0gPSBtbV9yZWFkQihiYXRjaCxcbiAgICAgICAgICAgIGtTdGFydCArIGlucHV0Um93LFxuICAgICAgICAgICAgZ2xvYmFsQ29sU3RhcnQgKyBpbnB1dENvbCR7YmF0Y2hEaW1zID8gJywgYmF0Y2hJbmRpY2VzJyA6ICcnfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGtTdGFydCA9IGtTdGFydCArIHRpbGVJbm5lcjtcbiAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcblxuICAgICAgLy8gQ29tcHV0ZSBhY2MgdmFsdWVzIGZvciBhIHNpbmdsZSB0aHJlYWQuXG4gICAgICB2YXIgQkNhY2hlZCA6IGFycmF5PCR7dHlwZX0sIGNvbFBlclRocmVhZD47XG4gICAgICBmb3IgKHZhciBrID0gMDsgayA8IHRpbGVJbm5lcjsgayA9IGsgKyAxKSB7XG4gICAgICAgIGZvciAodmFyIGlubmVyID0gMDsgaW5uZXIgPCBjb2xQZXJUaHJlYWQ7IGlubmVyID0gaW5uZXIgKyAxKSB7XG4gICAgICAgICAgQkNhY2hlZFtpbm5lcl0gPSBtbV9Cc3ViW2tdW2xvY2FsQ29sICsgaW5uZXIgKiAke3dvcmtncm91cFNpemVbMF19XTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBpbm5lclJvdyA9IDA7IGlubmVyUm93IDwgcm93UGVyVGhyZWFkOyBpbm5lclJvdyA9IGlubmVyUm93ICsgMSkge1xuICAgICAgICAgIGxldCBBQ2FjaGVkID0gJHtcbiAgICAgICAgICAgIHRyYW5zcG9zZUFcbiAgICAgICAgICAgICAgPyBgbW1fQXN1YltrXVtsb2NhbFJvdyArIGlubmVyUm93ICogJHt3b3JrZ3JvdXBTaXplWzFdfV07YFxuICAgICAgICAgICAgICA6IGBtbV9Bc3ViW2xvY2FsUm93ICsgaW5uZXJSb3cgKiAke3dvcmtncm91cFNpemVbMV19XVtrXTtgXG4gICAgICAgICAgfVxuICAgICAgICAgIGZvciAodmFyIGlubmVyQ29sID0gMDsgaW5uZXJDb2wgPCBjb2xQZXJUaHJlYWQ7IGlubmVyQ29sID0gaW5uZXJDb2wgKyAxKSB7XG4gICAgICAgICAgICBhY2NbaW5uZXJSb3ddW2lubmVyQ29sXSA9IGFjY1tpbm5lclJvd11baW5uZXJDb2xdICtcbiAgICAgICAgICAgICAgICBBQ2FjaGVkICogQkNhY2hlZFtpbm5lckNvbF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gICAgfVxuICAgIGZvciAodmFyIGlubmVyUm93ID0gMDsgaW5uZXJSb3cgPCByb3dQZXJUaHJlYWQ7IGlubmVyUm93ID0gaW5uZXJSb3cgKyAxKSB7XG4gICAgICBsZXQgZ1JvdyA9IGdsb2JhbFJvd1N0YXJ0ICsgbG9jYWxSb3cgKyBpbm5lclJvdyAqICR7d29ya2dyb3VwU2l6ZVsxXX07XG4gICAgICBmb3IgKHZhciBpbm5lckNvbCA9IDA7IGlubmVyQ29sIDwgY29sUGVyVGhyZWFkOyBpbm5lckNvbCA9IGlubmVyQ29sICsgMSkge1xuICAgICAgICBsZXQgZ0NvbCA9IGdsb2JhbENvbFN0YXJ0ICsgbG9jYWxDb2wgKyBpbm5lckNvbCAqICR7d29ya2dyb3VwU2l6ZVswXX07XG4gICAgICAgIG1tX3dyaXRlKGJhdGNoLCBnUm93LCBnQ29sLCBhY2NbaW5uZXJSb3ddW2lubmVyQ29sXSk7XG4gICAgICB9XG4gICAgfVxuICAgIGBcbiAgICA6IGBcbmxldCB0aWxlUm93ID0gaTMyKGxvY2FsSWQueSkgKiByb3dQZXJUaHJlYWQ7XG5sZXQgdGlsZUNvbCA9IGkzMihsb2NhbElkLngpICogY29sUGVyVGhyZWFkO1xuXG5sZXQgZ2xvYmFsUm93ID0gaTMyKGdsb2JhbElkLnkpICogcm93UGVyVGhyZWFkO1xubGV0IGdsb2JhbENvbCA9IGkzMihnbG9iYWxJZC54KSAqIGNvbFBlclRocmVhZDtcbmxldCBnbG9iYWxSb3dTdGFydCA9IGkzMih3b3JrZ3JvdXBJZC55KSAqICR7dGlsZUFPdXRlcn07XG5cbmxldCB0aWxlUm93QSA9IGkzMihsb2NhbElkLnkpICogJHtyb3dQZXJUaHJlYWRBfTtcbmxldCB0aWxlQ29sQSA9IGkzMihsb2NhbElkLngpICogJHtjb2xQZXJUaHJlYWRBfTtcbmxldCB0aWxlUm93QiA9IGkzMihsb2NhbElkLnkpICogJHtyb3dQZXJUaHJlYWRCfTtcbi8vIExvb3Agb3ZlciBzaGFyZWQgZGltZW5zaW9uLlxuZm9yICh2YXIgdCA9IDA7IHQgPCBudW1fdGlsZXM7IHQgPSB0ICsgMSkge1xuICAvLyBMb2FkIG9uZSB0aWxlIG9mIEEgaW50byBsb2NhbCBtZW1vcnkuXG4gIGZvciAodmFyIGlubmVyUm93ID0gMDsgaW5uZXJSb3cgPCAke3Jvd1BlclRocmVhZEF9OyBpbm5lclJvdyA9IGlubmVyUm93ICsgMSkge1xuICAgIGZvciAodmFyIGlubmVyQ29sID0gMDsgaW5uZXJDb2wgPCAke2NvbFBlclRocmVhZEF9OyBpbm5lckNvbCA9IGlubmVyQ29sICsgMSkge1xuICAgICAgbGV0IGlucHV0Um93ID0gdGlsZVJvd0EgKyBpbm5lclJvdztcbiAgICAgIGxldCBpbnB1dENvbCA9IHRpbGVDb2xBICsgaW5uZXJDb2w7XG4gICAgICAke3dyaXRlRGF0YVRvU3ViQVNuaXBwZXQodHJhbnNwb3NlQSwgYmF0Y2hEaW1zKX1cbiAgICB9XG4gIH1cblxuICAvLyBMb2FkIG9uZSB0aWxlIG9mIEIgaW50byBsb2NhbCBtZW1vcnkuXG4gIGZvciAodmFyIGlubmVyUm93ID0gMDsgaW5uZXJSb3cgPCAke3Jvd1BlclRocmVhZEJ9OyBpbm5lclJvdyA9IGlubmVyUm93ICsgMSkge1xuICAgIGZvciAodmFyIGlubmVyQ29sID0gMDsgaW5uZXJDb2wgPCBjb2xQZXJUaHJlYWQ7IGlubmVyQ29sID0gaW5uZXJDb2wgKyAxKSB7XG4gICAgICBsZXQgaW5wdXRSb3cgPSB0aWxlUm93QiArIGlubmVyUm93O1xuICAgICAgbGV0IGlucHV0Q29sID0gdGlsZUNvbCArIGlubmVyQ29sO1xuICAgICAgbW1fQnN1YltpbnB1dFJvd11baW5wdXRDb2xdID0gbW1fcmVhZEIoYmF0Y2gsXG4gICAgICAgIGtTdGFydCArIGlucHV0Um93LFxuICAgICAgICBnbG9iYWxDb2wgKyBpbm5lckNvbCR7YmF0Y2hEaW1zID8gJywgYmF0Y2hJbmRpY2VzJyA6ICcnfSk7XG4gICAgfVxuICB9XG4gIGtTdGFydCA9IGtTdGFydCArIHRpbGVJbm5lcjtcbiAgd29ya2dyb3VwQmFycmllcigpO1xuXG4gIC8vIENvbXB1dGUgYWNjIHZhbHVlcyBmb3IgYSBzaW5nbGUgdGhyZWFkLlxuICB2YXIgQkNhY2hlZCA6IGFycmF5PCR7dHlwZX0sIGNvbFBlclRocmVhZD47XG4gIGZvciAodmFyIGsgPSAwOyBrIDwgdGlsZUlubmVyOyBrID0gayArIDEpIHtcbiAgICBmb3IgKHZhciBpbm5lciA9IDA7IGlubmVyIDwgY29sUGVyVGhyZWFkOyBpbm5lciA9IGlubmVyICsgMSkge1xuICAgICAgQkNhY2hlZFtpbm5lcl0gPSBtbV9Cc3ViW2tdW3RpbGVDb2wgKyBpbm5lcl07XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaW5uZXJSb3cgPSAwOyBpbm5lclJvdyA8IHJvd1BlclRocmVhZDsgaW5uZXJSb3cgPSBpbm5lclJvdyArIDEpIHtcbiAgICAgICR7cmVhZERhdGFGcm9tU3ViQVNuaXBwZXQodHJhbnNwb3NlQSl9XG4gICAgICBmb3IgKHZhciBpbm5lckNvbCA9IDA7IGlubmVyQ29sIDwgY29sUGVyVGhyZWFkOyBpbm5lckNvbCA9IGlubmVyQ29sICsgMSkge1xuICAgICAgICBhY2NbaW5uZXJSb3ddW2lubmVyQ29sXSA9IGFjY1tpbm5lclJvd11baW5uZXJDb2xdICsgQUNhY2hlZCAqIEJDYWNoZWRbaW5uZXJDb2xdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHdvcmtncm91cEJhcnJpZXIoKTtcbn1cblxuZm9yICh2YXIgaW5uZXJSb3cgPSAwOyBpbm5lclJvdyA8IHJvd1BlclRocmVhZDsgaW5uZXJSb3cgPSBpbm5lclJvdyArIDEpIHtcbiAgZm9yICh2YXIgaW5uZXJDb2wgPSAwOyBpbm5lckNvbCA8IGNvbFBlclRocmVhZDsgaW5uZXJDb2wgPSBpbm5lckNvbCArIDEpIHtcbiAgICBtbV93cml0ZShiYXRjaCwgZ2xvYmFsUm93ICsgaW5uZXJSb3csIGdsb2JhbENvbCArIGlubmVyQ29sLFxuICAgICAgICBhY2NbaW5uZXJSb3ddW2lubmVyQ29sXSk7XG4gIH1cbn1cbmA7XG5cbiAgcmV0dXJuIGBcbiAgdmFyPHdvcmtncm91cD4gbW1fQXN1YiA6IGFycmF5PGFycmF5PCR7dHlwZX0sICR7dGlsZUFXaWR0aH0+LCAke3RpbGVBSGlnaHR9PjtcbiAgdmFyPHdvcmtncm91cD4gbW1fQnN1YiA6IGFycmF5PGFycmF5PCR7dHlwZX0sICR7dGlsZUJPdXRlcn0+LCAke3RpbGVJbm5lcn0+O1xuICBjb25zdCByb3dQZXJUaHJlYWQgPSAke3dvcmtQZXJUaHJlYWRbMV19O1xuICBjb25zdCBjb2xQZXJUaHJlYWQgPSAke3dvcmtQZXJUaHJlYWRbMF19O1xuICBjb25zdCB0aWxlSW5uZXIgPSAke3RpbGVJbm5lcn07XG5cbkBjb21wdXRlIEB3b3JrZ3JvdXBfc2l6ZSgke3dvcmtncm91cFNpemVbMF19LCAke3dvcmtncm91cFNpemVbMV19LCAke3dvcmtncm91cFNpemVbMl19KVxuZm4gbWFpbihAYnVpbHRpbihsb2NhbF9pbnZvY2F0aW9uX2lkKSBsb2NhbElkIDogdmVjMzx1MzI+LFxuICAgICAgICBAYnVpbHRpbihnbG9iYWxfaW52b2NhdGlvbl9pZCkgZ2xvYmFsSWQgOiB2ZWMzPHUzMj4sXG4gICAgICAgIEBidWlsdGluKHdvcmtncm91cF9pZCkgd29ya2dyb3VwSWQgOiB2ZWMzPHUzMj4pIHtcbiAgICBsZXQgYmF0Y2ggPSAke3NwbGl0SyA/ICcwJyA6ICdpMzIoZ2xvYmFsSWQueiknfTtcbiAgICAke2JhdGNoRGltcyA/IGBsZXQgYmF0Y2hJbmRpY2VzID0gJHtiYXRjaERpbXMub2Zmc2V0VG9JbmRpY2VzKCd1MzIoYmF0Y2gpJyl9O2AgOiAnJ31cbiAgICBsZXQgbnVtX3RpbGVzID0gJHtcbiAgICAgIHNwbGl0SyA/IGAke01hdGguY2VpbChzcGxpdGVkRGltSW5uZXIgLyB0aWxlSW5uZXIpfWAgOiAnKHVuaWZvcm1zLmRpbV9pbm5lciAtIDEpIC8gdGlsZUlubmVyICsgMSdcbiAgICB9O1xuICAgIHZhciBrU3RhcnQgPSAke3NwbGl0SyA/IGBpMzIoZ2xvYmFsSWQueikgKiAke3NwbGl0ZWREaW1Jbm5lcn1gIDogJzAnfTtcblxuICAgIHZhciBhY2MgOiBhcnJheTxhcnJheTwke3R5cGV9LCBjb2xQZXJUaHJlYWQ+LCByb3dQZXJUaHJlYWQ+O1xuICAgICR7bWF0bXVsU25pcHBldH1cbiAgfVxuYDtcbn07XG5cbmNvbnN0IG1hdE11bFJlYWRXcml0ZUZuU291cmNlID0gKFxuICBjb21wb25lbnQ6IG51bWJlcixcbiAgaGFzQmlhczogYm9vbGVhbixcbiAgYXBwbHlBY3RpdmF0aW9uOiBzdHJpbmcsXG4gIHZhcmlhYmxlczogSW5kaWNlc0hlbHBlcltdLFxuICBpc0NoYW5uZWxzTGFzdCA9IGZhbHNlLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgW2JhdGNoVmFyaWFibGUsIGFWYXJpYWJsZSwgYlZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZV0gPSB2YXJpYWJsZXM7XG4gIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlKHZhcmlhYmxlc1swXS50eXBlLnRlbnNvcik7XG5cbiAgY29uc3Qgc291cmNlID0gYFxuICAgIGZuIG1tX3JlYWRBKGJhdGNoOiBpMzIsIHJvdzogaTMyLCBjb2xJbjogaTMyLCBiYXRjaEluZGljZXM6ICR7YmF0Y2hWYXJpYWJsZS50eXBlLmluZGljZXN9KSAtPiAke3R5cGVTbmlwcGV0KFxuICAgICAgY29tcG9uZW50LFxuICAgICAgZGF0YVR5cGUsXG4gICAgKX0ge1xuICAgICAgdmFyIHZhbHVlID0gJHt0eXBlU25pcHBldChjb21wb25lbnQsIGRhdGFUeXBlKX0oMC4wKTtcbiAgICAgIGxldCBjb2wgPSBjb2xJbiAqICR7Y29tcG9uZW50fTtcbiAgICAgIGlmKHJvdyA8IHVuaWZvcm1zLmRpbV9hX291dGVyICYmIGNvbCA8IHVuaWZvcm1zLmRpbV9pbm5lcilcbiAgICAgIHtcbiAgICAgICAgdmFyIGFJbmRpY2VzOiAke2FWYXJpYWJsZS50eXBlLmluZGljZXN9O1xuICAgICAgICAke2NvbnZlcnRPdXRwdXRCYXRjaEluZGljZXNUb0lucHV0QmF0Y2hJbmRpY2VzKFxuICAgICAgICAgICdhSW5kaWNlcycsXG4gICAgICAgICAgYVZhcmlhYmxlLFxuICAgICAgICAgIGFWYXJpYWJsZS5yYW5rIC0gMixcbiAgICAgICAgICBiYXRjaFZhcmlhYmxlLnJhbmssXG4gICAgICAgICAgJ2JhdGNoSW5kaWNlcycsXG4gICAgICAgICl9XG4gICAgICAgICR7YVZhcmlhYmxlLmluZGljZXNTZXQoJ2FJbmRpY2VzJywgYVZhcmlhYmxlLnJhbmsgLSAyLCAndTMyKHJvdyknKX1cbiAgICAgICAgJHthVmFyaWFibGUuaW5kaWNlc1NldCgnYUluZGljZXMnLCBhVmFyaWFibGUucmFuayAtIDEsICd1MzIoY29sSW4pJyl9XG4gICAgICAgIHZhbHVlID0gJHthVmFyaWFibGUuZ2V0QnlJbmRpY2VzKCdhSW5kaWNlcycpfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBmbiBtbV9yZWFkQihiYXRjaDogaTMyLCByb3c6IGkzMiwgY29sSW46IGkzMiwgYmF0Y2hJbmRpY2VzOiAke2JhdGNoVmFyaWFibGUudHlwZS5pbmRpY2VzfSkgLT4gJHt0eXBlU25pcHBldChcbiAgICAgIGNvbXBvbmVudCxcbiAgICAgIGRhdGFUeXBlLFxuICAgICl9IHtcbiAgICAgIHZhciB2YWx1ZSA9ICR7dHlwZVNuaXBwZXQoY29tcG9uZW50LCBkYXRhVHlwZSl9KDAuMCk7XG4gICAgICBsZXQgY29sID0gY29sSW4gKiAke2NvbXBvbmVudH07XG4gICAgICBpZihyb3cgPCB1bmlmb3Jtcy5kaW1faW5uZXIgJiYgY29sIDwgdW5pZm9ybXMuZGltX2Jfb3V0ZXIpXG4gICAgICB7XG4gICAgICAgIHZhciBiSW5kaWNlczogJHtiVmFyaWFibGUudHlwZS5pbmRpY2VzfTtcbiAgICAgICAgJHtjb252ZXJ0T3V0cHV0QmF0Y2hJbmRpY2VzVG9JbnB1dEJhdGNoSW5kaWNlcyhcbiAgICAgICAgICAnYkluZGljZXMnLFxuICAgICAgICAgIGJWYXJpYWJsZSxcbiAgICAgICAgICBiVmFyaWFibGUucmFuayAtIDIsXG4gICAgICAgICAgYmF0Y2hWYXJpYWJsZS5yYW5rLFxuICAgICAgICAgICdiYXRjaEluZGljZXMnLFxuICAgICAgICApfVxuICAgICAgICAke2JWYXJpYWJsZS5pbmRpY2VzU2V0KCdiSW5kaWNlcycsIGJWYXJpYWJsZS5yYW5rIC0gMiwgJ3UzMihyb3cpJyl9XG4gICAgICAgICR7YlZhcmlhYmxlLmluZGljZXNTZXQoJ2JJbmRpY2VzJywgYlZhcmlhYmxlLnJhbmsgLSAxLCAndTMyKGNvbEluKScpfVxuICAgICAgICB2YWx1ZSA9ICR7YlZhcmlhYmxlLmdldEJ5SW5kaWNlcygnYkluZGljZXMnKX07XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgZm4gbW1fd3JpdGUoYmF0Y2g6IGkzMiwgcm93OiBpMzIsIGNvbEluOiBpMzIsIHZhbHVlSW46ICR7dHlwZVNuaXBwZXQoY29tcG9uZW50LCBkYXRhVHlwZSl9KSB7XG4gICAgICBsZXQgY29sID0gY29sSW4gKiAke2NvbXBvbmVudH07XG4gICAgICBpZiAocm93IDwgdW5pZm9ybXMuZGltX2Ffb3V0ZXIgJiYgY29sIDwgdW5pZm9ybXMuZGltX2Jfb3V0ZXIpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gdmFsdWVJbjtcbiAgICAgICAgbGV0IGNvb3JkcyA9IHZlYzM8aTMyPihiYXRjaCwgcm93LCBjb2xJbik7XG4gICAgICAgICR7XG4gICAgICAgICAgaGFzQmlhc1xuICAgICAgICAgICAgPyBgdmFsdWUgPSB2YWx1ZSArICR7aXNDaGFubmVsc0xhc3QgPyAnYmlhc1tjb2xJbl0nIDogYCR7dHlwZVNuaXBwZXQoY29tcG9uZW50LCBkYXRhVHlwZSl9KGJpYXNbcm93XSlgfTtgXG4gICAgICAgICAgICA6ICcnXG4gICAgICAgIH1cbiAgICAgICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgICAgICR7b3V0cHV0VmFyaWFibGUuc2V0QnlJbmRpY2VzKCd2ZWMzPHUzMj4oY29vcmRzKScsICd2YWx1ZScpfVxuICAgICAgfVxuICAgIH1cbiAgICBgO1xuICByZXR1cm4gc291cmNlO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgcmVzaGFwZWRPdXRwdXRTaGFwZT86IHJlYWRvbmx5IG51bWJlcltdLFxuICBpc0NoYW5uZWxzTGFzdCA9IGZhbHNlIC8qIG9ubHkgdXNlZCBmb3IgY29udjJkQnlNYXRNdWwqLyxcbiAgc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24/OiAoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKSA9PiBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgYVNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGJTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRlckRpbXNBID0gYVNoYXBlLnNsaWNlKDAsIC0yKTtcbiAgY29uc3Qgb3V0ZXJEaW1zQiA9IGJTaGFwZS5zbGljZSgwLCAtMik7XG4gIGNvbnN0IG91dGVyRGltcyA9IHJlc2hhcGVkT3V0cHV0U2hhcGUgPyByZXNoYXBlZE91dHB1dFNoYXBlLnNsaWNlKDAsIC0yKSA6IG91dHB1dFNoYXBlLnNsaWNlKDAsIC0yKTtcbiAgY29uc3QgYmF0Y2hTaXplID0gU2hhcGVVdGlsLnNpemUob3V0ZXJEaW1zKTtcbiAgY29uc3QgZGltQU91dGVyID0gYVNoYXBlW2FTaGFwZS5sZW5ndGggLSAyXTtcbiAgY29uc3QgZGltSW5uZXIgPSBhU2hhcGVbYVNoYXBlLmxlbmd0aCAtIDFdO1xuICBjb25zdCBkaW1CT3V0ZXIgPSBiU2hhcGVbYlNoYXBlLmxlbmd0aCAtIDFdO1xuICBjb25zdCBpc1ZlYzQgPSBkaW1Jbm5lciAlIDQgPT09IDAgJiYgZGltQk91dGVyICUgNCA9PT0gMDtcblxuICAvLyBUT0RPOiBmaW5lIHR1bmUgc2l6ZVxuICBjb25zdCBlbGVtZW50c1BlclRocmVhZCA9IGRpbUFPdXRlciA8PSA4ID8gWzQsIDEsIDFdIDogWzQsIDQsIDFdO1xuICBjb25zdCB3b3JrZ3JvdXBTaXplOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbOCwgOCwgMV07XG4gIGNvbnN0IGRpc3BhdGNoID0gW1xuICAgIE1hdGguY2VpbChkaW1CT3V0ZXIgLyB3b3JrZ3JvdXBTaXplWzBdIC8gZWxlbWVudHNQZXJUaHJlYWRbMF0pLFxuICAgIE1hdGguY2VpbChkaW1BT3V0ZXIgLyB3b3JrZ3JvdXBTaXplWzFdIC8gZWxlbWVudHNQZXJUaHJlYWRbMV0pLFxuICAgIE1hdGguY2VpbChiYXRjaFNpemUgLyB3b3JrZ3JvdXBTaXplWzJdIC8gZWxlbWVudHNQZXJUaHJlYWRbMl0pLFxuICBdO1xuXG4gIGNvbnN0IGNvbXBvbmVudHMgPSBpc1ZlYzQgPyA0IDogMTtcbiAgY29uc3QgYVNoYXBlVGVtcCA9IFsuLi5vdXRlckRpbXNBLCBkaW1BT3V0ZXIsIGRpbUlubmVyIC8gY29tcG9uZW50c107XG4gIGNvbnN0IGFSYW5rID0gYVNoYXBlVGVtcC5sZW5ndGg7XG4gIGNvbnN0IGJTaGFwZVRlbXAgPSBbLi4ub3V0ZXJEaW1zQiwgZGltSW5uZXIsIGRpbUJPdXRlciAvIGNvbXBvbmVudHNdO1xuICBjb25zdCBiUmFuayA9IGJTaGFwZVRlbXAubGVuZ3RoO1xuICBjb25zdCBvdXRwdXRTaGFwZVRlbXAgPSBbYmF0Y2hTaXplLCBkaW1BT3V0ZXIsIGRpbUJPdXRlciAvIGNvbXBvbmVudHNdO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS5pbnQzMiwgZGF0YTogZGltQU91dGVyIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS5pbnQzMiwgZGF0YTogZGltQk91dGVyIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS5pbnQzMiwgZGF0YTogZGltSW5uZXIgfSxcbiAgXTtcbiAgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zRGF0YShhY3RpdmF0aW9uQXR0cmlidXRlcywgcHJvZ3JhbVVuaWZvcm1zKTtcbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMob3V0ZXJEaW1zLCBhU2hhcGVUZW1wLCBiU2hhcGVUZW1wKSk7XG4gIGNvbnN0IGlucHV0RGVwZW5kZW5jaWVzOiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdID0gWydyYW5rJywgJ3JhbmsnXTtcblxuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gIGlmIChoYXNCaWFzKSB7XG4gICAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRzWzJdLmRpbXMpKTtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCdyYW5rJyk7XG4gIH1cbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMob3V0cHV0U2hhcGVUZW1wKSk7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgYmF0Y2hSYW5rID0gb3V0ZXJEaW1zLmxlbmd0aDtcbiAgICBjb25zdCBiYXRjaERpbXMgPSBpbnRlcm5hbFZhcmlhYmxlKCdiYXRjaERpbXMnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGJhdGNoUmFuaywgMSk7XG4gICAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUoaW5wdXRzWzBdLmRhdGFUeXBlKTtcblxuICAgIGNvbnN0IEEgPSBpbnB1dFZhcmlhYmxlKCdhJywgaW5wdXRzWzBdLmRhdGFUeXBlLCBhUmFuaywgY29tcG9uZW50cyk7XG4gICAgY29uc3QgQiA9IGlucHV0VmFyaWFibGUoJ2InLCBpbnB1dHNbMV0uZGF0YVR5cGUsIGJSYW5rLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgncmVzdWx0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZVRlbXAubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBpbnB1dFZhcmlhYmxlcyA9IFtBLCBCXTtcbiAgICBpZiAoaGFzQmlhcykge1xuICAgICAgY29uc3QgYmlhc0NvbXBvbmVudHMgPSBpc0NoYW5uZWxzTGFzdCA/IGNvbXBvbmVudHMgOiAxO1xuICAgICAgaW5wdXRWYXJpYWJsZXMucHVzaChpbnB1dFZhcmlhYmxlKCdiaWFzJywgaW5wdXRzWzJdLmRhdGFUeXBlLCBpbnB1dHNbMl0uZGltcy5sZW5ndGgsIGJpYXNDb21wb25lbnRzKSk7XG4gICAgfVxuICAgIGNvbnN0IHVuaWZvcm1zOiBVbmlmb3Jtc0FycmF5VHlwZSA9IFtcbiAgICAgIHsgbmFtZTogJ2RpbV9hX291dGVyJywgdHlwZTogJ2kzMicgfSxcbiAgICAgIHsgbmFtZTogJ2RpbV9iX291dGVyJywgdHlwZTogJ2kzMicgfSxcbiAgICAgIHsgbmFtZTogJ2RpbV9pbm5lcicsIHR5cGU6ICdpMzInIH0sXG4gICAgXTtcbiAgICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXMoYWN0aXZhdGlvbkF0dHJpYnV0ZXMsIHVuaWZvcm1zKTtcbiAgICBjb25zdCBiYXNlVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZShvdXRwdXQudHlwZS50ZW5zb3IpO1xuICAgIGNvbnN0IGFwcGx5QWN0aXZhdGlvbiA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGFjdGl2YXRpb25BdHRyaWJ1dGVzLCBvdXRwdXQudHlwZS52YWx1ZSwgYmFzZVR5cGUpO1xuICAgIGNvbnN0IGRlY2xhcmVGdW5jdGlvbnMgPSBtYXRNdWxSZWFkV3JpdGVGblNvdXJjZShcbiAgICAgIGNvbXBvbmVudHMsXG4gICAgICBoYXNCaWFzLFxuICAgICAgYXBwbHlBY3RpdmF0aW9uLFxuICAgICAgW2JhdGNoRGltcywgQSwgQiwgb3V0cHV0XSxcbiAgICAgIGlzQ2hhbm5lbHNMYXN0LFxuICAgICk7XG4gICAgcmV0dXJuIGBcbiAgJHtzaGFkZXJIZWxwZXJcbiAgICAucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcylcbiAgICAucmVnaXN0ZXJJbnRlcm5hbFZhcmlhYmxlcyhiYXRjaERpbXMpXG4gICAgLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJpYWJsZXMsIG91dHB1dCl9XG4gICR7ZGVjbGFyZUZ1bmN0aW9uc31cbiAgJHtcbiAgICBpc1ZlYzRcbiAgICAgID8gbWFrZU1hdE11bFBhY2tlZFZlYzRTb3VyY2UoZWxlbWVudHNQZXJUaHJlYWQsIHdvcmtncm91cFNpemUsIGRhdGFUeXBlLCBiYXRjaERpbXMpXG4gICAgICA6IG1ha2VNYXRNdWxQYWNrZWRTb3VyY2UoZWxlbWVudHNQZXJUaHJlYWQsIHdvcmtncm91cFNpemUsIGRhdGFUeXBlLCBiYXRjaERpbXMpXG4gIH1cbiAgICAgICAgICAgICAgICAgICBgO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdNYXRNdWwnLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHtlbGVtZW50c1BlclRocmVhZH07JHthY3RpdmF0aW9uQXR0cmlidXRlcy5hY3RpdmF0aW9ufTske2lzVmVjNH07JHtpc0NoYW5uZWxzTGFzdH1gLFxuICAgICAgaW5wdXREZXBlbmRlbmNpZXMsXG4gICAgfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW1xuICAgICAgICB7XG4gICAgICAgICAgZGltczogc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24gPyBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbihvdXRwdXRTaGFwZSkgOiBvdXRwdXRTaGFwZSxcbiAgICAgICAgICBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogZGlzcGF0Y2hbMF0sIHk6IGRpc3BhdGNoWzFdLCB6OiBkaXNwYXRjaFsyXSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG4iLCAiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vLyBzYW1wbGVkIGZyb20gW0B0ZW5zb3JmbG93L3RmanNdIHRmanMtYmFja2VuZC13ZWJncHUvc3JjL2NvbnYyZF9tbV93ZWJncHUudHNcbi8vXG4vLyBtb2RpZmllZCB0byBmaXQgdGhlIG5lZWRzIG9mIHRoZSBwcm9qZWN0XG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgTE9HX0RFQlVHIH0gZnJvbSAnLi4vLi4vLi4vbG9nJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3ksIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZSxcbiAgVW5pZm9ybXNBcnJheVR5cGUsXG59IGZyb20gJy4uL2NvbW1vbic7XG5pbXBvcnQgeyBDb252QXR0cmlidXRlcyB9IGZyb20gJy4uL2NvbnYnO1xuaW1wb3J0IHsgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zLCBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXNEYXRhLCBnZXRBY3RpdmF0aW9uU25pcHBldCB9IGZyb20gJy4uL2Z1c2UtdXRpbHMnO1xuXG5pbXBvcnQgeyBiaWFzU25pcHBldCwgdHlwZVNuaXBwZXQgfSBmcm9tICcuL2FjdGl2YXRpb25fdXRpbCc7XG5pbXBvcnQgeyB1dGlsRnVuY3Rpb25zIH0gZnJvbSAnLi9jb252X3V0aWwnO1xuaW1wb3J0IHsgbWFrZU1hdE11bFBhY2tlZFNvdXJjZSwgbWFrZU1hdE11bFBhY2tlZFZlYzRTb3VyY2UgfSBmcm9tICcuL21hdG11bF9wYWNrZWRfd2ViZ3B1JztcblxuY29uc3QgY29udjJkQ29tbW9uU25pcHBldCA9IChcbiAgaXNDaGFubmVsc0xhc3Q6IGJvb2xlYW4sXG4gIGZpdEFPdXRlcjogYm9vbGVhbixcbiAgZml0Qk91dGVyOiBib29sZWFuLFxuICBmaXRJbm5lcjogYm9vbGVhbixcbiAgYWRkQmlhcyA9IGZhbHNlLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbiAgaW5uZXJFbGVtZW50U2l6ZVggPSA0LFxuICBpbm5lckVsZW1lbnRTaXplVyA9IDQsXG4gIGlubmVyRWxlbWVudFNpemUgPSA0LFxuICBkYXRhVHlwZSA9ICdmMzInLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgZ2V0WFNuaXBwZXQgPSAoaW5uZXJFbGVtZW50U2l6ZTogbnVtYmVyKSA9PiB7XG4gICAgc3dpdGNoIChpbm5lckVsZW1lbnRTaXplKSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiAncmVzRGF0YSA9IHhbeEluZGV4XTsnO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXR1cm4gYHJlc0RhdGEgPSB2ZWMzPCR7ZGF0YVR5cGV9Pih4W3hJbmRleF0sIHhbeEluZGV4ICsgMV0sIHhbeEluZGV4ICsgMl0pO2A7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHJldHVybiAncmVzRGF0YSA9IHhbeEluZGV4IC8gNF07JztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW5uZXJFbGVtZW50U2l6ZSAke2lubmVyRWxlbWVudFNpemV9IGlzIG5vdCBzdXBwb3J0ZWQuYCk7XG4gICAgfVxuICB9O1xuICBjb25zdCBnZXRXU25pcHBldCA9IChpbm5lckVsZW1lbnRTaXplOiBudW1iZXIpID0+IHtcbiAgICBzd2l0Y2ggKGlubmVyRWxlbWVudFNpemUpIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuICdyZXR1cm4gd1tyb3cgKiBpMzIodW5pZm9ybXMud19zaGFwZVszXSkgKyBjb2xJbl07JztcbiAgICAgIGNhc2UgNDpcbiAgICAgICAgcmV0dXJuICdyZXR1cm4gd1tyb3cgKiBpMzIodW5pZm9ybXMud19zaGFwZVszXSkgLyA0ICsgY29sSW5dOyc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGlubmVyRWxlbWVudFNpemUgJHtpbm5lckVsZW1lbnRTaXplfSBpcyBub3Qgc3VwcG9ydGVkLmApO1xuICAgIH1cbiAgfTtcbiAgY29uc3QgY29vcmRBU25pcHBldCA9IGlzQ2hhbm5lbHNMYXN0XG4gICAgPyBgXG4gICAgbGV0IGNvb3JkID0gdmVjNDxpMzI+KGJhdGNoLCB4Um93LCB4Q29sLCB4Q2gpO1xuICAgIGBcbiAgICA6IGBcbiAgICBsZXQgY29vcmQgPSB2ZWM0PGkzMj4oYmF0Y2gsIHhDaCwgeFJvdywgeENvbCk7XG4gICAgYDtcblxuICBjb25zdCBjb29yZFJlc1NuaXBwZXQgPSBpc0NoYW5uZWxzTGFzdFxuICAgID8gYFxuICAgIGxldCBjb29yZHMgPSB2ZWM0PGkzMj4oXG4gICAgICBiYXRjaCxcbiAgICAgIHJvdyAvIG91dFdpZHRoLFxuICAgICAgcm93ICUgb3V0V2lkdGgsXG4gICAgICBjb2wpO1xuICAgIGBcbiAgICA6IGBcbiAgICBsZXQgY29vcmRzID0gdmVjNDxpMzI+KFxuICAgICAgYmF0Y2gsXG4gICAgICByb3csXG4gICAgICBjb2wgLyBvdXRXaWR0aCxcbiAgICAgIGNvbCAlIG91dFdpZHRoKTtcbiAgICBgO1xuXG4gIGNvbnN0IHhIZWlnaHQgPSBpc0NoYW5uZWxzTGFzdCA/ICdpMzIodW5pZm9ybXMueF9zaGFwZVsxXSknIDogJ2kzMih1bmlmb3Jtcy54X3NoYXBlWzJdKSc7XG4gIGNvbnN0IHhXaWR0aCA9IGlzQ2hhbm5lbHNMYXN0ID8gJ2kzMih1bmlmb3Jtcy54X3NoYXBlWzJdKScgOiAnaTMyKHVuaWZvcm1zLnhfc2hhcGVbM10pJztcbiAgY29uc3Qgcm93ID0gaXNDaGFubmVsc0xhc3QgPyAncm93JyA6ICdjb2wnO1xuICBjb25zdCBjb2wgPSBpc0NoYW5uZWxzTGFzdCA/ICdjb2wnIDogJ3Jvdyc7XG4gIGNvbnN0IHJlYWRYU25pcHBldCA9IGBcbiAgICBsZXQgaW5DaGFubmVscyA9IGkzMih1bmlmb3Jtcy53X3NoYXBlWzJdKTtcbiAgICBsZXQgb3V0V2lkdGggPSAke2lzQ2hhbm5lbHNMYXN0ID8gJ2kzMih1bmlmb3Jtcy5yZXN1bHRfc2hhcGVbMl0pJyA6ICdpMzIodW5pZm9ybXMucmVzdWx0X3NoYXBlWzNdKSd9O1xuICAgIGxldCBvdXRSb3cgPSAke3Jvd30gLyBvdXRXaWR0aDtcbiAgICBsZXQgb3V0Q29sID0gJHtyb3d9ICUgb3V0V2lkdGg7XG5cbiAgICBsZXQgV1JvdyA9ICR7Y29sfSAvIChpMzIodW5pZm9ybXMud19zaGFwZVsxXSkgKiBpbkNoYW5uZWxzKTtcbiAgICBsZXQgV0NvbCA9ICR7Y29sfSAvIGluQ2hhbm5lbHMgJSBpMzIodW5pZm9ybXMud19zaGFwZVsxXSk7XG4gICAgbGV0IHhSb3cgPSBvdXRSb3cgKiB1bmlmb3Jtcy5zdHJpZGVbMF0gKyB1bmlmb3Jtcy5kaWxhdGlvblswXSAqIFdSb3cgLSB1bmlmb3Jtcy5wYWRbMF07XG4gICAgbGV0IHhDb2wgPSBvdXRDb2wgKiB1bmlmb3Jtcy5zdHJpZGVbMV0gKyB1bmlmb3Jtcy5kaWxhdGlvblsxXSAqIFdDb2wgLSB1bmlmb3Jtcy5wYWRbMV07XG4gICAgbGV0IHhDaCA9ICR7Y29sfSAlIGluQ2hhbm5lbHM7XG4gICAgdmFyIHJlc0RhdGEgPSAke3R5cGVTbmlwcGV0KGlubmVyRWxlbWVudFNpemVYLCBkYXRhVHlwZSl9KDAuMCk7XG4gICAgLy8gVGhlIGJvdW5kcyBjaGVja2luZyBpcyBhbHdheXMgbmVlZGVkIHNpbmNlIHdlIHVzZSBpdCB0byBwYWQgemVybyBmb3JcbiAgICAvLyB0aGUgJ3NhbWUnIHBhZGRpbmcgdHlwZS5cbiAgICBpZiAoeFJvdyA+PSAwICYmIHhSb3cgPCAke3hIZWlnaHR9ICYmIHhDb2wgPj0gMCAmJiB4Q29sIDwgJHt4V2lkdGh9KSB7XG4gICAgICAke2Nvb3JkQVNuaXBwZXR9XG4gICAgICBsZXQgeEluZGV4ID0gZ2V0SW5kZXhGcm9tQ29vcmRzNEQoY29vcmQsIHZlYzQ8aTMyPih1bmlmb3Jtcy54X3NoYXBlKSk7XG4gICAgICAke2dldFhTbmlwcGV0KGlubmVyRWxlbWVudFNpemVYKX1cbiAgICB9XG4gICAgcmV0dXJuIHJlc0RhdGE7YDtcblxuICBjb25zdCBzYW1wbGVYID0gaXNDaGFubmVsc0xhc3RcbiAgICA/IGZpdEFPdXRlciAmJiBmaXRJbm5lclxuICAgICAgPyBgXG4gICAgbGV0IGNvbCA9IGNvbEluICogJHtpbm5lckVsZW1lbnRTaXplWH07XG4gICAgJHtyZWFkWFNuaXBwZXR9YFxuICAgICAgOiBgXG4gICAgbGV0IGNvbCA9IGNvbEluICogJHtpbm5lckVsZW1lbnRTaXplWH07XG4gICAgaWYgKHJvdyA8IHVuaWZvcm1zLmRpbV9hX291dGVyICYmIGNvbCA8IHVuaWZvcm1zLmRpbV9pbm5lcikge1xuICAgICAgJHtyZWFkWFNuaXBwZXR9XG4gICAgfVxuICAgIHJldHVybiAke3R5cGVTbmlwcGV0KGlubmVyRWxlbWVudFNpemVYLCBkYXRhVHlwZSl9KDAuMCk7YFxuICAgIDogZml0SW5uZXIgJiYgZml0Qk91dGVyXG4gICAgICA/IGBcbiAgICBsZXQgY29sID0gY29sSW4gKiAke2lubmVyRWxlbWVudFNpemVYfTtcbiAgICAke3JlYWRYU25pcHBldH1gXG4gICAgICA6IGBcbiAgICBsZXQgY29sID0gY29sSW4gKiAke2lubmVyRWxlbWVudFNpemVYfTtcbiAgICBpZiAocm93IDwgdW5pZm9ybXMuZGltX2lubmVyICYmIGNvbCA8IHVuaWZvcm1zLmRpbV9iX291dGVyKSB7XG4gICAgICAke3JlYWRYU25pcHBldH1cbiAgICB9XG4gICAgcmV0dXJuICR7dHlwZVNuaXBwZXQoaW5uZXJFbGVtZW50U2l6ZVgsIGRhdGFUeXBlKX0oMC4wKTtgO1xuXG4gIGNvbnN0IHNhbXBsZVcgPSBpc0NoYW5uZWxzTGFzdFxuICAgID8gZml0SW5uZXIgJiYgZml0Qk91dGVyXG4gICAgICA/IGdldFdTbmlwcGV0KGlubmVyRWxlbWVudFNpemVXKVxuICAgICAgOiBgXG4gICAgbGV0IGNvbCA9IGNvbEluICogJHtpbm5lckVsZW1lbnRTaXplV307XG4gICAgaWYgKHJvdyA8IHVuaWZvcm1zLmRpbV9pbm5lciAmJiBjb2wgPCB1bmlmb3Jtcy5kaW1fYl9vdXRlcikge1xuICAgICAgJHtnZXRXU25pcHBldChpbm5lckVsZW1lbnRTaXplVyl9XG4gICAgfVxuICAgIHJldHVybiAke3R5cGVTbmlwcGV0KGlubmVyRWxlbWVudFNpemVXLCBkYXRhVHlwZSl9KDAuMCk7YFxuICAgIDogYFxuICAgIGxldCBjb2wgPSBjb2xJbiAqICR7aW5uZXJFbGVtZW50U2l6ZVd9O1xuICAgIGlmIChyb3cgPCB1bmlmb3Jtcy5kaW1faW5uZXIgJiYgY29sIDwgdW5pZm9ybXMuZGltX2Ffb3V0ZXIpIHtcbiAgICAgICR7Z2V0V1NuaXBwZXQoaW5uZXJFbGVtZW50U2l6ZVcpfVxuICAgIH1cbiAgICByZXR1cm4gJHt0eXBlU25pcHBldChpbm5lckVsZW1lbnRTaXplVywgZGF0YVR5cGUpfSgwLjApO2A7XG5cbiAgY29uc3QgcmVzVHlwZSA9IHR5cGVTbmlwcGV0KGlubmVyRWxlbWVudFNpemUsIGRhdGFUeXBlKTtcbiAgY29uc3QgYVR5cGUgPSBpc0NoYW5uZWxzTGFzdCA/IHR5cGVTbmlwcGV0KGlubmVyRWxlbWVudFNpemVYLCBkYXRhVHlwZSkgOiB0eXBlU25pcHBldChpbm5lckVsZW1lbnRTaXplVywgZGF0YVR5cGUpO1xuICBjb25zdCBiVHlwZSA9IGlzQ2hhbm5lbHNMYXN0ID8gdHlwZVNuaXBwZXQoaW5uZXJFbGVtZW50U2l6ZVcsIGRhdGFUeXBlKSA6IHR5cGVTbmlwcGV0KGlubmVyRWxlbWVudFNpemVYLCBkYXRhVHlwZSk7XG4gIGNvbnN0IGFwcGx5QWN0aXZhdGlvbiA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXMsIHJlc1R5cGUsIGRhdGFUeXBlKTtcbiAgY29uc3QgdXNlckNvZGUgPSBgXG4gICAgZm4gbW1fcmVhZEEoYmF0Y2g6IGkzMiwgcm93IDogaTMyLCBjb2xJbiA6IGkzMikgLT4gJHthVHlwZX0ge1xuICAgICAgJHtpc0NoYW5uZWxzTGFzdCA/IHNhbXBsZVggOiBzYW1wbGVXfVxuICAgIH1cblxuICAgIGZuIG1tX3JlYWRCKGJhdGNoOiBpMzIsIHJvdyA6IGkzMiwgY29sSW4gOiBpMzIpIC0+ICR7YlR5cGV9IHtcbiAgICAgICR7aXNDaGFubmVsc0xhc3QgPyBzYW1wbGVXIDogc2FtcGxlWH1cbiAgICB9XG5cbiAgICBmbiBtbV93cml0ZShiYXRjaDogaTMyLCByb3cgOiBpMzIsIGNvbEluIDogaTMyLCB2YWx1ZUluIDogJHtyZXNUeXBlfSkge1xuICAgICAgbGV0IGNvbCA9IGNvbEluICogJHtpbm5lckVsZW1lbnRTaXplfTtcbiAgICAgIGlmIChyb3cgPCB1bmlmb3Jtcy5kaW1fYV9vdXRlciAmJiBjb2wgPCB1bmlmb3Jtcy5kaW1fYl9vdXRlcilcbiAgICAgIHtcbiAgICAgIHZhciB2YWx1ZSA9IHZhbHVlSW47XG4gICAgICBsZXQgb3V0V2lkdGggPSAke2lzQ2hhbm5lbHNMYXN0ID8gJ2kzMih1bmlmb3Jtcy5yZXN1bHRfc2hhcGVbMl0pJyA6ICdpMzIodW5pZm9ybXMucmVzdWx0X3NoYXBlWzNdKSd9O1xuICAgICAgJHtjb29yZFJlc1NuaXBwZXR9XG4gICAgICAke2JpYXNTbmlwcGV0KGFkZEJpYXMpfVxuICAgICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgICBzZXRPdXRwdXRBdENvb3Jkcyhjb29yZHNbMF0sIGNvb3Jkc1sxXSwgY29vcmRzWzJdLCBjb29yZHNbM10sIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9YDtcbiAgcmV0dXJuIHVzZXJDb2RlO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbnYyRE1hdE11bFByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgZGltQU91dGVyOiBudW1iZXIsXG4gIGRpbUJPdXRlcjogbnVtYmVyLFxuICBkaW1Jbm5lcjogbnVtYmVyLFxuICBoYXNCaWFzOiBib29sZWFuLFxuICBzZXF1ZW50aWFsQWNjZXNzQnlUaHJlYWRzOiBib29sZWFuLFxuICBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbj86IChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pID0+IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpc0NoYW5uZWxzTGFzdCA9IGF0dHJpYnV0ZXMuZm9ybWF0ID09PSAnTkhXQyc7XG4gIGNvbnN0IGluQ2hhbm5lbHMgPSBpc0NoYW5uZWxzTGFzdCA/IGlucHV0c1swXS5kaW1zWzNdIDogaW5wdXRzWzBdLmRpbXNbMV07XG4gIGNvbnN0IGJhdGNoU2l6ZSA9IG91dHB1dFNoYXBlWzBdO1xuICBjb25zdCBvdXRXaWR0aCA9IGlzQ2hhbm5lbHNMYXN0ID8gb3V0cHV0U2hhcGVbMl0gOiBvdXRwdXRTaGFwZVszXTtcbiAgY29uc3Qgb3V0SGVpZ2h0ID0gaXNDaGFubmVsc0xhc3QgPyBvdXRwdXRTaGFwZVsxXSA6IG91dHB1dFNoYXBlWzJdO1xuICBjb25zdCBvdXRDaGFubmVscyA9IGlzQ2hhbm5lbHNMYXN0ID8gb3V0cHV0U2hhcGVbM10gOiBvdXRwdXRTaGFwZVsxXTtcbiAgLy8gVE9ETzogZW5hYmxlIHZlYzQgZm9yIE5DSFdcbiAgY29uc3QgaXNWZWM0ID0gaXNDaGFubmVsc0xhc3QgJiYgKGluQ2hhbm5lbHMgJSA0ID09PSAwIHx8IGluQ2hhbm5lbHMgJSAzID09PSAwKSAmJiBvdXRDaGFubmVscyAlIDQgPT09IDA7XG5cbiAgLy8gVE9ETzogZmluZSB0dW5lIHNpemVcbiAgY29uc3QgZGlzcGF0Y2hYID0gaXNDaGFubmVsc0xhc3QgPyBvdXRDaGFubmVscyA6IG91dFdpZHRoICogb3V0SGVpZ2h0O1xuICBjb25zdCBkaXNwYXRjaFkgPSBpc0NoYW5uZWxzTGFzdCA/IG91dFdpZHRoICogb3V0SGVpZ2h0IDogb3V0Q2hhbm5lbHM7XG4gIGNvbnN0IHdvcmtHcm91cFNpemU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFs4LCA4LCAxXTtcbiAgY29uc3QgZWxlbWVudHNQZXJUaHJlYWQgPSBkaW1BT3V0ZXIgPD0gOCA/IFs0LCAxLCAxXSA6IFs0LCA0LCAxXTtcbiAgY29uc3QgZGlzcGF0Y2ggPSBbXG4gICAgTWF0aC5jZWlsKGRpc3BhdGNoWCAvIHdvcmtHcm91cFNpemVbMF0gLyBlbGVtZW50c1BlclRocmVhZFswXSksXG4gICAgTWF0aC5jZWlsKGRpc3BhdGNoWSAvIHdvcmtHcm91cFNpemVbMV0gLyBlbGVtZW50c1BlclRocmVhZFsxXSksXG4gICAgTWF0aC5jZWlsKGJhdGNoU2l6ZSAvIHdvcmtHcm91cFNpemVbMl0gLyBlbGVtZW50c1BlclRocmVhZFsyXSksXG4gIF07XG5cbiAgTE9HX0RFQlVHKCd2ZXJib3NlJywgKCkgPT4gYFtjb252MmRfbW1fd2ViZ3B1XSBkaXNwYXRjaCA9ICR7ZGlzcGF0Y2h9YCk7XG5cbiAgY29uc3QgaW5uZXJFbGVtZW50U2l6ZSA9IGlzVmVjNCA/IChpc0NoYW5uZWxzTGFzdCAmJiBpbkNoYW5uZWxzICUgNCAhPT0gMCA/IDMgOiA0KSA6IDE7XG4gIGNvbnN0IHRpbGVBT3V0ZXIgPSB3b3JrR3JvdXBTaXplWzFdICogZWxlbWVudHNQZXJUaHJlYWRbMV07XG4gIGNvbnN0IHRpbGVCT3V0ZXIgPSB3b3JrR3JvdXBTaXplWzBdICogZWxlbWVudHNQZXJUaHJlYWRbMF07XG4gIGNvbnN0IHRpbGVJbm5lciA9IE1hdGgubWF4KHdvcmtHcm91cFNpemVbMF0gKiBpbm5lckVsZW1lbnRTaXplLCB3b3JrR3JvdXBTaXplWzFdKTtcbiAgY29uc3QgZml0QU91dGVyID0gZGltQU91dGVyICUgdGlsZUFPdXRlciA9PT0gMDtcbiAgY29uc3QgZml0Qk91dGVyID0gZGltQk91dGVyICUgdGlsZUJPdXRlciA9PT0gMDtcbiAgY29uc3QgZml0SW5uZXIgPSBkaW1Jbm5lciAlIHRpbGVJbm5lciA9PT0gMDtcbiAgY29uc3QgZWxlbWVudHNTaXplID0gaXNWZWM0ID8gW2lubmVyRWxlbWVudFNpemUsIDQsIDRdIDogWzEsIDEsIDFdO1xuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLmludDMyLCBkYXRhOiBkaW1BT3V0ZXIgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmludDMyLCBkYXRhOiBkaW1CT3V0ZXIgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmludDMyLCBkYXRhOiBkaW1Jbm5lciB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IFthdHRyaWJ1dGVzLnBhZHNbMF0sIGF0dHJpYnV0ZXMucGFkc1sxXV0gfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmludDMyLCBkYXRhOiBhdHRyaWJ1dGVzLnN0cmlkZXMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmludDMyLCBkYXRhOiBhdHRyaWJ1dGVzLmRpbGF0aW9ucyB9LFxuICBdO1xuICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXNEYXRhKGF0dHJpYnV0ZXMsIHByb2dyYW1Vbmlmb3Jtcyk7XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0c1swXS5kaW1zLCBpbnB1dHNbMV0uZGltcykpO1xuICBjb25zdCBpbnB1dERlcGVuZGVuY2llczogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXSA9IFsncmFuaycsICdyYW5rJ107XG4gIGlmIChoYXNCaWFzKSB7XG4gICAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRzWzJdLmRpbXMpKTtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCdyYW5rJyk7XG4gIH1cbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMob3V0cHV0U2hhcGUpKTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdkaW1fYV9vdXRlcicsIHR5cGU6ICdpMzInIH0sXG4gICAgICB7IG5hbWU6ICdkaW1fYl9vdXRlcicsIHR5cGU6ICdpMzInIH0sXG4gICAgICB7IG5hbWU6ICdkaW1faW5uZXInLCB0eXBlOiAnaTMyJyB9LFxuICAgICAgeyBuYW1lOiAncGFkJywgdHlwZTogJ2kzMicsIGxlbmd0aDogMiB9LFxuICAgICAgeyBuYW1lOiAnc3RyaWRlJywgdHlwZTogJ2kzMicsIGxlbmd0aDogMiB9LFxuICAgICAgeyBuYW1lOiAnZGlsYXRpb24nLCB0eXBlOiAnaTMyJywgbGVuZ3RoOiAyIH0sXG4gICAgXTtcbiAgICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXMoYXR0cmlidXRlcywgdW5pZm9ybXMpO1xuXG4gICAgLy8gVE9ETzogc3VwcG9ydCBjb21wb25lbnQgMiwgMy5cbiAgICBjb25zdCBjb21wb25lbnRzID0gaXNWZWM0ID8gNCA6IDE7XG4gICAgY29uc3QgdCA9IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZShpbnB1dHNbMF0uZGF0YVR5cGUpO1xuICAgIGxldCBkZWNsYXJlRnVuY3Rpb25zID0gYFxuICAgICAgZm4gc2V0T3V0cHV0QXRJbmRleChmbGF0SW5kZXggOiBpMzIsIHZhbHVlIDogJHtpc1ZlYzQgPyBgdmVjNDwke3R9PmAgOiB0fSkge1xuICAgICAgICByZXN1bHRbZmxhdEluZGV4XSA9ICR7aXNWZWM0ID8gYHZlYzQ8JHt0fT5gIDogdH0odmFsdWUpO1xuICAgICAgfVxuICAgICAgZm4gc2V0T3V0cHV0QXRDb29yZHMoZDAgOiBpMzIsIGQxIDogaTMyLCBkMiA6IGkzMiwgZDMgOiBpMzIsIHZhbHVlIDogJHtpc1ZlYzQgPyBgdmVjNDwke3R9PmAgOiB0fSkge1xuICAgICAgICBsZXQgZmxhdEluZGV4ID0gZ2V0T3V0cHV0SW5kZXhGcm9tQ29vcmRzKHZlYzQ8aTMyPihkMCwgZDEsIGQyLCBkMykpO1xuICAgICAgICBzZXRPdXRwdXRBdEluZGV4KGZsYXRJbmRleCAke2lzVmVjNCA/ICcvIDQnIDogJyd9LCB2YWx1ZSk7XG4gICAgICB9YDtcbiAgICBjb25zdCB4ID0gaW5wdXRWYXJpYWJsZShcbiAgICAgICd4JyxcbiAgICAgIGlucHV0c1swXS5kYXRhVHlwZSxcbiAgICAgIGlucHV0c1swXS5kaW1zLmxlbmd0aCxcbiAgICAgIGlubmVyRWxlbWVudFNpemUgPT09IDMgPyAxIDogaW5uZXJFbGVtZW50U2l6ZSxcbiAgICApO1xuICAgIGNvbnN0IHcgPSBpbnB1dFZhcmlhYmxlKCd3JywgaW5wdXRzWzFdLmRhdGFUeXBlLCBpbnB1dHNbMV0uZGltcy5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGlucHV0VmFyaWFibGVzID0gW3gsIHddO1xuICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdyZXN1bHQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gICAgaWYgKGhhc0JpYXMpIHtcbiAgICAgIGNvbnN0IGJpYXMgPSBpbnB1dFZhcmlhYmxlKCdiaWFzJywgaW5wdXRzWzJdLmRhdGFUeXBlLCBpbnB1dHNbMl0uZGltcy5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgICAgaW5wdXRWYXJpYWJsZXMucHVzaChiaWFzKTtcbiAgICAgIGRlY2xhcmVGdW5jdGlvbnMgKz0gYFxuICAgICAgICBmbiBnZXRCaWFzQnlPdXRwdXRDb29yZHMoY29vcmRzIDogdmVjNDxpMzI+KSAtPiAke2lzVmVjNCA/IGB2ZWM0PCR7dH0+YCA6IHR9IHtcbiAgICAgICAgICByZXR1cm4gYmlhc1tjb29yZHMuJHtpc0NoYW5uZWxzTGFzdCA/ICd3JyA6ICd5J30ke2lzVmVjNCA/ICcvIDQnIDogJyd9XTtcbiAgICAgICAgfWA7XG4gICAgfVxuXG4gICAgcmV0dXJuIGBcbiAgICAgICAgJHt1dGlsRnVuY3Rpb25zKCd1bmlmb3Jtcy5yZXN1bHRfc3RyaWRlcycpfVxuICAgICAgICAvL3N0cnVjdCBVbmlmb3JtcyB7IHhTaGFwZSA6IHZlYzQ8aTMyPiwgd1NoYXBlIDogdmVjNDxpMzI+LCBvdXRTaGFwZSA6IHZlYzQ8aTMyPixcbiAgICAgICAgLy8gIG91dFNoYXBlU3RyaWRlczogdmVjMzxpMzI+LCBmaWx0ZXJEaW1zIDogdmVjMjxpMzI+LCBwYWQgOiB2ZWMyPGkzMj4sIHN0cmlkZSA6IHZlYzI8aTMyPixcbiAgICAgICAgLy8gIGRpbGF0aW9uIDogdmVjMjxpMzI+LCBkaW1BT3V0ZXIgOiBpMzIsIGRpbUJPdXRlciA6IGkzMiwgZGltSW5uZXIgOiBpMzIgfTtcbiAgICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyguLi5pbnB1dFZhcmlhYmxlcywgb3V0cHV0KX1cbiAgICAgICAgJHtkZWNsYXJlRnVuY3Rpb25zfVxuICAgICAgICAke2NvbnYyZENvbW1vblNuaXBwZXQoXG4gICAgICAgICAgaXNDaGFubmVsc0xhc3QsXG4gICAgICAgICAgZml0QU91dGVyLFxuICAgICAgICAgIGZpdEJPdXRlcixcbiAgICAgICAgICBmaXRJbm5lcixcbiAgICAgICAgICBoYXNCaWFzLFxuICAgICAgICAgIGF0dHJpYnV0ZXMsXG4gICAgICAgICAgZWxlbWVudHNTaXplWzBdLFxuICAgICAgICAgIGVsZW1lbnRzU2l6ZVsxXSxcbiAgICAgICAgICBlbGVtZW50c1NpemVbMl0sXG4gICAgICAgICAgdCxcbiAgICAgICAgKX1cbiAgICAgICAgJHtcbiAgICAgICAgICBpc1ZlYzRcbiAgICAgICAgICAgID8gbWFrZU1hdE11bFBhY2tlZFZlYzRTb3VyY2UoZWxlbWVudHNQZXJUaHJlYWQsIHdvcmtHcm91cFNpemUsIHQsIHVuZGVmaW5lZCwgIWlzQ2hhbm5lbHNMYXN0LCB0aWxlSW5uZXIpXG4gICAgICAgICAgICA6IG1ha2VNYXRNdWxQYWNrZWRTb3VyY2UoXG4gICAgICAgICAgICAgICAgZWxlbWVudHNQZXJUaHJlYWQsXG4gICAgICAgICAgICAgICAgd29ya0dyb3VwU2l6ZSxcbiAgICAgICAgICAgICAgICB0LFxuICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAhaXNDaGFubmVsc0xhc3QsXG4gICAgICAgICAgICAgICAgdGlsZUlubmVyLFxuICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQWNjZXNzQnlUaHJlYWRzLFxuICAgICAgICAgICAgICApXG4gICAgICAgIH1gO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdDb252MkRNYXRNdWwnLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fTske2lubmVyRWxlbWVudFNpemV9OyR7aXNWZWM0fTske2ZpdEFPdXRlcn07JHtmaXRCT3V0ZXJ9OyR7Zml0SW5uZXJ9OyR7dGlsZUFPdXRlcn07JHt0aWxlQk91dGVyfTske3RpbGVJbm5lcn1gLFxuICAgICAgaW5wdXREZXBlbmRlbmNpZXMsXG4gICAgfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW1xuICAgICAgICB7XG4gICAgICAgICAgZGltczogc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24gPyBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbihvdXRwdXRTaGFwZSkgOiBvdXRwdXRTaGFwZSxcbiAgICAgICAgICBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogZGlzcGF0Y2hbMF0sIHk6IGRpc3BhdGNoWzFdLCB6OiBkaXNwYXRjaFsyXSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG4iLCAiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vLyBzYW1wbGVkIGZyb20gW0B0ZW5zb3JmbG93L3RmanNdIHRmanMtYmFja2VuZC13ZWJncHUvc3JjL2NvbnYzZF9uYWl2ZV93ZWJncHUudHNcbi8vXG4vLyBtb2RpZmllZCB0byBmaXQgdGhlIG5lZWRzIG9mIHRoZSBwcm9qZWN0XG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgTE9HX0RFQlVHIH0gZnJvbSAnLi4vLi4vLi4vbG9nJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeSwgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQge1xuICBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyxcbiAgZ2V0RWxlbWVudEF0LFxuICBpbnB1dFZhcmlhYmxlLFxuICBvdXRwdXRWYXJpYWJsZSxcbiAgU2hhZGVySGVscGVyLFxuICB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuLi9jb21tb24nO1xuaW1wb3J0IHsgQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuLi9jb252JztcbmltcG9ydCB7IGFwcGVuZEFjdGl2YXRpb25Vbmlmb3JtcywgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zRGF0YSwgZ2V0QWN0aXZhdGlvblNuaXBwZXQgfSBmcm9tICcuLi9mdXNlLXV0aWxzJztcblxuaW1wb3J0IHsgdHlwZVNuaXBwZXQgfSBmcm9tICcuL2FjdGl2YXRpb25fdXRpbCc7XG5cbmNvbnN0IGFycmF5UHJvZHVjdCA9IChhcnI6IG51bWJlcltdKSA9PiB7XG4gIGxldCBwcm9kdWN0ID0gMTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICBwcm9kdWN0ICo9IGFycltpXTtcbiAgfVxuICByZXR1cm4gcHJvZHVjdDtcbn07XG5cbmNvbnN0IHBhcnNlM1R1cGxlUGFyYW0gPSAocGFyYW06IG51bWJlciB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSk6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9PlxuICB0eXBlb2YgcGFyYW0gPT09ICdudW1iZXInID8gW3BhcmFtLCBwYXJhbSwgcGFyYW1dIDogcGFyYW07XG5cbmNvbnN0IGdldEVmZmVjdGl2ZUZpbHRlclNpemUgPSAoZmlsdGVyU2l6ZTogbnVtYmVyLCBkaWxhdGlvbjogbnVtYmVyKTogbnVtYmVyID0+IHtcbiAgaWYgKGRpbGF0aW9uIDw9IDEpIHtcbiAgICByZXR1cm4gZmlsdGVyU2l6ZTtcbiAgfVxuXG4gIHJldHVybiBmaWx0ZXJTaXplICsgKGZpbHRlclNpemUgLSAxKSAqIChkaWxhdGlvbiAtIDEpO1xufTtcblxuY29uc3QgY29tcHV0ZURlZmF1bHRQYWQgPSAoXG4gIGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlcl0gfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgZmllbGRTaXplOiBudW1iZXIsXG4gIHN0cmlkZTogbnVtYmVyLFxuICBkaWxhdGlvbiA9IDEsXG4pOiBudW1iZXIgPT4ge1xuICBjb25zdCBlZmZlY3RpdmVGaWVsZFNpemUgPSBnZXRFZmZlY3RpdmVGaWx0ZXJTaXplKGZpZWxkU2l6ZSwgZGlsYXRpb24pO1xuICByZXR1cm4gTWF0aC5mbG9vcigoaW5wdXRTaGFwZVswXSAqIChzdHJpZGUgLSAxKSAtIHN0cmlkZSArIGVmZmVjdGl2ZUZpZWxkU2l6ZSkgLyAyKTtcbn07XG5cbmNvbnN0IGNvbXB1dGVPdXRwdXRTaGFwZTREID0gKFxuICBpblNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgZmlsdGVyU2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgb3V0Q2hhbm5lbHM6IG51bWJlcixcbiAgc3RyaWRlczogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICB6ZXJvUGFkPzogbnVtYmVyLFxuKTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPT4ge1xuICBpZiAoemVyb1BhZCA9PSBudWxsKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgemVyb1BhZCA9IGNvbXB1dGVEZWZhdWx0UGFkKGluU2hhcGUsIGZpbHRlclNoYXBlWzBdLCBzdHJpZGVzWzBdKTtcbiAgfVxuICBjb25zdCBvdXRTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMCwgMCwgMCwgb3V0Q2hhbm5lbHNdO1xuICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgMzsgaW5kZXgrKykge1xuICAgIGlmIChpblNoYXBlW2luZGV4XSArIDIgKiB6ZXJvUGFkID49IGZpbHRlclNoYXBlW2luZGV4XSkge1xuICAgICAgb3V0U2hhcGVbaW5kZXhdID0gTWF0aC50cnVuYygoaW5TaGFwZVtpbmRleF0gLSBmaWx0ZXJTaGFwZVtpbmRleF0gKyAyICogemVyb1BhZCkgLyBzdHJpZGVzW2luZGV4XSArIDEpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gb3V0U2hhcGU7XG59O1xuXG5jb25zdCBnZXQzRFBhZEFuZE91dEluZm8gPSAoXG4gIHBhZDogbnVtYmVyIHwgc3RyaW5nIHwgbnVtYmVyW10sXG4gIGluRGVwdGg6IG51bWJlcixcbiAgaW5IZWlnaHQ6IG51bWJlcixcbiAgaW5XaWR0aDogbnVtYmVyLFxuICBzdHJpZGVEZXB0aDogbnVtYmVyLFxuICBzdHJpZGVIZWlnaHQ6IG51bWJlcixcbiAgc3RyaWRlV2lkdGg6IG51bWJlcixcbiAgZmlsdGVyRGVwdGg6IG51bWJlcixcbiAgZmlsdGVySGVpZ2h0OiBudW1iZXIsXG4gIGZpbHRlcldpZHRoOiBudW1iZXIsXG4pOiB7IHBhZEluZm86IFBhZEluZm8zRDsgb3V0RGVwdGg6IG51bWJlcjsgb3V0SGVpZ2h0OiBudW1iZXI7IG91dFdpZHRoOiBudW1iZXIgfSA9PiB7XG4gIGxldCBwYWRJbmZvOiBQYWRJbmZvM0Q7XG4gIGxldCBvdXREZXB0aDogbnVtYmVyO1xuICBsZXQgb3V0SGVpZ2h0OiBudW1iZXI7XG4gIGxldCBvdXRXaWR0aDogbnVtYmVyO1xuXG4gIGlmIChwYWQgPT09ICdWQUxJRCcpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgICBwYWQgPSAwO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYWQgPT09ICdudW1iZXInKSB7XG4gICAgcGFkSW5mbyA9IHsgdG9wOiBwYWQsIGJvdHRvbTogcGFkLCBsZWZ0OiBwYWQsIHJpZ2h0OiBwYWQsIGZyb250OiBwYWQsIGJhY2s6IHBhZCB9O1xuICAgIGNvbnN0IG91dFNoYXBlID0gY29tcHV0ZU91dHB1dFNoYXBlNEQoXG4gICAgICBbaW5EZXB0aCwgaW5IZWlnaHQsIGluV2lkdGgsIDFdLFxuICAgICAgW2ZpbHRlckRlcHRoLCBmaWx0ZXJIZWlnaHQsIGZpbHRlcldpZHRoXSxcbiAgICAgIDEsXG4gICAgICBbc3RyaWRlRGVwdGgsIHN0cmlkZUhlaWdodCwgc3RyaWRlV2lkdGhdLFxuICAgICAgcGFkLFxuICAgICk7XG4gICAgb3V0RGVwdGggPSBvdXRTaGFwZVswXTtcbiAgICBvdXRIZWlnaHQgPSBvdXRTaGFwZVsxXTtcbiAgICBvdXRXaWR0aCA9IG91dFNoYXBlWzJdO1xuICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkocGFkKSkge1xuICAgIGlmICghcGFkLmV2ZXJ5KCh2YWwsIF8sIGFycikgPT4gdmFsID09PSBhcnJbMF0pKSB7XG4gICAgICB0aHJvdyBFcnJvcihgVW5zdXBwb3J0ZWQgcGFkZGluZyBwYXJhbWV0ZXI6ICR7cGFkfWApO1xuICAgIH1cbiAgICBwYWRJbmZvID0geyB0b3A6IHBhZFswXSwgYm90dG9tOiBwYWRbMV0sIGxlZnQ6IHBhZFsyXSwgcmlnaHQ6IHBhZFszXSwgZnJvbnQ6IHBhZFs0XSwgYmFjazogcGFkWzVdIH07XG4gICAgY29uc3Qgb3V0U2hhcGUgPSBjb21wdXRlT3V0cHV0U2hhcGU0RChcbiAgICAgIFtpbkRlcHRoLCBpbkhlaWdodCwgaW5XaWR0aCwgMV0sXG4gICAgICBbZmlsdGVyRGVwdGgsIGZpbHRlckhlaWdodCwgZmlsdGVyV2lkdGhdLFxuICAgICAgMSxcbiAgICAgIFtzdHJpZGVEZXB0aCwgc3RyaWRlSGVpZ2h0LCBzdHJpZGVXaWR0aF0sXG4gICAgICBwYWRbMF0sXG4gICAgKTtcbiAgICBvdXREZXB0aCA9IG91dFNoYXBlWzBdO1xuICAgIG91dEhlaWdodCA9IG91dFNoYXBlWzFdO1xuICAgIG91dFdpZHRoID0gb3V0U2hhcGVbMl07XG4gIH0gZWxzZSBpZiAocGFkID09PSAnU0FNRV9VUFBFUicpIHtcbiAgICAvLyBUT0RPOiBzdXBwb3J0ICdTQU1FX0xPV0VSJy5cbiAgICBvdXREZXB0aCA9IE1hdGguY2VpbChpbkRlcHRoIC8gc3RyaWRlRGVwdGgpO1xuICAgIG91dEhlaWdodCA9IE1hdGguY2VpbChpbkhlaWdodCAvIHN0cmlkZUhlaWdodCk7XG4gICAgb3V0V2lkdGggPSBNYXRoLmNlaWwoaW5XaWR0aCAvIHN0cmlkZVdpZHRoKTtcbiAgICBjb25zdCBwYWRBbG9uZ0RlcHRoID0gKG91dERlcHRoIC0gMSkgKiBzdHJpZGVEZXB0aCArIGZpbHRlckRlcHRoIC0gaW5EZXB0aDtcbiAgICBjb25zdCBwYWRBbG9uZ0hlaWdodCA9IChvdXRIZWlnaHQgLSAxKSAqIHN0cmlkZUhlaWdodCArIGZpbHRlckhlaWdodCAtIGluSGVpZ2h0O1xuICAgIGNvbnN0IHBhZEFsb25nV2lkdGggPSAob3V0V2lkdGggLSAxKSAqIHN0cmlkZVdpZHRoICsgZmlsdGVyV2lkdGggLSBpbldpZHRoO1xuICAgIGNvbnN0IGZyb250ID0gTWF0aC5mbG9vcihwYWRBbG9uZ0RlcHRoIC8gMik7XG4gICAgY29uc3QgYmFjayA9IHBhZEFsb25nRGVwdGggLSBmcm9udDtcbiAgICBjb25zdCB0b3AgPSBNYXRoLmZsb29yKHBhZEFsb25nSGVpZ2h0IC8gMik7XG4gICAgY29uc3QgYm90dG9tID0gcGFkQWxvbmdIZWlnaHQgLSB0b3A7XG4gICAgY29uc3QgbGVmdCA9IE1hdGguZmxvb3IocGFkQWxvbmdXaWR0aCAvIDIpO1xuICAgIGNvbnN0IHJpZ2h0ID0gcGFkQWxvbmdXaWR0aCAtIGxlZnQ7XG5cbiAgICBwYWRJbmZvID0geyB0b3AsIGJvdHRvbSwgbGVmdCwgcmlnaHQsIGZyb250LCBiYWNrIH07XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgRXJyb3IoYFVua25vd24gcGFkZGluZyBwYXJhbWV0ZXI6ICR7cGFkfWApO1xuICB9XG4gIHJldHVybiB7IHBhZEluZm8sIG91dERlcHRoLCBvdXRIZWlnaHQsIG91dFdpZHRoIH07XG59O1xuXG50eXBlIFBhZEluZm8zRCA9IHtcbiAgdG9wOiBudW1iZXI7XG4gIGxlZnQ6IG51bWJlcjtcbiAgcmlnaHQ6IG51bWJlcjtcbiAgYm90dG9tOiBudW1iZXI7XG4gIGZyb250OiBudW1iZXI7XG4gIGJhY2s6IG51bWJlcjtcbn07XG5cbmV4cG9ydCB0eXBlIENvbnYzREluZm8gPSB7XG4gIGJhdGNoU2l6ZTogbnVtYmVyO1xuICBpbkRlcHRoOiBudW1iZXI7XG4gIGluSGVpZ2h0OiBudW1iZXI7XG4gIGluV2lkdGg6IG51bWJlcjtcbiAgaW5DaGFubmVsczogbnVtYmVyO1xuICBvdXREZXB0aDogbnVtYmVyO1xuICBvdXRIZWlnaHQ6IG51bWJlcjtcbiAgb3V0V2lkdGg6IG51bWJlcjtcbiAgb3V0Q2hhbm5lbHM6IG51bWJlcjtcbiAgZGF0YUZvcm1hdDogJ2NoYW5uZWxzRmlyc3QnIHwgJ2NoYW5uZWxzTGFzdCc7XG4gIHN0cmlkZURlcHRoOiBudW1iZXI7XG4gIHN0cmlkZUhlaWdodDogbnVtYmVyO1xuICBzdHJpZGVXaWR0aDogbnVtYmVyO1xuICBkaWxhdGlvbkRlcHRoOiBudW1iZXI7XG4gIGRpbGF0aW9uSGVpZ2h0OiBudW1iZXI7XG4gIGRpbGF0aW9uV2lkdGg6IG51bWJlcjtcbiAgZmlsdGVyRGVwdGg6IG51bWJlcjtcbiAgZmlsdGVySGVpZ2h0OiBudW1iZXI7XG4gIGZpbHRlcldpZHRoOiBudW1iZXI7XG4gIGVmZmVjdGl2ZUZpbHRlckRlcHRoOiBudW1iZXI7XG4gIGVmZmVjdGl2ZUZpbHRlckhlaWdodDogbnVtYmVyO1xuICBlZmZlY3RpdmVGaWx0ZXJXaWR0aDogbnVtYmVyO1xuICBwYWRJbmZvOiBQYWRJbmZvM0Q7XG4gIGluU2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIG91dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb21wdXRlQ29udjNESW5mbyA9IChcbiAgaW5TaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgZmlsdGVyU2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gIHN0cmlkZXM6IG51bWJlciB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgZGlsYXRpb25zOiBudW1iZXIgfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gIHBhZDogbnVtYmVyIHwgc3RyaW5nIHwgbnVtYmVyW10sXG4gIGRlcHRod2lzZSA9IGZhbHNlLFxuICBkYXRhRm9ybWF0OiAnY2hhbm5lbHNGaXJzdCcgfCAnY2hhbm5lbHNMYXN0JyA9ICdjaGFubmVsc0xhc3QnLFxuKTogQ29udjNESW5mbyA9PiB7XG4gIGxldCBiYXRjaFNpemUsIGluRGVwdGgsIGluSGVpZ2h0LCBpbldpZHRoLCBpbkNoYW5uZWxzO1xuICBpZiAoZGF0YUZvcm1hdCA9PT0gJ2NoYW5uZWxzTGFzdCcpIHtcbiAgICBbYmF0Y2hTaXplLCBpbkRlcHRoLCBpbkhlaWdodCwgaW5XaWR0aCwgaW5DaGFubmVsc10gPSBpblNoYXBlO1xuICB9IGVsc2UgaWYgKGRhdGFGb3JtYXQgPT09ICdjaGFubmVsc0ZpcnN0Jykge1xuICAgIFtiYXRjaFNpemUsIGluQ2hhbm5lbHMsIGluRGVwdGgsIGluSGVpZ2h0LCBpbldpZHRoXSA9IGluU2hhcGU7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGRhdGFGb3JtYXQgJHtkYXRhRm9ybWF0fWApO1xuICB9XG4gIGNvbnN0IFtmaWx0ZXJDaGFubmVscywgLCBmaWx0ZXJEZXB0aCwgZmlsdGVySGVpZ2h0LCBmaWx0ZXJXaWR0aF0gPSBmaWx0ZXJTaGFwZTtcblxuICBjb25zdCBbc3RyaWRlRGVwdGgsIHN0cmlkZUhlaWdodCwgc3RyaWRlV2lkdGhdID0gcGFyc2UzVHVwbGVQYXJhbShzdHJpZGVzKTtcbiAgY29uc3QgW2RpbGF0aW9uRGVwdGgsIGRpbGF0aW9uSGVpZ2h0LCBkaWxhdGlvbldpZHRoXSA9IHBhcnNlM1R1cGxlUGFyYW0oZGlsYXRpb25zKTtcblxuICBjb25zdCBlZmZlY3RpdmVGaWx0ZXJEZXB0aCA9IGdldEVmZmVjdGl2ZUZpbHRlclNpemUoZmlsdGVyRGVwdGgsIGRpbGF0aW9uRGVwdGgpO1xuICBjb25zdCBlZmZlY3RpdmVGaWx0ZXJIZWlnaHQgPSBnZXRFZmZlY3RpdmVGaWx0ZXJTaXplKGZpbHRlckhlaWdodCwgZGlsYXRpb25IZWlnaHQpO1xuICBjb25zdCBlZmZlY3RpdmVGaWx0ZXJXaWR0aCA9IGdldEVmZmVjdGl2ZUZpbHRlclNpemUoZmlsdGVyV2lkdGgsIGRpbGF0aW9uV2lkdGgpO1xuICBjb25zdCB7IHBhZEluZm8sIG91dERlcHRoLCBvdXRIZWlnaHQsIG91dFdpZHRoIH0gPSBnZXQzRFBhZEFuZE91dEluZm8oXG4gICAgcGFkLFxuICAgIGluRGVwdGgsXG4gICAgaW5IZWlnaHQsXG4gICAgaW5XaWR0aCxcbiAgICBzdHJpZGVEZXB0aCxcbiAgICBzdHJpZGVIZWlnaHQsXG4gICAgc3RyaWRlV2lkdGgsXG4gICAgZWZmZWN0aXZlRmlsdGVyRGVwdGgsXG4gICAgZWZmZWN0aXZlRmlsdGVySGVpZ2h0LFxuICAgIGVmZmVjdGl2ZUZpbHRlcldpZHRoLFxuICApO1xuXG4gIGNvbnN0IG91dENoYW5uZWxzID0gZGVwdGh3aXNlID8gZmlsdGVyQ2hhbm5lbHMgKiBpbkNoYW5uZWxzIDogZmlsdGVyQ2hhbm5lbHM7XG5cbiAgbGV0IG91dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzAsIDAsIDAsIDAsIDBdO1xuICBpZiAoZGF0YUZvcm1hdCA9PT0gJ2NoYW5uZWxzRmlyc3QnKSB7XG4gICAgb3V0U2hhcGUgPSBbYmF0Y2hTaXplLCBvdXRDaGFubmVscywgb3V0RGVwdGgsIG91dEhlaWdodCwgb3V0V2lkdGhdO1xuICB9IGVsc2UgaWYgKGRhdGFGb3JtYXQgPT09ICdjaGFubmVsc0xhc3QnKSB7XG4gICAgb3V0U2hhcGUgPSBbYmF0Y2hTaXplLCBvdXREZXB0aCwgb3V0SGVpZ2h0LCBvdXRXaWR0aCwgb3V0Q2hhbm5lbHNdO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBiYXRjaFNpemUsXG4gICAgZGF0YUZvcm1hdCxcbiAgICBpbkRlcHRoLFxuICAgIGluSGVpZ2h0LFxuICAgIGluV2lkdGgsXG4gICAgaW5DaGFubmVscyxcbiAgICBvdXREZXB0aCxcbiAgICBvdXRIZWlnaHQsXG4gICAgb3V0V2lkdGgsXG4gICAgb3V0Q2hhbm5lbHMsXG4gICAgcGFkSW5mbyxcbiAgICBzdHJpZGVEZXB0aCxcbiAgICBzdHJpZGVIZWlnaHQsXG4gICAgc3RyaWRlV2lkdGgsXG4gICAgZmlsdGVyRGVwdGgsXG4gICAgZmlsdGVySGVpZ2h0LFxuICAgIGZpbHRlcldpZHRoLFxuICAgIGVmZmVjdGl2ZUZpbHRlckRlcHRoLFxuICAgIGVmZmVjdGl2ZUZpbHRlckhlaWdodCxcbiAgICBlZmZlY3RpdmVGaWx0ZXJXaWR0aCxcbiAgICBkaWxhdGlvbkRlcHRoLFxuICAgIGRpbGF0aW9uSGVpZ2h0LFxuICAgIGRpbGF0aW9uV2lkdGgsXG4gICAgaW5TaGFwZSxcbiAgICBvdXRTaGFwZSxcbiAgICBmaWx0ZXJTaGFwZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVDb252M0ROYWl2ZVByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgZmlsdGVyRGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHBhZHM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBkYXRhRm9ybWF0OiBzdHJpbmcsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlzQ2hhbm5lbExhc3QgPSBkYXRhRm9ybWF0ID09PSAnY2hhbm5lbHNMYXN0JztcbiAgY29uc3QgaW5DaGFubmVscyA9IGlzQ2hhbm5lbExhc3QgPyBpbnB1dHNbMF0uZGltc1szXSA6IGlucHV0c1swXS5kaW1zWzFdO1xuICAvLyBUT0RPOiBlbmFibGUgdmVjNC5cbiAgY29uc3QgaXNWZWM0ID0gZmFsc2U7XG4gIGNvbnN0IHdvcmtHcm91cFNpemU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFs2NCwgMSwgMV07XG4gIGNvbnN0IGRpc3BhdGNoTGF5b3V0ID0geyB4OiBvdXRwdXRTaGFwZS5tYXAoKF8sIGkpID0+IGkpIH07XG4gIGNvbnN0IGRpc3BhdGNoID0gW01hdGguY2VpbChhcnJheVByb2R1Y3QoZGlzcGF0Y2hMYXlvdXQueC5tYXAoKGQpID0+IG91dHB1dFNoYXBlW2RdKSkgLyB3b3JrR3JvdXBTaXplWzBdKSwgMSwgMV07XG5cbiAgTE9HX0RFQlVHKCd2ZXJib3NlJywgKCkgPT4gYFtjb252M2RfbmFpdmVfd2ViZ3B1XSBkaXNwYXRjaCA9ICR7ZGlzcGF0Y2h9YCk7XG5cbiAgY29uc3QgaW5uZXJFbGVtZW50U2l6ZSA9IGlzVmVjNCA/IChpc0NoYW5uZWxMYXN0ICYmIGluQ2hhbm5lbHMgJSA0ICE9PSAwID8gMyA6IDQpIDogMTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGZpbHRlckRpbXMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFkcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBhdHRyaWJ1dGVzLnN0cmlkZXMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYXR0cmlidXRlcy5kaWxhdGlvbnMgfSxcbiAgXTtcbiAgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zRGF0YShhdHRyaWJ1dGVzLCBwcm9ncmFtVW5pZm9ybXMpO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmRpbXMpKTtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3JhbmsnLCAncmFuayddO1xuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA9PT0gMztcbiAgaWYgKGhhc0JpYXMpIHtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMl0uZGltcykpO1xuICAgIGlucHV0RGVwZW5kZW5jaWVzLnB1c2goJ3JhbmsnKTtcbiAgfVxuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhvdXRwdXRTaGFwZSkpO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IHVuaWZvcm1zOiBVbmlmb3Jtc0FycmF5VHlwZSA9IFtcbiAgICAgIHsgbmFtZTogJ291dHB1dF9zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2ZpbHRlcl9kaW1zJywgdHlwZTogJ3UzMicsIGxlbmd0aDogZmlsdGVyRGltcy5sZW5ndGggfSxcbiAgICAgIHsgbmFtZTogJ3BhZHMnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiBwYWRzLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAnc3RyaWRlcycsIHR5cGU6ICd1MzInLCBsZW5ndGg6IGF0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggfSxcbiAgICAgIHsgbmFtZTogJ2RpbGF0aW9ucycsIHR5cGU6ICd1MzInLCBsZW5ndGg6IGF0dHJpYnV0ZXMuZGlsYXRpb25zLmxlbmd0aCB9LFxuICAgIF07XG4gICAgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zKGF0dHJpYnV0ZXMsIHVuaWZvcm1zKTtcbiAgICAvLyBUT0RPOiBzdXBwb3J0IGNvbXBvbmVudCAyLCAzLlxuICAgIGNvbnN0IGNvbXBvbmVudHMgPSBpc1ZlYzQgPyA0IDogMTtcbiAgICBjb25zdCB0ID0gdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlKGlucHV0c1swXS5kYXRhVHlwZSk7XG5cbiAgICBjb25zdCB4ID0gaW5wdXRWYXJpYWJsZShcbiAgICAgICd4JyxcbiAgICAgIGlucHV0c1swXS5kYXRhVHlwZSxcbiAgICAgIGlucHV0c1swXS5kaW1zLmxlbmd0aCxcbiAgICAgIGlubmVyRWxlbWVudFNpemUgPT09IDMgPyAxIDogaW5uZXJFbGVtZW50U2l6ZSxcbiAgICApO1xuICAgIGNvbnN0IHcgPSBpbnB1dFZhcmlhYmxlKCdXJywgaW5wdXRzWzFdLmRhdGFUeXBlLCBpbnB1dHNbMV0uZGltcy5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGlucHV0VmFyaWFibGVzID0gW3gsIHddO1xuICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdyZXN1bHQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gICAgbGV0IGRlY2xhcmVGdW5jdGlvbnMgPSAnJztcbiAgICBpZiAoaGFzQmlhcykge1xuICAgICAgY29uc3QgYmlhcyA9IGlucHV0VmFyaWFibGUoJ2JpYXMnLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gICAgICBpbnB1dFZhcmlhYmxlcy5wdXNoKGJpYXMpO1xuICAgICAgZGVjbGFyZUZ1bmN0aW9ucyArPSBgXG4gICAgICAgIGZuIGdldEJpYXNCeU91dHB1dENvb3Jkcyhjb29yZHMgOiBhcnJheTx1MzIsIDU+KSAtPiAke2lzVmVjNCA/IGB2ZWM0PCR7dH0+YCA6IHR9IHtcbiAgICAgICAgICByZXR1cm4gYmlhc1ske2lzQ2hhbm5lbExhc3QgPyBnZXRFbGVtZW50QXQoJ2Nvb3JkcycsIDQsIDUpIDogZ2V0RWxlbWVudEF0KCdjb29yZHMnLCAxLCA1KX0ke1xuICAgICAgICAgICAgaXNWZWM0ID8gJy8gNCcgOiAnJ1xuICAgICAgICAgIH1dO1xuICAgICAgICB9YDtcbiAgICB9XG4gICAgY29uc3QgcmVzVHlwZSA9IHR5cGVTbmlwcGV0KGlubmVyRWxlbWVudFNpemUsIHQpO1xuICAgIGNvbnN0IGFwcGx5QWN0aXZhdGlvbiA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXMsIHJlc1R5cGUsIHQpO1xuXG4gICAgcmV0dXJuIGBcbiAgICAgICAgICAgICR7ZGVjbGFyZUZ1bmN0aW9uc31cbiAgICAgICAgICAgIGZuIGdldFgoZDAgOiB1MzIsIGQxIDogdTMyLCBkMiA6IHUzMiwgZDMgOiB1MzIsIGQ0IDogdTMyKSAtPiBmMzIge1xuICAgICAgICAgICAgICBsZXQgYUluZGljZXMgPSBhcnJheTx1MzIsIDU+KGQwLCBkMSwgZDIsIGQzLCBkNCk7XG4gICAgICAgICAgICAgIHJldHVybiAke3guZ2V0QnlJbmRpY2VzKCdhSW5kaWNlcycpfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZuIGdldFcoZDAgOiB1MzIsIGQxIDogdTMyLCBkMiA6IHUzMiwgZDMgOiB1MzIsIGQ0IDogdTMyKSAtPiBmMzIge1xuICAgICAgICAgICAgICBsZXQgYUluZGljZXMgPSBhcnJheTx1MzIsIDU+KGQwLCBkMSwgZDIsIGQzLCBkNCk7XG4gICAgICAgICAgICAgIHJldHVybiAke3cuZ2V0QnlJbmRpY2VzKCdhSW5kaWNlcycpfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKC4uLmlucHV0VmFyaWFibGVzLCBvdXRwdXQpfVxuICAgICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgICAgICAgICAgIGxldCBjb29yZHMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG4gICAgICAgICAgICAgIGxldCBiYXRjaCA9ICR7Z2V0RWxlbWVudEF0KCdjb29yZHMnLCAwLCB4LnJhbmspfTtcbiAgICAgICAgICAgICAgbGV0IGQyID0gJHtcbiAgICAgICAgICAgICAgICBpc0NoYW5uZWxMYXN0ID8gZ2V0RWxlbWVudEF0KCdjb29yZHMnLCB4LnJhbmsgLSAxLCB4LnJhbmspIDogZ2V0RWxlbWVudEF0KCdjb29yZHMnLCAxLCB4LnJhbmspXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIGxldCB4RlJDQ29ybmVyID0gdmVjMzx1MzI+KCR7XG4gICAgICAgICAgICAgICAgaXNDaGFubmVsTGFzdCA/IGdldEVsZW1lbnRBdCgnY29vcmRzJywgMSwgeC5yYW5rKSA6IGdldEVsZW1lbnRBdCgnY29vcmRzJywgMiwgeC5yYW5rKVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAke2lzQ2hhbm5lbExhc3QgPyBnZXRFbGVtZW50QXQoJ2Nvb3JkcycsIDIsIHgucmFuaykgOiBnZXRFbGVtZW50QXQoJ2Nvb3JkcycsIDMsIHgucmFuayl9LFxuICAgICAgICAgICAgICAke1xuICAgICAgICAgICAgICAgIGlzQ2hhbm5lbExhc3QgPyBnZXRFbGVtZW50QXQoJ2Nvb3JkcycsIDMsIHgucmFuaykgOiBnZXRFbGVtZW50QXQoJ2Nvb3JkcycsIDQsIHgucmFuaylcbiAgICAgICAgICAgICAgfSkgKiB1bmlmb3Jtcy5zdHJpZGVzIC0gdW5pZm9ybXMucGFkcztcbiAgICAgICAgICAgICAgbGV0IHhGQ29ybmVyID0geEZSQ0Nvcm5lci54O1xuICAgICAgICAgICAgICBsZXQgeFJDb3JuZXIgPSB4RlJDQ29ybmVyLnk7XG4gICAgICAgICAgICAgIGxldCB4Q0Nvcm5lciA9IHhGUkNDb3JuZXIuejtcbiAgICAgICAgICAgICAgbGV0IHhTaGFwZVkgPSAke1xuICAgICAgICAgICAgICAgIGlzQ2hhbm5lbExhc3RcbiAgICAgICAgICAgICAgICAgID8gZ2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3NoYXBlJywgMSwgeC5yYW5rKVxuICAgICAgICAgICAgICAgICAgOiBnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc2hhcGUnLCAyLCB4LnJhbmspXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIGxldCB4U2hhcGVaID0gJHtcbiAgICAgICAgICAgICAgICBpc0NoYW5uZWxMYXN0XG4gICAgICAgICAgICAgICAgICA/IGdldEVsZW1lbnRBdCgndW5pZm9ybXMueF9zaGFwZScsIDIsIHgucmFuaylcbiAgICAgICAgICAgICAgICAgIDogZ2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3NoYXBlJywgMywgeC5yYW5rKVxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBsZXQgeFNoYXBlVyA9ICR7XG4gICAgICAgICAgICAgICAgaXNDaGFubmVsTGFzdFxuICAgICAgICAgICAgICAgICAgPyBnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc2hhcGUnLCAzLCB4LnJhbmspXG4gICAgICAgICAgICAgICAgICA6IGdldEVsZW1lbnRBdCgndW5pZm9ybXMueF9zaGFwZScsIDQsIHgucmFuaylcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgbGV0IHhTaGFwZVUgPSAke1xuICAgICAgICAgICAgICAgIGlzQ2hhbm5lbExhc3RcbiAgICAgICAgICAgICAgICAgID8gZ2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3NoYXBlJywgNCwgeC5yYW5rKVxuICAgICAgICAgICAgICAgICAgOiBnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc2hhcGUnLCAxLCB4LnJhbmspXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIGxldCBpbnB1dERlcHRoTmVhcmVzdFZlYzQgPSAoeFNoYXBlVSAvIDQpICogNDtcbiAgICAgICAgICAgICAgbGV0IGlucHV0RGVwdGhWZWM0UmVtYWluZGVyID0geFNoYXBlVSAlIDQ7XG5cbiAgICAgICAgICAgICAgdmFyIHZhbHVlID0gMC4wO1xuICAgICAgICAgICAgICBmb3IgKHZhciB3RiA9IDB1OyB3RiA8IHVuaWZvcm1zLmZpbHRlcl9kaW1zWzBdOyB3RisrKSB7XG4gICAgICAgICAgICAgICAgbGV0IHhGID0geEZDb3JuZXIgKyB3RiAqIHVuaWZvcm1zLmRpbGF0aW9uc1swXTtcbiAgICAgICAgICAgICAgICBpZiAoeEYgPCAwIHx8IHhGID49IHhTaGFwZVkpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGZvciAodmFyIHdSID0gMHU7IHdSIDwgdW5pZm9ybXMuZmlsdGVyX2RpbXNbMV07IHdSKyspIHtcbiAgICAgICAgICAgICAgICAgIGxldCB4UiA9IHhSQ29ybmVyICsgd1IgKiB1bmlmb3Jtcy5kaWxhdGlvbnNbMV07XG4gICAgICAgICAgICAgICAgICBpZiAoeFIgPCAwIHx8IHhSID49IHhTaGFwZVopIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIGZvciAodmFyIHdDID0gMHU7IHdDIDwgdW5pZm9ybXMuZmlsdGVyX2RpbXNbMl07IHdDKyspIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHhDID0geENDb3JuZXIgKyB3QyAqIHVuaWZvcm1zLmRpbGF0aW9uc1syXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHhDIDwgMCB8fCB4QyA+PSB4U2hhcGVXKSB7XG4gICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBkMSA9IDB1OyBkMSA8IGlucHV0RGVwdGhOZWFyZXN0VmVjNDsgZDEgKz0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICR7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0NoYW5uZWxMYXN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgID8gYGxldCB4VmFsdWVzID0gdmVjNDxmMzI+KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsIGQxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4RiwgeFIsIHhDLCBkMSArIDEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsIGQxICsgMiksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgZDEgKyAzKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYFxuICAgICAgICAgICAgICAgICAgICAgICAgICA6IGBsZXQgeFZhbHVlcyA9IHZlYzQ8ZjMyPihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCBkMSwgeEYsIHhSLCB4QyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgZDEgKyAxLCB4RiwgeFIsIHhDKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCBkMSArIDIsIHhGLCB4UiwgeEMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIGQxICsgMywgeEYsIHhSLCB4QykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHdWYWx1ZXMgPSB2ZWM0PGYzMj4oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRXKGQyLCBkMSwgd0YsIHdSLCB3QyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRXKGQyLCBkMSArIDEsIHdGLCB3Uiwgd0MpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0VyhkMiwgZDEgKyAyLCB3Riwgd1IsIHdDKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFcoZDIsIGQxICsgMywgd0YsIHdSLCB3QykpO1xuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlICs9IGRvdCh4VmFsdWVzLCB3VmFsdWVzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXREZXB0aFZlYzRSZW1haW5kZXIgPT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaXNDaGFubmVsTGFzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gYHZhbHVlICs9IGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsIGlucHV0RGVwdGhOZWFyZXN0VmVjNClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKiBnZXRXKGQyLCBpbnB1dERlcHRoTmVhcmVzdFZlYzQsIHdGLCB3Uiwgd0MpO2BcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGB2YWx1ZSArPSBnZXRYKGJhdGNoLCBpbnB1dERlcHRoTmVhcmVzdFZlYzQsIHhGLCB4UiwgeEMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICogZ2V0VyhkMiwgaW5wdXREZXB0aE5lYXJlc3RWZWM0LCB3Riwgd1IsIHdDKTtgXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaW5wdXREZXB0aFZlYzRSZW1haW5kZXIgPT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICR7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0NoYW5uZWxMYXN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgID8gYGxldCB4VmFsdWVzID0gdmVjMjxmMzI+KFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgaW5wdXREZXB0aE5lYXJlc3RWZWM0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsIGlucHV0RGVwdGhOZWFyZXN0VmVjNCArIDEpKTtcbiAgICAgICAgICAgICAgICAgICAgICBgXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogYGxldCB4VmFsdWVzID0gdmVjMjxmMzI+KFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgaW5wdXREZXB0aE5lYXJlc3RWZWM0LCB4RiwgeFIsIHhDKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIGlucHV0RGVwdGhOZWFyZXN0VmVjNCArIDEsIHhGLCB4UiwgeEMpKTtcbiAgICAgICAgICAgICAgICAgICAgYFxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbGV0IHdWYWx1ZXMgPSB2ZWMyPGYzMj4oXG4gICAgICAgICAgICAgICAgICAgICAgZ2V0VyhkMiwgaW5wdXREZXB0aE5lYXJlc3RWZWM0LCB3Riwgd1IsIHdDKSxcbiAgICAgICAgICAgICAgICAgICAgICBnZXRXKGQyLCBpbnB1dERlcHRoTmVhcmVzdFZlYzQgKyAxLCB3Riwgd1IsIHdDKSk7XG4gICAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gZG90KHhWYWx1ZXMsIHdWYWx1ZXMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlucHV0RGVwdGhWZWM0UmVtYWluZGVyID09IDMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAke1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNDaGFubmVsTGFzdFxuICAgICAgICAgICAgICAgICAgICAgICAgICA/IGBsZXQgeFZhbHVlcyA9IHZlYzM8ZjMyPihcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsIGlucHV0RGVwdGhOZWFyZXN0VmVjNCksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4RiwgeFIsIHhDLCBpbnB1dERlcHRoTmVhcmVzdFZlYzQgKyAxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsIGlucHV0RGVwdGhOZWFyZXN0VmVjNCArIDIpKTtcbiAgICAgICAgICAgICAgICAgICAgICBgXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogYGxldCB4VmFsdWVzID0gdmVjMzxmMzI+KFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgaW5wdXREZXB0aE5lYXJlc3RWZWM0LCB4RiwgeFIsIHhDKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIGlucHV0RGVwdGhOZWFyZXN0VmVjNCArIDEsIHhGLCB4UiwgeEMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgaW5wdXREZXB0aE5lYXJlc3RWZWM0ICsgMiwgeEYsIHhSLCB4QykpO1xuICAgICAgICAgICAgICAgICAgICBgXG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBsZXQgd1ZhbHVlcyA9IHZlYzM8ZjMyPihcbiAgICAgICAgICAgICAgICAgICAgICBnZXRXKGQyLCBpbnB1dERlcHRoTmVhcmVzdFZlYzQsIHdGLCB3Uiwgd0MpLFxuICAgICAgICAgICAgICAgICAgICAgIGdldFcoZDIsIGlucHV0RGVwdGhOZWFyZXN0VmVjNCArIDEsIHdGLCB3Uiwgd0MpLFxuICAgICAgICAgICAgICAgICAgICAgIGdldFcoZDIsIGlucHV0RGVwdGhOZWFyZXN0VmVjNCArIDIsIHdGLCB3Uiwgd0MpKTtcbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSArPSBkb3QoeFZhbHVlcywgd1ZhbHVlcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgJHtoYXNCaWFzID8gJ3ZhbHVlID0gdmFsdWUgKyBnZXRCaWFzQnlPdXRwdXRDb29yZHMoY29vcmRzKScgOiAnJ307XG4gICAgICAgICAgICAgICR7YXBwbHlBY3RpdmF0aW9ufVxuICAgICAgICAgICAgICByZXN1bHRbZ2xvYmFsX2lkeF0gPSBmMzIodmFsdWUpO1xuICAgICAgICAgIH1gO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdDb252M0ROYWl2ZScsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX07JHtpc0NoYW5uZWxMYXN0fTske2lubmVyRWxlbWVudFNpemV9OyR7aGFzQmlhc31gLCBpbnB1dERlcGVuZGVuY2llcyB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogZGlzcGF0Y2hbMF0sIHk6IGRpc3BhdGNoWzFdLCB6OiBkaXNwYXRjaFsyXSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5LCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIGdldE1heENvbXBvbmVudHMsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZSxcbiAgVW5pZm9ybXNBcnJheVR5cGUsXG59IGZyb20gJy4vY29tbW9uJztcbmltcG9ydCB7IENvbnZBdHRyaWJ1dGVzIH0gZnJvbSAnLi9jb252JztcbmltcG9ydCB7IGFwcGVuZEFjdGl2YXRpb25Vbmlmb3JtcywgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zRGF0YSwgZ2V0QWN0aXZhdGlvblNuaXBwZXQgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuXG4vKipcbiAqIG5haXZlIGdyb3VwZWQgY29udiBpbXBsZW1lbnRhdGlvbiwgc3VwcG9ydHMgMWQvMmQgY29udlxuICogQHBhcmFtIHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uIC0gYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gc3F1ZWV6ZSB0aGUgb3V0cHV0IHNoYXBlLCBvbmx5IHVzZWQgaW4gY29udjFkXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVHcm91cGVkQ29udlByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24/OiAoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKSA9PiBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPiAyO1xuICBjb25zdCBwcm9jZXNzQmlhcyA9IGhhc0JpYXMgPyAndmFsdWUgKz0gYltvdXRwdXRfY2hhbm5lbF07JyA6ICcnO1xuICBjb25zdCB4U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qgd1NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG5cbiAgY29uc3QgaXNDaGFubmVsTGFzdCA9IGF0dHJpYnV0ZXMuZm9ybWF0ID09PSAnTkhXQyc7XG4gIGNvbnN0IG91dHB1dENoYW5uZWxzID0gaXNDaGFubmVsTGFzdCA/IG91dHB1dFNoYXBlWzNdIDogb3V0cHV0U2hhcGVbMV07XG4gIGNvbnN0IG91dHB1dENoYW5uZWxzUGVyR3JvdXAgPSBvdXRwdXRDaGFubmVscyAvIGF0dHJpYnV0ZXMuZ3JvdXA7XG4gIGNvbnN0IGNvbXBvbmVudHMgPSBpc0NoYW5uZWxMYXN0ICYmIG91dHB1dENoYW5uZWxzUGVyR3JvdXAgPj0gNCA/IGdldE1heENvbXBvbmVudHMob3V0cHV0Q2hhbm5lbHMpIDogMTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKSAvIGNvbXBvbmVudHM7XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGF0dHJpYnV0ZXMuZGlsYXRpb25zIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IFthdHRyaWJ1dGVzLnN0cmlkZXNbMF0sIGF0dHJpYnV0ZXMuc3RyaWRlc1sxXV0gfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogW2F0dHJpYnV0ZXMucGFkc1swXSwgYXR0cmlidXRlcy5wYWRzWzFdXSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRDaGFubmVsc1Blckdyb3VwIH0sXG4gIF07XG4gIGFwcGVuZEFjdGl2YXRpb25Vbmlmb3Jtc0RhdGEoYXR0cmlidXRlcywgcHJvZ3JhbVVuaWZvcm1zKTtcbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goXG4gICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoeFNoYXBlLCBbd1NoYXBlWzBdLCB3U2hhcGVbMV0sIHdTaGFwZVsyXSwgd1NoYXBlWzNdIC8gY29tcG9uZW50c10pLFxuICApO1xuICBjb25zdCBpbnB1dERlcGVuZGVuY2llczogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXSA9IGhhc0JpYXMgPyBbJ3JhbmsnLCAncmFuaycsICdyYW5rJ10gOiBbJ3JhbmsnLCAncmFuayddO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaChcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhbb3V0cHV0U2hhcGVbMF0sIG91dHB1dFNoYXBlWzFdLCBvdXRwdXRTaGFwZVsyXSwgb3V0cHV0U2hhcGVbM10gLyBjb21wb25lbnRzXSksXG4gICk7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBiYXNlVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZShvdXRwdXQudHlwZS50ZW5zb3IpO1xuICAgIGNvbnN0IGFwcGx5QWN0aXZhdGlvbiA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXMsIG91dHB1dC50eXBlLnZhbHVlLCBiYXNlVHlwZSk7XG4gICAgY29uc3QgeCA9IGlucHV0VmFyaWFibGUoJ3gnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIHhTaGFwZS5sZW5ndGgpO1xuICAgIGNvbnN0IHcgPSBpbnB1dFZhcmlhYmxlKCd3JywgaW5wdXRzWzFdLmRhdGFUeXBlLCB3U2hhcGUubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBpbnB1dFZhcnMgPSBbeCwgd107XG4gICAgaWYgKGhhc0JpYXMpIHtcbiAgICAgIGlucHV0VmFycy5wdXNoKGlucHV0VmFyaWFibGUoJ2InLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLCBjb21wb25lbnRzKSk7XG4gICAgfVxuXG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnZGlsYXRpb25zJywgdHlwZTogJ3UzMicsIGxlbmd0aDogYXR0cmlidXRlcy5kaWxhdGlvbnMubGVuZ3RoIH0sXG4gICAgICB7IG5hbWU6ICdzdHJpZGVzJywgdHlwZTogJ3UzMicsIGxlbmd0aDogMiB9LFxuICAgICAgeyBuYW1lOiAncGFkcycsIHR5cGU6ICd1MzInLCBsZW5ndGg6IDIgfSxcbiAgICAgIHsgbmFtZTogJ291dHB1dF9jaGFubmVsc19wZXJfZ3JvdXAnLCB0eXBlOiAndTMyJyB9LFxuICAgIF07XG4gICAgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zKGF0dHJpYnV0ZXMsIHVuaWZvcm1zKTtcblxuICAgIGNvbnN0IGNhbGN1bGF0ZVJlc3VsdCA9IGlzQ2hhbm5lbExhc3RcbiAgICAgID8gYFxuICAgICAgZm9yICh2YXIgd0hlaWdodDogdTMyID0gMHU7IHdIZWlnaHQgPCB1bmlmb3Jtcy53X3NoYXBlWzBdOyB3SGVpZ2h0KyspIHtcbiAgICAgICAgbGV0IHhIZWlnaHQgPSB4UkNDb3JuZXIueCArIHdIZWlnaHQgKiB1bmlmb3Jtcy5kaWxhdGlvbnNbMF07XG5cbiAgICAgICAgaWYgKHhIZWlnaHQgPCAwdSB8fCB4SGVpZ2h0ID49IHVuaWZvcm1zLnhfc2hhcGVbMV0pIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAodmFyIHdXaWR0aDogdTMyID0gMHU7IHdXaWR0aCA8IHVuaWZvcm1zLndfc2hhcGVbMV07IHdXaWR0aCsrKSB7XG4gICAgICAgICAgbGV0IHhXaWR0aCA9IHhSQ0Nvcm5lci55ICsgd1dpZHRoICogdW5pZm9ybXMuZGlsYXRpb25zWzFdO1xuICAgICAgICAgIGlmICh4V2lkdGggPCAwdSB8fCB4V2lkdGggPj0gdW5pZm9ybXMueF9zaGFwZVsyXSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yICh2YXIgd0luQ2hhbm5lbDogdTMyID0gMHU7IHdJbkNoYW5uZWwgPCB1bmlmb3Jtcy53X3NoYXBlWzJdOyB3SW5DaGFubmVsKyspIHtcbiAgICAgICAgICAgIGxldCBpbnB1dF9jaGFubmVsID0gaW5fY2hhbm5lbF9vZmZzZXQgKyB3SW5DaGFubmVsO1xuICAgICAgICAgICAgbGV0IHhWYWwgPSAke3guZ2V0KCdiYXRjaCcsICd4SGVpZ2h0JywgJ3hXaWR0aCcsICdpbnB1dF9jaGFubmVsJyl9O1xuICAgICAgICAgICAgbGV0IHdWYWwgPSAke3cuZ2V0KCd3SGVpZ2h0JywgJ3dXaWR0aCcsICd3SW5DaGFubmVsJywgJ291dHB1dF9jaGFubmVsJyl9O1xuICAgICAgICAgICAgdmFsdWUgKz0geFZhbCAqIHdWYWw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBgXG4gICAgICA6IGBcbiAgICAgIGZvciAodmFyIHdJbkNoYW5uZWw6IHUzMiA9IDB1OyB3SW5DaGFubmVsIDwgdW5pZm9ybXMud19zaGFwZVsxXTsgd0luQ2hhbm5lbCsrKSB7XG4gICAgICAgIGxldCBpbnB1dF9jaGFubmVsID0gaW5fY2hhbm5lbF9vZmZzZXQgKyB3SW5DaGFubmVsO1xuICAgICAgICBmb3IgKHZhciB3SGVpZ2h0OiB1MzIgPSAwdTsgd0hlaWdodCA8IHVuaWZvcm1zLndfc2hhcGVbMl07IHdIZWlnaHQrKykge1xuICAgICAgICAgIGxldCB4SGVpZ2h0ID0geFJDQ29ybmVyLnggKyB3SGVpZ2h0ICogdW5pZm9ybXMuZGlsYXRpb25zWzBdO1xuXG4gICAgICAgICAgaWYgKHhIZWlnaHQgPCAwdSB8fCB4SGVpZ2h0ID49IHVuaWZvcm1zLnhfc2hhcGVbMl0pIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZvciAodmFyIHdXaWR0aDogdTMyID0gMHU7IHdXaWR0aCA8IHVuaWZvcm1zLndfc2hhcGVbM107IHdXaWR0aCsrKSB7XG4gICAgICAgICAgICBsZXQgeFdpZHRoID0geFJDQ29ybmVyLnkgKyB3V2lkdGggKiB1bmlmb3Jtcy5kaWxhdGlvbnNbMV07XG4gICAgICAgICAgICBpZiAoeFdpZHRoIDwgMHUgfHwgeFdpZHRoID49IHVuaWZvcm1zLnhfc2hhcGVbM10pIHtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCB4VmFsID0gJHt4LmdldCgnYmF0Y2gnLCAnaW5wdXRfY2hhbm5lbCcsICd4SGVpZ2h0JywgJ3hXaWR0aCcpfTtcbiAgICAgICAgICAgIGxldCB3VmFsID0gJHt3LmdldCgnb3V0cHV0X2NoYW5uZWwnLCAnd0luQ2hhbm5lbCcsICd3SGVpZ2h0JywgJ3dXaWR0aCcpfTtcbiAgICAgICAgICAgIHZhbHVlICs9IHhWYWwgKiB3VmFsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKC4uLmlucHV0VmFycywgb3V0cHV0KX1cblxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRfc2l6ZScpfVxuXG4gICAgbGV0IG91dHB1dEluZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG4gICAgbGV0IGJhdGNoOiB1MzIgPSBvdXRwdXRJbmRpY2VzWzBdO1xuICAgIGxldCBvdXRwdXRfY2hhbm5lbDogdTMyID0gb3V0cHV0SW5kaWNlc1ske2lzQ2hhbm5lbExhc3QgPyAzIDogMX1dO1xuICAgIGxldCB4UkNDb3JuZXI6IHZlYzI8dTMyPiA9IHZlYzI8dTMyPihvdXRwdXRJbmRpY2VzWyR7aXNDaGFubmVsTGFzdCA/IDEgOiAyfV0sIG91dHB1dEluZGljZXNbJHtcbiAgICAgIGlzQ2hhbm5lbExhc3QgPyAyIDogM1xuICAgIH1dKSAqIHVuaWZvcm1zLnN0cmlkZXMgLSB1bmlmb3Jtcy5wYWRzO1xuICAgIGxldCBncm91cF9pZDogdTMyID0gb3V0cHV0X2NoYW5uZWwgKiAke2NvbXBvbmVudHN9IC8gdW5pZm9ybXMub3V0cHV0X2NoYW5uZWxzX3Blcl9ncm91cDtcbiAgICB2YXIgaW5fY2hhbm5lbF9vZmZzZXQgPSBncm91cF9pZCAqIHVuaWZvcm1zLndfc2hhcGVbJHtpc0NoYW5uZWxMYXN0ID8gMiA6IDF9XTtcblxuICAgIHZhciB2YWx1ZTogJHtvdXRwdXQudHlwZS52YWx1ZX0gPSAke291dHB1dC50eXBlLnZhbHVlfSgwKTtcbiAgICAke2NhbGN1bGF0ZVJlc3VsdH1cbiAgICAke3Byb2Nlc3NCaWFzfVxuICAgICR7YXBwbHlBY3RpdmF0aW9ufVxuICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ3ZhbHVlJyl9XG4gIH1gO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdHcm91cGVkQ29udicsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX1fJHtjb21wb25lbnRzfWAsIGlucHV0RGVwZW5kZW5jaWVzIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGRpbXM6IHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uID8gc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24ob3V0cHV0U2hhcGUpIDogb3V0cHV0U2hhcGUsXG4gICAgICAgICAgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUdyb3VwZWRDb252VmVjdG9yaXplUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbj86IChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pID0+IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gIGNvbnN0IGNvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKG91dHB1dFNoYXBlWzNdKTtcbiAgY29uc3Qgb3V0cHV0TnVtYmVyID0gZ2V0TWF4Q29tcG9uZW50cyhvdXRwdXRTaGFwZVsyXSk7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSkgLyBjb21wb25lbnRzIC8gb3V0cHV0TnVtYmVyO1xuICBjb25zdCB4U2hhcGUgPSBbaW5wdXRzWzBdLmRpbXNbMF0sIGlucHV0c1swXS5kaW1zWzFdLCBpbnB1dHNbMF0uZGltc1syXSwgaW5wdXRzWzBdLmRpbXNbM10gLyBjb21wb25lbnRzXTtcbiAgY29uc3Qgd1NoYXBlID0gW2lucHV0c1sxXS5kaW1zWzBdLCBpbnB1dHNbMV0uZGltc1sxXSwgaW5wdXRzWzFdLmRpbXNbMl0sIGlucHV0c1sxXS5kaW1zWzNdIC8gY29tcG9uZW50c107XG4gIGNvbnN0IG91dHB1dFNoYXBlSW5TaGFkZXIgPSBbb3V0cHV0U2hhcGVbMF0sIG91dHB1dFNoYXBlWzFdLCBvdXRwdXRTaGFwZVsyXSwgb3V0cHV0U2hhcGVbM10gLyBjb21wb25lbnRzXTtcblxuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmludDMyLCBkYXRhOiBbYXR0cmlidXRlcy5zdHJpZGVzWzBdLCBhdHRyaWJ1dGVzLnN0cmlkZXNbMV1dIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS5pbnQzMiwgZGF0YTogW2F0dHJpYnV0ZXMucGFkc1swXSwgYXR0cmlidXRlcy5wYWRzWzFdXSB9LFxuICBdO1xuICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXNEYXRhKGF0dHJpYnV0ZXMsIHByb2dyYW1Vbmlmb3Jtcyk7XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKHhTaGFwZSwgd1NoYXBlLCBvdXRwdXRTaGFwZUluU2hhZGVyKSk7XG4gIGNvbnN0IHhOdW1iZXIgPSAob3V0cHV0TnVtYmVyIC0gMSkgKiBhdHRyaWJ1dGVzLnN0cmlkZXNbMV0gKyB3U2hhcGVbMV07XG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlSW5TaGFkZXIubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBiYXNlVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZShvdXRwdXQudHlwZS50ZW5zb3IpO1xuICAgIGNvbnN0IGFwcGx5QWN0aXZhdGlvbiA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXMsIG91dHB1dC50eXBlLnZhbHVlLCBiYXNlVHlwZSk7XG4gICAgY29uc3QgeCA9IGlucHV0VmFyaWFibGUoJ3gnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIHhTaGFwZS5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IHcgPSBpbnB1dFZhcmlhYmxlKCd3JywgaW5wdXRzWzFdLmRhdGFUeXBlLCB3U2hhcGUubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBpbnB1dFZhcnMgPSBbeCwgd107XG4gICAgaWYgKGhhc0JpYXMpIHtcbiAgICAgIGlucHV0VmFycy5wdXNoKGlucHV0VmFyaWFibGUoJ2InLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLCBjb21wb25lbnRzKSk7XG4gICAgfVxuICAgIGNvbnN0IHByb2Nlc3NCaWFzID0gaGFzQmlhcyA/ICd2YWx1ZSArPSBiW291dHB1dF9jaGFubmVsXTsnIDogJyc7XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnc3RyaWRlcycsIHR5cGU6ICdpMzInLCBsZW5ndGg6IDIgfSxcbiAgICAgIHsgbmFtZTogJ3BhZHMnLCB0eXBlOiAnaTMyJywgbGVuZ3RoOiAyIH0sXG4gICAgXTtcbiAgICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXMoYXR0cmlidXRlcywgdW5pZm9ybXMpO1xuICAgIHJldHVybiBgXG4gICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJzLCBvdXRwdXQpfVxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRfc2l6ZScpfVxuICAgIGxldCB3aWR0aDAgPSB1bmlmb3Jtcy5vdXRwdXRfc2hhcGVbM107XG4gICAgbGV0IG91dHB1dF9jaGFubmVsID0gZ2xvYmFsX2lkeCAlIHdpZHRoMDtcbiAgICB2YXIgaW5kZXgxID0gZ2xvYmFsX2lkeCAvIHdpZHRoMDtcbiAgICBsZXQgd2lkdGgxID0gdW5pZm9ybXMub3V0cHV0X3NoYXBlWzJdIC8gJHtvdXRwdXROdW1iZXJ9dTtcbiAgICBsZXQgY29sID0gKGluZGV4MSAlIHdpZHRoMSkgKiAke291dHB1dE51bWJlcn11O1xuICAgIGluZGV4MSA9IGluZGV4MSAvIHdpZHRoMTtcbiAgICBsZXQgcm93ID0gaW5kZXgxICUgdW5pZm9ybXMub3V0cHV0X3NoYXBlWzFdO1xuICAgIGxldCBiYXRjaCA9IGluZGV4MSAvIHVuaWZvcm1zLm91dHB1dF9zaGFwZVsxXTtcblxuICAgIGxldCB4X2Nvcm5lciA9IHZlYzI8aTMyPihpMzIocm93KSwgaTMyKGNvbCkpICogdW5pZm9ybXMuc3RyaWRlcyAtIHVuaWZvcm1zLnBhZHM7XG5cbiAgICB2YXIgeF92YWxzOiBhcnJheTwke3gudHlwZS52YWx1ZX0sICR7eE51bWJlcn0+O1xuICAgIHZhciB2YWx1ZXM6IGFycmF5PCR7b3V0cHV0LnR5cGUudmFsdWV9LCAke291dHB1dE51bWJlcn0+O1xuICAgIGxldCBpbnB1dF9jaGFubmVsID0gb3V0cHV0X2NoYW5uZWw7XG4gICAgLy8gVXNlIGNvbnN0YW50IGluc3RlYWQgb2YgdW5pZm9ybSBjYW4gZ2l2ZSBiZXR0ZXIgcGVyZm9ybWFuY2UgZm9yIHcncyBoZWlnaHQvd2lkdGguXG4gICAgZm9yICh2YXIgd19oZWlnaHQ6IHUzMiA9IDB1OyB3X2hlaWdodCA8ICR7d1NoYXBlWzBdfTsgd19oZWlnaHQrKykge1xuICAgICAgbGV0IHhfaGVpZ2h0ID0geF9jb3JuZXIueCArIGkzMih3X2hlaWdodCk7XG4gICAgICBpZiAoeF9oZWlnaHQgPj0gMCAmJiB1MzIoeF9oZWlnaHQpIDwgdW5pZm9ybXMueF9zaGFwZVsxXSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8ICR7eE51bWJlcn07IGkrKykge1xuICAgICAgICAgIGxldCB4X3dpZHRoID0geF9jb3JuZXIueSArIGk7XG4gICAgICAgICAgaWYgKHhfd2lkdGggPj0gMCAmJiB1MzIoeF93aWR0aCkgPCB1bmlmb3Jtcy54X3NoYXBlWzJdKSB7XG4gICAgICAgICAgICB4X3ZhbHNbaV0gPSAke3guZ2V0KCdiYXRjaCcsICd1MzIoeF9oZWlnaHQpJywgJ3UzMih4X3dpZHRoKScsICdpbnB1dF9jaGFubmVsJyl9O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB4X3ZhbHNbaV0gPSAke3gudHlwZS52YWx1ZX0oMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIHdfd2lkdGg6IHUzMiA9IDB1OyB3X3dpZHRoIDwgJHt3U2hhcGVbMV19OyB3X3dpZHRoKyspIHtcbiAgICAgICAgICBsZXQgd192YWwgPSAke3cuZ2V0KCd3X2hlaWdodCcsICd3X3dpZHRoJywgJzAnLCAnb3V0cHV0X2NoYW5uZWwnKX07XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDB1OyBpIDwgJHtvdXRwdXROdW1iZXJ9dTsgaSsrKSB7XG4gICAgICAgICAgICB2YWx1ZXNbaV0gPSBmbWEoeF92YWxzW2kgKiB1MzIodW5pZm9ybXMuc3RyaWRlc1sxXSkgKyB3X3dpZHRoXSwgd192YWwsIHZhbHVlc1tpXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDB1OyBpIDwgJHtvdXRwdXROdW1iZXJ9dTsgaSsrKSB7XG4gICAgICB2YXIgdmFsdWUgPSB2YWx1ZXNbaV07XG4gICAgICAke3Byb2Nlc3NCaWFzfVxuICAgICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgICAke291dHB1dC5zZXQoJ2JhdGNoJywgJ3JvdycsICdjb2wgKyBpJywgJ291dHB1dF9jaGFubmVsJywgJ3ZhbHVlJyl9O1xuICAgIH1cbiAgfWA7XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnR3JvdXBlZENvbnYtVmVjdG9yaXplJyxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX07JHtjb21wb25lbnRzfTske291dHB1dE51bWJlcn07JHt4TnVtYmVyfTske3dTaGFwZVswXX07JHt3U2hhcGVbMV19YCxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzOiBoYXNCaWFzID8gWydyYW5rJywgJ3JhbmsnLCAndHlwZSddIDogWydyYW5rJywgJ3JhbmsnXSxcbiAgICB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBkaW1zOiBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbiA/IHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uKG91dHB1dFNoYXBlKSA6IG91dHB1dFNoYXBlLFxuICAgICAgICAgIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBQb29sQ29udlV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgY3JlYXRlQ29udjJETWF0TXVsUHJvZ3JhbUluZm8gfSBmcm9tICcuLzNyZC1wYXJ0eS9jb252MmRfbW1fd2ViZ3B1JztcbmltcG9ydCB7IGNvbXB1dGVDb252M0RJbmZvLCBjcmVhdGVDb252M0ROYWl2ZVByb2dyYW1JbmZvIH0gZnJvbSAnLi8zcmQtcGFydHkvY29udjNkX25haXZlX3dlYmdwdSc7XG5pbXBvcnQgeyBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mbyB9IGZyb20gJy4vM3JkLXBhcnR5L21hdG11bF9wYWNrZWRfd2ViZ3B1JztcbmltcG9ydCB7IGNyZWF0ZUdyb3VwZWRDb252UHJvZ3JhbUluZm8sIGNyZWF0ZUdyb3VwZWRDb252VmVjdG9yaXplUHJvZ3JhbUluZm8gfSBmcm9tICcuL2NvbnYtZ3JvdXBlZCc7XG5pbXBvcnQgeyBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLCBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuaW1wb3J0IHsgY3JlYXRlTmFpdmVNYXRtdWxQcm9ncmFtSW5mbyB9IGZyb20gJy4vbWF0bXVsLXNoYWRlcnMnO1xuaW1wb3J0IHsgY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8gfSBmcm9tICcuL3RyYW5zcG9zZSc7XG5cbmV4cG9ydCBjb25zdCBjYWxjdWxhdGVPdXRwdXRTaGFwZSA9IChcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXSxcbiAgYWRqdXN0UGFkczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBpc0NoYW5uZWxMYXN0OiBib29sZWFuLFxuKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCBiYXRjaFNpemUgPSBpbnB1dFNoYXBlWzBdO1xuICBjb25zdCBpbnB1dFNwYXRpYWxTaGFwZSA9IGlucHV0U2hhcGUuc2xpY2UoaXNDaGFubmVsTGFzdCA/IDEgOiAyLCBpc0NoYW5uZWxMYXN0ID8gMyA6IDQpO1xuICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0U3BhdGlhbFNoYXBlLmxlbmd0aDtcbiAgY29uc3Qgb3V0Q2hhbm5lbHMgPSBrZXJuZWxTaGFwZVswXTtcbiAgY29uc3Qga2VybmVsU3BhdGlhbFNoYXBlID0ga2VybmVsU2hhcGUuc2xpY2UoMik7XG4gIGNvbnN0IGRpbGF0ZWRLZXJuZWxTaGFwZSA9IGtlcm5lbFNwYXRpYWxTaGFwZS5tYXAoKHYsIGkpID0+IHYgKyAodiAtIDEpICogKGRpbGF0aW9uc1tpXSAtIDEpKTtcbiAgY29uc3QgaW5wdXRTcGF0aWFsU2hhcGVXaXRoUGFkID0gaW5wdXRTcGF0aWFsU2hhcGUubWFwKCh2LCBpKSA9PiB2ICsgYWRqdXN0UGFkc1tpXSArIGFkanVzdFBhZHNbaSArIHNwYXRpYWxSYW5rXSk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRTcGF0aWFsU2hhcGVXaXRoUGFkLm1hcCgodiwgaSkgPT5cbiAgICBNYXRoLmZsb29yKCh2IC0gZGlsYXRlZEtlcm5lbFNoYXBlW2ldICsgc3RyaWRlc1tpXSkgLyBzdHJpZGVzW2ldKSxcbiAgKTtcbiAgb3V0cHV0U2hhcGUuc3BsaWNlKDAsIDAsIGJhdGNoU2l6ZSk7XG4gIG91dHB1dFNoYXBlLnNwbGljZShpc0NoYW5uZWxMYXN0ID8gMyA6IDEsIDAsIG91dENoYW5uZWxzKTtcbiAgcmV0dXJuIG91dHB1dFNoYXBlO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBDb252QXR0cmlidXRlcyBleHRlbmRzIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF1dG9QYWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgZm9ybWF0OiAnTkhXQycgfCAnTkNIVyc7XG4gIHJlYWRvbmx5IGdyb3VwOiBudW1iZXI7XG4gIHJlYWRvbmx5IGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgcGFkczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSB3SXNDb25zdDogYm9vbGVhbjtcbn1cblxuLy8gZm9yIHRyYW5zcG9zaW5nIHdlaWdodCB0ZW5zb3IgZnJvbSBbTSwgQy9ncm91cCwgS0gsIEtXXSB0byBbS0gsIEtXLCBDL2dyb3VwLCBNXVxuY29uc3Qgd2VpZ2h0VHJhbnNwb3NlQXR0cmlidXRlID0gWzIsIDMsIDEsIDBdO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgLy8gUmVmZXIgdG8gdGhlIGJlbG93IGxpbmsgZm9yIGFsbCBpbnB1dCBjaGVja3NcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21hc3Rlci9kb2NzL09wZXJhdG9ycy5tZCNDb252XG4gIGlmICghaW5wdXRzIHx8IChpbnB1dHMubGVuZ3RoICE9PSAyICYmIGlucHV0cy5sZW5ndGggIT09IDMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252IHJlcXVpcmVzIDIgb3IgMyBpbnB1dHMnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggPiA1KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdncmVhdGVyIHRoYW4gNUQgaXMgbm90IHN1cHBvcnRlZCcpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdmaWx0ZXIgZG9lcyBub3QgaGF2ZSBzYW1lIGRpbWVuc2lvbiBhcyBpbnB1dCcpO1xuICB9XG5cbiAgLy8gRklMVEVSX0lOX0NIQU5ORUwgc2hvdWxkIGJlIGVxdWFsIHRvIERBVEFfQ0hBTk5FTFxuICBjb25zdCBkYXRhQ2hhbm5lbCA9IGlucHV0c1swXS5kaW1zW2F0dHJpYnV0ZXMuZm9ybWF0ID09PSAnTkhXQycgPyBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAxIDogMV07XG4gIGNvbnN0IGZpbHRlckluQ2hhbm5lbCA9IGlucHV0c1sxXS5kaW1zWzFdICogYXR0cmlidXRlcy5ncm91cDtcbiAgaWYgKGRhdGFDaGFubmVsICE9PSBmaWx0ZXJJbkNoYW5uZWwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUwnKTtcbiAgfVxuXG4gIC8vIGlmIGJpYXMgaXMgcHJvdmlkZWQgaXQgc2hvdWxkIGJlIDFEIGFuZCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHNob3VsZCBiZSBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGZlYXR1cmUgbWFwc1xuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiAoaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAxIHx8IGlucHV0c1sxXS5kaW1zWzBdICE9PSBpbnB1dHNbMl0uZGltc1swXSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYmlhcycpO1xuICB9XG5cbiAgY29uc3Qgc3BhdGlhbFJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAyO1xuICAvLyB3cm9uZyBkaWxhdGlvbnMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLmRpbGF0aW9ucy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBkaWxhdGlvbnMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3Jvbmcgc3RyaWRlcyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBzdHJpZGVzIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIHBhZHMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoICE9PSBzcGF0aWFsUmFuayAqIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHBhZHMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmsgKiAyfURgKTtcbiAgfVxuXG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIHNwZWNpZmllZCwgaXQncyBkYXRhIGxlbmd0aCBtdXN0IGJlIDIgbGVzcyB0aGFuIGRpbXMgbGVuZ3RoIG9mIHRoZSB3ZWlnaHRzIHRlbnNvclxuICAvLyAodGhlIGZpcnN0IDIgZGltcyBhcmUgYmF0Y2hfc2l6ZSBhbmQgY2hhbm5lbHMpXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gMCAmJiBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBrZXJuZWwgc2hhcGUnKTtcbiAgfVxufTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRDb252QXR0cmlidXRlcyA9IDxUIGV4dGVuZHMgQ29udkF0dHJpYnV0ZXM+KGF0dHJpYnV0ZXM6IFQsIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogVCA9PiB7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5zbGljZSgpO1xuICAvLyBpZiBrZXJuZWxTaGFwZSBpcyBub3Qgd2VsbCBzcGVjaWZpZWQgaW4gdGhlIGF0dHJpYnV0ZXMsIGluZmVyIGl0IGZyb20gdGhlIHdlaWdodCB0ZW5zb3IgZGltc1xuICBpZiAoa2VybmVsU2hhcGUubGVuZ3RoIDwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMikge1xuICAgIGtlcm5lbFNoYXBlLnB1c2goLi4uQXJyYXkoaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMiAtIGtlcm5lbFNoYXBlLmxlbmd0aCkuZmlsbCgwKSk7XG4gIH1cbiAgZm9yIChsZXQgaSA9IDI7IGkgPCBpbnB1dHNbMV0uZGltcy5sZW5ndGg7ICsraSkge1xuICAgIGlmIChrZXJuZWxTaGFwZVtpIC0gMl0gPT09IDApIHtcbiAgICAgIGtlcm5lbFNoYXBlW2kgLSAyXSA9IGlucHV0c1sxXS5kaW1zW2ldO1xuICAgIH1cbiAgfVxuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5wYWRzLnNsaWNlKCk7XG4gIFBvb2xDb252VXRpbC5hZGp1c3RQYWRzQmFzZWRPbkF1dG9QYWQoXG4gICAgaW5wdXRzWzBdLmRpbXMsXG4gICAgYXR0cmlidXRlcy5zdHJpZGVzLFxuICAgIGF0dHJpYnV0ZXMuZGlsYXRpb25zLFxuICAgIGtlcm5lbFNoYXBlLFxuICAgIHBhZHMsXG4gICAgYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJyxcbiAgICBhdHRyaWJ1dGVzLmF1dG9QYWQsXG4gICk7XG5cbiAgLy8gYWx3YXlzIHJldHVybiBhIG5ldyBvYmplY3Qgc28gZG9lcyBub3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCBhdHRyaWJ1dGVzXG4gIGNvbnN0IG5ld0F0dHJpYnV0ZXM6IFQgPSBPYmplY3QuYXNzaWduKHt9LCBhdHRyaWJ1dGVzKTtcbiAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7IGtlcm5lbFNoYXBlLCBwYWRzIH0pO1xuICByZXR1cm4gbmV3QXR0cmlidXRlcztcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNvbnZBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogQ29udkF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhY3RpdmF0aW9uQXR0cmlidXRlcyA9IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTtcbiAgLy8gVE9ETyA6IE1ha2UgdGhpcyBnZW5lcmljIGVub3VnaCB0byBjb21wdXRlIGRlZmF1bHQgYXR0cmlidXRlcyBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICBjb25zdCBmb3JtYXQgPSBhdHRyaWJ1dGVzLmZvcm1hdCBhcyAnTkhXQycgfCAnTkNIVyc7XG4gIGNvbnN0IGF1dG9QYWQgPSBbJ05PVFNFVCcsICdWQUxJRCcsICdTQU1FX1VQUEVSJywgJ1NBTUVfTE9XRVInXVthdHRyaWJ1dGVzLmF1dG9fcGFkIGFzIG51bWJlcl07XG4gIGNvbnN0IGRpbGF0aW9ucyA9IGF0dHJpYnV0ZXMuZGlsYXRpb25zIGFzIG51bWJlcltdO1xuICBjb25zdCBncm91cCA9IGF0dHJpYnV0ZXMuZ3JvdXAgYXMgbnVtYmVyO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMua2VybmVsX3NoYXBlIGFzIG51bWJlcltdO1xuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5wYWRzIGFzIG51bWJlcltdO1xuICBjb25zdCBzdHJpZGVzID0gYXR0cmlidXRlcy5zdHJpZGVzIGFzIG51bWJlcltdO1xuICBjb25zdCB3SXNDb25zdCA9IChhdHRyaWJ1dGVzLndfaXNfY29uc3QgYXMgKCkgPT4gYm9vbGVhbikoKTtcblxuICByZXR1cm4ge1xuICAgIGF1dG9QYWQsXG4gICAgZm9ybWF0LFxuICAgIGRpbGF0aW9ucyxcbiAgICBncm91cCxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBwYWRzLFxuICAgIHN0cmlkZXMsXG4gICAgd0lzQ29uc3QsXG4gICAgLi4uYWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4gICAgY2FjaGVLZXk6IGAke2F0dHJpYnV0ZXMuZm9ybWF0fTske2FjdGl2YXRpb25BdHRyaWJ1dGVzLmFjdGl2YXRpb259O2AsXG4gIH07XG59O1xuXG5jb25zdCBjb252MmQgPSAoXG4gIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4gIHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uPzogKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSkgPT4gbnVtYmVyW10sXG4pOiB2b2lkID0+IHtcbiAgLy8gY2hlY2sgYXR0cmlidXRlc1xuXG4gIC8vIGNvbnN0IGhhc1ByZWx1QWN0aXZhdGlvbldlaWdodHMgPSBmYWxzZTsgLyogVE9ETzogYWRkIHN1cHBvcnQgZm9yIHByZWx1IGFjdGl2YXRpb24gd2VpZ2h0cyAqL1xuICBjb25zdCBpc0NoYW5uZWxzTGFzdCA9IGF0dHJpYnV0ZXMuZm9ybWF0ID09PSAnTkhXQyc7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gY2FsY3VsYXRlT3V0cHV0U2hhcGUoXG4gICAgaW5wdXRzWzBdLmRpbXMsXG4gICAgaW5wdXRzWzFdLmRpbXMsXG4gICAgYXR0cmlidXRlcy5kaWxhdGlvbnMsXG4gICAgYXR0cmlidXRlcy5wYWRzLFxuICAgIGF0dHJpYnV0ZXMuc3RyaWRlcyxcbiAgICBpc0NoYW5uZWxzTGFzdCxcbiAgKTtcbiAgaWYgKGF0dHJpYnV0ZXMuZ3JvdXAgIT09IDEpIHtcbiAgICBjb25zdCBjb252SW5wdXRzID0gW2lucHV0c1swXV07XG4gICAgaWYgKGlzQ2hhbm5lbHNMYXN0KSB7XG4gICAgICBjb25zdCB0cmFuc3Bvc2VkV2VpZ2h0ID1cbiAgICAgICAgKGNvbnRleHQua2VybmVsQ3VzdG9tRGF0YS53VCBhcyBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkKSA/P1xuICAgICAgICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8oaW5wdXRzWzFdLCB3ZWlnaHRUcmFuc3Bvc2VBdHRyaWJ1dGUpLCB7XG4gICAgICAgICAgaW5wdXRzOiBbMV0sXG4gICAgICAgICAgb3V0cHV0czogW2F0dHJpYnV0ZXMud0lzQ29uc3QgPyAtMiA6IC0xXSxcbiAgICAgICAgfSlbMF07XG4gICAgICBpZiAoYXR0cmlidXRlcy53SXNDb25zdCAmJiAhY29udGV4dC5rZXJuZWxDdXN0b21EYXRhLndUKSB7XG4gICAgICAgIGNvbnRleHQua2VybmVsQ3VzdG9tRGF0YS53VCA9IHRyYW5zcG9zZWRXZWlnaHQ7XG4gICAgICB9XG4gICAgICBjb252SW5wdXRzLnB1c2godHJhbnNwb3NlZFdlaWdodCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnZJbnB1dHMucHVzaChpbnB1dHNbMV0pO1xuICAgIH1cbiAgICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgY29udklucHV0cy5wdXNoKGlucHV0c1syXSk7XG4gICAgfVxuICAgIC8vIE5WSURJQSBHUFUgd2l0aCBhbXBlcmUgYXJjaGl0ZWN0dXJlIGZhaWxzIHdpdGggYmVsb3cgMiBjYXNlcywgYnV0IHdlIGNvdWxkbid0IHJlcHJvIHRoZW0gd2l0aCBhbnkgb3RoZXJcbiAgICAvLyBHUFVzLiBTbyBqdXN0IGRpc2FibGUgdmVjdG9yaXplIG9uIE5WSURJQSBhbXBlcmUgdG8gZW5zdXJlIGFsd2F5cyBjb3JyZWN0IG91dHB1dHMuXG4gICAgLy8gW3dlYmdwdV1Db252IC0gY29udiAtIHZlY3Rvcml6ZSBncm91cCAtIEJcbiAgICAvLyBbd2ViZ3B1XUNvbnYgLSBjb252IC0gdmVjdG9yaXplIGdyb3VwIC0gRFxuICAgIGNvbnN0IGVuYWJsZUdyb3VwZWRDb252VmVjdG9yaXplID0gIWNvbnRleHQuYWRhcHRlckluZm8uaXNBcmNoaXRlY3R1cmUoJ2FtcGVyZScpO1xuICAgIGlmIChcbiAgICAgIGVuYWJsZUdyb3VwZWRDb252VmVjdG9yaXplICYmXG4gICAgICBpc0NoYW5uZWxzTGFzdCAmJlxuICAgICAgaW5wdXRzWzFdLmRpbXNbMF0gPT09IGF0dHJpYnV0ZXMuZ3JvdXAgJiZcbiAgICAgIGlucHV0c1sxXS5kaW1zWzFdID09PSAxICYmXG4gICAgICBhdHRyaWJ1dGVzLmRpbGF0aW9uc1swXSA9PT0gMSAmJlxuICAgICAgYXR0cmlidXRlcy5kaWxhdGlvbnNbMV0gPT09IDFcbiAgICApIHtcbiAgICAgIGNvbnRleHQuY29tcHV0ZShcbiAgICAgICAgY3JlYXRlR3JvdXBlZENvbnZWZWN0b3JpemVQcm9ncmFtSW5mbyhjb252SW5wdXRzLCBhdHRyaWJ1dGVzLCBvdXRwdXRTaGFwZSwgc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24pLFxuICAgICAgICB7IGlucHV0czogY29udklucHV0cyB9LFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUdyb3VwZWRDb252UHJvZ3JhbUluZm8oY29udklucHV0cywgYXR0cmlidXRlcywgb3V0cHV0U2hhcGUsIHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uKSwge1xuICAgICAgICBpbnB1dHM6IGNvbnZJbnB1dHMsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPT09IDM7XG4gIGNvbnN0IGlucHV0SGVpZ2h0ID0gaW5wdXRzWzBdLmRpbXNbaXNDaGFubmVsc0xhc3QgPyAxIDogMl07XG4gIGNvbnN0IGlucHV0V2lkdGggPSBpbnB1dHNbMF0uZGltc1tpc0NoYW5uZWxzTGFzdCA/IDIgOiAzXTtcbiAgY29uc3QgaW5wdXRDaGFubmVscyA9IGlucHV0c1swXS5kaW1zW2lzQ2hhbm5lbHNMYXN0ID8gMyA6IDFdO1xuICBjb25zdCB3ZWlnaHRIZWlnaHQgPSBpbnB1dHNbMV0uZGltc1syXTtcbiAgY29uc3Qgd2VpZ2h0V2lkdGggPSBpbnB1dHNbMV0uZGltc1szXTtcblxuICBjb25zdCBvdXRIZWlnaHQgPSBvdXRwdXRTaGFwZVtpc0NoYW5uZWxzTGFzdCA/IDEgOiAyXTtcbiAgY29uc3Qgb3V0V2lkdGggPSBvdXRwdXRTaGFwZVtpc0NoYW5uZWxzTGFzdCA/IDIgOiAzXTtcbiAgY29uc3Qgb3V0Q2hhbm5lbHMgPSBvdXRwdXRTaGFwZVtpc0NoYW5uZWxzTGFzdCA/IDMgOiAxXTtcblxuICBjb25zdCBzYW1lU2l6ZSA9XG4gICAgaXNDaGFubmVsc0xhc3QgJiZcbiAgICB3ZWlnaHRIZWlnaHQgPT09IGlucHV0SGVpZ2h0ICYmXG4gICAgd2VpZ2h0V2lkdGggPT09IGlucHV0V2lkdGggJiZcbiAgICBhdHRyaWJ1dGVzLnBhZHNbMF0gPT09IDAgJiZcbiAgICBhdHRyaWJ1dGVzLnBhZHNbMV0gPT09IDA7XG4gIGlmIChcbiAgICBzYW1lU2l6ZSB8fFxuICAgICh3ZWlnaHRIZWlnaHQgPT09IDEgJiZcbiAgICAgIHdlaWdodFdpZHRoID09PSAxICYmXG4gICAgICBhdHRyaWJ1dGVzLmRpbGF0aW9uc1swXSA9PT0gMSAmJlxuICAgICAgYXR0cmlidXRlcy5kaWxhdGlvbnNbMV0gPT09IDEgJiZcbiAgICAgIGF0dHJpYnV0ZXMuc3RyaWRlc1swXSA9PT0gMSAmJlxuICAgICAgYXR0cmlidXRlcy5zdHJpZGVzWzFdID09PSAxICYmXG4gICAgICBhdHRyaWJ1dGVzLnBhZHNbMF0gPT09IDAgJiZcbiAgICAgIGF0dHJpYnV0ZXMucGFkc1sxXSA9PT0gMClcbiAgKSB7XG4gICAgLy8gY29udjJkQnlNYXRNdWxcbiAgICBjb25zdCBiYXRjaCA9IG91dHB1dFNoYXBlWzBdO1xuICAgIGxldCB4UmVzaGFwZWQsIHdSZXNoYXBlZCwgbWF0bXVsT3V0cHV0U2hhcGU7XG4gICAgY29uc3QgbWF0bXVsSW5wdXRzID0gW107XG4gICAgaWYgKGlzQ2hhbm5lbHNMYXN0KSB7XG4gICAgICBjb25zdCB0cmFuc3Bvc2VkV2VpZ2h0ID1cbiAgICAgICAgKGNvbnRleHQua2VybmVsQ3VzdG9tRGF0YS53VCBhcyBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkKSA/P1xuICAgICAgICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8oaW5wdXRzWzFdLCB3ZWlnaHRUcmFuc3Bvc2VBdHRyaWJ1dGUpLCB7XG4gICAgICAgICAgaW5wdXRzOiBbMV0sXG4gICAgICAgICAgb3V0cHV0czogW2F0dHJpYnV0ZXMud0lzQ29uc3QgPyAtMiA6IC0xXSxcbiAgICAgICAgfSlbMF07XG4gICAgICBpZiAoYXR0cmlidXRlcy53SXNDb25zdCAmJiAhY29udGV4dC5rZXJuZWxDdXN0b21EYXRhLndUKSB7XG4gICAgICAgIGNvbnRleHQua2VybmVsQ3VzdG9tRGF0YS53VCA9IHRyYW5zcG9zZWRXZWlnaHQ7XG4gICAgICB9XG4gICAgICBpZiAoc2FtZVNpemUpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVkRGltID0gaW5wdXRIZWlnaHQgKiBpbnB1dFdpZHRoICogaW5wdXRDaGFubmVscztcbiAgICAgICAgeFJlc2hhcGVkID0gaW5wdXRzWzBdLnJlc2hhcGUoWzEsIGJhdGNoLCBzaGFyZWREaW1dKTtcbiAgICAgICAgd1Jlc2hhcGVkID0gdHJhbnNwb3NlZFdlaWdodC5yZXNoYXBlKFsxLCBzaGFyZWREaW0sIG91dENoYW5uZWxzXSk7XG4gICAgICAgIG1hdG11bE91dHB1dFNoYXBlID0gWzEsIGJhdGNoLCBvdXRDaGFubmVsc107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB4UmVzaGFwZWQgPSBpbnB1dHNbMF0ucmVzaGFwZShbYmF0Y2gsIGlucHV0SGVpZ2h0ICogaW5wdXRXaWR0aCwgaW5wdXRDaGFubmVsc10pO1xuICAgICAgICB3UmVzaGFwZWQgPSB0cmFuc3Bvc2VkV2VpZ2h0LnJlc2hhcGUoWzEsIGlucHV0Q2hhbm5lbHMsIG91dENoYW5uZWxzXSk7XG4gICAgICAgIG1hdG11bE91dHB1dFNoYXBlID0gW2JhdGNoLCBvdXRIZWlnaHQgKiBvdXRXaWR0aCwgb3V0Q2hhbm5lbHNdO1xuICAgICAgfVxuICAgICAgbWF0bXVsSW5wdXRzLnB1c2goeFJlc2hhcGVkKTtcbiAgICAgIG1hdG11bElucHV0cy5wdXNoKHdSZXNoYXBlZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHhSZXNoYXBlZCA9IGlucHV0c1swXS5yZXNoYXBlKFtiYXRjaCwgaW5wdXRDaGFubmVscywgaW5wdXRIZWlnaHQgKiBpbnB1dFdpZHRoXSk7XG4gICAgICB3UmVzaGFwZWQgPSBpbnB1dHNbMV0ucmVzaGFwZShbMSwgb3V0Q2hhbm5lbHMsIGlucHV0Q2hhbm5lbHNdKTtcbiAgICAgIG1hdG11bE91dHB1dFNoYXBlID0gW2JhdGNoLCBvdXRDaGFubmVscywgb3V0SGVpZ2h0ICogb3V0V2lkdGhdO1xuICAgICAgbWF0bXVsSW5wdXRzLnB1c2god1Jlc2hhcGVkKTtcbiAgICAgIG1hdG11bElucHV0cy5wdXNoKHhSZXNoYXBlZCk7XG4gICAgfVxuICAgIGlmIChoYXNCaWFzKSB7XG4gICAgICBtYXRtdWxJbnB1dHMucHVzaChpbnB1dHNbMl0pO1xuICAgIH1cbiAgICBjb25zdCBOID0gbWF0bXVsT3V0cHV0U2hhcGVbMl07XG4gICAgY29uc3QgSyA9IG1hdG11bElucHV0c1swXS5kaW1zW21hdG11bElucHV0c1swXS5kaW1zLmxlbmd0aCAtIDFdO1xuICAgIC8vIFR1bmUgdGhlIHRocmVzaG9sZC5cbiAgICBpZiAoTiA8IDggJiYgSyA8IDgpIHtcbiAgICAgIGNvbnRleHQuY29tcHV0ZShcbiAgICAgICAgY3JlYXRlTmFpdmVNYXRtdWxQcm9ncmFtSW5mbyhcbiAgICAgICAgICBtYXRtdWxJbnB1dHMsXG4gICAgICAgICAgYXR0cmlidXRlcyxcbiAgICAgICAgICBvdXRwdXRTaGFwZSxcbiAgICAgICAgICBtYXRtdWxPdXRwdXRTaGFwZSxcbiAgICAgICAgICBpc0NoYW5uZWxzTGFzdCxcbiAgICAgICAgICBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbixcbiAgICAgICAgKSxcbiAgICAgICAgeyBpbnB1dHM6IG1hdG11bElucHV0cyB9LFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGV4dC5jb21wdXRlKFxuICAgICAgICBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mbyhcbiAgICAgICAgICBtYXRtdWxJbnB1dHMsXG4gICAgICAgICAgYXR0cmlidXRlcyxcbiAgICAgICAgICBvdXRwdXRTaGFwZSxcbiAgICAgICAgICBtYXRtdWxPdXRwdXRTaGFwZSxcbiAgICAgICAgICBpc0NoYW5uZWxzTGFzdCxcbiAgICAgICAgICBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbixcbiAgICAgICAgKSxcbiAgICAgICAgeyBpbnB1dHM6IG1hdG11bElucHV0cyB9LFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gVE9ETzogaW1wbGVtZW50IGNvbnYyZFdpdGhJbTJDb2woKVxuXG4gIGNvbnN0IHNlcXVlbnRpYWxBY2Nlc3NCeVRocmVhZHMgPSAvKiBiYWNrZW5kLmFkYXB0ZXJJbmZvLmlzSW50ZWwoKSAqLyB0cnVlO1xuXG4gIC8vIFNURVAuMTogdHJhbnNwb3NlIHdlaWdodFxuICBjb25zdCB0cmFuc3Bvc2VkV2VpZ2h0ID1cbiAgICAoY29udGV4dC5rZXJuZWxDdXN0b21EYXRhLndUIGFzIFRlbnNvclZpZXcgfCB1bmRlZmluZWQpID8/XG4gICAgY29udGV4dC5jb21wdXRlKGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvKGlucHV0c1sxXSwgd2VpZ2h0VHJhbnNwb3NlQXR0cmlidXRlKSwge1xuICAgICAgaW5wdXRzOiBbMV0sXG4gICAgICBvdXRwdXRzOiBbYXR0cmlidXRlcy53SXNDb25zdCA/IC0yIDogLTFdLFxuICAgIH0pWzBdO1xuICBpZiAoYXR0cmlidXRlcy53SXNDb25zdCAmJiAhY29udGV4dC5rZXJuZWxDdXN0b21EYXRhLndUKSB7XG4gICAgY29udGV4dC5rZXJuZWxDdXN0b21EYXRhLndUID0gdHJhbnNwb3NlZFdlaWdodDtcbiAgfVxuXG4gIC8vIFNURVAuMjogcHJlcGFyZSByZXNoYXBlZCBpbnB1dHNcbiAgY29uc3QgY29udklucHV0cyA9IFtpbnB1dHNbMF0sIHRyYW5zcG9zZWRXZWlnaHRdO1xuICBpZiAoaGFzQmlhcykge1xuICAgIGNvbnZJbnB1dHMucHVzaChpbnB1dHNbMl0pO1xuICB9XG5cbiAgLy8gU1RFUC4zOiBjb21wdXRlIG1hdG11bFxuICBjb25zdCBkaW1BT3V0ZXIgPSBpc0NoYW5uZWxzTGFzdCA/IG91dEhlaWdodCAqIG91dFdpZHRoIDogb3V0Q2hhbm5lbHM7XG4gIGNvbnN0IGRpbUJPdXRlciA9IGlzQ2hhbm5lbHNMYXN0ID8gb3V0Q2hhbm5lbHMgOiBvdXRIZWlnaHQgKiBvdXRXaWR0aDtcbiAgY29uc3QgZGltSW5uZXIgPSB3ZWlnaHRIZWlnaHQgKiB3ZWlnaHRXaWR0aCAqIGlucHV0Q2hhbm5lbHM7XG4gIGNvbnRleHQuY29tcHV0ZShcbiAgICBjcmVhdGVDb252MkRNYXRNdWxQcm9ncmFtSW5mbyhcbiAgICAgIGNvbnZJbnB1dHMsXG4gICAgICBhdHRyaWJ1dGVzLFxuICAgICAgb3V0cHV0U2hhcGUsXG4gICAgICBkaW1BT3V0ZXIsXG4gICAgICBkaW1CT3V0ZXIsXG4gICAgICBkaW1Jbm5lcixcbiAgICAgIGhhc0JpYXMsXG4gICAgICBzZXF1ZW50aWFsQWNjZXNzQnlUaHJlYWRzLFxuICAgICAgc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24sXG4gICAgKSxcbiAgICB7IGlucHV0czogY29udklucHV0cyB9LFxuICApO1xufTtcblxuY29uc3QgY29udjFkID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICAvLyBleHRlbmQgdGhlIGlucHV0IHRvIDJEIGJ5IGFkZGluZyBIIGRpbWVuc2lvblxuICBjb25zdCBpc0NoYW5uZWxMYXN0ID0gYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJztcbiAgY29uc3QgaW5wdXRzID0gW1xuICAgIGNvbnRleHQuaW5wdXRzWzBdLnJlc2hhcGUoXG4gICAgICBpc0NoYW5uZWxMYXN0XG4gICAgICAgID8gLy8gW04sIFcsIENdIC0+IFtOLCBIPTEsIFcsIENdXG4gICAgICAgICAgW2NvbnRleHQuaW5wdXRzWzBdLmRpbXNbMF0sIDEsIGNvbnRleHQuaW5wdXRzWzBdLmRpbXNbMV0sIGNvbnRleHQuaW5wdXRzWzBdLmRpbXNbMl1dXG4gICAgICAgIDogLy8gW04sIEMsIFddIC0+IFtOLCBDLCBIPTEsIFddXG4gICAgICAgICAgW2NvbnRleHQuaW5wdXRzWzBdLmRpbXNbMF0sIGNvbnRleHQuaW5wdXRzWzBdLmRpbXNbMV0sIDEsIGNvbnRleHQuaW5wdXRzWzBdLmRpbXNbMl1dLFxuICAgICksXG4gICAgLy9bRklMVEVSX09VVF9DSEFOTkVMLCBGSUxURVJfSU5fQ0hBTk5FTCwga1ddIC0+IFtGSUxURVJfT1VUX0NIQU5ORUwsIEZJTFRFUl9JTl9DSEFOTkVMLCBrSD0xLCBrV11cbiAgICBjb250ZXh0LmlucHV0c1sxXS5yZXNoYXBlKFtjb250ZXh0LmlucHV0c1sxXS5kaW1zWzBdLCBjb250ZXh0LmlucHV0c1sxXS5kaW1zWzFdLCAxLCBjb250ZXh0LmlucHV0c1sxXS5kaW1zWzJdXSksXG4gIF07XG4gIGlmIChjb250ZXh0LmlucHV0cy5sZW5ndGggPT09IDMpIHtcbiAgICBpbnB1dHMucHVzaChjb250ZXh0LmlucHV0c1syXSk7XG4gIH1cbiAgY29uc3QgcGFkcyA9IFswLCBhdHRyaWJ1dGVzLnBhZHNbMF0sIDAsIGF0dHJpYnV0ZXMucGFkc1sxXV07XG4gIGNvbnN0IHN0cmlkZXMgPSBbMV0uY29uY2F0KGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gIGNvbnN0IGRpbGF0aW9ucyA9IFsxXS5jb25jYXQoYXR0cmlidXRlcy5kaWxhdGlvbnMpO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IFsxXS5jb25jYXQoYXR0cmlidXRlcy5rZXJuZWxTaGFwZSk7XG4gIGNvbnN0IGFkanVzdGVkQXR0cmlidXRlcyA9IGdldEFkanVzdGVkQ29udkF0dHJpYnV0ZXMoXG4gICAgeyAuLi5hdHRyaWJ1dGVzLCBwYWRzLCBzdHJpZGVzLCBkaWxhdGlvbnMsIGtlcm5lbFNoYXBlIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICBjb252MmQoY29udGV4dCwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMsIChvdXRwdXRTaGFwZSkgPT5cbiAgICBpc0NoYW5uZWxMYXN0ID8gW291dHB1dFNoYXBlWzBdLCBvdXRwdXRTaGFwZVsyXSwgb3V0cHV0U2hhcGVbM11dIDogW291dHB1dFNoYXBlWzBdLCBvdXRwdXRTaGFwZVsxXSwgb3V0cHV0U2hhcGVbM11dLFxuICApO1xufTtcblxuY29uc3QgY29udjNkID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgY29uc3QgZm9ybWF0ID0gYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJyA/ICdjaGFubmVsc0xhc3QnIDogJ2NoYW5uZWxzRmlyc3QnO1xuICBjb25zdCBhZGp1c3RlZEF0dHJpYnV0ZXMgPSBnZXRBZGp1c3RlZENvbnZBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMsIGlucHV0cyk7XG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLmF1dG9QYWQgPT09ICdOT1RTRVQnID8gYXR0cmlidXRlcy5wYWRzIDogYXR0cmlidXRlcy5hdXRvUGFkO1xuICBjb25zdCBjb252SW5mbyA9IGNvbXB1dGVDb252M0RJbmZvKFxuICAgIGlucHV0c1swXS5kaW1zIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgaW5wdXRzWzFdLmRpbXMgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICBhdHRyaWJ1dGVzLnN0cmlkZXMgYXMgbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIGF0dHJpYnV0ZXMuZGlsYXRpb25zIGFzIG51bWJlciB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICBwYWRzIGFzIHN0cmluZyB8IG51bWJlcltdLFxuICAgIGZhbHNlLFxuICAgIGZvcm1hdCxcbiAgKTtcbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZUNvbnYzRE5haXZlUHJvZ3JhbUluZm8oXG4gICAgICBpbnB1dHMsXG4gICAgICBhZGp1c3RlZEF0dHJpYnV0ZXMsXG4gICAgICBjb252SW5mby5vdXRTaGFwZSxcbiAgICAgIFtjb252SW5mby5maWx0ZXJEZXB0aCwgY29udkluZm8uZmlsdGVySGVpZ2h0LCBjb252SW5mby5maWx0ZXJXaWR0aF0sXG4gICAgICBbY29udkluZm8ucGFkSW5mby5mcm9udCwgY29udkluZm8ucGFkSW5mby50b3AsIGNvbnZJbmZvLnBhZEluZm8ubGVmdF0sXG4gICAgICBmb3JtYXQsXG4gICAgKSxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb252ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG4gIGlmIChjb250ZXh0LmlucHV0c1swXS5kaW1zLmxlbmd0aCA9PT0gMykge1xuICAgIGNvbnYxZChjb250ZXh0LCBhdHRyaWJ1dGVzKTtcbiAgfSBlbHNlIGlmIChjb250ZXh0LmlucHV0c1swXS5kaW1zLmxlbmd0aCA9PT0gNSkge1xuICAgIGNvbnYzZChjb250ZXh0LCBjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgYWRqdXN0ZWRBdHRyaWJ1dGVzID0gZ2V0QWRqdXN0ZWRDb252QXR0cmlidXRlcyhhdHRyaWJ1dGVzLCBjb250ZXh0LmlucHV0cyk7XG4gICAgY29udjJkKGNvbnRleHQsIGNvbnRleHQuaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMpO1xuICB9XG59O1xuIiwgIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuLy8gc2FtcGxlZCBmcm9tIFtAdGVuc29yZmxvdy90ZmpzXSB0ZmpzLWJhY2tlbmQtd2ViZ3B1L3NyYy9jb252X2JhY2twcm9wX3dlYmdwdS50c1xuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IExPR19ERUJVRyB9IGZyb20gJy4uLy4uLy4uL2xvZyc7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3ksIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZSxcbiAgVW5pZm9ybXNBcnJheVR5cGUsXG4gIGdldE1heENvbXBvbmVudHMsXG59IGZyb20gJy4uL2NvbW1vbic7XG5pbXBvcnQgeyBDb252VHJhbnNwb3NlQXR0cmlidXRlcyB9IGZyb20gJy4uL2NvbnYtdHJhbnNwb3NlJztcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbnZUcmFuc3Bvc2UyRFByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMsXG4gIHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uPzogKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSkgPT4gbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBhdHRyaWJ1dGVzLm91dHB1dFNoYXBlO1xuICBjb25zdCBpc0NoYW5uZWxzTGFzdCA9IGF0dHJpYnV0ZXMuZm9ybWF0ID09PSAnTkhXQyc7XG4gIGNvbnN0IGdyb3VwID0gYXR0cmlidXRlcy5ncm91cDtcbiAgY29uc3Qgd1NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IGlucHV0Q2hhbm5lbHNQZXJHcm91cCA9IHdTaGFwZVsyXSAvIGdyb3VwO1xuICBjb25zdCBvdXRwdXRDaGFubmVsc1Blckdyb3VwID0gd1NoYXBlWzNdO1xuICBjb25zdCBhQ29tcG9uZW50cyA9IGlzQ2hhbm5lbHNMYXN0ID8gZ2V0TWF4Q29tcG9uZW50cyhpbnB1dENoYW5uZWxzUGVyR3JvdXApIDogMTtcbiAgY29uc3QgcGFja0lucHV0QXM0ID0gaXNDaGFubmVsc0xhc3QgJiYgb3V0cHV0Q2hhbm5lbHNQZXJHcm91cCA9PT0gMSAmJiBpbnB1dENoYW5uZWxzUGVyR3JvdXAgPj0gNDtcbiAgY29uc3QgaW5wdXRDaGFubmVsc1Blckdyb3VwSW50ID0gcGFja0lucHV0QXM0XG4gICAgPyBNYXRoLmZsb29yKGlucHV0Q2hhbm5lbHNQZXJHcm91cCAvIDQpICogNFxuICAgIDogTWF0aC5mbG9vcihpbnB1dENoYW5uZWxzUGVyR3JvdXAgLyBhQ29tcG9uZW50cykgKiBhQ29tcG9uZW50cztcbiAgY29uc3QgaW5wdXRDaGFubmVsc1JlbWFpbmRlciA9IGlucHV0Q2hhbm5lbHNQZXJHcm91cCAtIGlucHV0Q2hhbm5lbHNQZXJHcm91cEludDtcbiAgY29uc3QgY29tcG9uZW50cyA9IGlzQ2hhbm5lbHNMYXN0ID8gZ2V0TWF4Q29tcG9uZW50cyhvdXRwdXRDaGFubmVsc1Blckdyb3VwKSA6IDE7XG4gIGNvbnN0IGJDb21wb25lbnRzID0gaXNDaGFubmVsc0xhc3QgPyAob3V0cHV0Q2hhbm5lbHNQZXJHcm91cCA9PT0gMSA/IGFDb21wb25lbnRzIDogY29tcG9uZW50cykgOiAxO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpIC8gY29tcG9uZW50cztcbiAgY29uc3QgZGlzcGF0Y2ggPSBbTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCksIDEsIDFdO1xuICBMT0dfREVCVUcoJ3ZlcmJvc2UnLCAoKSA9PiBgW2NvbnYyZF9iYWNrcHJvcF93ZWJncHVdIGRpc3BhdGNoID0gJHtkaXNwYXRjaH1gKTtcblxuICBjb25zdCBpbnB1dERlcGVuZGVuY2llczogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXSA9IFsncmFuaycsICdyYW5rJ107XG4gIGNvbnN0IHN0cmlkZXMgPSBbYXR0cmlidXRlcy5zdHJpZGVzWzBdLCBhdHRyaWJ1dGVzLnN0cmlkZXNbMV1dO1xuICBjb25zdCBmaWx0ZXJEaW1zID0gW2F0dHJpYnV0ZXMua2VybmVsU2hhcGVbaXNDaGFubmVsc0xhc3QgPyAxIDogMl0sIGF0dHJpYnV0ZXMua2VybmVsU2hhcGVbaXNDaGFubmVsc0xhc3QgPyAyIDogM11dO1xuICBjb25zdCBkaWxhdGlvbnMgPSBbYXR0cmlidXRlcy5kaWxhdGlvbnNbMF0sIGF0dHJpYnV0ZXMuZGlsYXRpb25zWzFdXTtcbiAgY29uc3QgZWZmZWN0aXZlRmlsdGVyRGltcyA9IFtcbiAgICBmaWx0ZXJEaW1zWzBdICtcbiAgICAgIChhdHRyaWJ1dGVzLmRpbGF0aW9uc1swXSA8PSAxXG4gICAgICAgID8gMFxuICAgICAgICA6IChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlW2lzQ2hhbm5lbHNMYXN0ID8gMSA6IDJdIC0gMSkgKiAoYXR0cmlidXRlcy5kaWxhdGlvbnNbMF0gLSAxKSksXG4gICAgZmlsdGVyRGltc1sxXSArXG4gICAgICAoYXR0cmlidXRlcy5kaWxhdGlvbnNbMV0gPD0gMVxuICAgICAgICA/IDBcbiAgICAgICAgOiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZVtpc0NoYW5uZWxzTGFzdCA/IDIgOiAzXSAtIDEpICogKGF0dHJpYnV0ZXMuZGlsYXRpb25zWzFdIC0gMSkpLFxuICBdO1xuICBjb25zdCBwYWRzID0gW1xuICAgIGVmZmVjdGl2ZUZpbHRlckRpbXNbMF0gLSAxIC0gTWF0aC5mbG9vcigoYXR0cmlidXRlcy5wYWRzWzBdICsgYXR0cmlidXRlcy5wYWRzWzJdKSAvIDIpLFxuICAgIGVmZmVjdGl2ZUZpbHRlckRpbXNbMV0gLSAxIC0gTWF0aC5mbG9vcigoYXR0cmlidXRlcy5wYWRzWzFdICsgYXR0cmlidXRlcy5wYWRzWzNdKSAvIDIpLFxuICBdO1xuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBzdHJpZGVzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGZpbHRlckRpbXMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogZGlsYXRpb25zIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGVmZmVjdGl2ZUZpbHRlckRpbXMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmludDMyLCBkYXRhOiBwYWRzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGlucHV0Q2hhbm5lbHNQZXJHcm91cEludCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBpbnB1dENoYW5uZWxzUGVyR3JvdXAgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0Q2hhbm5lbHNQZXJHcm91cCB9LFxuICAgIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0c1swXS5kaW1zLCBpbnB1dHNbMV0uZGltcyksXG4gIF07XG4gIGlmIChoYXNCaWFzKSB7XG4gICAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRzWzJdLmRpbXMpKTtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCdyYW5rJyk7XG4gIH1cbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMob3V0cHV0U2hhcGUpKTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdzdHJpZGVzJywgdHlwZTogJ3UzMicsIGxlbmd0aDogc3RyaWRlcy5sZW5ndGggfSxcbiAgICAgIHsgbmFtZTogJ2ZpbHRlcl9kaW1zJywgdHlwZTogJ3UzMicsIGxlbmd0aDogZmlsdGVyRGltcy5sZW5ndGggfSxcbiAgICAgIHsgbmFtZTogJ2RpbGF0aW9ucycsIHR5cGU6ICd1MzInLCBsZW5ndGg6IGZpbHRlckRpbXMubGVuZ3RoIH0sXG4gICAgICB7IG5hbWU6ICdlZmZlY3RpdmVfZmlsdGVyX2RpbXMnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiBlZmZlY3RpdmVGaWx0ZXJEaW1zLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAncGFkcycsIHR5cGU6ICdpMzInLCBsZW5ndGg6IHBhZHMubGVuZ3RoIH0sXG4gICAgICB7IG5hbWU6ICdpbnB1dF9jaGFubmVsc19wZXJfZ3JvdXBfaW50JywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2lucHV0X2NoYW5uZWxzX3Blcl9ncm91cCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdvdXRwdXRfY2hhbm5lbHNfcGVyX2dyb3VwJywgdHlwZTogJ3UzMicgfSxcbiAgICBdO1xuICAgIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlKGlucHV0c1swXS5kYXRhVHlwZSk7XG4gICAgY29uc3Qgcm93RGltID0gaXNDaGFubmVsc0xhc3QgPyAxIDogMjtcbiAgICBjb25zdCBjb2xEaW0gPSBpc0NoYW5uZWxzTGFzdCA/IDIgOiAzO1xuICAgIGNvbnN0IGNoYW5uZWxEaW0gPSBpc0NoYW5uZWxzTGFzdCA/IDMgOiAxO1xuXG4gICAgY29uc3QgdyA9IGlucHV0VmFyaWFibGUoJ1cnLCBpbnB1dHNbMV0uZGF0YVR5cGUsIGlucHV0c1sxXS5kaW1zLmxlbmd0aCwgYkNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGR5ID0gaW5wdXRWYXJpYWJsZSgnRHknLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0c1swXS5kaW1zLmxlbmd0aCwgYUNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGlucHV0VmFyaWFibGVzID0gW2R5LCB3XTtcbiAgICBpZiAoaGFzQmlhcykge1xuICAgICAgaW5wdXRWYXJpYWJsZXMucHVzaChpbnB1dFZhcmlhYmxlKCdiaWFzJywgaW5wdXRzWzJdLmRhdGFUeXBlLCBbb3V0cHV0U2hhcGVbY2hhbm5lbERpbV1dLmxlbmd0aCwgY29tcG9uZW50cykpO1xuICAgIH1cbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgncmVzdWx0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgsIGNvbXBvbmVudHMpO1xuXG4gICAgY29uc3QgY2FsY3VsYXRlUmVzdWx0ID0gKCk6IHN0cmluZyA9PiB7XG4gICAgICBsZXQgY2FsY1N0ciA9ICcnO1xuICAgICAgaWYgKHBhY2tJbnB1dEFzNCkge1xuICAgICAgICBpZiAoYUNvbXBvbmVudHMgPT09IDQpIHtcbiAgICAgICAgICBjYWxjU3RyICs9IGBcbiAgICAgICAgbGV0IHhWYWx1ZSA9ICR7ZHkuZ2V0QnlPZmZzZXQoJ3hfb2Zmc2V0Jyl9O1xuICAgICAgICBsZXQgd1ZhbHVlID0gJHt3LmdldEJ5T2Zmc2V0KCd3X29mZnNldCcpfTtcbiAgICAgICAgZG90UHJvZCA9IGRvdFByb2QgKyBkb3QoeFZhbHVlLCB3VmFsdWUpO1xuICAgICAgICB4X29mZnNldCArPSAxdTtcbiAgICAgICAgd19vZmZzZXQgKz0gMXU7YDtcbiAgICAgICAgfSBlbHNlIGlmIChhQ29tcG9uZW50cyA9PT0gMikge1xuICAgICAgICAgIGNhbGNTdHIgKz0gYFxuICAgICAgICAgIGRvdFByb2QgPSBkb3RQcm9kICsgZG90KHZlYzQ8JHtkYXRhVHlwZX0+KCR7ZHkuZ2V0QnlPZmZzZXQoJ3hfb2Zmc2V0Jyl9LCAke2R5LmdldEJ5T2Zmc2V0KCd4X29mZnNldCArIDF1Jyl9KSwgdmVjNDwke2RhdGFUeXBlfT4oJHt3LmdldEJ5T2Zmc2V0KCd3X29mZnNldCcpfSwgJHt3LmdldEJ5T2Zmc2V0KCd3X29mZnNldCArIDF1Jyl9KSk7XG4gICAgICAgICAgeF9vZmZzZXQgKz0gMnU7XG4gICAgICAgICAgd19vZmZzZXQgKz0gMnU7YDtcbiAgICAgICAgfSBlbHNlIGlmIChhQ29tcG9uZW50cyA9PT0gMSkge1xuICAgICAgICAgIGNhbGNTdHIgKz0gYFxuICAgICAgICAgIGRvdFByb2QgPSBkb3RQcm9kICsgZG90KHZlYzQ8JHtkYXRhVHlwZX0+KCR7ZHkuZ2V0QnlPZmZzZXQoJ3hfb2Zmc2V0Jyl9LCAke2R5LmdldEJ5T2Zmc2V0KCd4X29mZnNldCArIDF1Jyl9LCAke2R5LmdldEJ5T2Zmc2V0KCd4X29mZnNldCArIDJ1Jyl9LCAke2R5LmdldEJ5T2Zmc2V0KCd4X29mZnNldCArIDN1Jyl9KSwgdmVjNDwke2RhdGFUeXBlfT4oJHt3LmdldEJ5T2Zmc2V0KCd3X29mZnNldCcpfSwgJHt3LmdldEJ5T2Zmc2V0KCd3X29mZnNldCArIDF1Jyl9LCAke3cuZ2V0QnlPZmZzZXQoJ3dfb2Zmc2V0ICsgMnUnKX0sICR7dy5nZXRCeU9mZnNldCgnd19vZmZzZXQgKyAzdScpfSkpO1xuICAgICAgICAgIHhfb2Zmc2V0ICs9IDR1O1xuICAgICAgICAgIHdfb2Zmc2V0ICs9IDR1O2A7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhbGNTdHIgKz0gYFxuICAgICAgICAgICAgICAgICAgbGV0IHhWYWx1ZSA9ICR7XG4gICAgICAgICAgICAgICAgICAgIGlzQ2hhbm5lbHNMYXN0XG4gICAgICAgICAgICAgICAgICAgICAgPyBkeS5nZXRCeU9mZnNldChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYCR7ZHkuaW5kaWNlc1RvT2Zmc2V0KGAke2R5LnR5cGUuaW5kaWNlc30oYmF0Y2gsIGlkeVIsIGlkeUMsIGlucHV0Q2hhbm5lbClgKX0gLyAke2FDb21wb25lbnRzfWAsXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgOiBkeS5nZXQoJ2JhdGNoJywgJ2lucHV0Q2hhbm5lbCcsICdpZHlSJywgJ2lkeUMnKVxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgYDtcbiAgICAgICAgaWYgKGFDb21wb25lbnRzID09PSAxKSB7XG4gICAgICAgICAgY2FsY1N0ciArPSBgXG4gICAgICAgICAgbGV0IHdfb2Zmc2V0ID0gJHt3LmluZGljZXNUb09mZnNldChgJHt3LnR5cGUuaW5kaWNlc30odTMyKHdSUGVybSksIHUzMih3Q1Blcm0pLCBpbnB1dENoYW5uZWwsIHdPdXRDaGFubmVsKWApfTtcbiAgICAgICAgICBsZXQgd1ZhbHVlID0gJHt3LmdldEJ5T2Zmc2V0KGB3X29mZnNldCAvICR7YkNvbXBvbmVudHN9YCl9O1xuICAgICAgICAgIGRvdFByb2QgPSBkb3RQcm9kICsgeFZhbHVlICogd1ZhbHVlO2A7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZm9yIChsZXQgYyA9IDA7IGMgPCBhQ29tcG9uZW50czsgYysrKSB7XG4gICAgICAgICAgICBjYWxjU3RyICs9IGBcbiAgICAgICAgICAgIGxldCB3VmFsdWUke2N9ID0gJHt3LmdldEJ5T2Zmc2V0KGAke3cuaW5kaWNlc1RvT2Zmc2V0KGAke3cudHlwZS5pbmRpY2VzfSh1MzIod1JQZXJtKSwgdTMyKHdDUGVybSksIGlucHV0Q2hhbm5lbCArICR7Y30sIHdPdXRDaGFubmVsKWApfSAvICR7YkNvbXBvbmVudHN9YCl9O1xuICAgICAgICAgICAgZG90UHJvZCA9IGRvdFByb2QgKyB4VmFsdWVbJHtjfV0gKiB3VmFsdWUke2N9O2A7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gY2FsY1N0cjtcbiAgICB9O1xuICAgIGNvbnN0IGNhbGN1bGF0ZVJlbWFpbmRlciA9ICgpOiBzdHJpbmcgPT4ge1xuICAgICAgaWYgKGlucHV0Q2hhbm5lbHNSZW1haW5kZXIgPT09IDApIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfVxuICAgICAgaWYgKCFwYWNrSW5wdXRBczQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBwYWNrSW5wdXRBczQgJHtwYWNrSW5wdXRBczR9IGlzIG5vdCB0cnVlLmApO1xuICAgICAgfVxuICAgICAgbGV0IGNhbGNTdHIgPSAnJztcbiAgICAgIGlmIChhQ29tcG9uZW50cyA9PT0gMSkge1xuICAgICAgICBjYWxjU3RyICs9ICdkb3RQcm9kID0gZG90UHJvZCc7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRDaGFubmVsc1JlbWFpbmRlcjsgaSsrKSB7XG4gICAgICAgICAgY2FsY1N0ciArPSBgXG4gICAgICAgICAgICArICR7ZHkuZ2V0QnlPZmZzZXQoYHhfb2Zmc2V0ICsgJHtpfWApfSAqICR7dy5nZXRCeU9mZnNldChgd19vZmZzZXQgKyAke2l9YCl9YDtcbiAgICAgICAgfVxuICAgICAgICBjYWxjU3RyICs9ICc7JztcbiAgICAgIH0gZWxzZSBpZiAoYUNvbXBvbmVudHMgPT09IDIpIHtcbiAgICAgICAgaWYgKGlucHV0Q2hhbm5lbHNSZW1haW5kZXIgIT09IDIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgaW5wdXRDaGFubmVsc1JlbWFpbmRlciAke2lucHV0Q2hhbm5lbHNSZW1haW5kZXJ9LmApO1xuICAgICAgICB9XG4gICAgICAgIGNhbGNTdHIgKz0gYFxuICAgICAgICAgIGxldCB4VmFsdWUgPSAke2R5LmdldEJ5T2Zmc2V0KCd4X29mZnNldCcpfTtcbiAgICAgICAgICBsZXQgd1ZhbHVlID0gJHt3LmdldEJ5T2Zmc2V0KCd3X29mZnNldCcpfTtcbiAgICAgICAgICBkb3RQcm9kID0gZG90UHJvZCArIGRvdCh4VmFsdWUsIHdWYWx1ZSk7YDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjYWxjU3RyO1xuICAgIH07XG4gICAgY29uc3QgY29kZVNuaXBwZXQgPSBgXG4gICAgICAgICAgICBsZXQgb3V0cHV0SW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcyhgZ2xvYmFsX2lkeCAqICR7Y29tcG9uZW50c31gKX07XG4gICAgICAgICAgICBsZXQgYmF0Y2ggPSAke291dHB1dC5pbmRpY2VzR2V0KCdvdXRwdXRJbmRpY2VzJywgMCl9O1xuICAgICAgICAgICAgbGV0IGQxID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0SW5kaWNlcycsIGNoYW5uZWxEaW0pfTtcbiAgICAgICAgICAgIGxldCByID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0SW5kaWNlcycsIHJvd0RpbSl9O1xuICAgICAgICAgICAgbGV0IGMgPSAke291dHB1dC5pbmRpY2VzR2V0KCdvdXRwdXRJbmRpY2VzJywgY29sRGltKX07XG4gICAgICAgICAgICBsZXQgZHlDb3JuZXIgPSB2ZWMyPGkzMj4oaTMyKHIpLCBpMzIoYykpIC0gdW5pZm9ybXMucGFkcztcbiAgICAgICAgICAgIGxldCBkeVJDb3JuZXIgPSBkeUNvcm5lci54O1xuICAgICAgICAgICAgbGV0IGR5Q0Nvcm5lciA9IGR5Q29ybmVyLnk7XG4gICAgICAgICAgICBsZXQgZ3JvdXBJZCA9IGQxIC8gdW5pZm9ybXMub3V0cHV0X2NoYW5uZWxzX3Blcl9ncm91cDtcbiAgICAgICAgICAgIGxldCB3T3V0Q2hhbm5lbCA9IGQxIC0gZ3JvdXBJZCAqIHVuaWZvcm1zLm91dHB1dF9jaGFubmVsc19wZXJfZ3JvdXA7XG4gICAgICAgICAgICAvLyBDb252b2x2ZSBkeSg/LCA/LCBkMikgd2l0aCB3KDosIDosIGQxLCBkMikgdG8gY29tcHV0ZSBkeCh4UiwgeEMsIGQxKS5cbiAgICAgICAgICAgIC8vID8gPSB0byBiZSBkZXRlcm1pbmVkLiA6ID0gYWNyb3NzIGFsbCB2YWx1ZXMgaW4gdGhhdCBheGlzLlxuICAgICAgICAgICAgdmFyIGRvdFByb2QgPSAke291dHB1dC50eXBlLnZhbHVlfSgwLjApO1xuICAgICAgICAgICAgdmFyIHdSOiB1MzIgPSAwO1xuICAgICAgICAgICAgaWYgKHVuaWZvcm1zLmRpbGF0aW9ucy54ID09IDEpIHtcbiAgICAgICAgICAgICAgLy8gTWluaW11bSB3UiA+PSAwIHRoYXQgc2F0aXNmaWVzIChkeVJDb3JuZXIgKyB3UikgJSAodW5pZm9ybXMuc3RyaWRlcy54KSA9PSAwXG4gICAgICAgICAgICAgIHdSID0gdTMyKCgoZHlSQ29ybmVyICsgaTMyKHVuaWZvcm1zLnN0cmlkZXMueCkgLSAxKSAvIGkzMih1bmlmb3Jtcy5zdHJpZGVzLngpKSAqIGkzMih1bmlmb3Jtcy5zdHJpZGVzLngpIC0gZHlSQ29ybmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoOyB3UiA8IHVuaWZvcm1zLmVmZmVjdGl2ZV9maWx0ZXJfZGltcy54OyB3UiA9IHdSICsgMSkge1xuICAgICAgICAgICAgICBpZiAod1IgJSB1bmlmb3Jtcy5kaWxhdGlvbnMueCAhPSAwKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGV0IGR5UiA9ICgke2RhdGFUeXBlfShkeVJDb3JuZXIpICsgJHtkYXRhVHlwZX0od1IpKSAvICR7ZGF0YVR5cGV9KHVuaWZvcm1zLnN0cmlkZXNbMF0pO1xuICAgICAgICAgICAgICBsZXQgd1JQZXJtID0gdW5pZm9ybXMuZmlsdGVyX2RpbXMueCAtIDEgLSB3UiAvIHVuaWZvcm1zLmRpbGF0aW9ucy54O1xuICAgICAgICAgICAgICBpZiAoZHlSIDwgMC4wIHx8IGR5UiA+PSAke2RhdGFUeXBlfSh1bmlmb3Jtcy5EeV9zaGFwZVske3Jvd0RpbX1dKSB8fCBmcmFjdChkeVIpID4gMC4wIHx8XG4gICAgICAgICAgICAgICAgICB3UlBlcm0gPCAwKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGV0IGlkeVI6IHUzMiA9IHUzMihkeVIpO1xuICAgICAgICAgICAgICB2YXIgd0M6IHUzMiA9IDA7XG4gICAgICAgICAgICAgIGlmICh1bmlmb3Jtcy5kaWxhdGlvbnMueSA9PSAxKSB7XG4gICAgICAgICAgICAgICAgLy8gTWluaW11bSB3QyA+PSAwIHRoYXQgc2F0aXNmaWVzIChkeUNDb3JuZXIgKyB3QykgJSAodW5pZm9ybXMuc3RyaWRlcy55KSA9PSAwXG4gICAgICAgICAgICAgICAgd0MgPSB1MzIoKChkeUNDb3JuZXIgKyBpMzIodW5pZm9ybXMuc3RyaWRlcy55KSAtIDEpIC8gaTMyKHVuaWZvcm1zLnN0cmlkZXMueSkpICogaTMyKHVuaWZvcm1zLnN0cmlkZXMueSkgLSBkeUNDb3JuZXIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGZvciAoOyB3QyA8IHVuaWZvcm1zLmVmZmVjdGl2ZV9maWx0ZXJfZGltcy55OyB3QyA9IHdDICsgMSkge1xuICAgICAgICAgICAgICAgIGlmICh3QyAlIHVuaWZvcm1zLmRpbGF0aW9ucy55ICE9IDApIHtcbiAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZHlDID0gKCR7ZGF0YVR5cGV9KGR5Q0Nvcm5lcikgKyAke2RhdGFUeXBlfSh3QykpIC8gJHtkYXRhVHlwZX0odW5pZm9ybXMuc3RyaWRlcy55KTtcbiAgICAgICAgICAgICAgICBsZXQgd0NQZXJtID0gdW5pZm9ybXMuZmlsdGVyX2RpbXMueSAtIDEgLSB3QyAvIHVuaWZvcm1zLmRpbGF0aW9ucy55O1xuICAgICAgICAgICAgICAgIGlmIChkeUMgPCAwLjAgfHwgZHlDID49ICR7ZGF0YVR5cGV9KHVuaWZvcm1zLkR5X3NoYXBlWyR7Y29sRGltfV0pIHx8XG4gICAgICAgICAgICAgICAgICAgIGZyYWN0KGR5QykgPiAwLjAgfHwgd0NQZXJtIDwgMCkge1xuICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBpZHlDOiB1MzIgPSB1MzIoZHlDKTtcbiAgICAgICAgICAgICAgICB2YXIgaW5wdXRDaGFubmVsID0gZ3JvdXBJZCAqIHVuaWZvcm1zLmlucHV0X2NoYW5uZWxzX3Blcl9ncm91cDtcbiAgICAgICAgICAgICAgICAke1xuICAgICAgICAgICAgICAgICAgcGFja0lucHV0QXM0XG4gICAgICAgICAgICAgICAgICAgID8gYFxuICAgICAgICAgICAgICAgIHZhciB4X29mZnNldCA9ICR7ZHkuaW5kaWNlc1RvT2Zmc2V0KGAke2R5LnR5cGUuaW5kaWNlc30oYmF0Y2gsIGlkeVIsIGlkeUMsIGlucHV0Q2hhbm5lbClgKX0gLyAke2FDb21wb25lbnRzfTtcbiAgICAgICAgICAgICAgICB2YXIgd19vZmZzZXQgPSAke3cuaW5kaWNlc1RvT2Zmc2V0KGAke3cudHlwZS5pbmRpY2VzfSh3UlBlcm0sIHdDUGVybSwgaW5wdXRDaGFubmVsLCB3T3V0Q2hhbm5lbClgKX0gLyAke2JDb21wb25lbnRzfTtcbiAgICAgICAgICAgICAgICAgIGBcbiAgICAgICAgICAgICAgICAgICAgOiAnJ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmb3IgKHZhciBkMjogdTMyID0gMDsgZDIgPCB1bmlmb3Jtcy5pbnB1dF9jaGFubmVsc19wZXJfZ3JvdXBfaW50OyBkMiA9IGQyICsgJHtwYWNrSW5wdXRBczQgPyA0IDogYUNvbXBvbmVudHN9KSB7XG4gICAgICAgICAgICAgICAgICAke2NhbGN1bGF0ZVJlc3VsdCgpfVxuICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsID0gaW5wdXRDaGFubmVsICsgJHtwYWNrSW5wdXRBczQgPyA0IDogYUNvbXBvbmVudHN9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAke2NhbGN1bGF0ZVJlbWFpbmRlcigpfVxuICAgICAgICAgICAgICAgIHdDID0gd0MgKyB1bmlmb3Jtcy5zdHJpZGVzLnkgLSAxO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHdSID0gd1IgKyB1bmlmb3Jtcy5zdHJpZGVzWzBdIC0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCB2YWx1ZSA9IGRvdFByb2Qke2hhc0JpYXMgPyBgICsgYmlhc1tkMSAvICR7Y29tcG9uZW50c31dYCA6ICcnfTtcbiAgICAgICAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ3ZhbHVlJyl9O1xuICAgICAgICAgIGA7XG5cbiAgICByZXR1cm4gYFxuICAgICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJpYWJsZXMsIG91dHB1dCl9XG4gICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9O1xuICAgICR7Y29kZVNuaXBwZXR9fWA7XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnQ29udlRyYW5zcG9zZTJEJyxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX07JHthQ29tcG9uZW50c30ke2JDb21wb25lbnRzfSR7Y29tcG9uZW50c30ke3BhY2tJbnB1dEFzNH0ke2lucHV0Q2hhbm5lbHNSZW1haW5kZXJ9YCxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzLFxuICAgIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogZGlzcGF0Y2hbMF0sIHk6IGRpc3BhdGNoWzFdLCB6OiBkaXNwYXRjaFsyXSB9LFxuICAgICAgb3V0cHV0czogW1xuICAgICAgICB7XG4gICAgICAgICAgZGltczogc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24gPyBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbihvdXRwdXRTaGFwZSkgOiBvdXRwdXRTaGFwZSxcbiAgICAgICAgICBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZUNvbnZUcmFuc3Bvc2UyRFByb2dyYW1JbmZvIH0gZnJvbSAnLi8zcmQtcGFydHkvY29udl9iYWNrcHJvcF93ZWJncHUnO1xuaW1wb3J0IHsgQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbnYnO1xuaW1wb3J0IHsgcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9mdXNlLXV0aWxzJztcbmltcG9ydCB7IGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvIH0gZnJvbSAnLi90cmFuc3Bvc2UnO1xuXG5jb25zdCBjb21wdXRlVG90YWxQYWQgPSAoXG4gIGluRGltOiBudW1iZXIsXG4gIHN0cmlkZTogbnVtYmVyLFxuICBhZGo6IG51bWJlcixcbiAga2VybmVsOiBudW1iZXIsXG4gIGRpbGF0aW9uOiBudW1iZXIsXG4gIG91dFNpemU6IG51bWJlcixcbikgPT4gKGluRGltIC0gMSkgKiBzdHJpZGUgKyBhZGogKyAoa2VybmVsIC0gMSkgKiBkaWxhdGlvbiArIDEgLSBvdXRTaXplO1xuXG5jb25zdCBkaXN0cmlidXRlUGFkZGluZyA9ICh0b3RhbFBhZDogbnVtYmVyLCBhdXRvUGFkOiBzdHJpbmcsIHBhZHM6IG51bWJlcltdLCBoZWFkOiBudW1iZXIsIHRhaWw6IG51bWJlcikgPT4ge1xuICBjb25zdCBzbWFsbFBhZCA9IE1hdGguZmxvb3IodG90YWxQYWQgLyAyKTtcbiAgaWYgKGF1dG9QYWQgPT09ICdTQU1FX1VQUEVSJykge1xuICAgIHBhZHNbaGVhZF0gPSBzbWFsbFBhZDtcbiAgICBwYWRzW3RhaWxdID0gdG90YWxQYWQgLSBzbWFsbFBhZDtcbiAgfSBlbHNlIGlmIChhdXRvUGFkID09PSAnU0FNRV9MT1dFUicpIHtcbiAgICBwYWRzW2hlYWRdID0gdG90YWxQYWQgLSBzbWFsbFBhZDtcbiAgICBwYWRzW3RhaWxdID0gc21hbGxQYWQ7XG4gIH1cbn07XG5cbmNvbnN0IGNhbGN1bGF0ZU91dHB1dFNoYXBlQW5kUGFkcyA9IChcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXV0b1BhZDogc3RyaW5nLFxuICBncm91cDogbnVtYmVyLFxuICBwYWRzOiBudW1iZXJbXSxcbiAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGlzQ2hhbm5lbExhc3Q6IGJvb2xlYW4sXG4gIG91dHB1dFBhZGRpbmc6IG51bWJlcltdLFxuICBvdXRwdXRTaGFwZTogbnVtYmVyW10sXG4pID0+IHtcbiAgY29uc3Qgc3BhdGlhbFJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aCAtIDI7XG4gIGNvbnN0IHVwZGF0ZU91dHB1dFNoYXBlID0gb3V0cHV0U2hhcGUubGVuZ3RoID09PSAwO1xuICBpZiAob3V0cHV0UGFkZGluZy5sZW5ndGggPCBzcGF0aWFsUmFuaykge1xuICAgIG91dHB1dFBhZGRpbmcucHVzaCguLi5BcnJheShzcGF0aWFsUmFuayAtIG91dHB1dFBhZGRpbmcubGVuZ3RoKS5maWxsKDApKTtcbiAgfVxuICBjb25zdCBiYXRjaFNpemUgPSBpbnB1dFNoYXBlWzBdO1xuICBjb25zdCBvdXRDaGFubmVscyA9IGtlcm5lbFNoYXBlW2lzQ2hhbm5lbExhc3QgPyAzIDogMV0gKiBncm91cDtcbiAgZm9yIChsZXQgaSA9IDAsIGogPSBpbnB1dFNoYXBlLmxlbmd0aCAtIHNwYXRpYWxSYW5rIC0gKGlzQ2hhbm5lbExhc3QgPyAxIDogMCk7IGkgPCBzcGF0aWFsUmFuazsgKytpLCArK2opIHtcbiAgICBjb25zdCBpblNpemUgPSBpbnB1dFNoYXBlW2pdO1xuICAgIGNvbnN0IG91dFNpemUgPSB1cGRhdGVPdXRwdXRTaGFwZSA/IGluU2l6ZSAqIHN0cmlkZXNbaV0gOiBvdXRwdXRTaGFwZVtpXTtcbiAgICBjb25zdCB0b3RhbFBhZCA9IGNvbXB1dGVUb3RhbFBhZChpblNpemUsIHN0cmlkZXNbaV0sIHBhZHNbaV0sIGtlcm5lbFNoYXBlW2pdLCBkaWxhdGlvbnNbaV0sIG91dFNpemUpO1xuICAgIGRpc3RyaWJ1dGVQYWRkaW5nKHRvdGFsUGFkLCBhdXRvUGFkLCBwYWRzLCBpLCBpICsgc3BhdGlhbFJhbmspO1xuICAgIGlmICh1cGRhdGVPdXRwdXRTaGFwZSkge1xuICAgICAgb3V0cHV0U2hhcGUucHVzaChcbiAgICAgICAgc3RyaWRlc1tpXSAqIChpblNpemUgLSAxKSArXG4gICAgICAgICAgb3V0cHV0UGFkZGluZ1tpXSArXG4gICAgICAgICAgKGtlcm5lbFNoYXBlW2pdIC0gMSkgKiBkaWxhdGlvbnNbaV0gK1xuICAgICAgICAgIDEgLVxuICAgICAgICAgIHBhZHNbaV0gLVxuICAgICAgICAgIHBhZHNbaSArIHNwYXRpYWxSYW5rXSxcbiAgICAgICk7XG4gICAgfVxuICB9XG4gIG91dHB1dFNoYXBlLnNwbGljZSgwLCAwLCBiYXRjaFNpemUpO1xuICBvdXRwdXRTaGFwZS5zcGxpY2UoaXNDaGFubmVsTGFzdCA/IDMgOiAxLCAwLCBvdXRDaGFubmVscyk7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzIGV4dGVuZHMgQ29udkF0dHJpYnV0ZXMge1xuICByZWFkb25seSBvdXRwdXRQYWRkaW5nOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5jb25zdCBnZXRBZGp1c3RlZENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzID0gPFQgZXh0ZW5kcyBDb252VHJhbnNwb3NlQXR0cmlidXRlcz4oXG4gIGF0dHJpYnV0ZXM6IFQsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuKTogVCA9PiB7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5zbGljZSgpO1xuICAvLyBpZiBrZXJuZWxTaGFwZSBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgb3AsIGluZmVyIGl0IGZyb20gdGhlIHdlaWdodCB0ZW5zb3IgZGltc1xuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPT09IDAgfHwgYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiLCAxKSA9PT0gMCkge1xuICAgIGtlcm5lbFNoYXBlLmxlbmd0aCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDI7IGkgPCBpbnB1dHNbMV0uZGltcy5sZW5ndGg7ICsraSkge1xuICAgICAga2VybmVsU2hhcGUucHVzaChpbnB1dHNbMV0uZGltc1tpXSk7XG4gICAgfVxuICB9XG4gIGNvbnN0IGlzQ2hhbm5lbHNMYXN0ID0gYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJztcbiAga2VybmVsU2hhcGUuc3BsaWNlKDAsIDAsIGlucHV0c1sxXS5kaW1zWzBdKTtcbiAga2VybmVsU2hhcGUuc3BsaWNlKGlzQ2hhbm5lbHNMYXN0ID8gMyA6IDEsIDAsIGlucHV0c1sxXS5kaW1zWzFdKTtcblxuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5wYWRzLnNsaWNlKCk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gYXR0cmlidXRlcy5vdXRwdXRTaGFwZS5zbGljZSgpO1xuICBjb25zdCBvdXRwdXRQYWRkaW5nID0gYXR0cmlidXRlcy5vdXRwdXRQYWRkaW5nLnNsaWNlKCk7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgbGV0IGRpbGF0aW9ucyA9IGF0dHJpYnV0ZXMuZGlsYXRpb25zLnNsaWNlKCk7XG4gIGlmIChkaWxhdGlvbnMucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCkgPT09IDApIHtcbiAgICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDI7XG4gICAgZGlsYXRpb25zID0gbmV3IEFycmF5KHNwYXRpYWxSYW5rKS5maWxsKDEpO1xuICB9XG4gIGxldCBzdHJpZGVzID0gYXR0cmlidXRlcy5zdHJpZGVzLnNsaWNlKCk7XG4gIGlmIChzdHJpZGVzLnJlZHVjZSgoYSwgYikgPT4gYSArIGIsIDApID09PSAwKSB7XG4gICAgY29uc3Qgc3BhdGlhbFJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAyO1xuICAgIHN0cmlkZXMgPSBuZXcgQXJyYXkoc3BhdGlhbFJhbmspLmZpbGwoMSk7XG4gIH1cbiAgLy8gSWYgb3V0cHV0U2hhcGUgaXMgbm90IHNwZWNpZmllZCBpbiB0aGUgYXR0cmlidXRlcyBvZiB0aGlzIG9wLCBpbmZlciBpdCBmcm9tIHRoZSBwYXJhbWV0ZXJzXG4gIC8vIFNpbWlsYXJseSwgYXV0b21hdGljYWxseSBpbmZlciBwYWRzIGlmIG5vdCBzcGVjaWZpZWRcbiAgY2FsY3VsYXRlT3V0cHV0U2hhcGVBbmRQYWRzKFxuICAgIGlucHV0U2hhcGUsXG4gICAga2VybmVsU2hhcGUsXG4gICAgZGlsYXRpb25zLFxuICAgIGF0dHJpYnV0ZXMuYXV0b1BhZCxcbiAgICBhdHRyaWJ1dGVzLmdyb3VwLFxuICAgIHBhZHMsXG4gICAgc3RyaWRlcyxcbiAgICBpc0NoYW5uZWxzTGFzdCxcbiAgICBvdXRwdXRQYWRkaW5nLFxuICAgIG91dHB1dFNoYXBlLFxuICApO1xuXG4gIC8vIGFsd2F5cyByZXR1cm4gYSBuZXcgb2JqZWN0IHNvIGRvZXMgbm90IG1vZGlmeSB0aGUgb3JpZ2luYWwgYXR0cmlidXRlc1xuICBjb25zdCBuZXdBdHRyaWJ1dGVzOiBUID0gT2JqZWN0LmFzc2lnbih7fSwgYXR0cmlidXRlcyk7XG4gIE9iamVjdC5hc3NpZ24obmV3QXR0cmlidXRlcywgeyBrZXJuZWxTaGFwZSwgcGFkcywgb3V0cHV0UGFkZGluZywgb3V0cHV0U2hhcGUsIGRpbGF0aW9ucywgc3RyaWRlcyB9KTtcbiAgcmV0dXJuIG5ld0F0dHJpYnV0ZXM7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VDb252VHJhbnNwb3NlQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYWN0aXZhdGlvbkF0dHJpYnV0ZXMgPSBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMoYXR0cmlidXRlcyk7XG4gIC8vIFRPRE8gOiBNYWtlIHRoaXMgZ2VuZXJpYyBlbm91Z2ggdG8gY29tcHV0ZSBkZWZhdWx0IGF0dHJpYnV0ZXMgZm9yIG11bHRpLWRpbWVuc2lvbmFsIGNvbnZcbiAgY29uc3QgZm9ybWF0ID0gYXR0cmlidXRlcy5mb3JtYXQgYXMgJ05IV0MnIHwgJ05DSFcnO1xuICBjb25zdCBhdXRvUGFkID0gWydOT1RTRVQnLCAnVkFMSUQnLCAnU0FNRV9VUFBFUicsICdTQU1FX0xPV0VSJ11bXG4gICAgdHlwZW9mIGF0dHJpYnV0ZXMuYXV0b1BhZCA9PSAndW5kZWZpbmVkJyA/IDAgOiAoYXR0cmlidXRlcy5hdXRvUGFkIGFzIG51bWJlcilcbiAgXTtcbiAgY29uc3QgZGlsYXRpb25zID0gYXR0cmlidXRlcy5kaWxhdGlvbnMgYXMgW251bWJlciwgbnVtYmVyXTtcbiAgY29uc3QgZ3JvdXAgPSAoYXR0cmlidXRlcy5ncm91cCBhcyBudW1iZXIpID8/IDE7IC8vIGRlZmF1bHQgdG8gMSBwZXIgT05OWCBzcGVjXG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdO1xuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5wYWRzIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICBjb25zdCBzdHJpZGVzID0gYXR0cmlidXRlcy5zdHJpZGVzIGFzIFtudW1iZXIsIG51bWJlcl07XG4gIGNvbnN0IHdJc0NvbnN0ID0gKGF0dHJpYnV0ZXMud0lzQ29uc3QgYXMgKCkgPT4gYm9vbGVhbikoKTtcbiAgY29uc3Qgb3V0cHV0UGFkZGluZyA9IGF0dHJpYnV0ZXMub3V0cHV0UGFkZGluZyBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBhdHRyaWJ1dGVzLm91dHB1dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl07XG4gIHJldHVybiB7XG4gICAgYXV0b1BhZCxcbiAgICBmb3JtYXQsXG4gICAgZGlsYXRpb25zLFxuICAgIGdyb3VwLFxuICAgIGtlcm5lbFNoYXBlLFxuICAgIG91dHB1dFBhZGRpbmcsXG4gICAgb3V0cHV0U2hhcGUsXG4gICAgcGFkcyxcbiAgICBzdHJpZGVzLFxuICAgIHdJc0NvbnN0LFxuICAgIC4uLmFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuICAgIGNhY2hlS2V5OiBgJHthdHRyaWJ1dGVzLmZvcm1hdH07JHthY3RpdmF0aW9uQXR0cmlidXRlcy5hY3RpdmF0aW9ufTtgLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIC8vIFJlZmVyIHRvIHRoZSBiZWxvdyBsaW5rIGZvciBhbGwgaW5wdXQgY2hlY2tzXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9vbm54L29ubngvYmxvYi9tYWluL2RvY3MvT3BlcmF0b3JzLm1kI0NvbnZUcmFuc3Bvc2VcbiAgaWYgKCFpbnB1dHMgfHwgKGlucHV0cy5sZW5ndGggIT09IDIgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnYgcmVxdWlyZXMgMiBvciAzIGlucHV0cycpO1xuICB9XG5cbiAgLy8gVE9ETyA6IE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIG11bHRpLWRpbWVuc2lvbmFsIGNvbnZcbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCAmJiBpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2N1cnJlbnRseSBvbmx5IHN1cHBvcnQgMi1kaW1lbnNpb25hbCBjb252Jyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSBpbnB1dHNbMV0uZGltcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZpbHRlciBkb2VzIG5vdCBoYXZlIHNhbWUgZGltZW5zaW9uIGFzIGlucHV0Jyk7XG4gIH1cblxuICAvLyBGSUxURVJfSU5fQ0hBTk5FTCBzaG91bGQgYmUgZXF1YWwgdG8gREFUQV9DSEFOTkVMXG4gIGNvbnN0IGRhdGFDaGFubmVsID0gaW5wdXRzWzBdLmRpbXNbYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJyA/IGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDEgOiAxXTtcbiAgY29uc3QgZmlsdGVySW5DaGFubmVsID0gaW5wdXRzWzFdLmRpbXNbMF07XG4gIGlmIChkYXRhQ2hhbm5lbCAhPT0gZmlsdGVySW5DaGFubmVsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGSUxURVJfSU5fQ0hBTk5FTCBzaG91bGQgYmUgZXF1YWwgdG8gREFUQV9DSEFOTkVMJyk7XG4gIH1cblxuICBjb25zdCBmZWF0dXJlTWFwcyA9IGlucHV0c1sxXS5kaW1zWzFdICogYXR0cmlidXRlcy5ncm91cDtcblxuICAvLyBpZiBiaWFzIGlzIHByb3ZpZGVkIGl0IHNob3VsZCBiZSAxRCBhbmQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBzaG91bGQgYmUgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBmZWF0dXJlIG1hcHNcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgKGlucHV0c1syXS5kaW1zLmxlbmd0aCAhPT0gMSB8fCBpbnB1dHNbMl0uZGltc1swXSAhPT0gZmVhdHVyZU1hcHMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGJpYXMnKTtcbiAgfVxuXG4gIGNvbnN0IHNwYXRpYWxSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMjtcbiAgY29uc3QgZGlsYXRpb25zU2V0ID0gYXR0cmlidXRlcy5kaWxhdGlvbnMucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCkgPiAwO1xuICAvLyB3cm9uZyBkaWxhdGlvbnMgZGltZW5zaW9uXG4gIGlmIChkaWxhdGlvbnNTZXQgJiYgYXR0cmlidXRlcy5kaWxhdGlvbnMubGVuZ3RoICE9PSBzcGF0aWFsUmFuaykge1xuICAgIHRocm93IG5ldyBFcnJvcihgZGlsYXRpb25zIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIGNvbnN0IHN0cmlkZXNTZXQgPSBhdHRyaWJ1dGVzLnN0cmlkZXMucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCkgPiAwO1xuICAvLyBXcm9uZyBzdHJpZGVzIGRpbWVuc2lvblxuICBpZiAoc3RyaWRlc1NldCAmJiBhdHRyaWJ1dGVzLnN0cmlkZXMubGVuZ3RoICE9PSBzcGF0aWFsUmFuaykge1xuICAgIHRocm93IG5ldyBFcnJvcihgc3RyaWRlcyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBwYWRzIGRpbWVuc2lvblxuICBjb25zdCBwYWRzU2V0ID0gYXR0cmlidXRlcy5wYWRzLnJlZHVjZSgoYSwgYikgPT4gYSArIGIsIDApID4gMDtcbiAgaWYgKHBhZHNTZXQgJiYgYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmsgKiAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBwYWRzIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rICogMn1EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBvdXRwdXQgcGFkZGluZyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMub3V0cHV0UGFkZGluZy5sZW5ndGggIT09IHNwYXRpYWxSYW5rICYmIGF0dHJpYnV0ZXMub3V0cHV0UGFkZGluZy5sZW5ndGggIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG91dHB1dF9wYWRkaW5nIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIHNwZWNpZmllZCwgaXQncyBkYXRhIGxlbmd0aCBtdXN0IGJlIDIgbGVzcyB0aGFuIGRpbXMgbGVuZ3RoIG9mIHRoZSB3ZWlnaHRzIHRlbnNvclxuICAvLyAodGhlIGZpcnN0IDIgZGltcyBhcmUgYmF0Y2hfc2l6ZSBhbmQgY2hhbm5lbHMpXG4gIGNvbnN0IGtlcm5lbFNoYXBlU2V0ID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKSA+IDA7XG4gIGlmIChcbiAgICBrZXJuZWxTaGFwZVNldCAmJlxuICAgIGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoICE9PSAwICYmXG4gICAgYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggIT09IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAtIDJcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGtlcm5lbCBzaGFwZScpO1xuICB9XG5cbiAgLy8gYXMgd2l0aCBrZXJuZWxTaGFwZSwgbXVzdCBoYXZlIHNhbWUgbnVtYmVyIG9mIHNwYXRpYWwgZGltcyBhcyBpbnB1dFxuICBpZiAoYXR0cmlidXRlcy5vdXRwdXRTaGFwZS5sZW5ndGggIT09IDAgJiYgYXR0cmlidXRlcy5vdXRwdXRTaGFwZS5sZW5ndGggIT09IGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgb3V0cHV0IHNoYXBlJyk7XG4gIH1cbn07XG5cbmNvbnN0IGNvbnZUcmFuc3Bvc2UyZCA9IChcbiAgY29udGV4dDogQ29tcHV0ZUNvbnRleHQsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyxcbiAgc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24/OiAoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKSA9PiBudW1iZXJbXSxcbik6IHZvaWQgPT4ge1xuICAvLyBTVEVQLjE6IHRyYW5zcG9zZSB3ZWlnaHRcbiAgY29uc3QgdHJhbnNwb3NlZFdlaWdodCA9XG4gICAgKGNvbnRleHQua2VybmVsQ3VzdG9tRGF0YS53VCBhcyBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkKSA/P1xuICAgIGNvbnRleHQuY29tcHV0ZShjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyhpbnB1dHNbMV0sIFsyLCAzLCAwLCAxXSksIHtcbiAgICAgIGlucHV0czogWzFdLFxuICAgICAgb3V0cHV0czogW2F0dHJpYnV0ZXMud0lzQ29uc3QgPyAtMiA6IC0xXSxcbiAgICB9KVswXTtcbiAgaWYgKGF0dHJpYnV0ZXMud0lzQ29uc3QgJiYgIWNvbnRleHQua2VybmVsQ3VzdG9tRGF0YS53VCkge1xuICAgIGNvbnRleHQua2VybmVsQ3VzdG9tRGF0YS53VCA9IHRyYW5zcG9zZWRXZWlnaHQ7XG4gIH1cblxuICAvLyBTVEVQLjI6IHByZXBhcmUgcmVzaGFwZWQgaW5wdXRzXG4gIGNvbnN0IGNvbnZUcmFuc3Bvc2VJbnB1dHMgPSBbaW5wdXRzWzBdLCB0cmFuc3Bvc2VkV2VpZ2h0XTtcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDMpIHtcbiAgICBjb252VHJhbnNwb3NlSW5wdXRzLnB1c2goaW5wdXRzWzJdKTtcbiAgfVxuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlQ29udlRyYW5zcG9zZTJEUHJvZ3JhbUluZm8oY29udlRyYW5zcG9zZUlucHV0cywgYXR0cmlidXRlcywgc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24pLCB7XG4gICAgaW5wdXRzOiBjb252VHJhbnNwb3NlSW5wdXRzLFxuICB9KTtcbn07XG5cbmNvbnN0IGNvbnZUcmFuc3Bvc2UxZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgLy8gZXh0ZW5kIHRoZSBpbnB1dCB0byAyRCBieSBhZGRpbmcgSCBkaW1lbnNpb25cbiAgY29uc3QgaXNDaGFubmVsTGFzdCA9IGF0dHJpYnV0ZXMuZm9ybWF0ID09PSAnTkhXQyc7XG5cbiAgY29uc3QgaW5wdXRzID0gW1xuICAgIGNvbnRleHQuaW5wdXRzWzBdLnJlc2hhcGUoXG4gICAgICBpc0NoYW5uZWxMYXN0XG4gICAgICAgID8gLy8gW04sIFcsIENdIC0+IFtOLCBIPTEsIFcsIENdXG4gICAgICAgICAgW2NvbnRleHQuaW5wdXRzWzBdLmRpbXNbMF0sIDEsIGNvbnRleHQuaW5wdXRzWzBdLmRpbXNbMV0sIGNvbnRleHQuaW5wdXRzWzBdLmRpbXNbMl1dXG4gICAgICAgIDogLy8gW04sIEMsIFddIC0+IFtOLCBDLCBIPTEsIFddXG4gICAgICAgICAgW2NvbnRleHQuaW5wdXRzWzBdLmRpbXNbMF0sIGNvbnRleHQuaW5wdXRzWzBdLmRpbXNbMV0sIDEsIGNvbnRleHQuaW5wdXRzWzBdLmRpbXNbMl1dLFxuICAgICksXG4gICAgLy9bRklMVEVSX09VVF9DSEFOTkVMLCBGSUxURVJfSU5fQ0hBTk5FTCwga1ddIC0+IFtGSUxURVJfT1VUX0NIQU5ORUwsIEZJTFRFUl9JTl9DSEFOTkVMLCBrSD0xLCBrV11cbiAgICBjb250ZXh0LmlucHV0c1sxXS5yZXNoYXBlKFtjb250ZXh0LmlucHV0c1sxXS5kaW1zWzBdLCBjb250ZXh0LmlucHV0c1sxXS5kaW1zWzFdLCAxLCBjb250ZXh0LmlucHV0c1sxXS5kaW1zWzJdXSksXG4gIF07XG4gIGlmIChjb250ZXh0LmlucHV0cy5sZW5ndGggPT09IDMpIHtcbiAgICBpbnB1dHMucHVzaChjb250ZXh0LmlucHV0c1syXSk7XG4gIH1cbiAgbGV0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZTtcbiAgaWYgKGtlcm5lbFNoYXBlLmxlbmd0aCA9PT0gMCB8fCBrZXJuZWxTaGFwZVswXSA9PT0gMCkge1xuICAgIGtlcm5lbFNoYXBlID0gW2NvbnRleHQuaW5wdXRzWzFdLmRpbXNbMl1dO1xuICB9XG4gIGxldCBkaWxhdGlvbnMgPSBhdHRyaWJ1dGVzLmRpbGF0aW9ucztcbiAgaWYgKGRpbGF0aW9ucy5sZW5ndGggPT09IDAgfHwgZGlsYXRpb25zWzBdID09PSAwKSB7XG4gICAgZGlsYXRpb25zID0gWzFdO1xuICB9XG4gIGxldCBzdHJpZGVzID0gYXR0cmlidXRlcy5zdHJpZGVzO1xuICBpZiAoc3RyaWRlcy5sZW5ndGggPT09IDAgfHwgc3RyaWRlc1swXSA9PT0gMCkge1xuICAgIHN0cmlkZXMgPSBbMV07XG4gIH1cbiAgbGV0IHBhZHMgPSBhdHRyaWJ1dGVzLnBhZHM7XG4gIGlmIChwYWRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHBhZHMgPSBbMCwgMF07XG4gIH1cbiAgcGFkcyA9IFswLCBwYWRzWzBdLCAwLCBwYWRzWzFdXTtcbiAgc3RyaWRlcyA9IFsxXS5jb25jYXQoc3RyaWRlcyk7XG4gIGRpbGF0aW9ucyA9IFsxXS5jb25jYXQoZGlsYXRpb25zKTtcbiAga2VybmVsU2hhcGUgPSBbMV0uY29uY2F0KGtlcm5lbFNoYXBlKTtcbiAgbGV0IG91dHB1dFBhZGRpbmcgPSBhdHRyaWJ1dGVzLm91dHB1dFBhZGRpbmc7XG4gIG91dHB1dFBhZGRpbmcgPSBbMF0uY29uY2F0KG91dHB1dFBhZGRpbmcpO1xuICBjb25zdCBhZGp1c3RlZEF0dHJpYnV0ZXMgPSBnZXRBZGp1c3RlZENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzKFxuICAgIHsgLi4uYXR0cmlidXRlcywgcGFkcywgc3RyaWRlcywgZGlsYXRpb25zLCBrZXJuZWxTaGFwZSwgb3V0cHV0UGFkZGluZyB9LFxuICAgIGlucHV0cyxcbiAgKTtcblxuICBjb252VHJhbnNwb3NlMmQoY29udGV4dCwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMsIChvdXRwdXRTaGFwZSkgPT5cbiAgICBpc0NoYW5uZWxMYXN0ID8gW291dHB1dFNoYXBlWzBdLCBvdXRwdXRTaGFwZVsyXSwgb3V0cHV0U2hhcGVbM11dIDogW291dHB1dFNoYXBlWzBdLCBvdXRwdXRTaGFwZVsxXSwgb3V0cHV0U2hhcGVbM11dLFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbnZUcmFuc3Bvc2UgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgaWYgKGNvbnRleHQuaW5wdXRzWzBdLmRpbXMubGVuZ3RoID09PSAzKSB7XG4gICAgY29udlRyYW5zcG9zZTFkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGFkanVzdGVkQXR0cmlidXRlcyA9IGdldEFkanVzdGVkQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMoYXR0cmlidXRlcywgY29udGV4dC5pbnB1dHMpO1xuICAgIGNvbnZUcmFuc3Bvc2UyZChjb250ZXh0LCBjb250ZXh0LmlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBnZXRFbGVtZW50QXQsIGlucHV0VmFyaWFibGUsIG91dHB1dFZhcmlhYmxlLCBTaGFkZXJIZWxwZXIgfSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3VtU3VtQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGV4Y2x1c2l2ZTogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcmV2ZXJzZTogYm9vbGVhbjtcbn1cbmNvbnN0IGNyZWF0ZUN1bXN1bVByb2dyYW1JbmZvID0gKFxuICBpbnB1dFR5cGU6IG51bWJlcixcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGF4aXNJbnB1dDogVGVuc29yVmlldyxcbiAgYXR0cmlidXRlczogQ3VtU3VtQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKGlucHV0U2hhcGUpOyAvLyBvdXRwdXRTaGFwZSBpcyBzYW1lIGFzIGlucHV0U2hhcGUuXG4gIGNvbnN0IHJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDsgLy8gaW5wdXQvb3V0cHV0IHJhbmtcbiAgY29uc3QgaW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdpbnB1dCcsIGlucHV0VHlwZSwgcmFuayk7XG4gIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dFR5cGUsIHJhbmspO1xuICBjb25zdCBheGlzVmFsdWUgPVxuICAgIGF4aXNJbnB1dC5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuaW50MzIgPyBheGlzSW5wdXQuZ2V0SW50MzJBcnJheSgpWzBdIDogTnVtYmVyKGF4aXNJbnB1dC5nZXRCaWdJbnQ2NEFycmF5KClbMF0pO1xuICBjb25zdCBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXhpc1ZhbHVlLCByYW5rKTtcbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgaW5kZXggPSBgIGkzMigke2lucHV0LmluZGljZXNHZXQoJ2lucHV0SW5kaWNlcycsICd1bmlmb3Jtcy5heGlzJyl9KSBgO1xuICAgIGNvbnN0IG1heCA9IGdldEVsZW1lbnRBdCgndW5pZm9ybXMuaW5wdXRfc2hhcGUnLCAndW5pZm9ybXMuYXhpcycsIHJhbmspO1xuICAgIGNvbnN0IGxvd2VyTGltaXQgPSBhdHRyaWJ1dGVzLnJldmVyc2UgPyBpbmRleCArIChhdHRyaWJ1dGVzLmV4Y2x1c2l2ZSA/ICcgKyAxJyA6ICcnKSA6ICcwJztcbiAgICBjb25zdCB1cHBlckxpbWl0ID0gYXR0cmlidXRlcy5yZXZlcnNlID8gbWF4IDogaW5kZXggKyAoYXR0cmlidXRlcy5leGNsdXNpdmUgPyAnJyA6ICcgKyAxJyk7XG4gICAgcmV0dXJuIGBcbiAgICAgICAgICAgICAgICAke3NoYWRlckhlbHBlclxuICAgICAgICAgICAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0U2l6ZScsICd1MzInKVxuICAgICAgICAgICAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnYXhpcycsICd1MzInKVxuICAgICAgICAgICAgICAgICAgLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIG91dHB1dCl9XG4gICAgICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAgICAgICAgICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRTaXplJyl9XG4gICAgICAgICAgICAgICAgICB2YXIgaW5wdXRJbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuICAgICAgICAgICAgICAgICAgdmFyIHN1bSA9ICR7b3V0cHV0LnR5cGUudmFsdWV9KDApO1xuICAgICAgICAgICAgICAgICAgbGV0IGZpcnN0IDogaTMyID0gJHtsb3dlckxpbWl0fTtcbiAgICAgICAgICAgICAgICAgIGxldCBsYXN0IDogaTMyID0gJHt1cHBlckxpbWl0fTtcbiAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgOiBpMzIgPSBmaXJzdDsgaSA8IGxhc3Q7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAke2lucHV0LmluZGljZXNTZXQoJ2lucHV0SW5kaWNlcycsICd1bmlmb3Jtcy5heGlzJywgJ3UzMihpKScpfTtcbiAgICAgICAgICAgICAgICAgICAgc3VtID0gc3VtICsgJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0SW5kaWNlcycpfTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ3N1bScpfTtcbiAgICAgICAgICAgICAgICB9YDtcbiAgfTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnQ3VtU3VtJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LCBpbnB1dERlcGVuZGVuY2llczogWydyYW5rJ10gfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogaW5wdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0VHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtczogW1xuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYXhpcyB9LFxuICAgICAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dFNoYXBlLCBpbnB1dFNoYXBlKSxcbiAgICAgIF0sXG4gICAgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGN1bXN1bSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogQ3VtU3VtQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gY29udGV4dC5pbnB1dHNbMF0uZGltcztcbiAgY29uc3QgaW5wdXRUeXBlID0gY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGU7XG4gIGNvbnN0IGF4aXMgPSBjb250ZXh0LmlucHV0c1sxXTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUN1bXN1bVByb2dyYW1JbmZvKGlucHV0VHlwZSwgaW5wdXRTaGFwZSwgYXhpcywgYXR0cmlidXRlcyksIHsgaW5wdXRzOiBbMF0gfSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VDdW1TdW1BdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogQ3VtU3VtQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGV4Y2x1c2l2ZSA9IChhdHRyaWJ1dGVzLmV4Y2x1c2l2ZSBhcyBudW1iZXIpID09PSAxO1xuICBjb25zdCByZXZlcnNlID0gKGF0dHJpYnV0ZXMucmV2ZXJzZSBhcyBudW1iZXIpID09PSAxO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgZXhjbHVzaXZlLCByZXZlcnNlIH0pO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBJbmRpY2VzSGVscGVyLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZvcm1hdEF0dHJpYnV0ZXMge1xuICByZWFkb25seSBmb3JtYXQ6ICdOSFdDJyB8ICdOQ0hXJztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzIGV4dGVuZHMgRm9ybWF0QXR0cmlidXRlcywgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYmxvY2tzaXplOiBudW1iZXI7XG4gIHJlYWRvbmx5IG1vZGU6IHN0cmluZztcbn1cblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRGVwdGhUb1NwYWNlIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRGVwdGhUb1NwYWNlIHJlcXVpcmVzIDREIGlucHV0LicpO1xuICB9XG59O1xuXG5jb25zdCBwZXJtRnVuY3Rpb25Cb2R5ID0gKHBlcm06IG51bWJlcltdLCByYW5rOiBudW1iZXIsIGlucHV0OiBJbmRpY2VzSGVscGVyLCBvdXRwdXQ6IEluZGljZXNIZWxwZXIpOiBzdHJpbmcgPT4ge1xuICBjb25zdCByZXZlcnNlRnVuYyA9IFtdO1xuICByZXZlcnNlRnVuYy5wdXNoKGBmbiBwZXJtKGk6ICR7b3V0cHV0LnR5cGUuaW5kaWNlc30pIC0+ICR7aW5wdXQudHlwZS5pbmRpY2VzfSB7XG4gICAgdmFyIGE6ICR7aW5wdXQudHlwZS5pbmRpY2VzfTtgKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICByZXZlcnNlRnVuYy5wdXNoKGlucHV0LmluZGljZXNTZXQoJ2EnLCBwZXJtW2ldLCBgaVske2l9XWApKTtcbiAgfVxuICByZXZlcnNlRnVuYy5wdXNoKCdyZXR1cm4gYTt9Jyk7XG4gIHJldHVybiByZXZlcnNlRnVuYy5qb2luKCdcXG4nKTtcbn07XG5cbmNvbnN0IGNyZWF0ZURlcHRoVG9TcGFjZVByb2dyYW1JbmZvID0gKGlucHV0VGVuc29yOiBUZW5zb3JWaWV3LCBhdHRyaWJ1dGVzOiBEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICBsZXQgbjogbnVtYmVyLCBoOiBudW1iZXIsIHc6IG51bWJlciwgYzogbnVtYmVyO1xuICBsZXQgc2hhcGU6IG51bWJlcltdO1xuICBsZXQgcGVybTogbnVtYmVyW107XG4gIGNvbnN0IGlzQ2hhbm5lbExhc3QgPSBhdHRyaWJ1dGVzLmZvcm1hdCA9PT0gJ05IV0MnO1xuICBjb25zdCBibG9ja3NpemUgPSBhdHRyaWJ1dGVzLmJsb2Nrc2l6ZTtcbiAgY29uc3QgaXNEQ1Jtb2RlID0gYXR0cmlidXRlcy5tb2RlID09PSAnRENSJztcbiAgaWYgKGlzQ2hhbm5lbExhc3QpIHtcbiAgICBbbiwgaCwgdywgY10gPSBpbnB1dFRlbnNvci5kaW1zO1xuICAgIHNoYXBlID0gaXNEQ1Jtb2RlXG4gICAgICA/IFtuLCBoLCB3LCBibG9ja3NpemUsIGJsb2Nrc2l6ZSwgYyAvIGJsb2Nrc2l6ZSAqKiAyXVxuICAgICAgOiBbbiwgaCwgdywgYyAvIGJsb2Nrc2l6ZSAqKiAyLCBibG9ja3NpemUsIGJsb2Nrc2l6ZV07XG4gICAgcGVybSA9IGlzRENSbW9kZSA/IFswLCAxLCAzLCAyLCA0LCA1XSA6IFswLCAxLCA0LCAyLCA1LCAzXTtcbiAgfSBlbHNlIHtcbiAgICBbbiwgaCwgdywgY10gPSBbaW5wdXRUZW5zb3IuZGltc1swXSwgaW5wdXRUZW5zb3IuZGltc1syXSwgaW5wdXRUZW5zb3IuZGltc1szXSwgaW5wdXRUZW5zb3IuZGltc1sxXV07XG4gICAgc2hhcGUgPSBpc0RDUm1vZGVcbiAgICAgID8gW24sIGJsb2Nrc2l6ZSwgYmxvY2tzaXplLCBjIC8gYmxvY2tzaXplICoqIDIsIGgsIHddXG4gICAgICA6IFtuLCBjIC8gYmxvY2tzaXplICoqIDIsIGJsb2Nrc2l6ZSwgYmxvY2tzaXplLCBoLCB3XTtcbiAgICBwZXJtID0gaXNEQ1Jtb2RlID8gWzAsIDMsIDQsIDEsIDUsIDJdIDogWzAsIDEsIDQsIDIsIDUsIDNdO1xuICB9XG4gIGNvbnN0IHJlc2hhcGVkSW5wdXRUZW5zb3IgPSBpbnB1dFRlbnNvci5yZXNoYXBlKHNoYXBlKTtcbiAgY29uc3QgcmVzaGFwZWRJbnB1dFJhbmsgPSByZXNoYXBlZElucHV0VGVuc29yLmRpbXMubGVuZ3RoO1xuICBjb25zdCBpbnB1dERhdGFUeXBlID0gaW5wdXRUZW5zb3IuZGF0YVR5cGU7XG5cbiAgY29uc3QgcmVzaGFwZWRJbnB1dCA9IGlucHV0VmFyaWFibGUoJ2EnLCBpbnB1dERhdGFUeXBlLCByZXNoYXBlZElucHV0UmFuayk7XG4gIGNvbnN0IHBlcm1lZE91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dERhdGFUeXBlLCByZXNoYXBlZElucHV0UmFuayk7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiBgXG4gICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0X3NpemUnLCAndTMyJykuZGVjbGFyZVZhcmlhYmxlcyhyZXNoYXBlZElucHV0LCBwZXJtZWRPdXRwdXQpfVxuXG4gICR7cGVybUZ1bmN0aW9uQm9keShwZXJtLCByZXNoYXBlZElucHV0UmFuaywgcmVzaGFwZWRJbnB1dCwgcGVybWVkT3V0cHV0KX1cblxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRfc2l6ZScpfVxuXG4gICAgbGV0IGluZGljZXMgPSAke3Blcm1lZE91dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG4gICAgbGV0IGFJbmRpY2VzID0gcGVybShpbmRpY2VzKTtcblxuICAgICR7cGVybWVkT3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgcmVzaGFwZWRJbnB1dC5nZXRCeUluZGljZXMoJ2FJbmRpY2VzJykpfVxuICB9YDtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdEZXB0aFRvU3BhY2UnLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHtpbnB1dFRlbnNvci5kaW1zfTske2F0dHJpYnV0ZXMuYmxvY2tzaXplfTske2F0dHJpYnV0ZXMubW9kZX1gLFxuICAgICAgaW5wdXREZXBlbmRlbmNpZXM6IFsncmFuayddLFxuICAgIH0sXG4gICAgZ2V0UnVuRGF0YTogKGlucHV0cykgPT4ge1xuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpc0NoYW5uZWxMYXN0XG4gICAgICAgID8gW24sIGggKiBibG9ja3NpemUsIHcgKiBibG9ja3NpemUsIGMgLyBibG9ja3NpemUgKiogMl1cbiAgICAgICAgOiBbbiwgYyAvIGJsb2Nrc2l6ZSAqKiAyLCBoICogYmxvY2tzaXplLCB3ICogYmxvY2tzaXplXTtcbiAgICAgIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gICAgICBjb25zdCBzaGFwZUJlZm9yZVBlcm0gPSByZXNoYXBlZElucHV0VGVuc29yLmRpbXM7XG4gICAgICBjb25zdCBzaGFwZUFmdGVyUGVybSA9IFNoYXBlVXRpbC5zb3J0QmFzZWRPblBlcm0oc2hhcGVCZWZvcmVQZXJtLCBwZXJtKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH1dLFxuICAgICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICAgIHByb2dyYW1Vbmlmb3JtczogW1xuICAgICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgICAgICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoc2hhcGVCZWZvcmVQZXJtLCBzaGFwZUFmdGVyUGVybSksXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGRlcHRoVG9TcGFjZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogRGVwdGhUb1NwYWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVEZXB0aFRvU3BhY2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgYXR0cmlidXRlcykpO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlRGVwdGhUb1NwYWNlQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IERlcHRoVG9TcGFjZUF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBibG9ja3NpemU6IGF0dHJpYnV0ZXMuYmxvY2tzaXplIGFzIG51bWJlcixcbiAgICBtb2RlOiBhdHRyaWJ1dGVzLm1vZGUgYXMgc3RyaW5nLFxuICAgIGZvcm1hdDogYXR0cmlidXRlcy5mb3JtYXQgYXMgJ05IV0MnIHwgJ05DSFcnLFxuICB9KTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcywgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciB9IGZyb20gJy4vY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBFaW5zdW1BdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgZXF1YXRpb246IHN0cmluZztcbn1cbi8vIFRoZSBlcXVhdGlvbiBhdHRyaWJ1dGUgdmFsdWUgaXMgYSBzdHJpbmcgd2hpY2ggY29uc2lzdHMgb2YgbGVmdCBoYW5kIHNpZGUgKExIUykgYW5kIG9wdGlvbmFsbHkgcmlnaHQgaGFuZCBzaWRlIChSSFMpXG4vLyBzZXBhcmF0ZWQgYnkgJy0+Jy4gRXguIFwiaWosamsgLT4gaWtcIiBleHByZXNzZXMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG4vLyAgICAgXCJpai0+amlcIiBleHByZXNzZXMgbWF0cml4IHRyYW5zcG9zZVxuLy8gICAgICBcImlpLT5pXCIgZGlhZ29uYWwgZWxlbWVudHMgb2YgYSBzcXVhcmUgbWF0cml4XG4vLyBMSFMgY29uc2lzdHMgb2YgYSBzZXF1ZW5jZSBvZiB0ZXJtcyBzZXBhcmF0ZWQgYnkgY29tbWFzLiBFYWNoIHRlcm0gY29ycmVzcG9uZHMgdG8gYW4gaW5wdXQgdmFyaWFibGUuXG4vLyBFYWNoIHN5bWJvbCBjb3JyZXNwb25kcyB0byBhIGRpbWVuc2lvbiBpbiB0aGUgaW5wdXQgdmFyaWFibGUuIFRoZSBzeW1ib2wgY2FuIGJlIGVpdGhlciBhIGxldHRlciwgJ2EnIHRvICd6JyBvciAnQScgdG9cbi8vICdaJyBvciAnLi4uJyB0byByZXByZXNlbnQgYXJiaXRyYXJ5IGRpbWVuc2lvbnMuXG5cbmNvbnN0IHN5bWJvbFBhdHRlcm4gPSAnW2EtekEtWl18XFxcXC5cXFxcLlxcXFwuJzsgLy8gVGhlIHBhdHRlcm4gZWFjaCBzeW1ib2wgaW4gZWFjaCB0ZXJtIGluIHRoZSBzeW1ib2xpYyBlcXVhdGlvbiBzaG91bGQgbWF0Y2hcbmNvbnN0IHRlcm1QYXR0ZXJuID0gJygnICsgc3ltYm9sUGF0dGVybiArICcpKyc7IC8vIFRoZSBwYXR0ZXJuIGVhY2ggdGVybSBpbiB0aGUgc3ltYm9saWMgZXF1YXRpb24gc2hvdWxkIG1hdGNoXG5jb25zdCB0ZXJtUGF0dGVybk9ubHkgPSAnXicgKyB0ZXJtUGF0dGVybiArICckJzsgLy8gVGhlIHBhdHRlcm5zIG9ubHkgbWF0Y2hlcyBhIHRlcm0gYmVnaW4gdG8gZW5kLlxuY29uc3QgbGhzUGF0dGVybiA9ICcoJyArIHRlcm1QYXR0ZXJuICsgJywpKicgKyB0ZXJtUGF0dGVybjsgLy8gVGhlIHBhdHRlcm4gdGhlIExIUyBzaG91bGQgbWF0Y2hcbmNvbnN0IGxoc1BhdHRlcm5Pbmx5ID0gJ14nICsgbGhzUGF0dGVybiArICckJzsgLy8gVGhlIHBhdHRlcm5zIG9ubHkgbWF0Y2hlcyBhIExIUyBiZWdpbiB0byBlbmQuXG5cbmludGVyZmFjZSBTeW1ib2xJbmZvIHtcbiAgY291bnQ6IG51bWJlcjsgLy8gU3ltYm9sIGNvcnJlc3BvbmRpbmcgdG8gYSBkaW1lbnNpb24gb2YgYW4gaW5wdXRcbiAgaW5wdXRJbmRpY2VzOiBudW1iZXJbXTsgLy8gTnVtYmVyIG9mIGlucHV0IHZhcmlhYmxlcyB0aGUgc3ltYm9sIGNvcnJlc3BvbmRzIHRvXG4gIGRpbVZhbHVlOiBudW1iZXI7IC8vIE51bWJlciBvZiBkaW1lbnNpb25zIHRoZSBzeW1ib2wgY29ycmVzcG9uZHMgdG9cbn1cblxuY2xhc3MgRWluc3VtVGVybSB7XG4gIGNvbnN0cnVjdG9yKGlucHV0SW5kZXggPSAtMSkge1xuICAgIHRoaXMuc3ltYm9sVG9JbmRpY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcltdPigpO1xuICAgIHRoaXMuaW5wdXRJbmRleCA9IGlucHV0SW5kZXg7XG4gIH1cblxuICAvLyBBZGQgYSBzeW1ib2wgdG8gdGhlIHRlcm1cbiAgYWRkU3ltYm9sKHN5bWJvbDogc3RyaW5nLCBpbmRleDogbnVtYmVyKSB7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5zeW1ib2xUb0luZGljZXMuZ2V0KHN5bWJvbCk7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhbHVlID0gW2luZGV4XTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUucHVzaChpbmRleCk7XG4gICAgfVxuICAgIHRoaXMuc3ltYm9sVG9JbmRpY2VzLnNldChzeW1ib2wsIHZhbHVlKTtcbiAgfVxuXG4gIHN5bWJvbFRvSW5kaWNlczogTWFwPHN0cmluZywgbnVtYmVyW10+OyAvLyBNYXAgZnJvbSBzeW1ib2wgdG8gZGltZW5zaW9ucyBvZiB0aGUgaW5wdXQgY29ycmVzcG9uZGluZyB0byB0aGUgdGVybVxuICBpbnB1dEluZGV4OiBudW1iZXI7IC8vIC0xIGZvciBvdXRwdXQgYW5kIDAsIDEsIDIsIC4uLiBmb3IgaW5wdXRzXG59XG5cbmNsYXNzIEVpbnN1bUVxdWF0aW9uIHtcbiAgY29uc3RydWN0b3IoXG4gICAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gICAgcHVibGljIHJlYWRvbmx5IGVxdWF0aW9uOiBzdHJpbmcsXG4gICkge1xuICAgIHRoaXMuaGFzRWxsaXBzaXMgPSBmYWxzZTtcbiAgICB0aGlzLnN5bWJvbFRvSW5mbyA9IG5ldyBNYXA8c3RyaW5nLCBTeW1ib2xJbmZvPigpO1xuICAgIHRoaXMubGhzID0gbmV3IEFycmF5PEVpbnN1bVRlcm0+KCk7XG4gICAgdGhpcy5vdXRwdXREaW1zID0gW107XG4gICAgLy8gQXMgcmhzIG5lZWRzIHRvIGJlIHVwZGF0ZWQgYWxsb3cgdXNpbmcgbGV0IGluc3RlYWQgb2YgY29uc3QgZm9yIGJvdGggbGhzIGFuZCByaHMuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdFxuICAgIGxldCBbbGhzLCByaHNdID0gZXF1YXRpb24uaW5jbHVkZXMoJy0+JykgPyBlcXVhdGlvbi5zcGxpdCgnLT4nLCAyKSA6IFtlcXVhdGlvbiwgJyddO1xuICAgIGlmICghbGhzLm1hdGNoKFJlZ0V4cChsaHNQYXR0ZXJuT25seSkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgTEhTIHRlcm0nKTtcbiAgICB9XG4gICAgY29uc3QgaW5wdXRUZXJtcyA9IGxocy5zcGxpdCgnLCcpO1xuICAgIGlucHV0VGVybXMuZm9yRWFjaCgoaW5wdXRUZXJtLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgZGltcyA9IGlucHV0c1tpbmRleF0uZGltcy5zbGljZSgpO1xuICAgICAgaWYgKCFpbnB1dFRlcm0ubWF0Y2goUmVnRXhwKHRlcm1QYXR0ZXJuT25seSkpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBMSFMgdGVybScpO1xuICAgICAgfVxuICAgICAgY29uc3QgZWluc3VtVGVybSA9IHRoaXMucHJvY2Vzc1Rlcm0oaW5wdXRUZXJtLCB0cnVlLCBkaW1zLCBpbmRleCk7XG4gICAgICB0aGlzLmxocy5wdXNoKGVpbnN1bVRlcm0pO1xuICAgIH0pO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgUkhTIGlmIG5vdCBzcGVjaWZpZWRcbiAgICBpZiAocmhzID09PSAnJykge1xuICAgICAgLy8gQ29uc3RydWN0IFJIUyBmcm9tIExIUyB0ZXJtcy9zeW1ib2xzXG4gICAgICByaHMgKz0gWy4uLnRoaXMuc3ltYm9sVG9JbmZvLmVudHJpZXMoKV1cbiAgICAgICAgLmZpbHRlcigoW3N5bSwgaW5mb10pID0+IGluZm8uY291bnQgPT09IDEgfHwgc3ltID09PSAnLi4uJylcbiAgICAgICAgLm1hcCgoW3N5bV0pID0+IHN5bSlcbiAgICAgICAgLmpvaW4oJycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXJocy5tYXRjaChSZWdFeHAodGVybVBhdHRlcm4pKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUkhTJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ29tcHV0ZSBvdXRwdXQgZGltc1xuICAgIGNvbnN0IHJoc1N5bWJvbHMgPSByaHMubWF0Y2goUmVnRXhwKHN5bWJvbFBhdHRlcm4sICdnJykpO1xuICAgIHJoc1N5bWJvbHM/LmZvckVhY2goKHN5bWJvbCkgPT4ge1xuICAgICAgaWYgKHN5bWJvbCA9PT0gJy4uLicpIHtcbiAgICAgICAgdGhpcy5vdXRwdXREaW1zID0gdGhpcy5vdXRwdXREaW1zLmNvbmNhdCh0aGlzLmVsbGlwc2lzRGltcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBpbmZvID0gdGhpcy5zeW1ib2xUb0luZm8uZ2V0KHN5bWJvbCk7XG4gICAgICAgIGlmIChpbmZvID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUkhTIHN5bWJvbCcpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3V0cHV0RGltcy5wdXNoKGluZm8uZGltVmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMucmhzID0gdGhpcy5wcm9jZXNzVGVybShyaHMsIGZhbHNlLCB0aGlzLm91dHB1dERpbXMpO1xuICB9IC8vIEVuZCBvZiBFaW5zdW1FcWF0aW9uIGNvbnN0cnVjdG9yXG5cbiAgLy8gQWRkIGEgc3ltYm9sIHRvIHRoZSBlcXVhdGlvblxuICBhZGRTeW1ib2woc3ltYm9sOiBzdHJpbmcsIGRpbVZhbHVlOiBudW1iZXIsIGlucHV0SW5kZXg6IG51bWJlcikge1xuICAgIGxldCBpbmZvID0gdGhpcy5zeW1ib2xUb0luZm8uZ2V0KHN5bWJvbCk7XG4gICAgaWYgKGluZm8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGluZm8uZGltVmFsdWUgIT09IGRpbVZhbHVlICYmIGluZm8uY291bnQgIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEaW1lbnNpb24gbWlzbWF0Y2gnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZm8uY291bnQrKztcbiAgICAgICAgaW5mby5pbnB1dEluZGljZXMucHVzaChpbnB1dEluZGV4KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaW5mbyA9IHsgY291bnQ6IDEsIGRpbVZhbHVlLCBpbnB1dEluZGljZXM6IFtpbnB1dEluZGV4XSB9O1xuICAgIH1cbiAgICB0aGlzLnN5bWJvbFRvSW5mby5zZXQoc3ltYm9sLCBpbmZvKTtcbiAgfVxuXG4gIC8vIFByb2Nlc3Mgb25lIGlucHV0L291dHB1dCB0ZXJtXG4gIHByb2Nlc3NUZXJtKHRlcm06IHN0cmluZywgaXNJbnB1dDogYm9vbGVhbiwgZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGluZGV4ID0gLTEpOiBFaW5zdW1UZXJtIHtcbiAgICBjb25zdCByYW5rID0gZGltcy5sZW5ndGg7XG4gICAgbGV0IGVsbGlwc2lzID0gZmFsc2U7XG4gICAgbGV0IGVsbGlwc2lzRGltcyA9IFtdO1xuICAgIGxldCBuZXh0RGltID0gMDtcbiAgICAvLyBGb3Igb3V0cHV0IGVtcHR5IHN0cmluZyBpcyBhbGxvd2VkIGJlY2F1c2UgdGhlIG91dHB1dCBtYXkgYmUgcmVkdWNlZCB0byBhIHNjYWxhciB2YWx1ZVxuICAgIGlmICghdGVybS5tYXRjaChSZWdFeHAodGVybVBhdHRlcm5Pbmx5KSkgJiYgIWlzSW5wdXQgJiYgdGVybSAhPT0gJycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBMSFMgdGVybScpO1xuICAgIH1cbiAgICBjb25zdCBpbmRleFN5bWJvbHMgPSB0ZXJtLm1hdGNoKFJlZ0V4cChzeW1ib2xQYXR0ZXJuLCAnZycpKTtcbiAgICBjb25zdCBlaW5zdW1UZXJtID0gbmV3IEVpbnN1bVRlcm0oaW5kZXgpO1xuICAgIC8vIHN5bWJvbCBjYW4gYmUgZWl0aGVyIGEgbGV0dHJlLCAnYScgdG8gJ3onIG9yICdBJyB0byAnWicsIG9yICcuLi4nXG4gICAgaW5kZXhTeW1ib2xzPy5mb3JFYWNoKChzeW1ib2w6IHN0cmluZywgaTogbnVtYmVyKSA9PiB7XG4gICAgICBpZiAoc3ltYm9sID09PSAnLi4uJykge1xuICAgICAgICBpZiAoZWxsaXBzaXMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ09ubHkgb25lIGVsbGlwc2lzIGlzIGFsbG93ZWQgcGVyIGlucHV0IHRlcm0nKTtcbiAgICAgICAgfVxuICAgICAgICBlbGxpcHNpcyA9IHRydWU7XG4gICAgICAgIGNvbnN0IGVsbGlwc2lzRGltTGVuZ3RoID0gcmFuayAtIGluZGV4U3ltYm9scy5sZW5ndGggKyAxO1xuICAgICAgICBpZiAoZWxsaXBzaXNEaW1MZW5ndGggPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFbGxpcHNpcyBvdXQgb2YgYm91bmRzJyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxsaXBzaXNEaW1zID0gZGltcy5zbGljZShuZXh0RGltLCBuZXh0RGltICsgZWxsaXBzaXNEaW1MZW5ndGgpO1xuICAgICAgICBpZiAodGhpcy5oYXNFbGxpcHNpcykge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuZWxsaXBzaXNEaW1zLmxlbmd0aCAhPT0gZWxsaXBzaXNEaW1zLmxlbmd0aCB8fFxuICAgICAgICAgICAgdGhpcy5lbGxpcHNpc0RpbXMudG9TdHJpbmcoKSAhPT0gZWxsaXBzaXNEaW1zLnRvU3RyaW5nKClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRWxsaXBzaXMgZGltZW5zaW9ucyBtaXNtYXRjaCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChpc0lucHV0KSB7XG4gICAgICAgICAgdGhpcy5oYXNFbGxpcHNpcyA9IHRydWU7XG4gICAgICAgICAgdGhpcy5lbGxpcHNpc0RpbXMgPSBlbGxpcHNpc0RpbXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFbGxpcHNpcyBtdXN0IGJlIHNwZWNpZmllZCBpbiB0aGUgTEhTJyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQWRkICcwJywgJzEnLCAnMicsICczJywgJzQnLCBldGMgdG8gcmVwcmVzZW50IGVsbGlwc2lzIGRpbWVuc2lvbnMgdG8gYXZvaWQgc3BlY2lhbCBoYW5kbGluZ1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGVsbGlwc2lzRGltcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgIGNvbnN0IHN5bWJvbCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoJzAnLmNoYXJDb2RlQXQoMCkgKyBqKTtcbiAgICAgICAgICBlaW5zdW1UZXJtLmFkZFN5bWJvbChzeW1ib2wsIGkgKyBqKTtcbiAgICAgICAgICB0aGlzLmFkZFN5bWJvbChzeW1ib2wsIGRpbXNbbmV4dERpbSsrXSwgaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlaW5zdW1UZXJtLmFkZFN5bWJvbChzeW1ib2wsIGkgKyAodGhpcy5oYXNFbGxpcHNpcyA/IHRoaXMuZWxsaXBzaXNEaW1zLmxlbmd0aCAtIDEgOiAwKSk7XG4gICAgICAgIHRoaXMuYWRkU3ltYm9sKHN5bWJvbCwgZGltc1tuZXh0RGltKytdLCBpbmRleCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGVpbnN1bVRlcm07XG4gIH1cblxuICBzeW1ib2xUb0luZm86IE1hcDxzdHJpbmcsIFN5bWJvbEluZm8+OyAvLyBBbGwgc3ltYm9scyBpbiB0aGUgZXF1YXRpb25cbiAgaGFzRWxsaXBzaXM6IGJvb2xlYW47IC8vIFRoZSBlcXVhdGlvbiBoYXMgZWxsaXBzaXMgb3Igbm90XG4gIGVsbGlwc2lzRGltczogbnVtYmVyW107IC8vIFRoZSBkaW1lbnNpb25zIG9mIHRoZSBlcXVhdGlvbiBlbGxpcHNpcyBjb3JyZXNwb25kcyB0by5cbiAgbGhzOiBFaW5zdW1UZXJtW107IC8vIFRlcm1zIG9uIHRoZSBsZWZ0LWhhbmQgc2lkZSBvZiB0aGUgZXF1YXRpb25cbiAgcmhzOiBFaW5zdW1UZXJtOyAvLyBUZXJtIG9uIHRoZSByaWdodC1oYW5kIHNpZGUgb2YgdGhlIGVxdWF0aW9uXG4gIG91dHB1dERpbXM6IG51bWJlcltdOyAvLyBPdXRwdXQgZGltZW5zaW9ucyBvZiB0aGUgZXF1YXRpb25cbn0gLy8gRW5kIG9mIGNsYXNzIEVpbnN1bUVxdWF0aW9uXG5cbmNvbnN0IGFwcGVuZE1heCA9IChuYW1lOiBzdHJpbmcpOiBzdHJpbmcgPT4gbmFtZSArICdfbWF4JztcblxuY29uc3QgY3JlYXRlRWluc3VtUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0U2hhcGVzOiBBcnJheTxyZWFkb25seSBudW1iZXJbXT4sXG4gIGRhdGFUeXBlOiBudW1iZXIsXG4gIGVpbnN1bUVxdWF0aW9uOiBFaW5zdW1FcXVhdGlvbixcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCByYW5rcyA9IGlucHV0U2hhcGVzLm1hcCgoZGltcykgPT4gZGltcy5sZW5ndGgpO1xuICBjb25zdCBpbnB1dFZhcnMgPSByYW5rcy5tYXAoKHJhbmssIGluZGV4KSA9PiBpbnB1dFZhcmlhYmxlKGBpbnB1dCR7aW5kZXh9YCwgZGF0YVR5cGUsIHJhbmspKTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCB1bmlmb3Jtc1N5bWJvbHMgPSBbLi4uZWluc3VtRXF1YXRpb24uc3ltYm9sVG9JbmZvLmtleXMoKV0uZmlsdGVyKFxuICAgIChzeW1ib2wpID0+ICFlaW5zdW1FcXVhdGlvbi5yaHMuc3ltYm9sVG9JbmRpY2VzLmhhcyhzeW1ib2wpLFxuICApO1xuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBpZHhDb3B5OiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IGluaXRQcm9kID0gJ3ZhciBwcm9kID0gMS4wOyc7XG4gICAgY29uc3QgaW5pdFN1bSA9ICd2YXIgc3VtID0gMC4wOyc7XG4gICAgY29uc3QgdXBkYXRlU3VtID0gJ3N1bSArPSBwcm9kOyc7XG4gICAgY29uc3QgcmVkdWNlT3BzU2V0SW5kaWNlczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCByZWR1Y2VPcHNMb29wSGVhZGVyczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCByZWR1Y2VPcHNMb29wRm9vdGVyczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCByZWR1Y2VPcENvbXB1dGU6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgaXNSZWR1Y2VPcHNXaXRob3V0TG9vcCA9IGVpbnN1bUVxdWF0aW9uLnN5bWJvbFRvSW5mby5zaXplID09PSBlaW5zdW1FcXVhdGlvbi5yaHMuc3ltYm9sVG9JbmRpY2VzLnNpemU7XG4gICAgZWluc3VtRXF1YXRpb24uc3ltYm9sVG9JbmZvLmZvckVhY2goKGluZm8sIHN5bWJvbCkgPT4ge1xuICAgICAgaWYgKGVpbnN1bUVxdWF0aW9uLnJocy5zeW1ib2xUb0luZGljZXMuaGFzKHN5bWJvbCkpIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0SW5kZXggPSBlaW5zdW1FcXVhdGlvbi5yaHMuc3ltYm9sVG9JbmRpY2VzLmdldChzeW1ib2wpPy5bMF07XG4gICAgICAgIGlmIChvdXRwdXRJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgZWluc3VtRXF1YXRpb24ubGhzLmZvckVhY2goKHRlcm0sIGkpID0+IHtcbiAgICAgICAgICAgIGlmIChpbmZvLmlucHV0SW5kaWNlcy5pbmNsdWRlcyhpKSkge1xuICAgICAgICAgICAgICBjb25zdCBpbmRpY2VzID0gdGVybS5zeW1ib2xUb0luZGljZXMuZ2V0KHN5bWJvbCk7XG4gICAgICAgICAgICAgIGlmIChpbmRpY2VzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3ltYm9sIGVycm9yJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaW5kaWNlcy5mb3JFYWNoKChpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGlkeENvcHkucHVzaChcbiAgICAgICAgICAgICAgICAgIGAke2lucHV0VmFyc1tpXS5pbmRpY2VzU2V0KFxuICAgICAgICAgICAgICAgICAgICBgaW5wdXQke2l9SW5kaWNlc2AsXG4gICAgICAgICAgICAgICAgICAgIGluZGV4LFxuICAgICAgICAgICAgICAgICAgICBvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0SW5kaWNlcycsIG91dHB1dEluZGV4KSxcbiAgICAgICAgICAgICAgICAgICl9YCxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWluc3VtRXF1YXRpb24ubGhzLmZvckVhY2goKHRlcm0sIGkpID0+IHtcbiAgICAgICAgICBpZiAoaW5mby5pbnB1dEluZGljZXMuaW5jbHVkZXMoaSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGluZGljZXMgPSB0ZXJtLnN5bWJvbFRvSW5kaWNlcy5nZXQoc3ltYm9sKTtcbiAgICAgICAgICAgIGlmIChpbmRpY2VzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN5bWJvbCBlcnJvcicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5kaWNlcy5mb3JFYWNoKChpbmRleCkgPT4ge1xuICAgICAgICAgICAgICByZWR1Y2VPcHNTZXRJbmRpY2VzLnB1c2goYCR7aW5wdXRWYXJzW2ldLmluZGljZXNTZXQoYGlucHV0JHtpfUluZGljZXNgLCBpbmRleCwgYCR7c3ltYm9sfWApfWApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZWR1Y2VPcENvbXB1dGUucHVzaChgcHJvZCAqPSAke2lucHV0VmFyc1tpXS5nZXRCeUluZGljZXMoYGlucHV0JHtpfUluZGljZXNgKX07YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmVkdWNlT3BzTG9vcEhlYWRlcnMucHVzaChcbiAgICAgICAgICBgZm9yKHZhciAke3N5bWJvbH06IHUzMiA9IDA7ICR7c3ltYm9sfSA8IHVuaWZvcm1zLiR7YXBwZW5kTWF4KHN5bWJvbCl9OyAke3N5bWJvbH0rKykge2AsXG4gICAgICAgICk7XG4gICAgICAgIHJlZHVjZU9wc0xvb3BGb290ZXJzLnB1c2goJ30nKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCByZWR1Y2VPcHMgPSBpc1JlZHVjZU9wc1dpdGhvdXRMb29wXG4gICAgICA/IFtcbiAgICAgICAgICAuLi5pZHhDb3B5LFxuICAgICAgICAgIGBsZXQgc3VtID0gJHtpbnB1dFZhcnMubWFwKChpbnB1dFZhciwgaSkgPT4gaW5wdXRWYXIuZ2V0QnlJbmRpY2VzKGBpbnB1dCR7aX1JbmRpY2VzYCkpLmpvaW4oJyAqICcpfTtgLFxuICAgICAgICBdXG4gICAgICA6IFtcbiAgICAgICAgICAuLi5pZHhDb3B5LFxuICAgICAgICAgIGluaXRTdW0sXG4gICAgICAgICAgLi4ucmVkdWNlT3BzTG9vcEhlYWRlcnMsXG4gICAgICAgICAgLi4ucmVkdWNlT3BzU2V0SW5kaWNlcyxcbiAgICAgICAgICBpbml0UHJvZCxcbiAgICAgICAgICAuLi5yZWR1Y2VPcENvbXB1dGUsXG4gICAgICAgICAgdXBkYXRlU3VtLFxuICAgICAgICAgIC4uLnJlZHVjZU9wc0xvb3BGb290ZXJzLFxuICAgICAgICBdO1xuICAgIHJldHVybiBgXG4gICAgICAgICAgICAke3NoYWRlckhlbHBlclxuICAgICAgICAgICAgICAucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3Jtc1N5bWJvbHMubWFwKChzeW1ib2wpID0+ICh7IG5hbWU6IGAke2FwcGVuZE1heChzeW1ib2wpfWAsIHR5cGU6ICd1MzInIH0pKSlcbiAgICAgICAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0U2l6ZScsICd1MzInKVxuICAgICAgICAgICAgICAuZGVjbGFyZVZhcmlhYmxlcyguLi5pbnB1dFZhcnMsIG91dHB1dCl9XG5cbiAgICAgICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0U2l6ZScpfVxuICAgICAgICAgICAgdmFyIG91dHB1dEluZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG4gICAgICAgICAgICAke2lucHV0VmFycy5tYXAoKF92YXIsIGkpID0+IGB2YXIgaW5wdXQke2l9SW5kaWNlczogJHtpbnB1dFZhcnNbaV0udHlwZS5pbmRpY2VzfTtgKS5qb2luKCdcXG4nKX1cbiAgICAgICAgICAgICR7cmVkdWNlT3BzLmpvaW4oJ1xcbicpfTtcbiAgICAgICAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ3N1bScpfTtcbiAgICAgICAgICB9YDtcbiAgfTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnRWluc3VtJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBlaW5zdW1FcXVhdGlvbi5lcXVhdGlvbiwgaW5wdXREZXBlbmRlbmNpZXM6IGlucHV0U2hhcGVzLm1hcCgoKSA9PiAncmFuaycpIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4ge1xuICAgICAgLy8gVGhlIHN5bWJvbHMgZnJvbSB1bmlmb3JtU3ltYm9scyBhcnJheSBhcmUgZ3VhcmFudGVlZCB0byBleGlzdCBpbiBlaW5zdW1FcXVhdGlvbnMuc3ltYm9sVG9JbmZvIG1hcC4gVGhlXG4gICAgICAvLyBmaWx0ZXIgaXMgYWRkZWQgdG8gbWFrZSBzdXJlIHRoYXQgZGltVmFsdWUgaXMgbmV2ZXIgMC5cbiAgICAgIGNvbnN0IHByb2dyYW1Vbmlmb3Jtc0luaXQ6IFByb2dyYW1Vbmlmb3JtW10gPSB1bmlmb3Jtc1N5bWJvbHNcbiAgICAgICAgLmZpbHRlcigoc3ltYm9sKSA9PiBlaW5zdW1FcXVhdGlvbi5zeW1ib2xUb0luZm8uaGFzKHN5bWJvbCkpXG4gICAgICAgIC5tYXAoKHN5bWJvbCkgPT4gKHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBlaW5zdW1FcXVhdGlvbi5zeW1ib2xUb0luZm8uZ2V0KHN5bWJvbCk/LmRpbVZhbHVlIHx8IDAgfSkpO1xuICAgICAgcHJvZ3JhbVVuaWZvcm1zSW5pdC5wdXNoKHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0pO1xuICAgICAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gaW5wdXRTaGFwZXNcbiAgICAgICAgLm1hcCgoZGltcywgXykgPT4gWy4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGRpbXMpXSlcbiAgICAgICAgLnJlZHVjZSgoYWNjLCBpbnB1dFByb2dyYW1Vbmlmb3JtcykgPT4gYWNjLmNvbmNhdChpbnB1dFByb2dyYW1Vbmlmb3JtcyksIHByb2dyYW1Vbmlmb3Jtc0luaXQpO1xuICAgICAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMob3V0cHV0U2hhcGUpKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZSB9XSxcbiAgICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgICB9O1xuICAgIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGVpbnN1bSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogRWluc3VtQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBlaW5zdW1FcXVhdGlvbiA9IG5ldyBFaW5zdW1FcXVhdGlvbihjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcy5lcXVhdGlvbik7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gZWluc3VtRXF1YXRpb24ub3V0cHV0RGltcztcbiAgY29uc3QgaW5wdXRTaGFwZXMgPSBjb250ZXh0LmlucHV0cy5tYXAoKGlucHV0LCBfKSA9PiBpbnB1dC5kaW1zKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVpbnN1bVByb2dyYW1JbmZvKGlucHV0U2hhcGVzLCBjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSwgZWluc3VtRXF1YXRpb24sIG91dHB1dFNoYXBlKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VFaW5zdW1BdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogRWluc3VtQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGVxdWF0aW9uID0gKGF0dHJpYnV0ZXMuZXF1YXRpb24gYXMgc3RyaW5nKS5yZXBsYWNlKC9cXHMrL2csICcnKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGVxdWF0aW9uIH0pO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcywgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciB9IGZyb20gJy4vY29tbW9uJztcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignRXhwYW5kIHJlcXVpcmVzIDIgaW5wdXQuJyk7XG4gIH1cbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBzaGFwZSA9IEFycmF5LmZyb20oaW5wdXRzWzFdLmdldEJpZ0ludDY0QXJyYXkoKSwgTnVtYmVyKTtcblxuICBsZXQgc2hhcGVJbmRleCA9IHNoYXBlLmxlbmd0aCA8IGlucHV0U2hhcGUubGVuZ3RoID8gMCA6IHNoYXBlLmxlbmd0aCAtIGlucHV0U2hhcGUubGVuZ3RoO1xuICBsZXQgaW5wdXRTaGFwZUluZGV4ID0gaW5wdXRTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGggPyAwIDogaW5wdXRTaGFwZS5sZW5ndGggLSBzaGFwZS5sZW5ndGg7XG4gIGZvciAoOyBzaGFwZUluZGV4IDwgc2hhcGUubGVuZ3RoICYmIGlucHV0U2hhcGVJbmRleCA8IGlucHV0U2hhcGUubGVuZ3RoOyArK3NoYXBlSW5kZXgsICsraW5wdXRTaGFwZUluZGV4KSB7XG4gICAgaWYgKFxuICAgICAgc2hhcGVbc2hhcGVJbmRleF0gIT09IGlucHV0U2hhcGVbaW5wdXRTaGFwZUluZGV4XSAmJlxuICAgICAgc2hhcGVbc2hhcGVJbmRleF0gIT09IDEgJiZcbiAgICAgIGlucHV0U2hhcGVbaW5wdXRTaGFwZUluZGV4XSAhPT0gMVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBhbmQgcmVxdWlyZXMgc2hhcGUgdG8gYmUgYnJvYWRjYXN0YWJsZSB0byBpbnB1dCcpO1xuICAgIH1cbiAgfVxufTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRTaGFwZSA9IChzaGFwZTE6IHJlYWRvbmx5IG51bWJlcltdLCBzaGFwZTI6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCBkaWZmID0gc2hhcGUxLmxlbmd0aCAtIHNoYXBlMi5sZW5ndGg7XG4gIGNvbnN0IHNoYXBlOiBudW1iZXJbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGRpZmY7ICsraSkge1xuICAgIHNoYXBlLnB1c2goc2hhcGUxW2ldKTtcbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNoYXBlMi5sZW5ndGg7ICsraSkge1xuICAgIHNoYXBlLnB1c2goc2hhcGUyW2ldID09PSAxID8gc2hhcGUxW2kgKyBkaWZmXSA6IHNoYXBlMltpXSk7XG4gIH1cbiAgcmV0dXJuIHNoYXBlO1xufTtcblxuY29uc3QgY2FsY3VsYXRlT3V0cHV0U2hhcGUgPSAoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlcltdID0+XG4gIGlucHV0U2hhcGUubGVuZ3RoID4gc2hhcGUubGVuZ3RoID8gZ2V0QWRqdXN0ZWRTaGFwZShpbnB1dFNoYXBlLCBzaGFwZSkgOiBnZXRBZGp1c3RlZFNoYXBlKHNoYXBlLCBpbnB1dFNoYXBlKTtcblxuY29uc3QgY3JlYXRlRXhwYW5kUHJvZ3JhbUluZm8gPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qgc2hhcGUgPSBBcnJheS5mcm9tKGlucHV0c1sxXS5nZXRCaWdJbnQ2NEFycmF5KCksIE51bWJlcik7XG4gIGNvbnN0IG91dHB1dFNoYXBlOiBudW1iZXJbXSA9IGNhbGN1bGF0ZU91dHB1dFNoYXBlKGlucHV0U2hhcGUsIHNoYXBlKTtcbiAgY29uc3QgZGF0YVR5cGUgPSBpbnB1dHNbMF0uZGF0YVR5cGU7XG4gIGNvbnN0IGlzQm9vbE9yU2NhbGFyID0gZGF0YVR5cGUgPT09IERhdGFUeXBlLmJvb2wgfHwgU2hhcGVVdGlsLnNpemUoaW5wdXRTaGFwZSkgPT09IDE7XG4gIGNvbnN0IGlDb21wb25lbnRzID1cbiAgICBkYXRhVHlwZSA9PT0gRGF0YVR5cGUuYm9vbCA/IDQgOiBpbnB1dFNoYXBlLmxlbmd0aCA+IDAgJiYgaW5wdXRTaGFwZVtpbnB1dFNoYXBlLmxlbmd0aCAtIDFdICUgNCA9PT0gMCA/IDQgOiAxO1xuICBjb25zdCBjb21wb25lbnRzID0gaXNCb29sT3JTY2FsYXJcbiAgICA/IDRcbiAgICA6IG91dHB1dFNoYXBlLmxlbmd0aCA+IDAgJiYgb3V0cHV0U2hhcGVbb3V0cHV0U2hhcGUubGVuZ3RoIC0gMV0gJSA0ID09PSAwXG4gICAgICA/IDRcbiAgICAgIDogMTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IE1hdGguY2VpbChTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSkgLyBjb21wb25lbnRzKTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBpbnB1dCA9IGlucHV0VmFyaWFibGUoJ2lucHV0JywgZGF0YVR5cGUsIGlucHV0U2hhcGUubGVuZ3RoLCBpQ29tcG9uZW50cyk7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgIGxldCBhc3NpZ25tZW50OiBzdHJpbmc7XG4gICAgaWYgKGRhdGFUeXBlID09PSBEYXRhVHlwZS5ib29sKSB7XG4gICAgICBjb25zdCBzaW5nbGVBc3NpZ25tZW50ID0gKHJlc1N0cjogc3RyaW5nLCB4OiBudW1iZXIsIHR5cGVDYXN0ID0gJycpID0+IGBcbiAgICAgICAgICBsZXQgb3V0cHV0SW5kaWNlcyR7eH0gPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoYG91dHB1dE9mZnNldCArICR7eH11YCl9O1xuICAgICAgICAgIGxldCBvZmZzZXQke3h9ID0gJHtpbnB1dC5icm9hZGNhc3RlZEluZGljZXNUb09mZnNldChgb3V0cHV0SW5kaWNlcyR7eH1gLCBvdXRwdXQpfTtcbiAgICAgICAgICBsZXQgaW5kZXgke3h9ID0gb2Zmc2V0JHt4fSAvIDR1O1xuICAgICAgICAgIGxldCBjb21wb25lbnQke3h9ID0gb2Zmc2V0JHt4fSAlIDR1O1xuICAgICAgICAgICR7cmVzU3RyfVske3h9XSA9ICR7dHlwZUNhc3R9KCR7aW5wdXQuZ2V0QnlPZmZzZXQoYGluZGV4JHt4fWApfVtjb21wb25lbnQke3h9XSk7XG4gICAgICAgIGA7XG4gICAgICBhc3NpZ25tZW50ID0gYFxuICAgICAgICBsZXQgb3V0cHV0T2Zmc2V0ID0gZ2xvYmFsX2lkeCAqICR7Y29tcG9uZW50c307XG4gICAgICAgIHZhciBkYXRhID0gdmVjNDx1MzI+KDApO1xuICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ2RhdGEnLCAwLCAndTMyJyl9XG4gICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnZGF0YScsIDEsICd1MzInKX1cbiAgICAgICAgJHtzaW5nbGVBc3NpZ25tZW50KCdkYXRhJywgMiwgJ3UzMicpfVxuICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ2RhdGEnLCAzLCAndTMyJyl9XG4gICAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ2RhdGEnKX1cbiAgICAgIH1gO1xuICAgIH0gZWxzZSB7XG4gICAgICBhc3NpZ25tZW50ID0gYFxuICAgICAgICBsZXQgb3V0cHV0SW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcyhgZ2xvYmFsX2lkeCAqICR7Y29tcG9uZW50c31gKX07XG4gICAgICAgIGxldCBpbnB1dE9mZnNldCA9ICR7aW5wdXQuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQoJ291dHB1dEluZGljZXMnLCBvdXRwdXQpfTtcbiAgICAgICAgbGV0IGRhdGEgPSAke291dHB1dC50eXBlLnZhbHVlfSgke2lucHV0LmdldEJ5T2Zmc2V0KGBpbnB1dE9mZnNldCAvICR7aUNvbXBvbmVudHN9YCl9KTtcbiAgICAgICAgJHtvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAnZGF0YScpfVxuICAgICAgfWA7XG4gICAgfVxuICAgIHJldHVybiBgXG4gICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3JtKCd2ZWNfc2l6ZScsICd1MzInKS5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCBvdXRwdXQpfVxuICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLnZlY19zaXplJyl9XG4gICAgJHthc3NpZ25tZW50fWA7XG4gIH07XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRTaGFwZSwgb3V0cHV0U2hhcGUpLFxuICBdO1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdFeHBhbmQnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke291dHB1dFNoYXBlLmxlbmd0aH07JHtpQ29tcG9uZW50c30ke2NvbXBvbmVudHN9YCwgaW5wdXREZXBlbmRlbmNpZXM6IFsncmFuayddIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBleHBhbmQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRXhwYW5kUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMpLCB7IGlucHV0czogWzBdIH0pO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxuICBXT1JLR1JPVVBfU0laRSxcbn0gZnJvbSAnLi9jb21tb24nO1xuaW1wb3J0ICogYXMgdW5hcnkgZnJvbSAnLi91bmFyeS1vcCc7XG5cbi8vIEdFTFUgaXMgZGVmaW5lZCBhcyBZPTAuNSpYKigxK3RhbmgoMC43OTc4ODUqWCswLjAzNTY3NypYKlgqWCkpLCB3aGVyZSBYIG1heSBwcmUtYWRkIGEgYmlhcy5cblxuY29uc3QgY3JlYXRlRmFzdEdlbHVQcm9ncmFtSW5mbyA9IChpbnB1dFRlbnNvcnM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZGF0YVR5cGUgPSBpbnB1dFRlbnNvcnNbMF0uZGF0YVR5cGU7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShpbnB1dFRlbnNvcnNbMF0uZGltcyk7XG4gIGNvbnN0IGJpYXNMZW5ndGggPSBTaGFwZVV0aWwuc2l6ZShpbnB1dFRlbnNvcnNbMV0uZGltcyk7XG4gIC8vIGNhbiBvbmx5IHVzZSB2ZWM0IHdoZW4gYmlhcyBsZW5ndGggaXMgbXVsdGlwbGUgb2YgNFxuICBjb25zdCB1c2VWZWM0ID0gYmlhc0xlbmd0aCAlIDQgPT09IDA7XG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcik6IHN0cmluZyA9PiB7XG4gICAgY29uc3QgeCA9IGlucHV0VmFyaWFibGUoJ3gnLCBkYXRhVHlwZSwgWzFdLCA0KTtcbiAgICBjb25zdCBiaWFzID0gaW5wdXRWYXJpYWJsZSgnYmlhcycsIGRhdGFUeXBlLCBbMV0sIDQpO1xuICAgIGNvbnN0IHkgPSBvdXRwdXRWYXJpYWJsZSgneScsIGRhdGFUeXBlLCBbMV0sIDQpO1xuXG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3ZlY19zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2JpYXNfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgXTtcblxuICAgIGNvbnN0IHNpbmdsZUVsZW1lbnRCaWFzID0gKGk6IDAgfCAxIHwgMiB8IDMpID0+IGBcbiAgICAgIGxldCBiaWFzJHtpfV9vZmZzZXQ6IHUzMiA9IChnbG9iYWxfaWR4ICogNCArICR7aX0pICUgdW5pZm9ybXMuYmlhc19zaXplO1xuICAgICAgbGV0IGJpYXMke2l9ID0gJHtiaWFzLmdldEJ5T2Zmc2V0KGBiaWFzJHtpfV9vZmZzZXQgLyA0YCl9W2JpYXMke2l9X29mZnNldCAlIDRdO2A7XG4gICAgY29uc3QgYmlhc0dldEV4cHJlc3Npb24gPSB1c2VWZWM0XG4gICAgICA/IGBcbiAgICAgIGxldCBiaWFzID0gJHtiaWFzLmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4ICUgKHVuaWZvcm1zLmJpYXNfc2l6ZSAvIDQpJyl9O2BcbiAgICAgIDogYCR7c2luZ2xlRWxlbWVudEJpYXMoMCl9JHtzaW5nbGVFbGVtZW50QmlhcygxKX0ke3NpbmdsZUVsZW1lbnRCaWFzKDIpfSR7c2luZ2xlRWxlbWVudEJpYXMoMyl9XG4gICAgICBsZXQgYmlhcyA9ICR7eC50eXBlLnZhbHVlfShiaWFzMCwgYmlhczEsIGJpYXMyLCBiaWFzMyk7YDtcblxuICAgIHJldHVybiBgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyh4LCBiaWFzLCB5KX1cblxuICAgICR7dW5hcnkuZmFzdEdlbHVJbXBsKHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoZGF0YVR5cGUpKX1cblxuICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydChXT1JLR1JPVVBfU0laRSl9XG4gICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRfdmVjX3NpemUnKX1cblxuICAgICAgbGV0IHggPSAke3guZ2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnKX07XG4gICAgICAke2JpYXNHZXRFeHByZXNzaW9ufVxuICAgICAgbGV0IHhfaW4gPSB4ICsgYmlhcztcbiAgICAgICR7eS5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsIHVuYXJ5LmZhc3RHZWx1RXhwcmVzc2lvbigneF9pbicpKX1cbiAgICB9YDtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdGYXN0R2VsdVdpdGhCaWFzJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHt1c2VWZWM0fWAsIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3R5cGUnLCAndHlwZSddIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6IChpbnB1dHMpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBpbnB1dHNbMF0uZGltcywgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtczogW1xuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA0KSB9LFxuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYmlhc0xlbmd0aCB9LFxuICAgICAgXSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyBXT1JLR1JPVVBfU0laRSAvIDQpIH0sXG4gICAgfSksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgZmFzdEdlbHUgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgaWYgKGNvbnRleHQuaW5wdXRzLmxlbmd0aCA8IDIgfHwgU2hhcGVVdGlsLnNpemUoY29udGV4dC5pbnB1dHNbMV0uZGltcykgPT09IDApIHtcbiAgICB1bmFyeS5mYXN0R2VsdShjb250ZXh0KTtcbiAgfSBlbHNlIHtcbiAgICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRmFzdEdlbHVQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0cykpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEdhdGhlckF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBheGlzOiBudW1iZXI7XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dhdGhlciByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxufTtcblxuY29uc3QgY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm8gPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IEdhdGhlckF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgaW5kaWNlc1NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG5cbiAgY29uc3QgaW5wdXRSYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0UmFuayk7XG5cbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNoYXBlLnNsaWNlKDApO1xuICBvdXRwdXRTaGFwZS5zcGxpY2UoYXhpcywgMSwgLi4uaW5kaWNlc1NoYXBlKTtcblxuICBjb25zdCBheGlzRGltTGltaXQgPSBpbnB1dFNoYXBlW2F4aXNdO1xuICBjb25zdCBjb21wb25lbnRzID0gaW5wdXRzWzBdLmRhdGFUeXBlID09PSBEYXRhVHlwZS5ib29sID8gNCA6IDE7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBNYXRoLmNlaWwoU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpIC8gY29tcG9uZW50cyk7XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS5pbnQzMiwgZGF0YTogYXhpc0RpbUxpbWl0IH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGF4aXMgfSxcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmRpbXMsIG91dHB1dFNoYXBlKSxcbiAgXTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBkYXRhID0gaW5wdXRWYXJpYWJsZSgnZGF0YScsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBpbmRpY2VzID0gaW5wdXRWYXJpYWJsZSgnaW5wdXRJbmRpY2VzJywgaW5wdXRzWzFdLmRhdGFUeXBlLCBpbnB1dHNbMV0uZGltcy5sZW5ndGgpO1xuICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlLmxlbmd0aCwgY29tcG9uZW50cyk7XG5cbiAgICBjb25zdCBjYWxjRGF0YUluZGljZXMgPSAoeDogbnVtYmVyIHwgc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICAgIGNvbnN0IGluZGljZXNSYW5rID0gaW5kaWNlc1NoYXBlLmxlbmd0aDtcbiAgICAgIGxldCBjYWxjU3RyID0gYHZhciBpbmRpY2VzSW5kaWNlcyR7eH0gID0gJHtpbmRpY2VzLnR5cGUuaW5kaWNlc30oMCk7YDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlc1Jhbms7IGkrKykge1xuICAgICAgICBjYWxjU3RyICs9IGAke2luZGljZXNSYW5rID4gMSA/IGBpbmRpY2VzSW5kaWNlcyR7eH1bJHtpfV1gIDogYGluZGljZXNJbmRpY2VzJHt4fWB9ID0gJHtcbiAgICAgICAgICBvdXRwdXRTaGFwZS5sZW5ndGggPiAxID8gYG91dHB1dEluZGljZXMke3h9W3VuaWZvcm1zLmF4aXMgKyAke2l9XWAgOiBgb3V0cHV0SW5kaWNlcyR7eH1gXG4gICAgICAgIH07YDtcbiAgICAgIH1cbiAgICAgIGNhbGNTdHIgKz0gYFxuICAgICAgICAgIHZhciBpZHgke3h9ID0gJHtpbmRpY2VzLmdldEJ5SW5kaWNlcyhgaW5kaWNlc0luZGljZXMke3h9YCl9O1xuICAgICAgICAgIGlmIChpZHgke3h9IDwgMCkge1xuICAgICAgICAgICAgaWR4JHt4fSA9IGlkeCR7eH0gKyB1bmlmb3Jtcy5heGlzRGltTGltaXQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciBkYXRhSW5kaWNlcyR7eH0gOiAke2RhdGEudHlwZS5pbmRpY2VzfTtcbiAgICAgICAgYDtcbiAgICAgIGZvciAobGV0IGkgPSAwLCBqID0gMDsgaSA8IGlucHV0UmFuazsgaSsrKSB7XG4gICAgICAgIGlmIChpID09PSBheGlzKSB7XG4gICAgICAgICAgY2FsY1N0ciArPSBgJHtpbnB1dFJhbmsgPiAxID8gYGRhdGFJbmRpY2VzJHt4fVske2l9XWAgOiBgZGF0YUluZGljZXMke3h9YH0gPSB1MzIoaWR4JHt4fSk7YDtcbiAgICAgICAgICBqICs9IGluZGljZXNSYW5rO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNhbGNTdHIgKz0gYCR7aW5wdXRSYW5rID4gMSA/IGBkYXRhSW5kaWNlcyR7eH1bJHtpfV1gIDogYGRhdGFJbmRpY2VzJHt4fWB9ID0gJHtcbiAgICAgICAgICAgIG91dHB1dFNoYXBlLmxlbmd0aCA+IDEgPyBgb3V0cHV0SW5kaWNlcyR7eH1bJHtqfV1gIDogYG91dHB1dEluZGljZXMke3h9YFxuICAgICAgICAgIH07YDtcbiAgICAgICAgICBqKys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBjYWxjU3RyO1xuICAgIH07XG4gICAgbGV0IGFzc2lnbm1lbnQ6IHN0cmluZztcbiAgICBpZiAoaW5wdXRzWzBdLmRhdGFUeXBlID09PSBEYXRhVHlwZS5ib29sKSB7XG4gICAgICBjb25zdCBzaW5nbGVBc3NpZ25tZW50ID0gKHJlc1N0cjogc3RyaW5nLCB4OiBudW1iZXIsIHR5cGVDYXN0ID0gJycpID0+IGBcbiAgICAgICAgICBsZXQgb3V0cHV0SW5kaWNlcyR7eH0gPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoYG91dHB1dE9mZnNldCArICR7eH11YCl9O1xuICAgICAgICAgICR7Y2FsY0RhdGFJbmRpY2VzKHgpfTtcbiAgICAgICAgICBsZXQgb2Zmc2V0JHt4fSA9ICR7ZGF0YS5pbmRpY2VzVG9PZmZzZXQoYGRhdGFJbmRpY2VzJHt4fWApfTtcbiAgICAgICAgICBsZXQgaW5kZXgke3h9ID0gb2Zmc2V0JHt4fSAvIDR1O1xuICAgICAgICAgIGxldCBjb21wb25lbnQke3h9ID0gb2Zmc2V0JHt4fSAlIDR1O1xuICAgICAgICAgICR7cmVzU3RyfVske3h9XSA9ICR7dHlwZUNhc3R9KCR7ZGF0YS5nZXRCeU9mZnNldChgaW5kZXgke3h9YCl9W2NvbXBvbmVudCR7eH1dKTtcbiAgICAgICAgYDtcbiAgICAgIGFzc2lnbm1lbnQgPSBgXG4gICAgICAgIGxldCBvdXRwdXRPZmZzZXQgPSBnbG9iYWxfaWR4ICogJHtjb21wb25lbnRzfTtcbiAgICAgICAgdmFyIHZhbHVlID0gdmVjNDx1MzI+KDApO1xuICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ3ZhbHVlJywgMCwgJ3UzMicpfVxuICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ3ZhbHVlJywgMSwgJ3UzMicpfVxuICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ3ZhbHVlJywgMiwgJ3UzMicpfVxuICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ3ZhbHVlJywgMywgJ3UzMicpfVxuICAgICAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICd2YWx1ZScpfVxuICAgICAgYDtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzaWdubWVudCA9IGBcbiAgICAgIGxldCBvdXRwdXRJbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuICAgICAgJHtjYWxjRGF0YUluZGljZXMoJycpfTtcbiAgICAgIGxldCB2YWx1ZSA9ICR7ZGF0YS5nZXRCeUluZGljZXMoJ2RhdGFJbmRpY2VzJyl9O1xuICAgICAgJHtvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAndmFsdWUnKX07XG4gICAgICBgO1xuICAgIH1cbiAgICByZXR1cm4gYFxuICAgICAgJHtzaGFkZXJIZWxwZXJcbiAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0U2l6ZScsICd1MzInKVxuICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdheGlzRGltTGltaXQnLCAnaTMyJylcbiAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnYXhpcycsICd1MzInKVxuICAgICAgICAuZGVjbGFyZVZhcmlhYmxlcyhkYXRhLCBpbmRpY2VzLCBvdXRwdXQpfVxuICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dFNpemUnKX1cbiAgICAgICAgJHthc3NpZ25tZW50fVxuICAgICAgfWA7XG4gIH07XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0dhdGhlcicsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgaW5wdXREZXBlbmRlbmNpZXM6IFsncmFuaycsICdyYW5rJ10gfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR2F0aGVyQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEdhdGhlckF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpczogYXR0cmlidXRlcy5heGlzIGFzIG51bWJlciB9KTtcblxuZXhwb3J0IGNvbnN0IGdhdGhlciA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogR2F0aGVyQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBjb250ZXh0LmlucHV0cztcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUdhdGhlclByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyLCBVbmlmb3Jtc0FycmF5VHlwZSB9IGZyb20gJy4vY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBHYXRoZXJOREF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBiYXRjaERpbXM6IG51bWJlcjtcbn1cblxuY29uc3QgY29tcHV0ZVNsaWNlT2Zmc2V0cyA9IChcbiAgY29udGV4dDogQ29tcHV0ZUNvbnRleHQsXG4gIGluZGljZXNEYXRhOiBUZW5zb3JWaWV3LFxuICBzaXplc0Zyb21TbGljZURpbXNEYXRhOiBudW1iZXJbXSxcbiAgYmF0Y2hEaW1zOiBudW1iZXIsXG4gIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG51bVNsaWNlczogbnVtYmVyLFxuICBudW1TbGljZXNQZXJCYXRjaDogbnVtYmVyLFxuICBpbnB1dEJhdGNoU3RyaWRlOiBudW1iZXIsXG4gIG51bVNsaWNlRGltczogbnVtYmVyLFxuKSA9PiB7XG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogbnVtU2xpY2VzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGJhdGNoRGltcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBpbnB1dERpbXMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogc2l6ZXNGcm9tU2xpY2VEaW1zRGF0YSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBudW1TbGljZXNQZXJCYXRjaCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBpbnB1dEJhdGNoU3RyaWRlIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG51bVNsaWNlRGltcyB9LFxuICBdO1xuXG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW251bVNsaWNlc107XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGluZGljZXNEYXRhLmRpbXMsIG91dHB1dFNoYXBlKSk7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgaW5kaWNlcyA9IGlucHV0VmFyaWFibGUoJ2luZGljZXNfZGF0YScsIGluZGljZXNEYXRhLmRhdGFUeXBlLCBpbmRpY2VzRGF0YS5kaW1zLmxlbmd0aCk7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ2lucHV0X3NsaWNlX29mZnNldHNfZGF0YScsIERhdGFUeXBlLnVpbnQzMiwgMSwgMSk7XG4gICAgY29uc3QgdmFyaWFibGVzID0gW2luZGljZXMsIG91dHB1dF07XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnYmF0Y2hfZGltcycsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdpbnB1dF9kaW1zJywgdHlwZTogJ3UzMicsIGxlbmd0aDogaW5wdXREaW1zLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAnc2l6ZXNfZnJvbV9zbGljZV9kaW1zX2RhdGEnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiBzaXplc0Zyb21TbGljZURpbXNEYXRhLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAnbnVtX3NsaWNlc19wZXJfYmF0Y2gnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnaW5wdXRfYmF0Y2hfc3RyaWRlJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ251bV9zbGljZV9kaW1zJywgdHlwZTogJ3UzMicgfSxcbiAgICBdO1xuICAgIHJldHVybiBgXG4gICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4udmFyaWFibGVzKX1cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX1cbiAgICBsZXQgYmF0Y2hfaWR4ID0gZ2xvYmFsX2lkeCAvIHVuaWZvcm1zLm51bV9zbGljZXNfcGVyX2JhdGNoO1xuICAgIGxldCBiYXNlX29mZnNldCA9IGJhdGNoX2lkeCAqIHVuaWZvcm1zLmlucHV0X2JhdGNoX3N0cmlkZTtcblxuICAgIGxldCBzbGljZV9pbmRpY2VzX2Jhc2Vfb2Zmc2V0ID0gZ2xvYmFsX2lkeCAqIHVuaWZvcm1zLm51bV9zbGljZV9kaW1zO1xuICAgIHZhciByZWxhdGl2ZV9zbGljZV9vZmZzZXQgPSAwO1xuICAgIGZvciAodmFyIGRpbV9pZHggPSAwdTsgZGltX2lkeCA8IHVuaWZvcm1zLm51bV9zbGljZV9kaW1zOyBkaW1faWR4ICsrKSB7XG4gICAgICB2YXIgaW5kZXggPSBpMzIoaW5kaWNlc19kYXRhW2RpbV9pZHggKyBzbGljZV9pbmRpY2VzX2Jhc2Vfb2Zmc2V0XS54KTtcbiAgICAgIGxldCBpbnB1dF9kaW1faWR4ID0gdW5pZm9ybXMuYmF0Y2hfZGltcyArIGRpbV9pZHg7XG4gICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgICR7XG4gICAgICAgICAgaW5wdXREaW1zLmxlbmd0aCA9PT0gMVxuICAgICAgICAgICAgPyAnaW5kZXggKz0gaTMyKHVuaWZvcm1zLmlucHV0X2RpbXMpOydcbiAgICAgICAgICAgIDogJ2luZGV4ICs9IGkzMih1bmlmb3Jtcy5pbnB1dF9kaW1zW2lucHV0X2RpbV9pZHhdKTsnXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgICR7XG4gICAgICAgIHNpemVzRnJvbVNsaWNlRGltc0RhdGEubGVuZ3RoID09PSAxXG4gICAgICAgICAgPyAncmVsYXRpdmVfc2xpY2Vfb2Zmc2V0ICs9IGluZGV4ICogaTMyKHVuaWZvcm1zLnNpemVzX2Zyb21fc2xpY2VfZGltc19kYXRhKTsnXG4gICAgICAgICAgOiAncmVsYXRpdmVfc2xpY2Vfb2Zmc2V0ICs9IGluZGV4ICogaTMyKHVuaWZvcm1zLnNpemVzX2Zyb21fc2xpY2VfZGltc19kYXRhW2RpbV9pZHhdKTsnXG4gICAgICB9XG4gICAgfVxuXG4gICAgaW5wdXRfc2xpY2Vfb2Zmc2V0c19kYXRhW2dsb2JhbF9pZHhdID0gIGJhc2Vfb2Zmc2V0ICsgdTMyKHJlbGF0aXZlX3NsaWNlX29mZnNldCk7XG4gIH1gO1xuICB9O1xuXG4gIHJldHVybiBjb250ZXh0LmNvbXB1dGUoXG4gICAge1xuICAgICAgbmFtZTogJ2NvbXB1dGVTbGljZU9mZnNldHMnLFxuICAgICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYCR7aW5wdXREaW1zLmxlbmd0aH1fJHtzaXplc0Zyb21TbGljZURpbXNEYXRhLmxlbmd0aH1gLCBpbnB1dERlcGVuZGVuY2llczogWydyYW5rJ10gfSxcbiAgICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogY29udGV4dC5pbnB1dHNbMV0uZGF0YVR5cGUgfV0sXG4gICAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG51bVNsaWNlcyAvIDY0KSB9LFxuICAgICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgICB9KSxcbiAgICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICB9LFxuICAgIHsgaW5wdXRzOiBbaW5kaWNlc0RhdGFdLCBvdXRwdXRzOiBbLTFdIH0sXG4gIClbMF07XG59O1xuXG5leHBvcnQgY29uc3QgZ2F0aGVyTkQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEdhdGhlck5EQXR0cmlidXRlcykgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBjb250ZXh0LmlucHV0cztcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbnB1dFR5cGUgPSBpbnB1dHNbMF0uZGF0YVR5cGU7XG4gIGNvbnN0IGluZGljZXNTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBudW1TbGljZURpbXMgPSBpbmRpY2VzU2hhcGVbaW5kaWNlc1NoYXBlLmxlbmd0aCAtIDFdO1xuICBjb25zdCBudW1TbGljZXMgPSBTaGFwZVV0aWwuc2l6ZVRvRGltZW5zaW9uKGluZGljZXNTaGFwZSwgaW5kaWNlc1NoYXBlLmxlbmd0aCAtIDEpO1xuICBjb25zdCBzbGljZVNpemUgPSBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24oaW5wdXRTaGFwZSwgYXR0cmlidXRlcy5iYXRjaERpbXMgKyBudW1TbGljZURpbXMpO1xuICBjb25zdCBudW1CYXRjaGVzID0gU2hhcGVVdGlsLnNpemVUb0RpbWVuc2lvbihpbnB1dFNoYXBlLCBhdHRyaWJ1dGVzLmJhdGNoRGltcyk7XG4gIGNvbnN0IGlucHV0QmF0Y2hTdHJpZGUgPSBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24oaW5wdXRTaGFwZSwgYXR0cmlidXRlcy5iYXRjaERpbXMpO1xuICBjb25zdCBudW1TbGljZXNQZXJCYXRjaCA9IG51bVNsaWNlcyAvIG51bUJhdGNoZXM7XG4gIGNvbnN0IHNpemVzRnJvbVNsaWNlRGltcyA9IG5ldyBBcnJheShudW1TbGljZURpbXMpO1xuICBsZXQgcnVubmluZ1Byb2R1Y3QgPSBzbGljZVNpemU7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtU2xpY2VEaW1zOyArK2kpIHtcbiAgICBzaXplc0Zyb21TbGljZURpbXNbbnVtU2xpY2VEaW1zIC0gMSAtIGldID0gcnVubmluZ1Byb2R1Y3Q7XG4gICAgcnVubmluZ1Byb2R1Y3QgKj0gaW5wdXRTaGFwZVthdHRyaWJ1dGVzLmJhdGNoRGltcyArIG51bVNsaWNlRGltcyAtIDEgLSBpXTtcbiAgfVxuXG4gIGNvbnN0IGlucHV0U2xpY2VPZmZzZXRzID0gY29tcHV0ZVNsaWNlT2Zmc2V0cyhcbiAgICBjb250ZXh0LFxuICAgIGlucHV0c1sxXSxcbiAgICBzaXplc0Zyb21TbGljZURpbXMsXG4gICAgYXR0cmlidXRlcy5iYXRjaERpbXMsXG4gICAgaW5wdXRTaGFwZSxcbiAgICBudW1TbGljZXMsXG4gICAgbnVtU2xpY2VzUGVyQmF0Y2gsXG4gICAgaW5wdXRCYXRjaFN0cmlkZSxcbiAgICBudW1TbGljZURpbXMsXG4gICk7XG5cbiAgY29uc3QgbGFzdEluZGljZXNEaW1lbnNpb24gPSBhdHRyaWJ1dGVzLmJhdGNoRGltcyArIG51bVNsaWNlRGltcztcbiAgaWYgKGxhc3RJbmRpY2VzRGltZW5zaW9uID4gaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2xhc3QgZGltZW5zaW9uIG9mIGluZGljZXMgbXVzdCBub3QgYmUgbGFyZ2VyIHRoYW4gcmFuayBvZiBpbnB1dCB0ZW5zb3InKTtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5kaWNlc1NoYXBlLnNsaWNlKDAsIC0xKS5jb25jYXQoaW5wdXRTaGFwZS5zbGljZShsYXN0SW5kaWNlc0RpbWVuc2lvbikpO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBzbGljZVNpemUgfSxcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMF0uZGltcywgaW5wdXRTbGljZU9mZnNldHMuZGltcywgb3V0cHV0U2hhcGUpLFxuICBdO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnZGF0YScsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgICBjb25zdCBpbmRpY2VzID0gaW5wdXRWYXJpYWJsZSgnc2xpY2Vfb2Zmc2V0cycsIERhdGFUeXBlLnVpbnQzMiwgaW5wdXRTbGljZU9mZnNldHMuZGltcy5sZW5ndGgpO1xuXG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgICByZXR1cm4gYFxuICAgICAgICAgICR7c2hhZGVySGVscGVyXG4gICAgICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdvdXRwdXRfc2l6ZScsICd1MzInKVxuICAgICAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnc2xpY2Vfc2l6ZScsICd1MzInKVxuICAgICAgICAgICAgLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIGluZGljZXMsIG91dHB1dCl9XG4gICAgICAgICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAgICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgICAgICAgbGV0IHNsaWNlX29mZnNldCA9IHNsaWNlX29mZnNldHNbZ2xvYmFsX2lkeCAvIHVuaWZvcm1zLnNsaWNlX3NpemVdO1xuICAgICAgICAgIG91dHB1dFtnbG9iYWxfaWR4XSA9IGRhdGFbdTMyKHNsaWNlX29mZnNldCkgKyBnbG9iYWxfaWR4ICUgdW5pZm9ybXMuc2xpY2Vfc2l6ZV07XG4gICAgICAgIH1gO1xuICB9O1xuICBjb250ZXh0LmNvbXB1dGUoXG4gICAge1xuICAgICAgbmFtZTogJ0dhdGhlck5EJyxcbiAgICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnLCAncmFuayddIH0sXG4gICAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0VHlwZSB9XSxcbiAgICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgICB9KSxcbiAgICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICB9LFxuICAgIHsgaW5wdXRzOiBbaW5wdXRzWzBdLCBpbnB1dFNsaWNlT2Zmc2V0c10gfSxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdhdGhlck5EQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEdhdGhlck5EQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGJhdGNoRGltcyA9IGF0dHJpYnV0ZXMuYmF0Y2hfZGltcyBhcyBudW1iZXI7XG4gIHJldHVybiB7XG4gICAgYmF0Y2hEaW1zLFxuICAgIGNhY2hlS2V5OiAnJyxcbiAgfTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvLCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2F0aGVyQmxvY2tRdWFudGl6ZWRBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgZ2F0aGVyQXhpczogbnVtYmVyO1xuICBxdWFudGl6ZUF4aXM6IG51bWJlcjtcbiAgYmxvY2tTaXplOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogR2F0aGVyQmxvY2tRdWFudGl6ZWRBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmIChpbnB1dHMubGVuZ3RoIDwgMyB8fCBpbnB1dHMubGVuZ3RoID4gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignR2F0aGVyQmxvY2tRdWFudGl6ZWQgcmVxdWlyZXMgMyBvciA0IGlucHV0cy4nKTtcbiAgfVxuICBjb25zdCBxdWFudGl6ZUF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLnF1YW50aXplQXhpcywgaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgY29uc3QgYmxvY2tTaXplID0gYXR0cmlidXRlcy5ibG9ja1NpemU7XG4gIGNvbnN0IGRhdGEgPSBpbnB1dHNbMF07XG4gIGNvbnN0IHNjYWxlcyA9IGlucHV0c1syXTtcbiAgY29uc3QgemVyb1BvaW50ID0gaW5wdXRzLmxlbmd0aCA9PT0gNCA/IGlucHV0c1szXSA6IHVuZGVmaW5lZDtcbiAgaWYgKFxuICAgIHNjYWxlcy5kaW1zLmxlbmd0aCAhPT0gZGF0YS5kaW1zLmxlbmd0aCB8fFxuICAgICFkYXRhLmRpbXNcbiAgICAgIC5tYXAoKGQsIGkpID0+IChpID09PSBxdWFudGl6ZUF4aXMgPyBNYXRoLmNlaWwoZCAvIGJsb2NrU2l6ZSkgPT09IHNjYWxlcy5kaW1zW2ldIDogZCA9PT0gc2NhbGVzLmRpbXNbaV0pKVxuICAgICAgLnJlZHVjZSgoYSwgYikgPT4gYSAmJiBiLCB0cnVlKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnU2NhbGVzIG11c3QgaGF2ZSB0aGUgc2FtZSByYW5rIGFzIHRoZSBpbnB1dCB0ZW5zb3IgYW5kIHRoZSBkaW1zIHNob3VsZCBtYXRjaCBleGNlcHQgb24gZ2F0aGVyQXhpcy4nLFxuICAgICk7XG4gIH1cbiAgLy8gVE9ETyBVbmNvbW1lbnQgdGhlIGZvbGxvd2luZyBjaGVjayBvbmNlIHRoZSB0ZXN0IGNhc2UgY3JlYXRpb24gY29kZSBpcyBmaXhlZCB0byBjcmVhdGUgZGF0YSBjb3JyZWN0bHkgYWxpZ25lZC5cbiAgLy8gY29uc3QgaW5kaWNlcyA9IGlucHV0c1sxXTtcbiAgLy8gY29uc3QgdmFsaWRJbmRleCA9IChpbmRleDogbnVtYmVyKSA9PiBpbmRleCA+PSAwICYmIGluZGV4IDwgZGF0YS5kaW1zW2F0dHJpYnV0ZXMuZ2F0aGVyQXhpc107XG4gIC8vIGlmIChpbmRpY2VzLmRhdGFUeXBlID09PSBEYXRhVHlwZS5pbnQzMiAmJiBpbmRpY2VzLmdldEludDMyQXJyYXkoKS5zb21lKCh2KSA9PiAhdmFsaWRJbmRleCh2KSkgfHxcbiAgLy8gICAgIGluZGljZXMuZGF0YVR5cGUgPT09IERhdGFUeXBlLmludDY0ICYmIGluZGljZXMuZ2V0QmlnSW50NjRBcnJheSgpLnNvbWUoKHYpID0+ICF2YWxpZEluZGV4KE51bWJlcih2KSkpKSB7XG4gIC8vICAgdGhyb3cgbmV3IEVycm9yKCdJbmRpY2VzIG11c3QgYmUgd2l0aGluIHRoZSBib3VuZHMgb2YgdGhlIGdhdGhlckF4aXMuJyk7XG4gIC8vIH1cbiAgaWYgKHplcm9Qb2ludCkge1xuICAgIGlmICh6ZXJvUG9pbnQuZGF0YVR5cGUgIT09IGRhdGEuZGF0YVR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignWmVybyBwb2ludCBtdXN0IGhhdmUgdGhlIHNhbWUgZGF0YSB0eXBlIGFzIHRoZSBpbnB1dCB0ZW5zb3IuJyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHplcm9Qb2ludC5kaW1zLmxlbmd0aCAhPT0gc2NhbGVzLmRpbXMubGVuZ3RoIHx8XG4gICAgICAhemVyb1BvaW50LmRpbXMubWFwKChkLCBpKSA9PiBkID09PSBzY2FsZXMuZGltc1tpXSkucmVkdWNlKChhLCBiKSA9PiBhICYmIGIsIHRydWUpXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdaZXJvIHBvaW50IG11c3QgaGF2ZSB0aGUgc2FtZSByYW5rIGFzIHRoZSBpbnB1dCB0ZW5zb3IgYW5kIHRoZSBkaW1zIHNob3VsZCBtYXRjaCBleGNlcHQgb24gcXVhbnRpemVBeGlzLicsXG4gICAgICApO1xuICAgIH1cbiAgfVxufTtcblxuY29uc3QgY3JlYXRlR2F0aGVyQmxvY2tRdWFudGl6ZWRQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IEdhdGhlckJsb2NrUXVhbnRpemVkQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbmRpY2VzU2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3QgaW5wdXRSYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGdhdGhlckF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmdhdGhlckF4aXMsIGlucHV0UmFuayk7XG4gIGNvbnN0IHF1YW50aXplQXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMucXVhbnRpemVBeGlzLCBpbnB1dFJhbmspO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0U2hhcGUuc2xpY2UoMCk7XG4gIG91dHB1dFNoYXBlLnNwbGljZShnYXRoZXJBeGlzLCAxLCAuLi5pbmRpY2VzU2hhcGUpO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICBjb25zdCBvdXRwdXRUeXBlID0gaW5wdXRzWzJdLmRhdGFUeXBlO1xuICBjb25zdCBpbnB1dFR5cGUgPSBpbnB1dHNbMF0uZGF0YVR5cGU7XG4gIGNvbnN0IGlzU2lnbmVkID0gaW5wdXRUeXBlID09PSBEYXRhVHlwZS5pbnQ0OyAvLyBpbnB1dCBkYXRhIHR5cGUgaXMgZWl0aGVyIGludDQgb3IgdWludDQuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBxdWFudGl6ZUF4aXMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogZ2F0aGVyQXhpcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBhdHRyaWJ1dGVzLmJsb2NrU2l6ZSB9LFxuICAgIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKC4uLmlucHV0cy5tYXAoKGlucHV0LCBfKSA9PiBpbnB1dC5kaW1zKSwgb3V0cHV0U2hhcGUpLFxuICBdO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGRhdGEgPSBpbnB1dFZhcmlhYmxlKCdkYXRhJywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dHNbMF0uZGltcy5sZW5ndGgpO1xuICAgIGNvbnN0IGluZGljZXMgPSBpbnB1dFZhcmlhYmxlKCdpbnB1dEluZGljZXMnLCBpbnB1dHNbMV0uZGF0YVR5cGUsIGlucHV0c1sxXS5kaW1zLmxlbmd0aCk7XG4gICAgY29uc3Qgc2NhbGVzID0gaW5wdXRWYXJpYWJsZSgnc2NhbGVzJywgaW5wdXRzWzJdLmRhdGFUeXBlLCBpbnB1dHNbMl0uZGltcy5sZW5ndGgpO1xuICAgIGNvbnN0IHplcm9Qb2ludCA9XG4gICAgICBpbnB1dHMubGVuZ3RoID4gMyA/IGlucHV0VmFyaWFibGUoJ3plcm9Qb2ludCcsIGlucHV0c1szXS5kYXRhVHlwZSwgaW5wdXRzWzNdLmRpbXMubGVuZ3RoKSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0Jywgb3V0cHV0VHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgICBjb25zdCBpbnB1dFZhcmlhYmxlcyA9IFtkYXRhLCBpbmRpY2VzLCBzY2FsZXNdO1xuICAgIGlmICh6ZXJvUG9pbnQpIHtcbiAgICAgIGlucHV0VmFyaWFibGVzLnB1c2goemVyb1BvaW50KTtcbiAgICB9XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAncXVhbnRpemVfYXhpcycsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdnYXRoZXJfYXhpcycsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdibG9ja19zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICBdO1xuICAgIHJldHVybiBgXG4gICAgICAgICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJpYWJsZXMsIG91dHB1dCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICBsZXQgb3V0cHV0X2luZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG4gICAgICAgIHZhciBpbmRpY2VzX2luZGljZXMgPSAke2luZGljZXMudHlwZS5pbmRpY2VzfSgwKTtcbiAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgIGlmIChpbmRpY2VzU2hhcGUubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICBmb3IgKHZhciBpOiB1MzIgPSAwOyBpIDwgJHtpbmRpY2VzU2hhcGUubGVuZ3RofTsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAke291dHB1dC5pbmRpY2VzR2V0KCdvdXRwdXRfaW5kaWNlcycsICd1bmlmb3Jtcy5nYXRoZXJfYXhpcyArIGknKX07XG4gICAgICAgICAgICAke2luZGljZXMuaW5kaWNlc1NldCgnaW5kaWNlc19pbmRpY2VzJywgJ2knLCAnaW5kZXgnKX07XG4gICAgICAgICAgfWA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBgaW5kaWNlc19pbmRpY2VzID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCAndW5pZm9ybXMuZ2F0aGVyX2F4aXMnKX07YDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCl9O1xuICAgICAgICB2YXIgZGF0YV9pbmRpY2VzID0gJHtkYXRhLnR5cGUuaW5kaWNlc30oMCk7XG4gICAgICAgIGZvciAodmFyIGk6IHUzMiA9IDA7IGkgPCB1bmlmb3Jtcy5nYXRoZXJfYXhpczsgaSsrKSB7XG4gICAgICAgICAgbGV0IGluZGV4ID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCAnaScpfTtcbiAgICAgICAgICAke2RhdGEuaW5kaWNlc1NldCgnZGF0YV9pbmRpY2VzJywgJ2knLCAnaW5kZXgnKX07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGluZGV4X2Zyb21faW5kaWNlcyA9ICR7aW5kaWNlcy5nZXRCeUluZGljZXMoJ2luZGljZXNfaW5kaWNlcycpfTtcbiAgICAgICAgaWYgKGluZGV4X2Zyb21faW5kaWNlcyA8IDApIHtcbiAgICAgICAgICBpbmRleF9mcm9tX2luZGljZXMgKz0gJHtpbnB1dFNoYXBlW2dhdGhlckF4aXNdfTtcbiAgICAgICAgfVxuICAgICAgICAke2RhdGEuaW5kaWNlc1NldCgnZGF0YV9pbmRpY2VzJywgJ3VuaWZvcm1zLmdhdGhlcl9heGlzJywgJ3UzMihpbmRleF9mcm9tX2luZGljZXMpJyl9O1xuICAgICAgICBmb3IgKHZhciBpID0gdW5pZm9ybXMuZ2F0aGVyX2F4aXMgKyAxOyBpIDwgJHtvdXRwdXRTaGFwZS5sZW5ndGh9OyBpKyspIHtcbiAgICAgICAgICBsZXQgaW5kZXggPSAke291dHB1dC5pbmRpY2VzR2V0KCdvdXRwdXRfaW5kaWNlcycsIGBpICsgJHtpbmRpY2VzU2hhcGUubGVuZ3RofSAtIDFgKX07XG4gICAgICAgICAgJHtkYXRhLmluZGljZXNTZXQoJ2RhdGFfaW5kaWNlcycsICdpJywgJ2luZGV4Jyl9O1xuICAgICAgICB9XG4gICAgICAgIGxldCBkYXRhX29mZnNldCA9ICR7ZGF0YS5pbmRpY2VzVG9PZmZzZXQoJ2RhdGFfaW5kaWNlcycpfTtcbiAgICAgICAgbGV0IGRhdGFfaW5kZXggPSBkYXRhX29mZnNldCAlIDg7XG4gICAgICAgIC8vIENvbnZlcnQgNC1iaXQgcGFja2VkIGRhdGEgdG8gOC1iaXQgcGFja2VkIGRhdGEuXG4gICAgICAgIGxldCBwYWNrZWRfNGJpdF9xdWFudGl6ZWRfZGF0YSA9ICR7ZGF0YS5nZXRCeU9mZnNldCgnZGF0YV9vZmZzZXQgLyA4Jyl9O1xuICAgICAgICBsZXQgcGFja2VkXzhiaXRfcXVhbnRpemVkX2RhdGEgPSAocGFja2VkXzRiaXRfcXVhbnRpemVkX2RhdGEgPj4gKDQgKiAoZGF0YV9pbmRleCAlIDIpKSkgJiAweDBmMGYwZjBmO1xuICAgICAgICBsZXQgcXVhbnRpemVkX2RhdGFfdmVjID0gJHtpc1NpZ25lZCA/ICd1bnBhY2s0eEk4JyA6ICd1bnBhY2s0eFU4J30odTMyKHBhY2tlZF84Yml0X3F1YW50aXplZF9kYXRhKSk7XG4gICAgICAgIGxldCBxdWFudGl6ZWRfZGF0YSA9IHF1YW50aXplZF9kYXRhX3ZlY1tkYXRhX2luZGV4IC8gMl07XG4gICAgICAgIHZhciBzY2FsZV9pbmRpY2VzID0gZGF0YV9pbmRpY2VzO1xuICAgICAgICBsZXQgcXVhbnRpemVfYXhpc19pbmRleCA9ICR7c2NhbGVzLmluZGljZXNHZXQoJ2RhdGFfaW5kaWNlcycsICd1bmlmb3Jtcy5xdWFudGl6ZV9heGlzJyl9IC8gdW5pZm9ybXMuYmxvY2tfc2l6ZTtcbiAgICAgICAgJHtzY2FsZXMuaW5kaWNlc1NldCgnc2NhbGVfaW5kaWNlcycsICd1bmlmb3Jtcy5xdWFudGl6ZV9heGlzJywgJ3F1YW50aXplX2F4aXNfaW5kZXgnKX07XG4gICAgICAgIHZhciBzY2FsZSA9ICR7c2NhbGVzLmdldEJ5SW5kaWNlcygnc2NhbGVfaW5kaWNlcycpfTtcbiAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgIGlmICghemVyb1BvaW50KSB7XG4gICAgICAgICAgICByZXR1cm4gJ3ZhciB6ZXJvX3BvaW50ID0gMCc7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X2luZGljZXMgPSBzY2FsZV9pbmRpY2VzO1xuICAgICAgICAgICAgICBsZXQgemVyb19wb2ludF9vZmZzZXQgPSAke3plcm9Qb2ludC5pbmRpY2VzVG9PZmZzZXQoJ3plcm9fcG9pbnRfaW5kaWNlcycpfTtcbiAgICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfaW5kZXggPSB6ZXJvX3BvaW50X29mZnNldCAlIDg7XG4gICAgICAgICAgICAgIGxldCBwYWNrZWRfNGJpdF96ZXJvX3BvaW50cyA9ICR7emVyb1BvaW50LmdldEJ5T2Zmc2V0KCd6ZXJvX3BvaW50X29mZnNldCAvIDgnKX07XG4gICAgICAgICAgICAgIGxldCBwYWNrZWRfOGJpdF96ZXJvX3BvaW50cyA9IChwYWNrZWRfNGJpdF96ZXJvX3BvaW50cyA+PiAoNCAqICh6ZXJvX3BvaW50X2luZGV4ICUgMikpKSAmIDB4MGYwZjBmMGY7XG4gICAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X3ZlYyA9ICR7aXNTaWduZWQgPyAndW5wYWNrNHhJOCcgOiAndW5wYWNrNHhVOCd9KHUzMihwYWNrZWRfOGJpdF96ZXJvX3BvaW50cykpO1xuICAgICAgICAgICAgICBsZXQgemVyb19wb2ludCA9IHplcm9fcG9pbnRfdmVjW3plcm9fcG9pbnRfaW5kZXggLyAyXTtgO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKX07XG4gICAgICAgIGxldCBkZXF1YW50aXplZF9kYXRhID0gJHt0ZW5zb3JUeXBlVG9Xc2dsVmFsdWVUeXBlKG91dHB1dFR5cGUpfShxdWFudGl6ZWRfZGF0YSAtIHplcm9fcG9pbnQpICogc2NhbGU7XG4gICAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ2RlcXVhbnRpemVkX2RhdGEnKX07XG4gICAgfWA7XG4gIH07XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0dhdGhlckJsb2NrUXVhbnRpemVkJyxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX07JHtpbnB1dHNcbiAgICAgICAgLmZpbHRlcigoXywgaSkgPT4gaSAhPT0gMSlcbiAgICAgICAgLm1hcCgoaW5wdXQpID0+IGlucHV0LmRpbXMuam9pbignXycpKVxuICAgICAgICAuam9pbignOycpfWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llczogQXJyYXkuZnJvbSh7IGxlbmd0aDogaW5wdXRzLmxlbmd0aCB9LCAoX3YsIF9pKSA9PiAncmFuaycpLFxuICAgIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogb3V0cHV0VHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgZ2F0aGVyQmxvY2tRdWFudGl6ZWQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEdhdGhlckJsb2NrUXVhbnRpemVkQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBjb250ZXh0LmlucHV0cztcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUdhdGhlckJsb2NrUXVhbnRpemVkUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdhdGhlckJsb2NrUXVhbnRpemVkQXR0cmlidXRlcyA9IChcbiAgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4pOiBHYXRoZXJCbG9ja1F1YW50aXplZEF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBibG9ja1NpemU6IGF0dHJpYnV0ZXMuYmxvY2tTaXplIGFzIG51bWJlcixcbiAgICBnYXRoZXJBeGlzOiBhdHRyaWJ1dGVzLmdhdGhlckF4aXMgYXMgbnVtYmVyLFxuICAgIHF1YW50aXplQXhpczogYXR0cmlidXRlcy5xdWFudGl6ZUF4aXMgYXMgbnVtYmVyLFxuICB9KTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5LCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsIGlucHV0VmFyaWFibGUsIG91dHB1dFZhcmlhYmxlLCBTaGFkZXJIZWxwZXIgfSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2F0aGVyRWxlbWVudHNBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgYXhpczogbnVtYmVyO1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHYXRoZXJFbGVtZW50cyByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHYXRoZXJFbGVtZW50cyByZXF1aXJlcyB0aGF0IHRoZSBkYXRhIGlucHV0IGJlIHJhbmsgPj0gMS4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IGlucHV0c1sxXS5kaW1zLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgR2F0aGVyRWxlbWVudHMgcmVxdWlyZXMgdGhhdCB0aGUgZGF0YSBpbnB1dCBhbmRcbiAgICAgICAgICAgICAgICAgICAgIGluZGljZXMgaW5wdXQgdGVuc29ycyBiZSBvZiBzYW1lIHJhbmsuYCk7XG4gIH1cbn07XG5cbmNvbnN0IGNyZWF0ZUdhdGhlckVsZW1lbnRzUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBHYXRoZXJFbGVtZW50c0F0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgaW5wdXRPdXRwdXREYXRhVHlwZSA9IGlucHV0c1swXS5kYXRhVHlwZTtcbiAgY29uc3QgaW5wdXRSYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3QgaW5kaWNlc1NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IGluZGljZXNEYXRhVHlwZSA9IGlucHV0c1sxXS5kYXRhVHlwZTtcbiAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgaW5wdXRSYW5rKTtcbiAgY29uc3QgYXhpc0RpbUxpbWl0ID0gaW5wdXRTaGFwZVtheGlzXTtcblxuICBjb25zdCBvdXRwdXRTaGFwZSA9IGluZGljZXNTaGFwZS5zbGljZSgwKTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcblxuICBjb25zdCBpbnB1dCA9IGlucHV0VmFyaWFibGUoJ2lucHV0JywgaW5wdXRPdXRwdXREYXRhVHlwZSwgaW5wdXRSYW5rKTtcbiAgY29uc3QgaW5kaWNlcyA9IGlucHV0VmFyaWFibGUoJ2luZGljZXNJbnB1dCcsIGluZGljZXNEYXRhVHlwZSwgaW5kaWNlc1NoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dE91dHB1dERhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IGF4aXNEaW1MaW1pdCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBheGlzIH0sXG4gIF07XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0U2hhcGUsIGluZGljZXNTaGFwZSwgb3V0cHV0U2hhcGUpKTtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3JhbmsnLCAncmFuayddO1xuXG4gIC8vIGludDY0IGluZGljZXMgd291bGQgYmUgdHJlYXRlZCBhcyBsaXR0bGUgZW5kaWFuIGkzMiB3aXRoIGFzc3VtcHRpb24gdGhleSBmYWxsIGluIGkzMiBsaW1pdHNcbiAgLy8gVGhhdCBhc3N1bXB0aW9uIGlzIHNhZmUgYXMgaXQncyBub3QgcG9zc2libGUgdG8gYWxsb2NhdGUgPjJnYiBidWZmZXIgZm9yIGlucHV0IHRlbnNvclxuICAvLyBJbnB1dCBkYXRhIHdpbGwgYmUgdHJlYXRlZCBhcyB1MzIgb3IgdHdvIHUzMiBmb3IgOC1ieXRlIHRlbnNvcnNcbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiBgXG4gICAgICAke3NoYWRlckhlbHBlclxuICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdvdXRwdXRTaXplJywgJ3UzMicpXG4gICAgICAgIC5yZWdpc3RlclVuaWZvcm0oJ2F4aXNEaW1MaW1pdCcsICdpMzInKVxuICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdheGlzJywgJ3UzMicpXG4gICAgICAgIC5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCBpbmRpY2VzLCBvdXRwdXQpfVxuICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRTaXplJyl9XG5cbiAgICAgIGxldCBvdXRwdXRJbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuXG4gICAgICB2YXIgaWR4ID0gJHtpbmRpY2VzLmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4Jyl9O1xuICAgICAgaWYgKGlkeCA8IDApIHtcbiAgICAgICAgaWR4ID0gaWR4ICsgdW5pZm9ybXMuYXhpc0RpbUxpbWl0O1xuICAgICAgfVxuICAgICAgdmFyIGlucHV0SW5kaWNlcyA9ICR7aW5wdXQudHlwZS5pbmRpY2VzfShvdXRwdXRJbmRpY2VzKTtcbiAgICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5wdXRJbmRpY2VzJywgJ3VuaWZvcm1zLmF4aXMnLCAndTMyKGlkeCknKX07XG4gICAgICBsZXQgdmFsdWUgPSAke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRJbmRpY2VzJyl9O1xuXG4gICAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICd2YWx1ZScpfTtcbiAgfWA7XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnR2F0aGVyRWxlbWVudHMnLFxuICAgIHNoYWRlckNhY2hlOiB7IGlucHV0RGVwZW5kZW5jaWVzIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH1dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdhdGhlckVsZW1lbnRzQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEdhdGhlckVsZW1lbnRzQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGlzOiBhdHRyaWJ1dGVzLmF4aXMgYXMgbnVtYmVyIH0pO1xuXG5leHBvcnQgY29uc3QgZ2F0aGVyRWxlbWVudHMgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEdhdGhlckVsZW1lbnRzQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBjb250ZXh0LmlucHV0cztcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUdhdGhlckVsZW1lbnRzUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IEdlbW1VdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5LCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIEluZGljZXNIZWxwZXIsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBpcyBtaXNzaW5nJyk7XG4gIH1cbiAgaWYgKGlucHV0cy5sZW5ndGggPCAyIHx8IGlucHV0cy5sZW5ndGggPiAzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhaWQgaW5wdXQgbnVtYmVyLicpO1xuICB9XG5cbiAgLy8gJ0MnIGNhbiBiZSBvZiBkaW1lbnNpb25hbGl0eSAwLCAxIG9yIDIgb25seVxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0uZGltcy5sZW5ndGggPiAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlIG9mIEMnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0uZGF0YVR5cGUgIT09IGlucHV0c1sxXS5kYXRhVHlwZSB8fCAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMF0uZGF0YVR5cGUgIT09IGlucHV0c1syXS5kYXRhVHlwZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHR5cGVzIGFyZSBtaXNtYXRjaGVkJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2VtbUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICB0cmFuc0E6IGJvb2xlYW47XG4gIHRyYW5zQjogYm9vbGVhbjtcbiAgYWxwaGE6IG51bWJlcjtcbiAgYmV0YTogbnVtYmVyO1xufVxuXG5jb25zdCBjcmVhdGVHZW1tUHJvZ3JhbUluZm8gPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IEdlbW1BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBiU2hhcGUgPSBpbnB1dHNbMV0uZGltcy5zbGljZSgpO1xuICBjb25zdCBbTSwgTiwgS10gPSBHZW1tVXRpbC5nZXRTaGFwZU9mR2VtbVJlc3VsdChcbiAgICBhU2hhcGUsXG4gICAgYXR0cmlidXRlcy50cmFuc0EsXG4gICAgYlNoYXBlLFxuICAgIGF0dHJpYnV0ZXMudHJhbnNCLFxuICAgIGlucHV0cy5sZW5ndGggPT09IDMgPyBpbnB1dHNbMl0uZGltcyA6IHVuZGVmaW5lZCxcbiAgKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBbTSwgTl07XG4gIGlmICghb3V0cHV0U2hhcGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCB1c2UgZ2VtbSBvbiB0aGUgZ2l2ZW4gdGVuc29yc1wiKTtcbiAgfVxuICBjb25zdCB0aWxlU2l6ZSA9IDE2O1xuICBjb25zdCBudW1UaWxlTiA9IE1hdGguY2VpbChOIC8gdGlsZVNpemUpO1xuICBjb25zdCBudW1UaWxlTSA9IE1hdGguY2VpbChNIC8gdGlsZVNpemUpO1xuICAvLyBUT0RPOiBGaW5kIHRoZSBjb25kaXRpb24gd2hlbiB0byB1c2UgdGhlIG5haXZlIG9uZS5cbiAgY29uc3QgdXNlU2hhcmVkID0gdHJ1ZTtcblxuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHVzZVNoYXJlZCA/IG51bVRpbGVOIDogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBNIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IE4gfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogSyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuZmxvYXQsIGRhdGE6IGF0dHJpYnV0ZXMuYWxwaGEgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmZsb2F0LCBkYXRhOiBhdHRyaWJ1dGVzLmJldGEgfSxcbiAgXTtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3R5cGUnLCAndHlwZSddO1xuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMykge1xuICAgIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0c1syXS5kaW1zKSk7XG4gICAgaW5wdXREZXBlbmRlbmNpZXMucHVzaCgncmFuaycpO1xuICB9XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKG91dHB1dFNoYXBlKSk7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgbGV0IGxpbmUgPSAnJztcbiAgICBpZiAoYXR0cmlidXRlcy50cmFuc0EgJiYgYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICAgIGxpbmUgPSAndmFsdWUgKz0gYVtrICogdW5pZm9ybXMuTSArIG1dICogYltuICogdW5pZm9ybXMuSyArIGtdOyc7XG4gICAgfSBlbHNlIGlmIChhdHRyaWJ1dGVzLnRyYW5zQSAmJiAhYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICAgIGxpbmUgPSAndmFsdWUgKz0gYVtrICogdW5pZm9ybXMuTSArIG1dICogYltrICogdW5pZm9ybXMuTiArIG5dOyc7XG4gICAgfSBlbHNlIGlmICghYXR0cmlidXRlcy50cmFuc0EgJiYgYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICAgIGxpbmUgPSAndmFsdWUgKz0gYVttICogdW5pZm9ybXMuSyArIGtdICogYltuICogdW5pZm9ybXMuSyArIGtdOyc7XG4gICAgfSBlbHNlIGlmICghYXR0cmlidXRlcy50cmFuc0EgJiYgIWF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgICBsaW5lID0gJ3ZhbHVlICs9IGFbbSAqIHVuaWZvcm1zLksgKyBrXSAqIGJbayAqIHVuaWZvcm1zLk4gKyBuXTsnO1xuICAgIH1cblxuICAgIGNvbnN0IGNhbGN1bGF0ZUFscGhhID0gYXR0cmlidXRlcy5hbHBoYSA9PT0gMSA/ICcnIDogJ3ZhbHVlICo9IHVuaWZvcm1zLmFscGhhOyc7XG4gICAgY29uc3QgYSA9IGlucHV0VmFyaWFibGUoJ2EnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0c1swXS5kaW1zKTtcbiAgICBjb25zdCBiID0gaW5wdXRWYXJpYWJsZSgnYicsIGlucHV0c1sxXS5kYXRhVHlwZSwgaW5wdXRzWzFdLmRpbXMpO1xuICAgIGNvbnN0IGRhdGFUeXBlID0gYS50eXBlLnZhbHVlO1xuICAgIGxldCBjOiBJbmRpY2VzSGVscGVyIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3QgdmFyaWFibGVzID0gW2EsIGJdO1xuICAgIGlmIChpbnB1dHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBjID0gaW5wdXRWYXJpYWJsZSgnYycsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoKTtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKGMpO1xuICAgIH1cbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dCk7XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnTScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdOJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ0snLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnYWxwaGEnLCB0eXBlOiAnZjMyJyB9LFxuICAgICAgeyBuYW1lOiAnYmV0YScsIHR5cGU6ICdmMzInIH0sXG4gICAgXTtcbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKC4uLnZhcmlhYmxlcyl9XG5cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX1cblxuICAgIGxldCBtID0gZ2xvYmFsX2lkeCAvIHVuaWZvcm1zLk47XG4gICAgbGV0IG4gPSBnbG9iYWxfaWR4ICUgdW5pZm9ybXMuTjtcblxuICAgIHZhciB2YWx1ZSA9ICR7ZGF0YVR5cGV9KDApO1xuICAgIGZvciAodmFyIGs6IHUzMiA9IDB1OyBrIDwgdW5pZm9ybXMuSzsgaysrKSB7XG4gICAgICAke2xpbmV9XG4gICAgfVxuXG4gICAgJHtjYWxjdWxhdGVBbHBoYX1cbiAgICAkeygoKSA9PiB7XG4gICAgICBpZiAoYyAhPSBudWxsKSB7XG4gICAgICAgIHJldHVybiBgbGV0IGNPZmZzZXQgPSAke2MuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQoJ3ZlYzIobSwgbiknLCBvdXRwdXQpfTsgdmFsdWUgKz0gJHtcbiAgICAgICAgICBkYXRhVHlwZVxuICAgICAgICB9KHVuaWZvcm1zLmJldGEpICogJHtjLmdldEJ5T2Zmc2V0KCdjT2Zmc2V0Jyl9O2A7XG4gICAgICB9XG4gICAgICByZXR1cm4gJyc7XG4gICAgfSkoKX1cbiAgICBvdXRwdXRbZ2xvYmFsX2lkeF0gPSB2YWx1ZTtcbiAgfWA7XG4gIH07XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlU2hhcmVkID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgYSA9IGlucHV0VmFyaWFibGUoJ2EnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0c1swXS5kaW1zKTtcbiAgICBjb25zdCBiID0gaW5wdXRWYXJpYWJsZSgnYicsIGlucHV0c1sxXS5kYXRhVHlwZSwgaW5wdXRzWzFdLmRpbXMpO1xuICAgIGxldCBjOiBJbmRpY2VzSGVscGVyIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3QgdmFyaWFibGVzID0gW2EsIGJdO1xuICAgIGlmIChpbnB1dHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBjID0gaW5wdXRWYXJpYWJsZSgnYycsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoKTtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKGMpO1xuICAgIH1cbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dCk7XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnbnVtX3RpbGVfbicsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdNJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ04nLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnSycsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdhbHBoYScsIHR5cGU6ICdmMzInIH0sXG4gICAgICB7IG5hbWU6ICdiZXRhJywgdHlwZTogJ2YzMicgfSxcbiAgICBdO1xuXG4gICAgbGV0IGNhbGNSZXN1bHQgPSAnJztcbiAgICBsZXQgZmlsbFdvcmtncm91cE1lbW9yeSA9ICcnO1xuICAgIGlmIChhdHRyaWJ1dGVzLnRyYW5zQSAmJiBhdHRyaWJ1dGVzLnRyYW5zQikge1xuICAgICAgZmlsbFdvcmtncm91cE1lbW9yeSA9IGBcbiAgICAgIHZhciBjb2wgPSB0aWxlX3Jvd19zdGFydCArIGxvY2FsX2lkLng7XG4gICAgICB2YXIgcm93ID0ga19zdGFydCArIGxvY2FsX2lkLnk7XG4gICAgICBpZiAoY29sIDwgdW5pZm9ybXMuTSAmJiByb3cgPCB1bmlmb3Jtcy5LKSB7XG4gICAgICAgIHRpbGVfYVtsb2NhbF9pZC55XVtsb2NhbF9pZC54XSA9IGFbcm93ICogdW5pZm9ybXMuTSArIGNvbF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aWxlX2FbbG9jYWxfaWQueV1bbG9jYWxfaWQueF0gPSAke2EudHlwZS52YWx1ZX0oMCk7XG4gICAgICB9XG5cbiAgICAgIGNvbCA9IGtfc3RhcnQgKyBsb2NhbF9pZC54O1xuICAgICAgcm93ID0gdGlsZV9jb2xfc3RhcnQgKyBsb2NhbF9pZC55O1xuICAgICAgaWYgKGNvbCA8IHVuaWZvcm1zLksgJiYgcm93IDwgdW5pZm9ybXMuTikge1xuICAgICAgICB0aWxlX2JbbG9jYWxfaWQueV1bbG9jYWxfaWQueF0gPSBiW3JvdyAqIHVuaWZvcm1zLksgKyBjb2xdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGlsZV9iW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdID0gJHtiLnR5cGUudmFsdWV9KDApO1xuICAgICAgfVxuICAgICAgYDtcbiAgICAgIGNhbGNSZXN1bHQgPSBgdmFsdWUgKz0gdGlsZV9hW2tdW2xvY2FsX2lkLnldICogdGlsZV9iW2xvY2FsX2lkLnhdW2tdO2A7XG4gICAgfSBlbHNlIGlmIChhdHRyaWJ1dGVzLnRyYW5zQSAmJiAhYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICAgIGZpbGxXb3JrZ3JvdXBNZW1vcnkgPSBgXG4gICAgICB2YXIgY29sID0gdGlsZV9yb3dfc3RhcnQgKyBsb2NhbF9pZC54O1xuICAgICAgdmFyIHJvdyA9IGtfc3RhcnQgKyBsb2NhbF9pZC55O1xuICAgICAgaWYgKGNvbCA8IHVuaWZvcm1zLk0gJiYgcm93IDwgdW5pZm9ybXMuSykge1xuICAgICAgICB0aWxlX2FbbG9jYWxfaWQueV1bbG9jYWxfaWQueF0gPSBhW3JvdyAqIHVuaWZvcm1zLk0gKyBjb2xdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGlsZV9hW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdID0gJHthLnR5cGUudmFsdWV9KDApO1xuICAgICAgfVxuXG4gICAgICBjb2wgPSB0aWxlX2NvbF9zdGFydCArIGxvY2FsX2lkLng7XG4gICAgICByb3cgPSBrX3N0YXJ0ICsgbG9jYWxfaWQueTtcbiAgICAgIGlmIChjb2wgPCB1bmlmb3Jtcy5OICYmIHJvdyA8IHVuaWZvcm1zLkspIHtcbiAgICAgICAgdGlsZV9iW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdID0gYltyb3cgKiB1bmlmb3Jtcy5OICsgY29sXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRpbGVfYltsb2NhbF9pZC55XVtsb2NhbF9pZC54XSA9ICR7Yi50eXBlLnZhbHVlfSgwKTtcbiAgICAgIH1cbiAgICAgIGA7XG4gICAgICBjYWxjUmVzdWx0ID0gYHZhbHVlICs9IHRpbGVfYVtrXVtsb2NhbF9pZC55XSAqIHRpbGVfYltrXVtsb2NhbF9pZC54XTtgO1xuICAgIH0gZWxzZSBpZiAoIWF0dHJpYnV0ZXMudHJhbnNBICYmIGF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgICBmaWxsV29ya2dyb3VwTWVtb3J5ID0gYFxuICAgICAgdmFyIGNvbCA9IGtfc3RhcnQgKyBsb2NhbF9pZC54O1xuICAgICAgdmFyIHJvdyA9IHRpbGVfcm93X3N0YXJ0ICsgbG9jYWxfaWQueTtcbiAgICAgIGlmIChjb2wgPCB1bmlmb3Jtcy5LICYmIHJvdyA8IHVuaWZvcm1zLk0pIHtcbiAgICAgICAgdGlsZV9hW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdID0gYVtyb3cgKiB1bmlmb3Jtcy5LICsgY29sXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRpbGVfYVtsb2NhbF9pZC55XVtsb2NhbF9pZC54XSA9ICR7YS50eXBlLnZhbHVlfSgwKTtcbiAgICAgIH1cblxuICAgICAgY29sID0ga19zdGFydCArIGxvY2FsX2lkLng7XG4gICAgICByb3cgPSB0aWxlX2NvbF9zdGFydCArIGxvY2FsX2lkLnk7XG4gICAgICBpZiAoY29sIDwgdW5pZm9ybXMuSyAmJiByb3cgPCB1bmlmb3Jtcy5OKSB7XG4gICAgICAgIHRpbGVfYltsb2NhbF9pZC55XVtsb2NhbF9pZC54XSA9IGJbcm93ICogdW5pZm9ybXMuSyArIGNvbF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aWxlX2JbbG9jYWxfaWQueV1bbG9jYWxfaWQueF0gPSAke2IudHlwZS52YWx1ZX0oMCk7XG4gICAgICB9XG4gICAgICBgO1xuICAgICAgY2FsY1Jlc3VsdCA9IGB2YWx1ZSArPSB0aWxlX2FbbG9jYWxfaWQueV1ba10gKiB0aWxlX2JbbG9jYWxfaWQueF1ba107YDtcbiAgICB9IGVsc2UgaWYgKCFhdHRyaWJ1dGVzLnRyYW5zQSAmJiAhYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICAgIGZpbGxXb3JrZ3JvdXBNZW1vcnkgPSBgXG4gICAgICB2YXIgY29sID0ga19zdGFydCArIGxvY2FsX2lkLng7XG4gICAgICB2YXIgcm93ID0gdGlsZV9yb3dfc3RhcnQgKyBsb2NhbF9pZC55O1xuICAgICAgaWYgKGNvbCA8IHVuaWZvcm1zLksgJiYgcm93IDwgdW5pZm9ybXMuTSkge1xuICAgICAgICB0aWxlX2FbbG9jYWxfaWQueV1bbG9jYWxfaWQueF0gPSBhW3JvdyAqIHVuaWZvcm1zLksgKyBjb2xdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGlsZV9hW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdID0gJHthLnR5cGUudmFsdWV9KDApO1xuICAgICAgfVxuXG4gICAgICBjb2wgPSB0aWxlX2NvbF9zdGFydCArIGxvY2FsX2lkLng7XG4gICAgICByb3cgPSBrX3N0YXJ0ICsgbG9jYWxfaWQueTtcbiAgICAgIGlmIChjb2wgPCB1bmlmb3Jtcy5OICYmIHJvdyA8IHVuaWZvcm1zLkspIHtcbiAgICAgICAgdGlsZV9iW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdID0gYltyb3cgKiB1bmlmb3Jtcy5OICsgY29sXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRpbGVfYltsb2NhbF9pZC55XVtsb2NhbF9pZC54XSA9ICR7Yi50eXBlLnZhbHVlfSgwKTtcbiAgICAgIH1cbiAgICAgIGA7XG4gICAgICBjYWxjUmVzdWx0ID0gYHZhbHVlICs9IHRpbGVfYVtsb2NhbF9pZC55XVtrXSAqIHRpbGVfYltrXVtsb2NhbF9pZC54XTtgO1xuICAgIH1cblxuICAgIGNvbnN0IGNhbGN1bGF0ZUFscGhhID0gYXR0cmlidXRlcy5hbHBoYSA9PT0gMSA/ICcnIDogJ3ZhbHVlICo9IHVuaWZvcm1zLmFscGhhOyc7XG5cbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKC4uLnZhcmlhYmxlcyl9XG4gIHZhcjx3b3JrZ3JvdXA+IHRpbGVfYTogYXJyYXk8YXJyYXk8JHthLnR5cGUuc3RvcmFnZX0sICR7dGlsZVNpemV9PiwgJHt0aWxlU2l6ZX0+O1xuICB2YXI8d29ya2dyb3VwPiB0aWxlX2I6IGFycmF5PGFycmF5PCR7Yi50eXBlLnN0b3JhZ2V9LCAke3RpbGVTaXplfT4sICR7dGlsZVNpemV9PjtcbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KFt0aWxlU2l6ZSwgdGlsZVNpemUsIDFdKX1cbiAgICBsZXQgdGlsZV9jb2xfc3RhcnQgPSAod29ya2dyb3VwX2luZGV4ICUgdW5pZm9ybXMubnVtX3RpbGVfbikgKiAke3RpbGVTaXplfTtcbiAgICBsZXQgdGlsZV9yb3dfc3RhcnQgPSAod29ya2dyb3VwX2luZGV4IC8gdW5pZm9ybXMubnVtX3RpbGVfbikgKiAke3RpbGVTaXplfTtcbiAgICBsZXQgbnVtX3RpbGVzID0gKHVuaWZvcm1zLksgLSAxKSAvICR7dGlsZVNpemV9ICsgMTtcbiAgICB2YXIga19zdGFydCA9IDB1O1xuICAgIHZhciB2YWx1ZSA9ICR7b3V0cHV0LnR5cGUudmFsdWV9KDApO1xuICAgIGZvciAodmFyIHQ6IHUzMiA9IDB1OyB0IDwgbnVtX3RpbGVzOyB0KyspIHtcbiAgICAgICR7ZmlsbFdvcmtncm91cE1lbW9yeX1cbiAgICAgIGtfc3RhcnQgPSBrX3N0YXJ0ICsgJHt0aWxlU2l6ZX07XG4gICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICAgIGZvciAodmFyIGs6IHUzMiA9IDB1OyBrIDwgJHt0aWxlU2l6ZX07IGsrKykge1xuICAgICAgICAke2NhbGNSZXN1bHR9XG4gICAgICB9XG4gICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gICAgfVxuXG4gICAgJHtjYWxjdWxhdGVBbHBoYX1cbiAgICBsZXQgbSA9IHRpbGVfcm93X3N0YXJ0ICsgbG9jYWxfaWQueTtcbiAgICBsZXQgbiA9IHRpbGVfY29sX3N0YXJ0ICsgbG9jYWxfaWQueDtcbiAgICAkeygoKSA9PiB7XG4gICAgICBpZiAoYyAhPSBudWxsKSB7XG4gICAgICAgIHJldHVybiBgbGV0IGNPZmZzZXQgPSAke2MuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQoJ3ZlYzIobSwgbiknLCBvdXRwdXQpfTsgdmFsdWUgKz0gJHtcbiAgICAgICAgICBvdXRwdXQudHlwZS52YWx1ZVxuICAgICAgICB9KHVuaWZvcm1zLmJldGEpICogJHtjLmdldEJ5T2Zmc2V0KCdjT2Zmc2V0Jyl9O2A7XG4gICAgICB9XG4gICAgICByZXR1cm4gJyc7XG4gICAgfSkoKX1cbiAgICBpZiAobSA8IHVuaWZvcm1zLk0gJiYgbiA8IHVuaWZvcm1zLk4pIHtcbiAgICAgIG91dHB1dFttICogdW5pZm9ybXMuTiArIG5dID0gdmFsdWU7XG4gICAgfVxuICB9YDtcbiAgfTtcblxuICBpZiAodXNlU2hhcmVkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6ICdHZW1tU2hhcmVkJyxcbiAgICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke2F0dHJpYnV0ZXMuY2FjaGVLZXl9YCwgaW5wdXREZXBlbmRlbmNpZXMgfSxcbiAgICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH1dLFxuICAgICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IG51bVRpbGVOICogbnVtVGlsZU0gfSxcbiAgICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgICAgfSksXG4gICAgICBnZXRTaGFkZXJTb3VyY2U6IGdldFNoYWRlclNvdXJjZVNoYXJlZCxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnR2VtbScsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX1gLCBpbnB1dERlcGVuZGVuY2llcyB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VHZW1tQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEdlbW1BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgdHJhbnNBID0gYXR0cmlidXRlcy50cmFuc0EgYXMgYm9vbGVhbjtcbiAgY29uc3QgdHJhbnNCID0gYXR0cmlidXRlcy50cmFuc0IgYXMgYm9vbGVhbjtcbiAgY29uc3QgYWxwaGEgPSBhdHRyaWJ1dGVzLmFscGhhIGFzIG51bWJlcjtcbiAgY29uc3QgYmV0YSA9IGF0dHJpYnV0ZXMuYmV0YSBhcyBudW1iZXI7XG4gIHJldHVybiB7XG4gICAgdHJhbnNBLFxuICAgIHRyYW5zQixcbiAgICBhbHBoYSxcbiAgICBiZXRhLFxuICAgIGNhY2hlS2V5OiBgJHthdHRyaWJ1dGVzLnRyYW5zQX07JHthdHRyaWJ1dGVzLnRyYW5zQn07JHthdHRyaWJ1dGVzLmFscGhhID09PSAxfWAsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgZ2VtbSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlR2VtbVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBJbmRpY2VzSGVscGVyLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG5sZXQgW2lkeE4sIGlkeEMsIGlkeEgsIGlkeFddID0gWzAsIDEsIDIsIDNdOyAvLyBOQ0hXXG50eXBlIE1vZGUgPSAnYmlsaW5lYXInIHwgJ25lYXJlc3QnIHwgJ2JpY3ViaWMnO1xudHlwZSBQYWRkaW5nTW9kZSA9ICd6ZXJvcycgfCAnYm9yZGVyJyB8ICdyZWZsZWN0aW9uJztcbnR5cGUgRm9ybWF0ID0gJ05IV0MnIHwgJ05DSFcnO1xuZXhwb3J0IGludGVyZmFjZSBHcmlkU2FtcGVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgYWxpZ25Db3JuZXJzOiBudW1iZXI7XG4gIG1vZGU6IE1vZGU7XG4gIHBhZGRpbmdNb2RlOiBQYWRkaW5nTW9kZTtcbiAgZm9ybWF0OiBGb3JtYXQ7XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ29ubHkgNC1EIHRlbnNvciBpcyBzdXBwb3J0ZWQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCBkaW1lbnNpb25zIG11c3QgYmUgZXF1YWwgdG8gZ3JpZCBkaW1lbnNpb25zJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMiAhPT0gaW5wdXRzWzFdLmRpbXNbaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMV0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGxhc3QgZGltZW5zaW9uIG9mIGdyaWQgbXVzdCBiZSBlcXVhbCB0byAke2lucHV0c1swXS5kaW1zLmxlbmd0aCAtIDJ9YCk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLmRpbXNbMF0gIT09IGlucHV0c1sxXS5kaW1zWzBdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdncmlkIGJhdGNoIHNpemUgbXVzdCBtYXRjaCBpbnB1dCBiYXRjaCBzaXplJyk7XG4gIH1cbn07XG5cbmNvbnN0IGdzR2V0Q3ViaWNDb2VmZnMgPSBgXG4gIGZuIGdzX2dldF9jdWJpY19jb2VmZnMoeDogZjMyKSAtPiB2ZWM0PGYzMj4ge1xuICAgIGxldCBjdWJpY19hbHBoYSA9IC0wLjc1ZjtcbiAgICBsZXQgeF9hYnMgPSBhYnMoeCk7XG4gICAgdmFyIGNvZWZmczogdmVjNDxmMzI+O1xuICAgIGNvZWZmc1swXSA9ICgoKGN1YmljX2FscGhhICogKHhfYWJzICsgMSkgLSA1ICogY3ViaWNfYWxwaGEpICogKHhfYWJzICsgMSkgKyA4ICogY3ViaWNfYWxwaGEpICogKHhfYWJzICsgMSkgLSA0ICogY3ViaWNfYWxwaGEpO1xuICAgIGNvZWZmc1sxXSA9ICgoKGN1YmljX2FscGhhICsgMikgKiB4X2FicyAtIChjdWJpY19hbHBoYSArIDMpKSAqIHhfYWJzICogeF9hYnMgKyAxKTtcbiAgICBjb2VmZnNbMl0gPSAoKChjdWJpY19hbHBoYSArIDIpICogKDEgLSB4X2FicykgLSAoY3ViaWNfYWxwaGEgKyAzKSkgKiAoMSAtIHhfYWJzKSAqICgxIC0geF9hYnMpICsgMSk7XG4gICAgY29lZmZzWzNdID0gKCgoY3ViaWNfYWxwaGEgKiAoMiAtIHhfYWJzKSAtIDUgKiBjdWJpY19hbHBoYSkgKiAoMiAtIHhfYWJzKSArIDggKiBjdWJpY19hbHBoYSkgKiAoMiAtIHhfYWJzKSAtIDQgKiBjdWJpY19hbHBoYSk7XG4gICAgcmV0dXJuIGNvZWZmcztcbiAgfVxuYDtcblxuY29uc3QgZ3NCaWN1YmljSW50ZXJwb2xhdGUgPSAoZGF0YVR5cGU6IHN0cmluZyk6IHN0cmluZyA9PiBgXG4gIGZuIGdzX2JpY3ViaWNfaW50ZXJwb2xhdGUocDogbWF0NHg0PCR7ZGF0YVR5cGV9PiwgeDogZjMyLCB5OiBmMzIpIC0+ICR7ZGF0YVR5cGV9IHtcbiAgICB2YXIgdjogdmVjNDxmMzI+O1xuICAgIHZhciBjb2VmZnMgPSBnc19nZXRfY3ViaWNfY29lZmZzKHgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICB2W2ldID0gY29lZmZzWzBdICogcFtpXVswXSArIGNvZWZmc1sxXSAqIHBbaV1bMV0gKyBjb2VmZnNbMl0gKiBwW2ldWzJdICsgY29lZmZzWzNdICogcFtpXVszXTtcbiAgICB9XG4gICAgY29lZmZzID0gZ3NfZ2V0X2N1YmljX2NvZWZmcyh5KTtcbiAgICBsZXQgcGl4ZWwgPSAke2RhdGFUeXBlfShjb2VmZnNbMF0gKiB2WzBdICsgY29lZmZzWzFdICogdlsxXSArIGNvZWZmc1syXSAqIHZbMl0gKyBjb2VmZnNbM10gKiB2WzNdKTtcbiAgICByZXR1cm4gcGl4ZWw7XG4gIH1cbmA7XG5cbmNvbnN0IGdzRGVub3JtYWxpemUgPSAoYXR0cmlidXRlczogR3JpZFNhbXBlQXR0cmlidXRlcyk6IHN0cmluZyA9PiBgXG4gIGZuIGdzX2Rlbm9ybWFsaXplKG46IGYzMiwgbGVuZ3RoOiBpMzIpIC0+IGYzMiB7XG4gICAgJHtcbiAgICAgIGF0dHJpYnV0ZXMuYWxpZ25Db3JuZXJzID09PSAwXG4gICAgICAgID8gYFxuICAgIC8vIGFsaWduQ29ybmVyczogZmFsc2UgPT4gWy0xLCAxXSB0byBbLTAuNSwgbGVuZ3RoIC0gMC41XVxuICAgIHJldHVybiAoKG4gKyAxLjApICogZjMyKGxlbmd0aCkgLSAxLjApIC8gMi4wO1xuICAgIGBcbiAgICAgICAgOiBgXG4gICAgLy8gYWxpZ25Db3JuZXJzOiB0cnVlID0+IFstMSwgMV0gdG8gWzAsIGxlbmd0aCAtIDFdXG4gICAgcmV0dXJuIChuICsgMS4wKSAvIDIuMCAqIChmMzIobGVuZ3RoIC0gMSkpO1xuICAgIGBcbiAgICB9XG4gIH1cbmA7XG5cbmNvbnN0IGdzUmVmbGVjdCA9IChhdHRyaWJ1dGVzOiBHcmlkU2FtcGVBdHRyaWJ1dGVzKTogc3RyaW5nID0+IGBcbiAgJHtcbiAgICBhdHRyaWJ1dGVzLnBhZGRpbmdNb2RlID09PSAncmVmbGVjdGlvbidcbiAgICAgID8gYFxuICAgICAgZm4gZ3NfcmVmbGVjdCh4OiBpMzIsIHhfbWluOiBmMzIsIHhfbWF4OiBmMzIpIC0+IHUzMiB7XG4gICAgICAgIHZhciBkeCA9IDAuMDtcbiAgICAgICAgdmFyIGZ4ID0gZjMyKHgpO1xuICAgICAgICBsZXQgcmFuZ2UgPSB4X21heCAtIHhfbWluO1xuICAgICAgICBpZiAoZnggPCB4X21pbikge1xuICAgICAgICAgIGR4ID0geF9taW4gLSBmeDtcbiAgICAgICAgICBsZXQgbiA9IHUzMihkeCAvIHJhbmdlKTtcbiAgICAgICAgICBsZXQgciA9IGR4IC0gZjMyKG4pICogcmFuZ2U7XG4gICAgICAgICAgaWYgKG4gJSAyID09IDApIHtcbiAgICAgICAgICAgIGZ4ID0geF9taW4gKyByO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmeCA9IHhfbWF4IC0gcjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZnggPiB4X21heCkge1xuICAgICAgICAgIGR4ID0gZnggLSB4X21heDtcbiAgICAgICAgICBsZXQgbiA9IHUzMihkeCAvIHJhbmdlKTtcbiAgICAgICAgICBsZXQgciA9IGR4IC0gZjMyKG4pICogcmFuZ2U7XG4gICAgICAgICAgaWYgKG4gJSAyID09IDApIHtcbiAgICAgICAgICAgIGZ4ID0geF9tYXggLSByO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmeCA9IHhfbWluICsgcjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHUzMihmeCk7XG4gICAgICB9YFxuICAgICAgOiAnJ1xuICB9XG5gO1xuXG5jb25zdCBwaXhlbEF0R3JpZCA9IChpbnB1dDogSW5kaWNlc0hlbHBlciwgZGF0YVR5cGU6IHN0cmluZywgYXR0cmlidXRlczogR3JpZFNhbXBlQXR0cmlidXRlcyk6IHN0cmluZyA9PlxuICBgXG4gIGZuIHBpeGVsX2F0X2dyaWQocjogaTMyLCBjOiBpMzIsIEg6IGkzMiwgVzogaTMyLCBiYXRjaDogdTMyLCBjaGFubmVsOiB1MzIsIGJvcmRlcjogdmVjNDxmMzI+KSAtPiAke2RhdGFUeXBlfSB7XG4gICAgIHZhciBwaXhlbCA9ICR7ZGF0YVR5cGV9KDApO1xuICAgICB2YXIgaW5kaWNlcyA9IHZlYzQ8dTMyPigwKTtcbiAgICAgaW5kaWNlc1ske2lkeE59XSA9IGJhdGNoO1xuICAgICBpbmRpY2VzWyR7aWR4Q31dID0gY2hhbm5lbDtgICtcbiAgKCgpID0+IHtcbiAgICBzd2l0Y2ggKGF0dHJpYnV0ZXMucGFkZGluZ01vZGUpIHtcbiAgICAgIGNhc2UgJ3plcm9zJzpcbiAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICBpZiAociA+PSAwICYmIHIgPCBIICYmIGMgPj0wICYmIGMgPCBXKSB7XG4gICAgICAgICAgICBpbmRpY2VzWyR7aWR4SH1dID0gdTMyKHIpO1xuICAgICAgICAgICAgaW5kaWNlc1ske2lkeFd9XSA9IHUzMihjKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuICR7ZGF0YVR5cGV9KDApO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIGNhc2UgJ2JvcmRlcic6XG4gICAgICAgIHJldHVybiBgXG4gICAgICAgICAgaW5kaWNlc1ske2lkeEh9XSA9IHUzMihjbGFtcChyLCAwLCBIIC0gMSkpO1xuICAgICAgICAgIGluZGljZXNbJHtpZHhXfV0gPSB1MzIoY2xhbXAoYywgMCwgVyAtIDEpKTtcbiAgICAgICAgYDtcbiAgICAgIGNhc2UgJ3JlZmxlY3Rpb24nOlxuICAgICAgICByZXR1cm4gYFxuICAgICAgICAgIGluZGljZXNbJHtpZHhIfV0gPSBnc19yZWZsZWN0KHIsIGJvcmRlclsxXSwgYm9yZGVyWzNdKTtcbiAgICAgICAgICBpbmRpY2VzWyR7aWR4V31dID0gZ3NfcmVmbGVjdChjLCBib3JkZXJbMF0sIGJvcmRlclsyXSk7XG4gICAgICAgIGA7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHBhZGRpbmcgbW9kZSAke2F0dHJpYnV0ZXMucGFkZGluZ01vZGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICB9XG4gIH0pKCkgK1xuICBgXG4gICAgcmV0dXJuICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbmRpY2VzJyl9O1xuICB9XG5gO1xuXG5jb25zdCBjb21wdXRlUGl4ZWwgPSAob3V0cHV0OiBJbmRpY2VzSGVscGVyLCBkYXRhVHlwZTogc3RyaW5nLCBhdHRyaWJ1dGVzOiBHcmlkU2FtcGVBdHRyaWJ1dGVzKTogc3RyaW5nID0+XG4gICgoKSA9PiB7XG4gICAgc3dpdGNoIChhdHRyaWJ1dGVzLm1vZGUpIHtcbiAgICAgIGNhc2UgJ25lYXJlc3QnOlxuICAgICAgICByZXR1cm4gYFxuICAgICAgICAgIGxldCByZXN1bHQgPSBwaXhlbF9hdF9ncmlkKGkzMihyb3VuZCh5KSksIGkzMihyb3VuZCh4KSksIEhfaW4sIFdfaW4sIGluZGljZXNbJHtpZHhOfV0sIGluZGljZXNbJHtpZHhDfV0sIGJvcmRlcik7XG4gICAgICAgIGA7XG4gICAgICBjYXNlICdiaWxpbmVhcic6XG4gICAgICAgIHJldHVybiBgXG4gICAgICAgICAgbGV0IHgxID0gaTMyKGZsb29yKHgpKTtcbiAgICAgICAgICBsZXQgeTEgPSBpMzIoZmxvb3IoeSkpO1xuICAgICAgICAgIGxldCB4MiA9IHgxICsgMTtcbiAgICAgICAgICBsZXQgeTIgPSB5MSArIDE7XG5cbiAgICAgICAgICBsZXQgcDExID0gcGl4ZWxfYXRfZ3JpZCh5MSwgeDEsIEhfaW4sIFdfaW4sIGluZGljZXNbJHtpZHhOfV0sIGluZGljZXNbJHtpZHhDfV0sIGJvcmRlcik7XG4gICAgICAgICAgbGV0IHAxMiA9IHBpeGVsX2F0X2dyaWQoeTEsIHgyLCBIX2luLCBXX2luLCBpbmRpY2VzWyR7aWR4Tn1dLCBpbmRpY2VzWyR7aWR4Q31dLCBib3JkZXIpO1xuICAgICAgICAgIGxldCBwMjEgPSBwaXhlbF9hdF9ncmlkKHkyLCB4MSwgSF9pbiwgV19pbiwgaW5kaWNlc1ske2lkeE59XSwgaW5kaWNlc1ske2lkeEN9XSwgYm9yZGVyKTtcbiAgICAgICAgICBsZXQgcDIyID0gcGl4ZWxfYXRfZ3JpZCh5MiwgeDIsIEhfaW4sIFdfaW4sIGluZGljZXNbJHtpZHhOfV0sIGluZGljZXNbJHtpZHhDfV0sIGJvcmRlcik7XG5cbiAgICAgICAgICBsZXQgZHgyID0gJHtkYXRhVHlwZX0oZjMyKHgyKSAtIHgpO1xuICAgICAgICAgIGxldCBkeDEgPSAke2RhdGFUeXBlfSh4IC0gZjMyKHgxKSk7XG4gICAgICAgICAgbGV0IGR5MiA9ICR7ZGF0YVR5cGV9KGYzMih5MikgLSB5KTtcbiAgICAgICAgICBsZXQgZHkxID0gJHtkYXRhVHlwZX0oeSAtIGYzMih5MSkpO1xuICAgICAgICAgIGxldCByZXN1bHQgPSBkeTIgKiAoZHgyICogcDExICsgZHgxICogcDEyKSArIGR5MSAqIChkeDIgKiBwMjEgKyBkeDEgKiBwMjIpO1xuICAgICAgICBgO1xuICAgICAgY2FzZSAnYmljdWJpYyc6XG4gICAgICAgIHJldHVybiBgXG4gICAgICAgICAgbGV0IHgwID0gaTMyKGZsb29yKHgpKSAtIDE7XG4gICAgICAgICAgbGV0IHkwID0gaTMyKGZsb29yKHkpKSAtIDE7XG4gICAgICAgICAgdmFyIHA6IG1hdDR4NDwke2RhdGFUeXBlfT47XG4gICAgICAgICAgZm9yICh2YXIgaCA9IDA7IGggPCA0OyBoKyspIHtcbiAgICAgICAgICAgIGZvciAodmFyIHcgPSAwOyB3IDwgNDsgdysrKSB7XG4gICAgICAgICAgICAgIHBbaF1bd10gPSBwaXhlbF9hdF9ncmlkKGggKyB5MCwgdyArIHgwLCBIX2luLCBXX2luLCBpbmRpY2VzWyR7aWR4Tn1dLCBpbmRpY2VzWyR7aWR4Q31dLCBib3JkZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGxldCBkeCA9IHggLSBmMzIoeDAgKyAxKTtcbiAgICAgICAgICBsZXQgZHkgPSB5IC0gZjMyKHkwICsgMSk7XG4gICAgICAgICAgbGV0IHJlc3VsdCA9IGdzX2JpY3ViaWNfaW50ZXJwb2xhdGUocCwgZHgsIGR5KTtcbiAgICAgICAgYDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbW9kZSAke2F0dHJpYnV0ZXMubW9kZX0gaXMgbm90IHN1cHBvcnRlZGApO1xuICAgIH1cbiAgfSkoKSArIGAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICdyZXN1bHQnKX1gO1xuXG5jb25zdCBjcmVhdGVHcmlkU2FtcGxlUHJvZ3JhbUluZm8gPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IEdyaWRTYW1wZUF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHggPSBpbnB1dFZhcmlhYmxlKCd4JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dHNbMF0uZGltcy5sZW5ndGgpO1xuICAvLyBkaXNjYXJkIGxhc3QgZGltZW5zaW9uIGZvciB1c2luZyB2ZWMyIHRvIGFjY2VzcyBncmlkIGRhdGFcbiAgY29uc3QgZ3JpZFNoYXBlID0gW2lucHV0c1sxXS5kaW1zWzBdLCBpbnB1dHNbMV0uZGltc1sxXSwgaW5wdXRzWzFdLmRpbXNbMl1dO1xuICBjb25zdCBncmlkID0gaW5wdXRWYXJpYWJsZSgnZ3JpZCcsIGlucHV0c1sxXS5kYXRhVHlwZSwgZ3JpZFNoYXBlLmxlbmd0aCwgMik7XG4gIGxldCBvdXRwdXRTaGFwZSA9IFtpbnB1dHNbMF0uZGltc1swXSwgaW5wdXRzWzBdLmRpbXNbMV0sIGlucHV0c1sxXS5kaW1zWzFdLCBpbnB1dHNbMV0uZGltc1syXV07XG4gIGlmIChhdHRyaWJ1dGVzLmZvcm1hdCA9PT0gJ05IV0MnKSB7XG4gICAgb3V0cHV0U2hhcGUgPSBbaW5wdXRzWzBdLmRpbXNbMF0sIGlucHV0c1sxXS5kaW1zWzFdLCBpbnB1dHNbMV0uZGltc1syXSwgaW5wdXRzWzBdLmRpbXNbM11dO1xuICAgIFtpZHhOLCBpZHhDLCBpZHhILCBpZHhXXSA9IFswLCAzLCAxLCAyXTtcbiAgfVxuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBkYXRhVHlwZSA9IHgudHlwZS52YWx1ZTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcblxuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMF0uZGltcywgZ3JpZFNoYXBlLCBvdXRwdXRTaGFwZSksXG4gIF07XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiBgXG4gICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0X3NpemUnLCAndTMyJykuZGVjbGFyZVZhcmlhYmxlcyh4LCBncmlkLCBvdXRwdXQpfVxuICAke2dzR2V0Q3ViaWNDb2VmZnN9XG4gICR7Z3NCaWN1YmljSW50ZXJwb2xhdGUoZGF0YVR5cGUpfVxuICAke2dzRGVub3JtYWxpemUoYXR0cmlidXRlcyl9XG4gICR7Z3NSZWZsZWN0KGF0dHJpYnV0ZXMpfVxuICAke3BpeGVsQXRHcmlkKHgsIGRhdGFUeXBlLCBhdHRyaWJ1dGVzKX1cblxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRfc2l6ZScpfVxuICAgICAgbGV0IEhfaW4gPSBpMzIodW5pZm9ybXMueF9zaGFwZVske2lkeEh9XSk7XG4gICAgICBsZXQgV19pbiA9IGkzMih1bmlmb3Jtcy54X3NoYXBlWyR7aWR4V31dKTtcblxuICAgICAgJHtcbiAgICAgICAgYXR0cmlidXRlcy5hbGlnbkNvcm5lcnMgPT09IDBcbiAgICAgICAgICA/IGBcbiAgICAgIGxldCB4X21pbiA9IC0wLjU7XG4gICAgICBsZXQgeF9tYXggPSBmMzIoV19pbikgLSAwLjU7XG4gICAgICBsZXQgeV9taW4gPSAtMC41O1xuICAgICAgbGV0IHlfbWF4ID0gZjMyKEhfaW4pIC0gMC41O1xuICAgICAgYFxuICAgICAgICAgIDogYFxuICAgICAgbGV0IHhfbWluID0gMC4wO1xuICAgICAgbGV0IHhfbWF4ID0gZjMyKFdfaW4pIC0gMS4wO1xuICAgICAgbGV0IHlfbWluID0gMC4wO1xuICAgICAgbGV0IHlfbWF4ID0gZjMyKEhfaW4pIC0gMS4wO1xuICAgICAgYFxuICAgICAgfTtcbiAgICAgIGxldCBib3JkZXIgPSB2ZWM0PGYzMj4oeF9taW4sIHlfbWluLCB4X21heCwgeV9tYXgpO1xuXG4gICAgICBsZXQgaW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcbiAgICAgIHZhciBncmlkX2luZGljZXMgPSB2ZWMzPHUzMj4oaW5kaWNlc1ske2lkeE59XSwgaW5kaWNlc1ske2lkeEh9XSwgaW5kaWNlc1ske2lkeFd9XSk7XG4gICAgICBsZXQgbnh5ID0gJHtncmlkLmdldEJ5SW5kaWNlcygnZ3JpZF9pbmRpY2VzJyl9O1xuICAgICAgdmFyIHggPSBnc19kZW5vcm1hbGl6ZShmMzIobnh5WzBdKSwgV19pbik7XG4gICAgICB2YXIgeSA9IGdzX2Rlbm9ybWFsaXplKGYzMihueHlbMV0pLCBIX2luKTtcblxuICAgICAgJHtjb21wdXRlUGl4ZWwob3V0cHV0LCBkYXRhVHlwZSwgYXR0cmlidXRlcyl9XG4gIH1gO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0dyaWRTYW1wbGUnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke2F0dHJpYnV0ZXMuY2FjaGVLZXl9YCwgaW5wdXREZXBlbmRlbmNpZXM6IFsndHlwZScsICd0eXBlJ10gfSxcbiAgICBnZXRSdW5EYXRhOiAoaW5wdXRzKSA9PiB7XG4gICAgICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUgfV0sXG4gICAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgICAgfTtcbiAgICB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBncmlkU2FtcGxlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBHcmlkU2FtcGVBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUdyaWRTYW1wbGVQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcykpO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR3JpZFNhbXBsZUF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBHcmlkU2FtcGVBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgYWxpZ25Db3JuZXJzOiBhdHRyaWJ1dGVzLmFsaWduX2Nvcm5lcnMgYXMgbnVtYmVyLFxuICAgIG1vZGU6IGF0dHJpYnV0ZXMubW9kZSBhcyBNb2RlLFxuICAgIHBhZGRpbmdNb2RlOiBhdHRyaWJ1dGVzLnBhZGRpbmdfbW9kZSBhcyBQYWRkaW5nTW9kZSxcbiAgICBmb3JtYXQ6IGF0dHJpYnV0ZXMuZm9ybWF0IGFzIEZvcm1hdCxcbiAgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBHcHVEYXRhVHlwZSwgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGFwcGx5QXR0ZW50aW9uLFxuICBBdHRlbnRpb25BdHRycyxcbiAgQXR0ZW50aW9uTWFza1R5cGUsXG4gIEF0dGVudGlvblBhcmFtZXRlcnMsXG4gIEF0dGVudGlvblFrdkZvcm1hdCxcbn0gZnJvbSAnLi9hdHRlbnRpb24nO1xuaW1wb3J0IHsgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciwgVW5pZm9ybXNBcnJheVR5cGUgfSBmcm9tICcuL2NvbW1vbic7XG5pbXBvcnQgeyBjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbywgVHJhbnNwb3NlQXR0cmlidXRlcyB9IGZyb20gJy4vdHJhbnNwb3NlJztcblxuY29uc3QgZ2V0SW5wdXQgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGk6IG51bWJlcikgPT5cbiAgaW5wdXRzLmxlbmd0aCA+IGkgJiYgaW5wdXRzW2ldLmRpbXMubGVuZ3RoID4gMCA/IGlucHV0c1tpXSA6IHVuZGVmaW5lZDtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IEF0dGVudGlvbkF0dHJzKTogQXR0ZW50aW9uUGFyYW1ldGVycyA9PiB7XG4gIGNvbnN0IHF1ZXJ5ID0gaW5wdXRzWzBdO1xuICBjb25zdCBrZXkgPSBnZXRJbnB1dChpbnB1dHMsIDEpO1xuICBjb25zdCB2YWx1ZSA9IGdldElucHV0KGlucHV0cywgMik7XG4gIGNvbnN0IGJpYXMgPSBnZXRJbnB1dChpbnB1dHMsIDMpO1xuICBjb25zdCBrZXlQYWRkaW5nTWFzayA9IGdldElucHV0KGlucHV0cywgNCk7XG4gIGNvbnN0IGF0dGVudGlvbkJpYXMgPSBnZXRJbnB1dChpbnB1dHMsIDUpO1xuICBjb25zdCBwYXN0S2V5ID0gZ2V0SW5wdXQoaW5wdXRzLCA2KTtcbiAgY29uc3QgcGFzdFZhbHVlID0gZ2V0SW5wdXQoaW5wdXRzLCA3KTtcblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gTm90YXRpb25zOlxuICAvLyAgICBCOiBiYXRjaF9zaXplXG4gIC8vICAgIE46IG51bV9oZWFkc1xuICAvLyAgICBIOiBoZWFkX3NpemUgb2YgUSBhbmQgS1xuICAvLyAgICBIX3Y6IGhlYWRfc2l6ZSBvZiBWXG4gIC8vICAgIEQ6IGhpZGRlbl9zaXplIGZvciBRIGFuZCBLLCB3aGVyZSBEID0gTiAqIEhcbiAgLy8gICAgRF92OiBoaWRkZW5fc2l6ZSBvZiBWLCB3aGVyZSBEX3YgPSBOICogSF92XG4gIC8vICAgIFM6IHFfc2VxdWVuY2VfbGVuZ3RoXG4gIC8vICAgIFA6IHBhc3Rfc2VxdWVuY2VfbGVuZ3RoIG9mIGt2IGNhY2hlXG4gIC8vICAgIEw6IGt2X3NlcXVlbmNlX2xlbmd0aFxuICAvLyAgICBUOiB0b3RhbF9zZXF1ZW5jZV9sZW5ndGggPSBQICsgTFxuICAvLyAgICBNOiBtYXhfc2VxdWVuY2VfbGVuZ3RoIG9mIGt2IGNhY2hlIHdoZW4gcGFzdCBhbmQgcHJlc2VudCBzaGFyZSBidWZmZXJcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIE11bHRpSGVhZEF0dGVudGlvbiBpbnB1dHM6XG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyAgUV9LX1ZfQlNOSCAtIG5vIHBhY2tpbmc6XG4gIC8vICAgICBxdWVyeSAgICAgICAgICAgIChRKSAgICAgICA6IChCLCBTLCBEKVxuICAvLyAgICAga2V5ICAgICAgICAgICAgICAoSykgICAgICAgOiAoQiwgTCwgRClcbiAgLy8gICAgIHZhbHVlICAgICAgICAgICAgKFYpICAgICAgIDogKEIsIEwsIERfdilcbiAgLy8gIFFfS19WX0JTTkhfQk5TSF9CTlNIIC0gY3Jvc3MgYXR0ZW50aW9uIChrdiBjYWNoZSBpcyBub3QgdXNlZCwgTCA9PSBULCBEID09IERfdik6XG4gIC8vICAgICBxdWVyeSAgICAgICAgICAgIChRKSAgICAgICA6IChCLCBTLCBEKVxuICAvLyAgICAga2V5ICAgICAgICAgICAgICAoSykgICAgICAgOiAoQiwgTiwgTCwgSClcbiAgLy8gICAgIHZhbHVlICAgICAgICAgICAgKFYpICAgICAgIDogKEIsIE4sIEwsIEhfdilcbiAgLy8gIFFfS1ZfQlNOSF9CU04ySCAtIHBhY2tlZCBrdiAoa3YgY2FjaGUgaXMgbm90IHVzZWQsIGJpYXMgaXMgbm90IGFsbG93ZWQgZm9yIHBhY2tlZCBrdik6XG4gIC8vICAgICBxdWVyeSAgICAgICAgICAgIChRKSAgICAgICA6IChCLCBTLCBEKVxuICAvLyAgICAga2V5ICAgICAgICAgICAgICAoSy9WKSAgICAgOiAoQiwgTCwgTiwgMiwgSClcbiAgLy8gICAgIHZhbHVlICAgICAgICAgICAgICAgICAgICAgIDogTm9uZVxuICAvLyAgUUtWX0JTTjNIIC0gcGFja2VkIHFrdiAoa3YgY2FjaGUgaXMgbm90IHVzZWQsIFMgPT0gTCwgRCA9PSBEX3YpOlxuICAvLyAgICAgcXVlcnkgICAgICAgICAgICAoUS9LL1YpICAgOiAoQiwgUywgTiwgMywgSClcbiAgLy8gICAgIGtleSAgICAgICAgICAgICAgICAgICAgICAgIDogTm9uZVxuICAvLyAgICAgdmFsdWUgICAgICAgICAgICAgICAgICAgICAgOiBOb25lXG4gIC8vXG4gIC8vICBPdGhlciBpbnB1dHM6XG4gIC8vICAgICBiaWFzICAgICAgICAgICAgIChRL0svVikgICA6IE5vbmUgb3IgKEQgKyBEICsgRF92KVxuICAvLyAgICAga2V5X3BhZGRpbmdfbWFzayAoSy9WKSAgICAgOiAoQikgb3IgKDMgKiBCICsgMikgb3IgKEIsIFQpIG9yIChCLCBTLCBUKVxuICAvLyAgICAgYXR0ZW50aW9uX2JpYXMgICAgICAgICAgICAgOiBOb25lIG9yIChCLCBOLCBTLCBUKSwgKDEsIE4sIFMsIFQpLCAoQiwgMSwgUywgVCkgb3IgKDEsIDEsIFMsIFQpXG4gIC8vICAgICBwYXN0X2tleSAgICAgICAgICAgICAgICAgICA6IChCLCBOLCBQLCBIKSBvciBOb25lLiBQYXN0IHN0YXRlIGlzIG9ubHkgYWxsb3dlZCBmb3IgUV9LX1ZfQlNOSC5cbiAgLy8gICAgIHBhc3RfdmFsdWUgICAgICAgICAgICAgICAgIDogKEIsIE4sIFAsIEgpIG9yIE5vbmUuIFBhc3Qgc3RhdGUgaXMgb25seSBhbGxvd2VkIGZvciBRX0tfVl9CU05ILlxuICAvL1xuICAvLyAgTm90IFN1cHBvcnRlZDpcbiAgLy8gICAgIGtleV9wYWRkaW5nX21hc2ssIHBhY2tlZCBrdiwgcGFja2VkIHFrdiwgYW5kIGJyb2FkY2FzdCBmb3IgYXR0ZW50aW9uX2JpYXMuXG5cbiAgaWYgKHF1ZXJ5LmRpbXMubGVuZ3RoICE9PSAzICYmIHF1ZXJ5LmRpbXMubGVuZ3RoICE9PSA1KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBxdWVyeSBpcyBleHBlY3RlZCB0byBoYXZlIDMgb3IgNSBkaW1lbnNpb25zJyk7XG4gIH1cblxuICBjb25zdCBiYXRjaFNpemUgPSBxdWVyeS5kaW1zWzBdO1xuICBjb25zdCBzZXF1ZW5jZUxlbmd0aCA9IHF1ZXJ5LmRpbXNbMV07XG4gIGNvbnN0IGhpZGRlblNpemUgPSBxdWVyeS5kaW1zLmxlbmd0aCA9PT0gMyA/IHF1ZXJ5LmRpbXNbMl0gOiBhdHRyaWJ1dGVzLm51bUhlYWRzICogcXVlcnkuZGltc1s0XTtcbiAgbGV0IGt2U2VxdWVuY2VMZW5ndGggPSBzZXF1ZW5jZUxlbmd0aDtcblxuICBsZXQgcGFzdFNlcXVlbmNlTGVuZ3RoID0gMDtcbiAgbGV0IG1heFNlcXVlbmNlTGVuZ3RoID0gMDtcbiAgY29uc3QgaGVhZFNpemUgPSBNYXRoLmZsb29yKGhpZGRlblNpemUgLyBhdHRyaWJ1dGVzLm51bUhlYWRzKTtcbiAgaWYgKHBhc3RLZXkgJiYgcGFzdFZhbHVlICYmIFNoYXBlVXRpbC5zaXplKHBhc3RLZXkuZGltcykgJiYgU2hhcGVVdGlsLnNpemUocGFzdFZhbHVlLmRpbXMpKSB7XG4gICAgaWYgKHBhc3RLZXkuZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0X2tleVwiIGlzIGV4cGVjdGVkIHRvIGhhdmUgNCBkaW1lbnNpb25zJyk7XG4gICAgfVxuICAgIGlmIChwYXN0S2V5LmRpbXNbMF0gIT09IGJhdGNoU2l6ZSB8fCBwYXN0S2V5LmRpbXNbMV0gIT09IGF0dHJpYnV0ZXMubnVtSGVhZHMgfHwgcGFzdEtleS5kaW1zWzNdICE9PSBoZWFkU2l6ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcInBhc3Rfa2V5XCIgc2hhcGUgKGJhdGNoX3NpemUsIG51bV9oZWFkcywgcGFzdF9zZXF1ZW5jZV9sZW5ndGgsIGhlYWRfc2l6ZSknKTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgcGFzdFZhbHVlLmRpbXNbMF0gIT09IGJhdGNoU2l6ZSB8fFxuICAgICAgcGFzdFZhbHVlLmRpbXNbMV0gIT09IGF0dHJpYnV0ZXMubnVtSGVhZHMgfHxcbiAgICAgIHBhc3RWYWx1ZS5kaW1zWzNdICE9PSBoZWFkU2l6ZVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcInBhc3RfdmFsdWVcIiBzaGFwZSAoYmF0Y2hfc2l6ZSwgbnVtX2hlYWRzLCBwYXN0X3NlcXVlbmNlX2xlbmd0aCwgaGVhZF9zaXplKScpO1xuICAgIH1cbiAgICBpZiAocGFzdEtleS5kaW1zWzJdICE9PSBwYXN0VmFsdWUuZGltc1syXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcInBhc3Rfa2V5XCIgYW5kIFwicGFzdF92YWx1ZVwiIHNoYWxsIGhhdmUgc2FtZSBkaW0gMiAocGFzdF9zZXF1ZW5jZV9sZW5ndGgpJyk7XG4gICAgfVxuICAgIGlmIChwYXN0VmFsdWUuZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0X3ZhbHVlXCIgaXMgZXhwZWN0ZWQgdG8gaGF2ZSA0IGRpbWVuc2lvbnMnKTtcbiAgICB9XG4gICAgcGFzdFNlcXVlbmNlTGVuZ3RoID0gcGFzdEtleS5kaW1zWzJdO1xuICAgIG1heFNlcXVlbmNlTGVuZ3RoID0gcGFzdEtleS5kaW1zWzJdO1xuICB9IGVsc2UgaWYgKChwYXN0S2V5ICYmIFNoYXBlVXRpbC5zaXplKHBhc3RLZXkuZGltcykpIHx8IChwYXN0VmFsdWUgJiYgU2hhcGVVdGlsLnNpemUocGFzdFZhbHVlLmRpbXMpKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0X2tleVwiIGFuZCBcInBhc3RfdmFsdWVcIiBzaGFsbCBiZSBib3RoIHByZXNlbnQgb3IgYm90aCBhYnNlbnQnKTtcbiAgfVxuXG4gIGxldCBxa3ZGb3JtYXQ6IEF0dGVudGlvblFrdkZvcm1hdDtcbiAgaWYgKGtleSAmJiBTaGFwZVV0aWwuc2l6ZShrZXkuZGltcykgPiAwKSB7XG4gICAgaWYgKHF1ZXJ5LmRpbXMubGVuZ3RoICE9PSAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicXVlcnlcIiBpcyBleHBlY3RlZCB0byBoYXZlIDMgZGltZW5zaW9ucyB3aGVuIGtleSBpcyBnaXZlbicpO1xuICAgIH1cbiAgICBpZiAoa2V5LmRpbXMubGVuZ3RoIDwgMyB8fCBrZXkuZGltcy5sZW5ndGggPiA1KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwia2V5XCIgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAzLCA0LCBvciA1IGRpbWVuc2lvbnMnKTtcbiAgICB9XG4gICAgaWYgKHF1ZXJ5LmRpbXNbMF0gIT09IGtleS5kaW1zWzBdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicXVlcnlcIiBhbmQgXCJrZXlcIiBzaGFsbCBoYXZlIHNhbWUgZGltIDAgKGJhdGNoIHNpemUpJyk7XG4gICAgfVxuXG4gICAgaWYgKGtleS5kaW1zLmxlbmd0aCA9PT0gMykge1xuICAgICAgaWYgKGtleS5kaW1zWzJdICE9PSBxdWVyeS5kaW1zWzJdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJxdWVyeVwiIGFuZCBcImtleVwiIHNoYWxsIGhhdmUgc2FtZSBkaW0gMiAoaGlkZGVuX3NpemUpJyk7XG4gICAgICB9XG4gICAgICBxa3ZGb3JtYXQgPSBBdHRlbnRpb25Ra3ZGb3JtYXQucWt2QlNOSDtcbiAgICAgIGt2U2VxdWVuY2VMZW5ndGggPSBrZXkuZGltc1sxXTtcbiAgICB9IGVsc2UgaWYgKGtleS5kaW1zLmxlbmd0aCA9PT0gNSkge1xuICAgICAgaWYgKGtleS5kaW1zWzJdICE9PSBhdHRyaWJ1dGVzLm51bUhlYWRzIHx8IGtleS5kaW1zWzNdICE9PSAyIHx8IGtleS5kaW1zWzRdICE9PSBoZWFkU2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdCBcImtleVwiIHNoYXBlIChiYXRjaF9zaXplLCBrdl9zZXF1ZW5jZV9sZW5ndGgsIG51bV9oZWFkcywgMiwgaGVhZF9zaXplKSBmb3IgcGFja2VkIGt2Jyk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3QgXCJ2YWx1ZVwiIGJlIG5vbmUgd2hlbiBcImtleVwiIGhhcyBwYWNrZWQga3YgZm9ybWF0LicpO1xuICAgICAgfVxuICAgICAgcWt2Rm9ybWF0ID0gQXR0ZW50aW9uUWt2Rm9ybWF0LnFLdkJTTkh4QlNOMkg7XG4gICAgICBrdlNlcXVlbmNlTGVuZ3RoID0ga2V5LmRpbXNbMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGtleV9kaW1zLnNpemUoKSA9PSA0IChjcm9zcy1hdHRlbnRpb24gd2l0aCBwYXN0X2tleSlcbiAgICAgIGlmIChrZXkuZGltc1sxXSAhPT0gYXR0cmlidXRlcy5udW1IZWFkcyB8fCBrZXkuZGltc1szXSAhPT0gaGVhZFNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3QgXCJrZXlcIiBzaGFwZSAoYmF0Y2hfc2l6ZSwgbnVtX2hlYWRzLCBrdl9zZXF1ZW5jZV9sZW5ndGgsIGhlYWRfc2l6ZSkgZm9yIHBhc3Rfa2V5Jyk7XG4gICAgICB9XG5cbiAgICAgIHFrdkZvcm1hdCA9IEF0dGVudGlvblFrdkZvcm1hdC51bmtub3duOyAvLyBRX0tfVl9CU05IX0JOU0hfQk5TSFxuICAgICAga3ZTZXF1ZW5jZUxlbmd0aCA9IGtleS5kaW1zWzJdO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBwYWNrZWQgUUtWXG4gICAgaWYgKHF1ZXJ5LmRpbXMubGVuZ3RoICE9PSA1KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicXVlcnlcIiBpcyBleHBlY3RlZCB0byBoYXZlIDUgZGltZW5zaW9ucyB3aGVuIGtleSBpcyBlbXB0eScpO1xuICAgIH1cbiAgICBpZiAocXVlcnkuZGltc1syXSAhPT0gYXR0cmlidXRlcy5udW1IZWFkcyB8fCBxdWVyeS5kaW1zWzNdICE9PSAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdCBcInF1ZXJ5XCIgc2hhcGUgKGJhdGNoX3NpemUsIGt2X3NlcXVlbmNlX2xlbmd0aCwgbnVtX2hlYWRzLCAzLCBoZWFkX3NpemUpIGZvciBwYWNrZWQga3YnKTtcbiAgICB9XG5cbiAgICBxa3ZGb3JtYXQgPSBBdHRlbnRpb25Ra3ZGb3JtYXQucWt2QlNOM0g7XG4gIH1cblxuICBpZiAoYmlhcyAmJiBTaGFwZVV0aWwuc2l6ZShiaWFzLmRpbXMpID4gMCkge1xuICAgIGlmIChiaWFzLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwiYmlhc1wiIGlzIGV4cGVjdGVkIHRvIGhhdmUgMSBkaW1lbnNpb24nKTtcbiAgICB9XG5cbiAgICBpZiAoa2V5KSB7XG4gICAgICBpZiAoa2V5LmRpbXMubGVuZ3RoID09PSA1ICYmIGtleS5kaW1zWzNdID09PSAyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYmlhcyBpcyBub3QgYWxsb3dlZCBmb3IgcGFja2VkIGt2LicpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHRvdGFsU2VxdWVuY2VMZW5ndGggPSBwYXN0U2VxdWVuY2VMZW5ndGggKyBrdlNlcXVlbmNlTGVuZ3RoO1xuXG4gIGxldCBtYXNrVHlwZTogQXR0ZW50aW9uTWFza1R5cGUgPSBBdHRlbnRpb25NYXNrVHlwZS5ub25lO1xuICBpZiAoa2V5UGFkZGluZ01hc2sgJiYgU2hhcGVVdGlsLnNpemUoa2V5UGFkZGluZ01hc2suZGltcykgPiAwKSB7XG4gICAgbWFza1R5cGUgPSBBdHRlbnRpb25NYXNrVHlwZS5tYXNrVW5rbm93bjtcbiAgICBjb25zdCBtYXNrRGltcyA9IGtleVBhZGRpbmdNYXNrLmRpbXM7XG4gICAgaWYgKG1hc2tEaW1zLmxlbmd0aCA9PT0gMSkge1xuICAgICAgaWYgKG1hc2tEaW1zWzBdID09PSBiYXRjaFNpemUpIHtcbiAgICAgICAgbWFza1R5cGUgPSBBdHRlbnRpb25NYXNrVHlwZS5tYXNrMWRLZXlTZXFMZW47XG4gICAgICB9IGVsc2UgaWYgKG1hc2tEaW1zWzBdID09PSAzICogYmF0Y2hTaXplICsgMikge1xuICAgICAgICBtYXNrVHlwZSA9IEF0dGVudGlvbk1hc2tUeXBlLm1hc2sxREtleVNlcUxlblN0YXJ0O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobWFza0RpbXMubGVuZ3RoID09PSAyICYmIG1hc2tEaW1zWzBdID09PSBiYXRjaFNpemUgJiYgbWFza0RpbXNbMV0gPT09IHRvdGFsU2VxdWVuY2VMZW5ndGgpIHtcbiAgICAgIG1hc2tUeXBlID0gQXR0ZW50aW9uTWFza1R5cGUubWFzazJkS2V5UGFkZGluZztcbiAgICB9XG4gICAgaWYgKG1hc2tUeXBlID09PSBBdHRlbnRpb25NYXNrVHlwZS5tYXNrVW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcImtleV9wYWRkaW5nX21hc2tcIiBzaGFwZSBzaGFsbCBiZSAoYmF0Y2hfc2l6ZSkgb3IgKGJhdGNoX3NpemUsIHRvdGFsX3NlcXVlbmNlX2xlbmd0aCknKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNYXNrIG5vdCBzdXBwb3J0ZWQnKTtcbiAgfVxuXG4gIGxldCBwYXNzUGFzdEluS3YgPSBmYWxzZTtcbiAgbGV0IHZIaWRkZW5TaXplID0gaGlkZGVuU2l6ZTtcbiAgaWYgKHZhbHVlICYmIFNoYXBlVXRpbC5zaXplKHZhbHVlLmRpbXMpID4gMCkge1xuICAgIGlmICh2YWx1ZS5kaW1zLmxlbmd0aCAhPT0gMyAmJiB2YWx1ZS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcInZhbHVlXCIgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAzIG9yIDQgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGlmIChxdWVyeS5kaW1zWzBdICE9PSB2YWx1ZS5kaW1zWzBdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicXVlcnlcIiBhbmQgXCJ2YWx1ZVwiIHNoYWxsIGhhdmUgc2FtZSBkaW0gMCAoYmF0Y2hfc2l6ZSknKTtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUuZGltcy5sZW5ndGggPT09IDMpIHtcbiAgICAgIGlmIChrdlNlcXVlbmNlTGVuZ3RoICE9PSB2YWx1ZS5kaW1zWzFdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJrZXlcIiBhbmQgXCJ2YWx1ZVwiIHNoYWxsIGhhdmUgdGhlIHNhbWUgZGltIDEgKGt2X3NlcXVlbmNlX2xlbmd0aCknKTtcbiAgICAgIH1cbiAgICAgIHZIaWRkZW5TaXplID0gdmFsdWUuZGltc1syXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUV9LX1ZfQlNOSF9CTlNIX0JOU0hcbiAgICAgIGlmIChrdlNlcXVlbmNlTGVuZ3RoICE9PSB2YWx1ZS5kaW1zWzJdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJrZXlcIiBhbmQgXCJ2YWx1ZVwiIHNoYWxsIGhhdmUgdGhlIHNhbWUgZGltIDIgKGt2X3NlcXVlbmNlX2xlbmd0aCknKTtcbiAgICAgIH1cbiAgICAgIHZIaWRkZW5TaXplID0gdmFsdWUuZGltc1sxXSAqIHZhbHVlLmRpbXNbM107XG4gICAgICBwYXNzUGFzdEluS3YgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGJyb2FkY2FzdFJlc1Bvc0JpYXMgPSBmYWxzZTtcblxuICBpZiAoa2V5UGFkZGluZ01hc2sgJiYgU2hhcGVVdGlsLnNpemUoa2V5UGFkZGluZ01hc2suZGltcykgPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdLZXkgcGFkZGluZyBtYXNrIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgfVxuXG4gIGlmIChhdHRlbnRpb25CaWFzICYmIFNoYXBlVXRpbC5zaXplKGF0dGVudGlvbkJpYXMuZGltcykgPiAwKSB7XG4gICAgaWYgKGF0dGVudGlvbkJpYXMuZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJhdHRlbnRpb25fYmlhc1wiIGlzIGV4cGVjdGVkIHRvIGhhdmUgNCBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogc3VwcG9ydCBicm9hZGNhc3RpbmcgdGhlIGZpcnN0IGFuZCBzZWNvbmQgZGltZW5zaW9ucyBvZiBhdHRlbnRpb25fYmlhcy5cbiAgICBpZiAoXG4gICAgICBhdHRlbnRpb25CaWFzLmRpbXNbMF0gIT09IGJhdGNoU2l6ZSB8fFxuICAgICAgYXR0ZW50aW9uQmlhcy5kaW1zWzFdICE9PSBhdHRyaWJ1dGVzLm51bUhlYWRzIHx8XG4gICAgICBhdHRlbnRpb25CaWFzLmRpbXNbMl0gIT09IHNlcXVlbmNlTGVuZ3RoIHx8XG4gICAgICBhdHRlbnRpb25CaWFzLmRpbXNbM10gIT09IHRvdGFsU2VxdWVuY2VMZW5ndGhcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0IFwiYXR0ZW50aW9uX2JpYXNcIiBzaGFwZSAoYmF0Y2hfc2l6ZSwgbnVtX2hlYWRzLCBzZXF1ZW5jZV9sZW5ndGgsIHRvdGFsX3NlcXVlbmNlX2xlbmd0aCknKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJhdGNoU2l6ZSxcbiAgICBzZXF1ZW5jZUxlbmd0aCxcbiAgICBwYXN0U2VxdWVuY2VMZW5ndGgsXG4gICAga3ZTZXF1ZW5jZUxlbmd0aCxcbiAgICB0b3RhbFNlcXVlbmNlTGVuZ3RoLFxuICAgIG1heFNlcXVlbmNlTGVuZ3RoLFxuICAgIGlucHV0SGlkZGVuU2l6ZTogMCxcbiAgICBoaWRkZW5TaXplLFxuICAgIHZIaWRkZW5TaXplLFxuICAgIGhlYWRTaXplLFxuICAgIHZIZWFkU2l6ZTogTWF0aC5mbG9vcih2SGlkZGVuU2l6ZSAvIGF0dHJpYnV0ZXMubnVtSGVhZHMpLFxuICAgIG51bUhlYWRzOiBhdHRyaWJ1dGVzLm51bUhlYWRzLFxuICAgIGlzVW5pZGlyZWN0aW9uYWw6IGZhbHNlLFxuICAgIHBhc3RQcmVzZW50U2hhcmVCdWZmZXI6IGZhbHNlLFxuICAgIG1hc2tGaWx0ZXJWYWx1ZTogYXR0cmlidXRlcy5tYXNrRmlsdGVyVmFsdWUsXG4gICAgbWFza1R5cGUsXG4gICAgc2NhbGU6IGF0dHJpYnV0ZXMuc2NhbGUsXG4gICAgYnJvYWRjYXN0UmVzUG9zQmlhcyxcbiAgICBwYXNzUGFzdEluS3YsXG4gICAgcWt2Rm9ybWF0LFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTXVsdGlIZWFkQXR0ZW50aW9uQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBBdHRlbnRpb25BdHRycyk6IEF0dGVudGlvbkF0dHJzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IC4uLmF0dHJpYnV0ZXMgfSk7XG5cbmNvbnN0IHdlaWdodFRyYW5zcG9zZUF0dHJpYnV0ZTogVHJhbnNwb3NlQXR0cmlidXRlcyA9IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IHBlcm06IFswLCAyLCAxLCAzXSB9KTtcblxuY29uc3QgYWRkQmlhc1RyYW5zcG9zZSA9IChcbiAgY29udGV4dDogQ29tcHV0ZUNvbnRleHQsXG4gIHFrdjogVGVuc29yVmlldyxcbiAgYmlhczogVGVuc29yVmlldyxcbiAgYmF0Y2hTaXplOiBudW1iZXIsXG4gIHNlcXVlbmNlTGVuZ3RoOiBudW1iZXIsXG4gIGhpZGRlblNpemU6IG51bWJlcixcbiAgYmlhc09mZnNldDogbnVtYmVyLFxuKSA9PiB7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW2JhdGNoU2l6ZSwgc2VxdWVuY2VMZW5ndGgsIGhpZGRlblNpemVdO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYmlhc09mZnNldCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBoaWRkZW5TaXplIH0sXG4gIF07XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ3Frdl93aXRoX2JpYXMnLCBxa3YuZGF0YVR5cGUsIG91dHB1dFNoYXBlKTtcbiAgICBjb25zdCBxa3ZJbnB1dCA9IGlucHV0VmFyaWFibGUoJ3FrdicsIHFrdi5kYXRhVHlwZSwgb3V0cHV0U2hhcGUpO1xuICAgIGNvbnN0IGJpYXNJbnB1dCA9IGlucHV0VmFyaWFibGUoJ2JpYXMnLCBiaWFzLmRhdGFUeXBlLCBvdXRwdXRTaGFwZSk7XG5cbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdiaWFzX29mZnNldCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdoaWRkZW5fc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgXTtcbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKHFrdklucHV0LCBiaWFzSW5wdXQsIG91dHB1dCl9XG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgbGV0IGJpYXNfb2Zmc2V0X2lkeCA9IChnbG9iYWxfaWR4ICUgdW5pZm9ybXMuaGlkZGVuX3NpemUpICsgdW5pZm9ybXMuYmlhc19vZmZzZXQ7XG5cbiAgICBxa3Zfd2l0aF9iaWFzW2dsb2JhbF9pZHhdID0gcWt2W2dsb2JhbF9pZHhdICsgYmlhc1tiaWFzX29mZnNldF9pZHhdO1xuICB9YDtcbiAgfTtcblxuICByZXR1cm4gY29udGV4dC5jb21wdXRlKFxuICAgIHtcbiAgICAgIG5hbWU6ICdNdWx0aUhlYWRBdHRlbnRpb25BZGRCaWFzJyxcbiAgICAgIHNoYWRlckNhY2hlOiB7IGlucHV0RGVwZW5kZW5jaWVzOiBbJ3R5cGUnLCAndHlwZSddIH0sXG4gICAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IHFrdi5kYXRhVHlwZSwgZ3B1RGF0YVR5cGU6IEdwdURhdGFUeXBlLmRlZmF1bHQgfV0sXG4gICAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgICAgfSksXG4gICAgICBnZXRTaGFkZXJTb3VyY2UsXG4gICAgfSxcbiAgICB7IGlucHV0czogW3FrdiwgYmlhc10sIG91dHB1dHM6IFstMV0gfSxcbiAgKVswXTtcbn07XG5cbmV4cG9ydCBjb25zdCBtYXliZVRyYW5zcG9zZVRvQk5TSEFuZEFkZEJpYXMgPSAoXG4gIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LFxuICBiYXRjaFNpemU6IG51bWJlcixcbiAgbnVtSGVhZHM6IG51bWJlcixcbiAgc2VxdWVuY2VMZW5ndGg6IG51bWJlcixcbiAgaGVhZFNpemU6IG51bWJlcixcbiAgaW5wdXQ6IFRlbnNvclZpZXcsXG4gIGJpYXM/OiBUZW5zb3JWaWV3LFxuICBiaWFzT2Zmc2V0PzogbnVtYmVyLFxuKSA9PiB7XG4gIC8vIGNvbnN0IG5ld0RpbXMgPSBbXTtcblxuICBsZXQgcmVzaGFwZWRJbnB1dCA9IGlucHV0O1xuICBpZiAoIShiaWFzICYmIFNoYXBlVXRpbC5zaXplKGJpYXMuZGltcykgPiAwKSkge1xuICAgIGlmIChpbnB1dC5kaW1zLmxlbmd0aCA9PT0gMykge1xuICAgICAgcmVzaGFwZWRJbnB1dCA9IGlucHV0LnJlc2hhcGUoW2JhdGNoU2l6ZSwgc2VxdWVuY2VMZW5ndGgsIG51bUhlYWRzLCBoZWFkU2l6ZV0pO1xuICAgIH1cbiAgICBpZiAobnVtSGVhZHMgPT09IDEgfHwgc2VxdWVuY2VMZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiByZXNoYXBlZElucHV0O1xuICAgIH1cbiAgICByZXR1cm4gY29udGV4dC5jb21wdXRlKGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvKHJlc2hhcGVkSW5wdXQsIHdlaWdodFRyYW5zcG9zZUF0dHJpYnV0ZS5wZXJtKSwge1xuICAgICAgaW5wdXRzOiBbcmVzaGFwZWRJbnB1dF0sXG4gICAgICBvdXRwdXRzOiBbLTFdLFxuICAgIH0pWzBdO1xuICB9IGVsc2Uge1xuICAgIGlmIChzZXF1ZW5jZUxlbmd0aCA9PT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBZGRCaWFzUmVzaGFwZSBpcyBub3QgaW1wbGVtZW50ZWQuIFBsZWFzZSBleHBvcnQgeW91ciBtb2RlbCB3aXRoIHBhY2tlZCBRS1Ygb3IgS1YnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzaGFwZWRJbnB1dCA9IGFkZEJpYXNUcmFuc3Bvc2UoXG4gICAgICAgIGNvbnRleHQsXG4gICAgICAgIGlucHV0LFxuICAgICAgICBiaWFzLFxuICAgICAgICBiYXRjaFNpemUsXG4gICAgICAgIHNlcXVlbmNlTGVuZ3RoLFxuICAgICAgICBudW1IZWFkcyAqIGhlYWRTaXplLFxuICAgICAgICBiaWFzT2Zmc2V0ISxcbiAgICAgICk7XG4gICAgICByZXNoYXBlZElucHV0ID0gcmVzaGFwZWRJbnB1dC5yZXNoYXBlKFtiYXRjaFNpemUsIHNlcXVlbmNlTGVuZ3RoLCBudW1IZWFkcywgaGVhZFNpemVdKTtcbiAgICAgIGlmIChudW1IZWFkcyA9PT0gMSB8fCBzZXF1ZW5jZUxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gcmVzaGFwZWRJbnB1dDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb250ZXh0LmNvbXB1dGUoY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8ocmVzaGFwZWRJbnB1dCwgd2VpZ2h0VHJhbnNwb3NlQXR0cmlidXRlLnBlcm0pLCB7XG4gICAgICAgIGlucHV0czogW3Jlc2hhcGVkSW5wdXRdLFxuICAgICAgICBvdXRwdXRzOiBbLTFdLFxuICAgICAgfSlbMF07XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgY29uc3QgbXVsdGlIZWFkQXR0ZW50aW9uID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBdHRlbnRpb25BdHRycyk6IHZvaWQgPT4ge1xuICBjb25zdCBwYXJhbXMgPSB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG4gIGNvbnN0IHF1ZXJ5ID0gY29udGV4dC5pbnB1dHNbMF07XG4gIGNvbnN0IGtleSA9IGdldElucHV0KGNvbnRleHQuaW5wdXRzLCAxKTtcbiAgY29uc3QgdmFsdWUgPSBnZXRJbnB1dChjb250ZXh0LmlucHV0cywgMik7XG4gIGNvbnN0IGJpYXMgPSBnZXRJbnB1dChjb250ZXh0LmlucHV0cywgMyk7XG4gIGNvbnN0IGtleVBhZGRpbmdNYXNrID0gZ2V0SW5wdXQoY29udGV4dC5pbnB1dHMsIDQpO1xuICBjb25zdCBhdHRlbnRpb25CaWFzID0gZ2V0SW5wdXQoY29udGV4dC5pbnB1dHMsIDUpO1xuICBjb25zdCBwYXN0S2V5ID0gZ2V0SW5wdXQoY29udGV4dC5pbnB1dHMsIDYpO1xuICBjb25zdCBwYXN0VmFsdWUgPSBnZXRJbnB1dChjb250ZXh0LmlucHV0cywgNyk7XG4gIGlmIChxdWVyeS5kaW1zLmxlbmd0aCA9PT0gNSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUGFja2VkIFFLViBpcyBub3QgaW1wbGVtZW50ZWQnKTtcbiAgfVxuXG4gIGlmIChrZXk/LmRpbXMubGVuZ3RoID09PSA1KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQYWNrZWQgS1YgaXMgbm90IGltcGxlbWVudGVkJyk7XG4gIH1cblxuICAvLyBhcHBseUF0dGVudGlvbiBleHBlY3RzIEJOU0ggaW5wdXRzXG4gIGNvbnN0IGt2Qk5TSCA9IGtleSAmJiB2YWx1ZSAmJiBrZXkuZGltcy5sZW5ndGggPT09IDQgJiYgdmFsdWUuZGltcy5sZW5ndGggPT09IDQ7XG5cbiAgY29uc3QgUSA9IG1heWJlVHJhbnNwb3NlVG9CTlNIQW5kQWRkQmlhcyhcbiAgICBjb250ZXh0LFxuICAgIHBhcmFtcy5iYXRjaFNpemUsXG4gICAgcGFyYW1zLm51bUhlYWRzLFxuICAgIHBhcmFtcy5zZXF1ZW5jZUxlbmd0aCxcbiAgICBwYXJhbXMuaGVhZFNpemUsXG4gICAgcXVlcnksXG4gICAgYmlhcyxcbiAgICAwLFxuICApO1xuXG4gIGlmIChrdkJOU0gpIHtcbiAgICByZXR1cm4gYXBwbHlBdHRlbnRpb24oY29udGV4dCwgUSwga2V5LCB2YWx1ZSwga2V5UGFkZGluZ01hc2ssIHVuZGVmaW5lZCwgcGFzdEtleSwgcGFzdFZhbHVlLCBhdHRlbnRpb25CaWFzLCBwYXJhbXMpO1xuICB9XG4gIGlmICgha2V5IHx8ICF2YWx1ZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigna2V5IGFuZCB2YWx1ZSBtdXN0IGJlIHByb3ZpZGVkJyk7XG4gIH1cbiAgY29uc3QgSyA9IG1heWJlVHJhbnNwb3NlVG9CTlNIQW5kQWRkQmlhcyhcbiAgICBjb250ZXh0LFxuICAgIHBhcmFtcy5iYXRjaFNpemUsXG4gICAgcGFyYW1zLm51bUhlYWRzLFxuICAgIHBhcmFtcy5rdlNlcXVlbmNlTGVuZ3RoLFxuICAgIHBhcmFtcy5oZWFkU2l6ZSxcbiAgICBrZXksXG4gICAgYmlhcyxcbiAgICBwYXJhbXMuaGlkZGVuU2l6ZSxcbiAgKTtcblxuICBjb25zdCBWID0gbWF5YmVUcmFuc3Bvc2VUb0JOU0hBbmRBZGRCaWFzKFxuICAgIGNvbnRleHQsXG4gICAgcGFyYW1zLmJhdGNoU2l6ZSxcbiAgICBwYXJhbXMubnVtSGVhZHMsXG4gICAgcGFyYW1zLmt2U2VxdWVuY2VMZW5ndGgsXG4gICAgcGFyYW1zLnZIZWFkU2l6ZSxcbiAgICB2YWx1ZSxcbiAgICBiaWFzLFxuICAgIDIgKiBwYXJhbXMuaGlkZGVuU2l6ZSxcbiAgKTtcblxuICBhcHBseUF0dGVudGlvbihjb250ZXh0LCBRLCBLLCBWLCBrZXlQYWRkaW5nTWFzaywgdW5kZWZpbmVkLCBwYXN0S2V5LCBwYXN0VmFsdWUsIGF0dGVudGlvbkJpYXMsIHBhcmFtcyk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0sIFRlbnNvckluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLFxuICBnZXRFbGVtZW50QXQsXG4gIEluZGljZXNIZWxwZXIsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG59IGZyb20gJy4vY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBTcGxpdEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG4gIHJlYWRvbmx5IG51bU91dHB1dHM6IG51bWJlcjtcbiAgcmVhZG9ubHkgc3BsaXRTaXplczogbnVtYmVyW107XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0b28gZmV3IGlucHV0cycpO1xuICB9XG59O1xuXG5jb25zdCBjcmVhdGVTcGxpdEF0dHJpYnV0ZXNGcm9tSW5wdXRzID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzLFxuKTogU3BsaXRBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3Qgc3BsaXRTaXplczogbnVtYmVyW10gPSBbXTtcbiAgbGV0IG51bU91dHB1dHM6IG51bWJlciA9IGF0dHJpYnV0ZXMubnVtT3V0cHV0cztcbiAgaWYgKGlucHV0c1sxXS5kaW1zWzBdID4gMCkge1xuICAgIGlucHV0c1sxXS5nZXRCaWdJbnQ2NEFycmF5KCkuZm9yRWFjaCgodikgPT4gc3BsaXRTaXplcy5wdXNoKE51bWJlcih2KSkpO1xuICAgIG51bU91dHB1dHMgPSBzcGxpdFNpemVzLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgbnVtT3V0cHV0cywgYXhpczogYXR0cmlidXRlcy5heGlzLCBzcGxpdFNpemVzIH0pO1xufTtcblxuY29uc3QgY2FsY3VsYXRlT3V0cHV0SW5kZXhJbXBsID0gKG51bWJlck9mVGVuc29yczogbnVtYmVyKTogc3RyaW5nID0+IGBcbmZuIGNhbGN1bGF0ZU91dHB1dEluZGV4KGluZGV4OiB1MzIpIC0+IHUzMiB7XG4gICAgZm9yICh2YXIgaTogdTMyID0gMHU7IGkgPCAke251bWJlck9mVGVuc29yc311OyBpICs9IDF1ICkge1xuICAgIGlmIChpbmRleCA8ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5zaXplX2luX3NwbGl0X2F4aXMnLCAnaScsIG51bWJlck9mVGVuc29ycyl9KSB7XG4gICAgICAgIHJldHVybiBpO1xuICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICR7bnVtYmVyT2ZUZW5zb3JzfXU7XG59YDtcbmNvbnN0IHdyaXRlQnVmZmVyRGF0YUltcGwgPSAob3V0cHV0czogcmVhZG9ubHkgSW5kaWNlc0hlbHBlcltdKSA9PiB7XG4gIGNvbnN0IG51bWJlck9mVGVuc29ycyA9IG91dHB1dHMubGVuZ3RoO1xuICBjb25zdCBjb2RlTGluZXM6IHN0cmluZ1tdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZUZW5zb3JzOyArK2kpIHtcbiAgICBjb25zdCByZXR1cm5TbmlwcGV0ID0gb3V0cHV0c1tpXS5zZXRCeUluZGljZXMoJ2luZGljZXMnLCAnaW5wdXRbZ2xvYmFsX2lkeF0nKTtcbiAgICBpZiAobnVtYmVyT2ZUZW5zb3JzID09PSAxKSB7XG4gICAgICBjb2RlTGluZXMucHVzaChyZXR1cm5TbmlwcGV0KTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IDApIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKGBpZiAob3V0cHV0X251bWJlciA9PSAke2l9dSkgeyAke3JldHVyblNuaXBwZXR9IH1gKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IG51bWJlck9mVGVuc29ycyAtIDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKGBlbHNlIHsgJHtyZXR1cm5TbmlwcGV0fSB9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKGBlbHNlIGlmIChvdXRwdXRfbnVtYmVyID09ICR7aX0pIHsgJHtyZXR1cm5TbmlwcGV0fSB9YCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBgXG4gICAgICBmbiB3cml0ZUJ1ZmZlckRhdGEob3V0cHV0X251bWJlcjogdTMyLCBpbmRpY2VzOiAke291dHB1dHNbMF0udHlwZS5pbmRpY2VzfSwgZ2xvYmFsX2lkeDogdTMyKSB7XG4gICAgICAgICR7Y29kZUxpbmVzLmpvaW4oJ1xcbicpfVxuICAgICAgfWA7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlU3BsaXRQcm9ncmFtSW5mbyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGlucHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKGlucHV0U2hhcGUpO1xuICBjb25zdCBkYXRhVHlwZSA9IGlucHV0c1swXS5kYXRhVHlwZTtcbiAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgaW5wdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBvdXRwdXRzID0gbmV3IEFycmF5PEluZGljZXNIZWxwZXI+KGF0dHJpYnV0ZXMubnVtT3V0cHV0cyk7XG4gIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnaW5wdXQnLCBkYXRhVHlwZSwgaW5wdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBzaXplSW5TcGxpdEF4aXMgPSBuZXcgQXJyYXk8bnVtYmVyPihhdHRyaWJ1dGVzLm51bU91dHB1dHMpO1xuICBjb25zdCBvdXRwdXRzVGVuc29ySW5mbzogVGVuc29ySW5mb1tdID0gW107XG4gIGNvbnN0IG91dHB1dFNoYXBlczogbnVtYmVyW11bXSA9IFtdO1xuICBsZXQgcHJldmlvdXNTdW0gPSAwO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGlucHV0U2l6ZSB9XTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLm51bU91dHB1dHM7IGkrKykge1xuICAgIHByZXZpb3VzU3VtICs9IGF0dHJpYnV0ZXMuc3BsaXRTaXplc1tpXTtcbiAgICBzaXplSW5TcGxpdEF4aXNbaV0gPSBwcmV2aW91c1N1bTtcbiAgICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0U2hhcGUuc2xpY2UoKTtcbiAgICBvdXRwdXRTaGFwZVtheGlzXSA9IGF0dHJpYnV0ZXMuc3BsaXRTaXplc1tpXTtcbiAgICBvdXRwdXRTaGFwZXMucHVzaChvdXRwdXRTaGFwZSk7XG4gICAgb3V0cHV0c1tpXSA9IG91dHB1dFZhcmlhYmxlKGBvdXRwdXQke2l9YCwgZGF0YVR5cGUsIG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgb3V0cHV0c1RlbnNvckluZm8ucHVzaCh7IGRpbXM6IG91dHB1dFNoYXBlc1tpXSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9KTtcbiAgfVxuICBwcm9ncmFtVW5pZm9ybXMucHVzaChcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogc2l6ZUluU3BsaXRBeGlzIH0sXG4gICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRTaGFwZSwgLi4ub3V0cHV0U2hhcGVzKSxcbiAgKTtcbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiBgXG4gICR7c2hhZGVySGVscGVyXG4gICAgLnJlZ2lzdGVyVW5pZm9ybSgnaW5wdXRfc2l6ZScsICd1MzInKVxuICAgIC5yZWdpc3RlclVuaWZvcm0oJ3NpemVfaW5fc3BsaXRfYXhpcycsICd1MzInLCBzaXplSW5TcGxpdEF4aXMubGVuZ3RoKVxuICAgIC5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCAuLi5vdXRwdXRzKX1cbiAgJHtjYWxjdWxhdGVPdXRwdXRJbmRleEltcGwoc2l6ZUluU3BsaXRBeGlzLmxlbmd0aCl9XG4gICR7d3JpdGVCdWZmZXJEYXRhSW1wbChvdXRwdXRzKX1cblxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5pbnB1dF9zaXplJyl9XG5cbiAgICB2YXIgaW5kaWNlcyA9ICR7aW5wdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuICAgIHZhciBpbmRleCA9ICR7aW5wdXQuaW5kaWNlc0dldCgnaW5kaWNlcycsIGF4aXMpfTtcbiAgICBsZXQgb3V0cHV0X251bWJlciA9IGNhbGN1bGF0ZU91dHB1dEluZGV4KGluZGV4KTtcbiAgICBpZiAob3V0cHV0X251bWJlciAhPSAwKSB7XG4gICAgICBpbmRleCAtPSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMuc2l6ZV9pbl9zcGxpdF9heGlzJywgJ291dHB1dF9udW1iZXIgLSAxdScsIHNpemVJblNwbGl0QXhpcy5sZW5ndGgpfTtcbiAgICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5kaWNlcycsIGF4aXMsICdpbmRleCcpfTtcbiAgICB9XG4gICAgd3JpdGVCdWZmZXJEYXRhKG91dHB1dF9udW1iZXIsIGluZGljZXMsIGdsb2JhbF9pZHgpO1xuICB9YDtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnU3BsaXQnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnXSB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogb3V0cHV0c1RlbnNvckluZm8sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChpbnB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBzcGxpdCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgdXBkYXRlZEF0dHJpYnV0ZXMgPVxuICAgIGNvbnRleHQuaW5wdXRzLmxlbmd0aCA9PT0gMSA/IGF0dHJpYnV0ZXMgOiBjcmVhdGVTcGxpdEF0dHJpYnV0ZXNGcm9tSW5wdXRzKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZVNwbGl0UHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIHVwZGF0ZWRBdHRyaWJ1dGVzKSwgeyBpbnB1dHM6IFswXSB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNwbGl0QXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFNwbGl0QXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF4aXMgPSBhdHRyaWJ1dGVzLmF4aXMgYXMgbnVtYmVyO1xuICBjb25zdCBzcGxpdFNpemVzOiBudW1iZXJbXSA9IGF0dHJpYnV0ZXMuc3BsaXRTaXplcyBhcyBudW1iZXJbXTtcbiAgY29uc3QgbnVtT3V0cHV0cyA9IChhdHRyaWJ1dGVzLm51bU91dHB1dHMgYXMgbnVtYmVyKSA8IDAgPyBzcGxpdFNpemVzLmxlbmd0aCA6IChhdHRyaWJ1dGVzLm51bU91dHB1dHMgYXMgbnVtYmVyKTtcbiAgaWYgKG51bU91dHB1dHMgIT09IHNwbGl0U2l6ZXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdudW1PdXRwdXRzIGFuZCBzcGxpdFNpemVzIGxlbmd0aCBtdXN0IGJlIGVxdWFsJyk7XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF4aXMsIG51bU91dHB1dHMsIHNwbGl0U2l6ZXMgfSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcywgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciwgV09SS0dST1VQX1NJWkUgfSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUm90YXJ5RW1iZWRkaW5nQXR0cmlidXRlcyB7XG4gIHJlYWRvbmx5IGludGVybGVhdmVkOiBib29sZWFuO1xuICByZWFkb25seSBudW1IZWFkczogbnVtYmVyO1xuICByZWFkb25seSByb3RhcnlFbWJlZGRpbmdEaW06IG51bWJlcjtcbiAgcmVhZG9ubHkgc2NhbGU6IG51bWJlcjtcbn1cblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IFJvdGFyeUVtYmVkZGluZ0F0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgY29uc3QgW2lucHV0LCBwb3NpdGlvbklkcywgY29zQ2FjaGUsIHNpbkNhY2hlXSA9IGlucHV0cztcbiAgY29uc3QgeyBudW1IZWFkcywgcm90YXJ5RW1iZWRkaW5nRGltIH0gPSBhdHRyaWJ1dGVzO1xuXG4gIGlmIChpbnB1dC5kaW1zLmxlbmd0aCAhPT0gMyAmJiBpbnB1dC5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgJ3gnIGlzIGV4cGVjdGVkIHRvIGhhdmUgMyBvciA0IGRpbWVuc2lvbnMsIGdvdCAke2lucHV0LmRpbXMubGVuZ3RofWApO1xuICB9XG4gIGlmIChcbiAgICAhU2hhcGVVdGlsLmFyZUVxdWFsKHBvc2l0aW9uSWRzLmRpbXMsIFtdKSAmJlxuICAgICFTaGFwZVV0aWwuYXJlRXF1YWwocG9zaXRpb25JZHMuZGltcywgWzFdKSAmJlxuICAgIHBvc2l0aW9uSWRzLmRpbXMubGVuZ3RoICE9PSAyXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgJ3Bvc2l0aW9uX2lkcycgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAwLCAxLCBvciAyIGRpbWVuc2lvbnMsIGdvdCAke3Bvc2l0aW9uSWRzLmRpbXMubGVuZ3RofWApO1xuICB9XG4gIGlmIChjb3NDYWNoZS5kaW1zLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgJ2Nvc19jYWNoZScgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAyIGRpbWVuc2lvbnMsIGdvdCAke2Nvc0NhY2hlLmRpbXMubGVuZ3RofWApO1xuICB9XG4gIGlmIChzaW5DYWNoZS5kaW1zLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgJ3Npbl9jYWNoZScgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAyIGRpbWVuc2lvbnMsIGdvdCAke3NpbkNhY2hlLmRpbXMubGVuZ3RofWApO1xuICB9XG4gIGlmICghU2hhcGVVdGlsLmFyZUVxdWFsKGNvc0NhY2hlLmRpbXMsIHNpbkNhY2hlLmRpbXMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSW5wdXRzICdjb3NfY2FjaGUnIGFuZCAnc2luX2NhY2hlJyBhcmUgZXhwZWN0ZWQgdG8gaGF2ZSB0aGUgc2FtZSBzaGFwZVwiKTtcbiAgfVxuXG4gIGlmIChyb3RhcnlFbWJlZGRpbmdEaW0gPiAwICYmIG51bUhlYWRzID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdudW1faGVhZHMgbXVzdCBiZSBwcm92aWRlZCBpZiByb3RhcnlfZW1iZWRkaW5nX2RpbSBpcyBzcGVjaWZpZWQnKTtcbiAgfVxuXG4gIGNvbnN0IGJhdGNoU2l6ZSA9IGlucHV0LmRpbXNbMF07XG4gIGNvbnN0IHNlcXVlbmNlTGVuZ3RoID0gaW5wdXQuZGltc1tpbnB1dC5kaW1zLmxlbmd0aCAtIDJdO1xuICBjb25zdCBtYXhTZXF1ZW5jZUxlbmd0aCA9IGNvc0NhY2hlLmRpbXNbMF07XG4gIGNvbnN0IGhpZGRlblNpemUgPSBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24oaW5wdXQuZGltcywgMSkgLyBzZXF1ZW5jZUxlbmd0aDtcbiAgY29uc3QgaGVhZFNpemUgPSByb3RhcnlFbWJlZGRpbmdEaW0gPT09IDAgPyBjb3NDYWNoZS5kaW1zWzFdICogMiA6IGhpZGRlblNpemUgLyBudW1IZWFkcztcbiAgaWYgKHJvdGFyeUVtYmVkZGluZ0RpbSA+IGhlYWRTaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdyb3RhcnlfZW1iZWRkaW5nX2RpbSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byBoZWFkX3NpemUnKTtcbiAgfVxuXG4gIGlmIChwb3NpdGlvbklkcy5kaW1zLmxlbmd0aCA9PT0gMikge1xuICAgIGlmIChiYXRjaFNpemUgIT09IHBvc2l0aW9uSWRzLmRpbXNbMF0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgJ3Bvc2l0aW9uX2lkcycgZGltZW5zaW9uIDAgc2hvdWxkIGJlIG9mIHNpemUgYmF0Y2hfc2l6ZSwgZ290ICR7cG9zaXRpb25JZHMuZGltc1swXX1gKTtcbiAgICB9XG4gICAgaWYgKHNlcXVlbmNlTGVuZ3RoICE9PSBwb3NpdGlvbklkcy5kaW1zWzFdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYElucHV0ICdwb3NpdGlvbl9pZHMnIGRpbWVuc2lvbiAxIHNob3VsZCBiZSBvZiBzaXplIHNlcXVlbmNlX2xlbmd0aCwgZ290ICR7cG9zaXRpb25JZHMuZGltc1sxXX1gKTtcbiAgICB9XG4gIH1cblxuICBpZiAoc2VxdWVuY2VMZW5ndGggPiBtYXhTZXF1ZW5jZUxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignVXBkYXRpbmcgY29zX2NhY2hlIGFuZCBzaW5fY2FjaGUgaW4gUm90YXJ5RW1iZWRkaW5nIGlzIG5vdCBjdXJyZW50bHkgc3VwcG9ydGVkJyk7XG4gIH1cblxuICAvLyBOb3RlOiBwb3NpdGlvbl9pZHMgdmFsdWUgdmFsaWRhdGlvbiBpcyBoYW5kbGVkIGJ5IHNoYWRlci1zaWRlIGJvdW5kcyBjaGVja3MgKGRlZmVuc2UtaW4tZGVwdGgpLlxuICAvLyBXZSBjYW5ub3QgdmFsaWRhdGUgcG9zaXRpb25faWRzIHZhbHVlcyBoZXJlIGJlY2F1c2UgdGhlIHRlbnNvciBpcyBHUFUtcmVzaWRlbnQgXHUyMDE0IGl0cyBkYXRhIGZpZWxkXG4gIC8vIGlzIGEgR1BVIGJ1ZmZlciBJRCwgbm90IGEgV0FTTSBoZWFwIHBvaW50ZXIsIHNvIGdldEJpZ0ludDY0QXJyYXkoKSB3b3VsZCByZWFkIGdhcmJhZ2UuXG5cbiAgaWYgKGhlYWRTaXplIC8gMiAhPT0gY29zQ2FjaGUuZGltc1sxXSAmJiByb3RhcnlFbWJlZGRpbmdEaW0gLyAyICE9PSBjb3NDYWNoZS5kaW1zWzFdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYElucHV0ICdjb3NfY2FjaGUnIGRpbWVuc2lvbiAxIHNob3VsZCBiZSBzYW1lIGFzIGhlYWRfc2l6ZSAvIDIgb3Igcm90YXJ5X2VtYmVkZGluZ19kaW0gLyAyLCBnb3QgJHtcbiAgICAgICAgY29zQ2FjaGUuZGltc1sxXVxuICAgICAgfWAsXG4gICAgKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVJvdGFyeUVtYmVkZGluZ1Byb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogUm90YXJ5RW1iZWRkaW5nQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgeyBpbnRlcmxlYXZlZCwgbnVtSGVhZHMsIHJvdGFyeUVtYmVkZGluZ0RpbSwgc2NhbGUgfSA9IGF0dHJpYnV0ZXM7XG4gIGNvbnN0IGJhdGNoU2l6ZSA9IGlucHV0c1swXS5kaW1zWzBdO1xuICBjb25zdCBiYXRjaFN0cmlkZSA9IFNoYXBlVXRpbC5zaXplRnJvbURpbWVuc2lvbihpbnB1dHNbMF0uZGltcywgMSk7XG4gIGNvbnN0IHNlcXVlbmNlTGVuZ3RoID0gaW5wdXRzWzBdLmRpbXNbaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMl07XG4gIGNvbnN0IGhpZGRlblNpemUgPSBiYXRjaFN0cmlkZSAvIHNlcXVlbmNlTGVuZ3RoO1xuICBjb25zdCBoYWxmUm90YXJ5RW1iZWRkaW5nRGltID0gaW5wdXRzWzJdLmRpbXNbMV07XG4gIGNvbnN0IGhlYWRTaXplID0gcm90YXJ5RW1iZWRkaW5nRGltID09PSAwID8gaGFsZlJvdGFyeUVtYmVkZGluZ0RpbSAqIDIgOiBoaWRkZW5TaXplIC8gbnVtSGVhZHM7XG5cbiAgLy8gUm90YXJ5IGVtYmVkZGluZ3Mgd2lsbCBiZSBjYWxjdWxhdGVkIGluIGEgcGFpci13aXNlIGZhc2hpb24uIEluIGFjY29yZGFuY2UsIHVzZSB0aGUgc2hhcGVcbiAgLy8gW2JhdGNoIHNpemUsIHNlcXVlbmNlIGxlbmd0aCwgbnVtIG9mIGhlYWRzLCBudW0gb2YgcGFpcnMgdG8gcm90YXRlICsgbnVtIG9mIGRpbXMgdG8gY29weV1cbiAgLy8gdG8gdW5mb2xkIHRoZSBnbG9iYWwgaW5kZXggaW4gc2hhZGVyLlxuICBjb25zdCBnbG9iYWxTaGFwZSA9IG5ldyBBcnJheTxudW1iZXI+KFxuICAgIGJhdGNoU2l6ZSxcbiAgICBzZXF1ZW5jZUxlbmd0aCxcbiAgICBoaWRkZW5TaXplIC8gaGVhZFNpemUsXG4gICAgaGVhZFNpemUgLSBoYWxmUm90YXJ5RW1iZWRkaW5nRGltLFxuICApO1xuICBjb25zdCBnbG9iYWxTdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGdsb2JhbFNoYXBlKTtcblxuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS5mbG9hdCwgZGF0YTogc2NhbGUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogZ2xvYmFsU2hhcGUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogZ2xvYmFsU3RyaWRlcyB9LFxuXG4gICAgLy8gc3RyaWRlcyBmb3IgYWRkcmVzc2luZyB0aGUgaW5wdXQvb3V0cHV0IHRlbnNvciwgaW4gcGVybXV0YXRlZCBvcmRlciB0byBhbGlnbiB3aXRoIHRoZSB1bmZvbGRlZCBnbG9iYWwgaW5kZXgsXG4gICAgLy8gaS5lLiBCU05IXG4gICAgLi4uKGlucHV0c1swXS5kaW1zLmxlbmd0aCA9PT0gM1xuICAgICAgPyBuZXcgQXJyYXk8UHJvZ3JhbVVuaWZvcm0+KHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBbYmF0Y2hTdHJpZGUsIGhpZGRlblNpemUsIGhlYWRTaXplLCAxXSB9KVxuICAgICAgOiBbXSksXG4gICAgLi4uKGlucHV0c1swXS5kaW1zLmxlbmd0aCA9PT0gNFxuICAgICAgPyBuZXcgQXJyYXk8UHJvZ3JhbVVuaWZvcm0+KHtcbiAgICAgICAgICB0eXBlOiBEYXRhVHlwZS51aW50MzIsXG4gICAgICAgICAgZGF0YTogW2JhdGNoU3RyaWRlLCBoZWFkU2l6ZSwgc2VxdWVuY2VMZW5ndGggKiBoZWFkU2l6ZSwgMV0sXG4gICAgICAgIH0pXG4gICAgICA6IFtdKSxcblxuICAgIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0c1swXS5kaW1zLCBpbnB1dHNbMV0uZGltcywgaW5wdXRzWzJdLmRpbXMsIGlucHV0c1szXS5kaW1zLCBpbnB1dHNbMF0uZGltcyksXG4gIF07XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgaW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdpbnB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgICBjb25zdCBwb3NpdGlvbklkcyA9IGlucHV0VmFyaWFibGUoJ3Bvc2l0aW9uX2lkcycsIGlucHV0c1sxXS5kYXRhVHlwZSwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoKTtcbiAgICBjb25zdCBjb3NDYWNoZSA9IGlucHV0VmFyaWFibGUoJ2Nvc19jYWNoZScsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoKTtcbiAgICBjb25zdCBzaW5DYWNoZSA9IGlucHV0VmFyaWFibGUoJ3Npbl9jYWNoZScsIGlucHV0c1szXS5kYXRhVHlwZSwgaW5wdXRzWzNdLmRpbXMubGVuZ3RoKTtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dHNbMF0uZGltcy5sZW5ndGgpO1xuXG4gICAgc2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXMoW1xuICAgICAgeyBuYW1lOiAnc2NhbGUnLCB0eXBlOiAnZjMyJyB9LFxuICAgICAgeyBuYW1lOiAnZ2xvYmFsX3NoYXBlJywgdHlwZTogJ3UzMicsIGxlbmd0aDogZ2xvYmFsU2hhcGUubGVuZ3RoIH0sXG4gICAgICB7IG5hbWU6ICdnbG9iYWxfc3RyaWRlcycsIHR5cGU6ICd1MzInLCBsZW5ndGg6IGdsb2JhbFN0cmlkZXMubGVuZ3RoIH0sXG4gICAgICB7IG5hbWU6ICdpbnB1dF9vdXRwdXRfc3RyaWRlcycsIHR5cGU6ICd1MzInLCBsZW5ndGg6IGdsb2JhbFN0cmlkZXMubGVuZ3RoIH0sXG4gICAgXSk7XG5cbiAgICByZXR1cm4gYFxuICAgICAgICAke3NoYWRlckhlbHBlci5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCBwb3NpdGlvbklkcywgY29zQ2FjaGUsIHNpbkNhY2hlLCBvdXRwdXQpfVxuXG4gICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydChXT1JLR1JPVVBfU0laRSl9XG4gICAgICAgICAgbGV0IGhhbGZfcm90YXJ5X2VtYl9kaW0gPSB1bmlmb3Jtcy4ke2Nvc0NhY2hlLm5hbWV9X3NoYXBlWzFdO1xuICAgICAgICAgIGxldCBic25oID0gZ2xvYmFsX2lkeCAvIHVuaWZvcm1zLmdsb2JhbF9zdHJpZGVzICUgdW5pZm9ybXMuZ2xvYmFsX3NoYXBlO1xuICAgICAgICAgIGxldCBzaXplID0gdW5pZm9ybXMuZ2xvYmFsX3NoYXBlWzBdICogdW5pZm9ybXMuZ2xvYmFsX3N0cmlkZXNbMF07XG4gICAgICAgICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygnc2l6ZScpfVxuXG4gICAgICAgICAgaWYgKGJzbmhbM10gPCBoYWxmX3JvdGFyeV9lbWJfZGltKSB7XG4gICAgICAgICAgICBsZXQgcG9zaXRpb25faWRzX2lkeCA9XG4gICAgICAgICAgICAgICAgJHtwb3NpdGlvbklkcy5icm9hZGNhc3RlZEluZGljZXNUb09mZnNldCgnYnNuaC54eScsIG91dHB1dFZhcmlhYmxlKCcnLCBwb3NpdGlvbklkcy50eXBlLnRlbnNvciwgMikpfTtcbiAgICAgICAgICAgIGxldCBwb3NpdGlvbl9pZCA9XG4gICAgICAgICAgICAgICAgdTMyKCR7cG9zaXRpb25JZHMuZ2V0QnlPZmZzZXQoJ3Bvc2l0aW9uX2lkc19pZHgnKX0pICsgc2VsZWN0KDAsIGJzbmhbMV0sIHBvc2l0aW9uX2lkc19pZHggPT0gMCk7XG4gICAgICAgICAgICBsZXQgaSA9IGRvdChic25oLCB1bmlmb3Jtcy5pbnB1dF9vdXRwdXRfc3RyaWRlcykgKyBzZWxlY3QoMCwgYnNuaFszXSwgJHtpbnRlcmxlYXZlZH0pO1xuICAgICAgICAgICAgbGV0IGogPSBpICsgc2VsZWN0KGhhbGZfcm90YXJ5X2VtYl9kaW0sIDEsICR7aW50ZXJsZWF2ZWR9KTtcbiAgICAgICAgICAgIGxldCByZSA9ICR7aW5wdXQuZ2V0QnlPZmZzZXQoJ2knKX0gKiAke2Nvc0NhY2hlLmdldCgncG9zaXRpb25faWQnLCAnYnNuaFszXScpfSAtXG4gICAgICAgICAgICAgICAgJHtpbnB1dC5nZXRCeU9mZnNldCgnaicpfSAqICR7c2luQ2FjaGUuZ2V0KCdwb3NpdGlvbl9pZCcsICdic25oWzNdJyl9O1xuICAgICAgICAgICAgJHtvdXRwdXQuc2V0QnlPZmZzZXQoJ2knLCAncmUnKX1cbiAgICAgICAgICAgIGxldCBpbSA9ICR7aW5wdXQuZ2V0QnlPZmZzZXQoJ2knKX0gKiAke3NpbkNhY2hlLmdldCgncG9zaXRpb25faWQnLCAnYnNuaFszXScpfSArXG4gICAgICAgICAgICAgICAgJHtpbnB1dC5nZXRCeU9mZnNldCgnaicpfSAqICR7Y29zQ2FjaGUuZ2V0KCdwb3NpdGlvbl9pZCcsICdic25oWzNdJyl9O1xuICAgICAgICAgICAgJHtvdXRwdXQuc2V0QnlPZmZzZXQoJ2onLCAnaW0nKX1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGsgPSBkb3QoYnNuaCwgdW5pZm9ybXMuaW5wdXRfb3V0cHV0X3N0cmlkZXMpICsgaGFsZl9yb3RhcnlfZW1iX2RpbTtcbiAgICAgICAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdrJywgaW5wdXQuZ2V0QnlPZmZzZXQoJ2snKSl9XG4gICAgICAgICAgfVxuICAgICAgICB9YDtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdSb3RhcnlFbWJlZGRpbmcnLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe1xuICAgICAgICBpbnRlcmxlYXZlZCxcbiAgICAgIH0pLmNhY2hlS2V5LFxuICAgICAgaW5wdXREZXBlbmRlbmNpZXM6IFsncmFuaycsICdyYW5rJywgJ3JhbmsnLCAncmFuayddLFxuICAgIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBpbnB1dHNbMF0uZGltcywgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKFNoYXBlVXRpbC5zaXplKGdsb2JhbFNoYXBlKSAvIFdPUktHUk9VUF9TSVpFKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHJvdGFyeUVtYmVkZGluZyA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUm90YXJ5RW1iZWRkaW5nQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVSb3RhcnlFbWJlZGRpbmdQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcykpO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3ksIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5cbmltcG9ydCB7IGFwcGx5QXR0ZW50aW9uLCBBdHRlbnRpb25NYXNrVHlwZSwgQXR0ZW50aW9uUGFyYW1ldGVycywgQXR0ZW50aW9uUWt2Rm9ybWF0IH0gZnJvbSAnLi9hdHRlbnRpb24nO1xuaW1wb3J0IHsgbWF5YmVUcmFuc3Bvc2VUb0JOU0hBbmRBZGRCaWFzIH0gZnJvbSAnLi9tdWx0aWhlYWQtYXR0ZW50aW9uJztcbmltcG9ydCB7IGNyZWF0ZVNwbGl0UHJvZ3JhbUluZm8sIFNwbGl0QXR0cmlidXRlcyB9IGZyb20gJy4vc3BsaXQnO1xuaW1wb3J0IHsgY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8sIFRyYW5zcG9zZUF0dHJpYnV0ZXMgfSBmcm9tICcuL3RyYW5zcG9zZSc7XG5pbXBvcnQgeyBSb3RhcnlFbWJlZGRpbmdBdHRyaWJ1dGVzLCBjcmVhdGVSb3RhcnlFbWJlZGRpbmdQcm9ncmFtSW5mbyB9IGZyb20gJy4vcm90YXJ5LWVtYmVkZGluZyc7XG5pbXBvcnQgeyBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyLCBVbmlmb3Jtc0FycmF5VHlwZSB9IGZyb20gJy4vY29tbW9uJztcbmV4cG9ydCBpbnRlcmZhY2UgR3JvdXBRdWVyeUF0dGVudGlvbkF0dHJpYnV0ZXMge1xuICBudW1IZWFkczogbnVtYmVyO1xuICBrdk51bUhlYWRzOiBudW1iZXI7XG4gIHNjYWxlOiBudW1iZXI7XG4gIHNvZnRjYXA6IG51bWJlcjtcbiAgZG9Sb3Rhcnk6IG51bWJlcjtcbiAgcm90YXJ5SW50ZXJsZWF2ZWQ6IG51bWJlcjtcbiAgc21vb3RoU29mdG1heDogYm9vbGVhbjtcbiAgbG9jYWxXaW5kb3dTaXplOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZUlucHV0cyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IEdyb3VwUXVlcnlBdHRlbnRpb25BdHRyaWJ1dGVzLFxuKTogQXR0ZW50aW9uUGFyYW1ldGVycyA9PiB7XG4gIGlmIChhdHRyaWJ1dGVzLmRvUm90YXJ5ICYmIGlucHV0cy5sZW5ndGggPD0gNykge1xuICAgIHRocm93IG5ldyBFcnJvcignY29zX2NhY2hlIGFuZCBzaW5fY2FjaGUgaW5wdXRzIGFyZSByZXF1aXJlZCBpZiBkb19yb3RhcnkgaXMgc3BlY2lmaWVkJyk7XG4gIH1cbiAgY29uc3QgcXVlcnkgPSBpbnB1dHNbMF07XG4gIGNvbnN0IGtleSA9IGlucHV0c1sxXTtcbiAgY29uc3QgdmFsdWUgPSBpbnB1dHNbMl07XG4gIGNvbnN0IHBhc3RLZXkgPSBpbnB1dHNbM107XG4gIGNvbnN0IHBhc3RWYWx1ZSA9IGlucHV0c1s0XTtcbiAgaWYgKGF0dHJpYnV0ZXMuZG9Sb3RhcnkgIT09IDAgJiYgaW5wdXRzLmxlbmd0aCA8PSA3KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjb3NfY2FzdCBhbmQgc2luX2NhY2hlIGFyZSBleHBlY3RlZCBpZiBkb19yb3RhcnkgYXR0cmlidXRlIGlzIG5vbi16ZXJvJyk7XG4gIH1cbiAgaWYgKGF0dHJpYnV0ZXMubG9jYWxXaW5kb3dTaXplICE9PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTG9jYWwgYXR0ZW50aW9uIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgfVxuICBpZiAoYXR0cmlidXRlcy5zb2Z0Y2FwICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTb2Z0Y2FwIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgfVxuICBpZiAoYXR0cmlidXRlcy5yb3RhcnlJbnRlcmxlYXZlZCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignUm90YXJ5IGludGVybGVhdmVkIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgfVxuICBpZiAoYXR0cmlidXRlcy5zbW9vdGhTb2Z0bWF4KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTbW9vdGggc29mdG1heCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gIH1cbiAgLy8gQWJicmV2aWF0aW9uIGFuZCBNZWFuaW5nczpcbiAgLy8gICBCOiAgICBiYXRjaF9zaXplXG4gIC8vICAgUzogICAgc2VxdWVuY2VfbGVuZ3RoIChpbnB1dCBzZXF1ZW5jZSBsZW5ndGggb2YgcXVlcnkpXG4gIC8vICAgUDogICAgcGFzdF9zZXF1ZW5jZV9sZW5ndGggKHBhc3Qgc2VxdWVuY2UgbGVuZ3RoIG9mIGtleSBvciB2YWx1ZSlcbiAgLy8gICBMOiAgICBrdl9zZXF1ZW5jZV9sZW5ndGggKGlucHV0IHNlcXVlbmNlIGxlbmd0aCBvZiBrZXkgb3IgdmFsdWUpXG4gIC8vICAgTTogICAgbWF4X3NlcXVlbmNlX2xlbmd0aFxuICAvLyAgIFQ6ICAgIHRvdGFsX3NlcXVlbmNlX2xlbmd0aCA9IHBhc3Rfc2VxdWVuY2VfbGVuZ3RoICsga3Zfc2VxdWVuY2VfbGVuZ3RoXG4gIC8vICAgTjogICAgbnVtX2hlYWRzXG4gIC8vICAgSDogICAgaGVhZCBzaXplIGZvciBRIGFuZCBLLCBha2EgcV9oZWFkX3NpemUgb3Iga19oZWFkX3NpemUgb3IgcWtfaGVhZF9zaXplXG4gIC8vICAgSF92OiAgdl9oZWFkX3NpemVcbiAgLy8gICBEX2k6ICBpbnB1dCBoaWRkZW4gc2l6ZVxuICAvLyAgIEQ6ICAgIGhpZGRlbiBzaXplIGZvciBRIGFuZCBLIChEID0gTiAqIEgpLCBha2EgcV9oaWRkZW5fc2l6ZSBvciBrX2hpZGRlbl9zaXplIG9yIHFrX2hpZGRlbl9zaXplXG4gIC8vICAgRF92OiAgdl9oaWRkZW5fc2l6ZSA9IG51bV9oZWFkcyAqIHZfaGVhZF9zaXplXG5cbiAgLy8gICAgIHBhc3Rfa2V5ICAgICAgICAgICAgICAgICAgIDogKEIsIE4sIFMqLCBIKVxuICAvLyAgICAgcGFzdF92YWx1ZSAgICAgICAgICAgICAgICAgOiAoQiwgTiwgUyosIEgpXG4gIC8vIFdoZW4gbm8gcGFja2luZyBmb3IgcS9rL3Y6XG4gIC8vICAgICBxdWVyeSAgICAgICAgICAgIChRKSAgICAgICA6IChCLCBTLCBEKVxuICAvLyAgICAga2V5ICAgICAgICAgICAgICAoSykgICAgICAgOiAoQiwgTCwgRCkgb3IgKEIsIE4sIFMqLCBIKVxuICAvLyAgICAgdmFsdWUgICAgICAgICAgICAoVikgICAgICAgOiAoQiwgTCwgRF92KSBvciAoQiwgTiwgUyosIEgpXG4gIC8vIFdoZW4gcGFja2VkIGt2IGlzIHVzZWQ6XG4gIC8vICAgICBxdWVyeSAgICAgICAgICAgIChRKSAgICAgICA6IChCLCBTLCBEKVxuICAvLyAgICAga2V5ICAgICAgICAgICAgICAoSykgICAgICAgOiAoQiwgTCwgTiwgMiwgSClcbiAgLy8gICAgIHZhbHVlICAgICAgICAgICAgKFYpICAgICAgIDogTm9uZVxuICAvLyBXaGVuIHBhY2tlZCBxa3YgaXMgdXNlZDpcbiAgLy8gICAgIHF1ZXJ5ICAgICAgICAgICAgKFEpICAgICAgIDogKEIsIEwsIE4sIDMsIEgpIG9yIChCLCBTLCAzKkQpXG4gIC8vICAgICBrZXkgICAgICAgICAgICAgIChLKSAgICAgICA6IE5vbmVcbiAgLy8gICAgIHZhbHVlICAgICAgICAgICAgKFYpICAgICAgIDogTm9uZVxuXG4gIGlmIChxdWVyeS5kaW1zLmxlbmd0aCAhPT0gMyAmJiBxdWVyeS5kaW1zLmxlbmd0aCAhPT0gNSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgcXVlcnkgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAzIG9yIDUgZGltZW5zaW9ucycpO1xuICB9XG5cbiAgY29uc3QgZG1taGFQYWNraW5nID0gZmFsc2U7XG4gIGNvbnN0IGJhdGNoU2l6ZSA9IHF1ZXJ5LmRpbXNbMF07XG4gIGNvbnN0IHNlcXVlbmNlTGVuZ3RoID0gcXVlcnkuZGltc1sxXTtcbiAgbGV0IGhpZGRlblNpemUgPVxuICAgIHF1ZXJ5LmRpbXMubGVuZ3RoID09PSAzID8gKGRtbWhhUGFja2luZyA/IHF1ZXJ5LmRpbXNbMl0gLyAzIDogcXVlcnkuZGltc1syXSkgOiBhdHRyaWJ1dGVzLm51bUhlYWRzICogcXVlcnkuZGltc1s0XTtcbiAgbGV0IGt2U2VxdWVuY2VMZW5ndGggPSBzZXF1ZW5jZUxlbmd0aDtcblxuICBsZXQgcGFzdFNlcXVlbmNlTGVuZ3RoID0gMDtcbiAgY29uc3QgcGFja2VkUUtWID0gIWtleSB8fCBrZXkuZGltcy5sZW5ndGggPT09IDA7XG4gIGNvbnN0IGhlYWRTaXplID0gIXBhY2tlZFFLVlxuICAgID8gTWF0aC5mbG9vcihoaWRkZW5TaXplIC8gYXR0cmlidXRlcy5udW1IZWFkcylcbiAgICA6IE1hdGguZmxvb3IoaGlkZGVuU2l6ZSAvIChhdHRyaWJ1dGVzLm51bUhlYWRzICsgMiAqIGF0dHJpYnV0ZXMua3ZOdW1IZWFkcykpO1xuICBpZiAocGFja2VkUUtWKSB7XG4gICAgaGlkZGVuU2l6ZSA9IGhlYWRTaXplICogYXR0cmlidXRlcy5udW1IZWFkcztcbiAgfVxuICBjb25zdCBoYXNQYXN0S2V5ID0gcGFzdEtleSAmJiBwYXN0S2V5LmRpbXMubGVuZ3RoICE9PSAwO1xuICBjb25zdCBoYXNQYXN0VmFsdWUgPSBwYXN0VmFsdWUgJiYgcGFzdFZhbHVlLmRpbXMubGVuZ3RoICE9PSAwO1xuICAvLyBDdXJyZW50bHkgdGhlIG9ubnhydW50aW1lIEdRQSBzcGVjaWZpY2F0aW9uIG9ubHkgc3VwcG9ydCBrZXkvdmFsdWUgQk5TSCBmb3JtYXQuXG4gIGNvbnN0IGlzUGFzdGt2QlNOSCA9XG4gICAgaGFzUGFzdEtleSAmJlxuICAgIHBhc3RLZXkuZGltcy5sZW5ndGggPT09IDQgJiZcbiAgICBwYXN0S2V5LmRpbXNbMF0gPT09IGJhdGNoU2l6ZSAmJlxuICAgIHBhc3RLZXkuZGltc1sxXSAhPT0gYXR0cmlidXRlcy5rdk51bUhlYWRzICYmXG4gICAgcGFzdEtleS5kaW1zWzJdID09PSBhdHRyaWJ1dGVzLmt2TnVtSGVhZHMgJiZcbiAgICBwYXN0S2V5LmRpbXNbM10gPT09IGhlYWRTaXplO1xuXG4gIGlmIChpc1Bhc3RrdkJTTkgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0JTTkggcGFzdEtleS9wYXN0VmFsdWUgaXMgbm90IHN1cHBvcnRlZCcpO1xuICB9XG4gIGlmIChoYXNQYXN0S2V5ICYmIGhhc1Bhc3RWYWx1ZSkge1xuICAgIGlmIChwYXN0S2V5LmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicGFzdF9rZXlcIiBpcyBleHBlY3RlZCB0byBoYXZlIDQgZGltZW5zaW9ucycpO1xuICAgIH1cbiAgICBpZiAocGFzdFZhbHVlLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicGFzdF92YWx1ZVwiIGlzIGV4cGVjdGVkIHRvIGhhdmUgNCBkaW1lbnNpb25zJyk7XG4gICAgfVxuICAgIHBhc3RTZXF1ZW5jZUxlbmd0aCA9IHBhc3RLZXkuZGltc1syXTtcbiAgfSBlbHNlIGlmIChoYXNQYXN0S2V5IHx8IGhhc1Bhc3RWYWx1ZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0X2tleVwiIGFuZCBcInBhc3RfdmFsdWVcIiBzaGFsbCBiZSBib3RoIHByZXNlbnQgb3IgYm90aCBhYnNlbnQnKTtcbiAgfVxuXG4gIGxldCBxa3ZGb3JtYXQ6IEF0dGVudGlvblFrdkZvcm1hdCA9IEF0dGVudGlvblFrdkZvcm1hdC5xa3ZCTlNIO1xuICBpZiAoa2V5ICYmIGtleS5kaW1zLmxlbmd0aCA+IDApIHtcbiAgICBpZiAocXVlcnkuZGltcy5sZW5ndGggIT09IDMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJxdWVyeVwiIGlzIGV4cGVjdGVkIHRvIGhhdmUgMyBkaW1lbnNpb25zIHdoZW4ga2V5IGlzIGdpdmVuJyk7XG4gICAgfVxuICAgIGlmIChrZXkuZGltcy5sZW5ndGggPCAzIHx8IGtleS5kaW1zLmxlbmd0aCA+IDUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJrZXlcIiBpcyBleHBlY3RlZCB0byBoYXZlIDMsIDQsIG9yIDUgZGltZW5zaW9ucycpO1xuICAgIH1cbiAgICBpZiAocXVlcnkuZGltc1swXSAhPT0ga2V5LmRpbXNbMF0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJxdWVyeVwiIGFuZCBcImtleVwiIHNoYWxsIGhhdmUgc2FtZSBkaW0gMCAoYmF0Y2ggc2l6ZSknKTtcbiAgICB9XG5cbiAgICBpZiAoa2V5LmRpbXMubGVuZ3RoID09PSAzKSB7XG4gICAgICBpZiAocXVlcnkuZGltc1syXSAlIGtleS5kaW1zWzJdICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRGltZW5zaW9uIDIgb2YgXCJxdWVyeVwiIHNob3VsZCBiZSBhIG11bHRpcGxlIG9mIFwia2V5XCInKTtcbiAgICAgIH1cbiAgICAgIGt2U2VxdWVuY2VMZW5ndGggPSBrZXkuZGltc1sxXTtcbiAgICB9IGVsc2UgaWYgKGtleS5kaW1zLmxlbmd0aCA9PT0gNSkge1xuICAgICAgaWYgKGtleS5kaW1zWzJdICE9PSBhdHRyaWJ1dGVzLm51bUhlYWRzIHx8IGtleS5kaW1zWzNdICE9PSAyIHx8IGtleS5kaW1zWzRdICE9PSBoZWFkU2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdCBcImtleVwiIHNoYXBlIChiYXRjaF9zaXplLCBrdl9zZXF1ZW5jZV9sZW5ndGgsIG51bV9oZWFkcywgMiwgaGVhZF9zaXplKSBmb3IgcGFja2VkIGt2Jyk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3QgXCJ2YWx1ZVwiIGJlIG5vbmUgd2hlbiBcImtleVwiIGhhcyBwYWNrZWQga3YgZm9ybWF0LicpO1xuICAgICAgfVxuICAgICAga3ZTZXF1ZW5jZUxlbmd0aCA9IGtleS5kaW1zWzFdO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBrZXlfZGltcy5zaXplKCkgPT0gNCAoY3Jvc3MtYXR0ZW50aW9uIHdpdGggcGFzdF9rZXkpXG4gICAgICBpZiAoa2V5LmRpbXNbMV0gIT09IGF0dHJpYnV0ZXMubnVtSGVhZHMgfHwga2V5LmRpbXNbM10gIT09IGhlYWRTaXplKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0IFwia2V5XCIgc2hhcGUgKGJhdGNoX3NpemUsIG51bV9oZWFkcywga3Zfc2VxdWVuY2VfbGVuZ3RoLCBoZWFkX3NpemUpIGZvciBwYXN0X2tleScpO1xuICAgICAgfVxuICAgICAga3ZTZXF1ZW5jZUxlbmd0aCA9IGtleS5kaW1zWzJdO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBwYWNrZWQgUUtWXG4gICAgaWYgKHF1ZXJ5LmRpbXMubGVuZ3RoICE9PSAzICYmIHF1ZXJ5LmRpbXMubGVuZ3RoICE9PSA1KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicXVlcnlcIiBpcyBleHBlY3RlZCB0byBoYXZlIDMgb3IgNSBkaW1lbnNpb25zIHdoZW4ga2V5IGlzIGVtcHR5Jyk7XG4gICAgfVxuICAgIGlmIChxdWVyeS5kaW1zLmxlbmd0aCA9PT0gNSAmJiAocXVlcnkuZGltc1syXSAhPT0gYXR0cmlidXRlcy5udW1IZWFkcyB8fCBxdWVyeS5kaW1zWzNdICE9PSAzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3QgXCJxdWVyeVwiIHNoYXBlIChiYXRjaF9zaXplLCBrdl9zZXF1ZW5jZV9sZW5ndGgsIG51bV9oZWFkcywgMywgaGVhZF9zaXplKSBmb3IgcGFja2VkIGt2Jyk7XG4gICAgfVxuXG4gICAgcWt2Rm9ybWF0ID0gQXR0ZW50aW9uUWt2Rm9ybWF0LnFrdkJTTjNIO1xuICB9XG5cbiAgY29uc3QgbWFza1R5cGU6IEF0dGVudGlvbk1hc2tUeXBlID0gQXR0ZW50aW9uTWFza1R5cGUubm9uZTtcbiAgbGV0IHBhc3NQYXN0SW5LdiA9IGZhbHNlO1xuICBsZXQgdkhpZGRlblNpemUgPSBhdHRyaWJ1dGVzLmt2TnVtSGVhZHMgPyBoZWFkU2l6ZSAqIGF0dHJpYnV0ZXMua3ZOdW1IZWFkcyA6IGhpZGRlblNpemU7XG4gIGlmICh2YWx1ZSAmJiB2YWx1ZS5kaW1zLmxlbmd0aCA+IDApIHtcbiAgICBpZiAodmFsdWUuZGltcy5sZW5ndGggIT09IDMgJiYgdmFsdWUuZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJ2YWx1ZVwiIGlzIGV4cGVjdGVkIHRvIGhhdmUgMyBvciA0IGRpbWVuc2lvbnMnKTtcbiAgICB9XG5cbiAgICBpZiAocXVlcnkuZGltc1swXSAhPT0gdmFsdWUuZGltc1swXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcInF1ZXJ5XCIgYW5kIFwidmFsdWVcIiBzaGFsbCBoYXZlIHNhbWUgZGltIDAgKGJhdGNoX3NpemUpJyk7XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLmRpbXMubGVuZ3RoID09PSAzKSB7XG4gICAgICBpZiAoa3ZTZXF1ZW5jZUxlbmd0aCAhPT0gdmFsdWUuZGltc1sxXSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwia2V5XCIgYW5kIFwidmFsdWVcIiBzaGFsbCBoYXZlIHRoZSBzYW1lIGRpbSAxIChrdl9zZXF1ZW5jZV9sZW5ndGgpJyk7XG4gICAgICB9XG4gICAgICB2SGlkZGVuU2l6ZSA9IHZhbHVlLmRpbXNbMl07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChrdlNlcXVlbmNlTGVuZ3RoICE9PSB2YWx1ZS5kaW1zWzJdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0X2tleVwiIGFuZCBcInBhc3RfdmFsdWVcIiBzaGFsbCBoYXZlIHRoZSBzYW1lIGRpbSAyIChrdl9zZXF1ZW5jZV9sZW5ndGgpJyk7XG4gICAgICB9XG4gICAgICB2SGlkZGVuU2l6ZSA9IHZhbHVlLmRpbXNbMV0gKiB2YWx1ZS5kaW1zWzNdO1xuICAgICAgcGFzc1Bhc3RJbkt2ID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgLy8gU3BlYyByZXF1aXJlcyAxRCBzaGFwZSAoYmF0Y2hfc2l6ZSksIGJ1dCBvbGRlciBtb2RlbCBidWlsZGVycyBtYXkgYWRkIHVuaXRcbiAgLy8gZGltZW5zaW9ucyAoZS5nLiBbQiwgMV0gaW5zdGVhZCBvZiBbQl0pLiBBbGxvdyBzaGFwZXMgd2hlcmUgZWFjaCBkaW0gaXMgMSBvciBiYXRjaFNpemUuXG4gIGNvbnN0IHNlcWxMZW5zID0gaW5wdXRzLmxlbmd0aCA+IDQgPyBpbnB1dHNbNV0gOiB1bmRlZmluZWQ7XG4gIGlmIChzZXFsTGVucykge1xuICAgIGlmIChzZXFsTGVucy5kaW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzZXFsZW5zX2sgbXVzdCBiZSBhdCBsZWFzdCAxRCwgZ290IHNjYWxhci4nKTtcbiAgICB9XG4gICAgY29uc3Qgc2VxbExlblNpemUgPSBzZXFsTGVucy5kaW1zLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIsIDEpO1xuICAgIGlmIChzZXFsTGVuU2l6ZSAhPT0gYmF0Y2hTaXplKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHNlcWxlbnNfayBtdXN0IGhhdmUgYmF0Y2hfc2l6ZSAoJHtiYXRjaFNpemV9KSBlbGVtZW50cywgZ290ICR7c2VxbExlblNpemV9LmApO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlcWxMZW5zLmRpbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChzZXFsTGVucy5kaW1zW2ldICE9PSAxICYmIHNlcWxMZW5zLmRpbXNbaV0gIT09IGJhdGNoU2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYHNlcWxlbnNfayBoYXMgdW5leHBlY3RlZCBzaGFwZS4gRWFjaCBkaW1lbnNpb24gbXVzdCBiZSAxIG9yIGJhdGNoX3NpemUgKCR7YmF0Y2hTaXplfSksIGdvdCBkaW1zWyR7aX1dID0gJHtzZXFsTGVucy5kaW1zW2ldfS5gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCB0b3RhbFNlcXVlbmNlTGVuZ3RoID0gLTE7XG4gIGNvbnN0IG1heFNlcXVlbmNlTGVuZ3RoID0gLTE7XG4gIGNvbnN0IGJyb2FkY2FzdFJlc1Bvc0JpYXMgPSBmYWxzZTtcblxuICByZXR1cm4ge1xuICAgIGJhdGNoU2l6ZSxcbiAgICBzZXF1ZW5jZUxlbmd0aCxcbiAgICBwYXN0U2VxdWVuY2VMZW5ndGgsXG4gICAga3ZTZXF1ZW5jZUxlbmd0aCxcbiAgICB0b3RhbFNlcXVlbmNlTGVuZ3RoLFxuICAgIG1heFNlcXVlbmNlTGVuZ3RoLFxuICAgIGlucHV0SGlkZGVuU2l6ZTogMCxcbiAgICBoaWRkZW5TaXplLFxuICAgIHZIaWRkZW5TaXplLFxuICAgIGhlYWRTaXplLFxuICAgIHZIZWFkU2l6ZTogTWF0aC5mbG9vcih2SGlkZGVuU2l6ZSAvIGF0dHJpYnV0ZXMua3ZOdW1IZWFkcyksXG4gICAgbnVtSGVhZHM6IGF0dHJpYnV0ZXMubnVtSGVhZHMsXG4gICAga3ZOdW1IZWFkczogYXR0cmlidXRlcy5rdk51bUhlYWRzLFxuICAgIG5SZXBzOiBhdHRyaWJ1dGVzLm51bUhlYWRzIC8gYXR0cmlidXRlcy5rdk51bUhlYWRzLFxuICAgIHBhc3RQcmVzZW50U2hhcmVCdWZmZXI6IGZhbHNlLFxuICAgIG1hc2tUeXBlLFxuICAgIHNjYWxlOiBhdHRyaWJ1dGVzLnNjYWxlLFxuICAgIGJyb2FkY2FzdFJlc1Bvc0JpYXMsXG4gICAgcGFzc1Bhc3RJbkt2LFxuICAgIHFrdkZvcm1hdCxcbiAgfTtcbn07XG5cbmNvbnN0IHdlaWdodFRyYW5zcG9zZUF0dHJpYnV0ZTogVHJhbnNwb3NlQXR0cmlidXRlcyA9IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IHBlcm06IFswLCAyLCAxLCAzXSB9KTtcblxuY29uc3QgbWF5YmVUcmFuc3Bvc2VUb0JOU0ggPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGlucHV0OiBUZW5zb3JWaWV3LCBwYXJhbXM6IEF0dGVudGlvblBhcmFtZXRlcnMpID0+IHtcbiAgbGV0IHJlc2hhcGVkSW5wdXQgPSBpbnB1dDtcbiAgY29uc3QgbnVtSGVhZHMgPSBwYXJhbXMua3ZOdW1IZWFkcyE7XG4gIGlmIChpbnB1dC5kaW1zLmxlbmd0aCA9PT0gMyAmJiBwYXJhbXMua3ZTZXF1ZW5jZUxlbmd0aCAhPT0gMCkge1xuICAgIHJlc2hhcGVkSW5wdXQgPSBpbnB1dC5yZXNoYXBlKFtwYXJhbXMuYmF0Y2hTaXplLCBwYXJhbXMua3ZTZXF1ZW5jZUxlbmd0aCwgbnVtSGVhZHMsIHBhcmFtcy5oZWFkU2l6ZV0pO1xuICAgIHJlc2hhcGVkSW5wdXQgPSBjb250ZXh0LmNvbXB1dGUoY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8ocmVzaGFwZWRJbnB1dCwgd2VpZ2h0VHJhbnNwb3NlQXR0cmlidXRlLnBlcm0pLCB7XG4gICAgICBpbnB1dHM6IFtyZXNoYXBlZElucHV0XSxcbiAgICAgIG91dHB1dHM6IFstMV0sXG4gICAgfSlbMF07XG4gIH1cblxuICByZXR1cm4gcmVzaGFwZWRJbnB1dDtcbn07XG5cbmNvbnN0IGdlbmVyYXRlUG9zaXRpb25JZHNQcm9ncmFtSW5mbyA9IChcbiAgYmF0Y2hTaXplOiBudW1iZXIsXG4gIHNlcXVlbmNlTGVuZ3RoOiBudW1iZXIsXG4gIHNlcUxlbnM6IFRlbnNvclZpZXcsXG4gIHRvdGFsU2VxTGVuOiBUZW5zb3JWaWV3LFxuKSA9PiB7XG4gIGNvbnN0IG91dHB1dERhdGFUeXBlID0gRGF0YVR5cGUuaW50NjQ7XG4gIGNvbnN0IGlucHV0RGVwZW5kZW5jaWVzOiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdID0gWyd0eXBlJywgJ3R5cGUnXTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBbYmF0Y2hTaXplICogc2VxdWVuY2VMZW5ndGhdO1xuICBjb25zdCBvdXRwdXRTaXplID0gYmF0Y2hTaXplICogc2VxdWVuY2VMZW5ndGg7XG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBzZXF1ZW5jZUxlbmd0aCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBiYXRjaFNpemUgfSxcbiAgXTtcbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3Qgc2VxTGVuc0lucHV0SGVscGVyID0gaW5wdXRWYXJpYWJsZSgnc2VxX2xlbnMnLCBzZXFMZW5zLmRhdGFUeXBlLCBzZXFMZW5zLmRpbXMpO1xuICAgIGNvbnN0IHRvdGFsU2VxTGVuSW5wdXRIZWxwZXIgPSBpbnB1dFZhcmlhYmxlKCd0b3RhbF9zZXFfbGVucycsIHRvdGFsU2VxTGVuLmRhdGFUeXBlLCB0b3RhbFNlcUxlbi5kaW1zKTtcbiAgICBjb25zdCBwb3NpdGlvbklkc0hlbHBlciA9IG91dHB1dFZhcmlhYmxlKCdwb3NfaWRzJywgb3V0cHV0RGF0YVR5cGUsIG91dHB1dFNoYXBlKTtcblxuICAgIGNvbnN0IHVuaWZvcm1zOiBVbmlmb3Jtc0FycmF5VHlwZSA9IFtcbiAgICAgIHsgbmFtZTogJ291dHB1dF9zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ3NlcXVlbmNlX2xlbmd0aCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdiYXRjaF9zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICBdO1xuXG4gICAgcmV0dXJuIGBcbiAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyhzZXFMZW5zSW5wdXRIZWxwZXIsIHRvdGFsU2VxTGVuSW5wdXRIZWxwZXIsIHBvc2l0aW9uSWRzSGVscGVyKX1cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX1cbiAgICBsZXQgdG90YWxfc2VxdWVuY2VfbGVuZ3RoID0gdTMyKCR7dG90YWxTZXFMZW5JbnB1dEhlbHBlci5nZXRCeU9mZnNldCgnMCcpfSk7XG4gICAgbGV0IGlzX3N1YnNlcXVlbnRfcHJvbXB0ID0gdW5pZm9ybXMuc2VxdWVuY2VfbGVuZ3RoID4gMSAmJiB1bmlmb3Jtcy5zZXF1ZW5jZV9sZW5ndGggIT0gdG90YWxfc2VxdWVuY2VfbGVuZ3RoO1xuICAgIGxldCBpc19maXJzdF9wcm9tcHQgPSAhaXNfc3Vic2VxdWVudF9wcm9tcHQgJiYgdW5pZm9ybXMuc2VxdWVuY2VfbGVuZ3RoID09IHRvdGFsX3NlcXVlbmNlX2xlbmd0aDtcbiAgICBsZXQgYmF0Y2hfaWR4ID0gZ2xvYmFsX2lkeCAvIHVuaWZvcm1zLnNlcXVlbmNlX2xlbmd0aDtcbiAgICBsZXQgc2VxdWVuY2VfaWR4ID0gaTMyKGdsb2JhbF9pZHggJSB1bmlmb3Jtcy5zZXF1ZW5jZV9sZW5ndGgpO1xuICAgIHZhciBwb3NfaWQ6IGkzMiA9IDA7XG4gICAgbGV0IHNlcWxlbiA9ICR7c2VxTGVuc0lucHV0SGVscGVyLmdldEJ5T2Zmc2V0KCdiYXRjaF9pZHgnKX07XG4gICAgbGV0IHRvdGFsX3NlcWxlbiA9IHNlcWxlbiArIDE7XG4gICAgaWYgKGlzX2ZpcnN0X3Byb21wdCkge1xuICAgICAgaWYgKHNlcXVlbmNlX2lkeCA8IHRvdGFsX3NlcWxlbikge1xuICAgICAgICBwb3NfaWQgPSBzZXF1ZW5jZV9pZHg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwb3NfaWQgPSAxO1xuICAgICAgfVxuICAgICAgJHtwb3NpdGlvbklkc0hlbHBlci5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICdwb3NfaWQnKX1cbiAgICB9IGVsc2UgaWYgKGlzX3N1YnNlcXVlbnRfcHJvbXB0KSB7XG4gICAgICBsZXQgcGFzdF9zZXFsZW4gPSB0b3RhbF9zZXFsZW4gLSBpMzIodW5pZm9ybXMuc2VxdWVuY2VfbGVuZ3RoKTtcbiAgICAgIGlmIChwYXN0X3NlcWxlbiArIHNlcXVlbmNlX2lkeCA8IHRvdGFsX3NlcWxlbikge1xuICAgICAgICBwb3NfaWQgPSBwYXN0X3NlcWxlbiArIHNlcXVlbmNlX2lkeDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBvc19pZCA9IDE7XG4gICAgICB9XG4gICAgICAke3Bvc2l0aW9uSWRzSGVscGVyLnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ3Bvc19pZCcpfVxuICAgIH0gZWxzZSBpZiAoZ2xvYmFsX2lkeCA8IHVuaWZvcm1zLmJhdGNoX3NpemUpIHtcbiAgICAgICR7cG9zaXRpb25JZHNIZWxwZXIuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAnc2VxbGVuJyl9XG4gICAgfTtcbiAgfVxuICBgO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdHZW5lcmF0ZVBvc2l0aW9uSWRzJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtiYXRjaFNpemV9OyR7c2VxdWVuY2VMZW5ndGh9YCwgaW5wdXREZXBlbmRlbmNpZXMgfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBvdXRwdXREYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgZ3JvdXBRdWVyeUF0dGVudGlvbiA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogR3JvdXBRdWVyeUF0dGVudGlvbkF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgY29uc3QgcGFyYW1zID0gdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBpZiAoY29udGV4dC5pbnB1dHNbMF0uZGltcy5sZW5ndGggPT09IDUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhY2tlZCBRS1YgaXMgbm90IGltcGxlbWVudGVkJyk7XG4gIH1cblxuICBpZiAoY29udGV4dC5pbnB1dHNbMV0/LmRpbXMubGVuZ3RoID09PSA1KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQYWNrZWQgS1YgaXMgbm90IGltcGxlbWVudGVkJyk7XG4gIH1cblxuICBjb25zdCBxID0gY29udGV4dC5pbnB1dHNbMF07XG4gIGNvbnN0IGsgPSBjb250ZXh0LmlucHV0c1sxXSAmJiBjb250ZXh0LmlucHV0c1sxXS5kaW1zLmxlbmd0aCA+IDAgPyBjb250ZXh0LmlucHV0c1sxXSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgdiA9IGNvbnRleHQuaW5wdXRzWzJdICYmIGNvbnRleHQuaW5wdXRzWzJdLmRpbXMubGVuZ3RoID4gMCA/IGNvbnRleHQuaW5wdXRzWzJdIDogdW5kZWZpbmVkO1xuICBjb25zdCBwYXN0S2V5ID0gY29udGV4dC5pbnB1dHNbM10gJiYgY29udGV4dC5pbnB1dHNbM10uZGltcy5sZW5ndGggIT09IDAgPyBjb250ZXh0LmlucHV0c1szXSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgcGFzdFZhbHVlID0gY29udGV4dC5pbnB1dHNbNF0gJiYgY29udGV4dC5pbnB1dHNbNF0uZGltcy5sZW5ndGggIT09IDAgPyBjb250ZXh0LmlucHV0c1s0XSA6IHVuZGVmaW5lZDtcbiAgY29uc3Qgc2VxTGVucyA9IGNvbnRleHQuaW5wdXRzLmxlbmd0aCA+IDQgPyBjb250ZXh0LmlucHV0c1s1XSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0ID0gY29udGV4dC5pbnB1dHMubGVuZ3RoID4gNSA/IGNvbnRleHQuaW5wdXRzWzZdIDogdW5kZWZpbmVkO1xuICBjb25zdCBrdk51bUhlYWRzID0gcGFyYW1zLmt2TnVtSGVhZHMgPyBwYXJhbXMua3ZOdW1IZWFkcyA6IHBhcmFtcy5udW1IZWFkcztcblxuICAvLyBUT0RPIFJlbW92ZSBleHBsaWNpdCBzcGxpdCBvcGVyYXRpb24gYW5kIHVzZSBpbmRleGluZyBpbiBBdHRlbnRpb24gaW1wbGVtZW50YXRpb24gdG8gYXZvaWQgb3ZlcmhlYWQuXG5cbiAgY29uc3Qgc3BsaXRBdHRyaWJ1dGVzOiBTcGxpdEF0dHJpYnV0ZXMgPSBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe1xuICAgIGF4aXM6IDIsXG4gICAgbnVtT3V0cHV0czogMyxcbiAgICBzcGxpdFNpemVzOiBbcGFyYW1zLm51bUhlYWRzICogcGFyYW1zLmhlYWRTaXplLCBrdk51bUhlYWRzICogcGFyYW1zLmhlYWRTaXplLCBrdk51bUhlYWRzICogcGFyYW1zLmhlYWRTaXplXSxcbiAgfSk7XG4gIGNvbnN0IFtxdWVyeSwga2V5LCB2YWx1ZV0gPVxuICAgICFrICYmICF2XG4gICAgICA/IGNvbnRleHQuY29tcHV0ZShjcmVhdGVTcGxpdFByb2dyYW1JbmZvKFtxXSwgc3BsaXRBdHRyaWJ1dGVzKSwgeyBpbnB1dHM6IFtxXSwgb3V0cHV0czogWy0xLCAtMSwgLTFdIH0pXG4gICAgICA6IFtxLCBrISwgdiFdO1xuICBsZXQgcVJvdGFyeTogVGVuc29yVmlldyB8IHVuZGVmaW5lZDtcbiAgbGV0IGtSb3Rhcnk6IFRlbnNvclZpZXcgfCB1bmRlZmluZWQ7XG4gIGlmIChhdHRyaWJ1dGVzLmRvUm90YXJ5KSB7XG4gICAgY29uc3QgcG9zSWRzID0gY29udGV4dC5jb21wdXRlKFxuICAgICAgZ2VuZXJhdGVQb3NpdGlvbklkc1Byb2dyYW1JbmZvKHBhcmFtcy5iYXRjaFNpemUsIHBhcmFtcy5zZXF1ZW5jZUxlbmd0aCwgc2VxTGVucyEsIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCEpLFxuICAgICAgeyBpbnB1dHM6IFtzZXFMZW5zISwgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0IV0sIG91dHB1dHM6IFstMV0gfSxcbiAgICApWzBdO1xuICAgIGNvbnN0IGNvc0NhY2hlID0gY29udGV4dC5pbnB1dHNbN107XG4gICAgY29uc3Qgc2luQ2FjaGUgPSBjb250ZXh0LmlucHV0c1s4XTtcbiAgICBjb25zdCBxUm90YXJ5RW1iZWRkaW5nQXR0cmlidXRlczogUm90YXJ5RW1iZWRkaW5nQXR0cmlidXRlcyA9IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgICBpbnRlcmxlYXZlZDogYXR0cmlidXRlcy5yb3RhcnlJbnRlcmxlYXZlZCAhPT0gMCxcbiAgICAgIG51bUhlYWRzOiBwYXJhbXMubnVtSGVhZHMsXG4gICAgICByb3RhcnlFbWJlZGRpbmdEaW06IDAsXG4gICAgICBzY2FsZTogYXR0cmlidXRlcy5zY2FsZSxcbiAgICB9KTtcbiAgICBjb25zdCBpbnB1dHMgPSBbcXVlcnksIHBvc0lkcywgY29zQ2FjaGUsIHNpbkNhY2hlXTtcbiAgICBjb25zdCBvdXRwdXRzID0gWy0xXTtcbiAgICBxUm90YXJ5ID0gY29udGV4dC5jb21wdXRlKGNyZWF0ZVJvdGFyeUVtYmVkZGluZ1Byb2dyYW1JbmZvKGlucHV0cywgcVJvdGFyeUVtYmVkZGluZ0F0dHJpYnV0ZXMpLCB7XG4gICAgICBpbnB1dHMsXG4gICAgICBvdXRwdXRzLFxuICAgIH0pWzBdO1xuICAgIGlucHV0cy5zcGxpY2UoMCwgMSwga2V5KTtcbiAgICBjb25zdCBrUm90YXJ5RW1iZWRkaW5nQXR0cmlidXRlczogUm90YXJ5RW1iZWRkaW5nQXR0cmlidXRlcyA9IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgICBpbnRlcmxlYXZlZDogYXR0cmlidXRlcy5yb3RhcnlJbnRlcmxlYXZlZCAhPT0gMCxcbiAgICAgIG51bUhlYWRzOiBwYXJhbXMua3ZOdW1IZWFkcyEsXG4gICAgICByb3RhcnlFbWJlZGRpbmdEaW06IDAsXG4gICAgICBzY2FsZTogYXR0cmlidXRlcy5zY2FsZSxcbiAgICB9KTtcbiAgICBrUm90YXJ5ID0gY29udGV4dC5jb21wdXRlKGNyZWF0ZVJvdGFyeUVtYmVkZGluZ1Byb2dyYW1JbmZvKGlucHV0cywga1JvdGFyeUVtYmVkZGluZ0F0dHJpYnV0ZXMpLCB7XG4gICAgICBpbnB1dHMsXG4gICAgICBvdXRwdXRzLFxuICAgIH0pWzBdO1xuICB9XG4gIGNvbnN0IFEgPSBtYXliZVRyYW5zcG9zZVRvQk5TSEFuZEFkZEJpYXMoXG4gICAgY29udGV4dCxcbiAgICBwYXJhbXMuYmF0Y2hTaXplLFxuICAgIHBhcmFtcy5udW1IZWFkcyxcbiAgICBwYXJhbXMuc2VxdWVuY2VMZW5ndGgsXG4gICAgcGFyYW1zLmhlYWRTaXplLFxuICAgIGF0dHJpYnV0ZXMuZG9Sb3RhcnkgPyBxUm90YXJ5ISA6IHF1ZXJ5LFxuICAgIHVuZGVmaW5lZCxcbiAgICAwLFxuICApO1xuICBjb25zdCBLID0gbWF5YmVUcmFuc3Bvc2VUb0JOU0goY29udGV4dCwgYXR0cmlidXRlcy5kb1JvdGFyeSA/IGtSb3RhcnkhIDoga2V5LCBwYXJhbXMpO1xuICBjb25zdCBWID0gbWF5YmVUcmFuc3Bvc2VUb0JOU0goY29udGV4dCwgdmFsdWUsIHBhcmFtcyk7XG5cbiAgYXBwbHlBdHRlbnRpb24oXG4gICAgY29udGV4dCxcbiAgICBRLFxuICAgIEssXG4gICAgVixcbiAgICB1bmRlZmluZWQsXG4gICAgdW5kZWZpbmVkLFxuICAgIHBhc3RLZXksXG4gICAgcGFzdFZhbHVlLFxuICAgIHVuZGVmaW5lZCxcbiAgICBwYXJhbXMsXG4gICAgc2VxTGVucyxcbiAgICB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQsXG4gICk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeSwgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyB9IGZyb20gJy4vdHJhbnNwb3NlJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIGdldE1heENvbXBvbmVudHMsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIHN1bVZlY3RvcixcbiAgdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5zdGFuY2VOb3JtQXR0cmlidXRlcyB7XG4gIGVwc2lsb246IG51bWJlcjtcbiAgZm9ybWF0OiAnTkhXQycgfCAnTkNIVyc7XG59XG5cbmNvbnN0IGNvbXB1dGVDaGFubmVsU2NhbGVTaGlmdCA9IChcbiAgY29udGV4dDogQ29tcHV0ZUNvbnRleHQsXG4gIGlucHV0OiBUZW5zb3JWaWV3LFxuICBzY2FsZTogVGVuc29yVmlldyxcbiAgYmlhczogVGVuc29yVmlldyxcbiAgbjogbnVtYmVyLFxuICBoOiBudW1iZXIsXG4gIGM6IG51bWJlcixcbiAgZXBzaWxvbjogbnVtYmVyLFxuKSA9PiB7XG4gIGNvbnN0IGNvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKGgpO1xuICBjb25zdCBmMzJUeXBlID0gY29tcG9uZW50cyA9PT0gMSA/ICdmMzInIDogYHZlYyR7Y29tcG9uZW50c31mYDtcbiAgY29uc3Qgd2dUeXBlID0gY29tcG9uZW50cyA9PT0gMSA/ICd2ZWMyZicgOiBgbWF0Mngke2NvbXBvbmVudHN9ZmA7XG4gIGNvbnN0IHVuaXRzT2ZXb3JrID0gbiAqIGM7XG4gIGxldCB3b3JrZ3JvdXBTaXplID0gNjQ7XG4gIGlmICh1bml0c09mV29yayA9PT0gMSkge1xuICAgIHdvcmtncm91cFNpemUgPSAyNTY7XG4gIH1cbiAgY29uc3QgaW5wdXRTaGFwZSA9IFtuLCBjLCBoIC8gY29tcG9uZW50c107XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW24sIGMsIDJdO1xuICBjb25zdCBpbnB1dERlcGVuZGVuY2llczogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXSA9IFsncmFuaycsICd0eXBlJywgJ3R5cGUnXTtcbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW107XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0U2hhcGUsIG91dHB1dFNoYXBlKSk7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgeCA9IGlucHV0VmFyaWFibGUoJ3gnLCBpbnB1dC5kYXRhVHlwZSwgMywgY29tcG9uZW50cyk7XG4gICAgY29uc3QgcyA9IGlucHV0VmFyaWFibGUoJ3NjYWxlJywgc2NhbGUuZGF0YVR5cGUsIHNjYWxlLmRpbXMpO1xuICAgIGNvbnN0IGIgPSBpbnB1dFZhcmlhYmxlKCdiaWFzJywgYmlhcy5kYXRhVHlwZSwgYmlhcy5kaW1zKTtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgRGF0YVR5cGUuZmxvYXQsIDMsIDIpO1xuICAgIGNvbnN0IHZhcmlhYmxlcyA9IFt4LCBzLCBiLCBvdXRwdXRdO1xuICAgIHJldHVybiBgXG4gIHZhcjx3b3JrZ3JvdXA+IHdvcmtncm91cF9zaGFyZWQgOiBhcnJheTwke3dnVHlwZX0sICR7d29ya2dyb3VwU2l6ZX0+O1xuICBjb25zdCB3b3JrZ3JvdXBfc2l6ZSA9ICR7d29ya2dyb3VwU2l6ZX11O1xuICAke3NoYWRlckhlbHBlci5kZWNsYXJlVmFyaWFibGVzKC4uLnZhcmlhYmxlcyl9XG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydCh3b3JrZ3JvdXBTaXplKX1cbiAgICBsZXQgYmF0Y2ggPSB3b3JrZ3JvdXBfaW5kZXggLyB1bmlmb3Jtcy54X3NoYXBlWzFdO1xuICAgIGxldCBjaGFubmVsID0gd29ya2dyb3VwX2luZGV4ICUgdW5pZm9ybXMueF9zaGFwZVsxXTtcbiAgICBsZXQgaGlnaHQgPSB1bmlmb3Jtcy54X3NoYXBlWzJdO1xuICAgIC8vIGluaXRpYWxpemUgd29ya2dyb3VwIG1lbW9yeVxuICAgIHZhciBzdW0gPSAke2YzMlR5cGV9KDApO1xuICAgIHZhciBzcXVhcmVkX3N1bSA9ICR7ZjMyVHlwZX0oMCk7XG4gICAgZm9yICh2YXIgaCA9IGxvY2FsX2lkeDsgaCA8IGhpZ2h0OyBoICs9IHdvcmtncm91cF9zaXplKSB7XG4gICAgICBsZXQgdmFsdWUgPSAke2YzMlR5cGV9KCR7eC5nZXQoJ2JhdGNoJywgJ2NoYW5uZWwnLCAnaCcpfSk7XG4gICAgICBzdW0gKz0gdmFsdWU7XG4gICAgICBzcXVhcmVkX3N1bSArPSB2YWx1ZSAqIHZhbHVlO1xuICAgIH1cbiAgICB3b3JrZ3JvdXBfc2hhcmVkW2xvY2FsX2lkeF0gPSAke3dnVHlwZX0oc3VtLCBzcXVhcmVkX3N1bSk7XG4gICAgd29ya2dyb3VwQmFycmllcigpO1xuXG4gICAgZm9yICh2YXIgY3VyclNpemUgPSB3b3JrZ3JvdXBfc2l6ZSA+PiAxOyAgY3VyclNpemUgPiAwOyBjdXJyU2l6ZSA9IGN1cnJTaXplID4+IDEpIHtcbiAgICAgIGlmIChsb2NhbF9pZHggPCBjdXJyU2l6ZSkge1xuICAgICAgICB3b3JrZ3JvdXBfc2hhcmVkW2xvY2FsX2lkeF0gPSB3b3JrZ3JvdXBfc2hhcmVkW2xvY2FsX2lkeF0gKyB3b3JrZ3JvdXBfc2hhcmVkW2xvY2FsX2lkeCArIGN1cnJTaXplXTtcbiAgICAgIH1cbiAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcbiAgICB9XG4gICAgaWYgKGxvY2FsX2lkeCA9PSAwKSB7XG4gICAgICBsZXQgc3VtX2ZpbmFsID0gJHtzdW1WZWN0b3IoJ3dvcmtncm91cF9zaGFyZWRbMF1bMF0nLCBjb21wb25lbnRzKX0gLyBmMzIoaGlnaHQgKiAke2NvbXBvbmVudHN9KTtcbiAgICAgIGxldCBzcXVhcmVkX3N1bV9maW5hbCA9ICR7c3VtVmVjdG9yKCd3b3JrZ3JvdXBfc2hhcmVkWzBdWzFdJywgY29tcG9uZW50cyl9IC8gZjMyKGhpZ2h0ICogJHtjb21wb25lbnRzfSk7XG5cbiAgICAgIGxldCBpbnZfc3RkX2RldiA9IGludmVyc2VTcXJ0KHNxdWFyZWRfc3VtX2ZpbmFsIC0gc3VtX2ZpbmFsICogc3VtX2ZpbmFsICsgZjMyKCR7ZXBzaWxvbn0pKTtcbiAgICAgIGxldCBjaGFubmVsX3NjYWxlID0gaW52X3N0ZF9kZXYgKiBmMzIoc2NhbGVbY2hhbm5lbF0pO1xuICAgICAgbGV0IGNoYW5uZWxfc2hpZnQgPSBmMzIoYmlhc1tjaGFubmVsXSkgLSBzdW1fZmluYWwgKiBjaGFubmVsX3NjYWxlO1xuICAgICAgb3V0cHV0W3dvcmtncm91cF9pbmRleF0gPSB2ZWMyZihjaGFubmVsX3NjYWxlLCBjaGFubmVsX3NoaWZ0KTtcbiAgICB9XG4gIH1gO1xuICB9O1xuXG4gIHJldHVybiBjb250ZXh0LmNvbXB1dGUoXG4gICAge1xuICAgICAgbmFtZTogJ0luc3RhbmNlTm9ybUNvbXB1dGVDaGFubmVsU2NhbGVTaGlmdCcsXG4gICAgICAvLyBUT0RPOiB1c2UgZXBzaWxvbiBhcyB1bmlmb3JtLiBDdXJyZW50bHkgZXBzaWxvbiBhcyB1bmlmb3JtIGZhaWxzIHRlc3RfaW5zdGFuY2Vub3JtX2Vwc2lsb24uXG4gICAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtjb21wb25lbnRzfTske2Vwc2lsb259OyR7d29ya2dyb3VwU2l6ZX1gLCBpbnB1dERlcGVuZGVuY2llcyB9LFxuICAgICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBEYXRhVHlwZS5mbG9hdCB9XSxcbiAgICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiB1bml0c09mV29yayB9LFxuICAgICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgICB9KSxcbiAgICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICB9LFxuICAgIHsgaW5wdXRzOiBbaW5wdXQsIHNjYWxlLCBiaWFzXSwgb3V0cHV0czogWy0xXSB9LFxuICApWzBdO1xufTtcblxuY29uc3QgY3JlYXRlSW5zdGFuY2VOb3JtUHJvZ3JhbUluZm8gPSAoXG4gIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogSW5zdGFuY2VOb3JtQXR0cmlidXRlcyxcbikgPT4ge1xuICBjb25zdCB4U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSB4U2hhcGU7XG4gIGNvbnN0IGF4aXMgPSAyO1xuICBjb25zdCBOID0geFNoYXBlWzBdO1xuICBjb25zdCBDID0geFNoYXBlWzFdO1xuICBjb25zdCBIID0gU2hhcGVVdGlsLnNpemVGcm9tRGltZW5zaW9uKHhTaGFwZSwgYXhpcyk7XG4gIGNvbnN0IGNvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKEgpO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpIC8gY29tcG9uZW50cztcbiAgLy8gY29tcHV0ZSBjaGFubmVsIHNjYWxlIGFuZCBjaGFubmVsIHNoaWZ0LlxuICBjb25zdCBjaGFubmVsU2NhbGVTaGlmdCA9IGNvbXB1dGVDaGFubmVsU2NhbGVTaGlmdChcbiAgICBjb250ZXh0LFxuICAgIGlucHV0c1swXSxcbiAgICBpbnB1dHNbMV0sXG4gICAgaW5wdXRzWzJdLFxuICAgIE4sXG4gICAgSCxcbiAgICBDLFxuICAgIGF0dHJpYnV0ZXMuZXBzaWxvbixcbiAgKTtcblxuICBjb25zdCBpbnB1dFNoYXBlID0gW04sIEMsIEggLyBjb21wb25lbnRzXTtcbiAgY29uc3Qgc2NhbGVTaGFwZSA9IFtOLCBDXTtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3R5cGUnLCAnbm9uZSddO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IHggPSBpbnB1dFZhcmlhYmxlKCd4JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dFNoYXBlLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gICAgY29uc3Qgc2NhbGUgPSBpbnB1dFZhcmlhYmxlKCdzY2FsZV9zaGlmdCcsIERhdGFUeXBlLmZsb2F0LCBzY2FsZVNoYXBlLmxlbmd0aCwgMik7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRTaGFwZS5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IHZhcmlhYmxlcyA9IFt4LCBzY2FsZSwgb3V0cHV0XTtcbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ291dHB1dF9zaXplJywgJ3UzMicpLmRlY2xhcmVWYXJpYWJsZXMoLi4udmFyaWFibGVzKX1cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgICBsZXQgb3V0cHV0SW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcbiAgICAgIGxldCBiYXRjaCA9IG91dHB1dEluZGljZXNbMF07XG4gICAgICBsZXQgY2hhbm5lbCA9IG91dHB1dEluZGljZXNbMV07XG4gICAgICBsZXQgc2NhbGVfc2hpZnQgPSAke3NjYWxlLmdldEJ5SW5kaWNlcygndmVjMjx1MzI+KGJhdGNoLCBjaGFubmVsKScpfTtcbiAgICAgIGxldCB2YWx1ZSA9ICR7eC5nZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcpfSAqICR7b3V0cHV0LnR5cGUudmFsdWV9KHNjYWxlX3NoaWZ0LngpICsgJHtvdXRwdXQudHlwZS52YWx1ZX0oc2NhbGVfc2hpZnQueSk7XG4gICAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICd2YWx1ZScpfTtcbiAgfWA7XG4gIH07XG5cbiAgY29udGV4dC5jb21wdXRlKFxuICAgIHtcbiAgICAgIG5hbWU6ICdJbnN0YW5jZU5vcm1hbGl6YXRpb24nLFxuICAgICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYCR7Y29tcG9uZW50c31gLCBpbnB1dERlcGVuZGVuY2llcyB9LFxuICAgICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUgfV0sXG4gICAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgICAgcHJvZ3JhbVVuaWZvcm1zOiBbXG4gICAgICAgICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICAgICAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dFNoYXBlLCBzY2FsZVNoYXBlLCBpbnB1dFNoYXBlKSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIH0sXG4gICAgeyBpbnB1dHM6IFtpbnB1dHNbMF0sIGNoYW5uZWxTY2FsZVNoaWZ0XSB9LFxuICApO1xufTtcblxuY29uc3QgY3JlYXRlSW5zdGFuY2VOb3JtTkhXQ1Byb2dyYW1JbmZvID0gKFxuICBjb250ZXh0OiBDb21wdXRlQ29udGV4dCxcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IEluc3RhbmNlTm9ybUF0dHJpYnV0ZXMsXG4pID0+IHtcbiAgY29uc3QgeFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0geFNoYXBlO1xuICBjb25zdCBOID0geFNoYXBlWzBdO1xuICBjb25zdCBDID0geFNoYXBlW3hTaGFwZS5sZW5ndGggLSAxXTtcbiAgY29uc3QgSCA9IFNoYXBlVXRpbC5zaXplRnJvbURpbWVuc2lvbih4U2hhcGUsIDEpIC8gQztcbiAgY29uc3QgY29tcG9uZW50cyA9IGdldE1heENvbXBvbmVudHMoQyk7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSkgLyBjb21wb25lbnRzO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IEggfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogTWF0aC5mbG9vcihDIC8gY29tcG9uZW50cykgfSxcbiAgXTtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3R5cGUnLCAndHlwZSddO1xuXG4gIC8vIDEuIHRyYW5zcG9zZSB4IGZyb20gTkhXQyB0byBOQ0hXXG4gIGxldCBuZWVkVHJhbnNwb3NlID0gZmFsc2U7XG4gIGNvbnN0IHRyYW5zcG9zZWRYUGVybSA9IFswLCB4U2hhcGUubGVuZ3RoIC0gMV07XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgeFNoYXBlLmxlbmd0aCAtIDI7IGkrKykge1xuICAgIG5lZWRUcmFuc3Bvc2UgPSBuZWVkVHJhbnNwb3NlIHx8IHhTaGFwZVtpICsgMV0gIT09IDE7XG4gICAgdHJhbnNwb3NlZFhQZXJtLnB1c2goaSArIDEpO1xuICB9XG5cbiAgbmVlZFRyYW5zcG9zZSA9IG5lZWRUcmFuc3Bvc2UgJiYgeFNoYXBlW3hTaGFwZS5sZW5ndGggLSAxXSAhPT0gMTtcblxuICBjb25zdCB0cmFuc3Bvc2VkWCA9IG5lZWRUcmFuc3Bvc2VcbiAgICA/IGNvbnRleHQuY29tcHV0ZShjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgdHJhbnNwb3NlZFhQZXJtKSwge1xuICAgICAgICBpbnB1dHM6IFtjb250ZXh0LmlucHV0c1swXV0sXG4gICAgICAgIG91dHB1dHM6IFstMV0sXG4gICAgICB9KVswXVxuICAgIDogY29udGV4dC5pbnB1dHNbMF0ucmVzaGFwZShBcnJheS5mcm9tKHsgbGVuZ3RoOiB4U2hhcGUubGVuZ3RoIH0sIChfLCBpKSA9PiB4U2hhcGVbdHJhbnNwb3NlZFhQZXJtW2ldXSkpO1xuICAvLyAyLiBjb21wdXRlIGNoYW5uZWwgc2NhbGUgYW5kIGNoYW5uZWwgc2hpZnQuXG4gIGNvbnN0IGNoYW5uZWxTY2FsZVNoaWZ0ID0gY29tcHV0ZUNoYW5uZWxTY2FsZVNoaWZ0KFxuICAgIGNvbnRleHQsXG4gICAgdHJhbnNwb3NlZFgsXG4gICAgaW5wdXRzWzFdLFxuICAgIGlucHV0c1syXSxcbiAgICBOLFxuICAgIEgsXG4gICAgQyxcbiAgICBhdHRyaWJ1dGVzLmVwc2lsb24sXG4gICk7XG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlKGlucHV0c1swXS5kYXRhVHlwZSk7XG4gICAgY29uc3Qgc2NhbGVUeXBlID0gY29tcG9uZW50cyA9PT0gMSA/ICd2ZWMyZicgOiBgbWF0JHtjb21wb25lbnRzfXgyZmA7XG4gICAgY29uc3Qgc2NhbGVEYXRhID0gKG51bTogbnVtYmVyKSA9PiB7XG4gICAgICBjb25zdCBpbmRleCA9IG51bSA9PT0gMCA/ICd4JyA6ICd5JztcbiAgICAgIGNvbnN0IGYzMlR5cGUgPSBjb21wb25lbnRzID09PSAxID8gJ2YzMicgOiBgdmVjJHtjb21wb25lbnRzfWZgO1xuICAgICAgc3dpdGNoIChjb21wb25lbnRzKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICByZXR1cm4gYCR7ZGF0YVR5cGV9KCR7ZjMyVHlwZX0oc2NhbGUuJHtpbmRleH0pKWA7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICByZXR1cm4gYHZlYzI8JHtkYXRhVHlwZX0+KCR7ZjMyVHlwZX0oc2NhbGVbMF0uJHtpbmRleH0sIHNjYWxlWzFdLiR7aW5kZXh9KSlgO1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgcmV0dXJuIGB2ZWM0PCR7ZGF0YVR5cGV9Pigke2YzMlR5cGV9KHNjYWxlWzBdLiR7aW5kZXh9LCBzY2FsZVsxXS4ke2luZGV4fSwgc2NhbGVbMl0uJHtpbmRleH0sIHNjYWxlWzNdLiR7aW5kZXh9KSlgO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTm90IHN1cHBvcnRlZCBjb21wb2VudHMgJHtjb21wb25lbnRzfWApO1xuICAgICAgfVxuICAgIH07XG4gICAgY29uc3QgaW5wdXRIZWxwZXIgPSBpbnB1dFZhcmlhYmxlKCdpbnB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRzWzBdLmRpbXMsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IG91dHB1dEhlbHBlciA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlLCBjb21wb25lbnRzKTtcblxuICAgIHJldHVybiBgXG4gIEBncm91cCgwKSBAYmluZGluZygwKSB2YXI8c3RvcmFnZSwgcmVhZD4gaW5wdXQgOiBhcnJheTwke2lucHV0SGVscGVyLnR5cGUuc3RvcmFnZX0+O1xuICBAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyPHN0b3JhZ2UsIHJlYWQ+IHNjYWxlX2lucHV0IDogYXJyYXk8JHtzY2FsZVR5cGV9PjtcbiAgQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhcjxzdG9yYWdlLCByZWFkX3dyaXRlPiBvdXRwdXQgOiBhcnJheTwke291dHB1dEhlbHBlci50eXBlLnN0b3JhZ2V9PjtcbiAgc3RydWN0IFVuaWZvcm1zIHtIOiB1MzIsIEMgOiB1MzJ9O1xuICBAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyPHVuaWZvcm0+IHVuaWZvcm1zOiBVbmlmb3JtcztcblxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICBsZXQgY3VycmVudF9pbWFnZV9udW1iZXIgPSBnbG9iYWxfaWR4IC8gKHVuaWZvcm1zLkMgKiB1bmlmb3Jtcy5IKTtcbiAgICBsZXQgY3VycmVudF9jaGFubmVsX251bWJlciA9IGdsb2JhbF9pZHggJSB1bmlmb3Jtcy5DO1xuXG4gICAgbGV0IHNjYWxlX29mZnNldCA9IGN1cnJlbnRfaW1hZ2VfbnVtYmVyICogdW5pZm9ybXMuQyArIGN1cnJlbnRfY2hhbm5lbF9udW1iZXI7XG4gICAgbGV0IHNjYWxlID0gc2NhbGVfaW5wdXRbc2NhbGVfb2Zmc2V0XTtcbiAgICBvdXRwdXRbZ2xvYmFsX2lkeF0gPSBmbWEoaW5wdXRbZ2xvYmFsX2lkeF0sICR7c2NhbGVEYXRhKDApfSwgJHtzY2FsZURhdGEoMSl9KTtcbiAgfWA7XG4gIH07XG4gIGNvbnRleHQuY29tcHV0ZShcbiAgICB7XG4gICAgICBuYW1lOiAnSW5zdGFuY2VOb3JtYWxpemF0aW9uTkhXQycsXG4gICAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtjb21wb25lbnRzfWAsIGlucHV0RGVwZW5kZW5jaWVzIH0sXG4gICAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgICB9KSxcbiAgICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICB9LFxuICAgIHsgaW5wdXRzOiBbaW5wdXRzWzBdLCBjaGFubmVsU2NhbGVTaGlmdF0gfSxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBpbnN0YW5jZU5vcm0gPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEluc3RhbmNlTm9ybUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgaWYgKGF0dHJpYnV0ZXMuZm9ybWF0ID09PSAnTkhXQycpIHtcbiAgICBjcmVhdGVJbnN0YW5jZU5vcm1OSFdDUHJvZ3JhbUluZm8oY29udGV4dCwgY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICB9IGVsc2Uge1xuICAgIGNyZWF0ZUluc3RhbmNlTm9ybVByb2dyYW1JbmZvKGNvbnRleHQsIGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5LCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY2FzdFRvRjMyLFxuICBmaWxsVmVjdG9yLFxuICBnZXRNYXhDb21wb25lbnRzLFxuICBpbnB1dFZhcmlhYmxlLFxuICBvdXRwdXRWYXJpYWJsZSxcbiAgU2hhZGVySGVscGVyLFxuICBzdW1WZWN0b3IsXG4gIHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZSxcbiAgVW5pZm9ybXNBcnJheVR5cGUsXG59IGZyb20gJy4vY29tbW9uJztcblxuaW50ZXJmYWNlIExheWVyTm9ybUF0dHJpYnV0ZXMge1xuICBzaW1wbGlmaWVkOiBib29sZWFuO1xuICBheGlzOiBudW1iZXI7XG4gIGVwc2lsb246IG51bWJlcjtcbn1cblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCA8IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2xheWVyTm9ybSByZXF1aXJlcyBhdCBsZWFzdCAyIGlucHV0cy4nKTtcbiAgfVxufTtcblxuY29uc3QgY3JlYXRlTGF5ZXJOb3JtUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBMYXllck5vcm1BdHRyaWJ1dGVzLFxuICBvdXRwdXRDb3VudDogbnVtYmVyLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBzaW1wbGlmaWVkID0gYXR0cmlidXRlcy5zaW1wbGlmaWVkO1xuXG4gIGNvbnN0IHhTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBzY2FsZSA9IGlucHV0c1sxXTtcbiAgY29uc3QgYmlhcyA9ICFzaW1wbGlmaWVkICYmIGlucHV0c1syXTtcblxuICBjb25zdCBvdXRwdXRTaGFwZSA9IHhTaGFwZTtcbiAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgeFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IG5vcm1Db3VudCA9IFNoYXBlVXRpbC5zaXplVG9EaW1lbnNpb24oeFNoYXBlLCBheGlzKTtcbiAgY29uc3Qgbm9ybVNpemUgPSBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24oeFNoYXBlLCBheGlzKTtcblxuICBjb25zdCBzY2FsZVNpemUgPSBTaGFwZVV0aWwuc2l6ZShzY2FsZS5kaW1zKTtcbiAgY29uc3QgYmlhc1NpemUgPSBiaWFzID8gU2hhcGVVdGlsLnNpemUoYmlhcy5kaW1zKSA6IDA7XG4gIGlmIChzY2FsZVNpemUgIT09IG5vcm1TaXplIHx8IChiaWFzICYmIGJpYXNTaXplICE9PSBub3JtU2l6ZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFNpemUgb2YgWC5zaGFwZSgpW2F4aXM6XSA9PSAke25vcm1TaXplfS5cbiAgICAgICBTaXplIG9mIHNjYWxlIGFuZCBiaWFzIChpZiBwcm92aWRlZCkgbXVzdCBtYXRjaCB0aGlzLlxuICAgICAgIEdvdCBzY2FsZSBzaXplIG9mICR7c2NhbGVTaXplfSBhbmQgYmlhcyBzaXplIG9mICR7Ymlhc1NpemV9YCk7XG4gIH1cblxuICBjb25zdCBtZWFuSW52U3RkRGV2RGltOiBudW1iZXJbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHhTaGFwZS5sZW5ndGg7ICsraSkge1xuICAgIGlmIChpIDwgYXhpcykge1xuICAgICAgbWVhbkludlN0ZERldkRpbS5wdXNoKHhTaGFwZVtpXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1lYW5JbnZTdGREZXZEaW0ucHVzaCgxKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgY29tcG9uZW50cyA9IGdldE1heENvbXBvbmVudHMobm9ybVNpemUpO1xuICBjb25zdCBpbnB1dERlcGVuZGVuY2llczogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXSA9IFsndHlwZScsICd0eXBlJ107XG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogbm9ybUNvdW50IH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS5mbG9hdCwgZGF0YTogbm9ybVNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogTWF0aC5mbG9vcihub3JtU2l6ZSAvIGNvbXBvbmVudHMpIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS5mbG9hdCwgZGF0YTogYXR0cmlidXRlcy5lcHNpbG9uIH0sXG4gIF07XG4gIGlmIChiaWFzKSB7XG4gICAgaW5wdXREZXBlbmRlbmNpZXMucHVzaCgndHlwZScpO1xuICB9XG4gIGNvbnN0IGhhc01lYW5EYXRhT3V0cHV0ID0gb3V0cHV0Q291bnQgPiAxO1xuICBjb25zdCBoYXNJbnZTdGRPdXRwdXQgPSBvdXRwdXRDb3VudCA+IDI7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUoaW5wdXRzWzBdLmRhdGFUeXBlKTtcbiAgICBjb25zdCB2YXJpYWJsZXMgPSBbXG4gICAgICBpbnB1dFZhcmlhYmxlKCd4JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dHNbMF0uZGltcywgY29tcG9uZW50cyksXG4gICAgICBpbnB1dFZhcmlhYmxlKCdzY2FsZScsIHNjYWxlLmRhdGFUeXBlLCBzY2FsZS5kaW1zLCBjb21wb25lbnRzKSxcbiAgICBdO1xuICAgIGlmIChiaWFzKSB7XG4gICAgICB2YXJpYWJsZXMucHVzaChpbnB1dFZhcmlhYmxlKCdiaWFzJywgYmlhcy5kYXRhVHlwZSwgYmlhcy5kaW1zLCBjb21wb25lbnRzKSk7XG4gICAgfVxuICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlLCBjb21wb25lbnRzKSk7XG4gICAgaWYgKGhhc01lYW5EYXRhT3V0cHV0KSB7XG4gICAgICB2YXJpYWJsZXMucHVzaChvdXRwdXRWYXJpYWJsZSgnbWVhbl9kYXRhX291dHB1dCcsIERhdGFUeXBlLmZsb2F0LCBtZWFuSW52U3RkRGV2RGltKSk7XG4gICAgfVxuICAgIGlmIChoYXNJbnZTdGRPdXRwdXQpIHtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dFZhcmlhYmxlKCdpbnZfc3RkX291dHB1dCcsIERhdGFUeXBlLmZsb2F0LCBtZWFuSW52U3RkRGV2RGltKSk7XG4gICAgfVxuXG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnbm9ybV9jb3VudCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdub3JtX3NpemUnLCB0eXBlOiAnZjMyJyB9LFxuICAgICAgeyBuYW1lOiAnbm9ybV9zaXplX3ZlY3Rvcml6ZWQnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnZXBzaWxvbicsIHR5cGU6ICdmMzInIH0sXG4gICAgXTtcbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKC4uLnZhcmlhYmxlcyl9XG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm5vcm1fY291bnQnKX1cbiAgICBsZXQgb2Zmc2V0ID0gZ2xvYmFsX2lkeCAqIHVuaWZvcm1zLm5vcm1fc2l6ZV92ZWN0b3JpemVkO1xuICAgIHZhciBtZWFuX3ZlY3RvciA9ICR7ZmlsbFZlY3RvcignZjMyJywgY29tcG9uZW50cyl9O1xuICAgIHZhciBtZWFuX3NxdWFyZV92ZWN0b3IgPSAke2ZpbGxWZWN0b3IoJ2YzMicsIGNvbXBvbmVudHMpfTtcblxuICAgIGZvciAodmFyIGg6IHUzMiA9IDB1OyBoIDwgdW5pZm9ybXMubm9ybV9zaXplX3ZlY3Rvcml6ZWQ7IGgrKykge1xuICAgICAgbGV0IHZhbHVlID0gJHtjYXN0VG9GMzIoZGF0YVR5cGUsIGNvbXBvbmVudHMsICd4W2ggKyBvZmZzZXRdJyl9O1xuICAgICAgbWVhbl92ZWN0b3IgKz0gdmFsdWU7XG4gICAgICBtZWFuX3NxdWFyZV92ZWN0b3IgKz0gdmFsdWUgKiB2YWx1ZTtcbiAgICB9XG4gICAgbGV0IG1lYW4gPSAke3N1bVZlY3RvcignbWVhbl92ZWN0b3InLCBjb21wb25lbnRzKX0gLyB1bmlmb3Jtcy5ub3JtX3NpemU7XG4gICAgbGV0IGludl9zdGRfZGV2ID0gaW52ZXJzZVNxcnQoJHtzdW1WZWN0b3IoJ21lYW5fc3F1YXJlX3ZlY3RvcicsIGNvbXBvbmVudHMpfSAvIHVuaWZvcm1zLm5vcm1fc2l6ZSAke1xuICAgICAgc2ltcGxpZmllZCA/ICcnIDogJy0gbWVhbiAqIG1lYW4nXG4gICAgfSArIHVuaWZvcm1zLmVwc2lsb24pO1xuXG4gICAgZm9yICh2YXIgajogdTMyID0gMDsgaiA8IHVuaWZvcm1zLm5vcm1fc2l6ZV92ZWN0b3JpemVkOyBqKyspIHtcbiAgICAgIGxldCBmMzJpbnB1dCA9ICR7Y2FzdFRvRjMyKGRhdGFUeXBlLCBjb21wb25lbnRzLCAneFtqICsgb2Zmc2V0XScpfTtcbiAgICAgIGxldCBmMzJzY2FsZSA9ICR7Y2FzdFRvRjMyKGRhdGFUeXBlLCBjb21wb25lbnRzLCAnc2NhbGVbal0nKX07XG4gICAgICBvdXRwdXRbaiArIG9mZnNldF0gPSAke3ZhcmlhYmxlc1swXS50eXBlLnZhbHVlfSgoZjMyaW5wdXQgJHtzaW1wbGlmaWVkID8gJycgOiAnLSBtZWFuJ30pICogaW52X3N0ZF9kZXYgKiBmMzJzY2FsZVxuICAgICAgICAke2JpYXMgPyBgKyAke2Nhc3RUb0YzMihkYXRhVHlwZSwgY29tcG9uZW50cywgJ2JpYXNbal0nKX1gIDogJyd9XG4gICAgICApO1xuICAgIH1cblxuICAgICR7aGFzTWVhbkRhdGFPdXRwdXQgPyAnbWVhbl9kYXRhX291dHB1dFtnbG9iYWxfaWR4XSA9IG1lYW4nIDogJyd9O1xuICAgICR7aGFzSW52U3RkT3V0cHV0ID8gJ2ludl9zdGRfb3V0cHV0W2dsb2JhbF9pZHhdID0gaW52X3N0ZF9kZXYnIDogJyd9O1xuICB9YDtcbiAgfTtcbiAgY29uc3Qgb3V0cHV0cyA9IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH1dO1xuICBpZiAoaGFzTWVhbkRhdGFPdXRwdXQpIHtcbiAgICBvdXRwdXRzLnB1c2goeyBkaW1zOiBtZWFuSW52U3RkRGV2RGltLCBkYXRhVHlwZTogRGF0YVR5cGUuZmxvYXQgfSk7XG4gIH1cbiAgaWYgKGhhc0ludlN0ZE91dHB1dCkge1xuICAgIG91dHB1dHMucHVzaCh7IGRpbXM6IG1lYW5JbnZTdGREZXZEaW0sIGRhdGFUeXBlOiBEYXRhVHlwZS5mbG9hdCB9KTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0xheWVyTm9ybWFsaXphdGlvbicsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYCR7Y29tcG9uZW50c307JHtvdXRwdXRDb3VudH07JHtzaW1wbGlmaWVkfWAsIGlucHV0RGVwZW5kZW5jaWVzIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHMsXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChub3JtQ291bnQgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgbGF5ZXJOb3JtID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBMYXllck5vcm1BdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUxheWVyTm9ybVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzLCBjb250ZXh0Lm91dHB1dENvdW50KSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgQnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgY3JlYXRlTmFpdmVNYXRtdWxQcm9ncmFtSW5mbyB9IGZyb20gJy4vbWF0bXVsLXNoYWRlcnMnO1xuaW1wb3J0IHsgY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm8gfSBmcm9tICcuLzNyZC1wYXJ0eS9tYXRtdWxfcGFja2VkX3dlYmdwdSc7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01hdE11bCByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0uZGltc1tpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAxXSAhPT0gaW5wdXRzWzFdLmRpbXNbaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMl0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NoYXJlZCBkaW1lbnNpb24gZG9lcyBub3QgbWF0Y2guJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBtYXRNdWwgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IEJyb2FkY2FzdFV0aWwuY2FsY1NoYXBlKGNvbnRleHQuaW5wdXRzWzBdLmRpbXMsIGNvbnRleHQuaW5wdXRzWzFdLmRpbXMsIHRydWUpO1xuICBpZiAoIW91dHB1dFNoYXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgdXNlIG1hdG11bCBvbiB0aGUgZ2l2ZW4gdGVuc29yc1wiKTtcbiAgfVxuICBjb25zdCBOID0gb3V0cHV0U2hhcGVbb3V0cHV0U2hhcGUubGVuZ3RoIC0gMV07XG4gIGNvbnN0IEsgPSBjb250ZXh0LmlucHV0c1swXS5kaW1zW2NvbnRleHQuaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMV07XG4gIGlmIChOIDwgOCAmJiBLIDwgOCkge1xuICAgIGNvbnRleHQuY29tcHV0ZShjcmVhdGVOYWl2ZU1hdG11bFByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzLCB7IGFjdGl2YXRpb246ICcnIH0sIG91dHB1dFNoYXBlKSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgTSA9IG91dHB1dFNoYXBlW291dHB1dFNoYXBlLmxlbmd0aCAtIDJdO1xuICAgIGNvbnN0IGJhdGNoQSA9IFNoYXBlVXRpbC5zaXplKGNvbnRleHQuaW5wdXRzWzBdLmRpbXMuc2xpY2UoMCwgLTIpKTtcbiAgICBjb25zdCBiYXRjaEIgPSBTaGFwZVV0aWwuc2l6ZShjb250ZXh0LmlucHV0c1sxXS5kaW1zLnNsaWNlKDAsIC0yKSk7XG4gICAgaWYgKGJhdGNoQSAhPT0gMSAmJiBNID09PSAxICYmIGJhdGNoQiA9PT0gMSkge1xuICAgICAgLy8gT3B0aW1pemF0aW9uIGZvciBiYXRjaGVkIHZlYy1tYXQtbXVsXG4gICAgICBjb25zdCByZXNoYXBlZEEgPSBjb250ZXh0LmlucHV0c1swXS5yZXNoYXBlKFsxLCBiYXRjaEEsIEtdKTtcbiAgICAgIGNvbnN0IHJlc2hhcGVkQiA9IGNvbnRleHQuaW5wdXRzWzFdLnJlc2hhcGUoWzEsIEssIE5dKTtcbiAgICAgIGNvbnN0IG1hdG11bE91dHB1dFNoYXBlID0gWzEsIGJhdGNoQSwgTl07XG4gICAgICBjb25zdCBtYXRtdWxJbnB1dHMgPSBbcmVzaGFwZWRBLCByZXNoYXBlZEJdO1xuICAgICAgY29udGV4dC5jb21wdXRlKGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvKG1hdG11bElucHV0cywgeyBhY3RpdmF0aW9uOiAnJyB9LCBvdXRwdXRTaGFwZSwgbWF0bXVsT3V0cHV0U2hhcGUpLCB7XG4gICAgICAgIGlucHV0czogbWF0bXVsSW5wdXRzLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnRleHQuY29tcHV0ZShjcmVhdGVNYXRtdWxQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0cywgeyBhY3RpdmF0aW9uOiAnJyB9LCBvdXRwdXRTaGFwZSkpO1xuICAgIH1cbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyxcbiAgZ2V0TWF4Q29tcG9uZW50cyxcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbiAgdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbi8vICBUT0RPIHN1cHBvcnQgcXVhbnRpemF0aW9uIGJpdHMgbm90IGVxdWFsIHRvIDRcbmV4cG9ydCBpbnRlcmZhY2UgTWF0TXVsTkJpdHNBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgazogbnVtYmVyO1xuICBuOiBudW1iZXI7XG4gIGFjY3VyYWN5TGV2ZWw6IG51bWJlcjtcbiAgYml0czogbnVtYmVyO1xuICBibG9ja1NpemU6IG51bWJlcjtcbn1cblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IE1hdE11bE5CaXRzQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAoaW5wdXRzLmxlbmd0aCA8IDMgfHwgaW5wdXRzLmxlbmd0aCA+IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01hdE11bE5CaXRzIHJlcXVpcmVzIDMgb3IgNCBpbnB1dHMnKTtcbiAgfVxuICBjb25zdCBhID0gaW5wdXRzWzBdO1xuICBjb25zdCBhUmFuayA9IGEuZGltcy5sZW5ndGg7XG4gIGlmIChhLmRpbXNbYVJhbmsgLSAxXSAhPT0gYXR0cmlidXRlcy5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgbGFzdCBkaW0gb2YgaW5wdXQgc2hhcGUgZG9lcyBub3QgbWF0Y2ggdGhlIGsgdmFsdWUnKTtcbiAgfVxuICBjb25zdCBuQmxvY2tzUGVyQ29sID0gTWF0aC5mbG9vcigoYXR0cmlidXRlcy5rICsgYXR0cmlidXRlcy5ibG9ja1NpemUgLSAxKSAvIGF0dHJpYnV0ZXMuYmxvY2tTaXplKTtcbiAgY29uc3QgYmxvYlNpemUgPSAoYXR0cmlidXRlcy5ibG9ja1NpemUgLyA4KSAqIGF0dHJpYnV0ZXMuYml0cztcbiAgY29uc3QgYiA9IGlucHV0c1sxXTtcbiAgaWYgKCFTaGFwZVV0aWwuYXJlRXF1YWwoYi5kaW1zLCBbYXR0cmlidXRlcy5uLCBuQmxvY2tzUGVyQ29sLCBibG9iU2l6ZV0pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgc2Vjb25kIGlucHV0cyBtdXN0IGJlIDNEIHRlbnNvciB3aXRoIHNoYXBlIE4gWCBuQmxvY2tzUGVyQ29sIFggYmxvYlNpemUnKTtcbiAgfVxuICBjb25zdCBzY2FsZXMgPSBpbnB1dHNbMl07XG4gIGNvbnN0IHNjYWxlc1NoYXBlID0gc2NhbGVzLmRpbXM7XG4gIGlmIChTaGFwZVV0aWwuc2l6ZShzY2FsZXNTaGFwZSkgIT09IGF0dHJpYnV0ZXMubiAqIG5CbG9ja3NQZXJDb2wpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NjYWxlcyBpbnB1dCBzaXplIGVycm9yLicpO1xuICB9XG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSA0KSB7XG4gICAgY29uc3QgemVyb1BvaW50cyA9IGlucHV0c1szXTtcbiAgICBjb25zdCB6ZXJvUG9pbnRzU2hhcGUgPSB6ZXJvUG9pbnRzLmRpbXM7XG5cbiAgICAvLyBUaGlzIGFzc3VtZXMgemVybyBwb2ludHMgYXJlIHBhY2tlZC5cbiAgICAvLyBVbnBhY2sgZm9ybWF0ICh6ZXJvIHBvaW50IGhhcyBzYW1lIGRhdGEgdHlwZSBhbmQgc2hhcGUgYXMgc2NhbGUpIGlzIG5vdCBzdXBwb3J0ZWQgYnkgd2ViZ3B1LlxuICAgIGNvbnN0IGV4cGVjdGVkWmVyb1BvaW50c1NpemUgPVxuICAgICAgYXR0cmlidXRlcy5uICogKGF0dHJpYnV0ZXMuYml0cyA9PT0gOCA/IG5CbG9ja3NQZXJDb2wgOiBNYXRoLmZsb29yKChuQmxvY2tzUGVyQ29sICogYXR0cmlidXRlcy5iaXRzICsgNykgLyA4KSk7XG4gICAgaWYgKFNoYXBlVXRpbC5zaXplKHplcm9Qb2ludHNTaGFwZSkgIT09IGV4cGVjdGVkWmVyb1BvaW50c1NpemUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignemVyb1BvaW50cyBpbnB1dCBzaXplIGVycm9yLicpO1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZU1hdE11bE5CaXRzUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBNYXRNdWxOQml0c0F0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgYVJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgZGltQU91dGVyID0gaW5wdXRTaGFwZVthUmFuayAtIDJdO1xuICBjb25zdCBkaW1Jbm5lciA9IGF0dHJpYnV0ZXMuaztcbiAgY29uc3QgZGltQk91dGVyID0gYXR0cmlidXRlcy5uO1xuICBjb25zdCBiYXRjaERpbXMgPSBpbnB1dFNoYXBlLnNsaWNlKDAsIGFSYW5rIC0gMik7XG4gIGNvbnN0IGJhdGNoU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGJhdGNoRGltcyk7XG4gIGNvbnN0IGJsb2JTaXplID0gaW5wdXRzWzFdLmRpbXNbMl07XG4gIGNvbnN0IGJsb2JTaXplSW5Xb3JkcyA9IGJsb2JTaXplIC8gNDtcbiAgY29uc3QgZGF0YVR5cGUgPSBpbnB1dHNbMF0uZGF0YVR5cGU7XG4gIGNvbnN0IGFDb21wb25lbnRzID0gZ2V0TWF4Q29tcG9uZW50cyhhdHRyaWJ1dGVzLmspO1xuICBjb25zdCBiQ29tcG9uZW50cyA9IGdldE1heENvbXBvbmVudHMoYmxvYlNpemVJbldvcmRzKTtcbiAgY29uc3QgY29tcG9uZW50cyA9IGdldE1heENvbXBvbmVudHMoZGltQk91dGVyKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBiYXRjaERpbXMuY29uY2F0KFtkaW1BT3V0ZXIsIGRpbUJPdXRlcl0pO1xuICBjb25zdCBvdXRwdXROdW1iZXIgPSBkaW1BT3V0ZXIgPiAxICYmIChkaW1CT3V0ZXIgLyBjb21wb25lbnRzKSAlIDIgPT09IDAgPyAyIDogMTtcbiAgY29uc3QgZGlzcGF0Y2hTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpIC8gY29tcG9uZW50cyAvIG91dHB1dE51bWJlcjtcblxuICBjb25zdCB3b3JrZ3JvdXBTaXplID0gNjQ7XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW107XG4gIGNvbnN0IGlucHV0U2hhcGVUZW1wID0gW2JhdGNoU2l6ZSwgZGltQU91dGVyLCBkaW1Jbm5lciAvIGFDb21wb25lbnRzXTtcbiAgY29uc3QgYlNoYXBlID0gU2hhcGVVdGlsLmNvbnZlcnRTaGFwZShpbnB1dHNbMV0uZGltcykuc2xpY2UoKTtcbiAgYlNoYXBlLnNwbGljZSgtMSwgMSwgYmxvYlNpemVJbldvcmRzIC8gYkNvbXBvbmVudHMpO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dFNoYXBlVGVtcCkpO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhiU2hhcGUpKTtcbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRzWzJdLmRpbXMpKTtcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDQpIHtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhTaGFwZVV0aWwuY29udmVydFNoYXBlKGlucHV0c1szXS5kaW1zKSkpO1xuICB9XG4gIGNvbnN0IG91dHB1dFNoYXBlVGVtcCA9IFtiYXRjaFNpemUsIGRpbUFPdXRlciwgZGltQk91dGVyIC8gY29tcG9uZW50c107XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKG91dHB1dFNoYXBlVGVtcCkpO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGlucHV0UmFuayA9IGlucHV0U2hhcGVUZW1wLmxlbmd0aDtcbiAgICBjb25zdCBhID0gaW5wdXRWYXJpYWJsZSgnYScsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRSYW5rLCBhQ29tcG9uZW50cyk7XG4gICAgY29uc3QgYiA9IGlucHV0VmFyaWFibGUoJ2InLCBEYXRhVHlwZS51aW50MzIsIGJTaGFwZS5sZW5ndGgsIGJDb21wb25lbnRzKTtcbiAgICBjb25zdCBzY2FsZXMgPSBpbnB1dFZhcmlhYmxlKCdzY2FsZXMnLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLmxlbmd0aCk7XG4gICAgY29uc3QgaW5wdXRWYXJpYWJsZXMgPSBbYSwgYiwgc2NhbGVzXTtcbiAgICBjb25zdCB6ZXJvUG9pbnRzID1cbiAgICAgIGlucHV0cy5sZW5ndGggPT09IDQgPyBpbnB1dFZhcmlhYmxlKCd6ZXJvX3BvaW50cycsIERhdGFUeXBlLnVpbnQzMiwgaW5wdXRzWzNdLmRpbXMubGVuZ3RoKSA6IHVuZGVmaW5lZDtcbiAgICBpZiAoemVyb1BvaW50cykge1xuICAgICAgaW5wdXRWYXJpYWJsZXMucHVzaCh6ZXJvUG9pbnRzKTtcbiAgICB9XG4gICAgY29uc3Qgb3V0cHV0UmFuayA9IG91dHB1dFNoYXBlVGVtcC5sZW5ndGg7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0UmFuaywgY29tcG9uZW50cyk7XG4gICAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUoaW5wdXRzWzBdLmRhdGFUeXBlKTtcblxuICAgIGNvbnN0IHFEcURhdGFUeXBlID0gKCgpID0+IHtcbiAgICAgIHN3aXRjaCAoYUNvbXBvbmVudHMpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIHJldHVybiBgYXJyYXk8JHtkYXRhVHlwZX0sIDg+YDtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHJldHVybiBgbWF0NHgyPCR7ZGF0YVR5cGV9PmA7XG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICByZXR1cm4gYG1hdDJ4NDwke2RhdGFUeXBlfT5gO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHthQ29tcG9uZW50c30tY29tcG9uZW50IGlzIG5vdCBzdXBwb3J0ZWQuYCk7XG4gICAgICB9XG4gICAgfSkoKTtcblxuICAgIC8vIE51bWJlciBvZiBxdWFudGl6ZWQgdmFsdWVzIHBlciB1MzIgd29yZCBhbmQgcGFzc2VzIG5lZWRlZCAoZWFjaCBwYXNzIGV4dHJhY3RzIDggdmFsdWVzKS5cbiAgICBjb25zdCB2YWx1ZXNQZXJXb3JkID0gTWF0aC5mbG9vcigzMiAvIGF0dHJpYnV0ZXMuYml0cyk7IC8vIFE0PTgsIFEyPTE2XG4gICAgY29uc3QgcGFzc2VzUGVyV29yZCA9IE1hdGguZmxvb3IodmFsdWVzUGVyV29yZCAvIDgpOyAvLyBRND0xLCBRMj0yXG5cbiAgICBjb25zdCBwcm9jZXNzT25lV29yZCA9ICgpOiBzdHJpbmcgPT4ge1xuICAgICAgbGV0IGNhbGNTdHIgPSAnJztcbiAgICAgIGZvciAobGV0IHBhc3MgPSAwOyBwYXNzIDwgcGFzc2VzUGVyV29yZDsgcGFzcysrKSB7XG4gICAgICAgIC8vIEVhY2ggcGFzcyBwcm9jZXNzZXMgOCB2YWx1ZXMgZnJvbSB0aGUgY3VycmVudCB1MzIgd29yZC5cbiAgICAgICAgLy8gRm9yIFE0IChwYXNzPTApOiBzaGlmdCBieSAwIGFuZCA0LiBGb3IgUTIgKHBhc3MgMDogc2hpZnQgMCwyOyBwYXNzIDE6IHNoaWZ0IDQsNikuXG4gICAgICAgIGNvbnN0IGxvd2VyU2hpZnQgPSBwYXNzICogYXR0cmlidXRlcy5iaXRzICogNDsgLy8gYml0IG9mZnNldCBmb3IgbG93ZXIgZ3JvdXAgd2l0aGluIGVhY2ggYnl0ZVxuICAgICAgICBjb25zdCB1cHBlclNoaWZ0ID0gbG93ZXJTaGlmdCArIGF0dHJpYnV0ZXMuYml0cztcbiAgICAgICAgY2FsY1N0ciArPSBgXG4gICAgICAgICAgLy8gcmV1c2UgYSBkYXRhIChwYXNzICR7cGFzc30pXG4gICAgICAgICAgICB2YXIgaW5wdXRfb2Zmc2V0JHtwYXNzID4gMCA/IHBhc3MgOiAnJ30gPSAke3Bhc3MgPT09IDAgPyBhLmluZGljZXNUb09mZnNldChgJHthLnR5cGUuaW5kaWNlc30oYmF0Y2gsIHJvdywgd29yZF9vZmZzZXQpYCkgOiBgaW5wdXRfb2Zmc2V0YH07XG4gICAgICAgICAgICB2YXIgYV9kYXRhJHtwYXNzID4gMCA/IHBhc3MgOiAnJ306ICR7cURxRGF0YVR5cGV9O1xuICAgICAgICAgICAgZm9yICh2YXIgaiR7cGFzcyA+IDAgPyBwYXNzIDogJyd9OiB1MzIgPSAwOyBqJHtwYXNzID4gMCA/IHBhc3MgOiAnJ30gPCAkezggLyBhQ29tcG9uZW50c307IGoke3Bhc3MgPiAwID8gcGFzcyA6ICcnfSsrKSB7XG4gICAgICAgICAgICAgIGFfZGF0YSR7cGFzcyA+IDAgPyBwYXNzIDogJyd9W2oke3Bhc3MgPiAwID8gcGFzcyA6ICcnfV0gPSAke2EuZ2V0QnlPZmZzZXQoYGlucHV0X29mZnNldCR7cGFzcyA+IDAgPyBwYXNzIDogJyd9YCl9O1xuICAgICAgICAgICAgICBpbnB1dF9vZmZzZXQke3Bhc3MgPiAwID8gcGFzcyA6ICcnfSsrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIGA7XG4gICAgICAgIGZvciAobGV0IGMgPSAwOyBjIDwgY29tcG9uZW50cyAqIG91dHB1dE51bWJlcjsgYysrKSB7XG4gICAgICAgICAgY2FsY1N0ciArPSBgXG4gICAgICAgICAgICBiX3ZhbHVlID0gJHtiQ29tcG9uZW50cyA9PT0gMSA/IGBiJHtjfV9kYXRhYCA6IGBiJHtjfV9kYXRhW2ldYH07XG4gICAgICAgICAgICAke1xuICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmJpdHMgPT09IDJcbiAgICAgICAgICAgICAgICA/IGB7XG4gICAgICAgICAgICAgIGxldCBoYWxmX3dvcmQgPSBiX3ZhbHVlID4+ICR7cGFzcyAqIDE2fXU7XG4gICAgICAgICAgICAgIGxldCBieXRlX2xvID0gaGFsZl93b3JkICYgMHhGRnU7XG4gICAgICAgICAgICAgIGxldCBieXRlX2hpID0gKGhhbGZfd29yZCA+PiA4dSkgJiAweEZGdTtcbiAgICAgICAgICAgICAgbGV0IHNwcmVhZF93b3JkID0gKGJ5dGVfbG8gJiAweEZ1KSB8ICgoYnl0ZV9sbyA+PiA0dSkgPDwgOHUpIHwgKChieXRlX2hpICYgMHhGdSkgPDwgMTZ1KSB8ICgoYnl0ZV9oaSA+PiA0dSkgPDwgMjR1KTtcbiAgICAgICAgICAgICAgYl92YWx1ZV9sb3dlciA9IHVucGFjazR4VTgoc3ByZWFkX3dvcmQgJiBiX21hc2spO1xuICAgICAgICAgICAgICBiX3ZhbHVlX3VwcGVyID0gdW5wYWNrNHhVOCgoc3ByZWFkX3dvcmQgPj4gMnUpICYgYl9tYXNrKTtcbiAgICAgICAgICAgIH1gXG4gICAgICAgICAgICAgICAgOiBgYl92YWx1ZV9sb3dlciA9IHVucGFjazR4VTgoKGJfdmFsdWUgPj4gJHtsb3dlclNoaWZ0fXUpICYgYl9tYXNrKTtcbiAgICAgICAgICAgIGJfdmFsdWVfdXBwZXIgPSB1bnBhY2s0eFU4KChiX3ZhbHVlID4+ICR7dXBwZXJTaGlmdH11KSAmIGJfbWFzayk7YFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYl9xdWFudGl6ZWRfdmFsdWVzID0gJHtxRHFEYXRhVHlwZX0oJHtBcnJheS5mcm9tKFxuICAgICAgICAgICAgICB7IGxlbmd0aDogNCB9LFxuICAgICAgICAgICAgICAoXywgaSkgPT4gYCR7ZGF0YVR5cGV9KGJfdmFsdWVfbG93ZXJbJHtpfV0pLCAke2RhdGFUeXBlfShiX3ZhbHVlX3VwcGVyWyR7aX1dKWAsXG4gICAgICAgICAgICApLmpvaW4oJywgJyl9KTtcbiAgICAgICAgICAgIGJfZGVxdWFudGl6ZWRfdmFsdWVzID0gJHsoKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoYUNvbXBvbmVudHMgPT09IDEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7cURxRGF0YVR5cGV9KCR7QXJyYXkuZnJvbShcbiAgICAgICAgICAgICAgICAgIHsgbGVuZ3RoOiA4IH0sXG4gICAgICAgICAgICAgICAgICAoXywgaSkgPT4gYChiX3F1YW50aXplZF92YWx1ZXNbJHtpfV0gLSAke3plcm9Qb2ludHMgPyBgemVyb19wb2ludCR7Y31gIDogJ3plcm9fcG9pbnQnfSkgKiBzY2FsZSR7Y31gLFxuICAgICAgICAgICAgICAgICkuam9pbignLCAnKX0pO2A7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAoYl9xdWFudGl6ZWRfdmFsdWVzIC0gJHtxRHFEYXRhVHlwZX0oJHtBcnJheSg4KVxuICAgICAgICAgICAgICAgICAgLmZpbGwoYCR7emVyb1BvaW50cyA/IGB6ZXJvX3BvaW50JHtjfWAgOiAnemVyb19wb2ludCd9YClcbiAgICAgICAgICAgICAgICAgIC5qb2luKCcsJyl9KSkgKiBzY2FsZSR7Y307YDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkoKX07XG4gICAgICAgICAgICB3b3JrZ3JvdXBfc2hhcmVkW2xvY2FsX2lkLnggKiAke291dHB1dE51bWJlcn0gKyAke01hdGguZmxvb3IoYyAvIGNvbXBvbmVudHMpfV0ke2NvbXBvbmVudHMgPiAxID8gYFske2MgJSBjb21wb25lbnRzfV1gIDogJyd9ICs9ICR7QXJyYXkuZnJvbShcbiAgICAgICAgICAgICAgeyBsZW5ndGg6IDggLyBhQ29tcG9uZW50cyB9LFxuICAgICAgICAgICAgICAoXywgaSkgPT5cbiAgICAgICAgICAgICAgICBgJHtcbiAgICAgICAgICAgICAgICAgIGFDb21wb25lbnRzID09PSAxXG4gICAgICAgICAgICAgICAgICAgID8gYGFfZGF0YSR7cGFzcyA+IDAgPyBwYXNzIDogJyd9WyR7aX1dICogYl9kZXF1YW50aXplZF92YWx1ZXNbJHtpfV1gXG4gICAgICAgICAgICAgICAgICAgIDogYGRvdChhX2RhdGEke3Bhc3MgPiAwID8gcGFzcyA6ICcnfVske2l9XSwgYl9kZXF1YW50aXplZF92YWx1ZXNbJHtpfV0pYFxuICAgICAgICAgICAgICAgIH1gLFxuICAgICAgICAgICAgKS5qb2luKCcgKyAnKX07XG4gICAgICAgICAgYDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGNhbGNTdHI7XG4gICAgfTtcbiAgICBjb25zdCBwcmVwYXJlU2NhbGVBbmRaZXJvUG9pbnQgPSAoKTogc3RyaW5nID0+IHtcbiAgICAgIGxldCBjYWxjU3RyID0gYFxuICAgICAgICAgICAgdmFyIGNvbF9pbmRleCA9IGNvbCAqICR7Y29tcG9uZW50c307XG4gICAgICAgICAgICAke1xuICAgICAgICAgICAgICB6ZXJvUG9pbnRzXG4gICAgICAgICAgICAgICAgPyBgXG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF92YWx1ZXNfcGVyX2J5dGU6IHUzMiA9ICR7TWF0aC5mbG9vcig4IC8gYXR0cmlidXRlcy5iaXRzKX11O1xuICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfYnl0ZXNfcGVyX2NvbCA9IChuQmxvY2tzUGVyQ29sICsgemVyb19wb2ludF92YWx1ZXNfcGVyX2J5dGUgLSAxdSkgLyB6ZXJvX3BvaW50X3ZhbHVlc19wZXJfYnl0ZTtcbiAgICAgICAgICAgIHZhciB6ZXJvX3BvaW50X2J5dGVfY291bnQ6IHUzMjtcbiAgICAgICAgICAgIHZhciB6ZXJvX3BvaW50X3dvcmRfaW5kZXg6IHUzMjtcbiAgICAgICAgICAgIHZhciB6ZXJvX3BvaW50X2J5dGVfb2Zmc2V0OiB1MzI7XG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF9zdWJfb2Zmc2V0OiB1MzIgPSBibG9jayAlIHplcm9fcG9pbnRfdmFsdWVzX3Blcl9ieXRlO1xuICAgICAgICAgICAgdmFyIHplcm9fcG9pbnRfYml0c19vZmZzZXQ6IHUzMjtcbiAgICAgICAgICAgIHZhciB6ZXJvX3BvaW50X3dvcmQ6IHUzMjtgXG4gICAgICAgICAgICAgICAgOiBgXG4gICAgICAgICAgICAvLyBUaGUgZGVmYXVsdCB6ZXJvIHBvaW50IGlzICR7TWF0aC5wb3coMiwgYXR0cmlidXRlcy5iaXRzIC0gMSl9IGZvciB1bnNpZ25lZCAke2F0dHJpYnV0ZXMuYml0c30tYml0IHF1YW50aXphdGlvbi5cbiAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50ID0gJHtkYXRhVHlwZX0oJHtNYXRoLnBvdygyLCBhdHRyaWJ1dGVzLmJpdHMgLSAxKS50b0ZpeGVkKDEpfSk7YFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYDtcbiAgICAgIGZvciAobGV0IGMgPSAwOyBjIDwgY29tcG9uZW50cyAqIG91dHB1dE51bWJlcjsgYysrKSB7XG4gICAgICAgIGNhbGNTdHIgKz0gYFxuICAgICAgICAgICAgbGV0IHNjYWxlJHtjfSA9ICR7c2NhbGVzLmdldEJ5T2Zmc2V0KGBjb2xfaW5kZXggKiBuQmxvY2tzUGVyQ29sICsgYmxvY2tgKX07XG4gICAgICAgICAgICAke1xuICAgICAgICAgICAgICB6ZXJvUG9pbnRzXG4gICAgICAgICAgICAgICAgPyBgXG4gICAgICAgICAgICB6ZXJvX3BvaW50X2J5dGVfY291bnQgPSBjb2xfaW5kZXggKiB6ZXJvX3BvaW50X2J5dGVzX3Blcl9jb2wgKyAoYmxvY2sgLyB6ZXJvX3BvaW50X3ZhbHVlc19wZXJfYnl0ZSk7XG4gICAgICAgICAgICB6ZXJvX3BvaW50X3dvcmRfaW5kZXggPSB6ZXJvX3BvaW50X2J5dGVfY291bnQgPj4gMHgydTtcbiAgICAgICAgICAgIHplcm9fcG9pbnRfYnl0ZV9vZmZzZXQgPSB6ZXJvX3BvaW50X2J5dGVfY291bnQgJiAweDN1O1xuICAgICAgICAgICAgemVyb19wb2ludF9iaXRzX29mZnNldCA9ICh6ZXJvX3BvaW50X2J5dGVfb2Zmc2V0IDw8IDMpICsgKHplcm9fcG9pbnRfc3ViX29mZnNldCAqICR7YXR0cmlidXRlcy5iaXRzfXUpO1xuICAgICAgICAgICAgemVyb19wb2ludF93b3JkID0gJHt6ZXJvUG9pbnRzLmdldEJ5T2Zmc2V0KCd6ZXJvX3BvaW50X3dvcmRfaW5kZXgnKX0gPj4gemVyb19wb2ludF9iaXRzX29mZnNldDtcbiAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50JHtjfSA9ICR7ZGF0YVR5cGV9KCh6ZXJvX3BvaW50X3dvcmQpICYgJHthdHRyaWJ1dGVzLmJpdHMgPT09IDIgPyAnMHgzdScgOiAnMHhGdSd9KTtgXG4gICAgICAgICAgICAgICAgOiAnJ1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29sX2luZGV4ICs9IDE7YDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjYWxjU3RyO1xuICAgIH07XG4gICAgY29uc3QgcHJlcGFyZUJEYXRhID0gKCk6IHN0cmluZyA9PiB7XG4gICAgICBsZXQgY2FsY1N0ciA9IGBjb2xfaW5kZXggPSBjb2wgKiAke2NvbXBvbmVudHN9O2A7XG4gICAgICBmb3IgKGxldCBjID0gMDsgYyA8IGNvbXBvbmVudHMgKiBvdXRwdXROdW1iZXI7IGMrKykge1xuICAgICAgICBjYWxjU3RyICs9IGBcbiAgICAgICAgICAgIGxldCBiJHtjfV9kYXRhID0gJHtiLmdldEJ5SW5kaWNlcyhgJHtiLnR5cGUuaW5kaWNlc30oY29sX2luZGV4LCBibG9jaywgd29yZClgKX07XG4gICAgICAgICAgICBjb2xfaW5kZXggKz0gMTtgO1xuICAgICAgfVxuICAgICAgY2FsY1N0ciArPSBgXG4gICAgICAgICAgICB2YXIgYl92YWx1ZTogdTMyO1xuICAgICAgICAgICAgbGV0IGJfbWFzazogdTMyID0gJHthdHRyaWJ1dGVzLmJpdHMgPT09IDIgPyAnMHgwMzAzMDMwM3UnIDogJzB4MEYwRjBGMEZ1J307XG4gICAgICAgICAgICB2YXIgYl92YWx1ZV9sb3dlcjogdmVjNDx1MzI+O1xuICAgICAgICAgICAgdmFyIGJfdmFsdWVfdXBwZXI6IHZlYzQ8dTMyPjtcbiAgICAgICAgICAgIHZhciBiX3F1YW50aXplZF92YWx1ZXM6ICR7cURxRGF0YVR5cGV9O1xuICAgICAgICAgICAgdmFyIGJfZGVxdWFudGl6ZWRfdmFsdWVzOiAke3FEcURhdGFUeXBlfTtgO1xuICAgICAgcmV0dXJuIGNhbGNTdHI7XG4gICAgfTtcbiAgICByZXR1cm4gYFxuICAgICAgICB2YXI8d29ya2dyb3VwPiB3b3JrZ3JvdXBfc2hhcmVkOiBhcnJheTwke291dHB1dC50eXBlLnZhbHVlfSwgJHtvdXRwdXROdW1iZXIgKiB3b3JrZ3JvdXBTaXplfT47XG4gICAgICAgICR7c2hhZGVySGVscGVyLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJpYWJsZXMsIG91dHB1dCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydChbd29ya2dyb3VwU2l6ZSwgMSwgMV0pfVxuICAgICAgICAgIGxldCBvdXRwdXRfaW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcyhgKGdsb2JhbF9pZHggLyAke3dvcmtncm91cFNpemV9KSAqICR7b3V0cHV0TnVtYmVyfWApfTtcbiAgICAgICAgICBsZXQgY29sID0gb3V0cHV0X2luZGljZXNbMl07XG4gICAgICAgICAgbGV0IHJvdyA9IG91dHB1dF9pbmRpY2VzWzFdO1xuICAgICAgICAgIGxldCBiYXRjaCA9IG91dHB1dF9pbmRpY2VzWzBdO1xuICAgICAgICAgIGxldCBuQmxvY2tzUGVyQ29sID0gdW5pZm9ybXMuYl9zaGFwZVsxXTtcblxuICAgICAgICAgIGZvciAodmFyIGJsb2NrID0gbG9jYWxfaWQueDsgYmxvY2sgPCBuQmxvY2tzUGVyQ29sOyBibG9jayArPSAke3dvcmtncm91cFNpemV9KSB7XG4gICAgICAgICAgICAvL3Byb2Nlc3Mgb25lIGJsb2NrXG4gICAgICAgICAgICB2YXIgd29yZF9vZmZzZXQ6IHUzMiA9IGJsb2NrICogJHthdHRyaWJ1dGVzLmJsb2NrU2l6ZSAvIGFDb21wb25lbnRzfTtcbiAgICAgICAgICAgICR7cHJlcGFyZVNjYWxlQW5kWmVyb1BvaW50KCl9XG4gICAgICAgICAgICBmb3IgKHZhciB3b3JkOiB1MzIgPSAwOyB3b3JkIDwgJHtibG9iU2l6ZUluV29yZHN9OyB3b3JkICs9ICR7YkNvbXBvbmVudHN9KSB7XG4gICAgICAgICAgICAgICR7cHJlcGFyZUJEYXRhKCl9XG4gICAgICAgICAgICAgIGZvciAodmFyIGk6IHUzMiA9IDA7IGkgPCAke2JDb21wb25lbnRzfTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgJHtwcm9jZXNzT25lV29yZCgpfVxuICAgICAgICAgICAgICAgIHdvcmRfb2Zmc2V0ICs9ICR7dmFsdWVzUGVyV29yZCAvIGFDb21wb25lbnRzfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICAgICAgICBpZiAobG9jYWxfaWQueCA8ICR7b3V0cHV0TnVtYmVyfSkge1xuICAgICAgICAgICAgdmFyIG91dHB1dF92YWx1ZTogJHtvdXRwdXQudHlwZS52YWx1ZX0gPSAke291dHB1dC50eXBlLnZhbHVlfSgwKTtcbiAgICAgICAgICAgIHZhciB3b3JrZ3JvdXBfc2hhcmVkX29mZnNldDogdTMyID0gbG9jYWxfaWQueDtcbiAgICAgICAgICAgIGZvciAodmFyIGI6IHUzMiA9IDB1OyBiIDwgJHt3b3JrZ3JvdXBTaXplfXU7IGIrKykge1xuICAgICAgICAgICAgICBvdXRwdXRfdmFsdWUgKz0gd29ya2dyb3VwX3NoYXJlZFt3b3JrZ3JvdXBfc2hhcmVkX29mZnNldF07XG4gICAgICAgICAgICAgIHdvcmtncm91cF9zaGFyZWRfb2Zmc2V0ICs9ICR7b3V0cHV0TnVtYmVyfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICR7b3V0cHV0LnNldEJ5SW5kaWNlcyhgJHtvdXRwdXQudHlwZS5pbmRpY2VzfShiYXRjaCwgcm93LCBjb2wgKyBsb2NhbF9pZC54KWAsICdvdXRwdXRfdmFsdWUnKX07XG4gICAgICAgICAgfVxuICAgICAgICB9YDtcbiAgfTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnTWF0TXVsTkJpdHMnLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHthdHRyaWJ1dGVzLmJsb2NrU2l6ZX07JHthdHRyaWJ1dGVzLmJpdHN9OyR7YUNvbXBvbmVudHN9OyR7YkNvbXBvbmVudHN9OyR7Y29tcG9uZW50c307JHtvdXRwdXROdW1iZXJ9OyR7d29ya2dyb3VwU2l6ZX1gLFxuICAgICAgaW5wdXREZXBlbmRlbmNpZXM6IEFycmF5KGlucHV0cy5sZW5ndGgpLmZpbGwoJ3JhbmsnKSxcbiAgICB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IGRpc3BhdGNoU2l6ZSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbi8vIEN1cnJlbnRseSwgb25seSBzdXBwb3J0IGJsb2NrU2l6ZSA9IDMyLlxuZXhwb3J0IGNvbnN0IGNyZWF0ZU1hdE11bE5CaXRzQmxvY2tTaXplMzJQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IE1hdE11bE5CaXRzQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBhUmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBkaW1BT3V0ZXIgPSBpbnB1dFNoYXBlW2FSYW5rIC0gMl07XG4gIGNvbnN0IGRpbUlubmVyID0gYXR0cmlidXRlcy5rO1xuICBjb25zdCBkaW1CT3V0ZXIgPSBhdHRyaWJ1dGVzLm47XG4gIGNvbnN0IGJhdGNoRGltcyA9IGlucHV0U2hhcGUuc2xpY2UoMCwgYVJhbmsgLSAyKTtcbiAgY29uc3QgYmF0Y2hTaXplID0gU2hhcGVVdGlsLnNpemUoYmF0Y2hEaW1zKTtcbiAgY29uc3QgYmxvYlNpemUgPSBpbnB1dHNbMV0uZGltc1syXTtcbiAgY29uc3QgYmxvYlNpemVJbldvcmRzID0gYmxvYlNpemUgLyA0O1xuICBjb25zdCBkYXRhVHlwZSA9IGlucHV0c1swXS5kYXRhVHlwZTtcbiAgY29uc3QgYUNvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKGF0dHJpYnV0ZXMuayk7XG4gIGNvbnN0IGJDb21wb25lbnRzID0gZ2V0TWF4Q29tcG9uZW50cyhibG9iU2l6ZUluV29yZHMpO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGJhdGNoRGltcy5jb25jYXQoW2RpbUFPdXRlciwgZGltQk91dGVyXSk7XG5cbiAgY29uc3Qgd29ya2dyb3VwU2l6ZSA9IDEyODtcbiAgY29uc3Qgd29ya2dyb3VwWSA9IGRpbUJPdXRlciAlIDggPT09IDAgPyA4IDogZGltQk91dGVyICUgNCA9PT0gMCA/IDQgOiAxO1xuICBjb25zdCB3b3JrZ3JvdXBYID0gd29ya2dyb3VwU2l6ZSAvIHdvcmtncm91cFk7XG4gIGNvbnN0IHZhbHVlc1BlcldvcmRCczMyID0gTWF0aC5mbG9vcigzMiAvIGF0dHJpYnV0ZXMuYml0cyk7IC8vIFE0PTgsIFEyPTE2XG4gIGNvbnN0IHRpbGVTaXplID0gd29ya2dyb3VwWCAqIGJDb21wb25lbnRzICogdmFsdWVzUGVyV29yZEJzMzI7IC8vIGVhY2ggdWludDMyIGhhcyB2YWx1ZXNQZXJXb3JkIGRhdGEuXG4gIGNvbnN0IGFMZW5ndGhQZXJUaWxlID0gdGlsZVNpemUgLyBhQ29tcG9uZW50cztcbiAgY29uc3QgYmxvY2tzUGVyVGlsZSA9IHRpbGVTaXplIC8gYXR0cmlidXRlcy5ibG9ja1NpemU7XG4gIGNvbnN0IGRpc3BhdGNoU2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKSAvIHdvcmtncm91cFk7XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW107XG4gIGNvbnN0IGlucHV0U2hhcGVUZW1wID0gW2JhdGNoU2l6ZSwgZGltQU91dGVyLCBkaW1Jbm5lciAvIGFDb21wb25lbnRzXTtcbiAgY29uc3QgYlNoYXBlID0gU2hhcGVVdGlsLmNvbnZlcnRTaGFwZShpbnB1dHNbMV0uZGltcykuc2xpY2UoKTtcbiAgYlNoYXBlLnNwbGljZSgtMSwgMSwgYmxvYlNpemVJbldvcmRzIC8gYkNvbXBvbmVudHMpO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dFNoYXBlVGVtcCkpO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhiU2hhcGUpKTtcbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRzWzJdLmRpbXMpKTtcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDQpIHtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhTaGFwZVV0aWwuY29udmVydFNoYXBlKGlucHV0c1szXS5kaW1zKSkpO1xuICB9XG4gIGNvbnN0IG91dHB1dFNoYXBlVGVtcCA9IFtiYXRjaFNpemUsIGRpbUFPdXRlciwgZGltQk91dGVyXTtcbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMob3V0cHV0U2hhcGVUZW1wKSk7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgaW5wdXRSYW5rID0gaW5wdXRTaGFwZVRlbXAubGVuZ3RoO1xuICAgIGNvbnN0IGEgPSBpbnB1dFZhcmlhYmxlKCdhJywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dFJhbmssIGFDb21wb25lbnRzKTtcbiAgICBjb25zdCBiID0gaW5wdXRWYXJpYWJsZSgnYicsIERhdGFUeXBlLnVpbnQzMiwgYlNoYXBlLmxlbmd0aCwgYkNvbXBvbmVudHMpO1xuICAgIGNvbnN0IHNjYWxlcyA9IGlucHV0VmFyaWFibGUoJ3NjYWxlcycsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoKTtcbiAgICBjb25zdCBpbnB1dFZhcmlhYmxlcyA9IFthLCBiLCBzY2FsZXNdO1xuICAgIGNvbnN0IHplcm9Qb2ludHMgPVxuICAgICAgaW5wdXRzLmxlbmd0aCA9PT0gNCA/IGlucHV0VmFyaWFibGUoJ3plcm9fcG9pbnRzJywgRGF0YVR5cGUudWludDMyLCBpbnB1dHNbM10uZGltcy5sZW5ndGgpIDogdW5kZWZpbmVkO1xuICAgIGlmICh6ZXJvUG9pbnRzKSB7XG4gICAgICBpbnB1dFZhcmlhYmxlcy5wdXNoKHplcm9Qb2ludHMpO1xuICAgIH1cbiAgICBjb25zdCBvdXRwdXRSYW5rID0gb3V0cHV0U2hhcGVUZW1wLmxlbmd0aDtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRSYW5rKTtcbiAgICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZShpbnB1dHNbMF0uZGF0YVR5cGUpO1xuICAgIGNvbnN0IHJlYWRBID0gKCkgPT4ge1xuICAgICAgc3dpdGNoIChhQ29tcG9uZW50cykge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICBsZXQgYV9kYXRhMCA9IHZlYzQ8JHtkYXRhVHlwZX0+KHN1Yl9hW3dvcmRfb2Zmc2V0XSwgc3ViX2Fbd29yZF9vZmZzZXQgKyAxXSwgc3ViX2Fbd29yZF9vZmZzZXQgKyAyXSwgc3ViX2Fbd29yZF9vZmZzZXQgKyAzXSk7XG4gICAgICAgICAgbGV0IGFfZGF0YTEgPSB2ZWM0PCR7ZGF0YVR5cGV9PihzdWJfYVt3b3JkX29mZnNldCArIDRdLCBzdWJfYVt3b3JkX29mZnNldCArIDVdLCBzdWJfYVt3b3JkX29mZnNldCArIDZdLCBzdWJfYVt3b3JkX29mZnNldCArIDddKTtgO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICBsZXQgYV9kYXRhMCA9IHZlYzQ8JHtkYXRhVHlwZX0+KHN1Yl9hW3dvcmRfb2Zmc2V0XSwgc3ViX2Fbd29yZF9vZmZzZXQgKyAxXSk7XG4gICAgICAgICAgbGV0IGFfZGF0YTEgPSB2ZWM0PCR7ZGF0YVR5cGV9PihzdWJfYVt3b3JkX29mZnNldCArIDJdLCBzdWJfYVt3b3JkX29mZnNldCArIDNdKTtgO1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICBsZXQgYV9kYXRhMCA9IHN1Yl9hW3dvcmRfb2Zmc2V0XTtcbiAgICAgICAgICBsZXQgYV9kYXRhMSA9IHN1Yl9hW3dvcmRfb2Zmc2V0ICsgMV07YDtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7YUNvbXBvbmVudHN9LWNvbXBvbmVudCBpcyBub3Qgc3VwcG9ydGVkLmApO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gYFxuICAgICAgICB2YXI8d29ya2dyb3VwPiBzdWJfYTogYXJyYXk8JHthLnR5cGUudmFsdWV9LCAke2FMZW5ndGhQZXJUaWxlfT47XG4gICAgICAgIHZhcjx3b3JrZ3JvdXA+IGludGVyX3Jlc3VsdHM6IGFycmF5PGFycmF5PCR7b3V0cHV0LnR5cGUudmFsdWV9LCAke3dvcmtncm91cFh9PiwgJHt3b3JrZ3JvdXBZfT47XG4gICAgICAgICR7c2hhZGVySGVscGVyLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJpYWJsZXMsIG91dHB1dCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydChbd29ya2dyb3VwWCwgd29ya2dyb3VwWSwgMV0pfVxuICAgICAgICAgIGxldCBvdXRwdXRfaW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcyhgd29ya2dyb3VwX2luZGV4ICogJHt3b3JrZ3JvdXBZfWApfTtcbiAgICAgICAgICBsZXQgY29sID0gb3V0cHV0X2luZGljZXNbMl07XG4gICAgICAgICAgbGV0IHJvdyA9IG91dHB1dF9pbmRpY2VzWzFdO1xuICAgICAgICAgIGxldCBiYXRjaCA9IG91dHB1dF9pbmRpY2VzWzBdO1xuICAgICAgICAgIGxldCBuX2Jsb2Nrc19wZXJfY29sID0gdW5pZm9ybXMuYl9zaGFwZVsxXTtcbiAgICAgICAgICBsZXQgbnVtX3RpbGVzID0gIChuX2Jsb2Nrc19wZXJfY29sIC0gMSkgLyAke2Jsb2Nrc1BlclRpbGV9ICsgMTtcblxuICAgICAgICAgIC8vIExvb3Agb3ZlciBzaGFyZWQgZGltZW5zaW9uLlxuICAgICAgICAgIGZvciAodmFyIHRpbGU6IHUzMiA9IDA7IHRpbGUgPCBudW1fdGlsZXM7IHRpbGUgKz0gMSkge1xuICAgICAgICAgICAgbGV0IGFfY29sX3N0YXJ0ID0gdGlsZSAqICR7YUxlbmd0aFBlclRpbGV9O1xuICAgICAgICAgICAgLy8gbG9hZCBvbmUgdGlsZSBBIGRhdGEgaW50byBzaGFyZWQgbWVtb3J5LlxuICAgICAgICAgICAgZm9yICh2YXIgYV9vZmZzZXQgPSBsb2NhbF9pZHg7IGFfb2Zmc2V0IDwgJHthTGVuZ3RoUGVyVGlsZX07IGFfb2Zmc2V0ICs9ICR7d29ya2dyb3VwU2l6ZX0pXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGxldCBhX2NvbCA9IGFfY29sX3N0YXJ0ICsgYV9vZmZzZXQ7XG4gICAgICAgICAgICAgIGlmIChhX2NvbCA8IHVuaWZvcm1zLmFfc2hhcGVbMl0pXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBzdWJfYVthX29mZnNldF0gPSAke2EuZ2V0QnlJbmRpY2VzKGAke2EudHlwZS5pbmRpY2VzfShiYXRjaCwgcm93LCBhX2NvbClgKX07XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3ViX2FbYV9vZmZzZXRdID0gJHthLnR5cGUudmFsdWV9KDApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICAgICAgICAgIC8vIGVhY2ggdGhyZWFkIHByb2Nlc3Mgb25lIGJsb2NrXG4gICAgICAgICAgICBsZXQgYl9yb3cgPSBjb2wgKyBsb2NhbF9pZC55O1xuICAgICAgICAgICAgbGV0IGJsb2NrID0gdGlsZSAqICR7YmxvY2tzUGVyVGlsZX0gKyBsb2NhbF9pZC54O1xuICAgICAgICAgICAgJHtcbiAgICAgICAgICAgICAgemVyb1BvaW50c1xuICAgICAgICAgICAgICAgID8gYFxuICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfdmFsdWVzX3Blcl9ieXRlOiB1MzIgPSAke01hdGguZmxvb3IoOCAvIGF0dHJpYnV0ZXMuYml0cyl9dTtcbiAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X2J5dGVzX3Blcl9jb2wgPSAobl9ibG9ja3NfcGVyX2NvbCArIHplcm9fcG9pbnRfdmFsdWVzX3Blcl9ieXRlIC0gMXUpIC8gemVyb19wb2ludF92YWx1ZXNfcGVyX2J5dGU7XG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF9ieXRlX2NvdW50ID0gYl9yb3cgKiB6ZXJvX3BvaW50X2J5dGVzX3Blcl9jb2wgKyAoYmxvY2sgLyB6ZXJvX3BvaW50X3ZhbHVlc19wZXJfYnl0ZSk7XG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF93b3JkX2luZGV4ID0gemVyb19wb2ludF9ieXRlX2NvdW50ID4+IDB4MnU7XG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF9ieXRlX29mZnNldCA9IHplcm9fcG9pbnRfYnl0ZV9jb3VudCAmIDB4M3U7XG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF9zdWJfb2Zmc2V0OiB1MzIgPSBibG9jayAlIHplcm9fcG9pbnRfdmFsdWVzX3Blcl9ieXRlO1xuICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfYml0c19vZmZzZXQgPSAoemVyb19wb2ludF9ieXRlX29mZnNldCA8PCAzKSArICh6ZXJvX3BvaW50X3N1Yl9vZmZzZXQgKiAke2F0dHJpYnV0ZXMuYml0c311KTtcbiAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X3dvcmQgPSAke3plcm9Qb2ludHMuZ2V0QnlPZmZzZXQoJ3plcm9fcG9pbnRfd29yZF9pbmRleCcpfSA+PiB6ZXJvX3BvaW50X2JpdHNfb2Zmc2V0O1xuICAgICAgICAgICAgbGV0IHplcm9fcG9pbnQgPSAke2RhdGFUeXBlfSgoemVyb19wb2ludF93b3JkKSAmICR7YXR0cmlidXRlcy5iaXRzID09PSAyID8gJzB4M3UnIDogJzB4RnUnfSk7YFxuICAgICAgICAgICAgICAgIDogYFxuICAgICAgICAgICAgLy8gVGhlIGRlZmF1bHQgemVybyBwb2ludCBpcyAke01hdGgucG93KDIsIGF0dHJpYnV0ZXMuYml0cyAtIDEpfSBmb3IgdW5zaWduZWQgJHthdHRyaWJ1dGVzLmJpdHN9LWJpdCBxdWFudGl6YXRpb24uXG4gICAgICAgICAgICBsZXQgemVyb19wb2ludCA9ICR7ZGF0YVR5cGV9KCR7TWF0aC5wb3coMiwgYXR0cmlidXRlcy5iaXRzIC0gMSkudG9GaXhlZCgxKX0pO2BcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBzY2FsZSA9ICR7c2NhbGVzLmdldEJ5T2Zmc2V0KGBiX3JvdyAqIG5fYmxvY2tzX3Blcl9jb2wgKyBibG9ja2ApfTtcbiAgICAgICAgICAgIGxldCBiX2RhdGEgPSAke2IuZ2V0QnlJbmRpY2VzKGAke2IudHlwZS5pbmRpY2VzfShiX3JvdywgYmxvY2ssIDApYCl9O1xuICAgICAgICAgICAgdmFyIHdvcmRfb2Zmc2V0ID0gbG9jYWxfaWQueCAqICR7YXR0cmlidXRlcy5ibG9ja1NpemUgLyBhQ29tcG9uZW50c307XG4gICAgICAgICAgICBmb3IgKHZhciBpOiB1MzIgPSAwOyBpIDwgJHtiQ29tcG9uZW50c307IGkrKykge1xuICAgICAgICAgICAgICBsZXQgYl92YWx1ZSA9ICR7YkNvbXBvbmVudHMgPT09IDEgPyBgYl9kYXRhYCA6IGBiX2RhdGFbaV1gfTtcbiAgICAgICAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhc3Nlc1BlcldvcmRCczMyID0gTWF0aC5mbG9vcih2YWx1ZXNQZXJXb3JkQnMzMiAvIDgpO1xuICAgICAgICAgICAgICAgIGxldCBjb2RlID0gJyc7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgcGFzcyA9IDA7IHBhc3MgPCBwYXNzZXNQZXJXb3JkQnMzMjsgcGFzcysrKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBsb3dlclNoaWZ0ID0gcGFzcyAqIGF0dHJpYnV0ZXMuYml0cyAqIDQ7XG4gICAgICAgICAgICAgICAgICBjb25zdCB1cHBlclNoaWZ0ID0gbG93ZXJTaGlmdCArIGF0dHJpYnV0ZXMuYml0cztcbiAgICAgICAgICAgICAgICAgIGNvZGUgKz0gYFxuICAgICAgICAgICAgICAke3JlYWRBKCl9XG4gICAgICAgICAgICAgIHske1xuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuYml0cyA9PT0gMlxuICAgICAgICAgICAgICAgICAgPyBgXG4gICAgICAgICAgICAgICAgbGV0IGhhbGZfd29yZCA9IGJfdmFsdWUgPj4gJHtwYXNzICogMTZ9dTtcbiAgICAgICAgICAgICAgICBsZXQgYnl0ZV9sbyA9IGhhbGZfd29yZCAmIDB4RkZ1O1xuICAgICAgICAgICAgICAgIGxldCBieXRlX2hpID0gKGhhbGZfd29yZCA+PiA4dSkgJiAweEZGdTtcbiAgICAgICAgICAgICAgICBsZXQgc3ByZWFkX3dvcmQgPSAoYnl0ZV9sbyAmIDB4RnUpIHwgKChieXRlX2xvID4+IDR1KSA8PCA4dSkgfCAoKGJ5dGVfaGkgJiAweEZ1KSA8PCAxNnUpIHwgKChieXRlX2hpID4+IDR1KSA8PCAyNHUpO1xuICAgICAgICAgICAgICAgIGxldCBiX3ZhbHVlX2xvd2VyID0gdW5wYWNrNHhVOChzcHJlYWRfd29yZCAmIDB4MDMwMzAzMDN1KTtcbiAgICAgICAgICAgICAgICBsZXQgYl92YWx1ZV91cHBlciA9IHVucGFjazR4VTgoKHNwcmVhZF93b3JkID4+IDJ1KSAmIDB4MDMwMzAzMDN1KTtgXG4gICAgICAgICAgICAgICAgICA6IGBcbiAgICAgICAgICAgICAgICBsZXQgYl92YWx1ZV9sb3dlciA9IHVucGFjazR4VTgoKGJfdmFsdWUgPj4gJHtsb3dlclNoaWZ0fXUpICYgMHgwRjBGMEYwRnUpO1xuICAgICAgICAgICAgICAgIGxldCBiX3ZhbHVlX3VwcGVyID0gdW5wYWNrNHhVOCgoYl92YWx1ZSA+PiAke3VwcGVyU2hpZnR9dSkgJiAweDBGMEYwRjBGdSk7YFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IGJfcXVhbnRpemVkX3ZhbHVlcyA9IG1hdDJ4NDwke2RhdGFUeXBlfT4oJHtBcnJheS5mcm9tKFxuICAgICAgICAgICAgICAgICAgeyBsZW5ndGg6IDQgfSxcbiAgICAgICAgICAgICAgICAgIChfLCBpKSA9PiBgJHtkYXRhVHlwZX0oYl92YWx1ZV9sb3dlclske2l9XSksICR7ZGF0YVR5cGV9KGJfdmFsdWVfdXBwZXJbJHtpfV0pYCxcbiAgICAgICAgICAgICAgICApLmpvaW4oJywgJyl9KTtcbiAgICAgICAgICAgICAgICBsZXQgYl9kZXF1YW50aXplZF92YWx1ZXMgPSAoYl9xdWFudGl6ZWRfdmFsdWVzIC0gbWF0Mng0PCR7ZGF0YVR5cGV9Pigke0FycmF5KDgpLmZpbGwoJ3plcm9fcG9pbnQnKS5qb2luKCcsJyl9KSkgKiBzY2FsZTtcbiAgICAgICAgICAgICAgICBpbnRlcl9yZXN1bHRzW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdICs9ICR7QXJyYXkuZnJvbShcbiAgICAgICAgICAgICAgICAgIHsgbGVuZ3RoOiAyIH0sXG4gICAgICAgICAgICAgICAgICAoXywgaSkgPT4gYCR7YGRvdChhX2RhdGEke2l9LCBiX2RlcXVhbnRpemVkX3ZhbHVlc1ske2l9XSlgfWAsXG4gICAgICAgICAgICAgICAgKS5qb2luKCcgKyAnKX07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgd29yZF9vZmZzZXQgKz0gJHs4IC8gYUNvbXBvbmVudHN9O2A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjb2RlO1xuICAgICAgICAgICAgICB9KSgpfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgd29ya2dyb3VwQmFycmllcigpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChsb2NhbF9pZHggPCAke3dvcmtncm91cFl9KSB7XG4gICAgICAgICAgICB2YXIgb3V0cHV0X3ZhbHVlOiAke291dHB1dC50eXBlLnZhbHVlfSA9ICR7b3V0cHV0LnR5cGUudmFsdWV9KDApO1xuICAgICAgICAgICAgZm9yICh2YXIgYiA9IDB1OyBiIDwgJHt3b3JrZ3JvdXBYfTsgYisrKSB7XG4gICAgICAgICAgICAgIG91dHB1dF92YWx1ZSArPSBpbnRlcl9yZXN1bHRzW2xvY2FsX2lkeF1bYl07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY29sICsgbG9jYWxfaWR4IDwgdW5pZm9ybXMub3V0cHV0X3NoYXBlWzJdKVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAke291dHB1dC5zZXRCeUluZGljZXMoYCR7b3V0cHV0LnR5cGUuaW5kaWNlc30oYmF0Y2gsIHJvdywgY29sICsgbG9jYWxfaWR4KWAsICdvdXRwdXRfdmFsdWUnKX1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1gO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdCbG9ja3dpc2VNYXRNdWxOQml0czMyJyxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogYCR7YXR0cmlidXRlcy5ibG9ja1NpemV9OyR7YUNvbXBvbmVudHN9OyR7YkNvbXBvbmVudHN9OyR7d29ya2dyb3VwWH07JHt3b3JrZ3JvdXBZfWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llczogQXJyYXkoaW5wdXRzLmxlbmd0aCkuZmlsbCgncmFuaycpLFxuICAgIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogZGlzcGF0Y2hTaXplIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IG1hdE11bE5CaXRzID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBNYXRNdWxOQml0c0F0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBpZiAoXG4gICAgYXR0cmlidXRlcy5ibG9ja1NpemUgPT09IDMyICYmXG4gICAgY29udGV4dC5hZGFwdGVySW5mby5pc1ZlbmRvcignaW50ZWwnKSAmJlxuICAgIGNvbnRleHQuYWRhcHRlckluZm8uaXNBcmNoaXRlY3R1cmUoJ2dlbi0xMmxwJylcbiAgKSB7XG4gICAgY29udGV4dC5jb21wdXRlKGNyZWF0ZU1hdE11bE5CaXRzQmxvY2tTaXplMzJQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcykpO1xuICB9IGVsc2Uge1xuICAgIGNvbnRleHQuY29tcHV0ZShjcmVhdGVNYXRNdWxOQml0c1Byb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKSk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZU1hdE11bE5CaXRzQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IE1hdE11bE5CaXRzQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoYXR0cmlidXRlcyBhcyBPbWl0PE1hdE11bE5CaXRzQXR0cmlidXRlcywga2V5b2YgQXR0cmlidXRlV2l0aENhY2hlS2V5Pik7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvLCBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeSwgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLFxuICBnZXRFbGVtZW50QXQsXG4gIEluZGljZXNIZWxwZXIsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIFVuaWZvcm1EYXRhRWxlbWVudFR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmludGVyZmFjZSBQYWRBdHRyaWJ1dGVzIHtcbiAgLy8gMC1jb25zdGFudCwgMS1yZWZsZWN0LCAyLWVkZ2UsIDMtd3JhcFxuICByZWFkb25seSBtb2RlOiBudW1iZXI7XG4gIHJlYWRvbmx5IHZhbHVlOiBudW1iZXI7XG4gIHJlYWRvbmx5IHBhZHM6IG51bWJlcltdO1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoIDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVG9vIGZldyBpbnB1dHMnKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLmRhdGFUeXBlICE9PSBEYXRhVHlwZS5mbG9hdCAmJiBpbnB1dHNbMF0uZGF0YVR5cGUgIT09IERhdGFUeXBlLmZsb2F0MTYpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHR5cGUgbXVzdCBiZSBmbG9hdCBvciBmbG9hdDE2LicpO1xuICB9XG5cbiAgaWYgKGlucHV0cy5sZW5ndGggPj0gMikge1xuICAgIGxldCB2YWxpZFBhZHMgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggKiAyID09PSBpbnB1dHNbMV0uZGltc1swXTtcbiAgICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gNCkge1xuICAgICAgdmFsaWRQYWRzID0gaW5wdXRzWzNdLmRpbXNbMF0gKiAyID09PSBpbnB1dHNbMV0uZGltc1swXTtcbiAgICB9XG4gICAgaWYgKCF2YWxpZFBhZHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIHBhZHMgc2hvdWxkIGJlIGEgMUQgdGVuc29yIG9mIHNoYXBlIFsyICogaW5wdXRfcmFua10gb3IgWzIgKiBudW1fYXhlc10uJyk7XG4gICAgfVxuICB9XG59O1xuXG5jb25zdCBnZXRQYWRDb25zdGFudCA9IChvdXRwdXQ6IEluZGljZXNIZWxwZXIsIGlucHV0UmFuazogbnVtYmVyLCBwYWRzTGVuZ3RoOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICBsZXQgYmxvY2sgPSAnJztcbiAgZm9yIChsZXQgaSA9IGlucHV0UmFuayAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICAgICAgayA9IGkzMigke291dHB1dC5pbmRpY2VzR2V0KCdpbmRpY2VzJywgaSl9KSAtICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5wYWRzJywgaSwgcGFkc0xlbmd0aCl9O1xuICAgICAgICAgICAgaWYgKGsgPCAwKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGsgPj0gaTMyKCR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3NoYXBlJywgaSwgaW5wdXRSYW5rKX0pKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb2Zmc2V0ICs9IGsgKiBpMzIoJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc3RyaWRlcycsIGksIGlucHV0UmFuayl9KTtcbiAgICAgICAgYDtcbiAgfVxuXG4gIHJldHVybiBgXG4gICAgICAgICAgdmFsdWUgPSAke291dHB1dC50eXBlLnZhbHVlfSh1bmlmb3Jtcy5jb25zdGFudF92YWx1ZSk7XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBvZmZzZXQgPSAwO1xuICAgICAgICAgICAgdmFyIGsgPSAwO1xuICAgICAgICAgICAgJHtibG9ja31cbiAgICAgICAgICAgIHZhbHVlID0geFtvZmZzZXRdO1xuICAgICAgICAgIH1cbiAgICAgIGA7XG59O1xuXG5jb25zdCBnZXRQYWRSZWZsZWN0ID0gKG91dHB1dDogSW5kaWNlc0hlbHBlciwgaW5wdXRSYW5rOiBudW1iZXIsIHBhZHNMZW5ndGg6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gIGxldCBibG9jayA9ICcnO1xuICBmb3IgKGxldCBpID0gaW5wdXRSYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICBibG9jayArPSBgXG4gICAgICAgICAgICAgICAgayA9IGkzMigke291dHB1dC5pbmRpY2VzR2V0KCdpbmRpY2VzJywgaSl9KSAtICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5wYWRzJywgaSwgcGFkc0xlbmd0aCl9O1xuICAgICAgICAgICAgICAgIGlmIChrIDwgMCkge1xuICAgICAgICAgICAgICAgICAgayA9IC1rO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBsZXQgXzJuXzEgPSAyICogKGkzMigke2dldEVsZW1lbnRBdCgndW5pZm9ybXMueF9zaGFwZScsIGksIGlucHV0UmFuayl9KSAtIDEpO1xuICAgICAgICAgICAgICAgICAgayA9IGsgJSBfMm5fMTtcbiAgICAgICAgICAgICAgICAgIGlmKGsgPj0gaTMyKCR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3NoYXBlJywgaSwgaW5wdXRSYW5rKX0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGsgPSBfMm5fMSAtIGs7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9mZnNldCArPSBrICogaTMyKCR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3N0cmlkZXMnLCBpLCBpbnB1dFJhbmspfSk7XG4gICAgICAgICAgICBgO1xuICB9XG5cbiAgcmV0dXJuIGBcbiAgICAgICAgICAgICAgdmFyIG9mZnNldCA9IDA7XG4gICAgICAgICAgICAgIHZhciBrID0gMDtcbiAgICAgICAgICAgICAgJHtibG9ja31cbiAgICAgICAgICAgICAgdmFsdWUgPSB4W29mZnNldF07XG4gICAgICAgICAgYDtcbn07XG5cbmNvbnN0IGdldFBhZEVkZ2UgPSAob3V0cHV0OiBJbmRpY2VzSGVscGVyLCBpbnB1dFJhbms6IG51bWJlciwgcGFkc0xlbmd0aDogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgbGV0IGJsb2NrID0gJyc7XG4gIGZvciAobGV0IGkgPSBpbnB1dFJhbmsgLSAxOyBpID49IDA7IC0taSkge1xuICAgIGJsb2NrICs9IGBcbiAgICAgICAgICAgICAgICBrID0gaTMyKCR7b3V0cHV0LmluZGljZXNHZXQoJ2luZGljZXMnLCBpKX0pIC0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnBhZHMnLCBpLCBwYWRzTGVuZ3RoKX07XG4gICAgICAgICAgICAgICAgaWYgKGsgPCAwKSB7XG4gICAgICAgICAgICAgICAgICBrID0gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGsgPj0gaTMyKCR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3NoYXBlJywgaSwgaW5wdXRSYW5rKX0pKSB7XG4gICAgICAgICAgICAgICAgICBrID0gaTMyKCR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3NoYXBlJywgaSwgaW5wdXRSYW5rKX0pIC0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IGsgKiBpMzIoJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc3RyaWRlcycsIGksIGlucHV0UmFuayl9KTtcbiAgICAgICAgICAgIGA7XG4gIH1cblxuICByZXR1cm4gYFxuICAgICAgICAgICAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICAgICAgICAgICAgdmFyIGsgPSAwO1xuICAgICAgICAgICAgICAke2Jsb2NrfVxuICAgICAgICAgICAgICB2YWx1ZSA9IHhbb2Zmc2V0XTtcbiAgICAgICAgICBgO1xufTtcblxuY29uc3QgZ2V0UGFkV3JhcCA9IChvdXRwdXQ6IEluZGljZXNIZWxwZXIsIGlucHV0UmFuazogbnVtYmVyLCBwYWRzTGVuZ3RoOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICBsZXQgYmxvY2sgPSAnJztcbiAgZm9yIChsZXQgaSA9IGlucHV0UmFuayAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICAgICAgICAgIGsgPSBpMzIoJHtvdXRwdXQuaW5kaWNlc0dldCgnaW5kaWNlcycsIGkpfSkgLSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMucGFkcycsIGksIHBhZHNMZW5ndGgpfTtcbiAgICAgICAgICAgICAgICBpZiAoayA8IDApICB7XG4gICAgICAgICAgICAgICAgICBrICs9IGkzMigke2dldEVsZW1lbnRBdCgndW5pZm9ybXMueF9zaGFwZScsIGksIGlucHV0UmFuayl9XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChrID49IGkzMigke2dldEVsZW1lbnRBdCgndW5pZm9ybXMueF9zaGFwZScsIGksIGlucHV0UmFuayl9KSkge1xuICAgICAgICAgICAgICAgICAgayAtPSBpMzIoJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc2hhcGUnLCBpLCBpbnB1dFJhbmspfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9mZnNldCArPSBrICogaTMyKCR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3N0cmlkZXMnLCBpLCBpbnB1dFJhbmspfSk7XG4gICAgICAgICAgICBgO1xuICB9XG5cbiAgcmV0dXJuIGBcbiAgICAgICAgICAgICAgdmFyIG9mZnNldCA9IDA7XG4gICAgICAgICAgICAgIHZhciBrID0gMDtcbiAgICAgICAgICAgICAgJHtibG9ja31cbiAgICAgICAgICAgICAgdmFsdWUgPSB4W29mZnNldF07XG4gICAgICAgICAgYDtcbn07XG5cbmNvbnN0IGdldFBhZFNuaXBwZXQgPSAob3V0cHV0OiBJbmRpY2VzSGVscGVyLCBpbnB1dFJhbms6IG51bWJlciwgYXR0cmlidXRlczogUGFkQXR0cmlidXRlcyk6IHN0cmluZyA9PiB7XG4gIHN3aXRjaCAoYXR0cmlidXRlcy5tb2RlKSB7XG4gICAgY2FzZSAwOlxuICAgICAgcmV0dXJuIGdldFBhZENvbnN0YW50KG91dHB1dCwgaW5wdXRSYW5rLCBhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoKTtcbiAgICBjYXNlIDE6XG4gICAgICByZXR1cm4gZ2V0UGFkUmVmbGVjdChvdXRwdXQsIGlucHV0UmFuaywgYXR0cmlidXRlcy5wYWRzLmxlbmd0aCk7XG4gICAgY2FzZSAyOlxuICAgICAgcmV0dXJuIGdldFBhZEVkZ2Uob3V0cHV0LCBpbnB1dFJhbmssIGF0dHJpYnV0ZXMucGFkcy5sZW5ndGgpO1xuICAgIGNhc2UgMzpcbiAgICAgIHJldHVybiBnZXRQYWRXcmFwKG91dHB1dCwgaW5wdXRSYW5rLCBhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoKTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG1vZGUnKTtcbiAgfVxufTtcblxuY29uc3QgY3JlYXRlUGFkUHJvZ3JhbUluZm8gPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IFBhZEF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gU2hhcGVVdGlsLnBhZFNoYXBlKGlucHV0c1swXS5kaW1zLnNsaWNlKCksIGF0dHJpYnV0ZXMucGFkcyk7XG4gIGNvbnN0IGlucHV0RGltcyA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmludDMyLCBkYXRhOiBhdHRyaWJ1dGVzLnBhZHMgfSxcbiAgXTtcblxuICBjb25zdCBpc1ZhbHVlRnJvbUlucHV0ID0gaW5wdXRzLmxlbmd0aCA+PSAzICYmIGlucHV0c1syXS5kYXRhO1xuICBpZiAoYXR0cmlidXRlcy5tb2RlID09PSAwKSB7XG4gICAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goeyB0eXBlOiBpc1ZhbHVlRnJvbUlucHV0ID8gaW5wdXRzWzJdLmRhdGFUeXBlIDogRGF0YVR5cGUuZmxvYXQsIGRhdGE6IGF0dHJpYnV0ZXMudmFsdWUgfSk7XG4gIH1cblxuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMF0uZGltcywgb3V0cHV0U2hhcGUpKTtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3JhbmsnXTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgneCcsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXREaW1zLmxlbmd0aCk7XG4gICAgY29uc3QgZGF0YVR5cGUgPSBpbnB1dC50eXBlLnZhbHVlO1xuICAgIGNvbnN0IHBhZFNuaXBwZXQgPSBnZXRQYWRTbmlwcGV0KG91dHB1dCwgaW5wdXREaW1zLmxlbmd0aCwgYXR0cmlidXRlcyk7XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAncGFkcycsIHR5cGU6ICdpMzInLCBsZW5ndGg6IGF0dHJpYnV0ZXMucGFkcy5sZW5ndGggfSxcbiAgICBdO1xuICAgIGlmIChhdHRyaWJ1dGVzLm1vZGUgPT09IDApIHtcbiAgICAgIHVuaWZvcm1zLnB1c2goeyBuYW1lOiAnY29uc3RhbnRfdmFsdWUnLCB0eXBlOiAoaXNWYWx1ZUZyb21JbnB1dCA/IGRhdGFUeXBlIDogJ2YzMicpIGFzIFVuaWZvcm1EYXRhRWxlbWVudFR5cGUgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGBcbiAgICAgICAgICAgICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIG91dHB1dCl9XG4gICAgICAgICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAgICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG5cbiAgICAgICAgICAgIGxldCBpbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuXG4gICAgICAgICAgICB2YXIgdmFsdWUgPSAke2RhdGFUeXBlfSgwKTtcbiAgICAgICAgICAgICR7cGFkU25pcHBldH1cbiAgICAgICAgICAgIG91dHB1dFtnbG9iYWxfaWR4XSA9IHZhbHVlO1xuICAgICAgICB9YDtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdQYWQnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke2F0dHJpYnV0ZXMubW9kZX0ke2lzVmFsdWVGcm9tSW5wdXR9YCwgaW5wdXREZXBlbmRlbmNpZXMgfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSkgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVQYWRBdHRyaWJ1dGVzRnJvbUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogUGFkQXR0cmlidXRlcyk6IFBhZEF0dHJpYnV0ZXMgPT4ge1xuICBpZiAoaW5wdXRzLmxlbmd0aCA+IDEpIHtcbiAgICBjb25zdCBiaWdJbnQ2NFBhZHMgPSBpbnB1dHNbMV0uZ2V0QmlnSW50NjRBcnJheSgpO1xuICAgIGNvbnN0IHZhbHVlID1cbiAgICAgIGlucHV0cy5sZW5ndGggPj0gMyAmJiBpbnB1dHNbMl0uZGF0YVxuICAgICAgICA/IGlucHV0c1syXS5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuZmxvYXQxNlxuICAgICAgICAgID8gaW5wdXRzWzJdLmdldFVpbnQxNkFycmF5KClbMF1cbiAgICAgICAgICA6IGlucHV0c1syXS5nZXRGbG9hdDMyQXJyYXkoKVswXVxuICAgICAgICA6IDAuMDtcblxuICAgIGNvbnN0IGlucHV0UmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgICBjb25zdCB1cGRhdGVQYWRzID0gbmV3IEludDMyQXJyYXkoMiAqIGlucHV0UmFuaykuZmlsbCgwKTtcbiAgICBpZiAoaW5wdXRzLmxlbmd0aCA+PSA0KSB7XG4gICAgICBjb25zdCBheGVzID0gaW5wdXRzWzNdLmdldEJpZ0ludDY0QXJyYXkoKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXhlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB1cGRhdGVQYWRzW051bWJlcihheGVzW2ldKV0gPSBOdW1iZXIoYmlnSW50NjRQYWRzW2ldKTtcbiAgICAgICAgdXBkYXRlUGFkc1tOdW1iZXIoYXhlc1tpXSkgKyBpbnB1dFJhbmtdID0gTnVtYmVyKGJpZ0ludDY0UGFkc1tpICsgYXhlcy5sZW5ndGhdKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYmlnSW50NjRQYWRzLmZvckVhY2goKHYsIGkpID0+ICh1cGRhdGVQYWRzW051bWJlcihpKV0gPSBOdW1iZXIodikpKTtcbiAgICB9XG5cbiAgICBjb25zdCBwYWRzOiBudW1iZXJbXSA9IFtdO1xuICAgIHVwZGF0ZVBhZHMuZm9yRWFjaCgodikgPT4gcGFkcy5wdXNoKHYpKTtcblxuICAgIHJldHVybiB7IG1vZGU6IGF0dHJpYnV0ZXMubW9kZSwgdmFsdWUsIHBhZHMgfTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHBhZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUGFkQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnN0IHVwZGF0ZWRBdHRyaWJ1dGVzID0gY3JlYXRlUGFkQXR0cmlidXRlc0Zyb21JbnB1dHMoY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlUGFkUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIHVwZGF0ZWRBdHRyaWJ1dGVzKSwgeyBpbnB1dHM6IFswXSB9KTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFBvb2xDb252VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvLCBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeSwgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLFxuICBnZXRFbGVtZW50QXQsXG4gIEluZGljZXNIZWxwZXIsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbi8vIFRPRE86IHN1cHBvcnQ6XG4vLyAtIGNlaWxfbW9kZSAgICAgICAgICAgICAgICAgXCJ0ZXN0X21heHBvb2xfMmRfY2VpbFwiXG4vLyAtIHN0b3JhZ2Vfb3JkZXIgICAgICAgICAgICAgXCJ0ZXN0X21heHBvb2xfd2l0aF9hcmdtYXhfMmRfcHJlY29tcHV0ZWRfc3RyaWRlc1wiXG4vLyAtIFtNYXhQb29sXSBkaWxhdGlvbnMgICAgICAgXCJ0ZXN0X21heHBvb2xfMmRfZGlsYXRpb25zXCJcbi8vIC0gW01heFBvb2xdIG91dHB1dFsxXSAgICAgICBcInRlc3RfbWF4cG9vbF93aXRoX2FyZ21heF8yZF9wcmVjb21wdXRlZF9wYWRzXCJcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pOiB2b2lkID0+IHtcbiAgaWYgKGVudi53ZWJncHUudmFsaWRhdGVJbnB1dENvbnRlbnQgJiYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Bvb2wgb3BzIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cbn07XG5cbmNvbnN0IGdldEFkanVzdGVkUG9vbEF0dHJpYnV0ZXNBbmRPdXRwdXRTaGFwZSA9IDxBdHRyaWJ1dGVUeXBlIGV4dGVuZHMgQXZlcmFnZVBvb2xBdHRyaWJ1dGVzIHwgTWF4UG9vbEF0dHJpYnV0ZXM+KFxuICBpbnB1dDogVGVuc29yVmlldyxcbiAgYXR0cmlidXRlczogQXR0cmlidXRlVHlwZSxcbiAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbik6IFtBdHRyaWJ1dGVUeXBlLCBudW1iZXJbXV0gPT4ge1xuICBjb25zdCBpc0NoYW5uZWxzTGFzdCA9IGF0dHJpYnV0ZXMuZm9ybWF0ID09PSAnTkhXQyc7XG4gIGNvbnN0IGlucHV0U2hhcGVBc0NoYW5uZWxGaXJzdCA9IGlucHV0LmRpbXMuc2xpY2UoKTtcbiAgaWYgKGlzQ2hhbm5lbHNMYXN0KSB7XG4gICAgaW5wdXRTaGFwZUFzQ2hhbm5lbEZpcnN0LnNwbGljZSgxLCAwLCBpbnB1dFNoYXBlQXNDaGFubmVsRmlyc3QucG9wKCkhKTsgLy8gTW92ZSBjaGFubmVsIHRvIHRoZSBzZWNvbmQgcG9zaXRpb24uXG4gIH1cbiAgY29uc3QgaGFzRGlsYXRpb25zID0gT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cmlidXRlcywgJ2RpbGF0aW9ucycpO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGUuc2xpY2UoKTtcbiAgY29uc3Qgc3RyaWRlcyA9IGF0dHJpYnV0ZXMuc3RyaWRlcy5zbGljZSgpO1xuICBjb25zdCBkaWxhdGlvbnM6IG51bWJlcltdID0gaGFzRGlsYXRpb25zID8gKGF0dHJpYnV0ZXMgYXMgTWF4UG9vbEF0dHJpYnV0ZXMpLmRpbGF0aW9ucy5zbGljZSgpIDogW107XG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLnBhZHMuc2xpY2UoKTtcbiAgUG9vbENvbnZVdGlsLmFkanVzdFBvb2xBdHRyaWJ1dGVzKGlzR2xvYmFsT3BlcmF0b3IsIGlucHV0U2hhcGVBc0NoYW5uZWxGaXJzdCwga2VybmVsU2hhcGUsIHN0cmlkZXMsIGRpbGF0aW9ucywgcGFkcyk7XG5cbiAgY29uc3Qgb3V0cHV0U2hhcGVBc0NoYW5uZWxGaXJzdCA9IFBvb2xDb252VXRpbC5jb21wdXRlUG9vbE91dHB1dFNoYXBlKFxuICAgIGlzR2xvYmFsT3BlcmF0b3IsXG4gICAgaW5wdXRTaGFwZUFzQ2hhbm5lbEZpcnN0LFxuICAgIHN0cmlkZXMsXG4gICAgZGlsYXRpb25zLFxuICAgIGtlcm5lbFNoYXBlLFxuICAgIHBhZHMsXG4gICAgYXR0cmlidXRlcy5hdXRvUGFkLFxuICApO1xuXG4gIGNvbnN0IG5ld0F0dHJpYnV0ZXMgPSBPYmplY3QuYXNzaWduKHt9LCBhdHRyaWJ1dGVzKTtcbiAgaWYgKGhhc0RpbGF0aW9ucykge1xuICAgIE9iamVjdC5hc3NpZ24obmV3QXR0cmlidXRlcywgeyBrZXJuZWxTaGFwZSwgc3RyaWRlcywgcGFkcywgZGlsYXRpb25zLCBjYWNoZUtleTogYXR0cmlidXRlcy5jYWNoZUtleSB9KTtcbiAgfSBlbHNlIHtcbiAgICBPYmplY3QuYXNzaWduKG5ld0F0dHJpYnV0ZXMsIHsga2VybmVsU2hhcGUsIHN0cmlkZXMsIHBhZHMsIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH0pO1xuICB9XG4gIGNvbnN0IG91dHB1dFNoYXBlQXNDaGFubmVsTGFzdCA9IG91dHB1dFNoYXBlQXNDaGFubmVsRmlyc3Quc2xpY2UoKTtcbiAgb3V0cHV0U2hhcGVBc0NoYW5uZWxMYXN0LnB1c2gob3V0cHV0U2hhcGVBc0NoYW5uZWxMYXN0LnNwbGljZSgxLCAxKVswXSk7XG4gIHJldHVybiBbbmV3QXR0cmlidXRlcywgaXNDaGFubmVsc0xhc3QgPyBvdXRwdXRTaGFwZUFzQ2hhbm5lbExhc3QgOiBvdXRwdXRTaGFwZUFzQ2hhbm5lbEZpcnN0XTtcbn07XG5cbmNvbnN0IGdldFVuaWZvcm1BbmRQYWRJbmZvID0gPEF0dHJpYnV0ZVR5cGUgZXh0ZW5kcyBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgfCBNYXhQb29sQXR0cmlidXRlcz4oXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogQXR0cmlidXRlVHlwZSxcbik6IFtQcm9ncmFtVW5pZm9ybVtdLCBVbmlmb3Jtc0FycmF5VHlwZSwgYm9vbGVhbiwgYm9vbGVhbiwgYm9vbGVhbl0gPT4ge1xuICBjb25zdCBpc0NoYW5uZWxzTGFzdCA9IGF0dHJpYnV0ZXMuZm9ybWF0ID09PSAnTkhXQyc7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gIGNvbnN0IGtlcm5lbFNpemUgPSBTaGFwZVV0aWwuc2l6ZShhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlKTtcbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGtlcm5lbFNpemUgfSxcbiAgXTtcbiAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgIHsgbmFtZTogJ291dHB1dFNpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgIHsgbmFtZTogJ2tlcm5lbFNpemUnLCB0eXBlOiAndTMyJyB9LFxuICBdO1xuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPD0gMikge1xuICAgIGNvbnN0IGt3ID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZVthdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAtIDFdO1xuICAgIGNvbnN0IHN3ID0gYXR0cmlidXRlcy5zdHJpZGVzW2F0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggLSAxXTtcbiAgICBjb25zdCBwd1N0YXJ0ID0gYXR0cmlidXRlcy5wYWRzW2F0dHJpYnV0ZXMucGFkcy5sZW5ndGggLyAyIC0gMV07XG4gICAgY29uc3QgcHdFbmQgPSBhdHRyaWJ1dGVzLnBhZHNbYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAtIDFdO1xuICAgIGNvbnN0IHB3U3RhcnRFbmROb3RaZXJvID0gISEocHdTdGFydCArIHB3RW5kKTtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaChcbiAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBrdyB9LFxuICAgICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHN3IH0sXG4gICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcHdTdGFydCB9LFxuICAgICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHB3RW5kIH0sXG4gICAgKTtcbiAgICB1bmlmb3Jtcy5wdXNoKFxuICAgICAgeyBuYW1lOiAna3cnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnc3cnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAncHdTdGFydCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdwd0VuZCcsIHR5cGU6ICd1MzInIH0sXG4gICAgKTtcblxuICAgIGxldCBwaFN0YXJ0RW5kTm90WmVybyA9IGZhbHNlO1xuICAgIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA9PT0gMikge1xuICAgICAgY29uc3Qga2ggPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlW2F0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoIC0gMl07XG4gICAgICBjb25zdCBzaCA9IGF0dHJpYnV0ZXMuc3RyaWRlc1thdHRyaWJ1dGVzLnN0cmlkZXMubGVuZ3RoIC0gMl07XG4gICAgICBjb25zdCBwaFN0YXJ0ID0gYXR0cmlidXRlcy5wYWRzW2F0dHJpYnV0ZXMucGFkcy5sZW5ndGggLyAyIC0gMl07XG4gICAgICBjb25zdCBwaEVuZCA9IGF0dHJpYnV0ZXMucGFkc1thdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIC0gMl07XG4gICAgICBwaFN0YXJ0RW5kTm90WmVybyA9ICEhKHBoU3RhcnQgKyBwaEVuZCk7XG4gICAgICBwcm9ncmFtVW5pZm9ybXMucHVzaChcbiAgICAgICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGtoIH0sXG4gICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBzaCB9LFxuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGhTdGFydCB9LFxuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGhFbmQgfSxcbiAgICAgICk7XG5cbiAgICAgIHVuaWZvcm1zLnB1c2goXG4gICAgICAgIHsgbmFtZTogJ2toJywgdHlwZTogJ3UzMicgfSxcbiAgICAgICAgeyBuYW1lOiAnc2gnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgICB7IG5hbWU6ICdwaFN0YXJ0JywgdHlwZTogJ3UzMicgfSxcbiAgICAgICAgeyBuYW1lOiAncGhFbmQnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIFtwcm9ncmFtVW5pZm9ybXMsIHVuaWZvcm1zLCB0cnVlLCBwd1N0YXJ0RW5kTm90WmVybywgcGhTdGFydEVuZE5vdFplcm9dO1xuICB9IGVsc2Uge1xuICAgIGlmIChpc0NoYW5uZWxzTGFzdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQb29saW5nIHdpdGgga2VybmVsU2hhcGUubGVuZ3RoID4gMiBpcyBub3Qgc3VwcG9ydGVkIGZvciBOSFdDIGZvcm1hdC4nKTtcbiAgICB9XG4gICAgY29uc3Qga2VybmVsU3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlKTtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaChcbiAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBrZXJuZWxTdHJpZGVzIH0sXG4gICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYXR0cmlidXRlcy5wYWRzIH0sXG4gICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYXR0cmlidXRlcy5zdHJpZGVzIH0sXG4gICAgKTtcbiAgICB1bmlmb3Jtcy5wdXNoKFxuICAgICAgeyBuYW1lOiAna2VybmVsU3RyaWRlcycsIHR5cGU6ICd1MzInLCBsZW5ndGg6IGtlcm5lbFN0cmlkZXMubGVuZ3RoIH0sXG4gICAgICB7IG5hbWU6ICdwYWRzJywgdHlwZTogJ3UzMicsIGxlbmd0aDogYXR0cmlidXRlcy5wYWRzLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAnc3RyaWRlcycsIHR5cGU6ICd1MzInLCBsZW5ndGg6IGF0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggfSxcbiAgICApO1xuXG4gICAgY29uc3QgaGFzUGFkcyA9IGF0dHJpYnV0ZXMucGFkcy5yZWR1Y2UoKHN1bSwgY3VyKSA9PiBzdW0gKyBjdXIpO1xuICAgIHJldHVybiBbcHJvZ3JhbVVuaWZvcm1zLCB1bmlmb3JtcywgISFoYXNQYWRzLCBmYWxzZSwgZmFsc2VdO1xuICB9XG59O1xuXG5jb25zdCBnZW5lcmF0ZVBvb2xpbmdDb2RlID0gPEF0dHJpYnV0ZVR5cGUgZXh0ZW5kcyBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgfCBNYXhQb29sQXR0cmlidXRlcz4oXG4gIHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyLFxuICB4OiBJbmRpY2VzSGVscGVyLFxuICByYW5rOiBudW1iZXIsXG4gIG91dHB1dFNoYXBlUmFuazogbnVtYmVyLFxuICBhdHRyaWJ1dGVzOiBBdHRyaWJ1dGVUeXBlLFxuICBvcDE6IHN0cmluZyxcbiAgb3AyOiBzdHJpbmcsXG4gIHN0YXJ0OiBudW1iZXIsXG4gIHVuaWZvcm1zOiBVbmlmb3Jtc0FycmF5VHlwZSxcbiAgaGFzUGFkczogYm9vbGVhbixcbiAgcHdTdGFydEVuZE5vdFplcm86IGJvb2xlYW4sXG4gIHBoU3RhcnRFbmROb3RaZXJvOiBib29sZWFuLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgaXNDaGFubmVsc0xhc3QgPSBhdHRyaWJ1dGVzLmZvcm1hdCA9PT0gJ05IV0MnO1xuICBjb25zdCBkYXRhVHlwZSA9IHgudHlwZS52YWx1ZTtcbiAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIHgudHlwZS50ZW5zb3IsIG91dHB1dFNoYXBlUmFuayk7XG5cbiAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoIDw9IDIpIHtcbiAgICBsZXQgY29kZVcgPSAnJztcbiAgICBsZXQgY29kZUggPSAnJztcbiAgICBsZXQgY29kZUhFbmQgPSAnJztcbiAgICBjb25zdCBkaW1JZHhXID0gcmFuayAtIChpc0NoYW5uZWxzTGFzdCA/IDIgOiAxKTtcbiAgICBpZiAocHdTdGFydEVuZE5vdFplcm8pIHtcbiAgICAgIGNvZGVXID0gYFxuICAgICAgICAgICAgICAgIGZvciAodmFyIGk6IHUzMiA9IDB1OyBpIDwgdW5pZm9ybXMua3c7IGkrKykge1xuICAgICAgICAgICAgICAgICAgeEluZGljZXNbJHtkaW1JZHhXfV0gPSBpbmRpY2VzWyR7ZGltSWR4V31dICogdW5pZm9ybXMuc3cgLSB1bmlmb3Jtcy5wd1N0YXJ0ICsgaTtcbiAgICAgICAgICAgICAgICAgIGlmICh4SW5kaWNlc1ske2RpbUlkeFd9XSA8IDAgfHwgeEluZGljZXNbJHtkaW1JZHhXfV1cbiAgICAgICAgICAgICAgICAgICAgICA+PSB1bmlmb3Jtcy54X3NoYXBlWyR7ZGltSWR4V31dKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhZCsrO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGxldCB4X3ZhbCA9IHhbJHt4LmluZGljZXNUb09mZnNldCgneEluZGljZXMnKX1dO1xuICAgICAgICAgICAgICAgICAgJHtvcDF9XG4gICAgICAgICAgICAgICAgfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVXID0gYFxuICAgICAgICAgICAgICAgIGZvciAodmFyIGk6IHUzMiA9IDB1OyBpIDwgdW5pZm9ybXMua3c7IGkrKykge1xuICAgICAgICAgICAgICAgICAgeEluZGljZXNbJHtkaW1JZHhXfV0gPSBpbmRpY2VzWyR7ZGltSWR4V31dICogdW5pZm9ybXMuc3cgLSB1bmlmb3Jtcy5wd1N0YXJ0ICsgaTtcbiAgICAgICAgICAgICAgICAgIGxldCB4X3ZhbCA9IHhbJHt4LmluZGljZXNUb09mZnNldCgneEluZGljZXMnKX1dO1xuICAgICAgICAgICAgICAgICAgJHtvcDF9XG4gICAgICAgICAgICAgICAgfWA7XG4gICAgfVxuXG4gICAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoID09PSAyKSB7XG4gICAgICBjb25zdCBkaW1JZHhIID0gcmFuayAtIChpc0NoYW5uZWxzTGFzdCA/IDMgOiAyKTtcbiAgICAgIGlmIChwaFN0YXJ0RW5kTm90WmVybykge1xuICAgICAgICBjb2RlSCA9IGBcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqOiB1MzIgPSAwdTsgaiA8IHVuaWZvcm1zLmtoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgIHhJbmRpY2VzWyR7ZGltSWR4SH1dID0gaW5kaWNlc1ske2RpbUlkeEh9XSAqIHVuaWZvcm1zLnNoIC0gdW5pZm9ybXMucGhTdGFydCArIGo7XG4gICAgICAgICAgICAgICAgICBpZiAoeEluZGljZXNbJHtkaW1JZHhIfV0gPCAwIHx8IHhJbmRpY2VzWyR7ZGltSWR4SH1dID49IHVuaWZvcm1zLnhfc2hhcGVbJHtkaW1JZHhIfV0pIHtcbiAgICAgICAgICAgICAgICAgICAgcGFkICs9IGkzMih1bmlmb3Jtcy5rdyk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29kZUggPSBgXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgajogdTMyID0gMHU7IGogPCB1bmlmb3Jtcy5raDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICB4SW5kaWNlc1ske2RpbUlkeEh9XSA9IGluZGljZXNbJHtkaW1JZHhIfV0gKiB1bmlmb3Jtcy5zaCAtIHVuaWZvcm1zLnBoU3RhcnQgKyBqO1xuICAgICAgICAgICAgICAgIGA7XG4gICAgICB9XG4gICAgICBjb2RlSEVuZCA9IGBcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgYDtcbiAgICB9XG5cbiAgICBjb25zdCBwb29saW5nQ29kZSA9IGBcbiAgICAgICAgICAgICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoeCwgb3V0cHV0KX1cblxuICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAgICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dFNpemUnKX1cblxuICAgICAgICAgICAgICBsZXQgaW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcbiAgICAgICAgICAgICAgdmFyIHhJbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuXG4gICAgICAgICAgICAgIHZhciB2YWx1ZSA9ICR7ZGF0YVR5cGV9KCR7c3RhcnR9KTtcbiAgICAgICAgICAgICAgdmFyIHBhZCA9IDA7XG4gICAgICAgICAgICAgICR7Y29kZUh9XG4gICAgICAgICAgICAgICR7Y29kZVd9XG4gICAgICAgICAgICAgICR7Y29kZUhFbmR9XG4gICAgICAgICAgICAgICR7b3AyfVxuXG4gICAgICAgICAgICAgIG91dHB1dFtnbG9iYWxfaWR4XSA9IHZhbHVlO1xuICAgICAgICAgICAgfWA7XG4gICAgcmV0dXJuIHBvb2xpbmdDb2RlO1xuICB9IGVsc2Uge1xuICAgIGlmIChpc0NoYW5uZWxzTGFzdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQb29saW5nIHdpdGgga2VybmVsU2hhcGUubGVuZ3RoID4gMiBpcyBub3Qgc3VwcG9ydGVkIGZvciBOSFdDIGZvcm1hdC4nKTtcbiAgICB9XG4gICAgY29uc3Qgc3RyaWRlc1JhbmsgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBwYWRzUmFuayA9IGF0dHJpYnV0ZXMucGFkcy5sZW5ndGg7XG4gICAgbGV0IHBhZENvZGUgPSAnJztcbiAgICBpZiAoaGFzUGFkcykge1xuICAgICAgcGFkQ29kZSA9IGBcbiAgICAgICAgICAgICAgICBpZiAoeEluZGljZXNbal0gPj0gdW5pZm9ybXMueF9zaGFwZVtqXSkge1xuICAgICAgICAgICAgICAgICAgcGFkKys7XG4gICAgICAgICAgICAgICAgICBpc1BhZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKCFpc1BhZCkge1xuICAgICAgICAgICAgICAgIGxldCB4X3ZhbCA9IHhbJHt4LmluZGljZXNUb09mZnNldCgneEluZGljZXMnKX1dO1xuICAgICAgICAgICAgICAgICR7b3AxfVxuICAgICAgICAgICAgICB9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcGFkQ29kZSA9IGBcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsZXQgeF92YWwgPSB4WyR7eC5pbmRpY2VzVG9PZmZzZXQoJ3hJbmRpY2VzJyl9XTtcbiAgICAgICAgICAgICAgJHtvcDF9XG4gICAgICAgICAgICBgO1xuICAgIH1cbiAgICBjb25zdCBwb29saW5nQ29kZSA9IGBcbiAgICAgICAgICAgICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoeCwgb3V0cHV0KX1cblxuICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAgICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dFNpemUnKX1cbiAgICAgICAgICAgICAgbGV0IGluZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG4gICAgICAgICAgICAgIHZhciB4SW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcblxuICAgICAgICAgICAgICB2YXIgb2Zmc2V0czogYXJyYXk8dTMyLCAke3N0cmlkZXNSYW5rfT47XG5cbiAgICAgICAgICAgICAgdmFyIHZhbHVlID0gJHtkYXRhVHlwZX0oJHtzdGFydH0pO1xuICAgICAgICAgICAgICB2YXIgcGFkID0gMDtcbiAgICAgICAgICAgICAgdmFyIGlzUGFkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgZm9yICh2YXIgaTogdTMyID0gMHU7IGkgPCB1bmlmb3Jtcy5rZXJuZWxTaXplOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0ID0gaTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMHU7IGogPCAke3N0cmlkZXNSYW5rIC0gMX11OyBqKyspIHtcbiAgICAgICAgICAgICAgICAgIG9mZnNldHNbal0gPSBvZmZzZXQgLyAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMua2VybmVsU3RyaWRlcycsICdqJywgc3RyaWRlc1JhbmspfTtcbiAgICAgICAgICAgICAgICAgIG9mZnNldCAtPSBvZmZzZXRzW2pdICogJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLmtlcm5lbFN0cmlkZXMnLCAnaicsIHN0cmlkZXNSYW5rKX07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9mZnNldHNbJHtzdHJpZGVzUmFuayAtIDF9XSA9IG9mZnNldDtcblxuICAgICAgICAgICAgICAgIGlzUGFkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9ICR7cmFuayAtIHN0cmlkZXNSYW5rfXU7IGogPCAke3Jhbmt9dTsgaisrKSB7XG4gICAgICAgICAgICAgICAgICB4SW5kaWNlc1tqXSA9IGluZGljZXNbal0gKiAke2dldEVsZW1lbnRBdChcbiAgICAgICAgICAgICAgICAgICAgJ3VuaWZvcm1zLnN0cmlkZXMnLFxuICAgICAgICAgICAgICAgICAgICBgaiAtICR7cmFuayAtIHN0cmlkZXNSYW5rfXVgLFxuICAgICAgICAgICAgICAgICAgICBzdHJpZGVzUmFuayxcbiAgICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgICAgICsgb2Zmc2V0c1tqIC0gJHtyYW5rIC0gc3RyaWRlc1Jhbmt9dV0gLSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMucGFkcycsICdqIC0gMnUnLCBwYWRzUmFuayl9O1xuICAgICAgICAgICAgICAgICAgJHtwYWRDb2RlfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICR7b3AyfVxuXG4gICAgICAgICAgICAgIG91dHB1dFtnbG9iYWxfaWR4XSA9IHZhbHVlO1xuICAgICAgICAgICAgfWA7XG4gICAgcmV0dXJuIHBvb2xpbmdDb2RlO1xuICB9XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIEZvcm1hdEF0dHJpYnV0ZXMge1xuICByZWFkb25seSBmb3JtYXQ6ICdOSFdDJyB8ICdOQ0hXJztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQb29sQ29tbW9uQXR0cmlidXRlcyBleHRlbmRzIEZvcm1hdEF0dHJpYnV0ZXMge1xuICByZWFkb25seSBhdXRvUGFkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNlaWxNb2RlOiBudW1iZXI7XG4gIHJlYWRvbmx5IGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHBhZHM6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5jb25zdCBjcmVhdGVTaGFkZXJLZXlGcm9tQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBQb29sQ29tbW9uQXR0cmlidXRlcyk6IHN0cmluZyA9PlxuICBgJHthdHRyaWJ1dGVzLmZvcm1hdH07JHthdHRyaWJ1dGVzLmNlaWxNb2RlfTske2F0dHJpYnV0ZXMuYXV0b1BhZH07JHthdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aH1gO1xuXG5jb25zdCBjcmVhdGVBdmVyYWdlUG9vbFNoYWRlcktleUZyb21BdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyk6IHN0cmluZyA9PlxuICBgJHtjcmVhdGVTaGFkZXJLZXlGcm9tQXR0cmlidXRlcyhhdHRyaWJ1dGVzKX07JHthdHRyaWJ1dGVzLmNvdW50SW5jbHVkZVBhZH1gO1xuXG5jb25zdCBjcmVhdGVNYXhQb29sU2hhZGVyS2V5RnJvbUF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogTWF4UG9vbEF0dHJpYnV0ZXMpOiBzdHJpbmcgPT5cbiAgYCR7Y3JlYXRlU2hhZGVyS2V5RnJvbUF0dHJpYnV0ZXMoYXR0cmlidXRlcyl9OyR7YXR0cmlidXRlcy5zdG9yYWdlT3JkZXJ9OyR7YXR0cmlidXRlcy5kaWxhdGlvbnN9YDtcblxuY29uc3QgcGFyc2VQb29sQ29tbW9uQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFBvb2xDb21tb25BdHRyaWJ1dGVzID0+ICh7XG4gIGZvcm1hdDogYXR0cmlidXRlcy5mb3JtYXQgYXMgRm9ybWF0QXR0cmlidXRlc1snZm9ybWF0J10sXG4gIGF1dG9QYWQ6IFsnTk9UU0VUJywgJ1ZBTElEJywgJ1NBTUVfVVBQRVInLCAnU0FNRV9MT1dFUiddW2F0dHJpYnV0ZXMuYXV0b19wYWQgYXMgbnVtYmVyXSxcbiAgY2VpbE1vZGU6IGF0dHJpYnV0ZXMuY2VpbF9tb2RlIGFzIG51bWJlcixcbiAga2VybmVsU2hhcGU6IGF0dHJpYnV0ZXMua2VybmVsX3NoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gIHN0cmlkZXM6IGF0dHJpYnV0ZXMuc3RyaWRlcyBhcyBbbnVtYmVyLCBudW1iZXJdLFxuICBwYWRzOiBhdHRyaWJ1dGVzLnBhZHMgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG59KTtcblxuZXhwb3J0IGludGVyZmFjZSBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgZXh0ZW5kcyBQb29sQ29tbW9uQXR0cmlidXRlcywgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgY291bnRJbmNsdWRlUGFkOiBib29sZWFuO1xufVxuXG5jb25zdCBjcmVhdGVBdmVyYWdlUG9vbFByb2dyYW1JbmZvID0gKFxuICBuYW1lOiBzdHJpbmcsXG4gIGlucHV0OiBUZW5zb3JWaWV3LFxuICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuICBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IFthZGp1c3RlZEF0dHJpYnV0ZXMsIG91dHB1dFNoYXBlXSA9IGdldEFkanVzdGVkUG9vbEF0dHJpYnV0ZXNBbmRPdXRwdXRTaGFwZShcbiAgICBpbnB1dCxcbiAgICBhdHRyaWJ1dGVzLFxuICAgIGlzR2xvYmFsT3BlcmF0b3IsXG4gICk7XG4gIGNvbnN0IHggPSBpbnB1dFZhcmlhYmxlKCd4JywgaW5wdXQuZGF0YVR5cGUsIGlucHV0LmRpbXMubGVuZ3RoKTtcbiAgY29uc3QgZGF0YVR5cGUgPSB4LnR5cGUudmFsdWU7XG5cbiAgY29uc3Qgb3AxID0gJ3ZhbHVlICs9IHhfdmFsOyc7XG4gIGxldCBvcDIgPSAnJztcbiAgaWYgKGFkanVzdGVkQXR0cmlidXRlcy5jb3VudEluY2x1ZGVQYWQpIHtcbiAgICBvcDIgKz0gYHZhbHVlIC89ICR7ZGF0YVR5cGV9KHVuaWZvcm1zLmtlcm5lbFNpemUpO2A7XG4gIH0gZWxzZSB7XG4gICAgb3AyICs9IGB2YWx1ZSAvPSAke2RhdGFUeXBlfShpMzIodW5pZm9ybXMua2VybmVsU2l6ZSkgLSBwYWQpO2A7XG4gIH1cbiAgY29uc3QgW3Byb2dyYW1Vbmlmb3JtcywgdW5pZm9ybXMsIGhhc1BhZHMsIHB3U3RhcnRFbmROb3RaZXJvLCBwaFN0YXJ0RW5kTm90WmVyb10gPSBnZXRVbmlmb3JtQW5kUGFkSW5mbyhcbiAgICBvdXRwdXRTaGFwZSxcbiAgICBhZGp1c3RlZEF0dHJpYnV0ZXMsXG4gICk7XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0LmRpbXMsIG91dHB1dFNoYXBlKSk7XG4gIGNvbnN0IGlucHV0RGVwZW5kZW5jaWVzOiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdID0gWydyYW5rJ107XG4gIHJldHVybiB7XG4gICAgbmFtZSxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX07JHtoYXNQYWRzfTske3B3U3RhcnRFbmROb3RaZXJvfTske3BoU3RhcnRFbmROb3RaZXJvfWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llcyxcbiAgICB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0LmRhdGFUeXBlIH1dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwoU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlOiAoc2hhZGVySGVscGVyKSA9PlxuICAgICAgZ2VuZXJhdGVQb29saW5nQ29kZShcbiAgICAgICAgc2hhZGVySGVscGVyLFxuICAgICAgICB4LFxuICAgICAgICBpbnB1dC5kaW1zLmxlbmd0aCxcbiAgICAgICAgb3V0cHV0U2hhcGUubGVuZ3RoLFxuICAgICAgICBhZGp1c3RlZEF0dHJpYnV0ZXMsXG4gICAgICAgIG9wMSxcbiAgICAgICAgb3AyLFxuICAgICAgICAwLjAsXG4gICAgICAgIHVuaWZvcm1zLFxuICAgICAgICBoYXNQYWRzLFxuICAgICAgICBwd1N0YXJ0RW5kTm90WmVybyxcbiAgICAgICAgcGhTdGFydEVuZE5vdFplcm8sXG4gICAgICApLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQXZlcmFnZVBvb2xBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgY291bnRJbmNsdWRlUGFkID0gKGF0dHJpYnV0ZXMuY291bnRfaW5jbHVkZV9wYWQgYXMgbnVtYmVyKSA9PT0gMCA/IGZhbHNlIDogdHJ1ZTtcblxuICBjb25zdCBhdHRyID0gcGFyc2VQb29sQ29tbW9uQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTtcbiAgLy8gVE9ETzogc3VwcG9ydCBhdHRyaWJ1dGUgJ2NlaWxfbW9kZSdcbiAgaWYgKGF0dHIuY2VpbE1vZGUgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzaW5nIGNlaWwoKSBpbiBzaGFwZSBjb21wdXRhdGlvbiBpcyBub3QgeWV0IHN1cHBvcnRlZCBmb3IgQXZlcmFnZVBvb2wnKTtcbiAgfVxuICBjb25zdCBhdmVyYWdlUG9vbEF0dHJpYnV0ZXMgPSB7IGNvdW50SW5jbHVkZVBhZCwgLi4uYXR0ciwgY2FjaGVLZXk6ICcnIH07XG4gIHJldHVybiB7IC4uLmF2ZXJhZ2VQb29sQXR0cmlidXRlcywgY2FjaGVLZXk6IGNyZWF0ZUF2ZXJhZ2VQb29sU2hhZGVyS2V5RnJvbUF0dHJpYnV0ZXMoYXZlcmFnZVBvb2xBdHRyaWJ1dGVzKSB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGF2ZXJhZ2VQb29sID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlQXZlcmFnZVBvb2xQcm9ncmFtSW5mbygnQXZlcmFnZVBvb2wnLCBjb250ZXh0LmlucHV0c1swXSwgZmFsc2UsIGF0dHJpYnV0ZXMpKTtcbn07XG5cbmNvbnN0IGdsb2JhbFBvb2xBdHRyaWJ1dGVzID0ge1xuICBhdXRvUGFkOiAnJyxcbiAgY2VpbE1vZGU6IDAsXG4gIGNvdW50SW5jbHVkZVBhZDogZmFsc2UsXG4gIGtlcm5lbFNoYXBlOiBbXSxcbiAgc3RyaWRlczogW10sXG4gIHBhZHM6IFtdLFxuICBzdG9yYWdlT3JkZXI6IDAsXG4gIGRpbGF0aW9uczogW10sXG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VHbG9iYWxBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBmb3JtYXQgPSBhdHRyaWJ1dGVzLmZvcm1hdCBhcyBGb3JtYXRBdHRyaWJ1dGVzWydmb3JtYXQnXTtcbiAgcmV0dXJuIHsgZm9ybWF0LCAuLi5nbG9iYWxQb29sQXR0cmlidXRlcywgY2FjaGVLZXk6IGZvcm1hdCB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGdsb2JhbEF2ZXJhZ2VQb29sID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlQXZlcmFnZVBvb2xQcm9ncmFtSW5mbygnR2xvYmFsQXZlcmFnZVBvb2wnLCBjb250ZXh0LmlucHV0c1swXSwgdHJ1ZSwgYXR0cmlidXRlcykpO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBNYXhQb29sQXR0cmlidXRlcyBleHRlbmRzIFBvb2xDb21tb25BdHRyaWJ1dGVzLCBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBzdG9yYWdlT3JkZXI6IG51bWJlcjtcbiAgcmVhZG9ubHkgZGlsYXRpb25zOiBudW1iZXJbXTtcbn1cblxuY29uc3QgY3JlYXRlTWF4UG9vbFByb2dyYW1JbmZvID0gKFxuICBuYW1lOiBzdHJpbmcsXG4gIGlucHV0OiBUZW5zb3JWaWV3LFxuICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuICBhdHRyaWJ1dGVzOiBNYXhQb29sQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW2FkanVzdGVkQXR0cmlidXRlcywgb3V0cHV0U2hhcGVdID0gZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlKFxuICAgIGlucHV0LFxuICAgIGF0dHJpYnV0ZXMsXG4gICAgaXNHbG9iYWxPcGVyYXRvcixcbiAgKTtcbiAgY29uc3Qgb3AxID0gYFxuICAgICAgdmFsdWUgPSBtYXgoeF92YWwsIHZhbHVlKTtcbiAgICBgO1xuICBjb25zdCBvcDIgPSAnJztcbiAgY29uc3QgeCA9IGlucHV0VmFyaWFibGUoJ3gnLCBpbnB1dC5kYXRhVHlwZSwgaW5wdXQuZGltcy5sZW5ndGgpO1xuICBjb25zdCBpbnB1dERlcGVuZGVuY2llczogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXSA9IFsncmFuayddO1xuICBjb25zdCBbcHJvZ3JhbVVuaWZvcm1zLCB1bmlmb3JtcywgaGFzUGFkcywgcHdTdGFydEVuZE5vdFplcm8sIHBoU3RhcnRFbmROb3RaZXJvXSA9IGdldFVuaWZvcm1BbmRQYWRJbmZvKFxuICAgIG91dHB1dFNoYXBlLFxuICAgIGFkanVzdGVkQXR0cmlidXRlcyxcbiAgKTtcbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXQuZGltcywgb3V0cHV0U2hhcGUpKTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fTske2hhc1BhZHN9OyR7cHdTdGFydEVuZE5vdFplcm99OyR7cGhTdGFydEVuZE5vdFplcm99YCxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzLFxuICAgIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXQuZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSkgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2U6IChzaGFkZXJIZWxwZXIpID0+XG4gICAgICBnZW5lcmF0ZVBvb2xpbmdDb2RlKFxuICAgICAgICBzaGFkZXJIZWxwZXIsXG4gICAgICAgIHgsXG4gICAgICAgIGlucHV0LmRpbXMubGVuZ3RoLFxuICAgICAgICBvdXRwdXRTaGFwZS5sZW5ndGgsXG4gICAgICAgIGFkanVzdGVkQXR0cmlidXRlcyxcbiAgICAgICAgb3AxLFxuICAgICAgICBvcDIsXG4gICAgICAgIGlucHV0LmRhdGFUeXBlID09PSBEYXRhVHlwZS5mbG9hdDE2ID8gLTY1NTA0IDogLTFlNSxcbiAgICAgICAgdW5pZm9ybXMsXG4gICAgICAgIGhhc1BhZHMsXG4gICAgICAgIHB3U3RhcnRFbmROb3RaZXJvLFxuICAgICAgICBwaFN0YXJ0RW5kTm90WmVybyxcbiAgICAgICksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgbWF4UG9vbCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogTWF4UG9vbEF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlTWF4UG9vbFByb2dyYW1JbmZvKCdNYXhQb29sJywgY29udGV4dC5pbnB1dHNbMF0sIGZhbHNlLCBhdHRyaWJ1dGVzKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VNYXhQb29sQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IE1heFBvb2xBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3Qgc3RvcmFnZU9yZGVyID0gYXR0cmlidXRlcy5zdG9yYWdlX29yZGVyIGFzIG51bWJlcjtcbiAgY29uc3QgZGlsYXRpb25zID0gYXR0cmlidXRlcy5kaWxhdGlvbnMgYXMgW251bWJlciwgbnVtYmVyXTtcblxuICBjb25zdCBhdHRyID0gcGFyc2VQb29sQ29tbW9uQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTtcbiAgLy8gVE9ETzogc3VwcG9ydCBhdHRyaWJ1dGUgJ2NlaWxfbW9kZScgYW5kICdzdG9yYWdlX29yZGVyJ1xuICBpZiAoc3RvcmFnZU9yZGVyICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjb2x1bW4gbWFqb3Igc3RvcmFnZSBvcmRlciBpcyBub3QgeWV0IHN1cHBvcnRlZCBmb3IgTWF4UG9vbCcpO1xuICB9XG4gIGlmIChhdHRyLmNlaWxNb2RlICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1c2luZyBjZWlsKCkgaW4gc2hhcGUgY29tcHV0YXRpb24gaXMgbm90IHlldCBzdXBwb3J0ZWQgZm9yIE1heFBvb2wnKTtcbiAgfVxuICBjb25zdCBtYXhQb29sQXR0cmlidXRlcyA9IHsgc3RvcmFnZU9yZGVyLCBkaWxhdGlvbnMsIC4uLmF0dHIsIGNhY2hlS2V5OiAnJyB9O1xuICByZXR1cm4geyAuLi5tYXhQb29sQXR0cmlidXRlcywgY2FjaGVLZXk6IGNyZWF0ZU1heFBvb2xTaGFkZXJLZXlGcm9tQXR0cmlidXRlcyhtYXhQb29sQXR0cmlidXRlcykgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdsb2JhbE1heFBvb2xBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogTWF4UG9vbEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBmb3JtYXQgPSBhdHRyaWJ1dGVzLmZvcm1hdCBhcyBGb3JtYXRBdHRyaWJ1dGVzWydmb3JtYXQnXTtcbiAgcmV0dXJuIHsgZm9ybWF0LCAuLi5nbG9iYWxQb29sQXR0cmlidXRlcywgY2FjaGVLZXk6IGZvcm1hdCB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGdsb2JhbE1heFBvb2wgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IE1heFBvb2xBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZU1heFBvb2xQcm9ncmFtSW5mbygnR2xvYmFsTWF4UG9vbCcsIGNvbnRleHQuaW5wdXRzWzBdLCB0cnVlLCBhdHRyaWJ1dGVzKSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLFxuICBnZXRNYXhDb21wb25lbnRzLFxuICBpbnB1dFZhcmlhYmxlLFxuICBvdXRwdXRWYXJpYWJsZSxcbiAgU2hhZGVySGVscGVyLFxuICBVbmlmb3Jtc0FycmF5VHlwZSxcbn0gZnJvbSAnLi9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIERlcXVhbnRpemVMaW5lckF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBheGlzOiBudW1iZXI7XG4gIGJsb2NrU2l6ZTogbnVtYmVyO1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogRGVxdWFudGl6ZUxpbmVyQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAoaW5wdXRzLmxlbmd0aCA8IDIgfHwgaW5wdXRzLmxlbmd0aCA+IDMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0RlcXVhbnRpemVMaW5lYXIgcmVxdWlyZXMgMiBvciAzIGlucHV0cy4nKTtcbiAgfVxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMV0uZGltcyA9PT0gaW5wdXRzWzJdLmRpbXMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3gtc2NhbGUgYW5kIHgtemVyby1wb2ludCBtdXN0IGhhdmUgdGhlIHNhbWUgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgaW5wdXRzWzBdLmRhdGFUeXBlICE9PSBpbnB1dHNbMl0uZGF0YVR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3ggYW5kIHgtemVyby1wb2ludCBtdXN0IGhhdmUgdGhlIHNhbWUgZGF0YSB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDAgJiYgaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSAxICYmIGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzY2FsZSBpbnB1dCBtdXN0IGJlIGEgc2NhbGFyLCBhIDFEIHRlbnNvciwgb3IgaGF2ZSB0aGUgc2FtZSByYW5rIGFzIHRoZSBpbnB1dCB0ZW5zb3IuJyk7XG4gIH1cbiAgLy8gdmFsaWRhdGUgc2NhbGUgYW5kIHplcm8tcG9pbnQgaW5wdXQgc2hhcGVzXG4gIGlmIChpbnB1dHMubGVuZ3RoID4gMikge1xuICAgIC8vIHplcm8tcG9pbnQgaW5wdXQgdHlwZSBzaG91bGQgYmUgdGhlIHNhbWUgYXMgaW5wdXQgZGF0YSB0eXBlLlxuICAgIGlmIChpbnB1dHNbMF0uZGF0YVR5cGUgIT09IGlucHV0c1syXS5kYXRhVHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd4IGFuZCB4LXplcm8tcG9pbnQgbXVzdCBoYXZlIHRoZSBzYW1lIGRhdGEgdHlwZS4nKTtcbiAgICB9XG4gICAgLy8gU2NhbGUgYW5kIHplcm8tcG9pbnQgaW5wdXRzIG11c3QgaGF2ZSB0aGUgc2FtZSBzaGFwZVxuICAgIGlmIChpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IGlucHV0c1syXS5kaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzY2FsZSBhbmQgemVyby1wb2ludCBpbnB1dHMgbXVzdCBoYXZlIHRoZSBzYW1lIHJhbmsuJyk7XG4gICAgfVxuICAgIGlmICghaW5wdXRzWzFdLmRpbXMubWFwKChkLCBpKSA9PiBkID09PSBpbnB1dHNbMl0uZGltc1tpXSkucmVkdWNlKChhLCBiKSA9PiBhICYmIGIsIHRydWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NjYWxlIGFuZCB6ZXJvLXBvaW50IGlucHV0cyBtdXN0IGhhdmUgdGhlIHNhbWUgc2hhcGUuJyk7XG4gICAgfVxuICB9XG4gIC8vIFZhbGlkYXRlIGJsb2NrU2l6ZVxuICBpZiAoYXR0cmlidXRlcy5ibG9ja1NpemUgPiAwKSB7XG4gICAgLy8gQmxvY2sgcXVuYXRpemF0aW9uXG4gICAgaWYgKGlucHV0c1sxXS5kaW1zLmxlbmd0aCA9PT0gMCB8fCAoaW5wdXRzWzFdLmRpbXMubGVuZ3RoID09PSAxICYmIGlucHV0c1sxXS5kaW1zWzBdID09PSAxKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdibG9ja1NpemUgbXVzdCBiZSBzZXQgb25seSBmb3IgYmxvY2sgcXVhbnRpemF0aW9uLicpO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICAhaW5wdXRzWzFdLmRpbXMubWFwKChkLCBpKSA9PiBpID09PSBhdHRyaWJ1dGVzLmF4aXMgfHwgZCA9PT0gaW5wdXRzWzBdLmRpbXNbaV0pLnJlZHVjZSgoYSwgYikgPT4gYSAmJiBiLCB0cnVlKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGb3IgYmxvY2sgcXVuYXRpemF0aW9uLCBzY2FsZSBpbnB1dCBzaGFwZSB0byBtYXRjaCB0aGUgaW5wdXQgc2hhcGUgZXhjZXB0IGZvciB0aGUgYXhpcycpO1xuICAgIH1cbiAgICAvLyBTY2FsZSBpbnB1dCByYW5rIHNob3VsZCBiZSBzYW1lIGFzIHRoZSBpbnB1dCByYW5rXG4gICAgaWYgKGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZvciBibG9jayBxdW5hdGl6YXRpb24gdGhlIHNjYWxlIGlucHV0IHJhbmsgbXVzdCBiZSB0aGUgc2FtZSBhcyB0aGUgeCByYW5rLicpO1xuICAgIH1cbiAgICBjb25zdCBkSSA9IGlucHV0c1swXS5kaW1zW2F0dHJpYnV0ZXMuYXhpc107XG4gICAgY29uc3Qgc2kgPSBpbnB1dHNbMV0uZGltc1thdHRyaWJ1dGVzLmF4aXNdO1xuICAgIGlmIChhdHRyaWJ1dGVzLmJsb2NrU2l6ZSA8IE1hdGguY2VpbChkSSAvIHNpKSB8fCBhdHRyaWJ1dGVzLmJsb2NrU2l6ZSA+IE1hdGguY2VpbChkSSAvIChzaSAtIDEpIC0gMSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYmxvY2tTaXplIG11c3QgYmUgd2l0aCBpbiB0aGUgcmFuZ2UgW2NlaWwoZEkgLyBTaSksIGNlaWwoZEkgLyAoU2kgLSAxKSAtIDEpXS4nKTtcbiAgICB9XG4gIH1cbn07XG5cbmNvbnN0IGNyZWF0ZURlcXVhbnRpemVMaW5lYXJQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IERlcXVhbnRpemVMaW5lckF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0c1swXS5kaW1zLmxlbmd0aCk7XG4gIGNvbnN0IGlucHV0VHlwZSA9IGlucHV0c1swXS5kYXRhVHlwZTtcbiAgY29uc3QgaXNTaWduZWQgPSBpbnB1dFR5cGUgPT09IERhdGFUeXBlLmludDg7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7IC8vIG91dHB1dCBzaGFwZSBpcyBzYW1lIGFzIHRoZSBpbnB1dCBzaGFwZVxuICBjb25zdCBkYXRhVHlwZSA9IGlucHV0c1sxXS5kYXRhVHlwZTsgLy8gb3V0cHV0IHR5cGUgaXMgc2FtZSBhcyB0aGUgdGhlIHNjYWxlIGlucHV0IHR5cGVcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgY29uc3QgaXNQYWNrZWQgPSBpbnB1dFR5cGUgPT09IERhdGFUeXBlLmludDggfHwgaW5wdXRUeXBlID09PSBEYXRhVHlwZS51aW50ODtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlzUGFja2VkID8gW01hdGguY2VpbChTaGFwZVV0aWwuc2l6ZShpbnB1dHNbMF0uZGltcykgLyA0KV0gOiBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qgc2NhbGVTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCB6ZXJvUG9pbnRJbnB1dCA9IGlucHV0cy5sZW5ndGggPiAyID8gaW5wdXRzWzJdIDogdW5kZWZpbmVkO1xuICBjb25zdCB6ZXJvUG9pbnRTaGFwZSA9IHplcm9Qb2ludElucHV0XG4gICAgPyBpc1BhY2tlZFxuICAgICAgPyBbTWF0aC5jZWlsKFNoYXBlVXRpbC5zaXplKHplcm9Qb2ludElucHV0LmRpbXMpIC8gNCldXG4gICAgICA6IHplcm9Qb2ludElucHV0LmRpbXNcbiAgICA6IHVuZGVmaW5lZDtcbiAgLy8gU2NhbGVzIGlucHV0IGlzIGEgc2NhbGVyIGZvciBwZXItdGVuc29yL3Blci1sYXllciBxdWFudGl6YXRpb24sIDEtRCB0ZW5zb3IgZm9yIHBlci1heGlzIHF1YW50aXphdGlvblxuICAvLyBvciB0ZW5zb3Igd2l0aCBzYW1lIHJhbmsgYXMgaW5wdXQgZm9yIGJsb2NrZWQgcXVhbnRpemF0aW9uLlxuICBjb25zdCBwZXJMYXllclF1YW50aXphdGlvbiA9IHNjYWxlU2hhcGUubGVuZ3RoID09PSAwIHx8IChzY2FsZVNoYXBlLmxlbmd0aCA9PT0gMSAmJiBzY2FsZVNoYXBlWzBdID09PSAxKTtcbiAgY29uc3QgcGVyQXhpc1F1YW50aXphdGlvbiA9IHBlckxheWVyUXVhbnRpemF0aW9uID09PSBmYWxzZSAmJiBzY2FsZVNoYXBlLmxlbmd0aCA9PT0gMTtcbiAgLy8gTGVmdCB1bm5lY2Vzc2FyeSBjb21tZW50ZWQtb3V0IGFzc2lnbm1lbnQgZm9yIGRvY3VtZW50YXRpb25cbiAgLy8gY29uc3QgYmxvY2tRdWFudGl6YXRpb24gPSBwZXJMYXllclF1YW50aXphdGlvbiA9PT0gZmFsc2UgJiYgcGVyQXhpc1F1YW50aXphdGlvbiA9PT0gZmFsc2U7XG4gIGNvbnN0IG1heENvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKG91dHB1dFNpemUpO1xuICBjb25zdCB1c2VDb21wb25lbnRzID0gcGVyTGF5ZXJRdWFudGl6YXRpb24gJiYgKCFpc1BhY2tlZCB8fCBtYXhDb21wb25lbnRzID09PSA0KTtcbiAgY29uc3QgY29tcG9uZW50cyA9IHVzZUNvbXBvbmVudHMgPyBtYXhDb21wb25lbnRzIDogMTtcbiAgY29uc3QgaW5wdXRDb21wb25lbnQgPSB1c2VDb21wb25lbnRzICYmICFpc1BhY2tlZCA/IG1heENvbXBvbmVudHMgOiAxO1xuICBjb25zdCBpbnB1dCA9IGlucHV0VmFyaWFibGUoJ2lucHV0JywgaXNQYWNrZWQgPyBEYXRhVHlwZS51aW50MzIgOiBpbnB1dFR5cGUsIGlucHV0U2hhcGUubGVuZ3RoLCBpbnB1dENvbXBvbmVudCk7XG4gIGNvbnN0IHNjYWxlID0gaW5wdXRWYXJpYWJsZSgnc2NhbGUnLCBkYXRhVHlwZSwgc2NhbGVTaGFwZS5sZW5ndGgpO1xuICBjb25zdCB6ZXJvUG9pbnQgPSB6ZXJvUG9pbnRJbnB1dFxuICAgID8gaW5wdXRWYXJpYWJsZSgnemVyb19wb2ludCcsIGlzUGFja2VkID8gRGF0YVR5cGUudWludDMyIDogaW5wdXRUeXBlLCB6ZXJvUG9pbnRTaGFwZSEubGVuZ3RoKVxuICAgIDogdW5kZWZpbmVkO1xuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgZGF0YVR5cGUsIG91dHB1dFNoYXBlLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gIGNvbnN0IGlucHV0VmFyaWFibGVzID0gW2lucHV0LCBzY2FsZV07XG4gIGlmICh6ZXJvUG9pbnQpIHtcbiAgICBpbnB1dFZhcmlhYmxlcy5wdXNoKHplcm9Qb2ludCk7XG4gIH1cbiAgY29uc3QgaW5wdXRTaGFwZXMgPSBbaW5wdXRTaGFwZSwgc2NhbGVTaGFwZV07XG4gIGlmICh6ZXJvUG9pbnRJbnB1dCkge1xuICAgIGlucHV0U2hhcGVzLnB1c2goemVyb1BvaW50U2hhcGUhKTtcbiAgfVxuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgLyBjb21wb25lbnRzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGF4aXMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYXR0cmlidXRlcy5ibG9ja1NpemUgfSxcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyguLi5pbnB1dFNoYXBlcywgb3V0cHV0U2hhcGUpLFxuICBdO1xuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdheGlzJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2Jsb2NrX3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgIF07XG4gICAgcmV0dXJuIGBcbiAgICAgICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJpYWJsZXMsIG91dHB1dCl9XG4gICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAgICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRfc2l6ZScpfVxuICAgICAgICAgIGxldCBvdXRwdXRfaW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcblxuICAgICAgICAgIC8vIFNldCBpbnB1dCB4XG4gICAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICBsZXQgaW5wdXQgPSAke2lucHV0LmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4IC8gNCcpfTtcbiAgICAgICAgICAgIGxldCB4X3ZlYyA9ICR7aXNTaWduZWQgPyAndW5wYWNrNHhJOChpbnB1dCknIDogJ3VucGFjazR4VTgoaW5wdXQpJ307XG4gICAgICAgICAgICBsZXQgeF92YWx1ZSA9ICR7Y29tcG9uZW50cyA9PT0gMSA/ICd4X3ZlY1tnbG9iYWxfaWR4ICUgNF0nIDogJ3hfdmVjJ307YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBgbGV0IHhfdmFsdWUgPSAke2lucHV0LmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4Jyl9O2A7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkoKX07XG5cbiAgICAgICAgICAvLyBTZXQgc2NhbGUgaW5wdXRcbiAgICAgICAgICAkeygoKSA9PiB7XG4gICAgICAgICAgICBpZiAocGVyTGF5ZXJRdWFudGl6YXRpb24pIHtcbiAgICAgICAgICAgICAgLy8gc2NhbGUgaW5wdXQgaXMgYSBzY2FsYXIgKClcbiAgICAgICAgICAgICAgcmV0dXJuIGBsZXQgc2NhbGVfdmFsdWU9ICR7c2NhbGUuZ2V0QnlPZmZzZXQoJzAnKX1gO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChwZXJBeGlzUXVhbnRpemF0aW9uKSB7XG4gICAgICAgICAgICAgIC8vIHNjYWxlIGlucHV0IGlzIGEgMUQgdGVuc29yXG4gICAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICBsZXQgc2NhbGVfaW5kZXggPSAke291dHB1dC5pbmRpY2VzR2V0KCdvdXRwdXRfaW5kaWNlcycsICd1bmlmb3Jtcy5heGlzJyl9O1xuICAgICAgICAgICAgbGV0IHNjYWxlX3ZhbHVlPSAke3NjYWxlLmdldEJ5T2Zmc2V0KCdzY2FsZV9pbmRleCcpfTtgO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gQmxvY2sgcXVhbnRpemF0aW9uLiBTY2FsZSBpbnB1dCByYW5rIGlzIHNhbWUgYXMgaW5wdXQvb3V0cHV0IHJhbmsuXG4gICAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICB2YXIgc2NhbGVfaW5kaWNlczogJHtzY2FsZS50eXBlLmluZGljZXN9ID0gb3V0cHV0X2luZGljZXM7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAke3NjYWxlLmluZGljZXNHZXQoJ3NjYWxlX2luZGljZXMnLCAndW5pZm9ybXMuYXhpcycpfSAvIHVuaWZvcm1zLmJsb2NrX3NpemU7XG4gICAgICAgICAgICAke3NjYWxlLmluZGljZXNTZXQoJ3NjYWxlX2luZGljZXMnLCAndW5pZm9ybXMuYXhpcycsICdpbmRleCcpfTtcbiAgICAgICAgICAgIGxldCBzY2FsZV92YWx1ZT0gJHtzY2FsZS5nZXRCeUluZGljZXMoJ3NjYWxlX2luZGljZXMnKX07YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSgpfTtcblxuICAgICAgICAgIC8vIFNldCB6ZXJvLXBvaW50IGlucHV0XG4gICAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHplcm9Qb2ludCkge1xuICAgICAgICAgICAgICBpZiAocGVyTGF5ZXJRdWFudGl6YXRpb24pIHtcbiAgICAgICAgICAgICAgICAvLyB6ZXJvLXBvaW50IGlucHV0IGlzIGEgc2NhbGFyXG4gICAgICAgICAgICAgICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X2lucHV0ID0gJHt6ZXJvUG9pbnQuZ2V0QnlPZmZzZXQoJzAnKX07XG4gICAgICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfdmVjID0gICR7aXNTaWduZWQgPyAndW5wYWNrNHhJOCh6ZXJvX3BvaW50X2lucHV0KScgOiAndW5wYWNrNHhVOCh6ZXJvX3BvaW50X2lucHV0KSd9O1xuICAgICAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X3ZhbHVlPSB6ZXJvX3BvaW50X3ZlY1swXWA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBgbGV0IHplcm9fcG9pbnRfdmFsdWUgPSAke3plcm9Qb2ludC5nZXRCeU9mZnNldCgnMCcpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBlckF4aXNRdWFudGl6YXRpb24pIHtcbiAgICAgICAgICAgICAgICAvLyB6ZXJvLXBvaW50IGlucHV0IGlzIGEgMUQgdGVuc29yXG4gICAgICAgICAgICAgICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X2luZGV4ID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCAndW5pZm9ybXMuYXhpcycpfTtcbiAgICAgICAgICAgICAgICBsZXQgemVyb19wb2ludF9pbnB1dCA9ICR7emVyb1BvaW50LmdldEJ5T2Zmc2V0KCd6ZXJvX3BvaW50X2luZGV4IC8gNCcpfTtcbiAgICAgICAgICAgICAgICBsZXQgemVyb19wb2ludF92ZWMgPSAgJHtpc1NpZ25lZCA/ICd1bnBhY2s0eEk4KHplcm9fcG9pbnRfaW5wdXQpJyA6ICd1bnBhY2s0eFU4KHplcm9fcG9pbnRfaW5wdXQpJ307XG4gICAgICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfdmFsdWUgPSB6ZXJvX3BvaW50X3ZlY1t6ZXJvX3BvaW50X2luZGV4ICUgNF1gO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X2luZGV4ID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCAndW5pZm9ybXMuYXhpcycpfTtcbiAgICAgICAgICAgICAgICBsZXQgemVyb19wb2ludF92YWx1ZSA9ICR7emVyb1BvaW50LmdldEJ5T2Zmc2V0KCd6ZXJvX3BvaW50X2luZGV4Jyl9O2A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEJsb2NrZWRRdWFudGl6YXRpb24uIFRoZSB6ZXJvLXBvaW50IGlucHV0IHNoYXBlIGlzIHNhbWUgYXMgdGhlIGlucHV0IHNoYXBlIGV4Y2VwdCBhbG9uZyBheGlzLlxuICAgICAgICAgICAgICAgIGlmIChpc1BhY2tlZCkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICAgICAgICBsZXQgemVyb19wb2ludF9vZmZzZXQgPSAke3NjYWxlLmluZGljZXNUb09mZnNldCgnc2NhbGVfaW5kaWNlcycpfTtcbiAgICAgICAgICAgICAgICBsZXQgemVyb19wb2ludF9pbnB1dCA9ICR7emVyb1BvaW50LmdldEJ5T2Zmc2V0KCd6ZXJvX3BvaW50X29mZnNldCAvIDQnKX07XG4gICAgICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfdmVjID0gJHtpc1NpZ25lZCA/ICd1bnBhY2s0eEk4KHplcm9fcG9pbnRfaW5wdXQpJyA6ICd1bnBhY2s0eFU4KHplcm9fcG9pbnRfaW5wdXQpJ307XG4gICAgICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfdmFsdWUgPSB6ZXJvX3BvaW50X3ZlY1t6ZXJvX3BvaW50X29mZnNldCAlIDRdO2A7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBgbGV0IHplcm9fcG9pbnRfdmFsdWUgPSAke3plcm9Qb2ludC5nZXRCeUluZGljZXMoJ3NjYWxlX2luZGljZXMnKX07YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBgbGV0IHplcm9fcG9pbnRfdmFsdWUgPSAke2lzUGFja2VkID8gKGlzU2lnbmVkID8gJ2kzMicgOiAndTMyJykgOiBpbnB1dC50eXBlLnZhbHVlfSgwKTtgO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pKCl9O1xuICAgICAgLy8gQ29tcHV0ZSBhbmQgd3JpdGUgb3V0cHV0XG4gICAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsIGAke291dHB1dC50eXBlLnZhbHVlfSh4X3ZhbHVlIC0gemVyb19wb2ludF92YWx1ZSkgKiBzY2FsZV92YWx1ZWApfTtcbiAgICAgIH1gO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdEZXF1YW50aXplTGluZWFyJyxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzOiB6ZXJvUG9pbnQgPyBbJ3JhbmsnLCAncmFuaycsICdyYW5rJ10gOiBbJ3JhbmsnLCAncmFuayddLFxuICAgIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gY29tcG9uZW50cyAvIDY0KSwgeTogMSwgejogMSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGRlcXVhbnRpemVMaW5lYXIgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IERlcXVhbnRpemVMaW5lckF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRGVxdWFudGl6ZUxpbmVhclByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VEZXF1YW50aXplTGluZWFyQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IERlcXVhbnRpemVMaW5lckF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpczogYXR0cmlidXRlcy5heGlzIGFzIG51bWJlciwgYmxvY2tTaXplOiBhdHRyaWJ1dGVzLmJsb2NrU2l6ZSBhcyBudW1iZXIgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvLCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIFVuaWZvcm1EYXRhRWxlbWVudFR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzQ29udGVudCA9IChzdGFydDogbnVtYmVyLCBsaW1pdDogbnVtYmVyLCBkZWx0YTogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGNvbnN0IHNhbWVTdGFydExpbWl0ID0gc3RhcnQgPT09IGxpbWl0O1xuICBjb25zdCBpbmNyZWFzaW5nUmFuZ2VOZWdhdGl2ZVN0ZXAgPSBzdGFydCA8IGxpbWl0ICYmIGRlbHRhIDwgMDtcbiAgY29uc3QgZGVjcmVhc2luZ1JhbmdlUG9zaXRpdmVTdGVwID0gc3RhcnQgPiBsaW1pdCAmJiBkZWx0YSA+IDA7XG5cbiAgaWYgKHNhbWVTdGFydExpbWl0IHx8IGluY3JlYXNpbmdSYW5nZU5lZ2F0aXZlU3RlcCB8fCBkZWNyZWFzaW5nUmFuZ2VQb3NpdGl2ZVN0ZXApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJSYW5nZSB0aGVzZSBpbnB1dHMnIGNvbnRlbnRzIGFyZSBpbnZhbGlkLlwiKTtcbiAgfVxufTtcblxuY29uc3QgY3JlYXRlUmFuZ2VQcm9ncmFtSW5mbyA9IChzdGFydDogbnVtYmVyLCBsaW1pdDogbnVtYmVyLCBkZWx0YTogbnVtYmVyLCBkYXRhVHlwZTogRGF0YVR5cGUpOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IG51bUVsZW1lbnRzID0gTWF0aC5hYnMoTWF0aC5jZWlsKChsaW1pdCAtIHN0YXJ0KSAvIGRlbHRhKSk7XG4gIGNvbnN0IG91dHB1dFNoYXBlOiBudW1iZXJbXSA9IFtudW1FbGVtZW50c107XG4gIGNvbnN0IG91dHB1dFNpemUgPSBudW1FbGVtZW50cztcbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBkYXRhVHlwZSwgZGF0YTogc3RhcnQgfSxcbiAgICB7IHR5cGU6IGRhdGFUeXBlLCBkYXRhOiBkZWx0YSB9LFxuICAgIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKG91dHB1dFNoYXBlKSxcbiAgXTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgZGF0YVR5cGUsIG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgY29uc3Qgd2dzbFR5cGUgPSBvdXRwdXQudHlwZS52YWx1ZTtcbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRTaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ3N0YXJ0JywgdHlwZTogd2dzbFR5cGUgYXMgVW5pZm9ybURhdGFFbGVtZW50VHlwZSB9LFxuICAgICAgeyBuYW1lOiAnZGVsdGEnLCB0eXBlOiB3Z3NsVHlwZSBhcyBVbmlmb3JtRGF0YUVsZW1lbnRUeXBlIH0sXG4gICAgXTtcbiAgICByZXR1cm4gYFxuICAgICAgICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKG91dHB1dCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRTaXplJyl9XG4gICAgICAgIG91dHB1dFtnbG9iYWxfaWR4XSA9IHVuaWZvcm1zLnN0YXJ0ICsgJHt3Z3NsVHlwZX0oZ2xvYmFsX2lkeCkgKiB1bmlmb3Jtcy5kZWx0YTtcbiAgICAgIH1gO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ1JhbmdlJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtkYXRhVHlwZX1gIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgcmFuZ2UgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IGxpbWl0ID0gMDtcbiAgbGV0IGRlbHRhID0gMDtcbiAgaWYgKGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlID09PSBEYXRhVHlwZS5pbnQzMikge1xuICAgIHN0YXJ0ID0gY29udGV4dC5pbnB1dHNbMF0uZ2V0SW50MzJBcnJheSgpWzBdO1xuICAgIGxpbWl0ID0gY29udGV4dC5pbnB1dHNbMV0uZ2V0SW50MzJBcnJheSgpWzBdO1xuICAgIGRlbHRhID0gY29udGV4dC5pbnB1dHNbMl0uZ2V0SW50MzJBcnJheSgpWzBdO1xuICB9IGVsc2UgaWYgKGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlID09PSBEYXRhVHlwZS5mbG9hdCkge1xuICAgIHN0YXJ0ID0gY29udGV4dC5pbnB1dHNbMF0uZ2V0RmxvYXQzMkFycmF5KClbMF07XG4gICAgbGltaXQgPSBjb250ZXh0LmlucHV0c1sxXS5nZXRGbG9hdDMyQXJyYXkoKVswXTtcbiAgICBkZWx0YSA9IGNvbnRleHQuaW5wdXRzWzJdLmdldEZsb2F0MzJBcnJheSgpWzBdO1xuICB9XG4gIGlmIChlbnYud2ViZ3B1LnZhbGlkYXRlSW5wdXRDb250ZW50KSB7XG4gICAgdmFsaWRhdGVJbnB1dHNDb250ZW50KHN0YXJ0LCBsaW1pdCwgZGVsdGEpO1xuICB9XG5cbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZVJhbmdlUHJvZ3JhbUluZm8oc3RhcnQsIGxpbWl0LCBkZWx0YSwgY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUpLCB7IGlucHV0czogW10gfSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGF0b21pY091dHB1dFZhcmlhYmxlLFxuICBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyxcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbn0gZnJvbSAnLi9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNjYXR0ZXJOREF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWR1Y3Rpb246IHN0cmluZztcbn1cblxudHlwZSBSZWR1Y3Rpb25UeXBlID0gJ2kzMicgfCAndTMyJyB8ICdmMzInO1xuXG5jb25zdCBhdG9taWNSZWR1Y3Rpb25TbmlwcGV0ID0gKHJlZHVjdGlvbjogc3RyaW5nLCBwdHI6IHN0cmluZywgdjogc3RyaW5nLCB0eXBlOiBSZWR1Y3Rpb25UeXBlKSA9PiB7XG4gIGlmIChyZWR1Y3Rpb24gIT09ICdub25lJyAmJiB0eXBlICE9PSAnaTMyJyAmJiB0eXBlICE9PSAndTMyJyAmJiB0eXBlICE9PSAnZjMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgJHt0eXBlfSBpcyBub3Qgc3VwcG9ydGVkIHdpdGggcmVkdWN0aW9uICR7cmVkdWN0aW9ufS5gKTtcbiAgfVxuXG4gIGNvbnN0IGZsb2F0U3RhcnQgPSBge1xuICAgICAgICAgICAgICAgIHZhciBvbGRWYWx1ZSA9IDA7XG4gICAgICAgICAgICAgICAgbG9vcCB7XG4gICAgICAgICAgICAgICAgICBsZXQgbmV3VmFsdWVGMzIgPWA7XG4gIGNvbnN0IGZsb2F0RW5kID0gYDtcbiAgICAgICAgICAgICAgICAgIGxldCBuZXdWYWx1ZSA9IGJpdGNhc3Q8aTMyPihuZXdWYWx1ZUYzMik7XG4gICAgICAgICAgICAgICAgICBsZXQgcmVzID0gYXRvbWljQ29tcGFyZUV4Y2hhbmdlV2VhaygmJHtwdHJ9LCBvbGRWYWx1ZSwgbmV3VmFsdWUpO1xuICAgICAgICAgICAgICAgICAgaWYgcmVzLmV4Y2hhbmdlZCB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSByZXMub2xkX3ZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfWA7XG5cbiAgc3dpdGNoIChyZWR1Y3Rpb24pIHtcbiAgICBjYXNlICdub25lJzpcbiAgICAgIHJldHVybiBgJHtwdHJ9PSR7dn07YDtcbiAgICBjYXNlICdhZGQnOlxuICAgICAgaWYgKHR5cGUgPT09ICdpMzInIHx8IHR5cGUgPT09ICd1MzInKSB7XG4gICAgICAgIHJldHVybiBgYXRvbWljQWRkKCYke3B0cn0sIGJpdGNhc3Q8JHt0eXBlfT4oJHt2fSkpO2A7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBhdG9taWNBZGQgb25seSBzdXBwb3J0cyB1aW50L2ludCB0eXBlLiBGb3IgZmxvYXQsIHdlIHVzZVxuICAgICAgICAvLyBhdG9taWNDb21wYXJlRXhjaGFuZ2VXZWFrIHRvIHNpbXVsYXRlLlxuICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAke2Zsb2F0U3RhcnR9Yml0Y2FzdDwke3R5cGV9PihvbGRWYWx1ZSkgKyAoJHt2fSkke2Zsb2F0RW5kfWA7XG4gICAgICB9XG4gICAgY2FzZSAnbWF4JzpcbiAgICAgIGlmICh0eXBlID09PSAnaTMyJyB8fCB0eXBlID09PSAndTMyJykge1xuICAgICAgICByZXR1cm4gYGF0b21pY01heCgmJHtwdHJ9LCBiaXRjYXN0PCR7dHlwZX0+KCR7dn0pKTtgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gYXRvbWljTWF4IG9ubHkgc3VwcG9ydHMgdWludC9pbnQgdHlwZS4gRm9yIGZsb2F0LCB3ZSB1c2VcbiAgICAgICAgLy8gYXRvbWljQ29tcGFyZUV4Y2hhbmdlV2VhayB0byBzaW11bGF0ZS5cbiAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICAgICAgICAke2Zsb2F0U3RhcnR9bWF4KGJpdGNhc3Q8ZjMyPihvbGRWYWx1ZSksICgke3Z9KSkke2Zsb2F0RW5kfWA7XG4gICAgICB9XG4gICAgY2FzZSAnbWluJzpcbiAgICAgIGlmICh0eXBlID09PSAnaTMyJyB8fCB0eXBlID09PSAndTMyJykge1xuICAgICAgICByZXR1cm4gYGF0b21pY01pbigmJHtwdHJ9LCBiaXRjYXN0PCR7dHlwZX0+KCR7dn0pKTtgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gYXRvbWljTWluIG9ubHkgc3VwcG9ydHMgdWludC9pbnQgdHlwZS4gRm9yIGZsb2F0LCB3ZSB1c2VcbiAgICAgICAgLy8gYXRvbWljQ29tcGFyZUV4Y2hhbmdlV2VhayB0byBzaW11bGF0ZS5cbiAgICAgICAgcmV0dXJuIGAke2Zsb2F0U3RhcnR9bWluKGJpdGNhc3Q8JHt0eXBlfT4ob2xkVmFsdWUpLCAoJHt2fSkpJHtmbG9hdEVuZH1gO1xuICAgICAgfVxuICAgIGNhc2UgJ211bCc6XG4gICAgICAvLyBhdG9taWNNdWwgaXMgbm90IHN1cHBvcnRlZCwgd2UgdXNlIGF0b21pY0NvbXBhcmVFeGNoYW5nZVdlYWsgdG8gc2ltdWxhdGUuXG4gICAgICByZXR1cm4gYCR7ZmxvYXRTdGFydH0oYml0Y2FzdDwke3R5cGV9PihvbGRWYWx1ZSkgKiAoJHt2fSkpJHtmbG9hdEVuZH1gO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUmVkdWN0aW9uICR7cmVkdWN0aW9ufSBpcyBub3Qgc3VwcG9ydGVkLmApO1xuICB9XG59O1xuXG5jb25zdCBjcmVhdGVTY2F0dGVyTkRQcm9ncmFtSW5mbyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogU2NhdHRlck5EQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbmRpY2VzU2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNoYXBlO1xuICAvLyBUT0RPOiBzdXBwb3J0IGJvb2wgd2l0aCBjb21wb25lbnRzIDQuXG4gIGNvbnN0IGNvbXBvbmVudHMgPSAxO1xuICBjb25zdCBvdXRwdXRTaXplID0gTWF0aC5jZWlsKFNoYXBlVXRpbC5zaXplVG9EaW1lbnNpb24oaW5kaWNlc1NoYXBlLCBpbmRpY2VzU2hhcGUubGVuZ3RoIC0gMSkgLyBjb21wb25lbnRzKTtcbiAgY29uc3QgbGFzdEluZGV4RGltZW5zaW9uID0gaW5kaWNlc1NoYXBlW2luZGljZXNTaGFwZS5sZW5ndGggLSAxXTtcbiAgY29uc3QgbnVtVXBkYXRlc0VsZW1lbnRzID0gU2hhcGVVdGlsLnNpemVGcm9tRGltZW5zaW9uKGlucHV0U2hhcGUsIGxhc3RJbmRleERpbWVuc2lvbik7XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGxhc3RJbmRleERpbWVuc2lvbiB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBudW1VcGRhdGVzRWxlbWVudHMgfSxcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMV0uZGltcywgaW5wdXRzWzJdLmRpbXMsIG91dHB1dFNoYXBlKSxcbiAgXTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBpbmRpY2VzID0gaW5wdXRWYXJpYWJsZSgnaW5kaWNlcycsIGlucHV0c1sxXS5kYXRhVHlwZSwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoKTtcbiAgICBjb25zdCB1cGRhdGVzID0gaW5wdXRWYXJpYWJsZSgndXBkYXRlcycsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBvdXRwdXQgPVxuICAgICAgYXR0cmlidXRlcy5yZWR1Y3Rpb24gIT09ICdub25lJyAmJiBhdHRyaWJ1dGVzLnJlZHVjdGlvbiAhPT0gJydcbiAgICAgICAgPyBhdG9taWNPdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpXG4gICAgICAgIDogb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoLCBjb21wb25lbnRzKTtcblxuICAgIHJldHVybiBgXG4gICAgICAke3NoYWRlckhlbHBlclxuICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdvdXRwdXRfc2l6ZScsICd1MzInKVxuICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdsYXN0X2luZGV4X2RpbWVuc2lvbicsICd1MzInKVxuICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdudW1fdXBkYXRlc19lbGVtZW50cycsICd1MzInKVxuICAgICAgICAuZGVjbGFyZVZhcmlhYmxlcyhpbmRpY2VzLCB1cGRhdGVzLCBvdXRwdXQpfVxuICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gIHZhciBkYXRhX29mZnNldCA9IDB1O1xuICBsZXQgaW5kaWNlc19zdGFydCA9IHVuaWZvcm1zLmxhc3RfaW5kZXhfZGltZW5zaW9uICogZ2xvYmFsX2lkeDtcbiAgbGV0IGluZGljZXNfZW5kID0gaW5kaWNlc19zdGFydCArIHVuaWZvcm1zLmxhc3RfaW5kZXhfZGltZW5zaW9uO1xuICBmb3IgKHZhciBpID0gaW5kaWNlc19zdGFydDsgaSA8IGluZGljZXNfZW5kOyBpKyspIHtcbiAgICB2YXIgaW5kZXggPSBpMzIoaW5kaWNlc1tpXS54KTtcbiAgICAke1xuICAgICAgaW5wdXRzWzBdLmRpbXMubGVuZ3RoID09PSAxXG4gICAgICAgID8gYFxuICAgIGxldCBlbGVtZW50X2NvdW50X2RpbSA9IHVuaWZvcm1zLm91dHB1dF9zdHJpZGVzO1xuICAgIGxldCBkaW1fdmFsdWUgPSB1bmlmb3Jtcy5vdXRwdXRfc2hhcGU7YFxuICAgICAgICA6IGBcbiAgICBsZXQgZWxlbWVudF9jb3VudF9kaW0gPSB1bmlmb3Jtcy5vdXRwdXRfc3RyaWRlc1tpIC0gaW5kaWNlc19zdGFydF07XG4gICAgbGV0IGRpbV92YWx1ZSA9IHVuaWZvcm1zLm91dHB1dF9zaGFwZVtpIC0gaW5kaWNlc19zdGFydF07YFxuICAgIH1cbiAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgaWYgKGluZGV4ID49IGkzMihkaW1fdmFsdWUpKSB7XG4gICAgICAgIGluZGV4ID0gaTMyKGRpbV92YWx1ZSAtIDEpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaW5kZXggPCAtaTMyKGRpbV92YWx1ZSkpIHtcbiAgICAgICAgaW5kZXggPSAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW5kZXggKz0gaTMyKGRpbV92YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGRhdGFfb2Zmc2V0ICs9IHUzMigodTMyKGluZGV4KSAqIGVsZW1lbnRfY291bnRfZGltKSk7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMHU7IGkgPCB1bmlmb3Jtcy5udW1fdXBkYXRlc19lbGVtZW50czsgaSsrKSB7XG4gICAgbGV0IHZhbHVlID0gdXBkYXRlc1t1bmlmb3Jtcy5udW1fdXBkYXRlc19lbGVtZW50cyAqIGdsb2JhbF9pZHggKyBpXTtcbiAgICAke2F0b21pY1JlZHVjdGlvblNuaXBwZXQoXG4gICAgICBhdHRyaWJ1dGVzLnJlZHVjdGlvbixcbiAgICAgICdvdXRwdXRbZGF0YV9vZmZzZXQgKyBpXScsXG4gICAgICAndmFsdWUnLFxuICAgICAgb3V0cHV0LnR5cGUudmFsdWUgYXMgUmVkdWN0aW9uVHlwZSxcbiAgICApfVxuICB9XG5cbiAgICAgIH1gO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdTY2F0dGVyTkQnLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fV8ke2F0dHJpYnV0ZXMucmVkdWN0aW9ufWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llczogWydyYW5rJywgJ3JhbmsnXSxcbiAgICB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTY2F0dGVyTkRBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogU2NhdHRlck5EQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyByZWR1Y3Rpb246IGF0dHJpYnV0ZXMucmVkdWN0aW9uIGFzIHN0cmluZyB9KTtcblxuZXhwb3J0IGNvbnN0IHNjYXR0ZXJORCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogU2NhdHRlck5EQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlU2NhdHRlck5EUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpLCB7XG4gICAgaW5wdXRzOiBbY29udGV4dC5pbnB1dHNbMV0sIGNvbnRleHQuaW5wdXRzWzJdXSxcbiAgICBvdXRwdXRzOiBbXSxcbiAgfSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbyB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIGdldEVsZW1lbnRBdCxcbiAgSW5kaWNlc0hlbHBlcixcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbn0gZnJvbSAnLi9jb21tb24nO1xuXG50eXBlIENvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlID1cbiAgfCAnaGFsZl9waXhlbCdcbiAgfCAnYXN5bW1ldHJpYydcbiAgfCAncHl0b3JjaF9oYWxmX3BpeGVsJ1xuICB8ICd0Zl9oYWxmX3BpeGVsX2Zvcl9ubidcbiAgfCAnYWxpZ25fY29ybmVycydcbiAgfCAndGZfY3JvcF9hbmRfcmVzaXplJ1xuICB8ICdoYWxmX3BpeGVsX3N5bW1ldHJpYyc7XG5cbnR5cGUgS2VlcEFzcGVjdFJhdGlvUG9saWN5ID0gJ3N0cmV0Y2gnIHwgJ25vdF9zbWFsbGVyJyB8ICdub3RfbGFyZ2VyJztcblxudHlwZSBNb2RlID0gJ25lYXJlc3QnIHwgJ2xpbmVhcicgfCAnY3ViaWMnO1xuXG50eXBlIE5lYXJlc3RNb2RlID0gJ3JvdW5kX3ByZWZlcl9mbG9vcicgfCAncm91bmRfcHJlZmVyX2NlaWwnIHwgJ2Zsb29yJyB8ICdjZWlsJyB8ICdzaW1wbGUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlc2l6ZUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBhbnRpYWxpYXM6IG51bWJlcjtcbiAgYXhlczogbnVtYmVyW107XG4gIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlOiBDb29yZGluYXRlVHJhbnNmb3JtTW9kZTtcbiAgY3ViaWNDb2VmZkE6IG51bWJlcjtcbiAgZXhjbHVkZU91dHNpZGU6IGJvb2xlYW47XG4gIGV4dHJhcG9sYXRpb25WYWx1ZTogbnVtYmVyO1xuICBrZWVwQXNwZWN0UmF0aW9Qb2xpY3k6IEtlZXBBc3BlY3RSYXRpb1BvbGljeTtcbiAgbW9kZTogTW9kZTtcbiAgbmVhcmVzdE1vZGU6IE5lYXJlc3RNb2RlO1xufVxuXG5jb25zdCB2YWxpZGF0ZVNjYWxlcyA9IChzY2FsZXM6IG51bWJlcltdLCBhdHRyaWJ1dGVzOiBSZXNpemVBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHNjYWxlcy5ldmVyeShcbiAgICAodmFsdWUpID0+XG4gICAgICB2YWx1ZSA+IDAgfHxcbiAgICAgICgoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUmVzaXplIHJlcXVpcmVzIHNjYWxlcyBpbnB1dCB2YWx1ZXMgdG8gYmUgcG9zaXRpdmUnKTtcbiAgICAgIH0pLFxuICApO1xuICAvLyBDaGVjayBzY2FsZXMgZGltcyBiYXNlZCBvbiBtb2RlOiBMSU5FQVIsIENVQklDXG4gIGlmIChzY2FsZXMubGVuZ3RoID4gMCkge1xuICAgIGlmIChhdHRyaWJ1dGVzLm1vZGUgPT09ICdsaW5lYXInKSB7XG4gICAgICBpZiAoXG4gICAgICAgICEoXG4gICAgICAgICAgc2NhbGVzLmxlbmd0aCA9PT0gMiB8fFxuICAgICAgICAgIHNjYWxlcy5sZW5ndGggPT09IDMgfHxcbiAgICAgICAgICAoc2NhbGVzLmxlbmd0aCA9PT0gNCAmJiBzY2FsZXNbMF0gPT09IDEgJiYgc2NhbGVzWzFdID09PSAxKSB8fFxuICAgICAgICAgIChzY2FsZXMubGVuZ3RoID09PSA0ICYmIHNjYWxlc1swXSA9PT0gMSAmJiBzY2FsZXNbM10gPT09IDEpIHx8XG4gICAgICAgICAgKHNjYWxlcy5sZW5ndGggPT09IDUgJiYgc2NhbGVzWzBdID09PSAxICYmIHNjYWxlc1sxXSA9PT0gMSlcbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgRm9yIGxpbmVhciBtb2RlLCBSZXNpemUgcmVxdWlyZXMgc2NhbGVzIHRvIGJlIDJELCAzRCwgNEQgd2l0aCBlaXRoZXIgdHdvIG91dGVybW9zdCBvciBvbmUgaW5uZXJtb3N0IGFuZFxuICAgICAgICAgICAgb25lIG91dGVybW9zdCBzY2FsZSB2YWx1ZXMgZXF1YWwgdG8gMSwgb3IgNUQgd2l0aCB0d28gb3V0ZXJtb3N0IHNjYWxlIHZhbHVlcyBlcXVhbCB0byAxYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGF0dHJpYnV0ZXMubW9kZSA9PT0gJ2N1YmljJykge1xuICAgICAgaWYgKFxuICAgICAgICAhKFxuICAgICAgICAgIHNjYWxlcy5sZW5ndGggPT09IDIgfHxcbiAgICAgICAgICAoc2NhbGVzLmxlbmd0aCA9PT0gNCAmJiBzY2FsZXNbMF0gPT09IDEgJiYgc2NhbGVzWzFdID09PSAxKSB8fFxuICAgICAgICAgIChzY2FsZXMubGVuZ3RoID09PSA0ICYmIHNjYWxlc1swXSA9PT0gMSAmJiBzY2FsZXNbM10gPT09IDEpXG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jlc2l6ZSByZXF1aXJlcyBzY2FsZXMgaW5wdXQgc2l6ZSB0byBiZSAyIG9yIDQgZm9yIGN1YmljIG1vZGUnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cbmNvbnN0IHVwZGF0ZVNjYWxlcyA9IChzY2FsZXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGVzOiByZWFkb25seSBudW1iZXJbXSwgcmFuazogbnVtYmVyKTogbnVtYmVyW10gPT4ge1xuICBheGVzLmV2ZXJ5KFxuICAgICh2YWx1ZSkgPT5cbiAgICAgICh2YWx1ZSA+PSAwICYmIHZhbHVlIDwgcmFuaykgfHxcbiAgICAgICgoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUmVzaXplIHJlcXVpcmVzIGF4ZXMgaW5wdXQgdmFsdWVzIHRvIGJlIHBvc2l0aXZlIGFuZCBsZXNzIHRoYW4gcmFuaycpO1xuICAgICAgfSksXG4gICk7XG4gIGNvbnN0IG5ld1NjYWxlcyA9IG5ldyBBcnJheShyYW5rKS5maWxsKDEuMCk7XG4gIGF4ZXMuZm9yRWFjaCgodmFsdWUsIGluZGV4KSA9PiAobmV3U2NhbGVzW3ZhbHVlXSA9IHNjYWxlc1tpbmRleF0pKTtcbiAgcmV0dXJuIG5ld1NjYWxlcztcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogUmVzaXplQXR0cmlidXRlcyxcbiAgb3BzZXRWZXJzaW9uOiBudW1iZXIsXG4gIHNjYWxlczogbnVtYmVyW10sXG4gIHNpemVzOiBudW1iZXJbXSxcbiAgcm9pOiBudW1iZXJbXSxcbik6IHZvaWQgPT4ge1xuICBjb25zdCBbcm9pSW5wdXRJbmRleCwgc2NhbGVzSW5wdXRJbmRleCwgc2l6ZXNJbnB1dEluZGV4XSA9XG4gICAgb3BzZXRWZXJzaW9uID4gMTAgPyBbMSwgMiwgM10gOiBbLTEsIGlucHV0cy5sZW5ndGggPiAxID8gMSA6IC0xLCAtMV07XG4gIGNvbnN0IHJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGlmIChyb2lJbnB1dEluZGV4ID4gMCAmJiBpbnB1dHMubGVuZ3RoID4gcm9pSW5wdXRJbmRleCAmJiBpbnB1dHNbcm9pSW5wdXRJbmRleF0uZGltcy5sZW5ndGggPiAwKSB7XG4gICAgaW5wdXRzW3JvaUlucHV0SW5kZXhdLmdldEZsb2F0MzJBcnJheSgpLmZvckVhY2goKHZhbHVlKSA9PiByb2kucHVzaCh2YWx1ZSkpO1xuICB9IGVsc2UgaWYgKGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPT09ICd0Zl9jcm9wX2FuZF9yZXNpemUnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZXNpemUgcmVxdWlyZXMgUm9JIGlucHV0IHRvIGJlIHNwZWNpZmllZCB3aGVuIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlIGlzIHRmQ3JvcEFuZFJlc2l6ZScpO1xuICB9XG5cbiAgaWYgKFxuICAgIHNjYWxlc0lucHV0SW5kZXggPiAwICYmXG4gICAgaW5wdXRzLmxlbmd0aCA+IHNjYWxlc0lucHV0SW5kZXggJiZcbiAgICBpbnB1dHNbc2NhbGVzSW5wdXRJbmRleF0uZGltcy5sZW5ndGggPT09IDEgJiZcbiAgICBpbnB1dHNbc2NhbGVzSW5wdXRJbmRleF0uZGltc1swXSA+IDBcbiAgKSB7XG4gICAgaW5wdXRzW3NjYWxlc0lucHV0SW5kZXhdLmdldEZsb2F0MzJBcnJheSgpLmZvckVhY2goKHZhbHVlKSA9PiBzY2FsZXMucHVzaCh2YWx1ZSkpO1xuICAgIGlmIChcbiAgICAgIHNjYWxlcy5sZW5ndGggIT09IDAgJiZcbiAgICAgIHNjYWxlcy5sZW5ndGggIT09IHJhbmsgJiZcbiAgICAgIG9wc2V0VmVyc2lvbiA+PSAxOCAmJlxuICAgICAgc2NhbGVzLmxlbmd0aCAhPT0gYXR0cmlidXRlcy5heGVzLmxlbmd0aFxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZXNpemUgcmVxdWlyZXMgc2NhbGVzIGlucHV0IHNpemUgdG8gYmUgc2FtZSBhcyBpbnB1dCByYW5rIG9yIGF4ZXMgc2l6ZSBmb3Igb3BzZXQgMTggYW5kIHVwJyk7XG4gICAgfVxuICAgIHZhbGlkYXRlU2NhbGVzKHNjYWxlcywgYXR0cmlidXRlcyk7XG4gICAgaWYgKGF0dHJpYnV0ZXMuYXhlcy5sZW5ndGggPiAwKSB7XG4gICAgICB1cGRhdGVTY2FsZXMoc2NhbGVzLCBhdHRyaWJ1dGVzLmF4ZXMsIHJhbmspLmZvckVhY2goKHZhbHVlLCBpbmRleCkgPT4gKHNjYWxlc1tpbmRleF0gPSB2YWx1ZSkpO1xuICAgIH1cbiAgfVxuICBpZiAoXG4gICAgc2l6ZXNJbnB1dEluZGV4ID4gMCAmJlxuICAgIGlucHV0cy5sZW5ndGggPiBzaXplc0lucHV0SW5kZXggJiZcbiAgICBpbnB1dHNbc2l6ZXNJbnB1dEluZGV4XS5kaW1zLmxlbmd0aCA9PT0gMSAmJlxuICAgIGlucHV0c1tzaXplc0lucHV0SW5kZXhdLmRpbXNbMF0gPiAwXG4gICkge1xuICAgIGlucHV0c1tzaXplc0lucHV0SW5kZXhdLmdldEJpZ0ludDY0QXJyYXkoKS5mb3JFYWNoKCh2YWx1ZSkgPT4gc2l6ZXMucHVzaChOdW1iZXIodmFsdWUpKSk7XG4gICAgaWYgKHNpemVzLmxlbmd0aCAhPT0gMCAmJiBzaXplcy5sZW5ndGggIT09IHJhbmsgJiYgb3BzZXRWZXJzaW9uID49IDE4ICYmIHNpemVzLmxlbmd0aCAhPT0gYXR0cmlidXRlcy5heGVzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZXNpemUgcmVxdWlyZXMgc2l6ZXMgaW5wdXQgc2l6ZSB0byBiZSBzYW1lIGFzIGlucHV0IHJhbmsgb3IgYXhlcyBzaXplIGZvciBvcHNldCAxOCBhbmQgdXAnKTtcbiAgICB9XG4gIH1cblxuICBpZiAoYXR0cmlidXRlcy5heGVzLmxlbmd0aCA+IDApIHtcbiAgICBpZiAoc2NhbGVzLmxlbmd0aCAhPT0gMCAmJiBzY2FsZXMubGVuZ3RoICE9PSBhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jlc2l6ZSByZXF1aXJlcyBcInNjYWxlc1wiIGlucHV0IHNpemUgdG8gYmUgb2YgYXhlcyByYW5rIHdoZW4gYXhlcyBhdHRyaWJ1dGVzIGlzIHNwZWNpZmllZCcpO1xuICAgIH1cbiAgICBpZiAoc2l6ZXMubGVuZ3RoICE9PSAwICYmIHNpemVzLmxlbmd0aCAhPT0gYXR0cmlidXRlcy5heGVzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZXNpemUgcmVxdWlyZXMgXCJzaXplc1wiIGlucHV0IHNpemUgdG8gYmUgb2YgcmFuayBheGVzIHJhbmsgd2hlbiBheGVzIGF0dHJpYnV0ZXMgaXMgc3BlY2lmaWVkJyk7XG4gICAgfVxuICB9XG4gIGlmICh0eXBlb2Ygc2NhbGVzICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygc2l6ZXMgIT09ICd1bmRlZmluZWQnICYmIHNjYWxlcy5sZW5ndGggPiAwICYmIHNpemVzLmxlbmd0aCA+IHJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jlc2l6ZSByZXF1aXJlcyBvbmx5IG9mIHNjYWxlcyBvciBzaXplcyB0byBiZSBzcGVjaWZpZWQnKTtcbiAgfVxufTtcblxuY29uc3QgZ2V0U2FmZUludGVnZXJEaXZpc2lvbiA9IChhOiBzdHJpbmcsIGI6IHN0cmluZywgYzogc3RyaW5nLCBkVHlwZTogc3RyaW5nKTogc3RyaW5nID0+IGBcbiAgLy8gVGhlIHdob2xlIHBhcnQgYW5kIHRoZSBmcmFjdGlvbmFsIHBhcnQgYXJlIGNhbGN1bGF0ZWQgc2VwYXJhdGVseSBkdWUgdG8gaW5hY2N1cmFjeSBvZiBmbG9hdGluZ1xuICAvLyBwb2ludCBkaXZpc2lvbi4gQXMgYW4gZXhhbXBsZSwgZjMyKDIxKSAvIGYzMig3KSBtYXkgZXZhbHVhdGUgdG8gMi45OS4uLiBpbnN0ZWFkIG9mIDMsIGNhdXNpbmcgYW5cbiAgLy8gb2Zmc2V0LWJ5LW9uZSBlcnJvciBsYXRlciBpbiBmbG9vcigpLlxuICBsZXQgYmlnID0gKCR7YX0pICogKCR7Yn0pO1xuICBsZXQgd2hvbGUgPSAke2RUeXBlfShiaWcgLyAoJHtjfSkpO1xuICBsZXQgZnJhY3QgPSAke2RUeXBlfShiaWcgJSAoJHtjfSkpIC8gJHtkVHlwZX0oJHtjfSk7XG4gIHJldHVybiB3aG9sZSArIGZyYWN0O1xuYDtcblxuY29uc3QgZ2V0T3JpZ2luYWxDb29yZGluYXRlRnJvbVJlc2l6ZWRDb29yZGluYXRlID0gKFxuICBjb29yZGluYXRlVHJhbnNmZXJNb2RlOiBDb29yZGluYXRlVHJhbnNmb3JtTW9kZSxcbiAgZFR5cGU6IHN0cmluZyxcbik6IHN0cmluZyA9PlxuICBgZm4gZ2V0T3JpZ2luYWxDb29yZGluYXRlRnJvbVJlc2l6ZWRDb29yZGluYXRlKHhSZXNpemVkOiB1MzIsIHhTY2FsZTogZjMyLCBsZW5ndGhSZXNpemVkOiB1MzIsXG4gICAgIGxlbmd0aE9yaWdpbmFsOiB1MzIsIHJvaVN0YXJ0OiBmMzIsIHJvaUVuZDogZjMyKSAtPiAke2RUeXBlfSB7IGAgK1xuICAoKCkgPT4ge1xuICAgIHN3aXRjaCAoY29vcmRpbmF0ZVRyYW5zZmVyTW9kZSkge1xuICAgICAgY2FzZSAnYXN5bW1ldHJpYyc6XG4gICAgICAgIHJldHVybiBgXG4gICAgICAgICAgaWYgKHhTY2FsZSA8IDEuMCB8fCBmbG9vcih4U2NhbGUpICE9IHhTY2FsZSkge1xuICAgICAgICAgICAgcmV0dXJuICR7ZFR5cGV9KHhSZXNpemVkKSAvICR7ZFR5cGV9KHhTY2FsZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICR7Z2V0U2FmZUludGVnZXJEaXZpc2lvbigneFJlc2l6ZWQnLCAnbGVuZ3RoT3JpZ2luYWwnLCAnbGVuZ3RoUmVzaXplZCcsIGRUeXBlKX1cbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICBjYXNlICdweXRvcmNoX2hhbGZfcGl4ZWwnOlxuICAgICAgICByZXR1cm4gYGlmIChsZW5ndGhSZXNpemVkID4gMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCR7ZFR5cGV9KHhSZXNpemVkKSArIDAuNSkgLyAke2RUeXBlfSh4U2NhbGUpIC0gMC41O1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDAuMDtcbiAgICAgICAgICAgICAgICAgIH1gO1xuICAgICAgY2FzZSAndGZfaGFsZl9waXhlbF9mb3Jfbm4nOlxuICAgICAgICByZXR1cm4gYHJldHVybiAoJHtkVHlwZX0oeFJlc2l6ZWQpICsgMC41KSAvICR7ZFR5cGV9KHhTY2FsZSk7YDtcbiAgICAgIGNhc2UgJ2FsaWduX2Nvcm5lcnMnOlxuICAgICAgICByZXR1cm4gYGlmIChsZW5ndGhSZXNpemVkID09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDAuMDtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICR7Z2V0U2FmZUludGVnZXJEaXZpc2lvbigneFJlc2l6ZWQnLCAnbGVuZ3RoT3JpZ2luYWwgLSAxJywgJ2xlbmd0aFJlc2l6ZWQgLSAxJywgZFR5cGUpfVxuICAgICAgICAgICAgICAgICAgfWA7XG4gICAgICBjYXNlICd0Zl9jcm9wX2FuZF9yZXNpemUnOlxuICAgICAgICByZXR1cm4gYGlmIChsZW5ndGhSZXNpemVkID4gMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHtkVHlwZX0ocm9pU3RhcnQpICogJHtkVHlwZX0obGVuZ3RoT3JpZ2luYWwgLSAxKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAoJHtkVHlwZX0oeFJlc2l6ZWQpICogJHtkVHlwZX0ocm9pRW5kIC0gcm9pU3RhcnQpICogJHtkVHlwZX0obGVuZ3RoT3JpZ2luYWwgLSAxKSkgL1xuICAgICAgICAgICAgICAgICAgICAgICAgJHtkVHlwZX0obGVuZ3RoUmVzaXplZCAtIDEpO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDAuNSAqICR7ZFR5cGV9KHJvaVN0YXJ0ICsgcm9pRW5kKSAqICR7ZFR5cGV9KGxlbmd0aE9yaWdpbmFsIC0gMSk7XG4gICAgICAgICAgICAgICAgICB9YDtcbiAgICAgIGNhc2UgJ2hhbGZfcGl4ZWxfc3ltbWV0cmljJzpcbiAgICAgICAgcmV0dXJuIGBjb25zdCBvdXRwdXRXaWR0aCA9ICR7ZFR5cGV9eFNjYWxlICogJHtkVHlwZX0obGVuZ3RoUmVzaXplZCk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBhZGp1c3RtZW50ID0gJHtkVHlwZX0obGVuZ3RoUmVzaXplZCkgLyBvdXRwdXRXaWR0aDtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGNlbnRlciA9ICR7ZFR5cGV9KGxlbmd0aE9yaWdpbmFsKSAvIDI7XG4gICAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXQgPSBjZW50ZXIgKiAoMSAtIGFkanVzdG1lbnQpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mZnNldCArICgoJHtkVHlwZX0oeFJlc2l6ZWQpICsgMC41KSAvICR7ZFR5cGV9KHhTY2FsZSkpIC0gMC41O2A7XG4gICAgICBjYXNlICdoYWxmX3BpeGVsJzpcbiAgICAgICAgcmV0dXJuIGByZXR1cm4gKCgke2RUeXBlfSh4UmVzaXplZCkgKyAwLjUpIC8gJHtkVHlwZX0oeFNjYWxlKSkgLSAwLjU7YDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ29vcmRpbmF0ZSB0cmFuc2Zvcm0gbW9kZSAke2Nvb3JkaW5hdGVUcmFuc2Zlck1vZGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICB9XG4gIH0pKCkgK1xuICAnfSc7XG5cbmNvbnN0IGdldE5lYXJlc3RQaXhlbEZyb21PcmlnaW5hbCA9IChuZWFyZXN0TW9kZTogTmVhcmVzdE1vZGUsIG9wc2V0VmVyc2lvbjogbnVtYmVyLCBkVHlwZTogc3RyaW5nKTogc3RyaW5nID0+XG4gIGBmbiBnZXROZWFyZXN0UGl4ZWxGcm9tT3JpZ2luYWwoeE9yaWdpbmFsOiAke2RUeXBlfSwgaXNEb3duU2FtcGxlOiBib29sKSAtPiAke2RUeXBlfSB7YCArXG4gICgoKSA9PiB7XG4gICAgc3dpdGNoIChuZWFyZXN0TW9kZSkge1xuICAgICAgY2FzZSAncm91bmRfcHJlZmVyX2NlaWwnOlxuICAgICAgICByZXR1cm4gJ2lmIChmcmFjdCh4T3JpZ2luYWwpID09IDAuNSkgeyBcXFxuICAgICAgICAgICAgcmV0dXJuIGNlaWwoeE9yaWdpbmFsKTsgXFxcbiAgICAgICAgICB9IGVsc2UgeyBcXFxuICAgICAgICAgICAgcmV0dXJuIHJvdW5kKHhPcmlnaW5hbCk7IFxcXG4gICAgICAgICAgfSc7XG4gICAgICBjYXNlICdmbG9vcic6XG4gICAgICAgIHJldHVybiAncmV0dXJuIGZsb29yKHhPcmlnaW5hbCk7JztcbiAgICAgIGNhc2UgJ2NlaWwnOlxuICAgICAgICByZXR1cm4gJ3JldHVybiBjZWlsKHhPcmlnaW5hbCk7JztcbiAgICAgIGNhc2UgJ3JvdW5kX3ByZWZlcl9mbG9vcic6XG4gICAgICAgIHJldHVybiAnaWYgKGZyYWN0KHhPcmlnaW5hbCkgPT0gMC41KSB7IFxcXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmbG9vcih4T3JpZ2luYWwpOyBcXFxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgXFxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJvdW5kKHhPcmlnaW5hbCk7IFxcXG4gICAgICAgICAgICAgICAgICB9JztcbiAgICAgIGNhc2UgJ3NpbXBsZSc6XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAob3BzZXRWZXJzaW9uIDwgMTEpIHtcbiAgICAgICAgICByZXR1cm4gJ2lmIChpc0Rvd25TYW1wbGUpIFxcXG4gICAgICAgICAgICAgICAgICAgIHsgXFxcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2VpbCh4T3JpZ2luYWwpOyBcXFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyBcXFxuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB4T3JpZ2luYWw7IFxcXG4gICAgICAgICAgICAgICAgICAgIH0nO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTmVhcmVzdCBtb2RlICR7bmVhcmVzdE1vZGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICB9XG4gIH0pKCkgK1xuICAnfSc7XG5cbmNvbnN0IHVwZGF0ZVJvSSA9IChyb2k6IHJlYWRvbmx5IG51bWJlcltdLCBheGVzOiByZWFkb25seSBudW1iZXJbXSwgcmFuazogbnVtYmVyKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCByb2lUbXAgPSBuZXcgQXJyYXkocmFuaykuZmlsbCgwKS5jb25jYXQobmV3IEFycmF5KHJhbmspLmZpbGwoMSkpO1xuICBjb25zdCByb2lMb2NhbCA9IHJvaS5sZW5ndGggPT09IDAgPyByb2lUbXAgOiByb2kuc2xpY2UoKTtcbiAgaWYgKGF4ZXMubGVuZ3RoID4gMCkge1xuICAgIGF4ZXMuZm9yRWFjaCgodiwgaSkgPT4ge1xuICAgICAgcm9pVG1wW3ZdID0gcm9pTG9jYWxbaV07XG4gICAgICByb2lUbXBbaSArIHJhbmtdID0gcm9pTG9jYWxbYXhlcy5sZW5ndGggKyBpXTtcbiAgICB9KTtcbiAgICByZXR1cm4gcm9pVG1wO1xuICB9XG4gIHJldHVybiByb2lMb2NhbDtcbn07XG5cbmNvbnN0IGluaXRPdXRwdXRTaGFwZSA9IChcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHNjYWxlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHNpemVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXhlczogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBudW1iZXJbXSA9PiB7XG4gIGxldCBvdXRwdXRTaGFwZTogbnVtYmVyW10gPSBbXTtcbiAgaWYgKHNpemVzLmxlbmd0aCA+IDApIHtcbiAgICBpZiAoYXhlcy5sZW5ndGggPiAwKSB7XG4gICAgICBpbnB1dFNoYXBlLmZvckVhY2goKHYpID0+IG91dHB1dFNoYXBlLnB1c2godikpO1xuICAgICAgaWYgKE1hdGgubWF4KC4uLmF4ZXMpID4gaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdheGVzIGlzIG91dCBvZiBib3VuZCcpO1xuICAgICAgfVxuICAgICAgYXhlcy5mb3JFYWNoKCh2LCBpKSA9PiAob3V0cHV0U2hhcGVbdl0gPSBzaXplc1tpXSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzaXplcy5mb3JFYWNoKCh2KSA9PiBvdXRwdXRTaGFwZS5wdXNoKHYpKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKHNjYWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUmVzaXplIHJlcXVpcmVzIGVpdGhlciBzY2FsZXMgb3Igc2l6ZXMuJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dFNoYXBlID0gaW5wdXRTaGFwZS5tYXAoKHZhbHVlLCBpbmRleCkgPT4gTWF0aC5yb3VuZCh2YWx1ZSAqIHNjYWxlc1tpbmRleF0pKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dHB1dFNoYXBlO1xufTtcblxuY29uc3QgYWRqdXN0T3V0cHV0U2hhcGUgPSAoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHNjYWxlczogbnVtYmVyW10sIGF0dHJpYnV0ZXM6IFJlc2l6ZUF0dHJpYnV0ZXMpID0+IHtcbiAgY29uc3Qgc2NhbGVJblBvbGljeSA9ICgoKSA9PiB7XG4gICAgc3dpdGNoIChhdHRyaWJ1dGVzLmtlZXBBc3BlY3RSYXRpb1BvbGljeSkge1xuICAgICAgY2FzZSAnbm90X2xhcmdlcic6XG4gICAgICAgIHJldHVybiBhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoID4gMFxuICAgICAgICAgID8gTWF0aC5taW4oLi4uYXR0cmlidXRlcy5heGVzLm1hcCgoaSkgPT4gc2NhbGVzW2ldKSwgTnVtYmVyLk1BWF9WQUxVRSlcbiAgICAgICAgICA6IE1hdGgubWluKC4uLnNjYWxlcywgTnVtYmVyLk1BWF9WQUxVRSk7XG4gICAgICBjYXNlICdub3Rfc21hbGxlcic6XG4gICAgICAgIHJldHVybiBhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoID4gMFxuICAgICAgICAgID8gTWF0aC5tYXgoLi4uYXR0cmlidXRlcy5heGVzLm1hcCgoaSkgPT4gc2NhbGVzW2ldKSwgTnVtYmVyLk1JTl9WQUxVRSlcbiAgICAgICAgICA6IE1hdGgubWF4KC4uLnNjYWxlcywgTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEtlZXAgYXNwZWN0IHJhdGlvIHBvbGljeSAke2F0dHJpYnV0ZXMua2VlcEFzcGVjdFJhdGlvUG9saWN5fSBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gICAgfVxuICB9KSgpO1xuICBzY2FsZXMuZmlsbCgxLjAsIDAsIHNjYWxlcy5sZW5ndGgpO1xuICBjb25zdCBhZGp1c3RlZE91dHB1dFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZSgpO1xuICBpZiAoYXR0cmlidXRlcy5heGVzLmxlbmd0aCA+IDApIHtcbiAgICBhdHRyaWJ1dGVzLmF4ZXMuZm9yRWFjaCgodikgPT4gKHNjYWxlc1t2XSA9IHNjYWxlSW5Qb2xpY3kpKTtcbiAgICBhdHRyaWJ1dGVzLmF4ZXMuZm9yRWFjaCgodikgPT4gKGFkanVzdGVkT3V0cHV0U2hhcGVbdl0gPSBNYXRoLnJvdW5kKGlucHV0U2hhcGVbdl0gKiBzY2FsZXNbdl0pKSk7XG4gIH0gZWxzZSB7XG4gICAgc2NhbGVzLmZpbGwoc2NhbGVJblBvbGljeSwgMCwgc2NhbGVzLmxlbmd0aCk7XG4gICAgYWRqdXN0ZWRPdXRwdXRTaGFwZS5mb3JFYWNoKCh2LCBpKSA9PiAoYWRqdXN0ZWRPdXRwdXRTaGFwZVtpXSA9IE1hdGgucm91bmQodiAqIHNjYWxlc1tpXSkpKTtcbiAgfVxuICByZXR1cm4gYWRqdXN0ZWRPdXRwdXRTaGFwZTtcbn07XG5cbmNvbnN0IGNhbGN1bGF0ZU9yaWdpbmFsSW5kaWNlc0Zyb21PdXRwdXRJbmRpY2VzID0gKFxuICBvdXRwdXQ6IEluZGljZXNIZWxwZXIsXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHNjYWxlc0xlbmd0aDogbnVtYmVyLFxuICByb2lMZW5ndGg6IG51bWJlcixcbik6IHN0cmluZyA9PiBgXG4gICAgZm4gY2FsY3VsYXRlT3JpZ2luYWxJbmRpY2VzRnJvbU91dHB1dEluZGljZXMob3V0cHV0X2luZGljZXM6ICR7b3V0cHV0LnR5cGUuaW5kaWNlc30pIC0+IGFycmF5PCR7XG4gICAgICBvdXRwdXQudHlwZS52YWx1ZVxuICAgIH0sICR7b3V0cHV0U2hhcGUubGVuZ3RofT4ge1xuICAgICAgdmFyIG9yaWdpbmFsX2luZGljZXM6IGFycmF5PCR7b3V0cHV0LnR5cGUudmFsdWV9LCAke291dHB1dFNoYXBlLmxlbmd0aH0+O1xuICAgICAgZm9yICh2YXIgaTp1MzIgPSAwOyBpIDwgJHtvdXRwdXRTaGFwZS5sZW5ndGh9OyBpKyspIHtcbiAgICAgICAgdmFyIG91dHB1dF9pbmRleCA9ICR7b3V0cHV0LmluZGljZXNHZXQoJ291dHB1dF9pbmRpY2VzJywgJ2knKX07XG4gICAgICAgIHZhciBzY2FsZSA9ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5zY2FsZXMnLCAnaScsIHNjYWxlc0xlbmd0aCl9O1xuICAgICAgICB2YXIgcm9pX2xvdyA9ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5yb2knLCAnaScsIHJvaUxlbmd0aCl9O1xuICAgICAgICB2YXIgcm9pX2hpID0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnJvaScsIGBpICsgJHtpbnB1dFNoYXBlLmxlbmd0aH1gLCByb2lMZW5ndGgpfTtcbiAgICAgICAgaWYgKHNjYWxlID09IDEuMCkge1xuICAgICAgICAgIG9yaWdpbmFsX2luZGljZXNbaV0gPSAke291dHB1dC50eXBlLnZhbHVlfShvdXRwdXRfaW5kZXgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBpbnB1dF9zaGFwZV9pID0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLmlucHV0X3NoYXBlJywgJ2knLCBpbnB1dFNoYXBlLmxlbmd0aCl9O1xuICAgICAgICAgIHZhciBvdXRwdXRfc2hhcGVfaSA9ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5vdXRwdXRfc2hhcGUnLCAnaScsIG91dHB1dFNoYXBlLmxlbmd0aCl9O1xuICAgICAgICAgIG9yaWdpbmFsX2luZGljZXNbaV0gPSBnZXRPcmlnaW5hbENvb3JkaW5hdGVGcm9tUmVzaXplZENvb3JkaW5hdGUob3V0cHV0X2luZGV4LCBzY2FsZSwgb3V0cHV0X3NoYXBlX2ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dF9zaGFwZV9pLCByb2lfbG93LCByb2lfaGkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gb3JpZ2luYWxfaW5kaWNlcztcbiAgICB9YDtcblxuY29uc3QgY2FsY3VsYXRlSW5wdXRJbmRpY2VzRnJvbU91dHB1dEluZGljZXMgPSAoXG4gIGlucHV0OiBJbmRpY2VzSGVscGVyLFxuICBvdXRwdXQ6IEluZGljZXNIZWxwZXIsXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHNjYWxlc0xlbmd0aDogbnVtYmVyLFxuICByb2lMZW5ndGg6IG51bWJlcixcbiAgdXNlRXh0cmFwb2xhdGlvbjogYm9vbGVhbixcbik6IHN0cmluZyA9PiBgXG4gICAgZm4gY2FsY3VsYXRlSW5wdXRJbmRpY2VzRnJvbU91dHB1dEluZGljZXMob3V0cHV0X2luZGljZXM6ICR7b3V0cHV0LnR5cGUuaW5kaWNlc30pIC0+ICR7aW5wdXQudHlwZS5pbmRpY2VzfSB7XG4gICAgICB2YXIgaW5wdXRfaW5kaWNlczogJHtpbnB1dC50eXBlLmluZGljZXN9O1xuICAgICAgZm9yICh2YXIgaTp1MzIgPSAwOyBpIDwgJHtvdXRwdXRTaGFwZS5sZW5ndGh9OyBpKyspIHtcbiAgICAgICAgdmFyIG91dHB1dF9pbmRleCA9ICR7b3V0cHV0LmluZGljZXNHZXQoJ291dHB1dF9pbmRpY2VzJywgJ2knKX07XG4gICAgICAgIHZhciBpbnB1dF9pbmRleDogdTMyO1xuICAgICAgICB2YXIgc2NhbGUgPSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMuc2NhbGVzJywgJ2knLCBzY2FsZXNMZW5ndGgpfTtcbiAgICAgICAgaWYgKHNjYWxlID09IDEuMCkge1xuICAgICAgICAgIGlucHV0X2luZGV4ID0gb3V0cHV0X2luZGV4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciByb2lfbG93ID0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnJvaScsICdpJywgcm9pTGVuZ3RoKX07XG4gICAgICAgICAgdmFyIHJvaV9oaSA9ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5yb2knLCBgaSArICR7aW5wdXRTaGFwZS5sZW5ndGh9YCwgcm9pTGVuZ3RoKX07XG4gICAgICAgICAgdmFyIGlucHV0X3NoYXBlX2kgPSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMuaW5wdXRfc2hhcGUnLCAnaScsIGlucHV0U2hhcGUubGVuZ3RoKX07XG4gICAgICAgICAgdmFyIG91dHB1dF9zaGFwZV9pID0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLm91dHB1dF9zaGFwZScsICdpJywgb3V0cHV0U2hhcGUubGVuZ3RoKX07XG4gICAgICAgICAgdmFyIG9yaWdpbmFsX2lkeCA9IGdldE9yaWdpbmFsQ29vcmRpbmF0ZUZyb21SZXNpemVkQ29vcmRpbmF0ZShvdXRwdXRfaW5kZXgsIHNjYWxlLCBvdXRwdXRfc2hhcGVfaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0X3NoYXBlX2ksIHJvaV9sb3csIHJvaV9oaSk7XG4gICAgICAgICAgaWYgKCEke3VzZUV4dHJhcG9sYXRpb259IHx8IChvcmlnaW5hbF9pZHggPj0gMCAmJiBvcmlnaW5hbF9pZHggPCAke291dHB1dC50eXBlLnZhbHVlfShpbnB1dF9zaGFwZV9pKSkpIHtcbiAgICAgICAgICAgIGlmIChvcmlnaW5hbF9pZHggPCAwKSB7XG4gICAgICAgICAgICAgIGlucHV0X2luZGV4ID0gMDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAob3JpZ2luYWxfaWR4ID4gJHtvdXRwdXQudHlwZS52YWx1ZX0oaW5wdXRfc2hhcGVfaSAtIDEpKSB7XG4gICAgICAgICAgICAgIGlucHV0X2luZGV4ID0gaW5wdXRfc2hhcGVfaSAtIDE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpbnB1dF9pbmRleCA9IHUzMihnZXROZWFyZXN0UGl4ZWxGcm9tT3JpZ2luYWwob3JpZ2luYWxfaWR4LCBzY2FsZSA8IDEpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5wdXRfaW5kZXggPSB1MzIob3JpZ2luYWxfaWR4KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgJHtpbnB1dC5pbmRpY2VzU2V0KCdpbnB1dF9pbmRpY2VzJywgJ2knLCAnaW5wdXRfaW5kZXgnKX1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpbnB1dF9pbmRpY2VzO1xuICAgIH1gO1xuY29uc3QgY2hlY2tJbnB1dEluZGljZXMgPSAoaW5wdXQ6IEluZGljZXNIZWxwZXIsIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogc3RyaW5nID0+IGBcbiAgICBmbiBjaGVja0lucHV0SW5kaWNlcyhpbnB1dF9pbmRpY2VzOiAke2lucHV0LnR5cGUuaW5kaWNlc30pIC0+IGJvb2wge1xuICAgICAgZm9yICh2YXIgaTp1MzIgPSAwOyBpIDwgJHtpbnB1dFNoYXBlLmxlbmd0aH07IGkrKykge1xuICAgICAgICB2YXIgaW5wdXRfaW5kZXggPSAke2lucHV0LmluZGljZXNHZXQoJ2lucHV0X2luZGljZXMnLCAnaScpfTtcbiAgICAgICAgaWYgKGlucHV0X2luZGV4IDwgMCB8fCBpbnB1dF9pbmRleCA+PSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMuaW5wdXRfc2hhcGUnLCAnaScsIGlucHV0U2hhcGUubGVuZ3RoKX0pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1gO1xuXG5jb25zdCBzZXRDaGFubmVsQW5kQmF0Y2hJbmRpY2VzID0gKFxuICBpbnB1dDogSW5kaWNlc0hlbHBlcixcbiAgY2hhbm5lbElkeDogbnVtYmVyLFxuICBiYXRjaElkeDogbnVtYmVyLFxuICBzcGFjaWFsRGltczogbnVtYmVyLFxuKTogc3RyaW5nID0+XG4gIGlucHV0LnJhbmsgPiBzcGFjaWFsRGltc1xuICAgID8gYFxuICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5wdXRfaW5kaWNlcycsIGNoYW5uZWxJZHgsICdjaGFubmVsJyl9O1xuICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5wdXRfaW5kaWNlcycsIGJhdGNoSWR4LCAnYmF0Y2gnKX07XG5gXG4gICAgOiAnJztcblxuY29uc3QgYmlsaW5lYXJJbnRlcnBvbGF0aW9uID0gKFxuICBpbnB1dDogSW5kaWNlc0hlbHBlcixcbiAgb3V0cHV0OiBJbmRpY2VzSGVscGVyLFxuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgdXNlRXh0cmFwb2xhdGlvbjogYm9vbGVhbixcbiAgZXh0cmFwb2xhdGlvblZhbHVlOiBudW1iZXIsXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBpc05jaHcgPSB0cnVlO1xuICBjb25zdCBbYmF0Y2hJZHgsIGhlaWdodElkeCwgd2lkdGhJZHgsIGNoYW5uZWxJZHhdID1cbiAgICBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gMiA/IFstMSwgMCwgMSwgLTFdIDogaXNOY2h3ID8gWzAsIDIsIDMsIDFdIDogWzAsIDEsIDIsIDNdO1xuICBjb25zdCBkVHlwZSA9IGlucHV0LnR5cGUudmFsdWU7XG4gIHJldHVybiBgXG4gICAgZm4gZ2V0SW5wdXRWYWx1ZShiYXRjaDogdTMyLCBjaGFubmVsOiB1MzIsIHJvdzogdTMyLCBjb2w6IHUzMikgLT4gJHtkVHlwZX0ge1xuICAgICAgdmFyIGlucHV0X2luZGljZXM6ICR7aW5wdXQudHlwZS5pbmRpY2VzfTtcbiAgICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5wdXRfaW5kaWNlcycsIGhlaWdodElkeCwgYG1heCgwLCBtaW4ocm93LCAke2lucHV0U2hhcGVbaGVpZ2h0SWR4XX0gLSAxKSlgKX07XG4gICAgICAke2lucHV0LmluZGljZXNTZXQoJ2lucHV0X2luZGljZXMnLCB3aWR0aElkeCwgYG1heCgwLCBtaW4oY29sLCAke2lucHV0U2hhcGVbd2lkdGhJZHhdfSAtIDEpKWApfTtcbiAgICAgICR7c2V0Q2hhbm5lbEFuZEJhdGNoSW5kaWNlcyhpbnB1dCwgY2hhbm5lbElkeCwgYmF0Y2hJZHgsIDIpfVxuICAgICAgcmV0dXJuICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9O1xuICAgIH1cblxuICAgIGZuIGJpbGluZWFySW50ZXJwb2xhdGlvbihvdXRwdXRfaW5kaWNlczogJHtvdXRwdXQudHlwZS5pbmRpY2VzfSkgLT4gJHtkVHlwZX0ge1xuICAgICAgdmFyIG9yaWdpbmFsSW5kaWNlcyA9IGNhbGN1bGF0ZU9yaWdpbmFsSW5kaWNlc0Zyb21PdXRwdXRJbmRpY2VzKG91dHB1dF9pbmRpY2VzKTtcbiAgICAgIHZhciByb3c6JHtkVHlwZX0gPSBvcmlnaW5hbEluZGljZXNbJHtoZWlnaHRJZHh9XTtcbiAgICAgIHZhciBjb2w6JHtkVHlwZX0gPSBvcmlnaW5hbEluZGljZXNbJHt3aWR0aElkeH1dO1xuICAgICAgJHtcbiAgICAgICAgdXNlRXh0cmFwb2xhdGlvblxuICAgICAgICAgID8gYGlmIChyb3cgPCAwIHx8IHJvdyA+ICgke2lucHV0U2hhcGVbaGVpZ2h0SWR4XX0gLSAxKSB8fCBjb2wgPCAwIHx8IGNvbCA+ICgke2lucHV0U2hhcGVbd2lkdGhJZHhdfSAtIDEpKSB7XG4gICAgICAgIHJldHVybiAke2V4dHJhcG9sYXRpb25WYWx1ZX07XG4gICAgICB9YFxuICAgICAgICAgIDogJydcbiAgICAgIH07XG4gICAgICByb3cgPSBtYXgoMCwgbWluKHJvdywgJHtpbnB1dFNoYXBlW2hlaWdodElkeF19IC0gMSkpO1xuICAgICAgY29sID0gbWF4KDAsIG1pbihjb2wsICR7aW5wdXRTaGFwZVt3aWR0aElkeF19IC0gMSkpO1xuICAgICAgdmFyIHJvdzE6IHUzMiA9IHUzMihyb3cpO1xuICAgICAgdmFyIGNvbDE6IHUzMiA9IHUzMihjb2wpO1xuICAgICAgdmFyIHJvdzI6IHUzMiA9IHUzMihyb3cgKyAxKTtcbiAgICAgIHZhciBjb2wyOiB1MzIgPSB1MzIoY29sICsgMSk7XG4gICAgICB2YXIgY2hhbm5lbDogdTMyID0gJHtpbnB1dFNoYXBlLmxlbmd0aCA+IDIgPyBgdTMyKG9yaWdpbmFsSW5kaWNlc1ske2NoYW5uZWxJZHh9XSlgIDogJzAnfTtcbiAgICAgIHZhciBiYXRjaDogdTMyID0gICR7aW5wdXRTaGFwZS5sZW5ndGggPiAyID8gYHUzMihvcmlnaW5hbEluZGljZXNbJHtiYXRjaElkeH1dKWAgOiAnMCd9O1xuICAgICAgdmFyIHgxMTogJHtkVHlwZX0gPSBnZXRJbnB1dFZhbHVlKGJhdGNoLCBjaGFubmVsLCByb3cxLCBjb2wxKTtcbiAgICAgIHZhciB4MTI6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgcm93MSwgY29sMik7XG4gICAgICB2YXIgeDIxOiAke2RUeXBlfSA9IGdldElucHV0VmFsdWUoYmF0Y2gsIGNoYW5uZWwsIHJvdzIsIGNvbDEpO1xuICAgICAgdmFyIHgyMjogJHtkVHlwZX0gPSBnZXRJbnB1dFZhbHVlKGJhdGNoLCBjaGFubmVsLCByb3cyLCBjb2wyKTtcbiAgICAgIHZhciBkeDE6ICR7ZFR5cGV9ID0gYWJzKHJvdyAtICR7ZFR5cGV9KHJvdzEpKTtcbiAgICAgIHZhciBkeDI6ICR7ZFR5cGV9ID0gYWJzKCR7ZFR5cGV9KHJvdzIpIC0gcm93KTtcbiAgICAgIHZhciBkeTE6ICR7ZFR5cGV9ID0gYWJzKGNvbCAtICR7ZFR5cGV9KGNvbDEpKTtcbiAgICAgIHZhciBkeTI6ICR7ZFR5cGV9ID0gYWJzKCR7ZFR5cGV9KGNvbDIpIC0gY29sKTtcbiAgICAgIGlmIChyb3cxID09IHJvdzIpIHtcbiAgICAgICAgZHgxID0gMC41O1xuICAgICAgICBkeDIgPSAwLjU7XG4gICAgICB9XG4gICAgICBpZiAoY29sMSA9PSBjb2wyKSB7XG4gICAgICAgIGR5MSA9IDAuNTtcbiAgICAgICAgZHkyID0gMC41O1xuICAgICAgfVxuICAgICAgcmV0dXJuICh4MTEgKiBkeDIgKiBkeTIgKyB4MTIgKiBkeDIgKiBkeTEgKyB4MjEgKiBkeDEgKiBkeTIgKyB4MjIgKiBkeDEgKiBkeTEpO1xuICAgIH1gO1xufTtcblxuY29uc3QgYmljdWJpY0ludGVycG9sYXRpb24gPSAoXG4gIGlucHV0OiBJbmRpY2VzSGVscGVyLFxuICBvdXRwdXQ6IEluZGljZXNIZWxwZXIsXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHNjYWxlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHJvaTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGN1YmljQ29lZmZBOiBudW1iZXIsXG4gIHVzZUV4dHJhcG9sYXRpb246IGJvb2xlYW4sXG4gIGV4dHJhcG9sYXRpb25WYWx1ZTogbnVtYmVyLFxuICBleGNsdWRlT3V0c2lkZTogYm9vbGVhbixcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGlzMkQgPSBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gMjtcbiAgY29uc3QgaXNOY2h3ID0gdHJ1ZTtcbiAgY29uc3QgW2hlaWdodElkeCwgd2lkdGhJZHhdID0gaXMyRCA/IFswLCAxXSA6IGlzTmNodyA/IFsyLCAzXSA6IFsxLCAyXTtcbiAgY29uc3QgZFR5cGUgPSBpbnB1dC50eXBlLnZhbHVlO1xuICBjb25zdCBjcmVhdGVDdWJpY0ludGVycG9sYXRpb25GdW5jdGlvbiA9IChpZHg6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gICAgY29uc3QgZGlyZWN0aW9uID0gaWR4ID09PSBoZWlnaHRJZHggPyAncm93JyA6ICdjb2wnO1xuICAgIHJldHVybiBgXG4gICAgICBmbiAke2RpcmVjdGlvbn1DdWJpY0ludGVycG9sYXRpb24oaW5wdXRfaW5kaWNlczogJHtpbnB1dC50eXBlLmluZGljZXN9LCBvdXRwdXRfaW5kaWNlczogJHtcbiAgICAgICAgb3V0cHV0LnR5cGUuaW5kaWNlc1xuICAgICAgfSkgLT4gJHtkVHlwZX0ge1xuICAgICAgICB2YXIgb3V0cHV0X2luZGV4ID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCBpZHgpfTtcbiAgICAgICAgdmFyIG9yaWdpbmFsSWR4OiAke2RUeXBlfSA9IGdldE9yaWdpbmFsQ29vcmRpbmF0ZUZyb21SZXNpemVkQ29vcmRpbmF0ZShvdXRwdXRfaW5kZXgsICR7c2NhbGVzW2lkeF19LFxuICAgICAgICAke291dHB1dFNoYXBlW2lkeF19LCAke2lucHV0U2hhcGVbaWR4XX0sICR7cm9pW2lkeF19LCAke3JvaVtpZHhdfSArICR7aW5wdXRTaGFwZS5sZW5ndGh9KTtcbiAgICAgICAgdmFyIGZyYWN0T3JpZ2luYWxJZHg6ICR7ZFR5cGV9ID0gb3JpZ2luYWxJZHggLSBmbG9vcihvcmlnaW5hbElkeCk7XG4gICAgICAgIHZhciBjb2VmcyA9IGdldEN1YmljSW50ZXJwb2xhdGlvbkNvZWZzKGZyYWN0T3JpZ2luYWxJZHgpO1xuXG4gICAgICAgIGlmICgke3VzZUV4dHJhcG9sYXRpb259ICYmIChvcmlnaW5hbElkeCA8IDAgfHwgb3JpZ2luYWxJZHggPiAoJHtpbnB1dFNoYXBlW2lkeF19IC0gMSkpKSB7XG4gICAgICAgICAgcmV0dXJuICR7ZXh0cmFwb2xhdGlvblZhbHVlfTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF0YTogYXJyYXk8JHtkVHlwZX0sIDQ+ID0gYXJyYXk8JHtkVHlwZX0sIDQ+KDAuMCwgMC4wLCAwLjAsIDAuMCk7XG4gICAgICAgIGZvciAodmFyIGk6IGkzMiA9IC0xOyBpIDwgMzsgaSsrKSB7XG4gICAgICAgICAgdmFyICR7ZGlyZWN0aW9ufTogJHtkVHlwZX0gPSBvcmlnaW5hbElkeCArICR7ZFR5cGV9KGkpO1xuICAgICAgICAgIGlmICgke2RpcmVjdGlvbn0gPCAwIHx8ICR7ZGlyZWN0aW9ufSA+PSAke2lucHV0U2hhcGVbaWR4XX0pIHtcbiAgICAgICAgICAgICR7KCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKGV4Y2x1ZGVPdXRzaWRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBjb2Vmc1tpICsgMV0gPSAwLjA7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtgO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHVzZUV4dHJhcG9sYXRpb24pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYHJldHVybiAke2V4dHJhcG9sYXRpb25WYWx1ZX07YDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7ZGlyZWN0aW9ufSA9IG1heCgwLCBtaW4oJHtkaXJlY3Rpb259LCAke2lucHV0U2hhcGVbaWR4XX0gLSAxKSk7YDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkoKX07XG4gICAgICAgICAgfVxuICAgICAgICB2YXIgaW5wdXRfaW5kaWNlc19jb3B5OiAke2lucHV0LnR5cGUuaW5kaWNlc30gPSBpbnB1dF9pbmRpY2VzO1xuICAgICAgICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5wdXRfaW5kaWNlc19jb3B5JywgaWR4LCBgdTMyKCR7ZGlyZWN0aW9ufSlgKX07XG4gICAgICAgICAgZGF0YVtpICsgMV0gPSAke1xuICAgICAgICAgICAgaWR4ID09PSBoZWlnaHRJZHhcbiAgICAgICAgICAgICAgPyBpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXNfY29weScpXG4gICAgICAgICAgICAgIDogJ3Jvd0N1YmljSW50ZXJwb2xhdGlvbihpbnB1dF9pbmRpY2VzX2NvcHksIG91dHB1dF9pbmRpY2VzKSdcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjdWJpY0ludGVycG9sYXRpb24xRChkYXRhLCBjb2Vmcyk7XG4gICAgICB9YDtcbiAgfTtcblxuICByZXR1cm4gYFxuICAgICR7Y3JlYXRlQ3ViaWNJbnRlcnBvbGF0aW9uRnVuY3Rpb24oaGVpZ2h0SWR4KX07XG4gICAgJHtjcmVhdGVDdWJpY0ludGVycG9sYXRpb25GdW5jdGlvbih3aWR0aElkeCl9O1xuICBmbiBnZXRDdWJpY0ludGVycG9sYXRpb25Db2VmcyhzOiAke2RUeXBlfSkgLT4gYXJyYXk8JHtkVHlwZX0sIDQ+IHtcbiAgICB2YXIgYWJzUyA9IGFicyhzKTtcbiAgICB2YXIgY29lZmZzOiBhcnJheTwke2RUeXBlfSwgND4gPSBhcnJheTwke2RUeXBlfSwgND4oMC4wLCAwLjAsIDAuMCwgMC4wKTtcbiAgICB2YXIgb25lTWludXNBYnNTOiAke2RUeXBlfSA9IDEuMCAtIGFic1M7XG4gICAgdmFyIHR3b01pbnVzQWJzUzogJHtkVHlwZX0gPSAyLjAgLSBhYnNTO1xuICAgIHZhciBvbmVQbHVzQWJzUzogJHtkVHlwZX0gPSAxLjAgKyBhYnNTO1xuICAgIGNvZWZmc1swXSA9ICgoJHtjdWJpY0NvZWZmQX0gKiBvbmVQbHVzQWJzUyAtIDUgKiAke2N1YmljQ29lZmZBfSkgKiBvbmVQbHVzQWJzUyArIDggKiAke1xuICAgICAgY3ViaWNDb2VmZkFcbiAgICB9KSAqIG9uZVBsdXNBYnNTIC0gNCAqICR7Y3ViaWNDb2VmZkF9O1xuICAgIGNvZWZmc1sxXSA9ICgoJHtjdWJpY0NvZWZmQX0gKyAyKSAqIGFic1MgLSAoJHtjdWJpY0NvZWZmQX0gKyAzKSkgKiBhYnNTICogYWJzUyArIDE7XG4gICAgY29lZmZzWzJdID0gKCgke2N1YmljQ29lZmZBfSArIDIpICogb25lTWludXNBYnNTIC0gKCR7Y3ViaWNDb2VmZkF9ICsgMykpICogb25lTWludXNBYnNTICogb25lTWludXNBYnNTICsgMTtcbiAgICBjb2VmZnNbM10gPSAoKCR7Y3ViaWNDb2VmZkF9ICogdHdvTWludXNBYnNTIC0gNSAqICR7Y3ViaWNDb2VmZkF9KSAqIHR3b01pbnVzQWJzUyArIDggKiAke1xuICAgICAgY3ViaWNDb2VmZkFcbiAgICB9KSAqIHR3b01pbnVzQWJzUyAtIDQgKiAke2N1YmljQ29lZmZBfTtcbiAgICByZXR1cm4gY29lZmZzO1xuICB9XG5cbiAgZm4gY3ViaWNJbnRlcnBvbGF0aW9uMUQoeDogYXJyYXk8JHtkVHlwZX0sIDQ+LCBjb2VmczogYXJyYXk8JHtkVHlwZX0sIDQ+KSAtPiAke2RUeXBlfSB7XG4gICAgdmFyIGNvZWZzU3VtOiAke2RUeXBlfSA9IGNvZWZzWzBdICsgY29lZnNbMV0gKyBjb2Vmc1syXSArIGNvZWZzWzNdO1xuICAgIHJldHVybiAoeFswXSAqIGNvZWZzWzBdICsgeFsxXSAqIGNvZWZzWzFdKyB4WzJdICogY29lZnNbMl0rIHhbM10gKiBjb2Vmc1szXSkgLyBjb2Vmc1N1bTtcbiAgfVxuXG4gIGZuIGJpY3ViaWNJbnRlcnBvbGF0aW9uKG91dHB1dF9pbmRpY2VzOiAke291dHB1dC50eXBlLmluZGljZXN9KSAtPiAke2RUeXBlfSB7XG4gICAgdmFyIGlucHV0X2luZGljZXM6ICR7aW5wdXQudHlwZS5pbmRpY2VzfSA9IG91dHB1dF9pbmRpY2VzO1xuICAgIHJldHVybiBjb2xDdWJpY0ludGVycG9sYXRpb24oaW5wdXRfaW5kaWNlcywgb3V0cHV0X2luZGljZXMpO1xuICB9XG4gICAgYDtcbn07XG5cbmNvbnN0IHRyaWxpbmVhckludGVycG9sYXRpb24gPSAoXG4gIGlucHV0OiBJbmRpY2VzSGVscGVyLFxuICBvdXRwdXQ6IEluZGljZXNIZWxwZXIsXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICB1c2VFeHRyYXBvbGF0aW9uOiBib29sZWFuLFxuICBleHRyYXBvbGF0aW9uVmFsdWU6IG51bWJlcixcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGlzTmNodyA9IHRydWU7XG4gIGNvbnN0IFtiYXRjaElkeCwgZGVwdGhJZHgsIGhlaWdodElkeCwgd2lkdGhJZHgsIGNoYW5uZWxJZHhdID1cbiAgICBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gMyA/IFstMSwgMCwgMSwgMiwgLTFdIDogaXNOY2h3ID8gWzAsIDIsIDMsIDQsIDFdIDogWzAsIDEsIDIsIDMsIDRdO1xuICBjb25zdCBkVHlwZSA9IGlucHV0LnR5cGUudmFsdWU7XG4gIHJldHVybiBgXG4gICAgZm4gZ2V0SW5wdXRWYWx1ZShiYXRjaDogdTMyLCBjaGFubmVsOiB1MzIsIGRlcHRoOnUzMiwgaGVpZ2h0OiB1MzIsIHdpZHRoOiB1MzIpIC0+ICR7ZFR5cGV9IHtcbiAgICAgIHZhciBpbnB1dF9pbmRpY2VzOiAke2lucHV0LnR5cGUuaW5kaWNlc307XG4gICAgICAke2lucHV0LmluZGljZXNTZXQoJ2lucHV0X2luZGljZXMnLCBkZXB0aElkeCwgYG1heCgwLCBtaW4oZGVwdGgsICR7aW5wdXRTaGFwZVtkZXB0aElkeF19IC0gMSkpYCl9O1xuICAgICAgJHtpbnB1dC5pbmRpY2VzU2V0KCdpbnB1dF9pbmRpY2VzJywgaGVpZ2h0SWR4LCBgbWF4KDAsIG1pbihoZWlnaHQsICR7aW5wdXRTaGFwZVtoZWlnaHRJZHhdfSAtIDEpKWApfTtcbiAgICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5wdXRfaW5kaWNlcycsIHdpZHRoSWR4LCBgbWF4KDAsIG1pbih3aWR0aCwgJHtpbnB1dFNoYXBlW3dpZHRoSWR4XX0gLSAxKSlgKX07XG4gICAgICAke3NldENoYW5uZWxBbmRCYXRjaEluZGljZXMoaW5wdXQsIGNoYW5uZWxJZHgsIGJhdGNoSWR4LCAzKX1cbiAgICAgIHJldHVybiAke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpfTtcbiAgICB9XG5cbiAgICBmbiB0cmlsaW5lYXJJbnRlcnBvbGF0aW9uKG91dHB1dF9pbmRpY2VzOiAke291dHB1dC50eXBlLmluZGljZXN9KSAtPiAke2RUeXBlfSB7XG4gICAgICB2YXIgb3JpZ2luYWxJbmRpY2VzID0gY2FsY3VsYXRlT3JpZ2luYWxJbmRpY2VzRnJvbU91dHB1dEluZGljZXMob3V0cHV0X2luZGljZXMpO1xuICAgICAgdmFyIGRlcHRoOiR7ZFR5cGV9ID0gb3JpZ2luYWxJbmRpY2VzWyR7ZGVwdGhJZHh9XTtcbiAgICAgIHZhciBoZWlnaHQ6JHtkVHlwZX0gPSBvcmlnaW5hbEluZGljZXNbJHtoZWlnaHRJZHh9XTtcbiAgICAgIHZhciB3aWR0aDoke2RUeXBlfSA9IG9yaWdpbmFsSW5kaWNlc1ske3dpZHRoSWR4fV07XG4gICAgICAke1xuICAgICAgICB1c2VFeHRyYXBvbGF0aW9uXG4gICAgICAgICAgPyBgaWYgKGRlcHRoIDwgMCB8fCBkZXB0aCA+ICgke2lucHV0U2hhcGVbZGVwdGhJZHhdfSAtIDEpIHx8IGhlaWdodCA8IDAgfHwgaGVpZ2h0ID4gKCR7XG4gICAgICAgICAgICAgIGlucHV0U2hhcGVbaGVpZ2h0SWR4XVxuICAgICAgICAgICAgfSAtIDEpIHx8IHdpZHRoIDwgMCB8fCAod2lkdGggPiAke2lucHV0U2hhcGVbd2lkdGhJZHhdfSAtIDEpKSB7XG4gICAgICByZXR1cm4gJHtleHRyYXBvbGF0aW9uVmFsdWV9O1xuICAgICAgICB9YFxuICAgICAgICAgIDogJydcbiAgICAgIH07XG5cbiAgICBkZXB0aCA9IG1heCgwLCBtaW4oZGVwdGgsICR7aW5wdXRTaGFwZVtkZXB0aElkeF19IC0gMSkpO1xuICAgICAgaGVpZ2h0ID0gbWF4KDAsIG1pbihoZWlnaHQsICR7aW5wdXRTaGFwZVtoZWlnaHRJZHhdfSAtIDEpKTtcbiAgICAgIHdpZHRoID0gbWF4KDAsIG1pbih3aWR0aCwgJHtpbnB1dFNoYXBlW3dpZHRoSWR4XX0gLSAxKSk7XG4gICAgICB2YXIgZGVwdGgxOiB1MzIgPSB1MzIoZGVwdGgpO1xuICAgICAgdmFyIGhlaWdodDE6IHUzMiA9IHUzMihoZWlnaHQpO1xuICAgICAgdmFyIHdpZHRoMTogdTMyID0gdTMyKHdpZHRoKTtcbiAgICAgIHZhciBkZXB0aDI6IHUzMiA9IHUzMihkZXB0aCArIDEpO1xuICAgICAgdmFyIGhlaWdodDI6IHUzMiA9IHUzMihoZWlnaHQgKyAxKTtcbiAgICAgIHZhciB3aWR0aDI6IHUzMiA9IHUzMih3aWR0aCArIDEpO1xuICAgICAgdmFyIGNoYW5uZWw6IHUzMiA9ICR7aW5wdXRTaGFwZS5sZW5ndGggPiAzID8gYHUzMihvcmlnaW5hbEluZGljZXNbJHtjaGFubmVsSWR4fV0pYCA6ICcwJ307XG4gICAgICB2YXIgYmF0Y2g6IHUzMiA9ICAke2lucHV0U2hhcGUubGVuZ3RoID4gMyA/IGB1MzIob3JpZ2luYWxJbmRpY2VzWyR7YmF0Y2hJZHh9XSlgIDogJzAnfTtcblxuICAgICAgdmFyIHgxMTE6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgxLCBoZWlnaHQxLCB3aWR0aDEpO1xuICAgICAgdmFyIHgxMTI6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgxLCBoZWlnaHQxLCB3aWR0aDIpO1xuICAgICAgdmFyIHgxMjE6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgxLCBoZWlnaHQyLCB3aWR0aDEpO1xuICAgICAgdmFyIHgxMjI6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgxLCBoZWlnaHQyLCB3aWR0aDIpO1xuICAgICAgdmFyIHgyMTE6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgyLCBoZWlnaHQxLCB3aWR0aDEpO1xuICAgICAgdmFyIHgyMTI6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgyLCBoZWlnaHQxLCB3aWR0aDIpO1xuICAgICAgdmFyIHgyMjE6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgyLCBoZWlnaHQyLCB3aWR0aDEpO1xuICAgICAgdmFyIHgyMjI6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgyLCBoZWlnaHQyLCB3aWR0aDIpO1xuICAgICAgdmFyIGR4MTogJHtkVHlwZX0gPSBhYnMoZGVwdGggLSAke2RUeXBlfShkZXB0aDEpKTtcbiAgICAgIHZhciBkeDI6ICR7ZFR5cGV9ID0gYWJzKCR7ZFR5cGV9KGRlcHRoMikgLSBkZXB0aCk7XG4gICAgICB2YXIgZHkxOiAke2RUeXBlfSA9IGFicyhoZWlnaHQgLSAke2RUeXBlfShoZWlnaHQxKSk7XG4gICAgICB2YXIgZHkyOiAke2RUeXBlfSA9IGFicygke2RUeXBlfShoZWlnaHQyKSAtIGhlaWdodCk7XG4gICAgICB2YXIgZHoxOiAke2RUeXBlfSA9IGFicyh3aWR0aCAtICR7ZFR5cGV9KHdpZHRoMSkpO1xuICAgICAgdmFyIGR6MjogJHtkVHlwZX0gPSBhYnMoJHtkVHlwZX0od2lkdGgyKSAtIHdpZHRoKTtcbiAgICAgIGlmIChkZXB0aDEgPT0gZGVwdGgyKSB7XG4gICAgICAgIGR4MSA9IDAuNTtcbiAgICAgICAgZHgyID0gMC41O1xuICAgICAgfVxuICAgICAgaWYgKGhlaWdodDEgPT0gaGVpZ2h0Mikge1xuICAgICAgICBkeTEgPSAwLjU7XG4gICAgICAgIGR5MiA9IDAuNTtcbiAgICAgIH1cbiAgICAgIGlmICh3aWR0aDEgPT0gd2lkdGgyKSB7XG4gICAgICAgIGR6MSA9IDAuNTtcbiAgICAgICAgZHoyID0gMC41O1xuICAgICAgfVxuICAgICAgcmV0dXJuICh4MTExICogZHgyICogZHkyICogZHoyICsgeDExMiAqIGR4MiAqIGR5MiAqIGR6MSArIHgxMjEgKiBkeDIgKiBkeTEgKmR6MiArIHgxMjIgKiBkeDIgKiBkeTEgKiBkejEgK1xuICAgICAgICAgICAgICB4MjExICogZHgxICogZHkyICogZHoyICsgeDIxMiAqIGR4MSAqIGR5MiAqIGR6MSArIHgyMjEgKiBkeDEgKiBkeTEgKmR6MiArIHgyMjIgKiBkeDEgKiBkeTEgKiBkejEpO1xuICAgIH1gO1xufTtcblxuY29uc3QgY3JlYXRlUmVzaXplUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0VGVuc29yOiBUZW5zb3JWaWV3LFxuICBhdHRyaWJ1dGVzOiBSZXNpemVBdHRyaWJ1dGVzLFxuICBvcHNldFZlcnNpb246IG51bWJlcixcbiAgc2NhbGVzSW5wdXQ6IHJlYWRvbmx5IG51bWJlcltdLFxuICBzaXplczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHJvaUlucHV0OiByZWFkb25seSBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0VGVuc29yLmRpbXM7XG4gIGNvbnN0IHJvaSA9IHVwZGF0ZVJvSShyb2lJbnB1dCwgYXR0cmlidXRlcy5heGVzLCBpbnB1dFNoYXBlLmxlbmd0aCk7XG5cbiAgbGV0IG91dHB1dFNoYXBlID0gaW5pdE91dHB1dFNoYXBlKGlucHV0U2hhcGUsIHNjYWxlc0lucHV0LCBzaXplcywgYXR0cmlidXRlcy5heGVzKTtcbiAgbGV0IHNjYWxlcyA9IHNjYWxlc0lucHV0LnNsaWNlKCk7XG4gIGlmIChzY2FsZXNJbnB1dC5sZW5ndGggPT09IDApIHtcbiAgICBzY2FsZXMgPSBpbnB1dFNoYXBlLm1hcCgodmFsdWUsIGluZGV4KSA9PiAodmFsdWUgPT09IDAgPyAxLjAgOiBvdXRwdXRTaGFwZVtpbmRleF0gLyB2YWx1ZSkpO1xuICAgIGlmIChhdHRyaWJ1dGVzLmtlZXBBc3BlY3RSYXRpb1BvbGljeSAhPT0gJ3N0cmV0Y2gnKSB7XG4gICAgICBvdXRwdXRTaGFwZSA9IGFkanVzdE91dHB1dFNoYXBlKGlucHV0U2hhcGUsIHNjYWxlcywgYXR0cmlidXRlcyk7XG4gICAgfVxuICB9XG4gIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dFRlbnNvci5kYXRhVHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3QgaW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdpbnB1dCcsIGlucHV0VGVuc29yLmRhdGFUeXBlLCBpbnB1dFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gIGNvbnN0IG5vU2NhbGUgPSBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gb3V0cHV0U2hhcGUubGVuZ3RoICYmIGlucHV0U2hhcGUuZXZlcnkoKGQsIGkpID0+IGQgPT09IG91dHB1dFNoYXBlW2ldKTtcbiAgY29uc3QgdXNlRXh0cmFwb2xhdGlvbiA9IGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPT09ICd0Zl9jcm9wX2FuZF9yZXNpemUnO1xuICBjb25zdCBleHRyYXBvbGF0aW9uVmFsdWUgPSBhdHRyaWJ1dGVzLmV4dHJhcG9sYXRpb25WYWx1ZTtcbiAgY29uc3QgZGF0YVR5cGUgPSBpbnB1dC50eXBlLnZhbHVlO1xuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IGBcbiAgICAgICR7XG4gICAgICAgIG5vU2NhbGVcbiAgICAgICAgICA/ICcnXG4gICAgICAgICAgOiBgXG4gICAgICAke2dldE9yaWdpbmFsQ29vcmRpbmF0ZUZyb21SZXNpemVkQ29vcmRpbmF0ZShhdHRyaWJ1dGVzLmNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlLCBkYXRhVHlwZSl9O1xuICAgICAgJHsoKCkgPT4ge1xuICAgICAgICBzd2l0Y2ggKGF0dHJpYnV0ZXMubW9kZSkge1xuICAgICAgICAgIGNhc2UgJ25lYXJlc3QnOlxuICAgICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICAgICAgJHtjaGVja0lucHV0SW5kaWNlcyhpbnB1dCwgaW5wdXRTaGFwZSl9O1xuICAgICAgICAgICAgICAke2dldE5lYXJlc3RQaXhlbEZyb21PcmlnaW5hbChhdHRyaWJ1dGVzLm5lYXJlc3RNb2RlLCBvcHNldFZlcnNpb24sIGRhdGFUeXBlKX07XG4gICAgICAgICAgICAgICR7Y2FsY3VsYXRlSW5wdXRJbmRpY2VzRnJvbU91dHB1dEluZGljZXMoXG4gICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgb3V0cHV0LFxuICAgICAgICAgICAgICAgIGlucHV0U2hhcGUsXG4gICAgICAgICAgICAgICAgb3V0cHV0U2hhcGUsXG4gICAgICAgICAgICAgICAgc2NhbGVzLmxlbmd0aCxcbiAgICAgICAgICAgICAgICByb2kubGVuZ3RoLFxuICAgICAgICAgICAgICAgIHVzZUV4dHJhcG9sYXRpb24sXG4gICAgICAgICAgICAgICl9O1xuICAgICAgICAgICAgICBgO1xuICAgICAgICAgIGNhc2UgJ2xpbmVhcic6XG4gICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAke2NhbGN1bGF0ZU9yaWdpbmFsSW5kaWNlc0Zyb21PdXRwdXRJbmRpY2VzKG91dHB1dCwgaW5wdXRTaGFwZSwgb3V0cHV0U2hhcGUsIHNjYWxlcy5sZW5ndGgsIHJvaS5sZW5ndGgpfTtcbiAgICAgICAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpbnB1dFNoYXBlLmxlbmd0aCA9PT0gMiB8fCBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke2JpbGluZWFySW50ZXJwb2xhdGlvbihpbnB1dCwgb3V0cHV0LCBpbnB1dFNoYXBlLCB1c2VFeHRyYXBvbGF0aW9uLCBleHRyYXBvbGF0aW9uVmFsdWUpfWA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbnB1dFNoYXBlLmxlbmd0aCA9PT0gMyB8fCBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gNSkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke3RyaWxpbmVhckludGVycG9sYXRpb24oaW5wdXQsIG91dHB1dCwgaW5wdXRTaGFwZSwgdXNlRXh0cmFwb2xhdGlvbiwgZXh0cmFwb2xhdGlvblZhbHVlKX1gO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcignTGluZWFyIG1vZGUgb25seSBzdXBwb3J0cyBpbnB1dCBkaW1zIDIsIDMsIDQgYW5kIDUgYXJlIHN1cHBvcnRlZCBpbiBsaW5lYXIgbW9kZS4nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pKCl9O1xuICAgICAgICAgICAgYDtcbiAgICAgICAgICBjYXNlICdjdWJpYyc6XG4gICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoaW5wdXRTaGFwZS5sZW5ndGggPT09IDIgfHwgaW5wdXRTaGFwZS5sZW5ndGggPT09IDQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7YmljdWJpY0ludGVycG9sYXRpb24oXG4gICAgICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgICAgIG91dHB1dCxcbiAgICAgICAgICAgICAgICAgIGlucHV0U2hhcGUsXG4gICAgICAgICAgICAgICAgICBvdXRwdXRTaGFwZSxcbiAgICAgICAgICAgICAgICAgIHNjYWxlcyxcbiAgICAgICAgICAgICAgICAgIHJvaSxcbiAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuY3ViaWNDb2VmZkEsXG4gICAgICAgICAgICAgICAgICB1c2VFeHRyYXBvbGF0aW9uLFxuICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5leHRyYXBvbGF0aW9uVmFsdWUsXG4gICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmV4Y2x1ZGVPdXRzaWRlLFxuICAgICAgICAgICAgICAgICl9YDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcignQ3ViaWMgbW9kZSBvbmx5IHN1cHBvcnRzIGlucHV0IGRpbXMgMiBhbmQgNCBhcmUgc3VwcG9ydGVkIGluIGxpbmVhciBtb2RlLicpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSgpfTtcbiAgICAgICAgICAgIGA7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdJbnZhbGlkIHJlc2l6ZSBtb2RlJyk7XG4gICAgICAgIH1cbiAgICAgIH0pKCl9O1xuICAgICAgYFxuICAgICAgfVxuICAgICAgJHtzaGFkZXJIZWxwZXJcbiAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0X3NpemUnLCAndTMyJylcbiAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnc2NhbGVzJywgJ2YzMicsIHNjYWxlcy5sZW5ndGgpXG4gICAgICAgIC5yZWdpc3RlclVuaWZvcm0oJ3JvaScsICdmMzInLCByb2kubGVuZ3RoKVxuICAgICAgICAuZGVjbGFyZVZhcmlhYmxlcyhpbnB1dCwgb3V0cHV0KX1cbiAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRfc2l6ZScpfVxuICAgICAgICAke1xuICAgICAgICAgIG5vU2NhbGVcbiAgICAgICAgICAgID8gJ291dHB1dFtnbG9iYWxfaWR4XSA9IGlucHV0W2dsb2JhbF9pZHhdOydcbiAgICAgICAgICAgIDogYFxuICAgICAgICBsZXQgb3V0cHV0X2luZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG4gICAgICAgIHZhciBpbnB1dF9pbmRpY2VzOiAke2lucHV0LnR5cGUuaW5kaWNlc307XG4gICAgICAgICR7KCgpID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKGF0dHJpYnV0ZXMubW9kZSkge1xuICAgICAgICAgICAgY2FzZSAnbmVhcmVzdCc6XG4gICAgICAgICAgICAgIHJldHVybiBgaW5wdXRfaW5kaWNlcyA9IGNhbGN1bGF0ZUlucHV0SW5kaWNlc0Zyb21PdXRwdXRJbmRpY2VzKG91dHB1dF9pbmRpY2VzKTtcbiAgICAgICAgICAgICAgICBpZiAoY2hlY2tJbnB1dEluZGljZXMoaW5wdXRfaW5kaWNlcykpIHtcbiAgICAgICAgICAgICAgICAgIG91dHB1dFtnbG9iYWxfaWR4XSA9ICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRbZ2xvYmFsX2lkeF0gPSAke2F0dHJpYnV0ZXMuZXh0cmFwb2xhdGlvblZhbHVlfTtcbiAgICAgICAgICAgICAgICB9YDtcbiAgICAgICAgICAgIGNhc2UgJ2xpbmVhcic6XG4gICAgICAgICAgICAgIHJldHVybiBgb3V0cHV0W2dsb2JhbF9pZHhdID0gJHtcbiAgICAgICAgICAgICAgICBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gMiB8fCBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gNCA/ICdiaWxpbmVhckludGVycG9sYXRpb24nIDogJ3RyaWxpbmVhckludGVycG9sYXRpb24nXG4gICAgICAgICAgICAgIH0ob3V0cHV0X2luZGljZXMpO2A7XG4gICAgICAgICAgICBjYXNlICdjdWJpYyc6XG4gICAgICAgICAgICAgIHJldHVybiAnb3V0cHV0W2dsb2JhbF9pZHhdID0gYmljdWJpY0ludGVycG9sYXRpb24ob3V0cHV0X2luZGljZXMpOyc7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICB0aHJvdyBFcnJvcihgVW5zdXBwb3J0ZWQgcmVzaXplIG1vZGU6ICR7YXR0cmlidXRlcy5tb2RlfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKX07XG5gXG4gICAgICAgIH1cbiAgICAgIH1gO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ1Jlc2l6ZScsXG4gICAgc2hhZGVyQ2FjaGU6IHtcbiAgICAgIGhpbnQ6IGAke2F0dHJpYnV0ZXMuY2FjaGVLZXl9fCR7b3BzZXRWZXJzaW9ufXwke1xuICAgICAgICBzY2FsZXMubGVuZ3RoID4gMCA/IChhdHRyaWJ1dGVzLm1vZGUgPT09ICdjdWJpYycgPyBzY2FsZXMgOiBzY2FsZXMubGVuZ3RoKSA6ICcnXG4gICAgICB9fCR7c2l6ZXMubGVuZ3RoID4gMCA/IHNpemVzIDogJyd9fCR7cm9pLmxlbmd0aCA+IDAgPyByb2kgOiAnJ318JHtub1NjYWxlfXwke1xuICAgICAgICBhdHRyaWJ1dGVzLm1vZGUgPT09ICduZWFyZXN0JyA/IGlucHV0U2hhcGUubGVuZ3RoIDogaW5wdXRTaGFwZVxuICAgICAgfWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llczogWydyYW5rJ10sXG4gICAgfSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRUZW5zb3IuZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXM6IFtcbiAgICAgICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICAgICAgeyB0eXBlOiBEYXRhVHlwZS5mbG9hdCwgZGF0YTogc2NhbGVzIH0sXG4gICAgICAgIHsgdHlwZTogRGF0YVR5cGUuZmxvYXQsIGRhdGE6IHJvaSB9LFxuICAgICAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dFNoYXBlLCBvdXRwdXRTaGFwZSksXG4gICAgICBdLFxuICAgIH0pLFxuICB9O1xufTtcblxuY29uc3QgZ2V0T3BzZXRWZXJzaW9uRnJvbUN1c3RvbURhdGFCdWZmZXIgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiBudW1iZXIgPT4ge1xuICBjb25zdCBjdXN0b21EYXRhQnVmZmVyID0gY29udGV4dC5jdXN0b21EYXRhQnVmZmVyO1xuICBjb25zdCBjdXN0b21EYXRhQnVmZmVyMzIgPSBuZXcgVWludDMyQXJyYXkoY3VzdG9tRGF0YUJ1ZmZlciwgY3VzdG9tRGF0YUJ1ZmZlci5ieXRlT2Zmc2V0LCAxKTtcbiAgY29uc3Qgb3BzZXRWZXJzaW9uID0gY3VzdG9tRGF0YUJ1ZmZlcjMyWzBdO1xuICByZXR1cm4gb3BzZXRWZXJzaW9uO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlc2l6ZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVzaXplQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBzY2FsZXM6IG51bWJlcltdID0gW107XG4gIGNvbnN0IHNpemVzOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCByb2k6IG51bWJlcltdID0gW107XG5cbiAgLy8gTm90ZSB0aGF0IHNjYWxlcyBpbiByZXNpemUgYXJlIGFsd2F5cyBmMzIuIHJvaSBjYW4gYmUgZjMyIG9yIGYxNi5cbiAgLy8gVE9ETzogQ3VycmVudGx5IHRoaXMgY29kZSBkb2VzIG5vdCBzdXBwb3J0IGYxNiBmb3Igcm9pIHdoZW4gcGFzc2VkIGFzIG9wdGlvbmFsIGlucHV0LlxuXG4gIGNvbnN0IG9wc2V0VmVyc2lvbiA9IGdldE9wc2V0VmVyc2lvbkZyb21DdXN0b21EYXRhQnVmZmVyKGNvbnRleHQpO1xuICBpZiAoYXR0cmlidXRlcy5hbnRpYWxpYXMgIT09IDApIHtcbiAgICB0aHJvdyBFcnJvcignT25seSBkZWZhdWx0IHZhbHVlICgwKSBmb3IgQW50aWFsaWFzIGF0dHJpYnV0ZSBpcyBzdXBwb3J0ZWQnKTtcbiAgfVxuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcywgb3BzZXRWZXJzaW9uLCBzY2FsZXMsIHNpemVzLCByb2kpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlUmVzaXplUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sIGF0dHJpYnV0ZXMsIG9wc2V0VmVyc2lvbiwgc2NhbGVzLCBzaXplcywgcm9pKSwge1xuICAgIGlucHV0czogWzBdLFxuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBSZXNpemVBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYW50aWFsaWFzID0gYXR0cmlidXRlcy5hbnRpYWxpYXMgYXMgbnVtYmVyO1xuICBjb25zdCBheGVzID0gYXR0cmlidXRlcy5heGVzIGFzIG51bWJlcltdO1xuICBjb25zdCBjb29yZGluYXRlVHJhbnNmb3JtTW9kZTogQ29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPVxuICAgIGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgYXMgQ29vcmRpbmF0ZVRyYW5zZm9ybU1vZGU7XG4gIGNvbnN0IGN1YmljQ29lZmZBID0gYXR0cmlidXRlcy5jdWJpY0NvZWZmQSBhcyBudW1iZXI7XG4gIGNvbnN0IGV4Y2x1ZGVPdXRzaWRlID0gKGF0dHJpYnV0ZXMuZXhjbHVkZU91dHNpZGUgYXMgbnVtYmVyKSAhPT0gMDtcbiAgY29uc3QgZXh0cmFwb2xhdGlvblZhbHVlID0gYXR0cmlidXRlcy5leHRyYXBvbGF0aW9uVmFsdWUgYXMgbnVtYmVyO1xuICBjb25zdCBrZWVwQXNwZWN0UmF0aW9Qb2xpY3k6IEtlZXBBc3BlY3RSYXRpb1BvbGljeSA9IGF0dHJpYnV0ZXMua2VlcEFzcGVjdFJhdGlvUG9saWN5IGFzIEtlZXBBc3BlY3RSYXRpb1BvbGljeTtcbiAgY29uc3QgbW9kZTogTW9kZSA9IGF0dHJpYnV0ZXMubW9kZSBhcyBNb2RlO1xuICAvLyBJZiBuZWFyZXN0TW9kZSBpcyBub3Qgc3BlY2lmaWVkLCB1c2Ugc2ltcGxlIG1vZGUuXG4gIGNvbnN0IG5lYXJlc3RNb2RlOiBOZWFyZXN0TW9kZSA9IChhdHRyaWJ1dGVzLm5lYXJlc3RNb2RlID09PSAnJyA/ICdzaW1wbGUnIDogYXR0cmlidXRlcy5uZWFyZXN0TW9kZSkgYXMgTmVhcmVzdE1vZGU7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe1xuICAgIGFudGlhbGlhcyxcbiAgICBheGVzLFxuICAgIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlLFxuICAgIGN1YmljQ29lZmZBLFxuICAgIGV4Y2x1ZGVPdXRzaWRlLFxuICAgIGV4dHJhcG9sYXRpb25WYWx1ZSxcbiAgICBrZWVwQXNwZWN0UmF0aW9Qb2xpY3ksXG4gICAgbW9kZSxcbiAgICBuZWFyZXN0TW9kZSxcbiAgfSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGNhc3RUb0YzMixcbiAgZ2V0TWF4Q29tcG9uZW50cyxcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbiAgc3VtVmVjdG9yLFxuICB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2tpcExheWVyTm9ybUF0dHJpYnV0ZXMge1xuICBzaW1wbGlmaWVkOiBib29sZWFuO1xuICBlcHNpbG9uOiBudW1iZXI7XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdsYXllck5vcm0gcmVxdWlyZXMgYXQgbGVhc3QgMyBpbnB1dHMuJyk7XG4gIH1cblxuICBjb25zdCBpbnB1dDogVGVuc29yVmlldyA9IGlucHV0c1swXTtcbiAgY29uc3Qgc2tpcDogVGVuc29yVmlldyA9IGlucHV0c1sxXTtcbiAgY29uc3QgZ2FtbWE6IFRlbnNvclZpZXcgPSBpbnB1dHNbMl07XG5cbiAgaWYgKGlucHV0LmRhdGFUeXBlICE9PSBza2lwLmRhdGFUeXBlIHx8IGlucHV0LmRhdGFUeXBlICE9PSBnYW1tYS5kYXRhVHlwZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQWxsIGlucHV0cyBtdXN0IGhhdmUgdGhlIHNhbWUgZGF0YSB0eXBlJyk7XG4gIH1cblxuICBpZiAoaW5wdXQuZGltcy5sZW5ndGggIT09IDMgJiYgaW5wdXQuZGltcy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IG11c3QgYmUgMkQgb3IgM0QnKTtcbiAgfVxuXG4gIGlmIChza2lwLmRpbXMubGVuZ3RoICE9PSAzICYmIHNraXAuZGltcy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NraXAgbXVzdCBiZSAyRCBvciAzRCcpO1xuICB9XG5cbiAgY29uc3QgaGlkZGVuU2l6ZSA9IGlucHV0LmRpbXNbaW5wdXQuZGltcy5sZW5ndGggLSAxXTtcbiAgY29uc3Qgc2VxdWVuY2VMZW5ndGggPSBpbnB1dC5kaW1zW2lucHV0LmRpbXMubGVuZ3RoIC0gMl07XG4gIGlmIChza2lwLmRpbXNbc2tpcC5kaW1zLmxlbmd0aCAtIDFdICE9PSBoaWRkZW5TaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTa2lwIG11c3QgaGF2ZSB0aGUgc2FtZSBoaWRkZW4gc2l6ZSBhcyBpbnB1dCcpO1xuICB9XG4gIGlmIChza2lwLmRpbXNbc2tpcC5kaW1zLmxlbmd0aCAtIDJdICE9PSBzZXF1ZW5jZUxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2tpcCBtdXN0IGhhdmUgdGhlIHNhbWUgc2VxdWVuY2UgbGVuZ3RoIGFzIGlucHV0Jyk7XG4gIH1cblxuICBpZiAoZ2FtbWEuZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dhbW1hIG11c3QgYmUgMUQnKTtcbiAgfVxuICBpZiAoZ2FtbWEuZGltc1tnYW1tYS5kaW1zLmxlbmd0aCAtIDFdICE9PSBoaWRkZW5TaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHYW1tYSBtdXN0IGhhdmUgdGhlIHNhbWUgaGlkZGVuIHNpemUgYXMgaW5wdXQnKTtcbiAgfVxuICBpZiAoaW5wdXRzLmxlbmd0aCA+IDMpIHtcbiAgICBjb25zdCBiZXRhOiBUZW5zb3JWaWV3ID0gaW5wdXRzWzNdO1xuICAgIGlmIChiZXRhLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JldGEgbXVzdCBiZSAxRCcpO1xuICAgIH1cbiAgICBpZiAoYmV0YS5kaW1zW2JldGEuZGltcy5sZW5ndGggLSAxXSAhPT0gaGlkZGVuU2l6ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdCZXRhIG11c3QgaGF2ZSB0aGUgc2FtZSBoaWRkZW4gc2l6ZSBhcyBpbnB1dCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaW5wdXRzLmxlbmd0aCA+IDQpIHtcbiAgICBjb25zdCBiaWFzOiBUZW5zb3JWaWV3ID0gaW5wdXRzWzRdO1xuICAgIGlmIChiaWFzLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JpYXMgbXVzdCBiZSAxRCcpO1xuICAgIH1cbiAgICBpZiAoYmlhcy5kaW1zW2JpYXMuZGltcy5sZW5ndGggLSAxXSAhPT0gaGlkZGVuU2l6ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdCaWFzIG11c3QgaGF2ZSB0aGUgc2FtZSBoaWRkZW4gc2l6ZSBhcyBpbnB1dCcpO1xuICAgIH1cbiAgfVxufTtcblxuY29uc3QgY3JlYXRlU2tpcExheWVyTm9ybVByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogU2tpcExheWVyTm9ybUF0dHJpYnV0ZXMsXG4gIG91dHB1dENvdW50OiBudW1iZXIsXG4gIGlzVHJhaW5pbmc6IGJvb2xlYW4sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHNpbXBsaWZpZWQgPSBhdHRyaWJ1dGVzLnNpbXBsaWZpZWQ7XG5cbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbnB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShpbnB1dFNoYXBlKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNoYXBlO1xuICBjb25zdCBvdXRwdXRTaXplID0gaW5wdXRTaXplO1xuICBjb25zdCBoaWRkZW5TaXplID0gaW5wdXRTaGFwZS5zbGljZSgtMSlbMF07XG4gIGNvbnN0IG1lYW5JbnZTdGREZXZEaW0gPSBpc1RyYWluaW5nID8gaW5wdXRTaGFwZS5zbGljZSgwLCAtMSkuY29uY2F0KDEpIDogW107XG4gIGNvbnN0IGhhc0JldGFJbnB1dCA9ICFzaW1wbGlmaWVkICYmIGlucHV0cy5sZW5ndGggPiAzO1xuICBjb25zdCBoYXNCaWFzSW5wdXQgPSBpbnB1dHMubGVuZ3RoID4gNDtcbiAgY29uc3QgaGFzTWVhbk91dHB1dCA9IGlzVHJhaW5pbmcgJiYgb3V0cHV0Q291bnQgPiAxO1xuICBjb25zdCBoYXNJbnZTdGREZXZPdXRwdXQgPSBpc1RyYWluaW5nICYmIG91dHB1dENvdW50ID4gMjtcbiAgY29uc3QgaGFzSW5wdXRTa2lwQmlhc1N1bU91dHB1dCA9IG91dHB1dENvdW50ID4gMztcbiAgY29uc3Qgd29ya2dyb3VwU2l6ZSA9IDY0O1xuXG4gIGNvbnN0IGNvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKGhpZGRlblNpemUpO1xuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBjb21wb25lbnRzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGhpZGRlblNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmZsb2F0LCBkYXRhOiBhdHRyaWJ1dGVzLmVwc2lsb24gfSxcbiAgXTtcbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgdW5pZm9ybXNBcnJheTogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdjb21wb25lbnRzJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2hpZGRlbl9zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2Vwc2lsb24nLCB0eXBlOiAnZjMyJyB9LFxuICAgIF07XG4gICAgY29uc3QgdmFyaWFibGVzID0gW1xuICAgICAgaW5wdXRWYXJpYWJsZSgneCcsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRzWzBdLmRpbXMsIGNvbXBvbmVudHMpLFxuICAgICAgaW5wdXRWYXJpYWJsZSgnc2tpcCcsIGlucHV0c1sxXS5kYXRhVHlwZSwgaW5wdXRzWzFdLmRpbXMsIGNvbXBvbmVudHMpLFxuICAgICAgaW5wdXRWYXJpYWJsZSgnZ2FtbWEnLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLCBjb21wb25lbnRzKSxcbiAgICBdO1xuICAgIGlmIChoYXNCZXRhSW5wdXQpIHtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKGlucHV0VmFyaWFibGUoJ2JldGEnLCBpbnB1dHNbM10uZGF0YVR5cGUsIGlucHV0c1szXS5kaW1zLCBjb21wb25lbnRzKSk7XG4gICAgfVxuICAgIGlmIChoYXNCaWFzSW5wdXQpIHtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKGlucHV0VmFyaWFibGUoJ2JpYXMnLCBpbnB1dHNbNF0uZGF0YVR5cGUsIGlucHV0c1s0XS5kaW1zLCBjb21wb25lbnRzKSk7XG4gICAgfVxuICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlLCBjb21wb25lbnRzKSk7XG4gICAgaWYgKGhhc01lYW5PdXRwdXQpIHtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dFZhcmlhYmxlKCdtZWFuX291dHB1dCcsIERhdGFUeXBlLmZsb2F0LCBtZWFuSW52U3RkRGV2RGltKSk7XG4gICAgfVxuICAgIGlmIChoYXNJbnZTdGREZXZPdXRwdXQpIHtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dFZhcmlhYmxlKCdpbnZfc3RkX291dHB1dCcsIERhdGFUeXBlLmZsb2F0LCBtZWFuSW52U3RkRGV2RGltKSk7XG4gICAgfVxuICAgIGlmIChoYXNJbnB1dFNraXBCaWFzU3VtT3V0cHV0KSB7XG4gICAgICB2YXJpYWJsZXMucHVzaChvdXRwdXRWYXJpYWJsZSgnaW5wdXRfc2tpcF9iaWFzX3N1bScsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUsIGNvbXBvbmVudHMpKTtcbiAgICB9XG4gICAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUoaW5wdXRzWzBdLmRhdGFUeXBlKTtcbiAgICBjb25zdCB2ZWNEYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZShEYXRhVHlwZS5mbG9hdCwgY29tcG9uZW50cyk7XG4gICAgcmV0dXJuIGBcblxuICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3Jtc0FycmF5KS5kZWNsYXJlVmFyaWFibGVzKC4uLnZhcmlhYmxlcyl9XG4gICAgICB2YXI8d29ya2dyb3VwPiBzdW1fc2hhcmVkIDogYXJyYXk8JHt2ZWNEYXRhVHlwZX0sICR7d29ya2dyb3VwU2l6ZX0+O1xuICAgICAgdmFyPHdvcmtncm91cD4gc3VtX3NxdWFyZWRfc2hhcmVkIDogYXJyYXk8JHt2ZWNEYXRhVHlwZX0sICR7d29ya2dyb3VwU2l6ZX0+O1xuXG4gICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoW3dvcmtncm91cFNpemUsIDEsIDFdKX1cbiAgICAgICAgbGV0IGl4ID0gbG9jYWxfaWQueDtcbiAgICAgICAgbGV0IGl5ID0gZ2xvYmFsX2lkLnggLyAke3dvcmtncm91cFNpemV9O1xuXG4gICAgICAgIGxldCBoaWRkZW5fc2l6ZV92ZWN0b3JpemVkOiB1MzIgPSB1bmlmb3Jtcy5oaWRkZW5fc2l6ZSAvIHVuaWZvcm1zLmNvbXBvbmVudHM7XG4gICAgICAgIHZhciBzdHJpZGUgPSBoaWRkZW5fc2l6ZV92ZWN0b3JpemVkIC8gJHt3b3JrZ3JvdXBTaXplfTtcbiAgICAgICAgbGV0IG9mZnNldCA9IGl4ICogc3RyaWRlICsgaXkgKiBoaWRkZW5fc2l6ZV92ZWN0b3JpemVkO1xuICAgICAgICBsZXQgb2Zmc2V0MWQgPSBzdHJpZGUgKiBpeDtcbiAgICAgICAgaWYgKGl4ID09ICR7d29ya2dyb3VwU2l6ZSAtIDF9KSB7XG4gICAgICAgICAgc3RyaWRlID0gaGlkZGVuX3NpemVfdmVjdG9yaXplZCAtIHN0cmlkZSAqIGl4O1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGk6IHUzMiA9IDA7IGkgPCBzdHJpZGU7IGkrKykge1xuICAgICAgICAgIGxldCBza2lwX3ZhbHVlID0gc2tpcFtvZmZzZXQgKyBpXTtcbiAgICAgICAgICBsZXQgYmlhc192YWx1ZSA9ICR7aGFzQmlhc0lucHV0ID8gJ2JpYXNbb2Zmc2V0MWQgKyBpXScgOiBkYXRhVHlwZSArICcoMC4wKSd9O1xuICAgICAgICAgIGxldCBpbnB1dF92YWx1ZSA9IHhbb2Zmc2V0ICsgaV07XG4gICAgICAgICAgbGV0IHZhbHVlID0gaW5wdXRfdmFsdWUgKyBza2lwX3ZhbHVlICsgYmlhc192YWx1ZTtcbiAgICAgICAgICAke2hhc0lucHV0U2tpcEJpYXNTdW1PdXRwdXQgPyAnaW5wdXRfc2tpcF9iaWFzX3N1bVtvZmZzZXQgKyBpXSA9IHZhbHVlOycgOiAnJ31cbiAgICAgICAgICBvdXRwdXRbb2Zmc2V0ICsgaV0gPSB2YWx1ZTtcbiAgICAgICAgICBsZXQgZjMyX3ZhbHVlID0gJHtjYXN0VG9GMzIoZGF0YVR5cGUsIGNvbXBvbmVudHMsICd2YWx1ZScpfTtcbiAgICAgICAgICBzdW1fc2hhcmVkW2l4XSArPSBmMzJfdmFsdWU7XG4gICAgICAgICAgc3VtX3NxdWFyZWRfc2hhcmVkW2l4XSArPSBmMzJfdmFsdWUgKiBmMzJfdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgd29ya2dyb3VwQmFycmllcigpO1xuXG4gICAgICAgIHZhciByZWR1Y2Vfc2l6ZSA6IHUzMiA9ICR7d29ya2dyb3VwU2l6ZX07XG4gICAgICAgIGZvciAodmFyIGN1cnJfc2l6ZSA9IHJlZHVjZV9zaXplID4+IDE7ICBjdXJyX3NpemUgPiAwOyBjdXJyX3NpemUgPSByZWR1Y2Vfc2l6ZSA+PiAxKSB7XG4gICAgICAgICAgcmVkdWNlX3NpemUgPSBjdXJyX3NpemUgKyAocmVkdWNlX3NpemUgJiAxKTtcbiAgICAgICAgICBpZiAoaXggPCBjdXJyX3NpemUpIHtcbiAgICAgICAgICAgIHN1bV9zaGFyZWRbaXhdICs9IHN1bV9zaGFyZWRbaXggKyByZWR1Y2Vfc2l6ZV07XG4gICAgICAgICAgICBzdW1fc3F1YXJlZF9zaGFyZWRbaXhdICs9IHN1bV9zcXVhcmVkX3NoYXJlZFtpeCArIHJlZHVjZV9zaXplXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgd29ya2dyb3VwQmFycmllcigpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHN1bSA9IHN1bV9zaGFyZWRbMF07XG4gICAgICAgIGxldCBzcXVhcmVfc3VtID0gc3VtX3NxdWFyZWRfc2hhcmVkWzBdO1xuICAgICAgICBsZXQgbWVhbiA9ICR7c3VtVmVjdG9yKCdzdW0nLCBjb21wb25lbnRzKX0gLyBmMzIodW5pZm9ybXMuaGlkZGVuX3NpemUpO1xuICAgICAgICBsZXQgaW52X3N0ZF9kZXYgPSBpbnZlcnNlU3FydCgke3N1bVZlY3Rvcignc3F1YXJlX3N1bScsIGNvbXBvbmVudHMpfSAvIGYzMih1bmlmb3Jtcy5oaWRkZW5fc2l6ZSkgJHtcbiAgICAgICAgICBzaW1wbGlmaWVkID8gJycgOiAnLSBtZWFuICogbWVhbidcbiAgICAgICAgfSArIHVuaWZvcm1zLmVwc2lsb24pO1xuICAgICAgICAke2hhc01lYW5PdXRwdXQgPyAnbWVhbl9vdXRwdXRbZ2xvYmFsX2lkeF0gPSBtZWFuOycgOiAnJ31cbiAgICAgICAgJHtoYXNJbnZTdGREZXZPdXRwdXQgPyAnaW52X3N0ZF9vdXRwdXRbZ2xvYmFsX2lkeF0gPSBpbnZfc3RkX2RldjsnIDogJyd9XG5cbiAgICAgICAgZm9yICh2YXIgaTogdTMyID0gMDsgaSA8IHN0cmlkZTsgaSsrKSB7XG4gICAgICAgICAgb3V0cHV0W29mZnNldCArIGldID0gKG91dHB1dFtvZmZzZXQgKyBpXSAke3NpbXBsaWZpZWQgPyAnJyA6IGAtICR7ZGF0YVR5cGV9KG1lYW4pYH0pICpcbiAgICAgICAgICAgICR7ZGF0YVR5cGV9KGludl9zdGRfZGV2KSAqIGdhbW1hW29mZnNldDFkICsgaV1cbiAgICAgICAgICAgICR7aGFzQmV0YUlucHV0ID8gJysgYmV0YVtvZmZzZXQxZCArIGldJyA6ICcnfTtcbiAgICAgICAgfVxuICAgICAgfWA7XG4gIH07XG4gIGNvbnN0IG91dHB1dHMgPSBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XTtcbiAgaWYgKG91dHB1dENvdW50ID4gMSkge1xuICAgIG91dHB1dHMucHVzaCh7IGRpbXM6IG1lYW5JbnZTdGREZXZEaW0sIGRhdGFUeXBlOiBEYXRhVHlwZS5mbG9hdCB9KTtcbiAgfVxuICBpZiAob3V0cHV0Q291bnQgPiAyKSB7XG4gICAgb3V0cHV0cy5wdXNoKHsgZGltczogbWVhbkludlN0ZERldkRpbSwgZGF0YVR5cGU6IERhdGFUeXBlLmZsb2F0IH0pO1xuICB9XG4gIGlmIChvdXRwdXRDb3VudCA+IDMpIHtcbiAgICBvdXRwdXRzLnB1c2goeyBkaW1zOiBpbnB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH0pO1xuICB9XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ1NraXBMYXllck5vcm1hbGl6YXRpb24nLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHtjb21wb25lbnRzfTske2hhc01lYW5PdXRwdXR9OyR7aGFzSW52U3RkRGV2T3V0cHV0fTske2hhc0lucHV0U2tpcEJpYXNTdW1PdXRwdXR9YCxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzOiBpbnB1dHMubWFwKChfaW5wdXQsIF9pbmRleCkgPT4gJ3R5cGUnKSxcbiAgICB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0cyxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHtcbiAgICAgICAgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyBoaWRkZW5TaXplKSxcbiAgICAgIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3Qgc2tpcExheWVyTm9ybSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogU2tpcExheWVyTm9ybUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgLy8gVE9ETzogaW5pdGlhbGl6ZSBpc1RyYWluaW5nIGZyb20gQ29tcHV0ZUNvbnRleHRcbiAgY29uc3QgaXNUcmFpbmluZyA9IGZhbHNlO1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIC8vIE1lYW4gYW5kIEludlN0ZERldiBhcmUgb25seSB1c2VkIGluIHRyYWluaW5nIG1vZGUgYW5kIGFyZSBub3QgcmVxdWlyZWQgZm9yIGluZmVyZW5jZS5cbiAgLy8gVGhleSBhcmUgYWRkZWQgaGVyZSBmb3IgY29tcGxldGVuZXNzIG9ubHkuXG4gIGNvbnN0IG91dHB1dHMgPSBbMF07XG4gIGlmIChjb250ZXh0Lm91dHB1dENvdW50ID4gMSkge1xuICAgIG91dHB1dHMucHVzaChpc1RyYWluaW5nID8gMSA6IC0zKTtcbiAgfVxuICBpZiAoY29udGV4dC5vdXRwdXRDb3VudCA+IDIpIHtcbiAgICBvdXRwdXRzLnB1c2goaXNUcmFpbmluZyA/IDIgOiAtMyk7XG4gIH1cbiAgaWYgKGNvbnRleHQub3V0cHV0Q291bnQgPiAzKSB7XG4gICAgb3V0cHV0cy5wdXNoKDMpO1xuICB9XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVTa2lwTGF5ZXJOb3JtUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMsIGNvbnRleHQub3V0cHV0Q291bnQsIGlzVHJhaW5pbmcpLCB7XG4gICAgb3V0cHV0cyxcbiAgfSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0sIFRlbnNvckluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLFxuICBnZXRFbGVtZW50QXQsXG4gIEluZGljZXNIZWxwZXIsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2xpY2VBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgc3RhcnRzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgZW5kczogbnVtYmVyW107XG4gIHJlYWRvbmx5IGF4ZXM6IG51bWJlcltdO1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogU2xpY2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0b28gZmV3IGlucHV0cycpO1xuICB9XG4gIGlmIChhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoICE9PSAwKSB7XG4gICAgaWYgKGF0dHJpYnV0ZXMuYXhlcy5sZW5ndGggIT09IGF0dHJpYnV0ZXMuc3RhcnRzLmxlbmd0aCB8fCBhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoICE9PSBhdHRyaWJ1dGVzLmVuZHMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2F4ZXMsIHN0YXJ0cyBhbmQgZW5kcyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoJyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGF0dHJpYnV0ZXMuc3RhcnRzLmxlbmd0aCAhPT0gYXR0cmlidXRlcy5lbmRzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc3RhcnRzIGFuZCBlbmRzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGgnKTtcbiAgfVxuICBpbnB1dHMuc2xpY2UoMSkuZm9yRWFjaCgoXywgaWR4KSA9PiB7XG4gICAgaWYgKGlucHV0c1tpZHggKyAxXS5kYXRhVHlwZSAhPT0gRGF0YVR5cGUuaW50MzIgJiYgaW5wdXRzW2lkeCArIDFdLmRhdGFUeXBlICE9PSBEYXRhVHlwZS5pbnQ2NCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnB1dCAke2lkeH0gbXVzdCBiZSBhbiBhcnJheSBvZiBpbnQzMiBvciBpbnQ2NGApO1xuICAgIH1cbiAgfSk7XG59O1xuXG5jb25zdCByZWFkSW5wdXQgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGlkeDogbnVtYmVyKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCBpbnB1dDogbnVtYmVyW10gPSBbXTtcbiAgaWYgKGlucHV0cy5sZW5ndGggPiBpZHgpIHtcbiAgICBpZiAoaW5wdXRzW2lkeF0uZGF0YVR5cGUgPT09IERhdGFUeXBlLmludDY0KSB7XG4gICAgICBpbnB1dHNbaWR4XS5nZXRCaWdJbnQ2NEFycmF5KCkuZm9yRWFjaCgodikgPT4gaW5wdXQucHVzaChOdW1iZXIodikpKTtcbiAgICB9IGVsc2UgaWYgKGlucHV0c1tpZHhdLmRhdGFUeXBlID09PSBEYXRhVHlwZS5pbnQzMikge1xuICAgICAgaW5wdXRzW2lkeF0uZ2V0SW50MzJBcnJheSgpLmZvckVhY2goKHYpID0+IGlucHV0LnB1c2goTnVtYmVyKHYpKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgJHtpZHh9IG11c3QgYmUgYW4gYXJyYXkgb2YgaW50MzIgb3IgaW50NjRgKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGlucHV0O1xufTtcblxuY29uc3QgY3JlYXRlU2xpY2VBdHRyaWJ1dGVzRnJvbUlucHV0cyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IFNsaWNlQXR0cmlidXRlcyxcbik6IFNsaWNlQXR0cmlidXRlcyA9PiB7XG4gIGlmIChpbnB1dHMubGVuZ3RoID4gMSkge1xuICAgIGNvbnN0IHN0YXJ0czogbnVtYmVyW10gPSByZWFkSW5wdXQoaW5wdXRzLCAxKTtcbiAgICBjb25zdCBlbmRzOiBudW1iZXJbXSA9IHJlYWRJbnB1dChpbnB1dHMsIDIpO1xuICAgIGxldCBheGVzOiBudW1iZXJbXSA9IHJlYWRJbnB1dChpbnB1dHMsIDMpO1xuICAgIGlmIChheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgYXhlcyA9IFsuLi5BcnJheShpbnB1dHNbMF0uZGltcy5sZW5ndGgpLmtleXMoKV07XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBzdGFydHMsIGVuZHMsIGF4ZXMgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGF0dHJpYnV0ZXM7XG4gIH1cbn07XG5cbmNvbnN0IGZpeFN0YXJ0RW5kVmFsdWVzID0gKFxuICB2YWx1ZTogbnVtYmVyLFxuICBpbmRleDogbnVtYmVyLFxuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXhlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHN0ZXBzOiByZWFkb25seSBudW1iZXJbXSxcbik6IG51bWJlciA9PiB7XG4gIGxldCBuZXdWYWx1ZSA9IHZhbHVlO1xuICBpZiAodmFsdWUgPCAwKSB7XG4gICAgbmV3VmFsdWUgKz0gaW5wdXRTaGFwZVtheGVzW2luZGV4XV07XG4gIH1cbiAgaWYgKHN0ZXBzW2luZGV4XSA8IDApIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5taW4obmV3VmFsdWUsIGlucHV0U2hhcGVbYXhlc1tpbmRleF1dIC0gMSkpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBNYXRoLm1heCgwLCBNYXRoLm1pbihuZXdWYWx1ZSwgaW5wdXRTaGFwZVtheGVzW2luZGV4XV0pKTtcbiAgfVxufTtcblxuY29uc3QgY2FsY3VsYXRlSW5wdXRJbmRpY2VzSW1wbCA9IChcbiAgaW5wdXQ6IEluZGljZXNIZWxwZXIsXG4gIG91dHB1dDogSW5kaWNlc0hlbHBlcixcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBzdHJpbmcgPT5cbiAgYGZuIGNhbGN1bGF0ZUlucHV0SW5kaWNlcyhvdXRwdXRfaW5kaWNlczogJHtvdXRwdXQudHlwZS5pbmRpY2VzfSkgLT4gJHtpbnB1dC50eXBlLmluZGljZXN9IHtcbiAgICAgICAgICB2YXIgaW5wdXRfaW5kaWNlczogJHtpbnB1dC50eXBlLmluZGljZXN9O1xuICAgICAgICAgIHZhciBjYXJyeSA9IDB1O1xuICAgICAgICAgIGZvciAodmFyIGkgPSAke2lucHV0U2hhcGUubGVuZ3RoIC0gMX07IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBsZXQgaW5wdXRfc2hhcGVfaSA9ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5pbnB1dF9zaGFwZScsICdpJywgaW5wdXRTaGFwZS5sZW5ndGgpfTtcbiAgICAgICAgICAgIGxldCBzdGVwc19pID0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnN0ZXBzJywgJ2knLCBpbnB1dFNoYXBlLmxlbmd0aCl9O1xuICAgICAgICAgICAgbGV0IHNpZ25zX2kgPSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMuc2lnbnMnLCAnaScsIGlucHV0U2hhcGUubGVuZ3RoKX07XG4gICAgICAgICAgICBsZXQgc3RhcnRzX2kgPSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMuc3RhcnRzJywgJ2knLCBpbnB1dFNoYXBlLmxlbmd0aCl9O1xuICAgICAgICAgICAgdmFyIG91dHB1dF9pbmRleCA9ICR7b3V0cHV0LmluZGljZXNHZXQoJ291dHB1dF9pbmRpY2VzJywgJ2knKX07XG4gICAgICAgICAgICB2YXIgaW5wdXRfaW5kZXggPSBvdXRwdXRfaW5kZXggKiBzdGVwc19pICsgc3RhcnRzX2kgKyBjYXJyeTtcbiAgICAgICAgICAgIGNhcnJ5ID0gaW5wdXRfaW5kZXggLyBpbnB1dF9zaGFwZV9pO1xuICAgICAgICAgICAgaW5wdXRfaW5kZXggPSBpbnB1dF9pbmRleCAlIGlucHV0X3NoYXBlX2k7XG4gICAgICAgICAgICBpZiAoc2lnbnNfaSA8IDApIHtcbiAgICAgICAgICAgICAgaW5wdXRfaW5kZXggPSBpbnB1dF9zaGFwZV9pIC0gaW5wdXRfaW5kZXggLSAxdSArIHN0YXJ0c19pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgJHtpbnB1dC5pbmRpY2VzU2V0KCdpbnB1dF9pbmRpY2VzJywgJ2knLCAnaW5wdXRfaW5kZXgnKX07XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBpbnB1dF9pbmRpY2VzO1xuICAgICAgfWA7XG5cbmNvbnN0IGNyZWF0ZVNsaWNlUHJvZ3JhbUluZm8gPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IFNsaWNlQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbnB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShpbnB1dFNoYXBlKTtcbiAgY29uc3QgYXhlcyA9XG4gICAgYXR0cmlidXRlcy5heGVzLmxlbmd0aCA+IDBcbiAgICAgID8gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4ZXMoYXR0cmlidXRlcy5heGVzLCBpbnB1dFNoYXBlLmxlbmd0aClcbiAgICAgIDogWy4uLkFycmF5KGlucHV0U2hhcGUubGVuZ3RoKS5rZXlzKCldO1xuICBsZXQgc3RlcHMgPSByZWFkSW5wdXQoaW5wdXRzLCA0KTtcbiAgc3RlcHMuZm9yRWFjaChcbiAgICAoc3RlcCkgPT5cbiAgICAgIHN0ZXAgIT09IDAgfHxcbiAgICAgICgoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignc3RlcCBjYW5ub3QgYmUgMCcpO1xuICAgICAgfSksXG4gICk7XG4gIGlmIChzdGVwcy5sZW5ndGggPT09IDApIHtcbiAgICBzdGVwcyA9IEFycmF5KGF4ZXMubGVuZ3RoKS5maWxsKDEpO1xuICB9XG4gIGNvbnN0IHN0YXJ0cyA9IGF0dHJpYnV0ZXMuc3RhcnRzLm1hcCgoc3RhcnQsIGkpID0+IGZpeFN0YXJ0RW5kVmFsdWVzKHN0YXJ0LCBpLCBpbnB1dFNoYXBlLCBheGVzLCBzdGVwcykpO1xuXG4gIGNvbnN0IGVuZHMgPSBhdHRyaWJ1dGVzLmVuZHMubWFwKChlbmQsIGkpID0+IGZpeFN0YXJ0RW5kVmFsdWVzKGVuZCwgaSwgaW5wdXRTaGFwZSwgYXhlcywgc3RlcHMpKTtcblxuICBpZiAoYXhlcy5sZW5ndGggIT09IHN0YXJ0cy5sZW5ndGggfHwgYXhlcy5sZW5ndGggIT09IGVuZHMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzdGFydCwgZW5kcyBhbmQgYXhlcyBzaG91bGQgaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgZWxlbWVudHMnKTtcbiAgfVxuXG4gIGlmIChheGVzLmxlbmd0aCAhPT0gaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0U2hhcGUubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmICghYXhlcy5pbmNsdWRlcyhpKSkge1xuICAgICAgICBzdGFydHMuc3BsaWNlKGksIDAsIDApO1xuICAgICAgICBlbmRzLnNwbGljZShpLCAwLCBpbnB1dFNoYXBlW2ldKTtcbiAgICAgICAgc3RlcHMuc3BsaWNlKGksIDAsIDEpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCBzaWducyA9IHN0ZXBzLm1hcCgoc3RlcCkgPT4gTWF0aC5zaWduKHN0ZXApKTtcbiAgLy8gQ29udmVydCBuZWdhdGl2ZSBzdGVwcyB0byBwb3NpdGl2ZSBzdGVwcyBhbmQgcmV2ZXJzZSBzdGFydHMgYW5kIGVuZHNcbiAgc3RlcHMuZm9yRWFjaCgoc3RlcCwgaSwgYXJyYXkpID0+IHtcbiAgICBpZiAoc3RlcCA8IDApIHtcbiAgICAgIGNvbnN0IG51bVN0ZXBzID0gKGVuZHNbaV0gLSBzdGFydHNbaV0pIC8gc3RlcDtcbiAgICAgIGNvbnN0IG5ld0VuZCA9IHN0YXJ0c1tpXTtcbiAgICAgIGNvbnN0IG5ld1N0YXJ0ID0gbmV3RW5kICsgbnVtU3RlcHMgKiBzdGVwc1tpXTtcbiAgICAgIHN0YXJ0c1tpXSA9IG5ld1N0YXJ0O1xuICAgICAgZW5kc1tpXSA9IG5ld0VuZDtcbiAgICAgIGFycmF5W2ldID0gLXN0ZXA7XG4gICAgfVxuICB9KTtcbiAgLy8gT3V0cHV0IHJhbmsgaXMgZXhwZWN0ZWQgdG8gYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBpbnB1dCByYW5rLlxuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0U2hhcGUuc2xpY2UoMCk7XG4gIGF4ZXMuZm9yRWFjaCgoYXhpcywgXykgPT4ge1xuICAgIG91dHB1dFNoYXBlW2F4aXNdID0gTWF0aC5jZWlsKChlbmRzW2F4aXNdIC0gc3RhcnRzW2F4aXNdKSAvIHN0ZXBzW2F4aXNdKTtcbiAgfSk7XG4gIGNvbnN0IG91dHB1dFRlbnNvckluZm86IFRlbnNvckluZm8gPSB7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH07XG5cbiAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3QgaW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdpbnB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgIHsgbmFtZTogJ291dHB1dFNpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgIHsgbmFtZTogJ3N0YXJ0cycsIHR5cGU6ICd1MzInLCBsZW5ndGg6IHN0YXJ0cy5sZW5ndGggfSxcbiAgICB7IG5hbWU6ICdzaWducycsIHR5cGU6ICdpMzInLCBsZW5ndGg6IHNpZ25zLmxlbmd0aCB9LFxuICAgIHsgbmFtZTogJ3N0ZXBzJywgdHlwZTogJ3UzMicsIGxlbmd0aDogc3RlcHMubGVuZ3RoIH0sXG4gIF07XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHN0YXJ0cyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IHNpZ25zIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHN0ZXBzIH0sXG4gICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRzWzBdLmRpbXMsIG91dHB1dFNoYXBlKSxcbiAgXTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IGBcbiAgICAgICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIG91dHB1dCl9XG4gICAgICAgICR7Y2FsY3VsYXRlSW5wdXRJbmRpY2VzSW1wbChpbnB1dCwgb3V0cHV0LCBpbnB1dFNoYXBlKX1cbiAgICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAgICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0U2l6ZScpfVxuICAgICAgICAgIGxldCBvdXRwdXRfaW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcbiAgICAgICAgICBsZXQgaW5wdXRfaW5kaWNlcyA9IGNhbGN1bGF0ZUlucHV0SW5kaWNlcyhvdXRwdXRfaW5kaWNlcyk7XG4gICAgICAgICAgJHtvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCBpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKSl9XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnU2xpY2UnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke3NpZ25zLmxlbmd0aH1fJHtzdGFydHMubGVuZ3RofV8ke3N0ZXBzLmxlbmd0aH1gLCBpbnB1dERlcGVuZGVuY2llczogWydyYW5rJ10gfSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFtvdXRwdXRUZW5zb3JJbmZvXSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKGlucHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHNsaWNlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBTbGljZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBjb25zdCB1cGRhdGVkQXR0cmlidXRlcyA9IGNyZWF0ZVNsaWNlQXR0cmlidXRlc0Zyb21JbnB1dHMoY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlU2xpY2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0cywgdXBkYXRlZEF0dHJpYnV0ZXMpLCB7IGlucHV0czogWzBdIH0pO1xuICAvLyBpZiAoU2hhcGVVdGlsLnNpemUocHJvZ3JhbS5vdXRwdXRzWzBdLmRpbXMpID4gMCkge1xuICAvLyAgIGNvbnRleHQuY29tcHV0ZShwcm9ncmFtSW5mb0xvYWRlciwge2lucHV0czogWzBdfSk7XG4gIC8vIH0gZWxzZSB7XG4gIC8vICAgLy8gVE9ETzogc3VwcG9ydCBlbXB0eSBvdXRwdXRcbiAgLy8gICB0aHJvdyBuZXcgRXJyb3IoJ3NsaWNlOiBvdXRwdXQgc2l6ZSBpcyAwJyk7XG4gIC8vIH1cbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNsaWNlQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFNsaWNlQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IHN0YXJ0cyA9IGF0dHJpYnV0ZXMuc3RhcnRzIGFzIG51bWJlcltdO1xuICBjb25zdCBlbmRzID0gYXR0cmlidXRlcy5lbmRzIGFzIG51bWJlcltdO1xuICBjb25zdCBheGVzID0gYXR0cmlidXRlcy5heGVzIGFzIG51bWJlcltdO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgc3RhcnRzLCBlbmRzLCBheGVzIH0pO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLy8gVE9ETzogdGhpcyBpcyB0aGUgc2FtZSBuYWl2ZSBpbXBsZW1lbnRhdGlvbiB3ZSB1c2UgZm9yIHJlZHVjZSB0aGF0IGhhc1xuLy8gcGVyZm9ybWFuY2UgbGltaXRhdGlvbnMgd2hlbiB0aGUgcmVkdWNlZCBheGlzIGlzIGxvbmcuIE5lZWQgdG8gYWRkXG4vLyBhIG9wdGltaXplZCBjb2RlcGF0aCBmb3IgdGhpcy5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvIH0gZnJvbSAnLi90cmFuc3Bvc2UnO1xuXG5pbXBvcnQge1xuICBnZXRNYXhDb21wb25lbnRzLFxuICBpbnB1dFZhcmlhYmxlLFxuICBvdXRwdXRWYXJpYWJsZSxcbiAgU2hhZGVySGVscGVyLFxuICBzdW1WZWN0b3IsXG4gIHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZSxcbn0gZnJvbSAnLi9jb21tb24nO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTb2Z0bWF4IG9wIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgU29mdG1heEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG59XG5cbmNvbnN0IGNyZWF0ZVNvZnRtYXhQcm9ncmFtSW5mbyA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogU29mdG1heEF0dHJpYnV0ZXMpID0+IHtcbiAgY29uc3QgaW5wdXQgPSBjb250ZXh0LmlucHV0c1swXTtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0LmRpbXM7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShpbnB1dFNoYXBlKTtcbiAgY29uc3QgaW5wdXRSYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0UmFuayk7XG4gIGNvbnN0IGlzVHJhbnNwb3NlUmVxdWlyZWQgPSBheGlzIDwgaW5wdXRTaGFwZS5sZW5ndGggLSAxO1xuICBsZXQgdHJhbnNwb3NlZElucHV0OiBUZW5zb3JWaWV3O1xuICBsZXQgcGVybTogbnVtYmVyW10gPSBbXTtcblxuICBpZiAoaXNUcmFuc3Bvc2VSZXF1aXJlZCkge1xuICAgIHBlcm0gPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiBpbnB1dFJhbmsgfSwgKF8sIGkpID0+IGkpO1xuICAgIHBlcm1bYXhpc10gPSBpbnB1dFJhbmsgLSAxO1xuICAgIHBlcm1baW5wdXRSYW5rIC0gMV0gPSBheGlzO1xuXG4gICAgdHJhbnNwb3NlZElucHV0ID0gY29udGV4dC5jb21wdXRlKGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvKGlucHV0LCBwZXJtKSwge1xuICAgICAgaW5wdXRzOiBbaW5wdXRdLFxuICAgICAgb3V0cHV0czogWy0xXSxcbiAgICB9KVswXTtcbiAgfSBlbHNlIHtcbiAgICB0cmFuc3Bvc2VkSW5wdXQgPSBpbnB1dDtcbiAgfVxuXG4gIGNvbnN0IHRyYW5zcG9zZWRJbnB1dFNoYXBlID0gdHJhbnNwb3NlZElucHV0LmRpbXM7XG4gIGNvbnN0IGNvbHMgPSB0cmFuc3Bvc2VkSW5wdXRTaGFwZVtpbnB1dFJhbmsgLSAxXTtcbiAgY29uc3Qgcm93cyA9IG91dHB1dFNpemUgLyBjb2xzO1xuICBjb25zdCBjb21wb25lbnRzID0gZ2V0TWF4Q29tcG9uZW50cyhjb2xzKTtcbiAgY29uc3QgcGFja2VkQ29scyA9IGNvbHMgLyBjb21wb25lbnRzO1xuICBsZXQgV0cgPSA2NDtcbiAgLy8gSWYgb25seSBvbmUgd29ya2dyb3VwIGlzIGRpc3BhdGNoZWQsIGluY3JlYXNlIHdvcmtncm91cFNpemUgdG8gaW1wcm92ZSBwYXJhbGxlbGlzbS5cbiAgaWYgKHJvd3MgPT09IDEpIHtcbiAgICBXRyA9IDI1NjtcbiAgfVxuICBjb25zdCBtYXhWZWN0b3IgPSAobmFtZTogc3RyaW5nLCBjb21wb25lbnRzOiBudW1iZXIpID0+IHtcbiAgICBpZiAoY29tcG9uZW50cyA9PT0gNCkge1xuICAgICAgcmV0dXJuIGBtYXgobWF4KCR7bmFtZX0ueCwgJHtuYW1lfS55KSwgbWF4KCR7bmFtZX0ueiwgJHtuYW1lfS53KSlgO1xuICAgIH0gZWxzZSBpZiAoY29tcG9uZW50cyA9PT0gMikge1xuICAgICAgcmV0dXJuIGBtYXgoJHtuYW1lfS54LCAke25hbWV9LnkpYDtcbiAgICB9IGVsc2UgaWYgKGNvbXBvbmVudHMgPT09IDMpIHtcbiAgICAgIHJldHVybiBgbWF4KG1heCgke25hbWV9LngsICR7bmFtZX0ueSksICR7bmFtZX0ueilgO1xuICAgIH1cblxuICAgIHJldHVybiBuYW1lO1xuICB9O1xuICBjb25zdCB4ID0gaW5wdXRWYXJpYWJsZSgneCcsIHRyYW5zcG9zZWRJbnB1dC5kYXRhVHlwZSwgdHJhbnNwb3NlZElucHV0LmRpbXMsIGNvbXBvbmVudHMpO1xuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgncmVzdWx0JywgdHJhbnNwb3NlZElucHV0LmRhdGFUeXBlLCB0cmFuc3Bvc2VkSW5wdXQuZGltcywgY29tcG9uZW50cyk7XG4gIGNvbnN0IHZhbHVlVHlwZSA9IHgudHlwZS52YWx1ZTtcbiAgLy8gNi4yLjQgaW4gd2dzbCBzcGVjXG4gIGNvbnN0IHRocmVhZE1heERlY2wgPVxuICAgIHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZSh0cmFuc3Bvc2VkSW5wdXQuZGF0YVR5cGUpID09PSAnZjMyJ1xuICAgICAgPyBgdmFyIHRocmVhZE1heCA9ICR7dmFsdWVUeXBlfSgtMy40MDI4MjM0NjYzODUyODg2ZSszOGYpO2BcbiAgICAgIDogYHZhciB0aHJlYWRNYXggPSAke3ZhbHVlVHlwZX0oLTY1NTA0LjBoKTtgO1xuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IGBcbiAgICAgIHZhcjx3b3JrZ3JvdXA+IHJvd01heFNoYXJlZCA6ICR7dmFsdWVUeXBlfTtcbiAgICAgIHZhcjx3b3JrZ3JvdXA+IHJvd1N1bVNoYXJlZCA6ICR7dmFsdWVUeXBlfTtcbiAgICAgIHZhcjx3b3JrZ3JvdXA+IHRocmVhZFNoYXJlZCA6IGFycmF5PCR7dmFsdWVUeXBlfSwgJHtXR30+O1xuXG4gICAgICBmbiBnZXRWYWx1ZShyb3c6IGkzMiwgY29sOiBpMzIsIHJvd19zdHJpZGU6IGkzMikgLT4gJHt2YWx1ZVR5cGV9IHtcbiAgICAgICAgbGV0IGluZGV4ID0gcm93ICogcm93X3N0cmlkZSArIGNvbDtcbiAgICAgICAgcmV0dXJuIHhbaW5kZXhdO1xuICAgICAgfVxuXG4gICAgICBmbiBzZXRWYWx1ZShyb3c6IGkzMiwgY29sOiBpMzIsIHJvd19zdHJpZGU6IGkzMiwgdmFsdWU6ICR7dmFsdWVUeXBlfSkge1xuICAgICAgICBsZXQgaW5kZXggPSByb3cgKiByb3dfc3RyaWRlICsgY29sO1xuICAgICAgICByZXN1bHRbaW5kZXhdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ3BhY2tlZENvbHMnLCAnaTMyJykuZGVjbGFyZVZhcmlhYmxlcyh4LCBvdXRwdXQpfVxuICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KFdHKX1cbiAgICAgICAgbGV0IGdpbmRleCA9IGkzMihnbG9iYWxfaWR4KTtcbiAgICAgICAgbGV0IGxpbmRleCA9IGkzMihsb2NhbF9pZHgpO1xuICAgICAgICBjb25zdCB3ZyA9ICR7V0d9O1xuICAgICAgICBsZXQgcm93ID0gZ2luZGV4IC8gd2c7XG4gICAgICAgIGxldCBjb2xzID0gdW5pZm9ybXMucGFja2VkQ29scztcbiAgICAgICAgbGV0IHJvd19zdHJpZGUgOiBpMzIgPSB1bmlmb3Jtcy5wYWNrZWRDb2xzO1xuXG4gICAgICAgIC8vIGZpbmQgdGhlIHJvd3MgbWF4XG4gICAgICAgICR7dGhyZWFkTWF4RGVjbH1cbiAgICAgICAgZm9yICh2YXIgY29sID0gbGluZGV4OyBjb2wgPCBjb2xzOyBjb2wgKz0gd2cpIHtcbiAgICAgICAgICBsZXQgdmFsdWUgPSBnZXRWYWx1ZShyb3csIGNvbCwgcm93X3N0cmlkZSk7XG4gICAgICAgICAgdGhyZWFkTWF4ID0gbWF4KHRocmVhZE1heCwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW5kZXggPCBjb2xzKSB7XG4gICAgICAgICAgdGhyZWFkU2hhcmVkW2xpbmRleF0gPSB0aHJlYWRNYXg7XG4gICAgICAgIH1cbiAgICAgICAgd29ya2dyb3VwQmFycmllcigpO1xuXG4gICAgICAgIHZhciByZWR1Y2VTaXplID0gbWluKGNvbHMsIHdnKTtcbiAgICAgICAgZm9yICh2YXIgY3VyclNpemUgPSByZWR1Y2VTaXplID4+IDE7ICBjdXJyU2l6ZSA+IDA7IGN1cnJTaXplID0gcmVkdWNlU2l6ZSA+PiAxKSB7XG4gICAgICAgICAgcmVkdWNlU2l6ZSA9IGN1cnJTaXplICsgKHJlZHVjZVNpemUgJiAxKTtcbiAgICAgICAgICBpZiAobGluZGV4IDwgY3VyclNpemUpIHtcbiAgICAgICAgICAgIHRocmVhZFNoYXJlZFtsaW5kZXhdID0gbWF4KHRocmVhZFNoYXJlZFtsaW5kZXhdLCB0aHJlYWRTaGFyZWRbbGluZGV4ICsgcmVkdWNlU2l6ZV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxpbmRleCA9PSAwKSB7XG4gICAgICAgICAgcm93TWF4U2hhcmVkID0gJHt2YWx1ZVR5cGV9KCR7bWF4VmVjdG9yKCd0aHJlYWRTaGFyZWRbMF0nLCBjb21wb25lbnRzKX0pO1xuICAgICAgICB9XG4gICAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcblxuICAgICAgICAvLyBmaW5kIHRoZSByb3dzIHN1bVxuICAgICAgICB2YXIgdGhyZWFkU3VtID0gJHt2YWx1ZVR5cGV9KDAuMCk7XG4gICAgICAgIGZvciAodmFyIGNvbCA9IGxpbmRleDsgY29sIDwgY29sczsgY29sICs9IHdnKSB7XG4gICAgICAgICAgbGV0IHN1YkV4cCA9IGV4cChnZXRWYWx1ZShyb3csIGNvbCwgcm93X3N0cmlkZSkgLSByb3dNYXhTaGFyZWQpO1xuICAgICAgICAgIHRocmVhZFN1bSArPSBzdWJFeHA7XG4gICAgICAgIH1cbiAgICAgICAgdGhyZWFkU2hhcmVkW2xpbmRleF0gPSB0aHJlYWRTdW07XG4gICAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcblxuICAgICAgICBmb3IgKHZhciBjdXJyU2l6ZSA9IHdnID4+IDE7ICBjdXJyU2l6ZSA+IDA7IGN1cnJTaXplID0gY3VyclNpemUgPj4gMSkge1xuICAgICAgICAgIGlmIChsaW5kZXggPCBjdXJyU2l6ZSkge1xuICAgICAgICAgICAgdGhyZWFkU2hhcmVkW2xpbmRleF0gPSB0aHJlYWRTaGFyZWRbbGluZGV4XSArIHRocmVhZFNoYXJlZFtsaW5kZXggKyBjdXJyU2l6ZV07XG4gICAgICAgICAgfVxuICAgICAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGluZGV4ID09IDApIHtcbiAgICAgICAgICByb3dTdW1TaGFyZWQgPSAke3ZhbHVlVHlwZX0oJHtzdW1WZWN0b3IoJ3RocmVhZFNoYXJlZFswXScsIGNvbXBvbmVudHMpfSk7XG4gICAgICAgIH1cbiAgICAgICAgd29ya2dyb3VwQmFycmllcigpO1xuXG4gICAgICAgIC8vIGNhbGN1bGF0ZSBmaW5hbCB2YWx1ZSBmb3IgZWFjaCBlbGVtZW50IGluIHRoZSByb3dcbiAgICAgICAgZm9yICh2YXIgY29sID0gbGluZGV4OyBjb2wgPCBjb2xzOyBjb2wgKz0gd2cpIHtcbiAgICAgICAgICB2YXIgdmFsdWUgPSBleHAoZ2V0VmFsdWUocm93LCBjb2wsIHJvd19zdHJpZGUpIC0gcm93TWF4U2hhcmVkKSAvIHJvd1N1bVNoYXJlZDtcbiAgICAgICAgICAvLyBtYXggb3BlcmF0aW9uIHByb3RlY3RzIGFnYWluc3QgTmFOIHNpbmNlIGFsbCB2YWx1ZXMgc2hvdWxkIGJlID49MFxuICAgICAgICAgIHZhbHVlID0gbWF4KHZhbHVlLCAke3ZhbHVlVHlwZX0oMC4wKSk7XG4gICAgICAgICAgc2V0VmFsdWUocm93LCBjb2wsIHJvd19zdHJpZGUsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfWA7XG4gIGNvbnN0IHJlc3VsdCA9IGNvbnRleHQuY29tcHV0ZShcbiAgICB7XG4gICAgICBuYW1lOiAnU29mdG1heCcsXG4gICAgICAvLyBOb3RlIHRoYXQgaW4gSlNFUCwgV0cgc2l6ZSBpcyBub3QgaW5jbHVkZWQgaW4gY2FjaGUgYnkgZGVmYXVsdCwgYnV0IFdlYkdQVSBFUCBpdCBpcy5cbiAgICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke2NvbXBvbmVudHN9OyR7V0d9YCwgaW5wdXREZXBlbmRlbmNpZXM6IFsndHlwZSddIH0sXG4gICAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiB0cmFuc3Bvc2VkSW5wdXRTaGFwZSwgZGF0YVR5cGU6IHRyYW5zcG9zZWRJbnB1dC5kYXRhVHlwZSB9XSxcbiAgICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiByb3dzIH0sXG4gICAgICAgIHByb2dyYW1Vbmlmb3JtczogW3sgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IHBhY2tlZENvbHMgfV0sXG4gICAgICB9KSxcbiAgICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGlucHV0czogW3RyYW5zcG9zZWRJbnB1dF0sXG4gICAgICBvdXRwdXRzOiBbaXNUcmFuc3Bvc2VSZXF1aXJlZCA/IC0xIDogMF0sXG4gICAgfSxcbiAgKVswXTtcblxuICBpZiAoaXNUcmFuc3Bvc2VSZXF1aXJlZCkge1xuICAgIGNvbnRleHQuY29tcHV0ZShjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyhyZXN1bHQsIHBlcm0pLCB7XG4gICAgICBpbnB1dHM6IFtyZXN1bHRdLFxuICAgIH0pO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc29mdG1heCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogU29mdG1heEF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjcmVhdGVTb2Z0bWF4UHJvZ3JhbUluZm8oY29udGV4dCwgYXR0cmlidXRlcyk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTb2Z0bWF4QXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFNvZnRtYXhBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF4aXM6IGF0dHJpYnV0ZXMuYXhpcyBhcyBudW1iZXIgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcywgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciB9IGZyb20gJy4vY29tbW9uJztcblxuY29uc3QgZ2V0UmVwZWF0cyA9IChyZXBlYXRzVGVuc29yVmlldzogVGVuc29yVmlldyk6IHJlYWRvbmx5IG51bWJlcltdID0+XG4gIEFycmF5LmZyb20ocmVwZWF0c1RlbnNvclZpZXcuZ2V0QmlnSW50NjRBcnJheSgpLCBOdW1iZXIpO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaWxlIHJlcXVpcmVzIDIgaW5wdXRzLicpO1xuICB9XG5cbiAgaWYgKFxuICAgIGlucHV0c1swXS5kYXRhVHlwZSAhPT0gRGF0YVR5cGUuZmxvYXQgJiZcbiAgICBpbnB1dHNbMF0uZGF0YVR5cGUgIT09IERhdGFUeXBlLmZsb2F0MTYgJiZcbiAgICBpbnB1dHNbMF0uZGF0YVR5cGUgIT09IERhdGFUeXBlLmludDMyICYmXG4gICAgaW5wdXRzWzBdLmRhdGFUeXBlICE9PSBEYXRhVHlwZS51aW50MzJcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaWxlIG9ubHkgc3VwcG9ydCBmbG9hdCwgZmxvYXQxNiwgaW50MzIsIGFuZCB1aW50MzIgZGF0YSB0eXBlcycpO1xuICB9XG5cbiAgaWYgKGlucHV0c1sxXS5kYXRhVHlwZSAhPT0gRGF0YVR5cGUuaW50NjQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RpbGUgYHJlcGVhdHNgIGlucHV0IHNob3VsZCBiZSBvZiBpbnQ2NCBkYXRhIHR5cGUnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RpbGUgYHJlcGVhdHNgIGlucHV0IHNob3VsZCBiZSAxLUQnKTtcbiAgfVxuXG4gIGNvbnN0IHJlcGVhdHM6IHJlYWRvbmx5IG51bWJlcltdID0gZ2V0UmVwZWF0cyhpbnB1dHNbMV0pO1xuXG4gIGlmIChyZXBlYXRzLmxlbmd0aCAhPT0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaWxlIGByZXBlYXRzYCBpbnB1dCBzaG91bGQgaGF2ZSBzYW1lIG51bWJlciBvZiBlbGVtZW50cyBhcyByYW5rIG9mIGlucHV0IGRhdGEgdGVuc29yJyk7XG4gIH1cbn07XG5cbmNvbnN0IGdldE91dHB1dFNoYXBlID0gKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCByZXBlYXRzOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGU6IG51bWJlcltdID0gW107XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dFNoYXBlLmxlbmd0aDsgKytpKSB7XG4gICAgb3V0cHV0U2hhcGUucHVzaChpbnB1dFNoYXBlW2ldICogcmVwZWF0c1tpXSk7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0U2hhcGU7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVGlsZVByb2dyYW1JbmZvID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLCBzaGFwZT86IG51bWJlcltdKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IHJlcGVhdHM6IHJlYWRvbmx5IG51bWJlcltdID0gc2hhcGUgPT0gbnVsbCA/IGdldFJlcGVhdHMoaW5wdXRzWzFdKSA6IHNoYXBlO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGdldE91dHB1dFNoYXBlKGlucHV0U2hhcGUsIHJlcGVhdHMpO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuXG4gIGNvbnN0IGRhdGFUeXBlID0gaW5wdXRzWzBdLmRhdGFUeXBlO1xuICBjb25zdCBpbnB1dCA9IGlucHV0VmFyaWFibGUoJ2lucHV0JywgZGF0YVR5cGUsIGlucHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gYFxuICAgICAgY29uc3QgaW5wdXRTaGFwZSA9ICR7aW5wdXQuaW5kaWNlcyguLi5pbnB1dFNoYXBlKX07XG4gICAgICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ291dHB1dF9zaXplJywgJ3UzMicpLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIG91dHB1dCl9XG4gICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgICBsZXQgb3V0cHV0X2luZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG4gICAgICB2YXIgaW5wdXRfaW5kaWNlczogJHtpbnB1dC50eXBlLmluZGljZXN9O1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAke2lucHV0U2hhcGUubGVuZ3RofTsgaSsrKSB7XG4gICAgICAgIGxldCBpbnB1dF9kaW1faSA9ICR7aW5wdXQuaW5kaWNlc0dldCgndW5pZm9ybXMuaW5wdXRfc2hhcGUnLCAnaScpfTtcbiAgICAgICAgbGV0IGlucHV0X2RpbV92YWx1ZSA9ICR7b3V0cHV0LmluZGljZXNHZXQoJ291dHB1dF9pbmRpY2VzJywgJ2knKX0gICUgaW5wdXRfZGltX2k7XG5cbiAgICAgICAgJHtpbnB1dC5pbmRpY2VzU2V0KCdpbnB1dF9pbmRpY2VzJywgJ2knLCAnaW5wdXRfZGltX3ZhbHVlJyl9XG4gICAgICB9XG4gICAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsIGlucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpKX1cbiAgICB9YDtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdUaWxlJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtyZXBlYXRzfWAsIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnXSB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtczogW1xuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgICAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMF0uZGltcywgb3V0cHV0U2hhcGUpLFxuICAgICAgXSxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgdGlsZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVUaWxlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMpLCB7IGlucHV0czogWzBdIH0pO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgQnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG5jb25zdCBjcmVhdGVXaGVyZU9wUHJvZ3JhbVNoYWRlciA9IChcbiAgc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBkaW1zT3V0cHV0OiByZWFkb25seSBudW1iZXJbXSxcbiAgaXNCcm9hZGNhc3Q6IGJvb2xlYW4sXG4gIHR5cGVPdXRwdXQ6IG51bWJlcixcbikgPT4ge1xuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0X2RhdGEnLCB0eXBlT3V0cHV0LCBkaW1zT3V0cHV0Lmxlbmd0aCwgNCk7XG4gIGNvbnN0IGEgPSBpbnB1dFZhcmlhYmxlKCdhX2RhdGEnLCBpbnB1dHNbMV0uZGF0YVR5cGUsIGlucHV0c1sxXS5kaW1zLmxlbmd0aCwgNCk7XG4gIGNvbnN0IGIgPSBpbnB1dFZhcmlhYmxlKCdiX2RhdGEnLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLmxlbmd0aCwgNCk7XG4gIGNvbnN0IGMgPSBpbnB1dFZhcmlhYmxlKCdjX2RhdGEnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0c1swXS5kaW1zLmxlbmd0aCwgNCk7XG5cbiAgbGV0IGFzc2lnbm1lbnQ6IHN0cmluZztcbiAgY29uc3QgZXhwcmVzc2lvbiA9IChhOiBzdHJpbmcsIGI6IHN0cmluZywgYzogc3RyaW5nKSA9PiBgc2VsZWN0KCR7Yn0sICR7YX0sICR7Y30pYDtcbiAgaWYgKCFpc0Jyb2FkY2FzdCkge1xuICAgIGFzc2lnbm1lbnQgPSBvdXRwdXQuc2V0QnlPZmZzZXQoXG4gICAgICAnZ2xvYmFsX2lkeCcsXG4gICAgICBleHByZXNzaW9uKGEuZ2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnKSwgYi5nZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcpLCBjLmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JykpLFxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgc2luZ2xlQXNzaWdubWVudCA9IChyZXNTdHI6IHN0cmluZywgeDogbnVtYmVyLCB0eXBlQ2FzdCA9ICcnKSA9PiB7XG4gICAgICBjb25zdCBleHByZXNzaW9uQSA9IGBhX2RhdGFbaW5kZXhfYSR7eH1dW2NvbXBvbmVudF9hJHt4fV1gO1xuICAgICAgY29uc3QgZXhwcmVzc2lvbkIgPSBgYl9kYXRhW2luZGV4X2Ike3h9XVtjb21wb25lbnRfYiR7eH1dYDtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb25DID0gYGJvb2woY19kYXRhW2luZGV4X2Mke3h9XSAmICgweGZmdSA8PCAoY29tcG9uZW50X2Mke3h9ICogOCkpKWA7XG4gICAgICByZXR1cm4gYFxuICAgICAgICAgICAgbGV0IG91dHB1dF9pbmRpY2VzJHt4fSA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcyhgZ2xvYmFsX2lkeCAqIDR1ICsgJHt4fXVgKX07XG4gICAgICAgICAgICBsZXQgb2Zmc2V0X2Eke3h9ID0gJHthLmJyb2FkY2FzdGVkSW5kaWNlc1RvT2Zmc2V0KGBvdXRwdXRfaW5kaWNlcyR7eH1gLCBvdXRwdXQpfTtcbiAgICAgICAgICAgIGxldCBvZmZzZXRfYiR7eH0gPSAke2IuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQoYG91dHB1dF9pbmRpY2VzJHt4fWAsIG91dHB1dCl9O1xuICAgICAgICAgICAgbGV0IG9mZnNldF9jJHt4fSA9ICR7Yy5icm9hZGNhc3RlZEluZGljZXNUb09mZnNldChgb3V0cHV0X2luZGljZXMke3h9YCwgb3V0cHV0KX07XG4gICAgICAgICAgICBsZXQgaW5kZXhfYSR7eH0gPSBvZmZzZXRfYSR7eH0gLyA0dTtcbiAgICAgICAgICAgIGxldCBpbmRleF9iJHt4fSA9IG9mZnNldF9iJHt4fSAvIDR1O1xuICAgICAgICAgICAgbGV0IGluZGV4X2Mke3h9ID0gb2Zmc2V0X2Mke3h9IC8gNHU7XG4gICAgICAgICAgICBsZXQgY29tcG9uZW50X2Eke3h9ID0gb2Zmc2V0X2Eke3h9ICUgNHU7XG4gICAgICAgICAgICBsZXQgY29tcG9uZW50X2Ike3h9ID0gb2Zmc2V0X2Ike3h9ICUgNHU7XG4gICAgICAgICAgICBsZXQgY29tcG9uZW50X2Mke3h9ID0gb2Zmc2V0X2Mke3h9ICUgNHU7XG4gICAgICAgICAgICAke3Jlc1N0cn1bJHt4fV0gPSAke3R5cGVDYXN0fSgke2V4cHJlc3Npb24oZXhwcmVzc2lvbkEsIGV4cHJlc3Npb25CLCBleHByZXNzaW9uQyl9KTtcbiAgICAgICAgICBgO1xuICAgIH07XG4gICAgaWYgKHR5cGVPdXRwdXQgPT09IERhdGFUeXBlLmJvb2wpIHtcbiAgICAgIGFzc2lnbm1lbnQgPSBgXG4gICAgICAgICAgICB2YXIgZGF0YSA9IHZlYzQ8dTMyPigwKTtcbiAgICAgICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnZGF0YScsIDAsICd1MzInKX1cbiAgICAgICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnZGF0YScsIDEsICd1MzInKX1cbiAgICAgICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnZGF0YScsIDIsICd1MzInKX1cbiAgICAgICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnZGF0YScsIDMsICd1MzInKX1cbiAgICAgICAgICAgIG91dHB1dF9kYXRhW2dsb2JhbF9pZHhdID0gZG90KHZlYzQ8dTMyPigweDEsIDB4MTAwLCAweDEwMDAwLCAweDEwMDAwMDApLCB2ZWM0PHUzMj4oZGF0YSkpO2A7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFzc2lnbm1lbnQgPSBgXG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ291dHB1dF9kYXRhW2dsb2JhbF9pZHhdJywgMCl9XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ291dHB1dF9kYXRhW2dsb2JhbF9pZHhdJywgMSl9XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ291dHB1dF9kYXRhW2dsb2JhbF9pZHhdJywgMil9XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ291dHB1dF9kYXRhW2dsb2JhbF9pZHhdJywgMyl9XG4gICAgICAgICAgYDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYFxuICAgICAgICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ3ZlY19zaXplJywgJ3UzMicpLmRlY2xhcmVWYXJpYWJsZXMoYywgYSwgYiwgb3V0cHV0KX1cbiAgICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLnZlY19zaXplJyl9XG4gICAgICAgICR7YXNzaWdubWVudH1cbiAgICAgIH1gO1xufTtcblxuY29uc3QgY3JlYXRlV2hlcmVPcFByb2dyYW1JbmZvID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBkaW1zQSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBkaW1zQiA9IGlucHV0c1syXS5kaW1zO1xuICBjb25zdCBkaW1zQyA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBvdXRwdXREYXRhVHlwZSA9IGlucHV0c1sxXS5kYXRhVHlwZTtcblxuICBjb25zdCBpc0Jyb2FkY2FzdCA9ICEoU2hhcGVVdGlsLmFyZUVxdWFsKGRpbXNBLCBkaW1zQikgJiYgU2hhcGVVdGlsLmFyZUVxdWFsKGRpbXNCLCBkaW1zQykpO1xuICBsZXQgb3V0cHV0U2hhcGUgPSBkaW1zQTtcbiAgbGV0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShkaW1zQSk7XG4gIC8vIFRPRE86IGRlYWwgd2l0aCB6ZXJvLXNpemVkIHRlbnNvcnMgKGVnLiBkaW1zPVsxLDBdKVxuXG4gIGlmIChpc0Jyb2FkY2FzdCkge1xuICAgIGNvbnN0IGNhbGN1bGF0ZWRTaGFwZSA9IEJyb2FkY2FzdFV0aWwuY2FsY1NoYXBlKEJyb2FkY2FzdFV0aWwuY2FsY1NoYXBlKGRpbXNBLCBkaW1zQiwgZmFsc2UpISwgZGltc0MsIGZhbHNlKTtcbiAgICBpZiAoIWNhbGN1bGF0ZWRTaGFwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgcGVyZm9ybSB3aGVyZSBvcCBvbiB0aGUgZ2l2ZW4gdGVuc29yc1wiKTtcbiAgICB9XG4gICAgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVkU2hhcGU7XG4gICAgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgfVxuXG4gIGNvbnN0IHZlY1NpemUgPSBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDQpO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ1doZXJlJyxcbiAgICBzaGFkZXJDYWNoZTogeyBpbnB1dERlcGVuZGVuY2llczogWydyYW5rJywgJ3JhbmsnLCAncmFuayddIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlOiAoc2hhZGVySGVscGVyKSA9PlxuICAgICAgY3JlYXRlV2hlcmVPcFByb2dyYW1TaGFkZXIoc2hhZGVySGVscGVyLCBpbnB1dHMsIG91dHB1dFNoYXBlLCBpc0Jyb2FkY2FzdCwgb3V0cHV0RGF0YVR5cGUpLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IG91dHB1dERhdGFUeXBlIH1dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovIC8gNCAvKiB2ZWMgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtczogW1xuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogdmVjU2l6ZSB9LFxuICAgICAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhkaW1zQywgZGltc0EsIGRpbXNCLCBvdXRwdXRTaGFwZSksXG4gICAgICBdLFxuICAgIH0pLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHdoZXJlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVXaGVyZU9wUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMpKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGFyZ01heCwgYXJnTWluLCBwYXJzZUFyZ01pbk1heEF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9hcmdtaW5tYXgnO1xuaW1wb3J0IHsgYXR0ZW50aW9uIH0gZnJvbSAnLi9vcHMvYXR0ZW50aW9uJztcbmltcG9ydCB7IGJhdGNoTm9ybSB9IGZyb20gJy4vb3BzL2JhdGNoLW5vcm0nO1xuaW1wb3J0IHsgYmlhc0FkZCB9IGZyb20gJy4vb3BzL2JpYXMtYWRkJztcbmltcG9ydCB7IGJpYXNTcGxpdEdlbHUgfSBmcm9tICcuL29wcy9iaWFzLXNwbGl0LWdlbHUnO1xuaW1wb3J0ICogYXMgYmluYXJ5T3BzIGZyb20gJy4vb3BzL2JpbmFyeS1vcCc7XG5pbXBvcnQgeyBjb25jYXQsIHBhcnNlQ29uY2F0QXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2NvbmNhdCc7XG5pbXBvcnQgeyBjb252LCBwYXJzZUNvbnZBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvY29udic7XG5pbXBvcnQgeyBjb252VHJhbnNwb3NlLCBwYXJzZUNvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvY29udi10cmFuc3Bvc2UnO1xuaW1wb3J0IHsgY3Vtc3VtLCBwYXJzZUN1bVN1bUF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9jdW1zdW0nO1xuaW1wb3J0IHsgZGVwdGhUb1NwYWNlLCBwYXJzZURlcHRoVG9TcGFjZUF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9kZXB0aC10by1zcGFjZSc7XG5pbXBvcnQgeyBlaW5zdW0sIHBhcnNlRWluc3VtQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2VpbnN1bSc7XG5pbXBvcnQgeyBleHBhbmQgfSBmcm9tICcuL29wcy9leHBhbmQnO1xuaW1wb3J0IHsgZmFzdEdlbHUgfSBmcm9tICcuL29wcy9mYXN0LWdlbHUnO1xuaW1wb3J0IHsgZ2F0aGVyLCBwYXJzZUdhdGhlckF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9nYXRoZXInO1xuaW1wb3J0IHsgZ2F0aGVyTkQsIHBhcnNlR2F0aGVyTkRBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvZ2F0aGVyLW5kJztcbmltcG9ydCB7IGdhdGhlckJsb2NrUXVhbnRpemVkLCBwYXJzZUdhdGhlckJsb2NrUXVhbnRpemVkQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2dhdGhlci1ibG9jay1xdWFudGl6ZWQnO1xuaW1wb3J0IHsgZ2F0aGVyRWxlbWVudHMsIHBhcnNlR2F0aGVyRWxlbWVudHNBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvZ2F0aGVyLWVsZW1lbnRzJztcbmltcG9ydCB7IGdlbW0sIHBhcnNlR2VtbUF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9nZW1tJztcbmltcG9ydCB7IGdyaWRTYW1wbGUsIHBhcnNlR3JpZFNhbXBsZUF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9ncmlkLXNhbXBsZSc7XG5pbXBvcnQgeyBncm91cFF1ZXJ5QXR0ZW50aW9uIH0gZnJvbSAnLi9vcHMvZ3JvdXAtcXVlcnktYXR0ZW50aW9uJztcbmltcG9ydCB7IGluc3RhbmNlTm9ybSB9IGZyb20gJy4vb3BzL2luc3RhbmNlLW5vcm0nO1xuaW1wb3J0IHsgbGF5ZXJOb3JtIH0gZnJvbSAnLi9vcHMvbGF5ZXItbm9ybSc7XG5pbXBvcnQgeyBtYXRNdWwgfSBmcm9tICcuL29wcy9tYXRtdWwnO1xuaW1wb3J0IHsgbWF0TXVsTkJpdHMsIHBhcnNlTWF0TXVsTkJpdHNBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvbWF0bXVsbmJpdHMnO1xuaW1wb3J0IHsgbXVsdGlIZWFkQXR0ZW50aW9uLCBwYXJzZU11bHRpSGVhZEF0dGVudGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9tdWx0aWhlYWQtYXR0ZW50aW9uJztcbmltcG9ydCB7IHBhZCB9IGZyb20gJy4vb3BzL3BhZCc7XG5pbXBvcnQgKiBhcyBwb29sIGZyb20gJy4vb3BzL3Bvb2wnO1xuaW1wb3J0IHsgZGVxdWFudGl6ZUxpbmVhciwgcGFyc2VEZXF1YW50aXplTGluZWFyQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL3F1YW50aXplLWxpbmVhcic7XG5pbXBvcnQgeyByYW5nZSB9IGZyb20gJy4vb3BzL3JhbmdlJztcbmltcG9ydCB7IHNjYXR0ZXJORCwgcGFyc2VTY2F0dGVyTkRBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvc2NhdHRlci1uZCc7XG5pbXBvcnQge1xuICByZWR1Y2VMMSxcbiAgcmVkdWNlTDIsXG4gIHJlZHVjZUxvZ1N1bSxcbiAgcmVkdWNlTG9nU3VtRXhwLFxuICByZWR1Y2VNYXgsXG4gIHJlZHVjZU1lYW4sXG4gIHJlZHVjZU1pbixcbiAgcmVkdWNlUHJvZCxcbiAgcmVkdWNlU3VtLFxuICByZWR1Y2VTdW1TcXVhcmUsXG59IGZyb20gJy4vb3BzL3JlZHVjZSc7XG5pbXBvcnQgeyBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXMsIHJlc2l6ZSB9IGZyb20gJy4vb3BzL3Jlc2l6ZSc7XG5pbXBvcnQgeyByb3RhcnlFbWJlZGRpbmcgfSBmcm9tICcuL29wcy9yb3RhcnktZW1iZWRkaW5nJztcbmltcG9ydCB7IHNraXBMYXllck5vcm0gfSBmcm9tICcuL29wcy9za2lwLWxheWVyLW5vcm0nO1xuaW1wb3J0IHsgcGFyc2VTbGljZUF0dHJpYnV0ZXMsIHNsaWNlIH0gZnJvbSAnLi9vcHMvc2xpY2UnO1xuaW1wb3J0IHsgcGFyc2VTb2Z0bWF4QXR0cmlidXRlcywgc29mdG1heCB9IGZyb20gJy4vb3BzL3NvZnRtYXgnO1xuaW1wb3J0IHsgcGFyc2VTcGxpdEF0dHJpYnV0ZXMsIHNwbGl0IH0gZnJvbSAnLi9vcHMvc3BsaXQnO1xuaW1wb3J0IHsgdGlsZSB9IGZyb20gJy4vb3BzL3RpbGUnO1xuaW1wb3J0IHsgcGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzLCB0cmFuc3Bvc2UgfSBmcm9tICcuL29wcy90cmFuc3Bvc2UnO1xuaW1wb3J0ICogYXMgdW5hcnlPcHMgZnJvbSAnLi9vcHMvdW5hcnktb3AnO1xuaW1wb3J0IHsgd2hlcmUgfSBmcm9tICcuL29wcy93aGVyZSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgdHlwZSBSdW5GdW5jdGlvbiA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlPzogdW5rbm93bikgPT4gdm9pZDtcbmV4cG9ydCB0eXBlIFBhcnNlQXR0cmlidXRlRnVuY3Rpb24gPSAoYXR0cmlidXRlUmF3OiB1bmtub3duKSA9PiB1bmtub3duO1xuZXhwb3J0IHR5cGUgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiA9IFtSdW5GdW5jdGlvbl0gfCBbUnVuRnVuY3Rpb24sIFBhcnNlQXR0cmlidXRlRnVuY3Rpb25dO1xuXG5leHBvcnQgY29uc3QgV0VCR1BVX09QX1JFU09MVkVfUlVMRVM6IE1hcDxzdHJpbmcsIE9wZXJhdG9ySW1wbGVtZW50YXRpb24+ID0gbmV3IE1hcChbXG4gIFsnQWJzJywgW3VuYXJ5T3BzLmFic11dLFxuICBbJ0Fjb3MnLCBbdW5hcnlPcHMuYWNvc11dLFxuICBbJ0Fjb3NoJywgW3VuYXJ5T3BzLmFjb3NoXV0sXG4gIFsnQWRkJywgW2JpbmFyeU9wcy5hZGRdXSxcbiAgWydBcmdNYXgnLCBbYXJnTWF4LCBwYXJzZUFyZ01pbk1heEF0dHJpYnV0ZXNdXSxcbiAgWydBcmdNaW4nLCBbYXJnTWluLCBwYXJzZUFyZ01pbk1heEF0dHJpYnV0ZXNdXSxcbiAgWydBc2luJywgW3VuYXJ5T3BzLmFzaW5dXSxcbiAgWydBc2luaCcsIFt1bmFyeU9wcy5hc2luaF1dLFxuICBbJ0F0YW4nLCBbdW5hcnlPcHMuYXRhbl1dLFxuICBbJ0F0YW5oJywgW3VuYXJ5T3BzLmF0YW5oXV0sXG4gIFsnQXR0ZW50aW9uJywgW2F0dGVudGlvbl1dLFxuICAvLyBUT0RPOiBzdXBwb3J0IG5ldyBhdHRyaWJ1dGVzIGZvciBBdmVyYWdlUG9vbC0xMFxuICBbJ0F2ZXJhZ2VQb29sJywgW3Bvb2wuYXZlcmFnZVBvb2wsIHBvb2wucGFyc2VBdmVyYWdlUG9vbEF0dHJpYnV0ZXNdXSxcbiAgWydCYXRjaE5vcm1hbGl6YXRpb24nLCBbYmF0Y2hOb3JtXV0sXG4gIFsnQmlhc0FkZCcsIFtiaWFzQWRkXV0sXG4gIFsnQmlhc1NwbGl0R2VsdScsIFtiaWFzU3BsaXRHZWx1XV0sXG4gIFsnQ2FzdCcsIFt1bmFyeU9wcy5jYXN0LCB1bmFyeU9wcy5wYXJzZUNhc3RBdHRyaWJ1dGVzXV0sXG4gIFsnQ2VpbCcsIFt1bmFyeU9wcy5jZWlsXV0sXG4gIFsnQ2xpcCcsIFt1bmFyeU9wcy5jbGlwXV0sXG4gIFsnQ29uY2F0JywgW2NvbmNhdCwgcGFyc2VDb25jYXRBdHRyaWJ1dGVzXV0sXG4gIFsnQ29udicsIFtjb252LCBwYXJzZUNvbnZBdHRyaWJ1dGVzXV0sXG4gIFsnQ29udlRyYW5zcG9zZScsIFtjb252VHJhbnNwb3NlLCBwYXJzZUNvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzXV0sXG4gIFsnQ29zJywgW3VuYXJ5T3BzLmNvc11dLFxuICBbJ0Nvc2gnLCBbdW5hcnlPcHMuY29zaF1dLFxuICBbJ0N1bVN1bScsIFtjdW1zdW0sIHBhcnNlQ3VtU3VtQXR0cmlidXRlc11dLFxuICBbJ0RlcHRoVG9TcGFjZScsIFtkZXB0aFRvU3BhY2UsIHBhcnNlRGVwdGhUb1NwYWNlQXR0cmlidXRlc11dLFxuICBbJ0RlcXVhbnRpemVMaW5lYXInLCBbZGVxdWFudGl6ZUxpbmVhciwgcGFyc2VEZXF1YW50aXplTGluZWFyQXR0cmlidXRlc11dLFxuICBbJ0RpdicsIFtiaW5hcnlPcHMuZGl2XV0sXG4gIFsnRWluc3VtJywgW2VpbnN1bSwgcGFyc2VFaW5zdW1BdHRyaWJ1dGVzXV0sXG4gIFsnRWx1JywgW3VuYXJ5T3BzLmVsdSwgdW5hcnlPcHMucGFyc2VBbHBoYUF0dHJpYnV0ZXNdXSxcbiAgWydFcXVhbCcsIFtiaW5hcnlPcHMuZXF1YWxdXSxcbiAgWydFcmYnLCBbdW5hcnlPcHMuZXJmXV0sXG4gIFsnRXhwJywgW3VuYXJ5T3BzLmV4cF1dLFxuICBbJ0V4cGFuZCcsIFtleHBhbmRdXSxcbiAgWydGYXN0R2VsdScsIFtmYXN0R2VsdV1dLFxuICBbJ0Zsb29yJywgW3VuYXJ5T3BzLmZsb29yXV0sXG4gIFsnRnVzZWRDb252JywgW2NvbnYsIHBhcnNlQ29udkF0dHJpYnV0ZXNdXSxcbiAgWydHYXRoZXInLCBbZ2F0aGVyLCBwYXJzZUdhdGhlckF0dHJpYnV0ZXNdXSxcbiAgWydHYXRoZXJFbGVtZW50cycsIFtnYXRoZXJFbGVtZW50cywgcGFyc2VHYXRoZXJFbGVtZW50c0F0dHJpYnV0ZXNdXSxcbiAgWydHYXRoZXJCbG9ja1F1YW50aXplZCcsIFtnYXRoZXJCbG9ja1F1YW50aXplZCwgcGFyc2VHYXRoZXJCbG9ja1F1YW50aXplZEF0dHJpYnV0ZXNdXSxcbiAgWydHYXRoZXJORCcsIFtnYXRoZXJORCwgcGFyc2VHYXRoZXJOREF0dHJpYnV0ZXNdXSxcbiAgWydHZWx1JywgW3VuYXJ5T3BzLmdlbHVdXSxcbiAgWydHZW1tJywgW2dlbW0sIHBhcnNlR2VtbUF0dHJpYnV0ZXNdXSxcbiAgWydHbG9iYWxBdmVyYWdlUG9vbCcsIFtwb29sLmdsb2JhbEF2ZXJhZ2VQb29sLCBwb29sLnBhcnNlR2xvYmFsQXZlcmFnZVBvb2xBdHRyaWJ1dGVzXV0sXG4gIFsnR2xvYmFsTWF4UG9vbCcsIFtwb29sLmdsb2JhbE1heFBvb2wsIHBvb2wucGFyc2VHbG9iYWxNYXhQb29sQXR0cmlidXRlc11dLFxuICBbJ0dyZWF0ZXInLCBbYmluYXJ5T3BzLmdyZWF0ZXJdXSxcbiAgWydHcmVhdGVyT3JFcXVhbCcsIFtiaW5hcnlPcHMuZ3JlYXRlck9yRXF1YWxdXSxcbiAgWydHcmlkU2FtcGxlJywgW2dyaWRTYW1wbGUsIHBhcnNlR3JpZFNhbXBsZUF0dHJpYnV0ZXNdXSxcbiAgWydHcm91cFF1ZXJ5QXR0ZW50aW9uJywgW2dyb3VwUXVlcnlBdHRlbnRpb25dXSxcbiAgWydIYXJkU2lnbW9pZCcsIFt1bmFyeU9wcy5oYXJkU2lnbW9pZCwgdW5hcnlPcHMucGFyc2VIYXJkU2lnbW9pZEF0dHJpYnV0ZXNdXSxcbiAgWydJbnN0YW5jZU5vcm1hbGl6YXRpb24nLCBbaW5zdGFuY2VOb3JtXV0sXG4gIFsnTGF5ZXJOb3JtYWxpemF0aW9uJywgW2xheWVyTm9ybV1dLFxuICBbJ0xlYWt5UmVsdScsIFt1bmFyeU9wcy5sZWFreVJlbHUsIHVuYXJ5T3BzLnBhcnNlQWxwaGFBdHRyaWJ1dGVzXV0sXG4gIFsnTGVzcycsIFtiaW5hcnlPcHMubGVzc11dLFxuICBbJ0xlc3NPckVxdWFsJywgW2JpbmFyeU9wcy5sZXNzT3JFcXVhbF1dLFxuICBbJ0xvZycsIFt1bmFyeU9wcy5sb2ddXSxcbiAgWydNYXRNdWwnLCBbbWF0TXVsXV0sXG4gIFsnTWF0TXVsTkJpdHMnLCBbbWF0TXVsTkJpdHMsIHBhcnNlTWF0TXVsTkJpdHNBdHRyaWJ1dGVzXV0sXG4gIC8vIFRPRE86IHN1cHBvcnQgbmV3IGF0dHJpYnV0ZXMgZm9yIE1heFBvb2wtOCBhbmQgTWF4UG9vbC0xMFxuICBbJ01heFBvb2wnLCBbcG9vbC5tYXhQb29sLCBwb29sLnBhcnNlTWF4UG9vbEF0dHJpYnV0ZXNdXSxcbiAgWydNdWwnLCBbYmluYXJ5T3BzLm11bF1dLFxuICBbJ011bHRpSGVhZEF0dGVudGlvbicsIFttdWx0aUhlYWRBdHRlbnRpb24sIHBhcnNlTXVsdGlIZWFkQXR0ZW50aW9uQXR0cmlidXRlc11dLFxuICBbJ05lZycsIFt1bmFyeU9wcy5uZWddXSxcbiAgWydOb3QnLCBbdW5hcnlPcHMubm90XV0sXG4gIFsnUGFkJywgW3BhZF1dLFxuICBbJ1BvdycsIFtiaW5hcnlPcHMucG93XV0sXG4gIFsnUXVpY2tHZWx1JywgW3VuYXJ5T3BzLnF1aWNrZ2VsdSwgdW5hcnlPcHMucGFyc2VBbHBoYUF0dHJpYnV0ZXNdXSxcbiAgWydSYW5nZScsIFtyYW5nZV1dLFxuICBbJ1JlY2lwcm9jYWwnLCBbdW5hcnlPcHMucmVjaXByb2NhbF1dLFxuICBbJ1JlZHVjZU1pbicsIFtyZWR1Y2VNaW5dXSxcbiAgWydSZWR1Y2VNZWFuJywgW3JlZHVjZU1lYW5dXSxcbiAgWydSZWR1Y2VNYXgnLCBbcmVkdWNlTWF4XV0sXG4gIFsnUmVkdWNlU3VtJywgW3JlZHVjZVN1bV1dLFxuICBbJ1JlZHVjZVByb2QnLCBbcmVkdWNlUHJvZF1dLFxuICBbJ1JlZHVjZUwxJywgW3JlZHVjZUwxXV0sXG4gIFsnUmVkdWNlTDInLCBbcmVkdWNlTDJdXSxcbiAgWydSZWR1Y2VMb2dTdW0nLCBbcmVkdWNlTG9nU3VtXV0sXG4gIFsnUmVkdWNlTG9nU3VtRXhwJywgW3JlZHVjZUxvZ1N1bUV4cF1dLFxuICBbJ1JlZHVjZVN1bVNxdWFyZScsIFtyZWR1Y2VTdW1TcXVhcmVdXSxcbiAgWydSZWx1JywgW3VuYXJ5T3BzLnJlbHVdXSxcbiAgWydSZXNpemUnLCBbcmVzaXplLCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNdXSxcbiAgWydSb3RhcnlFbWJlZGRpbmcnLCBbcm90YXJ5RW1iZWRkaW5nXV0sXG4gIFsnU2NhdHRlck5EJywgW3NjYXR0ZXJORCwgcGFyc2VTY2F0dGVyTkRBdHRyaWJ1dGVzXV0sXG4gIFsnU2lnbW9pZCcsIFt1bmFyeU9wcy5zaWdtb2lkXV0sXG4gIFsnU2luJywgW3VuYXJ5T3BzLnNpbl1dLFxuICBbJ1NpbmgnLCBbdW5hcnlPcHMuc2luaF1dLFxuICBbJ1NsaWNlJywgW3NsaWNlLCBwYXJzZVNsaWNlQXR0cmlidXRlc11dLFxuICBbJ1NraXBMYXllck5vcm1hbGl6YXRpb24nLCBbc2tpcExheWVyTm9ybV1dLFxuICBbJ1NwbGl0JywgW3NwbGl0LCBwYXJzZVNwbGl0QXR0cmlidXRlc11dLFxuICBbJ1NxcnQnLCBbdW5hcnlPcHMuc3FydF1dLFxuICBbJ1NvZnRtYXgnLCBbc29mdG1heCwgcGFyc2VTb2Z0bWF4QXR0cmlidXRlc11dLFxuICBbJ1N1YicsIFtiaW5hcnlPcHMuc3ViXV0sXG4gIFsnVGFuJywgW3VuYXJ5T3BzLnRhbl1dLFxuICBbJ1RhbmgnLCBbdW5hcnlPcHMudGFuaF1dLFxuICBbJ1RocmVzaG9sZGVkUmVsdScsIFt1bmFyeU9wcy50aHJlc2hvbGRlZFJlbHUsIHVuYXJ5T3BzLnBhcnNlQWxwaGFBdHRyaWJ1dGVzXV0sXG4gIFsnVGlsZScsIFt0aWxlXV0sXG4gIFsnVHJhbnNwb3NlJywgW3RyYW5zcG9zZSwgcGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzXV0sXG4gIFsnV2hlcmUnLCBbd2hlcmVdXSxcbl0pO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUUkFDRV9GVU5DX0JFR0lOLCBUUkFDRV9GVU5DX0VORCB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IFdlYkdwdUJhY2tlbmQgfSBmcm9tICcuLi9iYWNrZW5kLXdlYmdwdSc7XG5pbXBvcnQgeyBMT0dfREVCVUcgfSBmcm9tICcuLi9sb2cnO1xuXG5pbXBvcnQgeyBjcmVhdGVTaGFkZXJIZWxwZXIgfSBmcm9tICcuL29wcy9jb21tb24nO1xuaW1wb3J0IHsgQXJ0aWZhY3QsIEdwdURhdGEsIFByb2dyYW1JbmZvIH0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogUHJvZ3JhbU1hbmFnZXIgaXMgdGhlIG1haW4gY2xhc3MgYmVoaW5kIHJ1bm5pbmcgY29tcHV0YXRpb25zXG4gKiBJdCBidWlsZHMgUHJvZ3JhbUluZm8ncyBpbnRvIEFydGlmYWN0c1xuICogSXQgY29tcGlsZXMgZ2l2ZW4gUHJvZ3JhbUluZm8ncyBpbnRvIFdlYkdMIFByb3JhbXMgKGNhY2hlZCBhcyBBcnRpZmFjdHMpXG4gKiBVc2VzIHRoZSBhcnRpZmFjdCB0byBydW4gdGhlIGNvbXB1dGF0aW9uIGJ5IGNhbGxpbmcgRHJhdyBvblxuICogdGhlIFdlYkdMIGRyYXdpbmcgYnVmZmVyXG4gKiBQcm9ncmFtTWFuYWdlciBhdXRvbWF0aWNhbGx5IG1hcHMgKGJpbmRzKSBpbnB1dCB2YXJpYWJsZXMgdG8gdGhlaXJcbiAqIGNvcnJlc3BvbmRpbmcgTG9jYXRpb24ncyBpbiB0aGUgYmluYXJ5IHByb2dyYW1cbiAqL1xuZXhwb3J0IGNsYXNzIFByb2dyYW1NYW5hZ2VyIHtcbiAgcmVwbzogTWFwPHVua25vd24sIEFydGlmYWN0PjsgLy8gdGhpcyBzaG91bGQgYmUgcGVyLXNlc3Npb24gb2JqZWN0XG4gIGF0dHJpYnV0ZXNCb3VuZDogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGJhY2tlbmQ6IFdlYkdwdUJhY2tlbmQpIHtcbiAgICB0aGlzLnJlcG8gPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5hdHRyaWJ1dGVzQm91bmQgPSBmYWxzZTtcbiAgfVxuICBnZXRBcnRpZmFjdChrZXk6IHVua25vd24pOiBBcnRpZmFjdCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMucmVwby5nZXQoa2V5KTtcbiAgfVxuICBzZXRBcnRpZmFjdChrZXk6IHVua25vd24sIGFydGlmYWN0OiBBcnRpZmFjdCk6IHZvaWQge1xuICAgIHRoaXMucmVwby5zZXQoa2V5LCBhcnRpZmFjdCk7XG4gIH1cbiAgcnVuKFxuICAgIGJ1aWxkQXJ0aWZhY3Q6IEFydGlmYWN0LFxuICAgIGlucHV0czogR3B1RGF0YVtdLFxuICAgIG91dHB1dHM6IEdwdURhdGFbXSxcbiAgICBkaXNwYXRjaEdyb3VwOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgdW5pZm9ybUJ1ZmZlckJpbmRpbmc6IEdQVUJpbmRpbmdSZXNvdXJjZSB8IHVuZGVmaW5lZCxcbiAgKTogdm9pZCB7XG4gICAgVFJBQ0VfRlVOQ19CRUdJTihidWlsZEFydGlmYWN0LnByb2dyYW1JbmZvLm5hbWUpO1xuICAgIGNvbnN0IGRldmljZSA9IHRoaXMuYmFja2VuZC5kZXZpY2U7XG4gICAgY29uc3QgY29tcHV0ZVBhc3NFbmNvZGVyID0gdGhpcy5iYWNrZW5kLmdldENvbXB1dGVQYXNzRW5jb2RlcigpO1xuICAgIHRoaXMuYmFja2VuZC53cml0ZVRpbWVzdGFtcCh0aGlzLmJhY2tlbmQucGVuZGluZ0Rpc3BhdGNoTnVtYmVyICogMik7XG4gICAgY29uc3QgZW50cmllcyA9IFtdO1xuICAgIGZvciAoY29uc3QgaW5wdXQgb2YgaW5wdXRzKSB7XG4gICAgICBlbnRyaWVzLnB1c2goeyBiaW5kaW5nOiBlbnRyaWVzLmxlbmd0aCwgcmVzb3VyY2U6IHsgYnVmZmVyOiBpbnB1dC5idWZmZXIgfSB9KTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBvdXRwdXQgb2Ygb3V0cHV0cykge1xuICAgICAgZW50cmllcy5wdXNoKHsgYmluZGluZzogZW50cmllcy5sZW5ndGgsIHJlc291cmNlOiB7IGJ1ZmZlcjogb3V0cHV0LmJ1ZmZlciB9IH0pO1xuICAgIH1cbiAgICBpZiAodW5pZm9ybUJ1ZmZlckJpbmRpbmcpIHtcbiAgICAgIGVudHJpZXMucHVzaCh7IGJpbmRpbmc6IGVudHJpZXMubGVuZ3RoLCByZXNvdXJjZTogdW5pZm9ybUJ1ZmZlckJpbmRpbmcgfSk7XG4gICAgfVxuICAgIGNvbnN0IGJpbmRHcm91cCA9IGRldmljZS5jcmVhdGVCaW5kR3JvdXAoe1xuICAgICAgbGF5b3V0OiBidWlsZEFydGlmYWN0LmNvbXB1dGVQaXBlbGluZS5nZXRCaW5kR3JvdXBMYXlvdXQoMCksXG4gICAgICBlbnRyaWVzLFxuICAgICAgbGFiZWw6IGJ1aWxkQXJ0aWZhY3QucHJvZ3JhbUluZm8ubmFtZSxcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLmJhY2tlbmQuc2Vzc2lvblN0YXR1cyA9PT0gJ2NhcHR1cmluZycpIHtcbiAgICAgIGNvbnN0IGNvbW1hbmRJbmZvID0ge1xuICAgICAgICBrZXJuZWxJZDogdGhpcy5iYWNrZW5kLmN1cnJlbnRLZXJuZWxJZCEsXG4gICAgICAgIGNvbXB1dGVQaXBlbGluZTogYnVpbGRBcnRpZmFjdC5jb21wdXRlUGlwZWxpbmUsXG4gICAgICAgIGJpbmRHcm91cCxcbiAgICAgICAgZGlzcGF0Y2hHcm91cCxcbiAgICAgIH07XG4gICAgICBjb25zdCBzZXNzaW9uQ29tbWFuZExpc3QgPSB0aGlzLmJhY2tlbmQuY2FwdHVyZWRDb21tYW5kTGlzdC5nZXQodGhpcy5iYWNrZW5kLmN1cnJlbnRTZXNzaW9uSWQhKTtcbiAgICAgIHNlc3Npb25Db21tYW5kTGlzdCEucHVzaChjb21tYW5kSW5mbyk7XG4gICAgfVxuXG4gICAgY29tcHV0ZVBhc3NFbmNvZGVyLnNldFBpcGVsaW5lKGJ1aWxkQXJ0aWZhY3QuY29tcHV0ZVBpcGVsaW5lKTtcbiAgICBjb21wdXRlUGFzc0VuY29kZXIuc2V0QmluZEdyb3VwKDAsIGJpbmRHcm91cCk7XG4gICAgY29tcHV0ZVBhc3NFbmNvZGVyLmRpc3BhdGNoV29ya2dyb3VwcyguLi5kaXNwYXRjaEdyb3VwKTtcbiAgICB0aGlzLmJhY2tlbmQud3JpdGVUaW1lc3RhbXAodGhpcy5iYWNrZW5kLnBlbmRpbmdEaXNwYXRjaE51bWJlciAqIDIgKyAxKTtcbiAgICB0aGlzLmJhY2tlbmQucGVuZGluZ0Rpc3BhdGNoTnVtYmVyKys7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLmJhY2tlbmQucGVuZGluZ0Rpc3BhdGNoTnVtYmVyID49IHRoaXMuYmFja2VuZC5tYXhEaXNwYXRjaE51bWJlciB8fFxuICAgICAgdGhpcy5iYWNrZW5kLnF1ZXJ5VHlwZSA9PT0gJ2F0LXBhc3NlcydcbiAgICApIHtcbiAgICAgIHRoaXMuYmFja2VuZC5lbmRDb21wdXRlUGFzcygpO1xuICAgIH1cbiAgICBpZiAodGhpcy5iYWNrZW5kLnBlbmRpbmdEaXNwYXRjaE51bWJlciA+PSB0aGlzLmJhY2tlbmQubWF4RGlzcGF0Y2hOdW1iZXIpIHtcbiAgICAgIHRoaXMuYmFja2VuZC5mbHVzaCgpO1xuICAgIH1cbiAgICBUUkFDRV9GVU5DX0VORChidWlsZEFydGlmYWN0LnByb2dyYW1JbmZvLm5hbWUpO1xuICB9XG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgLy8gdGhpcy5yZXBvLmZvckVhY2goYSA9PiB0aGlzLmdsQ29udGV4dC5kZWxldGVQcm9ncmFtKGEucHJvZ3JhbSkpO1xuICB9XG4gIGJ1aWxkKHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbywgbm9ybWFsaXplZERpc3BhdGNoR3JvdXBTaXplOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0pOiBBcnRpZmFjdCB7XG4gICAgVFJBQ0VfRlVOQ19CRUdJTihwcm9ncmFtSW5mby5uYW1lKTtcbiAgICBjb25zdCBkZXZpY2UgPSB0aGlzLmJhY2tlbmQuZGV2aWNlO1xuICAgIGNvbnN0IGVuYWJsZURpcmVjdGl2ZXM6IHN0cmluZ1tdID0gW107XG5cbiAgICAvLyBFbmFibGUgV0dTTCBleHRlbnNpb25zIGJhc2VkIG9uIGF2YWlsYWJsZSBXZWJHUFUgZmVhdHVyZXNcbiAgICBjb25zdCBleHRlbnNpb25zSW5mbzogQXJyYXk8eyBmZWF0dXJlOiBHUFVGZWF0dXJlTmFtZTsgZXh0ZW5zaW9uOiBzdHJpbmcgfT4gPSBbXG4gICAgICB7IGZlYXR1cmU6ICdzaGFkZXItZjE2JywgZXh0ZW5zaW9uOiAnZjE2JyB9LFxuICAgICAgeyBmZWF0dXJlOiAnc3ViZ3JvdXBzJyBhcyBHUFVGZWF0dXJlTmFtZSwgZXh0ZW5zaW9uOiAnc3ViZ3JvdXBzJyB9LFxuICAgIF07XG4gICAgZXh0ZW5zaW9uc0luZm8uZm9yRWFjaCgoaW5mbykgPT4ge1xuICAgICAgaWYgKGRldmljZS5mZWF0dXJlcy5oYXMoaW5mby5mZWF0dXJlKSkge1xuICAgICAgICBlbmFibGVEaXJlY3RpdmVzLnB1c2goYGVuYWJsZSAke2luZm8uZXh0ZW5zaW9ufTtgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNvbnN0IHNoYWRlckhlbHBlciA9IGNyZWF0ZVNoYWRlckhlbHBlcihub3JtYWxpemVkRGlzcGF0Y2hHcm91cFNpemUsIHRoaXMuYmFja2VuZC5kZXZpY2UubGltaXRzKTtcbiAgICBjb25zdCB1c2VyQ29kZSA9IHByb2dyYW1JbmZvLmdldFNoYWRlclNvdXJjZShzaGFkZXJIZWxwZXIpO1xuICAgIGNvbnN0IGNvZGUgPSBgJHtlbmFibGVEaXJlY3RpdmVzLmpvaW4oJ1xcbicpfVxcbiR7c2hhZGVySGVscGVyLmFkZGl0aW9uYWxJbXBsZW1lbnRhdGlvbnN9XFxuJHt1c2VyQ29kZX1gO1xuICAgIGNvbnN0IHNoYWRlck1vZHVsZSA9IGRldmljZS5jcmVhdGVTaGFkZXJNb2R1bGUoeyBjb2RlLCBsYWJlbDogcHJvZ3JhbUluZm8ubmFtZSB9KTtcbiAgICBMT0dfREVCVUcoJ3ZlcmJvc2UnLCAoKSA9PiBgW1dlYkdQVV0gJHtwcm9ncmFtSW5mby5uYW1lfSBzaGFkZXIgY29kZTogJHtjb2RlfWApO1xuXG4gICAgY29uc3QgY29tcHV0ZVBpcGVsaW5lID0gZGV2aWNlLmNyZWF0ZUNvbXB1dGVQaXBlbGluZSh7XG4gICAgICBjb21wdXRlOiB7IG1vZHVsZTogc2hhZGVyTW9kdWxlLCBlbnRyeVBvaW50OiAnbWFpbicgfSxcbiAgICAgIGxheW91dDogJ2F1dG8nLFxuICAgICAgbGFiZWw6IHByb2dyYW1JbmZvLm5hbWUsXG4gICAgfSk7XG5cbiAgICBUUkFDRV9GVU5DX0VORChwcm9ncmFtSW5mby5uYW1lKTtcbiAgICByZXR1cm4geyBwcm9ncmFtSW5mbywgY29tcHV0ZVBpcGVsaW5lLCB1bmlmb3JtVmFyaWFibGVzSW5mbzogc2hhZGVySGVscGVyLnZhcmlhYmxlc0luZm8gfTtcbiAgfVxuXG4gIG5vcm1hbGl6ZURpc3BhdGNoR3JvdXBTaXplKFxuICAgIGRpc3BhdGNoR3JvdXA6IFJldHVyblR5cGU8UHJvZ3JhbUluZm9bJ2dldFJ1bkRhdGEnXT5bJ2Rpc3BhdGNoR3JvdXAnXSxcbiAgKTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHtcbiAgICBjb25zdCB4ID0gdHlwZW9mIGRpc3BhdGNoR3JvdXAgPT09ICdudW1iZXInID8gZGlzcGF0Y2hHcm91cCA6IGRpc3BhdGNoR3JvdXAueDtcbiAgICBjb25zdCB5ID0gdHlwZW9mIGRpc3BhdGNoR3JvdXAgPT09ICdudW1iZXInID8gMSA6IGRpc3BhdGNoR3JvdXAueSB8fCAxO1xuICAgIGNvbnN0IHogPSB0eXBlb2YgZGlzcGF0Y2hHcm91cCA9PT0gJ251bWJlcicgPyAxIDogZGlzcGF0Y2hHcm91cC56IHx8IDE7XG4gICAgY29uc3QgbGltaXRQZXJEaW1lbnNpb24gPSB0aGlzLmJhY2tlbmQuZGV2aWNlLmxpbWl0cy5tYXhDb21wdXRlV29ya2dyb3Vwc1BlckRpbWVuc2lvbjtcbiAgICBpZiAoeCA8PSBsaW1pdFBlckRpbWVuc2lvbiAmJiB5IDw9IGxpbWl0UGVyRGltZW5zaW9uICYmIHogPD0gbGltaXRQZXJEaW1lbnNpb24pIHtcbiAgICAgIHJldHVybiBbeCwgeSwgel07XG4gICAgfVxuICAgIGNvbnN0IHNpemUgPSB4ICogeSAqIHo7XG4gICAgbGV0IGRpc3BhdGNoQXZlcmFnZSA9IE1hdGguY2VpbChNYXRoLnNxcnQoc2l6ZSkpO1xuICAgIGlmIChkaXNwYXRjaEF2ZXJhZ2UgPiBsaW1pdFBlckRpbWVuc2lvbikge1xuICAgICAgZGlzcGF0Y2hBdmVyYWdlID0gTWF0aC5jZWlsKE1hdGguY2JydChzaXplKSk7XG4gICAgICBpZiAoZGlzcGF0Y2hBdmVyYWdlID4gbGltaXRQZXJEaW1lbnNpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUb3RhbCBkaXNwYXRjaCBzaXplIGV4Y2VlZHMgV2ViR1BVIG1heGltdW0uJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gW2Rpc3BhdGNoQXZlcmFnZSwgZGlzcGF0Y2hBdmVyYWdlLCBkaXNwYXRjaEF2ZXJhZ2VdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gW2Rpc3BhdGNoQXZlcmFnZSwgZGlzcGF0Y2hBdmVyYWdlLCAxXTtcbiAgICB9XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRW52LCBUZW5zb3IsIFRSQUNFLCBUUkFDRV9GVU5DX0JFR0lOLCBUUkFDRV9GVU5DX0VORCB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IERhdGFUeXBlLCB0ZW5zb3JEYXRhVHlwZUVudW1Ub1N0cmluZyB9IGZyb20gJy4uL3dhc20tY29tbW9uJztcblxuaW1wb3J0IHsgY29uZmlndXJlTG9nZ2VyLCBMT0dfREVCVUcgfSBmcm9tICcuL2xvZyc7XG5pbXBvcnQgeyBjcmVhdGVWaWV3LCBUZW5zb3JWaWV3IH0gZnJvbSAnLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBjcmVhdGVHcHVEYXRhTWFuYWdlciwgZG93bmxvYWRHcHVEYXRhLCBHcHVEYXRhTWFuYWdlciB9IGZyb20gJy4vd2ViZ3B1L2dwdS1kYXRhLW1hbmFnZXInO1xuaW1wb3J0IHsgUnVuRnVuY3Rpb24sIFdFQkdQVV9PUF9SRVNPTFZFX1JVTEVTIH0gZnJvbSAnLi93ZWJncHUvb3AtcmVzb2x2ZS1ydWxlcyc7XG5pbXBvcnQgeyBQcm9ncmFtTWFuYWdlciB9IGZyb20gJy4vd2ViZ3B1L3Byb2dyYW0tbWFuYWdlcic7XG5pbXBvcnQge1xuICBBZGFwdGVySW5mbyxcbiAgQ29tcHV0ZUNvbnRleHQsXG4gIEdwdUFyY2hpdGVjdHVyZSxcbiAgR3B1RGF0YSxcbiAgR3B1VmVuZG9yLFxuICBQcm9ncmFtSW5mbyxcbiAgUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3ksXG4gIFNlc3Npb25TdGF0ZSxcbiAgVGltZXN0YW1wUXVlcnksXG59IGZyb20gJy4vd2ViZ3B1L3R5cGVzJztcblxuaW50ZXJmYWNlIENvbW1hbmRJbmZvIHtcbiAgcmVhZG9ubHkga2VybmVsSWQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgY29tcHV0ZVBpcGVsaW5lOiBHUFVDb21wdXRlUGlwZWxpbmU7XG4gIHJlYWRvbmx5IGJpbmRHcm91cDogR1BVQmluZEdyb3VwO1xuICByZWFkb25seSBkaXNwYXRjaEdyb3VwOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG59XG5cbmludGVyZmFjZSBLZXJuZWxJbmZvIHtcbiAgcmVhZG9ubHkga2VybmVsVHlwZTogc3RyaW5nO1xuICByZWFkb25seSBrZXJuZWxOYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGtlcm5lbEVudHJ5OiBSdW5GdW5jdGlvbjtcbiAgcmVhZG9ubHkgYXR0cmlidXRlczogWygoYXR0cmlidXRlOiB1bmtub3duKSA9PiB1bmtub3duKSB8IHVuZGVmaW5lZCwgdW5rbm93bl07XG59XG5cbmludGVyZmFjZSBQZW5kaW5nS2VybmVsSW5mbyB7XG4gIHJlYWRvbmx5IGtlcm5lbElkOiBudW1iZXI7XG4gIHJlYWRvbmx5IHByb2dyYW1OYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGlucHV0VGVuc29yVmlld3M6IHJlYWRvbmx5IFRlbnNvclZpZXdbXTtcbiAgcmVhZG9ubHkgb3V0cHV0VGVuc29yVmlld3M6IHJlYWRvbmx5IFRlbnNvclZpZXdbXTtcbn1cblxuY29uc3QgZ2V0UHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lLZXkgPSAoXG4gIGlucHV0VGVuc29yczogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBpbnB1dERlcGVuZGVuY2llczogcmVhZG9ubHkgUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXSxcbik6IHN0cmluZyA9PiB7XG4gIGlmIChpbnB1dERlcGVuZGVuY2llcy5sZW5ndGggIT09IGlucHV0VGVuc29ycy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgaW5wdXREZXBlbmRlbmNpZXMgbGVuZ3RoICR7aW5wdXREZXBlbmRlbmNpZXMubGVuZ3RofSBpcyBub3QgZXF1YWwgdG8gaW5wdXRUZW5zb3JzIGxlbmd0aCAke1xuICAgICAgICBpbnB1dFRlbnNvcnMubGVuZ3RoXG4gICAgICB9LmAsXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IGlucHV0SW5mb3M6IHN0cmluZ1tdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRUZW5zb3JzLmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgdHlwZSA9IGlucHV0VGVuc29yc1tpXS5kYXRhVHlwZTtcbiAgICBzd2l0Y2ggKGlucHV0RGVwZW5kZW5jaWVzW2ldKSB7XG4gICAgICBjYXNlICdub25lJzoge1xuICAgICAgICBpbnB1dEluZm9zLnB1c2goJycpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3R5cGUnOiB7XG4gICAgICAgIGlucHV0SW5mb3MucHVzaChgJHt0eXBlfWApO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3JhbmsnOiB7XG4gICAgICAgIGNvbnN0IHJhbmsgPSBpbnB1dFRlbnNvcnNbaV0uZGltcy5sZW5ndGg7XG4gICAgICAgIGlucHV0SW5mb3MucHVzaChgJHt0eXBlfTske3Jhbmt9YCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnZGltcyc6IHtcbiAgICAgICAgY29uc3QgZGltcyA9IGlucHV0VGVuc29yc1tpXS5kaW1zLmpvaW4oJywnKTtcbiAgICAgICAgaW5wdXRJbmZvcy5wdXNoKGAke3R5cGV9OyR7ZGltc31gKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGlucHV0IGRlcGVuZGVuY3k6ICR7aW5wdXREZXBlbmRlbmNpZXNbaV19YCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGlucHV0SW5mb3Muam9pbignfCcpO1xufTtcblxuLyoqXG4gKiBnZXQgYSB1bmlxdWUga2V5IHJlcHJlc2VudGluZyB0aGUgcHJvZ3JhbSBmcm9tIHRoZSBwcm9ncmFtIGluZm8sIGlucHV0IHNoYXBlcyBhbmQgdHlwZXMuXG4gKlxuICogQHJldHVybnMgYSB1bmlxdWUga2V5IGlzIGEgc2hvcnRlciBzdHJpbmcgdGhhbiB0aGUgc2hhZGVyIHNvdXJjZSwgd2hpY2ggY29udGFpbnMgYWxsIHRoZSBpbmZvcm1hdGlvbiB0byBpZGVudGlmeSBhXG4gKiBwcm9ncmFtLiBpZiB0aGUga2V5IGlzIHRoZSBzYW1lLCB0aGUgcHJvZ3JhbSBzaGFkZXIgc291cmNlIHNob3VsZCBiZSB0aGUgc2FtZSwgc28gd2UgY2FuIHJldXNlIHRoZSBwcm9ncmFtLlxuICpcbiAqL1xuY29uc3QgZ2V0UHJvZ3JhbUluZm9VbmlxdWVLZXkgPSAoXG4gIHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbyxcbiAgaW5wdXRUZW5zb3JzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGlzMURpbWVuc2lvbkRpc3BhdGNoOiBib29sZWFuLFxuKTogc3RyaW5nID0+IHtcbiAgLy8gZmluYWwga2V5IGZvcm1hdDpcbiAgLy8gPFBST0dSQU1fTkFNRT5bPFBST0dSQU1fQ1VTVE9NX0NBQ0hFX0hJTlQ+XTppczFEaW1lbnNpb25EaXNwYXRjaDo8SU5QVVRTX0lORk9fMD58PElOUFVUU19JTkZPXzE+fC4uLlxuICBsZXQga2V5ID0gcHJvZ3JhbUluZm8ubmFtZTtcbiAgaWYgKHByb2dyYW1JbmZvLnNoYWRlckNhY2hlPy5oaW50KSB7XG4gICAga2V5ICs9ICdbJyArIHByb2dyYW1JbmZvLnNoYWRlckNhY2hlLmhpbnQgKyAnXSc7XG4gIH1cbiAga2V5ICs9XG4gICAgJzonICtcbiAgICBpczFEaW1lbnNpb25EaXNwYXRjaCArXG4gICAgYDoke2dldFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5S2V5KFxuICAgICAgaW5wdXRUZW5zb3JzLFxuICAgICAgcHJvZ3JhbUluZm8uc2hhZGVyQ2FjaGU/LmlucHV0RGVwZW5kZW5jaWVzID8/XG4gICAgICAgIG5ldyBBcnJheTxQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeT4oaW5wdXRUZW5zb3JzLmxlbmd0aCkuZmlsbCgnZGltcycpLFxuICAgICl9YDtcbiAgcmV0dXJuIGtleTtcbn07XG5cbmNsYXNzIEFkYXB0ZXJJbmZvSW1wbCBpbXBsZW1lbnRzIEFkYXB0ZXJJbmZvIHtcbiAgcmVhZG9ubHkgYXJjaGl0ZWN0dXJlPzogc3RyaW5nO1xuICByZWFkb25seSB2ZW5kb3I/OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoYWRhcHRlckluZm86IEdQVUFkYXB0ZXJJbmZvKSB7XG4gICAgaWYgKGFkYXB0ZXJJbmZvKSB7XG4gICAgICB0aGlzLmFyY2hpdGVjdHVyZSA9IGFkYXB0ZXJJbmZvLmFyY2hpdGVjdHVyZTtcbiAgICAgIHRoaXMudmVuZG9yID0gYWRhcHRlckluZm8udmVuZG9yO1xuICAgIH1cbiAgfVxuXG4gIGlzQXJjaGl0ZWN0dXJlKGFyY2hpdGVjdHVyZTogR3B1QXJjaGl0ZWN0dXJlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYXJjaGl0ZWN0dXJlID09PSBhcmNoaXRlY3R1cmU7XG4gIH1cblxuICBpc1ZlbmRvcih2ZW5kb3I6IEdwdVZlbmRvcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZlbmRvciA9PT0gdmVuZG9yO1xuICB9XG59XG5cbi8qKlxuICogdGhpcyBjbGFzcyBpcyBkZXNpZ25lZCB0byBzdG9yZSBzdGF0dXMgYW5kIGJlaW5nIHVzZWQgYXMgYSBzaW5nbGV0b24gZm9yIEpTRVAuIEl0IHdpbGwgYmUgcGFzc2VkIHRvIGpzZXBJbml0KCkgYXNcbiAqIHRoZSBmaXJzdCBwYXJhbWV0ZXIgc28gdGhhdCBpdCBpcyBzdG9yZWQgZm9yIGZ1dHVyZSB1c2UuXG4gKi9cbmV4cG9ydCBjbGFzcyBXZWJHcHVCYWNrZW5kIHtcbiAgYWRhcHRlckluZm86IEFkYXB0ZXJJbmZvSW1wbDtcbiAgZGV2aWNlOiBHUFVEZXZpY2U7XG4gIC8qKlxuICAgKiBhbiBpbnN0YW5jZSBvZiBHcHVEYXRhTWFuYWdlciB0byBtYW5hZ2UgYSBHcHVEYXRhSWQgLT4gR3B1QnVmZmVyIG1hcHBpbmdcbiAgICovXG4gIGdwdURhdGFNYW5hZ2VyOiBHcHVEYXRhTWFuYWdlcjtcbiAgLyoqXG4gICAqIGFuIGluc3RhbmNlIG9mIFByb2dyYW1NYW5hZ2VyIHRvIGJ1aWxkIGFuZCBydW4gV2ViR1BVIGNvbXB1dGUgc2hhZGVyIHByb2dyYW0sIGFuZCBtYW5hZ2UgYSBQcm9ncmFtS2V5IC0+IFByb2dyYW1cbiAgICogYXJ0aWZhY3RzIG1hcHBpbmdcbiAgICovXG4gIHByb2dyYW1NYW5hZ2VyOiBQcm9ncmFtTWFuYWdlcjtcblxuICAvKipcbiAgICogcmVwcmVzZW50aW5nIHRoZSBzZXNzaW9uIElEIG9mIHdoaWNoIGlzIGN1cnJlbnRseSBiZWluZyBydW4uXG4gICAqIGBudWxsYCBtZWFucyBubyBzZXNzaW9uIGlzIGJlaW5nIHJ1bi5cbiAgICogb25seSB2YWxpZCB3aGVuIHNlc3Npb24ucnVuIGlzIGV4ZWN1dGVkLlxuICAgKi9cbiAgY3VycmVudFNlc3Npb25JZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIHJlcHJlc2VudGluZyB0aGUga2VybmVsIElEIG9mIHdoaWNoIGlzIGN1cnJlbnRseSBiZWluZyBjb21wdXRlZCAoQ1BVIGNvZGUgcGVyc3BlY3RpdmUpLlxuICAgKiBgbnVsbGAgbWVhbnMgbm8ga2VybmVsIGlzIGJlaW5nIGNvbXB1dGVkLlxuICAgKiBvbmx5IG9uZSBrZXJuZWwgY2FuIGJlIGNvbXB1dGVkIGF0IGEgbW9tZW50LlxuICAgKi9cbiAgY3VycmVudEtlcm5lbElkOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqXG4gICAqIGEgbGlzdCBvZiB0ZW1wb3JhcnkgR1BVIGRhdGEgZm9yIHRoZSBjdXJyZW50IGtlcm5lbC4gc2hvdWxkIHJlbGVhc2Ugd2hlbiB0aGUga2VybmVsIGRvbmUgY29tcHV0YXRpb24uXG4gICAqL1xuICBwcml2YXRlIHRlbXBvcmFyeURhdGE6IEdwdURhdGFbXTtcbiAgLyoqXG4gICAqIGEgS2VybmVsSUQgLT4gYSBHUFUgZGF0YSBsaXN0LCB3aGljaCBzdG9yZXMgcGVyc2lzdGVudCBHUFUgZGF0YSBvd25lZCBieSB0aGUgc3BlY2lmaWMga2VybmVsLlxuICAgKi9cbiAgcHJpdmF0ZSBrZXJuZWxQZXJzaXN0ZW50RGF0YTogTWFwPG51bWJlciwgR3B1RGF0YVtdPjtcbiAgLyoqXG4gICAqIGEgS2VybmVsSUQgLT4gYSBjdXN0b20gZGF0YSwgd2hpY2ggc3RvcmVzIGN1c3RvbSBkYXRhIG93bmVkIGJ5IHRoZSBzcGVjaWZpYyBrZXJuZWwuXG4gICAqL1xuICBwcml2YXRlIGtlcm5lbEN1c3RvbURhdGE6IE1hcDxudW1iZXIsIHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9PjtcbiAgLyoqXG4gICAqIGdldCB0aGUgY3VzdG9tIGRhdGEgb2YgdGhlIGN1cnJlbnQga2VybmVsXG4gICAqL1xuICBnZXQgY3VycmVudEtlcm5lbEN1c3RvbURhdGEoKTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0ge1xuICAgIGlmICh0aGlzLmN1cnJlbnRLZXJuZWxJZCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50S2VybmVsQ3VzdG9tRGF0YSgpOiBjdXJyZW50S2VybmVsSWQgaXMgbnVsbC4gKHNob3VsZCBub3QgaGFwcGVuKScpO1xuICAgIH1cblxuICAgIGxldCBkYXRhID0gdGhpcy5rZXJuZWxDdXN0b21EYXRhLmdldCh0aGlzLmN1cnJlbnRLZXJuZWxJZCk7XG4gICAgaWYgKCFkYXRhKSB7XG4gICAgICBkYXRhID0ge307XG4gICAgICB0aGlzLmtlcm5lbEN1c3RvbURhdGEuc2V0KHRoaXMuY3VycmVudEtlcm5lbElkLCBkYXRhKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIC8vIEtlcm5lbElEIC0+IGtlcm5lbEluZm8gbWFwcGluZ1xuICBrZXJuZWxzOiBNYXA8bnVtYmVyLCBLZXJuZWxJbmZvPjtcbiAgcHJpdmF0ZSBjb21tYW5kRW5jb2RlcjogR1BVQ29tbWFuZEVuY29kZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjb21wdXRlUGFzc0VuY29kZXI6IEdQVUNvbXB1dGVQYXNzRW5jb2RlciB8IG51bGwgPSBudWxsO1xuICBtYXhEaXNwYXRjaE51bWJlciA9IDE2O1xuICBwZW5kaW5nRGlzcGF0Y2hOdW1iZXIgPSAwO1xuXG4gIC8vIGluZm8gb2Yga2VybmVscyBwZW5kaW5nIHN1Ym1pc3Npb24gZm9yIGEgc2luZ2xlIGJhdGNoXG4gIHByaXZhdGUgcGVuZGluZ0tlcm5lbHM6IFBlbmRpbmdLZXJuZWxJbmZvW10gPSBbXTtcbiAgLy8gcXVlcnlSZWFkQnVmZmVyIC0+IHBlbmRpbmdLZXJuZWxzIG1hcHBpbmcgZm9yIGFsbCB0aGUgYmF0Y2hlc1xuICBwcml2YXRlIHBlbmRpbmdRdWVyaWVzOiBNYXA8R1BVQnVmZmVyLCBQZW5kaW5nS2VybmVsSW5mb1tdPiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBxdWVyeVJlc29sdmVCdWZmZXI/OiBHUFVCdWZmZXI7XG4gIHByaXZhdGUgcXVlcnlTZXQ/OiBHUFVRdWVyeVNldDtcbiAgcHJpdmF0ZSBxdWVyeVRpbWVCYXNlPzogYmlnaW50O1xuICBxdWVyeVR5cGU6IFRpbWVzdGFtcFF1ZXJ5O1xuXG4gIGVudjogRW52O1xuICBzZXNzaW9uU3RhdHVzOiBTZXNzaW9uU3RhdGUgPSAnZGVmYXVsdCc7XG4gIC8qKlxuICAgKiBhIFNlc3Npb25JRCAtPiBDb21tYW5kSW5mb1tdIG1hcHBpbmcuIEl0J3MgdXNlZCB0byByZWNvcmQgYWxsIEdQVSBjb21tYW5kcyBmb3IgY29ycmVzcG9uZGluZyBzZXNzaW9uLlxuICAgKi9cbiAgY2FwdHVyZWRDb21tYW5kTGlzdDogTWFwPG51bWJlciwgQ29tbWFuZEluZm9bXT4gPSBuZXcgTWFwKCk7XG5cbiAgLyoqXG4gICAqIGEgU2Vzc2lvbklEIC0+IFBlbmRpbmdLZXJuZWxJbmZvW10gbWFwcGluZyBmb3IgcHJvZmlsaW5nLlxuICAgKi9cbiAgcHJpdmF0ZSBjYXB0dXJlZFBlbmRpbmdLZXJuZWxzOiBNYXA8bnVtYmVyLCBQZW5kaW5nS2VybmVsSW5mb1tdPiA9IG5ldyBNYXAoKTtcblxuICAvKipcbiAgICogYSBTZXNzaW9uSUQgLT4gYSBNYXAgb2YgKElucHV0T3V0cHV0SW5kZXggLT4gW0lELCBHUFVCdWZmZXJdKSBtYXBwaW5nLlxuICAgKi9cbiAgc2Vzc2lvbkV4dGVybmFsRGF0YU1hcHBpbmc6IE1hcDxudW1iZXIsIE1hcDxudW1iZXIsIFtudW1iZXIsIEdQVUJ1ZmZlcl0+PiA9IG5ldyBNYXAoKTtcblxuICBhc3luYyBpbml0aWFsaXplKGVudjogRW52LCBhZGFwdGVyOiBHUFVBZGFwdGVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5lbnYgPSBlbnY7XG4gICAgY29uc3QgcmVxdWlyZWRGZWF0dXJlczogR1BVRmVhdHVyZU5hbWVbXSA9IFtdO1xuICAgIGNvbnN0IGRldmljZURlc2NyaXB0b3I6IEdQVURldmljZURlc2NyaXB0b3IgPSB7XG4gICAgICByZXF1aXJlZExpbWl0czoge1xuICAgICAgICBtYXhDb21wdXRlV29ya2dyb3VwU3RvcmFnZVNpemU6IGFkYXB0ZXIubGltaXRzLm1heENvbXB1dGVXb3JrZ3JvdXBTdG9yYWdlU2l6ZSxcbiAgICAgICAgbWF4Q29tcHV0ZVdvcmtncm91cHNQZXJEaW1lbnNpb246IGFkYXB0ZXIubGltaXRzLm1heENvbXB1dGVXb3JrZ3JvdXBzUGVyRGltZW5zaW9uLFxuICAgICAgICBtYXhTdG9yYWdlQnVmZmVyQmluZGluZ1NpemU6IGFkYXB0ZXIubGltaXRzLm1heFN0b3JhZ2VCdWZmZXJCaW5kaW5nU2l6ZSxcbiAgICAgICAgbWF4QnVmZmVyU2l6ZTogYWRhcHRlci5saW1pdHMubWF4QnVmZmVyU2l6ZSxcbiAgICAgICAgbWF4Q29tcHV0ZUludm9jYXRpb25zUGVyV29ya2dyb3VwOiBhZGFwdGVyLmxpbWl0cy5tYXhDb21wdXRlSW52b2NhdGlvbnNQZXJXb3JrZ3JvdXAsXG4gICAgICAgIG1heENvbXB1dGVXb3JrZ3JvdXBTaXplWDogYWRhcHRlci5saW1pdHMubWF4Q29tcHV0ZVdvcmtncm91cFNpemVYLFxuICAgICAgICBtYXhDb21wdXRlV29ya2dyb3VwU2l6ZVk6IGFkYXB0ZXIubGltaXRzLm1heENvbXB1dGVXb3JrZ3JvdXBTaXplWSxcbiAgICAgICAgbWF4Q29tcHV0ZVdvcmtncm91cFNpemVaOiBhZGFwdGVyLmxpbWl0cy5tYXhDb21wdXRlV29ya2dyb3VwU2l6ZVosXG4gICAgICB9LFxuICAgICAgcmVxdWlyZWRGZWF0dXJlcyxcbiAgICB9O1xuXG4gICAgLy8gVHJ5IHJlcXVpcmluZyBXZWJHUFUgZmVhdHVyZXNcbiAgICBjb25zdCByZXF1aXJlRmVhdHVyZUlmQXZhaWxhYmxlID0gKGZlYXR1cmU6IEdQVUZlYXR1cmVOYW1lKSA9PlxuICAgICAgYWRhcHRlci5mZWF0dXJlcy5oYXMoZmVhdHVyZSkgJiYgcmVxdWlyZWRGZWF0dXJlcy5wdXNoKGZlYXR1cmUpICYmIHRydWU7XG4gICAgLy8gVHJ5IGNocm9taXVtLWV4cGVyaW1lbnRhbC10aW1lc3RhbXAtcXVlcnktaW5zaWRlLXBhc3NlcyBhbmQgZmFsbGJhY2sgdG8gdGltZXN0YW1wLXF1ZXJ5XG4gICAgaWYgKCFyZXF1aXJlRmVhdHVyZUlmQXZhaWxhYmxlKCdjaHJvbWl1bS1leHBlcmltZW50YWwtdGltZXN0YW1wLXF1ZXJ5LWluc2lkZS1wYXNzZXMnIGFzIEdQVUZlYXR1cmVOYW1lKSkge1xuICAgICAgcmVxdWlyZUZlYXR1cmVJZkF2YWlsYWJsZSgndGltZXN0YW1wLXF1ZXJ5Jyk7XG4gICAgfVxuICAgIHJlcXVpcmVGZWF0dXJlSWZBdmFpbGFibGUoJ3NoYWRlci1mMTYnKTtcbiAgICAvLyBUcnkgc3ViZ3JvdXBzXG4gICAgcmVxdWlyZUZlYXR1cmVJZkF2YWlsYWJsZSgnc3ViZ3JvdXBzJyBhcyBHUFVGZWF0dXJlTmFtZSk7XG5cbiAgICB0aGlzLmRldmljZSA9IGF3YWl0IGFkYXB0ZXIucmVxdWVzdERldmljZShkZXZpY2VEZXNjcmlwdG9yKTtcbiAgICB0aGlzLmFkYXB0ZXJJbmZvID0gbmV3IEFkYXB0ZXJJbmZvSW1wbChhZGFwdGVyLmluZm8gfHwgKGF3YWl0IGFkYXB0ZXIucmVxdWVzdEFkYXB0ZXJJbmZvKCkpKTtcbiAgICB0aGlzLmdwdURhdGFNYW5hZ2VyID0gY3JlYXRlR3B1RGF0YU1hbmFnZXIodGhpcyk7XG4gICAgdGhpcy5wcm9ncmFtTWFuYWdlciA9IG5ldyBQcm9ncmFtTWFuYWdlcih0aGlzKTtcbiAgICB0aGlzLmtlcm5lbHMgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5rZXJuZWxQZXJzaXN0ZW50RGF0YSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmtlcm5lbEN1c3RvbURhdGEgPSBuZXcgTWFwKCk7XG5cbiAgICAvLyBzZXQgdXAgZmxhZ3MgZm9yIGxvZ2dlclxuICAgIGNvbmZpZ3VyZUxvZ2dlcihlbnYubG9nTGV2ZWwhLCAhIWVudi5kZWJ1Zyk7XG5cbiAgICAvLyBUT0RPOiBzZXQgdXAgZmxhZ3NcblxuICAgIHRoaXMuZGV2aWNlLm9udW5jYXB0dXJlZGVycm9yID0gKGV2KSA9PiB7XG4gICAgICBpZiAoZXYuZXJyb3IgaW5zdGFuY2VvZiBHUFVWYWxpZGF0aW9uRXJyb3IpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgY29uc29sZS5lcnJvcihgQW4gdW5jYXVnaHQgV2ViR1BVIHZhbGlkYXRpb24gZXJyb3Igd2FzIHJhaXNlZDogJHtldi5lcnJvci5tZXNzYWdlfWApO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcy5lbnYud2ViZ3B1LCAnZGV2aWNlJywge1xuICAgICAgdmFsdWU6IHRoaXMuZGV2aWNlLFxuICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwgLy8gQWxsb3cgZGVsZXRpb24gd2hlbiBkZXZpY2UgaXMgZGVzdHJveWVkXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMuZW52LndlYmdwdSwgJ2FkYXB0ZXInLCB7XG4gICAgICB2YWx1ZTogYWRhcHRlcixcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgLy8gaW5pdCBxdWVyeVR5cGUsIHdoaWNoIGlzIG5lY2Vzc2FyeSBmb3IgSW5mZXJlbmNlU2Vzc2lvbi5jcmVhdGVcbiAgICB0aGlzLnNldFF1ZXJ5VHlwZSgpO1xuICB9XG5cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIHRoaXMucXVlcnlTZXQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLnF1ZXJ5U2V0LmRlc3Ryb3koKTtcbiAgICB9XG4gICAgdGhpcy5ncHVEYXRhTWFuYWdlci5kaXNwb3NlKCk7XG5cbiAgICAvLyBDbGVhciB0aGUgZGV2aWNlIHJlZmVyZW5jZSB3aGVuIGl0J3MgbG9zdCB0byBhbGxvdyBuZXcgc2Vzc2lvbnMgdG8gY3JlYXRlIGEgZnJlc2ggZGV2aWNlXG4gICAgLy8gVGhpcyBoYW5kbGVzIHRoZSBjYXNlIHdoZXJlIHByZXNlcnZlX2RldmljZT1mYWxzZSAoZGVmYXVsdCkgY2F1c2VzIHRoZSBDKysgc2lkZSB0byBkZXN0cm95IHRoZSBkZXZpY2VcbiAgICBpZiAodGhpcy5kZXZpY2UgJiYgdGhpcy5lbnY/LndlYmdwdSkge1xuICAgICAgdm9pZCB0aGlzLmRldmljZS5sb3N0LnRoZW4oKCkgPT4ge1xuICAgICAgICBkZWxldGUgKHRoaXMuZW52LndlYmdwdSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5kZXZpY2U7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXRDb21tYW5kRW5jb2RlcigpOiBHUFVDb21tYW5kRW5jb2RlciB7XG4gICAgaWYgKCF0aGlzLmNvbW1hbmRFbmNvZGVyKSB7XG4gICAgICB0aGlzLmNvbW1hbmRFbmNvZGVyID0gdGhpcy5kZXZpY2UuY3JlYXRlQ29tbWFuZEVuY29kZXIoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZEVuY29kZXI7XG4gIH1cblxuICBnZXRDb21wdXRlUGFzc0VuY29kZXIoKTogR1BVQ29tcHV0ZVBhc3NFbmNvZGVyIHtcbiAgICBpZiAoIXRoaXMuY29tcHV0ZVBhc3NFbmNvZGVyKSB7XG4gICAgICBjb25zdCBjb21tYW5kRW5jb2RlciA9IHRoaXMuZ2V0Q29tbWFuZEVuY29kZXIoKTtcbiAgICAgIGNvbnN0IGNvbXB1dGVQYXNzRGVzY3JpcHRvcjogR1BVQ29tcHV0ZVBhc3NEZXNjcmlwdG9yID0ge307XG5cbiAgICAgIGlmICh0aGlzLnF1ZXJ5VHlwZSA9PT0gJ2F0LXBhc3NlcycpIHtcbiAgICAgICAgY29tcHV0ZVBhc3NEZXNjcmlwdG9yLnRpbWVzdGFtcFdyaXRlcyA9IHtcbiAgICAgICAgICBxdWVyeVNldDogdGhpcy5xdWVyeVNldCEsXG4gICAgICAgICAgYmVnaW5uaW5nT2ZQYXNzV3JpdGVJbmRleDogdGhpcy5wZW5kaW5nRGlzcGF0Y2hOdW1iZXIgKiAyLFxuICAgICAgICAgIGVuZE9mUGFzc1dyaXRlSW5kZXg6IHRoaXMucGVuZGluZ0Rpc3BhdGNoTnVtYmVyICogMiArIDEsXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHRoaXMuY29tcHV0ZVBhc3NFbmNvZGVyID0gY29tbWFuZEVuY29kZXIuYmVnaW5Db21wdXRlUGFzcyhjb21wdXRlUGFzc0Rlc2NyaXB0b3IpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlUGFzc0VuY29kZXI7XG4gIH1cblxuICBlbmRDb21wdXRlUGFzcygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jb21wdXRlUGFzc0VuY29kZXIpIHtcbiAgICAgIHRoaXMuY29tcHV0ZVBhc3NFbmNvZGVyLmVuZCgpO1xuICAgICAgdGhpcy5jb21wdXRlUGFzc0VuY29kZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGZsdXNoKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jb21tYW5kRW5jb2Rlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIFRSQUNFX0ZVTkNfQkVHSU4oKTtcblxuICAgIHRoaXMuZW5kQ29tcHV0ZVBhc3MoKTtcbiAgICBsZXQgcXVlcnlSZWFkQnVmZmVyOiBHUFVCdWZmZXI7XG4gICAgaWYgKHRoaXMucXVlcnlUeXBlICE9PSAnbm9uZScpIHtcbiAgICAgIHRoaXMuY29tbWFuZEVuY29kZXIucmVzb2x2ZVF1ZXJ5U2V0KFxuICAgICAgICB0aGlzLnF1ZXJ5U2V0ISxcbiAgICAgICAgMCxcbiAgICAgICAgdGhpcy5wZW5kaW5nRGlzcGF0Y2hOdW1iZXIgKiAyLFxuICAgICAgICB0aGlzLnF1ZXJ5UmVzb2x2ZUJ1ZmZlciEsXG4gICAgICAgIDAsXG4gICAgICApO1xuXG4gICAgICBxdWVyeVJlYWRCdWZmZXIgPSB0aGlzLmRldmljZS5jcmVhdGVCdWZmZXIoXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgICAgIHsgc2l6ZTogdGhpcy5wZW5kaW5nRGlzcGF0Y2hOdW1iZXIgKiAyICogOCwgdXNhZ2U6IEdQVUJ1ZmZlclVzYWdlLk1BUF9SRUFEIHwgR1BVQnVmZmVyVXNhZ2UuQ09QWV9EU1QgfSxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMucGVuZGluZ1F1ZXJpZXMuc2V0KHF1ZXJ5UmVhZEJ1ZmZlciwgdGhpcy5wZW5kaW5nS2VybmVscyk7XG4gICAgICB0aGlzLnBlbmRpbmdLZXJuZWxzID0gW107XG4gICAgICB0aGlzLmNvbW1hbmRFbmNvZGVyLmNvcHlCdWZmZXJUb0J1ZmZlcihcbiAgICAgICAgdGhpcy5xdWVyeVJlc29sdmVCdWZmZXIhLFxuICAgICAgICAwLFxuICAgICAgICBxdWVyeVJlYWRCdWZmZXIsXG4gICAgICAgIDAsXG4gICAgICAgIHRoaXMucGVuZGluZ0Rpc3BhdGNoTnVtYmVyICogMiAqIDgsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMuZGV2aWNlLnF1ZXVlLnN1Ym1pdChbdGhpcy5jb21tYW5kRW5jb2Rlci5maW5pc2goKV0pO1xuICAgIHRoaXMuZ3B1RGF0YU1hbmFnZXIucmVmcmVzaFBlbmRpbmdCdWZmZXJzKCk7XG4gICAgdGhpcy5jb21tYW5kRW5jb2RlciA9IG51bGw7XG4gICAgdGhpcy5wZW5kaW5nRGlzcGF0Y2hOdW1iZXIgPSAwO1xuXG4gICAgaWYgKHRoaXMucXVlcnlUeXBlICE9PSAnbm9uZScpIHtcbiAgICAgIHZvaWQgcXVlcnlSZWFkQnVmZmVyIS5tYXBBc3luYyhHUFVNYXBNb2RlLlJFQUQpLnRoZW4oKCkgPT4ge1xuICAgICAgICBjb25zdCBtYXBwZWREYXRhID0gbmV3IEJpZ1VpbnQ2NEFycmF5KHF1ZXJ5UmVhZEJ1ZmZlci5nZXRNYXBwZWRSYW5nZSgpKTtcbiAgICAgICAgY29uc3QgcGVuZGluZ0tlcm5lbHMgPSB0aGlzLnBlbmRpbmdRdWVyaWVzLmdldChxdWVyeVJlYWRCdWZmZXIpITtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXBwZWREYXRhLmxlbmd0aCAvIDI7IGkrKykge1xuICAgICAgICAgIGNvbnN0IHBlbmRpbmdLZXJuZWxJbmZvID0gcGVuZGluZ0tlcm5lbHNbaV07XG4gICAgICAgICAgY29uc3Qga2VybmVsSWQgPSBwZW5kaW5nS2VybmVsSW5mby5rZXJuZWxJZDtcbiAgICAgICAgICBjb25zdCBrZXJuZWxJbmZvID0gdGhpcy5rZXJuZWxzLmdldChrZXJuZWxJZCkhO1xuICAgICAgICAgIGNvbnN0IGtlcm5lbFR5cGUgPSBrZXJuZWxJbmZvLmtlcm5lbFR5cGU7XG4gICAgICAgICAgY29uc3Qga2VybmVsTmFtZSA9IGtlcm5lbEluZm8ua2VybmVsTmFtZTtcbiAgICAgICAgICBjb25zdCBwcm9ncmFtTmFtZSA9IHBlbmRpbmdLZXJuZWxJbmZvLnByb2dyYW1OYW1lO1xuICAgICAgICAgIGNvbnN0IGlucHV0VGVuc29yVmlld3MgPSBwZW5kaW5nS2VybmVsSW5mby5pbnB1dFRlbnNvclZpZXdzO1xuICAgICAgICAgIGNvbnN0IG91dHB1dFRlbnNvclZpZXdzID0gcGVuZGluZ0tlcm5lbEluZm8ub3V0cHV0VGVuc29yVmlld3M7XG4gICAgICAgICAgY29uc3Qgc3RhcnRUaW1lVTY0ID0gbWFwcGVkRGF0YVtpICogMl07XG4gICAgICAgICAgY29uc3QgZW5kVGltZVU2NCA9IG1hcHBlZERhdGFbaSAqIDIgKyAxXTtcblxuICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5xdWVyeVRpbWVCYXNlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhpcy5xdWVyeVRpbWVCYXNlID0gc3RhcnRUaW1lVTY0O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IE51bWJlcihzdGFydFRpbWVVNjQgLSB0aGlzLnF1ZXJ5VGltZUJhc2UpO1xuICAgICAgICAgIGNvbnN0IGVuZFRpbWUgPSBOdW1iZXIoZW5kVGltZVU2NCAtIHRoaXMucXVlcnlUaW1lQmFzZSk7XG5cbiAgICAgICAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKHN0YXJ0VGltZSkgfHwgIU51bWJlci5pc1NhZmVJbnRlZ2VyKGVuZFRpbWUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignaW5jb3JyZWN0IHRpbWVzdGFtcCByYW5nZScpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0aGlzLmVudi53ZWJncHUucHJvZmlsaW5nPy5vbmRhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuZW52LndlYmdwdS5wcm9maWxpbmcub25kYXRhKHtcbiAgICAgICAgICAgICAgdmVyc2lvbjogMSxcbiAgICAgICAgICAgICAgaW5wdXRzTWV0YWRhdGE6IGlucHV0VGVuc29yVmlld3MubWFwKCh2YWx1ZSkgPT4gKHtcbiAgICAgICAgICAgICAgICBkaW1zOiB2YWx1ZS5kaW1zLFxuICAgICAgICAgICAgICAgIGRhdGFUeXBlOiB0ZW5zb3JEYXRhVHlwZUVudW1Ub1N0cmluZyh2YWx1ZS5kYXRhVHlwZSksXG4gICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgICAgb3V0cHV0c01ldGFkYXRhOiBvdXRwdXRUZW5zb3JWaWV3cy5tYXAoKHZhbHVlKSA9PiAoe1xuICAgICAgICAgICAgICAgIGRpbXM6IHZhbHVlLmRpbXMsXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6IHRlbnNvckRhdGFUeXBlRW51bVRvU3RyaW5nKHZhbHVlLmRhdGFUeXBlKSxcbiAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgICBrZXJuZWxJZCxcbiAgICAgICAgICAgICAga2VybmVsVHlwZSxcbiAgICAgICAgICAgICAga2VybmVsTmFtZSxcbiAgICAgICAgICAgICAgcHJvZ3JhbU5hbWUsXG4gICAgICAgICAgICAgIHN0YXJ0VGltZSxcbiAgICAgICAgICAgICAgZW5kVGltZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBpZiBubyBjYWxsYmFjayBpcyBwcm92aWRlZCwgcHJpbnQgdGhlIHByb2ZpbGluZyBtZXNzYWdlIHRvIGNvbnNvbGVcbiAgICAgICAgICAgIGxldCBpbnB1dFNoYXBlcyA9ICcnO1xuICAgICAgICAgICAgaW5wdXRUZW5zb3JWaWV3cy5mb3JFYWNoKCh2YWx1ZSwgaSkgPT4ge1xuICAgICAgICAgICAgICBpbnB1dFNoYXBlcyArPSBgaW5wdXRbJHtpfV06IFske3ZhbHVlLmRpbXN9XSB8ICR7dGVuc29yRGF0YVR5cGVFbnVtVG9TdHJpbmcodmFsdWUuZGF0YVR5cGUpfSwgYDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbGV0IG91dHB1dFNoYXBlcyA9ICcnO1xuICAgICAgICAgICAgb3V0cHV0VGVuc29yVmlld3MuZm9yRWFjaCgodmFsdWUsIGkpID0+IHtcbiAgICAgICAgICAgICAgb3V0cHV0U2hhcGVzICs9IGBvdXRwdXRbJHtpfV06IFske3ZhbHVlLmRpbXN9XSB8ICR7dGVuc29yRGF0YVR5cGVFbnVtVG9TdHJpbmcodmFsdWUuZGF0YVR5cGUpfSwgYDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICBgW3Byb2ZpbGluZ10ga2VybmVsIFwiJHtrZXJuZWxJZH18JHtrZXJuZWxUeXBlfXwke2tlcm5lbE5hbWV9fCR7cHJvZ3JhbU5hbWV9XCIgJHtpbnB1dFNoYXBlc30ke1xuICAgICAgICAgICAgICAgIG91dHB1dFNoYXBlc1xuICAgICAgICAgICAgICB9c3RhcnQgdGltZTogJHtzdGFydFRpbWV9IG5zLCBleGVjdXRpb24gdGltZTogJHtlbmRUaW1lIC0gc3RhcnRUaW1lfSBuc2AsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBUUkFDRSgnR1BVJywgYCR7cHJvZ3JhbU5hbWV9Ojoke3N0YXJ0VGltZVU2NH06OiR7ZW5kVGltZVU2NH1gKTtcbiAgICAgICAgfVxuICAgICAgICBxdWVyeVJlYWRCdWZmZXIudW5tYXAoKTtcbiAgICAgICAgdGhpcy5wZW5kaW5nUXVlcmllcy5kZWxldGUocXVlcnlSZWFkQnVmZmVyKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBUUkFDRV9GVU5DX0VORCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIHJ1biBhIFdlYkdQVSBwcm9ncmFtLlxuICAgKiBAcGFyYW0gcHJvZ3JhbSBhIFByb2dyYW1JbmZvIGluc3RhbmNlXG4gICAqIEBwYXJhbSBpbnB1dFRlbnNvclZpZXdzIGEgVGVuc29yVmlldyBhcnJheS4gZWFjaCBlbGVtZW50IHJlcHJlc2VudHMgYSB2YWx1ZSBhbHJlYWR5IGV4aXN0cyBpbiBHUFUuXG4gICAqIEBwYXJhbSBvdXRwdXRJbmRpY2VzIGFuIGluZGljZXMgYXJyYXkuIGVhY2ggZWxlbWVudCBjYW4gYmUgZWl0aGVyIC0xICh0ZW1wb3JhcnkgZGF0YSksIC0yIChwZXJzaXN0ZW50IGRhdGEpIG9yIGFuXG4gICAqIGluZGV4IHRvIHRoZSBrZXJuZWwncyBvdXRwdXQuXG4gICAqIEBwYXJhbSBjcmVhdGVLZXJuZWxPdXRwdXQgYSBjYWxsYmFjayBmdW5jdGlvbiB0aGF0IGNyZWF0ZSBhIHZhbHVlIHRvIGtlcm5lbCdzIG91dHB1dCB3aXRoIHRoZSBnaXZlbiBpbmRleFxuICAgKiBAcGFyYW0gY3JlYXRlSW50ZXJtZWRpYXRlT3V0cHV0IGEgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCBjcmVhdGUgYSB2YWx1ZSBhcyBhIGludGVybWVkaWF0ZSB2YWx1ZSwgZWl0aGVyIHRlbXBvcmFyeVxuICAgKiBvciBwZXJzaXN0ZW50IChvd25lZCBieSB0aGUgY3VycmVudCBrZXJuZWwpXG4gICAqIEByZXR1cm5zIGEgVGVuc29yVmlldyBhcnJheSByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC5cbiAgICovXG4gIHJ1bihcbiAgICBwcm9ncmFtOiBQcm9ncmFtSW5mbyxcbiAgICBpbnB1dFRlbnNvclZpZXdzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gICAgb3V0cHV0SW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgY3JlYXRlS2VybmVsT3V0cHV0OiAoaW5kZXg6IG51bWJlciwgZGF0YVR5cGU6IG51bWJlciwgZGltczogcmVhZG9ubHkgbnVtYmVyW10pID0+IFRlbnNvclZpZXcsXG4gICAgY3JlYXRlSW50ZXJtZWRpYXRlT3V0cHV0OiAoZGF0YVR5cGU6IG51bWJlciwgZGltczogcmVhZG9ubHkgbnVtYmVyW10pID0+IFRlbnNvclZpZXcsXG4gICAgb3V0cHV0Q291bnQ6IG51bWJlcixcbiAgKTogVGVuc29yVmlld1tdIHtcbiAgICBUUkFDRV9GVU5DX0JFR0lOKHByb2dyYW0ubmFtZSk7XG4gICAgLy8gY3JlYXRlIGluZm8gZm9yIGlucHV0c1xuICAgIGNvbnN0IGlucHV0RGF0YXM6IEdwdURhdGFbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRUZW5zb3JWaWV3cy5sZW5ndGg7ICsraSkge1xuICAgICAgY29uc3QgZGF0YSA9IGlucHV0VGVuc29yVmlld3NbaV0uZGF0YTtcbiAgICAgIC8vIGlmIHRlbnNvciB2aWV3IGRhdGEgaXMgMCwgaXQgbWVhbnMgdGhlIG91dHB1dCBpcyB6ZXJvLXNpemVkIHRlbnNvciwgYW5kIHRoZXJlIGlzIG5vIEdQVSBkYXRhIGZvciBpdC5cbiAgICAgIGlmIChkYXRhID09PSAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgZ3B1RGF0YSA9IHRoaXMuZ3B1RGF0YU1hbmFnZXIuZ2V0KGRhdGEpO1xuICAgICAgaWYgKCFncHVEYXRhKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbm8gR1BVIGRhdGEgZm9yIGlucHV0OiAke2RhdGF9YCk7XG4gICAgICB9XG4gICAgICBpbnB1dERhdGFzLnB1c2goZ3B1RGF0YSk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBvdXRwdXRzLCBkaXNwYXRjaEdyb3VwLCBwcm9ncmFtVW5pZm9ybXMgfSA9IHByb2dyYW0uZ2V0UnVuRGF0YShpbnB1dFRlbnNvclZpZXdzKTtcblxuICAgIC8vIGNoZWNrIG91dHB1dCBpbmRpY2VzXG4gICAgY29uc3QgdmFsaWRhdGVkT3V0cHV0SW5kaWNlcyA9IG91dHB1dEluZGljZXMubGVuZ3RoID09PSAwID8gb3V0cHV0cy5tYXAoKF8sIGkpID0+IGkpIDogb3V0cHV0SW5kaWNlcztcbiAgICBpZiAodmFsaWRhdGVkT3V0cHV0SW5kaWNlcy5sZW5ndGggIT09IG91dHB1dHMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE91dHB1dCBzaXplICR7dmFsaWRhdGVkT3V0cHV0SW5kaWNlcy5sZW5ndGh9IG11c3QgYmUgZXF1YWwgdG8gJHtvdXRwdXRzLmxlbmd0aH0uYCk7XG4gICAgfVxuXG4gICAgLy8gY3JlYXRlIGluZm8gZm9yIG91dHB1dHNcbiAgICBjb25zdCBvdXRwdXRUZW5zb3JWaWV3czogVGVuc29yVmlld1tdID0gW107XG4gICAgY29uc3Qgb3V0cHV0RGF0YXM6IEdwdURhdGFbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0cy5sZW5ndGg7ICsraSkge1xuICAgICAgLy8gdmFsdWUgLTEgYW5kIC0yIGFyZSB1c2VkIGZvciBjcmVhdGluZyB0ZW1wb3JhcnkgYW5kIHBlcnNpc3RlbnQgb3V0cHV0cy5cbiAgICAgIC8vIHZhbHVlIC0zIGlzIHVzZWQgZm9yIHBsYWNlaG9sZGVyIG91dHB1dC4gU28gLTMsIC0yLCAtMSBhbmQgMCwgMSwgMiwgLi4uIGFyZSB2YWxpZFxuICAgICAgLy8gb3V0cHV0IGluZGljZXMuIHNlZSB0eXBlIGRlZmluaXRpb24gb2YgQ29tcHV0ZUNvbnRleHRJbnB1dHNPdXRwdXRzTWFwcGluZyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgaWYgKFxuICAgICAgICAhTnVtYmVyLmlzSW50ZWdlcih2YWxpZGF0ZWRPdXRwdXRJbmRpY2VzW2ldKSB8fFxuICAgICAgICB2YWxpZGF0ZWRPdXRwdXRJbmRpY2VzW2ldIDwgLTMgfHxcbiAgICAgICAgdmFsaWRhdGVkT3V0cHV0SW5kaWNlc1tpXSA+PSBvdXRwdXRDb3VudFxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBvdXRwdXQgaW5kZXg6ICR7dmFsaWRhdGVkT3V0cHV0SW5kaWNlc1tpXX1gKTtcbiAgICAgIH1cbiAgICAgIGlmICh2YWxpZGF0ZWRPdXRwdXRJbmRpY2VzW2ldID09PSAtMykge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGlzVGVtcG9yYXJ5ID0gdmFsaWRhdGVkT3V0cHV0SW5kaWNlc1tpXSA9PT0gLTE7XG4gICAgICBjb25zdCBpc1BlcnNpc3RlbnQgPSB2YWxpZGF0ZWRPdXRwdXRJbmRpY2VzW2ldID09PSAtMjtcbiAgICAgIGNvbnN0IHRlbnNvclZpZXcgPVxuICAgICAgICBpc1RlbXBvcmFyeSB8fCBpc1BlcnNpc3RlbnRcbiAgICAgICAgICA/IGNyZWF0ZUludGVybWVkaWF0ZU91dHB1dChvdXRwdXRzW2ldLmRhdGFUeXBlLCBvdXRwdXRzW2ldLmRpbXMpXG4gICAgICAgICAgOiBjcmVhdGVLZXJuZWxPdXRwdXQodmFsaWRhdGVkT3V0cHV0SW5kaWNlc1tpXSwgb3V0cHV0c1tpXS5kYXRhVHlwZSwgb3V0cHV0c1tpXS5kaW1zKTtcbiAgICAgIG91dHB1dFRlbnNvclZpZXdzLnB1c2godGVuc29yVmlldyk7XG4gICAgICAvLyBpZiB0ZW5zb3IgdmlldyBkYXRhIGlzIDAsIGl0IG1lYW5zIHRoZSBvdXRwdXQgaXMgemVyby1zaXplZCB0ZW5zb3IsIGFuZCB0aGVyZSBpcyBubyBHUFUgZGF0YSBmb3IgaXQuXG4gICAgICBpZiAodGVuc29yVmlldy5kYXRhID09PSAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgZ3B1RGF0YSA9IHRoaXMuZ3B1RGF0YU1hbmFnZXIuZ2V0KHRlbnNvclZpZXcuZGF0YSk7XG4gICAgICBpZiAoIWdwdURhdGEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBubyBHUFUgZGF0YSBmb3Igb3V0cHV0OiAke3RlbnNvclZpZXcuZGF0YX1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1RlbXBvcmFyeSkge1xuICAgICAgICB0aGlzLnRlbXBvcmFyeURhdGEucHVzaChncHVEYXRhKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1BlcnNpc3RlbnQpIHtcbiAgICAgICAgbGV0IHBlcnNpc3RlbnREYXRhID0gdGhpcy5rZXJuZWxQZXJzaXN0ZW50RGF0YS5nZXQodGhpcy5jdXJyZW50S2VybmVsSWQhKTtcbiAgICAgICAgaWYgKCFwZXJzaXN0ZW50RGF0YSkge1xuICAgICAgICAgIHBlcnNpc3RlbnREYXRhID0gW107XG4gICAgICAgICAgdGhpcy5rZXJuZWxQZXJzaXN0ZW50RGF0YS5zZXQodGhpcy5jdXJyZW50S2VybmVsSWQhLCBwZXJzaXN0ZW50RGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcGVyc2lzdGVudERhdGEucHVzaChncHVEYXRhKTtcbiAgICAgIH1cbiAgICAgIG91dHB1dERhdGFzLnB1c2goZ3B1RGF0YSk7XG4gICAgfVxuXG4gICAgLy8gd2hlbiB0aGVyZSBhcmUgYW55IHplcm8tc2l6ZWQgdGVuc29yIGluIHRoZSBpbnB1dHMgb3Igb3V0cHV0cywgd2Ugc2hvdWxkIHJlcG9ydCBlcnJvciB1bmxlc3MgYWxsIG91dHB1dHMgYXJlXG4gICAgLy8gemVyby1zaXplZCB0ZW5zb3JzLlxuICAgIGlmIChpbnB1dERhdGFzLmxlbmd0aCAhPT0gaW5wdXRUZW5zb3JWaWV3cy5sZW5ndGggfHwgb3V0cHV0RGF0YXMubGVuZ3RoICE9PSBvdXRwdXRUZW5zb3JWaWV3cy5sZW5ndGgpIHtcbiAgICAgIC8vIGlmIGFsbCBvdXRwdXRzIGFyZSB6ZXJvLXNpemVkIHRlbnNvcnMsIHRoZXJlIGlzIG5vIG5lZWQgdG8gcnVuIHRoZSBwcm9ncmFtLlxuICAgICAgaWYgKG91dHB1dERhdGFzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBUUkFDRV9GVU5DX0VORChwcm9ncmFtLm5hbWUpO1xuICAgICAgICByZXR1cm4gb3V0cHV0VGVuc29yVmlld3M7XG4gICAgICB9XG4gICAgICAvLyBpZiBzb21lIG91dHB1dHMgYXJlIHplcm8tc2l6ZWQgdGVuc29ycywgcmVwb3J0IGFuIGVycm9yLlxuICAgICAgLy9cbiAgICAgIC8vIFRPRE86IHNvIGZhciB3ZSBkb24ndCBzZWUgYW55IHVzZSBjYXNlIHRoYXQgb3V0cHV0cyBpbmNsdWRlIGJvdGggemVyby1zaXplZCB0ZW5zb3JzIGFuZCBub24temVyby1zaXplZCB0ZW5zb3JzLlxuICAgICAgLy8gSWYgd2Ugc2VlIHN1Y2ggdXNlIGNhc2UsIHdlIG5lZWQgdG8gbWFrZSBhIGNoYW5nZSBoZXJlIHRvIHN1cHBvcnQgaXQuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBQcm9ncmFtICR7cHJvZ3JhbS5uYW1lfSBoYXMgemVyby1zaXplZCB0ZW5zb3IocykgaW4gaW5wdXRzIG9yIG91dHB1dHMuIFRoaXMgaXMgbm90IHN1cHBvcnRlZCBub3cuYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gbG9hZCB1bmlmb3Jtc1xuICAgIC8vIFRPRE86IGFkZCBjYWNoZSBmb3IgdW5pZm9ybSAoaXMgaXQgbmVjZXNzYXJ5PylcbiAgICAvL1xuICAgIGxldCB1bmlmb3JtQnVmZmVyQmluZGluZzogR1BVQmluZGluZ1Jlc291cmNlIHwgdW5kZWZpbmVkO1xuICAgIGlmIChwcm9ncmFtVW5pZm9ybXMpIHtcbiAgICAgIGxldCBjdXJyZW50T2Zmc2V0ID0gMDtcbiAgICAgIGNvbnN0IG9mZnNldHM6IG51bWJlcltdID0gW107XG5cbiAgICAgIHByb2dyYW1Vbmlmb3Jtcy5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0eXBlb2Ygdi5kYXRhID09PSAnbnVtYmVyJyA/IFt2LmRhdGFdIDogdi5kYXRhO1xuICAgICAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSL1dHU0wvI2FsaWdub2ZcbiAgICAgICAgY29uc3Qgc2l6ZU9mRWxlbWVudCA9IHYudHlwZSA9PT0gRGF0YVR5cGUuZmxvYXQxNiA/IDIgOiA0O1xuICAgICAgICBsZXQgc2l6ZU9mVmVjT3JNYXQ7XG4gICAgICAgIGxldCBiYXNlQWxpZ25tZW50O1xuICAgICAgICBpZiAodi50eXBlID09PSBEYXRhVHlwZS5mbG9hdDE2KSB7XG4gICAgICAgICAgYmFzZUFsaWdubWVudCA9IGRhdGEubGVuZ3RoID4gNCA/IDE2IDogZGF0YS5sZW5ndGggPiAyID8gOCA6IGRhdGEubGVuZ3RoICogc2l6ZU9mRWxlbWVudDtcbiAgICAgICAgICBzaXplT2ZWZWNPck1hdCA9IGRhdGEubGVuZ3RoID4gNCA/IDE2IDogc2l6ZU9mRWxlbWVudCAqIGRhdGEubGVuZ3RoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJhc2VBbGlnbm1lbnQgPSBkYXRhLmxlbmd0aCA8PSAyID8gZGF0YS5sZW5ndGggKiBzaXplT2ZFbGVtZW50IDogMTY7XG4gICAgICAgICAgc2l6ZU9mVmVjT3JNYXQgPSAxNjtcbiAgICAgICAgfVxuICAgICAgICBjdXJyZW50T2Zmc2V0ID0gTWF0aC5jZWlsKGN1cnJlbnRPZmZzZXQgLyBiYXNlQWxpZ25tZW50KSAqIGJhc2VBbGlnbm1lbnQ7XG4gICAgICAgIG9mZnNldHMucHVzaChjdXJyZW50T2Zmc2V0KTtcbiAgICAgICAgLy8gRm9yIG5vbi1mbG9hdDE2IHR5cGUsIHdoZW4gZGF0YS5sZW5ndGggPiA0LCB0aGUgdW5pZm9ybSB2YXJpYWJsZSBpcyBvZiB0eXBlIGFycmF5PHZlYzQ8aTMyfHUzMnxmMzI+LE4+LCB3aGVyZVxuICAgICAgICAvLyBOID0gTWF0aC5jZWlsKGRhdGEubGVuZ3RoIC8gNCkgYW5kIFNpemVPZih2ZWM0PGkzMnx1MzJ8ZjMyPikgPSAxNi4gVGhlIHRvdGFsIGJ5dGUgbGVuZ3RoIGlzIE4gKlxuICAgICAgICAvLyBTaXplT2YodmVjNDxpMzJ8dTMyfGYzMj4pLiBGb3IgZmxvYXQxNiB0eXBlLCB3aGVuIGRhdGEubGVuZ3RoID4gNCwgdGhlIHVuaWZvcm0gdmFyaWFibGUgaXMgb2YgdHlwZVxuICAgICAgICAvLyBhcnJheTxtYXQyeDQ8ZjE2PixOPiwgd2hlcmUgTiA9IE1hdGguY2VpbChkYXRhLmxlbmd0aCAvIDgpIGFuZCBTaXplT2YobWF0Mng0PGYxNj4pID0gMTYuIFRoZSB0b3RhbCBieXRlXG4gICAgICAgIC8vIGxlbmd0aCBpcyBOICogU2l6ZU9mKG1hdDJ4NDxmMTY+KS5cbiAgICAgICAgY29uc3QgZWxlbWVudFBlclZlY09yTWF0ID0gdi50eXBlID09PSBEYXRhVHlwZS5mbG9hdDE2ID8gOCA6IDQ7XG4gICAgICAgIGN1cnJlbnRPZmZzZXQgKz1cbiAgICAgICAgICBkYXRhLmxlbmd0aCA+IDQgPyBNYXRoLmNlaWwoZGF0YS5sZW5ndGggLyBlbGVtZW50UGVyVmVjT3JNYXQpICogc2l6ZU9mVmVjT3JNYXQgOiBkYXRhLmxlbmd0aCAqIHNpemVPZkVsZW1lbnQ7XG4gICAgICB9KTtcblxuICAgICAgLy8gTWVldCBhbGlnbm1lbnQgb2Ygc3RydWN0IGhlcmU6IGh0dHBzOi8vd3d3LnczLm9yZy9UUi9XR1NMLyNhbGlnbm1lbnQtYW5kLXNpemUuIEZvciBzaW1wbGljaXR5LCBzZXRcbiAgICAgIC8vIG1heEFsaWdubWVudE9mRmllbGQgdG8gMTYgc2luY2UgdGhlIHVuZGVybHlpbmcgYnVmZmVyIGhhcyBiZWVuIHJvdW5kZWQgdXAgdG8gMTYuXG4gICAgICBjb25zdCBtYXhBbGlnbm1lbnRPZkZpZWxkID0gMTY7XG4gICAgICBjdXJyZW50T2Zmc2V0ID0gTWF0aC5jZWlsKGN1cnJlbnRPZmZzZXQgLyBtYXhBbGlnbm1lbnRPZkZpZWxkKSAqIG1heEFsaWdubWVudE9mRmllbGQ7XG4gICAgICBjb25zdCBhcnJheUJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihjdXJyZW50T2Zmc2V0KTtcbiAgICAgIHByb2dyYW1Vbmlmb3Jtcy5mb3JFYWNoKCh2LCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IG9mZnNldHNbaV07XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0eXBlb2Ygdi5kYXRhID09PSAnbnVtYmVyJyA/IFt2LmRhdGFdIDogdi5kYXRhO1xuICAgICAgICBpZiAodi50eXBlID09PSBEYXRhVHlwZS5pbnQzMikge1xuICAgICAgICAgIG5ldyBJbnQzMkFycmF5KGFycmF5QnVmZmVyLCBvZmZzZXQsIGRhdGEubGVuZ3RoKS5zZXQoZGF0YSk7XG4gICAgICAgIH0gZWxzZSBpZiAodi50eXBlID09PSBEYXRhVHlwZS51aW50MzIpIHtcbiAgICAgICAgICBuZXcgVWludDMyQXJyYXkoYXJyYXlCdWZmZXIsIG9mZnNldCwgZGF0YS5sZW5ndGgpLnNldChkYXRhKTtcbiAgICAgICAgfSBlbHNlIGlmICh2LnR5cGUgPT09IERhdGFUeXBlLmZsb2F0MTYpIHtcbiAgICAgICAgICBuZXcgVWludDE2QXJyYXkoYXJyYXlCdWZmZXIsIG9mZnNldCwgZGF0YS5sZW5ndGgpLnNldChkYXRhKTtcbiAgICAgICAgfSBlbHNlIGlmICh2LnR5cGUgPT09IERhdGFUeXBlLmZsb2F0KSB7XG4gICAgICAgICAgbmV3IEZsb2F0MzJBcnJheShhcnJheUJ1ZmZlciwgb2Zmc2V0LCBkYXRhLmxlbmd0aCkuc2V0KGRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdW5pZm9ybSB0eXBlOiAke3RlbnNvckRhdGFUeXBlRW51bVRvU3RyaW5nKHYudHlwZSl9YCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB1bmlmb3JtQnVmZmVyRGF0YSA9XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgICAgIHRoaXMuZ3B1RGF0YU1hbmFnZXIuY3JlYXRlKGN1cnJlbnRPZmZzZXQsIEdQVUJ1ZmZlclVzYWdlLkNPUFlfRFNUIHwgR1BVQnVmZmVyVXNhZ2UuVU5JRk9STSk7XG4gICAgICB0aGlzLmRldmljZS5xdWV1ZS53cml0ZUJ1ZmZlcih1bmlmb3JtQnVmZmVyRGF0YS5idWZmZXIsIDAsIGFycmF5QnVmZmVyLCAwLCBjdXJyZW50T2Zmc2V0KTtcbiAgICAgIHRoaXMuZ3B1RGF0YU1hbmFnZXIucmVsZWFzZSh1bmlmb3JtQnVmZmVyRGF0YS5pZCk7XG4gICAgICB1bmlmb3JtQnVmZmVyQmluZGluZyA9IHsgb2Zmc2V0OiAwLCBzaXplOiBjdXJyZW50T2Zmc2V0LCBidWZmZXI6IHVuaWZvcm1CdWZmZXJEYXRhLmJ1ZmZlciB9O1xuICAgIH1cblxuICAgIGNvbnN0IG5vcm1hbGl6ZWREaXNwYXRjaEdyb3VwID0gdGhpcy5wcm9ncmFtTWFuYWdlci5ub3JtYWxpemVEaXNwYXRjaEdyb3VwU2l6ZShkaXNwYXRjaEdyb3VwKTtcbiAgICBjb25zdCBpczFEaW1lbnNpb25EaXNwYXRjaCA9IG5vcm1hbGl6ZWREaXNwYXRjaEdyb3VwWzFdID09PSAxICYmIG5vcm1hbGl6ZWREaXNwYXRjaEdyb3VwWzJdID09PSAxO1xuICAgIC8vIGdldCBwcm9ncmFtIGluZm9cbiAgICBjb25zdCBrZXkgPSBnZXRQcm9ncmFtSW5mb1VuaXF1ZUtleShwcm9ncmFtLCBpbnB1dFRlbnNvclZpZXdzLCBpczFEaW1lbnNpb25EaXNwYXRjaCk7XG4gICAgbGV0IGFydGlmYWN0ID0gdGhpcy5wcm9ncmFtTWFuYWdlci5nZXRBcnRpZmFjdChrZXkpO1xuICAgIGlmICghYXJ0aWZhY3QpIHtcbiAgICAgIGFydGlmYWN0ID0gdGhpcy5wcm9ncmFtTWFuYWdlci5idWlsZChwcm9ncmFtLCBub3JtYWxpemVkRGlzcGF0Y2hHcm91cCk7XG4gICAgICB0aGlzLnByb2dyYW1NYW5hZ2VyLnNldEFydGlmYWN0KGtleSwgYXJ0aWZhY3QpO1xuICAgICAgTE9HX0RFQlVHKCdpbmZvJywgKCkgPT4gYFthcnRpZmFjdF0ga2V5OiAke2tleX0sIHByb2dyYW1OYW1lOiAke3Byb2dyYW0ubmFtZX1gKTtcbiAgICB9XG5cbiAgICAvLyB2YWxpZGF0ZSB1bmlmb3JtIHZhcmlhYmxlc1xuICAgIGlmIChwcm9ncmFtVW5pZm9ybXMgJiYgYXJ0aWZhY3QudW5pZm9ybVZhcmlhYmxlc0luZm8pIHtcbiAgICAgIGlmIChwcm9ncmFtVW5pZm9ybXMubGVuZ3RoICE9PSBhcnRpZmFjdC51bmlmb3JtVmFyaWFibGVzSW5mby5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBVbmlmb3JtIHZhcmlhYmxlcyBjb3VudCBtaXNtYXRjaDogZXhwZWN0ICR7YXJ0aWZhY3QudW5pZm9ybVZhcmlhYmxlc0luZm8ubGVuZ3RofSwgZ290ICR7XG4gICAgICAgICAgICBwcm9ncmFtVW5pZm9ybXMubGVuZ3RoXG4gICAgICAgICAgfSBpbiBwcm9ncmFtIFwiJHthcnRpZmFjdC5wcm9ncmFtSW5mby5uYW1lfVwiLmAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb2dyYW1Vbmlmb3Jtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCB1bmlmb3JtID0gcHJvZ3JhbVVuaWZvcm1zW2ldO1xuICAgICAgICBjb25zdCBhY3R1YWxUeXBlID0gdW5pZm9ybS50eXBlO1xuICAgICAgICBjb25zdCBhY3R1YWxMZW5ndGggPSB0eXBlb2YgdW5pZm9ybS5kYXRhID09PSAnbnVtYmVyJyA/IDEgOiB1bmlmb3JtLmRhdGEubGVuZ3RoO1xuICAgICAgICBjb25zdCBbdHlwZSwgbGVuZ3RoXSA9IGFydGlmYWN0LnVuaWZvcm1WYXJpYWJsZXNJbmZvW2ldO1xuICAgICAgICBpZiAoYWN0dWFsVHlwZSAhPT0gdHlwZSB8fCBhY3R1YWxMZW5ndGggIT09IGxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBVbmlmb3JtIHZhcmlhYmxlICR7aX0gbWlzbWF0Y2g6IGV4cGVjdCB0eXBlICR7dHlwZX0gd2l0aCBzaXplICR7bGVuZ3RofSwgZ290IHR5cGUgJHtcbiAgICAgICAgICAgICAgYWN0dWFsVHlwZVxuICAgICAgICAgICAgfSB3aXRoIHNpemUgJHthY3R1YWxMZW5ndGh9IGluIHByb2dyYW0gXCIke2FydGlmYWN0LnByb2dyYW1JbmZvLm5hbWV9XCIuYCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgTE9HX0RFQlVHKFxuICAgICAgJ2luZm8nLFxuICAgICAgKCkgPT5cbiAgICAgICAgYFtQcm9ncmFtTWFuYWdlcl0gcnVuIFwiJHtwcm9ncmFtLm5hbWV9XCIgKGtleT0ke2tleX0pIHdpdGggJHtub3JtYWxpemVkRGlzcGF0Y2hHcm91cFswXX14JHtcbiAgICAgICAgICBub3JtYWxpemVkRGlzcGF0Y2hHcm91cFsxXVxuICAgICAgICB9eCR7bm9ybWFsaXplZERpc3BhdGNoR3JvdXBbMl19YCxcbiAgICApO1xuXG4gICAgaWYgKHRoaXMucXVlcnlUeXBlICE9PSAnbm9uZScgfHwgdGhpcy5zZXNzaW9uU3RhdHVzID09PSAnY2FwdHVyaW5nJykge1xuICAgICAgY29uc3QgcGVuZGluZ0tlcm5lbEluZm86IFBlbmRpbmdLZXJuZWxJbmZvID0ge1xuICAgICAgICBrZXJuZWxJZDogdGhpcy5jdXJyZW50S2VybmVsSWQhLFxuICAgICAgICBwcm9ncmFtTmFtZTogYXJ0aWZhY3QucHJvZ3JhbUluZm8ubmFtZSxcbiAgICAgICAgaW5wdXRUZW5zb3JWaWV3cyxcbiAgICAgICAgb3V0cHV0VGVuc29yVmlld3MsXG4gICAgICB9O1xuICAgICAgdGhpcy5wZW5kaW5nS2VybmVscy5wdXNoKHBlbmRpbmdLZXJuZWxJbmZvKTtcblxuICAgICAgaWYgKHRoaXMuc2Vzc2lvblN0YXR1cyA9PT0gJ2NhcHR1cmluZycpIHtcbiAgICAgICAgY29uc3Qgc2Vzc2lvblBlbmRpbmdLZXJuZWxzID0gdGhpcy5jYXB0dXJlZFBlbmRpbmdLZXJuZWxzLmdldCh0aGlzLmN1cnJlbnRTZXNzaW9uSWQhKTtcbiAgICAgICAgc2Vzc2lvblBlbmRpbmdLZXJuZWxzIS5wdXNoKHBlbmRpbmdLZXJuZWxJbmZvKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnByb2dyYW1NYW5hZ2VyLnJ1bihhcnRpZmFjdCwgaW5wdXREYXRhcywgb3V0cHV0RGF0YXMsIG5vcm1hbGl6ZWREaXNwYXRjaEdyb3VwLCB1bmlmb3JtQnVmZmVyQmluZGluZyk7XG5cbiAgICBUUkFDRV9GVU5DX0VORChwcm9ncmFtLm5hbWUpO1xuICAgIHJldHVybiBvdXRwdXRUZW5zb3JWaWV3cztcbiAgfVxuXG4gIHVwbG9hZChncHVEYXRhSWQ6IG51bWJlciwgZGF0YTogVWludDhBcnJheSk6IHZvaWQge1xuICAgIHRoaXMuZ3B1RGF0YU1hbmFnZXIudXBsb2FkKGdwdURhdGFJZCwgZGF0YSk7XG4gIH1cblxuICBtZW1jcHkoc3JjOiBudW1iZXIsIGRzdDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5ncHVEYXRhTWFuYWdlci5tZW1jcHkoc3JjLCBkc3QpO1xuICB9XG5cbiAgYXN5bmMgZG93bmxvYWQoZ3B1RGF0YUlkOiBudW1iZXIsIGdldFRhcmdldEJ1ZmZlcjogKCkgPT4gVWludDhBcnJheSk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIHRoZSB1bmRlcmx5aW5nIGJ1ZmZlciBtYXkgYmUgY2hhbmdlZCBhZnRlciB0aGUgYXN5bmMgZnVuY3Rpb24gaXMgY2FsbGVkLiBzbyB3ZSB1c2UgYSBnZXR0ZXIgZnVuY3Rpb24gdG8gbWFrZSBzdXJlXG4gICAgLy8gdGhlIGJ1ZmZlciBpcyB1cC10by1kYXRlLlxuICAgIGF3YWl0IHRoaXMuZ3B1RGF0YU1hbmFnZXIuZG93bmxvYWQoZ3B1RGF0YUlkLCBnZXRUYXJnZXRCdWZmZXIpO1xuICB9XG5cbiAgYWxsb2Moc2l6ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5ncHVEYXRhTWFuYWdlci5jcmVhdGUoc2l6ZSkuaWQ7XG4gIH1cblxuICBmcmVlKHB0cjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5ncHVEYXRhTWFuYWdlci5yZWxlYXNlKHB0cik7XG4gIH1cblxuICBjcmVhdGVLZXJuZWwoa2VybmVsVHlwZTogc3RyaW5nLCBrZXJuZWxJZDogbnVtYmVyLCBhdHRyaWJ1dGU6IHVua25vd24sIGtlcm5lbE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IG9wID0gV0VCR1BVX09QX1JFU09MVkVfUlVMRVMuZ2V0KGtlcm5lbFR5cGUpO1xuICAgIGlmICghb3ApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihga2VybmVsIG5vdCBpbXBsZW1lbnRlZDogJHtrZXJuZWxUeXBlfWApO1xuICAgIH1cblxuICAgIGNvbnN0IGtlcm5lbEluZm86IEtlcm5lbEluZm8gPSB7XG4gICAgICBrZXJuZWxUeXBlLFxuICAgICAga2VybmVsTmFtZSxcbiAgICAgIGtlcm5lbEVudHJ5OiBvcFswXSxcbiAgICAgIGF0dHJpYnV0ZXM6IFtvcFsxXSwgYXR0cmlidXRlXSxcbiAgICB9O1xuICAgIHRoaXMua2VybmVscy5zZXQoa2VybmVsSWQsIGtlcm5lbEluZm8pO1xuICB9XG5cbiAgcmVsZWFzZUtlcm5lbChrZXJuZWxJZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgcGVyc2lzdGVudERhdGEgPSB0aGlzLmtlcm5lbFBlcnNpc3RlbnREYXRhLmdldChrZXJuZWxJZCk7XG4gICAgaWYgKHBlcnNpc3RlbnREYXRhKSB7XG4gICAgICBmb3IgKGNvbnN0IGRhdGEgb2YgcGVyc2lzdGVudERhdGEpIHtcbiAgICAgICAgdGhpcy5ncHVEYXRhTWFuYWdlci5yZWxlYXNlKGRhdGEuaWQpO1xuICAgICAgfVxuICAgICAgdGhpcy5rZXJuZWxQZXJzaXN0ZW50RGF0YS5kZWxldGUoa2VybmVsSWQpO1xuICAgIH1cblxuICAgIHRoaXMua2VybmVsQ3VzdG9tRGF0YS5kZWxldGUoa2VybmVsSWQpO1xuICAgIHRoaXMua2VybmVscy5kZWxldGUoa2VybmVsSWQpO1xuICB9XG5cbiAgY29tcHV0ZUtlcm5lbChrZXJuZWxJZDogbnVtYmVyLCBjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgZXJyb3JzOiBBcnJheTxQcm9taXNlPHN0cmluZyB8IG51bGw+Pik6IG51bWJlciB7XG4gICAgY29uc3Qga2VybmVsID0gdGhpcy5rZXJuZWxzLmdldChrZXJuZWxJZCk7XG4gICAgaWYgKCFrZXJuZWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihga2VybmVsIG5vdCBjcmVhdGVkOiAke2tlcm5lbElkfWApO1xuICAgIH1cbiAgICBjb25zdCBrZXJuZWxUeXBlID0ga2VybmVsLmtlcm5lbFR5cGU7XG4gICAgY29uc3Qga2VybmVsTmFtZSA9IGtlcm5lbC5rZXJuZWxOYW1lO1xuICAgIGNvbnN0IGtlcm5lbEVudHJ5ID0ga2VybmVsLmtlcm5lbEVudHJ5O1xuICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBrZXJuZWwuYXR0cmlidXRlcztcbiAgICBpZiAodGhpcy5jdXJyZW50S2VybmVsSWQgIT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihga2VybmVsIFwiWyR7a2VybmVsVHlwZX1dICR7a2VybmVsTmFtZX1cIiBpcyBub3QgYWxsb3dlZCB0byBiZSBjYWxsZWQgcmVjdXJzaXZlbHlgKTtcbiAgICB9XG4gICAgdGhpcy5jdXJyZW50S2VybmVsSWQgPSBrZXJuZWxJZDtcblxuICAgIC8vIHBhcnNlIGF0dHJpYnV0ZXMgaWYgbmVjZXNzYXJ5XG4gICAgaWYgKGF0dHJpYnV0ZXNbMF0pIHtcbiAgICAgIGF0dHJpYnV0ZXNbMV0gPSBhdHRyaWJ1dGVzWzBdKGF0dHJpYnV0ZXNbMV0pO1xuICAgICAgYXR0cmlidXRlc1swXSA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBMT0dfREVCVUcoJ2luZm8nLCAoKSA9PiBgW1dlYkdQVV0gU3RhcnQgdG8gcnVuIGtlcm5lbCBcIlske2tlcm5lbFR5cGV9XSAke2tlcm5lbE5hbWV9XCIuLi5gKTtcblxuICAgIGNvbnN0IHVzZUVycm9yU2NvcGUgPSB0aGlzLmVudi5kZWJ1ZztcblxuICAgIHRoaXMudGVtcG9yYXJ5RGF0YSA9IFtdO1xuICAgIHRyeSB7XG4gICAgICBpZiAodXNlRXJyb3JTY29wZSkge1xuICAgICAgICB0aGlzLmRldmljZS5wdXNoRXJyb3JTY29wZSgndmFsaWRhdGlvbicpO1xuICAgICAgfVxuXG4gICAgICBrZXJuZWxFbnRyeShjb250ZXh0LCBhdHRyaWJ1dGVzWzFdKTtcbiAgICAgIHJldHVybiAwOyAvLyBPUlRfT0tcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBlcnJvcnMucHVzaChQcm9taXNlLnJlc29sdmUoYFtXZWJHUFVdIEtlcm5lbCBcIlske2tlcm5lbFR5cGV9XSAke2tlcm5lbE5hbWV9XCIgZmFpbGVkLiAke2V9YCkpO1xuICAgICAgcmV0dXJuIDE7IC8vIE9SVF9GQUlMXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmICh1c2VFcnJvclNjb3BlKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICAgIHRoaXMuZGV2aWNlXG4gICAgICAgICAgICAucG9wRXJyb3JTY29wZSgpXG4gICAgICAgICAgICAudGhlbigoZXJyKSA9PlxuICAgICAgICAgICAgICBlcnIgPyBgR1BVIHZhbGlkYXRpb24gZXJyb3IgZm9yIGtlcm5lbCBcIlske2tlcm5lbFR5cGV9XSAke2tlcm5lbE5hbWV9XCI6ICR7ZXJyLm1lc3NhZ2V9YCA6IG51bGwsXG4gICAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGRhdGEgb2YgdGhpcy50ZW1wb3JhcnlEYXRhKSB7XG4gICAgICAgIHRoaXMuZ3B1RGF0YU1hbmFnZXIucmVsZWFzZShkYXRhLmlkKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudGVtcG9yYXJ5RGF0YSA9IFtdO1xuICAgICAgdGhpcy5jdXJyZW50S2VybmVsSWQgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8vICNyZWdpb24gZXh0ZXJuYWwgYnVmZmVyXG4gIHJlZ2lzdGVyQnVmZmVyKHNlc3Npb25JZDogbnVtYmVyLCBpbmRleDogbnVtYmVyLCBidWZmZXI6IEdQVUJ1ZmZlciwgc2l6ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgc2Vzc2lvbklucHV0T3V0cHV0TWFwcGluZyA9IHRoaXMuc2Vzc2lvbkV4dGVybmFsRGF0YU1hcHBpbmcuZ2V0KHNlc3Npb25JZCk7XG4gICAgaWYgKCFzZXNzaW9uSW5wdXRPdXRwdXRNYXBwaW5nKSB7XG4gICAgICBzZXNzaW9uSW5wdXRPdXRwdXRNYXBwaW5nID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy5zZXNzaW9uRXh0ZXJuYWxEYXRhTWFwcGluZy5zZXQoc2Vzc2lvbklkLCBzZXNzaW9uSW5wdXRPdXRwdXRNYXBwaW5nKTtcbiAgICB9XG5cbiAgICAvLyB0aGUgYnVmZmVyIG1heSBiZSB1c2VyIGNyZWF0ZWQsIG9yIG1hbmFnZWQgYnkgR1BVIGRhdGEgbWFuYWdlci5cbiAgICAvLyBUaGUgR1BVIGRhdGEgbWFuYWdlciB3aWxsIG5vdCBtYW5hZ2UgdGhlc2UgYnVmZmVycy4gd2UgcmVnaXN0ZXIgdGhlbSBhcyBleHRlcm5hbCBidWZmZXJzLlxuICAgIC8vXG4gICAgLy8gVGhlIG1hcCBgc2Vzc2lvbklucHV0T3V0cHV0TWFwcGluZ2AgaXMgdXNlZCB0byBzdG9yZSB0aGUgZGF0YSBJRCBhbmQgYnVmZmVyIGZvciBlYWNoIGlucHV0L291dHB1dC4gT25jZSBhXG4gICAgLy8gc3BlY2lmaWMgaW5wdXQvb3V0cHV0IGlzIHJlZ2lzdGVyZWQsIHRoZSBkYXRhIElEIHdpbGwgbm90IGNoYW5nZS5cbiAgICBjb25zdCBwcmV2aW91c0J1ZmZlciA9IHNlc3Npb25JbnB1dE91dHB1dE1hcHBpbmcuZ2V0KGluZGV4KTtcbiAgICBjb25zdCBpZCA9IHRoaXMuZ3B1RGF0YU1hbmFnZXIucmVnaXN0ZXJFeHRlcm5hbEJ1ZmZlcihidWZmZXIsIHNpemUsIHByZXZpb3VzQnVmZmVyKTtcbiAgICBzZXNzaW9uSW5wdXRPdXRwdXRNYXBwaW5nLnNldChpbmRleCwgW2lkLCBidWZmZXJdKTtcbiAgICByZXR1cm4gaWQ7XG4gIH1cbiAgdW5yZWdpc3RlckJ1ZmZlcnMoc2Vzc2lvbklkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBzZXNzaW9uSW5wdXRPdXRwdXRNYXBwaW5nID0gdGhpcy5zZXNzaW9uRXh0ZXJuYWxEYXRhTWFwcGluZy5nZXQoc2Vzc2lvbklkKTtcbiAgICBpZiAoc2Vzc2lvbklucHV0T3V0cHV0TWFwcGluZykge1xuICAgICAgc2Vzc2lvbklucHV0T3V0cHV0TWFwcGluZy5mb3JFYWNoKChidWZmZXJJbmZvKSA9PiB0aGlzLmdwdURhdGFNYW5hZ2VyLnVucmVnaXN0ZXJFeHRlcm5hbEJ1ZmZlcihidWZmZXJJbmZvWzBdKSk7XG4gICAgICB0aGlzLnNlc3Npb25FeHRlcm5hbERhdGFNYXBwaW5nLmRlbGV0ZShzZXNzaW9uSWQpO1xuICAgIH1cbiAgfVxuICBnZXRCdWZmZXIoZ3B1RGF0YUlkOiBudW1iZXIpOiBHUFVCdWZmZXIge1xuICAgIGNvbnN0IGdwdURhdGEgPSB0aGlzLmdwdURhdGFNYW5hZ2VyLmdldChncHVEYXRhSWQpO1xuICAgIGlmICghZ3B1RGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBubyBHUFUgZGF0YSBmb3IgYnVmZmVyOiAke2dwdURhdGFJZH1gKTtcbiAgICB9XG4gICAgcmV0dXJuIGdwdURhdGEuYnVmZmVyO1xuICB9XG4gIGNyZWF0ZURvd25sb2FkZXIoXG4gICAgZ3B1QnVmZmVyOiBHUFVCdWZmZXIsXG4gICAgc2l6ZTogbnVtYmVyLFxuICAgIHR5cGU6IFRlbnNvci5HcHVCdWZmZXJEYXRhVHlwZXMsXG4gICk6ICgpID0+IFByb21pc2U8VGVuc29yLkRhdGFUeXBlPiB7XG4gICAgcmV0dXJuIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBkb3dubG9hZEdwdURhdGEodGhpcywgZ3B1QnVmZmVyLCBzaXplKTtcbiAgICAgIHJldHVybiBjcmVhdGVWaWV3KGRhdGEuYnVmZmVyLCB0eXBlKTtcbiAgICB9O1xuICB9XG4gIC8vICNlbmRyZWdpb25cbiAgd3JpdGVUaW1lc3RhbXAoaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLnF1ZXJ5VHlwZSAhPT0gJ2luc2lkZS1wYXNzZXMnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAodGhpcy5jb21wdXRlUGFzc0VuY29kZXIgYXMgYW55KS53cml0ZVRpbWVzdGFtcCh0aGlzLnF1ZXJ5U2V0LCBpbmRleCk7XG4gIH1cbiAgc2V0UXVlcnlUeXBlKCk6IHZvaWQge1xuICAgIHRoaXMucXVlcnlUeXBlID0gJ25vbmUnO1xuICAgIGlmIChcbiAgICAgIHRoaXMuZW52LndlYmdwdS5wcm9maWxpbmc/Lm1vZGUgPT09ICdkZWZhdWx0JyB8fFxuICAgICAgKHR5cGVvZiB0aGlzLmVudi50cmFjZSA9PT0gJ3VuZGVmaW5lZCcgPyB0aGlzLmVudi53YXNtLnRyYWNlIDogdGhpcy5lbnYudHJhY2UpXG4gICAgKSB7XG4gICAgICBpZiAodGhpcy5kZXZpY2UuZmVhdHVyZXMuaGFzKCdjaHJvbWl1bS1leHBlcmltZW50YWwtdGltZXN0YW1wLXF1ZXJ5LWluc2lkZS1wYXNzZXMnKSkge1xuICAgICAgICB0aGlzLnF1ZXJ5VHlwZSA9ICdpbnNpZGUtcGFzc2VzJztcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5kZXZpY2UuZmVhdHVyZXMuaGFzKCd0aW1lc3RhbXAtcXVlcnknKSkge1xuICAgICAgICB0aGlzLnF1ZXJ5VHlwZSA9ICdhdC1wYXNzZXMnO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5xdWVyeVR5cGUgIT09ICdub25lJyAmJiB0eXBlb2YgdGhpcy5xdWVyeVNldCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhpcy5xdWVyeVNldCA9IHRoaXMuZGV2aWNlLmNyZWF0ZVF1ZXJ5U2V0KHtcbiAgICAgICAgICB0eXBlOiAndGltZXN0YW1wJyxcbiAgICAgICAgICBjb3VudDogdGhpcy5tYXhEaXNwYXRjaE51bWJlciAqIDIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnF1ZXJ5UmVzb2x2ZUJ1ZmZlciA9IHRoaXMuZGV2aWNlLmNyZWF0ZUJ1ZmZlcihcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYml0d2lzZVxuICAgICAgICAgIHsgc2l6ZTogdGhpcy5tYXhEaXNwYXRjaE51bWJlciAqIDIgKiA4LCB1c2FnZTogR1BVQnVmZmVyVXNhZ2UuQ09QWV9TUkMgfCBHUFVCdWZmZXJVc2FnZS5RVUVSWV9SRVNPTFZFIH0sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY2FwdHVyZUJlZ2luKCk6IHZvaWQge1xuICAgIExPR19ERUJVRygnaW5mbycsICdjYXB0dXJlQmVnaW4nKTtcbiAgICBpZiAoIXRoaXMuY2FwdHVyZWRDb21tYW5kTGlzdC5nZXQodGhpcy5jdXJyZW50U2Vzc2lvbklkISkpIHtcbiAgICAgIHRoaXMuY2FwdHVyZWRDb21tYW5kTGlzdC5zZXQodGhpcy5jdXJyZW50U2Vzc2lvbklkISwgW10pO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuY2FwdHVyZWRQZW5kaW5nS2VybmVscy5nZXQodGhpcy5jdXJyZW50U2Vzc2lvbklkISkpIHtcbiAgICAgIHRoaXMuY2FwdHVyZWRQZW5kaW5nS2VybmVscy5zZXQodGhpcy5jdXJyZW50U2Vzc2lvbklkISwgW10pO1xuICAgIH1cbiAgICAvLyBmbHVzaCB0aGUgbGVmdCBjb21tYW5kcyBiZWZvcmUgd2UgY2hhbmdlIHRoZSBzdGF0dXMuXG4gICAgdGhpcy5mbHVzaCgpO1xuICAgIHRoaXMuc2Vzc2lvblN0YXR1cyA9ICdjYXB0dXJpbmcnO1xuICB9XG4gIGNhcHR1cmVFbmQoKTogdm9pZCB7XG4gICAgTE9HX0RFQlVHKCdpbmZvJywgJ2NhcHR1cmVFbmQnKTtcbiAgICAvLyBmbHVzaCB0aGUgbGVmdCBjb21tYW5kcyBiZWZvcmUgd2UgY2hhbmdlIHRoZSBzdGF0dXMuXG4gICAgdGhpcy5mbHVzaCgpO1xuICAgIHRoaXMuc2Vzc2lvblN0YXR1cyA9ICdkZWZhdWx0JztcbiAgfVxuICByZXBsYXkoKTogdm9pZCB7XG4gICAgTE9HX0RFQlVHKCdpbmZvJywgJ3JlcGxheScpO1xuICAgIHRoaXMuc2Vzc2lvblN0YXR1cyA9ICdyZXBsYXlpbmcnO1xuICAgIGNvbnN0IHNlc3Npb25Db21tYW5kTGlzdCA9IHRoaXMuY2FwdHVyZWRDb21tYW5kTGlzdC5nZXQodGhpcy5jdXJyZW50U2Vzc2lvbklkISk7XG4gICAgY29uc3Qgc2Vzc2lvblBlbmRpbmdLZXJuZWxzID0gdGhpcy5jYXB0dXJlZFBlbmRpbmdLZXJuZWxzLmdldCh0aGlzLmN1cnJlbnRTZXNzaW9uSWQhKTtcbiAgICBjb25zdCBsZW5ndGggPSBzZXNzaW9uQ29tbWFuZExpc3QhLmxlbmd0aDtcbiAgICB0aGlzLnBlbmRpbmdLZXJuZWxzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgY29tcHV0ZVBhc3NFbmNvZGVyID0gdGhpcy5nZXRDb21wdXRlUGFzc0VuY29kZXIoKTtcbiAgICAgIGNvbnN0IGNvbW1hbmQgPSBzZXNzaW9uQ29tbWFuZExpc3QhW2ldO1xuICAgICAgdGhpcy53cml0ZVRpbWVzdGFtcCh0aGlzLnBlbmRpbmdEaXNwYXRjaE51bWJlciAqIDIpO1xuICAgICAgY29tcHV0ZVBhc3NFbmNvZGVyLnNldFBpcGVsaW5lKGNvbW1hbmQuY29tcHV0ZVBpcGVsaW5lKTtcbiAgICAgIGNvbXB1dGVQYXNzRW5jb2Rlci5zZXRCaW5kR3JvdXAoMCwgY29tbWFuZC5iaW5kR3JvdXApO1xuICAgICAgY29tcHV0ZVBhc3NFbmNvZGVyLmRpc3BhdGNoV29ya2dyb3VwcyguLi5jb21tYW5kLmRpc3BhdGNoR3JvdXApO1xuICAgICAgdGhpcy53cml0ZVRpbWVzdGFtcCh0aGlzLnBlbmRpbmdEaXNwYXRjaE51bWJlciAqIDIgKyAxKTtcbiAgICAgIHRoaXMucGVuZGluZ0Rpc3BhdGNoTnVtYmVyKys7XG4gICAgICBpZiAodGhpcy5xdWVyeVR5cGUgIT09ICdub25lJykge1xuICAgICAgICB0aGlzLnBlbmRpbmdLZXJuZWxzLnB1c2goc2Vzc2lvblBlbmRpbmdLZXJuZWxzIVtpXSk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5wZW5kaW5nRGlzcGF0Y2hOdW1iZXIgPj0gdGhpcy5tYXhEaXNwYXRjaE51bWJlciB8fCB0aGlzLnF1ZXJ5VHlwZSA9PT0gJ2F0LXBhc3NlcycpIHtcbiAgICAgICAgdGhpcy5lbmRDb21wdXRlUGFzcygpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMucGVuZGluZ0Rpc3BhdGNoTnVtYmVyID49IHRoaXMubWF4RGlzcGF0Y2hOdW1iZXIpIHtcbiAgICAgICAgdGhpcy5mbHVzaCgpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBmbHVzaCB0aGUgbGVmdCBjb21tYW5kcyBiZWZvcmUgd2UgY2hhbmdlIHRoZSBzdGF0dXMuXG4gICAgdGhpcy5mbHVzaCgpO1xuICAgIHRoaXMuc2Vzc2lvblN0YXR1cyA9ICdkZWZhdWx0JztcbiAgfVxuXG4gIG9uQ3JlYXRlU2Vzc2lvbigpOiB2b2lkIHtcbiAgICB0aGlzLmdwdURhdGFNYW5hZ2VyLm9uQ3JlYXRlU2Vzc2lvbigpO1xuICB9XG5cbiAgb25SZWxlYXNlU2Vzc2lvbihzZXNzaW9uSWQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMudW5yZWdpc3RlckJ1ZmZlcnMoc2Vzc2lvbklkKTtcbiAgICBpZiAodGhpcy5jYXB0dXJlZENvbW1hbmRMaXN0LmhhcyhzZXNzaW9uSWQpKSB7XG4gICAgICB0aGlzLmNhcHR1cmVkQ29tbWFuZExpc3QuZGVsZXRlKHNlc3Npb25JZCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNhcHR1cmVkUGVuZGluZ0tlcm5lbHMuaGFzKHNlc3Npb25JZCkpIHtcbiAgICAgIHRoaXMuY2FwdHVyZWRQZW5kaW5nS2VybmVscy5kZWxldGUoc2Vzc2lvbklkKTtcbiAgICB9XG4gICAgdGhpcy5ncHVEYXRhTWFuYWdlci5vblJlbGVhc2VTZXNzaW9uKHNlc3Npb25JZCk7XG4gIH1cblxuICBvblJ1blN0YXJ0KHNlc3Npb25JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5jdXJyZW50U2Vzc2lvbklkID0gc2Vzc2lvbklkO1xuICAgIHRoaXMuc2V0UXVlcnlUeXBlKCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHR5cGUgeyBFbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBjYWxjdWxhdGVUZW5zb3JTaXplSW5CeXRlcywgRGF0YVR5cGUgfSBmcm9tICcuLi93YXNtLWNvbW1vbic7XG5cbmltcG9ydCB0eXBlIHsgT3J0V2FzbU1vZHVsZSB9IGZyb20gJy4uL3dhc20tdHlwZXMnO1xuXG5pbXBvcnQgdHlwZSB7IFdlYkdwdUJhY2tlbmQgfSBmcm9tICcuL2JhY2tlbmQtd2ViZ3B1JztcbmltcG9ydCB7IExPR19ERUJVRyB9IGZyb20gJy4vbG9nJztcbmltcG9ydCB0eXBlIHsgVGVuc29yVmlldyB9IGZyb20gJy4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi91dGlsJztcbmltcG9ydCB0eXBlIHsgQWRhcHRlckluZm8sIENvbXB1dGVDb250ZXh0LCBDb21wdXRlQ29udGV4dElucHV0c091dHB1dHNNYXBwaW5nLCBQcm9ncmFtSW5mbyB9IGZyb20gJy4vd2ViZ3B1L3R5cGVzJztcbmltcG9ydCB7IFdlYk5OQmFja2VuZCB9IGZyb20gJy4vYmFja2VuZC13ZWJubic7XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLWJpdHdpc2UgKi9cblxuY2xhc3MgVGVuc29yVmlld0ltcGwgaW1wbGVtZW50cyBUZW5zb3JWaWV3IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBtb2R1bGU6IE9ydFdhc21Nb2R1bGUsXG4gICAgcHVibGljIHJlYWRvbmx5IGRhdGFUeXBlOiBudW1iZXIsXG4gICAgcHVibGljIHJlYWRvbmx5IGRhdGE6IG51bWJlcixcbiAgICBwdWJsaWMgcmVhZG9ubHkgZGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICkge31cblxuICBnZXRGbG9hdDMyQXJyYXkoKTogRmxvYXQzMkFycmF5IHtcbiAgICBpZiAodGhpcy5kYXRhVHlwZSAhPT0gRGF0YVR5cGUuZmxvYXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBkYXRhIHR5cGUnKTtcbiAgICB9XG4gICAgY29uc3QgZWxlbWVudENvdW50ID0gU2hhcGVVdGlsLnNpemUodGhpcy5kaW1zKTtcbiAgICByZXR1cm4gZWxlbWVudENvdW50ID09PSAwXG4gICAgICA/IG5ldyBGbG9hdDMyQXJyYXkoKVxuICAgICAgOiBuZXcgRmxvYXQzMkFycmF5KHRoaXMubW9kdWxlLkhFQVA4LmJ1ZmZlciwgdGhpcy5kYXRhLCBlbGVtZW50Q291bnQpO1xuICB9XG5cbiAgZ2V0QmlnSW50NjRBcnJheSgpOiBCaWdJbnQ2NEFycmF5IHtcbiAgICBpZiAodGhpcy5kYXRhVHlwZSAhPT0gRGF0YVR5cGUuaW50NjQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBkYXRhIHR5cGUnKTtcbiAgICB9XG4gICAgY29uc3QgZWxlbWVudENvdW50ID0gU2hhcGVVdGlsLnNpemUodGhpcy5kaW1zKTtcbiAgICByZXR1cm4gZWxlbWVudENvdW50ID09PSAwXG4gICAgICA/IG5ldyBCaWdJbnQ2NEFycmF5KClcbiAgICAgIDogbmV3IEJpZ0ludDY0QXJyYXkodGhpcy5tb2R1bGUuSEVBUDguYnVmZmVyLCB0aGlzLmRhdGEsIGVsZW1lbnRDb3VudCk7XG4gIH1cblxuICBnZXRJbnQzMkFycmF5KCk6IEludDMyQXJyYXkge1xuICAgIGlmICh0aGlzLmRhdGFUeXBlICE9PSBEYXRhVHlwZS5pbnQzMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRhdGEgdHlwZScpO1xuICAgIH1cbiAgICBjb25zdCBlbGVtZW50Q291bnQgPSBTaGFwZVV0aWwuc2l6ZSh0aGlzLmRpbXMpO1xuICAgIHJldHVybiBlbGVtZW50Q291bnQgPT09IDAgPyBuZXcgSW50MzJBcnJheSgpIDogbmV3IEludDMyQXJyYXkodGhpcy5tb2R1bGUuSEVBUDguYnVmZmVyLCB0aGlzLmRhdGEsIGVsZW1lbnRDb3VudCk7XG4gIH1cblxuICBnZXRVaW50MTZBcnJheSgpOiBVaW50MTZBcnJheSB7XG4gICAgaWYgKHRoaXMuZGF0YVR5cGUgIT09IERhdGFUeXBlLmZsb2F0MTYgJiYgdGhpcy5kYXRhVHlwZSAhPT0gRGF0YVR5cGUudWludDE2KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZGF0YSB0eXBlJyk7XG4gICAgfVxuICAgIGNvbnN0IGVsZW1lbnRDb3VudCA9IFNoYXBlVXRpbC5zaXplKHRoaXMuZGltcyk7XG4gICAgcmV0dXJuIGVsZW1lbnRDb3VudCA9PT0gMCA/IG5ldyBVaW50MTZBcnJheSgpIDogbmV3IFVpbnQxNkFycmF5KHRoaXMubW9kdWxlLkhFQVA4LmJ1ZmZlciwgdGhpcy5kYXRhLCBlbGVtZW50Q291bnQpO1xuICB9XG5cbiAgcmVzaGFwZShuZXdEaW1zOiByZWFkb25seSBudW1iZXJbXSk6IFRlbnNvclZpZXcge1xuICAgIGlmIChTaGFwZVV0aWwuc2l6ZShuZXdEaW1zKSAhPT0gU2hhcGVVdGlsLnNpemUodGhpcy5kaW1zKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG5ldyBzaGFwZScpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFRlbnNvclZpZXdJbXBsKHRoaXMubW9kdWxlLCB0aGlzLmRhdGFUeXBlLCB0aGlzLmRhdGEsIG5ld0RpbXMpO1xuICB9XG59XG5cbmNsYXNzIENvbXB1dGVDb250ZXh0SW1wbCBpbXBsZW1lbnRzIENvbXB1dGVDb250ZXh0IHtcbiAgcmVhZG9ubHkgYWRhcHRlckluZm86IEFkYXB0ZXJJbmZvO1xuICByZWFkb25seSBvcEtlcm5lbENvbnRleHQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W107XG4gIHJlYWRvbmx5IG91dHB1dENvdW50OiBudW1iZXI7XG4gIGdldCBrZXJuZWxDdXN0b21EYXRhKCk6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9IHtcbiAgICByZXR1cm4gdGhpcy5iYWNrZW5kLmN1cnJlbnRLZXJuZWxDdXN0b21EYXRhO1xuICB9XG4gIGdldCBjdXN0b21EYXRhQnVmZmVyKCk6IFVpbnQ4QXJyYXkge1xuICAgIHJldHVybiB0aGlzLm1vZHVsZS5IRUFQVTguc3ViYXJyYXkodGhpcy5jdXN0b21EYXRhT2Zmc2V0LCB0aGlzLmN1c3RvbURhdGFPZmZzZXQgKyB0aGlzLmN1c3RvbURhdGFTaXplKTtcbiAgfVxuICBwcml2YXRlIGN1c3RvbURhdGFPZmZzZXQgPSAwO1xuICBwcml2YXRlIGN1c3RvbURhdGFTaXplID0gMDtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBtb2R1bGU6IE9ydFdhc21Nb2R1bGUsXG4gICAgcHJpdmF0ZSBiYWNrZW5kOiBXZWJHcHVCYWNrZW5kLFxuICAgIGNvbnRleHREYXRhT2Zmc2V0OiBudW1iZXIsXG4gICkge1xuICAgIHRoaXMuYWRhcHRlckluZm8gPSBiYWNrZW5kLmFkYXB0ZXJJbmZvO1xuXG4gICAgLy8gZXh0cmFjdCBjb250ZXh0IGRhdGFcbiAgICBjb25zdCBwdHJTaXplID0gbW9kdWxlLlBUUl9TSVpFO1xuICAgIGxldCBkYXRhSW5kZXggPSBjb250ZXh0RGF0YU9mZnNldCAvIG1vZHVsZS5QVFJfU0laRTtcbiAgICBjb25zdCB0eXBlID0gcHRyU2l6ZSA9PT0gNCA/ICdpMzInIDogJ2k2NCc7XG4gICAgdGhpcy5vcEtlcm5lbENvbnRleHQgPSBOdW1iZXIobW9kdWxlLmdldFZhbHVlKHB0clNpemUgKiBkYXRhSW5kZXgrKywgdHlwZSkpO1xuICAgIGNvbnN0IGlucHV0Q291bnQgPSBOdW1iZXIobW9kdWxlLmdldFZhbHVlKHB0clNpemUgKiBkYXRhSW5kZXgrKywgdHlwZSkpO1xuICAgIHRoaXMub3V0cHV0Q291bnQgPSBOdW1iZXIobW9kdWxlLmdldFZhbHVlKHB0clNpemUgKiBkYXRhSW5kZXgrKywgdHlwZSkpO1xuICAgIHRoaXMuY3VzdG9tRGF0YU9mZnNldCA9IE51bWJlcihtb2R1bGUuZ2V0VmFsdWUocHRyU2l6ZSAqIGRhdGFJbmRleCsrLCAnKicpKTtcbiAgICB0aGlzLmN1c3RvbURhdGFTaXplID0gTnVtYmVyKG1vZHVsZS5nZXRWYWx1ZShwdHJTaXplICogZGF0YUluZGV4KyssIHR5cGUpKTtcblxuICAgIGNvbnN0IGlucHV0czogVGVuc29yVmlld1tdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dENvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IGRhdGFUeXBlID0gTnVtYmVyKG1vZHVsZS5nZXRWYWx1ZShwdHJTaXplICogZGF0YUluZGV4KyssIHR5cGUpKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBOdW1iZXIobW9kdWxlLmdldFZhbHVlKHB0clNpemUgKiBkYXRhSW5kZXgrKywgJyonKSk7XG4gICAgICBjb25zdCBkaW0gPSBOdW1iZXIobW9kdWxlLmdldFZhbHVlKHB0clNpemUgKiBkYXRhSW5kZXgrKywgdHlwZSkpO1xuICAgICAgY29uc3QgZGltczogbnVtYmVyW10gPSBbXTtcbiAgICAgIGZvciAobGV0IGQgPSAwOyBkIDwgZGltOyBkKyspIHtcbiAgICAgICAgZGltcy5wdXNoKE51bWJlcihtb2R1bGUuZ2V0VmFsdWUocHRyU2l6ZSAqIGRhdGFJbmRleCsrLCB0eXBlKSkpO1xuICAgICAgfVxuICAgICAgaW5wdXRzLnB1c2gobmV3IFRlbnNvclZpZXdJbXBsKG1vZHVsZSwgZGF0YVR5cGUsIGRhdGEsIGRpbXMpKTtcbiAgICB9XG4gICAgdGhpcy5pbnB1dHMgPSBpbnB1dHM7XG4gIH1cblxuICBjb21wdXRlKHByb2dyYW06IFByb2dyYW1JbmZvLCBpbnB1dHNPdXRwdXRzTWFwcGluZz86IENvbXB1dGVDb250ZXh0SW5wdXRzT3V0cHV0c01hcHBpbmcpOiBUZW5zb3JWaWV3W10ge1xuICAgIC8vIHByZXBhcmUgaW5wdXRzLiBpbnB1dHMgc2hvdWxkIGFsd2F5cyBiZSB2YWxpZCBkYXRhLlxuICAgIGNvbnN0IG1hcHBlZElucHV0cyA9XG4gICAgICBpbnB1dHNPdXRwdXRzTWFwcGluZz8uaW5wdXRzPy5tYXAoKGkpID0+ICh0eXBlb2YgaSA9PT0gJ251bWJlcicgPyB0aGlzLmlucHV0c1tpXSA6IGkpKSA/PyB0aGlzLmlucHV0cztcbiAgICAvLyBwcmVwYXJlIG91dHB1dHMuXG4gICAgY29uc3Qgb3V0cHV0SW5kaWNlcyA9IGlucHV0c091dHB1dHNNYXBwaW5nPy5vdXRwdXRzID8/IFtdO1xuICAgIGNvbnN0IGNyZWF0ZUtlcm5lbE91dHB1dCA9IChpbmRleDogbnVtYmVyLCBkYXRhVHlwZTogbnVtYmVyLCBkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IFRlbnNvclZpZXcgPT5cbiAgICAgIG5ldyBUZW5zb3JWaWV3SW1wbCh0aGlzLm1vZHVsZSwgZGF0YVR5cGUsIHRoaXMub3V0cHV0KGluZGV4LCBkaW1zKSwgZGltcyk7XG4gICAgY29uc3QgY3JlYXRlVGVtcG9yYXJ5T3V0cHV0ID0gKGRhdGFUeXBlOiBudW1iZXIsIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yVmlldyA9PiB7XG4gICAgICBjb25zdCBidWZmZXJTaXplID0gY2FsY3VsYXRlVGVuc29yU2l6ZUluQnl0ZXMoZGF0YVR5cGUsIGRpbXMpO1xuICAgICAgaWYgKCFidWZmZXJTaXplKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZGF0YSB0eXBlOiAke2RhdGFUeXBlfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgZ3B1RGF0YUlkID0gYnVmZmVyU2l6ZSA+IDAgPyB0aGlzLmJhY2tlbmQuZ3B1RGF0YU1hbmFnZXIuY3JlYXRlKGJ1ZmZlclNpemUpLmlkIDogMDtcbiAgICAgIHJldHVybiBuZXcgVGVuc29yVmlld0ltcGwodGhpcy5tb2R1bGUsIGRhdGFUeXBlLCBncHVEYXRhSWQsIGRpbXMpO1xuICAgIH07XG4gICAgcmV0dXJuIHRoaXMuYmFja2VuZC5ydW4oXG4gICAgICBwcm9ncmFtLFxuICAgICAgbWFwcGVkSW5wdXRzLFxuICAgICAgb3V0cHV0SW5kaWNlcyxcbiAgICAgIGNyZWF0ZUtlcm5lbE91dHB1dCxcbiAgICAgIGNyZWF0ZVRlbXBvcmFyeU91dHB1dCxcbiAgICAgIHRoaXMub3V0cHV0Q291bnQsXG4gICAgKTtcbiAgfVxuXG4gIG91dHB1dChpbmRleDogbnVtYmVyLCBkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlciB7XG4gICAgY29uc3Qgc3RhY2sgPSB0aGlzLm1vZHVsZS5zdGFja1NhdmUoKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcHRyU2l6ZSA9IHRoaXMubW9kdWxlLlBUUl9TSVpFO1xuICAgICAgY29uc3QgdHlwZSA9IHB0clNpemUgPT09IDQgPyAnaTMyJyA6ICdpNjQnO1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMubW9kdWxlLnN0YWNrQWxsb2MoKDEgKyBkaW1zLmxlbmd0aCkgKiBwdHJTaXplIC8qIHNpemVvZihzaXplX3QpICovKTtcbiAgICAgIHRoaXMubW9kdWxlLnNldFZhbHVlKGRhdGEsIGRpbXMubGVuZ3RoLCB0eXBlKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGltcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzLm1vZHVsZS5zZXRWYWx1ZShkYXRhICsgcHRyU2l6ZSAqIChpICsgMSksIGRpbXNbaV0sIHR5cGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMubW9kdWxlLl9Kc2VwT3V0cHV0ISh0aGlzLm9wS2VybmVsQ29udGV4dCwgaW5kZXgsIGRhdGEpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBnZW5lcmF0ZSBrZXJuZWwncyBvdXRwdXRbJHtpbmRleH1dIHdpdGggZGltcyBbJHtkaW1zfV0uIGAgK1xuICAgICAgICAgICdJZiB5b3UgYXJlIHJ1bm5pbmcgd2l0aCBwcmUtYWxsb2NhdGVkIG91dHB1dCwgcGxlYXNlIG1ha2Ugc3VyZSB0aGUgb3V0cHV0IHR5cGUvZGltcyBhcmUgY29ycmVjdC4gJyArXG4gICAgICAgICAgYEVycm9yOiAke2V9YCxcbiAgICAgICk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMubW9kdWxlLnN0YWNrUmVzdG9yZShzdGFjayk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBKU0VQIHdpdGggV2ViR1BVIGJhY2tlbmQuXG4gKlxuICogVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCBhZnRlciB0aGUgV2ViQXNzZW1ibHkgbW9kdWxlIGlzIGxvYWRlZCBhbmQgaW5pdGlhbGl6ZWQgKFwiX09ydEluaXRcIiBpcyBjYWxsZWQpLCBvbmNlIGZvclxuICogZWFjaCBvZiB0aGUgZm9sbG93aW5nIEVQcyBpZiB0aGV5IGFyZSBzcGVjaWZpZWQ6XG4gKiAtIFwid2ViZ3B1XCJcbiAqIC0gXCJ3ZWJublwiXG4gKlxuICogRm9yIFdlYkdQVSwgdGhpcyBmdW5jdGlvbiBleHBlY3RzOlxuICogIC0gV2ViR1BVIGlzIGVuYWJsZWQgaW4gYnVpbGQgKEJVSUxEX0RFRlMuRElTQUJMRV9KU0VQID09PSBmYWxzZSkuXG4gKiAgLSBXZWJHUFUgaXMgYXZhaWxhYmxlIGluIGN1cnJlbnQgZW52aXJvbm1lbnQuIChhIHZhbGlkIEdQVUFkYXB0ZXIgaXMgcGFzc2VkIGluKVxuICpcbiAqIEZvciBXZWJOTiwgdGhpcyBmdW5jdGlvbiBleHBlY3RzOlxuICogLSBXZWJOTiBpcyBlbmFibGVkIGluIGJ1aWxkIChCVUlMRF9ERUZTLkRJU0FCTEVfSlNFUCA9PT0gZmFsc2UpLlxuICogLSBXZWJOTiBpcyBhdmFpbGFibGUgaW4gY3VycmVudCBlbnZpcm9ubWVudC4gKG5hdmlnYXRvci5tbCBpcyBub3QgdW5kZWZpbmVkKVxuICpcbiAqIElmIHRoZSBXZWJBc3NlbWJseSBtb2R1bGUgaXMgbm90IGJ1aWx0IHdpdGggSlNFUCBzdXBwb3J0LCB0aGlzIGZ1bmN0aW9uIHdpbGwgdGhyb3cgYW4gZXJyb3IuIFRoaXMgd2lsbCBpbnZhbGlkYXRlXG4gKiAnd2ViZ3B1Jy8nd2Vibm4nIGJhY2tlbmQuXG4gKlxuICogQHBhcmFtIG5hbWUgLSB0aGUgbmFtZSBvZiB0aGUgRVAsIGVpdGhlciBcIndlYmdwdVwiIG9yIFwid2Vibm5cIlxuICogQHBhcmFtIG1vZHVsZSAtIHRoZSBPUlQgV2ViQXNzZW1ibHkgbW9kdWxlXG4gKiBAcGFyYW0gZW52IC0gdGhlIE9SVCBlbnZpcm9ubWVudCB2YXJpYWJsZSAob3J0LmVudilcbiAqIEBwYXJhbSBncHVBZGFwdGVyIC0gdGhlIHByZS1jcmVhdGVkIEdQVSBhZGFwdGVyXG4gKi9cbmV4cG9ydCBjb25zdCBpbml0ID0gYXN5bmMgKFxuICBuYW1lOiAnd2ViZ3B1JyB8ICd3ZWJubicsXG4gIG1vZHVsZTogT3J0V2FzbU1vZHVsZSxcbiAgZW52OiBFbnYsXG4gIGdwdUFkYXB0ZXI/OiBHUFVBZGFwdGVyLFxuKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGNvbnN0IGpzZXBJbml0ID0gbW9kdWxlLmpzZXBJbml0O1xuICBpZiAoIWpzZXBJbml0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gaW5pdGlhbGl6ZSBKU0VQLiBUaGUgV2ViQXNzZW1ibHkgbW9kdWxlIGlzIG5vdCBidWlsdCB3aXRoIEpTRVAgc3VwcG9ydC4nKTtcbiAgfVxuXG4gIGlmIChuYW1lID09PSAnd2ViZ3B1Jykge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzXG4gICAgY29uc3Qgd2ViR3B1QmFja2VuZEltcGwgPSByZXF1aXJlKCcuL2JhY2tlbmQtd2ViZ3B1JykuV2ViR3B1QmFja2VuZDtcbiAgICBjb25zdCBiYWNrZW5kID0gbmV3IHdlYkdwdUJhY2tlbmRJbXBsKCk7XG4gICAgYXdhaXQgYmFja2VuZC5pbml0aWFsaXplKGVudiwgZ3B1QWRhcHRlciEpO1xuXG4gICAganNlcEluaXQoJ3dlYmdwdScsIFtcbiAgICAgIC8vIGJhY2tlbmRcbiAgICAgIGJhY2tlbmQsXG5cbiAgICAgIC8vIGpzZXBBbGxvYygpXG4gICAgICAoc2l6ZTogbnVtYmVyKSA9PiBiYWNrZW5kLmFsbG9jKE51bWJlcihzaXplKSksXG5cbiAgICAgIC8vIGpzZXBGcmVlKClcbiAgICAgIChwdHI6IG51bWJlcikgPT4gYmFja2VuZC5mcmVlKHB0ciksXG5cbiAgICAgIC8vIGpzZXBDb3B5KHNyYywgZHN0LCBzaXplLCBpc1NvdXJjZUdwdSlcbiAgICAgIChzcmM6IG51bWJlciwgZHN0OiBudW1iZXIsIHNpemU6IG51bWJlciwgaXNTb3VyY2VHcHUgPSBmYWxzZSkgPT4ge1xuICAgICAgICBpZiAoaXNTb3VyY2VHcHUpIHtcbiAgICAgICAgICBMT0dfREVCVUcoXG4gICAgICAgICAgICAndmVyYm9zZScsXG4gICAgICAgICAgICAoKSA9PiBgW1dlYkdQVV0ganNlcENvcHlHcHVUb0dwdTogc3JjPSR7TnVtYmVyKHNyYyl9LCBkc3Q9JHtOdW1iZXIoZHN0KX0sIHNpemU9JHtOdW1iZXIoc2l6ZSl9YCxcbiAgICAgICAgICApO1xuICAgICAgICAgIGJhY2tlbmQubWVtY3B5KE51bWJlcihzcmMpLCBOdW1iZXIoZHN0KSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgTE9HX0RFQlVHKFxuICAgICAgICAgICAgJ3ZlcmJvc2UnLFxuICAgICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgICAgYFtXZWJHUFVdIGpzZXBDb3B5Q3B1VG9HcHU6IGRhdGFPZmZzZXQ9JHtOdW1iZXIoc3JjKX0sIGdwdURhdGFJZD0ke051bWJlcihkc3QpfSwgc2l6ZT0ke051bWJlcihzaXplKX1gLFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgZGF0YSA9IG1vZHVsZS5IRUFQVTguc3ViYXJyYXkoTnVtYmVyKHNyYyA+Pj4gMCksIE51bWJlcihzcmMgPj4+IDApICsgTnVtYmVyKHNpemUpKTtcbiAgICAgICAgICBiYWNrZW5kLnVwbG9hZChOdW1iZXIoZHN0KSwgZGF0YSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIC8vIGpzZXBDb3B5QXN5bmMoc3JjLCBkc3QsIHNpemUpXG4gICAgICBhc3luYyAoZ3B1RGF0YUlkOiBudW1iZXIsIGRhdGFPZmZzZXQ6IG51bWJlciwgc2l6ZTogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIExPR19ERUJVRyhcbiAgICAgICAgICAndmVyYm9zZScsXG4gICAgICAgICAgKCkgPT4gYFtXZWJHUFVdIGpzZXBDb3B5R3B1VG9DcHU6IGdwdURhdGFJZD0ke2dwdURhdGFJZH0sIGRhdGFPZmZzZXQ9JHtkYXRhT2Zmc2V0fSwgc2l6ZT0ke3NpemV9YCxcbiAgICAgICAgKTtcblxuICAgICAgICBhd2FpdCBiYWNrZW5kLmRvd25sb2FkKE51bWJlcihncHVEYXRhSWQpLCAoKSA9PlxuICAgICAgICAgIG1vZHVsZS5IRUFQVTguc3ViYXJyYXkoTnVtYmVyKGRhdGFPZmZzZXQpID4+PiAwLCBOdW1iZXIoZGF0YU9mZnNldCArIHNpemUpID4+PiAwKSxcbiAgICAgICAgKTtcbiAgICAgIH0sXG5cbiAgICAgIC8vIGpzZXBDcmVhdGVLZXJuZWxcbiAgICAgIChrZXJuZWxUeXBlOiBzdHJpbmcsIGtlcm5lbElkOiBudW1iZXIsIGF0dHJpYnV0ZTogdW5rbm93bikgPT5cbiAgICAgICAgYmFja2VuZC5jcmVhdGVLZXJuZWwoXG4gICAgICAgICAga2VybmVsVHlwZSxcbiAgICAgICAgICBOdW1iZXIoa2VybmVsSWQpLFxuICAgICAgICAgIGF0dHJpYnV0ZSxcbiAgICAgICAgICBtb2R1bGUuVVRGOFRvU3RyaW5nKG1vZHVsZS5fSnNlcEdldE5vZGVOYW1lIShOdW1iZXIoa2VybmVsSWQpKSksXG4gICAgICAgICksXG5cbiAgICAgIC8vIGpzZXBSZWxlYXNlS2VybmVsXG4gICAgICAoa2VybmVsOiBudW1iZXIpID0+IGJhY2tlbmQucmVsZWFzZUtlcm5lbChrZXJuZWwpLFxuXG4gICAgICAvLyBqc2VwUnVuXG4gICAgICAoa2VybmVsOiBudW1iZXIsIGNvbnRleHREYXRhT2Zmc2V0OiBudW1iZXIsIHNlc3Npb25IYW5kbGU6IG51bWJlciwgZXJyb3JzOiBBcnJheTxQcm9taXNlPHN0cmluZyB8IG51bGw+PikgPT4ge1xuICAgICAgICBMT0dfREVCVUcoXG4gICAgICAgICAgJ3ZlcmJvc2UnLFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBgW1dlYkdQVV0ganNlcFJ1bjogc2Vzc2lvbkhhbmRsZT0ke3Nlc3Npb25IYW5kbGV9LCBrZXJuZWw9JHtrZXJuZWx9LCBjb250ZXh0RGF0YU9mZnNldD0ke2NvbnRleHREYXRhT2Zmc2V0fWAsXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgQ29tcHV0ZUNvbnRleHRJbXBsKG1vZHVsZSwgYmFja2VuZCwgTnVtYmVyKGNvbnRleHREYXRhT2Zmc2V0KSk7XG4gICAgICAgIHJldHVybiBiYWNrZW5kLmNvbXB1dGVLZXJuZWwoTnVtYmVyKGtlcm5lbCksIGNvbnRleHQsIGVycm9ycyk7XG4gICAgICB9LFxuICAgICAgLy8ganNlcENhcHR1cmVCZWdpblxuICAgICAgKCkgPT4gYmFja2VuZC5jYXB0dXJlQmVnaW4oKSxcbiAgICAgIC8vIGpzZXBDYXB0dXJlRW5kXG4gICAgICAoKSA9PiBiYWNrZW5kLmNhcHR1cmVFbmQoKSxcbiAgICAgIC8vIGpzZXBSZXBsYXlcbiAgICAgICgpID0+IGJhY2tlbmQucmVwbGF5KCksXG4gICAgXSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgYmFja2VuZCA9IG5ldyBXZWJOTkJhY2tlbmQoZW52KTtcbiAgICBqc2VwSW5pdCgnd2Vibm4nLCBbXG4gICAgICBiYWNrZW5kLFxuICAgICAgLy8gd2Vibm5SZXNlcnZlVGVuc29ySWRcbiAgICAgICgpID0+IGJhY2tlbmQucmVzZXJ2ZVRlbnNvcklkKCksXG4gICAgICAvLyB3ZWJublJlbGVhc2VUZW5zb3JJZFxuICAgICAgKHRlbnNvcklkOiBudW1iZXIpID0+IGJhY2tlbmQucmVsZWFzZVRlbnNvcklkKHRlbnNvcklkKSxcbiAgICAgIC8vIHdlYm5uRW5zdXJlVGVuc29yXG4gICAgICBhc3luYyAoXG4gICAgICAgIHNlc3Npb25JZDogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgICAgICB0ZW5zb3JJZDogbnVtYmVyLFxuICAgICAgICBvbm54RGF0YVR5cGU6IG51bWJlcixcbiAgICAgICAgc2hhcGU6IG51bWJlcltdLFxuICAgICAgICBjb3B5T2xkOiBib29sZWFuLFxuICAgICAgKSA9PiBiYWNrZW5kLmVuc3VyZVRlbnNvcihzZXNzaW9uSWQsIHRlbnNvcklkLCBvbm54RGF0YVR5cGUsIHNoYXBlLCBjb3B5T2xkKSxcbiAgICAgIC8vIHdlYm5uVXBsb2FkVGVuc29yXG4gICAgICAodGVuc29ySWQ6IG51bWJlciwgZGF0YTogVWludDhBcnJheSkgPT4ge1xuICAgICAgICBiYWNrZW5kLnVwbG9hZFRlbnNvcih0ZW5zb3JJZCwgZGF0YSk7XG4gICAgICB9LFxuICAgICAgLy8gd2Vibm5Eb3dubG9hZFRlbnNvclxuICAgICAgYXN5bmMgKHRlbnNvcklkOiBudW1iZXIsIGRzdEJ1ZmZlcjogQXJyYXlCdWZmZXJWaWV3IHwgQXJyYXlCdWZmZXIpID0+IGJhY2tlbmQuZG93bmxvYWRUZW5zb3IodGVuc29ySWQsIGRzdEJ1ZmZlciksXG4gICAgICAvLyB3ZWJublJlZ2lzdGVyTUxDb250ZXh0XG4gICAgICAoc2Vzc2lvbklkOiBudW1iZXIsIG1sQ29udGV4dDogTUxDb250ZXh0KSA9PiBiYWNrZW5kLnJlZ2lzdGVyTUxDb250ZXh0KHNlc3Npb25JZCwgbWxDb250ZXh0KSxcbiAgICAgIC8vIHdlYm5uRW5hYmxlVHJhY2VFdmVudFxuICAgICAgISFlbnYudHJhY2UsXG4gICAgXSk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8vIFdlYk5OIEFQSSBjdXJyZW50bHkgZG9lcyBub3QgaGF2ZSBhIFR5cGVTY3JpcHQgZGVmaW5pdGlvbiBmaWxlLiBUaGlzIGZpbGUgaXMgYSB3b3JrYXJvdW5kIHdpdGggdHlwZXMgZ2VuZXJhdGVkIGZyb21cbi8vIFdlYk5OIEFQSSBzcGVjaWZpY2F0aW9uLlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3dlYm1hY2hpbmVsZWFybmluZy93ZWJubi9pc3N1ZXMvNjc3XG4vLy8gPHJlZmVyZW5jZSBwYXRoPVwianNlcC93ZWJubi93ZWJubi5kLnRzXCIgLz5cblxuaW1wb3J0IHsgRW52LCBJbmZlcmVuY2VTZXNzaW9uLCBUZW5zb3IsIFRSQUNFX0VWRU5UX0JFR0lOLCBUUkFDRV9FVkVOVF9FTkQgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQge1xuICBTZXJpYWxpemFibGVJbnRlcm5hbEJ1ZmZlcixcbiAgU2VyaWFsaXphYmxlU2Vzc2lvbk1ldGFkYXRhLFxuICBTZXJpYWxpemFibGVUZW5zb3JNZXRhZGF0YSxcbiAgVGVuc29yTWV0YWRhdGEsXG59IGZyb20gJy4vcHJveHktbWVzc2FnZXMnO1xuaW1wb3J0IHsgc2V0UnVuT3B0aW9ucyB9IGZyb20gJy4vcnVuLW9wdGlvbnMnO1xuaW1wb3J0IHsgc2V0U2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuL3Nlc3Npb24tb3B0aW9ucyc7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVUZW5zb3JTaXplSW5CeXRlcyxcbiAgZGF0YUxvY2F0aW9uU3RyaW5nVG9FbnVtLFxuICBpc0dwdUJ1ZmZlclN1cHBvcnRlZFR5cGUsXG4gIGlzTUxUZW5zb3JTdXBwb3J0ZWRUeXBlLFxuICBsb2dMZXZlbFN0cmluZ1RvRW51bSxcbiAgdGVuc29yRGF0YVR5cGVFbnVtVG9TdHJpbmcsXG4gIHRlbnNvckRhdGFUeXBlU3RyaW5nVG9FbnVtLFxuICB0ZW5zb3JUeXBlVG9UeXBlZEFycmF5Q29uc3RydWN0b3IsXG59IGZyb20gJy4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgZ2V0SW5zdGFuY2UgfSBmcm9tICcuL3dhc20tZmFjdG9yeSc7XG5pbXBvcnQgeyBhbGxvY1dhc21TdHJpbmcsIGNoZWNrTGFzdEVycm9yIH0gZnJvbSAnLi93YXNtLXV0aWxzJztcbmltcG9ydCB7IGxvYWRGaWxlIH0gZnJvbSAnLi93YXNtLXV0aWxzLWxvYWQtZmlsZSc7XG5cbi8vICNyZWdpb24gSW5pdGlhbGl6YXRpb25zXG5cbi8qKlxuICogVGhlcmUgYXJlIDQgZGlmZmVyZW50IFwiaW5pdGlhbGl6YXRpb25cIiBzdGVwcyBmb3IgT1JULiBUaGV5IGhhcHBlbiBpbiBkaWZmZXJlbnQgcGxhY2VzIGFuZCBkaWZmZXJlbnQgdGltZS5cbiAqXG4gKiAxLiBKYXZhU2NyaXB0IGluaXRpYWxpemF0aW9uIGZvciBvbm54cnVudGltZS1jb21tb24gYW5kIG9ubnhydW50aW1lLXdlYi5cbiAqICAgIFRoaXMgaXMgdGhlIGZpcnN0IGluaXRpYWxpemF0aW9uIHN0ZXAuIEluIHRoaXMgc3RlcCwgb25ueHJ1bnRpbWUtd2ViIGNhbGxzIG9ubnhydW50aW1lLWNvbW1vbidzIHJlZ2lzdGVyQmFja2VuZCgpXG4gKiBmdW5jdGlvbiBtdWx0aXBsZSB0aW1lcyB0byByZWdpc3RlciBhbGwgdGhlIGF2YWlsYWJsZSBiYWNrZW5kcy4gVGhlIGJhY2tlbmQgcmVnaXN0cmF0aW9uIGlzIHZlcnkgZmFzdC4gSXQgb25seVxuICogcmVnaXN0ZXJzIHRoZSBiYWNrZW5kIG5hbWUgd2l0aCB0aGUgdW5pbml0aWFsaXplZCBiYWNrZW5kIG9iamVjdC4gTm8gaGVhdnkgaW5pdGlhbGl6YXRpb24gaXMgZG9uZSBpbiB0aGlzIHN0ZXAuXG4gKiAgICBSZWZlciB0byB3ZWIvbGliL2luZGV4LnRzIGZvciB0aGUgYmFja2VuZCByZWdpc3RyYXRpb24uXG4gKlxuICogMi4gV2ViQXNzZW1ibHkgYXJ0aWZhY3QgaW5pdGlhbGl6YXRpb24uXG4gKiAgICBUaGlzIGhhcHBlbnMgd2hlbiBhbnkgcmVnaXN0ZXJlZCB3YXNtIGJhY2tlbmQgaXMgdXNlZCBmb3IgdGhlIGZpcnN0IHRpbWUgKGllLiBgb3J0LkluZmVyZW5jZVNlc3Npb24uY3JlYXRlKClgIGlzXG4gKiBjYWxsZWQpLiBJbiB0aGlzIHN0ZXAsIG9ubnhydW50aW1lLXdlYiBkb2VzIHRoZSBmb2xsb3dpbmdzOlxuICogICAgIC0gY3JlYXRlIGEgcHJveHkgd29ya2VyIGFuZCBtYWtlIHN1cmUgdGhlIHByb3h5IHdvcmtlciBpcyByZWFkeSB0byByZWNlaXZlIG1lc3NhZ2VzLCBpZiBwcm94eSBpcyBlbmFibGVkLlxuICogICAgIC0gcGVyZm9ybSBmZWF0dXJlIGRldGVjdGlvbiwgbG9jYXRlIGNvcnJlY3QgV2ViQXNzZW1ibHkgYXJ0aWZhY3QgcGF0aCBhbmQgY2FsbCB0aGUgRW1zY3JpcHRlbiBnZW5lcmF0ZWRcbiAqIEphdmFTY3JpcHQgY29kZSB0byBpbml0aWFsaXplIHRoZSBXZWJBc3NlbWJseSBydW50aW1lLlxuICogICAgICAgICAtIGlmIHByb3h5IGlzIGVuYWJsZWQsIHRoaXMgc3RlcCBoYXBwZW5zIGluIHRoZSBwcm94eSB3b3JrZXIgdXNpbmcgbWVzc2FnZSAnaW5pdC13YXNtJy5cbiAqICAgICAgICAgLSBkb3dubG9hZGluZyB0aGUgJ29ydC13YXNtey4uLn0ud2FzbScgZmlsZSBpcyBkb25lIGluIHRoaXMgc3RlcC5cbiAqICAgICAgICAgLSBpZiBtdWx0aS10aHJlYWQgaXMgZW5hYmxlZCwgb25lIG9yIG1vcmUgd2Vid29ya2VyIHdpbGwgYmUgY3JlYXRlZCB0byBpbml0aWFsaXplIHRoZSBQVGhyZWFkIHRocmVhZHBvb2wuXG4gKlxuICogMy4gT1JUIGVudmlyb25tZW50IGluaXRpYWxpemF0aW9uLlxuICogICAgVGhpcyBoYXBwZW5zIGFmdGVyIHN0ZXAgMi4gSW4gdGhpcyBzdGVwLCBvbm54cnVudGltZS13ZWIgcGVyZm9ybXMgT05OWCBSdW50aW1lIGVudmlyb25tZW50IGluaXRpYWxpemF0aW9uLlxuICogRnVuY3Rpb24gYF9PcnRJbml0KClgIGlzIGNhbGxlZCBpbiB0aGlzIHN0ZXAuXG4gKiAgICAgLSBpZiBwcm94eSBpcyBlbmFibGVkLCB0aGlzIHN0ZXAgaGFwcGVucyBpbiB0aGUgcHJveHkgd29ya2VyIHVzaW5nIG1lc3NhZ2UgJ2luaXQtb3J0Jy5cbiAqICAgICAtIGxvZ2dpbmcgbGV2ZWwgKG9ydC5lbnYubG9nTGV2ZWwpIGFuZCB0aHJlYWQgbnVtYmVyIChvcnQuZW52Lndhc20ubnVtVGhyZWFkcykgYXJlIHNldCBpbiB0aGlzIHN0ZXAuXG4gKlxuICogNC4gU2Vzc2lvbiBpbml0aWFsaXphdGlvbi5cbiAqICAgIFRoaXMgaGFwcGVucyB3aGVuIGBvcnQuSW5mZXJlbmNlU2Vzc2lvbi5jcmVhdGUoKWAgaXMgY2FsbGVkLiBVbmxpa2UgdGhlIGZpcnN0IDMgc3RlcHMgKHRoZXkgb25seSBjYWxsZWQgb25jZSksXG4gKiB0aGlzIHN0ZXAgd2lsbCBiZSBkb25lIGZvciBlYWNoIHNlc3Npb24uIEluIHRoaXMgc3RlcCwgb25ueHJ1bnRpbWUtd2ViIGRvZXMgdGhlIGZvbGxvd2luZ3M6XG4gKiAgICBJZiB0aGUgcGFyYW1ldGVyIGlzIGEgVVJMOlxuICogICAgLSBkb3dubG9hZCB0aGUgbW9kZWwgZGF0YSBmcm9tIHRoZSBVUkwuXG4gKiAgICAtIGNvcHkgdGhlIG1vZGVsIGRhdGEgdG8gdGhlIFdBU00gaGVhcC4gKHByb3h5OiAnY29weS1mcm9tJylcbiAqICAgIC0gZGVyZWZlcmVuY2UgdGhlIG1vZGVsIGJ1ZmZlci4gVGhpcyBzdGVwIGFsbG93cyB0aGUgb3JpZ2luYWwgQXJyYXlCdWZmZXIgdG8gYmUgZ2FyYmFnZSBjb2xsZWN0ZWQuXG4gKiAgICAtIGNhbGwgYF9PcnRDcmVhdGVTZXNzaW9uKClgIHRvIGNyZWF0ZSB0aGUgc2Vzc2lvbi4gKHByb3h5OiAnY3JlYXRlJylcbiAqXG4gKiAgICBJZiB0aGUgcGFyYW1ldGVyIGlzIGEgVWludDhBcnJheSBvYmplY3Q6XG4gKiAgICAtIGNvcHkgdGhlIG1vZGVsIGRhdGEgdG8gdGhlIFdBU00gaGVhcC4gKHByb3h5OiAnY29weS1mcm9tJylcbiAqICAgIC0gY2FsbCBgX09ydENyZWF0ZVNlc3Npb24oKWAgdG8gY3JlYXRlIHRoZSBzZXNzaW9uLiAocHJveHk6ICdjcmVhdGUnKVxuICpcbiAqXG4gKi9cblxuLyoqXG4gKiBpbml0aWFsaXplIE9SVCBlbnZpcm9ubWVudC5cbiAqXG4gKiBAcGFyYW0gbnVtVGhyZWFkcyBTZXRHbG9iYWxJbnRyYU9wTnVtVGhyZWFkcyhudW1UaHJlYWRzKVxuICogQHBhcmFtIGxvZ2dpbmdMZXZlbCBDcmVhdGVFbnYoc3RhdGljX2Nhc3Q8T3J0TG9nZ2luZ0xldmVsPihsb2dnaW5nX2xldmVsKSlcbiAqL1xuY29uc3QgaW5pdE9ydCA9IChudW1UaHJlYWRzOiBudW1iZXIsIGxvZ2dpbmdMZXZlbDogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGNvbnN0IGVycm9yQ29kZSA9IGdldEluc3RhbmNlKCkuX09ydEluaXQobnVtVGhyZWFkcywgbG9nZ2luZ0xldmVsKTtcbiAgaWYgKGVycm9yQ29kZSAhPT0gMCkge1xuICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgaW5pdGlhbGl6ZSBvbm54cnVudGltZS5cIik7XG4gIH1cbn07XG5cbi8qKlxuICogaW5pdGlhbGl6ZSBydW50aW1lIGVudmlyb25tZW50LlxuICogQHBhcmFtIGVudiBwYXNzZWQgaW4gdGhlIGVudmlyb25tZW50IGNvbmZpZyBvYmplY3QuXG4gKi9cbmV4cG9ydCBjb25zdCBpbml0UnVudGltZSA9IGFzeW5jIChlbnY6IEVudik6IFByb21pc2U8dm9pZD4gPT4ge1xuICAvLyBpbml0IE9SVFxuICBpbml0T3J0KGVudi53YXNtLm51bVRocmVhZHMhLCBsb2dMZXZlbFN0cmluZ1RvRW51bShlbnYubG9nTGV2ZWwpKTtcbn07XG5cbi8qKlxuICogcGVyZm9ybSBFUCBzcGVjaWZpYyBpbml0aWFsaXphdGlvbi5cbiAqXG4gKiBAcGFyYW0gZW52XG4gKiBAcGFyYW0gZXBOYW1lXG4gKi9cbmV4cG9ydCBjb25zdCBpbml0RXAgPSBhc3luYyAoZW52OiBFbnYsIGVwTmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIC8vIGluaXRpYWxpemUgQVNZTkNJRlkgc3VwcG9ydFxuICBnZXRJbnN0YW5jZSgpLmFzeW5jSW5pdD8uKCk7XG5cbiAgLy8gcGVyZm9ybSBXZWJHUFUgYXZhaWxhYmlsaXR5IGNoZWNrICggZWl0aGVyIEpTRVAgb3IgV2ViR1BVIEVQIClcbiAgbGV0IHdlYmdwdUFkYXB0ZXIgPSBlbnYud2ViZ3B1LmFkYXB0ZXIgYXMgR1BVQWRhcHRlciB8IG51bGw7XG4gIGlmIChlcE5hbWUgPT09ICd3ZWJncHUnKSB7XG4gICAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IgPT09ICd1bmRlZmluZWQnIHx8ICFuYXZpZ2F0b3IuZ3B1KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdQVSBpcyBub3Qgc3VwcG9ydGVkIGluIGN1cnJlbnQgZW52aXJvbm1lbnQnKTtcbiAgICB9XG4gICAgaWYgKCF3ZWJncHVBZGFwdGVyKSB7XG4gICAgICAvLyBpZiBhZGFwdGVyIGlzIG5vdCBzZXQsIHJlcXVlc3QgYSBuZXcgYWRhcHRlci5cbiAgICAgIGNvbnN0IHBvd2VyUHJlZmVyZW5jZSA9IGVudi53ZWJncHUucG93ZXJQcmVmZXJlbmNlO1xuICAgICAgaWYgKHBvd2VyUHJlZmVyZW5jZSAhPT0gdW5kZWZpbmVkICYmIHBvd2VyUHJlZmVyZW5jZSAhPT0gJ2xvdy1wb3dlcicgJiYgcG93ZXJQcmVmZXJlbmNlICE9PSAnaGlnaC1wZXJmb3JtYW5jZScpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHBvd2VyUHJlZmVyZW5jZSBzZXR0aW5nOiBcIiR7cG93ZXJQcmVmZXJlbmNlfVwiYCk7XG4gICAgICB9XG4gICAgICBjb25zdCBmb3JjZUZhbGxiYWNrQWRhcHRlciA9IGVudi53ZWJncHUuZm9yY2VGYWxsYmFja0FkYXB0ZXI7XG4gICAgICBpZiAoZm9yY2VGYWxsYmFja0FkYXB0ZXIgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgZm9yY2VGYWxsYmFja0FkYXB0ZXIgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZm9yY2VGYWxsYmFja0FkYXB0ZXIgc2V0dGluZzogXCIke2ZvcmNlRmFsbGJhY2tBZGFwdGVyfVwiYCk7XG4gICAgICB9XG4gICAgICB3ZWJncHVBZGFwdGVyID0gYXdhaXQgbmF2aWdhdG9yLmdwdS5yZXF1ZXN0QWRhcHRlcih7IHBvd2VyUHJlZmVyZW5jZSwgZm9yY2VGYWxsYmFja0FkYXB0ZXIgfSk7XG4gICAgICBpZiAoIXdlYmdwdUFkYXB0ZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdGYWlsZWQgdG8gZ2V0IEdQVSBhZGFwdGVyLiAnICtcbiAgICAgICAgICAgICdZb3UgbWF5IG5lZWQgdG8gZW5hYmxlIGZsYWcgXCItLWVuYWJsZS11bnNhZmUtd2ViZ3B1XCIgaWYgeW91IGFyZSB1c2luZyBDaHJvbWUuJyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaWYgYWRhcHRlciBpcyBzZXQsIHZhbGlkYXRlIGl0LlxuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2Ygd2ViZ3B1QWRhcHRlci5saW1pdHMgIT09ICdvYmplY3QnIHx8XG4gICAgICAgIHR5cGVvZiB3ZWJncHVBZGFwdGVyLmZlYXR1cmVzICE9PSAnb2JqZWN0JyB8fFxuICAgICAgICB0eXBlb2Ygd2ViZ3B1QWRhcHRlci5yZXF1ZXN0RGV2aWNlICE9PSAnZnVuY3Rpb24nXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIEdQVSBhZGFwdGVyIHNldCBpbiBgZW52LndlYmdwdS5hZGFwdGVyYC4gSXQgbXVzdCBiZSBhIEdQVUFkYXB0ZXIgb2JqZWN0LicpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIHBlcmZvcm0gV2ViTk4gYXZhaWxhYmlsaXR5IGNoZWNrICggZWl0aGVyIEpTRVAgb3IgV2ViTk4gRVAgKVxuICBpZiAoZXBOYW1lID09PSAnd2Vibm4nKSB7XG4gICAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IgPT09ICd1bmRlZmluZWQnIHx8ICEobmF2aWdhdG9yIGFzIHVua25vd24gYXMgeyBtbDogdW5rbm93biB9KS5tbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJOTiBpcyBub3Qgc3VwcG9ydGVkIGluIGN1cnJlbnQgZW52aXJvbm1lbnQnKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9KU0VQKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMsIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXNcbiAgICBjb25zdCBpbml0SnNlcCA9IHJlcXVpcmUoJy4vanNlcC9pbml0JykuaW5pdDtcblxuICAgIGlmIChlcE5hbWUgPT09ICd3ZWJncHUnKSB7XG4gICAgICBhd2FpdCBpbml0SnNlcCgnd2ViZ3B1JywgZ2V0SW5zdGFuY2UoKSwgZW52LCB3ZWJncHVBZGFwdGVyKTtcbiAgICB9XG4gICAgaWYgKGVwTmFtZSA9PT0gJ3dlYm5uJykge1xuICAgICAgYXdhaXQgaW5pdEpzZXAoJ3dlYm5uJywgZ2V0SW5zdGFuY2UoKSwgZW52KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR1BVICYmIGVwTmFtZSA9PT0gJ3dlYmdwdScpIHtcbiAgICAgIGdldEluc3RhbmNlKCkud2ViZ3B1SW5pdCEoKGRldmljZSkgPT4ge1xuICAgICAgICBlbnYud2ViZ3B1LmRldmljZSA9IGRldmljZTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XRUJOTiAmJiBlcE5hbWUgPT09ICd3ZWJubicpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzXG4gICAgICBjb25zdCBiYWNrZW5kID0gbmV3IChyZXF1aXJlKCcuL2pzZXAvYmFja2VuZC13ZWJubicpLldlYk5OQmFja2VuZCkoZW52KTtcbiAgICAgIGdldEluc3RhbmNlKCkud2Vibm5Jbml0IShbXG4gICAgICAgIGJhY2tlbmQsXG4gICAgICAgIC8vIHdlYm5uUmVzZXJ2ZVRlbnNvcklkXG4gICAgICAgICgpID0+IGJhY2tlbmQucmVzZXJ2ZVRlbnNvcklkKCksXG4gICAgICAgIC8vIHdlYm5uUmVsZWFzZVRlbnNvcklkLFxuICAgICAgICAodGVuc29ySWQ6IG51bWJlcikgPT4gYmFja2VuZC5yZWxlYXNlVGVuc29ySWQodGVuc29ySWQpLFxuICAgICAgICAvLyB3ZWJubkVuc3VyZVRlbnNvclxuICAgICAgICBhc3luYyAoc2Vzc2lvbklkOiBudW1iZXIgfCB1bmRlZmluZWQsIHRlbnNvcklkOiBudW1iZXIsIG9ubnhEYXRhVHlwZTogbnVtYmVyLCBzaGFwZTogbnVtYmVyW10sIGNvcHlPbGQpID0+XG4gICAgICAgICAgYmFja2VuZC5lbnN1cmVUZW5zb3Ioc2Vzc2lvbklkLCB0ZW5zb3JJZCwgb25ueERhdGFUeXBlLCBzaGFwZSwgY29weU9sZCksXG4gICAgICAgIC8vIHdlYm5uVXBsb2FkVGVuc29yXG4gICAgICAgICh0ZW5zb3JJZDogbnVtYmVyLCBkYXRhOiBVaW50OEFycmF5KSA9PiB7XG4gICAgICAgICAgYmFja2VuZC51cGxvYWRUZW5zb3IodGVuc29ySWQsIGRhdGEpO1xuICAgICAgICB9LFxuICAgICAgICAvLyB3ZWJubkRvd25sb2FkVGVuc29yXG4gICAgICAgIGFzeW5jICh0ZW5zb3JJZDogbnVtYmVyLCBkc3RCdWZmZXI6IEFycmF5QnVmZmVyVmlldyB8IEFycmF5QnVmZmVyKSA9PlxuICAgICAgICAgIGJhY2tlbmQuZG93bmxvYWRUZW5zb3IodGVuc29ySWQsIGRzdEJ1ZmZlciksXG4gICAgICAgIC8vIHdlYm5uUmVnaXN0ZXJNTENvbnRleHRcbiAgICAgICAgKHNlc3Npb25JZDogbnVtYmVyLCBtbENvbnRleHQ6IE1MQ29udGV4dCkgPT4gYmFja2VuZC5yZWdpc3Rlck1MQ29udGV4dChzZXNzaW9uSWQsIG1sQ29udGV4dCksXG4gICAgICAgIC8vIHdlYm5uRW5hYmxlVHJhY2VFdmVudFxuICAgICAgICAhIWVudi50cmFjZSxcbiAgICAgIF0pO1xuICAgIH1cbiAgfVxufTtcblxuLy8gI2VuZHJlZ2lvbiBJbml0aWFsaXphdGlvbnNcblxuLyoqXG4gKiB2YWxpZCBkYXRhIGxvY2F0aW9ucyBmb3IgaW5wdXQvb3V0cHV0IHRlbnNvcnMuXG4gKi9cbnR5cGUgU3VwcG9ydGVkVGVuc29yRGF0YUxvY2F0aW9uRm9ySW5wdXRPdXRwdXQgPVxuICB8ICdjcHUnXG4gIHwgJ2NwdS1waW5uZWQnXG4gIHwgJ2dwdS1idWZmZXInXG4gIHwgJ21sLXRlbnNvcidcbiAgLy8gVXNlICdtbC10ZW5zb3InIGR1cmluZyBpbmZlcmVuY2UsIGJ1dCBvdXRwdXQgYSB0ZW5zb3IgbG9jYXRlZCBvbiB0aGUgQ1BVLlxuICB8ICdtbC10ZW5zb3ItY3B1LW91dHB1dCc7XG5cbnR5cGUgSU9CaW5kaW5nU3RhdGUgPSB7XG4gIC8qKlxuICAgKiB0aGUgaGFuZGxlIG9mIElPIGJpbmRpbmcuXG4gICAqL1xuICByZWFkb25seSBoYW5kbGU6IG51bWJlcjtcblxuICAvKipcbiAgICogdGhlIHByZWZlcnJlZCBsb2NhdGlvbiBmb3IgZWFjaCBvdXRwdXQgdGVuc29yLlxuICAgKlxuICAgKiB2YWx1ZSBpcyBvbmUgb2YgJ2NwdScsICdjcHUtcGlubmVkJywgJ2dwdS1idWZmZXInLCAnbWwtdGVuc29yJy5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dFByZWZlcnJlZExvY2F0aW9uczogcmVhZG9ubHkgU3VwcG9ydGVkVGVuc29yRGF0YUxvY2F0aW9uRm9ySW5wdXRPdXRwdXRbXTtcblxuICAvKipcbiAgICogZW51bSB2YWx1ZSBvZiB0aGUgcHJlZmVycmVkIGxvY2F0aW9uIGZvciBlYWNoIG91dHB1dCB0ZW5zb3IuXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRQcmVmZXJyZWRMb2NhdGlvbnNFbmNvZGVkOiByZWFkb25seSBudW1iZXJbXTtcbn07XG5cbi8qKlxuICogIHR1cGxlIGVsZW1lbnRzIGFyZTogSW5mZXJlbmNlU2Vzc2lvbiBJRDsgaW5wdXROYW1lc1VURjhFbmNvZGVkOyBvdXRwdXROYW1lc1VURjhFbmNvZGVkOyBiaW5kaW5nU3RhdGVcbiAqL1xudHlwZSBTZXNzaW9uTWV0YWRhdGEgPSBbXG4gIGluZmVyZW5jZVNlc3Npb25JZDogbnVtYmVyLFxuICBpbnB1dE5hbWVzVVRGOEVuY29kZWQ6IG51bWJlcltdLFxuICBvdXRwdXROYW1lc1VURjhFbmNvZGVkOiBudW1iZXJbXSxcbiAgYmluZGluZ1N0YXRlOiBJT0JpbmRpbmdTdGF0ZSB8IG51bGwsXG4gIGVuYWJsZUdyYXBoQ2FwdHVyZTogYm9vbGVhbixcbiAgaW5wdXRPdXRwdXRCb3VuZDogYm9vbGVhbixcbl07XG5cbmNvbnN0IGFjdGl2ZVNlc3Npb25zID0gbmV3IE1hcDxudW1iZXIsIFNlc3Npb25NZXRhZGF0YT4oKTtcblxuLyoqXG4gKiBnZXQgdGhlIGlucHV0L291dHB1dCBjb3VudCBvZiB0aGUgc2Vzc2lvbi5cbiAqIEBwYXJhbSBzZXNzaW9uSGFuZGxlIHRoZSBoYW5kbGUgcmVwcmVzZW50aW5nIHRoZSBzZXNzaW9uLiBzaG91bGQgYmUgbm9uLXplcm8uXG4gKiBAcmV0dXJucyBhIHR1cGxlIGluY2x1ZGluZyAyIG51bWJlcnMsIHJlcHJlc2VudGluZyB0aGUgaW5wdXQgY291bnQgYW5kIG91dHB1dCBjb3VudC5cbiAqL1xuY29uc3QgZ2V0U2Vzc2lvbklucHV0T3V0cHV0Q291bnQgPSAoc2Vzc2lvbkhhbmRsZTogbnVtYmVyKTogW251bWJlciwgbnVtYmVyXSA9PiB7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICBjb25zdCBzdGFjayA9IHdhc20uc3RhY2tTYXZlKCk7XG4gIHRyeSB7XG4gICAgY29uc3QgcHRyU2l6ZSA9IHdhc20uUFRSX1NJWkU7XG4gICAgY29uc3QgZGF0YU9mZnNldCA9IHdhc20uc3RhY2tBbGxvYygyICogcHRyU2l6ZSk7XG4gICAgY29uc3QgZXJyb3JDb2RlID0gd2FzbS5fT3J0R2V0SW5wdXRPdXRwdXRDb3VudChzZXNzaW9uSGFuZGxlLCBkYXRhT2Zmc2V0LCBkYXRhT2Zmc2V0ICsgcHRyU2l6ZSk7XG4gICAgaWYgKGVycm9yQ29kZSAhPT0gMCkge1xuICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCBnZXQgc2Vzc2lvbiBpbnB1dC9vdXRwdXQgY291bnQuXCIpO1xuICAgIH1cbiAgICBjb25zdCB0eXBlID0gcHRyU2l6ZSA9PT0gNCA/ICdpMzInIDogJ2k2NCc7XG4gICAgcmV0dXJuIFtOdW1iZXIod2FzbS5nZXRWYWx1ZShkYXRhT2Zmc2V0LCB0eXBlKSksIE51bWJlcih3YXNtLmdldFZhbHVlKGRhdGFPZmZzZXQgKyBwdHJTaXplLCB0eXBlKSldO1xuICB9IGZpbmFsbHkge1xuICAgIHdhc20uc3RhY2tSZXN0b3JlKHN0YWNrKTtcbiAgfVxufTtcblxuY29uc3QgZ2V0U2Vzc2lvbklucHV0T3V0cHV0TWV0YWRhdGEgPSAoXG4gIHNlc3Npb25IYW5kbGU6IG51bWJlcixcbiAgaW5kZXg6IG51bWJlcixcbik6IFtuYW1lT2Zmc2V0OiBudW1iZXIsIGVsZW1lbnRUeXBlOiBudW1iZXIsIGRpbXM/OiBBcnJheTxudW1iZXIgfCBzdHJpbmc+XSA9PiB7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICBjb25zdCBzdGFjayA9IHdhc20uc3RhY2tTYXZlKCk7XG4gIGxldCBtZXRhZGF0YU9mZnNldCA9IDA7XG4gIHRyeSB7XG4gICAgY29uc3QgcHRyU2l6ZSA9IHdhc20uUFRSX1NJWkU7XG4gICAgY29uc3QgZGF0YU9mZnNldCA9IHdhc20uc3RhY2tBbGxvYygyICogcHRyU2l6ZSk7XG4gICAgY29uc3QgZXJyb3JDb2RlID0gd2FzbS5fT3J0R2V0SW5wdXRPdXRwdXRNZXRhZGF0YShzZXNzaW9uSGFuZGxlLCBpbmRleCwgZGF0YU9mZnNldCwgZGF0YU9mZnNldCArIHB0clNpemUpO1xuICAgIGlmIChlcnJvckNvZGUgIT09IDApIHtcbiAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgZ2V0IHNlc3Npb24gaW5wdXQvb3V0cHV0IG1ldGFkYXRhLlwiKTtcbiAgICB9XG4gICAgY29uc3QgbmFtZU9mZnNldCA9IE51bWJlcih3YXNtLmdldFZhbHVlKGRhdGFPZmZzZXQsICcqJykpO1xuICAgIG1ldGFkYXRhT2Zmc2V0ID0gTnVtYmVyKHdhc20uZ2V0VmFsdWUoZGF0YU9mZnNldCArIHB0clNpemUsICcqJykpO1xuICAgIC8vIGdldCBlbGVtZW50IHR5cGVcbiAgICBjb25zdCBlbGVtZW50VHlwZSA9IHdhc20uSEVBUDMyW21ldGFkYXRhT2Zmc2V0IC8gNF07XG4gICAgaWYgKGVsZW1lbnRUeXBlID09PSAwKSB7XG4gICAgICByZXR1cm4gW25hbWVPZmZzZXQsIDBdOyAvLyBub24tdGVuc29yXG4gICAgfVxuXG4gICAgLy8gZ2V0IGRpbXMgY291bnRcbiAgICBjb25zdCBkaW1zQ291bnQgPSB3YXNtLkhFQVBVMzJbbWV0YWRhdGFPZmZzZXQgLyA0ICsgMV07XG4gICAgLy8gZ2V0IGRpbXNcbiAgICBjb25zdCBkaW1zOiBBcnJheTxudW1iZXIgfCBzdHJpbmc+ID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaW1zQ291bnQ7IGkrKykge1xuICAgICAgY29uc3Qgc3ltYm9saWNEaW1OYW1lT2Zmc2V0ID0gTnVtYmVyKHdhc20uZ2V0VmFsdWUobWV0YWRhdGFPZmZzZXQgKyA4ICsgaSAqIHB0clNpemUsICcqJykpO1xuICAgICAgZGltcy5wdXNoKFxuICAgICAgICBzeW1ib2xpY0RpbU5hbWVPZmZzZXQgIT09IDBcbiAgICAgICAgICA/IHdhc20uVVRGOFRvU3RyaW5nKHN5bWJvbGljRGltTmFtZU9mZnNldClcbiAgICAgICAgICA6IE51bWJlcih3YXNtLmdldFZhbHVlKG1ldGFkYXRhT2Zmc2V0ICsgOCArIChpICsgZGltc0NvdW50KSAqIHB0clNpemUsICcqJykpLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIFtuYW1lT2Zmc2V0LCBlbGVtZW50VHlwZSwgZGltc107XG4gIH0gZmluYWxseSB7XG4gICAgd2FzbS5zdGFja1Jlc3RvcmUoc3RhY2spO1xuICAgIGlmIChtZXRhZGF0YU9mZnNldCAhPT0gMCkge1xuICAgICAgd2FzbS5fT3J0RnJlZShtZXRhZGF0YU9mZnNldCk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIGFsbG9jYXRlIHRoZSBtZW1vcnkgYW5kIG1lbWNweSB0aGUgZXh0ZXJuYWwgYnVmZmVyLlxuICpcbiAqIEBwYXJhbSBtb2RlbCAtIHRoZSBleHRlcm5hbCBidWZmZXIgY29udGFpbmluZyB0aGUgbW9kZWwgZGF0YS4gTXVzdCBub3QgYmUgdGhlIHNhbWUgYnVmZmVyIGFzIHRoZSBXQVNNIGhlYXAuXG4gKiBAcmV0dXJucyBhIDItZWxlbWVudHMgdHVwbGUgLSB0aGUgcG9pbnRlciBhbmQgc2l6ZSBvZiB0aGUgYWxsb2NhdGVkIGJ1ZmZlclxuICovXG5leHBvcnQgY29uc3QgY29weUZyb21FeHRlcm5hbEJ1ZmZlciA9IChtb2RlbDogVWludDhBcnJheSk6IFtudW1iZXIsIG51bWJlcl0gPT4ge1xuICBjb25zdCB3YXNtID0gZ2V0SW5zdGFuY2UoKTtcbiAgY29uc3QgbW9kZWxEYXRhT2Zmc2V0ID0gd2FzbS5fbWFsbG9jKG1vZGVsLmJ5dGVMZW5ndGgpO1xuICBpZiAobW9kZWxEYXRhT2Zmc2V0ID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYW4ndCBjcmVhdGUgYSBzZXNzaW9uLiBmYWlsZWQgdG8gYWxsb2NhdGUgYSBidWZmZXIgb2Ygc2l6ZSAke21vZGVsLmJ5dGVMZW5ndGh9LmApO1xuICB9XG4gIHdhc20uSEVBUFU4LnNldChtb2RlbCwgbW9kZWxEYXRhT2Zmc2V0KTtcbiAgcmV0dXJuIFttb2RlbERhdGFPZmZzZXQsIG1vZGVsLmJ5dGVMZW5ndGhdO1xufTtcblxuLyoqXG4gKiBjcmVhdGUgYW4gaW5mZXJlbmNlIHNlc3Npb24gZnJvbSBhIG1vZGVsIGRhdGEgYnVmZmVyLlxuICpcbiAqIEBwYXJhbSBtb2RlbERhdGEgLSBlaXRoZXIgYSBVaW50OEFycmF5IG9iamVjdCByZXByZXNlbnRpbmcgdGhlIG1vZGVsIGRhdGEsIG9yIGEgMi1lbGVtZW50cyB0dXBsZSBjb250YWluaW5nIHRoZVxuICogICAgIHBvaW50ZXIgYW5kIHNpemUgb2YgdGhlIG1vZGVsIGRhdGEgYnVmZmVyLlxuICogQHBhcmFtIG9wdGlvbnMgYW4gb3B0aW9uYWwgc2Vzc2lvbiBvcHRpb25zIG9iamVjdC5cbiAqIEByZXR1cm5zIGEgMy1lbGVtZW50cyB0dXBsZSBjb250YWluaW5nIFtzZXNzaW9uIGhhbmRsZSwgaW5wdXQgbmFtZXMsIG91dHB1dCBuYW1lc11cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVNlc3Npb24gPSBhc3luYyAoXG4gIG1vZGVsRGF0YTogVWludDhBcnJheSB8IFNlcmlhbGl6YWJsZUludGVybmFsQnVmZmVyLFxuICBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyxcbik6IFByb21pc2U8U2VyaWFsaXphYmxlU2Vzc2lvbk1ldGFkYXRhPiA9PiB7XG4gIGxldCBtb2RlbERhdGFPZmZzZXQ6IG51bWJlciwgbW9kZWxEYXRhTGVuZ3RoOiBudW1iZXI7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuXG4gIGlmIChBcnJheS5pc0FycmF5KG1vZGVsRGF0YSkpIHtcbiAgICAvLyBpZiBtb2RlbCBkYXRhIGlzIGFuIGFycmF5LCBpdCBtdXN0IGJlIGEgMi1lbGVtZW50cyB0dXBsZSBjb250YWluaW5nIHRoZSBwb2ludGVyIGFuZCBzaXplIG9mIHRoZSBtb2RlbCBkYXRhXG4gICAgW21vZGVsRGF0YU9mZnNldCwgbW9kZWxEYXRhTGVuZ3RoXSA9IG1vZGVsRGF0YTtcbiAgfSBlbHNlIGlmIChtb2RlbERhdGEuYnVmZmVyID09PSB3YXNtLkhFQVBVOC5idWZmZXIpIHtcbiAgICAvLyBpZiBtb2RlbCBkYXRhIHVzZXMgdGhlIHNhbWUgYnVmZmVyIGFzIHRoZSBXQVNNIGhlYXAsIHdlIGRvbid0IG5lZWQgdG8gY29weSBpdC5cbiAgICBbbW9kZWxEYXRhT2Zmc2V0LCBtb2RlbERhdGFMZW5ndGhdID0gW21vZGVsRGF0YS5ieXRlT2Zmc2V0LCBtb2RlbERhdGEuYnl0ZUxlbmd0aF07XG4gIH0gZWxzZSB7XG4gICAgLy8gb3RoZXJ3aXNlLCBjb3B5IHRoZSBtb2RlbCBkYXRhIHRvIHRoZSBXQVNNIGhlYXAuXG4gICAgW21vZGVsRGF0YU9mZnNldCwgbW9kZWxEYXRhTGVuZ3RoXSA9IGNvcHlGcm9tRXh0ZXJuYWxCdWZmZXIobW9kZWxEYXRhKTtcbiAgfVxuXG4gIGxldCBzZXNzaW9uSGFuZGxlID0gMDtcbiAgbGV0IHNlc3Npb25PcHRpb25zSGFuZGxlID0gMDtcbiAgbGV0IGlvQmluZGluZ0hhbmRsZSA9IDA7XG4gIGxldCBhbGxvY3M6IG51bWJlcltdID0gW107XG4gIGNvbnN0IGlucHV0TmFtZXNVVEY4RW5jb2RlZCA9IFtdO1xuICBjb25zdCBvdXRwdXROYW1lc1VURjhFbmNvZGVkID0gW107XG5cbiAgdHJ5IHtcbiAgICBbc2Vzc2lvbk9wdGlvbnNIYW5kbGUsIGFsbG9jc10gPSBhd2FpdCBzZXRTZXNzaW9uT3B0aW9ucyhvcHRpb25zKTtcblxuICAgIGlmIChvcHRpb25zPy5leHRlcm5hbERhdGEgJiYgd2FzbS5tb3VudEV4dGVybmFsRGF0YSkge1xuICAgICAgY29uc3QgbG9hZGluZ1Byb21pc2VzID0gW107XG4gICAgICBmb3IgKGNvbnN0IGZpbGUgb2Ygb3B0aW9ucy5leHRlcm5hbERhdGEpIHtcbiAgICAgICAgY29uc3QgcGF0aCA9IHR5cGVvZiBmaWxlID09PSAnc3RyaW5nJyA/IGZpbGUgOiBmaWxlLnBhdGg7XG4gICAgICAgIGxvYWRpbmdQcm9taXNlcy5wdXNoKFxuICAgICAgICAgIGxvYWRGaWxlKHR5cGVvZiBmaWxlID09PSAnc3RyaW5nJyA/IGZpbGUgOiBmaWxlLmRhdGEpLnRoZW4oKGRhdGEpID0+IHtcbiAgICAgICAgICAgIHdhc20ubW91bnRFeHRlcm5hbERhdGEocGF0aCwgZGF0YSk7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIHdhaXQgZm9yIGFsbCBleHRlcm5hbCBkYXRhIGZpbGVzIHRvIGJlIGxvYWRlZFxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwobG9hZGluZ1Byb21pc2VzKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHByb3ZpZGVyIG9mIG9wdGlvbnM/LmV4ZWN1dGlvblByb3ZpZGVycyA/PyBbXSkge1xuICAgICAgY29uc3QgcHJvdmlkZXJOYW1lID0gdHlwZW9mIHByb3ZpZGVyID09PSAnc3RyaW5nJyA/IHByb3ZpZGVyIDogcHJvdmlkZXIubmFtZTtcbiAgICAgIGlmIChwcm92aWRlck5hbWUgPT09ICd3ZWJubicpIHtcbiAgICAgICAgd2FzbS5zaG91bGRUcmFuc2ZlclRvTUxUZW5zb3IgPSBmYWxzZTtcbiAgICAgICAgaWYgKHR5cGVvZiBwcm92aWRlciAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBjb25zdCB3ZWJubk9wdGlvbnMgPSBwcm92aWRlciBhcyBJbmZlcmVuY2VTZXNzaW9uLldlYk5ORXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgICAgICAgY29uc3QgY29udGV4dCA9ICh3ZWJubk9wdGlvbnMgYXMgSW5mZXJlbmNlU2Vzc2lvbi5XZWJOTk9wdGlvbnNXaXRoTUxDb250ZXh0KT8uY29udGV4dDtcbiAgICAgICAgICBjb25zdCBncHVEZXZpY2UgPSAod2Vibm5PcHRpb25zIGFzIEluZmVyZW5jZVNlc3Npb24uV2ViTk5PcHRpb25zV2ViR3B1KT8uZ3B1RGV2aWNlO1xuICAgICAgICAgIGNvbnN0IGRldmljZVR5cGUgPSAod2Vibm5PcHRpb25zIGFzIEluZmVyZW5jZVNlc3Npb24uV2ViTk5Db250ZXh0T3B0aW9ucyk/LmRldmljZVR5cGU7XG4gICAgICAgICAgY29uc3QgcG93ZXJQcmVmZXJlbmNlID0gKHdlYm5uT3B0aW9ucyBhcyBJbmZlcmVuY2VTZXNzaW9uLldlYk5OQ29udGV4dE9wdGlvbnMpPy5wb3dlclByZWZlcmVuY2U7XG4gICAgICAgICAgaWYgKGNvbnRleHQpIHtcbiAgICAgICAgICAgIHdhc20uY3VycmVudENvbnRleHQgPSBjb250ZXh0IGFzIE1MQ29udGV4dDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGdwdURldmljZSkge1xuICAgICAgICAgICAgd2FzbS5jdXJyZW50Q29udGV4dCA9IGF3YWl0IHdhc20ud2Vibm5DcmVhdGVNTENvbnRleHQhKGdwdURldmljZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdhc20uY3VycmVudENvbnRleHQgPSBhd2FpdCB3YXNtLndlYm5uQ3JlYXRlTUxDb250ZXh0ISh7IGRldmljZVR5cGUsIHBvd2VyUHJlZmVyZW5jZSB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgd2FzbS5jdXJyZW50Q29udGV4dCA9IGF3YWl0IHdhc20ud2Vibm5DcmVhdGVNTENvbnRleHQhKCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc2Vzc2lvbkhhbmRsZSA9IGF3YWl0IHdhc20uX09ydENyZWF0ZVNlc3Npb24obW9kZWxEYXRhT2Zmc2V0LCBtb2RlbERhdGFMZW5ndGgsIHNlc3Npb25PcHRpb25zSGFuZGxlKTtcbiAgICB3YXNtLndlYmdwdU9uQ3JlYXRlU2Vzc2lvbj8uKHNlc3Npb25IYW5kbGUpO1xuICAgIGlmIChzZXNzaW9uSGFuZGxlID09PSAwKSB7XG4gICAgICBjaGVja0xhc3RFcnJvcihcIkNhbid0IGNyZWF0ZSBhIHNlc3Npb24uXCIpO1xuICAgIH1cblxuICAgIHdhc20uanNlcE9uQ3JlYXRlU2Vzc2lvbj8uKCk7XG5cbiAgICAvLyBjbGVhciBjdXJyZW50IE1MQ29udGV4dCBhZnRlciBzZXNzaW9uIGNyZWF0aW9uXG4gICAgaWYgKHdhc20uY3VycmVudENvbnRleHQpIHtcbiAgICAgIHdhc20ud2Vibm5SZWdpc3Rlck1MQ29udGV4dCEoc2Vzc2lvbkhhbmRsZSwgd2FzbS5jdXJyZW50Q29udGV4dCk7XG4gICAgICB3YXNtLmN1cnJlbnRDb250ZXh0ID0gdW5kZWZpbmVkO1xuICAgICAgd2FzbS5zaG91bGRUcmFuc2ZlclRvTUxUZW5zb3IgPSB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IFtpbnB1dENvdW50LCBvdXRwdXRDb3VudF0gPSBnZXRTZXNzaW9uSW5wdXRPdXRwdXRDb3VudChzZXNzaW9uSGFuZGxlKTtcblxuICAgIGNvbnN0IGVuYWJsZUdyYXBoQ2FwdHVyZSA9ICEhb3B0aW9ucz8uZW5hYmxlR3JhcGhDYXB0dXJlO1xuXG4gICAgY29uc3QgaW5wdXROYW1lcyA9IFtdO1xuICAgIGNvbnN0IG91dHB1dE5hbWVzID0gW107XG4gICAgY29uc3QgaW5wdXRNZXRhZGF0YTogSW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhW10gPSBbXTtcbiAgICBjb25zdCBvdXRwdXRNZXRhZGF0YTogSW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhW10gPSBbXTtcbiAgICBjb25zdCBvdXRwdXRQcmVmZXJyZWRMb2NhdGlvbnM6IFN1cHBvcnRlZFRlbnNvckRhdGFMb2NhdGlvbkZvcklucHV0T3V0cHV0W10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Q291bnQ7IGkrKykge1xuICAgICAgY29uc3QgW25hbWVPZmZzZXQsIGVsZW1lbnRUeXBlLCBzaGFwZV0gPSBnZXRTZXNzaW9uSW5wdXRPdXRwdXRNZXRhZGF0YShzZXNzaW9uSGFuZGxlLCBpKTtcbiAgICAgIGlmIChuYW1lT2Zmc2V0ID09PSAwKSB7XG4gICAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgZ2V0IGFuIGlucHV0IG5hbWUuXCIpO1xuICAgICAgfVxuICAgICAgaW5wdXROYW1lc1VURjhFbmNvZGVkLnB1c2gobmFtZU9mZnNldCk7XG4gICAgICBjb25zdCBuYW1lID0gd2FzbS5VVEY4VG9TdHJpbmcobmFtZU9mZnNldCk7XG4gICAgICBpbnB1dE5hbWVzLnB1c2gobmFtZSk7XG4gICAgICBpbnB1dE1ldGFkYXRhLnB1c2goXG4gICAgICAgIGVsZW1lbnRUeXBlID09PSAwXG4gICAgICAgICAgPyB7IG5hbWUsIGlzVGVuc29yOiBmYWxzZSB9XG4gICAgICAgICAgOiB7IG5hbWUsIGlzVGVuc29yOiB0cnVlLCB0eXBlOiB0ZW5zb3JEYXRhVHlwZUVudW1Ub1N0cmluZyhlbGVtZW50VHlwZSksIHNoYXBlOiBzaGFwZSEgfSxcbiAgICAgICk7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0Q291bnQ7IGkrKykge1xuICAgICAgY29uc3QgW25hbWVPZmZzZXQsIGVsZW1lbnRUeXBlLCBzaGFwZV0gPSBnZXRTZXNzaW9uSW5wdXRPdXRwdXRNZXRhZGF0YShzZXNzaW9uSGFuZGxlLCBpICsgaW5wdXRDb3VudCk7XG4gICAgICBpZiAobmFtZU9mZnNldCA9PT0gMCkge1xuICAgICAgICBjaGVja0xhc3RFcnJvcihcIkNhbid0IGdldCBhbiBvdXRwdXQgbmFtZS5cIik7XG4gICAgICB9XG4gICAgICBvdXRwdXROYW1lc1VURjhFbmNvZGVkLnB1c2gobmFtZU9mZnNldCk7XG4gICAgICBjb25zdCBuYW1lU3RyaW5nID0gd2FzbS5VVEY4VG9TdHJpbmcobmFtZU9mZnNldCk7XG4gICAgICBvdXRwdXROYW1lcy5wdXNoKG5hbWVTdHJpbmcpO1xuICAgICAgb3V0cHV0TWV0YWRhdGEucHVzaChcbiAgICAgICAgZWxlbWVudFR5cGUgPT09IDBcbiAgICAgICAgICA/IHsgbmFtZTogbmFtZVN0cmluZywgaXNUZW5zb3I6IGZhbHNlIH1cbiAgICAgICAgICA6IHsgbmFtZTogbmFtZVN0cmluZywgaXNUZW5zb3I6IHRydWUsIHR5cGU6IHRlbnNvckRhdGFUeXBlRW51bVRvU3RyaW5nKGVsZW1lbnRUeXBlKSwgc2hhcGU6IHNoYXBlISB9LFxuICAgICAgKTtcblxuICAgICAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfSlNFUCB8fCAhQlVJTERfREVGUy5ESVNBQkxFX1dFQkdQVSkge1xuICAgICAgICBpZiAoZW5hYmxlR3JhcGhDYXB0dXJlICYmIG9wdGlvbnM/LnByZWZlcnJlZE91dHB1dExvY2F0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBvdXRwdXRQcmVmZXJyZWRMb2NhdGlvbnMucHVzaCgnZ3B1LWJ1ZmZlcicpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxvY2F0aW9uID1cbiAgICAgICAgICB0eXBlb2Ygb3B0aW9ucz8ucHJlZmVycmVkT3V0cHV0TG9jYXRpb24gPT09ICdzdHJpbmcnXG4gICAgICAgICAgICA/IG9wdGlvbnMucHJlZmVycmVkT3V0cHV0TG9jYXRpb25cbiAgICAgICAgICAgIDogKG9wdGlvbnM/LnByZWZlcnJlZE91dHB1dExvY2F0aW9uPy5bbmFtZVN0cmluZ10gPz8gJ2NwdScpO1xuICAgICAgICBjb25zdCBpc0dyYXBoT3V0cHV0ID0gd2FzbS53ZWJubklzR3JhcGhPdXRwdXQ7XG4gICAgICAgIGlmIChsb2NhdGlvbiA9PT0gJ2NwdScgJiYgaXNHcmFwaE91dHB1dCAmJiBpc0dyYXBoT3V0cHV0KHNlc3Npb25IYW5kbGUsIG5hbWVTdHJpbmcpKSB7XG4gICAgICAgICAgb3V0cHV0UHJlZmVycmVkTG9jYXRpb25zLnB1c2goJ21sLXRlbnNvci1jcHUtb3V0cHV0Jyk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxvY2F0aW9uICE9PSAnY3B1JyAmJiBsb2NhdGlvbiAhPT0gJ2NwdS1waW5uZWQnICYmIGxvY2F0aW9uICE9PSAnZ3B1LWJ1ZmZlcicgJiYgbG9jYXRpb24gIT09ICdtbC10ZW5zb3InKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBOb3Qgc3VwcG9ydGVkIHByZWZlcnJlZCBvdXRwdXQgbG9jYXRpb246ICR7bG9jYXRpb259LmApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlbmFibGVHcmFwaENhcHR1cmUgJiYgbG9jYXRpb24gIT09ICdncHUtYnVmZmVyJykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBOb3Qgc3VwcG9ydGVkIHByZWZlcnJlZCBvdXRwdXQgbG9jYXRpb246ICR7bG9jYXRpb259LiBPbmx5ICdncHUtYnVmZmVyJyBsb2NhdGlvbiBpcyBzdXBwb3J0ZWQgd2hlbiBlbmFibGVHcmFwaENhcHR1cmUgaXMgdHJ1ZS5gLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgb3V0cHV0UHJlZmVycmVkTG9jYXRpb25zLnB1c2gobG9jYXRpb24pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHVzZSBJTyBiaW5kaW5nIG9ubHkgd2hlbiBhdCBsZWFzdCBvbmUgb3V0cHV0IGlzIHByZWZlcnJlZCB0byBiZSBvbiBHUFUuXG4gICAgbGV0IGJpbmRpbmdTdGF0ZTogSU9CaW5kaW5nU3RhdGUgfCBudWxsID0gbnVsbDtcbiAgICBpZiAoXG4gICAgICAoIUJVSUxEX0RFRlMuRElTQUJMRV9KU0VQIHx8ICFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR1BVKSAmJlxuICAgICAgb3V0cHV0UHJlZmVycmVkTG9jYXRpb25zLnNvbWUoKGwpID0+IGwgPT09ICdncHUtYnVmZmVyJyB8fCBsID09PSAnbWwtdGVuc29yJyB8fCBsID09PSAnbWwtdGVuc29yLWNwdS1vdXRwdXQnKVxuICAgICkge1xuICAgICAgaW9CaW5kaW5nSGFuZGxlID0gd2FzbS5fT3J0Q3JlYXRlQmluZGluZyhzZXNzaW9uSGFuZGxlKTtcbiAgICAgIGlmIChpb0JpbmRpbmdIYW5kbGUgPT09IDApIHtcbiAgICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCBjcmVhdGUgSU8gYmluZGluZy5cIik7XG4gICAgICB9XG5cbiAgICAgIGJpbmRpbmdTdGF0ZSA9IHtcbiAgICAgICAgaGFuZGxlOiBpb0JpbmRpbmdIYW5kbGUsXG4gICAgICAgIG91dHB1dFByZWZlcnJlZExvY2F0aW9ucyxcbiAgICAgICAgb3V0cHV0UHJlZmVycmVkTG9jYXRpb25zRW5jb2RlZDogb3V0cHV0UHJlZmVycmVkTG9jYXRpb25zXG4gICAgICAgICAgLy8gJ21sLXRlbnNvci1jcHUtb3V0cHV0JyBpcyB0cmVhdGVkIGFzICdtbC10ZW5zb3InIGZvciB0aGUgcHVycG9zZSBvZiBJTyBiaW5kaW5nLlxuICAgICAgICAgIC5tYXAoKGwpID0+IChsID09PSAnbWwtdGVuc29yLWNwdS1vdXRwdXQnID8gJ21sLXRlbnNvcicgOiBsKSlcbiAgICAgICAgICAubWFwKChsKSA9PiBkYXRhTG9jYXRpb25TdHJpbmdUb0VudW0obCkpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBhY3RpdmVTZXNzaW9ucy5zZXQoc2Vzc2lvbkhhbmRsZSwgW1xuICAgICAgc2Vzc2lvbkhhbmRsZSxcbiAgICAgIGlucHV0TmFtZXNVVEY4RW5jb2RlZCxcbiAgICAgIG91dHB1dE5hbWVzVVRGOEVuY29kZWQsXG4gICAgICBiaW5kaW5nU3RhdGUsXG4gICAgICBlbmFibGVHcmFwaENhcHR1cmUsXG4gICAgICBmYWxzZSxcbiAgICBdKTtcbiAgICByZXR1cm4gW3Nlc3Npb25IYW5kbGUsIGlucHV0TmFtZXMsIG91dHB1dE5hbWVzLCBpbnB1dE1ldGFkYXRhLCBvdXRwdXRNZXRhZGF0YV07XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpbnB1dE5hbWVzVVRGOEVuY29kZWQuZm9yRWFjaCgoYnVmKSA9PiB3YXNtLl9PcnRGcmVlKGJ1ZikpO1xuICAgIG91dHB1dE5hbWVzVVRGOEVuY29kZWQuZm9yRWFjaCgoYnVmKSA9PiB3YXNtLl9PcnRGcmVlKGJ1ZikpO1xuXG4gICAgaWYgKGlvQmluZGluZ0hhbmRsZSAhPT0gMCkge1xuICAgICAgaWYgKHdhc20uX09ydFJlbGVhc2VCaW5kaW5nKGlvQmluZGluZ0hhbmRsZSkgIT09IDApIHtcbiAgICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCByZWxlYXNlIElPIGJpbmRpbmcuXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzZXNzaW9uSGFuZGxlICE9PSAwKSB7XG4gICAgICBpZiAod2FzbS5fT3J0UmVsZWFzZVNlc3Npb24oc2Vzc2lvbkhhbmRsZSkgIT09IDApIHtcbiAgICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCByZWxlYXNlIHNlc3Npb24uXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aHJvdyBlO1xuICB9IGZpbmFsbHkge1xuICAgIHdhc20uX2ZyZWUobW9kZWxEYXRhT2Zmc2V0KTtcbiAgICBpZiAoc2Vzc2lvbk9wdGlvbnNIYW5kbGUgIT09IDApIHtcbiAgICAgIGlmICh3YXNtLl9PcnRSZWxlYXNlU2Vzc2lvbk9wdGlvbnMoc2Vzc2lvbk9wdGlvbnNIYW5kbGUpICE9PSAwKSB7XG4gICAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgcmVsZWFzZSBzZXNzaW9uIG9wdGlvbnMuXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICBhbGxvY3MuZm9yRWFjaCgoYWxsb2MpID0+IHdhc20uX2ZyZWUoYWxsb2MpKTtcblxuICAgIC8vIHVubW91bnQgZXh0ZXJuYWwgZGF0YSBpZiBuZWNlc3NhcnlcbiAgICB3YXNtLnVubW91bnRFeHRlcm5hbERhdGE/LigpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVsZWFzZVNlc3Npb24gPSAoc2Vzc2lvbklkOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgY29uc3Qgd2FzbSA9IGdldEluc3RhbmNlKCk7XG4gIGNvbnN0IHNlc3Npb24gPSBhY3RpdmVTZXNzaW9ucy5nZXQoc2Vzc2lvbklkKTtcbiAgaWYgKCFzZXNzaW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgcmVsZWFzZSBzZXNzaW9uLiBpbnZhbGlkIHNlc3Npb24gaWQ6ICR7c2Vzc2lvbklkfWApO1xuICB9XG4gIGNvbnN0IFtzZXNzaW9uSGFuZGxlLCBpbnB1dE5hbWVzVVRGOEVuY29kZWQsIG91dHB1dE5hbWVzVVRGOEVuY29kZWQsIGlvQmluZGluZ1N0YXRlLCBlbmFibGVHcmFwaENhcHR1cmVdID0gc2Vzc2lvbjtcblxuICBpZiAoaW9CaW5kaW5nU3RhdGUpIHtcbiAgICBpZiAoZW5hYmxlR3JhcGhDYXB0dXJlKSB7XG4gICAgICBpZiAod2FzbS5fT3J0Q2xlYXJCb3VuZE91dHB1dHMoaW9CaW5kaW5nU3RhdGUuaGFuZGxlKSAhPT0gMCkge1xuICAgICAgICBjaGVja0xhc3RFcnJvcihcIkNhbid0IGNsZWFyIGJvdW5kIG91dHB1dHMuXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAod2FzbS5fT3J0UmVsZWFzZUJpbmRpbmcoaW9CaW5kaW5nU3RhdGUuaGFuZGxlKSAhPT0gMCkge1xuICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCByZWxlYXNlIElPIGJpbmRpbmcuXCIpO1xuICAgIH1cbiAgfVxuXG4gIHdhc20uanNlcE9uUmVsZWFzZVNlc3Npb24/LihzZXNzaW9uSWQpO1xuICB3YXNtLndlYm5uT25SZWxlYXNlU2Vzc2lvbj8uKHNlc3Npb25JZCk7XG4gIHdhc20ud2ViZ3B1T25SZWxlYXNlU2Vzc2lvbj8uKHNlc3Npb25JZCk7XG5cbiAgaW5wdXROYW1lc1VURjhFbmNvZGVkLmZvckVhY2goKGJ1ZikgPT4gd2FzbS5fT3J0RnJlZShidWYpKTtcbiAgb3V0cHV0TmFtZXNVVEY4RW5jb2RlZC5mb3JFYWNoKChidWYpID0+IHdhc20uX09ydEZyZWUoYnVmKSk7XG4gIGlmICh3YXNtLl9PcnRSZWxlYXNlU2Vzc2lvbihzZXNzaW9uSGFuZGxlKSAhPT0gMCkge1xuICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgcmVsZWFzZSBzZXNzaW9uLlwiKTtcbiAgfVxuICBhY3RpdmVTZXNzaW9ucy5kZWxldGUoc2Vzc2lvbklkKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwcmVwYXJlSW5wdXRPdXRwdXRUZW5zb3IgPSBhc3luYyAoXG4gIHRlbnNvcjogVGVuc29yTWV0YWRhdGEgfCBudWxsLFxuICB0ZW5zb3JIYW5kbGVzOiBudW1iZXJbXSxcbiAgYWxsb2NzOiBudW1iZXJbXSxcbiAgc2Vzc2lvbklkOiBudW1iZXIsXG4gIHRlbnNvck5hbWVVVEY4RW5jb2RlZDogbnVtYmVyLFxuICBpbmRleDogbnVtYmVyLFxuICBlbmFibGVHcmFwaENhcHR1cmUgPSBmYWxzZSxcbik6IFByb21pc2U8dm9pZD4gPT4ge1xuICBpZiAoIXRlbnNvcikge1xuICAgIHRlbnNvckhhbmRsZXMucHVzaCgwKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB3YXNtID0gZ2V0SW5zdGFuY2UoKTtcbiAgY29uc3QgcHRyU2l6ZSA9IHdhc20uUFRSX1NJWkU7XG5cbiAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JbMF07XG4gIGNvbnN0IGRpbXMgPSB0ZW5zb3JbMV07XG4gIGNvbnN0IGxvY2F0aW9uID0gdGVuc29yWzNdO1xuICBsZXQgYWN0dWFsTG9jYXRpb24gPSBsb2NhdGlvbjtcblxuICBsZXQgcmF3RGF0YTogbnVtYmVyO1xuICBsZXQgZGF0YUJ5dGVMZW5ndGg6IG51bWJlcjtcblxuICBpZiAoZGF0YVR5cGUgPT09ICdzdHJpbmcnICYmIChsb2NhdGlvbiA9PT0gJ2dwdS1idWZmZXInIHx8IGxvY2F0aW9uID09PSAnbWwtdGVuc29yJykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1N0cmluZyB0ZW5zb3IgaXMgbm90IHN1cHBvcnRlZCBvbiBHUFUuJyk7XG4gIH1cblxuICBpZiAoZW5hYmxlR3JhcGhDYXB0dXJlICYmIGxvY2F0aW9uICE9PSAnZ3B1LWJ1ZmZlcicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRXh0ZXJuYWwgYnVmZmVyIG11c3QgYmUgcHJvdmlkZWQgZm9yIGlucHV0L291dHB1dCBpbmRleCAke2luZGV4fSB3aGVuIGVuYWJsZUdyYXBoQ2FwdHVyZSBpcyB0cnVlLmAsXG4gICAgKTtcbiAgfVxuXG4gIGlmIChsb2NhdGlvbiA9PT0gJ2dwdS1idWZmZXInKSB7XG4gICAgY29uc3QgZ3B1QnVmZmVyID0gdGVuc29yWzJdLmdwdUJ1ZmZlcjtcbiAgICBkYXRhQnl0ZUxlbmd0aCA9IGNhbGN1bGF0ZVRlbnNvclNpemVJbkJ5dGVzKHRlbnNvckRhdGFUeXBlU3RyaW5nVG9FbnVtKGRhdGFUeXBlKSwgZGltcykhO1xuXG4gICAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR1BVKSB7XG4gICAgICBjb25zdCByZWdpc3RlckJ1ZmZlciA9IHdhc20ud2ViZ3B1UmVnaXN0ZXJCdWZmZXI7XG4gICAgICBpZiAoIXJlZ2lzdGVyQnVmZmVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGVuc29yIGxvY2F0aW9uIFwiZ3B1LWJ1ZmZlclwiIGlzIG5vdCBzdXBwb3J0ZWQgd2l0aG91dCB1c2luZyBXZWJHUFUuJyk7XG4gICAgICB9XG5cbiAgICAgIHJhd0RhdGEgPSByZWdpc3RlckJ1ZmZlcihncHVCdWZmZXIsIHNlc3Npb25JZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHJlZ2lzdGVyQnVmZmVyID0gd2FzbS5qc2VwUmVnaXN0ZXJCdWZmZXI7XG4gICAgICBpZiAoIXJlZ2lzdGVyQnVmZmVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGVuc29yIGxvY2F0aW9uIFwiZ3B1LWJ1ZmZlclwiIGlzIG5vdCBzdXBwb3J0ZWQgd2l0aG91dCB1c2luZyBXZWJHUFUuJyk7XG4gICAgICB9XG4gICAgICByYXdEYXRhID0gcmVnaXN0ZXJCdWZmZXIoc2Vzc2lvbklkLCBpbmRleCwgZ3B1QnVmZmVyLCBkYXRhQnl0ZUxlbmd0aCk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGxvY2F0aW9uID09PSAnbWwtdGVuc29yJykge1xuICAgIGNvbnN0IG1sVGVuc29yID0gdGVuc29yWzJdLm1sVGVuc29yIGFzIE1MVGVuc29yO1xuICAgIGRhdGFCeXRlTGVuZ3RoID0gY2FsY3VsYXRlVGVuc29yU2l6ZUluQnl0ZXModGVuc29yRGF0YVR5cGVTdHJpbmdUb0VudW0oZGF0YVR5cGUpLCBkaW1zKSE7XG5cbiAgICBjb25zdCByZWdpc3Rlck1MVGVuc29yID0gd2FzbS53ZWJublJlZ2lzdGVyTUxUZW5zb3I7XG4gICAgaWYgKCFyZWdpc3Rlck1MVGVuc29yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RlbnNvciBsb2NhdGlvbiBcIm1sLXRlbnNvclwiIGlzIG5vdCBzdXBwb3J0ZWQgd2l0aG91dCB1c2luZyBXZWJOTi4nKTtcbiAgICB9XG4gICAgcmF3RGF0YSA9IHJlZ2lzdGVyTUxUZW5zb3Ioc2Vzc2lvbklkLCBtbFRlbnNvciwgdGVuc29yRGF0YVR5cGVTdHJpbmdUb0VudW0oZGF0YVR5cGUpLCBkaW1zKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBkYXRhID0gdGVuc29yWzJdO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIC8vIHN0cmluZyB0ZW5zb3JcbiAgICAgIGRhdGFCeXRlTGVuZ3RoID0gcHRyU2l6ZSAqIGRhdGEubGVuZ3RoO1xuICAgICAgcmF3RGF0YSA9IHdhc20uX21hbGxvYyhkYXRhQnl0ZUxlbmd0aCk7XG4gICAgICBhbGxvY3MucHVzaChyYXdEYXRhKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAodHlwZW9mIGRhdGFbaV0gIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdGVuc29yIGRhdGEgYXQgaW5kZXggJHtpfSBpcyBub3QgYSBzdHJpbmdgKTtcbiAgICAgICAgfVxuICAgICAgICB3YXNtLnNldFZhbHVlKHJhd0RhdGEgKyBpICogcHRyU2l6ZSwgYWxsb2NXYXNtU3RyaW5nKGRhdGFbaV0sIGFsbG9jcyksICcqJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGlzR3JhcGhJbnB1dCA9IHdhc20ud2Vibm5Jc0dyYXBoSW5wdXQ7XG4gICAgICBjb25zdCBpc0dyYXBoT3V0cHV0ID0gd2FzbS53ZWJubklzR3JhcGhPdXRwdXQ7XG4gICAgICBpZiAoZGF0YVR5cGUgIT09ICdzdHJpbmcnICYmIGlzR3JhcGhJbnB1dCAmJiBpc0dyYXBoT3V0cHV0KSB7XG4gICAgICAgIGNvbnN0IHRlbnNvck5hbWUgPSB3YXNtLlVURjhUb1N0cmluZyh0ZW5zb3JOYW1lVVRGOEVuY29kZWQpO1xuICAgICAgICAvLyBQcm9tb3RlIHRoZSB0ZW5zb3IgdG8gJ21sLXRlbnNvcicgaWYgaXQgaXMgYSBncmFwaCBpbnB1dC5cbiAgICAgICAgaWYgKGlzR3JhcGhJbnB1dChzZXNzaW9uSWQsIHRlbnNvck5hbWUpIHx8IGlzR3JhcGhPdXRwdXQoc2Vzc2lvbklkLCB0ZW5zb3JOYW1lKSkge1xuICAgICAgICAgIGNvbnN0IGRhdGFUeXBlRW51bSA9IHRlbnNvckRhdGFUeXBlU3RyaW5nVG9FbnVtKGRhdGFUeXBlKTtcbiAgICAgICAgICBkYXRhQnl0ZUxlbmd0aCA9IGNhbGN1bGF0ZVRlbnNvclNpemVJbkJ5dGVzKGRhdGFUeXBlRW51bSwgZGltcykhO1xuICAgICAgICAgIGFjdHVhbExvY2F0aW9uID0gJ21sLXRlbnNvcic7XG4gICAgICAgICAgY29uc3QgY3JlYXRlVGVtcG9yYXJ5VGVuc29yID0gd2FzbS53ZWJubkNyZWF0ZVRlbXBvcmFyeVRlbnNvcjtcbiAgICAgICAgICBjb25zdCB1cGxvYWRUZW5zb3IgPSB3YXNtLndlYm5uVXBsb2FkVGVuc29yO1xuICAgICAgICAgIGlmICghY3JlYXRlVGVtcG9yYXJ5VGVuc29yIHx8ICF1cGxvYWRUZW5zb3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGVuc29yIGxvY2F0aW9uIFwibWwtdGVuc29yXCIgaXMgbm90IHN1cHBvcnRlZCB3aXRob3V0IHVzaW5nIFdlYk5OLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB0ZW5zb3JJZCA9IGF3YWl0IGNyZWF0ZVRlbXBvcmFyeVRlbnNvcihzZXNzaW9uSWQsIGRhdGFUeXBlRW51bSwgZGltcyBhcyBudW1iZXJbXSk7XG4gICAgICAgICAgdXBsb2FkVGVuc29yKHRlbnNvcklkLCBuZXcgVWludDhBcnJheShkYXRhLmJ1ZmZlciwgZGF0YS5ieXRlT2Zmc2V0LCBkYXRhLmJ5dGVMZW5ndGgpKTtcbiAgICAgICAgICByYXdEYXRhID0gdGVuc29ySWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGF0YUJ5dGVMZW5ndGggPSBkYXRhLmJ5dGVMZW5ndGg7XG4gICAgICAgICAgcmF3RGF0YSA9IHdhc20uX21hbGxvYyhkYXRhQnl0ZUxlbmd0aCk7XG4gICAgICAgICAgYWxsb2NzLnB1c2gocmF3RGF0YSk7XG4gICAgICAgICAgd2FzbS5IRUFQVTguc2V0KG5ldyBVaW50OEFycmF5KGRhdGEuYnVmZmVyLCBkYXRhLmJ5dGVPZmZzZXQsIGRhdGFCeXRlTGVuZ3RoKSwgcmF3RGF0YSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRhdGFCeXRlTGVuZ3RoID0gZGF0YS5ieXRlTGVuZ3RoO1xuICAgICAgICByYXdEYXRhID0gd2FzbS5fbWFsbG9jKGRhdGFCeXRlTGVuZ3RoKTtcbiAgICAgICAgYWxsb2NzLnB1c2gocmF3RGF0YSk7XG4gICAgICAgIHdhc20uSEVBUFU4LnNldChuZXcgVWludDhBcnJheShkYXRhLmJ1ZmZlciwgZGF0YS5ieXRlT2Zmc2V0LCBkYXRhQnl0ZUxlbmd0aCksIHJhd0RhdGEpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHN0YWNrID0gd2FzbS5zdGFja1NhdmUoKTtcbiAgY29uc3QgZGltc09mZnNldCA9IHdhc20uc3RhY2tBbGxvYyg0ICogZGltcy5sZW5ndGgpO1xuICB0cnkge1xuICAgIGRpbXMuZm9yRWFjaCgoZCwgaW5kZXgpID0+IHdhc20uc2V0VmFsdWUoZGltc09mZnNldCArIGluZGV4ICogcHRyU2l6ZSwgZCwgcHRyU2l6ZSA9PT0gNCA/ICdpMzInIDogJ2k2NCcpKTtcbiAgICBjb25zdCB0ZW5zb3IgPSB3YXNtLl9PcnRDcmVhdGVUZW5zb3IoXG4gICAgICB0ZW5zb3JEYXRhVHlwZVN0cmluZ1RvRW51bShkYXRhVHlwZSksXG4gICAgICByYXdEYXRhLFxuICAgICAgZGF0YUJ5dGVMZW5ndGgsXG4gICAgICBkaW1zT2Zmc2V0LFxuICAgICAgZGltcy5sZW5ndGgsXG4gICAgICBkYXRhTG9jYXRpb25TdHJpbmdUb0VudW0oYWN0dWFsTG9jYXRpb24pLFxuICAgICk7XG4gICAgaWYgKHRlbnNvciA9PT0gMCkge1xuICAgICAgY2hlY2tMYXN0RXJyb3IoYENhbid0IGNyZWF0ZSB0ZW5zb3IgZm9yIGlucHV0L291dHB1dC4gc2Vzc2lvbj0ke3Nlc3Npb25JZH0sIGluZGV4PSR7aW5kZXh9LmApO1xuICAgIH1cbiAgICB0ZW5zb3JIYW5kbGVzLnB1c2godGVuc29yKTtcbiAgfSBmaW5hbGx5IHtcbiAgICB3YXNtLnN0YWNrUmVzdG9yZShzdGFjayk7XG4gIH1cbn07XG5cbi8qKlxuICogcGVyZm9ybSBpbmZlcmVuY2UgcnVuXG4gKi9cbmV4cG9ydCBjb25zdCBydW4gPSBhc3luYyAoXG4gIHNlc3Npb25JZDogbnVtYmVyLFxuICBpbnB1dEluZGljZXM6IG51bWJlcltdLFxuICBpbnB1dFRlbnNvcnM6IFRlbnNvck1ldGFkYXRhW10sXG4gIG91dHB1dEluZGljZXM6IG51bWJlcltdLFxuICBvdXRwdXRUZW5zb3JzOiBBcnJheTxUZW5zb3JNZXRhZGF0YSB8IG51bGw+LFxuICBvcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMsXG4pOiBQcm9taXNlPFRlbnNvck1ldGFkYXRhW10+ID0+IHtcbiAgY29uc3Qgd2FzbSA9IGdldEluc3RhbmNlKCk7XG4gIGNvbnN0IHB0clNpemUgPSB3YXNtLlBUUl9TSVpFO1xuICBjb25zdCBzZXNzaW9uID0gYWN0aXZlU2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XG4gIGlmICghc2Vzc2lvbikge1xuICAgIHRocm93IG5ldyBFcnJvcihgY2Fubm90IHJ1biBpbmZlcmVuY2UuIGludmFsaWQgc2Vzc2lvbiBpZDogJHtzZXNzaW9uSWR9YCk7XG4gIH1cbiAgY29uc3Qgc2Vzc2lvbkhhbmRsZSA9IHNlc3Npb25bMF07XG4gIGNvbnN0IGlucHV0TmFtZXNVVEY4RW5jb2RlZCA9IHNlc3Npb25bMV07XG4gIGNvbnN0IG91dHB1dE5hbWVzVVRGOEVuY29kZWQgPSBzZXNzaW9uWzJdO1xuICBjb25zdCBpb0JpbmRpbmdTdGF0ZSA9IHNlc3Npb25bM107XG4gIGNvbnN0IGVuYWJsZUdyYXBoQ2FwdHVyZSA9IHNlc3Npb25bNF07XG4gIGNvbnN0IGlucHV0T3V0cHV0Qm91bmQgPSBzZXNzaW9uWzVdO1xuXG4gIGNvbnN0IGlucHV0Q291bnQgPSBpbnB1dEluZGljZXMubGVuZ3RoO1xuICBjb25zdCBvdXRwdXRDb3VudCA9IG91dHB1dEluZGljZXMubGVuZ3RoO1xuXG4gIGxldCBydW5PcHRpb25zSGFuZGxlID0gMDtcbiAgbGV0IHJ1bk9wdGlvbnNBbGxvY3M6IG51bWJlcltdID0gW107XG5cbiAgY29uc3QgaW5wdXRUZW5zb3JIYW5kbGVzOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBvdXRwdXRUZW5zb3JIYW5kbGVzOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBpbnB1dE91dHB1dEFsbG9jczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgcHJlQWxsb2NhdGVkT3V0cHV0czogbnVtYmVyW10gPSBbXTtcblxuICBjb25zdCBiZWZvcmVSdW5TdGFjayA9IHdhc20uc3RhY2tTYXZlKCk7XG4gIGNvbnN0IGlucHV0VmFsdWVzT2Zmc2V0ID0gd2FzbS5zdGFja0FsbG9jKGlucHV0Q291bnQgKiBwdHJTaXplKTtcbiAgY29uc3QgaW5wdXROYW1lc09mZnNldCA9IHdhc20uc3RhY2tBbGxvYyhpbnB1dENvdW50ICogcHRyU2l6ZSk7XG4gIGNvbnN0IG91dHB1dFZhbHVlc09mZnNldCA9IHdhc20uc3RhY2tBbGxvYyhvdXRwdXRDb3VudCAqIHB0clNpemUpO1xuICBjb25zdCBvdXRwdXROYW1lc09mZnNldCA9IHdhc20uc3RhY2tBbGxvYyhvdXRwdXRDb3VudCAqIHB0clNpemUpO1xuXG4gIHRyeSB7XG4gICAgW3J1bk9wdGlvbnNIYW5kbGUsIHJ1bk9wdGlvbnNBbGxvY3NdID0gc2V0UnVuT3B0aW9ucyhvcHRpb25zKTtcblxuICAgIFRSQUNFX0VWRU5UX0JFR0lOKCd3YXNtIHByZXBhcmVJbnB1dE91dHB1dFRlbnNvcicpO1xuICAgIC8vIGNyZWF0ZSBpbnB1dCB0ZW5zb3JzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dENvdW50OyBpKyspIHtcbiAgICAgIGF3YWl0IHByZXBhcmVJbnB1dE91dHB1dFRlbnNvcihcbiAgICAgICAgaW5wdXRUZW5zb3JzW2ldLFxuICAgICAgICBpbnB1dFRlbnNvckhhbmRsZXMsXG4gICAgICAgIGlucHV0T3V0cHV0QWxsb2NzLFxuICAgICAgICBzZXNzaW9uSWQsXG4gICAgICAgIGlucHV0TmFtZXNVVEY4RW5jb2RlZFtpbnB1dEluZGljZXNbaV1dLFxuICAgICAgICBpbnB1dEluZGljZXNbaV0sXG4gICAgICAgIGVuYWJsZUdyYXBoQ2FwdHVyZSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gY3JlYXRlIG91dHB1dCB0ZW5zb3JzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRDb3VudDsgaSsrKSB7XG4gICAgICBhd2FpdCBwcmVwYXJlSW5wdXRPdXRwdXRUZW5zb3IoXG4gICAgICAgIG91dHB1dFRlbnNvcnNbaV0sXG4gICAgICAgIG91dHB1dFRlbnNvckhhbmRsZXMsXG4gICAgICAgIGlucHV0T3V0cHV0QWxsb2NzLFxuICAgICAgICBzZXNzaW9uSWQsXG4gICAgICAgIG91dHB1dE5hbWVzVVRGOEVuY29kZWRbb3V0cHV0SW5kaWNlc1tpXV0sXG4gICAgICAgIGlucHV0Q291bnQgKyBvdXRwdXRJbmRpY2VzW2ldLFxuICAgICAgICBlbmFibGVHcmFwaENhcHR1cmUsXG4gICAgICApO1xuICAgIH1cbiAgICBUUkFDRV9FVkVOVF9FTkQoJ3dhc20gcHJlcGFyZUlucHV0T3V0cHV0VGVuc29yJyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Q291bnQ7IGkrKykge1xuICAgICAgd2FzbS5zZXRWYWx1ZShpbnB1dFZhbHVlc09mZnNldCArIGkgKiBwdHJTaXplLCBpbnB1dFRlbnNvckhhbmRsZXNbaV0sICcqJyk7XG4gICAgICB3YXNtLnNldFZhbHVlKGlucHV0TmFtZXNPZmZzZXQgKyBpICogcHRyU2l6ZSwgaW5wdXROYW1lc1VURjhFbmNvZGVkW2lucHV0SW5kaWNlc1tpXV0sICcqJyk7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0Q291bnQ7IGkrKykge1xuICAgICAgd2FzbS5zZXRWYWx1ZShvdXRwdXRWYWx1ZXNPZmZzZXQgKyBpICogcHRyU2l6ZSwgb3V0cHV0VGVuc29ySGFuZGxlc1tpXSwgJyonKTtcbiAgICAgIHdhc20uc2V0VmFsdWUob3V0cHV0TmFtZXNPZmZzZXQgKyBpICogcHRyU2l6ZSwgb3V0cHV0TmFtZXNVVEY4RW5jb2RlZFtvdXRwdXRJbmRpY2VzW2ldXSwgJyonKTtcbiAgICB9XG5cbiAgICBpZiAoKCFCVUlMRF9ERUZTLkRJU0FCTEVfSlNFUCB8fCAhQlVJTERfREVGUy5ESVNBQkxFX1dFQkdQVSkgJiYgaW9CaW5kaW5nU3RhdGUgJiYgIWlucHV0T3V0cHV0Qm91bmQpIHtcbiAgICAgIGNvbnN0IHsgaGFuZGxlLCBvdXRwdXRQcmVmZXJyZWRMb2NhdGlvbnMsIG91dHB1dFByZWZlcnJlZExvY2F0aW9uc0VuY29kZWQgfSA9IGlvQmluZGluZ1N0YXRlO1xuXG4gICAgICBpZiAoaW5wdXROYW1lc1VURjhFbmNvZGVkLmxlbmd0aCAhPT0gaW5wdXRDb3VudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYGlucHV0IGNvdW50IGZyb20gZmVlZHMgKCR7aW5wdXRDb3VudH0pIGlzIGV4cGVjdGVkIHRvIGJlIGFsd2F5cyBlcXVhbCB0byBtb2RlbCdzIGlucHV0IGNvdW50ICgke2lucHV0TmFtZXNVVEY4RW5jb2RlZC5sZW5ndGh9KS5gLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBUUkFDRV9FVkVOVF9CRUdJTignd2FzbSBiaW5kSW5wdXRzT3V0cHV0cycpO1xuICAgICAgLy8gcHJvY2VzcyBpbnB1dHNcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRDb3VudDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gaW5wdXRJbmRpY2VzW2ldO1xuICAgICAgICBjb25zdCBlcnJvckNvZGUgPSBhd2FpdCB3YXNtLl9PcnRCaW5kSW5wdXQoaGFuZGxlLCBpbnB1dE5hbWVzVVRGOEVuY29kZWRbaW5kZXhdLCBpbnB1dFRlbnNvckhhbmRsZXNbaV0pO1xuICAgICAgICBpZiAoZXJyb3JDb2RlICE9PSAwKSB7XG4gICAgICAgICAgY2hlY2tMYXN0RXJyb3IoYENhbid0IGJpbmQgaW5wdXRbJHtpfV0gZm9yIHNlc3Npb249JHtzZXNzaW9uSWR9LmApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHByb2Nlc3MgcHJlLWFsbG9jYXRlZCBvdXRwdXRzXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dHB1dENvdW50OyBpKyspIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBvdXRwdXRJbmRpY2VzW2ldO1xuICAgICAgICBjb25zdCBsb2NhdGlvbiA9IG91dHB1dFRlbnNvcnNbaV0/LlszXTsgLy8gdW5kZWZpbmVkIG1lYW5zIG91dHB1dCBpcyBub3QgcHJlLWFsbG9jYXRlZC5cblxuICAgICAgICBpZiAobG9jYXRpb24pIHtcbiAgICAgICAgICAvLyBvdXRwdXQgaXMgcHJlLWFsbG9jYXRlZCwgc3RvcmUgYW5kIGJpbmQgdGhlIHRlbnNvci5cbiAgICAgICAgICBwcmVBbGxvY2F0ZWRPdXRwdXRzLnB1c2gob3V0cHV0VGVuc29ySGFuZGxlc1tpXSk7XG4gICAgICAgICAgY29uc3QgZXJyb3JDb2RlID0gd2FzbS5fT3J0QmluZE91dHB1dChoYW5kbGUsIG91dHB1dE5hbWVzVVRGOEVuY29kZWRbaW5kZXhdLCBvdXRwdXRUZW5zb3JIYW5kbGVzW2ldLCAwKTtcbiAgICAgICAgICBpZiAoZXJyb3JDb2RlICE9PSAwKSB7XG4gICAgICAgICAgICBjaGVja0xhc3RFcnJvcihgQ2FuJ3QgYmluZCBwcmUtYWxsb2NhdGVkIG91dHB1dFske2l9XSBmb3Igc2Vzc2lvbj0ke3Nlc3Npb25JZH0uYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIG91dHB1dCBpcyBub3QgcHJlLWFsbG9jYXRlZC4gcmVzZXQgcHJlZmVycmVkIGxvY2F0aW9uLlxuICAgICAgICAgIGNvbnN0IGVycm9yQ29kZSA9IHdhc20uX09ydEJpbmRPdXRwdXQoXG4gICAgICAgICAgICBoYW5kbGUsXG4gICAgICAgICAgICBvdXRwdXROYW1lc1VURjhFbmNvZGVkW2luZGV4XSxcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICBvdXRwdXRQcmVmZXJyZWRMb2NhdGlvbnNFbmNvZGVkW2luZGV4XSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChlcnJvckNvZGUgIT09IDApIHtcbiAgICAgICAgICAgIGNoZWNrTGFzdEVycm9yKGBDYW4ndCBiaW5kIG91dHB1dFske2l9XSB0byAke291dHB1dFByZWZlcnJlZExvY2F0aW9uc1tpXX0gZm9yIHNlc3Npb249JHtzZXNzaW9uSWR9LmApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgVFJBQ0VfRVZFTlRfRU5EKCd3YXNtIGJpbmRJbnB1dHNPdXRwdXRzJyk7XG4gICAgICBhY3RpdmVTZXNzaW9ucy5zZXQoc2Vzc2lvbklkLCBbXG4gICAgICAgIHNlc3Npb25IYW5kbGUsXG4gICAgICAgIGlucHV0TmFtZXNVVEY4RW5jb2RlZCxcbiAgICAgICAgb3V0cHV0TmFtZXNVVEY4RW5jb2RlZCxcbiAgICAgICAgaW9CaW5kaW5nU3RhdGUsXG4gICAgICAgIGVuYWJsZUdyYXBoQ2FwdHVyZSxcbiAgICAgICAgdHJ1ZSxcbiAgICAgIF0pO1xuICAgIH1cblxuICAgIHdhc20uanNlcE9uUnVuU3RhcnQ/LihzZXNzaW9uSGFuZGxlKTtcbiAgICB3YXNtLndlYm5uT25SdW5TdGFydD8uKHNlc3Npb25IYW5kbGUpO1xuXG4gICAgbGV0IGVycm9yQ29kZTogbnVtYmVyO1xuICAgIGlmICgoIUJVSUxEX0RFRlMuRElTQUJMRV9KU0VQIHx8ICFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR1BVKSAmJiBpb0JpbmRpbmdTdGF0ZSkge1xuICAgICAgZXJyb3JDb2RlID0gYXdhaXQgd2FzbS5fT3J0UnVuV2l0aEJpbmRpbmcoXG4gICAgICAgIHNlc3Npb25IYW5kbGUsXG4gICAgICAgIGlvQmluZGluZ1N0YXRlLmhhbmRsZSxcbiAgICAgICAgb3V0cHV0Q291bnQsXG4gICAgICAgIG91dHB1dFZhbHVlc09mZnNldCxcbiAgICAgICAgcnVuT3B0aW9uc0hhbmRsZSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVycm9yQ29kZSA9IGF3YWl0IHdhc20uX09ydFJ1bihcbiAgICAgICAgc2Vzc2lvbkhhbmRsZSxcbiAgICAgICAgaW5wdXROYW1lc09mZnNldCxcbiAgICAgICAgaW5wdXRWYWx1ZXNPZmZzZXQsXG4gICAgICAgIGlucHV0Q291bnQsXG4gICAgICAgIG91dHB1dE5hbWVzT2Zmc2V0LFxuICAgICAgICBvdXRwdXRDb3VudCxcbiAgICAgICAgb3V0cHV0VmFsdWVzT2Zmc2V0LFxuICAgICAgICBydW5PcHRpb25zSGFuZGxlLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoZXJyb3JDb2RlICE9PSAwKSB7XG4gICAgICBjaGVja0xhc3RFcnJvcignZmFpbGVkIHRvIGNhbGwgT3J0UnVuKCkuJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3V0cHV0OiBUZW5zb3JNZXRhZGF0YVtdID0gW107XG4gICAgY29uc3Qgb3V0cHV0UHJvbWlzZXM6IEFycmF5PFByb21pc2U8W251bWJlciwgVGVuc29yLkRhdGFUeXBlXT4+ID0gW107XG5cbiAgICBUUkFDRV9FVkVOVF9CRUdJTignd2FzbSBQcm9jZXNzT3V0cHV0VGVuc29yJyk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRDb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCB0ZW5zb3IgPSBOdW1iZXIod2FzbS5nZXRWYWx1ZShvdXRwdXRWYWx1ZXNPZmZzZXQgKyBpICogcHRyU2l6ZSwgJyonKSk7XG4gICAgICAvLyBUT0RPOiByZXZpc2l0IHRoaXMgcGFydCB0byBlbnN1cmUgaXQgd29ya3MgZm9yIFdlYkdQVSB3aGVuIGJvdGggcHJlLWFsbG9jYXRlZCBvdXRwdXRzIGFuZFxuICAgICAgLy8gcHJlZmVycmVkIGxvY2F0aW9uIGFyZSBzcGVjaWZpZWQuXG4gICAgICAvLyBDZXJ0YWluIHByZS1hbGxvY2F0ZWQgdGVuc29ycyBtYXkgYWxyZWFkeSBiZSBib3VuZCBpbiB0aGUgSU8gYmluZGluZy4gZS5nLiB0aGUgV2ViTk4gYmFja2VuZFxuICAgICAgLy8gYWx3YXlzIGJpbmRzIGl0cyB0ZW5zb3IgdG8gJ21sLXRlbnNvcicuIEluIHN1Y2ggY2FzZXMsIHRoZSB0ZW5zb3IgSUQgbWlnaHQgY2hhbmdlIGFmdGVyIGJpbmRpbmcsXG4gICAgICAvLyBidXQgY29weWluZyBkYXRhIGZvciB0aGVzZSB0ZW5zb3JzIHNob3VsZCBzdGlsbCBiZSBhdm9pZGVkLlxuICAgICAgaWYgKHRlbnNvciA9PT0gb3V0cHV0VGVuc29ySGFuZGxlc1tpXSB8fCBwcmVBbGxvY2F0ZWRPdXRwdXRzLmluY2x1ZGVzKG91dHB1dFRlbnNvckhhbmRsZXNbaV0pKSB7XG4gICAgICAgIC8vIG91dHB1dCB0ZW5zb3IgaXMgcHJlLWFsbG9jYXRlZC4gbm8gbmVlZCB0byBjb3B5IGRhdGEuXG4gICAgICAgIG91dHB1dC5wdXNoKG91dHB1dFRlbnNvcnNbaV0hKTtcbiAgICAgICAgaWYgKHRlbnNvciAhPT0gb3V0cHV0VGVuc29ySGFuZGxlc1tpXSkge1xuICAgICAgICAgIC8vIHJlbGVhc2UgcmVkdW5kYW50IHRlbnNvciBlYXJsaWVyLlxuICAgICAgICAgIGlmICh3YXNtLl9PcnRSZWxlYXNlVGVuc29yKHRlbnNvcikgIT09IDApIHtcbiAgICAgICAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgcmVsZWFzZSB0ZW5zb3IuXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYmVmb3JlR2V0VGVuc29yRGF0YVN0YWNrID0gd2FzbS5zdGFja1NhdmUoKTtcbiAgICAgIC8vIHN0YWNrIGFsbG9jYXRlIDQgcG9pbnRlciB2YWx1ZVxuICAgICAgY29uc3QgdGVuc29yRGF0YU9mZnNldCA9IHdhc20uc3RhY2tBbGxvYyg0ICogcHRyU2l6ZSk7XG5cbiAgICAgIGxldCBrZWVwT3V0cHV0VGVuc29yID0gZmFsc2U7XG4gICAgICBsZXQgdHlwZTogVGVuc29yLlR5cGUgfCB1bmRlZmluZWQsXG4gICAgICAgIGRhdGFPZmZzZXQgPSAwO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZXJyb3JDb2RlID0gd2FzbS5fT3J0R2V0VGVuc29yRGF0YShcbiAgICAgICAgICB0ZW5zb3IsXG4gICAgICAgICAgdGVuc29yRGF0YU9mZnNldCxcbiAgICAgICAgICB0ZW5zb3JEYXRhT2Zmc2V0ICsgcHRyU2l6ZSxcbiAgICAgICAgICB0ZW5zb3JEYXRhT2Zmc2V0ICsgMiAqIHB0clNpemUsXG5cbiAgICAgICAgICB0ZW5zb3JEYXRhT2Zmc2V0ICsgMyAqIHB0clNpemUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChlcnJvckNvZGUgIT09IDApIHtcbiAgICAgICAgICBjaGVja0xhc3RFcnJvcihgQ2FuJ3QgYWNjZXNzIG91dHB1dCB0ZW5zb3IgZGF0YSBvbiBpbmRleCAke2l9LmApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IHB0clNpemUgPT09IDQgPyAnaTMyJyA6ICdpNjQnO1xuICAgICAgICBjb25zdCBkYXRhVHlwZSA9IE51bWJlcih3YXNtLmdldFZhbHVlKHRlbnNvckRhdGFPZmZzZXQsIHZhbHVlVHlwZSkpO1xuICAgICAgICBkYXRhT2Zmc2V0ID0gd2FzbS5nZXRWYWx1ZSh0ZW5zb3JEYXRhT2Zmc2V0ICsgcHRyU2l6ZSwgJyonKTtcbiAgICAgICAgY29uc3QgZGltc09mZnNldCA9IHdhc20uZ2V0VmFsdWUodGVuc29yRGF0YU9mZnNldCArIHB0clNpemUgKiAyLCAnKicpO1xuICAgICAgICBjb25zdCBkaW1zTGVuZ3RoID0gTnVtYmVyKHdhc20uZ2V0VmFsdWUodGVuc29yRGF0YU9mZnNldCArIHB0clNpemUgKiAzLCB2YWx1ZVR5cGUpKTtcbiAgICAgICAgY29uc3QgZGltcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbXNMZW5ndGg7IGkrKykge1xuICAgICAgICAgIGRpbXMucHVzaChOdW1iZXIod2FzbS5nZXRWYWx1ZShkaW1zT2Zmc2V0ICsgaSAqIHB0clNpemUsIHZhbHVlVHlwZSkpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAod2FzbS5fT3J0RnJlZShkaW1zT2Zmc2V0KSAhPT0gMCkge1xuICAgICAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgZnJlZSBtZW1vcnkgZm9yIHRlbnNvciBkaW1zLlwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzaXplID0gZGltcy5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiLCAxKTtcbiAgICAgICAgdHlwZSA9IHRlbnNvckRhdGFUeXBlRW51bVRvU3RyaW5nKGRhdGFUeXBlKTtcblxuICAgICAgICBjb25zdCBwcmVmZXJyZWRMb2NhdGlvbiA9IGlvQmluZGluZ1N0YXRlPy5vdXRwdXRQcmVmZXJyZWRMb2NhdGlvbnNbb3V0cHV0SW5kaWNlc1tpXV07XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgaWYgKHByZWZlcnJlZExvY2F0aW9uID09PSAnZ3B1LWJ1ZmZlcicgfHwgcHJlZmVycmVkTG9jYXRpb24gPT09ICdtbC10ZW5zb3InKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N0cmluZyB0ZW5zb3IgaXMgbm90IHN1cHBvcnRlZCBvbiBHUFUuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHN0cmluZ0RhdGE6IHN0cmluZ1tdID0gW107XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IHdhc20uZ2V0VmFsdWUoZGF0YU9mZnNldCArIGkgKiBwdHJTaXplLCAnKicpO1xuICAgICAgICAgICAgY29uc3QgbmV4dE9mZnNldCA9IHdhc20uZ2V0VmFsdWUoZGF0YU9mZnNldCArIChpICsgMSkgKiBwdHJTaXplLCAnKicpO1xuICAgICAgICAgICAgY29uc3QgbWF4Qnl0ZXNUb1JlYWQgPSBpID09PSBzaXplIC0gMSA/IHVuZGVmaW5lZCA6IG5leHRPZmZzZXQgLSBvZmZzZXQ7XG4gICAgICAgICAgICBzdHJpbmdEYXRhLnB1c2god2FzbS5VVEY4VG9TdHJpbmcob2Zmc2V0LCBtYXhCeXRlc1RvUmVhZCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvdXRwdXQucHVzaChbdHlwZSwgZGltcywgc3RyaW5nRGF0YSwgJ2NwdSddKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBJZiBhIGNlcnRhaW4gb3V0cHV0J3MgcHJlZmVycmVkIGxvY2F0aW9uIGlzIEdQVSBidXQgdGhlIHRlbnNvciBpcyBlbXB0eSwgd2Ugc3RpbGwgbmVlZCB0byBjcmVhdGUgYSBDUFVcbiAgICAgICAgICAvLyB0ZW5zb3IgZm9yIGl0LiBUaGVyZSBpcyBubyBtYXBwaW5nIEdQVSBidWZmZXIgZm9yIGFuIGVtcHR5IHRlbnNvci5cbiAgICAgICAgICBpZiAocHJlZmVycmVkTG9jYXRpb24gPT09ICdncHUtYnVmZmVyJyAmJiBzaXplID4gMCkge1xuICAgICAgICAgICAgY29uc3QgZ2V0QnVmZmVyID0gIUJVSUxEX0RFRlMuRElTQUJMRV9XRUJHUFUgPyB3YXNtLndlYmdwdUdldEJ1ZmZlciA6IHdhc20uanNlcEdldEJ1ZmZlcjtcbiAgICAgICAgICAgIGlmICghZ2V0QnVmZmVyKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigncHJlZmVycmVkTG9jYXRpb24gXCJncHUtYnVmZmVyXCIgaXMgbm90IHN1cHBvcnRlZCB3aXRob3V0IHVzaW5nIFdlYkdQVS4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGdwdUJ1ZmZlciA9IGdldEJ1ZmZlcihkYXRhT2Zmc2V0KTtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclNpemUgPSBjYWxjdWxhdGVUZW5zb3JTaXplSW5CeXRlcyhkYXRhVHlwZSwgc2l6ZSk7XG4gICAgICAgICAgICBpZiAoYnVmZmVyU2l6ZSA9PT0gdW5kZWZpbmVkIHx8ICFpc0dwdUJ1ZmZlclN1cHBvcnRlZFR5cGUodHlwZSkpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7dHlwZX1gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gZG8gbm90IHJlbGVhc2UgdGhlIHRlbnNvciByaWdodCBub3cuIGl0IHdpbGwgYmUgcmVsZWFzZWQgd2hlbiB1c2VyIGNhbGxzIHRlbnNvci5kaXNwb3NlKCkuXG4gICAgICAgICAgICBrZWVwT3V0cHV0VGVuc29yID0gdHJ1ZTtcblxuICAgICAgICAgICAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR1BVKSB7XG4gICAgICAgICAgICAgIHdhc20ud2ViZ3B1UmVnaXN0ZXJCdWZmZXIhKGdwdUJ1ZmZlciwgc2Vzc2lvbklkLCBkYXRhT2Zmc2V0KTtcbiAgICAgICAgICAgICAgY29uc3QgZG93bmxvYWREYXRhRnVuY3Rpb24gPSB3YXNtLndlYmdwdUNyZWF0ZURvd25sb2FkZXIhKGdwdUJ1ZmZlciwgYnVmZmVyU2l6ZSwgc2Vzc2lvbklkKTtcbiAgICAgICAgICAgICAgb3V0cHV0LnB1c2goW1xuICAgICAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICAgICAgZGltcyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBncHVCdWZmZXIsXG4gICAgICAgICAgICAgICAgICBkb3dubG9hZDogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhcnJheUJ1ZmZlciA9IGF3YWl0IGRvd25sb2FkRGF0YUZ1bmN0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBuZXcgKHRlbnNvclR5cGVUb1R5cGVkQXJyYXlDb25zdHJ1Y3Rvcih0eXBlISkpKGFycmF5QnVmZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEgYXMgVGVuc29yLkRhdGFUeXBlTWFwW1RlbnNvci5HcHVCdWZmZXJEYXRhVHlwZXNdO1xuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGRpc3Bvc2U6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdhc20uX09ydFJlbGVhc2VUZW5zb3IodGVuc29yKSAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgcmVsZWFzZSB0ZW5zb3IuXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgJ2dwdS1idWZmZXInLFxuICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG91dHB1dC5wdXNoKFtcbiAgICAgICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgICAgIGRpbXMsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZ3B1QnVmZmVyLFxuICAgICAgICAgICAgICAgICAgZG93bmxvYWQ6IHdhc20uanNlcENyZWF0ZURvd25sb2FkZXIhKGdwdUJ1ZmZlciwgYnVmZmVyU2l6ZSwgdHlwZSksXG4gICAgICAgICAgICAgICAgICBkaXNwb3NlOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh3YXNtLl9PcnRSZWxlYXNlVGVuc29yKHRlbnNvcikgIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICBjaGVja0xhc3RFcnJvcihcIkNhbid0IHJlbGVhc2UgdGVuc29yLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICdncHUtYnVmZmVyJyxcbiAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChwcmVmZXJyZWRMb2NhdGlvbiA9PT0gJ21sLXRlbnNvcicgJiYgc2l6ZSA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGVuc3VyZVRlbnNvciA9IHdhc20ud2Vibm5FbnN1cmVUZW5zb3I7XG4gICAgICAgICAgICBjb25zdCBpc0dyYXBoSW5wdXRPdXRwdXRUeXBlU3VwcG9ydGVkID0gd2FzbS53ZWJubklzR3JhcGhJbnB1dE91dHB1dFR5cGVTdXBwb3J0ZWQ7XG4gICAgICAgICAgICBpZiAoIWVuc3VyZVRlbnNvciB8fCAhaXNHcmFwaElucHV0T3V0cHV0VHlwZVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3ByZWZlcnJlZExvY2F0aW9uIFwibWwtdGVuc29yXCIgaXMgbm90IHN1cHBvcnRlZCB3aXRob3V0IHVzaW5nIFdlYk5OLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgdGVuc29yU2l6ZSA9IGNhbGN1bGF0ZVRlbnNvclNpemVJbkJ5dGVzKGRhdGFUeXBlLCBzaXplKTtcbiAgICAgICAgICAgIGlmICh0ZW5zb3JTaXplID09PSB1bmRlZmluZWQgfHwgIWlzTUxUZW5zb3JTdXBwb3J0ZWRUeXBlKHR5cGUpKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZGF0YSB0eXBlOiAke3R5cGV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWlzR3JhcGhJbnB1dE91dHB1dFR5cGVTdXBwb3J0ZWQoc2Vzc2lvbklkLCB0eXBlLCBmYWxzZSkpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIGBwcmVmZXJyZWRMb2NhdGlvbiBcIm1sLXRlbnNvclwiIGZvciAke3R5cGV9IG91dHB1dCBpcyBub3Qgc3VwcG9ydGVkIGJ5IGN1cnJlbnQgV2ViTk4gQ29udGV4dC5gLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiB0aGUgZ3JhcGggaGFzIGJlZW4gcGFydGl0aW9uZWQsIHRoZSBvdXRwdXQgdGVuc29yIG1heSBoYXZlIG5vdCBiZWVuIGNyZWF0ZWQuIEZvciB0aGlzIHJlYXNvbiwgd2UgdXNlXG4gICAgICAgICAgICAvLyBlbnN1cmVUZW5zb3IgdG8gZ2V0L2NyZWF0ZSB0aGUgTUxUZW5zb3IuIEluIHdoaWNoIGNhc2UsIHdlIGRvbid0IG5lZWQgdG8gY29weSB0aGUgZGF0YSBpZiBhIG5ldyB0ZW5zb3JcbiAgICAgICAgICAgIC8vIGhhcyBiZWVuIGNyZWF0ZWQuXG4gICAgICAgICAgICBjb25zdCBtbFRlbnNvciA9IGF3YWl0IGVuc3VyZVRlbnNvcihzZXNzaW9uSWQsIGRhdGFPZmZzZXQsIGRhdGFUeXBlLCBkaW1zLCBmYWxzZSk7XG5cbiAgICAgICAgICAgIC8vIGRvIG5vdCByZWxlYXNlIHRoZSB0ZW5zb3IgcmlnaHQgbm93LiBpdCB3aWxsIGJlIHJlbGVhc2VkIHdoZW4gdXNlciBjYWxscyB0ZW5zb3IuZGlzcG9zZSgpLlxuICAgICAgICAgICAga2VlcE91dHB1dFRlbnNvciA9IHRydWU7XG5cbiAgICAgICAgICAgIG91dHB1dC5wdXNoKFtcbiAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgZGltcyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG1sVGVuc29yLFxuICAgICAgICAgICAgICAgIGRvd25sb2FkOiB3YXNtLndlYm5uQ3JlYXRlTUxUZW5zb3JEb3dubG9hZGVyIShkYXRhT2Zmc2V0LCB0eXBlKSxcbiAgICAgICAgICAgICAgICBkaXNwb3NlOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICB3YXNtLndlYm5uUmVsZWFzZVRlbnNvcklkIShkYXRhT2Zmc2V0KTtcbiAgICAgICAgICAgICAgICAgIHdhc20uX09ydFJlbGVhc2VUZW5zb3IodGVuc29yKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAnbWwtdGVuc29yJyxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgIH0gZWxzZSBpZiAocHJlZmVycmVkTG9jYXRpb24gPT09ICdtbC10ZW5zb3ItY3B1LW91dHB1dCcgJiYgc2l6ZSA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSB3YXNtLndlYm5uQ3JlYXRlTUxUZW5zb3JEb3dubG9hZGVyIShkYXRhT2Zmc2V0LCB0eXBlIGFzIFRlbnNvci5NTFRlbnNvckRhdGFUeXBlcykoKTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gb3V0cHV0Lmxlbmd0aDtcbiAgICAgICAgICAgIC8vIERlbGF5IHRoZSBkYXRhIGRvd25sb2FkIGFuZCByZWxlYXNpbmcgdGhlIHRlbnNvciB1bnRpbCB3ZSBjYW4gd2FpdCBmb3IgYWxsIG91dHB1dCB0ZW5zb3JzIHRvIGJlIGRvd25sb2FkZWQuXG4gICAgICAgICAgICBrZWVwT3V0cHV0VGVuc29yID0gdHJ1ZTtcbiAgICAgICAgICAgIG91dHB1dFByb21pc2VzLnB1c2goXG4gICAgICAgICAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0OiBbbnVtYmVyLCBUZW5zb3IuRGF0YVR5cGVdID0gW2luZGV4LCBhd2FpdCBkYXRhXTtcbiAgICAgICAgICAgICAgICB3YXNtLndlYm5uUmVsZWFzZVRlbnNvcklkIShkYXRhT2Zmc2V0KTtcbiAgICAgICAgICAgICAgICB3YXNtLl9PcnRSZWxlYXNlVGVuc29yKHRlbnNvcik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgfSkoKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBvdXRwdXQucHVzaChbdHlwZSwgZGltcywgW10sICdjcHUnXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHR5cGVkQXJyYXlDb25zdHJ1Y3RvciA9IHRlbnNvclR5cGVUb1R5cGVkQXJyYXlDb25zdHJ1Y3Rvcih0eXBlKTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBuZXcgdHlwZWRBcnJheUNvbnN0cnVjdG9yKHNpemUpO1xuICAgICAgICAgICAgbmV3IFVpbnQ4QXJyYXkoZGF0YS5idWZmZXIsIGRhdGEuYnl0ZU9mZnNldCwgZGF0YS5ieXRlTGVuZ3RoKS5zZXQoXG4gICAgICAgICAgICAgIHdhc20uSEVBUFU4LnN1YmFycmF5KGRhdGFPZmZzZXQsIGRhdGFPZmZzZXQgKyBkYXRhLmJ5dGVMZW5ndGgpLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIG91dHB1dC5wdXNoKFt0eXBlLCBkaW1zLCBkYXRhLCAnY3B1J10pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgd2FzbS5zdGFja1Jlc3RvcmUoYmVmb3JlR2V0VGVuc29yRGF0YVN0YWNrKTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIGRhdGFPZmZzZXQpIHtcbiAgICAgICAgICB3YXNtLl9mcmVlKGRhdGFPZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICgha2VlcE91dHB1dFRlbnNvcikge1xuICAgICAgICAgIHdhc20uX09ydFJlbGVhc2VUZW5zb3IodGVuc29yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpb0JpbmRpbmdTdGF0ZSAmJiAhZW5hYmxlR3JhcGhDYXB0dXJlKSB7XG4gICAgICBpZiAod2FzbS5fT3J0Q2xlYXJCb3VuZE91dHB1dHMoaW9CaW5kaW5nU3RhdGUuaGFuZGxlKSAhPT0gMCkge1xuICAgICAgICBjaGVja0xhc3RFcnJvcihcIkNhbid0IGNsZWFyIGJvdW5kIG91dHB1dHMuXCIpO1xuICAgICAgfVxuICAgICAgYWN0aXZlU2Vzc2lvbnMuc2V0KHNlc3Npb25JZCwgW1xuICAgICAgICBzZXNzaW9uSGFuZGxlLFxuICAgICAgICBpbnB1dE5hbWVzVVRGOEVuY29kZWQsXG4gICAgICAgIG91dHB1dE5hbWVzVVRGOEVuY29kZWQsXG4gICAgICAgIGlvQmluZGluZ1N0YXRlLFxuICAgICAgICBlbmFibGVHcmFwaENhcHR1cmUsXG4gICAgICAgIGZhbHNlLFxuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIFdhaXQgZm9yIGFsbCBvdXRwdXQgdGVuc29yIGRhdGEgdG8gYmUgZG93bmxvYWRlZC5cbiAgICBmb3IgKGNvbnN0IFtpbmRleCwgZGF0YV0gb2YgYXdhaXQgUHJvbWlzZS5hbGwob3V0cHV0UHJvbWlzZXMpKSB7XG4gICAgICBvdXRwdXRbaW5kZXhdWzJdID0gZGF0YTtcbiAgICB9XG4gICAgVFJBQ0VfRVZFTlRfRU5EKCd3YXNtIFByb2Nlc3NPdXRwdXRUZW5zb3InKTtcbiAgICByZXR1cm4gb3V0cHV0O1xuICB9IGZpbmFsbHkge1xuICAgIHdhc20ud2Vibm5PblJ1bkVuZD8uKHNlc3Npb25IYW5kbGUpO1xuXG4gICAgd2FzbS5zdGFja1Jlc3RvcmUoYmVmb3JlUnVuU3RhY2spO1xuXG4gICAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR1BVKSB7XG4gICAgICBpbnB1dFRlbnNvcnMuZm9yRWFjaCgodCkgPT4ge1xuICAgICAgICBpZiAodCAmJiB0WzNdID09PSAnZ3B1LWJ1ZmZlcicpIHtcbiAgICAgICAgICB3YXNtLndlYmdwdVVucmVnaXN0ZXJCdWZmZXIhKHRbMl0uZ3B1QnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBvdXRwdXRUZW5zb3JzLmZvckVhY2goKHQpID0+IHtcbiAgICAgICAgaWYgKHQgJiYgdFszXSA9PT0gJ2dwdS1idWZmZXInKSB7XG4gICAgICAgICAgd2FzbS53ZWJncHVVbnJlZ2lzdGVyQnVmZmVyISh0WzJdLmdwdUJ1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICBpbnB1dFRlbnNvckhhbmRsZXMuZm9yRWFjaCgodikgPT4gd2FzbS5fT3J0UmVsZWFzZVRlbnNvcih2KSk7XG4gICAgb3V0cHV0VGVuc29ySGFuZGxlcy5mb3JFYWNoKCh2KSA9PiB3YXNtLl9PcnRSZWxlYXNlVGVuc29yKHYpKTtcbiAgICBpbnB1dE91dHB1dEFsbG9jcy5mb3JFYWNoKChwKSA9PiB3YXNtLl9mcmVlKHApKTtcblxuICAgIGlmIChydW5PcHRpb25zSGFuZGxlICE9PSAwKSB7XG4gICAgICB3YXNtLl9PcnRSZWxlYXNlUnVuT3B0aW9ucyhydW5PcHRpb25zSGFuZGxlKTtcbiAgICB9XG4gICAgcnVuT3B0aW9uc0FsbG9jcy5mb3JFYWNoKChwKSA9PiB3YXNtLl9mcmVlKHApKTtcbiAgfVxufTtcblxuLyoqXG4gKiBlbmQgcHJvZmlsaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBlbmRQcm9maWxpbmcgPSAoc2Vzc2lvbklkOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgY29uc3Qgd2FzbSA9IGdldEluc3RhbmNlKCk7XG4gIGNvbnN0IHNlc3Npb24gPSBhY3RpdmVTZXNzaW9ucy5nZXQoc2Vzc2lvbklkKTtcbiAgaWYgKCFzZXNzaW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNlc3Npb24gaWQnKTtcbiAgfVxuICBjb25zdCBzZXNzaW9uSGFuZGxlID0gc2Vzc2lvblswXTtcblxuICAvLyBwcm9maWxlIGZpbGUgbmFtZSBpcyBub3QgdXNlZCB5ZXQsIGJ1dCBpdCBtdXN0IGJlIGZyZWVkLlxuICBjb25zdCBwcm9maWxlRmlsZU5hbWUgPSB3YXNtLl9PcnRFbmRQcm9maWxpbmcoc2Vzc2lvbkhhbmRsZSk7XG4gIGlmIChwcm9maWxlRmlsZU5hbWUgPT09IDApIHtcbiAgICBjaGVja0xhc3RFcnJvcihcIkNhbid0IGdldCBhbiBwcm9maWxlIGZpbGUgbmFtZS5cIik7XG4gIH1cbiAgd2FzbS5fT3J0RnJlZShwcm9maWxlRmlsZU5hbWUpO1xufTtcblxuZXhwb3J0IGNvbnN0IGV4dHJhY3RUcmFuc2ZlcmFibGVCdWZmZXJzID0gKHRlbnNvcnM6IHJlYWRvbmx5IFNlcmlhbGl6YWJsZVRlbnNvck1ldGFkYXRhW10pOiBBcnJheUJ1ZmZlckxpa2VbXSA9PiB7XG4gIGNvbnN0IGJ1ZmZlcnM6IEFycmF5QnVmZmVyTGlrZVtdID0gW107XG4gIGZvciAoY29uc3QgdGVuc29yIG9mIHRlbnNvcnMpIHtcbiAgICBjb25zdCBkYXRhID0gdGVuc29yWzJdO1xuICAgIGlmICghQXJyYXkuaXNBcnJheShkYXRhKSAmJiAnYnVmZmVyJyBpbiBkYXRhKSB7XG4gICAgICBidWZmZXJzLnB1c2goZGF0YS5idWZmZXIpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYnVmZmVycztcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiwgSW5mZXJlbmNlU2Vzc2lvbiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7XG4gIE9ydFdhc21NZXNzYWdlLFxuICBTZXJpYWxpemFibGVJbnRlcm5hbEJ1ZmZlcixcbiAgU2VyaWFsaXphYmxlU2Vzc2lvbk1ldGFkYXRhLFxuICBTZXJpYWxpemFibGVUZW5zb3JNZXRhZGF0YSxcbiAgVGVuc29yTWV0YWRhdGEsXG59IGZyb20gJy4vcHJveHktbWVzc2FnZXMnO1xuaW1wb3J0ICogYXMgY29yZSBmcm9tICcuL3dhc20tY29yZS1pbXBsJztcbmltcG9ydCB7IGluaXRpYWxpemVXZWJBc3NlbWJseSB9IGZyb20gJy4vd2FzbS1mYWN0b3J5JztcbmltcG9ydCB7XG4gIGltcG9ydFByb3h5V29ya2VyLFxuICBpbmZlcldhc21QYXRoUHJlZml4RnJvbVNjcmlwdFNyYyxcbiAgaXNFc21JbXBvcnRNZXRhVXJsSGFyZGNvZGVkQXNGaWxlVXJpLFxufSBmcm9tICcuL3dhc20tdXRpbHMtaW1wb3J0JztcblxuY29uc3QgaXNQcm94eSA9ICgpOiBib29sZWFuID0+ICEhZW52Lndhc20ucHJveHkgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJztcbmxldCBwcm94eVdvcmtlcjogV29ya2VyIHwgdW5kZWZpbmVkO1xubGV0IGluaXRpYWxpemluZyA9IGZhbHNlO1xubGV0IGluaXRpYWxpemVkID0gZmFsc2U7XG5sZXQgYWJvcnRlZCA9IGZhbHNlO1xubGV0IHRlbXBvcmFyeU9iamVjdFVybDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG50eXBlIFByb21pc2VDYWxsYmFja3M8VCA9IHZvaWQ+ID0gW3Jlc29sdmU6IChyZXN1bHQ6IFQpID0+IHZvaWQsIHJlamVjdDogKHJlYXNvbjogdW5rbm93bikgPT4gdm9pZF07XG5sZXQgaW5pdFdhc21DYWxsYmFja3M6IFByb21pc2VDYWxsYmFja3M7XG5jb25zdCBxdWV1ZWRDYWxsYmFja3M6IE1hcDxPcnRXYXNtTWVzc2FnZVsndHlwZSddLCBBcnJheTxQcm9taXNlQ2FsbGJhY2tzPHVua25vd24+Pj4gPSBuZXcgTWFwKCk7XG5cbmNvbnN0IGVucXVldWVDYWxsYmFja3MgPSAodHlwZTogT3J0V2FzbU1lc3NhZ2VbJ3R5cGUnXSwgY2FsbGJhY2tzOiBQcm9taXNlQ2FsbGJhY2tzPHVua25vd24+KTogdm9pZCA9PiB7XG4gIGNvbnN0IHF1ZXVlID0gcXVldWVkQ2FsbGJhY2tzLmdldCh0eXBlKTtcbiAgaWYgKHF1ZXVlKSB7XG4gICAgcXVldWUucHVzaChjYWxsYmFja3MpO1xuICB9IGVsc2Uge1xuICAgIHF1ZXVlZENhbGxiYWNrcy5zZXQodHlwZSwgW2NhbGxiYWNrc10pO1xuICB9XG59O1xuXG5jb25zdCBlbnN1cmVXb3JrZXIgPSAoKTogdm9pZCA9PiB7XG4gIGlmIChpbml0aWFsaXppbmcgfHwgIWluaXRpYWxpemVkIHx8IGFib3J0ZWQgfHwgIXByb3h5V29ya2VyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd3b3JrZXIgbm90IHJlYWR5Jyk7XG4gIH1cbn07XG5cbmNvbnN0IG9uUHJveHlXb3JrZXJNZXNzYWdlID0gKGV2OiBNZXNzYWdlRXZlbnQ8T3J0V2FzbU1lc3NhZ2U+KTogdm9pZCA9PiB7XG4gIHN3aXRjaCAoZXYuZGF0YS50eXBlKSB7XG4gICAgY2FzZSAnaW5pdC13YXNtJzpcbiAgICAgIGluaXRpYWxpemluZyA9IGZhbHNlO1xuICAgICAgaWYgKGV2LmRhdGEuZXJyKSB7XG4gICAgICAgIGFib3J0ZWQgPSB0cnVlO1xuICAgICAgICBpbml0V2FzbUNhbGxiYWNrc1sxXShldi5kYXRhLmVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbml0aWFsaXplZCA9IHRydWU7XG4gICAgICAgIGluaXRXYXNtQ2FsbGJhY2tzWzBdKCk7XG4gICAgICB9XG4gICAgICBpZiAodGVtcG9yYXJ5T2JqZWN0VXJsKSB7XG4gICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwodGVtcG9yYXJ5T2JqZWN0VXJsKTtcbiAgICAgICAgdGVtcG9yYXJ5T2JqZWN0VXJsID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnaW5pdC1lcCc6XG4gICAgY2FzZSAnY29weS1mcm9tJzpcbiAgICBjYXNlICdjcmVhdGUnOlxuICAgIGNhc2UgJ3JlbGVhc2UnOlxuICAgIGNhc2UgJ3J1bic6XG4gICAgY2FzZSAnZW5kLXByb2ZpbGluZyc6IHtcbiAgICAgIGNvbnN0IGNhbGxiYWNrcyA9IHF1ZXVlZENhbGxiYWNrcy5nZXQoZXYuZGF0YS50eXBlKSE7XG4gICAgICBpZiAoZXYuZGF0YS5lcnIpIHtcbiAgICAgICAgY2FsbGJhY2tzLnNoaWZ0KCkhWzFdKGV2LmRhdGEuZXJyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrcy5zaGlmdCgpIVswXShldi5kYXRhLm91dCEpO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGRlZmF1bHQ6XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBpbml0aWFsaXplV2ViQXNzZW1ibHlBbmRPcnRSdW50aW1lID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICBpZiAoaW5pdGlhbGl6ZWQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKGluaXRpYWxpemluZykge1xuICAgIHRocm93IG5ldyBFcnJvcihcIm11bHRpcGxlIGNhbGxzIHRvICdpbml0V2FzbSgpJyBkZXRlY3RlZC5cIik7XG4gIH1cbiAgaWYgKGFib3J0ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJwcmV2aW91cyBjYWxsIHRvICdpbml0V2FzbSgpJyBmYWlsZWQuXCIpO1xuICB9XG5cbiAgaW5pdGlhbGl6aW5nID0gdHJ1ZTtcblxuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XQVNNX1BST1hZICYmIGlzUHJveHkoKSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBwcm94eVdvcmtlcj8udGVybWluYXRlKCk7XG5cbiAgICAgIHZvaWQgaW1wb3J0UHJveHlXb3JrZXIoKS50aGVuKChbb2JqZWN0VXJsLCB3b3JrZXJdKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcHJveHlXb3JrZXIgPSB3b3JrZXI7XG4gICAgICAgICAgcHJveHlXb3JrZXIub25lcnJvciA9IChldjogRXJyb3JFdmVudCkgPT4gcmVqZWN0KGV2KTtcbiAgICAgICAgICBwcm94eVdvcmtlci5vbm1lc3NhZ2UgPSBvblByb3h5V29ya2VyTWVzc2FnZTtcbiAgICAgICAgICBpbml0V2FzbUNhbGxiYWNrcyA9IFtyZXNvbHZlLCByZWplY3RdO1xuICAgICAgICAgIGNvbnN0IG1lc3NhZ2U6IE9ydFdhc21NZXNzYWdlID0geyB0eXBlOiAnaW5pdC13YXNtJywgaW46IGVudiB9O1xuXG4gICAgICAgICAgLy8gaWYgdGhlIHByb3h5IHdvcmtlciBpcyBsb2FkZWQgZnJvbSBhIGJsb2IgVVJMLCB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGUgcGF0aCBpbmZvcm1hdGlvbiBpcyBub3QgbG9zdC5cbiAgICAgICAgICAvL1xuICAgICAgICAgIC8vIHdoZW4gYGVudi53YXNtLndhc21QYXRoc2AgaXMgbm90IHNldCwgd2UgbmVlZCB0byBwYXNzIHRoZSBwYXRoIGluZm9ybWF0aW9uIHRvIHRoZSB3b3JrZXIuXG4gICAgICAgICAgLy9cbiAgICAgICAgICBpZiAoIUJVSUxEX0RFRlMuRU5BQkxFX0JVTkRMRV9XQVNNX0pTICYmICFtZXNzYWdlLmluIS53YXNtLndhc21QYXRocyAmJiBvYmplY3RVcmwpIHtcbiAgICAgICAgICAgIC8vIGZvciBhIGJ1aWxkIG5vdCBidW5kbGVkIHRoZSB3YXNtIEpTLCB3ZSBuZWVkIHRvIHBhc3MgdGhlIHBhdGggcHJlZml4IHRvIHRoZSB3b3JrZXIuXG4gICAgICAgICAgICAvLyB0aGUgcGF0aCBwcmVmaXggd2lsbCBiZSB1c2VkIHRvIHJlc29sdmUgdGhlIHBhdGggdG8gYm90aCB0aGUgd2FzbSBKUyBhbmQgdGhlIHdhc20gZmlsZS5cbiAgICAgICAgICAgIGNvbnN0IGluZmVycmVkV2FzbVBhdGhQcmVmaXggPSBpbmZlcldhc21QYXRoUHJlZml4RnJvbVNjcmlwdFNyYygpO1xuICAgICAgICAgICAgaWYgKGluZmVycmVkV2FzbVBhdGhQcmVmaXgpIHtcbiAgICAgICAgICAgICAgbWVzc2FnZS5pbiEud2FzbS53YXNtUGF0aHMgPSBpbmZlcnJlZFdhc21QYXRoUHJlZml4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIEJVSUxEX0RFRlMuSVNfRVNNICYmXG4gICAgICAgICAgICBCVUlMRF9ERUZTLkVOQUJMRV9CVU5ETEVfV0FTTV9KUyAmJlxuICAgICAgICAgICAgIW1lc3NhZ2UuaW4hLndhc20ud2FzbVBhdGhzICYmXG4gICAgICAgICAgICAob2JqZWN0VXJsIHx8IGlzRXNtSW1wb3J0TWV0YVVybEhhcmRjb2RlZEFzRmlsZVVyaSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIC8vIGZvciBhIGJ1aWxkIGJ1bmRsZWQgdGhlIHdhc20gSlMsIGlmIGVpdGhlciBvZiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgaXMgbWV0OlxuICAgICAgICAgICAgLy8gLSB0aGUgcHJveHkgd29ya2VyIGlzIGxvYWRlZCBmcm9tIGEgYmxvYiBVUkxcbiAgICAgICAgICAgIC8vIC0gYGltcG9ydC5tZXRhLnVybGAgaXMgYSBmaWxlIFVSTCwgaXQgbWVhbnMgaXQgaXMgb3ZlcndyaXR0ZW4gYnkgdGhlIGJ1bmRsZXIuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gaW4gZWl0aGVyIGNhc2UsIHRoZSBwYXRoIGluZm9ybWF0aW9uIGlzIGxvc3QsIHdlIG5lZWQgdG8gcGFzcyB0aGUgcGF0aCBvZiB0aGUgLndhc20gZmlsZSB0byB0aGUgd29ya2VyLlxuICAgICAgICAgICAgLy8gd2UgbmVlZCB0byB1c2UgdGhlIGJ1bmRsZXIgcHJlZmVycmVkIFVSTCBmb3JtYXQ6XG4gICAgICAgICAgICAvLyBuZXcgVVJMKCdmaWxlbmFtZScsIGltcG9ydC5tZXRhLnVybClcbiAgICAgICAgICAgIC8vIHNvIHRoYXQgdGhlIGJ1bmRsZXIgY2FuIGhhbmRsZSB0aGUgZmlsZSB1c2luZyBjb3JyZXNwb25kaW5nIGxvYWRlcnMuXG4gICAgICAgICAgICBtZXNzYWdlLmluIS53YXNtLndhc21QYXRocyA9IHtcbiAgICAgICAgICAgICAgd2FzbTogIUJVSUxEX0RFRlMuRElTQUJMRV9KU0VQXG4gICAgICAgICAgICAgICAgPyBuZXcgVVJMKCdvcnQtd2FzbS1zaW1kLXRocmVhZGVkLmpzZXAud2FzbScsIEJVSUxEX0RFRlMuRVNNX0lNUE9SVF9NRVRBX1VSTCkuaHJlZlxuICAgICAgICAgICAgICAgIDogQlVJTERfREVGUy5FTkFCTEVfSlNQSVxuICAgICAgICAgICAgICAgICAgPyBuZXcgVVJMKCdvcnQtd2FzbS1zaW1kLXRocmVhZGVkLmpzcGkud2FzbScsIEJVSUxEX0RFRlMuRVNNX0lNUE9SVF9NRVRBX1VSTCkuaHJlZlxuICAgICAgICAgICAgICAgICAgOiAhQlVJTERfREVGUy5ESVNBQkxFX1dFQkdQVVxuICAgICAgICAgICAgICAgICAgICA/IG5ldyBVUkwoJ29ydC13YXNtLXNpbWQtdGhyZWFkZWQuYXN5bmNpZnkud2FzbScsIEJVSUxEX0RFRlMuRVNNX0lNUE9SVF9NRVRBX1VSTCkuaHJlZlxuICAgICAgICAgICAgICAgICAgICA6IG5ldyBVUkwoJ29ydC13YXNtLXNpbWQtdGhyZWFkZWQud2FzbScsIEJVSUxEX0RFRlMuRVNNX0lNUE9SVF9NRVRBX1VSTCkuaHJlZixcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIHByb3h5V29ya2VyLnBvc3RNZXNzYWdlKG1lc3NhZ2UpO1xuICAgICAgICAgIHRlbXBvcmFyeU9iamVjdFVybCA9IG9iamVjdFVybDtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgfVxuICAgICAgfSwgcmVqZWN0KTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgaW5pdGlhbGl6ZVdlYkFzc2VtYmx5KGVudi53YXNtKTtcbiAgICAgIGF3YWl0IGNvcmUuaW5pdFJ1bnRpbWUoZW52KTtcbiAgICAgIGluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBhYm9ydGVkID0gdHJ1ZTtcbiAgICAgIHRocm93IGU7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGluaXRpYWxpemluZyA9IGZhbHNlO1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGluaXRpYWxpemVPcnRFcCA9IGFzeW5jIChlcE5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XQVNNX1BST1hZICYmIGlzUHJveHkoKSkge1xuICAgIGVuc3VyZVdvcmtlcigpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBlbnF1ZXVlQ2FsbGJhY2tzKCdpbml0LWVwJywgW3Jlc29sdmUsIHJlamVjdF0pO1xuICAgICAgY29uc3QgbWVzc2FnZTogT3J0V2FzbU1lc3NhZ2UgPSB7IHR5cGU6ICdpbml0LWVwJywgaW46IHsgZXBOYW1lLCBlbnYgfSB9O1xuICAgICAgcHJveHlXb3JrZXIhLnBvc3RNZXNzYWdlKG1lc3NhZ2UpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGF3YWl0IGNvcmUuaW5pdEVwKGVudiwgZXBOYW1lKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGNvcHlGcm9tRXh0ZXJuYWxCdWZmZXIgPSBhc3luYyAoYnVmZmVyOiBVaW50OEFycmF5KTogUHJvbWlzZTxTZXJpYWxpemFibGVJbnRlcm5hbEJ1ZmZlcj4gPT4ge1xuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XQVNNX1BST1hZICYmIGlzUHJveHkoKSkge1xuICAgIGVuc3VyZVdvcmtlcigpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxTZXJpYWxpemFibGVJbnRlcm5hbEJ1ZmZlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZW5xdWV1ZUNhbGxiYWNrcygnY29weS1mcm9tJywgW3Jlc29sdmUsIHJlamVjdF0pO1xuICAgICAgY29uc3QgbWVzc2FnZTogT3J0V2FzbU1lc3NhZ2UgPSB7IHR5cGU6ICdjb3B5LWZyb20nLCBpbjogeyBidWZmZXIgfSB9O1xuICAgICAgcHJveHlXb3JrZXIhLnBvc3RNZXNzYWdlKG1lc3NhZ2UsIFtidWZmZXIuYnVmZmVyXSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGNvcmUuY29weUZyb21FeHRlcm5hbEJ1ZmZlcihidWZmZXIpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlU2Vzc2lvbiA9IGFzeW5jIChcbiAgbW9kZWw6IFNlcmlhbGl6YWJsZUludGVybmFsQnVmZmVyIHwgVWludDhBcnJheSxcbiAgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMsXG4pOiBQcm9taXNlPFNlcmlhbGl6YWJsZVNlc3Npb25NZXRhZGF0YT4gPT4ge1xuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XQVNNX1BST1hZICYmIGlzUHJveHkoKSkge1xuICAgIC8vIGNoZWNrIHVuc3VwcG9ydGVkIG9wdGlvbnNcbiAgICBpZiAob3B0aW9ucz8ucHJlZmVycmVkT3V0cHV0TG9jYXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc2Vzc2lvbiBvcHRpb24gXCJwcmVmZXJyZWRPdXRwdXRMb2NhdGlvblwiIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHByb3h5LicpO1xuICAgIH1cbiAgICBlbnN1cmVXb3JrZXIoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8U2VyaWFsaXphYmxlU2Vzc2lvbk1ldGFkYXRhPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBlbnF1ZXVlQ2FsbGJhY2tzKCdjcmVhdGUnLCBbcmVzb2x2ZSwgcmVqZWN0XSk7XG4gICAgICBjb25zdCBtZXNzYWdlOiBPcnRXYXNtTWVzc2FnZSA9IHsgdHlwZTogJ2NyZWF0ZScsIGluOiB7IG1vZGVsLCBvcHRpb25zOiB7IC4uLm9wdGlvbnMgfSB9IH07XG4gICAgICBjb25zdCB0cmFuc2ZlcmFibGU6IFRyYW5zZmVyYWJsZVtdID0gW107XG4gICAgICBpZiAobW9kZWwgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgIHRyYW5zZmVyYWJsZS5wdXNoKG1vZGVsLmJ1ZmZlcik7XG4gICAgICB9XG4gICAgICBwcm94eVdvcmtlciEucG9zdE1lc3NhZ2UobWVzc2FnZSwgdHJhbnNmZXJhYmxlKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gY29yZS5jcmVhdGVTZXNzaW9uKG1vZGVsLCBvcHRpb25zKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHJlbGVhc2VTZXNzaW9uID0gYXN5bmMgKHNlc3Npb25JZDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGlmICghQlVJTERfREVGUy5ESVNBQkxFX1dBU01fUFJPWFkgJiYgaXNQcm94eSgpKSB7XG4gICAgZW5zdXJlV29ya2VyKCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGVucXVldWVDYWxsYmFja3MoJ3JlbGVhc2UnLCBbcmVzb2x2ZSwgcmVqZWN0XSk7XG4gICAgICBjb25zdCBtZXNzYWdlOiBPcnRXYXNtTWVzc2FnZSA9IHsgdHlwZTogJ3JlbGVhc2UnLCBpbjogc2Vzc2lvbklkIH07XG4gICAgICBwcm94eVdvcmtlciEucG9zdE1lc3NhZ2UobWVzc2FnZSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29yZS5yZWxlYXNlU2Vzc2lvbihzZXNzaW9uSWQpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcnVuID0gYXN5bmMgKFxuICBzZXNzaW9uSWQ6IG51bWJlcixcbiAgaW5wdXRJbmRpY2VzOiBudW1iZXJbXSxcbiAgaW5wdXRzOiBUZW5zb3JNZXRhZGF0YVtdLFxuICBvdXRwdXRJbmRpY2VzOiBudW1iZXJbXSxcbiAgb3V0cHV0czogQXJyYXk8VGVuc29yTWV0YWRhdGEgfCBudWxsPixcbiAgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zLFxuKTogUHJvbWlzZTxUZW5zb3JNZXRhZGF0YVtdPiA9PiB7XG4gIGlmICghQlVJTERfREVGUy5ESVNBQkxFX1dBU01fUFJPWFkgJiYgaXNQcm94eSgpKSB7XG4gICAgLy8gY2hlY2sgaW5wdXRzIGxvY2F0aW9uXG4gICAgaWYgKGlucHV0cy5zb21lKCh0KSA9PiB0WzNdICE9PSAnY3B1JykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgdGVuc29yIG9uIEdQVSBpcyBub3Qgc3VwcG9ydGVkIGZvciBwcm94eS4nKTtcbiAgICB9XG4gICAgLy8gY2hlY2sgb3V0cHV0cyBsb2NhdGlvblxuICAgIGlmIChvdXRwdXRzLnNvbWUoKHQpID0+IHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3ByZS1hbGxvY2F0ZWQgb3V0cHV0IHRlbnNvciBpcyBub3Qgc3VwcG9ydGVkIGZvciBwcm94eS4nKTtcbiAgICB9XG4gICAgZW5zdXJlV29ya2VyKCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPFNlcmlhbGl6YWJsZVRlbnNvck1ldGFkYXRhW10+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGVucXVldWVDYWxsYmFja3MoJ3J1bicsIFtyZXNvbHZlLCByZWplY3RdKTtcbiAgICAgIGNvbnN0IHNlcmlhbGl6YWJsZUlucHV0cyA9IGlucHV0cyBhcyBTZXJpYWxpemFibGVUZW5zb3JNZXRhZGF0YVtdOyAvLyBldmVyeSBpbnB1dCBpcyBvbiBDUFUuXG4gICAgICBjb25zdCBtZXNzYWdlOiBPcnRXYXNtTWVzc2FnZSA9IHtcbiAgICAgICAgdHlwZTogJ3J1bicsXG4gICAgICAgIGluOiB7IHNlc3Npb25JZCwgaW5wdXRJbmRpY2VzLCBpbnB1dHM6IHNlcmlhbGl6YWJsZUlucHV0cywgb3V0cHV0SW5kaWNlcywgb3B0aW9ucyB9LFxuICAgICAgfTtcbiAgICAgIHByb3h5V29ya2VyIS5wb3N0TWVzc2FnZShtZXNzYWdlLCBjb3JlLmV4dHJhY3RUcmFuc2ZlcmFibGVCdWZmZXJzKHNlcmlhbGl6YWJsZUlucHV0cykpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBjb3JlLnJ1bihzZXNzaW9uSWQsIGlucHV0SW5kaWNlcywgaW5wdXRzLCBvdXRwdXRJbmRpY2VzLCBvdXRwdXRzLCBvcHRpb25zKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGVuZFByb2ZpbGluZyA9IGFzeW5jIChzZXNzaW9uSWQ6IG51bWJlcik6IFByb21pc2U8dm9pZD4gPT4ge1xuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XQVNNX1BST1hZICYmIGlzUHJveHkoKSkge1xuICAgIGVuc3VyZVdvcmtlcigpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBlbnF1ZXVlQ2FsbGJhY2tzKCdlbmQtcHJvZmlsaW5nJywgW3Jlc29sdmUsIHJlamVjdF0pO1xuICAgICAgY29uc3QgbWVzc2FnZTogT3J0V2FzbU1lc3NhZ2UgPSB7IHR5cGU6ICdlbmQtcHJvZmlsaW5nJywgaW46IHNlc3Npb25JZCB9O1xuICAgICAgcHJveHlXb3JrZXIhLnBvc3RNZXNzYWdlKG1lc3NhZ2UpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNvcmUuZW5kUHJvZmlsaW5nKHNlc3Npb25JZCk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7XG4gIEluZmVyZW5jZVNlc3Npb24sXG4gIEluZmVyZW5jZVNlc3Npb25IYW5kbGVyLFxuICBTZXNzaW9uSGFuZGxlcixcbiAgVGVuc29yLFxuICBUUkFDRV9GVU5DX0JFR0lOLFxuICBUUkFDRV9GVU5DX0VORCxcbn0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHsgU2VyaWFsaXphYmxlSW50ZXJuYWxCdWZmZXIsIFRlbnNvck1ldGFkYXRhIH0gZnJvbSAnLi9wcm94eS1tZXNzYWdlcyc7XG5pbXBvcnQgeyBjb3B5RnJvbUV4dGVybmFsQnVmZmVyLCBjcmVhdGVTZXNzaW9uLCBlbmRQcm9maWxpbmcsIHJlbGVhc2VTZXNzaW9uLCBydW4gfSBmcm9tICcuL3Byb3h5LXdyYXBwZXInO1xuaW1wb3J0IHsgaXNHcHVCdWZmZXJTdXBwb3J0ZWRUeXBlLCBpc01MVGVuc29yU3VwcG9ydGVkVHlwZSB9IGZyb20gJy4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgaXNOb2RlIH0gZnJvbSAnLi93YXNtLXV0aWxzLWVudic7XG5pbXBvcnQgeyBsb2FkRmlsZSB9IGZyb20gJy4vd2FzbS11dGlscy1sb2FkLWZpbGUnO1xuXG5leHBvcnQgY29uc3QgZW5jb2RlVGVuc29yTWV0YWRhdGEgPSAodGVuc29yOiBUZW5zb3IsIGdldE5hbWU6ICgpID0+IHN0cmluZyk6IFRlbnNvck1ldGFkYXRhID0+IHtcbiAgc3dpdGNoICh0ZW5zb3IubG9jYXRpb24pIHtcbiAgICBjYXNlICdjcHUnOlxuICAgICAgcmV0dXJuIFt0ZW5zb3IudHlwZSwgdGVuc29yLmRpbXMsIHRlbnNvci5kYXRhLCAnY3B1J107XG4gICAgY2FzZSAnZ3B1LWJ1ZmZlcic6XG4gICAgICByZXR1cm4gW3RlbnNvci50eXBlLCB0ZW5zb3IuZGltcywgeyBncHVCdWZmZXI6IHRlbnNvci5ncHVCdWZmZXIgfSwgJ2dwdS1idWZmZXInXTtcbiAgICBjYXNlICdtbC10ZW5zb3InOlxuICAgICAgcmV0dXJuIFt0ZW5zb3IudHlwZSwgdGVuc29yLmRpbXMsIHsgbWxUZW5zb3I6IHRlbnNvci5tbFRlbnNvciB9LCAnbWwtdGVuc29yJ107XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBkYXRhIGxvY2F0aW9uOiAke3RlbnNvci5sb2NhdGlvbn0gZm9yICR7Z2V0TmFtZSgpfWApO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZGVjb2RlVGVuc29yTWV0YWRhdGEgPSAodGVuc29yOiBUZW5zb3JNZXRhZGF0YSk6IFRlbnNvciA9PiB7XG4gIHN3aXRjaCAodGVuc29yWzNdKSB7XG4gICAgY2FzZSAnY3B1JzpcbiAgICAgIHJldHVybiBuZXcgVGVuc29yKHRlbnNvclswXSwgdGVuc29yWzJdLCB0ZW5zb3JbMV0pO1xuICAgIGNhc2UgJ2dwdS1idWZmZXInOiB7XG4gICAgICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclswXTtcbiAgICAgIGlmICghaXNHcHVCdWZmZXJTdXBwb3J0ZWRUeXBlKGRhdGFUeXBlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG5vdCBzdXBwb3J0ZWQgZGF0YSB0eXBlOiAke2RhdGFUeXBlfSBmb3IgZGVzZXJpYWxpemluZyBHUFUgdGVuc29yYCk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IGdwdUJ1ZmZlciwgZG93bmxvYWQsIGRpc3Bvc2UgfSA9IHRlbnNvclsyXTtcbiAgICAgIHJldHVybiBUZW5zb3IuZnJvbUdwdUJ1ZmZlcihncHVCdWZmZXIsIHsgZGF0YVR5cGUsIGRpbXM6IHRlbnNvclsxXSwgZG93bmxvYWQsIGRpc3Bvc2UgfSk7XG4gICAgfVxuICAgIGNhc2UgJ21sLXRlbnNvcic6IHtcbiAgICAgIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yWzBdO1xuICAgICAgaWYgKCFpc01MVGVuc29yU3VwcG9ydGVkVHlwZShkYXRhVHlwZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBub3Qgc3VwcG9ydGVkIGRhdGEgdHlwZTogJHtkYXRhVHlwZX0gZm9yIGRlc2VyaWFsaXppbmcgTUxUZW5zb3IgdGVuc29yYCk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IG1sVGVuc29yLCBkb3dubG9hZCwgZGlzcG9zZSB9ID0gdGVuc29yWzJdO1xuICAgICAgcmV0dXJuIFRlbnNvci5mcm9tTUxUZW5zb3IobWxUZW5zb3IsIHsgZGF0YVR5cGUsIGRpbXM6IHRlbnNvclsxXSwgZG93bmxvYWQsIGRpc3Bvc2UgfSk7XG4gICAgfVxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgZGF0YSBsb2NhdGlvbjogJHt0ZW5zb3JbM119YCk7XG4gIH1cbn07XG5cbmV4cG9ydCBjbGFzcyBPbm54cnVudGltZVdlYkFzc2VtYmx5U2Vzc2lvbkhhbmRsZXIgaW1wbGVtZW50cyBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciB7XG4gIHByaXZhdGUgc2Vzc2lvbklkOiBudW1iZXI7XG5cbiAgaW5wdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG4gIG91dHB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgaW5wdXRNZXRhZGF0YTogcmVhZG9ubHkgSW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhW107XG4gIG91dHB1dE1ldGFkYXRhOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXTtcblxuICBhc3luYyBmZXRjaE1vZGVsQW5kQ29weVRvV2FzbU1lbW9yeShwYXRoOiBzdHJpbmcpOiBQcm9taXNlPFNlcmlhbGl6YWJsZUludGVybmFsQnVmZmVyPiB7XG4gICAgLy8gZmV0Y2ggbW9kZWwgZnJvbSB1cmwgYW5kIG1vdmUgdG8gd2FzbSBoZWFwLlxuICAgIHJldHVybiBjb3B5RnJvbUV4dGVybmFsQnVmZmVyKGF3YWl0IGxvYWRGaWxlKHBhdGgpKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWRNb2RlbChwYXRoT3JCdWZmZXI6IHN0cmluZyB8IFVpbnQ4QXJyYXksIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgVFJBQ0VfRlVOQ19CRUdJTigpO1xuICAgIGxldCBtb2RlbDogUGFyYW1ldGVyczx0eXBlb2YgY3JlYXRlU2Vzc2lvbj5bMF07XG5cbiAgICBpZiAodHlwZW9mIHBhdGhPckJ1ZmZlciA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmIChpc05vZGUpIHtcbiAgICAgICAgLy8gbm9kZVxuICAgICAgICBtb2RlbCA9IGF3YWl0IGxvYWRGaWxlKHBhdGhPckJ1ZmZlcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBicm93c2VyXG4gICAgICAgIC8vIGZldGNoIG1vZGVsIGFuZCBjb3B5IHRvIHdhc20gaGVhcC5cbiAgICAgICAgbW9kZWwgPSBhd2FpdCB0aGlzLmZldGNoTW9kZWxBbmRDb3B5VG9XYXNtTWVtb3J5KHBhdGhPckJ1ZmZlcik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG1vZGVsID0gcGF0aE9yQnVmZmVyO1xuICAgIH1cblxuICAgIFt0aGlzLnNlc3Npb25JZCwgdGhpcy5pbnB1dE5hbWVzLCB0aGlzLm91dHB1dE5hbWVzLCB0aGlzLmlucHV0TWV0YWRhdGEsIHRoaXMub3V0cHV0TWV0YWRhdGFdID0gYXdhaXQgY3JlYXRlU2Vzc2lvbihcbiAgICAgIG1vZGVsLFxuICAgICAgb3B0aW9ucyxcbiAgICApO1xuICAgIFRSQUNFX0ZVTkNfRU5EKCk7XG4gIH1cblxuICBhc3luYyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiByZWxlYXNlU2Vzc2lvbih0aGlzLnNlc3Npb25JZCk7XG4gIH1cblxuICBhc3luYyBydW4oXG4gICAgZmVlZHM6IFNlc3Npb25IYW5kbGVyLkZlZWRzVHlwZSxcbiAgICBmZXRjaGVzOiBTZXNzaW9uSGFuZGxlci5GZXRjaGVzVHlwZSxcbiAgICBvcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMsXG4gICk6IFByb21pc2U8U2Vzc2lvbkhhbmRsZXIuUmV0dXJuVHlwZT4ge1xuICAgIFRSQUNFX0ZVTkNfQkVHSU4oKTtcbiAgICBjb25zdCBpbnB1dEFycmF5OiBUZW5zb3JbXSA9IFtdO1xuICAgIGNvbnN0IGlucHV0SW5kaWNlczogbnVtYmVyW10gPSBbXTtcbiAgICBPYmplY3QuZW50cmllcyhmZWVkcykuZm9yRWFjaCgoa3ZwKSA9PiB7XG4gICAgICBjb25zdCBuYW1lID0ga3ZwWzBdO1xuICAgICAgY29uc3QgdGVuc29yID0ga3ZwWzFdO1xuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLmlucHV0TmFtZXMuaW5kZXhPZihuYW1lKTtcbiAgICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIGlucHV0ICcke25hbWV9J2ApO1xuICAgICAgfVxuICAgICAgaW5wdXRBcnJheS5wdXNoKHRlbnNvcik7XG4gICAgICBpbnB1dEluZGljZXMucHVzaChpbmRleCk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBvdXRwdXRBcnJheTogQXJyYXk8VGVuc29yIHwgbnVsbD4gPSBbXTtcbiAgICBjb25zdCBvdXRwdXRJbmRpY2VzOiBudW1iZXJbXSA9IFtdO1xuICAgIE9iamVjdC5lbnRyaWVzKGZldGNoZXMpLmZvckVhY2goKGt2cCkgPT4ge1xuICAgICAgY29uc3QgbmFtZSA9IGt2cFswXTtcbiAgICAgIGNvbnN0IHRlbnNvciA9IGt2cFsxXTtcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5vdXRwdXROYW1lcy5pbmRleE9mKG5hbWUpO1xuICAgICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgb3V0cHV0ICcke25hbWV9J2ApO1xuICAgICAgfVxuICAgICAgb3V0cHV0QXJyYXkucHVzaCh0ZW5zb3IpO1xuICAgICAgb3V0cHV0SW5kaWNlcy5wdXNoKGluZGV4KTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGlucHV0cyA9IGlucHV0QXJyYXkubWFwKCh0LCBpKSA9PlxuICAgICAgZW5jb2RlVGVuc29yTWV0YWRhdGEodCwgKCkgPT4gYGlucHV0IFwiJHt0aGlzLmlucHV0TmFtZXNbaW5wdXRJbmRpY2VzW2ldXX1cImApLFxuICAgICk7XG4gICAgY29uc3Qgb3V0cHV0cyA9IG91dHB1dEFycmF5Lm1hcCgodCwgaSkgPT5cbiAgICAgIHQgPyBlbmNvZGVUZW5zb3JNZXRhZGF0YSh0LCAoKSA9PiBgb3V0cHV0IFwiJHt0aGlzLm91dHB1dE5hbWVzW291dHB1dEluZGljZXNbaV1dfVwiYCkgOiBudWxsLFxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgcnVuKHRoaXMuc2Vzc2lvbklkLCBpbnB1dEluZGljZXMsIGlucHV0cywgb3V0cHV0SW5kaWNlcywgb3V0cHV0cywgb3B0aW9ucyk7XG5cbiAgICBjb25zdCByZXN1bHRNYXA6IFNlc3Npb25IYW5kbGVyLlJldHVyblR5cGUgPSB7fTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc3VsdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdE1hcFt0aGlzLm91dHB1dE5hbWVzW291dHB1dEluZGljZXNbaV1dXSA9IG91dHB1dEFycmF5W2ldID8/IGRlY29kZVRlbnNvck1ldGFkYXRhKHJlc3VsdHNbaV0pO1xuICAgIH1cbiAgICBUUkFDRV9GVU5DX0VORCgpO1xuICAgIHJldHVybiByZXN1bHRNYXA7XG4gIH1cblxuICBzdGFydFByb2ZpbGluZygpOiB2b2lkIHtcbiAgICAvLyBUT0RPOiBpbXBsZW1lbnQgcHJvZmlsaW5nXG4gIH1cblxuICBlbmRQcm9maWxpbmcoKTogdm9pZCB7XG4gICAgdm9pZCBlbmRQcm9maWxpbmcodGhpcy5zZXNzaW9uSWQpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEJhY2tlbmQsIGVudiwgSW5mZXJlbmNlU2Vzc2lvbiwgSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBpbml0aWFsaXplT3J0RXAsIGluaXRpYWxpemVXZWJBc3NlbWJseUFuZE9ydFJ1bnRpbWUgfSBmcm9tICcuL3dhc20vcHJveHktd3JhcHBlcic7XG5pbXBvcnQgeyBPbm54cnVudGltZVdlYkFzc2VtYmx5U2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuL3dhc20vc2Vzc2lvbi1oYW5kbGVyLWluZmVyZW5jZSc7XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBpbml0aWFsaXplcyBhbGwgZmxhZ3MgZm9yIFdlYkFzc2VtYmx5LlxuICpcbiAqIFRob3NlIGZsYWdzIGFyZSBhY2Nlc3NpYmxlIGZyb20gYG9ydC5lbnYud2FzbWAuIFVzZXJzIGFyZSBhbGxvdyB0byBzZXQgdGhvc2UgZmxhZ3MgYmVmb3JlIHRoZSBmaXJzdCBpbmZlcmVuY2Ugc2Vzc2lvblxuICogYmVpbmcgY3JlYXRlZCwgdG8gb3ZlcnJpZGUgZGVmYXVsdCB2YWx1ZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGluaXRpYWxpemVGbGFncyA9ICgpOiB2b2lkID0+IHtcbiAgaWYgKHR5cGVvZiBlbnYud2FzbS5pbml0VGltZW91dCAhPT0gJ251bWJlcicgfHwgZW52Lndhc20uaW5pdFRpbWVvdXQgPCAwKSB7XG4gICAgZW52Lndhc20uaW5pdFRpbWVvdXQgPSAwO1xuICB9XG5cbiAgY29uc3Qgc2ltZCA9IGVudi53YXNtLnNpbWQ7XG4gIGlmICh0eXBlb2Ygc2ltZCAhPT0gJ2Jvb2xlYW4nICYmIHNpbWQgIT09IHVuZGVmaW5lZCAmJiBzaW1kICE9PSAnZml4ZWQnICYmIHNpbWQgIT09ICdyZWxheGVkJykge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS53YXJuKFxuICAgICAgYFByb3BlcnR5IFwiZW52Lndhc20uc2ltZFwiIGlzIHNldCB0byB1bmtub3duIHZhbHVlIFwiJHtzaW1kfVwiLiBSZXNldCBpdCB0byBcXGBmYWxzZVxcYCBhbmQgaWdub3JlIFNJTUQgZmVhdHVyZSBjaGVja2luZy5gLFxuICAgICk7XG4gICAgZW52Lndhc20uc2ltZCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBlbnYud2FzbS5wcm94eSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgZW52Lndhc20ucHJveHkgPSBmYWxzZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZW52Lndhc20udHJhY2UgIT09ICdib29sZWFuJykge1xuICAgIGVudi53YXNtLnRyYWNlID0gZmFsc2U7XG4gIH1cblxuICBpZiAodHlwZW9mIGVudi53YXNtLm51bVRocmVhZHMgIT09ICdudW1iZXInIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKGVudi53YXNtLm51bVRocmVhZHMpIHx8IGVudi53YXNtLm51bVRocmVhZHMgPD0gMCkge1xuICAgIC8vIFRoZSBmb2xsb3dpbmcgbG9naWMgb25seSBhcHBsaWVzIHdoZW4gYG9ydC5lbnYud2FzbS5udW1UaHJlYWRzYCBpcyBub3Qgc2V0IGJ5IHVzZXIuIFdlIHdpbGwgYWx3YXlzIGhvbm9yIHVzZXInc1xuICAgIC8vIHNldHRpbmcgaWYgaXQgaXMgcHJvdmlkZWQuXG5cbiAgICAvLyBCcm93c2VyOiB3aGVuIGNyb3NzT3JpZ2luSXNvbGF0ZWQgaXMgZmFsc2UsIFNoYXJlZEFycmF5QnVmZmVyIGlzIG5vdCBhdmFpbGFibGUgc28gV2ViQXNzZW1ibHkgdGhyZWFkcyB3aWxsIG5vdFxuICAgIC8vIHdvcmsuIEluIHRoaXMgY2FzZSwgd2Ugd2lsbCBzZXQgbnVtVGhyZWFkcyB0byAxLlxuICAgIC8vXG4gICAgLy8gVGhlcmUgaXMgYW4gZXhjZXB0aW9uOiB3aGVuIHRoZSBicm93c2VyIGlzIGNvbmZpZ3VyZWQgdG8gZm9yY2UtZW5hYmxlIFNoYXJlZEFycmF5QnVmZmVyIChlLmcuIENocm9tdWltIHdpdGhcbiAgICAvLyAtLWVuYWJsZS1mZWF0dXJlcz1TaGFyZWRBcnJheUJ1ZmZlciksIGl0IGlzIHBvc3NpYmxlIHRoYXQgYHNlbGYuY3Jvc3NPcmlnaW5Jc29sYXRlZGAgaXMgZmFsc2UgYW5kXG4gICAgLy8gU2hhcmVkQXJyYXlCdWZmZXIgaXMgYXZhaWxhYmxlIGF0IHRoZSBzYW1lIHRpbWUuIFRoaXMgaXMgdXN1YWxseSBmb3IgdGVzdGluZy4gSW4gdGhpcyBjYXNlLCAgd2Ugd2lsbCBzdGlsbCBzZXRcbiAgICAvLyBudW1UaHJlYWRzIHRvIDEgaGVyZS4gSWYgd2Ugd2FudCB0byBlbmFibGUgbXVsdGktdGhyZWFkaW5nIGluIHRlc3QsIHdlIHNob3VsZCBzZXQgYG9ydC5lbnYud2FzbS5udW1UaHJlYWRzYCB0byBhXG4gICAgLy8gdmFsdWUgZ3JlYXRlciB0aGFuIDEuXG4gICAgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyAmJiAhc2VsZi5jcm9zc09yaWdpbklzb2xhdGVkKSB7XG4gICAgICBlbnYud2FzbS5udW1UaHJlYWRzID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbnVtQ3B1TG9naWNhbENvcmVzID1cbiAgICAgICAgdHlwZW9mIG5hdmlnYXRvciA9PT0gJ3VuZGVmaW5lZCcgPyByZXF1aXJlKCdub2RlOm9zJykuY3B1cygpLmxlbmd0aCA6IG5hdmlnYXRvci5oYXJkd2FyZUNvbmN1cnJlbmN5O1xuICAgICAgZW52Lndhc20ubnVtVGhyZWFkcyA9IE1hdGgubWluKDQsIE1hdGguY2VpbCgobnVtQ3B1TG9naWNhbENvcmVzIHx8IDEpIC8gMikpO1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0IGNsYXNzIE9ubnhydW50aW1lV2ViQXNzZW1ibHlCYWNrZW5kIGltcGxlbWVudHMgQmFja2VuZCB7XG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGluaXRpYWxpemVzIHRoZSBXZWJBc3NlbWJseSBiYWNrZW5kLlxuICAgKlxuICAgKiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIG9ubHkgb25jZSBmb3IgZWFjaCBiYWNrZW5kIG5hbWUuIEl0IHdpbGwgYmUgY2FsbGVkIHRoZSBmaXJzdCB0aW1lIHdoZW5cbiAgICogYG9ydC5JbmZlcmVuY2VTZXNzaW9uLmNyZWF0ZSgpYCBpcyBjYWxsZWQgd2l0aCBhIHJlZ2lzdGVyZWQgYmFja2VuZCBuYW1lLlxuICAgKlxuICAgKiBAcGFyYW0gYmFja2VuZE5hbWUgLSB0aGUgcmVnaXN0ZXJlZCBiYWNrZW5kIG5hbWUuXG4gICAqL1xuICBhc3luYyBpbml0KGJhY2tlbmROYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBwb3B1bGF0ZSB3YXNtIGZsYWdzXG4gICAgaW5pdGlhbGl6ZUZsYWdzKCk7XG5cbiAgICAvLyBpbml0IHdhc21cbiAgICBhd2FpdCBpbml0aWFsaXplV2ViQXNzZW1ibHlBbmRPcnRSdW50aW1lKCk7XG5cbiAgICAvLyBwZXJmb3JtZSBFUCBzcGVjaWZpYyBpbml0aWFsaXphdGlvblxuICAgIGF3YWl0IGluaXRpYWxpemVPcnRFcChiYWNrZW5kTmFtZSk7XG4gIH1cbiAgY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIoXG4gICAgcGF0aDogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25IYW5kbGVyPjtcbiAgY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIoXG4gICAgYnVmZmVyOiBVaW50OEFycmF5LFxuICAgIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25IYW5kbGVyPjtcbiAgYXN5bmMgY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIoXG4gICAgcGF0aE9yQnVmZmVyOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25IYW5kbGVyPiB7XG4gICAgY29uc3QgaGFuZGxlciA9IG5ldyBPbm54cnVudGltZVdlYkFzc2VtYmx5U2Vzc2lvbkhhbmRsZXIoKTtcbiAgICBhd2FpdCBoYW5kbGVyLmxvYWRNb2RlbChwYXRoT3JCdWZmZXIsIG9wdGlvbnMpO1xuICAgIHJldHVybiBoYW5kbGVyO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCB3YXNtQmFja2VuZCA9IG5ldyBPbm54cnVudGltZVdlYkFzc2VtYmx5QmFja2VuZCgpO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzICovXG5cbi8vIFdlIHVzZSBcInJlcXVpcmVcIiBpbnN0ZWFkIG9mIFwiaW1wb3J0XCIgaGVyZSBiZWNhdXNlIGltcG9ydCBzdGF0ZW1lbnQgbXVzdCBiZSBwdXQgaW4gdG9wIGxldmVsLiBPdXIgY3VycmVudCBjb2RlIGRvZXNcbi8vIG5vdCBhbGxvdyBidW5kbGVyIHRvIHRyZWUtc2hha2luZyBjb2RlIGFzIGV4cGVjdGVkIGJlY2F1c2Ugc29tZSBjb2RlcyBhcmUgdHJlYXRlZCBhcyBoYXZpbmcgc2lkZSBlZmZlY3RzLlxuLy8gU28gd2UgaW1wb3J0IGNvZGUgaW5zaWRlIHRoZSBpZi1jbGF1c2UgdG8gYWxsb3cgYnVuZGxlciByZW1vdmUgdGhlIGNvZGUgc2FmZWx5LlxuXG5leHBvcnQgKiBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuaW1wb3J0ICogYXMgb3J0IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5leHBvcnQgZGVmYXVsdCBvcnQ7XG5cbmltcG9ydCB7IHJlZ2lzdGVyQmFja2VuZCwgZW52IH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcbmltcG9ydCB7IHZlcnNpb24gfSBmcm9tICcuL3ZlcnNpb24nO1xuXG5pZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XRUJHTCkge1xuICBjb25zdCBvbm54anNCYWNrZW5kID0gcmVxdWlyZSgnLi9iYWNrZW5kLW9ubnhqcycpLm9ubnhqc0JhY2tlbmQ7XG4gIHJlZ2lzdGVyQmFja2VuZCgnd2ViZ2wnLCBvbm54anNCYWNrZW5kLCAtMTApO1xufVxuXG5pZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9KU0VQICYmICFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR1BVKSB7XG4gIHRocm93IG5ldyBFcnJvcihcbiAgICAnVGhlIGN1cnJlbnQgYnVpbGQgaXMgc3BlY2lmaWVkIHRvIGVuYWJsZSBib3RoIEpTRVAgYW5kIFdlYkdQVSBFUC4gVGhpcyBpcyBub3QgYSB2YWxpZCBjb25maWd1cmF0aW9uLiAnICtcbiAgICAgICdKU0VQIGFuZCBXZWJHUFUgRVBzIGNhbm5vdCBiZSBlbmFibGVkIGF0IHRoZSBzYW1lIHRpbWUuJyxcbiAgKTtcbn1cblxuaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCTk4gJiYgQlVJTERfREVGUy5ESVNBQkxFX0pTRVAgJiYgQlVJTERfREVGUy5ESVNBQkxFX1dFQkdQVSkge1xuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgJ1RoZSBjdXJyZW50IGJ1aWxkIGlzIHNwZWNpZmllZCB0byBlbmFibGUgV2ViTk4gRVAgd2l0aG91dCBKU0VQIG9yIFdlYkdQVSBFUC4gVGhpcyBpcyBub3QgYSB2YWxpZCBjb25maWd1cmF0aW9uLiAnICtcbiAgICAgICdXZWJOTiBFUCByZXF1aXJlcyBlaXRoZXIgSlNFUCBvciBXZWJHUFUgRVAgdG8gYmUgZW5hYmxlZC4nLFxuICApO1xufVxuXG5pZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XQVNNKSB7XG4gIGNvbnN0IHdhc21CYWNrZW5kID0gcmVxdWlyZSgnLi9iYWNrZW5kLXdhc20nKS53YXNtQmFja2VuZDtcbiAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfSlNFUCB8fCAhQlVJTERfREVGUy5ESVNBQkxFX1dFQkdQVSkge1xuICAgIHJlZ2lzdGVyQmFja2VuZCgnd2ViZ3B1Jywgd2FzbUJhY2tlbmQsIDUpO1xuICB9XG4gIGlmICghQlVJTERfREVGUy5ESVNBQkxFX1dFQk5OKSB7XG4gICAgcmVnaXN0ZXJCYWNrZW5kKCd3ZWJubicsIHdhc21CYWNrZW5kLCA1KTtcbiAgfVxuICByZWdpc3RlckJhY2tlbmQoJ2NwdScsIHdhc21CYWNrZW5kLCAxMCk7XG4gIHJlZ2lzdGVyQmFja2VuZCgnd2FzbScsIHdhc21CYWNrZW5kLCAxMCk7XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbnYudmVyc2lvbnMsICd3ZWInLCB7IHZhbHVlOiB2ZXJzaW9uLCBlbnVtZXJhYmxlOiB0cnVlIH0pO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkIGJ5IC9qcy9zY3JpcHRzL3VwZGF0ZS12ZXJzaW9uLnRzXG4vLyBEbyBub3QgbW9kaWZ5IGZpbGUgY29udGVudCBtYW51YWxseS5cblxuZXhwb3J0IGNvbnN0IHZlcnNpb24gPSAnMS4yNi4wJztcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE1BZ0JNLFVBQ0EsMEJBWU8saUJBd0NQLGdDQXdDTztBQTdHYjs7O0FBZ0JBLE1BQU0sV0FBcUMsb0JBQUksSUFBRztBQUNsRCxNQUFNLDJCQUFxQyxDQUFBO0FBWXBDLE1BQU0sa0JBQWtCLENBQUNBLE9BQWNDLFVBQWtCLGFBQTBCO0FBQ3hGLFlBQUlBLFlBQVcsT0FBT0EsU0FBUSxTQUFTLGNBQWMsT0FBT0EsU0FBUSxrQ0FBa0MsWUFBWTtBQUNoSCxnQkFBTSxpQkFBaUIsU0FBUyxJQUFJRCxLQUFJO0FBQ3hDLGNBQUksbUJBQW1CLFFBQVc7QUFDaEMscUJBQVMsSUFBSUEsT0FBTSxFQUFFLFNBQUFDLFVBQVMsU0FBUSxDQUFFO3FCQUMvQixlQUFlLFdBQVcsVUFBVTtBQUU3QztxQkFDUyxlQUFlLGFBQWEsVUFBVTtBQUMvQyxnQkFBSSxlQUFlLFlBQVlBLFVBQVM7QUFDdEMsb0JBQU0sSUFBSSxNQUFNLDRCQUE0QkQsS0FBSSxvQkFBb0IsUUFBUSxFQUFFOzs7QUFJbEYsY0FBSSxZQUFZLEdBQUc7QUFDakIsa0JBQU0sSUFBSSx5QkFBeUIsUUFBUUEsS0FBSTtBQUMvQyxnQkFBSSxNQUFNLElBQUk7QUFDWix1Q0FBeUIsT0FBTyxHQUFHLENBQUM7O0FBR3RDLHFCQUFTRSxLQUFJ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SSxPQUFPO0FBQ1gsVUFBSTtBQUNGLGVBQU8sSUFBSSxZQUFZLFNBQVMsSUFBSSxZQUFZLE9BQU8sSUFBSSxXQUFXO0FBQUEsVUFDcEU7QUFBQSxVQUFHO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFHO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFJO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFLO0FB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ZXMiOiBbIm5hbWUiLCAiYmFja2VuZCIsICJpIiwgImVudiIsICJjcmVhdGVDYW52YXMiLCAiRmxvYXQxNkFycmF5IiwgIlRlbnNvciIsICJUZW5zb3IiLCAibmFtZSIsICJiYWNrZW5kIiwgIkluZmVyZW5jZVNlc3Npb24iLCAiSW5mZXJlbmNlU2Vzc2lvbiIsICJUZW5zb3IiLCAiZW52IiwgImxvZyIsICJlbnYiLCAibmFtZSIsICJ2ZXJzaW9uIiwgImV4cG9ydHMiLCAiR3VpZCIsICJndWlkIiwgImNhY2hlIiwgImRpdiIsICJsb2cyIiwgIkFyZ1R5cGUiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgImV4cG9ydHMiLCAiZXhwb3J0cyIsICJFbmNvZGluZyIsICJleHBvcnRzIiwgIkJ5dGVCdWZmZXIiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgImV4cG9ydHMiLCAibW9kIiwgIkFyZ1R5cGVBbmRJbmRleCIsICJmbGF0YnVmZmVycyIsICJBdHRyaWJ1dGVUeXBlIiwgImV4cG9ydHMiLCAiTm9kZVR5cGUiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgIm1vZCIsICJOb2RlIiwgImZsYXRidWZmZXJzIiwgIkVkZ2VFbmQiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgIm1vZCIsICJOb2RlRWRnZSIsICJmbGF0YnVmZmVycyIsICJleHBvcnRzIiwgIm1vZCIsICJmbGF0YnVmZmVycyIsICJOb2Rlc1RvT3B0aW1pemVJbmRpY2VzIiwgIm1vZCIsICJleHBvcnRzIiwgIlJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQiLCAiZmxhdGJ1ZmZlcnMiLCAiZXhwb3J0cyIsICJtb2QiLCAiUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5IiwgImZsYXRidWZmZXJzIiwgImV4cG9ydHMiLCAibW9kIiwgIlJ1bnRpbWVPcHRpbWl6YXRpb25zIiwgImZsYXRidWZmZXJzIiwgIlRlbnNvckRhdGFUeXBlIiwgImV4cG9ydHMiLCAiZXhwb3J0cyIsICJtb2QiLCAiVGVuc29yIiwgImZsYXRidWZmZXJzIiwgImV4cG9ydHMiLCAibW9kIiwgIlNwYXJzZVRlbnNvciIsICJmbGF0YnVmZmVycyIsICJleHBvcnRzIiwgIm1vZCIsICJNYXBUeXBlIiwgImZsYXRidWZmZXJzIiwgImV4cG9ydHMiLCAibW9kIiwgIlNlcXVlbmNlVHlwZSIsICJmbGF0YnVmZmVycyIsICJEaW1lbnNpb25WYWx1ZVR5cGUiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgIm1vZCIsICJEaW1lbnNpb25WYWx1ZSIsICJmbGF0YnVmZmVycyIsICJleHBvcnRzIiwgIm1vZCIsICJEaW1lbnNpb24iLCAiZmxhdGJ1ZmZlcnMiLCAiZXhwb3J0cyIsICJtb2QiLCAiU2hhcGUiLCAiZmxhdGJ1ZmZlcnMiLCAiZXhwb3J0cyIsICJtb2QiLCAiVGVuc29yVHlwZUFuZFNoYXBlIiwgImZsYXRidWZmZXJzIiwgIlR5cGVJbmZvVmFsdWUiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgIm1vZCIsICJUeXBlSW5mbyIsICJmbGF0YnVmZmVycyIsICJleHBvcnRzIiwgIm1vZCIsICJWYWx1ZUluZm8iLCAiZmxhdGJ1ZmZlcnMiLCAiZXhwb3J0cyIsICJtb2QiLCAiZmxhdGJ1ZmZlcnMiLCAiR3JhcGgiLCAiZXhwb3J0cyIsICJtb2QiLCAiZmxhdGJ1ZmZlcnMiLCAiQXR0cmlidXRlIiwgImV4cG9ydHMiLCAibW9kIiwgImZsYXRidWZmZXJzIiwgIkRlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyIsICJleHBvcnRzIiwgIm1vZCIsICJmbGF0YnVmZmVycyIsICJEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCIsICJleHBvcnRzIiwgIm1vZCIsICJmbGF0YnVmZmVycyIsICJEZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUiLCAibW9kIiwgImV4cG9ydHMiLCAiRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSIsICJmbGF0YnVmZmVycyIsICJleHBvcnRzIiwgIm1vZCIsICJLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IiwgImZsYXRidWZmZXJzIiwgImV4cG9ydHMiLCAibW9kIiwgIk9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IiwgImZsYXRidWZmZXJzIiwgImV4cG9ydHMiLCAibW9kIiwgIktlcm5lbFR5cGVTdHJSZXNvbHZlciIsICJmbGF0YnVmZmVycyIsICJleHBvcnRzIiwgIm1vZCIsICJmbGF0YnVmZmVycyIsICJPcGVyYXRvclNldElkIiwgImV4cG9ydHMiLCAibW9kIiwgImZsYXRidWZmZXJzIiwgIlN0cmluZ1N0cmluZ0VudHJ5IiwgImV4cG9ydHMiLCAibW9kIiwgImZsYXRidWZmZXJzIiwgIk1vZGVsIiwgImV4cG9ydHMiLCAibW9kIiwgIkluZmVyZW5jZVNlc3Npb24iLCAiZmxhdGJ1ZmZlcnMiLCAiaW1wb3J0X3RlbnNvciIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJwYXJhbXMiLCAib2Zmc2V0IiwgImV4cG9ydHMiLCAiaSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJleHBvcnRzIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgInNsaWNlIiwgInNpemUiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiZnJvbU51bWJlciIsICJ0b051bWJlciIsICJleHBvcnRzIiwgIkJ1ZmZlciIsICJuYW1lIiwgImkiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiY3JlYXRlIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImNyZWF0ZV9hcnJheSIsICJjcmVhdGUiLCAiYnVmZmVyIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgInNlbGYiLCAiZXJyIiwgImV4cG9ydHMiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiZXhwb3J0cyIsICJyZXF1aXJlX21pbmltYWwiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAib25ueCIsICJEaW1lbnNpb24iLCAiVGVuc29yIiwgIk1hcCIsICJTcGFyc2VUZW5zb3IiLCAiaW5pdF90ZW5zb3IiLCAiVGVuc29yIiwgInNoYXBlIiwgInBhZCIsICJzcGxpdCIsICJpbXBvcnRfb25ueCIsICJUZW5zb3IiLCAiaW5pdF90ZW5zb3IiLCAiY2FjaGUiLCAidmVyc2lvbiIsICJuYW1lIiwgInNoYXBlIiwgInNoYXBlIiwgInNoYXBlIiwgImluaXRfdGVuc29yIiwgInNoYXBlIiwgIlRlbnNvciIsICJuYW1lIiwgIm5hbWUiLCAibmFtZSIsICJhZGQiLCAiYW5kIiwgIm9yIiwgInhvciIsICJnbHNsIiwgInNoYWRlclNvdXJjZSIsICJ2YWxpZGF0ZUlucHV0cyIsICJzaGlmdCIsICJ2YWxpZGF0ZUlucHV0cyIsICJuYW1lIiwgImxvZyIsICJub3QiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAibmFtZSIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJzaGFwZSIsICJ2YWxpZGF0ZUlucHV0cyIsICJzdW0iLCAidmFsaWRhdGVJbnB1dHMiLCAibmFtZSIsICJyZWR1Y2VPcHMiLCAiaW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgImRpbSIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJpbml0X3RlbnNvciIsICJUZW5zb3IiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAic3BsaXQiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHNWMTMiLCAiYWRkIiwgImFuZCIsICJsb2ciLCAibm90IiwgIm9yIiwgInhvciIsICJuYW1lIiwgInNoYXBlIiwgInNoYXBlIiwgIm5hbWUiLCAic291cmNlIiwgInBhY2tlZFNhbXBsZXIiLCAidGV4TnVtUiIsICJ0ZXhOdW1DIiwgInRyYW5zcG9zZSIsICJuYW1lIiwgInNoYXBlIiwgImkiLCAibmFtZSIsICJuYW1lIiwgImVudiIsICJuYW1lIiwgImxvY2F0aW9uIiwgInRleHR1cmUiLCAiYmFja2VuZCIsICJ2ZXJzaW9uIiwgImVudiIsICJlbnYiLCAiY2FjaGUiLCAiYmFja2VuZCIsICJpbml0IiwgImluaXRfYmFja2VuZCIsICJvdXRwdXQiLCAiaW1wb3J0X29ubngiLCAiQXR0cmlidXRlIiwgImluaXRfdGVuc29yIiwgIlRlbnNvciIsICJ2YWx1ZSIsICJpbXBvcnRfb25ueCIsICJHcmFwaCIsICJOb2RlIiwgImluaXRfdGVuc29yIiwgIm5hbWUiLCAiQXR0cmlidXRlIiwgIlRlbnNvciIsICJzaGFwZSIsICJub2RlSW5kZXgiLCAiaW1wb3J0X29ubngiLCAiTW9kZWwiLCAiR3JhcGgiLCAiaW5pdF9iYWNrZW5kIiwgImJhY2tlbmQiLCAiTW9kZWwiLCAiaW5pdF90ZW5zb3IiLCAibmFtZSIsICJUZW5zb3IiLCAiZW52IiwgIndhc20iLCAibW9kdWxlIiwgIndhc20iLCAibmFtZSIsICJ3YXNtIiwgIndhc20iLCAibmFtZSIsICJsb2NhdGlvbiIsICJNYXRNdWxVdGlsIiwgIkJyb2FkY2FzdFV0aWwiLCAiU2hhcGVVdGlsIiwgIlBvb2xDb252VXRpbCIsICJHZW1tVXRpbCIsICJNSU5fQ0xJUCIsICJNQVhfQ0xJUCIsICJpbml0X3V0aWwiLCAic2hhcGUiLCAicGFkIiwgImNyZWF0ZVZpZXciLCAic2hhcGUiLCAiYmFja2VuZCIsICJ0ZW5zb3IiLCAiZW52IiwgIm1sQ29udGV4dEluZGV4IiwgInNoYXBlIiwgIndhc20iLCAiY3JlYXRlVmlldyIsICJpbml0X3R5cGVzIiwgImluaXRfdHlwZXMiLCAiYmFja2VuZCIsICJBdHRyaWJ1dGVXaXRoQ2FjaGVLZXlJbXBsIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJuYW1lIiwgImluaXRfdXRpbCIsICJTaGFwZVV0aWwiLCAibmFtZSIsICJzaGFwZSIsICJvZmZzZXRUb0luZGljZXMiLCAiaW5pdCIsICJvZmZzZXRzIiwgImluZGljZXMiLCAiaW1wbCIsICJ2YWxpZGF0ZUlucHV0cyIsICJnZXRBZGp1c3RlZFBlcm0iLCAiZ2V0T3V0cHV0U2hhcGUiLCAic3F1ZWV6ZVNoYXBlIiwgImNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvIiwgInRyYW5zcG9zZSIsICJwYXJzZVRyYW5zcG9zZUF0dHJpYnV0ZXMiLCAiaW5pdF90cmFuc3Bvc2UiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgIlNoYXBlVXRpbCIsICJzaGFwZSIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAiaW5pdF91dGlsIiwgImluaXRfcmVkdWNlIiwgImluaXRfdHJhbnNwb3NlIiwgInNoYXBlIiwgIm5hbWUiLCAiU2hhcGVVdGlsIiwgImNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvIiwgInZhbGlkYXRlSW5wdXRzIiwgImNyZWF0ZVJlZHVjZVByb2dyYW1JbmZvIiwgInJlZHVjZU1lYW4iLCAicmVkdWNlTWF4IiwgInJlZHVjZU1pbiIsICJyZWR1Y2VQcm9kIiwgInJlZHVjZVN1bSIsICJyZWR1Y2VMb2dTdW0iLCAiaW5pdF9yZWR1Y2UiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgIm5hbWUiLCAiU2hhcGVVdGlsIiwgInJlZHVjZU9wcyIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAic2hhcGUiLCAidmFsaWRhdGVJbnB1dHMiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAiaW5pdF9yZWR1Y2UiLCAiY3JlYXRlUmVkdWNlUHJvZ3JhbUluZm8iLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgImluaXRfdXRpbCIsICJpbml0X3R5cGVzIiwgIlNoYXBlVXRpbCIsICJ2YWxpZGF0ZUlucHV0cyIsICJpbml0X3V0aWwiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAic2hhcGUiLCAiU2hhcGVVdGlsIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJlbnYiLCAidmFsaWRhdGVJbnB1dHMiLCAiaW5pdF91dGlsIiwgIlNoYXBlVXRpbCIsICJjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvIiwgImFicyIsICJhY29zIiwgImFzaW4iLCAiYXRhbiIsICJwYXJzZUNhc3RBdHRyaWJ1dGVzIiwgImNhc3QiLCAiZ2VuZXJhdGVDbGlwQXR0cmlidXRlc0Zyb21JbnB1dHMiLCAiY2xpcCIsICJjZWlsIiwgImNvcyIsICJlbHUiLCAiZXhwIiwgImZsb29yIiwgImxlYWt5UmVsdSIsICJub3QiLCAibmVnIiwgInJlbHUiLCAic2lnbW9pZCIsICJzaW4iLCAic3FydCIsICJ0YW4iLCAidGFuaCIsICJsb2ciLCAiaW5pdF91bmFyeV9vcCIsICJpbml0X3V0aWwiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAibmFtZSIsICJTaGFwZVV0aWwiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgInZhbGlkYXRlSW5wdXRzIiwgImluaXRfdXRpbCIsICJpbml0X3VuYXJ5X29wIiwgIlNoYXBlVXRpbCIsICJhZGQiLCAiZGl2IiwgImVxdWFsIiwgIm11bCIsICJwb3ciLCAic3ViIiwgImdyZWF0ZXIiLCAibGVzcyIsICJpbml0X2JpbmFyeV9vcCIsICJpbml0X3V0aWwiLCAiYSIsICJiIiwgIlNoYXBlVXRpbCIsICJuYW1lIiwgIkJyb2FkY2FzdFV0aWwiLCAidmFsaWRhdGVJbnB1dHMiLCAiY29uY2F0IiwgInBhcnNlQ29uY2F0QXR0cmlidXRlcyIsICJpbml0X2NvbmNhdCIsICJpbml0X3V0aWwiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAiaSIsICJTaGFwZVV0aWwiLCAic3VtIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJnZXRBY3RpdmF0aW9uU25pcHBldCIsICJwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMiLCAiaW5pdF9mdXNlX3V0aWxzIiwgImluaXRfdXRpbCIsICJNSU5fQ0xJUCIsICJNQVhfQ0xJUCIsICJpbml0X3V0aWwiLCAiaW5pdF9mdXNlX3V0aWxzIiwgImlucHV0VmFyaWFibGUiLCAiU2hhcGVVdGlsIiwgImdldEFjdGl2YXRpb25TbmlwcGV0IiwgImNyZWF0ZU1hdG11bFByb2dyYW1JbmZvIiwgImluaXRfdXRpbCIsICJpbml0X2Z1c2VfdXRpbHMiLCAidHJhbnNwb3NlIiwgIm91dHB1dFZhcmlhYmxlIiwgIlNoYXBlVXRpbCIsICJnZXRBY3RpdmF0aW9uU25pcHBldCIsICJpbml0X2Z1c2VfdXRpbHMiLCAiaW5uZXJFbGVtZW50U2l6ZSIsICJnZXRBY3RpdmF0aW9uU25pcHBldCIsICJpbml0X3V0aWwiLCAiaW5pdF9mdXNlX3V0aWxzIiwgInBhZCIsICJTaGFwZVV0aWwiLCAiZ2V0QWN0aXZhdGlvblNuaXBwZXQiLCAiaW5pdF9jb252X2dyb3VwZWQiLCAiaW5pdF91dGlsIiwgImluaXRfZnVzZV91dGlscyIsICJTaGFwZVV0aWwiLCAiZ2V0QWN0aXZhdGlvblNuaXBwZXQiLCAiY2FsY3VsYXRlT3V0cHV0U2hhcGUiLCAidmFsaWRhdGVJbnB1dHMiLCAiZ2V0QWRqdXN0ZWRDb252QXR0cmlidXRlcyIsICJwYXJzZUNvbnZBdHRyaWJ1dGVzIiwgImNvbnYyZCIsICJjb252IiwgImluaXRfY29udiIsICJpbml0X3V0aWwiLCAiaW5pdF9jb252X2dyb3VwZWQiLCAiaW5pdF9mdXNlX3V0aWxzIiwgImluaXRfdHJhbnNwb3NlIiwgIlBvb2xDb252VXRpbCIsICJwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMiLCAiY29udklucHV0cyIsICJ0cmFuc3Bvc2VkV2VpZ2h0IiwgImNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvIiwgImNyZWF0ZU1hdG11bFByb2dyYW1JbmZvIiwgImluaXRfdXRpbCIsICJTaGFwZVV0aWwiLCAiY29tcHV0ZVRvdGFsUGFkIiwgImRpc3RyaWJ1dGVQYWRkaW5nIiwgImNhbGN1bGF0ZU91dHB1dFNoYXBlQW5kUGFkcyIsICJnZXRBZGp1c3RlZENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzIiwgInBhcnNlQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMiLCAidmFsaWRhdGVJbnB1dHMiLCAiY29udlRyYW5zcG9zZTJkIiwgImNvbnZUcmFuc3Bvc2UiLCAiaW5pdF9jb252X3RyYW5zcG9zZSIsICJpbml0X2Z1c2VfdXRpbHMiLCAiaW5pdF90cmFuc3Bvc2UiLCAicGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIiwgImNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvIiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJTaGFwZVV0aWwiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgInZhbGlkYXRlSW5wdXRzIiwgInBlcm1GdW5jdGlvbkJvZHkiLCAiZGVwdGhUb1NwYWNlIiwgInBhcnNlRGVwdGhUb1NwYWNlQXR0cmlidXRlcyIsICJpbml0X2RlcHRoX3RvX3NwYWNlIiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJzaGFwZSIsICJTaGFwZVV0aWwiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJzeW1ib2wiLCAibmFtZSIsICJTaGFwZVV0aWwiLCAicmVkdWNlT3BzIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJ2YWxpZGF0ZUlucHV0cyIsICJjYWxjdWxhdGVPdXRwdXRTaGFwZSIsICJpbml0X3V0aWwiLCAic2hhcGUiLCAiU2hhcGVVdGlsIiwgImZhc3RHZWx1IiwgImluaXRfdXRpbCIsICJpbml0X3VuYXJ5X29wIiwgIlNoYXBlVXRpbCIsICJ2YWxpZGF0ZUlucHV0cyIsICJjcmVhdGVHYXRoZXJQcm9ncmFtSW5mbyIsICJwYXJzZUdhdGhlckF0dHJpYnV0ZXMiLCAiZ2F0aGVyIiwgImluaXRfZ2F0aGVyIiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJTaGFwZVV0aWwiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgImluaXRfdXRpbCIsICJTaGFwZVV0aWwiLCAidmFsaWRhdGVJbnB1dHMiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgIlNoYXBlVXRpbCIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAidmFsaWRhdGVJbnB1dHMiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgIlNoYXBlVXRpbCIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAidmFsaWRhdGVJbnB1dHMiLCAiY3JlYXRlR2VtbVByb2dyYW1JbmZvIiwgInBhcnNlR2VtbUF0dHJpYnV0ZXMiLCAiZ2VtbSIsICJpbml0X2dlbW0iLCAiaW5pdF91dGlsIiwgIkdlbW1VdGlsIiwgIlNoYXBlVXRpbCIsICJ2YWxpZGF0ZUlucHV0cyIsICJpbml0X3V0aWwiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAiU2hhcGVVdGlsIiwgImlucHV0cyIsICJvdXRwdXRTaXplIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJ2YWxpZGF0ZUlucHV0cyIsICJ3ZWlnaHRUcmFuc3Bvc2VBdHRyaWJ1dGUiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgImluaXRfdHlwZXMiLCAiaW5pdF90cmFuc3Bvc2UiLCAiU2hhcGVVdGlsIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyIsICJ2YWxpZGF0ZUlucHV0cyIsICJjcmVhdGVTcGxpdFByb2dyYW1JbmZvIiwgInNwbGl0IiwgInBhcnNlU3BsaXRBdHRyaWJ1dGVzIiwgImluaXRfc3BsaXQiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJTaGFwZVV0aWwiLCAidmFsaWRhdGVJbnB1dHMiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgIlNoYXBlVXRpbCIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAidmFsaWRhdGVJbnB1dHMiLCAid2VpZ2h0VHJhbnNwb3NlQXR0cmlidXRlIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgImluaXRfc3BsaXQiLCAiaW5pdF90cmFuc3Bvc2UiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgImNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvIiwgImNyZWF0ZVNwbGl0UHJvZ3JhbUluZm8iLCAiaW5pdF91dGlsIiwgImluaXRfdHJhbnNwb3NlIiwgIlNoYXBlVXRpbCIsICJjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyIsICJ2YWxpZGF0ZUlucHV0cyIsICJpbml0X3V0aWwiLCAiU2hhcGVVdGlsIiwgInZhbGlkYXRlSW5wdXRzIiwgIm1hdE11bCIsICJpbml0X21hdG11bCIsICJpbml0X3V0aWwiLCAiQnJvYWRjYXN0VXRpbCIsICJTaGFwZVV0aWwiLCAiY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm8iLCAidmFsaWRhdGVJbnB1dHMiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgIlNoYXBlVXRpbCIsICJkYXRhVHlwZSIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAidmFsaWRhdGVJbnB1dHMiLCAiZ2V0UGFkQ29uc3RhbnQiLCAiZ2V0UGFkUmVmbGVjdCIsICJnZXRQYWRFZGdlIiwgImNyZWF0ZVBhZFByb2dyYW1JbmZvIiwgImluaXRfcGFkIiwgImluaXRfdXRpbCIsICJTaGFwZVV0aWwiLCAidmFsaWRhdGVJbnB1dHMiLCAiZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlIiwgImdlbmVyYXRlUG9vbGluZ0NvZGUiLCAiY3JlYXRlQXZlcmFnZVBvb2xQcm9ncmFtSW5mbyIsICJwYXJzZUF2ZXJhZ2VQb29sQXR0cmlidXRlcyIsICJhdmVyYWdlUG9vbCIsICJwYXJzZUdsb2JhbEF2ZXJhZ2VQb29sQXR0cmlidXRlcyIsICJnbG9iYWxBdmVyYWdlUG9vbCIsICJjcmVhdGVNYXhQb29sUHJvZ3JhbUluZm8iLCAibWF4UG9vbCIsICJwYXJzZU1heFBvb2xBdHRyaWJ1dGVzIiwgImdsb2JhbE1heFBvb2wiLCAiaW5pdF9wb29sIiwgImluaXRfdXRpbCIsICJlbnYiLCAiUG9vbENvbnZVdGlsIiwgIlNoYXBlVXRpbCIsICJzdW0iLCAibmFtZSIsICJ2YWxpZGF0ZUlucHV0cyIsICJpbml0X3V0aWwiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAiU2hhcGVVdGlsIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJlbnYiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgIlNoYXBlVXRpbCIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAidmFsaWRhdGVJbnB1dHMiLCAicmVzaXplIiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJTaGFwZVV0aWwiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgInZhbGlkYXRlSW5wdXRzIiwgImluaXRfdXRpbCIsICJTaGFwZVV0aWwiLCAidmFsaWRhdGVJbnB1dHMiLCAiY3JlYXRlU2xpY2VQcm9ncmFtSW5mbyIsICJzbGljZSIsICJwYXJzZVNsaWNlQXR0cmlidXRlcyIsICJpbml0X3NsaWNlIiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAiU2hhcGVVdGlsIiwgInZhbGlkYXRlSW5wdXRzIiwgInNvZnRtYXgiLCAicGFyc2VTb2Z0bWF4QXR0cmlidXRlcyIsICJpbml0X3NvZnRtYXgiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgImluaXRfdHJhbnNwb3NlIiwgIlNoYXBlVXRpbCIsICJjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyIsICJuYW1lIiwgImNvbXBvbmVudHMiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgInZhbGlkYXRlSW5wdXRzIiwgImdldE91dHB1dFNoYXBlIiwgImNyZWF0ZVRpbGVQcm9ncmFtSW5mbyIsICJ0aWxlIiwgImluaXRfdGlsZSIsICJpbml0X3V0aWwiLCAic2hhcGUiLCAiU2hhcGVVdGlsIiwgImluaXRfdXRpbCIsICJhIiwgImIiLCAiYyIsICJTaGFwZVV0aWwiLCAiQnJvYWRjYXN0VXRpbCIsICJpbml0X29wX3Jlc29sdmVfcnVsZXMiLCAiaW5pdF9iaW5hcnlfb3AiLCAiaW5pdF9jb25jYXQiLCAiaW5pdF9jb252IiwgImluaXRfY29udl90cmFuc3Bvc2UiLCAiaW5pdF9kZXB0aF90b19zcGFjZSIsICJpbml0X2dhdGhlciIsICJpbml0X2dlbW0iLCAiaW5pdF9tYXRtdWwiLCAiaW5pdF9wYWQiLCAiaW5pdF9wb29sIiwgImluaXRfcmVkdWNlIiwgImluaXRfc2xpY2UiLCAiaW5pdF9zb2Z0bWF4IiwgImluaXRfc3BsaXQiLCAiaW5pdF90aWxlIiwgImluaXRfdHJhbnNwb3NlIiwgImluaXRfdW5hcnlfb3AiLCAiYWJzIiwgImFjb3MiLCAiYWRkIiwgImFzaW4iLCAiYXRhbiIsICJhdmVyYWdlUG9vbCIsICJwYXJzZUF2ZXJhZ2VQb29sQXR0cmlidXRlcyIsICJjYXN0IiwgInBhcnNlQ2FzdEF0dHJpYnV0ZXMiLCAiY2VpbCIsICJjbGlwIiwgImNvbmNhdCIsICJwYXJzZUNvbmNhdEF0dHJpYnV0ZXMiLCAiY29udiIsICJwYXJzZUNvbnZBdHRyaWJ1dGVzIiwgImNvbnZUcmFuc3Bvc2UiLCAicGFyc2VDb252VHJhbnNwb3NlQXR0cmlidXRlcyIsICJjb3MiLCAiZGVwdGhUb1NwYWNlIiwgInBhcnNlRGVwdGhUb1NwYWNlQXR0cmlidXRlcyIsICJkaXYiLCAiZWx1IiwgImVxdWFsIiwgImV4cCIsICJmYXN0R2VsdSIsICJmbG9vciIsICJnYXRoZXIiLCAicGFyc2VHYXRoZXJBdHRyaWJ1dGVzIiwgImdlbW0iLCAicGFyc2VHZW1tQXR0cmlidXRlcyIsICJnbG9iYWxBdmVyYWdlUG9vbCIsICJwYXJzZUdsb2JhbEF2ZXJhZ2VQb29sQXR0cmlidXRlcyIsICJnbG9iYWxNYXhQb29sIiwgImdyZWF0ZXIiLCAibGVha3lSZWx1IiwgImxlc3MiLCAibG9nIiwgIm1hdE11bCIsICJtYXhQb29sIiwgInBhcnNlTWF4UG9vbEF0dHJpYnV0ZXMiLCAibXVsIiwgIm5lZyIsICJub3QiLCAicG93IiwgInJlZHVjZU1pbiIsICJyZWR1Y2VNZWFuIiwgInJlZHVjZU1heCIsICJyZWR1Y2VTdW0iLCAicmVkdWNlUHJvZCIsICJyZWR1Y2VMb2dTdW0iLCAicmVsdSIsICJyZXNpemUiLCAic2lnbW9pZCIsICJzaW4iLCAic2xpY2UiLCAicGFyc2VTbGljZUF0dHJpYnV0ZXMiLCAic3BsaXQiLCAicGFyc2VTcGxpdEF0dHJpYnV0ZXMiLCAic3FydCIsICJzb2Z0bWF4IiwgInBhcnNlU29mdG1heEF0dHJpYnV0ZXMiLCAic3ViIiwgInRhbiIsICJ0YW5oIiwgInRpbGUiLCAidHJhbnNwb3NlIiwgInBhcnNlVHJhbnNwb3NlQXR0cmlidXRlcyIsICJQcm9ncmFtTWFuYWdlciIsICJpbml0X3Byb2dyYW1fbWFuYWdlciIsICJiYWNrZW5kIiwgImdldFByb2dyYW1JbmZvVW5pcXVlS2V5IiwgImluaXRfb3BfcmVzb2x2ZV9ydWxlcyIsICJpbml0X3Byb2dyYW1fbWFuYWdlciIsICJlbnYiLCAiUHJvZ3JhbU1hbmFnZXIiLCAiaSIsICJjcmVhdGVWaWV3IiwgImluaXRfdXRpbCIsICJtb2R1bGUiLCAiU2hhcGVVdGlsIiwgImJhY2tlbmQiLCAibmFtZSIsICJlbnYiLCAic2hhcGUiLCAiZW52IiwgImJhY2tlbmQiLCAic2hhcGUiLCAid2FzbSIsICJuYW1lIiwgImxvY2F0aW9uIiwgImluZGV4IiwgInRlbnNvciIsICJlcnJvckNvZGUiLCAiaSIsICJpbml0aWFsaXppbmciLCAiaW5pdGlhbGl6ZWQiLCAiYWJvcnRlZCIsICJjb3B5RnJvbUV4dGVybmFsQnVmZmVyIiwgImNyZWF0ZVNlc3Npb24iLCAicmVsZWFzZVNlc3Npb24iLCAicnVuIiwgImVuZFByb2ZpbGluZyIsICJlbnYiLCAiaW5pdF9zZXNzaW9uX2hhbmRsZXJfaW5mZXJlbmNlIiwgIlRlbnNvciIsICJjb3B5RnJvbUV4dGVybmFsQnVmZmVyIiwgImNyZWF0ZVNlc3Npb24iLCAicmVsZWFzZVNlc3Npb24iLCAibmFtZSIsICJydW4iLCAiZW5kUHJvZmlsaW5nIiwgImluaXRfc2Vzc2lvbl9oYW5kbGVyX2luZmVyZW5jZSIsICJlbnYiLCAiSW5mZXJlbmNlU2Vzc2lvbiIsICJUZW5zb3IiLCAiZW52IiwgInZlcnNpb24iLCAib25ueGpzQmFja2VuZCIsICJ3YXNtQmFja2VuZCIsICJlbnYiLCAidmVyc2lvbiJdCn0K