tooltip.directive.js 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import * as tslib_1 from "tslib";
  6. /* tslint:disable: max-file-line-count deprecation */
  7. import { Directive, ElementRef, EventEmitter, HostBinding, Input, Output, Renderer2, ViewContainerRef } from '@angular/core';
  8. import { TooltipContainerComponent } from './tooltip-container.component';
  9. import { TooltipConfig } from './tooltip.config';
  10. import { ComponentLoaderFactory } from 'ngx-bootstrap/component-loader';
  11. import { OnChange, warnOnce, parseTriggers } from 'ngx-bootstrap/utils';
  12. import { PositioningService } from 'ngx-bootstrap/positioning';
  13. import { timer } from 'rxjs';
  14. /** @type {?} */
  15. var id = 0;
  16. var TooltipDirective = /** @class */ (function () {
  17. function TooltipDirective(_viewContainerRef, cis, config, _elementRef, _renderer, _positionService) {
  18. this._elementRef = _elementRef;
  19. this._renderer = _renderer;
  20. this._positionService = _positionService;
  21. this.tooltipId = id++;
  22. /**
  23. * Fired when tooltip content changes
  24. */
  25. /* tslint:disable-next-line:no-any */
  26. this.tooltipChange = new EventEmitter();
  27. /**
  28. * Css class for tooltip container
  29. */
  30. this.containerClass = '';
  31. /**
  32. * @deprecated - removed, will be added to configuration
  33. */
  34. this.tooltipAnimation = true;
  35. /**
  36. * @deprecated
  37. */
  38. this.tooltipFadeDuration = 150;
  39. this.ariaDescribedby = "tooltip-" + this.tooltipId;
  40. /**
  41. * @deprecated
  42. */
  43. this.tooltipStateChanged = new EventEmitter();
  44. this._tooltip = cis
  45. .createLoader(this._elementRef, _viewContainerRef, this._renderer)
  46. .provide({ provide: TooltipConfig, useValue: config });
  47. Object.assign(this, config);
  48. this.onShown = this._tooltip.onShown;
  49. this.onHidden = this._tooltip.onHidden;
  50. }
  51. Object.defineProperty(TooltipDirective.prototype, "isOpen", {
  52. /**
  53. * Returns whether or not the tooltip is currently being shown
  54. */
  55. get: /**
  56. * Returns whether or not the tooltip is currently being shown
  57. * @return {?}
  58. */
  59. function () {
  60. return this._tooltip.isShown;
  61. },
  62. set: /**
  63. * @param {?} value
  64. * @return {?}
  65. */
  66. function (value) {
  67. if (value) {
  68. this.show();
  69. }
  70. else {
  71. this.hide();
  72. }
  73. },
  74. enumerable: true,
  75. configurable: true
  76. });
  77. Object.defineProperty(TooltipDirective.prototype, "htmlContent", {
  78. /** @deprecated - please use `tooltip` instead */
  79. set: /**
  80. * @deprecated - please use `tooltip` instead
  81. * @param {?} value
  82. * @return {?}
  83. */
  84. function (value) {
  85. warnOnce('tooltipHtml was deprecated, please use `tooltip` instead');
  86. this.tooltip = value;
  87. },
  88. enumerable: true,
  89. configurable: true
  90. });
  91. Object.defineProperty(TooltipDirective.prototype, "_placement", {
  92. /** @deprecated - please use `placement` instead */
  93. set: /**
  94. * @deprecated - please use `placement` instead
  95. * @param {?} value
  96. * @return {?}
  97. */
  98. function (value) {
  99. warnOnce('tooltipPlacement was deprecated, please use `placement` instead');
  100. this.placement = value;
  101. },
  102. enumerable: true,
  103. configurable: true
  104. });
  105. Object.defineProperty(TooltipDirective.prototype, "_isOpen", {
  106. get: /**
  107. * @return {?}
  108. */
  109. function () {
  110. warnOnce('tooltipIsOpen was deprecated, please use `isOpen` instead');
  111. return this.isOpen;
  112. },
  113. /** @deprecated - please use `isOpen` instead */
  114. set: /**
  115. * @deprecated - please use `isOpen` instead
  116. * @param {?} value
  117. * @return {?}
  118. */
  119. function (value) {
  120. warnOnce('tooltipIsOpen was deprecated, please use `isOpen` instead');
  121. this.isOpen = value;
  122. },
  123. enumerable: true,
  124. configurable: true
  125. });
  126. Object.defineProperty(TooltipDirective.prototype, "_enable", {
  127. get: /**
  128. * @return {?}
  129. */
  130. function () {
  131. warnOnce('tooltipEnable was deprecated, please use `isDisabled` instead');
  132. return this.isDisabled;
  133. },
  134. /** @deprecated - please use `isDisabled` instead */
  135. set: /**
  136. * @deprecated - please use `isDisabled` instead
  137. * @param {?} value
  138. * @return {?}
  139. */
  140. function (value) {
  141. warnOnce('tooltipEnable was deprecated, please use `isDisabled` instead');
  142. this.isDisabled = !value;
  143. },
  144. enumerable: true,
  145. configurable: true
  146. });
  147. Object.defineProperty(TooltipDirective.prototype, "_appendToBody", {
  148. get: /**
  149. * @return {?}
  150. */
  151. function () {
  152. warnOnce('tooltipAppendToBody was deprecated, please use `container="body"` instead');
  153. return this.container === 'body';
  154. },
  155. /** @deprecated - please use `container="body"` instead */
  156. set: /**
  157. * @deprecated - please use `container="body"` instead
  158. * @param {?} value
  159. * @return {?}
  160. */
  161. function (value) {
  162. warnOnce('tooltipAppendToBody was deprecated, please use `container="body"` instead');
  163. this.container = value ? 'body' : this.container;
  164. },
  165. enumerable: true,
  166. configurable: true
  167. });
  168. Object.defineProperty(TooltipDirective.prototype, "_popupClass", {
  169. /** @deprecated - will replaced with customClass */
  170. set: /**
  171. * @deprecated - will replaced with customClass
  172. * @param {?} value
  173. * @return {?}
  174. */
  175. function (value) {
  176. warnOnce('tooltipClass deprecated');
  177. },
  178. enumerable: true,
  179. configurable: true
  180. });
  181. Object.defineProperty(TooltipDirective.prototype, "_tooltipContext", {
  182. /** @deprecated - removed */
  183. set: /**
  184. * @deprecated - removed
  185. * @param {?} value
  186. * @return {?}
  187. */
  188. function (value) {
  189. warnOnce('tooltipContext deprecated');
  190. },
  191. enumerable: true,
  192. configurable: true
  193. });
  194. Object.defineProperty(TooltipDirective.prototype, "_tooltipPopupDelay", {
  195. /** @deprecated */
  196. set: /**
  197. * @deprecated
  198. * @param {?} value
  199. * @return {?}
  200. */
  201. function (value) {
  202. warnOnce('tooltipPopupDelay is deprecated, use `delay` instead');
  203. this.delay = value;
  204. },
  205. enumerable: true,
  206. configurable: true
  207. });
  208. Object.defineProperty(TooltipDirective.prototype, "_tooltipTrigger", {
  209. /** @deprecated - please use `triggers` instead */
  210. get: /**
  211. * @deprecated - please use `triggers` instead
  212. * @return {?}
  213. */
  214. function () {
  215. warnOnce('tooltipTrigger was deprecated, please use `triggers` instead');
  216. return this.triggers;
  217. },
  218. set: /**
  219. * @param {?} value
  220. * @return {?}
  221. */
  222. function (value) {
  223. warnOnce('tooltipTrigger was deprecated, please use `triggers` instead');
  224. this.triggers = (value || '').toString();
  225. },
  226. enumerable: true,
  227. configurable: true
  228. });
  229. /**
  230. * @return {?}
  231. */
  232. TooltipDirective.prototype.ngOnInit = /**
  233. * @return {?}
  234. */
  235. function () {
  236. var _this = this;
  237. this._tooltip.listen({
  238. triggers: this.triggers,
  239. show: (/**
  240. * @return {?}
  241. */
  242. function () { return _this.show(); })
  243. });
  244. /* tslint:disable-next-line:no-any */
  245. this.tooltipChange.subscribe((/**
  246. * @param {?} value
  247. * @return {?}
  248. */
  249. function (value) {
  250. if (!value) {
  251. _this._tooltip.hide();
  252. }
  253. }));
  254. };
  255. /**
  256. * Toggles an element’s tooltip. This is considered a “manual” triggering of
  257. * the tooltip.
  258. */
  259. /**
  260. * Toggles an element’s tooltip. This is considered a “manual” triggering of
  261. * the tooltip.
  262. * @return {?}
  263. */
  264. TooltipDirective.prototype.toggle = /**
  265. * Toggles an element’s tooltip. This is considered a “manual” triggering of
  266. * the tooltip.
  267. * @return {?}
  268. */
  269. function () {
  270. if (this.isOpen) {
  271. return this.hide();
  272. }
  273. this.show();
  274. };
  275. /**
  276. * Opens an element’s tooltip. This is considered a “manual” triggering of
  277. * the tooltip.
  278. */
  279. /**
  280. * Opens an element’s tooltip. This is considered a “manual” triggering of
  281. * the tooltip.
  282. * @return {?}
  283. */
  284. TooltipDirective.prototype.show = /**
  285. * Opens an element’s tooltip. This is considered a “manual” triggering of
  286. * the tooltip.
  287. * @return {?}
  288. */
  289. function () {
  290. var _this = this;
  291. this._positionService.setOptions({
  292. modifiers: {
  293. flip: {
  294. enabled: this.adaptivePosition
  295. },
  296. preventOverflow: {
  297. enabled: this.adaptivePosition
  298. }
  299. }
  300. });
  301. if (this.isOpen ||
  302. this.isDisabled ||
  303. this._delayTimeoutId ||
  304. !this.tooltip) {
  305. return;
  306. }
  307. /** @type {?} */
  308. var showTooltip = (/**
  309. * @return {?}
  310. */
  311. function () {
  312. if (_this._delayTimeoutId) {
  313. _this._delayTimeoutId = undefined;
  314. }
  315. _this._tooltip
  316. .attach(TooltipContainerComponent)
  317. .to(_this.container)
  318. .position({ attachment: _this.placement })
  319. .show({
  320. content: _this.tooltip,
  321. placement: _this.placement,
  322. containerClass: _this.containerClass,
  323. id: _this.ariaDescribedby
  324. });
  325. });
  326. /** @type {?} */
  327. var cancelDelayedTooltipShowing = (/**
  328. * @return {?}
  329. */
  330. function () {
  331. if (_this._tooltipCancelShowFn) {
  332. _this._tooltipCancelShowFn();
  333. }
  334. });
  335. if (this.delay) {
  336. /** @type {?} */
  337. var _timer_1 = timer(this.delay).subscribe((/**
  338. * @return {?}
  339. */
  340. function () {
  341. showTooltip();
  342. cancelDelayedTooltipShowing();
  343. }));
  344. if (this.triggers) {
  345. parseTriggers(this.triggers)
  346. .forEach((/**
  347. * @param {?} trigger
  348. * @return {?}
  349. */
  350. function (trigger) {
  351. _this._tooltipCancelShowFn = _this._renderer.listen(_this._elementRef.nativeElement, trigger.close, (/**
  352. * @return {?}
  353. */
  354. function () {
  355. _timer_1.unsubscribe();
  356. cancelDelayedTooltipShowing();
  357. }));
  358. }));
  359. }
  360. }
  361. else {
  362. showTooltip();
  363. }
  364. };
  365. /**
  366. * Closes an element’s tooltip. This is considered a “manual” triggering of
  367. * the tooltip.
  368. */
  369. /**
  370. * Closes an element’s tooltip. This is considered a “manual” triggering of
  371. * the tooltip.
  372. * @return {?}
  373. */
  374. TooltipDirective.prototype.hide = /**
  375. * Closes an element’s tooltip. This is considered a “manual” triggering of
  376. * the tooltip.
  377. * @return {?}
  378. */
  379. function () {
  380. var _this = this;
  381. if (this._delayTimeoutId) {
  382. clearTimeout(this._delayTimeoutId);
  383. this._delayTimeoutId = undefined;
  384. }
  385. if (!this._tooltip.isShown) {
  386. return;
  387. }
  388. this._tooltip.instance.classMap.in = false;
  389. setTimeout((/**
  390. * @return {?}
  391. */
  392. function () {
  393. _this._tooltip.hide();
  394. }), this.tooltipFadeDuration);
  395. };
  396. /**
  397. * @return {?}
  398. */
  399. TooltipDirective.prototype.ngOnDestroy = /**
  400. * @return {?}
  401. */
  402. function () {
  403. this._tooltip.dispose();
  404. };
  405. TooltipDirective.decorators = [
  406. { type: Directive, args: [{
  407. selector: '[tooltip], [tooltipHtml]',
  408. exportAs: 'bs-tooltip'
  409. },] }
  410. ];
  411. /** @nocollapse */
  412. TooltipDirective.ctorParameters = function () { return [
  413. { type: ViewContainerRef },
  414. { type: ComponentLoaderFactory },
  415. { type: TooltipConfig },
  416. { type: ElementRef },
  417. { type: Renderer2 },
  418. { type: PositioningService }
  419. ]; };
  420. TooltipDirective.propDecorators = {
  421. adaptivePosition: [{ type: Input }],
  422. tooltip: [{ type: Input }],
  423. tooltipChange: [{ type: Output }],
  424. placement: [{ type: Input }],
  425. triggers: [{ type: Input }],
  426. container: [{ type: Input }],
  427. containerClass: [{ type: Input }],
  428. isOpen: [{ type: Input }],
  429. isDisabled: [{ type: Input }],
  430. delay: [{ type: Input }],
  431. onShown: [{ type: Output }],
  432. onHidden: [{ type: Output }],
  433. htmlContent: [{ type: Input, args: ['tooltipHtml',] }],
  434. _placement: [{ type: Input, args: ['tooltipPlacement',] }],
  435. _isOpen: [{ type: Input, args: ['tooltipIsOpen',] }],
  436. _enable: [{ type: Input, args: ['tooltipEnable',] }],
  437. _appendToBody: [{ type: Input, args: ['tooltipAppendToBody',] }],
  438. tooltipAnimation: [{ type: Input }],
  439. _popupClass: [{ type: Input, args: ['tooltipClass',] }],
  440. _tooltipContext: [{ type: Input, args: ['tooltipContext',] }],
  441. _tooltipPopupDelay: [{ type: Input, args: ['tooltipPopupDelay',] }],
  442. tooltipFadeDuration: [{ type: Input }],
  443. _tooltipTrigger: [{ type: Input, args: ['tooltipTrigger',] }],
  444. ariaDescribedby: [{ type: HostBinding, args: ['attr.aria-describedby',] }],
  445. tooltipStateChanged: [{ type: Output }]
  446. };
  447. tslib_1.__decorate([
  448. OnChange(),
  449. tslib_1.__metadata("design:type", Object)
  450. ], TooltipDirective.prototype, "tooltip", void 0);
  451. return TooltipDirective;
  452. }());
  453. export { TooltipDirective };
  454. if (false) {
  455. /** @type {?} */
  456. TooltipDirective.prototype.tooltipId;
  457. /**
  458. * sets disable adaptive position
  459. * @type {?}
  460. */
  461. TooltipDirective.prototype.adaptivePosition;
  462. /**
  463. * Content to be displayed as tooltip.
  464. * @type {?}
  465. */
  466. TooltipDirective.prototype.tooltip;
  467. /**
  468. * Fired when tooltip content changes
  469. * @type {?}
  470. */
  471. TooltipDirective.prototype.tooltipChange;
  472. /**
  473. * Placement of a tooltip. Accepts: "top", "bottom", "left", "right"
  474. * @type {?}
  475. */
  476. TooltipDirective.prototype.placement;
  477. /**
  478. * Specifies events that should trigger. Supports a space separated list of
  479. * event names.
  480. * @type {?}
  481. */
  482. TooltipDirective.prototype.triggers;
  483. /**
  484. * A selector specifying the element the tooltip should be appended to.
  485. * @type {?}
  486. */
  487. TooltipDirective.prototype.container;
  488. /**
  489. * Css class for tooltip container
  490. * @type {?}
  491. */
  492. TooltipDirective.prototype.containerClass;
  493. /**
  494. * Allows to disable tooltip
  495. * @type {?}
  496. */
  497. TooltipDirective.prototype.isDisabled;
  498. /**
  499. * Delay before showing the tooltip
  500. * @type {?}
  501. */
  502. TooltipDirective.prototype.delay;
  503. /**
  504. * Emits an event when the tooltip is shown
  505. * @type {?}
  506. */
  507. TooltipDirective.prototype.onShown;
  508. /**
  509. * Emits an event when the tooltip is hidden
  510. * @type {?}
  511. */
  512. TooltipDirective.prototype.onHidden;
  513. /**
  514. * @deprecated - removed, will be added to configuration
  515. * @type {?}
  516. */
  517. TooltipDirective.prototype.tooltipAnimation;
  518. /**
  519. * @deprecated
  520. * @type {?}
  521. */
  522. TooltipDirective.prototype.tooltipFadeDuration;
  523. /** @type {?} */
  524. TooltipDirective.prototype.ariaDescribedby;
  525. /**
  526. * @deprecated
  527. * @type {?}
  528. */
  529. TooltipDirective.prototype.tooltipStateChanged;
  530. /**
  531. * @type {?}
  532. * @protected
  533. */
  534. TooltipDirective.prototype._delayTimeoutId;
  535. /**
  536. * @type {?}
  537. * @protected
  538. */
  539. TooltipDirective.prototype._tooltipCancelShowFn;
  540. /**
  541. * @type {?}
  542. * @private
  543. */
  544. TooltipDirective.prototype._tooltip;
  545. /**
  546. * @type {?}
  547. * @private
  548. */
  549. TooltipDirective.prototype._elementRef;
  550. /**
  551. * @type {?}
  552. * @private
  553. */
  554. TooltipDirective.prototype._renderer;
  555. /**
  556. * @type {?}
  557. * @private
  558. */
  559. TooltipDirective.prototype._positionService;
  560. }
  561. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbHRpcC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtYm9vdHN0cmFwL3Rvb2x0aXAvIiwic291cmNlcyI6WyJ0b29sdGlwLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osV0FBVyxFQUNYLEtBQUssRUFHTCxNQUFNLEVBQ04sU0FBUyxFQUVULGdCQUFnQixFQUNqQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMxRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFakQsT0FBTyxFQUFtQixzQkFBc0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBVyxNQUFNLHFCQUFxQixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRS9ELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7O0lBRXpCLEVBQUUsR0FBRyxDQUFDO0FBRVY7SUFxTEUsMEJBQ0UsaUJBQW1DLEVBQ25DLEdBQTJCLEVBQzNCLE1BQXFCLEVBQ2IsV0FBdUIsRUFDdkIsU0FBb0IsRUFDcEIsZ0JBQW9DO1FBRnBDLGdCQUFXLEdBQVgsV0FBVyxDQUFZO1FBQ3ZCLGNBQVMsR0FBVCxTQUFTLENBQVc7UUFDcEIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFvQjtRQXRMOUMsY0FBUyxHQUFHLEVBQUUsRUFBRSxDQUFDOzs7O1FBWWpCLHFDQUFxQztRQUNyQyxrQkFBYSxHQUE0QyxJQUFJLFlBQVksRUFBRSxDQUFDOzs7O1FBa0JuRSxtQkFBYyxHQUFHLEVBQUUsQ0FBQzs7OztRQWlHcEIscUJBQWdCLEdBQUcsSUFBSSxDQUFDOzs7O1FBdUJ4Qix3QkFB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Q0FBdUI7Ozs7O0lBTXZCLG1DQUFxQzs7Ozs7SUFLckMsb0NBQXNDOzs7OztJQTZEdEMsNENBQWlDOzs7OztJQXVCakMsK0NBQW1DOztJQWVuQywyQ0FBb0Y7Ozs7O0lBR3BGLCtDQUN5RTs7Ozs7SUFFekUsMkNBQXdDOzs7OztJQUN4QyxnREFBeUM7Ozs7O0lBRXpDLG9DQUE2RDs7Ozs7SUFLM0QsdUNBQStCOzs7OztJQUMvQixxQ0FBNEI7Ozs7O0lBQzVCLDRDQUE0QyIsInNvdXJjZXNDb250ZW50IjpbIi8qIHRzbGludDpkaXNhYmxlOiBtYXgtZmlsZS1saW5lLWNvdW50IGRlcHJlY2F0aW9uICovXG5pbXBvcnQge1xuICBEaXJlY3RpdmUsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdEJpbmRpbmcsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBSZW5kZXJlcjIsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q29udGFpbmVyUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBUb29sdGlwQ29udGFpbmVyQ29tcG9uZW50IH0gZnJvbSAnLi90b29sdGlwLWNvbnRhaW5lci5jb21wb25lbnQnO1xuaW1wb3J0IHsgVG9vbHRpcENvbmZpZyB9IGZyb20gJy4vdG9vbHRpcC5jb25maWcnO1xuXG5pbXBvcnQgeyBDb21wb25lbnRMb2FkZXIsIENvbXBvbmVudExvYWRlckZhY3RvcnkgfSBmcm9tICduZ3gtYm9vdHN0cmFwL2NvbXBvbmVudC1sb2FkZXInO1xuaW1wb3J0IHsgT25DaGFuZ2UsIHdhcm5PbmNlLCBwYXJzZVRyaWdnZXJzLCBUcmlnZ2VyIH0gZnJvbSAnbmd4LWJvb3RzdHJhcC91dGlscyc7XG5pbXBvcnQgeyBQb3NpdGlvbmluZ1NlcnZpY2UgfSBmcm9tICduZ3gtYm9vdHN0cmFwL3Bvc2l0aW9uaW5nJztcblxuaW1wb3J0IHsgdGltZXIgfSBmcm9tICdyeGpzJztcblxubGV0IGlkID0gMDtcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW3Rvb2x0aXBdLCBbdG9vbHRpcEh0bWxdJyxcbiAgZXhwb3J0QXM6ICdicy10b29sdGlwJ1xufSlcbmV4cG9ydCBjbGFzcyBUb29sdGlwRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICB0b29sdGlwSWQgPSBpZCsrO1xuICAvKiogc2V0cyBkaXNhYmxlIGFkYXB0aXZlIHBvc2l0aW9uICovXG4gIEBJbnB1dCgpIGFkYXB0aXZlUG9zaXRpb246IGJvb2xlYW47XG4gIC8qKlxuICAgKiBDb250ZW50IHRvIGJlIGRpc3BsYXllZCBhcyB0b29sdGlwLlxuICAgKi9cbiAgQE9uQ2hhbmdlKClcbiAgQElucHV0KClcbiAgLyogdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueSAqL1xuICB0b29sdGlwOiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+O1xuICAvKiogRmlyZWQgd2hlbiB0b29sdGlwIGNvbnRlbnQgY2hhbmdlcyAqL1xuICBAT3V0cHV0KClcbiAgLyogdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueSAqL1xuICB0b29sdGlwQ2hhbmdlOiBFdmVudEVtaXR0ZXI8c3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55Pj4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgLyoqXG4gICAqIFBsYWNlbWVudCBvZiBhIHRvb2x0aXAuIEFjY2VwdHM6IFwidG9wXCIsIFwiYm90dG9tXCIsIFwibGVmdFwiLCBcInJpZ2h0XCJcbiAgICovXG4gIEBJbnB1dCgpIHBsYWNlbWVudDogc3RyaW5nO1xuICAvKipcbiAgICogU3BlY2lmaWVzIGV2ZW50cyB0aGF0IHNob3VsZCB0cmlnZ2VyLiBTdXBwb3J0cyBhIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mXG4gICAqIGV2ZW50IG5hbWVzLlxuICAgKi9cbiAgQElucHV0KCkgdHJpZ2dlcnM6IHN0cmluZztcbiAgLyoqXG4gICAqIEEgc2VsZWN0b3Igc3BlY2lmeWluZyB0aGUgZWxlbWVudCB0aGUgdG9vbHRpcCBzaG91bGQgYmUgYXBwZW5kZWQgdG8uXG4gICAqL1xuICBASW5wdXQoKSBjb250YWluZXI6IHN0cmluZztcbiAgLyoqXG4gICAqIENzcyBjbGFzcyBmb3IgdG9vbHRpcCBjb250YWluZXJcbiAgICovXG4gIEBJbnB1dCgpIGNvbnRhaW5lckNsYXNzID0gJyc7XG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSB0b29sdGlwIGlzIGN1cnJlbnRseSBiZWluZyBzaG93blxuICAgKi9cbiAgQElucHV0KClcbiAgZ2V0IGlzT3BlbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fdG9vbHRpcC5pc1Nob3duO1xuICB9XG5cbiAgc2V0IGlzT3Blbih2YWx1ZTogYm9vbGVhbikge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5zaG93KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaGlkZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBbGxvd3MgdG8gZGlzYWJsZSB0b29sdGlwXG4gICAqL1xuICBASW5wdXQoKSBpc0Rpc2FibGVkOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBEZWxheSBiZWZvcmUgc2hvd2luZyB0aGUgdG9vbHRpcFxuICAgKi9cbiAgQElucHV0KCkgZGVsYXk6IG51bWJlcjtcblxuICAvKipcbiAgICogRW1pdHMgYW4gZXZlbnQgd2hlbiB0aGUgdG9vbHRpcCBpcyBzaG93blxuICAgKi9cbiAgLyogdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueSAqL1xuICBAT3V0cHV0KCkgb25TaG93bjogRXZlbnRFbWl0dGVyPGFueT47XG4gIC8qKlxuICAgKiBFbWl0cyBhbiBldmVudCB3aGVuIHRoZSB0b29sdGlwIGlzIGhpZGRlblxuICAgKi9cbiAgLyogdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueSAqL1xuICBAT3V0cHV0KCkgb25IaWRkZW46IEV2ZW50RW1pdHRlcjxhbnk+O1xuXG4gIC8qKiBAZGVwcmVjYXRlZCAtIHBsZWFzZSB1c2UgYHRvb2x0aXBgIGluc3RlYWQgKi9cbiAgQElucHV0KCd0b29sdGlwSHRtbCcpXG4gIC8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnkgKi9cbiAgc2V0IGh0bWxDb250ZW50KHZhbHVlOiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+KSB7XG4gICAgd2Fybk9uY2UoJ3Rvb2x0aXBIdG1sIHdhcyBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIGB0b29sdGlwYCBpbnN0ZWFkJyk7XG4gICAgdGhpcy50b29sdGlwID0gdmFsdWU7XG4gIH1cblxuICAvKiogQGRlcHJlY2F0ZWQgLSBwbGVhc2UgdXNlIGBwbGFjZW1lbnRgIGluc3RlYWQgKi9cbiAgQElucHV0KCd0b29sdGlwUGxhY2VtZW50JylcbiAgc2V0IF9wbGFjZW1lbnQodmFsdWU6IHN0cmluZykge1xuICAgIHdhcm5PbmNlKCd0b29sdGlwUGxhY2VtZW50IHdhcyBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIGBwbGFjZW1lbnRgIGluc3RlYWQnKTtcbiAgICB0aGlzLnBsYWNlbWVudCA9IHZhbHVlO1xuICB9XG5cbiAgLyoqIEBkZXByZWNhdGVkIC0gcGxlYXNlIHVzZSBgaXNPcGVuYCBpbnN0ZWFkICovXG4gIEBJbnB1dCgndG9vbHRpcElzT3BlbicpXG4gIHNldCBfaXNPcGVuKHZhbHVlOiBib29sZWFuKSB7XG4gICAgd2Fybk9uY2UoJ3Rvb2x0aXBJc09wZW4gd2FzIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgYGlzT3BlbmAgaW5zdGVhZCcpO1xuICAgIHRoaXMuaXNPcGVuID0gdmFsdWU7XG4gIH1cblxuICBnZXQgX2lzT3BlbigpOiBib29sZWFuIHtcbiAgICB3YXJuT25jZSgndG9vbHRpcElzT3BlbiB3YXMgZGVwcmVjYXRlZCwgcGxlYXNlIHVzZSBgaXNPcGVuYCBpbnN0ZWFkJyk7XG5cbiAgICByZXR1cm4gdGhpcy5pc09wZW47XG4gIH1cblxuICAvKiogQGRlcHJlY2F0ZWQgLSBwbGVhc2UgdXNlIGBpc0Rpc2FibGVkYCBpbnN0ZWFkICovXG4gIEBJbnB1dCgndG9vbHRpcEVuYWJsZScpXG4gIHNldCBfZW5hYmxlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgd2Fybk9uY2UoJ3Rvb2x0aXBFbmFibGUgd2FzIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgYGlzRGlzYWJsZWRgIGluc3RlYWQnKTtcbiAgICB0aGlzLmlzRGlzYWJsZWQgPSAhdmFsdWU7XG4gIH1cblxuICBnZXQgX2VuYWJsZSgpOiBib29sZWFuIHtcbiAgICB3YXJuT25jZSgndG9vbHRpcEVuYWJsZSB3YXMgZGVwcmVjYXRlZCwgcGxlYXNlIHVzZSBgaXNEaXNhYmxlZGAgaW5zdGVhZCcpO1xuXG4gICAgcmV0dXJuIHRoaXMuaXNEaXNhYmxlZDtcbiAgfVxuXG4gIC8qKiBAZGVwcmVjYXRlZCAtIHBsZWFzZSB1c2UgYGNvbnRhaW5lcj1cImJvZHlcImAgaW5zdGVhZCAqL1xuICBASW5wdXQoJ3Rvb2x0aXBBcHBlbmRUb0JvZHknKVxuICBzZXQgX2FwcGVuZFRvQm9keSh2YWx1ZTogYm9vbGVhbikge1xuICAgIHdhcm5PbmNlKFxuICAgICAgJ3Rvb2x0aXBBcHBlbmRUb0JvZHkgd2FzIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgYGNvbnRhaW5lcj1cImJvZHlcImAgaW5zdGVhZCdcbiAgICApO1xuICAgIHRoaXMuY29udGFpbmVyID0gdmFsdWUgPyAnYm9keScgOiB0aGlzLmNvbnRhaW5lcjtcbiAgfVxuXG4gIGdldCBfYXBwZW5kVG9Cb2R5KCk6IGJvb2xlYW4ge1xuICAgIHdhcm5PbmNlKFxuICAgICAgJ3Rvb2x0aXBBcHBlbmRUb0JvZHkgd2FzIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgYGNvbnRhaW5lcj1cImJvZHlcImAgaW5zdGVhZCdcbiAgICApO1xuXG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyID09PSAnYm9keSc7XG4gIH1cblxuICAvKiogQGRlcHJlY2F0ZWQgLSByZW1vdmVkLCB3aWxsIGJlIGFkZGVkIHRvIGNvbmZpZ3VyYXRpb24gKi9cbiAgQElucHV0KCkgdG9vbHRpcEFuaW1hdGlvbiA9IHRydWU7XG5cbiAgLyoqIEBkZXByZWNhdGVkIC0gd2lsbCByZXBsYWNlZCB3aXRoIGN1c3RvbUNsYXNzICovXG4gIEBJbnB1dCgndG9vbHRpcENsYXNzJylcbiAgc2V0IF9wb3B1cENsYXNzKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB3YXJuT25jZSgndG9vbHRpcENsYXNzIGRlcHJlY2F0ZWQnKTtcbiAgfVxuXG4gIC8qKiBAZGVwcmVjYXRlZCAtIHJlbW92ZWQgKi9cbiAgQElucHV0KCd0b29sdGlwQ29udGV4dCcpXG4gIC8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnkgKi9cbiAgc2V0IF90b29sdGlwQ29udGV4dCh2YWx1ZTogYW55KSB7XG4gICAgd2Fybk9uY2UoJ3Rvb2x0aXBDb250ZXh0IGRlcHJlY2F0ZWQnKTtcbiAgfVxuXG4gIC8qKiBAZGVwcmVjYXRlZCAqL1xuICBASW5wdXQoJ3Rvb2x0aXBQb3B1cERlbGF5JylcbiAgc2V0IF90b29sdGlwUG9wdXBEZWxheSh2YWx1ZTogbnVtYmVyKSB7XG4gICAgd2Fybk9uY2UoJ3Rvb2x0aXBQb3B1cERlbGF5IGlzIGRlcHJlY2F0ZWQsIHVzZSBgZGVsYXlgIGluc3RlYWQnKTtcbiAgICB0aGlzLmRlbGF5ID0gdmFsdWU7XG4gIH1cblxuICAvKiogQGRlcHJlY2F0ZWQgKi9cbiAgQElucHV0KCkgdG9vbHRpcEZhZGVEdXJhdGlvbiA9IDE1MDtcblxuICAvKiogQGRlcHJlY2F0ZWQgLSAgcGxlYXNlIHVzZSBgdHJpZ2dlcnNgIGluc3RlYWQgKi9cbiAgQElucHV0KCd0b29sdGlwVHJpZ2dlcicpXG4gIGdldCBfdG9vbHRpcFRyaWdnZXIoKTogc3RyaW5nIHwgc3RyaW5nW10ge1xuICAgIHdhcm5PbmNlKCd0b29sdGlwVHJpZ2dlciB3YXMgZGVwcmVjYXRlZCwgcGxlYXNlIHVzZSBgdHJpZ2dlcnNgIGluc3RlYWQnKTtcblxuICAgIHJldHVybiB0aGlzLnRyaWdnZXJzO1xuICB9XG5cbiAgc2V0IF90b29sdGlwVHJpZ2dlcih2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10pIHtcbiAgICB3YXJuT25jZSgndG9vbHRpcFRyaWdnZXIgd2FzIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgYHRyaWdnZXJzYCBpbnN0ZWFkJyk7XG4gICAgdGhpcy50cmlnZ2VycyA9ICh2YWx1ZSB8fCAnJykudG9TdHJpbmcoKTtcbiAgfVxuXG4gIEBIb3N0QmluZGluZygnYXR0ci5hcmlhLWRlc2NyaWJlZGJ5JykgYXJpYURlc2NyaWJlZGJ5ID0gYHRvb2x0aXAtJHt0aGlzLnRvb2x0aXBJZH1gO1xuXG4gIC8qKiBAZGVwcmVjYXRlZCAqL1xuICBAT3V0cHV0KClcbiAgdG9vbHRpcFN0YXRlQ2hhbmdlZDogRXZlbnRFbWl0dGVyPGJvb2xlYW4+ID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55ICovXG4gIHByb3RlY3RlZCBfZGVsYXlUaW1lb3V0SWQ6IG51bWJlciB8IGFueTtcbiAgcHJvdGVjdGVkIF90b29sdGlwQ2FuY2VsU2hvd0ZuOiBGdW5jdGlvbjtcblxuICBwcml2YXRlIF90b29sdGlwOiBDb21wb25lbnRMb2FkZXI8VG9vbHRpcENvbnRhaW5lckNvbXBvbmVudD47XG4gIGNvbnN0cnVjdG9yKFxuICAgIF92aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgIGNpczogQ29tcG9uZW50TG9hZGVyRmFjdG9yeSxcbiAgICBjb25maWc6IFRvb2x0aXBDb25maWcsXG4gICAgcHJpdmF0ZSBfZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIF9yZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgX3Bvc2l0aW9uU2VydmljZTogUG9zaXRpb25pbmdTZXJ2aWNlXG4gICkge1xuXG4gICAgdGhpcy5fdG9vbHRpcCA9IGNpc1xuICAgICAgLmNyZWF0ZUxvYWRlcjxUb29sdGlwQ29udGFpbmVyQ29tcG9uZW50PihcbiAgICAgICAgdGhpcy5fZWxlbWVudFJlZixcbiAgICAgICAgX3ZpZXdDb250YWluZXJSZWYsXG4gICAgICAgIHRoaXMuX3JlbmRlcmVyXG4gICAgICApXG4gICAgICAucHJvdmlkZSh7cHJvdmlkZTogVG9vbHRpcENvbmZpZywgdXNlVmFsdWU6IGNvbmZpZ30pO1xuXG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBjb25maWcpO1xuICAgIHRoaXMub25TaG93biA9IHRoaXMuX3Rvb2x0aXAub25TaG93bjtcbiAgICB0aGlzLm9uSGlkZGVuID0gdGhpcy5fdG9vbHRpcC5vbkhpZGRlbjtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuX3Rvb2x0aXAubGlzdGVuKHtcbiAgICAgIHRyaWdnZXJzOiB0aGlzLnRyaWdnZXJzLFxuICAgICAgc2hvdzogKCkgPT4gdGhpcy5zaG93KClcbiAgICB9KTtcbiAgICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55ICovXG4gICAgdGhpcy50b29sdGlwQ2hhbmdlLnN1YnNjcmliZSgodmFsdWU6IGFueSkgPT4ge1xuICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICB0aGlzLl90b29sdGlwLmhpZGUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUb2dnbGVzIGFuIGVsZW1lbnTigJlzIHRvb2x0aXAuIFRoaXMgaXMgY29uc2lkZXJlZCBhIOKAnG1hbnVhbOKAnSB0cmlnZ2VyaW5nIG9mXG4gICAqIHRoZSB0b29sdGlwLlxuICAgKi9cbiAgdG9nZ2xlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzT3Blbikge1xuICAgICAgcmV0dXJuIHRoaXMuaGlkZSgpO1xuICAgIH1cblxuICAgIHRoaXMuc2hvdygpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW5zIGFuIGVsZW1lbnTigJlzIHRvb2x0aXAuIFRoaXMgaXMgY29uc2lkZXJlZCBhIOKAnG1hbnVhbOKAnSB0cmlnZ2VyaW5nIG9mXG4gICAqIHRoZSB0b29sdGlwLlxuICAgKi9cbiAgc2hvdygpOiB2b2lkIHtcbiAgICB0aGlzLl9wb3NpdGlvblNlcnZpY2Uuc2V0T3B0aW9ucyh7XG4gICAgICBtb2RpZmllcnM6IHtcbiAgICAgICAgZmxpcDoge1xuICAgICAgICAgIGVuYWJsZWQ6IHRoaXMuYWRhcHRpdmVQb3NpdGlvblxuICAgICAgICB9LFxuICAgICAgICBwcmV2ZW50T3ZlcmZsb3c6IHtcbiAgICAgICAgICBlbmFibGVkOiB0aGlzLmFkYXB0aXZlUG9zaXRpb25cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5pc09wZW4gfHxcbiAgICAgIHRoaXMuaXNEaXNhYmxlZCB8fFxuICAgICAgdGhpcy5fZGVsYXlUaW1lb3V0SWQgfHxcbiAgICAgICF0aGlzLnRvb2x0aXBcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzaG93VG9vbHRpcCA9ICgpID0+IHtcbiAgICAgIGlmICh0aGlzLl9kZWxheVRpbWVvdXRJZCkge1xuICAgICAgICB0aGlzLl9kZWxheVRpbWVvdXRJZCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fdG9vbHRpcFxuICAgICAgICAuYXR0YWNoKFRvb2x0aXBDb250YWluZXJDb21wb25lbnQpXG4gICAgICAgIC50byh0aGlzLmNvbnRhaW5lcilcbiAgICAgICAgLnBvc2l0aW9uKHthdHRhY2htZW50OiB0aGlzLnBsYWNlbWVudH0pXG4gICAgICAgIC5zaG93KHtcbiAgICAgICAgICBjb250ZW50OiB0aGlzLnRvb2x0aXAsXG4gICAgICAgICAgcGxhY2VtZW50OiB0aGlzLnBsYWNlbWVudCxcbiAgICAgICAgICBjb250YWluZXJDbGFzczogdGhpcy5jb250YWluZXJDbGFzcyxcbiAgICAgICAgICBpZDogdGhpcy5hcmlhRGVzY3JpYmVkYnlcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBjb25zdCBjYW5jZWxEZWxheWVkVG9vbHRpcFNob3dpbmcgPSAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fdG9vbHRpcENhbmNlbFNob3dGbikge1xuICAgICAgICB0aGlzLl90b29sdGlwQ2FuY2VsU2hvd0ZuKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmICh0aGlzLmRlbGF5KSB7XG4gICAgICBjb25zdCBfdGltZXIgPSB0aW1lcih0aGlzLmRlbGF5KS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICBzaG93VG9vbHRpcCgpO1xuICAgICAgICBjYW5jZWxEZWxheWVkVG9vbHRpcFNob3dpbmcoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAodGhpcy50cmlnZ2Vycykge1xuICAgICAgICBwYXJzZVRyaWdnZXJzKHRoaXMudHJpZ2dlcnMpXG4gICAgICAgICAgLmZvckVhY2goKHRyaWdnZXI6IFRyaWdnZXIpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3Rvb2x0aXBDYW5jZWxTaG93Rm4gPSB0aGlzLl9yZW5kZXJlci5saXN0ZW4oXG4gICAgICAgICAgICAgIHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCxcbiAgICAgICAgICAgICAgdHJpZ2dlci5jbG9zZSxcbiAgICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIF90aW1lci51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgIGNhbmNlbERlbGF5ZWRUb29sdGlwU2hvd2luZygpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzaG93VG9vbHRpcCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgYW4gZWxlbWVudOKAmXMgdG9vbHRpcC4gVGhpcyBpcyBjb25zaWRlcmVkIGEg4oCcbWFudWFs4oCdIHRyaWdnZXJpbmcgb2ZcbiAgICogdGhlIHRvb2x0aXAuXG4gICAqL1xuICBoaWRlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9kZWxheVRpbWVvdXRJZCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX2RlbGF5VGltZW91dElkKTtcbiAgICAgIHRoaXMuX2RlbGF5VGltZW91dElkID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5fdG9vbHRpcC5pc1Nob3duKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fdG9vbHRpcC5pbnN0YW5jZS5jbGFzc01hcC5pbiA9IGZhbHNlO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5fdG9vbHRpcC5oaWRlKCk7XG4gICAgfSwgdGhpcy50b29sdGlwRmFkZUR1cmF0aW9uKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuX3Rvb2x0aXAuZGlzcG9zZSgpO1xuICB9XG59XG4iXX0=