UNPKG

@duoduo-oba/ng-devui

Version:

DevUI components based on Angular

771 lines 82.5 kB
/** * @fileoverview added by tsickle * Generated from: directives/draggable.directive.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Subscription, fromEvent, Subject } from 'rxjs'; import { Directive, ElementRef, EventEmitter, HostBinding, Input, NgZone, Output, Renderer2, Self, Optional } from '@angular/core'; import { DragDropService } from '../services/drag-drop.service'; import { Utils } from '../shared/utils'; import { PreserveNextEventEmitter } from './../shared/preserve-next-event-emitter'; import { DragPreviewDirective } from './drag-preview.directive'; /** * Makes an element draggable by adding the draggable html attribute */ export class DraggableDirective { /** * @param {?} el * @param {?} renderer * @param {?} dragDropService * @param {?} ngZone * @param {?} dragPreviewDirective */ constructor(el, renderer, dragDropService, ngZone, dragPreviewDirective) { this.el = el; this.renderer = renderer; this.dragDropService = dragDropService; this.ngZone = ngZone; this.dragPreviewDirective = dragPreviewDirective; this.draggable = true; /** * Currently not used */ this.dragEffect = 'move'; /** * Defines compatible drag drop pairs. Values must match both in draggable and droppable.dropScope. */ this.dragScope = 'default'; this.dragHandleClass = 'drag-handle'; /** * Event fired when Drag is started */ this.dragStartEvent = new EventEmitter(); /** * @deprecated * Event fired while the element is being dragged * 为了性能优化,该函数废弃,请用(drag)自行监听, 如果不需要angular脏检测则最好用runOutsideAngular的addEventListener监听以获得好的性能 */ this.dragEvent = new PreserveNextEventEmitter(); /** * Event fired when dragged ends */ this.dragEndEvent = new EventEmitter(); this.dropEndEvent = new PreserveNextEventEmitter(); this.enableDragFollow = false; // 默认false使用浏览器H5API拖拽, 否则使用原dom定位偏移 // 用于虚拟滚动的恢复 this.dragItemParentName = ''; // 当前拖拽元素的类名或元素名称(类名需要加.),主要用于子节点的截取操作 // 当前拖拽元素的类名或元素名称(类名需要加.),主要用于子节点的截取操作 this.dragItemChildrenName = ''; // 当前拖拽元素的子节点类名或元素名称(类名需要加.) // 当前拖拽元素的子节点类名或元素名称(类名需要加.) this.dragsSub = new Subscription(); this.destroyDragEndSub = new Subscription(); this.dragElShowHideEvent = new Subject(); this.beforeDragStartEvent = new Subject(); this.insertOriginPlaceholder = (/** * @param {?=} directShow * @param {?=} updateService * @return {?} */ (directShow = true, updateService = true) => { if (this.delayRemoveOriginPlaceholderTimer) { clearTimeout(this.delayRemoveOriginPlaceholderTimer); this.delayRemoveOriginPlaceholderTimer = undefined; } /** @type {?} */ const node = document.createElement(this.originPlaceholder.tag || 'div'); /** @type {?} */ const rect = this.el.nativeElement.getBoundingClientRect(); if (directShow) { node.style.display = 'block'; } else { node.style.display = 'none'; } node.style.width = rect.width + 'px'; node.style.height = rect.height + 'px'; node.classList.add('drag-origin-placeholder'); if (this.originPlaceholder.text) { node.innerText = this.originPlaceholder.text; } if (this.originPlaceholder.style) { Utils.addElStyles(node, this.originPlaceholder.style); } if (updateService) { this.dragDropService.dragOriginPlaceholder = node; this.dragDropService.dragOriginPlaceholderNextSibling = this.el.nativeElement.nextSibling; } else { node.classList.add('side-drag-origin-placeholder'); /** @type {?} */ const originCloneNode = this.el.nativeElement.cloneNode(true); originCloneNode.style.margin = 0; originCloneNode.style.pointerEvents = 'none'; originCloneNode.style.opacity = '0.3'; node.appendChild(originCloneNode); } this.dragOriginPlaceholder = node; this.dragOriginPlaceholderNextSibling = this.el.nativeElement.nextSibling; this.el.nativeElement.parentElement.insertBefore(node, this.el.nativeElement.nextSibling); }); this.removeOriginPlaceholder = (/** * @param {?=} updateService * @return {?} */ (updateService = true) => { if (this.dragOriginPlaceholder) { this.dragOriginPlaceholder.parentElement.removeChild(this.dragOriginPlaceholder); } if (updateService) { this.dragDropService.dragOriginPlaceholder = undefined; this.dragDropService.dragOriginPlaceholderNextSibling = undefined; } this.dragOriginPlaceholder = undefined; this.dragOriginPlaceholderNextSibling = undefined; }); this.delayRemoveOriginPlaceholder = (/** * @param {?=} updateService * @return {?} */ (updateService = true) => { /** @type {?} */ const timeout = this.originPlaceholder.removeDelay; /** @type {?} */ const delayOriginPlaceholder = this.dragOriginPlaceholder; /** @type {?} */ const dragOriginPlaceholderNextSibling = this.findNextSibling(this.dragOriginPlaceholderNextSibling); // 需要临时移动位置,保证被ngFor刷新之后位置是正确的 // ngFor刷新的原理是有变化的部分都刷新,夹在变化部分中间的内容将被刷到变化部分之后的位置,所以需要恢复位置 // setTimeout是等ngFor的View刷新, 后续需要订阅sortContainer的view的更新才需要重新恢复位置 if (delayOriginPlaceholder.parentElement.contains(dragOriginPlaceholderNextSibling)) { delayOriginPlaceholder.parentElement.insertBefore(delayOriginPlaceholder, dragOriginPlaceholderNextSibling); } setTimeout((/** * @return {?} */ () => { if (delayOriginPlaceholder.parentElement.contains(dragOriginPlaceholderNextSibling)) { delayOriginPlaceholder.parentElement.insertBefore(delayOriginPlaceholder, dragOriginPlaceholderNextSibling); } delayOriginPlaceholder.classList.add('delay-deletion'); this.delayRemoveOriginPlaceholderTimer = setTimeout((/** * @return {?} */ () => { delayOriginPlaceholder.parentElement.removeChild(delayOriginPlaceholder); if (document.body.contains(this.el.nativeElement)) { this.el.nativeElement.style.display = ''; this.dragDropService.dragElShowHideEvent.next(false); } }), timeout); if (updateService) { this.dragDropService.dragOriginPlaceholder = undefined; this.dragDropService.dragOriginPlaceholderNextSibling = undefined; } this.dragOriginPlaceholder = undefined; this.dragOriginPlaceholderNextSibling = undefined; })); }); } /** * @return {?} */ get disabled() { return this._disabled; } /** * @param {?} value * @return {?} */ set disabled(value) { this._disabled = value; this.draggable = !this._disabled; } /** * @return {?} */ ngOnInit() { this.ngZone.runOutsideAngular((/** * @return {?} */ () => { this.dragsSub.add(fromEvent(this.el.nativeElement, 'mouseover').subscribe((/** * @param {?} event * @return {?} */ event => this.mouseover(event)))); this.dragsSub.add(fromEvent(this.el.nativeElement, 'dragstart').subscribe((/** * @param {?} event * @return {?} */ event => this.dragStart(event)))); this.dragsSub.add(fromEvent(this.el.nativeElement, 'dragend').subscribe((/** * @param {?} event * @return {?} */ event => this.dragEnd(event)))); })); } /** * @return {?} */ dropSubscription() { this.dragDropService.newSubscription().add(this.dragDropService.dropEvent.subscribe((/** * @param {?} event * @return {?} */ (event) => { this.mouseOverElement = undefined; this.renderer.removeClass(this.el.nativeElement, this.dragOverClass); this.dropEndEvent.emit(event); // 兼容虚拟滚动后被销毁 if (this.isDestroyed) { if (this.dropEndEvent.schedulerFns && this.dropEndEvent.schedulerFns.size > 0) { this.dropEndEvent.forceCallback(event, true); } } if (this.dragDropService.dragOriginPlaceholder) { if (this.originPlaceholder && this.originPlaceholder.removeDelay > 0 && !this.dragDropService.dropOnOrigin) { // 非drop到自己的情况 this.delayRemoveOriginPlaceholder(); } else { this.removeOriginPlaceholder(); } this.dragDropService.draggedElIdentity = undefined; } this.dragDropService.subscription.unsubscribe(); }))).add(this.dragDropService.dragElShowHideEvent.subscribe(this.dragElShowHideEvent)); } /** * @return {?} */ ngAfterViewInit() { this.applyDragHandleClass(); if (this.dragIdentity) { if (this.dragDropService.draggedEl && this.dragIdentity === this.dragDropService.draggedElIdentity) { if (this.originPlaceholder && this.originPlaceholder.show !== false) { this.insertOriginPlaceholder(); } this.dragDropService.draggedEl = this.el.nativeElement; this.el.nativeElement.style.display = 'none'; // recovery don't need to emit event } } } /** * @return {?} */ ngOnDestroy() { // 兼容虚拟滚动后被销毁 this.isDestroyed = true; if (this.dragDropService.draggedEl === this.el.nativeElement) { this.destroyDragEndSub = new Subscription(); this.destroyDragEndSub.add(fromEvent(this.el.nativeElement, 'dragend').subscribe((/** * @param {?} event * @return {?} */ event => { this.dragEnd(event); if (this.dropEndEvent.schedulerFns && this.dropEndEvent.schedulerFns.size > 0) { this.dropEndEvent.forceCallback(event, true); } this.destroyDragEndSub.unsubscribe(); this.destroyDragEndSub = undefined; }))); if (this.originPlaceholder && this.originPlaceholder.show !== false && this.dragDropService.dragOriginPlaceholder && this.dragDropService.draggedElIdentity) { // 如果有originPlaceholder 则销毁 this.removeOriginPlaceholder(); } } this.dragsSub.unsubscribe(); } /** * @param {?} e * @return {?} */ dragStart(e) { if (this.allowDrag(e)) { this.renderer.addClass(this.el.nativeElement, this.dragOverClass); this.dragDropService.dragData = this.dragData; this.dragDropService.scope = this.dragScope; this.dragDropService.draggedEl = this.el.nativeElement; this.dragDropService.draggedElIdentity = this.dragIdentity; this.dragDropService.dragFollow = this.enableDragFollow; this.dragDropService.dragFollowOptions = this.dragFollowOptions; this.dragDropService.dragItemParentName = this.dragItemParentName; this.dragDropService.dragItemChildrenName = this.dragItemChildrenName; this.beforeDragStartEvent.next(); if (this.dragPreviewDirective && this.dragPreviewDirective.dragPreviewTemplate) { this.dragDropService.dragFollow = true; this.dragDropService.dragPreviewDirective = this.dragPreviewDirective; } if (this.batchDraggable) { if (this.batchDraggable.dragData) { // 有dragData证明被加入到了group里 if (this.dragDropService.batchDragData && this.dragDropService.batchDragData.length > 1) { this.dragDropService.batchDragging = true; this.dragDropService.batchDragStyle = this.batchDraggable.batchDragStyle; } } else if (this.batchDraggable.batchDragLastOneAutoActiveEventKeys) { /** @type {?} */ const batchActiveAble = this.batchDraggable.batchDragLastOneAutoActiveEventKeys .map((/** * @param {?} key * @return {?} */ key => e[key])) .some((/** * @param {?} eventKey * @return {?} */ eventKey => eventKey === true)); if (batchActiveAble) { if (this.dragDropService.batchDragData && this.dragDropService.batchDragData.length > 0) { this.batchDraggable.active(); if (!this.batchDraggable.dragData) { // 如果用户没做任何处理把项目加到组里则加到组里 this.batchDraggable.addToBatchGroup(); } if (this.dragDropService.batchDragData.some((/** * @param {?} dragData * @return {?} */ dragData => dragData.draggable === this))) { this.dragDropService.batchDragging = true; this.dragDropService.batchDragStyle = this.batchDraggable.batchDragStyle; } } } } } /** @type {?} */ const targetOffset = this.el.nativeElement.getBoundingClientRect(); if (this.dragDropService.dragFollow) { /** @type {?} */ const mousePositionXY = this.mousePosition(e); // 用于出现transform的场景position:fixed相对位置变更 /** @type {?} */ const transformOffset = this.checkAndGetViewPointChange(this.el.nativeElement); this.dragDropService.dragOffset = { left: targetOffset.left, top: targetOffset.top, offsetLeft: mousePositionXY.x - targetOffset.left + transformOffset.offsetX, offsetTop: mousePositionXY.y - targetOffset.top + transformOffset.offsetY, width: targetOffset.width, height: targetOffset.height }; this.dragDropService.enableDraggedCloneNodeFollowMouse(); } else { this.dragDropService.dragOffset = { left: targetOffset.left, top: targetOffset.top, offsetLeft: null, offsetTop: null, width: targetOffset.width, height: targetOffset.height }; } if (this.originPlaceholder && this.originPlaceholder.show !== false) { this.insertOriginPlaceholder(false); } if (this.dragDropService.batchDragging && this.dragDropService.batchDragData && this.dragDropService.batchDragData.length > 1) { this.dragDropService.batchDragData.map((/** * @param {?} dragData * @return {?} */ dragData => dragData.draggable)) .filter((/** * @param {?} draggable * @return {?} */ draggable => draggable && draggable !== this)) .forEach((/** * @param {?} draggable * @return {?} */ (draggable) => { if (draggable.originPlaceholder && draggable.originPlaceholder.show !== false) { draggable.insertOriginPlaceholder(true, false); draggable.el.nativeElement.style.display = 'none'; } else { setTimeout((/** * @return {?} */ () => { draggable.el.nativeElement.style.display = 'none'; })); } })); } // Firefox requires setData() to be called otherwise the drag does not work. if (e.dataTransfer != null) { e.dataTransfer.setData('text', ''); } e.dataTransfer.effectAllowed = this.dragEffect; this.dropSubscription(); if (this.dragDropService.dragFollow) { if ('function' === typeof DataTransfer.prototype.setDragImage) { e.dataTransfer.setDragImage(this.dragDropService.dragEmptyImage, 0, 0); } else { e.srcElement.style.display = 'none'; this.dragDropService.dragElShowHideEvent.next(false); } } e.stopPropagation(); this.dragStartEvent.emit(e); this.dragDropService.dragStartEvent.next(e); } else { e.preventDefault(); } } /** * @param {?} e * @return {?} */ dragEnd(e) { this.renderer.removeClass(this.el.nativeElement, this.dragOverClass); this.dragDropService.dragEndEvent.next(e); this.mouseOverElement = undefined; if (this.dragDropService.draggedEl) { // 当dom被清除的的时候不会触发dragend,所以清理工作部分交给了drop,但是内部排序的时候dom不会被清理,dragend防止和drop重复操作清理动作 if (this.dragDropService.dragFollow) { this.dragDropService.disableDraggedCloneNodeFollowMouse(); } if (this.dragDropService.dragOriginPlaceholder) { this.removeOriginPlaceholder(); } if (this.dragDropService.batchDragging && this.dragDropService.batchDragData && this.dragDropService.batchDragData.length > 1) { this.dragDropService.batchDragData.map((/** * @param {?} dragData * @return {?} */ dragData => dragData.draggable)) .filter((/** * @param {?} draggable * @return {?} */ draggable => draggable && draggable !== this)) .forEach((/** * @param {?} draggable * @return {?} */ (draggable) => { if (draggable.originPlaceholder && draggable.originPlaceholder.show !== false) { draggable.el.nativeElement.style.display = ''; draggable.removeOriginPlaceholder(); } else { draggable.el.nativeElement.style.display = ''; } })); } if (this.batchDraggable && !this.batchDraggable.batchDragActive) { this.batchDraggable.removeFromBatchGroup(); this.dragDropService.batchDragging = false; this.dragDropService.batchDragStyle = undefined; } if (this.dragDropService.subscription) { this.dragDropService.subscription.unsubscribe(); } this.dragDropService.dragData = undefined; this.dragDropService.scope = undefined; this.dragDropService.draggedEl = undefined; this.dragDropService.dragFollow = undefined; this.dragDropService.dragFollowOptions = undefined; this.dragDropService.dragOffset = undefined; this.dragDropService.draggedElIdentity = undefined; this.dragDropService.dragPreviewDirective = undefined; } e.stopPropagation(); e.preventDefault(); this.dragEndEvent.emit(e); } /** * @param {?} e * @return {?} */ mouseover(e) { this.mouseOverElement = e.target; } /** * @private * @param {?} e * @return {?} */ allowDrag(e) { if (!this.draggable) { return false; } if (this.batchDraggable && !this.batchDraggable.allowAddToBatchGroup()) { // 批量拖拽判断group是否相同 return false; } if (this.dragHandle) { if (e && e.fromTouch) { return true; } // from touchstart dispatch event if (!this.mouseOverElement) { return false; } return Utils.matches(this.mouseOverElement, this.dragHandle); } else { return true; } } /** * @private * @return {?} */ applyDragHandleClass() { /** @type {?} */ const dragElement = this.getDragHandleElement(); if (!dragElement) { return; } if (this.draggable) { Utils.addClass(dragElement, this.dragHandleClass); } else { Utils.removeClass(this.el, this.dragHandleClass); } } /** * @private * @return {?} */ getDragHandleElement() { /** @type {?} */ let dragElement = this.el; if (this.dragHandle) { dragElement = this.el.nativeElement.querySelector(this.dragHandle); } return dragElement; } /** * @private * @param {?} event * @return {?} */ mousePosition(event) { return { x: event.clientX, y: event.clientY }; } /** * @param {?} currentNextSibling * @return {?} */ findNextSibling(currentNextSibling) { if (!this.dragDropService.batchDragData) { return currentNextSibling; } else { if (this.dragDropService.batchDragData .map((/** * @param {?} dragData * @return {?} */ dragData => dragData.draggable && dragData.draggable.el.nativeElement)) .indexOf(currentNextSibling) > -1) { currentNextSibling = currentNextSibling.nextSibling; } return currentNextSibling; } } /** * @private * @param {?} element * @return {?} */ checkAndGetViewPointChange(element) { if (!element.parentNode) { return null; } // 模拟一个元素测预测位置和最终位置是否符合,如果不符合则是有transform等造成的偏移 /** @type {?} */ const elementPosition = element.getBoundingClientRect(); /** @type {?} */ const testEl = document.createElement('div'); Utils.addElStyles(testEl, { opacity: '0', position: 'fixed', top: elementPosition.top + 'px', left: elementPosition.left + 'px', width: '1px', height: '1px', zIndex: '-999999', }); element.parentNode.appendChild(testEl); /** @type {?} */ const testElPosition = testEl.getBoundingClientRect(); element.parentNode.removeChild(testEl); return { offsetX: testElPosition.left - elementPosition.left, offsetY: testElPosition.top - elementPosition.top }; } } DraggableDirective.decorators = [ { type: Directive, args: [{ selector: '[dDraggable]' },] } ]; /** @nocollapse */ DraggableDirective.ctorParameters = () => [ { type: ElementRef }, { type: Renderer2 }, { type: DragDropService }, { type: NgZone }, { type: DragPreviewDirective, decorators: [{ type: Optional }, { type: Self }] } ]; DraggableDirective.propDecorators = { draggable: [{ type: HostBinding, args: ['draggable',] }], dragData: [{ type: Input }], dragHandle: [{ type: HostBinding, args: ['attr.data-drag-handle-selector',] }, { type: Input }], dragEffect: [{ type: Input }], dragScope: [{ type: Input }], dragHandleClass: [{ type: Input }], dragOverClass: [{ type: Input }], dragStartEvent: [{ type: Output }], dragEvent: [{ type: Output }], dragEndEvent: [{ type: Output }], dropEndEvent: [{ type: Output }], disabled: [{ type: Input }], enableDragFollow: [{ type: Input }], dragFollowOptions: [{ type: Input }], originPlaceholder: [{ type: Input }], dragIdentity: [{ type: Input }], dragItemParentName: [{ type: Input }], dragItemChildrenName: [{ type: Input }] }; if (false) { /** @type {?} */ DraggableDirective.prototype.draggable; /** * The data that will be available to the droppable directive on its `onDrop()` event. * @type {?} */ DraggableDirective.prototype.dragData; /** * The selector that defines the drag Handle. If defined drag will only be allowed if dragged from the selector element. * @type {?} */ DraggableDirective.prototype.dragHandle; /** * Currently not used * @type {?} */ DraggableDirective.prototype.dragEffect; /** * Defines compatible drag drop pairs. Values must match both in draggable and droppable.dropScope. * @type {?} */ DraggableDirective.prototype.dragScope; /** @type {?} */ DraggableDirective.prototype.dragHandleClass; /** * CSS class applied on the draggable that is applied when the item is being dragged. * @type {?} */ DraggableDirective.prototype.dragOverClass; /** * Event fired when Drag is started * @type {?} */ DraggableDirective.prototype.dragStartEvent; /** * @deprecated * Event fired while the element is being dragged * 为了性能优化,该函数废弃,请用(drag)自行监听, 如果不需要angular脏检测则最好用runOutsideAngular的addEventListener监听以获得好的性能 * @type {?} */ DraggableDirective.prototype.dragEvent; /** * Event fired when dragged ends * @type {?} */ DraggableDirective.prototype.dragEndEvent; /** * Keeps track of mouse over element that is used to determine drag handles * @type {?} * @private */ DraggableDirective.prototype.mouseOverElement; /** @type {?} */ DraggableDirective.prototype.dropEndEvent; /** * @type {?} * @private */ DraggableDirective.prototype._disabled; /** @type {?} */ DraggableDirective.prototype.enableDragFollow; /** @type {?} */ DraggableDirective.prototype.dragFollowOptions; /** @type {?} */ DraggableDirective.prototype.originPlaceholder; /** @type {?} */ DraggableDirective.prototype.dragIdentity; /** @type {?} */ DraggableDirective.prototype.dragItemParentName; /** @type {?} */ DraggableDirective.prototype.dragItemChildrenName; /** @type {?} */ DraggableDirective.prototype.dragsSub; /** @type {?} */ DraggableDirective.prototype.destroyDragEndSub; /** @type {?} */ DraggableDirective.prototype.isDestroyed; /** * @type {?} * @private */ DraggableDirective.prototype.delayRemoveOriginPlaceholderTimer; /** @type {?} */ DraggableDirective.prototype.batchDraggable; /** * @type {?} * @private */ DraggableDirective.prototype.dragOriginPlaceholder; /** * @type {?} * @private */ DraggableDirective.prototype.dragOriginPlaceholderNextSibling; /** @type {?} */ DraggableDirective.prototype.dragElShowHideEvent; /** @type {?} */ DraggableDirective.prototype.beforeDragStartEvent; /** @type {?} */ DraggableDirective.prototype.insertOriginPlaceholder; /** @type {?} */ DraggableDirective.prototype.removeOriginPlaceholder; /** @type {?} */ DraggableDirective.prototype.delayRemoveOriginPlaceholder; /** @type {?} */ DraggableDirective.prototype.el; /** * @type {?} * @private */ DraggableDirective.prototype.renderer; /** * @type {?} * @private */ DraggableDirective.prototype.dragDropService; /** * @type {?} * @private */ DraggableDirective.prototype.ngZone; /** @type {?} */ DraggableDirective.prototype.dragPreviewDirective; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZ2dhYmxlLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLWRldnVpL2RyYWdkcm9wLyIsInNvdXJjZXMiOlsiZGlyZWN0aXZlcy9kcmFnZ2FibGUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3hELE9BQU8sRUFBaUIsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUN0RSxLQUFLLEVBQUUsTUFBTSxFQUFxQixNQUFNLEVBQUUsU0FBUyxFQUFRLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkcsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNuRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUtoRTs7R0FFRztBQUNILE1BQU0sT0FBTyxrQkFBa0I7Ozs7Ozs7O0lBeUY3QixZQUFtQixFQUFjLEVBQVUsUUFBbUIsRUFBVSxlQUFnQyxFQUFVLE1BQWMsRUFDbkcsb0JBQTBDO1FBRHBELE9BQUUsR0FBRixFQUFFLENBQVk7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQVUsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQVUsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNuRyx5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXNCO1FBekY3QyxjQUFTLEdBQUcsSUFBSSxDQUFDOzs7O1FBZWxDLGVBQVUsR0FBRyxNQUFNLENBQUM7Ozs7UUFLcEIsY0FBUyxHQUEyQixTQUFTLENBQUM7UUFFOUMsb0JBQWUsR0FBRyxhQUFhLENBQUM7Ozs7UUFTL0IsbUJBQWMsR0FB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