angular-resizable.directive.js 88 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import * as tslib_1 from "tslib";
  6. import { Directive, ElementRef, Renderer2, Input, Output, EventEmitter } from '@angular/core';
  7. import { fromEvent } from 'rxjs';
  8. import { HelperBlock } from './widgets/helper-block';
  9. import { ResizeHandle } from './widgets/resize-handle';
  10. import { Position } from './models/position';
  11. import { Size } from './models/size';
  12. var AngularResizableDirective = /** @class */ (function () {
  13. function AngularResizableDirective(el, renderer) {
  14. this.el = el;
  15. this.renderer = renderer;
  16. this._resizable = true;
  17. this._handles = {};
  18. this._handleType = [];
  19. this._handleResizing = null;
  20. this._direction = null;
  21. this._directionChanged = null;
  22. this._aspectRatio = 0;
  23. this._containment = null;
  24. this._origMousePos = null;
  25. /**
  26. * Original Size and Position
  27. */
  28. this._origSize = null;
  29. this._origPos = null;
  30. /**
  31. * Current Size and Position
  32. */
  33. this._currSize = null;
  34. this._currPos = null;
  35. /**
  36. * Initial Size and Position
  37. */
  38. this._initSize = null;
  39. this._initPos = null;
  40. /**
  41. * Snap to gird
  42. */
  43. this._gridSize = null;
  44. this._bounding = null;
  45. /**
  46. * Bugfix: iFrames, and context unrelated elements block all events, and are unusable
  47. * https://github.com/xieziyu/angular2-draggable/issues/84
  48. */
  49. this._helperBlock = null;
  50. this.draggingSub = null;
  51. this._adjusted = false;
  52. /**
  53. * Which handles can be used for resizing.
  54. * \@example
  55. * [rzHandles] = "'n,e,s,w,se,ne,sw,nw'"
  56. * equals to: [rzHandles] = "'all'"
  57. *
  58. *
  59. */
  60. this.rzHandles = 'e,s,se';
  61. /**
  62. * Whether the element should be constrained to a specific aspect ratio.
  63. * Multiple types supported:
  64. * boolean: When set to true, the element will maintain its original aspect ratio.
  65. * number: Force the element to maintain a specific aspect ratio during resizing.
  66. */
  67. this.rzAspectRatio = false;
  68. /**
  69. * Constrains resizing to within the bounds of the specified element or region.
  70. * Multiple types supported:
  71. * Selector: The resizable element will be contained to the bounding box of the first element found by the selector.
  72. * If no element is found, no containment will be set.
  73. * Element: The resizable element will be contained to the bounding box of this element.
  74. * String: Possible values: "parent".
  75. */
  76. this.rzContainment = null;
  77. /**
  78. * Snaps the resizing element to a grid, every x and y pixels.
  79. * A number for both width and height or an array values like [ x, y ]
  80. */
  81. this.rzGrid = null;
  82. /**
  83. * The minimum width the resizable should be allowed to resize to.
  84. */
  85. this.rzMinWidth = null;
  86. /**
  87. * The minimum height the resizable should be allowed to resize to.
  88. */
  89. this.rzMinHeight = null;
  90. /**
  91. * The maximum width the resizable should be allowed to resize to.
  92. */
  93. this.rzMaxWidth = null;
  94. /**
  95. * The maximum height the resizable should be allowed to resize to.
  96. */
  97. this.rzMaxHeight = null;
  98. /**
  99. * Whether to prevent default event
  100. */
  101. this.preventDefaultEvent = true;
  102. /**
  103. * emitted when start resizing
  104. */
  105. this.rzStart = new EventEmitter();
  106. /**
  107. * emitted when start resizing
  108. */
  109. this.rzResizing = new EventEmitter();
  110. /**
  111. * emitted when stop resizing
  112. */
  113. this.rzStop = new EventEmitter();
  114. this._helperBlock = new HelperBlock(el.nativeElement, renderer);
  115. }
  116. Object.defineProperty(AngularResizableDirective.prototype, "ngResizable", {
  117. /** Disables the resizable if set to false. */
  118. set: /**
  119. * Disables the resizable if set to false.
  120. * @param {?} v
  121. * @return {?}
  122. */
  123. function (v) {
  124. if (v !== undefined && v !== null && v !== '') {
  125. this._resizable = !!v;
  126. this.updateResizable();
  127. }
  128. },
  129. enumerable: true,
  130. configurable: true
  131. });
  132. /**
  133. * @param {?} changes
  134. * @return {?}
  135. */
  136. AngularResizableDirective.prototype.ngOnChanges = /**
  137. * @param {?} changes
  138. * @return {?}
  139. */
  140. function (changes) {
  141. if (changes['rzHandles'] && !changes['rzHandles'].isFirstChange()) {
  142. this.updateResizable();
  143. }
  144. if (changes['rzAspectRatio'] && !changes['rzAspectRatio'].isFirstChange()) {
  145. this.updateAspectRatio();
  146. }
  147. if (changes['rzContainment'] && !changes['rzContainment'].isFirstChange()) {
  148. this.updateContainment();
  149. }
  150. };
  151. /**
  152. * @return {?}
  153. */
  154. AngularResizableDirective.prototype.ngOnInit = /**
  155. * @return {?}
  156. */
  157. function () {
  158. this.updateResizable();
  159. };
  160. /**
  161. * @return {?}
  162. */
  163. AngularResizableDirective.prototype.ngOnDestroy = /**
  164. * @return {?}
  165. */
  166. function () {
  167. this.removeHandles();
  168. this._containment = null;
  169. this._helperBlock.dispose();
  170. this._helperBlock = null;
  171. };
  172. /**
  173. * @return {?}
  174. */
  175. AngularResizableDirective.prototype.ngAfterViewInit = /**
  176. * @return {?}
  177. */
  178. function () {
  179. /** @type {?} */
  180. var elm = this.el.nativeElement;
  181. this._initSize = Size.getCurrent(elm);
  182. this._initPos = Position.getCurrent(elm);
  183. this._currSize = Size.copy(this._initSize);
  184. this._currPos = Position.copy(this._initPos);
  185. this.updateAspectRatio();
  186. this.updateContainment();
  187. };
  188. /** A method to reset size */
  189. /**
  190. * A method to reset size
  191. * @return {?}
  192. */
  193. AngularResizableDirective.prototype.resetSize = /**
  194. * A method to reset size
  195. * @return {?}
  196. */
  197. function () {
  198. this._currSize = Size.copy(this._initSize);
  199. this._currPos = Position.copy(this._initPos);
  200. this.doResize();
  201. };
  202. /** A method to get current status */
  203. /**
  204. * A method to get current status
  205. * @return {?}
  206. */
  207. AngularResizableDirective.prototype.getStatus = /**
  208. * A method to get current status
  209. * @return {?}
  210. */
  211. function () {
  212. if (!this._currPos || !this._currSize) {
  213. return null;
  214. }
  215. return {
  216. size: {
  217. width: this._currSize.width,
  218. height: this._currSize.height
  219. },
  220. position: {
  221. top: this._currPos.y,
  222. left: this._currPos.x
  223. }
  224. };
  225. };
  226. /**
  227. * @private
  228. * @return {?}
  229. */
  230. AngularResizableDirective.prototype.updateResizable = /**
  231. * @private
  232. * @return {?}
  233. */
  234. function () {
  235. /** @type {?} */
  236. var element = this.el.nativeElement;
  237. // clear handles:
  238. this.renderer.removeClass(element, 'ng-resizable');
  239. this.removeHandles();
  240. // create new ones:
  241. if (this._resizable) {
  242. this.renderer.addClass(element, 'ng-resizable');
  243. this.createHandles();
  244. }
  245. };
  246. /** Use it to update aspect */
  247. /**
  248. * Use it to update aspect
  249. * @private
  250. * @return {?}
  251. */
  252. AngularResizableDirective.prototype.updateAspectRatio = /**
  253. * Use it to update aspect
  254. * @private
  255. * @return {?}
  256. */
  257. function () {
  258. if (typeof this.rzAspectRatio === 'boolean') {
  259. if (this.rzAspectRatio && this._currSize.height) {
  260. this._aspectRatio = (this._currSize.width / this._currSize.height);
  261. }
  262. else {
  263. this._aspectRatio = 0;
  264. }
  265. }
  266. else {
  267. /** @type {?} */
  268. var r = Number(this.rzAspectRatio);
  269. this._aspectRatio = isNaN(r) ? 0 : r;
  270. }
  271. };
  272. /** Use it to update containment */
  273. /**
  274. * Use it to update containment
  275. * @private
  276. * @return {?}
  277. */
  278. AngularResizableDirective.prototype.updateContainment = /**
  279. * Use it to update containment
  280. * @private
  281. * @return {?}
  282. */
  283. function () {
  284. if (!this.rzContainment) {
  285. this._containment = null;
  286. return;
  287. }
  288. if (typeof this.rzContainment === 'string') {
  289. if (this.rzContainment === 'parent') {
  290. this._containment = this.el.nativeElement.parentElement;
  291. }
  292. else {
  293. this._containment = document.querySelector(this.rzContainment);
  294. }
  295. }
  296. else {
  297. this._containment = this.rzContainment;
  298. }
  299. };
  300. /** Use it to create handle divs */
  301. /**
  302. * Use it to create handle divs
  303. * @private
  304. * @return {?}
  305. */
  306. AngularResizableDirective.prototype.createHandles = /**
  307. * Use it to create handle divs
  308. * @private
  309. * @return {?}
  310. */
  311. function () {
  312. var e_1, _a, e_2, _b;
  313. if (!this.rzHandles) {
  314. return;
  315. }
  316. /** @type {?} */
  317. var tmpHandleTypes;
  318. if (typeof this.rzHandles === 'string') {
  319. if (this.rzHandles === 'all') {
  320. tmpHandleTypes = ['n', 'e', 's', 'w', 'ne', 'se', 'nw', 'sw'];
  321. }
  322. else {
  323. tmpHandleTypes = this.rzHandles.replace(/ /g, '').toLowerCase().split(',');
  324. }
  325. try {
  326. for (var tmpHandleTypes_1 = tslib_1.__values(tmpHandleTypes), tmpHandleTypes_1_1 = tmpHandleTypes_1.next(); !tmpHandleTypes_1_1.done; tmpHandleTypes_1_1 = tmpHandleTypes_1.next()) {
  327. var type = tmpHandleTypes_1_1.value;
  328. // default handle theme: ng-resizable-$type.
  329. /** @type {?} */
  330. var handle = this.createHandleByType(type, "ng-resizable-" + type);
  331. if (handle) {
  332. this._handleType.push(type);
  333. this._handles[type] = handle;
  334. }
  335. }
  336. }
  337. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  338. finally {
  339. try {
  340. if (tmpHandleTypes_1_1 && !tmpHandleTypes_1_1.done && (_a = tmpHandleTypes_1.return)) _a.call(tmpHandleTypes_1);
  341. }
  342. finally { if (e_1) throw e_1.error; }
  343. }
  344. }
  345. else {
  346. tmpHandleTypes = Object.keys(this.rzHandles);
  347. try {
  348. for (var tmpHandleTypes_2 = tslib_1.__values(tmpHandleTypes), tmpHandleTypes_2_1 = tmpHandleTypes_2.next(); !tmpHandleTypes_2_1.done; tmpHandleTypes_2_1 = tmpHandleTypes_2.next()) {
  349. var type = tmpHandleTypes_2_1.value;
  350. // custom handle theme.
  351. /** @type {?} */
  352. var handle = this.createHandleByType(type, this.rzHandles[type]);
  353. if (handle) {
  354. this._handleType.push(type);
  355. this._handles[type] = handle;
  356. }
  357. }
  358. }
  359. catch (e_2_1) { e_2 = { error: e_2_1 }; }
  360. finally {
  361. try {
  362. if (tmpHandleTypes_2_1 && !tmpHandleTypes_2_1.done && (_b = tmpHandleTypes_2.return)) _b.call(tmpHandleTypes_2);
  363. }
  364. finally { if (e_2) throw e_2.error; }
  365. }
  366. }
  367. };
  368. /** Use it to create a handle */
  369. /**
  370. * Use it to create a handle
  371. * @private
  372. * @param {?} type
  373. * @param {?} css
  374. * @return {?}
  375. */
  376. AngularResizableDirective.prototype.createHandleByType = /**
  377. * Use it to create a handle
  378. * @private
  379. * @param {?} type
  380. * @param {?} css
  381. * @return {?}
  382. */
  383. function (type, css) {
  384. /** @type {?} */
  385. var _el = this.el.nativeElement;
  386. if (!type.match(/^(se|sw|ne|nw|n|e|s|w)$/)) {
  387. console.error('Invalid handle type:', type);
  388. return null;
  389. }
  390. return new ResizeHandle(_el, this.renderer, type, css, this.onMouseDown.bind(this));
  391. };
  392. /**
  393. * @private
  394. * @return {?}
  395. */
  396. AngularResizableDirective.prototype.removeHandles = /**
  397. * @private
  398. * @return {?}
  399. */
  400. function () {
  401. var e_3, _a;
  402. try {
  403. for (var _b = tslib_1.__values(this._handleType), _c = _b.next(); !_c.done; _c = _b.next()) {
  404. var type = _c.value;
  405. this._handles[type].dispose();
  406. }
  407. }
  408. catch (e_3_1) { e_3 = { error: e_3_1 }; }
  409. finally {
  410. try {
  411. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  412. }
  413. finally { if (e_3) throw e_3.error; }
  414. }
  415. this._handleType = [];
  416. this._handles = {};
  417. };
  418. /**
  419. * @param {?} event
  420. * @param {?} handle
  421. * @return {?}
  422. */
  423. AngularResizableDirective.prototype.onMouseDown = /**
  424. * @param {?} event
  425. * @param {?} handle
  426. * @return {?}
  427. */
  428. function (event, handle) {
  429. // skip right click;
  430. if (event instanceof MouseEvent && event.button === 2) {
  431. return;
  432. }
  433. if (this.preventDefaultEvent) {
  434. // prevent default events
  435. event.stopPropagation();
  436. event.preventDefault();
  437. }
  438. if (!this._handleResizing) {
  439. this._origMousePos = Position.fromEvent(event);
  440. this.startResize(handle);
  441. this.subscribeEvents();
  442. }
  443. };
  444. /**
  445. * @private
  446. * @return {?}
  447. */
  448. AngularResizableDirective.prototype.subscribeEvents = /**
  449. * @private
  450. * @return {?}
  451. */
  452. function () {
  453. var _this = this;
  454. this.draggingSub = fromEvent(document, 'mousemove', { passive: false }).subscribe(function (event) { return _this.onMouseMove((/** @type {?} */ (event))); });
  455. this.draggingSub.add(fromEvent(document, 'touchmove', { passive: false }).subscribe(function (event) { return _this.onMouseMove((/** @type {?} */ (event))); }));
  456. this.draggingSub.add(fromEvent(document, 'mouseup', { passive: false }).subscribe(function () { return _this.onMouseLeave(); }));
  457. // fix for issue #164
  458. /** @type {?} */
  459. var isIEOrEdge = /msie\s|trident\//i.test(window.navigator.userAgent);
  460. if (!isIEOrEdge) {
  461. this.draggingSub.add(fromEvent(document, 'mouseleave', { passive: false }).subscribe(function () { return _this.onMouseLeave(); }));
  462. }
  463. this.draggingSub.add(fromEvent(document, 'touchend', { passive: false }).subscribe(function () { return _this.onMouseLeave(); }));
  464. this.draggingSub.add(fromEvent(document, 'touchcancel', { passive: false }).subscribe(function () { return _this.onMouseLeave(); }));
  465. };
  466. /**
  467. * @private
  468. * @return {?}
  469. */
  470. AngularResizableDirective.prototype.unsubscribeEvents = /**
  471. * @private
  472. * @return {?}
  473. */
  474. function () {
  475. this.draggingSub.unsubscribe();
  476. this.draggingSub = null;
  477. };
  478. /**
  479. * @return {?}
  480. */
  481. AngularResizableDirective.prototype.onMouseLeave = /**
  482. * @return {?}
  483. */
  484. function () {
  485. if (this._handleResizing) {
  486. this.stopResize();
  487. this._origMousePos = null;
  488. this.unsubscribeEvents();
  489. }
  490. };
  491. /**
  492. * @param {?} event
  493. * @return {?}
  494. */
  495. AngularResizableDirective.prototype.onMouseMove = /**
  496. * @param {?} event
  497. * @return {?}
  498. */
  499. function (event) {
  500. if (this._handleResizing && this._resizable && this._origMousePos && this._origPos && this._origSize) {
  501. this.resizeTo(Position.fromEvent(event));
  502. this.onResizing();
  503. }
  504. };
  505. /**
  506. * @private
  507. * @param {?} handle
  508. * @return {?}
  509. */
  510. AngularResizableDirective.prototype.startResize = /**
  511. * @private
  512. * @param {?} handle
  513. * @return {?}
  514. */
  515. function (handle) {
  516. /** @type {?} */
  517. var elm = this.el.nativeElement;
  518. this._origSize = Size.getCurrent(elm);
  519. this._origPos = Position.getCurrent(elm); // x: left, y: top
  520. this._currSize = Size.copy(this._origSize);
  521. this._currPos = Position.copy(this._origPos);
  522. if (this._containment) {
  523. this.getBounding();
  524. }
  525. this.getGridSize();
  526. // Add a transparent helper div:
  527. this._helperBlock.add();
  528. this._handleResizing = handle;
  529. this.updateDirection();
  530. this.rzStart.emit(this.getResizingEvent());
  531. };
  532. /**
  533. * @private
  534. * @return {?}
  535. */
  536. AngularResizableDirective.prototype.stopResize = /**
  537. * @private
  538. * @return {?}
  539. */
  540. function () {
  541. // Remove the helper div:
  542. this._helperBlock.remove();
  543. this.rzStop.emit(this.getResizingEvent());
  544. this._handleResizing = null;
  545. this._direction = null;
  546. this._origSize = null;
  547. this._origPos = null;
  548. if (this._containment) {
  549. this.resetBounding();
  550. }
  551. };
  552. /**
  553. * @private
  554. * @return {?}
  555. */
  556. AngularResizableDirective.prototype.onResizing = /**
  557. * @private
  558. * @return {?}
  559. */
  560. function () {
  561. this.rzResizing.emit(this.getResizingEvent());
  562. };
  563. /**
  564. * @private
  565. * @return {?}
  566. */
  567. AngularResizableDirective.prototype.getResizingEvent = /**
  568. * @private
  569. * @return {?}
  570. */
  571. function () {
  572. return {
  573. host: this.el.nativeElement,
  574. handle: this._handleResizing ? this._handleResizing.el : null,
  575. size: {
  576. width: this._currSize.width,
  577. height: this._currSize.height
  578. },
  579. position: {
  580. top: this._currPos.y,
  581. left: this._currPos.x
  582. },
  583. direction: tslib_1.__assign({}, this._directionChanged),
  584. };
  585. };
  586. /**
  587. * @private
  588. * @return {?}
  589. */
  590. AngularResizableDirective.prototype.updateDirection = /**
  591. * @private
  592. * @return {?}
  593. */
  594. function () {
  595. this._direction = {
  596. n: !!this._handleResizing.type.match(/n/),
  597. s: !!this._handleResizing.type.match(/s/),
  598. w: !!this._handleResizing.type.match(/w/),
  599. e: !!this._handleResizing.type.match(/e/)
  600. };
  601. this._directionChanged = tslib_1.__assign({}, this._direction);
  602. // if aspect ration should be preserved:
  603. if (this.rzAspectRatio) {
  604. // if north then west (unless ne)
  605. if (this._directionChanged.n && !this._directionChanged.e) {
  606. this._directionChanged.w = true;
  607. }
  608. // if south then east (unless sw)
  609. if (this._directionChanged.s && !this._directionChanged.w) {
  610. this._directionChanged.e = true;
  611. }
  612. // if east then south (unless ne)
  613. if (this._directionChanged.e && !this._directionChanged.n) {
  614. this._directionChanged.s = true;
  615. }
  616. // if west then south (unless nw)
  617. if (this._directionChanged.w && !this._directionChanged.n) {
  618. this._directionChanged.s = true;
  619. }
  620. }
  621. };
  622. /**
  623. * @private
  624. * @param {?} p
  625. * @return {?}
  626. */
  627. AngularResizableDirective.prototype.resizeTo = /**
  628. * @private
  629. * @param {?} p
  630. * @return {?}
  631. */
  632. function (p) {
  633. p.subtract(this._origMousePos);
  634. /** @type {?} */
  635. var tmpX = Math.round(p.x / this._gridSize.x) * this._gridSize.x;
  636. /** @type {?} */
  637. var tmpY = Math.round(p.y / this._gridSize.y) * this._gridSize.y;
  638. if (this._direction.n) {
  639. // n, ne, nw
  640. this._currPos.y = this._origPos.y + tmpY;
  641. this._currSize.height = this._origSize.height - tmpY;
  642. }
  643. else if (this._direction.s) {
  644. // s, se, sw
  645. this._currSize.height = this._origSize.height + tmpY;
  646. }
  647. if (this._direction.e) {
  648. // e, ne, se
  649. this._currSize.width = this._origSize.width + tmpX;
  650. }
  651. else if (this._direction.w) {
  652. // w, nw, sw
  653. this._currSize.width = this._origSize.width - tmpX;
  654. this._currPos.x = this._origPos.x + tmpX;
  655. }
  656. this.checkBounds();
  657. this.checkSize();
  658. this.adjustByRatio();
  659. this.doResize();
  660. };
  661. /**
  662. * @private
  663. * @return {?}
  664. */
  665. AngularResizableDirective.prototype.doResize = /**
  666. * @private
  667. * @return {?}
  668. */
  669. function () {
  670. /** @type {?} */
  671. var container = this.el.nativeElement;
  672. if (!this._direction || this._direction.n || this._direction.s || this._aspectRatio) {
  673. this.renderer.setStyle(container, 'height', this._currSize.height + 'px');
  674. }
  675. if (!this._direction || this._direction.w || this._direction.e || this._aspectRatio) {
  676. this.renderer.setStyle(container, 'width', this._currSize.width + 'px');
  677. }
  678. this.renderer.setStyle(container, 'left', this._currPos.x + 'px');
  679. this.renderer.setStyle(container, 'top', this._currPos.y + 'px');
  680. };
  681. /**
  682. * @private
  683. * @return {?}
  684. */
  685. AngularResizableDirective.prototype.adjustByRatio = /**
  686. * @private
  687. * @return {?}
  688. */
  689. function () {
  690. if (this._aspectRatio && !this._adjusted) {
  691. if (this._direction.e || this._direction.w) {
  692. /** @type {?} */
  693. var newHeight = Math.floor(this._currSize.width / this._aspectRatio);
  694. if (this._direction.n) {
  695. this._currPos.y += this._currSize.height - newHeight;
  696. }
  697. this._currSize.height = newHeight;
  698. }
  699. else {
  700. /** @type {?} */
  701. var newWidth = Math.floor(this._aspectRatio * this._currSize.height);
  702. if (this._direction.n) {
  703. this._currPos.x += this._currSize.width - newWidth;
  704. }
  705. this._currSize.width = newWidth;
  706. }
  707. }
  708. };
  709. /**
  710. * @private
  711. * @return {?}
  712. */
  713. AngularResizableDirective.prototype.checkBounds = /**
  714. * @private
  715. * @return {?}
  716. */
  717. function () {
  718. if (this._containment) {
  719. /** @type {?} */
  720. var maxWidth = this._bounding.width - this._bounding.pr - this._bounding.deltaL - this._bounding.translateX - this._currPos.x;
  721. /** @type {?} */
  722. var maxHeight = this._bounding.height - this._bounding.pb - this._bounding.deltaT - this._bounding.translateY - this._currPos.y;
  723. if (this._direction.n && (this._currPos.y + this._bounding.translateY < 0)) {
  724. this._currPos.y = -this._bounding.translateY;
  725. this._currSize.height = this._origSize.height + this._origPos.y + this._bounding.translateY;
  726. }
  727. if (this._direction.w && (this._currPos.x + this._bounding.translateX) < 0) {
  728. this._currPos.x = -this._bounding.translateX;
  729. this._currSize.width = this._origSize.width + this._origPos.x + this._bounding.translateX;
  730. }
  731. if (this._currSize.width > maxWidth) {
  732. this._currSize.width = maxWidth;
  733. }
  734. if (this._currSize.height > maxHeight) {
  735. this._currSize.height = maxHeight;
  736. }
  737. /**
  738. * Fix Issue: Additional check for aspect ratio
  739. * https://github.com/xieziyu/angular2-draggable/issues/132
  740. */
  741. if (this._aspectRatio) {
  742. this._adjusted = false;
  743. if ((this._direction.w || this._direction.e) &&
  744. (this._currSize.width / this._aspectRatio) >= maxHeight) {
  745. /** @type {?} */
  746. var newWidth = Math.floor(maxHeight * this._aspectRatio);
  747. if (this._direction.w) {
  748. this._currPos.x += this._currSize.width - newWidth;
  749. }
  750. this._currSize.width = newWidth;
  751. this._currSize.height = maxHeight;
  752. this._adjusted = true;
  753. }
  754. if ((this._direction.n || this._direction.s) &&
  755. (this._currSize.height * this._aspectRatio) >= maxWidth) {
  756. /** @type {?} */
  757. var newHeight = Math.floor(maxWidth / this._aspectRatio);
  758. if (this._direction.n) {
  759. this._currPos.y += this._currSize.height - newHeight;
  760. }
  761. this._currSize.width = maxWidth;
  762. this._currSize.height = newHeight;
  763. this._adjusted = true;
  764. }
  765. }
  766. }
  767. };
  768. /**
  769. * @private
  770. * @return {?}
  771. */
  772. AngularResizableDirective.prototype.checkSize = /**
  773. * @private
  774. * @return {?}
  775. */
  776. function () {
  777. /** @type {?} */
  778. var minHeight = !this.rzMinHeight ? 1 : this.rzMinHeight;
  779. /** @type {?} */
  780. var minWidth = !this.rzMinWidth ? 1 : this.rzMinWidth;
  781. if (this._currSize.height < minHeight) {
  782. this._currSize.height = minHeight;
  783. if (this._direction.n) {
  784. this._currPos.y = this._origPos.y + (this._origSize.height - minHeight);
  785. }
  786. }
  787. if (this._currSize.width < minWidth) {
  788. this._currSize.width = minWidth;
  789. if (this._direction.w) {
  790. this._currPos.x = this._origPos.x + (this._origSize.width - minWidth);
  791. }
  792. }
  793. if (this.rzMaxHeight && this._currSize.height > this.rzMaxHeight) {
  794. this._currSize.height = this.rzMaxHeight;
  795. if (this._direction.n) {
  796. this._currPos.y = this._origPos.y + (this._origSize.height - this.rzMaxHeight);
  797. }
  798. }
  799. if (this.rzMaxWidth && this._currSize.width > this.rzMaxWidth) {
  800. this._currSize.width = this.rzMaxWidth;
  801. if (this._direction.w) {
  802. this._currPos.x = this._origPos.x + (this._origSize.width - this.rzMaxWidth);
  803. }
  804. }
  805. };
  806. /**
  807. * @private
  808. * @return {?}
  809. */
  810. AngularResizableDirective.prototype.getBounding = /**
  811. * @private
  812. * @return {?}
  813. */
  814. function () {
  815. /** @type {?} */
  816. var el = this._containment;
  817. /** @type {?} */
  818. var computed = window.getComputedStyle(el);
  819. if (computed) {
  820. /** @type {?} */
  821. var p = computed.getPropertyValue('position');
  822. /** @type {?} */
  823. var nativeEl = window.getComputedStyle(this.el.nativeElement);
  824. /** @type {?} */
  825. var transforms = nativeEl.getPropertyValue('transform').replace(/[^-\d,]/g, '').split(',');
  826. this._bounding = {};
  827. this._bounding.width = el.clientWidth;
  828. this._bounding.height = el.clientHeight;
  829. this._bounding.pr = parseInt(computed.getPropertyValue('padding-right'), 10);
  830. this._bounding.pb = parseInt(computed.getPropertyValue('padding-bottom'), 10);
  831. this._bounding.deltaL = this.el.nativeElement.offsetLeft - this._currPos.x;
  832. this._bounding.deltaT = this.el.nativeElement.offsetTop - this._currPos.y;
  833. if (transforms.length >= 6) {
  834. this._bounding.translateX = parseInt(transforms[4], 10);
  835. this._bounding.translateY = parseInt(transforms[5], 10);
  836. }
  837. else {
  838. this._bounding.translateX = 0;
  839. this._bounding.translateY = 0;
  840. }
  841. this._bounding.position = computed.getPropertyValue('position');
  842. if (p === 'static') {
  843. this.renderer.setStyle(el, 'position', 'relative');
  844. }
  845. }
  846. };
  847. /**
  848. * @private
  849. * @return {?}
  850. */
  851. AngularResizableDirective.prototype.resetBounding = /**
  852. * @private
  853. * @return {?}
  854. */
  855. function () {
  856. if (this._bounding && this._bounding.position === 'static') {
  857. this.renderer.setStyle(this._containment, 'position', 'relative');
  858. }
  859. this._bounding = null;
  860. };
  861. /**
  862. * @private
  863. * @return {?}
  864. */
  865. AngularResizableDirective.prototype.getGridSize = /**
  866. * @private
  867. * @return {?}
  868. */
  869. function () {
  870. // set default value:
  871. this._gridSize = { x: 1, y: 1 };
  872. if (this.rzGrid) {
  873. if (typeof this.rzGrid === 'number') {
  874. this._gridSize = { x: this.rzGrid, y: this.rzGrid };
  875. }
  876. else if (Array.isArray(this.rzGrid)) {
  877. this._gridSize = { x: this.rzGrid[0], y: this.rzGrid[1] };
  878. }
  879. }
  880. };
  881. AngularResizableDirective.decorators = [
  882. { type: Directive, args: [{
  883. selector: '[ngResizable]',
  884. exportAs: 'ngResizable'
  885. },] }
  886. ];
  887. /** @nocollapse */
  888. AngularResizableDirective.ctorParameters = function () { return [
  889. { type: ElementRef },
  890. { type: Renderer2 }
  891. ]; };
  892. AngularResizableDirective.propDecorators = {
  893. ngResizable: [{ type: Input }],
  894. rzHandles: [{ type: Input }],
  895. rzAspectRatio: [{ type: Input }],
  896. rzContainment: [{ type: Input }],
  897. rzGrid: [{ type: Input }],
  898. rzMinWidth: [{ type: Input }],
  899. rzMinHeight: [{ type: Input }],
  900. rzMaxWidth: [{ type: Input }],
  901. rzMaxHeight: [{ type: Input }],
  902. preventDefaultEvent: [{ type: Input }],
  903. rzStart: [{ type: Output }],
  904. rzResizing: [{ type: Output }],
  905. rzStop: [{ type: Output }]
  906. };
  907. return AngularResizableDirective;
  908. }());
  909. export { AngularResizableDirective };
  910. if (false) {
  911. /**
  912. * @type {?}
  913. * @private
  914. */
  915. AngularResizableDirective.prototype._resizable;
  916. /**
  917. * @type {?}
  918. * @private
  919. */
  920. AngularResizableDirective.prototype._handles;
  921. /**
  922. * @type {?}
  923. * @private
  924. */
  925. AngularResizableDirective.prototype._handleType;
  926. /**
  927. * @type {?}
  928. * @private
  929. */
  930. AngularResizableDirective.prototype._handleResizing;
  931. /**
  932. * @type {?}
  933. * @private
  934. */
  935. AngularResizableDirective.prototype._direction;
  936. /**
  937. * @type {?}
  938. * @private
  939. */
  940. AngularResizableDirective.prototype._directionChanged;
  941. /**
  942. * @type {?}
  943. * @private
  944. */
  945. AngularResizableDirective.prototype._aspectRatio;
  946. /**
  947. * @type {?}
  948. * @private
  949. */
  950. AngularResizableDirective.prototype._containment;
  951. /**
  952. * @type {?}
  953. * @private
  954. */
  955. AngularResizableDirective.prototype._origMousePos;
  956. /**
  957. * Original Size and Position
  958. * @type {?}
  959. * @private
  960. */
  961. AngularResizableDirective.prototype._origSize;
  962. /**
  963. * @type {?}
  964. * @private
  965. */
  966. AngularResizableDirective.prototype._origPos;
  967. /**
  968. * Current Size and Position
  969. * @type {?}
  970. * @private
  971. */
  972. AngularResizableDirective.prototype._currSize;
  973. /**
  974. * @type {?}
  975. * @private
  976. */
  977. AngularResizableDirective.prototype._currPos;
  978. /**
  979. * Initial Size and Position
  980. * @type {?}
  981. * @private
  982. */
  983. AngularResizableDirective.prototype._initSize;
  984. /**
  985. * @type {?}
  986. * @private
  987. */
  988. AngularResizableDirective.prototype._initPos;
  989. /**
  990. * Snap to gird
  991. * @type {?}
  992. * @private
  993. */
  994. AngularResizableDirective.prototype._gridSize;
  995. /**
  996. * @type {?}
  997. * @private
  998. */
  999. AngularResizableDirective.prototype._bounding;
  1000. /**
  1001. * Bugfix: iFrames, and context unrelated elements block all events, and are unusable
  1002. * https://github.com/xieziyu/angular2-draggable/issues/84
  1003. * @type {?}
  1004. * @private
  1005. */
  1006. AngularResizableDirective.prototype._helperBlock;
  1007. /**
  1008. * @type {?}
  1009. * @private
  1010. */
  1011. AngularResizableDirective.prototype.draggingSub;
  1012. /**
  1013. * @type {?}
  1014. * @private
  1015. */
  1016. AngularResizableDirective.prototype._adjusted;
  1017. /**
  1018. * Which handles can be used for resizing.
  1019. * \@example
  1020. * [rzHandles] = "'n,e,s,w,se,ne,sw,nw'"
  1021. * equals to: [rzHandles] = "'all'"
  1022. *
  1023. *
  1024. * @type {?}
  1025. */
  1026. AngularResizableDirective.prototype.rzHandles;
  1027. /**
  1028. * Whether the element should be constrained to a specific aspect ratio.
  1029. * Multiple types supported:
  1030. * boolean: When set to true, the element will maintain its original aspect ratio.
  1031. * number: Force the element to maintain a specific aspect ratio during resizing.
  1032. * @type {?}
  1033. */
  1034. AngularResizableDirective.prototype.rzAspectRatio;
  1035. /**
  1036. * Constrains resizing to within the bounds of the specified element or region.
  1037. * Multiple types supported:
  1038. * Selector: The resizable element will be contained to the bounding box of the first element found by the selector.
  1039. * If no element is found, no containment will be set.
  1040. * Element: The resizable element will be contained to the bounding box of this element.
  1041. * String: Possible values: "parent".
  1042. * @type {?}
  1043. */
  1044. AngularResizableDirective.prototype.rzContainment;
  1045. /**
  1046. * Snaps the resizing element to a grid, every x and y pixels.
  1047. * A number for both width and height or an array values like [ x, y ]
  1048. * @type {?}
  1049. */
  1050. AngularResizableDirective.prototype.rzGrid;
  1051. /**
  1052. * The minimum width the resizable should be allowed to resize to.
  1053. * @type {?}
  1054. */
  1055. AngularResizableDirective.prototype.rzMinWidth;
  1056. /**
  1057. * The minimum height the resizable should be allowed to resize to.
  1058. * @type {?}
  1059. */
  1060. AngularResizableDirective.prototype.rzMinHeight;
  1061. /**
  1062. * The maximum width the resizable should be allowed to resize to.
  1063. * @type {?}
  1064. */
  1065. AngularResizableDirective.prototype.rzMaxWidth;
  1066. /**
  1067. * The maximum height the resizable should be allowed to resize to.
  1068. * @type {?}
  1069. */
  1070. AngularResizableDirective.prototype.rzMaxHeight;
  1071. /**
  1072. * Whether to prevent default event
  1073. * @type {?}
  1074. */
  1075. AngularResizableDirective.prototype.preventDefaultEvent;
  1076. /**
  1077. * emitted when start resizing
  1078. * @type {?}
  1079. */
  1080. AngularResizableDirective.prototype.rzStart;
  1081. /**
  1082. * emitted when start resizing
  1083. * @type {?}
  1084. */
  1085. AngularResizableDirective.prototype.rzResizing;
  1086. /**
  1087. * emitted when stop resizing
  1088. * @type {?}
  1089. */
  1090. AngularResizableDirective.prototype.rzStop;
  1091. /**
  1092. * @type {?}
  1093. * @private
  1094. */
  1095. AngularResizableDirective.prototype.el;
  1096. /**
  1097. * @type {?}
  1098. * @private
  1099. */
  1100. AngularResizableDirective.prototype.renderer;
  1101. }
  1102. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1yZXNpemFibGUuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vYW5ndWxhcjItZHJhZ2dhYmxlLyIsInNvdXJjZXMiOlsibGliL2FuZ3VsYXItcmVzaXphYmxlLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFDaEMsS0FBSyxFQUFFLE1BQU0sRUFBVSxZQUFZLEVBRXBDLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBZ0IsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFdkQsT0FBTyxFQUFFLFFBQVEsRUFBYSxNQUFNLG1CQUFtQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHckM7SUEwR0UsbUNBQW9CLEVBQTJCLEVBQVUsUUFBbUI7UUFBeEQsT0FBRSxHQUFGLEVBQUUsQ0FBeUI7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBckdwRSxlQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLGFBQVEsR0FBb0MsRUFBRSxDQUFDO1FBQy9DLGdCQUFXLEdBQWEsRUFBRSxDQUFDO1FBQzNCLG9CQUFlLEdBQWlCLElBQUksQ0FBQztRQUNyQyxlQUFVLEdBQStELElBQUksQ0FBQztRQUM5RSxzQkFBaUIsR0FBK0QsSUFBSSxDQUFDO1FBQ3JGLGlCQUFZLEdBQUcsQ0FBQyxDQUFDO1FBQ2pCLGlCQUFZLEdBQWdCLElBQUksQ0FBQztRQUNqQyxrQkFBYSxHQUFhLElBQUksQ0FBQzs7OztRQUcvQixjQUFTLEdBQVMsSUFBSSxDQUFDO1FBQ3ZCLGFBQVEsR0FBYSxJQUFJLENBQUM7Ozs7UUFHMUIsY0FBUyxHQUFTLElBQUksQ0FBQztRQUN2QixhQUFRLEdBQWEsSUFBSSxDQUFDOzs7O1FBRzFCLGNBQVMsR0FBUyxJQUFJLENBQUM7UUFDdkIsYUFBUSxHQUFhLElBQUksQ0FBQzs7OztRQUcxQixjQUFTLEdBQWMsSUFBSSxDQUFDO1FBRTVCLGNBQVMsR0FBUSxJQUFJLENBQUM7Ozs7O1FBTXRCLGlCQUFZLEdBQWdCLElBQUksQ0FBQztRQUVqQyxnQkFBVyxHQUFpQixJQUFJLENBQUM7UUFDakMsY0FBUyxHQUFHLEtBQUssQ0FBQzs7Ozs7Ozs7O1FBaUJqQixjQUFTLEdBQXFCLFFBQVEsQ0FBQzs7Ozs7OztRQVF2QyxrQkFBYSxHQUFxQixLQUFLLENBQUM7Ozs7Ozs7OztRQVV4QyxrQkFBYSxHQUF5QixJQUFJLENBQUM7Ozs7O1FBTTNDLFdBQU0sR0FBc0IsSUFBSSxDQUFDOzs7O1FBR2pDLGVBQVUsR0FBVyxJQUFJLENBQUM7Ozs7UUFHMUIsZ0JBQVcsR0FBVyxJQUFJLENBQUM7Ozs7UUFHM0IsZUFBVSxHQUFXLElBQUksQ0FBQzs7OztRQUcxQixnQkFBVyxHQUFXLElBQUksQ0FBQzs7OztRQUczQix3QkFBbUIsR0FBRyxJQUFJLENBQUM7Ozs7UUFHMUIsWUFBTyxHQUFHLElBQUksWUFBWSxFQUFnQixDQUFDOzs7O1FBRzNDLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBZ0IsQ0FBQzs7OztRQUc5QyxXQUFNLEdBQUcsSUFBSSxZQUFZLEVBQWdCLENBQUM7UUFHbEQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLFdBQVcsQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFsRUQsc0JBQWEsa0RBQVc7UUFEeEIsOENBQThDOzs7Ozs7UUFDOUMsVUFBeUIsQ0FBTTtZQUM3QixJQUFJLENBQUMsS0FBSyxTQUFTLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFO2dCQUM3QyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQzthQUN4QjtRQUNILENBQUM7OztPQUFBOzs7OztJQStERCwrQ0FBVzs7OztJQUFYLFVBQVksT0FBc0I7UUFDaEMsSUFBSSxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsYUFBYSxFQUFFLEVBQUU7WUFDakUsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1NBQ3hCO1FBRUQsSUFBSSxPQUFPLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUMsYUFBYSxFQUFFLEVBQUU7WUFDekUsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7U0FDMUI7UUFFRCxJQUFJLE9BQU8sQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQyxhQUFhLEVBQUUsRUFBRTtZQUN6RSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztTQUMxQjtJQUNILENBQUM7Ozs7SUFFRCw0Q0FBUTs7O0lBQVI7UUFDRSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDekIsQ0FBQzs7OztJQUVELCtDQUFXOzs7SUFBWDtRQUNFLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO0lBQzNCLENBQUM7Ozs7SUFFRCxtREFBZTs7O0lBQWY7O1lBQ1EsR0FBRyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYTtRQUNqQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQsNkJBQTZCOzs7OztJQUN0Qiw2Q0FBUzs7OztJQUFoQjtRQUNFLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDbEIsQ0FBQztJQUVELHFDQUFxQzs7Ozs7SUFDOUIsNkNBQVM7Ozs7SUFBaEI7UUFDRSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDckMsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUVELE9BQU87WUFDTCxJQUFJLEVBQUU7Z0JBQ0osS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSztnQkFDM0IsTUFBTSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTTthQUM5QjtZQUNELFFBQVEsRUFBRTtnQkFDUixHQUFHLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNwQixJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ3RCO1NBQ0YsQ0FBQztJQUNKLENBQUM7Ozs7O0lBRU8sbURBQWU7Ozs7SUFBdkI7O1lBQ1EsT0FBTyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYTtRQUVyQyxpQkFBaUI7UUFDakIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUVyQixtQkFBbUI7UUFDbkIsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ25CLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxjQUFjLENBQUMsQ0FBQztZQUNoRCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7U0FDdEI7SUFDSCxDQUFDO0lBRUQsOEJBQThCOzs7Ozs7SUFDdEIscURBQWlCOzs7OztJQUF6QjtRQUNFLElBQUksT0FBTyxJQUFJLENBQUMsYUFBYSxLQUFLLFNBQVMsRUFBRTtZQUMzQyxJQUFJLElBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUU7Z0JBQy9DLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQ3BFO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO2FBQ3ZCO1NBQ0Y7YUFBTTs7Z0JBQ0QsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUN0QztJQUNILENBQUM7SUFFRCxtQ0FBbUM7Ozs7OztJQUMzQixxREFBaUI7Ozs7O0lBQXpCO1FBQ0UsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDdkIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7WUFDekIsT0FBTztTQUNSO1FBRUQsSUFBSSxPQUFPLElBQUksQ0FBQyxhQUFhLEtBQUssUUFBUSxFQUFFO1lBQzFDLElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxRQUFRLEVBQUU7Z0JBQ25DLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDO2FBQ3pEO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBYyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7YUFDN0U7U0FDRjthQUFNO1lBQ0wsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1NBQ3hDO0lBQ0gsQ0FBQztJQUVELG1DQUFtQzs7Ozs7O0lBQzNCLGlEQUFhOzs7OztJQUFyQjs7UUFDRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNuQixPQUFPO1NBQ1I7O1lBRUcsY0FBd0I7UUFDNUIsSUFBSSxPQUFPLElBQUksQ0FBQyxTQUFTLEtBQUssUUFBUSxFQUFFO1lBQ3RDLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxLQUFLLEVBQUU7Z0JBQzVCLGNBQWMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQzthQUMvRDtpQkFBTTtnQkFDTCxjQUFjLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUM1RTs7Z0JBRUQsS0FBaUIsSUFBQSxtQkFBQSxpQkFBQSxjQUFjLENBQUEsOENBQUEsMEVBQUU7b0JBQTVCLElBQUksSUFBSSwyQkFBQTs7O3dCQUVQLE1BQU0sR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxFQUFFLGtCQUFnQixJQUFNLENBQUM7b0JBQ2xFLElBQUksTUFBTSxFQUFFO3dCQUNWLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO3dCQUM1QixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQztxQkFDOUI7aUJBQ0Y7Ozs7Ozs7OztTQUNGO2FBQU07WUFDTCxjQUFjLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7O2dCQUM3QyxLQUFpQixJQUFBLG1CQUFBLGlCQUFBLGNBQWMsQ0FBQSw4Q0FBQSwwRUFBRTtvQkFBNUIsSUFBSSxJQUFJLDJCQUFBOzs7d0JBRVAsTUFBTSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDaEUsSUFBSSxNQUFNLEVBQUU7d0JBQ1YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQzVCLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDO3FCQUM5QjtpQkFDRjs7Ozs7Ozs7O1NBQ0Y7SUFFSCxDQUFDO0lBRUQsZ0NBQWdDOzs7Ozs7OztJQUN4QixzREFBa0I7Ozs7Ozs7SUFBMUIsVUFBMkIsSUFBWSxFQUFFLEdBQVc7O1lBQzVDLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWE7UUFFakMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMseUJBQXlCLENBQUMsRUFBRTtZQUMxQyxPQUFPLENBQUMsS0FBSyxDQUFDLHNCQUFzQixFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzVDLE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFFRCxPQUFPLElBQUksWUFBWSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUN0RixDQUFDOzs7OztJQUVPLGlEQUFhOzs7O0lBQXJCOzs7WUFDRSxLQUFpQixJQUFBLEtBQUEsaUJBQUEsSUFBSSxDQUFDLFdBQVcsQ0FBQSxnQkFBQSw0QkFBRTtnQkFBOUIsSUFBSSxJQUFJLFdBQUE7Z0JBQ1gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQzthQUMvQjs7Ozs7Ozs7O1FBRUQsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUM7SUFDckIsQ0FBQzs7Ozs7O0lBRUQsK0NBQVc7Ozs7O0lBQVgsVUFBWSxLQUE4QixFQUFFLE1BQW9CO1FBQzlELG9CQUFvQjtRQUNwQixJQUFJLEtBQUssWUFBWSxVQUFVLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDckQsT0FBTztTQUNSO1FBRUQsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUU7WUFDNUIseUJBQXlCO1lBQ3pCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN4QixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7U0FDeEI7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUN6QixJQUFJLENBQUMsYUFBYSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDL0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUV6QixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7U0FDeEI7SUFDSCxDQUFDOzs7OztJQUVPLG1EQUFlOzs7O0lBQXZCO1FBQUEsaUJBV0M7UUFWQyxJQUFJLENBQUMsV0FBVyxHQUFHLFNBQVMsQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLFVBQUEsS0FBSyxJQUFJLE9BQUEsS0FBSSxDQUFDLFdBQVcsQ0FBQyxtQkFBQSxLQUFLLEVBQWMsQ0FBQyxFQUFyQyxDQUFxQyxDQUFDLENBQUM7UUFDbEksSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxXQUFXLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsVUFBQSxLQUFLLElBQUksT0FBQSxLQUFJLENBQUMsV0FBVyxDQUFDLG1CQUFBLEtBQUssRUFBYyxDQUFDLEVBQXJDLENBQXFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JJLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLGNBQU0sT0FBQSxLQUFJLENBQUMsWUFBWSxFQUFFLEVBQW5CLENBQW1CLENBQUMsQ0FBQyxDQUFDOzs7WUFFMUcsVUFBVSxHQUFHLG1CQUFtQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQztRQUNyRSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxZQUFZLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsY0FBTSxPQUFBLEtBQUksQ0FBQyxZQUFZLEVBQUUsRUFBbkIsQ0FBbUIsQ0FBQyxDQUFDLENBQUM7U0FDbEg7UUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLFVBQVUsRUFBRSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxjQUFNLE9BQUEsS0FBSSxDQUFDLFlBQVksRUFBRSxFQUFuQixDQUFtQixDQUFDLENBQUMsQ0FBQztRQUMvRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLGFBQWEsRUFBRSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxjQUFNLE9BQUEsS0FBSSxDQUFDLFlBQVksRUFBRSxFQUFuQixDQUFtQixDQUFDLENBQUMsQ0FBQztJQUNwSCxDQUFDOzs7OztJQUVPLHFEQUFpQjs7OztJQUF6QjtRQUNFLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDMUIsQ0FBQzs7OztJQUVELGdEQUFZOzs7SUFBWjtRQUNFLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUN4QixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDbEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7WUFDMUIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7U0FDMUI7SUFDSCxDQUFDOzs7OztJQUVELCtDQUFXOzs7O0lBQVgsVUFBWSxLQUE4QjtRQUN4QyxJQUFJLElBQUksQ0FBQyxlQUFlLElBQUksSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNwRyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUN6QyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7U0FDbkI7SUFDSCxDQUFDOzs7Ozs7SUFFTywrQ0FBVzs7Ozs7SUFBbkIsVUFBb0IsTUFBb0I7O1lBQ2hDLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWE7UUFDakMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLGtCQUFrQjtRQUM1RCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzNDLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDN0MsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQ3JCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztTQUNwQjtRQUNELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUVuQixnQ0FBZ0M7UUFDaEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsZUFBZSxHQUFHLE1BQU0sQ0FBQztRQUM5QixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQztJQUM3QyxDQUFDOzs7OztJQUVPLDhDQUFVOzs7O0lBQWxCO1FBQ0UseUJBQXlCO1FBQ3pCLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztRQUM1QixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUNyQixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDckIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1NBQ3RCO0lBQ0gsQ0FBQzs7Ozs7SUFFTyw4Q0FBVTs7OztJQUFsQjtRQUNFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7SUFDaEQsQ0FBQzs7Ozs7SUFFTyxvREFBZ0I7Ozs7SUFBeEI7UUFDRSxPQUFPO1lBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYTtZQUMzQixNQUFNLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUk7WUFDN0QsSUFBSSxFQUFFO2dCQUNKLEtBQUssRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUs7Z0JBQzNCLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU07YUFDOUI7WUFDRCxRQUFRLEVBQUU7Z0JBQ1IsR0FBRyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDcEIsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUN0QjtZQUNELFNBQVMsdUJBQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFFO1NBQ3pDLENBQUM7SUFDSixDQUFDOzs7OztJQUVPLG1EQUFlOzs7O0lBQXZCO1FBQ0UsSUFBSSxDQUFDLFVBQVUsR0FBRztZQUNoQixDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7WUFDekMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDO1lBQ3pDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQztZQUN6QyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7U0FDMUMsQ0FBQztRQUVGLElBQUksQ0FBQyxpQkFBaUIsd0JBQVEsSUFBSSxDQUFDLFVBQVUsQ0FBRSxDQUFDO1FBRWhELHdDQUF3QztRQUN4QyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFFdEIsaUNBQWlDO1lBQ2pDLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3pELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO2FBQ2pDO1lBRUQsaUNBQWlDO1lBQ2pDLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3pELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO2FBQ2pDO1lBRUQsaUNBQWlDO1lBQ2pDLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3pELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO2FBQ2pDO1lBRUQsaUNBQWlDO1lBQ2pDLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3pELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO2FBQ2pDO1NBQ0Y7SUFDSCxDQUFDOzs7Ozs7SUFFTyw0Q0FBUTs7Ozs7SUFBaEIsVUFBaUIsQ0FBVztRQUMxQixDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQzs7WUFFekIsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQzs7WUFDNUQsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUVsRSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFO1lBQ3JCLFlBQVk7WUFDWixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDekMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1NBQ3REO2FBQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRTtZQUM1QixZQUFZO1lBQ1osSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1NBQ3REO1FBRUQsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRTtZQUNyQixZQUFZO1lBQ1osSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1NBQ3BEO2FBQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRTtZQUM1QixZQUFZO1lBQ1osSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1lBQ25ELElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQztTQUMxQztRQUVELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDakIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNsQixDQUFDOzs7OztJQUVPLDRDQUFROzs7O0lBQWhCOztZQUNRLFNBQVMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWE7UUFDdkMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNuRixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxDQUFDO1NBQzNFO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNuRixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDO1NBQ3pFO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQ25FLENBQUM7Ozs7O0lBRU8saURBQWE7Ozs7SUFBckI7UUFDRSxJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ3hDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUU7O29CQUNwQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO2dCQUV0RSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFO29CQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7aUJBQ3REO2dCQUVELElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQzthQUNuQztpQkFBTTs7b0JBQ0MsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztnQkFFdEUsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRTtvQkFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDO2lCQUNwRDtnQkFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUM7YUFDakM7U0FDRjtJQUNILENBQUM7Ozs7O0lBRU8sK0NBQVc7Ozs7SUFBbkI7UUFDRSxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7O2dCQUNmLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7O2dCQUN6SCxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRWpJLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUMsRUFBRTtnQkFDMUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQztnQkFDN0MsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUM7YUFDN0Y7WUFFRCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUU7Z0JBQzFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUM7Z0JBQzdDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDO2FBQzNGO1lBRUQsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxRQUFRLEVBQUU7Z0JBQ25DLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQzthQUNqQztZQUVELElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsU0FBUyxFQUFFO2dCQUNyQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7YUFDbkM7WUFFRDs7O2VBR0c7WUFDSCxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7Z0JBQ3JCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO2dCQUV2QixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7b0JBQ3hDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLFNBQVMsRUFBRTs7d0JBQ3JELFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO29CQUUxRCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFO3dCQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUM7cUJBQ3BEO29CQUVELElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQztvQkFDaEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDO29CQUNsQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztpQkFDdkI7Z0JBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO29CQUN4QyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxRQUFRLEVBQUU7O3dCQUNyRCxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztvQkFFMUQsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRTt3QkFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDO3FCQUN0RDtvQkFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUM7b0JBQ2hDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQztvQkFDbEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7aUJBQ3ZCO2FBQ0Y7U0FDRjtJQUNILENBQUM7Ozs7O0lBRU8sNkNBQVM7Ozs7SUFBakI7O1lBQ1EsU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVzs7WUFDcEQsUUFBUSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVTtRQUV2RCxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLFNBQVMsRUFBRTtZQUNyQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7WUFFbEMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRTtnQkFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FBQzthQUN6RTtTQUNGO1FBRUQsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxRQUFRLEVBQUU7WUFDbkMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDO1lBRWhDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3JCLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLENBQUM7YUFDdkU7U0FDRjtRQUVELElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ2hFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7WUFFekMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRTtnQkFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7YUFDaEY7U0FDRjtRQUVELElBQUksSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQzdELElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7WUFFdkMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRTtnQkFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDOUU7U0FDRjtJQUNILENBQUM7Ozs7O0lBRU8sK0NBQVc7Ozs7SUFBbkI7O1lBQ1EsRUFBRSxHQUFHLElBQUksQ0FBQyxZQUFZOztZQUN0QixRQUFRLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztRQUM1QyxJQUFJLFFBQVEsRUFBRTs7Z0JBQ1IsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUM7O2dCQUV2QyxRQUFRLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDOztnQkFDM0QsVUFBVSxHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7WUFFMUYsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7WUFDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQztZQUN0QyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDO1lBQ3hDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsZUFBZSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDN0UsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzlFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUMzRSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFFMUUsSUFBSSxVQUFVLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRTtnQkFDMUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDeEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQzthQUN6RDtpQkFBTTtnQkFDTCxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUM7Z0JBQzlCLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQzthQUMvQjtZQUVELElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUVoRSxJQUFJLENBQUMsS0FBSyxRQUFRLEVBQUU7Z0JBQ2xCLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7YUFDcEQ7U0FDRjtJQUNILENBQUM7Ozs7O0lBRU8saURBQWE7Ozs7SUFBckI7UUFDRSxJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFO1lBQzFELElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1NBQ25FO1FBQ0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7SUFDeEIsQ0FBQzs7Ozs7SUFFTywrQ0FBVzs7OztJQUFuQjtRQUNFLHFCQUFxQjtRQUNyQixJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFFaEMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2YsSUFBSSxPQUFPLElBQUksQ0FBQyxNQUFNLEtBQUssUUFBUSxFQUFFO2dCQUNuQyxJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQzthQUNyRDtpQkFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUNyQyxJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzthQUMzRDtTQUNGO0lBQ0gsQ0FBQzs7Z0JBL21CRixTQUFTLFNBQUM7b0JBQ1QsUUFBUSxFQUFFLGVBQWU7b0JBQ3pCLFFBQVEsRUFBRSxhQUFhO2lCQUN4Qjs7OztnQkFoQlksVUFBVTtnQkFBRSxTQUFTOzs7OEJBdUQvQixLQUFLOzRCQWNMLEtBQUs7Z0NBUUwsS0FBSztnQ0FVTCxLQUFLO3lCQU1MLEtBQUs7NkJBR0wsS0FBSzs4QkFHTCxLQUFLOzZCQUdMLEtBQUs7OEJBR0wsS0FBSztzQ0FHTCxLQUFLOzBCQUdMLE1BQU07NkJBR04sTUFBTTt5QkFHTixNQUFNOztJQXdnQlQsZ0NBQUM7Q0FBQSxBQWhuQkQsSUFnbkJDO1NBNW1CWSx5QkFBeUI7Ozs7OztJQUNwQywrQ0FBMEI7Ozs7O0lBQzFCLDZDQUF1RDs7Ozs7SUFDdkQsZ0RBQW1DOzs7OztJQUNuQyxvREFBNkM7Ozs7O0lBQzdDLCtDQUFzRjs7Ozs7SUFDdEYsc0RBQTZGOzs7OztJQUM3RixpREFBeUI7Ozs7O0lBQ3pCLGlEQUF5Qzs7Ozs7SUFDekMsa0RBQXVDOzs7Ozs7SUFHdkMsOENBQStCOzs7OztJQUMvQiw2Q0FBa0M7Ozs7OztJQUdsQyw4Q0FBK0I7Ozs7O0lBQy9CLDZDQUFrQzs7Ozs7O0lBR2xDLDhDQUErQjs7Ozs7SUFDL0IsNkNBQWtDOzs7Ozs7SUFHbEMsOENBQW9DOzs7OztJQUVwQyw4Q0FBOEI7Ozs7Ozs7SUFNOUIsaURBQXlDOzs7OztJQUV6QyxnREFBeUM7Ozs7O0lBQ3pDLDhDQUEwQjs7Ozs7Ozs7OztJQWlCMUIsOENBQWdEOzs7Ozs7OztJQVFoRCxrREFBaUQ7Ozs7Ozs7Ozs7SUFVakQsa0RBQW9EOzs7Ozs7SUFNcEQsMkNBQTBDOzs7OztJQUcxQywrQ0FBbUM7Ozs7O0lBR25DLGdEQUFvQzs7Ozs7SUFHcEMsK0NBQW1DOzs7OztJQUduQyxnREFBb0M7Ozs7O0lBR3BDLHdEQUFvQzs7Ozs7SUFHcEMsNENBQXFEOzs7OztJQUdyRCwrQ0FBd0Q7Ozs7O0lBR3hELDJDQUFvRDs7Ozs7SUFFeEMsdUNBQW1DOzs7OztJQUFFLDZDQUEyQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgUmVuZGVyZXIyLFxuICBJbnB1dCwgT3V0cHV0LCBPbkluaXQsIEV2ZW50RW1pdHRlciwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLFxuICBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IFN1YnNjcmlwdGlvbiwgZnJvbUV2ZW50IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBIZWxwZXJCbG9jayB9IGZyb20gJy4vd2lkZ2V0cy9oZWxwZXItYmxvY2snO1xuaW1wb3J0IHsgUmVzaXplSGFuZGxlIH0gZnJvbSAnLi93aWRnZXRzL3Jlc2l6ZS1oYW5kbGUnO1xuaW1wb3J0IHsgUmVzaXplSGFuZGxlVHlwZSB9IGZyb20gJy4vbW9kZWxzL3Jlc2l6ZS1oYW5kbGUtdHlwZSc7XG5pbXBvcnQgeyBQb3NpdGlvbiwgSVBvc2l0aW9uIH0gZnJvbSAnLi9tb2RlbHMvcG9zaXRpb24nO1xuaW1wb3J0IHsgU2l6ZSB9IGZyb20gJy4vbW9kZWxzL3NpemUnO1xuaW1wb3J0IHsgSVJlc2l6ZUV2ZW50IH0gZnJvbSAnLi9tb2RlbHMvcmVzaXplLWV2ZW50JztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW25nUmVzaXphYmxlXScsXG4gIGV4cG9ydEFzOiAnbmdSZXNpemFibGUnXG59KVxuZXhwb3J0IGNsYXNzIEFuZ3VsYXJSZXNpemFibGVEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBBZnRlclZpZXdJbml0IHtcbiAgcHJpdmF0ZSBfcmVzaXphYmxlID0gdHJ1ZTtcbiAgcHJpdmF0ZSBfaGFuZGxlczogeyBba2V5OiBzdHJpbmddOiBSZXNpemVIYW5kbGUgfSA9IHt9O1xuICBwcml2YXRlIF9oYW5kbGVUeXBlOiBzdHJpbmdbXSA9IFtdO1xuICBwcml2YXRlIF9oYW5kbGVSZXNpemluZzogUmVzaXplSGFuZGxlID0gbnVsbDtcbiAgcHJpdmF0ZSBfZGlyZWN0aW9uOiB7ICduJzogYm9vbGVhbiwgJ3MnOiBib29sZWFuLCAndyc6IGJvb2xlYW4sICdlJzogYm9vbGVhbiB9ID0gbnVsbDtcbiAgcHJpdmF0ZSBfZGlyZWN0aW9uQ2hhbmdlZDogeyAnbic6IGJvb2xlYW4sICdzJzogYm9vbGVhbiwgJ3cnOiBib29sZWFuLCAnZSc6IGJvb2xlYW4gfSA9IG51bGw7XG4gIHByaXZhdGUgX2FzcGVjdFJhdGlvID0gMDtcbiAgcHJpdmF0ZSBfY29udGFpbm1lbnQ6IEhUTUxFbGVtZW50ID0gbnVsbDtcbiAgcHJpdmF0ZSBfb3JpZ01vdXNlUG9zOiBQb3NpdGlvbiA9IG51bGw7XG5cbiAgLyoqIE9yaWdpbmFsIFNpemUgYW5kIFBvc2l0aW9uICovXG4gIHByaXZhdGUgX29yaWdTaXplOiBTaXplID0gbnVsbDtcbiAgcHJpdmF0ZSBfb3JpZ1BvczogUG9zaXRpb24gPSBudWxsO1xuXG4gIC8qKiBDdXJyZW50IFNpemUgYW5kIFBvc2l0aW9uICovXG4gIHByaXZhdGUgX2N1cnJTaXplOiBTaXplID0gbnVsbDtcbiAgcHJpdmF0ZSBfY3VyclBvczogUG9zaXRpb24gPSBudWxsO1xuXG4gIC8qKiBJbml0aWFsIFNpemUgYW5kIFBvc2l0aW9uICovXG4gIHByaXZhdGUgX2luaXRTaXplOiBTaXplID0gbnVsbDtcbiAgcHJpdmF0ZSBfaW5pdFBvczogUG9zaXRpb24gPSBudWxsO1xuXG4gIC8qKiBTbmFwIHRvIGdpcmQgKi9cbiAgcHJpdmF0ZSBfZ3JpZFNpemU6IElQb3NpdGlvbiA9IG51bGw7XG5cbiAgcHJpdmF0ZSBfYm91bmRpbmc6IGFueSA9IG51bGw7XG5cbiAgLyoqXG4gICAqIEJ1Z2ZpeDogaUZyYW1lcywgYW5kIGNvbnRleHQgdW5yZWxhdGVkIGVsZW1lbnRzIGJsb2NrIGFsbCBldmVudHMsIGFuZCBhcmUgdW51c2FibGVcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL3hpZXppeXUvYW5ndWxhcjItZHJhZ2dhYmxlL2lzc3Vlcy84NFxuICAgKi9cbiAgcHJpdmF0ZSBfaGVscGVyQmxvY2s6IEhlbHBlckJsb2NrID0gbnVsbDtcblxuICBwcml2YXRlIGRyYWdnaW5nU3ViOiBTdWJzY3JpcHRpb24gPSBudWxsO1xuICBwcml2YXRlIF9hZGp1c3RlZCA9IGZhbHNlO1xuXG4gIC8qKiBEaXNhYmxlcyB0aGUgcmVzaXphYmxlIGlmIHNldCB0byBmYWxzZS4gKi9cbiAgQElucHV0KCkgc2V0IG5nUmVzaXphYmxlKHY6IGFueSkge1xuICAgIGlmICh2ICE9PSB1bmRlZmluZWQgJiYgdiAhPT0gbnVsbCAmJiB2ICE9PSAnJykge1xuICAgICAgdGhpcy5fcmVzaXphYmxlID0gISF2O1xuICAgICAgdGhpcy51cGRhdGVSZXNpemFibGUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogV2hpY2ggaGFuZGxlcyBjYW4gYmUgdXNlZCBmb3IgcmVzaXppbmcuXG4gICAqIEBleGFtcGxlXG4gICAqIFtyekhhbmRsZXNdID0gXCInbixlLHMsdyxzZSxuZSxzdyxudydcIlxuICAgKiBlcXVhbHMgdG86IFtyekhhbmRsZXNdID0gXCInYWxsJ1wiXG4gICAqXG4gICAqICovXG4gIEBJbnB1dCgpIHJ6SGFuZGxlczogUmVzaXplSGFuZGxlVHlwZSA9ICdlLHMsc2UnO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBlbGVtZW50IHNob3VsZCBiZSBjb25zdHJhaW5lZCB0byBhIHNwZWNpZmljIGFzcGVjdCByYXRpby5cbiAgICogIE11bHRpcGxlIHR5cGVzIHN1cHBvcnRlZDpcbiAgICogIGJvb2xlYW46IFdoZW4gc2V0IHRvIHRydWUsIHRoZSBlbGVtZW50IHdpbGwgbWFpbnRhaW4gaXRzIG9yaWdpbmFsIGFzcGVjdCByYXRpby5cbiAgICogIG51bWJlcjogRm9yY2UgdGhlIGVsZW1lbnQgdG8gbWFpbnRhaW4gYSBzcGVjaWZpYyBhc3BlY3QgcmF0aW8gZHVyaW5nIHJlc2l6aW5nLlxuICAgKi9cbiAgQElucHV0KCkgcnpBc3BlY3RSYXRpbzogYm9vbGVhbiB8IG51bWJlciA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBDb25zdHJhaW5zIHJlc2l6aW5nIHRvIHdpdGhpbiB0aGUgYm91bmRzIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBvciByZWdpb24uXG4gICAqICBNdWx0aXBsZSB0eXBlcyBzdXBwb3J0ZWQ6XG4gICAqICBTZWxlY3RvcjogVGhlIHJlc2l6YWJsZSBlbGVtZW50IHdpbGwgYmUgY29udGFpbmVkIHRvIHRoZSBib3VuZGluZyBib3ggb2YgdGhlIGZpcnN0IGVsZW1lbnQgZm91bmQgYnkgdGhlIHNlbGVjdG9yLlxuICAgKiAgICAgICAgICAgIElmIG5vIGVsZW1lbnQgaXMgZm91bmQsIG5vIGNvbnRhaW5tZW50IHdpbGwgYmUgc2V0LlxuICAgKiAgRWxlbWVudDogVGhlIHJlc2l6YWJsZSBlbGVtZW50IHdpbGwgYmUgY29udGFpbmVkIHRvIHRoZSBib3VuZGluZyBib3ggb2YgdGhpcyBlbGVtZW50LlxuICAgKiAgU3RyaW5nOiBQb3NzaWJsZSB2YWx1ZXM6IFwicGFyZW50XCIuXG4gICAqL1xuICBASW5wdXQoKSByekNvbnRhaW5tZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFNuYXBzIHRoZSByZXNpemluZyBlbGVtZW50IHRvIGEgZ3JpZCwgZXZlcnkgeCBhbmQgeSBwaXhlbHMuXG4gICAqIEEgbnVtYmVyIGZvciBib3RoIHdpZHRoIGFuZCBoZWlnaHQgb3IgYW4gYXJyYXkgdmFsdWVzIGxpa2UgWyB4LCB5IF1cbiAgICovXG4gIEBJbnB1dCgpIHJ6R3JpZDogbnVtYmVyIHwgbnVtYmVyW10gPSBudWxsO1xuXG4gIC8qKiBUaGUgbWluaW11bSB3aWR0aCB0aGUgcmVzaXphYmxlIHNob3VsZCBiZSBhbGxvd2VkIHRvIHJlc2l6ZSB0by4gKi9cbiAgQElucHV0KCkgcnpNaW5XaWR0aDogbnVtYmVyID0gbnVsbDtcblxuICAvKiogVGhlIG1pbmltdW0gaGVpZ2h0IHRoZSByZXNpemFibGUgc2hvdWxkIGJlIGFsbG93ZWQgdG8gcmVzaXplIHRvLiAqL1xuICBASW5wdXQoKSByek1pbkhlaWdodDogbnVtYmVyID0gbnVsbDtcblxuICAvKiogVGhlIG1heGltdW0gd2lkdGggdGhlIHJlc2l6YWJsZSBzaG91bGQgYmUgYWxsb3dlZCB0byByZXNpemUgdG8uICovXG4gIEBJbnB1dCgpIHJ6TWF4V2lkdGg6IG51bWJlciA9IG51bGw7XG5cbiAgLyoqIFRoZSBtYXhpbXVtIGhlaWdodCB0aGUgcmVzaXphYmxlIHNob3VsZCBiZSBhbGxvd2VkIHRvIHJlc2l6ZSB0by4gKi9cbiAgQElucHV0KCkgcnpNYXhIZWlnaHQ6IG51bWJlciA9IG51bGw7XG5cbiAgLyoqIFdoZXRoZXIgdG8gcHJldmVudCBkZWZhdWx0IGV2ZW50ICovXG4gIEBJbnB1dCgpIHByZXZlbnREZWZhdWx0RXZlbnQgPSB0cnVlO1xuXG4gIC8qKiBlbWl0dGVkIHdoZW4gc3RhcnQgcmVzaXppbmcgKi9cbiAgQE91dHB1dCgpIHJ6U3RhcnQgPSBuZXcgRXZlbnRFbWl0dGVyPElSZXNpemVFdmVudD4oKTtcblxuICAvKiogZW1pdHRlZCB3aGVuIHN0YXJ0IHJlc2l6aW5nICovXG4gIEBPdXRwdXQoKSByelJlc2l6aW5nID0gbmV3IEV2ZW50RW1pdHRlcjxJUmVzaXplRXZlbnQ+KCk7XG5cbiAgLyoqIGVtaXR0ZWQgd2hlbiBzdG9wIHJlc2l6aW5nICovXG4gIEBPdXRwdXQoKSByelN0b3AgPSBuZXcgRXZlbnRFbWl0dGVyPElSZXNpemVFdmVudD4oKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PiwgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyKSB7XG4gICAgdGhpcy5faGVscGVyQmxvY2sgPSBuZXcgSGVscGVyQmxvY2soZWwubmF0aXZlRWxlbWVudCwgcmVuZGVyZXIpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGlmIChjaGFuZ2VzWydyekhhbmRsZXMnXSAmJiAhY2hhbmdlc1sncnpIYW5kbGVzJ10uaXNGaXJzdENoYW5nZSgpKSB7XG4gICAgICB0aGlzLnVwZGF0ZVJlc2l6YWJsZSgpO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzWydyekFzcGVjdFJhdGlvJ10gJiYgIWNoYW5nZXNbJ3J6QXNwZWN0UmF0aW8nXS5pc0ZpcnN0Q2hhbmdlKCkpIHtcbiAgICAgIHRoaXMudXBkYXRlQXNwZWN0UmF0aW8oKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlc1sncnpDb250YWlubWVudCddICYmICFjaGFuZ2VzWydyekNvbnRhaW5tZW50J10uaXNGaXJzdENoYW5nZSgpKSB7XG4gICAgICB0aGlzLnVwZGF0ZUNvbnRhaW5tZW50KCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy51cGRhdGVSZXNpemFibGUoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMucmVtb3ZlSGFuZGxlcygpO1xuICAgIHRoaXMuX2NvbnRhaW5tZW50ID0gbnVsbDtcbiAgICB0aGlzLl9oZWxwZXJCbG9jay5kaXNwb3NlKCk7XG4gICAgdGhpcy5faGVscGVyQmxvY2sgPSBudWxsO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIGNvbnN0IGVsbSA9IHRoaXMuZWwubmF0aXZlRWxlbWVudDtcbiAgICB0aGlzLl9pbml0U2l6ZSA9IFNpemUuZ2V0Q3VycmVudChlbG0pO1xuICAgIHRoaXMuX2luaXRQb3MgPSBQb3NpdGlvbi5nZXRDdXJyZW50KGVsbSk7XG4gICAgdGhpcy5fY3VyclNpemUgPSBTaXplLmNvcHkodGhpcy5faW5pdFNpemUpO1xuICAgIHRoaXMuX2N1cnJQb3MgPSBQb3NpdGlvbi5jb3B5KHRoaXMuX2luaXRQb3MpO1xuICAgIHRoaXMudXBkYXRlQXNwZWN0UmF0aW8oKTtcbiAgICB0aGlzLnVwZGF0ZUNvbnRhaW5tZW50KCk7XG4gIH1cblxuICAvKiogQSBtZXRob2QgdG8gcmVzZXQgc2l6ZSAqL1xuICBwdWJsaWMgcmVzZXRTaXplKCkge1xuICAgIHRoaXMuX2N1cnJTaXplID0gU2l6ZS5jb3B5KHRoaXMuX2luaXRTaXplKTtcbiAgICB0aGlzLl9jdXJyUG9zID0gUG9zaXRpb24uY29weSh0aGlzLl9pbml0UG9zKTtcbiAgICB0aGlzLmRvUmVzaXplKCk7XG4gIH1cblxuICAvKiogQSBtZXRob2QgdG8gZ2V0IGN1cnJlbnQgc3RhdHVzICovXG4gIHB1YmxpYyBnZXRTdGF0dXMoKSB7XG4gICAgaWYgKCF0aGlzLl9jdXJyUG9zIHx8ICF0aGlzLl9jdXJyU2l6ZSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHNpemU6IHtcbiAgICAgICAgd2lkdGg6IHRoaXMuX2N1cnJTaXplLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IHRoaXMuX2N1cnJTaXplLmhlaWdodFxuICAgICAgfSxcbiAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgIHRvcDogdGhpcy5fY3VyclBvcy55LFxuICAgICAgICBsZWZ0OiB0aGlzLl9jdXJyUG9zLnhcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVSZXNpemFibGUoKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudDtcblxuICAgIC8vIGNsZWFyIGhhbmRsZXM6XG4gICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyhlbGVtZW50LCAnbmctcmVzaXphYmxlJyk7XG4gICAgdGhpcy5yZW1vdmVIYW5kbGVzKCk7XG5cbiAgICAvLyBjcmVhdGUgbmV3IG9uZXM6XG4gICAgaWYgKHRoaXMuX3Jlc2l6YWJsZSkge1xuICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyhlbGVtZW50LCAnbmctcmVzaXphYmxlJyk7XG4gICAgICB0aGlzLmNyZWF0ZUhhbmRsZXMoKTtcbiAgICB9XG4gIH1cblxuICAvKiogVXNlIGl0IHRvIHVwZGF0ZSBhc3BlY3QgKi9cbiAgcHJpdmF0ZSB1cGRhdGVBc3BlY3RSYXRpbygpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMucnpBc3BlY3RSYXRpbyA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBpZiAodGhpcy5yekFzcGVjdFJhdGlvICYmIHRoaXMuX2N1cnJTaXplLmhlaWdodCkge1xuICAgICAgICB0aGlzLl9hc3BlY3RSYXRpbyA9ICh0aGlzLl9jdXJyU2l6ZS53aWR0aCAvIHRoaXMuX2N1cnJTaXplLmhlaWdodCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9hc3BlY3RSYXRpbyA9IDA7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCByID0gTnVtYmVyKHRoaXMucnpBc3BlY3RSYXRpbyk7XG4gICAgICB0aGlzLl9hc3BlY3RSYXRpbyA9IGlzTmFOKHIpID8gMCA6IHI7XG4gICAgfVxuICB9XG5cbiAgLyoqIFVzZSBpdCB0byB1cGRhdGUgY29udGFpbm1lbnQgKi9cbiAgcHJpdmF0ZSB1cGRhdGVDb250YWlubWVudCgpIHtcbiAgICBpZiAoIXRoaXMucnpDb250YWlubWVudCkge1xuICAgICAgdGhpcy5fY29udGFpbm1lbnQgPSBudWxsO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5yekNvbnRhaW5tZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKHRoaXMucnpDb250YWlubWVudCA9PT0gJ3BhcmVudCcpIHtcbiAgICAgICAgdGhpcy5fY29udGFpbm1lbnQgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucGFyZW50RWxlbWVudDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2NvbnRhaW5tZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcjxIVE1MRWxlbWVudD4odGhpcy5yekNvbnRhaW5tZW50KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fY29udGFpbm1lbnQgPSB0aGlzLnJ6Q29udGFpbm1lbnQ7XG4gICAgfVxuICB9XG5cbiAgLyoqIFVzZSBpdCB0byBjcmVhdGUgaGFuZGxlIGRpdnMgKi9cbiAgcHJpdmF0ZSBjcmVhdGVIYW5kbGVzKCkge1xuICAgIGlmICghdGhpcy5yekhhbmRsZXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgdG1wSGFuZGxlVHlwZXM6IHN0cmluZ1tdO1xuICAgIGlmICh0eXBlb2YgdGhpcy5yekhhbmRsZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAodGhpcy5yekhhbmRsZXMgPT09ICdhbGwnKSB7XG4gICAgICAgIHRtcEhhbmRsZVR5cGVzID0gWyduJywgJ2UnLCAncycsICd3JywgJ25lJywgJ3NlJywgJ253JywgJ3N3J107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0bXBIYW5kbGVUeXBlcyA9IHRoaXMucnpIYW5kbGVzLnJlcGxhY2UoLyAvZywgJycpLnRvTG93ZXJDYXNlKCkuc3BsaXQoJywnKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgdHlwZSBvZiB0bXBIYW5kbGVUeXBlcykge1xuICAgICAgICAvLyBkZWZhdWx0IGhhbmRsZSB0aGVtZTogbmctcmVzaXphYmxlLSR0eXBlLlxuICAgICAgICBsZXQgaGFuZGxlID0gdGhpcy5jcmVhdGVIYW5kbGVCeVR5cGUodHlwZSwgYG5nLXJlc2l6YWJsZS0ke3R5cGV9YCk7XG4gICAgICAgIGlmIChoYW5kbGUpIHtcbiAgICAgICAgICB0aGlzLl9oYW5kbGVUeXBlLnB1c2godHlwZSk7XG4gICAgICAgICAgdGhpcy5faGFuZGxlc1t0eXBlXSA9IGhhbmRsZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0bXBIYW5kbGVUeXBlcyA9IE9iamVjdC5rZXlzKHRoaXMucnpIYW5kbGVzKTtcbiAgICAgIGZvciAobGV0IHR5cGUgb2YgdG1wSGFuZGxlVHlwZXMpIHtcbiAgICAgICAgLy8gY3VzdG9tIGhhbmRsZSB0aGVtZS5cbiAgICAgICAgbGV0IGhhbmRsZSA9IHRoaXMuY3JlYXRlSGFuZGxlQnlUeXBlKHR5cGUsIHRoaXMucnpIYW5kbGVzW3R5cGVdKTtcbiAgICAgICAgaWYgKGhhbmRsZSkge1xuICAgICAgICAgIHRoaXMuX2hhbmRsZVR5cGUucHVzaCh0eXBlKTtcbiAgICAgICAgICB0aGlzLl9oYW5kbGVzW3R5cGVdID0gaGFuZGxlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gIH1cblxuICAvKiogVXNlIGl0IHRvIGNyZWF0ZSBhIGhhbmRsZSAqL1xuICBwcml2YXRlIGNyZWF0ZUhhbmRsZUJ5VHlwZSh0eXBlOiBzdHJpbmcsIGNzczogc3RyaW5nKTogUmVzaXplSGFuZGxlIHtcbiAgICBjb25zdCBfZWwgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBpZiAoIXR5cGUubWF0Y2goL14oc2V8c3d8bmV8bnd8bnxlfHN8dykkLykpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgaGFuZGxlIHR5cGU6JywgdHlwZSk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFJlc2l6ZUhhbmRsZShfZWwsIHRoaXMucmVuZGVyZXIsIHR5cGUsIGNzcywgdGhpcy5vbk1vdXNlRG93bi5iaW5kKHRoaXMpKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlSGFuZGxlcygpIHtcbiAgICBmb3IgKGxldCB0eXBlIG9mIHRoaXMuX2hhbmRsZVR5cGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZXNbdHlwZV0uZGlzcG9zZSgpO1xuICAgIH1cblxuICAgIHRoaXMuX2hhbmRsZVR5cGUgPSBbXTtcbiAgICB0aGlzLl9oYW5kbGVzID0ge307XG4gIH1cblxuICBvbk1vdXNlRG93bihldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQsIGhhbmRsZTogUmVzaXplSGFuZGxlKSB7XG4gICAgLy8gc2tpcCByaWdodCBjbGljaztcbiAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBNb3VzZUV2ZW50ICYmIGV2ZW50LmJ1dHRvbiA9PT0gMikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnByZXZlbnREZWZhdWx0RXZlbnQpIHtcbiAgICAgIC8vIHByZXZlbnQgZGVmYXVsdCBldmVudHNcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuX2hhbmRsZVJlc2l6aW5nKSB7XG4gICAgICB0aGlzLl9vcmlnTW91c2VQb3MgPSBQb3NpdGlvbi5mcm9tRXZlbnQoZXZlbnQpO1xuICAgICAgdGhpcy5zdGFydFJlc2l6ZShoYW5kbGUpO1xuXG4gICAgICB0aGlzLnN1YnNjcmliZUV2ZW50cygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3Vic2NyaWJlRXZlbnRzKCkge1xuICAgIHRoaXMuZHJhZ2dpbmdTdWIgPSBmcm9tRXZlbnQoZG9jdW1lbnQsICdtb3VzZW1vdmUnLCB7IHBhc3NpdmU6IGZhbHNlIH0pLnN1YnNjcmliZShldmVudCA9PiB0aGlzLm9uTW91c2VNb3ZlKGV2ZW50IGFzIE1vdXNlRXZlbnQpKTtcbiAgICB0aGlzLmRyYWdnaW5nU3ViLmFkZChmcm9tRXZlbnQoZG9jdW1lbnQsICd0b3VjaG1vdmUnLCB7IHBhc3NpdmU6IGZhbHNlIH0pLnN1YnNjcmliZShldmVudCA9PiB0aGlzLm9uTW91c2VNb3ZlKGV2ZW50IGFzIFRvdWNoRXZlbnQpKSk7XG4gICAgdGhpcy5kcmFnZ2luZ1N1Yi5hZGQoZnJvbUV2ZW50KGRvY3VtZW50LCAnbW91c2V1cCcsIHsgcGFzc2l2ZTogZmFsc2UgfSkuc3Vic2NyaWJlKCgpID0+IHRoaXMub25Nb3VzZUxlYXZlKCkpKTtcbiAgICAvLyBmaXggZm9yIGlzc3VlICMxNjRcbiAgICBsZXQgaXNJRU9yRWRnZSA9IC9tc2llXFxzfHRyaWRlbnRcXC8vaS50ZXN0KHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgICBpZiAoIWlzSUVPckVkZ2UpIHtcbiAgICAgIHRoaXMuZHJhZ2dpbmdTdWIuYWRkKGZyb21FdmVudChkb2N1bWVudCwgJ21vdXNlbGVhdmUnLCB7IHBhc3NpdmU6IGZhbHNlIH0pLnN1YnNjcmliZSgoKSA9PiB0aGlzLm9uTW91c2VMZWF2ZSgpKSk7XG4gICAgfVxuICAgIHRoaXMuZHJhZ2dpbmdTdWIuYWRkKGZyb21FdmVudChkb2N1bWVudCwgJ3RvdWNoZW5kJywgeyBwYXNzaXZlOiBmYWxzZSB9KS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5vbk1vdXNlTGVhdmUoKSkpO1xuICAgIHRoaXMuZHJhZ2dpbmdTdWIuYWRkKGZyb21FdmVudChkb2N1bWVudCwgJ3RvdWNoY2FuY2VsJywgeyBwYXNzaXZlOiBmYWxzZSB9KS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5vbk1vdXNlTGVhdmUoKSkpO1xuICB9XG5cbiAgcHJpdmF0ZSB1bnN1YnNjcmliZUV2ZW50cygpIHtcbiAgICB0aGlzLmRyYWdnaW5nU3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5kcmFnZ2luZ1N1YiA9IG51bGw7XG4gIH1cblxuICBvbk1vdXNlTGVhdmUoKSB7XG4gICAgaWYgKHRoaXMuX2hhbmRsZVJlc2l6aW5nKSB7XG4gICAgICB0aGlzLnN0b3BSZXNpemUoKTtcbiAgICAgIHRoaXMuX29yaWdNb3VzZVBvcyA9IG51bGw7XG4gICAgICB0aGlzLnVuc3Vic2NyaWJlRXZlbnRzKCk7XG4gICAgfVxuICB9XG5cbiAgb25Nb3VzZU1vdmUoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSB7XG4gICAgaWYgKHRoaXMuX2hhbmRsZVJlc2l6aW5nICYmIHRoaXMuX3Jlc2l6YWJsZSAmJiB0aGlzLl9vcmlnTW91c2VQb3MgJiYgdGhpcy5fb3JpZ1BvcyAmJiB0aGlzLl9vcmlnU2l6ZSkge1xuICAgICAgdGhpcy5yZXNpemVUbyhQb3NpdGlvbi5mcm9tRXZlbnQoZXZlbnQpKTtcbiAgICAgIHRoaXMub25SZXNpemluZygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRSZXNpemUoaGFuZGxlOiBSZXNpemVIYW5kbGUpIHtcbiAgICBjb25zdCBlbG0gPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5fb3JpZ1NpemUgPSBTaXplLmdldEN1cnJlbnQoZWxtKTtcbiAgICB0aGlzLl9vcmlnUG9zID0gUG9zaXRpb24uZ2V0Q3VycmVudChlbG0pOyAvLyB4OiBsZWZ0LCB5OiB0b3BcbiAgICB0aGlzLl9jdXJyU2l6ZSA9IFNpemUuY29weSh0aGlzLl9vcmlnU2l6ZSk7XG4gICAgdGhpcy5fY3VyclBvcyA9IFBvc2l0aW9uLmNvcHkodGhpcy5fb3JpZ1Bvcyk7XG4gICAgaWYgKHRoaXMuX2NvbnRhaW5tZW50KSB7XG4gICAgICB0aGlzLmdldEJvdW5kaW5nKCk7XG4gICAgfVxuICAgIHRoaXMuZ2V0R3JpZFNpemUoKTtcblxuICAgIC8vIEFkZCBhIHRyYW5zcGFyZW50IGhlbHBlciBkaXY6XG4gICAgdGhpcy5faGVscGVyQmxvY2suYWRkKCk7XG4gICAgdGhpcy5faGFuZGxlUmVzaXppbmcgPSBoYW5kbGU7XG4gICAgdGhpcy51cGRhdGVEaXJlY3Rpb24oKTtcbiAgICB0aGlzLnJ6U3RhcnQuZW1pdCh0aGlzLmdldFJlc2l6aW5nRXZlbnQoKSk7XG4gIH1cblxuICBwcml2YXRlIHN0b3BSZXNpemUoKSB7XG4gICAgLy8gUmVtb3ZlIHRoZSBoZWxwZXIgZGl2OlxuICAgIHRoaXMuX2hlbHBlckJsb2NrLnJlbW92ZSgpO1xuICAgIHRoaXMucnpTdG9wLmVtaXQodGhpcy5nZXRSZXNpemluZ0V2ZW50KCkpO1xuICAgIHRoaXMuX2hhbmRsZVJlc2l6aW5nID0gbnVsbDtcbiAgICB0aGlzLl9kaXJlY3Rpb24gPSBudWxsO1xuICAgIHRoaXMuX29yaWdTaXplID0gbnVsbDtcbiAgICB0aGlzLl9vcmlnUG9zID0gbnVsbDtcbiAgICBpZiAodGhpcy5fY29udGFpbm1lbnQpIHtcbiAgICAgIHRoaXMucmVzZXRCb3VuZGluZygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25SZXNpemluZygpIHtcbiAgICB0aGlzLnJ6UmVzaXppbmcuZW1pdCh0aGlzLmdldFJlc2l6aW5nRXZlbnQoKSk7XG4gIH1cblxuICBwcml2YXRlIGdldFJlc2l6aW5nRXZlbnQoKTogSVJlc2l6ZUV2ZW50IHtcbiAgICByZXR1cm4ge1xuICAgICAgaG9zdDogdGhpcy5lbC5uYXRpdmVFbGVtZW50LFxuICAgICAgaGFuZGxlOiB0aGlzLl9oYW5kbGVSZXNpemluZyA/IHRoaXMuX2hhbmRsZVJlc2l6aW5nLmVsIDogbnVsbCxcbiAgICAgIHNpemU6IHtcbiAgICAgICAgd2lkdGg6IHRoaXMuX2N1cnJTaXplLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IHRoaXMuX2N1cnJTaXplLmhlaWdodFxuICAgICAgfSxcbiAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgIHRvcDogdGhpcy5fY3VyclBvcy55LFxuICAgICAgICBsZWZ0OiB0aGlzLl9jdXJyUG9zLnhcbiAgICAgIH0sXG4gICAgICBkaXJlY3Rpb246IHsgLi4udGhpcy5fZGlyZWN0aW9uQ2hhbmdlZCB9LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZURpcmVjdGlvbigpIHtcbiAgICB0aGlzLl9kaXJlY3Rpb24gPSB7XG4gICAgICBuOiAhIXRoaXMuX2hhbmRsZVJlc2l6aW5nLnR5cGUubWF0Y2goL24vKSxcbiAgICAgIHM6ICEhdGhpcy5faGFuZGxlUmVzaXppbmcudHlwZS5tYXRjaCgvcy8pLFxuICAgICAgdzogISF0aGlzLl9oYW5kbGVSZXNpemluZy50eXBlLm1hdGNoKC93LyksXG4gICAgICBlOiAhIXRoaXMuX2hhbmRsZVJlc2l6aW5nLnR5cGUubWF0Y2goL2UvKVxuICAgIH07XG5cbiAgICB0aGlzLl9kaXJlY3Rpb25DaGFuZ2VkID0geyAuLi50aGlzLl9kaXJlY3Rpb24gfTtcblxuICAgIC8vIGlmIGFzcGVjdCByYXRpb24gc2hvdWxkIGJlIHByZXNlcnZlZDpcbiAgICBpZiAodGhpcy5yekFzcGVjdFJhdGlvKSB7XG5cbiAgICAgIC8vIGlmIG5vcnRoIHRoZW4gd2VzdCAodW5sZXNzIG5lKVxuICAgICAgaWYgKHRoaXMuX2RpcmVjdGlvbkNoYW5nZWQubiAmJiAhdGhpcy5fZGlyZWN0aW9uQ2hhbmdlZC5lKSB7XG4gICAgICAgIHRoaXMuX2RpcmVjdGlvbkNoYW5nZWQudyA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGlmIHNvdXRoIHRoZW4gZWFzdCAodW5sZXNzIHN3KVxuICAgICAgaWYgKHRoaXMuX2RpcmVjdGlvbkNoYW5nZWQucyAmJiAhdGhpcy5fZGlyZWN0aW9uQ2hhbmdlZC53KSB7XG4gICAgICAgIHRoaXMuX2RpcmVjdGlvbkNoYW5nZWQuZSA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGlmIGVhc3QgdGhlbiBzb3V0aCAodW5sZXNzIG5lKVxuICAgICAgaWYgKHRoaXMuX2RpcmVjdGlvbkNoYW5nZWQuZSAmJiAhdGhpcy5fZGlyZWN0aW9uQ2hhbmdlZC5uKSB7XG4gICAgICAgIHRoaXMuX2RpcmVjdGlvbkNoYW5nZWQucyA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGlmIHdlc3QgdGhlbiBzb3V0aCAodW5sZXNzIG53KVxuICAgICAgaWYgKHRoaXMuX2RpcmVjdGlvbkNoYW5nZWQudyAmJiAhdGhpcy5fZGlyZWN0aW9uQ2hhbmdlZC5uKSB7XG4gICAgICAgIHRoaXMuX2RpcmVjdGlvbkNoYW5nZWQucyA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZXNpemVUbyhwOiBQb3NpdGlvbikge1xuICAgIHAuc3VidHJhY3QodGhpcy5fb3JpZ01vdXNlUG9zKTtcblxuICAgIGNvbnN0IHRtcFggPSBNYXRoLnJvdW5kKHAueCAvIHRoaXMuX2dyaWRTaXplLngpICogdGhpcy5fZ3JpZFNpemUueDtcbiAgICBjb25zdCB0bXBZID0gTWF0aC5yb3VuZChwLnkgLyB0aGlzLl9ncmlkU2l6ZS55KSAqIHRoaXMuX2dyaWRTaXplLnk7XG5cbiAgICBpZiAodGhpcy5fZGlyZWN0aW9uLm4pIHtcbiAgICAgIC8vIG4sIG5lLCBud1xuICAgICAgdGhpcy5fY3VyclBvcy55ID0gdGhpcy5fb3JpZ1Bvcy55ICsgdG1wWTtcbiAgICAgIHRoaXMuX2N1cnJTaXplLmhlaWdodCA9IHRoaXMuX29yaWdTaXplLmhlaWdodCAtIHRtcFk7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9kaXJlY3Rpb24ucykge1xuICAgICAgLy8gcywgc2UsIHN3XG4gICAgICB0aGlzLl9jdXJyU2l6ZS5oZWlnaHQgPSB0aGlzLl9vcmlnU2l6ZS5oZWlnaHQgKyB0bXBZO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9kaXJlY3Rpb24uZSkge1xuICAgICAgLy8gZSwgbmUsIHNlXG4gICAgICB0aGlzLl9jdXJyU2l6ZS53aWR0aCA9IHRoaXMuX29yaWdTaXplLndpZHRoICsgdG1wWDtcbiAgICB9IGVsc2UgaWYgKHRoaXMuX2RpcmVjdGlvbi53KSB7XG4gICAgICAvLyB3LCBudywgc3dcbiAgICAgIHRoaXMuX2N1cnJTaXplLndpZHRoID0gdGhpcy5fb3JpZ1NpemUud2lkdGggLSB0bXBYO1xuICAgICAgdGhpcy5fY3VyclBvcy54ID0gdGhpcy5fb3JpZ1Bvcy54ICsgdG1wWDtcbiAgICB9XG5cbiAgICB0aGlzLmNoZWNrQm91bmRzKCk7XG4gICAgdGhpcy5jaGVja1NpemUoKTtcbiAgICB0aGlzLmFkanVzdEJ5UmF0aW8oKTtcbiAgICB0aGlzLmRvUmVzaXplKCk7XG4gIH1cblxuICBwcml2YXRlIGRvUmVzaXplKCkge1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuZWwubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIXRoaXMuX2RpcmVjdGlvbiB8fCB0aGlzLl9kaXJlY3Rpb24ubiB8fCB0aGlzLl9kaXJlY3Rpb24ucyB8fCB0aGlzLl9hc3BlY3RSYXRpbykge1xuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShjb250YWluZXIsICdoZWlnaHQnLCB0aGlzLl9jdXJyU2l6ZS5oZWlnaHQgKyAncHgnKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLl9kaXJlY3Rpb24gfHwgdGhpcy5fZGlyZWN0aW9uLncgfHwgdGhpcy5fZGlyZWN0aW9uLmUgfHwgdGhpcy5fYXNwZWN0UmF0aW8pIHtcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoY29udGFpbmVyLCAnd2lkdGgnLCB0aGlzLl9jdXJyU2l6ZS53aWR0aCArICdweCcpO1xuICAgIH1cbiAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKGNvbnRhaW5lciwgJ2xlZnQnLCB0aGlzLl9jdXJyUG9zLnggKyAncHgnKTtcbiAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKGNvbnRhaW5lciwgJ3RvcCcsIHRoaXMuX2N1cnJQb3MueSArICdweCcpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGp1c3RCeVJhdGlvKCkge1xuICAgIGlmICh0aGlzLl9hc3BlY3RSYXRpbyAmJiAhdGhpcy5fYWRqdXN0ZWQpIHtcbiAgICAgIGlmICh0aGlzLl9kaXJlY3Rpb24uZSB8fCB0aGlzLl9kaXJlY3Rpb24udykge1xuICAgICAgICBjb25zdCBuZXdIZWlnaHQgPSBNYXRoLmZsb29yKHRoaXMuX2N1cnJTaXplLndpZHRoIC8gdGhpcy5fYXNwZWN0UmF0aW8pO1xuXG4gICAgICAgIGlmICh0aGlzLl9kaXJlY3Rpb24ubikge1xuICAgICAgICAgIHRoaXMuX2N1cnJQb3MueSArPSB0aGlzLl9jdXJyU2l6ZS5oZWlnaHQgLSBuZXdIZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9jdXJyU2l6ZS5oZWlnaHQgPSBuZXdIZWlnaHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBuZXdXaWR0aCA9IE1hdGguZmxvb3IodGhpcy5fYXNwZWN0UmF0aW8gKiB0aGlzLl9jdXJyU2l6ZS5oZWlnaHQpO1xuXG4gICAgICAgIGlmICh0aGlzLl9kaXJlY3Rpb24ubikge1xuICAgICAgICAgIHRoaXMuX2N1cnJQb3MueCArPSB0aGlzLl9jdXJyU2l6ZS53aWR0aCAtIG5ld1dpZHRoO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fY3VyclNpemUud2lkdGggPSBuZXdXaWR0aDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNoZWNrQm91bmRzKCkge1xuICAgIGlmICh0aGlzLl9jb250YWlubWVudCkge1xuICAgICAgY29uc3QgbWF4V2lkdGggPSB0aGlzLl9ib3VuZGluZy53aWR0aCAtIHRoaXMuX2JvdW5kaW5nLnByIC0gdGhpcy5fYm91bmRpbmcuZGVsdGFMIC0gdGhpcy5fYm91bmRpbmcudHJhbnNsYXRlWCAtIHRoaXMuX2N1cnJQb3MueDtcbiAgICAgIGNvbnN0IG1heEhlaWdodCA9IHRoaXMuX2JvdW5kaW5nLmhlaWdodCAtIHRoaXMuX2JvdW5kaW5nLnBiIC0gdGhpcy5fYm91bmRpbmcuZGVsdGFUIC0gdGhpcy5fYm91bmRpbmcudHJhbnNsYXRlWSAtIHRoaXMuX2N1cnJQb3MueTtcblxuICAgICAgaWYgKHRoaXMuX2RpcmVjdGlvbi5uICYmICh0aGlzLl9jdXJyUG9zLnkgKyB0aGlzLl9ib3VuZGluZy50cmFuc2xhdGVZIDwgMCkpIHtcbiAgICAgICAgdGhpcy5fY3VyclBvcy55ID0gLXRoaXMuX2JvdW5kaW5nLnRyYW5zbGF0ZVk7XG4gICAgICAgIHRoaXMuX2N1cnJTaXplLmhlaWdodCA9IHRoaXMuX29yaWdTaXplLmhlaWdodCArIHRoaXMuX29yaWdQb3MueSArIHRoaXMuX2JvdW5kaW5nLnRyYW5zbGF0ZVk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9kaXJlY3Rpb24udyAmJiAodGhpcy5fY3VyclBvcy54ICsgdGhpcy5fYm91bmRpbmcudHJhbnNsYXRlWCkgPCAwKSB7XG4gICAgICAgIHRoaXMuX2N1cnJQb3MueCA9IC10aGlzLl9ib3VuZGluZy50cmFuc2xhdGVYO1xuICAgICAgICB0aGlzLl9jdXJyU2l6ZS53aWR0aCA9IHRoaXMuX29yaWdTaXplLndpZHRoICsgdGhpcy5fb3JpZ1Bvcy54ICsgdGhpcy5fYm91bmRpbmcudHJhbnNsYXRlWDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuX2N1cnJTaXplLndpZHRoID4gbWF4V2lkdGgpIHtcbiAgICAgICAgdGhpcy5fY3VyclNpemUud2lkdGggPSBtYXhXaWR0aDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuX2N1cnJTaXplLmhlaWdodCA+IG1heEhlaWdodCkge1xuICAgICAgICB0aGlzLl9jdXJyU2l6ZS5oZWlnaHQgPSBtYXhIZWlnaHQ7XG4gICAgICB9XG5cbiAgICAgIC8qKlxuICAgICAgICogRml4IElzc3VlOiBBZGRpdGlvbmFsIGNoZWNrIGZvciBhc3BlY3QgcmF0aW9cbiAgICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS94aWV6aXl1L2FuZ3VsYXIyLWRyYWdnYWJsZS9pc3N1ZXMvMTMyXG4gICAgICAgKi9cbiAgICAgIGlmICh0aGlzLl9hc3BlY3RSYXRpbykge1xuICAgICAgICB0aGlzLl9hZGp1c3RlZCA9IGZhbHNlO1xuXG4gICAgICAgIGlmICgodGhpcy5fZGlyZWN0aW9uLncgfHwgdGhpcy5fZGlyZWN0aW9uLmUpICYmXG4gICAgICAgICAgICAodGhpcy5fY3VyclNpemUud2lkdGggLyB0aGlzLl9hc3BlY3RSYXRpbykgPj0gbWF4SGVpZ2h0KSB7XG4gICAgICAgICAgY29uc3QgbmV3V2lkdGggPSBNYXRoLmZsb29yKG1heEhlaWdodCAqIHRoaXMuX2FzcGVjdFJhdGlvKTtcblxuICAgICAgICAgIGlmICh0aGlzLl9kaXJlY3Rpb24udykge1xuICAgICAgICAgICAgdGhpcy5fY3VyclBvcy54ICs9IHRoaXMuX2N1cnJTaXplLndpZHRoIC0gbmV3V2lkdGg7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5fY3VyclNpemUud2lkdGggPSBuZXdXaWR0aDtcbiAgICAgICAgICB0aGlzLl9jdXJyU2l6ZS5oZWlnaHQgPSBtYXhIZWlnaHQ7XG4gICAgICAgICAgdGhpcy5fYWRqdXN0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCh0aGlzLl9kaXJlY3Rpb24ubiB8fCB0aGlzLl9kaXJlY3Rpb24ucykgJiZcbiAgICAgICAgICAgICh0aGlzLl9jdXJyU2l6ZS5oZWlnaHQgKiB0aGlzLl9hc3BlY3RSYXRpbykgPj0gbWF4V2lkdGgpIHtcbiAgICAgICAgICBjb25zdCBuZXdIZWlnaHQgPSBNYXRoLmZsb29yKG1heFdpZHRoIC8gdGhpcy5fYXNwZWN0UmF0aW8pO1xuXG4gICAgICAgICAgaWYgKHRoaXMuX2RpcmVjdGlvbi5uKSB7XG4gICAgICAgICAgICB0aGlzLl9jdXJyUG9zLnkgKz0gdGhpcy5fY3VyclNpemUuaGVpZ2h0IC0gbmV3SGVpZ2h0O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX2N1cnJTaXplLndpZHRoID0gbWF4V2lkdGg7XG4gICAgICAgICAgdGhpcy5fY3VyclNpemUuaGVpZ2h0ID0gbmV3SGVpZ2h0O1xuICAgICAgICAgIHRoaXMuX2FkanVzdGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tTaXplKCkge1xuICAgIGNvbnN0IG1pbkhlaWdodCA9ICF0aGlzLnJ6TWluSGVpZ2h0ID8gMSA6IHRoaXMucnpNaW5IZWlnaHQ7XG4gICAgY29uc3QgbWluV2lkdGggPSAhdGhpcy5yek1pbldpZHRoID8gMSA6IHRoaXMucnpNaW5XaWR0aDtcblxuICAgIGlmICh0aGlzLl9jdXJyU2l6ZS5oZWlnaHQgPCBtaW5IZWlnaHQpIHtcbiAgICAgIHRoaXMuX2N1cnJTaXplLmhlaWdodCA9IG1pbkhlaWdodDtcblxuICAgICAgaWYgKHRoaXMuX2RpcmVjdGlvbi5uKSB7XG4gICAgICAgIHRoaXMuX2N1cnJQb3MueSA9IHRoaXMuX29yaWdQb3MueSArICh0aGlzLl9vcmlnU2l6ZS5oZWlnaHQgLSBtaW5IZWlnaHQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9jdXJyU2l6ZS53aWR0aCA8IG1pbldpZHRoKSB7XG4gICAgICB0aGlzLl9jdXJyU2l6ZS53aWR0aCA9IG1pbldpZHRoO1xuXG4gICAgICBpZiAodGhpcy5fZGlyZWN0aW9uLncpIHtcbiAgICAgICAgdGhpcy5fY3VyclBvcy54ID0gdGhpcy5fb3JpZ1Bvcy54ICsgKHRoaXMuX29yaWdTaXplLndpZHRoIC0gbWluV2lkdGgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnJ6TWF4SGVpZ2h0ICYmIHRoaXMuX2N1cnJTaXplLmhlaWdodCA+IHRoaXMucnpNYXhIZWlnaHQpIHtcbiAgICAgIHRoaXMuX2N1cnJTaXplLmhlaWdodCA9IHRoaXMucnpNYXhIZWlnaHQ7XG5cbiAgICAgIGlmICh0aGlzLl9kaXJlY3Rpb24ubikge1xuICAgICAgICB0aGlzLl9jdXJyUG9zLnkgPSB0aGlzLl9vcmlnUG9zLnkgKyAodGhpcy5fb3JpZ1NpemUuaGVpZ2h0IC0gdGhpcy5yek1heEhlaWdodCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucnpNYXhXaWR0aCAmJiB0aGlzLl9jdXJyU2l6ZS53aWR0aCA+IHRoaXMucnpNYXhXaWR0aCkge1xuICAgICAgdGhpcy5fY3VyclNpemUud2lkdGggPSB0aGlzLnJ6TWF4V2lkdGg7XG5cbiAgICAgIGlmICh0aGlzLl9kaXJlY3Rpb24udykge1xuICAgICAgICB0aGlzLl9jdXJyUG9zLnggPSB0aGlzLl9vcmlnUG9zLnggKyAodGhpcy5fb3JpZ1NpemUud2lkdGggLSB0aGlzLnJ6TWF4V2lkdGgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0Qm91bmRpbmcoKSB7XG4gICAgY29uc3QgZWwgPSB0aGlzLl9jb250YWlubWVudDtcbiAgICBjb25zdCBjb21wdXRlZCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKTtcbiAgICBpZiAoY29tcHV0ZWQpIHtcbiAgICAgIGxldCBwID0gY29tcHV0ZWQuZ2V0UHJvcGVydHlWYWx1ZSgncG9zaXRpb24nKTtcblxuICAgICAgY29uc3QgbmF0aXZlRWwgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgbGV0IHRyYW5zZm9ybXMgPSBuYXRpdmVFbC5nZXRQcm9wZXJ0eVZhbHVlKCd0cmFuc2Zvcm0nKS5yZXBsYWNlKC9bXi1cXGQsXS9nLCAnJykuc3BsaXQoJywnKTtcblxuICAgICAgdGhpcy5fYm91bmRpbmcgPSB7fTtcbiAgICAgIHRoaXMuX2JvdW5kaW5nLndpZHRoID0gZWwuY2xpZW50V2lkdGg7XG4gICAgICB0aGlzLl9ib3VuZGluZy5oZWlnaHQgPSBlbC5jbGllbnRIZWlnaHQ7XG4gICAgICB0aGlzLl9ib3VuZGluZy5wciA9IHBhcnNlSW50KGNvbXB1dGVkLmdldFByb3BlcnR5VmFsdWUoJ3BhZGRpbmctcmlnaHQnKSwgMTApO1xuICAgICAgdGhpcy5fYm91bmRpbmcucGIgPSBwYXJzZUludChjb21wdXRlZC5nZXRQcm9wZXJ0eVZhbHVlKCdwYWRkaW5nLWJvdHRvbScpLCAxMCk7XG4gICAgICB0aGlzLl9ib3VuZGluZy5kZWx0YUwgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQub2Zmc2V0TGVmdCAtIHRoaXMuX2N1cnJQb3MueDtcbiAgICAgIHRoaXMuX2JvdW5kaW5nLmRlbHRhVCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5vZmZzZXRUb3AgLSB0aGlzLl9jdXJyUG9zLnk7XG5cbiAgICAgIGlmICh0cmFuc2Zvcm1zLmxlbmd0aCA+PSA2KSB7XG4gICAgICAgIHRoaXMuX2JvdW5kaW5nLnRyYW5zbGF0ZVggPSBwYXJzZUludCh0cmFuc2Zvcm1zWzRdLCAxMCk7XG4gICAgICAgIHRoaXMuX2JvdW5kaW5nLnRyYW5zbGF0ZVkgPSBwYXJzZUludCh0cmFuc2Zvcm1zWzVdLCAxMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9ib3VuZGluZy50cmFuc2xhdGVYID0gMDtcbiAgICAgICAgdGhpcy5fYm91bmRpbmcudHJhbnNsYXRlWSA9IDA7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2JvdW5kaW5nLnBvc2l0aW9uID0gY29tcHV0ZWQuZ2V0UHJvcGVydHlWYWx1ZSgncG9zaXRpb24nKTtcblxuICAgICAgaWYgKHAgPT09ICdzdGF0aWMnKSB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoZWwsICdwb3NpdGlvbicsICdyZWxhdGl2ZScpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVzZXRCb3VuZGluZygpIHtcbiAgICBpZiAodGhpcy5fYm91bmRpbmcgJiYgdGhpcy5fYm91bmRpbmcucG9zaXRpb24gPT09ICdzdGF0aWMnKSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuX2NvbnRhaW5tZW50LCAncG9zaXRpb24nLCAncmVsYXRpdmUnKTtcbiAgICB9XG4gICAgdGhpcy5fYm91bmRpbmcgPSBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRHcmlkU2l6ZSgpIHtcbiAgICAvLyBzZXQgZGVmYXVsdCB2YWx1ZTpcbiAgICB0aGlzLl9ncmlkU2l6ZSA9IHsgeDogMSwgeTogMSB9O1xuXG4gICAgaWYgKHRoaXMucnpHcmlkKSB7XG4gICAgICBpZiAodHlwZW9mIHRoaXMucnpHcmlkID09PSAnbnVtYmVyJykge1xuICAgICAgICB0aGlzLl9ncmlkU2l6ZSA9IHsgeDogdGhpcy5yekdyaWQsIHk6IHRoaXMucnpHcmlkIH07XG4gICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5yekdyaWQpKSB7XG4gICAgICAgIHRoaXMuX2dyaWRTaXplID0geyB4OiB0aGlzLnJ6R3JpZFswXSwgeTogdGhpcy5yekdyaWRbMV0gfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdfQ==