{"version":3,"file":"580.638e7c6ec00de585.js","mappings":"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","names":["extendStyles","dest","source","importantProperties","key","hasOwnProperty","value","setProperty","has","removeProperty","toggleNativeDragInteractions","element","enable","userSelect","style","toggleVisibility","position","top","opacity","left","combineTransforms","transform","initialTransform","parseCssTimeUnitsToMs","multiplier","toLowerCase","indexOf","parseFloat","parseCssPropertyValue","computedStyle","name","getPropertyValue","split","map","part","trim","getMutableClientRect","clientRect","getBoundingClientRect","right","bottom","width","height","x","y","isInsideClientRect","adjustClientRect","isPointerNearClientRect","rect","threshold","pointerX","pointerY","xThreshold","yThreshold","ParentPositionTracker","constructor","_document","this","positions","Map","clear","cache","elements","set","scrollPosition","getViewportScrollPosition","forEach","scrollTop","scrollLeft","handleScroll","event","target","_getEventTarget","cachedPosition","get","newTop","newLeft","viewportScrollPosition","topDifference","leftDifference","node","contains","window","scrollY","scrollX","deepCloneNode","clone","cloneNode","descendantsWithId","querySelectorAll","nodeName","removeAttribute","i","length","transferCanvasData","transferInputData","transferData","selector","callback","descendantElements","cloneElements","cloneUniqueId","type","context","getContext","drawImage","passiveEventListenerOptions","normalizePassiveListenerOptions","passive","activeEventListenerOptions","dragImportantProperties","Set","DragRef","disabled","_disabled","_dropContainer","newValue","coerceBooleanProperty","_toggleNativeDragInteractions","_handles","handle","_config","_ngZone","_viewportRuler","_dragDropRegistry","_passiveTransform","_activeTransform","_hasStartedDragging","_moveEvents","Subject","_pointerMoveSubscription","Subscription","EMPTY","_pointerUpSubscription","_scrollSubscription","_resizeSubscription","_boundaryElement","_nativeInteractionsEnabled","_disabledHandles","_direction","dragStartDelay","beforeStarted","started","released","ended","entered","exited","dropped","moved","_pointerDown","next","targetHandle","_getTargetHandle","_initializeDragSequence","_rootElement","_pointerMove","pointerPosition","_getPointerPositionOnPage","Math","abs","_pickupPositionOnPage","dragStartThreshold","isDelayElapsed","Date","now","_dragStartTime","_getDragStartDelay","container","_endDragSequence","isDragging","isReceiving","preventDefault","run","_startDragSequence","constrainedPointerPosition","_getConstrainedPointerPosition","_hasMoved","_lastKnownPointerPosition","_updatePointerDirectionDelta","_updateActiveDropContainer","offset","constrainPosition","_initialClientRect","activeTransform","_applyRootElementTransform","observers","distance","_getDragDistance","delta","_pointerDirectionDelta","_pointerUp","_nativeDragStart","withRootElement","withParent","parentDragRef","_parentPositions","registerDragItem","getPlaceholderElement","_placeholder","getRootElement","getVisibleElement","withHandles","handles","coerceElement","disabledHandles","add","withPreviewTemplate","template","_previewTemplate","withPlaceholderTemplate","_placeholderTemplate","rootElement","_removeRootElementListeners","runOutsideAngular","addEventListener","_initialTransform","undefined","SVGElement","_ownerSVGElement","ownerSVGElement","withBoundaryElement","boundaryElement","unsubscribe","change","subscribe","_containInsideBoundaryOnResize","parent","_parentDragRef","dispose","remove","_anchor","_destroyPreview","_destroyPlaceholder","removeDragItem","_removeSubscriptions","complete","reset","disableHandle","enableHandle","delete","withDirection","direction","_withDropContainer","getFreeDragPosition","setFreeDragPosition","withPreviewContainer","_previewContainer","_sortFromLastPointerPosition","_preview","_previewRef","destroy","_placeholderRef","stopDragging","webkitTapHighlightColor","_rootElementTapHighlight","_stopScrolling","_animatePreviewToPlaceholder","then","_cleanupDragArtifacts","_cleanupCachedDimensions","dropPoint","isTouchEvent","_lastTouchEventTime","dropContainer","parentNode","placeholder","_createPlaceholderElement","anchor","createComment","shadowRoot","_getShadowRoot","insertBefore","_createPreviewElement","body","appendChild","replaceChild","_getPreviewInsertionPoint","start","_initialContainer","_initialIndex","getItemIndex","getScrollableParents","referenceElement","stopPropagation","isTouchSequence","isAuxiliaryMouseButton","button","isSyntheticEvent","isFakeEvent","isFakeTouchstartFromScreenReader","touch","touches","changedTouches","identifier","radiusX","radiusY","isFakeMousedownFromScreenReader","buttons","offsetX","offsetY","draggable","rootStyles","pointerMove","pointerUp","scrolled","scrollEvent","_updateOnScroll","_boundaryRect","previewTemplate","_pickupPositionInElement","matchSize","_getPointerPositionInElement","_pointerPositionAtLastDirectionChange","startDragging","_previewRect","currentIndex","isPointerOverContainer","_isOverContainer","item","previousIndex","previousContainer","drop","rawX","rawY","newContainer","_getSiblingContainerFromPosition","exit","enter","sortingDisabled","_startScrollingIfNecessary","_sortItem","_applyPreviewTransform","previewConfig","previewClass","preview","rootRect","viewRef","viewContainer","createEmbeddedView","detectChanges","getRootNode","matchElementSize","getTransform","margin","zIndex","classList","setAttribute","Array","isArray","className","Promise","resolve","placeholderRect","duration","getTransformTransitionDurationInMs","getComputedStyle","transitionedProperties","property","find","prop","propertyIndex","rawDurations","rawDelays","handler","propertyName","removeEventListener","clearTimeout","timeout","setTimeout","placeholderConfig","placeholderTemplate","pointerEvents","elementRect","handleElement","referenceRect","point","targetTouches","_getViewportScrollPosition","pageX","pageY","svgMatrix","getScreenCTM","svgPoint","createSVGPoint","matrixTransform","inverse","dropContainerLock","lockAxis","pickupX","pickupY","boundaryRect","previewWidth","previewHeight","_getPreviewRect","minY","maxY","clamp$1","pointerPositionOnPage","positionSinceLastChange","changeX","changeY","pointerDirectionChangeThreshold","shouldEnable","styles","currentPosition","pickupPosition","leftOverflow","rightOverflow","topOverflow","bottomOverflow","mouse","scrollDifference","_cachedShadowRoot","initialParent","previewContainer","documentRef","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","round","min","max","rootNodes","nodeType","ELEMENT_NODE","wrapper","createElement","sourceRect","moveItemInArray","array","fromIndex","toIndex","from","clamp","to","SingleAxisSortStrategy","_element","_itemPositions","orientation","_previousSwap","drag","overlaps","items","withItems","sort","pointerDelta","siblings","newIndex","_getItemIndexFromPointerPosition","isHorizontal","findIndex","currentItem","siblingAtNewPosition","newPosition","itemOffset","_getItemOffsetPx","siblingOffset","_getSiblingOffsetPx","oldOrder","slice","sibling","index","isDraggedItem","elementToOffset","activeDraggables","_activeDraggables","newPositionReference","_shouldEnterAsFirstChild","splice","parentElement","push","_cacheItemPositions","withSortPredicate","predicate","_sortPredicate","p","getActiveItemsSnapshot","reverse","updateOnScroll","elementToMeasure","a","b","immediateSibling","end","itemPositions","lastItemRect","firstItemRect","floor","DropListRef","autoScrollDisabled","autoScrollStep","enterPredicate","sortPredicate","sorted","receivingStarted","receivingStopped","_isDragging","_draggables","_siblings","_activeSiblings","_viewportScrollSubscription","_verticalScrollDirection","_horizontalScrollDirection","_stopScrollTimers","_startScrollInterval","interval","period","scheduler","asyncScheduler","timer","animationFrameScheduler","pipe","takeUntil","_scrollNode","scrollStep","scrollBy","withScrollableParents","registerDropContainer","_sortStrategy","removeDropContainer","_draggingStarted","_notifyReceivingSiblings","_cacheParentPositions","_reset","previousItems","filter","every","connectedTo","withOrientation","_scrollableElements","size","_clientRect","result","scrollNode","verticalScrollDirection","horizontalScrollDirection","getElementScrollDirections","computedVertical","getVerticalScrollDirection","computedHorizontal","getHorizontalScrollDirection","scrollHeight","clientHeight","scrollWidth","clientWidth","getViewportSize","_initialScrollSnap","msScrollSnapType","scrollSnapType","_listenToScrollEvents","_stopReceiving","_canReceive","elementFromPoint","nativeElement","_startReceiving","activeSiblings","initiator","receiver","draggedItems","activeCapturingEventOptions","capture","DragDropRegistry","_dropInstances","_dragInstances","_activeDragInstances","_globalListeners","_draggingPredicate","scroll","_preventDefaultWhileDragging","_persistentTouchmoveListener","some","startsWith","e","options","config","_clearGlobalListeners","streams","Observable","observer","eventOptions","merge","ngOnDestroy","instance","ɵfac","t","i0","DOCUMENT","ɵprov","token","factory","providedIn","DEFAULT_CONFIG","DragDrop","createDrag","createDropList","i1","CDK_DRAG_PARENT","InjectionToken","CDK_DRAG_HANDLE","CdkDragHandle","_stateChanges","parentDrag","_parentDrag","ɵdir","selectors","hostAttrs","inputs","standalone","features","provide","useExisting","CDK_DRAG_PLACEHOLDER","CDK_DRAG_PREVIEW","CDK_DRAG_CONFIG","CDK_DROP_LIST","CdkDrag","_dragRef","_viewContainerRef","_dir","dragDrop","_changeDetectorRef","_selfHandle","_destroyed","EventEmitter","subscription","movedEvent","data","_assignDefaults","_dropListRef","addItem","_syncInputs","_handleEvents","ngAfterViewInit","onStable","take","_updateRootElement","_setupHandlesListener","freeDragPosition","ngOnChanges","changes","rootSelectorChange","rootElementSelector","positionChange","firstChange","removeItem","closest","_getBoundaryElement","boundary","ref","dir","templateRef","coerceNumberProperty","startEvent","emit","markForCheck","releaseEvent","endEvent","enterEvent","exitEvent","dropEvent","draggingDisabled","startWith","tap","childHandleElements","switchMap","handleInstance","dragRef","i1$1","contentQueries","rf","ctx","dirIndex","_t","first","hostVars","hostBindings","outputs","exportAs","CDK_DROP_LIST_GROUP","_uniqueIdCounter","CdkDropList","_group","_scrollDispatcher","id","_unsortedItems","_setupInputSyncSubscription","_dropLists","_items","_syncItemsWithRef","getSortedItems","compareDocumentPosition","Node","DOCUMENT_POSITION_FOLLOWING","coerceArray","list","_scrollableParentsResolved","scrollableParents","getAncestorScrollContainers","scrollable","getElementRef","listAutoScrollDisabled","listOrientation","useValue","DragDropModule","ɵmod","ɵinj","providers","imports","CdkScrollableModule","_r13","item_r7","$implicit","ctx_r11","updateIndex","order","ctx_r14","i_r8","ctx_r9","_r19","ctx_r18","ctx_r17","t_r1","DraggableOrderedListComponent_ng_container_0_ng_container_1_div_4_input_6_Template","DraggableOrderedListComponent_ng_container_0_ng_container_1_div_4_button_8_Template","ctx_r6","accessibilityMode","itemTemplate","_c1","showRemoveButton","DraggableOrderedListComponent_ng_container_0_ng_container_1_div_4_Template","ctx_r2","BufferAmount","parentScroll","_r5","viewPortItems","trackByIdentity","_r31","ctx_r30","i_r25","item_r24","ctx_r29","ctx_r33","ctx_r32","ctx_r26","_r38","ctx_r37","ctx_r36","DraggableOrderedListComponent_ng_container_0_ng_template_2_div_1_div_3_Template","DraggableOrderedListComponent_ng_container_0_ng_template_2_div_1_i_4_Template","DraggableOrderedListComponent_ng_container_0_ng_template_2_div_1_button_6_Template","ctx_r23","$event","_r42","ctx_r41","DraggableOrderedListComponent_ng_container_0_ng_template_2_div_1_Template","ctx_r4","DraggableOrderedListComponent_ng_container_0_ng_container_1_Template","DraggableOrderedListComponent_ng_container_0_ng_template_2_Template","ctx_r0","_r3","DraggableOrderedListComponent","cdRef","title","orderUpdated","itemRemove","fromPosition","toPosition","inputElem","document","querySelector","parseInt","core","Xpm","DraggableOrderedListComponent_ng_container_0_Template","NgIf","VirtualScrollerModule","NgFor","NgTemplateOutlet","TranslocoDirective","changeDetection","ctx_r3","pagesRead","pagesTotal","ctx_r7","seriesFormat","formatString_r6","ReadingListItemComponent_ng_container_0_ng_container_22_i_1_Template","MangaFormat","UNKNOWN","ctx_r5","releaseDate","ReadingListItemComponent_ng_container_0_ng_container_4_Template","ReadingListItemComponent_ng_container_0_div_5_Template","_r10","readChapter","ReadingListItemComponent_ng_container_0_ng_container_22_Template","ReadingListItemComponent_ng_container_0_div_26_Template","imageService","getChapterCoverImage","chapterId","libraryId","seriesId","seriesName","ReadingListItemComponent","libraryTypes","promoted","read","decls","vars","consts","ReadingListItemComponent_ng_container_0_Template","ImageComponent","NgbProgressbar","DatePipe","MangaFormatPipe","MangaFormatIconPipe","_r8","performAction","actions","readingList","ctx_r12","updateAccessibilityMode","_r17","offcanvas_r9","dismiss","removeRead","ReadingListDetailComponent_ng_container_0_ng_template_9_div_0_div_13_Template","ctx_r10","isAdmin","ReadingListDetailComponent_ng_container_0_ng_template_9_div_0_Template","ctx_r28","startingMonth","startingYear","endingMonth","ctx_r34","endingYear","ReadingListDetailComponent_ng_container_0_div_11_div_41_ng_container_6_ng_container_1_Template","ReadingListDetailComponent_ng_container_0_div_11_div_41_ng_container_6_ng_container_2_Template","ReadingListDetailComponent_ng_container_0_div_11_div_41_ng_container_6_ng_container_3_Template","ctx_r31","ReadingListDetailComponent_ng_container_0_div_11_div_41_ng_container_2_Template","ReadingListDetailComponent_ng_container_0_div_11_div_41_ng_container_3_Template","ReadingListDetailComponent_ng_container_0_div_11_div_41_ng_container_4_Template","ReadingListDetailComponent_ng_container_0_div_11_div_41_ng_container_6_Template","ctx_r20","item_r39","goToCharacter","ReadingListDetailComponent_ng_container_0_div_11_ng_container_44_div_2_ng_template_4_Template","characters_r35","ReadingListDetailComponent_ng_container_0_div_11_ng_container_44_div_2_Template","ctx_r46","isLoading","ReadingListDetailComponent_ng_container_0_div_11_ng_template_49_app_loading_0_Template","ctx_r25","_r50","ctx_r49","position_r48","idx","ctx_r51","itemRemoved","_c0","ctx_r27","item_r47","_r53","ctx_r52","continue","ctx_r54","ctx_r55","ctx_r56","ReadingListDetailComponent_ng_container_0_div_11_div_41_Template","ReadingListDetailComponent_ng_container_0_div_11_ng_container_44_Template","ReadingListDetailComponent_ng_container_0_div_11_ng_container_48_Template","ReadingListDetailComponent_ng_container_0_div_11_ng_template_49_Template","ctx_r57","ReadingListDetailComponent_ng_container_0_div_11_ng_template_52_Template","getReadingListCoverImage","readingListSummary","characters$","_r24","ReadingListDetailComponent_ng_container_0_app_card_actionables_3_Template","ReadingListDetailComponent_ng_container_0_span_5_Template","ReadingListDetailComponent_ng_container_0_ng_template_9_Template","ReadingListDetailComponent_ng_container_0_div_11_Template","_r4","ReadingListDetailComponent","route","router","readingListService","actionService","actionFactoryService","utilityService","accountService","toastr","confirmService","libraryService","readerService","filterUtilityService","titleService","hasDownloadingRole","downloadInProgress","translocoService","inject","TranslocoService","setTitle","translate","ngOnInit","listId","snapshot","paramMap","getCharacters","forkJoin","getLibraries","getReadingList","results","lib","error","navigateByUrl","summary","replace","currentUser$","user","hasAdminRole","hasDownloadRole","getReadingListActions","handleReadingListActionCallback","bind","action","actionListFilter","getListItems","params","getQueryParamsObject","navigate","getNavigationArray","queryParams","_this","_asyncToGenerator","Action","Delete","deleteList","Edit","editReadingList","rl","_this2","confirm","success","updatePosition","deleteItem","resp","info","incognitoMode","firstItem","readingListId","currentlyReadingChapter","character","applyFilter","FilterField","Characters","FilterComparison","Contains","i2","i3","i4","i5","i6","i7","i8","i9","i10","i11","i12","i13","ReadingListDetailComponent_ng_container_0_Template","SideNavCompanionBarComponent","CardActionablesComponent","NgbDropdown","NgbDropdownToggle","NgbDropdownMenu","NgbDropdownItem","ReadMoreComponent","BadgeExpanderComponent","PersonBadgeComponent","A11yClickDirective","LoadingComponent","NgClass","AsyncPipe","DecimalPipe","pagination","totalItems","item_r8","_r11","handleClick","_r14","ctx_r13","performGlobalAction","ReadingListsComponent_ng_container_0_h6_6_Template","ReadingListsComponent_ng_container_0_ng_template_8_Template","ReadingListsComponent_ng_container_0_ng_template_10_Template","globalActions","loadingLists","lists","jumpbarKeys","ReadingListsComponent","jumpbarService","ngbModal","Import","children","requiresAdmin","importCbl","loadPage","getActions","open","ImportCblModalComponent","closed","dismissed","_","updatedList","getPage","URLSearchParams","location","search","page","currentPage","getReadingLists","readingLists","getJumpKeys","l","scrollTo","ReadingListsComponent_ng_container_0_Template","CardDetailLayoutComponent","CardItemComponent","routes","path","runGuardsAndResolvers","canActivate","AuthGuard","component","pathMatch","ReadingListRoutingModule","oAB","cJS","RouterModule","forChild","ReadingListModule","CommonModule","ReactiveFormsModule","NgbNavModule","NgbProgressbarModule","NgbTooltipModule","NgbDropdownModule","CoverImageChooserComponent","AddToListModalComponent","EditReadingListModalComponent"],"sourceRoot":"webpack:///","sources":["./node_modules/@angular/cdk/fesm2022/drag-drop.mjs","./node_modules/@angular/cdk/fesm2022/a11y.mjs","./node_modules/rxjs/dist/esm/internal/observable/interval.js","./src/app/reading-list/_components/draggable-ordered-list/draggable-ordered-list.component.html","./src/app/reading-list/_components/draggable-ordered-list/draggable-ordered-list.component.ts","./src/app/reading-list/_components/reading-list-item/reading-list-item.component.html","./src/app/reading-list/_components/reading-list-item/reading-list-item.component.ts","./src/app/reading-list/_components/reading-list-detail/reading-list-detail.component.html","./src/app/reading-list/_components/reading-list-detail/reading-list-detail.component.ts","./src/app/reading-list/_components/reading-lists/reading-lists.component.html","./src/app/reading-list/_components/reading-lists/reading-lists.component.ts","./src/app/reading-list/reading-list-routing.module.ts","./src/app/reading-list/reading-list.module.ts"],"sourcesContent":["import * as i0 from '@angular/core';\nimport { Injectable, Inject, InjectionToken, Directive, Optional, SkipSelf, Input, EventEmitter, Self, ContentChildren, ContentChild, Output, NgModule } from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport * as i1 from '@angular/cdk/scrolling';\nimport { CdkScrollableModule } from '@angular/cdk/scrolling';\nimport { _getEventTarget, normalizePassiveListenerOptions, _getShadowRoot } from '@angular/cdk/platform';\nimport { coerceBooleanProperty, coerceElement, coerceNumberProperty, coerceArray } from '@angular/cdk/coercion';\nimport { isFakeTouchstartFromScreenReader, isFakeMousedownFromScreenReader } from '@angular/cdk/a11y';\nimport { Subject, Subscription, interval, animationFrameScheduler, Observable, merge } from 'rxjs';\nimport { takeUntil, map, take, startWith, tap, switchMap } from 'rxjs/operators';\nimport * as i1$1 from '@angular/cdk/bidi';\n\n/**\n * Shallow-extends a stylesheet object with another stylesheet-like object.\n * Note that the keys in `source` have to be dash-cased.\n * @docs-private\n */\nfunction extendStyles(dest, source, importantProperties) {\n for (let key in source) {\n if (source.hasOwnProperty(key)) {\n const value = source[key];\n if (value) {\n dest.setProperty(key, value, importantProperties?.has(key) ? 'important' : '');\n }\n else {\n dest.removeProperty(key);\n }\n }\n }\n return dest;\n}\n/**\n * Toggles whether the native drag interactions should be enabled for an element.\n * @param element Element on which to toggle the drag interactions.\n * @param enable Whether the drag interactions should be enabled.\n * @docs-private\n */\nfunction toggleNativeDragInteractions(element, enable) {\n const userSelect = enable ? '' : 'none';\n extendStyles(element.style, {\n 'touch-action': enable ? '' : 'none',\n '-webkit-user-drag': enable ? '' : 'none',\n '-webkit-tap-highlight-color': enable ? '' : 'transparent',\n 'user-select': userSelect,\n '-ms-user-select': userSelect,\n '-webkit-user-select': userSelect,\n '-moz-user-select': userSelect,\n });\n}\n/**\n * Toggles whether an element is visible while preserving its dimensions.\n * @param element Element whose visibility to toggle\n * @param enable Whether the element should be visible.\n * @param importantProperties Properties to be set as `!important`.\n * @docs-private\n */\nfunction toggleVisibility(element, enable, importantProperties) {\n extendStyles(element.style, {\n position: enable ? '' : 'fixed',\n top: enable ? '' : '0',\n opacity: enable ? '' : '0',\n left: enable ? '' : '-999em',\n }, importantProperties);\n}\n/**\n * Combines a transform string with an optional other transform\n * that exited before the base transform was applied.\n */\nfunction combineTransforms(transform, initialTransform) {\n return initialTransform && initialTransform != 'none'\n ? transform + ' ' + initialTransform\n : transform;\n}\n\n/** Parses a CSS time value to milliseconds. */\nfunction parseCssTimeUnitsToMs(value) {\n // Some browsers will return it in seconds, whereas others will return milliseconds.\n const multiplier = value.toLowerCase().indexOf('ms') > -1 ? 1 : 1000;\n return parseFloat(value) * multiplier;\n}\n/** Gets the transform transition duration, including the delay, of an element in milliseconds. */\nfunction getTransformTransitionDurationInMs(element) {\n const computedStyle = getComputedStyle(element);\n const transitionedProperties = parseCssPropertyValue(computedStyle, 'transition-property');\n const property = transitionedProperties.find(prop => prop === 'transform' || prop === 'all');\n // If there's no transition for `all` or `transform`, we shouldn't do anything.\n if (!property) {\n return 0;\n }\n // Get the index of the property that we're interested in and match\n // it up to the same index in `transition-delay` and `transition-duration`.\n const propertyIndex = transitionedProperties.indexOf(property);\n const rawDurations = parseCssPropertyValue(computedStyle, 'transition-duration');\n const rawDelays = parseCssPropertyValue(computedStyle, 'transition-delay');\n return (parseCssTimeUnitsToMs(rawDurations[propertyIndex]) +\n parseCssTimeUnitsToMs(rawDelays[propertyIndex]));\n}\n/** Parses out multiple values from a computed style into an array. */\nfunction parseCssPropertyValue(computedStyle, name) {\n const value = computedStyle.getPropertyValue(name);\n return value.split(',').map(part => part.trim());\n}\n\n/** Gets a mutable version of an element's bounding `ClientRect`. */\nfunction getMutableClientRect(element) {\n const clientRect = element.getBoundingClientRect();\n // We need to clone the `clientRect` here, because all the values on it are readonly\n // and we need to be able to update them. Also we can't use a spread here, because\n // the values on a `ClientRect` aren't own properties. See:\n // https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#Notes\n return {\n top: clientRect.top,\n right: clientRect.right,\n bottom: clientRect.bottom,\n left: clientRect.left,\n width: clientRect.width,\n height: clientRect.height,\n x: clientRect.x,\n y: clientRect.y,\n };\n}\n/**\n * Checks whether some coordinates are within a `ClientRect`.\n * @param clientRect ClientRect that is being checked.\n * @param x Coordinates along the X axis.\n * @param y Coordinates along the Y axis.\n */\nfunction isInsideClientRect(clientRect, x, y) {\n const { top, bottom, left, right } = clientRect;\n return y >= top && y <= bottom && x >= left && x <= right;\n}\n/**\n * Updates the top/left positions of a `ClientRect`, as well as their bottom/right counterparts.\n * @param clientRect `ClientRect` that should be updated.\n * @param top Amount to add to the `top` position.\n * @param left Amount to add to the `left` position.\n */\nfunction adjustClientRect(clientRect, top, left) {\n clientRect.top += top;\n clientRect.bottom = clientRect.top + clientRect.height;\n clientRect.left += left;\n clientRect.right = clientRect.left + clientRect.width;\n}\n/**\n * Checks whether the pointer coordinates are close to a ClientRect.\n * @param rect ClientRect to check against.\n * @param threshold Threshold around the ClientRect.\n * @param pointerX Coordinates along the X axis.\n * @param pointerY Coordinates along the Y axis.\n */\nfunction isPointerNearClientRect(rect, threshold, pointerX, pointerY) {\n const { top, right, bottom, left, width, height } = rect;\n const xThreshold = width * threshold;\n const yThreshold = height * threshold;\n return (pointerY > top - yThreshold &&\n pointerY < bottom + yThreshold &&\n pointerX > left - xThreshold &&\n pointerX < right + xThreshold);\n}\n\n/** Keeps track of the scroll position and dimensions of the parents of an element. */\nclass ParentPositionTracker {\n constructor(_document) {\n this._document = _document;\n /** Cached positions of the scrollable parent elements. */\n this.positions = new Map();\n }\n /** Clears the cached positions. */\n clear() {\n this.positions.clear();\n }\n /** Caches the positions. Should be called at the beginning of a drag sequence. */\n cache(elements) {\n this.clear();\n this.positions.set(this._document, {\n scrollPosition: this.getViewportScrollPosition(),\n });\n elements.forEach(element => {\n this.positions.set(element, {\n scrollPosition: { top: element.scrollTop, left: element.scrollLeft },\n clientRect: getMutableClientRect(element),\n });\n });\n }\n /** Handles scrolling while a drag is taking place. */\n handleScroll(event) {\n const target = _getEventTarget(event);\n const cachedPosition = this.positions.get(target);\n if (!cachedPosition) {\n return null;\n }\n const scrollPosition = cachedPosition.scrollPosition;\n let newTop;\n let newLeft;\n if (target === this._document) {\n const viewportScrollPosition = this.getViewportScrollPosition();\n newTop = viewportScrollPosition.top;\n newLeft = viewportScrollPosition.left;\n }\n else {\n newTop = target.scrollTop;\n newLeft = target.scrollLeft;\n }\n const topDifference = scrollPosition.top - newTop;\n const leftDifference = scrollPosition.left - newLeft;\n // Go through and update the cached positions of the scroll\n // parents that are inside the element that was scrolled.\n this.positions.forEach((position, node) => {\n if (position.clientRect && target !== node && target.contains(node)) {\n adjustClientRect(position.clientRect, topDifference, leftDifference);\n }\n });\n scrollPosition.top = newTop;\n scrollPosition.left = newLeft;\n return { top: topDifference, left: leftDifference };\n }\n /**\n * Gets the scroll position of the viewport. Note that we use the scrollX and scrollY directly,\n * instead of going through the `ViewportRuler`, because the first value the ruler looks at is\n * the top/left offset of the `document.documentElement` which works for most cases, but breaks\n * if the element is offset by something like the `BlockScrollStrategy`.\n */\n getViewportScrollPosition() {\n return { top: window.scrollY, left: window.scrollX };\n }\n}\n\n/** Creates a deep clone of an element. */\nfunction deepCloneNode(node) {\n const clone = node.cloneNode(true);\n const descendantsWithId = clone.querySelectorAll('[id]');\n const nodeName = node.nodeName.toLowerCase();\n // Remove the `id` to avoid having multiple elements with the same id on the page.\n clone.removeAttribute('id');\n for (let i = 0; i < descendantsWithId.length; i++) {\n descendantsWithId[i].removeAttribute('id');\n }\n if (nodeName === 'canvas') {\n transferCanvasData(node, clone);\n }\n else if (nodeName === 'input' || nodeName === 'select' || nodeName === 'textarea') {\n transferInputData(node, clone);\n }\n transferData('canvas', node, clone, transferCanvasData);\n transferData('input, textarea, select', node, clone, transferInputData);\n return clone;\n}\n/** Matches elements between an element and its clone and allows for their data to be cloned. */\nfunction transferData(selector, node, clone, callback) {\n const descendantElements = node.querySelectorAll(selector);\n if (descendantElements.length) {\n const cloneElements = clone.querySelectorAll(selector);\n for (let i = 0; i < descendantElements.length; i++) {\n callback(descendantElements[i], cloneElements[i]);\n }\n }\n}\n// Counter for unique cloned radio button names.\nlet cloneUniqueId = 0;\n/** Transfers the data of one input element to another. */\nfunction transferInputData(source, clone) {\n // Browsers throw an error when assigning the value of a file input programmatically.\n if (clone.type !== 'file') {\n clone.value = source.value;\n }\n // Radio button `name` attributes must be unique for radio button groups\n // otherwise original radio buttons can lose their checked state\n // once the clone is inserted in the DOM.\n if (clone.type === 'radio' && clone.name) {\n clone.name = `mat-clone-${clone.name}-${cloneUniqueId++}`;\n }\n}\n/** Transfers the data of one canvas element to another. */\nfunction transferCanvasData(source, clone) {\n const context = clone.getContext('2d');\n if (context) {\n // In some cases `drawImage` can throw (e.g. if the canvas size is 0x0).\n // We can't do much about it so just ignore the error.\n try {\n context.drawImage(source, 0, 0);\n }\n catch { }\n }\n}\n\n/** Options that can be used to bind a passive event listener. */\nconst passiveEventListenerOptions = normalizePassiveListenerOptions({ passive: true });\n/** Options that can be used to bind an active event listener. */\nconst activeEventListenerOptions = normalizePassiveListenerOptions({ passive: false });\n/**\n * Time in milliseconds for which to ignore mouse events, after\n * receiving a touch event. Used to avoid doing double work for\n * touch devices where the browser fires fake mouse events, in\n * addition to touch events.\n */\nconst MOUSE_EVENT_IGNORE_TIME = 800;\n/** Inline styles to be set as `!important` while dragging. */\nconst dragImportantProperties = new Set([\n // Needs to be important, because some `mat-table` sets `position: sticky !important`. See #22781.\n 'position',\n]);\n/**\n * Reference to a draggable item. Used to manipulate or dispose of the item.\n */\nclass DragRef {\n /** Whether starting to drag this element is disabled. */\n get disabled() {\n return this._disabled || !!(this._dropContainer && this._dropContainer.disabled);\n }\n set disabled(value) {\n const newValue = coerceBooleanProperty(value);\n if (newValue !== this._disabled) {\n this._disabled = newValue;\n this._toggleNativeDragInteractions();\n this._handles.forEach(handle => toggleNativeDragInteractions(handle, newValue));\n }\n }\n constructor(element, _config, _document, _ngZone, _viewportRuler, _dragDropRegistry) {\n this._config = _config;\n this._document = _document;\n this._ngZone = _ngZone;\n this._viewportRuler = _viewportRuler;\n this._dragDropRegistry = _dragDropRegistry;\n /**\n * CSS `transform` applied to the element when it isn't being dragged. We need a\n * passive transform in order for the dragged element to retain its new position\n * after the user has stopped dragging and because we need to know the relative\n * position in case they start dragging again. This corresponds to `element.style.transform`.\n */\n this._passiveTransform = { x: 0, y: 0 };\n /** CSS `transform` that is applied to the element while it's being dragged. */\n this._activeTransform = { x: 0, y: 0 };\n /**\n * Whether the dragging sequence has been started. Doesn't\n * necessarily mean that the element has been moved.\n */\n this._hasStartedDragging = false;\n /** Emits when the item is being moved. */\n this._moveEvents = new Subject();\n /** Subscription to pointer movement events. */\n this._pointerMoveSubscription = Subscription.EMPTY;\n /** Subscription to the event that is dispatched when the user lifts their pointer. */\n this._pointerUpSubscription = Subscription.EMPTY;\n /** Subscription to the viewport being scrolled. */\n this._scrollSubscription = Subscription.EMPTY;\n /** Subscription to the viewport being resized. */\n this._resizeSubscription = Subscription.EMPTY;\n /** Cached reference to the boundary element. */\n this._boundaryElement = null;\n /** Whether the native dragging interactions have been enabled on the root element. */\n this._nativeInteractionsEnabled = true;\n /** Elements that can be used to drag the draggable item. */\n this._handles = [];\n /** Registered handles that are currently disabled. */\n this._disabledHandles = new Set();\n /** Layout direction of the item. */\n this._direction = 'ltr';\n /**\n * Amount of milliseconds to wait after the user has put their\n * pointer down before starting to drag the element.\n */\n this.dragStartDelay = 0;\n this._disabled = false;\n /** Emits as the drag sequence is being prepared. */\n this.beforeStarted = new Subject();\n /** Emits when the user starts dragging the item. */\n this.started = new Subject();\n /** Emits when the user has released a drag item, before any animations have started. */\n this.released = new Subject();\n /** Emits when the user stops dragging an item in the container. */\n this.ended = new Subject();\n /** Emits when the user has moved the item into a new container. */\n this.entered = new Subject();\n /** Emits when the user removes the item its container by dragging it into another container. */\n this.exited = new Subject();\n /** Emits when the user drops the item inside a container. */\n this.dropped = new Subject();\n /**\n * Emits as the user is dragging the item. Use with caution,\n * because this event will fire for every pixel that the user has dragged.\n */\n this.moved = this._moveEvents;\n /** Handler for the `mousedown`/`touchstart` events. */\n this._pointerDown = (event) => {\n this.beforeStarted.next();\n // Delegate the event based on whether it started from a handle or the element itself.\n if (this._handles.length) {\n const targetHandle = this._getTargetHandle(event);\n if (targetHandle && !this._disabledHandles.has(targetHandle) && !this.disabled) {\n this._initializeDragSequence(targetHandle, event);\n }\n }\n else if (!this.disabled) {\n this._initializeDragSequence(this._rootElement, event);\n }\n };\n /** Handler that is invoked when the user moves their pointer after they've initiated a drag. */\n this._pointerMove = (event) => {\n const pointerPosition = this._getPointerPositionOnPage(event);\n if (!this._hasStartedDragging) {\n const distanceX = Math.abs(pointerPosition.x - this._pickupPositionOnPage.x);\n const distanceY = Math.abs(pointerPosition.y - this._pickupPositionOnPage.y);\n const isOverThreshold = distanceX + distanceY >= this._config.dragStartThreshold;\n // Only start dragging after the user has moved more than the minimum distance in either\n // direction. Note that this is preferable over doing something like `skip(minimumDistance)`\n // in the `pointerMove` subscription, because we're not guaranteed to have one move event\n // per pixel of movement (e.g. if the user moves their pointer quickly).\n if (isOverThreshold) {\n const isDelayElapsed = Date.now() >= this._dragStartTime + this._getDragStartDelay(event);\n const container = this._dropContainer;\n if (!isDelayElapsed) {\n this._endDragSequence(event);\n return;\n }\n // Prevent other drag sequences from starting while something in the container is still\n // being dragged. This can happen while we're waiting for the drop animation to finish\n // and can cause errors, because some elements might still be moving around.\n if (!container || (!container.isDragging() && !container.isReceiving())) {\n // Prevent the default action as soon as the dragging sequence is considered as\n // \"started\" since waiting for the next event can allow the device to begin scrolling.\n event.preventDefault();\n this._hasStartedDragging = true;\n this._ngZone.run(() => this._startDragSequence(event));\n }\n }\n return;\n }\n // We prevent the default action down here so that we know that dragging has started. This is\n // important for touch devices where doing this too early can unnecessarily block scrolling,\n // if there's a dragging delay.\n event.preventDefault();\n const constrainedPointerPosition = this._getConstrainedPointerPosition(pointerPosition);\n this._hasMoved = true;\n this._lastKnownPointerPosition = pointerPosition;\n this._updatePointerDirectionDelta(constrainedPointerPosition);\n if (this._dropContainer) {\n this._updateActiveDropContainer(constrainedPointerPosition, pointerPosition);\n }\n else {\n // If there's a position constraint function, we want the element's top/left to be at the\n // specific position on the page. Use the initial position as a reference if that's the case.\n const offset = this.constrainPosition ? this._initialClientRect : this._pickupPositionOnPage;\n const activeTransform = this._activeTransform;\n activeTransform.x = constrainedPointerPosition.x - offset.x + this._passiveTransform.x;\n activeTransform.y = constrainedPointerPosition.y - offset.y + this._passiveTransform.y;\n this._applyRootElementTransform(activeTransform.x, activeTransform.y);\n }\n // Since this event gets fired for every pixel while dragging, we only\n // want to fire it if the consumer opted into it. Also we have to\n // re-enter the zone because we run all of the events on the outside.\n if (this._moveEvents.observers.length) {\n this._ngZone.run(() => {\n this._moveEvents.next({\n source: this,\n pointerPosition: constrainedPointerPosition,\n event,\n distance: this._getDragDistance(constrainedPointerPosition),\n delta: this._pointerDirectionDelta,\n });\n });\n }\n };\n /** Handler that is invoked when the user lifts their pointer up, after initiating a drag. */\n this._pointerUp = (event) => {\n this._endDragSequence(event);\n };\n /** Handles a native `dragstart` event. */\n this._nativeDragStart = (event) => {\n if (this._handles.length) {\n const targetHandle = this._getTargetHandle(event);\n if (targetHandle && !this._disabledHandles.has(targetHandle) && !this.disabled) {\n event.preventDefault();\n }\n }\n else if (!this.disabled) {\n // Usually this isn't necessary since the we prevent the default action in `pointerDown`,\n // but some cases like dragging of links can slip through (see #24403).\n event.preventDefault();\n }\n };\n this.withRootElement(element).withParent(_config.parentDragRef || null);\n this._parentPositions = new ParentPositionTracker(_document);\n _dragDropRegistry.registerDragItem(this);\n }\n /**\n * Returns the element that is being used as a placeholder\n * while the current element is being dragged.\n */\n getPlaceholderElement() {\n return this._placeholder;\n }\n /** Returns the root draggable element. */\n getRootElement() {\n return this._rootElement;\n }\n /**\n * Gets the currently-visible element that represents the drag item.\n * While dragging this is the placeholder, otherwise it's the root element.\n */\n getVisibleElement() {\n return this.isDragging() ? this.getPlaceholderElement() : this.getRootElement();\n }\n /** Registers the handles that can be used to drag the element. */\n withHandles(handles) {\n this._handles = handles.map(handle => coerceElement(handle));\n this._handles.forEach(handle => toggleNativeDragInteractions(handle, this.disabled));\n this._toggleNativeDragInteractions();\n // Delete any lingering disabled handles that may have been destroyed. Note that we re-create\n // the set, rather than iterate over it and filter out the destroyed handles, because while\n // the ES spec allows for sets to be modified while they're being iterated over, some polyfills\n // use an array internally which may throw an error.\n const disabledHandles = new Set();\n this._disabledHandles.forEach(handle => {\n if (this._handles.indexOf(handle) > -1) {\n disabledHandles.add(handle);\n }\n });\n this._disabledHandles = disabledHandles;\n return this;\n }\n /**\n * Registers the template that should be used for the drag preview.\n * @param template Template that from which to stamp out the preview.\n */\n withPreviewTemplate(template) {\n this._previewTemplate = template;\n return this;\n }\n /**\n * Registers the template that should be used for the drag placeholder.\n * @param template Template that from which to stamp out the placeholder.\n */\n withPlaceholderTemplate(template) {\n this._placeholderTemplate = template;\n return this;\n }\n /**\n * Sets an alternate drag root element. The root element is the element that will be moved as\n * the user is dragging. Passing an alternate root element is useful when trying to enable\n * dragging on an element that you might not have access to.\n */\n withRootElement(rootElement) {\n const element = coerceElement(rootElement);\n if (element !== this._rootElement) {\n if (this._rootElement) {\n this._removeRootElementListeners(this._rootElement);\n }\n this._ngZone.runOutsideAngular(() => {\n element.addEventListener('mousedown', this._pointerDown, activeEventListenerOptions);\n element.addEventListener('touchstart', this._pointerDown, passiveEventListenerOptions);\n element.addEventListener('dragstart', this._nativeDragStart, activeEventListenerOptions);\n });\n this._initialTransform = undefined;\n this._rootElement = element;\n }\n if (typeof SVGElement !== 'undefined' && this._rootElement instanceof SVGElement) {\n this._ownerSVGElement = this._rootElement.ownerSVGElement;\n }\n return this;\n }\n /**\n * Element to which the draggable's position will be constrained.\n */\n withBoundaryElement(boundaryElement) {\n this._boundaryElement = boundaryElement ? coerceElement(boundaryElement) : null;\n this._resizeSubscription.unsubscribe();\n if (boundaryElement) {\n this._resizeSubscription = this._viewportRuler\n .change(10)\n .subscribe(() => this._containInsideBoundaryOnResize());\n }\n return this;\n }\n /** Sets the parent ref that the ref is nested in. */\n withParent(parent) {\n this._parentDragRef = parent;\n return this;\n }\n /** Removes the dragging functionality from the DOM element. */\n dispose() {\n this._removeRootElementListeners(this._rootElement);\n // Do this check before removing from the registry since it'll\n // stop being considered as dragged once it is removed.\n if (this.isDragging()) {\n // Since we move out the element to the end of the body while it's being\n // dragged, we have to make sure that it's removed if it gets destroyed.\n this._rootElement?.remove();\n }\n this._anchor?.remove();\n this._destroyPreview();\n this._destroyPlaceholder();\n this._dragDropRegistry.removeDragItem(this);\n this._removeSubscriptions();\n this.beforeStarted.complete();\n this.started.complete();\n this.released.complete();\n this.ended.complete();\n this.entered.complete();\n this.exited.complete();\n this.dropped.complete();\n this._moveEvents.complete();\n this._handles = [];\n this._disabledHandles.clear();\n this._dropContainer = undefined;\n this._resizeSubscription.unsubscribe();\n this._parentPositions.clear();\n this._boundaryElement =\n this._rootElement =\n this._ownerSVGElement =\n this._placeholderTemplate =\n this._previewTemplate =\n this._anchor =\n this._parentDragRef =\n null;\n }\n /** Checks whether the element is currently being dragged. */\n isDragging() {\n return this._hasStartedDragging && this._dragDropRegistry.isDragging(this);\n }\n /** Resets a standalone drag item to its initial position. */\n reset() {\n this._rootElement.style.transform = this._initialTransform || '';\n this._activeTransform = { x: 0, y: 0 };\n this._passiveTransform = { x: 0, y: 0 };\n }\n /**\n * Sets a handle as disabled. While a handle is disabled, it'll capture and interrupt dragging.\n * @param handle Handle element that should be disabled.\n */\n disableHandle(handle) {\n if (!this._disabledHandles.has(handle) && this._handles.indexOf(handle) > -1) {\n this._disabledHandles.add(handle);\n toggleNativeDragInteractions(handle, true);\n }\n }\n /**\n * Enables a handle, if it has been disabled.\n * @param handle Handle element to be enabled.\n */\n enableHandle(handle) {\n if (this._disabledHandles.has(handle)) {\n this._disabledHandles.delete(handle);\n toggleNativeDragInteractions(handle, this.disabled);\n }\n }\n /** Sets the layout direction of the draggable item. */\n withDirection(direction) {\n this._direction = direction;\n return this;\n }\n /** Sets the container that the item is part of. */\n _withDropContainer(container) {\n this._dropContainer = container;\n }\n /**\n * Gets the current position in pixels the draggable outside of a drop container.\n */\n getFreeDragPosition() {\n const position = this.isDragging() ? this._activeTransform : this._passiveTransform;\n return { x: position.x, y: position.y };\n }\n /**\n * Sets the current position in pixels the draggable outside of a drop container.\n * @param value New position to be set.\n */\n setFreeDragPosition(value) {\n this._activeTransform = { x: 0, y: 0 };\n this._passiveTransform.x = value.x;\n this._passiveTransform.y = value.y;\n if (!this._dropContainer) {\n this._applyRootElementTransform(value.x, value.y);\n }\n return this;\n }\n /**\n * Sets the container into which to insert the preview element.\n * @param value Container into which to insert the preview.\n */\n withPreviewContainer(value) {\n this._previewContainer = value;\n return this;\n }\n /** Updates the item's sort order based on the last-known pointer position. */\n _sortFromLastPointerPosition() {\n const position = this._lastKnownPointerPosition;\n if (position && this._dropContainer) {\n this._updateActiveDropContainer(this._getConstrainedPointerPosition(position), position);\n }\n }\n /** Unsubscribes from the global subscriptions. */\n _removeSubscriptions() {\n this._pointerMoveSubscription.unsubscribe();\n this._pointerUpSubscription.unsubscribe();\n this._scrollSubscription.unsubscribe();\n }\n /** Destroys the preview element and its ViewRef. */\n _destroyPreview() {\n this._preview?.remove();\n this._previewRef?.destroy();\n this._preview = this._previewRef = null;\n }\n /** Destroys the placeholder element and its ViewRef. */\n _destroyPlaceholder() {\n this._placeholder?.remove();\n this._placeholderRef?.destroy();\n this._placeholder = this._placeholderRef = null;\n }\n /**\n * Clears subscriptions and stops the dragging sequence.\n * @param event Browser event object that ended the sequence.\n */\n _endDragSequence(event) {\n // Note that here we use `isDragging` from the service, rather than from `this`.\n // The difference is that the one from the service reflects whether a dragging sequence\n // has been initiated, whereas the one on `this` includes whether the user has passed\n // the minimum dragging threshold.\n if (!this._dragDropRegistry.isDragging(this)) {\n return;\n }\n this._removeSubscriptions();\n this._dragDropRegistry.stopDragging(this);\n this._toggleNativeDragInteractions();\n if (this._handles) {\n this._rootElement.style.webkitTapHighlightColor =\n this._rootElementTapHighlight;\n }\n if (!this._hasStartedDragging) {\n return;\n }\n this.released.next({ source: this, event });\n if (this._dropContainer) {\n // Stop scrolling immediately, instead of waiting for the animation to finish.\n this._dropContainer._stopScrolling();\n this._animatePreviewToPlaceholder().then(() => {\n this._cleanupDragArtifacts(event);\n this._cleanupCachedDimensions();\n this._dragDropRegistry.stopDragging(this);\n });\n }\n else {\n // Convert the active transform into a passive one. This means that next time\n // the user starts dragging the item, its position will be calculated relatively\n // to the new passive transform.\n this._passiveTransform.x = this._activeTransform.x;\n const pointerPosition = this._getPointerPositionOnPage(event);\n this._passiveTransform.y = this._activeTransform.y;\n this._ngZone.run(() => {\n this.ended.next({\n source: this,\n distance: this._getDragDistance(pointerPosition),\n dropPoint: pointerPosition,\n event,\n });\n });\n this._cleanupCachedDimensions();\n this._dragDropRegistry.stopDragging(this);\n }\n }\n /** Starts the dragging sequence. */\n _startDragSequence(event) {\n if (isTouchEvent(event)) {\n this._lastTouchEventTime = Date.now();\n }\n this._toggleNativeDragInteractions();\n const dropContainer = this._dropContainer;\n if (dropContainer) {\n const element = this._rootElement;\n const parent = element.parentNode;\n const placeholder = (this._placeholder = this._createPlaceholderElement());\n const anchor = (this._anchor = this._anchor || this._document.createComment(''));\n // Needs to happen before the root element is moved.\n const shadowRoot = this._getShadowRoot();\n // Insert an anchor node so that we can restore the element's position in the DOM.\n parent.insertBefore(anchor, element);\n // There's no risk of transforms stacking when inside a drop container so\n // we can keep the initial transform up to date any time dragging starts.\n this._initialTransform = element.style.transform || '';\n // Create the preview after the initial transform has\n // been cached, because it can be affected by the transform.\n this._preview = this._createPreviewElement();\n // We move the element out at the end of the body and we make it hidden, because keeping it in\n // place will throw off the consumer's `:last-child` selectors. We can't remove the element\n // from the DOM completely, because iOS will stop firing all subsequent events in the chain.\n toggleVisibility(element, false, dragImportantProperties);\n this._document.body.appendChild(parent.replaceChild(placeholder, element));\n this._getPreviewInsertionPoint(parent, shadowRoot).appendChild(this._preview);\n this.started.next({ source: this, event }); // Emit before notifying the container.\n dropContainer.start();\n this._initialContainer = dropContainer;\n this._initialIndex = dropContainer.getItemIndex(this);\n }\n else {\n this.started.next({ source: this, event });\n this._initialContainer = this._initialIndex = undefined;\n }\n // Important to run after we've called `start` on the parent container\n // so that it has had time to resolve its scrollable parents.\n this._parentPositions.cache(dropContainer ? dropContainer.getScrollableParents() : []);\n }\n /**\n * Sets up the different variables and subscriptions\n * that will be necessary for the dragging sequence.\n * @param referenceElement Element that started the drag sequence.\n * @param event Browser event object that started the sequence.\n */\n _initializeDragSequence(referenceElement, event) {\n // Stop propagation if the item is inside another\n // draggable so we don't start multiple drag sequences.\n if (this._parentDragRef) {\n event.stopPropagation();\n }\n const isDragging = this.isDragging();\n const isTouchSequence = isTouchEvent(event);\n const isAuxiliaryMouseButton = !isTouchSequence && event.button !== 0;\n const rootElement = this._rootElement;\n const target = _getEventTarget(event);\n const isSyntheticEvent = !isTouchSequence &&\n this._lastTouchEventTime &&\n this._lastTouchEventTime + MOUSE_EVENT_IGNORE_TIME > Date.now();\n const isFakeEvent = isTouchSequence\n ? isFakeTouchstartFromScreenReader(event)\n : isFakeMousedownFromScreenReader(event);\n // If the event started from an element with the native HTML drag&drop, it'll interfere\n // with our own dragging (e.g. `img` tags do it by default). Prevent the default action\n // to stop it from happening. Note that preventing on `dragstart` also seems to work, but\n // it's flaky and it fails if the user drags it away quickly. Also note that we only want\n // to do this for `mousedown` since doing the same for `touchstart` will stop any `click`\n // events from firing on touch devices.\n if (target && target.draggable && event.type === 'mousedown') {\n event.preventDefault();\n }\n // Abort if the user is already dragging or is using a mouse button other than the primary one.\n if (isDragging || isAuxiliaryMouseButton || isSyntheticEvent || isFakeEvent) {\n return;\n }\n // If we've got handles, we need to disable the tap highlight on the entire root element,\n // otherwise iOS will still add it, even though all the drag interactions on the handle\n // are disabled.\n if (this._handles.length) {\n const rootStyles = rootElement.style;\n this._rootElementTapHighlight = rootStyles.webkitTapHighlightColor || '';\n rootStyles.webkitTapHighlightColor = 'transparent';\n }\n this._hasStartedDragging = this._hasMoved = false;\n // Avoid multiple subscriptions and memory leaks when multi touch\n // (isDragging check above isn't enough because of possible temporal and/or dimensional delays)\n this._removeSubscriptions();\n this._initialClientRect = this._rootElement.getBoundingClientRect();\n this._pointerMoveSubscription = this._dragDropRegistry.pointerMove.subscribe(this._pointerMove);\n this._pointerUpSubscription = this._dragDropRegistry.pointerUp.subscribe(this._pointerUp);\n this._scrollSubscription = this._dragDropRegistry\n .scrolled(this._getShadowRoot())\n .subscribe(scrollEvent => this._updateOnScroll(scrollEvent));\n if (this._boundaryElement) {\n this._boundaryRect = getMutableClientRect(this._boundaryElement);\n }\n // If we have a custom preview we can't know ahead of time how large it'll be so we position\n // it next to the cursor. The exception is when the consumer has opted into making the preview\n // the same size as the root element, in which case we do know the size.\n const previewTemplate = this._previewTemplate;\n this._pickupPositionInElement =\n previewTemplate && previewTemplate.template && !previewTemplate.matchSize\n ? { x: 0, y: 0 }\n : this._getPointerPositionInElement(this._initialClientRect, referenceElement, event);\n const pointerPosition = (this._pickupPositionOnPage =\n this._lastKnownPointerPosition =\n this._getPointerPositionOnPage(event));\n this._pointerDirectionDelta = { x: 0, y: 0 };\n this._pointerPositionAtLastDirectionChange = { x: pointerPosition.x, y: pointerPosition.y };\n this._dragStartTime = Date.now();\n this._dragDropRegistry.startDragging(this, event);\n }\n /** Cleans up the DOM artifacts that were added to facilitate the element being dragged. */\n _cleanupDragArtifacts(event) {\n // Restore the element's visibility and insert it at its old position in the DOM.\n // It's important that we maintain the position, because moving the element around in the DOM\n // can throw off `NgFor` which does smart diffing and re-creates elements only when necessary,\n // while moving the existing elements in all other cases.\n toggleVisibility(this._rootElement, true, dragImportantProperties);\n this._anchor.parentNode.replaceChild(this._rootElement, this._anchor);\n this._destroyPreview();\n this._destroyPlaceholder();\n this._initialClientRect =\n this._boundaryRect =\n this._previewRect =\n this._initialTransform =\n undefined;\n // Re-enter the NgZone since we bound `document` events on the outside.\n this._ngZone.run(() => {\n const container = this._dropContainer;\n const currentIndex = container.getItemIndex(this);\n const pointerPosition = this._getPointerPositionOnPage(event);\n const distance = this._getDragDistance(pointerPosition);\n const isPointerOverContainer = container._isOverContainer(pointerPosition.x, pointerPosition.y);\n this.ended.next({ source: this, distance, dropPoint: pointerPosition, event });\n this.dropped.next({\n item: this,\n currentIndex,\n previousIndex: this._initialIndex,\n container: container,\n previousContainer: this._initialContainer,\n isPointerOverContainer,\n distance,\n dropPoint: pointerPosition,\n event,\n });\n container.drop(this, currentIndex, this._initialIndex, this._initialContainer, isPointerOverContainer, distance, pointerPosition, event);\n this._dropContainer = this._initialContainer;\n });\n }\n /**\n * Updates the item's position in its drop container, or moves it\n * into a new one, depending on its current drag position.\n */\n _updateActiveDropContainer({ x, y }, { x: rawX, y: rawY }) {\n // Drop container that draggable has been moved into.\n let newContainer = this._initialContainer._getSiblingContainerFromPosition(this, x, y);\n // If we couldn't find a new container to move the item into, and the item has left its\n // initial container, check whether the it's over the initial container. This handles the\n // case where two containers are connected one way and the user tries to undo dragging an\n // item into a new container.\n if (!newContainer &&\n this._dropContainer !== this._initialContainer &&\n this._initialContainer._isOverContainer(x, y)) {\n newContainer = this._initialContainer;\n }\n if (newContainer && newContainer !== this._dropContainer) {\n this._ngZone.run(() => {\n // Notify the old container that the item has left.\n this.exited.next({ item: this, container: this._dropContainer });\n this._dropContainer.exit(this);\n // Notify the new container that the item has entered.\n this._dropContainer = newContainer;\n this._dropContainer.enter(this, x, y, newContainer === this._initialContainer &&\n // If we're re-entering the initial container and sorting is disabled,\n // put item the into its starting index to begin with.\n newContainer.sortingDisabled\n ? this._initialIndex\n : undefined);\n this.entered.next({\n item: this,\n container: newContainer,\n currentIndex: newContainer.getItemIndex(this),\n });\n });\n }\n // Dragging may have been interrupted as a result of the events above.\n if (this.isDragging()) {\n this._dropContainer._startScrollingIfNecessary(rawX, rawY);\n this._dropContainer._sortItem(this, x, y, this._pointerDirectionDelta);\n if (this.constrainPosition) {\n this._applyPreviewTransform(x, y);\n }\n else {\n this._applyPreviewTransform(x - this._pickupPositionInElement.x, y - this._pickupPositionInElement.y);\n }\n }\n }\n /**\n * Creates the element that will be rendered next to the user's pointer\n * and will be used as a preview of the element that is being dragged.\n */\n _createPreviewElement() {\n const previewConfig = this._previewTemplate;\n const previewClass = this.previewClass;\n const previewTemplate = previewConfig ? previewConfig.template : null;\n let preview;\n if (previewTemplate && previewConfig) {\n // Measure the element before we've inserted the preview\n // since the insertion could throw off the measurement.\n const rootRect = previewConfig.matchSize ? this._initialClientRect : null;\n const viewRef = previewConfig.viewContainer.createEmbeddedView(previewTemplate, previewConfig.context);\n viewRef.detectChanges();\n preview = getRootNode(viewRef, this._document);\n this._previewRef = viewRef;\n if (previewConfig.matchSize) {\n matchElementSize(preview, rootRect);\n }\n else {\n preview.style.transform = getTransform(this._pickupPositionOnPage.x, this._pickupPositionOnPage.y);\n }\n }\n else {\n preview = deepCloneNode(this._rootElement);\n matchElementSize(preview, this._initialClientRect);\n if (this._initialTransform) {\n preview.style.transform = this._initialTransform;\n }\n }\n extendStyles(preview.style, {\n // It's important that we disable the pointer events on the preview, because\n // it can throw off the `document.elementFromPoint` calls in the `CdkDropList`.\n 'pointer-events': 'none',\n // We have to reset the margin, because it can throw off positioning relative to the viewport.\n 'margin': '0',\n 'position': 'fixed',\n 'top': '0',\n 'left': '0',\n 'z-index': `${this._config.zIndex || 1000}`,\n }, dragImportantProperties);\n toggleNativeDragInteractions(preview, false);\n preview.classList.add('cdk-drag-preview');\n preview.setAttribute('dir', this._direction);\n if (previewClass) {\n if (Array.isArray(previewClass)) {\n previewClass.forEach(className => preview.classList.add(className));\n }\n else {\n preview.classList.add(previewClass);\n }\n }\n return preview;\n }\n /**\n * Animates the preview element from its current position to the location of the drop placeholder.\n * @returns Promise that resolves when the animation completes.\n */\n _animatePreviewToPlaceholder() {\n // If the user hasn't moved yet, the transitionend event won't fire.\n if (!this._hasMoved) {\n return Promise.resolve();\n }\n const placeholderRect = this._placeholder.getBoundingClientRect();\n // Apply the class that adds a transition to the preview.\n this._preview.classList.add('cdk-drag-animating');\n // Move the preview to the placeholder position.\n this._applyPreviewTransform(placeholderRect.left, placeholderRect.top);\n // If the element doesn't have a `transition`, the `transitionend` event won't fire. Since\n // we need to trigger a style recalculation in order for the `cdk-drag-animating` class to\n // apply its style, we take advantage of the available info to figure out whether we need to\n // bind the event in the first place.\n const duration = getTransformTransitionDurationInMs(this._preview);\n if (duration === 0) {\n return Promise.resolve();\n }\n return this._ngZone.runOutsideAngular(() => {\n return new Promise(resolve => {\n const handler = ((event) => {\n if (!event ||\n (_getEventTarget(event) === this._preview && event.propertyName === 'transform')) {\n this._preview?.removeEventListener('transitionend', handler);\n resolve();\n clearTimeout(timeout);\n }\n });\n // If a transition is short enough, the browser might not fire the `transitionend` event.\n // Since we know how long it's supposed to take, add a timeout with a 50% buffer that'll\n // fire if the transition hasn't completed when it was supposed to.\n const timeout = setTimeout(handler, duration * 1.5);\n this._preview.addEventListener('transitionend', handler);\n });\n });\n }\n /** Creates an element that will be shown instead of the current element while dragging. */\n _createPlaceholderElement() {\n const placeholderConfig = this._placeholderTemplate;\n const placeholderTemplate = placeholderConfig ? placeholderConfig.template : null;\n let placeholder;\n if (placeholderTemplate) {\n this._placeholderRef = placeholderConfig.viewContainer.createEmbeddedView(placeholderTemplate, placeholderConfig.context);\n this._placeholderRef.detectChanges();\n placeholder = getRootNode(this._placeholderRef, this._document);\n }\n else {\n placeholder = deepCloneNode(this._rootElement);\n }\n // Stop pointer events on the preview so the user can't\n // interact with it while the preview is animating.\n placeholder.style.pointerEvents = 'none';\n placeholder.classList.add('cdk-drag-placeholder');\n return placeholder;\n }\n /**\n * Figures out the coordinates at which an element was picked up.\n * @param referenceElement Element that initiated the dragging.\n * @param event Event that initiated the dragging.\n */\n _getPointerPositionInElement(elementRect, referenceElement, event) {\n const handleElement = referenceElement === this._rootElement ? null : referenceElement;\n const referenceRect = handleElement ? handleElement.getBoundingClientRect() : elementRect;\n const point = isTouchEvent(event) ? event.targetTouches[0] : event;\n const scrollPosition = this._getViewportScrollPosition();\n const x = point.pageX - referenceRect.left - scrollPosition.left;\n const y = point.pageY - referenceRect.top - scrollPosition.top;\n return {\n x: referenceRect.left - elementRect.left + x,\n y: referenceRect.top - elementRect.top + y,\n };\n }\n /** Determines the point of the page that was touched by the user. */\n _getPointerPositionOnPage(event) {\n const scrollPosition = this._getViewportScrollPosition();\n const point = isTouchEvent(event)\n ? // `touches` will be empty for start/end events so we have to fall back to `changedTouches`.\n // Also note that on real devices we're guaranteed for either `touches` or `changedTouches`\n // to have a value, but Firefox in device emulation mode has a bug where both can be empty\n // for `touchstart` and `touchend` so we fall back to a dummy object in order to avoid\n // throwing an error. The value returned here will be incorrect, but since this only\n // breaks inside a developer tool and the value is only used for secondary information,\n // we can get away with it. See https://bugzilla.mozilla.org/show_bug.cgi?id=1615824.\n event.touches[0] || event.changedTouches[0] || { pageX: 0, pageY: 0 }\n : event;\n const x = point.pageX - scrollPosition.left;\n const y = point.pageY - scrollPosition.top;\n // if dragging SVG element, try to convert from the screen coordinate system to the SVG\n // coordinate system\n if (this._ownerSVGElement) {\n const svgMatrix = this._ownerSVGElement.getScreenCTM();\n if (svgMatrix) {\n const svgPoint = this._ownerSVGElement.createSVGPoint();\n svgPoint.x = x;\n svgPoint.y = y;\n return svgPoint.matrixTransform(svgMatrix.inverse());\n }\n }\n return { x, y };\n }\n /** Gets the pointer position on the page, accounting for any position constraints. */\n _getConstrainedPointerPosition(point) {\n const dropContainerLock = this._dropContainer ? this._dropContainer.lockAxis : null;\n let { x, y } = this.constrainPosition\n ? this.constrainPosition(point, this, this._initialClientRect, this._pickupPositionInElement)\n : point;\n if (this.lockAxis === 'x' || dropContainerLock === 'x') {\n y = this._pickupPositionOnPage.y;\n }\n else if (this.lockAxis === 'y' || dropContainerLock === 'y') {\n x = this._pickupPositionOnPage.x;\n }\n if (this._boundaryRect) {\n const { x: pickupX, y: pickupY } = this._pickupPositionInElement;\n const boundaryRect = this._boundaryRect;\n const { width: previewWidth, height: previewHeight } = this._getPreviewRect();\n const minY = boundaryRect.top + pickupY;\n const maxY = boundaryRect.bottom - (previewHeight - pickupY);\n const minX = boundaryRect.left + pickupX;\n const maxX = boundaryRect.right - (previewWidth - pickupX);\n x = clamp$1(x, minX, maxX);\n y = clamp$1(y, minY, maxY);\n }\n return { x, y };\n }\n /** Updates the current drag delta, based on the user's current pointer position on the page. */\n _updatePointerDirectionDelta(pointerPositionOnPage) {\n const { x, y } = pointerPositionOnPage;\n const delta = this._pointerDirectionDelta;\n const positionSinceLastChange = this._pointerPositionAtLastDirectionChange;\n // Amount of pixels the user has dragged since the last time the direction changed.\n const changeX = Math.abs(x - positionSinceLastChange.x);\n const changeY = Math.abs(y - positionSinceLastChange.y);\n // Because we handle pointer events on a per-pixel basis, we don't want the delta\n // to change for every pixel, otherwise anything that depends on it can look erratic.\n // To make the delta more consistent, we track how much the user has moved since the last\n // delta change and we only update it after it has reached a certain threshold.\n if (changeX > this._config.pointerDirectionChangeThreshold) {\n delta.x = x > positionSinceLastChange.x ? 1 : -1;\n positionSinceLastChange.x = x;\n }\n if (changeY > this._config.pointerDirectionChangeThreshold) {\n delta.y = y > positionSinceLastChange.y ? 1 : -1;\n positionSinceLastChange.y = y;\n }\n return delta;\n }\n /** Toggles the native drag interactions, based on how many handles are registered. */\n _toggleNativeDragInteractions() {\n if (!this._rootElement || !this._handles) {\n return;\n }\n const shouldEnable = this._handles.length > 0 || !this.isDragging();\n if (shouldEnable !== this._nativeInteractionsEnabled) {\n this._nativeInteractionsEnabled = shouldEnable;\n toggleNativeDragInteractions(this._rootElement, shouldEnable);\n }\n }\n /** Removes the manually-added event listeners from the root element. */\n _removeRootElementListeners(element) {\n element.removeEventListener('mousedown', this._pointerDown, activeEventListenerOptions);\n element.removeEventListener('touchstart', this._pointerDown, passiveEventListenerOptions);\n element.removeEventListener('dragstart', this._nativeDragStart, activeEventListenerOptions);\n }\n /**\n * Applies a `transform` to the root element, taking into account any existing transforms on it.\n * @param x New transform value along the X axis.\n * @param y New transform value along the Y axis.\n */\n _applyRootElementTransform(x, y) {\n const transform = getTransform(x, y);\n const styles = this._rootElement.style;\n // Cache the previous transform amount only after the first drag sequence, because\n // we don't want our own transforms to stack on top of each other.\n // Should be excluded none because none + translate3d(x, y, x) is invalid css\n if (this._initialTransform == null) {\n this._initialTransform =\n styles.transform && styles.transform != 'none' ? styles.transform : '';\n }\n // Preserve the previous `transform` value, if there was one. Note that we apply our own\n // transform before the user's, because things like rotation can affect which direction\n // the element will be translated towards.\n styles.transform = combineTransforms(transform, this._initialTransform);\n }\n /**\n * Applies a `transform` to the preview, taking into account any existing transforms on it.\n * @param x New transform value along the X axis.\n * @param y New transform value along the Y axis.\n */\n _applyPreviewTransform(x, y) {\n // Only apply the initial transform if the preview is a clone of the original element, otherwise\n // it could be completely different and the transform might not make sense anymore.\n const initialTransform = this._previewTemplate?.template ? undefined : this._initialTransform;\n const transform = getTransform(x, y);\n this._preview.style.transform = combineTransforms(transform, initialTransform);\n }\n /**\n * Gets the distance that the user has dragged during the current drag sequence.\n * @param currentPosition Current position of the user's pointer.\n */\n _getDragDistance(currentPosition) {\n const pickupPosition = this._pickupPositionOnPage;\n if (pickupPosition) {\n return { x: currentPosition.x - pickupPosition.x, y: currentPosition.y - pickupPosition.y };\n }\n return { x: 0, y: 0 };\n }\n /** Cleans up any cached element dimensions that we don't need after dragging has stopped. */\n _cleanupCachedDimensions() {\n this._boundaryRect = this._previewRect = undefined;\n this._parentPositions.clear();\n }\n /**\n * Checks whether the element is still inside its boundary after the viewport has been resized.\n * If not, the position is adjusted so that the element fits again.\n */\n _containInsideBoundaryOnResize() {\n let { x, y } = this._passiveTransform;\n if ((x === 0 && y === 0) || this.isDragging() || !this._boundaryElement) {\n return;\n }\n // Note: don't use `_clientRectAtStart` here, because we want the latest position.\n const elementRect = this._rootElement.getBoundingClientRect();\n const boundaryRect = this._boundaryElement.getBoundingClientRect();\n // It's possible that the element got hidden away after dragging (e.g. by switching to a\n // different tab). Don't do anything in this case so we don't clear the user's position.\n if ((boundaryRect.width === 0 && boundaryRect.height === 0) ||\n (elementRect.width === 0 && elementRect.height === 0)) {\n return;\n }\n const leftOverflow = boundaryRect.left - elementRect.left;\n const rightOverflow = elementRect.right - boundaryRect.right;\n const topOverflow = boundaryRect.top - elementRect.top;\n const bottomOverflow = elementRect.bottom - boundaryRect.bottom;\n // If the element has become wider than the boundary, we can't\n // do much to make it fit so we just anchor it to the left.\n if (boundaryRect.width > elementRect.width) {\n if (leftOverflow > 0) {\n x += leftOverflow;\n }\n if (rightOverflow > 0) {\n x -= rightOverflow;\n }\n }\n else {\n x = 0;\n }\n // If the element has become taller than the boundary, we can't\n // do much to make it fit so we just anchor it to the top.\n if (boundaryRect.height > elementRect.height) {\n if (topOverflow > 0) {\n y += topOverflow;\n }\n if (bottomOverflow > 0) {\n y -= bottomOverflow;\n }\n }\n else {\n y = 0;\n }\n if (x !== this._passiveTransform.x || y !== this._passiveTransform.y) {\n this.setFreeDragPosition({ y, x });\n }\n }\n /** Gets the drag start delay, based on the event type. */\n _getDragStartDelay(event) {\n const value = this.dragStartDelay;\n if (typeof value === 'number') {\n return value;\n }\n else if (isTouchEvent(event)) {\n return value.touch;\n }\n return value ? value.mouse : 0;\n }\n /** Updates the internal state of the draggable element when scrolling has occurred. */\n _updateOnScroll(event) {\n const scrollDifference = this._parentPositions.handleScroll(event);\n if (scrollDifference) {\n const target = _getEventTarget(event);\n // ClientRect dimensions are based on the scroll position of the page and its parent\n // node so we have to update the cached boundary ClientRect if the user has scrolled.\n if (this._boundaryRect &&\n target !== this._boundaryElement &&\n target.contains(this._boundaryElement)) {\n adjustClientRect(this._boundaryRect, scrollDifference.top, scrollDifference.left);\n }\n this._pickupPositionOnPage.x += scrollDifference.left;\n this._pickupPositionOnPage.y += scrollDifference.top;\n // If we're in free drag mode, we have to update the active transform, because\n // it isn't relative to the viewport like the preview inside a drop list.\n if (!this._dropContainer) {\n this._activeTransform.x -= scrollDifference.left;\n this._activeTransform.y -= scrollDifference.top;\n this._applyRootElementTransform(this._activeTransform.x, this._activeTransform.y);\n }\n }\n }\n /** Gets the scroll position of the viewport. */\n _getViewportScrollPosition() {\n return (this._parentPositions.positions.get(this._document)?.scrollPosition ||\n this._parentPositions.getViewportScrollPosition());\n }\n /**\n * Lazily resolves and returns the shadow root of the element. We do this in a function, rather\n * than saving it in property directly on init, because we want to resolve it as late as possible\n * in order to ensure that the element has been moved into the shadow DOM. Doing it inside the\n * constructor might be too early if the element is inside of something like `ngFor` or `ngIf`.\n */\n _getShadowRoot() {\n if (this._cachedShadowRoot === undefined) {\n this._cachedShadowRoot = _getShadowRoot(this._rootElement);\n }\n return this._cachedShadowRoot;\n }\n /** Gets the element into which the drag preview should be inserted. */\n _getPreviewInsertionPoint(initialParent, shadowRoot) {\n const previewContainer = this._previewContainer || 'global';\n if (previewContainer === 'parent') {\n return initialParent;\n }\n if (previewContainer === 'global') {\n const documentRef = this._document;\n // We can't use the body if the user is in fullscreen mode,\n // because the preview will render under the fullscreen element.\n // TODO(crisbeto): dedupe this with the `FullscreenOverlayContainer` eventually.\n return (shadowRoot ||\n documentRef.fullscreenElement ||\n documentRef.webkitFullscreenElement ||\n documentRef.mozFullScreenElement ||\n documentRef.msFullscreenElement ||\n documentRef.body);\n }\n return coerceElement(previewContainer);\n }\n /** Lazily resolves and returns the dimensions of the preview. */\n _getPreviewRect() {\n // Cache the preview element rect if we haven't cached it already or if\n // we cached it too early before the element dimensions were computed.\n if (!this._previewRect || (!this._previewRect.width && !this._previewRect.height)) {\n this._previewRect = this._preview\n ? this._preview.getBoundingClientRect()\n : this._initialClientRect;\n }\n return this._previewRect;\n }\n /** Gets a handle that is the target of an event. */\n _getTargetHandle(event) {\n return this._handles.find(handle => {\n return event.target && (event.target === handle || handle.contains(event.target));\n });\n }\n}\n/**\n * Gets a 3d `transform` that can be applied to an element.\n * @param x Desired position of the element along the X axis.\n * @param y Desired position of the element along the Y axis.\n */\nfunction getTransform(x, y) {\n // Round the transforms since some browsers will\n // blur the elements for sub-pixel transforms.\n return `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`;\n}\n/** Clamps a value between a minimum and a maximum. */\nfunction clamp$1(value, min, max) {\n return Math.max(min, Math.min(max, value));\n}\n/** Determines whether an event is a touch event. */\nfunction isTouchEvent(event) {\n // This function is called for every pixel that the user has dragged so we need it to be\n // as fast as possible. Since we only bind mouse events and touch events, we can assume\n // that if the event's name starts with `t`, it's a touch event.\n return event.type[0] === 't';\n}\n/**\n * Gets the root HTML element of an embedded view.\n * If the root is not an HTML element it gets wrapped in one.\n */\nfunction getRootNode(viewRef, _document) {\n const rootNodes = viewRef.rootNodes;\n if (rootNodes.length === 1 && rootNodes[0].nodeType === _document.ELEMENT_NODE) {\n return rootNodes[0];\n }\n const wrapper = _document.createElement('div');\n rootNodes.forEach(node => wrapper.appendChild(node));\n return wrapper;\n}\n/**\n * Matches the target element's size to the source's size.\n * @param target Element that needs to be resized.\n * @param sourceRect Dimensions of the source element.\n */\nfunction matchElementSize(target, sourceRect) {\n target.style.width = `${sourceRect.width}px`;\n target.style.height = `${sourceRect.height}px`;\n target.style.transform = getTransform(sourceRect.left, sourceRect.top);\n}\n\n/**\n * Moves an item one index in an array to another.\n * @param array Array in which to move the item.\n * @param fromIndex Starting index of the item.\n * @param toIndex Index to which the item should be moved.\n */\nfunction moveItemInArray(array, fromIndex, toIndex) {\n const from = clamp(fromIndex, array.length - 1);\n const to = clamp(toIndex, array.length - 1);\n if (from === to) {\n return;\n }\n const target = array[from];\n const delta = to < from ? -1 : 1;\n for (let i = from; i !== to; i += delta) {\n array[i] = array[i + delta];\n }\n array[to] = target;\n}\n/**\n * Moves an item from one array to another.\n * @param currentArray Array from which to transfer the item.\n * @param targetArray Array into which to put the item.\n * @param currentIndex Index of the item in its current array.\n * @param targetIndex Index at which to insert the item.\n */\nfunction transferArrayItem(currentArray, targetArray, currentIndex, targetIndex) {\n const from = clamp(currentIndex, currentArray.length - 1);\n const to = clamp(targetIndex, targetArray.length);\n if (currentArray.length) {\n targetArray.splice(to, 0, currentArray.splice(from, 1)[0]);\n }\n}\n/**\n * Copies an item from one array to another, leaving it in its\n * original position in current array.\n * @param currentArray Array from which to copy the item.\n * @param targetArray Array into which is copy the item.\n * @param currentIndex Index of the item in its current array.\n * @param targetIndex Index at which to insert the item.\n *\n */\nfunction copyArrayItem(currentArray, targetArray, currentIndex, targetIndex) {\n const to = clamp(targetIndex, targetArray.length);\n if (currentArray.length) {\n targetArray.splice(to, 0, currentArray[currentIndex]);\n }\n}\n/** Clamps a number between zero and a maximum. */\nfunction clamp(value, max) {\n return Math.max(0, Math.min(max, value));\n}\n\n/**\n * Strategy that only supports sorting along a single axis.\n * Items are reordered using CSS transforms which allows for sorting to be animated.\n * @docs-private\n */\nclass SingleAxisSortStrategy {\n constructor(_element, _dragDropRegistry) {\n this._element = _element;\n this._dragDropRegistry = _dragDropRegistry;\n /** Cache of the dimensions of all the items inside the container. */\n this._itemPositions = [];\n /** Direction in which the list is oriented. */\n this.orientation = 'vertical';\n /**\n * Keeps track of the item that was last swapped with the dragged item, as well as what direction\n * the pointer was moving in when the swap occurred and whether the user's pointer continued to\n * overlap with the swapped item after the swapping occurred.\n */\n this._previousSwap = {\n drag: null,\n delta: 0,\n overlaps: false,\n };\n }\n /**\n * To be called when the drag sequence starts.\n * @param items Items that are currently in the list.\n */\n start(items) {\n this.withItems(items);\n }\n /**\n * To be called when an item is being sorted.\n * @param item Item to be sorted.\n * @param pointerX Position of the item along the X axis.\n * @param pointerY Position of the item along the Y axis.\n * @param pointerDelta Direction in which the pointer is moving along each axis.\n */\n sort(item, pointerX, pointerY, pointerDelta) {\n const siblings = this._itemPositions;\n const newIndex = this._getItemIndexFromPointerPosition(item, pointerX, pointerY, pointerDelta);\n if (newIndex === -1 && siblings.length > 0) {\n return null;\n }\n const isHorizontal = this.orientation === 'horizontal';\n const currentIndex = siblings.findIndex(currentItem => currentItem.drag === item);\n const siblingAtNewPosition = siblings[newIndex];\n const currentPosition = siblings[currentIndex].clientRect;\n const newPosition = siblingAtNewPosition.clientRect;\n const delta = currentIndex > newIndex ? 1 : -1;\n // How many pixels the item's placeholder should be offset.\n const itemOffset = this._getItemOffsetPx(currentPosition, newPosition, delta);\n // How many pixels all the other items should be offset.\n const siblingOffset = this._getSiblingOffsetPx(currentIndex, siblings, delta);\n // Save the previous order of the items before moving the item to its new index.\n // We use this to check whether an item has been moved as a result of the sorting.\n const oldOrder = siblings.slice();\n // Shuffle the array in place.\n moveItemInArray(siblings, currentIndex, newIndex);\n siblings.forEach((sibling, index) => {\n // Don't do anything if the position hasn't changed.\n if (oldOrder[index] === sibling) {\n return;\n }\n const isDraggedItem = sibling.drag === item;\n const offset = isDraggedItem ? itemOffset : siblingOffset;\n const elementToOffset = isDraggedItem\n ? item.getPlaceholderElement()\n : sibling.drag.getRootElement();\n // Update the offset to reflect the new position.\n sibling.offset += offset;\n // Since we're moving the items with a `transform`, we need to adjust their cached\n // client rects to reflect their new position, as well as swap their positions in the cache.\n // Note that we shouldn't use `getBoundingClientRect` here to update the cache, because the\n // elements may be mid-animation which will give us a wrong result.\n if (isHorizontal) {\n // Round the transforms since some browsers will\n // blur the elements, for sub-pixel transforms.\n elementToOffset.style.transform = combineTransforms(`translate3d(${Math.round(sibling.offset)}px, 0, 0)`, sibling.initialTransform);\n adjustClientRect(sibling.clientRect, 0, offset);\n }\n else {\n elementToOffset.style.transform = combineTransforms(`translate3d(0, ${Math.round(sibling.offset)}px, 0)`, sibling.initialTransform);\n adjustClientRect(sibling.clientRect, offset, 0);\n }\n });\n // Note that it's important that we do this after the client rects have been adjusted.\n this._previousSwap.overlaps = isInsideClientRect(newPosition, pointerX, pointerY);\n this._previousSwap.drag = siblingAtNewPosition.drag;\n this._previousSwap.delta = isHorizontal ? pointerDelta.x : pointerDelta.y;\n return { previousIndex: currentIndex, currentIndex: newIndex };\n }\n /**\n * Called when an item is being moved into the container.\n * @param item Item that was moved into the container.\n * @param pointerX Position of the item along the X axis.\n * @param pointerY Position of the item along the Y axis.\n * @param index Index at which the item entered. If omitted, the container will try to figure it\n * out automatically.\n */\n enter(item, pointerX, pointerY, index) {\n const newIndex = index == null || index < 0\n ? // We use the coordinates of where the item entered the drop\n // zone to figure out at which index it should be inserted.\n this._getItemIndexFromPointerPosition(item, pointerX, pointerY)\n : index;\n const activeDraggables = this._activeDraggables;\n const currentIndex = activeDraggables.indexOf(item);\n const placeholder = item.getPlaceholderElement();\n let newPositionReference = activeDraggables[newIndex];\n // If the item at the new position is the same as the item that is being dragged,\n // it means that we're trying to restore the item to its initial position. In this\n // case we should use the next item from the list as the reference.\n if (newPositionReference === item) {\n newPositionReference = activeDraggables[newIndex + 1];\n }\n // If we didn't find a new position reference, it means that either the item didn't start off\n // in this container, or that the item requested to be inserted at the end of the list.\n if (!newPositionReference &&\n (newIndex == null || newIndex === -1 || newIndex < activeDraggables.length - 1) &&\n this._shouldEnterAsFirstChild(pointerX, pointerY)) {\n newPositionReference = activeDraggables[0];\n }\n // Since the item may be in the `activeDraggables` already (e.g. if the user dragged it\n // into another container and back again), we have to ensure that it isn't duplicated.\n if (currentIndex > -1) {\n activeDraggables.splice(currentIndex, 1);\n }\n // Don't use items that are being dragged as a reference, because\n // their element has been moved down to the bottom of the body.\n if (newPositionReference && !this._dragDropRegistry.isDragging(newPositionReference)) {\n const element = newPositionReference.getRootElement();\n element.parentElement.insertBefore(placeholder, element);\n activeDraggables.splice(newIndex, 0, item);\n }\n else {\n coerceElement(this._element).appendChild(placeholder);\n activeDraggables.push(item);\n }\n // The transform needs to be cleared so it doesn't throw off the measurements.\n placeholder.style.transform = '';\n // Note that usually `start` is called together with `enter` when an item goes into a new\n // container. This will cache item positions, but we need to refresh them since the amount\n // of items has changed.\n this._cacheItemPositions();\n }\n /** Sets the items that are currently part of the list. */\n withItems(items) {\n this._activeDraggables = items.slice();\n this._cacheItemPositions();\n }\n /** Assigns a sort predicate to the strategy. */\n withSortPredicate(predicate) {\n this._sortPredicate = predicate;\n }\n /** Resets the strategy to its initial state before dragging was started. */\n reset() {\n // TODO(crisbeto): may have to wait for the animations to finish.\n this._activeDraggables.forEach(item => {\n const rootElement = item.getRootElement();\n if (rootElement) {\n const initialTransform = this._itemPositions.find(p => p.drag === item)?.initialTransform;\n rootElement.style.transform = initialTransform || '';\n }\n });\n this._itemPositions = [];\n this._activeDraggables = [];\n this._previousSwap.drag = null;\n this._previousSwap.delta = 0;\n this._previousSwap.overlaps = false;\n }\n /**\n * Gets a snapshot of items currently in the list.\n * Can include items that we dragged in from another list.\n */\n getActiveItemsSnapshot() {\n return this._activeDraggables;\n }\n /** Gets the index of a specific item. */\n getItemIndex(item) {\n // Items are sorted always by top/left in the cache, however they flow differently in RTL.\n // The rest of the logic still stands no matter what orientation we're in, however\n // we need to invert the array when determining the index.\n const items = this.orientation === 'horizontal' && this.direction === 'rtl'\n ? this._itemPositions.slice().reverse()\n : this._itemPositions;\n return items.findIndex(currentItem => currentItem.drag === item);\n }\n /** Used to notify the strategy that the scroll position has changed. */\n updateOnScroll(topDifference, leftDifference) {\n // Since we know the amount that the user has scrolled we can shift all of the\n // client rectangles ourselves. This is cheaper than re-measuring everything and\n // we can avoid inconsistent behavior where we might be measuring the element before\n // its position has changed.\n this._itemPositions.forEach(({ clientRect }) => {\n adjustClientRect(clientRect, topDifference, leftDifference);\n });\n // We need two loops for this, because we want all of the cached\n // positions to be up-to-date before we re-sort the item.\n this._itemPositions.forEach(({ drag }) => {\n if (this._dragDropRegistry.isDragging(drag)) {\n // We need to re-sort the item manually, because the pointer move\n // events won't be dispatched while the user is scrolling.\n drag._sortFromLastPointerPosition();\n }\n });\n }\n /** Refreshes the position cache of the items and sibling containers. */\n _cacheItemPositions() {\n const isHorizontal = this.orientation === 'horizontal';\n this._itemPositions = this._activeDraggables\n .map(drag => {\n const elementToMeasure = drag.getVisibleElement();\n return {\n drag,\n offset: 0,\n initialTransform: elementToMeasure.style.transform || '',\n clientRect: getMutableClientRect(elementToMeasure),\n };\n })\n .sort((a, b) => {\n return isHorizontal\n ? a.clientRect.left - b.clientRect.left\n : a.clientRect.top - b.clientRect.top;\n });\n }\n /**\n * Gets the offset in pixels by which the item that is being dragged should be moved.\n * @param currentPosition Current position of the item.\n * @param newPosition Position of the item where the current item should be moved.\n * @param delta Direction in which the user is moving.\n */\n _getItemOffsetPx(currentPosition, newPosition, delta) {\n const isHorizontal = this.orientation === 'horizontal';\n let itemOffset = isHorizontal\n ? newPosition.left - currentPosition.left\n : newPosition.top - currentPosition.top;\n // Account for differences in the item width/height.\n if (delta === -1) {\n itemOffset += isHorizontal\n ? newPosition.width - currentPosition.width\n : newPosition.height - currentPosition.height;\n }\n return itemOffset;\n }\n /**\n * Gets the offset in pixels by which the items that aren't being dragged should be moved.\n * @param currentIndex Index of the item currently being dragged.\n * @param siblings All of the items in the list.\n * @param delta Direction in which the user is moving.\n */\n _getSiblingOffsetPx(currentIndex, siblings, delta) {\n const isHorizontal = this.orientation === 'horizontal';\n const currentPosition = siblings[currentIndex].clientRect;\n const immediateSibling = siblings[currentIndex + delta * -1];\n let siblingOffset = currentPosition[isHorizontal ? 'width' : 'height'] * delta;\n if (immediateSibling) {\n const start = isHorizontal ? 'left' : 'top';\n const end = isHorizontal ? 'right' : 'bottom';\n // Get the spacing between the start of the current item and the end of the one immediately\n // after it in the direction in which the user is dragging, or vice versa. We add it to the\n // offset in order to push the element to where it will be when it's inline and is influenced\n // by the `margin` of its siblings.\n if (delta === -1) {\n siblingOffset -= immediateSibling.clientRect[start] - currentPosition[end];\n }\n else {\n siblingOffset += currentPosition[start] - immediateSibling.clientRect[end];\n }\n }\n return siblingOffset;\n }\n /**\n * Checks if pointer is entering in the first position\n * @param pointerX Position of the user's pointer along the X axis.\n * @param pointerY Position of the user's pointer along the Y axis.\n */\n _shouldEnterAsFirstChild(pointerX, pointerY) {\n if (!this._activeDraggables.length) {\n return false;\n }\n const itemPositions = this._itemPositions;\n const isHorizontal = this.orientation === 'horizontal';\n // `itemPositions` are sorted by position while `activeDraggables` are sorted by child index\n // check if container is using some sort of \"reverse\" ordering (eg: flex-direction: row-reverse)\n const reversed = itemPositions[0].drag !== this._activeDraggables[0];\n if (reversed) {\n const lastItemRect = itemPositions[itemPositions.length - 1].clientRect;\n return isHorizontal ? pointerX >= lastItemRect.right : pointerY >= lastItemRect.bottom;\n }\n else {\n const firstItemRect = itemPositions[0].clientRect;\n return isHorizontal ? pointerX <= firstItemRect.left : pointerY <= firstItemRect.top;\n }\n }\n /**\n * Gets the index of an item in the drop container, based on the position of the user's pointer.\n * @param item Item that is being sorted.\n * @param pointerX Position of the user's pointer along the X axis.\n * @param pointerY Position of the user's pointer along the Y axis.\n * @param delta Direction in which the user is moving their pointer.\n */\n _getItemIndexFromPointerPosition(item, pointerX, pointerY, delta) {\n const isHorizontal = this.orientation === 'horizontal';\n const index = this._itemPositions.findIndex(({ drag, clientRect }) => {\n // Skip the item itself.\n if (drag === item) {\n return false;\n }\n if (delta) {\n const direction = isHorizontal ? delta.x : delta.y;\n // If the user is still hovering over the same item as last time, their cursor hasn't left\n // the item after we made the swap, and they didn't change the direction in which they're\n // dragging, we don't consider it a direction swap.\n if (drag === this._previousSwap.drag &&\n this._previousSwap.overlaps &&\n direction === this._previousSwap.delta) {\n return false;\n }\n }\n return isHorizontal\n ? // Round these down since most browsers report client rects with\n // sub-pixel precision, whereas the pointer coordinates are rounded to pixels.\n pointerX >= Math.floor(clientRect.left) && pointerX < Math.floor(clientRect.right)\n : pointerY >= Math.floor(clientRect.top) && pointerY < Math.floor(clientRect.bottom);\n });\n return index === -1 || !this._sortPredicate(index, item) ? -1 : index;\n }\n}\n\n/**\n * Proximity, as a ratio to width/height, at which a\n * dragged item will affect the drop container.\n */\nconst DROP_PROXIMITY_THRESHOLD = 0.05;\n/**\n * Proximity, as a ratio to width/height at which to start auto-scrolling the drop list or the\n * viewport. The value comes from trying it out manually until it feels right.\n */\nconst SCROLL_PROXIMITY_THRESHOLD = 0.05;\n/**\n * Reference to a drop list. Used to manipulate or dispose of the container.\n */\nclass DropListRef {\n constructor(element, _dragDropRegistry, _document, _ngZone, _viewportRuler) {\n this._dragDropRegistry = _dragDropRegistry;\n this._ngZone = _ngZone;\n this._viewportRuler = _viewportRuler;\n /** Whether starting a dragging sequence from this container is disabled. */\n this.disabled = false;\n /** Whether sorting items within the list is disabled. */\n this.sortingDisabled = false;\n /**\n * Whether auto-scrolling the view when the user\n * moves their pointer close to the edges is disabled.\n */\n this.autoScrollDisabled = false;\n /** Number of pixels to scroll for each frame when auto-scrolling an element. */\n this.autoScrollStep = 2;\n /**\n * Function that is used to determine whether an item\n * is allowed to be moved into a drop container.\n */\n this.enterPredicate = () => true;\n /** Function that is used to determine whether an item can be sorted into a particular index. */\n this.sortPredicate = () => true;\n /** Emits right before dragging has started. */\n this.beforeStarted = new Subject();\n /**\n * Emits when the user has moved a new drag item into this container.\n */\n this.entered = new Subject();\n /**\n * Emits when the user removes an item from the container\n * by dragging it into another container.\n */\n this.exited = new Subject();\n /** Emits when the user drops an item inside the container. */\n this.dropped = new Subject();\n /** Emits as the user is swapping items while actively dragging. */\n this.sorted = new Subject();\n /** Emits when a dragging sequence is started in a list connected to the current one. */\n this.receivingStarted = new Subject();\n /** Emits when a dragging sequence is stopped from a list connected to the current one. */\n this.receivingStopped = new Subject();\n /** Whether an item in the list is being dragged. */\n this._isDragging = false;\n /** Draggable items in the container. */\n this._draggables = [];\n /** Drop lists that are connected to the current one. */\n this._siblings = [];\n /** Connected siblings that currently have a dragged item. */\n this._activeSiblings = new Set();\n /** Subscription to the window being scrolled. */\n this._viewportScrollSubscription = Subscription.EMPTY;\n /** Vertical direction in which the list is currently scrolling. */\n this._verticalScrollDirection = 0 /* AutoScrollVerticalDirection.NONE */;\n /** Horizontal direction in which the list is currently scrolling. */\n this._horizontalScrollDirection = 0 /* AutoScrollHorizontalDirection.NONE */;\n /** Used to signal to the current auto-scroll sequence when to stop. */\n this._stopScrollTimers = new Subject();\n /** Shadow root of the current element. Necessary for `elementFromPoint` to resolve correctly. */\n this._cachedShadowRoot = null;\n /** Starts the interval that'll auto-scroll the element. */\n this._startScrollInterval = () => {\n this._stopScrolling();\n interval(0, animationFrameScheduler)\n .pipe(takeUntil(this._stopScrollTimers))\n .subscribe(() => {\n const node = this._scrollNode;\n const scrollStep = this.autoScrollStep;\n if (this._verticalScrollDirection === 1 /* AutoScrollVerticalDirection.UP */) {\n node.scrollBy(0, -scrollStep);\n }\n else if (this._verticalScrollDirection === 2 /* AutoScrollVerticalDirection.DOWN */) {\n node.scrollBy(0, scrollStep);\n }\n if (this._horizontalScrollDirection === 1 /* AutoScrollHorizontalDirection.LEFT */) {\n node.scrollBy(-scrollStep, 0);\n }\n else if (this._horizontalScrollDirection === 2 /* AutoScrollHorizontalDirection.RIGHT */) {\n node.scrollBy(scrollStep, 0);\n }\n });\n };\n this.element = coerceElement(element);\n this._document = _document;\n this.withScrollableParents([this.element]);\n _dragDropRegistry.registerDropContainer(this);\n this._parentPositions = new ParentPositionTracker(_document);\n this._sortStrategy = new SingleAxisSortStrategy(this.element, _dragDropRegistry);\n this._sortStrategy.withSortPredicate((index, item) => this.sortPredicate(index, item, this));\n }\n /** Removes the drop list functionality from the DOM element. */\n dispose() {\n this._stopScrolling();\n this._stopScrollTimers.complete();\n this._viewportScrollSubscription.unsubscribe();\n this.beforeStarted.complete();\n this.entered.complete();\n this.exited.complete();\n this.dropped.complete();\n this.sorted.complete();\n this.receivingStarted.complete();\n this.receivingStopped.complete();\n this._activeSiblings.clear();\n this._scrollNode = null;\n this._parentPositions.clear();\n this._dragDropRegistry.removeDropContainer(this);\n }\n /** Whether an item from this list is currently being dragged. */\n isDragging() {\n return this._isDragging;\n }\n /** Starts dragging an item. */\n start() {\n this._draggingStarted();\n this._notifyReceivingSiblings();\n }\n /**\n * Attempts to move an item into the container.\n * @param item Item that was moved into the container.\n * @param pointerX Position of the item along the X axis.\n * @param pointerY Position of the item along the Y axis.\n * @param index Index at which the item entered. If omitted, the container will try to figure it\n * out automatically.\n */\n enter(item, pointerX, pointerY, index) {\n this._draggingStarted();\n // If sorting is disabled, we want the item to return to its starting\n // position if the user is returning it to its initial container.\n if (index == null && this.sortingDisabled) {\n index = this._draggables.indexOf(item);\n }\n this._sortStrategy.enter(item, pointerX, pointerY, index);\n // Note that this usually happens inside `_draggingStarted` as well, but the dimensions\n // can change when the sort strategy moves the item around inside `enter`.\n this._cacheParentPositions();\n // Notify siblings at the end so that the item has been inserted into the `activeDraggables`.\n this._notifyReceivingSiblings();\n this.entered.next({ item, container: this, currentIndex: this.getItemIndex(item) });\n }\n /**\n * Removes an item from the container after it was dragged into another container by the user.\n * @param item Item that was dragged out.\n */\n exit(item) {\n this._reset();\n this.exited.next({ item, container: this });\n }\n /**\n * Drops an item into this container.\n * @param item Item being dropped into the container.\n * @param currentIndex Index at which the item should be inserted.\n * @param previousIndex Index of the item when dragging started.\n * @param previousContainer Container from which the item got dragged in.\n * @param isPointerOverContainer Whether the user's pointer was over the\n * container when the item was dropped.\n * @param distance Distance the user has dragged since the start of the dragging sequence.\n * @param event Event that triggered the dropping sequence.\n *\n * @breaking-change 15.0.0 `previousIndex` and `event` parameters to become required.\n */\n drop(item, currentIndex, previousIndex, previousContainer, isPointerOverContainer, distance, dropPoint, event = {}) {\n this._reset();\n this.dropped.next({\n item,\n currentIndex,\n previousIndex,\n container: this,\n previousContainer,\n isPointerOverContainer,\n distance,\n dropPoint,\n event,\n });\n }\n /**\n * Sets the draggable items that are a part of this list.\n * @param items Items that are a part of this list.\n */\n withItems(items) {\n const previousItems = this._draggables;\n this._draggables = items;\n items.forEach(item => item._withDropContainer(this));\n if (this.isDragging()) {\n const draggedItems = previousItems.filter(item => item.isDragging());\n // If all of the items being dragged were removed\n // from the list, abort the current drag sequence.\n if (draggedItems.every(item => items.indexOf(item) === -1)) {\n this._reset();\n }\n else {\n this._sortStrategy.withItems(this._draggables);\n }\n }\n return this;\n }\n /** Sets the layout direction of the drop list. */\n withDirection(direction) {\n this._sortStrategy.direction = direction;\n return this;\n }\n /**\n * Sets the containers that are connected to this one. When two or more containers are\n * connected, the user will be allowed to transfer items between them.\n * @param connectedTo Other containers that the current containers should be connected to.\n */\n connectedTo(connectedTo) {\n this._siblings = connectedTo.slice();\n return this;\n }\n /**\n * Sets the orientation of the container.\n * @param orientation New orientation for the container.\n */\n withOrientation(orientation) {\n // TODO(crisbeto): eventually we should be constructing the new sort strategy here based on\n // the new orientation. For now we can assume that it'll always be `SingleAxisSortStrategy`.\n this._sortStrategy.orientation = orientation;\n return this;\n }\n /**\n * Sets which parent elements are can be scrolled while the user is dragging.\n * @param elements Elements that can be scrolled.\n */\n withScrollableParents(elements) {\n const element = coerceElement(this.element);\n // We always allow the current element to be scrollable\n // so we need to ensure that it's in the array.\n this._scrollableElements =\n elements.indexOf(element) === -1 ? [element, ...elements] : elements.slice();\n return this;\n }\n /** Gets the scrollable parents that are registered with this drop container. */\n getScrollableParents() {\n return this._scrollableElements;\n }\n /**\n * Figures out the index of an item in the container.\n * @param item Item whose index should be determined.\n */\n getItemIndex(item) {\n return this._isDragging\n ? this._sortStrategy.getItemIndex(item)\n : this._draggables.indexOf(item);\n }\n /**\n * Whether the list is able to receive the item that\n * is currently being dragged inside a connected drop list.\n */\n isReceiving() {\n return this._activeSiblings.size > 0;\n }\n /**\n * Sorts an item inside the container based on its position.\n * @param item Item to be sorted.\n * @param pointerX Position of the item along the X axis.\n * @param pointerY Position of the item along the Y axis.\n * @param pointerDelta Direction in which the pointer is moving along each axis.\n */\n _sortItem(item, pointerX, pointerY, pointerDelta) {\n // Don't sort the item if sorting is disabled or it's out of range.\n if (this.sortingDisabled ||\n !this._clientRect ||\n !isPointerNearClientRect(this._clientRect, DROP_PROXIMITY_THRESHOLD, pointerX, pointerY)) {\n return;\n }\n const result = this._sortStrategy.sort(item, pointerX, pointerY, pointerDelta);\n if (result) {\n this.sorted.next({\n previousIndex: result.previousIndex,\n currentIndex: result.currentIndex,\n container: this,\n item,\n });\n }\n }\n /**\n * Checks whether the user's pointer is close to the edges of either the\n * viewport or the drop list and starts the auto-scroll sequence.\n * @param pointerX User's pointer position along the x axis.\n * @param pointerY User's pointer position along the y axis.\n */\n _startScrollingIfNecessary(pointerX, pointerY) {\n if (this.autoScrollDisabled) {\n return;\n }\n let scrollNode;\n let verticalScrollDirection = 0 /* AutoScrollVerticalDirection.NONE */;\n let horizontalScrollDirection = 0 /* AutoScrollHorizontalDirection.NONE */;\n // Check whether we should start scrolling any of the parent containers.\n this._parentPositions.positions.forEach((position, element) => {\n // We have special handling for the `document` below. Also this would be\n // nicer with a for...of loop, but it requires changing a compiler flag.\n if (element === this._document || !position.clientRect || scrollNode) {\n return;\n }\n if (isPointerNearClientRect(position.clientRect, DROP_PROXIMITY_THRESHOLD, pointerX, pointerY)) {\n [verticalScrollDirection, horizontalScrollDirection] = getElementScrollDirections(element, position.clientRect, pointerX, pointerY);\n if (verticalScrollDirection || horizontalScrollDirection) {\n scrollNode = element;\n }\n }\n });\n // Otherwise check if we can start scrolling the viewport.\n if (!verticalScrollDirection && !horizontalScrollDirection) {\n const { width, height } = this._viewportRuler.getViewportSize();\n const clientRect = {\n width,\n height,\n top: 0,\n right: width,\n bottom: height,\n left: 0,\n };\n verticalScrollDirection = getVerticalScrollDirection(clientRect, pointerY);\n horizontalScrollDirection = getHorizontalScrollDirection(clientRect, pointerX);\n scrollNode = window;\n }\n if (scrollNode &&\n (verticalScrollDirection !== this._verticalScrollDirection ||\n horizontalScrollDirection !== this._horizontalScrollDirection ||\n scrollNode !== this._scrollNode)) {\n this._verticalScrollDirection = verticalScrollDirection;\n this._horizontalScrollDirection = horizontalScrollDirection;\n this._scrollNode = scrollNode;\n if ((verticalScrollDirection || horizontalScrollDirection) && scrollNode) {\n this._ngZone.runOutsideAngular(this._startScrollInterval);\n }\n else {\n this._stopScrolling();\n }\n }\n }\n /** Stops any currently-running auto-scroll sequences. */\n _stopScrolling() {\n this._stopScrollTimers.next();\n }\n /** Starts the dragging sequence within the list. */\n _draggingStarted() {\n const styles = coerceElement(this.element).style;\n this.beforeStarted.next();\n this._isDragging = true;\n // We need to disable scroll snapping while the user is dragging, because it breaks automatic\n // scrolling. The browser seems to round the value based on the snapping points which means\n // that we can't increment/decrement the scroll position.\n this._initialScrollSnap = styles.msScrollSnapType || styles.scrollSnapType || '';\n styles.scrollSnapType = styles.msScrollSnapType = 'none';\n this._sortStrategy.start(this._draggables);\n this._cacheParentPositions();\n this._viewportScrollSubscription.unsubscribe();\n this._listenToScrollEvents();\n }\n /** Caches the positions of the configured scrollable parents. */\n _cacheParentPositions() {\n const element = coerceElement(this.element);\n this._parentPositions.cache(this._scrollableElements);\n // The list element is always in the `scrollableElements`\n // so we can take advantage of the cached `ClientRect`.\n this._clientRect = this._parentPositions.positions.get(element).clientRect;\n }\n /** Resets the container to its initial state. */\n _reset() {\n this._isDragging = false;\n const styles = coerceElement(this.element).style;\n styles.scrollSnapType = styles.msScrollSnapType = this._initialScrollSnap;\n this._siblings.forEach(sibling => sibling._stopReceiving(this));\n this._sortStrategy.reset();\n this._stopScrolling();\n this._viewportScrollSubscription.unsubscribe();\n this._parentPositions.clear();\n }\n /**\n * Checks whether the user's pointer is positioned over the container.\n * @param x Pointer position along the X axis.\n * @param y Pointer position along the Y axis.\n */\n _isOverContainer(x, y) {\n return this._clientRect != null && isInsideClientRect(this._clientRect, x, y);\n }\n /**\n * Figures out whether an item should be moved into a sibling\n * drop container, based on its current position.\n * @param item Drag item that is being moved.\n * @param x Position of the item along the X axis.\n * @param y Position of the item along the Y axis.\n */\n _getSiblingContainerFromPosition(item, x, y) {\n return this._siblings.find(sibling => sibling._canReceive(item, x, y));\n }\n /**\n * Checks whether the drop list can receive the passed-in item.\n * @param item Item that is being dragged into the list.\n * @param x Position of the item along the X axis.\n * @param y Position of the item along the Y axis.\n */\n _canReceive(item, x, y) {\n if (!this._clientRect ||\n !isInsideClientRect(this._clientRect, x, y) ||\n !this.enterPredicate(item, this)) {\n return false;\n }\n const elementFromPoint = this._getShadowRoot().elementFromPoint(x, y);\n // If there's no element at the pointer position, then\n // the client rect is probably scrolled out of the view.\n if (!elementFromPoint) {\n return false;\n }\n const nativeElement = coerceElement(this.element);\n // The `ClientRect`, that we're using to find the container over which the user is\n // hovering, doesn't give us any information on whether the element has been scrolled\n // out of the view or whether it's overlapping with other containers. This means that\n // we could end up transferring the item into a container that's invisible or is positioned\n // below another one. We use the result from `elementFromPoint` to get the top-most element\n // at the pointer position and to find whether it's one of the intersecting drop containers.\n return elementFromPoint === nativeElement || nativeElement.contains(elementFromPoint);\n }\n /**\n * Called by one of the connected drop lists when a dragging sequence has started.\n * @param sibling Sibling in which dragging has started.\n */\n _startReceiving(sibling, items) {\n const activeSiblings = this._activeSiblings;\n if (!activeSiblings.has(sibling) &&\n items.every(item => {\n // Note that we have to add an exception to the `enterPredicate` for items that started off\n // in this drop list. The drag ref has logic that allows an item to return to its initial\n // container, if it has left the initial container and none of the connected containers\n // allow it to enter. See `DragRef._updateActiveDropContainer` for more context.\n return this.enterPredicate(item, this) || this._draggables.indexOf(item) > -1;\n })) {\n activeSiblings.add(sibling);\n this._cacheParentPositions();\n this._listenToScrollEvents();\n this.receivingStarted.next({\n initiator: sibling,\n receiver: this,\n items,\n });\n }\n }\n /**\n * Called by a connected drop list when dragging has stopped.\n * @param sibling Sibling whose dragging has stopped.\n */\n _stopReceiving(sibling) {\n this._activeSiblings.delete(sibling);\n this._viewportScrollSubscription.unsubscribe();\n this.receivingStopped.next({ initiator: sibling, receiver: this });\n }\n /**\n * Starts listening to scroll events on the viewport.\n * Used for updating the internal state of the list.\n */\n _listenToScrollEvents() {\n this._viewportScrollSubscription = this._dragDropRegistry\n .scrolled(this._getShadowRoot())\n .subscribe(event => {\n if (this.isDragging()) {\n const scrollDifference = this._parentPositions.handleScroll(event);\n if (scrollDifference) {\n this._sortStrategy.updateOnScroll(scrollDifference.top, scrollDifference.left);\n }\n }\n else if (this.isReceiving()) {\n this._cacheParentPositions();\n }\n });\n }\n /**\n * Lazily resolves and returns the shadow root of the element. We do this in a function, rather\n * than saving it in property directly on init, because we want to resolve it as late as possible\n * in order to ensure that the element has been moved into the shadow DOM. Doing it inside the\n * constructor might be too early if the element is inside of something like `ngFor` or `ngIf`.\n */\n _getShadowRoot() {\n if (!this._cachedShadowRoot) {\n const shadowRoot = _getShadowRoot(coerceElement(this.element));\n this._cachedShadowRoot = (shadowRoot || this._document);\n }\n return this._cachedShadowRoot;\n }\n /** Notifies any siblings that may potentially receive the item. */\n _notifyReceivingSiblings() {\n const draggedItems = this._sortStrategy\n .getActiveItemsSnapshot()\n .filter(item => item.isDragging());\n this._siblings.forEach(sibling => sibling._startReceiving(this, draggedItems));\n }\n}\n/**\n * Gets whether the vertical auto-scroll direction of a node.\n * @param clientRect Dimensions of the node.\n * @param pointerY Position of the user's pointer along the y axis.\n */\nfunction getVerticalScrollDirection(clientRect, pointerY) {\n const { top, bottom, height } = clientRect;\n const yThreshold = height * SCROLL_PROXIMITY_THRESHOLD;\n if (pointerY >= top - yThreshold && pointerY <= top + yThreshold) {\n return 1 /* AutoScrollVerticalDirection.UP */;\n }\n else if (pointerY >= bottom - yThreshold && pointerY <= bottom + yThreshold) {\n return 2 /* AutoScrollVerticalDirection.DOWN */;\n }\n return 0 /* AutoScrollVerticalDirection.NONE */;\n}\n/**\n * Gets whether the horizontal auto-scroll direction of a node.\n * @param clientRect Dimensions of the node.\n * @param pointerX Position of the user's pointer along the x axis.\n */\nfunction getHorizontalScrollDirection(clientRect, pointerX) {\n const { left, right, width } = clientRect;\n const xThreshold = width * SCROLL_PROXIMITY_THRESHOLD;\n if (pointerX >= left - xThreshold && pointerX <= left + xThreshold) {\n return 1 /* AutoScrollHorizontalDirection.LEFT */;\n }\n else if (pointerX >= right - xThreshold && pointerX <= right + xThreshold) {\n return 2 /* AutoScrollHorizontalDirection.RIGHT */;\n }\n return 0 /* AutoScrollHorizontalDirection.NONE */;\n}\n/**\n * Gets the directions in which an element node should be scrolled,\n * assuming that the user's pointer is already within it scrollable region.\n * @param element Element for which we should calculate the scroll direction.\n * @param clientRect Bounding client rectangle of the element.\n * @param pointerX Position of the user's pointer along the x axis.\n * @param pointerY Position of the user's pointer along the y axis.\n */\nfunction getElementScrollDirections(element, clientRect, pointerX, pointerY) {\n const computedVertical = getVerticalScrollDirection(clientRect, pointerY);\n const computedHorizontal = getHorizontalScrollDirection(clientRect, pointerX);\n let verticalScrollDirection = 0 /* AutoScrollVerticalDirection.NONE */;\n let horizontalScrollDirection = 0 /* AutoScrollHorizontalDirection.NONE */;\n // Note that we here we do some extra checks for whether the element is actually scrollable in\n // a certain direction and we only assign the scroll direction if it is. We do this so that we\n // can allow other elements to be scrolled, if the current element can't be scrolled anymore.\n // This allows us to handle cases where the scroll regions of two scrollable elements overlap.\n if (computedVertical) {\n const scrollTop = element.scrollTop;\n if (computedVertical === 1 /* AutoScrollVerticalDirection.UP */) {\n if (scrollTop > 0) {\n verticalScrollDirection = 1 /* AutoScrollVerticalDirection.UP */;\n }\n }\n else if (element.scrollHeight - scrollTop > element.clientHeight) {\n verticalScrollDirection = 2 /* AutoScrollVerticalDirection.DOWN */;\n }\n }\n if (computedHorizontal) {\n const scrollLeft = element.scrollLeft;\n if (computedHorizontal === 1 /* AutoScrollHorizontalDirection.LEFT */) {\n if (scrollLeft > 0) {\n horizontalScrollDirection = 1 /* AutoScrollHorizontalDirection.LEFT */;\n }\n }\n else if (element.scrollWidth - scrollLeft > element.clientWidth) {\n horizontalScrollDirection = 2 /* AutoScrollHorizontalDirection.RIGHT */;\n }\n }\n return [verticalScrollDirection, horizontalScrollDirection];\n}\n\n/** Event options that can be used to bind an active, capturing event. */\nconst activeCapturingEventOptions = normalizePassiveListenerOptions({\n passive: false,\n capture: true,\n});\n/**\n * Service that keeps track of all the drag item and drop container\n * instances, and manages global event listeners on the `document`.\n * @docs-private\n */\n// Note: this class is generic, rather than referencing CdkDrag and CdkDropList directly, in order\n// to avoid circular imports. If we were to reference them here, importing the registry into the\n// classes that are registering themselves will introduce a circular import.\nclass DragDropRegistry {\n constructor(_ngZone, _document) {\n this._ngZone = _ngZone;\n /** Registered drop container instances. */\n this._dropInstances = new Set();\n /** Registered drag item instances. */\n this._dragInstances = new Set();\n /** Drag item instances that are currently being dragged. */\n this._activeDragInstances = [];\n /** Keeps track of the event listeners that we've bound to the `document`. */\n this._globalListeners = new Map();\n /**\n * Predicate function to check if an item is being dragged. Moved out into a property,\n * because it'll be called a lot and we don't want to create a new function every time.\n */\n this._draggingPredicate = (item) => item.isDragging();\n /**\n * Emits the `touchmove` or `mousemove` events that are dispatched\n * while the user is dragging a drag item instance.\n */\n this.pointerMove = new Subject();\n /**\n * Emits the `touchend` or `mouseup` events that are dispatched\n * while the user is dragging a drag item instance.\n */\n this.pointerUp = new Subject();\n /**\n * Emits when the viewport has been scrolled while the user is dragging an item.\n * @deprecated To be turned into a private member. Use the `scrolled` method instead.\n * @breaking-change 13.0.0\n */\n this.scroll = new Subject();\n /**\n * Event listener that will prevent the default browser action while the user is dragging.\n * @param event Event whose default action should be prevented.\n */\n this._preventDefaultWhileDragging = (event) => {\n if (this._activeDragInstances.length > 0) {\n event.preventDefault();\n }\n };\n /** Event listener for `touchmove` that is bound even if no dragging is happening. */\n this._persistentTouchmoveListener = (event) => {\n if (this._activeDragInstances.length > 0) {\n // Note that we only want to prevent the default action after dragging has actually started.\n // Usually this is the same time at which the item is added to the `_activeDragInstances`,\n // but it could be pushed back if the user has set up a drag delay or threshold.\n if (this._activeDragInstances.some(this._draggingPredicate)) {\n event.preventDefault();\n }\n this.pointerMove.next(event);\n }\n };\n this._document = _document;\n }\n /** Adds a drop container to the registry. */\n registerDropContainer(drop) {\n if (!this._dropInstances.has(drop)) {\n this._dropInstances.add(drop);\n }\n }\n /** Adds a drag item instance to the registry. */\n registerDragItem(drag) {\n this._dragInstances.add(drag);\n // The `touchmove` event gets bound once, ahead of time, because WebKit\n // won't preventDefault on a dynamically-added `touchmove` listener.\n // See https://bugs.webkit.org/show_bug.cgi?id=184250.\n if (this._dragInstances.size === 1) {\n this._ngZone.runOutsideAngular(() => {\n // The event handler has to be explicitly active,\n // because newer browsers make it passive by default.\n this._document.addEventListener('touchmove', this._persistentTouchmoveListener, activeCapturingEventOptions);\n });\n }\n }\n /** Removes a drop container from the registry. */\n removeDropContainer(drop) {\n this._dropInstances.delete(drop);\n }\n /** Removes a drag item instance from the registry. */\n removeDragItem(drag) {\n this._dragInstances.delete(drag);\n this.stopDragging(drag);\n if (this._dragInstances.size === 0) {\n this._document.removeEventListener('touchmove', this._persistentTouchmoveListener, activeCapturingEventOptions);\n }\n }\n /**\n * Starts the dragging sequence for a drag instance.\n * @param drag Drag instance which is being dragged.\n * @param event Event that initiated the dragging.\n */\n startDragging(drag, event) {\n // Do not process the same drag twice to avoid memory leaks and redundant listeners\n if (this._activeDragInstances.indexOf(drag) > -1) {\n return;\n }\n this._activeDragInstances.push(drag);\n if (this._activeDragInstances.length === 1) {\n const isTouchEvent = event.type.startsWith('touch');\n // We explicitly bind __active__ listeners here, because newer browsers will default to\n // passive ones for `mousemove` and `touchmove`. The events need to be active, because we\n // use `preventDefault` to prevent the page from scrolling while the user is dragging.\n this._globalListeners\n .set(isTouchEvent ? 'touchend' : 'mouseup', {\n handler: (e) => this.pointerUp.next(e),\n options: true,\n })\n .set('scroll', {\n handler: (e) => this.scroll.next(e),\n // Use capturing so that we pick up scroll changes in any scrollable nodes that aren't\n // the document. See https://github.com/angular/components/issues/17144.\n options: true,\n })\n // Preventing the default action on `mousemove` isn't enough to disable text selection\n // on Safari so we need to prevent the selection event as well. Alternatively this can\n // be done by setting `user-select: none` on the `body`, however it has causes a style\n // recalculation which can be expensive on pages with a lot of elements.\n .set('selectstart', {\n handler: this._preventDefaultWhileDragging,\n options: activeCapturingEventOptions,\n });\n // We don't have to bind a move event for touch drag sequences, because\n // we already have a persistent global one bound from `registerDragItem`.\n if (!isTouchEvent) {\n this._globalListeners.set('mousemove', {\n handler: (e) => this.pointerMove.next(e),\n options: activeCapturingEventOptions,\n });\n }\n this._ngZone.runOutsideAngular(() => {\n this._globalListeners.forEach((config, name) => {\n this._document.addEventListener(name, config.handler, config.options);\n });\n });\n }\n }\n /** Stops dragging a drag item instance. */\n stopDragging(drag) {\n const index = this._activeDragInstances.indexOf(drag);\n if (index > -1) {\n this._activeDragInstances.splice(index, 1);\n if (this._activeDragInstances.length === 0) {\n this._clearGlobalListeners();\n }\n }\n }\n /** Gets whether a drag item instance is currently being dragged. */\n isDragging(drag) {\n return this._activeDragInstances.indexOf(drag) > -1;\n }\n /**\n * Gets a stream that will emit when any element on the page is scrolled while an item is being\n * dragged.\n * @param shadowRoot Optional shadow root that the current dragging sequence started from.\n * Top-level listeners won't pick up events coming from the shadow DOM so this parameter can\n * be used to include an additional top-level listener at the shadow root level.\n */\n scrolled(shadowRoot) {\n const streams = [this.scroll];\n if (shadowRoot && shadowRoot !== this._document) {\n // Note that this is basically the same as `fromEvent` from rxjs, but we do it ourselves,\n // because we want to guarantee that the event is bound outside of the `NgZone`. With\n // `fromEvent` it'll only happen if the subscription is outside the `NgZone`.\n streams.push(new Observable((observer) => {\n return this._ngZone.runOutsideAngular(() => {\n const eventOptions = true;\n const callback = (event) => {\n if (this._activeDragInstances.length) {\n observer.next(event);\n }\n };\n shadowRoot.addEventListener('scroll', callback, eventOptions);\n return () => {\n shadowRoot.removeEventListener('scroll', callback, eventOptions);\n };\n });\n }));\n }\n return merge(...streams);\n }\n ngOnDestroy() {\n this._dragInstances.forEach(instance => this.removeDragItem(instance));\n this._dropInstances.forEach(instance => this.removeDropContainer(instance));\n this._clearGlobalListeners();\n this.pointerMove.complete();\n this.pointerUp.complete();\n }\n /** Clears out the global event listeners from the `document`. */\n _clearGlobalListeners() {\n this._globalListeners.forEach((config, name) => {\n this._document.removeEventListener(name, config.handler, config.options);\n });\n this._globalListeners.clear();\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: DragDropRegistry, deps: [{ token: i0.NgZone }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }\n static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: DragDropRegistry, providedIn: 'root' }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: DragDropRegistry, decorators: [{\n type: Injectable,\n args: [{ providedIn: 'root' }]\n }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: undefined, decorators: [{\n type: Inject,\n args: [DOCUMENT]\n }] }]; } });\n\n/** Default configuration to be used when creating a `DragRef`. */\nconst DEFAULT_CONFIG = {\n dragStartThreshold: 5,\n pointerDirectionChangeThreshold: 5,\n};\n/**\n * Service that allows for drag-and-drop functionality to be attached to DOM elements.\n */\nclass DragDrop {\n constructor(_document, _ngZone, _viewportRuler, _dragDropRegistry) {\n this._document = _document;\n this._ngZone = _ngZone;\n this._viewportRuler = _viewportRuler;\n this._dragDropRegistry = _dragDropRegistry;\n }\n /**\n * Turns an element into a draggable item.\n * @param element Element to which to attach the dragging functionality.\n * @param config Object used to configure the dragging behavior.\n */\n createDrag(element, config = DEFAULT_CONFIG) {\n return new DragRef(element, config, this._document, this._ngZone, this._viewportRuler, this._dragDropRegistry);\n }\n /**\n * Turns an element into a drop list.\n * @param element Element to which to attach the drop list functionality.\n */\n createDropList(element) {\n return new DropListRef(element, this._dragDropRegistry, this._document, this._ngZone, this._viewportRuler);\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: DragDrop, deps: [{ token: DOCUMENT }, { token: i0.NgZone }, { token: i1.ViewportRuler }, { token: DragDropRegistry }], target: i0.ɵɵFactoryTarget.Injectable }); }\n static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: DragDrop, providedIn: 'root' }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: DragDrop, decorators: [{\n type: Injectable,\n args: [{ providedIn: 'root' }]\n }], ctorParameters: function () { return [{ type: undefined, decorators: [{\n type: Inject,\n args: [DOCUMENT]\n }] }, { type: i0.NgZone }, { type: i1.ViewportRuler }, { type: DragDropRegistry }]; } });\n\n/**\n * Injection token that can be used for a `CdkDrag` to provide itself as a parent to the\n * drag-specific child directive (`CdkDragHandle`, `CdkDragPreview` etc.). Used primarily\n * to avoid circular imports.\n * @docs-private\n */\nconst CDK_DRAG_PARENT = new InjectionToken('CDK_DRAG_PARENT');\n\n/**\n * Asserts that a particular node is an element.\n * @param node Node to be checked.\n * @param name Name to attach to the error message.\n */\nfunction assertElementNode(node, name) {\n if (node.nodeType !== 1) {\n throw Error(`${name} must be attached to an element node. ` + `Currently attached to \"${node.nodeName}\".`);\n }\n}\n\n/**\n * Injection token that can be used to reference instances of `CdkDragHandle`. It serves as\n * alternative token to the actual `CdkDragHandle` class which could cause unnecessary\n * retention of the class and its directive metadata.\n */\nconst CDK_DRAG_HANDLE = new InjectionToken('CdkDragHandle');\n/** Handle that can be used to drag a CdkDrag instance. */\nclass CdkDragHandle {\n /** Whether starting to drag through this handle is disabled. */\n get disabled() {\n return this._disabled;\n }\n set disabled(value) {\n this._disabled = coerceBooleanProperty(value);\n this._stateChanges.next(this);\n }\n constructor(element, parentDrag) {\n this.element = element;\n /** Emits when the state of the handle has changed. */\n this._stateChanges = new Subject();\n this._disabled = false;\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n assertElementNode(element.nativeElement, 'cdkDragHandle');\n }\n this._parentDrag = parentDrag;\n }\n ngOnDestroy() {\n this._stateChanges.complete();\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkDragHandle, deps: [{ token: i0.ElementRef }, { token: CDK_DRAG_PARENT, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.Directive }); }\n static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: \"14.0.0\", version: \"16.1.1\", type: CdkDragHandle, isStandalone: true, selector: \"[cdkDragHandle]\", inputs: { disabled: [\"cdkDragHandleDisabled\", \"disabled\"] }, host: { classAttribute: \"cdk-drag-handle\" }, providers: [{ provide: CDK_DRAG_HANDLE, useExisting: CdkDragHandle }], ngImport: i0 }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkDragHandle, decorators: [{\n type: Directive,\n args: [{\n selector: '[cdkDragHandle]',\n standalone: true,\n host: {\n 'class': 'cdk-drag-handle',\n },\n providers: [{ provide: CDK_DRAG_HANDLE, useExisting: CdkDragHandle }],\n }]\n }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: undefined, decorators: [{\n type: Inject,\n args: [CDK_DRAG_PARENT]\n }, {\n type: Optional\n }, {\n type: SkipSelf\n }] }]; }, propDecorators: { disabled: [{\n type: Input,\n args: ['cdkDragHandleDisabled']\n }] } });\n\n/**\n * Injection token that can be used to reference instances of `CdkDragPlaceholder`. It serves as\n * alternative token to the actual `CdkDragPlaceholder` class which could cause unnecessary\n * retention of the class and its directive metadata.\n */\nconst CDK_DRAG_PLACEHOLDER = new InjectionToken('CdkDragPlaceholder');\n/**\n * Element that will be used as a template for the placeholder of a CdkDrag when\n * it is being dragged. The placeholder is displayed in place of the element being dragged.\n */\nclass CdkDragPlaceholder {\n constructor(templateRef) {\n this.templateRef = templateRef;\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkDragPlaceholder, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }\n static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: \"14.0.0\", version: \"16.1.1\", type: CdkDragPlaceholder, isStandalone: true, selector: \"ng-template[cdkDragPlaceholder]\", inputs: { data: \"data\" }, providers: [{ provide: CDK_DRAG_PLACEHOLDER, useExisting: CdkDragPlaceholder }], ngImport: i0 }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkDragPlaceholder, decorators: [{\n type: Directive,\n args: [{\n selector: 'ng-template[cdkDragPlaceholder]',\n standalone: true,\n providers: [{ provide: CDK_DRAG_PLACEHOLDER, useExisting: CdkDragPlaceholder }],\n }]\n }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; }, propDecorators: { data: [{\n type: Input\n }] } });\n\n/**\n * Injection token that can be used to reference instances of `CdkDragPreview`. It serves as\n * alternative token to the actual `CdkDragPreview` class which could cause unnecessary\n * retention of the class and its directive metadata.\n */\nconst CDK_DRAG_PREVIEW = new InjectionToken('CdkDragPreview');\n/**\n * Element that will be used as a template for the preview\n * of a CdkDrag when it is being dragged.\n */\nclass CdkDragPreview {\n /** Whether the preview should preserve the same size as the item that is being dragged. */\n get matchSize() {\n return this._matchSize;\n }\n set matchSize(value) {\n this._matchSize = coerceBooleanProperty(value);\n }\n constructor(templateRef) {\n this.templateRef = templateRef;\n this._matchSize = false;\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkDragPreview, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }\n static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: \"14.0.0\", version: \"16.1.1\", type: CdkDragPreview, isStandalone: true, selector: \"ng-template[cdkDragPreview]\", inputs: { data: \"data\", matchSize: \"matchSize\" }, providers: [{ provide: CDK_DRAG_PREVIEW, useExisting: CdkDragPreview }], ngImport: i0 }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkDragPreview, decorators: [{\n type: Directive,\n args: [{\n selector: 'ng-template[cdkDragPreview]',\n standalone: true,\n providers: [{ provide: CDK_DRAG_PREVIEW, useExisting: CdkDragPreview }],\n }]\n }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; }, propDecorators: { data: [{\n type: Input\n }], matchSize: [{\n type: Input\n }] } });\n\n/**\n * Injection token that can be used to configure the\n * behavior of the drag&drop-related components.\n */\nconst CDK_DRAG_CONFIG = new InjectionToken('CDK_DRAG_CONFIG');\n\nconst DRAG_HOST_CLASS = 'cdk-drag';\n/**\n * Injection token that can be used to reference instances of `CdkDropList`. It serves as\n * alternative token to the actual `CdkDropList` class which could cause unnecessary\n * retention of the class and its directive metadata.\n */\nconst CDK_DROP_LIST = new InjectionToken('CdkDropList');\n/** Element that can be moved inside a CdkDropList container. */\nclass CdkDrag {\n static { this._dragInstances = []; }\n /** Whether starting to drag this element is disabled. */\n get disabled() {\n return this._disabled || (this.dropContainer && this.dropContainer.disabled);\n }\n set disabled(value) {\n this._disabled = coerceBooleanProperty(value);\n this._dragRef.disabled = this._disabled;\n }\n constructor(\n /** Element that the draggable is attached to. */\n element, \n /** Droppable container that the draggable is a part of. */\n dropContainer, \n /**\n * @deprecated `_document` parameter no longer being used and will be removed.\n * @breaking-change 12.0.0\n */\n _document, _ngZone, _viewContainerRef, config, _dir, dragDrop, _changeDetectorRef, _selfHandle, _parentDrag) {\n this.element = element;\n this.dropContainer = dropContainer;\n this._ngZone = _ngZone;\n this._viewContainerRef = _viewContainerRef;\n this._dir = _dir;\n this._changeDetectorRef = _changeDetectorRef;\n this._selfHandle = _selfHandle;\n this._parentDrag = _parentDrag;\n this._destroyed = new Subject();\n /** Emits when the user starts dragging the item. */\n this.started = new EventEmitter();\n /** Emits when the user has released a drag item, before any animations have started. */\n this.released = new EventEmitter();\n /** Emits when the user stops dragging an item in the container. */\n this.ended = new EventEmitter();\n /** Emits when the user has moved the item into a new container. */\n this.entered = new EventEmitter();\n /** Emits when the user removes the item its container by dragging it into another container. */\n this.exited = new EventEmitter();\n /** Emits when the user drops the item inside a container. */\n this.dropped = new EventEmitter();\n /**\n * Emits as the user is dragging the item. Use with caution,\n * because this event will fire for every pixel that the user has dragged.\n */\n this.moved = new Observable((observer) => {\n const subscription = this._dragRef.moved\n .pipe(map(movedEvent => ({\n source: this,\n pointerPosition: movedEvent.pointerPosition,\n event: movedEvent.event,\n delta: movedEvent.delta,\n distance: movedEvent.distance,\n })))\n .subscribe(observer);\n return () => {\n subscription.unsubscribe();\n };\n });\n this._dragRef = dragDrop.createDrag(element, {\n dragStartThreshold: config && config.dragStartThreshold != null ? config.dragStartThreshold : 5,\n pointerDirectionChangeThreshold: config && config.pointerDirectionChangeThreshold != null\n ? config.pointerDirectionChangeThreshold\n : 5,\n zIndex: config?.zIndex,\n });\n this._dragRef.data = this;\n // We have to keep track of the drag instances in order to be able to match an element to\n // a drag instance. We can't go through the global registry of `DragRef`, because the root\n // element could be different.\n CdkDrag._dragInstances.push(this);\n if (config) {\n this._assignDefaults(config);\n }\n // Note that usually the container is assigned when the drop list is picks up the item, but in\n // some cases (mainly transplanted views with OnPush, see #18341) we may end up in a situation\n // where there are no items on the first change detection pass, but the items get picked up as\n // soon as the user triggers another pass by dragging. This is a problem, because the item would\n // have to switch from standalone mode to drag mode in the middle of the dragging sequence which\n // is too late since the two modes save different kinds of information. We work around it by\n // assigning the drop container both from here and the list.\n if (dropContainer) {\n this._dragRef._withDropContainer(dropContainer._dropListRef);\n dropContainer.addItem(this);\n }\n this._syncInputs(this._dragRef);\n this._handleEvents(this._dragRef);\n }\n /**\n * Returns the element that is being used as a placeholder\n * while the current element is being dragged.\n */\n getPlaceholderElement() {\n return this._dragRef.getPlaceholderElement();\n }\n /** Returns the root draggable element. */\n getRootElement() {\n return this._dragRef.getRootElement();\n }\n /** Resets a standalone drag item to its initial position. */\n reset() {\n this._dragRef.reset();\n }\n /**\n * Gets the pixel coordinates of the draggable outside of a drop container.\n */\n getFreeDragPosition() {\n return this._dragRef.getFreeDragPosition();\n }\n /**\n * Sets the current position in pixels the draggable outside of a drop container.\n * @param value New position to be set.\n */\n setFreeDragPosition(value) {\n this._dragRef.setFreeDragPosition(value);\n }\n ngAfterViewInit() {\n // Normally this isn't in the zone, but it can cause major performance regressions for apps\n // using `zone-patch-rxjs` because it'll trigger a change detection when it unsubscribes.\n this._ngZone.runOutsideAngular(() => {\n // We need to wait for the zone to stabilize, in order for the reference\n // element to be in the proper place in the DOM. This is mostly relevant\n // for draggable elements inside portals since they get stamped out in\n // their original DOM position and then they get transferred to the portal.\n this._ngZone.onStable.pipe(take(1), takeUntil(this._destroyed)).subscribe(() => {\n this._updateRootElement();\n this._setupHandlesListener();\n if (this.freeDragPosition) {\n this._dragRef.setFreeDragPosition(this.freeDragPosition);\n }\n });\n });\n }\n ngOnChanges(changes) {\n const rootSelectorChange = changes['rootElementSelector'];\n const positionChange = changes['freeDragPosition'];\n // We don't have to react to the first change since it's being\n // handled in `ngAfterViewInit` where it needs to be deferred.\n if (rootSelectorChange && !rootSelectorChange.firstChange) {\n this._updateRootElement();\n }\n // Skip the first change since it's being handled in `ngAfterViewInit`.\n if (positionChange && !positionChange.firstChange && this.freeDragPosition) {\n this._dragRef.setFreeDragPosition(this.freeDragPosition);\n }\n }\n ngOnDestroy() {\n if (this.dropContainer) {\n this.dropContainer.removeItem(this);\n }\n const index = CdkDrag._dragInstances.indexOf(this);\n if (index > -1) {\n CdkDrag._dragInstances.splice(index, 1);\n }\n // Unnecessary in most cases, but used to avoid extra change detections with `zone-paths-rxjs`.\n this._ngZone.runOutsideAngular(() => {\n this._destroyed.next();\n this._destroyed.complete();\n this._dragRef.dispose();\n });\n }\n /** Syncs the root element with the `DragRef`. */\n _updateRootElement() {\n const element = this.element.nativeElement;\n let rootElement = element;\n if (this.rootElementSelector) {\n rootElement =\n element.closest !== undefined\n ? element.closest(this.rootElementSelector)\n : // Comment tag doesn't have closest method, so use parent's one.\n element.parentElement?.closest(this.rootElementSelector);\n }\n if (rootElement && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n assertElementNode(rootElement, 'cdkDrag');\n }\n this._dragRef.withRootElement(rootElement || element);\n }\n /** Gets the boundary element, based on the `boundaryElement` value. */\n _getBoundaryElement() {\n const boundary = this.boundaryElement;\n if (!boundary) {\n return null;\n }\n if (typeof boundary === 'string') {\n return this.element.nativeElement.closest(boundary);\n }\n return coerceElement(boundary);\n }\n /** Syncs the inputs of the CdkDrag with the options of the underlying DragRef. */\n _syncInputs(ref) {\n ref.beforeStarted.subscribe(() => {\n if (!ref.isDragging()) {\n const dir = this._dir;\n const dragStartDelay = this.dragStartDelay;\n const placeholder = this._placeholderTemplate\n ? {\n template: this._placeholderTemplate.templateRef,\n context: this._placeholderTemplate.data,\n viewContainer: this._viewContainerRef,\n }\n : null;\n const preview = this._previewTemplate\n ? {\n template: this._previewTemplate.templateRef,\n context: this._previewTemplate.data,\n matchSize: this._previewTemplate.matchSize,\n viewContainer: this._viewContainerRef,\n }\n : null;\n ref.disabled = this.disabled;\n ref.lockAxis = this.lockAxis;\n ref.dragStartDelay =\n typeof dragStartDelay === 'object' && dragStartDelay\n ? dragStartDelay\n : coerceNumberProperty(dragStartDelay);\n ref.constrainPosition = this.constrainPosition;\n ref.previewClass = this.previewClass;\n ref\n .withBoundaryElement(this._getBoundaryElement())\n .withPlaceholderTemplate(placeholder)\n .withPreviewTemplate(preview)\n .withPreviewContainer(this.previewContainer || 'global');\n if (dir) {\n ref.withDirection(dir.value);\n }\n }\n });\n // This only needs to be resolved once.\n ref.beforeStarted.pipe(take(1)).subscribe(() => {\n // If we managed to resolve a parent through DI, use it.\n if (this._parentDrag) {\n ref.withParent(this._parentDrag._dragRef);\n return;\n }\n // Otherwise fall back to resolving the parent by looking up the DOM. This can happen if\n // the item was projected into another item by something like `ngTemplateOutlet`.\n let parent = this.element.nativeElement.parentElement;\n while (parent) {\n if (parent.classList.contains(DRAG_HOST_CLASS)) {\n ref.withParent(CdkDrag._dragInstances.find(drag => {\n return drag.element.nativeElement === parent;\n })?._dragRef || null);\n break;\n }\n parent = parent.parentElement;\n }\n });\n }\n /** Handles the events from the underlying `DragRef`. */\n _handleEvents(ref) {\n ref.started.subscribe(startEvent => {\n this.started.emit({ source: this, event: startEvent.event });\n // Since all of these events run outside of change detection,\n // we need to ensure that everything is marked correctly.\n this._changeDetectorRef.markForCheck();\n });\n ref.released.subscribe(releaseEvent => {\n this.released.emit({ source: this, event: releaseEvent.event });\n });\n ref.ended.subscribe(endEvent => {\n this.ended.emit({\n source: this,\n distance: endEvent.distance,\n dropPoint: endEvent.dropPoint,\n event: endEvent.event,\n });\n // Since all of these events run outside of change detection,\n // we need to ensure that everything is marked correctly.\n this._changeDetectorRef.markForCheck();\n });\n ref.entered.subscribe(enterEvent => {\n this.entered.emit({\n container: enterEvent.container.data,\n item: this,\n currentIndex: enterEvent.currentIndex,\n });\n });\n ref.exited.subscribe(exitEvent => {\n this.exited.emit({\n container: exitEvent.container.data,\n item: this,\n });\n });\n ref.dropped.subscribe(dropEvent => {\n this.dropped.emit({\n previousIndex: dropEvent.previousIndex,\n currentIndex: dropEvent.currentIndex,\n previousContainer: dropEvent.previousContainer.data,\n container: dropEvent.container.data,\n isPointerOverContainer: dropEvent.isPointerOverContainer,\n item: this,\n distance: dropEvent.distance,\n dropPoint: dropEvent.dropPoint,\n event: dropEvent.event,\n });\n });\n }\n /** Assigns the default input values based on a provided config object. */\n _assignDefaults(config) {\n const { lockAxis, dragStartDelay, constrainPosition, previewClass, boundaryElement, draggingDisabled, rootElementSelector, previewContainer, } = config;\n this.disabled = draggingDisabled == null ? false : draggingDisabled;\n this.dragStartDelay = dragStartDelay || 0;\n if (lockAxis) {\n this.lockAxis = lockAxis;\n }\n if (constrainPosition) {\n this.constrainPosition = constrainPosition;\n }\n if (previewClass) {\n this.previewClass = previewClass;\n }\n if (boundaryElement) {\n this.boundaryElement = boundaryElement;\n }\n if (rootElementSelector) {\n this.rootElementSelector = rootElementSelector;\n }\n if (previewContainer) {\n this.previewContainer = previewContainer;\n }\n }\n /** Sets up the listener that syncs the handles with the drag ref. */\n _setupHandlesListener() {\n // Listen for any newly-added handles.\n this._handles.changes\n .pipe(startWith(this._handles), \n // Sync the new handles with the DragRef.\n tap((handles) => {\n const childHandleElements = handles\n .filter(handle => handle._parentDrag === this)\n .map(handle => handle.element);\n // Usually handles are only allowed to be a descendant of the drag element, but if\n // the consumer defined a different drag root, we should allow the drag element\n // itself to be a handle too.\n if (this._selfHandle && this.rootElementSelector) {\n childHandleElements.push(this.element);\n }\n this._dragRef.withHandles(childHandleElements);\n }), \n // Listen if the state of any of the handles changes.\n switchMap((handles) => {\n return merge(...handles.map(item => {\n return item._stateChanges.pipe(startWith(item));\n }));\n }), takeUntil(this._destroyed))\n .subscribe(handleInstance => {\n // Enabled/disable the handle that changed in the DragRef.\n const dragRef = this._dragRef;\n const handle = handleInstance.element.nativeElement;\n handleInstance.disabled ? dragRef.disableHandle(handle) : dragRef.enableHandle(handle);\n });\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkDrag, deps: [{ token: i0.ElementRef }, { token: CDK_DROP_LIST, optional: true, skipSelf: true }, { token: DOCUMENT }, { token: i0.NgZone }, { token: i0.ViewContainerRef }, { token: CDK_DRAG_CONFIG, optional: true }, { token: i1$1.Directionality, optional: true }, { token: DragDrop }, { token: i0.ChangeDetectorRef }, { token: CDK_DRAG_HANDLE, optional: true, self: true }, { token: CDK_DRAG_PARENT, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.Directive }); }\n static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: \"14.0.0\", version: \"16.1.1\", type: CdkDrag, isStandalone: true, selector: \"[cdkDrag]\", inputs: { data: [\"cdkDragData\", \"data\"], lockAxis: [\"cdkDragLockAxis\", \"lockAxis\"], rootElementSelector: [\"cdkDragRootElement\", \"rootElementSelector\"], boundaryElement: [\"cdkDragBoundary\", \"boundaryElement\"], dragStartDelay: [\"cdkDragStartDelay\", \"dragStartDelay\"], freeDragPosition: [\"cdkDragFreeDragPosition\", \"freeDragPosition\"], disabled: [\"cdkDragDisabled\", \"disabled\"], constrainPosition: [\"cdkDragConstrainPosition\", \"constrainPosition\"], previewClass: [\"cdkDragPreviewClass\", \"previewClass\"], previewContainer: [\"cdkDragPreviewContainer\", \"previewContainer\"] }, outputs: { started: \"cdkDragStarted\", released: \"cdkDragReleased\", ended: \"cdkDragEnded\", entered: \"cdkDragEntered\", exited: \"cdkDragExited\", dropped: \"cdkDragDropped\", moved: \"cdkDragMoved\" }, host: { properties: { \"class.cdk-drag-disabled\": \"disabled\", \"class.cdk-drag-dragging\": \"_dragRef.isDragging()\" }, classAttribute: \"cdk-drag\" }, providers: [{ provide: CDK_DRAG_PARENT, useExisting: CdkDrag }], queries: [{ propertyName: \"_previewTemplate\", first: true, predicate: CDK_DRAG_PREVIEW, descendants: true }, { propertyName: \"_placeholderTemplate\", first: true, predicate: CDK_DRAG_PLACEHOLDER, descendants: true }, { propertyName: \"_handles\", predicate: CDK_DRAG_HANDLE, descendants: true }], exportAs: [\"cdkDrag\"], usesOnChanges: true, ngImport: i0 }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkDrag, decorators: [{\n type: Directive,\n args: [{\n selector: '[cdkDrag]',\n exportAs: 'cdkDrag',\n standalone: true,\n host: {\n 'class': DRAG_HOST_CLASS,\n '[class.cdk-drag-disabled]': 'disabled',\n '[class.cdk-drag-dragging]': '_dragRef.isDragging()',\n },\n providers: [{ provide: CDK_DRAG_PARENT, useExisting: CdkDrag }],\n }]\n }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: undefined, decorators: [{\n type: Inject,\n args: [CDK_DROP_LIST]\n }, {\n type: Optional\n }, {\n type: SkipSelf\n }] }, { type: undefined, decorators: [{\n type: Inject,\n args: [DOCUMENT]\n }] }, { type: i0.NgZone }, { type: i0.ViewContainerRef }, { type: undefined, decorators: [{\n type: Optional\n }, {\n type: Inject,\n args: [CDK_DRAG_CONFIG]\n }] }, { type: i1$1.Directionality, decorators: [{\n type: Optional\n }] }, { type: DragDrop }, { type: i0.ChangeDetectorRef }, { type: CdkDragHandle, decorators: [{\n type: Optional\n }, {\n type: Self\n }, {\n type: Inject,\n args: [CDK_DRAG_HANDLE]\n }] }, { type: CdkDrag, decorators: [{\n type: Optional\n }, {\n type: SkipSelf\n }, {\n type: Inject,\n args: [CDK_DRAG_PARENT]\n }] }]; }, propDecorators: { _handles: [{\n type: ContentChildren,\n args: [CDK_DRAG_HANDLE, { descendants: true }]\n }], _previewTemplate: [{\n type: ContentChild,\n args: [CDK_DRAG_PREVIEW]\n }], _placeholderTemplate: [{\n type: ContentChild,\n args: [CDK_DRAG_PLACEHOLDER]\n }], data: [{\n type: Input,\n args: ['cdkDragData']\n }], lockAxis: [{\n type: Input,\n args: ['cdkDragLockAxis']\n }], rootElementSelector: [{\n type: Input,\n args: ['cdkDragRootElement']\n }], boundaryElement: [{\n type: Input,\n args: ['cdkDragBoundary']\n }], dragStartDelay: [{\n type: Input,\n args: ['cdkDragStartDelay']\n }], freeDragPosition: [{\n type: Input,\n args: ['cdkDragFreeDragPosition']\n }], disabled: [{\n type: Input,\n args: ['cdkDragDisabled']\n }], constrainPosition: [{\n type: Input,\n args: ['cdkDragConstrainPosition']\n }], previewClass: [{\n type: Input,\n args: ['cdkDragPreviewClass']\n }], previewContainer: [{\n type: Input,\n args: ['cdkDragPreviewContainer']\n }], started: [{\n type: Output,\n args: ['cdkDragStarted']\n }], released: [{\n type: Output,\n args: ['cdkDragReleased']\n }], ended: [{\n type: Output,\n args: ['cdkDragEnded']\n }], entered: [{\n type: Output,\n args: ['cdkDragEntered']\n }], exited: [{\n type: Output,\n args: ['cdkDragExited']\n }], dropped: [{\n type: Output,\n args: ['cdkDragDropped']\n }], moved: [{\n type: Output,\n args: ['cdkDragMoved']\n }] } });\n\n/**\n * Injection token that can be used to reference instances of `CdkDropListGroup`. It serves as\n * alternative token to the actual `CdkDropListGroup` class which could cause unnecessary\n * retention of the class and its directive metadata.\n */\nconst CDK_DROP_LIST_GROUP = new InjectionToken('CdkDropListGroup');\n/**\n * Declaratively connects sibling `cdkDropList` instances together. All of the `cdkDropList`\n * elements that are placed inside a `cdkDropListGroup` will be connected to each other\n * automatically. Can be used as an alternative to the `cdkDropListConnectedTo` input\n * from `cdkDropList`.\n */\nclass CdkDropListGroup {\n constructor() {\n /** Drop lists registered inside the group. */\n this._items = new Set();\n this._disabled = false;\n }\n /** Whether starting a dragging sequence from inside this group is disabled. */\n get disabled() {\n return this._disabled;\n }\n set disabled(value) {\n this._disabled = coerceBooleanProperty(value);\n }\n ngOnDestroy() {\n this._items.clear();\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkDropListGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }\n static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: \"14.0.0\", version: \"16.1.1\", type: CdkDropListGroup, isStandalone: true, selector: \"[cdkDropListGroup]\", inputs: { disabled: [\"cdkDropListGroupDisabled\", \"disabled\"] }, providers: [{ provide: CDK_DROP_LIST_GROUP, useExisting: CdkDropListGroup }], exportAs: [\"cdkDropListGroup\"], ngImport: i0 }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkDropListGroup, decorators: [{\n type: Directive,\n args: [{\n selector: '[cdkDropListGroup]',\n exportAs: 'cdkDropListGroup',\n standalone: true,\n providers: [{ provide: CDK_DROP_LIST_GROUP, useExisting: CdkDropListGroup }],\n }]\n }], propDecorators: { disabled: [{\n type: Input,\n args: ['cdkDropListGroupDisabled']\n }] } });\n\n/** Counter used to generate unique ids for drop zones. */\nlet _uniqueIdCounter = 0;\n/** Container that wraps a set of draggable items. */\nclass CdkDropList {\n /** Keeps track of the drop lists that are currently on the page. */\n static { this._dropLists = []; }\n /** Whether starting a dragging sequence from this container is disabled. */\n get disabled() {\n return this._disabled || (!!this._group && this._group.disabled);\n }\n set disabled(value) {\n // Usually we sync the directive and ref state right before dragging starts, in order to have\n // a single point of failure and to avoid having to use setters for everything. `disabled` is\n // a special case, because it can prevent the `beforeStarted` event from firing, which can lock\n // the user in a disabled state, so we also need to sync it as it's being set.\n this._dropListRef.disabled = this._disabled = coerceBooleanProperty(value);\n }\n constructor(\n /** Element that the drop list is attached to. */\n element, dragDrop, _changeDetectorRef, _scrollDispatcher, _dir, _group, config) {\n this.element = element;\n this._changeDetectorRef = _changeDetectorRef;\n this._scrollDispatcher = _scrollDispatcher;\n this._dir = _dir;\n this._group = _group;\n /** Emits when the list has been destroyed. */\n this._destroyed = new Subject();\n /**\n * Other draggable containers that this container is connected to and into which the\n * container's items can be transferred. Can either be references to other drop containers,\n * or their unique IDs.\n */\n this.connectedTo = [];\n /**\n * Unique ID for the drop zone. Can be used as a reference\n * in the `connectedTo` of another `CdkDropList`.\n */\n this.id = `cdk-drop-list-${_uniqueIdCounter++}`;\n /**\n * Function that is used to determine whether an item\n * is allowed to be moved into a drop container.\n */\n this.enterPredicate = () => true;\n /** Functions that is used to determine whether an item can be sorted into a particular index. */\n this.sortPredicate = () => true;\n /** Emits when the user drops an item inside the container. */\n this.dropped = new EventEmitter();\n /**\n * Emits when the user has moved a new drag item into this container.\n */\n this.entered = new EventEmitter();\n /**\n * Emits when the user removes an item from the container\n * by dragging it into another container.\n */\n this.exited = new EventEmitter();\n /** Emits as the user is swapping items while actively dragging. */\n this.sorted = new EventEmitter();\n /**\n * Keeps track of the items that are registered with this container. Historically we used to\n * do this with a `ContentChildren` query, however queries don't handle transplanted views very\n * well which means that we can't handle cases like dragging the headers of a `mat-table`\n * correctly. What we do instead is to have the items register themselves with the container\n * and then we sort them based on their position in the DOM.\n */\n this._unsortedItems = new Set();\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n assertElementNode(element.nativeElement, 'cdkDropList');\n }\n this._dropListRef = dragDrop.createDropList(element);\n this._dropListRef.data = this;\n if (config) {\n this._assignDefaults(config);\n }\n this._dropListRef.enterPredicate = (drag, drop) => {\n return this.enterPredicate(drag.data, drop.data);\n };\n this._dropListRef.sortPredicate = (index, drag, drop) => {\n return this.sortPredicate(index, drag.data, drop.data);\n };\n this._setupInputSyncSubscription(this._dropListRef);\n this._handleEvents(this._dropListRef);\n CdkDropList._dropLists.push(this);\n if (_group) {\n _group._items.add(this);\n }\n }\n /** Registers an items with the drop list. */\n addItem(item) {\n this._unsortedItems.add(item);\n if (this._dropListRef.isDragging()) {\n this._syncItemsWithRef();\n }\n }\n /** Removes an item from the drop list. */\n removeItem(item) {\n this._unsortedItems.delete(item);\n if (this._dropListRef.isDragging()) {\n this._syncItemsWithRef();\n }\n }\n /** Gets the registered items in the list, sorted by their position in the DOM. */\n getSortedItems() {\n return Array.from(this._unsortedItems).sort((a, b) => {\n const documentPosition = a._dragRef\n .getVisibleElement()\n .compareDocumentPosition(b._dragRef.getVisibleElement());\n // `compareDocumentPosition` returns a bitmask so we have to use a bitwise operator.\n // https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition\n // tslint:disable-next-line:no-bitwise\n return documentPosition & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;\n });\n }\n ngOnDestroy() {\n const index = CdkDropList._dropLists.indexOf(this);\n if (index > -1) {\n CdkDropList._dropLists.splice(index, 1);\n }\n if (this._group) {\n this._group._items.delete(this);\n }\n this._unsortedItems.clear();\n this._dropListRef.dispose();\n this._destroyed.next();\n this._destroyed.complete();\n }\n /** Syncs the inputs of the CdkDropList with the options of the underlying DropListRef. */\n _setupInputSyncSubscription(ref) {\n if (this._dir) {\n this._dir.change\n .pipe(startWith(this._dir.value), takeUntil(this._destroyed))\n .subscribe(value => ref.withDirection(value));\n }\n ref.beforeStarted.subscribe(() => {\n const siblings = coerceArray(this.connectedTo).map(drop => {\n if (typeof drop === 'string') {\n const correspondingDropList = CdkDropList._dropLists.find(list => list.id === drop);\n if (!correspondingDropList && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n console.warn(`CdkDropList could not find connected drop list with id \"${drop}\"`);\n }\n return correspondingDropList;\n }\n return drop;\n });\n if (this._group) {\n this._group._items.forEach(drop => {\n if (siblings.indexOf(drop) === -1) {\n siblings.push(drop);\n }\n });\n }\n // Note that we resolve the scrollable parents here so that we delay the resolution\n // as long as possible, ensuring that the element is in its final place in the DOM.\n if (!this._scrollableParentsResolved) {\n const scrollableParents = this._scrollDispatcher\n .getAncestorScrollContainers(this.element)\n .map(scrollable => scrollable.getElementRef().nativeElement);\n this._dropListRef.withScrollableParents(scrollableParents);\n // Only do this once since it involves traversing the DOM and the parents\n // shouldn't be able to change without the drop list being destroyed.\n this._scrollableParentsResolved = true;\n }\n ref.disabled = this.disabled;\n ref.lockAxis = this.lockAxis;\n ref.sortingDisabled = coerceBooleanProperty(this.sortingDisabled);\n ref.autoScrollDisabled = coerceBooleanProperty(this.autoScrollDisabled);\n ref.autoScrollStep = coerceNumberProperty(this.autoScrollStep, 2);\n ref\n .connectedTo(siblings.filter(drop => drop && drop !== this).map(list => list._dropListRef))\n .withOrientation(this.orientation);\n });\n }\n /** Handles events from the underlying DropListRef. */\n _handleEvents(ref) {\n ref.beforeStarted.subscribe(() => {\n this._syncItemsWithRef();\n this._changeDetectorRef.markForCheck();\n });\n ref.entered.subscribe(event => {\n this.entered.emit({\n container: this,\n item: event.item.data,\n currentIndex: event.currentIndex,\n });\n });\n ref.exited.subscribe(event => {\n this.exited.emit({\n container: this,\n item: event.item.data,\n });\n this._changeDetectorRef.markForCheck();\n });\n ref.sorted.subscribe(event => {\n this.sorted.emit({\n previousIndex: event.previousIndex,\n currentIndex: event.currentIndex,\n container: this,\n item: event.item.data,\n });\n });\n ref.dropped.subscribe(dropEvent => {\n this.dropped.emit({\n previousIndex: dropEvent.previousIndex,\n currentIndex: dropEvent.currentIndex,\n previousContainer: dropEvent.previousContainer.data,\n container: dropEvent.container.data,\n item: dropEvent.item.data,\n isPointerOverContainer: dropEvent.isPointerOverContainer,\n distance: dropEvent.distance,\n dropPoint: dropEvent.dropPoint,\n event: dropEvent.event,\n });\n // Mark for check since all of these events run outside of change\n // detection and we're not guaranteed for something else to have triggered it.\n this._changeDetectorRef.markForCheck();\n });\n merge(ref.receivingStarted, ref.receivingStopped).subscribe(() => this._changeDetectorRef.markForCheck());\n }\n /** Assigns the default input values based on a provided config object. */\n _assignDefaults(config) {\n const { lockAxis, draggingDisabled, sortingDisabled, listAutoScrollDisabled, listOrientation } = config;\n this.disabled = draggingDisabled == null ? false : draggingDisabled;\n this.sortingDisabled = sortingDisabled == null ? false : sortingDisabled;\n this.autoScrollDisabled = listAutoScrollDisabled == null ? false : listAutoScrollDisabled;\n this.orientation = listOrientation || 'vertical';\n if (lockAxis) {\n this.lockAxis = lockAxis;\n }\n }\n /** Syncs up the registered drag items with underlying drop list ref. */\n _syncItemsWithRef() {\n this._dropListRef.withItems(this.getSortedItems().map(item => item._dragRef));\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkDropList, deps: [{ token: i0.ElementRef }, { token: DragDrop }, { token: i0.ChangeDetectorRef }, { token: i1.ScrollDispatcher }, { token: i1$1.Directionality, optional: true }, { token: CDK_DROP_LIST_GROUP, optional: true, skipSelf: true }, { token: CDK_DRAG_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }\n static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: \"14.0.0\", version: \"16.1.1\", type: CdkDropList, isStandalone: true, selector: \"[cdkDropList], cdk-drop-list\", inputs: { connectedTo: [\"cdkDropListConnectedTo\", \"connectedTo\"], data: [\"cdkDropListData\", \"data\"], orientation: [\"cdkDropListOrientation\", \"orientation\"], id: \"id\", lockAxis: [\"cdkDropListLockAxis\", \"lockAxis\"], disabled: [\"cdkDropListDisabled\", \"disabled\"], sortingDisabled: [\"cdkDropListSortingDisabled\", \"sortingDisabled\"], enterPredicate: [\"cdkDropListEnterPredicate\", \"enterPredicate\"], sortPredicate: [\"cdkDropListSortPredicate\", \"sortPredicate\"], autoScrollDisabled: [\"cdkDropListAutoScrollDisabled\", \"autoScrollDisabled\"], autoScrollStep: [\"cdkDropListAutoScrollStep\", \"autoScrollStep\"] }, outputs: { dropped: \"cdkDropListDropped\", entered: \"cdkDropListEntered\", exited: \"cdkDropListExited\", sorted: \"cdkDropListSorted\" }, host: { properties: { \"attr.id\": \"id\", \"class.cdk-drop-list-disabled\": \"disabled\", \"class.cdk-drop-list-dragging\": \"_dropListRef.isDragging()\", \"class.cdk-drop-list-receiving\": \"_dropListRef.isReceiving()\" }, classAttribute: \"cdk-drop-list\" }, providers: [\n // Prevent child drop lists from picking up the same group as their parent.\n { provide: CDK_DROP_LIST_GROUP, useValue: undefined },\n { provide: CDK_DROP_LIST, useExisting: CdkDropList },\n ], exportAs: [\"cdkDropList\"], ngImport: i0 }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkDropList, decorators: [{\n type: Directive,\n args: [{\n selector: '[cdkDropList], cdk-drop-list',\n exportAs: 'cdkDropList',\n standalone: true,\n providers: [\n // Prevent child drop lists from picking up the same group as their parent.\n { provide: CDK_DROP_LIST_GROUP, useValue: undefined },\n { provide: CDK_DROP_LIST, useExisting: CdkDropList },\n ],\n host: {\n 'class': 'cdk-drop-list',\n '[attr.id]': 'id',\n '[class.cdk-drop-list-disabled]': 'disabled',\n '[class.cdk-drop-list-dragging]': '_dropListRef.isDragging()',\n '[class.cdk-drop-list-receiving]': '_dropListRef.isReceiving()',\n },\n }]\n }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: DragDrop }, { type: i0.ChangeDetectorRef }, { type: i1.ScrollDispatcher }, { type: i1$1.Directionality, decorators: [{\n type: Optional\n }] }, { type: CdkDropListGroup, decorators: [{\n type: Optional\n }, {\n type: Inject,\n args: [CDK_DROP_LIST_GROUP]\n }, {\n type: SkipSelf\n }] }, { type: undefined, decorators: [{\n type: Optional\n }, {\n type: Inject,\n args: [CDK_DRAG_CONFIG]\n }] }]; }, propDecorators: { connectedTo: [{\n type: Input,\n args: ['cdkDropListConnectedTo']\n }], data: [{\n type: Input,\n args: ['cdkDropListData']\n }], orientation: [{\n type: Input,\n args: ['cdkDropListOrientation']\n }], id: [{\n type: Input\n }], lockAxis: [{\n type: Input,\n args: ['cdkDropListLockAxis']\n }], disabled: [{\n type: Input,\n args: ['cdkDropListDisabled']\n }], sortingDisabled: [{\n type: Input,\n args: ['cdkDropListSortingDisabled']\n }], enterPredicate: [{\n type: Input,\n args: ['cdkDropListEnterPredicate']\n }], sortPredicate: [{\n type: Input,\n args: ['cdkDropListSortPredicate']\n }], autoScrollDisabled: [{\n type: Input,\n args: ['cdkDropListAutoScrollDisabled']\n }], autoScrollStep: [{\n type: Input,\n args: ['cdkDropListAutoScrollStep']\n }], dropped: [{\n type: Output,\n args: ['cdkDropListDropped']\n }], entered: [{\n type: Output,\n args: ['cdkDropListEntered']\n }], exited: [{\n type: Output,\n args: ['cdkDropListExited']\n }], sorted: [{\n type: Output,\n args: ['cdkDropListSorted']\n }] } });\n\nconst DRAG_DROP_DIRECTIVES = [\n CdkDropList,\n CdkDropListGroup,\n CdkDrag,\n CdkDragHandle,\n CdkDragPreview,\n CdkDragPlaceholder,\n];\nclass DragDropModule {\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: DragDropModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }\n static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: \"14.0.0\", version: \"16.1.1\", ngImport: i0, type: DragDropModule, imports: [CdkDropList,\n CdkDropListGroup,\n CdkDrag,\n CdkDragHandle,\n CdkDragPreview,\n CdkDragPlaceholder], exports: [CdkScrollableModule, CdkDropList,\n CdkDropListGroup,\n CdkDrag,\n CdkDragHandle,\n CdkDragPreview,\n CdkDragPlaceholder] }); }\n static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: DragDropModule, providers: [DragDrop], imports: [CdkScrollableModule] }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: DragDropModule, decorators: [{\n type: NgModule,\n args: [{\n imports: DRAG_DROP_DIRECTIVES,\n exports: [CdkScrollableModule, ...DRAG_DROP_DIRECTIVES],\n providers: [DragDrop],\n }]\n }] });\n\n/**\n * Generated bundle index. Do not edit.\n */\n\nexport { CDK_DRAG_CONFIG, CDK_DRAG_HANDLE, CDK_DRAG_PARENT, CDK_DRAG_PLACEHOLDER, CDK_DRAG_PREVIEW, CDK_DROP_LIST, CDK_DROP_LIST_GROUP, CdkDrag, CdkDragHandle, CdkDragPlaceholder, CdkDragPreview, CdkDropList, CdkDropListGroup, DragDrop, DragDropModule, DragDropRegistry, DragRef, DropListRef, copyArrayItem, moveItemInArray, transferArrayItem };\n","import { DOCUMENT } from '@angular/common';\nimport * as i0 from '@angular/core';\nimport { inject, APP_ID, Injectable, Inject, QueryList, Directive, Input, InjectionToken, Optional, EventEmitter, Output, NgModule } from '@angular/core';\nimport * as i1 from '@angular/cdk/platform';\nimport { _getFocusedElementPierceShadowDom, normalizePassiveListenerOptions, _getEventTarget, _getShadowRoot } from '@angular/cdk/platform';\nimport { Subject, Subscription, BehaviorSubject, of } from 'rxjs';\nimport { hasModifierKey, A, Z, ZERO, NINE, PAGE_DOWN, PAGE_UP, END, HOME, LEFT_ARROW, RIGHT_ARROW, UP_ARROW, DOWN_ARROW, TAB, ALT, CONTROL, MAC_META, META, SHIFT } from '@angular/cdk/keycodes';\nimport { tap, debounceTime, filter, map, take, skip, distinctUntilChanged, takeUntil } from 'rxjs/operators';\nimport { coerceBooleanProperty, coerceElement } from '@angular/cdk/coercion';\nimport * as i1$1 from '@angular/cdk/observers';\nimport { ObserversModule } from '@angular/cdk/observers';\nimport { BreakpointObserver } from '@angular/cdk/layout';\n\n/** IDs are delimited by an empty space, as per the spec. */\nconst ID_DELIMITER = ' ';\n/**\n * Adds the given ID to the specified ARIA attribute on an element.\n * Used for attributes such as aria-labelledby, aria-owns, etc.\n */\nfunction addAriaReferencedId(el, attr, id) {\n const ids = getAriaReferenceIds(el, attr);\n if (ids.some(existingId => existingId.trim() == id.trim())) {\n return;\n }\n ids.push(id.trim());\n el.setAttribute(attr, ids.join(ID_DELIMITER));\n}\n/**\n * Removes the given ID from the specified ARIA attribute on an element.\n * Used for attributes such as aria-labelledby, aria-owns, etc.\n */\nfunction removeAriaReferencedId(el, attr, id) {\n const ids = getAriaReferenceIds(el, attr);\n const filteredIds = ids.filter(val => val != id.trim());\n if (filteredIds.length) {\n el.setAttribute(attr, filteredIds.join(ID_DELIMITER));\n }\n else {\n el.removeAttribute(attr);\n }\n}\n/**\n * Gets the list of IDs referenced by the given ARIA attribute on an element.\n * Used for attributes such as aria-labelledby, aria-owns, etc.\n */\nfunction getAriaReferenceIds(el, attr) {\n // Get string array of all individual ids (whitespace delimited) in the attribute value\n return (el.getAttribute(attr) || '').match(/\\S+/g) || [];\n}\n\n/**\n * ID used for the body container where all messages are appended.\n * @deprecated No longer being used. To be removed.\n * @breaking-change 14.0.0\n */\nconst MESSAGES_CONTAINER_ID = 'cdk-describedby-message-container';\n/**\n * ID prefix used for each created message element.\n * @deprecated To be turned into a private variable.\n * @breaking-change 14.0.0\n */\nconst CDK_DESCRIBEDBY_ID_PREFIX = 'cdk-describedby-message';\n/**\n * Attribute given to each host element that is described by a message element.\n * @deprecated To be turned into a private variable.\n * @breaking-change 14.0.0\n */\nconst CDK_DESCRIBEDBY_HOST_ATTRIBUTE = 'cdk-describedby-host';\n/** Global incremental identifier for each registered message element. */\nlet nextId = 0;\n/**\n * Utility that creates visually hidden elements with a message content. Useful for elements that\n * want to use aria-describedby to further describe themselves without adding additional visual\n * content.\n */\nclass AriaDescriber {\n constructor(_document, \n /**\n * @deprecated To be turned into a required parameter.\n * @breaking-change 14.0.0\n */\n _platform) {\n this._platform = _platform;\n /** Map of all registered message elements that have been placed into the document. */\n this._messageRegistry = new Map();\n /** Container for all registered messages. */\n this._messagesContainer = null;\n /** Unique ID for the service. */\n this._id = `${nextId++}`;\n this._document = _document;\n this._id = inject(APP_ID) + '-' + nextId++;\n }\n describe(hostElement, message, role) {\n if (!this._canBeDescribed(hostElement, message)) {\n return;\n }\n const key = getKey(message, role);\n if (typeof message !== 'string') {\n // We need to ensure that the element has an ID.\n setMessageId(message, this._id);\n this._messageRegistry.set(key, { messageElement: message, referenceCount: 0 });\n }\n else if (!this._messageRegistry.has(key)) {\n this._createMessageElement(message, role);\n }\n if (!this._isElementDescribedByMessage(hostElement, key)) {\n this._addMessageReference(hostElement, key);\n }\n }\n removeDescription(hostElement, message, role) {\n if (!message || !this._isElementNode(hostElement)) {\n return;\n }\n const key = getKey(message, role);\n if (this._isElementDescribedByMessage(hostElement, key)) {\n this._removeMessageReference(hostElement, key);\n }\n // If the message is a string, it means that it's one that we created for the\n // consumer so we can remove it safely, otherwise we should leave it in place.\n if (typeof message === 'string') {\n const registeredMessage = this._messageRegistry.get(key);\n if (registeredMessage && registeredMessage.referenceCount === 0) {\n this._deleteMessageElement(key);\n }\n }\n if (this._messagesContainer?.childNodes.length === 0) {\n this._messagesContainer.remove();\n this._messagesContainer = null;\n }\n }\n /** Unregisters all created message elements and removes the message container. */\n ngOnDestroy() {\n const describedElements = this._document.querySelectorAll(`[${CDK_DESCRIBEDBY_HOST_ATTRIBUTE}=\"${this._id}\"]`);\n for (let i = 0; i < describedElements.length; i++) {\n this._removeCdkDescribedByReferenceIds(describedElements[i]);\n describedElements[i].removeAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE);\n }\n this._messagesContainer?.remove();\n this._messagesContainer = null;\n this._messageRegistry.clear();\n }\n /**\n * Creates a new element in the visually hidden message container element with the message\n * as its content and adds it to the message registry.\n */\n _createMessageElement(message, role) {\n const messageElement = this._document.createElement('div');\n setMessageId(messageElement, this._id);\n messageElement.textContent = message;\n if (role) {\n messageElement.setAttribute('role', role);\n }\n this._createMessagesContainer();\n this._messagesContainer.appendChild(messageElement);\n this._messageRegistry.set(getKey(message, role), { messageElement, referenceCount: 0 });\n }\n /** Deletes the message element from the global messages container. */\n _deleteMessageElement(key) {\n this._messageRegistry.get(key)?.messageElement?.remove();\n this._messageRegistry.delete(key);\n }\n /** Creates the global container for all aria-describedby messages. */\n _createMessagesContainer() {\n if (this._messagesContainer) {\n return;\n }\n const containerClassName = 'cdk-describedby-message-container';\n const serverContainers = this._document.querySelectorAll(`.${containerClassName}[platform=\"server\"]`);\n for (let i = 0; i < serverContainers.length; i++) {\n // When going from the server to the client, we may end up in a situation where there's\n // already a container on the page, but we don't have a reference to it. Clear the\n // old container so we don't get duplicates. Doing this, instead of emptying the previous\n // container, should be slightly faster.\n serverContainers[i].remove();\n }\n const messagesContainer = this._document.createElement('div');\n // We add `visibility: hidden` in order to prevent text in this container from\n // being searchable by the browser's Ctrl + F functionality.\n // Screen-readers will still read the description for elements with aria-describedby even\n // when the description element is not visible.\n messagesContainer.style.visibility = 'hidden';\n // Even though we use `visibility: hidden`, we still apply `cdk-visually-hidden` so that\n // the description element doesn't impact page layout.\n messagesContainer.classList.add(containerClassName);\n messagesContainer.classList.add('cdk-visually-hidden');\n // @breaking-change 14.0.0 Remove null check for `_platform`.\n if (this._platform && !this._platform.isBrowser) {\n messagesContainer.setAttribute('platform', 'server');\n }\n this._document.body.appendChild(messagesContainer);\n this._messagesContainer = messagesContainer;\n }\n /** Removes all cdk-describedby messages that are hosted through the element. */\n _removeCdkDescribedByReferenceIds(element) {\n // Remove all aria-describedby reference IDs that are prefixed by CDK_DESCRIBEDBY_ID_PREFIX\n const originalReferenceIds = getAriaReferenceIds(element, 'aria-describedby').filter(id => id.indexOf(CDK_DESCRIBEDBY_ID_PREFIX) != 0);\n element.setAttribute('aria-describedby', originalReferenceIds.join(' '));\n }\n /**\n * Adds a message reference to the element using aria-describedby and increments the registered\n * message's reference count.\n */\n _addMessageReference(element, key) {\n const registeredMessage = this._messageRegistry.get(key);\n // Add the aria-describedby reference and set the\n // describedby_host attribute to mark the element.\n addAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id);\n element.setAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE, this._id);\n registeredMessage.referenceCount++;\n }\n /**\n * Removes a message reference from the element using aria-describedby\n * and decrements the registered message's reference count.\n */\n _removeMessageReference(element, key) {\n const registeredMessage = this._messageRegistry.get(key);\n registeredMessage.referenceCount--;\n removeAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id);\n element.removeAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE);\n }\n /** Returns true if the element has been described by the provided message ID. */\n _isElementDescribedByMessage(element, key) {\n const referenceIds = getAriaReferenceIds(element, 'aria-describedby');\n const registeredMessage = this._messageRegistry.get(key);\n const messageId = registeredMessage && registeredMessage.messageElement.id;\n return !!messageId && referenceIds.indexOf(messageId) != -1;\n }\n /** Determines whether a message can be described on a particular element. */\n _canBeDescribed(element, message) {\n if (!this._isElementNode(element)) {\n return false;\n }\n if (message && typeof message === 'object') {\n // We'd have to make some assumptions about the description element's text, if the consumer\n // passed in an element. Assume that if an element is passed in, the consumer has verified\n // that it can be used as a description.\n return true;\n }\n const trimmedMessage = message == null ? '' : `${message}`.trim();\n const ariaLabel = element.getAttribute('aria-label');\n // We shouldn't set descriptions if they're exactly the same as the `aria-label` of the\n // element, because screen readers will end up reading out the same text twice in a row.\n return trimmedMessage ? !ariaLabel || ariaLabel.trim() !== trimmedMessage : false;\n }\n /** Checks whether a node is an Element node. */\n _isElementNode(element) {\n return element.nodeType === this._document.ELEMENT_NODE;\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: AriaDescriber, deps: [{ token: DOCUMENT }, { token: i1.Platform }], target: i0.ɵɵFactoryTarget.Injectable }); }\n static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: AriaDescriber, providedIn: 'root' }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: AriaDescriber, decorators: [{\n type: Injectable,\n args: [{ providedIn: 'root' }]\n }], ctorParameters: function () { return [{ type: undefined, decorators: [{\n type: Inject,\n args: [DOCUMENT]\n }] }, { type: i1.Platform }]; } });\n/** Gets a key that can be used to look messages up in the registry. */\nfunction getKey(message, role) {\n return typeof message === 'string' ? `${role || ''}/${message}` : message;\n}\n/** Assigns a unique ID to an element, if it doesn't have one already. */\nfunction setMessageId(element, serviceId) {\n if (!element.id) {\n element.id = `${CDK_DESCRIBEDBY_ID_PREFIX}-${serviceId}-${nextId++}`;\n }\n}\n\n/**\n * This class manages keyboard events for selectable lists. If you pass it a query list\n * of items, it will set the active item correctly when arrow events occur.\n */\nclass ListKeyManager {\n constructor(_items) {\n this._items = _items;\n this._activeItemIndex = -1;\n this._activeItem = null;\n this._wrap = false;\n this._letterKeyStream = new Subject();\n this._typeaheadSubscription = Subscription.EMPTY;\n this._vertical = true;\n this._allowedModifierKeys = [];\n this._homeAndEnd = false;\n this._pageUpAndDown = { enabled: false, delta: 10 };\n /**\n * Predicate function that can be used to check whether an item should be skipped\n * by the key manager. By default, disabled items are skipped.\n */\n this._skipPredicateFn = (item) => item.disabled;\n // Buffer for the letters that the user has pressed when the typeahead option is turned on.\n this._pressedLetters = [];\n /**\n * Stream that emits any time the TAB key is pressed, so components can react\n * when focus is shifted off of the list.\n */\n this.tabOut = new Subject();\n /** Stream that emits whenever the active item of the list manager changes. */\n this.change = new Subject();\n // We allow for the items to be an array because, in some cases, the consumer may\n // not have access to a QueryList of the items they want to manage (e.g. when the\n // items aren't being collected via `ViewChildren` or `ContentChildren`).\n if (_items instanceof QueryList) {\n this._itemChangesSubscription = _items.changes.subscribe((newItems) => {\n if (this._activeItem) {\n const itemArray = newItems.toArray();\n const newIndex = itemArray.indexOf(this._activeItem);\n if (newIndex > -1 && newIndex !== this._activeItemIndex) {\n this._activeItemIndex = newIndex;\n }\n }\n });\n }\n }\n /**\n * Sets the predicate function that determines which items should be skipped by the\n * list key manager.\n * @param predicate Function that determines whether the given item should be skipped.\n */\n skipPredicate(predicate) {\n this._skipPredicateFn = predicate;\n return this;\n }\n /**\n * Configures wrapping mode, which determines whether the active item will wrap to\n * the other end of list when there are no more items in the given direction.\n * @param shouldWrap Whether the list should wrap when reaching the end.\n */\n withWrap(shouldWrap = true) {\n this._wrap = shouldWrap;\n return this;\n }\n /**\n * Configures whether the key manager should be able to move the selection vertically.\n * @param enabled Whether vertical selection should be enabled.\n */\n withVerticalOrientation(enabled = true) {\n this._vertical = enabled;\n return this;\n }\n /**\n * Configures the key manager to move the selection horizontally.\n * Passing in `null` will disable horizontal movement.\n * @param direction Direction in which the selection can be moved.\n */\n withHorizontalOrientation(direction) {\n this._horizontal = direction;\n return this;\n }\n /**\n * Modifier keys which are allowed to be held down and whose default actions will be prevented\n * as the user is pressing the arrow keys. Defaults to not allowing any modifier keys.\n */\n withAllowedModifierKeys(keys) {\n this._allowedModifierKeys = keys;\n return this;\n }\n /**\n * Turns on typeahead mode which allows users to set the active item by typing.\n * @param debounceInterval Time to wait after the last keystroke before setting the active item.\n */\n withTypeAhead(debounceInterval = 200) {\n if ((typeof ngDevMode === 'undefined' || ngDevMode) &&\n this._items.length &&\n this._items.some(item => typeof item.getLabel !== 'function')) {\n throw Error('ListKeyManager items in typeahead mode must implement the `getLabel` method.');\n }\n this._typeaheadSubscription.unsubscribe();\n // Debounce the presses of non-navigational keys, collect the ones that correspond to letters\n // and convert those letters back into a string. Afterwards find the first item that starts\n // with that string and select it.\n this._typeaheadSubscription = this._letterKeyStream\n .pipe(tap(letter => this._pressedLetters.push(letter)), debounceTime(debounceInterval), filter(() => this._pressedLetters.length > 0), map(() => this._pressedLetters.join('')))\n .subscribe(inputString => {\n const items = this._getItemsArray();\n // Start at 1 because we want to start searching at the item immediately\n // following the current active item.\n for (let i = 1; i < items.length + 1; i++) {\n const index = (this._activeItemIndex + i) % items.length;\n const item = items[index];\n if (!this._skipPredicateFn(item) &&\n item.getLabel().toUpperCase().trim().indexOf(inputString) === 0) {\n this.setActiveItem(index);\n break;\n }\n }\n this._pressedLetters = [];\n });\n return this;\n }\n /** Cancels the current typeahead sequence. */\n cancelTypeahead() {\n this._pressedLetters = [];\n return this;\n }\n /**\n * Configures the key manager to activate the first and last items\n * respectively when the Home or End key is pressed.\n * @param enabled Whether pressing the Home or End key activates the first/last item.\n */\n withHomeAndEnd(enabled = true) {\n this._homeAndEnd = enabled;\n return this;\n }\n /**\n * Configures the key manager to activate every 10th, configured or first/last element in up/down direction\n * respectively when the Page-Up or Page-Down key is pressed.\n * @param enabled Whether pressing the Page-Up or Page-Down key activates the first/last item.\n * @param delta Whether pressing the Home or End key activates the first/last item.\n */\n withPageUpDown(enabled = true, delta = 10) {\n this._pageUpAndDown = { enabled, delta };\n return this;\n }\n setActiveItem(item) {\n const previousActiveItem = this._activeItem;\n this.updateActiveItem(item);\n if (this._activeItem !== previousActiveItem) {\n this.change.next(this._activeItemIndex);\n }\n }\n /**\n * Sets the active item depending on the key event passed in.\n * @param event Keyboard event to be used for determining which element should be active.\n */\n onKeydown(event) {\n const keyCode = event.keyCode;\n const modifiers = ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'];\n const isModifierAllowed = modifiers.every(modifier => {\n return !event[modifier] || this._allowedModifierKeys.indexOf(modifier) > -1;\n });\n switch (keyCode) {\n case TAB:\n this.tabOut.next();\n return;\n case DOWN_ARROW:\n if (this._vertical && isModifierAllowed) {\n this.setNextItemActive();\n break;\n }\n else {\n return;\n }\n case UP_ARROW:\n if (this._vertical && isModifierAllowed) {\n this.setPreviousItemActive();\n break;\n }\n else {\n return;\n }\n case RIGHT_ARROW:\n if (this._horizontal && isModifierAllowed) {\n this._horizontal === 'rtl' ? this.setPreviousItemActive() : this.setNextItemActive();\n break;\n }\n else {\n return;\n }\n case LEFT_ARROW:\n if (this._horizontal && isModifierAllowed) {\n this._horizontal === 'rtl' ? this.setNextItemActive() : this.setPreviousItemActive();\n break;\n }\n else {\n return;\n }\n case HOME:\n if (this._homeAndEnd && isModifierAllowed) {\n this.setFirstItemActive();\n break;\n }\n else {\n return;\n }\n case END:\n if (this._homeAndEnd && isModifierAllowed) {\n this.setLastItemActive();\n break;\n }\n else {\n return;\n }\n case PAGE_UP:\n if (this._pageUpAndDown.enabled && isModifierAllowed) {\n const targetIndex = this._activeItemIndex - this._pageUpAndDown.delta;\n this._setActiveItemByIndex(targetIndex > 0 ? targetIndex : 0, 1);\n break;\n }\n else {\n return;\n }\n case PAGE_DOWN:\n if (this._pageUpAndDown.enabled && isModifierAllowed) {\n const targetIndex = this._activeItemIndex + this._pageUpAndDown.delta;\n const itemsLength = this._getItemsArray().length;\n this._setActiveItemByIndex(targetIndex < itemsLength ? targetIndex : itemsLength - 1, -1);\n break;\n }\n else {\n return;\n }\n default:\n if (isModifierAllowed || hasModifierKey(event, 'shiftKey')) {\n // Attempt to use the `event.key` which also maps it to the user's keyboard language,\n // otherwise fall back to resolving alphanumeric characters via the keyCode.\n if (event.key && event.key.length === 1) {\n this._letterKeyStream.next(event.key.toLocaleUpperCase());\n }\n else if ((keyCode >= A && keyCode <= Z) || (keyCode >= ZERO && keyCode <= NINE)) {\n this._letterKeyStream.next(String.fromCharCode(keyCode));\n }\n }\n // Note that we return here, in order to avoid preventing\n // the default action of non-navigational keys.\n return;\n }\n this._pressedLetters = [];\n event.preventDefault();\n }\n /** Index of the currently active item. */\n get activeItemIndex() {\n return this._activeItemIndex;\n }\n /** The active item. */\n get activeItem() {\n return this._activeItem;\n }\n /** Gets whether the user is currently typing into the manager using the typeahead feature. */\n isTyping() {\n return this._pressedLetters.length > 0;\n }\n /** Sets the active item to the first enabled item in the list. */\n setFirstItemActive() {\n this._setActiveItemByIndex(0, 1);\n }\n /** Sets the active item to the last enabled item in the list. */\n setLastItemActive() {\n this._setActiveItemByIndex(this._items.length - 1, -1);\n }\n /** Sets the active item to the next enabled item in the list. */\n setNextItemActive() {\n this._activeItemIndex < 0 ? this.setFirstItemActive() : this._setActiveItemByDelta(1);\n }\n /** Sets the active item to a previous enabled item in the list. */\n setPreviousItemActive() {\n this._activeItemIndex < 0 && this._wrap\n ? this.setLastItemActive()\n : this._setActiveItemByDelta(-1);\n }\n updateActiveItem(item) {\n const itemArray = this._getItemsArray();\n const index = typeof item === 'number' ? item : itemArray.indexOf(item);\n const activeItem = itemArray[index];\n // Explicitly check for `null` and `undefined` because other falsy values are valid.\n this._activeItem = activeItem == null ? null : activeItem;\n this._activeItemIndex = index;\n }\n /** Cleans up the key manager. */\n destroy() {\n this._typeaheadSubscription.unsubscribe();\n this._itemChangesSubscription?.unsubscribe();\n this._letterKeyStream.complete();\n this.tabOut.complete();\n this.change.complete();\n this._pressedLetters = [];\n }\n /**\n * This method sets the active item, given a list of items and the delta between the\n * currently active item and the new active item. It will calculate differently\n * depending on whether wrap mode is turned on.\n */\n _setActiveItemByDelta(delta) {\n this._wrap ? this._setActiveInWrapMode(delta) : this._setActiveInDefaultMode(delta);\n }\n /**\n * Sets the active item properly given \"wrap\" mode. In other words, it will continue to move\n * down the list until it finds an item that is not disabled, and it will wrap if it\n * encounters either end of the list.\n */\n _setActiveInWrapMode(delta) {\n const items = this._getItemsArray();\n for (let i = 1; i <= items.length; i++) {\n const index = (this._activeItemIndex + delta * i + items.length) % items.length;\n const item = items[index];\n if (!this._skipPredicateFn(item)) {\n this.setActiveItem(index);\n return;\n }\n }\n }\n /**\n * Sets the active item properly given the default mode. In other words, it will\n * continue to move down the list until it finds an item that is not disabled. If\n * it encounters either end of the list, it will stop and not wrap.\n */\n _setActiveInDefaultMode(delta) {\n this._setActiveItemByIndex(this._activeItemIndex + delta, delta);\n }\n /**\n * Sets the active item to the first enabled item starting at the index specified. If the\n * item is disabled, it will move in the fallbackDelta direction until it either\n * finds an enabled item or encounters the end of the list.\n */\n _setActiveItemByIndex(index, fallbackDelta) {\n const items = this._getItemsArray();\n if (!items[index]) {\n return;\n }\n while (this._skipPredicateFn(items[index])) {\n index += fallbackDelta;\n if (!items[index]) {\n return;\n }\n }\n this.setActiveItem(index);\n }\n /** Returns the items as an array. */\n _getItemsArray() {\n return this._items instanceof QueryList ? this._items.toArray() : this._items;\n }\n}\n\nclass ActiveDescendantKeyManager extends ListKeyManager {\n setActiveItem(index) {\n if (this.activeItem) {\n this.activeItem.setInactiveStyles();\n }\n super.setActiveItem(index);\n if (this.activeItem) {\n this.activeItem.setActiveStyles();\n }\n }\n}\n\nclass FocusKeyManager extends ListKeyManager {\n constructor() {\n super(...arguments);\n this._origin = 'program';\n }\n /**\n * Sets the focus origin that will be passed in to the items for any subsequent `focus` calls.\n * @param origin Focus origin to be used when focusing items.\n */\n setFocusOrigin(origin) {\n this._origin = origin;\n return this;\n }\n setActiveItem(item) {\n super.setActiveItem(item);\n if (this.activeItem) {\n this.activeItem.focus(this._origin);\n }\n }\n}\n\n/**\n * Configuration for the isFocusable method.\n */\nclass IsFocusableConfig {\n constructor() {\n /**\n * Whether to count an element as focusable even if it is not currently visible.\n */\n this.ignoreVisibility = false;\n }\n}\n// The InteractivityChecker leans heavily on the ally.js accessibility utilities.\n// Methods like `isTabbable` are only covering specific edge-cases for the browsers which are\n// supported.\n/**\n * Utility for checking the interactivity of an element, such as whether is is focusable or\n * tabbable.\n */\nclass InteractivityChecker {\n constructor(_platform) {\n this._platform = _platform;\n }\n /**\n * Gets whether an element is disabled.\n *\n * @param element Element to be checked.\n * @returns Whether the element is disabled.\n */\n isDisabled(element) {\n // This does not capture some cases, such as a non-form control with a disabled attribute or\n // a form control inside of a disabled form, but should capture the most common cases.\n return element.hasAttribute('disabled');\n }\n /**\n * Gets whether an element is visible for the purposes of interactivity.\n *\n * This will capture states like `display: none` and `visibility: hidden`, but not things like\n * being clipped by an `overflow: hidden` parent or being outside the viewport.\n *\n * @returns Whether the element is visible.\n */\n isVisible(element) {\n return hasGeometry(element) && getComputedStyle(element).visibility === 'visible';\n }\n /**\n * Gets whether an element can be reached via Tab key.\n * Assumes that the element has already been checked with isFocusable.\n *\n * @param element Element to be checked.\n * @returns Whether the element is tabbable.\n */\n isTabbable(element) {\n // Nothing is tabbable on the server 😎\n if (!this._platform.isBrowser) {\n return false;\n }\n const frameElement = getFrameElement(getWindow(element));\n if (frameElement) {\n // Frame elements inherit their tabindex onto all child elements.\n if (getTabIndexValue(frameElement) === -1) {\n return false;\n }\n // Browsers disable tabbing to an element inside of an invisible frame.\n if (!this.isVisible(frameElement)) {\n return false;\n }\n }\n let nodeName = element.nodeName.toLowerCase();\n let tabIndexValue = getTabIndexValue(element);\n if (element.hasAttribute('contenteditable')) {\n return tabIndexValue !== -1;\n }\n if (nodeName === 'iframe' || nodeName === 'object') {\n // The frame or object's content may be tabbable depending on the content, but it's\n // not possibly to reliably detect the content of the frames. We always consider such\n // elements as non-tabbable.\n return false;\n }\n // In iOS, the browser only considers some specific elements as tabbable.\n if (this._platform.WEBKIT && this._platform.IOS && !isPotentiallyTabbableIOS(element)) {\n return false;\n }\n if (nodeName === 'audio') {\n // Audio elements without controls enabled are never tabbable, regardless\n // of the tabindex attribute explicitly being set.\n if (!element.hasAttribute('controls')) {\n return false;\n }\n // Audio elements with controls are by default tabbable unless the\n // tabindex attribute is set to `-1` explicitly.\n return tabIndexValue !== -1;\n }\n if (nodeName === 'video') {\n // For all video elements, if the tabindex attribute is set to `-1`, the video\n // is not tabbable. Note: We cannot rely on the default `HTMLElement.tabIndex`\n // property as that one is set to `-1` in Chrome, Edge and Safari v13.1. The\n // tabindex attribute is the source of truth here.\n if (tabIndexValue === -1) {\n return false;\n }\n // If the tabindex is explicitly set, and not `-1` (as per check before), the\n // video element is always tabbable (regardless of whether it has controls or not).\n if (tabIndexValue !== null) {\n return true;\n }\n // Otherwise (when no explicit tabindex is set), a video is only tabbable if it\n // has controls enabled. Firefox is special as videos are always tabbable regardless\n // of whether there are controls or not.\n return this._platform.FIREFOX || element.hasAttribute('controls');\n }\n return element.tabIndex >= 0;\n }\n /**\n * Gets whether an element can be focused by the user.\n *\n * @param element Element to be checked.\n * @param config The config object with options to customize this method's behavior\n * @returns Whether the element is focusable.\n */\n isFocusable(element, config) {\n // Perform checks in order of left to most expensive.\n // Again, naive approach that does not capture many edge cases and browser quirks.\n return (isPotentiallyFocusable(element) &&\n !this.isDisabled(element) &&\n (config?.ignoreVisibility || this.isVisible(element)));\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: InteractivityChecker, deps: [{ token: i1.Platform }], target: i0.ɵɵFactoryTarget.Injectable }); }\n static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: InteractivityChecker, providedIn: 'root' }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: InteractivityChecker, decorators: [{\n type: Injectable,\n args: [{ providedIn: 'root' }]\n }], ctorParameters: function () { return [{ type: i1.Platform }]; } });\n/**\n * Returns the frame element from a window object. Since browsers like MS Edge throw errors if\n * the frameElement property is being accessed from a different host address, this property\n * should be accessed carefully.\n */\nfunction getFrameElement(window) {\n try {\n return window.frameElement;\n }\n catch {\n return null;\n }\n}\n/** Checks whether the specified element has any geometry / rectangles. */\nfunction hasGeometry(element) {\n // Use logic from jQuery to check for an invisible element.\n // See https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js#L12\n return !!(element.offsetWidth ||\n element.offsetHeight ||\n (typeof element.getClientRects === 'function' && element.getClientRects().length));\n}\n/** Gets whether an element's */\nfunction isNativeFormElement(element) {\n let nodeName = element.nodeName.toLowerCase();\n return (nodeName === 'input' ||\n nodeName === 'select' ||\n nodeName === 'button' ||\n nodeName === 'textarea');\n}\n/** Gets whether an element is an ``. */\nfunction isHiddenInput(element) {\n return isInputElement(element) && element.type == 'hidden';\n}\n/** Gets whether an element is an anchor that has an href attribute. */\nfunction isAnchorWithHref(element) {\n return isAnchorElement(element) && element.hasAttribute('href');\n}\n/** Gets whether an element is an input element. */\nfunction isInputElement(element) {\n return element.nodeName.toLowerCase() == 'input';\n}\n/** Gets whether an element is an anchor element. */\nfunction isAnchorElement(element) {\n return element.nodeName.toLowerCase() == 'a';\n}\n/** Gets whether an element has a valid tabindex. */\nfunction hasValidTabIndex(element) {\n if (!element.hasAttribute('tabindex') || element.tabIndex === undefined) {\n return false;\n }\n let tabIndex = element.getAttribute('tabindex');\n return !!(tabIndex && !isNaN(parseInt(tabIndex, 10)));\n}\n/**\n * Returns the parsed tabindex from the element attributes instead of returning the\n * evaluated tabindex from the browsers defaults.\n */\nfunction getTabIndexValue(element) {\n if (!hasValidTabIndex(element)) {\n return null;\n }\n // See browser issue in Gecko https://bugzilla.mozilla.org/show_bug.cgi?id=1128054\n const tabIndex = parseInt(element.getAttribute('tabindex') || '', 10);\n return isNaN(tabIndex) ? -1 : tabIndex;\n}\n/** Checks whether the specified element is potentially tabbable on iOS */\nfunction isPotentiallyTabbableIOS(element) {\n let nodeName = element.nodeName.toLowerCase();\n let inputType = nodeName === 'input' && element.type;\n return (inputType === 'text' ||\n inputType === 'password' ||\n nodeName === 'select' ||\n nodeName === 'textarea');\n}\n/**\n * Gets whether an element is potentially focusable without taking current visible/disabled state\n * into account.\n */\nfunction isPotentiallyFocusable(element) {\n // Inputs are potentially focusable *unless* they're type=\"hidden\".\n if (isHiddenInput(element)) {\n return false;\n }\n return (isNativeFormElement(element) ||\n isAnchorWithHref(element) ||\n element.hasAttribute('contenteditable') ||\n hasValidTabIndex(element));\n}\n/** Gets the parent window of a DOM node with regards of being inside of an iframe. */\nfunction getWindow(node) {\n // ownerDocument is null if `node` itself *is* a document.\n return (node.ownerDocument && node.ownerDocument.defaultView) || window;\n}\n\n/**\n * Class that allows for trapping focus within a DOM element.\n *\n * This class currently uses a relatively simple approach to focus trapping.\n * It assumes that the tab order is the same as DOM order, which is not necessarily true.\n * Things like `tabIndex > 0`, flex `order`, and shadow roots can cause the two to be misaligned.\n *\n * @deprecated Use `ConfigurableFocusTrap` instead.\n * @breaking-change 11.0.0\n */\nclass FocusTrap {\n /** Whether the focus trap is active. */\n get enabled() {\n return this._enabled;\n }\n set enabled(value) {\n this._enabled = value;\n if (this._startAnchor && this._endAnchor) {\n this._toggleAnchorTabIndex(value, this._startAnchor);\n this._toggleAnchorTabIndex(value, this._endAnchor);\n }\n }\n constructor(_element, _checker, _ngZone, _document, deferAnchors = false) {\n this._element = _element;\n this._checker = _checker;\n this._ngZone = _ngZone;\n this._document = _document;\n this._hasAttached = false;\n // Event listeners for the anchors. Need to be regular functions so that we can unbind them later.\n this.startAnchorListener = () => this.focusLastTabbableElement();\n this.endAnchorListener = () => this.focusFirstTabbableElement();\n this._enabled = true;\n if (!deferAnchors) {\n this.attachAnchors();\n }\n }\n /** Destroys the focus trap by cleaning up the anchors. */\n destroy() {\n const startAnchor = this._startAnchor;\n const endAnchor = this._endAnchor;\n if (startAnchor) {\n startAnchor.removeEventListener('focus', this.startAnchorListener);\n startAnchor.remove();\n }\n if (endAnchor) {\n endAnchor.removeEventListener('focus', this.endAnchorListener);\n endAnchor.remove();\n }\n this._startAnchor = this._endAnchor = null;\n this._hasAttached = false;\n }\n /**\n * Inserts the anchors into the DOM. This is usually done automatically\n * in the constructor, but can be deferred for cases like directives with `*ngIf`.\n * @returns Whether the focus trap managed to attach successfully. This may not be the case\n * if the target element isn't currently in the DOM.\n */\n attachAnchors() {\n // If we're not on the browser, there can be no focus to trap.\n if (this._hasAttached) {\n return true;\n }\n this._ngZone.runOutsideAngular(() => {\n if (!this._startAnchor) {\n this._startAnchor = this._createAnchor();\n this._startAnchor.addEventListener('focus', this.startAnchorListener);\n }\n if (!this._endAnchor) {\n this._endAnchor = this._createAnchor();\n this._endAnchor.addEventListener('focus', this.endAnchorListener);\n }\n });\n if (this._element.parentNode) {\n this._element.parentNode.insertBefore(this._startAnchor, this._element);\n this._element.parentNode.insertBefore(this._endAnchor, this._element.nextSibling);\n this._hasAttached = true;\n }\n return this._hasAttached;\n }\n /**\n * Waits for the zone to stabilize, then focuses the first tabbable element.\n * @returns Returns a promise that resolves with a boolean, depending\n * on whether focus was moved successfully.\n */\n focusInitialElementWhenReady(options) {\n return new Promise(resolve => {\n this._executeOnStable(() => resolve(this.focusInitialElement(options)));\n });\n }\n /**\n * Waits for the zone to stabilize, then focuses\n * the first tabbable element within the focus trap region.\n * @returns Returns a promise that resolves with a boolean, depending\n * on whether focus was moved successfully.\n */\n focusFirstTabbableElementWhenReady(options) {\n return new Promise(resolve => {\n this._executeOnStable(() => resolve(this.focusFirstTabbableElement(options)));\n });\n }\n /**\n * Waits for the zone to stabilize, then focuses\n * the last tabbable element within the focus trap region.\n * @returns Returns a promise that resolves with a boolean, depending\n * on whether focus was moved successfully.\n */\n focusLastTabbableElementWhenReady(options) {\n return new Promise(resolve => {\n this._executeOnStable(() => resolve(this.focusLastTabbableElement(options)));\n });\n }\n /**\n * Get the specified boundary element of the trapped region.\n * @param bound The boundary to get (start or end of trapped region).\n * @returns The boundary element.\n */\n _getRegionBoundary(bound) {\n // Contains the deprecated version of selector, for temporary backwards comparability.\n const markers = this._element.querySelectorAll(`[cdk-focus-region-${bound}], ` + `[cdkFocusRegion${bound}], ` + `[cdk-focus-${bound}]`);\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n for (let i = 0; i < markers.length; i++) {\n // @breaking-change 8.0.0\n if (markers[i].hasAttribute(`cdk-focus-${bound}`)) {\n console.warn(`Found use of deprecated attribute 'cdk-focus-${bound}', ` +\n `use 'cdkFocusRegion${bound}' instead. The deprecated ` +\n `attribute will be removed in 8.0.0.`, markers[i]);\n }\n else if (markers[i].hasAttribute(`cdk-focus-region-${bound}`)) {\n console.warn(`Found use of deprecated attribute 'cdk-focus-region-${bound}', ` +\n `use 'cdkFocusRegion${bound}' instead. The deprecated attribute ` +\n `will be removed in 8.0.0.`, markers[i]);\n }\n }\n }\n if (bound == 'start') {\n return markers.length ? markers[0] : this._getFirstTabbableElement(this._element);\n }\n return markers.length\n ? markers[markers.length - 1]\n : this._getLastTabbableElement(this._element);\n }\n /**\n * Focuses the element that should be focused when the focus trap is initialized.\n * @returns Whether focus was moved successfully.\n */\n focusInitialElement(options) {\n // Contains the deprecated version of selector, for temporary backwards comparability.\n const redirectToElement = this._element.querySelector(`[cdk-focus-initial], ` + `[cdkFocusInitial]`);\n if (redirectToElement) {\n // @breaking-change 8.0.0\n if ((typeof ngDevMode === 'undefined' || ngDevMode) &&\n redirectToElement.hasAttribute(`cdk-focus-initial`)) {\n console.warn(`Found use of deprecated attribute 'cdk-focus-initial', ` +\n `use 'cdkFocusInitial' instead. The deprecated attribute ` +\n `will be removed in 8.0.0`, redirectToElement);\n }\n // Warn the consumer if the element they've pointed to\n // isn't focusable, when not in production mode.\n if ((typeof ngDevMode === 'undefined' || ngDevMode) &&\n !this._checker.isFocusable(redirectToElement)) {\n console.warn(`Element matching '[cdkFocusInitial]' is not focusable.`, redirectToElement);\n }\n if (!this._checker.isFocusable(redirectToElement)) {\n const focusableChild = this._getFirstTabbableElement(redirectToElement);\n focusableChild?.focus(options);\n return !!focusableChild;\n }\n redirectToElement.focus(options);\n return true;\n }\n return this.focusFirstTabbableElement(options);\n }\n /**\n * Focuses the first tabbable element within the focus trap region.\n * @returns Whether focus was moved successfully.\n */\n focusFirstTabbableElement(options) {\n const redirectToElement = this._getRegionBoundary('start');\n if (redirectToElement) {\n redirectToElement.focus(options);\n }\n return !!redirectToElement;\n }\n /**\n * Focuses the last tabbable element within the focus trap region.\n * @returns Whether focus was moved successfully.\n */\n focusLastTabbableElement(options) {\n const redirectToElement = this._getRegionBoundary('end');\n if (redirectToElement) {\n redirectToElement.focus(options);\n }\n return !!redirectToElement;\n }\n /**\n * Checks whether the focus trap has successfully been attached.\n */\n hasAttached() {\n return this._hasAttached;\n }\n /** Get the first tabbable element from a DOM subtree (inclusive). */\n _getFirstTabbableElement(root) {\n if (this._checker.isFocusable(root) && this._checker.isTabbable(root)) {\n return root;\n }\n const children = root.children;\n for (let i = 0; i < children.length; i++) {\n const tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE\n ? this._getFirstTabbableElement(children[i])\n : null;\n if (tabbableChild) {\n return tabbableChild;\n }\n }\n return null;\n }\n /** Get the last tabbable element from a DOM subtree (inclusive). */\n _getLastTabbableElement(root) {\n if (this._checker.isFocusable(root) && this._checker.isTabbable(root)) {\n return root;\n }\n // Iterate in reverse DOM order.\n const children = root.children;\n for (let i = children.length - 1; i >= 0; i--) {\n const tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE\n ? this._getLastTabbableElement(children[i])\n : null;\n if (tabbableChild) {\n return tabbableChild;\n }\n }\n return null;\n }\n /** Creates an anchor element. */\n _createAnchor() {\n const anchor = this._document.createElement('div');\n this._toggleAnchorTabIndex(this._enabled, anchor);\n anchor.classList.add('cdk-visually-hidden');\n anchor.classList.add('cdk-focus-trap-anchor');\n anchor.setAttribute('aria-hidden', 'true');\n return anchor;\n }\n /**\n * Toggles the `tabindex` of an anchor, based on the enabled state of the focus trap.\n * @param isEnabled Whether the focus trap is enabled.\n * @param anchor Anchor on which to toggle the tabindex.\n */\n _toggleAnchorTabIndex(isEnabled, anchor) {\n // Remove the tabindex completely, rather than setting it to -1, because if the\n // element has a tabindex, the user might still hit it when navigating with the arrow keys.\n isEnabled ? anchor.setAttribute('tabindex', '0') : anchor.removeAttribute('tabindex');\n }\n /**\n * Toggles the`tabindex` of both anchors to either trap Tab focus or allow it to escape.\n * @param enabled: Whether the anchors should trap Tab.\n */\n toggleAnchors(enabled) {\n if (this._startAnchor && this._endAnchor) {\n this._toggleAnchorTabIndex(enabled, this._startAnchor);\n this._toggleAnchorTabIndex(enabled, this._endAnchor);\n }\n }\n /** Executes a function when the zone is stable. */\n _executeOnStable(fn) {\n if (this._ngZone.isStable) {\n fn();\n }\n else {\n this._ngZone.onStable.pipe(take(1)).subscribe(fn);\n }\n }\n}\n/**\n * Factory that allows easy instantiation of focus traps.\n * @deprecated Use `ConfigurableFocusTrapFactory` instead.\n * @breaking-change 11.0.0\n */\nclass FocusTrapFactory {\n constructor(_checker, _ngZone, _document) {\n this._checker = _checker;\n this._ngZone = _ngZone;\n this._document = _document;\n }\n /**\n * Creates a focus-trapped region around the given element.\n * @param element The element around which focus will be trapped.\n * @param deferCaptureElements Defers the creation of focus-capturing elements to be done\n * manually by the user.\n * @returns The created focus trap instance.\n */\n create(element, deferCaptureElements = false) {\n return new FocusTrap(element, this._checker, this._ngZone, this._document, deferCaptureElements);\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: FocusTrapFactory, deps: [{ token: InteractivityChecker }, { token: i0.NgZone }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }\n static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: FocusTrapFactory, providedIn: 'root' }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: FocusTrapFactory, decorators: [{\n type: Injectable,\n args: [{ providedIn: 'root' }]\n }], ctorParameters: function () { return [{ type: InteractivityChecker }, { type: i0.NgZone }, { type: undefined, decorators: [{\n type: Inject,\n args: [DOCUMENT]\n }] }]; } });\n/** Directive for trapping focus within a region. */\nclass CdkTrapFocus {\n /** Whether the focus trap is active. */\n get enabled() {\n return this.focusTrap.enabled;\n }\n set enabled(value) {\n this.focusTrap.enabled = coerceBooleanProperty(value);\n }\n /**\n * Whether the directive should automatically move focus into the trapped region upon\n * initialization and return focus to the previous activeElement upon destruction.\n */\n get autoCapture() {\n return this._autoCapture;\n }\n set autoCapture(value) {\n this._autoCapture = coerceBooleanProperty(value);\n }\n constructor(_elementRef, _focusTrapFactory, \n /**\n * @deprecated No longer being used. To be removed.\n * @breaking-change 13.0.0\n */\n _document) {\n this._elementRef = _elementRef;\n this._focusTrapFactory = _focusTrapFactory;\n /** Previously focused element to restore focus to upon destroy when using autoCapture. */\n this._previouslyFocusedElement = null;\n this.focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement, true);\n }\n ngOnDestroy() {\n this.focusTrap.destroy();\n // If we stored a previously focused element when using autoCapture, return focus to that\n // element now that the trapped region is being destroyed.\n if (this._previouslyFocusedElement) {\n this._previouslyFocusedElement.focus();\n this._previouslyFocusedElement = null;\n }\n }\n ngAfterContentInit() {\n this.focusTrap.attachAnchors();\n if (this.autoCapture) {\n this._captureFocus();\n }\n }\n ngDoCheck() {\n if (!this.focusTrap.hasAttached()) {\n this.focusTrap.attachAnchors();\n }\n }\n ngOnChanges(changes) {\n const autoCaptureChange = changes['autoCapture'];\n if (autoCaptureChange &&\n !autoCaptureChange.firstChange &&\n this.autoCapture &&\n this.focusTrap.hasAttached()) {\n this._captureFocus();\n }\n }\n _captureFocus() {\n this._previouslyFocusedElement = _getFocusedElementPierceShadowDom();\n this.focusTrap.focusInitialElementWhenReady();\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkTrapFocus, deps: [{ token: i0.ElementRef }, { token: FocusTrapFactory }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }\n static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: \"14.0.0\", version: \"16.1.1\", type: CdkTrapFocus, selector: \"[cdkTrapFocus]\", inputs: { enabled: [\"cdkTrapFocus\", \"enabled\"], autoCapture: [\"cdkTrapFocusAutoCapture\", \"autoCapture\"] }, exportAs: [\"cdkTrapFocus\"], usesOnChanges: true, ngImport: i0 }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkTrapFocus, decorators: [{\n type: Directive,\n args: [{\n selector: '[cdkTrapFocus]',\n exportAs: 'cdkTrapFocus',\n }]\n }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: FocusTrapFactory }, { type: undefined, decorators: [{\n type: Inject,\n args: [DOCUMENT]\n }] }]; }, propDecorators: { enabled: [{\n type: Input,\n args: ['cdkTrapFocus']\n }], autoCapture: [{\n type: Input,\n args: ['cdkTrapFocusAutoCapture']\n }] } });\n\n/**\n * Class that allows for trapping focus within a DOM element.\n *\n * This class uses a strategy pattern that determines how it traps focus.\n * See FocusTrapInertStrategy.\n */\nclass ConfigurableFocusTrap extends FocusTrap {\n /** Whether the FocusTrap is enabled. */\n get enabled() {\n return this._enabled;\n }\n set enabled(value) {\n this._enabled = value;\n if (this._enabled) {\n this._focusTrapManager.register(this);\n }\n else {\n this._focusTrapManager.deregister(this);\n }\n }\n constructor(_element, _checker, _ngZone, _document, _focusTrapManager, _inertStrategy, config) {\n super(_element, _checker, _ngZone, _document, config.defer);\n this._focusTrapManager = _focusTrapManager;\n this._inertStrategy = _inertStrategy;\n this._focusTrapManager.register(this);\n }\n /** Notifies the FocusTrapManager that this FocusTrap will be destroyed. */\n destroy() {\n this._focusTrapManager.deregister(this);\n super.destroy();\n }\n /** @docs-private Implemented as part of ManagedFocusTrap. */\n _enable() {\n this._inertStrategy.preventFocus(this);\n this.toggleAnchors(true);\n }\n /** @docs-private Implemented as part of ManagedFocusTrap. */\n _disable() {\n this._inertStrategy.allowFocus(this);\n this.toggleAnchors(false);\n }\n}\n\n/** The injection token used to specify the inert strategy. */\nconst FOCUS_TRAP_INERT_STRATEGY = new InjectionToken('FOCUS_TRAP_INERT_STRATEGY');\n\n/**\n * Lightweight FocusTrapInertStrategy that adds a document focus event\n * listener to redirect focus back inside the FocusTrap.\n */\nclass EventListenerFocusTrapInertStrategy {\n constructor() {\n /** Focus event handler. */\n this._listener = null;\n }\n /** Adds a document event listener that keeps focus inside the FocusTrap. */\n preventFocus(focusTrap) {\n // Ensure there's only one listener per document\n if (this._listener) {\n focusTrap._document.removeEventListener('focus', this._listener, true);\n }\n this._listener = (e) => this._trapFocus(focusTrap, e);\n focusTrap._ngZone.runOutsideAngular(() => {\n focusTrap._document.addEventListener('focus', this._listener, true);\n });\n }\n /** Removes the event listener added in preventFocus. */\n allowFocus(focusTrap) {\n if (!this._listener) {\n return;\n }\n focusTrap._document.removeEventListener('focus', this._listener, true);\n this._listener = null;\n }\n /**\n * Refocuses the first element in the FocusTrap if the focus event target was outside\n * the FocusTrap.\n *\n * This is an event listener callback. The event listener is added in runOutsideAngular,\n * so all this code runs outside Angular as well.\n */\n _trapFocus(focusTrap, event) {\n const target = event.target;\n const focusTrapRoot = focusTrap._element;\n // Don't refocus if target was in an overlay, because the overlay might be associated\n // with an element inside the FocusTrap, ex. mat-select.\n if (target && !focusTrapRoot.contains(target) && !target.closest?.('div.cdk-overlay-pane')) {\n // Some legacy FocusTrap usages have logic that focuses some element on the page\n // just before FocusTrap is destroyed. For backwards compatibility, wait\n // to be sure FocusTrap is still enabled before refocusing.\n setTimeout(() => {\n // Check whether focus wasn't put back into the focus trap while the timeout was pending.\n if (focusTrap.enabled && !focusTrapRoot.contains(focusTrap._document.activeElement)) {\n focusTrap.focusFirstTabbableElement();\n }\n });\n }\n }\n}\n\n/** Injectable that ensures only the most recently enabled FocusTrap is active. */\nclass FocusTrapManager {\n constructor() {\n // A stack of the FocusTraps on the page. Only the FocusTrap at the\n // top of the stack is active.\n this._focusTrapStack = [];\n }\n /**\n * Disables the FocusTrap at the top of the stack, and then pushes\n * the new FocusTrap onto the stack.\n */\n register(focusTrap) {\n // Dedupe focusTraps that register multiple times.\n this._focusTrapStack = this._focusTrapStack.filter(ft => ft !== focusTrap);\n let stack = this._focusTrapStack;\n if (stack.length) {\n stack[stack.length - 1]._disable();\n }\n stack.push(focusTrap);\n focusTrap._enable();\n }\n /**\n * Removes the FocusTrap from the stack, and activates the\n * FocusTrap that is the new top of the stack.\n */\n deregister(focusTrap) {\n focusTrap._disable();\n const stack = this._focusTrapStack;\n const i = stack.indexOf(focusTrap);\n if (i !== -1) {\n stack.splice(i, 1);\n if (stack.length) {\n stack[stack.length - 1]._enable();\n }\n }\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: FocusTrapManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }\n static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: FocusTrapManager, providedIn: 'root' }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: FocusTrapManager, decorators: [{\n type: Injectable,\n args: [{ providedIn: 'root' }]\n }] });\n\n/** Factory that allows easy instantiation of configurable focus traps. */\nclass ConfigurableFocusTrapFactory {\n constructor(_checker, _ngZone, _focusTrapManager, _document, _inertStrategy) {\n this._checker = _checker;\n this._ngZone = _ngZone;\n this._focusTrapManager = _focusTrapManager;\n this._document = _document;\n // TODO split up the strategies into different modules, similar to DateAdapter.\n this._inertStrategy = _inertStrategy || new EventListenerFocusTrapInertStrategy();\n }\n create(element, config = { defer: false }) {\n let configObject;\n if (typeof config === 'boolean') {\n configObject = { defer: config };\n }\n else {\n configObject = config;\n }\n return new ConfigurableFocusTrap(element, this._checker, this._ngZone, this._document, this._focusTrapManager, this._inertStrategy, configObject);\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: ConfigurableFocusTrapFactory, deps: [{ token: InteractivityChecker }, { token: i0.NgZone }, { token: FocusTrapManager }, { token: DOCUMENT }, { token: FOCUS_TRAP_INERT_STRATEGY, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }\n static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: ConfigurableFocusTrapFactory, providedIn: 'root' }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: ConfigurableFocusTrapFactory, decorators: [{\n type: Injectable,\n args: [{ providedIn: 'root' }]\n }], ctorParameters: function () { return [{ type: InteractivityChecker }, { type: i0.NgZone }, { type: FocusTrapManager }, { type: undefined, decorators: [{\n type: Inject,\n args: [DOCUMENT]\n }] }, { type: undefined, decorators: [{\n type: Optional\n }, {\n type: Inject,\n args: [FOCUS_TRAP_INERT_STRATEGY]\n }] }]; } });\n\n/** Gets whether an event could be a faked `mousedown` event dispatched by a screen reader. */\nfunction isFakeMousedownFromScreenReader(event) {\n // Some screen readers will dispatch a fake `mousedown` event when pressing enter or space on\n // a clickable element. We can distinguish these events when both `offsetX` and `offsetY` are\n // zero or `event.buttons` is zero, depending on the browser:\n // - `event.buttons` works on Firefox, but fails on Chrome.\n // - `offsetX` and `offsetY` work on Chrome, but fail on Firefox.\n // Note that there's an edge case where the user could click the 0x0 spot of the\n // screen themselves, but that is unlikely to contain interactive elements.\n return event.buttons === 0 || (event.offsetX === 0 && event.offsetY === 0);\n}\n/** Gets whether an event could be a faked `touchstart` event dispatched by a screen reader. */\nfunction isFakeTouchstartFromScreenReader(event) {\n const touch = (event.touches && event.touches[0]) || (event.changedTouches && event.changedTouches[0]);\n // A fake `touchstart` can be distinguished from a real one by looking at the `identifier`\n // which is typically >= 0 on a real device versus -1 from a screen reader. Just to be safe,\n // we can also look at `radiusX` and `radiusY`. This behavior was observed against a Windows 10\n // device with a touch screen running NVDA v2020.4 and Firefox 85 or Chrome 88.\n return (!!touch &&\n touch.identifier === -1 &&\n (touch.radiusX == null || touch.radiusX === 1) &&\n (touch.radiusY == null || touch.radiusY === 1));\n}\n\n/**\n * Injectable options for the InputModalityDetector. These are shallowly merged with the default\n * options.\n */\nconst INPUT_MODALITY_DETECTOR_OPTIONS = new InjectionToken('cdk-input-modality-detector-options');\n/**\n * Default options for the InputModalityDetector.\n *\n * Modifier keys are ignored by default (i.e. when pressed won't cause the service to detect\n * keyboard input modality) for two reasons:\n *\n * 1. Modifier keys are commonly used with mouse to perform actions such as 'right click' or 'open\n * in new tab', and are thus less representative of actual keyboard interaction.\n * 2. VoiceOver triggers some keyboard events when linearly navigating with Control + Option (but\n * confusingly not with Caps Lock). Thus, to have parity with other screen readers, we ignore\n * these keys so as to not update the input modality.\n *\n * Note that we do not by default ignore the right Meta key on Safari because it has the same key\n * code as the ContextMenu key on other browsers. When we switch to using event.key, we can\n * distinguish between the two.\n */\nconst INPUT_MODALITY_DETECTOR_DEFAULT_OPTIONS = {\n ignoreKeys: [ALT, CONTROL, MAC_META, META, SHIFT],\n};\n/**\n * The amount of time needed to pass after a touchstart event in order for a subsequent mousedown\n * event to be attributed as mouse and not touch.\n *\n * This is the value used by AngularJS Material. Through trial and error (on iPhone 6S) they found\n * that a value of around 650ms seems appropriate.\n */\nconst TOUCH_BUFFER_MS = 650;\n/**\n * Event listener options that enable capturing and also mark the listener as passive if the browser\n * supports it.\n */\nconst modalityEventListenerOptions = normalizePassiveListenerOptions({\n passive: true,\n capture: true,\n});\n/**\n * Service that detects the user's input modality.\n *\n * This service does not update the input modality when a user navigates with a screen reader\n * (e.g. linear navigation with VoiceOver, object navigation / browse mode with NVDA, virtual PC\n * cursor mode with JAWS). This is in part due to technical limitations (i.e. keyboard events do not\n * fire as expected in these modes) but is also arguably the correct behavior. Navigating with a\n * screen reader is akin to visually scanning a page, and should not be interpreted as actual user\n * input interaction.\n *\n * When a user is not navigating but *interacting* with a screen reader, this service attempts to\n * update the input modality to keyboard, but in general this service's behavior is largely\n * undefined.\n */\nclass InputModalityDetector {\n /** The most recently detected input modality. */\n get mostRecentModality() {\n return this._modality.value;\n }\n constructor(_platform, ngZone, document, options) {\n this._platform = _platform;\n /**\n * The most recently detected input modality event target. Is null if no input modality has been\n * detected or if the associated event target is null for some unknown reason.\n */\n this._mostRecentTarget = null;\n /** The underlying BehaviorSubject that emits whenever an input modality is detected. */\n this._modality = new BehaviorSubject(null);\n /**\n * The timestamp of the last touch input modality. Used to determine whether mousedown events\n * should be attributed to mouse or touch.\n */\n this._lastTouchMs = 0;\n /**\n * Handles keydown events. Must be an arrow function in order to preserve the context when it gets\n * bound.\n */\n this._onKeydown = (event) => {\n // If this is one of the keys we should ignore, then ignore it and don't update the input\n // modality to keyboard.\n if (this._options?.ignoreKeys?.some(keyCode => keyCode === event.keyCode)) {\n return;\n }\n this._modality.next('keyboard');\n this._mostRecentTarget = _getEventTarget(event);\n };\n /**\n * Handles mousedown events. Must be an arrow function in order to preserve the context when it\n * gets bound.\n */\n this._onMousedown = (event) => {\n // Touches trigger both touch and mouse events, so we need to distinguish between mouse events\n // that were triggered via mouse vs touch. To do so, check if the mouse event occurs closely\n // after the previous touch event.\n if (Date.now() - this._lastTouchMs < TOUCH_BUFFER_MS) {\n return;\n }\n // Fake mousedown events are fired by some screen readers when controls are activated by the\n // screen reader. Attribute them to keyboard input modality.\n this._modality.next(isFakeMousedownFromScreenReader(event) ? 'keyboard' : 'mouse');\n this._mostRecentTarget = _getEventTarget(event);\n };\n /**\n * Handles touchstart events. Must be an arrow function in order to preserve the context when it\n * gets bound.\n */\n this._onTouchstart = (event) => {\n // Same scenario as mentioned in _onMousedown, but on touch screen devices, fake touchstart\n // events are fired. Again, attribute to keyboard input modality.\n if (isFakeTouchstartFromScreenReader(event)) {\n this._modality.next('keyboard');\n return;\n }\n // Store the timestamp of this touch event, as it's used to distinguish between mouse events\n // triggered via mouse vs touch.\n this._lastTouchMs = Date.now();\n this._modality.next('touch');\n this._mostRecentTarget = _getEventTarget(event);\n };\n this._options = {\n ...INPUT_MODALITY_DETECTOR_DEFAULT_OPTIONS,\n ...options,\n };\n // Skip the first emission as it's null.\n this.modalityDetected = this._modality.pipe(skip(1));\n this.modalityChanged = this.modalityDetected.pipe(distinctUntilChanged());\n // If we're not in a browser, this service should do nothing, as there's no relevant input\n // modality to detect.\n if (_platform.isBrowser) {\n ngZone.runOutsideAngular(() => {\n document.addEventListener('keydown', this._onKeydown, modalityEventListenerOptions);\n document.addEventListener('mousedown', this._onMousedown, modalityEventListenerOptions);\n document.addEventListener('touchstart', this._onTouchstart, modalityEventListenerOptions);\n });\n }\n }\n ngOnDestroy() {\n this._modality.complete();\n if (this._platform.isBrowser) {\n document.removeEventListener('keydown', this._onKeydown, modalityEventListenerOptions);\n document.removeEventListener('mousedown', this._onMousedown, modalityEventListenerOptions);\n document.removeEventListener('touchstart', this._onTouchstart, modalityEventListenerOptions);\n }\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: InputModalityDetector, deps: [{ token: i1.Platform }, { token: i0.NgZone }, { token: DOCUMENT }, { token: INPUT_MODALITY_DETECTOR_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }\n static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: InputModalityDetector, providedIn: 'root' }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: InputModalityDetector, decorators: [{\n type: Injectable,\n args: [{ providedIn: 'root' }]\n }], ctorParameters: function () { return [{ type: i1.Platform }, { type: i0.NgZone }, { type: Document, decorators: [{\n type: Inject,\n args: [DOCUMENT]\n }] }, { type: undefined, decorators: [{\n type: Optional\n }, {\n type: Inject,\n args: [INPUT_MODALITY_DETECTOR_OPTIONS]\n }] }]; } });\n\nconst LIVE_ANNOUNCER_ELEMENT_TOKEN = new InjectionToken('liveAnnouncerElement', {\n providedIn: 'root',\n factory: LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY,\n});\n/** @docs-private */\nfunction LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY() {\n return null;\n}\n/** Injection token that can be used to configure the default options for the LiveAnnouncer. */\nconst LIVE_ANNOUNCER_DEFAULT_OPTIONS = new InjectionToken('LIVE_ANNOUNCER_DEFAULT_OPTIONS');\n\nlet uniqueIds = 0;\nclass LiveAnnouncer {\n constructor(elementToken, _ngZone, _document, _defaultOptions) {\n this._ngZone = _ngZone;\n this._defaultOptions = _defaultOptions;\n // We inject the live element and document as `any` because the constructor signature cannot\n // reference browser globals (HTMLElement, Document) on non-browser environments, since having\n // a class decorator causes TypeScript to preserve the constructor signature types.\n this._document = _document;\n this._liveElement = elementToken || this._createLiveElement();\n }\n announce(message, ...args) {\n const defaultOptions = this._defaultOptions;\n let politeness;\n let duration;\n if (args.length === 1 && typeof args[0] === 'number') {\n duration = args[0];\n }\n else {\n [politeness, duration] = args;\n }\n this.clear();\n clearTimeout(this._previousTimeout);\n if (!politeness) {\n politeness =\n defaultOptions && defaultOptions.politeness ? defaultOptions.politeness : 'polite';\n }\n if (duration == null && defaultOptions) {\n duration = defaultOptions.duration;\n }\n // TODO: ensure changing the politeness works on all environments we support.\n this._liveElement.setAttribute('aria-live', politeness);\n if (this._liveElement.id) {\n this._exposeAnnouncerToModals(this._liveElement.id);\n }\n // This 100ms timeout is necessary for some browser + screen-reader combinations:\n // - Both JAWS and NVDA over IE11 will not announce anything without a non-zero timeout.\n // - With Chrome and IE11 with NVDA or JAWS, a repeated (identical) message won't be read a\n // second time without clearing and then using a non-zero delay.\n // (using JAWS 17 at time of this writing).\n return this._ngZone.runOutsideAngular(() => {\n if (!this._currentPromise) {\n this._currentPromise = new Promise(resolve => (this._currentResolve = resolve));\n }\n clearTimeout(this._previousTimeout);\n this._previousTimeout = setTimeout(() => {\n this._liveElement.textContent = message;\n if (typeof duration === 'number') {\n this._previousTimeout = setTimeout(() => this.clear(), duration);\n }\n this._currentResolve();\n this._currentPromise = this._currentResolve = undefined;\n }, 100);\n return this._currentPromise;\n });\n }\n /**\n * Clears the current text from the announcer element. Can be used to prevent\n * screen readers from reading the text out again while the user is going\n * through the page landmarks.\n */\n clear() {\n if (this._liveElement) {\n this._liveElement.textContent = '';\n }\n }\n ngOnDestroy() {\n clearTimeout(this._previousTimeout);\n this._liveElement?.remove();\n this._liveElement = null;\n this._currentResolve?.();\n this._currentPromise = this._currentResolve = undefined;\n }\n _createLiveElement() {\n const elementClass = 'cdk-live-announcer-element';\n const previousElements = this._document.getElementsByClassName(elementClass);\n const liveEl = this._document.createElement('div');\n // Remove any old containers. This can happen when coming in from a server-side-rendered page.\n for (let i = 0; i < previousElements.length; i++) {\n previousElements[i].remove();\n }\n liveEl.classList.add(elementClass);\n liveEl.classList.add('cdk-visually-hidden');\n liveEl.setAttribute('aria-atomic', 'true');\n liveEl.setAttribute('aria-live', 'polite');\n liveEl.id = `cdk-live-announcer-${uniqueIds++}`;\n this._document.body.appendChild(liveEl);\n return liveEl;\n }\n /**\n * Some browsers won't expose the accessibility node of the live announcer element if there is an\n * `aria-modal` and the live announcer is outside of it. This method works around the issue by\n * pointing the `aria-owns` of all modals to the live announcer element.\n */\n _exposeAnnouncerToModals(id) {\n // TODO(http://github.com/angular/components/issues/26853): consider de-duplicating this with\n // the `SnakBarContainer` and other usages.\n //\n // Note that the selector here is limited to CDK overlays at the moment in order to reduce the\n // section of the DOM we need to look through. This should cover all the cases we support, but\n // the selector can be expanded if it turns out to be too narrow.\n const modals = this._document.querySelectorAll('body > .cdk-overlay-container [aria-modal=\"true\"]');\n for (let i = 0; i < modals.length; i++) {\n const modal = modals[i];\n const ariaOwns = modal.getAttribute('aria-owns');\n if (!ariaOwns) {\n modal.setAttribute('aria-owns', id);\n }\n else if (ariaOwns.indexOf(id) === -1) {\n modal.setAttribute('aria-owns', ariaOwns + ' ' + id);\n }\n }\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: LiveAnnouncer, deps: [{ token: LIVE_ANNOUNCER_ELEMENT_TOKEN, optional: true }, { token: i0.NgZone }, { token: DOCUMENT }, { token: LIVE_ANNOUNCER_DEFAULT_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }\n static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: LiveAnnouncer, providedIn: 'root' }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: LiveAnnouncer, decorators: [{\n type: Injectable,\n args: [{ providedIn: 'root' }]\n }], ctorParameters: function () { return [{ type: undefined, decorators: [{\n type: Optional\n }, {\n type: Inject,\n args: [LIVE_ANNOUNCER_ELEMENT_TOKEN]\n }] }, { type: i0.NgZone }, { type: undefined, decorators: [{\n type: Inject,\n args: [DOCUMENT]\n }] }, { type: undefined, decorators: [{\n type: Optional\n }, {\n type: Inject,\n args: [LIVE_ANNOUNCER_DEFAULT_OPTIONS]\n }] }]; } });\n/**\n * A directive that works similarly to aria-live, but uses the LiveAnnouncer to ensure compatibility\n * with a wider range of browsers and screen readers.\n */\nclass CdkAriaLive {\n /** The aria-live politeness level to use when announcing messages. */\n get politeness() {\n return this._politeness;\n }\n set politeness(value) {\n this._politeness = value === 'off' || value === 'assertive' ? value : 'polite';\n if (this._politeness === 'off') {\n if (this._subscription) {\n this._subscription.unsubscribe();\n this._subscription = null;\n }\n }\n else if (!this._subscription) {\n this._subscription = this._ngZone.runOutsideAngular(() => {\n return this._contentObserver.observe(this._elementRef).subscribe(() => {\n // Note that we use textContent here, rather than innerText, in order to avoid a reflow.\n const elementText = this._elementRef.nativeElement.textContent;\n // The `MutationObserver` fires also for attribute\n // changes which we don't want to announce.\n if (elementText !== this._previousAnnouncedText) {\n this._liveAnnouncer.announce(elementText, this._politeness, this.duration);\n this._previousAnnouncedText = elementText;\n }\n });\n });\n }\n }\n constructor(_elementRef, _liveAnnouncer, _contentObserver, _ngZone) {\n this._elementRef = _elementRef;\n this._liveAnnouncer = _liveAnnouncer;\n this._contentObserver = _contentObserver;\n this._ngZone = _ngZone;\n this._politeness = 'polite';\n }\n ngOnDestroy() {\n if (this._subscription) {\n this._subscription.unsubscribe();\n }\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkAriaLive, deps: [{ token: i0.ElementRef }, { token: LiveAnnouncer }, { token: i1$1.ContentObserver }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }\n static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: \"14.0.0\", version: \"16.1.1\", type: CdkAriaLive, selector: \"[cdkAriaLive]\", inputs: { politeness: [\"cdkAriaLive\", \"politeness\"], duration: [\"cdkAriaLiveDuration\", \"duration\"] }, exportAs: [\"cdkAriaLive\"], ngImport: i0 }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkAriaLive, decorators: [{\n type: Directive,\n args: [{\n selector: '[cdkAriaLive]',\n exportAs: 'cdkAriaLive',\n }]\n }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: LiveAnnouncer }, { type: i1$1.ContentObserver }, { type: i0.NgZone }]; }, propDecorators: { politeness: [{\n type: Input,\n args: ['cdkAriaLive']\n }], duration: [{\n type: Input,\n args: ['cdkAriaLiveDuration']\n }] } });\n\n/** InjectionToken for FocusMonitorOptions. */\nconst FOCUS_MONITOR_DEFAULT_OPTIONS = new InjectionToken('cdk-focus-monitor-default-options');\n/**\n * Event listener options that enable capturing and also\n * mark the listener as passive if the browser supports it.\n */\nconst captureEventListenerOptions = normalizePassiveListenerOptions({\n passive: true,\n capture: true,\n});\n/** Monitors mouse and keyboard events to determine the cause of focus events. */\nclass FocusMonitor {\n constructor(_ngZone, _platform, _inputModalityDetector, \n /** @breaking-change 11.0.0 make document required */\n document, options) {\n this._ngZone = _ngZone;\n this._platform = _platform;\n this._inputModalityDetector = _inputModalityDetector;\n /** The focus origin that the next focus event is a result of. */\n this._origin = null;\n /** Whether the window has just been focused. */\n this._windowFocused = false;\n /**\n * Whether the origin was determined via a touch interaction. Necessary as properly attributing\n * focus events to touch interactions requires special logic.\n */\n this._originFromTouchInteraction = false;\n /** Map of elements being monitored to their info. */\n this._elementInfo = new Map();\n /** The number of elements currently being monitored. */\n this._monitoredElementCount = 0;\n /**\n * Keeps track of the root nodes to which we've currently bound a focus/blur handler,\n * as well as the number of monitored elements that they contain. We have to treat focus/blur\n * handlers differently from the rest of the events, because the browser won't emit events\n * to the document when focus moves inside of a shadow root.\n */\n this._rootNodeFocusListenerCount = new Map();\n /**\n * Event listener for `focus` events on the window.\n * Needs to be an arrow function in order to preserve the context when it gets bound.\n */\n this._windowFocusListener = () => {\n // Make a note of when the window regains focus, so we can\n // restore the origin info for the focused element.\n this._windowFocused = true;\n this._windowFocusTimeoutId = window.setTimeout(() => (this._windowFocused = false));\n };\n /** Subject for stopping our InputModalityDetector subscription. */\n this._stopInputModalityDetector = new Subject();\n /**\n * Event listener for `focus` and 'blur' events on the document.\n * Needs to be an arrow function in order to preserve the context when it gets bound.\n */\n this._rootNodeFocusAndBlurListener = (event) => {\n const target = _getEventTarget(event);\n // We need to walk up the ancestor chain in order to support `checkChildren`.\n for (let element = target; element; element = element.parentElement) {\n if (event.type === 'focus') {\n this._onFocus(event, element);\n }\n else {\n this._onBlur(event, element);\n }\n }\n };\n this._document = document;\n this._detectionMode = options?.detectionMode || 0 /* FocusMonitorDetectionMode.IMMEDIATE */;\n }\n monitor(element, checkChildren = false) {\n const nativeElement = coerceElement(element);\n // Do nothing if we're not on the browser platform or the passed in node isn't an element.\n if (!this._platform.isBrowser || nativeElement.nodeType !== 1) {\n // Note: we don't want the observable to emit at all so we don't pass any parameters.\n return of();\n }\n // If the element is inside the shadow DOM, we need to bind our focus/blur listeners to\n // the shadow root, rather than the `document`, because the browser won't emit focus events\n // to the `document`, if focus is moving within the same shadow root.\n const rootNode = _getShadowRoot(nativeElement) || this._getDocument();\n const cachedInfo = this._elementInfo.get(nativeElement);\n // Check if we're already monitoring this element.\n if (cachedInfo) {\n if (checkChildren) {\n // TODO(COMP-318): this can be problematic, because it'll turn all non-checkChildren\n // observers into ones that behave as if `checkChildren` was turned on. We need a more\n // robust solution.\n cachedInfo.checkChildren = true;\n }\n return cachedInfo.subject;\n }\n // Create monitored element info.\n const info = {\n checkChildren: checkChildren,\n subject: new Subject(),\n rootNode,\n };\n this._elementInfo.set(nativeElement, info);\n this._registerGlobalListeners(info);\n return info.subject;\n }\n stopMonitoring(element) {\n const nativeElement = coerceElement(element);\n const elementInfo = this._elementInfo.get(nativeElement);\n if (elementInfo) {\n elementInfo.subject.complete();\n this._setClasses(nativeElement);\n this._elementInfo.delete(nativeElement);\n this._removeGlobalListeners(elementInfo);\n }\n }\n focusVia(element, origin, options) {\n const nativeElement = coerceElement(element);\n const focusedElement = this._getDocument().activeElement;\n // If the element is focused already, calling `focus` again won't trigger the event listener\n // which means that the focus classes won't be updated. If that's the case, update the classes\n // directly without waiting for an event.\n if (nativeElement === focusedElement) {\n this._getClosestElementsInfo(nativeElement).forEach(([currentElement, info]) => this._originChanged(currentElement, origin, info));\n }\n else {\n this._setOrigin(origin);\n // `focus` isn't available on the server\n if (typeof nativeElement.focus === 'function') {\n nativeElement.focus(options);\n }\n }\n }\n ngOnDestroy() {\n this._elementInfo.forEach((_info, element) => this.stopMonitoring(element));\n }\n /** Access injected document if available or fallback to global document reference */\n _getDocument() {\n return this._document || document;\n }\n /** Use defaultView of injected document if available or fallback to global window reference */\n _getWindow() {\n const doc = this._getDocument();\n return doc.defaultView || window;\n }\n _getFocusOrigin(focusEventTarget) {\n if (this._origin) {\n // If the origin was realized via a touch interaction, we need to perform additional checks\n // to determine whether the focus origin should be attributed to touch or program.\n if (this._originFromTouchInteraction) {\n return this._shouldBeAttributedToTouch(focusEventTarget) ? 'touch' : 'program';\n }\n else {\n return this._origin;\n }\n }\n // If the window has just regained focus, we can restore the most recent origin from before the\n // window blurred. Otherwise, we've reached the point where we can't identify the source of the\n // focus. This typically means one of two things happened:\n //\n // 1) The element was programmatically focused, or\n // 2) The element was focused via screen reader navigation (which generally doesn't fire\n // events).\n //\n // Because we can't distinguish between these two cases, we default to setting `program`.\n if (this._windowFocused && this._lastFocusOrigin) {\n return this._lastFocusOrigin;\n }\n // If the interaction is coming from an input label, we consider it a mouse interactions.\n // This is a special case where focus moves on `click`, rather than `mousedown` which breaks\n // our detection, because all our assumptions are for `mousedown`. We need to handle this\n // special case, because it's very common for checkboxes and radio buttons.\n if (focusEventTarget && this._isLastInteractionFromInputLabel(focusEventTarget)) {\n return 'mouse';\n }\n return 'program';\n }\n /**\n * Returns whether the focus event should be attributed to touch. Recall that in IMMEDIATE mode, a\n * touch origin isn't immediately reset at the next tick (see _setOrigin). This means that when we\n * handle a focus event following a touch interaction, we need to determine whether (1) the focus\n * event was directly caused by the touch interaction or (2) the focus event was caused by a\n * subsequent programmatic focus call triggered by the touch interaction.\n * @param focusEventTarget The target of the focus event under examination.\n */\n _shouldBeAttributedToTouch(focusEventTarget) {\n // Please note that this check is not perfect. Consider the following edge case:\n //\n //
\n //
\n //
\n //\n // Suppose there is a FocusMonitor in IMMEDIATE mode attached to #parent. When the user touches\n // #child, #parent is programmatically focused. This code will attribute the focus to touch\n // instead of program. This is a relatively minor edge-case that can be worked around by using\n // focusVia(parent, 'program') to focus #parent.\n return (this._detectionMode === 1 /* FocusMonitorDetectionMode.EVENTUAL */ ||\n !!focusEventTarget?.contains(this._inputModalityDetector._mostRecentTarget));\n }\n /**\n * Sets the focus classes on the element based on the given focus origin.\n * @param element The element to update the classes on.\n * @param origin The focus origin.\n */\n _setClasses(element, origin) {\n element.classList.toggle('cdk-focused', !!origin);\n element.classList.toggle('cdk-touch-focused', origin === 'touch');\n element.classList.toggle('cdk-keyboard-focused', origin === 'keyboard');\n element.classList.toggle('cdk-mouse-focused', origin === 'mouse');\n element.classList.toggle('cdk-program-focused', origin === 'program');\n }\n /**\n * Updates the focus origin. If we're using immediate detection mode, we schedule an async\n * function to clear the origin at the end of a timeout. The duration of the timeout depends on\n * the origin being set.\n * @param origin The origin to set.\n * @param isFromInteraction Whether we are setting the origin from an interaction event.\n */\n _setOrigin(origin, isFromInteraction = false) {\n this._ngZone.runOutsideAngular(() => {\n this._origin = origin;\n this._originFromTouchInteraction = origin === 'touch' && isFromInteraction;\n // If we're in IMMEDIATE mode, reset the origin at the next tick (or in `TOUCH_BUFFER_MS` ms\n // for a touch event). We reset the origin at the next tick because Firefox focuses one tick\n // after the interaction event. We wait `TOUCH_BUFFER_MS` ms before resetting the origin for\n // a touch event because when a touch event is fired, the associated focus event isn't yet in\n // the event queue. Before doing so, clear any pending timeouts.\n if (this._detectionMode === 0 /* FocusMonitorDetectionMode.IMMEDIATE */) {\n clearTimeout(this._originTimeoutId);\n const ms = this._originFromTouchInteraction ? TOUCH_BUFFER_MS : 1;\n this._originTimeoutId = setTimeout(() => (this._origin = null), ms);\n }\n });\n }\n /**\n * Handles focus events on a registered element.\n * @param event The focus event.\n * @param element The monitored element.\n */\n _onFocus(event, element) {\n // NOTE(mmalerba): We currently set the classes based on the focus origin of the most recent\n // focus event affecting the monitored element. If we want to use the origin of the first event\n // instead we should check for the cdk-focused class here and return if the element already has\n // it. (This only matters for elements that have includesChildren = true).\n // If we are not counting child-element-focus as focused, make sure that the event target is the\n // monitored element itself.\n const elementInfo = this._elementInfo.get(element);\n const focusEventTarget = _getEventTarget(event);\n if (!elementInfo || (!elementInfo.checkChildren && element !== focusEventTarget)) {\n return;\n }\n this._originChanged(element, this._getFocusOrigin(focusEventTarget), elementInfo);\n }\n /**\n * Handles blur events on a registered element.\n * @param event The blur event.\n * @param element The monitored element.\n */\n _onBlur(event, element) {\n // If we are counting child-element-focus as focused, make sure that we aren't just blurring in\n // order to focus another child of the monitored element.\n const elementInfo = this._elementInfo.get(element);\n if (!elementInfo ||\n (elementInfo.checkChildren &&\n event.relatedTarget instanceof Node &&\n element.contains(event.relatedTarget))) {\n return;\n }\n this._setClasses(element);\n this._emitOrigin(elementInfo, null);\n }\n _emitOrigin(info, origin) {\n if (info.subject.observers.length) {\n this._ngZone.run(() => info.subject.next(origin));\n }\n }\n _registerGlobalListeners(elementInfo) {\n if (!this._platform.isBrowser) {\n return;\n }\n const rootNode = elementInfo.rootNode;\n const rootNodeFocusListeners = this._rootNodeFocusListenerCount.get(rootNode) || 0;\n if (!rootNodeFocusListeners) {\n this._ngZone.runOutsideAngular(() => {\n rootNode.addEventListener('focus', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);\n rootNode.addEventListener('blur', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);\n });\n }\n this._rootNodeFocusListenerCount.set(rootNode, rootNodeFocusListeners + 1);\n // Register global listeners when first element is monitored.\n if (++this._monitoredElementCount === 1) {\n // Note: we listen to events in the capture phase so we\n // can detect them even if the user stops propagation.\n this._ngZone.runOutsideAngular(() => {\n const window = this._getWindow();\n window.addEventListener('focus', this._windowFocusListener);\n });\n // The InputModalityDetector is also just a collection of global listeners.\n this._inputModalityDetector.modalityDetected\n .pipe(takeUntil(this._stopInputModalityDetector))\n .subscribe(modality => {\n this._setOrigin(modality, true /* isFromInteraction */);\n });\n }\n }\n _removeGlobalListeners(elementInfo) {\n const rootNode = elementInfo.rootNode;\n if (this._rootNodeFocusListenerCount.has(rootNode)) {\n const rootNodeFocusListeners = this._rootNodeFocusListenerCount.get(rootNode);\n if (rootNodeFocusListeners > 1) {\n this._rootNodeFocusListenerCount.set(rootNode, rootNodeFocusListeners - 1);\n }\n else {\n rootNode.removeEventListener('focus', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);\n rootNode.removeEventListener('blur', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);\n this._rootNodeFocusListenerCount.delete(rootNode);\n }\n }\n // Unregister global listeners when last element is unmonitored.\n if (!--this._monitoredElementCount) {\n const window = this._getWindow();\n window.removeEventListener('focus', this._windowFocusListener);\n // Equivalently, stop our InputModalityDetector subscription.\n this._stopInputModalityDetector.next();\n // Clear timeouts for all potentially pending timeouts to prevent the leaks.\n clearTimeout(this._windowFocusTimeoutId);\n clearTimeout(this._originTimeoutId);\n }\n }\n /** Updates all the state on an element once its focus origin has changed. */\n _originChanged(element, origin, elementInfo) {\n this._setClasses(element, origin);\n this._emitOrigin(elementInfo, origin);\n this._lastFocusOrigin = origin;\n }\n /**\n * Collects the `MonitoredElementInfo` of a particular element and\n * all of its ancestors that have enabled `checkChildren`.\n * @param element Element from which to start the search.\n */\n _getClosestElementsInfo(element) {\n const results = [];\n this._elementInfo.forEach((info, currentElement) => {\n if (currentElement === element || (info.checkChildren && currentElement.contains(element))) {\n results.push([currentElement, info]);\n }\n });\n return results;\n }\n /**\n * Returns whether an interaction is likely to have come from the user clicking the `label` of\n * an `input` or `textarea` in order to focus it.\n * @param focusEventTarget Target currently receiving focus.\n */\n _isLastInteractionFromInputLabel(focusEventTarget) {\n const { _mostRecentTarget: mostRecentTarget, mostRecentModality } = this._inputModalityDetector;\n // If the last interaction used the mouse on an element contained by one of the labels\n // of an `input`/`textarea` that is currently focused, it is very likely that the\n // user redirected focus using the label.\n if (mostRecentModality !== 'mouse' ||\n !mostRecentTarget ||\n mostRecentTarget === focusEventTarget ||\n (focusEventTarget.nodeName !== 'INPUT' && focusEventTarget.nodeName !== 'TEXTAREA') ||\n focusEventTarget.disabled) {\n return false;\n }\n const labels = focusEventTarget.labels;\n if (labels) {\n for (let i = 0; i < labels.length; i++) {\n if (labels[i].contains(mostRecentTarget)) {\n return true;\n }\n }\n }\n return false;\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: FocusMonitor, deps: [{ token: i0.NgZone }, { token: i1.Platform }, { token: InputModalityDetector }, { token: DOCUMENT, optional: true }, { token: FOCUS_MONITOR_DEFAULT_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }\n static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: FocusMonitor, providedIn: 'root' }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: FocusMonitor, decorators: [{\n type: Injectable,\n args: [{ providedIn: 'root' }]\n }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i1.Platform }, { type: InputModalityDetector }, { type: undefined, decorators: [{\n type: Optional\n }, {\n type: Inject,\n args: [DOCUMENT]\n }] }, { type: undefined, decorators: [{\n type: Optional\n }, {\n type: Inject,\n args: [FOCUS_MONITOR_DEFAULT_OPTIONS]\n }] }]; } });\n/**\n * Directive that determines how a particular element was focused (via keyboard, mouse, touch, or\n * programmatically) and adds corresponding classes to the element.\n *\n * There are two variants of this directive:\n * 1) cdkMonitorElementFocus: does not consider an element to be focused if one of its children is\n * focused.\n * 2) cdkMonitorSubtreeFocus: considers an element focused if it or any of its children are focused.\n */\nclass CdkMonitorFocus {\n constructor(_elementRef, _focusMonitor) {\n this._elementRef = _elementRef;\n this._focusMonitor = _focusMonitor;\n this._focusOrigin = null;\n this.cdkFocusChange = new EventEmitter();\n }\n get focusOrigin() {\n return this._focusOrigin;\n }\n ngAfterViewInit() {\n const element = this._elementRef.nativeElement;\n this._monitorSubscription = this._focusMonitor\n .monitor(element, element.nodeType === 1 && element.hasAttribute('cdkMonitorSubtreeFocus'))\n .subscribe(origin => {\n this._focusOrigin = origin;\n this.cdkFocusChange.emit(origin);\n });\n }\n ngOnDestroy() {\n this._focusMonitor.stopMonitoring(this._elementRef);\n if (this._monitorSubscription) {\n this._monitorSubscription.unsubscribe();\n }\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkMonitorFocus, deps: [{ token: i0.ElementRef }, { token: FocusMonitor }], target: i0.ɵɵFactoryTarget.Directive }); }\n static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: \"14.0.0\", version: \"16.1.1\", type: CdkMonitorFocus, selector: \"[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]\", outputs: { cdkFocusChange: \"cdkFocusChange\" }, exportAs: [\"cdkMonitorFocus\"], ngImport: i0 }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: CdkMonitorFocus, decorators: [{\n type: Directive,\n args: [{\n selector: '[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]',\n exportAs: 'cdkMonitorFocus',\n }]\n }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: FocusMonitor }]; }, propDecorators: { cdkFocusChange: [{\n type: Output\n }] } });\n\n/** CSS class applied to the document body when in black-on-white high-contrast mode. */\nconst BLACK_ON_WHITE_CSS_CLASS = 'cdk-high-contrast-black-on-white';\n/** CSS class applied to the document body when in white-on-black high-contrast mode. */\nconst WHITE_ON_BLACK_CSS_CLASS = 'cdk-high-contrast-white-on-black';\n/** CSS class applied to the document body when in high-contrast mode. */\nconst HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS = 'cdk-high-contrast-active';\n/**\n * Service to determine whether the browser is currently in a high-contrast-mode environment.\n *\n * Microsoft Windows supports an accessibility feature called \"High Contrast Mode\". This mode\n * changes the appearance of all applications, including web applications, to dramatically increase\n * contrast.\n *\n * IE, Edge, and Firefox currently support this mode. Chrome does not support Windows High Contrast\n * Mode. This service does not detect high-contrast mode as added by the Chrome \"High Contrast\"\n * browser extension.\n */\nclass HighContrastModeDetector {\n constructor(_platform, document) {\n this._platform = _platform;\n this._document = document;\n this._breakpointSubscription = inject(BreakpointObserver)\n .observe('(forced-colors: active)')\n .subscribe(() => {\n if (this._hasCheckedHighContrastMode) {\n this._hasCheckedHighContrastMode = false;\n this._applyBodyHighContrastModeCssClasses();\n }\n });\n }\n /** Gets the current high-contrast-mode for the page. */\n getHighContrastMode() {\n if (!this._platform.isBrowser) {\n return 0 /* HighContrastMode.NONE */;\n }\n // Create a test element with an arbitrary background-color that is neither black nor\n // white; high-contrast mode will coerce the color to either black or white. Also ensure that\n // appending the test element to the DOM does not affect layout by absolutely positioning it\n const testElement = this._document.createElement('div');\n testElement.style.backgroundColor = 'rgb(1,2,3)';\n testElement.style.position = 'absolute';\n this._document.body.appendChild(testElement);\n // Get the computed style for the background color, collapsing spaces to normalize between\n // browsers. Once we get this color, we no longer need the test element. Access the `window`\n // via the document so we can fake it in tests. Note that we have extra null checks, because\n // this logic will likely run during app bootstrap and throwing can break the entire app.\n const documentWindow = this._document.defaultView || window;\n const computedStyle = documentWindow && documentWindow.getComputedStyle\n ? documentWindow.getComputedStyle(testElement)\n : null;\n const computedColor = ((computedStyle && computedStyle.backgroundColor) || '').replace(/ /g, '');\n testElement.remove();\n switch (computedColor) {\n // Pre Windows 11 dark theme.\n case 'rgb(0,0,0)':\n // Windows 11 dark themes.\n case 'rgb(45,50,54)':\n case 'rgb(32,32,32)':\n return 2 /* HighContrastMode.WHITE_ON_BLACK */;\n // Pre Windows 11 light theme.\n case 'rgb(255,255,255)':\n // Windows 11 light theme.\n case 'rgb(255,250,239)':\n return 1 /* HighContrastMode.BLACK_ON_WHITE */;\n }\n return 0 /* HighContrastMode.NONE */;\n }\n ngOnDestroy() {\n this._breakpointSubscription.unsubscribe();\n }\n /** Applies CSS classes indicating high-contrast mode to document body (browser-only). */\n _applyBodyHighContrastModeCssClasses() {\n if (!this._hasCheckedHighContrastMode && this._platform.isBrowser && this._document.body) {\n const bodyClasses = this._document.body.classList;\n bodyClasses.remove(HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS, BLACK_ON_WHITE_CSS_CLASS, WHITE_ON_BLACK_CSS_CLASS);\n this._hasCheckedHighContrastMode = true;\n const mode = this.getHighContrastMode();\n if (mode === 1 /* HighContrastMode.BLACK_ON_WHITE */) {\n bodyClasses.add(HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS, BLACK_ON_WHITE_CSS_CLASS);\n }\n else if (mode === 2 /* HighContrastMode.WHITE_ON_BLACK */) {\n bodyClasses.add(HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS, WHITE_ON_BLACK_CSS_CLASS);\n }\n }\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: HighContrastModeDetector, deps: [{ token: i1.Platform }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }\n static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: HighContrastModeDetector, providedIn: 'root' }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: HighContrastModeDetector, decorators: [{\n type: Injectable,\n args: [{ providedIn: 'root' }]\n }], ctorParameters: function () { return [{ type: i1.Platform }, { type: undefined, decorators: [{\n type: Inject,\n args: [DOCUMENT]\n }] }]; } });\n\nclass A11yModule {\n constructor(highContrastModeDetector) {\n highContrastModeDetector._applyBodyHighContrastModeCssClasses();\n }\n static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: A11yModule, deps: [{ token: HighContrastModeDetector }], target: i0.ɵɵFactoryTarget.NgModule }); }\n static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: \"14.0.0\", version: \"16.1.1\", ngImport: i0, type: A11yModule, declarations: [CdkAriaLive, CdkTrapFocus, CdkMonitorFocus], imports: [ObserversModule], exports: [CdkAriaLive, CdkTrapFocus, CdkMonitorFocus] }); }\n static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: A11yModule, imports: [ObserversModule] }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"16.1.1\", ngImport: i0, type: A11yModule, decorators: [{\n type: NgModule,\n args: [{\n imports: [ObserversModule],\n declarations: [CdkAriaLive, CdkTrapFocus, CdkMonitorFocus],\n exports: [CdkAriaLive, CdkTrapFocus, CdkMonitorFocus],\n }]\n }], ctorParameters: function () { return [{ type: HighContrastModeDetector }]; } });\n\n/**\n * Generated bundle index. Do not edit.\n */\n\nexport { A11yModule, ActiveDescendantKeyManager, AriaDescriber, CDK_DESCRIBEDBY_HOST_ATTRIBUTE, CDK_DESCRIBEDBY_ID_PREFIX, CdkAriaLive, CdkMonitorFocus, CdkTrapFocus, ConfigurableFocusTrap, ConfigurableFocusTrapFactory, EventListenerFocusTrapInertStrategy, FOCUS_MONITOR_DEFAULT_OPTIONS, FOCUS_TRAP_INERT_STRATEGY, FocusKeyManager, FocusMonitor, FocusTrap, FocusTrapFactory, HighContrastModeDetector, INPUT_MODALITY_DETECTOR_DEFAULT_OPTIONS, INPUT_MODALITY_DETECTOR_OPTIONS, InputModalityDetector, InteractivityChecker, IsFocusableConfig, LIVE_ANNOUNCER_DEFAULT_OPTIONS, LIVE_ANNOUNCER_ELEMENT_TOKEN, LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY, ListKeyManager, LiveAnnouncer, MESSAGES_CONTAINER_ID, addAriaReferencedId, getAriaReferenceIds, isFakeMousedownFromScreenReader, isFakeTouchstartFromScreenReader, removeAriaReferencedId };\n","import { asyncScheduler } from '../scheduler/async';\nimport { timer } from './timer';\nexport function interval(period = 0, scheduler = asyncScheduler) {\n if (period < 0) {\n period = 0;\n }\n return timer(period, period, scheduler);\n}\n","\n\n 100; else dragList\">\n
\n \n
\n
\n
\n
\n \n \n
\n
\n\n \n\n \n
\n
\n
\n
\n
\n \n
0 ? 'example-list list-group-flush' : ''}}\" (cdkDropListDropped)=\"drop($event)\">\n
\n
\n
\n
\n \n \n
\n \n
\n\n \n\n \n
\n
\n
\n
\n\n\n\n

\n {{t('instructions-alt')}}\n

\n\n\n
\n","import { CdkDragDrop, moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, EventEmitter, Input, Output, TemplateRef, TrackByFunction } from '@angular/core';\nimport { VirtualScrollerModule } from '@iharbeck/ngx-virtual-scroller';\nimport { NgIf, NgFor, NgTemplateOutlet } from '@angular/common';\nimport {TranslocoDirective} from \"@ngneat/transloco\";\n\nexport interface IndexUpdateEvent {\n fromPosition: number;\n toPosition: number;\n item: any;\n}\n\nexport interface ItemRemoveEvent {\n position: number;\n item: any;\n}\n\n@Component({\n selector: 'app-draggable-ordered-list',\n templateUrl: './draggable-ordered-list.component.html',\n styleUrls: ['./draggable-ordered-list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [NgIf, VirtualScrollerModule, NgFor, NgTemplateOutlet, CdkDropList, CdkDrag, CdkDragHandle, TranslocoDirective]\n})\nexport class DraggableOrderedListComponent {\n\n @Input() accessibilityMode: boolean = false;\n /**\n * Shows the remove button on the list item\n */\n @Input() showRemoveButton: boolean = true;\n @Input() items: Array = [];\n /**\n * Parent scroll for virtualize pagination\n */\n @Input() parentScroll!: Element | Window;\n @Input() trackByIdentity: TrackByFunction = (index: number, item: any) => `${item.id}_${item.order}_${item.title}`;\n @Output() orderUpdated: EventEmitter = new EventEmitter();\n @Output() itemRemove: EventEmitter = new EventEmitter();\n @ContentChild('draggableItem') itemTemplate!: TemplateRef;\n\n get BufferAmount() {\n return Math.min(this.items.length / 20, 20);\n }\n\n constructor(private readonly cdRef: ChangeDetectorRef) { }\n\n drop(event: CdkDragDrop) {\n if (event.previousIndex === event.currentIndex) return;\n moveItemInArray(this.items, event.previousIndex, event.currentIndex);\n this.orderUpdated.emit({\n fromPosition: event.previousIndex,\n toPosition: event.currentIndex,\n item: this.items[event.currentIndex]\n });\n this.cdRef.markForCheck();\n }\n\n updateIndex(previousIndex: number, item: any) {\n // get the new value of the input\n var inputElem = document.querySelector('#reorder-' + previousIndex);\n const newIndex = parseInt(inputElem.value, 10);\n if (previousIndex === newIndex) return;\n moveItemInArray(this.items, previousIndex, newIndex);\n this.orderUpdated.emit({\n fromPosition: previousIndex,\n toPosition: newIndex,\n item: this.items[newIndex]\n });\n this.cdRef.markForCheck();\n }\n\n removeItem(item: any, position: number) {\n this.itemRemove.emit({\n position,\n item\n });\n this.cdRef.markForCheck();\n }\n}\n","\n
\n
\n \n 0\">\n
\n
\n
0 && item.pagesRead !== item.pagesTotal\">\n

\n
\n
\n\n
\n
\n
\n {{item.title}}\n
\n \n \n
\n\n
\n
\n \n \n {{formatString}} \n \n\n {{item.seriesName}}\n
\n\n \n\n
\n Released: {{item.releaseDate | date:'longDate'}}\n
\n
\n
\n\n
\n
\n","import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';\nimport { LibraryType } from 'src/app/_models/library';\nimport { MangaFormat } from 'src/app/_models/manga-format';\nimport { ReadingListItem } from 'src/app/_models/reading-list';\nimport { ImageService } from 'src/app/_services/image.service';\nimport { MangaFormatIconPipe } from '../../../pipe/manga-format-icon.pipe';\nimport { MangaFormatPipe } from '../../../pipe/manga-format.pipe';\nimport { NgbProgressbar } from '@ng-bootstrap/ng-bootstrap';\nimport { NgIf, DatePipe } from '@angular/common';\nimport { ImageComponent } from '../../../shared/image/image.component';\nimport {TranslocoDirective} from \"@ngneat/transloco\";\n\n@Component({\n selector: 'app-reading-list-item',\n templateUrl: './reading-list-item.component.html',\n styleUrls: ['./reading-list-item.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [ImageComponent, NgIf, NgbProgressbar, DatePipe, MangaFormatPipe, MangaFormatIconPipe, TranslocoDirective]\n})\nexport class ReadingListItemComponent {\n\n @Input({required: true}) item!: ReadingListItem;\n @Input() position: number = 0;\n @Input() libraryTypes: {[key: number]: LibraryType} = {};\n /**\n * If the Reading List is promoted or not\n */\n @Input() promoted: boolean = false;\n\n @Output() read: EventEmitter = new EventEmitter();\n @Output() remove: EventEmitter = new EventEmitter();\n\n get MangaFormat(): typeof MangaFormat {\n return MangaFormat;\n }\n\n constructor(public imageService: ImageService) { }\n\n readChapter(item: ReadingListItem) {\n this.read.emit(item);\n }\n\n\n}\n","\n \n

\n 0\">\n {{readingList?.title}}\n ()\n

\n
{{t('item-count', {num: items.length | number})}}
\n\n \n
\n
\n

{{t('page-settings-title')}}

\n \n
\n
\n
\n
\n \n\n
\n
\n \n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n\n
\n
\n \n
\n
\n
\n
\n \n
\n \n
\n \n
\n \n \n \n
\n
\n
\n
\n
\n
\n

\n 0\">{{(readingList.startingMonth +'/01/2020')| date:'MMM'}}\n 0 && readingList.startingYear > 0\">, \n 0\">{{readingList.startingYear}}\n —\n 0\">\n 0\">{{(readingList.endingMonth +'/01/2020') | date:'MMM'}}\n 0 && readingList.endingYear > 0\">, \n 0\">{{readingList.endingYear}}\n \n\n

\n
\n \n
\n \n
\n
\n
\n\n \n
\n
0\">\n
{{t('characters-title')}}
\n \n \n \n \n \n
\n
\n
\n\n
\n \n
\n {{t('no-data')}}\n
\n
\n \n \n \n\n \n \n = 100}\" [item]=\"item\" [position]=\"position\" [libraryTypes]=\"libraryTypes\"\n [promoted]=\"item.promoted\" (read)=\"readChapter($event)\" (remove)=\"itemRemoved($event, position)\">\n \n \n
\n
\n\n
\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit} from '@angular/core';\nimport {ActivatedRoute, Router} from '@angular/router';\nimport {ToastrService} from 'ngx-toastr';\nimport {take} from 'rxjs/operators';\nimport {ConfirmService} from 'src/app/shared/confirm.service';\nimport {UtilityService} from 'src/app/shared/_services/utility.service';\nimport {LibraryType} from 'src/app/_models/library';\nimport {MangaFormat} from 'src/app/_models/manga-format';\nimport {ReadingList, ReadingListItem} from 'src/app/_models/reading-list';\nimport {AccountService} from 'src/app/_services/account.service';\nimport {Action, ActionFactoryService, ActionItem} from 'src/app/_services/action-factory.service';\nimport {ActionService} from 'src/app/_services/action.service';\nimport {ImageService} from 'src/app/_services/image.service';\nimport {ReadingListService} from 'src/app/_services/reading-list.service';\nimport {\n DraggableOrderedListComponent,\n IndexUpdateEvent\n} from '../draggable-ordered-list/draggable-ordered-list.component';\nimport {forkJoin, Observable} from 'rxjs';\nimport {ReaderService} from 'src/app/_services/reader.service';\nimport {LibraryService} from 'src/app/_services/library.service';\nimport {Person} from 'src/app/_models/metadata/person';\nimport {ReadingListItemComponent} from '../reading-list-item/reading-list-item.component';\nimport {LoadingComponent} from '../../../shared/loading/loading.component';\nimport {A11yClickDirective} from '../../../shared/a11y-click.directive';\nimport {PersonBadgeComponent} from '../../../shared/person-badge/person-badge.component';\nimport {BadgeExpanderComponent} from '../../../shared/badge-expander/badge-expander.component';\nimport {ReadMoreComponent} from '../../../shared/read-more/read-more.component';\nimport {NgbDropdown, NgbDropdownItem, NgbDropdownMenu, NgbDropdownToggle} from '@ng-bootstrap/ng-bootstrap';\nimport {ImageComponent} from '../../../shared/image/image.component';\nimport {AsyncPipe, DatePipe, DecimalPipe, NgClass, NgIf} from '@angular/common';\nimport {\n SideNavCompanionBarComponent\n} from '../../../sidenav/_components/side-nav-companion-bar/side-nav-companion-bar.component';\nimport {translate, TranslocoDirective, TranslocoService} from \"@ngneat/transloco\";\nimport {CardActionablesComponent} from \"../../../_single-module/card-actionables/card-actionables.component\";\nimport {FilterUtilitiesService} from \"../../../shared/_services/filter-utilities.service\";\nimport {FilterField} from \"../../../_models/metadata/v2/filter-field\";\nimport {FilterComparison} from \"../../../_models/metadata/v2/filter-comparison\";\nimport {MetadataDetailComponent} from \"../../../series-detail/_components/metadata-detail/metadata-detail.component\";\nimport {Title} from \"@angular/platform-browser\";\n\n@Component({\n selector: 'app-reading-list-detail',\n templateUrl: './reading-list-detail.component.html',\n styleUrls: ['./reading-list-detail.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [SideNavCompanionBarComponent, NgIf, CardActionablesComponent, ImageComponent, NgbDropdown, NgbDropdownToggle, NgbDropdownMenu, NgbDropdownItem, ReadMoreComponent, BadgeExpanderComponent, PersonBadgeComponent, A11yClickDirective, LoadingComponent, DraggableOrderedListComponent, ReadingListItemComponent, NgClass, AsyncPipe, DecimalPipe, DatePipe, TranslocoDirective, MetadataDetailComponent]\n})\nexport class ReadingListDetailComponent implements OnInit {\n items: Array = [];\n listId!: number;\n readingList: ReadingList | undefined;\n actions: Array> = [];\n isAdmin: boolean = false;\n isLoading: boolean = false;\n accessibilityMode: boolean = false;\n\n // Downloading\n hasDownloadingRole: boolean = false;\n downloadInProgress: boolean = false;\n\n readingListSummary: string = '';\n\n libraryTypes: {[key: number]: LibraryType} = {};\n characters$!: Observable;\n\n private translocoService = inject(TranslocoService);\n\n get MangaFormat(): typeof MangaFormat {\n return MangaFormat;\n }\n\n constructor(private route: ActivatedRoute, private router: Router, private readingListService: ReadingListService,\n private actionService: ActionService, private actionFactoryService: ActionFactoryService, public utilityService: UtilityService,\n public imageService: ImageService, private accountService: AccountService, private toastr: ToastrService,\n private confirmService: ConfirmService, private libraryService: LibraryService, private readerService: ReaderService,\n private readonly cdRef: ChangeDetectorRef, private filterUtilityService: FilterUtilitiesService, private titleService: Title) {\n this.titleService.setTitle('Kavita - ' + translate('side-nav.reading-lists'));\n }\n\n ngOnInit(): void {\n const listId = this.route.snapshot.paramMap.get('id');\n\n if (listId === null) {\n this.router.navigateByUrl('/libraries');\n return;\n }\n this.listId = parseInt(listId, 10);\n this.characters$ = this.readingListService.getCharacters(this.listId);\n\n forkJoin([\n this.libraryService.getLibraries(),\n this.readingListService.getReadingList(this.listId)\n ]).subscribe(results => {\n const libraries = results[0];\n const readingList = results[1];\n\n libraries.forEach(lib => {\n this.libraryTypes[lib.id] = lib.type;\n });\n\n if (readingList == null) {\n // The list doesn't exist\n this.toastr.error(translate('toasts.list-doesnt-exist'));\n this.router.navigateByUrl('library');\n return;\n }\n this.readingList = readingList;\n this.readingListSummary = (this.readingList.summary === null ? '' : this.readingList.summary).replace(/\\n/g, '
');\n\n this.cdRef.markForCheck();\n\n this.accountService.currentUser$.pipe(take(1)).subscribe(user => {\n if (user) {\n this.isAdmin = this.accountService.hasAdminRole(user);\n this.hasDownloadingRole = this.accountService.hasDownloadRole(user);\n\n this.actions = this.actionFactoryService.getReadingListActions(this.handleReadingListActionCallback.bind(this))\n .filter(action => this.readingListService.actionListFilter(action, readingList, this.isAdmin));\n this.cdRef.markForCheck();\n }\n });\n });\n this.getListItems();\n }\n\n getListItems() {\n this.isLoading = true;\n this.cdRef.markForCheck();\n\n this.readingListService.getListItems(this.listId).subscribe(items => {\n this.items = items;\n this.isLoading = false;\n this.cdRef.markForCheck();\n });\n }\n\n performAction(action: ActionItem) {\n if (typeof action.callback === 'function') {\n action.callback(action, this.readingList);\n }\n }\n\n readChapter(item: ReadingListItem) {\n if (!this.readingList) return;\n const params = this.readerService.getQueryParamsObject(false, true, this.readingList.id);\n this.router.navigate(this.readerService.getNavigationArray(item.libraryId, item.seriesId, item.chapterId, item.seriesFormat), {queryParams: params});\n }\n\n async handleReadingListActionCallback(action: ActionItem, readingList: ReadingList) {\n switch(action.action) {\n case Action.Delete:\n await this.deleteList(readingList);\n break;\n case Action.Edit:\n this.actionService.editReadingList(readingList, (readingList: ReadingList) => {\n // Reload information around list\n this.readingListService.getReadingList(this.listId).subscribe(rl => {\n this.readingList = rl;\n this.readingListSummary = (this.readingList.summary === null ? '' : this.readingList.summary).replace(/\\n/g, '
');\n this.cdRef.markForCheck();\n })\n });\n break;\n }\n }\n\n async deleteList(readingList: ReadingList) {\n if (!await this.confirmService.confirm(this.translocoService.translate('toasts.confirm-delete-reading-list'))) return;\n\n this.readingListService.delete(readingList.id).subscribe(() => {\n this.toastr.success(this.translocoService.translate('toasts.reading-list-deleted'));\n this.router.navigateByUrl('/lists');\n });\n }\n\n orderUpdated(event: IndexUpdateEvent) {\n if (!this.readingList) return;\n this.readingListService.updatePosition(this.readingList.id, event.item.id, event.fromPosition, event.toPosition).subscribe(() => { /* No Operation */ });\n }\n\n itemRemoved(item: ReadingListItem, position: number) {\n if (!this.readingList) return;\n this.readingListService.deleteItem(this.readingList.id, item.id).subscribe(() => {\n this.items.splice(position, 1);\n this.items = [...this.items];\n this.cdRef.markForCheck();\n this.toastr.success(this.translocoService.translate('toasts.item-removed'));\n });\n }\n\n removeRead() {\n if (!this.readingList) return;\n this.isLoading = true;\n this.cdRef.markForCheck();\n this.readingListService.removeRead(this.readingList.id).subscribe((resp) => {\n if (resp === 'Nothing to remove') {\n this.toastr.info(this.translocoService.translate('toasts.nothing-to-remove'));\n return;\n }\n this.getListItems();\n });\n }\n\n read(incognitoMode: boolean = false) {\n if (!this.readingList) return;\n const firstItem = this.items[0];\n this.router.navigate(\n this.readerService.getNavigationArray(firstItem.libraryId, firstItem.seriesId, firstItem.chapterId, firstItem.seriesFormat),\n {queryParams: {readingListId: this.readingList.id, incognitoMode: incognitoMode}});\n }\n\n continue(incognitoMode: boolean = false) {\n // TODO: Can I do this in the backend?\n if (!this.readingList) return;\n let currentlyReadingChapter = this.items[0];\n for (let i = 0; i < this.items.length; i++) {\n if (this.items[i].pagesRead >= this.items[i].pagesTotal) {\n continue;\n }\n currentlyReadingChapter = this.items[i];\n break;\n }\n\n this.router.navigate(\n this.readerService.getNavigationArray(currentlyReadingChapter.libraryId, currentlyReadingChapter.seriesId, currentlyReadingChapter.chapterId, currentlyReadingChapter.seriesFormat),\n {queryParams: {readingListId: this.readingList.id, incognitoMode: incognitoMode}});\n }\n\n updateAccessibilityMode() {\n this.accessibilityMode = !this.accessibilityMode;\n this.cdRef.markForCheck();\n }\n\n goToCharacter(character: Person) {\n this.filterUtilityService.applyFilter(['all-series'], FilterField.Characters, FilterComparison.Contains, character.id + '');\n }\n}\n","\n \n

\n \n {{t('title')}}\n

\n
{{t('item-count', {num: pagination.totalItems | number})}}
\n
\n\n \n \n \n \n\n \n {{t('no-data')}} {{t('create-one-part-1')}} {{t('create-one-part-2')}}.\n \n \n\n
\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit} from '@angular/core';\nimport { Router } from '@angular/router';\nimport { NgbModal } from '@ng-bootstrap/ng-bootstrap';\nimport { ToastrService } from 'ngx-toastr';\nimport { take } from 'rxjs/operators';\nimport { JumpKey } from 'src/app/_models/jumpbar/jump-key';\nimport { PaginatedResult, Pagination } from 'src/app/_models/pagination';\nimport { ReadingList } from 'src/app/_models/reading-list';\nimport { AccountService } from 'src/app/_services/account.service';\nimport { Action, ActionFactoryService, ActionItem } from 'src/app/_services/action-factory.service';\nimport { ActionService } from 'src/app/_services/action.service';\nimport { ImageService } from 'src/app/_services/image.service';\nimport { JumpbarService } from 'src/app/_services/jumpbar.service';\nimport { ReadingListService } from 'src/app/_services/reading-list.service';\nimport { ImportCblModalComponent } from '../../_modals/import-cbl-modal/import-cbl-modal.component';\nimport { CardItemComponent } from '../../../cards/card-item/card-item.component';\nimport { CardDetailLayoutComponent } from '../../../cards/card-detail-layout/card-detail-layout.component';\nimport { NgIf, DecimalPipe } from '@angular/common';\nimport { SideNavCompanionBarComponent } from '../../../sidenav/_components/side-nav-companion-bar/side-nav-companion-bar.component';\nimport {TranslocoDirective, TranslocoService} from \"@ngneat/transloco\";\nimport {CardActionablesComponent} from \"../../../_single-module/card-actionables/card-actionables.component\";\nimport {CollectionTag} from \"../../../_models/collection-tag\";\n\n@Component({\n selector: 'app-reading-lists',\n templateUrl: './reading-lists.component.html',\n styleUrls: ['./reading-lists.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [SideNavCompanionBarComponent, CardActionablesComponent, NgIf, CardDetailLayoutComponent, CardItemComponent, DecimalPipe, TranslocoDirective]\n})\nexport class ReadingListsComponent implements OnInit {\n\n lists: ReadingList[] = [];\n loadingLists = false;\n pagination!: Pagination;\n isAdmin: boolean = false;\n jumpbarKeys: Array = [];\n actions: {[key: number]: Array>} = {};\n globalActions: Array> = [{action: Action.Import, title: 'import-cbl', children: [], requiresAdmin: true, callback: this.importCbl.bind(this)}];\n trackByIdentity = (index: number, item: ReadingList) => `${item.id}_${item.title}`;\n\n translocoService = inject(TranslocoService);\n constructor(private readingListService: ReadingListService, public imageService: ImageService, private actionFactoryService: ActionFactoryService,\n private accountService: AccountService, private toastr: ToastrService, private router: Router, private actionService: ActionService,\n private jumpbarService: JumpbarService, private readonly cdRef: ChangeDetectorRef, private ngbModal: NgbModal) { }\n\n ngOnInit(): void {\n this.accountService.currentUser$.pipe(take(1)).subscribe(user => {\n if (user) {\n this.isAdmin = this.accountService.hasAdminRole(user);\n this.loadPage();\n }\n });\n }\n\n getActions(readingList: ReadingList) {\n return this.actionFactoryService.getReadingListActions(this.handleReadingListActionCallback.bind(this))\n .filter(action => this.readingListService.actionListFilter(action, readingList, this.isAdmin));\n }\n\n performAction(action: ActionItem, readingList: ReadingList) {\n if (typeof action.callback === 'function') {\n action.callback(action, readingList);\n }\n }\n\n performGlobalAction(action: ActionItem) {\n if (typeof action.callback === 'function') {\n action.callback(action, undefined);\n }\n }\n\n importCbl() {\n const ref = this.ngbModal.open(ImportCblModalComponent, {size: 'xl'});\n ref.closed.subscribe(result => this.loadPage());\n ref.dismissed.subscribe(_ => this.loadPage());\n }\n\n handleReadingListActionCallback(action: ActionItem, readingList: ReadingList) {\n switch(action.action) {\n case Action.Delete:\n this.readingListService.delete(readingList.id).subscribe(() => {\n this.toastr.success(this.translocoService.translate('toasts.reading-list-deleted'));\n this.loadPage();\n });\n break;\n case Action.Edit:\n this.actionService.editReadingList(readingList, (updatedList: ReadingList) => {\n // Reload information around list\n readingList = updatedList;\n this.cdRef.markForCheck();\n });\n break;\n }\n }\n\n getPage() {\n const urlParams = new URLSearchParams(window.location.search);\n return urlParams.get('page');\n }\n\n loadPage() {\n const page = this.getPage();\n if (page != null) {\n this.pagination.currentPage = parseInt(page, 10);\n }\n this.loadingLists = true;\n this.cdRef.markForCheck();\n\n this.readingListService.getReadingLists(true, false).pipe(take(1)).subscribe((readingLists: PaginatedResult) => {\n this.lists = readingLists.result;\n this.pagination = readingLists.pagination;\n this.jumpbarKeys = this.jumpbarService.getJumpKeys(readingLists.result, (rl: ReadingList) => rl.title);\n this.loadingLists = false;\n this.actions = {};\n this.lists.forEach(l => this.actions[l.id] = this.getActions(l));\n window.scrollTo(0, 0);\n this.cdRef.markForCheck();\n });\n }\n\n handleClick(list: ReadingList) {\n this.router.navigateByUrl('lists/' + list.id);\n }\n\n}\n","import { NgModule } from \"@angular/core\";\nimport { Routes, RouterModule } from \"@angular/router\";\nimport { AuthGuard } from \"../_guards/auth.guard\";\nimport { ReadingListDetailComponent } from \"./_components/reading-list-detail/reading-list-detail.component\";\nimport { ReadingListsComponent } from \"./_components/reading-lists/reading-lists.component\";\n\n\nconst routes: Routes = [\n {\n path: '',\n runGuardsAndResolvers: 'always',\n canActivate: [AuthGuard],\n children: [\n {path: '', component: ReadingListsComponent, pathMatch: 'full'},\n {path: ':id', component: ReadingListDetailComponent, pathMatch: 'full'},\n ]\n },\n {path: '**', component: ReadingListsComponent, pathMatch: 'full', canActivate: [AuthGuard]},\n];\n\n\n@NgModule({\n imports: [RouterModule.forChild(routes)],\n exports: [RouterModule]\n})\nexport class ReadingListRoutingModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { DraggableOrderedListComponent } from './_components/draggable-ordered-list/draggable-ordered-list.component';\nimport { ReadingListRoutingModule } from './reading-list-routing.module';\nimport {DragDropModule} from '@angular/cdk/drag-drop';\nimport { AddToListModalComponent } from './_modals/add-to-list-modal/add-to-list-modal.component';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { EditReadingListModalComponent } from './_modals/edit-reading-list-modal/edit-reading-list-modal.component';\nimport { NgbDropdownModule, NgbNavModule, NgbProgressbarModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';\nimport { ReadingListDetailComponent } from './_components/reading-list-detail/reading-list-detail.component';\nimport { ReadingListItemComponent } from './_components/reading-list-item/reading-list-item.component';\nimport { ReadingListsComponent } from './_components/reading-lists/reading-lists.component';\nimport { VirtualScrollerModule } from '@iharbeck/ngx-virtual-scroller';\nimport {ImageComponent} from \"../shared/image/image.component\";\nimport {ReadMoreComponent} from \"../shared/read-more/read-more.component\";\nimport {PersonBadgeComponent} from \"../shared/person-badge/person-badge.component\";\nimport {BadgeExpanderComponent} from \"../shared/badge-expander/badge-expander.component\";\nimport {MangaFormatPipe} from \"../pipe/manga-format.pipe\";\nimport {MangaFormatIconPipe} from \"../pipe/manga-format-icon.pipe\";\nimport {SafeHtmlPipe} from \"../pipe/safe-html.pipe\";\nimport {FilterPipe} from \"../pipe/filter.pipe\";\nimport {CoverImageChooserComponent} from \"../cards/cover-image-chooser/cover-image-chooser.component\";\nimport {CardDetailLayoutComponent} from \"../cards/card-detail-layout/card-detail-layout.component\";\nimport {CardItemComponent} from \"../cards/card-item/card-item.component\";\nimport {\n SideNavCompanionBarComponent\n} from \"../sidenav/_components/side-nav-companion-bar/side-nav-companion-bar.component\";\nimport {LoadingComponent} from \"../shared/loading/loading.component\";\nimport {A11yClickDirective} from \"../shared/a11y-click.directive\";\nimport {CardActionablesComponent} from \"../_single-module/card-actionables/card-actionables.component\";\n\n@NgModule({\n imports: [\n CommonModule,\n ReactiveFormsModule,\n DragDropModule,\n NgbNavModule,\n NgbProgressbarModule,\n NgbTooltipModule,\n NgbDropdownModule,\n ImageComponent,\n ReadMoreComponent,\n PersonBadgeComponent,\n BadgeExpanderComponent,\n ReadingListRoutingModule,\n VirtualScrollerModule,\n CardActionablesComponent,\n MangaFormatPipe,\n MangaFormatIconPipe,\n SafeHtmlPipe,\n FilterPipe,\n CoverImageChooserComponent,\n CardDetailLayoutComponent,\n CardItemComponent,\n SideNavCompanionBarComponent,\n LoadingComponent,\n A11yClickDirective,\n DraggableOrderedListComponent,\n ReadingListDetailComponent,\n AddToListModalComponent,\n ReadingListsComponent,\n EditReadingListModalComponent,\n ReadingListItemComponent,\n ],\n exports: [\n AddToListModalComponent,\n ReadingListsComponent,\n EditReadingListModalComponent\n ]\n})\nexport class ReadingListModule { }\n"],"x_google_ignoreList":[0,1,2]}