carousel.component.js 86 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240
  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
  7. /***
  8. * pause (not yet supported) (?string='hover') - event group name which pauses
  9. * the cycling of the carousel, if hover pauses on mouseenter and resumes on
  10. * mouseleave keyboard (not yet supported) (?boolean=true) - if false
  11. * carousel will not react to keyboard events
  12. * note: swiping not yet supported
  13. */
  14. /****
  15. * Problems:
  16. * 1) if we set an active slide via model changes, .active class remains on a
  17. * current slide.
  18. * 2) if we have only one slide, we shouldn't show prev/next nav buttons
  19. * 3) if first or last slide is active and noWrap is true, there should be
  20. * "disabled" class on the nav buttons.
  21. * 4) default interval should be equal 5000
  22. */
  23. import { Component, EventEmitter, Input, NgZone, Output } from '@angular/core';
  24. import { isBs3, LinkedList } from 'ngx-bootstrap/utils';
  25. import { CarouselConfig } from './carousel.config';
  26. import { findLastIndex, chunkByNumber } from './utils';
  27. /** @enum {number} */
  28. var Direction = {
  29. UNKNOWN: 0,
  30. NEXT: 1,
  31. PREV: 2,
  32. };
  33. export { Direction };
  34. Direction[Direction.UNKNOWN] = 'UNKNOWN';
  35. Direction[Direction.NEXT] = 'NEXT';
  36. Direction[Direction.PREV] = 'PREV';
  37. /**
  38. * Base element to create carousel
  39. */
  40. var CarouselComponent = /** @class */ (function () {
  41. function CarouselComponent(config, ngZone) {
  42. this.ngZone = ngZone;
  43. /* If `true` - carousel indicators indicate slides chunks
  44. works ONLY if singleSlideOffset = FALSE */
  45. this.indicatorsByChunk = false;
  46. /* If value more then 1 — carousel works in multilist mode */
  47. this.itemsPerSlide = 1;
  48. /* If `true` — carousel shifts by one element. By default carousel shifts by number
  49. of visible elements (itemsPerSlide field) */
  50. this.singleSlideOffset = false;
  51. /**
  52. * Will be emitted when active slide has been changed. Part of two-way-bindable [(activeSlide)] property
  53. */
  54. this.activeSlideChange = new EventEmitter(false);
  55. /**
  56. * Will be emitted when active slides has been changed in multilist mode
  57. */
  58. this.slideRangeChange = new EventEmitter();
  59. /* Index to start display slides from it */
  60. this.startFromIndex = 0;
  61. this._slides = new LinkedList();
  62. this._currentVisibleSlidesIndex = 0;
  63. this.destroyed = false;
  64. this.getActive = (/**
  65. * @param {?} slide
  66. * @return {?}
  67. */
  68. function (slide) { return slide.active; });
  69. this.makeSlidesConsistent = (/**
  70. * @param {?} slides
  71. * @return {?}
  72. */
  73. function (slides) {
  74. slides.forEach((/**
  75. * @param {?} slide
  76. * @param {?} index
  77. * @return {?}
  78. */
  79. function (slide, index) { return slide.item.order = index; }));
  80. });
  81. Object.assign(this, config);
  82. }
  83. Object.defineProperty(CarouselComponent.prototype, "activeSlide", {
  84. get: /**
  85. * @return {?}
  86. */
  87. function () {
  88. return this._currentActiveSlide;
  89. },
  90. /** Index of currently displayed slide(started for 0) */
  91. set: /**
  92. * Index of currently displayed slide(started for 0)
  93. * @param {?} index
  94. * @return {?}
  95. */
  96. function (index) {
  97. if (this.multilist) {
  98. return;
  99. }
  100. if (this._slides.length && index !== this._currentActiveSlide) {
  101. this._select(index);
  102. }
  103. },
  104. enumerable: true,
  105. configurable: true
  106. });
  107. Object.defineProperty(CarouselComponent.prototype, "interval", {
  108. /**
  109. * Delay of item cycling in milliseconds. If false, carousel won't cycle
  110. * automatically.
  111. */
  112. get: /**
  113. * Delay of item cycling in milliseconds. If false, carousel won't cycle
  114. * automatically.
  115. * @return {?}
  116. */
  117. function () {
  118. return this._interval;
  119. },
  120. set: /**
  121. * @param {?} value
  122. * @return {?}
  123. */
  124. function (value) {
  125. this._interval = value;
  126. this.restartTimer();
  127. },
  128. enumerable: true,
  129. configurable: true
  130. });
  131. Object.defineProperty(CarouselComponent.prototype, "slides", {
  132. get: /**
  133. * @return {?}
  134. */
  135. function () {
  136. return this._slides.toArray();
  137. },
  138. enumerable: true,
  139. configurable: true
  140. });
  141. Object.defineProperty(CarouselComponent.prototype, "isBs4", {
  142. get: /**
  143. * @return {?}
  144. */
  145. function () {
  146. return !isBs3();
  147. },
  148. enumerable: true,
  149. configurable: true
  150. });
  151. /**
  152. * @return {?}
  153. */
  154. CarouselComponent.prototype.ngAfterViewInit = /**
  155. * @return {?}
  156. */
  157. function () {
  158. var _this = this;
  159. setTimeout((/**
  160. * @return {?}
  161. */
  162. function () {
  163. if (_this.singleSlideOffset) {
  164. _this.indicatorsByChunk = false;
  165. }
  166. if (_this.multilist) {
  167. _this._chunkedSlides = chunkByNumber(_this.mapSlidesAndIndexes(), _this.itemsPerSlide);
  168. _this.selectInitialSlides();
  169. }
  170. }), 0);
  171. };
  172. /**
  173. * @return {?}
  174. */
  175. CarouselComponent.prototype.ngOnDestroy = /**
  176. * @return {?}
  177. */
  178. function () {
  179. this.destroyed = true;
  180. };
  181. /**
  182. * Adds new slide. If this slide is first in collection - set it as active
  183. * and starts auto changing
  184. * @param slide
  185. */
  186. /**
  187. * Adds new slide. If this slide is first in collection - set it as active
  188. * and starts auto changing
  189. * @param {?} slide
  190. * @return {?}
  191. */
  192. CarouselComponent.prototype.addSlide = /**
  193. * Adds new slide. If this slide is first in collection - set it as active
  194. * and starts auto changing
  195. * @param {?} slide
  196. * @return {?}
  197. */
  198. function (slide) {
  199. this._slides.add(slide);
  200. if (this.multilist && this._slides.length <= this.itemsPerSlide) {
  201. slide.active = true;
  202. }
  203. if (!this.multilist && this._slides.length === 1) {
  204. this._currentActiveSlide = undefined;
  205. this.activeSlide = 0;
  206. this.play();
  207. }
  208. if (this.multilist && this._slides.length > this.itemsPerSlide) {
  209. this.play();
  210. }
  211. };
  212. /**
  213. * Removes specified slide. If this slide is active - will roll to another
  214. * slide
  215. * @param slide
  216. */
  217. /**
  218. * Removes specified slide. If this slide is active - will roll to another
  219. * slide
  220. * @param {?} slide
  221. * @return {?}
  222. */
  223. CarouselComponent.prototype.removeSlide = /**
  224. * Removes specified slide. If this slide is active - will roll to another
  225. * slide
  226. * @param {?} slide
  227. * @return {?}
  228. */
  229. function (slide) {
  230. var _this = this;
  231. /** @type {?} */
  232. var remIndex = this._slides.indexOf(slide);
  233. if (this._currentActiveSlide === remIndex) {
  234. // removing of active slide
  235. /** @type {?} */
  236. var nextSlideIndex_1 = void 0;
  237. if (this._slides.length > 1) {
  238. // if this slide last - will roll to first slide, if noWrap flag is
  239. // FALSE or to previous, if noWrap is TRUE in case, if this slide in
  240. // middle of collection, index of next slide is same to removed
  241. nextSlideIndex_1 = !this.isLast(remIndex)
  242. ? remIndex
  243. : this.noWrap ? remIndex - 1 : 0;
  244. }
  245. this._slides.remove(remIndex);
  246. // prevents exception with changing some value after checking
  247. setTimeout((/**
  248. * @return {?}
  249. */
  250. function () {
  251. _this._select(nextSlideIndex_1);
  252. }), 0);
  253. }
  254. else {
  255. this._slides.remove(remIndex);
  256. /** @type {?} */
  257. var currentSlideIndex_1 = this.getCurrentSlideIndex();
  258. setTimeout((/**
  259. * @return {?}
  260. */
  261. function () {
  262. // after removing, need to actualize index of current active slide
  263. _this._currentActiveSlide = currentSlideIndex_1;
  264. _this.activeSlideChange.emit(_this._currentActiveSlide);
  265. }), 0);
  266. }
  267. };
  268. /**
  269. * @param {?=} force
  270. * @return {?}
  271. */
  272. CarouselComponent.prototype.nextSlideFromInterval = /**
  273. * @param {?=} force
  274. * @return {?}
  275. */
  276. function (force) {
  277. if (force === void 0) { force = false; }
  278. this.move(Direction.NEXT, force);
  279. };
  280. /**
  281. * Rolling to next slide
  282. * @param force: {boolean} if true - will ignore noWrap flag
  283. */
  284. /**
  285. * Rolling to next slide
  286. * @param {?=} force
  287. * @return {?}
  288. */
  289. CarouselComponent.prototype.nextSlide = /**
  290. * Rolling to next slide
  291. * @param {?=} force
  292. * @return {?}
  293. */
  294. function (force) {
  295. if (force === void 0) { force = false; }
  296. if (this.isPlaying) {
  297. this.restartTimer();
  298. }
  299. this.move(Direction.NEXT, force);
  300. };
  301. /**
  302. * Rolling to previous slide
  303. * @param force: {boolean} if true - will ignore noWrap flag
  304. */
  305. /**
  306. * Rolling to previous slide
  307. * @param {?=} force
  308. * @return {?}
  309. */
  310. CarouselComponent.prototype.previousSlide = /**
  311. * Rolling to previous slide
  312. * @param {?=} force
  313. * @return {?}
  314. */
  315. function (force) {
  316. if (force === void 0) { force = false; }
  317. if (this.isPlaying) {
  318. this.restartTimer();
  319. }
  320. this.move(Direction.PREV, force);
  321. };
  322. /**
  323. * @return {?}
  324. */
  325. CarouselComponent.prototype.getFirstVisibleIndex = /**
  326. * @return {?}
  327. */
  328. function () {
  329. return this.slides.findIndex(this.getActive);
  330. };
  331. /**
  332. * @return {?}
  333. */
  334. CarouselComponent.prototype.getLastVisibleIndex = /**
  335. * @return {?}
  336. */
  337. function () {
  338. return findLastIndex(this.slides, this.getActive);
  339. };
  340. /**
  341. * @param {?} direction
  342. * @param {?=} force
  343. * @return {?}
  344. */
  345. CarouselComponent.prototype.move = /**
  346. * @param {?} direction
  347. * @param {?=} force
  348. * @return {?}
  349. */
  350. function (direction, force) {
  351. if (force === void 0) { force = false; }
  352. /** @type {?} */
  353. var firstVisibleIndex = this.getFirstVisibleIndex();
  354. /** @type {?} */
  355. var lastVisibleIndex = this.getLastVisibleIndex();
  356. if (this.noWrap) {
  357. if (direction === Direction.NEXT &&
  358. this.isLast(lastVisibleIndex) ||
  359. direction === Direction.PREV &&
  360. firstVisibleIndex === 0) {
  361. return;
  362. }
  363. }
  364. if (!this.multilist) {
  365. this.activeSlide = this.findNextSlideIndex(direction, force);
  366. }
  367. else {
  368. this.moveMultilist(direction);
  369. }
  370. };
  371. /**
  372. * Swith slides by enter, space and arrows keys
  373. * @internal
  374. */
  375. /**
  376. * Swith slides by enter, space and arrows keys
  377. * \@internal
  378. * @param {?} event
  379. * @return {?}
  380. */
  381. CarouselComponent.prototype.keydownPress = /**
  382. * Swith slides by enter, space and arrows keys
  383. * \@internal
  384. * @param {?} event
  385. * @return {?}
  386. */
  387. function (event) {
  388. // tslint:disable-next-line:deprecation
  389. if (event.keyCode === 13 || event.key === 'Enter' || event.keyCode === 32 || event.key === 'Space') {
  390. this.nextSlide();
  391. event.preventDefault();
  392. return;
  393. }
  394. // tslint:disable-next-line:deprecation
  395. if (event.keyCode === 37 || event.key === 'LeftArrow') {
  396. this.previousSlide();
  397. return;
  398. }
  399. // tslint:disable-next-line:deprecation
  400. if (event.keyCode === 39 || event.key === 'RightArrow') {
  401. this.nextSlide();
  402. return;
  403. }
  404. };
  405. /**
  406. * Play on mouse leave
  407. * @internal
  408. */
  409. /**
  410. * Play on mouse leave
  411. * \@internal
  412. * @return {?}
  413. */
  414. CarouselComponent.prototype.onMouseLeave = /**
  415. * Play on mouse leave
  416. * \@internal
  417. * @return {?}
  418. */
  419. function () {
  420. if (!this.pauseOnFocus) {
  421. this.play();
  422. }
  423. };
  424. /**
  425. * Play on mouse up
  426. * @internal
  427. */
  428. /**
  429. * Play on mouse up
  430. * \@internal
  431. * @return {?}
  432. */
  433. CarouselComponent.prototype.onMouseUp = /**
  434. * Play on mouse up
  435. * \@internal
  436. * @return {?}
  437. */
  438. function () {
  439. if (!this.pauseOnFocus) {
  440. this.play();
  441. }
  442. };
  443. /**
  444. * When slides on focus autoplay is stopped(optional)
  445. * @internal
  446. */
  447. /**
  448. * When slides on focus autoplay is stopped(optional)
  449. * \@internal
  450. * @return {?}
  451. */
  452. CarouselComponent.prototype.pauseFocusIn = /**
  453. * When slides on focus autoplay is stopped(optional)
  454. * \@internal
  455. * @return {?}
  456. */
  457. function () {
  458. if (this.pauseOnFocus) {
  459. this.isPlaying = false;
  460. this.resetTimer();
  461. }
  462. };
  463. /**
  464. * When slides out of focus autoplay is started
  465. * @internal
  466. */
  467. /**
  468. * When slides out of focus autoplay is started
  469. * \@internal
  470. * @return {?}
  471. */
  472. CarouselComponent.prototype.pauseFocusOut = /**
  473. * When slides out of focus autoplay is started
  474. * \@internal
  475. * @return {?}
  476. */
  477. function () {
  478. this.play();
  479. };
  480. /**
  481. * Rolling to specified slide
  482. * @param index: {number} index of slide, which must be shown
  483. */
  484. /**
  485. * Rolling to specified slide
  486. * @param {?} index
  487. * @return {?}
  488. */
  489. CarouselComponent.prototype.selectSlide = /**
  490. * Rolling to specified slide
  491. * @param {?} index
  492. * @return {?}
  493. */
  494. function (index) {
  495. if (this.isPlaying) {
  496. this.restartTimer();
  497. }
  498. if (!this.multilist) {
  499. this.activeSlide = this.indicatorsByChunk ? index * this.itemsPerSlide : index;
  500. }
  501. else {
  502. this.selectSlideRange(this.indicatorsByChunk ? index * this.itemsPerSlide : index);
  503. }
  504. };
  505. /**
  506. * Starts a auto changing of slides
  507. */
  508. /**
  509. * Starts a auto changing of slides
  510. * @return {?}
  511. */
  512. CarouselComponent.prototype.play = /**
  513. * Starts a auto changing of slides
  514. * @return {?}
  515. */
  516. function () {
  517. if (!this.isPlaying) {
  518. this.isPlaying = true;
  519. this.restartTimer();
  520. }
  521. };
  522. /**
  523. * Stops a auto changing of slides
  524. */
  525. /**
  526. * Stops a auto changing of slides
  527. * @return {?}
  528. */
  529. CarouselComponent.prototype.pause = /**
  530. * Stops a auto changing of slides
  531. * @return {?}
  532. */
  533. function () {
  534. if (!this.noPause) {
  535. this.isPlaying = false;
  536. this.resetTimer();
  537. }
  538. };
  539. /**
  540. * Finds and returns index of currently displayed slide
  541. */
  542. /**
  543. * Finds and returns index of currently displayed slide
  544. * @return {?}
  545. */
  546. CarouselComponent.prototype.getCurrentSlideIndex = /**
  547. * Finds and returns index of currently displayed slide
  548. * @return {?}
  549. */
  550. function () {
  551. return this._slides.findIndex(this.getActive);
  552. };
  553. /**
  554. * Defines, whether the specified index is last in collection
  555. * @param index
  556. */
  557. /**
  558. * Defines, whether the specified index is last in collection
  559. * @param {?} index
  560. * @return {?}
  561. */
  562. CarouselComponent.prototype.isLast = /**
  563. * Defines, whether the specified index is last in collection
  564. * @param {?} index
  565. * @return {?}
  566. */
  567. function (index) {
  568. return index + 1 >= this._slides.length;
  569. };
  570. /**
  571. * Defines, whether the specified index is first in collection
  572. * @param index
  573. */
  574. /**
  575. * Defines, whether the specified index is first in collection
  576. * @param {?} index
  577. * @return {?}
  578. */
  579. CarouselComponent.prototype.isFirst = /**
  580. * Defines, whether the specified index is first in collection
  581. * @param {?} index
  582. * @return {?}
  583. */
  584. function (index) {
  585. return index === 0;
  586. };
  587. /**
  588. * @return {?}
  589. */
  590. CarouselComponent.prototype.indicatorsSlides = /**
  591. * @return {?}
  592. */
  593. function () {
  594. var _this = this;
  595. return this.slides.filter((/**
  596. * @param {?} slide
  597. * @param {?} index
  598. * @return {?}
  599. */
  600. function (slide, index) { return !_this.indicatorsByChunk || index % _this.itemsPerSlide === 0; }));
  601. };
  602. /**
  603. * @private
  604. * @return {?}
  605. */
  606. CarouselComponent.prototype.selectInitialSlides = /**
  607. * @private
  608. * @return {?}
  609. */
  610. function () {
  611. /** @type {?} */
  612. var startIndex = this.startFromIndex <= this._slides.length
  613. ? this.startFromIndex
  614. : 0;
  615. this.hideSlides();
  616. if (this.singleSlideOffset) {
  617. this._slidesWithIndexes = this.mapSlidesAndIndexes();
  618. if (this._slides.length - startIndex < this.itemsPerSlide) {
  619. /** @type {?} */
  620. var slidesToAppend = this._slidesWithIndexes.slice(0, startIndex);
  621. this._slidesWithIndexes = tslib_1.__spread(this._slidesWithIndexes, slidesToAppend).slice(slidesToAppend.length)
  622. .slice(0, this.itemsPerSlide);
  623. }
  624. else {
  625. this._slidesWithIndexes = this._slidesWithIndexes.slice(startIndex, startIndex + this.itemsPerSlide);
  626. }
  627. this._slidesWithIndexes.forEach((/**
  628. * @param {?} slide
  629. * @return {?}
  630. */
  631. function (slide) { return slide.item.active = true; }));
  632. this.makeSlidesConsistent(this._slidesWithIndexes);
  633. }
  634. else {
  635. this.selectRangeByNestedIndex(startIndex);
  636. }
  637. this.slideRangeChange.emit(this.getVisibleIndexes());
  638. };
  639. /**
  640. * Defines next slide index, depending of direction
  641. * @param direction: Direction(UNKNOWN|PREV|NEXT)
  642. * @param force: {boolean} if TRUE - will ignore noWrap flag, else will
  643. * return undefined if next slide require wrapping
  644. */
  645. /**
  646. * Defines next slide index, depending of direction
  647. * @private
  648. * @param {?} direction
  649. * @param {?} force
  650. * @return {?}
  651. */
  652. CarouselComponent.prototype.findNextSlideIndex = /**
  653. * Defines next slide index, depending of direction
  654. * @private
  655. * @param {?} direction
  656. * @param {?} force
  657. * @return {?}
  658. */
  659. function (direction, force) {
  660. /** @type {?} */
  661. var nextSlideIndex = 0;
  662. if (!force &&
  663. (this.isLast(this.activeSlide) &&
  664. direction !== Direction.PREV &&
  665. this.noWrap)) {
  666. return undefined;
  667. }
  668. switch (direction) {
  669. case Direction.NEXT:
  670. // if this is last slide, not force, looping is disabled
  671. // and need to going forward - select current slide, as a next
  672. nextSlideIndex = !this.isLast(this._currentActiveSlide)
  673. ? this._currentActiveSlide + 1
  674. : !force && this.noWrap ? this._currentActiveSlide : 0;
  675. break;
  676. case Direction.PREV:
  677. // if this is first slide, not force, looping is disabled
  678. // and need to going backward - select current slide, as a next
  679. nextSlideIndex =
  680. this._currentActiveSlide > 0
  681. ? this._currentActiveSlide - 1
  682. : !force && this.noWrap
  683. ? this._currentActiveSlide
  684. : this._slides.length - 1;
  685. break;
  686. default:
  687. throw new Error('Unknown direction');
  688. }
  689. return nextSlideIndex;
  690. };
  691. /**
  692. * @private
  693. * @return {?}
  694. */
  695. CarouselComponent.prototype.mapSlidesAndIndexes = /**
  696. * @private
  697. * @return {?}
  698. */
  699. function () {
  700. return this.slides
  701. .slice()
  702. .map((/**
  703. * @param {?} slide
  704. * @param {?} index
  705. * @return {?}
  706. */
  707. function (slide, index) {
  708. return {
  709. index: index,
  710. item: slide
  711. };
  712. }));
  713. };
  714. /**
  715. * @private
  716. * @param {?} index
  717. * @return {?}
  718. */
  719. CarouselComponent.prototype.selectSlideRange = /**
  720. * @private
  721. * @param {?} index
  722. * @return {?}
  723. */
  724. function (index) {
  725. if (this.isIndexInRange(index)) {
  726. return;
  727. }
  728. this.hideSlides();
  729. if (!this.singleSlideOffset) {
  730. this.selectRangeByNestedIndex(index);
  731. }
  732. else {
  733. /** @type {?} */
  734. var startIndex = this.isIndexOnTheEdges(index)
  735. ? index
  736. : index - this.itemsPerSlide + 1;
  737. /** @type {?} */
  738. var endIndex = this.isIndexOnTheEdges(index)
  739. ? index + this.itemsPerSlide
  740. : index + 1;
  741. this._slidesWithIndexes = this.mapSlidesAndIndexes().slice(startIndex, endIndex);
  742. this.makeSlidesConsistent(this._slidesWithIndexes);
  743. this._slidesWithIndexes.forEach((/**
  744. * @param {?} slide
  745. * @return {?}
  746. */
  747. function (slide) { return slide.item.active = true; }));
  748. }
  749. this.slideRangeChange.emit(this.getVisibleIndexes());
  750. };
  751. /**
  752. * @private
  753. * @param {?} index
  754. * @return {?}
  755. */
  756. CarouselComponent.prototype.selectRangeByNestedIndex = /**
  757. * @private
  758. * @param {?} index
  759. * @return {?}
  760. */
  761. function (index) {
  762. /** @type {?} */
  763. var selectedRange = this._chunkedSlides
  764. .map((/**
  765. * @param {?} slidesList
  766. * @param {?} i
  767. * @return {?}
  768. */
  769. function (slidesList, i) {
  770. return {
  771. index: i,
  772. list: slidesList
  773. };
  774. }))
  775. .find((/**
  776. * @param {?} slidesList
  777. * @return {?}
  778. */
  779. function (slidesList) {
  780. return slidesList.list.find((/**
  781. * @param {?} slide
  782. * @return {?}
  783. */
  784. function (slide) { return slide.index === index; })) !== undefined;
  785. }));
  786. this._currentVisibleSlidesIndex = selectedRange.index;
  787. this._chunkedSlides[selectedRange.index].forEach((/**
  788. * @param {?} slide
  789. * @return {?}
  790. */
  791. function (slide) {
  792. slide.item.active = true;
  793. }));
  794. };
  795. /**
  796. * @private
  797. * @param {?} index
  798. * @return {?}
  799. */
  800. CarouselComponent.prototype.isIndexOnTheEdges = /**
  801. * @private
  802. * @param {?} index
  803. * @return {?}
  804. */
  805. function (index) {
  806. return (index + 1 - this.itemsPerSlide <= 0 ||
  807. index + this.itemsPerSlide <= this._slides.length);
  808. };
  809. /**
  810. * @private
  811. * @param {?} index
  812. * @return {?}
  813. */
  814. CarouselComponent.prototype.isIndexInRange = /**
  815. * @private
  816. * @param {?} index
  817. * @return {?}
  818. */
  819. function (index) {
  820. if (this.singleSlideOffset) {
  821. /** @type {?} */
  822. var visibleIndexes = this._slidesWithIndexes.map((/**
  823. * @param {?} slide
  824. * @return {?}
  825. */
  826. function (slide) { return slide.index; }));
  827. return visibleIndexes.indexOf(index) >= 0;
  828. }
  829. return (index <= this.getLastVisibleIndex() &&
  830. index >= this.getFirstVisibleIndex());
  831. };
  832. /**
  833. * @private
  834. * @return {?}
  835. */
  836. CarouselComponent.prototype.hideSlides = /**
  837. * @private
  838. * @return {?}
  839. */
  840. function () {
  841. this.slides.forEach((/**
  842. * @param {?} slide
  843. * @return {?}
  844. */
  845. function (slide) { return slide.active = false; }));
  846. };
  847. /**
  848. * @private
  849. * @return {?}
  850. */
  851. CarouselComponent.prototype.isVisibleSlideListLast = /**
  852. * @private
  853. * @return {?}
  854. */
  855. function () {
  856. return this._currentVisibleSlidesIndex === this._chunkedSlides.length - 1;
  857. };
  858. /**
  859. * @private
  860. * @return {?}
  861. */
  862. CarouselComponent.prototype.isVisibleSlideListFirst = /**
  863. * @private
  864. * @return {?}
  865. */
  866. function () {
  867. return this._currentVisibleSlidesIndex === 0;
  868. };
  869. /**
  870. * @private
  871. * @param {?} direction
  872. * @return {?}
  873. */
  874. CarouselComponent.prototype.moveSliderByOneItem = /**
  875. * @private
  876. * @param {?} direction
  877. * @return {?}
  878. */
  879. function (direction) {
  880. /** @type {?} */
  881. var firstVisibleIndex;
  882. /** @type {?} */
  883. var lastVisibleIndex;
  884. /** @type {?} */
  885. var indexToHide;
  886. /** @type {?} */
  887. var indexToShow;
  888. if (this.noWrap) {
  889. firstVisibleIndex = this.getFirstVisibleIndex();
  890. lastVisibleIndex = this.getLastVisibleIndex();
  891. indexToHide = direction === Direction.NEXT
  892. ? firstVisibleIndex
  893. : lastVisibleIndex;
  894. indexToShow = direction !== Direction.NEXT
  895. ? firstVisibleIndex - 1
  896. : !this.isLast(lastVisibleIndex)
  897. ? lastVisibleIndex + 1 : 0;
  898. this._slides.get(indexToHide).active = false;
  899. this._slides.get(indexToShow).active = true;
  900. /** @type {?} */
  901. var slidesToReorder = this.mapSlidesAndIndexes().filter((/**
  902. * @param {?} slide
  903. * @return {?}
  904. */
  905. function (slide) { return slide.item.active; }));
  906. this.makeSlidesConsistent(slidesToReorder);
  907. this.slideRangeChange.emit(this.getVisibleIndexes());
  908. }
  909. else {
  910. /** @type {?} */
  911. var displayedIndex = void 0;
  912. firstVisibleIndex = this._slidesWithIndexes[0].index;
  913. lastVisibleIndex = this._slidesWithIndexes[this._slidesWithIndexes.length - 1].index;
  914. if (direction === Direction.NEXT) {
  915. this._slidesWithIndexes.shift();
  916. displayedIndex = this.isLast(lastVisibleIndex)
  917. ? 0
  918. : lastVisibleIndex + 1;
  919. this._slidesWithIndexes.push({
  920. index: displayedIndex,
  921. item: this._slides.get(displayedIndex)
  922. });
  923. }
  924. else {
  925. this._slidesWithIndexes.pop();
  926. displayedIndex = this.isFirst(firstVisibleIndex)
  927. ? this._slides.length - 1
  928. : firstVisibleIndex - 1;
  929. this._slidesWithIndexes = tslib_1.__spread([{
  930. index: displayedIndex,
  931. item: this._slides.get(displayedIndex)
  932. }], this._slidesWithIndexes);
  933. }
  934. this.hideSlides();
  935. this._slidesWithIndexes.forEach((/**
  936. * @param {?} slide
  937. * @return {?}
  938. */
  939. function (slide) { return slide.item.active = true; }));
  940. this.makeSlidesConsistent(this._slidesWithIndexes);
  941. this.slideRangeChange.emit(this._slidesWithIndexes.map((/**
  942. * @param {?} slide
  943. * @return {?}
  944. */
  945. function (slide) { return slide.index; })));
  946. }
  947. };
  948. /**
  949. * @private
  950. * @param {?} direction
  951. * @return {?}
  952. */
  953. CarouselComponent.prototype.moveMultilist = /**
  954. * @private
  955. * @param {?} direction
  956. * @return {?}
  957. */
  958. function (direction) {
  959. if (this.singleSlideOffset) {
  960. this.moveSliderByOneItem(direction);
  961. }
  962. else {
  963. this.hideSlides();
  964. if (this.noWrap) {
  965. this._currentVisibleSlidesIndex = direction === Direction.NEXT
  966. ? this._currentVisibleSlidesIndex + 1
  967. : this._currentVisibleSlidesIndex - 1;
  968. }
  969. else {
  970. if (direction === Direction.NEXT) {
  971. this._currentVisibleSlidesIndex = this.isVisibleSlideListLast()
  972. ? 0
  973. : this._currentVisibleSlidesIndex + 1;
  974. }
  975. else {
  976. this._currentVisibleSlidesIndex = this.isVisibleSlideListFirst()
  977. ? this._chunkedSlides.length - 1
  978. : this._currentVisibleSlidesIndex - 1;
  979. }
  980. }
  981. this._chunkedSlides[this._currentVisibleSlidesIndex].forEach((/**
  982. * @param {?} slide
  983. * @return {?}
  984. */
  985. function (slide) { return slide.item.active = true; }));
  986. this.slideRangeChange.emit(this.getVisibleIndexes());
  987. }
  988. };
  989. /**
  990. * @private
  991. * @return {?}
  992. */
  993. CarouselComponent.prototype.getVisibleIndexes = /**
  994. * @private
  995. * @return {?}
  996. */
  997. function () {
  998. if (!this.singleSlideOffset) {
  999. return this._chunkedSlides[this._currentVisibleSlidesIndex]
  1000. .map((/**
  1001. * @param {?} slide
  1002. * @return {?}
  1003. */
  1004. function (slide) { return slide.index; }));
  1005. }
  1006. else {
  1007. return this._slidesWithIndexes.map((/**
  1008. * @param {?} slide
  1009. * @return {?}
  1010. */
  1011. function (slide) { return slide.index; }));
  1012. }
  1013. };
  1014. /**
  1015. * Sets a slide, which specified through index, as active
  1016. * @param index
  1017. */
  1018. /**
  1019. * Sets a slide, which specified through index, as active
  1020. * @private
  1021. * @param {?} index
  1022. * @return {?}
  1023. */
  1024. CarouselComponent.prototype._select = /**
  1025. * Sets a slide, which specified through index, as active
  1026. * @private
  1027. * @param {?} index
  1028. * @return {?}
  1029. */
  1030. function (index) {
  1031. if (isNaN(index)) {
  1032. this.pause();
  1033. return;
  1034. }
  1035. if (!this.multilist) {
  1036. /** @type {?} */
  1037. var currentSlide = this._slides.get(this._currentActiveSlide);
  1038. if (currentSlide) {
  1039. currentSlide.active = false;
  1040. }
  1041. }
  1042. /** @type {?} */
  1043. var nextSlide = this._slides.get(index);
  1044. if (nextSlide) {
  1045. this._currentActiveSlide = index;
  1046. nextSlide.active = true;
  1047. this.activeSlide = index;
  1048. this.activeSlideChange.emit(index);
  1049. }
  1050. };
  1051. /**
  1052. * Starts loop of auto changing of slides
  1053. */
  1054. /**
  1055. * Starts loop of auto changing of slides
  1056. * @private
  1057. * @return {?}
  1058. */
  1059. CarouselComponent.prototype.restartTimer = /**
  1060. * Starts loop of auto changing of slides
  1061. * @private
  1062. * @return {?}
  1063. */
  1064. function () {
  1065. var _this = this;
  1066. this.resetTimer();
  1067. /** @type {?} */
  1068. var interval = +this.interval;
  1069. if (!isNaN(interval) && interval > 0) {
  1070. this.currentInterval = this.ngZone.runOutsideAngular((/**
  1071. * @return {?}
  1072. */
  1073. function () {
  1074. return setInterval((/**
  1075. * @return {?}
  1076. */
  1077. function () {
  1078. /** @type {?} */
  1079. var nInterval = +_this.interval;
  1080. _this.ngZone.run((/**
  1081. * @return {?}
  1082. */
  1083. function () {
  1084. if (_this.isPlaying &&
  1085. !isNaN(_this.interval) &&
  1086. nInterval > 0 &&
  1087. _this.slides.length) {
  1088. _this.nextSlideFromInterval();
  1089. }
  1090. else {
  1091. _this.pause();
  1092. }
  1093. }));
  1094. }), interval);
  1095. }));
  1096. }
  1097. };
  1098. Object.defineProperty(CarouselComponent.prototype, "multilist", {
  1099. get: /**
  1100. * @return {?}
  1101. */
  1102. function () {
  1103. return this.itemsPerSlide > 1;
  1104. },
  1105. enumerable: true,
  1106. configurable: true
  1107. });
  1108. /**
  1109. * Stops loop of auto changing of slides
  1110. */
  1111. /**
  1112. * Stops loop of auto changing of slides
  1113. * @private
  1114. * @return {?}
  1115. */
  1116. CarouselComponent.prototype.resetTimer = /**
  1117. * Stops loop of auto changing of slides
  1118. * @private
  1119. * @return {?}
  1120. */
  1121. function () {
  1122. if (this.currentInterval) {
  1123. clearInterval(this.currentInterval);
  1124. this.currentInterval = void 0;
  1125. }
  1126. };
  1127. CarouselComponent.decorators = [
  1128. { type: Component, args: [{
  1129. selector: 'carousel',
  1130. template: "<div (mouseenter)=\"pause()\" (mouseleave)=\"onMouseLeave()\" (mouseup)=\"onMouseUp()\" class=\"carousel slide\" (keydown)=\"keydownPress($event)\" (focusin)=\"pauseFocusIn()\" (focusout)=\"pauseFocusOut()\" tabindex=\"0\">\n <ol class=\"carousel-indicators\" *ngIf=\"showIndicators && slides.length > 1\">\n <li *ngFor=\"let slidez of indicatorsSlides(); let i = index;\" [class.active]=\"slidez.active === true\" (click)=\"selectSlide(i)\"></li>\n </ol>\n <div class=\"carousel-inner\" [ngStyle]=\"{'display': multilist ? 'flex' : 'block'}\"><ng-content></ng-content></div>\n <a class=\"left carousel-control carousel-control-prev\" [class.disabled]=\"activeSlide === 0 && noWrap\" (click)=\"previousSlide()\" *ngIf=\"slides.length > 1\"\n tabindex=\"0\" role=\"button\">\n <span class=\"icon-prev carousel-control-prev-icon\" aria-hidden=\"true\"></span>\n <span *ngIf=\"isBs4\" class=\"sr-only\">Previous</span>\n </a>\n <a class=\"right carousel-control carousel-control-next\" (click)=\"nextSlide()\" [class.disabled]=\"isLast(activeSlide) && noWrap\" *ngIf=\"slides.length > 1\"\n tabindex=\"0\" role=\"button\">\n <span class=\"icon-next carousel-control-next-icon\" aria-hidden=\"true\"></span>\n <span class=\"sr-only\">Next</span>\n </a>\n</div>\n"
  1131. }] }
  1132. ];
  1133. /** @nocollapse */
  1134. CarouselComponent.ctorParameters = function () { return [
  1135. { type: CarouselConfig },
  1136. { type: NgZone }
  1137. ]; };
  1138. CarouselComponent.propDecorators = {
  1139. noWrap: [{ type: Input }],
  1140. noPause: [{ type: Input }],
  1141. showIndicators: [{ type: Input }],
  1142. pauseOnFocus: [{ type: Input }],
  1143. indicatorsByChunk: [{ type: Input }],
  1144. itemsPerSlide: [{ type: Input }],
  1145. singleSlideOffset: [{ type: Input }],
  1146. activeSlideChange: [{ type: Output }],
  1147. slideRangeChange: [{ type: Output }],
  1148. activeSlide: [{ type: Input }],
  1149. startFromIndex: [{ type: Input }],
  1150. interval: [{ type: Input }]
  1151. };
  1152. return CarouselComponent;
  1153. }());
  1154. export { CarouselComponent };
  1155. if (false) {
  1156. /** @type {?} */
  1157. CarouselComponent.prototype.noWrap;
  1158. /** @type {?} */
  1159. CarouselComponent.prototype.noPause;
  1160. /** @type {?} */
  1161. CarouselComponent.prototype.showIndicators;
  1162. /** @type {?} */
  1163. CarouselComponent.prototype.pauseOnFocus;
  1164. /** @type {?} */
  1165. CarouselComponent.prototype.indicatorsByChunk;
  1166. /** @type {?} */
  1167. CarouselComponent.prototype.itemsPerSlide;
  1168. /** @type {?} */
  1169. CarouselComponent.prototype.singleSlideOffset;
  1170. /**
  1171. * Will be emitted when active slide has been changed. Part of two-way-bindable [(activeSlide)] property
  1172. * @type {?}
  1173. */
  1174. CarouselComponent.prototype.activeSlideChange;
  1175. /**
  1176. * Will be emitted when active slides has been changed in multilist mode
  1177. * @type {?}
  1178. */
  1179. CarouselComponent.prototype.slideRangeChange;
  1180. /** @type {?} */
  1181. CarouselComponent.prototype.startFromIndex;
  1182. /**
  1183. * @type {?}
  1184. * @protected
  1185. */
  1186. CarouselComponent.prototype.currentInterval;
  1187. /**
  1188. * @type {?}
  1189. * @protected
  1190. */
  1191. CarouselComponent.prototype._currentActiveSlide;
  1192. /**
  1193. * @type {?}
  1194. * @protected
  1195. */
  1196. CarouselComponent.prototype._interval;
  1197. /**
  1198. * @type {?}
  1199. * @protected
  1200. */
  1201. CarouselComponent.prototype._slides;
  1202. /**
  1203. * @type {?}
  1204. * @protected
  1205. */
  1206. CarouselComponent.prototype._chunkedSlides;
  1207. /**
  1208. * @type {?}
  1209. * @protected
  1210. */
  1211. CarouselComponent.prototype._slidesWithIndexes;
  1212. /**
  1213. * @type {?}
  1214. * @protected
  1215. */
  1216. CarouselComponent.prototype._currentVisibleSlidesIndex;
  1217. /**
  1218. * @type {?}
  1219. * @protected
  1220. */
  1221. CarouselComponent.prototype.isPlaying;
  1222. /**
  1223. * @type {?}
  1224. * @protected
  1225. */
  1226. CarouselComponent.prototype.destroyed;
  1227. /** @type {?} */
  1228. CarouselComponent.prototype.getActive;
  1229. /**
  1230. * @type {?}
  1231. * @private
  1232. */
  1233. CarouselComponent.prototype.makeSlidesConsistent;
  1234. /**
  1235. * @type {?}
  1236. * @private
  1237. */
  1238. CarouselComponent.prototype.ngZone;
  1239. }
  1240. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWJvb3RzdHJhcC9jYXJvdXNlbC8iLCJzb3VyY2VzIjpbImNhcm91c2VsLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBa0JBLE9BQU8sRUFDTCxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQWEsTUFBTSxFQUMxRCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXhELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxNQUFNLFNBQVMsQ0FBQzs7O0lBSXJELFVBQU87SUFDUCxPQUFJO0lBQ0osT0FBSTs7Ozs7Ozs7O0FBTU47SUFrRkUsMkJBQVksTUFBc0IsRUFBVSxNQUFjO1FBQWQsV0FBTSxHQUFOLE1BQU0sQ0FBUTs7O1FBbkVqRCxzQkFBaUIsR0FBRyxLQUFLLENBQUM7O1FBRTFCLGtCQUFhLEdBQUcsQ0FBQyxDQUFDOzs7UUFHbEIsc0JBQWlCLEdBQUcsS0FBSyxDQUFDOzs7O1FBSW5DLHNCQUFpQixHQUF5QixJQUFJLFlBQVksQ0FBUyxLQUFLLENBQUMsQ0FBQzs7OztRQUkxRSxxQkFBZ0IsR0FBMkIsSUFBSSxZQUFZLEVBQVksQ0FBQzs7UUFtQnhFLG1CQUFjLEdBQUcsQ0FBQyxDQUFDO1FBd0JULFlBQU8sR0FBK0IsSUFBSSxVQUFVLEVBQWtCLENBQUM7UUFHdkUsK0JBQTBCLEdBQUcsQ0FBQyxDQUFDO1FBRS9CLGNBQVMsR0FBRyxLQUFLLENBQUM7UUEwSDVCLGNBQVM7Ozs7UUFBRyxVQUFDLEtBQXFCLElBQUssT0FBQSxLQUFLLENBQUMsTUFBTSxFQUFaLENBQVksRUFBQztRQTRZNUMseUJBQW9COzs7O1FBQUcsVUFBQyxN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O2dCQWhCUSxjQUFjO2dCQUxXLE1BQU07Ozt5QkF3QnJDLEtBQUs7MEJBRUwsS0FBSztpQ0FFTCxLQUFLOytCQUVMLEtBQUs7b0NBR0wsS0FBSztnQ0FFTCxLQUFLO29DQUdMLEtBQUs7b0NBR0wsTUFBTTttQ0FJTixNQUFNOzhCQUlOLEtBQUs7aUNBZUwsS0FBSzsyQkFPTCxLQUFLOztJQTJvQlIsd0JBQUM7Q0FBQSxBQWhzQkQsSUFnc0JDO1NBNXJCWSxpQkFBaUI7OztJQUU1QixtQ0FBeUI7O0lBRXpCLG9DQUEwQjs7SUFFMUIsMkNBQWlDOztJQUVqQyx5Q0FBK0I7O0lBRy9CLDhDQUFtQzs7SUFFbkMsMENBQTJCOztJQUczQiw4Q0FBbUM7Ozs7O0lBR25DLDhDQUMwRTs7Ozs7SUFHMUUsNkNBQ3dFOztJQWtCeEUsMkNBQ21COzs7OztJQXFCbkIsNENBQStCOzs7OztJQUMvQixnREFBc0M7Ozs7O0lBQ3RDLHNDQUE0Qjs7Ozs7SUFDNUIsb0NBQWlGOzs7OztJQUNqRiwyQ0FBNkM7Ozs7O0lBQzdDLCtDQUErQzs7Ozs7SUFDL0MsdURBQXlDOzs7OztJQUN6QyxzQ0FBNkI7Ozs7O0lBQzdCLHNDQUE0Qjs7SUEwSDVCLHNDQUFvRDs7Ozs7SUE0WXBELGlEQUVDOzs7OztJQWxnQm1DLG1DQUFzQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIHRzbGludDpkaXNhYmxlOm1heC1maWxlLWxpbmUtY291bnRcbi8qKipcbiAqIHBhdXNlIChub3QgeWV0IHN1cHBvcnRlZCkgKD9zdHJpbmc9J2hvdmVyJykgLSBldmVudCBncm91cCBuYW1lIHdoaWNoIHBhdXNlc1xuICogdGhlIGN5Y2xpbmcgb2YgdGhlIGNhcm91c2VsLCBpZiBob3ZlciBwYXVzZXMgb24gbW91c2VlbnRlciBhbmQgcmVzdW1lcyBvblxuICogbW91c2VsZWF2ZSBrZXlib2FyZCAobm90IHlldCBzdXBwb3J0ZWQpICg/Ym9vbGVhbj10cnVlKSAtIGlmIGZhbHNlXG4gKiBjYXJvdXNlbCB3aWxsIG5vdCByZWFjdCB0byBrZXlib2FyZCBldmVudHNcbiAqIG5vdGU6IHN3aXBpbmcgbm90IHlldCBzdXBwb3J0ZWRcbiAqL1xuLyoqKipcbiAqIFByb2JsZW1zOlxuICogMSkgaWYgd2Ugc2V0IGFuIGFjdGl2ZSBzbGlkZSB2aWEgbW9kZWwgY2hhbmdlcywgLmFjdGl2ZSBjbGFzcyByZW1haW5zIG9uIGFcbiAqIGN1cnJlbnQgc2xpZGUuXG4gKiAyKSBpZiB3ZSBoYXZlIG9ubHkgb25lIHNsaWRlLCB3ZSBzaG91bGRuJ3Qgc2hvdyBwcmV2L25leHQgbmF2IGJ1dHRvbnNcbiAqIDMpIGlmIGZpcnN0IG9yIGxhc3Qgc2xpZGUgaXMgYWN0aXZlIGFuZCBub1dyYXAgaXMgdHJ1ZSwgdGhlcmUgc2hvdWxkIGJlXG4gKiBcImRpc2FibGVkXCIgY2xhc3Mgb24gdGhlIG5hdiBidXR0b25zLlxuICogNCkgZGVmYXVsdCBpbnRlcnZhbCBzaG91bGQgYmUgZXF1YWwgNTAwMFxuICovXG5cbmltcG9ydCB7XG4gIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgTmdab25lLCBPbkRlc3Ryb3ksIE91dHB1dCwgQWZ0ZXJWaWV3SW5pdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgaXNCczMsIExpbmtlZExpc3QgfSBmcm9tICduZ3gtYm9vdHN0cmFwL3V0aWxzJztcbmltcG9ydCB7IFNsaWRlQ29tcG9uZW50IH0gZnJvbSAnLi9zbGlkZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ2Fyb3VzZWxDb25maWcgfSBmcm9tICcuL2Nhcm91c2VsLmNvbmZpZyc7XG5pbXBvcnQgeyBmaW5kTGFzdEluZGV4LCBjaHVua0J5TnVtYmVyIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBTbGlkZVdpdGhJbmRleCwgSW5kZXhlZFNsaWRlTGlzdCB9IGZyb20gJy4vbW9kZWxzJztcblxuZXhwb3J0IGVudW0gRGlyZWN0aW9uIHtcbiAgVU5LTk9XTixcbiAgTkVYVCxcbiAgUFJFVlxufVxuXG4vKipcbiAqIEJhc2UgZWxlbWVudCB0byBjcmVhdGUgY2Fyb3VzZWxcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY2Fyb3VzZWwnLFxuICB0ZW1wbGF0ZVVybDogJy4vY2Fyb3VzZWwuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIENhcm91c2VsQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgLyogSWYgYHRydWVgIOKAlCBjYXJvdXNlbCB3aWxsIG5vdCBjeWNsZSBjb250aW51b3VzbHkgYW5kIHdpbGwgaGF2ZSBoYXJkIHN0b3BzIChwcmV2ZW50IGxvb3BpbmcpICovXG4gIEBJbnB1dCgpIG5vV3JhcDogYm9vbGVhbjtcbiAgLyogIElmIGB0cnVlYCDigJQgd2lsbCBkaXNhYmxlIHBhdXNpbmcgb24gY2Fyb3VzZWwgbW91c2UgaG92ZXIgKi9cbiAgQElucHV0KCkgbm9QYXVzZTogYm9vbGVhbjtcbiAgLyogIElmIGB0cnVlYCDigJQgY2Fyb3VzZWwtaW5kaWNhdG9ycyBhcmUgdmlzaWJsZSAgKi9cbiAgQElucHV0KCkgc2hvd0luZGljYXRvcnM6IGJvb2xlYW47XG4gIC8qICBJZiBgdHJ1ZWAgLSBhdXRvcGxheSB3aWxsIGJlIHN0b3BwZWQgb24gZm9jdXMgKi9cbiAgQElucHV0KCkgcGF1c2VPbkZvY3VzOiBib29sZWFuO1xuICAvKiBJZiBgdHJ1ZWAgLSBjYXJvdXNlbCBpbmRpY2F0b3JzIGluZGljYXRlIHNsaWRlcyBjaHVua3NcbiAgICAgd29ya3MgT05MWSBpZiBzaW5nbGVTbGlkZU9mZnNldCA9IEZBTFNFICovXG4gIEBJbnB1dCgpIGluZGljYXRvcnNCeUNodW5rID0gZmFsc2U7XG4gIC8qIElmIHZhbHVlIG1vcmUgdGhlbiAxIOKAlCBjYXJvdXNlbCB3b3JrcyBpbiBtdWx0aWxpc3QgbW9kZSAqL1xuICBASW5wdXQoKSBpdGVtc1BlclNsaWRlID0gMTtcbiAgLyogSWYgYHRydWVgIOKAlCBjYXJvdXNlbCBzaGlmdHMgYnkgb25lIGVsZW1lbnQuIEJ5IGRlZmF1bHQgY2Fyb3VzZWwgc2hpZnRzIGJ5IG51bWJlclxuICAgICBvZiB2aXNpYmxlIGVsZW1lbnRzIChpdGVtc1BlclNsaWRlIGZpZWxkKSAqL1xuICBASW5wdXQoKSBzaW5nbGVTbGlkZU9mZnNldCA9IGZhbHNlO1xuXG4gIC8qKiBXaWxsIGJlIGVtaXR0ZWQgd2hlbiBhY3RpdmUgc2xpZGUgaGFzIGJlZW4gY2hhbmdlZC4gUGFydCBvZiB0d28td2F5LWJpbmRhYmxlIFsoYWN0aXZlU2xpZGUpXSBwcm9wZXJ0eSAqL1xuICBAT3V0cHV0KClcbiAgYWN0aXZlU2xpZGVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KGZhbHNlKTtcblxuICAvKiogV2lsbCBiZSBlbWl0dGVkIHdoZW4gYWN0aXZlIHNsaWRlcyBoYXMgYmVlbiBjaGFuZ2VkIGluIG11bHRpbGlzdCBtb2RlICovXG4gIEBPdXRwdXQoKVxuICBzbGlkZVJhbmdlQ2hhbmdlOiBFdmVudEVtaXR0ZXI8bnVtYmVyW10+ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXJbXT4oKTtcblxuICAvKiogSW5kZXggb2YgY3VycmVudGx5IGRpc3BsYXllZCBzbGlkZShzdGFydGVkIGZvciAwKSAqL1xuICBASW5wdXQoKVxuICBzZXQgYWN0aXZlU2xpZGUoaW5kZXg6IG51bWJlcikge1xuICAgIGlmICh0aGlzLm11bHRpbGlzdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5fc2xpZGVzLmxlbmd0aCAmJiBpbmRleCAhPT0gdGhpcy5fY3VycmVudEFjdGl2ZVNsaWRlKSB7XG4gICAgICB0aGlzLl9zZWxlY3QoaW5kZXgpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBhY3RpdmVTbGlkZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9jdXJyZW50QWN0aXZlU2xpZGU7XG4gIH1cblxuICAvKiBJbmRleCB0byBzdGFydCBkaXNwbGF5IHNsaWRlcyBmcm9tIGl0ICovXG4gIEBJbnB1dCgpXG4gIHN0YXJ0RnJvbUluZGV4ID0gMDtcblxuICAvKipcbiAgICogRGVsYXkgb2YgaXRlbSBjeWNsaW5nIGluIG1pbGxpc2Vjb25kcy4gSWYgZmFsc2UsIGNhcm91c2VsIHdvbid0IGN5Y2xlXG4gICAqIGF1dG9tYXRpY2FsbHkuXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgaW50ZXJ2YWwoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5faW50ZXJ2YWw7XG4gIH1cblxuICBzZXQgaW50ZXJ2YWwodmFsdWU6IG51bWJlcikge1xuICAgIHRoaXMuX2ludGVydmFsID0gdmFsdWU7XG4gICAgdGhpcy5yZXN0YXJ0VGltZXIoKTtcbiAgfVxuXG4gIGdldCBzbGlkZXMoKTogU2xpZGVDb21wb25lbnRbXSB7XG4gICAgcmV0dXJuIHRoaXMuX3NsaWRlcy50b0FycmF5KCk7XG4gIH1cblxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gIHByb3RlY3RlZCBjdXJyZW50SW50ZXJ2YWw6IGFueTtcbiAgcHJvdGVjdGVkIF9jdXJyZW50QWN0aXZlU2xpZGU6IG51bWJlcjtcbiAgcHJvdGVjdGVkIF9pbnRlcnZhbDogbnVtYmVyO1xuICBwcm90ZWN0ZWQgX3NsaWRlczogTGlua2VkTGlzdDxTbGlkZUNvbXBvbmVudD4gPSBuZXcgTGlua2VkTGlzdDxTbGlkZUNvbXBvbmVudD4oKTtcbiAgcHJvdGVjdGVkIF9jaHVua2VkU2xpZGVzOiBTbGlkZVdpdGhJbmRleFtdW107XG4gIHByb3RlY3RlZCBfc2xpZGVzV2l0aEluZGV4ZXM6IFNsaWRlV2l0aEluZGV4W107XG4gIHByb3RlY3RlZCBfY3VycmVudFZpc2libGVTbGlkZXNJbmRleCA9IDA7XG4gIHByb3RlY3RlZCBpc1BsYXlpbmc6IGJvb2xlYW47XG4gIHByb3RlY3RlZCBkZXN0cm95ZWQgPSBmYWxzZTtcblxuICBnZXQgaXNCczQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICFpc0JzMygpO1xuICB9XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBDYXJvdXNlbENvbmZpZywgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSkge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcywgY29uZmlnKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICh0aGlzLnNpbmdsZVNsaWRlT2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuaW5kaWNhdG9yc0J5Q2h1bmsgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm11bHRpbGlzdCkge1xuICAgICAgICB0aGlzLl9jaHVua2VkU2xpZGVzID0gY2h1bmtCeU51bWJlcihcbiAgICAgICAgICB0aGlzLm1hcFNsaWRlc0FuZEluZGV4ZXMoKSxcbiAgICAgICAgICB0aGlzLml0ZW1zUGVyU2xpZGVcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zZWxlY3RJbml0aWFsU2xpZGVzKCk7XG4gICAgICB9XG4gICAgfSwgMCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3llZCA9IHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBuZXcgc2xpZGUuIElmIHRoaXMgc2xpZGUgaXMgZmlyc3QgaW4gY29sbGVjdGlvbiAtIHNldCBpdCBhcyBhY3RpdmVcbiAgICogYW5kIHN0YXJ0cyBhdXRvIGNoYW5naW5nXG4gICAqIEBwYXJhbSBzbGlkZVxuICAgKi9cbiAgYWRkU2xpZGUoc2xpZGU6IFNsaWRlQ29tcG9uZW50KTogdm9pZCB7XG4gICAgdGhpcy5fc2xpZGVzLmFkZChzbGlkZSk7XG5cbiAgICBpZiAodGhpcy5tdWx0aWxpc3QgJiYgdGhpcy5fc2xpZGVzLmxlbmd0aCA8PSB0aGlzLml0ZW1zUGVyU2xpZGUpIHtcbiAgICAgIHNsaWRlLmFjdGl2ZSA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLm11bHRpbGlzdCAmJiB0aGlzLl9zbGlkZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QWN0aXZlU2xpZGUgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLmFjdGl2ZVNsaWRlID0gMDtcbiAgICAgIHRoaXMucGxheSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm11bHRpbGlzdCAmJiB0aGlzLl9zbGlkZXMubGVuZ3RoID4gdGhpcy5pdGVtc1BlclNsaWRlKSB7XG4gICAgICB0aGlzLnBsYXkoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBzcGVjaWZpZWQgc2xpZGUuIElmIHRoaXMgc2xpZGUgaXMgYWN0aXZlIC0gd2lsbCByb2xsIHRvIGFub3RoZXJcbiAgICogc2xpZGVcbiAgICogQHBhcmFtIHNsaWRlXG4gICAqL1xuICByZW1vdmVTbGlkZShzbGlkZTogU2xpZGVDb21wb25lbnQpOiB2b2lkIHtcbiAgICBjb25zdCByZW1JbmRleCA9IHRoaXMuX3NsaWRlcy5pbmRleE9mKHNsaWRlKTtcblxuICAgIGlmICh0aGlzLl9jdXJyZW50QWN0aXZlU2xpZGUgPT09IHJlbUluZGV4KSB7XG4gICAgICAvLyByZW1vdmluZyBvZiBhY3RpdmUgc2xpZGVcbiAgICAgIGxldCBuZXh0U2xpZGVJbmRleDogbnVtYmVyID0gdm9pZCAwO1xuICAgICAgaWYgKHRoaXMuX3NsaWRlcy5sZW5ndGggPiAxKSB7XG4gICAgICAgIC8vIGlmIHRoaXMgc2xpZGUgbGFzdCAtIHdpbGwgcm9sbCB0byBmaXJzdCBzbGlkZSwgaWYgbm9XcmFwIGZsYWcgaXNcbiAgICAgICAgLy8gRkFMU0Ugb3IgdG8gcHJldmlvdXMsIGlmIG5vV3JhcCBpcyBUUlVFIGluIGNhc2UsIGlmIHRoaXMgc2xpZGUgaW5cbiAgICAgICAgLy8gbWlkZGxlIG9mIGNvbGxlY3Rpb24sIGluZGV4IG9mIG5leHQgc2xpZGUgaXMgc2FtZSB0byByZW1vdmVkXG4gICAgICAgIG5leHRTbGlkZUluZGV4ID0gIXRoaXMuaXNMYXN0KHJlbUluZGV4KVxuICAgICAgICAgID8gcmVtSW5kZXhcbiAgICAgICAgICA6IHRoaXMubm9XcmFwID8gcmVtSW5kZXggLSAxIDogMDtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3NsaWRlcy5yZW1vdmUocmVtSW5kZXgpO1xuXG4gICAgICAvLyBwcmV2ZW50cyBleGNlcHRpb24gd2l0aCBjaGFuZ2luZyBzb21lIHZhbHVlIGFmdGVyIGNoZWNraW5nXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5fc2VsZWN0KG5leHRTbGlkZUluZGV4KTtcbiAgICAgIH0sIDApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9zbGlkZXMucmVtb3ZlKHJlbUluZGV4KTtcbiAgICAgIGNvbnN0IGN1cnJlbnRTbGlkZUluZGV4ID0gdGhpcy5nZXRDdXJyZW50U2xpZGVJbmRleCgpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIC8vIGFmdGVyIHJlbW92aW5nLCBuZWVkIHRvIGFjdHVhbGl6ZSBpbmRleCBvZiBjdXJyZW50IGFjdGl2ZSBzbGlkZVxuICAgICAgICB0aGlzLl9jdXJyZW50QWN0aXZlU2xpZGUgPSBjdXJyZW50U2xpZGVJbmRleDtcbiAgICAgICAgdGhpcy5hY3RpdmVTbGlkZUNoYW5nZS5lbWl0KHRoaXMuX2N1cnJlbnRBY3RpdmVTbGlkZSk7XG4gICAgICB9LCAwKTtcbiAgICB9XG4gIH1cblxuICBuZXh0U2xpZGVGcm9tSW50ZXJ2YWwoZm9yY2UgPSBmYWxzZSk6IHZvaWQge1xuICAgIHRoaXMubW92ZShEaXJlY3Rpb24uTkVYVCwgZm9yY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJvbGxpbmcgdG8gbmV4dCBzbGlkZVxuICAgKiBAcGFyYW0gZm9yY2U6IHtib29sZWFufSBpZiB0cnVlIC0gd2lsbCBpZ25vcmUgbm9XcmFwIGZsYWdcbiAgICovXG4gIG5leHRTbGlkZShmb3JjZSA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNQbGF5aW5nKSB7XG4gICAgICB0aGlzLnJlc3RhcnRUaW1lcigpO1xuICAgIH1cbiAgICB0aGlzLm1vdmUoRGlyZWN0aW9uLk5FWFQsIGZvcmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSb2xsaW5nIHRvIHByZXZpb3VzIHNsaWRlXG4gICAqIEBwYXJhbSBmb3JjZToge2Jvb2xlYW59IGlmIHRydWUgLSB3aWxsIGlnbm9yZSBub1dyYXAgZmxhZ1xuICAgKi9cbiAgcHJldmlvdXNTbGlkZShmb3JjZSA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNQbGF5aW5nKSB7XG4gICAgICB0aGlzLnJlc3RhcnRUaW1lcigpO1xuICAgIH1cbiAgICB0aGlzLm1vdmUoRGlyZWN0aW9uLlBSRVYsIGZvcmNlKTtcbiAgfVxuXG4gIGdldEZpcnN0VmlzaWJsZUluZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc2xpZGVzLmZpbmRJbmRleCh0aGlzLmdldEFjdGl2ZSk7XG4gIH1cblxuICBnZXRMYXN0VmlzaWJsZUluZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIGZpbmRMYXN0SW5kZXgodGhpcy5zbGlkZXMsIHRoaXMuZ2V0QWN0aXZlKTtcbiAgfVxuXG4gIGdldEFjdGl2ZSA9IChzbGlkZTogU2xpZGVDb21wb25lbnQpID0+IHNsaWRlLmFjdGl2ZTtcblxuICBtb3ZlKGRpcmVjdGlvbjogRGlyZWN0aW9uLCBmb3JjZSA9IGZhbHNlKTogdm9pZCB7XG4gICAgY29uc3QgZmlyc3RWaXNpYmxlSW5kZXggPSB0aGlzLmdldEZpcnN0VmlzaWJsZUluZGV4KCk7XG4gICAgY29uc3QgbGFzdFZpc2libGVJbmRleCA9IHRoaXMuZ2V0TGFzdFZpc2libGVJbmRleCgpO1xuXG4gICAgaWYgKHRoaXMubm9XcmFwKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGRpcmVjdGlvbiA9PT0gRGlyZWN0aW9uLk5FWFQgJiZcbiAgICAgICAgdGhpcy5pc0xhc3QobGFzdFZpc2libGVJbmRleCkgfHxcbiAgICAgICAgZGlyZWN0aW9uID09PSBEaXJlY3Rpb24uUFJFViAmJlxuICAgICAgICBmaXJzdFZpc2libGVJbmRleCA9PT0gMFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMubXVsdGlsaXN0KSB7XG4gICAgICB0aGlzLmFjdGl2ZVNsaWRlID0gdGhpcy5maW5kTmV4dFNsaWRlSW5kZXgoZGlyZWN0aW9uLCBmb3JjZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubW92ZU11bHRpbGlzdChkaXJlY3Rpb24pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTd2l0aCBzbGlkZXMgYnkgZW50ZXIsIHNwYWNlIGFuZCBhcnJvd3Mga2V5c1xuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGtleWRvd25QcmVzcyhldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgIGlmIChldmVudC5rZXlDb2RlID09PSAxMyB8fCBldmVudC5rZXkgPT09ICdFbnRlcicgfHwgZXZlbnQua2V5Q29kZSA9PT0gMzIgfHwgZXZlbnQua2V5ID09PSAnU3BhY2UnKSB7XG4gICAgICB0aGlzLm5leHRTbGlkZSgpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgIGlmIChldmVudC5rZXlDb2RlID09PSAzNyB8fCBldmVudC5rZXkgPT09ICdMZWZ0QXJyb3cnKSB7XG4gICAgICB0aGlzLnByZXZpb3VzU2xpZGUoKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgIGlmIChldmVudC5rZXlDb2RlID09PSAzOSB8fCBldmVudC5rZXkgPT09ICdSaWdodEFycm93Jykge1xuICAgICAgdGhpcy5uZXh0U2xpZGUoKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQbGF5IG9uIG1vdXNlIGxlYXZlXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgb25Nb3VzZUxlYXZlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wYXVzZU9uRm9jdXMpIHtcbiAgICAgIHRoaXMucGxheSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQbGF5IG9uIG1vdXNlIHVwXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgb25Nb3VzZVVwKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wYXVzZU9uRm9jdXMpIHtcbiAgICAgIHRoaXMucGxheSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBXaGVuIHNsaWRlcyBvbiBmb2N1cyBhdXRvcGxheSBpcyBzdG9wcGVkKG9wdGlvbmFsKVxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHBhdXNlRm9jdXNJbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5wYXVzZU9uRm9jdXMpIHtcbiAgICAgIHRoaXMuaXNQbGF5aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLnJlc2V0VGltZXIoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogV2hlbiBzbGlkZXMgb3V0IG9mIGZvY3VzIGF1dG9wbGF5IGlzIHN0YXJ0ZWRcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwYXVzZUZvY3VzT3V0KCk6IHZvaWQge1xuICAgIHRoaXMucGxheSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJvbGxpbmcgdG8gc3BlY2lmaWVkIHNsaWRlXG4gICAqIEBwYXJhbSBpbmRleDoge251bWJlcn0gaW5kZXggb2Ygc2xpZGUsIHdoaWNoIG11c3QgYmUgc2hvd25cbiAgICovXG4gIHNlbGVjdFNsaWRlKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc1BsYXlpbmcpIHtcbiAgICAgIHRoaXMucmVzdGFydFRpbWVyKCk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLm11bHRpbGlzdCkge1xuICAgICAgdGhpcy5hY3RpdmVTbGlkZSA9IHRoaXMuaW5kaWNhdG9yc0J5Q2h1bmsgPyBpbmRleCAqIHRoaXMuaXRlbXNQZXJTbGlkZSA6IGluZGV4O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdFNsaWRlUmFuZ2UodGhpcy5pbmRpY2F0b3JzQnlDaHVuayA/IGluZGV4ICogdGhpcy5pdGVtc1BlclNsaWRlIDogaW5kZXgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydHMgYSBhdXRvIGNoYW5naW5nIG9mIHNsaWRlc1xuICAgKi9cbiAgcGxheSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNQbGF5aW5nKSB7XG4gICAgICB0aGlzLmlzUGxheWluZyA9IHRydWU7XG4gICAgICB0aGlzLnJlc3RhcnRUaW1lcigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wcyBhIGF1dG8gY2hhbmdpbmcgb2Ygc2xpZGVzXG4gICAqL1xuICBwYXVzZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubm9QYXVzZSkge1xuICAgICAgdGhpcy5pc1BsYXlpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMucmVzZXRUaW1lcigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyBhbmQgcmV0dXJucyBpbmRleCBvZiBjdXJyZW50bHkgZGlzcGxheWVkIHNsaWRlXG4gICAqL1xuICBnZXRDdXJyZW50U2xpZGVJbmRleCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9zbGlkZXMuZmluZEluZGV4KHRoaXMuZ2V0QWN0aXZlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZpbmVzLCB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgbGFzdCBpbiBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSBpbmRleFxuICAgKi9cbiAgaXNMYXN0KGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaW5kZXggKyAxID49IHRoaXMuX3NsaWRlcy5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogRGVmaW5lcywgd2hldGhlciB0aGUgc3BlY2lmaWVkIGluZGV4IGlzIGZpcnN0IGluIGNvbGxlY3Rpb25cbiAgICogQHBhcmFtIGluZGV4XG4gICAqL1xuICBpc0ZpcnN0KGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaW5kZXggPT09IDA7XG4gIH1cblxuICBpbmRpY2F0b3JzU2xpZGVzKCk6IFNsaWRlQ29tcG9uZW50W10ge1xuICAgIHJldHVybiB0aGlzLnNsaWRlcy5maWx0ZXIoXG4gICAgICAoc2xpZGU6IFNsaWRlQ29tcG9uZW50LCBpbmRleDogbnVtYmVyKSA9PiAhdGhpcy5pbmRpY2F0b3JzQnlDaHVuayB8fCBpbmRleCAlIHRoaXMuaXRlbXNQZXJTbGlkZSA9PT0gMFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHNlbGVjdEluaXRpYWxTbGlkZXMoKTogdm9pZCB7XG4gICAgY29uc3Qgc3RhcnRJbmRleCA9IHRoaXMuc3RhcnRGcm9tSW5kZXggPD0gdGhpcy5fc2xpZGVzLmxlbmd0aFxuICAgICAgPyB0aGlzLnN0YXJ0RnJvbUluZGV4XG4gICAgICA6IDA7XG5cbiAgICB0aGlzLmhpZGVTbGlkZXMoKTtcblxuICAgIGlmICh0aGlzLnNpbmdsZVNsaWRlT2Zmc2V0KSB7XG4gICAgICB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcyA9IHRoaXMubWFwU2xpZGVzQW5kSW5kZXhlcygpO1xuXG4gICAgICBpZiAodGhpcy5fc2xpZGVzLmxlbmd0aCAtIHN0YXJ0SW5kZXggPCB0aGlzLml0ZW1zUGVyU2xpZGUpIHtcbiAgICAgICAgY29uc3Qgc2xpZGVzVG9BcHBlbmQgPSB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcy5zbGljZSgwLCBzdGFydEluZGV4KTtcblxuICAgICAgICB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcyAgPSBbXG4gICAgICAgICAgLi4udGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMsXG4gICAgICAgICAgLi4uc2xpZGVzVG9BcHBlbmRcbiAgICAgICAgXVxuICAgICAgICAgIC5zbGljZShzbGlkZXNUb0FwcGVuZC5sZW5ndGgpXG4gICAgICAgICAgLnNsaWNlKDAsIHRoaXMuaXRlbXNQZXJTbGlkZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcyA9IHRoaXMuX3NsaWRlc1dpdGhJbmRleGVzLnNsaWNlKFxuICAgICAgICAgIHN0YXJ0SW5kZXgsXG4gICAgICAgICAgc3RhcnRJbmRleCArIHRoaXMuaXRlbXNQZXJTbGlkZVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcy5mb3JFYWNoKChzbGlkZTogU2xpZGVXaXRoSW5kZXgpID0+IHNsaWRlLml0ZW0uYWN0aXZlID0gdHJ1ZSk7XG4gICAgICB0aGlzLm1ha2VTbGlkZXNDb25zaXN0ZW50KHRoaXMuX3NsaWRlc1dpdGhJbmRleGVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZWxlY3RSYW5nZUJ5TmVzdGVkSW5kZXgoc3RhcnRJbmRleCk7XG4gICAgfVxuXG4gICAgdGhpcy5zbGlkZVJhbmdlQ2hhbmdlLmVtaXQodGhpcy5nZXRWaXNpYmxlSW5kZXhlcygpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZpbmVzIG5leHQgc2xpZGUgaW5kZXgsIGRlcGVuZGluZyBvZiBkaXJlY3Rpb25cbiAgICogQHBhcmFtIGRpcmVjdGlvbjogRGlyZWN0aW9uKFVOS05PV058UFJFVnxORVhUKVxuICAgKiBAcGFyYW0gZm9yY2U6IHtib29sZWFufSBpZiBUUlVFIC0gd2lsbCBpZ25vcmUgbm9XcmFwIGZsYWcsIGVsc2Ugd2lsbFxuICAgKiAgIHJldHVybiB1bmRlZmluZWQgaWYgbmV4dCBzbGlkZSByZXF1aXJlIHdyYXBwaW5nXG4gICAqL1xuICBwcml2YXRlIGZpbmROZXh0U2xpZGVJbmRleChkaXJlY3Rpb246IERpcmVjdGlvbiwgZm9yY2U6IGJvb2xlYW4pOiBudW1iZXIge1xuICAgIGxldCBuZXh0U2xpZGVJbmRleCA9IDA7XG5cbiAgICBpZiAoXG4gICAgICAhZm9yY2UgJiZcbiAgICAgICh0aGlzLmlzTGFzdCh0aGlzLmFjdGl2ZVNsaWRlKSAmJlxuICAgICAgICBkaXJlY3Rpb24gIT09IERpcmVjdGlvbi5QUkVWICYmXG4gICAgICAgIHRoaXMubm9XcmFwKVxuICAgICkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGRpcmVjdGlvbikge1xuICAgICAgY2FzZSBEaXJlY3Rpb24uTkVYVDpcbiAgICAgICAgLy8gaWYgdGhpcyBpcyBsYXN0IHNsaWRlLCBub3QgZm9yY2UsIGxvb3BpbmcgaXMgZGlzYWJsZWRcbiAgICAgICAgLy8gYW5kIG5lZWQgdG8gZ29pbmcgZm9yd2FyZCAtIHNlbGVjdCBjdXJyZW50IHNsaWRlLCBhcyBhIG5leHRcbiAgICAgICAgbmV4dFNsaWRlSW5kZXggPSAhdGhpcy5pc0xhc3QodGhpcy5fY3VycmVudEFjdGl2ZVNsaWRlKVxuICAgICAgICAgID8gdGhpcy5fY3VycmVudEFjdGl2ZVNsaWRlICsgMVxuICAgICAgICAgIDogIWZvcmNlICYmIHRoaXMubm9XcmFwID8gdGhpcy5fY3VycmVudEFjdGl2ZVNsaWRlIDogMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIERpcmVjdGlvbi5QUkVWOlxuICAgICAgICAvLyBpZiB0aGlzIGlzIGZpcnN0IHNsaWRlLCBub3QgZm9yY2UsIGxvb3BpbmcgaXMgZGlzYWJsZWRcbiAgICAgICAgLy8gYW5kIG5lZWQgdG8gZ29pbmcgYmFja3dhcmQgLSBzZWxlY3QgY3VycmVudCBzbGlkZSwgYXMgYSBuZXh0XG4gICAgICAgIG5leHRTbGlkZUluZGV4ID1cbiAgICAgICAgICB0aGlzLl9jdXJyZW50QWN0aXZlU2xpZGUgPiAwXG4gICAgICAgICAgICA/IHRoaXMuX2N1cnJlbnRBY3RpdmVTbGlkZSAtIDFcbiAgICAgICAgICAgIDogIWZvcmNlICYmIHRoaXMubm9XcmFwXG4gICAgICAgICAgICAgID8gdGhpcy5fY3VycmVudEFjdGl2ZVNsaWRlXG4gICAgICAgICAgICAgIDogdGhpcy5fc2xpZGVzLmxlbmd0aCAtIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGRpcmVjdGlvbicpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXh0U2xpZGVJbmRleDtcbiAgfVxuXG4gIHByaXZhdGUgbWFwU2xpZGVzQW5kSW5kZXhlcygpOiBTbGlkZVdpdGhJbmRleFtdIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXNcbiAgICAgIC5zbGljZSgpXG4gICAgICAubWFwKChzbGlkZTogU2xpZGVDb21wb25lbnQsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBpbmRleCxcbiAgICAgICAgICBpdGVtOiBzbGlkZVxuICAgICAgICB9O1xuICAgICAgfSk7XG4gIH1cblxuXG4gIHByaXZhdGUgc2VsZWN0U2xpZGVSYW5nZShpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNJbmRleEluUmFuZ2UoaW5kZXgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5oaWRlU2xpZGVzKCk7XG5cbiAgICBpZiAoIXRoaXMuc2luZ2xlU2xpZGVPZmZzZXQpIHtcbiAgICAgIHRoaXMuc2VsZWN0UmFuZ2VCeU5lc3RlZEluZGV4KGluZGV4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgc3RhcnRJbmRleCA9IHRoaXMuaXNJbmRleE9uVGhlRWRnZXMoaW5kZXgpXG4gICAgICAgID8gaW5kZXhcbiAgICAgICAgOiBpbmRleCAtIHRoaXMuaXRlbXNQZXJTbGlkZSArIDE7XG5cbiAgICAgIGNvbnN0IGVuZEluZGV4ID0gdGhpcy5pc0luZGV4T25UaGVFZGdlcyhpbmRleClcbiAgICAgICAgPyBpbmRleCArIHRoaXMuaXRlbXNQZXJTbGlkZVxuICAgICAgICA6IGluZGV4ICsgMTtcblxuICAgICAgdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMgPSB0aGlzLm1hcFNsaWRlc0FuZEluZGV4ZXMoKS5zbGljZShzdGFydEluZGV4LCBlbmRJbmRleCk7XG4gICAgICB0aGlzLm1ha2VTbGlkZXNDb25zaXN0ZW50KHRoaXMuX3NsaWRlc1dpdGhJbmRleGVzKTtcblxuICAgICAgdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMuZm9yRWFjaCgoc2xpZGU6IFNsaWRlV2l0aEluZGV4KSA9PiBzbGlkZS5pdGVtLmFjdGl2ZSA9IHRydWUpO1xuICAgIH1cblxuICAgIHRoaXMuc2xpZGVSYW5nZUNoYW5nZS5lbWl0KHRoaXMuZ2V0VmlzaWJsZUluZGV4ZXMoKSk7XG4gIH1cblxuICBwcml2YXRlIHNlbGVjdFJhbmdlQnlOZXN0ZWRJbmRleChpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0ZWRSYW5nZSA9IHRoaXMuX2NodW5rZWRTbGlkZXNcbiAgICAgIC5tYXAoKHNsaWRlc0xpc3QsIGk6IG51bWJlcikgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGluZGV4OiBpLFxuICAgICAgICAgIGxpc3Q6IHNsaWRlc0xpc3RcbiAgICAgICAgfTtcbiAgICAgIH0pXG4gICAgICAuZmluZChcbiAgICAgICAgKHNsaWRlc0xpc3Q6IEluZGV4ZWRTbGlkZUxpc3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gc2xpZGVzTGlzdC5saXN0LmZpbmQoc2xpZGUgPT4gc2xpZGUuaW5kZXggPT09IGluZGV4KSAhPT0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICApO1xuXG4gICAgdGhpcy5fY3VycmVudFZpc2libGVTbGlkZXNJbmRleCA9IHNlbGVjdGVkUmFuZ2UuaW5kZXg7XG5cbiAgICB0aGlzLl9jaHVua2VkU2xpZGVzW3NlbGVjdGVkUmFuZ2UuaW5kZXhdLmZvckVhY2goKHNsaWRlOiBTbGlkZVdpdGhJbmRleCkgPT4ge1xuICAgICAgc2xpZGUuaXRlbS5hY3RpdmUgPSB0cnVlO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0luZGV4T25UaGVFZGdlcyhpbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIGluZGV4ICsgMSAtIHRoaXMuaXRlbXNQZXJTbGlkZSA8PSAwIHx8XG4gICAgICBpbmRleCArIHRoaXMuaXRlbXNQZXJTbGlkZSA8PSB0aGlzLl9zbGlkZXMubGVuZ3RoXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNJbmRleEluUmFuZ2UoaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnNpbmdsZVNsaWRlT2Zmc2V0KSB7XG4gICAgICBjb25zdCB2aXNpYmxlSW5kZXhlcyA9IHRoaXMuX3NsaWRlc1dpdGhJbmRleGVzLm1hcCgoc2xpZGU6IFNsaWRlV2l0aEluZGV4KSA9PiBzbGlkZS5pbmRleCk7XG5cbiAgICAgIHJldHVybiB2aXNpYmxlSW5kZXhlcy5pbmRleE9mKGluZGV4KSA+PSAwO1xuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICBpbmRleCA8PSB0aGlzLmdldExhc3RWaXNpYmxlSW5kZXgoKSAmJlxuICAgICAgaW5kZXggPj0gdGhpcy5nZXRGaXJzdFZpc2libGVJbmRleCgpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgaGlkZVNsaWRlcygpOiB2b2lkIHtcbiAgICB0aGlzLnNsaWRlcy5mb3JFYWNoKChzbGlkZTogU2xpZGVDb21wb25lbnQpID0+IHNsaWRlLmFjdGl2ZSA9IGZhbHNlKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNWaXNpYmxlU2xpZGVMaXN0TGFzdCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudFZpc2libGVTbGlkZXNJbmRleCA9PT0gdGhpcy5fY2h1bmtlZFNsaWRlcy5sZW5ndGggLSAxO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1Zpc2libGVTbGlkZUxpc3RGaXJzdCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudFZpc2libGVTbGlkZXNJbmRleCA9PT0gMDtcbiAgfVxuXG4gIHByaXZhdGUgbW92ZVNsaWRlckJ5T25lSXRlbShkaXJlY3Rpb246IERpcmVjdGlvbik6IHZvaWQge1xuICAgIGxldCBmaXJzdFZpc2libGVJbmRleDogbnVtYmVyO1xuICAgIGxldCBsYXN0VmlzaWJsZUluZGV4OiBudW1iZXI7XG4gICAgbGV0IGluZGV4VG9IaWRlOiBudW1iZXI7XG4gICAgbGV0IGluZGV4VG9TaG93OiBudW1iZXI7XG5cbiAgICBpZiAodGhpcy5ub1dyYXApIHtcbiAgICAgIGZpcnN0VmlzaWJsZUluZGV4ID0gdGhpcy5nZXRGaXJzdFZpc2libGVJbmRleCgpO1xuICAgICAgbGFzdFZpc2libGVJbmRleCA9IHRoaXMuZ2V0TGFzdFZpc2libGVJbmRleCgpO1xuXG4gICAgICBpbmRleFRvSGlkZSA9IGRpcmVjdGlvbiA9PT0gRGlyZWN0aW9uLk5FWFRcbiAgICAgICAgPyBmaXJzdFZpc2libGVJbmRleFxuICAgICAgICA6IGxhc3RWaXNpYmxlSW5kZXg7XG5cbiAgICAgIGluZGV4VG9TaG93ID0gZGlyZWN0aW9uICE9PSBEaXJlY3Rpb24uTkVYVFxuICAgICAgICA/IGZpcnN0VmlzaWJsZUluZGV4IC0gMVxuICAgICAgICA6ICF0aGlzLmlzTGFzdChsYXN0VmlzaWJsZUluZGV4KVxuICAgICAgICAgID8gbGFzdFZpc2libGVJbmRleCArIDEgOiAwO1xuXG4gICAgICB0aGlzLl9zbGlkZXMuZ2V0KGluZGV4VG9IaWRlKS5hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuX3NsaWRlcy5nZXQoaW5kZXhUb1Nob3cpLmFjdGl2ZSA9IHRydWU7XG5cbiAgICAgIGNvbnN0IHNsaWRlc1RvUmVvcmRlciA9IHRoaXMubWFwU2xpZGVzQW5kSW5kZXhlcygpLmZpbHRlcihcbiAgICAgICAgKHNsaWRlOiBTbGlkZVdpdGhJbmRleCkgPT4gc2xpZGUuaXRlbS5hY3RpdmVcbiAgICAgICk7XG5cbiAgICAgIHRoaXMubWFrZVNsaWRlc0NvbnNpc3RlbnQoc2xpZGVzVG9SZW9yZGVyKTtcblxuICAgICAgdGhpcy5zbGlkZVJhbmdlQ2hhbmdlLmVtaXQodGhpcy5nZXRWaXNpYmxlSW5kZXhlcygpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGRpc3BsYXllZEluZGV4OiBudW1iZXI7XG5cbiAgICAgIGZpcnN0VmlzaWJsZUluZGV4ID0gdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXNbMF0uaW5kZXg7XG4gICAgICBsYXN0VmlzaWJsZUluZGV4ID0gdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXNbdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMubGVuZ3RoIC0gMV0uaW5kZXg7XG5cbiAgICAgIGlmIChkaXJlY3Rpb24gPT09IERpcmVjdGlvbi5ORVhUKSB7XG4gICAgICAgIHRoaXMuX3NsaWRlc1dpdGhJbmRleGVzLnNoaWZ0KCk7XG5cbiAgICAgICAgZGlzcGxheWVkSW5kZXggPSB0aGlzLmlzTGFzdChsYXN0VmlzaWJsZUluZGV4KVxuICAgICAgICAgID8gMFxuICAgICAgICAgIDogbGFzdFZpc2libGVJbmRleCArIDE7XG5cbiAgICAgICAgdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMucHVzaCh7XG4gICAgICAgICAgaW5kZXg6IGRpc3BsYXllZEluZGV4LFxuICAgICAgICAgIGl0ZW06IHRoaXMuX3NsaWRlcy5nZXQoZGlzcGxheWVkSW5kZXgpXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMucG9wKCk7XG4gICAgICAgIGRpc3BsYXllZEluZGV4ID0gdGhpcy5pc0ZpcnN0KGZpcnN0VmlzaWJsZUluZGV4KVxuICAgICAgICAgID8gdGhpcy5fc2xpZGVzLmxlbmd0aCAtIDFcbiAgICAgICAgICA6IGZpcnN0VmlzaWJsZUluZGV4IC0gMTtcblxuICAgICAgICB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcyA9IFt7XG4gICAgICAgICAgaW5kZXg6IGRpc3BsYXllZEluZGV4LFxuICAgICAgICAgIGl0ZW06IHRoaXMuX3NsaWRlcy5nZXQoZGlzcGxheWVkSW5kZXgpXG4gICAgICAgIH0sIC4uLnRoaXMuX3NsaWRlc1dpdGhJbmRleGVzXTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5oaWRlU2xpZGVzKCk7XG5cbiAgICAgIHRoaXMuX3NsaWRlc1dpdGhJbmRleGVzLmZvckVhY2goc2xpZGUgPT4gc2xpZGUuaXRlbS5hY3RpdmUgPSB0cnVlKTtcblxuICAgICAgdGhpcy5tYWtlU2xpZGVzQ29uc2lzdGVudCh0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcyk7XG5cbiAgICAgIHRoaXMuc2xpZGVSYW5nZUNoYW5nZS5lbWl0KFxuICAgICAgICB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcy5tYXAoKHNsaWRlOiBTbGlkZVdpdGhJbmRleCkgPT4gc2xpZGUuaW5kZXgpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbWFrZVNsaWRlc0NvbnNpc3RlbnQgPSAoc2xpZGVzOiBTbGlkZVdpdGhJbmRleFtdKTogdm9pZCA9PiB7XG4gICAgc2xpZGVzLmZvckVhY2goKHNsaWRlOiBTbGlkZVdpdGhJbmRleCwgaW5kZXg6IG51bWJlcikgPT4gc2xpZGUuaXRlbS5vcmRlciA9IGluZGV4KTtcbiAgfVxuXG4gIHByaXZhdGUgbW92ZU11bHRpbGlzdChkaXJlY3Rpb246IERpcmVjdGlvbik6IHZvaWQge1xuICAgIGlmICh0aGlzLnNpbmdsZVNsaWRlT2Zmc2V0KSB7XG4gICAgICB0aGlzLm1vdmVTbGlkZXJCeU9uZUl0ZW0oZGlyZWN0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5oaWRlU2xpZGVzKCk7XG5cbiAgICAgIGlmICh0aGlzLm5vV3JhcCkge1xuICAgICAgICB0aGlzLl9jdXJyZW50VmlzaWJsZVNsaWRlc0luZGV4ID0gZGlyZWN0aW9uID09PSBEaXJlY3Rpb24uTkVYVFxuICAgICAgICAgID8gdGhpcy5fY3VycmVudFZpc2libGVTbGlkZXNJbmRleCArIDFcbiAgICAgICAgICA6IHRoaXMuX2N1cnJlbnRWaXNpYmxlU2xpZGVzSW5kZXggLSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gRGlyZWN0aW9uLk5FWFQpIHtcbiAgICAgICAgICB0aGlzLl9jdXJyZW50VmlzaWJsZVNsaWRlc0luZGV4ID0gdGhpcy5pc1Zpc2libGVTbGlkZUxpc3RMYXN0KClcbiAgICAgICAgICAgID8gMFxuICAgICAgICAgICAgOiB0aGlzLl9jdXJyZW50VmlzaWJsZVNsaWRlc0luZGV4ICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9jdXJyZW50VmlzaWJsZVNsaWRlc0luZGV4ID0gdGhpcy5pc1Zpc2libGVTbGlkZUxpc3RGaXJzdCgpXG4gICAgICAgICAgICA/IHRoaXMuX2NodW5rZWRTbGlkZXMubGVuZ3RoIC0gMVxuICAgICAgICAgICAgOiB0aGlzLl9jdXJyZW50VmlzaWJsZVNsaWRlc0luZGV4IC0gMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLl9jaHVua2VkU2xpZGVzW3RoaXMuX2N1cnJlbnRWaXNpYmxlU2xpZGVzSW5kZXhdLmZvckVhY2goXG4gICAgICAgIChzbGlkZTogU2xpZGVXaXRoSW5kZXgpID0+IHNsaWRlLml0ZW0uYWN0aXZlID0gdHJ1ZVxuICAgICAgKTtcblxuICAgICAgdGhpcy5zbGlkZVJhbmdlQ2hhbmdlLmVtaXQodGhpcy5nZXRWaXNpYmxlSW5kZXhlcygpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldFZpc2libGVJbmRleGVzKCk6IG51bWJlcltdIHtcbiAgICBpZiAoIXRoaXMuc2luZ2xlU2xpZGVPZmZzZXQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jaHVua2VkU2xpZGVzW3RoaXMuX2N1cnJlbnRWaXNpYmxlU2xpZGVzSW5kZXhdXG4gICAgICAgIC5tYXAoKHNsaWRlOiBTbGlkZVdpdGhJbmRleCkgPT4gc2xpZGUuaW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMubWFwKChzbGlkZTogU2xpZGVXaXRoSW5kZXgpID0+IHNsaWRlLmluZGV4KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhIHNsaWRlLCB3aGljaCBzcGVjaWZpZWQgdGhyb3VnaCBpbmRleCwgYXMgYWN0aXZlXG4gICAqIEBwYXJhbSBpbmRleFxuICAgKi9cbiAgcHJpdmF0ZSBfc2VsZWN0KGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoaXNOYU4oaW5kZXgpKSB7XG4gICAgICB0aGlzLnBhdXNlKCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMubXVsdGlsaXN0KSB7XG4gICAgICBjb25zdCBjdXJyZW50U2xpZGUgPSB0aGlzLl9zbGlkZXMuZ2V0KHRoaXMuX2N1cnJlbnRBY3RpdmVTbGlkZSk7XG4gICAgICBpZiAoY3VycmVudFNsaWRlKSB7XG4gICAgICAgIGN1cnJlbnRTbGlkZS5hY3RpdmUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBuZXh0U2xpZGUgPSB0aGlzLl9zbGlkZXMuZ2V0KGluZGV4KTtcbiAgICBpZiAobmV4dFNsaWRlKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QWN0aXZlU2xpZGUgPSBpbmRleDtcbiAgICAgIG5leHRTbGlkZS5hY3RpdmUgPSB0cnVlO1xuICAgICAgdGhpcy5hY3RpdmVTbGlkZSA9IGluZGV4O1xuICAgICAgdGhpcy5hY3RpdmVTbGlkZUNoYW5nZS5lbWl0KGluZGV4KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3RhcnRzIGxvb3Agb2YgYXV0byBjaGFuZ2luZyBvZiBzbGlkZXNcbiAgICovXG4gIHByaXZhdGUgcmVzdGFydFRpbWVyKCkge1xuICAgIHRoaXMucmVzZXRUaW1lcigpO1xuICAgIGNvbnN0IGludGVydmFsID0gK3RoaXMuaW50ZXJ2YWw7XG4gICAgaWYgKCFpc05hTihpbnRlcnZhbCkgJiYgaW50ZXJ2YWwgPiAwKSB7XG4gICAgICB0aGlzLmN1cnJlbnRJbnRlcnZhbCA9IHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICBjb25zdCBuSW50ZXJ2YWwgPSArdGhpcy5pbnRlcnZhbDtcbiAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICB0aGlzLmlzUGxheWluZyAmJlxuICAgICAgICAgICAgICAhaXNOYU4odGhpcy5pbnRlcnZhbCkgJiZcbiAgICAgICAgICAgICAgbkludGVydmFsID4gMCAmJlxuICAgICAgICAgICAgICB0aGlzLnNsaWRlcy5sZW5ndGhcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB0aGlzLm5leHRTbGlkZUZyb21JbnRlcnZhbCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5wYXVzZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9LCBpbnRlcnZhbCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgbXVsdGlsaXN0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLml0ZW1zUGVyU2xpZGUgPiAxO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0b3BzIGxvb3Agb2YgYXV0byBjaGFuZ2luZyBvZiBzbGlkZXNcbiAgICovXG4gIHByaXZhdGUgcmVzZXRUaW1lcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jdXJyZW50SW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jdXJyZW50SW50ZXJ2YWwpO1xuICAgICAgdGhpcy5jdXJyZW50SW50ZXJ2YWwgPSB2b2lkIDA7XG4gICAgfVxuICB9XG59XG4iXX0=