contextMenu.service.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  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 { Overlay, ScrollStrategyOptions } from '@angular/cdk/overlay';
  7. import { ComponentPortal } from '@angular/cdk/portal';
  8. import { Injectable, ElementRef } from '@angular/core';
  9. import { Subject, Subscription } from 'rxjs';
  10. import { ContextMenuContentComponent } from './contextMenuContent.component';
  11. /**
  12. * @record
  13. */
  14. export function IContextMenuClickEvent() { }
  15. if (false) {
  16. /** @type {?|undefined} */
  17. IContextMenuClickEvent.prototype.anchorElement;
  18. /** @type {?|undefined} */
  19. IContextMenuClickEvent.prototype.contextMenu;
  20. /** @type {?|undefined} */
  21. IContextMenuClickEvent.prototype.event;
  22. /** @type {?|undefined} */
  23. IContextMenuClickEvent.prototype.parentContextMenu;
  24. /** @type {?} */
  25. IContextMenuClickEvent.prototype.item;
  26. /** @type {?|undefined} */
  27. IContextMenuClickEvent.prototype.activeMenuItemIndex;
  28. }
  29. /**
  30. * @record
  31. */
  32. export function IContextMenuContext() { }
  33. if (false) {
  34. /** @type {?} */
  35. IContextMenuContext.prototype.menuItems;
  36. /** @type {?} */
  37. IContextMenuContext.prototype.menuClass;
  38. }
  39. /**
  40. * @record
  41. */
  42. export function CloseLeafMenuEvent() { }
  43. if (false) {
  44. /** @type {?|undefined} */
  45. CloseLeafMenuEvent.prototype.exceptRootMenu;
  46. /** @type {?|undefined} */
  47. CloseLeafMenuEvent.prototype.event;
  48. }
  49. /**
  50. * @record
  51. */
  52. export function OverlayRefWithContextMenu() { }
  53. if (false) {
  54. /** @type {?|undefined} */
  55. OverlayRefWithContextMenu.prototype.contextMenu;
  56. }
  57. /**
  58. * @record
  59. */
  60. export function CancelContextMenuEvent() { }
  61. if (false) {
  62. /** @type {?} */
  63. CancelContextMenuEvent.prototype.eventType;
  64. /** @type {?|undefined} */
  65. CancelContextMenuEvent.prototype.event;
  66. }
  67. /**
  68. * @record
  69. */
  70. export function ExecuteContextMenuEvent() { }
  71. if (false) {
  72. /** @type {?} */
  73. ExecuteContextMenuEvent.prototype.eventType;
  74. /** @type {?|undefined} */
  75. ExecuteContextMenuEvent.prototype.event;
  76. /** @type {?} */
  77. ExecuteContextMenuEvent.prototype.item;
  78. /** @type {?} */
  79. ExecuteContextMenuEvent.prototype.menuItem;
  80. }
  81. var ContextMenuService = /** @class */ (function () {
  82. function ContextMenuService(overlay, scrollStrategy) {
  83. this.overlay = overlay;
  84. this.scrollStrategy = scrollStrategy;
  85. this.isDestroyingLeafMenu = false;
  86. this.show = new Subject();
  87. this.triggerClose = new Subject();
  88. this.close = new Subject();
  89. this.overlays = [];
  90. this.fakeElement = {
  91. getBoundingClientRect: (/**
  92. * @return {?}
  93. */
  94. function () { return ({
  95. bottom: 0,
  96. height: 0,
  97. left: 0,
  98. right: 0,
  99. top: 0,
  100. width: 0,
  101. }); })
  102. };
  103. }
  104. /**
  105. * @param {?} context
  106. * @return {?}
  107. */
  108. ContextMenuService.prototype.openContextMenu = /**
  109. * @param {?} context
  110. * @return {?}
  111. */
  112. function (context) {
  113. var anchorElement = context.anchorElement, event = context.event, parentContextMenu = context.parentContextMenu;
  114. if (!parentContextMenu) {
  115. /** @type {?} */
  116. var mouseEvent_1 = (/** @type {?} */ (event));
  117. this.fakeElement.getBoundingClientRect = (/**
  118. * @return {?}
  119. */
  120. function () { return ({
  121. bottom: mouseEvent_1.clientY,
  122. height: 0,
  123. left: mouseEvent_1.clientX,
  124. right: mouseEvent_1.clientX,
  125. top: mouseEvent_1.clientY,
  126. width: 0,
  127. }); });
  128. this.closeAllContextMenus({ eventType: 'cancel', event: event });
  129. /** @type {?} */
  130. var positionStrategy = this.overlay.position().connectedTo(new ElementRef(anchorElement || this.fakeElement), { originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' })
  131. .withFallbackPosition({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'bottom' })
  132. .withFallbackPosition({ originX: 'end', originY: 'top' }, { overlayX: 'start', overlayY: 'top' })
  133. .withFallbackPosition({ originX: 'start', originY: 'top' }, { overlayX: 'end', overlayY: 'top' })
  134. .withFallbackPosition({ originX: 'end', originY: 'center' }, { overlayX: 'start', overlayY: 'center' })
  135. .withFallbackPosition({ originX: 'start', originY: 'center' }, { overlayX: 'end', overlayY: 'center' });
  136. this.overlays = [this.overlay.create({
  137. positionStrategy: positionStrategy,
  138. panelClass: 'ngx-contextmenu',
  139. scrollStrategy: this.scrollStrategy.close(),
  140. })];
  141. this.attachContextMenu(this.overlays[0], context);
  142. }
  143. else {
  144. /** @type {?} */
  145. var positionStrategy = this.overlay.position().connectedTo(new ElementRef(event ? event.target : anchorElement), { originX: 'end', originY: 'top' }, { overlayX: 'start', overlayY: 'top' })
  146. .withFallbackPosition({ originX: 'start', originY: 'top' }, { overlayX: 'end', overlayY: 'top' })
  147. .withFallbackPosition({ originX: 'end', originY: 'bottom' }, { overlayX: 'start', overlayY: 'bottom' })
  148. .withFallbackPosition({ originX: 'start', originY: 'bottom' }, { overlayX: 'end', overlayY: 'bottom' });
  149. /** @type {?} */
  150. var newOverlay = this.overlay.create({
  151. positionStrategy: positionStrategy,
  152. panelClass: 'ngx-contextmenu',
  153. scrollStrategy: this.scrollStrategy.close(),
  154. });
  155. this.destroySubMenus(parentContextMenu);
  156. this.overlays = this.overlays.concat(newOverlay);
  157. this.attachContextMenu(newOverlay, context);
  158. }
  159. };
  160. /**
  161. * @param {?} overlay
  162. * @param {?} context
  163. * @return {?}
  164. */
  165. ContextMenuService.prototype.attachContextMenu = /**
  166. * @param {?} overlay
  167. * @param {?} context
  168. * @return {?}
  169. */
  170. function (overlay, context) {
  171. var _this = this;
  172. var event = context.event, item = context.item, menuItems = context.menuItems, menuClass = context.menuClass;
  173. /** @type {?} */
  174. var contextMenuContent = overlay.attach(new ComponentPortal(ContextMenuContentComponent));
  175. contextMenuContent.instance.event = event;
  176. contextMenuContent.instance.item = item;
  177. contextMenuContent.instance.menuItems = menuItems;
  178. contextMenuContent.instance.overlay = overlay;
  179. contextMenuContent.instance.isLeaf = true;
  180. contextMenuContent.instance.menuClass = menuClass;
  181. ((/** @type {?} */ (overlay))).contextMenu = contextMenuContent.instance;
  182. /** @type {?} */
  183. var subscriptions = new Subscription();
  184. subscriptions.add(contextMenuContent.instance.execute.asObservable()
  185. .subscribe((/**
  186. * @param {?} executeEvent
  187. * @return {?}
  188. */
  189. function (executeEvent) { return _this.closeAllContextMenus(tslib_1.__assign({ eventType: 'execute' }, executeEvent)); })));
  190. subscriptions.add(contextMenuContent.instance.closeAllMenus.asObservable()
  191. .subscribe((/**
  192. * @param {?} closeAllEvent
  193. * @return {?}
  194. */
  195. function (closeAllEvent) { return _this.closeAllContextMenus(tslib_1.__assign({ eventType: 'cancel' }, closeAllEvent)); })));
  196. subscriptions.add(contextMenuContent.instance.closeLeafMenu.asObservable()
  197. .subscribe((/**
  198. * @param {?} closeLeafMenuEvent
  199. * @return {?}
  200. */
  201. function (closeLeafMenuEvent) { return _this.destroyLeafMenu(closeLeafMenuEvent); })));
  202. subscriptions.add(contextMenuContent.instance.openSubMenu.asObservable()
  203. .subscribe((/**
  204. * @param {?} subMenuEvent
  205. * @return {?}
  206. */
  207. function (subMenuEvent) {
  208. _this.destroySubMenus(contextMenuContent.instance);
  209. if (!subMenuEvent.contextMenu) {
  210. contextMenuContent.instance.isLeaf = true;
  211. return;
  212. }
  213. contextMenuContent.instance.isLeaf = false;
  214. _this.show.next(subMenuEvent);
  215. })));
  216. contextMenuContent.onDestroy((/**
  217. * @return {?}
  218. */
  219. function () {
  220. menuItems.forEach((/**
  221. * @param {?} menuItem
  222. * @return {?}
  223. */
  224. function (menuItem) { return menuItem.isActive = false; }));
  225. subscriptions.unsubscribe();
  226. }));
  227. contextMenuContent.changeDetectorRef.detectChanges();
  228. };
  229. /**
  230. * @param {?} closeEvent
  231. * @return {?}
  232. */
  233. ContextMenuService.prototype.closeAllContextMenus = /**
  234. * @param {?} closeEvent
  235. * @return {?}
  236. */
  237. function (closeEvent) {
  238. if (this.overlays) {
  239. this.close.next(closeEvent);
  240. this.overlays.forEach((/**
  241. * @param {?} overlay
  242. * @param {?} index
  243. * @return {?}
  244. */
  245. function (overlay, index) {
  246. overlay.detach();
  247. overlay.dispose();
  248. }));
  249. }
  250. this.overlays = [];
  251. };
  252. /**
  253. * @return {?}
  254. */
  255. ContextMenuService.prototype.getLastAttachedOverlay = /**
  256. * @return {?}
  257. */
  258. function () {
  259. /** @type {?} */
  260. var overlay = this.overlays[this.overlays.length - 1];
  261. while (this.overlays.length > 1 && overlay && !overlay.hasAttached()) {
  262. overlay.detach();
  263. overlay.dispose();
  264. this.overlays = this.overlays.slice(0, -1);
  265. overlay = this.overlays[this.overlays.length - 1];
  266. }
  267. return overlay;
  268. };
  269. /**
  270. * @param {?=} __0
  271. * @return {?}
  272. */
  273. ContextMenuService.prototype.destroyLeafMenu = /**
  274. * @param {?=} __0
  275. * @return {?}
  276. */
  277. function (_a) {
  278. var _this = this;
  279. var _b = _a === void 0 ? {} : _a, exceptRootMenu = _b.exceptRootMenu, event = _b.event;
  280. if (this.isDestroyingLeafMenu) {
  281. return;
  282. }
  283. this.isDestroyingLeafMenu = true;
  284. setTimeout((/**
  285. * @return {?}
  286. */
  287. function () {
  288. /** @type {?} */
  289. var overlay = _this.getLastAttachedOverlay();
  290. if (_this.overlays.length > 1 && overlay) {
  291. overlay.detach();
  292. overlay.dispose();
  293. }
  294. if (!exceptRootMenu && _this.overlays.length > 0 && overlay) {
  295. _this.close.next({ eventType: 'cancel', event: event });
  296. overlay.detach();
  297. overlay.dispose();
  298. }
  299. /** @type {?} */
  300. var newLeaf = _this.getLastAttachedOverlay();
  301. if (newLeaf) {
  302. newLeaf.contextMenu.isLeaf = true;
  303. }
  304. _this.isDestroyingLeafMenu = false;
  305. }));
  306. };
  307. /**
  308. * @param {?} contextMenu
  309. * @return {?}
  310. */
  311. ContextMenuService.prototype.destroySubMenus = /**
  312. * @param {?} contextMenu
  313. * @return {?}
  314. */
  315. function (contextMenu) {
  316. /** @type {?} */
  317. var overlay = contextMenu.overlay;
  318. /** @type {?} */
  319. var index = this.overlays.indexOf(overlay);
  320. this.overlays.slice(index + 1).forEach((/**
  321. * @param {?} subMenuOverlay
  322. * @return {?}
  323. */
  324. function (subMenuOverlay) {
  325. subMenuOverlay.detach();
  326. subMenuOverlay.dispose();
  327. }));
  328. };
  329. /**
  330. * @param {?} contextMenuContent
  331. * @return {?}
  332. */
  333. ContextMenuService.prototype.isLeafMenu = /**
  334. * @param {?} contextMenuContent
  335. * @return {?}
  336. */
  337. function (contextMenuContent) {
  338. /** @type {?} */
  339. var overlay = this.getLastAttachedOverlay();
  340. return contextMenuContent.overlay === overlay;
  341. };
  342. ContextMenuService.decorators = [
  343. { type: Injectable }
  344. ];
  345. /** @nocollapse */
  346. ContextMenuService.ctorParameters = function () { return [
  347. { type: Overlay },
  348. { type: ScrollStrategyOptions }
  349. ]; };
  350. return ContextMenuService;
  351. }());
  352. export { ContextMenuService };
  353. if (false) {
  354. /** @type {?} */
  355. ContextMenuService.prototype.isDestroyingLeafMenu;
  356. /** @type {?} */
  357. ContextMenuService.prototype.show;
  358. /** @type {?} */
  359. ContextMenuService.prototype.triggerClose;
  360. /** @type {?} */
  361. ContextMenuService.prototype.close;
  362. /**
  363. * @type {?}
  364. * @private
  365. */
  366. ContextMenuService.prototype.contextMenuContent;
  367. /**
  368. * @type {?}
  369. * @private
  370. */
  371. ContextMenuService.prototype.overlays;
  372. /**
  373. * @type {?}
  374. * @private
  375. */
  376. ContextMenuService.prototype.fakeElement;
  377. /**
  378. * @type {?}
  379. * @private
  380. */
  381. ContextMenuService.prototype.overlay;
  382. /**
  383. * @type {?}
  384. * @private
  385. */
  386. ContextMenuService.prototype.scrollStrategy;
  387. }
  388. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dE1lbnUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1jb250ZXh0bWVudS8iLCJzb3VyY2VzIjpbImxpYi9jb250ZXh0TWVudS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLE9BQU8sRUFBYyxxQkFBcUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RCxPQUFPLEVBQWdCLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDckUsT0FBTyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFJN0MsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7Ozs7QUFFN0UsNENBT0M7OztJQU5DLCtDQUFzQzs7SUFDdEMsNkNBQW1DOztJQUNuQyx1Q0FBbUM7O0lBQ25DLG1EQUFnRDs7SUFDaEQsc0NBQVU7O0lBQ1YscURBQTZCOzs7OztBQUUvQix5Q0FHQzs7O0lBRkMsd0NBQXNDOztJQUN0Qyx3Q0FBa0I7Ozs7O0FBRXBCLHdDQUdDOzs7SUFGQyw0Q0FBeUI7O0lBQ3pCLG1DQUFtQzs7Ozs7QUFFckMsK0NBRUM7OztJQURDLGdEQUEwQzs7Ozs7QUFHNUMsNENBR0M7OztJQUZDLDJDQUFvQjs7SUFDcEIsdUNBQW1DOzs7OztBQUVyQyw2Q0FLQzs7O0lBSkMsNENBQXFCOztJQUNyQix3Q0FBbUM7O0lBQ25DLHVDQUFVOztJQUNWLDJDQUFtQzs7QUFJckM7SUFxQkUsNEJBQ1UsT0FBZ0IsRUFDaEIsY0FBcUM7UUFEckMsWUFBTyxHQUFQLE9BQU8sQ0FBUztRQUNoQixtQkFBYyxHQUFkLGNBQWMsQ0FBdUI7UUFyQnhDLHlCQUFvQixHQUFHLEtBQUssQ0FBQztRQUU3QixTQUFJLEdBQW9DLElBQUksT0FBTyxFQUEwQixDQUFDO1FBQzlFLGlCQUFZLEdBQXlD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QWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN4QixjQUFjLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDM0IsQ0FBQyxFQUFDLENBQUM7SUFDTCxDQUFDOzs7OztJQUVNLHVDQUFVOzs7O0lBQWpCLFVBQWtCLGtCQUErQzs7WUFDekQsT0FBTyxHQUFHLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtRQUM3QyxPQUFPLGtCQUFrQixDQUFDLE9BQU8sS0FBSyxPQUFPLENBQUM7SUFDaEQsQ0FBQzs7Z0JBN0xGLFVBQVU7Ozs7Z0JBekNGLE9BQU87Z0JBQWMscUJBQXFCOztJQXVPbkQseUJBQUM7Q0FBQSxBQTlMRCxJQThMQztTQTdMWSxrQkFBa0I7OztJQUM3QixrREFBb0M7O0lBRXBDLGtDQUFxRjs7SUFDckYsMENBQTBFOztJQUMxRSxtQ0FBNkQ7Ozs7O0lBRTdELGdEQUFzRTs7Ozs7SUFDdEUsc0NBQW9DOzs7OztJQUNwQyx5Q0FTRTs7Ozs7SUFHQSxxQ0FBd0I7Ozs7O0lBQ3hCLDRDQUE2QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE92ZXJsYXksIE92ZXJsYXlSZWYsIFNjcm9sbFN0cmF0ZWd5T3B0aW9ucyB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7IENvbXBvbmVudFBvcnRhbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xuaW1wb3J0IHsgQ29tcG9uZW50UmVmLCBJbmplY3RhYmxlLCBFbGVtZW50UmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgQ29udGV4dE1lbnVDb21wb25lbnQgfSBmcm9tICcuL2NvbnRleHRNZW51LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmUgfSBmcm9tICcuL2NvbnRleHRNZW51Lml0ZW0uZGlyZWN0aXZlJztcbmltcG9ydCB7IENvbnRleHRNZW51Q29udGVudENvbXBvbmVudCB9IGZyb20gJy4vY29udGV4dE1lbnVDb250ZW50LmNvbXBvbmVudCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUNvbnRleHRNZW51Q2xpY2tFdmVudCB7XG4gIGFuY2hvckVsZW1lbnQ/OiBFbGVtZW50IHwgRXZlbnRUYXJnZXQ7XG4gIGNvbnRleHRNZW51PzogQ29udGV4dE1lbnVDb21wb25lbnQ7XG4gIGV2ZW50PzogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQ7XG4gIHBhcmVudENvbnRleHRNZW51PzogQ29udGV4dE1lbnVDb250ZW50Q29tcG9uZW50O1xuICBpdGVtOiBhbnk7XG4gIGFjdGl2ZU1lbnVJdGVtSW5kZXg/OiBudW1iZXI7XG59XG5leHBvcnQgaW50ZXJmYWNlIElDb250ZXh0TWVudUNvbnRleHQgZXh0ZW5kcyBJQ29udGV4dE1lbnVDbGlja0V2ZW50IHtcbiAgbWVudUl0ZW1zOiBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmVbXTtcbiAgbWVudUNsYXNzOiBzdHJpbmc7XG59XG5leHBvcnQgaW50ZXJmYWNlIENsb3NlTGVhZk1lbnVFdmVudCB7XG4gIGV4Y2VwdFJvb3RNZW51PzogYm9vbGVhbjtcbiAgZXZlbnQ/OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudDtcbn1cbmV4cG9ydCBpbnRlcmZhY2UgT3ZlcmxheVJlZldpdGhDb250ZXh0TWVudSBleHRlbmRzIE92ZXJsYXlSZWYge1xuICBjb250ZXh0TWVudT86IENvbnRleHRNZW51Q29udGVudENvbXBvbmVudDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDYW5jZWxDb250ZXh0TWVudUV2ZW50IHtcbiAgZXZlbnRUeXBlOiAnY2FuY2VsJztcbiAgZXZlbnQ/OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudDtcbn1cbmV4cG9ydCBpbnRlcmZhY2UgRXhlY3V0ZUNvbnRleHRNZW51RXZlbnQge1xuICBldmVudFR5cGU6ICdleGVjdXRlJztcbiAgZXZlbnQ/OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudDtcbiAgaXRlbTogYW55O1xuICBtZW51SXRlbTogQ29udGV4dE1lbnVJdGVtRGlyZWN0aXZlO1xufVxuZXhwb3J0IHR5cGUgQ2xvc2VDb250ZXh0TWVudUV2ZW50ID0gRXhlY3V0ZUNvbnRleHRNZW51RXZlbnQgfCBDYW5jZWxDb250ZXh0TWVudUV2ZW50O1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQ29udGV4dE1lbnVTZXJ2aWNlIHtcbiAgcHVibGljIGlzRGVzdHJveWluZ0xlYWZNZW51ID0gZmFsc2U7XG5cbiAgcHVibGljIHNob3c6IFN1YmplY3Q8SUNvbnRleHRNZW51Q2xpY2tFdmVudD4gPSBuZXcgU3ViamVjdDxJQ29udGV4dE1lbnVDbGlja0V2ZW50PigpO1xuICBwdWJsaWMgdHJpZ2dlckNsb3NlOiBTdWJqZWN0PENvbnRleHRNZW51Q29udGVudENvbXBvbmVudD4gPSBuZXcgU3ViamVjdCgpO1xuICBwdWJsaWMgY2xvc2U6IFN1YmplY3Q8Q2xvc2VDb250ZXh0TWVudUV2ZW50PiA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgcHJpdmF0ZSBjb250ZXh0TWVudUNvbnRlbnQ6IENvbXBvbmVudFJlZjxDb250ZXh0TWVudUNvbnRlbnRDb21wb25lbnQ+O1xuICBwcml2YXRlIG92ZXJsYXlzOiBPdmVybGF5UmVmW10gPSBbXTtcbiAgcHJpdmF0ZSBmYWtlRWxlbWVudDogYW55ID0ge1xuICAgIGdldEJvdW5kaW5nQ2xpZW50UmVjdDogKCk6IENsaWVudFJlY3QgPT4gKHtcbiAgICAgIGJvdHRvbTogMCxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IDAsXG4gICAgICByaWdodDogMCxcbiAgICAgIHRvcDogMCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH0pXG4gIH07XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBvdmVybGF5OiBPdmVybGF5LFxuICAgIHByaXZhdGUgc2Nyb2xsU3RyYXRlZ3k6IFNjcm9sbFN0cmF0ZWd5T3B0aW9ucyxcbiAgKSB7IH1cblxuICBwdWJsaWMgb3BlbkNvbnRleHRNZW51KGNvbnRleHQ6IElDb250ZXh0TWVudUNvbnRleHQpIHtcbiAgICBjb25zdCB7IGFuY2hvckVsZW1lbnQsIGV2ZW50LCBwYXJlbnRDb250ZXh0TWVudSB9ID0gY29udGV4dDtcblxuICAgIGlmICghcGFyZW50Q29udGV4dE1lbnUpIHtcbiAgICAgIGNvbnN0IG1vdXNlRXZlbnQgPSBldmVudCBhcyBNb3VzZUV2ZW50O1xuICAgICAgdGhpcy5mYWtlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QgPSAoKTogQ2xpZW50UmVjdCA9PiAoe1xuICAgICAgICBib3R0b206IG1vdXNlRXZlbnQuY2xpZW50WSxcbiAgICAgICAgaGVpZ2h0OiAwLFxuICAgICAgICBsZWZ0OiBtb3VzZUV2ZW50LmNsaWVudFgsXG4gICAgICAgIHJpZ2h0OiBtb3VzZUV2ZW50LmNsaWVudFgsXG4gICAgICAgIHRvcDogbW91c2VFdmVudC5jbGllbnRZLFxuICAgICAgICB3aWR0aDogMCxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5jbG9zZUFsbENvbnRleHRNZW51cyh7IGV2ZW50VHlwZTogJ2NhbmNlbCcsIGV2ZW50IH0pO1xuICAgICAgY29uc3QgcG9zaXRpb25TdHJhdGVneSA9IHRoaXMub3ZlcmxheS5wb3NpdGlvbigpLmNvbm5lY3RlZFRvKFxuICAgICAgICBuZXcgRWxlbWVudFJlZihhbmNob3JFbGVtZW50IHx8IHRoaXMuZmFrZUVsZW1lbnQpLFxuICAgICAgICB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICdib3R0b20nIH0sXG4gICAgICAgIHsgb3ZlcmxheVg6ICdzdGFydCcsIG92ZXJsYXlZOiAndG9wJyB9KVxuICAgICAgICAud2l0aEZhbGxiYWNrUG9zaXRpb24oXG4gICAgICAgIHsgb3JpZ2luWDogJ3N0YXJ0Jywgb3JpZ2luWTogJ3RvcCcgfSxcbiAgICAgICAgeyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICdib3R0b20nIH0pXG4gICAgICAgIC53aXRoRmFsbGJhY2tQb3NpdGlvbihcbiAgICAgICAgeyBvcmlnaW5YOiAnZW5kJywgb3JpZ2luWTogJ3RvcCcgfSxcbiAgICAgICAgeyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICd0b3AnIH0pXG4gICAgICAgIC53aXRoRmFsbGJhY2tQb3NpdGlvbihcbiAgICAgICAgeyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAndG9wJyB9LFxuICAgICAgICB7IG92ZXJsYXlYOiAnZW5kJywgb3ZlcmxheVk6ICd0b3AnIH0pXG4gICAgICAgIC53aXRoRmFsbGJhY2tQb3NpdGlvbihcbiAgICAgICAgeyBvcmlnaW5YOiAnZW5kJywgb3JpZ2luWTogJ2NlbnRlcicgfSxcbiAgICAgICAgeyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICdjZW50ZXInIH0pXG4gICAgICAgIC53aXRoRmFsbGJhY2tQb3NpdGlvbihcbiAgICAgICAgeyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAnY2VudGVyJyB9LFxuICAgICAgICB7IG92ZXJsYXlYOiAnZW5kJywgb3ZlcmxheVk6ICdjZW50ZXInIH0pXG4gICAgICAgIDtcbiAgICAgIHRoaXMub3ZlcmxheXMgPSBbdGhpcy5vdmVybGF5LmNyZWF0ZSh7XG4gICAgICAgIHBvc2l0aW9uU3RyYXRlZ3ksXG4gICAgICAgIHBhbmVsQ2xhc3M6ICduZ3gtY29udGV4dG1lbnUnLFxuICAgICAgICBzY3JvbGxTdHJhdGVneTogdGhpcy5zY3JvbGxTdHJhdGVneS5jbG9zZSgpLFxuICAgICAgfSldO1xuICAgICAgdGhpcy5hdHRhY2hDb250ZXh0TWVudSh0aGlzLm92ZXJsYXlzWzBdLCBjb250ZXh0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcG9zaXRpb25TdHJhdGVneSA9IHRoaXMub3ZlcmxheS5wb3NpdGlvbigpLmNvbm5lY3RlZFRvKFxuICAgICAgICBuZXcgRWxlbWVudFJlZihldmVudCA/IGV2ZW50LnRhcmdldCA6IGFuY2hvckVsZW1lbnQpLFxuICAgICAgICB7IG9yaWdpblg6ICdlbmQnLCBvcmlnaW5ZOiAndG9wJyB9LFxuICAgICAgICB7IG92ZXJsYXlYOiAnc3RhcnQnLCBvdmVybGF5WTogJ3RvcCcgfSlcbiAgICAgICAgLndpdGhGYWxsYmFja1Bvc2l0aW9uKFxuICAgICAgICB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICd0b3AnIH0sXG4gICAgICAgIHsgb3ZlcmxheVg6ICdlbmQnLCBvdmVybGF5WTogJ3RvcCcgfSlcbiAgICAgICAgLndpdGhGYWxsYmFja1Bvc2l0aW9uKFxuICAgICAgICB7IG9yaWdpblg6ICdlbmQnLCBvcmlnaW5ZOiAnYm90dG9tJyB9LFxuICAgICAgICB7IG92ZXJsYXlYOiAnc3RhcnQnLCBvdmVybGF5WTogJ2JvdHRvbScgfSlcbiAgICAgICAgLndpdGhGYWxsYmFja1Bvc2l0aW9uKFxuICAgICAgICB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICdib3R0b20nIH0sXG4gICAgICAgIHsgb3ZlcmxheVg6ICdlbmQnLCBvdmVybGF5WTogJ2JvdHRvbScgfSlcbiAgICAgICAgO1xuICAgICAgY29uc3QgbmV3T3ZlcmxheSA9IHRoaXMub3ZlcmxheS5jcmVhdGUoe1xuICAgICAgICBwb3NpdGlvblN0cmF0ZWd5LFxuICAgICAgICBwYW5lbENsYXNzOiAnbmd4LWNvbnRleHRtZW51JyxcbiAgICAgICAgc2Nyb2xsU3RyYXRlZ3k6IHRoaXMuc2Nyb2xsU3RyYXRlZ3kuY2xvc2UoKSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5kZXN0cm95U3ViTWVudXMocGFyZW50Q29udGV4dE1lbnUpO1xuICAgICAgdGhpcy5vdmVybGF5cyA9IHRoaXMub3ZlcmxheXMuY29uY2F0KG5ld092ZXJsYXkpO1xuICAgICAgdGhpcy5hdHRhY2hDb250ZXh0TWVudShuZXdPdmVybGF5LCBjb250ZXh0KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXR0YWNoQ29udGV4dE1lbnUob3ZlcmxheTogT3ZlcmxheVJlZiwgY29udGV4dDogSUNvbnRleHRNZW51Q29udGV4dCk6IHZvaWQge1xuICAgIGNvbnN0IHsgZXZlbnQsIGl0ZW0sIG1lbnVJdGVtcywgbWVudUNsYXNzIH0gPSBjb250ZXh0O1xuXG4gICAgY29uc3QgY29udGV4dE1lbnVDb250ZW50OiBDb21wb25lbnRSZWY8Q29udGV4dE1lbnVDb250ZW50Q29tcG9uZW50PiA9IG92ZXJsYXkuYXR0YWNoKG5ldyBDb21wb25lbnRQb3J0YWwoQ29udGV4dE1lbnVDb250ZW50Q29tcG9uZW50KSk7XG4gICAgY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlLmV2ZW50ID0gZXZlbnQ7XG4gICAgY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlLml0ZW0gPSBpdGVtO1xuICAgIGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5tZW51SXRlbXMgPSBtZW51SXRlbXM7XG4gICAgY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlLm92ZXJsYXkgPSBvdmVybGF5O1xuICAgIGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5pc0xlYWYgPSB0cnVlO1xuICAgIGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5tZW51Q2xhc3MgPSBtZW51Q2xhc3M7XG4gICAgKDxPdmVybGF5UmVmV2l0aENvbnRleHRNZW51Pm92ZXJsYXkpLmNvbnRleHRNZW51ID0gY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlO1xuXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICAgIHN1YnNjcmlwdGlvbnMuYWRkKGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5leGVjdXRlLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAuc3Vic2NyaWJlKChleGVjdXRlRXZlbnQpID0+IHRoaXMuY2xvc2VBbGxDb250ZXh0TWVudXMoeyBldmVudFR5cGU6ICdleGVjdXRlJywgLi4uZXhlY3V0ZUV2ZW50IH0pKSk7XG4gICAgc3Vic2NyaXB0aW9ucy5hZGQoY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlLmNsb3NlQWxsTWVudXMuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5zdWJzY3JpYmUoKGNsb3NlQWxsRXZlbnQpID0+IHRoaXMuY2xvc2VBbGxDb250ZXh0TWVudXMoeyBldmVudFR5cGU6ICdjYW5jZWwnLCAuLi5jbG9zZUFsbEV2ZW50IH0pKSk7XG4gICAgc3Vic2NyaXB0aW9ucy5hZGQoY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlLmNsb3NlTGVhZk1lbnUuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5zdWJzY3JpYmUoY2xvc2VMZWFmTWVudUV2ZW50ID0+IHRoaXMuZGVzdHJveUxlYWZNZW51KGNsb3NlTGVhZk1lbnVFdmVudCkpKTtcbiAgICBzdWJzY3JpcHRpb25zLmFkZChjb250ZXh0TWVudUNvbnRlbnQuaW5zdGFuY2Uub3BlblN1Yk1lbnUuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5zdWJzY3JpYmUoKHN1Yk1lbnVFdmVudDogSUNvbnRleHRNZW51Q29udGV4dCkgPT4ge1xuICAgICAgICB0aGlzLmRlc3Ryb3lTdWJNZW51cyhjb250ZXh0TWVudUNvbnRlbnQuaW5zdGFuY2UpO1xuICAgICAgICBpZiAoIXN1Yk1lbnVFdmVudC5jb250ZXh0TWVudSkge1xuICAgICAgICAgIGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5pc0xlYWYgPSB0cnVlO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb250ZXh0TWVudUNvbnRlbnQuaW5zdGFuY2UuaXNMZWFmID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2hvdy5uZXh0KHN1Yk1lbnVFdmVudCk7XG4gICAgICB9KSk7XG4gICAgY29udGV4dE1lbnVDb250ZW50Lm9uRGVzdHJveSgoKSA9PiB7XG4gICAgICBtZW51SXRlbXMuZm9yRWFjaChtZW51SXRlbSA9PiBtZW51SXRlbS5pc0FjdGl2ZSA9IGZhbHNlKTtcbiAgICAgIHN1YnNjcmlwdGlvbnMudW5zdWJzY3JpYmUoKTtcbiAgICB9KTtcbiAgICBjb250ZXh0TWVudUNvbnRlbnQuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHVibGljIGNsb3NlQWxsQ29udGV4dE1lbnVzKGNsb3NlRXZlbnQ6IENsb3NlQ29udGV4dE1lbnVFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm92ZXJsYXlzKSB7XG4gICAgICB0aGlzLmNsb3NlLm5leHQoY2xvc2VFdmVudCk7XG4gICAgICB0aGlzLm92ZXJsYXlzLmZvckVhY2goKG92ZXJsYXksIGluZGV4KSA9PiB7XG4gICAgICAgIG92ZXJsYXkuZGV0YWNoKCk7XG4gICAgICAgIG92ZXJsYXkuZGlzcG9zZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMub3ZlcmxheXMgPSBbXTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRMYXN0QXR0YWNoZWRPdmVybGF5KCk6IE92ZXJsYXlSZWZXaXRoQ29udGV4dE1lbnUge1xuICAgIGxldCBvdmVybGF5OiBPdmVybGF5UmVmID0gdGhpcy5vdmVybGF5c1t0aGlzLm92ZXJsYXlzLmxlbmd0aCAtIDFdO1xuICAgIHdoaWxlICh0aGlzLm92ZXJsYXlzLmxlbmd0aCA+IDEgJiYgb3ZlcmxheSAmJiAhb3ZlcmxheS5oYXNBdHRhY2hlZCgpKSB7XG4gICAgICBvdmVybGF5LmRldGFjaCgpO1xuICAgICAgb3ZlcmxheS5kaXNwb3NlKCk7XG4gICAgICB0aGlzLm92ZXJsYXlzID0gdGhpcy5vdmVybGF5cy5zbGljZSgwLCAtMSk7XG4gICAgICBvdmVybGF5ID0gdGhpcy5vdmVybGF5c1t0aGlzLm92ZXJsYXlzLmxlbmd0aCAtIDFdO1xuICAgIH1cbiAgICByZXR1cm4gb3ZlcmxheTtcbiAgfVxuXG4gIHB1YmxpYyBkZXN0cm95TGVhZk1lbnUoeyBleGNlcHRSb290TWVudSwgZXZlbnQgfTogQ2xvc2VMZWFmTWVudUV2ZW50ID0ge30pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc0Rlc3Ryb3lpbmdMZWFmTWVudSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmlzRGVzdHJveWluZ0xlYWZNZW51ID0gdHJ1ZTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY29uc3Qgb3ZlcmxheSA9IHRoaXMuZ2V0TGFzdEF0dGFjaGVkT3ZlcmxheSgpO1xuICAgICAgaWYgKHRoaXMub3ZlcmxheXMubGVuZ3RoID4gMSAmJiBvdmVybGF5KSB7XG4gICAgICAgIG92ZXJsYXkuZGV0YWNoKCk7XG4gICAgICAgIG92ZXJsYXkuZGlzcG9zZSgpO1xuICAgICAgfVxuICAgICAgaWYgKCFleGNlcHRSb290TWVudSAmJiB0aGlzLm92ZXJsYXlzLmxlbmd0aCA+IDAgJiYgb3ZlcmxheSkge1xuICAgICAgICB0aGlzLmNsb3NlLm5leHQoeyBldmVudFR5cGU6ICdjYW5jZWwnLCBldmVudCB9KTtcbiAgICAgICAgb3ZlcmxheS5kZXRhY2goKTtcbiAgICAgICAgb3ZlcmxheS5kaXNwb3NlKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5ld0xlYWYgPSB0aGlzLmdldExhc3RBdHRhY2hlZE92ZXJsYXkoKTtcbiAgICAgIGlmIChuZXdMZWFmKSB7XG4gICAgICAgIG5ld0xlYWYuY29udGV4dE1lbnUuaXNMZWFmID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pc0Rlc3Ryb3lpbmdMZWFmTWVudSA9IGZhbHNlO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGRlc3Ryb3lTdWJNZW51cyhjb250ZXh0TWVudTogQ29udGV4dE1lbnVDb250ZW50Q29tcG9uZW50KTogdm9pZCB7XG4gICAgY29uc3Qgb3ZlcmxheSA9IGNvbnRleHRNZW51Lm92ZXJsYXk7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLm92ZXJsYXlzLmluZGV4T2Yob3ZlcmxheSk7XG4gICAgdGhpcy5vdmVybGF5cy5zbGljZShpbmRleCArIDEpLmZvckVhY2goc3ViTWVudU92ZXJsYXkgPT4ge1xuICAgICAgc3ViTWVudU92ZXJsYXkuZGV0YWNoKCk7XG4gICAgICBzdWJNZW51T3ZlcmxheS5kaXNwb3NlKCk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgaXNMZWFmTWVudShjb250ZXh0TWVudUNvbnRlbnQ6IENvbnRleHRNZW51Q29udGVudENvbXBvbmVudCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG92ZXJsYXkgPSB0aGlzLmdldExhc3RBdHRhY2hlZE92ZXJsYXkoKTtcbiAgICByZXR1cm4gY29udGV4dE1lbnVDb250ZW50Lm92ZXJsYXkgPT09IG92ZXJsYXk7XG4gIH1cbn1cbiJdfQ==