@awc-ui/core 1.0.0-beta.2 → 1.0.0-beta.3
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.
- package/README.md +18 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js +8 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js.map +1 -0
- package/dist/cjs/engine.wasm-9JtXME10.js +12 -0
- package/dist/cjs/engine.wasm-9JtXME10.js.map +1 -0
- package/dist/cjs/{index-DlQ_5_Mv.js → index-Bm07YAg9.js} +4 -15
- package/dist/cjs/index-Bm07YAg9.js.map +1 -0
- package/dist/cjs/loader.cjs.js +3 -2
- package/dist/cjs/loader.cjs.js.map +1 -1
- package/dist/cjs/md-accordion-item.cjs.entry.js +1 -1
- package/dist/cjs/md-accordion.cjs.entry.js +1 -1
- package/dist/cjs/md-app-bar.cjs.entry.js +1 -1
- package/dist/cjs/md-area-chart.cjs.entry.js +1 -1
- package/dist/cjs/md-autocomplete.cjs.entry.js +2 -2
- package/dist/cjs/md-avatar_2.cjs.entry.js +1 -1
- package/dist/cjs/md-badge.cjs.entry.js +1 -1
- package/dist/cjs/md-bar-chart.cjs.entry.js +1 -1
- package/dist/cjs/md-bottom-sheet.cjs.entry.js +1 -1
- package/dist/cjs/md-breadcrumb-item.cjs.entry.js +1 -1
- package/dist/cjs/md-breadcrumbs.cjs.entry.js +1 -1
- package/dist/cjs/md-button-group.cjs.entry.js +1 -1
- package/dist/cjs/md-button_7.cjs.entry.js +1 -1
- package/dist/cjs/md-checkbox.cjs.entry.js +1 -1
- package/dist/cjs/md-chip.cjs.entry.js +1 -1
- package/dist/cjs/md-color-picker.cjs.entry.js +1 -1
- package/dist/cjs/md-date-picker.cjs.entry.js +1 -1
- package/dist/cjs/md-dialog.cjs.entry.js +1 -1
- package/dist/cjs/md-divider.cjs.entry.js +1 -1
- package/dist/cjs/md-fab-menu-item.cjs.entry.js +1 -1
- package/dist/cjs/md-fab-menu.cjs.entry.js +1 -1
- package/dist/cjs/md-fab.cjs.entry.js +1 -1
- package/dist/cjs/md-line-chart.cjs.entry.js +1 -1
- package/dist/cjs/md-list-item.cjs.entry.js +1 -1
- package/dist/cjs/md-list.cjs.entry.js +1 -1
- package/dist/cjs/md-menu-item-group.cjs.entry.js +1 -1
- package/dist/cjs/md-menu_2.cjs.entry.js +1 -1
- package/dist/cjs/md-meter.cjs.entry.js +1 -1
- package/dist/cjs/md-multi-select.cjs.entry.js +2 -2
- package/dist/cjs/md-navigation-bar.cjs.entry.js +1 -1
- package/dist/cjs/md-navigation-rail-tab.cjs.entry.js +1 -1
- package/dist/cjs/md-navigation-rail.cjs.entry.js +1 -1
- package/dist/cjs/md-navigation-tab.cjs.entry.js +1 -1
- package/dist/cjs/md-number-field.cjs.entry.js +1 -1
- package/dist/cjs/md-organization-chart.cjs.entry.js +1 -1
- package/dist/cjs/md-otp-field.cjs.entry.js +1 -1
- package/dist/cjs/md-pie-chart.cjs.entry.js +1 -1
- package/dist/cjs/md-progress-indicator.cjs.entry.js +1 -1
- package/dist/cjs/md-rating.cjs.entry.js +1 -1
- package/dist/cjs/md-search.cjs.entry.js +1 -1
- package/dist/cjs/md-segmented-button-set.cjs.entry.js +1 -1
- package/dist/cjs/md-segmented-button.cjs.entry.js +1 -1
- package/dist/cjs/md-select-option.cjs.entry.js +1 -1
- package/dist/cjs/md-select.cjs.entry.js +2 -2
- package/dist/cjs/md-side-sheet.cjs.entry.js +1 -1
- package/dist/cjs/md-skeleton.cjs.entry.js +1 -1
- package/dist/cjs/md-slider.cjs.entry.js +1 -1
- package/dist/cjs/md-sparkline.cjs.entry.js +1 -1
- package/dist/cjs/md-split-button.cjs.entry.js +1 -1
- package/dist/cjs/md-status-dot.cjs.entry.js +1 -1
- package/dist/cjs/md-step.cjs.entry.js +1 -1
- package/dist/cjs/md-stepper.cjs.entry.js +1 -1
- package/dist/cjs/md-sub-menu-item.cjs.entry.js +1 -1
- package/dist/cjs/md-switch.cjs.entry.js +1 -1
- package/dist/cjs/md-tab-panel.cjs.entry.js +1 -1
- package/dist/cjs/md-tab-panels.cjs.entry.js +1 -1
- package/dist/cjs/md-tab.cjs.entry.js +1 -1
- package/dist/cjs/md-table-body.cjs.entry.js +1 -1
- package/dist/cjs/md-table-cell.cjs.entry.js +1 -1
- package/dist/cjs/md-table-container.cjs.entry.js +1 -1
- package/dist/cjs/md-table-expand-toggle.cjs.entry.js +1 -1
- package/dist/cjs/md-table-foot.cjs.entry.js +1 -1
- package/dist/cjs/md-table-head.cjs.entry.js +1 -1
- package/dist/cjs/md-table-pagination.cjs.entry.js +1 -1
- package/dist/cjs/md-table-row.cjs.entry.js +1 -1
- package/dist/cjs/md-table-sort-label.cjs.entry.js +1 -1
- package/dist/cjs/md-table-toolbar.cjs.entry.js +1 -1
- package/dist/cjs/md-table.cjs.entry.js +1 -1
- package/dist/cjs/md-tabs.cjs.entry.js +1 -1
- package/dist/cjs/md-text-field.cjs.entry.js +1 -1
- package/dist/cjs/md-time-picker.cjs.entry.js +1 -1
- package/dist/cjs/md-toolbar.cjs.entry.js +1 -1
- package/dist/cjs/md-transfer-list.cjs.entry.js +1 -1
- package/dist/cjs/md3.cjs.js +3 -2
- package/dist/cjs/md3.cjs.js.map +1 -1
- package/dist/cjs/{virtual-select-controller-CqriaZgm.js → virtual-select-controller-C5cSoKfB.js} +10 -9
- package/dist/cjs/virtual-select-controller-C5cSoKfB.js.map +1 -0
- package/dist/collection/wasm/engine-abi.js +8 -2
- package/dist/collection/wasm/engine-abi.js.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/md-accordion-item.js +1 -1
- package/dist/components/md-accordion.js +1 -1
- package/dist/components/md-app-bar.js +1 -1
- package/dist/components/md-area-chart.js +1 -1
- package/dist/components/md-area-chart.js.map +1 -1
- package/dist/components/md-autocomplete.js +1 -1
- package/dist/components/md-avatar.js +1 -1
- package/dist/components/md-badge.js +1 -1
- package/dist/components/md-bar-chart.js +1 -1
- package/dist/components/md-bottom-sheet.js +1 -1
- package/dist/components/md-breadcrumb-item.js +1 -1
- package/dist/components/md-breadcrumbs.js +1 -1
- package/dist/components/md-button-group.js +1 -1
- package/dist/components/md-button.js +1 -1
- package/dist/components/md-card.js +1 -1
- package/dist/components/md-checkbox.js +1 -1
- package/dist/components/md-chip.js +1 -1
- package/dist/components/md-color-picker.js +1 -1
- package/dist/components/md-date-picker.js +1 -1
- package/dist/components/md-dialog.js +1 -1
- package/dist/components/md-divider.js +1 -1
- package/dist/components/md-fab-menu-item.js +1 -1
- package/dist/components/md-fab-menu.js +1 -1
- package/dist/components/md-fab.js +1 -1
- package/dist/components/md-icon-button.js +1 -1
- package/dist/components/md-line-chart.js +1 -1
- package/dist/components/md-list-item.js +1 -1
- package/dist/components/md-list.js +1 -1
- package/dist/components/md-loading-indicator.js +1 -1
- package/dist/components/md-menu-item-group.js +1 -1
- package/dist/components/md-menu-item.js +1 -1
- package/dist/components/md-menu.js +1 -1
- package/dist/components/md-meter.js +1 -1
- package/dist/components/md-multi-select.js +1 -1
- package/dist/components/md-navigation-bar.js +1 -1
- package/dist/components/md-navigation-rail-tab.js +1 -1
- package/dist/components/md-navigation-rail.js +1 -1
- package/dist/components/md-navigation-tab.js +1 -1
- package/dist/components/md-number-field.js +1 -1
- package/dist/components/md-organization-chart.js +1 -1
- package/dist/components/md-otp-field.js +1 -1
- package/dist/components/md-pie-chart.js +1 -1
- package/dist/components/md-progress-indicator.js +1 -1
- package/dist/components/md-radio.js +1 -1
- package/dist/components/md-rating.js +1 -1
- package/dist/components/md-ripple.js +1 -1
- package/dist/components/md-search.js +1 -1
- package/dist/components/md-segmented-button-set.js +1 -1
- package/dist/components/md-segmented-button.js +1 -1
- package/dist/components/md-select-option.js +1 -1
- package/dist/components/md-select.js +1 -1
- package/dist/components/md-side-sheet.js +1 -1
- package/dist/components/md-skeleton.js +1 -1
- package/dist/components/md-slider.js +1 -1
- package/dist/components/md-snackbar.js +1 -1
- package/dist/components/md-sparkline.js +1 -1
- package/dist/components/md-split-button.js +1 -1
- package/dist/components/md-status-dot.js +1 -1
- package/dist/components/md-step.js +1 -1
- package/dist/components/md-stepper.js +1 -1
- package/dist/components/md-sub-menu-item.js +1 -1
- package/dist/components/md-switch.js +1 -1
- package/dist/components/md-tab-panel.js +1 -1
- package/dist/components/md-tab-panels.js +1 -1
- package/dist/components/md-tab.js +1 -1
- package/dist/components/md-table-body.js +1 -1
- package/dist/components/md-table-cell.js +1 -1
- package/dist/components/md-table-container.js +1 -1
- package/dist/components/md-table-expand-toggle.js +1 -1
- package/dist/components/md-table-foot.js +1 -1
- package/dist/components/md-table-head.js +1 -1
- package/dist/components/md-table-pagination.js +1 -1
- package/dist/components/md-table-row.js +1 -1
- package/dist/components/md-table-sort-label.js +1 -1
- package/dist/components/md-table-toolbar.js +1 -1
- package/dist/components/md-table.js +1 -1
- package/dist/components/md-tabs.js +1 -1
- package/dist/components/md-text-field.js +1 -1
- package/dist/components/md-time-picker.js +1 -1
- package/dist/components/md-toolbar.js +1 -1
- package/dist/components/md-tooltip.js +1 -1
- package/dist/components/md-transfer-list.js +1 -1
- package/dist/components/p-B-JfuA2g.js +2 -0
- package/dist/components/p-B-JfuA2g.js.map +1 -0
- package/dist/components/p-B-iHDK5h.js +2 -0
- package/dist/components/p-B-iHDK5h.js.map +1 -0
- package/dist/components/p-BA2v4IuG.js +2 -0
- package/dist/components/p-BA2v4IuG.js.map +1 -0
- package/dist/components/p-BADA63mI.js +2 -0
- package/dist/components/p-BADA63mI.js.map +1 -0
- package/dist/components/p-BR6gfOQH.js +2 -0
- package/dist/components/p-BR6gfOQH.js.map +1 -0
- package/dist/components/p-Bz-JaJcA.js +2 -0
- package/dist/components/p-Bz-JaJcA.js.map +1 -0
- package/dist/components/p-CCMritCA.js +2 -0
- package/dist/components/p-CCMritCA.js.map +1 -0
- package/dist/components/p-CTC8XAB6.js +2 -0
- package/dist/components/p-CTC8XAB6.js.map +1 -0
- package/dist/components/p-CfBPnYW7.js +2 -0
- package/dist/components/p-CfBPnYW7.js.map +1 -0
- package/dist/components/p-CtVItLby.js +2 -0
- package/dist/components/p-CtVItLby.js.map +1 -0
- package/dist/components/p-D8oM1Kr3.js +2 -0
- package/dist/components/p-D8oM1Kr3.js.map +1 -0
- package/dist/components/{p-Ddiw2Kjw.js → p-DEzb9xsY.js} +2 -2
- package/dist/components/p-DEzb9xsY.js.map +1 -0
- package/dist/components/p-DYL-8C5C.js +2 -0
- package/dist/components/p-DYL-8C5C.js.map +1 -0
- package/dist/components/p-DfU4xY2F.js +2 -0
- package/dist/components/p-DfU4xY2F.js.map +1 -0
- package/dist/components/p-Eb44PPZa.js +2 -0
- package/dist/components/p-Eb44PPZa.js.map +1 -0
- package/dist/components/{p-UdGDg2oJ.js → p-Lsoo1B-2.js} +2 -2
- package/dist/components/p-Lsoo1B-2.js.map +1 -0
- package/dist/components/p-tSoecrcz.js +2 -0
- package/dist/components/p-tSoecrcz.js.map +1 -0
- package/dist/components-csr/index.js +2 -0
- package/dist/components-csr/index.js.map +1 -0
- package/dist/components-csr/md-accordion-item.js +2 -0
- package/dist/components-csr/md-accordion-item.js.map +1 -0
- package/dist/components-csr/md-accordion.js +2 -0
- package/dist/components-csr/md-accordion.js.map +1 -0
- package/dist/components-csr/md-app-bar.js +2 -0
- package/dist/components-csr/md-app-bar.js.map +1 -0
- package/dist/components-csr/md-area-chart.js +2 -0
- package/dist/components-csr/md-area-chart.js.map +1 -0
- package/dist/components-csr/md-autocomplete.js +2 -0
- package/dist/components-csr/md-autocomplete.js.map +1 -0
- package/dist/components-csr/md-avatar.js +2 -0
- package/dist/components-csr/md-avatar.js.map +1 -0
- package/dist/components-csr/md-badge.js +2 -0
- package/dist/components-csr/md-badge.js.map +1 -0
- package/dist/components-csr/md-bar-chart.js +2 -0
- package/dist/components-csr/md-bar-chart.js.map +1 -0
- package/dist/components-csr/md-bottom-sheet.js +2 -0
- package/dist/components-csr/md-bottom-sheet.js.map +1 -0
- package/dist/components-csr/md-breadcrumb-item.js +2 -0
- package/dist/components-csr/md-breadcrumb-item.js.map +1 -0
- package/dist/components-csr/md-breadcrumbs.js +2 -0
- package/dist/components-csr/md-breadcrumbs.js.map +1 -0
- package/dist/components-csr/md-button-group.js +2 -0
- package/dist/components-csr/md-button-group.js.map +1 -0
- package/dist/components-csr/md-button.js +2 -0
- package/dist/components-csr/md-button.js.map +1 -0
- package/dist/components-csr/md-card.js +2 -0
- package/dist/components-csr/md-card.js.map +1 -0
- package/dist/components-csr/md-checkbox.js +2 -0
- package/dist/components-csr/md-checkbox.js.map +1 -0
- package/dist/components-csr/md-chip.js +2 -0
- package/dist/components-csr/md-chip.js.map +1 -0
- package/dist/components-csr/md-color-picker.js +2 -0
- package/dist/components-csr/md-color-picker.js.map +1 -0
- package/dist/components-csr/md-date-picker.js +2 -0
- package/dist/components-csr/md-date-picker.js.map +1 -0
- package/dist/components-csr/md-dialog.js +2 -0
- package/dist/components-csr/md-dialog.js.map +1 -0
- package/dist/components-csr/md-divider.js +2 -0
- package/dist/components-csr/md-divider.js.map +1 -0
- package/dist/components-csr/md-fab-menu-item.js +2 -0
- package/dist/components-csr/md-fab-menu-item.js.map +1 -0
- package/dist/components-csr/md-fab-menu.js +2 -0
- package/dist/components-csr/md-fab-menu.js.map +1 -0
- package/dist/components-csr/md-fab.js +2 -0
- package/dist/components-csr/md-fab.js.map +1 -0
- package/dist/components-csr/md-icon-button.js +2 -0
- package/dist/components-csr/md-icon-button.js.map +1 -0
- package/dist/components-csr/md-line-chart.js +2 -0
- package/dist/components-csr/md-line-chart.js.map +1 -0
- package/dist/components-csr/md-list-item.js +2 -0
- package/dist/components-csr/md-list-item.js.map +1 -0
- package/dist/components-csr/md-list.js +2 -0
- package/dist/components-csr/md-list.js.map +1 -0
- package/dist/components-csr/md-loading-indicator.js +2 -0
- package/dist/components-csr/md-loading-indicator.js.map +1 -0
- package/dist/components-csr/md-menu-item-group.js +2 -0
- package/dist/components-csr/md-menu-item-group.js.map +1 -0
- package/dist/components-csr/md-menu-item.js +2 -0
- package/dist/components-csr/md-menu-item.js.map +1 -0
- package/dist/components-csr/md-menu.js +2 -0
- package/dist/components-csr/md-menu.js.map +1 -0
- package/dist/components-csr/md-meter.js +2 -0
- package/dist/components-csr/md-meter.js.map +1 -0
- package/dist/components-csr/md-multi-select.js +2 -0
- package/dist/components-csr/md-multi-select.js.map +1 -0
- package/dist/components-csr/md-navigation-bar.js +2 -0
- package/dist/components-csr/md-navigation-bar.js.map +1 -0
- package/dist/components-csr/md-navigation-rail-tab.js +2 -0
- package/dist/components-csr/md-navigation-rail-tab.js.map +1 -0
- package/dist/components-csr/md-navigation-rail.js +2 -0
- package/dist/components-csr/md-navigation-rail.js.map +1 -0
- package/dist/components-csr/md-navigation-tab.js +2 -0
- package/dist/components-csr/md-navigation-tab.js.map +1 -0
- package/dist/components-csr/md-number-field.js +2 -0
- package/dist/components-csr/md-number-field.js.map +1 -0
- package/dist/components-csr/md-organization-chart.js +2 -0
- package/dist/components-csr/md-organization-chart.js.map +1 -0
- package/dist/components-csr/md-otp-field.js +2 -0
- package/dist/components-csr/md-otp-field.js.map +1 -0
- package/dist/components-csr/md-pie-chart.js +2 -0
- package/dist/components-csr/md-pie-chart.js.map +1 -0
- package/dist/components-csr/md-progress-indicator.js +2 -0
- package/dist/components-csr/md-progress-indicator.js.map +1 -0
- package/dist/components-csr/md-radio.js +2 -0
- package/dist/components-csr/md-radio.js.map +1 -0
- package/dist/components-csr/md-rating.js +2 -0
- package/dist/components-csr/md-rating.js.map +1 -0
- package/dist/components-csr/md-ripple.js +2 -0
- package/dist/components-csr/md-ripple.js.map +1 -0
- package/dist/components-csr/md-search.js +2 -0
- package/dist/components-csr/md-search.js.map +1 -0
- package/dist/components-csr/md-segmented-button-set.js +2 -0
- package/dist/components-csr/md-segmented-button-set.js.map +1 -0
- package/dist/components-csr/md-segmented-button.js +2 -0
- package/dist/components-csr/md-segmented-button.js.map +1 -0
- package/dist/components-csr/md-select-option.js +2 -0
- package/dist/components-csr/md-select-option.js.map +1 -0
- package/dist/components-csr/md-select.js +2 -0
- package/dist/components-csr/md-select.js.map +1 -0
- package/dist/components-csr/md-side-sheet.js +2 -0
- package/dist/components-csr/md-side-sheet.js.map +1 -0
- package/dist/components-csr/md-skeleton.js +2 -0
- package/dist/components-csr/md-skeleton.js.map +1 -0
- package/dist/components-csr/md-slider.js +2 -0
- package/dist/components-csr/md-slider.js.map +1 -0
- package/dist/components-csr/md-snackbar.js +2 -0
- package/dist/components-csr/md-snackbar.js.map +1 -0
- package/dist/components-csr/md-sparkline.js +2 -0
- package/dist/components-csr/md-sparkline.js.map +1 -0
- package/dist/components-csr/md-split-button.js +2 -0
- package/dist/components-csr/md-split-button.js.map +1 -0
- package/dist/components-csr/md-status-dot.js +2 -0
- package/dist/components-csr/md-status-dot.js.map +1 -0
- package/dist/components-csr/md-step.js +2 -0
- package/dist/components-csr/md-step.js.map +1 -0
- package/dist/components-csr/md-stepper.js +2 -0
- package/dist/components-csr/md-stepper.js.map +1 -0
- package/dist/components-csr/md-sub-menu-item.js +2 -0
- package/dist/components-csr/md-sub-menu-item.js.map +1 -0
- package/dist/components-csr/md-switch.js +2 -0
- package/dist/components-csr/md-switch.js.map +1 -0
- package/dist/components-csr/md-tab-panel.js +2 -0
- package/dist/components-csr/md-tab-panel.js.map +1 -0
- package/dist/components-csr/md-tab-panels.js +2 -0
- package/dist/components-csr/md-tab-panels.js.map +1 -0
- package/dist/components-csr/md-tab.js +2 -0
- package/dist/components-csr/md-tab.js.map +1 -0
- package/dist/components-csr/md-table-body.js +2 -0
- package/dist/components-csr/md-table-body.js.map +1 -0
- package/dist/components-csr/md-table-cell.js +2 -0
- package/dist/components-csr/md-table-cell.js.map +1 -0
- package/dist/components-csr/md-table-container.js +2 -0
- package/dist/components-csr/md-table-container.js.map +1 -0
- package/dist/components-csr/md-table-expand-toggle.js +2 -0
- package/dist/components-csr/md-table-expand-toggle.js.map +1 -0
- package/dist/components-csr/md-table-foot.js +2 -0
- package/dist/components-csr/md-table-foot.js.map +1 -0
- package/dist/components-csr/md-table-head.js +2 -0
- package/dist/components-csr/md-table-head.js.map +1 -0
- package/dist/components-csr/md-table-pagination.js +2 -0
- package/dist/components-csr/md-table-pagination.js.map +1 -0
- package/dist/components-csr/md-table-row.js +2 -0
- package/dist/components-csr/md-table-row.js.map +1 -0
- package/dist/components-csr/md-table-sort-label.js +2 -0
- package/dist/components-csr/md-table-sort-label.js.map +1 -0
- package/dist/components-csr/md-table-toolbar.js +2 -0
- package/dist/components-csr/md-table-toolbar.js.map +1 -0
- package/dist/components-csr/md-table.js +2 -0
- package/dist/components-csr/md-table.js.map +1 -0
- package/dist/components-csr/md-tabs.js +2 -0
- package/dist/components-csr/md-tabs.js.map +1 -0
- package/dist/components-csr/md-text-field.js +2 -0
- package/dist/components-csr/md-text-field.js.map +1 -0
- package/dist/components-csr/md-time-picker.js +2 -0
- package/dist/components-csr/md-time-picker.js.map +1 -0
- package/dist/components-csr/md-toolbar.js +2 -0
- package/dist/components-csr/md-toolbar.js.map +1 -0
- package/dist/components-csr/md-tooltip.js +2 -0
- package/dist/components-csr/md-tooltip.js.map +1 -0
- package/dist/components-csr/md-transfer-list.js +2 -0
- package/dist/components-csr/md-transfer-list.js.map +1 -0
- package/dist/{components/p-DXXUoRSH.js → components-csr/p--OUYjgKN.js} +2 -2
- package/dist/{components/p-Dp-w93ot.js → components-csr/p--TCJgZnE.js} +2 -2
- package/dist/components-csr/p-BdEoSBtL.js +2 -0
- package/dist/components-csr/p-BdEoSBtL.js.map +1 -0
- package/dist/components-csr/p-Bmu7RqHM.js +2 -0
- package/dist/components-csr/p-Bx6--dQF.js +2 -0
- package/dist/components-csr/p-Bx6--dQF.js.map +1 -0
- package/dist/components-csr/p-Bz-JaJcA.js +2 -0
- package/dist/components-csr/p-Bz-JaJcA.js.map +1 -0
- package/dist/{components/p-uTEkf0sE.js → components-csr/p-C0DlKmRg.js} +2 -2
- package/dist/{components/p-Ch2-tttM.js → components-csr/p-C4_7YnHT.js} +2 -2
- package/dist/{components/p-BwXpiUsu.js → components-csr/p-CG6FaRlt.js} +2 -2
- package/dist/{components/p-B0Opn6dK.js → components-csr/p-CSrxeWwL.js} +2 -2
- package/dist/components-csr/p-C_ogF68H.js +2 -0
- package/dist/components-csr/p-C_ogF68H.js.map +1 -0
- package/dist/components-csr/p-Cch_V1vi.js +2 -0
- package/dist/components-csr/p-Cch_V1vi.js.map +1 -0
- package/dist/components-csr/p-CfBPnYW7.js +2 -0
- package/dist/components-csr/p-CfBPnYW7.js.map +1 -0
- package/dist/{components/p-B3MWYEEJ.js → components-csr/p-CrbzXk64.js} +2 -2
- package/dist/components-csr/p-CxhZdOPw.js +2 -0
- package/dist/components-csr/p-CxhZdOPw.js.map +1 -0
- package/dist/{components/p-7fN_yCXW.js → components-csr/p-DF19mmLl.js} +2 -2
- package/dist/components-csr/p-DWxN44zD.js +2 -0
- package/dist/components-csr/p-DWxN44zD.js.map +1 -0
- package/dist/components-csr/p-DYBUr7K_.js +2 -0
- package/dist/components-csr/p-DYBUr7K_.js.map +1 -0
- package/dist/{components/p-e2HRV63Y.js → components-csr/p-DfcpeJAu.js} +2 -2
- package/dist/components-csr/p-DvOKnoqK.js +2 -0
- package/dist/components-csr/p-DvOKnoqK.js.map +1 -0
- package/dist/{components/p-C8EP4S21.js → components-csr/p-DvXQXhgu.js} +2 -2
- package/dist/components-csr/p-DzPKu-Ma.js +2 -0
- package/dist/components-csr/p-DzPKu-Ma.js.map +1 -0
- package/dist/{components/p-stybaFzj.js → components-csr/p-Hm3X1iai.js} +2 -2
- package/dist/{components/p-6wZSqm_2.js → components-csr/p-IWA0yIjJ.js} +2 -2
- package/dist/components-csr/p-RLxbNqRv.js +2 -0
- package/dist/components-csr/p-RLxbNqRv.js.map +1 -0
- package/dist/components-csr/p-bSpXNc5J.js +2 -0
- package/dist/components-csr/p-bSpXNc5J.js.map +1 -0
- package/dist/components-csr/p-uZbtHo-A.js +2 -0
- package/dist/components-csr/package.json +3 -0
- package/dist/esm/app-globals-DQuL1Twl.js +6 -0
- package/dist/esm/app-globals-DQuL1Twl.js.map +1 -0
- package/dist/esm/engine.wasm-CfBPnYW7.js +10 -0
- package/dist/esm/engine.wasm-CfBPnYW7.js.map +1 -0
- package/dist/esm/{index-DTaX19_O.js → index-WmvQpZnM.js} +5 -15
- package/dist/esm/index-WmvQpZnM.js.map +1 -0
- package/dist/esm/loader.js +3 -2
- package/dist/esm/loader.js.map +1 -1
- package/dist/esm/md-accordion-item.entry.js +1 -1
- package/dist/esm/md-accordion.entry.js +1 -1
- package/dist/esm/md-app-bar.entry.js +1 -1
- package/dist/esm/md-area-chart.entry.js +1 -1
- package/dist/esm/md-autocomplete.entry.js +2 -2
- package/dist/esm/md-avatar_2.entry.js +1 -1
- package/dist/esm/md-badge.entry.js +1 -1
- package/dist/esm/md-bar-chart.entry.js +1 -1
- package/dist/esm/md-bottom-sheet.entry.js +1 -1
- package/dist/esm/md-breadcrumb-item.entry.js +1 -1
- package/dist/esm/md-breadcrumbs.entry.js +1 -1
- package/dist/esm/md-button-group.entry.js +1 -1
- package/dist/esm/md-button_7.entry.js +1 -1
- package/dist/esm/md-checkbox.entry.js +1 -1
- package/dist/esm/md-chip.entry.js +1 -1
- package/dist/esm/md-color-picker.entry.js +1 -1
- package/dist/esm/md-date-picker.entry.js +1 -1
- package/dist/esm/md-dialog.entry.js +1 -1
- package/dist/esm/md-divider.entry.js +1 -1
- package/dist/esm/md-fab-menu-item.entry.js +1 -1
- package/dist/esm/md-fab-menu.entry.js +1 -1
- package/dist/esm/md-fab.entry.js +1 -1
- package/dist/esm/md-line-chart.entry.js +1 -1
- package/dist/esm/md-list-item.entry.js +1 -1
- package/dist/esm/md-list.entry.js +1 -1
- package/dist/esm/md-menu-item-group.entry.js +1 -1
- package/dist/esm/md-menu_2.entry.js +1 -1
- package/dist/esm/md-meter.entry.js +1 -1
- package/dist/esm/md-multi-select.entry.js +2 -2
- package/dist/esm/md-navigation-bar.entry.js +1 -1
- package/dist/esm/md-navigation-rail-tab.entry.js +1 -1
- package/dist/esm/md-navigation-rail.entry.js +1 -1
- package/dist/esm/md-navigation-tab.entry.js +1 -1
- package/dist/esm/md-number-field.entry.js +1 -1
- package/dist/esm/md-organization-chart.entry.js +1 -1
- package/dist/esm/md-otp-field.entry.js +1 -1
- package/dist/esm/md-pie-chart.entry.js +1 -1
- package/dist/esm/md-progress-indicator.entry.js +1 -1
- package/dist/esm/md-rating.entry.js +1 -1
- package/dist/esm/md-search.entry.js +1 -1
- package/dist/esm/md-segmented-button-set.entry.js +1 -1
- package/dist/esm/md-segmented-button.entry.js +1 -1
- package/dist/esm/md-select-option.entry.js +1 -1
- package/dist/esm/md-select.entry.js +2 -2
- package/dist/esm/md-side-sheet.entry.js +1 -1
- package/dist/esm/md-skeleton.entry.js +1 -1
- package/dist/esm/md-slider.entry.js +1 -1
- package/dist/esm/md-sparkline.entry.js +1 -1
- package/dist/esm/md-split-button.entry.js +1 -1
- package/dist/esm/md-status-dot.entry.js +1 -1
- package/dist/esm/md-step.entry.js +1 -1
- package/dist/esm/md-stepper.entry.js +1 -1
- package/dist/esm/md-sub-menu-item.entry.js +1 -1
- package/dist/esm/md-switch.entry.js +1 -1
- package/dist/esm/md-tab-panel.entry.js +1 -1
- package/dist/esm/md-tab-panels.entry.js +1 -1
- package/dist/esm/md-tab.entry.js +1 -1
- package/dist/esm/md-table-body.entry.js +1 -1
- package/dist/esm/md-table-cell.entry.js +1 -1
- package/dist/esm/md-table-container.entry.js +1 -1
- package/dist/esm/md-table-expand-toggle.entry.js +1 -1
- package/dist/esm/md-table-foot.entry.js +1 -1
- package/dist/esm/md-table-head.entry.js +1 -1
- package/dist/esm/md-table-pagination.entry.js +1 -1
- package/dist/esm/md-table-row.entry.js +1 -1
- package/dist/esm/md-table-sort-label.entry.js +1 -1
- package/dist/esm/md-table-toolbar.entry.js +1 -1
- package/dist/esm/md-table.entry.js +1 -1
- package/dist/esm/md-tabs.entry.js +1 -1
- package/dist/esm/md-text-field.entry.js +1 -1
- package/dist/esm/md-time-picker.entry.js +1 -1
- package/dist/esm/md-toolbar.entry.js +1 -1
- package/dist/esm/md-transfer-list.entry.js +1 -1
- package/dist/esm/md3.js +3 -2
- package/dist/esm/md3.js.map +1 -1
- package/dist/esm/{virtual-select-controller-BEWIC0pC.js → virtual-select-controller-CR60w6DO.js} +10 -9
- package/dist/esm/virtual-select-controller-CR60w6DO.js.map +1 -0
- package/dist/md3/md3.css +1 -1
- package/dist/md3/md3.esm.js +1 -1
- package/dist/md3/md3.esm.js.map +1 -1
- package/dist/md3/{p-2e9503d7.entry.js → p-0a599351.entry.js} +2 -2
- package/dist/md3/p-1d7e0203.entry.js +2 -0
- package/dist/md3/{p-fb61868c.entry.js.map → p-1d7e0203.entry.js.map} +1 -1
- package/dist/md3/p-1e85b8a8.entry.js +2 -0
- package/dist/md3/{p-aaec2698.entry.js.map → p-1e85b8a8.entry.js.map} +1 -1
- package/dist/md3/{p-396089fd.entry.js → p-1edb5a0d.entry.js} +2 -2
- package/dist/md3/{p-c00f7514.entry.js → p-21c89d1d.entry.js} +2 -2
- package/dist/md3/p-22633b2d.entry.js +2 -0
- package/dist/md3/{p-6b2871a0.entry.js.map → p-22633b2d.entry.js.map} +1 -1
- package/dist/md3/{p-2e09a7b7.entry.js → p-27135a6b.entry.js} +2 -2
- package/dist/md3/{p-c063c823.entry.js → p-2befc42c.entry.js} +2 -2
- package/dist/md3/p-2dda08b2.entry.js +2 -0
- package/dist/md3/{p-21772851.entry.js.map → p-2dda08b2.entry.js.map} +1 -1
- package/dist/md3/p-3508d0e0.entry.js +2 -0
- package/dist/md3/{p-f31ab454.entry.js.map → p-3508d0e0.entry.js.map} +1 -1
- package/dist/md3/{p-b34d385b.entry.js → p-35b05b45.entry.js} +2 -2
- package/dist/md3/{p-c2dd8c8c.entry.js → p-38e9a583.entry.js} +2 -2
- package/dist/md3/{p-3cce1de3.entry.js → p-38f82d34.entry.js} +2 -2
- package/dist/md3/p-3a4bd4eb.entry.js +2 -0
- package/dist/md3/{p-72457a85.entry.js.map → p-3a4bd4eb.entry.js.map} +1 -1
- package/dist/md3/{p-be02624e.entry.js → p-3c0469aa.entry.js} +2 -2
- package/dist/md3/{p-63b8c8d1.entry.js → p-408ee4be.entry.js} +2 -2
- package/dist/md3/{p-3015c7e3.entry.js → p-4770b534.entry.js} +2 -2
- package/dist/md3/p-4aed552f.entry.js +2 -0
- package/dist/md3/{p-6c44cf13.entry.js.map → p-4aed552f.entry.js.map} +1 -1
- package/dist/md3/{p-c5af701b.entry.js → p-4ba3623e.entry.js} +2 -2
- package/dist/md3/{p-7b463fbe.entry.js → p-4f2e82cb.entry.js} +2 -2
- package/dist/md3/{p-be412e3f.entry.js → p-501bf161.entry.js} +2 -2
- package/dist/md3/{p-81843ff7.entry.js → p-5929e59c.entry.js} +2 -2
- package/dist/md3/{p-32bdd439.entry.js → p-5c35f916.entry.js} +2 -2
- package/dist/md3/{p-ac35ac5f.entry.js → p-5db87a9d.entry.js} +2 -2
- package/dist/md3/{p-6038b907.entry.js → p-5f39b49d.entry.js} +2 -2
- package/dist/md3/p-637baee1.entry.js +2 -0
- package/dist/md3/{p-47af9819.entry.js.map → p-637baee1.entry.js.map} +1 -1
- package/dist/md3/{p-05ae91b6.entry.js → p-6bf632c7.entry.js} +2 -2
- package/dist/md3/{p-4e3d6e40.entry.js → p-6ea7117d.entry.js} +2 -2
- package/dist/md3/{p-9ddbf247.entry.js → p-7112374d.entry.js} +2 -2
- package/dist/md3/{p-1a8ec5bc.entry.js → p-7858833e.entry.js} +2 -2
- package/dist/md3/p-7c8842bf.entry.js +2 -0
- package/dist/md3/{p-ba2ebde1.entry.js.map → p-7c8842bf.entry.js.map} +1 -1
- package/dist/md3/{p-4d82132d.entry.js → p-7f53a423.entry.js} +2 -2
- package/dist/md3/{p-b0431a5c.entry.js → p-8135c606.entry.js} +2 -2
- package/dist/md3/{p-4dda4cb0.entry.js → p-845ca9cc.entry.js} +2 -2
- package/dist/md3/{p-5b74694e.entry.js → p-89d47130.entry.js} +2 -2
- package/dist/md3/p-8a6fed13.entry.js +2 -0
- package/dist/md3/{p-a803da99.entry.js.map → p-8a6fed13.entry.js.map} +1 -1
- package/dist/md3/{p-e3124e1e.entry.js → p-8b1ea5dc.entry.js} +2 -2
- package/dist/md3/{p-c10a33c2.entry.js → p-8e7df348.entry.js} +2 -2
- package/dist/md3/{p-65195996.entry.js → p-925768ac.entry.js} +2 -2
- package/dist/md3/p-944e69e0.entry.js +2 -0
- package/dist/md3/{p-a3308c40.entry.js.map → p-944e69e0.entry.js.map} +1 -1
- package/dist/md3/{p-ac8762e5.entry.js → p-96c06b24.entry.js} +2 -2
- package/dist/md3/p-9b9677cc.entry.js +2 -0
- package/dist/md3/{p-e7dc5a32.entry.js.map → p-9b9677cc.entry.js.map} +1 -1
- package/dist/md3/p-Bz-JaJcA.js +2 -0
- package/dist/md3/p-Bz-JaJcA.js.map +1 -0
- package/dist/md3/p-CfBPnYW7.js +2 -0
- package/dist/md3/p-CfBPnYW7.js.map +1 -0
- package/dist/md3/p-DQuL1Twl.js +2 -0
- package/dist/md3/p-DQuL1Twl.js.map +1 -0
- package/dist/md3/p-WmvQpZnM.js +3 -0
- package/dist/md3/p-WmvQpZnM.js.map +1 -0
- package/dist/md3/p-a3623653.entry.js +2 -0
- package/dist/md3/{p-19ee9c33.entry.js.map → p-a3623653.entry.js.map} +1 -1
- package/dist/md3/{p-a5fee424.entry.js → p-a49df43d.entry.js} +2 -2
- package/dist/md3/{p-da4e27d4.entry.js → p-a4d4cfed.entry.js} +2 -2
- package/dist/md3/{p-5394254f.entry.js → p-a976498b.entry.js} +2 -2
- package/dist/md3/{p-bf7842f8.entry.js → p-adf8a415.entry.js} +2 -2
- package/dist/md3/{p-c861d774.entry.js → p-ae360663.entry.js} +2 -2
- package/dist/md3/{p-8eb0b6a4.entry.js → p-b243284b.entry.js} +2 -2
- package/dist/md3/{p-45280bf4.entry.js → p-b2d88292.entry.js} +2 -2
- package/dist/md3/{p-796f79f8.entry.js → p-b3b5247b.entry.js} +2 -2
- package/dist/md3/{p-5b799707.entry.js → p-b4266f6b.entry.js} +2 -2
- package/dist/md3/p-b5586b66.entry.js +2 -0
- package/dist/md3/{p-04e97f5d.entry.js.map → p-b5586b66.entry.js.map} +1 -1
- package/dist/md3/{p-a7ffb779.entry.js → p-b7602557.entry.js} +2 -2
- package/dist/md3/{p-6ba63c73.entry.js → p-bc24f0c9.entry.js} +2 -2
- package/dist/md3/{p-edb34a6d.entry.js → p-bed8dfec.entry.js} +2 -2
- package/dist/md3/{p-50555bb7.entry.js → p-c0476406.entry.js} +2 -2
- package/dist/md3/{p-0c2e824d.entry.js → p-c20fbb9e.entry.js} +2 -2
- package/dist/md3/{p-4e45b2ff.entry.js → p-c58c68d0.entry.js} +2 -2
- package/dist/md3/{p-fc0b325d.entry.js → p-cdcea99f.entry.js} +2 -2
- package/dist/md3/{p-0f764a1e.entry.js → p-d2e39c6e.entry.js} +2 -2
- package/dist/md3/p-d7e99f9e.entry.js +2 -0
- package/dist/md3/{p-cf07e761.entry.js.map → p-d7e99f9e.entry.js.map} +1 -1
- package/dist/md3/{p-c1ca6f6c.entry.js → p-da0c36d9.entry.js} +2 -2
- package/dist/md3/{p-77a01bcc.entry.js → p-e3c37222.entry.js} +2 -2
- package/dist/md3/{p-39cb7c24.entry.js → p-e6b09e71.entry.js} +2 -2
- package/dist/md3/{p-b4631a55.entry.js → p-eddae19a.entry.js} +2 -2
- package/dist/md3/{p-c6a12344.entry.js → p-ef7b1826.entry.js} +2 -2
- package/dist/md3/p-f1b69181.entry.js +2 -0
- package/dist/md3/{p-a986fd24.entry.js.map → p-f1b69181.entry.js.map} +1 -1
- package/dist/md3/{p-e6d7f0ff.entry.js → p-f403ad20.entry.js} +2 -2
- package/dist/md3/{p-708a9313.entry.js → p-f5fd9a0b.entry.js} +2 -2
- package/dist/md3/{p-aa0e7d4d.entry.js → p-f71af38f.entry.js} +2 -2
- package/dist/md3/{p-757e3aaf.entry.js → p-fac6da4c.entry.js} +2 -2
- package/dist/md3/{p-134b670a.entry.js → p-fc864f96.entry.js} +2 -2
- package/dist/types/wasm/engine-abi.d.ts +14 -0
- package/hydrate/index.js +19 -7
- package/hydrate/index.mjs +19 -7
- package/package.json +14 -3
- package/dist/cjs/index-DlQ_5_Mv.js.map +0 -1
- package/dist/cjs/virtual-select-controller-CqriaZgm.js.map +0 -1
- package/dist/components/p-BEWIC0pC.js +0 -2
- package/dist/components/p-BEWIC0pC.js.map +0 -1
- package/dist/components/p-MWBNn6Lj.js +0 -2
- package/dist/components/p-MWBNn6Lj.js.map +0 -1
- package/dist/esm/index-DTaX19_O.js.map +0 -1
- package/dist/esm/virtual-select-controller-BEWIC0pC.js.map +0 -1
- package/dist/md3/p-04e97f5d.entry.js +0 -2
- package/dist/md3/p-19ee9c33.entry.js +0 -2
- package/dist/md3/p-21772851.entry.js +0 -2
- package/dist/md3/p-47af9819.entry.js +0 -2
- package/dist/md3/p-6b2871a0.entry.js +0 -2
- package/dist/md3/p-6c44cf13.entry.js +0 -2
- package/dist/md3/p-72457a85.entry.js +0 -2
- package/dist/md3/p-BEWIC0pC.js +0 -2
- package/dist/md3/p-BEWIC0pC.js.map +0 -1
- package/dist/md3/p-DTaX19_O.js +0 -3
- package/dist/md3/p-DTaX19_O.js.map +0 -1
- package/dist/md3/p-a3308c40.entry.js +0 -2
- package/dist/md3/p-a803da99.entry.js +0 -2
- package/dist/md3/p-a986fd24.entry.js +0 -2
- package/dist/md3/p-aaec2698.entry.js +0 -2
- package/dist/md3/p-ba2ebde1.entry.js +0 -2
- package/dist/md3/p-cf07e761.entry.js +0 -2
- package/dist/md3/p-e7dc5a32.entry.js +0 -2
- package/dist/md3/p-f31ab454.entry.js +0 -2
- package/dist/md3/p-fb61868c.entry.js +0 -2
- /package/dist/{components/p-DXXUoRSH.js.map → components-csr/p--OUYjgKN.js.map} +0 -0
- /package/dist/{components/p-Dp-w93ot.js.map → components-csr/p--TCJgZnE.js.map} +0 -0
- /package/dist/{components/p-UdGDg2oJ.js.map → components-csr/p-Bmu7RqHM.js.map} +0 -0
- /package/dist/{components/p-uTEkf0sE.js.map → components-csr/p-C0DlKmRg.js.map} +0 -0
- /package/dist/{components/p-Ch2-tttM.js.map → components-csr/p-C4_7YnHT.js.map} +0 -0
- /package/dist/{components/p-BwXpiUsu.js.map → components-csr/p-CG6FaRlt.js.map} +0 -0
- /package/dist/{components/p-B0Opn6dK.js.map → components-csr/p-CSrxeWwL.js.map} +0 -0
- /package/dist/{components/p-B3MWYEEJ.js.map → components-csr/p-CrbzXk64.js.map} +0 -0
- /package/dist/{components/p-7fN_yCXW.js.map → components-csr/p-DF19mmLl.js.map} +0 -0
- /package/dist/{components/p-e2HRV63Y.js.map → components-csr/p-DfcpeJAu.js.map} +0 -0
- /package/dist/{components/p-C8EP4S21.js.map → components-csr/p-DvXQXhgu.js.map} +0 -0
- /package/dist/{components/p-stybaFzj.js.map → components-csr/p-Hm3X1iai.js.map} +0 -0
- /package/dist/{components/p-6wZSqm_2.js.map → components-csr/p-IWA0yIjJ.js.map} +0 -0
- /package/dist/{components/p-Ddiw2Kjw.js.map → components-csr/p-uZbtHo-A.js.map} +0 -0
- /package/dist/md3/{p-2e9503d7.entry.js.map → p-0a599351.entry.js.map} +0 -0
- /package/dist/md3/{p-396089fd.entry.js.map → p-1edb5a0d.entry.js.map} +0 -0
- /package/dist/md3/{p-c00f7514.entry.js.map → p-21c89d1d.entry.js.map} +0 -0
- /package/dist/md3/{p-2e09a7b7.entry.js.map → p-27135a6b.entry.js.map} +0 -0
- /package/dist/md3/{p-c063c823.entry.js.map → p-2befc42c.entry.js.map} +0 -0
- /package/dist/md3/{p-b34d385b.entry.js.map → p-35b05b45.entry.js.map} +0 -0
- /package/dist/md3/{p-c2dd8c8c.entry.js.map → p-38e9a583.entry.js.map} +0 -0
- /package/dist/md3/{p-3cce1de3.entry.js.map → p-38f82d34.entry.js.map} +0 -0
- /package/dist/md3/{p-be02624e.entry.js.map → p-3c0469aa.entry.js.map} +0 -0
- /package/dist/md3/{p-63b8c8d1.entry.js.map → p-408ee4be.entry.js.map} +0 -0
- /package/dist/md3/{p-3015c7e3.entry.js.map → p-4770b534.entry.js.map} +0 -0
- /package/dist/md3/{p-c5af701b.entry.js.map → p-4ba3623e.entry.js.map} +0 -0
- /package/dist/md3/{p-7b463fbe.entry.js.map → p-4f2e82cb.entry.js.map} +0 -0
- /package/dist/md3/{p-be412e3f.entry.js.map → p-501bf161.entry.js.map} +0 -0
- /package/dist/md3/{p-81843ff7.entry.js.map → p-5929e59c.entry.js.map} +0 -0
- /package/dist/md3/{p-32bdd439.entry.js.map → p-5c35f916.entry.js.map} +0 -0
- /package/dist/md3/{p-ac35ac5f.entry.js.map → p-5db87a9d.entry.js.map} +0 -0
- /package/dist/md3/{p-6038b907.entry.js.map → p-5f39b49d.entry.js.map} +0 -0
- /package/dist/md3/{p-05ae91b6.entry.js.map → p-6bf632c7.entry.js.map} +0 -0
- /package/dist/md3/{p-4e3d6e40.entry.js.map → p-6ea7117d.entry.js.map} +0 -0
- /package/dist/md3/{p-9ddbf247.entry.js.map → p-7112374d.entry.js.map} +0 -0
- /package/dist/md3/{p-1a8ec5bc.entry.js.map → p-7858833e.entry.js.map} +0 -0
- /package/dist/md3/{p-4d82132d.entry.js.map → p-7f53a423.entry.js.map} +0 -0
- /package/dist/md3/{p-b0431a5c.entry.js.map → p-8135c606.entry.js.map} +0 -0
- /package/dist/md3/{p-4dda4cb0.entry.js.map → p-845ca9cc.entry.js.map} +0 -0
- /package/dist/md3/{p-5b74694e.entry.js.map → p-89d47130.entry.js.map} +0 -0
- /package/dist/md3/{p-e3124e1e.entry.js.map → p-8b1ea5dc.entry.js.map} +0 -0
- /package/dist/md3/{p-c10a33c2.entry.js.map → p-8e7df348.entry.js.map} +0 -0
- /package/dist/md3/{p-65195996.entry.js.map → p-925768ac.entry.js.map} +0 -0
- /package/dist/md3/{p-ac8762e5.entry.js.map → p-96c06b24.entry.js.map} +0 -0
- /package/dist/md3/{p-a5fee424.entry.js.map → p-a49df43d.entry.js.map} +0 -0
- /package/dist/md3/{p-da4e27d4.entry.js.map → p-a4d4cfed.entry.js.map} +0 -0
- /package/dist/md3/{p-5394254f.entry.js.map → p-a976498b.entry.js.map} +0 -0
- /package/dist/md3/{p-bf7842f8.entry.js.map → p-adf8a415.entry.js.map} +0 -0
- /package/dist/md3/{p-c861d774.entry.js.map → p-ae360663.entry.js.map} +0 -0
- /package/dist/md3/{p-8eb0b6a4.entry.js.map → p-b243284b.entry.js.map} +0 -0
- /package/dist/md3/{p-45280bf4.entry.js.map → p-b2d88292.entry.js.map} +0 -0
- /package/dist/md3/{p-796f79f8.entry.js.map → p-b3b5247b.entry.js.map} +0 -0
- /package/dist/md3/{p-5b799707.entry.js.map → p-b4266f6b.entry.js.map} +0 -0
- /package/dist/md3/{p-a7ffb779.entry.js.map → p-b7602557.entry.js.map} +0 -0
- /package/dist/md3/{p-6ba63c73.entry.js.map → p-bc24f0c9.entry.js.map} +0 -0
- /package/dist/md3/{p-edb34a6d.entry.js.map → p-bed8dfec.entry.js.map} +0 -0
- /package/dist/md3/{p-50555bb7.entry.js.map → p-c0476406.entry.js.map} +0 -0
- /package/dist/md3/{p-0c2e824d.entry.js.map → p-c20fbb9e.entry.js.map} +0 -0
- /package/dist/md3/{p-4e45b2ff.entry.js.map → p-c58c68d0.entry.js.map} +0 -0
- /package/dist/md3/{p-fc0b325d.entry.js.map → p-cdcea99f.entry.js.map} +0 -0
- /package/dist/md3/{p-0f764a1e.entry.js.map → p-d2e39c6e.entry.js.map} +0 -0
- /package/dist/md3/{p-c1ca6f6c.entry.js.map → p-da0c36d9.entry.js.map} +0 -0
- /package/dist/md3/{p-77a01bcc.entry.js.map → p-e3c37222.entry.js.map} +0 -0
- /package/dist/md3/{p-39cb7c24.entry.js.map → p-e6b09e71.entry.js.map} +0 -0
- /package/dist/md3/{p-b4631a55.entry.js.map → p-eddae19a.entry.js.map} +0 -0
- /package/dist/md3/{p-c6a12344.entry.js.map → p-ef7b1826.entry.js.map} +0 -0
- /package/dist/md3/{p-e6d7f0ff.entry.js.map → p-f403ad20.entry.js.map} +0 -0
- /package/dist/md3/{p-708a9313.entry.js.map → p-f5fd9a0b.entry.js.map} +0 -0
- /package/dist/md3/{p-aa0e7d4d.entry.js.map → p-f71af38f.entry.js.map} +0 -0
- /package/dist/md3/{p-757e3aaf.entry.js.map → p-fac6da4c.entry.js.map} +0 -0
- /package/dist/md3/{p-134b670a.entry.js.map → p-fc864f96.entry.js.map} +0 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function t(t){const s=(t.label||t.getAttribute("label")||t.textContent||"").trim();return{value:t.value??t.getAttribute("value")??"",label:s,disabled:t.disabled??t.hasAttribute("disabled"),icon:t.icon||t.getAttribute("icon")||undefined,iconColor:t.iconColor||t.getAttribute("icon-color")||undefined,supportingText:t.supportingText||t.getAttribute("supporting-text")||undefined,selected:t.selected??t.hasAttribute("selected")}}function s(t){return{value:t.value,label:t.label??t.value,disabled:!!t.disabled,icon:t.icon,iconColor:t.iconColor,supportingText:t.supportingText,selected:!!t.selected}}function i(t){return!Array.isArray(t)}function n(t){if(!i(t))return t.slice();const s=new Array(t.count);for(let i=0;i<t.count;i++)s[i]=t.getRow(i);return s}function e(t){return t.map(s)}function h(i,n){const e=Array.from(i.children).filter((t=>t.tagName.toLowerCase()==="md-select-option"));if(e.length>0){return e.map(t)}return(n??[]).map(s)}function o(t,s){return t.find((t=>t.value===s))?.label??""}const r=15e5;function c(t,s,i,n,e,h=r,o=-1){if(n<=0||i<=0||s<=0){const t=n>0&&i>0?n*i:0;return{start:0,end:0,topPad:0,bottomPad:t,scrollHeight:t,scrollTop:0}}const c=n*i;const a=Math.ceil(s/i);if(c<=h){const h=Math.min(Math.max(0,t),Math.max(0,c-s));const o=Math.floor(h/i);const r=Math.min(n,Math.max(0,o-e));const u=Math.min(n,Math.max(r,o+a+e));return{start:r,end:u,topPad:r*i,bottomPad:Math.max(0,(n-u)*i),scrollHeight:c,scrollTop:h}}const u=h;const f=Math.max(1,u-s);const l=Math.max(0,n-a);if(o>=0){const t=Math.min(l,o);const s=Math.min(e,t);const h=t-s;const r=Math.min(n,t+a+e);const c=(r-h)*i;const d=s*i;const M=Math.round(t/Math.max(1,l)*f);const m=Math.max(d,Math.min(f,M));const b=m-s*i;const p=Math.max(0,u-b-c);return{start:h,end:r,topPad:b,bottomPad:p,scrollHeight:u,scrollTop:m}}const d=Math.min(Math.max(0,t),f);const M=Math.round(d/f*l);const m=Math.min(e,M,Math.floor(d/i));const b=M-m;const p=Math.min(n,M+a+e);const w=(p-b)*i;const y=Math.max(0,u-w);let A=d-m*i;if(A<0)A=0;else if(A>y)A=y;const g=Math.max(0,u-A-w);return{start:b,end:p,topPad:A,bottomPad:g,scrollHeight:u,scrollTop:d}}const a=0;function u(t){if(typeof atob==="function"){const s=atob(t);const i=new Uint8Array(s.length);for(let t=0;t<s.length;t++)i[t]=s.charCodeAt(t);return i}return Uint8Array.from(Buffer.from(t,"base64"))}let f;async function l(){f??(f=import("./p-CfBPnYW7.js").then((({WASM_BASE64:t})=>WebAssembly.compile(u(t)))));const t=await f;const s={env:{abort(){},trace(){},seed(){return Date.now()}}};const i=await WebAssembly.instantiate(t,s);return i.exports}const d={substring:0,prefix:1,fuzzy:2};const M=1;const m=6;const b=2048;const p=typeof performance!=="undefined"&&typeof performance.now==="function"?()=>performance.now():()=>Date.now();function w(){const t=globalThis.scheduler;if(t?.yield)return t.yield();return new Promise((t=>setTimeout(t,0)))}const y=12;async function A(t){if(typeof requestAnimationFrame==="function"&&p()-t.t>=y){await new Promise((t=>{requestAnimationFrame((()=>setTimeout(t,0)))}));t.t=p();return}await w()}function g(){return typeof WebAssembly!=="undefined"&&typeof WebAssembly.instantiate==="function"}function P(t){let s=0;for(let i=0;i<t.length;i++){const n=t.charCodeAt(i);if(n<128){s+=1}else if(n<2048){s+=2}else if(n>=55296&&n<=56319){const n=t.charCodeAt(i+1);if(n>=56320&&n<=57343){s+=4;i++}else{s+=3}}else{s+=3}}return s}class x{constructor(){this.enc=new TextEncoder;this.dec=new TextDecoder;this._length=0;this._total=0;this.mode=a}ensureReady(){if(!this.ready){this.ready=g()?l().then((t=>{this.engine=t})):Promise.reject(new Error("WebAssembly is not available in this environment"))}return this.ready}get ready$(){return!!this.engine}get length(){return this._length}get total(){return this._total}setFilterMode(t){this.mode=d[t]??a}mem(){return new Uint8Array(this.engine.memory.buffer)}async load(t){await this.ensureReady();const s=this.engine;let n;let e;if(i(t)){n=t.count;e=t.getRow}else{n=t.length;e=s=>t[s]}const h={t:p()};let o=0;let r=0;let c=0;let a=0;for(let t=0;t<n;){const s=p();do{const s=Math.min(n,t+b);for(;t<s;t++){const s=e(t);o+=P(s.value);r+=P(s.label??s.value);if(s.icon)c+=P(s.icon);if(s.supportingText)a+=P(s.supportingText)}}while(t<n&&p()-s<m);if(t<n)await A(h)}s.reserve(n,o,r,c,a);for(let t=0;t<n;){const i=p();const o=this.mem();do{const i=Math.min(n,t+b);for(;t<i;t++){const i=e(t);const n=s.valueWritePtr();const h=this.enc.encodeInto(i.value,o.subarray(n));const r=s.labelWritePtr();const u=this.enc.encodeInto(i.label??i.value,o.subarray(r));const f=s.iconWritePtr();const l=c>0?this.enc.encodeInto(i.icon??"",o.subarray(f)):null;const d=s.supportWritePtr();const m=a>0?this.enc.encodeInto(i.supportingText??"",o.subarray(d)):null;s.appendRow(h.written??0,u.written??0,l?.written??0,m?.written??0,i.disabled?M:0)}}while(t<n&&p()-i<m);if(t<n)await A(h)}s.finalizeLoad();this._total=s.totalCount();this._length=s.filteredCount()}writeScratch(t){const s=this.engine;const i=s.queryCapacity();const n=s.queryPtr();const{written:e}=this.enc.encodeInto(t,this.mem().subarray(n,n+i));return e??0}setQuery(t){if(!this.engine)return 0;const s=this.writeScratch(t);this._length=this.engine.setQuery(s,this.mode);return this._length}decodeRow(t,s){const i=this.engine;const n=i.valuePtr(t);const e=i.valueLen(t);const h=i.labelPtr(t);const o=i.labelLen(t);const r=i.iconPtr(t);const c=i.iconLen(t);const a=i.supportPtr(t);const u=i.supportLen(t);return{index:t,value:this.dec.decode(s.subarray(n,n+e)),label:this.dec.decode(s.subarray(h,h+o)),disabled:(i.rowFlags(t)&M)!==0,icon:c>0?this.dec.decode(s.subarray(r,r+c)):"",supportingText:u>0?this.dec.decode(s.subarray(a,a+u)):""}}getWindow(t,s){if(!this.engine)return[];const i=this.engine;const n=this.mem();const e=[];const h=Math.max(0,t);const o=Math.min(this._length,t+s);for(let t=h;t<o;t++){const s=i.rowAt(t);if(s>=0)e.push(this.decodeRow(s,n))}return e}getRow(t){if(!this.engine)return null;const s=this.engine.rowAt(t);if(s<0)return null;return this.decodeRow(s,this.mem())}rowAt(t){return this.engine?this.engine.rowAt(t):-1}disabledAt(t){if(!this.engine)return false;const s=this.engine.rowAt(t);if(s<0)return false;return(this.engine.rowFlags(s)&M)!==0}labelAt(t){if(!this.engine)return"";const s=this.engine.rowAt(t);if(s<0)return"";const i=this.engine.labelPtr(s);const n=this.engine.labelLen(s);return this.dec.decode(this.mem().subarray(i,i+n))}getLabels(t){const s=new Map;if(!this.engine)return s;const i=this.engine;for(const n of t){const t=this.writeScratch(n);const e=i.indexOfValue(t);if(e>=0){const t=i.labelPtr(e);const h=i.labelLen(e);s.set(n,this.dec.decode(this.mem().subarray(t,t+h)))}}return s}has(t){if(!this.engine)return false;return this.engine.indexOfValue(this.writeScratch(t))>=0}findLabelPrefix(t,s){if(!this.engine)return-1;const i=this.writeScratch(t);return this.engine.findLabelPrefix(i,s)}reset(){this.engine?.reset();this._length=0;this._total=0}}const F=1e6;const T=8;const v=48;const W=320;const q=0;class H{constructor(t){this.host=t;this.store=new x;this.active=false;this.windowStart=0;this.windowRows=[];this.topPad=0;this.bottomPad=0;this.filteredLength=0;this.rowHeight=v;this.scrollRaf=0;this.browserMaxScroll=Infinity;this.intendedScrollHeight=0;this.detectRaf=0;this.detectRetries=0;this.navAnchorFirstRow=-1;this.usedScrollTop=0;this.onScroll=()=>{if(this.scrollRaf)return;this.scrollRaf=requestAnimationFrame((()=>{this.scrollRaf=0;const t=this.viewportEl;if(!t)return;if(this.navAnchorFirstRow>=0&&Math.abs(t.scrollTop-this.usedScrollTop)<=1){return}this.navAnchorFirstRow=-1;this.recompute(t.scrollTop)}))};this.provider={count:()=>this.filteredLength,labelAt:t=>this.store.labelAt(t),isDisabledAt:t=>this.store.disabledAt(t),ensureVisible:t=>this.ensureVisible(t),domItemForIndex:t=>this.host.queryItem(t),findPrefix:(t,s)=>this.store.findLabelPrefix(t,s)}}effectiveMaxScroll(){return Math.min(r,this.browserMaxScroll)}setFixedRowHeight(t){this.fixedRowHeight=t&&t>0?t:undefined;if(this.fixedRowHeight)this.rowHeight=this.fixedRowHeight}setFilterMode(t){this.store.setFilterMode(t)}async load(t){const s=i(t)?t.count:t.length;if(!g()||s===0)return false;try{await this.store.ensureReady()}catch{return false}await this.store.load(t);this.active=true;this.filteredLength=this.store.length;this.recompute(this.viewportEl?.scrollTop??0);return true}setQuery(t){if(!this.active)return;this.filteredLength=this.store.setQuery(t);this.navAnchorFirstRow=-1;if(this.viewportEl)this.viewportEl.scrollTop=0;this.recompute(0)}getLabels(t){return this.store.getLabels(t)}reset(){this.store.reset();this.active=false;this.windowRows=[];this.filteredLength=0;this.windowStart=0;this.topPad=0;this.bottomPad=0;this.navAnchorFirstRow=-1}async attachViewport(t){this.detachViewport();const s=await t();this.viewportEl=s??undefined;if(this.viewportEl){this.viewportEl.addEventListener("scroll",this.onScroll,{passive:true});this.measureRowHeight();this.recompute(this.viewportEl.scrollTop);this.detectRetries=60;this.detectScrollCap()}}detachViewport(){if(this.scrollRaf){cancelAnimationFrame(this.scrollRaf);this.scrollRaf=0}if(this.detectRaf){cancelAnimationFrame(this.detectRaf);this.detectRaf=0}this.viewportEl?.removeEventListener("scroll",this.onScroll);this.viewportEl=undefined}measureRowHeight(){if(this.fixedRowHeight){this.rowHeight=this.fixedRowHeight;return}const t=this.host.queryItem(this.windowStart);const s=t?.offsetHeight??0;if(s>0&&s!==this.rowHeight){this.rowHeight=s;if(this.viewportEl)this.recompute(this.viewportEl.scrollTop)}}recompute(t){const s=this.viewportEl?.clientHeight||W;const i=c(t,s,this.rowHeight,this.filteredLength,T,this.effectiveMaxScroll(),this.navAnchorFirstRow);this.windowStart=i.start;this.topPad=i.topPad;this.bottomPad=i.bottomPad;this.intendedScrollHeight=i.scrollHeight;this.usedScrollTop=i.scrollTop;this.windowRows=this.store.getWindow(i.start,i.end-i.start);this.host.requestRender()}detectScrollCap(){if(this.detectRaf)cancelAnimationFrame(this.detectRaf);this.detectRaf=requestAnimationFrame((()=>{this.detectRaf=requestAnimationFrame((()=>{this.detectRaf=0;const t=this.viewportEl;if(!t)return;const s=t.scrollHeight;if(s>0&&s+2<this.intendedScrollHeight&&s<this.browserMaxScroll){if(s<F){if(this.detectRetries-- >0)this.detectScrollCap();return}this.browserMaxScroll=s;this.recompute(t.scrollTop)}}))}))}async ensureVisible(t){const s=this.viewportEl;if(!s)return;const i=s.clientHeight||W;const n=this.filteredLength*this.rowHeight;if(n<=this.effectiveMaxScroll()){this.navAnchorFirstRow=-1;const n=t*this.rowHeight;const e=n+this.rowHeight;const h=Math.max(0,s.scrollHeight-i);if(n-q<s.scrollTop){s.scrollTop=Math.max(0,n-q)}else if(e+q>s.scrollTop+i){s.scrollTop=Math.min(h,e+q-i)}this.recompute(s.scrollTop)}else{const n=Math.max(1,Math.floor(i/this.rowHeight));const e=Math.ceil(i/this.rowHeight);const h=Math.max(0,this.filteredLength-e);const o=this.navAnchorFirstRow>=0?this.navAnchorFirstRow:this.windowStart+Math.max(0,Math.round((s.scrollTop-this.topPad)/this.rowHeight));const r=o+n-1;const c=Math.ceil(q/this.rowHeight);if(t<o+c||t>r-c){this.navAnchorFirstRow=Math.min(h,Math.max(0,t<o+c?t-c:t-n+1+c))}this.recompute(s.scrollTop);if(this.navAnchorFirstRow>=0){const t=Math.max(0,s.scrollHeight-i);const n=Math.min(Math.round(this.usedScrollTop),t);if(n!==Math.round(s.scrollTop)){s.scrollTop=n}this.usedScrollTop=s.scrollTop}}for(let s=0;s<8;s++){await new Promise((t=>requestAnimationFrame((()=>t()))));if(this.host.queryItem(t))return}}}export{H as V,h as c,g as i,o as l,e as n,n as r};
|
|
2
|
+
//# sourceMappingURL=p-Bz-JaJcA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["fromElement","el","label","getAttribute","textContent","trim","value","disabled","hasAttribute","icon","undefined","iconColor","supportingText","selected","fromInit","o","isRowSource","source","Array","isArray","rowsToArray","slice","out","count","i","getRow","normalizeInits","inits","map","collectOptions","host","optionsProp","slotted","from","children","filter","c","tagName","toLowerCase","length","labelFor","options","find","DEFAULT_MAX_SCROLL_HEIGHT","computeWindow","scrollTop","viewportHeight","rowHeight","total","overscan","maxScrollHeight","anchorFirstRow","realHeight","start","end","topPad","bottomPad","scrollHeight","visibleCount","Math","ceil","clamped","min","max","firstVisible","floor","maxScrollTop","maxFirstRow","firstVisibleRow","aboveRows","blockHeight","lo","proportional","round","usedScrollTop","maxTop","FILTER_SUBSTRING","decodeBase64","b64","atob","bin","Uint8Array","charCodeAt","Buffer","modulePromise","async","instantiateEngine","import","then","WASM_BASE64","WebAssembly","compile","module","imports","env","abort","trace","seed","Date","now","instance","instantiate","exports","FILTER_MODE","substring","prefix","fuzzy","DISABLED_FLAG","LOAD_SLICE_BUDGET_MS","LOAD_STRIDE","nowMs","performance","yieldToMain","scheduler","globalThis","yield","Promise","resolve","setTimeout","PAINT_INTERVAL_MS","yieldForPaint","lastPaint","requestAnimationFrame","t","isWasmSupported","utf8ByteLength","str","bytes","next","WasmOptionStore","constructor","this","enc","TextEncoder","dec","TextDecoder","_length","_total","mode","ensureReady","ready","e","engine","reject","Error","ready$","setFilterMode","mem","memory","buffer","load","at","valueBytesTotal","labelBytesTotal","iconBytesTotal","supportBytesTotal","sliceStart","r","reserve","vp","valueWritePtr","v","encodeInto","subarray","lp","labelWritePtr","l","ip","iconWritePtr","ic","sp","supportWritePtr","sc","appendRow","written","finalizeLoad","totalCount","filteredCount","writeScratch","s","cap","queryCapacity","ptr","queryPtr","setQuery","query","len","decodeRow","absIndex","valuePtr","vl","valueLen","labelPtr","ll","labelLen","iconPtr","il","iconLen","supportPtr","sl","supportLen","index","decode","rowFlags","getWindow","to","fi","abs","rowAt","push","filteredIndex","disabledAt","labelAt","getLabels","values","result","Map","indexOfValue","set","has","findLabelPrefix","fromFilteredIndex","reset","MIN_PLAUSIBLE_SCROLL_CAP","OVERSCAN","DEFAULT_ROW_HEIGHT","DEFAULT_VIEWPORT_HEIGHT","EDGE_SCRIM_PAD","VirtualSelectController","store","active","windowStart","windowRows","filteredLength","scrollRaf","browserMaxScroll","Infinity","intendedScrollHeight","detectRaf","detectRetries","navAnchorFirstRow","onScroll","viewportEl","recompute","provider","isDisabledAt","ensureVisible","domItemForIndex","queryItem","findPrefix","effectiveMaxScroll","setFixedRowHeight","px","fixedRowHeight","attachViewport","getViewport","detachViewport","addEventListener","passive","measureRowHeight","detectScrollCap","cancelAnimationFrame","removeEventListener","first","h","offsetHeight","vpH","clientHeight","calc","requestRender","measured","clientH","top","bottom","maxScroll","visibleRows","lastVisible","padRows","target","tries"],"sources":["src/utils/select-options.ts","src/utils/virtual-window.ts","src/wasm/engine-abi.ts","src/utils/wasm-option-store.ts","src/utils/virtual-select-controller.ts"],"sourcesContent":["/**\n * Shared option model + reader for `md-select` / `md-multi-select`.\n *\n * Both components accept options two ways (decided by the consumer):\n * 1. Declarative slotted `<md-select-option>` children (primary API —\n * framework-friendly, supports rich labels + per-option icons).\n * 2. A programmatic `options` array prop (data-driven lists).\n *\n * `collectOptions()` normalises either source into a single flat\n * `SelectOptionData[]` the pickers render into `md-menu-item`s. When\n * slotted children are present they take precedence; otherwise the\n * array prop is used. This keeps the result predictable (no silent\n * duplication when a consumer accidentally supplies both).\n */\n\n/** Normalised option the pickers render. */\nexport interface SelectOptionData {\n /** Stable identifier — emitted in the picker `value` and used for matching. */\n value: string;\n /** Visible label rendered in the menu, chips, and the trigger text. */\n label: string;\n /** Disabled options stay visible but cannot be selected. */\n disabled: boolean;\n /** Optional Material Symbols leading-icon glyph. */\n icon?: string;\n /** Optional CSS colour applied to the leading icon (e.g. a status/swatch hue).\n * Any CSS `<color>` — hex, `rgb()`, or a theme token like\n * `var(--md-sys-color-primary)`. Ignored when the option has no `icon`, and\n * not carried on the virtualized (WASM) path — huge datasets fall back to the\n * `--md-{multi-}select-option-icon-color` token. */\n iconColor?: string;\n /** Optional secondary text rendered under the label in the menu. */\n supportingText?: string;\n /** Initial-selected hint carried by the option element / array entry. */\n selected?: boolean;\n}\n\n/** Programmatic option entry accepted by the `options` array prop. */\nexport interface SelectOptionInit {\n value: string;\n label?: string;\n disabled?: boolean;\n icon?: string;\n iconColor?: string;\n supportingText?: string;\n selected?: boolean;\n}\n\n/** Element-side shape of a slotted `<md-select-option>`. */\ninterface SelectOptionEl extends HTMLElement {\n value?: string;\n label?: string;\n disabled?: boolean;\n icon?: string;\n iconColor?: string;\n supportingText?: string;\n selected?: boolean;\n}\n\nfunction fromElement(el: SelectOptionEl): SelectOptionData {\n const label = (el.label || el.getAttribute('label') || el.textContent || '').trim();\n return {\n value: el.value ?? el.getAttribute('value') ?? '',\n label,\n disabled: el.disabled ?? el.hasAttribute('disabled'),\n icon: el.icon || el.getAttribute('icon') || undefined,\n iconColor: el.iconColor || el.getAttribute('icon-color') || undefined,\n supportingText:\n el.supportingText || el.getAttribute('supporting-text') || undefined,\n selected: el.selected ?? el.hasAttribute('selected'),\n };\n}\n\nfunction fromInit(o: SelectOptionInit): SelectOptionData {\n return {\n value: o.value,\n label: o.label ?? o.value,\n disabled: !!o.disabled,\n icon: o.icon,\n iconColor: o.iconColor,\n supportingText: o.supportingText,\n selected: !!o.selected,\n };\n}\n\n/**\n * A dataset given as a row factory rather than a materialised array, so very\n * large option sets (tens of millions) can be streamed into the WASM store\n * without ever holding the whole array in JS at once.\n */\nexport interface OptionRowSource {\n count: number;\n getRow: (index: number) => SelectOptionInit;\n}\n\n/**\n * Type guard distinguishing a row factory from a materialised array.\n * (`Array.isArray` doesn't narrow a `readonly[]` union, so this is explicit.)\n */\nexport function isRowSource(\n source: ReadonlyArray<SelectOptionInit> | OptionRowSource,\n): source is OptionRowSource {\n return !Array.isArray(source);\n}\n\n/** Materialise a row source (array or factory) into a plain array. */\nexport function rowsToArray(\n source: ReadonlyArray<SelectOptionInit> | OptionRowSource,\n): SelectOptionInit[] {\n if (!isRowSource(source)) return source.slice();\n const out = new Array<SelectOptionInit>(source.count);\n for (let i = 0; i < source.count; i++) out[i] = source.getRow(i);\n return out;\n}\n\n/** Normalise a programmatic `options` array to `SelectOptionData[]`. */\nexport function normalizeInits(inits: ReadonlyArray<SelectOptionInit>): SelectOptionData[] {\n return inits.map(fromInit);\n}\n\n/**\n * Read the option set for a picker host. Slotted `<md-select-option>`\n * children win when present; otherwise the `options` array is used.\n */\nexport function collectOptions(\n host: HTMLElement,\n optionsProp?: SelectOptionInit[],\n): SelectOptionData[] {\n // Direct light-DOM children only (avoids `:scope`, which mock-doc/older\n // engines don't support, and avoids reaching into nested option groups).\n const slotted = Array.from(host.children).filter(\n (c) => c.tagName.toLowerCase() === 'md-select-option',\n ) as SelectOptionEl[];\n\n if (slotted.length > 0) {\n return slotted.map(fromElement);\n }\n return (optionsProp ?? []).map(fromInit);\n}\n\n/** Label for a single value, or '' if not found. */\nexport function labelFor(options: SelectOptionData[], value: string): string {\n return options.find((o) => o.value === value)?.label ?? '';\n}\n","/**\n * Fixed-row-height virtual windowing math, shared by the virtualized selects.\n *\n * Pure and DOM-free so it can be unit-tested directly. Given the scroll offset\n * and viewport size, it returns the slice of rows to render plus the spacer\n * heights that make the scroll container behave as if every row were present.\n *\n * Two regimes:\n * - Exact: when the full list height fits under `maxScrollHeight`, the spacers\n * reproduce the real height 1:1 and the offset maps to a row directly.\n * - Scaled: when the list is taller than a browser can lay out (millions of\n * rows × row height easily exceeds the ~16–33M px element-height cap), the\n * spacers reproduce a *capped* height and the scroll offset maps\n * proportionally onto the row range. The rendered block is always\n * positioned to cover the viewport, so the list never shows blank rows and\n * can be scrolled all the way to the end.\n */\nexport interface WindowCalc {\n /** First filtered index to render (inclusive), overscan applied. */\n start: number;\n /** One past the last filtered index to render (exclusive). */\n end: number;\n /** Spacer height (px) before the first rendered row. */\n topPad: number;\n /** Spacer height (px) after the last rendered row. */\n bottomPad: number;\n /** Total scrollable height the spacers reproduce (topPad + rows + bottomPad). */\n scrollHeight: number;\n /**\n * The scroll offset this window is laid out for. Equal to the input scrollTop\n * for mouse-driven windows; for an anchored (keyboard-nav) window it is the\n * offset the caller should apply so the anchor row lands at the viewport top.\n */\n scrollTop: number;\n}\n\n/**\n * Default ceiling on the scrollable height. Comfortably under every major\n * browser's maximum element height (Firefox ~17.9M, Chrome ~33.5M) so the\n * spacers always lay out, while still giving smooth scroll resolution for\n * millions of rows. The controller can lower this further at runtime if it\n * detects the browser clamping even shorter.\n */\nexport const DEFAULT_MAX_SCROLL_HEIGHT = 1_500_000;\n\nexport function computeWindow(\n scrollTop: number,\n viewportHeight: number,\n rowHeight: number,\n total: number,\n overscan: number,\n maxScrollHeight: number = DEFAULT_MAX_SCROLL_HEIGHT,\n // In the scaled regime, pin the first rendered row to this index instead of\n // deriving it from the scroll fraction. Keyboard nav uses this because integer\n // scrollTop is too coarse to address individual rows in a multi-million list.\n anchorFirstRow: number = -1,\n): WindowCalc {\n if (total <= 0 || rowHeight <= 0 || viewportHeight <= 0) {\n const realHeight = total > 0 && rowHeight > 0 ? total * rowHeight : 0;\n return { start: 0, end: 0, topPad: 0, bottomPad: realHeight, scrollHeight: realHeight, scrollTop: 0 };\n }\n\n const realHeight = total * rowHeight;\n const visibleCount = Math.ceil(viewportHeight / rowHeight);\n\n // ── Exact regime: the list fits, spacers mirror the real height. ──\n if (realHeight <= maxScrollHeight) {\n const clamped = Math.min(Math.max(0, scrollTop), Math.max(0, realHeight - viewportHeight));\n const firstVisible = Math.floor(clamped / rowHeight);\n const start = Math.min(total, Math.max(0, firstVisible - overscan));\n const end = Math.min(total, Math.max(start, firstVisible + visibleCount + overscan));\n return {\n start,\n end,\n topPad: start * rowHeight,\n bottomPad: Math.max(0, (total - end) * rowHeight),\n scrollHeight: realHeight,\n scrollTop: clamped,\n };\n }\n\n // ── Scaled regime: list taller than `maxScrollHeight`. ──\n const scrollHeight = maxScrollHeight;\n const maxScrollTop = Math.max(1, scrollHeight - viewportHeight);\n const maxFirstRow = Math.max(0, total - visibleCount);\n\n if (anchorFirstRow >= 0) {\n // Keyboard nav: position the anchor row at the viewport top and *derive* the\n // scroll offset to match. Integer scrollTop is too coarse to address single\n // rows near the ends of a multi-million-row list, so we treat the offset as\n // an output (the caller applies `scrollTop`) instead of an input. This is\n // what makes ArrowDown/ArrowUp keep advancing past the rendered window.\n const firstVisibleRow = Math.min(maxFirstRow, anchorFirstRow);\n const aboveRows = Math.min(overscan, firstVisibleRow);\n const start = firstVisibleRow - aboveRows;\n const end = Math.min(total, firstVisibleRow + visibleCount + overscan);\n const blockHeight = (end - start) * rowHeight;\n // Use the SAME proportional row↔offset mapping as the mouse-scroll branch\n // below, so a given offset uniquely identifies the anchor row and re-deriving\n // the window from `scrollTop` (when the anchor is dropped) lands on the same\n // row. We deliberately do NOT pull the offset up to bottom-align the block\n // near the end (an earlier `hi` clamp did): that collapsed many adjacent\n // anchors onto one integer offset, so a single stray scroll event would\n // re-map that offset proportionally and teleport the view thousands of rows\n // (ArrowUp \"jumping\" near the bottom of a huge list). `lo` still keeps\n // topPad ≥ 0 near the very top. The block may now extend a few hundred px\n // past the nominal cap at the very end; we clamp `bottomPad` to ≥ 0 and let\n // the real content height absorb the remainder — negligible against\n // `scrollHeight`, and the offset stays reachable.\n const lo = aboveRows * rowHeight;\n const proportional = Math.round((firstVisibleRow / Math.max(1, maxFirstRow)) * maxScrollTop);\n const usedScrollTop = Math.max(lo, Math.min(maxScrollTop, proportional));\n const topPad = usedScrollTop - aboveRows * rowHeight;\n const bottomPad = Math.max(0, scrollHeight - topPad - blockHeight);\n return { start, end, topPad, bottomPad, scrollHeight, scrollTop: usedScrollTop };\n }\n\n // Mouse scroll: the browser's scrollTop is authoritative; map it onto the row\n // range and seat the block so the first visible row lands at the viewport top\n // (overscan above limited to the room the offset leaves, so topPad stays ≥ 0).\n const clamped = Math.min(Math.max(0, scrollTop), maxScrollTop);\n const firstVisibleRow = Math.round((clamped / maxScrollTop) * maxFirstRow);\n const aboveRows = Math.min(overscan, firstVisibleRow, Math.floor(clamped / rowHeight));\n const start = firstVisibleRow - aboveRows;\n const end = Math.min(total, firstVisibleRow + visibleCount + overscan);\n const blockHeight = (end - start) * rowHeight;\n const maxTop = Math.max(0, scrollHeight - blockHeight);\n let topPad = clamped - aboveRows * rowHeight;\n if (topPad < 0) topPad = 0;\n else if (topPad > maxTop) topPad = maxTop;\n const bottomPad = Math.max(0, scrollHeight - topPad - blockHeight);\n\n return { start, end, topPad, bottomPad, scrollHeight, scrollTop: clamped };\n}\n","/**\n * Hand-written ABI surface for the WASM option engine.\n *\n * `engine.wasm.ts` (the base64 blob) is generated by scripts/build-wasm.mjs;\n * this file is the stable, committed wrapper the rest of the codebase imports.\n * Keep `EngineExports` in sync with the exports of `engine.ts`.\n *\n * The blob is imported DYNAMICALLY inside instantiateEngine() rather than at\n * module top level: the engine only ever instantiates above the virtualization\n * threshold (200+ options), but a static import made every consumer of\n * md-select/md-autocomplete/md-multi-select/md-table-pagination ship the\n * ~11 kB base64 string (5.6 kB gz) eagerly. As a dynamic import the bundler\n * emits it as its own async chunk, fetched only if virtualization engages.\n */\n\n/** Filter modes accepted by `setQuery` (mirrors engine.ts). */\nexport const FILTER_SUBSTRING = 0;\nexport const FILTER_PREFIX = 1;\nexport const FILTER_FUZZY = 2;\n\n/** The functions exported by the compiled WASM engine. */\nexport interface EngineExports {\n memory: WebAssembly.Memory;\n reserve(\n rows: number,\n valueBytesTotal: number,\n labelBytesTotal: number,\n iconBytesTotal: number,\n supportBytesTotal: number,\n ): void;\n valueWritePtr(): number;\n labelWritePtr(): number;\n iconWritePtr(): number;\n supportWritePtr(): number;\n appendRow(\n valueLen: number,\n labelLen: number,\n iconLen: number,\n supportLen: number,\n flags: number,\n ): number;\n finalizeLoad(): void;\n queryPtr(): number;\n queryCapacity(): number;\n setQuery(queryLen: number, mode: number): number;\n totalCount(): number;\n filteredCount(): number;\n rowAt(filteredIndex: number): number;\n valuePtr(absIndex: number): number;\n valueLen(absIndex: number): number;\n labelPtr(absIndex: number): number;\n labelLen(absIndex: number): number;\n iconPtr(absIndex: number): number;\n iconLen(absIndex: number): number;\n supportPtr(absIndex: number): number;\n supportLen(absIndex: number): number;\n rowFlags(absIndex: number): number;\n indexOfValue(queryLen: number): number;\n findLabelPrefix(queryLen: number, fromFilteredIndex: number): number;\n reset(): void;\n}\n\nfunction decodeBase64(b64: string): Uint8Array {\n if (typeof atob === 'function') {\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n }\n // Node without a global atob (older runtimes / spec env).\n return Uint8Array.from(Buffer.from(b64, 'base64'));\n}\n\n/**\n * Compiled once per process — the module bytes never change, and every\n * consumer gets its own isolated instance (fresh memory) below. Without this\n * cache each component instance re-decoded and recompiled the same module.\n */\nlet modulePromise: Promise<WebAssembly.Module> | undefined;\n\n/**\n * Lazily instantiate the engine. The compiled module is a few KB; consumers\n * load their (potentially millions of) rows into its memory at runtime.\n */\nexport async function instantiateEngine(): Promise<EngineExports> {\n modulePromise ??= import('./engine.wasm').then(({ WASM_BASE64 }) =>\n WebAssembly.compile(decodeBase64(WASM_BASE64)),\n );\n const module = await modulePromise;\n const imports = {\n env: {\n abort() {},\n trace() {},\n seed() {\n return Date.now();\n },\n },\n };\n const instance = await WebAssembly.instantiate(module, imports);\n return instance.exports as unknown as EngineExports;\n}\n","/**\n * `WasmOptionStore` — the single integration point both `md-select` and\n * `md-multi-select` use for virtualized, WASM-backed option data.\n *\n * It hides the engine ABI entirely (see `wasm/engine-abi.ts`): the dataset is\n * packed into WASM linear memory at `load()` time and JS keeps no copy, so a\n * select can hold millions of options while only ever decoding the ~visible\n * window back out per render. Filtering/typeahead run inside WASM.\n *\n * One instance per component → one `WebAssembly.Instance` → isolated memory.\n */\nimport {\n EngineExports,\n FILTER_SUBSTRING,\n instantiateEngine,\n} from '../wasm/engine-abi';\nimport { isRowSource, OptionRowSource, SelectOptionInit } from './select-options';\n\n/** A row read back out of the store for rendering. */\nexport interface VirtualRow {\n /** Absolute row index in the dataset (stable across filtering). */\n index: number;\n value: string;\n label: string;\n disabled: boolean;\n /** Material Symbols leading-icon glyph, or '' when the dataset has no icons. */\n icon: string;\n /** Secondary line under the label, or '' when the dataset has no supporting text. */\n supportingText: string;\n}\n\n/** Filter strategy, mapped to the engine's `setQuery` mode. */\nexport type FilterMode = 'substring' | 'prefix' | 'fuzzy';\n\nconst FILTER_MODE: Record<FilterMode, number> = {\n substring: 0,\n prefix: 1,\n fuzzy: 2,\n};\n\nconst DISABLED_FLAG = 1;\n\n/**\n * Time budget (ms) for one main-thread slice while packing. Bounding every\n * slice to roughly a frame keeps busy animations (the loading indicator)\n * fluid during multi-million-row loads — a fixed row-count chunk (formerly\n * 250k rows) blocked 100ms+ per chunk and dropped the spinner to ~7fps.\n */\nconst LOAD_SLICE_BUDGET_MS = 6;\n\n/** Rows between clock reads inside a slice (amortises performance.now()).\n * Small enough that one stride stays well inside the slice budget even with\n * an expensive consumer getRow (~1.4µs/row measured → ~3ms per stride). */\nconst LOAD_STRIDE = 2_048;\n\n/** Millisecond clock that also works in non-DOM (spec) environments. */\nconst nowMs: () => number =\n typeof performance !== 'undefined' && typeof performance.now === 'function'\n ? () => performance.now()\n : () => Date.now();\n\n/** Yield to the event loop so the browser can handle input mid-load. NB:\n * scheduler.yield() continuations PREEMPT rendering, so this alone does not\n * produce paints — see yieldForPaint(). */\nfunction yieldToMain(): Promise<void> {\n const scheduler = (globalThis as { scheduler?: { yield?: () => Promise<void> } }).scheduler;\n if (scheduler?.yield) return scheduler.yield();\n return new Promise((resolve) => setTimeout(resolve, 0));\n}\n\n/**\n * Work window between paint yields. Deliberately UNDER a 60Hz frame (16.7ms):\n * we resume ~1ms after a paint, so a 16ms window would finish just past the\n * next vsync and miss it (measured: alternating 17/33ms gaps → 25ms average).\n * 12ms of work + up to a stride of overshoot still lands the rAF request\n * before the deadline, giving a consistent ~16.7ms cadence.\n */\nconst PAINT_INTERVAL_MS = 12;\n\n/**\n * Yield in a way that guarantees the browser can PAINT when a frame is due —\n * scheduler.yield continuations outprioritise rendering, which froze the\n * loading animation to ~10fps during multi-million-row packs. When a frame is\n * due, await requestAnimationFrame (a real rendering opportunity); otherwise\n * take the cheap yield.\n */\nasync function yieldForPaint(lastPaint: { t: number }): Promise<void> {\n if (\n typeof requestAnimationFrame === 'function' &&\n nowMs() - lastPaint.t >= PAINT_INTERVAL_MS\n ) {\n // Resume AFTER the paint, not inside the rAF callback: resolving in rAF\n // would continue the pack as a microtask still inside the rendering-steps\n // task — the paint would then wait behind the next 16ms of work (measured\n // as ~33ms frame gaps). rAF marks the frame; the nested macrotask lands\n // once rendering has actually flushed.\n await new Promise<void>((resolve) => {\n requestAnimationFrame(() => setTimeout(resolve, 0));\n });\n lastPaint.t = nowMs();\n return;\n }\n await yieldToMain();\n}\n\n/** True when this runtime can host the engine (false in non-WASM SSR/test envs). */\nexport function isWasmSupported(): boolean {\n return typeof WebAssembly !== 'undefined' && typeof WebAssembly.instantiate === 'function';\n}\n\n/**\n * UTF-8 byte length of a string, matching `TextEncoder` semantics (lone\n * surrogates count as the 3-byte U+FFFD replacement). Allocation-free, so the\n * load sizing pass over millions of rows stays cheap.\n */\nexport function utf8ByteLength(str: string): number {\n let bytes = 0;\n for (let i = 0; i < str.length; i++) {\n const c = str.charCodeAt(i);\n if (c < 0x80) {\n bytes += 1;\n } else if (c < 0x800) {\n bytes += 2;\n } else if (c >= 0xd800 && c <= 0xdbff) {\n const next = str.charCodeAt(i + 1);\n if (next >= 0xdc00 && next <= 0xdfff) {\n bytes += 4;\n i++;\n } else {\n bytes += 3; // lone high surrogate → U+FFFD\n }\n } else {\n bytes += 3; // BMP ≥ 0x800, or lone low surrogate → U+FFFD\n }\n }\n return bytes;\n}\n\nexport class WasmOptionStore {\n private engine?: EngineExports;\n private ready?: Promise<void>;\n private enc = new TextEncoder();\n private dec = new TextDecoder();\n private _length = 0;\n private _total = 0;\n private mode: number = FILTER_SUBSTRING;\n\n /** Lazily instantiate the engine (memoized). */\n ensureReady(): Promise<void> {\n if (!this.ready) {\n this.ready = isWasmSupported()\n ? instantiateEngine().then((e) => {\n this.engine = e;\n })\n : Promise.reject(new Error('WebAssembly is not available in this environment'));\n }\n return this.ready;\n }\n\n get ready$(): boolean {\n return !!this.engine;\n }\n\n /** Current filtered row count. */\n get length(): number {\n return this._length;\n }\n\n /** Total rows loaded (ignores the active filter). */\n get total(): number {\n return this._total;\n }\n\n setFilterMode(mode: FilterMode): void {\n this.mode = FILTER_MODE[mode] ?? FILTER_SUBSTRING;\n }\n\n private mem(): Uint8Array {\n // Re-derived on every read batch: a prior `memory.grow` detaches the old\n // ArrayBuffer, so a cached view would throw.\n return new Uint8Array(this.engine!.memory.buffer);\n }\n\n /**\n * Load a dataset into WASM memory. Accepts either a materialised array or a\n * row factory (`{ count, getRow }`) — the factory path never holds more than\n * one row in JS at a time, so it scales to tens of millions of options. Two\n * passes over the input: size, then encode each row's UTF-8 directly into the\n * engine's buffers. JS references to the rows are not retained.\n */\n async load(source: ReadonlyArray<SelectOptionInit> | OptionRowSource): Promise<void> {\n await this.ensureReady();\n const e = this.engine!;\n\n let count: number;\n let at: (i: number) => SelectOptionInit;\n if (isRowSource(source)) {\n count = source.count;\n at = source.getRow;\n } else {\n count = source.length;\n at = (i) => source[i];\n }\n\n const lastPaint = { t: nowMs() };\n\n // Pass 1 — size the columns. TIME-SLICED with yields so a\n // multi-million-row load never blocks the main thread longer than about a\n // frame: the browser paints (fluid loading animation) and handles input\n // between slices. Icon / supporting-text totals stay 0 when the dataset\n // uses neither, so the engine skips those columns entirely.\n let valueBytesTotal = 0;\n let labelBytesTotal = 0;\n let iconBytesTotal = 0;\n let supportBytesTotal = 0;\n for (let i = 0; i < count; ) {\n const sliceStart = nowMs();\n do {\n const end = Math.min(count, i + LOAD_STRIDE);\n for (; i < end; i++) {\n const r = at(i);\n valueBytesTotal += utf8ByteLength(r.value);\n labelBytesTotal += utf8ByteLength(r.label ?? r.value);\n if (r.icon) iconBytesTotal += utf8ByteLength(r.icon);\n if (r.supportingText) supportBytesTotal += utf8ByteLength(r.supportingText);\n }\n } while (i < count && nowMs() - sliceStart < LOAD_SLICE_BUDGET_MS);\n if (i < count) await yieldForPaint(lastPaint);\n }\n\n e.reserve(count, valueBytesTotal, labelBytesTotal, iconBytesTotal, supportBytesTotal);\n\n // Pass 2 — encode each row's UTF-8 straight into the engine buffers, also\n // time-sliced + yielding. The memory view is re-derived per slice: appendRow\n // never grows memory, but a yield could let other work run in between. Read\n // all four write pointers before appendRow — it advances every cursor.\n for (let i = 0; i < count; ) {\n const sliceStart = nowMs();\n const mem = this.mem();\n do {\n const end = Math.min(count, i + LOAD_STRIDE);\n for (; i < end; i++) {\n const r = at(i);\n const vp = e.valueWritePtr();\n const v = this.enc.encodeInto(r.value, mem.subarray(vp));\n const lp = e.labelWritePtr();\n const l = this.enc.encodeInto(r.label ?? r.value, mem.subarray(lp));\n const ip = e.iconWritePtr();\n const ic =\n iconBytesTotal > 0 ? this.enc.encodeInto(r.icon ?? '', mem.subarray(ip)) : null;\n const sp = e.supportWritePtr();\n const sc =\n supportBytesTotal > 0\n ? this.enc.encodeInto(r.supportingText ?? '', mem.subarray(sp))\n : null;\n e.appendRow(\n v.written ?? 0,\n l.written ?? 0,\n ic?.written ?? 0,\n sc?.written ?? 0,\n r.disabled ? DISABLED_FLAG : 0,\n );\n }\n } while (i < count && nowMs() - sliceStart < LOAD_SLICE_BUDGET_MS);\n if (i < count) await yieldForPaint(lastPaint);\n }\n\n e.finalizeLoad(); // allocates the value index — may grow memory\n\n this._total = e.totalCount();\n this._length = e.filteredCount();\n }\n\n /** Write a string into the engine's scratch buffer; returns bytes written. */\n private writeScratch(s: string): number {\n const e = this.engine!;\n const cap = e.queryCapacity();\n const ptr = e.queryPtr();\n const { written } = this.enc.encodeInto(s, this.mem().subarray(ptr, ptr + cap));\n return written ?? 0;\n }\n\n /** Apply a filter query. Returns the new filtered length. */\n setQuery(query: string): number {\n if (!this.engine) return 0;\n const len = this.writeScratch(query);\n this._length = this.engine.setQuery(len, this.mode);\n return this._length;\n }\n\n private decodeRow(absIndex: number, mem: Uint8Array): VirtualRow {\n const e = this.engine!;\n const vp = e.valuePtr(absIndex);\n const vl = e.valueLen(absIndex);\n const lp = e.labelPtr(absIndex);\n const ll = e.labelLen(absIndex);\n // Icon / supporting-text columns return 0-length ranges when the dataset\n // didn't supply them, so these decode to '' at no extra packing cost.\n const ip = e.iconPtr(absIndex);\n const il = e.iconLen(absIndex);\n const sp = e.supportPtr(absIndex);\n const sl = e.supportLen(absIndex);\n return {\n index: absIndex,\n value: this.dec.decode(mem.subarray(vp, vp + vl)),\n label: this.dec.decode(mem.subarray(lp, lp + ll)),\n disabled: (e.rowFlags(absIndex) & DISABLED_FLAG) !== 0,\n icon: il > 0 ? this.dec.decode(mem.subarray(ip, ip + il)) : '',\n supportingText: sl > 0 ? this.dec.decode(mem.subarray(sp, sp + sl)) : '',\n };\n }\n\n /** Decode `count` rows starting at filtered position `start`. */\n getWindow(start: number, count: number): VirtualRow[] {\n if (!this.engine) return [];\n const e = this.engine;\n const mem = this.mem();\n const out: VirtualRow[] = [];\n const from = Math.max(0, start);\n const to = Math.min(this._length, start + count);\n for (let fi = from; fi < to; fi++) {\n const abs = e.rowAt(fi);\n if (abs >= 0) out.push(this.decodeRow(abs, mem));\n }\n return out;\n }\n\n /** Decode a single row at filtered position `filteredIndex`, or null. */\n getRow(filteredIndex: number): VirtualRow | null {\n if (!this.engine) return null;\n const abs = this.engine.rowAt(filteredIndex);\n if (abs < 0) return null;\n return this.decodeRow(abs, this.mem());\n }\n\n /** Map a filtered position to its absolute row index, or -1. */\n rowAt(filteredIndex: number): number {\n return this.engine ? this.engine.rowAt(filteredIndex) : -1;\n }\n\n /** Disabled flag for a filtered position — flag-only, no string decode. */\n disabledAt(filteredIndex: number): boolean {\n if (!this.engine) return false;\n const abs = this.engine.rowAt(filteredIndex);\n if (abs < 0) return false;\n return (this.engine.rowFlags(abs) & DISABLED_FLAG) !== 0;\n }\n\n /** Label for a filtered position — decodes a single label. */\n labelAt(filteredIndex: number): string {\n if (!this.engine) return '';\n const abs = this.engine.rowAt(filteredIndex);\n if (abs < 0) return '';\n const lp = this.engine.labelPtr(abs);\n const ll = this.engine.labelLen(abs);\n return this.dec.decode(this.mem().subarray(lp, lp + ll));\n }\n\n /**\n * Resolve labels for selected values that may be outside the current filter\n * (e.g. the trigger text / chips). O(1) per value via the engine's index.\n */\n getLabels(values: ReadonlyArray<string>): Map<string, string> {\n const result = new Map<string, string>();\n if (!this.engine) return result;\n const e = this.engine;\n for (const value of values) {\n const len = this.writeScratch(value);\n const abs = e.indexOfValue(len);\n if (abs >= 0) {\n const lp = e.labelPtr(abs);\n const ll = e.labelLen(abs);\n result.set(value, this.dec.decode(this.mem().subarray(lp, lp + ll)));\n }\n }\n return result;\n }\n\n /** Whether a value exists in the dataset. */\n has(value: string): boolean {\n if (!this.engine) return false;\n return this.engine.indexOfValue(this.writeScratch(value)) >= 0;\n }\n\n /**\n * Typeahead helper: first filtered position at/after `fromFilteredIndex`\n * whose label starts with `query` (wraps the filtered list). Returns a\n * filtered-list index, or -1.\n */\n findLabelPrefix(query: string, fromFilteredIndex: number): number {\n if (!this.engine) return -1;\n const len = this.writeScratch(query);\n return this.engine.findLabelPrefix(len, fromFilteredIndex);\n }\n\n /** Drop the dataset. */\n reset(): void {\n this.engine?.reset();\n this._length = 0;\n this._total = 0;\n }\n}\n","/**\n * `VirtualSelectController` — the shared virtualization engine for `md-select`\n * and `md-multi-select`, so neither component duplicates the window math,\n * scroll wiring, or the `VirtualMenuProvider` glue.\n *\n * It owns a `WasmOptionStore` (the dataset, packed in WASM memory) and the\n * current scroll window. The host component supplies a tiny adapter\n * (`queryItem` + `requestRender`) and reads the controller's public window\n * fields from its `render()`.\n */\nimport { computeWindow, DEFAULT_MAX_SCROLL_HEIGHT } from './virtual-window';\n\n/** Floor under which a measured scrollHeight cannot be a genuine browser\n * element-height clamp (real clamps are millions of px — Chrome ~33.5M,\n * Firefox ~17.8M) — it just means layout wasn't ready (see detectScrollCap). */\nconst MIN_PLAUSIBLE_SCROLL_CAP = 1_000_000;\nimport {\n FilterMode,\n isWasmSupported,\n VirtualRow,\n WasmOptionStore,\n} from './wasm-option-store';\nimport { isRowSource, OptionRowSource, SelectOptionInit } from './select-options';\nimport { VirtualMenuProvider } from './types';\n\n// Larger overscan than a typical virtual list: in the scaled regime a single\n// scroll frame can advance many rows, and render is async, so extra buffered\n// rows above/below the fold keep the body from flashing blank on fast scrolls.\nconst OVERSCAN = 8;\nconst DEFAULT_ROW_HEIGHT = 48;\nconst DEFAULT_VIEWPORT_HEIGHT = 320;\n// Extra px to keep a keyboard-revealed row clear of the viewport's top/bottom\n// edge. Historically 32px to clear md-scroll-shadow's edge fade; the scroll\n// shadow was removed, so a revealed row can sit flush against the edge (0). Kept\n// as a named knob in case a future edge treatment needs slack again.\nconst EDGE_SCRIM_PAD = 0;\n\nexport interface VirtualSelectHost {\n /** The rendered `md-menu-item` for a filtered index, from the host's shadow DOM. */\n queryItem(filteredIndex: number): HTMLElement | null;\n /** Re-render the host (it reads the controller's window fields). */\n requestRender(): void;\n}\n\nexport class VirtualSelectController {\n readonly store = new WasmOptionStore();\n\n /** True once a dataset is loaded and the component should render windowed. */\n active = false;\n /** First filtered index currently rendered. */\n windowStart = 0;\n /** The decoded rows in the current window. */\n windowRows: VirtualRow[] = [];\n /** Spacer heights (px) that preserve the full scroll height. */\n topPad = 0;\n bottomPad = 0;\n /** Current filtered row count. */\n filteredLength = 0;\n /** Effective fixed row height (measured or overridden). */\n rowHeight = DEFAULT_ROW_HEIGHT;\n\n private fixedRowHeight?: number;\n private viewportEl?: HTMLElement;\n private scrollRaf = 0;\n\n /**\n * The browser's observed maximum element height. Browsers clamp very tall\n * elements (a few-million-row list × row height blows past the ~16–33M px\n * cap), so the spacers can't reproduce the true height. We start optimistic\n * and shrink to the real clamp once we can measure it (see `detectScrollCap`).\n */\n private browserMaxScroll = Infinity;\n /** The scrollable height the last `recompute` asked the spacers to produce. */\n private intendedScrollHeight = 0;\n private detectRaf = 0;\n /** Retries left for detectScrollCap while layout isn't ready (see below). */\n private detectRetries = 0;\n\n /**\n * Scaled-regime keyboard nav: the first row to render, pinned independent of\n * the (too-coarse) integer scrollTop. -1 means the window is scroll-driven.\n */\n private navAnchorFirstRow = -1;\n /** The scroll offset the last `recompute` laid the window out for. */\n private usedScrollTop = 0;\n\n constructor(private host: VirtualSelectHost) {}\n\n /** Ceiling on the spacer height: our safe default, lowered by any real clamp. */\n private effectiveMaxScroll(): number {\n return Math.min(DEFAULT_MAX_SCROLL_HEIGHT, this.browserMaxScroll);\n }\n\n setFixedRowHeight(px?: number): void {\n this.fixedRowHeight = px && px > 0 ? px : undefined;\n if (this.fixedRowHeight) this.rowHeight = this.fixedRowHeight;\n }\n\n setFilterMode(mode: FilterMode): void {\n this.store.setFilterMode(mode);\n }\n\n /** Load a dataset into WASM memory. Returns false if WASM is unavailable. */\n async load(source: ReadonlyArray<SelectOptionInit> | OptionRowSource): Promise<boolean> {\n const count = isRowSource(source) ? source.count : source.length;\n if (!isWasmSupported() || count === 0) return false;\n try {\n await this.store.ensureReady();\n } catch {\n return false;\n }\n await this.store.load(source);\n this.active = true;\n this.filteredLength = this.store.length;\n this.recompute(this.viewportEl?.scrollTop ?? 0);\n return true;\n }\n\n /** Apply a filter query and reset the scroll to the top. */\n setQuery(query: string): void {\n if (!this.active) return;\n this.filteredLength = this.store.setQuery(query);\n this.navAnchorFirstRow = -1;\n if (this.viewportEl) this.viewportEl.scrollTop = 0;\n this.recompute(0);\n }\n\n getLabels(values: ReadonlyArray<string>): Map<string, string> {\n return this.store.getLabels(values);\n }\n\n reset(): void {\n this.store.reset();\n this.active = false;\n this.windowRows = [];\n this.filteredLength = 0;\n this.windowStart = 0;\n this.topPad = 0;\n this.bottomPad = 0;\n this.navAnchorFirstRow = -1;\n }\n\n // ── Viewport wiring (call when the menu opens / closes) ──────\n\n async attachViewport(getViewport: () => Promise<HTMLElement | null>): Promise<void> {\n this.detachViewport();\n const vp = await getViewport();\n this.viewportEl = vp ?? undefined;\n if (this.viewportEl) {\n this.viewportEl.addEventListener('scroll', this.onScroll, { passive: true });\n this.measureRowHeight();\n this.recompute(this.viewportEl.scrollTop);\n this.detectRetries = 60; // ~2s of rAF pairs — spacers may render late\n this.detectScrollCap();\n }\n }\n\n detachViewport(): void {\n if (this.scrollRaf) {\n cancelAnimationFrame(this.scrollRaf);\n this.scrollRaf = 0;\n }\n if (this.detectRaf) {\n cancelAnimationFrame(this.detectRaf);\n this.detectRaf = 0;\n }\n this.viewportEl?.removeEventListener('scroll', this.onScroll);\n this.viewportEl = undefined;\n }\n\n private onScroll = () => {\n if (this.scrollRaf) return;\n this.scrollRaf = requestAnimationFrame(() => {\n this.scrollRaf = 0;\n const vp = this.viewportEl;\n if (!vp) return;\n // Tell our own programmatic scroll (driving an anchored keyboard-nav\n // window) from a genuine user scroll by value: if the offset still matches\n // what the current window was laid out for, keep the anchor; otherwise the\n // user scrolled, so resume scroll-driven windowing. (A value check is\n // robust to event coalescing/ordering, unlike a one-shot flag.)\n if (this.navAnchorFirstRow >= 0 && Math.abs(vp.scrollTop - this.usedScrollTop) <= 1) {\n return;\n }\n this.navAnchorFirstRow = -1;\n this.recompute(vp.scrollTop);\n });\n };\n\n private measureRowHeight(): void {\n if (this.fixedRowHeight) {\n this.rowHeight = this.fixedRowHeight;\n return;\n }\n const first = this.host.queryItem(this.windowStart);\n const h = first?.offsetHeight ?? 0;\n if (h > 0 && h !== this.rowHeight) {\n this.rowHeight = h;\n if (this.viewportEl) this.recompute(this.viewportEl.scrollTop);\n }\n }\n\n private recompute(scrollTop: number): void {\n const vpH = this.viewportEl?.clientHeight || DEFAULT_VIEWPORT_HEIGHT;\n const calc = computeWindow(\n scrollTop,\n vpH,\n this.rowHeight,\n this.filteredLength,\n OVERSCAN,\n this.effectiveMaxScroll(),\n this.navAnchorFirstRow,\n );\n this.windowStart = calc.start;\n this.topPad = calc.topPad;\n this.bottomPad = calc.bottomPad;\n this.intendedScrollHeight = calc.scrollHeight;\n this.usedScrollTop = calc.scrollTop;\n this.windowRows = this.store.getWindow(calc.start, calc.end - calc.start);\n this.host.requestRender();\n }\n\n /**\n * Detect the browser's real maximum element height. After the spacers lay\n * out, if the viewport's `scrollHeight` came back shorter than we asked for,\n * the browser clamped it — and that clamp *is* the true maximum, so adopt it\n * and re-window against it. Runs a couple of frames after attach so the\n * (async) spacer render has committed; idempotent and only ever shrinks.\n */\n private detectScrollCap(): void {\n if (this.detectRaf) cancelAnimationFrame(this.detectRaf);\n this.detectRaf = requestAnimationFrame(() => {\n this.detectRaf = requestAnimationFrame(() => {\n this.detectRaf = 0;\n const vp = this.viewportEl;\n if (!vp) return;\n const measured = vp.scrollHeight;\n if (\n measured > 0 &&\n measured + 2 < this.intendedScrollHeight &&\n measured < this.browserMaxScroll\n ) {\n // A small reading is NOT a browser clamp — the spacers simply have\n // not been laid out yet (e.g. the menu opened during a dataset pack\n // and still showed the uncapped busy bar when we measured). Locking\n // it in would permanently collapse the scroll geometry (the cap\n // never grows back), so retry instead.\n if (measured < MIN_PLAUSIBLE_SCROLL_CAP) {\n if (this.detectRetries-- > 0) this.detectScrollCap();\n return;\n }\n this.browserMaxScroll = measured;\n this.recompute(vp.scrollTop);\n }\n });\n });\n }\n\n // ── VirtualMenuProvider (md-menu drives nav through this) ────\n\n readonly provider: VirtualMenuProvider = {\n count: () => this.filteredLength,\n labelAt: (i) => this.store.labelAt(i),\n isDisabledAt: (i) => this.store.disabledAt(i),\n ensureVisible: (i) => this.ensureVisible(i),\n domItemForIndex: (i) => this.host.queryItem(i),\n findPrefix: (buffer, from) => this.store.findLabelPrefix(buffer, from),\n };\n\n private async ensureVisible(filteredIndex: number): Promise<void> {\n const vp = this.viewportEl;\n if (!vp) return;\n const clientH = vp.clientHeight || DEFAULT_VIEWPORT_HEIGHT;\n const realHeight = this.filteredLength * this.rowHeight;\n\n if (realHeight <= this.effectiveMaxScroll()) {\n // Exact regime: pixel offset is the row index times the row height.\n this.navAnchorFirstRow = -1;\n const top = filteredIndex * this.rowHeight;\n const bottom = top + this.rowHeight;\n // Reveal with EDGE_SCRIM_PAD of slack so the row clears the edge fade.\n // Clamped to [0, maxScroll]: rows at the very top/bottom — where no scrim\n // shows — still seat flush.\n const maxScroll = Math.max(0, vp.scrollHeight - clientH);\n if (top - EDGE_SCRIM_PAD < vp.scrollTop) {\n vp.scrollTop = Math.max(0, top - EDGE_SCRIM_PAD);\n } else if (bottom + EDGE_SCRIM_PAD > vp.scrollTop + clientH) {\n vp.scrollTop = Math.min(maxScroll, bottom + EDGE_SCRIM_PAD - clientH);\n }\n this.recompute(vp.scrollTop);\n } else {\n // Scaled regime: integer scrollTop can't address single rows (millions of\n // rows compressed into a capped height — one pixel can be dozens of rows).\n // When the target row isn't already on screen, pin the window to an anchor\n // and let `computeWindow` choose the matching scroll offset, then apply it.\n const visibleRows = Math.max(1, Math.floor(clientH / this.rowHeight));\n const visibleCount = Math.ceil(clientH / this.rowHeight);\n const maxFirstRow = Math.max(0, this.filteredLength - visibleCount);\n // First visible row: take it exactly from the anchor when the window is\n // anchor-driven (deriving it from a fractional scrollTop drifts by a row);\n // fall back to the live geometry only when scroll-driven.\n const firstVisible =\n this.navAnchorFirstRow >= 0\n ? this.navAnchorFirstRow\n : this.windowStart +\n Math.max(0, Math.round((vp.scrollTop - this.topPad) / this.rowHeight));\n const lastVisible = firstVisible + visibleRows - 1;\n\n // Re-anchor when the focused row is outside the visible range OR within\n // `padRows` of either edge. The edge check matters even when the row is\n // already visible: navigating up one row at a time makes the focused row\n // the *first* visible row (flush against the top), which is never \"outside\"\n // the range — so without it the top scroll-shadow scrim would still cover\n // the focused row. Mirrors the exact-regime branch above.\n const padRows = Math.ceil(EDGE_SCRIM_PAD / this.rowHeight);\n if (\n filteredIndex < firstVisible + padRows ||\n filteredIndex > lastVisible - padRows\n ) {\n // Reveal `padRows` clear of the top (scrolling up) or bottom (scrolling\n // down) edge, clamped to [0, maxFirstRow] so the list ends — where no\n // scrim shows — still seat the row flush.\n this.navAnchorFirstRow = Math.min(\n maxFirstRow,\n Math.max(\n 0,\n filteredIndex < firstVisible + padRows\n ? filteredIndex - padRows\n : filteredIndex - visibleRows + 1 + padRows,\n ),\n );\n }\n this.recompute(vp.scrollTop);\n // Sync the browser scroll to the offset the (anchored) window was laid out\n // for. Clamp to the viewport's real max — the capped element can render a\n // hair shorter than we asked (scroll-shadow sentinels), and overshooting by\n // even a pixel near the end gets clamped by the browser — then adopt\n // whatever it actually applied, so the scroll guard and the next \"first\n // visible\" never drift out of sync and clear the anchor.\n if (this.navAnchorFirstRow >= 0) {\n const maxScroll = Math.max(0, vp.scrollHeight - clientH);\n const target = Math.min(Math.round(this.usedScrollTop), maxScroll);\n if (target !== Math.round(vp.scrollTop)) {\n vp.scrollTop = target;\n }\n this.usedScrollTop = vp.scrollTop;\n }\n }\n // Wait for the host to render the target row into the window so the menu\n // can move real focus onto it.\n for (let tries = 0; tries < 8; tries++) {\n await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()));\n if (this.host.queryItem(filteredIndex)) return;\n }\n }\n}\n"],"mappings":"AA2DA,SAASA,EAAYC,GACnB,MAAMC,GAASD,EAAGC,OAASD,EAAGE,aAAa,UAAYF,EAAGG,aAAe,IAAIC,OAC7E,MAAO,CACLC,MAAOL,EAAGK,OAASL,EAAGE,aAAa,UAAY,GAC/CD,QACAK,SAAUN,EAAGM,UAAYN,EAAGO,aAAa,YACzCC,KAAMR,EAAGQ,MAAQR,EAAGE,aAAa,SAAWO,UAC5CC,UAAWV,EAAGU,WAAaV,EAAGE,aAAa,eAAiBO,UAC5DE,eACEX,EAAGW,gBAAkBX,EAAGE,aAAa,oBAAsBO,UAC7DG,SAAUZ,EAAGY,UAAYZ,EAAGO,aAAa,YAE7C,CAEA,SAASM,EAASC,GAChB,MAAO,CACLT,MAAOS,EAAET,MACTJ,MAAOa,EAAEb,OAASa,EAAET,MACpBC,WAAYQ,EAAER,SACdE,KAAMM,EAAEN,KACRE,UAAWI,EAAEJ,UACbC,eAAgBG,EAAEH,eAClBC,WAAYE,EAAEF,SAElB,CAgBM,SAAUG,EACdC,GAEA,OAAQC,MAAMC,QAAQF,EACxB,CAGM,SAAUG,EACdH,GAEA,IAAKD,EAAYC,GAAS,OAAOA,EAAOI,QACxC,MAAMC,EAAM,IAAIJ,MAAwBD,EAAOM,OAC/C,IAAK,IAAIC,EAAI,EAAGA,EAAIP,EAAOM,MAAOC,IAAKF,EAAIE,GAAKP,EAAOQ,OAAOD,GAC9D,OAAOF,CACT,CAGM,SAAUI,EAAeC,GAC7B,OAAOA,EAAMC,IAAId,EACnB,CAMM,SAAUe,EACdC,EACAC,GAIA,MAAMC,EAAUd,MAAMe,KAAKH,EAAKI,UAAUC,QACvCC,GAAMA,EAAEC,QAAQC,gBAAkB,qBAGrC,GAAIN,EAAQO,OAAS,EAAG,CACtB,OAAOP,EAAQJ,IAAI5B,E,CAErB,OAAQ+B,GAAe,IAAIH,IAAId,EACjC,CAGM,SAAU0B,EAASC,EAA6BnC,GACpD,OAAOmC,EAAQC,MAAM3B,GAAMA,EAAET,QAAUA,KAAQJ,OAAS,EAC1D,CCpGO,MAAMyC,EAA4B,KAEnC,SAAUC,EACdC,EACAC,EACAC,EACAC,EACAC,EACAC,EAA0BP,EAI1BQ,GAAyB,GAEzB,GAAIH,GAAS,GAAKD,GAAa,GAAKD,GAAkB,EAAG,CACvD,MAAMM,EAAaJ,EAAQ,GAAKD,EAAY,EAAIC,EAAQD,EAAY,EACpE,MAAO,CAAEM,MAAO,EAAGC,IAAK,EAAGC,OAAQ,EAAGC,UAAWJ,EAAYK,aAAcL,EAAYP,UAAW,E,CAGpG,MAAMO,EAAaJ,EAAQD,EAC3B,MAAMW,EAAeC,KAAKC,KAAKd,EAAiBC,GAGhD,GAAIK,GAAcF,EAAiB,CACjC,MAAMW,EAAUF,KAAKG,IAAIH,KAAKI,IAAI,EAAGlB,GAAYc,KAAKI,IAAI,EAAGX,EAAaN,IAC1E,MAAMkB,EAAeL,KAAKM,MAAMJ,EAAUd,GAC1C,MAAMM,EAAQM,KAAKG,IAAId,EAAOW,KAAKI,IAAI,EAAGC,EAAef,IACzD,MAAMK,EAAMK,KAAKG,IAAId,EAAOW,KAAKI,IAAIV,EAAOW,EAAeN,EAAeT,IAC1E,MAAO,CACLI,QACAC,MACAC,OAAQF,EAAQN,EAChBS,UAAWG,KAAKI,IAAI,GAAIf,EAAQM,GAAOP,GACvCU,aAAcL,EACdP,UAAWgB,E,CAKf,MAAMJ,EAAeP,EACrB,MAAMgB,EAAeP,KAAKI,IAAI,EAAGN,EAAeX,GAChD,MAAMqB,EAAcR,KAAKI,IAAI,EAAGf,EAAQU,GAExC,GAAIP,GAAkB,EAAG,CAMvB,MAAMiB,EAAkBT,KAAKG,IAAIK,EAAahB,GAC9C,MAAMkB,EAAYV,KAAKG,IAAIb,EAAUmB,GACrC,MAAMf,EAAQe,EAAkBC,EAChC,MAAMf,EAAMK,KAAKG,IAAId,EAAOoB,EAAkBV,EAAeT,GAC7D,MAAMqB,GAAehB,EAAMD,GAASN,EAapC,MAAMwB,EAAKF,EAAYtB,EACvB,MAAMyB,EAAeb,KAAKc,MAAOL,EAAkBT,KAAKI,IAAI,EAAGI,GAAgBD,GAC/E,MAAMQ,EAAgBf,KAAKI,IAAIQ,EAAIZ,KAAKG,IAAII,EAAcM,IAC1D,MAAMjB,EAASmB,EAAgBL,EAAYtB,EAC3C,MAAMS,EAAYG,KAAKI,IAAI,EAAGN,EAAeF,EAASe,GACtD,MAAO,CAAEjB,QAAOC,MAAKC,SAAQC,YAAWC,eAAcZ,UAAW6B,E,CAMnE,MAAMb,EAAUF,KAAKG,IAAIH,KAAKI,IAAI,EAAGlB,GAAYqB,GACjD,MAAME,EAAkBT,KAAKc,MAAOZ,EAAUK,EAAgBC,GAC9D,MAAME,EAAYV,KAAKG,IAAIb,EAAUmB,EAAiBT,KAAKM,MAAMJ,EAAUd,IAC3E,MAAMM,EAAQe,EAAkBC,EAChC,MAAMf,EAAMK,KAAKG,IAAId,EAAOoB,EAAkBV,EAAeT,GAC7D,MAAMqB,GAAehB,EAAMD,GAASN,EACpC,MAAM4B,EAAShB,KAAKI,IAAI,EAAGN,EAAea,GAC1C,IAAIf,EAASM,EAAUQ,EAAYtB,EACnC,GAAIQ,EAAS,EAAGA,EAAS,OACpB,GAAIA,EAASoB,EAAQpB,EAASoB,EACnC,MAAMnB,EAAYG,KAAKI,IAAI,EAAGN,EAAeF,EAASe,GAEtD,MAAO,CAAEjB,QAAOC,MAAKC,SAAQC,YAAWC,eAAcZ,UAAWgB,EACnE,CCrHO,MAAMe,EAAmB,EA8ChC,SAASC,EAAaC,GACpB,UAAWC,OAAS,WAAY,CAC9B,MAAMC,EAAMD,KAAKD,GACjB,MAAMxD,EAAM,IAAI2D,WAAWD,EAAIzC,QAC/B,IAAK,IAAIf,EAAI,EAAGA,EAAIwD,EAAIzC,OAAQf,IAAKF,EAAIE,GAAKwD,EAAIE,WAAW1D,GAC7D,OAAOF,C,CAGT,OAAO2D,WAAWhD,KAAKkD,OAAOlD,KAAK6C,EAAK,UAC1C,CAOA,IAAIM,EAMGC,eAAeC,IACpBF,MAAkBG,OAAO,mBAAiBC,MAAK,EAAGC,iBAChDC,YAAYC,QAAQd,EAAaY,OAEnC,MAAMG,QAAeR,EACrB,MAAMS,EAAU,CACdC,IAAK,CACH,KAAAC,GAAK,EACL,KAAAC,GAAK,EACL,IAAAC,GACE,OAAOC,KAAKC,K,IAIlB,MAAMC,QAAiBV,YAAYW,YAAYT,EAAQC,GACvD,OAAOO,EAASE,OAClB,CClEA,MAAMC,EAA0C,CAC9CC,UAAW,EACXC,OAAQ,EACRC,MAAO,GAGT,MAAMC,EAAgB,EAQtB,MAAMC,EAAuB,EAK7B,MAAMC,EAAc,KAGpB,MAAMC,SACGC,cAAgB,oBAAsBA,YAAYZ,MAAQ,WAC7D,IAAMY,YAAYZ,MAClB,IAAMD,KAAKC,MAKjB,SAASa,IACP,MAAMC,EAAaC,WAA+DD,UAClF,GAAIA,GAAWE,MAAO,OAAOF,EAAUE,QACvC,OAAO,IAAIC,SAASC,GAAYC,WAAWD,EAAS,IACtD,CASA,MAAME,EAAoB,GAS1BlC,eAAemC,EAAcC,GAC3B,UACSC,wBAA0B,YACjCZ,IAAUW,EAAUE,GAAKJ,EACzB,OAMM,IAAIH,SAAeC,IACvBK,uBAAsB,IAAMJ,WAAWD,EAAS,IAAG,IAErDI,EAAUE,EAAIb,IACd,M,OAEIE,GACR,C,SAGgBY,IACd,cAAclC,cAAgB,oBAAsBA,YAAYW,cAAgB,UAClF,CAOM,SAAUwB,EAAeC,GAC7B,IAAIC,EAAQ,EACZ,IAAK,IAAIvG,EAAI,EAAGA,EAAIsG,EAAIvF,OAAQf,IAAK,CACnC,MAAMY,EAAI0F,EAAI5C,WAAW1D,GACzB,GAAIY,EAAI,IAAM,CACZ2F,GAAS,C,MACJ,GAAI3F,EAAI,KAAO,CACpB2F,GAAS,C,MACJ,GAAI3F,GAAK,OAAUA,GAAK,MAAQ,CACrC,MAAM4F,EAAOF,EAAI5C,WAAW1D,EAAI,GAChC,GAAIwG,GAAQ,OAAUA,GAAQ,MAAQ,CACpCD,GAAS,EACTvG,G,KACK,CACLuG,GAAS,C,MAEN,CACLA,GAAS,C,EAGb,OAAOA,CACT,C,MAEaE,EAAb,WAAAC,GAGUC,KAAAC,IAAM,IAAIC,YACVF,KAAAG,IAAM,IAAIC,YACVJ,KAAAK,QAAU,EACVL,KAAAM,OAAS,EACTN,KAAAO,KAAe9D,C,CAGvB,WAAA+D,GACE,IAAKR,KAAKS,MAAO,CACfT,KAAKS,MAAQhB,IACTtC,IAAoBE,MAAMqD,IACxBV,KAAKW,OAASD,CAAC,IAEjBzB,QAAQ2B,OAAO,IAAIC,MAAM,oD,CAE/B,OAAOb,KAAKS,K,CAGd,UAAIK,GACF,QAASd,KAAKW,M,CAIhB,UAAIvG,GACF,OAAO4F,KAAKK,O,CAId,SAAIxF,GACF,OAAOmF,KAAKM,M,CAGd,aAAAS,CAAcR,GACZP,KAAKO,KAAOnC,EAAYmC,IAAS9D,C,CAG3B,GAAAuE,GAGN,OAAO,IAAIlE,WAAWkD,KAAKW,OAAQM,OAAOC,O,CAU5C,UAAMC,CAAKrI,SACHkH,KAAKQ,cACX,MAAME,EAAIV,KAAKW,OAEf,IAAIvH,EACJ,IAAIgI,EACJ,GAAIvI,EAAYC,GAAS,CACvBM,EAAQN,EAAOM,MACfgI,EAAKtI,EAAOQ,M,KACP,CACLF,EAAQN,EAAOsB,OACfgH,EAAM/H,GAAMP,EAAOO,E,CAGrB,MAAMiG,EAAY,CAAEE,EAAGb,KAOvB,IAAI0C,EAAkB,EACtB,IAAIC,EAAkB,EACtB,IAAIC,EAAiB,EACrB,IAAIC,EAAoB,EACxB,IAAK,IAAInI,EAAI,EAAGA,EAAID,GAAS,CAC3B,MAAMqI,EAAa9C,IACnB,EAAG,CACD,MAAMxD,EAAMK,KAAKG,IAAIvC,EAAOC,EAAIqF,GAChC,KAAOrF,EAAI8B,EAAK9B,IAAK,CACnB,MAAMqI,EAAIN,EAAG/H,GACbgI,GAAmB3B,EAAegC,EAAEvJ,OACpCmJ,GAAmB5B,EAAegC,EAAE3J,OAAS2J,EAAEvJ,OAC/C,GAAIuJ,EAAEpJ,KAAMiJ,GAAkB7B,EAAegC,EAAEpJ,MAC/C,GAAIoJ,EAAEjJ,eAAgB+I,GAAqB9B,EAAegC,EAAEjJ,e,QAEvDY,EAAID,GAASuF,IAAU8C,EAAahD,GAC7C,GAAIpF,EAAID,QAAaiG,EAAcC,E,CAGrCoB,EAAEiB,QAAQvI,EAAOiI,EAAiBC,EAAiBC,EAAgBC,GAMnE,IAAK,IAAInI,EAAI,EAAGA,EAAID,GAAS,CAC3B,MAAMqI,EAAa9C,IACnB,MAAMqC,EAAMhB,KAAKgB,MACjB,EAAG,CACD,MAAM7F,EAAMK,KAAKG,IAAIvC,EAAOC,EAAIqF,GAChC,KAAOrF,EAAI8B,EAAK9B,IAAK,CACnB,MAAMqI,EAAIN,EAAG/H,GACb,MAAMuI,EAAKlB,EAAEmB,gBACb,MAAMC,EAAI9B,KAAKC,IAAI8B,WAAWL,EAAEvJ,MAAO6I,EAAIgB,SAASJ,IACpD,MAAMK,EAAKvB,EAAEwB,gBACb,MAAMC,EAAInC,KAAKC,IAAI8B,WAAWL,EAAE3J,OAAS2J,EAAEvJ,MAAO6I,EAAIgB,SAASC,IAC/D,MAAMG,EAAK1B,EAAE2B,eACb,MAAMC,EACJf,EAAiB,EAAIvB,KAAKC,IAAI8B,WAAWL,EAAEpJ,MAAQ,GAAI0I,EAAIgB,SAASI,IAAO,KAC7E,MAAMG,EAAK7B,EAAE8B,kBACb,MAAMC,EACJjB,EAAoB,EAChBxB,KAAKC,IAAI8B,WAAWL,EAAEjJ,gBAAkB,GAAIuI,EAAIgB,SAASO,IACzD,KACN7B,EAAEgC,UACAZ,EAAEa,SAAW,EACbR,EAAEQ,SAAW,EACbL,GAAIK,SAAW,EACfF,GAAIE,SAAW,EACfjB,EAAEtJ,SAAWoG,EAAgB,E,QAG1BnF,EAAID,GAASuF,IAAU8C,EAAahD,GAC7C,GAAIpF,EAAID,QAAaiG,EAAcC,E,CAGrCoB,EAAEkC,eAEF5C,KAAKM,OAASI,EAAEmC,aAChB7C,KAAKK,QAAUK,EAAEoC,e,CAIX,YAAAC,CAAaC,GACnB,MAAMtC,EAAIV,KAAKW,OACf,MAAMsC,EAAMvC,EAAEwC,gBACd,MAAMC,EAAMzC,EAAE0C,WACd,MAAMT,QAAEA,GAAY3C,KAAKC,IAAI8B,WAAWiB,EAAGhD,KAAKgB,MAAMgB,SAASmB,EAAKA,EAAMF,IAC1E,OAAON,GAAW,C,CAIpB,QAAAU,CAASC,GACP,IAAKtD,KAAKW,OAAQ,OAAO,EACzB,MAAM4C,EAAMvD,KAAK+C,aAAaO,GAC9BtD,KAAKK,QAAUL,KAAKW,OAAO0C,SAASE,EAAKvD,KAAKO,MAC9C,OAAOP,KAAKK,O,CAGN,SAAAmD,CAAUC,EAAkBzC,GAClC,MAAMN,EAAIV,KAAKW,OACf,MAAMiB,EAAKlB,EAAEgD,SAASD,GACtB,MAAME,EAAKjD,EAAEkD,SAASH,GACtB,MAAMxB,EAAKvB,EAAEmD,SAASJ,GACtB,MAAMK,EAAKpD,EAAEqD,SAASN,GAGtB,MAAMrB,EAAK1B,EAAEsD,QAAQP,GACrB,MAAMQ,EAAKvD,EAAEwD,QAAQT,GACrB,MAAMlB,EAAK7B,EAAEyD,WAAWV,GACxB,MAAMW,EAAK1D,EAAE2D,WAAWZ,GACxB,MAAO,CACLa,MAAOb,EACPtL,MAAO6H,KAAKG,IAAIoE,OAAOvD,EAAIgB,SAASJ,EAAIA,EAAK+B,IAC7C5L,MAAOiI,KAAKG,IAAIoE,OAAOvD,EAAIgB,SAASC,EAAIA,EAAK6B,IAC7C1L,UAAWsI,EAAE8D,SAASf,GAAYjF,KAAmB,EACrDlG,KAAM2L,EAAK,EAAIjE,KAAKG,IAAIoE,OAAOvD,EAAIgB,SAASI,EAAIA,EAAK6B,IAAO,GAC5DxL,eAAgB2L,EAAK,EAAIpE,KAAKG,IAAIoE,OAAOvD,EAAIgB,SAASO,EAAIA,EAAK6B,IAAO,G,CAK1E,SAAAK,CAAUvJ,EAAe9B,GACvB,IAAK4G,KAAKW,OAAQ,MAAO,GACzB,MAAMD,EAAIV,KAAKW,OACf,MAAMK,EAAMhB,KAAKgB,MACjB,MAAM7H,EAAoB,GAC1B,MAAMW,EAAO0B,KAAKI,IAAI,EAAGV,GACzB,MAAMwJ,EAAKlJ,KAAKG,IAAIqE,KAAKK,QAASnF,EAAQ9B,GAC1C,IAAK,IAAIuL,EAAK7K,EAAM6K,EAAKD,EAAIC,IAAM,CACjC,MAAMC,EAAMlE,EAAEmE,MAAMF,GACpB,GAAIC,GAAO,EAAGzL,EAAI2L,KAAK9E,KAAKwD,UAAUoB,EAAK5D,G,CAE7C,OAAO7H,C,CAIT,MAAAG,CAAOyL,GACL,IAAK/E,KAAKW,OAAQ,OAAO,KACzB,MAAMiE,EAAM5E,KAAKW,OAAOkE,MAAME,GAC9B,GAAIH,EAAM,EAAG,OAAO,KACpB,OAAO5E,KAAKwD,UAAUoB,EAAK5E,KAAKgB,M,CAIlC,KAAA6D,CAAME,GACJ,OAAO/E,KAAKW,OAASX,KAAKW,OAAOkE,MAAME,IAAiB,C,CAI1D,UAAAC,CAAWD,GACT,IAAK/E,KAAKW,OAAQ,OAAO,MACzB,MAAMiE,EAAM5E,KAAKW,OAAOkE,MAAME,GAC9B,GAAIH,EAAM,EAAG,OAAO,MACpB,OAAQ5E,KAAKW,OAAO6D,SAASI,GAAOpG,KAAmB,C,CAIzD,OAAAyG,CAAQF,GACN,IAAK/E,KAAKW,OAAQ,MAAO,GACzB,MAAMiE,EAAM5E,KAAKW,OAAOkE,MAAME,GAC9B,GAAIH,EAAM,EAAG,MAAO,GACpB,MAAM3C,EAAKjC,KAAKW,OAAOkD,SAASe,GAChC,MAAMd,EAAK9D,KAAKW,OAAOoD,SAASa,GAChC,OAAO5E,KAAKG,IAAIoE,OAAOvE,KAAKgB,MAAMgB,SAASC,EAAIA,EAAK6B,G,CAOtD,SAAAoB,CAAUC,GACR,MAAMC,EAAS,IAAIC,IACnB,IAAKrF,KAAKW,OAAQ,OAAOyE,EACzB,MAAM1E,EAAIV,KAAKW,OACf,IAAK,MAAMxI,KAASgN,EAAQ,CAC1B,MAAM5B,EAAMvD,KAAK+C,aAAa5K,GAC9B,MAAMyM,EAAMlE,EAAE4E,aAAa/B,GAC3B,GAAIqB,GAAO,EAAG,CACZ,MAAM3C,EAAKvB,EAAEmD,SAASe,GACtB,MAAMd,EAAKpD,EAAEqD,SAASa,GACtBQ,EAAOG,IAAIpN,EAAO6H,KAAKG,IAAIoE,OAAOvE,KAAKgB,MAAMgB,SAASC,EAAIA,EAAK6B,I,EAGnE,OAAOsB,C,CAIT,GAAAI,CAAIrN,GACF,IAAK6H,KAAKW,OAAQ,OAAO,MACzB,OAAOX,KAAKW,OAAO2E,aAAatF,KAAK+C,aAAa5K,KAAW,C,CAQ/D,eAAAsN,CAAgBnC,EAAeoC,GAC7B,IAAK1F,KAAKW,OAAQ,OAAO,EACzB,MAAM4C,EAAMvD,KAAK+C,aAAaO,GAC9B,OAAOtD,KAAKW,OAAO8E,gBAAgBlC,EAAKmC,E,CAI1C,KAAAC,GACE3F,KAAKW,QAAQgF,QACb3F,KAAKK,QAAU,EACfL,KAAKM,OAAS,C,EChYlB,MAAMsF,EAA2B,IAajC,MAAMC,EAAW,EACjB,MAAMC,EAAqB,GAC3B,MAAMC,EAA0B,IAKhC,MAAMC,EAAiB,E,MASVC,EA0CX,WAAAlG,CAAoBpG,GAAAqG,KAAArG,OAzCXqG,KAAAkG,MAAQ,IAAIpG,EAGrBE,KAAAmG,OAAS,MAETnG,KAAAoG,YAAc,EAEdpG,KAAAqG,WAA2B,GAE3BrG,KAAA5E,OAAS,EACT4E,KAAA3E,UAAY,EAEZ2E,KAAAsG,eAAiB,EAEjBtG,KAAApF,UAAYkL,EAIJ9F,KAAAuG,UAAY,EAQZvG,KAAAwG,iBAAmBC,SAEnBzG,KAAA0G,qBAAuB,EACvB1G,KAAA2G,UAAY,EAEZ3G,KAAA4G,cAAgB,EAMhB5G,KAAA6G,mBAAoB,EAEpB7G,KAAAzD,cAAgB,EAsFhByD,KAAA8G,SAAW,KACjB,GAAI9G,KAAKuG,UAAW,OACpBvG,KAAKuG,UAAYhH,uBAAsB,KACrCS,KAAKuG,UAAY,EACjB,MAAM3E,EAAK5B,KAAK+G,WAChB,IAAKnF,EAAI,OAMT,GAAI5B,KAAK6G,mBAAqB,GAAKrL,KAAKoJ,IAAIhD,EAAGlH,UAAYsF,KAAKzD,gBAAkB,EAAG,CACnF,M,CAEFyD,KAAK6G,mBAAoB,EACzB7G,KAAKgH,UAAUpF,EAAGlH,UAAU,GAC5B,EA0EKsF,KAAAiH,SAAgC,CACvC7N,MAAO,IAAM4G,KAAKsG,eAClBrB,QAAU5L,GAAM2G,KAAKkG,MAAMjB,QAAQ5L,GACnC6N,aAAe7N,GAAM2G,KAAKkG,MAAMlB,WAAW3L,GAC3C8N,cAAgB9N,GAAM2G,KAAKmH,cAAc9N,GACzC+N,gBAAkB/N,GAAM2G,KAAKrG,KAAK0N,UAAUhO,GAC5CiO,WAAY,CAACpG,EAAQpH,IAASkG,KAAKkG,MAAMT,gBAAgBvE,EAAQpH,G,CAjL3D,kBAAAyN,GACN,OAAO/L,KAAKG,IAAInB,EAA2BwF,KAAKwG,iB,CAGlD,iBAAAgB,CAAkBC,GAChBzH,KAAK0H,eAAiBD,GAAMA,EAAK,EAAIA,EAAKlP,UAC1C,GAAIyH,KAAK0H,eAAgB1H,KAAKpF,UAAYoF,KAAK0H,c,CAGjD,aAAA3G,CAAcR,GACZP,KAAKkG,MAAMnF,cAAcR,E,CAI3B,UAAMY,CAAKrI,GACT,MAAMM,EAAQP,EAAYC,GAAUA,EAAOM,MAAQN,EAAOsB,OAC1D,IAAKqF,KAAqBrG,IAAU,EAAG,OAAO,MAC9C,UACQ4G,KAAKkG,MAAM1F,a,CACjB,MACA,OAAO,K,OAEHR,KAAKkG,MAAM/E,KAAKrI,GACtBkH,KAAKmG,OAAS,KACdnG,KAAKsG,eAAiBtG,KAAKkG,MAAM9L,OACjC4F,KAAKgH,UAAUhH,KAAK+G,YAAYrM,WAAa,GAC7C,OAAO,I,CAIT,QAAA2I,CAASC,GACP,IAAKtD,KAAKmG,OAAQ,OAClBnG,KAAKsG,eAAiBtG,KAAKkG,MAAM7C,SAASC,GAC1CtD,KAAK6G,mBAAoB,EACzB,GAAI7G,KAAK+G,WAAY/G,KAAK+G,WAAWrM,UAAY,EACjDsF,KAAKgH,UAAU,E,CAGjB,SAAA9B,CAAUC,GACR,OAAOnF,KAAKkG,MAAMhB,UAAUC,E,CAG9B,KAAAQ,GACE3F,KAAKkG,MAAMP,QACX3F,KAAKmG,OAAS,MACdnG,KAAKqG,WAAa,GAClBrG,KAAKsG,eAAiB,EACtBtG,KAAKoG,YAAc,EACnBpG,KAAK5E,OAAS,EACd4E,KAAK3E,UAAY,EACjB2E,KAAK6G,mBAAoB,C,CAK3B,oBAAMc,CAAeC,GACnB5H,KAAK6H,iBACL,MAAMjG,QAAWgG,IACjB5H,KAAK+G,WAAanF,GAAMrJ,UACxB,GAAIyH,KAAK+G,WAAY,CACnB/G,KAAK+G,WAAWe,iBAAiB,SAAU9H,KAAK8G,SAAU,CAAEiB,QAAS,OACrE/H,KAAKgI,mBACLhI,KAAKgH,UAAUhH,KAAK+G,WAAWrM,WAC/BsF,KAAK4G,cAAgB,GACrB5G,KAAKiI,iB,EAIT,cAAAJ,GACE,GAAI7H,KAAKuG,UAAW,CAClB2B,qBAAqBlI,KAAKuG,WAC1BvG,KAAKuG,UAAY,C,CAEnB,GAAIvG,KAAK2G,UAAW,CAClBuB,qBAAqBlI,KAAK2G,WAC1B3G,KAAK2G,UAAY,C,CAEnB3G,KAAK+G,YAAYoB,oBAAoB,SAAUnI,KAAK8G,UACpD9G,KAAK+G,WAAaxO,S,CAsBZ,gBAAAyP,GACN,GAAIhI,KAAK0H,eAAgB,CACvB1H,KAAKpF,UAAYoF,KAAK0H,eACtB,M,CAEF,MAAMU,EAAQpI,KAAKrG,KAAK0N,UAAUrH,KAAKoG,aACvC,MAAMiC,EAAID,GAAOE,cAAgB,EACjC,GAAID,EAAI,GAAKA,IAAMrI,KAAKpF,UAAW,CACjCoF,KAAKpF,UAAYyN,EACjB,GAAIrI,KAAK+G,WAAY/G,KAAKgH,UAAUhH,KAAK+G,WAAWrM,U,EAIhD,SAAAsM,CAAUtM,GAChB,MAAM6N,EAAMvI,KAAK+G,YAAYyB,cAAgBzC,EAC7C,MAAM0C,EAAOhO,EACXC,EACA6N,EACAvI,KAAKpF,UACLoF,KAAKsG,eACLT,EACA7F,KAAKuH,qBACLvH,KAAK6G,mBAEP7G,KAAKoG,YAAcqC,EAAKvN,MACxB8E,KAAK5E,OAASqN,EAAKrN,OACnB4E,KAAK3E,UAAYoN,EAAKpN,UACtB2E,KAAK0G,qBAAuB+B,EAAKnN,aACjC0E,KAAKzD,cAAgBkM,EAAK/N,UAC1BsF,KAAKqG,WAAarG,KAAKkG,MAAMzB,UAAUgE,EAAKvN,MAAOuN,EAAKtN,IAAMsN,EAAKvN,OACnE8E,KAAKrG,KAAK+O,e,CAUJ,eAAAT,GACN,GAAIjI,KAAK2G,UAAWuB,qBAAqBlI,KAAK2G,WAC9C3G,KAAK2G,UAAYpH,uBAAsB,KACrCS,KAAK2G,UAAYpH,uBAAsB,KACrCS,KAAK2G,UAAY,EACjB,MAAM/E,EAAK5B,KAAK+G,WAChB,IAAKnF,EAAI,OACT,MAAM+G,EAAW/G,EAAGtG,aACpB,GACEqN,EAAW,GACXA,EAAW,EAAI3I,KAAK0G,sBACpBiC,EAAW3I,KAAKwG,iBAChB,CAMA,GAAImC,EAAW/C,EAA0B,CACvC,GAAI5F,KAAK4G,iBAAkB,EAAG5G,KAAKiI,kBACnC,M,CAEFjI,KAAKwG,iBAAmBmC,EACxB3I,KAAKgH,UAAUpF,EAAGlH,U,IAEpB,G,CAeE,mBAAMyM,CAAcpC,GAC1B,MAAMnD,EAAK5B,KAAK+G,WAChB,IAAKnF,EAAI,OACT,MAAMgH,EAAUhH,EAAG4G,cAAgBzC,EACnC,MAAM9K,EAAa+E,KAAKsG,eAAiBtG,KAAKpF,UAE9C,GAAIK,GAAc+E,KAAKuH,qBAAsB,CAE3CvH,KAAK6G,mBAAoB,EACzB,MAAMgC,EAAM9D,EAAgB/E,KAAKpF,UACjC,MAAMkO,EAASD,EAAM7I,KAAKpF,UAI1B,MAAMmO,EAAYvN,KAAKI,IAAI,EAAGgG,EAAGtG,aAAesN,GAChD,GAAIC,EAAM7C,EAAiBpE,EAAGlH,UAAW,CACvCkH,EAAGlH,UAAYc,KAAKI,IAAI,EAAGiN,EAAM7C,E,MAC5B,GAAI8C,EAAS9C,EAAiBpE,EAAGlH,UAAYkO,EAAS,CAC3DhH,EAAGlH,UAAYc,KAAKG,IAAIoN,EAAWD,EAAS9C,EAAiB4C,E,CAE/D5I,KAAKgH,UAAUpF,EAAGlH,U,KACb,CAKL,MAAMsO,EAAcxN,KAAKI,IAAI,EAAGJ,KAAKM,MAAM8M,EAAU5I,KAAKpF,YAC1D,MAAMW,EAAeC,KAAKC,KAAKmN,EAAU5I,KAAKpF,WAC9C,MAAMoB,EAAcR,KAAKI,IAAI,EAAGoE,KAAKsG,eAAiB/K,GAItD,MAAMM,EACJmE,KAAK6G,mBAAqB,EACtB7G,KAAK6G,kBACL7G,KAAKoG,YACL5K,KAAKI,IAAI,EAAGJ,KAAKc,OAAOsF,EAAGlH,UAAYsF,KAAK5E,QAAU4E,KAAKpF,YACjE,MAAMqO,EAAcpN,EAAemN,EAAc,EAQjD,MAAME,EAAU1N,KAAKC,KAAKuK,EAAiBhG,KAAKpF,WAChD,GACEmK,EAAgBlJ,EAAeqN,GAC/BnE,EAAgBkE,EAAcC,EAC9B,CAIAlJ,KAAK6G,kBAAoBrL,KAAKG,IAC5BK,EACAR,KAAKI,IACH,EACAmJ,EAAgBlJ,EAAeqN,EAC3BnE,EAAgBmE,EAChBnE,EAAgBiE,EAAc,EAAIE,G,CAI5ClJ,KAAKgH,UAAUpF,EAAGlH,WAOlB,GAAIsF,KAAK6G,mBAAqB,EAAG,CAC/B,MAAMkC,EAAYvN,KAAKI,IAAI,EAAGgG,EAAGtG,aAAesN,GAChD,MAAMO,EAAS3N,KAAKG,IAAIH,KAAKc,MAAM0D,KAAKzD,eAAgBwM,GACxD,GAAII,IAAW3N,KAAKc,MAAMsF,EAAGlH,WAAY,CACvCkH,EAAGlH,UAAYyO,C,CAEjBnJ,KAAKzD,cAAgBqF,EAAGlH,S,EAK5B,IAAK,IAAI0O,EAAQ,EAAGA,EAAQ,EAAGA,IAAS,OAChC,IAAInK,SAAeC,GAAYK,uBAAsB,IAAML,QACjE,GAAIc,KAAKrG,KAAK0N,UAAUtC,GAAgB,M","ignoreList":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{p as e,H as t,c as s,h as i,d as n,t as r}from"./p-BR6gfOQH.js";const a=()=>`:host{display:block;position:fixed;z-index:auto;pointer-events:none}:host(.md-menu--open){pointer-events:auto}.md-menu__surface{background-color:var(--md-sys-color-surface-container, #F7F2FA);border-radius:var(--md-sys-shape-corner-small, 8px);box-shadow:0 1px 2px rgba(0, 0, 0, 0.3), 0 2px 6px 2px rgba(0, 0, 0, 0.15);min-width:var(--md-menu-min-width, 112px);max-width:min( var(--md-menu-max-width, 100vw), calc(100vw - 2 * var(--md-menu-viewport-margin, 8px)) );padding:var(--md-sys-spacing-inset-xs, 4px) 0;overflow:visible;opacity:0;transform:scaleY(0.8);transform-origin:top left;transition:opacity var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1)), transform var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1))}:host(.md-menu--open) .md-menu__surface{opacity:1;transform:none}:host(.md-menu--closing) .md-menu__surface{opacity:0;transform:scaleY(0.8);transition:opacity var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)), transform var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15))}:host(.md-menu--closing){pointer-events:none}:host(.md-menu--quick) .md-menu__surface{transition:none}:host(.md-menu--inline-fill){position:relative;display:flex;flex-direction:column;flex:1 1 auto;min-block-size:0;block-size:100%;inline-size:100%;pointer-events:auto}:host(.md-menu--inline-fill) .md-menu__surface{flex:1 1 auto;block-size:100%;min-block-size:0;min-inline-size:100%;max-inline-size:none;display:flex;flex-direction:column;overflow:hidden;box-shadow:none;border:none;outline:none;padding:0;border-radius:0;border-end-start-radius:var(--md-menu-inline-fill-radius-end, 0);border-end-end-radius:var(--md-menu-inline-fill-radius-end, 0);background-color:var(--md-menu-inline-surface-color, transparent)}:host(.md-menu--inline-fill) .md-menu__scroll-shadow{flex:1 1 auto;min-block-size:0;block-size:100%}:host(.md-menu--inline-fill) .md-menu__surface ::slotted(md-menu-item:last-child){border-end-start-radius:var(--md-menu-inline-fill-radius-end, 0);border-end-end-radius:var(--md-menu-inline-fill-radius-end, 0)}:host(.md-menu--scroll):not(.md-menu--has-submenu) .md-menu__surface{overflow:hidden}:host(.md-menu--scroll) .md-menu__scroll-shadow{min-block-size:0}.md-menu__scroll-shadow{overflow-y:auto;overflow-anchor:none}:host([match-anchor-width]) .md-menu__surface{max-width:calc(100vw - 2 * var(--md-menu-viewport-margin, 8px));box-sizing:border-box}:host(:not(.md-menu--has-submenu):not(.md-menu--inline-fill):not(.md-menu--scroll)) .md-menu__surface{max-height:calc(100dvh - 2 * var(--md-menu-viewport-margin, 8px));overflow-y:auto;overscroll-behavior:contain}@media (max-width: 600px){:host(.md-menu--responsive) .md-menu__surface{width:calc(100vw - 2 * var(--md-menu-viewport-margin, 8px));min-width:0;max-width:none;box-sizing:border-box}}:host([placement="bottom-start"]) .md-menu__surface{transform-origin:top left}:host([placement="bottom-end"]) .md-menu__surface{transform-origin:top right}:host([placement="top-start"]) .md-menu__surface{transform-origin:bottom left}:host([placement="top-end"]) .md-menu__surface{transform-origin:bottom right}:host(.md-menu--standard) .md-menu__surface{background-color:var(--md-sys-color-surface-container-low, #F7F2FA);border-radius:var(--md-sys-shape-corner-large, 16px);box-shadow:0 1px 3px rgba(0, 0, 0, 0.12), 0 4px 8px 3px rgba(0, 0, 0, 0.08);padding:var(--md-sys-spacing-inset-xs, 4px)}:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item),:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item){border-radius:var(--md-sys-shape-corner-small, 8px)}:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:first-child),:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:first-child){border-start-start-radius:var(--md-sys-shape-corner-large, 16px);border-start-end-radius:var(--md-sys-shape-corner-large, 16px)}:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:last-child),:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:last-child){border-end-start-radius:var(--md-sys-shape-corner-large, 16px);border-end-end-radius:var(--md-sys-shape-corner-large, 16px)}:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:hover),:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:hover){border-radius:var(--md-sys-shape-corner-extra-small, 4px)}:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:active),:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item.md-menu-item--selected),:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:active){border-radius:var(--md-sys-shape-corner-medium, 12px)}:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:first-child:hover),:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:first-child:hover){border-start-start-radius:var(--md-sys-shape-corner-large, 16px);border-start-end-radius:var(--md-sys-shape-corner-large, 16px);border-end-start-radius:var(--md-sys-shape-corner-extra-small, 4px);border-end-end-radius:var(--md-sys-shape-corner-extra-small, 4px)}:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:last-child:hover),:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:last-child:hover){border-start-start-radius:var(--md-sys-shape-corner-extra-small, 4px);border-start-end-radius:var(--md-sys-shape-corner-extra-small, 4px);border-end-start-radius:var(--md-sys-shape-corner-large, 16px);border-end-end-radius:var(--md-sys-shape-corner-large, 16px)}:host(.md-menu--vibrant) .md-menu__surface{background-color:var(--md-sys-color-tertiary-container, #FFD8E4);border-radius:var(--md-sys-shape-corner-large, 16px);box-shadow:0 1px 3px rgba(0, 0, 0, 0.12), 0 4px 8px 3px rgba(0, 0, 0, 0.08);padding:var(--md-sys-spacing-inset-xs, 4px)}:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item),:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item){border-radius:var(--md-sys-shape-corner-small, 8px)}:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:first-child),:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:first-child){border-start-start-radius:var(--md-sys-shape-corner-large, 16px);border-start-end-radius:var(--md-sys-shape-corner-large, 16px)}:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:last-child),:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:last-child){border-end-start-radius:var(--md-sys-shape-corner-large, 16px);border-end-end-radius:var(--md-sys-shape-corner-large, 16px)}:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:hover),:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:hover){border-radius:var(--md-sys-shape-corner-extra-small, 4px)}:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:active),:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item.md-menu-item--selected),:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:active){border-radius:var(--md-sys-shape-corner-medium, 12px)}:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:first-child:hover),:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:first-child:hover){border-start-start-radius:var(--md-sys-shape-corner-large, 16px);border-start-end-radius:var(--md-sys-shape-corner-large, 16px);border-end-start-radius:var(--md-sys-shape-corner-extra-small, 4px);border-end-end-radius:var(--md-sys-shape-corner-extra-small, 4px)}:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:last-child:hover),:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:last-child:hover){border-start-start-radius:var(--md-sys-shape-corner-extra-small, 4px);border-start-end-radius:var(--md-sys-shape-corner-extra-small, 4px);border-end-start-radius:var(--md-sys-shape-corner-large, 16px);border-end-end-radius:var(--md-sys-shape-corner-large, 16px)}:host(.md-menu--gap) .md-menu__surface{gap:var(--md-sys-spacing-gap-xs, 4px);display:flex;flex-direction:column}:host(.md-menu--grouped.md-menu--gap.md-menu--standard) .md-menu__surface,:host(.md-menu--grouped.md-menu--gap.md-menu--vibrant) .md-menu__surface{background-color:transparent;box-shadow:none;overflow:visible;display:flex;flex-direction:column;gap:var(--md-menu-group-gap, 4px);padding:0;filter:drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15)) drop-shadow(0 2px 6px rgba(0, 0, 0, 0.1))}:host(.md-menu--grouped.md-menu--gap) .md-menu__surface ::slotted(md-menu-item-group),:host(.md-menu--grouped.md-menu--gap) .md-menu__scroll-shadow ::slotted(md-menu-item-group){flex-shrink:0}:host(.md-menu--grouped.md-menu--gap) .md-menu__scroll-shadow{display:flex;flex-direction:column;row-gap:var(--md-menu-group-gap, 4px)}:host(.md-menu--sectioned.md-menu--baseline) .md-menu__surface ::slotted([gap]){margin-bottom:var(--md-menu-section-gap, 2px)}.md-menu__empty{display:none;padding:var(--md-sys-spacing-inset-md, 12px) var(--md-sys-spacing-inset-lg, 16px);font-family:var(--md-sys-typescale-body-medium-font-family, Roboto, sans-serif);font-size:var(--md-sys-typescale-body-medium-size, 14px);line-height:var(--md-sys-typescale-body-medium-line-height, 20px);color:var(--md-sys-color-on-surface-variant, #49454F);text-align:center}:host(.md-menu--empty) .md-menu__empty{display:block}:host([density='-1']){--md-sys-density-scale:-1}:host([density='-2']){--md-sys-density-scale:-2}:host([density='-3']){--md-sys-density-scale:-3}:host([density='-4']){--md-sys-density-scale:-4}`;const d=150;const o=500;const m=8;const u=600;const h=new Set(["button","combobox","link","menuitem","tab","treeitem","checkbox","gridcell","row","rowheader","columnheader"]);const c=new Set(["BUTTON","SUMMARY"]);let l=0;const f=e(class e extends t{constructor(e){super();if(e!==false){this.__registerHost()}this.__attachShadow();this.mdOpen=s(this,"mdOpen",1);this.mdClose=s(this,"mdClose",1);this.open=false;this.anchor="";this.placement="bottom-start";this.quick=false;this.variant="baseline";this.layout="standard";this.useGap=false;this.emptyText="";this.matchAnchorWidth=false;this.responsive=false;this.persistent=false;this.autoFocus=true;this.closing=false;this.sectioned=false;this.empty=false;this.hasSubmenu=false;this.focusedIndex=-1;this.navSeq=0;this.ringedIndex=-1;this.skipAutoFocus=false;this.menuId=`md-menu-${++l}`;this.typeaheadBuffer="";this.keyboardModality=false;this.openedViaKeyboard=false;this.listboxMode=false;this.listbox=false;this.density=0;this.trackKeyboardModality=()=>{this.keyboardModality=true};this.trackPointerModality=()=>{this.keyboardModality=false};this.lastSurfaceSize="";this.handleOutsideClick=e=>{if(this.persistent)return;const t=e.composedPath();if(!t.includes(this.el)){this.close()}};this.handleDocumentKeyDown=e=>{if(e.key==="Escape"&&this.open){this.close();this.restoreFocusToAnchor()}};this.handleScroll=()=>{if(this.open&&!this.closing){this.positionMenu()}};this.handleSlotChange=()=>{this.updateSections();this.propagateVariant();this.wireItemObserver();this.updateEmpty();this.hasSubmenu=!!this.el.querySelector("md-sub-menu-item")}}get asListbox(){return this.listbox||this.listboxMode}async setComboboxElement(e){if(this.comboboxEl&&this.comboboxEl!==e){this.comboboxEl.removeAttribute("aria-activedescendant")}this.comboboxEl=e??undefined}connectedCallback(){if(typeof document==="undefined")return;document.addEventListener("keydown",this.trackKeyboardModality,true);document.addEventListener("pointerdown",this.trackPointerModality,true)}componentDidLoad(){if(this.open){this.applyDepthZIndex()}this.wireItemObserver();this.updateEmpty();this.propagateVariant()}onEmptyTextChange(){this.updateEmpty()}onVariantChange(){this.propagateVariant()}async setVirtualProvider(e){this.provider=e??undefined;this.listboxMode=!!this.provider}async getScrollViewport(){return this.el.shadowRoot?.querySelector(".md-menu__scroll-shadow")??null}async show(e){clearTimeout(this.closeTimer);this.closing=false;if(this.anchor)this.collapseSubmenus();this.skipAutoFocus=e?.autoFocus===false;this.open=true;this.applyDepthZIndex()}async reposition(){if(this.open)this.positionMenu()}async close(){if(!this.open||this.closing)return;if(this.quick){this.open=false;return}this.closing=true;this.closeTimer=setTimeout((()=>{this.closing=false;this.open=false}),d)}onOpenChange(e){if(e){this.openedViaKeyboard=this.keyboardModality;this.dismissPeerMenus();this.applyDepthZIndex();requestAnimationFrame((()=>this.positionMenu()));this.mdOpen.emit();this.updateAnchorAria(true);if(this.anchor){requestAnimationFrame((()=>{document.addEventListener("click",this.handleOutsideClick);document.addEventListener("keydown",this.handleDocumentKeyDown)}));window.addEventListener("scroll",this.handleScroll,true);window.addEventListener("resize",this.handleScroll);this.observeSurfaceResize()}if(this.skipAutoFocus||!this.autoFocus){this.scheduleFocus((()=>this.initRovingTabindex()))}else{this.scheduleFocus((()=>this.focusFirstItem()))}this.skipAutoFocus=false}else{this.mdClose.emit();this.focusedIndex=-1;this.updateAnchorAria(false);this.resetRovingTabindex();this.collapseSubmenus();if(this.anchor){document.removeEventListener("click",this.handleOutsideClick);document.removeEventListener("keydown",this.handleDocumentKeyDown);window.removeEventListener("scroll",this.handleScroll,true);window.removeEventListener("resize",this.handleScroll)}this.unobserveSurfaceResize()}}observeSurfaceResize(){if(typeof ResizeObserver==="undefined")return;const e=this.el.shadowRoot?.querySelector(".md-menu__surface");if(!e)return;this.lastSurfaceSize="";this.surfaceRO=new ResizeObserver((e=>{if(!this.open)return;const t=e[e.length-1]?.contentRect;if(!t)return;const s=`${Math.round(t.width)}x${Math.round(t.height)}`;if(s===this.lastSurfaceSize)return;this.lastSurfaceSize=s;this.positionMenu()}));this.surfaceRO.observe(e)}unobserveSurfaceResize(){this.surfaceRO?.disconnect();this.surfaceRO=undefined}handleFocusIn(e){if(!this.open)return;const t=e.target;if(this.provider){const e=t.closest("md-menu-item");const s=e?.getAttribute("data-vindex");if(e&&s!=null){const t=parseInt(s,10);if(!isNaN(t)&&t!==this.focusedIndex){const s=this.focusedIndex>=0?this.provider.domItemForIndex(this.focusedIndex):null;s?.setAttribute("tabindex","-1");this.focusedIndex=t;e.setAttribute("tabindex","0");if(this.ringedIndex>=0&&this.ringedIndex!==t){const e=this.provider.domItemForIndex(this.ringedIndex);e?.removeAttribute("data-md-focused")}this.ringedIndex=-1}}return}const s=this.getMenuItems();const i=s.indexOf(t);if(i>=0&&i!==this.focusedIndex){if(this.focusedIndex>=0&&this.focusedIndex<s.length){s[this.focusedIndex].setAttribute("tabindex","-1")}this.focusedIndex=i;t.setAttribute("tabindex","0")}}handleKeyDown(e){if(!this.open)return;const t=e.target;if(t&&t.closest("md-menu")!==this.el)return;if(this.provider){this.handleKeyDownVirtual(e);return}const s=this.getMenuItems();if(!s.length)return;switch(e.key){case"ArrowDown":e.preventDefault();this.focusItem(s,this.focusedIndex+1);break;case"ArrowUp":e.preventDefault();this.focusItem(s,this.focusedIndex-1);break;case"Home":e.preventDefault();this.focusItem(s,0);break;case"End":e.preventDefault();this.focusItem(s,s.length-1);break;case"Escape":e.preventDefault();this.close();this.restoreFocusToAnchor();break;case"Tab":e.stopPropagation();this.closeEntireMenuTree();this.restoreFocusToAnchor();break;default:if(e.key.length===1&&!e.ctrlKey&&!e.metaKey&&!e.altKey&&!e.shiftKey){this.handleTypeahead(e.key,s)}break}}handleKeyDownVirtual(e){const t=this.provider;const s=t.count();const i=e.target?.tagName==="INPUT";switch(e.key){case"ArrowDown":e.preventDefault();this.focusVirtual(this.nextEnabled(this.focusedIndex,1,s));break;case"ArrowUp":e.preventDefault();this.focusVirtual(this.nextEnabled(this.focusedIndex,-1,s));break;case"Home":e.preventDefault();this.focusVirtual(this.nextEnabled(-1,1,s));break;case"End":e.preventDefault();this.focusVirtual(this.nextEnabled(s,-1,s));break;case"Enter":if(this.comboboxEl&&this.focusedIndex>=0){e.preventDefault();this.provider.domItemForIndex(this.focusedIndex)?.click()}break;case"Escape":e.preventDefault();this.close();this.restoreFocusToAnchor();break;case"Tab":e.stopPropagation();this.closeEntireMenuTree();this.restoreFocusToAnchor();break;default:if(!i&&e.key.length===1&&!e.ctrlKey&&!e.metaKey&&!e.altKey&&!e.shiftKey){this.handleTypeaheadVirtual(e.key)}break}}nextEnabled(e,t,s){if(s<=0)return-1;let i=e;for(let e=0;e<s;e++){i+=t;if(i<0)i=s-1;else if(i>=s)i=0;if(!this.provider.isDisabledAt(i))return i}return e>=0&&e<s?e:-1}async focusVirtual(e,t=true){if(e<0)return;const s=this.provider;const i=++this.navSeq;this.focusedIndex=e;await s.ensureVisible(e);if(i!==this.navSeq)return;const n=s.domItemForIndex(e);if(!n)return;if(this.ringedIndex>=0&&this.ringedIndex!==e){const e=s.domItemForIndex(this.ringedIndex);e?.setAttribute("tabindex","-1");e?.removeAttribute("data-md-focused")}if(t){n.setAttribute("data-md-focused","");this.ringedIndex=e}else{n.removeAttribute("data-md-focused");this.ringedIndex=-1}if(this.comboboxEl){n.id||(n.id=`${this.menuId}-opt-${e}`);if(n.id)this.comboboxEl.setAttribute("aria-activedescendant",n.id)}else{n.setAttribute("tabindex","0");n.focus({preventScroll:true})}}handleTypeaheadVirtual(e){clearTimeout(this.typeaheadTimer);this.typeaheadBuffer+=e.toLowerCase();this.typeaheadTimer=setTimeout((()=>{this.typeaheadBuffer=""}),o);const t=this.typeaheadBuffer.length===1?this.focusedIndex+1:this.focusedIndex;const s=this.provider.findPrefix(this.typeaheadBuffer,t<0?0:t);if(s>=0)this.focusVirtual(s)}getMenuItems(){const e=Array.from(this.el.querySelectorAll("md-menu-item, md-sub-menu-item"));return e.filter((e=>e.closest("md-menu")===this.el))}getItemLabel(e){return e.headline||e.textContent?.trim()||""}handleTypeahead(e,t){clearTimeout(this.typeaheadTimer);this.typeaheadBuffer+=e.toLowerCase();this.typeaheadTimer=setTimeout((()=>{this.typeaheadBuffer=""}),o);const s=this.typeaheadBuffer.length===1?this.focusedIndex+1:this.focusedIndex;for(let e=0;e<t.length;e++){const i=(s+e)%t.length;const n=this.getItemLabel(t[i]).toLowerCase();if(n.startsWith(this.typeaheadBuffer)){this.focusItem(t,i);return}}}focusItem(e,t,s=true){if(e.length===0)return;if(t<0)t=e.length-1;if(t>=e.length)t=0;if(this.focusedIndex>=0&&this.focusedIndex<e.length){e[this.focusedIndex].setAttribute("tabindex","-1");e[this.focusedIndex].removeAttribute("data-md-focused")}this.focusedIndex=t;e[t].setAttribute("tabindex","0");if(s){e[t].setAttribute("data-md-focused","")}else{e[t].removeAttribute("data-md-focused")}e[t].focus()}initRovingTabindex(){if(this.provider){this.focusedIndex=-1;return}const e=this.getMenuItems();e.forEach(((e,t)=>{e.setAttribute("tabindex",t===0?"0":"-1")}));this.focusedIndex=0}resetRovingTabindex(){if(this.provider){const e=this.focusedIndex>=0?this.provider.domItemForIndex(this.focusedIndex):null;e?.setAttribute("tabindex","-1");e?.removeAttribute("data-md-focused");if(this.ringedIndex>=0&&this.ringedIndex!==this.focusedIndex){const e=this.provider.domItemForIndex(this.ringedIndex);e?.setAttribute("tabindex","-1");e?.removeAttribute("data-md-focused")}this.ringedIndex=-1;this.comboboxEl?.removeAttribute("aria-activedescendant");return}const e=this.getMenuItems();e.forEach((e=>{e.setAttribute("tabindex","-1");e.removeAttribute("data-md-focused")}))}collapseSubmenus(){const e=Array.from(this.el.querySelectorAll("md-sub-menu-item"));e.forEach((e=>e.collapse?.()));const t=Array.from(this.el.querySelectorAll("md-menu-item, md-sub-menu-item"));t.forEach((e=>{e.removeAttribute("data-md-focused");e.setAttribute("tabindex","-1")}))}scheduleFocus(e){setTimeout((()=>requestAnimationFrame((()=>e()))),0)}focusFirstItem(e=3){if(this.provider){const t=this.provider.count();if(t>0){this.focusVirtual(this.nextEnabled(-1,1,t),this.openedViaKeyboard)}else if(e>0){this.scheduleFocus((()=>this.focusFirstItem(e-1)))}return}const t=this.getMenuItems();if(t.length){this.focusItem(t,0,this.openedViaKeyboard)}else if(e>0){this.scheduleFocus((()=>this.focusFirstItem(e-1)))}}getAnchorEl(e=this.anchor){if(!e)return null;const t=this.el.getRootNode();return t.getElementById?.(e)??document.getElementById(e)}updateAnchorAria(e){if(!this.anchor)return;const t=this.getAnchorEl();if(!t)return;const s=t.getAttribute("role");const i=s!==null?h.has(s):c.has(t.tagName)||t.tagName==="A"&&t.hasAttribute("href");if(e){t.setAttribute("aria-haspopup",this.asListbox?"listbox":"menu");if(!this.asListbox)t.setAttribute("aria-controls",this.menuId)}if(i)t.setAttribute("aria-expanded",e?"true":"false");else t.removeAttribute("aria-expanded")}applyDepthZIndex(){if(!this.anchor)return;this.el.style.zIndex="var(--md-sys-z-index-popup, 1000)"}positionMenu(){if(!this.anchor)return;const e=this.getAnchorEl();if(!e)return;const t=e.getBoundingClientRect();const s=this.el.shadowRoot?.querySelector(".md-menu__surface");if(!s)return;const i=4;s.style.minWidth=this.matchAnchorWidth?`${t.width}px`:"";this.el.style.top="0";this.el.style.left="0";this.el.style.right="auto";this.el.style.bottom="auto";const n=s.offsetWidth;let r=s.offsetHeight;if(n===0||r===0){requestAnimationFrame((()=>this.positionMenu()));return}const a=window.innerWidth;const d=window.innerHeight;const o=m;if(this.responsive&&a<=u){const e=s.offsetHeight;let n=t.bottom+i;if(n+e+o>d&&t.top-i-e>=o){n=t.top-i-e;s.style.transformOrigin="bottom left"}else{s.style.transformOrigin="top left"}n=Math.max(o,Math.min(n,d-e-o));this.el.style.top=`${n}px`;this.el.style.left=`${o}px`;return}let h=this.placement.startsWith("bottom")?"bottom":"top";let c=this.placement.endsWith("start")?"start":"end";const l=d-t.bottom-i-o;const f=t.top-i-o;if(h==="bottom"&&r>l){if(r<=f||this.scrollCapped&&f>l)h="top"}else if(h==="top"&&r>f){if(r<=l||this.scrollCapped&&l>f)h="bottom"}if(c==="start"&&t.left+n>a){if(t.right-n>=0)c="end"}else if(c==="end"&&t.right-n<0){if(t.left+n<=a)c="start"}if(this.scrollCapped){const e=h==="bottom"?l:f;const t=s.querySelector(".md-menu__scroll-shadow");const i=s.offsetHeight-(t?.offsetHeight??0);this.el.style.setProperty("--md-menu-avail-block",`${Math.max(48,e-i)}px`);r=s.offsetHeight}else{this.el.style.removeProperty("--md-menu-avail-block")}const p=h==="bottom"?"top":"bottom";const b=c==="start"?"left":"right";s.style.transformOrigin=`${p} ${b}`;const x=h==="bottom"?t.bottom+i:t.top-i-r;const v=c==="start"?t.left:t.right-n;const y=Math.max(o,Math.min(v,a-n-o));const g=Math.max(o,Math.min(x,d-r-o));this.el.style.top=`${g}px`;this.el.style.left=`${y}px`}restoreFocusToAnchor(){if(!this.anchor)return;const e=this.getAnchorEl();e?.focus()}closeEntireMenuTree(){let e=this.el;let t=this.el;while(t){const s=t.parentElement?.closest("md-menu");if(s){e=s;t=s}else{break}}const s=e.querySelectorAll("md-menu-item, md-sub-menu-item");s.forEach((e=>e.setAttribute("tabindex","-1")));if(e.close)e.close();const i=e.anchor;if(i){const t=e.getRootNode();const s=t.getElementById?.(i)??document.getElementById(i);s?.focus()}}dismissPeerMenus(){if(this.persistent)return;if(typeof document==="undefined")return;const e=Array.from(document.querySelectorAll("md-menu"));for(const t of e){if(t===this.el)continue;if(!t.open)continue;if(t.persistent)continue;if(t.contains(this.el))continue;if(this.el.contains(t))continue;t.close()}}isHidden(e){if(e.hasAttribute("hidden"))return true;if(e.style.display==="none")return true;return false}hasVisibleItem(e){if(this.isHidden(e))return false;const t=e.tagName.toLowerCase();if(t==="md-menu-item"||t==="md-sub-menu-item")return true;if(t==="md-menu-item-group"){return Array.from(e.children).some((e=>this.hasVisibleItem(e)))}return false}updateEmpty(){if(!this.emptyText){this.empty=false;return}const e=this.getContentSlot();if(!e)return;const t=e.assignedElements();this.empty=!t.some((e=>this.hasVisibleItem(e)))}wireItemObserver(){this.itemObserver?.disconnect();if(typeof MutationObserver==="undefined")return;const e=this.getContentSlot();if(!e)return;const t=e.assignedElements();if(t.length===0)return;this.itemObserver=new MutationObserver((()=>this.updateEmpty()));for(const e of t){this.itemObserver.observe(e,{attributes:true,attributeFilter:["style","hidden"],subtree:true})}}getContentSlot(){const e=this.el.shadowRoot;if(!e)return null;const t=Array.from(e.querySelectorAll("slot"));return t.find((e=>!e.getAttribute("name")))??null}propagateVariant(){const e=this.getContentSlot();if(!e)return;const t=e.assignedElements();for(const e of t){e.setAttribute("data-variant",this.variant);if(e.tagName.toLowerCase()==="md-menu-item-group"){if(this.useGap){e.setAttribute("data-use-gap","")}else{e.removeAttribute("data-use-gap")}const t=e.querySelectorAll("md-menu-item, md-sub-menu-item");for(const e of Array.from(t)){e.setAttribute("data-variant",this.variant)}}}}updateSections(){const e=this.getContentSlot();if(!e)return;const t=e.assignedElements();let s=false;let i=false;for(const e of t){if(i){e.setAttribute("data-after-gap","");i=false}else{e.removeAttribute("data-after-gap")}if(e.hasAttribute("gap")){s=true;i=true}}this.sectioned=s}disconnectedCallback(){document.removeEventListener("click",this.handleOutsideClick);document.removeEventListener("keydown",this.handleDocumentKeyDown);document.removeEventListener("keydown",this.trackKeyboardModality,true);document.removeEventListener("pointerdown",this.trackPointerModality,true);window.removeEventListener("scroll",this.handleScroll,true);window.removeEventListener("resize",this.handleScroll);clearTimeout(this.closeTimer);clearTimeout(this.typeaheadTimer);this.itemObserver?.disconnect();this.itemObserver=undefined;this.unobserveSurfaceResize();this.updateAnchorAria(false)}get inlineFill(){return this.el.classList.contains("md-menu--inline-fill")}get maxHeightValue(){if(this.maxHeight===undefined||this.maxHeight===null||this.maxHeight===""){return null}const e=String(this.maxHeight);return/^\d+(\.\d+)?$/.test(e)?`${e}px`:e}get scrollCapped(){return!this.hasSubmenu&&!this.inlineFill}get useScrollViewport(){return this.inlineFill||this.scrollCapped}renderMenuBody(){return[i("slot",{onSlotchange:this.handleSlotChange}),this.emptyText?i("span",{class:"md-menu__empty",part:"empty-text",role:"status"},this.emptyText):null]}render(){return i(n,{key:"349ce271693310ea70aa98cb3980029e3afa1594",class:{"md-menu":true,"md-menu--open":this.open,"md-menu--closing":this.closing,"md-menu--quick":this.quick,[`md-menu--${this.variant}`]:true,[`md-menu--${this.layout}`]:this.variant!=="baseline","md-menu--gap":this.useGap,"md-menu--sectioned":this.sectioned,"md-menu--empty":this.empty,"md-menu--responsive":this.responsive,"md-menu--has-submenu":this.hasSubmenu,"md-menu--scroll":this.scrollCapped},"aria-hidden":!this.open||this.closing?"true":"false",inert:!this.open||this.closing},i("div",{key:"9a3e0ab8f4586b4164412fe972acbbf4cbc3000a",class:"md-menu__surface",part:"surface",role:this.asListbox?"presentation":"menu",id:this.menuId,"aria-orientation":this.asListbox?undefined:"vertical","aria-labelledby":this.asListbox?undefined:this.anchor||undefined},i("slot",{key:"abf20ee5e25dfcc174f8aa45814b6603b77e1c65",name:"header"}),this.useScrollViewport?i("div",{class:"md-menu__scroll-shadow",part:"menu-viewport",tabindex:this.asListbox?"0":undefined,style:this.inlineFill?undefined:{maxBlockSize:this.maxHeightValue?`min(${this.maxHeightValue}, var(--md-menu-avail-block, 100dvh), calc(100dvh - 2 * var(--md-menu-viewport-margin, 8px)))`:`min(var(--md-menu-avail-block, 100dvh), calc(100dvh - 2 * var(--md-menu-viewport-margin, 8px)))`}},this.renderMenuBody()):this.renderMenuBody()))}get el(){return this}static get watchers(){return{emptyText:[{onEmptyTextChange:0}],variant:[{onVariantChange:0}],useGap:[{onVariantChange:0}],open:[{onOpenChange:0}]}}static get style(){return a()}},[257,"md-menu",{open:[1540],anchor:[1],placement:[513],quick:[4],variant:[513],layout:[513],useGap:[516,"use-gap"],emptyText:[1,"empty-text"],matchAnchorWidth:[516,"match-anchor-width"],responsive:[516],persistent:[516],autoFocus:[516,"auto-focus"],maxHeight:[8,"max-height"],listLabel:[1,"list-label"],listbox:[516],density:[514],closing:[32],sectioned:[32],empty:[32],hasSubmenu:[32],listboxMode:[32],setComboboxElement:[64],setVirtualProvider:[64],getScrollViewport:[64],show:[64],reposition:[64],close:[64]},[[0,"focusin","handleFocusIn"],[0,"keydown","handleKeyDown"]],{emptyText:[{onEmptyTextChange:0}],variant:[{onVariantChange:0}],useGap:[{onVariantChange:0}],open:[{onOpenChange:0}]}]);function p(){if(typeof customElements==="undefined"){return}const e=["md-menu"];e.forEach((e=>{switch(e){case"md-menu":if(!customElements.get(r(e))){customElements.define(r(e),f)}break}}))}p();export{f as M,p as d};
|
|
2
|
+
//# sourceMappingURL=p-CCMritCA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["mdMenuCss","CLOSE_ANIMATION_MS","TYPEAHEAD_TIMEOUT_MS","VIEWPORT_MARGIN","COMPACT_BREAKPOINT","EXPANDABLE_ANCHOR_ROLES","Set","NATIVE_EXPANDABLE_TAGS","menuIdCounter","MdMenu","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","open","anchor","placement","quick","variant","layout","useGap","emptyText","matchAnchorWidth","responsive","persistent","autoFocus","closing","sectioned","empty","hasSubmenu","focusedIndex","navSeq","ringedIndex","skipAutoFocus","menuId","typeaheadBuffer","keyboardModality","openedViaKeyboard","listboxMode","listbox","density","trackKeyboardModality","trackPointerModality","lastSurfaceSize","handleOutsideClick","e","path","composedPath","includes","el","close","handleDocumentKeyDown","key","restoreFocusToAnchor","handleScroll","positionMenu","handleSlotChange","updateSections","propagateVariant","wireItemObserver","updateEmpty","querySelector","asListbox","setComboboxElement","comboboxEl","removeAttribute","undefined","connectedCallback","document","addEventListener","componentDidLoad","applyDepthZIndex","onEmptyTextChange","onVariantChange","setVirtualProvider","provider","getScrollViewport","shadowRoot","show","opts","clearTimeout","closeTimer","collapseSubmenus","reposition","setTimeout","onOpenChange","dismissPeerMenus","requestAnimationFrame","mdOpen","emit","updateAnchorAria","window","observeSurfaceResize","scheduleFocus","initRovingTabindex","focusFirstItem","mdClose","resetRovingTabindex","removeEventListener","unobserveSurfaceResize","ResizeObserver","surface","surfaceRO","entries","r","length","contentRect","size","Math","round","width","height","observe","disconnect","handleFocusIn","target","item","closest","attr","getAttribute","index","parseInt","isNaN","prev","domItemForIndex","setAttribute","ringed","items","getMenuItems","indexOf","handleKeyDown","handleKeyDownVirtual","preventDefault","focusItem","stopPropagation","closeEntireMenuTree","ctrlKey","metaKey","altKey","shiftKey","handleTypeahead","p","count","fromInput","tagName","focusVirtual","nextEnabled","click","handleTypeaheadVirtual","from","dir","idx","i","isDisabledAt","showRing","seq","ensureVisible","node","old","id","focus","preventScroll","char","typeaheadTimer","toLowerCase","findPrefix","all","Array","querySelectorAll","filter","getItemLabel","headline","textContent","trim","startIndex","label","startsWith","forEach","subItems","collapse","allItems","fn","retries","getAnchorEl","root","getRootNode","getElementById","anchorEl","anchorRole","supportsExpanded","has","hasAttribute","style","zIndex","anchorRect","getBoundingClientRect","gap","minWidth","top","left","right","bottom","menuW","offsetWidth","menuH","offsetHeight","vw","innerWidth","vh","innerHeight","m","h","transformOrigin","max","min","vertical","horizontal","endsWith","spaceBelow","spaceAbove","scrollCapped","avail","scrollEl","chrome","setProperty","removeProperty","vOrigin","hOrigin","clampedLeft","clampedTop","rootMenu","current","parentMenu","parentElement","anchorId","peer","contains","isHidden","display","hasVisibleItem","tag","children","some","child","slot","getContentSlot","assignedElements","itemObserver","MutationObserver","attributes","attributeFilter","subtree","slots","find","s","nested","foundGap","afterGap","disconnectedCallback","inlineFill","classList","maxHeightValue","maxHeight","raw","String","test","useScrollViewport","renderMenuBody","onSlotchange","class","part","role","render","Host","inert","name","tabindex","maxBlockSize"],"sources":["src/components/md-menu/md-menu.css?tag=md-menu&encapsulation=shadow","src/components/md-menu/md-menu.tsx"],"sourcesContent":["/* ═══════════════════════════════════════════════════════════\n md-menu\n Material Design 3 — Menus\n https://m3.material.io/components/menus/specs\n\n Variants:\n baseline — MD3 original (8px corners, surface container)\n standard — M3 Expressive vertical (16px corners, surface-based)\n vibrant — M3 Expressive vertical (16px corners, tertiary-based)\n\n CSS custom properties:\n --md-menu-min-width Min container width (default 112px)\n --md-menu-max-width Max container width (default 280px)\n --md-menu-inline-surface-color Background for md-menu--inline-fill only (default transparent)\n --md-menu-inline-fill-radius-end Bottom corner radius for inline-fill embed (default 0)\n --md-sys-z-index-popup Stack order (default 1000)\n\n Parts: (none — container is internal)\n Slots: (default) — accepts md-menu-item, md-sub-menu-item\n ═══════════════════════════════════════════════════════════ */\n\n/* ==========================================================\n 1. HOST\n ========================================================== */\n:host {\n display: block;\n position: fixed;\n z-index: auto;\n pointer-events: none;\n}\n\n:host(.md-menu--open) {\n pointer-events: auto;\n}\n\n/* ==========================================================\n 2. SURFACE — BASELINE\n ========================================================== */\n.md-menu__surface {\n background-color: var(--md-sys-color-surface-container, #F7F2FA);\n border-radius: var(--md-sys-shape-corner-small, 8px);\n box-shadow:\n 0 1px 2px rgba(0, 0, 0, 0.3),\n 0 2px 6px 2px rgba(0, 0, 0, 0.15);\n min-width: var(--md-menu-min-width, 112px);\n /* Grow to fit the widest item, bounded only by the viewport (minus an edge\n margin) — long labels no longer truncate at a fixed 280px. Consumers wanting\n the MD3 280dp cap (or any cap) set --md-menu-max-width; we still clamp that\n to the viewport so it can never run off-screen. */\n max-width: min(\n var(--md-menu-max-width, 100vw),\n calc(100vw - 2 * var(--md-menu-viewport-margin, 8px))\n );\n /* Inline padding is 0 by design: baseline menu rows are FULL-BLEED, so their\n hover / focus / selected state layer runs edge to edge (M3 gives the menu\n list vertical padding only). An inline inset here leaves the highlight\n floating in a gutter — visible on md-select, which uses this surface.\n The vertical `standard` / `vibrant` variants override this with a real\n inline inset further down, because THEIR rows are rounded plates and need\n the breathing room for the corner radius. */\n padding: var(--md-sys-spacing-inset-xs, 4px) 0;\n overflow: visible;\n opacity: 0;\n transform: scaleY(0.8);\n transform-origin: top left;\n transition:\n opacity var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1)),\n transform var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n\n:host(.md-menu--open) .md-menu__surface {\n opacity: 1;\n transform: none;\n}\n\n/* --- Close animation --- */\n:host(.md-menu--closing) .md-menu__surface {\n opacity: 0;\n transform: scaleY(0.8);\n transition:\n opacity var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)),\n transform var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15));\n}\n\n/* Keep pointer-events active during close so ripple finishes */\n:host(.md-menu--closing) {\n pointer-events: none;\n}\n\n:host(.md-menu--quick) .md-menu__surface {\n transition: none;\n}\n\n/* --- Inline fill: embedded in a flex parent (e.g. md-date-picker docked panel) --- */\n:host(.md-menu--inline-fill) {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-block-size: 0;\n block-size: 100%;\n inline-size: 100%;\n pointer-events: auto;\n}\n\n:host(.md-menu--inline-fill) .md-menu__surface {\n flex: 1 1 auto;\n block-size: 100%;\n min-block-size: 0;\n min-inline-size: 100%;\n max-inline-size: none;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-shadow: none;\n border: none;\n outline: none;\n /* Baseline menus use padding: 4px 0 — strip for flush embed (e.g. date-picker). */\n padding: 0;\n border-radius: 0;\n border-end-start-radius: var(--md-menu-inline-fill-radius-end, 0);\n border-end-end-radius: var(--md-menu-inline-fill-radius-end, 0);\n /* Consumer sets --md-menu-inline-surface-color (e.g. md-date-picker docked panel). */\n background-color: var(--md-menu-inline-surface-color, transparent);\n}\n\n/* Inline-fill scroll is owned by md-scroll-shadow (edge fades when overflow). */\n:host(.md-menu--inline-fill) .md-menu__scroll-shadow {\n flex: 1 1 auto;\n min-block-size: 0;\n block-size: 100%;\n}\n\n:host(.md-menu--inline-fill) .md-menu__surface ::slotted(md-menu-item:last-child) {\n border-end-start-radius: var(--md-menu-inline-fill-radius-end, 0);\n border-end-end-radius: var(--md-menu-inline-fill-radius-end, 0);\n}\n\n/* --- Capped height: long lists scroll inside md-scroll-shadow (edge fades) --- */\n/* The scroll-shadow (display:flex column, bounded by the inline max-block-size)\n owns the vertical scroll; the surface only clips so it never double-scrolls.\n The viewport-safe rule below opts capped menus out (:not(.md-menu--scroll))\n so its `overflow-y: auto` can't compete with this. */\n:host(.md-menu--scroll):not(.md-menu--has-submenu) .md-menu__surface {\n overflow: hidden;\n}\n\n:host(.md-menu--scroll) .md-menu__scroll-shadow {\n min-block-size: 0;\n}\n\n/* The menu's scroll viewport (long lists scroll inside its inline max-block-size\n cap). Virtualized menus reposition their windowed rows by rewriting a\n multi-million-px top spacer between renders. Browser scroll-anchoring would try\n to keep the pre-render content stable and silently shift scrollTop to\n compensate — which desyncs the keyboard-nav anchor from the offset it was laid\n out for and snaps the view away. Opt out so our programmatic offset wins. */\n.md-menu__scroll-shadow {\n overflow-y: auto;\n overflow-anchor: none;\n}\n\n/* --- Match anchor width: min-width set via JS; grow to content but stay on-screen --- */\n:host([match-anchor-width]) .md-menu__surface {\n max-width: calc(100vw - 2 * var(--md-menu-viewport-margin, 8px));\n box-sizing: border-box;\n}\n\n/* ==========================================================\n 2b. RESPONSIVE / VIEWPORT-SAFE SIZING\n ========================================================== */\n\n/* Tall menus scroll instead of running off the bottom of the screen. Skipped\n when the menu has submenus — their flyouts are positioned children that\n would be clipped by an overflow on the surface — and when capped, where\n md-scroll-shadow owns the scroll instead (see the capped-height block above). */\n:host(:not(.md-menu--has-submenu):not(.md-menu--inline-fill):not(.md-menu--scroll)) .md-menu__surface {\n max-height: calc(100dvh - 2 * var(--md-menu-viewport-margin, 8px));\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n/* `responsive` on a compact viewport: near-full-width sheet below the trigger.\n Positioning (left edge + vertical flip/clamp) is handled in positionMenu(). */\n@media (max-width: 600px) {\n :host(.md-menu--responsive) .md-menu__surface {\n width: calc(100vw - 2 * var(--md-menu-viewport-margin, 8px));\n min-width: 0;\n max-width: none;\n box-sizing: border-box;\n }\n}\n\n/* ==========================================================\n 3. PLACEMENT — TRANSFORM ORIGIN\n ========================================================== */\n:host([placement=\"bottom-start\"]) .md-menu__surface { transform-origin: top left; }\n:host([placement=\"bottom-end\"]) .md-menu__surface { transform-origin: top right; }\n:host([placement=\"top-start\"]) .md-menu__surface { transform-origin: bottom left; }\n:host([placement=\"top-end\"]) .md-menu__surface { transform-origin: bottom right; }\n\n/* ==========================================================\n 4. VERTICAL MENU — STANDARD VARIANT\n ========================================================== */\n:host(.md-menu--standard) .md-menu__surface {\n background-color: var(--md-sys-color-surface-container-low, #F7F2FA);\n border-radius: var(--md-sys-shape-corner-large, 16px);\n box-shadow:\n 0 1px 3px rgba(0, 0, 0, 0.12),\n 0 4px 8px 3px rgba(0, 0, 0, 0.08);\n padding: var(--md-sys-spacing-inset-xs, 4px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item) {\n border-radius: var(--md-sys-shape-corner-small, 8px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:first-child),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:first-child) {\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:last-child),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:last-child) {\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:hover),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:hover) {\n border-radius: var(--md-sys-shape-corner-extra-small, 4px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:active),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item.md-menu-item--selected),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:active) {\n border-radius: var(--md-sys-shape-corner-medium, 12px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:first-child:hover),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:first-child:hover) {\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-start-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-end-end-radius: var(--md-sys-shape-corner-extra-small, 4px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:last-child:hover),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:last-child:hover) {\n border-start-start-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-start-end-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n/* ==========================================================\n 5. VERTICAL MENU — VIBRANT VARIANT\n ========================================================== */\n:host(.md-menu--vibrant) .md-menu__surface {\n background-color: var(--md-sys-color-tertiary-container, #FFD8E4);\n border-radius: var(--md-sys-shape-corner-large, 16px);\n box-shadow:\n 0 1px 3px rgba(0, 0, 0, 0.12),\n 0 4px 8px 3px rgba(0, 0, 0, 0.08);\n padding: var(--md-sys-spacing-inset-xs, 4px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item) {\n border-radius: var(--md-sys-shape-corner-small, 8px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:first-child),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:first-child) {\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:last-child),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:last-child) {\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:hover),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:hover) {\n border-radius: var(--md-sys-shape-corner-extra-small, 4px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:active),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item.md-menu-item--selected),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:active) {\n border-radius: var(--md-sys-shape-corner-medium, 12px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:first-child:hover),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:first-child:hover) {\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-start-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-end-end-radius: var(--md-sys-shape-corner-extra-small, 4px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:last-child:hover),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:last-child:hover) {\n border-start-start-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-start-end-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n/* ==========================================================\n 6. GAP LAYOUT — uniform gap between all items\n ========================================================== */\n:host(.md-menu--gap) .md-menu__surface {\n gap: var(--md-sys-spacing-gap-xs, 4px);\n display: flex;\n flex-direction: column;\n}\n\n/* ==========================================================\n 6b. GROUPED + GAP — each md-menu-item-group becomes a card\n container. The surface is transparent; groups get their\n own background, separated by a gap.\n ========================================================== */\n:host(.md-menu--grouped.md-menu--gap.md-menu--standard) .md-menu__surface,\n:host(.md-menu--grouped.md-menu--gap.md-menu--vibrant) .md-menu__surface {\n background-color: transparent;\n box-shadow: none;\n overflow: visible;\n display: flex;\n flex-direction: column;\n /* The gap between group cards is a FLEX GAP, not a margin on the cards. A\n margin would have to be declared on the group's `:host`, and document-tree\n rules beat host styles — so a consumer's `* { margin: 0 }` reset (Starlight,\n Tailwind preflight, any normalise) silently collapsed the cards flush\n together. A height-capped menu nests the groups inside\n `.md-menu__scroll-shadow`, so that container repeats the gap below. */\n gap: var(--md-menu-group-gap, 4px);\n padding: 0;\n filter:\n drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15))\n drop-shadow(0 2px 6px rgba(0, 0, 0, 0.1));\n}\n\n/* The gap needs a flex container, and flex items shrink by default — in a short\n viewport that squashed each group card instead of overflowing, and because the\n cards clip (`overflow: hidden`) their rows were cut off rather than scrolled\n to. Pin the cards to their natural height so the viewport scrolls instead. */\n:host(.md-menu--grouped.md-menu--gap) .md-menu__surface ::slotted(md-menu-item-group),\n:host(.md-menu--grouped.md-menu--gap) .md-menu__scroll-shadow ::slotted(md-menu-item-group) {\n flex-shrink: 0;\n}\n\n/* When a height cap nests the groups inside the scroll viewport, that viewport\n is their flex parent — repeat the gap there so it survives the wrapper. */\n:host(.md-menu--grouped.md-menu--gap) .md-menu__scroll-shadow {\n display: flex;\n flex-direction: column;\n row-gap: var(--md-menu-group-gap, 4px);\n}\n\n/* --- Baseline: gap as spacing only --- */\n:host(.md-menu--sectioned.md-menu--baseline) .md-menu__surface ::slotted([gap]) {\n margin-bottom: var(--md-menu-section-gap, 2px);\n}\n\n/* ==========================================================\n 7. EMPTY STATE\n ========================================================== */\n.md-menu__empty {\n display: none;\n padding: var(--md-sys-spacing-inset-md, 12px) var(--md-sys-spacing-inset-lg, 16px);\n font-family: var(--md-sys-typescale-body-medium-font-family, Roboto, sans-serif);\n font-size: var(--md-sys-typescale-body-medium-size, 14px);\n line-height: var(--md-sys-typescale-body-medium-line-height, 20px);\n color: var(--md-sys-color-on-surface-variant, #49454F);\n text-align: center;\n}\n\n:host(.md-menu--empty) .md-menu__empty {\n display: block;\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, Method, Watch, Listen } from '@stencil/core';\nimport { MenuElement, VirtualMenuProvider } from '../../utils/types';\n\nconst CLOSE_ANIMATION_MS = 150;\nconst TYPEAHEAD_TIMEOUT_MS = 500;\n/** Gap kept between the menu surface and every viewport edge when clamping. */\nconst VIEWPORT_MARGIN = 8;\n/** MD3 \"compact\" window-class breakpoint — below this `responsive` goes full-width. */\nconst COMPACT_BREAKPOINT = 600;\n/** Anchor roles for which `aria-expanded` is a valid, announced state. A roleless\n * anchor (e.g. a md-text-field trigger host) can't carry it — see updateAnchorAria. */\nconst EXPANDABLE_ANCHOR_ROLES = new Set([\n 'button', 'combobox', 'link', 'menuitem', 'tab', 'treeitem', 'checkbox', 'gridcell', 'row', 'rowheader', 'columnheader',\n]);\n/** Native tags whose IMPLICIT role supports aria-expanded (used when the anchor\n * sets no explicit `role` — a custom element like md-text-field is roleless). */\nconst NATIVE_EXPANDABLE_TAGS = new Set(['BUTTON', 'SUMMARY']);\n\nlet menuIdCounter = 0;\n\n@Component({ tag: 'md-menu', styleUrl: 'md-menu.css', shadow: true })\nexport class MdMenu {\n @Element() el!: HTMLElement;\n\n /** Whether the menu is open. */\n @Prop({ mutable: true, reflect: true }) open: boolean = false;\n /** ID of the anchor element to position relative to. */\n @Prop() anchor: string = '';\n /** Position of the menu relative to the anchor. */\n @Prop({ reflect: true }) placement: 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end' = 'bottom-start';\n /** Skip open/close animation. */\n @Prop() quick: boolean = false;\n /**\n * Visual variant.\n * - 'baseline': MD3 baseline menu (square corners, surface container)\n * - 'standard': M3 Expressive vertical menu (rounded, surface-based colors)\n * - 'vibrant': M3 Expressive vertical menu (rounded, tertiary-based colors)\n */\n @Prop({ reflect: true }) variant: 'baseline' | 'standard' | 'vibrant' = 'baseline';\n /** Layout style for vertical menus. 'standard' is flat, 'grouped' uses visual section separators. */\n @Prop({ reflect: true }) layout: 'standard' | 'grouped' = 'standard';\n /** Use gap separators instead of dividers between groups (vertical menu only). */\n @Prop({ attribute: 'use-gap', reflect: true }) useGap: boolean = false;\n /** Message shown when all menu items are hidden (e.g. no filter results). Empty string disables. */\n @Prop({ attribute: 'empty-text' }) emptyText: string = '';\n /** When true, the menu surface min-width matches the anchor element's width. The menu still grows wider if items need more space. */\n @Prop({ attribute: 'match-anchor-width', reflect: true }) matchAnchorWidth: boolean = false;\n /**\n * Adapt to compact viewports. The menu is *always* clamped within the\n * viewport (it never overflows the screen and pins to the edges with a\n * margin). When `responsive` is set, on viewports at or below the compact\n * breakpoint (600px) the menu additionally expands to near-full-width\n * below the trigger for comfortable touch use.\n */\n @Prop({ reflect: true }) responsive: boolean = false;\n /**\n * When set, the menu does NOT auto-dismiss in response to interaction\n * elsewhere on the page. By default a menu closes when:\n * 1. The user clicks outside the menu and its anchor.\n * 2. Another non-persistent menu opens (single-open coordination —\n * opening menu B closes menu A so two top-level menus never\n * overlap each other on screen).\n *\n * `persistent` opts out of both auto-dismiss paths. The menu then only\n * closes via `close()`, the anchor's toggle, item activation, or\n * Escape. Useful for modal-style pickers, multi-step menus, and any\n * context where the consumer manages dismissal explicitly.\n *\n * Submenus (an `<md-menu>` rendered inside a parent menu's `submenu`\n * slot) are never affected by sibling-menu dismissal even without this\n * flag — ancestors and descendants are always preserved.\n */\n @Prop({ reflect: true }) persistent: boolean = false;\n /**\n * When false, opening the menu initializes roving tabindex without moving\n * focus to the first item. The consumer handles focus (e.g. docked pickers\n * that scroll to the selected option). `show({ autoFocus: false })` still\n * takes precedence for a single open.\n */\n @Prop({ attribute: 'auto-focus', reflect: true }) autoFocus: boolean = true;\n\n /**\n * Cap the menu surface block-size. When the items exceed it the list\n * scrolls vertically inside a plain scroll viewport. A number is treated\n * as pixels; any CSS length is passed through (e.g. `'50vh'`). Ignored\n * when the menu has submenus — their flyouts must not be clipped by an\n * overflow container.\n */\n @Prop({ attribute: 'max-height' }) maxHeight?: number | string;\n\n /**\n * Fires when the menu opens. Scoped to the menu element: `bubbles: false`\n * stops it climbing the light-DOM tree, and `composed: false` stops it\n * escaping the shadow root of a host that embeds this menu (md-select,\n * md-multi-select, md-date-picker …). Without `composed: false` a\n * `composed` event still surfaces at the embedding host as an\n * `AT_TARGET` event — so a consumer's `mdOpen` listener on the wrapper\n * would fire for both the wrapper's own event and this inner one\n * (duplicate open/close). Wrappers listen via `onMdOpen` on the menu\n * element itself, which still fires regardless.\n */\n @Event({ bubbles: false, composed: false }) mdOpen: EventEmitter<void>;\n /** Fires when the menu closes. Scoped like `mdOpen` — see its note. */\n @Event({ bubbles: false, composed: false }) mdClose: EventEmitter<void>;\n\n @State() private closing = false;\n @State() private sectioned = false;\n @State() private empty = false;\n /** True when the menu contains submenus — they fly out and must not be\n * clipped, so the surface keeps `overflow: visible` instead of scrolling. */\n @State() private hasSubmenu = false;\n\n private focusedIndex = -1;\n /**\n * Monotonic token for virtualized keyboard nav. `focusVirtual` is async (it\n * awaits `ensureVisible` to scroll the target row into the window). Under fast\n * ArrowUp/Down key-repeat the calls overlap; without this guard a superseded\n * call would resolve *after* a newer one and re-stamp `data-md-focused` on its\n * stale index — leaving a lingering focus state-layer on whatever row now sits\n * in that slot (the \"second item background flickers\" bug). Each call captures\n * the token and bails if a newer call has since incremented it.\n */\n private navSeq = 0;\n /**\n * Filtered index of the row that currently shows the visible focus ring\n * (`data-md-focused`) in provider/virtual mode, or -1 for none. The ring is\n * removed only by the *winning* `focusVirtual` call, just before it stamps the\n * new row — never synchronously up-front. That keeps the ring on a real row\n * across the whole ArrowUp/Down autorepeat burst instead of blinking off for\n * the frames between a press and its async `ensureVisible` settling.\n */\n private ringedIndex = -1;\n private closeTimer?: ReturnType<typeof setTimeout>;\n private skipAutoFocus = false;\n private menuId = `md-menu-${++menuIdCounter}`;\n private typeaheadBuffer = '';\n private typeaheadTimer?: ReturnType<typeof setTimeout>;\n private itemObserver?: MutationObserver;\n /**\n * Tracks whether the most recent interaction was via keyboard. Used to\n * decide if the initial focus ring should show when the menu opens: a\n * mouse-opened menu auto-focuses the first item (so arrow keys work)\n * but stays ring-less until the user actually uses the keyboard.\n */\n private keyboardModality = false;\n private openedViaKeyboard = false;\n\n /**\n * When set, the menu's keyboard navigation / typeahead / focus run against a\n * *virtualized* data model instead of `querySelectorAll('md-menu-item')` —\n * only the rows in the current scroll window exist in the DOM. Null = the\n * default DOM-driven behaviour (every other menu in the app). See\n * `setVirtualProvider`. In provider mode `focusedIndex` is a filtered row\n * index rather than an index into the live DOM items.\n */\n private provider?: VirtualMenuProvider;\n\n /**\n * In provider (virtualized `md-select`) mode the popup is a WAI-ARIA\n * combobox/listbox, not a menu. `listboxMode` flips the surface role to\n * `listbox` (reactive, so the role updates when a provider is registered) and\n * `comboboxEl` is the element that owns DOM focus (the select's search input):\n * keyboard nav moves `aria-activedescendant` on it instead of moving real\n * focus onto recycled virtual rows. `listboxLabel` names the listbox.\n */\n @State() private listboxMode = false;\n private comboboxEl?: HTMLElement;\n @Prop({ attribute: 'list-label' }) listLabel?: string;\n\n /**\n * Present the popup as a WAI-ARIA listbox (surface `role=\"presentation\"`,\n * anchor `aria-haspopup=\"listbox\"`) rather than a menu. `md-select` sets this\n * for both its virtual and non-virtual lists so the popup is a listbox of\n * options regardless of size. (The virtual path additionally registers a\n * provider, which adds the aria-activedescendant focus model.)\n */\n @Prop({ reflect: true }) listbox: boolean = false;\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** True when the popup should expose listbox semantics (prop or provider). */\n private get asListbox(): boolean {\n return this.listbox || this.listboxMode;\n }\n\n /**\n * Register (or clear with `null`) the combobox element that holds focus while\n * a virtual provider drives the list. When set, keyboard navigation manages\n * `aria-activedescendant` on it rather than calling `.focus()` on options —\n * the canonical pattern for a listbox whose rows are virtualized/recycled.\n */\n @Method()\n async setComboboxElement(el: HTMLElement | null) {\n if (this.comboboxEl && this.comboboxEl !== el) {\n this.comboboxEl.removeAttribute('aria-activedescendant');\n }\n this.comboboxEl = el ?? undefined;\n }\n\n connectedCallback() {\n if (typeof document === 'undefined') return;\n document.addEventListener('keydown', this.trackKeyboardModality, true);\n document.addEventListener('pointerdown', this.trackPointerModality, true);\n }\n\n private trackKeyboardModality = () => { this.keyboardModality = true; };\n private trackPointerModality = () => { this.keyboardModality = false; };\n\n componentDidLoad() {\n if (this.open) {\n this.applyDepthZIndex();\n }\n // Run an initial scan so a menu that mounts already-empty\n // (e.g. SSR snapshot, or items hidden before first paint)\n // shows the empty-state on its first frame instead of after\n // the first slotchange.\n this.wireItemObserver();\n this.updateEmpty();\n // Propagate variant/use-gap to slotted groups on load. The initial\n // `slotchange` can fire before our handler is wired (so it's missed), which\n // left grouped+gap groups without their data-variant/data-use-gap\n // attributes — the group cards then have no background (transparent surface,\n // floating items). componentDidLoad runs once children are assigned, so this\n // is the reliable initial pass; handleSlotChange keeps it in sync after.\n this.propagateVariant();\n }\n\n @Watch('emptyText')\n onEmptyTextChange() {\n this.updateEmpty();\n }\n\n // Re-propagate to slotted groups/items when the visual variant or gap mode\n // changes at runtime (e.g. via Storybook controls) — reflect only updates the\n // host attribute, not the children the group-card CSS keys off.\n @Watch('variant')\n @Watch('useGap')\n onVariantChange() {\n this.propagateVariant();\n }\n\n /**\n * Register (or clear with `null`) a virtual provider. With a provider set,\n * keyboard nav, typeahead, and roving focus run against the data model so a\n * windowed list of millions of options behaves like a normal menu. Without\n * one the menu is unchanged.\n */\n @Method()\n async setVirtualProvider(provider: VirtualMenuProvider | null) {\n this.provider = provider ?? undefined;\n // Flip the surface to a listbox (reactive via @State) so the virtualized\n // select's popup is exposed as a WAI-ARIA listbox, not a menu.\n this.listboxMode = !!this.provider;\n }\n\n /**\n * The scrollable viewport element (the menu's `.md-menu__scroll-shadow`\n * scroll div), or null when the menu isn't capped/scrollable. A virtualized\n * host attaches its scroll listener and reads `scrollTop`/`clientHeight`\n * from this.\n */\n @Method()\n async getScrollViewport(): Promise<HTMLElement | null> {\n return (\n (this.el.shadowRoot?.querySelector('.md-menu__scroll-shadow') as HTMLElement | null) ??\n null\n );\n }\n\n /** Opens the menu programmatically. Pass `{ autoFocus: false }` to keep focus on the caller (e.g. a text field). */\n @Method()\n async show(opts?: { autoFocus?: boolean }) {\n clearTimeout(this.closeTimer);\n this.closing = false;\n // Top-level menus always (re)open from a clean state. This also covers\n // the case where a prior close was interrupted — e.g. clicking the\n // trigger fires the anchor's show() which cancels the close timer, so\n // `open` never flips to false and the close-path reset never runs.\n // Submenus (no anchor) are skipped so live drill-down isn't disturbed.\n if (this.anchor) this.collapseSubmenus();\n this.skipAutoFocus = opts?.autoFocus === false;\n this.open = true;\n this.applyDepthZIndex();\n }\n\n /**\n * Recompute the menu's position against its anchor. md-menu already reacts to\n * scroll/resize, but not to the anchor MOVING because sibling content reflowed\n * (e.g. a multi-select whose button trigger shifts as chips are added beside\n * it). Call this after such a reflow to keep the popup glued to the anchor.\n */\n @Method()\n async reposition() {\n if (this.open) this.positionMenu();\n }\n\n /** Closes the menu programmatically. */\n @Method()\n async close() {\n if (!this.open || this.closing) return;\n\n if (this.quick) {\n this.open = false;\n return;\n }\n\n this.closing = true;\n this.closeTimer = setTimeout(() => {\n this.closing = false;\n this.open = false;\n }, CLOSE_ANIMATION_MS);\n }\n\n @Watch('open')\n onOpenChange(open: boolean) {\n if (open) {\n // Snapshot the modality that triggered this open; the actual focus\n // is deferred (scheduleFocus), so capture it now before it drifts.\n this.openedViaKeyboard = this.keyboardModality;\n this.dismissPeerMenus();\n this.applyDepthZIndex();\n requestAnimationFrame(() => this.positionMenu());\n this.mdOpen.emit();\n this.updateAnchorAria(true);\n if (this.anchor) {\n requestAnimationFrame(() => {\n document.addEventListener('click', this.handleOutsideClick);\n document.addEventListener('keydown', this.handleDocumentKeyDown);\n });\n window.addEventListener('scroll', this.handleScroll, true);\n window.addEventListener('resize', this.handleScroll);\n this.observeSurfaceResize();\n }\n if (this.skipAutoFocus || !this.autoFocus) {\n this.scheduleFocus(() => this.initRovingTabindex());\n } else {\n // Always move focus to the first item so it leaves the trigger\n // (a mouse-clicked trigger must not keep its keyboard ring). The\n // ring on the item itself is shown only for keyboard opens — see\n // focusFirstItem(): mouse opens focus the item ring-less, and the\n // ring appears once the user navigates with the keyboard.\n this.scheduleFocus(() => this.focusFirstItem());\n }\n this.skipAutoFocus = false;\n } else {\n this.mdClose.emit();\n this.focusedIndex = -1;\n this.updateAnchorAria(false);\n this.resetRovingTabindex();\n this.collapseSubmenus();\n if (this.anchor) {\n document.removeEventListener('click', this.handleOutsideClick);\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n window.removeEventListener('scroll', this.handleScroll, true);\n window.removeEventListener('resize', this.handleScroll);\n }\n this.unobserveSurfaceResize();\n }\n }\n\n /** Reposition when the open surface's own size changes — e.g. an\n * autocomplete's list shrinking as the user types. A top-flipped menu\n * positioned for the taller list would otherwise keep its stale `top`\n * and float detached above the anchor. */\n private surfaceRO?: ResizeObserver;\n private lastSurfaceSize = '';\n\n private observeSurfaceResize() {\n if (typeof ResizeObserver === 'undefined') return;\n const surface = this.el.shadowRoot?.querySelector('.md-menu__surface');\n if (!surface) return;\n this.lastSurfaceSize = '';\n this.surfaceRO = new ResizeObserver((entries) => {\n if (!this.open) return;\n const r = entries[entries.length - 1]?.contentRect;\n if (!r) return;\n // Guard against feedback loops: only reposition on a REAL size change\n // (positionMenu itself tweaks min-width, which would re-fire once).\n const size = `${Math.round(r.width)}x${Math.round(r.height)}`;\n if (size === this.lastSurfaceSize) return;\n this.lastSurfaceSize = size;\n this.positionMenu();\n });\n this.surfaceRO.observe(surface);\n }\n\n private unobserveSurfaceResize() {\n this.surfaceRO?.disconnect();\n this.surfaceRO = undefined;\n }\n\n @Listen('focusin')\n handleFocusIn(e: FocusEvent) {\n if (!this.open) return;\n const target = e.target as HTMLElement;\n\n if (this.provider) {\n // Map a pointer-focused windowed item back to its filtered index via the\n // `data-vindex` the host stamps on each rendered row.\n const item = target.closest('md-menu-item') as HTMLElement | null;\n const attr = item?.getAttribute('data-vindex');\n if (item && attr != null) {\n const index = parseInt(attr, 10);\n if (!isNaN(index) && index !== this.focusedIndex) {\n const prev =\n this.focusedIndex >= 0 ? this.provider.domItemForIndex(this.focusedIndex) : null;\n prev?.setAttribute('tabindex', '-1');\n this.focusedIndex = index;\n item.setAttribute('tabindex', '0');\n // Pointer focus is ring-less; drop any deferred keyboard ring still\n // seated on a different row so it can't linger after a hover/click.\n if (this.ringedIndex >= 0 && this.ringedIndex !== index) {\n const ringed = this.provider.domItemForIndex(this.ringedIndex);\n ringed?.removeAttribute('data-md-focused');\n }\n this.ringedIndex = -1;\n }\n }\n return;\n }\n\n const items = this.getMenuItems();\n const index = items.indexOf(target);\n if (index >= 0 && index !== this.focusedIndex) {\n if (this.focusedIndex >= 0 && this.focusedIndex < items.length) {\n items[this.focusedIndex].setAttribute('tabindex', '-1');\n }\n this.focusedIndex = index;\n target.setAttribute('tabindex', '0');\n }\n }\n\n @Listen('keydown')\n handleKeyDown(e: KeyboardEvent) {\n if (!this.open) return;\n\n const target = e.target as HTMLElement;\n if (target && target.closest('md-menu') !== this.el) return;\n\n if (this.provider) {\n this.handleKeyDownVirtual(e);\n return;\n }\n\n const items = this.getMenuItems();\n if (!items.length) return;\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this.focusItem(items, this.focusedIndex + 1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.focusItem(items, this.focusedIndex - 1);\n break;\n case 'Home':\n e.preventDefault();\n this.focusItem(items, 0);\n break;\n case 'End':\n e.preventDefault();\n this.focusItem(items, items.length - 1);\n break;\n case 'Escape':\n e.preventDefault();\n this.close();\n this.restoreFocusToAnchor();\n break;\n case 'Tab':\n e.stopPropagation();\n this.closeEntireMenuTree();\n // Return focus to the trigger (like Escape) so it doesn't fall to <body>\n // when the focused option/search input unmounts; the user tabs onward from\n // there.\n this.restoreFocusToAnchor();\n break;\n default:\n if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey) {\n this.handleTypeahead(e.key, items);\n }\n break;\n }\n }\n\n // ── Virtualized (provider) navigation ────────────────────\n // Mirrors the DOM-driven path but operates on filtered row indices in the\n // provider's data model, scrolling the target row into the rendered window\n // (ensureVisible) before moving real focus to it. `focusedIndex` is a\n // filtered index here, not a DOM-items index.\n\n private handleKeyDownVirtual(e: KeyboardEvent) {\n const p = this.provider!;\n const count = p.count();\n // Keystrokes inside a header search field (the filterable select) type into\n // the input; only navigation keys are intercepted for the list.\n const fromInput = (e.target as HTMLElement)?.tagName === 'INPUT';\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this.focusVirtual(this.nextEnabled(this.focusedIndex, 1, count));\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.focusVirtual(this.nextEnabled(this.focusedIndex, -1, count));\n break;\n case 'Home':\n e.preventDefault();\n this.focusVirtual(this.nextEnabled(-1, 1, count));\n break;\n case 'End':\n e.preventDefault();\n this.focusVirtual(this.nextEnabled(count, -1, count));\n break;\n case 'Enter':\n // In combobox mode the input keeps focus, so the active option never\n // receives the keystroke itself — activate it here. (In roving-focus\n // mode the focused option handles its own Enter, so don't double-fire.)\n if (this.comboboxEl && this.focusedIndex >= 0) {\n e.preventDefault();\n this.provider!.domItemForIndex(this.focusedIndex)?.click();\n }\n break;\n case 'Escape':\n e.preventDefault();\n this.close();\n this.restoreFocusToAnchor();\n break;\n case 'Tab':\n e.stopPropagation();\n this.closeEntireMenuTree();\n // Return focus to the trigger (like Escape) so it doesn't fall to <body>\n // when the focused option/search input unmounts; the user tabs onward from\n // there.\n this.restoreFocusToAnchor();\n break;\n default:\n if (\n !fromInput &&\n e.key.length === 1 &&\n !e.ctrlKey &&\n !e.metaKey &&\n !e.altKey &&\n !e.shiftKey\n ) {\n this.handleTypeaheadVirtual(e.key);\n }\n break;\n }\n }\n\n /**\n * Next non-disabled filtered index from `from` in `dir` (±1), wrapping like\n * the DOM path. Returns -1 only when every row is disabled / the list empty.\n */\n private nextEnabled(from: number, dir: number, count: number): number {\n if (count <= 0) return -1;\n let idx = from;\n for (let i = 0; i < count; i++) {\n idx += dir;\n if (idx < 0) idx = count - 1;\n else if (idx >= count) idx = 0;\n if (!this.provider!.isDisabledAt(idx)) return idx;\n }\n return from >= 0 && from < count ? from : -1;\n }\n\n private async focusVirtual(index: number, showRing = true) {\n if (index < 0) return;\n const p = this.provider!;\n const seq = ++this.navSeq;\n // Advance the logical active index immediately, but do NOT strip the visible\n // ring from the old row up-front: `ensureVisible` is async, and under\n // ArrowUp/Down autorepeat each press supersedes the last. Removing the ring\n // here left ~1-in-4 frames with no ring on any row (the held-key flicker).\n // The winning call below swaps the ring atomically once its row is windowed.\n this.focusedIndex = index;\n await p.ensureVisible(index);\n // A newer keystroke superseded this one while we awaited the scroll. Bail so\n // we don't re-stamp the focus ring / move focus to this now-stale row — the\n // latest call owns those. The current ring stays put (we never removed it).\n if (seq !== this.navSeq) return;\n const node = p.domItemForIndex(index);\n if (!node) return;\n // Atomic swap: clear the previously ringed row, then ring/seat the new one,\n // so the ring is never absent between the two.\n if (this.ringedIndex >= 0 && this.ringedIndex !== index) {\n const old = p.domItemForIndex(this.ringedIndex);\n old?.setAttribute('tabindex', '-1');\n old?.removeAttribute('data-md-focused');\n }\n if (showRing) {\n node.setAttribute('data-md-focused', '');\n this.ringedIndex = index;\n } else {\n node.removeAttribute('data-md-focused');\n this.ringedIndex = -1;\n }\n if (this.comboboxEl) {\n // WAI-ARIA combobox/listbox: focus stays on the combobox (the select's\n // search input); the active option is conveyed via aria-activedescendant.\n // This is the robust model for a virtualized listbox — no real focus is\n // moved onto rows that scroll out of the window and get recycled. The\n // option keeps tabindex -1 (only the combobox is in the tab order).\n node.id ||= `${this.menuId}-opt-${index}`;\n if (node.id) this.comboboxEl.setAttribute('aria-activedescendant', node.id);\n } else {\n // No combobox (e.g. a non-filterable virtual list): fall back to the\n // standalone-listbox roving-focus model.\n node.setAttribute('tabindex', '0');\n // ensureVisible already revealed the row; preventScroll stops the browser's\n // own scroll-into-view from fighting the (anchor-driven) virtual window.\n node.focus({ preventScroll: true });\n }\n }\n\n private handleTypeaheadVirtual(char: string) {\n clearTimeout(this.typeaheadTimer);\n this.typeaheadBuffer += char.toLowerCase();\n this.typeaheadTimer = setTimeout(() => {\n this.typeaheadBuffer = '';\n }, TYPEAHEAD_TIMEOUT_MS);\n\n const from =\n this.typeaheadBuffer.length === 1 ? this.focusedIndex + 1 : this.focusedIndex;\n const idx = this.provider!.findPrefix(this.typeaheadBuffer, from < 0 ? 0 : from);\n if (idx >= 0) this.focusVirtual(idx);\n }\n\n private getMenuItems(): HTMLElement[] {\n const all = Array.from(\n this.el.querySelectorAll('md-menu-item, md-sub-menu-item')\n ) as HTMLElement[];\n return all.filter(item => item.closest('md-menu') === this.el);\n }\n\n private getItemLabel(item: HTMLElement): string {\n return (item as MenuElement).headline || item.textContent?.trim() || '';\n }\n\n private handleTypeahead(char: string, items: HTMLElement[]) {\n clearTimeout(this.typeaheadTimer);\n this.typeaheadBuffer += char.toLowerCase();\n this.typeaheadTimer = setTimeout(() => { this.typeaheadBuffer = ''; }, TYPEAHEAD_TIMEOUT_MS);\n\n const startIndex = this.typeaheadBuffer.length === 1\n ? this.focusedIndex + 1\n : this.focusedIndex;\n\n for (let i = 0; i < items.length; i++) {\n const idx = (startIndex + i) % items.length;\n const label = this.getItemLabel(items[idx]).toLowerCase();\n if (label.startsWith(this.typeaheadBuffer)) {\n this.focusItem(items, idx);\n return;\n }\n }\n }\n\n private focusItem(items: HTMLElement[], index: number, showRing = true) {\n if (items.length === 0) return;\n if (index < 0) index = items.length - 1;\n if (index >= items.length) index = 0;\n\n if (this.focusedIndex >= 0 && this.focusedIndex < items.length) {\n items[this.focusedIndex].setAttribute('tabindex', '-1');\n items[this.focusedIndex].removeAttribute('data-md-focused');\n }\n\n this.focusedIndex = index;\n items[index].setAttribute('tabindex', '0');\n // `data-md-focused` is the visible focus ring. Keyboard navigation always\n // shows it; a mouse-opened menu focuses without it (see focusFirstItem)\n // so the ring only appears once the user reaches for the keyboard.\n if (showRing) {\n items[index].setAttribute('data-md-focused', '');\n } else {\n items[index].removeAttribute('data-md-focused');\n }\n items[index].focus();\n }\n\n private initRovingTabindex() {\n if (this.provider) {\n // No focus move (skipAutoFocus path, e.g. a combobox whose search input\n // keeps focus). Seat the active index *before* the first row (-1) so the\n // first ArrowDown lands on the first item — seating it on row 0 instead\n // made the first ArrowDown skip to the second item. Nothing is active /\n // ringed until the user actually arrows.\n this.focusedIndex = -1;\n return;\n }\n const items = this.getMenuItems();\n items.forEach((item, i) => {\n item.setAttribute('tabindex', i === 0 ? '0' : '-1');\n });\n this.focusedIndex = 0;\n }\n\n private resetRovingTabindex() {\n if (this.provider) {\n const node =\n this.focusedIndex >= 0 ? this.provider.domItemForIndex(this.focusedIndex) : null;\n node?.setAttribute('tabindex', '-1');\n node?.removeAttribute('data-md-focused');\n // Also clear any deferred ring still seated on a different row.\n if (this.ringedIndex >= 0 && this.ringedIndex !== this.focusedIndex) {\n const ringed = this.provider.domItemForIndex(this.ringedIndex);\n ringed?.setAttribute('tabindex', '-1');\n ringed?.removeAttribute('data-md-focused');\n }\n this.ringedIndex = -1;\n // Drop the active-option pointer on the combobox so a screen reader\n // doesn't announce a stale active row after the listbox closes.\n this.comboboxEl?.removeAttribute('aria-activedescendant');\n return;\n }\n const items = this.getMenuItems();\n items.forEach(item => {\n item.setAttribute('tabindex', '-1');\n item.removeAttribute('data-md-focused');\n });\n }\n\n /**\n * Reset the entire subtree when this menu closes: collapse every\n * descendant submenu and clear lingering focus markers / tabindex at\n * all depths. Without this, reopening the menu restores whichever\n * submenu was open and whichever item was focused last time.\n */\n private collapseSubmenus() {\n const subItems = Array.from(\n this.el.querySelectorAll('md-sub-menu-item')\n ) as Array<HTMLElement & { collapse?: () => Promise<void> }>;\n subItems.forEach(item => item.collapse?.());\n\n const allItems = Array.from(\n this.el.querySelectorAll('md-menu-item, md-sub-menu-item')\n ) as HTMLElement[];\n allItems.forEach(item => {\n item.removeAttribute('data-md-focused');\n item.setAttribute('tabindex', '-1');\n });\n }\n\n private scheduleFocus(fn: () => void) {\n setTimeout(() => requestAnimationFrame(() => fn()), 0);\n }\n\n private focusFirstItem(retries = 3) {\n if (this.provider) {\n const count = this.provider.count();\n if (count > 0) {\n // Ring only on keyboard opens, matching the DOM path.\n this.focusVirtual(this.nextEnabled(-1, 1, count), this.openedViaKeyboard);\n } else if (retries > 0) {\n this.scheduleFocus(() => this.focusFirstItem(retries - 1));\n }\n return;\n }\n const items = this.getMenuItems();\n if (items.length) {\n // Only show the ring on auto-focus when the menu was opened by keyboard.\n this.focusItem(items, 0, this.openedViaKeyboard);\n } else if (retries > 0) {\n this.scheduleFocus(() => this.focusFirstItem(retries - 1));\n }\n }\n\n /**\n * Resolve the anchor element by id. Looks within the menu's own root node\n * first — so a menu rendered inside another component's shadow root (e.g.\n * md-select) finds a sibling trigger that `document.getElementById` can't\n * see across the shadow boundary — then falls back to the document for\n * light-DOM anchors.\n */\n private getAnchorEl(id: string = this.anchor): HTMLElement | null {\n if (!id) return null;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n return (\n (root.getElementById?.(id) as HTMLElement | null) ??\n document.getElementById(id)\n );\n }\n\n private updateAnchorAria(open: boolean) {\n if (!this.anchor) return;\n const anchorEl = this.getAnchorEl();\n if (!anchorEl) return;\n\n // aria-expanded is only VALID on roles that support it. Some anchors can't\n // carry it — e.g. a md-text-field trigger whose HOST is roleless (its textbox\n // role sits on the inner input): a screen reader ignores it there and axe\n // flags aria-supported-attr. Gate it on the anchor's role; the popup stays\n // discoverable via aria-haspopup + focus moving into the menu, and role-bearing\n // triggers (a role=\"button\" opener) still get it.\n const anchorRole = anchorEl.getAttribute('role');\n const supportsExpanded =\n anchorRole !== null\n ? EXPANDABLE_ANCHOR_ROLES.has(anchorRole)\n : NATIVE_EXPANDABLE_TAGS.has(anchorEl.tagName) ||\n (anchorEl.tagName === 'A' && anchorEl.hasAttribute('href'));\n\n if (open) {\n anchorEl.setAttribute('aria-haspopup', this.asListbox ? 'listbox' : 'menu');\n // In listbox/provider mode the OWNER (md-select / md-multi-select) renders the\n // real role=\"listbox\" in ITS OWN shadow and points the trigger's aria-controls\n // at it (an in-scope IDREF). Don't clobber that with menuId, which identifies\n // this menu's role=\"presentation\" surface in a DIFFERENT shadow root (an\n // unresolvable cross-shadow reference).\n if (!this.asListbox) anchorEl.setAttribute('aria-controls', this.menuId);\n }\n if (supportsExpanded) anchorEl.setAttribute('aria-expanded', open ? 'true' : 'false');\n else anchorEl.removeAttribute('aria-expanded');\n }\n\n private applyDepthZIndex() {\n if (!this.anchor) return;\n this.el.style.zIndex = 'var(--md-sys-z-index-popup, 1000)';\n }\n\n private positionMenu() {\n if (!this.anchor) return;\n const anchorEl = this.getAnchorEl();\n if (!anchorEl) return;\n\n const anchorRect = anchorEl.getBoundingClientRect();\n const surface = this.el.shadowRoot?.querySelector('.md-menu__surface') as HTMLElement;\n if (!surface) return;\n\n const gap = 4;\n surface.style.minWidth = this.matchAnchorWidth ? `${anchorRect.width}px` : '';\n\n // Park at top-left with right/bottom cleared so stale inline styles\n // cannot shrink-to-fit the surface and corrupt the measurements.\n this.el.style.top = '0';\n this.el.style.left = '0';\n this.el.style.right = 'auto';\n this.el.style.bottom = 'auto';\n\n const menuW = surface.offsetWidth;\n let menuH = surface.offsetHeight;\n\n if (menuW === 0 || menuH === 0) {\n requestAnimationFrame(() => this.positionMenu());\n return;\n }\n\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const m = VIEWPORT_MARGIN;\n\n // Compact + responsive: drop the trigger-relative horizontal placement and\n // present a near-full-width sheet below (or above, if cramped) the anchor.\n // The CSS media query sizes the surface to `100vw - 2*margin`.\n if (this.responsive && vw <= COMPACT_BREAKPOINT) {\n const h = surface.offsetHeight;\n let top = anchorRect.bottom + gap;\n if (top + h + m > vh && anchorRect.top - gap - h >= m) {\n top = anchorRect.top - gap - h;\n surface.style.transformOrigin = 'bottom left';\n } else {\n surface.style.transformOrigin = 'top left';\n }\n top = Math.max(m, Math.min(top, vh - h - m));\n this.el.style.top = `${top}px`;\n this.el.style.left = `${m}px`;\n return;\n }\n\n let vertical: 'bottom' | 'top' = this.placement.startsWith('bottom') ? 'bottom' : 'top';\n let horizontal: 'start' | 'end' = this.placement.endsWith('start') ? 'start' : 'end';\n\n const spaceBelow = vh - anchorRect.bottom - gap - m;\n const spaceAbove = anchorRect.top - gap - m;\n\n // Keep the requested vertical side if the menu fits; otherwise flip to the side\n // that fits. A CAPPED (scrollable) menu that fits neither side picks the side\n // with MORE room and shrinks its scroll region to it (below), so it scrolls\n // instead of being clamped over the anchor.\n if (vertical === 'bottom' && menuH > spaceBelow) {\n if (menuH <= spaceAbove || (this.scrollCapped && spaceAbove > spaceBelow)) vertical = 'top';\n } else if (vertical === 'top' && menuH > spaceAbove) {\n if (menuH <= spaceBelow || (this.scrollCapped && spaceBelow > spaceAbove)) vertical = 'bottom';\n }\n\n if (horizontal === 'start' && anchorRect.left + menuW > vw) {\n if (anchorRect.right - menuW >= 0) horizontal = 'end';\n } else if (horizontal === 'end' && anchorRect.right - menuW < 0) {\n if (anchorRect.left + menuW <= vw) horizontal = 'start';\n }\n\n // Cap a scrollable menu's height to the chosen side's available space so it\n // scrolls instead of overflowing or being clamped across the anchor. Only\n // capped menus have the scroll viewport that makes this safe.\n if (this.scrollCapped) {\n const avail = vertical === 'bottom' ? spaceBelow : spaceAbove;\n const scrollEl = surface.querySelector('.md-menu__scroll-shadow') as HTMLElement | null;\n const chrome = surface.offsetHeight - (scrollEl?.offsetHeight ?? 0); // header + padding\n this.el.style.setProperty('--md-menu-avail-block', `${Math.max(48, avail - chrome)}px`);\n menuH = surface.offsetHeight; // re-measure after the cap reflows the surface\n } else {\n this.el.style.removeProperty('--md-menu-avail-block');\n }\n\n const vOrigin = vertical === 'bottom' ? 'top' : 'bottom';\n const hOrigin = horizontal === 'start' ? 'left' : 'right';\n surface.style.transformOrigin = `${vOrigin} ${hOrigin}`;\n\n const top = vertical === 'bottom'\n ? anchorRect.bottom + gap\n : anchorRect.top - gap - menuH;\n\n const left = horizontal === 'start'\n ? anchorRect.left\n : anchorRect.right - menuW;\n\n // Viewport clamp (always on): keep the surface fully on-screen with a\n // margin so it never bleeds off any edge. Width is capped in CSS, so a\n // clamp to `margin` here simply pins an oversized menu to the edge.\n const clampedLeft = Math.max(m, Math.min(left, vw - menuW - m));\n const clampedTop = Math.max(m, Math.min(top, vh - menuH - m));\n\n this.el.style.top = `${clampedTop}px`;\n this.el.style.left = `${clampedLeft}px`;\n }\n\n private restoreFocusToAnchor() {\n if (!this.anchor) return;\n const anchorEl = this.getAnchorEl();\n anchorEl?.focus();\n }\n\n private closeEntireMenuTree() {\n let rootMenu: MenuElement = this.el as unknown as MenuElement;\n let current: HTMLElement | null = this.el;\n while (current) {\n const parentMenu = current.parentElement?.closest('md-menu') as MenuElement | null;\n if (parentMenu) {\n rootMenu = parentMenu;\n current = parentMenu;\n } else {\n break;\n }\n }\n\n const allItems = rootMenu.querySelectorAll('md-menu-item, md-sub-menu-item');\n allItems.forEach(item => item.setAttribute('tabindex', '-1'));\n\n if (rootMenu.close) rootMenu.close();\n\n const anchorId = rootMenu.anchor;\n if (anchorId) {\n const root = (rootMenu as unknown as HTMLElement).getRootNode() as\n | Document\n | ShadowRoot;\n const anchorEl =\n (root.getElementById?.(anchorId) as HTMLElement | null) ??\n document.getElementById(anchorId);\n anchorEl?.focus();\n }\n }\n\n private handleOutsideClick = (e: MouseEvent) => {\n if (this.persistent) return;\n const path = e.composedPath();\n if (!path.includes(this.el)) {\n this.close();\n }\n };\n\n /**\n * Single-open coordination. When this menu opens, dismiss every other\n * non-persistent top-level menu currently open on the page so two\n * unrelated menus never overlap. Ancestors and descendants of `this`\n * are deliberately preserved — submenus must not close their parent\n * menu when they open, and parent menus must not nuke an in-flight\n * submenu the user is interacting with.\n */\n private dismissPeerMenus() {\n if (this.persistent) return;\n if (typeof document === 'undefined') return;\n const all = Array.from(document.querySelectorAll('md-menu')) as MenuElement[];\n for (const peer of all) {\n if (peer === this.el) continue;\n if (!peer.open) continue;\n if (peer.persistent) continue;\n if (peer.contains(this.el)) continue;\n if (this.el.contains(peer)) continue;\n peer.close();\n }\n }\n\n private handleDocumentKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && this.open) {\n this.close();\n this.restoreFocusToAnchor();\n }\n };\n\n private handleScroll = () => {\n if (this.open && !this.closing) {\n this.positionMenu();\n }\n };\n\n private handleSlotChange = () => {\n this.updateSections();\n this.propagateVariant();\n this.wireItemObserver();\n this.updateEmpty();\n this.hasSubmenu = !!this.el.querySelector('md-sub-menu-item');\n };\n\n /**\n * Returns true when the element is *explicitly* hidden — either the HTML\n * `hidden` attribute is set, or `style=\"display: none\"` is applied\n * inline. We deliberately avoid `getComputedStyle()` here because\n * `display: none` from a stylesheet rule on `<md-menu-item>` would\n * report the element as hidden during the brief window before the\n * loader finishes registering the custom element, which would flash\n * the empty-state on every menu open.\n */\n private isHidden(el: HTMLElement): boolean {\n if (el.hasAttribute('hidden')) return true;\n if (el.style.display === 'none') return true;\n return false;\n }\n\n private hasVisibleItem(el: HTMLElement): boolean {\n if (this.isHidden(el)) return false;\n const tag = el.tagName.toLowerCase();\n if (tag === 'md-menu-item' || tag === 'md-sub-menu-item') return true;\n if (tag === 'md-menu-item-group') {\n return Array.from(el.children).some((child) =>\n this.hasVisibleItem(child as HTMLElement),\n );\n }\n return false;\n }\n\n private updateEmpty() {\n if (!this.emptyText) {\n // No empty-text configured — the empty UI is opt-in; skip the\n // class entirely so the surface stays its natural collapsed\n // height when an unconfigured menu has no items.\n this.empty = false;\n return;\n }\n const slot = this.getContentSlot();\n if (!slot) return;\n const children = slot.assignedElements() as HTMLElement[];\n this.empty = !children.some((child) => this.hasVisibleItem(child));\n }\n\n private wireItemObserver() {\n // The empty-state has to react to consumer code toggling\n // `style=\"display: none\"` / `hidden` on items (the canonical\n // type-to-filter pattern). `slotchange` fires when *children* of\n // the menu are added/removed, but NOT when their attributes\n // change in place — so a MutationObserver covers that gap.\n this.itemObserver?.disconnect();\n // Stencil's jsdom-lite test environment doesn't ship a\n // MutationObserver. Skip the observer there — the slotchange-\n // driven path still keeps the empty-state in sync, and the\n // dynamic-attribute path is exercised by browser-only e2e tests.\n if (typeof MutationObserver === 'undefined') return;\n const slot = this.getContentSlot();\n if (!slot) return;\n const children = slot.assignedElements() as HTMLElement[];\n if (children.length === 0) return;\n this.itemObserver = new MutationObserver(() => this.updateEmpty());\n for (const child of children) {\n this.itemObserver.observe(child, {\n attributes: true,\n attributeFilter: ['style', 'hidden'],\n subtree: true,\n });\n }\n }\n\n /**\n * The default (content) slot — NOT the named `header` slot, which renders\n * FIRST inside the surface (a virtualized select's pinned search field). A\n * plain `querySelector('slot')` grabs that header slot (empty for normal\n * menus), so every slot-scanning method must filter by name — otherwise\n * grouped+gap groups never receive data-variant/data-use-gap and lose their\n * card background (transparent surface → floating items). Built from\n * querySelectorAll (a simple selector Stencil's jsdom-lite mock supports)\n * rather than `slot:not([name])`, which the mock can't parse.\n */\n private getContentSlot(): HTMLSlotElement | null {\n const root = this.el.shadowRoot;\n if (!root) return null;\n const slots = Array.from(root.querySelectorAll('slot')) as HTMLSlotElement[];\n // Match on the `name` ATTRIBUTE, not the `.name` property — Stencil's\n // jsdom-lite mock doesn't reflect the attribute onto the property, so `.name`\n // is undefined there and would wrongly match the header slot first.\n return slots.find((s) => !s.getAttribute('name')) ?? null;\n }\n\n private propagateVariant() {\n const slot = this.getContentSlot();\n if (!slot) return;\n const children = slot.assignedElements() as HTMLElement[];\n for (const child of children) {\n child.setAttribute('data-variant', this.variant);\n if (child.tagName.toLowerCase() === 'md-menu-item-group') {\n if (this.useGap) {\n child.setAttribute('data-use-gap', '');\n } else {\n child.removeAttribute('data-use-gap');\n }\n const nested = child.querySelectorAll('md-menu-item, md-sub-menu-item');\n for (const item of Array.from(nested)) {\n item.setAttribute('data-variant', this.variant);\n }\n }\n }\n }\n\n private updateSections() {\n const slot = this.getContentSlot();\n if (!slot) return;\n const children = slot.assignedElements() as HTMLElement[];\n\n let foundGap = false;\n let afterGap = false;\n\n for (const child of children) {\n if (afterGap) {\n child.setAttribute('data-after-gap', '');\n afterGap = false;\n } else {\n child.removeAttribute('data-after-gap');\n }\n\n if (child.hasAttribute('gap')) {\n foundGap = true;\n afterGap = true;\n }\n }\n\n this.sectioned = foundGap;\n }\n\n disconnectedCallback() {\n document.removeEventListener('click', this.handleOutsideClick);\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n document.removeEventListener('keydown', this.trackKeyboardModality, true);\n document.removeEventListener('pointerdown', this.trackPointerModality, true);\n window.removeEventListener('scroll', this.handleScroll, true);\n window.removeEventListener('resize', this.handleScroll);\n clearTimeout(this.closeTimer);\n clearTimeout(this.typeaheadTimer);\n this.itemObserver?.disconnect();\n this.itemObserver = undefined;\n this.unobserveSurfaceResize();\n this.updateAnchorAria(false);\n }\n\n /** Embedded flex menus (e.g. md-date-picker docked month/year lists). */\n private get inlineFill(): boolean {\n return this.el.classList.contains('md-menu--inline-fill');\n }\n\n /** Resolved `max-height` as a CSS length, or null when unset. */\n private get maxHeightValue(): string | null {\n if (this.maxHeight === undefined || this.maxHeight === null || this.maxHeight === '') {\n return null;\n }\n // A bare number — or a numeric string (attributes and `md-select`\n // forwarding both arrive as strings) — is treated as pixels; any other\n // CSS length (`'50vh'`, `'20rem'`, …) is passed through verbatim.\n const raw = String(this.maxHeight);\n return /^\\d+(\\.\\d+)?$/.test(raw) ? `${raw}px` : raw;\n }\n\n /** Every regular menu (not a submenu whose flyouts must not clip, not an inline-\n * fill embed) is bounded by the viewport and scrolls inside its scroll viewport\n * when it would overflow — with OR without an explicit max-height. This keeps a\n * pinned header and plain scrolling for every overflowing menu, not just capped\n * ones. */\n private get scrollCapped(): boolean {\n return !this.hasSubmenu && !this.inlineFill;\n }\n\n /** Inline-fill and every capped menu wrap their body in a scroll viewport. */\n private get useScrollViewport(): boolean {\n return this.inlineFill || this.scrollCapped;\n }\n\n private renderMenuBody() {\n return [\n <slot onSlotchange={this.handleSlotChange} />,\n this.emptyText ? (\n <span class=\"md-menu__empty\" part=\"empty-text\" role=\"status\">\n {this.emptyText}\n </span>\n ) : null,\n ];\n }\n\n render() {\n return (\n <Host\n class={{\n 'md-menu': true,\n 'md-menu--open': this.open,\n 'md-menu--closing': this.closing,\n 'md-menu--quick': this.quick,\n [`md-menu--${this.variant}`]: true,\n [`md-menu--${this.layout}`]: this.variant !== 'baseline',\n 'md-menu--gap': this.useGap,\n 'md-menu--sectioned': this.sectioned,\n 'md-menu--empty': this.empty,\n 'md-menu--responsive': this.responsive,\n 'md-menu--has-submenu': this.hasSubmenu,\n 'md-menu--scroll': this.scrollCapped,\n }}\n aria-hidden={(!this.open || this.closing) ? 'true' : 'false'}\n // A closed menu stays in the DOM (opacity 0, never display:none, so the\n // open/close motion can play), which leaves focusable content — items, a\n // filterable select's search input — inside an aria-hidden subtree. That\n // is tab-reachable-but-invisible for keyboard users and fails axe\n // aria-hidden-focus (caught as a transient on story navigation, but the\n // closed steady state is just as affected). `inert` while hidden removes\n // the whole subtree from focus order and the a11y tree; it flips off in\n // the same render that clears aria-hidden, before any post-open focus.\n inert={!this.open || this.closing}\n >\n <div\n class=\"md-menu__surface\"\n part=\"surface\"\n // In provider/listbox mode the surface is just a container: it holds\n // the combobox (header slot) AND the listbox, so it must not itself be\n // a menu or a listbox. The host (md-select) renders the actual\n // role=\"listbox\" wrapper around the options in its own shadow root, so\n // aria-controls / aria-activedescendant IDREFs resolve.\n role={this.asListbox ? 'presentation' : 'menu'}\n id={this.menuId}\n aria-orientation={this.asListbox ? undefined : 'vertical'}\n aria-labelledby={this.asListbox ? undefined : this.anchor || undefined}\n >\n {/* Pinned header above the scroll area (e.g. a virtualized select's\n search field). Empty — and zero-cost — for every other menu. */}\n <slot name=\"header\" />\n {this.useScrollViewport ? (\n <div\n class=\"md-menu__scroll-shadow\"\n part=\"menu-viewport\"\n // Keyboard access to the scrolling option list (WCAG 2.1.1): the\n // active option's roving tabindex can sit on a PINNED HEADER item\n // (e.g. a select's \"Select all\") that lives outside this viewport,\n // leaving the scroll area with no focusable child. Make it focusable\n // — but ONLY in listbox mode. There the surface is role=\"presentation\"\n // (the owner renders the real listbox), so a focusable tabindex=\"0\"\n // viewport is harmless. In a plain role=\"menu\" the viewport would be a\n // role-less `div[tabindex]` OWNED by the menu, which axe flags as a\n // disallowed menu child (aria-required-children) — and a menu's own\n // menuitems (roving tabindex) already satisfy WCAG 2.1.1 without it.\n tabindex={this.asListbox ? '0' : undefined}\n // inline-fill is bounded by its flex parent; a capped menu is\n // bounded by max-height so the viewport scrolls within it. Clamp\n // to the viewport so an oversized cap can't run off-screen.\n style={\n this.inlineFill\n ? undefined // flexes to fill its parent; no fixed cap\n : {\n // Bound the scroll region to the smaller of any explicit\n // max-height, the space on the chosen side (--md-menu-avail-block,\n // set by positionMenu), and the viewport — so it scrolls\n // instead of overflowing, with or without max-height.\n maxBlockSize: this.maxHeightValue\n ? `min(${this.maxHeightValue}, var(--md-menu-avail-block, 100dvh), calc(100dvh - 2 * var(--md-menu-viewport-margin, 8px)))`\n : `min(var(--md-menu-avail-block, 100dvh), calc(100dvh - 2 * var(--md-menu-viewport-margin, 8px)))`,\n }\n }\n >\n {this.renderMenuBody()}\n </div>\n ) : (\n this.renderMenuBody()\n )}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{p as t,H as s,h as e,d as i,t as n}from"./p-BR6gfOQH.js";const r=()=>`:host{display:contents;border-radius:inherit;--_color:var(--md-ripple-color, currentColor)}.md-ripple{position:absolute;inset:0;border-radius:inherit;overflow:hidden;pointer-events:none}.md-ripple__wave{position:absolute;border-radius:50%;pointer-events:none;background:var(--_color);opacity:0;transform:scale(0);will-change:transform, opacity}.md-ripple{opacity:var(--md-sys-ripple-enabled, 1)}`;const o=450;const h=150;const c=.12;const a="cubic-bezier(0.2, 0, 0, 1)";const l="--md-ripple-grow-duration";const p="--md-ripple-grow-easing";const d=t(class t extends s{constructor(t){super();if(t!==false){this.__registerHost()}this.__attachShadow();this.disabled=false;this.hostEl=null;this.activeWave=null;this.growAnimation=null;this.activeOpacity=c;this.bound=false;this.settlePromise=null;this.settleResolve=null;this.onPointerDown=t=>{if(this.disabled||this.rippleSuppressed())return;const s=this.el.shadowRoot?.querySelector(".md-ripple");if(!s||!this.hostEl)return;this.endWave();const e=this.hostEl.getBoundingClientRect();const i=this.resolveExtent("--md-ripple-extend-inline");const n=this.resolveExtent("--md-ripple-extend-block");const r=e.left-i;const o=e.right+i;const h=e.top-n;const c=e.bottom+n;const a=Math.max(Math.abs(t.clientX-r),Math.abs(t.clientX-o));const l=Math.max(Math.abs(t.clientY-h),Math.abs(t.clientY-c));const p=Math.sqrt(a*a+l*l);const d=p*2;const u=t.clientX-e.left-p;const f=t.clientY-e.top-p;const m=document.createElement("span");m.classList.add("md-ripple__wave");m.style.width=m.style.height=`${d}px`;m.style.left=`${u}px`;m.style.top=`${f}px`;s.appendChild(m);this.activeWave=m;this.activeOpacity=this.resolveOpacity();this.beginSettle();this.growAnimation=m.animate([{transform:"scale(0)",opacity:this.activeOpacity},{transform:"scale(1)",opacity:this.activeOpacity}],{duration:this.resolveGrowDuration(),easing:this.resolveGrowEasing(),fill:"forwards"});window.addEventListener("pointerup",this.onRelease,{once:true});window.addEventListener("pointercancel",this.onRelease,{once:true})};this.onRelease=()=>{this.endWave()}}rippleSuppressed(){if(typeof getComputedStyle!=="function")return false;try{return getComputedStyle(this.el).getPropertyValue("--md-sys-ripple-enabled").trim()==="0"}catch{return false}}resolveOpacity(){if(!this.hostEl)return c;const t=getComputedStyle(this.hostEl).getPropertyValue("--md-ripple-opacity").trim();if(!t)return c;const s=parseFloat(t);return Number.isFinite(s)?s:c}resolveExtent(t){const s=getComputedStyle(this.el).getPropertyValue(t).trim();if(!s)return 0;const e=parseFloat(s);return Number.isFinite(e)&&e>0?e:0}resolveGrowDuration(){const t=getComputedStyle(this.el).getPropertyValue(l).trim();if(!t)return o;const s=parseFloat(t);return Number.isFinite(s)&&s>0?s:o}resolveGrowEasing(){const t=getComputedStyle(this.el).getPropertyValue(p).trim();return t||a}beginSettle(){this.finishSettle();this.settlePromise=new Promise((t=>{this.settleResolve=t}))}finishSettle(){this.settleResolve?.();this.settleResolve=null;this.settlePromise=null}async whenSettled(){if(!this.settlePromise)return;const t=new Promise((t=>{setTimeout(t,h+50)}));await Promise.race([this.settlePromise,t]);this.finishSettle()}resolveHost(){const t=this.el.getRootNode();return this.el.parentElement??(t instanceof ShadowRoot?t.host:null)}bind(){if(this.bound)return;this.hostEl=this.resolveHost();if(!this.hostEl)return;this.bound=true;this.hostEl.addEventListener("pointerdown",this.onPointerDown)}connectedCallback(){this.bind();if(!this.bound){queueMicrotask((()=>this.bind()))}}disconnectedCallback(){this.hostEl?.removeEventListener("pointerdown",this.onPointerDown);this.hostEl=null;this.bound=false}async endWave(){const t=this.activeWave;const s=this.growAnimation;if(!t||!s)return;this.activeWave=null;this.growAnimation=null;if(s.playState!=="finished"){await s.finished}const e=t.animate([{opacity:this.activeOpacity},{opacity:0}],{duration:h,easing:a,fill:"forwards"});try{if(typeof e.finished?.then==="function"){await e.finished}else{await new Promise((t=>setTimeout(t,h)))}}catch{}t.remove();this.finishSettle()}async trigger(){if(this.disabled||this.rippleSuppressed())return;if(!this.hostEl)this.hostEl=this.resolveHost();const t=this.el.shadowRoot?.querySelector(".md-ripple");if(!t||!this.hostEl)return;this.endWave();const s=this.hostEl.getBoundingClientRect();const e=this.resolveExtent("--md-ripple-extend-inline");const i=this.resolveExtent("--md-ripple-extend-block");const n=s.width/2;const r=s.height/2;const o=n+e;const h=r+i;const c=Math.sqrt(o*o+h*h);const a=c*2;const l=document.createElement("span");l.classList.add("md-ripple__wave");l.style.width=l.style.height=`${a}px`;l.style.left=`${n-c}px`;l.style.top=`${r-c}px`;t.appendChild(l);this.activeWave=l;this.activeOpacity=this.resolveOpacity();this.beginSettle();this.growAnimation=l.animate([{transform:"scale(0)",opacity:this.activeOpacity},{transform:"scale(1)",opacity:this.activeOpacity}],{duration:this.resolveGrowDuration(),easing:this.resolveGrowEasing(),fill:"forwards"});this.growAnimation.addEventListener("finish",(()=>this.endWave()),{once:true})}render(){return e(i,{key:"db104269176da1fe8c379500716b44c7d6575407","aria-hidden":"true"},e("div",{key:"94d23e0d1697a050e49ae66e8e8c022b20f108bd",class:"md-ripple"}))}get el(){return this}static get style(){return r()}},[1,"md-ripple",{disabled:[4],whenSettled:[64],trigger:[64]}]);function u(){if(typeof customElements==="undefined"){return}const t=["md-ripple"];t.forEach((t=>{switch(t){case"md-ripple":if(!customElements.get(n(t))){customElements.define(n(t),d)}break}}))}u();export{d as M,u as d};
|
|
2
|
+
//# sourceMappingURL=p-CTC8XAB6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["mdRippleCss","PRESS_GROW_MS","RELEASE_FADE_MS","DEFAULT_PRESS_OPACITY","EASING_STANDARD","GROW_DURATION_PROP","GROW_EASING_PROP","MdRipple","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","disabled","hostEl","activeWave","growAnimation","activeOpacity","bound","settlePromise","settleResolve","onPointerDown","e","rippleSuppressed","container","el","shadowRoot","querySelector","endWave","rect","getBoundingClientRect","extendInline","resolveExtent","extendBlock","left","right","top","bottom","dx","Math","max","abs","clientX","dy","clientY","radius","sqrt","size","x","y","wave","document","createElement","classList","add","style","width","height","appendChild","resolveOpacity","beginSettle","animate","transform","opacity","duration","resolveGrowDuration","easing","resolveGrowEasing","fill","window","addEventListener","onRelease","once","getComputedStyle","getPropertyValue","trim","raw","parsed","parseFloat","Number","isFinite","prop","finishSettle","Promise","resolve","whenSettled","maxWait","setTimeout","race","resolveHost","root","getRootNode","parentElement","ShadowRoot","host","bind","connectedCallback","queueMicrotask","disconnectedCallback","removeEventListener","grow","playState","finished","fade","then","remove","trigger","cx","cy","halfX","halfY","render","h","Host","key","class"],"sources":["src/components/md-ripple/md-ripple.css?tag=md-ripple&encapsulation=shadow","src/components/md-ripple/md-ripple.tsx"],"sourcesContent":["/* ==========================================================\n md-ripple — Material Design 3 ripple effect\n Spec: https://m3.material.io/foundations/interaction/states\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-ripple-color Ripple tint color (default: currentColor)\n --md-ripple-opacity Ripple peak opacity (default: 0.12)\n --md-ripple-extend-inline Extra pixels to add on each inline edge\n of the host's rect when computing the\n wave's farthest-corner radius. Use on\n surfaces that GROW horizontally during\n the ripple's lifetime (e.g. md-search\n springing out on focus) so the wave is\n sized for the settled rect instead of\n the resting one. Wave position is\n unaffected — the wave still originates\n at the click point. Must be a CONCRETE\n PIXEL VALUE (e.g. `120px`). Computed\n expressions involving %, calc() or\n clamp() are NOT resolved by this hook —\n read the literal token via\n getComputedStyle and parseFloat returns\n NaN on those forms. Consumers needing\n such expressions should compute the\n value in JS and write it back as fixed\n pixels via inline style. (default: 0)\n --md-ripple-extend-block Same as --md-ripple-extend-inline but\n for the block axis. (default: 0)\n --md-ripple-grow-duration Override the wave's scale 0 → 1 grow\n duration. Use on surfaces that animate\n their own size during the ripple's\n lifetime (e.g. md-search) so the wave\n reaches full size at the same instant\n the surface settles — otherwise the\n wave is still ramping up while the\n surface is already at its final width.\n var() references and any value that\n resolves to a CSS time work (e.g.\n `250ms`). (default: 450ms)\n --md-ripple-grow-easing Companion to --md-ripple-grow-duration\n — usually set to the surface's own\n easing so the wave feels like part of\n the same motion.\n (default: cubic-bezier(0.2, 0, 0, 1))\n\n CSS PARTS:\n (none)\n\n SLOTS:\n (none)\n ========================================================== */\n\n:host {\n display: contents;\n\n /* `.md-ripple` clips the wave with `border-radius: inherit`, which inherits\n from THIS host — not from the component embedding us. Left at the initial\n 0, that clip is a square, and the wave only looked round because the\n embedding host happened to clip it with its own `overflow: hidden`. Any\n host that must let something escape (an icon button with a badge) then got\n a square ripple. Inheriting the radius here makes the clip follow the\n container's shape on its own. */\n border-radius: inherit;\n\n --_color: var(--md-ripple-color, currentColor);\n}\n\n.md-ripple {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n overflow: hidden;\n pointer-events: none;\n}\n\n.md-ripple__wave {\n position: absolute;\n border-radius: 50%;\n pointer-events: none;\n background: var(--_color);\n opacity: 0;\n transform: scale(0);\n will-change: transform, opacity;\n}\n\n/* ==========================================================\n SUPPRESSION (global data-ripple=\"off\" / per-component ripple=\"off\")\n The real gate is in TS — onPointerDown and trigger() bail before a wave is\n ever created, so nothing is allocated or animated. This rule is the safety\n net for the one case TS cannot cover: a wave already mid-flight when the\n toggle flips. Without it that wave would finish its 450ms grow after ripples\n were switched off.\n\n The signal is 0/1, which is already a valid opacity, so it drops straight in\n — no keyword mapping, and the default of 1 makes this a no-op when the\n feature is on. opacity (not display) so nothing about layout or the\n containing block changes.\n ========================================================== */\n.md-ripple {\n opacity: var(--md-sys-ripple-enabled, 1);\n}\n","import { Component, Element, h, Host, Method, Prop } from '@stencil/core';\n\nconst PRESS_GROW_MS = 450;\nconst RELEASE_FADE_MS = 150;\nconst DEFAULT_PRESS_OPACITY = 0.12;\nconst EASING_STANDARD = 'cubic-bezier(0.2, 0, 0, 1)';\n\nconst GROW_DURATION_PROP = '--md-ripple-grow-duration';\nconst GROW_EASING_PROP = '--md-ripple-grow-easing';\n\n@Component({ tag: 'md-ripple', styleUrl: 'md-ripple.css', shadow: true })\nexport class MdRipple {\n @Element() el!: HTMLElement;\n\n @Prop() disabled: boolean = false;\n\n /**\n * True when ripples are switched off for this element, either globally\n * (`data-ripple=\"off\"` on any ancestor) or on the owning component\n * (`ripple=\"off\"`). Both spellings resolve to `--md-sys-ripple-enabled` in\n * tokens.css, so only the resolved value is read here.\n *\n * Read at interaction time rather than cached. The signal is a plain\n * inherited custom property, so it can change at any moment — a theme\n * switch, a settings toggle, a parent re-render — with no attribute mutation\n * on THIS element to observe. One getComputedStyle per press is cheap next to\n * the wave animation that follows, and it cannot go stale.\n *\n * The check is deliberately `=== '0'`: an unset property returns '' and must\n * mean ENABLED, so testing for falsiness would disable ripples everywhere the\n * token sheet has not loaded.\n */\n private rippleSuppressed(): boolean {\n if (typeof getComputedStyle !== 'function') return false;\n try {\n return (\n getComputedStyle(this.el).getPropertyValue('--md-sys-ripple-enabled').trim() === '0'\n );\n } catch {\n return false;\n }\n }\n\n private hostEl: HTMLElement | null = null;\n private activeWave: HTMLElement | null = null;\n private growAnimation: Animation | null = null;\n private activeOpacity: number = DEFAULT_PRESS_OPACITY;\n private bound = false;\n private settlePromise: Promise<void> | null = null;\n private settleResolve: (() => void) | null = null;\n\n private resolveOpacity(): number {\n if (!this.hostEl) return DEFAULT_PRESS_OPACITY;\n const raw = getComputedStyle(this.hostEl)\n .getPropertyValue('--md-ripple-opacity')\n .trim();\n if (!raw) return DEFAULT_PRESS_OPACITY;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) ? parsed : DEFAULT_PRESS_OPACITY;\n }\n\n /**\n * Resolve the inline / block extents that surfaces growing during the\n * ripple's lifetime (e.g. md-search springing out on focus) declare via\n * `--md-ripple-extend-inline` / `--md-ripple-extend-block`. The values\n * inflate the host's rect ONLY for the wave's farthest-corner radius\n * calculation, so the wave is sized for the SETTLED rect even though\n * the actual host is still at its resting size at pointerdown. Wave\n * POSITION still uses the unmodified rect so the wave originates\n * exactly where the user clicked.\n *\n * Consumers MUST pass concrete pixel values here (e.g.\n * `style.setProperty('--md-ripple-extend-inline', '120px')`).\n * `getComputedStyle().getPropertyValue()` on a custom property returns\n * the LITERAL TOKEN — for `calc()` / `clamp()` / `%` expressions the\n * string is unparsed (`\"calc(clamp(0px, 8%, 64px) * 2)\"`) and\n * `parseFloat()` returns `NaN`. Resolving such expressions reliably\n * requires knowing the consumer's intended containing-block reference,\n * which md-ripple cannot infer; consumers therefore compute the value\n * themselves (typically with a hidden probe element scoped to the\n * correct containing block) and write it back as fixed pixels.\n */\n private resolveExtent(prop: string): number {\n const raw = getComputedStyle(this.el).getPropertyValue(prop).trim();\n if (!raw) return 0;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;\n }\n\n /**\n * Wave grow duration (ms). Surfaces that animate their size during the\n * ripple's lifetime (e.g. md-search springing from a narrower resting\n * width to its full width) should sync the wave's growth with their\n * own settle so the wave reaches scale = 1 at the same moment the\n * surface stops moving — otherwise the wave is still ramping up while\n * the surface is already at its final width and the user sees a\n * visible gap on the side that grew. Default is the spec-canonical\n * 450ms.\n */\n private resolveGrowDuration(): number {\n const raw = getComputedStyle(this.el).getPropertyValue(GROW_DURATION_PROP).trim();\n if (!raw) return PRESS_GROW_MS;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : PRESS_GROW_MS;\n }\n\n /**\n * Wave grow easing function. Companion to {@link resolveGrowDuration}\n * — when a surface drives the timing it should usually pass its own\n * easing (typically a back-out spring) so the wave's growth feels\n * like part of the same motion.\n */\n private resolveGrowEasing(): string {\n const raw = getComputedStyle(this.el).getPropertyValue(GROW_EASING_PROP).trim();\n return raw || EASING_STANDARD;\n }\n\n private beginSettle() {\n this.finishSettle();\n this.settlePromise = new Promise<void>((resolve) => {\n this.settleResolve = resolve;\n });\n }\n\n private finishSettle() {\n this.settleResolve?.();\n this.settleResolve = null;\n this.settlePromise = null;\n }\n\n /** Resolves when the active press ripple has fully faded out. */\n @Method()\n async whenSettled(): Promise<void> {\n if (!this.settlePromise) return;\n const maxWait = new Promise<void>((resolve) => {\n setTimeout(resolve, RELEASE_FADE_MS + 50);\n });\n await Promise.race([this.settlePromise, maxWait]);\n this.finishSettle();\n }\n\n private resolveHost(): HTMLElement | null {\n const root = this.el.getRootNode();\n return this.el.parentElement ??\n (root instanceof ShadowRoot ? (root.host as HTMLElement) : null);\n }\n\n private bind() {\n if (this.bound) return;\n this.hostEl = this.resolveHost();\n if (!this.hostEl) return;\n this.bound = true;\n this.hostEl.addEventListener('pointerdown', this.onPointerDown);\n }\n\n connectedCallback() {\n this.bind();\n if (!this.bound) {\n queueMicrotask(() => this.bind());\n }\n }\n\n disconnectedCallback() {\n this.hostEl?.removeEventListener('pointerdown', this.onPointerDown);\n this.hostEl = null;\n this.bound = false;\n }\n\n private onPointerDown = (e: PointerEvent) => {\n if (this.disabled || this.rippleSuppressed()) return;\n\n const container = this.el.shadowRoot?.querySelector('.md-ripple') as HTMLElement;\n if (!container || !this.hostEl) return;\n\n this.endWave();\n\n const rect = this.hostEl.getBoundingClientRect();\n // Treat the surface as if it spans an extended rect when the host has\n // declared `--md-ripple-extend-inline` / `--md-ripple-extend-block`.\n // Wave POSITION still uses the actual (current) rect so the wave\n // visually originates at the click point — only the RADIUS uses the\n // inflated bounds so the wave grows large enough to cover the surface\n // once it settles.\n const extendInline = this.resolveExtent('--md-ripple-extend-inline');\n const extendBlock = this.resolveExtent('--md-ripple-extend-block');\n const left = rect.left - extendInline;\n const right = rect.right + extendInline;\n const top = rect.top - extendBlock;\n const bottom = rect.bottom + extendBlock;\n const dx = Math.max(Math.abs(e.clientX - left), Math.abs(e.clientX - right));\n const dy = Math.max(Math.abs(e.clientY - top), Math.abs(e.clientY - bottom));\n const radius = Math.sqrt(dx * dx + dy * dy);\n const size = radius * 2;\n const x = e.clientX - rect.left - radius;\n const y = e.clientY - rect.top - radius;\n\n const wave = document.createElement('span');\n wave.classList.add('md-ripple__wave');\n wave.style.width = wave.style.height = `${size}px`;\n wave.style.left = `${x}px`;\n wave.style.top = `${y}px`;\n container.appendChild(wave);\n this.activeWave = wave;\n this.activeOpacity = this.resolveOpacity();\n this.beginSettle();\n\n this.growAnimation = wave.animate(\n [\n { transform: 'scale(0)', opacity: this.activeOpacity },\n { transform: 'scale(1)', opacity: this.activeOpacity },\n ],\n {\n duration: this.resolveGrowDuration(),\n easing: this.resolveGrowEasing(),\n fill: 'forwards',\n },\n );\n\n window.addEventListener('pointerup', this.onRelease, { once: true });\n window.addEventListener('pointercancel', this.onRelease, { once: true });\n };\n\n private onRelease = () => {\n this.endWave();\n };\n\n private async endWave() {\n const wave = this.activeWave;\n const grow = this.growAnimation;\n if (!wave || !grow) return;\n\n this.activeWave = null;\n this.growAnimation = null;\n\n if (grow.playState !== 'finished') {\n await grow.finished;\n }\n\n const fade = wave.animate(\n [{ opacity: this.activeOpacity }, { opacity: 0 }],\n { duration: RELEASE_FADE_MS, easing: EASING_STANDARD, fill: 'forwards' },\n );\n try {\n if (typeof fade.finished?.then === 'function') {\n await fade.finished;\n } else {\n await new Promise<void>((resolve) => setTimeout(resolve, RELEASE_FADE_MS));\n }\n } catch {\n /* animation cancelled */\n }\n wave.remove();\n this.finishSettle();\n }\n\n /** Programmatically trigger a centered ripple (for keyboard activations). */\n @Method()\n async trigger() {\n if (this.disabled || this.rippleSuppressed()) return;\n\n if (!this.hostEl) this.hostEl = this.resolveHost();\n const container = this.el.shadowRoot?.querySelector('.md-ripple') as HTMLElement;\n if (!container || !this.hostEl) return;\n\n this.endWave();\n\n const rect = this.hostEl.getBoundingClientRect();\n const extendInline = this.resolveExtent('--md-ripple-extend-inline');\n const extendBlock = this.resolveExtent('--md-ripple-extend-block');\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n // Centered ripples use the rect's centre as both anchor and farthest\n // reference, so the inflated half-extents become the radius\n // contribution directly.\n const halfX = cx + extendInline;\n const halfY = cy + extendBlock;\n const radius = Math.sqrt(halfX * halfX + halfY * halfY);\n const size = radius * 2;\n\n const wave = document.createElement('span');\n wave.classList.add('md-ripple__wave');\n wave.style.width = wave.style.height = `${size}px`;\n wave.style.left = `${cx - radius}px`;\n wave.style.top = `${cy - radius}px`;\n container.appendChild(wave);\n this.activeWave = wave;\n this.activeOpacity = this.resolveOpacity();\n this.beginSettle();\n\n this.growAnimation = wave.animate(\n [\n { transform: 'scale(0)', opacity: this.activeOpacity },\n { transform: 'scale(1)', opacity: this.activeOpacity },\n ],\n {\n duration: this.resolveGrowDuration(),\n easing: this.resolveGrowEasing(),\n fill: 'forwards',\n },\n );\n\n this.growAnimation.addEventListener('finish', () => this.endWave(), { once: true });\n }\n\n render() {\n return (\n <Host aria-hidden=\"true\">\n <div class=\"md-ripple\"></div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|