rating.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, EventEmitter, forwardRef, Input, Output, TemplateRef, ViewEncapsulation } from '@angular/core';
  6. import { NgbRatingConfig } from './rating-config';
  7. import { getValueInRange } from '../util/util';
  8. import { Key } from '../util/key';
  9. import { NG_VALUE_ACCESSOR } from '@angular/forms';
  10. /**
  11. * The context for the custom star display template defined in the `starTemplate`.
  12. * @record
  13. */
  14. export function StarTemplateContext() { }
  15. if (false) {
  16. /**
  17. * The star fill percentage, an integer in the `[0, 100]` range.
  18. * @type {?}
  19. */
  20. StarTemplateContext.prototype.fill;
  21. /**
  22. * Index of the star, starts with `0`.
  23. * @type {?}
  24. */
  25. StarTemplateContext.prototype.index;
  26. }
  27. /** @type {?} */
  28. var NGB_RATING_VALUE_ACCESSOR = {
  29. provide: NG_VALUE_ACCESSOR,
  30. useExisting: forwardRef((/**
  31. * @return {?}
  32. */
  33. function () { return NgbRating; })),
  34. multi: true
  35. };
  36. /**
  37. * A directive that helps visualising and interacting with a star rating bar.
  38. */
  39. var NgbRating = /** @class */ (function () {
  40. function NgbRating(config, _changeDetectorRef) {
  41. this._changeDetectorRef = _changeDetectorRef;
  42. this.contexts = [];
  43. this.disabled = false;
  44. /**
  45. * An event emitted when the user is hovering over a given rating.
  46. *
  47. * Event payload equals to the rating being hovered over.
  48. */
  49. this.hover = new EventEmitter();
  50. /**
  51. * An event emitted when the user stops hovering over a given rating.
  52. *
  53. * Event payload equals to the rating of the last item being hovered over.
  54. */
  55. this.leave = new EventEmitter();
  56. /**
  57. * An event emitted when the user selects a new rating.
  58. *
  59. * Event payload equals to the newly selected rating.
  60. */
  61. this.rateChange = new EventEmitter(true);
  62. this.onChange = (/**
  63. * @param {?} _
  64. * @return {?}
  65. */
  66. function (_) { });
  67. this.onTouched = (/**
  68. * @return {?}
  69. */
  70. function () { });
  71. this.max = config.max;
  72. this.readonly = config.readonly;
  73. }
  74. /**
  75. * @return {?}
  76. */
  77. NgbRating.prototype.ariaValueText = /**
  78. * @return {?}
  79. */
  80. function () { return this.nextRate + " out of " + this.max; };
  81. /**
  82. * @param {?} value
  83. * @return {?}
  84. */
  85. NgbRating.prototype.enter = /**
  86. * @param {?} value
  87. * @return {?}
  88. */
  89. function (value) {
  90. if (!this.readonly && !this.disabled) {
  91. this._updateState(value);
  92. }
  93. this.hover.emit(value);
  94. };
  95. /**
  96. * @return {?}
  97. */
  98. NgbRating.prototype.handleBlur = /**
  99. * @return {?}
  100. */
  101. function () { this.onTouched(); };
  102. /**
  103. * @param {?} value
  104. * @return {?}
  105. */
  106. NgbRating.prototype.handleClick = /**
  107. * @param {?} value
  108. * @return {?}
  109. */
  110. function (value) { this.update(this.resettable && this.rate === value ? 0 : value); };
  111. /**
  112. * @param {?} event
  113. * @return {?}
  114. */
  115. NgbRating.prototype.handleKeyDown = /**
  116. * @param {?} event
  117. * @return {?}
  118. */
  119. function (event) {
  120. // tslint:disable-next-line:deprecation
  121. switch (event.which) {
  122. case Key.ArrowDown:
  123. case Key.ArrowLeft:
  124. this.update(this.rate - 1);
  125. break;
  126. case Key.ArrowUp:
  127. case Key.ArrowRight:
  128. this.update(this.rate + 1);
  129. break;
  130. case Key.Home:
  131. this.update(0);
  132. break;
  133. case Key.End:
  134. this.update(this.max);
  135. break;
  136. default:
  137. return;
  138. }
  139. // note 'return' in default case
  140. event.preventDefault();
  141. };
  142. /**
  143. * @param {?} changes
  144. * @return {?}
  145. */
  146. NgbRating.prototype.ngOnChanges = /**
  147. * @param {?} changes
  148. * @return {?}
  149. */
  150. function (changes) {
  151. if (changes['rate']) {
  152. this.update(this.rate);
  153. }
  154. };
  155. /**
  156. * @return {?}
  157. */
  158. NgbRating.prototype.ngOnInit = /**
  159. * @return {?}
  160. */
  161. function () {
  162. this.contexts = Array.from({ length: this.max }, (/**
  163. * @param {?} v
  164. * @param {?} k
  165. * @return {?}
  166. */
  167. function (v, k) { return ({ fill: 0, index: k }); }));
  168. this._updateState(this.rate);
  169. };
  170. /**
  171. * @param {?} fn
  172. * @return {?}
  173. */
  174. NgbRating.prototype.registerOnChange = /**
  175. * @param {?} fn
  176. * @return {?}
  177. */
  178. function (fn) { this.onChange = fn; };
  179. /**
  180. * @param {?} fn
  181. * @return {?}
  182. */
  183. NgbRating.prototype.registerOnTouched = /**
  184. * @param {?} fn
  185. * @return {?}
  186. */
  187. function (fn) { this.onTouched = fn; };
  188. /**
  189. * @return {?}
  190. */
  191. NgbRating.prototype.reset = /**
  192. * @return {?}
  193. */
  194. function () {
  195. this.leave.emit(this.nextRate);
  196. this._updateState(this.rate);
  197. };
  198. /**
  199. * @param {?} isDisabled
  200. * @return {?}
  201. */
  202. NgbRating.prototype.setDisabledState = /**
  203. * @param {?} isDisabled
  204. * @return {?}
  205. */
  206. function (isDisabled) { this.disabled = isDisabled; };
  207. /**
  208. * @param {?} value
  209. * @param {?=} internalChange
  210. * @return {?}
  211. */
  212. NgbRating.prototype.update = /**
  213. * @param {?} value
  214. * @param {?=} internalChange
  215. * @return {?}
  216. */
  217. function (value, internalChange) {
  218. if (internalChange === void 0) { internalChange = true; }
  219. /** @type {?} */
  220. var newRate = getValueInRange(value, this.max, 0);
  221. if (!this.readonly && !this.disabled && this.rate !== newRate) {
  222. this.rate = newRate;
  223. this.rateChange.emit(this.rate);
  224. }
  225. if (internalChange) {
  226. this.onChange(this.rate);
  227. this.onTouched();
  228. }
  229. this._updateState(this.rate);
  230. };
  231. /**
  232. * @param {?} value
  233. * @return {?}
  234. */
  235. NgbRating.prototype.writeValue = /**
  236. * @param {?} value
  237. * @return {?}
  238. */
  239. function (value) {
  240. this.update(value, false);
  241. this._changeDetectorRef.markForCheck();
  242. };
  243. /**
  244. * @private
  245. * @param {?} index
  246. * @return {?}
  247. */
  248. NgbRating.prototype._getFillValue = /**
  249. * @private
  250. * @param {?} index
  251. * @return {?}
  252. */
  253. function (index) {
  254. /** @type {?} */
  255. var diff = this.nextRate - index;
  256. if (diff >= 1) {
  257. return 100;
  258. }
  259. if (diff < 1 && diff > 0) {
  260. return parseInt((diff * 100).toFixed(2), 10);
  261. }
  262. return 0;
  263. };
  264. /**
  265. * @private
  266. * @param {?} nextValue
  267. * @return {?}
  268. */
  269. NgbRating.prototype._updateState = /**
  270. * @private
  271. * @param {?} nextValue
  272. * @return {?}
  273. */
  274. function (nextValue) {
  275. var _this = this;
  276. this.nextRate = nextValue;
  277. this.contexts.forEach((/**
  278. * @param {?} context
  279. * @param {?} index
  280. * @return {?}
  281. */
  282. function (context, index) { return context.fill = _this._getFillValue(index); }));
  283. };
  284. NgbRating.decorators = [
  285. { type: Component, args: [{
  286. selector: 'ngb-rating',
  287. changeDetection: ChangeDetectionStrategy.OnPush,
  288. encapsulation: ViewEncapsulation.None,
  289. host: {
  290. 'class': 'd-inline-flex',
  291. 'tabindex': '0',
  292. 'role': 'slider',
  293. 'aria-valuemin': '0',
  294. '[attr.aria-valuemax]': 'max',
  295. '[attr.aria-valuenow]': 'nextRate',
  296. '[attr.aria-valuetext]': 'ariaValueText()',
  297. '[attr.aria-disabled]': 'readonly ? true : null',
  298. '(blur)': 'handleBlur()',
  299. '(keydown)': 'handleKeyDown($event)',
  300. '(mouseleave)': 'reset()'
  301. },
  302. template: "\n <ng-template #t let-fill=\"fill\">{{ fill === 100 ? '&#9733;' : '&#9734;' }}</ng-template>\n <ng-template ngFor [ngForOf]=\"contexts\" let-index=\"index\">\n <span class=\"sr-only\">({{ index < nextRate ? '*' : ' ' }})</span>\n <span (mouseenter)=\"enter(index + 1)\" (click)=\"handleClick(index + 1)\" [style.cursor]=\"readonly || disabled ? 'default' : 'pointer'\">\n <ng-template [ngTemplateOutlet]=\"starTemplate || starTemplateFromContent || t\" [ngTemplateOutletContext]=\"contexts[index]\">\n </ng-template>\n </span>\n </ng-template>\n ",
  303. providers: [NGB_RATING_VALUE_ACCESSOR]
  304. }] }
  305. ];
  306. /** @nocollapse */
  307. NgbRating.ctorParameters = function () { return [
  308. { type: NgbRatingConfig },
  309. { type: ChangeDetectorRef }
  310. ]; };
  311. NgbRating.propDecorators = {
  312. max: [{ type: Input }],
  313. rate: [{ type: Input }],
  314. readonly: [{ type: Input }],
  315. resettable: [{ type: Input }],
  316. starTemplate: [{ type: Input }],
  317. starTemplateFromContent: [{ type: ContentChild, args: [TemplateRef, { static: false },] }],
  318. hover: [{ type: Output }],
  319. leave: [{ type: Output }],
  320. rateChange: [{ type: Output }]
  321. };
  322. return NgbRating;
  323. }());
  324. export { NgbRating };
  325. if (false) {
  326. /** @type {?} */
  327. NgbRating.prototype.contexts;
  328. /** @type {?} */
  329. NgbRating.prototype.disabled;
  330. /** @type {?} */
  331. NgbRating.prototype.nextRate;
  332. /**
  333. * The maximal rating that can be given.
  334. * @type {?}
  335. */
  336. NgbRating.prototype.max;
  337. /**
  338. * The current rating. Could be a decimal value like `3.75`.
  339. * @type {?}
  340. */
  341. NgbRating.prototype.rate;
  342. /**
  343. * If `true`, the rating can't be changed.
  344. * @type {?}
  345. */
  346. NgbRating.prototype.readonly;
  347. /**
  348. * If `true`, the rating can be reset to `0` by mouse clicking currently set rating.
  349. * @type {?}
  350. */
  351. NgbRating.prototype.resettable;
  352. /**
  353. * The template to override the way each star is displayed.
  354. *
  355. * Alternatively put an `<ng-template>` as the only child of your `<ngb-rating>` element
  356. * @type {?}
  357. */
  358. NgbRating.prototype.starTemplate;
  359. /** @type {?} */
  360. NgbRating.prototype.starTemplateFromContent;
  361. /**
  362. * An event emitted when the user is hovering over a given rating.
  363. *
  364. * Event payload equals to the rating being hovered over.
  365. * @type {?}
  366. */
  367. NgbRating.prototype.hover;
  368. /**
  369. * An event emitted when the user stops hovering over a given rating.
  370. *
  371. * Event payload equals to the rating of the last item being hovered over.
  372. * @type {?}
  373. */
  374. NgbRating.prototype.leave;
  375. /**
  376. * An event emitted when the user selects a new rating.
  377. *
  378. * Event payload equals to the newly selected rating.
  379. * @type {?}
  380. */
  381. NgbRating.prototype.rateChange;
  382. /** @type {?} */
  383. NgbRating.prototype.onChange;
  384. /** @type {?} */
  385. NgbRating.prototype.onTouched;
  386. /**
  387. * @type {?}
  388. * @private
  389. */
  390. NgbRating.prototype._changeDetectorRef;
  391. }
  392. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmF0aW5nLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAvIiwic291cmNlcyI6WyJyYXRpbmcvcmF0aW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsWUFBWSxFQUNaLFlBQVksRUFDWixVQUFVLEVBQ1YsS0FBSyxFQUdMLE1BQU0sRUFFTixXQUFXLEVBQ1gsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFBQyxHQUFHLEVBQUMsTUFBTSxhQUFhLENBQUM7QUFDaEMsT0FBTyxFQUF1QixpQkFBaUIsRUFBQyxNQUFNLGdCQUFnQixDQUFDOzs7OztBQUt2RSx5Q0FVQzs7Ozs7O0lBTkMsbUNBQWE7Ozs7O0lBS2Isb0NBQWM7OztJQUdWLHlCQUF5QixHQUFHO0lBQ2hDLE9BQU8sRUFBRSxpQkFBaUI7SUFDMUIsV0FBVyxFQUFFLFVBQVU7OztJQUFDLGNBQU0sT0FBQSxTQUFTLEVBQVQsQ0FBUyxFQUFDO0lBQ3hDLEtBQUssRUFBRSxJQUFJO0NBQ1o7Ozs7QUFLRDtJQXdGRSxtQkFBWSxNQUF1QixFQUFVLGtCQUFxQztRQUFyQyx1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW1CO1FBekRsRixhQUFRLEdBQTBCLEVBQUUsQ0FBQztRQUNyQyxhQUFRLEdBQUcsS0FBSyxDQUFDOzs7Ozs7UUFxQ1AsVUFBSyxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7Ozs7OztRQU9uQyxVQUFLLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQzs7Ozs7O1FBT25DLGVBQVUsR0FBRyxJQUFJLFlBQVksQ0FBUyxJQUFJLENBQUMsQ0FBQztRQUV0RCxhQUFROzs7O1FBQUcsVUFB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QkFDcEMsY0FBYyxFQUFFLFNBQVM7cUJBQzFCO29CQUNELFFBQVEsRUFBRSw0a0JBU1Q7b0JBQ0QsU0FBUyxFQUFFLENBQUMseUJBQXlCLENBQUM7aUJBQ3ZDOzs7O2dCQXpETyxlQUFlO2dCQWJyQixpQkFBaUI7OztzQkFpRmhCLEtBQUs7dUJBS0wsS0FBSzsyQkFLTCxLQUFLOzZCQUtMLEtBQUs7K0JBT0wsS0FBSzswQ0FDTCxZQUFZLFNBQUMsV0FBVyxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQzt3QkFPekMsTUFBTTt3QkFPTixNQUFNOzZCQU9OLE1BQU07O0lBeUdULGdCQUFDO0NBQUEsQUE1TEQsSUE0TEM7U0EvSlksU0FBUzs7O0lBRXBCLDZCQUFxQzs7SUFDckMsNkJBQWlCOztJQUNqQiw2QkFBaUI7Ozs7O0lBTWpCLHdCQUFxQjs7Ozs7SUFLckIseUJBQXNCOzs7OztJQUt0Qiw2QkFBMkI7Ozs7O0lBSzNCLCtCQUE2Qjs7Ozs7OztJQU83QixpQ0FBd0Q7O0lBQ3hELDRDQUFzRzs7Ozs7OztJQU90RywwQkFBNkM7Ozs7Ozs7SUFPN0MsMEJBQTZDOzs7Ozs7O0lBTzdDLCtCQUFzRDs7SUFFdEQsNkJBQTBCOztJQUMxQiw4QkFBcUI7Ozs7O0lBRWdCLHVDQUE2QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGQsXG4gIEV2ZW50RW1pdHRlcixcbiAgZm9yd2FyZFJlZixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7TmdiUmF0aW5nQ29uZmlnfSBmcm9tICcuL3JhdGluZy1jb25maWcnO1xuaW1wb3J0IHtnZXRWYWx1ZUluUmFuZ2V9IGZyb20gJy4uL3V0aWwvdXRpbCc7XG5pbXBvcnQge0tleX0gZnJvbSAnLi4vdXRpbC9rZXknO1xuaW1wb3J0IHtDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1J9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuLyoqXG4gKiBUaGUgY29udGV4dCBmb3IgdGhlIGN1c3RvbSBzdGFyIGRpc3BsYXkgdGVtcGxhdGUgZGVmaW5lZCBpbiB0aGUgYHN0YXJUZW1wbGF0ZWAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhclRlbXBsYXRlQ29udGV4dCB7XG4gIC8qKlxuICAgKiBUaGUgc3RhciBmaWxsIHBlcmNlbnRhZ2UsIGFuIGludGVnZXIgaW4gdGhlIGBbMCwgMTAwXWAgcmFuZ2UuXG4gICAqL1xuICBmaWxsOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEluZGV4IG9mIHRoZSBzdGFyLCBzdGFydHMgd2l0aCBgMGAuXG4gICAqL1xuICBpbmRleDogbnVtYmVyO1xufVxuXG5jb25zdCBOR0JfUkFUSU5HX1ZBTFVFX0FDQ0VTU09SID0ge1xuICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTmdiUmF0aW5nKSxcbiAgbXVsdGk6IHRydWVcbn07XG5cbi8qKlxuICogQSBkaXJlY3RpdmUgdGhhdCBoZWxwcyB2aXN1YWxpc2luZyBhbmQgaW50ZXJhY3Rpbmcgd2l0aCBhIHN0YXIgcmF0aW5nIGJhci5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmdiLXJhdGluZycsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBob3N0OiB7XG4gICAgJ2NsYXNzJzogJ2QtaW5saW5lLWZsZXgnLFxuICAgICd0YWJpbmRleCc6ICcwJyxcbiAgICAncm9sZSc6ICdzbGlkZXInLFxuICAgICdhcmlhLXZhbHVlbWluJzogJzAnLFxuICAgICdbYXR0ci5hcmlhLXZhbHVlbWF4XSc6ICdtYXgnLFxuICAgICdbYXR0ci5hcmlhLXZhbHVlbm93XSc6ICduZXh0UmF0ZScsXG4gICAgJ1thdHRyLmFyaWEtdmFsdWV0ZXh0XSc6ICdhcmlhVmFsdWVUZXh0KCknLFxuICAgICdbYXR0ci5hcmlhLWRpc2FibGVkXSc6ICdyZWFkb25seSA/IHRydWUgOiBudWxsJyxcbiAgICAnKGJsdXIpJzogJ2hhbmRsZUJsdXIoKScsXG4gICAgJyhrZXlkb3duKSc6ICdoYW5kbGVLZXlEb3duKCRldmVudCknLFxuICAgICcobW91c2VsZWF2ZSknOiAncmVzZXQoKSdcbiAgfSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8bmctdGVtcGxhdGUgI3QgbGV0LWZpbGw9XCJmaWxsXCI+e3sgZmlsbCA9PT0gMTAwID8gJyYjOTczMzsnIDogJyYjOTczNDsnIH19PC9uZy10ZW1wbGF0ZT5cbiAgICA8bmctdGVtcGxhdGUgbmdGb3IgW25nRm9yT2ZdPVwiY29udGV4dHNcIiBsZXQtaW5kZXg9XCJpbmRleFwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJzci1vbmx5XCI+KHt7IGluZGV4IDwgbmV4dFJhdGUgPyAnKicgOiAnICcgfX0pPC9zcGFuPlxuICAgICAgPHNwYW4gKG1vdXNlZW50ZXIpPVwiZW50ZXIoaW5kZXggKyAxKVwiIChjbGljayk9XCJoYW5kbGVDbGljayhpbmRleCArIDEpXCIgW3N0eWxlLmN1cnNvcl09XCJyZWFkb25seSB8fCBkaXNhYmxlZCA/ICdkZWZhdWx0JyA6ICdwb2ludGVyJ1wiPlxuICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwic3RhclRlbXBsYXRlIHx8IHN0YXJUZW1wbGF0ZUZyb21Db250ZW50IHx8IHRcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwiY29udGV4dHNbaW5kZXhdXCI+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L3NwYW4+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgYCxcbiAgcHJvdmlkZXJzOiBbTkdCX1JBVElOR19WQUxVRV9BQ0NFU1NPUl1cbn0pXG5leHBvcnQgY2xhc3MgTmdiUmF0aW5nIGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsXG4gICAgT25Jbml0LCBPbkNoYW5nZXMge1xuICBjb250ZXh0czogU3RhclRlbXBsYXRlQ29udGV4dFtdID0gW107XG4gIGRpc2FibGVkID0gZmFsc2U7XG4gIG5leHRSYXRlOiBudW1iZXI7XG5cblxuICAvKipcbiAgICogVGhlIG1heGltYWwgcmF0aW5nIHRoYXQgY2FuIGJlIGdpdmVuLlxuICAgKi9cbiAgQElucHV0KCkgbWF4OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBjdXJyZW50IHJhdGluZy4gQ291bGQgYmUgYSBkZWNpbWFsIHZhbHVlIGxpa2UgYDMuNzVgLlxuICAgKi9cbiAgQElucHV0KCkgcmF0ZTogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBJZiBgdHJ1ZWAsIHRoZSByYXRpbmcgY2FuJ3QgYmUgY2hhbmdlZC5cbiAgICovXG4gIEBJbnB1dCgpIHJlYWRvbmx5OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJZiBgdHJ1ZWAsIHRoZSByYXRpbmcgY2FuIGJlIHJlc2V0IHRvIGAwYCBieSBtb3VzZSBjbGlja2luZyBjdXJyZW50bHkgc2V0IHJhdGluZy5cbiAgICovXG4gIEBJbnB1dCgpIHJlc2V0dGFibGU6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSB0ZW1wbGF0ZSB0byBvdmVycmlkZSB0aGUgd2F5IGVhY2ggc3RhciBpcyBkaXNwbGF5ZWQuXG4gICAqXG4gICAqIEFsdGVybmF0aXZlbHkgcHV0IGFuIGA8bmctdGVtcGxhdGU+YCBhcyB0aGUgb25seSBjaGlsZCBvZiB5b3VyIGA8bmdiLXJhdGluZz5gIGVsZW1lbnRcbiAgICovXG4gIEBJbnB1dCgpIHN0YXJUZW1wbGF0ZTogVGVtcGxhdGVSZWY8U3RhclRlbXBsYXRlQ29udGV4dD47XG4gIEBDb250ZW50Q2hpbGQoVGVtcGxhdGVSZWYsIHtzdGF0aWM6IGZhbHNlfSkgc3RhclRlbXBsYXRlRnJvbUNvbnRlbnQ6IFRlbXBsYXRlUmVmPFN0YXJUZW1wbGF0ZUNvbnRleHQ+O1xuXG4gIC8qKlxuICAgKiBBbiBldmVudCBlbWl0dGVkIHdoZW4gdGhlIHVzZXIgaXMgaG92ZXJpbmcgb3ZlciBhIGdpdmVuIHJhdGluZy5cbiAgICpcbiAgICogRXZlbnQgcGF5bG9hZCBlcXVhbHMgdG8gdGhlIHJhdGluZyBiZWluZyBob3ZlcmVkIG92ZXIuXG4gICAqL1xuICBAT3V0cHV0KCkgaG92ZXIgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcblxuICAvKipcbiAgICogQW4gZXZlbnQgZW1pdHRlZCB3aGVuIHRoZSB1c2VyIHN0b3BzIGhvdmVyaW5nIG92ZXIgYSBnaXZlbiByYXRpbmcuXG4gICAqXG4gICAqIEV2ZW50IHBheWxvYWQgZXF1YWxzIHRvIHRoZSByYXRpbmcgb2YgdGhlIGxhc3QgaXRlbSBiZWluZyBob3ZlcmVkIG92ZXIuXG4gICAqL1xuICBAT3V0cHV0KCkgbGVhdmUgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcblxuICAvKipcbiAgICogQW4gZXZlbnQgZW1pdHRlZCB3aGVuIHRoZSB1c2VyIHNlbGVjdHMgYSBuZXcgcmF0aW5nLlxuICAgKlxuICAgKiBFdmVudCBwYXlsb2FkIGVxdWFscyB0byB0aGUgbmV3bHkgc2VsZWN0ZWQgcmF0aW5nLlxuICAgKi9cbiAgQE91dHB1dCgpIHJhdGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4odHJ1ZSk7XG5cbiAgb25DaGFuZ2UgPSAoXzogYW55KSA9PiB7fTtcbiAgb25Ub3VjaGVkID0gKCkgPT4ge307XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBOZ2JSYXRpbmdDb25maWcsIHByaXZhdGUgX2NoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZikge1xuICAgIHRoaXMubWF4ID0gY29uZmlnLm1heDtcbiAgICB0aGlzLnJlYWRvbmx5ID0gY29uZmlnLnJlYWRvbmx5O1xuICB9XG5cbiAgYXJpYVZhbHVlVGV4dCgpIHsgcmV0dXJuIGAke3RoaXMubmV4dFJhdGV9IG91dCBvZiAke3RoaXMubWF4fWA7IH1cblxuICBlbnRlcih2YWx1ZTogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJlYWRvbmx5ICYmICF0aGlzLmRpc2FibGVkKSB7XG4gICAgICB0aGlzLl91cGRhdGVTdGF0ZSh2YWx1ZSk7XG4gICAgfVxuICAgIHRoaXMuaG92ZXIuZW1pdCh2YWx1ZSk7XG4gIH1cblxuICBoYW5kbGVCbHVyKCkgeyB0aGlzLm9uVG91Y2hlZCgpOyB9XG5cbiAgaGFuZGxlQ2xpY2sodmFsdWU6IG51bWJlcikgeyB0aGlzLnVwZGF0ZSh0aGlzLnJlc2V0dGFibGUgJiYgdGhpcy5yYXRlID09PSB2YWx1ZSA/IDAgOiB2YWx1ZSk7IH1cblxuICBoYW5kbGVLZXlEb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRlcHJlY2F0aW9uXG4gICAgc3dpdGNoIChldmVudC53aGljaCkge1xuICAgICAgY2FzZSBLZXkuQXJyb3dEb3duOlxuICAgICAgY2FzZSBLZXkuQXJyb3dMZWZ0OlxuICAgICAgICB0aGlzLnVwZGF0ZSh0aGlzLnJhdGUgLSAxKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEtleS5BcnJvd1VwOlxuICAgICAgY2FzZSBLZXkuQXJyb3dSaWdodDpcbiAgICAgICAgdGhpcy51cGRhdGUodGhpcy5yYXRlICsgMSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBLZXkuSG9tZTpcbiAgICAgICAgdGhpcy51cGRhdGUoMCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBLZXkuRW5kOlxuICAgICAgICB0aGlzLnVwZGF0ZSh0aGlzLm1heCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIG5vdGUgJ3JldHVybicgaW4gZGVmYXVsdCBjYXNlXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAoY2hhbmdlc1sncmF0ZSddKSB7XG4gICAgICB0aGlzLnVwZGF0ZSh0aGlzLnJhdGUpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuY29udGV4dHMgPSBBcnJheS5mcm9tKHtsZW5ndGg6IHRoaXMubWF4fSwgKHYsIGspID0+ICh7ZmlsbDogMCwgaW5kZXg6IGt9KSk7XG4gICAgdGhpcy5fdXBkYXRlU3RhdGUodGhpcy5yYXRlKTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46ICh2YWx1ZTogYW55KSA9PiBhbnkpOiB2b2lkIHsgdGhpcy5vbkNoYW5nZSA9IGZuOyB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IGFueSk6IHZvaWQgeyB0aGlzLm9uVG91Y2hlZCA9IGZuOyB9XG5cbiAgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5sZWF2ZS5lbWl0KHRoaXMubmV4dFJhdGUpO1xuICAgIHRoaXMuX3VwZGF0ZVN0YXRlKHRoaXMucmF0ZSk7XG4gIH1cblxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pIHsgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7IH1cblxuICB1cGRhdGUodmFsdWU6IG51bWJlciwgaW50ZXJuYWxDaGFuZ2UgPSB0cnVlKTogdm9pZCB7XG4gICAgY29uc3QgbmV3UmF0ZSA9IGdldFZhbHVlSW5SYW5nZSh2YWx1ZSwgdGhpcy5tYXgsIDApO1xuICAgIGlmICghdGhpcy5yZWFkb25seSAmJiAhdGhpcy5kaXNhYmxlZCAmJiB0aGlzLnJhdGUgIT09IG5ld1JhdGUpIHtcbiAgICAgIHRoaXMucmF0ZSA9IG5ld1JhdGU7XG4gICAgICB0aGlzLnJhdGVDaGFuZ2UuZW1pdCh0aGlzLnJhdGUpO1xuICAgIH1cbiAgICBpZiAoaW50ZXJuYWxDaGFuZ2UpIHtcbiAgICAgIHRoaXMub25DaGFuZ2UodGhpcy5yYXRlKTtcbiAgICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gICAgfVxuICAgIHRoaXMuX3VwZGF0ZVN0YXRlKHRoaXMucmF0ZSk7XG4gIH1cblxuICB3cml0ZVZhbHVlKHZhbHVlKSB7XG4gICAgdGhpcy51cGRhdGUodmFsdWUsIGZhbHNlKTtcbiAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldEZpbGxWYWx1ZShpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBkaWZmID0gdGhpcy5uZXh0UmF0ZSAtIGluZGV4O1xuXG4gICAgaWYgKGRpZmYgPj0gMSkge1xuICAgICAgcmV0dXJuIDEwMDtcbiAgICB9XG4gICAgaWYgKGRpZmYgPCAxICYmIGRpZmYgPiAwKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQoKGRpZmYgKiAxMDApLnRvRml4ZWQoMiksIDEwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIHByaXZhdGUgX3VwZGF0ZVN0YXRlKG5leHRWYWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5uZXh0UmF0ZSA9IG5leHRWYWx1ZTtcbiAgICB0aGlzLmNvbnRleHRzLmZvckVhY2goKGNvbnRleHQsIGluZGV4KSA9PiBjb250ZXh0LmZpbGwgPSB0aGlzLl9nZXRGaWxsVmFsdWUoaW5kZXgpKTtcbiAgfVxufVxuIl19