UNPKG

@ng-bootstrap/ng-bootstrap

Version:
1 lines 876 kB
{"version":3,"file":"ng-bootstrap.mjs","sources":["../../../src/util/util.ts","../../../src/util/transition/util.ts","../../../src/environment.ts","../../../src/util/transition/ngbTransition.ts","../../../src/util/transition/ngbCollapseTransition.ts","../../../src/ngb-config.ts","../../../src/accordion/accordion-config.ts","../../../src/accordion/accordion.ts","../../../src/collapse/collapse-config.ts","../../../src/collapse/collapse.ts","../../../src/accordion/accordion.directive.ts","../../../src/accordion/accordion.module.ts","../../../src/alert/alert-transition.ts","../../../src/alert/alert-config.ts","../../../src/alert/alert.ts","../../../src/alert/alert.module.ts","../../../src/carousel/carousel-transition.ts","../../../src/carousel/carousel-config.ts","../../../src/carousel/carousel.ts","../../../src/carousel/carousel.module.ts","../../../src/collapse/collapse.module.ts","../../../src/datepicker/ngb-date.ts","../../../src/datepicker/datepicker-tools.ts","../../../src/datepicker/ngb-calendar.ts","../../../src/datepicker/datepicker-i18n.ts","../../../src/datepicker/datepicker-service.ts","../../../src/datepicker/datepicker-view-model.ts","../../../src/datepicker/datepicker-day-view.ts","../../../src/datepicker/datepicker-navigation-select.ts","../../../src/datepicker/datepicker-navigation.ts","../../../src/util/key.ts","../../../src/datepicker/datepicker-keyboard-service.ts","../../../src/datepicker/datepicker-config.ts","../../../src/datepicker/adapters/ngb-date-adapter.ts","../../../src/datepicker/datepicker.ts","../../../src/util/autoclose.ts","../../../src/util/focus-trap.ts","../../../src/util/rtl.ts","../../../src/util/positioning.ts","../../../src/datepicker/datepicker-input-config.ts","../../../src/util/positioning-util.ts","../../../src/datepicker/ngb-date-parser-formatter.ts","../../../src/datepicker/datepicker-input.ts","../../../src/datepicker/hijri/ngb-calendar-hijri.ts","../../../src/datepicker/hijri/ngb-calendar-islamic-civil.ts","../../../src/datepicker/hijri/ngb-calendar-islamic-umalqura.ts","../../../src/datepicker/jalali/jalali.ts","../../../src/datepicker/jalali/ngb-calendar-persian.ts","../../../src/datepicker/hebrew/hebrew.ts","../../../src/datepicker/hebrew/ngb-calendar-hebrew.ts","../../../src/datepicker/hebrew/datepicker-i18n-hebrew.ts","../../../src/datepicker/buddhist/buddhist.ts","../../../src/datepicker/buddhist/ngb-calendar-buddhist.ts","../../../src/datepicker/adapters/ngb-date-native-adapter.ts","../../../src/datepicker/adapters/ngb-date-native-utc-adapter.ts","../../../src/datepicker/datepicker.module.ts","../../../src/dropdown/dropdown-config.ts","../../../src/dropdown/dropdown.ts","../../../src/dropdown/dropdown.module.ts","../../../src/util/popup.ts","../../../src/modal/modal-backdrop.ts","../../../src/modal/modal-ref.ts","../../../src/modal/modal-dismiss-reasons.ts","../../../src/modal/modal-window.ts","../../../src/util/scrollbar.ts","../../../src/modal/modal-stack.ts","../../../src/modal/modal-config.ts","../../../src/modal/modal.ts","../../../src/modal/modal.module.ts","../../../src/nav/nav-config.ts","../../../src/nav/nav.ts","../../../src/nav/nav-transition.ts","../../../src/nav/nav-outlet.ts","../../../src/nav/nav.module.ts","../../../src/pagination/pagination-config.ts","../../../src/pagination/pagination.ts","../../../src/pagination/pagination.module.ts","../../../src/util/triggers.ts","../../../src/popover/popover-config.ts","../../../src/popover/popover.ts","../../../src/popover/popover.module.ts","../../../src/progressbar/progressbar-config.ts","../../../src/progressbar/progressbar.ts","../../../src/progressbar/progressbar.module.ts","../../../src/rating/rating-config.ts","../../../src/rating/rating.ts","../../../src/rating/rating.module.ts","../../../src/scrollspy/scrollspy.utils.ts","../../../src/scrollspy/scrollspy-config.ts","../../../src/scrollspy/scrollspy.service.ts","../../../src/scrollspy/scrollspy.ts","../../../src/scrollspy/scrollspy.module.ts","../../../src/timepicker/ngb-time.ts","../../../src/timepicker/timepicker-config.ts","../../../src/timepicker/ngb-time-adapter.ts","../../../src/timepicker/timepicker-i18n.ts","../../../src/timepicker/timepicker.ts","../../../src/timepicker/timepicker.module.ts","../../../src/toast/toast-transition.ts","../../../src/toast/toast-config.ts","../../../src/toast/toast.ts","../../../src/toast/toast.module.ts","../../../src/tooltip/tooltip-config.ts","../../../src/tooltip/tooltip.ts","../../../src/tooltip/tooltip.module.ts","../../../src/typeahead/highlight.ts","../../../src/typeahead/typeahead-window.ts","../../../src/typeahead/typeahead-config.ts","../../../src/util/accessibility/live.ts","../../../src/typeahead/typeahead.ts","../../../src/typeahead/typeahead.module.ts","../../../src/offcanvas/offcanvas-ref.ts","../../../src/offcanvas/offcanvas-dismiss-reasons.ts","../../../src/offcanvas/offcanvas-backdrop.ts","../../../src/offcanvas/offcanvas-panel.ts","../../../src/offcanvas/offcanvas-stack.ts","../../../src/offcanvas/offcanvas-config.ts","../../../src/offcanvas/offcanvas.ts","../../../src/offcanvas/offcanvas.module.ts","../../../src/index.ts","../../../src/ng-bootstrap.ts"],"sourcesContent":["import { NgZone } from '@angular/core';\nimport { Observable, OperatorFunction } from 'rxjs';\n\nexport function toInteger(value: any): number {\n\treturn parseInt(`${value}`, 10);\n}\n\nexport function toString(value: any): string {\n\treturn value !== undefined && value !== null ? `${value}` : '';\n}\n\nexport function getValueInRange(value: number, max: number, min = 0): number {\n\treturn Math.max(Math.min(value, max), min);\n}\n\nexport function isString(value: any): value is string {\n\treturn typeof value === 'string';\n}\n\nexport function isNumber(value: any): value is number {\n\treturn !isNaN(toInteger(value));\n}\n\nexport function isInteger(value: any): value is number {\n\treturn typeof value === 'number' && isFinite(value) && Math.floor(value) === value;\n}\n\nexport function isDefined(value: any): boolean {\n\treturn value !== undefined && value !== null;\n}\n\nexport function isPromise<T>(v: any): v is Promise<T> {\n\treturn v && v.then;\n}\n\nexport function padNumber(value: number) {\n\tif (isNumber(value)) {\n\t\treturn `0${value}`.slice(-2);\n\t} else {\n\t\treturn '';\n\t}\n}\n\nexport function regExpEscape(text) {\n\treturn text.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&');\n}\n\nexport function hasClassName(element: any, className: string): boolean {\n\treturn (\n\t\telement && element.className && element.className.split && element.className.split(/\\s+/).indexOf(className) >= 0\n\t);\n}\n\nexport function closest(element: HTMLElement, selector?: string): HTMLElement | null {\n\tif (!selector) {\n\t\treturn null;\n\t}\n\n\t/*\n\t * In certain browsers (e.g. Edge 44.18362.449.0) HTMLDocument does\n\t * not support `Element.prototype.closest`. To emulate the correct behaviour\n\t * we return null when the method is missing.\n\t *\n\t * Note that in evergreen browsers `closest(document.documentElement, 'html')`\n\t * will return the document element whilst in Edge null will be returned. This\n\t * compromise was deemed good enough.\n\t */\n\tif (typeof element.closest === 'undefined') {\n\t\treturn null;\n\t}\n\n\treturn element.closest(selector);\n}\n\n/**\n * Force a browser reflow\n * @param element element where to apply the reflow\n */\nexport function reflow(element: HTMLElement) {\n\treturn (element || document.body).getBoundingClientRect();\n}\n\n/**\n * Creates an observable where all callbacks are executed inside a given zone\n *\n * @param zone\n */\nexport function runInZone<T>(zone: NgZone): OperatorFunction<T, T> {\n\treturn (source) => {\n\t\treturn new Observable((observer) => {\n\t\t\tconst next = (value: T) => zone.run(() => observer.next(value));\n\t\t\tconst error = (e: any) => zone.run(() => observer.error(e));\n\t\t\tconst complete = () => zone.run(() => observer.complete());\n\t\t\treturn source.subscribe({ next, error, complete });\n\t\t});\n\t};\n}\n\nexport function removeAccents(str: string): string {\n\treturn str.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\n}\n\n/**\n * Returns the active element in the given root.\n * If the active element is inside a shadow root, it is searched recursively.\n */\nexport function getActiveElement(root: Document | ShadowRoot = document): Element | null {\n\tconst activeEl = root?.activeElement;\n\n\tif (!activeEl) {\n\t\treturn null;\n\t}\n\n\treturn activeEl.shadowRoot ? getActiveElement(activeEl.shadowRoot) : activeEl;\n}\n","export function getTransitionDurationMs(element: HTMLElement) {\n\tconst { transitionDelay, transitionDuration } = window.getComputedStyle(element);\n\tconst transitionDelaySec = parseFloat(transitionDelay);\n\tconst transitionDurationSec = parseFloat(transitionDuration);\n\n\treturn (transitionDelaySec + transitionDurationSec) * 1000;\n}\n","export const environment = {\n\tanimation: true,\n\ttransitionTimerDelayMs: 5,\n};\n","import { NgZone } from '@angular/core';\nimport { EMPTY, fromEvent, Observable, of, race, Subject, timer } from 'rxjs';\nimport { endWith, filter, takeUntil } from 'rxjs/operators';\nimport { getTransitionDurationMs } from './util';\nimport { environment } from '../../environment';\nimport { runInZone } from '../util';\n\nexport type NgbTransitionStartFn<T = any> = (\n\telement: HTMLElement,\n\tanimation: boolean,\n\tcontext: T,\n) => NgbTransitionEndFn | void;\nexport type NgbTransitionEndFn = () => void;\n\nexport interface NgbTransitionOptions<T> {\n\tanimation: boolean;\n\trunningTransition: 'continue' | 'stop';\n\tcontext?: T;\n}\n\nexport interface NgbTransitionCtx<T> {\n\ttransition$: Subject<any>;\n\tcomplete: () => void;\n\tcontext: T;\n}\n\nconst noopFn: NgbTransitionEndFn = () => {};\n\nconst { transitionTimerDelayMs } = environment;\nconst runningTransitions = new Map<HTMLElement, NgbTransitionCtx<any>>();\n\nexport const ngbRunTransition = <T>(\n\tzone: NgZone,\n\telement: HTMLElement,\n\tstartFn: NgbTransitionStartFn<T>,\n\toptions: NgbTransitionOptions<T>,\n): Observable<void> => {\n\t// Getting initial context from options\n\tlet context = options.context || <T>{};\n\n\t// Checking if there are already running transitions on the given element.\n\tconst running = runningTransitions.get(element);\n\tif (running) {\n\t\tswitch (options.runningTransition) {\n\t\t\t// If there is one running and we want for it to 'continue' to run, we have to cancel the new one.\n\t\t\t// We're not emitting any values, but simply completing the observable (EMPTY).\n\t\t\tcase 'continue':\n\t\t\t\treturn EMPTY;\n\t\t\t// If there is one running and we want for it to 'stop', we have to complete the running one.\n\t\t\t// We're simply completing the running one and not emitting any values and merging newly provided context\n\t\t\t// with the one coming from currently running transition.\n\t\t\tcase 'stop':\n\t\t\t\tzone.run(() => running.transition$.complete());\n\t\t\t\tcontext = Object.assign(running.context, context);\n\t\t\t\trunningTransitions.delete(element);\n\t\t}\n\t}\n\n\t// Running the start function\n\tconst endFn = startFn(element, options.animation, context) || noopFn;\n\n\t// If 'prefer-reduced-motion' is enabled, the 'transition' will be set to 'none'.\n\t// If animations are disabled, we have to emit a value and complete the observable\n\t// In this case we have to call the end function, but can finish immediately by emitting a value,\n\t// completing the observable and executing end functions synchronously.\n\tif (!options.animation || window.getComputedStyle(element).transitionProperty === 'none') {\n\t\tzone.run(() => endFn());\n\t\treturn of(undefined).pipe(runInZone(zone));\n\t}\n\n\t// Starting a new transition\n\tconst transition$ = new Subject<void>();\n\tconst finishTransition$ = new Subject<void>();\n\tconst stop$ = transition$.pipe(endWith(true));\n\trunningTransitions.set(element, {\n\t\ttransition$,\n\t\tcomplete: () => {\n\t\t\tfinishTransition$.next();\n\t\t\tfinishTransition$.complete();\n\t\t},\n\t\tcontext,\n\t});\n\n\tconst transitionDurationMs = getTransitionDurationMs(element);\n\n\t// 1. We have to both listen for the 'transitionend' event and have a 'just-in-case' timer,\n\t// because 'transitionend' event might not be fired in some browsers, if the transitioning\n\t// element becomes invisible (ex. when scrolling, making browser tab inactive, etc.). The timer\n\t// guarantees, that we'll release the DOM element and complete 'ngbRunTransition'.\n\t// 2. We need to filter transition end events, because they might bubble from shorter transitions\n\t// on inner DOM elements. We're only interested in the transition on the 'element' itself.\n\tzone.runOutsideAngular(() => {\n\t\tconst transitionEnd$ = fromEvent(element, 'transitionend').pipe(\n\t\t\ttakeUntil(stop$),\n\t\t\tfilter(({ target }) => target === element),\n\t\t);\n\t\tconst timer$ = timer(transitionDurationMs + transitionTimerDelayMs).pipe(takeUntil(stop$));\n\n\t\trace(timer$, transitionEnd$, finishTransition$)\n\t\t\t.pipe(takeUntil(stop$))\n\t\t\t.subscribe(() => {\n\t\t\t\trunningTransitions.delete(element);\n\t\t\t\tzone.run(() => {\n\t\t\t\t\tendFn();\n\t\t\t\t\ttransition$.next();\n\t\t\t\t\ttransition$.complete();\n\t\t\t\t});\n\t\t\t});\n\t});\n\n\treturn transition$.asObservable();\n};\n\nexport const ngbCompleteTransition = (element: HTMLElement) => {\n\trunningTransitions.get(element)?.complete();\n};\n","import { NgbTransitionStartFn } from './ngbTransition';\nimport { reflow } from '../util';\n\nexport interface NgbCollapseCtx {\n\tdirection: 'show' | 'hide';\n\tdimension: 'width' | 'height';\n\tmaxSize?: string;\n}\n\nfunction measureCollapsingElementDimensionPx(element: HTMLElement, dimension: 'width' | 'height'): string {\n\t// SSR fix for without injecting the PlatformId\n\tif (typeof navigator === 'undefined') {\n\t\treturn '0px';\n\t}\n\n\tconst { classList } = element;\n\tconst hasShownClass = classList.contains('show');\n\tif (!hasShownClass) {\n\t\tclassList.add('show');\n\t}\n\n\telement.style[dimension] = '';\n\tconst dimensionSize = element.getBoundingClientRect()[dimension] + 'px';\n\n\tif (!hasShownClass) {\n\t\tclassList.remove('show');\n\t}\n\n\treturn dimensionSize;\n}\n\nexport const ngbCollapsingTransition: NgbTransitionStartFn<NgbCollapseCtx> = (\n\telement: HTMLElement,\n\tanimation: boolean,\n\tcontext: NgbCollapseCtx,\n) => {\n\tlet { direction, maxSize, dimension } = context;\n\tconst { classList } = element;\n\n\tfunction setInitialClasses() {\n\t\tclassList.add('collapse');\n\t\tif (direction === 'show') {\n\t\t\tclassList.add('show');\n\t\t} else {\n\t\t\tclassList.remove('show');\n\t\t}\n\t}\n\n\t// without animations we just need to set initial classes\n\tif (!animation) {\n\t\tsetInitialClasses();\n\t\treturn;\n\t}\n\n\t// No maxHeight -> running the transition for the first time\n\tif (!maxSize) {\n\t\tmaxSize = measureCollapsingElementDimensionPx(element, dimension);\n\t\tcontext.maxSize = maxSize;\n\n\t\t// Fix the height before starting the animation\n\t\telement.style[dimension] = direction !== 'show' ? maxSize : '0px';\n\n\t\tclassList.remove('collapse');\n\t\tclassList.remove('collapsing');\n\t\tclassList.remove('show');\n\n\t\treflow(element);\n\n\t\t// Start the animation\n\t\tclassList.add('collapsing');\n\t}\n\n\t// Start or revert the animation\n\telement.style[dimension] = direction === 'show' ? maxSize : '0px';\n\n\treturn () => {\n\t\tsetInitialClasses();\n\t\tclassList.remove('collapsing');\n\t\telement.style[dimension] = '';\n\t};\n};\n","import { Injectable } from '@angular/core';\nimport { environment } from './environment';\n\n/**\n * Global ng-bootstrap config\n *\n * @since 8.0.0\n */\n@Injectable({ providedIn: 'root' })\nexport class NgbConfig {\n\tanimation = environment.animation;\n}\n","import { Injectable } from '@angular/core';\nimport { NgbConfig } from '../ngb-config';\n\n/**\n * A configuration service for the [`NgbAccordionDirective`](#/components/accordion/api#NgbAccordionDirective).\n *\n * You can inject this service, typically in your root component, and customize its properties\n * to provide default values for all accordions used in the application.\n */\n@Injectable({ providedIn: 'root' })\nexport class NgbAccordionConfig {\n\tcloseOthers = false;\n\t/**\n\t * @deprecated 14.1.0\n\t */\n\ttype: string;\n\n\tprivate _animation: boolean;\n\n\tconstructor(private _ngbConfig: NgbConfig) {}\n\n\tget animation(): boolean {\n\t\treturn this._animation === undefined ? this._ngbConfig.animation : this._animation;\n\t}\n\tset animation(animation: boolean) {\n\t\tthis._animation = animation;\n\t}\n}\n","/* eslint-disable deprecation/deprecation */\nimport {\n\tAfterContentChecked,\n\tChangeDetectorRef,\n\tComponent,\n\tContentChildren,\n\tDirective,\n\tElementRef,\n\tEventEmitter,\n\tHost,\n\tInput,\n\tOptional,\n\tOutput,\n\tQueryList,\n\tTemplateRef,\n\tViewEncapsulation,\n\tNgZone,\n\tOnInit,\n\tOnDestroy,\n\tInject,\n\tforwardRef,\n} from '@angular/core';\n\nimport { isString } from '../util/util';\n\nimport { NgbAccordionConfig } from './accordion-config';\nimport { ngbRunTransition } from '../util/transition/ngbTransition';\nimport { ngbCollapsingTransition } from '../util/transition/ngbCollapseTransition';\nimport { take } from 'rxjs/operators';\nimport { NgFor, NgIf, NgTemplateOutlet } from '@angular/common';\n\nlet nextId = 0;\n\n/**\n * The context for the [NgbPanelHeader](#/components/accordion/api#NgbPanelHeader) template\n *\n * @since 4.1.0\n * @deprecated 14.1.0\n */\nexport interface NgbPanelHeaderContext {\n\t/**\n\t * `True` if current panel is opened\n\t */\n\topened: boolean;\n}\n\n/**\n * A directive that wraps an accordion panel header with any HTML markup and a toggling button\n * marked with [`NgbPanelToggle`](#/components/accordion/api#NgbPanelToggle).\n * See the [header customization demo](#/components/accordion/examples#header) for more details.\n *\n * You can also use [`NgbPanelTitle`](#/components/accordion/api#NgbPanelTitle) to customize only the panel title.\n *\n * @since 4.1.0\n * @deprecated 14.1.0\n */\n@Directive({ selector: 'ng-template[ngbPanelHeader]', standalone: true })\nexport class NgbPanelHeader {\n\tconstructor(public templateRef: TemplateRef<any>) {}\n}\n\n/**\n * A directive that wraps only the panel title with HTML markup inside.\n *\n * You can also use [`NgbPanelHeader`](#/components/accordion/api#NgbPanelHeader) to customize the full panel header.\n *\n * @deprecated 14.1.0\n */\n@Directive({ selector: 'ng-template[ngbPanelTitle]', standalone: true })\nexport class NgbPanelTitle {\n\tconstructor(public templateRef: TemplateRef<any>) {}\n}\n\n/**\n * A directive that wraps the accordion panel content.\n *\n * @deprecated 14.1.0\n */\n@Directive({ selector: 'ng-template[ngbPanelContent]', standalone: true })\nexport class NgbPanelContent {\n\tconstructor(public templateRef: TemplateRef<any>) {}\n}\n\n/**\n * A directive that wraps an individual accordion panel with title and collapsible content.\n *\n * @deprecated 14.1.0\n */\n@Directive({ selector: 'ngb-panel', standalone: true })\nexport class NgbPanel implements AfterContentChecked {\n\t/**\n\t * If `true`, the panel is disabled an can't be toggled.\n\t */\n\t@Input() disabled = false;\n\n\t/**\n\t * An optional id for the panel that must be unique on the page.\n\t *\n\t * If not provided, it will be auto-generated in the `ngb-panel-xxx` format.\n\t */\n\t@Input() id = `ngb-panel-${nextId++}`;\n\n\tisOpen = false;\n\n\t/* A flag to specified that the transition panel classes have been initialized */\n\tinitClassDone = false;\n\n\t/* A flag to specified if the panel is currently being animated, to ensure its presence in the dom */\n\ttransitionRunning = false;\n\n\t/**\n\t * The panel title.\n\t *\n\t * You can alternatively use [`NgbPanelTitle`](#/components/accordion/api#NgbPanelTitle) to set panel title.\n\t */\n\t@Input() title: string;\n\n\t/**\n\t * Type of the current panel.\n\t *\n\t * Bootstrap provides styles for the following types: `'success'`, `'info'`, `'warning'`, `'danger'`, `'primary'`,\n\t * `'secondary'`, `'light'` and `'dark'`.\n\t */\n\t@Input() type: string;\n\n\t/**\n\t * An optional class applied to the accordion card element that wraps both panel title and content.\n\t *\n\t * @since 5.3.0\n\t */\n\t@Input() cardClass: string;\n\n\t/**\n\t * An event emitted when the panel is shown, after the transition. It has no payload.\n\t *\n\t * @since 8.0.0\n\t */\n\t@Output() shown = new EventEmitter<void>();\n\n\t/**\n\t * An event emitted when the panel is hidden, after the transition. It has no payload.\n\t *\n\t * @since 8.0.0\n\t */\n\t@Output() hidden = new EventEmitter<void>();\n\n\ttitleTpl?: NgbPanelTitle;\n\theaderTpl?: NgbPanelHeader;\n\tcontentTpl?: NgbPanelContent;\n\tpanelDiv: HTMLElement | null;\n\n\t@ContentChildren(NgbPanelTitle, { descendants: false }) titleTpls: QueryList<NgbPanelTitle>;\n\t@ContentChildren(NgbPanelHeader, { descendants: false }) headerTpls: QueryList<NgbPanelHeader>;\n\t@ContentChildren(NgbPanelContent, { descendants: false }) contentTpls: QueryList<NgbPanelContent>;\n\n\tngAfterContentChecked() {\n\t\t// We are using @ContentChildren instead of @ContentChild as in the Angular version being used\n\t\t// only @ContentChildren allows us to specify the {descendants: false} option.\n\t\t// Without {descendants: false} we are hitting bugs described in:\n\t\t// https://github.com/ng-bootstrap/ng-bootstrap/issues/2240\n\t\tthis.titleTpl = this.titleTpls.first;\n\t\tthis.headerTpl = this.headerTpls.first;\n\t\tthis.contentTpl = this.contentTpls.first;\n\t}\n}\n\n/**\n * An event emitted right before toggling an accordion panel.\n *\n * @deprecated 14.1.0\n */\nexport interface NgbPanelChangeEvent {\n\t/**\n\t * The id of the accordion panel being toggled.\n\t */\n\tpanelId: string;\n\n\t/**\n\t * The next state of the panel.\n\t *\n\t * `true` if it will be opened, `false` if closed.\n\t */\n\tnextState: boolean;\n\n\t/**\n\t * Calling this function will prevent panel toggling.\n\t */\n\tpreventDefault: () => void;\n}\n\n@Directive({ selector: '[ngbRef]', standalone: true })\nexport class NgbRefDirective implements OnInit, OnDestroy {\n\t@Output() ngbRef = new EventEmitter<HTMLElement | null>();\n\tconstructor(private _El: ElementRef) {}\n\n\tngOnInit() {\n\t\tthis.ngbRef.emit(this._El.nativeElement);\n\t}\n\n\tngOnDestroy() {\n\t\tthis.ngbRef.emit(null);\n\t}\n}\n\n/**\n * A directive to put on a button that toggles panel opening and closing.\n *\n * To be used inside the [`NgbPanelHeader`](#/components/accordion/api#NgbPanelHeader)\n *\n * @since 4.1.0\n * @deprecated 14.1.0\n */\n@Directive({\n\tselector: 'button[ngbPanelToggle]',\n\tstandalone: true,\n\thost: {\n\t\ttype: 'button',\n\t\t'[disabled]': 'panel.disabled',\n\t\t'[class.collapsed]': '!panel.isOpen',\n\t\t'[attr.aria-expanded]': 'panel.isOpen',\n\t\t'[attr.aria-controls]': 'panel.id',\n\t\t'(click)': 'accordion.toggle(panel.id)',\n\t},\n})\nexport class NgbPanelToggle {\n\tstatic ngAcceptInputType_ngbPanelToggle: NgbPanel | '';\n\n\t@Input()\n\tset ngbPanelToggle(panel: NgbPanel) {\n\t\tif (panel) {\n\t\t\tthis.panel = panel;\n\t\t}\n\t}\n\n\tconstructor(\n\t\t@Inject(forwardRef(() => NgbAccordion)) public accordion: NgbAccordion,\n\t\t@Optional() @Host() public panel: NgbPanel,\n\t) {}\n}\n\n/**\n * Accordion is a collection of collapsible panels (bootstrap cards).\n *\n * It can ensure only one panel is opened at a time and allows to customize panel\n * headers.\n *\n * @deprecated 14.1.0\n */\n@Component({\n\tselector: 'ngb-accordion',\n\texportAs: 'ngbAccordion',\n\tstandalone: true,\n\timports: [NgFor, NgTemplateOutlet, NgbPanelToggle, NgbRefDirective, NgbPanelHeader, NgIf],\n\tencapsulation: ViewEncapsulation.None,\n\thost: { class: 'accordion', role: 'tablist', '[attr.aria-multiselectable]': '!closeOtherPanels' },\n\ttemplate: `\n\t\t<ng-template #t ngbPanelHeader let-panel>\n\t\t\t<button class=\"accordion-button\" [ngbPanelToggle]=\"panel\">\n\t\t\t\t{{ panel.title }}\n\t\t\t\t<ng-template [ngTemplateOutlet]=\"panel.titleTpl?.templateRef\"></ng-template>\n\t\t\t</button>\n\t\t</ng-template>\n\t\t<ng-template ngFor let-panel [ngForOf]=\"panels\">\n\t\t\t<div [class]=\"'accordion-item ' + (panel.cardClass || '')\">\n\t\t\t\t<div\n\t\t\t\t\trole=\"tab\"\n\t\t\t\t\tid=\"{{ panel.id }}-header\"\n\t\t\t\t\t[class]=\"'accordion-header ' + (panel.type ? 'bg-' + panel.type : type ? 'bg-' + type : '')\"\n\t\t\t\t>\n\t\t\t\t\t<ng-template\n\t\t\t\t\t\t[ngTemplateOutlet]=\"panel.headerTpl?.templateRef || t\"\n\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: panel, opened: panel.isOpen }\"\n\t\t\t\t\t></ng-template>\n\t\t\t\t</div>\n\t\t\t\t<div\n\t\t\t\t\tid=\"{{ panel.id }}\"\n\t\t\t\t\t(ngbRef)=\"panel.panelDiv = $event\"\n\t\t\t\t\trole=\"tabpanel\"\n\t\t\t\t\t[attr.aria-labelledby]=\"panel.id + '-header'\"\n\t\t\t\t\t*ngIf=\"!destroyOnHide || panel.isOpen || panel.transitionRunning\"\n\t\t\t\t>\n\t\t\t\t\t<div class=\"accordion-body\">\n\t\t\t\t\t\t<ng-template [ngTemplateOutlet]=\"panel.contentTpl?.templateRef || null\"></ng-template>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</ng-template>\n\t`,\n})\nexport class NgbAccordion implements AfterContentChecked {\n\t@ContentChildren(NgbPanel) panels: QueryList<NgbPanel>;\n\n\t/**\n\t * If `true`, accordion will be animated.\n\t *\n\t * @since 8.0.0\n\t */\n\t@Input() animation;\n\n\t/**\n\t * An array or comma separated strings of panel ids that should be opened **initially**.\n\t *\n\t * For subsequent changes use methods like `expand()`, `collapse()`, etc. and\n\t * the `(panelChange)` event.\n\t */\n\t@Input() activeIds: string | readonly string[] = [];\n\n\t/**\n\t * If `true`, only one panel could be opened at a time.\n\t *\n\t * Opening a new panel will close others.\n\t */\n\t@Input('closeOthers') closeOtherPanels: boolean;\n\n\t/**\n\t * If `true`, panel content will be detached from DOM and not simply hidden when the panel is collapsed.\n\t */\n\t@Input() destroyOnHide = true;\n\n\t/**\n\t * Type of panels.\n\t *\n\t * Bootstrap provides styles for the following types: `'success'`, `'info'`, `'warning'`, `'danger'`, `'primary'`,\n\t * `'secondary'`, `'light'` and `'dark'`.\n\t */\n\t@Input() type: string;\n\n\t/**\n\t * Event emitted right before the panel toggle happens.\n\t *\n\t * See [NgbPanelChangeEvent](#/components/accordion/api#NgbPanelChangeEvent) for payload details.\n\t */\n\t@Output() panelChange = new EventEmitter<NgbPanelChangeEvent>();\n\n\t/**\n\t * An event emitted when the expanding animation is finished on the panel. The payload is the panel id.\n\t *\n\t * @since 8.0.0\n\t */\n\t@Output() shown = new EventEmitter<string>();\n\n\t/**\n\t * An event emitted when the collapsing animation is finished on the panel, and before the panel element is removed.\n\t * The payload is the panel id.\n\t *\n\t * @since 8.0.0\n\t */\n\t@Output() hidden = new EventEmitter<string>();\n\n\tconstructor(config: NgbAccordionConfig, private _ngZone: NgZone, private _changeDetector: ChangeDetectorRef) {\n\t\tthis.animation = config.animation;\n\t\tthis.type = config.type;\n\t\tthis.closeOtherPanels = config.closeOthers;\n\t}\n\n\t/**\n\t * Checks if a panel with a given id is expanded.\n\t */\n\tisExpanded(panelId: string): boolean {\n\t\treturn this.activeIds.indexOf(panelId) > -1;\n\t}\n\n\t/**\n\t * Expands a panel with a given id.\n\t *\n\t * Has no effect if the panel is already expanded or disabled.\n\t */\n\texpand(panelId: string): void {\n\t\tthis._changeOpenState(this._findPanelById(panelId), true);\n\t}\n\n\t/**\n\t * Expands all panels, if `[closeOthers]` is `false`.\n\t *\n\t * If `[closeOthers]` is `true`, it will expand the first panel, unless there is already a panel opened.\n\t */\n\texpandAll(): void {\n\t\tif (this.closeOtherPanels) {\n\t\t\tif (this.activeIds.length === 0 && this.panels.length) {\n\t\t\t\tthis._changeOpenState(this.panels.first, true);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.panels.forEach((panel) => this._changeOpenState(panel, true));\n\t\t}\n\t}\n\n\t/**\n\t * Collapses a panel with the given id.\n\t *\n\t * Has no effect if the panel is already collapsed or disabled.\n\t */\n\tcollapse(panelId: string) {\n\t\tthis._changeOpenState(this._findPanelById(panelId), false);\n\t}\n\n\t/**\n\t * Collapses all opened panels.\n\t */\n\tcollapseAll() {\n\t\tthis.panels.forEach((panel) => {\n\t\t\tthis._changeOpenState(panel, false);\n\t\t});\n\t}\n\n\t/**\n\t * Toggles a panel with the given id.\n\t *\n\t * Has no effect if the panel is disabled.\n\t */\n\ttoggle(panelId: string) {\n\t\tconst panel = this._findPanelById(panelId);\n\t\tif (panel) {\n\t\t\tthis._changeOpenState(panel, !panel.isOpen);\n\t\t}\n\t}\n\n\tngAfterContentChecked() {\n\t\t// active id updates\n\t\tif (isString(this.activeIds)) {\n\t\t\tthis.activeIds = this.activeIds.split(/\\s*,\\s*/);\n\t\t}\n\n\t\t// update panels open states\n\t\tthis.panels.forEach((panel) => {\n\t\t\tpanel.isOpen = !panel.disabled && this.activeIds.indexOf(panel.id) > -1;\n\t\t});\n\n\t\t// closeOthers updates\n\t\tif (this.activeIds.length > 1 && this.closeOtherPanels) {\n\t\t\tthis._closeOthers(this.activeIds[0], false);\n\t\t\tthis._updateActiveIds();\n\t\t}\n\n\t\t// Setup the initial classes here\n\t\tthis._ngZone.onStable.pipe(take(1)).subscribe(() => {\n\t\t\tthis.panels.forEach((panel) => {\n\t\t\t\tconst panelElement = panel.panelDiv;\n\t\t\t\tif (panelElement) {\n\t\t\t\t\tif (!panel.initClassDone) {\n\t\t\t\t\t\tpanel.initClassDone = true;\n\t\t\t\t\t\tngbRunTransition(this._ngZone, panelElement, ngbCollapsingTransition, {\n\t\t\t\t\t\t\tanimation: false,\n\t\t\t\t\t\t\trunningTransition: 'continue',\n\t\t\t\t\t\t\tcontext: { direction: panel.isOpen ? 'show' : 'hide', dimension: 'height' },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Classes must be initialized next time it will be in the dom\n\t\t\t\t\tpanel.initClassDone = false;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate _changeOpenState(panel: NgbPanel | null, nextState: boolean) {\n\t\tif (panel != null && !panel.disabled && panel.isOpen !== nextState) {\n\t\t\tlet defaultPrevented = false;\n\n\t\t\tthis.panelChange.emit({\n\t\t\t\tpanelId: panel.id,\n\t\t\t\tnextState: nextState,\n\t\t\t\tpreventDefault: () => {\n\t\t\t\t\tdefaultPrevented = true;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (!defaultPrevented) {\n\t\t\t\tpanel.isOpen = nextState;\n\t\t\t\tpanel.transitionRunning = true;\n\n\t\t\t\tif (nextState && this.closeOtherPanels) {\n\t\t\t\t\tthis._closeOthers(panel.id);\n\t\t\t\t}\n\t\t\t\tthis._updateActiveIds();\n\t\t\t\tthis._runTransitions(this.animation);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _closeOthers(panelId: string, enableTransition = true) {\n\t\tthis.panels.forEach((panel) => {\n\t\t\tif (panel.id !== panelId && panel.isOpen) {\n\t\t\t\tpanel.isOpen = false;\n\t\t\t\tpanel.transitionRunning = enableTransition;\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate _findPanelById(panelId: string): NgbPanel | null {\n\t\treturn this.panels.find((p) => p.id === panelId) || null;\n\t}\n\n\tprivate _updateActiveIds() {\n\t\tthis.activeIds = this.panels.filter((panel) => panel.isOpen && !panel.disabled).map((panel) => panel.id);\n\t}\n\n\tprivate _runTransitions(animation: boolean) {\n\t\t// detectChanges is performed to ensure that all panels are in the dom (via transitionRunning = true)\n\t\t// before starting the animation\n\t\tthis._changeDetector.detectChanges();\n\n\t\tthis.panels.forEach((panel) => {\n\t\t\t// When panel.transitionRunning is true, the transition needs to be started OR reversed,\n\t\t\t// The direction (show or hide) is choosen by each panel.isOpen state\n\t\t\tif (panel.transitionRunning) {\n\t\t\t\tconst panelElement = panel.panelDiv;\n\t\t\t\tngbRunTransition(this._ngZone, panelElement!, ngbCollapsingTransition, {\n\t\t\t\t\tanimation,\n\t\t\t\t\trunningTransition: 'stop',\n\t\t\t\t\tcontext: { direction: panel.isOpen ? 'show' : 'hide', dimension: 'height' },\n\t\t\t\t}).subscribe(() => {\n\t\t\t\t\tpanel.transitionRunning = false;\n\t\t\t\t\tconst { id } = panel;\n\t\t\t\t\tif (panel.isOpen) {\n\t\t\t\t\t\tpanel.shown.emit();\n\t\t\t\t\t\tthis.shown.emit(id);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpanel.hidden.emit();\n\t\t\t\t\t\tthis.hidden.emit(id);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n}\n","import { Injectable } from '@angular/core';\nimport { NgbConfig } from '../ngb-config';\n\n/**\n * A configuration service for the [NgbCollapse](#/components/collapse/api#NgbCollapse) component.\n *\n * You can inject this service, typically in your root component, and customize its properties\n * to provide default values for all collapses used in the application.\n */\n@Injectable({ providedIn: 'root' })\nexport class NgbCollapseConfig {\n\tprivate _animation: boolean;\n\thorizontal = false;\n\n\tconstructor(private _ngbConfig: NgbConfig) {}\n\n\tget animation(): boolean {\n\t\treturn this._animation === undefined ? this._ngbConfig.animation : this._animation;\n\t}\n\tset animation(animation: boolean) {\n\t\tthis._animation = animation;\n\t}\n}\n","import { Directive, ElementRef, EventEmitter, Input, NgZone, OnInit, Output } from '@angular/core';\nimport { ngbRunTransition } from '../util/transition/ngbTransition';\nimport { ngbCollapsingTransition } from '../util/transition/ngbCollapseTransition';\nimport { NgbCollapseConfig } from './collapse-config';\n\n/**\n * A directive to provide a simple way of hiding and showing elements on the\n * page.\n */\n@Directive({\n\tselector: '[ngbCollapse]',\n\texportAs: 'ngbCollapse',\n\tstandalone: true,\n\thost: { '[class.collapse-horizontal]': 'horizontal' },\n})\nexport class NgbCollapse implements OnInit {\n\t/**\n\t * If `true`, collapse will be animated.\n\t *\n\t * Animation is triggered only when clicked on triggering element\n\t * or via the `.toggle()` function\n\t *\n\t * @since 8.0.0\n\t */\n\t@Input() animation;\n\n\t/**\n\t * Flag used to track if the collapse setter is invoked during initialization\n\t * or not. This distinction is made in order to avoid running the transition during initialization.\n\t */\n\tprivate _afterInit = false;\n\n\tprivate _isCollapsed = false;\n\n\t/**\n\t * If `true`, will collapse the element or show it otherwise.\n\t */\n\t@Input('ngbCollapse')\n\tset collapsed(isCollapsed: boolean) {\n\t\tif (this._isCollapsed !== isCollapsed) {\n\t\t\tthis._isCollapsed = isCollapsed;\n\t\t\tif (this._afterInit) {\n\t\t\t\tthis._runTransitionWithEvents(isCollapsed, this.animation);\n\t\t\t}\n\t\t}\n\t}\n\n\t@Output() ngbCollapseChange = new EventEmitter<boolean>();\n\n\t/**\n\t * If `true`, will collapse horizontally.\n\t *\n\t * @since 13.1.0\n\t */\n\t@Input() horizontal: boolean;\n\n\t/**\n\t * An event emitted when the collapse element is shown, after the transition.\n\t * It has no payload.\n\t *\n\t * @since 8.0.0\n\t */\n\t@Output() shown = new EventEmitter<void>();\n\n\t/**\n\t * An event emitted when the collapse element is hidden, after the transition.\n\t * It has no payload.\n\t *\n\t * @since 8.0.0\n\t */\n\t@Output() hidden = new EventEmitter<void>();\n\n\tconstructor(private _element: ElementRef, config: NgbCollapseConfig, private _zone: NgZone) {\n\t\tthis.animation = config.animation;\n\t\tthis.horizontal = config.horizontal;\n\t}\n\n\tngOnInit() {\n\t\tthis._runTransition(this._isCollapsed, false);\n\t\tthis._afterInit = true;\n\t}\n\n\t/**\n\t * Triggers collapsing programmatically.\n\t *\n\t * If there is a collapsing transition running already, it will be reversed.\n\t * If the animations are turned off this happens synchronously.\n\t *\n\t * @since 8.0.0\n\t */\n\ttoggle(open: boolean = this._isCollapsed) {\n\t\tthis.collapsed = !open;\n\t\tthis.ngbCollapseChange.next(this._isCollapsed);\n\t}\n\n\tprivate _runTransition(collapsed: boolean, animation: boolean) {\n\t\treturn ngbRunTransition(this._zone, this._element.nativeElement, ngbCollapsingTransition, {\n\t\t\tanimation,\n\t\t\trunningTransition: 'stop',\n\t\t\tcontext: { direction: collapsed ? 'hide' : 'show', dimension: this.horizontal ? 'width' : 'height' },\n\t\t});\n\t}\n\n\tprivate _runTransitionWithEvents(collapsed: boolean, animation: boolean) {\n\t\tthis._runTransition(collapsed, animation).subscribe(() => {\n\t\t\tif (collapsed) {\n\t\t\t\tthis.hidden.emit();\n\t\t\t} else {\n\t\t\t\tthis.shown.emit();\n\t\t\t}\n\t\t});\n\t}\n}\n","import {\n\tAfterContentChecked,\n\tAfterContentInit,\n\tApplicationRef,\n\tChangeDetectorRef,\n\tContentChild,\n\tContentChildren,\n\tDirective,\n\tElementRef,\n\tEmbeddedViewRef,\n\tEventEmitter,\n\tforwardRef,\n\tinject,\n\tInject,\n\tInput,\n\tOnDestroy,\n\tOutput,\n\tQueryList,\n\tTemplateRef,\n} from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { NgbAccordionConfig } from './accordion-config';\nimport { NgbCollapse } from '../collapse/collapse';\nimport { isString } from '../util/util';\n\nlet nextId = 0;\n\n/**\n * A directive that wraps the content of an accordion item's collapsible body.\n *\n * The actual content is provided in a child `ng-template` element.\n * Depending on the state of the accordion, the template will be either inserted or removed from the DOM.\n *\n * @since 14.1.0\n */\n@Directive({\n\tselector: '[ngbAccordionBody]',\n\tstandalone: true,\n\thost: { '[class.accordion-body]': 'true' },\n})\nexport class NgbAccordionBody implements AfterContentChecked, OnDestroy {\n\tprivate _appRef = inject(ApplicationRef);\n\tprivate _element = inject(ElementRef<HTMLElement>).nativeElement;\n\tprivate _item = inject(NgbAccordionItem);\n\n\tprivate _viewRef: EmbeddedViewRef<any> | null = null;\n\n\t@ContentChild(TemplateRef, { static: true }) private _bodyTpl: TemplateRef<any>;\n\n\tngAfterContentChecked(): void {\n\t\tif (this._bodyTpl) {\n\t\t\tif (this._item.animatingBodyCollapse || !this._item.destroyOnHide) {\n\t\t\t\tthis._createViewIfNotExists();\n\t\t\t} else {\n\t\t\t\tthis._destroyViewIfExists();\n\t\t\t}\n\t\t}\n\t}\n\n\tngOnDestroy(): void {\n\t\tthis._destroyViewIfExists();\n\t}\n\n\tprivate _destroyViewIfExists(): void {\n\t\tif (this._viewRef) {\n\t\t\tthis._appRef.detachView(this._viewRef);\n\t\t\tthis._viewRef.destroy();\n\t\t\tthis._viewRef = null;\n\t\t}\n\t}\n\n\tprivate _createViewIfNotExists(): void {\n\t\tif (!this._viewRef) {\n\t\t\tthis._viewRef = this._bodyTpl.createEmbeddedView(null);\n\t\t\tthis._viewRef.detectChanges();\n\t\t\tthis._appRef.attachView(this._viewRef);\n\t\t\tfor (const node of this._viewRef.rootNodes) {\n\t\t\t\tthis._element.appendChild(node);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * A directive that wraps the collapsible item's content of the accordion.\n *\n * Internally it reuses the [`NgbCollapse` directive](#/components/collapse)\n *\n * @since 14.1.0\n */\n@Directive({\n\texportAs: 'ngbAccordionCollapse',\n\tstandalone: true,\n\tselector: '[ngbAccordionCollapse]',\n\thost: {\n\t\trole: 'region',\n\t\t'[class.accordion-collapse]': 'true',\n\t\t'[id]': 'item.collapseId',\n\t\t'[attr.aria-labelledby]': 'item.toggleId',\n\t},\n\thostDirectives: [\n\t\t{\n\t\t\tdirective: NgbCollapse,\n\t\t},\n\t],\n})\nexport class NgbAccordionCollapse {\n\tconstructor(\n\t\t@Inject(forwardRef(() => NgbAccordionItem)) public item: NgbAccordionItem,\n\t\tpublic ngbCollapse: NgbCollapse,\n\t) {}\n}\n\n/**\n * A directive to put on a toggling element inside the accordion item's header.\n * It will register click handlers that toggle the associated panel and will handle accessibility attributes.\n *\n * This directive is used internally by the [`NgbAccordionButton` directive](#/components/accordion/api#NgbAccordionButton).\n *\n * @since 14.1.0\n */\n@Directive({\n\tselector: '[ngbAccordionToggle]',\n\tstandalone: true,\n\thost: {\n\t\t'[id]': 'item.toggleId',\n\t\t'[class.collapsed]': 'item.collapsed',\n\t\t'[attr.aria-controls]': 'item.collapseId',\n\t\t'[attr.aria-expanded]': '!item.collapsed',\n\t\t'(click)': '!item.disabled && accordion.toggle(item.id)',\n\t},\n})\nexport class NgbAccordionToggle {\n\tconstructor(\n\t\t@Inject(forwardRef(() => NgbAccordionItem)) public item: NgbAccordionItem,\n\t\t@Inject(forwardRef(() => NgbAccordionDirective)) public accordion: NgbAccordionDirective,\n\t) {}\n}\n\n/**\n * A directive to put on a button element inside an accordion item's header.\n *\n * If you want a custom markup for the header, you can also use the [`NgbAccordionToggle` directive](#/components/accordion/api#NgbAccordionToggle).\n *\n * @since 14.1.0\n */\n@Directive({\n\tselector: 'button[ngbAccordionButton]',\n\tstandalone: true,\n\thost: {\n\t\t'[disabled]': 'item.disabled',\n\t\t'[class.accordion-button]': 'true',\n\t\ttype: 'button',\n\t},\n\thostDirectives: [\n\t\t{\n\t\t\tdirective: NgbAccordionToggle,\n\t\t},\n\t],\n})\nexport class NgbAccordionButton {\n\tconstructor(@Inject(forwardRef(() => NgbAccordionItem)) public item: NgbAccordionItem) {}\n}\n\n/**\n * A directive that wraps an accordion item's header.\n *\n * @since 14.1.0\n */\n@Directive({\n\tselector: '[ngbAccordionHeader]',\n\tstandalone: true,\n\thost: {\n\t\trole: 'heading',\n\t\t'[class.accordion-header]': 'true',\n\t\t'[class.collapsed]': 'item.collapsed',\n\t},\n})\nexport class NgbAccordionHeader {\n\tconstructor(@Inject(forwardRef(() => NgbAccordionItem)) public item: NgbAccordionItem) {}\n}\n\n/**\n * A directive that wraps an accordion item: a toggleable header + body that collapses.\n *\n * You can get hold of the `NgbAccordionItem` instance in the template with `#item=\"ngbAccordionItem\"`.\n * It allows to check if the item is collapsed or not, toggle the collapse state, etc.\n *\n * Every accordion item has a string ID that is automatically generated in the `ngb-accordion-item-XX` format, unless provided explicitly.\n *\n * @since 14.1.0\n */\n@Directive({\n\tselector: '[ngbAccordionItem]',\n\texportAs: 'ngbAccordionItem',\n\tstandalone: true,\n\thost: {\n\t\t'[class.accordion-item]': 'true',\n\t\t'[id]': 'id',\n\t},\n})\nexport class NgbAccordionItem implements AfterContentInit, OnDestroy {\n\tconstructor(\n\t\t@Inject(forwardRef(() => NgbAccordionDirective)) private _accordion: NgbAccordionDirective,\n\t\tprivate _cd: ChangeDetectorRef,\n\t) {}\n\n\tprivate _subscriptions: Subscription[] = [];\n\tprivate _collapsed = true;\n\tprivate _id = `ngb-accordion-item-${nextId++}`;\n\tprivate _destroyOnHide: boolean | undefined;\n\n\tanimatingBodyCollapse = false;\n\n\t@ContentChild(NgbAccordionCollapse, { static: true }) private _collapse: NgbAccordionCollapse;\n\n\t/**\n\t * Sets the custom ID of the accordion item. It must be unique for the document.\n\t *\n\t * @param id The ID of the accordion item, must be a non-empty string\n\t */\n\t@Input('ngbAccordionItem') set id(id: string) {\n\t\tif (isString(id) && id !== '') {\n\t\t\tthis._id = id;\n\t\t}\n\t}\n\n\t/**\n\t * If `true`, the content of the accordion item's body will be removed from the DOM. It will be just hidden otherwise.\n\t *\n\t * This property can also be set up on the parent [`NgbAccordion` directive](#/components/accordion/api#NgbAccordionDirective).\n\t */\n\t@Input() set destroyOnHide(destroyOnHide: boolean) {\n\t\tthis._destroyOnHide = destroyOnHide;\n\t}\n\n\tget destroyOnHide(): boolean {\n\t\treturn this._destroyOnHide === undefined ? this._accordion.destroyOnHide : this._destroyOnHide!;\n\t}\n\n\t/**\n\t * If `true`, the accordion item will be disabled.\n\t * It won't react to user's clicks, but still will be toggelable programmatically.\n\t */\n\t@Input() disabled = false;\n\n\t/**\n\t *\tIf `true`, the accordion item will be collapsed. Otherwise, it will be expanded.\n\t *\n\t * @param collapsed New state of the accordion item.\n\t */\n\t@Input() set collapsed(collapsed: boolean) {\n\t\tif (this.collapsed !== collapsed) {\n\t\t\t// checking if accordion allows to expand the panel in respect to 'closeOthers' flag\n\t\t\tif (this.collapsed && !this._accordion._ensureCanExpand(this)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// changing the collapsed state\n\t\t\tthis._collapsed = collapsed;\n\n\t\t\tthis._cd.markForCheck(); // need if the accordion is used inside a component having OnPush change detection strategy\n\t\t\t// we need force CD to get template into DOM before starting animation to calculate its height correctly\n\t\t\tif (!this.collapsed) {\n\t\t\t\tthis.animatingBodyCollapse = true;\n\t\t\t\tthis._cd.detectChanges();\n\t\t\t}\n\n\t\t\t// firing events before starting animations\n\t\t\tif (!this.collapsed) {\n\t\t\t\tthis.show.emit();\n\t\t\t\tthis._accordion.show.emit(this.id);\n\t\t\t} else {\n\t\t\t\tthis.hide.emit();\n\t\t\t\tthis._accordion.hide.emit(this.id);\n\t\t\t}\n\n\t\t\t// we also need to make sure 'animation' flag is up-to- date\n\t\t\tthis._collapse.ngbCollapse.animation = this._accordion.animation;\n\t\t\tthis._collapse.ngbCollapse.collapsed = this.collapsed;\n\t\t}\n\t}\n\n\t/**\n\t * Event emitted before the expanding animation starts. It has no payload.\n\t *\n\t * @since 15.1.0\n\t */\n\t@Output() show = new EventEmitter<void>();\n\n\t/**\n\t * Event emitted when the expanding animation is finished. It has no payload.\n\t */\n\t@Output() shown = new EventEmitter<void>();\n\n\t/**\n\t * Event emitted before the collapsing animation starts. It has no payload.\n\t *\n\t * @since 15.1.0\n\t */\n\t@Output() hide = new EventEmitter<void>();\n\n\t/**\n\t * Event emitted when the collapsing animation is finished and before the content is removed from DOM.\n\t * It has no payload.\n\t */\n\t@Output() hidden = new EventEmitter<void>();\n\n\tget collapsed() {\n\t\treturn this._collapsed;\n\t}\n\n\tget id() {\n\t\treturn `${this._id}`;\n\t}\n\n\tget toggleId() {\n\t\treturn `${this.id}-toggle`;\n\t}\n\n\tget collapseId() {\n\t\treturn `${this.id}-collapse`;\n\t}\n\n\tngAfterContentInit() {\n\t\tconst { ngbCollapse } = this._collapse;\n\t\t// we need to disable the animation for the first init\n\t\tngbCollapse.animation = false;\n\t\tngbCollapse.collapsed = this.collapsed;\n\t\t// we set the animation to the default of the accordion\n\t\tngbCollapse.animation = this._accordion.animation;\n\t\t// event forwarding from 'ngbCollapse' to 'ngbAccordion'\n\t\tthis._subscriptions.push(\n\t\t\tngbCollapse.hidden.subscribe(() => {\n\t\t\t\t// when the animation finishes we can remove the template from DOM\n\t\t\t\tthis.animatingBodyCollapse = false;\n\t\t\t\tthis.hidden.emit();\n\t\t\t\tthis._accordion.hidden.emit(this.id);\n\t\t\t}),\n\t\t\tngbCollapse.shown.subscribe(() => {\n\t\t\t\tthis.shown.emit();\n\t\t\t\tthis._accordion.shown.emit(this.id);\n\t\t\t}),\n\t\t);\n\t}\n\n\tngOnDestroy() {\n\t\tthis._subscriptions.forEach((s) => s.unsubscribe());\n\t}\n\n\t/**\n\t * Toggles an accordion item.\n\t */\n\ttoggle() {\n\t\tthis.collapsed = !this.collapsed;\n\t}\n\n\t/**\n\t * Expands an accordion item.\n\t */\n\texpand() {\n\t\tthis.collapsed = false;\n\t}\n\n\t/**\n\t * Collapses an accordion item.\n\t */\n\tcollapse() {\n\t\tthis.collapsed = true;\n\t}\n}\n\n/**\n * Accordion is a stack of cards that have a header and collapsible body.\n *\n * This directive is a container for these items and provides an API to handle them.\n *\n * @since 14.1.0\n */\n@Directive({\n\tselector: '[ngbAccordion]',\n\tstandalone: true,\n\texportAs: 'ngbAccordion',\n\thost: { '[class.accordion]': 'true' },\n})\nexport class NgbAccordionDirective {\n\t@ContentChildren(NgbAccordionItem, { descendants: false }) private _items?: QueryList<NgbAccordionItem>;\n\t/**\n\t * If `true`, accordion will be animated.\n\t */\n\t@Input() animation: boolean;\n\n\t/**\n\t * If `true`, only one item at the time can stay open.\n\t */\n\t@Input() closeOthers: boolean;\n\n\t/**\n\t * If `true`, the content of the accordion items body will be removed from the DOM. It will be just hidden otherwise.\n\t *\n\t * This property can be overwritten at the [`NgbAccordionItem`](#/components/accordion/api#NgbAccordionItem) level\n\t */\n\t@Input() destroyOnHide = true;\n\n\t/**\n\t * Event emitted before expanding animation starts. The payload is the id of shown accordion item.\n\t *\n\t * @since 15.1.0\n\t */\n\t@Output() show = new EventEmitter<string>();\n\n\t/**\n\t * Event emitted when the expanding animation is finished. The payload is the id of shown accordion item.\n\t */\n\t@Output() shown = new EventEmitter<string>();\n\n\t/**\n\t * Event emitted before the collapsing animation starts. The payload is the id of hidden accordion item.\n\t *\n\t * @since 15.1.0\n\t */\n\t@Output() hide = new EventEmitter<string>();\n\n\t/**\n\t * Event emitted when the collapsing animation is finished and before the content is removed from DOM.\n\t * The payload is the id of hidden accordion item.\n\t */\n\t@Output() hidden = new EventEmitter<string>();\n\n\tprivate _anItemWasAlreadyExpandedDuringInitialisation = false;\n\n\tconstructor(config: NgbAccordionConfig) {\n\t\tthis.animation = config.animation;\n\t\tthis.closeOthers = config.closeOthers;\n\t}\n\n\t/**\n\t * Toggles an item with the given id.\n\t *\n\t * It will toggle an item, even if it is disabled.\n\t *\n\t * @param itemId The id of the item to toggle.\n\t */\n\ttoggle(itemId: string) {\n\t\tthis._getItem(itemId)?.toggle();\n\t}\n\n\t/**\n\t * Expands an item with the given id.\n\t *\n\t * If `closeOthers` is `true`, it will collapse other panels.\n\t *\n\t * @param itemId The id of the item to expand.\n\t */\n\texpand(itemId: string) {\n\t\tthis._getItem(itemId)?.expand();\n\t}\n\n\t/**\n\t * Expands all items.\n\t *\n\t * If `closeOthers` is `true` and all items are closed, it will open the first one. Otherwise, it will keep the opened one.\n\t */\n\texpandAll() {\n\t\tif (this._items) {\n\t\t\tif (this.closeOthers) {\n\t\t\t\t// we check if there is an item open and if it is not we can expand the first item\n\t\t\t\t// (otherwise we toggle nothing)\n\t\t\t\tif (!this._items.find((