@stemy/backend 5.2.2 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands/clear-command.d.ts +6 -6
- package/commands/fixtures-command.d.ts +9 -9
- package/commands/index.d.ts +2 -2
- package/common-types.d.ts +325 -326
- package/esm2022/commands/clear-command.mjs +15 -0
- package/esm2022/commands/fixtures-command.mjs +26 -0
- package/esm2022/commands/index.mjs +7 -0
- package/esm2022/common-types.mjs +26 -0
- package/esm2022/fixtures/index.mjs +5 -0
- package/esm2022/fixtures/ttl.fixture.mjs +23 -0
- package/esm2022/public_api.mjs +378 -0
- package/esm2022/requests/asset-image-params.mjs +60 -0
- package/esm2022/rest-controllers/assets.controller.mjs +177 -0
- package/esm2022/rest-controllers/auth.controller.mjs +57 -0
- package/esm2022/rest-controllers/gallery.controller.mjs +27 -0
- package/esm2022/rest-controllers/progresses.controller.mjs +38 -0
- package/esm2022/rest-controllers/terminal-styles.mjs +67 -0
- package/esm2022/rest-controllers/terminal.controller.mjs +132 -0
- package/esm2022/rest-middlewares/container.middleware.mjs +22 -0
- package/esm2022/rest-middlewares/error-handler.middleware.mjs +79 -0
- package/esm2022/rest-middlewares/language.middleware.mjs +21 -0
- package/esm2022/rest-middlewares/request-ended.middleware.mjs +26 -0
- package/esm2022/rest-middlewares/request-started.middleware.mjs +25 -0
- package/esm2022/services/asset-processor.mjs +88 -0
- package/esm2022/services/asset-resolver.mjs +36 -0
- package/esm2022/services/assets.mjs +154 -0
- package/esm2022/services/backend-provider.mjs +83 -0
- package/esm2022/services/cache-processor.mjs +16 -0
- package/esm2022/services/cache.mjs +70 -0
- package/esm2022/services/configuration.mjs +68 -0
- package/esm2022/services/drivers/asset-grid.driver.mjs +27 -0
- package/esm2022/services/drivers/asset-local.driver.mjs +41 -0
- package/esm2022/services/endpoint-provider.mjs +13 -0
- package/esm2022/services/entities/asset.mjs +61 -0
- package/esm2022/services/entities/base-entity.mjs +32 -0
- package/esm2022/services/entities/lazy-asset.mjs +87 -0
- package/esm2022/services/entities/progress.mjs +182 -0
- package/esm2022/services/entities/temp-asset.mjs +53 -0
- package/esm2022/services/fixtures.mjs +38 -0
- package/esm2022/services/gallery-cache.mjs +29 -0
- package/esm2022/services/gallery-image.mjs +42 -0
- package/esm2022/services/gallery.mjs +124 -0
- package/esm2022/services/id-generator.mjs +49 -0
- package/esm2022/services/job-manager.mjs +198 -0
- package/esm2022/services/lazy-assets.mjs +68 -0
- package/esm2022/services/logger.mjs +26 -0
- package/esm2022/services/mail-sender.mjs +42 -0
- package/esm2022/services/memory-cache.mjs +61 -0
- package/esm2022/services/mongo-connector.mjs +36 -0
- package/esm2022/services/open-api.mjs +123 -0
- package/esm2022/services/progresses.mjs +93 -0
- package/esm2022/services/template-renderer.mjs +71 -0
- package/esm2022/services/terminal-manager.mjs +88 -0
- package/esm2022/services/token-generator.mjs +37 -0
- package/esm2022/services/translation-provider.mjs +39 -0
- package/esm2022/services/translator.mjs +67 -0
- package/esm2022/services/user-manager.mjs +27 -0
- package/esm2022/socket-controllers/progress.controller.mjs +63 -0
- package/esm2022/socket-controllers/terminal.controller.mjs +61 -0
- package/esm2022/socket-controllers/terminal.mjs +89 -0
- package/esm2022/socket-middlewares/compression.middleware.mjs +14 -0
- package/esm2022/static.mjs +23 -0
- package/esm2022/stemy-backend.mjs +5 -0
- package/esm2022/utilities/base-doc.mjs +33 -0
- package/esm2022/utilities/decorators.mjs +51 -0
- package/esm2022/utilities/di-container.mjs +88 -0
- package/esm2022/utilities/empty-job.mjs +13 -0
- package/esm2022/utilities/lazy-asset-generator.mjs +38 -0
- package/esm2022/utilities/mongoose.mjs +216 -0
- package/esm2022/utilities/tree.mjs +119 -0
- package/esm2022/utils.mjs +728 -0
- package/esm2022/validators.mjs +46 -0
- package/fesm2022/stemy-backend.mjs +4689 -0
- package/fesm2022/stemy-backend.mjs.map +1 -0
- package/fixtures/index.d.ts +2 -2
- package/fixtures/ttl.fixture.d.ts +7 -7
- package/index.d.ts +5 -5
- package/package.json +42 -48
- package/public_api.d.ts +44 -44
- package/requests/asset-image-params.d.ts +12 -12
- package/rest-controllers/assets.controller.d.ts +25 -27
- package/rest-controllers/auth.controller.d.ts +14 -14
- package/rest-controllers/gallery.controller.d.ts +6 -7
- package/rest-controllers/progresses.controller.d.ts +9 -9
- package/rest-controllers/terminal-styles.d.ts +2 -2
- package/rest-controllers/terminal.controller.d.ts +10 -10
- package/rest-middlewares/container.middleware.d.ts +8 -8
- package/rest-middlewares/error-handler.middleware.d.ts +13 -13
- package/rest-middlewares/language.middleware.d.ts +8 -8
- package/rest-middlewares/request-ended.middleware.d.ts +8 -8
- package/rest-middlewares/request-started.middleware.d.ts +8 -8
- package/services/asset-processor.d.ts +10 -11
- package/services/asset-resolver.d.ts +10 -10
- package/services/assets.d.ts +24 -26
- package/services/backend-provider.d.ts +19 -20
- package/services/cache-processor.d.ts +4 -4
- package/services/cache.d.ts +23 -23
- package/services/configuration.d.ts +15 -15
- package/services/drivers/asset-grid.driver.d.ts +11 -11
- package/services/drivers/asset-local.driver.d.ts +10 -11
- package/services/endpoint-provider.d.ts +4 -4
- package/services/entities/asset.d.ts +19 -21
- package/services/entities/base-entity.d.ts +13 -13
- package/services/entities/lazy-asset.d.ts +25 -25
- package/services/entities/progress.d.ts +49 -49
- package/services/entities/temp-asset.d.ts +20 -22
- package/services/fixtures.d.ts +8 -8
- package/services/gallery-cache.d.ts +8 -9
- package/services/gallery-image.d.ts +10 -11
- package/services/gallery.d.ts +13 -13
- package/services/id-generator.d.ts +11 -11
- package/services/job-manager.d.ts +35 -35
- package/services/lazy-assets.d.ts +22 -22
- package/services/logger.d.ts +8 -8
- package/services/mail-sender.d.ts +20 -20
- package/services/memory-cache.d.ts +10 -10
- package/services/mongo-connector.d.ts +12 -12
- package/services/open-api.d.ts +13 -13
- package/services/progresses.d.ts +20 -20
- package/services/template-renderer.d.ts +14 -14
- package/services/terminal-manager.d.ts +15 -15
- package/services/token-generator.d.ts +6 -6
- package/services/translation-provider.d.ts +9 -9
- package/services/translator.d.ts +15 -15
- package/services/user-manager.d.ts +6 -6
- package/socket-controllers/progress.controller.d.ts +10 -10
- package/socket-controllers/terminal.controller.d.ts +13 -13
- package/socket-controllers/terminal.d.ts +19 -20
- package/socket-middlewares/compression.middleware.d.ts +4 -4
- package/static.d.ts +2 -2
- package/utilities/base-doc.d.ts +40 -40
- package/utilities/decorators.d.ts +10 -10
- package/utilities/di-container.d.ts +43 -43
- package/utilities/empty-job.d.ts +4 -4
- package/utilities/lazy-asset-generator.d.ts +15 -15
- package/utilities/mongoose.d.ts +36 -36
- package/utilities/tree.d.ts +15 -15
- package/utils.d.ts +118 -123
- package/validators.d.ts +7 -7
|
@@ -0,0 +1,728 @@
|
|
|
1
|
+
import { mkdir, readFile as fsReadFile, unlink, writeFile as fsWriteFile } from "fs";
|
|
2
|
+
import { gzip, gunzip } from "zlib";
|
|
3
|
+
import { basename, dirname } from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import { exec as execChildProcess } from "child_process";
|
|
6
|
+
import { createHash } from "crypto";
|
|
7
|
+
import { from, Observable, Subject, Subscription } from "rxjs";
|
|
8
|
+
import { ObjectId } from "mongodb";
|
|
9
|
+
import mongoose from "mongoose";
|
|
10
|
+
import { PassThrough, Readable } from "stream";
|
|
11
|
+
import sharp_ from "sharp";
|
|
12
|
+
import { HttpError } from "routing-controllers";
|
|
13
|
+
import axios from "axios";
|
|
14
|
+
import fileType from "file-type/core";
|
|
15
|
+
const sharp = sharp_;
|
|
16
|
+
export const diContainers = {
|
|
17
|
+
appContainer: null
|
|
18
|
+
};
|
|
19
|
+
export function isNullOrUndefined(value) {
|
|
20
|
+
return value == null || typeof value == "undefined";
|
|
21
|
+
}
|
|
22
|
+
export function isDefined(value) {
|
|
23
|
+
return !isNullOrUndefined(value);
|
|
24
|
+
}
|
|
25
|
+
export function getType(obj) {
|
|
26
|
+
const regex = new RegExp("\\s([a-zA-Z]+)");
|
|
27
|
+
return Object.prototype.toString.call(obj).match(regex)[1].toLowerCase();
|
|
28
|
+
}
|
|
29
|
+
export function isObject(value) {
|
|
30
|
+
return getType(value) == "object";
|
|
31
|
+
}
|
|
32
|
+
export function isArray(value) {
|
|
33
|
+
return Array.isArray(value);
|
|
34
|
+
}
|
|
35
|
+
export function isBuffer(value) {
|
|
36
|
+
return value instanceof Buffer;
|
|
37
|
+
}
|
|
38
|
+
export function isBoolean(value) {
|
|
39
|
+
return typeof value === "boolean";
|
|
40
|
+
}
|
|
41
|
+
export function isDate(value) {
|
|
42
|
+
return !!value && value[Symbol.toPrimitive] && !isNaN(value) && "undefined" !== typeof value.getDate;
|
|
43
|
+
}
|
|
44
|
+
export function isPrimitive(value) {
|
|
45
|
+
const type = typeof value;
|
|
46
|
+
return value == null || (type !== "object" && type !== "function");
|
|
47
|
+
}
|
|
48
|
+
export function isString(value) {
|
|
49
|
+
return typeof value === "string";
|
|
50
|
+
}
|
|
51
|
+
export function isFunction(value) {
|
|
52
|
+
return typeof value === "function";
|
|
53
|
+
}
|
|
54
|
+
export function isConstructor(value) {
|
|
55
|
+
return (value && typeof value === "function" && value.prototype && value.prototype.constructor) === value && value.name !== "Object";
|
|
56
|
+
}
|
|
57
|
+
export function isType(value) {
|
|
58
|
+
return isConstructor(value);
|
|
59
|
+
}
|
|
60
|
+
export function isInterface(obj, interFaceObject) {
|
|
61
|
+
if (!obj || typeof obj !== "object" || isArray(obj) || !isObject(interFaceObject))
|
|
62
|
+
return false;
|
|
63
|
+
const keys = Object.keys(interFaceObject);
|
|
64
|
+
for (const key of keys) {
|
|
65
|
+
let type = interFaceObject[key] || "";
|
|
66
|
+
if (type.startsWith("*")) {
|
|
67
|
+
type = type.substr(1);
|
|
68
|
+
if (obj.hasOwnProperty(key) && getType(obj[key]) !== type)
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
else if (!obj.hasOwnProperty(key) || getType(obj[key]) !== type) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
export function ucFirst(value) {
|
|
78
|
+
if (!value)
|
|
79
|
+
return "";
|
|
80
|
+
return value[0].toUpperCase() + value.substr(1);
|
|
81
|
+
}
|
|
82
|
+
export function lcFirst(value) {
|
|
83
|
+
if (!value)
|
|
84
|
+
return "";
|
|
85
|
+
return value[0].toLowerCase() + value.substr(1);
|
|
86
|
+
}
|
|
87
|
+
export function isObjectId(id) {
|
|
88
|
+
return typeof id === "string" && id.length == 24 && !isNaN(Number("0x" + id));
|
|
89
|
+
}
|
|
90
|
+
export function firstItem(value) {
|
|
91
|
+
return value[0];
|
|
92
|
+
}
|
|
93
|
+
export function lastItem(value) {
|
|
94
|
+
return value[value.length - 1];
|
|
95
|
+
}
|
|
96
|
+
export function regroup(value, comparator) {
|
|
97
|
+
const result = [];
|
|
98
|
+
if (!isArray(value) || value.length == 0)
|
|
99
|
+
return result;
|
|
100
|
+
value = Array.from(value);
|
|
101
|
+
result.push([value.shift()]);
|
|
102
|
+
value.forEach(item => {
|
|
103
|
+
const group = result.find(g => g.some(a => comparator(a, item)));
|
|
104
|
+
if (group) {
|
|
105
|
+
group.push(item);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
result.push([item]);
|
|
109
|
+
});
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
export function uniqueItems(value) {
|
|
113
|
+
return value.filter((v, ix) => value.indexOf(v) === ix);
|
|
114
|
+
}
|
|
115
|
+
export function getValue(obj, key, defaultValue, treeFallback = false) {
|
|
116
|
+
key = key || "";
|
|
117
|
+
const keys = key.split(".");
|
|
118
|
+
let curKey = "";
|
|
119
|
+
do {
|
|
120
|
+
curKey += keys.shift();
|
|
121
|
+
if (isDefined(obj) && isDefined(obj[curKey]) && (typeof obj[curKey] === "object" || !keys.length)) {
|
|
122
|
+
obj = obj[curKey];
|
|
123
|
+
curKey = "";
|
|
124
|
+
}
|
|
125
|
+
else if (!keys.length) {
|
|
126
|
+
defaultValue = typeof defaultValue == "undefined" ? key.replace(new RegExp(`${curKey}$`), `{${curKey}}`) : defaultValue;
|
|
127
|
+
obj = treeFallback ? obj || defaultValue : defaultValue;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
curKey += ".";
|
|
131
|
+
}
|
|
132
|
+
} while (keys.length);
|
|
133
|
+
return obj;
|
|
134
|
+
}
|
|
135
|
+
export function groupBy(items, cb) {
|
|
136
|
+
return items.reduce((res, item) => {
|
|
137
|
+
const group = cb(item);
|
|
138
|
+
res[group] = res[group] || [];
|
|
139
|
+
res[group].push(item);
|
|
140
|
+
return res;
|
|
141
|
+
}, {});
|
|
142
|
+
}
|
|
143
|
+
export function convertValue(value, type) {
|
|
144
|
+
switch (type) {
|
|
145
|
+
case "boolean":
|
|
146
|
+
value = typeof value == "string" ? value.toLowerCase() : value;
|
|
147
|
+
return (value == "no" || value == "false" || value == "0") ? false : !!value;
|
|
148
|
+
case "number":
|
|
149
|
+
const val = parseFloat(value);
|
|
150
|
+
return isNaN(val) ? 0 : val;
|
|
151
|
+
case "array":
|
|
152
|
+
try {
|
|
153
|
+
return JSON.parse(value);
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
return `${value}`.split(", ");
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return value;
|
|
160
|
+
}
|
|
161
|
+
const cropInterface = {
|
|
162
|
+
x: "number",
|
|
163
|
+
y: "number",
|
|
164
|
+
w: "number",
|
|
165
|
+
h: "number"
|
|
166
|
+
};
|
|
167
|
+
function toCropRegion(cropInfo) {
|
|
168
|
+
let crop = cropInfo;
|
|
169
|
+
if (isString(cropInfo)) {
|
|
170
|
+
try {
|
|
171
|
+
crop = JSON.parse(cropInfo);
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (!isInterface(crop, cropInterface))
|
|
178
|
+
return null;
|
|
179
|
+
return {
|
|
180
|
+
width: Math.round(crop.w),
|
|
181
|
+
height: Math.round(crop.h),
|
|
182
|
+
top: Math.round(crop.y),
|
|
183
|
+
left: Math.round(crop.x)
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
export async function toImage(src, params, meta) {
|
|
187
|
+
// Default params and meta
|
|
188
|
+
params = params || {};
|
|
189
|
+
meta = meta || {};
|
|
190
|
+
// Get default crop info
|
|
191
|
+
const crop = toCropRegion(meta.crop);
|
|
192
|
+
// Return the src if there are no params and no default crop exists
|
|
193
|
+
if (meta.extension === "svg" || (Object.keys(params).length == 0 && !crop)) {
|
|
194
|
+
return src;
|
|
195
|
+
}
|
|
196
|
+
// Parse params
|
|
197
|
+
params.rotation = isNaN(params.rotation) ? 0 : Math.round(params.rotation / 90) * 90;
|
|
198
|
+
params.canvasScaleX = isNaN(params.canvasScaleX) ? 1 : Number(params.canvasScaleX);
|
|
199
|
+
params.canvasScaleY = isNaN(params.canvasScaleY) ? 1 : Number(params.canvasScaleY);
|
|
200
|
+
params.scaleX = isNaN(params.scaleX) ? 1 : Number(params.scaleX);
|
|
201
|
+
params.scaleY = isNaN(params.scaleY) ? 1 : Number(params.scaleY);
|
|
202
|
+
params.crop = isBoolean(params.crop) ? params.crop : params.crop == "true";
|
|
203
|
+
let buffer = src instanceof Readable ? await streamToBuffer(src) : src;
|
|
204
|
+
try {
|
|
205
|
+
// Get crop info
|
|
206
|
+
const cropBefore = toCropRegion(params.cropBefore || (params.crop ? meta.cropBefore : null));
|
|
207
|
+
const cropAfter = toCropRegion(params.cropAfter || (params.crop ? meta.cropAfter : null));
|
|
208
|
+
// Get metadata
|
|
209
|
+
let img = sharp(buffer);
|
|
210
|
+
let { width, height } = await img.metadata();
|
|
211
|
+
// Crop before resize
|
|
212
|
+
if (cropBefore) {
|
|
213
|
+
width = cropBefore.width;
|
|
214
|
+
height = cropBefore.height;
|
|
215
|
+
img = img.extract(cropBefore);
|
|
216
|
+
}
|
|
217
|
+
else if (crop) {
|
|
218
|
+
width = crop.width;
|
|
219
|
+
height = crop.height;
|
|
220
|
+
img = img.extract(crop);
|
|
221
|
+
}
|
|
222
|
+
// Resize canvas
|
|
223
|
+
const canvasScaleX = meta?.canvasScaleX || 1;
|
|
224
|
+
const canvasScaleY = meta?.canvasScaleY || 1;
|
|
225
|
+
if (params.canvasScaleX !== canvasScaleX || params.canvasScaleY !== canvasScaleY) {
|
|
226
|
+
width = Math.round(width * params.canvasScaleX);
|
|
227
|
+
height = Math.round(height * params.canvasScaleY);
|
|
228
|
+
img = img.resize({ width, height, background: "#00000000", fit: "contain" });
|
|
229
|
+
}
|
|
230
|
+
// Resize image
|
|
231
|
+
if (params.scaleX !== 1 || params.scaleY !== 1) {
|
|
232
|
+
width = Math.round(width * params.scaleX);
|
|
233
|
+
height = Math.round(height * params.scaleY);
|
|
234
|
+
img = img.resize({ width, height, background: "#00000000", fit: "fill" });
|
|
235
|
+
}
|
|
236
|
+
// Crop after resize
|
|
237
|
+
if (cropAfter) {
|
|
238
|
+
img = img.extract(cropAfter);
|
|
239
|
+
}
|
|
240
|
+
// Rotate
|
|
241
|
+
if (params.rotation !== 0) {
|
|
242
|
+
buffer = await img.toBuffer();
|
|
243
|
+
img = sharp(buffer).rotate(params.rotation);
|
|
244
|
+
}
|
|
245
|
+
buffer = await img.toBuffer();
|
|
246
|
+
src = src instanceof Readable ? bufferToStream(buffer) : buffer;
|
|
247
|
+
return src;
|
|
248
|
+
}
|
|
249
|
+
catch (e) {
|
|
250
|
+
console.log("Image conversion error", e);
|
|
251
|
+
src = src instanceof Readable ? bufferToStream(buffer) : buffer;
|
|
252
|
+
return src;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
export function bufferToStream(buffer) {
|
|
256
|
+
const readStream = new PassThrough();
|
|
257
|
+
readStream.end(buffer);
|
|
258
|
+
return readStream;
|
|
259
|
+
}
|
|
260
|
+
export function streamToBuffer(stream) {
|
|
261
|
+
return new Promise((resolve, reject) => {
|
|
262
|
+
const concat = [];
|
|
263
|
+
stream.on("data", data => {
|
|
264
|
+
concat.push(data);
|
|
265
|
+
});
|
|
266
|
+
stream.on("error", reject);
|
|
267
|
+
stream.on("end", () => resolve(Buffer.concat(concat)));
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
class ReadableStreamClone extends Readable {
|
|
271
|
+
constructor(readableStream, opts) {
|
|
272
|
+
super(opts);
|
|
273
|
+
readableStream?.on("data", chunk => {
|
|
274
|
+
this.push(chunk);
|
|
275
|
+
});
|
|
276
|
+
readableStream?.on("end", () => {
|
|
277
|
+
this.push(null);
|
|
278
|
+
});
|
|
279
|
+
readableStream?.on("error", err => {
|
|
280
|
+
this.emit("error", err);
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
_read(size) {
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
export function copyStream(stream, opts) {
|
|
287
|
+
return new ReadableStreamClone(stream, opts);
|
|
288
|
+
}
|
|
289
|
+
export function mkdirRecursive(path, mode = null) {
|
|
290
|
+
return new Promise((resolve, reject) => {
|
|
291
|
+
mkdir(path, { mode: mode || 0o777, recursive: true }, err => {
|
|
292
|
+
if (err) {
|
|
293
|
+
reject(err);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
resolve();
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
export function deleteFile(path) {
|
|
301
|
+
return new Promise((resolve, reject) => {
|
|
302
|
+
unlink(path, err => {
|
|
303
|
+
if (err) {
|
|
304
|
+
reject(err);
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
resolve();
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
export function readFile(path) {
|
|
312
|
+
return new Promise((res, rej) => {
|
|
313
|
+
fsReadFile(path, (err, data) => {
|
|
314
|
+
if (err) {
|
|
315
|
+
rej(err);
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
res(data);
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
export async function readAndDeleteFile(path, timeout = 5000) {
|
|
323
|
+
const data = await readFile(path);
|
|
324
|
+
setTimeout(() => {
|
|
325
|
+
unlink(path, () => {
|
|
326
|
+
});
|
|
327
|
+
}, timeout);
|
|
328
|
+
return data;
|
|
329
|
+
}
|
|
330
|
+
export async function writeFile(path, data) {
|
|
331
|
+
await mkdirRecursive(dirname(path));
|
|
332
|
+
return new Promise((res, rej) => {
|
|
333
|
+
fsWriteFile(path, data, err => {
|
|
334
|
+
if (err) {
|
|
335
|
+
rej(err);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
res(data);
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
export function valueToPromise(value) {
|
|
343
|
+
return value instanceof Promise ? value : Promise.resolve(value);
|
|
344
|
+
}
|
|
345
|
+
export function promiseTimeout(timeout = 1000, error = false) {
|
|
346
|
+
return new Promise((resolve, reject) => {
|
|
347
|
+
setTimeout(() => {
|
|
348
|
+
if (error) {
|
|
349
|
+
reject(`Timeout exceeded: ${timeout}ms`);
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
resolve(`Timeout: ${timeout}ms`);
|
|
353
|
+
}, timeout);
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
export function getConstructorName(type) {
|
|
357
|
+
return type.prototype.constructor.name;
|
|
358
|
+
}
|
|
359
|
+
export function getFunctionParams(func) {
|
|
360
|
+
// Remove comments of the form /* ... */
|
|
361
|
+
// Removing comments of the form //
|
|
362
|
+
// Remove body of the function { ... }
|
|
363
|
+
// removing "=>" if func is arrow function
|
|
364
|
+
const str = func.toString()
|
|
365
|
+
.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
366
|
+
.replace(/\/\/(.)*/g, "")
|
|
367
|
+
.replace(/{[\s\S]*}/, "")
|
|
368
|
+
.replace(/=>/g, "")
|
|
369
|
+
.trim();
|
|
370
|
+
// Start parameter names after first "("
|
|
371
|
+
const start = str.indexOf("(") + 1;
|
|
372
|
+
// End parameter names is just before last ")"
|
|
373
|
+
const end = str.length - 1;
|
|
374
|
+
const result = str.substring(start, end).split(", ");
|
|
375
|
+
const params = [];
|
|
376
|
+
result.forEach(element => {
|
|
377
|
+
// Removing any default value
|
|
378
|
+
element = element.replace(/=[\s\S]*/g, "").trim();
|
|
379
|
+
if (element.length > 0)
|
|
380
|
+
params.push(element);
|
|
381
|
+
});
|
|
382
|
+
return params;
|
|
383
|
+
}
|
|
384
|
+
export function getFileName(path, withExtension = false) {
|
|
385
|
+
const name = basename(path || "");
|
|
386
|
+
return withExtension ? name : name.split(".").slice(0, -1).join(".");
|
|
387
|
+
}
|
|
388
|
+
export function getExtension(path) {
|
|
389
|
+
const name = basename(path || "");
|
|
390
|
+
return name.split(".").pop();
|
|
391
|
+
}
|
|
392
|
+
export function createIdString() {
|
|
393
|
+
return new ObjectId().toHexString();
|
|
394
|
+
}
|
|
395
|
+
export function idToString(value) {
|
|
396
|
+
if (Array.isArray(value)) {
|
|
397
|
+
return value.map(idToString);
|
|
398
|
+
}
|
|
399
|
+
return value instanceof ObjectId || value instanceof mongoose.Types.ObjectId
|
|
400
|
+
? value.toHexString()
|
|
401
|
+
: (isString(value) ? value : value || null);
|
|
402
|
+
}
|
|
403
|
+
export function createTransformer(transform) {
|
|
404
|
+
return (doc, ret, options) => {
|
|
405
|
+
ret.id = idToString(ret.id) || ret.id;
|
|
406
|
+
if (doc._id) {
|
|
407
|
+
ret._id = idToString(doc._id);
|
|
408
|
+
ret.id = ret.id || ret._id;
|
|
409
|
+
}
|
|
410
|
+
delete ret.__v;
|
|
411
|
+
return isFunction(transform) ? transform(doc, ret, options) || ret : ret;
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
export function broadcast(socketServer, cb) {
|
|
415
|
+
socketServer.sockets.sockets.forEach((client) => {
|
|
416
|
+
cb(client);
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
export function rand(min, max) {
|
|
420
|
+
return Math.round(random(min, max));
|
|
421
|
+
}
|
|
422
|
+
export function random(min, max) {
|
|
423
|
+
return min + Math.random() * (max - min);
|
|
424
|
+
}
|
|
425
|
+
export function multiSubscription(...subscriptions) {
|
|
426
|
+
return new Subscription(() => {
|
|
427
|
+
subscriptions.forEach(s => {
|
|
428
|
+
s.unsubscribe();
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
export function observableFromFunction(callbackFunc) {
|
|
433
|
+
let subject;
|
|
434
|
+
return new Observable((subscriber) => {
|
|
435
|
+
if (!subject) {
|
|
436
|
+
subject = new Subject();
|
|
437
|
+
try {
|
|
438
|
+
subject = from(callbackFunc());
|
|
439
|
+
}
|
|
440
|
+
catch (err) {
|
|
441
|
+
subject.error(err);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return subject.subscribe(subscriber);
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
export function padLeft(value, count = 3, padWith = "0") {
|
|
448
|
+
return `${value}`.padStart(count, padWith);
|
|
449
|
+
}
|
|
450
|
+
export function padRight(value, count = 3, padWith = "0") {
|
|
451
|
+
return `${value}`.padEnd(count, padWith);
|
|
452
|
+
}
|
|
453
|
+
export function camelCaseToDash(str) {
|
|
454
|
+
return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
455
|
+
}
|
|
456
|
+
export function gzipPromised(data, opts) {
|
|
457
|
+
return new Promise((resolve, reject) => {
|
|
458
|
+
gzip(data, opts, (err, result) => {
|
|
459
|
+
if (err) {
|
|
460
|
+
reject(err);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
resolve(result.toString("base64"));
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
export function gunzipPromised(data, opts) {
|
|
468
|
+
return new Promise((resolve, reject) => {
|
|
469
|
+
gunzip(Buffer.from(data, "base64"), opts, (err, result) => {
|
|
470
|
+
if (err) {
|
|
471
|
+
reject(err);
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
resolve(result.toString("utf8"));
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
export function deleteFromBucket(bucket, id) {
|
|
479
|
+
const fileId = id instanceof ObjectId ? id : new ObjectId(id);
|
|
480
|
+
return new Promise(((resolve, reject) => {
|
|
481
|
+
if (!id) {
|
|
482
|
+
// We don't care about empty id
|
|
483
|
+
resolve(null);
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
bucket.delete(fileId, error => {
|
|
487
|
+
let err = error;
|
|
488
|
+
if (error) {
|
|
489
|
+
err = error.message || error || "";
|
|
490
|
+
if (!isString(err) || !err.startsWith("FileNotFound")) {
|
|
491
|
+
reject(err);
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
resolve(fileId.toHexString());
|
|
496
|
+
});
|
|
497
|
+
}));
|
|
498
|
+
}
|
|
499
|
+
const defaultPredicate = () => true;
|
|
500
|
+
function copyRecursive(target, source, predicate, copies) {
|
|
501
|
+
if (isPrimitive(source) || isDate(source) || isFunction(source))
|
|
502
|
+
return source;
|
|
503
|
+
if (copies.has(source))
|
|
504
|
+
return copies.get(source);
|
|
505
|
+
if (isArray(source)) {
|
|
506
|
+
target = isArray(target) ? Array.from(target) : [];
|
|
507
|
+
source.forEach((item, index) => {
|
|
508
|
+
if (!predicate(item, index, target, source))
|
|
509
|
+
return;
|
|
510
|
+
if (target.length > index)
|
|
511
|
+
target[index] = copyRecursive(target[index], item, predicate, copies);
|
|
512
|
+
else
|
|
513
|
+
target.push(copyRecursive(null, item, predicate, copies));
|
|
514
|
+
});
|
|
515
|
+
copies.set(source, target);
|
|
516
|
+
return target;
|
|
517
|
+
}
|
|
518
|
+
if (isBuffer(source))
|
|
519
|
+
return Buffer.from(source);
|
|
520
|
+
// If object defines __shouldCopy as false, then don't copy it
|
|
521
|
+
if (source.__shouldCopy === false)
|
|
522
|
+
return source;
|
|
523
|
+
// Copy object
|
|
524
|
+
const shouldCopy = isFunction(source.__shouldCopy) ? source.__shouldCopy : () => true;
|
|
525
|
+
if (isConstructor(source.constructor)) {
|
|
526
|
+
if (!target) {
|
|
527
|
+
try {
|
|
528
|
+
target = new source.constructor();
|
|
529
|
+
}
|
|
530
|
+
catch (e) {
|
|
531
|
+
const proto = source.constructor.prototype || source.prototype;
|
|
532
|
+
target = Object.create(proto);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
target = Object.assign({}, target || {});
|
|
538
|
+
}
|
|
539
|
+
// Set to copies to prevent circular references
|
|
540
|
+
copies.set(source, target);
|
|
541
|
+
// Copy map entries
|
|
542
|
+
if (target instanceof Map) {
|
|
543
|
+
if (source instanceof Map) {
|
|
544
|
+
for (let [key, value] of source.entries()) {
|
|
545
|
+
if (!predicate(value, key, target, source))
|
|
546
|
+
continue;
|
|
547
|
+
target.set(key, !shouldCopy(key, value) ? value : copyRecursive(target.get(key), value, predicate, copies));
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return target;
|
|
551
|
+
}
|
|
552
|
+
// Copy object members
|
|
553
|
+
let keys = Object.keys(source);
|
|
554
|
+
keys.forEach(key => {
|
|
555
|
+
if (!predicate(source[key], key, target, source))
|
|
556
|
+
return;
|
|
557
|
+
target[key] = !shouldCopy(key, source[key]) ? source[key] : copyRecursive(target[key], source[key], predicate, copies);
|
|
558
|
+
}, target);
|
|
559
|
+
// Copy object properties
|
|
560
|
+
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
561
|
+
keys = Object.keys(descriptors).filter(k => keys.indexOf(k) < 0);
|
|
562
|
+
keys.forEach(key => {
|
|
563
|
+
Object.defineProperty(target, key, descriptors[key]);
|
|
564
|
+
});
|
|
565
|
+
return target;
|
|
566
|
+
}
|
|
567
|
+
export function filter(obj, predicate) {
|
|
568
|
+
return copyRecursive(null, obj, predicate || defaultPredicate, new Map());
|
|
569
|
+
}
|
|
570
|
+
export function copy(obj) {
|
|
571
|
+
return copyRecursive(null, obj, defaultPredicate, new Map());
|
|
572
|
+
}
|
|
573
|
+
export function assign(target, source, predicate) {
|
|
574
|
+
return copyRecursive(target, source, predicate, new Map());
|
|
575
|
+
}
|
|
576
|
+
export function md5(data) {
|
|
577
|
+
if (isObject(data)) {
|
|
578
|
+
data = JSON.stringify(data);
|
|
579
|
+
}
|
|
580
|
+
if (!isString(data)) {
|
|
581
|
+
throw `Can't md5 other that raw object or string`;
|
|
582
|
+
}
|
|
583
|
+
return createHash("md5").update(data).digest("hex");
|
|
584
|
+
}
|
|
585
|
+
export function runCommand(scriptPath, expectedCode = 0) {
|
|
586
|
+
return new Promise((resolve, reject) => {
|
|
587
|
+
const cp = execChildProcess(scriptPath, (error, stdout) => {
|
|
588
|
+
if (error && expectedCode !== error.code) {
|
|
589
|
+
console.log(error);
|
|
590
|
+
reject(error);
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
const lines = (stdout || "").split("\n");
|
|
594
|
+
let line = null;
|
|
595
|
+
while (!line && lines.length > 0) {
|
|
596
|
+
line = lines.pop();
|
|
597
|
+
}
|
|
598
|
+
resolve(line);
|
|
599
|
+
});
|
|
600
|
+
cp.stdout.on("data", function (data) {
|
|
601
|
+
console.log(data.toString());
|
|
602
|
+
});
|
|
603
|
+
cp.stderr.on("data", function (data) {
|
|
604
|
+
console.error(data.toString());
|
|
605
|
+
});
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
export var ConsoleColor;
|
|
609
|
+
(function (ConsoleColor) {
|
|
610
|
+
ConsoleColor["Reset"] = "\u001B[0m";
|
|
611
|
+
ConsoleColor["Bright"] = "\u001B[1m";
|
|
612
|
+
ConsoleColor["Dim"] = "\u001B[2m";
|
|
613
|
+
ConsoleColor["Underscore"] = "\u001B[4m";
|
|
614
|
+
ConsoleColor["Blink"] = "\u001B[5m";
|
|
615
|
+
ConsoleColor["Reverse"] = "\u001B[7m";
|
|
616
|
+
ConsoleColor["Hidden"] = "\u001B[8m";
|
|
617
|
+
ConsoleColor["FgBlack"] = "\u001B[30m";
|
|
618
|
+
ConsoleColor["FgRed"] = "\u001B[31m";
|
|
619
|
+
ConsoleColor["FgGreen"] = "\u001B[32m";
|
|
620
|
+
ConsoleColor["FgYellow"] = "\u001B[33m";
|
|
621
|
+
ConsoleColor["FgBlue"] = "\u001B[34m";
|
|
622
|
+
ConsoleColor["FgMagenta"] = "\u001B[35m";
|
|
623
|
+
ConsoleColor["FgCyan"] = "\u001B[36m";
|
|
624
|
+
ConsoleColor["FgWhite"] = "\u001B[37m";
|
|
625
|
+
ConsoleColor["FgDefault"] = "\u001B[38m";
|
|
626
|
+
ConsoleColor["BgBlack"] = "\u001B[40m";
|
|
627
|
+
ConsoleColor["BgRed"] = "\u001B[41m";
|
|
628
|
+
ConsoleColor["BgGreen"] = "\u001B[42m";
|
|
629
|
+
ConsoleColor["BgYellow"] = "\u001B[43m";
|
|
630
|
+
ConsoleColor["BgBlue"] = "\u001B[44m";
|
|
631
|
+
ConsoleColor["BgMagenta"] = "\u001B[45m";
|
|
632
|
+
ConsoleColor["BgCyan"] = "\u001B[46m";
|
|
633
|
+
ConsoleColor["BgWhite"] = "\u001B[47m";
|
|
634
|
+
ConsoleColor["BgDefault"] = "\u001B[48m";
|
|
635
|
+
})(ConsoleColor || (ConsoleColor = {}));
|
|
636
|
+
const defaultColors = {
|
|
637
|
+
keyColor: ConsoleColor.FgWhite,
|
|
638
|
+
numberColor: ConsoleColor.FgBlue,
|
|
639
|
+
stringColor: ConsoleColor.FgYellow,
|
|
640
|
+
trueColor: ConsoleColor.FgGreen,
|
|
641
|
+
falseColor: ConsoleColor.FgRed,
|
|
642
|
+
nullColor: ConsoleColor.BgMagenta
|
|
643
|
+
};
|
|
644
|
+
export function colorize(input, color) {
|
|
645
|
+
return `${color}${input}${ConsoleColor.Reset}`;
|
|
646
|
+
}
|
|
647
|
+
export function jsonHighlight(input, colorOptions) {
|
|
648
|
+
const colors = Object.assign({}, defaultColors, colorOptions);
|
|
649
|
+
const json = (isString(input) ? input : JSON.stringify(input, null, 2)).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
650
|
+
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+]?\d+)?)/g, (match) => {
|
|
651
|
+
let color = colors.numberColor;
|
|
652
|
+
if (/^"/.test(match)) {
|
|
653
|
+
if (/:$/.test(match)) {
|
|
654
|
+
color = colors.keyColor;
|
|
655
|
+
}
|
|
656
|
+
else {
|
|
657
|
+
color = colors.stringColor;
|
|
658
|
+
match = '"' + match.substr(1, match.length - 2) + '"';
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
color = /true/.test(match)
|
|
663
|
+
? colors.trueColor
|
|
664
|
+
: /false/.test(match)
|
|
665
|
+
? colors.falseColor
|
|
666
|
+
: /null/.test(match)
|
|
667
|
+
? colors.nullColor
|
|
668
|
+
: color;
|
|
669
|
+
}
|
|
670
|
+
return `${color}${match}${ConsoleColor.Reset}`;
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
export function replaceSpecialChars(str, to = "-") {
|
|
674
|
+
return `${str}`.replace(/[&\/\\#, +()$~%.@'":*?<>{}]/g, to);
|
|
675
|
+
}
|
|
676
|
+
export function regexEscape(str) {
|
|
677
|
+
return `${str}`.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
678
|
+
}
|
|
679
|
+
export function flatten(arr) {
|
|
680
|
+
return arr.reduce((flat, toFlatten) => {
|
|
681
|
+
return flat.concat(isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
|
|
682
|
+
}, []);
|
|
683
|
+
}
|
|
684
|
+
export function wrapError(e, message, httpCode = 500) {
|
|
685
|
+
if (axios.isAxiosError(e)) {
|
|
686
|
+
e.message = message;
|
|
687
|
+
return e;
|
|
688
|
+
}
|
|
689
|
+
return new HttpError(httpCode, `${message}: ${e}`);
|
|
690
|
+
}
|
|
691
|
+
export function getDirName() {
|
|
692
|
+
if (typeof __dirname === "undefined") {
|
|
693
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
694
|
+
return dirname(__filename);
|
|
695
|
+
}
|
|
696
|
+
return __dirname;
|
|
697
|
+
}
|
|
698
|
+
export function prepareUrl(ending = "/") {
|
|
699
|
+
return url => {
|
|
700
|
+
return url ? `${url.replace(/\/+$/, "")}${ending}` : ending;
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
export const prepareUrlSlash = prepareUrl("/");
|
|
704
|
+
export const prepareUrlEmpty = prepareUrl("");
|
|
705
|
+
function checkTextFileType(type) {
|
|
706
|
+
return type.mime.indexOf("text") >= 0 || type.mime.indexOf("xml") >= 0;
|
|
707
|
+
}
|
|
708
|
+
function fixTextFileType(type, buffer) {
|
|
709
|
+
const text = buffer.toString("utf8");
|
|
710
|
+
if (text.indexOf("<svg") >= 0) {
|
|
711
|
+
return { ext: "svg", mime: "image/svg+xml" };
|
|
712
|
+
}
|
|
713
|
+
return type;
|
|
714
|
+
}
|
|
715
|
+
export async function fileTypeFromBuffer(buffer) {
|
|
716
|
+
let type = { ext: "txt", mime: "text/plain" };
|
|
717
|
+
try {
|
|
718
|
+
type = await fileType.fromBuffer(buffer) || { ext: "txt", mime: "text/plain" };
|
|
719
|
+
}
|
|
720
|
+
catch (e) {
|
|
721
|
+
console.error(e);
|
|
722
|
+
}
|
|
723
|
+
if (checkTextFileType(type)) {
|
|
724
|
+
return fixTextFileType(type, buffer);
|
|
725
|
+
}
|
|
726
|
+
return type;
|
|
727
|
+
}
|
|
728
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLEtBQUssRUFBRSxRQUFRLElBQUksVUFBVSxFQUFFLE1BQU0sRUFBRSxTQUFTLElBQUksV0FBVyxFQUFDLE1BQU0sSUFBSSxDQUFDO0FBQ25GLE9BQU8sRUFBQyxJQUFJLEVBQUUsTUFBTSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBQy9DLE9BQU8sRUFBQyxRQUFRLEVBQUUsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ3ZDLE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxLQUFLLENBQUM7QUFDbEMsT0FBTyxFQUFDLElBQUksSUFBSSxnQkFBZ0IsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUN2RCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sUUFBUSxDQUFDO0FBQ2xDLE9BQU8sRUFBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFFN0QsT0FBTyxFQUFlLFFBQVEsRUFBQyxNQUFNLFNBQVMsQ0FBQztBQUUvQyxPQUFPLFFBQVEsTUFBTSxVQUFVLENBQUM7QUFDaEMsT0FBTyxFQUFDLFdBQVcsRUFBRSxRQUFRLEVBQWtCLE1BQU0sUUFBUSxDQUFDO0FBQzlELE9BQU8sTUFBZ0IsTUFBTSxPQUFPLENBQUM7QUFDckMsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMxQixPQUFPLFFBQVEsTUFBTSxnQkFBZ0IsQ0FBQztBQVd0QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUM7QUFNckIsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFrQjtJQUN2QyxZQUFZLEVBQUUsSUFBSTtDQUNyQixDQUFDO0FBSUYsTUFBTSxVQUFVLGlCQUFpQixDQUFDLEtBQVU7SUFDeEMsT0FB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LENBQUM7UUFDNUIsT0FBTyxFQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBQyxDQUFDO0lBQy9DLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSxrQkFBa0IsQ0FBQyxNQUFjO0lBQ25ELElBQUksSUFBSSxHQUFjLEVBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFDLENBQUM7SUFDdkQsSUFBSSxDQUFDO1FBQ0QsSUFBSSxHQUFHLE1BQU0sUUFBUSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBQyxDQUFDO0lBQ2pGLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1QsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBQ0QsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzFCLE9BQU8sZUFBZSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7bWtkaXIsIHJlYWRGaWxlIGFzIGZzUmVhZEZpbGUsIHVubGluaywgd3JpdGVGaWxlIGFzIGZzV3JpdGVGaWxlfSBmcm9tIFwiZnNcIjtcbmltcG9ydCB7Z3ppcCwgZ3VuemlwLCBabGliT3B0aW9uc30gZnJvbSBcInpsaWJcIjtcbmltcG9ydCB7YmFzZW5hbWUsIGRpcm5hbWV9IGZyb20gXCJwYXRoXCI7XG5pbXBvcnQge2ZpbGVVUkxUb1BhdGh9IGZyb20gXCJ1cmxcIjtcbmltcG9ydCB7ZXhlYyBhcyBleGVjQ2hpbGRQcm9jZXNzfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHtjcmVhdGVIYXNofSBmcm9tIFwiY3J5cHRvXCI7XG5pbXBvcnQge2Zyb20sIE9ic2VydmFibGUsIFN1YmplY3QsIFN1YnNjcmlwdGlvbn0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7U2VydmVyfSBmcm9tIFwic29ja2V0LmlvXCI7XG5pbXBvcnQge0dyaWRGU0J1Y2tldCwgT2JqZWN0SWR9IGZyb20gXCJtb25nb2RiXCI7XG5pbXBvcnQge0RvY3VtZW50fSBmcm9tIFwibW9uZ29vc2VcIjtcbmltcG9ydCBtb25nb29zZSBmcm9tIFwibW9uZ29vc2VcIjtcbmltcG9ydCB7UGFzc1Rocm91Z2gsIFJlYWRhYmxlLCBSZWFkYWJsZU9wdGlvbnN9IGZyb20gXCJzdHJlYW1cIjtcbmltcG9ydCBzaGFycF8sIHtSZWdpb259IGZyb20gXCJzaGFycFwiO1xuaW1wb3J0IHtIdHRwRXJyb3J9IGZyb20gXCJyb3V0aW5nLWNvbnRyb2xsZXJzXCI7XG5pbXBvcnQgYXhpb3MgZnJvbSBcImF4aW9zXCI7XG5pbXBvcnQgZmlsZVR5cGUgZnJvbSBcImZpbGUtdHlwZS9jb3JlXCI7XG5pbXBvcnQge1xuICAgIElBc3NldENyb3BJbmZvLFxuICAgIElBc3NldEltYWdlUGFyYW1zLFxuICAgIElBc3NldE1ldGEsXG4gICAgSUNsaWVudFNvY2tldCwgSURlcGVuZGVuY3lDb250YWluZXIsXG4gICAgSUZpbGVUeXBlLFxuICAgIFBhcmFtUmVzb2x2ZXIsXG4gICAgVHlwZVxufSBmcm9tIFwiLi9jb21tb24tdHlwZXNcIjtcblxuY29uc3Qgc2hhcnAgPSBzaGFycF87XG5cbmV4cG9ydCBpbnRlcmZhY2UgSURJQ29udGFpbmVycyB7XG4gICAgYXBwQ29udGFpbmVyOiBJRGVwZW5kZW5jeUNvbnRhaW5lclxufVxuXG5leHBvcnQgY29uc3QgZGlDb250YWluZXJzOiBJRElDb250YWluZXJzID0ge1xuICAgIGFwcENvbnRhaW5lcjogbnVsbFxufTtcblxuZXhwb3J0IHR5cGUgRmlsdGVyUHJlZGljYXRlID0gKHZhbHVlOiBhbnksIGtleT86IGFueSwgdGFyZ2V0PzogYW55LCBzb3VyY2U/OiBhbnkpID0+IGJvb2xlYW47XG5cbmV4cG9ydCBmdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZCh2YWx1ZTogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGwgfHwgdHlwZW9mIHZhbHVlID09IFwidW5kZWZpbmVkXCI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0RlZmluZWQodmFsdWU6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhaXNOdWxsT3JVbmRlZmluZWQodmFsdWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHlwZShvYmo6IGFueSk6IHN0cmluZyB7XG4gICAgY29uc3QgcmVnZXggPSBuZXcgUmVnRXhwKFwiXFxcXHMoW2EtekEtWl0rKVwiKTtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikubWF0Y2gocmVnZXgpWzFdLnRvTG93ZXJDYXNlKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc09iamVjdCh2YWx1ZTogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGdldFR5cGUodmFsdWUpID09IFwib2JqZWN0XCI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0FycmF5KHZhbHVlOiBhbnkpOiB2YWx1ZSBpcyBBcnJheTxhbnk+IHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0J1ZmZlcih2YWx1ZTogYW55KTogdmFsdWUgaXMgQnVmZmVyIHtcbiAgICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBCdWZmZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0Jvb2xlYW4odmFsdWU6IGFueSk6IHZhbHVlIGlzIGJvb2xlYW4ge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwiYm9vbGVhblwiO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNEYXRlKHZhbHVlOiBhbnkpOiB2YWx1ZSBpcyBEYXRlIHtcbiAgICByZXR1cm4gISF2YWx1ZSAmJiB2YWx1ZVtTeW1ib2wudG9QcmltaXRpdmVdICYmICFpc05hTih2YWx1ZSkgJiYgXCJ1bmRlZmluZWRcIiAhPT0gdHlwZW9mIHZhbHVlLmdldERhdGU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ByaW1pdGl2ZSh2YWx1ZTogYW55KTogYm9vbGVhbiB7XG4gICAgY29uc3QgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICByZXR1cm4gdmFsdWUgPT0gbnVsbCB8fCAodHlwZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlICE9PSBcImZ1bmN0aW9uXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTdHJpbmcodmFsdWU6IGFueSk6IHZhbHVlIGlzIHN0cmluZyB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWU6IGFueSk6IHZhbHVlIGlzIEZ1bmN0aW9uIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbnN0cnVjdG9yKHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiICYmIHZhbHVlLnByb3RvdHlwZSAmJiB2YWx1ZS5wcm90b3R5cGUuY29uc3RydWN0b3IpID09PSB2YWx1ZSAmJiB2YWx1ZS5uYW1lICE9PSBcIk9iamVjdFwiO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNUeXBlKHZhbHVlOiBhbnkpOiB2YWx1ZSBpcyBUeXBlPGFueT4ge1xuICAgIHJldHVybiBpc0NvbnN0cnVjdG9yKHZhbHVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzSW50ZXJmYWNlKG9iajogYW55LCBpbnRlckZhY2VPYmplY3Q6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0pOiBib29sZWFuIHtcbiAgICBpZiAoIW9iaiB8fCB0eXBlb2Ygb2JqICE9PSBcIm9iamVjdFwiIHx8IGlzQXJyYXkob2JqKSB8fCAhaXNPYmplY3QoaW50ZXJGYWNlT2JqZWN0KSkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhpbnRlckZhY2VPYmplY3QpO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICAgICAgbGV0IHR5cGUgPSBpbnRlckZhY2VPYmplY3Rba2V5XSB8fCBcIlwiO1xuICAgICAgICBpZiAodHlwZS5zdGFydHNXaXRoKFwiKlwiKSkge1xuICAgICAgICAgICAgdHlwZSA9IHR5cGUuc3Vic3RyKDEpO1xuICAgICAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGdldFR5cGUob2JqW2tleV0pICE9PSB0eXBlKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gZWxzZSBpZiAoIW9iai5oYXNPd25Qcm9wZXJ0eShrZXkpIHx8IGdldFR5cGUob2JqW2tleV0pICE9PSB0eXBlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1Y0ZpcnN0KHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICghdmFsdWUpIHJldHVybiBcIlwiO1xuICAgIHJldHVybiB2YWx1ZVswXS50b1VwcGVyQ2FzZSgpICsgdmFsdWUuc3Vic3RyKDEpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbGNGaXJzdCh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXZhbHVlKSByZXR1cm4gXCJcIjtcbiAgICByZXR1cm4gdmFsdWVbMF0udG9Mb3dlckNhc2UoKSArIHZhbHVlLnN1YnN0cigxKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0SWQoaWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0eXBlb2YgaWQgPT09IFwic3RyaW5nXCIgJiYgaWQubGVuZ3RoID09IDI0ICYmICFpc05hTihOdW1iZXIoXCIweFwiICsgaWQpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpcnN0SXRlbTxUPih2YWx1ZTogVFtdKTogVCB7XG4gICAgcmV0dXJuIHZhbHVlWzBdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbGFzdEl0ZW08VD4odmFsdWU6IFRbXSk6IFQge1xuICAgIHJldHVybiB2YWx1ZVt2YWx1ZS5sZW5ndGggLSAxXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlZ3JvdXA8VD4odmFsdWU6IFRbXSwgY29tcGFyYXRvcjogKGE6IFQsIGI6IFQpID0+IGJvb2xlYW4pOiBBcnJheTxUW10+IHtcbiAgICBjb25zdCByZXN1bHQ6IEFycmF5PFRbXT4gPSBbXTtcbiAgICBpZiAoIWlzQXJyYXkodmFsdWUpIHx8IHZhbHVlLmxlbmd0aCA9PSAwKSByZXR1cm4gcmVzdWx0O1xuICAgIHZhbHVlID0gQXJyYXkuZnJvbSh2YWx1ZSk7XG4gICAgcmVzdWx0LnB1c2goW3ZhbHVlLnNoaWZ0KCldKTtcbiAgICB2YWx1ZS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICBjb25zdCBncm91cCA9IHJlc3VsdC5maW5kKGcgPT4gZy5zb21lKGEgPT4gY29tcGFyYXRvcihhLCBpdGVtKSkpO1xuICAgICAgICBpZiAoZ3JvdXApIHtcbiAgICAgICAgICAgIGdyb3VwLnB1c2goaXRlbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0LnB1c2goW2l0ZW1dKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdW5pcXVlSXRlbXM8VD4odmFsdWU6IFRbXSk6IFRbXSB7XG4gICAgcmV0dXJuIHZhbHVlLmZpbHRlcigodiwgaXgpID0+IHZhbHVlLmluZGV4T2YodikgPT09IGl4KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZhbHVlKG9iajogYW55LCBrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogYW55LCB0cmVlRmFsbGJhY2s6IGJvb2xlYW4gPSBmYWxzZSk6IGFueSB7XG4gICAga2V5ID0ga2V5IHx8IFwiXCI7XG4gICAgY29uc3Qga2V5cyA9IGtleS5zcGxpdChcIi5cIik7XG4gICAgbGV0IGN1cktleSA9IFwiXCI7XG4gICAgZG8ge1xuICAgICAgICBjdXJLZXkgKz0ga2V5cy5zaGlmdCgpO1xuICAgICAgICBpZiAoaXNEZWZpbmVkKG9iaikgJiYgaXNEZWZpbmVkKG9ialtjdXJLZXldKSAmJiAodHlwZW9mIG9ialtjdXJLZXldID09PSBcIm9iamVjdFwiIHx8ICFrZXlzLmxlbmd0aCkpIHtcbiAgICAgICAgICAgIG9iaiA9IG9ialtjdXJLZXldO1xuICAgICAgICAgICAgY3VyS2V5ID0gXCJcIjtcbiAgICAgICAgfSBlbHNlIGlmICgha2V5cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IHR5cGVvZiBkZWZhdWx0VmFsdWUgPT0gXCJ1bmRlZmluZWRcIiA/IGtleS5yZXBsYWNlKG5ldyBSZWdFeHAoYCR7Y3VyS2V5fSRgKSwgYHske2N1cktleX19YCkgOiBkZWZhdWx0VmFsdWU7XG4gICAgICAgICAgICBvYmogPSB0cmVlRmFsbGJhY2sgPyBvYmogfHwgZGVmYXVsdFZhbHVlIDogZGVmYXVsdFZhbHVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3VyS2V5ICs9IFwiLlwiO1xuICAgICAgICB9XG4gICAgfSB3aGlsZSAoa2V5cy5sZW5ndGgpO1xuICAgIHJldHVybiBvYmo7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBncm91cEJ5PFQ+KGl0ZW1zOiBUW10sIGNiOiAoaXRlbTogVCkgPT4gc3RyaW5nKSB7XG4gICAgcmV0dXJuIGl0ZW1zLnJlZHVjZSgocmVzLCBpdGVtKSA9PiB7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gY2IoaXRlbSk7XG4gICAgICAgIHJlc1tncm91cF0gPSByZXNbZ3JvdXBdIHx8IFtdO1xuICAgICAgICByZXNbZ3JvdXBdLnB1c2goaXRlbSk7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfSwge30pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFZhbHVlKHZhbHVlOiBhbnksIHR5cGU6IHN0cmluZyk6IGFueSB7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICAgICAgICB2YWx1ZSA9IHR5cGVvZiB2YWx1ZSA9PSBcInN0cmluZ1wiID8gdmFsdWUudG9Mb3dlckNhc2UoKSA6IHZhbHVlO1xuICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSA9PSBcIm5vXCIgfHwgdmFsdWUgPT0gXCJmYWxzZVwiIHx8IHZhbHVlID09IFwiMFwiKSA/IGZhbHNlIDogISF2YWx1ZTtcbiAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgY29uc3QgdmFsID0gcGFyc2VGbG9hdCh2YWx1ZSk7XG4gICAgICAgICAgICByZXR1cm4gaXNOYU4odmFsKSA/IDAgOiB2YWw7XG4gICAgICAgIGNhc2UgXCJhcnJheVwiOlxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZSh2YWx1ZSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke3ZhbHVlfWAuc3BsaXQoXCIsIFwiKTtcbiAgICAgICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG5jb25zdCBjcm9wSW50ZXJmYWNlID0ge1xuICAgIHg6IFwibnVtYmVyXCIsXG4gICAgeTogXCJudW1iZXJcIixcbiAgICB3OiBcIm51bWJlclwiLFxuICAgIGg6IFwibnVtYmVyXCJcbn07XG5cbmZ1bmN0aW9uIHRvQ3JvcFJlZ2lvbihjcm9wSW5mbzogc3RyaW5nIHwgYm9vbGVhbiB8IElBc3NldENyb3BJbmZvKTogUmVnaW9uIHtcbiAgICBsZXQgY3JvcCA9IGNyb3BJbmZvIGFzIElBc3NldENyb3BJbmZvO1xuICAgIGlmIChpc1N0cmluZyhjcm9wSW5mbykpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNyb3AgPSBKU09OLnBhcnNlKGNyb3BJbmZvIGFzIHN0cmluZyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICghaXNJbnRlcmZhY2UoY3JvcCwgY3JvcEludGVyZmFjZSkpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB7XG4gICAgICAgIHdpZHRoOiBNYXRoLnJvdW5kKGNyb3AudyksXG4gICAgICAgIGhlaWdodDogTWF0aC5yb3VuZChjcm9wLmgpLFxuICAgICAgICB0b3A6IE1hdGgucm91bmQoY3JvcC55KSxcbiAgICAgICAgbGVmdDogTWF0aC5yb3VuZChjcm9wLngpXG4gICAgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRvSW1hZ2U8VCA9IEJ1ZmZlciB8IFJlYWRhYmxlPihzcmM6IFQsIHBhcmFtcz86IElBc3NldEltYWdlUGFyYW1zLCBtZXRhPzogSUFzc2V0TWV0YSk6IFByb21pc2U8VD4ge1xuXG4gICAgLy8gRGVmYXVsdCBwYXJhbXMgYW5kIG1ldGFcbiAgICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG4gICAgbWV0YSA9IG1ldGEgfHwge307XG5cbiAgICAvLyBHZXQgZGVmYXVsdCBjcm9wIGluZm9cbiAgICBjb25zdCBjcm9wID0gdG9Dcm9wUmVnaW9uKG1ldGEuY3JvcCk7XG5cbiAgICAvLyBSZXR1cm4gdGhlIHNyYyBpZiB0aGVyZSBhcmUgbm8gcGFyYW1zIGFuZCBubyBkZWZhdWx0IGNyb3AgZXhpc3RzXG4gICAgaWYgKG1ldGEuZXh0ZW5zaW9uID09PSBcInN2Z1wiIHx8IChPYmplY3Qua2V5cyhwYXJhbXMpLmxlbmd0aCA9PSAwICYmICFjcm9wKSkge1xuICAgICAgICByZXR1cm4gc3JjO1xuICAgIH1cblxuICAgIC8vIFBhcnNlIHBhcmFtc1xuICAgIHBhcmFtcy5yb3RhdGlvbiA9IGlzTmFOKHBhcmFtcy5yb3RhdGlvbikgPyAwIDogTWF0aC5yb3VuZChwYXJhbXMucm90YXRpb24gLyA5MCkgKiA5MDtcbiAgICBwYXJhbXMuY2FudmFzU2NhbGVYID0gaXNOYU4ocGFyYW1zLmNhbnZhc1NjYWxlWCkgPyAxIDogTnVtYmVyKHBhcmFtcy5jYW52YXNTY2FsZVgpO1xuICAgIHBhcmFtcy5jYW52YXNTY2FsZVkgPSBpc05hTihwYXJhbXMuY2FudmFzU2NhbGVZKSA/IDEgOiBOdW1iZXIocGFyYW1zLmNhbnZhc1NjYWxlWSk7XG4gICAgcGFyYW1zLnNjYWxlWCA9IGlzTmFOKHBhcmFtcy5zY2FsZVgpID8gMSA6IE51bWJlcihwYXJhbXMuc2NhbGVYKTtcbiAgICBwYXJhbXMuc2NhbGVZID0gaXNOYU4ocGFyYW1zLnNjYWxlWSkgPyAxIDogTnVtYmVyKHBhcmFtcy5zY2FsZVkpO1xuICAgIHBhcmFtcy5jcm9wID0gaXNCb29sZWFuKHBhcmFtcy5jcm9wKSA/IHBhcmFtcy5jcm9wIDogcGFyYW1zLmNyb3AgPT0gXCJ0cnVlXCI7XG5cbiAgICBsZXQgYnVmZmVyID0gc3JjIGluc3RhbmNlb2YgUmVhZGFibGUgPyBhd2FpdCBzdHJlYW1Ub0J1ZmZlcihzcmMpIDogc3JjIGFzIGFueTtcbiAgICB0cnkge1xuICAgICAgICAvLyBHZXQgY3JvcCBpbmZvXG4gICAgICAgIGNvbnN0IGNyb3BCZWZvcmUgPSB0b0Nyb3BSZWdpb24ocGFyYW1zLmNyb3BCZWZvcmUgfHwgKHBhcmFtcy5jcm9wID8gbWV0YS5jcm9wQmVmb3JlIDogbnVsbCkpO1xuICAgICAgICBjb25zdCBjcm9wQWZ0ZXIgPSB0b0Nyb3BSZWdpb24ocGFyYW1zLmNyb3BBZnRlciB8fCAocGFyYW1zLmNyb3AgPyBtZXRhLmNyb3BBZnRlciA6IG51bGwpKTtcbiAgICAgICAgLy8gR2V0IG1ldGFkYXRhXG4gICAgICAgIGxldCBpbWcgPSBzaGFycChidWZmZXIpO1xuICAgICAgICBsZXQge3dpZHRoLCBoZWlnaHR9ID0gYXdhaXQgaW1nLm1ldGFkYXRhKCk7XG4gICAgICAgIC8vIENyb3AgYmVmb3JlIHJlc2l6ZVxuICAgICAgICBpZiAoY3JvcEJlZm9yZSkge1xuICAgICAgICAgICAgd2lkdGggPSBjcm9wQmVmb3JlLndpZHRoO1xuICAgICAgICAgICAgaGVpZ2h0ID0gY3JvcEJlZm9yZS5oZWlnaHQ7XG4gICAgICAgICAgICBpbWcgPSBpbWcuZXh0cmFjdChjcm9wQmVmb3JlKTtcbiAgICAgICAgfSBlbHNlIGlmIChjcm9wKSB7XG4gICAgICAgICAgICB3aWR0aCA9IGNyb3Aud2lkdGg7XG4gICAgICAgICAgICBoZWlnaHQgPSBjcm9wLmhlaWdodDtcbiAgICAgICAgICAgIGltZyA9IGltZy5leHRyYWN0KGNyb3ApO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlc2l6ZSBjYW52YXNcbiAgICAgICAgY29uc3QgY2FudmFzU2NhbGVYID0gbWV0YT8uY2FudmFzU2NhbGVYIHx8IDE7XG4gICAgICAgIGNvbnN0IGNhbnZhc1NjYWxlWSA9IG1ldGE/LmNhbnZhc1NjYWxlWSB8fCAxO1xuICAgICAgICBpZiAocGFyYW1zLmNhbnZhc1NjYWxlWCAhPT0gY2FudmFzU2NhbGVYIHx8IHBhcmFtcy5jYW52YXNTY2FsZVkgIT09IGNhbnZhc1NjYWxlWSkge1xuICAgICAgICAgICAgd2lkdGggPSBNYXRoLnJvdW5kKHdpZHRoICogcGFyYW1zLmNhbnZhc1NjYWxlWCk7XG4gICAgICAgICAgICBoZWlnaHQgPSBNYXRoLnJvdW5kKGhlaWdodCAqIHBhcmFtcy5jYW52YXNTY2FsZVkpO1xuICAgICAgICAgICAgaW1nID0gaW1nLnJlc2l6ZSh7d2lkdGgsIGhlaWdodCwgYmFja2dyb3VuZDogXCIjMDAwMDAwMDBcIiwgZml0OiBcImNvbnRhaW5cIn0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlc2l6ZSBpbWFnZVxuICAgICAgICBpZiAocGFyYW1zLnNjYWxlWCAhPT0gMSB8fCBwYXJhbXMuc2NhbGVZICE9PSAxKSB7XG4gICAgICAgICAgICB3aWR0aCA9IE1hdGgucm91bmQod2lkdGggKiBwYXJhbXMuc2NhbGVYKTtcbiAgICAgICAgICAgIGhlaWdodCA9IE1hdGgucm91bmQoaGVpZ2h0ICogcGFyYW1zLnNjYWxlWSk7XG4gICAgICAgICAgICBpbWcgPSBpbWcucmVzaXplKHt3aWR0aCwgaGVpZ2h0LCBiYWNrZ3JvdW5kOiBcIiMwMDAwMDAwMFwiLCBmaXQ6IFwiZmlsbFwifSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ3JvcCBhZnRlciByZXNpemVcbiAgICAgICAgaWYgKGNyb3BBZnRlcikge1xuICAgICAgICAgICAgaW1nID0gaW1nLmV4dHJhY3QoY3JvcEFmdGVyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBSb3RhdGVcbiAgICAgICAgaWYgKHBhcmFtcy5yb3RhdGlvbiAhPT0gMCkge1xuICAgICAgICAgICAgYnVmZmVyID0gYXdhaXQgaW1nLnRvQnVmZmVyKCk7XG4gICAgICAgICAgICBpbWcgPSBzaGFycChidWZmZXIpLnJvdGF0ZShwYXJhbXMucm90YXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGJ1ZmZlciA9IGF3YWl0IGltZy50b0J1ZmZlcigpO1xuICAgICAgICBzcmMgPSBzcmMgaW5zdGFuY2VvZiBSZWFkYWJsZSA/IGJ1ZmZlclRvU3RyZWFtKGJ1ZmZlcikgOiBidWZmZXI7XG4gICAgICAgIHJldHVybiBzcmM7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmxvZyhcIkltYWdlIGNvbnZlcnNpb24gZXJyb3JcIiwgZSk7XG4gICAgICAgIHNyYyA9IHNyYyBpbnN0YW5jZW9mIFJlYWRhYmxlID8gYnVmZmVyVG9TdHJlYW0oYnVmZmVyKSA6IGJ1ZmZlcjtcbiAgICAgICAgcmV0dXJuIHNyYztcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWZmZXJUb1N0cmVhbShidWZmZXI6IEJ1ZmZlcik6IFJlYWRhYmxlIHtcbiAgICBjb25zdCByZWFkU3RyZWFtID0gbmV3IFBhc3NUaHJvdWdoKCk7XG4gICAgcmVhZFN0cmVhbS5lbmQoYnVmZmVyKTtcbiAgICByZXR1cm4gcmVhZFN0cmVhbVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RyZWFtVG9CdWZmZXIoc3RyZWFtOiBSZWFkYWJsZSk6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPEJ1ZmZlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCBjb25jYXQgPSBbXTtcbiAgICAgICAgc3RyZWFtLm9uKFwiZGF0YVwiLCBkYXRhID0+IHtcbiAgICAgICAgICAgIGNvbmNhdC5wdXNoKGRhdGEpO1xuICAgICAgICB9KTtcbiAgICAgICAgc3RyZWFtLm9uKFwiZXJyb3JcIiwgcmVqZWN0KTtcbiAgICAgICAgc3RyZWFtLm9uKFwiZW5kXCIsICgpID0+IHJlc29sdmUoQnVmZmVyLmNvbmNhdChjb25jYXQpKSk7XG4gICAgfSlcbn1cblxuY2xhc3MgUmVhZGFibGVTdHJlYW1DbG9uZSBleHRlbmRzIFJlYWRhYmxlIHtcblxuICAgIGNvbnN0cnVjdG9yKHJlYWRhYmxlU3RyZWFtOiBSZWFkYWJsZSwgb3B0cz86IFJlYWRhYmxlT3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRzKTtcbiAgICAgICAgcmVhZGFibGVTdHJlYW0/Lm9uKFwiZGF0YVwiLCBjaHVuayA9PiB7XG4gICAgICAgICAgICB0aGlzLnB1c2goY2h1bmspO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVhZGFibGVTdHJlYW0/Lm9uKFwiZW5kXCIsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucHVzaChudWxsKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRhYmxlU3RyZWFtPy5vbihcImVycm9yXCIsIGVyciA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJlcnJvclwiLCBlcnIpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfcmVhZChzaXplOiBudW1iZXIpIHtcblxuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvcHlTdHJlYW0oc3RyZWFtOiBSZWFkYWJsZSwgb3B0cz86IFJlYWRhYmxlT3B0aW9ucyk6IFJlYWRhYmxlIHtcbiAgICByZXR1cm4gbmV3IFJlYWRhYmxlU3RyZWFtQ2xvbmUoc3RyZWFtLCBvcHRzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1rZGlyUmVjdXJzaXZlKHBhdGg6IHN0cmluZywgbW9kZTogbnVtYmVyID0gbnVsbCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIG1rZGlyKHBhdGgsIHttb2RlOiBtb2RlIHx8IDBvNzc3LCByZWN1cnNpdmU6IHRydWV9LCBlcnIgPT4ge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWxldGVGaWxlKHBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHVubGluayhwYXRoLCBlcnIgPT4ge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWFkRmlsZShwYXRoOiBzdHJpbmcpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxCdWZmZXI+KChyZXMsIHJlaikgPT4ge1xuICAgICAgICBmc1JlYWRGaWxlKHBhdGgsIChlcnIsIGRhdGEpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICByZWooZXJyKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXMoZGF0YSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVhZEFuZERlbGV0ZUZpbGUocGF0aDogc3RyaW5nLCB0aW1lb3V0OiBudW1iZXIgPSA1MDAwKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVhZEZpbGUocGF0aCk7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHVubGluayhwYXRoLCAoKSA9PiB7XG4gICAgICAgIH0pO1xuICAgIH0sIHRpbWVvdXQpO1xuICAgIHJldHVybiBkYXRhO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd3JpdGVGaWxlKHBhdGg6IHN0cmluZywgZGF0YTogQnVmZmVyKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBhd2FpdCBta2RpclJlY3Vyc2l2ZShkaXJuYW1lKHBhdGgpKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8QnVmZmVyPigocmVzLCByZWopID0+IHtcbiAgICAgICAgZnNXcml0ZUZpbGUocGF0aCwgZGF0YSwgZXJyID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICByZWooZXJyKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXMoZGF0YSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdmFsdWVUb1Byb21pc2UodmFsdWU6IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUHJvbWlzZSA/IHZhbHVlIDogUHJvbWlzZS5yZXNvbHZlKHZhbHVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByb21pc2VUaW1lb3V0KHRpbWVvdXQ6IG51bWJlciA9IDEwMDAsIGVycm9yOiBib29sZWFuID0gZmFsc2UpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxhbnk+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoYFRpbWVvdXQgZXhjZWVkZWQ6ICR7dGltZW91dH1tc2ApO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmUoYFRpbWVvdXQ6ICR7dGltZW91dH1tc2ApO1xuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbnN0cnVjdG9yTmFtZSh0eXBlOiBUeXBlPGFueT4pOiBzdHJpbmcge1xuICAgIHJldHVybiB0eXBlLnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVuY3Rpb25QYXJhbXMoZnVuYzogRnVuY3Rpb24pOiBzdHJpbmdbXSB7XG4gICAgLy8gUmVtb3ZlIGNvbW1lbnRzIG9mIHRoZSBmb3JtIC8qIC4uLiAqL1xuICAgIC8vIFJlbW92aW5nIGNvbW1lbnRzIG9mIHRoZSBmb3JtIC8vXG4gICAgLy8gUmVtb3ZlIGJvZHkgb2YgdGhlIGZ1bmN0aW9uIHsgLi4uIH1cbiAgICAvLyByZW1vdmluZyBcIj0+XCIgaWYgZnVuYyBpcyBhcnJvdyBmdW5jdGlvblxuICAgIGNvbnN0IHN0ciA9IGZ1bmMudG9TdHJpbmcoKVxuICAgICAgICAucmVwbGFjZSgvXFwvXFwqW1xcc1xcU10qP1xcKlxcLy9nLCBcIlwiKVxuICAgICAgICAucmVwbGFjZSgvXFwvXFwvKC4pKi9nLCBcIlwiKVxuICAgICAgICAucmVwbGFjZSgve1tcXHNcXFNdKn0vLCBcIlwiKVxuICAgICAgICAucmVwbGFjZSgvPT4vZywgXCJcIilcbiAgICAgICAgLnRyaW0oKTtcblxuICAgIC8vIFN0YXJ0IHBhcmFtZXRlciBuYW1lcyBhZnRlciBmaXJzdCBcIihcIlxuICAgIGNvbnN0IHN0YXJ0ID0gc3RyLmluZGV4T2YoXCIoXCIpICsgMTtcblxuICAgIC8vIEVuZCBwYXJhbWV0ZXIgbmFtZXMgaXMganVzdCBiZWZvcmUgbGFzdCBcIilcIlxuICAgIGNvbnN0IGVuZCA9IHN0ci5sZW5ndGggLSAxO1xuICAgIGNvbnN0IHJlc3VsdCA9IHN0ci5zdWJzdHJpbmcoc3RhcnQsIGVuZCkuc3BsaXQoXCIsIFwiKTtcbiAgICBjb25zdCBwYXJhbXMgPSBbXTtcblxuICAgIHJlc3VsdC5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuXG4gICAgICAgIC8vIFJlbW92aW5nIGFueSBkZWZhdWx0IHZhbHVlXG4gICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnJlcGxhY2UoLz1bXFxzXFxTXSovZywgXCJcIikudHJpbSgpO1xuXG4gICAgICAgIGlmIChlbGVtZW50Lmxlbmd0aCA+IDApXG4gICAgICAgICAgICBwYXJhbXMucHVzaChlbGVtZW50KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBwYXJhbXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGaWxlTmFtZShwYXRoOiBzdHJpbmcsIHdpdGhFeHRlbnNpb246IGJvb2xlYW4gPSBmYWxzZSk6IHN0cmluZyB7XG4gICAgY29uc3QgbmFtZSA9IGJhc2VuYW1lKHBhdGggfHwgXCJcIik7XG4gICAgcmV0dXJuIHdpdGhFeHRlbnNpb24gPyBuYW1lIDogbmFtZS5zcGxpdChcIi5cIikuc2xpY2UoMCwgLTEpLmpvaW4oXCIuXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgbmFtZSA9IGJhc2VuYW1lKHBhdGggfHwgXCJcIik7XG4gICAgcmV0dXJuIG5hbWUuc3BsaXQoXCIuXCIpLnBvcCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlSWRTdHJpbmcoKTogYW55IHtcbiAgICByZXR1cm4gbmV3IE9iamVjdElkKCkudG9IZXhTdHJpbmcoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlkVG9TdHJpbmcodmFsdWU6IGFueSk6IGFueSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZS5tYXAoaWRUb1N0cmluZyk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIE9iamVjdElkIHx8IHZhbHVlIGluc3RhbmNlb2YgbW9uZ29vc2UuVHlwZXMuT2JqZWN0SWRcbiAgICAgICAgPyB2YWx1ZS50b0hleFN0cmluZygpXG4gICAgICAgIDogKGlzU3RyaW5nKHZhbHVlKSA/IHZhbHVlIDogdmFsdWUgfHwgbnVsbCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUcmFuc2Zvcm1lcih0cmFuc2Zvcm0/OiAoZG9jOiBEb2N1bWVudCwgcmV0OiBhbnksIG9wdGlvbnM/OiBhbnkpID0+IGFueSkge1xuICAgIHJldHVybiAoZG9jOiBEb2N1bWVudCwgcmV0OiBhbnksIG9wdGlvbnM/OiBhbnkpID0+IHtcbiAgICAgICAgcmV0LmlkID0gaWRUb1N0cmluZyhyZXQuaWQpIHx8IHJldC5pZDtcbiAgICAgICAgaWYgKGRvYy5faWQpIHtcbiAgICAgICAgICAgIHJldC5faWQgPSBpZFRvU3RyaW5nKGRvYy5faWQpO1xuICAgICAgICAgICAgcmV0LmlkID0gcmV0LmlkIHx8IHJldC5faWQ7XG4gICAgICAgIH1cbiAgICAgICAgZGVsZXRlIHJldC5fX3Y7XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKHRyYW5zZm9ybSkgPyB0cmFuc2Zvcm0oZG9jLCByZXQsIG9wdGlvbnMpIHx8IHJldCA6IHJldDtcbiAgICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnJvYWRjYXN0KHNvY2tldFNlcnZlcjogU2VydmVyLCBjYjogKGNsaWVudDogSUNsaWVudFNvY2tldCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHNvY2tldFNlcnZlci5zb2NrZXRzLnNvY2tldHMuZm9yRWFjaCgoY2xpZW50OiBJQ2xpZW50U29ja2V0KSA9PiB7XG4gICAgICAgIGNiKGNsaWVudCk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByYW5kKG1pbjogbnVtYmVyLCBtYXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQocmFuZG9tKG1pbiwgbWF4KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByYW5kb20obWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gbWluICsgTWF0aC5yYW5kb20oKSAqIChtYXggLSBtaW4pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlTdWJzY3JpcHRpb24oLi4uc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10pOiBTdWJzY3JpcHRpb24ge1xuICAgIHJldHVybiBuZXcgU3Vic2NyaXB0aW9uKCgpID0+IHtcbiAgICAgICAgc3Vic2NyaXB0aW9ucy5mb3JFYWNoKHMgPT4ge1xuICAgICAgICAgICAgcy51bnN1YnNjcmliZSgpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG9ic2VydmFibGVGcm9tRnVuY3Rpb24oY2FsbGJhY2tGdW5jOiAoKSA9PiBhbnkpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIGxldCBzdWJqZWN0OiBhbnk7XG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlPGFueT4oKHN1YnNjcmliZXIpID0+IHtcbiAgICAgICAgaWYgKCFzdWJqZWN0KSB7XG4gICAgICAgICAgICBzdWJqZWN0ID0gbmV3IFN1YmplY3QoKTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgc3ViamVjdCA9IGZyb20oY2FsbGJhY2tGdW5jKCkpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgc3ViamVjdC5lcnJvcihlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdWJqZWN0LnN1YnNjcmliZShzdWJzY3JpYmVyKTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhZExlZnQodmFsdWU6IGFueSwgY291bnQ6IG51bWJlciA9IDMsIHBhZFdpdGg6IHN0cmluZyA9IFwiMFwiKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7dmFsdWV9YC5wYWRTdGFydChjb3VudCwgcGFkV2l0aCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYWRSaWdodCh2YWx1ZTogYW55LCBjb3VudDogbnVtYmVyID0gMywgcGFkV2l0aDogc3RyaW5nID0gXCIwXCIpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt2YWx1ZX1gLnBhZEVuZChjb3VudCwgcGFkV2l0aCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYW1lbENhc2VUb0Rhc2goc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBzdHIucmVwbGFjZSgvKFthLXpdKShbQS1aXSkvZywgXCIkMS0kMlwiKS50b0xvd2VyQ2FzZSgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ3ppcFByb21pc2VkKGRhdGE6IHN0cmluZywgb3B0cz86IFpsaWJPcHRpb25zKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBnemlwKGRhdGEsIG9wdHMsIChlcnIsIHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmUocmVzdWx0LnRvU3RyaW5nKFwiYmFzZTY0XCIpKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBndW56aXBQcm9taXNlZChkYXRhOiBzdHJpbmcsIG9wdHM/OiBabGliT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgZ3VuemlwKEJ1ZmZlci5mcm9tKGRhdGEsIFwiYmFzZTY0XCIpLCBvcHRzLCAoZXJyLCByZXN1bHQpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXNvbHZlKHJlc3VsdC50b1N0cmluZyhcInV0ZjhcIikpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlbGV0ZUZyb21CdWNrZXQoYnVja2V0OiBHcmlkRlNCdWNrZXQsIGlkOiBPYmplY3RJZCB8IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgZmlsZUlkID0gaWQgaW5zdGFuY2VvZiBPYmplY3RJZCA/IGlkIDogbmV3IE9iamVjdElkKGlkKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8c3RyaW5nPigoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBpZiAoIWlkKSB7XG4gICAgICAgICAgICAvLyBXZSBkb24ndCBjYXJlIGFib3V0IGVtcHR5IGlkXG4gICAgICAgICAgICByZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGJ1Y2tldC5kZWxldGUoZmlsZUlkLCBlcnJvciA9PiB7XG4gICAgICAgICAgICBsZXQgZXJyID0gZXJyb3IgYXMgYW55O1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgZXJyID0gZXJyb3IubWVzc2FnZSB8fCBlcnJvciB8fCBcIlwiO1xuICAgICAgICAgICAgICAgIGlmICghaXNTdHJpbmcoZXJyKSB8fCAhZXJyLnN0YXJ0c1dpdGgoXCJGaWxlTm90Rm91bmRcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXNvbHZlKGZpbGVJZC50b0hleFN0cmluZygpKTtcbiAgICAgICAgfSk7XG4gICAgfSkpO1xufVxuXG5jb25zdCBkZWZhdWx0UHJlZGljYXRlOiBGaWx0ZXJQcmVkaWNhdGUgPSAoKSA9PiB0cnVlO1xuXG5mdW5jdGlvbiBjb3B5UmVjdXJzaXZlKHRhcmdldDogYW55LCBzb3VyY2U6IGFueSwgcHJlZGljYXRlOiBGaWx0ZXJQcmVkaWNhdGUsIGNvcGllczogTWFwPGFueSwgYW55Pik6IGFueSB7XG4gICAgaWYgKGlzUHJpbWl0aXZlKHNvdXJjZSkgfHwgaXNEYXRlKHNvdXJjZSkgfHwgaXNGdW5jdGlvbihzb3VyY2UpKSByZXR1cm4gc291cmNlO1xuICAgIGlmIChjb3BpZXMuaGFzKHNvdXJjZSkpIHJldHVybiBjb3BpZXMuZ2V0KHNvdXJjZSk7XG4gICAgaWYgKGlzQXJyYXkoc291cmNlKSkge1xuICAgICAgICB0YXJnZXQgPSBpc0FycmF5KHRhcmdldCkgPyBBcnJheS5mcm9tKHRhcmdldCkgOiBbXTtcbiAgICAgICAgc291cmNlLmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXByZWRpY2F0ZShpdGVtLCBpbmRleCwgdGFyZ2V0LCBzb3VyY2UpKSByZXR1cm47XG4gICAgICAgICAgICBpZiAodGFyZ2V0Lmxlbmd0aCA+IGluZGV4KVxuICAgICAgICAgICAgICAgIHRhcmdldFtpbmRleF0gPSBjb3B5UmVjdXJzaXZlKHRhcmdldFtpbmRleF0sIGl0ZW0sIHByZWRpY2F0ZSwgY29waWVzKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB0YXJnZXQucHVzaChjb3B5UmVjdXJzaXZlKG51bGwsIGl0ZW0sIHByZWRpY2F0ZSwgY29waWVzKSk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb3BpZXMuc2V0KHNvdXJjZSwgdGFyZ2V0KTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG4gICAgaWYgKGlzQnVmZmVyKHNvdXJjZSkpIHJldHVybiBCdWZmZXIuZnJvbShzb3VyY2UpO1xuXG4gICAgLy8gSWYgb2JqZWN0IGRlZmluZXMgX19zaG91bGRDb3B5IGFzIGZhbHNlLCB0aGVuIGRvbid0IGNvcHkgaXRcbiAgICBpZiAoc291cmNlLl9fc2hvdWxkQ29weSA9PT0gZmFsc2UpIHJldHVybiBzb3VyY2U7XG4gICAgLy8gQ29weSBvYmplY3RcbiAgICBjb25zdCBzaG91bGRDb3B5ID0gaXNGdW5jdGlvbihzb3VyY2UuX19zaG91bGRDb3B5KSA/IHNvdXJjZS5fX3Nob3VsZENvcHkgOiAoKSA9PiB0cnVlO1xuICAgIGlmIChpc0NvbnN0cnVjdG9yKHNvdXJjZS5jb25zdHJ1Y3RvcikpIHtcbiAgICAgICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0ID0gbmV3IHNvdXJjZS5jb25zdHJ1Y3RvcigpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb3RvID0gc291cmNlLmNvbnN0cnVjdG9yLnByb3RvdHlwZSB8fCBzb3VyY2UucHJvdG90eXBlO1xuICAgICAgICAgICAgICAgIHRhcmdldCA9IE9iamVjdC5jcmVhdGUocHJvdG8pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGFyZ2V0ID0gT2JqZWN0LmFzc2lnbih7fSwgdGFyZ2V0IHx8IHt9KTtcbiAgICB9XG4gICAgLy8gU2V0IHRvIGNvcGllcyB0byBwcmV2ZW50IGNpcmN1bGFyIHJlZmVyZW5jZXNcbiAgICBjb3BpZXMuc2V0KHNvdXJjZSwgdGFyZ2V0KTtcblxuICAgIC8vIENvcHkgbWFwIGVudHJpZXNcbiAgICBpZiAodGFyZ2V0IGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgICAgICAgIGZvciAobGV0IFtrZXksIHZhbHVlXSBvZiBzb3VyY2UuZW50cmllcygpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFwcmVkaWNhdGUodmFsdWUsIGtleSwgdGFyZ2V0LCBzb3VyY2UpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB0YXJnZXQuc2V0KGtleSwgIXNob3VsZENvcHkoa2V5LCB2YWx1ZSkgPyB2YWx1ZSA6IGNvcHlSZWN1cnNpdmUodGFyZ2V0LmdldChrZXkpLCB2YWx1ZSwgcHJlZGljYXRlLCBjb3BpZXMpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIC8vIENvcHkgb2JqZWN0IG1lbWJlcnNcbiAgICBsZXQga2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XG4gICAga2V5cy5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIGlmICghcHJlZGljYXRlKHNvdXJjZVtrZXldLCBrZXksIHRhcmdldCwgc291cmNlKSkgcmV0dXJuO1xuICAgICAgICB0YXJnZXRba2V5XSA9ICFzaG91bGRDb3B5KGtleSwgc291cmNlW2tleV0pID8gc291cmNlW2tleV0gOiBjb3B5UmVjdXJzaXZlKHRhcmdldFtrZXldLCBzb3VyY2Vba2V5XSwgcHJlZGljYXRlLCBjb3BpZXMpO1xuICAgIH0sIHRhcmdldCk7XG5cbiAgICAvLyBDb3B5IG9iamVjdCBwcm9wZXJ0aWVzXG4gICAgY29uc3QgZGVzY3JpcHRvcnMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhzb3VyY2UpO1xuICAgIGtleXMgPSBPYmplY3Qua2V5cyhkZXNjcmlwdG9ycykuZmlsdGVyKGsgPT4ga2V5cy5pbmRleE9mKGspIDwgMCk7XG4gICAga2V5cy5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcnNba2V5XSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRhcmdldDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbHRlcjxUPihvYmo6IFQsIHByZWRpY2F0ZTogRmlsdGVyUHJlZGljYXRlKTogUGFydGlhbDxUPiB7XG4gICAgcmV0dXJuIGNvcHlSZWN1cnNpdmUobnVsbCwgb2JqLCBwcmVkaWNhdGUgfHwgZGVmYXVsdFByZWRpY2F0ZSwgbmV3IE1hcCgpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvcHk8VD4ob2JqOiBUKTogVCB7XG4gICAgcmV0dXJuIGNvcHlSZWN1cnNpdmUobnVsbCwgb2JqLCBkZWZhdWx0UHJlZGljYXRlLCBuZXcgTWFwKCkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXNzaWduPFQ+KHRhcmdldDogVCwgc291cmNlOiBhbnksIHByZWRpY2F0ZT86IEZpbHRlclByZWRpY2F0ZSk6IFQge1xuICAgIHJldHVybiBjb3B5UmVjdXJzaXZlKHRhcmdldCwgc291cmNlLCBwcmVkaWNhdGUsIG5ldyBNYXAoKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtZDUoZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICBpZiAoaXNPYmplY3QoZGF0YSkpIHtcbiAgICAgICAgZGF0YSA9IEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuICAgIH1cbiAgICBpZiAoIWlzU3RyaW5nKGRhdGEpKSB7XG4gICAgICAgIHRocm93IGBDYW4ndCBtZDUgb3RoZXIgdGhhdCByYXcgb2JqZWN0IG9yIHN0cmluZ2A7XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVIYXNoKFwibWQ1XCIpLnVwZGF0ZShkYXRhKS5kaWdlc3QoXCJoZXhcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBydW5Db21tYW5kKHNjcmlwdFBhdGg6IHN0cmluZywgZXhwZWN0ZWRDb2RlOiBudW1iZXIgPSAwKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCBjcCA9IGV4ZWNDaGlsZFByb2Nlc3Moc2NyaXB0UGF0aCwgKGVycm9yLCBzdGRvdXQpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvciAmJiBleHBlY3RlZENvZGUgIT09IGVycm9yLmNvZGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBsaW5lcyA9IChzdGRvdXQgfHwgXCJcIikuc3BsaXQoXCJcXG5cIik7XG4gICAgICAgICAgICBsZXQgbGluZSA9IG51bGw7XG4gICAgICAgICAgICB3aGlsZSAoIWxpbmUgJiYgbGluZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGxpbmUgPSBsaW5lcy5wb3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmUobGluZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBjcC5zdGRvdXQub24oXCJkYXRhXCIsIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhkYXRhLnRvU3RyaW5nKCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgY3Auc3RkZXJyLm9uKFwiZGF0YVwiLCBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhLnRvU3RyaW5nKCkpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGVudW0gQ29uc29sZUNvbG9yIHtcbiAgICBSZXNldCA9IFwiXFx4MWJbMG1cIixcbiAgICBCcmlnaHQgPSBcIlxceDFiWzFtXCIsXG4gICAgRGltID0gXCJcXHgxYlsybVwiLFxuICAgIFVuZGVyc2NvcmUgPSBcIlxceDFiWzRtXCIsXG4gICAgQmxpbmsgPSBcIlxceDFiWzVtXCIsXG4gICAgUmV2ZXJzZSA9IFwiXFx4MWJbN21cIixcbiAgICBIaWRkZW4gPSBcIlxceDFiWzhtXCIsXG5cbiAgICBGZ0JsYWNrID0gXCJcXHgxYlszMG1cIixcbiAgICBGZ1JlZCA9IFwiXFx4MWJbMzFtXCIsXG4gICAgRmdHcmVlbiA9IFwiXFx4MWJbMzJtXCIsXG4gICAgRmdZZWxsb3cgPSBcIlxceDFiWzMzbVwiLFxuICAgIEZnQmx1ZSA9IFwiXFx4MWJbMzRtXCIsXG4gICAgRmdNYWdlbnRhID0gXCJcXHgxYlszNW1cIixcbiAgICBGZ0N5YW4gPSBcIlxceDFiWzM2bVwiLFxuICAgIEZnV2hpdGUgPSBcIlxceDFiWzM3bVwiLFxuICAgIEZnRGVmYXVsdCA9IFwiXFx4MWJbMzhtXCIsXG5cbiAgICBCZ0JsYWNrID0gXCJcXHgxYls0MG1cIixcbiAgICBCZ1JlZCA9IFwiXFx4MWJbNDFtXCIsXG4gICAgQmdHcmVlbiA9IFwiXFx4MWJbNDJtXCIsXG4gICAgQmdZZWxsb3cgPSBcIlxceDFiWzQzbVwiLFxuICAgIEJnQmx1ZSA9IFwiXFx4MWJbNDRtXCIsXG4gICAgQmdNYWdlbnRhID0gXCJcXHgxYls0NW1cIixcbiAgICBCZ0N5YW4gPSBcIlxceDFiWzQ2bVwiLFxuICAgIEJnV2hpdGUgPSBcIlxceDFiWzQ3bVwiLFxuICAgIEJnRGVmYXVsdCA9IFwiXFx4MWJbNDhtXCJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJSnNvbkNvbG9ycyB7XG4gICAga2V5Q29sb3I/OiBDb25zb2xlQ29sb3I7XG4gICAgbnVtYmVyQ29sb3I/OiBDb25zb2xlQ29sb3I7XG4gICAgc3RyaW5nQ29sb3I/OiBDb25zb2xlQ29sb3I7XG4gICAgdHJ1ZUNvbG9yPzogQ29uc29sZUNvbG9yO1xuICAgIGZhbHNlQ29sb3I/OiBDb25zb2xlQ29sb3I7XG4gICAgbnVsbENvbG9yPzogQ29uc29sZUNvbG9yO1xufVxuXG5jb25zdCBkZWZhdWx0Q29sb3JzOiBJSnNvbkNvbG9ycyA9IHtcbiAgICBrZXlDb2xvcjogQ29uc29sZUNvbG9yLkZnV2hpdGUsXG4gICAgbnVtYmVyQ29sb3I6IENvbnNvbGVDb2xvci5GZ0JsdWUsXG4gICAgc3RyaW5nQ29sb3I6IENvbnNvbGVDb2xvci5GZ1llbGxvdyxcbiAgICB0cnVlQ29sb3I6IENvbnNvbGVDb2xvci5GZ0dyZWVuLFxuICAgIGZhbHNlQ29sb3I6IENvbnNvbGVDb2xvci5GZ1JlZCxcbiAgICBudWxsQ29sb3I6IENvbnNvbGVDb2xvci5CZ01hZ2VudGFcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbG9yaXplKGlucHV0OiBhbnksIGNvbG9yOiBDb25zb2xlQ29sb3IpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHtjb2xvcn0ke2lucHV0fSR7Q29uc29sZUNvbG9yLlJlc2V0fWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBqc29uSGlnaGxpZ2h0KGlucHV0OiBzdHJpbmcgfCBvYmplY3QsIGNvbG9yT3B0aW9ucz86IElKc29uQ29sb3JzKTogc3RyaW5nIHtcbiAgICBjb25zdCBjb2xvcnMgPSBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0Q29sb3JzLCBjb2xvck9wdGlvbnMpXG4gICAgY29uc3QganNvbiA9IChpc1N0cmluZyhpbnB1dCkgPyBpbnB1dCA6IEpTT04uc3RyaW5naWZ5KGlucHV0LCBudWxsLCAyKSkucmVwbGFjZSgvJi9nLCAnJicpLnJlcGxhY2UoLzwvZywgJzwnKS5yZXBsYWNlKC8+L2csICc+JylcbiAgICByZXR1cm4ganNvbi5yZXBsYWNlKC8oXCIoXFxcXHVbYS16QS1aMC05XXs0fXxcXFxcW151XXxbXlxcXFxcIl0pKlwiKFxccyo6KT98XFxiKHRydWV8ZmFsc2V8bnVsbClcXGJ8LT9cXGQrKD86XFwuXFxkKik/KD86W2VFXVsrXT9cXGQrKT8pL2csIChtYXRjaCkgPT4ge1xuICAgICAgICBsZXQgY29sb3IgPSBjb2xvcnMubnVtYmVyQ29sb3JcbiAgICAgICAgaWYgKC9eXCIvLnRlc3QobWF0Y2gpKSB7XG4gICAgICAgICAgICBpZiAoLzokLy50ZXN0KG1hdGNoKSkge1xuICAgICAgICAgICAgICAgIGNvbG9yID0gY29sb3JzLmtleUNvbG9yXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbG9yID0gY29sb3JzLnN0cmluZ0NvbG9yO1xuICAgICAgICAgICAgICAgIG1hdGNoID0gJ1wiJyArIG1hdGNoLnN1YnN0cigxLCBtYXRjaC5sZW5ndGggLSAyKSArICdcIic7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb2xvciA9IC90cnVlLy50ZXN0KG1hdGNoKVxuICAgICAgICAgICAgICAgID8gY29sb3JzLnRydWVDb2xvclxuICAgICAgICAgICAgICAgIDogL2ZhbHNlLy50ZXN0KG1hdGNoKVxuICAgICAgICAgICAgICAgICAgICA/IGNvbG9ycy5mYWxzZUNvbG9yXG4gICAgICAgICAgICAgICAgICAgIDogL251bGwvLnRlc3QobWF0Y2gpXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGNvbG9ycy5udWxsQ29sb3JcbiAgICAgICAgICAgICAgICAgICAgICAgIDogY29sb3JcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYCR7Y29sb3J9JHttYXRjaH0ke0NvbnNvbGVDb2xvci5SZXNldH1gXG4gICAgfSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2VTcGVjaWFsQ2hhcnMoc3RyOiBzdHJpbmcsIHRvOiBzdHJpbmcgPSBcIi1cIik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3N0cn1gLnJlcGxhY2UoL1smXFwvXFxcXCMsICsoKSR+JS5AJ1wiOio/PD57fV0vZywgdG8pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVnZXhFc2NhcGUoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHtzdHJ9YC5yZXBsYWNlKC9bLVxcL1xcXFxeJCorPy4oKXxbXFxde31dL2csICdcXFxcJCYnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW4oYXJyOiBhbnlbXSk6IGFueVtdIHtcbiAgICByZXR1cm4gYXJyLnJlZHVjZSgoZmxhdCwgdG9GbGF0dGVuKSA9PiB7XG4gICAgICAgIHJldHVybiBmbGF0LmNvbmNhdChpc0FycmF5KHRvRmxhdHRlbikgPyBmbGF0dGVuKHRvRmxhdHRlbikgOiB0b0ZsYXR0ZW4pO1xuICAgIH0sIFtdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdyYXBFcnJvcihlOiBhbnksIG1lc3NhZ2U6IHN0cmluZywgaHR0cENvZGU6IG51bWJlciA9IDUwMCk6IEVycm9yIHtcbiAgICBpZiAoYXhpb3MuaXNBeGlvc0Vycm9yKGUpKSB7XG4gICAgICAgIGUubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgICAgIHJldHVybiBlO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEh0dHBFcnJvcihodHRwQ29kZSwgYCR7bWVzc2FnZX06ICR7ZX1gKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERpck5hbWUoKTogc3RyaW5nIHtcbiAgICBpZiAodHlwZW9mIF9fZGlybmFtZSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBjb25zdCBfX2ZpbGVuYW1lID0gZmlsZVVSTFRvUGF0aChpbXBvcnQubWV0YS51cmwpO1xuICAgICAgICByZXR1cm4gZGlybmFtZShfX2ZpbGVuYW1lKTtcbiAgICB9XG4gICAgcmV0dXJuIF9fZGlybmFtZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByZXBhcmVVcmwoZW5kaW5nOiBzdHJpbmcgPSBcIi9cIik6IFBhcmFtUmVzb2x2ZXIge1xuICAgIHJldHVybiB1cmwgPT4ge1xuICAgICAgICByZXR1cm4gdXJsID8gYCR7dXJsLnJlcGxhY2UoL1xcLyskLywgXCJcIil9JHtlbmRpbmd9YCA6IGVuZGluZztcbiAgICB9XG59XG5cbmV4cG9ydCBjb25zdCBwcmVwYXJlVXJsU2xhc2ggPSBwcmVwYXJlVXJsKFwiL1wiKTtcblxuZXhwb3J0IGNvbnN0IHByZXBhcmVVcmxFbXB0eSA9IHByZXBhcmVVcmwoXCJcIik7XG5cbmZ1bmN0aW9uIGNoZWNrVGV4dEZpbGVUeXBlKHR5cGU6IElGaWxlVHlwZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0eXBlLm1pbWUuaW5kZXhPZihcInRleHRcIikgPj0gMCB8fCB0eXBlLm1pbWUuaW5kZXhPZihcInhtbFwiKSA+PSAwO1xufVxuXG5mdW5jdGlvbiBmaXhUZXh0RmlsZVR5cGUodHlwZTogSUZpbGVUeXBlLCBidWZmZXI6IEJ1ZmZlcik6IElGaWxlVHlwZSB7XG4gICAgY29uc3QgdGV4dCA9IGJ1ZmZlci50b1N0cmluZyhcInV0ZjhcIik7XG4gICAgaWYgKHRleHQuaW5kZXhPZihcIjxzdmdcIikgPj0gMCkge1xuICAgICAgICByZXR1cm4ge2V4dDogXCJzdmdcIiwgbWltZTogXCJpbWFnZS9zdmcreG1sXCJ9O1xuICAgIH1cbiAgICByZXR1cm4gdHlwZTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZpbGVUeXBlRnJvbUJ1ZmZlcihidWZmZXI6IEJ1ZmZlcik6IFByb21pc2U8SUZpbGVUeXBlPiB7XG4gICAgbGV0IHR5cGU6IElGaWxlVHlwZSA9IHtleHQ6IFwidHh0XCIsIG1pbWU6IFwidGV4dC9wbGFpblwifTtcbiAgICB0cnkge1xuICAgICAgICB0eXBlID0gYXdhaXQgZmlsZVR5cGUuZnJvbUJ1ZmZlcihidWZmZXIpIHx8IHtleHQ6IFwidHh0XCIsIG1pbWU6IFwidGV4dC9wbGFpblwifTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgfVxuICAgIGlmIChjaGVja1RleHRGaWxlVHlwZSh0eXBlKSkge1xuICAgICAgICByZXR1cm4gZml4VGV4dEZpbGVUeXBlKHR5cGUsIGJ1ZmZlcik7XG4gICAgfVxuICAgIHJldHVybiB0eXBlO1xufVxuIl19
|