1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | 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;
|
4 | /**
|
5 | * Incrementally updated statistics on a set of values.
|
6 | * @public
|
7 | */
|
8 | class Statistics {
|
9 | /**
|
10 | * Incrementally track mean, stdev, min, max, of a sequence of values.
|
11 | * @param printFixedPrecision - The number of decimal places to print in
|
12 | * {@link Statistics.toString}.
|
13 | */
|
14 | constructor(
|
15 | /** The number of decimal places to print in {@link Statistics.toString} */
|
16 | printFixedPrecision = 1) {
|
17 | this.printFixedPrecision = printFixedPrecision;
|
18 | /** Number of values observed. */
|
19 | this.samples = 0;
|
20 | /** The maximum value observed. Initialized to `Number.NEGATIVE_INFINITY`. */
|
21 | this.max = Number.NEGATIVE_INFINITY;
|
22 | /** The minimum value observed. Initialized to `Number.POSITIVE_INFINITY`. */
|
23 | this.min = Number.POSITIVE_INFINITY;
|
24 | /** The variance of the values observed. */
|
25 | this.variance = 0;
|
26 | /** The standard deviation of the values observed. */
|
27 | this.stdev = 0;
|
28 | /** The mean (average) of the values observed. */
|
29 | this.mean = NaN;
|
30 | }
|
31 | /** @internal */
|
32 | clone() {
|
33 | const rv = new Statistics(this.printFixedPrecision);
|
34 | return Object.assign(rv, this);
|
35 | }
|
36 | /**
|
37 | * Update statistics with a new value in the sequence.
|
38 | */
|
39 | update(value) {
|
40 | if (value === undefined) {
|
41 | return;
|
42 | }
|
43 | let previousMean = this.mean;
|
44 | // https://math.stackexchange.com/questions/374881/recursive-formula-for-variance
|
45 | let previousVariance = this.variance;
|
46 | if (this.samples === 0) {
|
47 | previousMean = 0;
|
48 | previousVariance = 0;
|
49 | }
|
50 | this.samples++;
|
51 | this.mean = previousMean + (value - previousMean) / this.samples;
|
52 | this.variance =
|
53 | ((previousVariance + (previousMean - value) ** 2 / this.samples) *
|
54 | (this.samples - 1)) /
|
55 | this.samples;
|
56 | this.stdev = Math.sqrt(this.variance);
|
57 | if (value > this.max) {
|
58 | this.max = value;
|
59 | }
|
60 | if (value < this.min) {
|
61 | this.min = value;
|
62 | }
|
63 | }
|
64 | /**
|
65 | * Print the mean of the observations seen, with the precision specified in
|
66 | * the constructor.
|
67 | */
|
68 | toString() {
|
69 | return `${this.mean.toFixed(this.printFixedPrecision)}`;
|
70 | }
|
71 | }
|
72 | exports.Statistics = Statistics;
|
73 | class ExponentiallyDecayingAverageValue {
|
74 | constructor(smoothingFactor) {
|
75 | this.smoothingFactor = smoothingFactor;
|
76 | this.samples = 0;
|
77 | this.value = 0;
|
78 | }
|
79 | update(n) {
|
80 | // tslint:disable-next-line:prefer-conditional-expression
|
81 | if (this.samples++ === 0) {
|
82 | this.value = n;
|
83 | }
|
84 | else {
|
85 | this.value =
|
86 | this.smoothingFactor * n + (1 - this.smoothingFactor) * this.value;
|
87 | }
|
88 | }
|
89 | toString() {
|
90 | return this.value;
|
91 | }
|
92 | }
|
93 | exports.ExponentiallyDecayingAverageValue = ExponentiallyDecayingAverageValue;
|
94 | function sleep(ms, cancel = new Promise(() => { })) {
|
95 | let id;
|
96 | cancel.then(_ => clearTimeout(id)).catch(_ => clearTimeout(id));
|
97 | return Promise.race([new Promise(resolve => (id = setTimeout(resolve, ms))), cancel]);
|
98 | }
|
99 | exports.sleep = sleep;
|
100 | function streamToBuffer(s) {
|
101 | return new Promise((resolve, reject) => {
|
102 | const buffers = [];
|
103 | s.on("error", reject);
|
104 | s.on("data", (data) => buffers.push(data));
|
105 | s.on("end", () => resolve(Buffer.concat(buffers)));
|
106 | });
|
107 | }
|
108 | exports.streamToBuffer = streamToBuffer;
|
109 | function chomp(s) {
|
110 | if (s.length > 0 && s[s.length - 1] === "\n") {
|
111 | s = s.slice(0, s.length - 1);
|
112 | }
|
113 | return s;
|
114 | }
|
115 | exports.chomp = chomp;
|
116 | const sum = (a) => a.reduce((total, n) => total + n, 0);
|
117 | exports.sum = sum;
|
118 | function objectSize(obj) {
|
119 | if (!obj) {
|
120 | return 0;
|
121 | }
|
122 | return (0, exports.sum)(Object.keys(obj).map(key => key.length + obj[key].length));
|
123 | }
|
124 | exports.objectSize = objectSize;
|
125 | function computeHttpResponseBytes(headers, opts = { httpHeaders: true, min: 0 }) {
|
126 | const headerKeys = Object.keys(headers);
|
127 | let contentLength = 0;
|
128 | for (const key of headerKeys) {
|
129 | if (key.match(/^content-length$/i)) {
|
130 | contentLength = Number(headers[key]);
|
131 | break;
|
132 | }
|
133 | }
|
134 | if (!opts.httpHeaders) {
|
135 | return Math.max(contentLength, opts.min);
|
136 | }
|
137 | const headerLength = objectSize(headers) + headerKeys.length * ": ".length;
|
138 | const otherLength = 13;
|
139 | return Math.max(contentLength + headerLength + otherLength, opts.min);
|
140 | }
|
141 | exports.computeHttpResponseBytes = computeHttpResponseBytes;
|
142 | function hasExpired(date, retentionInDays) {
|
143 | if (retentionInDays <= 0) {
|
144 | return true;
|
145 | }
|
146 | const timestamp = typeof date === "string" ? Date.parse(date) : date || 0;
|
147 | return timestamp < Date.now() - retentionInDays * 24 * 60 * 60 * 1000;
|
148 | }
|
149 | exports.hasExpired = hasExpired;
|
150 | function roundTo100ms(n) {
|
151 | return Math.round(n / 100) * 100;
|
152 | }
|
153 | exports.roundTo100ms = roundTo100ms;
|
154 | exports.uuidv4Pattern = "[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}";
|
155 | exports.GB = 2 ** 30;
|
156 | exports.MB = 2 ** 20;
|
157 | exports.KB = 2 ** 10;
|
158 | function f1(n) {
|
159 | return n.toFixed(1);
|
160 | }
|
161 | exports.f1 = f1;
|
162 | function f2(n) {
|
163 | return n.toFixed(2);
|
164 | }
|
165 | exports.f2 = f2;
|
166 | function keysOf(obj) {
|
167 | return Object.keys(obj);
|
168 | }
|
169 | exports.keysOf = keysOf;
|
170 | function defined(arg) {
|
171 | return !!arg;
|
172 | }
|
173 | exports.defined = defined;
|
174 | class MaxHeap {
|
175 | constructor() {
|
176 | this._heap = [];
|
177 | }
|
178 | get size() {
|
179 | return this._heap.length;
|
180 | }
|
181 | clear() {
|
182 | this._heap = [];
|
183 | }
|
184 | peekMax() {
|
185 | return this._heap[0];
|
186 | }
|
187 | insert(value) {
|
188 | const h = this._heap;
|
189 | h.push(value);
|
190 | let i = h.length - 1;
|
191 | const parentOf = (n) => Math.floor((n - 1) / 2);
|
192 | let parent = parentOf(i);
|
193 | while (parent >= 0 && h[i] > h[parent]) {
|
194 | const tmp = h[parent];
|
195 | h[parent] = h[i];
|
196 | h[i] = tmp;
|
197 | i = parent;
|
198 | parent = parentOf(i);
|
199 | }
|
200 | }
|
201 | extractMax() {
|
202 | const h = this._heap;
|
203 | if (h.length === 0) {
|
204 | throw new Error("extractMax called on empty heap");
|
205 | }
|
206 | let i = 0;
|
207 | const rv = h[0];
|
208 | h[0] = h[h.length - 1];
|
209 | h.pop();
|
210 | while (i < h.length) {
|
211 | const [left, right] = [i * 2 + 1, i * 2 + 2];
|
212 | let maybe;
|
213 | if (h[i] < h[left] && !(h[right] > h[left])) {
|
214 | maybe = left;
|
215 | }
|
216 | else if (h[i] < h[right]) {
|
217 | maybe = right;
|
218 | }
|
219 | if (maybe === undefined) {
|
220 | break;
|
221 | }
|
222 | const [iValue, mValue] = [h[i], h[maybe]];
|
223 | h[i] = mValue;
|
224 | h[maybe] = iValue;
|
225 | i = maybe;
|
226 | }
|
227 | return rv;
|
228 | }
|
229 | [Symbol.iterator]() {
|
230 | return this._heap[Symbol.iterator]();
|
231 | }
|
232 | }
|
233 | exports.MaxHeap = MaxHeap;
|
234 | class SmallestN {
|
235 | constructor(_size) {
|
236 | this._size = _size;
|
237 | this._heap = new MaxHeap();
|
238 | this._map = [];
|
239 | }
|
240 | update(key, value) {
|
241 | if (this._heap.size < this._size) {
|
242 | this._heap.insert(key);
|
243 | this._map.push([key, value]);
|
244 | return;
|
245 | }
|
246 | if (key >= this._heap.peekMax()) {
|
247 | return;
|
248 | }
|
249 | this._heap.insert(key);
|
250 | this._map.push([key, value]);
|
251 | this.shrink();
|
252 | }
|
253 | shrink() {
|
254 | const max = this._heap.extractMax();
|
255 | let idx = this._map.length;
|
256 | while (--idx >= 0) {
|
257 | if (this._map[idx][0] === max) {
|
258 | break;
|
259 | }
|
260 | }
|
261 | if (idx === -1) {
|
262 | throw new Error(`SmallestN: could not find entry for key ${max}`);
|
263 | }
|
264 | this._map.splice(idx, 1);
|
265 | }
|
266 | [Symbol.iterator]() {
|
267 | return this._map[Symbol.iterator]();
|
268 | }
|
269 | entries() {
|
270 | return this._map[Symbol.iterator];
|
271 | }
|
272 | keys() {
|
273 | return [...this._heap];
|
274 | }
|
275 | get size() {
|
276 | return this._size;
|
277 | }
|
278 | clear() {
|
279 | this._heap.clear();
|
280 | this._map = [];
|
281 | }
|
282 | setSize(newSize) {
|
283 | while (this._size > newSize) {
|
284 | this.shrink();
|
285 | this._size--;
|
286 | }
|
287 | this._size = newSize;
|
288 | }
|
289 | }
|
290 | exports.SmallestN = SmallestN;
|
291 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NoYXJlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7O0dBR0c7QUFDSCxNQUFhLFVBQVU7SUFjbkI7Ozs7T0FJRztJQUNIO0lBQ0ksMkVBQTJFO0lBQ2pFLHNCQUE4QixDQUFDO1FBQS9CLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBWTtRQXBCN0MsaUNBQWlDO1FBQ2pDLFlBQU8sR0FBRyxDQUFDLENBQUM7UUFDWiw2RUFBNkU7UUFDN0UsUUFBRyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztRQUMvQiw2RUFBNkU7UUFDN0UsUUFBRyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztRQUMvQiwyQ0FBMkM7UUFDM0MsYUFBUSxHQUFHLENBQUMsQ0FBQztRQUNiLHFEQUFxRDtRQUNyRCxVQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ1YsaURBQWlEO1FBQ2pELFNBQUksR0FBRyxHQUFHLENBQUM7SUFVUixDQUFDO0lBRUosZ0JBQWdCO0lBQ2hCLEtBQUs7UUFDRCxNQUFNLEVBQUUsR0FBRyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUNwRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxLQUF5QjtRQUM1QixJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUU7WUFDckIsT0FBTztTQUNWO1FBQ0QsSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUM3QixpRkFBaUY7UUFDakYsSUFBSSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQ3JDLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxDQUFDLEVBQUU7WUFDcEIsWUFBWSxHQUFHLENBQUMsQ0FBQztZQUNqQixnQkFBZ0IsR0FBRyxDQUFDLENB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ckU7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVELENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztRQUNiLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztJQUN4QyxDQUFDO0lBRUQsT0FBTztRQUNILE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVELElBQUk7UUFDQSxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0IsQ0FBQztJQUVELElBQUksSUFBSTtRQUNKLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUN0QixDQUFDO0lBRUQsS0FBSztRQUNELElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVELE9BQU8sQ0FBQyxPQUFlO1FBQ25CLE9BQU8sSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLEVBQUU7WUFDekIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1NBQ2hCO1FBQ0QsSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUM7SUFDekIsQ0FBQztDQUNKO0FBOURELDhCQThEQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSW5jcmVtZW50YWxseSB1cGRhdGVkIHN0YXRpc3RpY3Mgb24gYSBzZXQgb2YgdmFsdWVzLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY2xhc3MgU3RhdGlzdGljcyB7XG4gICAgLyoqIE51bWJlciBvZiB2YWx1ZXMgb2JzZXJ2ZWQuICovXG4gICAgc2FtcGxlcyA9IDA7XG4gICAgLyoqIFRoZSBtYXhpbXVtIHZhbHVlIG9ic2VydmVkLiBJbml0aWFsaXplZCB0byBgTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZYC4gKi9cbiAgICBtYXggPSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XG4gICAgLyoqIFRoZSBtaW5pbXVtIHZhbHVlIG9ic2VydmVkLiBJbml0aWFsaXplZCB0byBgTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZYC4gKi9cbiAgICBtaW4gPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gICAgLyoqIFRoZSB2YXJpYW5jZSBvZiB0aGUgdmFsdWVzIG9ic2VydmVkLiAqL1xuICAgIHZhcmlhbmNlID0gMDtcbiAgICAvKiogVGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgdmFsdWVzIG9ic2VydmVkLiAqL1xuICAgIHN0ZGV2ID0gMDtcbiAgICAvKiogVGhlIG1lYW4gKGF2ZXJhZ2UpIG9mIHRoZSB2YWx1ZXMgb2JzZXJ2ZWQuICovXG4gICAgbWVhbiA9IE5hTjtcblxuICAgIC8qKlxuICAgICAqIEluY3JlbWVudGFsbHkgdHJhY2sgbWVhbiwgc3RkZXYsIG1pbiwgbWF4LCBvZiBhIHNlcXVlbmNlIG9mIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0gcHJpbnRGaXhlZFByZWNpc2lvbiAtIFRoZSBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXMgdG8gcHJpbnQgaW5cbiAgICAgKiB7QGxpbmsgU3RhdGlzdGljcy50b1N0cmluZ30uXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIC8qKiBUaGUgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzIHRvIHByaW50IGluIHtAbGluayBTdGF0aXN0aWNzLnRvU3RyaW5nfSAqL1xuICAgICAgICBwcm90ZWN0ZWQgcHJpbnRGaXhlZFByZWNpc2lvbjogbnVtYmVyID0gMVxuICAgICkge31cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBjbG9uZSgpIHtcbiAgICAgICAgY29uc3QgcnYgPSBuZXcgU3RhdGlzdGljcyh0aGlzLnByaW50Rml4ZWRQcmVjaXNpb24pO1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihydiwgdGhpcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlIHN0YXRpc3RpY3Mgd2l0aCBhIG5ldyB2YWx1ZSBpbiB0aGUgc2VxdWVuY2UuXG4gICAgICovXG4gICAgdXBkYXRlKHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcHJldmlvdXNNZWFuID0gdGhpcy5tZWFuO1xuICAgICAgICAvLyBodHRwczovL21hdGguc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzM3NDg4MS9yZWN1cnNpdmUtZm9ybXVsYS1mb3ItdmFyaWFuY2VcbiAgICAgICAgbGV0IHByZXZpb3VzVmFyaWFuY2UgPSB0aGlzLnZhcmlhbmNlO1xuICAgICAgICBpZiAodGhpcy5zYW1wbGVzID09PSAwKSB7XG4gICAgICAgICAgICBwcmV2aW91c01lYW4gPSAwO1xuICAgICAgICAgICAgcHJldmlvdXNWYXJpYW5jZSA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zYW1wbGVzKys7XG4gICAgICAgIHRoaXMubWVhbiA9IHByZXZpb3VzTWVhbiArICh2YWx1ZSAtIHByZXZpb3VzTWVhbikgLyB0aGlzLnNhbXBsZXM7XG4gICAgICAgIHRoaXMudmFyaWFuY2UgPVxuICAgICAgICAgICAgKChwcmV2aW91c1ZhcmlhbmNlICsgKHByZXZpb3VzTWVhbiAtIHZhbHVlKSAqKiAyIC8gdGhpcy5zYW1wbGVzKSAqXG4gICAgICAgICAgICAgICAgKHRoaXMuc2FtcGxlcyAtIDEpKSAvXG4gICAgICAgICAgICB0aGlzLnNhbXBsZXM7XG4gICAgICAgIHRoaXMuc3RkZXYgPSBNYXRoLnNxcnQodGhpcy52YXJpYW5jZSk7XG4gICAgICAgIGlmICh2YWx1ZSA+IHRoaXMubWF4KSB7XG4gICAgICAgICAgICB0aGlzLm1heCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh2YWx1ZSA8IHRoaXMubWluKSB7XG4gICAgICAgICAgICB0aGlzLm1pbiA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJpbnQgdGhlIG1lYW4gb2YgdGhlIG9ic2VydmF0aW9ucyBzZWVuLCB3aXRoIHRoZSBwcmVjaXNpb24gc3BlY2lmaWVkIGluXG4gICAgICogdGhlIGNvbnN0cnVjdG9yLlxuICAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gYCR7dGhpcy5tZWFuLnRvRml4ZWQodGhpcy5wcmludEZpeGVkUHJlY2lzaW9uKX1gO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEV4cG9uZW50aWFsbHlEZWNheWluZ0F2ZXJhZ2VWYWx1ZSB7XG4gICAgc2FtcGxlcyA9IDA7XG4gICAgdmFsdWUgPSAwO1xuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBzbW9vdGhpbmdGYWN0b3I6IG51bWJlcikge31cbiAgICB1cGRhdGUobjogbnVtYmVyKSB7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpwcmVmZXItY29uZGl0aW9uYWwtZXhwcmVzc2lvblxuICAgICAgICBpZiAodGhpcy5zYW1wbGVzKysgPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9XG4gICAgICAgICAgICAgICAgdGhpcy5zbW9vdGhpbmdGYWN0b3IgKiBuICsgKDEgLSB0aGlzLnNtb290aGluZ0ZhY3RvcikgKiB0aGlzLnZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyLCBjYW5jZWwgPSBuZXcgUHJvbWlzZTx2b2lkPigoKSA9PiB7fSkpIHtcbiAgICBsZXQgaWQ6IE5vZGVKUy5UaW1lcjtcbiAgICBjYW5jZWwudGhlbihfID0+IGNsZWFyVGltZW91dChpZCkpLmNhdGNoKF8gPT4gY2xlYXJUaW1lb3V0KGlkKSk7XG4gICAgcmV0dXJuIFByb21pc2UucmFjZShbbmV3IFByb21pc2UocmVzb2x2ZSA9PiAoaWQgPSBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSkpLCBjYW5jZWxdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN0cmVhbVRvQnVmZmVyKHM6IE5vZGVKUy5SZWFkYWJsZVN0cmVhbSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxCdWZmZXI+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3QgYnVmZmVyczogQnVmZmVyW10gPSBbXTtcbiAgICAgICAgcy5vbihcImVycm9yXCIsIHJlamVjdCk7XG4gICAgICAgIHMub24oXCJkYXRhXCIsIChkYXRhOiBCdWZmZXIpID0+IGJ1ZmZlcnMucHVzaChkYXRhKSk7XG4gICAgICAgIHMub24oXCJlbmRcIiwgKCkgPT4gcmVzb2x2ZShCdWZmZXIuY29uY2F0KGJ1ZmZlcnMpKSk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjaG9tcChzOiBzdHJpbmcpIHtcbiAgICBpZiAocy5sZW5ndGggPiAwICYmIHNbcy5sZW5ndGggLSAxXSA9PT0gXCJcXG5cIikge1xuICAgICAgICBzID0gcy5zbGljZSgwLCBzLmxlbmd0aCAtIDEpO1xuICAgIH1cbiAgICByZXR1cm4gcztcbn1cblxuZXhwb3J0IGNvbnN0IHN1bSA9IChhOiBudW1iZXJbXSkgPT4gYS5yZWR1Y2UoKHRvdGFsLCBuKSA9PiB0b3RhbCArIG4sIDApO1xuXG5leHBvcnQgZnVuY3Rpb24gb2JqZWN0U2l6ZShvYmo/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KSB7XG4gICAgaWYgKCFvYmopIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHJldHVybiBzdW0oT2JqZWN0LmtleXMob2JqKS5tYXAoa2V5ID0+IGtleS5sZW5ndGggKyBvYmpba2V5XS5sZW5ndGgpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVIdHRwUmVzcG9uc2VCeXRlcyhcbiAgICBoZWFkZXJzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9LFxuICAgIG9wdHMgPSB7IGh0dHBIZWFkZXJzOiB0cnVlLCBtaW46IDAgfVxuKSB7XG4gICAgY29uc3QgaGVhZGVyS2V5cyA9IE9iamVjdC5rZXlzKGhlYWRlcnMpO1xuICAgIGxldCBjb250ZW50TGVuZ3RoID0gMDtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBoZWFkZXJLZXlzKSB7XG4gICAgICAgIGlmIChrZXkubWF0Y2goL15jb250ZW50LWxlbmd0aCQvaSkpIHtcbiAgICAgICAgICAgIGNvbnRlbnRMZW5ndGggPSBOdW1iZXIoaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICghb3B0cy5odHRwSGVhZGVycykge1xuICAgICAgICByZXR1cm4gTWF0aC5tYXgoY29udGVudExlbmd0aCwgb3B0cy5taW4pO1xuICAgIH1cbiAgICBjb25zdCBoZWFkZXJMZW5ndGggPSBvYmplY3RTaXplKGhlYWRlcnMpICsgaGVhZGVyS2V5cy5sZW5ndGggKiBcIjogXCIubGVuZ3RoO1xuICAgIGNvbnN0IG90aGVyTGVuZ3RoID0gMTM7XG4gICAgcmV0dXJuIE1hdGgubWF4KGNvbnRlbnRMZW5ndGggKyBoZWFkZXJMZW5ndGggKyBvdGhlckxlbmd0aCwgb3B0cy5taW4pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzRXhwaXJlZChcbiAgICBkYXRlOiBzdHJpbmcgfCBudW1iZXIgfCB1bmRlZmluZWQgfCBudWxsLFxuICAgIHJldGVudGlvbkluRGF5czogbnVtYmVyXG4pIHtcbiAgICBpZiAocmV0ZW50aW9uSW5EYXlzIDw9IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IHRpbWVzdGFtcCA9IHR5cGVvZiBkYXRlID09PSBcInN0cmluZ1wiID8gRGF0ZS5wYXJzZShkYXRlKSA6IGRhdGUgfHwgMDtcbiAgICByZXR1cm4gdGltZXN0YW1wIDwgRGF0ZS5ub3coKSAtIHJldGVudGlvbkluRGF5cyAqIDI0ICogNjAgKiA2MCAqIDEwMDA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByb3VuZFRvMTAwbXMobjogbnVtYmVyKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQobiAvIDEwMCkgKiAxMDA7XG59XG5cbmV4cG9ydCBjb25zdCB1dWlkdjRQYXR0ZXJuID1cbiAgICBcIlthLWYwLTldezh9LVthLWYwLTldezR9LTRbYS1mMC05XXszfS1bODlhQWJCXVthLWYwLTldezN9LVthLWYwLTldezEyfVwiO1xuXG5leHBvcnQgY29uc3QgR0IgPSAyICoqIDMwO1xuZXhwb3J0IGNvbnN0IE1CID0gMiAqKiAyMDtcbmV4cG9ydCBjb25zdCBLQiA9IDIgKiogMTA7XG5cbmV4cG9ydCBmdW5jdGlvbiBmMShuOiBudW1iZXIpIHtcbiAgICByZXR1cm4gbi50b0ZpeGVkKDEpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZjIobjogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG4udG9GaXhlZCgyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGtleXNPZjxLIGV4dGVuZHMgc3RyaW5nLCBPIGV4dGVuZHMgeyBba2V5IGluIEtdOiBhbnkgfT4oXG4gICAgb2JqOiBPXG4pOiBBcnJheTxrZXlvZiBPPjtcbmV4cG9ydCBmdW5jdGlvbiBrZXlzT2Y8TyBleHRlbmRzIG9iamVjdD4ob2JqOiBPKTogQXJyYXk8a2V5b2YgTz4ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhvYmopIGFzIEFycmF5PGtleW9mIE8+O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVmaW5lZDxUPihhcmc6IFQgfCB1bmRlZmluZWQgfCBudWxsIHwgdm9pZCk6IGFyZyBpcyBUIHtcbiAgICByZXR1cm4gISFhcmc7XG59XG5cbmV4cG9ydCBjbGFzcyBNYXhIZWFwIHtcbiAgICBwcm90ZWN0ZWQgX2hlYXA6IG51bWJlcltdID0gW107XG5cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hlYXAubGVuZ3RoO1xuICAgIH1cblxuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLl9oZWFwID0gW107XG4gICAgfVxuXG4gICAgcGVla01heCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hlYXBbMF07XG4gICAgfVxuXG4gICAgaW5zZXJ0KHZhbHVlOiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgaCA9IHRoaXMuX2hlYXA7XG4gICAgICAgIGgucHVzaCh2YWx1ZSk7XG4gICAgICAgIGxldCBpID0gaC5sZW5ndGggLSAxO1xuICAgICAgICBjb25zdCBwYXJlbnRPZiA9IChuOiBudW1iZXIpID0+IE1hdGguZmxvb3IoKG4gLSAxKSAvIDIpO1xuICAgICAgICBsZXQgcGFyZW50ID0gcGFyZW50T2YoaSk7XG4gICAgICAgIHdoaWxlIChwYXJlbnQgPj0gMCAmJiBoW2ldID4gaFtwYXJlbnRdKSB7XG4gICAgICAgICAgICBjb25zdCB0bXAgPSBoW3BhcmVudF07XG4gICAgICAgICAgICBoW3BhcmVudF0gPSBoW2ldO1xuICAgICAgICAgICAgaFtpXSA9IHRtcDtcbiAgICAgICAgICAgIGkgPSBwYXJlbnQ7XG4gICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnRPZihpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGV4dHJhY3RNYXgoKSB7XG4gICAgICAgIGNvbnN0IGggPSB0aGlzLl9oZWFwO1xuICAgICAgICBpZiAoaC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImV4dHJhY3RNYXggY2FsbGVkIG9uIGVtcHR5IGhlYXBcIik7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICBjb25zdCBydiA9IGhbMF07XG4gICAgICAgIGhbMF0gPSBoW2gubGVuZ3RoIC0gMV07XG4gICAgICAgIGgucG9wKCk7XG5cbiAgICAgICAgd2hpbGUgKGkgPCBoLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgW2xlZnQsIHJpZ2h0XSA9IFtpICogMiArIDEsIGkgKiAyICsgMl07XG4gICAgICAgICAgICBsZXQgbWF5YmU6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmIChoW2ldIDwgaFtsZWZ0XSAmJiAhKGhbcmlnaHRdID4gaFtsZWZ0XSkpIHtcbiAgICAgICAgICAgICAgICBtYXliZSA9IGxlZnQ7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGhbaV0gPCBoW3JpZ2h0XSkge1xuICAgICAgICAgICAgICAgIG1heWJlID0gcmlnaHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWF5YmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgW2lWYWx1ZSwgbVZhbHVlXSA9IFtoW2ldLCBoW21heWJlXV07XG4gICAgICAgICAgICBoW2ldID0gbVZhbHVlO1xuICAgICAgICAgICAgaFttYXliZV0gPSBpVmFsdWU7XG4gICAgICAgICAgICBpID0gbWF5YmU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcnY7XG4gICAgfVxuXG4gICAgW1N5bWJvbC5pdGVyYXRvcl0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oZWFwW1N5bWJvbC5pdGVyYXRvcl0oKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTbWFsbGVzdE48VCA9IHZvaWQ+IHtcbiAgICBwcm90ZWN0ZWQgX2hlYXAgPSBuZXcgTWF4SGVhcCgpO1xuICAgIHByb3RlY3RlZCBfbWFwOiBbbnVtYmVyLCBUXVtdID0gW107XG5cbiAgICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgX3NpemU6IG51bWJlcikge31cblxuICAgIHVwZGF0ZShrZXk6IG51bWJlciwgdmFsdWU6IFQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2hlYXAuc2l6ZSA8IHRoaXMuX3NpemUpIHtcbiAgICAgICAgICAgIHRoaXMuX2hlYXAuaW5zZXJ0KGtleSk7XG4gICAgICAgICAgICB0aGlzLl9tYXAucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChrZXkgPj0gdGhpcy5faGVhcC5wZWVrTWF4KCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9oZWFwLmluc2VydChrZXkpO1xuICAgICAgICB0aGlzLl9tYXAucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgICB0aGlzLnNocmluaygpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBzaHJpbmsoKSB7XG4gICAgICAgIGNvbnN0IG1heCA9IHRoaXMuX2hlYXAuZXh0cmFjdE1heCgpO1xuICAgICAgICBsZXQgaWR4ID0gdGhpcy5fbWFwLmxlbmd0aDtcbiAgICAgICAgd2hpbGUgKC0taWR4ID49IDApIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9tYXBbaWR4XVswXSA9PT0gbWF4KSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlkeCA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU21hbGxlc3ROOiBjb3VsZCBub3QgZmluZCBlbnRyeSBmb3Iga2V5ICR7bWF4fWApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX21hcC5zcGxpY2UoaWR4LCAxKTtcbiAgICB9XG5cbiAgICBbU3ltYm9sLml0ZXJhdG9yXSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcFtTeW1ib2wuaXRlcmF0b3JdKCk7XG4gICAgfVxuXG4gICAgZW50cmllcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcFtTeW1ib2wuaXRlcmF0b3JdO1xuICAgIH1cblxuICAgIGtleXMoKSB7XG4gICAgICAgIHJldHVybiBbLi4udGhpcy5faGVhcF07XG4gICAgfVxuXG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zaXplO1xuICAgIH1cblxuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLl9oZWFwLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuX21hcCA9IFtdO1xuICAgIH1cblxuICAgIHNldFNpemUobmV3U2l6ZTogbnVtYmVyKSB7XG4gICAgICAgIHdoaWxlICh0aGlzLl9zaXplID4gbmV3U2l6ZSkge1xuICAgICAgICAgICAgdGhpcy5zaHJpbmsoKTtcbiAgICAgICAgICAgIHRoaXMuX3NpemUtLTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zaXplID0gbmV3U2l6ZTtcbiAgICB9XG59XG4iXX0= |
\ | No newline at end of file |