UNPKG

@cute-dw/core

Version:

This TypeScript library is the main part of a more powerfull package designed for the fast WEB software development. The cornerstone of the library is the **DataStore** class, which might be useful when you need a full control of the data, but do not need

323 lines 50.3 kB
import { CodeBlock } from "../util/evaluator/CodeBlock"; import { Strings } from "../util/Strings"; export class DSCodeBlock extends CodeBlock { constructor(input, ds, bindContext = false) { super(input, bindContext); this._ds = ds; this.registerDSFunctions(); } /** @private */ _getRangeName(func, astArgs, context, environment) { if (astArgs.length > 1) { let v = this.evaluate(astArgs[1], context, environment); if (typeof (v) === "object" && typeof (v.range) === "string") { let r = v.range; r = r.trim().toLowerCase(); return r; } } return "all"; } _getRangeRows(rangeName, row, defaultRange) { if (rangeName.startsWith("group_")) { const [token] = Strings.getLastToken(rangeName, "_"); const gn = parseInt(token); if (gn >= 0 && gn < this._ds.groupCount()) { const oGrp = this._ds.getGroups()[gn]; return oGrp.getRowRange(row); } } return defaultRange; } // CumulativeSum, CumulativePercent // Example: CumulativeSum( column [, {range: "group_N"|"all"}] ) /** @private */ _callCumFunction(func, astArgs, context, environment) { const rowCount = this._ds.rowCount(); if (rowCount == 0 || astArgs.length == 0) return 0; let result = 0; let [firstRow, lastRow] = [0, rowCount - 1]; const row = environment ?? this._ds.indexOf(context); let rngName = this._getRangeName(func, astArgs, context, environment); [firstRow, lastRow] = this._getRangeRows(rngName, row, [firstRow, lastRow]); if (firstRow >= 0 && lastRow >= 0) { let val; let totals = 0; let runningTotal = 0; let index = firstRow - 1; while (++index <= row) { val = this.evaluate(astArgs[0], this._ds.data[index], environment); if (Number.isFinite(val)) { runningTotal = func(runningTotal, val); } } if (Number.isFinite(runningTotal)) { if (func.name == "cumPcnt") { totals = runningTotal; index--; while (++index <= lastRow) { val = this.evaluate(astArgs[0], this._ds.data[index], environment); if (Number.isFinite(val)) { totals = func(totals, val); } } result = runningTotal / totals * 100; } else { result = runningTotal; } } } return isNaN(result) ? 0 : result; } // Sum, Avg, Min, Max, Count // Example: Sum( column [, {range: "group_N"|"all"}] ) /** @private */ _callAggFunction(func, astArgs, context, environment) { const rowCount = this._ds.rowCount(); if (rowCount == 0 || astArgs.length == 0) return 0; let result = 0; let [firstRow, lastRow] = [0, rowCount - 1]; const row = environment ?? this._ds.indexOf(context); let rngName = this._getRangeName(func, astArgs, context, environment); [firstRow, lastRow] = this._getRangeRows(rngName, row, [firstRow, lastRow]); if (firstRow >= 0 && lastRow >= 0) { let val; let index = firstRow - 1; while (++index <= lastRow) { val = this.evaluate(astArgs[0], this._ds.data[index], environment); if (Number.isFinite(val)) { result = func(result, val); } } if (func.name == "aggAvg" /* && Number.isFinite(result)*/) { result = result / (lastRow - firstRow + 1); } } return isNaN(result) ? 0 : result; } // First, Last // Example: First( column [, {range: "group_N"|"all"}] ) /** @private */ _callValFunction(func, astArgs, context, environment) { const rowCount = this._ds.rowCount(); if (rowCount == 0 || astArgs.length == 0) return 0; let result = undefined; let [firstRow, lastRow] = [0, rowCount - 1]; const row = environment ?? this._ds.indexOf(context); let rngName = this._getRangeName(func, astArgs, context, environment); [firstRow, lastRow] = this._getRangeRows(rngName, row, [firstRow, lastRow]); if (firstRow >= 0 && lastRow >= 0) { switch (func.name) { case "valFirst": result = this.evaluate(astArgs[0], this._ds.data[firstRow], environment); result = func(result); break; case "valLast": result = this.evaluate(astArgs[0], this._ds.data[lastRow], environment); result = func(result); break; case "valPercent": let val; let totals = 0; let index = firstRow - 1; while (++index <= lastRow) { val = this.evaluate(astArgs[0], this._ds.data[index], environment); if (Number.isFinite(val)) { totals = totals + (+val); } } val = this.evaluate(astArgs[0], context, environment); if (Number.isFinite(val) && Number.isFinite(totals)) { result = val / totals * 100; } else { result = null; } break; } } return result; } // StDev, StDevP // Example: StDev( column [, {range: "group_N"|"all"}] ) /** @private */ _callStDevFunction(func, astArgs, context, environment) { const rowCount = this._ds.rowCount(); if (rowCount == 0 || astArgs.length == 0) return 0; let result = undefined; let [firstRow, lastRow] = [0, rowCount - 1]; const row = environment ?? this._ds.indexOf(context); let rngName = this._getRangeName(func, astArgs, context, environment); [firstRow, lastRow] = this._getRangeRows(rngName, row, [firstRow, lastRow]); if (firstRow >= 0 && lastRow >= 0) { let i = -1; let val; let vals = []; let totals = 0; let index = firstRow - 1; while (++index <= lastRow) { val = this.evaluate(astArgs[0], this._ds.data[index], environment); if (Number.isFinite(val)) { vals[++i] = val; totals = totals + (+val); } } const N = vals.length; if (N > 0) { const mean = totals / N; let sqs = 0; i = -1; while (++i < N) { sqs += Math.pow(vals[i] - mean, 2); } if (func.name == "stdevp") { result = Math.sqrt(sqs / N); } else { // StDev result = Math.sqrt(sqs / (N - 1)); } } else { result = null; } } return result; } // VarE, VarP // Example: VarE( column [, {range: "group_N"|"all"}] ) /** @private */ _callVarFunction(func, astArgs, context, environment) { const rowCount = this._ds.rowCount(); if (rowCount == 0 || astArgs.length == 0) return 0; let result = undefined; let [firstRow, lastRow] = [0, rowCount - 1]; const row = environment ?? this._ds.indexOf(context); let rngName = this._getRangeName(func, astArgs, context, environment); [firstRow, lastRow] = this._getRangeRows(rngName, row, [firstRow, lastRow]); if (firstRow >= 0 && lastRow >= 0) { let i = -1; let val; let vals = []; let totals = 0; let index = firstRow - 1; while (++index <= lastRow) { val = this.evaluate(astArgs[0], this._ds.data[index], environment); if (Number.isFinite(val)) { vals[++i] = val; totals = totals + (+val); } } const N = vals.length; if (N > 0) { const mean = totals / N; let sqs = 0; i = -1; while (++i < N) { sqs += Math.pow(vals[i] - mean, 2); } if (func.name == "varp") { result = sqs / N; } else { // Var(E) result = sqs / (N - 1); } } else { result = null; } } return result; } /** * @override */ callFunc(func, astArgs, context, environment) { if (func.name.startsWith("agg")) { return this._callAggFunction(func, astArgs, context, environment); } else if (func.name.startsWith("cum")) { return this._callCumFunction(func, astArgs, context, environment); } else if (func.name.startsWith("val")) { return this._callValFunction(func, astArgs, context, environment); } else if (func.name.startsWith("stdev")) { return this._callStDevFunction(func, astArgs, context, environment); } else if (func.name.startsWith("var")) { return this._callVarFunction(func, astArgs, context, environment); } else { const row = environment; switch (func.name) { case "getrow": return func(context, row); case "isrownew": return func(context); case "isrowmodified": return func(context); case "isselected": return func(context); } } return super.callFunc(func, astArgs, context, environment); } registerDSFunctions() { // Not in validation rules or filter expressions !!! // You cannot use this or other aggregate functions in validation rules or filter expressions. // ++ const aggSum = (p, v) => { return p + (+v); }; const aggAvg = (p, v) => { return p + (+v); }; const aggMin = (p, v) => { return p <= v ? p : v; }; const aggMax = (p, v) => { return p >= v ? p : v; }; const aggCount = (p, v) => { return p + 1; }; const cumSum = (p, v) => { return p + (+v); }; const cumPcnt = (p, v) => { return p + (+v); }; const valFirst = (v) => { return v; }; const valLast = (v) => { return v; }; const valPercent = (v) => { return v; }; const stDev = (v) => { return v; }; const stDevP = (v) => { return v; }; const varE = (v) => { return v; }; const varP = (v) => { return v; }; this.registerFunction("sum", aggSum); this.registerFunction("avg", aggAvg); this.registerFunction("min", aggMin); this.registerFunction("max", aggMax); this.registerFunction("count", aggCount); this.registerFunction("cumulativeSum", cumSum); this.registerFunction("cumulativePercent", cumPcnt); this.registerFunction("first", valFirst); this.registerFunction("last", valLast); this.registerFunction("percent", valPercent); this.registerFunction("stdev", stDev); this.registerFunction("stdeve", stDev); this.registerFunction("stdevp", stDevP); this.registerFunction("vare", varE); this.registerFunction("varp", varP); // -- // //const getrow = function (row:number) {return row} const describe = (s) => { return this._ds.describe(s); }; this.registerNamedFunction(describe); const getrow = (context, row) => { return (typeof row === "number") ? row : this._ds.indexOf(context); }; this.registerNamedFunction(getrow); const currentrow = () => { return this._ds.getRow(); }; this.registerNamedFunction(currentrow); const isrownew = (context) => { return this._ds.isRowNew(context); }; this.registerNamedFunction(isrownew); const isrowmodified = (context) => { return this._ds.isRowModified(context); }; this.registerNamedFunction(isrowmodified); const isselected = (context) => { return this._ds.isSelected(context); }; this.registerNamedFunction(isselected); const rowcount = () => { return this._ds.rowCount(); }; this.registerNamedFunction(rowcount); const lookupdisplay = (col, val) => { return this._ds.getDisplayValue(col, val); }; this.registerNamedFunction(lookupdisplay); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRFNDb2RlQmxvY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jdXRlLWNvcmUvc3JjL2xpYi9kYXRhc3RvcmUvRFNDb2RlQmxvY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUcxQyxNQUFNLE9BQU8sV0FBWSxTQUFRLFNBQVM7SUFJeEMsWUFBWSxLQUFhLEVBQUUsRUFBbUIsRUFBRSxjQUF1QixLQUFLO1FBQzFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDMUIsSUFBSSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUM7UUFDZCxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsZUFBZTtJQUNQLGFBQWEsQ0FBQyxJQUFjLEVBQUUsT0FBYyxFQUFFLE9BQVksRUFBRSxXQUFpQjtRQUNuRixJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ3RCLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQztZQUN4RCxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxRQUFRLEVBQUU7Z0JBQzVELElBQUksQ0FBQyxHQUFXLENBQUMsQ0FBQyxLQUFLLENBQUM7Z0JBQ3hCLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQzNCLE9BQU8sQ0FBQyxDQUFDO2FBQ1Y7U0FDRjtRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVPLGFBQWEsQ0FBQyxTQUFp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UUFDOUYsSUFBSSxDQUFDLHFCQUFxQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sVUFBVSxHQUFhLENBQUMsT0FBWSxFQUFFLEVBQUUsR0FBRyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ3ZGLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN2QyxNQUFNLFFBQVEsR0FBYSxHQUFHLEVBQUUsR0FBRyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sYUFBYSxHQUFhLENBQUMsR0FBVyxFQUFFLEdBQVEsRUFBRSxFQUFFLEdBQUcsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDekcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzVDLENBQUM7Q0FFRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvZGVCbG9jayB9IGZyb20gXCIuLi91dGlsL2V2YWx1YXRvci9Db2RlQmxvY2tcIjtcclxuaW1wb3J0IHsgU3RyaW5ncyB9IGZyb20gXCIuLi91dGlsL1N0cmluZ3NcIjtcclxuaW1wb3J0IHsgSURhdGFTdG9yZSB9IGZyb20gXCIuL0lEYXRhU3RvcmVcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBEU0NvZGVCbG9jayBleHRlbmRzIENvZGVCbG9jayB7XHJcblxyXG4gIHByaXZhdGUgX2RzOiBJRGF0YVN0b3JlPGFueT47XHJcblxyXG4gIGNvbnN0cnVjdG9yKGlucHV0OiBzdHJpbmcsIGRzOiBJRGF0YVN0b3JlPGFueT4sIGJpbmRDb250ZXh0OiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgIHN1cGVyKGlucHV0LCBiaW5kQ29udGV4dCk7XHJcbiAgICB0aGlzLl9kcyA9IGRzO1xyXG4gICAgdGhpcy5yZWdpc3RlckRTRnVuY3Rpb25zKCk7XHJcbiAgfVxyXG5cclxuICAvKiogQHByaXZhdGUgKi9cclxuICBwcml2YXRlIF9nZXRSYW5nZU5hbWUoZnVuYzogRnVuY3Rpb24sIGFzdEFyZ3M6IGFueVtdLCBjb250ZXh0OiBhbnksIGVudmlyb25tZW50PzogYW55KTogc3RyaW5nIHtcclxuICAgIGlmIChhc3RBcmdzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgbGV0IHYgPSB0aGlzLmV2YWx1YXRlKGFzdEFyZ3NbMV0sIGNvbnRleHQsIGVudmlyb25tZW50KTtcclxuICAgICAgaWYgKHR5cGVvZiAodikgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mICh2LnJhbmdlKSA9PT0gXCJzdHJpbmdcIikge1xyXG4gICAgICAgIGxldCByOiBzdHJpbmcgPSB2LnJhbmdlO1xyXG4gICAgICAgIHIgPSByLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgIHJldHVybiByO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gXCJhbGxcIjtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2dldFJhbmdlUm93cyhyYW5nZU5hbWU6IHN0cmluZywgcm93OiBudW1iZXIsIGRlZmF1bHRSYW5nZTogW251bWJlcixudW1iZXJdKTogW251bWJlciwgbnVtYmVyXSB7XHJcbiAgICBpZiAocmFuZ2VOYW1lLnN0YXJ0c1dpdGgoXCJncm91cF9cIikpIHtcclxuICAgICAgY29uc3QgW3Rva2VuXSA9IFN0cmluZ3MuZ2V0TGFzdFRva2VuKHJhbmdlTmFtZSwgXCJfXCIpO1xyXG4gICAgICBjb25zdCBnbiA9IHBhcnNlSW50KHRva2VuISk7XHJcbiAgICAgIGlmIChnbiA+PSAwICYmIGduIDwgdGhpcy5fZHMuZ3JvdXBDb3VudCgpKSB7XHJcbiAgICAgICAgY29uc3Qgb0dycCA9IHRoaXMuX2RzLmdldEdyb3VwcygpW2duXTtcclxuICAgICAgICByZXR1cm4gb0dycC5nZXRSb3dSYW5nZShyb3cpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZGVmYXVsdFJhbmdlO1xyXG4gIH1cclxuXHJcbiAgLy8gQ3VtdWxhdGl2ZVN1bSwgQ3VtdWxhdGl2ZVBlcmNlbnRcclxuICAvLyBFeGFtcGxlOiBDdW11bGF0aXZlU3VtKCBjb2x1bW4gWywge3JhbmdlOiBcImdyb3VwX05cInxcImFsbFwifV0gKVxyXG4gIC8qKiBAcHJpdmF0ZSAqL1xyXG4gIHByaXZhdGUgX2NhbGxDdW1GdW5jdGlvbihmdW5jOiBGdW5jdGlvbiwgYXN0QXJnczogYW55W10sIGNvbnRleHQ6IGFueSwgZW52aXJvbm1lbnQ/OiBhbnkpOiBhbnkge1xyXG5cclxuICAgIGNvbnN0IHJvd0NvdW50ID0gdGhpcy5fZHMucm93Q291bnQoKTtcclxuICAgIGlmIChyb3dDb3VudCA9PSAwIHx8IGFzdEFyZ3MubGVuZ3RoID09IDApIHJldHVybiAwO1xyXG5cclxuICAgIGxldCByZXN1bHQ6IG51bWJlciA9IDA7XHJcbiAgICBsZXQgW2ZpcnN0Um93LCBsYXN0Um93XSA9IFswLCByb3dDb3VudCAtIDFdO1xyXG5cclxuICAgIGNvbnN0IHJvdzogbnVtYmVyID0gZW52aXJvbm1lbnQgPz8gdGhpcy5fZHMuaW5kZXhPZihjb250ZXh0KTtcclxuXHJcbiAgICBsZXQgcm5nTmFtZSA9IHRoaXMuX2dldFJhbmdlTmFtZShmdW5jLCBhc3RBcmdzLCBjb250ZXh0LCBlbnZpcm9ubWVudCk7XHJcbiAgICBbZmlyc3RSb3csIGxhc3RSb3ddID0gdGhpcy5fZ2V0UmFuZ2VSb3dzKHJuZ05hbWUsIHJvdywgW2ZpcnN0Um93LCBsYXN0Um93XSk7XHJcblxyXG4gICAgaWYgKGZpcnN0Um93ID49IDAgJiYgbGFzdFJvdyA+PSAwKSB7XHJcbiAgICAgIGxldCB2YWw7XHJcbiAgICAgIGxldCB0b3RhbHM6IG51bWJlciA9IDA7XHJcbiAgICAgIGxldCBydW5uaW5nVG90YWw6IG51bWJlciA9IDA7XHJcblxyXG4gICAgICBsZXQgaW5kZXggPSBmaXJzdFJvdyAtIDE7XHJcbiAgICAgIHdoaWxlICgrK2luZGV4IDw9IHJvdykge1xyXG4gICAgICAgIHZhbCA9IHRoaXMuZXZhbHVhdGUoYXN0QXJnc1swXSwgdGhpcy5fZHMuZGF0YVtpbmRleF0sIGVudmlyb25tZW50KTtcclxuICAgICAgICBpZiAoTnVtYmVyLmlzRmluaXRlKHZhbCkpIHtcclxuICAgICAgICAgIHJ1bm5pbmdUb3RhbCA9IGZ1bmMocnVubmluZ1RvdGFsLCB2YWwpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKE51bWJlci5pc0Zpbml0ZShydW5uaW5nVG90YWwpKSB7XHJcbiAgICAgICAgaWYgKGZ1bmMubmFtZSA9PSBcImN1bVBjbnRcIikge1xyXG4gICAgICAgICAgdG90YWxzID0gcnVubmluZ1RvdGFsO1xyXG4gICAgICAgICAgaW5kZXgtLTtcclxuICAgICAgICAgIHdoaWxlICgrK2luZGV4IDw9IGxhc3RSb3cpIHtcclxuICAgICAgICAgICAgdmFsID0gdGhpcy5ldmFsdWF0ZShhc3RBcmdzWzBdLCB0aGlzLl9kcy5kYXRhW2luZGV4XSwgZW52aXJvbm1lbnQpO1xyXG4gICAgICAgICAgICBpZiAoTnVtYmVyLmlzRmluaXRlKHZhbCkpIHtcclxuICAgICAgICAgICAgICB0b3RhbHMgPSBmdW5jKHRvdGFscywgdmFsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmVzdWx0ID0gcnVubmluZ1RvdGFsIC8gdG90YWxzICogMTAwO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICByZXN1bHQgPSBydW5uaW5nVG90YWw7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGlzTmFOKHJlc3VsdCkgPyAwIDogcmVzdWx0O1xyXG4gIH1cclxuXHJcbiAgLy8gU3VtLCBBdmcsIE1pbiwgTWF4LCBDb3VudFxyXG4gIC8vIEV4YW1wbGU6IFN1bSggY29sdW1uIFssIHtyYW5nZTogXCJncm91cF9OXCJ8XCJhbGxcIn1dIClcclxuICAvKiogQHByaXZhdGUgKi9cclxuICBwcml2YXRlIF9jYWxsQWdnRnVuY3Rpb24oZnVuYzogRnVuY3Rpb24sIGFzdEFyZ3M6IGFueVtdLCBjb250ZXh0OiBhbnksIGVudmlyb25tZW50PzogYW55KTogYW55IHtcclxuXHJcbiAgICBjb25zdCByb3dDb3VudCA9IHRoaXMuX2RzLnJvd0NvdW50KCk7XHJcbiAgICBpZiAocm93Q291bnQgPT0gMCB8fCBhc3RBcmdzLmxlbmd0aCA9PSAwKSByZXR1cm4gMDtcclxuXHJcbiAgICBsZXQgcmVzdWx0OiBudW1iZXIgPSAwO1xyXG4gICAgbGV0IFtmaXJzdFJvdywgbGFzdFJvd10gPSBbMCwgcm93Q291bnQgLSAxXTtcclxuXHJcbiAgICBjb25zdCByb3c6IG51bWJlciA9IGVudmlyb25tZW50ID8/IHRoaXMuX2RzLmluZGV4T2YoY29udGV4dCk7XHJcblxyXG4gICAgbGV0IHJuZ05hbWUgPSB0aGlzLl9nZXRSYW5nZU5hbWUoZnVuYywgYXN0QXJncywgY29udGV4dCwgZW52aXJvbm1lbnQpO1xyXG4gICAgW2ZpcnN0Um93LCBsYXN0Um93XSA9IHRoaXMuX2dldFJhbmdlUm93cyhybmdOYW1lLCByb3csIFtmaXJzdFJvdywgbGFzdFJvd10pO1xyXG5cclxuICAgIGlmIChmaXJzdFJvdyA+PSAwICYmIGxhc3RSb3cgPj0gMCkge1xyXG4gICAgICBsZXQgdmFsO1xyXG4gICAgICBsZXQgaW5kZXg6IG51bWJlciA9IGZpcnN0Um93IC0gMTtcclxuICAgICAgd2hpbGUgKCsraW5kZXggPD0gbGFzdFJvdykge1xyXG4gICAgICAgIHZhbCA9IHRoaXMuZXZhbHVhdGUoYXN0QXJnc1swXSwgdGhpcy5fZHMuZGF0YVtpbmRleF0sIGVudmlyb25tZW50KTtcclxuICAgICAgICBpZiAoTnVtYmVyLmlzRmluaXRlKHZhbCkgKSB7XHJcbiAgICAgICAgICByZXN1bHQgPSBmdW5jKHJlc3VsdCwgdmFsKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChmdW5jLm5hbWUgPT0gXCJhZ2dBdmdcIiAvKiAmJiBOdW1iZXIuaXNGaW5pdGUocmVzdWx0KSovKSB7XHJcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0IC8gKGxhc3RSb3cgLSBmaXJzdFJvdyArIDEpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGlzTmFOKHJlc3VsdCkgPyAwIDogcmVzdWx0O1xyXG4gIH1cclxuXHJcbiAgLy8gRmlyc3QsIExhc3RcclxuICAvLyBFeGFtcGxlOiBGaXJzdCggY29sdW1uIFssIHtyYW5nZTogXCJncm91cF9OXCJ8XCJhbGxcIn1dIClcclxuICAvKiogQHByaXZhdGUgKi9cclxuICBwcml2YXRlIF9jYWxsVmFsRnVuY3Rpb24oZnVuYzogRnVuY3Rpb24sIGFzdEFyZ3M6IGFueVtdLCBjb250ZXh0OiBhbnksIGVudmlyb25tZW50PzogYW55KTogYW55IHtcclxuXHJcbiAgICBjb25zdCByb3dDb3VudCA9IHRoaXMuX2RzLnJvd0NvdW50KCk7XHJcbiAgICBpZiAocm93Q291bnQgPT0gMCB8fCBhc3RBcmdzLmxlbmd0aCA9PSAwKSByZXR1cm4gMDtcclxuXHJcbiAgICBsZXQgcmVzdWx0OiBhbnkgPSB1bmRlZmluZWQ7XHJcbiAgICBsZXQgW2ZpcnN0Um93LCBsYXN0Um93XSA9IFswLCByb3dDb3VudCAtIDFdO1xyXG5cclxuICAgIGNvbnN0IHJvdzogbnVtYmVyID0gZW52aXJvbm1lbnQgPz8gdGhpcy5fZHMuaW5kZXhPZihjb250ZXh0KTtcclxuXHJcbiAgICBsZXQgcm5nTmFtZSA9IHRoaXMuX2dldFJhbmdlTmFtZShmdW5jLCBhc3RBcmdzLCBjb250ZXh0LCBlbnZpcm9ubWVudCk7XHJcbiAgICBbZmlyc3RSb3csIGxhc3RSb3ddID0gdGhpcy5fZ2V0UmFuZ2VSb3dzKHJuZ05hbWUsIHJvdywgW2ZpcnN0Um93LCBsYXN0Um93XSk7XHJcblxyXG4gICAgaWYgKGZpcnN0Um93ID49IDAgJiYgbGFzdFJvdyA+PSAwKSB7XHJcbiAgICAgIHN3aXRjaCAoZnVuYy5uYW1lKSB7XHJcbiAgICAgICAgY2FzZSBcInZhbEZpcnN0XCI6XHJcbiAgICAgICAgICByZXN1bHQgPSB0aGlzLmV2YWx1YXRlKGFzdEFyZ3NbMF0sIHRoaXMuX2RzLmRhdGFbZmlyc3RSb3ddLCBlbnZpcm9ubWVudCk7XHJcbiAgICAgICAgICByZXN1bHQgPSBmdW5jKHJlc3VsdCk7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIFwidmFsTGFzdFwiOlxyXG4gICAgICAgICAgcmVzdWx0ID0gdGhpcy5ldmFsdWF0ZShhc3RBcmdzWzBdLCB0aGlzLl9kcy5kYXRhW2xhc3RSb3ddLCBlbnZpcm9ubWVudCk7XHJcbiAgICAgICAgICByZXN1bHQgPSBmdW5jKHJlc3VsdCk7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIFwidmFsUGVyY2VudFwiOlxyXG4gICAgICAgICAgbGV0IHZhbDtcclxuICAgICAgICAgIGxldCB0b3RhbHM6IG51bWJlciA9IDBcclxuICAgICAgICAgIGxldCBpbmRleDogbnVtYmVyID0gZmlyc3RSb3cgLSAxO1xyXG4gICAgICAgICAgd2hpbGUgKCsraW5kZXggPD0gbGFzdFJvdykge1xyXG4gICAgICAgICAgICB2YWwgPSB0aGlzLmV2YWx1YXRlKGFzdEFyZ3NbMF0sIHRoaXMuX2RzLmRhdGFbaW5kZXhdLCBlbnZpcm9ubWVudCk7XHJcbiAgICAgICAgICAgIGlmIChOdW1iZXIuaXNGaW5pdGUodmFsKSkge1xyXG4gICAgICAgICAgICAgIHRvdGFscyA9IHRvdGFscyArICgrdmFsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIHZhbCA9IHRoaXMuZXZhbHVhdGUoYXN0QXJnc1swXSwgY29udGV4dCwgZW52aXJvbm1lbnQpO1xyXG4gICAgICAgICAgaWYgKE51bWJlci5pc0Zpbml0ZSh2YWwpICYmIE51bWJlci5pc0Zpbml0ZSh0b3RhbHMpKSB7XHJcbiAgICAgICAgICAgIHJlc3VsdCA9IHZhbCAvIHRvdGFscyAqIDEwMDtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG5cclxuICAvLyBTdERldiwgU3REZXZQXHJcbiAgLy8gRXhhbXBsZTogU3REZXYoIGNvbHVtbiBbLCB7cmFuZ2U6IFwiZ3JvdXBfTlwifFwiYWxsXCJ9XSApXHJcbiAgLyoqIEBwcml2YXRlICovXHJcbiAgcHJpdmF0ZSBfY2FsbFN0RGV2RnVuY3Rpb24oZnVuYzogRnVuY3Rpb24sIGFzdEFyZ3M6IGFueVtdLCBjb250ZXh0OiBhbnksIGVudmlyb25tZW50PzogYW55KTogYW55IHtcclxuICAgIGNvbnN0IHJvd0NvdW50ID0gdGhpcy5fZHMucm93Q291bnQoKTtcclxuICAgIGlmIChyb3dDb3VudCA9PSAwIHx8IGFzdEFyZ3MubGVuZ3RoID09IDApIHJldHVybiAwO1xyXG5cclxuICAgIGxldCByZXN1bHQ6IGFueSA9IHVuZGVmaW5lZDtcclxuICAgIGxldCBbZmlyc3RSb3csIGxhc3RSb3ddID0gWzAsIHJvd0NvdW50IC0gMV07XHJcblxyXG4gICAgY29uc3Qgcm93OiBudW1iZXIgPSBlbnZpcm9ubWVudCA/PyB0aGlzLl9kcy5pbmRleE9mKGNvbnRleHQpO1xyXG5cclxuICAgIGxldCBybmdOYW1lID0gdGhpcy5fZ2V0UmFuZ2VOYW1lKGZ1bmMsIGFzdEFyZ3MsIGNvbnRleHQsIGVudmlyb25tZW50KTtcclxuICAgIFtmaXJzdFJvdywgbGFzdFJvd10gPSB0aGlzLl9nZXRSYW5nZVJvd3Mocm5nTmFtZSwgcm93LCBbZmlyc3RSb3csIGxhc3RSb3ddKTtcclxuXHJcbiAgICBpZiAoZmlyc3RSb3cgPj0gMCAmJiBsYXN0Um93ID49IDApIHtcclxuICAgICAgbGV0IGkgPSAtMTtcclxuICAgICAgbGV0IHZhbDtcclxuICAgICAgbGV0IHZhbHMgPSBbXTtcclxuICAgICAgbGV0IHRvdGFsczogbnVtYmVyID0gMFxyXG4gICAgICBsZXQgaW5kZXg6IG51bWJlciA9IGZpcnN0Um93IC0gMTtcclxuICAgICAgd2hpbGUgKCsraW5kZXggPD0gbGFzdFJvdykge1xyXG4gICAgICAgIHZhbCA9IHRoaXMuZXZhbHVhdGUoYXN0QXJnc1swXSwgdGhpcy5fZHMuZGF0YVtpbmRleF0sIGVudmlyb25tZW50KTtcclxuICAgICAgICBpZiAoTnVtYmVyLmlzRmluaXRlKHZhbCkpIHtcclxuICAgICAgICAgIHZhbHNbKytpXSA9IHZhbDtcclxuICAgICAgICAgIHRvdGFscyA9IHRvdGFscyArICgrdmFsKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IE4gPSB2YWxzLmxlbmd0aDtcclxuICAgICAgaWYgKE4gPiAwKSB7XHJcbiAgICAgICAgY29uc3QgbWVhbiA9IHRvdGFscyAvIE47XHJcblxyXG4gICAgICAgIGxldCBzcXMgPSAwO1xyXG4gICAgICAgIGkgPSAtMTtcclxuICAgICAgICB3aGlsZSAoKytpIDwgTikge1xyXG4gICAgICAgICAgc3FzICs9IE1hdGgucG93KHZhbHNbaV0gLSBtZWFuLCAyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChmdW5jLm5hbWUgPT0gXCJzdGRldnBcIikge1xyXG4gICAgICAgICAgcmVzdWx0ID0gTWF0aC5zcXJ0KHNxcyAvIE4pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyBTdERldlxyXG4gICAgICAgICAgcmVzdWx0ID0gTWF0aC5zcXJ0KHNxcyAvIChOIC0gMSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICByZXN1bHQgPSBudWxsO1xyXG4gICAgICB9XHJcblxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG5cclxuICAvLyBWYXJFLCBWYXJQXHJcbiAgLy8gRXhhbXBsZTogVmFyRSggY29sdW1uIFssIHtyYW5nZTogXCJncm91cF9OXCJ8XCJhbGxcIn1dIClcclxuICAvKiogQHByaXZhdGUgKi9cclxuICBwcml2YXRlIF9jYWxsVmFyRnVuY3Rpb24oZnVuYzogRnVuY3Rpb24sIGFzdEFyZ3M6IGFueVtdLCBjb250ZXh0OiBhbnksIGVudmlyb25tZW50PzogYW55KTogYW55IHtcclxuICAgIGNvbnN0IHJvd0NvdW50ID0gdGhpcy5fZHMucm93Q291bnQoKTtcclxuICAgIGlmIChyb3dDb3VudCA9PSAwIHx8IGFzdEFyZ3MubGVuZ3RoID09IDApIHJldHVybiAwO1xyXG5cclxuICAgIGxldCByZXN1bHQ6IGFueSA9IHVuZGVmaW5lZDtcclxuICAgIGxldCBbZmlyc3RSb3csIGxhc3RSb3ddID0gWzAsIHJvd0NvdW50IC0gMV07XHJcblxyXG4gICAgY29uc3Qgcm93OiBudW1iZXIgPSBlbnZpcm9ubWVudCA/PyB0aGlzLl9kcy5pbmRleE9mKGNvbnRleHQpO1xyXG5cclxuICAgIGxldCBybmdOYW1lID0gdGhpcy5fZ2V0UmFuZ2VOYW1lKGZ1bmMsIGFzdEFyZ3MsIGNvbnRleHQsIGVudmlyb25tZW50KTtcclxuICAgIFtmaXJzdFJvdywgbGFzdFJvd10gPSB0aGlzLl9nZXRSYW5nZVJvd3Mocm5nTmFtZSwgcm93LCBbZmlyc3RSb3csIGxhc3RSb3ddKTtcclxuXHJcbiAgICBpZiAoZmlyc3RSb3cgPj0gMCAmJiBsYXN0Um93ID49IDApIHtcclxuICAgICAgbGV0IGkgPSAtMTtcclxuICAgICAgbGV0IHZhbDtcclxuICAgICAgbGV0IHZhbHMgPSBbXTtcclxuICAgICAgbGV0IHRvdGFsczogbnVtYmVyID0gMFxyXG4gICAgICBsZXQgaW5kZXg6IG51bWJlciA9IGZpcnN0Um93IC0gMTtcclxuICAgICAgd2hpbGUgKCsraW5kZXggPD0gbGFzdFJvdykge1xyXG4gICAgICAgIHZhbCA9IHRoaXMuZXZhbHVhdGUoYXN0QXJnc1swXSwgdGhpcy5fZHMuZGF0YVtpbmRleF0sIGVudmlyb25tZW50KTtcclxuICAgICAgICBpZiAoTnVtYmVyLmlzRmluaXRlKHZhbCkpIHtcclxuICAgICAgICAgIHZhbHNbKytpXSA9IHZhbDtcclxuICAgICAgICAgIHRvdGFscyA9IHRvdGFscyArICgrdmFsKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IE4gPSB2YWxzLmxlbmd0aDtcclxuICAgICAgaWYgKE4gPiAwKSB7XHJcbiAgICAgICAgY29uc3QgbWVhbiA9IHRvdGFscyAvIE47XHJcblxyXG4gICAgICAgIGxldCBzcXMgPSAwO1xyXG4gICAgICAgIGkgPSAtMTtcclxuICAgICAgICB3aGlsZSAoKytpIDwgTikge1xyXG4gICAgICAgICAgc3FzICs9IE1hdGgucG93KHZhbHNbaV0gLSBtZWFuLCAyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChmdW5jLm5hbWUgPT0gXCJ2YXJwXCIpIHtcclxuICAgICAgICAgIHJlc3VsdCA9IHNxcyAvIE47XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIFZhcihFKVxyXG4gICAgICAgICAgcmVzdWx0ID0gc3FzIC8gKE4gLSAxKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmVzdWx0ID0gbnVsbDtcclxuICAgICAgfVxyXG5cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAb3ZlcnJpZGVcclxuICAgKi9cclxuICBwcm90ZWN0ZWQgY2FsbEZ1bmMoZnVuYzogRnVuY3Rpb24sIGFzdEFyZ3M6IGFueVtdLCBjb250ZXh0OiBhbnksIGVudmlyb25tZW50PzogYW55KTogYW55IHtcclxuXHJcbiAgICBpZiAoZnVuYy5uYW1lLnN0YXJ0c1dpdGgoXCJhZ2dcIikpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX2NhbGxBZ2dGdW5jdGlvbihmdW5jLCBhc3RBcmdzLCBjb250ZXh0LCBlbnZpcm9ubWVudCk7XHJcbiAgICB9IGVsc2UgaWYgKGZ1bmMubmFtZS5zdGFydHNXaXRoKFwiY3VtXCIpKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jYWxsQ3VtRnVuY3Rpb24oZnVuYywgYXN0QXJncywgY29udGV4dCwgZW52aXJvbm1lbnQpO1xyXG4gICAgfSBlbHNlIGlmIChmdW5jLm5hbWUuc3RhcnRzV2l0aChcInZhbFwiKSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY2FsbFZhbEZ1bmN0aW9uKGZ1bmMsIGFzdEFyZ3MsIGNvbnRleHQsIGVudmlyb25tZW50KTtcclxuICAgIH0gZWxzZSBpZiAoZnVuYy5uYW1lLnN0YXJ0c1dpdGgoXCJzdGRldlwiKSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY2FsbFN0RGV2RnVuY3Rpb24oZnVuYywgYXN0QXJncywgY29udGV4dCwgZW52aXJvbm1lbnQpO1xyXG4gICAgfSBlbHNlIGlmIChmdW5jLm5hbWUuc3RhcnRzV2l0aChcInZhclwiKSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY2FsbFZhckZ1bmN0aW9uKGZ1bmMsIGFzdEFyZ3MsIGNvbnRleHQsIGVudmlyb25tZW50KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IHJvdzogbnVtYmVyIHwgdW5kZWZpbmVkID0gZW52aXJvbm1lbnQ7XHJcbiAgICAgIHN3aXRjaCAoZnVuYy5uYW1lKSB7XHJcbiAgICAgICAgY2FzZSBcImdldHJvd1wiOiByZXR1cm4gZnVuYyhjb250ZXh0LCByb3cpO1xyXG4gICAgICAgIGNhc2UgXCJpc3Jvd25ld1wiOiByZXR1cm4gZnVuYyhjb250ZXh0KTtcclxuICAgICAgICBjYXNlIFwiaXNyb3dtb2RpZmllZFwiOiByZXR1cm4gZnVuYyhjb250ZXh0KTtcclxuICAgICAgICBjYXNlIFwiaXNzZWxlY3RlZFwiOiByZXR1cm4gZnVuYyhjb250ZXh0KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHN1cGVyLmNhbGxGdW5jKGZ1bmMsIGFzdEFyZ3MsIGNvbnRleHQsIGVudmlyb25tZW50KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVnaXN0ZXJEU0Z1bmN0aW9ucygpIHtcclxuXHJcbiAgICAvLyBOb3QgaW4gdmFsaWRhdGlvbiBydWxlcyBvciBmaWx0ZXIgZXhwcmVzc2lvbnMgISEhXHJcbiAgICAvLyBZb3UgY2Fubm90IHVzZSB0aGlzIG9yIG90aGVyIGFnZ3JlZ2F0ZSBmdW5jdGlvbnMgaW4gdmFsaWRhdGlvbiBydWxlcyBvciBmaWx0ZXIgZXhwcmVzc2lvbnMuXHJcbiAgICAvLyArK1xyXG4gICAgY29uc3QgYWdnU3VtOiBGdW5jdGlvbiA9IChwOiBudW1iZXIsIHY6IGFueSkgPT4geyByZXR1cm4gcCArICgrdikgfTtcclxuICAgIGNvbnN0IGFnZ0F2ZzogRnVuY3Rpb24gPSAocDogbnVtYmVyLCB2OiBhbnkpID0+IHsgcmV0dXJuIHAgKyAoK3YpIH07XHJcbiAgICBjb25zdCBhZ2dNaW46IEZ1bmN0aW9uID0gKHA6IGFueSwgdjogYW55KSA9PiB7IHJldHVybiBwIDw9IHYgPyBwIDogdiB9O1xyXG4gICAgY29uc3QgYWdnTWF4OiBGdW5jdGlvbiA9IChwOiBhbnksIHY6IGFueSkgPT4geyByZXR1cm4gcCA+PSB2ID8gcCA6IHYgfTtcclxuICAgIGNvbnN0IGFnZ0NvdW50OiBGdW5jdGlvbiA9IChwOiBudW1iZXIsIHY6IGFueSkgPT4geyByZXR1cm4gcCArIDEgfTtcclxuICAgIGNvbnN0IGN1bVN1bTogRnVuY3Rpb24gPSAocDogbnVtYmVyLCB2OiBhbnkpID0+IHsgcmV0dXJuIHAgKyAoK3YpIH07XHJcbiAgICBjb25zdCBjdW1QY250OiBGdW5jdGlvbiA9IChwOiBudW1iZXIsIHY6IGFueSkgPT4geyByZXR1cm4gcCArICgrdikgfTtcclxuICAgIGNvbnN0IHZhbEZpcnN0OiBGdW5jdGlvbiA9ICh2OiBhbnkpID0+IHtyZXR1cm4gdn07XHJcbiAgICBjb25zdCB2YWxMYXN0OiBGdW5jdGlvbiA9ICh2OiBhbnkpID0+IHtyZXR1cm4gdn07XHJcbiAgICBjb25zdCB2YWxQZXJjZW50OiBGdW5jdGlvbiA9ICh2OiBhbnkpID0+IHtyZXR1cm4gdn07XHJcbiAgICBjb25zdCBzdERldjogRnVuY3Rpb24gPSAodjogYW55KSA9PiB7cmV0dXJuIHZ9O1xyXG4gICAgY29uc3Qgc3REZXZQOiBGdW5jdGlvbiA9ICh2OiBhbnkpID0+IHtyZXR1cm4gdn07XHJcbiAgICBjb25zdCB2YXJFOiBGdW5jdGlvbiA9ICh2OiBhbnkpID0+IHtyZXR1cm4gdn07XHJcbiAgICBjb25zdCB2YXJQOiBGdW5jdGlvbiA9ICh2OiBhbnkpID0+IHtyZXR1cm4gdn07XHJcblxyXG4gICAgdGhpcy5yZWdpc3RlckZ1bmN0aW9uKFwic3VtXCIsIGFnZ1N1bSk7XHJcbiAgICB0aGlzLnJlZ2lzdGVyRnVuY3Rpb24oXCJhdmdcIiwgYWdnQXZnKTtcclxuICAgIHRoaXMucmVnaXN0ZXJGdW5jdGlvbihcIm1pblwiLCBhZ2dNaW4pO1xyXG4gICAgdGhpcy5yZWdpc3RlckZ1bmN0aW9uKFwibWF4XCIsIGFnZ01heCk7XHJcbiAgICB0aGlzLnJlZ2lzdGVyRnVuY3Rpb24oXCJjb3VudFwiLCBhZ2dDb3VudCk7XHJcbiAgICB0aGlzLnJlZ2lzdGVyRnVuY3Rpb24oXCJjdW11bGF0aXZlU3VtXCIsIGN1bVN1bSk7XHJcbiAgICB0aGlzLnJlZ2lzdGVyRnVuY3Rpb24oXCJjdW11bGF0aXZlUGVyY2VudFwiLCBjdW1QY250KTtcclxuICAgIHRoaXMucmVnaXN0ZXJGdW5jdGlvbihcImZpcnN0XCIsIHZhbEZpcnN0KTtcclxuICAgIHRoaXMucmVnaXN0ZXJGdW5jdGlvbihcImxhc3RcIiwgdmFsTGFzdCk7XHJcbiAgICB0aGlzLnJlZ2lzdGVyRnVuY3Rpb24oXCJwZXJjZW50XCIsIHZhbFBlcmNlbnQpO1xyXG4gICAgdGhpcy5yZWdpc3RlckZ1bmN0aW9uKFwic3RkZXZcIiwgc3REZXYpO1xyXG4gICAgdGhpcy5yZWdpc3RlckZ1bmN0aW9uKFwic3RkZXZlXCIsIHN0RGV2KTtcclxuICAgIHRoaXMucmVnaXN0ZXJGdW5jdGlvbihcInN0ZGV2cFwiLCBzdERldlApO1xyXG4gICAgdGhpcy5yZWdpc3RlckZ1bmN0aW9uKFwidmFyZVwiLCB2YXJFKTtcclxuICAgIHRoaXMucmVnaXN0ZXJGdW5jdGlvbihcInZhcnBcIiwgdmFyUCk7XHJcbiAgICAvLyAtLVxyXG5cclxuICAgIC8vXHJcbiAgICAvL2NvbnN0IGdldHJvdyA9IGZ1bmN0aW9uIChyb3c6bnVtYmVyKSB7cmV0dXJuIHJvd31cclxuICAgIGNvbnN0IGRlc2NyaWJlOiBGdW5jdGlvbiA9IChzOiBzdHJpbmcpID0+IHsgcmV0dXJuIHRoaXMuX2RzLmRlc2NyaWJlKHMpOyB9O1xyXG4gICAgdGhpcy5yZWdpc3Rlck5hbWVkRnVuY3Rpb24oZGVzY3JpYmUpO1xyXG4gICAgY29uc3QgZ2V0cm93OiBGdW5jdGlvbiA9IChjb250ZXh0OiBhbnksIHJvdzogbnVtYmVyKSA9PiB7IHJldHVybiAodHlwZW9mIHJvdyA9PT0gXCJudW1iZXJcIikgPyByb3cgOiB0aGlzLl9kcy5pbmRleE9mKGNvbnRleHQpOyB9O1xyXG4gICAgdGhpcy5yZWdpc3Rlck5hbWVkRnVuY3Rpb24oZ2V0cm93KTtcclxuICAgIGNvbnN0IGN1cnJlbnRyb3c6IEZ1bmN0aW9uID0gKCkgPT4geyByZXR1cm4gdGhpcy5fZHMuZ2V0Um93KCk7IH07XHJcbiAgICB0aGlzLnJlZ2lzdGVyTmFtZWRGdW5jdGlvbihjdXJyZW50cm93KTtcclxuICAgIGNvbnN0IGlzcm93bmV3OiBGdW5jdGlvbiA9IChjb250ZXh0OiBhbnkpID0+IHsgcmV0dXJuIHRoaXMuX2RzLmlzUm93TmV3KGNvbnRleHQpOyB9O1xyXG4gICAgdGhpcy5yZWdpc3Rlck5hbWVkRnVuY3Rpb24oaXNyb3duZXcpO1xyXG4gICAgY29uc3QgaXNyb3dtb2RpZmllZDogRnVuY3Rpb24gPSAoY29udGV4dDogYW55KSA9PiB7IHJldHVybiB0aGlzLl9kcy5pc1Jvd01vZGlmaWVkKGNvbnRleHQpOyB9O1xyXG4gICAgdGhpcy5yZWdpc3Rlck5hbWVkRnVuY3Rpb24oaXNyb3dtb2RpZmllZCk7XHJcbiAgICBjb25zdCBpc3NlbGVjdGVkOiBGdW5jdGlvbiA9IChjb250ZXh0OiBhbnkpID0+IHsgcmV0dXJuIHRoaXMuX2RzLmlzU2VsZWN0ZWQoY29udGV4dCk7IH1cclxuICAgIHRoaXMucmVnaXN0ZXJOYW1lZEZ1bmN0aW9uKGlzc2VsZWN0ZWQpO1xyXG4gICAgY29uc3Qgcm93Y291bnQ6IEZ1bmN0aW9uID0gKCkgPT4geyByZXR1cm4gdGhpcy5fZHMucm93Q291bnQoKTsgfTtcclxuI