datepicker.js 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import * as tslib_1 from "tslib";
  6. import { fromEvent, merge, Subject } from 'rxjs';
  7. import { filter, take, takeUntil } from 'rxjs/operators';
  8. import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, NgZone, Output, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core';
  9. import { NG_VALUE_ACCESSOR } from '@angular/forms';
  10. import { NgbCalendar } from './ngb-calendar';
  11. import { NgbDate } from './ngb-date';
  12. import { NgbDatepickerService } from './datepicker-service';
  13. import { NgbDatepickerKeyboardService } from './datepicker-keyboard-service';
  14. import { NavigationEvent } from './datepicker-view-model';
  15. import { NgbDatepickerConfig } from './datepicker-config';
  16. import { NgbDateAdapter } from './adapters/ngb-date-adapter';
  17. import { NgbDatepickerI18n } from './datepicker-i18n';
  18. import { isChangedDate, isChangedMonth } from './datepicker-tools';
  19. import { hasClassName } from '../util/util';
  20. /** @type {?} */
  21. var NGB_DATEPICKER_VALUE_ACCESSOR = {
  22. provide: NG_VALUE_ACCESSOR,
  23. useExisting: forwardRef((/**
  24. * @return {?}
  25. */
  26. function () { return NgbDatepicker; })),
  27. multi: true
  28. };
  29. /**
  30. * An event emitted right before the navigation happens and the month displayed by the datepicker changes.
  31. * @record
  32. */
  33. export function NgbDatepickerNavigateEvent() { }
  34. if (false) {
  35. /**
  36. * The currently displayed month.
  37. * @type {?}
  38. */
  39. NgbDatepickerNavigateEvent.prototype.current;
  40. /**
  41. * The month we're navigating to.
  42. * @type {?}
  43. */
  44. NgbDatepickerNavigateEvent.prototype.next;
  45. /**
  46. * Calling this function will prevent navigation from happening.
  47. *
  48. * \@since 4.1.0
  49. * @type {?}
  50. */
  51. NgbDatepickerNavigateEvent.prototype.preventDefault;
  52. }
  53. /**
  54. * An interface that represents the readonly public state of the datepicker.
  55. *
  56. * Accessible via the `datepicker.state` getter
  57. *
  58. * \@since 5.2.0
  59. * @record
  60. */
  61. export function NgbDatepickerState() { }
  62. if (false) {
  63. /**
  64. * The earliest date that can be displayed or selected
  65. * @type {?}
  66. */
  67. NgbDatepickerState.prototype.minDate;
  68. /**
  69. * The latest date that can be displayed or selected
  70. * @type {?}
  71. */
  72. NgbDatepickerState.prototype.maxDate;
  73. /**
  74. * The first visible date of currently displayed months
  75. * @type {?}
  76. */
  77. NgbDatepickerState.prototype.firstDate;
  78. /**
  79. * The last visible date of currently displayed months
  80. * @type {?}
  81. */
  82. NgbDatepickerState.prototype.lastDate;
  83. /**
  84. * The date currently focused by the datepicker
  85. * @type {?}
  86. */
  87. NgbDatepickerState.prototype.focusedDate;
  88. }
  89. /**
  90. * A highly configurable component that helps you with selecting calendar dates.
  91. *
  92. * `NgbDatepicker` is meant to be displayed inline on a page or put inside a popup.
  93. */
  94. var NgbDatepicker = /** @class */ (function () {
  95. function NgbDatepicker(_service, _calendar, i18n, config, _keyboardService, cd, _elementRef, _ngbDateAdapter, _ngZone) {
  96. var _this = this;
  97. this._service = _service;
  98. this._calendar = _calendar;
  99. this.i18n = i18n;
  100. this._keyboardService = _keyboardService;
  101. this._elementRef = _elementRef;
  102. this._ngbDateAdapter = _ngbDateAdapter;
  103. this._ngZone = _ngZone;
  104. this._destroyed$ = new Subject();
  105. this._publicState = (/** @type {?} */ ({}));
  106. /**
  107. * An event emitted right before the navigation happens and displayed month changes.
  108. *
  109. * See [`NgbDatepickerNavigateEvent`](#/components/datepicker/api#NgbDatepickerNavigateEvent) for the payload info.
  110. */
  111. this.navigate = new EventEmitter();
  112. /**
  113. * An event emitted when user selects a date using keyboard or mouse.
  114. *
  115. * The payload of the event is currently selected `NgbDate`.
  116. *
  117. * \@since 5.2.0
  118. */
  119. this.dateSelect = new EventEmitter();
  120. /**
  121. * An event emitted when user selects a date using keyboard or mouse.
  122. *
  123. * The payload of the event is currently selected `NgbDate`.
  124. *
  125. * Please use 'dateSelect' output instead, this will be deprecated in version 6.0 due to collision with native
  126. * 'select' event.
  127. */
  128. this.select = this.dateSelect;
  129. this.onChange = (/**
  130. * @param {?} _
  131. * @return {?}
  132. */
  133. function (_) { });
  134. this.onTouched = (/**
  135. * @return {?}
  136. */
  137. function () { });
  138. ['dayTemplate', 'dayTemplateData', 'displayMonths', 'firstDayOfWeek', 'footerTemplate', 'markDisabled', 'minDate',
  139. 'maxDate', 'navigation', 'outsideDays', 'showWeekdays', 'showWeekNumbers', 'startDate']
  140. .forEach((/**
  141. * @param {?} input
  142. * @return {?}
  143. */
  144. function (input) { return _this[input] = config[input]; }));
  145. _service.dateSelect$.pipe(takeUntil(this._destroyed$)).subscribe((/**
  146. * @param {?} date
  147. * @return {?}
  148. */
  149. function (date) { _this.dateSelect.emit(date); }));
  150. _service.model$.pipe(takeUntil(this._destroyed$)).subscribe((/**
  151. * @param {?} model
  152. * @return {?}
  153. */
  154. function (model) {
  155. /** @type {?} */
  156. var newDate = model.firstDate;
  157. /** @type {?} */
  158. var oldDate = _this.model ? _this.model.firstDate : null;
  159. // update public state
  160. _this._publicState = {
  161. maxDate: model.maxDate,
  162. minDate: model.minDate,
  163. firstDate: model.firstDate,
  164. lastDate: model.lastDate,
  165. focusedDate: model.focusDate
  166. };
  167. /** @type {?} */
  168. var navigationPrevented = false;
  169. // emitting navigation event if the first month changes
  170. if (!newDate.equals(oldDate)) {
  171. _this.navigate.emit({
  172. current: oldDate ? { year: oldDate.year, month: oldDate.month } : null,
  173. next: { year: newDate.year, month: newDate.month },
  174. preventDefault: (/**
  175. * @return {?}
  176. */
  177. function () { return navigationPrevented = true; })
  178. });
  179. // can't prevent the very first navigation
  180. if (navigationPrevented && oldDate !== null) {
  181. _this._service.open(oldDate);
  182. return;
  183. }
  184. }
  185. /** @type {?} */
  186. var newSelectedDate = model.selectedDate;
  187. /** @type {?} */
  188. var newFocusedDate = model.focusDate;
  189. /** @type {?} */
  190. var oldFocusedDate = _this.model ? _this.model.focusDate : null;
  191. _this.model = model;
  192. // handling selection change
  193. if (isChangedDate(newSelectedDate, _this._controlValue)) {
  194. _this._controlValue = newSelectedDate;
  195. _this.onTouched();
  196. _this.onChange(_this._ngbDateAdapter.toModel(newSelectedDate));
  197. }
  198. // handling focus change
  199. if (isChangedDate(newFocusedDate, oldFocusedDate) && oldFocusedDate && model.focusVisible) {
  200. _this.focus();
  201. }
  202. cd.markForCheck();
  203. }));
  204. }
  205. Object.defineProperty(NgbDatepicker.prototype, "state", {
  206. /**
  207. * Returns the readonly public state of the datepicker
  208. *
  209. * @since 5.2.0
  210. */
  211. get: /**
  212. * Returns the readonly public state of the datepicker
  213. *
  214. * \@since 5.2.0
  215. * @return {?}
  216. */
  217. function () { return this._publicState; },
  218. enumerable: true,
  219. configurable: true
  220. });
  221. /**
  222. * Focuses on given date.
  223. */
  224. /**
  225. * Focuses on given date.
  226. * @param {?} date
  227. * @return {?}
  228. */
  229. NgbDatepicker.prototype.focusDate = /**
  230. * Focuses on given date.
  231. * @param {?} date
  232. * @return {?}
  233. */
  234. function (date) { this._service.focus(NgbDate.from(date)); };
  235. /**
  236. * Selects focused date.
  237. */
  238. /**
  239. * Selects focused date.
  240. * @return {?}
  241. */
  242. NgbDatepicker.prototype.focusSelect = /**
  243. * Selects focused date.
  244. * @return {?}
  245. */
  246. function () { this._service.focusSelect(); };
  247. /**
  248. * @return {?}
  249. */
  250. NgbDatepicker.prototype.focus = /**
  251. * @return {?}
  252. */
  253. function () {
  254. var _this = this;
  255. this._ngZone.onStable.asObservable().pipe(take(1)).subscribe((/**
  256. * @return {?}
  257. */
  258. function () {
  259. /** @type {?} */
  260. var elementToFocus = _this._elementRef.nativeElement.querySelector('div.ngb-dp-day[tabindex="0"]');
  261. if (elementToFocus) {
  262. elementToFocus.focus();
  263. }
  264. }));
  265. };
  266. /**
  267. * Navigates to the provided date.
  268. *
  269. * With the default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
  270. * If nothing or invalid date provided calendar will open current month.
  271. *
  272. * Use the `[startDate]` input as an alternative.
  273. */
  274. /**
  275. * Navigates to the provided date.
  276. *
  277. * With the default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
  278. * If nothing or invalid date provided calendar will open current month.
  279. *
  280. * Use the `[startDate]` input as an alternative.
  281. * @param {?=} date
  282. * @return {?}
  283. */
  284. NgbDatepicker.prototype.navigateTo = /**
  285. * Navigates to the provided date.
  286. *
  287. * With the default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
  288. * If nothing or invalid date provided calendar will open current month.
  289. *
  290. * Use the `[startDate]` input as an alternative.
  291. * @param {?=} date
  292. * @return {?}
  293. */
  294. function (date) {
  295. this._service.open(NgbDate.from(date ? date.day ? (/** @type {?} */ (date)) : tslib_1.__assign({}, date, { day: 1 }) : null));
  296. };
  297. /**
  298. * @return {?}
  299. */
  300. NgbDatepicker.prototype.ngAfterViewInit = /**
  301. * @return {?}
  302. */
  303. function () {
  304. var _this = this;
  305. this._ngZone.runOutsideAngular((/**
  306. * @return {?}
  307. */
  308. function () {
  309. /** @type {?} */
  310. var focusIns$ = fromEvent(_this._monthsEl.nativeElement, 'focusin');
  311. /** @type {?} */
  312. var focusOuts$ = fromEvent(_this._monthsEl.nativeElement, 'focusout');
  313. var nativeElement = _this._elementRef.nativeElement;
  314. // we're changing 'focusVisible' only when entering or leaving months view
  315. // and ignoring all focus events where both 'target' and 'related' target are day cells
  316. merge(focusIns$, focusOuts$)
  317. .pipe(filter((/**
  318. * @param {?} __0
  319. * @return {?}
  320. */
  321. function (_a) {
  322. var target = _a.target, relatedTarget = _a.relatedTarget;
  323. return !(hasClassName(target, 'ngb-dp-day') && hasClassName(relatedTarget, 'ngb-dp-day') &&
  324. nativeElement.contains((/** @type {?} */ (target))) && nativeElement.contains((/** @type {?} */ (relatedTarget))));
  325. })), takeUntil(_this._destroyed$))
  326. .subscribe((/**
  327. * @param {?} __0
  328. * @return {?}
  329. */
  330. function (_a) {
  331. var type = _a.type;
  332. return _this._ngZone.run((/**
  333. * @return {?}
  334. */
  335. function () { return _this._service.set({ focusVisible: type === 'focusin' }); }));
  336. }));
  337. }));
  338. };
  339. /**
  340. * @return {?}
  341. */
  342. NgbDatepicker.prototype.ngOnDestroy = /**
  343. * @return {?}
  344. */
  345. function () { this._destroyed$.next(); };
  346. /**
  347. * @return {?}
  348. */
  349. NgbDatepicker.prototype.ngOnInit = /**
  350. * @return {?}
  351. */
  352. function () {
  353. var _this = this;
  354. if (this.model === undefined) {
  355. /** @type {?} */
  356. var inputs_1 = {};
  357. ['dayTemplateData', 'displayMonths', 'markDisabled', 'firstDayOfWeek', 'navigation', 'minDate', 'maxDate',
  358. 'outsideDays']
  359. .forEach((/**
  360. * @param {?} name
  361. * @return {?}
  362. */
  363. function (name) { return inputs_1[name] = _this[name]; }));
  364. this._service.set(inputs_1);
  365. this.navigateTo(this.startDate);
  366. }
  367. };
  368. /**
  369. * @param {?} changes
  370. * @return {?}
  371. */
  372. NgbDatepicker.prototype.ngOnChanges = /**
  373. * @param {?} changes
  374. * @return {?}
  375. */
  376. function (changes) {
  377. var _this = this;
  378. /** @type {?} */
  379. var inputs = {};
  380. ['dayTemplateData', 'displayMonths', 'markDisabled', 'firstDayOfWeek', 'navigation', 'minDate', 'maxDate',
  381. 'outsideDays']
  382. .filter((/**
  383. * @param {?} name
  384. * @return {?}
  385. */
  386. function (name) { return name in changes; }))
  387. .forEach((/**
  388. * @param {?} name
  389. * @return {?}
  390. */
  391. function (name) { return inputs[name] = _this[name]; }));
  392. this._service.set(inputs);
  393. if ('startDate' in changes) {
  394. var _a = changes.startDate, currentValue = _a.currentValue, previousValue = _a.previousValue;
  395. if (isChangedMonth(previousValue, currentValue)) {
  396. this.navigateTo(this.startDate);
  397. }
  398. }
  399. };
  400. /**
  401. * @param {?} date
  402. * @return {?}
  403. */
  404. NgbDatepicker.prototype.onDateSelect = /**
  405. * @param {?} date
  406. * @return {?}
  407. */
  408. function (date) {
  409. this._service.focus(date);
  410. this._service.select(date, { emitEvent: true });
  411. };
  412. /**
  413. * @param {?} event
  414. * @return {?}
  415. */
  416. NgbDatepicker.prototype.onKeyDown = /**
  417. * @param {?} event
  418. * @return {?}
  419. */
  420. function (event) { this._keyboardService.processKey(event, this, this._calendar); };
  421. /**
  422. * @param {?} date
  423. * @return {?}
  424. */
  425. NgbDatepicker.prototype.onNavigateDateSelect = /**
  426. * @param {?} date
  427. * @return {?}
  428. */
  429. function (date) { this._service.open(date); };
  430. /**
  431. * @param {?} event
  432. * @return {?}
  433. */
  434. NgbDatepicker.prototype.onNavigateEvent = /**
  435. * @param {?} event
  436. * @return {?}
  437. */
  438. function (event) {
  439. switch (event) {
  440. case NavigationEvent.PREV:
  441. this._service.open(this._calendar.getPrev(this.model.firstDate, 'm', 1));
  442. break;
  443. case NavigationEvent.NEXT:
  444. this._service.open(this._calendar.getNext(this.model.firstDate, 'm', 1));
  445. break;
  446. }
  447. };
  448. /**
  449. * @param {?} fn
  450. * @return {?}
  451. */
  452. NgbDatepicker.prototype.registerOnChange = /**
  453. * @param {?} fn
  454. * @return {?}
  455. */
  456. function (fn) { this.onChange = fn; };
  457. /**
  458. * @param {?} fn
  459. * @return {?}
  460. */
  461. NgbDatepicker.prototype.registerOnTouched = /**
  462. * @param {?} fn
  463. * @return {?}
  464. */
  465. function (fn) { this.onTouched = fn; };
  466. /**
  467. * @param {?} disabled
  468. * @return {?}
  469. */
  470. NgbDatepicker.prototype.setDisabledState = /**
  471. * @param {?} disabled
  472. * @return {?}
  473. */
  474. function (disabled) { this._service.set({ disabled: disabled }); };
  475. /**
  476. * @param {?} value
  477. * @return {?}
  478. */
  479. NgbDatepicker.prototype.writeValue = /**
  480. * @param {?} value
  481. * @return {?}
  482. */
  483. function (value) {
  484. this._controlValue = NgbDate.from(this._ngbDateAdapter.fromModel(value));
  485. this._service.select(this._controlValue);
  486. };
  487. NgbDatepicker.decorators = [
  488. { type: Component, args: [{
  489. exportAs: 'ngbDatepicker',
  490. selector: 'ngb-datepicker',
  491. changeDetection: ChangeDetectionStrategy.OnPush,
  492. encapsulation: ViewEncapsulation.None,
  493. template: "\n <ng-template #dt let-date=\"date\" let-currentMonth=\"currentMonth\" let-selected=\"selected\" let-disabled=\"disabled\" let-focused=\"focused\">\n <div ngbDatepickerDayView\n [date]=\"date\"\n [currentMonth]=\"currentMonth\"\n [selected]=\"selected\"\n [disabled]=\"disabled\"\n [focused]=\"focused\">\n </div>\n </ng-template>\n\n <div class=\"ngb-dp-header\">\n <ngb-datepicker-navigation *ngIf=\"navigation !== 'none'\"\n [date]=\"model.firstDate\"\n [months]=\"model.months\"\n [disabled]=\"model.disabled\"\n [showSelect]=\"model.navigation === 'select'\"\n [prevDisabled]=\"model.prevDisabled\"\n [nextDisabled]=\"model.nextDisabled\"\n [selectBoxes]=\"model.selectBoxes\"\n (navigate)=\"onNavigateEvent($event)\"\n (select)=\"onNavigateDateSelect($event)\">\n </ngb-datepicker-navigation>\n </div>\n\n <div #months class=\"ngb-dp-months\" (keydown)=\"onKeyDown($event)\">\n <ng-template ngFor let-month [ngForOf]=\"model.months\" let-i=\"index\">\n <div class=\"ngb-dp-month\">\n <div *ngIf=\"navigation === 'none' || (displayMonths > 1 && navigation === 'select')\"\n class=\"ngb-dp-month-name\">\n {{ i18n.getMonthFullName(month.number, month.year) }} {{ i18n.getYearNumerals(month.year) }}\n </div>\n <ngb-datepicker-month-view\n [month]=\"month\"\n [dayTemplate]=\"dayTemplate || dt\"\n [showWeekdays]=\"showWeekdays\"\n [showWeekNumbers]=\"showWeekNumbers\"\n (select)=\"onDateSelect($event)\">\n </ngb-datepicker-month-view>\n </div>\n </ng-template>\n </div>\n\n <ng-template [ngTemplateOutlet]=\"footerTemplate\"></ng-template>\n ",
  494. providers: [NGB_DATEPICKER_VALUE_ACCESSOR, NgbDatepickerService],
  495. styles: ["ngb-datepicker{border:1px solid #dfdfdf;border-radius:.25rem;display:inline-block}ngb-datepicker-month-view{pointer-events:auto}ngb-datepicker.dropdown-menu{padding:0}.ngb-dp-body{z-index:1050}.ngb-dp-header{border-bottom:0;border-radius:.25rem .25rem 0 0;padding-top:.25rem;background-color:#f8f9fa;background-color:var(--light)}.ngb-dp-months{display:-ms-flexbox;display:flex}.ngb-dp-month{pointer-events:none}.ngb-dp-month-name{font-size:larger;height:2rem;line-height:2rem;text-align:center;background-color:#f8f9fa;background-color:var(--light)}.ngb-dp-month+.ngb-dp-month .ngb-dp-month-name,.ngb-dp-month+.ngb-dp-month .ngb-dp-week{padding-left:1rem}.ngb-dp-month:last-child .ngb-dp-week{padding-right:.25rem}.ngb-dp-month:first-child .ngb-dp-week{padding-left:.25rem}.ngb-dp-month .ngb-dp-week:last-child{padding-bottom:.25rem}"]
  496. }] }
  497. ];
  498. /** @nocollapse */
  499. NgbDatepicker.ctorParameters = function () { return [
  500. { type: NgbDatepickerService },
  501. { type: NgbCalendar },
  502. { type: NgbDatepickerI18n },
  503. { type: NgbDatepickerConfig },
  504. { type: NgbDatepickerKeyboardService },
  505. { type: ChangeDetectorRef },
  506. { type: ElementRef },
  507. { type: NgbDateAdapter },
  508. { type: NgZone }
  509. ]; };
  510. NgbDatepicker.propDecorators = {
  511. _monthsEl: [{ type: ViewChild, args: ['months', { static: true },] }],
  512. dayTemplate: [{ type: Input }],
  513. dayTemplateData: [{ type: Input }],
  514. displayMonths: [{ type: Input }],
  515. firstDayOfWeek: [{ type: Input }],
  516. footerTemplate: [{ type: Input }],
  517. markDisabled: [{ type: Input }],
  518. maxDate: [{ type: Input }],
  519. minDate: [{ type: Input }],
  520. navigation: [{ type: Input }],
  521. outsideDays: [{ type: Input }],
  522. showWeekdays: [{ type: Input }],
  523. showWeekNumbers: [{ type: Input }],
  524. startDate: [{ type: Input }],
  525. navigate: [{ type: Output }],
  526. dateSelect: [{ type: Output }],
  527. select: [{ type: Output }]
  528. };
  529. return NgbDatepicker;
  530. }());
  531. export { NgbDatepicker };
  532. if (false) {
  533. /** @type {?} */
  534. NgbDatepicker.prototype.model;
  535. /**
  536. * @type {?}
  537. * @private
  538. */
  539. NgbDatepicker.prototype._monthsEl;
  540. /**
  541. * @type {?}
  542. * @private
  543. */
  544. NgbDatepicker.prototype._controlValue;
  545. /**
  546. * @type {?}
  547. * @private
  548. */
  549. NgbDatepicker.prototype._destroyed$;
  550. /**
  551. * @type {?}
  552. * @private
  553. */
  554. NgbDatepicker.prototype._publicState;
  555. /**
  556. * The reference to a custom template for the day.
  557. *
  558. * Allows to completely override the way a day 'cell' in the calendar is displayed.
  559. *
  560. * See [`DayTemplateContext`](#/components/datepicker/api#DayTemplateContext) for the data you get inside.
  561. * @type {?}
  562. */
  563. NgbDatepicker.prototype.dayTemplate;
  564. /**
  565. * The callback to pass any arbitrary data to the template cell via the
  566. * [`DayTemplateContext`](#/components/datepicker/api#DayTemplateContext)'s `data` parameter.
  567. *
  568. * `current` is the month that is currently displayed by the datepicker.
  569. *
  570. * \@since 3.3.0
  571. * @type {?}
  572. */
  573. NgbDatepicker.prototype.dayTemplateData;
  574. /**
  575. * The number of months to display.
  576. * @type {?}
  577. */
  578. NgbDatepicker.prototype.displayMonths;
  579. /**
  580. * The first day of the week.
  581. *
  582. * With default calendar we use ISO 8601: 'weekday' is 1=Mon ... 7=Sun.
  583. * @type {?}
  584. */
  585. NgbDatepicker.prototype.firstDayOfWeek;
  586. /**
  587. * The reference to the custom template for the datepicker footer.
  588. *
  589. * \@since 3.3.0
  590. * @type {?}
  591. */
  592. NgbDatepicker.prototype.footerTemplate;
  593. /**
  594. * The callback to mark some dates as disabled.
  595. *
  596. * It is called for each new date when navigating to a different month.
  597. *
  598. * `current` is the month that is currently displayed by the datepicker.
  599. * @type {?}
  600. */
  601. NgbDatepicker.prototype.markDisabled;
  602. /**
  603. * The latest date that can be displayed or selected.
  604. *
  605. * If not provided, 'year' select box will display 10 years after the current month.
  606. * @type {?}
  607. */
  608. NgbDatepicker.prototype.maxDate;
  609. /**
  610. * The earliest date that can be displayed or selected.
  611. *
  612. * If not provided, 'year' select box will display 10 years before the current month.
  613. * @type {?}
  614. */
  615. NgbDatepicker.prototype.minDate;
  616. /**
  617. * Navigation type.
  618. *
  619. * * `"select"` - select boxes for month and navigation arrows
  620. * * `"arrows"` - only navigation arrows
  621. * * `"none"` - no navigation visible at all
  622. * @type {?}
  623. */
  624. NgbDatepicker.prototype.navigation;
  625. /**
  626. * The way of displaying days that don't belong to the current month.
  627. *
  628. * * `"visible"` - days are visible
  629. * * `"hidden"` - days are hidden, white space preserved
  630. * * `"collapsed"` - days are collapsed, so the datepicker height might change between months
  631. *
  632. * For the 2+ months view, days in between months are never shown.
  633. * @type {?}
  634. */
  635. NgbDatepicker.prototype.outsideDays;
  636. /**
  637. * If `true`, weekdays will be displayed.
  638. * @type {?}
  639. */
  640. NgbDatepicker.prototype.showWeekdays;
  641. /**
  642. * If `true`, week numbers will be displayed.
  643. * @type {?}
  644. */
  645. NgbDatepicker.prototype.showWeekNumbers;
  646. /**
  647. * The date to open calendar with.
  648. *
  649. * With the default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
  650. * If nothing or invalid date is provided, calendar will open with current month.
  651. *
  652. * You could use `navigateTo(date)` method as an alternative.
  653. * @type {?}
  654. */
  655. NgbDatepicker.prototype.startDate;
  656. /**
  657. * An event emitted right before the navigation happens and displayed month changes.
  658. *
  659. * See [`NgbDatepickerNavigateEvent`](#/components/datepicker/api#NgbDatepickerNavigateEvent) for the payload info.
  660. * @type {?}
  661. */
  662. NgbDatepicker.prototype.navigate;
  663. /**
  664. * An event emitted when user selects a date using keyboard or mouse.
  665. *
  666. * The payload of the event is currently selected `NgbDate`.
  667. *
  668. * \@since 5.2.0
  669. * @type {?}
  670. */
  671. NgbDatepicker.prototype.dateSelect;
  672. /**
  673. * An event emitted when user selects a date using keyboard or mouse.
  674. *
  675. * The payload of the event is currently selected `NgbDate`.
  676. *
  677. * Please use 'dateSelect' output instead, this will be deprecated in version 6.0 due to collision with native
  678. * 'select' event.
  679. * @type {?}
  680. */
  681. NgbDatepicker.prototype.select;
  682. /** @type {?} */
  683. NgbDatepicker.prototype.onChange;
  684. /** @type {?} */
  685. NgbDatepicker.prototype.onTouched;
  686. /**
  687. * @type {?}
  688. * @private
  689. */
  690. NgbDatepicker.prototype._service;
  691. /**
  692. * @type {?}
  693. * @private
  694. */
  695. NgbDatepicker.prototype._calendar;
  696. /** @type {?} */
  697. NgbDatepicker.prototype.i18n;
  698. /**
  699. * @type {?}
  700. * @private
  701. */
  702. NgbDatepicker.prototype._keyboardService;
  703. /**
  704. * @type {?}
  705. * @private
  706. */
  707. NgbDatepicker.prototype._elementRef;
  708. /**
  709. * @type {?}
  710. * @private
  711. */
  712. NgbDatepicker.prototype._ngbDateAdapter;
  713. /**
  714. * @type {?}
  715. * @private
  716. */
  717. NgbDatepicker.prototype._ngZone;
  718. }
  719. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwLyIsInNvdXJjZXMiOlsiZGF0ZXBpY2tlci9kYXRlcGlja2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQy9DLE9BQU8sRUFBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3ZELE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixLQUFLLEVBQ0wsTUFBTSxFQUlOLE1BQU0sRUFFTixXQUFXLEVBQ1gsU0FBUyxFQUNULGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXVCLGlCQUFpQixFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDdkUsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxZQUFZLENBQUM7QUFDbkMsT0FBTyxFQUEwQixvQkFBb0IsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQ25GLE9BQU8sRUFBQyw0QkFBNEIsRUFBQyxNQUFNLCtCQUErQixDQUFDO0FBQzNFLE9BQU8sRUFBc0IsZUFBZSxFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFFN0UsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDeEQsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLDZCQUE2QixDQUFDO0FBRTNELE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ3BELE9BQU8sRUFBQyxhQUFhLEVBQUUsY0FBYyxFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFDakUsT0FBTyxFQUFD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Ozs7SUFDbkYsb0NBQTRDOzs7OztJQUFFLHdDQUE0Qzs7Ozs7SUFDMUYsZ0NBQXVCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtmcm9tRXZlbnQsIG1lcmdlLCBTdWJqZWN0fSBmcm9tICdyeGpzJztcbmltcG9ydCB7ZmlsdGVyLCB0YWtlLCB0YWtlVW50aWx9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0NvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtOZ2JDYWxlbmRhcn0gZnJvbSAnLi9uZ2ItY2FsZW5kYXInO1xuaW1wb3J0IHtOZ2JEYXRlfSBmcm9tICcuL25nYi1kYXRlJztcbmltcG9ydCB7RGF0ZXBpY2tlclNlcnZpY2VJbnB1dHMsIE5nYkRhdGVwaWNrZXJTZXJ2aWNlfSBmcm9tICcuL2RhdGVwaWNrZXItc2VydmljZSc7XG5pbXBvcnQge05nYkRhdGVwaWNrZXJLZXlib2FyZFNlcnZpY2V9IGZyb20gJy4vZGF0ZXBpY2tlci1rZXlib2FyZC1zZXJ2aWNlJztcbmltcG9ydCB7RGF0ZXBpY2tlclZpZXdNb2RlbCwgTmF2aWdhdGlvbkV2ZW50fSBmcm9tICcuL2RhdGVwaWNrZXItdmlldy1tb2RlbCc7XG5pbXBvcnQge0RheVRlbXBsYXRlQ29udGV4dH0gZnJvbSAnLi9kYXRlcGlja2VyLWRheS10ZW1wbGF0ZS1jb250ZXh0JztcbmltcG9ydCB7TmdiRGF0ZXBpY2tlckNvbmZpZ30gZnJvbSAnLi9kYXRlcGlja2VyLWNvbmZpZyc7XG5pbXBvcnQge05nYkRhdGVBZGFwdGVyfSBmcm9tICcuL2FkYXB0ZXJzL25nYi1kYXRlLWFkYXB0ZXInO1xuaW1wb3J0IHtOZ2JEYXRlU3RydWN0fSBmcm9tICcuL25nYi1kYXRlLXN0cnVjdCc7XG5pbXBvcnQge05nYkRhdGVwaWNrZXJJMThufSBmcm9tICcuL2RhdGVwaWNrZXItaTE4bic7XG5pbXBvcnQge2lzQ2hhbmdlZERhdGUsIGlzQ2hhbmdlZE1vbnRofSBmcm9tICcuL2RhdGVwaWNrZXItdG9vbHMnO1xuaW1wb3J0IHtoYXNDbGFzc05hbWV9IGZyb20gJy4uL3V0aWwvdXRpbCc7XG5cbmNvbnN0IE5HQl9EQVRFUElDS0VSX1ZBTFVFX0FDQ0VTU09SID0ge1xuICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTmdiRGF0ZXBpY2tlciksXG4gIG11bHRpOiB0cnVlXG59O1xuXG4vKipcbiAqIEFuIGV2ZW50IGVtaXR0ZWQgcmlnaHQgYmVmb3JlIHRoZSBuYXZpZ2F0aW9uIGhhcHBlbnMgYW5kIHRoZSBtb250aCBkaXNwbGF5ZWQgYnkgdGhlIGRhdGVwaWNrZXIgY2hhbmdlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOZ2JEYXRlcGlja2VyTmF2aWdhdGVFdmVudCB7XG4gIC8qKlxuICAgKiBUaGUgY3VycmVudGx5IGRpc3BsYXllZCBtb250aC5cbiAgICovXG4gIGN1cnJlbnQ6IHt5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXJ9O1xuXG4gIC8qKlxuICAgKiBUaGUgbW9udGggd2UncmUgbmF2aWdhdGluZyB0by5cbiAgICovXG4gIG5leHQ6IHt5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXJ9O1xuXG4gIC8qKlxuICAgKiBDYWxsaW5nIHRoaXMgZnVuY3Rpb24gd2lsbCBwcmV2ZW50IG5hdmlnYXRpb24gZnJvbSBoYXBwZW5pbmcuXG4gICAqXG4gICAqIEBzaW5jZSA0LjEuMFxuICAgKi9cbiAgcHJldmVudERlZmF1bHQ6ICgpID0+IHZvaWQ7XG59XG5cbi8qKlxuICogQW4gaW50ZXJmYWNlIHRoYXQgcmVwcmVzZW50cyB0aGUgcmVhZG9ubHkgcHVibGljIHN0YXRlIG9mIHRoZSBkYXRlcGlja2VyLlxuICpcbiAqIEFjY2Vzc2libGUgdmlhIHRoZSBgZGF0ZXBpY2tlci5zdGF0ZWAgZ2V0dGVyXG4gKlxuICogQHNpbmNlIDUuMi4wXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmdiRGF0ZXBpY2tlclN0YXRlIHtcbiAgLyoqXG4gICAqIFRoZSBlYXJsaWVzdCBkYXRlIHRoYXQgY2FuIGJlIGRpc3BsYXllZCBvciBzZWxlY3RlZFxuICAgKi9cbiAgcmVhZG9ubHkgbWluRGF0ZTogTmdiRGF0ZTtcblxuICAvKipcbiAgICogVGhlIGxhdGVzdCBkYXRlIHRoYXQgY2FuIGJlIGRpc3BsYXllZCBvciBzZWxlY3RlZFxuICAgKi9cbiAgcmVhZG9ubHkgbWF4RGF0ZTogTmdiRGF0ZTtcblxuICAvKipcbiAgICogVGhlIGZpcnN0IHZpc2libGUgZGF0ZSBvZiBjdXJyZW50bHkgZGlzcGxheWVkIG1vbnRoc1xuICAgKi9cbiAgcmVhZG9ubHkgZmlyc3REYXRlOiBOZ2JEYXRlO1xuXG4gIC8qKlxuICAgKiBUaGUgbGFzdCB2aXNpYmxlIGRhdGUgb2YgY3VycmVudGx5IGRpc3BsYXllZCBtb250aHNcbiAgICovXG4gIHJlYWRvbmx5IGxhc3REYXRlOiBOZ2JEYXRlO1xuXG4gIC8qKlxuICAgKiBUaGUgZGF0ZSBjdXJyZW50bHkgZm9jdXNlZCBieSB0aGUgZGF0ZXBpY2tlclxuICAgKi9cbiAgcmVhZG9ubHkgZm9jdXNlZERhdGU6IE5nYkRhdGU7XG59XG5cbi8qKlxuICogQSBoaWdobHkgY29uZmlndXJhYmxlIGNvbXBvbmVudCB0aGF0IGhlbHBzIHlvdSB3aXRoIHNlbGVjdGluZyBjYWxlbmRhciBkYXRlcy5cbiAqXG4gKiBgTmdiRGF0ZXBpY2tlcmAgaXMgbWVhbnQgdG8gYmUgZGlzcGxheWVkIGlubGluZSBvbiBhIHBhZ2Ugb3IgcHV0IGluc2lkZSBhIHBvcHVwLlxuICovXG5AQ29tcG9uZW50KHtcbiAgZXhwb3J0QXM6ICduZ2JEYXRlcGlja2VyJyxcbiAgc2VsZWN0b3I6ICduZ2ItZGF0ZXBpY2tlcicsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBzdHlsZVVybHM6IFsnLi9kYXRlcGlja2VyLnNjc3MnXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8bmctdGVtcGxhdGUgI2R0IGxldC1kYXRlPVwiZGF0ZVwiIGxldC1jdXJyZW50TW9udGg9XCJjdXJyZW50TW9udGhcIiBsZXQtc2VsZWN0ZWQ9XCJzZWxlY3RlZFwiIGxldC1kaXNhYmxlZD1cImRpc2FibGVkXCIgbGV0LWZvY3VzZWQ9XCJmb2N1c2VkXCI+XG4gICAgICA8ZGl2IG5nYkRhdGVwaWNrZXJEYXlWaWV3XG4gICAgICAgIFtkYXRlXT1cImRhdGVcIlxuICAgICAgICBbY3VycmVudE1vbnRoXT1cImN1cnJlbnRNb250aFwiXG4gICAgICAgIFtzZWxlY3RlZF09XCJzZWxlY3RlZFwiXG4gICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgIFtmb2N1c2VkXT1cImZvY3VzZWRcIj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8ZGl2IGNsYXNzPVwibmdiLWRwLWhlYWRlclwiPlxuICAgICAgPG5nYi1kYXRlcGlja2VyLW5hdmlnYXRpb24gKm5nSWY9XCJuYXZpZ2F0aW9uICE9PSAnbm9uZSdcIlxuICAgICAgICBbZGF0ZV09XCJtb2RlbC5maXJzdERhdGVcIlxuICAgICAgICBbbW9udGhzXT1cIm1vZGVsLm1vbnRoc1wiXG4gICAgICAgIFtkaXNhYmxlZF09XCJtb2RlbC5kaXNhYmxlZFwiXG4gICAgICAgIFtzaG93U2VsZWN0XT1cIm1vZGVsLm5hdmlnYXRpb24gPT09ICdzZWxlY3QnXCJcbiAgICAgICAgW3ByZXZEaXNhYmxlZF09XCJtb2RlbC5wcmV2RGlzYWJsZWRcIlxuICAgICAgICBbbmV4dERpc2FibGVkXT1cIm1vZGVsLm5leHREaXNhYmxlZFwiXG4gICAgICAgIFtzZWxlY3RCb3hlc109XCJtb2RlbC5zZWxlY3RCb3hlc1wiXG4gICAgICAgIChuYXZpZ2F0ZSk9XCJvbk5hdmlnYXRlRXZlbnQoJGV2ZW50KVwiXG4gICAgICAgIChzZWxlY3QpPVwib25OYXZpZ2F0ZURhdGVTZWxlY3QoJGV2ZW50KVwiPlxuICAgICAgPC9uZ2ItZGF0ZXBpY2tlci1uYXZpZ2F0aW9uPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiAjbW9udGhzIGNsYXNzPVwibmdiLWRwLW1vbnRoc1wiIChrZXlkb3duKT1cIm9uS2V5RG93bigkZXZlbnQpXCI+XG4gICAgICA8bmctdGVtcGxhdGUgbmdGb3IgbGV0LW1vbnRoIFtuZ0Zvck9mXT1cIm1vZGVsLm1vbnRoc1wiIGxldC1pPVwiaW5kZXhcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm5nYi1kcC1tb250aFwiPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJuYXZpZ2F0aW9uID09PSAnbm9uZScgfHwgKGRpc3BsYXlNb250aHMgPiAxICYmIG5hdmlnYXRpb24gPT09ICdzZWxlY3QnKVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJuZ2ItZHAtbW9udGgtbmFtZVwiPlxuICAgICAgICAgICAge3sgaTE4bi5nZXRNb250aEZ1bGxOYW1lKG1vbnRoLm51bWJlciwgbW9udGgueWVhcikgfX0ge3sgaTE4bi5nZXRZZWFyTnVtZXJhbHMobW9udGgueWVhcikgfX1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8bmdiLWRhdGVwaWNrZXItbW9udGgtdmlld1xuICAgICAgICAgICAgW21vbnRoXT1cIm1vbnRoXCJcbiAgICAgICAgICAgIFtkYXlUZW1wbGF0ZV09XCJkYXlUZW1wbGF0ZSB8fCBkdFwiXG4gICAgICAgICAgICBbc2hvd1dlZWtkYXlzXT1cInNob3dXZWVrZGF5c1wiXG4gICAgICAgICAgICBbc2hvd1dlZWtOdW1iZXJzXT1cInNob3dXZWVrTnVtYmVyc1wiXG4gICAgICAgICAgICAoc2VsZWN0KT1cIm9uRGF0ZVNlbGVjdCgkZXZlbnQpXCI+XG4gICAgICAgICAgPC9uZ2ItZGF0ZXBpY2tlci1tb250aC12aWV3PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9kaXY+XG5cbiAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiZm9vdGVyVGVtcGxhdGVcIj48L25nLXRlbXBsYXRlPlxuICBgLFxuICBwcm92aWRlcnM6IFtOR0JfREFURVBJQ0tFUl9WQUxVRV9BQ0NFU1NPUiwgTmdiRGF0ZXBpY2tlclNlcnZpY2VdXG59KVxuZXhwb3J0IGNsYXNzIE5nYkRhdGVwaWNrZXIgaW1wbGVtZW50cyBPbkRlc3Ryb3ksXG4gICAgT25DaGFuZ2VzLCBPbkluaXQsIEFmdGVyVmlld0luaXQsIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgbW9kZWw6IERhdGVwaWNrZXJWaWV3TW9kZWw7XG5cbiAgQFZpZXdDaGlsZCgnbW9udGhzJywge3N0YXRpYzogdHJ1ZX0pIHByaXZhdGUgX21vbnRoc0VsOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcbiAgcHJpdmF0ZSBfY29udHJvbFZhbHVlOiBOZ2JEYXRlO1xuICBwcml2YXRlIF9kZXN0cm95ZWQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBfcHVibGljU3RhdGU6IE5nYkRhdGVwaWNrZXJTdGF0ZSA9IDxhbnk+e307XG5cbiAgLyoqXG4gICAqIFRoZSByZWZlcmVuY2UgdG8gYSBjdXN0b20gdGVtcGxhdGUgZm9yIHRoZSBkYXkuXG4gICAqXG4gICAqIEFsbG93cyB0byBjb21wbGV0ZWx5IG92ZXJyaWRlIHRoZSB3YXkgYSBkYXkgJ2NlbGwnIGluIHRoZSBjYWxlbmRhciBpcyBkaXNwbGF5ZWQuXG4gICAqXG4gICAqIFNlZSBbYERheVRlbXBsYXRlQ29udGV4dGBdKCMvY29tcG9uZW50cy9kYXRlcGlja2VyL2FwaSNEYXlUZW1wbGF0ZUNvbnRleHQpIGZvciB0aGUgZGF0YSB5b3UgZ2V0IGluc2lkZS5cbiAgICovXG4gIEBJbnB1dCgpIGRheVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxEYXlUZW1wbGF0ZUNvbnRleHQ+O1xuXG4gIC8qKlxuICAgKiBUaGUgY2FsbGJhY2sgdG8gcGFzcyBhbnkgYXJiaXRyYXJ5IGRhdGEgdG8gdGhlIHRlbXBsYXRlIGNlbGwgdmlhIHRoZVxuICAgKiBbYERheVRlbXBsYXRlQ29udGV4dGBdKCMvY29tcG9uZW50cy9kYXRlcGlja2VyL2FwaSNEYXlUZW1wbGF0ZUNvbnRleHQpJ3MgYGRhdGFgIHBhcmFtZXRlci5cbiAgICpcbiAgICogYGN1cnJlbnRgIGlzIHRoZSBtb250aCB0aGF0IGlzIGN1cnJlbnRseSBkaXNwbGF5ZWQgYnkgdGhlIGRhdGVwaWNrZXIuXG4gICAqXG4gICAqIEBzaW5jZSAzLjMuMFxuICAgKi9cbiAgQElucHV0KCkgZGF5VGVtcGxhdGVEYXRhOiAoZGF0ZTogTmdiRGF0ZSwgY3VycmVudDoge3llYXI6IG51bWJlciwgbW9udGg6IG51bWJlcn0pID0+IGFueTtcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBtb250aHMgdG8gZGlzcGxheS5cbiAgICovXG4gIEBJbnB1dCgpIGRpc3BsYXlNb250aHM6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGZpcnN0IGRheSBvZiB0aGUgd2Vlay5cbiAgICpcbiAgICogV2l0aCBkZWZhdWx0IGNhbGVuZGFyIHdlIHVzZSBJU08gODYwMTogJ3dlZWtkYXknIGlzIDE9TW9uIC4uLiA3PVN1bi5cbiAgICovXG4gIEBJbnB1dCgpIGZpcnN0RGF5T2ZXZWVrOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSByZWZlcmVuY2UgdG8gdGhlIGN1c3RvbSB0ZW1wbGF0ZSBmb3IgdGhlIGRhdGVwaWNrZXIgZm9vdGVyLlxuICAgKlxuICAgKiBAc2luY2UgMy4zLjBcbiAgICovXG4gIEBJbnB1dCgpIGZvb3RlclRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIC8qKlxuICAgKiBUaGUgY2FsbGJhY2sgdG8gbWFyayBzb21lIGRhdGVzIGFzIGRpc2FibGVkLlxuICAgKlxuICAgKiBJdCBpcyBjYWxsZWQgZm9yIGVhY2ggbmV3IGRhdGUgd2hlbiBuYXZpZ2F0aW5nIHRvIGEgZGlmZmVyZW50IG1vbnRoLlxuICAgKlxuICAgKiBgY3VycmVudGAgaXMgdGhlIG1vbnRoIHRoYXQgaXMgY3VycmVudGx5IGRpc3BsYXllZCBieSB0aGUgZGF0ZXBpY2tlci5cbiAgICovXG4gIEBJbnB1dCgpIG1hcmtEaXNhYmxlZDogKGRhdGU6IE5nYkRhdGUsIGN1cnJlbnQ6IHt5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXJ9KSA9PiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgbGF0ZXN0IGRhdGUgdGhhdCBjYW4gYmUgZGlzcGxheWVkIG9yIHNlbGVjdGVkLlxuICAgKlxuICAgKiBJZiBub3QgcHJvdmlkZWQsICd5ZWFyJyBzZWxlY3QgYm94IHdpbGwgZGlzcGxheSAxMCB5ZWFycyBhZnRlciB0aGUgY3VycmVudCBtb250aC5cbiAgICovXG4gIEBJbnB1dCgpIG1heERhdGU6IE5nYkRhdGVTdHJ1Y3Q7XG5cbiAgLyoqXG4gICAqIFRoZSBlYXJsaWVzdCBkYXRlIHRoYXQgY2FuIGJlIGRpc3BsYXllZCBvciBzZWxlY3RlZC5cbiAgICpcbiAgICogSWYgbm90IHByb3ZpZGVkLCAneWVhcicgc2VsZWN0IGJveCB3aWxsIGRpc3BsYXkgMTAgeWVhcnMgYmVmb3JlIHRoZSBjdXJyZW50IG1vbnRoLlxuICAgKi9cbiAgQElucHV0KCkgbWluRGF0ZTogTmdiRGF0ZVN0cnVjdDtcblxuICAvKipcbiAgICogTmF2aWdhdGlvbiB0eXBlLlxuICAgKlxuICAgKiAqIGBcInNlbGVjdFwiYCAtIHNlbGVjdCBib3hlcyBmb3IgbW9udGggYW5kIG5hdmlnYXRpb24gYXJyb3dzXG4gICAqICogYFwiYXJyb3dzXCJgIC0gb25seSBuYXZpZ2F0aW9uIGFycm93c1xuICAgKiAqIGBcIm5vbmVcImAgLSBubyBuYXZpZ2F0aW9uIHZpc2libGUgYXQgYWxsXG4gICAqL1xuICBASW5wdXQoKSBuYXZpZ2F0aW9uOiAnc2VsZWN0JyB8ICdhcnJvd3MnIHwgJ25vbmUnO1xuXG4gIC8qKlxuICAgKiBUaGUgd2F5IG9mIGRpc3BsYXlpbmcgZGF5cyB0aGF0IGRvbid0IGJlbG9uZyB0byB0aGUgY3VycmVudCBtb250aC5cbiAgICpcbiAgICogKiBgXCJ2aXNpYmxlXCJgIC0gZGF5cyBhcmUgdmlzaWJsZVxuICAgKiAqIGBcImhpZGRlblwiYCAtIGRheXMgYXJlIGhpZGRlbiwgd2hpdGUgc3BhY2UgcHJlc2VydmVkXG4gICAqICogYFwiY29sbGFwc2VkXCJgIC0gZGF5cyBhcmUgY29sbGFwc2VkLCBzbyB0aGUgZGF0ZXBpY2tlciBoZWlnaHQgbWlnaHQgY2hhbmdlIGJldHdlZW4gbW9udGhzXG4gICAqXG4gICAqIEZvciB0aGUgMisgbW9udGhzIHZpZXcsIGRheXMgaW4gYmV0d2VlbiBtb250aHMgYXJlIG5ldmVyIHNob3duLlxuICAgKi9cbiAgQElucHV0KCkgb3V0c2lkZURheXM6ICd2aXNpYmxlJyB8ICdjb2xsYXBzZWQnIHwgJ2hpZGRlbic7XG5cbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgd2Vla2RheXMgd2lsbCBiZSBkaXNwbGF5ZWQuXG4gICAqL1xuICBASW5wdXQoKSBzaG93V2Vla2RheXM6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgd2VlayBudW1iZXJzIHdpbGwgYmUgZGlzcGxheWVkLlxuICAgKi9cbiAgQElucHV0KCkgc2hvd1dlZWtOdW1iZXJzOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgZGF0ZSB0byBvcGVuIGNhbGVuZGFyIHdpdGguXG4gICAqXG4gICAqIFdpdGggdGhlIGRlZmF1bHQgY2FsZW5kYXIgd2UgdXNlIElTTyA4NjAxOiAnbW9udGgnIGlzIDE9SmFuIC4uLiAxMj1EZWMuXG4gICAqIElmIG5vdGhpbmcgb3IgaW52YWxpZCBkYXRlIGlzIHByb3ZpZGVkLCBjYWxlbmRhciB3aWxsIG9wZW4gd2l0aCBjdXJyZW50IG1vbnRoLlxuICAgKlxuICAgKiBZb3UgY291bGQgdXNlIGBuYXZpZ2F0ZVRvKGRhdGUpYCBtZXRob2QgYXMgYW4gYWx0ZXJuYXRpdmUuXG4gICAqL1xuICBASW5wdXQoKSBzdGFydERhdGU6IHt5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIsIGRheT86IG51bWJlcn07XG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGVtaXR0ZWQgcmlnaHQgYmVmb3JlIHRoZSBuYXZpZ2F0aW9uIGhhcHBlbnMgYW5kIGRpc3BsYXllZCBtb250aCBjaGFuZ2VzLlxuICAgKlxuICAgKiBTZWUgW2BOZ2JEYXRlcGlja2VyTmF2aWdhdGVFdmVudGBdKCMvY29tcG9uZW50cy9kYXRlcGlja2VyL2FwaSNOZ2JEYXRlcGlja2VyTmF2aWdhdGVFdmVudCkgZm9yIHRoZSBwYXlsb2FkIGluZm8uXG4gICAqL1xuICBAT3V0cHV0KCkgbmF2aWdhdGUgPSBuZXcgRXZlbnRFbWl0dGVyPE5nYkRhdGVwaWNrZXJOYXZpZ2F0ZUV2ZW50PigpO1xuXG4gIC8qKlxuICAgKiBBbiBldmVudCBlbWl0dGVkIHdoZW4gdXNlciBzZWxlY3RzIGEgZGF0ZSB1c2luZyBrZXlib2FyZCBvciBtb3VzZS5cbiAgICpcbiAgICogVGhlIHBheWxvYWQgb2YgdGhlIGV2ZW50IGlzIGN1cnJlbnRseSBzZWxlY3RlZCBgTmdiRGF0ZWAuXG4gICAqXG4gICAqIEBzaW5jZSA1LjIuMFxuICAgKi9cbiAgQE91dHB1dCgpIGRhdGVTZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPE5nYkRhdGU+KCk7XG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGVtaXR0ZWQgd2hlbiB1c2VyIHNlbGVjdHMgYSBkYXRlIHVzaW5nIGtleWJvYXJkIG9yIG1vdXNlLlxuICAgKlxuICAgKiBUaGUgcGF5bG9hZCBvZiB0aGUgZXZlbnQgaXMgY3VycmVudGx5IHNlbGVjdGVkIGBOZ2JEYXRlYC5cbiAgICpcbiAgICogUGxlYXNlIHVzZSAnZGF0ZVNlbGVjdCcgb3V0cHV0IGluc3RlYWQsIHRoaXMgd2lsbCBiZSBkZXByZWNhdGVkIGluIHZlcnNpb24gNi4wIGR1ZSB0byBjb2xsaXNpb24gd2l0aCBuYXRpdmVcbiAgICogJ3NlbGVjdCcgZXZlbnQuXG4gICAqL1xuICBAT3V0cHV0KCkgc2VsZWN0ID0gdGhpcy5kYXRlU2VsZWN0O1xuXG4gIG9uQ2hhbmdlID0gKF86IGFueSkgPT4ge307XG4gIG9uVG91Y2hlZCA9ICgpID0+IHt9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHJpdmF0ZSBfc2VydmljZTogTmdiRGF0ZXBpY2tlclNlcnZpY2UsIHByaXZhdGUgX2NhbGVuZGFyOiBOZ2JDYWxlbmRhciwgcHVibGljIGkxOG46IE5nYkRhdGVwaWNrZXJJMThuLFxuICAgICAgY29uZmlnOiBOZ2JEYXRlcGlja2VyQ29uZmlnLCBwcml2YXRlIF9rZXlib2FyZFNlcnZpY2U6IE5nYkRhdGVwaWNrZXJLZXlib2FyZFNlcnZpY2UsIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICAgIHByaXZhdGUgX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LCBwcml2YXRlIF9uZ2JEYXRlQWRhcHRlcjogTmdiRGF0ZUFkYXB0ZXI8YW55PixcbiAgICAgIHByaXZhdGUgX25nWm9uZTogTmdab25lKSB7XG4gICAgWydkYXlUZW1wbGF0ZScsICdkYXlUZW1wbGF0ZURhdGEnLCAnZGlzcGxheU1vbnRocycsICdmaXJzdERheU9mV2VlaycsICdmb290ZXJUZW1wbGF0ZScsICdtYXJrRGlzYWJsZWQnLCAnbWluRGF0ZScsXG4gICAgICdtYXhEYXRlJywgJ25hdmlnYXRpb24nLCAnb3V0c2lkZURheXMnLCAnc2hvd1dlZWtkYXlzJywgJ3Nob3dXZWVrTnVtYmVycycsICdzdGFydERhdGUnXVxuICAgICAgICAuZm9yRWFjaChpbnB1dCA9PiB0aGlzW2lucHV0XSA9IGNvbmZpZ1tpbnB1dF0pO1xuXG4gICAgX3NlcnZpY2UuZGF0ZVNlbGVjdCQucGlwZSh0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkJCkpLnN1YnNjcmliZShkYXRlID0+IHsgdGhpcy5kYXRlU2VsZWN0LmVtaXQoZGF0ZSk7IH0pO1xuXG4gICAgX3NlcnZpY2UubW9kZWwkLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCQpKS5zdWJzY3JpYmUobW9kZWwgPT4ge1xuICAgICAgY29uc3QgbmV3RGF0ZSA9IG1vZGVsLmZpcnN0RGF0ZTtcbiAgICAgIGNvbnN0IG9sZERhdGUgPSB0aGlzLm1vZGVsID8gdGhpcy5tb2RlbC5maXJzdERhdGUgOiBudWxsO1xuXG4gICAgICAvLyB1cGRhdGUgcHVibGljIHN0YXRlXG4gICAgICB0aGlzLl9wdWJsaWNTdGF0ZSA9IHtcbiAgICAgICAgbWF4RGF0ZTogbW9kZWwubWF4RGF0ZSxcbiAgICAgICAgbWluRGF0ZTogbW9kZWwubWluRGF0ZSxcbiAgICAgICAgZmlyc3REYXRlOiBtb2RlbC5maXJzdERhdGUsXG4gICAgICAgIGxhc3REYXRlOiBtb2RlbC5sYXN0RGF0ZSxcbiAgICAgICAgZm9jdXNlZERhdGU6IG1vZGVsLmZvY3VzRGF0ZVxuICAgICAgfTtcblxuICAgICAgbGV0IG5hdmlnYXRpb25QcmV2ZW50ZWQgPSBmYWxzZTtcbiAgICAgIC8vIGVtaXR0aW5nIG5hdmlnYXRpb24gZXZlbnQgaWYgdGhlIGZpcnN0IG1vbnRoIGNoYW5nZXNcbiAgICAgIGlmICghbmV3RGF0ZS5lcXVhbHMob2xkRGF0ZSkpIHtcbiAgICAgICAgdGhpcy5uYXZpZ2F0ZS5lbWl0KHtcbiAgICAgICAgICBjdXJyZW50OiBvbGREYXRlID8ge3llYXI6IG9sZERhdGUueWVhciwgbW9udGg6IG9sZERhdGUubW9udGh9IDogbnVsbCxcbiAgICAgICAgICBuZXh0OiB7eWVhcjogbmV3RGF0ZS55ZWFyLCBtb250aDogbmV3RGF0ZS5tb250aH0sXG4gICAgICAgICAgcHJldmVudERlZmF1bHQ6ICgpID0+IG5hdmlnYXRpb25QcmV2ZW50ZWQgPSB0cnVlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGNhbid0IHByZXZlbnQgdGhlIHZlcnkgZmlyc3QgbmF2aWdhdGlvblxuICAgICAgICBpZiAobmF2aWdhdGlvblByZXZlbnRlZCAmJiBvbGREYXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5fc2VydmljZS5vcGVuKG9sZERhdGUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBuZXdTZWxlY3RlZERhdGUgPSBtb2RlbC5zZWxlY3RlZERhdGU7XG4gICAgICBjb25zdCBuZXdGb2N1c2VkRGF0ZSA9IG1vZGVsLmZvY3VzRGF0ZTtcbiAgICAgIGNvbnN0IG9sZEZvY3VzZWREYXRlID0gdGhpcy5tb2RlbCA/IHRoaXMubW9kZWwuZm9jdXNEYXRlIDogbnVsbDtcblxuICAgICAgdGhpcy5tb2RlbCA9IG1vZGVsO1xuXG4gICAgICAvLyBoYW5kbGluZyBzZWxlY3Rpb24gY2hhbmdlXG4gICAgICBpZiAoaXNDaGFuZ2VkRGF0ZShuZXdTZWxlY3RlZERhdGUsIHRoaXMuX2NvbnRyb2xWYWx1ZSkpIHtcbiAgICAgICAgdGhpcy5fY29udHJvbFZhbHVlID0gbmV3U2VsZWN0ZWREYXRlO1xuICAgICAgICB0aGlzLm9uVG91Y2hlZCgpO1xuICAgICAgICB0aGlzLm9uQ2hhbmdlKHRoaXMuX25nYkRhdGVBZGFwdGVyLnRvTW9kZWwobmV3U2VsZWN0ZWREYXRlKSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGhhbmRsaW5nIGZvY3VzIGNoYW5nZVxuICAgICAgaWYgKGlzQ2hhbmdlZERhdGUobmV3Rm9jdXNlZERhdGUsIG9sZEZvY3VzZWREYXRlKSAmJiBvbGRGb2N1c2VkRGF0ZSAmJiBtb2RlbC5mb2N1c1Zpc2libGUpIHtcbiAgICAgICAgdGhpcy5mb2N1cygpO1xuICAgICAgfVxuXG4gICAgICBjZC5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiAgUmV0dXJucyB0aGUgcmVhZG9ubHkgcHVibGljIHN0YXRlIG9mIHRoZSBkYXRlcGlja2VyXG4gICAqXG4gICAqIEBzaW5jZSA1LjIuMFxuICAgKi9cbiAgZ2V0IHN0YXRlKCk6IE5nYkRhdGVwaWNrZXJTdGF0ZSB7IHJldHVybiB0aGlzLl9wdWJsaWNTdGF0ZTsgfVxuXG4gIC8qKlxuICAgKiAgRm9jdXNlcyBvbiBnaXZlbiBkYXRlLlxuICAgKi9cbiAgZm9jdXNEYXRlKGRhdGU6IE5nYkRhdGVTdHJ1Y3QpOiB2b2lkIHsgdGhpcy5fc2VydmljZS5mb2N1cyhOZ2JEYXRlLmZyb20oZGF0ZSkpOyB9XG5cbiAgLyoqXG4gICAqICBTZWxlY3RzIGZvY3VzZWQgZGF0ZS5cbiAgICovXG4gIGZvY3VzU2VsZWN0KCk6IHZvaWQgeyB0aGlzLl9zZXJ2aWNlLmZvY3VzU2VsZWN0KCk7IH1cblxuICBmb2N1cygpIHtcbiAgICB0aGlzLl9uZ1pvbmUub25TdGFibGUuYXNPYnNlcnZhYmxlKCkucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgY29uc3QgZWxlbWVudFRvRm9jdXMgPVxuICAgICAgICAgIHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yPEhUTUxEaXZFbGVtZW50PignZGl2Lm5nYi1kcC1kYXlbdGFiaW5kZXg9XCIwXCJdJyk7XG4gICAgICBpZiAoZWxlbWVudFRvRm9jdXMpIHtcbiAgICAgICAgZWxlbWVudFRvRm9jdXMuZm9jdXMoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBOYXZpZ2F0ZXMgdG8gdGhlIHByb3ZpZGVkIGRhdGUuXG4gICAqXG4gICAqIFdpdGggdGhlIGRlZmF1bHQgY2FsZW5kYXIgd2UgdXNlIElTTyA4NjAxOiAnbW9udGgnIGlzIDE9SmFuIC4uLiAxMj1EZWMuXG4gICAqIElmIG5vdGhpbmcgb3IgaW52YWxpZCBkYXRlIHByb3ZpZGVkIGNhbGVuZGFyIHdpbGwgb3BlbiBjdXJyZW50IG1vbnRoLlxuICAgKlxuICAgKiBVc2UgdGhlIGBbc3RhcnREYXRlXWAgaW5wdXQgYXMgYW4gYWx0ZXJuYXRpdmUuXG4gICAqL1xuICBuYXZpZ2F0ZVRvKGRhdGU/OiB7eWVhcjogbnVtYmVyLCBtb250aDogbnVtYmVyLCBkYXk/OiBudW1iZXJ9KSB7XG4gICAgdGhpcy5fc2VydmljZS5vcGVuKE5nYkRhdGUuZnJvbShkYXRlID8gZGF0ZS5kYXkgPyBkYXRlIGFzIE5nYkRhdGVTdHJ1Y3QgOiB7Li4uZGF0ZSwgZGF5OiAxfSA6IG51bGwpKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgY29uc3QgZm9jdXNJbnMkID0gZnJvbUV2ZW50PEZvY3VzRXZlbnQ+KHRoaXMuX21vbnRoc0VsLm5hdGl2ZUVsZW1lbnQsICdmb2N1c2luJyk7XG4gICAgICBjb25zdCBmb2N1c091dHMkID0gZnJvbUV2ZW50PEZvY3VzRXZlbnQ+KHRoaXMuX21vbnRoc0VsLm5hdGl2ZUVsZW1lbnQsICdmb2N1c291dCcpO1xuICAgICAgY29uc3Qge25hdGl2ZUVsZW1lbnR9ID0gdGhpcy5fZWxlbWVudFJlZjtcblxuICAgICAgLy8gd2UncmUgY2hhbmdpbmcgJ2ZvY3VzVmlzaWJsZScgb25seSB3aGVuIGVudGVyaW5nIG9yIGxlYXZpbmcgbW9udGhzIHZpZXdcbiAgICAgIC8vIGFuZCBpZ25vcmluZyBhbGwgZm9jdXMgZXZlbnRzIHdoZXJlIGJvdGggJ3RhcmdldCcgYW5kICdyZWxhdGVkJyB0YXJnZXQgYXJlIGRheSBjZWxsc1xuICAgICAgbWVyZ2UoZm9jdXNJbnMkLCBmb2N1c091dHMkKVxuICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICBmaWx0ZXIoXG4gICAgICAgICAgICAgICAgICAoe3RhcmdldCwgcmVsYXRlZFRhcmdldH0pID0+XG4gICAgICAgICAgICAgICAgICAgICAgIShoYXNDbGFzc05hbWUodGFyZ2V0LCAnbmdiLWRwLWRheScpICYmIGhhc0NsYXNzTmFtZShyZWxhdGVkVGFyZ2V0LCAnbmdiLWRwLWRheScpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVFbGVtZW50LmNvbnRhaW5zKHRhcmdldCBhcyBOb2RlKSAmJiBuYXRpdmVFbGVtZW50LmNvbnRhaW5zKHJlbGF0ZWRUYXJnZXQgYXMgTm9kZSkpKSxcbiAgICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCQpKVxuICAgICAgICAgIC5zdWJzY3JpYmUoKHt0eXBlfSkgPT4gdGhpcy5fbmdab25lLnJ1bigoKSA9PiB0aGlzLl9zZXJ2aWNlLnNldCh7Zm9jdXNWaXNpYmxlOiB0eXBlID09PSAnZm9jdXNpbid9KSkpO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7IHRoaXMuX2Rlc3Ryb3llZCQubmV4dCgpOyB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgaWYgKHRoaXMubW9kZWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgaW5wdXRzOiBEYXRlcGlja2VyU2VydmljZUlucHV0cyA9IHt9O1xuICAgICAgWydkYXlUZW1wbGF0ZURhdGEnLCAnZGlzcGxheU1vbnRocycsICdtYXJrRGlzYWJsZWQnLCAnZmlyc3REYXlPZldlZWsnLCAnbmF2aWdhdGlvbicsICdtaW5EYXRlJywgJ21heERhdGUnLFxuICAgICAgICdvdXRzaWRlRGF5cyddXG4gICAgICAgICAgLmZvckVhY2gobmFtZSA9PiBpbnB1dHNbbmFtZV0gPSB0aGlzW25hbWVdKTtcbiAgICAgIHRoaXMuX3NlcnZpY2Uuc2V0KGlucHV0cyk7XG5cbiAgICAgIHRoaXMubmF2aWdhdGVUbyh0aGlzLnN0YXJ0RGF0ZSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGNvbnN0IGlucHV0czogRGF0ZXBpY2tlclNlcnZpY2VJbnB1dHMgPSB7fTtcbiAgICBbJ2RheVRlbXBsYXRlRGF0YScsICdkaXNwbGF5TW9udGhzJywgJ21hcmtEaXNhYmxlZCcsICdmaXJzdERheU9mV2VlaycsICduYXZpZ2F0aW9uJywgJ21pbkRhdGUnLCAnbWF4RGF0ZScsXG4gICAgICdvdXRzaWRlRGF5cyddXG4gICAgICAgIC5maWx0ZXIobmFtZSA9PiBuYW1lIGluIGNoYW5nZXMpXG4gICAgICAgIC5mb3JFYWNoKG5hbWUgPT4gaW5wdXRzW25hbWVdID0gdGhpc1tuYW1lXSk7XG4gICAgdGhpcy5fc2VydmljZS5zZXQoaW5wdXRzKTtcblxuICAgIGlmICgnc3RhcnREYXRlJyBpbiBjaGFuZ2VzKSB7XG4gICAgICBjb25zdCB7Y3VycmVudFZhbHVlLCBwcmV2aW91c1ZhbHVlfSA9IGNoYW5nZXMuc3RhcnREYXRlO1xuICAgICAgaWYgKGlzQ2hhbmdlZE1vbnRoKHByZXZpb3VzVmFsdWUsIGN1cnJlbnRWYWx1ZSkpIHtcbiAgICAgICAgdGhpcy5uYXZpZ2F0ZVRvKHRoaXMuc3RhcnREYXRlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvbkRhdGVTZWxlY3QoZGF0ZTogTmdiRGF0ZSkge1xuICAgIHRoaXMuX3NlcnZpY2UuZm9jdXMoZGF0ZSk7XG4gICAgdGhpcy5fc2VydmljZS5zZWxlY3QoZGF0ZSwge2VtaXRFdmVudDogdHJ1ZX0pO1xuICB9XG5cbiAgb25LZXlEb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7IHRoaXMuX2tleWJvYXJkU2VydmljZS5wcm9jZXNzS2V5KGV2ZW50LCB0aGlzLCB0aGlzLl9jYWxlbmRhcik7IH1cblxuICBvbk5hdmlnYXRlRGF0ZVNlbGVjdChkYXRlOiBOZ2JEYXRlKSB7IHRoaXMuX3NlcnZpY2Uub3BlbihkYXRlKTsgfVxuXG4gIG9uTmF2aWdhdGVFdmVudChldmVudDogTmF2aWdhdGlvbkV2ZW50KSB7XG4gICAgc3dpdGNoIChldmVudCkge1xuICAgICAgY2FzZSBOYXZpZ2F0aW9uRXZlbnQuUFJFVjpcbiAgICAgICAgdGhpcy5fc2VydmljZS5vcGVuKHRoaXMuX2NhbGVuZGFyLmdldFByZXYodGhpcy5tb2RlbC5maXJzdERhdGUsICdtJywgMSkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTmF2aWdhdGlvbkV2ZW50Lk5FWFQ6XG4gICAgICAgIHRoaXMuX3NlcnZpY2Uub3Blbih0aGlzLl9jYWxlbmRhci5nZXROZXh0KHRoaXMubW9kZWwuZmlyc3REYXRlLCAnbScsIDEpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogKHZhbHVlOiBhbnkpID0+IGFueSk6IHZvaWQgeyB0aGlzLm9uQ2hhbmdlID0gZm47IH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4gYW55KTogdm9pZCB7IHRoaXMub25Ub3VjaGVkID0gZm47IH1cblxuICBzZXREaXNhYmxlZFN0YXRlKGRpc2FibGVkOiBib29sZWFuKSB7IHRoaXMuX3NlcnZpY2Uuc2V0KHtkaXNhYmxlZH0pOyB9XG5cbiAgd3JpdGVWYWx1ZSh2YWx1ZSkge1xuICAgIHRoaXMuX2NvbnRyb2xWYWx1ZSA9IE5nYkRhdGUuZnJvbSh0aGlzLl9uZ2JEYXRlQWRhcHRlci5mcm9tTW9kZWwodmFsdWUpKTtcbiAgICB0aGlzLl9zZXJ2aWNlLnNlbGVjdCh0aGlzLl9jb250cm9sVmFsdWUpO1xuICB9XG59XG4iXX0=