body-row.component.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  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 { Component, Input, HostBinding, ElementRef, Output, KeyValueDiffers, EventEmitter, HostListener, ChangeDetectionStrategy, ChangeDetectorRef, SkipSelf } from '@angular/core';
  7. import { columnsByPin, columnGroupWidths, columnsByPinArr } from '../../utils/column';
  8. import { Keys } from '../../utils/keys';
  9. import { ScrollbarHelper } from '../../services/scrollbar-helper.service';
  10. import { translateXY } from '../../utils/translate';
  11. var DataTableBodyRowComponent = /** @class */ (function () {
  12. function DataTableBodyRowComponent(differs, scrollbarHelper, cd, element) {
  13. this.differs = differs;
  14. this.scrollbarHelper = scrollbarHelper;
  15. this.cd = cd;
  16. this.treeStatus = 'collapsed';
  17. this.activate = new EventEmitter();
  18. this.treeAction = new EventEmitter();
  19. this._groupStyles = {
  20. left: {},
  21. center: {},
  22. right: {}
  23. };
  24. this._element = element.nativeElement;
  25. this._rowDiffer = differs.find({}).create();
  26. }
  27. Object.defineProperty(DataTableBodyRowComponent.prototype, "columns", {
  28. get: /**
  29. * @return {?}
  30. */
  31. function () {
  32. return this._columns;
  33. },
  34. set: /**
  35. * @param {?} val
  36. * @return {?}
  37. */
  38. function (val) {
  39. this._columns = val;
  40. this.recalculateColumns(val);
  41. this.buildStylesByGroup();
  42. },
  43. enumerable: true,
  44. configurable: true
  45. });
  46. Object.defineProperty(DataTableBodyRowComponent.prototype, "innerWidth", {
  47. get: /**
  48. * @return {?}
  49. */
  50. function () {
  51. return this._innerWidth;
  52. },
  53. set: /**
  54. * @param {?} val
  55. * @return {?}
  56. */
  57. function (val) {
  58. if (this._columns) {
  59. /** @type {?} */
  60. var colByPin = columnsByPin(this._columns);
  61. this._columnGroupWidths = columnGroupWidths(colByPin, this._columns);
  62. }
  63. this._innerWidth = val;
  64. this.recalculateColumns();
  65. this.buildStylesByGroup();
  66. },
  67. enumerable: true,
  68. configurable: true
  69. });
  70. Object.defineProperty(DataTableBodyRowComponent.prototype, "offsetX", {
  71. get: /**
  72. * @return {?}
  73. */
  74. function () {
  75. return this._offsetX;
  76. },
  77. set: /**
  78. * @param {?} val
  79. * @return {?}
  80. */
  81. function (val) {
  82. this._offsetX = val;
  83. this.buildStylesByGroup();
  84. },
  85. enumerable: true,
  86. configurable: true
  87. });
  88. Object.defineProperty(DataTableBodyRowComponent.prototype, "cssClass", {
  89. get: /**
  90. * @return {?}
  91. */
  92. function () {
  93. var e_1, _a;
  94. /** @type {?} */
  95. var cls = 'datatable-body-row';
  96. if (this.isSelected) {
  97. cls += ' active';
  98. }
  99. if (this.rowIndex % 2 !== 0) {
  100. cls += ' datatable-row-odd';
  101. }
  102. if (this.rowIndex % 2 === 0) {
  103. cls += ' datatable-row-even';
  104. }
  105. if (this.rowClass) {
  106. /** @type {?} */
  107. var res = this.rowClass(this.row);
  108. if (typeof res === 'string') {
  109. cls += " " + res;
  110. }
  111. else if (typeof res === 'object') {
  112. /** @type {?} */
  113. var keys = Object.keys(res);
  114. try {
  115. for (var keys_1 = tslib_1.__values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
  116. var k = keys_1_1.value;
  117. if (res[k] === true) {
  118. cls += " " + k;
  119. }
  120. }
  121. }
  122. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  123. finally {
  124. try {
  125. if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
  126. }
  127. finally { if (e_1) throw e_1.error; }
  128. }
  129. }
  130. }
  131. return cls;
  132. },
  133. enumerable: true,
  134. configurable: true
  135. });
  136. Object.defineProperty(DataTableBodyRowComponent.prototype, "columnsTotalWidths", {
  137. get: /**
  138. * @return {?}
  139. */
  140. function () {
  141. return this._columnGroupWidths.total;
  142. },
  143. enumerable: true,
  144. configurable: true
  145. });
  146. /**
  147. * @return {?}
  148. */
  149. DataTableBodyRowComponent.prototype.ngDoCheck = /**
  150. * @return {?}
  151. */
  152. function () {
  153. if (this._rowDiffer.diff(this.row)) {
  154. this.cd.markForCheck();
  155. }
  156. };
  157. /**
  158. * @param {?} index
  159. * @param {?} colGroup
  160. * @return {?}
  161. */
  162. DataTableBodyRowComponent.prototype.trackByGroups = /**
  163. * @param {?} index
  164. * @param {?} colGroup
  165. * @return {?}
  166. */
  167. function (index, colGroup) {
  168. return colGroup.type;
  169. };
  170. /**
  171. * @param {?} index
  172. * @param {?} column
  173. * @return {?}
  174. */
  175. DataTableBodyRowComponent.prototype.columnTrackingFn = /**
  176. * @param {?} index
  177. * @param {?} column
  178. * @return {?}
  179. */
  180. function (index, column) {
  181. return column.$$id;
  182. };
  183. /**
  184. * @return {?}
  185. */
  186. DataTableBodyRowComponent.prototype.buildStylesByGroup = /**
  187. * @return {?}
  188. */
  189. function () {
  190. this._groupStyles.left = this.calcStylesByGroup('left');
  191. this._groupStyles.center = this.calcStylesByGroup('center');
  192. this._groupStyles.right = this.calcStylesByGroup('right');
  193. this.cd.markForCheck();
  194. };
  195. /**
  196. * @param {?} group
  197. * @return {?}
  198. */
  199. DataTableBodyRowComponent.prototype.calcStylesByGroup = /**
  200. * @param {?} group
  201. * @return {?}
  202. */
  203. function (group) {
  204. /** @type {?} */
  205. var widths = this._columnGroupWidths;
  206. /** @type {?} */
  207. var offsetX = this.offsetX;
  208. /** @type {?} */
  209. var styles = {
  210. width: widths[group] + "px"
  211. };
  212. if (group === 'left') {
  213. translateXY(styles, offsetX, 0);
  214. }
  215. else if (group === 'right') {
  216. /** @type {?} */
  217. var bodyWidth = parseInt(this.innerWidth + '', 0);
  218. /** @type {?} */
  219. var totalDiff = widths.total - bodyWidth;
  220. /** @type {?} */
  221. var offsetDiff = totalDiff - offsetX;
  222. /** @type {?} */
  223. var offset = (offsetDiff + this.scrollbarHelper.width) * -1;
  224. translateXY(styles, offset, 0);
  225. }
  226. return styles;
  227. };
  228. /**
  229. * @param {?} event
  230. * @param {?} index
  231. * @return {?}
  232. */
  233. DataTableBodyRowComponent.prototype.onActivate = /**
  234. * @param {?} event
  235. * @param {?} index
  236. * @return {?}
  237. */
  238. function (event, index) {
  239. event.cellIndex = index;
  240. event.rowElement = this._element;
  241. this.activate.emit(event);
  242. };
  243. /**
  244. * @param {?} event
  245. * @return {?}
  246. */
  247. DataTableBodyRowComponent.prototype.onKeyDown = /**
  248. * @param {?} event
  249. * @return {?}
  250. */
  251. function (event) {
  252. /** @type {?} */
  253. var keyCode = event.keyCode;
  254. /** @type {?} */
  255. var isTargetRow = event.target === this._element;
  256. /** @type {?} */
  257. var isAction = keyCode === Keys.return ||
  258. keyCode === Keys.down ||
  259. keyCode === Keys.up ||
  260. keyCode === Keys.left ||
  261. keyCode === Keys.right;
  262. if (isAction && isTargetRow) {
  263. event.preventDefault();
  264. event.stopPropagation();
  265. this.activate.emit({
  266. type: 'keydown',
  267. event: event,
  268. row: this.row,
  269. rowElement: this._element
  270. });
  271. }
  272. };
  273. /**
  274. * @param {?} event
  275. * @return {?}
  276. */
  277. DataTableBodyRowComponent.prototype.onMouseenter = /**
  278. * @param {?} event
  279. * @return {?}
  280. */
  281. function (event) {
  282. this.activate.emit({
  283. type: 'mouseenter',
  284. event: event,
  285. row: this.row,
  286. rowElement: this._element
  287. });
  288. };
  289. /**
  290. * @param {?=} val
  291. * @return {?}
  292. */
  293. DataTableBodyRowComponent.prototype.recalculateColumns = /**
  294. * @param {?=} val
  295. * @return {?}
  296. */
  297. function (val) {
  298. if (val === void 0) { val = this.columns; }
  299. this._columns = val;
  300. /** @type {?} */
  301. var colsByPin = columnsByPin(this._columns);
  302. this._columnsByPin = columnsByPinArr(this._columns);
  303. this._columnGroupWidths = columnGroupWidths(colsByPin, this._columns);
  304. };
  305. /**
  306. * @return {?}
  307. */
  308. DataTableBodyRowComponent.prototype.onTreeAction = /**
  309. * @return {?}
  310. */
  311. function () {
  312. this.treeAction.emit();
  313. };
  314. DataTableBodyRowComponent.decorators = [
  315. { type: Component, args: [{
  316. selector: 'datatable-body-row',
  317. changeDetection: ChangeDetectionStrategy.OnPush,
  318. template: "\n <div\n *ngFor=\"let colGroup of _columnsByPin; let i = index; trackBy: trackByGroups\"\n class=\"datatable-row-{{ colGroup.type }} datatable-row-group\"\n [ngStyle]=\"_groupStyles[colGroup.type]\"\n >\n <datatable-body-cell\n *ngFor=\"let column of colGroup.columns; let ii = index; trackBy: columnTrackingFn\"\n tabindex=\"-1\"\n [row]=\"row\"\n [group]=\"group\"\n [expanded]=\"expanded\"\n [isSelected]=\"isSelected\"\n [rowIndex]=\"rowIndex\"\n [column]=\"column\"\n [rowHeight]=\"rowHeight\"\n [displayCheck]=\"displayCheck\"\n [treeStatus]=\"treeStatus\"\n (activate)=\"onActivate($event, ii)\"\n (treeAction)=\"onTreeAction()\"\n >\n </datatable-body-cell>\n </div>\n "
  319. }] }
  320. ];
  321. /** @nocollapse */
  322. DataTableBodyRowComponent.ctorParameters = function () { return [
  323. { type: KeyValueDiffers },
  324. { type: ScrollbarHelper, decorators: [{ type: SkipSelf }] },
  325. { type: ChangeDetectorRef },
  326. { type: ElementRef }
  327. ]; };
  328. DataTableBodyRowComponent.propDecorators = {
  329. columns: [{ type: Input }],
  330. innerWidth: [{ type: Input }],
  331. expanded: [{ type: Input }],
  332. rowClass: [{ type: Input }],
  333. row: [{ type: Input }],
  334. group: [{ type: Input }],
  335. isSelected: [{ type: Input }],
  336. rowIndex: [{ type: Input }],
  337. displayCheck: [{ type: Input }],
  338. treeStatus: [{ type: Input }],
  339. offsetX: [{ type: Input }],
  340. cssClass: [{ type: HostBinding, args: ['class',] }],
  341. rowHeight: [{ type: HostBinding, args: ['style.height.px',] }, { type: Input }],
  342. columnsTotalWidths: [{ type: HostBinding, args: ['style.width.px',] }],
  343. activate: [{ type: Output }],
  344. treeAction: [{ type: Output }],
  345. onKeyDown: [{ type: HostListener, args: ['keydown', ['$event'],] }],
  346. onMouseenter: [{ type: HostListener, args: ['mouseenter', ['$event'],] }]
  347. };
  348. return DataTableBodyRowComponent;
  349. }());
  350. export { DataTableBodyRowComponent };
  351. if (false) {
  352. /** @type {?} */
  353. DataTableBodyRowComponent.prototype.expanded;
  354. /** @type {?} */
  355. DataTableBodyRowComponent.prototype.rowClass;
  356. /** @type {?} */
  357. DataTableBodyRowComponent.prototype.row;
  358. /** @type {?} */
  359. DataTableBodyRowComponent.prototype.group;
  360. /** @type {?} */
  361. DataTableBodyRowComponent.prototype.isSelected;
  362. /** @type {?} */
  363. DataTableBodyRowComponent.prototype.rowIndex;
  364. /** @type {?} */
  365. DataTableBodyRowComponent.prototype.displayCheck;
  366. /** @type {?} */
  367. DataTableBodyRowComponent.prototype.treeStatus;
  368. /** @type {?} */
  369. DataTableBodyRowComponent.prototype.rowHeight;
  370. /** @type {?} */
  371. DataTableBodyRowComponent.prototype.activate;
  372. /** @type {?} */
  373. DataTableBodyRowComponent.prototype.treeAction;
  374. /** @type {?} */
  375. DataTableBodyRowComponent.prototype._element;
  376. /** @type {?} */
  377. DataTableBodyRowComponent.prototype._columnGroupWidths;
  378. /** @type {?} */
  379. DataTableBodyRowComponent.prototype._columnsByPin;
  380. /** @type {?} */
  381. DataTableBodyRowComponent.prototype._offsetX;
  382. /** @type {?} */
  383. DataTableBodyRowComponent.prototype._columns;
  384. /** @type {?} */
  385. DataTableBodyRowComponent.prototype._innerWidth;
  386. /** @type {?} */
  387. DataTableBodyRowComponent.prototype._groupStyles;
  388. /**
  389. * @type {?}
  390. * @private
  391. */
  392. DataTableBodyRowComponent.prototype._rowDiffer;
  393. /**
  394. * @type {?}
  395. * @private
  396. */
  397. DataTableBodyRowComponent.prototype.differs;
  398. /**
  399. * @type {?}
  400. * @private
  401. */
  402. DataTableBodyRowComponent.prototype.scrollbarHelper;
  403. /**
  404. * @type {?}
  405. * @private
  406. */
  407. DataTableBodyRowComponent.prototype.cd;
  408. }
  409. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9keS1yb3cuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQHN3aW1sYW5lL25neC1kYXRhdGFibGUvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9ib2R5L2JvZHktcm93LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUNMLFdBQVcsRUFDWCxVQUFVLEVBQ1YsTUFBTSxFQUNOLGVBQWUsRUFFZixZQUFZLEVBQ1osWUFBWSxFQUNaLHVCQUF1QixFQUN2QixpQkFBaUIsRUFFakIsUUFBUSxFQUNULE1BQU0sZUFBZSxDQUFDO0FBR3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDdEYsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3hDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFcEQ7SUFnSUUsbUNBQ1UsT0FBd0IsRUFDWixlQUFnQyxFQUM1QyxFQUFxQixFQUM3QixPQUFtQjtRQUhYLFlBQU8sR0FBUCxPQUFPLENBQWlCO1FBQ1osb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQzVDLE9BQUUsR0FBRixFQUFFLENBQW1CO1FBdEV0QixlQUFVLEdBQWUsV0FBVyxDQUFDO1FBa0RwQyxhQUFRLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDakQsZUFBVSxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO1FBUTdELGlCQUFZLEdBQTJCO1lBQ3JDLElBQUksRUFBRSxFQUFFO1lBQ1IsTUFBTSxFQUFFLEVBQUU7WUFDVixLQUFLLEVBQUUsRUFBRTtTQUNWLENBQUM7UUFVQSxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUM7UUFDdEMsSUFBSSxD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LFdBQVcsU0FBQyxpQkFBaUIsY0FDN0IsS0FBSztxQ0FHTCxXQUFXLFNBQUMsZ0JBQWdCOzJCQUs1QixNQUFNOzZCQUNOLE1BQU07NEJBMEVOLFlBQVksU0FBQyxTQUFTLEVBQUUsQ0FBQyxRQUFRLENBQUM7K0JBeUJsQyxZQUFZLFNBQUMsWUFBWSxFQUFFLENBQUMsUUFBUSxDQUFDOztJQW9CeEMsZ0NBQUM7Q0FBQSxBQXZPRCxJQXVPQztTQTNNWSx5QkFBeUI7OztJQTBCcEMsNkNBQTJCOztJQUMzQiw2Q0FBdUI7O0lBQ3ZCLHdDQUFrQjs7SUFDbEIsMENBQW9COztJQUNwQiwrQ0FBNkI7O0lBQzdCLDZDQUEwQjs7SUFDMUIsaURBQTJCOztJQUMzQiwrQ0FBOEM7O0lBeUM5Qyw4Q0FFa0I7O0lBT2xCLDZDQUEyRDs7SUFDM0QsK0NBQTZEOztJQUU3RCw2Q0FBYzs7SUFDZCx1REFBd0I7O0lBQ3hCLGtEQUFtQjs7SUFDbkIsNkNBQWlCOztJQUNqQiw2Q0FBZ0I7O0lBQ2hCLGdEQUFvQjs7SUFDcEIsaURBSUU7Ozs7O0lBRUYsK0NBQTJDOzs7OztJQUd6Qyw0Q0FBZ0M7Ozs7O0lBQ2hDLG9EQUFvRDs7Ozs7SUFDcEQsdUNBQTZCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgSG9zdEJpbmRpbmcsXG4gIEVsZW1lbnRSZWYsXG4gIE91dHB1dCxcbiAgS2V5VmFsdWVEaWZmZXJzLFxuICBLZXlWYWx1ZURpZmZlcixcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0TGlzdGVuZXIsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgRG9DaGVjayxcbiAgU2tpcFNlbGZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IFRyZWVTdGF0dXMgfSBmcm9tICcuL2JvZHktY2VsbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgY29sdW1uc0J5UGluLCBjb2x1bW5Hcm91cFdpZHRocywgY29sdW1uc0J5UGluQXJyIH0gZnJvbSAnLi4vLi4vdXRpbHMvY29sdW1uJztcbmltcG9ydCB7IEtleXMgfSBmcm9tICcuLi8uLi91dGlscy9rZXlzJztcbmltcG9ydCB7IFNjcm9sbGJhckhlbHBlciB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3Njcm9sbGJhci1oZWxwZXIuc2VydmljZSc7XG5pbXBvcnQgeyB0cmFuc2xhdGVYWSB9IGZyb20gJy4uLy4uL3V0aWxzL3RyYW5zbGF0ZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2RhdGF0YWJsZS1ib2R5LXJvdycsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXZcbiAgICAgICpuZ0Zvcj1cImxldCBjb2xHcm91cCBvZiBfY29sdW1uc0J5UGluOyBsZXQgaSA9IGluZGV4OyB0cmFja0J5OiB0cmFja0J5R3JvdXBzXCJcbiAgICAgIGNsYXNzPVwiZGF0YXRhYmxlLXJvdy17eyBjb2xHcm91cC50eXBlIH19IGRhdGF0YWJsZS1yb3ctZ3JvdXBcIlxuICAgICAgW25nU3R5bGVdPVwiX2dyb3VwU3R5bGVzW2NvbEdyb3VwLnR5cGVdXCJcbiAgICA+XG4gICAgICA8ZGF0YXRhYmxlLWJvZHktY2VsbFxuICAgICAgICAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGNvbEdyb3VwLmNvbHVtbnM7IGxldCBpaSA9IGluZGV4OyB0cmFja0J5OiBjb2x1bW5UcmFja2luZ0ZuXCJcbiAgICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgICAgIFtyb3ddPVwicm93XCJcbiAgICAgICAgW2dyb3VwXT1cImdyb3VwXCJcbiAgICAgICAgW2V4cGFuZGVkXT1cImV4cGFuZGVkXCJcbiAgICAgICAgW2lzU2VsZWN0ZWRdPVwiaXNTZWxlY3RlZFwiXG4gICAgICAgIFtyb3dJbmRleF09XCJyb3dJbmRleFwiXG4gICAgICAgIFtjb2x1bW5dPVwiY29sdW1uXCJcbiAgICAgICAgW3Jvd0hlaWdodF09XCJyb3dIZWlnaHRcIlxuICAgICAgICBbZGlzcGxheUNoZWNrXT1cImRpc3BsYXlDaGVja1wiXG4gICAgICAgIFt0cmVlU3RhdHVzXT1cInRyZWVTdGF0dXNcIlxuICAgICAgICAoYWN0aXZhdGUpPVwib25BY3RpdmF0ZSgkZXZlbnQsIGlpKVwiXG4gICAgICAgICh0cmVlQWN0aW9uKT1cIm9uVHJlZUFjdGlvbigpXCJcbiAgICAgID5cbiAgICAgIDwvZGF0YXRhYmxlLWJvZHktY2VsbD5cbiAgICA8L2Rpdj5cbiAgYFxufSlcbmV4cG9ydCBjbGFzcyBEYXRhVGFibGVCb2R5Um93Q29tcG9uZW50IGltcGxlbWVudHMgRG9DaGVjayB7XG4gIEBJbnB1dCgpIHNldCBjb2x1bW5zKHZhbDogYW55W10pIHtcbiAgICB0aGlzLl9jb2x1bW5zID0gdmFsO1xuICAgIHRoaXMucmVjYWxjdWxhdGVDb2x1bW5zKHZhbCk7XG4gICAgdGhpcy5idWlsZFN0eWxlc0J5R3JvdXAoKTtcbiAgfVxuXG4gIGdldCBjb2x1bW5zKCk6IGFueVtdIHtcbiAgICByZXR1cm4gdGhpcy5fY29sdW1ucztcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCBpbm5lcldpZHRoKHZhbDogbnVtYmVyKSB7XG4gICAgaWYgKHRoaXMuX2NvbHVtbnMpIHtcbiAgICAgIGNvbnN0IGNvbEJ5UGluID0gY29sdW1uc0J5UGluKHRoaXMuX2NvbHVtbnMpO1xuICAgICAgdGhpcy5fY29sdW1uR3JvdXBXaWR0aHMgPSBjb2x1bW5Hcm91cFdpZHRocyhjb2xCeVBpbiwgdGhpcy5fY29sdW1ucyk7XG4gICAgfVxuXG4gICAgdGhpcy5faW5uZXJXaWR0aCA9IHZhbDtcbiAgICB0aGlzLnJlY2FsY3VsYXRlQ29sdW1ucygpO1xuICAgIHRoaXMuYnVpbGRTdHlsZXNCeUdyb3VwKCk7XG4gIH1cblxuICBnZXQgaW5uZXJXaWR0aCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9pbm5lcldpZHRoO1xuICB9XG5cbiAgQElucHV0KCkgZXhwYW5kZWQ6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHJvd0NsYXNzOiBhbnk7XG4gIEBJbnB1dCgpIHJvdzogYW55O1xuICBASW5wdXQoKSBncm91cDogYW55O1xuICBASW5wdXQoKSBpc1NlbGVjdGVkOiBib29sZWFuO1xuICBASW5wdXQoKSByb3dJbmRleDogbnVtYmVyO1xuICBASW5wdXQoKSBkaXNwbGF5Q2hlY2s6IGFueTtcbiAgQElucHV0KCkgdHJlZVN0YXR1czogVHJlZVN0YXR1cyA9ICdjb2xsYXBzZWQnO1xuXG4gIEBJbnB1dCgpXG4gIHNldCBvZmZzZXRYKHZhbDogbnVtYmVyKSB7XG4gICAgdGhpcy5fb2Zmc2V0WCA9IHZhbDtcbiAgICB0aGlzLmJ1aWxkU3R5bGVzQnlHcm91cCgpO1xuICB9XG4gIGdldCBvZmZzZXRYKCkge1xuICAgIHJldHVybiB0aGlzLl9vZmZzZXRYO1xuICB9XG5cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcycpXG4gIGdldCBjc3NDbGFzcygpIHtcbiAgICBsZXQgY2xzID0gJ2RhdGF0YWJsZS1ib2R5LXJvdyc7XG4gICAgaWYgKHRoaXMuaXNTZWxlY3RlZCkge1xuICAgICAgY2xzICs9ICcgYWN0aXZlJztcbiAgICB9XG4gICAgaWYgKHRoaXMucm93SW5kZXggJSAyICE9PSAwKSB7XG4gICAgICBjbHMgKz0gJyBkYXRhdGFibGUtcm93LW9kZCc7XG4gICAgfVxuICAgIGlmICh0aGlzLnJvd0luZGV4ICUgMiA9PT0gMCkge1xuICAgICAgY2xzICs9ICcgZGF0YXRhYmxlLXJvdy1ldmVuJztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5yb3dDbGFzcykge1xuICAgICAgY29uc3QgcmVzID0gdGhpcy5yb3dDbGFzcyh0aGlzLnJvdyk7XG4gICAgICBpZiAodHlwZW9mIHJlcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY2xzICs9IGAgJHtyZXN9YDtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHJlcyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHJlcyk7XG4gICAgICAgIGZvciAoY29uc3QgayBvZiBrZXlzKSB7XG4gICAgICAgICAgaWYgKHJlc1trXSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgY2xzICs9IGAgJHtrfWA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGNscztcbiAgfVxuXG4gIEBIb3N0QmluZGluZygnc3R5bGUuaGVpZ2h0LnB4JylcbiAgQElucHV0KClcbiAgcm93SGVpZ2h0OiBudW1iZXI7XG5cbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS53aWR0aC5weCcpXG4gIGdldCBjb2x1bW5zVG90YWxXaWR0aHMoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fY29sdW1uR3JvdXBXaWR0aHMudG90YWw7XG4gIH1cblxuICBAT3V0cHV0KCkgYWN0aXZhdGU6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgdHJlZUFjdGlvbjogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgX2VsZW1lbnQ6IGFueTtcbiAgX2NvbHVtbkdyb3VwV2lkdGhzOiBhbnk7XG4gIF9jb2x1bW5zQnlQaW46IGFueTtcbiAgX29mZnNldFg6IG51bWJlcjtcbiAgX2NvbHVtbnM6IGFueVtdO1xuICBfaW5uZXJXaWR0aDogbnVtYmVyO1xuICBfZ3JvdXBTdHlsZXM6IHsgW3Byb3A6IHN0cmluZ106IHt9IH0gPSB7XG4gICAgbGVmdDoge30sXG4gICAgY2VudGVyOiB7fSxcbiAgICByaWdodDoge31cbiAgfTtcblxuICBwcml2YXRlIF9yb3dEaWZmZXI6IEtleVZhbHVlRGlmZmVyPHt9LCB7fT47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBkaWZmZXJzOiBLZXlWYWx1ZURpZmZlcnMsXG4gICAgQFNraXBTZWxmKCkgcHJpdmF0ZSBzY3JvbGxiYXJIZWxwZXI6IFNjcm9sbGJhckhlbHBlcixcbiAgICBwcml2YXRlIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBlbGVtZW50OiBFbGVtZW50UmVmXG4gICkge1xuICAgIHRoaXMuX2VsZW1lbnQgPSBlbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5fcm93RGlmZmVyID0gZGlmZmVycy5maW5kKHt9KS5jcmVhdGUoKTtcbiAgfVxuXG4gIG5nRG9DaGVjaygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fcm93RGlmZmVyLmRpZmYodGhpcy5yb3cpKSB7XG4gICAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIHRyYWNrQnlHcm91cHMoaW5kZXg6IG51bWJlciwgY29sR3JvdXA6IGFueSk6IGFueSB7XG4gICAgcmV0dXJuIGNvbEdyb3VwLnR5cGU7XG4gIH1cblxuICBjb2x1bW5UcmFja2luZ0ZuKGluZGV4OiBudW1iZXIsIGNvbHVtbjogYW55KTogYW55IHtcbiAgICByZXR1cm4gY29sdW1uLiQkaWQ7XG4gIH1cblxuICBidWlsZFN0eWxlc0J5R3JvdXAoKSB7XG4gICAgdGhpcy5fZ3JvdXBTdHlsZXMubGVmdCA9IHRoaXMuY2FsY1N0eWxlc0J5R3JvdXAoJ2xlZnQnKTtcbiAgICB0aGlzLl9ncm91cFN0eWxlcy5jZW50ZXIgPSB0aGlzLmNhbGNTdHlsZXNCeUdyb3VwKCdjZW50ZXInKTtcbiAgICB0aGlzLl9ncm91cFN0eWxlcy5yaWdodCA9IHRoaXMuY2FsY1N0eWxlc0J5R3JvdXAoJ3JpZ2h0Jyk7XG4gICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIGNhbGNTdHlsZXNCeUdyb3VwKGdyb3VwOiBzdHJpbmcpIHtcbiAgICBjb25zdCB3aWR0aHMgPSB0aGlzLl9jb2x1bW5Hcm91cFdpZHRocztcbiAgICBjb25zdCBvZmZzZXRYID0gdGhpcy5vZmZzZXRYO1xuXG4gICAgY29uc3Qgc3R5bGVzID0ge1xuICAgICAgd2lkdGg6IGAke3dpZHRoc1tncm91cF19cHhgXG4gICAgfTtcblxuICAgIGlmIChncm91cCA9PT0gJ2xlZnQnKSB7XG4gICAgICB0cmFuc2xhdGVYWShzdHlsZXMsIG9mZnNldFgsIDApO1xuICAgIH0gZWxzZSBpZiAoZ3JvdXAgPT09ICdyaWdodCcpIHtcbiAgICAgIGNvbnN0IGJvZHlXaWR0aCA9IHBhcnNlSW50KHRoaXMuaW5uZXJXaWR0aCArICcnLCAwKTtcbiAgICAgIGNvbnN0IHRvdGFsRGlmZiA9IHdpZHRocy50b3RhbCAtIGJvZHlXaWR0aDtcbiAgICAgIGNvbnN0IG9mZnNldERpZmYgPSB0b3RhbERpZmYgLSBvZmZzZXRYO1xuICAgICAgY29uc3Qgb2Zmc2V0ID0gKG9mZnNldERpZmYgKyB0aGlzLnNjcm9sbGJhckhlbHBlci53aWR0aCkgKiAtMTtcbiAgICAgIHRyYW5zbGF0ZVhZKHN0eWxlcywgb2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3R5bGVzO1xuICB9XG5cbiAgb25BY3RpdmF0ZShldmVudDogYW55LCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgZXZlbnQuY2VsbEluZGV4ID0gaW5kZXg7XG4gICAgZXZlbnQucm93RWxlbWVudCA9IHRoaXMuX2VsZW1lbnQ7XG4gICAgdGhpcy5hY3RpdmF0ZS5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2tleWRvd24nLCBbJyRldmVudCddKVxuICBvbktleURvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBrZXlDb2RlID0gZXZlbnQua2V5Q29kZTtcbiAgICBjb25zdCBpc1RhcmdldFJvdyA9IGV2ZW50LnRhcmdldCA9PT0gdGhpcy5fZWxlbWVudDtcblxuICAgIGNvbnN0IGlzQWN0aW9uID1cbiAgICAgIGtleUNvZGUgPT09IEtleXMucmV0dXJuIHx8XG4gICAgICBrZXlDb2RlID09PSBLZXlzLmRvd24gfHxcbiAgICAgIGtleUNvZGUgPT09IEtleXMudXAgfHxcbiAgICAgIGtleUNvZGUgPT09IEtleXMubGVmdCB8fFxuICAgICAga2V5Q29kZSA9PT0gS2V5cy5yaWdodDtcblxuICAgIGlmIChpc0FjdGlvbiAmJiBpc1RhcmdldFJvdykge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICB0aGlzLmFjdGl2YXRlLmVtaXQoe1xuICAgICAgICB0eXBlOiAna2V5ZG93bicsXG4gICAgICAgIGV2ZW50LFxuICAgICAgICByb3c6IHRoaXMucm93LFxuICAgICAgICByb3dFbGVtZW50OiB0aGlzLl9lbGVtZW50XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdtb3VzZWVudGVyJywgWyckZXZlbnQnXSlcbiAgb25Nb3VzZWVudGVyKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2YXRlLmVtaXQoe1xuICAgICAgdHlwZTogJ21vdXNlZW50ZXInLFxuICAgICAgZXZlbnQsXG4gICAgICByb3c6IHRoaXMucm93LFxuICAgICAgcm93RWxlbWVudDogdGhpcy5fZWxlbWVudFxuICAgIH0pO1xuICB9XG5cbiAgcmVjYWxjdWxhdGVDb2x1bW5zKHZhbDogYW55W10gPSB0aGlzLmNvbHVtbnMpOiB2b2lkIHtcbiAgICB0aGlzLl9jb2x1bW5zID0gdmFsO1xuICAgIGNvbnN0IGNvbHNCeVBpbiA9IGNvbHVtbnNCeVBpbih0aGlzLl9jb2x1bW5zKTtcbiAgICB0aGlzLl9jb2x1bW5zQnlQaW4gPSBjb2x1bW5zQnlQaW5BcnIodGhpcy5fY29sdW1ucyk7XG4gICAgdGhpcy5fY29sdW1uR3JvdXBXaWR0aHMgPSBjb2x1bW5Hcm91cFdpZHRocyhjb2xzQnlQaW4sIHRoaXMuX2NvbHVtbnMpO1xuICB9XG5cbiAgb25UcmVlQWN0aW9uKCkge1xuICAgIHRoaXMudHJlZUFjdGlvbi5lbWl0KCk7XG4gIH1cbn1cbiJdfQ==