faastjs
Version:
Serverless batch computing made simple.
291 lines • 32.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SmallestN = exports.MaxHeap = exports.defined = exports.keysOf = exports.f2 = exports.f1 = exports.KB = exports.MB = exports.GB = exports.uuidv4Pattern = exports.roundTo100ms = exports.hasExpired = exports.computeHttpResponseBytes = exports.objectSize = exports.sum = exports.chomp = exports.streamToBuffer = exports.sleep = exports.ExponentiallyDecayingAverageValue = exports.Statistics = void 0;
/**
* Incrementally updated statistics on a set of values.
* @public
*/
class Statistics {
/**
* Incrementally track mean, stdev, min, max, of a sequence of values.
* @param printFixedPrecision - The number of decimal places to print in
* {@link Statistics.toString}.
*/
constructor(
/** The number of decimal places to print in {@link Statistics.toString} */
printFixedPrecision = 1) {
this.printFixedPrecision = printFixedPrecision;
/** Number of values observed. */
this.samples = 0;
/** The maximum value observed. Initialized to `Number.NEGATIVE_INFINITY`. */
this.max = Number.NEGATIVE_INFINITY;
/** The minimum value observed. Initialized to `Number.POSITIVE_INFINITY`. */
this.min = Number.POSITIVE_INFINITY;
/** The variance of the values observed. */
this.variance = 0;
/** The standard deviation of the values observed. */
this.stdev = 0;
/** The mean (average) of the values observed. */
this.mean = NaN;
}
/** @internal */
clone() {
const rv = new Statistics(this.printFixedPrecision);
return Object.assign(rv, this);
}
/**
* Update statistics with a new value in the sequence.
*/
update(value) {
if (value === undefined) {
return;
}
let previousMean = this.mean;
// https://math.stackexchange.com/questions/374881/recursive-formula-for-variance
let previousVariance = this.variance;
if (this.samples === 0) {
previousMean = 0;
previousVariance = 0;
}
this.samples++;
this.mean = previousMean + (value - previousMean) / this.samples;
this.variance =
((previousVariance + (previousMean - value) ** 2 / this.samples) *
(this.samples - 1)) /
this.samples;
this.stdev = Math.sqrt(this.variance);
if (value > this.max) {
this.max = value;
}
if (value < this.min) {
this.min = value;
}
}
/**
* Print the mean of the observations seen, with the precision specified in
* the constructor.
*/
toString() {
return `${this.mean.toFixed(this.printFixedPrecision)}`;
}
}
exports.Statistics = Statistics;
class ExponentiallyDecayingAverageValue {
constructor(smoothingFactor) {
this.smoothingFactor = smoothingFactor;
this.samples = 0;
this.value = 0;
}
update(n) {
// tslint:disable-next-line:prefer-conditional-expression
if (this.samples++ === 0) {
this.value = n;
}
else {
this.value =
this.smoothingFactor * n + (1 - this.smoothingFactor) * this.value;
}
}
toString() {
return this.value;
}
}
exports.ExponentiallyDecayingAverageValue = ExponentiallyDecayingAverageValue;
function sleep(ms, cancel = new Promise(() => { })) {
let id;
cancel.then(_ => clearTimeout(id)).catch(_ => clearTimeout(id));
return Promise.race([new Promise(resolve => (id = setTimeout(resolve, ms))), cancel]);
}
exports.sleep = sleep;
function streamToBuffer(s) {
return new Promise((resolve, reject) => {
const buffers = [];
s.on("error", reject);
s.on("data", (data) => buffers.push(data));
s.on("end", () => resolve(Buffer.concat(buffers)));
});
}
exports.streamToBuffer = streamToBuffer;
function chomp(s) {
if (s.length > 0 && s[s.length - 1] === "\n") {
s = s.slice(0, s.length - 1);
}
return s;
}
exports.chomp = chomp;
const sum = (a) => a.reduce((total, n) => total + n, 0);
exports.sum = sum;
function objectSize(obj) {
if (!obj) {
return 0;
}
return (0, exports.sum)(Object.keys(obj).map(key => key.length + obj[key].length));
}
exports.objectSize = objectSize;
function computeHttpResponseBytes(headers, opts = { httpHeaders: true, min: 0 }) {
const headerKeys = Object.keys(headers);
let contentLength = 0;
for (const key of headerKeys) {
if (key.match(/^content-length$/i)) {
contentLength = Number(headers[key]);
break;
}
}
if (!opts.httpHeaders) {
return Math.max(contentLength, opts.min);
}
const headerLength = objectSize(headers) + headerKeys.length * ": ".length;
const otherLength = 13;
return Math.max(contentLength + headerLength + otherLength, opts.min);
}
exports.computeHttpResponseBytes = computeHttpResponseBytes;
function hasExpired(date, retentionInDays) {
if (retentionInDays <= 0) {
return true;
}
const timestamp = typeof date === "string" ? Date.parse(date) : date || 0;
return timestamp < Date.now() - retentionInDays * 24 * 60 * 60 * 1000;
}
exports.hasExpired = hasExpired;
function roundTo100ms(n) {
return Math.round(n / 100) * 100;
}
exports.roundTo100ms = roundTo100ms;
exports.uuidv4Pattern = "[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}";
exports.GB = 2 ** 30;
exports.MB = 2 ** 20;
exports.KB = 2 ** 10;
function f1(n) {
return n.toFixed(1);
}
exports.f1 = f1;
function f2(n) {
return n.toFixed(2);
}
exports.f2 = f2;
function keysOf(obj) {
return Object.keys(obj);
}
exports.keysOf = keysOf;
function defined(arg) {
return !!arg;
}
exports.defined = defined;
class MaxHeap {
constructor() {
this._heap = [];
}
get size() {
return this._heap.length;
}
clear() {
this._heap = [];
}
peekMax() {
return this._heap[0];
}
insert(value) {
const h = this._heap;
h.push(value);
let i = h.length - 1;
const parentOf = (n) => Math.floor((n - 1) / 2);
let parent = parentOf(i);
while (parent >= 0 && h[i] > h[parent]) {
const tmp = h[parent];
h[parent] = h[i];
h[i] = tmp;
i = parent;
parent = parentOf(i);
}
}
extractMax() {
const h = this._heap;
if (h.length === 0) {
throw new Error("extractMax called on empty heap");
}
let i = 0;
const rv = h[0];
h[0] = h[h.length - 1];
h.pop();
while (i < h.length) {
const [left, right] = [i * 2 + 1, i * 2 + 2];
let maybe;
if (h[i] < h[left] && !(h[right] > h[left])) {
maybe = left;
}
else if (h[i] < h[right]) {
maybe = right;
}
if (maybe === undefined) {
break;
}
const [iValue, mValue] = [h[i], h[maybe]];
h[i] = mValue;
h[maybe] = iValue;
i = maybe;
}
return rv;
}
[Symbol.iterator]() {
return this._heap[Symbol.iterator]();
}
}
exports.MaxHeap = MaxHeap;
class SmallestN {
constructor(_size) {
this._size = _size;
this._heap = new MaxHeap();
this._map = [];
}
update(key, value) {
if (this._heap.size < this._size) {
this._heap.insert(key);
this._map.push([key, value]);
return;
}
if (key >= this._heap.peekMax()) {
return;
}
this._heap.insert(key);
this._map.push([key, value]);
this.shrink();
}
shrink() {
const max = this._heap.extractMax();
let idx = this._map.length;
while (--idx >= 0) {
if (this._map[idx][0] === max) {
break;
}
}
if (idx === -1) {
throw new Error(`SmallestN: could not find entry for key ${max}`);
}
this._map.splice(idx, 1);
}
[Symbol.iterator]() {
return this._map[Symbol.iterator]();
}
entries() {
return this._map[Symbol.iterator];
}
keys() {
return [...this._heap];
}
get size() {
return this._size;
}
clear() {
this._heap.clear();
this._map = [];
}
setSize(newSize) {
while (this._size > newSize) {
this.shrink();
this._size--;
}
this._size = newSize;
}
}
exports.SmallestN = SmallestN;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NoYXJlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7O0dBR0c7QUFDSCxNQUFhLFVBQVU7SUFjbkI7Ozs7T0FJRztJQUNIO0lBQ0ksMkVBQTJFO0lBQ2pFLHNCQUE4QixDQUFDO1FBQS9CLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBWTtRQXBCN0MsaUNBQWlDO1FBQ2pDLFlBQU8sR0FBRyxDQUFDLENBQUM7UUFDWiw2RUFBNkU7UUFDN0UsUUFBRyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztRQUMvQiw2RUFBNkU7UUFDN0UsUUFBRyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztRQUMvQiwyQ0FBMkM7UUFDM0MsYUFBUSxHQUFHLENBQUMsQ0FBQztRQUNiLHFEQUFxRDtRQUNyRCxVQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ1YsaURBQWlEO1FBQ2pELFNBQUksR0FBRyxHQUFHLENBQUM7SUFVUixDQUFDO0lBRUosZ0JBQWdCO0lBQ2hCLEtBQUs7UUFDRCxNQUFNLEVBQUUsR0FBRyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUNwRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxLQUF5QjtRQUM1QixJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN0QixPQUFPO1FBQ1gsQ0FBQztRQUNELElBQUksWUFBWSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDN0IsaUZBQWlGO1FBQ2pGLElBQUksZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUNyQyxJQUFJLElBQUksQ0FBQyxPQUFPLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDckIsWUFBWSxHQUFHLENBQUMsQ0FBQztZQUNqQixnQkFB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OERDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBJbmNyZW1lbnRhbGx5IHVwZGF0ZWQgc3RhdGlzdGljcyBvbiBhIHNldCBvZiB2YWx1ZXMuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGF0aXN0aWNzIHtcbiAgICAvKiogTnVtYmVyIG9mIHZhbHVlcyBvYnNlcnZlZC4gKi9cbiAgICBzYW1wbGVzID0gMDtcbiAgICAvKiogVGhlIG1heGltdW0gdmFsdWUgb2JzZXJ2ZWQuIEluaXRpYWxpemVkIHRvIGBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFlgLiAqL1xuICAgIG1heCA9IE51bWJlci5ORUdBVElWRV9JTkZJTklUWTtcbiAgICAvKiogVGhlIG1pbmltdW0gdmFsdWUgb2JzZXJ2ZWQuIEluaXRpYWxpemVkIHRvIGBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFlgLiAqL1xuICAgIG1pbiA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcbiAgICAvKiogVGhlIHZhcmlhbmNlIG9mIHRoZSB2YWx1ZXMgb2JzZXJ2ZWQuICovXG4gICAgdmFyaWFuY2UgPSAwO1xuICAgIC8qKiBUaGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSB2YWx1ZXMgb2JzZXJ2ZWQuICovXG4gICAgc3RkZXYgPSAwO1xuICAgIC8qKiBUaGUgbWVhbiAoYXZlcmFnZSkgb2YgdGhlIHZhbHVlcyBvYnNlcnZlZC4gKi9cbiAgICBtZWFuID0gTmFOO1xuXG4gICAgLyoqXG4gICAgICogSW5jcmVtZW50YWxseSB0cmFjayBtZWFuLCBzdGRldiwgbWluLCBtYXgsIG9mIGEgc2VxdWVuY2Ugb2YgdmFsdWVzLlxuICAgICAqIEBwYXJhbSBwcmludEZpeGVkUHJlY2lzaW9uIC0gVGhlIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcyB0byBwcmludCBpblxuICAgICAqIHtAbGluayBTdGF0aXN0aWNzLnRvU3RyaW5nfS5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgLyoqIFRoZSBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXMgdG8gcHJpbnQgaW4ge0BsaW5rIFN0YXRpc3RpY3MudG9TdHJpbmd9ICovXG4gICAgICAgIHByb3RlY3RlZCBwcmludEZpeGVkUHJlY2lzaW9uOiBudW1iZXIgPSAxXG4gICAgKSB7fVxuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIGNsb25lKCkge1xuICAgICAgICBjb25zdCBydiA9IG5ldyBTdGF0aXN0aWNzKHRoaXMucHJpbnRGaXhlZFByZWNpc2lvbik7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHJ2LCB0aGlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgc3RhdGlzdGljcyB3aXRoIGEgbmV3IHZhbHVlIGluIHRoZSBzZXF1ZW5jZS5cbiAgICAgKi9cbiAgICB1cGRhdGUodmFsdWU6IG51bWJlciB8IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwcmV2aW91c01lYW4gPSB0aGlzLm1lYW47XG4gICAgICAgIC8vIGh0dHBzOi8vbWF0aC5zdGFja2V4Y2hhbmdlLmNvbS9xdWVzdGlvbnMvMzc0ODgxL3JlY3Vyc2l2ZS1mb3JtdWxhLWZvci12YXJpYW5jZVxuICAgICAgICBsZXQgcHJldmlvdXNWYXJpYW5jZSA9IHRoaXMudmFyaWFuY2U7XG4gICAgICAgIGlmICh0aGlzLnNhbXBsZXMgPT09IDApIHtcbiAgICAgICAgICAgIHByZXZpb3VzTWVhbiA9IDA7XG4gICAgICAgICAgICBwcmV2aW91c1ZhcmlhbmNlID0gMDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNhbXBsZXMrKztcbiAgICAgICAgdGhpcy5tZWFuID0gcHJldmlvdXNNZWFuICsgKHZhbHVlIC0gcHJldmlvdXNNZWFuKSAvIHRoaXMuc2FtcGxlcztcbiAgICAgICAgdGhpcy52YXJpYW5jZSA9XG4gICAgICAgICAgICAoKHByZXZpb3VzVmFyaWFuY2UgKyAocHJldmlvdXNNZWFuIC0gdmFsdWUpICoqIDIgLyB0aGlzLnNhbXBsZXMpICpcbiAgICAgICAgICAgICAgICAodGhpcy5zYW1wbGVzIC0gMSkpIC9cbiAgICAgICAgICAgIHRoaXMuc2FtcGxlcztcbiAgICAgICAgdGhpcy5zdGRldiA9IE1hdGguc3FydCh0aGlzLnZhcmlhbmNlKTtcbiAgICAgICAgaWYgKHZhbHVlID4gdGhpcy5tYXgpIHtcbiAgICAgICAgICAgIHRoaXMubWF4ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlIDwgdGhpcy5taW4pIHtcbiAgICAgICAgICAgIHRoaXMubWluID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmludCB0aGUgbWVhbiBvZiB0aGUgb2JzZXJ2YXRpb25zIHNlZW4sIHdpdGggdGhlIHByZWNpc2lvbiBzcGVjaWZpZWQgaW5cbiAgICAgKiB0aGUgY29uc3RydWN0b3IuXG4gICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiBgJHt0aGlzLm1lYW4udG9GaXhlZCh0aGlzLnByaW50Rml4ZWRQcmVjaXNpb24pfWA7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgRXhwb25lbnRpYWxseURlY2F5aW5nQXZlcmFnZVZhbHVlIHtcbiAgICBzYW1wbGVzID0gMDtcbiAgICB2YWx1ZSA9IDA7XG4gICAgY29uc3RydWN0b3IocHVibGljIHNtb290aGluZ0ZhY3RvcjogbnVtYmVyKSB7fVxuICAgIHVwZGF0ZShuOiBudW1iZXIpIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnByZWZlci1jb25kaXRpb25hbC1leHByZXNzaW9uXG4gICAgICAgIGlmICh0aGlzLnNhbXBsZXMrKyA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IG47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID1cbiAgICAgICAgICAgICAgICB0aGlzLnNtb290aGluZ0ZhY3RvciAqIG4gKyAoMSAtIHRoaXMuc21vb3RoaW5nRmFjdG9yKSAqIHRoaXMudmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNsZWVwKG1zOiBudW1iZXIsIGNhbmNlbCA9IG5ldyBQcm9taXNlPHZvaWQ+KCgpID0+IHt9KSkge1xuICAgIGxldCBpZDogTm9kZUpTLlRpbWVyO1xuICAgIGNhbmNlbC50aGVuKF8gPT4gY2xlYXJUaW1lb3V0KGlkKSkuY2F0Y2goXyA9PiBjbGVhclRpbWVvdXQoaWQpKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yYWNlKFtuZXcgUHJvbWlzZShyZXNvbHZlID0+IChpZCA9IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKSksIGNhbmNlbF0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RyZWFtVG9CdWZmZXIoczogTm9kZUpTLlJlYWRhYmxlU3RyZWFtKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPEJ1ZmZlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCBidWZmZXJzOiBCdWZmZXJbXSA9IFtdO1xuICAgICAgICBzLm9uKFwiZXJyb3JcIiwgcmVqZWN0KTtcbiAgICAgICAgcy5vbihcImRhdGFcIiwgKGRhdGE6IEJ1ZmZlcikgPT4gYnVmZmVycy5wdXNoKGRhdGEpKTtcbiAgICAgICAgcy5vbihcImVuZFwiLCAoKSA9PiByZXNvbHZlKEJ1ZmZlci5jb25jYXQoYnVmZmVycykpKTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNob21wKHM6IHN0cmluZykge1xuICAgIGlmIChzLmxlbmd0aCA+IDAgJiYgc1tzLmxlbmd0aCAtIDFdID09PSBcIlxcblwiKSB7XG4gICAgICAgIHMgPSBzLnNsaWNlKDAsIHMubGVuZ3RoIC0gMSk7XG4gICAgfVxuICAgIHJldHVybiBzO1xufVxuXG5leHBvcnQgY29uc3Qgc3VtID0gKGE6IG51bWJlcltdKSA9PiBhLnJlZHVjZSgodG90YWwsIG4pID0+IHRvdGFsICsgbiwgMCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBvYmplY3RTaXplKG9iaj86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0pIHtcbiAgICBpZiAoIW9iaikge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIHN1bShPYmplY3Qua2V5cyhvYmopLm1hcChrZXkgPT4ga2V5Lmxlbmd0aCArIG9ialtrZXldLmxlbmd0aCkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZUh0dHBSZXNwb25zZUJ5dGVzKFxuICAgIGhlYWRlcnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0sXG4gICAgb3B0cyA9IHsgaHR0cEhlYWRlcnM6IHRydWUsIG1pbjogMCB9XG4pIHtcbiAgICBjb25zdCBoZWFkZXJLZXlzID0gT2JqZWN0LmtleXMoaGVhZGVycyk7XG4gICAgbGV0IGNvbnRlbnRMZW5ndGggPSAwO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIGhlYWRlcktleXMpIHtcbiAgICAgICAgaWYgKGtleS5tYXRjaCgvXmNvbnRlbnQtbGVuZ3RoJC9pKSkge1xuICAgICAgICAgICAgY29udGVudExlbmd0aCA9IE51bWJlcihoZWFkZXJzW2tleV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFvcHRzLmh0dHBIZWFkZXJzKSB7XG4gICAgICAgIHJldHVybiBNYXRoLm1heChjb250ZW50TGVuZ3RoLCBvcHRzLm1pbik7XG4gICAgfVxuICAgIGNvbnN0IGhlYWRlckxlbmd0aCA9IG9iamVjdFNpemUoaGVhZGVycykgKyBoZWFkZXJLZXlzLmxlbmd0aCAqIFwiOiBcIi5sZW5ndGg7XG4gICAgY29uc3Qgb3RoZXJMZW5ndGggPSAxMztcbiAgICByZXR1cm4gTWF0aC5tYXgoY29udGVudExlbmd0aCArIGhlYWRlckxlbmd0aCArIG90aGVyTGVuZ3RoLCBvcHRzLm1pbik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNFeHBpcmVkKFxuICAgIGRhdGU6IHN0cmluZyB8IG51bWJlciB8IHVuZGVmaW5lZCB8IG51bGwsXG4gICAgcmV0ZW50aW9uSW5EYXlzOiBudW1iZXJcbikge1xuICAgIGlmIChyZXRlbnRpb25JbkRheXMgPD0gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgdGltZXN0YW1wID0gdHlwZW9mIGRhdGUgPT09IFwic3RyaW5nXCIgPyBEYXRlLnBhcnNlKGRhdGUpIDogZGF0ZSB8fCAwO1xuICAgIHJldHVybiB0aW1lc3RhbXAgPCBEYXRlLm5vdygpIC0gcmV0ZW50aW9uSW5EYXlzICogMjQgKiA2MCAqIDYwICogMTAwMDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdW5kVG8xMDBtcyhuOiBudW1iZXIpIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChuIC8gMTAwKSAqIDEwMDtcbn1cblxuZXhwb3J0IGNvbnN0IHV1aWR2NFBhdHRlcm4gPVxuICAgIFwiW2EtZjAtOV17OH0tW2EtZjAtOV17NH0tNFthLWYwLTldezN9LVs4OWFBYkJdW2EtZjAtOV17M30tW2EtZjAtOV17MTJ9XCI7XG5cbmV4cG9ydCBjb25zdCBHQiA9IDIgKiogMzA7XG5leHBvcnQgY29uc3QgTUIgPSAyICoqIDIwO1xuZXhwb3J0IGNvbnN0IEtCID0gMiAqKiAxMDtcblxuZXhwb3J0IGZ1bmN0aW9uIGYxKG46IG51bWJlcikge1xuICAgIHJldHVybiBuLnRvRml4ZWQoMSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmMihuOiBudW1iZXIpIHtcbiAgICByZXR1cm4gbi50b0ZpeGVkKDIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24ga2V5c09mPEsgZXh0ZW5kcyBzdHJpbmcsIE8gZXh0ZW5kcyB7IFtrZXkgaW4gS106IGFueSB9PihcbiAgICBvYmo6IE9cbik6IEFycmF5PGtleW9mIE8+O1xuZXhwb3J0IGZ1bmN0aW9uIGtleXNPZjxPIGV4dGVuZHMgb2JqZWN0PihvYmo6IE8pOiBBcnJheTxrZXlvZiBPPiB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKG9iaikgYXMgQXJyYXk8a2V5b2YgTz47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZpbmVkPFQ+KGFyZzogVCB8IHVuZGVmaW5lZCB8IG51bGwgfCB2b2lkKTogYXJnIGlzIFQge1xuICAgIHJldHVybiAhIWFyZztcbn1cblxuZXhwb3J0IGNsYXNzIE1heEhlYXAge1xuICAgIHByb3RlY3RlZCBfaGVhcDogbnVtYmVyW10gPSBbXTtcblxuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faGVhcC5sZW5ndGg7XG4gICAgfVxuXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuX2hlYXAgPSBbXTtcbiAgICB9XG5cbiAgICBwZWVrTWF4KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faGVhcFswXTtcbiAgICB9XG5cbiAgICBpbnNlcnQodmFsdWU6IG51bWJlcikge1xuICAgICAgICBjb25zdCBoID0gdGhpcy5faGVhcDtcbiAgICAgICAgaC5wdXNoKHZhbHVlKTtcbiAgICAgICAgbGV0IGkgPSBoLmxlbmd0aCAtIDE7XG4gICAgICAgIGNvbnN0IHBhcmVudE9mID0gKG46IG51bWJlcikgPT4gTWF0aC5mbG9vcigobiAtIDEpIC8gMik7XG4gICAgICAgIGxldCBwYXJlbnQgPSBwYXJlbnRPZihpKTtcbiAgICAgICAgd2hpbGUgKHBhcmVudCA+PSAwICYmIGhbaV0gPiBoW3BhcmVudF0pIHtcbiAgICAgICAgICAgIGNvbnN0IHRtcCA9IGhbcGFyZW50XTtcbiAgICAgICAgICAgIGhbcGFyZW50XSA9IGhbaV07XG4gICAgICAgICAgICBoW2ldID0gdG1wO1xuICAgICAgICAgICAgaSA9IHBhcmVudDtcbiAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudE9mKGkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZXh0cmFjdE1heCgpIHtcbiAgICAgICAgY29uc3QgaCA9IHRoaXMuX2hlYXA7XG4gICAgICAgIGlmIChoLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZXh0cmFjdE1heCBjYWxsZWQgb24gZW1wdHkgaGVhcFwiKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgIGNvbnN0IHJ2ID0gaFswXTtcbiAgICAgICAgaFswXSA9IGhbaC5sZW5ndGggLSAxXTtcbiAgICAgICAgaC5wb3AoKTtcblxuICAgICAgICB3aGlsZSAoaSA8IGgubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBbbGVmdCwgcmlnaHRdID0gW2kgKiAyICsgMSwgaSAqIDIgKyAyXTtcbiAgICAgICAgICAgIGxldCBtYXliZTogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKGhbaV0gPCBoW2xlZnRdICYmICEoaFtyaWdodF0gPiBoW2xlZnRdKSkge1xuICAgICAgICAgICAgICAgIG1heWJlID0gbGVmdDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaFtpXSA8IGhbcmlnaHRdKSB7XG4gICAgICAgICAgICAgICAgbWF5YmUgPSByaWdodDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtYXliZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBbaVZhbHVlLCBtVmFsdWVdID0gW2hbaV0sIGhbbWF5YmVdXTtcbiAgICAgICAgICAgIGhbaV0gPSBtVmFsdWU7XG4gICAgICAgICAgICBoW21heWJlXSA9IGlWYWx1ZTtcbiAgICAgICAgICAgIGkgPSBtYXliZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBydjtcbiAgICB9XG5cbiAgICBbU3ltYm9sLml0ZXJhdG9yXSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hlYXBbU3ltYm9sLml0ZXJhdG9yXSgpO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNtYWxsZXN0TjxUID0gdm9pZD4ge1xuICAgIHByb3RlY3RlZCBfaGVhcCA9IG5ldyBNYXhIZWFwKCk7XG4gICAgcHJvdGVjdGVkIF9tYXA6IFtudW1iZXIsIFRdW10gPSBbXTtcblxuICAgIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBfc2l6ZTogbnVtYmVyKSB7fVxuXG4gICAgdXBkYXRlKGtleTogbnVtYmVyLCB2YWx1ZTogVCkge1xuICAgICAgICBpZiAodGhpcy5faGVhcC5zaXplIDwgdGhpcy5fc2l6ZSkge1xuICAgICAgICAgICAgdGhpcy5faGVhcC5pbnNlcnQoa2V5KTtcbiAgICAgICAgICAgIHRoaXMuX21hcC5wdXNoKFtrZXksIHZhbHVlXSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGtleSA+PSB0aGlzLl9oZWFwLnBlZWtNYXgoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2hlYXAuaW5zZXJ0KGtleSk7XG4gICAgICAgIHRoaXMuX21hcC5wdXNoKFtrZXksIHZhbHVlXSk7XG4gICAgICAgIHRoaXMuc2hyaW5rKCk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHNocmluaygpIHtcbiAgICAgICAgY29uc3QgbWF4ID0gdGhpcy5faGVhcC5leHRyYWN0TWF4KCk7XG4gICAgICAgIGxldCBpZHggPSB0aGlzLl9tYXAubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoLS1pZHggPj0gMCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX21hcFtpZHhdWzBdID09PSBtYXgpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaWR4ID09PSAtMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTbWFsbGVzdE46IGNvdWxkIG5vdCBmaW5kIGVudHJ5IGZvciBrZXkgJHttYXh9YCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbWFwLnNwbGljZShpZHgsIDEpO1xuICAgIH1cblxuICAgIFtTeW1ib2wuaXRlcmF0b3JdKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwW1N5bWJvbC5pdGVyYXRvcl0oKTtcbiAgICB9XG5cbiAgICBlbnRyaWVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwW1N5bWJvbC5pdGVyYXRvcl07XG4gICAgfVxuXG4gICAga2V5cygpIHtcbiAgICAgICAgcmV0dXJuIFsuLi50aGlzLl9oZWFwXTtcbiAgICB9XG5cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpemU7XG4gICAgfVxuXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuX2hlYXAuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fbWFwID0gW107XG4gICAgfVxuXG4gICAgc2V0U2l6ZShuZXdTaXplOiBudW1iZXIpIHtcbiAgICAgICAgd2hpbGUgKHRoaXMuX3NpemUgPiBuZXdTaXplKSB7XG4gICAgICAgICAgICB0aGlzLnNocmluaygpO1xuICAgICAgICAgICAgdGhpcy5fc2l6ZS0tO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3NpemUgPSBuZXdTaXplO1xuICAgIH1cbn1cbiJdfQ==