@f-o-t/pdf 0.1.0
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/README.md +39 -0
- package/dist/generation/index.d.ts +268 -0
- package/dist/generation/index.js +26 -0
- package/dist/index.d.ts +808 -0
- package/dist/index.js +111 -0
- package/dist/parsing/index.d.ts +234 -0
- package/dist/parsing/index.js +16 -0
- package/dist/shared/chunk-10ftnz45.js +572 -0
- package/dist/shared/chunk-37mjkw9w.js +492 -0
- package/dist/shared/chunk-6dengthp.js +48 -0
- package/package.json +88 -0
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createArray,
|
|
3
|
+
createDictionary,
|
|
4
|
+
createName,
|
|
5
|
+
createRef,
|
|
6
|
+
createStream
|
|
7
|
+
} from "./chunk-6dengthp.js";
|
|
8
|
+
|
|
9
|
+
// src/parsing/lexer.ts
|
|
10
|
+
var TokenType;
|
|
11
|
+
((TokenType2) => {
|
|
12
|
+
TokenType2["NUMBER"] = "NUMBER";
|
|
13
|
+
TokenType2["STRING"] = "STRING";
|
|
14
|
+
TokenType2["NAME"] = "NAME";
|
|
15
|
+
TokenType2["BOOLEAN"] = "BOOLEAN";
|
|
16
|
+
TokenType2["NULL"] = "NULL";
|
|
17
|
+
TokenType2["ARRAY_START"] = "ARRAY_START";
|
|
18
|
+
TokenType2["ARRAY_END"] = "ARRAY_END";
|
|
19
|
+
TokenType2["DICT_START"] = "DICT_START";
|
|
20
|
+
TokenType2["DICT_END"] = "DICT_END";
|
|
21
|
+
TokenType2["OBJ"] = "OBJ";
|
|
22
|
+
TokenType2["ENDOBJ"] = "ENDOBJ";
|
|
23
|
+
TokenType2["STREAM"] = "STREAM";
|
|
24
|
+
TokenType2["ENDSTREAM"] = "ENDSTREAM";
|
|
25
|
+
TokenType2["XREF"] = "XREF";
|
|
26
|
+
TokenType2["TRAILER"] = "TRAILER";
|
|
27
|
+
TokenType2["STARTXREF"] = "STARTXREF";
|
|
28
|
+
TokenType2["R"] = "R";
|
|
29
|
+
TokenType2["EOF"] = "EOF";
|
|
30
|
+
})(TokenType ||= {});
|
|
31
|
+
|
|
32
|
+
class PDFLexer {
|
|
33
|
+
data;
|
|
34
|
+
position = 0;
|
|
35
|
+
constructor(data) {
|
|
36
|
+
this.data = data;
|
|
37
|
+
}
|
|
38
|
+
nextToken() {
|
|
39
|
+
this.skipWhitespace();
|
|
40
|
+
if (this.position >= this.data.length) {
|
|
41
|
+
return { type: "EOF" /* EOF */, value: null, position: this.position };
|
|
42
|
+
}
|
|
43
|
+
const char = String.fromCharCode(this.data[this.position]);
|
|
44
|
+
if (char === "[") {
|
|
45
|
+
this.position++;
|
|
46
|
+
return { type: "ARRAY_START" /* ARRAY_START */, value: "[", position: this.position - 1 };
|
|
47
|
+
}
|
|
48
|
+
if (char === "]") {
|
|
49
|
+
this.position++;
|
|
50
|
+
return { type: "ARRAY_END" /* ARRAY_END */, value: "]", position: this.position - 1 };
|
|
51
|
+
}
|
|
52
|
+
if (char === "<" && this.peek() === "<") {
|
|
53
|
+
this.position += 2;
|
|
54
|
+
return { type: "DICT_START" /* DICT_START */, value: "<<", position: this.position - 2 };
|
|
55
|
+
}
|
|
56
|
+
if (char === ">" && this.peek() === ">") {
|
|
57
|
+
this.position += 2;
|
|
58
|
+
return { type: "DICT_END" /* DICT_END */, value: ">>", position: this.position - 2 };
|
|
59
|
+
}
|
|
60
|
+
if (char === "/") {
|
|
61
|
+
return this.readName();
|
|
62
|
+
}
|
|
63
|
+
if (char === "(") {
|
|
64
|
+
return this.readString();
|
|
65
|
+
}
|
|
66
|
+
if (char === "-" || char === "+" || char === "." || char >= "0" && char <= "9") {
|
|
67
|
+
return this.readNumber();
|
|
68
|
+
}
|
|
69
|
+
return this.readKeyword();
|
|
70
|
+
}
|
|
71
|
+
peek() {
|
|
72
|
+
if (this.position + 1 >= this.data.length)
|
|
73
|
+
return "";
|
|
74
|
+
return String.fromCharCode(this.data[this.position + 1]);
|
|
75
|
+
}
|
|
76
|
+
skipWhitespace() {
|
|
77
|
+
while (this.position < this.data.length) {
|
|
78
|
+
const char = this.data[this.position];
|
|
79
|
+
if (char === 32 || char === 9 || char === 10 || char === 13 || char === 0) {
|
|
80
|
+
this.position++;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (char === 37) {
|
|
84
|
+
while (this.position < this.data.length && this.data[this.position] !== 10 && this.data[this.position] !== 13) {
|
|
85
|
+
this.position++;
|
|
86
|
+
}
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
readName() {
|
|
93
|
+
const start = this.position;
|
|
94
|
+
this.position++;
|
|
95
|
+
let value = "";
|
|
96
|
+
while (this.position < this.data.length) {
|
|
97
|
+
const char = String.fromCharCode(this.data[this.position]);
|
|
98
|
+
if (this.isDelimiter(char) || this.isWhitespace(this.data[this.position])) {
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
value += char;
|
|
102
|
+
this.position++;
|
|
103
|
+
}
|
|
104
|
+
return { type: "NAME" /* NAME */, value, position: start };
|
|
105
|
+
}
|
|
106
|
+
readString() {
|
|
107
|
+
const start = this.position;
|
|
108
|
+
this.position++;
|
|
109
|
+
let value = "";
|
|
110
|
+
let depth = 1;
|
|
111
|
+
while (this.position < this.data.length && depth > 0) {
|
|
112
|
+
const char = String.fromCharCode(this.data[this.position]);
|
|
113
|
+
if (char === "\\") {
|
|
114
|
+
this.position++;
|
|
115
|
+
if (this.position < this.data.length) {
|
|
116
|
+
const escaped = String.fromCharCode(this.data[this.position]);
|
|
117
|
+
value += escaped === "n" ? `
|
|
118
|
+
` : escaped === "r" ? "\r" : escaped === "t" ? "\t" : escaped;
|
|
119
|
+
}
|
|
120
|
+
} else if (char === "(") {
|
|
121
|
+
depth++;
|
|
122
|
+
value += char;
|
|
123
|
+
} else if (char === ")") {
|
|
124
|
+
depth--;
|
|
125
|
+
if (depth > 0)
|
|
126
|
+
value += char;
|
|
127
|
+
} else {
|
|
128
|
+
value += char;
|
|
129
|
+
}
|
|
130
|
+
this.position++;
|
|
131
|
+
}
|
|
132
|
+
return { type: "STRING" /* STRING */, value, position: start };
|
|
133
|
+
}
|
|
134
|
+
readNumber() {
|
|
135
|
+
const start = this.position;
|
|
136
|
+
let value = "";
|
|
137
|
+
while (this.position < this.data.length) {
|
|
138
|
+
const char = String.fromCharCode(this.data[this.position]);
|
|
139
|
+
if (char === "-" || char === "+" || char === "." || char >= "0" && char <= "9") {
|
|
140
|
+
value += char;
|
|
141
|
+
this.position++;
|
|
142
|
+
} else {
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return { type: "NUMBER" /* NUMBER */, value: value.includes(".") ? parseFloat(value) : parseInt(value, 10), position: start };
|
|
147
|
+
}
|
|
148
|
+
readKeyword() {
|
|
149
|
+
const start = this.position;
|
|
150
|
+
let value = "";
|
|
151
|
+
while (this.position < this.data.length) {
|
|
152
|
+
const char = String.fromCharCode(this.data[this.position]);
|
|
153
|
+
if (this.isDelimiter(char) || this.isWhitespace(this.data[this.position])) {
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
value += char;
|
|
157
|
+
this.position++;
|
|
158
|
+
}
|
|
159
|
+
const upper = value.toUpperCase();
|
|
160
|
+
if (upper === "OBJ")
|
|
161
|
+
return { type: "OBJ" /* OBJ */, value, position: start };
|
|
162
|
+
if (upper === "ENDOBJ")
|
|
163
|
+
return { type: "ENDOBJ" /* ENDOBJ */, value, position: start };
|
|
164
|
+
if (upper === "STREAM")
|
|
165
|
+
return { type: "STREAM" /* STREAM */, value, position: start };
|
|
166
|
+
if (upper === "ENDSTREAM")
|
|
167
|
+
return { type: "ENDSTREAM" /* ENDSTREAM */, value, position: start };
|
|
168
|
+
if (upper === "XREF")
|
|
169
|
+
return { type: "XREF" /* XREF */, value, position: start };
|
|
170
|
+
if (upper === "TRAILER")
|
|
171
|
+
return { type: "TRAILER" /* TRAILER */, value, position: start };
|
|
172
|
+
if (upper === "STARTXREF")
|
|
173
|
+
return { type: "STARTXREF" /* STARTXREF */, value, position: start };
|
|
174
|
+
if (upper === "R")
|
|
175
|
+
return { type: "R" /* R */, value, position: start };
|
|
176
|
+
if (upper === "TRUE")
|
|
177
|
+
return { type: "BOOLEAN" /* BOOLEAN */, value: true, position: start };
|
|
178
|
+
if (upper === "FALSE")
|
|
179
|
+
return { type: "BOOLEAN" /* BOOLEAN */, value: false, position: start };
|
|
180
|
+
if (upper === "NULL")
|
|
181
|
+
return { type: "NULL" /* NULL */, value: null, position: start };
|
|
182
|
+
return { type: "NAME" /* NAME */, value, position: start };
|
|
183
|
+
}
|
|
184
|
+
isDelimiter(char) {
|
|
185
|
+
return ["(", ")", "<", ">", "[", "]", "{", "}", "/", "%"].includes(char);
|
|
186
|
+
}
|
|
187
|
+
isWhitespace(byte) {
|
|
188
|
+
return byte === 32 || byte === 9 || byte === 10 || byte === 13 || byte === 0;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// src/parsing/parser.ts
|
|
192
|
+
class PDFParser {
|
|
193
|
+
lexer;
|
|
194
|
+
currentToken;
|
|
195
|
+
nextToken = null;
|
|
196
|
+
data;
|
|
197
|
+
constructor(data) {
|
|
198
|
+
this.data = data;
|
|
199
|
+
this.lexer = new PDFLexer(data);
|
|
200
|
+
this.currentToken = this.lexer.nextToken();
|
|
201
|
+
}
|
|
202
|
+
parseValue() {
|
|
203
|
+
switch (this.currentToken.type) {
|
|
204
|
+
case "NUMBER" /* NUMBER */:
|
|
205
|
+
return this.parseNumberOrRef();
|
|
206
|
+
case "STRING" /* STRING */:
|
|
207
|
+
return this.parseString();
|
|
208
|
+
case "NAME" /* NAME */:
|
|
209
|
+
return this.parseName();
|
|
210
|
+
case "BOOLEAN" /* BOOLEAN */:
|
|
211
|
+
return this.parseBoolean();
|
|
212
|
+
case "NULL" /* NULL */:
|
|
213
|
+
return this.parseNull();
|
|
214
|
+
case "ARRAY_START" /* ARRAY_START */:
|
|
215
|
+
return this.parseArray();
|
|
216
|
+
case "DICT_START" /* DICT_START */:
|
|
217
|
+
return this.parseDictionary();
|
|
218
|
+
default:
|
|
219
|
+
throw new Error(`Unexpected token: ${this.currentToken.type}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
parseNumberOrRef() {
|
|
223
|
+
const first = this.currentToken.value;
|
|
224
|
+
this.advance();
|
|
225
|
+
if (this.currentToken.type === "NUMBER" /* NUMBER */) {
|
|
226
|
+
const second = this.currentToken.value;
|
|
227
|
+
this.advance();
|
|
228
|
+
if (this.currentToken.type === "R" /* R */) {
|
|
229
|
+
this.advance();
|
|
230
|
+
return createRef(first, second);
|
|
231
|
+
}
|
|
232
|
+
const thirdToken = this.currentToken;
|
|
233
|
+
this.currentToken = { type: "NUMBER" /* NUMBER */, value: second, position: 0 };
|
|
234
|
+
this.nextToken = thirdToken;
|
|
235
|
+
return first;
|
|
236
|
+
}
|
|
237
|
+
return first;
|
|
238
|
+
}
|
|
239
|
+
parseString() {
|
|
240
|
+
const value = this.currentToken.value;
|
|
241
|
+
this.advance();
|
|
242
|
+
return value;
|
|
243
|
+
}
|
|
244
|
+
parseName() {
|
|
245
|
+
const value = this.currentToken.value;
|
|
246
|
+
this.advance();
|
|
247
|
+
return createName(value);
|
|
248
|
+
}
|
|
249
|
+
parseBoolean() {
|
|
250
|
+
const value = this.currentToken.value;
|
|
251
|
+
this.advance();
|
|
252
|
+
return value;
|
|
253
|
+
}
|
|
254
|
+
parseNull() {
|
|
255
|
+
this.advance();
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
parseArray() {
|
|
259
|
+
this.advance();
|
|
260
|
+
const values = [];
|
|
261
|
+
while (this.currentToken.type !== "ARRAY_END" /* ARRAY_END */) {
|
|
262
|
+
if (this.currentToken.type === "EOF" /* EOF */) {
|
|
263
|
+
throw new Error("Unexpected EOF in array");
|
|
264
|
+
}
|
|
265
|
+
values.push(this.parseValue());
|
|
266
|
+
}
|
|
267
|
+
this.advance();
|
|
268
|
+
return createArray(values);
|
|
269
|
+
}
|
|
270
|
+
parseDictionary() {
|
|
271
|
+
this.advance();
|
|
272
|
+
const entries = {};
|
|
273
|
+
while (this.currentToken.type !== "DICT_END" /* DICT_END */) {
|
|
274
|
+
if (this.currentToken.type === "EOF" /* EOF */) {
|
|
275
|
+
throw new Error("Unexpected EOF in dictionary");
|
|
276
|
+
}
|
|
277
|
+
if (this.currentToken.type !== "NAME" /* NAME */) {
|
|
278
|
+
throw new Error(`Expected name in dictionary, got ${this.currentToken.type}`);
|
|
279
|
+
}
|
|
280
|
+
const key = this.currentToken.value;
|
|
281
|
+
this.advance();
|
|
282
|
+
const value = this.parseValue();
|
|
283
|
+
entries[key] = value;
|
|
284
|
+
}
|
|
285
|
+
this.advance();
|
|
286
|
+
return createDictionary(entries);
|
|
287
|
+
}
|
|
288
|
+
parseIndirectObject() {
|
|
289
|
+
if (this.currentToken.type !== "NUMBER" /* NUMBER */) {
|
|
290
|
+
throw new Error("Expected object number");
|
|
291
|
+
}
|
|
292
|
+
const objectNumber = this.currentToken.value;
|
|
293
|
+
this.advance();
|
|
294
|
+
if (this.currentToken.type !== "NUMBER" /* NUMBER */) {
|
|
295
|
+
throw new Error("Expected generation number");
|
|
296
|
+
}
|
|
297
|
+
const generation = this.currentToken.value;
|
|
298
|
+
this.advance();
|
|
299
|
+
if (this.currentToken.type !== "OBJ" /* OBJ */) {
|
|
300
|
+
throw new Error("Expected 'obj' keyword");
|
|
301
|
+
}
|
|
302
|
+
this.advance();
|
|
303
|
+
let value = this.parseValue();
|
|
304
|
+
if (this.currentToken.type === "STREAM" /* STREAM */) {
|
|
305
|
+
value = this.parseStream(value);
|
|
306
|
+
}
|
|
307
|
+
if (this.currentToken.type !== "ENDOBJ" /* ENDOBJ */) {
|
|
308
|
+
throw new Error("Expected 'endobj' keyword");
|
|
309
|
+
}
|
|
310
|
+
this.advance();
|
|
311
|
+
return {
|
|
312
|
+
ref: createRef(objectNumber, generation),
|
|
313
|
+
value
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
parseStream(dictionary) {
|
|
317
|
+
const streamKeywordPos = this.currentToken.position;
|
|
318
|
+
this.advance();
|
|
319
|
+
let streamDataStart = streamKeywordPos + 6;
|
|
320
|
+
while (streamDataStart < this.data.length) {
|
|
321
|
+
const byte = this.data[streamDataStart];
|
|
322
|
+
if (byte === 13 || byte === 10) {
|
|
323
|
+
streamDataStart++;
|
|
324
|
+
if (byte === 13 && this.data[streamDataStart] === 10) {
|
|
325
|
+
streamDataStart++;
|
|
326
|
+
}
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
streamDataStart++;
|
|
330
|
+
}
|
|
331
|
+
const length = dictionary.Length;
|
|
332
|
+
if (typeof length !== "number") {
|
|
333
|
+
throw new Error("Stream dictionary missing Length");
|
|
334
|
+
}
|
|
335
|
+
const data = this.data.slice(streamDataStart, streamDataStart + length);
|
|
336
|
+
while (this.currentToken.type !== "ENDSTREAM" /* ENDSTREAM */ && this.currentToken.type !== "EOF" /* EOF */) {
|
|
337
|
+
this.advance();
|
|
338
|
+
}
|
|
339
|
+
if (this.currentToken.type !== "ENDSTREAM" /* ENDSTREAM */) {
|
|
340
|
+
throw new Error("Expected 'endstream' keyword");
|
|
341
|
+
}
|
|
342
|
+
this.advance();
|
|
343
|
+
return createStream(data, dictionary);
|
|
344
|
+
}
|
|
345
|
+
advance() {
|
|
346
|
+
if (this.nextToken !== null) {
|
|
347
|
+
this.currentToken = this.nextToken;
|
|
348
|
+
this.nextToken = null;
|
|
349
|
+
} else {
|
|
350
|
+
this.currentToken = this.lexer.nextToken();
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
hasMore() {
|
|
354
|
+
return this.currentToken.type !== "EOF" /* EOF */;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// src/errors.ts
|
|
358
|
+
class PDFError extends Error {
|
|
359
|
+
constructor(message) {
|
|
360
|
+
super(message);
|
|
361
|
+
this.name = "PDFError";
|
|
362
|
+
if (Error.captureStackTrace) {
|
|
363
|
+
Error.captureStackTrace(this, this.constructor);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
class PDFParseError extends PDFError {
|
|
369
|
+
offset;
|
|
370
|
+
constructor(message, offset) {
|
|
371
|
+
super(message);
|
|
372
|
+
this.offset = offset;
|
|
373
|
+
this.name = "PDFParseError";
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
class PDFGenerationError extends PDFError {
|
|
378
|
+
constructor(message) {
|
|
379
|
+
super(message);
|
|
380
|
+
this.name = "PDFGenerationError";
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
class InvalidPDFObjectError extends PDFError {
|
|
385
|
+
objectType;
|
|
386
|
+
constructor(objectType, reason) {
|
|
387
|
+
super(`Invalid ${objectType}: ${reason}`);
|
|
388
|
+
this.objectType = objectType;
|
|
389
|
+
this.name = "InvalidPDFObjectError";
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
class FontNotFoundError extends PDFError {
|
|
394
|
+
fontName;
|
|
395
|
+
constructor(fontName) {
|
|
396
|
+
super(`Font not found: ${fontName}`);
|
|
397
|
+
this.fontName = fontName;
|
|
398
|
+
this.name = "FontNotFoundError";
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
class InvalidImageError extends PDFError {
|
|
403
|
+
constructor(reason) {
|
|
404
|
+
super(`Invalid image: ${reason}`);
|
|
405
|
+
this.name = "InvalidImageError";
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
class PDFSignatureError extends PDFError {
|
|
410
|
+
constructor(reason) {
|
|
411
|
+
super(`PDF signature error: ${reason}`);
|
|
412
|
+
this.name = "PDFSignatureError";
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
class PDFEncryptionError extends PDFError {
|
|
417
|
+
constructor(reason) {
|
|
418
|
+
super(`PDF encryption error: ${reason}`);
|
|
419
|
+
this.name = "PDFEncryptionError";
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
class NotImplementedError extends PDFError {
|
|
424
|
+
constructor(feature) {
|
|
425
|
+
super(`Feature not yet implemented: ${feature}`);
|
|
426
|
+
this.name = "NotImplementedError";
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// src/parsing/reader.ts
|
|
431
|
+
class PDFReader {
|
|
432
|
+
data;
|
|
433
|
+
objects = new Map;
|
|
434
|
+
constructor(data) {
|
|
435
|
+
this.data = data;
|
|
436
|
+
}
|
|
437
|
+
parse() {
|
|
438
|
+
const xrefOffset = this.findStartXRef();
|
|
439
|
+
const xrefTable = this.parseXRefTable(xrefOffset);
|
|
440
|
+
const trailer = this.parseTrailer(xrefOffset);
|
|
441
|
+
const catalogRef = trailer.Root;
|
|
442
|
+
this.readObjects(xrefTable);
|
|
443
|
+
const version = this.parseVersion();
|
|
444
|
+
const pages = this.parsePages(catalogRef);
|
|
445
|
+
return {
|
|
446
|
+
version,
|
|
447
|
+
catalog: catalogRef,
|
|
448
|
+
pages,
|
|
449
|
+
objects: this.objects
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
findStartXRef() {
|
|
453
|
+
const decoder = new TextDecoder;
|
|
454
|
+
const content = decoder.decode(this.data);
|
|
455
|
+
const match = content.match(/startxref\s+(\d+)/);
|
|
456
|
+
if (!match) {
|
|
457
|
+
throw new PDFParseError("Could not find startxref");
|
|
458
|
+
}
|
|
459
|
+
return parseInt(match[1], 10);
|
|
460
|
+
}
|
|
461
|
+
parseXRefTable(offset) {
|
|
462
|
+
const decoder = new TextDecoder;
|
|
463
|
+
const content = decoder.decode(this.data.slice(offset));
|
|
464
|
+
const lines = content.split(`
|
|
465
|
+
`);
|
|
466
|
+
const xref = new Map;
|
|
467
|
+
let i = 0;
|
|
468
|
+
while (i < lines.length && !lines[i].trim().startsWith("xref"))
|
|
469
|
+
i++;
|
|
470
|
+
i++;
|
|
471
|
+
while (i < lines.length && !lines[i].trim().startsWith("trailer")) {
|
|
472
|
+
const subsection = lines[i].trim().split(/\s+/);
|
|
473
|
+
if (subsection.length === 2) {
|
|
474
|
+
const start = parseInt(subsection[0], 10);
|
|
475
|
+
const count = parseInt(subsection[1], 10);
|
|
476
|
+
i++;
|
|
477
|
+
for (let j = 0;j < count; j++) {
|
|
478
|
+
const entry = lines[i].trim().split(/\s+/);
|
|
479
|
+
if (entry.length >= 3 && entry[2] === "n") {
|
|
480
|
+
const offset2 = parseInt(entry[0], 10);
|
|
481
|
+
xref.set(start + j, offset2);
|
|
482
|
+
}
|
|
483
|
+
i++;
|
|
484
|
+
}
|
|
485
|
+
} else {
|
|
486
|
+
i++;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
return xref;
|
|
490
|
+
}
|
|
491
|
+
parseTrailer(xrefOffset) {
|
|
492
|
+
const decoder = new TextDecoder;
|
|
493
|
+
const content = decoder.decode(this.data.slice(xrefOffset));
|
|
494
|
+
const trailerMatch = content.match(/trailer\s*<<[\s\S]*?>>/);
|
|
495
|
+
if (!trailerMatch) {
|
|
496
|
+
throw new PDFParseError("Could not find trailer");
|
|
497
|
+
}
|
|
498
|
+
const parser = new PDFParser(new TextEncoder().encode(trailerMatch[0].replace("trailer", "")));
|
|
499
|
+
return parser.parseValue();
|
|
500
|
+
}
|
|
501
|
+
readObjects(xrefTable) {
|
|
502
|
+
for (const [objectNum, offset] of xrefTable) {
|
|
503
|
+
try {
|
|
504
|
+
const objData = this.data.slice(offset);
|
|
505
|
+
const parser = new PDFParser(objData);
|
|
506
|
+
const obj = parser.parseIndirectObject();
|
|
507
|
+
this.objects.set(objectNum, obj.value);
|
|
508
|
+
} catch (error) {}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
parseVersion() {
|
|
512
|
+
const decoder = new TextDecoder;
|
|
513
|
+
const header = decoder.decode(this.data.slice(0, 20));
|
|
514
|
+
const match = header.match(/%PDF-(\d+\.\d+)/);
|
|
515
|
+
return match ? match[1] : "1.7";
|
|
516
|
+
}
|
|
517
|
+
parsePages(catalogRef) {
|
|
518
|
+
const catalog = this.objects.get(catalogRef.objectNumber);
|
|
519
|
+
if (!catalog) {
|
|
520
|
+
throw new PDFParseError("Catalog not found");
|
|
521
|
+
}
|
|
522
|
+
const pagesRef = catalog.Pages;
|
|
523
|
+
const pagesTree = this.objects.get(pagesRef.objectNumber);
|
|
524
|
+
if (!pagesTree) {
|
|
525
|
+
throw new PDFParseError("Pages tree not found");
|
|
526
|
+
}
|
|
527
|
+
const kids = pagesTree.Kids;
|
|
528
|
+
const pages = [];
|
|
529
|
+
for (const kidRef of kids) {
|
|
530
|
+
if (typeof kidRef === "object" && "objectNumber" in kidRef) {
|
|
531
|
+
const page = this.parsePage(kidRef);
|
|
532
|
+
if (page)
|
|
533
|
+
pages.push(page);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return pages;
|
|
537
|
+
}
|
|
538
|
+
parsePage(ref) {
|
|
539
|
+
const pageDict = this.objects.get(ref.objectNumber);
|
|
540
|
+
if (!pageDict)
|
|
541
|
+
return null;
|
|
542
|
+
const mediaBox = pageDict.MediaBox;
|
|
543
|
+
const size = {
|
|
544
|
+
width: mediaBox[2],
|
|
545
|
+
height: mediaBox[3]
|
|
546
|
+
};
|
|
547
|
+
let content = "";
|
|
548
|
+
const contentsRef = pageDict.Contents;
|
|
549
|
+
if (contentsRef && typeof contentsRef === "object" && "objectNumber" in contentsRef) {
|
|
550
|
+
content = this.extractText(contentsRef);
|
|
551
|
+
}
|
|
552
|
+
return { ref, size, content };
|
|
553
|
+
}
|
|
554
|
+
extractText(ref) {
|
|
555
|
+
const stream = this.objects.get(ref.objectNumber);
|
|
556
|
+
if (!stream || !stream.data)
|
|
557
|
+
return "";
|
|
558
|
+
const decoder = new TextDecoder;
|
|
559
|
+
const content = decoder.decode(stream.data);
|
|
560
|
+
const texts = [];
|
|
561
|
+
const regex = /\(([^)]*)\)\s*Tj/g;
|
|
562
|
+
let match;
|
|
563
|
+
while ((match = regex.exec(content)) !== null) {
|
|
564
|
+
texts.push(match[1]);
|
|
565
|
+
}
|
|
566
|
+
return texts.join(" ");
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
export { PDFError, PDFParseError, PDFGenerationError, InvalidPDFObjectError, FontNotFoundError, InvalidImageError, PDFSignatureError, PDFEncryptionError, NotImplementedError, TokenType, PDFLexer, PDFParser, PDFReader };
|
|
570
|
+
|
|
571
|
+
//# debugId=2D25678A9DC8958E64756E2164756E21
|
|
572
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL3BhcnNpbmcvbGV4ZXIudHMiLCAic3JjL3BhcnNpbmcvcGFyc2VyLnRzIiwgInNyYy9lcnJvcnMudHMiLCAic3JjL3BhcnNpbmcvcmVhZGVyLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgIi8qKlxuICogUERGIHRva2VuIHR5cGVzXG4gKi9cbmV4cG9ydCBlbnVtIFRva2VuVHlwZSB7XG4gICAvLyBQcmltaXRpdmVzXG4gICBOVU1CRVIgPSBcIk5VTUJFUlwiLFxuICAgU1RSSU5HID0gXCJTVFJJTkdcIixcbiAgIE5BTUUgPSBcIk5BTUVcIixcbiAgIEJPT0xFQU4gPSBcIkJPT0xFQU5cIixcbiAgIE5VTEwgPSBcIk5VTExcIixcblxuICAgLy8gRGVsaW1pdGVyc1xuICAgQVJSQVlfU1RBUlQgPSBcIkFSUkFZX1NUQVJUXCIsICAgICAvLyBbXG4gICBBUlJBWV9FTkQgPSBcIkFSUkFZX0VORFwiLCAgICAgICAgIC8vIF1cbiAgIERJQ1RfU1RBUlQgPSBcIkRJQ1RfU1RBUlRcIiwgICAgICAgLy8gPDxcbiAgIERJQ1RfRU5EID0gXCJESUNUX0VORFwiLCAgICAgICAgICAgLy8gPj5cblxuICAgLy8gS2V5d29yZHNcbiAgIE9CSiA9IFwiT0JKXCIsICAgICAgICAgICAgICAgICAgICAgLy8gb2JqXG4gICBFTkRPQkogPSBcIkVORE9CSlwiLCAgICAgICAgICAgICAgIC8vIGVuZG9ialxuICAgU1RSRUFNID0gXCJTVFJFQU1cIiwgICAgICAgICAgICAgICAvLyBzdHJlYW1cbiAgIEVORFNUUkVBTSA9IFwiRU5EU1RSRUFNXCIsICAgICAgICAgLy8gZW5kc3RyZWFtXG4gICBYUkVGID0gXCJYUkVGXCIsICAgICAgICAgICAgICAgICAgIC8vIHhyZWZcbiAgIFRSQUlMRVIgPSBcIlRSQUlMRVJcIiwgICAgICAgICAgICAgLy8gdHJhaWxlclxuICAgU1RBUlRYUkVGID0gXCJTVEFSVFhSRUZcIiwgICAgICAgICAvLyBzdGFydHhyZWZcbiAgIFIgPSBcIlJcIiwgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUiAocmVmZXJlbmNlKVxuXG4gICAvLyBTcGVjaWFsXG4gICBFT0YgPSBcIkVPRlwiLFxufVxuXG4vKipcbiAqIFBERiB0b2tlblxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRva2VuIHtcbiAgIHR5cGU6IFRva2VuVHlwZTtcbiAgIHZhbHVlOiBhbnk7XG4gICBwb3NpdGlvbjogbnVtYmVyO1xufVxuXG4vKipcbiAqIFBERiBMZXhlclxuICovXG5leHBvcnQgY2xhc3MgUERGTGV4ZXIge1xuICAgcHJpdmF0ZSBkYXRhOiBVaW50OEFycmF5O1xuICAgcHJpdmF0ZSBwb3NpdGlvbjogbnVtYmVyID0gMDtcblxuICAgY29uc3RydWN0b3IoZGF0YTogVWludDhBcnJheSkge1xuICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBHZXQgbmV4dCB0b2tlblxuICAgICovXG4gICBuZXh0VG9rZW4oKTogVG9rZW4ge1xuICAgICAgdGhpcy5za2lwV2hpdGVzcGFjZSgpO1xuXG4gICAgICBpZiAodGhpcy5wb3NpdGlvbiA+PSB0aGlzLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgICByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuRU9GLCB2YWx1ZTogbnVsbCwgcG9zaXRpb246IHRoaXMucG9zaXRpb24gfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hhciA9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5kYXRhW3RoaXMucG9zaXRpb25dKTtcblxuICAgICAgLy8gRGVsaW1pdGVyc1xuICAgICAgaWYgKGNoYXIgPT09IFwiW1wiKSB7XG4gICAgICAgICB0aGlzLnBvc2l0aW9uKys7XG4gICAgICAgICByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuQVJSQVlfU1RBUlQsIHZhbHVlOiBcIltcIiwgcG9zaXRpb246IHRoaXMucG9zaXRpb24gLSAxIH07XG4gICAgICB9XG4gICAgICBpZiAoY2hhciA9PT0gXCJdXCIpIHtcbiAgICAgICAgIHRoaXMucG9zaXRpb24rKztcbiAgICAgICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5BUlJBWV9FTkQsIHZhbHVlOiBcIl1cIiwgcG9zaXRpb246IHRoaXMucG9zaXRpb24gLSAxIH07XG4gICAgICB9XG4gICAgICBpZiAoY2hhciA9PT0gXCI8XCIgJiYgdGhpcy5wZWVrKCkgPT09IFwiPFwiKSB7XG4gICAgICAgICB0aGlzLnBvc2l0aW9uICs9IDI7XG4gICAgICAgICByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuRElDVF9TVEFSVCwgdmFsdWU6IFwiPDxcIiwgcG9zaXRpb246IHRoaXMucG9zaXRpb24gLSAyIH07XG4gICAgICB9XG4gICAgICBpZiAoY2hhciA9PT0gXCI+XCIgJiYgdGhpcy5wZWVrKCkgPT09IFwiPlwiKSB7XG4gICAgICAgICB0aGlzLnBvc2l0aW9uICs9IDI7XG4gICAgICAgICByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuRElDVF9FTkQsIHZhbHVlOiBcIj4+XCIsIHBvc2l0aW9uOiB0aGlzLnBvc2l0aW9uIC0gMiB9O1xuICAgICAgfVxuXG4gICAgICAvLyBOYW1lIChzdGFydHMgd2l0aCAvKVxuICAgICAgaWYgKGNoYXIgPT09IFwiL1wiKSB7XG4gICAgICAgICByZXR1cm4gdGhpcy5yZWFkTmFtZSgpO1xuICAgICAgfVxuXG4gICAgICAvLyBTdHJpbmcgKHN0YXJ0cyB3aXRoICgpXG4gICAgICBpZiAoY2hhciA9PT0gXCIoXCIpIHtcbiAgICAgICAgIHJldHVybiB0aGlzLnJlYWRTdHJpbmcoKTtcbiAgICAgIH1cblxuICAgICAgLy8gTnVtYmVyIG9yIGtleXdvcmRcbiAgICAgIGlmIChjaGFyID09PSBcIi1cIiB8fCBjaGFyID09PSBcIitcIiB8fCBjaGFyID09PSBcIi5cIiB8fCAoY2hhciA+PSBcIjBcIiAmJiBjaGFyIDw9IFwiOVwiKSkge1xuICAgICAgICAgcmV0dXJuIHRoaXMucmVhZE51bWJlcigpO1xuICAgICAgfVxuXG4gICAgICAvLyBLZXl3b3JkIG9yIGJvb2xlYW5cbiAgICAgIHJldHVybiB0aGlzLnJlYWRLZXl3b3JkKCk7XG4gICB9XG5cbiAgIC8qKlxuICAgICogUGVlayBhdCBuZXh0IGNoYXJhY3RlciB3aXRob3V0IGNvbnN1bWluZ1xuICAgICovXG4gICBwcml2YXRlIHBlZWsoKTogc3RyaW5nIHtcbiAgICAgIGlmICh0aGlzLnBvc2l0aW9uICsgMSA+PSB0aGlzLmRhdGEubGVuZ3RoKSByZXR1cm4gXCJcIjtcbiAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uICsgMV0pO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFNraXAgd2hpdGVzcGFjZSBhbmQgY29tbWVudHNcbiAgICAqL1xuICAgcHJpdmF0ZSBza2lwV2hpdGVzcGFjZSgpOiB2b2lkIHtcbiAgICAgIHdoaWxlICh0aGlzLnBvc2l0aW9uIDwgdGhpcy5kYXRhLmxlbmd0aCkge1xuICAgICAgICAgY29uc3QgY2hhciA9IHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uXTtcblxuICAgICAgICAgLy8gV2hpdGVzcGFjZVxuICAgICAgICAgaWYgKGNoYXIgPT09IDB4MjAgfHwgY2hhciA9PT0gMHgwOSB8fCBjaGFyID09PSAweDBBIHx8IGNoYXIgPT09IDB4MEQgfHwgY2hhciA9PT0gMHgwMCkge1xuICAgICAgICAgICAgdGhpcy5wb3NpdGlvbisrO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICB9XG5cbiAgICAgICAgIC8vIENvbW1lbnQgKHN0YXJ0cyB3aXRoICUpXG4gICAgICAgICBpZiAoY2hhciA9PT0gMHgyNSkge1xuICAgICAgICAgICAgd2hpbGUgKHRoaXMucG9zaXRpb24gPCB0aGlzLmRhdGEubGVuZ3RoICYmIHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uXSAhPT0gMHgwQSAmJiB0aGlzLmRhdGFbdGhpcy5wb3NpdGlvbl0gIT09IDB4MEQpIHtcbiAgICAgICAgICAgICAgIHRoaXMucG9zaXRpb24rKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgfVxuXG4gICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgIH1cblxuICAgLyoqXG4gICAgKiBSZWFkIGEgbmFtZSB0b2tlblxuICAgICovXG4gICBwcml2YXRlIHJlYWROYW1lKCk6IFRva2VuIHtcbiAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5wb3NpdGlvbjtcbiAgICAgIHRoaXMucG9zaXRpb24rKzsgLy8gU2tpcCAvXG5cbiAgICAgIGxldCB2YWx1ZSA9IFwiXCI7XG4gICAgICB3aGlsZSAodGhpcy5wb3NpdGlvbiA8IHRoaXMuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgIGNvbnN0IGNoYXIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uXSk7XG4gICAgICAgICBpZiAodGhpcy5pc0RlbGltaXRlcihjaGFyKSB8fCB0aGlzLmlzV2hpdGVzcGFjZSh0aGlzLmRhdGFbdGhpcy5wb3NpdGlvbl0pKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgIH1cbiAgICAgICAgIHZhbHVlICs9IGNoYXI7XG4gICAgICAgICB0aGlzLnBvc2l0aW9uKys7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5OQU1FLCB2YWx1ZSwgcG9zaXRpb246IHN0YXJ0IH07XG4gICB9XG5cbiAgIC8qKlxuICAgICogUmVhZCBhIHN0cmluZyB0b2tlblxuICAgICovXG4gICBwcml2YXRlIHJlYWRTdHJpbmcoKTogVG9rZW4ge1xuICAgICAgY29uc3Qgc3RhcnQgPSB0aGlzLnBvc2l0aW9uO1xuICAgICAgdGhpcy5wb3NpdGlvbisrOyAvLyBTa2lwIChcblxuICAgICAgbGV0IHZhbHVlID0gXCJcIjtcbiAgICAgIGxldCBkZXB0aCA9IDE7XG5cbiAgICAgIHdoaWxlICh0aGlzLnBvc2l0aW9uIDwgdGhpcy5kYXRhLmxlbmd0aCAmJiBkZXB0aCA+IDApIHtcbiAgICAgICAgIGNvbnN0IGNoYXIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uXSk7XG5cbiAgICAgICAgIGlmIChjaGFyID09PSBcIlxcXFxcIikge1xuICAgICAgICAgICAgLy8gRXNjYXBlIHNlcXVlbmNlXG4gICAgICAgICAgICB0aGlzLnBvc2l0aW9uKys7XG4gICAgICAgICAgICBpZiAodGhpcy5wb3NpdGlvbiA8IHRoaXMuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgIGNvbnN0IGVzY2FwZWQgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uXSk7XG4gICAgICAgICAgICAgICB2YWx1ZSArPSBlc2NhcGVkID09PSBcIm5cIiA/IFwiXFxuXCIgOiBlc2NhcGVkID09PSBcInJcIiA/IFwiXFxyXCIgOiBlc2NhcGVkID09PSBcInRcIiA/IFwiXFx0XCIgOiBlc2NhcGVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgfSBlbHNlIGlmIChjaGFyID09PSBcIihcIikge1xuICAgICAgICAgICAgZGVwdGgrKztcbiAgICAgICAgICAgIHZhbHVlICs9IGNoYXI7XG4gICAgICAgICB9IGVsc2UgaWYgKGNoYXIgPT09IFwiKVwiKSB7XG4gICAgICAgICAgICBkZXB0aC0tO1xuICAgICAgICAgICAgaWYgKGRlcHRoID4gMCkgdmFsdWUgKz0gY2hhcjtcbiAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZSArPSBjaGFyO1xuICAgICAgICAgfVxuXG4gICAgICAgICB0aGlzLnBvc2l0aW9uKys7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5TVFJJTkcsIHZhbHVlLCBwb3NpdGlvbjogc3RhcnQgfTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBSZWFkIGEgbnVtYmVyIHRva2VuXG4gICAgKi9cbiAgIHByaXZhdGUgcmVhZE51bWJlcigpOiBUb2tlbiB7XG4gICAgICBjb25zdCBzdGFydCA9IHRoaXMucG9zaXRpb247XG4gICAgICBsZXQgdmFsdWUgPSBcIlwiO1xuXG4gICAgICB3aGlsZSAodGhpcy5wb3NpdGlvbiA8IHRoaXMuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgIGNvbnN0IGNoYXIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uXSk7XG4gICAgICAgICBpZiAoY2hhciA9PT0gXCItXCIgfHwgY2hhciA9PT0gXCIrXCIgfHwgY2hhciA9PT0gXCIuXCIgfHwgKGNoYXIgPj0gXCIwXCIgJiYgY2hhciA8PSBcIjlcIikpIHtcbiAgICAgICAgICAgIHZhbHVlICs9IGNoYXI7XG4gICAgICAgICAgICB0aGlzLnBvc2l0aW9uKys7XG4gICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5OVU1CRVIsIHZhbHVlOiB2YWx1ZS5pbmNsdWRlcyhcIi5cIikgPyBwYXJzZUZsb2F0KHZhbHVlKSA6IHBhcnNlSW50KHZhbHVlLCAxMCksIHBvc2l0aW9uOiBzdGFydCB9O1xuICAgfVxuXG4gICAvKipcbiAgICAqIFJlYWQgYSBrZXl3b3JkIHRva2VuXG4gICAgKi9cbiAgIHByaXZhdGUgcmVhZEtleXdvcmQoKTogVG9rZW4ge1xuICAgICAgY29uc3Qgc3RhcnQgPSB0aGlzLnBvc2l0aW9uO1xuICAgICAgbGV0IHZhbHVlID0gXCJcIjtcblxuICAgICAgd2hpbGUgKHRoaXMucG9zaXRpb24gPCB0aGlzLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgICBjb25zdCBjaGFyID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLmRhdGFbdGhpcy5wb3NpdGlvbl0pO1xuICAgICAgICAgaWYgKHRoaXMuaXNEZWxpbWl0ZXIoY2hhcikgfHwgdGhpcy5pc1doaXRlc3BhY2UodGhpcy5kYXRhW3RoaXMucG9zaXRpb25dKSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICB9XG4gICAgICAgICB2YWx1ZSArPSBjaGFyO1xuICAgICAgICAgdGhpcy5wb3NpdGlvbisrO1xuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBmb3Iga2V5d29yZHNcbiAgICAgIGNvbnN0IHVwcGVyID0gdmFsdWUudG9VcHBlckNhc2UoKTtcbiAgICAgIGlmICh1cHBlciA9PT0gXCJPQkpcIikgcmV0dXJuIHsgdHlwZTogVG9rZW5UeXBlLk9CSiwgdmFsdWUsIHBvc2l0aW9uOiBzdGFydCB9O1xuICAgICAgaWYgKHVwcGVyID09PSBcIkVORE9CSlwiKSByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuRU5ET0JKLCB2YWx1ZSwgcG9zaXRpb246IHN0YXJ0IH07XG4gICAgICBpZiAodXBwZXIgPT09IFwiU1RSRUFNXCIpIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5TVFJFQU0sIHZhbHVlLCBwb3NpdGlvbjogc3RhcnQgfTtcbiAgICAgIGlmICh1cHBlciA9PT0gXCJFTkRTVFJFQU1cIikgcmV0dXJuIHsgdHlwZTogVG9rZW5UeXBlLkVORFNUUkVBTSwgdmFsdWUsIHBvc2l0aW9uOiBzdGFydCB9O1xuICAgICAgaWYgKHVwcGVyID09PSBcIlhSRUZcIikgcmV0dXJuIHsgdHlwZTogVG9rZW5UeXBlLlhSRUYsIHZhbHVlLCBwb3NpdGlvbjogc3RhcnQgfTtcbiAgICAgIGlmICh1cHBlciA9PT0gXCJUUkFJTEVSXCIpIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5UUkFJTEVSLCB2YWx1ZSwgcG9zaXRpb246IHN0YXJ0IH07XG4gICAgICBpZiAodXBwZXIgPT09IFwiU1RBUlRYUkVGXCIpIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5TVEFSVFhSRUYsIHZhbHVlLCBwb3NpdGlvbjogc3RhcnQgfTtcbiAgICAgIGlmICh1cHBlciA9PT0gXCJSXCIpIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5SLCB2YWx1ZSwgcG9zaXRpb246IHN0YXJ0IH07XG4gICAgICBpZiAodXBwZXIgPT09IFwiVFJVRVwiKSByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuQk9PTEVBTiwgdmFsdWU6IHRydWUsIHBvc2l0aW9uOiBzdGFydCB9O1xuICAgICAgaWYgKHVwcGVyID09PSBcIkZBTFNFXCIpIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5CT09MRUFOLCB2YWx1ZTogZmFsc2UsIHBvc2l0aW9uOiBzdGFydCB9O1xuICAgICAgaWYgKHVwcGVyID09PSBcIk5VTExcIikgcmV0dXJuIHsgdHlwZTogVG9rZW5UeXBlLk5VTEwsIHZhbHVlOiBudWxsLCBwb3NpdGlvbjogc3RhcnQgfTtcblxuICAgICAgLy8gVW5rbm93biBrZXl3b3JkIC0gdHJlYXQgYXMgbmFtZSB3aXRob3V0IC9cbiAgICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5OQU1FLCB2YWx1ZSwgcG9zaXRpb246IHN0YXJ0IH07XG4gICB9XG5cbiAgIC8qKlxuICAgICogQ2hlY2sgaWYgY2hhcmFjdGVyIGlzIGRlbGltaXRlclxuICAgICovXG4gICBwcml2YXRlIGlzRGVsaW1pdGVyKGNoYXI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIFtcIihcIiwgXCIpXCIsIFwiPFwiLCBcIj5cIiwgXCJbXCIsIFwiXVwiLCBcIntcIiwgXCJ9XCIsIFwiL1wiLCBcIiVcIl0uaW5jbHVkZXMoY2hhcik7XG4gICB9XG5cbiAgIC8qKlxuICAgICogQ2hlY2sgaWYgYnl0ZSBpcyB3aGl0ZXNwYWNlXG4gICAgKi9cbiAgIHByaXZhdGUgaXNXaGl0ZXNwYWNlKGJ5dGU6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIGJ5dGUgPT09IDB4MjAgfHwgYnl0ZSA9PT0gMHgwOSB8fCBieXRlID09PSAweDBBIHx8IGJ5dGUgPT09IDB4MEQgfHwgYnl0ZSA9PT0gMHgwMDtcbiAgIH1cbn1cbiIsCiAgICAiaW1wb3J0IHsgUERGTGV4ZXIsIFRva2VuVHlwZSwgdHlwZSBUb2tlbiB9IGZyb20gXCIuL2xleGVyLnRzXCI7XG5pbXBvcnQgdHlwZSB7IFBERlZhbHVlLCBQREZEaWN0aW9uYXJ5LCBQREZBcnJheSwgUERGUmVmLCBQREZTdHJlYW0gfSBmcm9tIFwiLi4vdHlwZXMudHNcIjtcbmltcG9ydCB7IGNyZWF0ZURpY3Rpb25hcnksIGNyZWF0ZUFycmF5LCBjcmVhdGVSZWYsIGNyZWF0ZU5hbWUsIGNyZWF0ZVN0cmVhbSB9IGZyb20gXCIuLi9jb3JlL29iamVjdHMudHNcIjtcblxuLyoqXG4gKiBQREYgUGFyc2VyXG4gKi9cbmV4cG9ydCBjbGFzcyBQREZQYXJzZXIge1xuICAgcHJpdmF0ZSBsZXhlcjogUERGTGV4ZXI7XG4gICBwcml2YXRlIGN1cnJlbnRUb2tlbjogVG9rZW47XG4gICBwcml2YXRlIG5leHRUb2tlbjogVG9rZW4gfCBudWxsID0gbnVsbDtcbiAgIHByaXZhdGUgZGF0YTogVWludDhBcnJheTtcblxuICAgY29uc3RydWN0b3IoZGF0YTogVWludDhBcnJheSkge1xuICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICAgIHRoaXMubGV4ZXIgPSBuZXcgUERGTGV4ZXIoZGF0YSk7XG4gICAgICB0aGlzLmN1cnJlbnRUb2tlbiA9IHRoaXMubGV4ZXIubmV4dFRva2VuKCk7XG4gICB9XG5cbiAgIC8qKlxuICAgICogUGFyc2UgYSBQREYgdmFsdWVcbiAgICAqL1xuICAgcGFyc2VWYWx1ZSgpOiBQREZWYWx1ZSB7XG4gICAgICBzd2l0Y2ggKHRoaXMuY3VycmVudFRva2VuLnR5cGUpIHtcbiAgICAgICAgIGNhc2UgVG9rZW5UeXBlLk5VTUJFUjpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBhcnNlTnVtYmVyT3JSZWYoKTtcbiAgICAgICAgIGNhc2UgVG9rZW5UeXBlLlNUUklORzpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBhcnNlU3RyaW5nKCk7XG4gICAgICAgICBjYXNlIFRva2VuVHlwZS5OQU1FOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VOYW1lKCk7XG4gICAgICAgICBjYXNlIFRva2VuVHlwZS5CT09MRUFOOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VCb29sZWFuKCk7XG4gICAgICAgICBjYXNlIFRva2VuVHlwZS5OVUxMOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VOdWxsKCk7XG4gICAgICAgICBjYXNlIFRva2VuVHlwZS5BUlJBWV9TVEFSVDpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBhcnNlQXJyYXkoKTtcbiAgICAgICAgIGNhc2UgVG9rZW5UeXBlLkRJQ1RfU1RBUlQ6XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJzZURpY3Rpb25hcnkoKTtcbiAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgdG9rZW46ICR7dGhpcy5jdXJyZW50VG9rZW4udHlwZX1gKTtcbiAgICAgIH1cbiAgIH1cblxuICAgLyoqXG4gICAgKiBQYXJzZSBudW1iZXIgb3IgcmVmZXJlbmNlIChudW1iZXIgbnVtYmVyIFIpXG4gICAgKi9cbiAgIHByaXZhdGUgcGFyc2VOdW1iZXJPclJlZigpOiBudW1iZXIgfCBQREZSZWYge1xuICAgICAgY29uc3QgZmlyc3QgPSB0aGlzLmN1cnJlbnRUb2tlbi52YWx1ZSBhcyBudW1iZXI7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcblxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIHJlZmVyZW5jZSAodHdvIG51bWJlcnMgZm9sbG93ZWQgYnkgUilcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlID09PSBUb2tlblR5cGUuTlVNQkVSKSB7XG4gICAgICAgICBjb25zdCBzZWNvbmQgPSB0aGlzLmN1cnJlbnRUb2tlbi52YWx1ZSBhcyBudW1iZXI7XG4gICAgICAgICB0aGlzLmFkdmFuY2UoKTtcblxuICAgICAgICAgaWYgKHRoaXMuY3VycmVudFRva2VuLnR5cGUgPT09IFRva2VuVHlwZS5SKSB7XG4gICAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVSZWYoZmlyc3QsIHNlY29uZCk7XG4gICAgICAgICB9XG5cbiAgICAgICAgIC8vIE5vdCBhIHJlZmVyZW5jZSAtIHdlIGNvbnN1bWVkIHRoZSBzZWNvbmQgbnVtYmVyLCBuZWVkIHRvIHB1dCBpdCBiYWNrXG4gICAgICAgICAvLyBQdXQgdGhlIGN1cnJlbnQgdG9rZW4gKHRoaXJkIHRva2VuKSBpbnRvIG5leHRUb2tlbiBidWZmZXJcbiAgICAgICAgIC8vIFRoZW4gcmVzdG9yZSBzZWNvbmQgbnVtYmVyIGFzIGN1cnJlbnQgdG9rZW5cbiAgICAgICAgIGNvbnN0IHRoaXJkVG9rZW4gPSB0aGlzLmN1cnJlbnRUb2tlbjtcbiAgICAgICAgIHRoaXMuY3VycmVudFRva2VuID0geyB0eXBlOiBUb2tlblR5cGUuTlVNQkVSLCB2YWx1ZTogc2Vjb25kLCBwb3NpdGlvbjogMCB9O1xuICAgICAgICAgdGhpcy5uZXh0VG9rZW4gPSB0aGlyZFRva2VuO1xuICAgICAgICAgcmV0dXJuIGZpcnN0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmlyc3Q7XG4gICB9XG5cbiAgIC8qKlxuICAgICogUGFyc2Ugc3RyaW5nXG4gICAgKi9cbiAgIHByaXZhdGUgcGFyc2VTdHJpbmcoKTogc3RyaW5nIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5jdXJyZW50VG9rZW4udmFsdWUgYXMgc3RyaW5nO1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICB9XG5cbiAgIC8qKlxuICAgICogUGFyc2UgbmFtZVxuICAgICovXG4gICBwcml2YXRlIHBhcnNlTmFtZSgpOiBQREZWYWx1ZSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuY3VycmVudFRva2VuLnZhbHVlIGFzIHN0cmluZztcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIGNyZWF0ZU5hbWUodmFsdWUpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIGJvb2xlYW5cbiAgICAqL1xuICAgcHJpdmF0ZSBwYXJzZUJvb2xlYW4oKTogYm9vbGVhbiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuY3VycmVudFRva2VuLnZhbHVlIGFzIGJvb2xlYW47XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBQYXJzZSBudWxsXG4gICAgKi9cbiAgIHByaXZhdGUgcGFyc2VOdWxsKCk6IG51bGwge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBQYXJzZSBhcnJheVxuICAgICovXG4gICBwcml2YXRlIHBhcnNlQXJyYXkoKTogUERGQXJyYXkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7IC8vIFNraXAgW1xuICAgICAgY29uc3QgdmFsdWVzOiBQREZWYWx1ZVtdID0gW107XG5cbiAgICAgIHdoaWxlICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuQVJSQVlfRU5EKSB7XG4gICAgICAgICBpZiAodGhpcy5jdXJyZW50VG9rZW4udHlwZSA9PT0gVG9rZW5UeXBlLkVPRikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5leHBlY3RlZCBFT0YgaW4gYXJyYXlcIik7XG4gICAgICAgICB9XG4gICAgICAgICB2YWx1ZXMucHVzaCh0aGlzLnBhcnNlVmFsdWUoKSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuYWR2YW5jZSgpOyAvLyBTa2lwIF1cbiAgICAgIHJldHVybiBjcmVhdGVBcnJheSh2YWx1ZXMpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIGRpY3Rpb25hcnlcbiAgICAqL1xuICAgcHJpdmF0ZSBwYXJzZURpY3Rpb25hcnkoKTogUERGRGljdGlvbmFyeSB7XG4gICAgICB0aGlzLmFkdmFuY2UoKTsgLy8gU2tpcCA8PFxuICAgICAgY29uc3QgZW50cmllczogUmVjb3JkPHN0cmluZywgUERGVmFsdWU+ID0ge307XG5cbiAgICAgIHdoaWxlICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuRElDVF9FTkQpIHtcbiAgICAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlID09PSBUb2tlblR5cGUuRU9GKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIEVPRiBpbiBkaWN0aW9uYXJ5XCIpO1xuICAgICAgICAgfVxuXG4gICAgICAgICAvLyBLZXkgbXVzdCBiZSBhIG5hbWVcbiAgICAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuTkFNRSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBuYW1lIGluIGRpY3Rpb25hcnksIGdvdCAke3RoaXMuY3VycmVudFRva2VuLnR5cGV9YCk7XG4gICAgICAgICB9XG4gICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmN1cnJlbnRUb2tlbi52YWx1ZSBhcyBzdHJpbmc7XG4gICAgICAgICB0aGlzLmFkdmFuY2UoKTtcblxuICAgICAgICAgLy8gVmFsdWVcbiAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5wYXJzZVZhbHVlKCk7XG4gICAgICAgICBlbnRyaWVzW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hZHZhbmNlKCk7IC8vIFNraXAgPj5cbiAgICAgIHJldHVybiBjcmVhdGVEaWN0aW9uYXJ5KGVudHJpZXMpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIGluZGlyZWN0IG9iamVjdFxuICAgICovXG4gICBwYXJzZUluZGlyZWN0T2JqZWN0KCk6IHsgcmVmOiBQREZSZWY7IHZhbHVlOiBQREZWYWx1ZSB9IHtcbiAgICAgIC8vIFBhcnNlOiBvYmplY3ROdW1iZXIgZ2VuZXJhdGlvbiBvYmpcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuTlVNQkVSKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RlZCBvYmplY3QgbnVtYmVyXCIpO1xuICAgICAgfVxuICAgICAgY29uc3Qgb2JqZWN0TnVtYmVyID0gdGhpcy5jdXJyZW50VG9rZW4udmFsdWUgYXMgbnVtYmVyO1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG5cbiAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuTlVNQkVSKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RlZCBnZW5lcmF0aW9uIG51bWJlclwiKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGdlbmVyYXRpb24gPSB0aGlzLmN1cnJlbnRUb2tlbi52YWx1ZSBhcyBudW1iZXI7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcblxuICAgICAgaWYgKHRoaXMuY3VycmVudFRva2VuLnR5cGUgIT09IFRva2VuVHlwZS5PQkopIHtcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkICdvYmonIGtleXdvcmRcIik7XG4gICAgICB9XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcblxuICAgICAgLy8gUGFyc2Ugb2JqZWN0IHZhbHVlXG4gICAgICBsZXQgdmFsdWU6IFBERlZhbHVlID0gdGhpcy5wYXJzZVZhbHVlKCk7XG5cbiAgICAgIC8vIENoZWNrIGZvciBzdHJlYW1cbiAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlID09PSBUb2tlblR5cGUuU1RSRUFNKSB7XG4gICAgICAgICB2YWx1ZSA9IHRoaXMucGFyc2VTdHJlYW0odmFsdWUgYXMgUERGRGljdGlvbmFyeSk7XG4gICAgICB9XG5cbiAgICAgIC8vIEV4cGVjdCBlbmRvYmpcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuRU5ET0JKKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RlZCAnZW5kb2JqJyBrZXl3b3JkXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5hZHZhbmNlKCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgICByZWY6IGNyZWF0ZVJlZihvYmplY3ROdW1iZXIsIGdlbmVyYXRpb24pLFxuICAgICAgICAgdmFsdWUsXG4gICAgICB9O1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIHN0cmVhbSAoZGljdGlvbmFyeSBhbHJlYWR5IHBhcnNlZClcbiAgICAqL1xuICAgcHJpdmF0ZSBwYXJzZVN0cmVhbShkaWN0aW9uYXJ5OiBQREZEaWN0aW9uYXJ5KTogUERGU3RyZWFtIHtcbiAgICAgIC8vIEdldCBjdXJyZW50IHBvc2l0aW9uIHdoZXJlICdzdHJlYW0nIGtleXdvcmQgaXNcbiAgICAgIGNvbnN0IHN0cmVhbUtleXdvcmRQb3MgPSB0aGlzLmN1cnJlbnRUb2tlbi5wb3NpdGlvbjtcbiAgICAgIHRoaXMuYWR2YW5jZSgpOyAvLyBTa2lwICdzdHJlYW0nXG5cbiAgICAgIC8vIEZpbmQgdGhlIGFjdHVhbCBzdGFydCBvZiBzdHJlYW0gZGF0YSAoYWZ0ZXIgJ3N0cmVhbScga2V5d29yZCBhbmQgbmV3bGluZSlcbiAgICAgIC8vIFRoZSBzdHJlYW0ga2V5d29yZCBpcyBmb2xsb3dlZCBieSBlaXRoZXIgXFxuIG9yIFxcclxcblxuICAgICAgbGV0IHN0cmVhbURhdGFTdGFydCA9IHN0cmVhbUtleXdvcmRQb3MgKyA2OyAvLyAnc3RyZWFtJyBpcyA2IGNoYXJhY3RlcnNcbiAgICAgIFxuICAgICAgLy8gU2tpcCB0aGUgbmV3bGluZSBhZnRlciAnc3RyZWFtJ1xuICAgICAgd2hpbGUgKHN0cmVhbURhdGFTdGFydCA8IHRoaXMuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgIGNvbnN0IGJ5dGUgPSB0aGlzLmRhdGFbc3RyZWFtRGF0YVN0YXJ0XTtcbiAgICAgICAgIGlmIChieXRlID09PSAweDBEIHx8IGJ5dGUgPT09IDB4MEEpIHsgLy8gXFxyIG9yIFxcblxuICAgICAgICAgICAgc3RyZWFtRGF0YVN0YXJ0Kys7XG4gICAgICAgICAgICAvLyBIYW5kbGUgXFxyXFxuXG4gICAgICAgICAgICBpZiAoYnl0ZSA9PT0gMHgwRCAmJiB0aGlzLmRhdGFbc3RyZWFtRGF0YVN0YXJ0XSA9PT0gMHgwQSkge1xuICAgICAgICAgICAgICAgc3RyZWFtRGF0YVN0YXJ0Kys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgIH1cbiAgICAgICAgIHN0cmVhbURhdGFTdGFydCsrO1xuICAgICAgfVxuXG4gICAgICAvLyBHZXQgc3RyZWFtIGxlbmd0aFxuICAgICAgY29uc3QgbGVuZ3RoID0gZGljdGlvbmFyeS5MZW5ndGggYXMgbnVtYmVyO1xuICAgICAgaWYgKHR5cGVvZiBsZW5ndGggIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlN0cmVhbSBkaWN0aW9uYXJ5IG1pc3NpbmcgTGVuZ3RoXCIpO1xuICAgICAgfVxuXG4gICAgICAvLyBFeHRyYWN0IHN0cmVhbSBkYXRhXG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5kYXRhLnNsaWNlKHN0cmVhbURhdGFTdGFydCwgc3RyZWFtRGF0YVN0YXJ0ICsgbGVuZ3RoKTtcblxuICAgICAgLy8gU2tpcCB0byBlbmRzdHJlYW1cbiAgICAgIHdoaWxlICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuRU5EU1RSRUFNICYmIHRoaXMuY3VycmVudFRva2VuLnR5cGUgIT09IFRva2VuVHlwZS5FT0YpIHtcbiAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5jdXJyZW50VG9rZW4udHlwZSAhPT0gVG9rZW5UeXBlLkVORFNUUkVBTSkge1xuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgJ2VuZHN0cmVhbScga2V5d29yZFwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuXG4gICAgICByZXR1cm4gY3JlYXRlU3RyZWFtKGRhdGEsIGRpY3Rpb25hcnkpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIEFkdmFuY2UgdG8gbmV4dCB0b2tlblxuICAgICovXG4gICBwcml2YXRlIGFkdmFuY2UoKTogdm9pZCB7XG4gICAgICBpZiAodGhpcy5uZXh0VG9rZW4gIT09IG51bGwpIHtcbiAgICAgICAgIHRoaXMuY3VycmVudFRva2VuID0gdGhpcy5uZXh0VG9rZW47XG4gICAgICAgICB0aGlzLm5leHRUb2tlbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4gPSB0aGlzLmxleGVyLm5leHRUb2tlbigpO1xuICAgICAgfVxuICAgfVxuXG4gICAvKipcbiAgICAqIENoZWNrIGlmIG1vcmUgdG9rZW5zIGF2YWlsYWJsZVxuICAgICovXG4gICBoYXNNb3JlKCk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFRva2VuLnR5cGUgIT09IFRva2VuVHlwZS5FT0Y7XG4gICB9XG59XG4iLAogICAgIi8qKlxuICogQmFzZSBlcnJvciBjbGFzcyBmb3IgYWxsIFBERiBlcnJvcnNcbiAqL1xuZXhwb3J0IGNsYXNzIFBERkVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICBzdXBlcihtZXNzYWdlKTtcbiAgICAgIHRoaXMubmFtZSA9IFwiUERGRXJyb3JcIjtcbiAgICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3Rvcik7XG4gICAgICB9XG4gICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gUERGIHBhcnNpbmcgZmFpbHNcbiAqL1xuZXhwb3J0IGNsYXNzIFBERlBhcnNlRXJyb3IgZXh0ZW5kcyBQREZFcnJvciB7XG4gICBjb25zdHJ1Y3RvcihcbiAgICAgIG1lc3NhZ2U6IHN0cmluZyxcbiAgICAgIHB1YmxpYyByZWFkb25seSBvZmZzZXQ/OiBudW1iZXIsXG4gICApIHtcbiAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgdGhpcy5uYW1lID0gXCJQREZQYXJzZUVycm9yXCI7XG4gICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gUERGIGdlbmVyYXRpb24gZmFpbHNcbiAqL1xuZXhwb3J0IGNsYXNzIFBERkdlbmVyYXRpb25FcnJvciBleHRlbmRzIFBERkVycm9yIHtcbiAgIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICB0aGlzLm5hbWUgPSBcIlBERkdlbmVyYXRpb25FcnJvclwiO1xuICAgfVxufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIFBERiBvYmplY3QgaXMgaW52YWxpZFxuICovXG5leHBvcnQgY2xhc3MgSW52YWxpZFBERk9iamVjdEVycm9yIGV4dGVuZHMgUERGRXJyb3Ige1xuICAgY29uc3RydWN0b3IoXG4gICAgICBwdWJsaWMgcmVhZG9ubHkgb2JqZWN0VHlwZTogc3RyaW5nLFxuICAgICAgcmVhc29uOiBzdHJpbmcsXG4gICApIHtcbiAgICAgIHN1cGVyKGBJbnZhbGlkICR7b2JqZWN0VHlwZX06ICR7cmVhc29ufWApO1xuICAgICAgdGhpcy5uYW1lID0gXCJJbnZhbGlkUERGT2JqZWN0RXJyb3JcIjtcbiAgIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiBmb250IGlzIG5vdCBmb3VuZFxuICovXG5leHBvcnQgY2xhc3MgRm9udE5vdEZvdW5kRXJyb3IgZXh0ZW5kcyBQREZFcnJvciB7XG4gICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgZm9udE5hbWU6IHN0cmluZykge1xuICAgICAgc3VwZXIoYEZvbnQgbm90IGZvdW5kOiAke2ZvbnROYW1lfWApO1xuICAgICAgdGhpcy5uYW1lID0gXCJGb250Tm90Rm91bmRFcnJvclwiO1xuICAgfVxufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGltYWdlIGlzIGludmFsaWRcbiAqL1xuZXhwb3J0IGNsYXNzIEludmFsaWRJbWFnZUVycm9yIGV4dGVuZHMgUERGRXJyb3Ige1xuICAgY29uc3RydWN0b3IocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgIHN1cGVyKGBJbnZhbGlkIGltYWdlOiAke3JlYXNvbn1gKTtcbiAgICAgIHRoaXMubmFtZSA9IFwiSW52YWxpZEltYWdlRXJyb3JcIjtcbiAgIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiBQREYgc2lnbmF0dXJlIGZhaWxzXG4gKi9cbmV4cG9ydCBjbGFzcyBQREZTaWduYXR1cmVFcnJvciBleHRlbmRzIFBERkVycm9yIHtcbiAgIGNvbnN0cnVjdG9yKHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICBzdXBlcihgUERGIHNpZ25hdHVyZSBlcnJvcjogJHtyZWFzb259YCk7XG4gICAgICB0aGlzLm5hbWUgPSBcIlBERlNpZ25hdHVyZUVycm9yXCI7XG4gICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gUERGIGVuY3J5cHRpb24gZmFpbHNcbiAqL1xuZXhwb3J0IGNsYXNzIFBERkVuY3J5cHRpb25FcnJvciBleHRlbmRzIFBERkVycm9yIHtcbiAgIGNvbnN0cnVjdG9yKHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICBzdXBlcihgUERGIGVuY3J5cHRpb24gZXJyb3I6ICR7cmVhc29ufWApO1xuICAgICAgdGhpcy5uYW1lID0gXCJQREZFbmNyeXB0aW9uRXJyb3JcIjtcbiAgIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiByZXF1aXJlZCBmZWF0dXJlIGlzIG5vdCBpbXBsZW1lbnRlZFxuICovXG5leHBvcnQgY2xhc3MgTm90SW1wbGVtZW50ZWRFcnJvciBleHRlbmRzIFBERkVycm9yIHtcbiAgIGNvbnN0cnVjdG9yKGZlYXR1cmU6IHN0cmluZykge1xuICAgICAgc3VwZXIoYEZlYXR1cmUgbm90IHlldCBpbXBsZW1lbnRlZDogJHtmZWF0dXJlfWApO1xuICAgICAgdGhpcy5uYW1lID0gXCJOb3RJbXBsZW1lbnRlZEVycm9yXCI7XG4gICB9XG59XG4iLAogICAgImltcG9ydCB7IFBERlBhcnNlciB9IGZyb20gXCIuL3BhcnNlci50c1wiO1xuaW1wb3J0IHR5cGUgeyBQREZEaWN0aW9uYXJ5LCBQREZSZWYsIFBERkFycmF5IH0gZnJvbSBcIi4uL3R5cGVzLnRzXCI7XG5pbXBvcnQgeyBQREZQYXJzZUVycm9yIH0gZnJvbSBcIi4uL2Vycm9ycy50c1wiO1xuXG4vKipcbiAqIFBhcnNlZCBQREYgRG9jdW1lbnRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYXJzZWRQREYge1xuICAgdmVyc2lvbjogc3RyaW5nO1xuICAgY2F0YWxvZzogUERGUmVmO1xuICAgcGFnZXM6IFBERlBhZ2VbXTtcbiAgIG9iamVjdHM6IE1hcDxudW1iZXIsIGFueT47XG59XG5cbi8qKlxuICogUGFyc2VkIFBERiBQYWdlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUERGUGFnZSB7XG4gICByZWY6IFBERlJlZjtcbiAgIHNpemU6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfTtcbiAgIGNvbnRlbnQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBQREYgUmVhZGVyIC0gcmVhZHMgYW5kIHBhcnNlcyBleGlzdGluZyBQREZzXG4gKi9cbmV4cG9ydCBjbGFzcyBQREZSZWFkZXIge1xuICAgcHJpdmF0ZSBkYXRhOiBVaW50OEFycmF5O1xuICAgcHJpdmF0ZSBvYmplY3RzOiBNYXA8bnVtYmVyLCBhbnk+ID0gbmV3IE1hcCgpO1xuXG4gICBjb25zdHJ1Y3RvcihkYXRhOiBVaW50OEFycmF5KSB7XG4gICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIFBERiBmaWxlXG4gICAgKi9cbiAgIHBhcnNlKCk6IFBhcnNlZFBERiB7XG4gICAgICAvLyAxLiBGaW5kIGFuZCBwYXJzZSB4cmVmIHRhYmxlXG4gICAgICBjb25zdCB4cmVmT2Zmc2V0ID0gdGhpcy5maW5kU3RhcnRYUmVmKCk7XG4gICAgICBjb25zdCB4cmVmVGFibGUgPSB0aGlzLnBhcnNlWFJlZlRhYmxlKHhyZWZPZmZzZXQpO1xuXG4gICAgICAvLyAyLiBQYXJzZSB0cmFpbGVyXG4gICAgICBjb25zdCB0cmFpbGVyID0gdGhpcy5wYXJzZVRyYWlsZXIoeHJlZk9mZnNldCk7XG4gICAgICBjb25zdCBjYXRhbG9nUmVmID0gdHJhaWxlci5Sb290IGFzIFBERlJlZjtcblxuICAgICAgLy8gMy4gUmVhZCBhbGwgb2JqZWN0cyB1c2luZyB4cmVmIHRhYmxlXG4gICAgICB0aGlzLnJlYWRPYmplY3RzKHhyZWZUYWJsZSk7XG5cbiAgICAgIC8vIDQuIEdldCBQREYgdmVyc2lvbiBmcm9tIGhlYWRlclxuICAgICAgY29uc3QgdmVyc2lvbiA9IHRoaXMucGFyc2VWZXJzaW9uKCk7XG5cbiAgICAgIC8vIDUuIFBhcnNlIHBhZ2VzXG4gICAgICBjb25zdCBwYWdlcyA9IHRoaXMucGFyc2VQYWdlcyhjYXRhbG9nUmVmKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgIHZlcnNpb24sXG4gICAgICAgICBjYXRhbG9nOiBjYXRhbG9nUmVmLFxuICAgICAgICAgcGFnZXMsXG4gICAgICAgICBvYmplY3RzOiB0aGlzLm9iamVjdHMsXG4gICAgICB9O1xuICAgfVxuXG4gICAvKipcbiAgICAqIEZpbmQgc3RhcnR4cmVmIG9mZnNldFxuICAgICovXG4gICBwcml2YXRlIGZpbmRTdGFydFhSZWYoKTogbnVtYmVyIHtcbiAgICAgIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBkZWNvZGVyLmRlY29kZSh0aGlzLmRhdGEpO1xuICAgICAgY29uc3QgbWF0Y2ggPSBjb250ZW50Lm1hdGNoKC9zdGFydHhyZWZcXHMrKFxcZCspLyk7XG4gICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgICB0aHJvdyBuZXcgUERGUGFyc2VFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHN0YXJ0eHJlZlwiKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwYXJzZUludChtYXRjaFsxXSwgMTApO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIHhyZWYgdGFibGVcbiAgICAqL1xuICAgcHJpdmF0ZSBwYXJzZVhSZWZUYWJsZShvZmZzZXQ6IG51bWJlcik6IE1hcDxudW1iZXIsIG51bWJlcj4ge1xuICAgICAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpO1xuICAgICAgY29uc3QgY29udGVudCA9IGRlY29kZXIuZGVjb2RlKHRoaXMuZGF0YS5zbGljZShvZmZzZXQpKTtcbiAgICAgIGNvbnN0IGxpbmVzID0gY29udGVudC5zcGxpdChcIlxcblwiKTtcblxuICAgICAgY29uc3QgeHJlZiA9IG5ldyBNYXA8bnVtYmVyLCBudW1iZXI+KCk7XG4gICAgICBsZXQgaSA9IDA7XG5cbiAgICAgIC8vIFNraXAgXCJ4cmVmXCIga2V5d29yZFxuICAgICAgd2hpbGUgKGkgPCBsaW5lcy5sZW5ndGggJiYgIWxpbmVzW2ldLnRyaW0oKS5zdGFydHNXaXRoKFwieHJlZlwiKSkgaSsrO1xuICAgICAgaSsrO1xuXG4gICAgICAvLyBQYXJzZSBzdWJzZWN0aW9uc1xuICAgICAgd2hpbGUgKGkgPCBsaW5lcy5sZW5ndGggJiYgIWxpbmVzW2ldLnRyaW0oKS5zdGFydHNXaXRoKFwidHJhaWxlclwiKSkge1xuICAgICAgICAgY29uc3Qgc3Vic2VjdGlvbiA9IGxpbmVzW2ldLnRyaW0oKS5zcGxpdCgvXFxzKy8pO1xuICAgICAgICAgaWYgKHN1YnNlY3Rpb24ubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICBjb25zdCBzdGFydCA9IHBhcnNlSW50KHN1YnNlY3Rpb25bMF0sIDEwKTtcbiAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gcGFyc2VJbnQoc3Vic2VjdGlvblsxXSwgMTApO1xuICAgICAgICAgICAgaSsrO1xuXG4gICAgICAgICAgICAvLyBQYXJzZSBlbnRyaWVzXG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvdW50OyBqKyspIHtcbiAgICAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gbGluZXNbaV0udHJpbSgpLnNwbGl0KC9cXHMrLyk7XG4gICAgICAgICAgICAgICBpZiAoZW50cnkubGVuZ3RoID49IDMgJiYgZW50cnlbMl0gPT09IFwiblwiKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXQgPSBwYXJzZUludChlbnRyeVswXSwgMTApO1xuICAgICAgICAgICAgICAgICAgeHJlZi5zZXQoc3RhcnQgKyBqLCBvZmZzZXQpO1xuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHhyZWY7XG4gICB9XG5cbiAgIC8qKlxuICAgICogUGFyc2UgdHJhaWxlciBkaWN0aW9uYXJ5XG4gICAgKi9cbiAgIHByaXZhdGUgcGFyc2VUcmFpbGVyKHhyZWZPZmZzZXQ6IG51bWJlcik6IFBERkRpY3Rpb25hcnkge1xuICAgICAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpO1xuICAgICAgY29uc3QgY29udGVudCA9IGRlY29kZXIuZGVjb2RlKHRoaXMuZGF0YS5zbGljZSh4cmVmT2Zmc2V0KSk7XG4gICAgICBjb25zdCB0cmFpbGVyTWF0Y2ggPSBjb250ZW50Lm1hdGNoKC90cmFpbGVyXFxzKjw8W1xcc1xcU10qPz4+Lyk7XG4gICAgICBpZiAoIXRyYWlsZXJNYXRjaCkge1xuICAgICAgICAgdGhyb3cgbmV3IFBERlBhcnNlRXJyb3IoXCJDb3VsZCBub3QgZmluZCB0cmFpbGVyXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYXJzZXIgPSBuZXcgUERGUGFyc2VyKG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSh0cmFpbGVyTWF0Y2hbMF0ucmVwbGFjZShcInRyYWlsZXJcIiwgXCJcIikpKTtcbiAgICAgIHJldHVybiBwYXJzZXIucGFyc2VWYWx1ZSgpIGFzIFBERkRpY3Rpb25hcnk7XG4gICB9XG5cbiAgIC8qKlxuICAgICogUmVhZCBhbGwgb2JqZWN0cyBmcm9tIHhyZWYgdGFibGVcbiAgICAqL1xuICAgcHJpdmF0ZSByZWFkT2JqZWN0cyh4cmVmVGFibGU6IE1hcDxudW1iZXIsIG51bWJlcj4pOiB2b2lkIHtcbiAgICAgIGZvciAoY29uc3QgW29iamVjdE51bSwgb2Zmc2V0XSBvZiB4cmVmVGFibGUpIHtcbiAgICAgICAgIHRyeSB7XG4gICAgICAgICAgIGNvbnN0IG9iakRhdGEgPSB0aGlzLmRhdGEuc2xpY2Uob2Zmc2V0KTtcbiAgICAgICAgICAgY29uc3QgcGFyc2VyID0gbmV3IFBERlBhcnNlcihvYmpEYXRhKTtcbiAgICAgICAgICAgY29uc3Qgb2JqID0gcGFyc2VyLnBhcnNlSW5kaXJlY3RPYmplY3QoKTtcbiAgICAgICAgICAgdGhpcy5vYmplY3RzLnNldChvYmplY3ROdW0sIG9iai52YWx1ZSk7XG4gICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAvLyBTa2lwIG1hbGZvcm1lZCBvYmplY3RzXG4gICAgICAgICB9XG4gICAgICB9XG4gICB9XG5cbiAgIC8qKlxuICAgICogUGFyc2UgUERGIHZlcnNpb24gZnJvbSBoZWFkZXJcbiAgICAqL1xuICAgcHJpdmF0ZSBwYXJzZVZlcnNpb24oKTogc3RyaW5nIHtcbiAgICAgIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTtcbiAgICAgIGNvbnN0IGhlYWRlciA9IGRlY29kZXIuZGVjb2RlKHRoaXMuZGF0YS5zbGljZSgwLCAyMCkpO1xuICAgICAgY29uc3QgbWF0Y2ggPSBoZWFkZXIubWF0Y2goLyVQREYtKFxcZCtcXC5cXGQrKS8pO1xuICAgICAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMV0gOiBcIjEuN1wiO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIHBhZ2VzIGZyb20gY2F0YWxvZ1xuICAgICovXG4gICBwcml2YXRlIHBhcnNlUGFnZXMoY2F0YWxvZ1JlZjogUERGUmVmKTogUERGUGFnZVtdIHtcbiAgICAgIGNvbnN0IGNhdGFsb2cgPSB0aGlzLm9iamVjdHMuZ2V0KGNhdGFsb2dSZWYub2JqZWN0TnVtYmVyKSBhcyBQREZEaWN0aW9uYXJ5O1xuICAgICAgaWYgKCFjYXRhbG9nKSB7XG4gICAgICAgICB0aHJvdyBuZXcgUERGUGFyc2VFcnJvcihcIkNhdGFsb2cgbm90IGZvdW5kXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYWdlc1JlZiA9IGNhdGFsb2cuUGFnZXMgYXMgUERGUmVmO1xuICAgICAgY29uc3QgcGFnZXNUcmVlID0gdGhpcy5vYmplY3RzLmdldChwYWdlc1JlZi5vYmplY3ROdW1iZXIpIGFzIFBERkRpY3Rpb25hcnk7XG4gICAgICBpZiAoIXBhZ2VzVHJlZSkge1xuICAgICAgICAgdGhyb3cgbmV3IFBERlBhcnNlRXJyb3IoXCJQYWdlcyB0cmVlIG5vdCBmb3VuZFwiKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qga2lkcyA9IHBhZ2VzVHJlZS5LaWRzIGFzIFBERkFycmF5O1xuICAgICAgY29uc3QgcGFnZXM6IFBERlBhZ2VbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGtpZFJlZiBvZiBraWRzKSB7XG4gICAgICAgICBpZiAodHlwZW9mIGtpZFJlZiA9PT0gXCJvYmplY3RcIiAmJiBcIm9iamVjdE51bWJlclwiIGluIGtpZFJlZikge1xuICAgICAgICAgICAgY29uc3QgcGFnZSA9IHRoaXMucGFyc2VQYWdlKGtpZFJlZiBhcyBQREZSZWYpO1xuICAgICAgICAgICAgaWYgKHBhZ2UpIHBhZ2VzLnB1c2gocGFnZSk7XG4gICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYWdlcztcbiAgIH1cblxuICAgLyoqXG4gICAgKiBQYXJzZSBhIHNpbmdsZSBwYWdlXG4gICAgKi9cbiAgIHByaXZhdGUgcGFyc2VQYWdlKHJlZjogUERGUmVmKTogUERGUGFnZSB8IG51bGwge1xuICAgICAgY29uc3QgcGFnZURpY3QgPSB0aGlzLm9iamVjdHMuZ2V0KHJlZi5vYmplY3ROdW1iZXIpIGFzIFBERkRpY3Rpb25hcnk7XG4gICAgICBpZiAoIXBhZ2VEaWN0KSByZXR1cm4gbnVsbDtcblxuICAgICAgY29uc3QgbWVkaWFCb3ggPSBwYWdlRGljdC5NZWRpYUJveCBhcyBQREZBcnJheTtcbiAgICAgIGNvbnN0IHNpemUgPSB7XG4gICAgICAgICB3aWR0aDogbWVkaWFCb3hbMl0gYXMgbnVtYmVyLFxuICAgICAgICAgaGVpZ2h0OiBtZWRpYUJveFszXSBhcyBudW1iZXIsXG4gICAgICB9O1xuXG4gICAgICAvLyBFeHRyYWN0IGNvbnRlbnRcbiAgICAgIGxldCBjb250ZW50ID0gXCJcIjtcbiAgICAgIGNvbnN0IGNvbnRlbnRzUmVmID0gcGFnZURpY3QuQ29udGVudHMgYXMgUERGUmVmO1xuICAgICAgaWYgKGNvbnRlbnRzUmVmICYmIHR5cGVvZiBjb250ZW50c1JlZiA9PT0gXCJvYmplY3RcIiAmJiBcIm9iamVjdE51bWJlclwiIGluIGNvbnRlbnRzUmVmKSB7XG4gICAgICAgICBjb250ZW50ID0gdGhpcy5leHRyYWN0VGV4dChjb250ZW50c1JlZik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHJlZiwgc2l6ZSwgY29udGVudCB9O1xuICAgfVxuXG4gICAvKipcbiAgICAqIEV4dHJhY3QgdGV4dCBmcm9tIGNvbnRlbnQgc3RyZWFtXG4gICAgKi9cbiAgIHByaXZhdGUgZXh0cmFjdFRleHQocmVmOiBQREZSZWYpOiBzdHJpbmcge1xuICAgICAgY29uc3Qgc3RyZWFtID0gdGhpcy5vYmplY3RzLmdldChyZWYub2JqZWN0TnVtYmVyKTtcbiAgICAgIGlmICghc3RyZWFtIHx8ICFzdHJlYW0uZGF0YSkgcmV0dXJuIFwiXCI7XG5cbiAgICAgIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBkZWNvZGVyLmRlY29kZShzdHJlYW0uZGF0YSk7XG5cbiAgICAgIC8vIFNpbXBsZSB0ZXh0IGV4dHJhY3Rpb24gLSBsb29rIGZvciAodGV4dCkgVGogcGF0dGVybnNcbiAgICAgIGNvbnN0IHRleHRzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgY29uc3QgcmVnZXggPSAvXFwoKFteKV0qKVxcKVxccypUai9nO1xuICAgICAgbGV0IG1hdGNoO1xuICAgICAgd2hpbGUgKChtYXRjaCA9IHJlZ2V4LmV4ZWMoY29udGVudCkpICE9PSBudWxsKSB7XG4gICAgICAgICB0ZXh0cy5wdXNoKG1hdGNoWzFdKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRleHRzLmpvaW4oXCIgXCIpO1xuICAgfVxufVxuIgogIF0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7O0FBR08sSUFBSztBQUFBLENBQUwsQ0FBSyxlQUFMO0FBQUEsRUFFSix1QkFBUztBQUFBLEVBQ1QsdUJBQVM7QUFBQSxFQUNULHFCQUFPO0FBQUEsRUFDUCx3QkFBVTtBQUFBLEVBQ1YscUJBQU87QUFBQSxFQUdQLDRCQUFjO0FBQUEsRUFDZCwwQkFBWTtBQUFBLEVBQ1osMkJBQWE7QUFBQSxFQUNiLHlCQUFXO0FBQUEsRUFHWCxvQkFBTTtBQUFBLEVBQ04sdUJBQVM7QUFBQSxFQUNULHVCQUFTO0FBQUEsRUFDVCwwQkFBWTtBQUFBLEVBQ1oscUJBQU87QUFBQSxFQUNQLHdCQUFVO0FBQUEsRUFDViwwQkFBWTtBQUFBLEVBQ1osa0JBQUk7QUFBQSxFQUdKLG9CQUFNO0FBQUEsR0F6Qkc7QUFBQTtBQXdDTCxNQUFNLFNBQVM7QUFBQSxFQUNYO0FBQUEsRUFDQSxXQUFtQjtBQUFBLEVBRTNCLFdBQVcsQ0FBQyxNQUFrQjtBQUFBLElBQzNCLEtBQUssT0FBTztBQUFBO0FBQUEsRUFNZixTQUFTLEdBQVU7QUFBQSxJQUNoQixLQUFLLGVBQWU7QUFBQSxJQUVwQixJQUFJLEtBQUssWUFBWSxLQUFLLEtBQUssUUFBUTtBQUFBLE1BQ3BDLE9BQU8sRUFBRSxNQUFNLGlCQUFlLE9BQU8sTUFBTSxVQUFVLEtBQUssU0FBUztBQUFBLElBQ3RF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LElBRXRCLE1BQU0sV0FBVyxTQUFTO0FBQUEsSUFDMUIsTUFBTSxPQUFPO0FBQUEsTUFDVixPQUFPLFNBQVM7QUFBQSxNQUNoQixRQUFRLFNBQVM7QUFBQSxJQUNwQjtBQUFBLElBR0EsSUFBSSxVQUFVO0FBQUEsSUFDZCxNQUFNLGNBQWMsU0FBUztBQUFBLElBQzdCLElBQUksZUFBZSxPQUFPLGdCQUFnQixZQUFZLGtCQUFrQixhQUFhO0FBQUEsTUFDbEYsVUFBVSxLQUFLLFlBQVksV0FBVztBQUFBLElBQ3pDO0FBQUEsSUFFQSxPQUFPLEVBQUUsS0FBSyxNQUFNLFFBQVE7QUFBQTtBQUFBLEVBTXZCLFdBQVcsQ0FBQyxLQUFxQjtBQUFBLElBQ3RDLE1BQU0sU0FBUyxLQUFLLFFBQVEsSUFBSSxJQUFJLFlBQVk7QUFBQSxJQUNoRCxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU87QUFBQSxNQUFNLE9BQU87QUFBQSxJQUVwQyxNQUFNLFVBQVUsSUFBSTtBQUFBLElBQ3BCLE1BQU0sVUFBVSxRQUFRLE9BQU8sT0FBTyxJQUFJO0FBQUEsSUFHMUMsTUFBTSxRQUFrQixDQUFDO0FBQUEsSUFDekIsTUFBTSxRQUFRO0FBQUEsSUFDZCxJQUFJO0FBQUEsSUFDSixRQUFRLFFBQVEsTUFBTSxLQUFLLE9BQU8sT0FBTyxNQUFNO0FBQUEsTUFDNUMsTUFBTSxLQUFLLE1BQU0sRUFBRTtBQUFBLElBQ3RCO0FBQUEsSUFFQSxPQUFPLE1BQU0sS0FBSyxHQUFHO0FBQUE7QUFFM0I7IiwKICAiZGVidWdJZCI6ICIyRDI1Njc4QTlEQzg5NThFNjQ3NTZFMjE2NDc1NkUyMSIsCiAgIm5hbWVzIjogW10KfQ==
|