popover.js 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import { Component, Directive, Input, Output, EventEmitter, ChangeDetectionStrategy, Inject, Injector, Renderer2, ElementRef, TemplateRef, ViewContainerRef, ComponentFactoryResolver, NgZone, ViewEncapsulation, ChangeDetectorRef, ApplicationRef } from '@angular/core';
  6. import { DOCUMENT } from '@angular/common';
  7. import { listenToTriggers } from '../util/triggers';
  8. import { ngbAutoClose } from '../util/autoclose';
  9. import { positionElements } from '../util/positioning';
  10. import { PopupService } from '../util/popup';
  11. import { NgbPopoverConfig } from './popover-config';
  12. /** @type {?} */
  13. var nextId = 0;
  14. var NgbPopoverWindow = /** @class */ (function () {
  15. function NgbPopoverWindow() {
  16. }
  17. /**
  18. * @return {?}
  19. */
  20. NgbPopoverWindow.prototype.isTitleTemplate = /**
  21. * @return {?}
  22. */
  23. function () { return this.title instanceof TemplateRef; };
  24. NgbPopoverWindow.decorators = [
  25. { type: Component, args: [{
  26. selector: 'ngb-popover-window',
  27. changeDetection: ChangeDetectionStrategy.OnPush,
  28. encapsulation: ViewEncapsulation.None,
  29. host: { '[class]': '"popover" + (popoverClass ? " " + popoverClass : "")', 'role': 'tooltip', '[id]': 'id' },
  30. template: "\n <div class=\"arrow\"></div>\n <h3 class=\"popover-header\" *ngIf=\"title != null\">\n <ng-template #simpleTitle>{{title}}</ng-template>\n <ng-template [ngTemplateOutlet]=\"isTitleTemplate() ? title : simpleTitle\" [ngTemplateOutletContext]=\"context\"></ng-template>\n </h3>\n <div class=\"popover-body\"><ng-content></ng-content></div>",
  31. styles: ["ngb-popover-window.bs-popover-bottom>.arrow,ngb-popover-window.bs-popover-top>.arrow{left:50%;margin-left:-.5rem}ngb-popover-window.bs-popover-bottom-left>.arrow,ngb-popover-window.bs-popover-top-left>.arrow{left:2em}ngb-popover-window.bs-popover-bottom-right>.arrow,ngb-popover-window.bs-popover-top-right>.arrow{left:auto;right:2em}ngb-popover-window.bs-popover-left>.arrow,ngb-popover-window.bs-popover-right>.arrow{top:50%;margin-top:-.5rem}ngb-popover-window.bs-popover-left-top>.arrow,ngb-popover-window.bs-popover-right-top>.arrow{top:.7em}ngb-popover-window.bs-popover-left-bottom>.arrow,ngb-popover-window.bs-popover-right-bottom>.arrow{top:auto;bottom:.7em}"]
  32. }] }
  33. ];
  34. NgbPopoverWindow.propDecorators = {
  35. title: [{ type: Input }],
  36. id: [{ type: Input }],
  37. popoverClass: [{ type: Input }],
  38. context: [{ type: Input }]
  39. };
  40. return NgbPopoverWindow;
  41. }());
  42. export { NgbPopoverWindow };
  43. if (false) {
  44. /** @type {?} */
  45. NgbPopoverWindow.prototype.title;
  46. /** @type {?} */
  47. NgbPopoverWindow.prototype.id;
  48. /** @type {?} */
  49. NgbPopoverWindow.prototype.popoverClass;
  50. /** @type {?} */
  51. NgbPopoverWindow.prototype.context;
  52. }
  53. /**
  54. * A lightweight and extensible directive for fancy popover creation.
  55. */
  56. var NgbPopover = /** @class */ (function () {
  57. function NgbPopover(_elementRef, _renderer, injector, componentFactoryResolver, viewContainerRef, config, _ngZone, _document, _changeDetector, applicationRef) {
  58. var _this = this;
  59. this._elementRef = _elementRef;
  60. this._renderer = _renderer;
  61. this._ngZone = _ngZone;
  62. this._document = _document;
  63. this._changeDetector = _changeDetector;
  64. /**
  65. * An event emitted when the popover is shown. Contains no payload.
  66. */
  67. this.shown = new EventEmitter();
  68. /**
  69. * An event emitted when the popover is hidden. Contains no payload.
  70. */
  71. this.hidden = new EventEmitter();
  72. this._ngbPopoverWindowId = "ngb-popover-" + nextId++;
  73. this.autoClose = config.autoClose;
  74. this.placement = config.placement;
  75. this.triggers = config.triggers;
  76. this.container = config.container;
  77. this.disablePopover = config.disablePopover;
  78. this.popoverClass = config.popoverClass;
  79. this.openDelay = config.openDelay;
  80. this.closeDelay = config.closeDelay;
  81. this._popupService = new PopupService(NgbPopoverWindow, injector, viewContainerRef, _renderer, componentFactoryResolver, applicationRef);
  82. this._zoneSubscription = _ngZone.onStable.subscribe((/**
  83. * @return {?}
  84. */
  85. function () {
  86. if (_this._windowRef) {
  87. positionElements(_this._elementRef.nativeElement, _this._windowRef.location.nativeElement, _this.placement, _this.container === 'body', 'bs-popover');
  88. }
  89. }));
  90. }
  91. /**
  92. * @private
  93. * @return {?}
  94. */
  95. NgbPopover.prototype._isDisabled = /**
  96. * @private
  97. * @return {?}
  98. */
  99. function () {
  100. if (this.disablePopover) {
  101. return true;
  102. }
  103. if (!this.ngbPopover && !this.popoverTitle) {
  104. return true;
  105. }
  106. return false;
  107. };
  108. /**
  109. * Opens the popover.
  110. *
  111. * This is considered to be a "manual" triggering.
  112. * The `context` is an optional value to be injected into the popover template when it is created.
  113. */
  114. /**
  115. * Opens the popover.
  116. *
  117. * This is considered to be a "manual" triggering.
  118. * The `context` is an optional value to be injected into the popover template when it is created.
  119. * @param {?=} context
  120. * @return {?}
  121. */
  122. NgbPopover.prototype.open = /**
  123. * Opens the popover.
  124. *
  125. * This is considered to be a "manual" triggering.
  126. * The `context` is an optional value to be injected into the popover template when it is created.
  127. * @param {?=} context
  128. * @return {?}
  129. */
  130. function (context) {
  131. var _this = this;
  132. if (!this._windowRef && !this._isDisabled()) {
  133. this._windowRef = this._popupService.open(this.ngbPopover, context);
  134. this._windowRef.instance.title = this.popoverTitle;
  135. this._windowRef.instance.context = context;
  136. this._windowRef.instance.popoverClass = this.popoverClass;
  137. this._windowRef.instance.id = this._ngbPopoverWindowId;
  138. this._renderer.setAttribute(this._elementRef.nativeElement, 'aria-describedby', this._ngbPopoverWindowId);
  139. if (this.container === 'body') {
  140. this._document.querySelector(this.container).appendChild(this._windowRef.location.nativeElement);
  141. }
  142. // We need to detect changes, because we don't know where .open() might be called from.
  143. // Ex. opening popover from one of lifecycle hooks that run after the CD
  144. // (say from ngAfterViewInit) will result in 'ExpressionHasChanged' exception
  145. this._windowRef.changeDetectorRef.detectChanges();
  146. // We need to mark for check, because popover won't work inside the OnPush component.
  147. // Ex. when we use expression like `{{ popover.isOpen() : 'opened' : 'closed' }}`
  148. // inside the template of an OnPush component and we change the popover from
  149. // open -> closed, the expression in question won't be updated unless we explicitly
  150. // mark the parent component to be checked.
  151. this._windowRef.changeDetectorRef.markForCheck();
  152. ngbAutoClose(this._ngZone, this._document, this.autoClose, (/**
  153. * @return {?}
  154. */
  155. function () { return _this.close(); }), this.hidden, [this._windowRef.location.nativeElement]);
  156. this.shown.emit();
  157. }
  158. };
  159. /**
  160. * Closes the popover.
  161. *
  162. * This is considered to be a "manual" triggering of the popover.
  163. */
  164. /**
  165. * Closes the popover.
  166. *
  167. * This is considered to be a "manual" triggering of the popover.
  168. * @return {?}
  169. */
  170. NgbPopover.prototype.close = /**
  171. * Closes the popover.
  172. *
  173. * This is considered to be a "manual" triggering of the popover.
  174. * @return {?}
  175. */
  176. function () {
  177. if (this._windowRef) {
  178. this._renderer.removeAttribute(this._elementRef.nativeElement, 'aria-describedby');
  179. this._popupService.close();
  180. this._windowRef = null;
  181. this.hidden.emit();
  182. this._changeDetector.markForCheck();
  183. }
  184. };
  185. /**
  186. * Toggles the popover.
  187. *
  188. * This is considered to be a "manual" triggering of the popover.
  189. */
  190. /**
  191. * Toggles the popover.
  192. *
  193. * This is considered to be a "manual" triggering of the popover.
  194. * @return {?}
  195. */
  196. NgbPopover.prototype.toggle = /**
  197. * Toggles the popover.
  198. *
  199. * This is considered to be a "manual" triggering of the popover.
  200. * @return {?}
  201. */
  202. function () {
  203. if (this._windowRef) {
  204. this.close();
  205. }
  206. else {
  207. this.open();
  208. }
  209. };
  210. /**
  211. * Returns `true`, if the popover is currently shown.
  212. */
  213. /**
  214. * Returns `true`, if the popover is currently shown.
  215. * @return {?}
  216. */
  217. NgbPopover.prototype.isOpen = /**
  218. * Returns `true`, if the popover is currently shown.
  219. * @return {?}
  220. */
  221. function () { return this._windowRef != null; };
  222. /**
  223. * @return {?}
  224. */
  225. NgbPopover.prototype.ngOnInit = /**
  226. * @return {?}
  227. */
  228. function () {
  229. this._unregisterListenersFn = listenToTriggers(this._renderer, this._elementRef.nativeElement, this.triggers, this.isOpen.bind(this), this.open.bind(this), this.close.bind(this), +this.openDelay, +this.closeDelay);
  230. };
  231. /**
  232. * @param {?} __0
  233. * @return {?}
  234. */
  235. NgbPopover.prototype.ngOnChanges = /**
  236. * @param {?} __0
  237. * @return {?}
  238. */
  239. function (_a) {
  240. var ngbPopover = _a.ngbPopover, popoverTitle = _a.popoverTitle, disablePopover = _a.disablePopover, popoverClass = _a.popoverClass;
  241. if (popoverClass && this.isOpen()) {
  242. this._windowRef.instance.popoverClass = popoverClass.currentValue;
  243. }
  244. // close popover if title and content become empty, or disablePopover set to true
  245. if ((ngbPopover || popoverTitle || disablePopover) && this._isDisabled()) {
  246. this.close();
  247. }
  248. };
  249. /**
  250. * @return {?}
  251. */
  252. NgbPopover.prototype.ngOnDestroy = /**
  253. * @return {?}
  254. */
  255. function () {
  256. this.close();
  257. // This check is needed as it might happen that ngOnDestroy is called before ngOnInit
  258. // under certain conditions, see: https://github.com/ng-bootstrap/ng-bootstrap/issues/2199
  259. if (this._unregisterListenersFn) {
  260. this._unregisterListenersFn();
  261. }
  262. this._zoneSubscription.unsubscribe();
  263. };
  264. NgbPopover.decorators = [
  265. { type: Directive, args: [{ selector: '[ngbPopover]', exportAs: 'ngbPopover' },] }
  266. ];
  267. /** @nocollapse */
  268. NgbPopover.ctorParameters = function () { return [
  269. { type: ElementRef },
  270. { type: Renderer2 },
  271. { type: Injector },
  272. { type: ComponentFactoryResolver },
  273. { type: ViewContainerRef },
  274. { type: NgbPopoverConfig },
  275. { type: NgZone },
  276. { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
  277. { type: ChangeDetectorRef },
  278. { type: ApplicationRef }
  279. ]; };
  280. NgbPopover.propDecorators = {
  281. autoClose: [{ type: Input }],
  282. ngbPopover: [{ type: Input }],
  283. popoverTitle: [{ type: Input }],
  284. placement: [{ type: Input }],
  285. triggers: [{ type: Input }],
  286. container: [{ type: Input }],
  287. disablePopover: [{ type: Input }],
  288. popoverClass: [{ type: Input }],
  289. openDelay: [{ type: Input }],
  290. closeDelay: [{ type: Input }],
  291. shown: [{ type: Output }],
  292. hidden: [{ type: Output }]
  293. };
  294. return NgbPopover;
  295. }());
  296. export { NgbPopover };
  297. if (false) {
  298. /**
  299. * Indicates whether the popover should be closed on `Escape` key and inside/outside clicks:
  300. *
  301. * * `true` - closes on both outside and inside clicks as well as `Escape` presses
  302. * * `false` - disables the autoClose feature (NB: triggers still apply)
  303. * * `"inside"` - closes on inside clicks as well as Escape presses
  304. * * `"outside"` - closes on outside clicks (sometimes also achievable through triggers)
  305. * as well as `Escape` presses
  306. *
  307. * \@since 3.0.0
  308. * @type {?}
  309. */
  310. NgbPopover.prototype.autoClose;
  311. /**
  312. * The string content or a `TemplateRef` for the content to be displayed in the popover.
  313. *
  314. * If the title and the content are empty, the popover won't open.
  315. * @type {?}
  316. */
  317. NgbPopover.prototype.ngbPopover;
  318. /**
  319. * The title of the popover.
  320. *
  321. * If the title and the content are empty, the popover won't open.
  322. * @type {?}
  323. */
  324. NgbPopover.prototype.popoverTitle;
  325. /**
  326. * The preferred placement of the popover.
  327. *
  328. * Possible values are `"top"`, `"top-left"`, `"top-right"`, `"bottom"`, `"bottom-left"`,
  329. * `"bottom-right"`, `"left"`, `"left-top"`, `"left-bottom"`, `"right"`, `"right-top"`,
  330. * `"right-bottom"`
  331. *
  332. * Accepts an array of strings or a string with space separated possible values.
  333. *
  334. * The default order of preference is `"auto"` (same as the sequence above).
  335. *
  336. * Please see the [positioning overview](#/positioning) for more details.
  337. * @type {?}
  338. */
  339. NgbPopover.prototype.placement;
  340. /**
  341. * Specifies events that should trigger the tooltip.
  342. *
  343. * Supports a space separated list of event names.
  344. * For more details see the [triggers demo](#/components/popover/examples#triggers).
  345. * @type {?}
  346. */
  347. NgbPopover.prototype.triggers;
  348. /**
  349. * A selector specifying the element the popover should be appended to.
  350. *
  351. * Currently only supports `body`.
  352. * @type {?}
  353. */
  354. NgbPopover.prototype.container;
  355. /**
  356. * If `true`, popover is disabled and won't be displayed.
  357. *
  358. * \@since 1.1.0
  359. * @type {?}
  360. */
  361. NgbPopover.prototype.disablePopover;
  362. /**
  363. * An optional class applied to the popover window element.
  364. *
  365. * \@since 2.2.0
  366. * @type {?}
  367. */
  368. NgbPopover.prototype.popoverClass;
  369. /**
  370. * The opening delay in ms. Works only for "non-manual" opening triggers defined by the `triggers` input.
  371. *
  372. * \@since 4.1.0
  373. * @type {?}
  374. */
  375. NgbPopover.prototype.openDelay;
  376. /**
  377. * The closing delay in ms. Works only for "non-manual" opening triggers defined by the `triggers` input.
  378. *
  379. * \@since 4.1.0
  380. * @type {?}
  381. */
  382. NgbPopover.prototype.closeDelay;
  383. /**
  384. * An event emitted when the popover is shown. Contains no payload.
  385. * @type {?}
  386. */
  387. NgbPopover.prototype.shown;
  388. /**
  389. * An event emitted when the popover is hidden. Contains no payload.
  390. * @type {?}
  391. */
  392. NgbPopover.prototype.hidden;
  393. /**
  394. * @type {?}
  395. * @private
  396. */
  397. NgbPopover.prototype._ngbPopoverWindowId;
  398. /**
  399. * @type {?}
  400. * @private
  401. */
  402. NgbPopover.prototype._popupService;
  403. /**
  404. * @type {?}
  405. * @private
  406. */
  407. NgbPopover.prototype._windowRef;
  408. /**
  409. * @type {?}
  410. * @private
  411. */
  412. NgbPopover.prototype._unregisterListenersFn;
  413. /**
  414. * @type {?}
  415. * @private
  416. */
  417. NgbPopover.prototype._zoneSubscription;
  418. /**
  419. * @type {?}
  420. * @private
  421. */
  422. NgbPopover.prototype._elementRef;
  423. /**
  424. * @type {?}
  425. * @private
  426. */
  427. NgbPopover.prototype._renderer;
  428. /**
  429. * @type {?}
  430. * @private
  431. */
  432. NgbPopover.prototype._ngZone;
  433. /**
  434. * @type {?}
  435. * @private
  436. */
  437. NgbPopover.prototype._document;
  438. /**
  439. * @type {?}
  440. * @private
  441. */
  442. NgbPopover.prototype._changeDetector;
  443. }
  444. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9wb3Zlci5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwLyIsInNvdXJjZXMiOlsicG9wb3Zlci9wb3BvdmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFNBQVMsRUFDVCxLQUFLLEVBQ0wsTUFBTSxFQUNOLFlBQVksRUFDWix1QkFBdUIsRUFJdkIsTUFBTSxFQUNOLFFBQVEsRUFDUixTQUFTLEVBRVQsVUFBVSxFQUNWLFdBQVcsRUFDWCxnQkFBZ0IsRUFDaEIsd0JBQXdCLEVBQ3hCLE1BQU0sRUFFTixpQkFBaUIsRUFDakIsaUJBQWlCLEVBQ2pCLGNBQWMsRUFDZixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFekMsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQy9DLE9BQU8sRUFBQyxnQkFBZ0IsRUFBaUIsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRSxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGtCQUFrQixDQUFDOztJQUU5QyxNQUFNLEdBQUcsQ0FBQztBQUVkO0lBQUE7SUFxQkEsQ0FBQzs7OztJQURDLDBDQUFlOzs7SUFBZixjQUFvQixPQUFPLElBQUksQ0FBQyxLQUFLLFlBQVksV0FBVyxDQUFDLENBQUMsQ0FBQzs7Z0JBcEJoRSxTQUFTLFNBQUM7b0JBQ1QsUUFBUSxFQUFFLG9CQUFvQjtvQkFDOUIsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07b0JBQy9DLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJO29CQUNyQyxJQUFJLEVBQUUsRUFBQyxTQUFTLEVBQUUsc0RBQXNELEVBQUUsTUFBTSxFQUFFLFNB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QUFLOzRCQU9MLEtBQUs7NkJBT0wsS0FBSzt3QkFLTCxNQUFNO3lCQUtOLE1BQU07O0lBMklULGlCQUFDO0NBQUEsQUExT0QsSUEwT0M7U0F6T1ksVUFBVTs7Ozs7Ozs7Ozs7Ozs7SUFZckIsK0JBQW1EOzs7Ozs7O0lBT25ELGdDQUErQzs7Ozs7OztJQU8vQyxrQ0FBaUQ7Ozs7Ozs7Ozs7Ozs7OztJQWVqRCwrQkFBbUM7Ozs7Ozs7O0lBUW5DLDhCQUEwQjs7Ozs7OztJQU8xQiwrQkFBMkI7Ozs7Ozs7SUFPM0Isb0NBQWlDOzs7Ozs7O0lBT2pDLGtDQUE4Qjs7Ozs7OztJQU85QiwrQkFBMkI7Ozs7Ozs7SUFPM0IsZ0NBQTRCOzs7OztJQUs1QiwyQkFBMkM7Ozs7O0lBSzNDLDRCQUE0Qzs7Ozs7SUFFNUMseUNBQXdEOzs7OztJQUN4RCxtQ0FBc0Q7Ozs7O0lBQ3RELGdDQUFtRDs7Ozs7SUFDbkQsNENBQStCOzs7OztJQUMvQix1Q0FBK0I7Ozs7O0lBWTNCLGlDQUE0Qzs7Ozs7SUFBRSwrQkFBNEI7Ozs7O0lBRTFFLDZCQUF1Qjs7Ozs7SUFBRSwrQkFBd0M7Ozs7O0lBQUUscUNBQTBDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBEaXJlY3RpdmUsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIE9uSW5pdCxcbiAgT25EZXN0cm95LFxuICBPbkNoYW5nZXMsXG4gIEluamVjdCxcbiAgSW5qZWN0b3IsXG4gIFJlbmRlcmVyMixcbiAgQ29tcG9uZW50UmVmLFxuICBFbGVtZW50UmVmLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NvbnRhaW5lclJlZixcbiAgQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLFxuICBOZ1pvbmUsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQXBwbGljYXRpb25SZWZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0RPQ1VNRU5UfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG5pbXBvcnQge2xpc3RlblRvVHJpZ2dlcnN9IGZyb20gJy4uL3V0aWwvdHJpZ2dlcnMnO1xuaW1wb3J0IHtuZ2JBdXRvQ2xvc2V9IGZyb20gJy4uL3V0aWwvYXV0b2Nsb3NlJztcbmltcG9ydCB7cG9zaXRpb25FbGVtZW50cywgUGxhY2VtZW50QXJyYXl9IGZyb20gJy4uL3V0aWwvcG9zaXRpb25pbmcnO1xuaW1wb3J0IHtQb3B1cFNlcnZpY2V9IGZyb20gJy4uL3V0aWwvcG9wdXAnO1xuXG5pbXBvcnQge05nYlBvcG92ZXJDb25maWd9IGZyb20gJy4vcG9wb3Zlci1jb25maWcnO1xuXG5sZXQgbmV4dElkID0gMDtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmdiLXBvcG92ZXItd2luZG93JyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGhvc3Q6IHsnW2NsYXNzXSc6ICdcInBvcG92ZXJcIiArIChwb3BvdmVyQ2xhc3MgPyBcIiBcIiArIHBvcG92ZXJDbGFzcyA6IFwiXCIpJywgJ3JvbGUnOiAndG9vbHRpcCcsICdbaWRdJzogJ2lkJ30sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImFycm93XCI+PC9kaXY+XG4gICAgPGgzIGNsYXNzPVwicG9wb3Zlci1oZWFkZXJcIiAqbmdJZj1cInRpdGxlICE9IG51bGxcIj5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjc2ltcGxlVGl0bGU+e3t0aXRsZX19PC9uZy10ZW1wbGF0ZT5cbiAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJpc1RpdGxlVGVtcGxhdGUoKSA/IHRpdGxlIDogc2ltcGxlVGl0bGVcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwiY29udGV4dFwiPjwvbmctdGVtcGxhdGU+XG4gICAgPC9oMz5cbiAgICA8ZGl2IGNsYXNzPVwicG9wb3Zlci1ib2R5XCI+PG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PjwvZGl2PmAsXG4gIHN0eWxlVXJsczogWycuL3BvcG92ZXIuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIE5nYlBvcG92ZXJXaW5kb3cge1xuICBASW5wdXQoKSB0aXRsZTogdW5kZWZpbmVkIHwgc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55PjtcbiAgQElucHV0KCkgaWQ6IHN0cmluZztcbiAgQElucHV0KCkgcG9wb3ZlckNsYXNzOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGNvbnRleHQ6IGFueTtcblxuICBpc1RpdGxlVGVtcGxhdGUoKSB7IHJldHVybiB0aGlzLnRpdGxlIGluc3RhbmNlb2YgVGVtcGxhdGVSZWY7IH1cbn1cblxuLyoqXG4gKiBBIGxpZ2h0d2VpZ2h0IGFuZCBleHRlbnNpYmxlIGRpcmVjdGl2ZSBmb3IgZmFuY3kgcG9wb3ZlciBjcmVhdGlvbi5cbiAqL1xuQERpcmVjdGl2ZSh7c2VsZWN0b3I6ICdbbmdiUG9wb3Zlcl0nLCBleHBvcnRBczogJ25nYlBvcG92ZXInfSlcbmV4cG9ydCBjbGFzcyBOZ2JQb3BvdmVyIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlcyB7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgcG9wb3ZlciBzaG91bGQgYmUgY2xvc2VkIG9uIGBFc2NhcGVgIGtleSBhbmQgaW5zaWRlL291dHNpZGUgY2xpY2tzOlxuICAgKlxuICAgKiAqIGB0cnVlYCAtIGNsb3NlcyBvbiBib3RoIG91dHNpZGUgYW5kIGluc2lkZSBjbGlja3MgYXMgd2VsbCBhcyBgRXNjYXBlYCBwcmVzc2VzXG4gICAqICogYGZhbHNlYCAtIGRpc2FibGVzIHRoZSBhdXRvQ2xvc2UgZmVhdHVyZSAoTkI6IHRyaWdnZXJzIHN0aWxsIGFwcGx5KVxuICAgKiAqIGBcImluc2lkZVwiYCAtIGNsb3NlcyBvbiBpbnNpZGUgY2xpY2tzIGFzIHdlbGwgYXMgRXNjYXBlIHByZXNzZXNcbiAgICogKiBgXCJvdXRzaWRlXCJgIC0gY2xvc2VzIG9uIG91dHNpZGUgY2xpY2tzIChzb21ldGltZXMgYWxzbyBhY2hpZXZhYmxlIHRocm91Z2ggdHJpZ2dlcnMpXG4gICAqIGFzIHdlbGwgYXMgYEVzY2FwZWAgcHJlc3Nlc1xuICAgKlxuICAgKiBAc2luY2UgMy4wLjBcbiAgICovXG4gIEBJbnB1dCgpIGF1dG9DbG9zZTogYm9vbGVhbiB8ICdpbnNpZGUnIHwgJ291dHNpZGUnO1xuXG4gIC8qKlxuICAgKiBUaGUgc3RyaW5nIGNvbnRlbnQgb3IgYSBgVGVtcGxhdGVSZWZgIGZvciB0aGUgY29udGVudCB0byBiZSBkaXNwbGF5ZWQgaW4gdGhlIHBvcG92ZXIuXG4gICAqXG4gICAqIElmIHRoZSB0aXRsZSBhbmQgdGhlIGNvbnRlbnQgYXJlIGVtcHR5LCB0aGUgcG9wb3ZlciB3b24ndCBvcGVuLlxuICAgKi9cbiAgQElucHV0KCkgbmdiUG9wb3Zlcjogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55PjtcblxuICAvKipcbiAgICogVGhlIHRpdGxlIG9mIHRoZSBwb3BvdmVyLlxuICAgKlxuICAgKiBJZiB0aGUgdGl0bGUgYW5kIHRoZSBjb250ZW50IGFyZSBlbXB0eSwgdGhlIHBvcG92ZXIgd29uJ3Qgb3Blbi5cbiAgICovXG4gIEBJbnB1dCgpIHBvcG92ZXJUaXRsZTogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55PjtcblxuICAvKipcbiAgICogVGhlIHByZWZlcnJlZCBwbGFjZW1lbnQgb2YgdGhlIHBvcG92ZXIuXG4gICAqXG4gICAqIFBvc3NpYmxlIHZhbHVlcyBhcmUgYFwidG9wXCJgLCBgXCJ0b3AtbGVmdFwiYCwgYFwidG9wLXJpZ2h0XCJgLCBgXCJib3R0b21cImAsIGBcImJvdHRvbS1sZWZ0XCJgLFxuICAgKiBgXCJib3R0b20tcmlnaHRcImAsIGBcImxlZnRcImAsIGBcImxlZnQtdG9wXCJgLCBgXCJsZWZ0LWJvdHRvbVwiYCwgYFwicmlnaHRcImAsIGBcInJpZ2h0LXRvcFwiYCxcbiAgICogYFwicmlnaHQtYm90dG9tXCJgXG4gICAqXG4gICAqIEFjY2VwdHMgYW4gYXJyYXkgb2Ygc3RyaW5ncyBvciBhIHN0cmluZyB3aXRoIHNwYWNlIHNlcGFyYXRlZCBwb3NzaWJsZSB2YWx1ZXMuXG4gICAqXG4gICAqIFRoZSBkZWZhdWx0IG9yZGVyIG9mIHByZWZlcmVuY2UgaXMgYFwiYXV0b1wiYCAoc2FtZSBhcyB0aGUgc2VxdWVuY2UgYWJvdmUpLlxuICAgKlxuICAgKiBQbGVhc2Ugc2VlIHRoZSBbcG9zaXRpb25pbmcgb3ZlcnZpZXddKCMvcG9zaXRpb25pbmcpIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICBASW5wdXQoKSBwbGFjZW1lbnQ6IFBsYWNlbWVudEFycmF5O1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgZXZlbnRzIHRoYXQgc2hvdWxkIHRyaWdnZXIgdGhlIHRvb2x0aXAuXG4gICAqXG4gICAqIFN1cHBvcnRzIGEgc3BhY2Ugc2VwYXJhdGVkIGxpc3Qgb2YgZXZlbnQgbmFtZXMuXG4gICAqIEZvciBtb3JlIGRldGFpbHMgc2VlIHRoZSBbdHJpZ2dlcnMgZGVtb10oIy9jb21wb25lbnRzL3BvcG92ZXIvZXhhbXBsZXMjdHJpZ2dlcnMpLlxuICAgKi9cbiAgQElucHV0KCkgdHJpZ2dlcnM6IHN0cmluZztcblxuICAvKipcbiAgICogQSBzZWxlY3RvciBzcGVjaWZ5aW5nIHRoZSBlbGVtZW50IHRoZSBwb3BvdmVyIHNob3VsZCBiZSBhcHBlbmRlZCB0by5cbiAgICpcbiAgICogQ3VycmVudGx5IG9ubHkgc3VwcG9ydHMgYGJvZHlgLlxuICAgKi9cbiAgQElucHV0KCkgY29udGFpbmVyOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgcG9wb3ZlciBpcyBkaXNhYmxlZCBhbmQgd29uJ3QgYmUgZGlzcGxheWVkLlxuICAgKlxuICAgKiBAc2luY2UgMS4xLjBcbiAgICovXG4gIEBJbnB1dCgpIGRpc2FibGVQb3BvdmVyOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBbiBvcHRpb25hbCBjbGFzcyBhcHBsaWVkIHRvIHRoZSBwb3BvdmVyIHdpbmRvdyBlbGVtZW50LlxuICAgKlxuICAgKiBAc2luY2UgMi4yLjBcbiAgICovXG4gIEBJbnB1dCgpIHBvcG92ZXJDbGFzczogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgb3BlbmluZyBkZWxheSBpbiBtcy4gV29ya3Mgb25seSBmb3IgXCJub24tbWFudWFsXCIgb3BlbmluZyB0cmlnZ2VycyBkZWZpbmVkIGJ5IHRoZSBgdHJpZ2dlcnNgIGlucHV0LlxuICAgKlxuICAgKiBAc2luY2UgNC4xLjBcbiAgICovXG4gIEBJbnB1dCgpIG9wZW5EZWxheTogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgY2xvc2luZyBkZWxheSBpbiBtcy4gV29ya3Mgb25seSBmb3IgXCJub24tbWFudWFsXCIgb3BlbmluZyB0cmlnZ2VycyBkZWZpbmVkIGJ5IHRoZSBgdHJpZ2dlcnNgIGlucHV0LlxuICAgKlxuICAgKiBAc2luY2UgNC4xLjBcbiAgICovXG4gIEBJbnB1dCgpIGNsb3NlRGVsYXk6IG51bWJlcjtcblxuICAvKipcbiAgICogQW4gZXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBwb3BvdmVyIGlzIHNob3duLiBDb250YWlucyBubyBwYXlsb2FkLlxuICAgKi9cbiAgQE91dHB1dCgpIHNob3duID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIC8qKlxuICAgKiBBbiBldmVudCBlbWl0dGVkIHdoZW4gdGhlIHBvcG92ZXIgaXMgaGlkZGVuLiBDb250YWlucyBubyBwYXlsb2FkLlxuICAgKi9cbiAgQE91dHB1dCgpIGhpZGRlbiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBwcml2YXRlIF9uZ2JQb3BvdmVyV2luZG93SWQgPSBgbmdiLXBvcG92ZXItJHtuZXh0SWQrK31gO1xuICBwcml2YXRlIF9wb3B1cFNlcnZpY2U6IFBvcHVwU2VydmljZTxOZ2JQb3BvdmVyV2luZG93PjtcbiAgcHJpdmF0ZSBfd2luZG93UmVmOiBDb21wb25lbnRSZWY8TmdiUG9wb3ZlcldpbmRvdz47XG4gIHByaXZhdGUgX3VucmVnaXN0ZXJMaXN0ZW5lcnNGbjtcbiAgcHJpdmF0ZSBfem9uZVN1YnNjcmlwdGlvbjogYW55O1xuICBwcml2YXRlIF9pc0Rpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmRpc2FibGVQb3BvdmVyKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLm5nYlBvcG92ZXIgJiYgIXRoaXMucG9wb3ZlclRpdGxlKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PiwgcHJpdmF0ZSBfcmVuZGVyZXI6IFJlbmRlcmVyMiwgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgICAgY29tcG9uZW50RmFjdG9yeVJlc29sdmVyOiBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYsIGNvbmZpZzogTmdiUG9wb3ZlckNvbmZpZyxcbiAgICAgIHByaXZhdGUgX25nWm9uZTogTmdab25lLCBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIF9kb2N1bWVudDogYW55LCBwcml2YXRlIF9jaGFuZ2VEZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICBhcHBsaWNhdGlvblJlZjogQXBwbGljYXRpb25SZWYpIHtcbiAgICB0aGlzLmF1dG9DbG9zZSA9IGNvbmZpZy5hdXRvQ2xvc2U7XG4gICAgdGhpcy5wbGFjZW1lbnQgPSBjb25maWcucGxhY2VtZW50O1xuICAgIHRoaXMudHJpZ2dlcnMgPSBjb25maWcudHJpZ2dlcnM7XG4gICAgdGhpcy5jb250YWluZXIgPSBjb25maWcuY29udGFpbmVyO1xuICAgIHRoaXMuZGlzYWJsZVBvcG92ZXIgPSBjb25maWcuZGlzYWJsZVBvcG92ZXI7XG4gICAgdGhpcy5wb3BvdmVyQ2xhc3MgPSBjb25maWcucG9wb3ZlckNsYXNzO1xuICAgIHRoaXMub3BlbkRlbGF5ID0gY29uZmlnLm9wZW5EZWxheTtcbiAgICB0aGlzLmNsb3NlRGVsYXkgPSBjb25maWcuY2xvc2VEZWxheTtcbiAgICB0aGlzLl9wb3B1cFNlcnZpY2UgPSBuZXcgUG9wdXBTZXJ2aWNlPE5nYlBvcG92ZXJXaW5kb3c+KFxuICAgICAgICBOZ2JQb3BvdmVyV2luZG93LCBpbmplY3Rvciwgdmlld0NvbnRhaW5lclJlZiwgX3JlbmRlcmVyLCBjb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsIGFwcGxpY2F0aW9uUmVmKTtcblxuICAgIHRoaXMuX3pvbmVTdWJzY3JpcHRpb24gPSBfbmdab25lLm9uU3RhYmxlLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fd2luZG93UmVmKSB7XG4gICAgICAgIHBvc2l0aW9uRWxlbWVudHMoXG4gICAgICAgICAgICB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsIHRoaXMuX3dpbmRvd1JlZi5sb2NhdGlvbi5uYXRpdmVFbGVtZW50LCB0aGlzLnBsYWNlbWVudCxcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyID09PSAnYm9keScsICdicy1wb3BvdmVyJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogT3BlbnMgdGhlIHBvcG92ZXIuXG4gICAqXG4gICAqIFRoaXMgaXMgY29uc2lkZXJlZCB0byBiZSBhIFwibWFudWFsXCIgdHJpZ2dlcmluZy5cbiAgICogVGhlIGBjb250ZXh0YCBpcyBhbiBvcHRpb25hbCB2YWx1ZSB0byBiZSBpbmplY3RlZCBpbnRvIHRoZSBwb3BvdmVyIHRlbXBsYXRlIHdoZW4gaXQgaXMgY3JlYXRlZC5cbiAgICovXG4gIG9wZW4oY29udGV4dD86IGFueSkge1xuICAgIGlmICghdGhpcy5fd2luZG93UmVmICYmICF0aGlzLl9pc0Rpc2FibGVkKCkpIHtcbiAgICAgIHRoaXMuX3dpbmRvd1JlZiA9IHRoaXMuX3BvcHVwU2VydmljZS5vcGVuKHRoaXMubmdiUG9wb3ZlciwgY29udGV4dCk7XG4gICAgICB0aGlzLl93aW5kb3dSZWYuaW5zdGFuY2UudGl0bGUgPSB0aGlzLnBvcG92ZXJUaXRsZTtcbiAgICAgIHRoaXMuX3dpbmRvd1JlZi5pbnN0YW5jZS5jb250ZXh0ID0gY29udGV4dDtcbiAgICAgIHRoaXMuX3dpbmRvd1JlZi5pbnN0YW5jZS5wb3BvdmVyQ2xhc3MgPSB0aGlzLnBvcG92ZXJDbGFzcztcbiAgICAgIHRoaXMuX3dpbmRvd1JlZi5pbnN0YW5jZS5pZCA9IHRoaXMuX25nYlBvcG92ZXJXaW5kb3dJZDtcblxuICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ2FyaWEtZGVzY3JpYmVkYnknLCB0aGlzLl9uZ2JQb3BvdmVyV2luZG93SWQpO1xuXG4gICAgICBpZiAodGhpcy5jb250YWluZXIgPT09ICdib2R5Jykge1xuICAgICAgICB0aGlzLl9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29udGFpbmVyKS5hcHBlbmRDaGlsZCh0aGlzLl93aW5kb3dSZWYubG9jYXRpb24ubmF0aXZlRWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFdlIG5lZWQgdG8gZGV0ZWN0IGNoYW5nZXMsIGJlY2F1c2Ugd2UgZG9uJ3Qga25vdyB3aGVyZSAub3BlbigpIG1pZ2h0IGJlIGNhbGxlZCBmcm9tLlxuICAgICAgLy8gRXguIG9wZW5pbmcgcG9wb3ZlciBmcm9tIG9uZSBvZiBsaWZlY3ljbGUgaG9va3MgdGhhdCBydW4gYWZ0ZXIgdGhlIENEXG4gICAgICAvLyAoc2F5IGZyb20gbmdBZnRlclZpZXdJbml0KSB3aWxsIHJlc3VsdCBpbiAnRXhwcmVzc2lvbkhhc0NoYW5nZWQnIGV4Y2VwdGlvblxuICAgICAgdGhpcy5fd2luZG93UmVmLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcblxuICAgICAgLy8gV2UgbmVlZCB0byBtYXJrIGZvciBjaGVjaywgYmVjYXVzZSBwb3BvdmVyIHdvbid0IHdvcmsgaW5zaWRlIHRoZSBPblB1c2ggY29tcG9uZW50LlxuICAgICAgLy8gRXguIHdoZW4gd2UgdXNlIGV4cHJlc3Npb24gbGlrZSBge3sgcG9wb3Zlci5pc09wZW4oKSA6ICdvcGVuZWQnIDogJ2Nsb3NlZCcgfX1gXG4gICAgICAvLyBpbnNpZGUgdGhlIHRlbXBsYXRlIG9mIGFuIE9uUHVzaCBjb21wb25lbnQgYW5kIHdlIGNoYW5nZSB0aGUgcG9wb3ZlciBmcm9tXG4gICAgICAvLyBvcGVuIC0+IGNsb3NlZCwgdGhlIGV4cHJlc3Npb24gaW4gcXVlc3Rpb24gd29uJ3QgYmUgdXBkYXRlZCB1bmxlc3Mgd2UgZXhwbGljaXRseVxuICAgICAgLy8gbWFyayB0aGUgcGFyZW50IGNvbXBvbmVudCB0byBiZSBjaGVja2VkLlxuICAgICAgdGhpcy5fd2luZG93UmVmLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgICBuZ2JBdXRvQ2xvc2UoXG4gICAgICAgICAgdGhpcy5fbmdab25lLCB0aGlzLl9kb2N1bWVudCwgdGhpcy5hdXRvQ2xvc2UsICgpID0+IHRoaXMuY2xvc2UoKSwgdGhpcy5oaWRkZW4sXG4gICAgICAgICAgW3RoaXMuX3dpbmRvd1JlZi5sb2NhdGlvbi5uYXRpdmVFbGVtZW50XSk7XG4gICAgICB0aGlzLnNob3duLmVtaXQoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIHRoZSBwb3BvdmVyLlxuICAgKlxuICAgKiBUaGlzIGlzIGNvbnNpZGVyZWQgdG8gYmUgYSBcIm1hbnVhbFwiIHRyaWdnZXJpbmcgb2YgdGhlIHBvcG92ZXIuXG4gICAqL1xuICBjbG9zZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fd2luZG93UmVmKSB7XG4gICAgICB0aGlzLl9yZW5kZXJlci5yZW1vdmVBdHRyaWJ1dGUodGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAnYXJpYS1kZXNjcmliZWRieScpO1xuICAgICAgdGhpcy5fcG9wdXBTZXJ2aWNlLmNsb3NlKCk7XG4gICAgICB0aGlzLl93aW5kb3dSZWYgPSBudWxsO1xuICAgICAgdGhpcy5oaWRkZW4uZW1pdCgpO1xuICAgICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZXMgdGhlIHBvcG92ZXIuXG4gICAqXG4gICAqIFRoaXMgaXMgY29uc2lkZXJlZCB0byBiZSBhIFwibWFudWFsXCIgdHJpZ2dlcmluZyBvZiB0aGUgcG9wb3Zlci5cbiAgICovXG4gIHRvZ2dsZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fd2luZG93UmVmKSB7XG4gICAgICB0aGlzLmNsb3NlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub3BlbigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGB0cnVlYCwgaWYgdGhlIHBvcG92ZXIgaXMgY3VycmVudGx5IHNob3duLlxuICAgKi9cbiAgaXNPcGVuKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5fd2luZG93UmVmICE9IG51bGw7IH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLl91bnJlZ2lzdGVyTGlzdGVuZXJzRm4gPSBsaXN0ZW5Ub1RyaWdnZXJzKFxuICAgICAgICB0aGlzLl9yZW5kZXJlciwgdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCB0aGlzLnRyaWdnZXJzLCB0aGlzLmlzT3Blbi5iaW5kKHRoaXMpLCB0aGlzLm9wZW4uYmluZCh0aGlzKSxcbiAgICAgICAgdGhpcy5jbG9zZS5iaW5kKHRoaXMpLCArdGhpcy5vcGVuRGVsYXksICt0aGlzLmNsb3NlRGVsYXkpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoe25nYlBvcG92ZXIsIHBvcG92ZXJUaXRsZSwgZGlzYWJsZVBvcG92ZXIsIHBvcG92ZXJDbGFzc306IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAocG9wb3ZlckNsYXNzICYmIHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMuX3dpbmRvd1JlZi5pbnN0YW5jZS5wb3BvdmVyQ2xhc3MgPSBwb3BvdmVyQ2xhc3MuY3VycmVudFZhbHVlO1xuICAgIH1cbiAgICAvLyBjbG9zZSBwb3BvdmVyIGlmIHRpdGxlIGFuZCBjb250ZW50IGJlY29tZSBlbXB0eSwgb3IgZGlzYWJsZVBvcG92ZXIgc2V0IHRvIHRydWVcbiAgICBpZiAoKG5nYlBvcG92ZXIgfHwgcG9wb3ZlclRpdGxlIHx8IGRpc2FibGVQb3BvdmVyKSAmJiB0aGlzLl9pc0Rpc2FibGVkKCkpIHtcbiAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmNsb3NlKCk7XG4gICAgLy8gVGhpcyBjaGVjayBpcyBuZWVkZWQgYXMgaXQgbWlnaHQgaGFwcGVuIHRoYXQgbmdPbkRlc3Ryb3kgaXMgY2FsbGVkIGJlZm9yZSBuZ09uSW5pdFxuICAgIC8vIHVuZGVyIGNlcnRhaW4gY29uZGl0aW9ucywgc2VlOiBodHRwczovL2dpdGh1Yi5jb20vbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcC9pc3N1ZXMvMjE5OVxuICAgIGlmICh0aGlzLl91bnJlZ2lzdGVyTGlzdGVuZXJzRm4pIHtcbiAgICAgIHRoaXMuX3VucmVnaXN0ZXJMaXN0ZW5lcnNGbigpO1xuICAgIH1cbiAgICB0aGlzLl96b25lU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIH1cbn1cbiJdfQ==