@mintplayer/ng-bootstrap 21.12.6 → 21.12.7
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.
|
@@ -61,6 +61,9 @@ class BsVirtualDatatableComponent extends DatatableSortBase {
|
|
|
61
61
|
const bodyTableBody = el.querySelector('cdk-virtual-scroll-viewport tbody');
|
|
62
62
|
if (!bodyTableBody)
|
|
63
63
|
return;
|
|
64
|
+
// Track the max width seen for each column so columns only grow, never
|
|
65
|
+
// shrink (prevents layout jumps as rows scroll in/out of view).
|
|
66
|
+
const maxWidths = [];
|
|
64
67
|
const syncWidths = () => {
|
|
65
68
|
const headerCells = el.querySelectorAll('bs-table thead th');
|
|
66
69
|
const allBodyRows = Array.from(bodyTableBody.querySelectorAll('tr'));
|
|
@@ -89,24 +92,46 @@ class BsVirtualDatatableComponent extends DatatableSortBase {
|
|
|
89
92
|
for (let i = 0; i < columnCount; i++) {
|
|
90
93
|
headerCells[i].style.minWidth = '';
|
|
91
94
|
}
|
|
92
|
-
//
|
|
93
|
-
|
|
95
|
+
// Temporarily force both tables to size to content only, overriding
|
|
96
|
+
// Bootstrap's width:100% which causes table-layout:auto to redistribute
|
|
97
|
+
// extra space across columns. Without this, measured widths include
|
|
98
|
+
// redistributed space that varies with each data slice.
|
|
99
|
+
const headerTable = el.querySelector('bs-table table');
|
|
100
|
+
const bodyTable = el.querySelector('cdk-virtual-scroll-viewport table');
|
|
101
|
+
headerTable?.style.setProperty('width', 'max-content', 'important');
|
|
102
|
+
bodyTable?.style.setProperty('width', 'max-content', 'important');
|
|
103
|
+
// Measure natural content widths across all visible rows
|
|
94
104
|
for (let i = 0; i < columnCount; i++) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
let colWidth = headerCells[i].offsetWidth;
|
|
106
|
+
for (const row of allBodyRows) {
|
|
107
|
+
const tds = row.cells;
|
|
108
|
+
if (i < tds.length) {
|
|
109
|
+
const w = tds[i].offsetWidth;
|
|
110
|
+
if (w > colWidth)
|
|
111
|
+
colWidth = w;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Update tracked maximum so columns only grow, never shrink
|
|
115
|
+
if (!maxWidths[i] || colWidth > maxWidths[i]) {
|
|
116
|
+
maxWidths[i] = colWidth;
|
|
103
117
|
}
|
|
104
118
|
}
|
|
105
|
-
//
|
|
119
|
+
// Remove temporary width override so tables render normally
|
|
120
|
+
headerTable?.style.removeProperty('width');
|
|
121
|
+
bodyTable?.style.removeProperty('width');
|
|
122
|
+
// Apply max widths to header and ALL body rows to keep them in sync.
|
|
123
|
+
// Setting min-width on every row prevents table-layout:auto from
|
|
124
|
+
// redistributing extra space differently across the two tables when
|
|
125
|
+
// some rows contain placeholder content.
|
|
106
126
|
for (let i = 0; i < columnCount; i++) {
|
|
107
|
-
const w = `${
|
|
127
|
+
const w = `${maxWidths[i]}px`;
|
|
108
128
|
headerCells[i].style.minWidth = w;
|
|
109
|
-
|
|
129
|
+
for (const row of allBodyRows) {
|
|
130
|
+
const tds = row.cells;
|
|
131
|
+
if (i < tds.length) {
|
|
132
|
+
tds[i].style.minWidth = w;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
110
135
|
}
|
|
111
136
|
// Restore scroll positions after min-widths are re-applied
|
|
112
137
|
if (headerScrollContainer)
|
|
@@ -128,11 +153,11 @@ class BsVirtualDatatableComponent extends DatatableSortBase {
|
|
|
128
153
|
this.cleanup.push(() => observer.disconnect());
|
|
129
154
|
}
|
|
130
155
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: BsVirtualDatatableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
131
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: BsVirtualDatatableComponent, isStandalone: true, selector: "bs-virtual-datatable", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, isResponsive: { classPropertyName: "isResponsive", publicName: "isResponsive", isSignal: true, isRequired: false, transformFunction: null }, itemSize: { classPropertyName: "itemSize", publicName: "itemSize", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div class=\"virtual-datatable-container\">\n <bs-table [isResponsive]=\"isResponsive()\" [striped]=\"true\" [hover]=\"true\">\n <thead>\n <tr>\n @for (column of columnsArray; track column) {\n <th class=\"text-nowrap\"\n [class.sort]=\"column.sortable\"\n [class.sort-asc]=\"column.sortable && getSortDirection(column.name) === 'ascending'\"\n [class.sort-desc]=\"column.sortable && getSortDirection(column.name) === 'descending'\"\n (mousedown)=\"onHeaderMouseDown($event)\"\n (click)=\"columnHeaderClicked(column, $event)\">\n <ng-container *ngTemplateOutlet=\"column.templateRef\"></ng-container>\n @if (settings().sortColumns.length > 1 && getSortIndex(column.name) >= 0) {\n <span class=\"sort-priority\">{{ getSortIndex(column.name) + 1 }}</span>\n }\n </th>\n }\n </tr>\n </thead>\n </bs-table>\n\n <bs-table-styles>\n <cdk-virtual-scroll-viewport [itemSize]=\"itemSize()\" class=\"virtual-scroll-viewport\">\n <table class=\"table table-striped table-hover\" [class.nowrap]=\"isResponsive()\">\n <tbody>\n <tr *cdkVirtualFor=\"let item of dataSource()\" class=\"virtual-row\">\n @if (item && rowTemplate) {\n <ng-container *ngTemplateOutlet=\"rowTemplate; context: { $implicit: item }\"></ng-container>\n } @else {\n @for (column of columnsArray; track column) {\n <td> </td>\n }\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n </bs-table-styles>\n</div>\n", styles: ["@charset \"UTF-8\";bs-table thead th.sort{position:relative;cursor:pointer;padding-right:2rem}bs-table thead th.sort:before,bs-table thead th.sort:after{position:absolute;display:block;opacity:.3;bottom:.5em}bs-table thead th.sort:before{content:\"\\2191\";right:1em}bs-table thead th.sort:after{content:\"\\2193\";right:.5em}bs-table thead th.sort.sort-asc:after{opacity:1}bs-table thead th.sort.sort-desc:before{opacity:1}bs-table thead th.sort .sort-priority{position:absolute;right:.1em;bottom:.3em;font-size:.65em;font-weight:700;opacity:.7}:host{display:block;height:100%}.virtual-datatable-container{display:flex;flex-direction:column;height:100%}.virtual-datatable-container bs-table{flex-shrink:0}bs-table ::ng-deep table,.virtual-scroll-viewport table{table-layout:auto}.virtual-scroll-viewport .nowrap td{white-space:nowrap}bs-table ::ng-deep .table-responsive{overflow-x:hidden;scrollbar-gutter:stable}.virtual-scroll-viewport{flex:1 1 auto;min-height:0;scrollbar-gutter:stable}.virtual-scroll-viewport table{margin-bottom:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: BsTableComponent, selector: "bs-table", inputs: ["isResponsive", "striped", "hover"] }, { kind: "component", type: BsTableStylesComponent, selector: "bs-table-styles" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
156
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: BsVirtualDatatableComponent, isStandalone: true, selector: "bs-virtual-datatable", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, isResponsive: { classPropertyName: "isResponsive", publicName: "isResponsive", isSignal: true, isRequired: false, transformFunction: null }, itemSize: { classPropertyName: "itemSize", publicName: "itemSize", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div class=\"virtual-datatable-container\">\n <bs-table [isResponsive]=\"isResponsive()\" [striped]=\"true\" [hover]=\"true\">\n <thead>\n <tr>\n @for (column of columnsArray; track column) {\n <th class=\"text-nowrap\"\n [class.sort]=\"column.sortable\"\n [class.sort-asc]=\"column.sortable && getSortDirection(column.name) === 'ascending'\"\n [class.sort-desc]=\"column.sortable && getSortDirection(column.name) === 'descending'\"\n (mousedown)=\"onHeaderMouseDown($event)\"\n (click)=\"columnHeaderClicked(column, $event)\">\n <ng-container *ngTemplateOutlet=\"column.templateRef\"></ng-container>\n @if (settings().sortColumns.length > 1 && getSortIndex(column.name) >= 0) {\n <span class=\"sort-priority\">{{ getSortIndex(column.name) + 1 }}</span>\n }\n </th>\n }\n </tr>\n </thead>\n </bs-table>\n\n <bs-table-styles>\n <cdk-virtual-scroll-viewport [itemSize]=\"itemSize()\" class=\"virtual-scroll-viewport\">\n <table class=\"table table-striped table-hover\" [class.nowrap]=\"isResponsive()\">\n <tbody>\n <tr *cdkVirtualFor=\"let item of dataSource()\" class=\"virtual-row\">\n @if (item && rowTemplate) {\n <ng-container *ngTemplateOutlet=\"rowTemplate; context: { $implicit: item }\"></ng-container>\n } @else {\n @for (column of columnsArray; track column) {\n <td> </td>\n }\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n </bs-table-styles>\n</div>\n", styles: ["@charset \"UTF-8\";bs-table thead th.sort{position:relative;cursor:pointer;padding-right:2rem}bs-table thead th.sort:before,bs-table thead th.sort:after{position:absolute;display:block;opacity:.3;bottom:.5em}bs-table thead th.sort:before{content:\"\\2191\";right:1em}bs-table thead th.sort:after{content:\"\\2193\";right:.5em}bs-table thead th.sort.sort-asc:after{opacity:1}bs-table thead th.sort.sort-desc:before{opacity:1}bs-table thead th.sort .sort-priority{position:absolute;right:.1em;bottom:.3em;font-size:.65em;font-weight:700;opacity:.7}:host{display:block;height:100%}.virtual-datatable-container{display:flex;flex-direction:column;height:100%}.virtual-datatable-container bs-table{flex-shrink:0}bs-table ::ng-deep table,.virtual-scroll-viewport table{table-layout:auto;width:max-content}.virtual-scroll-viewport .nowrap td{white-space:nowrap}bs-table ::ng-deep .table-responsive{overflow-x:hidden;scrollbar-gutter:stable}.virtual-scroll-viewport{flex:1 1 auto;min-height:0;scrollbar-gutter:stable}.virtual-scroll-viewport table{margin-bottom:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: BsTableComponent, selector: "bs-table", inputs: ["isResponsive", "striped", "hover"] }, { kind: "component", type: BsTableStylesComponent, selector: "bs-table-styles" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
132
157
|
}
|
|
133
158
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: BsVirtualDatatableComponent, decorators: [{
|
|
134
159
|
type: Component,
|
|
135
|
-
args: [{ selector: 'bs-virtual-datatable', imports: [NgTemplateOutlet, ScrollingModule, BsTableComponent, BsTableStylesComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"virtual-datatable-container\">\n <bs-table [isResponsive]=\"isResponsive()\" [striped]=\"true\" [hover]=\"true\">\n <thead>\n <tr>\n @for (column of columnsArray; track column) {\n <th class=\"text-nowrap\"\n [class.sort]=\"column.sortable\"\n [class.sort-asc]=\"column.sortable && getSortDirection(column.name) === 'ascending'\"\n [class.sort-desc]=\"column.sortable && getSortDirection(column.name) === 'descending'\"\n (mousedown)=\"onHeaderMouseDown($event)\"\n (click)=\"columnHeaderClicked(column, $event)\">\n <ng-container *ngTemplateOutlet=\"column.templateRef\"></ng-container>\n @if (settings().sortColumns.length > 1 && getSortIndex(column.name) >= 0) {\n <span class=\"sort-priority\">{{ getSortIndex(column.name) + 1 }}</span>\n }\n </th>\n }\n </tr>\n </thead>\n </bs-table>\n\n <bs-table-styles>\n <cdk-virtual-scroll-viewport [itemSize]=\"itemSize()\" class=\"virtual-scroll-viewport\">\n <table class=\"table table-striped table-hover\" [class.nowrap]=\"isResponsive()\">\n <tbody>\n <tr *cdkVirtualFor=\"let item of dataSource()\" class=\"virtual-row\">\n @if (item && rowTemplate) {\n <ng-container *ngTemplateOutlet=\"rowTemplate; context: { $implicit: item }\"></ng-container>\n } @else {\n @for (column of columnsArray; track column) {\n <td> </td>\n }\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n </bs-table-styles>\n</div>\n", styles: ["@charset \"UTF-8\";bs-table thead th.sort{position:relative;cursor:pointer;padding-right:2rem}bs-table thead th.sort:before,bs-table thead th.sort:after{position:absolute;display:block;opacity:.3;bottom:.5em}bs-table thead th.sort:before{content:\"\\2191\";right:1em}bs-table thead th.sort:after{content:\"\\2193\";right:.5em}bs-table thead th.sort.sort-asc:after{opacity:1}bs-table thead th.sort.sort-desc:before{opacity:1}bs-table thead th.sort .sort-priority{position:absolute;right:.1em;bottom:.3em;font-size:.65em;font-weight:700;opacity:.7}:host{display:block;height:100%}.virtual-datatable-container{display:flex;flex-direction:column;height:100%}.virtual-datatable-container bs-table{flex-shrink:0}bs-table ::ng-deep table,.virtual-scroll-viewport table{table-layout:auto}.virtual-scroll-viewport .nowrap td{white-space:nowrap}bs-table ::ng-deep .table-responsive{overflow-x:hidden;scrollbar-gutter:stable}.virtual-scroll-viewport{flex:1 1 auto;min-height:0;scrollbar-gutter:stable}.virtual-scroll-viewport table{margin-bottom:0}\n"] }]
|
|
160
|
+
args: [{ selector: 'bs-virtual-datatable', imports: [NgTemplateOutlet, ScrollingModule, BsTableComponent, BsTableStylesComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"virtual-datatable-container\">\n <bs-table [isResponsive]=\"isResponsive()\" [striped]=\"true\" [hover]=\"true\">\n <thead>\n <tr>\n @for (column of columnsArray; track column) {\n <th class=\"text-nowrap\"\n [class.sort]=\"column.sortable\"\n [class.sort-asc]=\"column.sortable && getSortDirection(column.name) === 'ascending'\"\n [class.sort-desc]=\"column.sortable && getSortDirection(column.name) === 'descending'\"\n (mousedown)=\"onHeaderMouseDown($event)\"\n (click)=\"columnHeaderClicked(column, $event)\">\n <ng-container *ngTemplateOutlet=\"column.templateRef\"></ng-container>\n @if (settings().sortColumns.length > 1 && getSortIndex(column.name) >= 0) {\n <span class=\"sort-priority\">{{ getSortIndex(column.name) + 1 }}</span>\n }\n </th>\n }\n </tr>\n </thead>\n </bs-table>\n\n <bs-table-styles>\n <cdk-virtual-scroll-viewport [itemSize]=\"itemSize()\" class=\"virtual-scroll-viewport\">\n <table class=\"table table-striped table-hover\" [class.nowrap]=\"isResponsive()\">\n <tbody>\n <tr *cdkVirtualFor=\"let item of dataSource()\" class=\"virtual-row\">\n @if (item && rowTemplate) {\n <ng-container *ngTemplateOutlet=\"rowTemplate; context: { $implicit: item }\"></ng-container>\n } @else {\n @for (column of columnsArray; track column) {\n <td> </td>\n }\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n </bs-table-styles>\n</div>\n", styles: ["@charset \"UTF-8\";bs-table thead th.sort{position:relative;cursor:pointer;padding-right:2rem}bs-table thead th.sort:before,bs-table thead th.sort:after{position:absolute;display:block;opacity:.3;bottom:.5em}bs-table thead th.sort:before{content:\"\\2191\";right:1em}bs-table thead th.sort:after{content:\"\\2193\";right:.5em}bs-table thead th.sort.sort-asc:after{opacity:1}bs-table thead th.sort.sort-desc:before{opacity:1}bs-table thead th.sort .sort-priority{position:absolute;right:.1em;bottom:.3em;font-size:.65em;font-weight:700;opacity:.7}:host{display:block;height:100%}.virtual-datatable-container{display:flex;flex-direction:column;height:100%}.virtual-datatable-container bs-table{flex-shrink:0}bs-table ::ng-deep table,.virtual-scroll-viewport table{table-layout:auto;width:max-content}.virtual-scroll-viewport .nowrap td{white-space:nowrap}bs-table ::ng-deep .table-responsive{overflow-x:hidden;scrollbar-gutter:stable}.virtual-scroll-viewport{flex:1 1 auto;min-height:0;scrollbar-gutter:stable}.virtual-scroll-viewport table{margin-bottom:0}\n"] }]
|
|
136
161
|
}], propDecorators: { dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: true }] }], isResponsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "isResponsive", required: false }] }], itemSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemSize", required: false }] }] } });
|
|
137
162
|
|
|
138
163
|
class VirtualDatatableDataSource extends DataSource {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mintplayer-ng-bootstrap-virtual-datatable.mjs","sources":["../../../../libs/mintplayer-ng-bootstrap/virtual-datatable/src/virtual-datatable/virtual-datatable.component.ts","../../../../libs/mintplayer-ng-bootstrap/virtual-datatable/src/virtual-datatable/virtual-datatable.component.html","../../../../libs/mintplayer-ng-bootstrap/virtual-datatable/src/virtual-datatable-data-source.ts","../../../../libs/mintplayer-ng-bootstrap/virtual-datatable/src/virtual-row-template/virtual-row-template.directive.ts","../../../../libs/mintplayer-ng-bootstrap/virtual-datatable/mintplayer-ng-bootstrap-virtual-datatable.ts"],"sourcesContent":["import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, inject, input, NgZone, OnDestroy, TemplateRef } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ScrollingModule } from '@angular/cdk/scrolling';\nimport { BsTableComponent, BsTableStylesComponent } from '@mintplayer/ng-bootstrap/table';\nimport { DatatableSortBase } from '@mintplayer/ng-bootstrap/datatable';\nimport { VirtualDatatableDataSource } from '../virtual-datatable-data-source';\nimport { BsVirtualRowTemplateContext } from '../virtual-row-template/virtual-row-template.directive';\n\n@Component({\n selector: 'bs-virtual-datatable',\n templateUrl: './virtual-datatable.component.html',\n styleUrls: ['./virtual-datatable.component.scss'],\n imports: [NgTemplateOutlet, ScrollingModule, BsTableComponent, BsTableStylesComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class BsVirtualDatatableComponent<TData> extends DatatableSortBase implements AfterViewInit, OnDestroy {\n\n private readonly elementRef = inject(ElementRef);\n private readonly ngZone = inject(NgZone);\n private cleanup: (() => void)[] = [];\n\n dataSource = input.required<VirtualDatatableDataSource<TData>>();\n isResponsive = input(false);\n itemSize = input(48);\n\n rowTemplate?: TemplateRef<BsVirtualRowTemplateContext<TData>>;\n\n ngAfterViewInit() {\n this.setupScrollSync();\n this.setupColumnWidthSync();\n }\n\n ngOnDestroy() {\n this.cleanup.forEach(fn => fn());\n }\n\n private setupScrollSync() {\n const el = this.elementRef.nativeElement as HTMLElement;\n const headerScrollContainer = el.querySelector('.table-responsive') as HTMLElement;\n const viewport = el.querySelector('cdk-virtual-scroll-viewport') as HTMLElement;\n\n if (!headerScrollContainer || !viewport) return;\n\n let syncing = false;\n\n const onHeaderScroll = () => {\n if (syncing) return;\n syncing = true;\n viewport.scrollLeft = headerScrollContainer.scrollLeft;\n syncing = false;\n };\n\n const onViewportScroll = () => {\n if (syncing) return;\n syncing = true;\n headerScrollContainer.scrollLeft = viewport.scrollLeft;\n syncing = false;\n };\n\n this.ngZone.runOutsideAngular(() => {\n headerScrollContainer.addEventListener('scroll', onHeaderScroll, { passive: true });\n viewport.addEventListener('scroll', onViewportScroll, { passive: true });\n });\n\n this.cleanup.push(() => {\n headerScrollContainer.removeEventListener('scroll', onHeaderScroll);\n viewport.removeEventListener('scroll', onViewportScroll);\n });\n }\n\n private setupColumnWidthSync() {\n const el = this.elementRef.nativeElement as HTMLElement;\n const bodyTableBody = el.querySelector('cdk-virtual-scroll-viewport tbody') as HTMLElement;\n\n if (!bodyTableBody) return;\n\n const syncWidths = () => {\n const headerCells = el.querySelectorAll<HTMLElement>('bs-table thead th');\n const allBodyRows = Array.from(bodyTableBody.querySelectorAll<HTMLTableRowElement>('tr'));\n const firstBodyRow = allBodyRows[0];\n const bodyCells = firstBodyRow?.cells;\n\n if (!headerCells.length || !bodyCells?.length) return;\n\n const columnCount = Math.min(headerCells.length, bodyCells.length);\n\n // Save scroll positions before measurement (clearing min-width can shrink\n // the table and cause the browser to clamp scrollLeft to 0).\n const headerScrollContainer = el.querySelector('.table-responsive') as HTMLElement;\n const viewport = el.querySelector('cdk-virtual-scroll-viewport') as HTMLElement;\n const savedHeaderScroll = headerScrollContainer?.scrollLeft ?? 0;\n const savedViewportScroll = viewport?.scrollLeft ?? 0;\n\n // Clear inline min-widths on ALL body rows. CDK virtual scroll recycles\n // <tr> DOM elements, so rows that were previously the \"first row\" retain\n // stale min-width styles. With table-layout: auto the column width is\n // determined by the widest cell across all visible rows, so stale\n // min-widths on any row prevent columns from ever shrinking.\n for (const row of allBodyRows) {\n const tds = row.cells;\n for (let i = 0; i < Math.min(tds.length, columnCount); i++) {\n tds[i].style.minWidth = '';\n }\n }\n for (let i = 0; i < columnCount; i++) {\n headerCells[i].style.minWidth = '';\n }\n\n // Measure natural widths across all visible rows\n const widths: number[] = [];\n for (let i = 0; i < columnCount; i++) {\n widths[i] = headerCells[i].offsetWidth;\n }\n for (const row of allBodyRows) {\n const tds = row.cells;\n for (let i = 0; i < Math.min(tds.length, columnCount); i++) {\n const w = tds[i].offsetWidth;\n if (w > widths[i]) widths[i] = w;\n }\n }\n\n // Apply measured widths to header and first body row to keep them in sync\n for (let i = 0; i < columnCount; i++) {\n const w = `${widths[i]}px`;\n headerCells[i].style.minWidth = w;\n bodyCells[i].style.minWidth = w;\n }\n\n // Restore scroll positions after min-widths are re-applied\n if (headerScrollContainer) headerScrollContainer.scrollLeft = savedHeaderScroll;\n if (viewport) viewport.scrollLeft = savedViewportScroll;\n };\n\n // Sync after first render\n this.ngZone.runOutsideAngular(() => {\n requestAnimationFrame(() => syncWidths());\n });\n\n // Re-sync when body rows change (virtual scroll swaps rows)\n const observer = new MutationObserver(() => {\n requestAnimationFrame(() => syncWidths());\n });\n\n this.ngZone.runOutsideAngular(() => {\n observer.observe(bodyTableBody, { childList: true, subtree: true });\n });\n\n this.cleanup.push(() => observer.disconnect());\n }\n}\n","<div class=\"virtual-datatable-container\">\n <bs-table [isResponsive]=\"isResponsive()\" [striped]=\"true\" [hover]=\"true\">\n <thead>\n <tr>\n @for (column of columnsArray; track column) {\n <th class=\"text-nowrap\"\n [class.sort]=\"column.sortable\"\n [class.sort-asc]=\"column.sortable && getSortDirection(column.name) === 'ascending'\"\n [class.sort-desc]=\"column.sortable && getSortDirection(column.name) === 'descending'\"\n (mousedown)=\"onHeaderMouseDown($event)\"\n (click)=\"columnHeaderClicked(column, $event)\">\n <ng-container *ngTemplateOutlet=\"column.templateRef\"></ng-container>\n @if (settings().sortColumns.length > 1 && getSortIndex(column.name) >= 0) {\n <span class=\"sort-priority\">{{ getSortIndex(column.name) + 1 }}</span>\n }\n </th>\n }\n </tr>\n </thead>\n </bs-table>\n\n <bs-table-styles>\n <cdk-virtual-scroll-viewport [itemSize]=\"itemSize()\" class=\"virtual-scroll-viewport\">\n <table class=\"table table-striped table-hover\" [class.nowrap]=\"isResponsive()\">\n <tbody>\n <tr *cdkVirtualFor=\"let item of dataSource()\" class=\"virtual-row\">\n @if (item && rowTemplate) {\n <ng-container *ngTemplateOutlet=\"rowTemplate; context: { $implicit: item }\"></ng-container>\n } @else {\n @for (column of columnsArray; track column) {\n <td> </td>\n }\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n </bs-table-styles>\n</div>\n","import { CollectionViewer, DataSource } from '@angular/cdk/collections';\nimport { BehaviorSubject, Observable, Subject, Subscription, from, merge, of } from 'rxjs';\nimport { catchError, distinctUntilChanged, filter, map, startWith, switchMap } from 'rxjs/operators';\n\nexport class VirtualDatatableDataSource<T> extends DataSource<T> {\n private readonly fetchFn: (skip: number, take: number) => Promise<{ data: T[]; totalRecords: number }>;\n private readonly pageSize: number;\n private readonly cachedPages = new Map<number, T[]>();\n private totalRecords = 0;\n private dataStream = new BehaviorSubject<T[]>([]);\n private subscription?: Subscription;\n private resetSubject = new Subject<void>();\n private resetVersion = 0;\n\n constructor(\n fetchFn: (skip: number, take: number) => Promise<{ data: T[]; totalRecords: number }>,\n pageSize = 50\n ) {\n super();\n this.fetchFn = fetchFn;\n this.pageSize = pageSize;\n }\n\n connect(collectionViewer: CollectionViewer): Observable<T[]> {\n // Support reconnection after disconnect (which completes the previous dataStream)\n this.dataStream = new BehaviorSubject<T[]>([]);\n this.cachedPages.clear();\n this.totalRecords = 0;\n\n // Track the last viewport range so reset() can re-trigger a fetch.\n // resetVersion is incremented on reset() to bypass distinctUntilChanged.\n let lastRange = { start: 0, end: this.pageSize };\n this.subscription = merge(\n collectionViewer.viewChange.pipe(startWith(lastRange)),\n this.resetSubject.pipe(map(() => lastRange))\n ).pipe(\n filter(range => range.end > range.start),\n map(range => { lastRange = range; return { pages: this.getPageIndices(range), version: this.resetVersion }; }),\n distinctUntilChanged((a, b) => a.version === b.version && a.pages.join() === b.pages.join()),\n switchMap(({ pages }) => from(this.fetchPages(pages)).pipe(\n catchError(() => of(this.dataStream.value))\n ))\n ).subscribe(data => this.dataStream.next(data));\n\n return this.dataStream;\n }\n\n disconnect(): void {\n this.subscription?.unsubscribe();\n this.dataStream.complete();\n }\n\n get length(): number {\n return this.totalRecords;\n }\n\n reset(): void {\n this.cachedPages.clear();\n this.resetVersion++;\n this.resetSubject.next();\n }\n\n private getPageIndices(range: { start: number; end: number }): number[] {\n const startPage = Math.floor(range.start / this.pageSize);\n const endPage = Math.floor((range.end - 1) / this.pageSize);\n const pages: number[] = [];\n for (let i = startPage; i <= endPage; i++) {\n pages.push(i);\n }\n return pages;\n }\n\n private async fetchPages(pageIndices: number[]): Promise<T[]> {\n const uncachedPages = pageIndices.filter(p => !this.cachedPages.has(p));\n\n const results = await Promise.all(\n uncachedPages.map(async pageIndex => {\n const skip = pageIndex * this.pageSize;\n const result = await this.fetchFn(skip, this.pageSize);\n return { pageIndex, result };\n })\n );\n\n for (const { pageIndex, result } of results) {\n this.cachedPages.set(pageIndex, result.data);\n }\n if (results.length > 0) {\n this.totalRecords = results[0].result.totalRecords;\n }\n\n // Build the full data array with placeholders for unloaded pages\n const totalPages = Math.ceil(this.totalRecords / this.pageSize);\n const data: T[] = [];\n for (let i = 0; i < totalPages; i++) {\n const page = this.cachedPages.get(i);\n if (page) {\n data.push(...page);\n } else {\n // Fill with empty slots to maintain correct virtual scroll positioning\n const remaining = Math.min(this.pageSize, this.totalRecords - i * this.pageSize);\n data.push(...new Array<T>(remaining));\n }\n }\n return data;\n }\n}\n","import { Directive, inject, TemplateRef } from '@angular/core';\nimport { BsVirtualDatatableComponent } from '../virtual-datatable/virtual-datatable.component';\n\n@Directive({\n selector: '[bsVirtualRowTemplate]',\n})\nexport class BsVirtualRowTemplateDirective<TData> {\n\n private datatableComponent = inject<BsVirtualDatatableComponent<TData>>(BsVirtualDatatableComponent);\n private templateRef = inject<TemplateRef<BsVirtualRowTemplateContext<TData>>>(TemplateRef);\n\n constructor() {\n this.datatableComponent.rowTemplate = this.templateRef;\n }\n\n public static ngTemplateContextGuard<TData>(\n dir: BsVirtualRowTemplateDirective<TData>,\n ctx: any\n ): ctx is BsVirtualRowTemplateContext<Exclude<TData, false | 0 | '' | null | undefined>> {\n return true;\n }\n}\n\nexport class BsVirtualRowTemplateContext<TData = unknown> {\n public $implicit: TData = null!;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mintplayer-ng-bootstrap-virtual-datatable.mjs","sources":["../../../../libs/mintplayer-ng-bootstrap/virtual-datatable/src/virtual-datatable/virtual-datatable.component.ts","../../../../libs/mintplayer-ng-bootstrap/virtual-datatable/src/virtual-datatable/virtual-datatable.component.html","../../../../libs/mintplayer-ng-bootstrap/virtual-datatable/src/virtual-datatable-data-source.ts","../../../../libs/mintplayer-ng-bootstrap/virtual-datatable/src/virtual-row-template/virtual-row-template.directive.ts","../../../../libs/mintplayer-ng-bootstrap/virtual-datatable/mintplayer-ng-bootstrap-virtual-datatable.ts"],"sourcesContent":["import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, inject, input, NgZone, OnDestroy, TemplateRef } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ScrollingModule } from '@angular/cdk/scrolling';\nimport { BsTableComponent, BsTableStylesComponent } from '@mintplayer/ng-bootstrap/table';\nimport { DatatableSortBase } from '@mintplayer/ng-bootstrap/datatable';\nimport { VirtualDatatableDataSource } from '../virtual-datatable-data-source';\nimport { BsVirtualRowTemplateContext } from '../virtual-row-template/virtual-row-template.directive';\n\n@Component({\n selector: 'bs-virtual-datatable',\n templateUrl: './virtual-datatable.component.html',\n styleUrls: ['./virtual-datatable.component.scss'],\n imports: [NgTemplateOutlet, ScrollingModule, BsTableComponent, BsTableStylesComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class BsVirtualDatatableComponent<TData> extends DatatableSortBase implements AfterViewInit, OnDestroy {\n\n private readonly elementRef = inject(ElementRef);\n private readonly ngZone = inject(NgZone);\n private cleanup: (() => void)[] = [];\n\n dataSource = input.required<VirtualDatatableDataSource<TData>>();\n isResponsive = input(false);\n itemSize = input(48);\n\n rowTemplate?: TemplateRef<BsVirtualRowTemplateContext<TData>>;\n\n ngAfterViewInit() {\n this.setupScrollSync();\n this.setupColumnWidthSync();\n }\n\n ngOnDestroy() {\n this.cleanup.forEach(fn => fn());\n }\n\n private setupScrollSync() {\n const el = this.elementRef.nativeElement as HTMLElement;\n const headerScrollContainer = el.querySelector('.table-responsive') as HTMLElement;\n const viewport = el.querySelector('cdk-virtual-scroll-viewport') as HTMLElement;\n\n if (!headerScrollContainer || !viewport) return;\n\n let syncing = false;\n\n const onHeaderScroll = () => {\n if (syncing) return;\n syncing = true;\n viewport.scrollLeft = headerScrollContainer.scrollLeft;\n syncing = false;\n };\n\n const onViewportScroll = () => {\n if (syncing) return;\n syncing = true;\n headerScrollContainer.scrollLeft = viewport.scrollLeft;\n syncing = false;\n };\n\n this.ngZone.runOutsideAngular(() => {\n headerScrollContainer.addEventListener('scroll', onHeaderScroll, { passive: true });\n viewport.addEventListener('scroll', onViewportScroll, { passive: true });\n });\n\n this.cleanup.push(() => {\n headerScrollContainer.removeEventListener('scroll', onHeaderScroll);\n viewport.removeEventListener('scroll', onViewportScroll);\n });\n }\n\n private setupColumnWidthSync() {\n const el = this.elementRef.nativeElement as HTMLElement;\n const bodyTableBody = el.querySelector('cdk-virtual-scroll-viewport tbody') as HTMLElement;\n\n if (!bodyTableBody) return;\n\n // Track the max width seen for each column so columns only grow, never\n // shrink (prevents layout jumps as rows scroll in/out of view).\n const maxWidths: number[] = [];\n\n const syncWidths = () => {\n const headerCells = el.querySelectorAll<HTMLElement>('bs-table thead th');\n const allBodyRows = Array.from(bodyTableBody.querySelectorAll<HTMLTableRowElement>('tr'));\n const firstBodyRow = allBodyRows[0];\n const bodyCells = firstBodyRow?.cells;\n\n if (!headerCells.length || !bodyCells?.length) return;\n\n const columnCount = Math.min(headerCells.length, bodyCells.length);\n\n // Save scroll positions before measurement (clearing min-width can shrink\n // the table and cause the browser to clamp scrollLeft to 0).\n const headerScrollContainer = el.querySelector('.table-responsive') as HTMLElement;\n const viewport = el.querySelector('cdk-virtual-scroll-viewport') as HTMLElement;\n const savedHeaderScroll = headerScrollContainer?.scrollLeft ?? 0;\n const savedViewportScroll = viewport?.scrollLeft ?? 0;\n\n // Clear inline min-widths on ALL body rows. CDK virtual scroll recycles\n // <tr> DOM elements, so rows that were previously the \"first row\" retain\n // stale min-width styles. With table-layout: auto the column width is\n // determined by the widest cell across all visible rows, so stale\n // min-widths on any row prevent columns from ever shrinking.\n for (const row of allBodyRows) {\n const tds = row.cells;\n for (let i = 0; i < Math.min(tds.length, columnCount); i++) {\n tds[i].style.minWidth = '';\n }\n }\n for (let i = 0; i < columnCount; i++) {\n headerCells[i].style.minWidth = '';\n }\n\n // Temporarily force both tables to size to content only, overriding\n // Bootstrap's width:100% which causes table-layout:auto to redistribute\n // extra space across columns. Without this, measured widths include\n // redistributed space that varies with each data slice.\n const headerTable = el.querySelector<HTMLElement>('bs-table table');\n const bodyTable = el.querySelector<HTMLElement>('cdk-virtual-scroll-viewport table');\n headerTable?.style.setProperty('width', 'max-content', 'important');\n bodyTable?.style.setProperty('width', 'max-content', 'important');\n\n // Measure natural content widths across all visible rows\n for (let i = 0; i < columnCount; i++) {\n let colWidth = headerCells[i].offsetWidth;\n for (const row of allBodyRows) {\n const tds = row.cells;\n if (i < tds.length) {\n const w = tds[i].offsetWidth;\n if (w > colWidth) colWidth = w;\n }\n }\n // Update tracked maximum so columns only grow, never shrink\n if (!maxWidths[i] || colWidth > maxWidths[i]) {\n maxWidths[i] = colWidth;\n }\n }\n\n // Remove temporary width override so tables render normally\n headerTable?.style.removeProperty('width');\n bodyTable?.style.removeProperty('width');\n\n // Apply max widths to header and ALL body rows to keep them in sync.\n // Setting min-width on every row prevents table-layout:auto from\n // redistributing extra space differently across the two tables when\n // some rows contain placeholder content.\n for (let i = 0; i < columnCount; i++) {\n const w = `${maxWidths[i]}px`;\n headerCells[i].style.minWidth = w;\n for (const row of allBodyRows) {\n const tds = row.cells;\n if (i < tds.length) {\n tds[i].style.minWidth = w;\n }\n }\n }\n\n // Restore scroll positions after min-widths are re-applied\n if (headerScrollContainer) headerScrollContainer.scrollLeft = savedHeaderScroll;\n if (viewport) viewport.scrollLeft = savedViewportScroll;\n };\n\n // Sync after first render\n this.ngZone.runOutsideAngular(() => {\n requestAnimationFrame(() => syncWidths());\n });\n\n // Re-sync when body rows change (virtual scroll swaps rows)\n const observer = new MutationObserver(() => {\n requestAnimationFrame(() => syncWidths());\n });\n\n this.ngZone.runOutsideAngular(() => {\n observer.observe(bodyTableBody, { childList: true, subtree: true });\n });\n\n this.cleanup.push(() => observer.disconnect());\n }\n}\n","<div class=\"virtual-datatable-container\">\n <bs-table [isResponsive]=\"isResponsive()\" [striped]=\"true\" [hover]=\"true\">\n <thead>\n <tr>\n @for (column of columnsArray; track column) {\n <th class=\"text-nowrap\"\n [class.sort]=\"column.sortable\"\n [class.sort-asc]=\"column.sortable && getSortDirection(column.name) === 'ascending'\"\n [class.sort-desc]=\"column.sortable && getSortDirection(column.name) === 'descending'\"\n (mousedown)=\"onHeaderMouseDown($event)\"\n (click)=\"columnHeaderClicked(column, $event)\">\n <ng-container *ngTemplateOutlet=\"column.templateRef\"></ng-container>\n @if (settings().sortColumns.length > 1 && getSortIndex(column.name) >= 0) {\n <span class=\"sort-priority\">{{ getSortIndex(column.name) + 1 }}</span>\n }\n </th>\n }\n </tr>\n </thead>\n </bs-table>\n\n <bs-table-styles>\n <cdk-virtual-scroll-viewport [itemSize]=\"itemSize()\" class=\"virtual-scroll-viewport\">\n <table class=\"table table-striped table-hover\" [class.nowrap]=\"isResponsive()\">\n <tbody>\n <tr *cdkVirtualFor=\"let item of dataSource()\" class=\"virtual-row\">\n @if (item && rowTemplate) {\n <ng-container *ngTemplateOutlet=\"rowTemplate; context: { $implicit: item }\"></ng-container>\n } @else {\n @for (column of columnsArray; track column) {\n <td> </td>\n }\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n </bs-table-styles>\n</div>\n","import { CollectionViewer, DataSource } from '@angular/cdk/collections';\nimport { BehaviorSubject, Observable, Subject, Subscription, from, merge, of } from 'rxjs';\nimport { catchError, distinctUntilChanged, filter, map, startWith, switchMap } from 'rxjs/operators';\n\nexport class VirtualDatatableDataSource<T> extends DataSource<T> {\n private readonly fetchFn: (skip: number, take: number) => Promise<{ data: T[]; totalRecords: number }>;\n private readonly pageSize: number;\n private readonly cachedPages = new Map<number, T[]>();\n private totalRecords = 0;\n private dataStream = new BehaviorSubject<T[]>([]);\n private subscription?: Subscription;\n private resetSubject = new Subject<void>();\n private resetVersion = 0;\n\n constructor(\n fetchFn: (skip: number, take: number) => Promise<{ data: T[]; totalRecords: number }>,\n pageSize = 50\n ) {\n super();\n this.fetchFn = fetchFn;\n this.pageSize = pageSize;\n }\n\n connect(collectionViewer: CollectionViewer): Observable<T[]> {\n // Support reconnection after disconnect (which completes the previous dataStream)\n this.dataStream = new BehaviorSubject<T[]>([]);\n this.cachedPages.clear();\n this.totalRecords = 0;\n\n // Track the last viewport range so reset() can re-trigger a fetch.\n // resetVersion is incremented on reset() to bypass distinctUntilChanged.\n let lastRange = { start: 0, end: this.pageSize };\n this.subscription = merge(\n collectionViewer.viewChange.pipe(startWith(lastRange)),\n this.resetSubject.pipe(map(() => lastRange))\n ).pipe(\n filter(range => range.end > range.start),\n map(range => { lastRange = range; return { pages: this.getPageIndices(range), version: this.resetVersion }; }),\n distinctUntilChanged((a, b) => a.version === b.version && a.pages.join() === b.pages.join()),\n switchMap(({ pages }) => from(this.fetchPages(pages)).pipe(\n catchError(() => of(this.dataStream.value))\n ))\n ).subscribe(data => this.dataStream.next(data));\n\n return this.dataStream;\n }\n\n disconnect(): void {\n this.subscription?.unsubscribe();\n this.dataStream.complete();\n }\n\n get length(): number {\n return this.totalRecords;\n }\n\n reset(): void {\n this.cachedPages.clear();\n this.resetVersion++;\n this.resetSubject.next();\n }\n\n private getPageIndices(range: { start: number; end: number }): number[] {\n const startPage = Math.floor(range.start / this.pageSize);\n const endPage = Math.floor((range.end - 1) / this.pageSize);\n const pages: number[] = [];\n for (let i = startPage; i <= endPage; i++) {\n pages.push(i);\n }\n return pages;\n }\n\n private async fetchPages(pageIndices: number[]): Promise<T[]> {\n const uncachedPages = pageIndices.filter(p => !this.cachedPages.has(p));\n\n const results = await Promise.all(\n uncachedPages.map(async pageIndex => {\n const skip = pageIndex * this.pageSize;\n const result = await this.fetchFn(skip, this.pageSize);\n return { pageIndex, result };\n })\n );\n\n for (const { pageIndex, result } of results) {\n this.cachedPages.set(pageIndex, result.data);\n }\n if (results.length > 0) {\n this.totalRecords = results[0].result.totalRecords;\n }\n\n // Build the full data array with placeholders for unloaded pages\n const totalPages = Math.ceil(this.totalRecords / this.pageSize);\n const data: T[] = [];\n for (let i = 0; i < totalPages; i++) {\n const page = this.cachedPages.get(i);\n if (page) {\n data.push(...page);\n } else {\n // Fill with empty slots to maintain correct virtual scroll positioning\n const remaining = Math.min(this.pageSize, this.totalRecords - i * this.pageSize);\n data.push(...new Array<T>(remaining));\n }\n }\n return data;\n }\n}\n","import { Directive, inject, TemplateRef } from '@angular/core';\nimport { BsVirtualDatatableComponent } from '../virtual-datatable/virtual-datatable.component';\n\n@Directive({\n selector: '[bsVirtualRowTemplate]',\n})\nexport class BsVirtualRowTemplateDirective<TData> {\n\n private datatableComponent = inject<BsVirtualDatatableComponent<TData>>(BsVirtualDatatableComponent);\n private templateRef = inject<TemplateRef<BsVirtualRowTemplateContext<TData>>>(TemplateRef);\n\n constructor() {\n this.datatableComponent.rowTemplate = this.templateRef;\n }\n\n public static ngTemplateContextGuard<TData>(\n dir: BsVirtualRowTemplateDirective<TData>,\n ctx: any\n ): ctx is BsVirtualRowTemplateContext<Exclude<TData, false | 0 | '' | null | undefined>> {\n return true;\n }\n}\n\nexport class BsVirtualRowTemplateContext<TData = unknown> {\n public $implicit: TData = null!;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|