@hypoth-ui/wc 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +60 -0
- package/dist/button-MKQKTC5Q.js +10 -0
- package/dist/button-MKQKTC5Q.js.map +1 -0
- package/dist/chunk-4HLM6DBG.js +910 -0
- package/dist/chunk-4HLM6DBG.js.map +1 -0
- package/dist/chunk-55ID7LJL.js +3602 -0
- package/dist/chunk-55ID7LJL.js.map +1 -0
- package/dist/chunk-66HFYJD7.js +86 -0
- package/dist/chunk-66HFYJD7.js.map +1 -0
- package/dist/chunk-CZOXIJVS.js +70 -0
- package/dist/chunk-CZOXIJVS.js.map +1 -0
- package/dist/chunk-DHUM4Q5Y.js +495 -0
- package/dist/chunk-DHUM4Q5Y.js.map +1 -0
- package/dist/chunk-DNNI5BDE.js +1842 -0
- package/dist/chunk-DNNI5BDE.js.map +1 -0
- package/dist/chunk-GXKZ6E6K.js +99 -0
- package/dist/chunk-GXKZ6E6K.js.map +1 -0
- package/dist/chunk-H4GJJZ3N.js +51 -0
- package/dist/chunk-H4GJJZ3N.js.map +1 -0
- package/dist/chunk-JMPTFALJ.js +175 -0
- package/dist/chunk-JMPTFALJ.js.map +1 -0
- package/dist/chunk-MYQWCLUJ.js +45 -0
- package/dist/chunk-MYQWCLUJ.js.map +1 -0
- package/dist/chunk-QZSPWT7L.js +183 -0
- package/dist/chunk-QZSPWT7L.js.map +1 -0
- package/dist/chunk-TSKBQCTR.js +5137 -0
- package/dist/chunk-TSKBQCTR.js.map +1 -0
- package/dist/chunk-TXIIUVL3.js +130 -0
- package/dist/chunk-TXIIUVL3.js.map +1 -0
- package/dist/chunk-UM7WRO7W.js +237 -0
- package/dist/chunk-UM7WRO7W.js.map +1 -0
- package/dist/chunk-VPXL4RB3.js +202 -0
- package/dist/chunk-VPXL4RB3.js.map +1 -0
- package/dist/chunk-VX5CKSMN.js +39 -0
- package/dist/chunk-VX5CKSMN.js.map +1 -0
- package/dist/chunk-WQ5BEP3E.js +2845 -0
- package/dist/chunk-WQ5BEP3E.js.map +1 -0
- package/dist/chunk-YDQ434UH.js +60 -0
- package/dist/chunk-YDQ434UH.js.map +1 -0
- package/dist/chunk-ZWV4VI6D.js +153 -0
- package/dist/chunk-ZWV4VI6D.js.map +1 -0
- package/dist/core.d.ts +127 -0
- package/dist/core.js +38 -0
- package/dist/core.js.map +1 -0
- package/dist/data-display.d.ts +872 -0
- package/dist/data-display.js +57 -0
- package/dist/data-display.js.map +1 -0
- package/dist/ds-element-Db0LMfxI.d.ts +43 -0
- package/dist/feedback.d.ts +292 -0
- package/dist/feedback.js +31 -0
- package/dist/feedback.js.map +1 -0
- package/dist/form-controls.d.ts +1713 -0
- package/dist/form-controls.js +63 -0
- package/dist/form-controls.js.map +1 -0
- package/dist/icon-7IZTJ5WT.js +8 -0
- package/dist/icon-7IZTJ5WT.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +423 -0
- package/dist/index.js.map +1 -0
- package/dist/input-LB6UR37A.js +10 -0
- package/dist/input-LB6UR37A.js.map +1 -0
- package/dist/layout.d.ts +504 -0
- package/dist/layout.js +34 -0
- package/dist/layout.js.map +1 -0
- package/dist/link-NHDJ6SFY.js +9 -0
- package/dist/link-NHDJ6SFY.js.map +1 -0
- package/dist/navigation.d.ts +255 -0
- package/dist/navigation.js +111 -0
- package/dist/navigation.js.map +1 -0
- package/dist/overlays.d.ts +1291 -0
- package/dist/overlays.js +106 -0
- package/dist/overlays.js.map +1 -0
- package/dist/primitives.d.ts +230 -0
- package/dist/primitives.js +26 -0
- package/dist/primitives.js.map +1 -0
- package/dist/registry-Bns0t11H.d.ts +233 -0
- package/dist/skeleton-MUdd2029.d.ts +109 -0
- package/dist/spinner-BWaNlc-Y.d.ts +45 -0
- package/dist/spinner-UIYDUVBZ.js +8 -0
- package/dist/spinner-UIYDUVBZ.js.map +1 -0
- package/dist/stepper-CCRwcQOe.d.ts +851 -0
- package/dist/text-MT3S3EMU.js +8 -0
- package/dist/text-MT3S3EMU.js.map +1 -0
- package/dist/visually-hidden-MW2XY4CS.js +8 -0
- package/dist/visually-hidden-MW2XY4CS.js.map +1 -0
- package/package.json +92 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/table/table.ts","../src/components/table/table-header.ts","../src/components/table/table-body.ts","../src/components/table/table-row.ts","../src/components/table/table-head.ts","../src/components/table/table-cell.ts","../src/components/data-table/data-table.ts","../src/components/avatar/avatar.ts","../src/components/avatar/avatar-group.ts","../src/components/badge/badge.ts","../src/components/tag/tag.ts","../src/components/calendar/calendar.ts","../src/components/tree/tree.ts","../src/components/tree/tree-item.ts","../src/components/tree/tree-utils.ts","../src/components/list/list.ts","../src/components/list/list-item.ts","../src/components/card/card.ts","../src/components/card/card-header.ts","../src/components/card/card-content.ts","../src/components/card/card-footer.ts","../src/components/separator/separator.ts","../src/components/aspect-ratio/aspect-ratio.ts"],"sourcesContent":["import { type TemplateResult, html, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport type TableSize = \"compact\" | \"default\" | \"spacious\";\n\n/**\n * Table root component.\n *\n * @element ds-table\n *\n * @slot - Table content (thead, tbody, tfoot)\n *\n * @cssprop --ds-table-border - Border style\n * @cssprop --ds-table-radius - Border radius\n * @cssprop --ds-table-bg - Background color\n */\nexport class DsTable extends DSElement {\n static override styles = [];\n\n /**\n * Size variant.\n */\n @property({ type: String, reflect: true })\n size: TableSize = \"default\";\n\n /**\n * Whether to show striped rows.\n */\n @property({ type: Boolean, reflect: true })\n striped = false;\n\n /**\n * Whether to remove borders.\n */\n @property({ type: Boolean, reflect: true })\n borderless = false;\n\n /**\n * Whether to use fixed layout.\n */\n @property({ type: Boolean, reflect: true })\n fixed = false;\n\n /**\n * Whether header is sticky.\n */\n @property({ type: Boolean, attribute: \"sticky-header\", reflect: true })\n stickyHeader = false;\n\n /**\n * Accessible caption for screen readers.\n */\n @property({ type: String })\n caption = \"\";\n\n override render(): TemplateResult {\n const classes = {\n \"ds-table\": true,\n };\n\n return html`\n <table\n class=${classMap(classes)}\n role=\"grid\"\n data-size=${this.size !== \"default\" ? this.size : nothing}\n ?data-striped=${this.striped}\n ?data-borderless=${this.borderless}\n ?data-fixed=${this.fixed}\n ?data-sticky-header=${this.stickyHeader}\n >\n ${\n this.caption\n ? html`<caption class=\"ds-table__caption\">${this.caption}</caption>`\n : nothing\n }\n <slot></slot>\n </table>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-table\", DsTable);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-table\": DsTable;\n }\n}\n","import { type TemplateResult, html } from \"lit\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\n\n/**\n * Table header component (thead).\n *\n * @element ds-table-header\n *\n * @slot - TableRow elements for header\n */\nexport class DsTableHeader extends DSElement {\n static override styles = [];\n\n override render(): TemplateResult {\n return html`\n <thead class=\"ds-table__header\" role=\"rowgroup\">\n <slot></slot>\n </thead>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-table-header\", DsTableHeader);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-table-header\": DsTableHeader;\n }\n}\n","import { type TemplateResult, html } from \"lit\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\n\n/**\n * Table body component (tbody).\n *\n * @element ds-table-body\n *\n * @slot - TableRow elements for body\n */\nexport class DsTableBody extends DSElement {\n static override styles = [];\n\n override render(): TemplateResult {\n return html`\n <tbody class=\"ds-table__body\" role=\"rowgroup\">\n <slot></slot>\n </tbody>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-table-body\", DsTableBody);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-table-body\": DsTableBody;\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\n\n/**\n * Table row component (tr).\n *\n * @element ds-table-row\n *\n * @slot - TableHead or TableCell elements\n */\nexport class DsTableRow extends DSElement {\n static override styles = [];\n\n /**\n * Row ID for selection tracking.\n */\n @property({ type: String, attribute: \"row-id\" })\n rowId = \"\";\n\n /**\n * Whether this row is selected.\n */\n @property({ type: Boolean, reflect: true })\n selected = false;\n\n override render(): TemplateResult {\n return html`\n <tr\n class=\"ds-table__row\"\n role=\"row\"\n ?data-selected=${this.selected}\n aria-selected=${this.selected ? \"true\" : nothing}\n >\n <slot></slot>\n </tr>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-table-row\", DsTableRow);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-table-row\": DsTableRow;\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { emitEvent } from \"../../events/emit.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport type TableAlign = \"left\" | \"center\" | \"right\";\nexport type SortDirection = \"asc\" | \"desc\" | \"none\";\n\n// Sort icon SVG\nconst sortIcon = html`\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"M12 5v14M5 12l7-7 7 7\" />\n </svg>\n`;\n\n/**\n * Table header cell component (th).\n *\n * @element ds-table-head\n *\n * @slot - Header content\n *\n * @fires ds-sort - When sortable header is clicked\n */\nexport class DsTableHead extends DSElement {\n static override styles = [];\n\n /**\n * Column key for sorting.\n */\n @property({ type: String })\n column = \"\";\n\n /**\n * Text alignment.\n */\n @property({ type: String, reflect: true })\n align: TableAlign = \"left\";\n\n /**\n * Whether this column is sortable.\n */\n @property({ type: Boolean, reflect: true })\n sortable = false;\n\n /**\n * Current sort direction.\n */\n @property({ type: String, attribute: \"sort-direction\", reflect: true })\n sortDirection: SortDirection = \"none\";\n\n /**\n * Column width (CSS value).\n */\n @property({ type: String })\n width = \"\";\n\n private handleClick(): void {\n if (!this.sortable) return;\n\n emitEvent(this, \"sort\", {\n detail: {\n column: this.column,\n direction: this.getNextDirection(),\n },\n });\n }\n\n private handleKeyDown(event: KeyboardEvent): void {\n if (!this.sortable) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n this.handleClick();\n }\n }\n\n private getNextDirection(): SortDirection {\n if (this.sortDirection === \"none\") return \"asc\";\n if (this.sortDirection === \"asc\") return \"desc\";\n return \"none\";\n }\n\n /**\n * Get the aria-sort attribute value.\n * Per APG, sortable columns should always have aria-sort:\n * - \"ascending\" for A-Z or low-high sort\n * - \"descending\" for Z-A or high-low sort\n * - \"none\" when sortable but not currently sorted\n */\n private getAriaSort(): \"ascending\" | \"descending\" | \"none\" {\n if (this.sortDirection === \"asc\") return \"ascending\";\n if (this.sortDirection === \"desc\") return \"descending\";\n return \"none\";\n }\n\n override render(): TemplateResult {\n const style = this.width ? `width: ${this.width}` : \"\";\n\n return html`\n <th\n class=\"ds-table__head\"\n role=\"columnheader\"\n scope=\"col\"\n data-align=${this.align !== \"left\" ? this.align : nothing}\n ?data-sortable=${this.sortable}\n data-sort-direction=${this.sortable ? this.sortDirection : nothing}\n aria-sort=${this.sortable ? this.getAriaSort() : nothing}\n tabindex=${this.sortable ? 0 : nothing}\n style=${style || nothing}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <slot></slot>\n ${this.sortable ? html`<span class=\"ds-table__sort-icon\">${sortIcon}</span>` : nothing}\n </th>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-table-head\", DsTableHead);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-table-head\": DsTableHead;\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\nimport type { TableAlign } from \"./table-head.js\";\n\n/**\n * Table cell component (td).\n *\n * @element ds-table-cell\n *\n * @slot - Cell content\n */\nexport class DsTableCell extends DSElement {\n static override styles = [];\n\n /**\n * Text alignment.\n */\n @property({ type: String, reflect: true })\n align: TableAlign = \"left\";\n\n /**\n * Column span.\n */\n @property({ type: Number })\n colspan = 1;\n\n /**\n * Row span.\n */\n @property({ type: Number })\n rowspan = 1;\n\n override render(): TemplateResult {\n return html`\n <td\n class=\"ds-table__cell\"\n role=\"gridcell\"\n data-align=${this.align !== \"left\" ? this.align : nothing}\n colspan=${this.colspan > 1 ? this.colspan : nothing}\n rowspan=${this.rowspan > 1 ? this.rowspan : nothing}\n >\n <slot></slot>\n </td>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-table-cell\", DsTableCell);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-table-cell\": DsTableCell;\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { emitEvent } from \"../../events/emit.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport type DataTableSortDirection = \"asc\" | \"desc\" | \"none\";\n\nexport interface DataTableColumn {\n id: string;\n header: string;\n accessor?: string;\n sortable?: boolean;\n resizable?: boolean;\n width?: string;\n minWidth?: string;\n maxWidth?: string;\n align?: \"left\" | \"center\" | \"right\";\n}\n\nexport interface DataTableSort {\n column: string;\n direction: DataTableSortDirection;\n}\n\nexport interface DataTablePagination {\n page: number;\n pageSize: number;\n total: number;\n}\n\n// Navigation icons\nconst chevronIcon = html`\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n`;\n\n/**\n * DataTable component for large dataset display with virtualization,\n * filtering, pagination, and column features.\n *\n * @element ds-data-table\n *\n * @slot - Table content (use Table sub-components)\n *\n * @fires ds-sort - When sort changes\n * @fires ds-page-change - When page changes\n * @fires ds-page-size-change - When page size changes\n * @fires ds-selection-change - When row selection changes\n *\n * @cssprop --ds-data-table-border - Border style\n */\nexport class DsDataTable extends DSElement {\n static override styles = [];\n\n /**\n * Enable virtualization for large datasets.\n */\n @property({ type: Boolean, reflect: true })\n virtualized = false;\n\n /**\n * Row height for virtualization (in pixels).\n */\n @property({ type: Number, attribute: \"row-height\" })\n rowHeight = 48;\n\n /**\n * Number of overscan rows for virtualization.\n */\n @property({ type: Number })\n overscan = 5;\n\n /**\n * Total number of rows (for server-side pagination).\n */\n @property({ type: Number, attribute: \"total-rows\" })\n totalRows = 0;\n\n /**\n * Current page (1-indexed).\n */\n @property({ type: Number })\n page = 1;\n\n /**\n * Page size.\n */\n @property({ type: Number, attribute: \"page-size\" })\n pageSize = 10;\n\n /**\n * Available page sizes.\n */\n @property({ type: String, attribute: \"page-sizes\" })\n pageSizes = \"10,25,50,100\";\n\n /**\n * Enable row selection.\n */\n @property({ type: Boolean, reflect: true })\n selectable = false;\n\n /**\n * Selection mode.\n */\n @property({ type: String, attribute: \"selection-mode\" })\n selectionMode: \"single\" | \"multiple\" = \"multiple\";\n\n /**\n * Show loading state.\n */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n /**\n * Sort column ID.\n */\n @property({ type: String, attribute: \"sort-column\" })\n sortColumn = \"\";\n\n /**\n * Sort direction.\n */\n @property({ type: String, attribute: \"sort-direction\" })\n sortDirection: DataTableSortDirection = \"none\";\n\n /**\n * Filter/search query.\n */\n @property({ type: String })\n filter = \"\";\n\n /**\n * Empty state message.\n */\n @property({ type: String, attribute: \"empty-message\" })\n emptyMessage = \"No data available\";\n\n @state()\n private selectedRows: Set<string> = new Set();\n\n @state()\n private sortAnnouncement = \"\";\n\n private get pageSizeOptions(): number[] {\n return this.pageSizes.split(\",\").map((s) => Number(s.trim()));\n }\n\n private get totalPages(): number {\n return Math.ceil(this.totalRows / this.pageSize);\n }\n\n private get startRow(): number {\n return (this.page - 1) * this.pageSize + 1;\n }\n\n private get endRow(): number {\n return Math.min(this.page * this.pageSize, this.totalRows);\n }\n\n handleSort(column: string): void {\n let newDirection: DataTableSortDirection = \"asc\";\n\n if (this.sortColumn === column) {\n if (this.sortDirection === \"asc\") {\n newDirection = \"desc\";\n } else if (this.sortDirection === \"desc\") {\n newDirection = \"none\";\n }\n }\n\n this.sortColumn = newDirection === \"none\" ? \"\" : column;\n this.sortDirection = newDirection;\n\n // Announce sort change to screen readers via live region\n this.announceSortChange(column, newDirection);\n\n emitEvent(this, \"sort\", {\n detail: {\n column: this.sortColumn,\n direction: this.sortDirection,\n },\n });\n }\n\n /**\n * Announce sort state changes to screen readers.\n * Uses a live region to provide immediate feedback.\n */\n private announceSortChange(column: string, direction: DataTableSortDirection): void {\n if (direction === \"asc\") {\n this.sortAnnouncement = `Sorted by ${column}, ascending`;\n } else if (direction === \"desc\") {\n this.sortAnnouncement = `Sorted by ${column}, descending`;\n } else {\n this.sortAnnouncement = \"Sort cleared\";\n }\n\n // Clear announcement after a brief delay to allow re-announcement on next sort\n setTimeout(() => {\n this.sortAnnouncement = \"\";\n }, 1000);\n }\n\n handlePageChange(newPage: number): void {\n if (newPage < 1 || newPage > this.totalPages) return;\n\n this.page = newPage;\n emitEvent(this, \"page-change\", { detail: { page: newPage } });\n }\n\n handlePageSizeChange(event: Event): void {\n const select = event.target as HTMLSelectElement;\n const newSize = Number(select.value);\n this.pageSize = newSize;\n this.page = 1; // Reset to first page\n emitEvent(this, \"page-size-change\", { detail: { pageSize: newSize } });\n }\n\n toggleRowSelection(rowId: string): void {\n if (!this.selectable) return;\n\n if (this.selectionMode === \"single\") {\n this.selectedRows.clear();\n this.selectedRows.add(rowId);\n } else {\n if (this.selectedRows.has(rowId)) {\n this.selectedRows.delete(rowId);\n } else {\n this.selectedRows.add(rowId);\n }\n }\n\n emitEvent(this, \"selection-change\", {\n detail: { selectedRows: Array.from(this.selectedRows) },\n });\n this.requestUpdate();\n }\n\n clearSelection(): void {\n this.selectedRows.clear();\n emitEvent(this, \"selection-change\", { detail: { selectedRows: [] } });\n this.requestUpdate();\n }\n\n isRowSelected(rowId: string): boolean {\n return this.selectedRows.has(rowId);\n }\n\n private renderPagination(): TemplateResult {\n const pages: number[] = [];\n const maxButtons = 5;\n let start = Math.max(1, this.page - Math.floor(maxButtons / 2));\n const end = Math.min(this.totalPages, start + maxButtons - 1);\n\n if (end - start + 1 < maxButtons) {\n start = Math.max(1, end - maxButtons + 1);\n }\n\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n\n return html`\n <div class=\"ds-data-table__pagination\">\n <button\n type=\"button\"\n class=\"ds-data-table__page-button\"\n ?disabled=${this.page === 1}\n @click=${() => this.handlePageChange(this.page - 1)}\n aria-label=\"Previous page\"\n >\n ${chevronIcon}\n </button>\n\n ${pages.map(\n (p) => html`\n <button\n type=\"button\"\n class=\"ds-data-table__page-button\"\n ?data-active=${p === this.page}\n @click=${() => this.handlePageChange(p)}\n aria-label=\"Page ${p}\"\n aria-current=${p === this.page ? \"page\" : nothing}\n >\n ${p}\n </button>\n `\n )}\n\n <button\n type=\"button\"\n class=\"ds-data-table__page-button\"\n ?disabled=${this.page === this.totalPages}\n @click=${() => this.handlePageChange(this.page + 1)}\n aria-label=\"Next page\"\n style=\"transform: rotate(180deg)\"\n >\n ${chevronIcon}\n </button>\n </div>\n `;\n }\n\n override render(): TemplateResult {\n const classes = {\n \"ds-data-table\": true,\n };\n\n return html`\n <div\n class=${classMap(classes)}\n role=\"region\"\n aria-label=\"Data table\"\n aria-busy=${this.loading ? \"true\" : nothing}\n ?data-loading=${this.loading}\n >\n <!-- Live region for sort announcements (APG compliance) -->\n <div\n class=\"ds-data-table__live-region\"\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n style=\"position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;\"\n >\n ${this.sortAnnouncement}\n </div>\n ${\n this.selectedRows.size > 0\n ? html`\n <div class=\"ds-data-table__selection-info\">\n <span class=\"ds-data-table__selection-count\">\n ${this.selectedRows.size} selected\n </span>\n <button\n type=\"button\"\n class=\"ds-data-table__clear-selection\"\n @click=${this.clearSelection}\n >\n Clear\n </button>\n </div>\n `\n : nothing\n }\n\n <div\n class=${this.virtualized ? \"ds-data-table__virtualized\" : \"ds-data-table__container\"}\n >\n <slot></slot>\n\n ${\n this.loading\n ? html`\n <div class=\"ds-data-table__loading\">\n <ds-spinner size=\"lg\"></ds-spinner>\n </div>\n `\n : nothing\n }\n </div>\n\n ${\n this.totalRows > 0\n ? html`\n <div class=\"ds-data-table__footer\">\n <div class=\"ds-data-table__info\">\n Showing ${this.startRow}-${this.endRow} of ${this.totalRows}\n </div>\n\n <div class=\"ds-data-table__per-page\">\n <span>Rows per page:</span>\n <select @change=${this.handlePageSizeChange}>\n ${this.pageSizeOptions.map(\n (size) => html`\n <option value=${size} ?selected=${size === this.pageSize}>\n ${size}\n </option>\n `\n )}\n </select>\n </div>\n\n ${this.renderPagination()}\n </div>\n `\n : nothing\n }\n </div>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-data-table\", DsDataTable);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-data-table\": DsDataTable;\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport type AvatarSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\";\nexport type AvatarShape = \"circle\" | \"square\";\nexport type AvatarStatus = \"online\" | \"offline\" | \"away\" | \"busy\";\n\n// Default user icon SVG\nconst defaultUserIcon = html`\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z\" />\n </svg>\n`;\n\n/**\n * Avatar component for user representation.\n *\n * @element ds-avatar\n *\n * @csspart image - The avatar image element\n * @csspart initials - The initials fallback element\n * @csspart icon - The icon fallback element\n * @csspart status - The status indicator element\n *\n * @cssprop --ds-avatar-size - Avatar dimensions\n * @cssprop --ds-avatar-radius - Border radius\n * @cssprop --ds-avatar-bg - Background color for fallback\n * @cssprop --ds-avatar-color - Text color for initials/icon\n */\nexport class DsAvatar extends DSElement {\n static override styles = [];\n\n /**\n * Image source URL.\n */\n @property({ type: String })\n src = \"\";\n\n /**\n * Alt text for image.\n */\n @property({ type: String })\n alt = \"\";\n\n /**\n * User's name (used for initials fallback).\n */\n @property({ type: String })\n name = \"\";\n\n /**\n * Size variant.\n */\n @property({ type: String, reflect: true })\n size: AvatarSize = \"md\";\n\n /**\n * Shape variant.\n */\n @property({ type: String, reflect: true })\n shape: AvatarShape = \"circle\";\n\n /**\n * Status indicator.\n */\n @property({ type: String })\n status?: AvatarStatus;\n\n /**\n * Whether to show status indicator.\n */\n @property({ type: Boolean, attribute: \"show-status\" })\n showStatus = false;\n\n @state()\n private imageError = false;\n\n private get initials(): string {\n if (!this.name) return \"\";\n\n const names = this.name.trim().split(/\\s+/);\n if (names.length === 0) return \"\";\n if (names.length === 1) {\n return (names[0] ?? \"\").charAt(0).toUpperCase();\n }\n const first = names[0] ?? \"\";\n const last = names[names.length - 1] ?? \"\";\n return (first.charAt(0) + last.charAt(0)).toUpperCase();\n }\n\n private get showImage(): boolean {\n return Boolean(this.src && !this.imageError);\n }\n\n private get showInitials(): boolean {\n return !this.showImage && Boolean(this.initials);\n }\n\n private get showIcon(): boolean {\n return !this.showImage && !this.showInitials;\n }\n\n private handleImageError(): void {\n this.imageError = true;\n }\n\n private handleImageLoad(): void {\n this.imageError = false;\n }\n\n override render(): TemplateResult {\n const classes = {\n \"ds-avatar\": true,\n };\n\n return html`\n <span\n class=${classMap(classes)}\n role=\"img\"\n aria-label=${this.alt || this.name || \"Avatar\"}\n data-size=${this.size}\n data-shape=${this.shape !== \"circle\" ? this.shape : nothing}\n >\n ${\n this.showImage\n ? html`\n <img\n part=\"image\"\n class=\"ds-avatar__image\"\n src=${this.src}\n alt=\"\"\n @error=${this.handleImageError}\n @load=${this.handleImageLoad}\n />\n `\n : nothing\n }\n ${\n this.showInitials\n ? html`\n <span part=\"initials\" class=\"ds-avatar__initials\">\n ${this.initials}\n </span>\n `\n : nothing\n }\n ${\n this.showIcon\n ? html`\n <span part=\"icon\" class=\"ds-avatar__icon\">\n ${defaultUserIcon}\n </span>\n `\n : nothing\n }\n ${\n this.showStatus && this.status\n ? html`\n <span\n part=\"status\"\n class=\"ds-avatar__status\"\n data-status=${this.status}\n aria-label=${`Status: ${this.status}`}\n ></span>\n `\n : nothing\n }\n </span>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-avatar\", DsAvatar);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-avatar\": DsAvatar;\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\nimport type { AvatarSize } from \"./avatar.js\";\n\n/**\n * Avatar group component for displaying multiple avatars with overflow.\n *\n * @element ds-avatar-group\n *\n * @slot - Avatar elements to display\n *\n * @csspart overflow - The overflow indicator element\n *\n * @cssprop --ds-avatar-size - Avatar dimensions (inherited by children)\n */\nexport class DsAvatarGroup extends DSElement {\n static override styles = [];\n\n /**\n * Maximum number of avatars to display before showing overflow.\n */\n @property({ type: Number })\n max = 5;\n\n /**\n * Size variant (inherited by child avatars).\n */\n @property({ type: String, reflect: true })\n size: AvatarSize = \"md\";\n\n @state()\n private overflowCount = 0;\n\n @state()\n private visibleAvatars: Element[] = [];\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.updateAvatarVisibility();\n\n // Use MutationObserver to track slot changes\n const observer = new MutationObserver(() => this.updateAvatarVisibility());\n observer.observe(this, { childList: true });\n }\n\n private updateAvatarVisibility(): void {\n const avatars = Array.from(this.querySelectorAll(\"ds-avatar\"));\n const total = avatars.length;\n\n if (total <= this.max) {\n this.visibleAvatars = avatars;\n this.overflowCount = 0;\n } else {\n this.visibleAvatars = avatars.slice(0, this.max);\n this.overflowCount = total - this.max;\n }\n\n // Hide overflow avatars\n avatars.forEach((avatar, index) => {\n if (index >= this.max) {\n (avatar as HTMLElement).style.display = \"none\";\n } else {\n (avatar as HTMLElement).style.display = \"\";\n }\n });\n\n this.requestUpdate();\n }\n\n override render(): TemplateResult {\n const classes = {\n \"ds-avatar-group\": true,\n };\n\n return html`\n <div\n class=${classMap(classes)}\n role=\"group\"\n aria-label=\"Avatar group\"\n data-size=${this.size}\n >\n ${\n this.overflowCount > 0\n ? html`\n <span\n part=\"overflow\"\n class=\"ds-avatar-group__overflow\"\n aria-label=\"${this.overflowCount} more users\"\n >\n +${this.overflowCount}\n </span>\n `\n : nothing\n }\n <slot @slotchange=${this.updateAvatarVisibility}></slot>\n </div>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-avatar-group\", DsAvatarGroup);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-avatar-group\": DsAvatarGroup;\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport type BadgeVariant =\n | \"neutral\"\n | \"primary\"\n | \"secondary\"\n | \"success\"\n | \"warning\"\n | \"error\"\n | \"info\";\nexport type BadgeSize = \"sm\" | \"md\" | \"lg\";\nexport type BadgePosition = \"top-right\" | \"top-left\" | \"bottom-right\" | \"bottom-left\";\n\n/**\n * Badge component for counts, notifications, and status indicators.\n *\n * @element ds-badge\n *\n * @cssprop --ds-badge-bg - Background color\n * @cssprop --ds-badge-color - Text color\n */\nexport class DsBadge extends DSElement {\n static override styles = [];\n\n /**\n * Badge content/count.\n */\n @property({ type: String })\n content = \"\";\n\n /**\n * Maximum count to show. Displays \"{max}+\" if exceeded.\n */\n @property({ type: Number })\n max?: number;\n\n /**\n * Color variant.\n */\n @property({ type: String, reflect: true })\n variant: BadgeVariant = \"primary\";\n\n /**\n * Size variant.\n */\n @property({ type: String, reflect: true })\n size: BadgeSize = \"md\";\n\n /**\n * Use outline style.\n */\n @property({ type: Boolean, reflect: true })\n outline = false;\n\n /**\n * Show as dot (no content).\n */\n @property({ type: Boolean, reflect: true })\n dot = false;\n\n /**\n * Position when used in wrapper.\n */\n @property({ type: String, reflect: true })\n position: BadgePosition = \"top-right\";\n\n /**\n * Show pulse animation.\n */\n @property({ type: Boolean, reflect: true })\n pulse = false;\n\n private get displayContent(): string {\n if (this.dot) return \"\";\n if (this.max !== undefined && !Number.isNaN(Number(this.content))) {\n const count = Number(this.content);\n if (count > this.max) {\n return `${this.max}+`;\n }\n }\n return this.content;\n }\n\n override render(): TemplateResult {\n const classes = {\n \"ds-badge\": true,\n };\n\n return html`\n <span\n class=${classMap(classes)}\n role=\"status\"\n data-variant=${this.variant}\n data-size=${this.size !== \"md\" ? this.size : nothing}\n ?data-outline=${this.outline}\n ?data-dot=${this.dot}\n data-position=${this.position}\n ?data-pulse=${this.pulse}\n aria-label=${this.dot ? \"Notification indicator\" : `${this.displayContent} notifications`}\n >\n ${this.dot ? nothing : this.displayContent}\n </span>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-badge\", DsBadge);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-badge\": DsBadge;\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { emitEvent } from \"../../events/emit.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport type TagVariant =\n | \"neutral\"\n | \"primary\"\n | \"secondary\"\n | \"success\"\n | \"warning\"\n | \"error\"\n | \"info\";\nexport type TagSize = \"sm\" | \"md\" | \"lg\";\n\n// Close icon SVG\nconst closeIcon = html`\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n`;\n\n/**\n * Tag component for categorization with optional remove action.\n *\n * @element ds-tag\n *\n * @slot - Tag content\n * @slot icon - Optional leading icon\n *\n * @fires ds-remove - When the remove button is clicked\n * @fires ds-click - When the tag is clicked (if clickable)\n *\n * @cssprop --ds-tag-bg - Background color\n * @cssprop --ds-tag-color - Text color\n */\nexport class DsTag extends DSElement {\n static override styles = [];\n\n /**\n * Color variant.\n */\n @property({ type: String, reflect: true })\n variant: TagVariant = \"neutral\";\n\n /**\n * Size variant.\n */\n @property({ type: String, reflect: true })\n size: TagSize = \"md\";\n\n /**\n * Use solid (filled) style instead of subtle.\n */\n @property({ type: Boolean, reflect: true })\n solid = false;\n\n /**\n * Show remove button.\n */\n @property({ type: Boolean, reflect: true })\n removable = false;\n\n /**\n * Make tag clickable/interactive.\n */\n @property({ type: Boolean, reflect: true })\n clickable = false;\n\n /**\n * Disable the tag.\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Value for identification in events.\n */\n @property({ type: String })\n value = \"\";\n\n private handleRemove(event: Event): void {\n event.stopPropagation();\n if (this.disabled) return;\n\n emitEvent(this, \"remove\", {\n detail: { value: this.value },\n });\n }\n\n private handleClick(): void {\n if (!this.clickable || this.disabled) return;\n\n emitEvent(this, \"click\", {\n detail: { value: this.value },\n });\n }\n\n private handleKeyDown(event: KeyboardEvent): void {\n if (this.disabled) return;\n\n if (event.key === \"Enter\" || event.key === \" \") {\n if (this.clickable) {\n event.preventDefault();\n this.handleClick();\n }\n } else if (event.key === \"Backspace\" || event.key === \"Delete\") {\n if (this.removable) {\n event.preventDefault();\n emitEvent(this, \"remove\", { detail: { value: this.value } });\n }\n }\n }\n\n override render(): TemplateResult {\n const classes = {\n \"ds-tag\": true,\n };\n\n return html`\n <span\n class=${classMap(classes)}\n role=${this.clickable ? \"button\" : \"status\"}\n tabindex=${this.clickable && !this.disabled ? 0 : nothing}\n data-variant=${this.variant}\n data-size=${this.size !== \"md\" ? this.size : nothing}\n ?data-solid=${this.solid}\n ?data-clickable=${this.clickable}\n ?data-disabled=${this.disabled}\n aria-disabled=${this.disabled ? \"true\" : nothing}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <slot name=\"icon\"></slot>\n <slot></slot>\n ${\n this.removable\n ? html`\n <button\n type=\"button\"\n class=\"ds-tag__remove\"\n aria-label=\"Remove\"\n ?disabled=${this.disabled}\n @click=${this.handleRemove}\n >\n ${closeIcon}\n </button>\n `\n : nothing\n }\n </span>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-tag\", DsTag);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-tag\": DsTag;\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { emitEvent } from \"../../events/emit.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport type CalendarSize = \"default\" | \"compact\";\n\n// Navigation icons\nconst chevronLeftIcon = html`\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n`;\n\nconst chevronRightIcon = html`\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n`;\n\n/**\n * Calendar component for date selection.\n *\n * @element ds-calendar\n *\n * @fires ds-change - When a date is selected\n * @fires ds-month-change - When the displayed month changes\n *\n * @cssprop --ds-calendar-width - Calendar width\n * @cssprop --ds-calendar-cell-size - Day cell size\n */\nexport class DsCalendar extends DSElement {\n static override styles = [];\n\n /**\n * Selected date (ISO format: YYYY-MM-DD).\n */\n @property({ type: String })\n value = \"\";\n\n /**\n * Minimum selectable date (ISO format).\n */\n @property({ type: String })\n min = \"\";\n\n /**\n * Maximum selectable date (ISO format).\n */\n @property({ type: String })\n max = \"\";\n\n /**\n * Disabled dates (comma-separated ISO format).\n */\n @property({ type: String, attribute: \"disabled-dates\" })\n disabledDates = \"\";\n\n /**\n * Locale for month/day names.\n */\n @property({ type: String })\n locale = \"en-US\";\n\n /**\n * Size variant.\n */\n @property({ type: String, reflect: true })\n size: CalendarSize = \"default\";\n\n /**\n * First day of week (0 = Sunday, 1 = Monday).\n */\n @property({ type: Number, attribute: \"first-day-of-week\" })\n firstDayOfWeek = 0;\n\n @state()\n private viewDate: Date = new Date();\n\n private get selectedDate(): Date | null {\n return this.value ? new Date(this.value) : null;\n }\n\n private get minDate(): Date | null {\n return this.min ? new Date(this.min) : null;\n }\n\n private get maxDate(): Date | null {\n return this.max ? new Date(this.max) : null;\n }\n\n private get disabledDateSet(): Set<string> {\n if (!this.disabledDates) return new Set();\n return new Set(this.disabledDates.split(\",\").map((d) => d.trim()));\n }\n\n private get weekdayNames(): string[] {\n const formatter = new Intl.DateTimeFormat(this.locale, { weekday: \"short\" });\n const days: string[] = [];\n // Start from a known Sunday\n const baseDate = new Date(2024, 0, 7); // Jan 7, 2024 is a Sunday\n for (let i = 0; i < 7; i++) {\n const day = new Date(baseDate);\n day.setDate(baseDate.getDate() + ((i + this.firstDayOfWeek) % 7));\n days.push(formatter.format(day));\n }\n return days;\n }\n\n private get monthYearLabel(): string {\n const formatter = new Intl.DateTimeFormat(this.locale, {\n month: \"long\",\n year: \"numeric\",\n });\n return formatter.format(this.viewDate);\n }\n\n private get calendarDays(): Array<{ date: Date; isOutside: boolean }> {\n const days: Array<{ date: Date; isOutside: boolean }> = [];\n const year = this.viewDate.getFullYear();\n const month = this.viewDate.getMonth();\n\n // First day of the month\n const firstOfMonth = new Date(year, month, 1);\n // Day of week of first day (0-6)\n const startDayOfWeek = firstOfMonth.getDay();\n // How many days to show from previous month\n const daysFromPrevMonth = (startDayOfWeek - this.firstDayOfWeek + 7) % 7;\n\n // Add days from previous month\n for (let i = daysFromPrevMonth; i > 0; i--) {\n const date = new Date(year, month, 1 - i);\n days.push({ date, isOutside: true });\n }\n\n // Add days of current month\n const daysInMonth = new Date(year, month + 1, 0).getDate();\n for (let i = 1; i <= daysInMonth; i++) {\n days.push({ date: new Date(year, month, i), isOutside: false });\n }\n\n // Add days from next month to complete grid (6 rows × 7 days = 42)\n const remaining = 42 - days.length;\n for (let i = 1; i <= remaining; i++) {\n const date = new Date(year, month + 1, i);\n days.push({ date, isOutside: true });\n }\n\n return days;\n }\n\n private isToday(date: Date): boolean {\n const today = new Date();\n return (\n date.getDate() === today.getDate() &&\n date.getMonth() === today.getMonth() &&\n date.getFullYear() === today.getFullYear()\n );\n }\n\n private isSelected(date: Date): boolean {\n if (!this.selectedDate) return false;\n return (\n date.getDate() === this.selectedDate.getDate() &&\n date.getMonth() === this.selectedDate.getMonth() &&\n date.getFullYear() === this.selectedDate.getFullYear()\n );\n }\n\n private isDisabled(date: Date): boolean {\n const dateStr = date.toISOString().split(\"T\")[0] ?? \"\";\n\n // Check disabled dates\n if (dateStr && this.disabledDateSet.has(dateStr)) return true;\n\n // Check min/max bounds\n if (this.minDate && date < this.minDate) return true;\n if (this.maxDate && date > this.maxDate) return true;\n\n return false;\n }\n\n private formatDateISO(date: Date): string {\n return date.toISOString().split(\"T\")[0] ?? \"\";\n }\n\n private handlePrevMonth(): void {\n const newDate = new Date(this.viewDate);\n newDate.setMonth(newDate.getMonth() - 1);\n this.viewDate = newDate;\n\n emitEvent(this, \"month-change\", {\n detail: {\n month: newDate.getMonth() + 1,\n year: newDate.getFullYear(),\n },\n });\n }\n\n private handleNextMonth(): void {\n const newDate = new Date(this.viewDate);\n newDate.setMonth(newDate.getMonth() + 1);\n this.viewDate = newDate;\n\n emitEvent(this, \"month-change\", {\n detail: {\n month: newDate.getMonth() + 1,\n year: newDate.getFullYear(),\n },\n });\n }\n\n private handleDateSelect(date: Date): void {\n if (this.isDisabled(date)) return;\n\n this.value = this.formatDateISO(date);\n\n emitEvent(this, \"change\", {\n detail: {\n value: this.value,\n date: date.toISOString(),\n },\n });\n }\n\n private handleKeyDown(event: KeyboardEvent, date: Date): void {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n this.handleDateSelect(date);\n }\n }\n\n override render(): TemplateResult {\n const classes = {\n \"ds-calendar\": true,\n };\n\n return html`\n <div\n class=${classMap(classes)}\n role=\"application\"\n aria-label=\"Calendar\"\n data-size=${this.size !== \"default\" ? this.size : nothing}\n >\n <div class=\"ds-calendar__header\">\n <button\n type=\"button\"\n class=\"ds-calendar__nav-button\"\n aria-label=\"Previous month\"\n @click=${this.handlePrevMonth}\n >\n ${chevronLeftIcon}\n </button>\n <span class=\"ds-calendar__title\" aria-live=\"polite\">\n ${this.monthYearLabel}\n </span>\n <button\n type=\"button\"\n class=\"ds-calendar__nav-button\"\n aria-label=\"Next month\"\n @click=${this.handleNextMonth}\n >\n ${chevronRightIcon}\n </button>\n </div>\n\n <div class=\"ds-calendar__weekdays\" role=\"row\">\n ${this.weekdayNames.map(\n (day) => html`\n <div class=\"ds-calendar__weekday\" role=\"columnheader\">${day}</div>\n `\n )}\n </div>\n\n <div class=\"ds-calendar__grid\" role=\"grid\">\n ${this.calendarDays.map(({ date, isOutside }) => {\n const disabled = this.isDisabled(date);\n const selected = this.isSelected(date);\n const today = this.isToday(date);\n\n return html`\n <button\n type=\"button\"\n class=\"ds-calendar__day\"\n role=\"gridcell\"\n tabindex=${selected ? 0 : -1}\n aria-selected=${selected ? \"true\" : \"false\"}\n aria-disabled=${disabled ? \"true\" : nothing}\n ?data-outside=${isOutside}\n ?data-selected=${selected}\n ?data-today=${today}\n ?data-disabled=${disabled}\n @click=${() => this.handleDateSelect(date)}\n @keydown=${(e: KeyboardEvent) => this.handleKeyDown(e, date)}\n >\n ${date.getDate()}\n </button>\n `;\n })}\n </div>\n </div>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-calendar\", DsCalendar);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-calendar\": DsCalendar;\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { emitEvent } from \"../../events/emit.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport type TreeSelectionMode = \"single\" | \"multiple\" | \"none\";\nexport type TreeSize = \"default\" | \"compact\";\n\n/**\n * Tree root component for hierarchical data display.\n *\n * @element ds-tree\n *\n * @slot - TreeItem elements\n *\n * @fires ds-selection-change - When selection changes\n *\n * @cssprop --ds-tree-indent - Indentation for nested items\n */\nexport class DsTree extends DSElement {\n static override styles = [];\n\n /**\n * Selection mode.\n */\n @property({ type: String, attribute: \"selection-mode\", reflect: true })\n selectionMode: TreeSelectionMode = \"single\";\n\n /**\n * Size variant.\n */\n @property({ type: String, reflect: true })\n size: TreeSize = \"default\";\n\n /**\n * Show connecting lines.\n */\n @property({ type: Boolean, reflect: true })\n lines = false;\n\n /**\n * Accessible label.\n */\n @property({ type: String })\n label = \"Tree\";\n\n /**\n * Whether the tree is in a loading state.\n * When true, sets aria-busy and disables keyboard navigation.\n */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n /**\n * Text to display/announce during loading.\n */\n @property({ type: String, attribute: \"loading-text\" })\n loadingText = \"Loading...\";\n\n /**\n * Node IDs that are currently loading children.\n * Allows for node-level loading indicators.\n */\n @property({ attribute: false })\n loadingNodes: Set<string> | string[] = new Set();\n\n @state()\n private selectedItems: Set<string> = new Set();\n\n /**\n * Checks if a specific node is currently loading.\n */\n isNodeLoading(nodeId: string): boolean {\n if (this.loadingNodes instanceof Set) {\n return this.loadingNodes.has(nodeId);\n }\n return this.loadingNodes.includes(nodeId);\n }\n\n handleItemSelect(itemId: string): void {\n // Disable selection during loading\n if (this.loading) return;\n if (this.selectionMode === \"none\") return;\n\n if (this.selectionMode === \"single\") {\n this.selectedItems.clear();\n this.selectedItems.add(itemId);\n } else {\n if (this.selectedItems.has(itemId)) {\n this.selectedItems.delete(itemId);\n } else {\n this.selectedItems.add(itemId);\n }\n }\n\n emitEvent(this, \"selection-change\", {\n detail: { selectedItems: Array.from(this.selectedItems) },\n });\n\n this.requestUpdate();\n }\n\n isItemSelected(itemId: string): boolean {\n return this.selectedItems.has(itemId);\n }\n\n override render(): TemplateResult {\n const classes = {\n \"ds-tree\": true,\n };\n\n return html`\n <ul\n class=${classMap(classes)}\n role=\"tree\"\n aria-label=${this.label}\n aria-multiselectable=${this.selectionMode === \"multiple\" ? \"true\" : nothing}\n aria-busy=${this.loading ? \"true\" : nothing}\n data-size=${this.size !== \"default\" ? this.size : nothing}\n ?data-lines=${this.lines}\n ?data-loading=${this.loading}\n >\n <slot></slot>\n </ul>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-tree\", DsTree);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-tree\": DsTree;\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { emitEvent } from \"../../events/emit.js\";\nimport { define } from \"../../registry/define.js\";\nimport type { DsTree } from \"./tree.js\";\nimport { calculateTreeItemPosition } from \"./tree-utils.js\";\n\n// Chevron icon\nconst chevronIcon = html`\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n`;\n\n/**\n * Tree item component for hierarchical nodes.\n *\n * @element ds-tree-item\n *\n * @slot - Item content (label)\n * @slot icon - Optional leading icon\n * @slot children - Nested TreeItem elements\n *\n * @fires ds-expand - When expand state changes\n * @fires ds-select - When item is selected\n * @fires ds-activate - When item is activated (Enter/double-click)\n */\nexport class DsTreeItem extends DSElement {\n static override styles = [];\n\n /**\n * Unique item ID.\n */\n @property({ type: String, attribute: \"item-id\" })\n itemId = \"\";\n\n /**\n * Whether item is expanded.\n */\n @property({ type: Boolean, reflect: true })\n expanded = false;\n\n /**\n * Whether item is selected.\n */\n @property({ type: Boolean, reflect: true })\n selected = false;\n\n /**\n * Whether item is disabled.\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Whether this item is loading (e.g., fetching children).\n * Can be set directly or inherited from tree's loadingNodes.\n */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n @state()\n private hasChildren = false;\n\n @state()\n private _level = 1;\n\n @state()\n private _setSize = 1;\n\n @state()\n private _posInSet = 1;\n\n private get treeRoot(): DsTree | null {\n return this.closest(\"ds-tree\") as DsTree | null;\n }\n\n /**\n * Returns true if this item is loading (either directly or via tree's loadingNodes).\n */\n private get isLoading(): boolean {\n if (this.loading) return true;\n const tree = this.treeRoot;\n if (tree && this.itemId) {\n return tree.isNodeLoading(this.itemId);\n }\n return false;\n }\n\n /**\n * Returns true if the tree root is in a loading state.\n */\n private get isTreeLoading(): boolean {\n return this.treeRoot?.loading ?? false;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.updateHasChildren();\n // Calculate position after DOM is ready\n requestAnimationFrame(() => {\n this.updateAriaPosition();\n });\n }\n\n /**\n * Update ARIA position attributes for APG compliance.\n * Provides screen readers with context like \"Item 3 of 5, level 2\".\n */\n private updateAriaPosition(): void {\n const position = calculateTreeItemPosition(this as unknown as HTMLElement);\n this._level = position.level;\n this._setSize = position.setSize;\n this._posInSet = position.posInSet;\n }\n\n private updateHasChildren(): void {\n const childrenSlot = this.querySelector(\"[slot=children]\");\n this.hasChildren = childrenSlot !== null && childrenSlot.querySelector(\"ds-tree-item\") !== null;\n }\n\n private handleExpandClick(event: Event): void {\n event.stopPropagation();\n if (this.disabled || this.isTreeLoading || this.isLoading || !this.hasChildren) return;\n\n this.expanded = !this.expanded;\n emitEvent(this, \"expand\", {\n detail: {\n itemId: this.itemId,\n expanded: this.expanded,\n },\n });\n }\n\n private handleContentClick(): void {\n if (this.disabled || this.isTreeLoading) return;\n\n const tree = this.treeRoot;\n if (tree) {\n tree.handleItemSelect(this.itemId);\n this.selected = tree.isItemSelected(this.itemId);\n }\n\n emitEvent(this, \"select\", {\n detail: {\n itemId: this.itemId,\n selected: this.selected,\n },\n });\n }\n\n private handleKeyDown(event: KeyboardEvent): void {\n if (this.disabled || this.isTreeLoading) return;\n\n switch (event.key) {\n case \"ArrowRight\":\n if (this.hasChildren && !this.expanded) {\n event.preventDefault();\n this.expanded = true;\n emitEvent(this, \"expand\", {\n detail: {\n itemId: this.itemId,\n expanded: true,\n },\n });\n }\n break;\n\n case \"ArrowLeft\":\n if (this.hasChildren && this.expanded) {\n event.preventDefault();\n this.expanded = false;\n emitEvent(this, \"expand\", {\n detail: {\n itemId: this.itemId,\n expanded: false,\n },\n });\n }\n break;\n\n case \"Enter\":\n event.preventDefault();\n emitEvent(this, \"activate\", { detail: { itemId: this.itemId } });\n break;\n\n case \" \":\n event.preventDefault();\n this.handleContentClick();\n break;\n }\n }\n\n override render(): TemplateResult {\n const classes = {\n \"ds-tree-item\": true,\n };\n\n // Check for children via slot\n this.updateHasChildren();\n\n const itemLoading = this.isLoading;\n\n return html`\n <li\n class=${classMap(classes)}\n role=\"treeitem\"\n aria-expanded=${this.hasChildren ? (this.expanded ? \"true\" : \"false\") : nothing}\n aria-selected=${this.selected ? \"true\" : \"false\"}\n aria-busy=${itemLoading ? \"true\" : nothing}\n aria-level=${this._level}\n aria-setsize=${this._setSize}\n aria-posinset=${this._posInSet}\n ?data-expanded=${this.expanded}\n ?data-selected=${this.selected}\n ?data-disabled=${this.disabled}\n ?data-loading=${itemLoading}\n >\n <div\n class=\"ds-tree-item__content\"\n tabindex=${this.disabled ? -1 : 0}\n @click=${this.handleContentClick}\n @keydown=${this.handleKeyDown}\n >\n ${\n this.hasChildren\n ? html`\n <button\n type=\"button\"\n class=\"ds-tree-item__expand\"\n aria-label=${this.expanded ? \"Collapse\" : \"Expand\"}\n tabindex=\"-1\"\n @click=${this.handleExpandClick}\n >\n ${chevronIcon}\n </button>\n `\n : html`<span class=\"ds-tree-item__spacer\"></span>`\n }\n <slot name=\"icon\"></slot>\n <span class=\"ds-tree-item__label\">\n <slot></slot>\n </span>\n </div>\n ${\n this.hasChildren\n ? html`\n <ul\n class=\"ds-tree-item__children ds-tree\"\n role=\"group\"\n ?hidden=${!this.expanded}\n >\n <slot name=\"children\" @slotchange=${this.updateHasChildren}></slot>\n </ul>\n `\n : nothing\n }\n </li>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-tree-item\", DsTreeItem);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-tree-item\": DsTreeItem;\n }\n}\n","/**\n * Tree structure utilities for APG-compliant ARIA attributes.\n *\n * Calculates aria-level, aria-setsize, and aria-posinset for tree items\n * to provide proper screen reader context (e.g., \"Item 3 of 5, level 2\").\n */\n\nexport interface TreeItemPosition {\n /** Nesting depth (1-based, root items are level 1) */\n level: number;\n /** Number of siblings at this level */\n setSize: number;\n /** Position among siblings (1-based) */\n posInSet: number;\n}\n\n/**\n * Calculate position attributes for a tree item element.\n *\n * @param element - The ds-tree-item element\n * @returns Position info for aria-level, aria-setsize, aria-posinset\n *\n * @example\n * ```ts\n * const position = calculateTreeItemPosition(treeItemElement);\n * // { level: 2, setSize: 3, posInSet: 1 }\n * ```\n */\nexport function calculateTreeItemPosition(element: HTMLElement): TreeItemPosition {\n // Calculate level by counting ancestor tree items\n let level = 1;\n let parent: HTMLElement | null = element.parentElement;\n\n while (parent) {\n // Check if parent is a tree item (indicates nested level)\n if (parent.tagName?.toLowerCase() === \"ds-tree-item\") {\n level++;\n }\n // Stop at tree root\n if (parent.tagName?.toLowerCase() === \"ds-tree\") {\n break;\n }\n parent = parent.parentElement;\n }\n\n // Find siblings at the same level\n const siblings = getSiblingTreeItems(element);\n const setSize = siblings.length;\n const posInSet = siblings.indexOf(element) + 1;\n\n return { level, setSize, posInSet };\n}\n\n/**\n * Get sibling tree items at the same level.\n *\n * @param element - The ds-tree-item element\n * @returns Array of sibling tree item elements\n */\nfunction getSiblingTreeItems(element: HTMLElement): HTMLElement[] {\n // Find the container (either tree root or children slot)\n let container: HTMLElement | null = element.parentElement;\n\n // If parent is a slot, get the slot's parent\n if (container?.tagName?.toLowerCase() === \"slot\") {\n container = container.parentElement;\n }\n\n // If parent is a ul with role=\"group\", get its parent (the tree-item)\n // and then find the children slot\n if (container?.getAttribute(\"role\") === \"group\") {\n container = container.parentElement;\n }\n\n if (!container) {\n return [element];\n }\n\n // Query for direct tree-item children\n // This handles both root level (ds-tree > ds-tree-item)\n // and nested level (ds-tree-item [slot=children] > ds-tree-item)\n const items: HTMLElement[] = [];\n\n // Check direct children and slotted children\n const checkChildren = (parent: HTMLElement) => {\n for (const child of parent.children) {\n if (child.tagName?.toLowerCase() === \"ds-tree-item\") {\n items.push(child as HTMLElement);\n } else if (child.tagName?.toLowerCase() === \"slot\") {\n // Get assigned elements from slot\n const slot = child as HTMLSlotElement;\n for (const assigned of slot.assignedElements()) {\n if (assigned.tagName?.toLowerCase() === \"ds-tree-item\") {\n items.push(assigned as HTMLElement);\n }\n }\n }\n }\n };\n\n // For root tree, check its direct children\n if (container.tagName?.toLowerCase() === \"ds-tree\") {\n checkChildren(container);\n } else if (container.tagName?.toLowerCase() === \"ds-tree-item\") {\n // For nested items, find the children slot container\n const childrenSlot = container.querySelector('[slot=\"children\"]');\n if (childrenSlot) {\n for (const child of childrenSlot.children) {\n if (child.tagName?.toLowerCase() === \"ds-tree-item\") {\n items.push(child as HTMLElement);\n }\n }\n }\n }\n\n // If no items found via DOM traversal, fall back to the element itself\n return items.length > 0 ? items : [element];\n}\n\n/**\n * Update ARIA position attributes on a tree item element.\n *\n * @param element - The ds-tree-item element to update\n */\nexport function updateTreeItemAriaAttributes(element: HTMLElement): void {\n const position = calculateTreeItemPosition(element);\n\n element.setAttribute(\"aria-level\", String(position.level));\n element.setAttribute(\"aria-setsize\", String(position.setSize));\n element.setAttribute(\"aria-posinset\", String(position.posInSet));\n}\n\n/**\n * Update ARIA position attributes on all tree items within a tree.\n *\n * @param treeRoot - The ds-tree root element\n */\nexport function updateAllTreeItemAriaAttributes(treeRoot: HTMLElement): void {\n const items = treeRoot.querySelectorAll(\"ds-tree-item\");\n for (const item of items) {\n updateTreeItemAriaAttributes(item as unknown as HTMLElement);\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { emitEvent } from \"../../events/emit.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport type ListSelectionMode = \"single\" | \"multiple\" | \"none\";\nexport type ListOrientation = \"vertical\" | \"horizontal\";\nexport type ListSize = \"default\" | \"compact\" | \"spacious\";\n\n/**\n * List root component for collection display.\n *\n * @element ds-list\n *\n * @slot - ListItem elements\n *\n * @fires ds-selection-change - When selection changes\n *\n * @cssprop --ds-list-gap - Gap between items\n */\nexport class DsList extends DSElement {\n static override styles = [];\n\n /**\n * Selection mode.\n */\n @property({ type: String, attribute: \"selection-mode\", reflect: true })\n selectionMode: ListSelectionMode = \"single\";\n\n /**\n * List orientation.\n */\n @property({ type: String, reflect: true })\n orientation: ListOrientation = \"vertical\";\n\n /**\n * Size variant.\n */\n @property({ type: String, reflect: true })\n size: ListSize = \"default\";\n\n /**\n * Show border around list.\n */\n @property({ type: Boolean, reflect: true })\n bordered = false;\n\n /**\n * Accessible label.\n */\n @property({ type: String })\n label = \"List\";\n\n @state()\n private selectedItems: Set<string> = new Set();\n\n handleItemSelect(itemId: string): void {\n if (this.selectionMode === \"none\") return;\n\n if (this.selectionMode === \"single\") {\n this.selectedItems.clear();\n this.selectedItems.add(itemId);\n } else {\n if (this.selectedItems.has(itemId)) {\n this.selectedItems.delete(itemId);\n } else {\n this.selectedItems.add(itemId);\n }\n }\n\n emitEvent(this, \"selection-change\", {\n detail: { selectedItems: Array.from(this.selectedItems) },\n });\n\n this.requestUpdate();\n }\n\n isItemSelected(itemId: string): boolean {\n return this.selectedItems.has(itemId);\n }\n\n override render(): TemplateResult {\n const classes = {\n \"ds-list\": true,\n };\n\n return html`\n <ul\n class=${classMap(classes)}\n role=\"listbox\"\n aria-label=${this.label}\n aria-multiselectable=${this.selectionMode === \"multiple\" ? \"true\" : nothing}\n aria-orientation=${this.orientation}\n data-size=${this.size !== \"default\" ? this.size : nothing}\n data-orientation=${this.orientation !== \"vertical\" ? this.orientation : nothing}\n ?data-bordered=${this.bordered}\n >\n <slot></slot>\n </ul>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-list\", DsList);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-list\": DsList;\n }\n}\n","import { type TemplateResult, html, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { emitEvent } from \"../../events/emit.js\";\nimport { define } from \"../../registry/define.js\";\nimport type { DsList } from \"./list.js\";\n\n/**\n * List item component for collection items.\n *\n * @element ds-list-item\n *\n * @slot - Item content\n * @slot leading - Optional leading element (icon, avatar)\n * @slot secondary - Optional secondary text\n * @slot trailing - Optional trailing element (action, badge)\n *\n * @fires ds-select - When item is selected\n * @fires ds-activate - When item is activated (Enter/double-click)\n */\nexport class DsListItem extends DSElement {\n static override styles = [];\n\n /**\n * Unique item ID.\n */\n @property({ type: String, attribute: \"item-id\" })\n itemId = \"\";\n\n /**\n * Whether item is selected.\n */\n @property({ type: Boolean, reflect: true })\n selected = false;\n\n /**\n * Whether item is disabled.\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Value for identification.\n */\n @property({ type: String })\n value = \"\";\n\n private get listRoot(): DsList | null {\n return this.closest(\"ds-list\") as DsList | null;\n }\n\n private handleClick(): void {\n if (this.disabled) return;\n\n const list = this.listRoot;\n if (list) {\n list.handleItemSelect(this.itemId || this.value);\n this.selected = list.isItemSelected(this.itemId || this.value);\n }\n\n emitEvent(this, \"select\", {\n detail: {\n itemId: this.itemId,\n value: this.value,\n selected: this.selected,\n },\n });\n }\n\n private handleKeyDown(event: KeyboardEvent): void {\n if (this.disabled) return;\n\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n this.handleClick();\n\n if (event.key === \"Enter\") {\n emitEvent(this, \"activate\", {\n detail: {\n itemId: this.itemId,\n value: this.value,\n },\n });\n }\n }\n }\n\n override render(): TemplateResult {\n const classes = {\n \"ds-list-item\": true,\n };\n\n return html`\n <li\n class=${classMap(classes)}\n role=\"option\"\n tabindex=${this.disabled ? -1 : 0}\n aria-selected=${this.selected ? \"true\" : \"false\"}\n ?data-selected=${this.selected}\n ?data-disabled=${this.disabled}\n aria-disabled=${this.disabled ? \"true\" : nothing}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <slot name=\"leading\"></slot>\n <div class=\"ds-list-item__content\">\n <span class=\"ds-list-item__primary\">\n <slot></slot>\n </span>\n <slot name=\"secondary\"></slot>\n </div>\n <slot name=\"trailing\"></slot>\n </li>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-list-item\", DsListItem);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-list-item\": DsListItem;\n }\n}\n","/**\n * Card component - container for grouping related content.\n *\n * A structural component that provides visual grouping with consistent\n * styling for headers, content areas, and footers.\n *\n * @element ds-card\n *\n * @slot - Default slot for card content (ds-card-header, ds-card-content, ds-card-footer)\n *\n * @example\n * ```html\n * <ds-card>\n * <ds-card-header>\n * <h3>Card Title</h3>\n * </ds-card-header>\n * <ds-card-content>\n * <p>Card content goes here.</p>\n * </ds-card-content>\n * <ds-card-footer>\n * <button>Action</button>\n * </ds-card-footer>\n * </ds-card>\n * ```\n */\n\nimport { html } from \"lit\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport class DsCard extends DSElement {\n override render() {\n return html`<slot></slot>`;\n }\n}\n\ndefine(\"ds-card\", DsCard);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-card\": DsCard;\n }\n}\n","/**\n * Card Header component - header section for ds-card.\n *\n * @element ds-card-header\n *\n * @slot - Default slot for header content (typically title and description)\n */\n\nimport { html } from \"lit\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport class DsCardHeader extends DSElement {\n override render() {\n return html`<slot></slot>`;\n }\n}\n\ndefine(\"ds-card-header\", DsCardHeader);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-card-header\": DsCardHeader;\n }\n}\n","/**\n * Card Content component - main content section for ds-card.\n *\n * @element ds-card-content\n *\n * @slot - Default slot for main card content\n */\n\nimport { html } from \"lit\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport class DsCardContent extends DSElement {\n override render() {\n return html`<slot></slot>`;\n }\n}\n\ndefine(\"ds-card-content\", DsCardContent);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-card-content\": DsCardContent;\n }\n}\n","/**\n * Card Footer component - footer section for ds-card.\n *\n * @element ds-card-footer\n *\n * @slot - Default slot for footer content (typically actions)\n */\n\nimport { html } from \"lit\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport class DsCardFooter extends DSElement {\n override render() {\n return html`<slot></slot>`;\n }\n}\n\ndefine(\"ds-card-footer\", DsCardFooter);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-card-footer\": DsCardFooter;\n }\n}\n","/**\n * Separator component - visual divider between content sections.\n *\n * @element ds-separator\n *\n * @example\n * ```html\n * <ds-separator></ds-separator>\n * <ds-separator orientation=\"vertical\"></ds-separator>\n * <ds-separator decorative></ds-separator>\n * ```\n */\n\nimport { html } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport type SeparatorOrientation = \"horizontal\" | \"vertical\";\n\nexport class DsSeparator extends DSElement {\n /** Visual orientation of the separator */\n @property({ reflect: true })\n orientation: SeparatorOrientation = \"horizontal\";\n\n /** Whether the separator is purely decorative (no semantic meaning) */\n @property({ type: Boolean, reflect: true })\n decorative = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.updateAccessibility();\n }\n\n override updated(): void {\n this.updateAccessibility();\n }\n\n private updateAccessibility(): void {\n if (this.decorative) {\n this.setAttribute(\"role\", \"none\");\n this.removeAttribute(\"aria-orientation\");\n } else {\n this.setAttribute(\"role\", \"separator\");\n this.setAttribute(\"aria-orientation\", this.orientation);\n }\n }\n\n override render() {\n return html``;\n }\n}\n\ndefine(\"ds-separator\", DsSeparator);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-separator\": DsSeparator;\n }\n}\n","/**\n * AspectRatio component - maintains consistent width-to-height ratio.\n *\n * @element ds-aspect-ratio\n *\n * @slot - Default slot for content to maintain aspect ratio\n *\n * @example\n * ```html\n * <ds-aspect-ratio ratio=\"16/9\">\n * <img src=\"image.jpg\" alt=\"...\" />\n * </ds-aspect-ratio>\n * <ds-aspect-ratio ratio=\"4/3\">\n * <video src=\"video.mp4\"></video>\n * </ds-aspect-ratio>\n * ```\n */\n\nimport { html } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport class DsAspectRatio extends DSElement {\n /**\n * Aspect ratio as width/height (e.g., \"16/9\", \"4/3\", \"1/1\").\n * Can also be a number (e.g., 1.777 for 16:9).\n */\n @property({ reflect: true })\n ratio = \"1/1\";\n\n override updated(): void {\n this.updateCssVariable();\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.updateCssVariable();\n }\n\n private updateCssVariable(): void {\n const ratioValue = this.parseRatio(this.ratio);\n this.style.setProperty(\"--ds-aspect-ratio\", String(ratioValue));\n }\n\n private parseRatio(ratio: string): number {\n // Handle fraction format like \"16/9\"\n if (ratio.includes(\"/\")) {\n const parts = ratio.split(\"/\").map(Number);\n const width = parts[0];\n const height = parts[1];\n if (\n width !== undefined &&\n height !== undefined &&\n !Number.isNaN(width) &&\n !Number.isNaN(height) &&\n height !== 0\n ) {\n return width / height;\n }\n }\n // Handle decimal format\n const parsed = Number.parseFloat(ratio);\n return Number.isNaN(parsed) ? 1 : parsed;\n }\n\n override render() {\n return html`<slot></slot>`;\n }\n}\n\ndefine(\"ds-aspect-ratio\", DsAspectRatio);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-aspect-ratio\": DsAspectRatio;\n }\n}\n"],"mappings":";;;;;;;;;;AAAA,SAA8B,MAAM,eAAe;AACnD,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AAiBlB,IAAM,UAAN,cAAsB,UAAU;AAAA,EAAhC;AAAA;AAOL,gBAAkB;AAMlB,mBAAU;AAMV,sBAAa;AAMb,iBAAQ;AAMR,wBAAe;AAMf,mBAAU;AAAA;AAAA,EApCV;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EAsCjB,SAAyB;AAChC,UAAM,UAAU;AAAA,MACd,YAAY;AAAA,IACd;AAEA,WAAO;AAAA;AAAA,gBAEK,SAAS,OAAO,CAAC;AAAA;AAAA,oBAEb,KAAK,SAAS,YAAY,KAAK,OAAO,OAAO;AAAA,wBACzC,KAAK,OAAO;AAAA,2BACT,KAAK,UAAU;AAAA,sBACpB,KAAK,KAAK;AAAA,8BACF,KAAK,YAAY;AAAA;AAAA,UAGrC,KAAK,UACD,0CAA0C,KAAK,OAAO,eACtD,OACN;AAAA;AAAA;AAAA;AAAA,EAIN;AACF;AAxDE;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAN9B,QAOX;AAMA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAZ/B,QAaX;AAMA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAlB/B,QAmBX;AAMA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAxB/B,QAyBX;AAMA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,WAAW,iBAAiB,SAAS,KAAK,CAAC;AAAA,GA9B3D,QA+BX;AAMA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GApCf,QAqCX;AA6BF,OAAO,YAAY,OAAO;;;ACrF1B,SAA8B,QAAAA,aAAY;AAWnC,IAAM,gBAAN,cAA4B,UAAU;AAAA,EAC3C;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EAEjB,SAAyB;AAChC,WAAOC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKT;AACF;AAGA,OAAO,mBAAmB,aAAa;;;ACxBvC,SAA8B,QAAAC,aAAY;AAWnC,IAAM,cAAN,cAA0B,UAAU;AAAA,EACzC;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EAEjB,SAAyB;AAChC,WAAOC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKT;AACF;AAGA,OAAO,iBAAiB,WAAW;;;ACxBnC,SAA8B,QAAAC,OAAM,WAAAC,gBAAe;AACnD,SAAS,YAAAC,iBAAgB;AAWlB,IAAM,aAAN,cAAyB,UAAU;AAAA,EAAnC;AAAA;AAOL,iBAAQ;AAMR,oBAAW;AAAA;AAAA,EAZX;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EAcjB,SAAyB;AAChC,WAAOC;AAAA;AAAA;AAAA;AAAA,yBAIc,KAAK,QAAQ;AAAA,wBACd,KAAK,WAAW,SAASC,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKtD;AACF;AApBE;AAAA,EADCC,UAAS,EAAE,MAAM,QAAQ,WAAW,SAAS,CAAC;AAAA,GANpC,WAOX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAZ/B,WAaX;AAiBF,OAAO,gBAAgB,UAAU;;;AC1CjC,SAA8B,QAAAC,OAAM,WAAAC,gBAAe;AACnD,SAAS,YAAAC,iBAAgB;AASzB,IAAM,WAAWC;AAAA;AAAA;AAAA;AAAA;AAeV,IAAM,cAAN,cAA0B,UAAU;AAAA,EAApC;AAAA;AAOL,kBAAS;AAMT,iBAAoB;AAMpB,oBAAW;AAMX,yBAA+B;AAM/B,iBAAQ;AAAA;AAAA,EA9BR;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EAgClB,cAAoB;AAC1B,QAAI,CAAC,KAAK,SAAU;AAEpB,cAAU,MAAM,QAAQ;AAAA,MACtB,QAAQ;AAAA,QACN,QAAQ,KAAK;AAAA,QACb,WAAW,KAAK,iBAAiB;AAAA,MACnC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,cAAc,OAA4B;AAChD,QAAI,CAAC,KAAK,SAAU;AACpB,QAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,YAAM,eAAe;AACrB,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,mBAAkC;AACxC,QAAI,KAAK,kBAAkB,OAAQ,QAAO;AAC1C,QAAI,KAAK,kBAAkB,MAAO,QAAO;AACzC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,cAAmD;AACzD,QAAI,KAAK,kBAAkB,MAAO,QAAO;AACzC,QAAI,KAAK,kBAAkB,OAAQ,QAAO;AAC1C,WAAO;AAAA,EACT;AAAA,EAES,SAAyB;AAChC,UAAM,QAAQ,KAAK,QAAQ,UAAU,KAAK,KAAK,KAAK;AAEpD,WAAOA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAKU,KAAK,UAAU,SAAS,KAAK,QAAQC,QAAO;AAAA,yBACxC,KAAK,QAAQ;AAAA,8BACR,KAAK,WAAW,KAAK,gBAAgBA,QAAO;AAAA,oBACtD,KAAK,WAAW,KAAK,YAAY,IAAIA,QAAO;AAAA,mBAC7C,KAAK,WAAW,IAAIA,QAAO;AAAA,gBAC9B,SAASA,QAAO;AAAA,iBACf,KAAK,WAAW;AAAA,mBACd,KAAK,aAAa;AAAA;AAAA;AAAA,UAG3B,KAAK,WAAWD,0CAAyC,QAAQ,YAAYC,QAAO;AAAA;AAAA;AAAA,EAG5F;AACF;AAtFE;AAAA,EADCC,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GANf,YAOX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAZ9B,YAaX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAlB/B,YAmBX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,WAAW,kBAAkB,SAAS,KAAK,CAAC;AAAA,GAxB3D,YAyBX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA9Bf,YA+BX;AAiEF,OAAO,iBAAiB,WAAW;;;ACzHnC,SAA8B,QAAAC,OAAM,WAAAC,gBAAe;AACnD,SAAS,YAAAC,iBAAgB;AAYlB,IAAM,cAAN,cAA0B,UAAU;AAAA,EAApC;AAAA;AAOL,iBAAoB;AAMpB,mBAAU;AAMV,mBAAU;AAAA;AAAA,EAlBV;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EAoBjB,SAAyB;AAChC,WAAOC;AAAA;AAAA;AAAA;AAAA,qBAIU,KAAK,UAAU,SAAS,KAAK,QAAQC,QAAO;AAAA,kBAC/C,KAAK,UAAU,IAAI,KAAK,UAAUA,QAAO;AAAA,kBACzC,KAAK,UAAU,IAAI,KAAK,UAAUA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKzD;AACF;AA3BE;AAAA,EADCC,UAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAN9B,YAOX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAZf,YAaX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAlBf,YAmBX;AAkBF,OAAO,iBAAiB,WAAW;;;AClDnC,SAA8B,QAAAC,OAAM,WAAAC,gBAAe;AACnD,SAAS,YAAAC,WAAU,aAAa;AAChC,SAAS,YAAAC,iBAAgB;AA+BzB,IAAM,cAAcC;AAAA;AAAA;AAAA;AAAA;AAqBb,IAAM,cAAN,cAA0B,UAAU;AAAA,EAApC;AAAA;AAOL,uBAAc;AAMd,qBAAY;AAMZ,oBAAW;AAMX,qBAAY;AAMZ,gBAAO;AAMP,oBAAW;AAMX,qBAAY;AAMZ,sBAAa;AAMb,yBAAuC;AAMvC,mBAAU;AAMV,sBAAa;AAMb,yBAAwC;AAMxC,kBAAS;AAMT,wBAAe;AAGf,SAAQ,eAA4B,oBAAI,IAAI;AAG5C,SAAQ,mBAAmB;AAAA;AAAA,EA1F3B;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EA4F1B,IAAY,kBAA4B;AACtC,WAAO,KAAK,UAAU,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,CAAC,CAAC;AAAA,EAC9D;AAAA,EAEA,IAAY,aAAqB;AAC/B,WAAO,KAAK,KAAK,KAAK,YAAY,KAAK,QAAQ;AAAA,EACjD;AAAA,EAEA,IAAY,WAAmB;AAC7B,YAAQ,KAAK,OAAO,KAAK,KAAK,WAAW;AAAA,EAC3C;AAAA,EAEA,IAAY,SAAiB;AAC3B,WAAO,KAAK,IAAI,KAAK,OAAO,KAAK,UAAU,KAAK,SAAS;AAAA,EAC3D;AAAA,EAEA,WAAW,QAAsB;AAC/B,QAAI,eAAuC;AAE3C,QAAI,KAAK,eAAe,QAAQ;AAC9B,UAAI,KAAK,kBAAkB,OAAO;AAChC,uBAAe;AAAA,MACjB,WAAW,KAAK,kBAAkB,QAAQ;AACxC,uBAAe;AAAA,MACjB;AAAA,IACF;AAEA,SAAK,aAAa,iBAAiB,SAAS,KAAK;AACjD,SAAK,gBAAgB;AAGrB,SAAK,mBAAmB,QAAQ,YAAY;AAE5C,cAAU,MAAM,QAAQ;AAAA,MACtB,QAAQ;AAAA,QACN,QAAQ,KAAK;AAAA,QACb,WAAW,KAAK;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAmB,QAAgB,WAAyC;AAClF,QAAI,cAAc,OAAO;AACvB,WAAK,mBAAmB,aAAa,MAAM;AAAA,IAC7C,WAAW,cAAc,QAAQ;AAC/B,WAAK,mBAAmB,aAAa,MAAM;AAAA,IAC7C,OAAO;AACL,WAAK,mBAAmB;AAAA,IAC1B;AAGA,eAAW,MAAM;AACf,WAAK,mBAAmB;AAAA,IAC1B,GAAG,GAAI;AAAA,EACT;AAAA,EAEA,iBAAiB,SAAuB;AACtC,QAAI,UAAU,KAAK,UAAU,KAAK,WAAY;AAE9C,SAAK,OAAO;AACZ,cAAU,MAAM,eAAe,EAAE,QAAQ,EAAE,MAAM,QAAQ,EAAE,CAAC;AAAA,EAC9D;AAAA,EAEA,qBAAqB,OAAoB;AACvC,UAAM,SAAS,MAAM;AACrB,UAAM,UAAU,OAAO,OAAO,KAAK;AACnC,SAAK,WAAW;AAChB,SAAK,OAAO;AACZ,cAAU,MAAM,oBAAoB,EAAE,QAAQ,EAAE,UAAU,QAAQ,EAAE,CAAC;AAAA,EACvE;AAAA,EAEA,mBAAmB,OAAqB;AACtC,QAAI,CAAC,KAAK,WAAY;AAEtB,QAAI,KAAK,kBAAkB,UAAU;AACnC,WAAK,aAAa,MAAM;AACxB,WAAK,aAAa,IAAI,KAAK;AAAA,IAC7B,OAAO;AACL,UAAI,KAAK,aAAa,IAAI,KAAK,GAAG;AAChC,aAAK,aAAa,OAAO,KAAK;AAAA,MAChC,OAAO;AACL,aAAK,aAAa,IAAI,KAAK;AAAA,MAC7B;AAAA,IACF;AAEA,cAAU,MAAM,oBAAoB;AAAA,MAClC,QAAQ,EAAE,cAAc,MAAM,KAAK,KAAK,YAAY,EAAE;AAAA,IACxD,CAAC;AACD,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,iBAAuB;AACrB,SAAK,aAAa,MAAM;AACxB,cAAU,MAAM,oBAAoB,EAAE,QAAQ,EAAE,cAAc,CAAC,EAAE,EAAE,CAAC;AACpE,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,cAAc,OAAwB;AACpC,WAAO,KAAK,aAAa,IAAI,KAAK;AAAA,EACpC;AAAA,EAEQ,mBAAmC;AACzC,UAAM,QAAkB,CAAC;AACzB,UAAM,aAAa;AACnB,QAAI,QAAQ,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK,MAAM,aAAa,CAAC,CAAC;AAC9D,UAAM,MAAM,KAAK,IAAI,KAAK,YAAY,QAAQ,aAAa,CAAC;AAE5D,QAAI,MAAM,QAAQ,IAAI,YAAY;AAChC,cAAQ,KAAK,IAAI,GAAG,MAAM,aAAa,CAAC;AAAA,IAC1C;AAEA,aAAS,IAAI,OAAO,KAAK,KAAK,KAAK;AACjC,YAAM,KAAK,CAAC;AAAA,IACd;AAEA,WAAOA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAKW,KAAK,SAAS,CAAC;AAAA,mBAClB,MAAM,KAAK,iBAAiB,KAAK,OAAO,CAAC,CAAC;AAAA;AAAA;AAAA,YAGjD,WAAW;AAAA;AAAA;AAAA,UAGb,MAAM;AAAA,MACN,CAAC,MAAMA;AAAA;AAAA;AAAA;AAAA,6BAIY,MAAM,KAAK,IAAI;AAAA,uBACrB,MAAM,KAAK,iBAAiB,CAAC,CAAC;AAAA,iCACpB,CAAC;AAAA,6BACL,MAAM,KAAK,OAAO,SAASC,QAAO;AAAA;AAAA,gBAE/C,CAAC;AAAA;AAAA;AAAA,IAGT,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,sBAKa,KAAK,SAAS,KAAK,UAAU;AAAA,mBAChC,MAAM,KAAK,iBAAiB,KAAK,OAAO,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA,YAIjD,WAAW;AAAA;AAAA;AAAA;AAAA,EAIrB;AAAA,EAES,SAAyB;AAChC,UAAM,UAAU;AAAA,MACd,iBAAiB;AAAA,IACnB;AAEA,WAAOD;AAAA;AAAA,gBAEKE,UAAS,OAAO,CAAC;AAAA;AAAA;AAAA,oBAGb,KAAK,UAAU,SAASD,QAAO;AAAA,wBAC3B,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAUxB,KAAK,gBAAgB;AAAA;AAAA,UAGvB,KAAK,aAAa,OAAO,IACrBD;AAAA;AAAA;AAAA,oBAGM,KAAK,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,2BAKf,KAAK,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA,gBAMhCC,QACN;AAAA;AAAA;AAAA,kBAGU,KAAK,cAAc,+BAA+B,0BAA0B;AAAA;AAAA;AAAA;AAAA,YAKlF,KAAK,UACDD;AAAA;AAAA;AAAA;AAAA,kBAKAC,QACN;AAAA;AAAA;AAAA,UAIA,KAAK,YAAY,IACbD;AAAA;AAAA;AAAA,4BAGc,KAAK,QAAQ,IAAI,KAAK,MAAM,OAAO,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,oCAKzC,KAAK,oBAAoB;AAAA,sBACvC,KAAK,gBAAgB;AAAA,MACrB,CAAC,SAASA;AAAA,wCACQ,IAAI,cAAc,SAAS,KAAK,QAAQ;AAAA,4BACpD,IAAI;AAAA;AAAA;AAAA,IAGZ,CAAC;AAAA;AAAA;AAAA;AAAA,kBAIH,KAAK,iBAAiB,CAAC;AAAA;AAAA,gBAG3BC,QACN;AAAA;AAAA;AAAA,EAGN;AACF;AA7UE;AAAA,EADCE,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAN/B,YAOX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,WAAW,aAAa,CAAC;AAAA,GAZxC,YAaX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAlBf,YAmBX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,WAAW,aAAa,CAAC;AAAA,GAxBxC,YAyBX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA9Bf,YA+BX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,WAAW,YAAY,CAAC;AAAA,GApCvC,YAqCX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,WAAW,aAAa,CAAC;AAAA,GA1CxC,YA2CX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAhD/B,YAiDX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,WAAW,iBAAiB,CAAC;AAAA,GAtD5C,YAuDX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GA5D/B,YA6DX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,WAAW,cAAc,CAAC;AAAA,GAlEzC,YAmEX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,WAAW,iBAAiB,CAAC;AAAA,GAxE5C,YAyEX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA9Ef,YA+EX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,WAAW,gBAAgB,CAAC;AAAA,GApF3C,YAqFX;AAGQ;AAAA,EADP,MAAM;AAAA,GAvFI,YAwFH;AAGA;AAAA,EADP,MAAM;AAAA,GA1FI,YA2FH;AA4PV,OAAO,iBAAiB,WAAW;;;AC7YnC,SAA8B,QAAAC,OAAM,WAAAC,gBAAe;AACnD,SAAS,YAAAC,WAAU,SAAAC,cAAa;AAChC,SAAS,YAAAC,iBAAgB;AASzB,IAAM,kBAAkBC;AAAA;AAAA;AAAA;AAAA;AAqBjB,IAAM,WAAN,cAAuB,UAAU;AAAA,EAAjC;AAAA;AAOL,eAAM;AAMN,eAAM;AAMN,gBAAO;AAMP,gBAAmB;AAMnB,iBAAqB;AAYrB,sBAAa;AAGb,SAAQ,aAAa;AAAA;AAAA,EA7CrB;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EA+C1B,IAAY,WAAmB;AAC7B,QAAI,CAAC,KAAK,KAAM,QAAO;AAEvB,UAAM,QAAQ,KAAK,KAAK,KAAK,EAAE,MAAM,KAAK;AAC1C,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAI,MAAM,WAAW,GAAG;AACtB,cAAQ,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,EAAE,YAAY;AAAA,IAChD;AACA,UAAM,QAAQ,MAAM,CAAC,KAAK;AAC1B,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC,KAAK;AACxC,YAAQ,MAAM,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,GAAG,YAAY;AAAA,EACxD;AAAA,EAEA,IAAY,YAAqB;AAC/B,WAAO,QAAQ,KAAK,OAAO,CAAC,KAAK,UAAU;AAAA,EAC7C;AAAA,EAEA,IAAY,eAAwB;AAClC,WAAO,CAAC,KAAK,aAAa,QAAQ,KAAK,QAAQ;AAAA,EACjD;AAAA,EAEA,IAAY,WAAoB;AAC9B,WAAO,CAAC,KAAK,aAAa,CAAC,KAAK;AAAA,EAClC;AAAA,EAEQ,mBAAyB;AAC/B,SAAK,aAAa;AAAA,EACpB;AAAA,EAEQ,kBAAwB;AAC9B,SAAK,aAAa;AAAA,EACpB;AAAA,EAES,SAAyB;AAChC,UAAM,UAAU;AAAA,MACd,aAAa;AAAA,IACf;AAEA,WAAOA;AAAA;AAAA,gBAEKC,UAAS,OAAO,CAAC;AAAA;AAAA,qBAEZ,KAAK,OAAO,KAAK,QAAQ,QAAQ;AAAA,oBAClC,KAAK,IAAI;AAAA,qBACR,KAAK,UAAU,WAAW,KAAK,QAAQC,QAAO;AAAA;AAAA,UAGzD,KAAK,YACDF;AAAA;AAAA;AAAA;AAAA,sBAIQ,KAAK,GAAG;AAAA;AAAA,yBAEL,KAAK,gBAAgB;AAAA,wBACtB,KAAK,eAAe;AAAA;AAAA,gBAG9BE,QACN;AAAA,UAEE,KAAK,eACDF;AAAA;AAAA,kBAEI,KAAK,QAAQ;AAAA;AAAA,gBAGjBE,QACN;AAAA,UAEE,KAAK,WACDF;AAAA;AAAA,kBAEI,eAAe;AAAA;AAAA,gBAGnBE,QACN;AAAA,UAEE,KAAK,cAAc,KAAK,SACpBF;AAAA;AAAA;AAAA;AAAA,8BAIgB,KAAK,MAAM;AAAA,6BACZ,WAAW,KAAK,MAAM,EAAE;AAAA;AAAA,gBAGvCE,QACN;AAAA;AAAA;AAAA,EAGN;AACF;AAtIE;AAAA,EADCC,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GANf,SAOX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAZf,SAaX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAlBf,SAmBX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAxB9B,SAyBX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GA9B9B,SA+BX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GApCf,SAqCX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,WAAW,cAAc,CAAC;AAAA,GA1C1C,SA2CX;AAGQ;AAAA,EADPC,OAAM;AAAA,GA7CI,SA8CH;AAkGV,OAAO,aAAa,QAAQ;;;AChL5B,SAA8B,QAAAC,OAAM,WAAAC,gBAAe;AACnD,SAAS,YAAAC,WAAU,SAAAC,cAAa;AAChC,SAAS,YAAAC,iBAAgB;AAgBlB,IAAM,gBAAN,cAA4B,UAAU;AAAA,EAAtC;AAAA;AAOL,eAAM;AAMN,gBAAmB;AAGnB,SAAQ,gBAAgB;AAGxB,SAAQ,iBAA4B,CAAC;AAAA;AAAA,EAlBrC;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EAoBjB,oBAA0B;AACjC,UAAM,kBAAkB;AACxB,SAAK,uBAAuB;AAG5B,UAAM,WAAW,IAAI,iBAAiB,MAAM,KAAK,uBAAuB,CAAC;AACzE,aAAS,QAAQ,MAAM,EAAE,WAAW,KAAK,CAAC;AAAA,EAC5C;AAAA,EAEQ,yBAA+B;AACrC,UAAM,UAAU,MAAM,KAAK,KAAK,iBAAiB,WAAW,CAAC;AAC7D,UAAM,QAAQ,QAAQ;AAEtB,QAAI,SAAS,KAAK,KAAK;AACrB,WAAK,iBAAiB;AACtB,WAAK,gBAAgB;AAAA,IACvB,OAAO;AACL,WAAK,iBAAiB,QAAQ,MAAM,GAAG,KAAK,GAAG;AAC/C,WAAK,gBAAgB,QAAQ,KAAK;AAAA,IACpC;AAGA,YAAQ,QAAQ,CAAC,QAAQ,UAAU;AACjC,UAAI,SAAS,KAAK,KAAK;AACrB,QAAC,OAAuB,MAAM,UAAU;AAAA,MAC1C,OAAO;AACL,QAAC,OAAuB,MAAM,UAAU;AAAA,MAC1C;AAAA,IACF,CAAC;AAED,SAAK,cAAc;AAAA,EACrB;AAAA,EAES,SAAyB;AAChC,UAAM,UAAU;AAAA,MACd,mBAAmB;AAAA,IACrB;AAEA,WAAOC;AAAA;AAAA,gBAEKC,UAAS,OAAO,CAAC;AAAA;AAAA;AAAA,oBAGb,KAAK,IAAI;AAAA;AAAA,UAGnB,KAAK,gBAAgB,IACjBD;AAAA;AAAA;AAAA;AAAA,8BAIgB,KAAK,aAAa;AAAA;AAAA,mBAE7B,KAAK,aAAa;AAAA;AAAA,gBAGvBE,QACN;AAAA,4BACoB,KAAK,sBAAsB;AAAA;AAAA;AAAA,EAGrD;AACF;AA5EE;AAAA,EADCC,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GANf,cAOX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAZ9B,cAaX;AAGQ;AAAA,EADPC,OAAM;AAAA,GAfI,cAgBH;AAGA;AAAA,EADPA,OAAM;AAAA,GAlBI,cAmBH;AAmEV,OAAO,mBAAmB,aAAa;;;ACxGvC,SAA8B,QAAAC,QAAM,WAAAC,gBAAe;AACnD,SAAS,YAAAC,iBAAgB;AACzB,SAAS,YAAAC,iBAAgB;AAuBlB,IAAM,UAAN,cAAsB,UAAU;AAAA,EAAhC;AAAA;AAOL,mBAAU;AAYV,mBAAwB;AAMxB,gBAAkB;AAMlB,mBAAU;AAMV,eAAM;AAMN,oBAA0B;AAM1B,iBAAQ;AAAA;AAAA,EAhDR;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EAkD1B,IAAY,iBAAyB;AACnC,QAAI,KAAK,IAAK,QAAO;AACrB,QAAI,KAAK,QAAQ,UAAa,CAAC,OAAO,MAAM,OAAO,KAAK,OAAO,CAAC,GAAG;AACjE,YAAM,QAAQ,OAAO,KAAK,OAAO;AACjC,UAAI,QAAQ,KAAK,KAAK;AACpB,eAAO,GAAG,KAAK,GAAG;AAAA,MACpB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAES,SAAyB;AAChC,UAAM,UAAU;AAAA,MACd,YAAY;AAAA,IACd;AAEA,WAAOC;AAAA;AAAA,gBAEKC,UAAS,OAAO,CAAC;AAAA;AAAA,uBAEV,KAAK,OAAO;AAAA,oBACf,KAAK,SAAS,OAAO,KAAK,OAAOC,QAAO;AAAA,wBACpC,KAAK,OAAO;AAAA,oBAChB,KAAK,GAAG;AAAA,wBACJ,KAAK,QAAQ;AAAA,sBACf,KAAK,KAAK;AAAA,qBACX,KAAK,MAAM,2BAA2B,GAAG,KAAK,cAAc,gBAAgB;AAAA;AAAA,UAEvF,KAAK,MAAMA,WAAU,KAAK,cAAc;AAAA;AAAA;AAAA,EAGhD;AACF;AA5EE;AAAA,EADCC,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GANf,QAOX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAZf,QAaX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAlB9B,QAmBX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAxB9B,QAyBX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GA9B/B,QA+BX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GApC/B,QAqCX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GA1C9B,QA2CX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAhD/B,QAiDX;AAqCF,OAAO,YAAY,OAAO;;;AC/G1B,SAA8B,QAAAC,QAAM,WAAAC,gBAAe;AACnD,SAAS,YAAAC,iBAAgB;AACzB,SAAS,YAAAC,iBAAgB;AAgBzB,IAAM,YAAYC;AAAA;AAAA;AAAA;AAAA;AAoBX,IAAM,QAAN,cAAoB,UAAU;AAAA,EAA9B;AAAA;AAOL,mBAAsB;AAMtB,gBAAgB;AAMhB,iBAAQ;AAMR,qBAAY;AAMZ,qBAAY;AAMZ,oBAAW;AAMX,iBAAQ;AAAA;AAAA,EA1CR;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EA4ClB,aAAa,OAAoB;AACvC,UAAM,gBAAgB;AACtB,QAAI,KAAK,SAAU;AAEnB,cAAU,MAAM,UAAU;AAAA,MACxB,QAAQ,EAAE,OAAO,KAAK,MAAM;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA,EAEQ,cAAoB;AAC1B,QAAI,CAAC,KAAK,aAAa,KAAK,SAAU;AAEtC,cAAU,MAAM,SAAS;AAAA,MACvB,QAAQ,EAAE,OAAO,KAAK,MAAM;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA,EAEQ,cAAc,OAA4B;AAChD,QAAI,KAAK,SAAU;AAEnB,QAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,UAAI,KAAK,WAAW;AAClB,cAAM,eAAe;AACrB,aAAK,YAAY;AAAA,MACnB;AAAA,IACF,WAAW,MAAM,QAAQ,eAAe,MAAM,QAAQ,UAAU;AAC9D,UAAI,KAAK,WAAW;AAClB,cAAM,eAAe;AACrB,kBAAU,MAAM,UAAU,EAAE,QAAQ,EAAE,OAAO,KAAK,MAAM,EAAE,CAAC;AAAA,MAC7D;AAAA,IACF;AAAA,EACF;AAAA,EAES,SAAyB;AAChC,UAAM,UAAU;AAAA,MACd,UAAU;AAAA,IACZ;AAEA,WAAOA;AAAA;AAAA,gBAEKC,UAAS,OAAO,CAAC;AAAA,eAClB,KAAK,YAAY,WAAW,QAAQ;AAAA,mBAChC,KAAK,aAAa,CAAC,KAAK,WAAW,IAAIC,QAAO;AAAA,uBAC1C,KAAK,OAAO;AAAA,oBACf,KAAK,SAAS,OAAO,KAAK,OAAOA,QAAO;AAAA,sBACtC,KAAK,KAAK;AAAA,0BACN,KAAK,SAAS;AAAA,yBACf,KAAK,QAAQ;AAAA,wBACd,KAAK,WAAW,SAASA,QAAO;AAAA,iBACvC,KAAK,WAAW;AAAA,mBACd,KAAK,aAAa;AAAA;AAAA;AAAA;AAAA,UAK3B,KAAK,YACDF;AAAA;AAAA;AAAA;AAAA;AAAA,4BAKc,KAAK,QAAQ;AAAA,yBAChB,KAAK,YAAY;AAAA;AAAA,kBAExB,SAAS;AAAA;AAAA,gBAGbE,QACN;AAAA;AAAA;AAAA,EAGN;AACF;AA9GE;AAAA,EADCC,UAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAN9B,MAOX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAZ9B,MAaX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAlB/B,MAmBX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAxB/B,MAyBX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GA9B/B,MA+BX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GApC/B,MAqCX;AAMA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA1Cf,MA2CX;AA6EF,OAAO,UAAU,KAAK;;;AC9JtB,SAA8B,QAAAC,QAAM,WAAAC,iBAAe;AACnD,SAAS,YAAAC,YAAU,SAAAC,cAAa;AAChC,SAAS,YAAAC,iBAAgB;AAQzB,IAAM,kBAAkBC;AAAA;AAAA;AAAA;AAAA;AAMxB,IAAM,mBAAmBA;AAAA;AAAA;AAAA;AAAA;AAiBlB,IAAM,aAAN,cAAyB,UAAU;AAAA,EAAnC;AAAA;AAOL,iBAAQ;AAMR,eAAM;AAMN,eAAM;AAMN,yBAAgB;AAMhB,kBAAS;AAMT,gBAAqB;AAMrB,0BAAiB;AAGjB,SAAQ,WAAiB,oBAAI,KAAK;AAAA;AAAA,EA7ClC;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EA+C1B,IAAY,eAA4B;AACtC,WAAO,KAAK,QAAQ,IAAI,KAAK,KAAK,KAAK,IAAI;AAAA,EAC7C;AAAA,EAEA,IAAY,UAAuB;AACjC,WAAO,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG,IAAI;AAAA,EACzC;AAAA,EAEA,IAAY,UAAuB;AACjC,WAAO,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG,IAAI;AAAA,EACzC;AAAA,EAEA,IAAY,kBAA+B;AACzC,QAAI,CAAC,KAAK,cAAe,QAAO,oBAAI,IAAI;AACxC,WAAO,IAAI,IAAI,KAAK,cAAc,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAAA,EACnE;AAAA,EAEA,IAAY,eAAyB;AACnC,UAAM,YAAY,IAAI,KAAK,eAAe,KAAK,QAAQ,EAAE,SAAS,QAAQ,CAAC;AAC3E,UAAM,OAAiB,CAAC;AAExB,UAAM,WAAW,IAAI,KAAK,MAAM,GAAG,CAAC;AACpC,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,MAAM,IAAI,KAAK,QAAQ;AAC7B,UAAI,QAAQ,SAAS,QAAQ,KAAM,IAAI,KAAK,kBAAkB,CAAE;AAChE,WAAK,KAAK,UAAU,OAAO,GAAG,CAAC;AAAA,IACjC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,IAAY,iBAAyB;AACnC,UAAM,YAAY,IAAI,KAAK,eAAe,KAAK,QAAQ;AAAA,MACrD,OAAO;AAAA,MACP,MAAM;AAAA,IACR,CAAC;AACD,WAAO,UAAU,OAAO,KAAK,QAAQ;AAAA,EACvC;AAAA,EAEA,IAAY,eAA0D;AACpE,UAAM,OAAkD,CAAC;AACzD,UAAM,OAAO,KAAK,SAAS,YAAY;AACvC,UAAM,QAAQ,KAAK,SAAS,SAAS;AAGrC,UAAM,eAAe,IAAI,KAAK,MAAM,OAAO,CAAC;AAE5C,UAAM,iBAAiB,aAAa,OAAO;AAE3C,UAAM,qBAAqB,iBAAiB,KAAK,iBAAiB,KAAK;AAGvE,aAAS,IAAI,mBAAmB,IAAI,GAAG,KAAK;AAC1C,YAAM,OAAO,IAAI,KAAK,MAAM,OAAO,IAAI,CAAC;AACxC,WAAK,KAAK,EAAE,MAAM,WAAW,KAAK,CAAC;AAAA,IACrC;AAGA,UAAM,cAAc,IAAI,KAAK,MAAM,QAAQ,GAAG,CAAC,EAAE,QAAQ;AACzD,aAAS,IAAI,GAAG,KAAK,aAAa,KAAK;AACrC,WAAK,KAAK,EAAE,MAAM,IAAI,KAAK,MAAM,OAAO,CAAC,GAAG,WAAW,MAAM,CAAC;AAAA,IAChE;AAGA,UAAM,YAAY,KAAK,KAAK;AAC5B,aAAS,IAAI,GAAG,KAAK,WAAW,KAAK;AACnC,YAAM,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG,CAAC;AACxC,WAAK,KAAK,EAAE,MAAM,WAAW,KAAK,CAAC;AAAA,IACrC;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,QAAQ,MAAqB;AACnC,UAAM,QAAQ,oBAAI,KAAK;AACvB,WACE,KAAK,QAAQ,MAAM,MAAM,QAAQ,KACjC,KAAK,SAAS,MAAM,MAAM,SAAS,KACnC,KAAK,YAAY,MAAM,MAAM,YAAY;AAAA,EAE7C;AAAA,EAEQ,WAAW,MAAqB;AACtC,QAAI,CAAC,KAAK,aAAc,QAAO;AAC/B,WACE,KAAK,QAAQ,MAAM,KAAK,aAAa,QAAQ,KAC7C,KAAK,SAAS,MAAM,KAAK,aAAa,SAAS,KAC/C,KAAK,YAAY,MAAM,KAAK,aAAa,YAAY;AAAA,EAEzD;AAAA,EAEQ,WAAW,MAAqB;AACtC,UAAM,UAAU,KAAK,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,KAAK;AAGpD,QAAI,WAAW,KAAK,gBAAgB,IAAI,OAAO,EAAG,QAAO;AAGzD,QAAI,KAAK,WAAW,OAAO,KAAK,QAAS,QAAO;AAChD,QAAI,KAAK,WAAW,OAAO,KAAK,QAAS,QAAO;AAEhD,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,MAAoB;AACxC,WAAO,KAAK,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,KAAK;AAAA,EAC7C;AAAA,EAEQ,kBAAwB;AAC9B,UAAM,UAAU,IAAI,KAAK,KAAK,QAAQ;AACtC,YAAQ,SAAS,QAAQ,SAAS,IAAI,CAAC;AACvC,SAAK,WAAW;AAEhB,cAAU,MAAM,gBAAgB;AAAA,MAC9B,QAAQ;AAAA,QACN,OAAO,QAAQ,SAAS,IAAI;AAAA,QAC5B,MAAM,QAAQ,YAAY;AAAA,MAC5B;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,kBAAwB;AAC9B,UAAM,UAAU,IAAI,KAAK,KAAK,QAAQ;AACtC,YAAQ,SAAS,QAAQ,SAAS,IAAI,CAAC;AACvC,SAAK,WAAW;AAEhB,cAAU,MAAM,gBAAgB;AAAA,MAC9B,QAAQ;AAAA,QACN,OAAO,QAAQ,SAAS,IAAI;AAAA,QAC5B,MAAM,QAAQ,YAAY;AAAA,MAC5B;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,iBAAiB,MAAkB;AACzC,QAAI,KAAK,WAAW,IAAI,EAAG;AAE3B,SAAK,QAAQ,KAAK,cAAc,IAAI;AAEpC,cAAU,MAAM,UAAU;AAAA,MACxB,QAAQ;AAAA,QACN,OAAO,KAAK;AAAA,QACZ,MAAM,KAAK,YAAY;AAAA,MACzB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,cAAc,OAAsB,MAAkB;AAC5D,QAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,YAAM,eAAe;AACrB,WAAK,iBAAiB,IAAI;AAAA,IAC5B;AAAA,EACF;AAAA,EAES,SAAyB;AAChC,UAAM,UAAU;AAAA,MACd,eAAe;AAAA,IACjB;AAEA,WAAOA;AAAA;AAAA,gBAEKC,UAAS,OAAO,CAAC;AAAA;AAAA;AAAA,oBAGb,KAAK,SAAS,YAAY,KAAK,OAAOC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAO5C,KAAK,eAAe;AAAA;AAAA,cAE3B,eAAe;AAAA;AAAA;AAAA,cAGf,KAAK,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAMZ,KAAK,eAAe;AAAA;AAAA,cAE3B,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,YAKlB,KAAK,aAAa;AAAA,MAClB,CAAC,QAAQF;AAAA,sEACiD,GAAG;AAAA;AAAA,IAE/D,CAAC;AAAA;AAAA;AAAA;AAAA,YAIC,KAAK,aAAa,IAAI,CAAC,EAAE,MAAM,UAAU,MAAM;AAC/C,YAAM,WAAW,KAAK,WAAW,IAAI;AACrC,YAAM,WAAW,KAAK,WAAW,IAAI;AACrC,YAAM,QAAQ,KAAK,QAAQ,IAAI;AAE/B,aAAOA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAKQ,WAAW,IAAI,EAAE;AAAA,gCACZ,WAAW,SAAS,OAAO;AAAA,gCAC3B,WAAW,SAASE,SAAO;AAAA,gCAC3B,SAAS;AAAA,iCACR,QAAQ;AAAA,8BACX,KAAK;AAAA,iCACF,QAAQ;AAAA,yBAChB,MAAM,KAAK,iBAAiB,IAAI,CAAC;AAAA,2BAC/B,CAAC,MAAqB,KAAK,cAAc,GAAG,IAAI,CAAC;AAAA;AAAA,kBAE1D,KAAK,QAAQ,CAAC;AAAA;AAAA;AAAA,IAGtB,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA,EAIV;AACF;AAzQE;AAAA,EADCC,WAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GANf,WAOX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAZf,WAaX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAlBf,WAmBX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,QAAQ,WAAW,iBAAiB,CAAC;AAAA,GAxB5C,WAyBX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA9Bf,WA+BX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GApC9B,WAqCX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,QAAQ,WAAW,oBAAoB,CAAC;AAAA,GA1C/C,WA2CX;AAGQ;AAAA,EADPC,OAAM;AAAA,GA7CI,WA8CH;AAqOV,OAAO,eAAe,UAAU;;;ACpThC,SAA8B,QAAAC,QAAM,WAAAC,iBAAe;AACnD,SAAS,YAAAC,YAAU,SAAAC,cAAa;AAChC,SAAS,YAAAC,iBAAgB;AAmBlB,IAAM,SAAN,cAAqB,UAAU;AAAA,EAA/B;AAAA;AAOL,yBAAmC;AAMnC,gBAAiB;AAMjB,iBAAQ;AAMR,iBAAQ;AAOR,mBAAU;AAMV,uBAAc;AAOd,wBAAuC,oBAAI,IAAI;AAG/C,SAAQ,gBAA6B,oBAAI,IAAI;AAAA;AAAA,EA/C7C;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAoD1B,cAAc,QAAyB;AACrC,QAAI,KAAK,wBAAwB,KAAK;AACpC,aAAO,KAAK,aAAa,IAAI,MAAM;AAAA,IACrC;AACA,WAAO,KAAK,aAAa,SAAS,MAAM;AAAA,EAC1C;AAAA,EAEA,iBAAiB,QAAsB;AAErC,QAAI,KAAK,QAAS;AAClB,QAAI,KAAK,kBAAkB,OAAQ;AAEnC,QAAI,KAAK,kBAAkB,UAAU;AACnC,WAAK,cAAc,MAAM;AACzB,WAAK,cAAc,IAAI,MAAM;AAAA,IAC/B,OAAO;AACL,UAAI,KAAK,cAAc,IAAI,MAAM,GAAG;AAClC,aAAK,cAAc,OAAO,MAAM;AAAA,MAClC,OAAO;AACL,aAAK,cAAc,IAAI,MAAM;AAAA,MAC/B;AAAA,IACF;AAEA,cAAU,MAAM,oBAAoB;AAAA,MAClC,QAAQ,EAAE,eAAe,MAAM,KAAK,KAAK,aAAa,EAAE;AAAA,IAC1D,CAAC;AAED,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,eAAe,QAAyB;AACtC,WAAO,KAAK,cAAc,IAAI,MAAM;AAAA,EACtC;AAAA,EAES,SAAyB;AAChC,UAAM,UAAU;AAAA,MACd,WAAW;AAAA,IACb;AAEA,WAAOC;AAAA;AAAA,gBAEKC,UAAS,OAAO,CAAC;AAAA;AAAA,qBAEZ,KAAK,KAAK;AAAA,+BACA,KAAK,kBAAkB,aAAa,SAASC,SAAO;AAAA,oBAC/D,KAAK,UAAU,SAASA,SAAO;AAAA,oBAC/B,KAAK,SAAS,YAAY,KAAK,OAAOA,SAAO;AAAA,sBAC3C,KAAK,KAAK;AAAA,wBACR,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKlC;AACF;AApGE;AAAA,EADCC,WAAS,EAAE,MAAM,QAAQ,WAAW,kBAAkB,SAAS,KAAK,CAAC;AAAA,GAN3D,OAOX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAZ9B,OAaX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAlB/B,OAmBX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAxBf,OAyBX;AAOA;AAAA,EADCA,WAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GA/B/B,OAgCX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,QAAQ,WAAW,eAAe,CAAC;AAAA,GArC1C,OAsCX;AAOA;AAAA,EADCA,WAAS,EAAE,WAAW,MAAM,CAAC;AAAA,GA5CnB,OA6CX;AAGQ;AAAA,EADPC,OAAM;AAAA,GA/CI,OAgDH;AA8DV,OAAO,WAAW,MAAM;;;ACnIxB,SAA8B,QAAAC,QAAM,WAAAC,iBAAe;AACnD,SAAS,YAAAC,YAAU,SAAAC,cAAa;AAChC,SAAS,YAAAC,iBAAgB;;;AC0BlB,SAAS,0BAA0B,SAAwC;AAEhF,MAAI,QAAQ;AACZ,MAAI,SAA6B,QAAQ;AAEzC,SAAO,QAAQ;AAEb,QAAI,OAAO,SAAS,YAAY,MAAM,gBAAgB;AACpD;AAAA,IACF;AAEA,QAAI,OAAO,SAAS,YAAY,MAAM,WAAW;AAC/C;AAAA,IACF;AACA,aAAS,OAAO;AAAA,EAClB;AAGA,QAAM,WAAW,oBAAoB,OAAO;AAC5C,QAAM,UAAU,SAAS;AACzB,QAAM,WAAW,SAAS,QAAQ,OAAO,IAAI;AAE7C,SAAO,EAAE,OAAO,SAAS,SAAS;AACpC;AAQA,SAAS,oBAAoB,SAAqC;AAEhE,MAAI,YAAgC,QAAQ;AAG5C,MAAI,WAAW,SAAS,YAAY,MAAM,QAAQ;AAChD,gBAAY,UAAU;AAAA,EACxB;AAIA,MAAI,WAAW,aAAa,MAAM,MAAM,SAAS;AAC/C,gBAAY,UAAU;AAAA,EACxB;AAEA,MAAI,CAAC,WAAW;AACd,WAAO,CAAC,OAAO;AAAA,EACjB;AAKA,QAAM,QAAuB,CAAC;AAG9B,QAAM,gBAAgB,CAAC,WAAwB;AAC7C,eAAW,SAAS,OAAO,UAAU;AACnC,UAAI,MAAM,SAAS,YAAY,MAAM,gBAAgB;AACnD,cAAM,KAAK,KAAoB;AAAA,MACjC,WAAW,MAAM,SAAS,YAAY,MAAM,QAAQ;AAElD,cAAM,OAAO;AACb,mBAAW,YAAY,KAAK,iBAAiB,GAAG;AAC9C,cAAI,SAAS,SAAS,YAAY,MAAM,gBAAgB;AACtD,kBAAM,KAAK,QAAuB;AAAA,UACpC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,UAAU,SAAS,YAAY,MAAM,WAAW;AAClD,kBAAc,SAAS;AAAA,EACzB,WAAW,UAAU,SAAS,YAAY,MAAM,gBAAgB;AAE9D,UAAM,eAAe,UAAU,cAAc,mBAAmB;AAChE,QAAI,cAAc;AAChB,iBAAW,SAAS,aAAa,UAAU;AACzC,YAAI,MAAM,SAAS,YAAY,MAAM,gBAAgB;AACnD,gBAAM,KAAK,KAAoB;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO,MAAM,SAAS,IAAI,QAAQ,CAAC,OAAO;AAC5C;;;AD3GA,IAAMC,eAAcC;AAAA;AAAA;AAAA;AAAA;AAmBb,IAAM,aAAN,cAAyB,UAAU;AAAA,EAAnC;AAAA;AAOL,kBAAS;AAMT,oBAAW;AAMX,oBAAW;AAMX,oBAAW;AAOX,mBAAU;AAGV,SAAQ,cAAc;AAGtB,SAAQ,SAAS;AAGjB,SAAQ,WAAW;AAGnB,SAAQ,YAAY;AAAA;AAAA,EA3CpB;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EA6C1B,IAAY,WAA0B;AACpC,WAAO,KAAK,QAAQ,SAAS;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAY,YAAqB;AAC/B,QAAI,KAAK,QAAS,QAAO;AACzB,UAAM,OAAO,KAAK;AAClB,QAAI,QAAQ,KAAK,QAAQ;AACvB,aAAO,KAAK,cAAc,KAAK,MAAM;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAY,gBAAyB;AACnC,WAAO,KAAK,UAAU,WAAW;AAAA,EACnC;AAAA,EAES,oBAA0B;AACjC,UAAM,kBAAkB;AACxB,SAAK,kBAAkB;AAEvB,0BAAsB,MAAM;AAC1B,WAAK,mBAAmB;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,qBAA2B;AACjC,UAAM,WAAW,0BAA0B,IAA8B;AACzE,SAAK,SAAS,SAAS;AACvB,SAAK,WAAW,SAAS;AACzB,SAAK,YAAY,SAAS;AAAA,EAC5B;AAAA,EAEQ,oBAA0B;AAChC,UAAM,eAAe,KAAK,cAAc,iBAAiB;AACzD,SAAK,cAAc,iBAAiB,QAAQ,aAAa,cAAc,cAAc,MAAM;AAAA,EAC7F;AAAA,EAEQ,kBAAkB,OAAoB;AAC5C,UAAM,gBAAgB;AACtB,QAAI,KAAK,YAAY,KAAK,iBAAiB,KAAK,aAAa,CAAC,KAAK,YAAa;AAEhF,SAAK,WAAW,CAAC,KAAK;AACtB,cAAU,MAAM,UAAU;AAAA,MACxB,QAAQ;AAAA,QACN,QAAQ,KAAK;AAAA,QACb,UAAU,KAAK;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,qBAA2B;AACjC,QAAI,KAAK,YAAY,KAAK,cAAe;AAEzC,UAAM,OAAO,KAAK;AAClB,QAAI,MAAM;AACR,WAAK,iBAAiB,KAAK,MAAM;AACjC,WAAK,WAAW,KAAK,eAAe,KAAK,MAAM;AAAA,IACjD;AAEA,cAAU,MAAM,UAAU;AAAA,MACxB,QAAQ;AAAA,QACN,QAAQ,KAAK;AAAA,QACb,UAAU,KAAK;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,cAAc,OAA4B;AAChD,QAAI,KAAK,YAAY,KAAK,cAAe;AAEzC,YAAQ,MAAM,KAAK;AAAA,MACjB,KAAK;AACH,YAAI,KAAK,eAAe,CAAC,KAAK,UAAU;AACtC,gBAAM,eAAe;AACrB,eAAK,WAAW;AAChB,oBAAU,MAAM,UAAU;AAAA,YACxB,QAAQ;AAAA,cACN,QAAQ,KAAK;AAAA,cACb,UAAU;AAAA,YACZ;AAAA,UACF,CAAC;AAAA,QACH;AACA;AAAA,MAEF,KAAK;AACH,YAAI,KAAK,eAAe,KAAK,UAAU;AACrC,gBAAM,eAAe;AACrB,eAAK,WAAW;AAChB,oBAAU,MAAM,UAAU;AAAA,YACxB,QAAQ;AAAA,cACN,QAAQ,KAAK;AAAA,cACb,UAAU;AAAA,YACZ;AAAA,UACF,CAAC;AAAA,QACH;AACA;AAAA,MAEF,KAAK;AACH,cAAM,eAAe;AACrB,kBAAU,MAAM,YAAY,EAAE,QAAQ,EAAE,QAAQ,KAAK,OAAO,EAAE,CAAC;AAC/D;AAAA,MAEF,KAAK;AACH,cAAM,eAAe;AACrB,aAAK,mBAAmB;AACxB;AAAA,IACJ;AAAA,EACF;AAAA,EAES,SAAyB;AAChC,UAAM,UAAU;AAAA,MACd,gBAAgB;AAAA,IAClB;AAGA,SAAK,kBAAkB;AAEvB,UAAM,cAAc,KAAK;AAEzB,WAAOA;AAAA;AAAA,gBAEKC,UAAS,OAAO,CAAC;AAAA;AAAA,wBAET,KAAK,cAAe,KAAK,WAAW,SAAS,UAAWC,SAAO;AAAA,wBAC/D,KAAK,WAAW,SAAS,OAAO;AAAA,oBACpC,cAAc,SAASA,SAAO;AAAA,qBAC7B,KAAK,MAAM;AAAA,uBACT,KAAK,QAAQ;AAAA,wBACZ,KAAK,SAAS;AAAA,yBACb,KAAK,QAAQ;AAAA,yBACb,KAAK,QAAQ;AAAA,yBACb,KAAK,QAAQ;AAAA,wBACd,WAAW;AAAA;AAAA;AAAA;AAAA,qBAId,KAAK,WAAW,KAAK,CAAC;AAAA,mBACxB,KAAK,kBAAkB;AAAA,qBACrB,KAAK,aAAa;AAAA;AAAA,YAG3B,KAAK,cACDF;AAAA;AAAA;AAAA;AAAA,+BAIe,KAAK,WAAW,aAAa,QAAQ;AAAA;AAAA,2BAEzC,KAAK,iBAAiB;AAAA;AAAA,oBAE7BD,YAAW;AAAA;AAAA,kBAGfC,kDACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOA,KAAK,cACDA;AAAA;AAAA;AAAA;AAAA,0BAIY,CAAC,KAAK,QAAQ;AAAA;AAAA,oDAEY,KAAK,iBAAiB;AAAA;AAAA,gBAG5DE,SACN;AAAA;AAAA;AAAA,EAGN;AACF;AAlOE;AAAA,EADCC,WAAS,EAAE,MAAM,QAAQ,WAAW,UAAU,CAAC;AAAA,GANrC,WAOX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAZ/B,WAaX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAlB/B,WAmBX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAxB/B,WAyBX;AAOA;AAAA,EADCA,WAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GA/B/B,WAgCX;AAGQ;AAAA,EADPC,OAAM;AAAA,GAlCI,WAmCH;AAGA;AAAA,EADPA,OAAM;AAAA,GArCI,WAsCH;AAGA;AAAA,EADPA,OAAM;AAAA,GAxCI,WAyCH;AAGA;AAAA,EADPA,OAAM;AAAA,GA3CI,WA4CH;AAgMV,OAAO,gBAAgB,UAAU;;;AEzQjC,SAA8B,QAAAC,QAAM,WAAAC,iBAAe;AACnD,SAAS,YAAAC,YAAU,SAAAC,cAAa;AAChC,SAAS,YAAAC,kBAAgB;AAoBlB,IAAM,SAAN,cAAqB,UAAU;AAAA,EAA/B;AAAA;AAOL,yBAAmC;AAMnC,uBAA+B;AAM/B,gBAAiB;AAMjB,oBAAW;AAMX,iBAAQ;AAGR,SAAQ,gBAA6B,oBAAI,IAAI;AAAA;AAAA,EAjC7C;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EAmC1B,iBAAiB,QAAsB;AACrC,QAAI,KAAK,kBAAkB,OAAQ;AAEnC,QAAI,KAAK,kBAAkB,UAAU;AACnC,WAAK,cAAc,MAAM;AACzB,WAAK,cAAc,IAAI,MAAM;AAAA,IAC/B,OAAO;AACL,UAAI,KAAK,cAAc,IAAI,MAAM,GAAG;AAClC,aAAK,cAAc,OAAO,MAAM;AAAA,MAClC,OAAO;AACL,aAAK,cAAc,IAAI,MAAM;AAAA,MAC/B;AAAA,IACF;AAEA,cAAU,MAAM,oBAAoB;AAAA,MAClC,QAAQ,EAAE,eAAe,MAAM,KAAK,KAAK,aAAa,EAAE;AAAA,IAC1D,CAAC;AAED,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,eAAe,QAAyB;AACtC,WAAO,KAAK,cAAc,IAAI,MAAM;AAAA,EACtC;AAAA,EAES,SAAyB;AAChC,UAAM,UAAU;AAAA,MACd,WAAW;AAAA,IACb;AAEA,WAAOC;AAAA;AAAA,gBAEKC,WAAS,OAAO,CAAC;AAAA;AAAA,qBAEZ,KAAK,KAAK;AAAA,+BACA,KAAK,kBAAkB,aAAa,SAASC,SAAO;AAAA,2BACxD,KAAK,WAAW;AAAA,oBACvB,KAAK,SAAS,YAAY,KAAK,OAAOA,SAAO;AAAA,2BACtC,KAAK,gBAAgB,aAAa,KAAK,cAAcA,SAAO;AAAA,yBAC9D,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpC;AACF;AA1EE;AAAA,EADCC,WAAS,EAAE,MAAM,QAAQ,WAAW,kBAAkB,SAAS,KAAK,CAAC;AAAA,GAN3D,OAOX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAZ9B,OAaX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAlB9B,OAmBX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAxB/B,OAyBX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA9Bf,OA+BX;AAGQ;AAAA,EADPC,OAAM;AAAA,GAjCI,OAkCH;AAkDV,OAAO,WAAW,MAAM;;;AC1GxB,SAA8B,QAAAC,QAAM,WAAAC,iBAAe;AACnD,SAAS,YAAAC,kBAAgB;AACzB,SAAS,YAAAC,kBAAgB;AAmBlB,IAAM,aAAN,cAAyB,UAAU;AAAA,EAAnC;AAAA;AAOL,kBAAS;AAMT,oBAAW;AAMX,oBAAW;AAMX,iBAAQ;AAAA;AAAA,EAxBR;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EA0B1B,IAAY,WAA0B;AACpC,WAAO,KAAK,QAAQ,SAAS;AAAA,EAC/B;AAAA,EAEQ,cAAoB;AAC1B,QAAI,KAAK,SAAU;AAEnB,UAAM,OAAO,KAAK;AAClB,QAAI,MAAM;AACR,WAAK,iBAAiB,KAAK,UAAU,KAAK,KAAK;AAC/C,WAAK,WAAW,KAAK,eAAe,KAAK,UAAU,KAAK,KAAK;AAAA,IAC/D;AAEA,cAAU,MAAM,UAAU;AAAA,MACxB,QAAQ;AAAA,QACN,QAAQ,KAAK;AAAA,QACb,OAAO,KAAK;AAAA,QACZ,UAAU,KAAK;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,cAAc,OAA4B;AAChD,QAAI,KAAK,SAAU;AAEnB,QAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,YAAM,eAAe;AACrB,WAAK,YAAY;AAEjB,UAAI,MAAM,QAAQ,SAAS;AACzB,kBAAU,MAAM,YAAY;AAAA,UAC1B,QAAQ;AAAA,YACN,QAAQ,KAAK;AAAA,YACb,OAAO,KAAK;AAAA,UACd;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAES,SAAyB;AAChC,UAAM,UAAU;AAAA,MACd,gBAAgB;AAAA,IAClB;AAEA,WAAOC;AAAA;AAAA,gBAEKC,WAAS,OAAO,CAAC;AAAA;AAAA,mBAEd,KAAK,WAAW,KAAK,CAAC;AAAA,wBACjB,KAAK,WAAW,SAAS,OAAO;AAAA,yBAC/B,KAAK,QAAQ;AAAA,yBACb,KAAK,QAAQ;AAAA,wBACd,KAAK,WAAW,SAASC,SAAO;AAAA,iBACvC,KAAK,WAAW;AAAA,mBACd,KAAK,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYnC;AACF;AAxFE;AAAA,EADCC,WAAS,EAAE,MAAM,QAAQ,WAAW,UAAU,CAAC;AAAA,GANrC,WAOX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAZ/B,WAaX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAlB/B,WAmBX;AAMA;AAAA,EADCA,WAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAxBf,WAyBX;AAyEF,OAAO,gBAAgB,UAAU;;;AC7FjC,SAAS,QAAAC,cAAY;AAId,IAAM,SAAN,cAAqB,UAAU;AAAA,EAC3B,SAAS;AAChB,WAAOC;AAAA,EACT;AACF;AAEA,OAAO,WAAW,MAAM;;;AC5BxB,SAAS,QAAAC,cAAY;AAId,IAAM,eAAN,cAA2B,UAAU;AAAA,EACjC,SAAS;AAChB,WAAOC;AAAA,EACT;AACF;AAEA,OAAO,kBAAkB,YAAY;;;ACVrC,SAAS,QAAAC,cAAY;AAId,IAAM,gBAAN,cAA4B,UAAU;AAAA,EAClC,SAAS;AAChB,WAAOC;AAAA,EACT;AACF;AAEA,OAAO,mBAAmB,aAAa;;;ACVvC,SAAS,QAAAC,cAAY;AAId,IAAM,eAAN,cAA2B,UAAU;AAAA,EACjC,SAAS;AAChB,WAAOC;AAAA,EACT;AACF;AAEA,OAAO,kBAAkB,YAAY;;;ACLrC,SAAS,QAAAC,cAAY;AACrB,SAAS,YAAAC,kBAAgB;AAMlB,IAAM,cAAN,cAA0B,UAAU;AAAA,EAApC;AAAA;AAGL,uBAAoC;AAIpC,sBAAa;AAAA;AAAA,EAEJ,oBAA0B;AACjC,UAAM,kBAAkB;AACxB,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAES,UAAgB;AACvB,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEQ,sBAA4B;AAClC,QAAI,KAAK,YAAY;AACnB,WAAK,aAAa,QAAQ,MAAM;AAChC,WAAK,gBAAgB,kBAAkB;AAAA,IACzC,OAAO;AACL,WAAK,aAAa,QAAQ,WAAW;AACrC,WAAK,aAAa,oBAAoB,KAAK,WAAW;AAAA,IACxD;AAAA,EACF;AAAA,EAES,SAAS;AAChB,WAAOC;AAAA,EACT;AACF;AA5BE;AAAA,EADCC,WAAS,EAAE,SAAS,KAAK,CAAC;AAAA,GAFhB,YAGX;AAIA;AAAA,EADCA,WAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAN/B,YAOX;AA0BF,OAAO,gBAAgB,WAAW;;;ACnClC,SAAS,QAAAC,cAAY;AACrB,SAAS,YAAAC,kBAAgB;AAIlB,IAAM,gBAAN,cAA4B,UAAU;AAAA,EAAtC;AAAA;AAML,iBAAQ;AAAA;AAAA,EAEC,UAAgB;AACvB,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAES,oBAA0B;AACjC,UAAM,kBAAkB;AACxB,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEQ,oBAA0B;AAChC,UAAM,aAAa,KAAK,WAAW,KAAK,KAAK;AAC7C,SAAK,MAAM,YAAY,qBAAqB,OAAO,UAAU,CAAC;AAAA,EAChE;AAAA,EAEQ,WAAW,OAAuB;AAExC,QAAI,MAAM,SAAS,GAAG,GAAG;AACvB,YAAM,QAAQ,MAAM,MAAM,GAAG,EAAE,IAAI,MAAM;AACzC,YAAM,QAAQ,MAAM,CAAC;AACrB,YAAM,SAAS,MAAM,CAAC;AACtB,UACE,UAAU,UACV,WAAW,UACX,CAAC,OAAO,MAAM,KAAK,KACnB,CAAC,OAAO,MAAM,MAAM,KACpB,WAAW,GACX;AACA,eAAO,QAAQ;AAAA,MACjB;AAAA,IACF;AAEA,UAAM,SAAS,OAAO,WAAW,KAAK;AACtC,WAAO,OAAO,MAAM,MAAM,IAAI,IAAI;AAAA,EACpC;AAAA,EAES,SAAS;AAChB,WAAOC;AAAA,EACT;AACF;AAxCE;AAAA,EADCC,WAAS,EAAE,SAAS,KAAK,CAAC;AAAA,GALhB,cAMX;AA0CF,OAAO,mBAAmB,aAAa;","names":["html","html","html","html","html","nothing","property","html","nothing","property","html","nothing","property","html","nothing","property","html","nothing","property","html","nothing","property","html","nothing","property","classMap","html","nothing","classMap","property","html","nothing","property","state","classMap","html","classMap","nothing","property","state","html","nothing","property","state","classMap","html","classMap","nothing","property","state","html","nothing","property","classMap","html","classMap","nothing","property","html","nothing","property","classMap","html","classMap","nothing","property","html","nothing","property","state","classMap","html","classMap","nothing","property","state","html","nothing","property","state","classMap","html","classMap","nothing","property","state","html","nothing","property","state","classMap","chevronIcon","html","classMap","nothing","property","state","html","nothing","property","state","classMap","html","classMap","nothing","property","state","html","nothing","property","classMap","html","classMap","nothing","property","html","html","html","html","html","html","html","html","html","property","html","property","html","property","html","property"]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import {
|
|
2
|
+
StandardEvents,
|
|
3
|
+
emitEvent
|
|
4
|
+
} from "./chunk-YDQ434UH.js";
|
|
5
|
+
import {
|
|
6
|
+
DSElement,
|
|
7
|
+
__decorateClass,
|
|
8
|
+
define
|
|
9
|
+
} from "./chunk-H4GJJZ3N.js";
|
|
10
|
+
|
|
11
|
+
// src/components/link/link.ts
|
|
12
|
+
import { html, nothing } from "lit";
|
|
13
|
+
import { property } from "lit/decorators.js";
|
|
14
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
15
|
+
var DsLink = class extends DSElement {
|
|
16
|
+
constructor() {
|
|
17
|
+
super(...arguments);
|
|
18
|
+
this.href = "";
|
|
19
|
+
this.external = false;
|
|
20
|
+
this.variant = "default";
|
|
21
|
+
}
|
|
22
|
+
static {
|
|
23
|
+
this.styles = [];
|
|
24
|
+
}
|
|
25
|
+
handleClick(event) {
|
|
26
|
+
const navigateEvent = emitEvent(this, StandardEvents.NAVIGATE, {
|
|
27
|
+
detail: {
|
|
28
|
+
href: this.href,
|
|
29
|
+
external: this.external,
|
|
30
|
+
originalEvent: event
|
|
31
|
+
},
|
|
32
|
+
cancelable: true
|
|
33
|
+
});
|
|
34
|
+
if (navigateEvent.defaultPrevented) {
|
|
35
|
+
event.preventDefault();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
render() {
|
|
39
|
+
const classes = {
|
|
40
|
+
"ds-link": true,
|
|
41
|
+
[`ds-link--${this.variant}`]: true,
|
|
42
|
+
"ds-link--external": this.external
|
|
43
|
+
};
|
|
44
|
+
if (!this.href) {
|
|
45
|
+
return html`
|
|
46
|
+
<span class=${classMap(classes)}>
|
|
47
|
+
<span class="ds-link__content"><slot></slot></span>
|
|
48
|
+
</span>
|
|
49
|
+
`;
|
|
50
|
+
}
|
|
51
|
+
return html`
|
|
52
|
+
<a
|
|
53
|
+
class=${classMap(classes)}
|
|
54
|
+
href=${this.href}
|
|
55
|
+
target=${this.external ? "_blank" : nothing}
|
|
56
|
+
rel=${this.external ? "noopener noreferrer" : nothing}
|
|
57
|
+
@click=${this.handleClick}
|
|
58
|
+
>
|
|
59
|
+
<span class="ds-link__content"><slot></slot></span>
|
|
60
|
+
${this.external ? this.renderExternalIndicator() : nothing}
|
|
61
|
+
</a>
|
|
62
|
+
`;
|
|
63
|
+
}
|
|
64
|
+
renderExternalIndicator() {
|
|
65
|
+
return html`
|
|
66
|
+
<span class="ds-link__external-icon" aria-hidden="true">
|
|
67
|
+
<svg
|
|
68
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
69
|
+
viewBox="0 0 24 24"
|
|
70
|
+
fill="none"
|
|
71
|
+
stroke="currentColor"
|
|
72
|
+
stroke-width="2"
|
|
73
|
+
stroke-linecap="round"
|
|
74
|
+
stroke-linejoin="round"
|
|
75
|
+
>
|
|
76
|
+
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
|
|
77
|
+
<polyline points="15 3 21 3 21 9" />
|
|
78
|
+
<line x1="10" y1="14" x2="21" y2="3" />
|
|
79
|
+
</svg>
|
|
80
|
+
</span>
|
|
81
|
+
<span class="ds-visually-hidden">(opens in new tab)</span>
|
|
82
|
+
`;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
__decorateClass([
|
|
86
|
+
property({ type: String, reflect: true })
|
|
87
|
+
], DsLink.prototype, "href", 2);
|
|
88
|
+
__decorateClass([
|
|
89
|
+
property({ type: Boolean, reflect: true })
|
|
90
|
+
], DsLink.prototype, "external", 2);
|
|
91
|
+
__decorateClass([
|
|
92
|
+
property({ type: String, reflect: true })
|
|
93
|
+
], DsLink.prototype, "variant", 2);
|
|
94
|
+
define("ds-link", DsLink);
|
|
95
|
+
|
|
96
|
+
export {
|
|
97
|
+
DsLink
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=chunk-GXKZ6E6K.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/link/link.ts"],"sourcesContent":["import { type TemplateResult, html, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { DSElement } from \"../../base/ds-element.js\";\nimport { StandardEvents, emitEvent } from \"../../events/emit.js\";\nimport { define } from \"../../registry/define.js\";\n\nexport type LinkVariant = \"default\" | \"muted\" | \"underline\";\n\nexport interface DsNavigateEventDetail {\n href: string;\n external: boolean;\n originalEvent: MouseEvent | KeyboardEvent;\n}\n\n/**\n * A link component following WAI-ARIA link pattern.\n *\n * @element ds-link\n * @slot - Default slot for link content\n *\n * @fires ds:navigate - When the link is activated (cancelable)\n */\nexport class DsLink extends DSElement {\n static override styles = [];\n\n /**\n * The URL to navigate to.\n * Required for proper link functionality.\n */\n @property({ type: String, reflect: true })\n href = \"\";\n\n /**\n * Whether this link opens in a new tab.\n * When true, adds target=\"_blank\" and rel=\"noopener noreferrer\".\n */\n @property({ type: Boolean, reflect: true })\n external = false;\n\n /**\n * The link visual variant.\n */\n @property({ type: String, reflect: true })\n variant: LinkVariant = \"default\";\n\n private handleClick(event: MouseEvent): void {\n // Emit cancelable ds:navigate event\n const navigateEvent = emitEvent<DsNavigateEventDetail>(this, StandardEvents.NAVIGATE, {\n detail: {\n href: this.href,\n external: this.external,\n originalEvent: event,\n },\n cancelable: true,\n });\n\n // If consumer prevented the event, prevent navigation\n if (navigateEvent.defaultPrevented) {\n event.preventDefault();\n }\n }\n\n override render(): TemplateResult {\n const classes = {\n \"ds-link\": true,\n [`ds-link--${this.variant}`]: true,\n \"ds-link--external\": this.external,\n };\n\n // If href is empty, render as span (not a real link)\n if (!this.href) {\n return html`\n <span class=${classMap(classes)}>\n <span class=\"ds-link__content\"><slot></slot></span>\n </span>\n `;\n }\n\n return html`\n <a\n class=${classMap(classes)}\n href=${this.href}\n target=${this.external ? \"_blank\" : nothing}\n rel=${this.external ? \"noopener noreferrer\" : nothing}\n @click=${this.handleClick}\n >\n <span class=\"ds-link__content\"><slot></slot></span>\n ${this.external ? this.renderExternalIndicator() : nothing}\n </a>\n `;\n }\n\n private renderExternalIndicator(): TemplateResult {\n return html`\n <span class=\"ds-link__external-icon\" aria-hidden=\"true\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n </span>\n <span class=\"ds-visually-hidden\">(opens in new tab)</span>\n `;\n }\n}\n\n// Register the component\ndefine(\"ds-link\", DsLink);\n\n// TypeScript declaration for HTML\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ds-link\": DsLink;\n }\n}\n"],"mappings":";;;;;;;;;;;AAAA,SAA8B,MAAM,eAAe;AACnD,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AAqBlB,IAAM,SAAN,cAAqB,UAAU;AAAA,EAA/B;AAAA;AAQL,gBAAO;AAOP,oBAAW;AAMX,mBAAuB;AAAA;AAAA,EApBvB;AAAA,SAAgB,SAAS,CAAC;AAAA;AAAA,EAsBlB,YAAY,OAAyB;AAE3C,UAAM,gBAAgB,UAAiC,MAAM,eAAe,UAAU;AAAA,MACpF,QAAQ;AAAA,QACN,MAAM,KAAK;AAAA,QACX,UAAU,KAAK;AAAA,QACf,eAAe;AAAA,MACjB;AAAA,MACA,YAAY;AAAA,IACd,CAAC;AAGD,QAAI,cAAc,kBAAkB;AAClC,YAAM,eAAe;AAAA,IACvB;AAAA,EACF;AAAA,EAES,SAAyB;AAChC,UAAM,UAAU;AAAA,MACd,WAAW;AAAA,MACX,CAAC,YAAY,KAAK,OAAO,EAAE,GAAG;AAAA,MAC9B,qBAAqB,KAAK;AAAA,IAC5B;AAGA,QAAI,CAAC,KAAK,MAAM;AACd,aAAO;AAAA,sBACS,SAAS,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA,IAInC;AAEA,WAAO;AAAA;AAAA,gBAEK,SAAS,OAAO,CAAC;AAAA,eAClB,KAAK,IAAI;AAAA,iBACP,KAAK,WAAW,WAAW,OAAO;AAAA,cACrC,KAAK,WAAW,wBAAwB,OAAO;AAAA,iBAC5C,KAAK,WAAW;AAAA;AAAA;AAAA,UAGvB,KAAK,WAAW,KAAK,wBAAwB,IAAI,OAAO;AAAA;AAAA;AAAA,EAGhE;AAAA,EAEQ,0BAA0C;AAChD,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBT;AACF;AAlFE;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAP9B,OAQX;AAOA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAd/B,OAeX;AAMA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GApB9B,OAqBX;AAwEF,OAAO,WAAW,MAAM;","names":[]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// src/base/ds-element.ts
|
|
13
|
+
import { LitElement } from "lit";
|
|
14
|
+
var DSElement = class extends LitElement {
|
|
15
|
+
/**
|
|
16
|
+
* Override createRenderRoot to use Light DOM.
|
|
17
|
+
* This renders content directly into the host element instead of Shadow DOM.
|
|
18
|
+
*
|
|
19
|
+
* @returns The host element itself for Light DOM rendering
|
|
20
|
+
*/
|
|
21
|
+
createRenderRoot() {
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// src/registry/define.ts
|
|
27
|
+
function define(tagName, elementClass) {
|
|
28
|
+
if (typeof customElements === "undefined") return;
|
|
29
|
+
if (!customElements.get(tagName)) {
|
|
30
|
+
customElements.define(tagName, elementClass);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function isDefined(tagName) {
|
|
34
|
+
if (typeof customElements === "undefined") return false;
|
|
35
|
+
return customElements.get(tagName) !== void 0;
|
|
36
|
+
}
|
|
37
|
+
function whenDefined(tagName) {
|
|
38
|
+
if (typeof customElements === "undefined") {
|
|
39
|
+
return Promise.reject(new Error("customElements is not available"));
|
|
40
|
+
}
|
|
41
|
+
return customElements.whenDefined(tagName);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export {
|
|
45
|
+
__decorateClass,
|
|
46
|
+
DSElement,
|
|
47
|
+
define,
|
|
48
|
+
isDefined,
|
|
49
|
+
whenDefined
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=chunk-H4GJJZ3N.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/base/ds-element.ts","../src/registry/define.ts"],"sourcesContent":["import { LitElement } from \"lit\";\n\n/**\n * DSElement - Base class for design system Web Components.\n *\n * All design system components should extend this class to ensure\n * consistent Light DOM rendering behavior.\n *\n * Light DOM rendering enables:\n * - Direct CSS styling from @hypoth-ui/css and consumer stylesheets\n * - Form integration (autocomplete, form association)\n * - Standard DOM API access (querySelector from any scope)\n * - Natural event bubbling without shadow boundary issues\n *\n * @example\n * ```typescript\n * import { html } from 'lit';\n * import { property } from 'lit/decorators.js';\n * import { DSElement } from '@hypoth-ui/wc';\n *\n * export class DsCard extends DSElement {\n * @property({ reflect: true })\n * variant: 'default' | 'elevated' = 'default';\n *\n * render() {\n * return html`<div class=\"ds-card ds-card--${this.variant}\">\n * <slot></slot>\n * </div>`;\n * }\n * }\n * ```\n */\nexport class DSElement extends LitElement {\n /**\n * Override createRenderRoot to use Light DOM.\n * This renders content directly into the host element instead of Shadow DOM.\n *\n * @returns The host element itself for Light DOM rendering\n */\n protected override createRenderRoot(): HTMLElement {\n return this;\n }\n}\n\n// Re-export with legacy name for backwards compatibility\nexport { DSElement as LightElement };\n","/**\n * Safe custom element registration utility.\n * Prevents duplicate registration errors.\n */\n\ntype CustomElementConstructor = new (...args: unknown[]) => HTMLElement;\n\n/**\n * Register a custom element if not already defined.\n * @param tagName - The custom element tag name (e.g., 'ds-button')\n * @param elementClass - The custom element class\n */\nexport function define(tagName: string, elementClass: CustomElementConstructor): void {\n if (typeof customElements === \"undefined\") return;\n\n if (!customElements.get(tagName)) {\n customElements.define(tagName, elementClass);\n }\n}\n\n/**\n * Check if a custom element is already registered.\n */\nexport function isDefined(tagName: string): boolean {\n if (typeof customElements === \"undefined\") return false;\n return customElements.get(tagName) !== undefined;\n}\n\n/**\n * Wait for a custom element to be defined.\n */\nexport function whenDefined(tagName: string): Promise<CustomElementConstructor> {\n if (typeof customElements === \"undefined\") {\n return Promise.reject(new Error(\"customElements is not available\"));\n }\n return customElements.whenDefined(tagName);\n}\n"],"mappings":";;;;;;;;;;;;AAAA,SAAS,kBAAkB;AAgCpB,IAAM,YAAN,cAAwB,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOrB,mBAAgC;AACjD,WAAO;AAAA,EACT;AACF;;;AC9BO,SAAS,OAAO,SAAiB,cAA8C;AACpF,MAAI,OAAO,mBAAmB,YAAa;AAE3C,MAAI,CAAC,eAAe,IAAI,OAAO,GAAG;AAChC,mBAAe,OAAO,SAAS,YAAY;AAAA,EAC7C;AACF;AAKO,SAAS,UAAU,SAA0B;AAClD,MAAI,OAAO,mBAAmB,YAAa,QAAO;AAClD,SAAO,eAAe,IAAI,OAAO,MAAM;AACzC;AAKO,SAAS,YAAY,SAAoD;AAC9E,MAAI,OAAO,mBAAmB,aAAa;AACzC,WAAO,QAAQ,OAAO,IAAI,MAAM,iCAAiC,CAAC;AAAA,EACpE;AACA,SAAO,eAAe,YAAY,OAAO;AAC3C;","names":[]}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// src/utils/dev-warnings.ts
|
|
2
|
+
var WarningCodes = {
|
|
3
|
+
MISSING_REQUIRED_CHILD: "DS001",
|
|
4
|
+
INVALID_PROP_COMBINATION: "DS002",
|
|
5
|
+
ACCESSIBILITY_VIOLATION: "DS003",
|
|
6
|
+
DEPRECATED_USAGE: "DS004",
|
|
7
|
+
MISSING_CONTEXT: "DS005",
|
|
8
|
+
INVALID_VALUE: "DS006"
|
|
9
|
+
};
|
|
10
|
+
var isDev = typeof process !== "undefined" && process.env.NODE_ENV !== "production";
|
|
11
|
+
var emittedWarnings = /* @__PURE__ */ new Set();
|
|
12
|
+
function devWarn(warning) {
|
|
13
|
+
if (!isDev) return;
|
|
14
|
+
const prefix = `[${warning.component}]`;
|
|
15
|
+
const codeStr = WarningCodes[warning.code];
|
|
16
|
+
const key = `${warning.component}:${warning.code}:${warning.message}`;
|
|
17
|
+
if (emittedWarnings.has(key)) return;
|
|
18
|
+
emittedWarnings.add(key);
|
|
19
|
+
const suggestionText = warning.suggestion ? `
|
|
20
|
+
\u{1F4A1} ${warning.suggestion}` : "";
|
|
21
|
+
const fullMessage = `${prefix} ${warning.message} (${codeStr})${suggestionText}`;
|
|
22
|
+
console.warn(fullMessage);
|
|
23
|
+
if (warning.context) {
|
|
24
|
+
console.warn("Context:", warning.context);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
var Warnings = {
|
|
28
|
+
/**
|
|
29
|
+
* Dialog missing title element
|
|
30
|
+
*/
|
|
31
|
+
dialogMissingTitle: (component) => ({
|
|
32
|
+
code: "MISSING_REQUIRED_CHILD",
|
|
33
|
+
component,
|
|
34
|
+
message: "Missing required ds-dialog-title for accessibility.",
|
|
35
|
+
suggestion: "Add a <ds-dialog-title> element inside the dialog, or use aria-label on the dialog."
|
|
36
|
+
}),
|
|
37
|
+
/**
|
|
38
|
+
* Dialog missing description when using title
|
|
39
|
+
*/
|
|
40
|
+
dialogMissingDescription: (component) => ({
|
|
41
|
+
code: "ACCESSIBILITY_VIOLATION",
|
|
42
|
+
component,
|
|
43
|
+
message: "Dialog has title but no description for screen readers.",
|
|
44
|
+
suggestion: "Add a <ds-dialog-description> element, or use aria-describedby to reference existing content."
|
|
45
|
+
}),
|
|
46
|
+
/**
|
|
47
|
+
* Input missing accessible label
|
|
48
|
+
*/
|
|
49
|
+
inputMissingLabel: (component) => ({
|
|
50
|
+
code: "ACCESSIBILITY_VIOLATION",
|
|
51
|
+
component,
|
|
52
|
+
message: "Input is missing an accessible label.",
|
|
53
|
+
suggestion: "Add aria-label, aria-labelledby, or wrap in a <ds-field> with <ds-label>."
|
|
54
|
+
}),
|
|
55
|
+
/**
|
|
56
|
+
* Invalid variant value
|
|
57
|
+
*/
|
|
58
|
+
invalidVariant: (component, variant, validVariants) => ({
|
|
59
|
+
code: "INVALID_VALUE",
|
|
60
|
+
component,
|
|
61
|
+
message: `Invalid variant "${variant}".`,
|
|
62
|
+
suggestion: `Use one of: ${validVariants.join(", ")}.`,
|
|
63
|
+
context: { received: variant, valid: validVariants }
|
|
64
|
+
}),
|
|
65
|
+
/**
|
|
66
|
+
* Invalid size value
|
|
67
|
+
*/
|
|
68
|
+
invalidSize: (component, size, validSizes) => ({
|
|
69
|
+
code: "INVALID_VALUE",
|
|
70
|
+
component,
|
|
71
|
+
message: `Invalid size "${size}".`,
|
|
72
|
+
suggestion: `Use one of: ${validSizes.join(", ")}.`,
|
|
73
|
+
context: { received: size, valid: validSizes }
|
|
74
|
+
}),
|
|
75
|
+
/**
|
|
76
|
+
* Missing form field context
|
|
77
|
+
*/
|
|
78
|
+
missingFieldContext: (component) => ({
|
|
79
|
+
code: "MISSING_CONTEXT",
|
|
80
|
+
component,
|
|
81
|
+
message: "Form input is not wrapped in a <ds-field> context.",
|
|
82
|
+
suggestion: "Wrap your input in <ds-field> to enable automatic label association and error display."
|
|
83
|
+
}),
|
|
84
|
+
/**
|
|
85
|
+
* Missing form context
|
|
86
|
+
*/
|
|
87
|
+
missingFormContext: (component) => ({
|
|
88
|
+
code: "MISSING_CONTEXT",
|
|
89
|
+
component,
|
|
90
|
+
message: "Form control is not inside a <ds-form> context.",
|
|
91
|
+
suggestion: "Wrap your form controls in <ds-form> to enable form-level validation and submission."
|
|
92
|
+
}),
|
|
93
|
+
/**
|
|
94
|
+
* Deprecated prop usage
|
|
95
|
+
*/
|
|
96
|
+
deprecatedProp: (component, oldProp, newProp) => ({
|
|
97
|
+
code: "DEPRECATED_USAGE",
|
|
98
|
+
component,
|
|
99
|
+
message: `Prop "${oldProp}" is deprecated.`,
|
|
100
|
+
suggestion: `Use "${newProp}" instead.`,
|
|
101
|
+
context: { deprecated: oldProp, replacement: newProp }
|
|
102
|
+
}),
|
|
103
|
+
/**
|
|
104
|
+
* Conflicting props
|
|
105
|
+
*/
|
|
106
|
+
conflictingProps: (component, prop1, prop2) => ({
|
|
107
|
+
code: "INVALID_PROP_COMBINATION",
|
|
108
|
+
component,
|
|
109
|
+
message: `Props "${prop1}" and "${prop2}" should not be used together.`,
|
|
110
|
+
suggestion: "Choose one or the other based on your use case.",
|
|
111
|
+
context: { conflicting: [prop1, prop2] }
|
|
112
|
+
}),
|
|
113
|
+
/**
|
|
114
|
+
* Required children missing
|
|
115
|
+
*/
|
|
116
|
+
missingRequiredChild: (component, childType) => ({
|
|
117
|
+
code: "MISSING_REQUIRED_CHILD",
|
|
118
|
+
component,
|
|
119
|
+
message: `Missing required child element <${childType}>.`,
|
|
120
|
+
suggestion: `Add a <${childType}> element as a child of <${component}>.`
|
|
121
|
+
}),
|
|
122
|
+
/**
|
|
123
|
+
* Invalid ARIA reference
|
|
124
|
+
*/
|
|
125
|
+
invalidAriaReference: (component, attribute, targetId) => ({
|
|
126
|
+
code: "ACCESSIBILITY_VIOLATION",
|
|
127
|
+
component,
|
|
128
|
+
message: `${attribute} references "${targetId}" which does not exist in the document.`,
|
|
129
|
+
suggestion: `Ensure an element with id="${targetId}" exists, or remove the ${attribute} attribute.`,
|
|
130
|
+
context: { attribute, targetId }
|
|
131
|
+
}),
|
|
132
|
+
/**
|
|
133
|
+
* Interactive element inside interactive element
|
|
134
|
+
*/
|
|
135
|
+
nestedInteractive: (component, childType) => ({
|
|
136
|
+
code: "ACCESSIBILITY_VIOLATION",
|
|
137
|
+
component,
|
|
138
|
+
message: `Interactive element <${childType}> is nested inside another interactive element.`,
|
|
139
|
+
suggestion: "Avoid nesting interactive elements. Screen readers may not announce them correctly.",
|
|
140
|
+
context: { nestedElement: childType }
|
|
141
|
+
})
|
|
142
|
+
};
|
|
143
|
+
function validateProp(component, propName, value, validValues) {
|
|
144
|
+
if (value !== void 0 && !validValues.includes(value)) {
|
|
145
|
+
if (propName === "variant") {
|
|
146
|
+
devWarn(Warnings.invalidVariant(component, value, [...validValues]));
|
|
147
|
+
} else if (propName === "size") {
|
|
148
|
+
devWarn(Warnings.invalidSize(component, value, [...validValues]));
|
|
149
|
+
} else {
|
|
150
|
+
devWarn({
|
|
151
|
+
code: "INVALID_VALUE",
|
|
152
|
+
component,
|
|
153
|
+
message: `Invalid ${propName} "${value}".`,
|
|
154
|
+
suggestion: `Use one of: ${validValues.join(", ")}.`
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
function hasAccessibleLabel(element) {
|
|
162
|
+
return !!(element.getAttribute("aria-label") || element.getAttribute("aria-labelledby") || element.getAttribute("title") || element.labels?.length);
|
|
163
|
+
}
|
|
164
|
+
function hasRequiredChild(parent, selector) {
|
|
165
|
+
return parent.querySelector(selector) !== null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export {
|
|
169
|
+
devWarn,
|
|
170
|
+
Warnings,
|
|
171
|
+
validateProp,
|
|
172
|
+
hasAccessibleLabel,
|
|
173
|
+
hasRequiredChild
|
|
174
|
+
};
|
|
175
|
+
//# sourceMappingURL=chunk-JMPTFALJ.js.map
|