@sumit_yewale/angular 1.1.18 → 1.1.21-fix.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.
@@ -3,18 +3,137 @@
3
3
  * Generated from: lib/csvbox-button.component.ts
4
4
  * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5
5
  */
6
- import { Component, ViewChild, Input, SecurityContext } from '@angular/core';
6
+ import { Component, Input, SecurityContext, ChangeDetectorRef, NgZone } from '@angular/core';
7
7
  import { DomSanitizer } from '@angular/platform-browser';
8
8
  import { insertCSS } from '../utlis/insertCSS';
9
- import { buildImportUrl, generateUuid, buildInitPayload, classifyStructuredMessage } from '@sumit_yewale/adapter-core';
9
+ import { buildImportUrl, generateUuid, buildInitPayload, createMessageGate, createImportTracker, createFileSender, classifyStructuredMessage, classifyLegacyMessage } from '@sumit_yewale/adapter-core';
10
+ // How long we wait for the importer to confirm a file it was sent before giving up on it.
10
11
  /** @type {?} */
11
- const appVersion = '1.1.16';
12
+ const FILE_ACK_TIMEOUT_MS = 8000;
13
+ /**
14
+ * @record
15
+ */
16
+ function OpenImporterEntry() { }
17
+ if (false) {
18
+ /** @type {?} */
19
+ OpenImporterEntry.prototype.getHolder;
20
+ }
21
+ /**
22
+ * @record
23
+ */
24
+ function OpenImporters() { }
25
+ if (false) {
26
+ /** @type {?} */
27
+ OpenImporters.prototype.open;
28
+ /** @type {?} */
29
+ OpenImporters.prototype.listeners;
30
+ }
31
+ /** @type {?} */
32
+ const OPEN_IMPORTERS_KEY = '__csvboxOpenImporters';
33
+ /** @type {?} */
34
+ const TOP_Z_INDEX = 2147483647;
35
+ /**
36
+ * @return {?}
37
+ */
38
+ function openImporters() {
39
+ /** @type {?} */
40
+ const w = (/** @type {?} */ (window));
41
+ if (!w[OPEN_IMPORTERS_KEY])
42
+ w[OPEN_IMPORTERS_KEY] = { open: [], listeners: [] };
43
+ return w[OPEN_IMPORTERS_KEY];
44
+ }
45
+ /**
46
+ * @param {?} reg
47
+ * @return {?}
48
+ */
49
+ function restackOpenImporters(reg) {
50
+ reg.open.forEach((/**
51
+ * @param {?} entry
52
+ * @param {?} i
53
+ * @return {?}
54
+ */
55
+ (entry, i) => {
56
+ /** @type {?} */
57
+ const holder = entry.getHolder();
58
+ if (holder)
59
+ holder.style.zIndex = String(TOP_Z_INDEX - (reg.open.length - 1 - i));
60
+ }));
61
+ }
62
+ /**
63
+ * @param {?} entry
64
+ * @return {?}
65
+ */
66
+ function registerOpenImporter(entry) {
67
+ /** @type {?} */
68
+ const reg = openImporters();
69
+ if (reg.open.indexOf(entry) >= 0)
70
+ return;
71
+ reg.open.push(entry);
72
+ restackOpenImporters(reg);
73
+ reg.listeners.slice().forEach((/**
74
+ * @param {?} fn
75
+ * @return {?}
76
+ */
77
+ fn => fn()));
78
+ }
79
+ /**
80
+ * @param {?} entry
81
+ * @return {?}
82
+ */
83
+ function unregisterOpenImporter(entry) {
84
+ /** @type {?} */
85
+ const reg = openImporters();
86
+ /** @type {?} */
87
+ const i = reg.open.indexOf(entry);
88
+ if (i < 0)
89
+ return;
90
+ reg.open.splice(i, 1);
91
+ restackOpenImporters(reg);
92
+ reg.listeners.slice().forEach((/**
93
+ * @param {?} fn
94
+ * @return {?}
95
+ */
96
+ fn => fn()));
97
+ }
98
+ /**
99
+ * @param {?} entry
100
+ * @return {?}
101
+ */
102
+ function isBlockedByOpenImporter(entry) {
103
+ /** @type {?} */
104
+ const reg = openImporters();
105
+ return reg.open.length > 0 && reg.open.indexOf(entry) < 0;
106
+ }
107
+ /**
108
+ * @param {?} fn
109
+ * @return {?}
110
+ */
111
+ function subscribeOpenImporters(fn) {
112
+ /** @type {?} */
113
+ const reg = openImporters();
114
+ reg.listeners.push(fn);
115
+ return (/**
116
+ * @return {?}
117
+ */
118
+ () => {
119
+ /** @type {?} */
120
+ const i = reg.listeners.indexOf(fn);
121
+ if (i >= 0)
122
+ reg.listeners.splice(i, 1);
123
+ });
124
+ }
125
+ /** @type {?} */
126
+ const appVersion = '1.1.20';
12
127
  export class CSVBoxButtonComponent {
13
128
  /**
14
129
  * @param {?} sanitizer
130
+ * @param {?} cdr
131
+ * @param {?} zone
15
132
  */
16
- constructor(sanitizer) {
133
+ constructor(sanitizer, cdr, zone) {
17
134
  this.sanitizer = sanitizer;
135
+ this.cdr = cdr;
136
+ this.zone = zone;
18
137
  this.isModalShown = false;
19
138
  this.licenseKey = null;
20
139
  this.uuid = null;
@@ -27,58 +146,138 @@ export class CSVBoxButtonComponent {
27
146
  this.lazy = false;
28
147
  this.iframe = null;
29
148
  this.disabled = true;
30
- }
31
- /**
32
- * @return {?}
33
- */
34
- ngOnInit() {
35
- this.uuid = generateUuid();
36
- /** @type {?} */
37
- let iframeUrl = buildImportUrl({
38
- licenseKey: this.licenseKey,
39
- customDomain: this.customDomain,
40
- dataLocation: this.dataLocation,
41
- language: this.language,
42
- theme: this.theme,
43
- environment: this.environment
44
- }, "angular", appVersion);
45
- this.safeUrl = this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, this.sanitizer.bypassSecurityTrustResourceUrl(iframeUrl));
46
- }
47
- /**
48
- * @param {?} changes
49
- * @return {?}
50
- */
51
- ngOnChanges(changes) {
52
- if (changes["user"] && changes['user'].currentValue != changes['user'].previousValue) {
53
- this.updateUserVariabe(changes['user'].currentValue);
54
- }
55
- }
56
- /**
57
- * @param {?} data
58
- * @return {?}
59
- */
60
- updateUserVariabe(data) {
61
- this.user = data;
62
- if (this.iframe && this.iframe.contentWindow) {
63
- this.iframe.contentWindow.postMessage({
64
- "customer": data
65
- }, "*");
66
- }
67
- }
68
- /**
69
- * @return {?}
70
- */
71
- ngAfterContentInit() {
72
- window.addEventListener("message", (/**
149
+ // True while a different importer on the page is open: the button stays disabled.
150
+ this.blockedByOther = false;
151
+ this.messageGate = createMessageGate();
152
+ this.importTracker = createImportTracker();
153
+ this.registryEntry = { getHolder: (/**
154
+ * @return {?}
155
+ */
156
+ () => this.holder) };
157
+ this.fileSender = createFileSender({
158
+ getIframe: (/**
159
+ * @return {?}
160
+ */
161
+ () => this.iframe),
162
+ getToken: (/**
163
+ * @return {?}
164
+ */
165
+ () => (/** @type {?} */ (this.uuid))),
166
+ getTargetOrigin: (/**
167
+ * @return {?}
168
+ */
169
+ () => (/** @type {?} */ (this.targetOrigin))),
170
+ getBaseDomain: (/**
171
+ * @return {?}
172
+ */
173
+ () => this.baseDomain),
174
+ takeFile: (/**
175
+ * @return {?}
176
+ */
177
+ () => {
178
+ /** @type {?} */
179
+ const file = this.pendingFile;
180
+ this.pendingFile = null;
181
+ return file;
182
+ }),
183
+ onSent: (/**
184
+ * @return {?}
185
+ */
186
+ () => this.startFileAckTimer())
187
+ });
188
+ this.unsubscribeOpenImporters = null;
189
+ this.pendingFile = null;
190
+ // Data-location sheets redirect to another host, so the iframe origin can differ from
191
+ // targetOrigin. baseDomain is used to check the real origin before trusting it.
192
+ this.baseDomain = "app.csvbox.io";
193
+ this.fileAckTimer = null;
194
+ this.messageListener = (/**
73
195
  * @param {?} event
74
196
  * @return {?}
75
197
  */
76
198
  (event) => {
199
+ // Older importers send these as bare strings, without a token.
200
+ /** @type {?} */
201
+ const legacy = classifyLegacyMessage(event.data);
202
+ if (legacy) {
203
+ // Legacy messages carry no token, so the only way to tell which importer sent one is its
204
+ // window. Ignore those that came from another instance's iframe (or anywhere else).
205
+ if (!this.iframe || event.source !== this.iframe.contentWindow) {
206
+ return;
207
+ }
208
+ // A newer importer sends the typed message as well; act on that one only.
209
+ if (!this.messageGate.allowLegacy()) {
210
+ return;
211
+ }
212
+ /** @type {?} */
213
+ const ended = this.importTracker.observe(legacy);
214
+ if (legacy.type === "mainModalHidden") {
215
+ this.handleModalClosed();
216
+ }
217
+ else if (legacy.type === "uploadSuccessful") {
218
+ if (this.onImport)
219
+ this.onImport(true);
220
+ if (this.isImported)
221
+ this.isImported(true);
222
+ if (this.imported)
223
+ this.imported(true);
224
+ }
225
+ else if (legacy.type === "uploadFailed") {
226
+ if (this.onImport)
227
+ this.onImport(false);
228
+ if (this.isImported)
229
+ this.isImported(false);
230
+ if (this.imported)
231
+ this.imported(false);
232
+ }
233
+ this.finishImport(ended);
234
+ return;
235
+ }
236
+ // Set-file handshake messages. The shared core does not classify these, so they are
237
+ // read here, behind the same unique_token check the core applies.
238
+ /** @type {?} */
239
+ const raw = event.data;
240
+ if (raw && typeof raw === "object" && raw.data && raw.data.unique_token == this.uuid) {
241
+ this.fileSender.learnOrigin(event);
242
+ if (raw.type === "csvbox-set-file-rejected" && raw.data.reason === "not-a-file") {
243
+ // Reply to our probe (it has no file). It only tells us the origin, so do nothing.
244
+ return;
245
+ }
246
+ if (raw.type === "csvbox-modal-shown") {
247
+ this.clearFileAckTimer();
248
+ registerOpenImporter(this.registryEntry);
249
+ // What the file path in openModal() is waiting for. display as well as
250
+ // pointer-events: a second file declined while the first was still opening the
251
+ // modal has put the holder away in the meantime.
252
+ this.isModalShown = true;
253
+ if (this.holder) {
254
+ this.holder.style.display = 'block';
255
+ this.holder.style.pointerEvents = 'auto';
256
+ }
257
+ return;
258
+ }
259
+ if (raw.type === "csvbox-set-file-rejected") {
260
+ this.clearFileAckTimer();
261
+ // The importer has the file and will not take it. Put the holder away only if the
262
+ // modal was never confirmed up: a file declined while it is open leaves that modal
263
+ // where it is, and its own 'csvbox-modal-hidden' will put the holder away.
264
+ if (!this.isModalShown && this.holder) {
265
+ this.holder.style.display = 'none';
266
+ this.holder.style.pointerEvents = 'auto';
267
+ unregisterOpenImporter(this.registryEntry);
268
+ }
269
+ console.warn("[csvbox] importer declined the supplied file: " + raw.data.reason);
270
+ return;
271
+ }
272
+ }
77
273
  /** @type {?} */
78
274
  let message = classifyStructuredMessage(event.data, (/** @type {?} */ (this.uuid)));
79
275
  if (!message) {
80
276
  return;
81
277
  }
278
+ this.messageGate.markTyped();
279
+ /** @type {?} */
280
+ const ended = this.importTracker.observe(message);
82
281
  if (message.type === "data-on-submit") {
83
282
  if (this.onSubmit)
84
283
  this.onSubmit(message.metadata);
@@ -88,9 +287,6 @@ export class CSVBoxButtonComponent {
88
287
  this.submitted(message.metadata);
89
288
  }
90
289
  else if (message.type === "data-push-status") {
91
- if (!message.success) {
92
- delete message.metadata["unique_token"];
93
- }
94
290
  if (this.onImport)
95
291
  this.onImport(message.success, message.metadata);
96
292
  if (this.isImported)
@@ -117,7 +313,59 @@ export class CSVBoxButtonComponent {
117
313
  if (this.imported)
118
314
  this.imported(false);
119
315
  }
120
- }), false);
316
+ this.finishImport(ended);
317
+ });
318
+ }
319
+ /**
320
+ * @return {?}
321
+ */
322
+ ngOnInit() {
323
+ this.uuid = generateUuid();
324
+ /** @type {?} */
325
+ let iframeUrl = buildImportUrl({
326
+ licenseKey: this.licenseKey,
327
+ customDomain: this.customDomain,
328
+ dataLocation: this.dataLocation,
329
+ language: this.language,
330
+ theme: this.theme,
331
+ environment: this.environment
332
+ }, "angular", appVersion);
333
+ // Default place to send the file. A file is only ever sent to a named origin, never "*".
334
+ this.targetOrigin = new URL(iframeUrl).origin;
335
+ this.baseDomain = this.customDomain || "app.csvbox.io";
336
+ this.safeUrl = this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, this.sanitizer.bypassSecurityTrustResourceUrl(iframeUrl));
337
+ }
338
+ /**
339
+ * @param {?} changes
340
+ * @return {?}
341
+ */
342
+ ngOnChanges(changes) {
343
+ if (changes["user"] && changes['user'].currentValue != changes['user'].previousValue) {
344
+ this.updateUserVariabe(changes['user'].currentValue);
345
+ }
346
+ }
347
+ /**
348
+ * @param {?} data
349
+ * @return {?}
350
+ */
351
+ updateUserVariabe(data) {
352
+ this.user = data;
353
+ if (this.iframe && this.iframe.contentWindow) {
354
+ this.iframe.contentWindow.postMessage({
355
+ "customer": data
356
+ }, "*");
357
+ }
358
+ }
359
+ /**
360
+ * @return {?}
361
+ */
362
+ ngAfterContentInit() {
363
+ window.addEventListener("message", this.messageListener, false);
364
+ this.syncBlocked();
365
+ this.unsubscribeOpenImporters = subscribeOpenImporters((/**
366
+ * @return {?}
367
+ */
368
+ () => this.syncBlocked()));
121
369
  if (this.lazy) {
122
370
  this.disabled = false;
123
371
  }
@@ -130,15 +378,22 @@ export class CSVBoxButtonComponent {
130
378
  * @return {?}
131
379
  */
132
380
  handleModalClosed() {
133
- if (this.holder)
134
- this.holder.style.display = 'none';
135
- this.isModalShown = false;
136
- this.isIframeLoaded = false;
137
- this.openModalOnIframeLoad = false;
138
- if (this.holder)
139
- this.holder.remove();
140
- this.holder = null;
141
- this.iframe = null;
381
+ if (this.importTracker.isInFlight()) {
382
+ // Closed after submitting and before the result arrived: keep the iframe and its listener
383
+ // so the late result still reaches onImport. It is removed once that result has been
384
+ // delivered (see finishImport), so the next open is a fresh load.
385
+ if (this.holder) {
386
+ this.holder.style.display = 'none';
387
+ this.holder.style.pointerEvents = 'auto';
388
+ }
389
+ this.isModalShown = false;
390
+ this.openModalOnIframeLoad = false;
391
+ this.clearFileAckTimer();
392
+ unregisterOpenImporter(this.registryEntry);
393
+ }
394
+ else {
395
+ this.destroyImporter();
396
+ }
142
397
  if (this.onClose)
143
398
  this.onClose();
144
399
  if (this.isClosed)
@@ -146,6 +401,40 @@ export class CSVBoxButtonComponent {
146
401
  if (this.closed)
147
402
  this.closed();
148
403
  }
404
+ // Called after the result of an import has been delivered. If the modal was closed in the
405
+ // meantime the iframe was only hidden, so remove it now.
406
+ /**
407
+ * @private
408
+ * @param {?} ended
409
+ * @return {?}
410
+ */
411
+ finishImport(ended) {
412
+ if (ended && !this.isModalShown && this.iframe) {
413
+ this.destroyImporter();
414
+ }
415
+ }
416
+ // Puts the importer away: the next open builds a new iframe with a new token.
417
+ /**
418
+ * @private
419
+ * @return {?}
420
+ */
421
+ destroyImporter() {
422
+ if (this.holder) {
423
+ this.holder.style.display = 'none';
424
+ this.holder.style.pointerEvents = 'auto';
425
+ this.holder.remove();
426
+ }
427
+ this.holder = null;
428
+ this.iframe = null;
429
+ this.isModalShown = false;
430
+ this.isIframeLoaded = false;
431
+ this.openModalOnIframeLoad = false;
432
+ this.messageGate.reset();
433
+ this.importTracker.reset();
434
+ // A new iframe is built on the next open, so the origin is learned again.
435
+ this.clearProbeTimer();
436
+ unregisterOpenImporter(this.registryEntry);
437
+ }
149
438
  /**
150
439
  * @return {?}
151
440
  */
@@ -153,11 +442,14 @@ export class CSVBoxButtonComponent {
153
442
  if (this.loadStarted)
154
443
  this.loadStarted();
155
444
  this.uuid = generateUuid();
445
+ this.messageGate.reset();
446
+ this.importTracker.reset();
156
447
  insertCSS();
157
448
  /** @type {?} */
158
449
  let iframe = document.createElement("iframe");
159
450
  this.iframe = iframe;
160
451
  iframe.setAttribute("src", this.safeUrl);
452
+ iframe.setAttribute("allow", "clipboard-read; clipboard-write *");
161
453
  iframe.frameBorder = "0";
162
454
  /** @type {?} */
163
455
  let self = this;
@@ -165,17 +457,19 @@ export class CSVBoxButtonComponent {
165
457
  * @return {?}
166
458
  */
167
459
  function () {
460
+ self.disabled = false;
461
+ self.isIframeLoaded = true;
462
+ // The handshake goes first: a consumer that calls openModalWithFile() from the ready
463
+ // callback needs the importer to already have its customer, columns, options and token.
464
+ if (self.iframe && self.iframe.contentWindow) {
465
+ self.iframe.contentWindow.postMessage(buildInitPayload(self.user, self.dynamicColumns, self.options, (/** @type {?} */ (self.uuid))), "*");
466
+ }
168
467
  if (self.onReady)
169
468
  self.onReady();
170
469
  if (self.isReady)
171
470
  self.isReady();
172
471
  if (self.importerReady)
173
472
  self.importerReady();
174
- self.disabled = false;
175
- self.isIframeLoaded = true;
176
- if (self.iframe && self.iframe.contentWindow) {
177
- self.iframe.contentWindow.postMessage(buildInitPayload(self.user, self.dynamicColumns, self.options, (/** @type {?} */ (self.uuid))), "*");
178
- }
179
473
  if (self.openModalOnIframeLoad) {
180
474
  self.openModal();
181
475
  }
@@ -185,11 +479,16 @@ export class CSVBoxButtonComponent {
185
479
  this.holder.setAttribute('id', `csvbox-embed-${this.uuid}`);
186
480
  this.holder.appendChild(iframe);
187
481
  document.body.insertAdjacentElement('beforeend', this.holder);
482
+ // The holder did not exist yet if openModal() asked for the importer before it was built.
483
+ restackOpenImporters(openImporters());
188
484
  }
189
485
  /**
190
486
  * @return {?}
191
487
  */
192
488
  openModal() {
489
+ // Counts as open from the moment it is requested, so the other buttons are disabled while
490
+ // this importer is still loading, and so it is stacked above any importer opened earlier.
491
+ registerOpenImporter(this.registryEntry);
193
492
  if (!this.iframe) {
194
493
  this.openModalOnIframeLoad = true;
195
494
  this.initImporter();
@@ -197,11 +496,36 @@ export class CSVBoxButtonComponent {
197
496
  }
198
497
  if (!this.isModalShown) {
199
498
  if (this.isIframeLoaded) {
200
- this.isModalShown = true;
201
- if (this.holder)
202
- this.holder.style.display = 'block';
203
- if (this.iframe && this.iframe.contentWindow) {
204
- this.iframe.contentWindow.postMessage('openModal', '*');
499
+ if (this.pendingFile) {
500
+ // The importer opens its own modal once it has the file, so that it can inject on
501
+ // 'shown.bs.modal'. Sending 'openModal' as well would race that.
502
+ //
503
+ // It can also decline: wrong step, an import file URL configured on the sheet, or
504
+ // an importer too old to know the message at all. So the holder goes up
505
+ // click-through and stays that way until 'csvbox-modal-shown' confirms the modal
506
+ // is really up. It covers the viewport at z-index 2147483647 and the importer
507
+ // renders transparent with its modal closed, so arming it on an unanswered message
508
+ // leaves an invisible sheet over the host page eating every click.
509
+ //
510
+ // display:block regardless, so the iframe lays out and animates normally; only
511
+ // pointer-events is held back. isModalShown likewise waits for the confirmation,
512
+ // or a declined file would latch the importer shut for good.
513
+ if (this.holder) {
514
+ this.holder.style.pointerEvents = 'none';
515
+ this.holder.style.display = 'block';
516
+ }
517
+ this.fileSender.send();
518
+ }
519
+ else {
520
+ this.isModalShown = true;
521
+ if (this.holder) {
522
+ // Explicit: a previously declined file leaves the holder click-through.
523
+ this.holder.style.pointerEvents = 'auto';
524
+ this.holder.style.display = 'block';
525
+ }
526
+ if (this.iframe && this.iframe.contentWindow) {
527
+ this.iframe.contentWindow.postMessage('openModal', '*');
528
+ }
205
529
  }
206
530
  }
207
531
  else {
@@ -209,13 +533,119 @@ export class CSVBoxButtonComponent {
209
533
  }
210
534
  }
211
535
  }
536
+ /**
537
+ * Open the importer on a File the host page already has, instead of the file picker.
538
+ *
539
+ * Reachable through a template reference (`#importer` then `importer.openModalWithFile(file)`)
540
+ * or `\@ViewChild(CSVBoxButtonComponent)`.
541
+ *
542
+ * The File crosses to the iframe by structured clone, so the importer receives the real
543
+ * object and applies its own extension, worksheet and size rules to it -- this does not
544
+ * bypass any of them. Pass a File; a Blob has no name for the importer to read an
545
+ * extension from.
546
+ * @param {?} file
547
+ * @return {?}
548
+ */
549
+ openModalWithFile(file) {
550
+ if (typeof File === 'undefined' || !(file instanceof File)) {
551
+ return;
552
+ }
553
+ this.pendingFile = file;
554
+ // Already open: hand it over now rather than holding it for the next open. The importer
555
+ // takes it only while it is still on the upload step, and ignores it once the user has a
556
+ // dataset and a mapping in progress.
557
+ if (this.isModalShown && this.iframe && this.isIframeLoaded) {
558
+ this.fileSender.send();
559
+ return;
560
+ }
561
+ this.openModal();
562
+ }
563
+ /**
564
+ * @return {?}
565
+ */
566
+ clearProbeTimer() {
567
+ this.clearFileAckTimer();
568
+ this.fileSender.reset();
569
+ }
570
+ /**
571
+ * @return {?}
572
+ */
573
+ startFileAckTimer() {
574
+ this.clearFileAckTimer();
575
+ this.fileAckTimer = setTimeout((/**
576
+ * @return {?}
577
+ */
578
+ () => {
579
+ this.fileAckTimer = null;
580
+ this.giveUpOnFile();
581
+ }), FILE_ACK_TIMEOUT_MS);
582
+ }
583
+ /**
584
+ * @return {?}
585
+ */
586
+ clearFileAckTimer() {
587
+ if (this.fileAckTimer) {
588
+ clearTimeout(this.fileAckTimer);
589
+ this.fileAckTimer = null;
590
+ }
591
+ }
592
+ // The importer never confirmed the file it was sent (an origin we do not trust, or an importer too
593
+ // old to know the message). Without this the holder would stay up, invisible and click-through,
594
+ // and the other instances' buttons would stay disabled for good.
595
+ /**
596
+ * @return {?}
597
+ */
598
+ giveUpOnFile() {
599
+ if (this.isModalShown) {
600
+ return;
601
+ }
602
+ /** @type {?} */
603
+ const holder = this.holder;
604
+ if (holder) {
605
+ holder.style.display = 'none';
606
+ holder.style.pointerEvents = 'auto';
607
+ }
608
+ unregisterOpenImporter(this.registryEntry);
609
+ console.warn("[csvbox] the importer did not respond to the supplied file");
610
+ }
611
+ /**
612
+ * @private
613
+ * @return {?}
614
+ */
615
+ syncBlocked() {
616
+ /** @type {?} */
617
+ const blocked = isBlockedByOpenImporter(this.registryEntry);
618
+ if (blocked !== this.blockedByOther) {
619
+ // The registry can call back from outside Angular's zone (another instance, another app).
620
+ this.zone.run((/**
621
+ * @return {?}
622
+ */
623
+ () => {
624
+ this.blockedByOther = blocked;
625
+ this.cdr.markForCheck();
626
+ }));
627
+ }
628
+ }
629
+ /**
630
+ * @return {?}
631
+ */
632
+ ngOnDestroy() {
633
+ window.removeEventListener("message", this.messageListener);
634
+ // Takes the holder out of document.body: left there, it would keep covering the page with
635
+ // an invisible full-screen layer that nothing is left to hide.
636
+ this.destroyImporter();
637
+ if (this.unsubscribeOpenImporters) {
638
+ this.unsubscribeOpenImporters();
639
+ this.unsubscribeOpenImporters = null;
640
+ }
641
+ }
212
642
  }
213
643
  CSVBoxButtonComponent.decorators = [
214
644
  { type: Component, args: [{
215
645
  selector: 'csvbox-button',
216
646
  template: `
217
647
  <div>
218
- <button [disabled]="disabled" #initiator (click)="openModal()" [attr.data-csvbox-token]="uuid">
648
+ <button [disabled]="disabled || blockedByOther" (click)="openModal()" [attr.data-csvbox-token]="uuid">
219
649
  <ng-content></ng-content>
220
650
  </button>
221
651
  </div>
@@ -224,10 +654,11 @@ CSVBoxButtonComponent.decorators = [
224
654
  ];
225
655
  /** @nocollapse */
226
656
  CSVBoxButtonComponent.ctorParameters = () => [
227
- { type: DomSanitizer }
657
+ { type: DomSanitizer },
658
+ { type: ChangeDetectorRef },
659
+ { type: NgZone }
228
660
  ];
229
661
  CSVBoxButtonComponent.propDecorators = {
230
- initiator: [{ type: ViewChild, args: ['initiator', { static: false },] }],
231
662
  onImport: [{ type: Input }],
232
663
  onReady: [{ type: Input }],
233
664
  onClose: [{ type: Input }],
@@ -260,8 +691,6 @@ if (false) {
260
691
  /** @type {?} */
261
692
  CSVBoxButtonComponent.prototype.isModalShown;
262
693
  /** @type {?} */
263
- CSVBoxButtonComponent.prototype.initiator;
264
- /** @type {?} */
265
694
  CSVBoxButtonComponent.prototype.onImport;
266
695
  /** @type {?} */
267
696
  CSVBoxButtonComponent.prototype.onReady;
@@ -320,8 +749,61 @@ if (false) {
320
749
  /** @type {?} */
321
750
  CSVBoxButtonComponent.prototype.disabled;
322
751
  /** @type {?} */
752
+ CSVBoxButtonComponent.prototype.blockedByOther;
753
+ /**
754
+ * @type {?}
755
+ * @private
756
+ */
757
+ CSVBoxButtonComponent.prototype.messageGate;
758
+ /**
759
+ * @type {?}
760
+ * @private
761
+ */
762
+ CSVBoxButtonComponent.prototype.importTracker;
763
+ /**
764
+ * @type {?}
765
+ * @private
766
+ */
767
+ CSVBoxButtonComponent.prototype.registryEntry;
768
+ /**
769
+ * @type {?}
770
+ * @private
771
+ */
772
+ CSVBoxButtonComponent.prototype.fileSender;
773
+ /**
774
+ * @type {?}
775
+ * @private
776
+ */
777
+ CSVBoxButtonComponent.prototype.unsubscribeOpenImporters;
778
+ /** @type {?} */
323
779
  CSVBoxButtonComponent.prototype.holder;
324
780
  /** @type {?} */
781
+ CSVBoxButtonComponent.prototype.pendingFile;
782
+ /** @type {?} */
783
+ CSVBoxButtonComponent.prototype.targetOrigin;
784
+ /** @type {?} */
785
+ CSVBoxButtonComponent.prototype.baseDomain;
786
+ /**
787
+ * @type {?}
788
+ * @private
789
+ */
790
+ CSVBoxButtonComponent.prototype.fileAckTimer;
791
+ /**
792
+ * @type {?}
793
+ * @private
794
+ */
795
+ CSVBoxButtonComponent.prototype.messageListener;
796
+ /** @type {?} */
325
797
  CSVBoxButtonComponent.prototype.sanitizer;
798
+ /**
799
+ * @type {?}
800
+ * @private
801
+ */
802
+ CSVBoxButtonComponent.prototype.cdr;
803
+ /**
804
+ * @type {?}
805
+ * @private
806
+ */
807
+ CSVBoxButtonComponent.prototype.zone;
326
808
  }
327
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3N2Ym94LWJ1dHRvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac3VtaXRfeWV3YWxlL2FuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvY3N2Ym94LWJ1dHRvbi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULFNBQVMsRUFDVCxLQUFLLEVBR0wsZUFBZSxFQUVoQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsWUFBWSxFQUFXLE1BQU0sMkJBQTJCLENBQUM7QUFDbEUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixFQUFFLHlCQUF5QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7O01BRWpILFVBQVUsR0FBRyxRQUFRO0FBYTNCLE1BQU0sT0FBTyxxQkFBcUI7Ozs7SUE0Q2hDLFlBQW1CLFNBQXNCO1FBQXRCLGNBQVMsR0FBVCxTQUFTLENBQWE7UUExQ3pDLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBcUJaLGVBQVUsR0FBa0IsSUFBSSxDQUFDO1FBRWpDLFNBQUksR0FBa0IsSUFBSSxDQUFDO1FBQzNCLGlCQUFZLEdBQWtCLElBQUksQ0FBQztRQUNuQyxpQkFBWSxHQUFrQixJQUFJLENBQUM7UUFDbkMsYUFBUSxHQUFrQixJQUFJLENBQUM7UUFHL0IsVUFBSyxHQUFrQixJQUFJLENBQUM7UUFFNUIsbUJBQWMsR0FBWSxLQUFLLENBQUM7UUFDaEMsMEJBQXFCLEdBQVksS0FBSyxDQUFDO1FBRXZDLFNBQUksR0FBWSxLQUFLLENBQUM7UUFJL0IsV0FBTSxHQUE2QixJQUFJLENBQUM7UUFFL0IsYUFBUSxHQUFZLElBQUksQ0FBQztJQUVVLENBQUM7Ozs7SUFJN0MsUUFBUTtRQUNOLElBQUksQ0FBQyxJQUFJLEdBQUcsWUFBWSxFQUFFLENBQUM7O1lBQ3ZCLFNBQVMsR0FBRyxj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SUFFaEMsOENBQWtDOztJQUNsQyx1Q0FBMkI7O0lBQzNCLDBDQUE4Qjs7SUFDOUIseUNBQTZCOztJQUM3Qiw0Q0FBZ0M7O0lBRWhDLHFDQUF1Qjs7SUFDdkIsK0NBQWlDOztJQUNqQywyQ0FBMEM7O0lBQzFDLHdDQUEwQjs7SUFDMUIscUNBQW9DOztJQUNwQyw2Q0FBNEM7O0lBQzVDLDZDQUE0Qzs7SUFDNUMseUNBQXdDOztJQUN4Qyw0Q0FBOEI7O0lBRTlCLHNDQUFxQzs7SUFFckMsK0NBQXlDOztJQUN6QyxzREFBZ0Q7O0lBRWhELHFDQUErQjs7SUFFL0Isd0NBQWE7O0lBRWIsdUNBQXdDOztJQUV4Qyx5Q0FBa0M7O0lBSWxDLHVDQUFZOztJQUZBLDBDQUE2QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgT25Jbml0LFxuICBWaWV3Q2hpbGQsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFNlY3VyaXR5Q29udGV4dCxcbiAgQWZ0ZXJDb250ZW50SW5pdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgRG9tU2FuaXRpemVyLCBTYWZlVXJsIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgeyBpbnNlcnRDU1MgfSBmcm9tICcuLi91dGxpcy9pbnNlcnRDU1MnO1xuaW1wb3J0IHsgYnVpbGRJbXBvcnRVcmwsIGdlbmVyYXRlVXVpZCwgYnVpbGRJbml0UGF5bG9hZCwgY2xhc3NpZnlTdHJ1Y3R1cmVkTWVzc2FnZSB9IGZyb20gJ0BzdW1pdF95ZXdhbGUvYWRhcHRlci1jb3JlJztcblxuY29uc3QgYXBwVmVyc2lvbiA9ICcxLjEuMTYnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjc3Zib3gtYnV0dG9uJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2PlxuICAgICAgPGJ1dHRvbiBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiAjaW5pdGlhdG9yIChjbGljayk9XCJvcGVuTW9kYWwoKVwiIFthdHRyLmRhdGEtY3N2Ym94LXRva2VuXT1cInV1aWRcIj5cbiAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIGBcbn0pXG5cbmV4cG9ydCBjbGFzcyBDU1ZCb3hCdXR0b25Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJDb250ZW50SW5pdCB7XG5cbiAgaXNNb2RhbFNob3duID0gZmFsc2U7XG5cbiAgQFZpZXdDaGlsZCgnaW5pdGlhdG9yJywge3N0YXRpYzogZmFsc2V9KSBpbml0aWF0b3I6IGFueTtcbiAgQElucHV0KCkgb25JbXBvcnQ/OiBGdW5jdGlvbjtcbiAgQElucHV0KCkgb25SZWFkeT86IEZ1bmN0aW9uO1xuICBASW5wdXQoKSBvbkNsb3NlPzogRnVuY3Rpb247XG4gIEBJbnB1dCgpIG9uU3VibWl0PzogRnVuY3Rpb247XG5cbiAgQElucHV0KCkgaXNJbXBvcnRlZD86IEZ1bmN0aW9uO1xuICBASW5wdXQoKSBpc1JlYWR5PzogRnVuY3Rpb247XG4gIEBJbnB1dCgpIGlzQ2xvc2VkPzogRnVuY3Rpb247XG4gIEBJbnB1dCgpIGlzU3VibWl0dGVkPzogRnVuY3Rpb247XG5cbiAgQElucHV0KCkgaW1wb3J0ZXJSZWFkeT86IEZ1bmN0aW9uO1xuICBASW5wdXQoKSBjbG9zZWQ/OiBGdW5jdGlvbjtcbiAgQElucHV0KCkgc3VibWl0dGVkPzogRnVuY3Rpb247XG4gIEBJbnB1dCgpIGltcG9ydGVkPzogRnVuY3Rpb247XG4gIEBJbnB1dCgpIGxvYWRTdGFydGVkPzogRnVuY3Rpb247XG5cbiAgQElucHV0KCkgdXNlcj86IG9iamVjdDtcbiAgQElucHV0KCkgZHluYW1pY0NvbHVtbnM/OiBvYmplY3Q7XG4gIEBJbnB1dCgpIGxpY2Vuc2VLZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBvcHRpb25zPzogb2JqZWN0O1xuICBASW5wdXQoKSB1dWlkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgY3VzdG9tRG9tYWluOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgZGF0YUxvY2F0aW9uOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgbGFuZ3VhZ2U6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBlbnZpcm9ubWVudD86IG9iamVjdDtcblxuICBASW5wdXQoKSB0aGVtZTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgQElucHV0KCkgaXNJZnJhbWVMb2FkZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgb3Blbk1vZGFsT25JZnJhbWVMb2FkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgQElucHV0KCkgbGF6eTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHNhZmVVcmw6IGFueTtcblxuICBpZnJhbWU6IEhUTUxJRnJhbWVFbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBzYW5pdGl6ZXI6RG9tU2FuaXRpemVyKSB7fVxuXG4gIGhvbGRlcjogYW55O1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMudXVpZCA9IGdlbmVyYXRlVXVpZCgpO1xuICAgIGxldCBpZnJhbWVVcmwgPSBidWlsZEltcG9ydFVybChcbiAgICAgIHtcbiAgICAgICAgbGljZW5zZUtleTogdGhpcy5saWNlbnNlS2V5LFxuICAgICAgICBjdXN0b21Eb21haW46IHRoaXMuY3VzdG9tRG9tYWluLFxuICAgICAgICBkYXRhTG9jYXRpb246IHRoaXMuZGF0YUxvY2F0aW9uLFxuICAgICAgICBsYW5ndWFnZTogdGhpcy5sYW5ndWFnZSxcbiAgICAgICAgdGhlbWU6IHRoaXMudGhlbWUsXG4gICAgICAgIGVudmlyb25tZW50OiB0aGlzLmVudmlyb25tZW50XG4gICAgICB9LFxuICAgICAgXCJhbmd1bGFyXCIsXG4gICAgICBhcHBWZXJzaW9uXG4gICAgKTtcbiAgICB0aGlzLnNhZmVVcmwgPSB0aGlzLnNhbml0aXplci5zYW5pdGl6ZShTZWN1cml0eUNvbnRleHQuUkVTT1VSQ0VfVVJMLCB0aGlzLnNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0UmVzb3VyY2VVcmwoaWZyYW1lVXJsKSk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgaWYoY2hhbmdlc1tcInVzZXJcIl0gJiYgY2hhbmdlc1sndXNlciddLmN1cnJlbnRWYWx1ZSAhPSBjaGFuZ2VzWyd1c2VyJ10ucHJldmlvdXNWYWx1ZSkge1xuICAgICAgdGhpcy51cGRhdGVVc2VyVmFyaWFiZShjaGFuZ2VzWyd1c2VyJ10uY3VycmVudFZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGVVc2VyVmFyaWFiZShkYXRhOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLnVzZXIgPSBkYXRhO1xuICAgIGlmICh0aGlzLmlmcmFtZSAmJiB0aGlzLmlmcmFtZS5jb250ZW50V2luZG93KSB7XG4gICAgICB0aGlzLmlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgXCJjdXN0b21lclwiIDogZGF0YVxuICAgICAgfSwgXCIqXCIpO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgKGV2ZW50KSA9PiB7XG4gICAgICBsZXQgbWVzc2FnZSA9IGNsYXNzaWZ5U3RydWN0dXJlZE1lc3NhZ2UoZXZlbnQuZGF0YSwgdGhpcy51dWlkISk7XG4gICAgICBpZiAoIW1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAobWVzc2FnZS50eXBlID09PSBcImRhdGEtb24tc3VibWl0XCIpIHtcbiAgICAgICAgaWYgKHRoaXMub25TdWJtaXQpIHRoaXMub25TdWJtaXQobWVzc2FnZS5tZXRhZGF0YSk7XG4gICAgICAgIGlmICh0aGlzLmlzU3VibWl0dGVkKSB0aGlzLmlzU3VibWl0dGVkKG1lc3NhZ2UubWV0YWRhdGEpO1xuICAgICAgICBpZiAodGhpcy5zdWJtaXR0ZWQpIHRoaXMuc3VibWl0dGVkKG1lc3NhZ2UubWV0YWRhdGEpO1xuICAgICAgfSBlbHNlIGlmIChtZXNzYWdlLnR5cGUgPT09IFwiZGF0YS1wdXNoLXN0YXR1c1wiKSB7XG4gICAgICAgIGlmICghbWVzc2FnZS5zdWNjZXNzKSB7XG4gICAgICAgICAgZGVsZXRlIG1lc3NhZ2UubWV0YWRhdGFbXCJ1bmlxdWVfdG9rZW5cIl07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub25JbXBvcnQpIHRoaXMub25JbXBvcnQobWVzc2FnZS5zdWNjZXNzLCBtZXNzYWdlLm1ldGFkYXRhKTtcbiAgICAgICAgaWYgKHRoaXMuaXNJbXBvcnRlZCkgdGhpcy5pc0ltcG9ydGVkKG1lc3NhZ2Uuc3VjY2VzcywgbWVzc2FnZS5tZXRhZGF0YSk7XG4gICAgICAgIGlmICh0aGlzLmltcG9ydGVkKSB0aGlzLmltcG9ydGVkKG1lc3NhZ2Uuc3VjY2VzcywgbWVzc2FnZS5tZXRhZGF0YSk7XG4gICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UudHlwZSA9PT0gXCJjc3Zib3gtbW9kYWwtaGlkZGVuXCIpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVNb2RhbENsb3NlZCgpO1xuICAgICAgfSBlbHNlIGlmIChtZXNzYWdlLnR5cGUgPT09IFwiY3N2Ym94LXVwbG9hZC1zdWNjZXNzZnVsXCIpIHtcbiAgICAgICAgICBpZiAodGhpcy5vbkltcG9ydCkgdGhpcy5vbkltcG9ydCh0cnVlKTtcbiAgICAgICAgICBpZiAodGhpcy5pc0ltcG9ydGVkKSB0aGlzLmlzSW1wb3J0ZWQodHJ1ZSk7XG4gICAgICAgICAgaWYgKHRoaXMuaW1wb3J0ZWQpIHRoaXMuaW1wb3J0ZWQodHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UudHlwZSA9PT0gXCJjc3Zib3gtdXBsb2FkLWZhaWxlZFwiKSB7XG4gICAgICAgICAgaWYgKHRoaXMub25JbXBvcnQpIHRoaXMub25JbXBvcnQoZmFsc2UpO1xuICAgICAgICAgIGlmICh0aGlzLmlzSW1wb3J0ZWQpIHRoaXMuaXNJbXBvcnRlZChmYWxzZSk7XG4gICAgICAgICAgaWYgKHRoaXMuaW1wb3J0ZWQpIHRoaXMuaW1wb3J0ZWQoZmFsc2UpO1xuICAgICAgfVxuICAgIH0sIGZhbHNlKTtcblxuICAgIGlmKHRoaXMubGF6eSkge1xuICAgICAgdGhpcy5kaXNhYmxlZCA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMuaW5pdEltcG9ydGVyKCk7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlTW9kYWxDbG9zZWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaG9sZGVyKSB0aGlzLmhvbGRlci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHRoaXMuaXNNb2RhbFNob3duID0gZmFsc2U7XG4gICAgdGhpcy5pc0lmcmFtZUxvYWRlZCA9IGZhbHNlO1xuICAgIHRoaXMub3Blbk1vZGFsT25JZnJhbWVMb2FkID0gZmFsc2U7XG4gICAgaWYgKHRoaXMuaG9sZGVyKSB0aGlzLmhvbGRlci5yZW1vdmUoKTtcbiAgICB0aGlzLmhvbGRlciA9IG51bGw7XG4gICAgdGhpcy5pZnJhbWUgPSBudWxsO1xuICAgIGlmICh0aGlzLm9uQ2xvc2UpIHRoaXMub25DbG9zZSgpO1xuICAgIGlmICh0aGlzLmlzQ2xvc2VkKSB0aGlzLmlzQ2xvc2VkKCk7XG4gICAgaWYgKHRoaXMuY2xvc2VkKSB0aGlzLmNsb3NlZCgpO1xuICB9XG5cbiAgaW5pdEltcG9ydGVyKCkge1xuICAgIGlmICh0aGlzLmxvYWRTdGFydGVkKSB0aGlzLmxvYWRTdGFydGVkKCk7XG5cbiAgICB0aGlzLnV1aWQgPSBnZW5lcmF0ZVV1aWQoKTtcblxuICAgIGluc2VydENTUygpO1xuXG4gICAgbGV0IGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpZnJhbWVcIik7XG4gICAgdGhpcy5pZnJhbWUgPSBpZnJhbWU7XG4gICAgaWZyYW1lLnNldEF0dHJpYnV0ZShcInNyY1wiLCB0aGlzLnNhZmVVcmwpO1xuICAgIGlmcmFtZS5mcmFtZUJvcmRlciA9IFwiMFwiO1xuXG4gICAgbGV0IHNlbGYgPSB0aGlzO1xuICAgIGlmcmFtZS5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoc2VsZi5vblJlYWR5KSBzZWxmLm9uUmVhZHkoKTtcbiAgICAgIGlmIChzZWxmLmlzUmVhZHkpIHNlbGYuaXNSZWFkeSgpO1xuICAgICAgaWYgKHNlbGYuaW1wb3J0ZXJSZWFkeSkgc2VsZi5pbXBvcnRlclJlYWR5KCk7XG5cbiAgICAgIHNlbGYuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgIHNlbGYuaXNJZnJhbWVMb2FkZWQgPSB0cnVlO1xuICAgICAgaWYgKHNlbGYuaWZyYW1lICYmIHNlbGYuaWZyYW1lLmNvbnRlbnRXaW5kb3cpIHtcbiAgICAgICAgc2VsZi5pZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZShidWlsZEluaXRQYXlsb2FkKHNlbGYudXNlciwgc2VsZi5keW5hbWljQ29sdW1ucywgc2VsZi5vcHRpb25zLCBzZWxmLnV1aWQhKSwgXCIqXCIpO1xuICAgICAgfVxuICAgICAgaWYoc2VsZi5vcGVuTW9kYWxPbklmcmFtZUxvYWQpIHtcbiAgICAgICAgc2VsZi5vcGVuTW9kYWwoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmhvbGRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMuaG9sZGVyLmNsYXNzTGlzdC5hZGQoJ2NzdmJveC1ob2xkZXInKTtcbiAgICB0aGlzLmhvbGRlci5zZXRBdHRyaWJ1dGUoJ2lkJywgYGNzdmJveC1lbWJlZC0ke3RoaXMudXVpZH1gKTtcbiAgICB0aGlzLmhvbGRlci5hcHBlbmRDaGlsZChpZnJhbWUpO1xuXG4gICAgZG9jdW1lbnQuYm9keS5pbnNlcnRBZGphY2VudEVsZW1lbnQoXG4gICAgICAnYmVmb3JlZW5kJywgdGhpcy5ob2xkZXJcbiAgICApO1xuICB9XG5cbiAgb3Blbk1vZGFsKCk6IHZvaWQge1xuICAgIGlmKCF0aGlzLmlmcmFtZSkge1xuICAgICAgICB0aGlzLm9wZW5Nb2RhbE9uSWZyYW1lTG9hZCA9IHRydWU7XG4gICAgICAgIHRoaXMuaW5pdEltcG9ydGVyKCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYoIXRoaXMuaXNNb2RhbFNob3duKSB7XG4gICAgICBpZih0aGlzLmlzSWZyYW1lTG9hZGVkKSB7XG4gICAgICAgICAgdGhpcy5pc01vZGFsU2hvd24gPSB0cnVlO1xuICAgICAgICAgIGlmKHRoaXMuaG9sZGVyKSB0aGlzLmhvbGRlci5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgICBpZih0aGlzLmlmcmFtZSAmJiB0aGlzLmlmcmFtZS5jb250ZW50V2luZG93KSB7XG4gICAgICAgICAgICB0aGlzLmlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKCdvcGVuTW9kYWwnLCAnKicpO1xuICAgICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5vcGVuTW9kYWxPbklmcmFtZUxvYWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG59XG4iXX0=
809
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3N2Ym94LWJ1dHRvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac3VtaXRfeWV3YWxlL2FuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvY3N2Ym94LWJ1dHRvbi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULEtBQUssRUFHTCxlQUFlLEVBR2YsaUJBQWlCLEVBQ2pCLE1BQU0sRUFDUCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDekQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLG1CQUFtQixFQUFFLGdCQUFnQixFQUFFLHlCQUF5QixFQUFFLHFCQUFxQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7OztNQUdsTSxtQkFBbUIsR0FBRyxJQUFJOzs7O0FBT2hDLGdDQUFvRTs7O0lBQXRDLHNDQUFvQzs7Ozs7QUFDbEUsNEJBQW9GOzs7SUFBMUQsNkJBQTBCOztJQUFDLGtDQUE2Qjs7O01BQzVFLGtCQUFrQixHQUFHLHVCQUF1Qjs7TUFDNUMsV0FBVyxHQUFHLFVBQVU7Ozs7QUFFOUIsU0FBUyxhQUFhOztVQUNkLENBQUMsR0FBRyxtQkFBQSxNQUFNLEVBQU87SUFDdkIsSUFBSSxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQztRQUFFLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDaEYsT0FBTyxDQUFDLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUMvQixDQUFDOzs7OztBQUVELFNBQVMsb0JBQW9CLENBQUMsR0FBa0I7SUFDOUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPOzs7OztJQUFD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S0FBSzt5QkFDTCxLQUFLO3NCQUNMLEtBQUs7bUJBQ0wsS0FBSzsyQkFDTCxLQUFLOzJCQUNMLEtBQUs7dUJBQ0wsS0FBSzswQkFDTCxLQUFLO29CQUVMLEtBQUs7NkJBRUwsS0FBSztvQ0FDTCxLQUFLO21CQUVMLEtBQUs7dUJBTUwsS0FBSzs7OztJQXZDTiw2Q0FBcUI7O0lBRXJCLHlDQUE2Qjs7SUFDN0Isd0NBQTRCOztJQUM1Qix3Q0FBNEI7O0lBQzVCLHlDQUE2Qjs7SUFFN0IsMkNBQStCOztJQUMvQix3Q0FBNEI7O0lBQzVCLHlDQUE2Qjs7SUFDN0IsNENBQWdDOztJQUVoQyw4Q0FBa0M7O0lBQ2xDLHVDQUEyQjs7SUFDM0IsMENBQThCOztJQUM5Qix5Q0FBNkI7O0lBQzdCLDRDQUFnQzs7SUFFaEMscUNBQXVCOztJQUN2QiwrQ0FBaUM7O0lBQ2pDLDJDQUEwQzs7SUFDMUMsd0NBQTBCOztJQUMxQixxQ0FBb0M7O0lBQ3BDLDZDQUE0Qzs7SUFDNUMsNkNBQTRDOztJQUM1Qyx5Q0FBd0M7O0lBQ3hDLDRDQUE4Qjs7SUFFOUIsc0NBQXFDOztJQUVyQywrQ0FBeUM7O0lBQ3pDLHNEQUFnRDs7SUFFaEQscUNBQStCOztJQUUvQix3Q0FBYTs7SUFFYix1Q0FBd0M7O0lBRXhDLHlDQUFrQzs7SUFLbEMsK0NBQWdDOzs7OztJQUVoQyw0Q0FBMEM7Ozs7O0lBQzFDLDhDQUE4Qzs7Ozs7SUFFOUMsOENBQTRFOzs7OztJQUU1RSwyQ0FXRzs7Ozs7SUFFSCx5REFBNkQ7O0lBRTdELHVDQUFZOztJQUVaLDRDQUFnQzs7SUFFaEMsNkNBQWlDOztJQUlqQywyQ0FBcUM7Ozs7O0lBRXJDLDZDQUFpQzs7Ozs7SUFxQ2pDLGdEQThGRTs7SUF0S1UsMENBQTZCOzs7OztJQUFFLG9DQUE4Qjs7Ozs7SUFBRSxxQ0FBb0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIE9uSW5pdCxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgU2VjdXJpdHlDb250ZXh0LFxuICBBZnRlckNvbnRlbnRJbml0LFxuICBPbkRlc3Ryb3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBOZ1pvbmVcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgaW5zZXJ0Q1NTIH0gZnJvbSAnLi4vdXRsaXMvaW5zZXJ0Q1NTJztcbmltcG9ydCB7IGJ1aWxkSW1wb3J0VXJsLCBnZW5lcmF0ZVV1aWQsIGJ1aWxkSW5pdFBheWxvYWQsIGNyZWF0ZU1lc3NhZ2VHYXRlLCBjcmVhdGVJbXBvcnRUcmFja2VyLCBjcmVhdGVGaWxlU2VuZGVyLCBjbGFzc2lmeVN0cnVjdHVyZWRNZXNzYWdlLCBjbGFzc2lmeUxlZ2FjeU1lc3NhZ2UgfSBmcm9tICdAc3VtaXRfeWV3YWxlL2FkYXB0ZXItY29yZSc7XG5cbi8vIEhvdyBsb25nIHdlIHdhaXQgZm9yIHRoZSBpbXBvcnRlciB0byBjb25maXJtIGEgZmlsZSBpdCB3YXMgc2VudCBiZWZvcmUgZ2l2aW5nIHVwIG9uIGl0LlxuY29uc3QgRklMRV9BQ0tfVElNRU9VVF9NUyA9IDgwMDA7XG5cbi8vIFBhZ2Utd2lkZSByZWNvcmQgb2YgdGhlIGltcG9ydGVycyB0aGF0IGFyZSBvcGVuIG9yIG9wZW5pbmcsIHNoYXJlZCBieSBldmVyeSBDU1ZCb3ggYWRhcHRlclxuLy8gb24gdGhlIHBhZ2UgKGl0IGxpdmVzIG9uIHdpbmRvdyBzbyBzZXBhcmF0ZSBjb3BpZXMgb2YgYW4gYWRhcHRlciBzZWUgdGhlIHNhbWUgbGlzdCkuIEl0IGRvZXNcbi8vIHR3byB0aGluZ3M6IHRoZSBuZXdlc3QgaW1wb3J0ZXIgaXMgc3RhY2tlZCBvbiB0b3AgKGV2ZXJ5IGhvbGRlciBpcyBmaXhlZCwgZnVsbCBzY3JlZW4gYW5kXG4vLyB6LWluZGV4IDIxNDc0ODM2NDcsIHNvIGVxdWFsIHotaW5kZXhlcyB3b3VsZCBsZWF2ZSB0aGUgb25lIHRoYXQgY29tZXMgZmlyc3QgaW4gdGhlIERPTSBvblxuLy8gdG9wKSwgYW5kIHRoZSBvdGhlciBpbnN0YW5jZXMgbGVhcm4gdGhhdCBhbiBpbXBvcnRlciBpcyBvcGVuIHNvIHRoZXkgY2FuIGRpc2FibGUgdGhlaXIgYnV0dG9uLlxuaW50ZXJmYWNlIE9wZW5JbXBvcnRlckVudHJ5IHsgZ2V0SG9sZGVyOiAoKSA9PiBIVE1MRWxlbWVudCB8IG51bGw7IH1cbmludGVyZmFjZSBPcGVuSW1wb3J0ZXJzIHsgb3BlbjogT3BlbkltcG9ydGVyRW50cnlbXTsgbGlzdGVuZXJzOiBBcnJheTwoKSA9PiB2b2lkPjsgfVxuY29uc3QgT1BFTl9JTVBPUlRFUlNfS0VZID0gJ19fY3N2Ym94T3BlbkltcG9ydGVycyc7XG5jb25zdCBUT1BfWl9JTkRFWCA9IDIxNDc0ODM2NDc7XG5cbmZ1bmN0aW9uIG9wZW5JbXBvcnRlcnMoKTogT3BlbkltcG9ydGVycyB7XG4gIGNvbnN0IHcgPSB3aW5kb3cgYXMgYW55O1xuICBpZiAoIXdbT1BFTl9JTVBPUlRFUlNfS0VZXSkgd1tPUEVOX0lNUE9SVEVSU19LRVldID0geyBvcGVuOiBbXSwgbGlzdGVuZXJzOiBbXSB9O1xuICByZXR1cm4gd1tPUEVOX0lNUE9SVEVSU19LRVldO1xufVxuXG5mdW5jdGlvbiByZXN0YWNrT3BlbkltcG9ydGVycyhyZWc6IE9wZW5JbXBvcnRlcnMpOiB2b2lkIHtcbiAgcmVnLm9wZW4uZm9yRWFjaCgoZW50cnksIGkpID0+IHtcbiAgICBjb25zdCBob2xkZXIgPSBlbnRyeS5nZXRIb2xkZXIoKTtcbiAgICBpZiAoaG9sZGVyKSBob2xkZXIuc3R5bGUuekluZGV4ID0gU3RyaW5nKFRPUF9aX0lOREVYIC0gKHJlZy5vcGVuLmxlbmd0aCAtIDEgLSBpKSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiByZWdpc3Rlck9wZW5JbXBvcnRlcihlbnRyeTogT3BlbkltcG9ydGVyRW50cnkpOiB2b2lkIHtcbiAgY29uc3QgcmVnID0gb3BlbkltcG9ydGVycygpO1xuICBpZiAocmVnLm9wZW4uaW5kZXhPZihlbnRyeSkgPj0gMCkgcmV0dXJuO1xuICByZWcub3Blbi5wdXNoKGVudHJ5KTtcbiAgcmVzdGFja09wZW5JbXBvcnRlcnMocmVnKTtcbiAgcmVnLmxpc3RlbmVycy5zbGljZSgpLmZvckVhY2goZm4gPT4gZm4oKSk7XG59XG5cbmZ1bmN0aW9uIHVucmVnaXN0ZXJPcGVuSW1wb3J0ZXIoZW50cnk6IE9wZW5JbXBvcnRlckVudHJ5KTogdm9pZCB7XG4gIGNvbnN0IHJlZyA9IG9wZW5JbXBvcnRlcnMoKTtcbiAgY29uc3QgaSA9IHJlZy5vcGVuLmluZGV4T2YoZW50cnkpO1xuICBpZiAoaSA8IDApIHJldHVybjtcbiAgcmVnLm9wZW4uc3BsaWNlKGksIDEpO1xuICByZXN0YWNrT3BlbkltcG9ydGVycyhyZWcpO1xuICByZWcubGlzdGVuZXJzLnNsaWNlKCkuZm9yRWFjaChmbiA9PiBmbigpKTtcbn1cblxuZnVuY3Rpb24gaXNCbG9ja2VkQnlPcGVuSW1wb3J0ZXIoZW50cnk6IE9wZW5JbXBvcnRlckVudHJ5KTogYm9vbGVhbiB7XG4gIGNvbnN0IHJlZyA9IG9wZW5JbXBvcnRlcnMoKTtcbiAgcmV0dXJuIHJlZy5vcGVuLmxlbmd0aCA+IDAgJiYgcmVnLm9wZW4uaW5kZXhPZihlbnRyeSkgPCAwO1xufVxuXG5mdW5jdGlvbiBzdWJzY3JpYmVPcGVuSW1wb3J0ZXJzKGZuOiAoKSA9PiB2b2lkKTogKCkgPT4gdm9pZCB7XG4gIGNvbnN0IHJlZyA9IG9wZW5JbXBvcnRlcnMoKTtcbiAgcmVnLmxpc3RlbmVycy5wdXNoKGZuKTtcbiAgcmV0dXJuICgpID0+IHtcbiAgICBjb25zdCBpID0gcmVnLmxpc3RlbmVycy5pbmRleE9mKGZuKTtcbiAgICBpZiAoaSA+PSAwKSByZWcubGlzdGVuZXJzLnNwbGljZShpLCAxKTtcbiAgfTtcbn1cblxuY29uc3QgYXBwVmVyc2lvbiA9ICcxLjEuMjAnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjc3Zib3gtYnV0dG9uJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2PlxuICAgICAgPGJ1dHRvbiBbZGlzYWJsZWRdPVwiZGlzYWJsZWQgfHwgYmxvY2tlZEJ5T3RoZXJcIiAoY2xpY2spPVwib3Blbk1vZGFsKClcIiBbYXR0ci5kYXRhLWNzdmJveC10b2tlbl09XCJ1dWlkXCI+XG4gICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICBgXG59KVxuXG5leHBvcnQgY2xhc3MgQ1NWQm94QnV0dG9uQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG5cbiAgaXNNb2RhbFNob3duID0gZmFsc2U7XG5cbiAgQElucHV0KCkgb25JbXBvcnQ/OiBGdW5jdGlvbjtcbiAgQElucHV0KCkgb25SZWFkeT86IEZ1bmN0aW9uO1xuICBASW5wdXQoKSBvbkNsb3NlPzogRnVuY3Rpb247XG4gIEBJbnB1dCgpIG9uU3VibWl0PzogRnVuY3Rpb247XG5cbiAgQElucHV0KCkgaXNJbXBvcnRlZD86IEZ1bmN0aW9uO1xuICBASW5wdXQoKSBpc1JlYWR5PzogRnVuY3Rpb247XG4gIEBJbnB1dCgpIGlzQ2xvc2VkPzogRnVuY3Rpb247XG4gIEBJbnB1dCgpIGlzU3VibWl0dGVkPzogRnVuY3Rpb247XG5cbiAgQElucHV0KCkgaW1wb3J0ZXJSZWFkeT86IEZ1bmN0aW9uO1xuICBASW5wdXQoKSBjbG9zZWQ/OiBGdW5jdGlvbjtcbiAgQElucHV0KCkgc3VibWl0dGVkPzogRnVuY3Rpb247XG4gIEBJbnB1dCgpIGltcG9ydGVkPzogRnVuY3Rpb247XG4gIEBJbnB1dCgpIGxvYWRTdGFydGVkPzogRnVuY3Rpb247XG5cbiAgQElucHV0KCkgdXNlcj86IG9iamVjdDtcbiAgQElucHV0KCkgZHluYW1pY0NvbHVtbnM/OiBvYmplY3Q7XG4gIEBJbnB1dCgpIGxpY2Vuc2VLZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBvcHRpb25zPzogb2JqZWN0O1xuICBASW5wdXQoKSB1dWlkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgY3VzdG9tRG9tYWluOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgZGF0YUxvY2F0aW9uOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgbGFuZ3VhZ2U6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBlbnZpcm9ubWVudD86IG9iamVjdDtcblxuICBASW5wdXQoKSB0aGVtZTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgQElucHV0KCkgaXNJZnJhbWVMb2FkZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgb3Blbk1vZGFsT25JZnJhbWVMb2FkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgQElucHV0KCkgbGF6eTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHNhZmVVcmw6IGFueTtcblxuICBpZnJhbWU6IEhUTUxJRnJhbWVFbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBzYW5pdGl6ZXI6RG9tU2FuaXRpemVyLCBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsIHByaXZhdGUgem9uZTogTmdab25lKSB7fVxuXG4gIC8vIFRydWUgd2hpbGUgYSBkaWZmZXJlbnQgaW1wb3J0ZXIgb24gdGhlIHBhZ2UgaXMgb3BlbjogdGhlIGJ1dHRvbiBzdGF5cyBkaXNhYmxlZC5cbiAgYmxvY2tlZEJ5T3RoZXI6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcml2YXRlIG1lc3NhZ2VHYXRlID0gY3JlYXRlTWVzc2FnZUdhdGUoKTtcbiAgcHJpdmF0ZSBpbXBvcnRUcmFja2VyID0gY3JlYXRlSW1wb3J0VHJhY2tlcigpO1xuXG4gIHByaXZhdGUgcmVnaXN0cnlFbnRyeTogT3BlbkltcG9ydGVyRW50cnkgPSB7IGdldEhvbGRlcjogKCkgPT4gdGhpcy5ob2xkZXIgfTtcblxuICBwcml2YXRlIGZpbGVTZW5kZXIgPSBjcmVhdGVGaWxlU2VuZGVyKHtcbiAgICBnZXRJZnJhbWU6ICgpID0+IHRoaXMuaWZyYW1lLFxuICAgIGdldFRva2VuOiAoKSA9PiB0aGlzLnV1aWQgYXMgc3RyaW5nLFxuICAgIGdldFRhcmdldE9yaWdpbjogKCkgPT4gdGhpcy50YXJnZXRPcmlnaW4gYXMgc3RyaW5nLFxuICAgIGdldEJhc2VEb21haW46ICgpID0+IHRoaXMuYmFzZURvbWFpbixcbiAgICB0YWtlRmlsZTogKCkgPT4ge1xuICAgICAgY29uc3QgZmlsZSA9IHRoaXMucGVuZGluZ0ZpbGU7XG4gICAgICB0aGlzLnBlbmRpbmdGaWxlID0gbnVsbDtcbiAgICAgIHJldHVybiBmaWxlO1xuICAgIH0sXG4gICAgb25TZW50OiAoKSA9PiB0aGlzLnN0YXJ0RmlsZUFja1RpbWVyKClcbiAgfSk7XG5cbiAgcHJpdmF0ZSB1bnN1YnNjcmliZU9wZW5JbXBvcnRlcnM6ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuXG4gIGhvbGRlcjogYW55O1xuXG4gIHBlbmRpbmdGaWxlOiBGaWxlIHwgbnVsbCA9IG51bGw7XG5cbiAgdGFyZ2V0T3JpZ2luOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLy8gRGF0YS1sb2NhdGlvbiBzaGVldHMgcmVkaXJlY3QgdG8gYW5vdGhlciBob3N0LCBzbyB0aGUgaWZyYW1lIG9yaWdpbiBjYW4gZGlmZmVyIGZyb21cbiAgLy8gdGFyZ2V0T3JpZ2luLiBiYXNlRG9tYWluIGlzIHVzZWQgdG8gY2hlY2sgdGhlIHJlYWwgb3JpZ2luIGJlZm9yZSB0cnVzdGluZyBpdC5cbiAgYmFzZURvbWFpbjogc3RyaW5nID0gXCJhcHAuY3N2Ym94LmlvXCI7XG5cbiAgcHJpdmF0ZSBmaWxlQWNrVGltZXI6IGFueSA9IG51bGw7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy51dWlkID0gZ2VuZXJhdGVVdWlkKCk7XG4gICAgbGV0IGlmcmFtZVVybCA9IGJ1aWxkSW1wb3J0VXJsKFxuICAgICAge1xuICAgICAgICBsaWNlbnNlS2V5OiB0aGlzLmxpY2Vuc2VLZXksXG4gICAgICAgIGN1c3RvbURvbWFpbjogdGhpcy5jdXN0b21Eb21haW4sXG4gICAgICAgIGRhdGFMb2NhdGlvbjogdGhpcy5kYXRhTG9jYXRpb24sXG4gICAgICAgIGxhbmd1YWdlOiB0aGlzLmxhbmd1YWdlLFxuICAgICAgICB0aGVtZTogdGhpcy50aGVtZSxcbiAgICAgICAgZW52aXJvbm1lbnQ6IHRoaXMuZW52aXJvbm1lbnRcbiAgICAgIH0sXG4gICAgICBcImFuZ3VsYXJcIixcbiAgICAgIGFwcFZlcnNpb25cbiAgICApO1xuICAgIC8vIERlZmF1bHQgcGxhY2UgdG8gc2VuZCB0aGUgZmlsZS4gQSBmaWxlIGlzIG9ubHkgZXZlciBzZW50IHRvIGEgbmFtZWQgb3JpZ2luLCBuZXZlciBcIipcIi5cbiAgICB0aGlzLnRhcmdldE9yaWdpbiA9IG5ldyBVUkwoaWZyYW1lVXJsKS5vcmlnaW47XG4gICAgdGhpcy5iYXNlRG9tYWluID0gdGhpcy5jdXN0b21Eb21haW4gfHwgXCJhcHAuY3N2Ym94LmlvXCI7XG4gICAgdGhpcy5zYWZlVXJsID0gdGhpcy5zYW5pdGl6ZXIuc2FuaXRpemUoU2VjdXJpdHlDb250ZXh0LlJFU09VUkNFX1VSTCwgdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFJlc291cmNlVXJsKGlmcmFtZVVybCkpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGlmKGNoYW5nZXNbXCJ1c2VyXCJdICYmIGNoYW5nZXNbJ3VzZXInXS5jdXJyZW50VmFsdWUgIT0gY2hhbmdlc1sndXNlciddLnByZXZpb3VzVmFsdWUpIHtcbiAgICAgIHRoaXMudXBkYXRlVXNlclZhcmlhYmUoY2hhbmdlc1sndXNlciddLmN1cnJlbnRWYWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlVXNlclZhcmlhYmUoZGF0YTogYW55KTogdm9pZCB7XG4gICAgdGhpcy51c2VyID0gZGF0YTtcbiAgICBpZiAodGhpcy5pZnJhbWUgJiYgdGhpcy5pZnJhbWUuY29udGVudFdpbmRvdykge1xuICAgICAgdGhpcy5pZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSh7XG4gICAgICAgIFwiY3VzdG9tZXJcIiA6IGRhdGFcbiAgICAgIH0sIFwiKlwiKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1lc3NhZ2VMaXN0ZW5lciA9IChldmVudDogTWVzc2FnZUV2ZW50KSA9PiB7XG4gICAgLy8gT2xkZXIgaW1wb3J0ZXJzIHNlbmQgdGhlc2UgYXMgYmFyZSBzdHJpbmdzLCB3aXRob3V0IGEgdG9rZW4uXG4gICAgY29uc3QgbGVnYWN5ID0gY2xhc3NpZnlMZWdhY3lNZXNzYWdlKGV2ZW50LmRhdGEpO1xuICAgIGlmIChsZWdhY3kpIHtcbiAgICAgIC8vIExlZ2FjeSBtZXNzYWdlcyBjYXJyeSBubyB0b2tlbiwgc28gdGhlIG9ubHkgd2F5IHRvIHRlbGwgd2hpY2ggaW1wb3J0ZXIgc2VudCBvbmUgaXMgaXRzXG4gICAgICAvLyB3aW5kb3cuIElnbm9yZSB0aG9zZSB0aGF0IGNhbWUgZnJvbSBhbm90aGVyIGluc3RhbmNlJ3MgaWZyYW1lIChvciBhbnl3aGVyZSBlbHNlKS5cbiAgICAgIGlmICghdGhpcy5pZnJhbWUgfHwgZXZlbnQuc291cmNlICE9PSB0aGlzLmlmcmFtZS5jb250ZW50V2luZG93KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIC8vIEEgbmV3ZXIgaW1wb3J0ZXIgc2VuZHMgdGhlIHR5cGVkIG1lc3NhZ2UgYXMgd2VsbDsgYWN0IG9uIHRoYXQgb25lIG9ubHkuXG4gICAgICBpZiAoIXRoaXMubWVzc2FnZUdhdGUuYWxsb3dMZWdhY3koKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBlbmRlZCA9IHRoaXMuaW1wb3J0VHJhY2tlci5vYnNlcnZlKGxlZ2FjeSk7XG4gICAgICBpZiAobGVnYWN5LnR5cGUgPT09IFwibWFpbk1vZGFsSGlkZGVuXCIpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVNb2RhbENsb3NlZCgpO1xuICAgICAgfSBlbHNlIGlmIChsZWdhY3kudHlwZSA9PT0gXCJ1cGxvYWRTdWNjZXNzZnVsXCIpIHtcbiAgICAgICAgaWYgKHRoaXMub25JbXBvcnQpIHRoaXMub25JbXBvcnQodHJ1ZSk7XG4gICAgICAgIGlmICh0aGlzLmlzSW1wb3J0ZWQpIHRoaXMuaXNJbXBvcnRlZCh0cnVlKTtcbiAgICAgICAgaWYgKHRoaXMuaW1wb3J0ZWQpIHRoaXMuaW1wb3J0ZWQodHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKGxlZ2FjeS50eXBlID09PSBcInVwbG9hZEZhaWxlZFwiKSB7XG4gICAgICAgIGlmICh0aGlzLm9uSW1wb3J0KSB0aGlzLm9uSW1wb3J0KGZhbHNlKTtcbiAgICAgICAgaWYgKHRoaXMuaXNJbXBvcnRlZCkgdGhpcy5pc0ltcG9ydGVkKGZhbHNlKTtcbiAgICAgICAgaWYgKHRoaXMuaW1wb3J0ZWQpIHRoaXMuaW1wb3J0ZWQoZmFsc2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5maW5pc2hJbXBvcnQoZW5kZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNldC1maWxlIGhhbmRzaGFrZSBtZXNzYWdlcy4gVGhlIHNoYXJlZCBjb3JlIGRvZXMgbm90IGNsYXNzaWZ5IHRoZXNlLCBzbyB0aGV5IGFyZVxuICAgIC8vIHJlYWQgaGVyZSwgYmVoaW5kIHRoZSBzYW1lIHVuaXF1ZV90b2tlbiBjaGVjayB0aGUgY29yZSBhcHBsaWVzLlxuICAgIGNvbnN0IHJhdyA9IGV2ZW50LmRhdGE7XG4gICAgaWYgKHJhdyAmJiB0eXBlb2YgcmF3ID09PSBcIm9iamVjdFwiICYmIHJhdy5kYXRhICYmIHJhdy5kYXRhLnVuaXF1ZV90b2tlbiA9PSB0aGlzLnV1aWQpIHtcbiAgICAgIHRoaXMuZmlsZVNlbmRlci5sZWFybk9yaWdpbihldmVudCk7XG5cbiAgICAgIGlmIChyYXcudHlwZSA9PT0gXCJjc3Zib3gtc2V0LWZpbGUtcmVqZWN0ZWRcIiAmJiByYXcuZGF0YS5yZWFzb24gPT09IFwibm90LWEtZmlsZVwiKSB7XG4gICAgICAgIC8vIFJlcGx5IHRvIG91ciBwcm9iZSAoaXQgaGFzIG5vIGZpbGUpLiBJdCBvbmx5IHRlbGxzIHVzIHRoZSBvcmlnaW4sIHNvIGRvIG5vdGhpbmcuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChyYXcudHlwZSA9PT0gXCJjc3Zib3gtbW9kYWwtc2hvd25cIikge1xuICAgICAgICB0aGlzLmNsZWFyRmlsZUFja1RpbWVyKCk7XG4gICAgICAgIHJlZ2lzdGVyT3BlbkltcG9ydGVyKHRoaXMucmVnaXN0cnlFbnRyeSk7XG4gICAgICAgIC8vIFdoYXQgdGhlIGZpbGUgcGF0aCBpbiBvcGVuTW9kYWwoKSBpcyB3YWl0aW5nIGZvci4gZGlzcGxheSBhcyB3ZWxsIGFzXG4gICAgICAgIC8vIHBvaW50ZXItZXZlbnRzOiBhIHNlY29uZCBmaWxlIGRlY2xpbmVkIHdoaWxlIHRoZSBmaXJzdCB3YXMgc3RpbGwgb3BlbmluZyB0aGVcbiAgICAgICAgLy8gbW9kYWwgaGFzIHB1dCB0aGUgaG9sZGVyIGF3YXkgaW4gdGhlIG1lYW50aW1lLlxuICAgICAgICB0aGlzLmlzTW9kYWxTaG93biA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLmhvbGRlcikge1xuICAgICAgICAgIHRoaXMuaG9sZGVyLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICAgIHRoaXMuaG9sZGVyLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnYXV0byc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHJhdy50eXBlID09PSBcImNzdmJveC1zZXQtZmlsZS1yZWplY3RlZFwiKSB7XG4gICAgICAgIHRoaXMuY2xlYXJGaWxlQWNrVGltZXIoKTtcbiAgICAgICAgLy8gVGhlIGltcG9ydGVyIGhhcyB0aGUgZmlsZSBhbmQgd2lsbCBub3QgdGFrZSBpdC4gUHV0IHRoZSBob2xkZXIgYXdheSBvbmx5IGlmIHRoZVxuICAgICAgICAvLyBtb2RhbCB3YXMgbmV2ZXIgY29uZmlybWVkIHVwOiBhIGZpbGUgZGVjbGluZWQgd2hpbGUgaXQgaXMgb3BlbiBsZWF2ZXMgdGhhdCBtb2RhbFxuICAgICAgICAvLyB3aGVyZSBpdCBpcywgYW5kIGl0cyBvd24gJ2NzdmJveC1tb2RhbC1oaWRkZW4nIHdpbGwgcHV0IHRoZSBob2xkZXIgYXdheS5cbiAgICAgICAgaWYgKCF0aGlzLmlzTW9kYWxTaG93biAmJiB0aGlzLmhvbGRlcikge1xuICAgICAgICAgIHRoaXMuaG9sZGVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgdGhpcy5ob2xkZXIuc3R5bGUucG9pbnRlckV2ZW50cyA9ICdhdXRvJztcbiAgICAgICAgICB1bnJlZ2lzdGVyT3BlbkltcG9ydGVyKHRoaXMucmVnaXN0cnlFbnRyeSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS53YXJuKFwiW2NzdmJveF0gaW1wb3J0ZXIgZGVjbGluZWQgdGhlIHN1cHBsaWVkIGZpbGU6IFwiICsgcmF3LmRhdGEucmVhc29uKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBtZXNzYWdlID0gY2xhc3NpZnlTdHJ1Y3R1cmVkTWVzc2FnZShldmVudC5kYXRhLCB0aGlzLnV1aWQhKTtcbiAgICBpZiAoIW1lc3NhZ2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5tZXNzYWdlR2F0ZS5tYXJrVHlwZWQoKTtcbiAgICBjb25zdCBlbmRlZCA9IHRoaXMuaW1wb3J0VHJhY2tlci5vYnNlcnZlKG1lc3NhZ2UpO1xuXG4gICAgaWYgKG1lc3NhZ2UudHlwZSA9PT0gXCJkYXRhLW9uLXN1Ym1pdFwiKSB7XG4gICAgICBpZiAodGhpcy5vblN1Ym1pdCkgdGhpcy5vblN1Ym1pdChtZXNzYWdlLm1ldGFkYXRhKTtcbiAgICAgIGlmICh0aGlzLmlzU3VibWl0dGVkKSB0aGlzLmlzU3VibWl0dGVkKG1lc3NhZ2UubWV0YWRhdGEpO1xuICAgICAgaWYgKHRoaXMuc3VibWl0dGVkKSB0aGlzLnN1Ym1pdHRlZChtZXNzYWdlLm1ldGFkYXRhKTtcbiAgICB9IGVsc2UgaWYgKG1lc3NhZ2UudHlwZSA9PT0gXCJkYXRhLXB1c2gtc3RhdHVzXCIpIHtcbiAgICAgIGlmICh0aGlzLm9uSW1wb3J0KSB0aGlzLm9uSW1wb3J0KG1lc3NhZ2Uuc3VjY2VzcywgbWVzc2FnZS5tZXRhZGF0YSk7XG4gICAgICBpZiAodGhpcy5pc0ltcG9ydGVkKSB0aGlzLmlzSW1wb3J0ZWQobWVzc2FnZS5zdWNjZXNzLCBtZXNzYWdlLm1ldGFkYXRhKTtcbiAgICAgIGlmICh0aGlzLmltcG9ydGVkKSB0aGlzLmltcG9ydGVkKG1lc3NhZ2Uuc3VjY2VzcywgbWVzc2FnZS5tZXRhZGF0YSk7XG4gICAgfSBlbHNlIGlmIChtZXNzYWdlLnR5cGUgPT09IFwiY3N2Ym94LW1vZGFsLWhpZGRlblwiKSB7XG4gICAgICB0aGlzLmhhbmRsZU1vZGFsQ2xvc2VkKCk7XG4gICAgfSBlbHNlIGlmIChtZXNzYWdlLnR5cGUgPT09IFwiY3N2Ym94LXVwbG9hZC1zdWNjZXNzZnVsXCIpIHtcbiAgICAgICAgaWYgKHRoaXMub25JbXBvcnQpIHRoaXMub25JbXBvcnQodHJ1ZSk7XG4gICAgICAgIGlmICh0aGlzLmlzSW1wb3J0ZWQpIHRoaXMuaXNJbXBvcnRlZCh0cnVlKTtcbiAgICAgICAgaWYgKHRoaXMuaW1wb3J0ZWQpIHRoaXMuaW1wb3J0ZWQodHJ1ZSk7XG4gICAgfSBlbHNlIGlmIChtZXNzYWdlLnR5cGUgPT09IFwiY3N2Ym94LXVwbG9hZC1mYWlsZWRcIikge1xuICAgICAgICBpZiAodGhpcy5vbkltcG9ydCkgdGhpcy5vbkltcG9ydChmYWxzZSk7XG4gICAgICAgIGlmICh0aGlzLmlzSW1wb3J0ZWQpIHRoaXMuaXNJbXBvcnRlZChmYWxzZSk7XG4gICAgICAgIGlmICh0aGlzLmltcG9ydGVkKSB0aGlzLmltcG9ydGVkKGZhbHNlKTtcbiAgICB9XG4gICAgdGhpcy5maW5pc2hJbXBvcnQoZW5kZWQpO1xuICB9O1xuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgdGhpcy5tZXNzYWdlTGlzdGVuZXIsIGZhbHNlKTtcbiAgICB0aGlzLnN5bmNCbG9ja2VkKCk7XG4gICAgdGhpcy51bnN1YnNjcmliZU9wZW5JbXBvcnRlcnMgPSBzdWJzY3JpYmVPcGVuSW1wb3J0ZXJzKCgpID0+IHRoaXMuc3luY0Jsb2NrZWQoKSk7XG5cbiAgICBpZih0aGlzLmxhenkpIHtcbiAgICAgIHRoaXMuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kaXNhYmxlZCA9IHRydWU7XG4gICAgICB0aGlzLmluaXRJbXBvcnRlcigpO1xuICAgIH1cbiAgfVxuXG4gIGhhbmRsZU1vZGFsQ2xvc2VkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmltcG9ydFRyYWNrZXIuaXNJbkZsaWdodCgpKSB7XG4gICAgICAvLyBDbG9zZWQgYWZ0ZXIgc3VibWl0dGluZyBhbmQgYmVmb3JlIHRoZSByZXN1bHQgYXJyaXZlZDoga2VlcCB0aGUgaWZyYW1lIGFuZCBpdHMgbGlzdGVuZXJcbiAgICAgIC8vIHNvIHRoZSBsYXRlIHJlc3VsdCBzdGlsbCByZWFjaGVzIG9uSW1wb3J0LiBJdCBpcyByZW1vdmVkIG9uY2UgdGhhdCByZXN1bHQgaGFzIGJlZW5cbiAgICAgIC8vIGRlbGl2ZXJlZCAoc2VlIGZpbmlzaEltcG9ydCksIHNvIHRoZSBuZXh0IG9wZW4gaXMgYSBmcmVzaCBsb2FkLlxuICAgICAgaWYgKHRoaXMuaG9sZGVyKSB7XG4gICAgICAgIHRoaXMuaG9sZGVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHRoaXMuaG9sZGVyLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnYXV0byc7XG4gICAgICB9XG4gICAgICB0aGlzLmlzTW9kYWxTaG93biA9IGZhbHNlO1xuICAgICAgdGhpcy5vcGVuTW9kYWxPbklmcmFtZUxvYWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuY2xlYXJGaWxlQWNrVGltZXIoKTtcbiAgICAgIHVucmVnaXN0ZXJPcGVuSW1wb3J0ZXIodGhpcy5yZWdpc3RyeUVudHJ5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kZXN0cm95SW1wb3J0ZXIoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMub25DbG9zZSkgdGhpcy5vbkNsb3NlKCk7XG4gICAgaWYgKHRoaXMuaXNDbG9zZWQpIHRoaXMuaXNDbG9zZWQoKTtcbiAgICBpZiAodGhpcy5jbG9zZWQpIHRoaXMuY2xvc2VkKCk7XG4gIH1cblxuICAvLyBDYWxsZWQgYWZ0ZXIgdGhlIHJlc3VsdCBvZiBhbiBpbXBvcnQgaGFzIGJlZW4gZGVsaXZlcmVkLiBJZiB0aGUgbW9kYWwgd2FzIGNsb3NlZCBpbiB0aGVcbiAgLy8gbWVhbnRpbWUgdGhlIGlmcmFtZSB3YXMgb25seSBoaWRkZW4sIHNvIHJlbW92ZSBpdCBub3cuXG4gIHByaXZhdGUgZmluaXNoSW1wb3J0KGVuZGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKGVuZGVkICYmICF0aGlzLmlzTW9kYWxTaG93biAmJiB0aGlzLmlmcmFtZSkge1xuICAgICAgdGhpcy5kZXN0cm95SW1wb3J0ZXIoKTtcbiAgICB9XG4gIH1cblxuICAvLyBQdXRzIHRoZSBpbXBvcnRlciBhd2F5OiB0aGUgbmV4dCBvcGVuIGJ1aWxkcyBhIG5ldyBpZnJhbWUgd2l0aCBhIG5ldyB0b2tlbi5cbiAgcHJpdmF0ZSBkZXN0cm95SW1wb3J0ZXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaG9sZGVyKSB7XG4gICAgICB0aGlzLmhvbGRlci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgdGhpcy5ob2xkZXIuc3R5bGUucG9pbnRlckV2ZW50cyA9ICdhdXRvJztcbiAgICAgIHRoaXMuaG9sZGVyLnJlbW92ZSgpO1xuICAgIH1cbiAgICB0aGlzLmhvbGRlciA9IG51bGw7XG4gICAgdGhpcy5pZnJhbWUgPSBudWxsO1xuICAgIHRoaXMuaXNNb2RhbFNob3duID0gZmFsc2U7XG4gICAgdGhpcy5pc0lmcmFtZUxvYWRlZCA9IGZhbHNlO1xuICAgIHRoaXMub3Blbk1vZGFsT25JZnJhbWVMb2FkID0gZmFsc2U7XG4gICAgdGhpcy5tZXNzYWdlR2F0ZS5yZXNldCgpO1xuICAgIHRoaXMuaW1wb3J0VHJhY2tlci5yZXNldCgpO1xuICAgIC8vIEEgbmV3IGlmcmFtZSBpcyBidWlsdCBvbiB0aGUgbmV4dCBvcGVuLCBzbyB0aGUgb3JpZ2luIGlzIGxlYXJuZWQgYWdhaW4uXG4gICAgdGhpcy5jbGVhclByb2JlVGltZXIoKTtcbiAgICB1bnJlZ2lzdGVyT3BlbkltcG9ydGVyKHRoaXMucmVnaXN0cnlFbnRyeSk7XG4gIH1cblxuICBpbml0SW1wb3J0ZXIoKSB7XG4gICAgaWYgKHRoaXMubG9hZFN0YXJ0ZWQpIHRoaXMubG9hZFN0YXJ0ZWQoKTtcblxuICAgIHRoaXMudXVpZCA9IGdlbmVyYXRlVXVpZCgpO1xuICAgIHRoaXMubWVzc2FnZUdhdGUucmVzZXQoKTtcbiAgICB0aGlzLmltcG9ydFRyYWNrZXIucmVzZXQoKTtcblxuICAgIGluc2VydENTUygpO1xuXG4gICAgbGV0IGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpZnJhbWVcIik7XG4gICAgdGhpcy5pZnJhbWUgPSBpZnJhbWU7XG4gICAgaWZyYW1lLnNldEF0dHJpYnV0ZShcInNyY1wiLCB0aGlzLnNhZmVVcmwpO1xuICAgIGlmcmFtZS5zZXRBdHRyaWJ1dGUoXCJhbGxvd1wiLCBcImNsaXBib2FyZC1yZWFkOyBjbGlwYm9hcmQtd3JpdGUgKlwiKTtcbiAgICBpZnJhbWUuZnJhbWVCb3JkZXIgPSBcIjBcIjtcblxuICAgIGxldCBzZWxmID0gdGhpcztcbiAgICBpZnJhbWUub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgc2VsZi5kaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgc2VsZi5pc0lmcmFtZUxvYWRlZCA9IHRydWU7XG4gICAgICAvLyBUaGUgaGFuZHNoYWtlIGdvZXMgZmlyc3Q6IGEgY29uc3VtZXIgdGhhdCBjYWxscyBvcGVuTW9kYWxXaXRoRmlsZSgpIGZyb20gdGhlIHJlYWR5XG4gICAgICAvLyBjYWxsYmFjayBuZWVkcyB0aGUgaW1wb3J0ZXIgdG8gYWxyZWFkeSBoYXZlIGl0cyBjdXN0b21lciwgY29sdW1ucywgb3B0aW9ucyBhbmQgdG9rZW4uXG4gICAgICBpZiAoc2VsZi5pZnJhbWUgJiYgc2VsZi5pZnJhbWUuY29udGVudFdpbmRvdykge1xuICAgICAgICBzZWxmLmlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKGJ1aWxkSW5pdFBheWxvYWQoc2VsZi51c2VyLCBzZWxmLmR5bmFtaWNDb2x1bW5zLCBzZWxmLm9wdGlvbnMsIHNlbGYudXVpZCEpLCBcIipcIik7XG4gICAgICB9XG4gICAgICBpZiAoc2VsZi5vblJlYWR5KSBzZWxmLm9uUmVhZHkoKTtcbiAgICAgIGlmIChzZWxmLmlzUmVhZHkpIHNlbGYuaXNSZWFkeSgpO1xuICAgICAgaWYgKHNlbGYuaW1wb3J0ZXJSZWFkeSkgc2VsZi5pbXBvcnRlclJlYWR5KCk7XG5cbiAgICAgIGlmKHNlbGYub3Blbk1vZGFsT25JZnJhbWVMb2FkKSB7XG4gICAgICAgIHNlbGYub3Blbk1vZGFsKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5ob2xkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLmhvbGRlci5jbGFzc0xpc3QuYWRkKCdjc3Zib3gtaG9sZGVyJyk7XG4gICAgdGhpcy5ob2xkZXIuc2V0QXR0cmlidXRlKCdpZCcsIGBjc3Zib3gtZW1iZWQtJHt0aGlzLnV1aWR9YCk7XG4gICAgdGhpcy5ob2xkZXIuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcblxuICAgIGRvY3VtZW50LmJvZHkuaW5zZXJ0QWRqYWNlbnRFbGVtZW50KFxuICAgICAgJ2JlZm9yZWVuZCcsIHRoaXMuaG9sZGVyXG4gICAgKTtcbiAgICAvLyBUaGUgaG9sZGVyIGRpZCBub3QgZXhpc3QgeWV0IGlmIG9wZW5Nb2RhbCgpIGFza2VkIGZvciB0aGUgaW1wb3J0ZXIgYmVmb3JlIGl0IHdhcyBidWlsdC5cbiAgICByZXN0YWNrT3BlbkltcG9ydGVycyhvcGVuSW1wb3J0ZXJzKCkpO1xuICB9XG5cbiAgb3Blbk1vZGFsKCk6IHZvaWQge1xuICAgIC8vIENvdW50cyBhcyBvcGVuIGZyb20gdGhlIG1vbWVudCBpdCBpcyByZXF1ZXN0ZWQsIHNvIHRoZSBvdGhlciBidXR0b25zIGFyZSBkaXNhYmxlZCB3aGlsZVxuICAgIC8vIHRoaXMgaW1wb3J0ZXIgaXMgc3RpbGwgbG9hZGluZywgYW5kIHNvIGl0IGlzIHN0YWNrZWQgYWJvdmUgYW55IGltcG9ydGVyIG9wZW5lZCBlYXJsaWVyLlxuICAgIHJlZ2lzdGVyT3BlbkltcG9ydGVyKHRoaXMucmVnaXN0cnlFbnRyeSk7XG4gICAgaWYoIXRoaXMuaWZyYW1lKSB7XG4gICAgICAgIHRoaXMub3Blbk1vZGFsT25JZnJhbWVMb2FkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5pbml0SW1wb3J0ZXIoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZighdGhpcy5pc01vZGFsU2hvd24pIHtcbiAgICAgIGlmKHRoaXMuaXNJZnJhbWVMb2FkZWQpIHtcbiAgICAgICAgaWYodGhpcy5wZW5kaW5nRmlsZSkge1xuICAgICAgICAgIC8vIFRoZSBpbXBvcnRlciBvcGVucyBpdHMgb3duIG1vZGFsIG9uY2UgaXQgaGFzIHRoZSBmaWxlLCBzbyB0aGF0IGl0IGNhbiBpbmplY3Qgb25cbiAgICAgICAgICAvLyAnc2hvd24uYnMubW9kYWwnLiBTZW5kaW5nICdvcGVuTW9kYWwnIGFzIHdlbGwgd291bGQgcmFjZSB0aGF0LlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gSXQgY2FuIGFsc28gZGVjbGluZTogd3Jvbmcgc3RlcCwgYW4gaW1wb3J0IGZpbGUgVVJMIGNvbmZpZ3VyZWQgb24gdGhlIHNoZWV0LCBvclxuICAgICAgICAgIC8vIGFuIGltcG9ydGVyIHRvbyBvbGQgdG8ga25vdyB0aGUgbWVzc2FnZSBhdCBhbGwuIFNvIHRoZSBob2xkZXIgZ29lcyB1cFxuICAgICAgICAgIC8vIGNsaWNrLXRocm91Z2ggYW5kIHN0YXlzIHRoYXQgd2F5IHVudGlsICdjc3Zib3gtbW9kYWwtc2hvd24nIGNvbmZpcm1zIHRoZSBtb2RhbFxuICAgICAgICAgIC8vIGlzIHJlYWxseSB1cC4gSXQgY292ZXJzIHRoZSB2aWV3cG9ydCBhdCB6LWluZGV4IDIxNDc0ODM2NDcgYW5kIHRoZSBpbXBvcnRlclxuICAgICAgICAgIC8vIHJlbmRlcnMgdHJhbnNwYXJlbnQgd2l0aCBpdHMgbW9kYWwgY2xvc2VkLCBzbyBhcm1pbmcgaXQgb24gYW4gdW5hbnN3ZXJlZCBtZXNzYWdlXG4gICAgICAgICAgLy8gbGVhdmVzIGFuIGludmlzaWJsZSBzaGVldCBvdmVyIHRoZSBob3N0IHBhZ2UgZWF0aW5nIGV2ZXJ5IGNsaWNrLlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gZGlzcGxheTpibG9jayByZWdhcmRsZXNzLCBzbyB0aGUgaWZyYW1lIGxheXMgb3V0IGFuZCBhbmltYXRlcyBub3JtYWxseTsgb25seVxuICAgICAgICAgIC8vIHBvaW50ZXItZXZlbnRzIGlzIGhlbGQgYmFjay4gaXNNb2RhbFNob3duIGxpa2V3aXNlIHdhaXRzIGZvciB0aGUgY29uZmlybWF0aW9uLFxuICAgICAgICAgIC8vIG9yIGEgZGVjbGluZWQgZmlsZSB3b3VsZCBsYXRjaCB0aGUgaW1wb3J0ZXIgc2h1dCBmb3IgZ29vZC5cbiAgICAgICAgICBpZih0aGlzLmhvbGRlcikge1xuICAgICAgICAgICAgdGhpcy5ob2xkZXIuc3R5bGUucG9pbnRlckV2ZW50cyA9ICdub25lJztcbiAgICAgICAgICAgIHRoaXMuaG9sZGVyLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmZpbGVTZW5kZXIuc2VuZCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuaXNNb2RhbFNob3duID0gdHJ1ZTtcbiAgICAgICAgICBpZih0aGlzLmhvbGRlcikge1xuICAgICAgICAgICAgLy8gRXhwbGljaXQ6IGEgcHJldmlvdXNseSBkZWNsaW5lZCBmaWxlIGxlYXZlcyB0aGUgaG9sZGVyIGNsaWNrLXRocm91Z2guXG4gICAgICAgICAgICB0aGlzLmhvbGRlci5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ2F1dG8nO1xuICAgICAgICAgICAgdGhpcy5ob2xkZXIuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKHRoaXMuaWZyYW1lICYmIHRoaXMuaWZyYW1lLmNvbnRlbnRXaW5kb3cpIHtcbiAgICAgICAgICAgIHRoaXMuaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UoJ29wZW5Nb2RhbCcsICcqJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMub3Blbk1vZGFsT25JZnJhbWVMb2FkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogT3BlbiB0aGUgaW1wb3J0ZXIgb24gYSBGaWxlIHRoZSBob3N0IHBhZ2UgYWxyZWFkeSBoYXMsIGluc3RlYWQgb2YgdGhlIGZpbGUgcGlja2VyLlxuICAgKlxuICAgKiBSZWFjaGFibGUgdGhyb3VnaCBhIHRlbXBsYXRlIHJlZmVyZW5jZSAoYCNpbXBvcnRlcmAgdGhlbiBgaW1wb3J0ZXIub3Blbk1vZGFsV2l0aEZpbGUoZmlsZSlgKVxuICAgKiBvciBgQFZpZXdDaGlsZChDU1ZCb3hCdXR0b25Db21wb25lbnQpYC5cbiAgICpcbiAgICogVGhlIEZpbGUgY3Jvc3NlcyB0byB0aGUgaWZyYW1lIGJ5IHN0cnVjdHVyZWQgY2xvbmUsIHNvIHRoZSBpbXBvcnRlciByZWNlaXZlcyB0aGUgcmVhbFxuICAgKiBvYmplY3QgYW5kIGFwcGxpZXMgaXRzIG93biBleHRlbnNpb24sIHdvcmtzaGVldCBhbmQgc2l6ZSBydWxlcyB0byBpdCAtLSB0aGlzIGRvZXMgbm90XG4gICAqIGJ5cGFzcyBhbnkgb2YgdGhlbS4gUGFzcyBhIEZpbGU7IGEgQmxvYiBoYXMgbm8gbmFtZSBmb3IgdGhlIGltcG9ydGVyIHRvIHJlYWQgYW5cbiAgICogZXh0ZW5zaW9uIGZyb20uXG4gICAqL1xuICBvcGVuTW9kYWxXaXRoRmlsZShmaWxlOiBGaWxlKTogdm9pZCB7XG4gICAgaWYodHlwZW9mIEZpbGUgPT09ICd1bmRlZmluZWQnIHx8ICEoZmlsZSBpbnN0YW5jZW9mIEZpbGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5wZW5kaW5nRmlsZSA9IGZpbGU7XG5cbiAgICAvLyBBbHJlYWR5IG9wZW46IGhhbmQgaXQgb3ZlciBub3cgcmF0aGVyIHRoYW4gaG9sZGluZyBpdCBmb3IgdGhlIG5leHQgb3Blbi4gVGhlIGltcG9ydGVyXG4gICAgLy8gdGFrZXMgaXQgb25seSB3aGlsZSBpdCBpcyBzdGlsbCBvbiB0aGUgdXBsb2FkIHN0ZXAsIGFuZCBpZ25vcmVzIGl0IG9uY2UgdGhlIHVzZXIgaGFzIGFcbiAgICAvLyBkYXRhc2V0IGFuZCBhIG1hcHBpbmcgaW4gcHJvZ3Jlc3MuXG4gICAgaWYodGhpcy5pc01vZGFsU2hvd24gJiYgdGhpcy5pZnJhbWUgJiYgdGhpcy5pc0lmcmFtZUxvYWRlZCkge1xuICAgICAgdGhpcy5maWxlU2VuZGVyLnNlbmQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLm9wZW5Nb2RhbCgpO1xuICB9XG5cbiAgY2xlYXJQcm9iZVRpbWVyKCk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJGaWxlQWNrVGltZXIoKTtcbiAgICB0aGlzLmZpbGVTZW5kZXIucmVzZXQoKTtcbiAgfVxuXG4gIHN0YXJ0RmlsZUFja1RpbWVyKCk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJGaWxlQWNrVGltZXIoKTtcbiAgICB0aGlzLmZpbGVBY2tUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5maWxlQWNrVGltZXIgPSBudWxsO1xuICAgICAgdGhpcy5naXZlVXBPbkZpbGUoKTtcbiAgICB9LCBGSUxFX0FDS19USU1FT1VUX01TKTtcbiAgfVxuXG4gIGNsZWFyRmlsZUFja1RpbWVyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmZpbGVBY2tUaW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuZmlsZUFja1RpbWVyKTtcbiAgICAgIHRoaXMuZmlsZUFja1RpbWVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvLyBUaGUgaW1wb3J0ZXIgbmV2ZXIgY29uZmlybWVkIHRoZSBmaWxlIGl0IHdhcyBzZW50IChhbiBvcmlnaW4gd2UgZG8gbm90IHRydXN0LCBvciBhbiBpbXBvcnRlciB0b29cbiAgLy8gb2xkIHRvIGtub3cgdGhlIG1lc3NhZ2UpLiBXaXRob3V0IHRoaXMgdGhlIGhvbGRlciB3b3VsZCBzdGF5IHVwLCBpbnZpc2libGUgYW5kIGNsaWNrLXRocm91Z2gsXG4gIC8vIGFuZCB0aGUgb3RoZXIgaW5zdGFuY2VzJyBidXR0b25zIHdvdWxkIHN0YXkgZGlzYWJsZWQgZm9yIGdvb2QuXG4gIGdpdmVVcE9uRmlsZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc01vZGFsU2hvd24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaG9sZGVyID0gdGhpcy5ob2xkZXI7XG4gICAgaWYgKGhvbGRlcikge1xuICAgICAgaG9sZGVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICBob2xkZXIuc3R5bGUucG9pbnRlckV2ZW50cyA9ICdhdXRvJztcbiAgICB9XG4gICAgdW5yZWdpc3Rlck9wZW5JbXBvcnRlcih0aGlzLnJlZ2lzdHJ5RW50cnkpO1xuICAgIGNvbnNvbGUud2FybihcIltjc3Zib3hdIHRoZSBpbXBvcnRlciBkaWQgbm90IHJlc3BvbmQgdG8gdGhlIHN1cHBsaWVkIGZpbGVcIik7XG4gIH1cblxuICBwcml2YXRlIHN5bmNCbG9ja2VkKCk6IHZvaWQge1xuICAgIGNvbnN0IGJsb2NrZWQgPSBpc0Jsb2NrZWRCeU9wZW5JbXBvcnRlcih0aGlzLnJlZ2lzdHJ5RW50cnkpO1xuICAgIGlmIChibG9ja2VkICE9PSB0aGlzLmJsb2NrZWRCeU90aGVyKSB7XG4gICAgICAvLyBUaGUgcmVnaXN0cnkgY2FuIGNhbGwgYmFjayBmcm9tIG91dHNpZGUgQW5ndWxhcidzIHpvbmUgKGFub3RoZXIgaW5zdGFuY2UsIGFub3RoZXIgYXBwKS5cbiAgICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgICB0aGlzLmJsb2NrZWRCeU90aGVyID0gYmxvY2tlZDtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgdGhpcy5tZXNzYWdlTGlzdGVuZXIpO1xuICAgIC8vIFRha2VzIHRoZSBob2xkZXIgb3V0IG9mIGRvY3VtZW50LmJvZHk6IGxlZnQgdGhlcmUsIGl0IHdvdWxkIGtlZXAgY292ZXJpbmcgdGhlIHBhZ2Ugd2l0aFxuICAgIC8vIGFuIGludmlzaWJsZSBmdWxsLXNjcmVlbiBsYXllciB0aGF0IG5vdGhpbmcgaXMgbGVmdCB0byBoaWRlLlxuICAgIHRoaXMuZGVzdHJveUltcG9ydGVyKCk7XG4gICAgaWYgKHRoaXMudW5zdWJzY3JpYmVPcGVuSW1wb3J0ZXJzKSB7XG4gICAgICB0aGlzLnVuc3Vic2NyaWJlT3BlbkltcG9ydGVycygpO1xuICAgICAgdGhpcy51bnN1YnNjcmliZU9wZW5JbXBvcnRlcnMgPSBudWxsO1xuICAgIH1cbiAgfVxufVxuIl19