tooltip.directive.js 33 KB

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