UNPKG

98.2 kBJavaScriptView Raw
1import { Component, Input, Output, ChangeDetectionStrategy, ChangeDetectorRef, Renderer2, ElementRef, NgZone, ViewChildren, Directive, Injectable, NgModule } from '@angular/core';
2import { Observable, Subject } from 'rxjs';
3import { debounceTime } from 'rxjs/operators';
4import { CommonModule } from '@angular/common';
5import { EVENT_MANAGER_PLUGINS } from '@angular/platform-browser';
6
7/**
8 * @fileoverview added by tsickle
9 * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
10 */
11/**
12 * @param {?} event
13 * @return {?}
14 */
15function getPointFromEvent(event) {
16 // TouchEvent
17 if (((/** @type {?} */ (event))).touches !== undefined && ((/** @type {?} */ (event))).touches.length > 0) {
18 return {
19 x: ((/** @type {?} */ (event))).touches[0].clientX,
20 y: ((/** @type {?} */ (event))).touches[0].clientY,
21 };
22 }
23 // MouseEvent
24 else if (((/** @type {?} */ (event))).clientX !== undefined && ((/** @type {?} */ (event))).clientY !== undefined) {
25 return {
26 x: ((/** @type {?} */ (event))).clientX,
27 y: ((/** @type {?} */ (event))).clientY,
28 };
29 }
30 return null;
31}
32/**
33 * @param {?} elRef
34 * @param {?} direction
35 * @return {?}
36 */
37function getPixelSize(elRef, direction) {
38 return elRef.nativeElement[(direction === 'horizontal') ? 'offsetWidth' : 'offsetHeight'];
39}
40/**
41 * @param {?} v
42 * @return {?}
43 */
44function getInputBoolean(v) {
45 return (typeof (v) === 'boolean') ? v : (v === 'false' ? false : true);
46}
47/**
48 * @param {?} total
49 * @return {?}
50 */
51function isValidTotalSize(total) {
52 return total > .999 && total < 1.001;
53}
54
55/**
56 * @fileoverview added by tsickle
57 * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
58 */
59/**
60 * angular-split
61 *
62 * Areas size are set in percentage of the split container.
63 * Gutters size are set in pixels.
64 *
65 * So we set css 'flex-basis' property like this (where 0 <= area.size <= 1):
66 * calc( { area.size * 100 }% - { area.size * nbGutter * gutterSize }px );
67 *
68 * Examples with 3 visible areas and 2 gutters:
69 *
70 * | 10px 10px |
71 * |---------------------[]---------------------[]------------------------------------|
72 * | calc(20% - 4px) calc(20% - 4px) calc(60% - 12px) |
73 *
74 *
75 * | 10px 10px |
76 * |--------------------------[]--------------------------[]--------------------------|
77 * | calc(33.33% - 6.667px) calc(33.33% - 6.667px) calc(33.33% - 6.667px) |
78 *
79 *
80 * |10px 10px |
81 * |[]----------------------------------------------------[]--------------------------|
82 * |0 calc(66.66% - 13.333px) calc(33%% - 6.667px) |
83 *
84 *
85 * 10px 10px |
86 * |[][]------------------------------------------------------------------------------|
87 * |0 0 calc(100% - 20px) |
88 *
89 */
90class SplitComponent {
91 /**
92 * @param {?} ngZone
93 * @param {?} elRef
94 * @param {?} cdRef
95 * @param {?} renderer
96 */
97 constructor(ngZone, elRef, cdRef, renderer) {
98 this.ngZone = ngZone;
99 this.elRef = elRef;
100 this.cdRef = cdRef;
101 this.renderer = renderer;
102 this._direction = 'horizontal';
103 ////
104 this._gutterSize = 11;
105 ////
106 this._useTransition = false;
107 ////
108 this._disabled = false;
109 ////
110 this._dir = 'ltr';
111 this.dragProgressSubject = new Subject();
112 this.dragProgress$ = this.dragProgressSubject.asObservable();
113 ////
114 this.isDragging = false;
115 this.currentGutterNum = 0;
116 this.startPoint = null;
117 this.endPoint = null;
118 this.displayedAreas = [];
119 this.hidedAreas = [];
120 this.dragListeners = [];
121 this.dragStartValues = {
122 sizePixelContainer: 0,
123 sizePixelA: 0,
124 sizePixelB: 0,
125 sizePercentA: 0,
126 sizePercentB: 0,
127 };
128 // To force adding default class, could be override by user @Input() or not
129 this.direction = this._direction;
130 }
131 /**
132 * @param {?} v
133 * @return {?}
134 */
135 set direction(v) {
136 this._direction = (v === 'vertical') ? 'vertical' : 'horizontal';
137 this.renderer.addClass(this.elRef.nativeElement, `is-${this._direction}`);
138 this.renderer.removeClass(this.elRef.nativeElement, `is-${(this._direction === 'vertical') ? 'horizontal' : 'vertical'}`);
139 this.build(false, false);
140 }
141 /**
142 * @return {?}
143 */
144 get direction() {
145 return this._direction;
146 }
147 /**
148 * @param {?} v
149 * @return {?}
150 */
151 set gutterSize(v) {
152 v = Number(v);
153 this._gutterSize = (!isNaN(v) && v > 0) ? v : 11;
154 this.build(false, false);
155 }
156 /**
157 * @return {?}
158 */
159 get gutterSize() {
160 return this._gutterSize;
161 }
162 /**
163 * @param {?} v
164 * @return {?}
165 */
166 set useTransition(v) {
167 this._useTransition = getInputBoolean(v);
168 if (this._useTransition)
169 this.renderer.addClass(this.elRef.nativeElement, 'is-transition');
170 else
171 this.renderer.removeClass(this.elRef.nativeElement, 'is-transition');
172 }
173 /**
174 * @return {?}
175 */
176 get useTransition() {
177 return this._useTransition;
178 }
179 /**
180 * @param {?} v
181 * @return {?}
182 */
183 set disabled(v) {
184 this._disabled = getInputBoolean(v);
185 if (this._disabled)
186 this.renderer.addClass(this.elRef.nativeElement, 'is-disabled');
187 else
188 this.renderer.removeClass(this.elRef.nativeElement, 'is-disabled');
189 }
190 /**
191 * @return {?}
192 */
193 get disabled() {
194 return this._disabled;
195 }
196 /**
197 * @param {?} v
198 * @return {?}
199 */
200 set dir(v) {
201 v = (v === 'rtl') ? 'rtl' : 'ltr';
202 this._dir = v;
203 this.renderer.setAttribute(this.elRef.nativeElement, 'dir', this._dir);
204 }
205 /**
206 * @return {?}
207 */
208 get dir() {
209 return this._dir;
210 }
211 /**
212 * @return {?}
213 */
214 get dragStart() {
215 return new Observable(subscriber => this.dragStartSubscriber = subscriber);
216 }
217 /**
218 * @return {?}
219 */
220 get dragEnd() {
221 return new Observable(subscriber => this.dragEndSubscriber = subscriber);
222 }
223 /**
224 * @return {?}
225 */
226 get gutterClick() {
227 return new Observable(subscriber => this.gutterClickSubscriber = subscriber);
228 }
229 /**
230 * @return {?}
231 */
232 get transitionEnd() {
233 return new Observable(subscriber => this.transitionEndSubscriber = subscriber).pipe(debounceTime(20));
234 }
235 /**
236 * @return {?}
237 */
238 ngAfterViewInit() {
239 this.ngZone.runOutsideAngular(() => {
240 // To avoid transition at first rendering
241 setTimeout(() => this.renderer.addClass(this.elRef.nativeElement, 'is-init'));
242 });
243 }
244 /**
245 * @return {?}
246 */
247 getNbGutters() {
248 return (this.displayedAreas.length === 0) ? 0 : this.displayedAreas.length - 1;
249 }
250 /**
251 * @param {?} component
252 * @return {?}
253 */
254 addArea(component) {
255 /** @type {?} */
256 const newArea = {
257 component,
258 order: 0,
259 size: 0,
260 };
261 if (component.visible === true) {
262 this.displayedAreas.push(newArea);
263 this.build(true, true);
264 }
265 else {
266 this.hidedAreas.push(newArea);
267 }
268 }
269 /**
270 * @param {?} component
271 * @return {?}
272 */
273 removeArea(component) {
274 if (this.displayedAreas.some(a => a.component === component)) {
275 /** @type {?} */
276 const area = this.displayedAreas.find(a => a.component === component);
277 this.displayedAreas.splice(this.displayedAreas.indexOf(area), 1);
278 this.build(true, true);
279 }
280 else if (this.hidedAreas.some(a => a.component === component)) {
281 /** @type {?} */
282 const area = this.hidedAreas.find(a => a.component === component);
283 this.hidedAreas.splice(this.hidedAreas.indexOf(area), 1);
284 }
285 }
286 /**
287 * @param {?} component
288 * @param {?} resetOrders
289 * @param {?} resetSizes
290 * @return {?}
291 */
292 updateArea(component, resetOrders, resetSizes) {
293 // Only refresh if area is displayed (No need to check inside 'hidedAreas')
294 /** @type {?} */
295 const area = this.displayedAreas.find(a => a.component === component);
296 if (!area) {
297 return;
298 }
299 this.build(resetOrders, resetSizes);
300 }
301 /**
302 * @param {?} component
303 * @return {?}
304 */
305 showArea(component) {
306 /** @type {?} */
307 const area = this.hidedAreas.find(a => a.component === component);
308 if (!area) {
309 return;
310 }
311 /** @type {?} */
312 const areas = this.hidedAreas.splice(this.hidedAreas.indexOf(area), 1);
313 this.displayedAreas.push(...areas);
314 this.build(true, true);
315 }
316 /**
317 * @param {?} comp
318 * @return {?}
319 */
320 hideArea(comp) {
321 /** @type {?} */
322 const area = this.displayedAreas.find(a => a.component === comp);
323 if (!area) {
324 return;
325 }
326 /** @type {?} */
327 const areas = this.displayedAreas.splice(this.displayedAreas.indexOf(area), 1);
328 areas.forEach(area => {
329 area.order = 0;
330 area.size = 0;
331 });
332 this.hidedAreas.push(...areas);
333 this.build(true, true);
334 }
335 /**
336 * @return {?}
337 */
338 getVisibleAreaSizes() {
339 return this.displayedAreas.map(a => a.size * 100);
340 }
341 /**
342 * @param {?} sizes
343 * @return {?}
344 */
345 setVisibleAreaSizes(sizes) {
346 if (sizes.length !== this.displayedAreas.length) {
347 return false;
348 }
349 sizes = sizes.map(s => s / 100);
350 /** @type {?} */
351 const total = sizes.reduce((total, v) => total + v, 0);
352 if (!isValidTotalSize(total)) {
353 return false;
354 }
355 this.displayedAreas.forEach((area, i) => {
356 // @ts-ignore
357 area.component._size = sizes[i];
358 });
359 this.build(false, true);
360 return true;
361 }
362 /**
363 * @param {?} resetOrders
364 * @param {?} resetSizes
365 * @return {?}
366 */
367 build(resetOrders, resetSizes) {
368 this.stopDragging();
369 // ¤ AREAS ORDER
370 if (resetOrders === true) {
371 // If user provided 'order' for each area, use it to sort them.
372 if (this.displayedAreas.every(a => a.component.order !== null)) {
373 this.displayedAreas.sort((a, b) => ((/** @type {?} */ (a.component.order))) - ((/** @type {?} */ (b.component.order))));
374 }
375 // Then set real order with multiples of 2, numbers between will be used by gutters.
376 this.displayedAreas.forEach((area, i) => {
377 area.order = i * 2;
378 area.component.setStyleOrder(area.order);
379 });
380 }
381 // ¤ AREAS SIZE PERCENT
382 if (resetSizes === true) {
383 /** @type {?} */
384 const totalUserSize = (/** @type {?} */ (this.displayedAreas.reduce((total, s) => s.component.size ? total + s.component.size : total, 0)));
385 // If user provided 'size' for each area and total == 1, use it.
386 if (this.displayedAreas.every(a => a.component.size !== null) && isValidTotalSize(totalUserSize)) {
387 this.displayedAreas.forEach(area => {
388 area.size = (/** @type {?} */ (area.component.size));
389 });
390 }
391 // Else set equal sizes for all areas.
392 else {
393 /** @type {?} */
394 const size = 1 / this.displayedAreas.length;
395 this.displayedAreas.forEach(area => {
396 area.size = size;
397 });
398 }
399 }
400 // ¤
401 // If some real area sizes are less than gutterSize,
402 // set them to zero and dispatch size to others.
403 /** @type {?} */
404 let percentToDispatch = 0;
405 // Get container pixel size
406 /** @type {?} */
407 const containerSizePixel = getPixelSize(this.elRef, this.direction);
408 this.displayedAreas.forEach(area => {
409 if (area.size * containerSizePixel < this.gutterSize) {
410 percentToDispatch += area.size;
411 area.size = 0;
412 }
413 });
414 if (percentToDispatch > 0 && this.displayedAreas.length > 0) {
415 /** @type {?} */
416 const nbAreasNotZero = this.displayedAreas.filter(a => a.size !== 0).length;
417 if (nbAreasNotZero > 0) {
418 /** @type {?} */
419 const percentToAdd = percentToDispatch / nbAreasNotZero;
420 this.displayedAreas.filter(a => a.size !== 0).forEach(area => {
421 area.size += percentToAdd;
422 });
423 }
424 // All area sizes (container percentage) are less than guterSize,
425 // It means containerSize < ngGutters * gutterSize
426 else {
427 this.displayedAreas[this.displayedAreas.length - 1].size = 1;
428 }
429 }
430 this.refreshStyleSizes();
431 this.cdRef.markForCheck();
432 }
433 /**
434 * @return {?}
435 */
436 refreshStyleSizes() {
437 /** @type {?} */
438 const sumGutterSize = this.getNbGutters() * this.gutterSize;
439 this.displayedAreas.forEach(area => {
440 area.component.setStyleFlexbasis(`calc( ${area.size * 100}% - ${area.size * sumGutterSize}px )`);
441 });
442 }
443 /**
444 * @param {?} event
445 * @param {?} gutterNum
446 * @return {?}
447 */
448 clickGutter(event, gutterNum) {
449 event.preventDefault();
450 event.stopPropagation();
451 if (this.startPoint && this.startPoint.x === event.clientX && this.startPoint.y === event.clientY) {
452 this.currentGutterNum = gutterNum;
453 this.notify('click');
454 }
455 }
456 /**
457 * @param {?} event
458 * @param {?} gutterOrder
459 * @param {?} gutterNum
460 * @return {?}
461 */
462 startDragging(event, gutterOrder, gutterNum) {
463 event.preventDefault();
464 event.stopPropagation();
465 this.startPoint = getPointFromEvent(event);
466 if (!this.startPoint || this.disabled) {
467 return;
468 }
469 /** @type {?} */
470 const areaA = this.displayedAreas.find(a => a.order === gutterOrder - 1);
471 /** @type {?} */
472 const areaB = this.displayedAreas.find(a => a.order === gutterOrder + 1);
473 if (!areaA || !areaB) {
474 return;
475 }
476 this.dragStartValues.sizePixelContainer = getPixelSize(this.elRef, this.direction);
477 this.dragStartValues.sizePixelA = getPixelSize(areaA.component.elRef, this.direction);
478 this.dragStartValues.sizePixelB = getPixelSize(areaB.component.elRef, this.direction);
479 this.dragStartValues.sizePercentA = areaA.size;
480 this.dragStartValues.sizePercentB = areaB.size;
481 this.currentGutterNum = gutterNum;
482 this.ngZone.runOutsideAngular(() => {
483 this.dragListeners.push(this.renderer.listen('document', 'mouseup', this.stopDragging.bind(this)));
484 this.dragListeners.push(this.renderer.listen('document', 'touchend', this.stopDragging.bind(this)));
485 this.dragListeners.push(this.renderer.listen('document', 'touchcancel', this.stopDragging.bind(this)));
486 this.dragListeners.push(this.renderer.listen('document', 'mousemove', (e) => this.dragEvent(e, areaA, areaB)));
487 this.dragListeners.push(this.renderer.listen('document', 'touchmove', (e) => this.dragEvent(e, areaA, areaB)));
488 });
489 areaA.component.lockEvents();
490 areaB.component.lockEvents();
491 this.isDragging = true;
492 this.renderer.addClass(this.elRef.nativeElement, 'is-dragging');
493 this.renderer.addClass(this.gutterEls.toArray()[this.currentGutterNum - 1].nativeElement, 'is-dragged');
494 this.notify('start');
495 }
496 /**
497 * @param {?} event
498 * @param {?} areaA
499 * @param {?} areaB
500 * @return {?}
501 */
502 dragEvent(event, areaA, areaB) {
503 event.preventDefault();
504 event.stopPropagation();
505 if (!this.isDragging) {
506 return;
507 }
508 this.endPoint = getPointFromEvent(event);
509 if (!this.endPoint) {
510 return;
511 }
512 // ¤ AREAS SIZE PIXEL
513 /** @type {?} */
514 let offsetPixel = (this.direction === 'horizontal') ? (this.startPoint.x - this.endPoint.x) : (this.startPoint.y - this.endPoint.y);
515 if (this.dir === 'rtl') {
516 offsetPixel = -offsetPixel;
517 }
518 /** @type {?} */
519 let newSizePixelA = this.dragStartValues.sizePixelA - offsetPixel;
520 /** @type {?} */
521 let newSizePixelB = this.dragStartValues.sizePixelB + offsetPixel;
522 if (newSizePixelA < this.gutterSize && newSizePixelB < this.gutterSize) {
523 // WTF.. get out of here!
524 return;
525 }
526 else if (newSizePixelA < this.gutterSize) {
527 newSizePixelB += newSizePixelA;
528 newSizePixelA = 0;
529 }
530 else if (newSizePixelB < this.gutterSize) {
531 newSizePixelA += newSizePixelB;
532 newSizePixelB = 0;
533 }
534 // ¤ AREAS SIZE PERCENT
535 if (newSizePixelA === 0) {
536 areaB.size += areaA.size;
537 areaA.size = 0;
538 }
539 else if (newSizePixelB === 0) {
540 areaA.size += areaB.size;
541 areaB.size = 0;
542 }
543 else {
544 // NEW_PERCENT = START_PERCENT / START_PIXEL * NEW_PIXEL;
545 if (this.dragStartValues.sizePercentA === 0) {
546 areaB.size = this.dragStartValues.sizePercentB / this.dragStartValues.sizePixelB * newSizePixelB;
547 areaA.size = this.dragStartValues.sizePercentB - areaB.size;
548 }
549 else if (this.dragStartValues.sizePercentB === 0) {
550 areaA.size = this.dragStartValues.sizePercentA / this.dragStartValues.sizePixelA * newSizePixelA;
551 areaB.size = this.dragStartValues.sizePercentA - areaA.size;
552 }
553 else {
554 areaA.size = this.dragStartValues.sizePercentA / this.dragStartValues.sizePixelA * newSizePixelA;
555 areaB.size = (this.dragStartValues.sizePercentA + this.dragStartValues.sizePercentB) - areaA.size;
556 }
557 }
558 this.refreshStyleSizes();
559 // If moved from starting point, notify progress
560 if (this.startPoint.x !== this.endPoint.x || this.startPoint.y !== this.endPoint.y) {
561 this.notify('progress');
562 }
563 }
564 /**
565 * @param {?=} event
566 * @return {?}
567 */
568 stopDragging(event) {
569 if (event) {
570 event.preventDefault();
571 event.stopPropagation();
572 }
573 if (this.isDragging === false) {
574 return;
575 }
576 this.displayedAreas.forEach(area => {
577 area.component.unlockEvents();
578 });
579 while (this.dragListeners.length > 0) {
580 /** @type {?} */
581 const fct = this.dragListeners.pop();
582 if (fct) {
583 fct();
584 }
585 }
586 // If moved from starting point, notify end
587 if (event && this.endPoint && (this.startPoint.x !== this.endPoint.x || this.startPoint.y !== this.endPoint.y)) {
588 this.notify('end');
589 }
590 this.isDragging = false;
591 this.renderer.removeClass(this.elRef.nativeElement, 'is-dragging');
592 this.renderer.removeClass(this.gutterEls.toArray()[this.currentGutterNum - 1].nativeElement, 'is-dragged');
593 // Needed to let (click)="clickGutter(...)" event run and verify if mouse moved or not
594 this.ngZone.runOutsideAngular(() => {
595 setTimeout(() => {
596 this.startPoint = null;
597 this.endPoint = null;
598 });
599 });
600 }
601 /**
602 * @param {?} type
603 * @return {?}
604 */
605 notify(type) {
606 /** @type {?} */
607 const sizes = this.displayedAreas.map(a => a.size * 100);
608 if (type === 'start') {
609 if (this.dragStartSubscriber) {
610 this.ngZone.run(() => this.dragStartSubscriber.next({ gutterNum: this.currentGutterNum, sizes }));
611 }
612 }
613 else if (type === 'end') {
614 if (this.dragEndSubscriber) {
615 this.ngZone.run(() => this.dragEndSubscriber.next({ gutterNum: this.currentGutterNum, sizes }));
616 }
617 }
618 else if (type === 'click') {
619 if (this.gutterClickSubscriber) {
620 this.ngZone.run(() => this.gutterClickSubscriber.next({ gutterNum: this.currentGutterNum, sizes }));
621 }
622 }
623 else if (type === 'transitionEnd') {
624 if (this.transitionEndSubscriber) {
625 this.ngZone.run(() => this.transitionEndSubscriber.next(sizes));
626 }
627 }
628 else if (type === 'progress') {
629 // Stay outside zone to allow users do what they want about change detection mechanism.
630 this.dragProgressSubject.next({ gutterNum: this.currentGutterNum, sizes });
631 }
632 }
633 /**
634 * @return {?}
635 */
636 ngOnDestroy() {
637 this.stopDragging();
638 }
639}
640SplitComponent.decorators = [
641 { type: Component, args: [{
642 selector: 'as-split',
643 changeDetection: ChangeDetectionStrategy.OnPush,
644 template: `
645 <ng-content></ng-content>
646 <ng-template ngFor [ngForOf]="displayedAreas" let-index="index" let-last="last">
647 <div *ngIf="last === false"
648 #gutterEls
649 class="as-split-gutter"
650 [style.flex-basis.px]="gutterSize"
651 [style.order]="index*2+1"
652 (as-split-undetected.click)="clickGutter($event, index+1)"
653 (as-split-undetected.mousedown)="startDragging($event, index*2+1, index+1)"
654 (as-split-undetected.touchstart)="startDragging($event, index*2+1, index+1)">
655 <div class="as-split-gutter-icon"></div>
656 </div>
657 </ng-template>`,
658 styles: [":host{display:flex;flex-wrap:nowrap;justify-content:flex-start;align-items:stretch;overflow:hidden;width:100%;height:100%}:host>.as-split-gutter{flex-grow:0;flex-shrink:0;background-color:#eee;display:flex;align-items:center;justify-content:center}:host>.as-split-gutter>.as-split-gutter-icon{width:100%;height:100%;background-position:center center;background-repeat:no-repeat}:host ::ng-deep>.as-split-area{flex-grow:0;flex-shrink:0;overflow-x:hidden;overflow-y:auto}:host ::ng-deep>.as-split-area.is-hided{flex-basis:0!important;overflow-x:hidden;overflow-y:hidden}:host.is-horizontal{flex-direction:row}:host.is-horizontal>.as-split-gutter{flex-direction:row;cursor:col-resize;height:100%}:host.is-horizontal>.as-split-gutter>.as-split-gutter-icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==)}:host.is-horizontal ::ng-deep>.as-split-area{height:100%}:host.is-vertical{flex-direction:column}:host.is-vertical>.as-split-gutter{flex-direction:column;cursor:row-resize;width:100%}:host.is-vertical>.as-split-gutter .as-split-gutter-icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFCAMAAABl/6zIAAAABlBMVEUAAADMzMzIT8AyAAAAAXRSTlMAQObYZgAAABRJREFUeAFjYGRkwIMJSeMHlBkOABP7AEGzSuPKAAAAAElFTkSuQmCC)}:host.is-vertical ::ng-deep>.as-split-area{width:100%}:host.is-vertical ::ng-deep>.as-split-area.is-hided{max-width:0}:host.is-disabled>.as-split-gutter{cursor:default}:host.is-disabled>.as-split-gutter .as-split-gutter-icon{background-image:url(\"\")}:host.is-transition.is-init:not(.is-dragging) ::ng-deep>.as-split-area,:host.is-transition.is-init:not(.is-dragging)>.as-split-gutter{transition:flex-basis .3s}"]
659 }] }
660];
661/** @nocollapse */
662SplitComponent.ctorParameters = () => [
663 { type: NgZone },
664 { type: ElementRef },
665 { type: ChangeDetectorRef },
666 { type: Renderer2 }
667];
668SplitComponent.propDecorators = {
669 direction: [{ type: Input }],
670 gutterSize: [{ type: Input }],
671 useTransition: [{ type: Input }],
672 disabled: [{ type: Input }],
673 dir: [{ type: Input }],
674 dragStart: [{ type: Output }],
675 dragEnd: [{ type: Output }],
676 gutterClick: [{ type: Output }],
677 transitionEnd: [{ type: Output }],
678 gutterEls: [{ type: ViewChildren, args: ['gutterEls',] }]
679};
680
681/**
682 * @fileoverview added by tsickle
683 * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
684 */
685class SplitAreaDirective {
686 /**
687 * @param {?} ngZone
688 * @param {?} elRef
689 * @param {?} renderer
690 * @param {?} split
691 */
692 constructor(ngZone, elRef, renderer, split) {
693 this.ngZone = ngZone;
694 this.elRef = elRef;
695 this.renderer = renderer;
696 this.split = split;
697 this._order = null;
698 ////
699 this._size = null;
700 ////
701 this._visible = true;
702 this.lockListeners = [];
703 this.renderer.addClass(this.elRef.nativeElement, 'as-split-area');
704 }
705 /**
706 * @param {?} v
707 * @return {?}
708 */
709 set order(v) {
710 v = Number(v);
711 this._order = !isNaN(v) ? v : null;
712 this.split.updateArea(this, true, false);
713 }
714 /**
715 * @return {?}
716 */
717 get order() {
718 return this._order;
719 }
720 /**
721 * @param {?} v
722 * @return {?}
723 */
724 set size(v) {
725 v = Number(v);
726 this._size = (!isNaN(v) && v >= 0 && v <= 100) ? (v / 100) : null;
727 this.split.updateArea(this, false, true);
728 }
729 /**
730 * @return {?}
731 */
732 get size() {
733 return this._size;
734 }
735 /**
736 * @param {?} v
737 * @return {?}
738 */
739 set visible(v) {
740 this._visible = getInputBoolean(v);
741 if (this._visible) {
742 this.split.showArea(this);
743 this.renderer.removeClass(this.elRef.nativeElement, 'is-hided');
744 }
745 else {
746 this.split.hideArea(this);
747 this.renderer.addClass(this.elRef.nativeElement, 'is-hided');
748 }
749 }
750 /**
751 * @return {?}
752 */
753 get visible() {
754 return this._visible;
755 }
756 /**
757 * @return {?}
758 */
759 ngOnInit() {
760 this.split.addArea(this);
761 this.ngZone.runOutsideAngular(() => {
762 this.transitionListener = this.renderer.listen(this.elRef.nativeElement, 'transitionend', (event) => {
763 // Limit only flex-basis transition to trigger the event
764 if (event.propertyName === 'flex-basis') {
765 this.split.notify('transitionEnd');
766 }
767 });
768 });
769 }
770 /**
771 * @param {?} value
772 * @return {?}
773 */
774 setStyleOrder(value) {
775 this.renderer.setStyle(this.elRef.nativeElement, 'order', value);
776 }
777 /**
778 * @param {?} value
779 * @return {?}
780 */
781 setStyleFlexbasis(value) {
782 this.renderer.setStyle(this.elRef.nativeElement, 'flex-basis', value);
783 }
784 /**
785 * @return {?}
786 */
787 lockEvents() {
788 this.ngZone.runOutsideAngular(() => {
789 this.lockListeners.push(this.renderer.listen(this.elRef.nativeElement, 'selectstart', (e) => false));
790 this.lockListeners.push(this.renderer.listen(this.elRef.nativeElement, 'dragstart', (e) => false));
791 });
792 }
793 /**
794 * @return {?}
795 */
796 unlockEvents() {
797 while (this.lockListeners.length > 0) {
798 /** @type {?} */
799 const fct = this.lockListeners.pop();
800 if (fct) {
801 fct();
802 }
803 }
804 }
805 /**
806 * @return {?}
807 */
808 ngOnDestroy() {
809 this.unlockEvents();
810 if (this.transitionListener) {
811 this.transitionListener();
812 }
813 this.split.removeArea(this);
814 }
815}
816SplitAreaDirective.decorators = [
817 { type: Directive, args: [{
818 selector: 'as-split-area, [as-split-area]'
819 },] }
820];
821/** @nocollapse */
822SplitAreaDirective.ctorParameters = () => [
823 { type: NgZone },
824 { type: ElementRef },
825 { type: Renderer2 },
826 { type: SplitComponent }
827];
828SplitAreaDirective.propDecorators = {
829 order: [{ type: Input }],
830 size: [{ type: Input }],
831 visible: [{ type: Input }]
832};
833
834/**
835 * @fileoverview added by tsickle
836 * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
837 */
838/**
839 * Credit to Michael Strobel from:
840 * https://github.com/kryops/ng2-events
841 */
842class UndetectedEventPlugin {
843 /**
844 * @param {?} eventName
845 * @return {?}
846 */
847 supports(eventName) {
848 return eventName.indexOf('as-split-undetected.') === 0;
849 }
850 /**
851 * @param {?} element
852 * @param {?} eventName
853 * @param {?} handler
854 * @return {?}
855 */
856 addEventListener(element, eventName, handler) {
857 /** @type {?} */
858 const realEventName = eventName.slice(20);
859 return this.manager.getZone().runOutsideAngular(() => this.manager.addEventListener(element, realEventName, handler));
860 }
861}
862UndetectedEventPlugin.decorators = [
863 { type: Injectable }
864];
865
866/**
867 * @fileoverview added by tsickle
868 * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
869 */
870class AngularSplitModule {
871 /**
872 * @return {?}
873 */
874 static forRoot() {
875 return {
876 ngModule: AngularSplitModule,
877 providers: [{
878 provide: EVENT_MANAGER_PLUGINS,
879 useClass: UndetectedEventPlugin,
880 multi: true
881 }]
882 };
883 }
884 /**
885 * @return {?}
886 */
887 static forChild() {
888 return {
889 ngModule: AngularSplitModule,
890 providers: []
891 };
892 }
893}
894AngularSplitModule.decorators = [
895 { type: NgModule, args: [{
896 imports: [
897 CommonModule
898 ],
899 declarations: [
900 SplitComponent,
901 SplitAreaDirective,
902 ],
903 exports: [
904 SplitComponent,
905 SplitAreaDirective,
906 ]
907 },] }
908];
909
910/**
911 * @fileoverview added by tsickle
912 * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
913 */
914
915/**
916 * @fileoverview added by tsickle
917 * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
918 */
919
920export { AngularSplitModule, SplitComponent, SplitAreaDirective, UndetectedEventPlugin as ɵa };
921
922//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1zcGxpdC5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vYW5ndWxhci1zcGxpdC9saWIvdXRpbHMudHMiLCJuZzovL2FuZ3VsYXItc3BsaXQvbGliL2NvbXBvbmVudC9zcGxpdC5jb21wb25lbnQudHMiLCJuZzovL2FuZ3VsYXItc3BsaXQvbGliL2RpcmVjdGl2ZS9zcGxpdEFyZWEuZGlyZWN0aXZlLnRzIiwibmc6Ly9hbmd1bGFyLXNwbGl0L2xpYi9zZXJ2aWNlL1VuZGV0ZWN0ZWRFdmVudFBsdWdpbi50cyIsIm5nOi8vYW5ndWxhci1zcGxpdC9saWIvbW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEVsZW1lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7IElQb2ludCB9IGZyb20gJy4vaW50ZXJmYWNlL0lQb2ludCc7XHJcblxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldFBvaW50RnJvbUV2ZW50KGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCk6IElQb2ludCB7XHJcbiAgICAvLyBUb3VjaEV2ZW50XHJcbiAgICBpZigoPFRvdWNoRXZlbnQ+IGV2ZW50KS50b3VjaGVzICE9PSB1bmRlZmluZWQgJiYgKDxUb3VjaEV2ZW50PiBldmVudCkudG91Y2hlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgeDogKDxUb3VjaEV2ZW50PiBldmVudCkudG91Y2hlc1swXS5jbGllbnRYLFxyXG4gICAgICAgICAgICB5OiAoPFRvdWNoRXZlbnQ+IGV2ZW50KS50b3VjaGVzWzBdLmNsaWVudFksXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIC8vIE1vdXNlRXZlbnRcclxuICAgIGVsc2UgaWYoKDxNb3VzZUV2ZW50PiBldmVudCkuY2xpZW50WCAhPT0gdW5kZWZpbmVkICYmICg8TW91c2VFdmVudD4gZXZlbnQpLmNsaWVudFkgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHg6ICg8TW91c2VFdmVudD4gZXZlbnQpLmNsaWVudFgsXHJcbiAgICAgICAgICAgIHk6ICg8TW91c2VFdmVudD4gZXZlbnQpLmNsaWVudFksXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGl4ZWxTaXplKGVsUmVmOiBFbGVtZW50UmVmLCBkaXJlY3Rpb246ICdob3Jpem9udGFsJyB8ICd2ZXJ0aWNhbCcpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIGVsUmVmLm5hdGl2ZUVsZW1lbnRbKGRpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnKSA/ICdvZmZzZXRXaWR0aCcgOiAnb2Zmc2V0SGVpZ2h0J107XHJcblxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW5wdXRCb29sZWFuKHY6IGFueSkge1xyXG4gICAgcmV0dXJuICh0eXBlb2YodikgPT09ICdib29sZWFuJykgPyB2IDogKHYgPT09ICdmYWxzZScgPyBmYWxzZSA6IHRydWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFRvdGFsU2l6ZSh0b3RhbDogbnVtYmVyKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdG90YWwgPiAuOTk5ICYmIHRvdGFsIDwgMS4wMDE7XHJcbn0iLCJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgUmVuZGVyZXIyLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIEVsZW1lbnRSZWYsIE5nWm9uZSwgVmlld0NoaWxkcmVuLCBRdWVyeUxpc3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3Vic2NyaWJlciwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQgeyBJQXJlYSB9IGZyb20gJy4uL2ludGVyZmFjZS9JQXJlYSc7XHJcbmltcG9ydCB7IElQb2ludCB9IGZyb20gJy4uL2ludGVyZmFjZS9JUG9pbnQnO1xyXG5pbXBvcnQgeyBTcGxpdEFyZWFEaXJlY3RpdmUgfSBmcm9tICcuLi9kaXJlY3RpdmUvc3BsaXRBcmVhLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IGdldFBvaW50RnJvbUV2ZW50LCBnZXRQaXhlbFNpemUsIGdldElucHV0Qm9vbGVhbiwgaXNWYWxpZFRvdGFsU2l6ZSB9IGZyb20gJy4uL3V0aWxzJztcclxuXHJcbi8qKlxyXG4gKiBhbmd1bGFyLXNwbGl0XHJcbiAqIFxyXG4gKiBBcmVhcyBzaXplIGFyZSBzZXQgaW4gcGVyY2VudGFnZSBvZiB0aGUgc3BsaXQgY29udGFpbmVyLlxyXG4gKiBHdXR0ZXJzIHNpemUgYXJlIHNldCBpbiBwaXhlbHMuXHJcbiAqIFxyXG4gKiBTbyB3ZSBzZXQgY3NzICdmbGV4LWJhc2lzJyBwcm9wZXJ0eSBsaWtlIHRoaXMgKHdoZXJlIDAgPD0gYXJlYS5zaXplIDw9IDEpOiBcclxuICogIGNhbGMoIHsgYXJlYS5zaXplICogMTAwIH0lIC0geyBhcmVhLnNpemUgKiBuYkd1dHRlciAqIGd1dHRlclNpemUgfXB4ICk7XHJcbiAqIFxyXG4gKiBFeGFtcGxlcyB3aXRoIDMgdmlzaWJsZSBhcmVhcyBhbmQgMiBndXR0ZXJzOiBcclxuICogXHJcbiAqIHwgICAgICAgICAgICAgICAgICAgICAxMHB4ICAgICAgICAgICAgICAgICAgIDEwcHggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxyXG4gKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tW10tLS0tLS0tLS0tLS0tLS0tLS0tLS1bXS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXxcclxuICogfCAgY2FsYygyMCUgLSA0cHgpICAgICAgICAgIGNhbGMoMjAlIC0gNHB4KSAgICAgICAgICAgICAgY2FsYyg2MCUgLSAxMnB4KSAgICAgICAgICB8XHJcbiAqIFxyXG4gKiBcclxuICogfCAgICAgICAgICAgICAgICAgICAgICAgICAgMTBweCAgICAgICAgICAgICAgICAgICAgICAgIDEwcHggICAgICAgICAgICAgICAgICAgICAgICB8XHJcbiAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVtdLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1bXS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfFxyXG4gKiB8ICBjYWxjKDMzLjMzJSAtIDYuNjY3cHgpICAgICAgY2FsYygzMy4zMyUgLSA2LjY2N3B4KSAgICAgIGNhbGMoMzMuMzMlIC0gNi42NjdweCkgIHxcclxuICogXHJcbiAqIFxyXG4gKiB8MTBweCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTBweCAgICAgICAgICAgICAgICAgICAgICAgIHxcclxuICogfFtdLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVtdLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18XHJcbiAqIHwwICAgICAgICAgICAgICAgICBjYWxjKDY2LjY2JSAtIDEzLjMzM3B4KSAgICAgICAgICAgICAgICAgIGNhbGMoMzMlJSAtIDYuNjY3cHgpICAgfFxyXG4gKiBcclxuICogXHJcbiAqICAxMHB4IDEwcHggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxyXG4gKiB8W11bXS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXxcclxuICogfDAgMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxjKDEwMCUgLSAyMHB4KSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XHJcbiAqIFxyXG4gKi9cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdhcy1zcGxpdCcsXHJcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxuICAgIHN0eWxlVXJsczogW2AuL3NwbGl0LmNvbXBvbmVudC5zY3NzYF0sXHJcbiAgICB0ZW1wbGF0ZTogYFxyXG4gICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cclxuICAgICAgICA8bmctdGVtcGxhdGUgbmdGb3IgW25nRm9yT2ZdPVwiZGlzcGxheWVkQXJlYXNcIiBsZXQtaW5kZXg9XCJpbmRleFwiIGxldC1sYXN0PVwibGFzdFwiPlxyXG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwibGFzdCA9PT0gZmFsc2VcIiBcclxuICAgICAgICAgICAgICAgICAjZ3V0dGVyRWxzXHJcbiAgICAgICAgICAgICAgICAgY2xhc3M9XCJhcy1zcGxpdC1ndXR0ZXJcIlxyXG4gICAgICAgICAgICAgICAgIFtzdHlsZS5mbGV4LWJhc2lzLnB4XT1cImd1dHRlclNpemVcIlxyXG4gICAgICAgICAgICAgICAgIFtzdHlsZS5vcmRlcl09XCJpbmRleCoyKzFcIlxyXG4gICAgICAgICAgICAgICAgIChhcy1zcGxpdC11bmRldGVjdGVkLmNsaWNrKT1cImNsaWNrR3V0dGVyKCRldmVudCwgaW5kZXgrMSlcIlxyXG4gICAgICAgICAgICAgICAgIChhcy1zcGxpdC11bmRldGVjdGVkLm1vdXNlZG93bik9XCJzdGFydERyYWdnaW5nKCRldmVudCwgaW5kZXgqMisxLCBpbmRleCsxKVwiXHJcbiAgICAgICAgICAgICAgICAgKGFzLXNwbGl0LXVuZGV0ZWN0ZWQudG91Y2hzdGFydCk9XCJzdGFydERyYWdnaW5nKCRldmVudCwgaW5kZXgqMisxLCBpbmRleCsxKVwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFzLXNwbGl0LWd1dHRlci1pY29uXCI+PC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvbmctdGVtcGxhdGU+YCxcclxufSlcclxuZXhwb3J0IGNsYXNzIFNwbGl0Q29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuXHJcbiAgICBwcml2YXRlIF9kaXJlY3Rpb246ICdob3Jpem9udGFsJyB8ICd2ZXJ0aWNhbCcgPSAnaG9yaXpvbnRhbCc7XHJcblxyXG4gICAgQElucHV0KCkgc2V0IGRpcmVjdGlvbih2OiAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnKSB7XHJcbiAgICAgICAgdGhpcy5fZGlyZWN0aW9uID0gKHYgPT09ICd2ZXJ0aWNhbCcpID8gJ3ZlcnRpY2FsJyA6ICdob3Jpem9udGFsJztcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudCwgYGlzLSR7IHRoaXMuX2RpcmVjdGlvbiB9YCk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQsIGBpcy0keyAodGhpcy5fZGlyZWN0aW9uID09PSAndmVydGljYWwnKSA/ICdob3Jpem9udGFsJyA6ICd2ZXJ0aWNhbCcgfWApO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHRoaXMuYnVpbGQoZmFsc2UsIGZhbHNlKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgZ2V0IGRpcmVjdGlvbigpOiAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZGlyZWN0aW9uO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvLy8vXHJcblxyXG4gICAgcHJpdmF0ZSBfZ3V0dGVyU2l6ZTogbnVtYmVyID0gMTE7XHJcblxyXG4gICAgQElucHV0KCkgc2V0IGd1dHRlclNpemUodjogbnVtYmVyKSB7XHJcbiAgICAgICAgdiA9IE51bWJlcih2KTtcclxuICAgICAgICB0aGlzLl9ndXR0ZXJTaXplID0gKCFpc05hTih2KSAmJiB2ID4gMCkgPyB2IDogMTE7XHJcblxyXG4gICAgICAgIHRoaXMuYnVpbGQoZmFsc2UsIGZhbHNlKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgZ2V0IGd1dHRlclNpemUoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ3V0dGVyU2l6ZTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgLy8vL1xyXG5cclxuICAgIHByaXZhdGUgX3VzZVRyYW5zaXRpb246IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgICBASW5wdXQoKSBzZXQgdXNlVHJhbnNpdGlvbih2OiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlVHJhbnNpdGlvbiA9IGdldElucHV0Qm9vbGVhbih2KTtcclxuXHJcbiAgICAgICAgaWYodGhpcy5fdXNlVHJhbnNpdGlvbikgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQsICdpcy10cmFuc2l0aW9uJyk7XHJcbiAgICAgICAgZWxzZSAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQsICdpcy10cmFuc2l0aW9uJyk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGdldCB1c2VUcmFuc2l0aW9uKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl91c2VUcmFuc2l0aW9uO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvLy8vXHJcblxyXG4gICAgcHJpdmF0ZSBfZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIFxyXG4gICAgQElucHV0KCkgc2V0IGRpc2FibGVkKHY6IGJvb2xlYW4pIHtcclxuICAgICAgICB0aGlzLl9kaXNhYmxlZCA9IGdldElucHV0Qm9vbGVhbih2KTtcclxuXHJcbiAgICAgICAgaWYodGhpcy5fZGlzYWJsZWQpICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudCwgJ2lzLWRpc2FibGVkJyk7XHJcbiAgICAgICAgZWxzZSAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudCwgJ2lzLWRpc2FibGVkJyk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGdldCBkaXNhYmxlZCgpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZGlzYWJsZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8vL1xyXG5cclxuICAgIHByaXZhdGUgX2RpcjogJ2x0cicgfCAncnRsJyA9ICdsdHInO1xyXG4gICAgXHJcbiAgICBASW5wdXQoKSBzZXQgZGlyKHY6ICdsdHInIHwgJ3J0bCcpIHtcclxuICAgICAgICB2ID0gKHYgPT09ICdydGwnKSA/ICdydGwnIDogJ2x0cic7XHJcbiAgICAgICAgdGhpcy5fZGlyID0gdjtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldEF0dHJpYnV0ZSh0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQsICdkaXInLCB0aGlzLl9kaXIpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBnZXQgZGlyKCk6ICdsdHInIHwgJ3J0bCcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9kaXI7XHJcbiAgICB9XHJcblxyXG4gICAgLy8vL1xyXG5cclxuICAgIHByaXZhdGUgZHJhZ1N0YXJ0U3Vic2NyaWJlcjogU3Vic2NyaWJlcjx7Z3V0dGVyTnVtOiBudW1iZXIsIHNpemVzOiBBcnJheTxudW1iZXI+fT5cclxuICAgIEBPdXRwdXQoKSBnZXQgZHJhZ1N0YXJ0KCk6IE9ic2VydmFibGU8e2d1dHRlck51bTogbnVtYmVyLCBzaXplczogQXJyYXk8bnVtYmVyPn0+IHtcclxuICAgICAgICByZXR1cm4gbmV3IE9ic2VydmFibGUoc3Vic2NyaWJlciA9PiB0aGlzLmRyYWdTdGFydFN1YnNjcmliZXIgPSBzdWJzY3JpYmVyKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGRyYWdFbmRTdWJzY3JpYmVyOiBTdWJzY3JpYmVyPHtndXR0ZXJOdW06IG51bWJlciwgc2l6ZXM6IEFycmF5PG51bWJlcj59PlxyXG4gICAgQE91dHB1dCgpIGdldCBkcmFnRW5kKCk6IE9ic2VydmFibGU8e2d1dHRlck51bTogbnVtYmVyLCBzaXplczogQXJyYXk8bnVtYmVyPn0+IHtcclxuICAgICAgICByZXR1cm4gbmV3IE9ic2VydmFibGUoc3Vic2NyaWJlciA9PiB0aGlzLmRyYWdFbmRTdWJzY3JpYmVyID0gc3Vic2NyaWJlcik7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBndXR0ZXJDbGlja1N1YnNjcmliZXI6IFN1YnNjcmliZXI8e2d1dHRlck51bTogbnVtYmVyLCBzaXplczogQXJyYXk8bnVtYmVyPn0+XHJcbiAgICBAT3V0cHV0KCkgZ2V0IGd1dHRlckNsaWNrKCk6IE9ic2VydmFibGU8e2d1dHRlck51bTogbnVtYmVyLCBzaXplczogQXJyYXk8bnVtYmVyPn0+IHtcclxuICAgICAgICByZXR1cm4gbmV3IE9ic2VydmFibGUoc3Vic2NyaWJlciA9PiB0aGlzLmd1dHRlckNsaWNrU3Vic2NyaWJlciA9IHN1YnNjcmliZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgdHJhbnNpdGlvbkVuZFN1YnNjcmliZXI6IFN1YnNjcmliZXI8QXJyYXk8bnVtYmVyPj5cclxuICAgIEBPdXRwdXQoKSBnZXQgdHJhbnNpdGlvbkVuZCgpOiBPYnNlcnZhYmxlPEFycmF5PG51bWJlcj4+IHtcclxuICAgICAgICByZXR1cm4gbmV3IE9ic2VydmFibGUoc3Vic2NyaWJlciA9PiB0aGlzLnRyYW5zaXRpb25FbmRTdWJzY3JpYmVyID0gc3Vic2NyaWJlcikucGlwZShcclxuICAgICAgICAgICAgZGVib3VuY2VUaW1lPEFycmF5PG51bWJlcj4+KDIwKVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHByaXZhdGUgZHJhZ1Byb2dyZXNzU3ViamVjdDogU3ViamVjdDx7Z3V0dGVyTnVtOiBudW1iZXIsIHNpemVzOiBBcnJheTxudW1iZXI+fT4gPSBuZXcgU3ViamVjdCgpO1xyXG4gICAgZHJhZ1Byb2dyZXNzJDogT2JzZXJ2YWJsZTx7Z3V0dGVyTnVtOiBudW1iZXIsIHNpemVzOiBBcnJheTxudW1iZXI+fT4gPSB0aGlzLmRyYWdQcm9ncmVzc1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gICAgLy8vL1xyXG5cclxuICAgIHByaXZhdGUgaXNEcmFnZ2luZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgcHJpdmF0ZSBjdXJyZW50R3V0dGVyTnVtOiBudW1iZXIgPSAwO1xyXG4gICAgcHJpdmF0ZSBzdGFydFBvaW50OiBJUG9pbnQgfCBudWxsID0gbnVsbDtcclxuICAgIHByaXZhdGUgZW5kUG9pbnQ6IElQb2ludCB8IG51bGwgPSBudWxsO1xyXG5cclxuICAgIHB1YmxpYyByZWFkb25seSBkaXNwbGF5ZWRBcmVhczogQXJyYXk8SUFyZWE+ID0gW107XHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGhpZGVkQXJlYXM6IEFycmF5PElBcmVhPiA9IFtdO1xyXG4gICAgXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRyYWdMaXN0ZW5lcnM6IEFycmF5PEZ1bmN0aW9uPiA9IFtdO1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBkcmFnU3RhcnRWYWx1ZXMgPSB7XHJcbiAgICAgICAgc2l6ZVBpeGVsQ29udGFpbmVyOiAwLFxyXG4gICAgICAgIHNpemVQaXhlbEE6IDAsXHJcbiAgICAgICAgc2l6ZVBpeGVsQjogMCxcclxuICAgICAgICBzaXplUGVyY2VudEE6IDAsXHJcbiAgICAgICAgc2l6ZVBlcmNlbnRCOiAwLFxyXG4gICAgfTtcclxuXHJcbiAgICBAVmlld0NoaWxkcmVuKCdndXR0ZXJFbHMnKSBwcml2YXRlIGd1dHRlckVsczogUXVlcnlMaXN0PEVsZW1lbnRSZWY+O1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXHJcbiAgICAgICAgICAgICAgICBwcml2YXRlIGVsUmVmOiBFbGVtZW50UmVmLFxyXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBjZFJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICAgICAgICAgICAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIpIHtcclxuICAgICAgICAvLyBUbyBmb3JjZSBhZGRpbmcgZGVmYXVsdCBjbGFzcywgY291bGQgYmUgb3ZlcnJpZGUgYnkgdXNlciBASW5wdXQoKSBvciBub3RcclxuICAgICAgICB0aGlzLmRpcmVjdGlvbiA9IHRoaXMuX2RpcmVjdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcclxuICAgICAgICAgICAgLy8gVG8gYXZvaWQgdHJhbnNpdGlvbiBhdCBmaXJzdCByZW5kZXJpbmdcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudCwgJ2lzLWluaXQnKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHByaXZhdGUgZ2V0TmJHdXR0ZXJzKCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmRpc3BsYXllZEFyZWFzLmxlbmd0aCA9PT0gMCkgPyAwIDogdGhpcy5kaXNwbGF5ZWRBcmVhcy5sZW5ndGggLSAxO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhZGRBcmVhKGNvbXBvbmVudDogU3BsaXRBcmVhRGlyZWN0aXZlKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgbmV3QXJlYTogSUFyZWEgPSB7XHJcbiAgICAgICAgICAgIGNvbXBvbmVudCwgXHJcbiAgICAgICAgICAgIG9yZGVyOiAwLCBcclxuICAgICAgICAgICAgc2l6ZTogMCxcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBpZihjb21wb25lbnQudmlzaWJsZSA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLmRpc3BsYXllZEFyZWFzLnB1c2gobmV3QXJlYSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmJ1aWxkKHRydWUsIHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5oaWRlZEFyZWFzLnB1c2gobmV3QXJlYSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyByZW1vdmVBcmVhKGNvbXBvbmVudDogU3BsaXRBcmVhRGlyZWN0aXZlKTogdm9pZCB7XHJcbiAgICAgICAgaWYodGhpcy5kaXNwbGF5ZWRBcmVhcy5zb21lKGEgPT4gYS5jb21wb25lbnQgPT09IGNvbXBvbmVudCkpIHtcclxuICAgICAgICAgICAgY29uc3QgYXJlYSA9IHRoaXMuZGlzcGxheWVkQXJlYXMuZmluZChhID0+IGEuY29tcG9uZW50ID09PSBjb21wb25lbnQpO1xyXG4gICAgICAgICAgICB0aGlzLmRpc3BsYXllZEFyZWFzLnNwbGljZSh0aGlzLmRpc3BsYXllZEFyZWFzLmluZGV4T2YoYXJlYSksIDEpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5idWlsZCh0cnVlLCB0cnVlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZih0aGlzLmhpZGVkQXJlYXMuc29tZShhID0+IGEuY29tcG9uZW50ID09PSBjb21wb25lbnQpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGFyZWEgPSB0aGlzLmhpZGVkQXJlYXMuZmluZChhID0+IGEuY29tcG9uZW50ID09PSBjb21wb25lbnQpO1xyXG4gICAgICAgICAgICB0aGlzLmhpZGVkQXJlYXMuc3BsaWNlKHRoaXMuaGlkZWRBcmVhcy5pbmRleE9mKGFyZWEpLCAxKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHVwZGF0ZUFyZWEoY29tcG9uZW50OiBTcGxpdEFyZWFEaXJlY3RpdmUsIHJlc2V0T3JkZXJzOiBib29sZWFuLCByZXNldFNpemVzOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICAgICAgLy8gT25seSByZWZyZXNoIGlmIGFyZWEgaXMgZGlzcGxheWVkIChObyBuZWVkIHRvIGNoZWNrIGluc2lkZSAnaGlkZWRBcmVhcycpXHJcbiAgICAgICAgY29uc3QgYXJlYSA9IHRoaXMuZGlzcGxheWVkQXJlYXMuZmluZChhID0+IGEuY29tcG9uZW50ID09PSBjb21wb25lbnQpO1xyXG4gICAgICAgIGlmKCFhcmVhKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuYnVpbGQocmVzZXRPcmRlcnMsIHJlc2V0U2l6ZXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzaG93QXJlYShjb21wb25lbnQ6IFNwbGl0QXJlYURpcmVjdGl2ZSk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGFyZWEgPSB0aGlzLmhpZGVkQXJlYXMuZmluZChhID0+IGEuY29tcG9uZW50ID09PSBjb21wb25lbnQpO1xyXG4gICAgICAgIGlmKCFhcmVhKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGFyZWFzID0gdGhpcy5oaWRlZEFyZWFzLnNwbGljZSh0aGlzLmhpZGVkQXJlYXMuaW5kZXhPZihhcmVhKSwgMSk7XHJcbiAgICAgICAgdGhpcy5kaXNwbGF5ZWRBcmVhcy5wdXNoKC4uLmFyZWFzKTtcclxuXHJcbiAgICAgICAgdGhpcy5idWlsZCh0cnVlLCB0cnVlKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgaGlkZUFyZWEoY29tcDogU3BsaXRBcmVhRGlyZWN0aXZlKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgYXJlYSA9IHRoaXMuZGlzcGxheWVkQXJlYXMuZmluZChhID0+IGEuY29tcG9uZW50ID09PSBjb21wKTtcclxuICAgICAgICBpZighYXJlYSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBhcmVhcyA9IHRoaXMuZGlzcGxheWVkQXJlYXMuc3BsaWNlKHRoaXMuZGlzcGxheWVkQXJlYXMuaW5kZXhPZihhcmVhKSwgMSk7XHJcbiAgICAgICAgYXJlYXMuZm9yRWFjaChhcmVhID0+IHtcclxuICAgICAgICAgICAgYXJlYS5vcmRlciA9IDA7XHJcbiAgICAgICAgICAgIGFyZWEuc2l6ZSA9IDA7XHJcbiAgICAgICAgfSlcclxuICAgICAgICB0aGlzLmhpZGVkQXJlYXMucHVzaCguLi5hcmVhcyk7XHJcblxyXG4gICAgICAgIHRoaXMuYnVpbGQodHJ1ZSwgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldFZpc2libGVBcmVhU2l6ZXMoKTogQXJyYXk8bnVtYmVyPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlzcGxheWVkQXJlYXMubWFwKGEgPT4gYS5zaXplICogMTAwKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc2V0VmlzaWJsZUFyZWFTaXplcyhzaXplczogQXJyYXk8bnVtYmVyPik6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmKHNpemVzLmxlbmd0aCAhPT0gdGhpcy5kaXNwbGF5ZWRBcmVhcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc2l6ZXMgPSBzaXplcy5tYXAocyA9PiBzIC8gMTAwKTtcclxuXHJcbiAgICAgICAgY29uc3QgdG90YWwgPSBzaXplcy5yZWR1Y2UoKHRvdGFsOiBudW1iZXIsIHY6IG51bWJlcikgPT4gdG90YWwgKyB2LCAwKTtcclxuICAgICAgICBpZighaXNWYWxpZFRvdGFsU2l6ZSh0b3RhbCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5kaXNwbGF5ZWRBcmVhcy5mb3JFYWNoKChhcmVhLCBpKSA9PiB7XHJcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcclxuICAgICAgICAgICAgYXJlYS5jb21wb25lbnQuX3NpemUgPSBzaXplc1tpXTtcclxuICAgICAgICB9KVxyXG5cclxuICAgICAgICB0aGlzLmJ1aWxkKGZhbHNlLCB0cnVlKTtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGJ1aWxkKHJlc2V0T3JkZXJzOiBib29sZWFuLCByZXNldFNpemVzOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5zdG9wRHJhZ2dpbmcoKTtcclxuXHJcbiAgICAgICAgLy8gw4LCpCBBUkVBUyBPUkRFUlxyXG4gICAgICAgIFxyXG4gICAgICAgIGlmKHJlc2V0T3JkZXJzID09PSB0cnVlKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBJZiB1c2VyIHByb3ZpZGVkICdvcmRlcicgZm9yIGVhY2ggYXJlYSwgdXNlIGl0IHRvIHNvcnQgdGhlbS5cclxuICAgICAgICAgICAgaWYodGhpcy5kaXNwbGF5ZWRBcmVhcy5ldmVyeShhID0+IGEuY29tcG9uZW50Lm9yZGVyICE9PSBudWxsKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5ZWRBcmVhcy5zb3J0KChhLCBiKSA9PiAoPG51bWJlcj4gYS5jb21wb25lbnQub3JkZXIpIC0gKDxudW1iZXI+IGIuY29tcG9uZW50Lm9yZGVyKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgIFxyXG4gICAgICAgICAgICAvLyBUaGVuIHNldCByZWFsIG9yZGVyIHdpdGggbXVsdGlwbGVzIG9mIDIsIG51bWJlcnMgYmV0d2VlbiB3aWxsIGJlIHVzZWQgYnkgZ3V0dGVycy5cclxuICAgICAgICAgICAgdGhpcy5kaXNwbGF5ZWRBcmVhcy5mb3JFYWNoKChhcmVhLCBpKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBhcmVhLm9yZGVyID0gaSAqIDI7XHJcbiAgICAgICAgICAgICAgICBhcmVhLmNvbXBvbmVudC5zZXRTdHlsZU9yZGVyKGFyZWEub3JkZXIpO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyDDgsKkIEFSRUFTIFNJWkUgUEVSQ0VOVFxyXG4gICAgICAgIFxyXG4gICAgICAgIGlmKHJlc2V0U2l6ZXMgPT09IHRydWUpIHtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHRvdGFsVXNlclNpemUgPSA8bnVtYmVyPiB0aGlzLmRpc3BsYXllZEFyZWFzLnJlZHVjZSgodG90YWw6IG51bWJlciwgczogSUFyZWEpID0+IHMuY29tcG9uZW50LnNpemUgPyB0b3RhbCArIHMuY29tcG9uZW50LnNpemUgOiB0b3RhbCwgMCk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyBJZiB1c2VyIHByb3ZpZGVkICdzaXplJyBmb3IgZWFjaCBhcmVhIGFuZCB0b3RhbCA9PSAxLCB1c2UgaXQuXHJcbiAgICAgICAgICAgIGlmKHRoaXMuZGlzcGxheWVkQXJlYXMuZXZlcnkoYSA9PiBhLmNvbXBvbmVudC5zaXplICE9PSBudWxsKSAmJiBpc1ZhbGlkVG90YWxTaXplKHRvdGFsVXNlclNpemUpICkge1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheWVkQXJlYXMuZm9yRWFjaChhcmVhID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBhcmVhLnNpemUgPSA8bnVtYmVyPiBhcmVhLmNvbXBvbmVudC5zaXplO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gRWxzZSBzZXQgZXF1YWwgc2l6ZXMgZm9yIGFsbCBhcmVhcy5cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzaXplID0gMSAvIHRoaXMuZGlzcGxheWVkQXJlYXMubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXllZEFyZWFzLmZvckVhY2goYXJlYSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXJlYS5zaXplID0gc2l6ZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIMOCwqQgXHJcbiAgICAgICAgLy8gSWYgc29tZSByZWFsIGFyZWEgc2l6ZXMgYXJlIGxlc3MgdGhhbiBndXR0ZXJTaXplLCBcclxuICAgICAgICAvLyBzZXQgdGhlbSB0byB6ZXJvIGFuZCBkaXNwYXRjaCBzaXplIHRvIG90aGVycy5cclxuXHJcbiAgICAgICAgbGV0IHBlcmNlbnRUb0Rpc3BhdGNoID0gMDtcclxuICAgICAgICBcclxuICAgICAgICAvLyBHZXQgY29udGFpbmVyIHBpeGVsIHNpemVcclxuICAgICAgICBjb25zdCBjb250YWluZXJTaXplUGl4ZWwgPSBnZXRQaXhlbFNpemUodGhpcy5lbFJlZiwgdGhpcy5kaXJlY3Rpb24pO1xyXG5cclxuICAgICAgICB0aGlzLmRpc3BsYXllZEFyZWFzLmZvckVhY2goYXJlYSA9PiB7XHJcbiAgICAgICAgICAgIGlmKGFyZWEuc2l6ZSAqIGNvbnRhaW5lclNpemVQaXhlbCA8IHRoaXMuZ3V0dGVyU2l6ZSkge1xyXG4gICAgICAgICAgICAgICAgcGVyY2VudFRvRGlzcGF0Y2ggKz0gYXJlYS5zaXplO1xyXG4gICAgICAgICAgICAgICAgYXJlYS5zaXplID0gMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmKHBlcmNlbnRUb0Rpc3BhdGNoID4gMCAmJiB0aGlzLmRpc3BsYXllZEFyZWFzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgY29uc3QgbmJBcmVhc05vdFplcm8gPSB0aGlzLmRpc3BsYXllZEFyZWFzLmZpbHRlcihhID0+IGEuc2l6ZSAhPT0gMCkubGVuZ3RoO1xyXG5cclxuICAgICAgICAgICAgaWYobmJBcmVhc05vdFplcm8gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwZXJjZW50VG9BZGQgPSBwZXJjZW50VG9EaXNwYXRjaCAvIG5iQXJlYXNOb3RaZXJvO1xyXG4gICAgXHJcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXllZEFyZWFzLmZpbHRlcihhID0+IGEuc2l6ZSAhPT0gMCkuZm9yRWFjaChhcmVhID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBhcmVhLnNpemUgKz0gcGVyY2VudFRvQWRkO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gQWxsIGFyZWEgc2l6ZXMgKGNvbnRhaW5lciBwZXJjZW50YWdlKSBhcmUgbGVzcyB0aGFuIGd1dGVyU2l6ZSxcclxuICAgICAgICAgICAgLy8gSXQgbWVhbnMgY29udGFpbmVyU2l6ZSA8IG5nR3V0dGVycyAqIGd1dHRlclNpemVcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXllZEFyZWFzW3RoaXMuZGlzcGxheWVkQXJlYXMubGVuZ3RoIC0gMV0uc2l6ZSA9IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMucmVmcmVzaFN0eWxlU2l6ZXMoKTtcclxuICAgICAgICB0aGlzLmNkUmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgcmVmcmVzaFN0eWxlU2l6ZXMoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3Qgc3VtR3V0dGVyU2l6ZSA9IHRoaXMuZ2V0TmJHdXR0ZXJzKCkgKiB0aGlzLmd1dHRlclNpemU7XHJcblxyXG4gICAgICAgIHRoaXMuZGlzcGxheWVkQXJlYXMuZm9yRWFjaChhcmVhID0+IHtcclxuICAgICAgICAgICAgYXJlYS5jb21wb25lbnQuc2V0U3R5bGVGbGV4YmFzaXMoYGNhbGMoICR7IGFyZWEuc2l6ZSAqIDEwMCB9JSAtICR7IGFyZWEuc2l6ZSAqIHN1bUd1dHRlclNpemUgfXB4IClgKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgY2xpY2tHdXR0ZXIoZXZlbnQ6IE1vdXNlRXZlbnQsIGd1dHRlck51bTogbnVtYmVyKTogdm9pZCB7XHJcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHJcbiAgICAgICAgaWYodGhpcy5zdGFydFBvaW50ICYmIHRoaXMuc3RhcnRQb2ludC54ID09PSBldmVudC5jbGllbnRYICYmIHRoaXMuc3RhcnRQb2ludC55ID09PSBldmVudC5jbGllbnRZKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEd1dHRlck51bSA9IGd1dHRlck51bTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMubm90aWZ5KCdjbGljaycpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhcnREcmFnZ2luZyhldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQsIGd1dHRlck9yZGVyOiBudW1iZXIsIGd1dHRlck51bTogbnVtYmVyKTogdm9pZCB7XHJcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHJcbiAgICAgICAgdGhpcy5zdGFydFBvaW50ID0gZ2V0UG9pbnRGcm9tRXZlbnQoZXZlbnQpO1xyXG4gICAgICAgIGlmKCF0aGlzLnN0YXJ0UG9pbnQgfHwgdGhpcy5kaXNhYmxlZCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBhcmVhQSA9IHRoaXMuZGlzcGxheWVkQXJlYXMuZmluZChhID0+IGEub3JkZXIgPT09IGd1dHRlck9yZGVyIC0gMSk7XHJcbiAgICAgICAgY29uc3QgYXJlYUIgPSB0aGlzLmRpc3BsYXllZEFyZWFzLmZpbmQoYSA9PiBhLm9yZGVyID09PSBndXR0ZXJPcmRlciArIDEpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmKCFhcmVhQSB8fCAhYXJlYUIpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5kcmFnU3RhcnRWYWx1ZXMuc2l6ZVBpeGVsQ29udGFpbmVyID0gZ2V0UGl4ZWxTaXplKHRoaXMuZWxSZWYsIHRoaXMuZGlyZWN0aW9uKTtcclxuICAgICAgICB0aGlzLmRyYWdTdGFydFZhbHVlcy5zaXplUGl4ZWxBID0gZ2V0UGl4ZWxTaXplKGFyZWFBLmNvbXBvbmVudC5lbFJlZiwgdGhpcy5kaXJlY3Rpb24pO1xyXG4gICAgICAgIHRoaXMuZHJhZ1N0YXJ0VmFsdWVzLnNpemVQaXhlbEIgPSBnZXRQaXhlbFNpemUoYXJlYUIuY29tcG9uZW50LmVsUmVmLCB0aGlzLmRpcmVjdGlvbik7XHJcbiAgICAgICAgdGhpcy5kcmFnU3RhcnRWYWx1ZXMuc2l6ZVBlcmNlbnRBID0gYXJlYUEuc2l6ZTtcclxuICAgICAgICB0aGlzLmRyYWdTdGFydFZhbHVlcy5zaXplUGVyY2VudEIgPSBhcmVhQi5zaXplO1xyXG4gICAgICAgIHRoaXMuY3VycmVudEd1dHRlck51bSA9IGd1dHRlck51bTtcclxuXHJcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmRyYWdMaXN0ZW5lcnMucHVzaCggdGhpcy5yZW5kZXJlci5saXN0ZW4oJ2RvY3VtZW50JywgJ21vdXNldXAnLCB0aGlzLnN0b3BEcmFnZ2luZy5iaW5kKHRoaXMpKSApO1xyXG4gICAgICAgICAgICB0aGlzLmRyYWdMaXN0ZW5lcnMucHVzaCggdGhpcy5yZW5kZXJlci5saXN0ZW4oJ2RvY3VtZW50JywgJ3RvdWNoZW5kJywgdGhpcy5zdG9wRHJhZ2dpbmcuYmluZCh0aGlzKSkgKTtcclxuICAgICAgICAgICAgdGhpcy5kcmFnTGlzdGVuZXJzLnB1c2goIHRoaXMucmVuZGVyZXIubGlzdGVuKCdkb2N1bWVudCcsICd0b3VjaGNhbmNlbCcsIHRoaXMuc3RvcERyYWdnaW5nLmJpbmQodGhpcykpICk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB0aGlzLmRyYWdMaXN0ZW5lcnMucHVzaCggdGhpcy5yZW5kZXJlci5saXN0ZW4oJ2RvY3VtZW50JywgJ21vdXNlbW92ZScsIChlOiBNb3VzZUV2ZW50KSA9PiB0aGlzLmRyYWdFdmVudChlLCBhcmVhQSwgYXJlYUIpKSApO1xyXG4gICAgICAgICAgICB0aGlzLmRyYWdMaXN0ZW5lcnMucHVzaCggdGhpcy5yZW5kZXJlci5saXN0ZW4oJ2RvY3VtZW50JywgJ3RvdWNobW92ZScsIChlOiBUb3VjaEV2ZW50KSA9PiB0aGlzLmRyYWdFdmVudChlLCBhcmVhQSwgYXJlYUIpKSApO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBhcmVhQS5jb21wb25lbnQubG9ja0V2ZW50cygpO1xyXG4gICAgICAgIGFyZWFCLmNvbXBvbmVudC5sb2NrRXZlbnRzKCk7XHJcblxyXG4gICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQsICdpcy1kcmFnZ2luZycpO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5ndXR0ZXJFbHMudG9BcnJheSgpW3RoaXMuY3VycmVudEd1dHRlck51bS0xXS5uYXRpdmVFbGVtZW50LCAnaXMtZHJhZ2dlZCcpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHRoaXMubm90aWZ5KCdzdGFydCcpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZHJhZ0V2ZW50KGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCwgYXJlYUE6IElBcmVhLCBhcmVhQjogSUFyZWEpOiB2b2lkIHtcclxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cclxuICAgICAgICBpZighdGhpcy5pc0RyYWdnaW5nKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuZW5kUG9pbnQgPSBnZXRQb2ludEZyb21FdmVudChldmVudCk7XHJcbiAgICAgICAgaWYoIXRoaXMuZW5kUG9pbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICAvLyDDgsKkIEFSRUFTIFNJWkUgUElYRUxcclxuXHJcbiAgICAgICAgbGV0IG9mZnNldFBpeGVsID0gKHRoaXMuZGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcpID8gKHRoaXMuc3RhcnRQb2ludC54IC0gdGhpcy5lbmRQb2ludC54KSA6ICh0aGlzLnN0YXJ0UG9pbnQueSAtIHRoaXMuZW5kUG9pbnQueSk7XHJcbiAgICAgICAgaWYodGhpcy5kaXIgPT09ICdydGwnKSB7XHJcbiAgICAgICAgICAgIG9mZnNldFBpeGVsID0gLW9mZnNldFBpeGVsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IG5ld1NpemVQaXhlbEEgPSB0aGlzLmRyYWdTdGFydFZhbHVlcy5zaXplUGl4ZWxBIC0gb2Zmc2V0UGl4ZWw7XHJcbiAgICAgICAgbGV0IG5ld1NpemVQaXhlbEIgPSB0aGlzLmRyYWdTdGFydFZhbHVlcy5zaXplUGl4ZWxCICsgb2Zmc2V0UGl4ZWw7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYobmV3U2l6ZVBpeGVsQSA8IHRoaXMuZ3V0dGVyU2l6ZSAmJiBuZXdTaXplUGl4ZWxCIDwgdGhpcy5ndXR0ZXJTaXplKSB7XHJcbiAgICAgICAgICAgIC8vIFdURi4uIGdldCBvdXQgb2YgaGVyZSFcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmKG5ld1NpemVQaXhlbEEgPCB0aGlzLmd1dHRlclNpemUpIHtcclxuICAgICAgICAgICAgbmV3U2l6ZVBpeGVsQiArPSBuZXdTaXplUGl4ZWxBO1xyXG4gICAgICAgICAgICBuZXdTaXplUGl4ZWxBID0gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZihuZXdTaXplUGl4ZWxCIDwgdGhpcy5ndXR0ZXJTaXplKSB7XHJcbiAgICAgICAgICAgIG5ld1NpemVQaXhlbEEgKz0gbmV3U2l6ZVBpeGVsQjtcclxuICAgICAgICAgICAgbmV3U2l6ZVBpeGVsQiA9IDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyDDgsKkIEFSRUFTIFNJWkUgUEVSQ0VOVFxyXG5cclxuICAgICAgICBpZihuZXdTaXplUGl4ZWxBID09PSAwKSB7XHJcbiAgICAgICAgICAgIGFyZWFCLnNpemUgKz0gYXJlYUEuc2l6ZTtcclxuICAgICAgICAgICAgYXJlYUEuc2l6ZSA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYobmV3U2l6ZVBpeGVsQiA9PT0gMCkge1xyXG4gICAgICAgICAgICBhcmVhQS5zaXplICs9IGFyZWFCLnNpemU7XHJcbiAgICAgICAgICAgIGFyZWFCLnNpemUgPSAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gTkVXX1BFUkNFTlQgPSBTVEFSVF9QRVJDRU5UIC8gU1RBUlRfUElYRUwgKiBORVdfUElYRUw7XHJcbiAgICAgICAgICAgIGlmKHRoaXMuZHJhZ1N0YXJ0VmFsdWVzLnNpemVQZXJjZW50QSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgYXJlYUIuc2l6ZSA9IHRoaXMuZHJhZ1N0YXJ0VmFsdWVzLnNpemVQZXJjZW50QiAvIHRoaXMuZHJhZ1N0YXJ0VmFsdWVzLnNpemVQaXhlbEIgKiBuZXdTaXplUGl4ZWxCO1xyXG4gICAgICAgICAgICAgICAgYXJlYUEuc2l6ZSA9IHRoaXMuZHJhZ1N0YXJ0VmFsdWVzLnNpemVQZXJjZW50QiAtIGFyZWFCLnNpemU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZih0aGlzLmRyYWdTdGFydFZhbHVlcy5zaXplUGVyY2VudEIgPT09IDApIHtcclxuICAgICAgICAgICAgICAgIGFyZWFBLnNpemUgPSB0aGlzLmRyYWdTdGFydFZhbHVlcy5zaXplUGVyY2VudEEgLyB0aGlzLmRyYWdTdGFydFZhbHVlcy5zaXplUGl4ZWxBICogbmV3U2l6ZVBpeGVsQTtcclxuICAgICAgICAgICAgICAgIGFyZWFCLnNpemUgPSB0aGlzLmRyYWdTdGFydFZhbHVlcy5zaXplUGVyY2VudEEgLSBhcmVhQS5zaXplO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYXJlYUEuc2l6ZSA9IHRoaXMuZHJhZ1N0YXJ0VmFsdWVzLnNpemVQZXJjZW50QSAvIHRoaXMuZHJhZ1N0YXJ0VmFsdWVzLnNpemVQaXhlbEEgKiBuZXdTaXplUGl4ZWxBO1xyXG4gICAgICAgICAgICAgICAgYXJlYUIuc2l6ZSA9ICh0aGlzLmRyYWdTdGFydFZhbHVlcy5zaXplUGVyY2VudEEgKyB0aGlzLmRyYWdTdGFydFZhbHVlcy5zaXplUGVyY2VudEIpIC0gYXJlYUEuc2l6ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5yZWZyZXNoU3R5bGVTaXplcygpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIElmIG1vdmVkIGZyb20gc3RhcnRpbmcgcG9pbnQsIG5vdGlmeSBwcm9ncmVzc1xyXG4gICAgICAgIGlmKHRoaXMuc3RhcnRQb2ludC54ICE9PSB0aGlzLmVuZFBvaW50LnggfHwgdGhpcy5zdGFydFBvaW50LnkgIT09IHRoaXMuZW5kUG9pbnQueSkge1xyXG4gICAgICAgICAgICB0aGlzLm5vdGlmeSgncHJvZ3Jlc3MnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdG9wRHJhZ2dpbmcoZXZlbnQ/OiBFdmVudCk6IHZvaWQge1xyXG4gICAgICAgIGlmKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBpZih0aGlzLmlzRHJhZ2dpbmcgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGhpcy5kaXNwbGF5ZWRBcmVhcy5mb3JFYWNoKGFyZWEgPT4ge1xyXG4gICAgICAgICAgICBhcmVhLmNvbXBvbmVudC51bmxvY2tFdmVudHMoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBcclxuICAgICAgICB3aGlsZSh0aGlzLmRyYWdMaXN0ZW5lcnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBjb25zdCBmY3QgPSB0aGlzLmRyYWdMaXN0ZW5lcnMucG9wKCk7XHJcbiAgICAgICAgICAgIGlmKGZjdCkge1xyXG4gICAgICAgICAgICAgICAgZmN0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gSWYgbW92ZWQgZnJvbSBzdGFydGluZyBwb2ludCwgbm90aWZ5IGVuZFxyXG4gICAgICAgIGlmKGV2ZW50ICYmIHRoaXMuZW5kUG9pbnQgJiYgKHRoaXMuc3RhcnRQb2ludC54ICE9PSB0aGlzLmVuZFBvaW50LnggfHwgdGhpcy5zdGFydFBvaW50LnkgIT09IHRoaXMuZW5kUG9pbnQueSkpIHtcclxuICAgICAgICAgICAgdGhpcy5ub3RpZnkoJ2VuZCcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudCwgJ2lzLWRyYWdnaW5nJyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLmd1dHRlckVscy50b0FycmF5KClbdGhpcy5jdXJyZW50R3V0dGVyTnVtLTFdLm5hdGl2ZUVsZW1lbnQsICdpcy1kcmFnZ2VkJyk7XHJcblxyXG4gICAgICAgIC8vIE5lZWRlZCB0byBsZXQgKGNsaWNrKT1cImNsaWNrR3V0dGVyKC4uLilcIiBldmVudCBydW4gYW5kIHZlcmlmeSBpZiBtb3VzZSBtb3ZlZCBvciBub3RcclxuICAgICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zdGFydFBvaW50ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIHRoaXMuZW5kUG9pbnQgPSBudWxsO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBub3RpZnkodHlwZTogJ3N0YXJ0JyB8ICdwcm9ncmVzcycgfCAnZW5kJyB8ICdjbGljaycgfCAndHJhbnNpdGlvbkVuZCcpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBzaXplczogQXJyYXk8bnVtYmVyPiA9IHRoaXMuZGlzcGxheWVkQXJlYXMubWFwKGEgPT4gYS5zaXplICogMTAwKTtcclxuXHJcbiAgICAgICAgaWYodHlwZSA9PT0gJ3N0YXJ0Jykge1xyXG4gICAgICAgICAgICBpZih0aGlzLmRyYWdTdGFydFN1YnNjcmliZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLmRyYWdTdGFydFN1YnNjcmliZXIubmV4dCh7Z3V0dGVyTnVtOiB0aGlzLmN1cnJlbnRHdXR0ZXJOdW0sIHNpemVzfSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYodHlwZSA9PT0gJ2VuZCcpIHtcclxuICAgICAgICAgICAgaWYodGhpcy5kcmFnRW5kU3Vic2NyaWJlcikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuZHJhZ0VuZFN1YnNjcmliZXIubmV4dCh7Z3V0dGVyTnVtOiB0aGlzLmN1cnJlbnRHdXR0ZXJOdW0sIHNpemVzfSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYodHlwZSA9PT0gJ2NsaWNrJykge1xyXG4gICAgICAgICAgICBpZih0aGlzLmd1dHRlckNsaWNrU3Vic2NyaWJlcikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuZ3V0dGVyQ2xpY2tTdWJzY3JpYmVyLm5leHQoe2d1dHRlck51bTogdGhpcy5jdXJyZW50R3V0dGVyTnVtLCBzaXplc30pKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmKHR5cGUgPT09ICd0cmFuc2l0aW9uRW5kJykge1xyXG4gICAgICAgICAgICBpZih0aGlzLnRyYW5zaXRpb25FbmRTdWJzY3JpYmVyKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy50cmFuc2l0aW9uRW5kU3Vic2NyaWJlci5uZXh0KHNpemVzKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZih0eXBlID09PSAncHJvZ3Jlc3MnKSB7XHJcbiAgICAgICAgICAgIC8vIFN0YXkgb3V0c2lkZSB6b25lIHRvIGFsbG93IHVzZXJzIGRvIHdoYXQgdGhleSB3YW50IGFib3V0IGNoYW5nZSBkZXRlY3Rpb24gbWVjaGFuaXNtLlxyXG4gICAgICAgICAgICB0aGlzLmRyYWdQcm9ncmVzc1N1YmplY3QubmV4dCh7Z3V0dGVyTnVtOiB0aGlzLmN1cnJlbnRHdXR0ZXJOdW0sIHNpemVzfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnN0b3BEcmFnZ2luZygpO1xyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7IERpcmVjdGl2ZSwgSW5wdXQsIEVsZW1lbnRSZWYsIFJlbmRlcmVyMiwgT25Jbml0LCBPbkRlc3Ryb3ksIE5nWm9uZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuaW1wb3J0IHsgU3BsaXRDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnQvc3BsaXQuY29tcG9uZW50JztcclxuaW1wb3J0IHsgZ2V0SW5wdXRCb29sZWFuIH0gZnJvbSAnLi4vdXRpbHMnO1xyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgICBzZWxlY3RvcjogJ2FzLXNwbGl0LWFyZWEsIFthcy1zcGxpdC1hcmVhXSdcclxufSlcclxuZXhwb3J0IGNsYXNzIFNwbGl0QXJlYURpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuXHJcbiAgICBwcml2YXRlIF9vcmRlcjogbnVtYmVyIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gICAgQElucHV0KCkgc2V0IG9yZGVyKHY6IG51bWJlciB8IG51bGwpIHtcclxuICAgICAgICB2ID0gTnVtYmVyKHYpO1xyXG4gICAgICAgIHRoaXMuX29yZGVyID0gIWlzTmFOKHYpID8gdiA6IG51bGw7XHJcblxyXG4gICAgICAgIHRoaXMuc3BsaXQudXBkYXRlQXJlYSh0aGlzLCB0cnVlLCBmYWxzZSk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGdldCBvcmRlcigpOiBudW1iZXIgfCBudWxsIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fb3JkZXI7XHJcbiAgICB9XHJcblxyXG4gICAgLy8vL1xyXG5cclxuICAgIHByaXZhdGUgX3NpemU6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG5cclxuICAgIEBJbnB1dCgpIHNldCBzaXplKHY6IG51bWJlciB8IG51bGwpIHtcclxuICAgICAgICB2ID0gTnVtYmVyKHYpO1xyXG4gICAgICAgIHRoaXMuX3NpemUgPSAoIWlzTmFOKHYpICYmIHYgPj0gMCAmJiB2IDw9IDEwMCkgPyAodi8xMDApIDogbnVsbDtcclxuXHJcbiAgICAgICAgdGhpcy5zcGxpdC51cGRhdGVBcmVhKHRoaXMsIGZhbHNlLCB0cnVlKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgZ2V0IHNpemUoKTogbnVtYmVyIHwgbnVsbCB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpemU7XHJcbiAgICB9XHJcblxyXG4gICAgLy8vL1xyXG5cclxuICAgIHByaXZhdGUgX3Zpc2libGU6IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICAgIEBJbnB1dCgpIHNldCB2aXNpYmxlKHY6IGJvb2xlYW4pIHtcclxuICAgICAgICB0aGlzLl92aXNpYmxlID0gZ2V0SW5wdXRCb29sZWFuKHYpO1xyXG5cclxuICAgICAgICBpZih0aGlzLl92aXNpYmxlKSB7IFxyXG4gICAgICAgICAgICB0aGlzLnNwbGl0LnNob3dBcmVhKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudCwgJ2lzLWhpZGVkJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnNwbGl0LmhpZGVBcmVhKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudCwgJ2lzLWhpZGVkJyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCB2aXNpYmxlKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl92aXNpYmxlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vLy9cclxuXHJcbiAgICBwcml2YXRlIHRyYW5zaXRpb25MaXN0ZW5lcjogRnVuY3Rpb247XHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGxvY2tMaXN0ZW5lcnM6IEFycmF5PEZ1bmN0aW9uPiA9IFtdO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXHJcbiAgICAgICAgICAgICAgICBwdWJsaWMgZWxSZWY6IEVsZW1lbnRSZWYsXHJcbiAgICAgICAgICAgICAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXHJcbiAgICAgICAgICAgICAgICBwcml2YXRlIHNwbGl0OiBTcGxpdENvbXBvbmVudCkge1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50LCAnYXMtc3BsaXQtYXJlYScpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnNwbGl0LmFkZEFyZWEodGhpcyk7XHJcblxyXG4gICAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy50cmFuc2l0aW9uTGlzdGVuZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbih0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQsICd0cmFuc2l0aW9uZW5kJywgKGV2ZW50OiBUcmFuc2l0aW9uRXZlbnQpID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIExpbWl0IG9ubHkgZmxleC1iYXNpcyB0cmFuc2l0aW9uIHRvIHRyaWdnZXIgdGhlIGV2ZW50XHJcbiAgICAgICAgICAgICAgICBpZihldmVudC5wcm9wZXJ0eU5hbWUgPT09ICdmbGV4LWJhc2lzJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3BsaXQubm90aWZ5KCd0cmFuc2l0aW9uRW5kJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzZXRTdHlsZU9yZGVyKHZhbHVlOiBudW1iZXIpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudCwgJ29yZGVyJywgdmFsdWUpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBwdWJsaWMgc2V0U3R5bGVGbGV4YmFzaXModmFsdWU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50LCAnZmxleC1iYXNpcycsIHZhbHVlKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgcHVibGljIGxvY2tFdmVudHMoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmxvY2tMaXN0ZW5lcnMucHVzaCggdGhpcy5yZW5kZXJlci5saXN0ZW4odGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50LCAnc2VsZWN0c3RhcnQnLCAoZTogRXZlbnQpID0+IGZhbHNlKSApO1xyXG4gICAgICAgICAgICB0aGlzLmxvY2tMaXN0ZW5lcnMucHVzaCggdGhpcy5yZW5kZXJlci5saXN0ZW4odGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50LCAnZHJhZ3N0YXJ0JywgKGU6IEV2ZW50KSA9PiBmYWxzZSkgKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgdW5sb2NrRXZlbnRzKCk6IHZvaWQge1xyXG4gICAgICAgIHdoaWxlKHRoaXMubG9ja0xpc3RlbmVycy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGZjdCA9IHRoaXMubG9ja0xpc3RlbmVycy5wb3AoKTtcclxuICAgICAgICAgICAgaWYoZmN0KSB7XHJcbiAgICAgICAgICAgICAgICBmY3QoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy51bmxvY2tFdmVudHMoKTtcclxuXHJcbiAgICAgICAgaWYodGhpcy50cmFuc2l0aW9uTGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgdGhpcy50cmFuc2l0aW9uTGlzdGVuZXIoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuc3BsaXQucmVtb3ZlQXJlYSh0aGlzKTtcclxuICAgIH1cclxufVxyXG4iLCJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEV2ZW50TWFuYWdlciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xyXG5cclxuLyoqXHJcbiAqIENyZWRpdCB0byBNaWNoYWVsIFN0cm9iZWwgZnJvbTpcclxuICogaHR0cHM6Ly9naXRodWIuY29tL2tyeW9wcy9uZzItZXZlbnRzXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBVbmRldGVjdGVkRXZlbnRQbHVnaW4ge1xyXG4gICAgbWFuYWdlcjogRXZlbnRNYW5hZ2VyO1xyXG5cclxuICAgIHN1cHBvcnRzKGV2ZW50TmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIGV2ZW50TmFtZS5pbmRleE9mKCdhcy1zcGxpdC11bmRldGVjdGVkLicpID09PSAwO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZEV2ZW50TGlzdGVuZXIoZWxlbWVudDogSFRNTEVsZW1lbnQsIGV2ZW50TmFtZTogc3RyaW5nLCBoYW5kbGVyOiBGdW5jdGlvbik6IEZ1bmN0aW9uIHtcclxuICAgICAgICBjb25zdCByZWFsRXZlbnROYW1lID0gZXZlbnROYW1lLnNsaWNlKDIwKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuYWdlci5nZXRab25lKCkucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4gdGhpcy5tYW5hZ2VyLmFkZEV2ZW50TGlzdGVuZXIoZWxlbWVudCwgcmVhbEV2ZW50TmFtZSwgaGFuZGxlcikpO1xyXG4gICAgfVxyXG59IiwiaW1wb3J0IHsgTmdNb2R1bGUsIE1vZHVsZVdpdGhQcm92aWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgRVZFTlRfTUFOQUdFUl9QTFVHSU5TIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XHJcblxyXG5pbXBvcnQgeyBTcGxpdENvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50L3NwbGl0LmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IFNwbGl0QXJlYURpcmVjdGl2ZSB9IGZyb20gJy4vZGlyZWN0aXZlL3NwbGl0QXJlYS5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBVbmRldGVjdGVkRXZlbnRQbHVnaW4gfSBmcm9tIFwiLi9zZXJ2aWNlL1VuZGV0ZWN0ZWRFdmVudFBsdWdpblwiO1xyXG5cclxuQE5nTW9kdWxlKHtcclxuICAgIGltcG9ydHM6IFtcclxuICAgICAgICBDb21tb25Nb2R1bGVcclxuICAgIF0sXHJcbiAgICBkZWNsYXJhdGlvbnM6IFtcclxuICAgICAgICBTcGxpdENvbXBvbmVudCxcclxuICAgICAgICBTcGxpdEFyZWFEaXJlY3RpdmUsXHJcbiAgICBdLFxyXG4gICAgZXhwb3J0czogW1xyXG4gICAgICAgIFNwbGl0Q29tcG9uZW50LFxyXG4gICAgICAgIFNwbGl0QXJlYURpcmVjdGl2ZSxcclxuICAgIF1cclxufSlcclxuZXhwb3J0IGNsYXNzIEFuZ3VsYXJTcGxpdE1vZHVsZSB7XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBmb3JSb290KCk6IE1vZHVsZVdpdGhQcm92aWRlcnMge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIG5nTW9kdWxlOiBBbmd1bGFyU3BsaXRNb2R1bGUsXHJcbiAgICAgICAgICAgIHByb3ZpZGVyczogW3tcclxuICAgICAgICAgICAgICAgIHByb3ZpZGU6IEVWRU5UX01BTkFHRVJfUExVR0lOUyxcclxuICAgICAgICAgICAgICAgIHVzZUNsYXNzOiBVbmRldGVjdGVkRXZlbnRQbHVnaW4sXHJcbiAgICAgICAgICAgICAgICBtdWx0aTogdHJ1ZVxyXG4gICAgICAgICAgICB9XVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBmb3JDaGlsZCgpOiBNb2R1bGVXaXRoUHJvdmlkZXJzIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBuZ01vZHVsZTogQW5ndWxhclNwbGl0TW9kdWxlLFxyXG4gICAgICAgICAgICBwcm92aWRlcnM6IFtdXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbn1cclxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBS0EsU0FBZ0IsaUJBQWlCLENBQUMsS0FBOEI7O0lBRTVELElBQUcsb0JBQWMsS0FBSyxJQUFFLE9BQU8sS0FBSyxTQUFTLElBQUksb0JBQWMsS0FBSyxJQUFFLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ3RGLE9BQU87WUFDSCxDQUFDLEVBQUUsb0JBQWMsS0FBSyxJQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPO1lBQzFDLENBQUMsRUFBRSxvQkFBYyxLQUFLLElBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU87U0FDN0MsQ0FBQztLQUNMOztTQUVJLElBQUcsb0JBQWMsS0FBSyxJQUFFLE9BQU8sS0FBSyxTQUFTLElBQUksb0JBQWMsS0FBSyxJQUFFLE9BQU8sS0FBSyxTQUFTLEVBQUU7UUFDOUYsT0FBTztZQUNILENBQUMsRUFBRSxvQkFBYyxLQUFLLElBQUUsT0FBTztZQUMvQixDQUFDLEVBQUUsb0JBQWMsS0FBSyxJQUFFLE9BQU87U0FDbEMsQ0FBQztLQUNMO0lBQ0QsT0FBTyxJQUFJLENBQUM7Q0FDZjs7Ozs7O0FBRUQsU0FBZ0IsWUFBWSxDQUFDLEtBQWlCLEVBQUUsU0FBb0M7SUFDaEYsT0FBTyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUMsU0FBUyxLQUFLLFlBQVksSUFBSSxhQUFhLEdBQUcsY0FBYyxDQUFDLENBQUM7Q0FFN0Y7Ozs7O0FBRUQsU0FBZ0IsZUFBZSxDQUFDLENBQU07SUFDbEMsT0FBTyxDQUFDLFFBQU8sQ0FBQyxDQUFDLEtBQUssU0FBUyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssT0FBTyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQztDQUN6RTs7Ozs7QUFFRCxTQUFnQixnQkFBZ0IsQ0FBQyxLQUFhO0lBQzFDLE9BQU8sS0FBSyxHQUFHLElBQUksSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDO0NBQ3hDOzs7Ozs7QUNsQ0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE0REEsTUFBYSxjQUFjOzs7Ozs7O0lBNkh2QixZQUFvQixNQUFjLEVBQ2QsS0FBaUIsRUFDakIsS0FBd0IsRUFDeEIsUUFBbUI7UUFIbkIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFVBQUssR0FBTCxLQUFLLENBQVk7UUFDakIsVUFBSyxHQUFMLEtBQUssQ0FBbUI7UUFDeEIsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQTlIL0IsZUFBVSxHQUE4QixZQUFZLENBQUM7O1FBaUJyRCxnQkFBVyxHQUFXLEVBQUUsQ0FBQzs7UUFlekIsbUJBQWMsR0FBWSxLQUFLLENBQUM7O1FBZWhDLGNBQVMsR0FBWSxLQUFLLENBQUM7O1FBZTNCLFNBQUksR0FBa0IsS0FBSyxDQUFDO1FBcUM1Qix3QkFBbUIsR0FBdUQsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUNoRyxrQkFBYSxHQUEwRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsWUFBWSxFQUFFLENBQUM7O1FBSXZHLGVBQVUsR0FBWSxLQUFLLENBQUM7UUFDNUIscUJBQWdCLEdBQVcsQ0FBQyxDQUFDO1FBQzdCLGVBQVUsR0FBa0IsSUFBSSxDQUFDO1FBQ2pDLGFBQVEsR0FBa0IsSUFBSSxDQUFDO1FBRXZCLG1CQUFjLEdBQWlCLEVBQUUsQ0FBQztRQUNqQyxlQUFVLEdBQWlCLEVBQUUsQ0FBQztRQUU5QixrQkFBYSxHQUFvQixFQUFFLENBQUM7UUFDcEMsb0JBQWUsR0FBRztZQUMvQixrQkFBa0IsRUFBRSxDQUFDO1lBQ3JCLFVBQVUsRUFBRSxDQUFDO1lBQ2IsVUFBVSxFQUFFLENBQUM7WUFDYixZQUFZLEVBQUUsQ0FBQztZQUNmLFlBQVksRUFBRSxDQUFDO1NBQ2xCLENBQUM7O1FBU0UsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO0tBQ3BDOzs7OztJQS9IRCxJQUFhLFNBQVMsQ0FBQyxDQUE0QjtRQUMvQyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQyxLQUFLLFVBQVUsSUFBSSxVQUFVLEdBQUcsWUFBWSxDQUFDO1FBRWpFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLE1BQU8sSUFBSSxDQUFDLFVBQVcsRUFBRSxDQUFDLENBQUM7UUFDNUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsTUFBTyxDQUFDLElBQUksQ0FBQyxVQUFVLEtBQUssVUFBVSxJQUFJLFlBQVksR0FBRyxVQUFXLEVBQUUsQ0FBQyxDQUFDO1FBRTVILElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0tBQzVCOzs7O0lBRUQsSUFBSSxTQUFTO1FBQ1QsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0tBQzFCOzs7OztJQU1ELElBQWEsVUFBVSxDQUFDLENBQVM7UUFDN0IsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNkLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFakQsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7S0FDNUI7Ozs7SUFFRCxJQUFJLFVBQVU7UUFDVixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7S0FDM0I7Ozs7O0lBTUQsSUFBYSxhQUFhLENBQUMsQ0FBVTtRQUNqQyxJQUFJLENBQUMsY0FBYyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV6QyxJQUFHLElBQUksQ0FBQyxjQUFjO1lBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsZUFBZSxDQUFDLENBQUM7O1lBQ2xFLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLGVBQWUsQ0FBQyxDQUFDO0tBQ2hHOzs7O0lBRUQsSUFBSSxhQUFhO1FBQ2IsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDO0tBQzlCOzs7OztJQU1ELElBQWEsUUFBUSxDQUFDLENBQVU7UUFDNUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFcEMsSUFBRyxJQUFJLENBQUMsU0FBUztZQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDOztZQUNoRSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxhQUFhLENBQUMsQ0FBQztLQUMxRjs7OztJQUVELElBQUksUUFBUTtRQUNSLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztLQUN6Qjs7Ozs7SUFNRCxJQUFhLEdBQUcsQ0FBQyxDQUFnQjtRQUM3QixDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssS0FBSyxJQUFJLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbEMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7UUFFZCxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQzFFOzs7O0lBRUQsSUFBSSxHQUFHO1FBQ0gsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDO0tBQ3BCOzs7O0lBS0QsSUFBYyxTQUFTO1FBQ25CLE9BQU8sSUFBSSxVQUFVLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxVQUFVLENBQUMsQ0FBQztLQUM5RTs7OztJQUdELElBQWMsT0FBTztRQUNqQixPQUFPLElBQUksVUFBVSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsVUFBVSxDQUFDLENBQUM7S0FDNUU7Ozs7SUFHRCxJQUFjLFdBQVc7UUFDckIsT0FBTyxJQUFJLFVBQVUsQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLHFCQUFxQixHQUFHLFVBQVUsQ0FBQyxDQUFDO0tBQ2hGOzs7O0lBR0QsSUFBYyxhQUFhO1FBQ3ZCLE9BQU8sSUFBSSxVQUFVLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQy9FLFlBQVksQ0FBZ0IsRUFBRSxDQUFDLENBQ2xDLENBQUM7S0FDTDs7OztJQWtDTSxlQUFlO1FBQ2xCLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUM7O1lBRTFCLFVBQVUsQ0FBQyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7U0FDakYsQ0FBQyxDQUFDO0tBQ047Ozs7SUFFTyxZQUFZO1FBQ2hCLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztLQUNsRjs7Ozs7SUFFTSxPQUFPLENBQUMsU0FBNkI7O2NBQ2xDLE9BQU8sR0FBVTtZQUNuQixTQUFTO1lBQ1QsS0FBSyxFQUFFLENBQUM7WUFDUixJQUFJLEVBQUUsQ0FBQztTQUNWO1FBRUQsSUFBRyxTQUFTLENBQUMsT0FBTyxLQUFLLElBQUksRUFBRTtZQUMzQixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUVsQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztTQUMxQjthQUNJO1lBQ0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDakM7S0FDSjs7Ozs7SUFFTSxVQUFVLENBQUMsU0FBNkI7UUFDM0MsSUFBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsRUFBRTs7a0JBQ25ELElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUM7WUFDckUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFakUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7U0FDMUI7YUFDSSxJQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQyxFQUFFOztrQkFDcEQsSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQztZQUNqRSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUM1RDtLQUNKOzs7Ozs7O0lBRU0sVUFBVSxDQUFDLFNBQTZCLEVBQUUsV0FBb0IsRUFBRSxVQUFtQjs7O2NBRWhGLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUM7UUFDckUsSUFBRyxDQUFDLElBQUksRUFBRTtZQUNOLE9BQU87U0FDVjtRQUVELElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0tBQ3ZDOzs7OztJQUVNLFFBQVEsQ0FBQyxTQUE2Qjs7Y0FDbkMsSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQztRQUNqRSxJQUFHLENBQUMsSUFBSSxFQUFFO1lBQ04sT0FBTztTQUNWOztjQUVLLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDdEUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQztRQUVuQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztLQUMxQjs7Ozs7SUFFTSxRQUFRLENBQUMsSUFBd0I7O2NBQzlCLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsS0FBSyxJQUFJLENBQUM7UUFDaEUsSUFBRyxDQUFDLElBQUksRUFBRTtZQUNOLE9BQU87U0FDVjs7Y0FFSyxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzlFLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSTtZQUNkLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1lBQ2YsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7U0FDakIsQ0FBQyxDQUFBO1FBQ0YsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQztRQUUvQixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztLQUMxQjs7OztJQUVNLG1CQUFtQjtRQUN0QixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO0tBQ3JEOzs7OztJQUVNLG1CQUFtQixDQUFDLEtBQW9CO1FBQzNDLElBQUcsS0FBSyxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRTtZQUM1QyxPQUFPLEtBQUssQ0FBQztTQUNoQjtRQUVELEtBQUssR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7O2NBRTFCLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBYSxFQUFFLENBQVMsS0FBSyxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN0RSxJQUFHLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDekIsT0FBTyxLQUFLLENBQUM7U0FDaEI7UUFFRCxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDOztZQUVoQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDbkMsQ0FBQyxDQUFBO1FBRUYsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDeEIsT0FBTyxJQUFJLENBQUM7S0FDZjs7Ozs7O0lBRU8sS0FBSyxDQUFDLFdBQW9CLEVBQUUsVUFBbUI7UUFDbkQsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDOztRQUlwQixJQUFHLFdBQVcsS0FBSyxJQUFJLEVBQUU7O1lBR3JCLElBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxFQUFFO2dCQUMzRCxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssb0JBQVUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLDBCQUFjLENBQUMsQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFDLENBQUMsQ0FBQzthQUNuRzs7WUFHRCxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNoQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ25CLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUM1QyxDQUFDLENBQUM7U0FFTjs7UUFJRCxJQUFHLFVBQVUsS0FBSyxJQUFJLEVBQUU7O2tCQUVkLGFBQWEsc0JBQVksSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFhLEVBQUUsQ0FBUSxLQUFLLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLEtBQUssR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQUE7O1lBRzlJLElBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxFQUFHO2dCQUU5RixJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJO29CQUM1QixJQUFJLENBQUMsSUFBSSxzQkFBWSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBQSxDQUFDO2lCQUM1QyxDQUFDLENBQUM7YUFDTjs7aUJBRUk7O3NCQUNLLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNO2dCQUUzQyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJO29CQUM1QixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztpQkFDcEIsQ0FBQyxDQUFDO2FBQ047U0FDSjs7Ozs7WUFNRyxpQkFBaUIsR0FBRyxDQUFDOzs7Y0FHbkIsa0JBQWtCLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUVuRSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJO1lBQzVCLElBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFO2dCQUNqRCxpQkFBaUIsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUMvQixJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQzthQUNqQjtTQUNKLENBQUMsQ0FBQztRQUVILElBQUcsaUJBQWlCLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTs7a0JBQ2xELGNBQWMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNO1lBRTNFLElBQUcsY0FBYyxHQUFHLENBQUMsRUFBRTs7c0JBQ2IsWUFBWSxHQUFHLGlCQUFpQixHQUFHLGNBQWM7Z0JBRXZELElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJO29CQUN0RCxJQUFJLENBQUMsSUFBSSxJQUFJLFlBQVksQ0FBQztpQkFDN0IsQ0FBQyxDQUFDO2FBQ047OztpQkFHSTtnQkFDRCxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7YUFDaEU7U0FDSjtRQUVELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLENBQUM7S0FDN0I7Ozs7SUFFTyxpQkFBaUI7O2NBQ2YsYUFBYSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsR0FBRyxJQUFJLENBQUMsVUFBVTtRQUUzRCxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJO1lBQzVCLElBQUksQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUMsU0FBVSxJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUksT0FBUSxJQUFJLENBQUMsSUFBSSxHQUFHLGFBQWMsTUFBTSxDQUFDLENBQUM7U0FDeEcsQ0FBQyxDQUFDO0tBQ047Ozs7OztJQUVNLFdBQVcsQ0FBQyxLQUFpQixFQUFFLFNBQWlCO1FBQ25ELEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN2QixLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFeEIsSUFBRyxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDLE9BQU8sRUFBRTtZQUM5RixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsU0FBUyxDQUFDO1lBRWxDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDeEI7S0FDSjs7Ozs7OztJQUVNLGFBQWEsQ0FBQyxLQUE4QixFQUFFLFdBQW1CLEVBQUUsU0FBaUI7UUFDdkYsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUV4QixJQUFJLENBQUMsVUFBVSxHQUFHLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLElBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDbEMsT0FBTztTQUNWOztjQUVLLEtBQUssR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssS0FBSyxXQUFXLEdBQUcsQ0FBQyxDQUFDOztjQUNsRSxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEtBQUssV0FBVyxHQUFHLENBQUMsQ0FBQztRQUV4RSxJQUFHLENBQUMsS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ2pCLE9BQU87U0FDVjtRQUVELElBQUksQ0FBQyxlQUFlLENBQUMsa0JBQWtCLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ25GLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdEYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN0RixJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO1FBQy9DLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7UUFDL0MsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFNBQVMsQ0FBQztRQUVsQyxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDO1lBQzFCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBRSxDQUFDO1lBQ3JHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBRSxDQUFDO1lBQ3RHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxhQUFhLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBRSxDQUFDO1lBRXpHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFhLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUUsQ0FBQztZQUM3SCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBYSxLQUFLLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFFLENBQUM7U0FDaEksQ0FBQyxDQUFDO1FBRUgsS0FBSyxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM3QixLQUFLLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBRTdCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixHQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUV0RyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0tBQ3hCOzs7Ozs7O0lBRU8sU0FBUyxDQUFDLEtBQThCLEVBQUUsS0FBWSxFQUFFLEtBQVk7UUFDeEUsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUV4QixJQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNqQixPQUFPO1NBQ1Y7UUFFRCxJQUFJLENBQUMsUUFBUSxHQUFHLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3pDLElBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2YsT0FBTztTQUNWOzs7WUFJRyxXQUFXLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxLQUFLLFlBQVksS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNuSSxJQUFHLElBQUksQ0FBQyxHQUFHLEtBQUssS0FBSyxFQUFFO1lBQ25CLFdBQVcsR0FBRyxDQUFDLFdBQVcsQ0FBQztTQUM5Qjs7WUFFRyxhQUFhLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEdBQUcsV0FBVzs7WUFDN0QsYUFBYSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxHQUFHLFdBQVc7UUFFakUsSUFBRyxhQUFhLEdBQUcsSUFBSSxDQUFDLFVBQVUsSUFBSSxhQUFhLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRTs7WUFFbkUsT0FBTztTQUNWO2FBQ0ksSUFBRyxhQUFhLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNyQyxhQUFhLElBQUksYUFBYSxDQUFDO1lBQy9CLGFBQWEsR0FBRyxDQUFDLENBQUM7U0FDckI7YUFDSSxJQUFHLGFBQWEsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ3JDLGFBQWEsSUFBSSxhQUFhLENBQUM7WUFDL0IsYUFBYSxHQUFHLENBQUMsQ0FBQztTQUNyQjs7UUFJRCxJQUFHLGFBQWEsS0FBSyxDQUFDLEVBQUU7WUFDcEIsS0FBSyxDQUFDLElBQUksSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDO1lBQ3pCLEtBQUssQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO1NBQ2xCO2FBQ0ksSUFBRyxhQUFhLEtBQUssQ0FBQyxFQUFFO1lBQ3pCLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQztZQUN6QixLQUFLLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztTQUNsQjthQUNJOztZQUVELElBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEtBQUssQ0FBQyxFQUFFO2dCQUN4QyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxHQUFHLGFBQWEsQ0FBQztnQkFDakcsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO2FBQy9EO2lCQUNJLElBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEtBQUssQ0FBQyxFQUFFO2dCQUM3QyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxHQUFHLGFBQWEsQ0FBQztnQkFDakcsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO2FBQy9EO2lCQUNJO2dCQUNELEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEdBQUcsYUFBYSxDQUFDO2dCQUNqRyxLQUFLLENBQUMsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQzthQUNyRztTQUNKO1FBRUQsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7O1FBR3pCLElBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUU7WUFDL0UsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUMzQjtLQUNKOzs7OztJQUVPLFlBQVksQ0FBQyxLQUFhO1FBQzlCLElBQUcsS0FBSyxFQUFFO1lBQ04sS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3ZCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztTQUMzQjtRQUVELElBQUcsSUFBSSxDQUFDLFVBQVUsS0FBSyxLQUFLLEVBQUU7WUFDMUIsT0FBTztTQUNWO1FBRUQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSTtZQUM1QixJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDO1NBQ2pDLENBQUMsQ0FBQztRQUVILE9BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFOztrQkFDM0IsR0FBRyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFO1lBQ3BDLElBQUcsR0FBRyxFQUFFO2dCQUNKLEdBQUcsRUFBRSxDQUFDO2FBQ1Q7U0FDSjs7UUFHRCxJQUFHLEtBQUssSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDM0csSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN0QjtRQUVELElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQ25FLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixHQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsRUFBRSxZQUFZLENBQUMsQ0FBQzs7UUFHekcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztZQUMxQixVQUFVLENBQUM7Z0JBQ1AsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO2FBQ3hCLENBQUMsQ0FBQTtTQUNMLENBQUMsQ0FBQztLQUNOOzs7OztJQUVNLE1BQU0sQ0FBQyxJQUE4RDs7Y0FDbEUsS0FBSyxHQUFrQixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUM7UUFFdkUsSUFBRyxJQUFJLEtBQUssT0FBTyxFQUFFO1lBQ2pCLElBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFO2dCQUN6QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsRUFBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEtBQUssRUFBQyxDQUFDLENBQUMsQ0FBQzthQUNuRztTQUNKO2FBQ0ksSUFBRyxJQUFJLEtBQUssS0FBSyxFQUFFO1lBQ3BCLElBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFO2dCQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEtBQUssRUFBQyxDQUFDLENBQUMsQ0FBQzthQUNqRztTQUNKO2FBQ0ksSUFBRyxJQUFJLEtBQUssT0FBTyxFQUFFO1lBQ3RCLElBQUcsSUFBSSxDQUFDLHFCQUFxQixFQUFFO2dCQUMzQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsRUFBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEtBQUssRUFBQyxDQUFDLENBQUMsQ0FBQzthQUNyRztTQUNKO2FBQ0ksSUFBRyxJQUFJLEtBQUssZUFBZSxFQUFFO1lBQzlCLElBQUcsSUFBSSxDQUFDLHVCQUF1QixFQUFFO2dCQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQzthQUNuRTtTQUNKO2FBQ0ksSUFBRyxJQUFJLEtBQUssVUFBVSxFQUFFOztZQUV6QixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEVBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDO1NBQzVFO0tBQ0o7Ozs7SUFFTSxXQUFXO1FBQ2QsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0tBQ3ZCOzs7WUF6aEJKLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsVUFBVTtnQkFDcEIsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07Z0JBRS9DLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozt1QkFhUzs7YUFDdEI7Ozs7WUEzRCtILE1BQU07WUFBbEIsVUFBVTtZQUFsRSxpQkFBaUI7WUFBRSxTQUFTOzs7d0JBZ0VuRixLQUFLO3lCQWlCTCxLQUFLOzRCQWVMLEtBQUs7dUJBZUwsS0FBSztrQkFlTCxLQUFLO3dCQWNMLE1BQU07c0JBS04sTUFBTTswQkFLTixNQUFNOzRCQUtOLE1BQU07d0JBNEJOLFlBQVksU0FBQyxXQUFXOzs7Ozs7O0FDdkw3QixNQVFhLGtCQUFrQjs7Ozs7OztJQXdEM0IsWUFBb0IsTUFBYyxFQUNmLEtBQWlCLEVBQ2hCLFFBQW1CLEVBQ25CLEtBQXFCO1FBSHJCLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZixVQUFLLEdBQUwsS0FBSyxDQUFZO1FBQ2hCLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsVUFBSyxHQUFMLEtBQUssQ0FBZ0I7UUF6RGpDLFdBQU0sR0FBa0IsSUFBSSxDQUFDOztRQWU3QixVQUFLLEdBQWtCLElBQUksQ0FBQzs7UUFlNUIsYUFBUSxHQUFZLElBQUksQ0FBQztRQXNCaEIsa0JBQWEsR0FBb0IsRUFBRSxDQUFDO1FBTWpELElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLGVBQWUsQ0FBQyxDQUFDO0tBQ3JFOzs7OztJQXpERCxJQUFhLEtBQUssQ0FBQyxDQUFnQjtRQUMvQixDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBRW5DLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7S0FDNUM7Ozs7SUFFRCxJQUFJLEtBQUs7UUFDTCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7S0FDdEI7Ozs7O0lBTUQsSUFBYSxJQUFJLENBQUMsQ0FBZ0I7UUFDOUIsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNkLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFDLEdBQUcsSUFBSSxJQUFJLENBQUM7UUFFaEUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztLQUM1Qzs7OztJQUVELElBQUksSUFBSTtRQUNKLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztLQUNyQjs7Ozs7SUFNRCxJQUFhLE9BQU8sQ0FBQyxDQUFVO1FBQzNCLElBQUksQ0FBQyxRQUFRLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRW5DLElBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNkLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzFCLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1NBQ25FO2FBQ0k7WUFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMxQixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxVQUFVLENBQUMsQ0FBQztTQUNoRTtLQUNKOzs7O0lBRUQsSUFBSSxPQUFPO1FBQ1AsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0tBQ3hCOzs7O0lBY00sUUFBUTtRQUNYLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXpCLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUM7WUFDMUIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLGVBQWUsRUFBRSxDQUFDLEtBQXNCOztnQkFFN0csSUFBRyxLQUFLLENBQUMsWUFBWSxLQUFLLFlBQVksRUFBRTtvQkFDcEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7aUJBQ3RDO2FBQ0osQ0FBQyxDQUFDO1NBQ04sQ0FBQyxDQUFDO0tBQ047Ozs7O0lBRU0sYUFBYSxDQUFDLEtBQWE7UUFDOUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO0tBQ3BFOzs7OztJQUVNLGlCQUFpQixDQUFDLEtBQWE7UUFDbEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO0tBQ3pFOzs7O0lBRU0sVUFBVTtRQUNiLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUM7WUFDMUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBUSxLQUFLLEtBQUssQ0FBQyxDQUFFLENBQUM7WUFDOUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBUSxLQUFLLEtBQUssQ0FBQyxDQUFFLENBQUM7U0FDL0csQ0FBQyxDQUFDO0tBQ047Ozs7SUFFTSxZQUFZO1FBQ2YsT0FBTSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7O2tCQUMzQixHQUFHLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUU7WUFDcEMsSUFBRyxHQUFHLEVBQUU7Z0JBQ0osR0FBRyxFQUFFLENBQUM7YUFDVDtTQUNKO0tBQ0o7Ozs7SUFFTSxXQUFXO1FBQ2QsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXBCLElBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQ3hCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1NBQzdCO1FBRUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDL0I7OztZQS9HSixTQUFTLFNBQUM7Z0JBQ1AsUUFBUSxFQUFFLGdDQUFnQzthQUM3Qzs7OztZQVBvRSxNQUFNO1lBQWhELFVBQVU7WUFBRSxTQUFTO1lBRXZDLGNBQWM7OztvQkFVbEIsS0FBSzttQkFlTCxLQUFLO3NCQWVMLEtBQUs7Ozs7Ozs7QUMxQ1Y7Ozs7QUFRQSxNQUFhLHFCQUFxQjs7Ozs7SUFHOUIsUUFBUSxDQUFDLFNBQWlCO1FBQ3RCLE9BQU8sU0FBUyxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUMxRDs7Ozs7OztJQUVELGdCQUFnQixDQUFDLE9BQW9CLEVBQUUsU0FBaUIsRUFBRSxPQUFpQjs7Y0FDakUsYUFBYSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBRXpDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0tBQ3pIOzs7WUFaSixVQUFVOzs7Ozs7O0FDUFgsTUFxQmEsa0JBQWtCOzs7O0lBRXBCLE9BQU8sT0FBTztRQUNqQixPQUFPO1lBQ0gsUUFBUSxFQUFFLGtCQUFrQjtZQUM1QixTQUFTLEVBQUUsQ0FBQztvQkFDUixPQUFPLEVBQUUscUJBQXFCO29CQUM5QixRQUFRLEVBQUUscUJBQXFCO29CQUMvQixLQUFLLEVBQUUsSUFBSTtpQkFDZCxDQUFDO1NBQ0wsQ0FBQztLQUNMOzs7O0lBRU0sT0FBTyxRQUFRO1FBQ2xCLE9BQU87WUFDSCxRQUFRLEVBQUUsa0JBQWtCO1lBQzVCLFNBQVMsRUFBRSxFQUFFO1NBQ2hCLENBQUM7S0FDTDs7O1lBL0JKLFFBQVEsU0FBQztnQkFDTixPQUFPLEVBQUU7b0JBQ0wsWUFBWTtpQkFDZjtnQkFDRCxZQUFZLEVBQUU7b0JBQ1YsY0FBYztvQkFDZCxrQkFBa0I7aUJBQ3JCO2dCQUNELE9BQU8sRUFBRTtvQkFDTCxjQUFjO29CQUNkLGtCQUFrQjtpQkFDckI7YUFDSjs7Ozs7Ozs7Ozs7Ozs7OyJ9
\No newline at end of file