@myrmidon/paged-data-browsers 5.0.2 → 5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"myrmidon-paged-data-browsers.mjs","sources":["../../../../projects/myrmidon/paged-data-browsers/src/lib/components/compact-pager/compact-pager.component.ts","../../../../projects/myrmidon/paged-data-browsers/src/lib/components/compact-pager/compact-pager.component.html","../../../../projects/myrmidon/paged-data-browsers/src/lib/components/range-view/range-view.component.ts","../../../../projects/myrmidon/paged-data-browsers/src/lib/components/range-view/range-view.component.html","../../../../projects/myrmidon/paged-data-browsers/src/lib/components/browser-tree-node/browser-tree-node.component.ts","../../../../projects/myrmidon/paged-data-browsers/src/lib/components/browser-tree-node/browser-tree-node.component.html","../../../../projects/myrmidon/paged-data-browsers/src/lib/services/lru-cache.ts","../../../../projects/myrmidon/paged-data-browsers/src/lib/services/paged-list.store.ts","../../../../projects/myrmidon/paged-data-browsers/src/lib/services/paged-tree.store.ts","../../../../projects/myrmidon/paged-data-browsers/src/public-api.ts","../../../../projects/myrmidon/paged-data-browsers/src/myrmidon-paged-data-browsers.ts"],"sourcesContent":["import { Component, input, output } from '@angular/core';\r\n\r\nimport { CommonModule } from '@angular/common';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatButtonModule } from '@angular/material/button';\r\n\r\nimport { PagingInfo } from '../../services/paged-tree.store';\r\n\r\n@Component({\r\n selector: 'pdb-compact-pager',\r\n imports: [CommonModule, MatButtonModule, MatIconModule],\r\n templateUrl: './compact-pager.component.html',\r\n styleUrls: ['./compact-pager.component.scss'],\r\n})\r\nexport class CompactPagerComponent {\r\n public paging = input<PagingInfo>({ pageNumber: 0, pageCount: 0, total: 0 });\r\n\r\n /**\r\n * Emits the new paging information when the user changes the page.\r\n */\r\n public readonly pagingChange = output<PagingInfo>();\r\n\r\n public onFirst(): void {\r\n this.pagingChange.emit({ ...this.paging(), pageNumber: 1 });\r\n }\r\n\r\n public onPrevious(): void {\r\n if (this.paging().pageNumber > 1) {\r\n this.pagingChange.emit({\r\n ...this.paging(),\r\n pageNumber: this.paging().pageNumber - 1,\r\n });\r\n }\r\n }\r\n\r\n public onNext(): void {\r\n if (this.paging().pageNumber < this.paging().pageCount) {\r\n this.pagingChange.emit({\r\n ...this.paging(),\r\n pageNumber: this.paging().pageNumber + 1,\r\n });\r\n }\r\n }\r\n\r\n public onLast(): void {\r\n if (this.paging().pageNumber < this.paging().pageCount) {\r\n this.pagingChange.emit({\r\n ...this.paging(),\r\n pageNumber: this.paging().pageCount,\r\n });\r\n }\r\n }\r\n}\r\n","@if (paging().pageCount) {\r\n <div class=\"form-row\">\r\n <span id=\"pages\">{{ paging().pageNumber }}/{{ paging().pageCount }}</span>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"onFirst()\"\r\n [disabled]=\"paging().pageNumber < 2\"\r\n >\r\n <mat-icon>first_page</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"onPrevious()\"\r\n [disabled]=\"paging().pageNumber < 2\"\r\n >\r\n <mat-icon>navigate_before</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"onNext()\"\r\n [disabled]=\"paging().pageNumber === paging().pageCount\"\r\n >\r\n <mat-icon>navigate_next</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"onLast()\"\r\n [disabled]=\"paging().pageNumber === paging().pageCount\"\r\n >\r\n <mat-icon>last_page</mat-icon>\r\n </button>\r\n <span id=\"total\">{{ paging().total }} </span>\r\n </div>\r\n}\r\n","import { Component, computed, input, signal } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'pdb-range-view',\r\n templateUrl: './range-view.component.html',\r\n styleUrls: ['./range-view.component.scss'],\r\n})\r\nexport class RangeViewComponent {\r\n /**\r\n * The domain of the range view (start, limit).\r\n */\r\n public domain = input([0, 100]);\r\n /**\r\n * The range of the range view (start, limit).\r\n */\r\n public range = input([0, 100]);\r\n /**\r\n * The width of the component.\r\n */\r\n public width = input(100);\r\n /**\r\n * The height of the component.\r\n */\r\n public height = input(5);\r\n\r\n public scaledRange = computed(() => {\r\n const domain = this.domain();\r\n const range = this.range();\r\n const width = this.width();\r\n\r\n const domainWidth = domain[1] - domain[0];\r\n const rangeWidth = range[1] - range[0];\r\n const rangeStart = range[0] - domain[0];\r\n\r\n return [\r\n (rangeStart / domainWidth) * width,\r\n ((rangeStart + rangeWidth) / domainWidth) * width,\r\n ];\r\n });\r\n\r\n constructor() {}\r\n}\r\n","<svg [attr.width]=\"width()\" [attr.height]=\"height()\">\r\n <rect id=\"rdomain\" [attr.width]=\"width()\" [attr.height]=\"height()\" />\r\n <rect\r\n id=\"rrange\"\r\n [attr.x]=\"scaledRange()[0]\"\r\n [attr.y]=\"0\"\r\n [attr.width]=\"scaledRange()[1] - scaledRange()[0]\"\r\n [attr.height]=\"height()\"\r\n />\r\n</svg>\r\n","import { Component, input, output } from '@angular/core';\r\n\r\nimport { CommonModule } from '@angular/common';\r\nimport { MatBadgeModule } from '@angular/material/badge';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\nimport { MatIconModule } from '@angular/material/icon';\r\n\r\nimport { ColorToContrastPipe, StringToColorPipe } from '@myrmidon/ngx-tools';\r\n\r\nimport { PagedTreeNode, PagingInfo } from '../../services/paged-tree.store';\r\nimport { CompactPagerComponent } from '../compact-pager/compact-pager.component';\r\nimport { RangeViewComponent } from '../range-view/range-view.component';\r\n\r\n/**\r\n * A request to change the page number of a node's children.\r\n */\r\nexport interface PageChangeRequest {\r\n node: PagedTreeNode<any>;\r\n paging: PagingInfo;\r\n}\r\n\r\n/**\r\n * Browser tree node component view. This wraps some HTML content providing\r\n * a toggle button to expand/collapse the node, a paging control for the\r\n * node's children, and a button to edit the node's filter. You should then\r\n * provide the HTML content to display the node's data inside this component, e.g.\r\n * <pdb-browser-tree-node [node]=\"node\">\r\n * <your-node-view [node]=\"node\" />\r\n * <pdb-browser-tree-node>\r\n */\r\n@Component({\r\n selector: 'pdb-browser-tree-node',\r\n imports: [\r\n CommonModule,\r\n MatBadgeModule,\r\n MatButtonModule,\r\n MatIconModule,\r\n MatTooltipModule,\r\n // ngx-tools\r\n ColorToContrastPipe,\r\n StringToColorPipe,\r\n // local\r\n CompactPagerComponent,\r\n RangeViewComponent,\r\n ],\r\n templateUrl: './browser-tree-node.component.html',\r\n styleUrls: ['./browser-tree-node.component.css'],\r\n})\r\nexport class BrowserTreeNodeComponent {\r\n /**\r\n * The node to display.\r\n */\r\n public readonly node = input<PagedTreeNode<any> | undefined | null>();\r\n\r\n /**\r\n * The paging information for the node's children.\r\n */\r\n public readonly paging = input<PagingInfo>();\r\n\r\n /**\r\n * True to show debug information.\r\n */\r\n public readonly debug = input<boolean>();\r\n\r\n /**\r\n * True to hide the node's loc and label. This is useful if you want to\r\n * provide your own view for the node, between the expansion toggle and\r\n * the filter edit button. In this case, in your consumer template provide\r\n * your own view as the content of this component. If instead you are fine\r\n * with the default loc and label, and just want to add more data to\r\n * the view, then you can just add your own content to this component's\r\n * template, without setting this property to true.\r\n */\r\n public readonly hideLabel = input<boolean>();\r\n\r\n /**\r\n * True to hide the node's location (y and x).\r\n */\r\n public readonly hideLoc = input<boolean>();\r\n\r\n /**\r\n * True to hide the node's paging control unless hovered.\r\n */\r\n public readonly hidePaging = input<boolean>();\r\n\r\n /**\r\n * True to hide the node's filter edit button.\r\n */\r\n public readonly hideFilter = input<boolean>();\r\n\r\n /**\r\n * The indent size for the node's children.\r\n */\r\n public readonly indentSize = input(30);\r\n\r\n /**\r\n * The width of the range view.\r\n */\r\n public readonly rangeWidth = input(250);\r\n\r\n /**\r\n * Emits when the user wants to toggle the expanded state of the node.\r\n */\r\n public readonly toggleExpandedRequest = output<PagedTreeNode<any>>();\r\n\r\n /**\r\n * Emits when the user wants to change the page number of the node's children.\r\n */\r\n public readonly changePageRequest = output<PageChangeRequest>();\r\n\r\n /**\r\n * Emits when the user wants to edit the node's filter.\r\n */\r\n public readonly editNodeFilterRequest = output<PagedTreeNode<any>>();\r\n\r\n public onToggleExpanded(): void {\r\n if (!this.node()) {\r\n return;\r\n }\r\n this.toggleExpandedRequest.emit(this.node() as PagedTreeNode<any>);\r\n }\r\n\r\n public onPagingChange(node: PagedTreeNode<any>, paging: PagingInfo): void {\r\n this.changePageRequest.emit({\r\n node,\r\n paging,\r\n });\r\n }\r\n\r\n public onEditFilter(): void {\r\n if (this.node()) {\r\n this.editNodeFilterRequest.emit(this.node() as PagedTreeNode<any>);\r\n }\r\n }\r\n}\r\n","@if (node()) {\r\n<div id=\"node\" [style.margin-left.px]=\"(node()!.y - 1) * indentSize()\">\r\n <!-- pager -->\r\n @if (node()!.expanded && paging() && paging()!.pageCount > 1) {\r\n <div id=\"pager\" [style.display]=\"hidePaging() ? 'inherit' : 'block'\">\r\n <pdb-compact-pager\r\n [paging]=\"paging()!\"\r\n (pagingChange)=\"onPagingChange(node()!, $event)\"\r\n />\r\n <pdb-range-view\r\n [width]=\"rangeWidth()\"\r\n [domain]=\"[0, paging()!.pageCount]\"\r\n [range]=\"[paging()!.pageNumber - 1, paging()!.pageNumber]\"\r\n />\r\n </div>\r\n }\r\n <!-- node -->\r\n <div class=\"form-row\">\r\n <!-- expand/collapse button -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [matTooltip]=\"node()?.expanded ? 'Collapse' : 'Expand'\"\r\n i18n-matTooltip\r\n [disabled]=\"node()!.hasChildren === false\"\r\n (click)=\"onToggleExpanded()\"\r\n >\r\n <mat-icon class=\"mat-primary\" i18n>\r\n @if (node()!.hasChildren === true) { @if (node()!.expanded) {\r\n chevron_left } @else { chevron_right } } @else { stop }\r\n </mat-icon>\r\n </button>\r\n\r\n <!-- tag -->\r\n @if (!hideLabel()) {\r\n <span\r\n class=\"tag\"\r\n [ngStyle]=\"{\r\n 'background-color': (node()!.tag | stringToColor),\r\n color: node()!.tag | stringToColor | colorToContrast\r\n }\"\r\n >{{ node()!.tag }}</span\r\n >\r\n\r\n <!-- loc and label -->\r\n @if (!hideLoc()) {\r\n <span class=\"loc\">{{ node()!.y }}.{{ node()!.x }}</span> - }\r\n {{ node()!.label }}\r\n }\r\n\r\n <!-- PROJECTED NODE -->\r\n <ng-content></ng-content>\r\n\r\n <!-- debug -->\r\n @if (debug()) {\r\n <span class=\"debug\"\r\n >#{{ node()!.id }}\r\n <span\r\n >| {{ node()!.paging.pageNumber }}/{{ node()!.paging.pageCount }} ({{\r\n node()!.paging.total\r\n }})</span\r\n ></span\r\n >\r\n }\r\n\r\n <!-- filter -->\r\n @if (!hideFilter()){ @if (!node()?.filter && node()?.y) {\r\n <div class=\"muted\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Add filter\"\r\n i18n-matTooltip\r\n (click)=\"onEditFilter()\"\r\n >\r\n <mat-icon>filter_list</mat-icon>\r\n </button>\r\n </div>\r\n } @if (node()?.filter && node()?.y) {\r\n <div class=\"muted\">\r\n <button type=\"button\" mat-icon-button (click)=\"onEditFilter()\">\r\n <mat-icon [matBadge]=\"node()?.filter ? 'F' : ''\">filter_alt</mat-icon>\r\n </button>\r\n </div>\r\n } }\r\n </div>\r\n</div>\r\n}\r\n","/**\r\n * A Least Recently Used cache that can be used to store any type of object.\r\n * The cache works in two modes: considering the size of the objects or not.\r\n * If the size is considered, the cache will have a maximum size and will\r\n * remove the oldest objects when the maximum size is reached. Note that\r\n * the size is only roughly estimated. This avoids removing too many\r\n * entries from the cache when the maximum is reached.\r\n * If the size is not considered, the cache will have a maximum number of\r\n * objects and will remove the oldest objects when the maximum number is\r\n * reached.\r\n */\r\nexport class LRUCache<T> {\r\n private _maxSize: number;\r\n private _totalSize: number;\r\n private _considerSize: boolean;\r\n private _cache: Map<string, T>;\r\n private _sizes: Map<string, number>;\r\n\r\n /**\r\n * Creates a new cache.\r\n * @param maxSize The maximum size of the cache. This is either\r\n * the maximum number of items in the cache (when considerSize\r\n * is false) or the maximum total size of all items in the\r\n * cache in bytes (when considerSize is true).\r\n * @param considerSize True if the size of the objects should be\r\n * considered.\r\n */\r\n constructor(maxSize: number, considerSize: boolean = false) {\r\n this._maxSize = maxSize;\r\n this._totalSize = 0;\r\n this._considerSize = considerSize;\r\n this._cache = new Map<string, T>();\r\n this._sizes = new Map<string, number>();\r\n }\r\n\r\n /**\r\n * Get an item from the cache.\r\n * @param key The key of the item to get.\r\n * @returns The item or undefined if the item is not in the cache.\r\n */\r\n public get(key: string): T | undefined {\r\n let item: T | undefined = this._cache.get(key);\r\n if (item) {\r\n this._cache.delete(key);\r\n this._cache.set(key, item);\r\n }\r\n return item;\r\n }\r\n\r\n /**\r\n * Check if an item is in the cache.\r\n * @param key The key of the item to check.\r\n * @returns True if the item is in cache.\r\n */\r\n public has(key: string): boolean {\r\n return this._cache.has(key);\r\n }\r\n\r\n /**\r\n * Put an item in the cache.\r\n * @param key The key of the item to put.\r\n * @param item The item to put.\r\n * @param size The estimated size of the item in bytes.\r\n * This must be calculated by the caller but only when\r\n * considerSize is true.\r\n */\r\n public put(key: string, item: T, size: number): void {\r\n this._cache.delete(key);\r\n this._cache.set(key, item);\r\n this._sizes.set(key, size);\r\n if (this._considerSize) {\r\n this._totalSize += size;\r\n while (this._totalSize > this._maxSize) {\r\n const oldestKey = this._cache.keys().next().value;\r\n if (!oldestKey) {\r\n break;\r\n }\r\n let oldestSize = this._sizes.get(oldestKey);\r\n if (oldestSize) {\r\n this._totalSize -= oldestSize;\r\n }\r\n this._cache.delete(oldestKey);\r\n this._sizes.delete(oldestKey);\r\n }\r\n } else {\r\n while (this._cache.size > this._maxSize) {\r\n const oldestKey = this._cache.keys().next().value;\r\n if (!oldestKey) {\r\n break;\r\n }\r\n this._cache.delete(oldestKey);\r\n this._sizes.delete(oldestKey);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear the cache.\r\n */\r\n public clear(): void {\r\n this._cache.clear();\r\n this._sizes.clear();\r\n this._totalSize = 0;\r\n }\r\n\r\n /**\r\n * Estimate the size of an object in bytes.\r\n * @param obj The object to calculate the size of.\r\n * @returns The estimated size of the object in bytes.\r\n */\r\n public static calculateObjectSize(obj: any): number {\r\n if (!obj) {\r\n return 0;\r\n }\r\n let totalSize = 0;\r\n let keys = Object.keys(obj);\r\n for (let key of keys) {\r\n let value = obj[key];\r\n if (typeof value === 'string') {\r\n totalSize += value.length * 2;\r\n } else if (typeof value === 'number') {\r\n totalSize += 8;\r\n } else if (typeof value === 'boolean') {\r\n totalSize += 4;\r\n } else if (typeof value === 'object' && value !== null) {\r\n totalSize += this.calculateObjectSize(value);\r\n }\r\n }\r\n return totalSize;\r\n }\r\n}\r\n","import { BehaviorSubject, Observable } from 'rxjs';\r\n\r\nimport { DataPage } from '@myrmidon/ngx-tools';\r\n\r\nimport { LRUCache } from './lru-cache';\r\n\r\n/**\r\n * Options for the paged list store.\r\n */\r\nexport interface PagedListStoreOptions {\r\n /**\r\n * The size of pages in the store.\r\n */\r\n pageSize: number;\r\n /**\r\n * The size of the cache for pages in the store.\r\n */\r\n cacheSize: number;\r\n\r\n /**\r\n * A custom function for building the cache key for the given page number\r\n * and filter.\r\n * @param pageNumber The page number.\r\n * @param filter The filter.\r\n * @returns A string to be used as cache key.\r\n */\r\n buildCacheKey?: (pageNumber: number, filter: any) => string;\r\n}\r\n\r\n/**\r\n * Default options for the paged list store.\r\n */\r\nexport const DEFAULT_PAGED_LIST_STORE_OPTIONS: PagedListStoreOptions = {\r\n pageSize: 20,\r\n cacheSize: 50,\r\n};\r\n\r\n/**\r\n * The interface to be implemented by the service used by PagedListStore.\r\n */\r\nexport interface PagedListStoreService<F, E> {\r\n /**\r\n * Load the page with the given number.\r\n * @param pageNumber The page number to load.\r\n * @param pageSize The size of the page to load.\r\n * @param filter The filter to apply.\r\n */\r\n loadPage(\r\n pageNumber: number,\r\n pageSize: number,\r\n filter: F\r\n ): Observable<DataPage<E>>;\r\n}\r\n\r\n/**\r\n * A generic paged list store using a filter object of type F\r\n * and a list of elements of type E.\r\n */\r\nexport class PagedListStore<F, E> {\r\n private _pageSize: number;\r\n private readonly _customCacheKeyBuilder?: (\r\n pageNumber: number,\r\n filter: any\r\n ) => string;\r\n private _page$: BehaviorSubject<DataPage<E>>;\r\n private _filter$: BehaviorSubject<F>;\r\n private readonly _cache: LRUCache<DataPage<E>>;\r\n\r\n /**\r\n * The page. It is updated when the page is changed or the filter is changed.\r\n */\r\n public page$: Observable<Readonly<DataPage<E>>>;\r\n\r\n /**\r\n * The filter. It is updated when the filter is changed.\r\n */\r\n public filter$: Observable<Readonly<F>>;\r\n\r\n /**\r\n * The size of nodes pages in this store. If you change it, the store\r\n * is reset. The default value is 20.\r\n */\r\n public get pageSize(): number {\r\n return this._pageSize;\r\n }\r\n public set pageSize(value: number) {\r\n if (this._pageSize === value) {\r\n return;\r\n }\r\n this._pageSize = value;\r\n this.reset();\r\n }\r\n\r\n /**\r\n * Create a new paged list store.\r\n * @param options Options for the paged list store.\r\n */\r\n constructor(\r\n private _service: PagedListStoreService<F, E>,\r\n options: PagedListStoreOptions = DEFAULT_PAGED_LIST_STORE_OPTIONS\r\n ) {\r\n this._pageSize = options.pageSize;\r\n this._cache = new LRUCache<DataPage<E>>(options.cacheSize);\r\n // page\r\n this._page$ = new BehaviorSubject<DataPage<E>>({\r\n pageNumber: 0,\r\n pageCount: 0,\r\n pageSize: 0,\r\n total: 0,\r\n items: [],\r\n });\r\n this.page$ = this._page$.asObservable();\r\n // filter\r\n this._filter$ = new BehaviorSubject<F>({} as F);\r\n this.filter$ = this._filter$.asObservable();\r\n }\r\n\r\n /**\r\n * Returns true if the store is empty, false otherwise.\r\n * @returns true if the store is empty, false otherwise.\r\n */\r\n public isEmpty(): boolean {\r\n return this._page$.value.items.length === 0;\r\n }\r\n\r\n /**\r\n * Build the cache key for the given page number and filter.\r\n * The default implementation just returns a stringified object\r\n * containing the page number and the filter. You may override\r\n * this method to provide a custom cache key.\r\n * @param pageNumber The page number.\r\n * @param filter The filter.\r\n * @returns A string to be used as cache key.\r\n */\r\n public buildCacheKey(pageNumber: number, filter: F): string {\r\n if (this._customCacheKeyBuilder) {\r\n return this._customCacheKeyBuilder(pageNumber, filter);\r\n }\r\n return JSON.stringify({ pageNumber, ...filter });\r\n }\r\n\r\n /**\r\n * Load the page with the given number.\r\n * @param pageNumber the page number to load.\r\n */\r\n private loadPage(pageNumber: number): Observable<DataPage<E>> {\r\n return this._service.loadPage(\r\n pageNumber,\r\n this._pageSize,\r\n this._filter$.value\r\n );\r\n }\r\n\r\n /**\r\n * Set the page with the given number.\r\n * @param pageNumber The page number to load.\r\n * @param pageSize The page size.\r\n * @returns Promise which resolves when the page is loaded.\r\n */\r\n public setPage(pageNumber: number, pageSize?: number): Promise<void> {\r\n if (pageSize && pageSize !== this._pageSize) {\r\n this._pageSize = pageSize;\r\n }\r\n return new Promise((resolve, reject) => {\r\n // if page is in cache, return it\r\n const key = this.buildCacheKey(pageNumber, this._filter$.value);\r\n const cachedPage = this._cache.get(key);\r\n if (cachedPage) {\r\n this._page$.next(cachedPage);\r\n resolve();\r\n return;\r\n }\r\n\r\n // else load page\r\n this.loadPage(pageNumber).subscribe({\r\n next: (page) => {\r\n this._page$.next(page);\r\n this._cache.put(key, page, 0);\r\n resolve();\r\n },\r\n error: reject,\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Get the current page.\r\n * @returns The current page.\r\n */\r\n public getPage(): DataPage<E> {\r\n return this._page$.value;\r\n }\r\n\r\n /**\r\n * Apply the given filter and load the first page.\r\n * @param filter The filter to apply.\r\n * @returns Promise which resolves when the page is loaded.\r\n */\r\n public setFilter(filter: F): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n this._filter$.next(filter);\r\n this.setPage(1).then(resolve, reject);\r\n });\r\n }\r\n\r\n /**\r\n * Get the current filter.\r\n * @returns The current filter.\r\n */\r\n public getFilter(): F {\r\n return this._filter$.value;\r\n }\r\n\r\n /**\r\n * Reset the filter and load the first page. The cache is cleared.\r\n * @returns Promise which resolves when the page is loaded.\r\n */\r\n public reset(): Promise<void> {\r\n this._cache.clear();\r\n return this.setFilter({} as F);\r\n }\r\n\r\n /**\r\n * Clear the store. The cache is cleared and the page is emptied.\r\n */\r\n public clear(): void {\r\n this._cache.clear();\r\n this._page$.next({\r\n pageNumber: 0,\r\n pageCount: 0,\r\n pageSize: 0,\r\n total: 0,\r\n items: [],\r\n });\r\n }\r\n\r\n /**\r\n * Clear the cache.\r\n */\r\n public clearCache(): void {\r\n this._cache.clear();\r\n }\r\n\r\n /**\r\n * Check if the page with the given number and filter is in cache.\r\n * @param pageNumber The page number.\r\n * @param filter The filter.\r\n * @returns True if the page is in cache, false otherwise.\r\n */\r\n public hasCachedPage(pageNumber: number, filter: F): boolean {\r\n const key = this.buildCacheKey(pageNumber, filter);\r\n return this._cache.has(key);\r\n }\r\n}\r\n","import { BehaviorSubject, Observable, forkJoin, of, tap } from 'rxjs';\r\n\r\nimport { DataPage } from '@myrmidon/ngx-tools';\r\n\r\nimport { LRUCache } from './lru-cache';\r\nimport { DEFAULT_PAGED_LIST_STORE_OPTIONS } from './paged-list.store';\r\n\r\n/**\r\n * A tree node. Your data service should return a list of these nodes\r\n * or of any type extending this interface.\r\n */\r\nexport interface TreeNode {\r\n id: number;\r\n parentId?: number;\r\n y: number;\r\n x: number;\r\n label: string;\r\n tag?: string;\r\n hasChildren?: boolean;\r\n}\r\n\r\n/**\r\n * A filter for tree nodes.\r\n */\r\nexport interface TreeNodeFilter {\r\n tags?: string[];\r\n parentId?: number;\r\n}\r\n\r\n/**\r\n * Paging information for a paged tree node.\r\n */\r\nexport interface PagingInfo {\r\n pageNumber: number;\r\n pageCount: number;\r\n total: number;\r\n}\r\n\r\n/**\r\n * A tree node with paging information, used in NodeBrowserStore.\r\n */\r\nexport interface PagedTreeNode<F extends TreeNodeFilter> extends TreeNode {\r\n paging: PagingInfo;\r\n expanded?: boolean;\r\n filter?: F;\r\n}\r\n\r\n/**\r\n * The interface to be implemented by the service used by NodeBrowserStore\r\n * to load nodes.\r\n */\r\nexport interface PagedTreeStoreService<F extends TreeNodeFilter> {\r\n /**\r\n * Get the specified page of nodes.\r\n * @param filter The filter.\r\n * @param pageNumber The page number.\r\n * @param pageSize The page size.\r\n * @param hasMockRoot If true, the root node is a mock node provided by your\r\n * service, which implies that its Y value is 0 rather than 1. Default is\r\n * false, meaning that your service will return a single root node with Y\r\n * value 1.\r\n */\r\n getNodes(\r\n filter: F,\r\n pageNumber: number,\r\n pageSize: number,\r\n hasMockRoot?: boolean\r\n ): Observable<DataPage<TreeNode>>;\r\n}\r\n\r\n/**\r\n * Options for the NodeBrowserStore.\r\n */\r\nexport interface PagedTreeStoreOptions {\r\n /**\r\n * The size of pages in the store.\r\n */\r\n pageSize: number;\r\n /**\r\n * The size of the cache for pages in the store.\r\n */\r\n cacheSize: number;\r\n /**\r\n * A custom function for building the cache key for the given page number\r\n * and filter.\r\n * @param pageNumber The page number.\r\n * @param filter The filter.\r\n * @returns A string to be used as cache key.\r\n */\r\n buildCacheKey?: (pageNumber: number, filter: any) => string;\r\n /**\r\n * If true, the root node is a mock node provided by your service, which\r\n * implies that its Y value is 0 rather than 1. Default is false, meaning\r\n * that there are many root-level nodes, all with parent ID = undefined.\r\n */\r\n hasMockRoot?: boolean;\r\n}\r\n\r\n/**\r\n * A store for the node browser component. This store is used to keep a\r\n * list of nodes, and to load them from the API. It also keeps the root\r\n * node. Every tree node in the list is extended with page number,\r\n * page count and total items, plus expansion-related metadata.\r\n * The store keeps a flat list of these tree nodes, allowing users to\r\n * expand and collapse them.\r\n * F is the type of the filter object, E is the type of the paged tree nodes.\r\n */\r\nexport class PagedTreeStore<\r\n E extends PagedTreeNode<F>,\r\n F extends TreeNodeFilter\r\n> {\r\n private _nodes$: BehaviorSubject<E[]>;\r\n private _filter$: BehaviorSubject<F>;\r\n private readonly _customCacheKeyBuilder?: (\r\n pageNumber: number,\r\n filter: any\r\n ) => string;\r\n private readonly _cache: LRUCache<DataPage<TreeNode>>;\r\n private readonly _hasMockRoot: boolean;\r\n\r\n private _pageSize: number;\r\n // dirty state: this is reset when the store is reset, and set to true\r\n // when the store is changed\r\n private _dirty?: boolean;\r\n\r\n /**\r\n * The flat list of paged nodes in this store.\r\n */\r\n public nodes$: Observable<Readonly<E[]>>;\r\n\r\n /**\r\n * The global filter for all the nodes.\r\n */\r\n public filter$: Observable<Readonly<F>>;\r\n\r\n /**\r\n * The size of nodes pages in this store. If you change it, the store\r\n * is reset. The default value is 20.\r\n */\r\n public get pageSize(): number {\r\n return this._pageSize;\r\n }\r\n public set pageSize(value: number) {\r\n if (this._pageSize === value) {\r\n return;\r\n }\r\n this._pageSize = value;\r\n this.reset();\r\n }\r\n\r\n /**\r\n * Create an instance of the store.\r\n * @param _service The service used to load nodes.\r\n * @param options The options to configure this store.\r\n */\r\n constructor(\r\n private _service: PagedTreeStoreService<F>,\r\n options: PagedTreeStoreOptions = DEFAULT_PAGED_LIST_STORE_OPTIONS\r\n ) {\r\n this._pageSize = options.pageSize;\r\n this._cache = new LRUCache<DataPage<TreeNode>>(options.cacheSize);\r\n this._customCacheKeyBuilder = options.buildCacheKey;\r\n this._nodes$ = new BehaviorSubject<E[]>([]);\r\n this.nodes$ = this._nodes$.asObservable();\r\n this._filter$ = new BehaviorSubject<F>({} as F);\r\n this.filter$ = this._filter$.asObservable();\r\n this._dirty = true;\r\n this._hasMockRoot = options.hasMockRoot || false;\r\n }\r\n\r\n /**\r\n * Gets the global filter, eventually overridden with values\r\n * from the specified node's filter.\r\n * @param node The optional node.\r\n * @returns The filter.\r\n */\r\n private getFilter(node?: PagedTreeNode<F>): F {\r\n return node?.filter\r\n ? {\r\n ...this._filter$.value,\r\n ...node.filter,\r\n }\r\n : this._filter$.value;\r\n }\r\n\r\n /**\r\n * Checks if this store is empty.\r\n * @returns True if this store is empty.\r\n */\r\n public isEmpty(): boolean {\r\n return this._nodes$.value.length === 0;\r\n }\r\n\r\n /**\r\n * Gets all the nodes in the store.\r\n * @returns The nodes.\r\n */\r\n public getNodes(): Readonly<PagedTreeNode<F>[]> {\r\n return this._nodes$.value;\r\n }\r\n\r\n /**\r\n * Get the root node of the tree.\r\n * @returns The root node of the tree or undefined if empty.\r\n */\r\n public getRootNode(): PagedTreeNode<F> | undefined {\r\n return this._nodes$.value[0];\r\n }\r\n\r\n /**\r\n * Build the cache key for the given page number and filter.\r\n * The default implementation just returns a stringified object\r\n * containing the page number and the filter. You may override\r\n * this method to provide a custom cache key.\r\n * @param pageNumber The page number.\r\n * @param filter The filter.\r\n * @returns A string to be used as cache key.\r\n */\r\n public buildCacheKey(pageNumber: number, filter: F): string {\r\n if (this._customCacheKeyBuilder) {\r\n return this._customCacheKeyBuilder(pageNumber, filter);\r\n }\r\n return JSON.stringify({ ...filter, pageNumber });\r\n }\r\n\r\n /**\r\n * Get the specified page of nodes, either from cache or from the server.\r\n * When the page is retrieved from the server, it is stored in cache.\r\n * @param filter The filter to apply.\r\n * @param pageNumber The page number to get.\r\n * @returns Observable of the page of nodes.\r\n */\r\n private getPageFromCacheOrServer(\r\n filter: F,\r\n pageNumber: number\r\n ): Observable<DataPage<TreeNode>> {\r\n const key = this.buildCacheKey(pageNumber, filter);\r\n const pageInCache = this._cache.get(key);\r\n\r\n if (pageInCache) {\r\n return of(pageInCache);\r\n } else {\r\n return this._service\r\n .getNodes(filter, pageNumber, this._pageSize, this._hasMockRoot)\r\n .pipe(\r\n tap((page) => {\r\n this._cache.put(key, page, 0);\r\n })\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Create paged tree nodes from a page of tree nodes, by providing further\r\n * metadata like page number, page count and total items.\r\n * @param page The page to create nodes from.\r\n * @returns Paged nodes.\r\n */\r\n private createPageNodes(page: DataPage<TreeNode>): E[] {\r\n return page.items.map((n) => {\r\n return {\r\n ...n,\r\n hasChildren: n.hasChildren,\r\n paging: {\r\n pageNumber: page.pageNumber,\r\n pageCount: page.pageCount,\r\n total: page.total,\r\n },\r\n } as E;\r\n });\r\n }\r\n\r\n /**\r\n * Sets the filter for this store. Whenever the filter is set,\r\n * the store is reset.\r\n * @param filter The filter.\r\n * @returns true if tree was changed, false otherwise.\r\n */\r\n public setFilter(filter: F): Promise<boolean> {\r\n if (this._filter$.value === filter) {\r\n return Promise.resolve(false);\r\n }\r\n this._filter$.next(filter);\r\n this._dirty = true;\r\n return this.reset();\r\n }\r\n\r\n /**\r\n * Reset the store, loading the root nodes and their children.\r\n * @returns true if tree was changed, false otherwise.\r\n */\r\n public reset(): Promise<boolean> {\r\n this._cache.clear();\r\n const filter = this._filter$.value;\r\n\r\n return new Promise<boolean>((resolve, reject) => {\r\n this._service\r\n .getNodes(\r\n {\r\n ...filter,\r\n parentId: undefined,\r\n },\r\n 1,\r\n this._pageSize,\r\n this._hasMockRoot\r\n )\r\n .subscribe({\r\n next: (page: DataPage<TreeNode>) => {\r\n this._nodes$.next(this.createPageNodes(page));\r\n\r\n // get the children of each node thus calculating their hasChildren property\r\n const childrenObservables = this._nodes$.value.map((node) =>\r\n this.getPageFromCacheOrServer({ ...filter, parentId: node.id }, 1)\r\n );\r\n forkJoin(childrenObservables).subscribe((childrenPages) => {\r\n childrenPages.forEach((page, i) => {\r\n this._nodes$.value[i].hasChildren = page.total > 0;\r\n });\r\n });\r\n\r\n this._dirty = false;\r\n resolve(true);\r\n },\r\n error: (error) => {\r\n reject(error);\r\n },\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Set the node filter for the node with the specified ID.\r\n * @param id The node ID.\r\n * @param filter The filter to set.\r\n * @returns Promise with true if filter was set, false otherwise.\r\n */\r\n public setNodeFilter(id: number, filter?: F | null): Promise<boolean> {\r\n if (!id) {\r\n return Promise.resolve(false);\r\n }\r\n return new Promise<boolean>((resolve, reject) => {\r\n const node = this._nodes$.value.find((n) => n.id === id);\r\n if (!node) {\r\n reject(`Node ID ${id} not found in store`);\r\n return;\r\n }\r\n node!.filter = filter || undefined;\r\n return this.changePage(id, 1);\r\n });\r\n }\r\n\r\n /**\r\n * Expand the node with the specified ID. If the node is not expandable,\r\n * or it is already expanded, this method does nothing.\r\n * @param node The ID of the node to expand.\r\n * @returns Promise with true if the node was expanded, false otherwise.\r\n */\r\n public expand(id: number): Promise<boolean> {\r\n return new Promise<boolean>((resolve, reject) => {\r\n const node = this._nodes$.value.find((n) => n.id === id);\r\n if (!node || node.hasChildren === false || node.expanded) {\r\n resolve(false);\r\n }\r\n\r\n this.getPageFromCacheOrServer(\r\n { ...this.getFilter(node), parentId: id },\r\n 1\r\n ).subscribe((page) => {\r\n // no children, set hasChildren to false\r\n if (!page.total) {\r\n node!.hasChildren = false;\r\n resolve(false);\r\n } else {\r\n this._dirty = true;\r\n // insert page nodes after the current node\r\n const nodes = this._nodes$.value;\r\n const index = nodes.indexOf(node!);\r\n if (index === -1) {\r\n reject(`Node ID ${id} not found in store`);\r\n } else {\r\n const pageNodes = this.createPageNodes(page);\r\n nodes.splice(index + 1, 0, ...(pageNodes as E[]));\r\n this._nodes$.next(nodes);\r\n node!.hasChildren = true;\r\n node!.expanded = true;\r\n resolve(true);\r\n }\r\n }\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Expand all the descendants of the node with the specified ID.\r\n *\r\n * @param id The ID of the node to expand, or undefined to expand the\r\n * descendants of all the root level nodes.\r\n * @returns Promise.\r\n */\r\n public async expandAll(id?: number): Promise<boolean> {\r\n if (id === undefined) {\r\n // for each root level node call expandAll\r\n const nodes = [...this._nodes$.value];\r\n const promises: Promise<boolean>[] = [];\r\n for (const node of nodes) {\r\n if (node.parentId === undefined) {\r\n promises.push(this.expandAll(node.id));\r\n }\r\n }\r\n await Promise.all(promises);\r\n return true;\r\n }\r\n\r\n // get the parent node to start from\r\n const nodes = this._nodes$.value;\r\n const nodeIndex = nodes.findIndex((n) => n.id === id);\r\n if (nodeIndex === -1) {\r\n return false;\r\n }\r\n\r\n const node = nodes[nodeIndex];\r\n\r\n // first expand this node if it has children and isn't already expanded\r\n if (node.hasChildren && !node.expanded) {\r\n await this.expand(id);\r\n }\r\n\r\n // then expand all its immediate children recursively\r\n const children = this.getChildren(id);\r\n const promises: Promise<boolean>[] = [];\r\n for (const child of children) {\r\n if (child.hasChildren) {\r\n promises.push(this.expandAll(child.id));\r\n }\r\n }\r\n\r\n if (promises.length > 0) {\r\n await Promise.all(promises);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n public getChildren(id: number): E[] {\r\n const node = this._nodes$.value.find((n) => n.id === id);\r\n if (!node || node.hasChildren === false) {\r\n return [];\r\n }\r\n const nodes = this._nodes$.value;\r\n const index = nodes.indexOf(node);\r\n if (index === -1) {\r\n return [];\r\n }\r\n const children: E[] = [];\r\n let i = index + 1;\r\n while (i < nodes.length && nodes[i].y > node.y) {\r\n children.push(nodes[i]);\r\n i++;\r\n }\r\n return children;\r\n }\r\n\r\n private removeDescendants(\r\n nodes: PagedTreeNode<F>[],\r\n nodeIndex: number\r\n ): void {\r\n let i = nodeIndex + 1;\r\n while (i < nodes.length && nodes[i].y > nodes[nodeIndex].y) {\r\n i++;\r\n }\r\n nodes.splice(nodeIndex + 1, i - nodeIndex - 1);\r\n }\r\n\r\n /**\r\n * Collapse the node with the specified ID. If the node is not expandable,\r\n * or it is already collapsed, this method does nothing.\r\n * @param node The node to collapse.\r\n * @returns Promise with true if the node was collapsed, false otherwise.\r\n */\r\n public collapse(id: number): Promise<boolean> {\r\n return new Promise<boolean>((resolve, reject) => {\r\n const node = this._nodes$.value.find((n) => n.id === id);\r\n if (!node || node.hasChildren === false || !node.expanded) {\r\n resolve(false);\r\n }\r\n\r\n // remove all the descendant nodes after the current node\r\n const nodes = this._nodes$.value;\r\n const nodeIndex = nodes.indexOf(node!);\r\n if (nodeIndex === -1) {\r\n reject(`Node ID ${id} not found in store`);\r\n } else {\r\n this._dirty = true;\r\n this.removeDescendants(nodes, nodeIndex);\r\n node!.expanded = false;\r\n // reset paging info\r\n if (node?.paging) {\r\n node.paging.pageNumber = 1;\r\n }\r\n this._nodes$.next(nodes);\r\n resolve(true);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Collapse all the descendants of the node with the specified ID.\r\n *\r\n * @param id The ID of the node to collapse, or undefined to collapse the\r\n * descendants of all the root level nodes.\r\n * @returns Promise.\r\n */\r\n public collapseAll(id?: number): Promise<boolean> {\r\n if (id === undefined) {\r\n // for each expanded root level node\r\n const nodes = [...this._nodes$.value.filter((n) => n.expanded)];\r\n let i = 0;\r\n while (i < nodes.length) {\r\n if (nodes[i].parentId === undefined) {\r\n this.collapseAll(nodes[i].id);\r\n }\r\n i++;\r\n }\r\n return Promise.resolve(true);\r\n }\r\n\r\n this.collapse(id);\r\n return Promise.resolve(true);\r\n }\r\n\r\n /**\r\n * Change the page including the node with the specified ID.\r\n * @param parentId The ID of the parent node whose children are inside the page\r\n * you want to change.\r\n * @param pageNumber The new page number.\r\n * @returns Promise with true if the page was changed, false otherwise.\r\n */\r\n public changePage(parentId: number, pageNumber: number): Promise<boolean> {\r\n return new Promise<boolean>((resolve, reject) => {\r\n // get the parent node\r\n const parentNode = this._nodes$.value.find((n) => n.id === parentId);\r\n if (!parentNode) {\r\n resolve(false);\r\n }\r\n\r\n // get the page\r\n this.getPageFromCacheOrServer(\r\n { ...this.getFilter(parentNode), parentId },\r\n pageNumber\r\n ).subscribe((page) => {\r\n // if page is empty do nothing\r\n if (!page.total) {\r\n resolve(false);\r\n } else {\r\n this._dirty = true;\r\n // remove all the nodes in the same page of node\r\n // with all their descendants\r\n const nodes = this._nodes$.value;\r\n const nodeIndex = nodes.indexOf(parentNode!) + 1;\r\n const pageNodes = this.createPageNodes(page);\r\n\r\n // find the first node of the node's page\r\n let start = nodeIndex;\r\n const oldPageNr = nodes[start].paging.pageNumber;\r\n while (\r\n start > 0 &&\r\n nodes[start - 1].parentId === parentId &&\r\n nodes[start - 1].paging.pageNumber === oldPageNr\r\n ) {\r\n start--;\r\n }\r\n\r\n // find the last node of the node's page,\r\n // including all their descendants\r\n let end = start;\r\n const y = nodes[start].y;\r\n while (end < nodes.length && nodes[end].y >= y) {\r\n end++;\r\n }\r\n // replace all these nodes with the new ones\r\n nodes.splice(start, end - start);\r\n nodes.splice(start, 0, ...(pageNodes as E[]));\r\n\r\n // update the parent node paging info\r\n parentNode!.paging.pageNumber = page.pageNumber;\r\n this._nodes$.next(nodes);\r\n resolve(true);\r\n }\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Clear the store. The cache is cleared and the nodes are removed.\r\n */\r\n public clear(): void {\r\n this._cache.clear();\r\n this._nodes$.next([]);\r\n this._dirty = true;\r\n }\r\n\r\n /**\r\n * Clear the cache.\r\n */\r\n public clearCache(): void {\r\n this._cache.clear();\r\n }\r\n\r\n /**\r\n * Check if the page with the given number and filter is in cache.\r\n * @param pageNumber The page number.\r\n * @param filter The filter.\r\n * @returns True if the page is in cache, false otherwise.\r\n */\r\n public hasCachedPage(pageNumber: number, filter: F): boolean {\r\n const key = this.buildCacheKey(pageNumber, filter);\r\n return this._cache.has(key);\r\n }\r\n}\r\n","/*\r\n * Public API Surface of paged-data-browsers\r\n */\r\n\r\nexport * from './lib/components/compact-pager/compact-pager.component';\r\nexport * from './lib/components/range-view/range-view.component';\r\nexport * from './lib/components/browser-tree-node/browser-tree-node.component';\r\n\r\nexport * from './lib/services/paged-list.store';\r\nexport * from './lib/services/paged-tree.store';\r\nexport * from './lib/services/lru-cache';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i2","i3","i4"],"mappings":"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"}
1
+ {"version":3,"file":"myrmidon-paged-data-browsers.mjs","sources":["../../../../projects/myrmidon/paged-data-browsers/src/lib/components/compact-pager/compact-pager.component.ts","../../../../projects/myrmidon/paged-data-browsers/src/lib/components/compact-pager/compact-pager.component.html","../../../../projects/myrmidon/paged-data-browsers/src/lib/components/range-view/range-view.component.ts","../../../../projects/myrmidon/paged-data-browsers/src/lib/components/range-view/range-view.component.html","../../../../projects/myrmidon/paged-data-browsers/src/lib/components/browser-tree-node/browser-tree-node.component.ts","../../../../projects/myrmidon/paged-data-browsers/src/lib/components/browser-tree-node/browser-tree-node.component.html","../../../../projects/myrmidon/paged-data-browsers/src/lib/services/lru-cache.ts","../../../../projects/myrmidon/paged-data-browsers/src/lib/services/paged-list.store.ts","../../../../projects/myrmidon/paged-data-browsers/src/lib/services/paged-tree.store.ts","../../../../projects/myrmidon/paged-data-browsers/src/lib/services/editable-paged-tree.store.ts","../../../../projects/myrmidon/paged-data-browsers/src/public-api.ts","../../../../projects/myrmidon/paged-data-browsers/src/myrmidon-paged-data-browsers.ts"],"sourcesContent":["import { Component, input, output } from '@angular/core';\r\n\r\nimport { CommonModule } from '@angular/common';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatButtonModule } from '@angular/material/button';\r\n\r\nimport { PagingInfo } from '../../services/paged-tree.store';\r\n\r\n@Component({\r\n selector: 'pdb-compact-pager',\r\n imports: [CommonModule, MatButtonModule, MatIconModule],\r\n templateUrl: './compact-pager.component.html',\r\n styleUrls: ['./compact-pager.component.scss'],\r\n})\r\nexport class CompactPagerComponent {\r\n /**\r\n * The current paging information.\r\n */\r\n public paging = input<PagingInfo>({ pageNumber: 0, pageCount: 0, total: 0 });\r\n\r\n /**\r\n * Emits the new paging information when the user changes the page.\r\n */\r\n public readonly pagingChange = output<PagingInfo>();\r\n\r\n public onFirst(): void {\r\n this.pagingChange.emit({ ...this.paging(), pageNumber: 1 });\r\n }\r\n\r\n public onPrevious(): void {\r\n if (this.paging().pageNumber > 1) {\r\n this.pagingChange.emit({\r\n ...this.paging(),\r\n pageNumber: this.paging().pageNumber - 1,\r\n });\r\n }\r\n }\r\n\r\n public onNext(): void {\r\n if (this.paging().pageNumber < this.paging().pageCount) {\r\n this.pagingChange.emit({\r\n ...this.paging(),\r\n pageNumber: this.paging().pageNumber + 1,\r\n });\r\n }\r\n }\r\n\r\n public onLast(): void {\r\n if (this.paging().pageNumber < this.paging().pageCount) {\r\n this.pagingChange.emit({\r\n ...this.paging(),\r\n pageNumber: this.paging().pageCount,\r\n });\r\n }\r\n }\r\n}\r\n","@if (paging().pageCount) {\n <div class=\"form-row\">\n <span id=\"pages\">{{ paging().pageNumber }}/{{ paging().pageCount }}</span>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"onFirst()\"\n [disabled]=\"paging().pageNumber < 2\"\n >\n <mat-icon>first_page</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"onPrevious()\"\n [disabled]=\"paging().pageNumber < 2\"\n >\n <mat-icon>navigate_before</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"onNext()\"\n [disabled]=\"paging().pageNumber === paging().pageCount\"\n >\n <mat-icon>navigate_next</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"onLast()\"\n [disabled]=\"paging().pageNumber === paging().pageCount\"\n >\n <mat-icon>last_page</mat-icon>\n </button>\n <span id=\"total\">{{ paging().total }} </span>\n </div>\n}\n","import { Component, computed, input, signal } from '@angular/core';\n\n@Component({\n selector: 'pdb-range-view',\n templateUrl: './range-view.component.html',\n styleUrls: ['./range-view.component.scss'],\n})\nexport class RangeViewComponent {\n /**\n * The domain of the range view (start, limit).\n */\n public domain = input([0, 100]);\n /**\n * The range of the range view (start, limit).\n */\n public range = input([0, 100]);\n /**\n * The width of the component.\n */\n public width = input(100);\n /**\n * The height of the component.\n */\n public height = input(5);\n\n public scaledRange = computed(() => {\n const domain = this.domain();\n const range = this.range();\n const width = this.width();\n\n const domainWidth = domain[1] - domain[0];\n const rangeWidth = range[1] - range[0];\n const rangeStart = range[0] - domain[0];\n\n return [\n (rangeStart / domainWidth) * width,\n ((rangeStart + rangeWidth) / domainWidth) * width,\n ];\n });\n\n constructor() {}\n}\n","<svg [attr.width]=\"width()\" [attr.height]=\"height()\">\n <rect id=\"rdomain\" [attr.width]=\"width()\" [attr.height]=\"height()\" />\n <rect\n id=\"rrange\"\n [attr.x]=\"scaledRange()[0]\"\n [attr.y]=\"0\"\n [attr.width]=\"scaledRange()[1] - scaledRange()[0]\"\n [attr.height]=\"height()\"\n />\n</svg>\n","import { Component, input, output } from '@angular/core';\n\nimport { CommonModule } from '@angular/common';\nimport { MatBadgeModule } from '@angular/material/badge';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { MatIconModule } from '@angular/material/icon';\n\nimport { ColorToContrastPipe, StringToColorPipe } from '@myrmidon/ngx-tools';\n\nimport { PagedTreeNode, PagingInfo } from '../../services/paged-tree.store';\nimport { CompactPagerComponent } from '../compact-pager/compact-pager.component';\nimport { RangeViewComponent } from '../range-view/range-view.component';\n\n/**\n * A request to change the page number of a node's children.\n */\nexport interface PageChangeRequest {\n node: PagedTreeNode<any>;\n paging: PagingInfo;\n}\n\n/**\n * Browser tree node component view. This wraps some HTML content providing\n * a toggle button to expand/collapse the node, a paging control for the\n * node's children, and a button to edit the node's filter. You should then\n * provide the HTML content to display the node's data inside this component, e.g.\n * <pdb-browser-tree-node [node]=\"node\">\n * <your-node-view [node]=\"node\" />\n * <pdb-browser-tree-node>\n */\n@Component({\n selector: 'pdb-browser-tree-node',\n imports: [\n CommonModule,\n MatBadgeModule,\n MatButtonModule,\n MatIconModule,\n MatTooltipModule,\n // ngx-tools\n ColorToContrastPipe,\n StringToColorPipe,\n // local\n CompactPagerComponent,\n RangeViewComponent,\n ],\n templateUrl: './browser-tree-node.component.html',\n styleUrls: ['./browser-tree-node.component.css'],\n})\nexport class BrowserTreeNodeComponent {\n /**\n * The node to display.\n */\n public readonly node = input<PagedTreeNode<any> | undefined | null>();\n\n /**\n * The paging information for the node's children.\n */\n public readonly paging = input<PagingInfo>();\n\n /**\n * True to show debug information.\n */\n public readonly debug = input<boolean>();\n\n /**\n * True to hide the node's loc and label. This is useful if you want to\n * provide your own view for the node, between the expansion toggle and\n * the filter edit button. In this case, in your consumer template provide\n * your own view as the content of this component. If instead you are fine\n * with the default loc and label, and just want to add more data to\n * the view, then you can just add your own content to this component's\n * template, without setting this property to true.\n */\n public readonly hideLabel = input<boolean>();\n\n /**\n * True to hide the node's location (y and x).\n */\n public readonly hideLoc = input<boolean>();\n\n /**\n * True to hide the node's paging control unless hovered.\n */\n public readonly hidePaging = input<boolean>();\n\n /**\n * True to hide the node's filter edit button.\n */\n public readonly hideFilter = input<boolean>();\n\n /**\n * The indent size for the node's children.\n */\n public readonly indentSize = input(30);\n\n /**\n * The width of the range view.\n */\n public readonly rangeWidth = input(250);\n\n /**\n * Emits when the user wants to toggle the expanded state of the node.\n */\n public readonly toggleExpandedRequest = output<PagedTreeNode<any>>();\n\n /**\n * Emits when the user wants to change the page number of the node's children.\n */\n public readonly changePageRequest = output<PageChangeRequest>();\n\n /**\n * Emits when the user wants to edit the node's filter.\n */\n public readonly editNodeFilterRequest = output<PagedTreeNode<any>>();\n\n public onToggleExpanded(): void {\n if (!this.node()) {\n return;\n }\n this.toggleExpandedRequest.emit(this.node() as PagedTreeNode<any>);\n }\n\n public onPagingChange(node: PagedTreeNode<any>, paging: PagingInfo): void {\n this.changePageRequest.emit({\n node,\n paging,\n });\n }\n\n public onEditFilter(): void {\n if (this.node()) {\n this.editNodeFilterRequest.emit(this.node() as PagedTreeNode<any>);\n }\n }\n}\n","@if (node()) {\n<div id=\"node\" [style.margin-left.px]=\"(node()!.y - 1) * indentSize()\">\n <!-- pager -->\n @if (node()!.expanded && paging() && paging()!.pageCount > 1) {\n <div id=\"pager\" [style.display]=\"hidePaging() ? 'inherit' : 'block'\">\n <pdb-compact-pager\n [paging]=\"paging()!\"\n (pagingChange)=\"onPagingChange(node()!, $event)\"\n />\n <pdb-range-view\n [width]=\"rangeWidth()\"\n [domain]=\"[0, paging()!.pageCount]\"\n [range]=\"[paging()!.pageNumber - 1, paging()!.pageNumber]\"\n />\n </div>\n }\n <!-- node -->\n <div class=\"form-row\">\n <!-- expand/collapse button -->\n <button\n type=\"button\"\n mat-icon-button\n [matTooltip]=\"node()?.expanded ? 'Collapse' : 'Expand'\"\n i18n-matTooltip\n [disabled]=\"node()!.hasChildren === false\"\n (click)=\"onToggleExpanded()\"\n >\n <mat-icon class=\"mat-primary\" i18n>\n @if (node()!.hasChildren === true) { @if (node()!.expanded) {\n chevron_left } @else { chevron_right } } @else { stop }\n </mat-icon>\n </button>\n\n <!-- tag -->\n @if (!hideLabel()) {\n <span\n class=\"tag\"\n [ngStyle]=\"{\n 'background-color': (node()!.tag | stringToColor),\n color: node()!.tag | stringToColor | colorToContrast\n }\"\n >{{ node()!.tag }}</span\n >\n\n <!-- loc and label -->\n @if (!hideLoc()) {\n <span class=\"loc\">{{ node()!.y }}.{{ node()!.x }}</span> - }\n {{ node()!.label }}\n }\n\n <!-- PROJECTED NODE -->\n <ng-content></ng-content>\n\n <!-- debug -->\n @if (debug()) {\n <span class=\"debug\"\n >#{{ node()!.id }}\n <span\n >| {{ node()!.paging.pageNumber }}/{{ node()!.paging.pageCount }} ({{\n node()!.paging.total\n }})</span\n ></span\n >\n }\n\n <!-- filter -->\n @if (!hideFilter()){ @if (!node()?.filter && node()?.y) {\n <div class=\"muted\">\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Add filter\"\n i18n-matTooltip\n (click)=\"onEditFilter()\"\n >\n <mat-icon>filter_list</mat-icon>\n </button>\n </div>\n } @if (node()?.filter && node()?.y) {\n <div class=\"muted\">\n <button type=\"button\" mat-icon-button (click)=\"onEditFilter()\">\n <mat-icon [matBadge]=\"node()?.filter ? 'F' : ''\">filter_alt</mat-icon>\n </button>\n </div>\n } }\n </div>\n</div>\n}\n","/**\r\n * A Least Recently Used cache that can be used to store any type of object.\r\n * The cache works in two modes: considering the size of the objects or not.\r\n * If the size is considered, the cache will have a maximum size and will\r\n * remove the oldest objects when the maximum size is reached. Note that\r\n * the size is only roughly estimated. This avoids removing too many\r\n * entries from the cache when the maximum is reached.\r\n * If the size is not considered, the cache will have a maximum number of\r\n * objects and will remove the oldest objects when the maximum number is\r\n * reached.\r\n */\r\nexport class LRUCache<T> {\r\n private _maxSize: number;\r\n private _totalSize: number;\r\n private _considerSize: boolean;\r\n private _cache: Map<string, T>;\r\n private _sizes: Map<string, number>;\r\n\r\n /**\r\n * Creates a new cache.\r\n * @param maxSize The maximum size of the cache. This is either\r\n * the maximum number of items in the cache (when considerSize\r\n * is false) or the maximum total size of all items in the\r\n * cache in bytes (when considerSize is true).\r\n * @param considerSize True if the size of the objects should be\r\n * considered.\r\n */\r\n constructor(maxSize: number, considerSize: boolean = false) {\r\n this._maxSize = maxSize;\r\n this._totalSize = 0;\r\n this._considerSize = considerSize;\r\n this._cache = new Map<string, T>();\r\n this._sizes = new Map<string, number>();\r\n }\r\n\r\n /**\r\n * Get an item from the cache.\r\n * @param key The key of the item to get.\r\n * @returns The item or undefined if the item is not in the cache.\r\n */\r\n public get(key: string): T | undefined {\r\n let item: T | undefined = this._cache.get(key);\r\n if (item) {\r\n this._cache.delete(key);\r\n this._cache.set(key, item);\r\n }\r\n return item;\r\n }\r\n\r\n /**\r\n * Check if an item is in the cache.\r\n * @param key The key of the item to check.\r\n * @returns True if the item is in cache.\r\n */\r\n public has(key: string): boolean {\r\n return this._cache.has(key);\r\n }\r\n\r\n /**\r\n * Put an item in the cache.\r\n * @param key The key of the item to put.\r\n * @param item The item to put.\r\n * @param size The estimated size of the item in bytes.\r\n * This must be calculated by the caller but only when\r\n * considerSize is true.\r\n */\r\n public put(key: string, item: T, size: number): void {\r\n this._cache.delete(key);\r\n this._cache.set(key, item);\r\n this._sizes.set(key, size);\r\n if (this._considerSize) {\r\n this._totalSize += size;\r\n while (this._totalSize > this._maxSize) {\r\n const oldestKey = this._cache.keys().next().value;\r\n if (!oldestKey) {\r\n break;\r\n }\r\n let oldestSize = this._sizes.get(oldestKey);\r\n if (oldestSize) {\r\n this._totalSize -= oldestSize;\r\n }\r\n this._cache.delete(oldestKey);\r\n this._sizes.delete(oldestKey);\r\n }\r\n } else {\r\n while (this._cache.size > this._maxSize) {\r\n const oldestKey = this._cache.keys().next().value;\r\n if (!oldestKey) {\r\n break;\r\n }\r\n this._cache.delete(oldestKey);\r\n this._sizes.delete(oldestKey);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear the cache.\r\n */\r\n public clear(): void {\r\n this._cache.clear();\r\n this._sizes.clear();\r\n this._totalSize = 0;\r\n }\r\n\r\n /**\r\n * Estimate the size of an object in bytes.\r\n * @param obj The object to calculate the size of.\r\n * @returns The estimated size of the object in bytes.\r\n */\r\n public static calculateObjectSize(obj: any): number {\r\n if (!obj) {\r\n return 0;\r\n }\r\n let totalSize = 0;\r\n let keys = Object.keys(obj);\r\n for (let key of keys) {\r\n let value = obj[key];\r\n if (typeof value === 'string') {\r\n totalSize += value.length * 2;\r\n } else if (typeof value === 'number') {\r\n totalSize += 8;\r\n } else if (typeof value === 'boolean') {\r\n totalSize += 4;\r\n } else if (typeof value === 'object' && value !== null) {\r\n totalSize += this.calculateObjectSize(value);\r\n }\r\n }\r\n return totalSize;\r\n }\r\n}\r\n","import { BehaviorSubject, Observable } from 'rxjs';\r\n\r\nimport { DataPage } from '@myrmidon/ngx-tools';\r\n\r\nimport { LRUCache } from './lru-cache';\r\n\r\n/**\r\n * Options for the paged list store.\r\n */\r\nexport interface PagedListStoreOptions {\r\n /**\r\n * The size of pages in the store.\r\n */\r\n pageSize: number;\r\n /**\r\n * The size of the cache for pages in the store.\r\n */\r\n cacheSize: number;\r\n\r\n /**\r\n * A custom function for building the cache key for the given page number\r\n * and filter.\r\n * @param pageNumber The page number.\r\n * @param filter The filter.\r\n * @returns A string to be used as cache key.\r\n */\r\n buildCacheKey?: (pageNumber: number, filter: any) => string;\r\n}\r\n\r\n/**\r\n * Default options for the paged list store.\r\n */\r\nexport const DEFAULT_PAGED_LIST_STORE_OPTIONS: PagedListStoreOptions = {\r\n pageSize: 20,\r\n cacheSize: 50,\r\n};\r\n\r\n/**\r\n * The interface to be implemented by the service used by PagedListStore.\r\n */\r\nexport interface PagedListStoreService<F, E> {\r\n /**\r\n * Load the page with the given number.\r\n * @param pageNumber The page number to load.\r\n * @param pageSize The size of the page to load.\r\n * @param filter The filter to apply.\r\n */\r\n loadPage(\r\n pageNumber: number,\r\n pageSize: number,\r\n filter: F\r\n ): Observable<DataPage<E>>;\r\n}\r\n\r\n/**\r\n * A generic paged list store using a filter object of type F\r\n * and a list of elements of type E.\r\n */\r\nexport class PagedListStore<F, E> {\r\n private _pageSize: number;\r\n private readonly _customCacheKeyBuilder?: (\r\n pageNumber: number,\r\n filter: any\r\n ) => string;\r\n private _page$: BehaviorSubject<DataPage<E>>;\r\n private _filter$: BehaviorSubject<F>;\r\n private readonly _cache: LRUCache<DataPage<E>>;\r\n\r\n /**\r\n * The page. It is updated when the page is changed or the filter is changed.\r\n */\r\n public page$: Observable<Readonly<DataPage<E>>>;\r\n\r\n /**\r\n * The filter. It is updated when the filter is changed.\r\n */\r\n public filter$: Observable<Readonly<F>>;\r\n\r\n /**\r\n * The size of nodes pages in this store. If you change it, the store\r\n * is reset. The default value is 20.\r\n */\r\n public get pageSize(): number {\r\n return this._pageSize;\r\n }\r\n public set pageSize(value: number) {\r\n if (this._pageSize === value) {\r\n return;\r\n }\r\n this._pageSize = value;\r\n this.reset();\r\n }\r\n\r\n /**\r\n * Create a new paged list store.\r\n * @param options Options for the paged list store.\r\n */\r\n constructor(\r\n private _service: PagedListStoreService<F, E>,\r\n options: PagedListStoreOptions = DEFAULT_PAGED_LIST_STORE_OPTIONS\r\n ) {\r\n this._pageSize = options.pageSize;\r\n this._cache = new LRUCache<DataPage<E>>(options.cacheSize);\r\n // page\r\n this._page$ = new BehaviorSubject<DataPage<E>>({\r\n pageNumber: 0,\r\n pageCount: 0,\r\n pageSize: 0,\r\n total: 0,\r\n items: [],\r\n });\r\n this.page$ = this._page$.asObservable();\r\n // filter\r\n this._filter$ = new BehaviorSubject<F>({} as F);\r\n this.filter$ = this._filter$.asObservable();\r\n }\r\n\r\n /**\r\n * Returns true if the store is empty, false otherwise.\r\n * @returns true if the store is empty, false otherwise.\r\n */\r\n public isEmpty(): boolean {\r\n return this._page$.value.items.length === 0;\r\n }\r\n\r\n /**\r\n * Build the cache key for the given page number and filter.\r\n * The default implementation just returns a stringified object\r\n * containing the page number and the filter. You may override\r\n * this method to provide a custom cache key.\r\n * @param pageNumber The page number.\r\n * @param filter The filter.\r\n * @returns A string to be used as cache key.\r\n */\r\n public buildCacheKey(pageNumber: number, filter: F): string {\r\n if (this._customCacheKeyBuilder) {\r\n return this._customCacheKeyBuilder(pageNumber, filter);\r\n }\r\n return JSON.stringify({ pageNumber, ...filter });\r\n }\r\n\r\n /**\r\n * Load the page with the given number.\r\n * @param pageNumber the page number to load.\r\n */\r\n private loadPage(pageNumber: number): Observable<DataPage<E>> {\r\n return this._service.loadPage(\r\n pageNumber,\r\n this._pageSize,\r\n this._filter$.value\r\n );\r\n }\r\n\r\n /**\r\n * Set the page with the given number.\r\n * @param pageNumber The page number to load.\r\n * @param pageSize The page size.\r\n * @returns Promise which resolves when the page is loaded.\r\n */\r\n public setPage(pageNumber: number, pageSize?: number): Promise<void> {\r\n if (pageSize && pageSize !== this._pageSize) {\r\n this._pageSize = pageSize;\r\n }\r\n return new Promise((resolve, reject) => {\r\n // if page is in cache, return it\r\n const key = this.buildCacheKey(pageNumber, this._filter$.value);\r\n const cachedPage = this._cache.get(key);\r\n if (cachedPage) {\r\n this._page$.next(cachedPage);\r\n resolve();\r\n return;\r\n }\r\n\r\n // else load page\r\n this.loadPage(pageNumber).subscribe({\r\n next: (page) => {\r\n this._page$.next(page);\r\n this._cache.put(key, page, 0);\r\n resolve();\r\n },\r\n error: reject,\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Get the current page.\r\n * @returns The current page.\r\n */\r\n public getPage(): DataPage<E> {\r\n return this._page$.value;\r\n }\r\n\r\n /**\r\n * Apply the given filter and load the first page.\r\n * @param filter The filter to apply.\r\n * @returns Promise which resolves when the page is loaded.\r\n */\r\n public setFilter(filter: F): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n this._filter$.next(filter);\r\n this.setPage(1).then(resolve, reject);\r\n });\r\n }\r\n\r\n /**\r\n * Get the current filter.\r\n * @returns The current filter.\r\n */\r\n public getFilter(): F {\r\n return this._filter$.value;\r\n }\r\n\r\n /**\r\n * Reset the filter and load the first page. The cache is cleared.\r\n * @returns Promise which resolves when the page is loaded.\r\n */\r\n public reset(): Promise<void> {\r\n this._cache.clear();\r\n return this.setFilter({} as F);\r\n }\r\n\r\n /**\r\n * Clear the store. The cache is cleared and the page is emptied.\r\n */\r\n public clear(): void {\r\n this._cache.clear();\r\n this._page$.next({\r\n pageNumber: 0,\r\n pageCount: 0,\r\n pageSize: 0,\r\n total: 0,\r\n items: [],\r\n });\r\n }\r\n\r\n /**\r\n * Clear the cache.\r\n */\r\n public clearCache(): void {\r\n this._cache.clear();\r\n }\r\n\r\n /**\r\n * Check if the page with the given number and filter is in cache.\r\n * @param pageNumber The page number.\r\n * @param filter The filter.\r\n * @returns True if the page is in cache, false otherwise.\r\n */\r\n public hasCachedPage(pageNumber: number, filter: F): boolean {\r\n const key = this.buildCacheKey(pageNumber, filter);\r\n return this._cache.has(key);\r\n }\r\n}\r\n","import { BehaviorSubject, Observable, forkJoin, of, tap } from 'rxjs';\r\n\r\nimport { DataPage } from '@myrmidon/ngx-tools';\r\n\r\nimport { LRUCache } from './lru-cache';\r\nimport { DEFAULT_PAGED_LIST_STORE_OPTIONS } from './paged-list.store';\r\nimport { EditablePagedTreeStoreService } from './editable-paged-tree.store';\r\n\r\n/**\r\n * A tree node. Your data service should return a list of these nodes\r\n * or of any type extending this interface.\r\n */\r\nexport interface TreeNode {\r\n id: number;\r\n parentId?: number;\r\n y: number;\r\n x: number;\r\n label: string;\r\n tag?: string;\r\n hasChildren?: boolean;\r\n hilite?: boolean;\r\n}\r\n\r\n/**\r\n * A filter for tree nodes.\r\n */\r\nexport interface TreeNodeFilter {\r\n tags?: string[];\r\n parentId?: number;\r\n}\r\n\r\n/**\r\n * Paging information for a paged tree node.\r\n */\r\nexport interface PagingInfo {\r\n pageNumber: number;\r\n pageCount: number;\r\n total: number;\r\n}\r\n\r\n/**\r\n * A tree node with paging information, used in NodeBrowserStore.\r\n */\r\nexport interface PagedTreeNode<F extends TreeNodeFilter> extends TreeNode {\r\n paging: PagingInfo;\r\n expanded?: boolean;\r\n filter?: F;\r\n}\r\n\r\n/**\r\n * The interface to be implemented by the service used by NodeBrowserStore\r\n * to load nodes.\r\n */\r\nexport interface PagedTreeStoreService<F extends TreeNodeFilter> {\r\n /**\r\n * Get the specified page of nodes.\r\n * @param filter The filter.\r\n * @param pageNumber The page number.\r\n * @param pageSize The page size.\r\n * @param hasMockRoot If true, the root node is a mock node provided by your\r\n * service, which implies that its Y value is 0 rather than 1. Default is\r\n * false, meaning that your service will return a single root node with Y\r\n * value 1.\r\n */\r\n getNodes(\r\n filter: F,\r\n pageNumber: number,\r\n pageSize: number,\r\n hasMockRoot?: boolean\r\n ): Observable<DataPage<TreeNode>>;\r\n}\r\n\r\n/**\r\n * Options for the PagedTreeStore.\r\n */\r\nexport interface PagedTreeStoreOptions {\r\n /**\r\n * The size of pages in the store.\r\n */\r\n pageSize: number;\r\n /**\r\n * The size of the cache for pages in the store.\r\n */\r\n cacheSize: number;\r\n /**\r\n * A custom function for building the cache key for the given page number\r\n * and filter.\r\n * @param pageNumber The page number.\r\n * @param filter The filter.\r\n * @returns A string to be used as cache key.\r\n */\r\n buildCacheKey?: (pageNumber: number, filter: any) => string;\r\n /**\r\n * If true, the root node is a mock node provided by your service, which\r\n * implies that its Y value is 0 rather than 1. Default is false, meaning\r\n * that there are many root-level nodes, all with parent ID = undefined.\r\n */\r\n hasMockRoot?: boolean;\r\n}\r\n\r\n/**\r\n * A store for the node browser component. This store is used to keep a\r\n * list of nodes, and to load them from the injected PagedTreeStoreService<F>.\r\n * It also keeps the root node(s) in memory. Every tree node in the list\r\n * is extended with page number, page count and total items, plus\r\n * expansion-related metadata.\r\n * The store keeps a flat list of these tree nodes, allowing users to\r\n * expand and collapse them. Each node has its children paged, and optionally\r\n * filtered.\r\n * F is the type of the filter object, E is the type of the paged tree nodes.\r\n */\r\nexport class PagedTreeStore<\r\n E extends PagedTreeNode<F>,\r\n F extends TreeNodeFilter\r\n> {\r\n // nodes\r\n private _nodes$: BehaviorSubject<E[]>;\r\n // per-node filters\r\n private _filter$: BehaviorSubject<F>;\r\n // optional custom cache key builder\r\n private readonly _customCacheKeyBuilder?: (\r\n pageNumber: number,\r\n filter: any\r\n ) => string;\r\n // cache of pages\r\n private readonly _cache: LRUCache<DataPage<TreeNode>>;\r\n // indicates if the root is a mock node provided by the service\r\n private readonly _hasMockRoot: boolean;\r\n\r\n private _pageSize: number;\r\n // dirty state: this is reset when the store is reset, and set to true\r\n // when the store is changed\r\n private _dirty?: boolean;\r\n\r\n /**\r\n * The flat list of paged nodes in this store.\r\n */\r\n public nodes$: Observable<Readonly<E[]>>;\r\n\r\n /**\r\n * The global filter for all the nodes.\r\n */\r\n public filter$: Observable<Readonly<F>>;\r\n\r\n /**\r\n * The size of nodes pages in this store. If you change it, the store\r\n * is reset. The default value is 20.\r\n */\r\n public get pageSize(): number {\r\n return this._pageSize;\r\n }\r\n public set pageSize(value: number) {\r\n if (this._pageSize === value) {\r\n return;\r\n }\r\n this._pageSize = value;\r\n this.reset();\r\n }\r\n\r\n /**\r\n * Create an instance of the store.\r\n * @param _service The service used to load nodes.\r\n * @param options The options to configure this store.\r\n */\r\n constructor(\r\n private _service: PagedTreeStoreService<F>,\r\n options: PagedTreeStoreOptions = DEFAULT_PAGED_LIST_STORE_OPTIONS\r\n ) {\r\n this._pageSize = options.pageSize;\r\n this._cache = new LRUCache<DataPage<TreeNode>>(options.cacheSize);\r\n this._customCacheKeyBuilder = options.buildCacheKey;\r\n this._nodes$ = new BehaviorSubject<E[]>([]);\r\n this.nodes$ = this._nodes$.asObservable();\r\n this._filter$ = new BehaviorSubject<F>({} as F);\r\n this.filter$ = this._filter$.asObservable();\r\n this._dirty = true;\r\n this._hasMockRoot = options.hasMockRoot || false;\r\n }\r\n\r\n /**\r\n * Gets the global filter, optionally overridden with values\r\n * from the specified node's filter.\r\n * @param node The optional node.\r\n * @returns The filter.\r\n */\r\n private getFilter(node?: PagedTreeNode<F>): F {\r\n return node?.filter\r\n ? {\r\n ...this._filter$.value,\r\n ...node.filter,\r\n }\r\n : this._filter$.value;\r\n }\r\n\r\n /**\r\n * Checks if this store is empty.\r\n * @returns True if this store is empty.\r\n */\r\n public isEmpty(): boolean {\r\n return this._nodes$.value.length === 0;\r\n }\r\n\r\n /**\r\n * Gets all the nodes in the store.\r\n * @returns The nodes.\r\n */\r\n public getNodes(): Readonly<PagedTreeNode<F>[]> {\r\n return this._nodes$.value;\r\n }\r\n\r\n /**\r\n * Get the root node of the tree. Given that the store keeps a flat\r\n * list, this is the first node in the list, if any.\r\n * @returns The root node of the tree or undefined if empty.\r\n */\r\n public getRootNode(): PagedTreeNode<F> | undefined {\r\n return this._nodes$.value[0];\r\n }\r\n\r\n /**\r\n * Build the cache key for the given page number and filter.\r\n * The default implementation just returns a stringified object\r\n * containing the page number and the filter. You may override\r\n * this method to provide a custom cache key.\r\n * @param pageNumber The page number.\r\n * @param filter The filter.\r\n * @returns A string to be used as cache key.\r\n */\r\n public buildCacheKey(pageNumber: number, filter: F): string {\r\n if (this._customCacheKeyBuilder) {\r\n return this._customCacheKeyBuilder(pageNumber, filter);\r\n }\r\n return JSON.stringify({ ...filter, pageNumber });\r\n }\r\n\r\n /**\r\n * Get the specified page of nodes, either from cache or from the server.\r\n * When the page is retrieved from the server, it is stored in cache.\r\n * @param filter The filter to apply.\r\n * @param pageNumber The page number to get.\r\n * @returns Observable of the page of nodes.\r\n */\r\n private getPageFromCacheOrServer(\r\n filter: F,\r\n pageNumber: number\r\n ): Observable<DataPage<TreeNode>> {\r\n // try to get the page from cache\r\n const key = this.buildCacheKey(pageNumber, filter);\r\n const pageInCache = this._cache.get(key);\r\n\r\n // if in cache, just return it; else, get it from the server and\r\n // store it in cache\r\n if (pageInCache) {\r\n return of(pageInCache);\r\n } else {\r\n return this._service\r\n .getNodes(filter, pageNumber, this._pageSize, this._hasMockRoot)\r\n .pipe(\r\n tap((page) => {\r\n this._cache.put(key, page, 0);\r\n })\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Create paged tree nodes from a page of tree nodes, by providing further\r\n * metadata like page number, page count and total items.\r\n * @param page The page to create nodes from.\r\n * @returns Paged nodes.\r\n */\r\n private createPageNodes(page: DataPage<TreeNode>): E[] {\r\n return page.items.map((n) => {\r\n return {\r\n ...n,\r\n hasChildren: n.hasChildren,\r\n paging: {\r\n pageNumber: page.pageNumber,\r\n pageCount: page.pageCount,\r\n total: page.total,\r\n },\r\n } as E;\r\n });\r\n }\r\n\r\n /**\r\n * Sets the filter for this store. Whenever the filter is set,\r\n * the store is reset.\r\n * @param filter The filter.\r\n * @returns true if tree was changed, false otherwise.\r\n */\r\n public setFilter(filter: F): Promise<boolean> {\r\n if (this._filter$.value === filter) {\r\n return Promise.resolve(false);\r\n }\r\n this._filter$.next(filter);\r\n this._dirty = true;\r\n return this.reset();\r\n }\r\n\r\n /**\r\n * Reset the store, loading the root nodes and their children.\r\n * @returns true if tree was changed, false otherwise.\r\n */\r\n public reset(): Promise<boolean> {\r\n this._cache.clear();\r\n const filter = this._filter$.value;\r\n\r\n return new Promise<boolean>((resolve, reject) => {\r\n this._service\r\n .getNodes(\r\n {\r\n ...filter,\r\n parentId: undefined, // root have no parent\r\n },\r\n 1,\r\n this._pageSize,\r\n this._hasMockRoot\r\n )\r\n .subscribe({\r\n next: (page: DataPage<TreeNode>) => {\r\n // update the nodes\r\n this._nodes$.next(this.createPageNodes(page));\r\n\r\n // get the children of each node thus calculating their hasChildren property\r\n const childrenObservables = this._nodes$.value.map((node) =>\r\n this.getPageFromCacheOrServer({ ...filter, parentId: node.id }, 1)\r\n );\r\n forkJoin(childrenObservables).subscribe((childrenPages) => {\r\n childrenPages.forEach((page, i) => {\r\n this._nodes$.value[i].hasChildren = page.total > 0;\r\n });\r\n });\r\n\r\n this._dirty = false;\r\n resolve(true);\r\n },\r\n error: (error) => {\r\n reject(error);\r\n },\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Set the node filter for the node with the specified ID.\r\n * @param id The node ID.\r\n * @param filter The filter to set.\r\n * @returns Promise with true if filter was set, false otherwise.\r\n */\r\n public setNodeFilter(id: number, filter?: F | null): Promise<boolean> {\r\n if (!id) {\r\n return Promise.resolve(false);\r\n }\r\n return new Promise<boolean>((resolve, reject) => {\r\n const node = this._nodes$.value.find((n) => n.id === id);\r\n if (!node) {\r\n reject(`Node ID ${id} not found in store`);\r\n return;\r\n }\r\n node!.filter = filter || undefined;\r\n return this.changePage(id, 1);\r\n });\r\n }\r\n\r\n /**\r\n * Expand the node with the specified ID. If the node is not expandable,\r\n * or it is already expanded, this method does nothing.\r\n * @param node The ID of the node to expand.\r\n * @returns Promise with true if the node was expanded, false otherwise.\r\n */\r\n public expand(id: number): Promise<boolean> {\r\n return new Promise<boolean>((resolve, reject) => {\r\n // get the node to expand\r\n const node = this._nodes$.value.find((n) => n.id === id);\r\n // if no node, or no children, or already expanded, do nothing\r\n if (!node || node.hasChildren === false || node.expanded) {\r\n resolve(false);\r\n }\r\n\r\n // get the first page of children for this node\r\n this.getPageFromCacheOrServer(\r\n { ...this.getFilter(node), parentId: id },\r\n 1\r\n ).subscribe((page) => {\r\n // no children, set hasChildren to false\r\n if (!page.total) {\r\n // no children, next time we won't try to expand\r\n node!.hasChildren = false;\r\n resolve(false);\r\n } else {\r\n this._dirty = true;\r\n // insert page nodes after the current node\r\n const nodes = this._nodes$.value;\r\n const index = nodes.indexOf(node!);\r\n if (index === -1) {\r\n reject(`Node ID ${id} not found in store`);\r\n } else {\r\n const pageNodes = this.createPageNodes(page);\r\n nodes.splice(index + 1, 0, ...(pageNodes as E[]));\r\n this._nodes$.next(nodes);\r\n node!.hasChildren = true;\r\n node!.expanded = true;\r\n resolve(true);\r\n }\r\n }\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Expand all the descendants of the node with the specified ID.\r\n *\r\n * @param id The ID of the node to expand, or undefined to expand the\r\n * descendants of all the root level nodes.\r\n * @returns Promise.\r\n */\r\n public async expandAll(id?: number): Promise<boolean> {\r\n if (id === undefined) {\r\n // for each root level node call expandAll\r\n const nodes = [...this._nodes$.value];\r\n const promises: Promise<boolean>[] = [];\r\n for (const node of nodes) {\r\n if (node.parentId === undefined) {\r\n promises.push(this.expandAll(node.id));\r\n }\r\n }\r\n await Promise.all(promises);\r\n return true;\r\n }\r\n\r\n // get the parent node to start from\r\n const nodes = this._nodes$.value;\r\n const nodeIndex = nodes.findIndex((n) => n.id === id);\r\n if (nodeIndex === -1) {\r\n return false;\r\n }\r\n\r\n const node = nodes[nodeIndex];\r\n\r\n // first expand this node if it has children and isn't already expanded\r\n if (node.hasChildren && !node.expanded) {\r\n await this.expand(id);\r\n }\r\n\r\n // then expand all its immediate children recursively\r\n const children = this.getChildren(id);\r\n const promises: Promise<boolean>[] = [];\r\n for (const child of children) {\r\n if (child.hasChildren) {\r\n promises.push(this.expandAll(child.id));\r\n }\r\n }\r\n\r\n if (promises.length > 0) {\r\n await Promise.all(promises);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Get the children of the node with the specified ID.\r\n * @param id The ID of the node whose children you want to get.\r\n * @returns An array of child nodes.\r\n */\r\n public getChildren(id: number): E[] {\r\n const node = this._nodes$.value.find((n) => n.id === id);\r\n if (!node || node.hasChildren === false) {\r\n return [];\r\n }\r\n const nodes = this._nodes$.value;\r\n const index = nodes.indexOf(node);\r\n if (index === -1) {\r\n return [];\r\n }\r\n const children: E[] = [];\r\n let i = index + 1;\r\n while (i < nodes.length && nodes[i].y > node.y) {\r\n children.push(nodes[i]);\r\n i++;\r\n }\r\n return children;\r\n }\r\n\r\n private removeDescendants(\r\n nodes: PagedTreeNode<F>[],\r\n nodeIndex: number\r\n ): void {\r\n let i = nodeIndex + 1;\r\n while (i < nodes.length && nodes[i].y > nodes[nodeIndex].y) {\r\n i++;\r\n }\r\n nodes.splice(nodeIndex + 1, i - nodeIndex - 1);\r\n }\r\n\r\n /**\r\n * Collapse the node with the specified ID. If the node is not expandable,\r\n * or it is already collapsed, this method does nothing.\r\n * @param node The node to collapse.\r\n * @returns Promise with true if the node was collapsed, false otherwise.\r\n */\r\n public collapse(id: number): Promise<boolean> {\r\n return new Promise<boolean>((resolve, reject) => {\r\n const node = this._nodes$.value.find((n) => n.id === id);\r\n if (!node || node.hasChildren === false || !node.expanded) {\r\n resolve(false);\r\n }\r\n\r\n // remove all the descendant nodes after the current node\r\n const nodes = this._nodes$.value;\r\n const nodeIndex = nodes.indexOf(node!);\r\n if (nodeIndex === -1) {\r\n reject(`Node ID ${id} not found in store`);\r\n } else {\r\n this._dirty = true;\r\n this.removeDescendants(nodes, nodeIndex);\r\n node!.expanded = false;\r\n // reset paging info\r\n if (node?.paging) {\r\n node.paging.pageNumber = 1;\r\n }\r\n this._nodes$.next(nodes);\r\n resolve(true);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Collapse all the descendants of the node with the specified ID.\r\n *\r\n * @param id The ID of the node to collapse, or undefined to collapse the\r\n * descendants of all the root level nodes.\r\n * @returns Promise.\r\n */\r\n public collapseAll(id?: number): Promise<boolean> {\r\n if (id === undefined) {\r\n // for each expanded root level node\r\n const nodes = [...this._nodes$.value.filter((n) => n.expanded)];\r\n let i = 0;\r\n while (i < nodes.length) {\r\n if (nodes[i].parentId === undefined) {\r\n this.collapseAll(nodes[i].id);\r\n }\r\n i++;\r\n }\r\n return Promise.resolve(true);\r\n }\r\n\r\n this.collapse(id);\r\n return Promise.resolve(true);\r\n }\r\n\r\n /**\r\n * Change the page including the children of the parent node with\r\n * the specified ID.\r\n * @param parentId The ID of the parent node whose children are inside the page\r\n * you want to change.\r\n * @param pageNumber The new page number.\r\n * @returns Promise with true if the page was changed, false otherwise.\r\n */\r\n public changePage(parentId: number, pageNumber: number): Promise<boolean> {\r\n return new Promise<boolean>((resolve, reject) => {\r\n // get the parent node\r\n const parentNode = this._nodes$.value.find((n) => n.id === parentId);\r\n\r\n // if parent not found, do nothing\r\n if (!parentNode) {\r\n resolve(false);\r\n return;\r\n }\r\n\r\n // parent should be expanded\r\n if (!parentNode.expanded) {\r\n resolve(false);\r\n return;\r\n }\r\n\r\n // get the page\r\n this.getPageFromCacheOrServer(\r\n { ...this.getFilter(parentNode), parentId },\r\n pageNumber\r\n ).subscribe({\r\n next: (page) => {\r\n // if page is empty, collapse the parent\r\n if (!page.total) {\r\n parentNode.hasChildren = false;\r\n parentNode.expanded = false;\r\n this._nodes$.next(this._nodes$.value);\r\n resolve(false);\r\n return;\r\n }\r\n\r\n this._dirty = true;\r\n const nodes = this._nodes$.value;\r\n const parentIndex = nodes.indexOf(parentNode);\r\n\r\n if (parentIndex === -1) {\r\n reject(`Parent node ID ${parentId} not found in store`);\r\n return;\r\n }\r\n\r\n const pageNodes = this.createPageNodes(page);\r\n\r\n // find the range of children to replace\r\n let start = parentIndex + 1;\r\n let end = start;\r\n\r\n // find all current children of this parent (at any page)\r\n while (\r\n end < nodes.length &&\r\n nodes[end].parentId === parentId &&\r\n nodes[end].y === parentNode.y + 1\r\n ) {\r\n // skip descendants of children\r\n const childY = nodes[end].y;\r\n end++;\r\n while (end < nodes.length && nodes[end].y > childY) {\r\n end++;\r\n }\r\n }\r\n\r\n // replace the children with the new page\r\n nodes.splice(start, end - start, ...(pageNodes as E[]));\r\n\r\n // update parent paging info\r\n parentNode.paging = {\r\n pageNumber: page.pageNumber,\r\n pageCount: page.pageCount,\r\n total: page.total,\r\n };\r\n\r\n this._nodes$.next(nodes);\r\n resolve(true);\r\n },\r\n error: (error) => {\r\n console.error('Error changing page:', error);\r\n reject(error);\r\n },\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Clear the store. The cache is cleared and the nodes are removed.\r\n */\r\n public clear(): void {\r\n this._cache.clear();\r\n this._nodes$.next([]);\r\n this._dirty = true;\r\n }\r\n\r\n /**\r\n * Clear the cache.\r\n */\r\n public clearCache(): void {\r\n this._cache.clear();\r\n }\r\n\r\n /**\r\n * Check if the page with the given number and filter is in cache.\r\n * @param pageNumber The page number.\r\n * @param filter The filter.\r\n * @returns True if the page is in cache, false otherwise.\r\n */\r\n public hasCachedPage(pageNumber: number, filter: F): boolean {\r\n const key = this.buildCacheKey(pageNumber, filter);\r\n return this._cache.has(key);\r\n }\r\n\r\n /**\r\n * Remove all hilite properties from all nodes in the store.\r\n */\r\n public removeHilites(): void {\r\n const nodes = this._nodes$.value;\r\n nodes.forEach((node) => {\r\n node.hilite = undefined;\r\n });\r\n this._nodes$.next(nodes);\r\n }\r\n\r\n /**\r\n * Find all nodes whose labels include the specified search text,\r\n * highlight them, and ensure they are visible by expanding their ancestors.\r\n * @param searchText The text to search for in node labels (case-insensitive).\r\n * @returns Promise that resolves when all matching nodes are highlighted and visible.\r\n */\r\n public async findLabels(searchText: string): Promise<void> {\r\n if (!searchText || searchText.trim().length === 0) {\r\n this.removeHilites();\r\n return;\r\n }\r\n\r\n // first remove all existing hilites\r\n this.removeHilites();\r\n\r\n const searchLower = searchText.toLowerCase();\r\n const matchingNodes: E[] = [];\r\n\r\n // find all matching nodes (including those not currently visible):\r\n // search through all possible nodes, not just visible ones\r\n await this.searchAllNodes(searchLower, matchingNodes);\r\n\r\n // highlight the matching nodes\r\n matchingNodes.forEach((node) => {\r\n node.hilite = true;\r\n });\r\n\r\n // ensure all matching nodes are visible by expanding their ancestor paths\r\n const expansionPromises: Promise<void>[] = [];\r\n for (const node of matchingNodes) {\r\n expansionPromises.push(this.ensureNodeVisible(node.id));\r\n }\r\n\r\n await Promise.all(expansionPromises);\r\n\r\n // update the nodes observable\r\n this._nodes$.next(this._nodes$.value);\r\n }\r\n\r\n /**\r\n * Search through all nodes recursively to find matches, including nodes\r\n * that are not currently loaded/visible.\r\n * @param searchLower The search text in lowercase.\r\n * @param matchingNodes Array to collect matching nodes.\r\n */\r\n private async searchAllNodes(\r\n searchLower: string,\r\n matchingNodes: E[]\r\n ): Promise<void> {\r\n // start with root nodes\r\n const rootNodes = this._nodes$.value.filter(\r\n (n) => n.parentId === undefined\r\n );\r\n\r\n for (const rootNode of rootNodes) {\r\n await this.searchNodeAndDescendants(rootNode, searchLower, matchingNodes);\r\n }\r\n }\r\n\r\n /**\r\n * Recursively search a node and all its descendants for label matches.\r\n * @param node The node to search.\r\n * @param searchLower The search text in lowercase.\r\n * @param matchingNodes Array to collect matching nodes.\r\n */\r\n private async searchNodeAndDescendants(\r\n node: E,\r\n searchLower: string,\r\n matchingNodes: E[]\r\n ): Promise<void> {\r\n // check if current node matches\r\n if (node.label.toLowerCase().includes(searchLower)) {\r\n matchingNodes.push(node);\r\n }\r\n\r\n // if node has children, we need to load them to search through them\r\n if (node.hasChildren) {\r\n // Expand the node if not already expanded to load its children\r\n if (!node.expanded) {\r\n await this.expand(node.id);\r\n }\r\n\r\n // get all direct children and search them recursively\r\n const children = this.getChildren(node.id);\r\n for (const child of children) {\r\n await this.searchNodeAndDescendants(child, searchLower, matchingNodes);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Ensure a node is visible by expanding all its ancestors.\r\n * @param nodeId The ID of the node to make visible.\r\n */\r\n private async ensureNodeVisible(nodeId: number): Promise<void> {\r\n const node = this._nodes$.value.find((n) => n.id === nodeId);\r\n if (!node) {\r\n return;\r\n }\r\n\r\n // find the path from root to this node\r\n const ancestorPath: number[] = [];\r\n let currentNode: PagedTreeNode<F> | undefined = node;\r\n\r\n while (currentNode && currentNode.parentId !== undefined) {\r\n ancestorPath.unshift(currentNode.parentId);\r\n currentNode = this._nodes$.value.find(\r\n (n) => n.id === currentNode!.parentId\r\n );\r\n }\r\n\r\n // expand all ancestors in order\r\n for (const ancestorId of ancestorPath) {\r\n const ancestor = this._nodes$.value.find((n) => n.id === ancestorId);\r\n if (ancestor && ancestor.hasChildren && !ancestor.expanded) {\r\n await this.expand(ancestorId);\r\n }\r\n }\r\n }\r\n\r\n private get _isEditable(): boolean {\r\n // check if the service supports editing\r\n return 'saveChanges' in this._service;\r\n }\r\n\r\n private get _editableService(): EditablePagedTreeStoreService<F> | undefined {\r\n return this._isEditable\r\n ? (this._service as EditablePagedTreeStoreService<F>)\r\n : undefined;\r\n }\r\n\r\n /**\r\n * Add a child node to the specified parent.\r\n * @param parentId The ID of the parent node.\r\n * @param child The child node to add (without ID).\r\n * @param first If true, add as first child; otherwise add as last child.\r\n * @returns The added node with temporary ID, or undefined if service doesn't support editing.\r\n */\r\n public addChild(\r\n parentId: number,\r\n child: Omit<TreeNode, 'id' | 'parentId'>,\r\n first: boolean = false\r\n ): Promise<TreeNode | undefined> {\r\n return new Promise((resolve, reject) => {\r\n const editableService = this._editableService;\r\n if (!editableService) {\r\n resolve(undefined);\r\n return;\r\n }\r\n\r\n const parent = this._nodes$.value.find((n) => n.id === parentId);\r\n if (!parent) {\r\n reject(`Parent node with ID ${parentId} not found`);\r\n return;\r\n }\r\n\r\n // calculate position\r\n const siblings = this.getChildren(parentId);\r\n const position = first ? 1 : siblings.length + 1;\r\n const y = parent.y + 1;\r\n\r\n // adjust x values of existing siblings if inserting at beginning\r\n if (first && siblings.length > 0) {\r\n siblings.forEach((sibling) => {\r\n sibling.x++;\r\n editableService.updateNode(sibling.id, { x: sibling.x });\r\n });\r\n }\r\n\r\n const newChild: Omit<TreeNode, 'id'> = {\r\n ...child,\r\n parentId,\r\n y,\r\n x: position,\r\n };\r\n\r\n const addedNode = editableService.addNode(newChild, parentId, position);\r\n\r\n // update parent hasChildren if it was false\r\n if (parent.hasChildren === false) {\r\n parent.hasChildren = true;\r\n editableService.updateNode(parentId, { hasChildren: true });\r\n }\r\n\r\n // if parent is expanded, add the node to the visible list\r\n if (parent.expanded) {\r\n const nodes = this._nodes$.value;\r\n const parentIndex = nodes.indexOf(parent as E);\r\n if (parentIndex !== -1) {\r\n const insertIndex = first\r\n ? parentIndex + 1\r\n : parentIndex + siblings.length + 1;\r\n const pagedNode: E = {\r\n ...addedNode,\r\n paging: parent.paging,\r\n expanded: false,\r\n } as E;\r\n nodes.splice(insertIndex, 0, pagedNode);\r\n this._nodes$.next(nodes);\r\n }\r\n }\r\n\r\n this._dirty = true;\r\n this.invalidateCache(parentId);\r\n resolve(addedNode);\r\n });\r\n }\r\n\r\n /**\r\n * Add a sibling node next to the anchor node.\r\n * @param anchorId The ID of the anchor node.\r\n * @param sibling The sibling node to add (without ID).\r\n * @param before If true, add before anchor; otherwise add after anchor.\r\n * @returns The added node with temporary ID, or undefined if service doesn't support editing.\r\n */\r\n public addSibling(\r\n anchorId: number,\r\n sibling: Omit<TreeNode, 'id' | 'parentId' | 'y' | 'x'>,\r\n before: boolean = false\r\n ): Promise<TreeNode | undefined> {\r\n return new Promise((resolve, reject) => {\r\n const editableService = this._editableService;\r\n if (!editableService) {\r\n resolve(undefined);\r\n return;\r\n }\r\n\r\n const anchor = this._nodes$.value.find((n) => n.id === anchorId);\r\n if (!anchor) {\r\n reject(`Anchor node with ID ${anchorId} not found`);\r\n return;\r\n }\r\n\r\n // get all siblings of the anchor\r\n const siblings = this._nodes$.value.filter(\r\n (n) => n.parentId === anchor.parentId && n.y === anchor.y\r\n );\r\n siblings.sort((a, b) => a.x - b.x);\r\n\r\n const anchorIndex = siblings.findIndex((s) => s.id === anchorId);\r\n const insertPosition = before ? anchor.x : anchor.x + 1;\r\n\r\n // adjust x values of siblings that come after the insertion point\r\n siblings.slice(before ? anchorIndex : anchorIndex + 1).forEach((s) => {\r\n s.x++;\r\n editableService.updateNode(s.id, { x: s.x });\r\n });\r\n\r\n const newSibling: Omit<TreeNode, 'id'> = {\r\n ...sibling,\r\n parentId: anchor.parentId,\r\n y: anchor.y,\r\n x: insertPosition,\r\n };\r\n\r\n const addedNode = editableService.addNode(newSibling, anchor.parentId);\r\n\r\n // add to visible list if the parent is expanded\r\n const nodes = this._nodes$.value;\r\n const anchorVisibleIndex = nodes.indexOf(anchor as E);\r\n if (anchorVisibleIndex !== -1) {\r\n const insertIndex = before\r\n ? anchorVisibleIndex\r\n : anchorVisibleIndex + 1;\r\n const pagedNode: E = {\r\n ...addedNode,\r\n paging: anchor.paging,\r\n expanded: false,\r\n } as E;\r\n nodes.splice(insertIndex, 0, pagedNode);\r\n this._nodes$.next(nodes);\r\n }\r\n\r\n this._dirty = true;\r\n this.invalidateCache(anchor.parentId);\r\n resolve(addedNode);\r\n });\r\n }\r\n\r\n /**\r\n * Remove a node from the tree.\r\n * We only track the deletion and update visible siblings.\r\n * Coordinate adjustments for non-visible nodes are handled by applyLocalChanges.\r\n */\r\n public removeNode(nodeId: number): Promise<boolean> {\r\n return new Promise((resolve, reject) => {\r\n const editableService = this._editableService;\r\n if (!editableService) {\r\n resolve(false);\r\n return;\r\n }\r\n\r\n const node = this._nodes$.value.find((n) => n.id === nodeId);\r\n if (!node) {\r\n resolve(false);\r\n return;\r\n }\r\n\r\n const parentId = node.parentId;\r\n const nodeY = node.y;\r\n const nodeX = node.x;\r\n\r\n // CRITICAL: ensure the node is in the editable service's cache\r\n // before removing it, so its original data is preserved\r\n if (!editableService.getNode(nodeId)) {\r\n // pass the complete node including any extended properties (like 'key'):\r\n // this preserves all data needed for persistence\r\n editableService.updateNode(nodeId, node as TreeNode);\r\n console.log('Added node to cache before deletion:', nodeId);\r\n }\r\n\r\n // remove all descendants first\r\n const descendants = this.getDescendants(nodeId);\r\n descendants.forEach((descendant) => {\r\n // ensure each descendant is in cache before removing\r\n if (!editableService.getNode(descendant.id)) {\r\n editableService.updateNode(descendant.id, descendant as TreeNode);\r\n console.log(\r\n 'Added descendant to cache before deletion:',\r\n descendant.id\r\n );\r\n }\r\n editableService.removeNode(descendant.id);\r\n });\r\n\r\n // remove the node itself\r\n console.log('Removing node from editable service:', nodeId);\r\n editableService.removeNode(nodeId);\r\n\r\n // update ONLY visible siblings' x coordinates\r\n // (Non-visible siblings will get adjusted by applyLocalChanges)\r\n const visibleSiblings = this._nodes$.value.filter(\r\n (n) => n.parentId === parentId && n.y === nodeY && n.x > nodeX\r\n );\r\n\r\n visibleSiblings.forEach((sibling) => {\r\n sibling.x--;\r\n // this will succeed because these nodes ARE in the local cache\r\n editableService.updateNode(sibling.id, { x: sibling.x });\r\n });\r\n\r\n // remove from visible list\r\n const nodes = this._nodes$.value;\r\n const nodeIndex = nodes.indexOf(node as E);\r\n if (nodeIndex !== -1) {\r\n let endIndex = nodeIndex + 1;\r\n while (endIndex < nodes.length && nodes[endIndex].y > nodeY) {\r\n endIndex++;\r\n }\r\n nodes.splice(nodeIndex, endIndex - nodeIndex);\r\n }\r\n\r\n // update parent hasChildren if needed\r\n if (parentId !== undefined) {\r\n const parent = this._nodes$.value.find((n) => n.id === parentId);\r\n if (parent && parent.paging.total === 1) {\r\n // this was the last child\r\n parent.hasChildren = false;\r\n parent.expanded = false;\r\n editableService.updateNode(parentId, { hasChildren: false });\r\n this._nodes$.next(nodes);\r\n this._dirty = true;\r\n this.invalidateCache(parentId);\r\n resolve(true);\r\n return;\r\n }\r\n }\r\n\r\n this._nodes$.next(nodes);\r\n this._dirty = true;\r\n this.invalidateCache(parentId);\r\n\r\n // reload the parent's current page to show the updated state\r\n if (parentId !== undefined) {\r\n const parent = this._nodes$.value.find((n) => n.id === parentId);\r\n if (parent?.expanded && parent?.paging) {\r\n this.changePage(parentId, parent.paging.pageNumber)\r\n .then(() => resolve(true))\r\n .catch(reject);\r\n return;\r\n }\r\n }\r\n\r\n resolve(true);\r\n });\r\n }\r\n\r\n /**\r\n * Replace a node with a new one.\r\n * @param oldNodeId The ID of the node to replace.\r\n * @param newNode The new node data (without ID).\r\n * @param keepDescendants If true, keep descendants; otherwise remove them.\r\n * @returns Promise that resolves to the new node, or undefined if service\r\n * doesn't support editing.\r\n */\r\n public replaceNode(\r\n oldNodeId: number,\r\n newNode: Omit<TreeNode, 'id' | 'parentId' | 'y' | 'x'>,\r\n keepDescendants: boolean = true\r\n ): Promise<TreeNode | undefined> {\r\n return new Promise((resolve, reject) => {\r\n const editableService = this._editableService;\r\n if (!editableService) {\r\n resolve(undefined);\r\n return;\r\n }\r\n\r\n const oldNode = this._nodes$.value.find((n) => n.id === oldNodeId);\r\n if (!oldNode) {\r\n reject(`Node with ID ${oldNodeId} not found`);\r\n return;\r\n }\r\n\r\n const updatedNode: TreeNode = {\r\n ...newNode,\r\n id: oldNodeId,\r\n parentId: oldNode.parentId,\r\n y: oldNode.y,\r\n x: oldNode.x,\r\n };\r\n\r\n editableService.updateNode(oldNodeId, updatedNode);\r\n\r\n // handle descendants\r\n if (!keepDescendants) {\r\n const descendants = this.getDescendants(oldNodeId);\r\n descendants.forEach((descendant) => {\r\n editableService.removeNode(descendant.id);\r\n });\r\n\r\n // update hasChildren\r\n editableService.updateNode(oldNodeId, { hasChildren: false });\r\n }\r\n\r\n // update in visible list\r\n const nodes = this._nodes$.value;\r\n const nodeIndex = nodes.findIndex((n) => n.id === oldNodeId);\r\n if (nodeIndex !== -1) {\r\n const pagedNode = nodes[nodeIndex] as E;\r\n Object.assign(pagedNode, updatedNode);\r\n if (!keepDescendants) {\r\n pagedNode.hasChildren = false;\r\n pagedNode.expanded = false;\r\n // remove descendants from visible list\r\n let endIndex = nodeIndex + 1;\r\n while (endIndex < nodes.length && nodes[endIndex].y > oldNode.y) {\r\n endIndex++;\r\n }\r\n if (endIndex > nodeIndex + 1) {\r\n nodes.splice(nodeIndex + 1, endIndex - nodeIndex - 1);\r\n }\r\n }\r\n this._nodes$.next(nodes);\r\n }\r\n\r\n this._dirty = true;\r\n this.invalidateCache(oldNode.parentId);\r\n resolve(updatedNode);\r\n });\r\n }\r\n\r\n /**\r\n * Get all descendants of a node.\r\n */\r\n private getDescendants(nodeId: number): E[] {\r\n const node = this._nodes$.value.find((n) => n.id === nodeId);\r\n if (!node) return [];\r\n\r\n const descendants: E[] = [];\r\n const nodes = this._nodes$.value;\r\n const nodeIndex = nodes.indexOf(node as E);\r\n\r\n if (nodeIndex !== -1) {\r\n let i = nodeIndex + 1;\r\n while (i < nodes.length && nodes[i].y > node.y) {\r\n descendants.push(nodes[i]);\r\n i++;\r\n }\r\n }\r\n\r\n return descendants;\r\n }\r\n\r\n /**\r\n * Invalidate cache for a specific parent and its ancestors.\r\n */\r\n private invalidateCache(parentId?: number): void {\r\n // clear cache entries that might be affected by the change\r\n this._cache.clear();\r\n\r\n // if we have a specific parent, we could be more selective about\r\n // cache invalidation but for now, clearing all is safer\r\n }\r\n\r\n /**\r\n * Save all pending changes if the service supports it.\r\n * Preserves the current expansion state after saving.\r\n * @returns Promise that resolves when save is complete,\r\n * with ID mappings for new nodes.\r\n */\r\n public saveChanges(): Promise<Map<number, number> | undefined> {\r\n return new Promise((resolve, reject) => {\r\n const editableService = this._editableService;\r\n if (!editableService) {\r\n resolve(undefined);\r\n return;\r\n }\r\n\r\n // capture current expansion state before saving\r\n const expandedNodeIds = this._nodes$.value\r\n .filter((n) => n.expanded)\r\n .map((n) => n.id);\r\n\r\n editableService.saveChanges().subscribe({\r\n next: (idMap) => {\r\n // update temporary IDs to permanent IDs in the visible list\r\n if (idMap.size > 0) {\r\n const nodes = this._nodes$.value;\r\n\r\n // update node IDs\r\n nodes.forEach((node) => {\r\n const newId = idMap.get(node.id);\r\n if (newId !== undefined) {\r\n node.id = newId;\r\n }\r\n });\r\n\r\n // update parent IDs for children of replaced nodes\r\n nodes.forEach((node) => {\r\n if (node.parentId !== undefined) {\r\n const newParentId = idMap.get(node.parentId);\r\n if (newParentId !== undefined) {\r\n node.parentId = newParentId;\r\n }\r\n }\r\n });\r\n\r\n this._nodes$.next(nodes);\r\n }\r\n\r\n // clear cache to force fresh data\r\n this._cache.clear();\r\n this._dirty = false;\r\n\r\n // restore expansion state by re-expanding previously expanded nodes\r\n const restoreExpansion = async () => {\r\n for (const oldId of expandedNodeIds) {\r\n const newId = idMap.get(oldId) ?? oldId;\r\n const node = this._nodes$.value.find((n) => n.id === newId);\r\n if (node && !node.expanded) {\r\n await this.expand(newId);\r\n }\r\n }\r\n };\r\n\r\n restoreExpansion().then(() => resolve(idMap));\r\n },\r\n error: (error) => reject(error),\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Check if there are unsaved changes.\r\n */\r\n public hasUnsavedChanges(): boolean {\r\n return this._editableService?.hasChanges() || false;\r\n }\r\n\r\n /**\r\n * Clear all unsaved changes.\r\n */\r\n public clearUnsavedChanges(): void {\r\n this._editableService?.clearChanges();\r\n this._dirty = true;\r\n }\r\n}\r\n","import { Observable, BehaviorSubject, of } from 'rxjs';\r\nimport { map } from 'rxjs/operators';\r\n\r\nimport { DataPage } from '@myrmidon/ngx-tools';\r\n\r\nimport {\r\n TreeNode,\r\n TreeNodeFilter,\r\n PagedTreeStoreService,\r\n} from './paged-tree.store';\r\n\r\n/**\r\n * Types of operations that can be performed on tree nodes.\r\n */\r\nexport enum ChangeOperationType {\r\n ADD = 'add',\r\n REMOVE = 'remove',\r\n UPDATE = 'update',\r\n}\r\n\r\n/**\r\n * Represents a change operation on a tree node.\r\n */\r\nexport interface ChangeOperation {\r\n type: ChangeOperationType;\r\n id: number;\r\n node?: TreeNode;\r\n originalNode?: TreeNode;\r\n parentId?: number;\r\n position?: number;\r\n}\r\n\r\n/**\r\n * Interface for a service that can handle both reading and editing tree nodes.\r\n * Extends the base PagedTreeStoreService with editing capabilities.\r\n */\r\nexport interface EditablePagedTreeStoreService<F extends TreeNodeFilter>\r\n extends PagedTreeStoreService<F> {\r\n /**\r\n * Add a new node to the tree.\r\n * @param node The node data (without ID).\r\n * @param parentId The parent node ID.\r\n * @param position Optional position hint.\r\n * @returns The added node with temporary ID.\r\n */\r\n addNode(\r\n node: Omit<TreeNode, 'id'>,\r\n parentId?: number,\r\n position?: number\r\n ): TreeNode;\r\n\r\n /**\r\n * Update an existing node.\r\n * @param id The node ID.\r\n * @param updates Partial node updates.\r\n */\r\n updateNode(id: number, updates: Partial<TreeNode>): void;\r\n\r\n /**\r\n * Remove a node from the tree.\r\n * @param id The node ID.\r\n */\r\n removeNode(id: number): void;\r\n\r\n /**\r\n * Get a node by ID, including local changes.\r\n * @param id The node ID.\r\n * @returns The node or undefined if not found.\r\n */\r\n getNode(id: number): TreeNode | undefined;\r\n\r\n /**\r\n * Save all pending changes to the data source.\r\n * @returns Observable that completes when save is finished, emitting any ID mappings\r\n * for nodes that received new IDs from the backend.\r\n */\r\n saveChanges(): Observable<Map<number, number>>;\r\n\r\n /**\r\n * Check if there are any unsaved changes.\r\n * @returns True if there are pending changes.\r\n */\r\n hasChanges(): boolean;\r\n\r\n /**\r\n * Clear all pending changes without saving.\r\n */\r\n clearChanges(): void;\r\n\r\n /**\r\n * Get all pending change operations.\r\n * @returns Array of change operations.\r\n */\r\n getChanges(): ChangeOperation[];\r\n}\r\n\r\n/**\r\n * Base implementation of EditablePagedTreeStoreService that handles change tracking\r\n * and provides common editing functionality. Implementers only need to override\r\n * the abstract methods for actual data persistence.\r\n */\r\nexport abstract class EditablePagedTreeStoreServiceBase<\r\n F extends TreeNodeFilter\r\n> implements EditablePagedTreeStoreService<F>\r\n{\r\n protected _changes: ChangeOperation[] = [];\r\n protected _nextTempId = -1;\r\n protected _nodes = new Map<number, TreeNode>();\r\n protected _removedNodes = new Set<number>();\r\n private _hasChanges$ = new BehaviorSubject<boolean>(false);\r\n\r\n /**\r\n * Observable that emits when the change state changes.\r\n */\r\n public hasChanges$ = this._hasChanges$.asObservable();\r\n\r\n /**\r\n * Abstract method to be implemented by subclasses to fetch nodes from the actual data source.\r\n */\r\n protected abstract fetchNodes(\r\n filter: F,\r\n pageNumber: number,\r\n pageSize: number,\r\n hasMockRoot?: boolean\r\n ): Observable<DataPage<TreeNode>>;\r\n\r\n /**\r\n * Abstract method to be implemented by subclasses to persist changes to the data source.\r\n * @param changes The changes to persist.\r\n * @returns Observable that emits a map of temporary IDs to permanent IDs.\r\n */\r\n protected abstract persistChanges(\r\n changes: ChangeOperation[]\r\n ): Observable<Map<number, number>>;\r\n\r\n /**\r\n * Get nodes, including any local changes that haven't been saved yet.\r\n */\r\n public getNodes(\r\n filter: F,\r\n pageNumber: number,\r\n pageSize: number,\r\n hasMockRoot?: boolean\r\n ): Observable<DataPage<TreeNode>> {\r\n return this.fetchNodes(filter, pageNumber, pageSize, hasMockRoot).pipe(\r\n map((page) => this.applyLocalChanges(page, filter))\r\n );\r\n }\r\n\r\n /**\r\n * Apply local changes to a page of nodes.\r\n * This includes applying x-coordinate adjustments for siblings of deleted nodes.\r\n */\r\n private applyLocalChanges(\r\n page: DataPage<TreeNode>,\r\n filter: F\r\n ): DataPage<TreeNode> {\r\n let items = [...page.items];\r\n\r\n // Step 1: Remove deleted nodes from the current page\r\n items = items.filter((node) => !this._removedNodes.has(node.id));\r\n\r\n // Step 2: Calculate x-coordinate adjustments for this page based on deletions\r\n // For each removed node that would affect this page, adjust x coordinates\r\n const xAdjustments = new Map<number, number>(); // nodeId -> adjustment amount\r\n\r\n this._removedNodes.forEach((removedId) => {\r\n const removeChange = this._changes.find(\r\n (c) => c.type === ChangeOperationType.REMOVE && c.id === removedId\r\n );\r\n\r\n if (removeChange?.originalNode) {\r\n const removedNode = removeChange.originalNode;\r\n\r\n // For each item in current page that was a sibling after the removed node\r\n items.forEach((item) => {\r\n if (\r\n item.parentId === removedNode.parentId &&\r\n item.y === removedNode.y &&\r\n item.x > removedNode.x\r\n ) {\r\n // This sibling should have its x decreased\r\n const currentAdjustment = xAdjustments.get(item.id) || 0;\r\n xAdjustments.set(item.id, currentAdjustment - 1);\r\n }\r\n });\r\n }\r\n });\r\n\r\n // Step 3: Apply updates to existing nodes, including coordinate adjustments\r\n items = items.map((node) => {\r\n let result = { ...node };\r\n\r\n // First apply any explicit updates from cache\r\n const updated = this._nodes.get(node.id);\r\n if (updated && !this._removedNodes.has(node.id)) {\r\n result = { ...result, ...updated };\r\n }\r\n\r\n // Then apply calculated x-coordinate adjustments from deletions\r\n const xAdjustment = xAdjustments.get(node.id);\r\n if (xAdjustment !== undefined && xAdjustment !== 0) {\r\n result.x = result.x + xAdjustment;\r\n }\r\n\r\n return result;\r\n });\r\n\r\n // Step 4: Add new nodes that belong to this specific page\r\n const pageParentId = filter.parentId;\r\n const newNodesForThisPage = Array.from(this._nodes.values()).filter(\r\n (node) =>\r\n node.id < 0 && // temporary ID (newly added)\r\n !this._removedNodes.has(node.id) && // not removed\r\n node.parentId === pageParentId && // belongs to the same parent\r\n this.matchesFilter(node, filter) && // matches the filter\r\n node.label !== undefined && // has all required properties\r\n node.x !== undefined &&\r\n node.y !== undefined\r\n );\r\n\r\n items.push(...newNodesForThisPage);\r\n\r\n // Step 5: Sort items by their position (x coordinate)\r\n items.sort((a, b) => a.x - b.x);\r\n\r\n // Step 6: Adjust total count to reflect deletions and additions for this parent\r\n let totalAdjustment = 0;\r\n\r\n // Count deletions that affect this parent\r\n this._removedNodes.forEach((removedId) => {\r\n const change = this._changes.find(\r\n (c) => c.type === ChangeOperationType.REMOVE && c.id === removedId\r\n );\r\n if (change?.originalNode?.parentId === pageParentId) {\r\n totalAdjustment--;\r\n }\r\n });\r\n\r\n // Count additions for this parent\r\n totalAdjustment += newNodesForThisPage.length;\r\n\r\n const adjustedTotal = Math.max(0, page.total + totalAdjustment);\r\n const adjustedPageCount = Math.ceil(adjustedTotal / (page.pageSize || 20));\r\n\r\n return {\r\n ...page,\r\n items: items,\r\n total: adjustedTotal,\r\n pageCount: adjustedPageCount,\r\n };\r\n }\r\n\r\n /**\r\n * Check if a node matches the given filter.\r\n */\r\n private matchesFilter(node: TreeNode, filter: F): boolean {\r\n if (filter.parentId !== undefined && node.parentId !== filter.parentId) {\r\n return false;\r\n }\r\n if (\r\n filter.tags &&\r\n filter.tags.length > 0 &&\r\n (!node.tag || !filter.tags.includes(node.tag))\r\n ) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Add a new node to the tree.\r\n */\r\n public addNode(\r\n node: Omit<TreeNode, 'id'>,\r\n parentId?: number,\r\n position?: number\r\n ): TreeNode {\r\n const newNode: TreeNode = {\r\n ...node,\r\n id: this._nextTempId--,\r\n parentId,\r\n };\r\n\r\n this._nodes.set(newNode.id, newNode);\r\n this._changes.push({\r\n type: ChangeOperationType.ADD,\r\n id: newNode.id,\r\n node: newNode,\r\n parentId,\r\n position,\r\n });\r\n\r\n this.updateHasChanges();\r\n return newNode;\r\n }\r\n\r\n /**\r\n * Remove a node from the tree.\r\n */\r\n public removeNode(id: number): void {\r\n const node = this._nodes.get(id);\r\n if (node || !this._removedNodes.has(id)) {\r\n this._removedNodes.add(id);\r\n this._changes.push({\r\n type: ChangeOperationType.REMOVE,\r\n id,\r\n originalNode: node,\r\n });\r\n this.updateHasChanges();\r\n }\r\n }\r\n\r\n /**\r\n * Update an existing node.\r\n * If the node is in cache, update it with the partial updates.\r\n * If not in cache and updates is a complete TreeNode, add it to cache.\r\n * Otherwise skip (normal for pagination).\r\n */\r\n public updateNode(id: number, updates: Partial<TreeNode>): void {\r\n const existing = this._nodes.get(id);\r\n\r\n if (!existing) {\r\n // Check if updates contains a complete TreeNode (used for deletion prep)\r\n const isCompleteNode =\r\n updates.label !== undefined &&\r\n updates.y !== undefined &&\r\n updates.x !== undefined;\r\n\r\n if (isCompleteNode) {\r\n // Add the complete node to cache (used before deletion)\r\n const completeNode = { ...updates, id } as TreeNode;\r\n this._nodes.set(id, completeNode);\r\n // Don't add a change operation - this is just caching for later operations\r\n }\r\n // Otherwise silently skip - normal for pagination\r\n return;\r\n }\r\n\r\n const updated = { ...existing, ...updates, id } as TreeNode;\r\n\r\n this._nodes.set(id, updated);\r\n this._changes.push({\r\n type: ChangeOperationType.UPDATE,\r\n id,\r\n node: updated,\r\n originalNode: existing,\r\n });\r\n\r\n this.updateHasChanges();\r\n }\r\n\r\n /**\r\n * Save all pending changes.\r\n */\r\n public saveChanges(): Observable<Map<number, number>> {\r\n if (this._changes.length === 0) {\r\n return of(new Map());\r\n }\r\n\r\n return this.persistChanges([...this._changes]).pipe(\r\n map((idMap) => {\r\n // update temporary IDs with permanent ones\r\n idMap.forEach((permanentId, tempId) => {\r\n const node = this._nodes.get(tempId);\r\n if (node) {\r\n this._nodes.delete(tempId);\r\n this._nodes.set(permanentId, { ...node, id: permanentId });\r\n }\r\n });\r\n\r\n // clear changes after successful save\r\n this._changes = [];\r\n this._removedNodes.clear();\r\n this.updateHasChanges();\r\n\r\n return idMap;\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Check if there are unsaved changes.\r\n */\r\n public hasChanges(): boolean {\r\n return this._changes.length > 0;\r\n }\r\n\r\n /**\r\n * Clear all pending changes.\r\n */\r\n public clearChanges(): void {\r\n this._changes = [];\r\n this._nodes.clear();\r\n this._removedNodes.clear();\r\n this.updateHasChanges();\r\n }\r\n\r\n /**\r\n * Get all pending changes.\r\n */\r\n public getChanges(): ChangeOperation[] {\r\n return [...this._changes];\r\n }\r\n\r\n /**\r\n * Get a node by ID, including local changes.\r\n */\r\n public getNode(id: number): TreeNode | undefined {\r\n return this._nodes.get(id);\r\n }\r\n\r\n protected updateHasChanges(): void {\r\n this._hasChanges$.next(this._changes.length > 0);\r\n }\r\n}\r\n","/*\r\n * Public API Surface of paged-data-browsers\r\n */\r\n\r\nexport * from './lib/components/compact-pager/compact-pager.component';\r\nexport * from './lib/components/range-view/range-view.component';\r\nexport * from './lib/components/browser-tree-node/browser-tree-node.component';\r\n\r\nexport * from './lib/services/paged-list.store';\r\nexport * from './lib/services/paged-tree.store';\r\nexport * from './lib/services/editable-paged-tree.store';\r\nexport * from './lib/services/lru-cache';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i2","i3","i4"],"mappings":";;;;;;;;;;;;;;;;MAca,qBAAqB,CAAA;AANlC,IAAA,WAAA,GAAA;AAOE;;AAEG;AACI,QAAA,IAAA,CAAA,MAAM,GAAG,KAAK,CAAa,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,kDAAC;AAE5E;;AAEG;QACa,IAAA,CAAA,YAAY,GAAG,MAAM,EAAc;AAgCpD,IAAA;IA9BQ,OAAO,GAAA;AACZ,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC7D;IAEO,UAAU,GAAA;QACf,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,GAAG,CAAC,EAAE;AAChC,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;gBACrB,GAAG,IAAI,CAAC,MAAM,EAAE;gBAChB,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,GAAG,CAAC;AACzC,aAAA,CAAC;QACJ;IACF;IAEO,MAAM,GAAA;AACX,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE;AACtD,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;gBACrB,GAAG,IAAI,CAAC,MAAM,EAAE;gBAChB,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,GAAG,CAAC;AACzC,aAAA,CAAC;QACJ;IACF;IAEO,MAAM,GAAA;AACX,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE;AACtD,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;gBACrB,GAAG,IAAI,CAAC,MAAM,EAAE;AAChB,gBAAA,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,SAAS;AACpC,aAAA,CAAC;QACJ;IACF;8GAxCW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAArB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,qBAAqB,+PCdlC,ghCAsCA,EAAA,MAAA,EAAA,CAAA,0HAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED5BY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,eAAe,qNAAE,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;2FAI3C,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBANjC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,WACpB,CAAC,YAAY,EAAE,eAAe,EAAE,aAAa,CAAC,EAAA,QAAA,EAAA,ghCAAA,EAAA,MAAA,EAAA,CAAA,0HAAA,CAAA,EAAA;;;MEH5C,kBAAkB,CAAA;AAiC7B,IAAA,WAAA,GAAA;AAhCA;;AAEG;QACI,IAAA,CAAA,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,QAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAC;AAC/B;;AAEG;QACI,IAAA,CAAA,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,OAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAC;AAC9B;;AAEG;AACI,QAAA,IAAA,CAAA,KAAK,GAAG,KAAK,CAAC,GAAG,iDAAC;AACzB;;AAEG;AACI,QAAA,IAAA,CAAA,MAAM,GAAG,KAAK,CAAC,CAAC,kDAAC;AAEjB,QAAA,IAAA,CAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;AACjC,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;AAC5B,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;AAC1B,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;YAE1B,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YACzC,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;YACtC,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YAEvC,OAAO;AACL,gBAAA,CAAC,UAAU,GAAG,WAAW,IAAI,KAAK;gBAClC,CAAC,CAAC,UAAU,GAAG,UAAU,IAAI,WAAW,IAAI,KAAK;aAClD;AACH,QAAA,CAAC,uDAAC;IAEa;8GAjCJ,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAlB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,kBAAkB,4jBCP/B,uUAUA,EAAA,MAAA,EAAA,CAAA,4FAAA,CAAA,EAAA,CAAA,CAAA;;2FDHa,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAL9B,SAAS;+BACE,gBAAgB,EAAA,QAAA,EAAA,uUAAA,EAAA,MAAA,EAAA,CAAA,4FAAA,CAAA,EAAA;;;AEmB5B;;;;;;;;AAQG;MAmBU,wBAAwB,CAAA;AAlBrC,IAAA,WAAA,GAAA;AAmBE;;AAEG;QACa,IAAA,CAAA,IAAI,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAyC;AAErE;;AAEG;QACa,IAAA,CAAA,MAAM,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,QAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAc;AAE5C;;AAEG;QACa,IAAA,CAAA,KAAK,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,OAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAW;AAExC;;;;;;;;AAQG;QACa,IAAA,CAAA,SAAS,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAW;AAE5C;;AAEG;QACa,IAAA,CAAA,OAAO,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,SAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAW;AAE1C;;AAEG;QACa,IAAA,CAAA,UAAU,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,YAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAW;AAE7C;;AAEG;QACa,IAAA,CAAA,UAAU,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,YAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAW;AAE7C;;AAEG;AACa,QAAA,IAAA,CAAA,UAAU,GAAG,KAAK,CAAC,EAAE,sDAAC;AAEtC;;AAEG;AACa,QAAA,IAAA,CAAA,UAAU,GAAG,KAAK,CAAC,GAAG,sDAAC;AAEvC;;AAEG;QACa,IAAA,CAAA,qBAAqB,GAAG,MAAM,EAAsB;AAEpE;;AAEG;QACa,IAAA,CAAA,iBAAiB,GAAG,MAAM,EAAqB;AAE/D;;AAEG;QACa,IAAA,CAAA,qBAAqB,GAAG,MAAM,EAAsB;AAqBrE,IAAA;IAnBQ,gBAAgB,GAAA;AACrB,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE;YAChB;QACF;QACA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAwB,CAAC;IACpE;IAEO,cAAc,CAAC,IAAwB,EAAE,MAAkB,EAAA;AAChE,QAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;YAC1B,IAAI;YACJ,MAAM;AACP,SAAA,CAAC;IACJ;IAEO,YAAY,GAAA;AACjB,QAAA,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE;YACf,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAwB,CAAC;QACpE;IACF;8GArFW,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAxB,wBAAwB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,qBAAA,EAAA,uBAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,qBAAA,EAAA,uBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECjDrC,s8EAwFA,EAAA,MAAA,EAAA,CAAA,87BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDtDI,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACZ,cAAc,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,IAAA,CAAA,QAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,cAAA,EAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACd,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,sFAAA,EAAA,QAAA,EAAA,CAAA,WAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACf,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACb,gBAAgB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,UAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA;;AAKhB,gBAAA,qBAAqB,6GACrB,kBAAkB,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,OAAA,EAAA,OAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA;;AAJlB,gBAAA,mBAAmB,mDACnB,iBAAiB,EAAA,IAAA,EAAA,eAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;2FAQR,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBAlBpC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,uBAAuB,EAAA,OAAA,EACxB;wBACP,YAAY;wBACZ,cAAc;wBACd,eAAe;wBACf,aAAa;wBACb,gBAAgB;;wBAEhB,mBAAmB;wBACnB,iBAAiB;;wBAEjB,qBAAqB;wBACrB,kBAAkB;AACnB,qBAAA,EAAA,QAAA,EAAA,s8EAAA,EAAA,MAAA,EAAA,CAAA,87BAAA,CAAA,EAAA;;;AE7CH;;;;;;;;;;AAUG;MACU,QAAQ,CAAA;AAOnB;;;;;;;;AAQG;IACH,WAAA,CAAY,OAAe,EAAE,YAAA,GAAwB,KAAK,EAAA;AACxD,QAAA,IAAI,CAAC,QAAQ,GAAG,OAAO;AACvB,QAAA,IAAI,CAAC,UAAU,GAAG,CAAC;AACnB,QAAA,IAAI,CAAC,aAAa,GAAG,YAAY;AACjC,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAa;AAClC,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAkB;IACzC;AAEA;;;;AAIG;AACI,IAAA,GAAG,CAAC,GAAW,EAAA;QACpB,IAAI,IAAI,GAAkB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;QAC9C,IAAI,IAAI,EAAE;AACR,YAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC;QAC5B;AACA,QAAA,OAAO,IAAI;IACb;AAEA;;;;AAIG;AACI,IAAA,GAAG,CAAC,GAAW,EAAA;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;IAC7B;AAEA;;;;;;;AAOG;AACI,IAAA,GAAG,CAAC,GAAW,EAAE,IAAO,EAAE,IAAY,EAAA;AAC3C,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC;AAC1B,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE;AACtB,YAAA,IAAI,CAAC,UAAU,IAAI,IAAI;YACvB,OAAO,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE;AACtC,gBAAA,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK;gBACjD,IAAI,CAAC,SAAS,EAAE;oBACd;gBACF;gBACA,IAAI,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;gBAC3C,IAAI,UAAU,EAAE;AACd,oBAAA,IAAI,CAAC,UAAU,IAAI,UAAU;gBAC/B;AACA,gBAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;AAC7B,gBAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;YAC/B;QACF;aAAO;YACL,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;AACvC,gBAAA,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK;gBACjD,IAAI,CAAC,SAAS,EAAE;oBACd;gBACF;AACA,gBAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;AAC7B,gBAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;YAC/B;QACF;IACF;AAEA;;AAEG;IACI,KAAK,GAAA;AACV,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACnB,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACnB,QAAA,IAAI,CAAC,UAAU,GAAG,CAAC;IACrB;AAEA;;;;AAIG;IACI,OAAO,mBAAmB,CAAC,GAAQ,EAAA;QACxC,IAAI,CAAC,GAAG,EAAE;AACR,YAAA,OAAO,CAAC;QACV;QACA,IAAI,SAAS,GAAG,CAAC;QACjB,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;AAC3B,QAAA,KAAK,IAAI,GAAG,IAAI,IAAI,EAAE;AACpB,YAAA,IAAI,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC;AACpB,YAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC7B,gBAAA,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAC/B;AAAO,iBAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;gBACpC,SAAS,IAAI,CAAC;YAChB;AAAO,iBAAA,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE;gBACrC,SAAS,IAAI,CAAC;YAChB;iBAAO,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE;AACtD,gBAAA,SAAS,IAAI,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC;YAC9C;QACF;AACA,QAAA,OAAO,SAAS;IAClB;AACD;;ACrGD;;AAEG;AACI,MAAM,gCAAgC,GAA0B;AACrE,IAAA,QAAQ,EAAE,EAAE;AACZ,IAAA,SAAS,EAAE,EAAE;;AAoBf;;;AAGG;MACU,cAAc,CAAA;AAoBzB;;;AAGG;AACH,IAAA,IAAW,QAAQ,GAAA;QACjB,OAAO,IAAI,CAAC,SAAS;IACvB;IACA,IAAW,QAAQ,CAAC,KAAa,EAAA;AAC/B,QAAA,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE;YAC5B;QACF;AACA,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK;QACtB,IAAI,CAAC,KAAK,EAAE;IACd;AAEA;;;AAGG;IACH,WAAA,CACU,QAAqC,EAC7C,OAAA,GAAiC,gCAAgC,EAAA;QADzD,IAAA,CAAA,QAAQ,GAAR,QAAQ;AAGhB,QAAA,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ;QACjC,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,CAAc,OAAO,CAAC,SAAS,CAAC;;AAE1D,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI,eAAe,CAAc;AAC7C,YAAA,UAAU,EAAE,CAAC;AACb,YAAA,SAAS,EAAE,CAAC;AACZ,YAAA,QAAQ,EAAE,CAAC;AACX,YAAA,KAAK,EAAE,CAAC;AACR,YAAA,KAAK,EAAE,EAAE;AACV,SAAA,CAAC;QACF,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;;QAEvC,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAe,CAAI,EAAO,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE;IAC7C;AAEA;;;AAGG;IACI,OAAO,GAAA;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;IAC7C;AAEA;;;;;;;;AAQG;IACI,aAAa,CAAC,UAAkB,EAAE,MAAS,EAAA;AAChD,QAAA,IAAI,IAAI,CAAC,sBAAsB,EAAE;YAC/B,OAAO,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,MAAM,CAAC;QACxD;QACA,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,CAAC;IAClD;AAEA;;;AAGG;AACK,IAAA,QAAQ,CAAC,UAAkB,EAAA;AACjC,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAC3B,UAAU,EACV,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,QAAQ,CAAC,KAAK,CACpB;IACH;AAEA;;;;;AAKG;IACI,OAAO,CAAC,UAAkB,EAAE,QAAiB,EAAA;QAClD,IAAI,QAAQ,IAAI,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE;AAC3C,YAAA,IAAI,CAAC,SAAS,GAAG,QAAQ;QAC3B;QACA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;;AAErC,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;YACvC,IAAI,UAAU,EAAE;AACd,gBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;AAC5B,gBAAA,OAAO,EAAE;gBACT;YACF;;AAGA,YAAA,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC;AAClC,gBAAA,IAAI,EAAE,CAAC,IAAI,KAAI;AACb,oBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;oBACtB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7B,oBAAA,OAAO,EAAE;gBACX,CAAC;AACD,gBAAA,KAAK,EAAE,MAAM;AACd,aAAA,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA;;;AAGG;IACI,OAAO,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK;IAC1B;AAEA;;;;AAIG;AACI,IAAA,SAAS,CAAC,MAAS,EAAA;QACxB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1B,YAAA,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC;AACvC,QAAA,CAAC,CAAC;IACJ;AAEA;;;AAGG;IACI,SAAS,GAAA;AACd,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK;IAC5B;AAEA;;;AAGG;IACI,KAAK,GAAA;AACV,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACnB,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,EAAO,CAAC;IAChC;AAEA;;AAEG;IACI,KAAK,GAAA;AACV,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACnB,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;AACf,YAAA,UAAU,EAAE,CAAC;AACb,YAAA,SAAS,EAAE,CAAC;AACZ,YAAA,QAAQ,EAAE,CAAC;AACX,YAAA,KAAK,EAAE,CAAC;AACR,YAAA,KAAK,EAAE,EAAE;AACV,SAAA,CAAC;IACJ;AAEA;;AAEG;IACI,UAAU,GAAA;AACf,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;IACrB;AAEA;;;;;AAKG;IACI,aAAa,CAAC,UAAkB,EAAE,MAAS,EAAA;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC;QAClD,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;IAC7B;AACD;;ACzJD;;;;;;;;;;AAUG;MACU,cAAc,CAAA;AAiCzB;;;AAGG;AACH,IAAA,IAAW,QAAQ,GAAA;QACjB,OAAO,IAAI,CAAC,SAAS;IACvB;IACA,IAAW,QAAQ,CAAC,KAAa,EAAA;AAC/B,QAAA,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE;YAC5B;QACF;AACA,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK;QACtB,IAAI,CAAC,KAAK,EAAE;IACd;AAEA;;;;AAIG;IACH,WAAA,CACU,QAAkC,EAC1C,OAAA,GAAiC,gCAAgC,EAAA;QADzD,IAAA,CAAA,QAAQ,GAAR,QAAQ;AAGhB,QAAA,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ;QACjC,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,CAAqB,OAAO,CAAC,SAAS,CAAC;AACjE,QAAA,IAAI,CAAC,sBAAsB,GAAG,OAAO,CAAC,aAAa;QACnD,IAAI,CAAC,OAAO,GAAG,IAAI,eAAe,CAAM,EAAE,CAAC;QAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE;QACzC,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAe,CAAI,EAAO,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE;AAC3C,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;QAClB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,IAAI,KAAK;IAClD;AAEA;;;;;AAKG;AACK,IAAA,SAAS,CAAC,IAAuB,EAAA;QACvC,OAAO,IAAI,EAAE;AACX,cAAE;AACE,gBAAA,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK;gBACtB,GAAG,IAAI,CAAC,MAAM;AACf;AACH,cAAE,IAAI,CAAC,QAAQ,CAAC,KAAK;IACzB;AAEA;;;AAGG;IACI,OAAO,GAAA;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;IACxC;AAEA;;;AAGG;IACI,QAAQ,GAAA;AACb,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;IAC3B;AAEA;;;;AAIG;IACI,WAAW,GAAA;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9B;AAEA;;;;;;;;AAQG;IACI,aAAa,CAAC,UAAkB,EAAE,MAAS,EAAA;AAChD,QAAA,IAAI,IAAI,CAAC,sBAAsB,EAAE;YAC/B,OAAO,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,MAAM,CAAC;QACxD;QACA,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,CAAC;IAClD;AAEA;;;;;;AAMG;IACK,wBAAwB,CAC9B,MAAS,EACT,UAAkB,EAAA;;QAGlB,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC;QAClD,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;;;QAIxC,IAAI,WAAW,EAAE;AACf,YAAA,OAAO,EAAE,CAAC,WAAW,CAAC;QACxB;aAAO;YACL,OAAO,IAAI,CAAC;AACT,iBAAA,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY;AAC9D,iBAAA,IAAI,CACH,GAAG,CAAC,CAAC,IAAI,KAAI;gBACX,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/B,CAAC,CAAC,CACH;QACL;IACF;AAEA;;;;;AAKG;AACK,IAAA,eAAe,CAAC,IAAwB,EAAA;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAI;YAC1B,OAAO;AACL,gBAAA,GAAG,CAAC;gBACJ,WAAW,EAAE,CAAC,CAAC,WAAW;AAC1B,gBAAA,MAAM,EAAE;oBACN,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,KAAK,EAAE,IAAI,CAAC,KAAK;AAClB,iBAAA;aACG;AACR,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;AAKG;AACI,IAAA,SAAS,CAAC,MAAS,EAAA;QACxB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,KAAK,MAAM,EAAE;AAClC,YAAA,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;QAC/B;AACA,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1B,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,QAAA,OAAO,IAAI,CAAC,KAAK,EAAE;IACrB;AAEA;;;AAGG;IACI,KAAK,GAAA;AACV,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACnB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK;QAElC,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,KAAI;AAC9C,YAAA,IAAI,CAAC;AACF,iBAAA,QAAQ,CACP;AACE,gBAAA,GAAG,MAAM;gBACT,QAAQ,EAAE,SAAS;aACpB,EACD,CAAC,EACD,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,YAAY;AAElB,iBAAA,SAAS,CAAC;AACT,gBAAA,IAAI,EAAE,CAAC,IAAwB,KAAI;;AAEjC,oBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;;AAG7C,oBAAA,MAAM,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KACtD,IAAI,CAAC,wBAAwB,CAAC,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CACnE;oBACD,QAAQ,CAAC,mBAAmB,CAAC,CAAC,SAAS,CAAC,CAAC,aAAa,KAAI;wBACxD,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,KAAI;AAChC,4BAAA,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;AACpD,wBAAA,CAAC,CAAC;AACJ,oBAAA,CAAC,CAAC;AAEF,oBAAA,IAAI,CAAC,MAAM,GAAG,KAAK;oBACnB,OAAO,CAAC,IAAI,CAAC;gBACf,CAAC;AACD,gBAAA,KAAK,EAAE,CAAC,KAAK,KAAI;oBACf,MAAM,CAAC,KAAK,CAAC;gBACf,CAAC;AACF,aAAA,CAAC;AACN,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;AAKG;IACI,aAAa,CAAC,EAAU,EAAE,MAAiB,EAAA;QAChD,IAAI,CAAC,EAAE,EAAE;AACP,YAAA,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;QAC/B;QACA,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,KAAI;YAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;YACxD,IAAI,CAAC,IAAI,EAAE;AACT,gBAAA,MAAM,CAAC,CAAA,QAAA,EAAW,EAAE,CAAA,mBAAA,CAAqB,CAAC;gBAC1C;YACF;AACA,YAAA,IAAK,CAAC,MAAM,GAAG,MAAM,IAAI,SAAS;YAClC,OAAO,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/B,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;AAKG;AACI,IAAA,MAAM,CAAC,EAAU,EAAA;QACtB,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,KAAI;;YAE9C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;;AAExD,YAAA,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,KAAK,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE;gBACxD,OAAO,CAAC,KAAK,CAAC;YAChB;;YAGA,IAAI,CAAC,wBAAwB,CAC3B,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,EACzC,CAAC,CACF,CAAC,SAAS,CAAC,CAAC,IAAI,KAAI;;AAEnB,gBAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;;AAEf,oBAAA,IAAK,CAAC,WAAW,GAAG,KAAK;oBACzB,OAAO,CAAC,KAAK,CAAC;gBAChB;qBAAO;AACL,oBAAA,IAAI,CAAC,MAAM,GAAG,IAAI;;AAElB,oBAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;oBAChC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAK,CAAC;AAClC,oBAAA,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE;AAChB,wBAAA,MAAM,CAAC,CAAA,QAAA,EAAW,EAAE,CAAA,mBAAA,CAAqB,CAAC;oBAC5C;yBAAO;wBACL,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;AAC5C,wBAAA,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,GAAI,SAAiB,CAAC;AACjD,wBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;AACxB,wBAAA,IAAK,CAAC,WAAW,GAAG,IAAI;AACxB,wBAAA,IAAK,CAAC,QAAQ,GAAG,IAAI;wBACrB,OAAO,CAAC,IAAI,CAAC;oBACf;gBACF;AACF,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;;AAMG;IACI,MAAM,SAAS,CAAC,EAAW,EAAA;AAChC,QAAA,IAAI,EAAE,KAAK,SAAS,EAAE;;YAEpB,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACrC,MAAM,QAAQ,GAAuB,EAAE;AACvC,YAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACxB,gBAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;AAC/B,oBAAA,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACxC;YACF;AACA,YAAA,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC3B,YAAA,OAAO,IAAI;QACb;;AAGA,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;AAChC,QAAA,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;AACrD,QAAA,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE;AACpB,YAAA,OAAO,KAAK;QACd;AAEA,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC;;QAG7B,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AACtC,YAAA,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB;;QAGA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAuB,EAAE;AACvC,QAAA,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE;AAC5B,YAAA,IAAI,KAAK,CAAC,WAAW,EAAE;AACrB,gBAAA,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACzC;QACF;AAEA,QAAA,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;AACvB,YAAA,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC7B;AAEA,QAAA,OAAO,IAAI;IACb;AAEA;;;;AAIG;AACI,IAAA,WAAW,CAAC,EAAU,EAAA;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QACxD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,KAAK,KAAK,EAAE;AACvC,YAAA,OAAO,EAAE;QACX;AACA,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;QAChC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;AACjC,QAAA,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE;AAChB,YAAA,OAAO,EAAE;QACX;QACA,MAAM,QAAQ,GAAQ,EAAE;AACxB,QAAA,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC;AACjB,QAAA,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE;YAC9C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvB,YAAA,CAAC,EAAE;QACL;AACA,QAAA,OAAO,QAAQ;IACjB;IAEQ,iBAAiB,CACvB,KAAyB,EACzB,SAAiB,EAAA;AAEjB,QAAA,IAAI,CAAC,GAAG,SAAS,GAAG,CAAC;QACrB,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;AAC1D,YAAA,CAAC,EAAE;QACL;AACA,QAAA,KAAK,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC;IAChD;AAEA;;;;;AAKG;AACI,IAAA,QAAQ,CAAC,EAAU,EAAA;QACxB,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,KAAI;YAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;AACxD,YAAA,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;gBACzD,OAAO,CAAC,KAAK,CAAC;YAChB;;AAGA,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;YAChC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,IAAK,CAAC;AACtC,YAAA,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE;AACpB,gBAAA,MAAM,CAAC,CAAA,QAAA,EAAW,EAAE,CAAA,mBAAA,CAAqB,CAAC;YAC5C;iBAAO;AACL,gBAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,gBAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC;AACxC,gBAAA,IAAK,CAAC,QAAQ,GAAG,KAAK;;AAEtB,gBAAA,IAAI,IAAI,EAAE,MAAM,EAAE;AAChB,oBAAA,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC;gBAC5B;AACA,gBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;gBACxB,OAAO,CAAC,IAAI,CAAC;YACf;AACF,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;;AAMG;AACI,IAAA,WAAW,CAAC,EAAW,EAAA;AAC5B,QAAA,IAAI,EAAE,KAAK,SAAS,EAAE;;YAEpB,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC/D,IAAI,CAAC,GAAG,CAAC;AACT,YAAA,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE;gBACvB,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,EAAE;oBACnC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/B;AACA,gBAAA,CAAC,EAAE;YACL;AACA,YAAA,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;QAC9B;AAEA,QAAA,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;AACjB,QAAA,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;IAC9B;AAEA;;;;;;;AAOG;IACI,UAAU,CAAC,QAAgB,EAAE,UAAkB,EAAA;QACpD,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,KAAI;;YAE9C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC;;YAGpE,IAAI,CAAC,UAAU,EAAE;gBACf,OAAO,CAAC,KAAK,CAAC;gBACd;YACF;;AAGA,YAAA,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE;gBACxB,OAAO,CAAC,KAAK,CAAC;gBACd;YACF;;AAGA,YAAA,IAAI,CAAC,wBAAwB,CAC3B,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,EAC3C,UAAU,CACX,CAAC,SAAS,CAAC;AACV,gBAAA,IAAI,EAAE,CAAC,IAAI,KAAI;;AAEb,oBAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AACf,wBAAA,UAAU,CAAC,WAAW,GAAG,KAAK;AAC9B,wBAAA,UAAU,CAAC,QAAQ,GAAG,KAAK;wBAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;wBACrC,OAAO,CAAC,KAAK,CAAC;wBACd;oBACF;AAEA,oBAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,oBAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;oBAChC,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;AAE7C,oBAAA,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE;AACtB,wBAAA,MAAM,CAAC,CAAA,eAAA,EAAkB,QAAQ,CAAA,mBAAA,CAAqB,CAAC;wBACvD;oBACF;oBAEA,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;;AAG5C,oBAAA,IAAI,KAAK,GAAG,WAAW,GAAG,CAAC;oBAC3B,IAAI,GAAG,GAAG,KAAK;;AAGf,oBAAA,OACE,GAAG,GAAG,KAAK,CAAC,MAAM;AAClB,wBAAA,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,QAAQ;AAChC,wBAAA,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,GAAG,CAAC,EACjC;;wBAEA,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3B,wBAAA,GAAG,EAAE;AACL,wBAAA,OAAO,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE;AAClD,4BAAA,GAAG,EAAE;wBACP;oBACF;;AAGA,oBAAA,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,EAAE,GAAI,SAAiB,CAAC;;oBAGvD,UAAU,CAAC,MAAM,GAAG;wBAClB,UAAU,EAAE,IAAI,CAAC,UAAU;wBAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;wBACzB,KAAK,EAAE,IAAI,CAAC,KAAK;qBAClB;AAED,oBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;oBACxB,OAAO,CAAC,IAAI,CAAC;gBACf,CAAC;AACD,gBAAA,KAAK,EAAE,CAAC,KAAK,KAAI;AACf,oBAAA,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC;oBAC5C,MAAM,CAAC,KAAK,CAAC;gBACf,CAAC;AACF,aAAA,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA;;AAEG;IACI,KAAK,GAAA;AACV,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACnB,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;AACrB,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;IACpB;AAEA;;AAEG;IACI,UAAU,GAAA;AACf,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;IACrB;AAEA;;;;;AAKG;IACI,aAAa,CAAC,UAAkB,EAAE,MAAS,EAAA;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC;QAClD,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;IAC7B;AAEA;;AAEG;IACI,aAAa,GAAA;AAClB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;AAChC,QAAA,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;AACrB,YAAA,IAAI,CAAC,MAAM,GAAG,SAAS;AACzB,QAAA,CAAC,CAAC;AACF,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;IAC1B;AAEA;;;;;AAKG;IACI,MAAM,UAAU,CAAC,UAAkB,EAAA;AACxC,QAAA,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;YACjD,IAAI,CAAC,aAAa,EAAE;YACpB;QACF;;QAGA,IAAI,CAAC,aAAa,EAAE;AAEpB,QAAA,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,EAAE;QAC5C,MAAM,aAAa,GAAQ,EAAE;;;QAI7B,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,aAAa,CAAC;;AAGrD,QAAA,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;AAC7B,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AACpB,QAAA,CAAC,CAAC;;QAGF,MAAM,iBAAiB,GAAoB,EAAE;AAC7C,QAAA,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE;AAChC,YAAA,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzD;AAEA,QAAA,MAAM,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;;QAGpC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;IACvC;AAEA;;;;;AAKG;AACK,IAAA,MAAM,cAAc,CAC1B,WAAmB,EACnB,aAAkB,EAAA;;QAGlB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CACzC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,KAAK,SAAS,CAChC;AAED,QAAA,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;YAChC,MAAM,IAAI,CAAC,wBAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,aAAa,CAAC;QAC3E;IACF;AAEA;;;;;AAKG;AACK,IAAA,MAAM,wBAAwB,CACpC,IAAO,EACP,WAAmB,EACnB,aAAkB,EAAA;;AAGlB,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE;AAClD,YAAA,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1B;;AAGA,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE;;AAEpB,YAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;gBAClB,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B;;YAGA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1C,YAAA,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE;gBAC5B,MAAM,IAAI,CAAC,wBAAwB,CAAC,KAAK,EAAE,WAAW,EAAE,aAAa,CAAC;YACxE;QACF;IACF;AAEA;;;AAGG;IACK,MAAM,iBAAiB,CAAC,MAAc,EAAA;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC;QAC5D,IAAI,CAAC,IAAI,EAAE;YACT;QACF;;QAGA,MAAM,YAAY,GAAa,EAAE;QACjC,IAAI,WAAW,GAAiC,IAAI;QAEpD,OAAO,WAAW,IAAI,WAAW,CAAC,QAAQ,KAAK,SAAS,EAAE;AACxD,YAAA,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC;YAC1C,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CACnC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,WAAY,CAAC,QAAQ,CACtC;QACH;;AAGA,QAAA,KAAK,MAAM,UAAU,IAAI,YAAY,EAAE;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC;YACpE,IAAI,QAAQ,IAAI,QAAQ,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;AAC1D,gBAAA,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;YAC/B;QACF;IACF;AAEA,IAAA,IAAY,WAAW,GAAA;;AAErB,QAAA,OAAO,aAAa,IAAI,IAAI,CAAC,QAAQ;IACvC;AAEA,IAAA,IAAY,gBAAgB,GAAA;QAC1B,OAAO,IAAI,CAAC;cACP,IAAI,CAAC;cACN,SAAS;IACf;AAEA;;;;;;AAMG;AACI,IAAA,QAAQ,CACb,QAAgB,EAChB,KAAwC,EACxC,QAAiB,KAAK,EAAA;QAEtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,YAAA,MAAM,eAAe,GAAG,IAAI,CAAC,gBAAgB;YAC7C,IAAI,CAAC,eAAe,EAAE;gBACpB,OAAO,CAAC,SAAS,CAAC;gBAClB;YACF;YAEA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC;YAChE,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,MAAM,CAAC,CAAA,oBAAA,EAAuB,QAAQ,CAAA,UAAA,CAAY,CAAC;gBACnD;YACF;;YAGA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;AAC3C,YAAA,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC;AAChD,YAAA,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC;;YAGtB,IAAI,KAAK,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;AAChC,gBAAA,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,KAAI;oBAC3B,OAAO,CAAC,CAAC,EAAE;AACX,oBAAA,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;AAC1D,gBAAA,CAAC,CAAC;YACJ;AAEA,YAAA,MAAM,QAAQ,GAAyB;AACrC,gBAAA,GAAG,KAAK;gBACR,QAAQ;gBACR,CAAC;AACD,gBAAA,CAAC,EAAE,QAAQ;aACZ;AAED,YAAA,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;;AAGvE,YAAA,IAAI,MAAM,CAAC,WAAW,KAAK,KAAK,EAAE;AAChC,gBAAA,MAAM,CAAC,WAAW,GAAG,IAAI;gBACzB,eAAe,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;YAC7D;;AAGA,YAAA,IAAI,MAAM,CAAC,QAAQ,EAAE;AACnB,gBAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;gBAChC,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAW,CAAC;AAC9C,gBAAA,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE;oBACtB,MAAM,WAAW,GAAG;0BAChB,WAAW,GAAG;0BACd,WAAW,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC;AACrC,oBAAA,MAAM,SAAS,GAAM;AACnB,wBAAA,GAAG,SAAS;wBACZ,MAAM,EAAE,MAAM,CAAC,MAAM;AACrB,wBAAA,QAAQ,EAAE,KAAK;qBACX;oBACN,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,SAAS,CAAC;AACvC,oBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;gBAC1B;YACF;AAEA,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,YAAA,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;YAC9B,OAAO,CAAC,SAAS,CAAC;AACpB,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;;AAMG;AACI,IAAA,UAAU,CACf,QAAgB,EAChB,OAAsD,EACtD,SAAkB,KAAK,EAAA;QAEvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,YAAA,MAAM,eAAe,GAAG,IAAI,CAAC,gBAAgB;YAC7C,IAAI,CAAC,eAAe,EAAE;gBACpB,OAAO,CAAC,SAAS,CAAC;gBAClB;YACF;YAEA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC;YAChE,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,MAAM,CAAC,CAAA,oBAAA,EAAuB,QAAQ,CAAA,UAAA,CAAY,CAAC;gBACnD;YACF;;AAGA,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CACxC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAC1D;AACD,YAAA,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAElC,YAAA,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC;AAChE,YAAA,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC;;YAGvD,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAI;gBACnE,CAAC,CAAC,CAAC,EAAE;AACL,gBAAA,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9C,YAAA,CAAC,CAAC;AAEF,YAAA,MAAM,UAAU,GAAyB;AACvC,gBAAA,GAAG,OAAO;gBACV,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,CAAC,EAAE,MAAM,CAAC,CAAC;AACX,gBAAA,CAAC,EAAE,cAAc;aAClB;AAED,YAAA,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC;;AAGtE,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;YAChC,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAAC,MAAW,CAAC;AACrD,YAAA,IAAI,kBAAkB,KAAK,CAAC,CAAC,EAAE;gBAC7B,MAAM,WAAW,GAAG;AAClB,sBAAE;AACF,sBAAE,kBAAkB,GAAG,CAAC;AAC1B,gBAAA,MAAM,SAAS,GAAM;AACnB,oBAAA,GAAG,SAAS;oBACZ,MAAM,EAAE,MAAM,CAAC,MAAM;AACrB,oBAAA,QAAQ,EAAE,KAAK;iBACX;gBACN,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,SAAS,CAAC;AACvC,gBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;YAC1B;AAEA,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,YAAA,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC;YACrC,OAAO,CAAC,SAAS,CAAC;AACpB,QAAA,CAAC,CAAC;IACJ;AAEA;;;;AAIG;AACI,IAAA,UAAU,CAAC,MAAc,EAAA;QAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,YAAA,MAAM,eAAe,GAAG,IAAI,CAAC,gBAAgB;YAC7C,IAAI,CAAC,eAAe,EAAE;gBACpB,OAAO,CAAC,KAAK,CAAC;gBACd;YACF;YAEA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC;YAC5D,IAAI,CAAC,IAAI,EAAE;gBACT,OAAO,CAAC,KAAK,CAAC;gBACd;YACF;AAEA,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ;AAC9B,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC;AACpB,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC;;;YAIpB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;;;AAGpC,gBAAA,eAAe,CAAC,UAAU,CAAC,MAAM,EAAE,IAAgB,CAAC;AACpD,gBAAA,OAAO,CAAC,GAAG,CAAC,sCAAsC,EAAE,MAAM,CAAC;YAC7D;;YAGA,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;AAC/C,YAAA,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,KAAI;;gBAEjC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE;oBAC3C,eAAe,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,EAAE,UAAsB,CAAC;oBACjE,OAAO,CAAC,GAAG,CACT,4CAA4C,EAC5C,UAAU,CAAC,EAAE,CACd;gBACH;AACA,gBAAA,eAAe,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;AAC3C,YAAA,CAAC,CAAC;;AAGF,YAAA,OAAO,CAAC,GAAG,CAAC,sCAAsC,EAAE,MAAM,CAAC;AAC3D,YAAA,eAAe,CAAC,UAAU,CAAC,MAAM,CAAC;;;AAIlC,YAAA,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAC/C,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAC/D;AAED,YAAA,eAAe,CAAC,OAAO,CAAC,CAAC,OAAO,KAAI;gBAClC,OAAO,CAAC,CAAC,EAAE;;AAEX,gBAAA,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;AAC1D,YAAA,CAAC,CAAC;;AAGF,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;YAChC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,IAAS,CAAC;AAC1C,YAAA,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE;AACpB,gBAAA,IAAI,QAAQ,GAAG,SAAS,GAAG,CAAC;AAC5B,gBAAA,OAAO,QAAQ,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE;AAC3D,oBAAA,QAAQ,EAAE;gBACZ;gBACA,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,GAAG,SAAS,CAAC;YAC/C;;AAGA,YAAA,IAAI,QAAQ,KAAK,SAAS,EAAE;gBAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC;gBAChE,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,EAAE;;AAEvC,oBAAA,MAAM,CAAC,WAAW,GAAG,KAAK;AAC1B,oBAAA,MAAM,CAAC,QAAQ,GAAG,KAAK;oBACvB,eAAe,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AAC5D,oBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;AACxB,oBAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,oBAAA,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;oBAC9B,OAAO,CAAC,IAAI,CAAC;oBACb;gBACF;YACF;AAEA,YAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;AACxB,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,YAAA,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;;AAG9B,YAAA,IAAI,QAAQ,KAAK,SAAS,EAAE;gBAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC;gBAChE,IAAI,MAAM,EAAE,QAAQ,IAAI,MAAM,EAAE,MAAM,EAAE;oBACtC,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU;yBAC/C,IAAI,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC;yBACxB,KAAK,CAAC,MAAM,CAAC;oBAChB;gBACF;YACF;YAEA,OAAO,CAAC,IAAI,CAAC;AACf,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;;;AAOG;AACI,IAAA,WAAW,CAChB,SAAiB,EACjB,OAAsD,EACtD,kBAA2B,IAAI,EAAA;QAE/B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,YAAA,MAAM,eAAe,GAAG,IAAI,CAAC,gBAAgB;YAC7C,IAAI,CAAC,eAAe,EAAE;gBACpB,OAAO,CAAC,SAAS,CAAC;gBAClB;YACF;YAEA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC;YAClE,IAAI,CAAC,OAAO,EAAE;AACZ,gBAAA,MAAM,CAAC,CAAA,aAAA,EAAgB,SAAS,CAAA,UAAA,CAAY,CAAC;gBAC7C;YACF;AAEA,YAAA,MAAM,WAAW,GAAa;AAC5B,gBAAA,GAAG,OAAO;AACV,gBAAA,EAAE,EAAE,SAAS;gBACb,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,CAAC,EAAE,OAAO,CAAC,CAAC;gBACZ,CAAC,EAAE,OAAO,CAAC,CAAC;aACb;AAED,YAAA,eAAe,CAAC,UAAU,CAAC,SAAS,EAAE,WAAW,CAAC;;YAGlD,IAAI,CAAC,eAAe,EAAE;gBACpB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;AAClD,gBAAA,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,KAAI;AACjC,oBAAA,eAAe,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;AAC3C,gBAAA,CAAC,CAAC;;gBAGF,eAAe,CAAC,UAAU,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;YAC/D;;AAGA,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;AAChC,YAAA,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC;AAC5D,YAAA,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE;AACpB,gBAAA,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAM;AACvC,gBAAA,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC;gBACrC,IAAI,CAAC,eAAe,EAAE;AACpB,oBAAA,SAAS,CAAC,WAAW,GAAG,KAAK;AAC7B,oBAAA,SAAS,CAAC,QAAQ,GAAG,KAAK;;AAE1B,oBAAA,IAAI,QAAQ,GAAG,SAAS,GAAG,CAAC;AAC5B,oBAAA,OAAO,QAAQ,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE;AAC/D,wBAAA,QAAQ,EAAE;oBACZ;AACA,oBAAA,IAAI,QAAQ,GAAG,SAAS,GAAG,CAAC,EAAE;AAC5B,wBAAA,KAAK,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,CAAC,CAAC;oBACvD;gBACF;AACA,gBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;YAC1B;AAEA,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,YAAA,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC;YACtC,OAAO,CAAC,WAAW,CAAC;AACtB,QAAA,CAAC,CAAC;IACJ;AAEA;;AAEG;AACK,IAAA,cAAc,CAAC,MAAc,EAAA;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC;AAC5D,QAAA,IAAI,CAAC,IAAI;AAAE,YAAA,OAAO,EAAE;QAEpB,MAAM,WAAW,GAAQ,EAAE;AAC3B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;QAChC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,IAAS,CAAC;AAE1C,QAAA,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE;AACpB,YAAA,IAAI,CAAC,GAAG,SAAS,GAAG,CAAC;AACrB,YAAA,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE;gBAC9C,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1B,gBAAA,CAAC,EAAE;YACL;QACF;AAEA,QAAA,OAAO,WAAW;IACpB;AAEA;;AAEG;AACK,IAAA,eAAe,CAAC,QAAiB,EAAA;;AAEvC,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;;;IAIrB;AAEA;;;;;AAKG;IACI,WAAW,GAAA;QAChB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,YAAA,MAAM,eAAe,GAAG,IAAI,CAAC,gBAAgB;YAC7C,IAAI,CAAC,eAAe,EAAE;gBACpB,OAAO,CAAC,SAAS,CAAC;gBAClB;YACF;;AAGA,YAAA,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC;iBAClC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ;iBACxB,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;AAEnB,YAAA,eAAe,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC;AACtC,gBAAA,IAAI,EAAE,CAAC,KAAK,KAAI;;AAEd,oBAAA,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE;AAClB,wBAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;;AAGhC,wBAAA,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;4BACrB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;AAChC,4BAAA,IAAI,KAAK,KAAK,SAAS,EAAE;AACvB,gCAAA,IAAI,CAAC,EAAE,GAAG,KAAK;4BACjB;AACF,wBAAA,CAAC,CAAC;;AAGF,wBAAA,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;AACrB,4BAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;gCAC/B,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC5C,gCAAA,IAAI,WAAW,KAAK,SAAS,EAAE;AAC7B,oCAAA,IAAI,CAAC,QAAQ,GAAG,WAAW;gCAC7B;4BACF;AACF,wBAAA,CAAC,CAAC;AAEF,wBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;oBAC1B;;AAGA,oBAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACnB,oBAAA,IAAI,CAAC,MAAM,GAAG,KAAK;;AAGnB,oBAAA,MAAM,gBAAgB,GAAG,YAAW;AAClC,wBAAA,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE;4BACnC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK;4BACvC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC;AAC3D,4BAAA,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AAC1B,gCAAA,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;4BAC1B;wBACF;AACF,oBAAA,CAAC;AAED,oBAAA,gBAAgB,EAAE,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC/C,CAAC;gBACD,KAAK,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC;AAChC,aAAA,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA;;AAEG;IACI,iBAAiB,GAAA;QACtB,OAAO,IAAI,CAAC,gBAAgB,EAAE,UAAU,EAAE,IAAI,KAAK;IACrD;AAEA;;AAEG;IACI,mBAAmB,GAAA;AACxB,QAAA,IAAI,CAAC,gBAAgB,EAAE,YAAY,EAAE;AACrC,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;IACpB;AACD;;AC9tCD;;AAEG;IACS;AAAZ,CAAA,UAAY,mBAAmB,EAAA;AAC7B,IAAA,mBAAA,CAAA,KAAA,CAAA,GAAA,KAAW;AACX,IAAA,mBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACjB,IAAA,mBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACnB,CAAC,EAJW,mBAAmB,KAAnB,mBAAmB,GAAA,EAAA,CAAA,CAAA;AAkF/B;;;;AAIG;MACmB,iCAAiC,CAAA;AAAvD,IAAA,WAAA,GAAA;QAIY,IAAA,CAAA,QAAQ,GAAsB,EAAE;QAChC,IAAA,CAAA,WAAW,GAAG,CAAC,CAAC;AAChB,QAAA,IAAA,CAAA,MAAM,GAAG,IAAI,GAAG,EAAoB;AACpC,QAAA,IAAA,CAAA,aAAa,GAAG,IAAI,GAAG,EAAU;AACnC,QAAA,IAAA,CAAA,YAAY,GAAG,IAAI,eAAe,CAAU,KAAK,CAAC;AAE1D;;AAEG;AACI,QAAA,IAAA,CAAA,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE;IA6SvD;AAxRE;;AAEG;AACI,IAAA,QAAQ,CACb,MAAS,EACT,UAAkB,EAClB,QAAgB,EAChB,WAAqB,EAAA;AAErB,QAAA,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,IAAI,CACpE,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CACpD;IACH;AAEA;;;AAGG;IACK,iBAAiB,CACvB,IAAwB,EACxB,MAAS,EAAA;QAET,IAAI,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;;QAG3B,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;;;AAIhE,QAAA,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE/C,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,SAAS,KAAI;YACvC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CACrC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,mBAAmB,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS,CACnE;AAED,YAAA,IAAI,YAAY,EAAE,YAAY,EAAE;AAC9B,gBAAA,MAAM,WAAW,GAAG,YAAY,CAAC,YAAY;;AAG7C,gBAAA,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;AACrB,oBAAA,IACE,IAAI,CAAC,QAAQ,KAAK,WAAW,CAAC,QAAQ;AACtC,wBAAA,IAAI,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC;AACxB,wBAAA,IAAI,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,EACtB;;AAEA,wBAAA,MAAM,iBAAiB,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;wBACxD,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,iBAAiB,GAAG,CAAC,CAAC;oBAClD;AACF,gBAAA,CAAC,CAAC;YACJ;AACF,QAAA,CAAC,CAAC;;QAGF,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAI;AACzB,YAAA,IAAI,MAAM,GAAG,EAAE,GAAG,IAAI,EAAE;;AAGxB,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;AACxC,YAAA,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;gBAC/C,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,EAAE;YACpC;;YAGA,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7C,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,CAAC,EAAE;gBAClD,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,WAAW;YACnC;AAEA,YAAA,OAAO,MAAM;AACf,QAAA,CAAC,CAAC;;AAGF,QAAA,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ;QACpC,MAAM,mBAAmB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CACjE,CAAC,IAAI,KACH,IAAI,CAAC,EAAE,GAAG,CAAC;YACX,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;AAChC,YAAA,IAAI,CAAC,QAAQ,KAAK,YAAY;YAC9B,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC;AAChC,YAAA,IAAI,CAAC,KAAK,KAAK,SAAS;YACxB,IAAI,CAAC,CAAC,KAAK,SAAS;AACpB,YAAA,IAAI,CAAC,CAAC,KAAK,SAAS,CACvB;AAED,QAAA,KAAK,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC;;AAGlC,QAAA,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;;QAG/B,IAAI,eAAe,GAAG,CAAC;;QAGvB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,SAAS,KAAI;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAC/B,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,mBAAmB,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS,CACnE;YACD,IAAI,MAAM,EAAE,YAAY,EAAE,QAAQ,KAAK,YAAY,EAAE;AACnD,gBAAA,eAAe,EAAE;YACnB;AACF,QAAA,CAAC,CAAC;;AAGF,QAAA,eAAe,IAAI,mBAAmB,CAAC,MAAM;AAE7C,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,eAAe,CAAC;AAC/D,QAAA,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QAE1E,OAAO;AACL,YAAA,GAAG,IAAI;AACP,YAAA,KAAK,EAAE,KAAK;AACZ,YAAA,KAAK,EAAE,aAAa;AACpB,YAAA,SAAS,EAAE,iBAAiB;SAC7B;IACH;AAEA;;AAEG;IACK,aAAa,CAAC,IAAc,EAAE,MAAS,EAAA;AAC7C,QAAA,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,EAAE;AACtE,YAAA,OAAO,KAAK;QACd;QACA,IACE,MAAM,CAAC,IAAI;AACX,YAAA,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;AACtB,aAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAC9C;AACA,YAAA,OAAO,KAAK;QACd;AACA,QAAA,OAAO,IAAI;IACb;AAEA;;AAEG;AACI,IAAA,OAAO,CACZ,IAA0B,EAC1B,QAAiB,EACjB,QAAiB,EAAA;AAEjB,QAAA,MAAM,OAAO,GAAa;AACxB,YAAA,GAAG,IAAI;AACP,YAAA,EAAE,EAAE,IAAI,CAAC,WAAW,EAAE;YACtB,QAAQ;SACT;QAED,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC;AACpC,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,IAAI,EAAE,mBAAmB,CAAC,GAAG;YAC7B,EAAE,EAAE,OAAO,CAAC,EAAE;AACd,YAAA,IAAI,EAAE,OAAO;YACb,QAAQ;YACR,QAAQ;AACT,SAAA,CAAC;QAEF,IAAI,CAAC,gBAAgB,EAAE;AACvB,QAAA,OAAO,OAAO;IAChB;AAEA;;AAEG;AACI,IAAA,UAAU,CAAC,EAAU,EAAA;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AAChC,QAAA,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;AACvC,YAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1B,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,mBAAmB,CAAC,MAAM;gBAChC,EAAE;AACF,gBAAA,YAAY,EAAE,IAAI;AACnB,aAAA,CAAC;YACF,IAAI,CAAC,gBAAgB,EAAE;QACzB;IACF;AAEA;;;;;AAKG;IACI,UAAU,CAAC,EAAU,EAAE,OAA0B,EAAA;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAEpC,IAAI,CAAC,QAAQ,EAAE;;AAEb,YAAA,MAAM,cAAc,GAClB,OAAO,CAAC,KAAK,KAAK,SAAS;gBAC3B,OAAO,CAAC,CAAC,KAAK,SAAS;AACvB,gBAAA,OAAO,CAAC,CAAC,KAAK,SAAS;YAEzB,IAAI,cAAc,EAAE;;gBAElB,MAAM,YAAY,GAAG,EAAE,GAAG,OAAO,EAAE,EAAE,EAAc;gBACnD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,YAAY,CAAC;;YAEnC;;YAEA;QACF;QAEA,MAAM,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,EAAc;QAE3D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC;AAC5B,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,IAAI,EAAE,mBAAmB,CAAC,MAAM;YAChC,EAAE;AACF,YAAA,IAAI,EAAE,OAAO;AACb,YAAA,YAAY,EAAE,QAAQ;AACvB,SAAA,CAAC;QAEF,IAAI,CAAC,gBAAgB,EAAE;IACzB;AAEA;;AAEG;IACI,WAAW,GAAA;QAChB,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;AAC9B,YAAA,OAAO,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC;QACtB;AAEA,QAAA,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CACjD,GAAG,CAAC,CAAC,KAAK,KAAI;;YAEZ,KAAK,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,MAAM,KAAI;gBACpC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;gBACpC,IAAI,IAAI,EAAE;AACR,oBAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;AAC1B,oBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;gBAC5D;AACF,YAAA,CAAC,CAAC;;AAGF,YAAA,IAAI,CAAC,QAAQ,GAAG,EAAE;AAClB,YAAA,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;YAC1B,IAAI,CAAC,gBAAgB,EAAE;AAEvB,YAAA,OAAO,KAAK;QACd,CAAC,CAAC,CACH;IACH;AAEA;;AAEG;IACI,UAAU,GAAA;AACf,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;IACjC;AAEA;;AAEG;IACI,YAAY,GAAA;AACjB,QAAA,IAAI,CAAC,QAAQ,GAAG,EAAE;AAClB,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACnB,QAAA,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;QAC1B,IAAI,CAAC,gBAAgB,EAAE;IACzB;AAEA;;AAEG;IACI,UAAU,GAAA;AACf,QAAA,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC3B;AAEA;;AAEG;AACI,IAAA,OAAO,CAAC,EAAU,EAAA;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAC5B;IAEU,gBAAgB,GAAA;AACxB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAClD;AACD;;AC/ZD;;AAEG;;ACFH;;AAEG;;;;"}