@sdcorejs/angular 20.0.5 → 20.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/index.d.ts +1 -0
- package/components/upload-file/index.d.ts +7 -4
- package/fesm2022/sdcorejs-angular-components-anchor.mjs +9 -9
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +15 -15
- package/fesm2022/sdcorejs-angular-components-avatar.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-badge.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-base.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-button.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-chart.mjs +12 -12
- package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-code-editor.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-document-builder.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-editor.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs +201 -201
- package/fesm2022/sdcorejs-angular-components-history.mjs +7 -7
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs +10 -10
- package/fesm2022/sdcorejs-angular-components-inform.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-mini-editor.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-modal.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-operator.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-org-chart.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-preview.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs +27 -27
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-quick-action.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-section.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-splitter.mjs +28 -14
- package/fesm2022/sdcorejs-angular-components-splitter.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-stepper.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs +18 -18
- package/fesm2022/sdcorejs-angular-components-tab.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-table.mjs +105 -105
- package/fesm2022/sdcorejs-angular-components-tree.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs +30 -24
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-view.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components.mjs +1 -0
- package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-directives.mjs +21 -21
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +6 -6
- package/fesm2022/sdcorejs-angular-forms-chip.mjs +6 -6
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-date.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs +9 -9
- package/fesm2022/sdcorejs-angular-forms-directives.mjs +12 -12
- package/fesm2022/sdcorejs-angular-forms-inline-text.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-input.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-label.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-radio.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-select.mjs +37 -8
- package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-switch.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms.mjs +4 -4
- package/fesm2022/sdcorejs-angular-handlers.mjs +3 -3
- package/fesm2022/sdcorejs-angular-i18n.mjs +6 -6
- package/fesm2022/sdcorejs-angular-interceptors.mjs +6 -6
- package/fesm2022/sdcorejs-angular-modules-auth.mjs +9 -9
- package/fesm2022/sdcorejs-angular-modules-authom.mjs +7 -7
- package/fesm2022/sdcorejs-angular-modules-keycloak.mjs +37 -14
- package/fesm2022/sdcorejs-angular-modules-keycloak.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-layout.mjs +73 -73
- package/fesm2022/sdcorejs-angular-modules-permission.mjs +9 -9
- package/fesm2022/sdcorejs-angular-pipes.mjs +14 -14
- package/fesm2022/sdcorejs-angular-services-api.mjs +10 -10
- package/fesm2022/sdcorejs-angular-services-cache.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-confirm.mjs +6 -6
- package/fesm2022/sdcorejs-angular-services-docx.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-excel.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-license.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-loading.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-notify.mjs +9 -9
- package/fesm2022/sdcorejs-angular-services-storage.mjs +3 -3
- package/forms/select/index.d.ts +21 -3
- package/modules/keycloak/htmls/auth-keycloak-error.html +54 -0
- package/modules/keycloak/htmls/silent-renew.html +7 -0
- package/modules/keycloak/index.d.ts +30 -0
- package/package.json +2 -2
package/components/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export * from '@sdcorejs/angular/components/quick-action';
|
|
|
10
10
|
export * from '@sdcorejs/angular/components/query-bar';
|
|
11
11
|
export * from '@sdcorejs/angular/components/upload-file';
|
|
12
12
|
export * from '@sdcorejs/angular/components/section';
|
|
13
|
+
export * from '@sdcorejs/angular/components/inform';
|
|
13
14
|
export * from '@sdcorejs/angular/components/anchor';
|
|
14
15
|
export * from '@sdcorejs/angular/components/query-builder';
|
|
15
16
|
export * from '@sdcorejs/angular/components/org-chart';
|
|
@@ -154,10 +154,13 @@ declare class SdUploadFile<TArgs = any> {
|
|
|
154
154
|
preview: () => Promise<void>;
|
|
155
155
|
/**
|
|
156
156
|
* Tải xuống một tệp tin dựa trên đối tượng PreviewFile.
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
157
|
+
*
|
|
158
|
+
* Ưu tiên:
|
|
159
|
+
* 1. Nếu consumer CÓ implement hàm download (input `download` hoặc configuration) VÀ file có
|
|
160
|
+
* `idOrKey` (file đã lưu trên server) → LUÔN gọi hàm download. KHÔNG mở `src` (URL lấy từ detail).
|
|
161
|
+
* Dùng cho trường hợp tải file qua API có xác thực thay vì truy cập trực tiếp URL.
|
|
162
|
+
* 2. Ngược lại (không có hàm download, hoặc file local chưa upload nên chưa có `idOrKey`) →
|
|
163
|
+
* tải trực tiếp từ `file` (blob) hoặc `src` (URL).
|
|
161
164
|
*
|
|
162
165
|
* @param previewFile Đối tượng PreviewFile chứa thông tin tệp tin.
|
|
163
166
|
*/
|
|
@@ -22,10 +22,10 @@ class SdAnchorItem {
|
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
26
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.
|
|
25
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAnchorItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
26
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.25", type: SdAnchorItem, isStandalone: true, selector: "sd-anchor-item", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<section>\n <ng-content></ng-content>\n</section>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
27
27
|
}
|
|
28
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
28
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAnchorItem, decorators: [{
|
|
29
29
|
type: Component,
|
|
30
30
|
args: [{ selector: 'sd-anchor-item', imports: [CommonModule], standalone: true, template: "<section>\n <ng-content></ng-content>\n</section>\n" }]
|
|
31
31
|
}], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: false }] }] } });
|
|
@@ -62,10 +62,10 @@ class AnchorNav {
|
|
|
62
62
|
ngOnDestroy() {
|
|
63
63
|
this.#subscription.unsubscribe();
|
|
64
64
|
}
|
|
65
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
66
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
65
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AnchorNav, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
66
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AnchorNav, isStandalone: true, selector: "anchor-nav", inputs: { sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: true, transformFunction: null }, activeSectionId: { classPropertyName: "activeSectionId", publicName: "activeSectionId", isSignal: true, isRequired: false, transformFunction: null }, ellipsis: { classPropertyName: "ellipsis", publicName: "ellipsis", isSignal: true, isRequired: false, transformFunction: null }, sidebarWidth: { classPropertyName: "sidebarWidth", publicName: "sidebarWidth", isSignal: true, isRequired: false, transformFunction: null }, parentAutoId: { classPropertyName: "parentAutoId", publicName: "parentAutoId", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clickSection: "clickSection" }, ngImport: i0, template: "<div\n class=\"c-anchor-list\"\n [style.width]=\"sidebarWidth()\"\n [style.--anchor-active-color]=\"cssActiveVar()\">\n @for (section of sections(); track section.id) {\n <div\n class=\"c-anchor-list-item\"\n [class.active]=\"section.id === activeSectionId()\"\n (click)=\"onClickSection(section.id)\"\n (keydown.enter)=\"onClickSection(section.id)\"\n [attr.data-autoId]=\"itemAutoId(section)\"\n tabindex=\"0\">\n @if (section.icon()) {\n <mat-icon class=\"c-anchor-list-item-icon\">{{ section.icon() }}</mat-icon>\n }\n <div class=\"c-anchor-list-item-text\" [class.ellipsis]=\"ellipsis()\">\n {{ section.title() }}\n </div>\n </div>\n }\n</div>\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}.c-anchor-list{height:100%;display:flex;flex-direction:column}.c-anchor-list .c-anchor-list-item{border-left:2px solid var(--sd-secondary-light);color:var(--sd-black500);padding:.5rem 1.5rem;cursor:pointer;display:flex;align-items:center;gap:.5rem;min-width:0;overflow:hidden}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-icon{flex:0 0 auto}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text{flex:1 1 0;min-width:0;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text.ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-anchor-list .c-anchor-list-item.active{border-left:2px solid var(--anchor-active-color, var(--sd-primary));color:var(--anchor-active-color, var(--sd-primary));font-weight:700}.c-anchor-list .c-anchor-list-item.active .c-anchor-list-item-icon{color:var(--anchor-active-color, var(--sd-primary))}.c-anchor-list .c-anchor-list-item:not(.active){border-left:2px solid var(--sd-secondary-light);font-weight:400}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
67
67
|
}
|
|
68
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
68
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AnchorNav, decorators: [{
|
|
69
69
|
type: Component,
|
|
70
70
|
args: [{ selector: 'anchor-nav', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, MatIconModule], standalone: true, template: "<div\n class=\"c-anchor-list\"\n [style.width]=\"sidebarWidth()\"\n [style.--anchor-active-color]=\"cssActiveVar()\">\n @for (section of sections(); track section.id) {\n <div\n class=\"c-anchor-list-item\"\n [class.active]=\"section.id === activeSectionId()\"\n (click)=\"onClickSection(section.id)\"\n (keydown.enter)=\"onClickSection(section.id)\"\n [attr.data-autoId]=\"itemAutoId(section)\"\n tabindex=\"0\">\n @if (section.icon()) {\n <mat-icon class=\"c-anchor-list-item-icon\">{{ section.icon() }}</mat-icon>\n }\n <div class=\"c-anchor-list-item-text\" [class.ellipsis]=\"ellipsis()\">\n {{ section.title() }}\n </div>\n </div>\n }\n</div>\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}.c-anchor-list{height:100%;display:flex;flex-direction:column}.c-anchor-list .c-anchor-list-item{border-left:2px solid var(--sd-secondary-light);color:var(--sd-black500);padding:.5rem 1.5rem;cursor:pointer;display:flex;align-items:center;gap:.5rem;min-width:0;overflow:hidden}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-icon{flex:0 0 auto}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text{flex:1 1 0;min-width:0;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.c-anchor-list .c-anchor-list-item .c-anchor-list-item-text.ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-anchor-list .c-anchor-list-item.active{border-left:2px solid var(--anchor-active-color, var(--sd-primary));color:var(--anchor-active-color, var(--sd-primary));font-weight:700}.c-anchor-list .c-anchor-list-item.active .c-anchor-list-item-icon{color:var(--anchor-active-color, var(--sd-primary))}.c-anchor-list .c-anchor-list-item:not(.active){border-left:2px solid var(--sd-secondary-light);font-weight:400}\n"] }]
|
|
71
71
|
}], ctorParameters: () => [], propDecorators: { sections: [{ type: i0.Input, args: [{ isSignal: true, alias: "sections", required: true }] }], activeSectionId: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSectionId", required: false }] }], ellipsis: [{ type: i0.Input, args: [{ isSignal: true, alias: "ellipsis", required: false }] }], sidebarWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarWidth", required: false }] }], parentAutoId: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentAutoId", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], clickSection: [{ type: i0.Output, args: ["clickSection"] }] } });
|
|
@@ -181,10 +181,10 @@ class SdAnchor {
|
|
|
181
181
|
this.#cleanScrollSectionByClickObserver();
|
|
182
182
|
this.#cleanIntersectionObserver();
|
|
183
183
|
}
|
|
184
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
185
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
184
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAnchor, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
185
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdAnchor, isStandalone: true, selector: "sd-anchor", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, sidebarWidth: { classPropertyName: "sidebarWidth", publicName: "sidebarWidth", isSignal: true, isRequired: false, transformFunction: null }, ellipsis: { classPropertyName: "ellipsis", publicName: "ellipsis", isSignal: true, isRequired: false, transformFunction: null }, overScroll: { classPropertyName: "overScroll", publicName: "overScroll", isSignal: true, isRequired: false, transformFunction: null }, hideNav: { classPropertyName: "hideNav", publicName: "hideNav", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "sections", predicate: SdAnchorItem, isSignal: true }], viewQueries: [{ propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"c-anchor-vertical\" [ngClass]=\"{ 'c-stop-scroll-propagation': !overScroll() }\" #wrapper>\n <div class=\"c-anchor-content\">\n <ng-content></ng-content>\n </div>\n\n @if (!hideNav()) {\n <div class=\"c-anchor-list\" [style.flex-basis]=\"sidebarWidth()\">\n <anchor-nav\n [sections]=\"sections()\"\n [ellipsis]=\"ellipsis()\"\n [sidebarWidth]=\"sidebarWidth()\"\n [activeSectionId]=\"activeSectionId()\"\n [parentAutoId]=\"autoId()\"\n [color]=\"color()\"\n (clickSection)=\"scrollSectionByClick($event)\">\n </anchor-nav>\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";.c-anchor-vertical{position:relative;display:flex;height:100%;width:100%;gap:16px;overflow-y:auto}.c-anchor-vertical.c-stop-scroll-propagation{overscroll-behavior:contain}.c-anchor-vertical .c-anchor-content{flex:1 1 auto;min-width:0}.c-anchor-vertical .c-anchor-list{flex:0 0 auto;position:sticky;top:0;right:6px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AnchorNav, selector: "anchor-nav", inputs: ["sections", "activeSectionId", "ellipsis", "sidebarWidth", "parentAutoId", "color"], outputs: ["clickSection"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
186
186
|
}
|
|
187
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
187
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAnchor, decorators: [{
|
|
188
188
|
type: Component,
|
|
189
189
|
args: [{ selector: 'sd-anchor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AnchorNav], standalone: true, template: "<div class=\"c-anchor-vertical\" [ngClass]=\"{ 'c-stop-scroll-propagation': !overScroll() }\" #wrapper>\n <div class=\"c-anchor-content\">\n <ng-content></ng-content>\n </div>\n\n @if (!hideNav()) {\n <div class=\"c-anchor-list\" [style.flex-basis]=\"sidebarWidth()\">\n <anchor-nav\n [sections]=\"sections()\"\n [ellipsis]=\"ellipsis()\"\n [sidebarWidth]=\"sidebarWidth()\"\n [activeSectionId]=\"activeSectionId()\"\n [parentAutoId]=\"autoId()\"\n [color]=\"color()\"\n (clickSection)=\"scrollSectionByClick($event)\">\n </anchor-nav>\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";.c-anchor-vertical{position:relative;display:flex;height:100%;width:100%;gap:16px;overflow-y:auto}.c-anchor-vertical.c-stop-scroll-propagation{overscroll-behavior:contain}.c-anchor-vertical .c-anchor-content{flex:1 1 auto;min-width:0}.c-anchor-vertical .c-anchor-list{flex:0 0 auto;position:sticky;top:0;right:6px}\n"] }]
|
|
190
190
|
}], ctorParameters: () => [], propDecorators: { wrapper: [{ type: i0.ViewChild, args: ['wrapper', { isSignal: true }] }], sections: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdAnchorItem), { isSignal: true }] }], autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], sidebarWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarWidth", required: false }] }], ellipsis: [{ type: i0.Input, args: [{ isSignal: true, alias: "ellipsis", required: false }] }], overScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "overScroll", required: false }] }], hideNav: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideNav", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }] } });
|
|
@@ -184,10 +184,10 @@ class SdAutoidScannerService {
|
|
|
184
184
|
return input.value;
|
|
185
185
|
return (node.textContent ?? '').trim().slice(0, 80);
|
|
186
186
|
}
|
|
187
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
188
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
187
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidScannerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
188
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidScannerService, providedIn: 'root' });
|
|
189
189
|
}
|
|
190
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
190
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidScannerService, decorators: [{
|
|
191
191
|
type: Injectable,
|
|
192
192
|
args: [{ providedIn: 'root' }]
|
|
193
193
|
}] });
|
|
@@ -270,10 +270,10 @@ class SdAutoidAuditService {
|
|
|
270
270
|
?? node.getAttribute('title')
|
|
271
271
|
?? '';
|
|
272
272
|
}
|
|
273
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
274
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
273
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidAuditService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
274
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidAuditService, providedIn: 'root' });
|
|
275
275
|
}
|
|
276
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
276
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidAuditService, decorators: [{
|
|
277
277
|
type: Injectable,
|
|
278
278
|
args: [{ providedIn: 'root' }]
|
|
279
279
|
}] });
|
|
@@ -374,10 +374,10 @@ class SdAutoidHighlightService {
|
|
|
374
374
|
}
|
|
375
375
|
node.setAttribute(ATTR, marker);
|
|
376
376
|
}
|
|
377
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
378
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
377
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidHighlightService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
378
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidHighlightService, providedIn: 'root' });
|
|
379
379
|
}
|
|
380
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
380
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidHighlightService, decorators: [{
|
|
381
381
|
type: Injectable,
|
|
382
382
|
args: [{ providedIn: 'root' }]
|
|
383
383
|
}] });
|
|
@@ -566,10 +566,10 @@ class SdAutoidExportService {
|
|
|
566
566
|
.map(p => p[0].toUpperCase() + p.slice(1))
|
|
567
567
|
.join('');
|
|
568
568
|
}
|
|
569
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
570
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
569
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidExportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
570
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidExportService, providedIn: 'root' });
|
|
571
571
|
}
|
|
572
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
572
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidExportService, decorators: [{
|
|
573
573
|
type: Injectable,
|
|
574
574
|
args: [{ providedIn: 'root' }]
|
|
575
575
|
}] });
|
|
@@ -791,10 +791,10 @@ class SdAutoidInspector {
|
|
|
791
791
|
this.copyOk.set(true);
|
|
792
792
|
setTimeout(() => this.copyOk.set(false), 1200);
|
|
793
793
|
}
|
|
794
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
795
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SdAutoidInspector, isStandalone: true, selector: "sd-autoid-inspector", inputs: { enabled: { classPropertyName: "enabled", publicName: "enabled", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "@let _enabled = enabled();\n@let _open = open();\n@if (_enabled && !dismissed()) {\n <div class=\"sd-autoid-inspector__fab-wrap\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__fab\"\n data-autoid=\"sd-autoid-inspector-fab\"\n [attr.data-opened]=\"dataOpened()\"\n [matTooltip]=\"_open ? '\u0110\u00F3ng AutoId Inspector' : 'M\u1EDF AutoId Inspector'\"\n matTooltipPosition=\"left\"\n (click)=\"togglePanel()\">\n <mat-icon>{{ _open ? 'close' : 'tag' }}</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__fab-dismiss\"\n matTooltip=\"\u1EA8n t\u1EA1m \u2014 reload trang \u0111\u1EC3 hi\u1EC7n l\u1EA1i\"\n matTooltipPosition=\"left\"\n aria-label=\"\u1EA8n t\u1EA1m FAB\"\n (click)=\"dismissFab($event)\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n}\n\n@if (_enabled && _open) {\n @let _segment = segment();\n <div class=\"sd-autoid-inspector__backdrop\" (click)=\"closePanel()\"></div>\n <section class=\"sd-autoid-inspector__panel\"\n role=\"dialog\"\n aria-label=\"AutoId Inspector\"\n data-autoid=\"sd-autoid-inspector-panel\"\n [attr.data-segment]=\"dataSegment()\"\n [attr.data-highlight-on]=\"dataHighlightOn()\"\n [attr.data-element-count]=\"dataElementCount()\"\n [attr.data-missing-count]=\"dataMissingCount()\"\n [attr.data-duplicate-count]=\"dataDuplicateCount()\">\n <header class=\"sd-autoid-inspector__header\">\n <div class=\"sd-autoid-inspector__segments\">\n <button\n type=\"button\"\n [class.is-active]=\"_segment === 'audit'\"\n (click)=\"setSegment('audit')\">\n Audit\n @if (audit(); as a) {\n <span class=\"sd-autoid-inspector__badge\" [class.is-warn]=\"a.missingCount + a.duplicateCount > 0\">\n {{ a.missingCount + a.duplicateCount }}\n </span>\n }\n </button>\n <button\n type=\"button\"\n [class.is-active]=\"_segment === 'elements'\"\n (click)=\"setSegment('elements')\">\n Elements\n <span class=\"sd-autoid-inspector__badge\">{{ elements().length }}</span>\n </button>\n <button\n type=\"button\"\n [class.is-active]=\"_segment === 'export'\"\n (click)=\"setSegment('export')\">\n Export\n </button>\n </div>\n <div class=\"sd-autoid-inspector__actions\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn\"\n matTooltip=\"Qu\u00E9t l\u1EA1i\"\n (click)=\"refresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__close-btn\"\n matTooltip=\"\u0110\u00F3ng\"\n aria-label=\"\u0110\u00F3ng panel\"\n (click)=\"closePanel()\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </header>\n\n @if (copyOk()) {\n <div class=\"sd-autoid-inspector__toast\">\u0110\u00E3 copy \u2713</div>\n }\n\n <div class=\"sd-autoid-inspector__body\">\n @switch (_segment) {\n @case ('audit') {\n <ng-container *ngTemplateOutlet=\"auditTpl\"></ng-container>\n }\n @case ('elements') {\n <ng-container *ngTemplateOutlet=\"elementsTpl\"></ng-container>\n }\n @case ('export') {\n <ng-container *ngTemplateOutlet=\"exportTpl\"></ng-container>\n }\n }\n </div>\n </section>\n\n <ng-template #auditTpl>\n @if (audit(); as a) {\n @let _highlightOn = highlightOn();\n <div class=\"sd-autoid-inspector__audit-toolbar\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__toggle\"\n [class.is-on]=\"_highlightOn\"\n (click)=\"toggleHighlight()\">\n <mat-icon>{{ _highlightOn ? 'visibility' : 'visibility_off' }}</mat-icon>\n <span>Highlight DOM</span>\n <span class=\"sd-autoid-inspector__toggle-state\">{{ _highlightOn ? 'ON' : 'OFF' }}</span>\n </button>\n </div>\n <div class=\"sd-autoid-inspector__summary\">\n <div class=\"sd-autoid-inspector__stat is-info\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.total }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">T\u1ED5ng autoid</div>\n </div>\n <div class=\"sd-autoid-inspector__stat\" [class.is-error]=\"a.duplicateCount > 0\" [class.is-success]=\"a.duplicateCount === 0\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.duplicateCount }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">Tr\u00F9ng</div>\n </div>\n <div class=\"sd-autoid-inspector__stat\" [class.is-warning]=\"a.missingCount > 0\" [class.is-success]=\"a.missingCount === 0\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.missingCount }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">Thi\u1EBFu</div>\n </div>\n </div>\n\n @if (a.duplicateCount > 0) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-error\">error_outline</mat-icon>\n Autoid b\u1ECB tr\u00F9ng\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr><th>Autoid</th><th>S\u1ED1 l\u1EA7n</th></tr>\n </thead>\n <tbody>\n @for (entry of a.duplicates | keyvalue; track entry.key) {\n <tr class=\"is-error\">\n <td><code>{{ entry.key }}</code></td>\n <td>{{ entry.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n @if (a.missingCount > 0) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-warning\">warning_amber</mat-icon>\n Element thi\u1EBFu autoid\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr><th>Tag</th><th>Name hint</th><th>Selector</th></tr>\n </thead>\n <tbody>\n @for (m of a.missing; track $index) {\n <tr class=\"is-warning\">\n <td><code>{{ m.tag }}</code></td>\n <td>{{ m.nameHint }}</td>\n <td><code>{{ m.selector }}</code></td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n @if (a.duplicateCount === 0 && a.missingCount === 0) {\n <div class=\"sd-autoid-inspector__success-card\">\n <mat-icon>check_circle</mat-icon>\n <div>\n <strong>Kh\u00F4ng c\u00F3 element thi\u1EBFu ho\u1EB7c tr\u00F9ng autoid.</strong>\n <small>Trang \u0111\u00E3 \u0111\u1EA1t chu\u1EA9n convention autoid.</small>\n </div>\n </div>\n }\n }\n </ng-template>\n\n <ng-template #elementsTpl>\n @let _filter = filter();\n <div class=\"sd-autoid-inspector__filter\">\n <mat-icon>search</mat-icon>\n <input\n type=\"text\"\n placeholder=\"L\u1ECDc theo autoid / name / tag\"\n [ngModel]=\"_filter\"\n (ngModelChange)=\"filter.set($event)\"/>\n @if (_filter) {\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn\"\n matTooltip=\"Xo\u00E1 filter\"\n (click)=\"filter.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n\n <!-- Top-level elements (not inside any sd-table) -->\n <h4 class=\"sd-autoid-inspector__section-title\">\n Top-level elements\n <span class=\"sd-autoid-inspector__badge\">{{ topLevelElements().length }}</span>\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr>\n <th class=\"is-num\">STT</th>\n <th>Name</th>\n <th>Autoid</th>\n <th>Tag</th>\n <th>State</th>\n <th>Value</th>\n </tr>\n </thead>\n <tbody>\n @for (el of topLevelElements(); track el.autoid + $index) {\n <tr [class.is-error]=\"el.duplicate\">\n <td class=\"is-num\">{{ el.stt }}</td>\n <td>{{ el.name || '\u2014' }}</td>\n <td>\n <div class=\"sd-autoid-inspector__autoid-cell\">\n <code>{{ el.autoid }}</code>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn is-primary\"\n matTooltip=\"Copy xpath\"\n (click)=\"copyXpath(el.autoid)\">\n <mat-icon>content_copy</mat-icon>\n </button>\n </div>\n </td>\n <td><span class=\"sd-autoid-inspector__tag-chip\">{{ el.tag }}</span></td>\n <td class=\"sd-autoid-inspector__state-cell\">\n @if (el.state.disabled !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.disabled === 'true'\">\n disabled={{ el.state.disabled }}\n </span>\n }\n @if (el.state.loading !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.loading === 'true'\">\n loading={{ el.state.loading }}\n </span>\n }\n @if (el.state.empty !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.empty === 'true'\">\n empty={{ el.state.empty }}\n </span>\n }\n @if (el.state.invalid !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.invalid === 'true'\">\n invalid={{ el.state.invalid }}\n </span>\n }\n @if (el.state.opened !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.opened === 'true'\">\n opened={{ el.state.opened }}\n </span>\n }\n @if (el.state.count !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n count={{ el.state.count }}\n </span>\n }\n @if (el.state.required !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.required === 'true'\">\n required={{ el.state.required }}\n </span>\n }\n @if (el.state.maxlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n maxlength={{ el.state.maxlength }}\n </span>\n }\n @if (el.state.minlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n minlength={{ el.state.minlength }}\n </span>\n }\n @if (el.state.pattern !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n pattern={{ el.state.pattern }}\n </span>\n }\n @if (el.state.errorMessage !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-error\">\n error: {{ el.state.errorMessage }}\n </span>\n }\n </td>\n <td class=\"sd-autoid-inspector__value\" [matTooltip]=\"el.state.dataValue || el.text || ''\">\n {{ el.state.dataValue || el.text || '\u2014' }}\n </td>\n </tr>\n } @empty {\n <tr><td colspan=\"6\" class=\"sd-autoid-inspector__empty\">Kh\u00F4ng c\u00F3 k\u1EBFt qu\u1EA3.</td></tr>\n }\n </tbody>\n </table>\n </div>\n\n <!-- One section per sd-table group -->\n @for (group of tableGroups(); track group.scope) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-info\">table_chart</mat-icon>\n Inside <code>{{ group.scope }}</code>\n <span class=\"sd-autoid-inspector__badge\">{{ group.items.length }}</span>\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr>\n <th class=\"is-num\">STT</th>\n <th>Name</th>\n <th>Autoid</th>\n <th>Tag</th>\n <th>State</th>\n <th>Value</th>\n </tr>\n </thead>\n <tbody>\n @for (el of group.items; track el.autoid + $index) {\n <tr [class.is-error]=\"el.duplicate\">\n <td class=\"is-num\">{{ el.stt }}</td>\n <td>{{ el.name || '\u2014' }}</td>\n <td>\n <div class=\"sd-autoid-inspector__autoid-cell\">\n <code>{{ el.autoid }}</code>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn is-primary\"\n matTooltip=\"Copy xpath\"\n (click)=\"copyXpath(el.autoid)\">\n <mat-icon>content_copy</mat-icon>\n </button>\n </div>\n </td>\n <td><span class=\"sd-autoid-inspector__tag-chip\">{{ el.tag }}</span></td>\n <td class=\"sd-autoid-inspector__state-cell\">\n @if (el.state.disabled !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.disabled === 'true'\">\n disabled={{ el.state.disabled }}\n </span>\n }\n @if (el.state.loading !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.loading === 'true'\">\n loading={{ el.state.loading }}\n </span>\n }\n @if (el.state.empty !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.empty === 'true'\">\n empty={{ el.state.empty }}\n </span>\n }\n @if (el.state.invalid !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.invalid === 'true'\">\n invalid={{ el.state.invalid }}\n </span>\n }\n @if (el.state.opened !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.opened === 'true'\">\n opened={{ el.state.opened }}\n </span>\n }\n @if (el.state.count !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n count={{ el.state.count }}\n </span>\n }\n @if (el.state.required !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.required === 'true'\">\n required={{ el.state.required }}\n </span>\n }\n @if (el.state.maxlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n maxlength={{ el.state.maxlength }}\n </span>\n }\n @if (el.state.minlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n minlength={{ el.state.minlength }}\n </span>\n }\n @if (el.state.pattern !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n pattern={{ el.state.pattern }}\n </span>\n }\n @if (el.state.errorMessage !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-error\">\n error: {{ el.state.errorMessage }}\n </span>\n }\n </td>\n <td class=\"sd-autoid-inspector__value\" [matTooltip]=\"el.state.dataValue || el.text || ''\">\n {{ el.state.dataValue || el.text || '\u2014' }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </ng-template>\n\n <ng-template #exportTpl>\n <div class=\"sd-autoid-inspector__export-grid\">\n <button type=\"button\" matTooltip=\"Copy JSON v\u00E0o clipboard\" (click)=\"copyJson()\">\n <mat-icon>content_copy</mat-icon>\n <span>Copy JSON</span>\n <small>clipboard</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i file JSON\" (click)=\"exportJson()\">\n <mat-icon>download</mat-icon>\n <span>JSON</span>\n <small>.json</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i file CSV\" (click)=\"exportCsv()\">\n <mat-icon>table_view</mat-icon>\n <span>CSV</span>\n <small>.csv</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i MD POM skeleton \u2014 cho AI vi\u1EBFt auto-test\" (click)=\"exportMdPom()\">\n <mat-icon>code</mat-icon>\n <span>MD POM</span>\n <small>AI test</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i MD reference table \u2014 group theo tag sd-*\" (click)=\"exportMdTable()\">\n <mat-icon>view_list</mat-icon>\n <span>MD Table</span>\n <small>reference</small>\n </button>\n </div>\n </ng-template>\n}\n", styles: [":host{position:fixed;inset:auto 0 0 auto;z-index:100000;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-size:13px;color:var(--sd-black500, #212121)}.sd-autoid-inspector__fab-wrap{position:fixed;right:16px;bottom:16px;z-index:100000}.sd-autoid-inspector__fab-wrap:hover .sd-autoid-inspector__fab-dismiss{opacity:1;transform:scale(1);pointer-events:auto}.sd-autoid-inspector__fab{width:36px;height:36px;border-radius:50%;border:none;background:var(--sd-primary, #2A66F4);color:#fff;cursor:pointer;box-shadow:0 3px 10px #00000038;display:inline-flex;align-items:center;justify-content:center;transition:transform .15s ease,background .15s ease,box-shadow .15s ease}.sd-autoid-inspector__fab:hover{background:var(--sd-primary-dark, #1C4AD9);transform:scale(1.08);box-shadow:0 5px 14px #00000047}.sd-autoid-inspector__fab mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__fab-dismiss{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;border:1px solid var(--sd-black200, #E6E6E6);background:#fff;color:var(--sd-black400, #757575);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;opacity:0;transform:scale(.7);pointer-events:none;transition:opacity .12s ease,transform .12s ease,color .12s ease,background .12s ease;box-shadow:0 1px 4px #00000026}.sd-autoid-inspector__fab-dismiss:hover{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__fab-dismiss mat-icon{font-size:12px;width:12px;height:12px;line-height:12px}.sd-autoid-inspector__backdrop{position:fixed;inset:0;background:#00000052;z-index:100001;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.sd-autoid-inspector__panel{position:fixed;right:20px;bottom:80px;width:min(860px,100vw - 40px);max-height:calc(100vh - 110px);background:#fff;border-radius:12px;box-shadow:0 16px 48px #00000038;display:flex;flex-direction:column;z-index:100002;overflow:hidden;border:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__header{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--sd-black200, #E6E6E6);background:var(--sd-black100, #F2F2F2);flex-shrink:0}.sd-autoid-inspector__segments{display:inline-flex;border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;background:#fff;overflow:hidden}.sd-autoid-inspector__segments button{border:none;background:transparent;padding:5px 12px;cursor:pointer;font-size:12px;font-weight:500;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;gap:6px;border-right:1px solid var(--sd-black200, #E6E6E6);transition:background .12s ease,color .12s ease}.sd-autoid-inspector__segments button:last-child{border-right:none}.sd-autoid-inspector__segments button:hover:not(.is-active){background:var(--sd-black100, #F2F2F2);color:var(--sd-black500, #212121)}.sd-autoid-inspector__segments button.is-active{background:var(--sd-primary, #2A66F4);color:#fff}.sd-autoid-inspector__badge{background:var(--sd-black200, #E6E6E6);color:var(--sd-black500, #212121);border-radius:10px;padding:0 7px;font-size:11px;font-weight:600;line-height:16px}.is-active .sd-autoid-inspector__badge{background:#ffffff40;color:#fff}.sd-autoid-inspector__badge.is-warn{background:var(--sd-error, #F82C13);color:#fff}.sd-autoid-inspector__actions{display:inline-flex;gap:4px;margin-left:auto}.sd-autoid-inspector__icon-btn{border:none;background:transparent;cursor:pointer;padding:4px;border-radius:6px;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.sd-autoid-inspector__icon-btn:hover{background:var(--sd-black100, #F2F2F2);color:var(--sd-black500, #212121)}.sd-autoid-inspector__icon-btn.is-primary{color:var(--sd-primary, #2A66F4)}.sd-autoid-inspector__icon-btn.is-primary:hover{background:var(--sd-primary-light, #EAF1FF);color:var(--sd-primary-dark, #1C4AD9)}.sd-autoid-inspector__icon-btn mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__close-btn{border:none;cursor:pointer;padding:4px;border-radius:50%;width:28px;height:28px;background:transparent;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.sd-autoid-inspector__close-btn:hover{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E)}.sd-autoid-inspector__close-btn mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__body{padding:14px;overflow:auto;flex:1;background:#fff}.sd-autoid-inspector__toast{position:absolute;top:56px;right:14px;background:var(--sd-success, #4CAF50);color:#fff;padding:6px 12px;border-radius:6px;font-size:12px;z-index:2;box-shadow:0 4px 12px #0000002e}.sd-autoid-inspector__audit-toolbar{display:flex;justify-content:flex-end;margin-bottom:12px}.sd-autoid-inspector__toggle{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--sd-black200, #E6E6E6);background:#fff;border-radius:999px;padding:5px 12px 5px 10px;cursor:pointer;font-size:12px;font-weight:500;color:var(--sd-black400, #757575);transition:all .15s ease}.sd-autoid-inspector__toggle:hover{border-color:var(--sd-primary, #2A66F4);color:var(--sd-primary, #2A66F4)}.sd-autoid-inspector__toggle.is-on{border-color:var(--sd-primary, #2A66F4);color:var(--sd-primary, #2A66F4);background:var(--sd-primary-light, #EAF1FF)}.sd-autoid-inspector__toggle mat-icon{font-size:16px;width:16px;height:16px}.sd-autoid-inspector__toggle-state{font-size:10px;font-weight:700;padding:1px 7px;border-radius:999px;background:var(--sd-black200, #E6E6E6);color:var(--sd-black400, #757575)}.is-on .sd-autoid-inspector__toggle-state{background:var(--sd-primary, #2A66F4);color:#fff}.sd-autoid-inspector__summary{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:16px}.sd-autoid-inspector__stat{background:var(--sd-black100, #F2F2F2);border-radius:10px;padding:12px;text-align:center;border:1px solid transparent}.sd-autoid-inspector__stat.is-info{background:var(--sd-info-light, #E7E9FF);border-color:var(--sd-info, #2962FF)}.sd-autoid-inspector__stat.is-info .sd-autoid-inspector__stat-value{color:var(--sd-info, #2962FF)}.sd-autoid-inspector__stat.is-success{background:var(--sd-success-light, #DBEFDC);border-color:var(--sd-success, #4CAF50)}.sd-autoid-inspector__stat.is-success .sd-autoid-inspector__stat-value{color:var(--sd-success-dark, #39833C)}.sd-autoid-inspector__stat.is-warning{background:var(--sd-warning-light, #FFEACC);border-color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__stat.is-warning .sd-autoid-inspector__stat-value{color:var(--sd-warning-dark, #BF7000)}.sd-autoid-inspector__stat.is-error{background:var(--sd-error-light, #FED5D0);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__stat.is-error .sd-autoid-inspector__stat-value{color:var(--sd-error-dark, #BA200E)}.sd-autoid-inspector__stat-value{font-size:22px;font-weight:700;line-height:1;margin-bottom:4px}.sd-autoid-inspector__stat-label{font-size:11px;color:var(--sd-black400, #757575);text-transform:uppercase;letter-spacing:.4px;font-weight:600}.sd-autoid-inspector__section-title{display:flex;align-items:center;gap:6px;margin:14px 0 8px;font-size:13px;font-weight:600;color:var(--sd-black500, #212121)}.sd-autoid-inspector__section-title mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__section-title mat-icon.is-error{color:var(--sd-error, #F82C13)}.sd-autoid-inspector__section-title mat-icon.is-warning{color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__section-title mat-icon.is-info{color:var(--sd-info, #2962FF)}.sd-autoid-inspector__success-card{display:flex;align-items:center;gap:12px;padding:14px 16px;background:var(--sd-success-light, #DBEFDC);border:1px solid var(--sd-success, #4CAF50);border-radius:10px;color:var(--sd-success-dark, #39833C)}.sd-autoid-inspector__success-card mat-icon{font-size:28px;width:28px;height:28px;color:var(--sd-success, #4CAF50)}.sd-autoid-inspector__success-card strong{display:block;font-size:13px;margin-bottom:2px}.sd-autoid-inspector__success-card small{font-size:11px;opacity:.85}.sd-autoid-inspector__table-wrap{border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;overflow:auto;max-height:60vh;background:#fff}.sd-autoid-inspector__table{width:100%;border-collapse:separate;border-spacing:0;font-size:12px}.sd-autoid-inspector__table th,.sd-autoid-inspector__table td{padding:8px 10px;text-align:left;vertical-align:middle;border-bottom:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__table thead th{position:sticky;top:0;z-index:1;background:var(--sd-black100, #F2F2F2);font-weight:600;color:var(--sd-black500, #212121);text-transform:none;font-size:11px;letter-spacing:.3px;border-bottom:none;box-shadow:inset 0 -1px 0 var(--sd-black200, #E6E6E6),0 2px 4px #0000000a;white-space:nowrap}.sd-autoid-inspector__table thead th.is-num{text-align:right;width:50px}.sd-autoid-inspector__table tbody tr{transition:background .1s ease}.sd-autoid-inspector__table tbody tr:hover{background:var(--sd-primary-light, #EAF1FF)}.sd-autoid-inspector__table tbody tr:last-child td{border-bottom:none}.sd-autoid-inspector__table tbody tr.is-error{background:var(--sd-error-light, #FED5D0)}.sd-autoid-inspector__table tbody tr.is-error:hover{background:var(--sd-error-light, #FED5D0);filter:brightness(.98)}.sd-autoid-inspector__table tbody tr.is-warning{background:var(--sd-warning-light, #FFEACC)}.sd-autoid-inspector__table tbody tr.is-warning:hover{background:var(--sd-warning-light, #FFEACC);filter:brightness(.98)}.sd-autoid-inspector__table td.is-num{text-align:right;color:var(--sd-black400, #757575);font-variant-numeric:tabular-nums}.sd-autoid-inspector__table code{font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;background:var(--sd-black100, #F2F2F2);padding:2px 6px;border-radius:4px;color:var(--sd-primary-dark, #1C4AD9);border:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__autoid-cell{display:inline-flex;align-items:center;gap:6px}.sd-autoid-inspector__tag-chip{display:inline-block;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;background:var(--sd-info-light, #E7E9FF);color:var(--sd-info, #2962FF);border:1px solid var(--sd-info, #2962FF);padding:1px 8px;border-radius:999px;font-weight:500}.sd-autoid-inspector__value{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--sd-black400, #757575);font-style:italic}.sd-autoid-inspector__state-cell{display:flex;flex-wrap:wrap;gap:4px;align-items:center;min-width:0}.sd-autoid-inspector__state-chip{display:inline-block;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:10px;background:var(--sd-black100, #F2F2F2);color:var(--sd-black400, #757575);border:1px solid var(--sd-black200, #E6E6E6);padding:1px 6px;border-radius:999px;font-weight:500;white-space:nowrap}.sd-autoid-inspector__state-chip.is-error{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__state-chip.is-warning{background:var(--sd-warning-light, #FFEACC);color:var(--sd-warning-dark, #BF7000);border-color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__state-chip.is-info{background:var(--sd-info-light, #E7E9FF);color:var(--sd-info, #2962FF);border-color:var(--sd-info, #2962FF)}.sd-autoid-inspector__empty{text-align:center;color:var(--sd-black400, #757575);padding:24px;font-style:italic}.sd-autoid-inspector__filter{display:flex;align-items:center;gap:6px;background:var(--sd-black100, #F2F2F2);border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;padding:6px 10px;margin-bottom:12px;transition:border-color .15s ease}.sd-autoid-inspector__filter:focus-within{border-color:var(--sd-primary, #2A66F4);background:#fff}.sd-autoid-inspector__filter input{flex:1;border:none;background:transparent;outline:none;font-size:13px;color:var(--sd-black500, #212121)}.sd-autoid-inspector__filter input::placeholder{color:var(--sd-black300, #BFBFBF)}.sd-autoid-inspector__filter>mat-icon{font-size:18px;width:18px;height:18px;color:var(--sd-black400, #757575)}.sd-autoid-inspector__export-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px}.sd-autoid-inspector__export-grid button{border:1px solid var(--sd-black200, #E6E6E6);background:#fff;border-radius:10px;padding:12px 10px;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-width:0;transition:border-color .15s ease,background .15s ease,transform .12s ease;text-align:center}.sd-autoid-inspector__export-grid button:hover{border-color:var(--sd-primary, #2A66F4);background:var(--sd-primary-light, #EAF1FF);transform:translateY(-1px)}.sd-autoid-inspector__export-grid button span{font-size:12px;font-weight:600;color:var(--sd-black500, #212121);line-height:1.25}.sd-autoid-inspector__export-grid button small{font-size:10px;color:var(--sd-black400, #757575);line-height:1.2}.sd-autoid-inspector__export-grid button mat-icon{font-size:22px;width:22px;height:22px;color:var(--sd-primary, #2A66F4)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
794
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidInspector, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
795
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdAutoidInspector, isStandalone: true, selector: "sd-autoid-inspector", inputs: { enabled: { classPropertyName: "enabled", publicName: "enabled", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "@let _enabled = enabled();\n@let _open = open();\n@if (_enabled && !dismissed()) {\n <div class=\"sd-autoid-inspector__fab-wrap\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__fab\"\n data-autoid=\"sd-autoid-inspector-fab\"\n [attr.data-opened]=\"dataOpened()\"\n [matTooltip]=\"_open ? '\u0110\u00F3ng AutoId Inspector' : 'M\u1EDF AutoId Inspector'\"\n matTooltipPosition=\"left\"\n (click)=\"togglePanel()\">\n <mat-icon>{{ _open ? 'close' : 'tag' }}</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__fab-dismiss\"\n matTooltip=\"\u1EA8n t\u1EA1m \u2014 reload trang \u0111\u1EC3 hi\u1EC7n l\u1EA1i\"\n matTooltipPosition=\"left\"\n aria-label=\"\u1EA8n t\u1EA1m FAB\"\n (click)=\"dismissFab($event)\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n}\n\n@if (_enabled && _open) {\n @let _segment = segment();\n <div class=\"sd-autoid-inspector__backdrop\" (click)=\"closePanel()\"></div>\n <section class=\"sd-autoid-inspector__panel\"\n role=\"dialog\"\n aria-label=\"AutoId Inspector\"\n data-autoid=\"sd-autoid-inspector-panel\"\n [attr.data-segment]=\"dataSegment()\"\n [attr.data-highlight-on]=\"dataHighlightOn()\"\n [attr.data-element-count]=\"dataElementCount()\"\n [attr.data-missing-count]=\"dataMissingCount()\"\n [attr.data-duplicate-count]=\"dataDuplicateCount()\">\n <header class=\"sd-autoid-inspector__header\">\n <div class=\"sd-autoid-inspector__segments\">\n <button\n type=\"button\"\n [class.is-active]=\"_segment === 'audit'\"\n (click)=\"setSegment('audit')\">\n Audit\n @if (audit(); as a) {\n <span class=\"sd-autoid-inspector__badge\" [class.is-warn]=\"a.missingCount + a.duplicateCount > 0\">\n {{ a.missingCount + a.duplicateCount }}\n </span>\n }\n </button>\n <button\n type=\"button\"\n [class.is-active]=\"_segment === 'elements'\"\n (click)=\"setSegment('elements')\">\n Elements\n <span class=\"sd-autoid-inspector__badge\">{{ elements().length }}</span>\n </button>\n <button\n type=\"button\"\n [class.is-active]=\"_segment === 'export'\"\n (click)=\"setSegment('export')\">\n Export\n </button>\n </div>\n <div class=\"sd-autoid-inspector__actions\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn\"\n matTooltip=\"Qu\u00E9t l\u1EA1i\"\n (click)=\"refresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__close-btn\"\n matTooltip=\"\u0110\u00F3ng\"\n aria-label=\"\u0110\u00F3ng panel\"\n (click)=\"closePanel()\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </header>\n\n @if (copyOk()) {\n <div class=\"sd-autoid-inspector__toast\">\u0110\u00E3 copy \u2713</div>\n }\n\n <div class=\"sd-autoid-inspector__body\">\n @switch (_segment) {\n @case ('audit') {\n <ng-container *ngTemplateOutlet=\"auditTpl\"></ng-container>\n }\n @case ('elements') {\n <ng-container *ngTemplateOutlet=\"elementsTpl\"></ng-container>\n }\n @case ('export') {\n <ng-container *ngTemplateOutlet=\"exportTpl\"></ng-container>\n }\n }\n </div>\n </section>\n\n <ng-template #auditTpl>\n @if (audit(); as a) {\n @let _highlightOn = highlightOn();\n <div class=\"sd-autoid-inspector__audit-toolbar\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__toggle\"\n [class.is-on]=\"_highlightOn\"\n (click)=\"toggleHighlight()\">\n <mat-icon>{{ _highlightOn ? 'visibility' : 'visibility_off' }}</mat-icon>\n <span>Highlight DOM</span>\n <span class=\"sd-autoid-inspector__toggle-state\">{{ _highlightOn ? 'ON' : 'OFF' }}</span>\n </button>\n </div>\n <div class=\"sd-autoid-inspector__summary\">\n <div class=\"sd-autoid-inspector__stat is-info\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.total }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">T\u1ED5ng autoid</div>\n </div>\n <div class=\"sd-autoid-inspector__stat\" [class.is-error]=\"a.duplicateCount > 0\" [class.is-success]=\"a.duplicateCount === 0\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.duplicateCount }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">Tr\u00F9ng</div>\n </div>\n <div class=\"sd-autoid-inspector__stat\" [class.is-warning]=\"a.missingCount > 0\" [class.is-success]=\"a.missingCount === 0\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.missingCount }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">Thi\u1EBFu</div>\n </div>\n </div>\n\n @if (a.duplicateCount > 0) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-error\">error_outline</mat-icon>\n Autoid b\u1ECB tr\u00F9ng\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr><th>Autoid</th><th>S\u1ED1 l\u1EA7n</th></tr>\n </thead>\n <tbody>\n @for (entry of a.duplicates | keyvalue; track entry.key) {\n <tr class=\"is-error\">\n <td><code>{{ entry.key }}</code></td>\n <td>{{ entry.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n @if (a.missingCount > 0) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-warning\">warning_amber</mat-icon>\n Element thi\u1EBFu autoid\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr><th>Tag</th><th>Name hint</th><th>Selector</th></tr>\n </thead>\n <tbody>\n @for (m of a.missing; track $index) {\n <tr class=\"is-warning\">\n <td><code>{{ m.tag }}</code></td>\n <td>{{ m.nameHint }}</td>\n <td><code>{{ m.selector }}</code></td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n @if (a.duplicateCount === 0 && a.missingCount === 0) {\n <div class=\"sd-autoid-inspector__success-card\">\n <mat-icon>check_circle</mat-icon>\n <div>\n <strong>Kh\u00F4ng c\u00F3 element thi\u1EBFu ho\u1EB7c tr\u00F9ng autoid.</strong>\n <small>Trang \u0111\u00E3 \u0111\u1EA1t chu\u1EA9n convention autoid.</small>\n </div>\n </div>\n }\n }\n </ng-template>\n\n <ng-template #elementsTpl>\n @let _filter = filter();\n <div class=\"sd-autoid-inspector__filter\">\n <mat-icon>search</mat-icon>\n <input\n type=\"text\"\n placeholder=\"L\u1ECDc theo autoid / name / tag\"\n [ngModel]=\"_filter\"\n (ngModelChange)=\"filter.set($event)\"/>\n @if (_filter) {\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn\"\n matTooltip=\"Xo\u00E1 filter\"\n (click)=\"filter.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n\n <!-- Top-level elements (not inside any sd-table) -->\n <h4 class=\"sd-autoid-inspector__section-title\">\n Top-level elements\n <span class=\"sd-autoid-inspector__badge\">{{ topLevelElements().length }}</span>\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr>\n <th class=\"is-num\">STT</th>\n <th>Name</th>\n <th>Autoid</th>\n <th>Tag</th>\n <th>State</th>\n <th>Value</th>\n </tr>\n </thead>\n <tbody>\n @for (el of topLevelElements(); track el.autoid + $index) {\n <tr [class.is-error]=\"el.duplicate\">\n <td class=\"is-num\">{{ el.stt }}</td>\n <td>{{ el.name || '\u2014' }}</td>\n <td>\n <div class=\"sd-autoid-inspector__autoid-cell\">\n <code>{{ el.autoid }}</code>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn is-primary\"\n matTooltip=\"Copy xpath\"\n (click)=\"copyXpath(el.autoid)\">\n <mat-icon>content_copy</mat-icon>\n </button>\n </div>\n </td>\n <td><span class=\"sd-autoid-inspector__tag-chip\">{{ el.tag }}</span></td>\n <td class=\"sd-autoid-inspector__state-cell\">\n @if (el.state.disabled !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.disabled === 'true'\">\n disabled={{ el.state.disabled }}\n </span>\n }\n @if (el.state.loading !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.loading === 'true'\">\n loading={{ el.state.loading }}\n </span>\n }\n @if (el.state.empty !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.empty === 'true'\">\n empty={{ el.state.empty }}\n </span>\n }\n @if (el.state.invalid !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.invalid === 'true'\">\n invalid={{ el.state.invalid }}\n </span>\n }\n @if (el.state.opened !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.opened === 'true'\">\n opened={{ el.state.opened }}\n </span>\n }\n @if (el.state.count !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n count={{ el.state.count }}\n </span>\n }\n @if (el.state.required !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.required === 'true'\">\n required={{ el.state.required }}\n </span>\n }\n @if (el.state.maxlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n maxlength={{ el.state.maxlength }}\n </span>\n }\n @if (el.state.minlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n minlength={{ el.state.minlength }}\n </span>\n }\n @if (el.state.pattern !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n pattern={{ el.state.pattern }}\n </span>\n }\n @if (el.state.errorMessage !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-error\">\n error: {{ el.state.errorMessage }}\n </span>\n }\n </td>\n <td class=\"sd-autoid-inspector__value\" [matTooltip]=\"el.state.dataValue || el.text || ''\">\n {{ el.state.dataValue || el.text || '\u2014' }}\n </td>\n </tr>\n } @empty {\n <tr><td colspan=\"6\" class=\"sd-autoid-inspector__empty\">Kh\u00F4ng c\u00F3 k\u1EBFt qu\u1EA3.</td></tr>\n }\n </tbody>\n </table>\n </div>\n\n <!-- One section per sd-table group -->\n @for (group of tableGroups(); track group.scope) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-info\">table_chart</mat-icon>\n Inside <code>{{ group.scope }}</code>\n <span class=\"sd-autoid-inspector__badge\">{{ group.items.length }}</span>\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr>\n <th class=\"is-num\">STT</th>\n <th>Name</th>\n <th>Autoid</th>\n <th>Tag</th>\n <th>State</th>\n <th>Value</th>\n </tr>\n </thead>\n <tbody>\n @for (el of group.items; track el.autoid + $index) {\n <tr [class.is-error]=\"el.duplicate\">\n <td class=\"is-num\">{{ el.stt }}</td>\n <td>{{ el.name || '\u2014' }}</td>\n <td>\n <div class=\"sd-autoid-inspector__autoid-cell\">\n <code>{{ el.autoid }}</code>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn is-primary\"\n matTooltip=\"Copy xpath\"\n (click)=\"copyXpath(el.autoid)\">\n <mat-icon>content_copy</mat-icon>\n </button>\n </div>\n </td>\n <td><span class=\"sd-autoid-inspector__tag-chip\">{{ el.tag }}</span></td>\n <td class=\"sd-autoid-inspector__state-cell\">\n @if (el.state.disabled !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.disabled === 'true'\">\n disabled={{ el.state.disabled }}\n </span>\n }\n @if (el.state.loading !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.loading === 'true'\">\n loading={{ el.state.loading }}\n </span>\n }\n @if (el.state.empty !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.empty === 'true'\">\n empty={{ el.state.empty }}\n </span>\n }\n @if (el.state.invalid !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.invalid === 'true'\">\n invalid={{ el.state.invalid }}\n </span>\n }\n @if (el.state.opened !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.opened === 'true'\">\n opened={{ el.state.opened }}\n </span>\n }\n @if (el.state.count !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n count={{ el.state.count }}\n </span>\n }\n @if (el.state.required !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.required === 'true'\">\n required={{ el.state.required }}\n </span>\n }\n @if (el.state.maxlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n maxlength={{ el.state.maxlength }}\n </span>\n }\n @if (el.state.minlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n minlength={{ el.state.minlength }}\n </span>\n }\n @if (el.state.pattern !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n pattern={{ el.state.pattern }}\n </span>\n }\n @if (el.state.errorMessage !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-error\">\n error: {{ el.state.errorMessage }}\n </span>\n }\n </td>\n <td class=\"sd-autoid-inspector__value\" [matTooltip]=\"el.state.dataValue || el.text || ''\">\n {{ el.state.dataValue || el.text || '\u2014' }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </ng-template>\n\n <ng-template #exportTpl>\n <div class=\"sd-autoid-inspector__export-grid\">\n <button type=\"button\" matTooltip=\"Copy JSON v\u00E0o clipboard\" (click)=\"copyJson()\">\n <mat-icon>content_copy</mat-icon>\n <span>Copy JSON</span>\n <small>clipboard</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i file JSON\" (click)=\"exportJson()\">\n <mat-icon>download</mat-icon>\n <span>JSON</span>\n <small>.json</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i file CSV\" (click)=\"exportCsv()\">\n <mat-icon>table_view</mat-icon>\n <span>CSV</span>\n <small>.csv</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i MD POM skeleton \u2014 cho AI vi\u1EBFt auto-test\" (click)=\"exportMdPom()\">\n <mat-icon>code</mat-icon>\n <span>MD POM</span>\n <small>AI test</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i MD reference table \u2014 group theo tag sd-*\" (click)=\"exportMdTable()\">\n <mat-icon>view_list</mat-icon>\n <span>MD Table</span>\n <small>reference</small>\n </button>\n </div>\n </ng-template>\n}\n", styles: [":host{position:fixed;inset:auto 0 0 auto;z-index:100000;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-size:13px;color:var(--sd-black500, #212121)}.sd-autoid-inspector__fab-wrap{position:fixed;right:16px;bottom:16px;z-index:100000}.sd-autoid-inspector__fab-wrap:hover .sd-autoid-inspector__fab-dismiss{opacity:1;transform:scale(1);pointer-events:auto}.sd-autoid-inspector__fab{width:36px;height:36px;border-radius:50%;border:none;background:var(--sd-primary, #2A66F4);color:#fff;cursor:pointer;box-shadow:0 3px 10px #00000038;display:inline-flex;align-items:center;justify-content:center;transition:transform .15s ease,background .15s ease,box-shadow .15s ease}.sd-autoid-inspector__fab:hover{background:var(--sd-primary-dark, #1C4AD9);transform:scale(1.08);box-shadow:0 5px 14px #00000047}.sd-autoid-inspector__fab mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__fab-dismiss{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;border:1px solid var(--sd-black200, #E6E6E6);background:#fff;color:var(--sd-black400, #757575);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;opacity:0;transform:scale(.7);pointer-events:none;transition:opacity .12s ease,transform .12s ease,color .12s ease,background .12s ease;box-shadow:0 1px 4px #00000026}.sd-autoid-inspector__fab-dismiss:hover{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__fab-dismiss mat-icon{font-size:12px;width:12px;height:12px;line-height:12px}.sd-autoid-inspector__backdrop{position:fixed;inset:0;background:#00000052;z-index:100001;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.sd-autoid-inspector__panel{position:fixed;right:20px;bottom:80px;width:min(860px,100vw - 40px);max-height:calc(100vh - 110px);background:#fff;border-radius:12px;box-shadow:0 16px 48px #00000038;display:flex;flex-direction:column;z-index:100002;overflow:hidden;border:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__header{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--sd-black200, #E6E6E6);background:var(--sd-black100, #F2F2F2);flex-shrink:0}.sd-autoid-inspector__segments{display:inline-flex;border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;background:#fff;overflow:hidden}.sd-autoid-inspector__segments button{border:none;background:transparent;padding:5px 12px;cursor:pointer;font-size:12px;font-weight:500;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;gap:6px;border-right:1px solid var(--sd-black200, #E6E6E6);transition:background .12s ease,color .12s ease}.sd-autoid-inspector__segments button:last-child{border-right:none}.sd-autoid-inspector__segments button:hover:not(.is-active){background:var(--sd-black100, #F2F2F2);color:var(--sd-black500, #212121)}.sd-autoid-inspector__segments button.is-active{background:var(--sd-primary, #2A66F4);color:#fff}.sd-autoid-inspector__badge{background:var(--sd-black200, #E6E6E6);color:var(--sd-black500, #212121);border-radius:10px;padding:0 7px;font-size:11px;font-weight:600;line-height:16px}.is-active .sd-autoid-inspector__badge{background:#ffffff40;color:#fff}.sd-autoid-inspector__badge.is-warn{background:var(--sd-error, #F82C13);color:#fff}.sd-autoid-inspector__actions{display:inline-flex;gap:4px;margin-left:auto}.sd-autoid-inspector__icon-btn{border:none;background:transparent;cursor:pointer;padding:4px;border-radius:6px;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.sd-autoid-inspector__icon-btn:hover{background:var(--sd-black100, #F2F2F2);color:var(--sd-black500, #212121)}.sd-autoid-inspector__icon-btn.is-primary{color:var(--sd-primary, #2A66F4)}.sd-autoid-inspector__icon-btn.is-primary:hover{background:var(--sd-primary-light, #EAF1FF);color:var(--sd-primary-dark, #1C4AD9)}.sd-autoid-inspector__icon-btn mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__close-btn{border:none;cursor:pointer;padding:4px;border-radius:50%;width:28px;height:28px;background:transparent;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.sd-autoid-inspector__close-btn:hover{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E)}.sd-autoid-inspector__close-btn mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__body{padding:14px;overflow:auto;flex:1;background:#fff}.sd-autoid-inspector__toast{position:absolute;top:56px;right:14px;background:var(--sd-success, #4CAF50);color:#fff;padding:6px 12px;border-radius:6px;font-size:12px;z-index:2;box-shadow:0 4px 12px #0000002e}.sd-autoid-inspector__audit-toolbar{display:flex;justify-content:flex-end;margin-bottom:12px}.sd-autoid-inspector__toggle{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--sd-black200, #E6E6E6);background:#fff;border-radius:999px;padding:5px 12px 5px 10px;cursor:pointer;font-size:12px;font-weight:500;color:var(--sd-black400, #757575);transition:all .15s ease}.sd-autoid-inspector__toggle:hover{border-color:var(--sd-primary, #2A66F4);color:var(--sd-primary, #2A66F4)}.sd-autoid-inspector__toggle.is-on{border-color:var(--sd-primary, #2A66F4);color:var(--sd-primary, #2A66F4);background:var(--sd-primary-light, #EAF1FF)}.sd-autoid-inspector__toggle mat-icon{font-size:16px;width:16px;height:16px}.sd-autoid-inspector__toggle-state{font-size:10px;font-weight:700;padding:1px 7px;border-radius:999px;background:var(--sd-black200, #E6E6E6);color:var(--sd-black400, #757575)}.is-on .sd-autoid-inspector__toggle-state{background:var(--sd-primary, #2A66F4);color:#fff}.sd-autoid-inspector__summary{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:16px}.sd-autoid-inspector__stat{background:var(--sd-black100, #F2F2F2);border-radius:10px;padding:12px;text-align:center;border:1px solid transparent}.sd-autoid-inspector__stat.is-info{background:var(--sd-info-light, #E7E9FF);border-color:var(--sd-info, #2962FF)}.sd-autoid-inspector__stat.is-info .sd-autoid-inspector__stat-value{color:var(--sd-info, #2962FF)}.sd-autoid-inspector__stat.is-success{background:var(--sd-success-light, #DBEFDC);border-color:var(--sd-success, #4CAF50)}.sd-autoid-inspector__stat.is-success .sd-autoid-inspector__stat-value{color:var(--sd-success-dark, #39833C)}.sd-autoid-inspector__stat.is-warning{background:var(--sd-warning-light, #FFEACC);border-color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__stat.is-warning .sd-autoid-inspector__stat-value{color:var(--sd-warning-dark, #BF7000)}.sd-autoid-inspector__stat.is-error{background:var(--sd-error-light, #FED5D0);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__stat.is-error .sd-autoid-inspector__stat-value{color:var(--sd-error-dark, #BA200E)}.sd-autoid-inspector__stat-value{font-size:22px;font-weight:700;line-height:1;margin-bottom:4px}.sd-autoid-inspector__stat-label{font-size:11px;color:var(--sd-black400, #757575);text-transform:uppercase;letter-spacing:.4px;font-weight:600}.sd-autoid-inspector__section-title{display:flex;align-items:center;gap:6px;margin:14px 0 8px;font-size:13px;font-weight:600;color:var(--sd-black500, #212121)}.sd-autoid-inspector__section-title mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__section-title mat-icon.is-error{color:var(--sd-error, #F82C13)}.sd-autoid-inspector__section-title mat-icon.is-warning{color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__section-title mat-icon.is-info{color:var(--sd-info, #2962FF)}.sd-autoid-inspector__success-card{display:flex;align-items:center;gap:12px;padding:14px 16px;background:var(--sd-success-light, #DBEFDC);border:1px solid var(--sd-success, #4CAF50);border-radius:10px;color:var(--sd-success-dark, #39833C)}.sd-autoid-inspector__success-card mat-icon{font-size:28px;width:28px;height:28px;color:var(--sd-success, #4CAF50)}.sd-autoid-inspector__success-card strong{display:block;font-size:13px;margin-bottom:2px}.sd-autoid-inspector__success-card small{font-size:11px;opacity:.85}.sd-autoid-inspector__table-wrap{border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;overflow:auto;max-height:60vh;background:#fff}.sd-autoid-inspector__table{width:100%;border-collapse:separate;border-spacing:0;font-size:12px}.sd-autoid-inspector__table th,.sd-autoid-inspector__table td{padding:8px 10px;text-align:left;vertical-align:middle;border-bottom:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__table thead th{position:sticky;top:0;z-index:1;background:var(--sd-black100, #F2F2F2);font-weight:600;color:var(--sd-black500, #212121);text-transform:none;font-size:11px;letter-spacing:.3px;border-bottom:none;box-shadow:inset 0 -1px 0 var(--sd-black200, #E6E6E6),0 2px 4px #0000000a;white-space:nowrap}.sd-autoid-inspector__table thead th.is-num{text-align:right;width:50px}.sd-autoid-inspector__table tbody tr{transition:background .1s ease}.sd-autoid-inspector__table tbody tr:hover{background:var(--sd-primary-light, #EAF1FF)}.sd-autoid-inspector__table tbody tr:last-child td{border-bottom:none}.sd-autoid-inspector__table tbody tr.is-error{background:var(--sd-error-light, #FED5D0)}.sd-autoid-inspector__table tbody tr.is-error:hover{background:var(--sd-error-light, #FED5D0);filter:brightness(.98)}.sd-autoid-inspector__table tbody tr.is-warning{background:var(--sd-warning-light, #FFEACC)}.sd-autoid-inspector__table tbody tr.is-warning:hover{background:var(--sd-warning-light, #FFEACC);filter:brightness(.98)}.sd-autoid-inspector__table td.is-num{text-align:right;color:var(--sd-black400, #757575);font-variant-numeric:tabular-nums}.sd-autoid-inspector__table code{font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;background:var(--sd-black100, #F2F2F2);padding:2px 6px;border-radius:4px;color:var(--sd-primary-dark, #1C4AD9);border:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__autoid-cell{display:inline-flex;align-items:center;gap:6px}.sd-autoid-inspector__tag-chip{display:inline-block;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;background:var(--sd-info-light, #E7E9FF);color:var(--sd-info, #2962FF);border:1px solid var(--sd-info, #2962FF);padding:1px 8px;border-radius:999px;font-weight:500}.sd-autoid-inspector__value{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--sd-black400, #757575);font-style:italic}.sd-autoid-inspector__state-cell{display:flex;flex-wrap:wrap;gap:4px;align-items:center;min-width:0}.sd-autoid-inspector__state-chip{display:inline-block;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:10px;background:var(--sd-black100, #F2F2F2);color:var(--sd-black400, #757575);border:1px solid var(--sd-black200, #E6E6E6);padding:1px 6px;border-radius:999px;font-weight:500;white-space:nowrap}.sd-autoid-inspector__state-chip.is-error{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__state-chip.is-warning{background:var(--sd-warning-light, #FFEACC);color:var(--sd-warning-dark, #BF7000);border-color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__state-chip.is-info{background:var(--sd-info-light, #E7E9FF);color:var(--sd-info, #2962FF);border-color:var(--sd-info, #2962FF)}.sd-autoid-inspector__empty{text-align:center;color:var(--sd-black400, #757575);padding:24px;font-style:italic}.sd-autoid-inspector__filter{display:flex;align-items:center;gap:6px;background:var(--sd-black100, #F2F2F2);border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;padding:6px 10px;margin-bottom:12px;transition:border-color .15s ease}.sd-autoid-inspector__filter:focus-within{border-color:var(--sd-primary, #2A66F4);background:#fff}.sd-autoid-inspector__filter input{flex:1;border:none;background:transparent;outline:none;font-size:13px;color:var(--sd-black500, #212121)}.sd-autoid-inspector__filter input::placeholder{color:var(--sd-black300, #BFBFBF)}.sd-autoid-inspector__filter>mat-icon{font-size:18px;width:18px;height:18px;color:var(--sd-black400, #757575)}.sd-autoid-inspector__export-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px}.sd-autoid-inspector__export-grid button{border:1px solid var(--sd-black200, #E6E6E6);background:#fff;border-radius:10px;padding:12px 10px;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-width:0;transition:border-color .15s ease,background .15s ease,transform .12s ease;text-align:center}.sd-autoid-inspector__export-grid button:hover{border-color:var(--sd-primary, #2A66F4);background:var(--sd-primary-light, #EAF1FF);transform:translateY(-1px)}.sd-autoid-inspector__export-grid button span{font-size:12px;font-weight:600;color:var(--sd-black500, #212121);line-height:1.25}.sd-autoid-inspector__export-grid button small{font-size:10px;color:var(--sd-black400, #757575);line-height:1.2}.sd-autoid-inspector__export-grid button mat-icon{font-size:22px;width:22px;height:22px;color:var(--sd-primary, #2A66F4)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
796
796
|
}
|
|
797
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
797
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAutoidInspector, decorators: [{
|
|
798
798
|
type: Component,
|
|
799
799
|
args: [{ selector: 'sd-autoid-inspector', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormsModule, MatIconModule, MatTooltipModule], template: "@let _enabled = enabled();\n@let _open = open();\n@if (_enabled && !dismissed()) {\n <div class=\"sd-autoid-inspector__fab-wrap\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__fab\"\n data-autoid=\"sd-autoid-inspector-fab\"\n [attr.data-opened]=\"dataOpened()\"\n [matTooltip]=\"_open ? '\u0110\u00F3ng AutoId Inspector' : 'M\u1EDF AutoId Inspector'\"\n matTooltipPosition=\"left\"\n (click)=\"togglePanel()\">\n <mat-icon>{{ _open ? 'close' : 'tag' }}</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__fab-dismiss\"\n matTooltip=\"\u1EA8n t\u1EA1m \u2014 reload trang \u0111\u1EC3 hi\u1EC7n l\u1EA1i\"\n matTooltipPosition=\"left\"\n aria-label=\"\u1EA8n t\u1EA1m FAB\"\n (click)=\"dismissFab($event)\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n}\n\n@if (_enabled && _open) {\n @let _segment = segment();\n <div class=\"sd-autoid-inspector__backdrop\" (click)=\"closePanel()\"></div>\n <section class=\"sd-autoid-inspector__panel\"\n role=\"dialog\"\n aria-label=\"AutoId Inspector\"\n data-autoid=\"sd-autoid-inspector-panel\"\n [attr.data-segment]=\"dataSegment()\"\n [attr.data-highlight-on]=\"dataHighlightOn()\"\n [attr.data-element-count]=\"dataElementCount()\"\n [attr.data-missing-count]=\"dataMissingCount()\"\n [attr.data-duplicate-count]=\"dataDuplicateCount()\">\n <header class=\"sd-autoid-inspector__header\">\n <div class=\"sd-autoid-inspector__segments\">\n <button\n type=\"button\"\n [class.is-active]=\"_segment === 'audit'\"\n (click)=\"setSegment('audit')\">\n Audit\n @if (audit(); as a) {\n <span class=\"sd-autoid-inspector__badge\" [class.is-warn]=\"a.missingCount + a.duplicateCount > 0\">\n {{ a.missingCount + a.duplicateCount }}\n </span>\n }\n </button>\n <button\n type=\"button\"\n [class.is-active]=\"_segment === 'elements'\"\n (click)=\"setSegment('elements')\">\n Elements\n <span class=\"sd-autoid-inspector__badge\">{{ elements().length }}</span>\n </button>\n <button\n type=\"button\"\n [class.is-active]=\"_segment === 'export'\"\n (click)=\"setSegment('export')\">\n Export\n </button>\n </div>\n <div class=\"sd-autoid-inspector__actions\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn\"\n matTooltip=\"Qu\u00E9t l\u1EA1i\"\n (click)=\"refresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__close-btn\"\n matTooltip=\"\u0110\u00F3ng\"\n aria-label=\"\u0110\u00F3ng panel\"\n (click)=\"closePanel()\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </header>\n\n @if (copyOk()) {\n <div class=\"sd-autoid-inspector__toast\">\u0110\u00E3 copy \u2713</div>\n }\n\n <div class=\"sd-autoid-inspector__body\">\n @switch (_segment) {\n @case ('audit') {\n <ng-container *ngTemplateOutlet=\"auditTpl\"></ng-container>\n }\n @case ('elements') {\n <ng-container *ngTemplateOutlet=\"elementsTpl\"></ng-container>\n }\n @case ('export') {\n <ng-container *ngTemplateOutlet=\"exportTpl\"></ng-container>\n }\n }\n </div>\n </section>\n\n <ng-template #auditTpl>\n @if (audit(); as a) {\n @let _highlightOn = highlightOn();\n <div class=\"sd-autoid-inspector__audit-toolbar\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__toggle\"\n [class.is-on]=\"_highlightOn\"\n (click)=\"toggleHighlight()\">\n <mat-icon>{{ _highlightOn ? 'visibility' : 'visibility_off' }}</mat-icon>\n <span>Highlight DOM</span>\n <span class=\"sd-autoid-inspector__toggle-state\">{{ _highlightOn ? 'ON' : 'OFF' }}</span>\n </button>\n </div>\n <div class=\"sd-autoid-inspector__summary\">\n <div class=\"sd-autoid-inspector__stat is-info\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.total }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">T\u1ED5ng autoid</div>\n </div>\n <div class=\"sd-autoid-inspector__stat\" [class.is-error]=\"a.duplicateCount > 0\" [class.is-success]=\"a.duplicateCount === 0\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.duplicateCount }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">Tr\u00F9ng</div>\n </div>\n <div class=\"sd-autoid-inspector__stat\" [class.is-warning]=\"a.missingCount > 0\" [class.is-success]=\"a.missingCount === 0\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.missingCount }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">Thi\u1EBFu</div>\n </div>\n </div>\n\n @if (a.duplicateCount > 0) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-error\">error_outline</mat-icon>\n Autoid b\u1ECB tr\u00F9ng\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr><th>Autoid</th><th>S\u1ED1 l\u1EA7n</th></tr>\n </thead>\n <tbody>\n @for (entry of a.duplicates | keyvalue; track entry.key) {\n <tr class=\"is-error\">\n <td><code>{{ entry.key }}</code></td>\n <td>{{ entry.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n @if (a.missingCount > 0) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-warning\">warning_amber</mat-icon>\n Element thi\u1EBFu autoid\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr><th>Tag</th><th>Name hint</th><th>Selector</th></tr>\n </thead>\n <tbody>\n @for (m of a.missing; track $index) {\n <tr class=\"is-warning\">\n <td><code>{{ m.tag }}</code></td>\n <td>{{ m.nameHint }}</td>\n <td><code>{{ m.selector }}</code></td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n @if (a.duplicateCount === 0 && a.missingCount === 0) {\n <div class=\"sd-autoid-inspector__success-card\">\n <mat-icon>check_circle</mat-icon>\n <div>\n <strong>Kh\u00F4ng c\u00F3 element thi\u1EBFu ho\u1EB7c tr\u00F9ng autoid.</strong>\n <small>Trang \u0111\u00E3 \u0111\u1EA1t chu\u1EA9n convention autoid.</small>\n </div>\n </div>\n }\n }\n </ng-template>\n\n <ng-template #elementsTpl>\n @let _filter = filter();\n <div class=\"sd-autoid-inspector__filter\">\n <mat-icon>search</mat-icon>\n <input\n type=\"text\"\n placeholder=\"L\u1ECDc theo autoid / name / tag\"\n [ngModel]=\"_filter\"\n (ngModelChange)=\"filter.set($event)\"/>\n @if (_filter) {\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn\"\n matTooltip=\"Xo\u00E1 filter\"\n (click)=\"filter.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n\n <!-- Top-level elements (not inside any sd-table) -->\n <h4 class=\"sd-autoid-inspector__section-title\">\n Top-level elements\n <span class=\"sd-autoid-inspector__badge\">{{ topLevelElements().length }}</span>\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr>\n <th class=\"is-num\">STT</th>\n <th>Name</th>\n <th>Autoid</th>\n <th>Tag</th>\n <th>State</th>\n <th>Value</th>\n </tr>\n </thead>\n <tbody>\n @for (el of topLevelElements(); track el.autoid + $index) {\n <tr [class.is-error]=\"el.duplicate\">\n <td class=\"is-num\">{{ el.stt }}</td>\n <td>{{ el.name || '\u2014' }}</td>\n <td>\n <div class=\"sd-autoid-inspector__autoid-cell\">\n <code>{{ el.autoid }}</code>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn is-primary\"\n matTooltip=\"Copy xpath\"\n (click)=\"copyXpath(el.autoid)\">\n <mat-icon>content_copy</mat-icon>\n </button>\n </div>\n </td>\n <td><span class=\"sd-autoid-inspector__tag-chip\">{{ el.tag }}</span></td>\n <td class=\"sd-autoid-inspector__state-cell\">\n @if (el.state.disabled !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.disabled === 'true'\">\n disabled={{ el.state.disabled }}\n </span>\n }\n @if (el.state.loading !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.loading === 'true'\">\n loading={{ el.state.loading }}\n </span>\n }\n @if (el.state.empty !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.empty === 'true'\">\n empty={{ el.state.empty }}\n </span>\n }\n @if (el.state.invalid !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.invalid === 'true'\">\n invalid={{ el.state.invalid }}\n </span>\n }\n @if (el.state.opened !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.opened === 'true'\">\n opened={{ el.state.opened }}\n </span>\n }\n @if (el.state.count !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n count={{ el.state.count }}\n </span>\n }\n @if (el.state.required !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.required === 'true'\">\n required={{ el.state.required }}\n </span>\n }\n @if (el.state.maxlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n maxlength={{ el.state.maxlength }}\n </span>\n }\n @if (el.state.minlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n minlength={{ el.state.minlength }}\n </span>\n }\n @if (el.state.pattern !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n pattern={{ el.state.pattern }}\n </span>\n }\n @if (el.state.errorMessage !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-error\">\n error: {{ el.state.errorMessage }}\n </span>\n }\n </td>\n <td class=\"sd-autoid-inspector__value\" [matTooltip]=\"el.state.dataValue || el.text || ''\">\n {{ el.state.dataValue || el.text || '\u2014' }}\n </td>\n </tr>\n } @empty {\n <tr><td colspan=\"6\" class=\"sd-autoid-inspector__empty\">Kh\u00F4ng c\u00F3 k\u1EBFt qu\u1EA3.</td></tr>\n }\n </tbody>\n </table>\n </div>\n\n <!-- One section per sd-table group -->\n @for (group of tableGroups(); track group.scope) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-info\">table_chart</mat-icon>\n Inside <code>{{ group.scope }}</code>\n <span class=\"sd-autoid-inspector__badge\">{{ group.items.length }}</span>\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr>\n <th class=\"is-num\">STT</th>\n <th>Name</th>\n <th>Autoid</th>\n <th>Tag</th>\n <th>State</th>\n <th>Value</th>\n </tr>\n </thead>\n <tbody>\n @for (el of group.items; track el.autoid + $index) {\n <tr [class.is-error]=\"el.duplicate\">\n <td class=\"is-num\">{{ el.stt }}</td>\n <td>{{ el.name || '\u2014' }}</td>\n <td>\n <div class=\"sd-autoid-inspector__autoid-cell\">\n <code>{{ el.autoid }}</code>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn is-primary\"\n matTooltip=\"Copy xpath\"\n (click)=\"copyXpath(el.autoid)\">\n <mat-icon>content_copy</mat-icon>\n </button>\n </div>\n </td>\n <td><span class=\"sd-autoid-inspector__tag-chip\">{{ el.tag }}</span></td>\n <td class=\"sd-autoid-inspector__state-cell\">\n @if (el.state.disabled !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.disabled === 'true'\">\n disabled={{ el.state.disabled }}\n </span>\n }\n @if (el.state.loading !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.loading === 'true'\">\n loading={{ el.state.loading }}\n </span>\n }\n @if (el.state.empty !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.empty === 'true'\">\n empty={{ el.state.empty }}\n </span>\n }\n @if (el.state.invalid !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.invalid === 'true'\">\n invalid={{ el.state.invalid }}\n </span>\n }\n @if (el.state.opened !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.opened === 'true'\">\n opened={{ el.state.opened }}\n </span>\n }\n @if (el.state.count !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n count={{ el.state.count }}\n </span>\n }\n @if (el.state.required !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.required === 'true'\">\n required={{ el.state.required }}\n </span>\n }\n @if (el.state.maxlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n maxlength={{ el.state.maxlength }}\n </span>\n }\n @if (el.state.minlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n minlength={{ el.state.minlength }}\n </span>\n }\n @if (el.state.pattern !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n pattern={{ el.state.pattern }}\n </span>\n }\n @if (el.state.errorMessage !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-error\">\n error: {{ el.state.errorMessage }}\n </span>\n }\n </td>\n <td class=\"sd-autoid-inspector__value\" [matTooltip]=\"el.state.dataValue || el.text || ''\">\n {{ el.state.dataValue || el.text || '\u2014' }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </ng-template>\n\n <ng-template #exportTpl>\n <div class=\"sd-autoid-inspector__export-grid\">\n <button type=\"button\" matTooltip=\"Copy JSON v\u00E0o clipboard\" (click)=\"copyJson()\">\n <mat-icon>content_copy</mat-icon>\n <span>Copy JSON</span>\n <small>clipboard</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i file JSON\" (click)=\"exportJson()\">\n <mat-icon>download</mat-icon>\n <span>JSON</span>\n <small>.json</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i file CSV\" (click)=\"exportCsv()\">\n <mat-icon>table_view</mat-icon>\n <span>CSV</span>\n <small>.csv</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i MD POM skeleton \u2014 cho AI vi\u1EBFt auto-test\" (click)=\"exportMdPom()\">\n <mat-icon>code</mat-icon>\n <span>MD POM</span>\n <small>AI test</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i MD reference table \u2014 group theo tag sd-*\" (click)=\"exportMdTable()\">\n <mat-icon>view_list</mat-icon>\n <span>MD Table</span>\n <small>reference</small>\n </button>\n </div>\n </ng-template>\n}\n", styles: [":host{position:fixed;inset:auto 0 0 auto;z-index:100000;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-size:13px;color:var(--sd-black500, #212121)}.sd-autoid-inspector__fab-wrap{position:fixed;right:16px;bottom:16px;z-index:100000}.sd-autoid-inspector__fab-wrap:hover .sd-autoid-inspector__fab-dismiss{opacity:1;transform:scale(1);pointer-events:auto}.sd-autoid-inspector__fab{width:36px;height:36px;border-radius:50%;border:none;background:var(--sd-primary, #2A66F4);color:#fff;cursor:pointer;box-shadow:0 3px 10px #00000038;display:inline-flex;align-items:center;justify-content:center;transition:transform .15s ease,background .15s ease,box-shadow .15s ease}.sd-autoid-inspector__fab:hover{background:var(--sd-primary-dark, #1C4AD9);transform:scale(1.08);box-shadow:0 5px 14px #00000047}.sd-autoid-inspector__fab mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__fab-dismiss{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;border:1px solid var(--sd-black200, #E6E6E6);background:#fff;color:var(--sd-black400, #757575);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;opacity:0;transform:scale(.7);pointer-events:none;transition:opacity .12s ease,transform .12s ease,color .12s ease,background .12s ease;box-shadow:0 1px 4px #00000026}.sd-autoid-inspector__fab-dismiss:hover{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__fab-dismiss mat-icon{font-size:12px;width:12px;height:12px;line-height:12px}.sd-autoid-inspector__backdrop{position:fixed;inset:0;background:#00000052;z-index:100001;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.sd-autoid-inspector__panel{position:fixed;right:20px;bottom:80px;width:min(860px,100vw - 40px);max-height:calc(100vh - 110px);background:#fff;border-radius:12px;box-shadow:0 16px 48px #00000038;display:flex;flex-direction:column;z-index:100002;overflow:hidden;border:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__header{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--sd-black200, #E6E6E6);background:var(--sd-black100, #F2F2F2);flex-shrink:0}.sd-autoid-inspector__segments{display:inline-flex;border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;background:#fff;overflow:hidden}.sd-autoid-inspector__segments button{border:none;background:transparent;padding:5px 12px;cursor:pointer;font-size:12px;font-weight:500;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;gap:6px;border-right:1px solid var(--sd-black200, #E6E6E6);transition:background .12s ease,color .12s ease}.sd-autoid-inspector__segments button:last-child{border-right:none}.sd-autoid-inspector__segments button:hover:not(.is-active){background:var(--sd-black100, #F2F2F2);color:var(--sd-black500, #212121)}.sd-autoid-inspector__segments button.is-active{background:var(--sd-primary, #2A66F4);color:#fff}.sd-autoid-inspector__badge{background:var(--sd-black200, #E6E6E6);color:var(--sd-black500, #212121);border-radius:10px;padding:0 7px;font-size:11px;font-weight:600;line-height:16px}.is-active .sd-autoid-inspector__badge{background:#ffffff40;color:#fff}.sd-autoid-inspector__badge.is-warn{background:var(--sd-error, #F82C13);color:#fff}.sd-autoid-inspector__actions{display:inline-flex;gap:4px;margin-left:auto}.sd-autoid-inspector__icon-btn{border:none;background:transparent;cursor:pointer;padding:4px;border-radius:6px;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.sd-autoid-inspector__icon-btn:hover{background:var(--sd-black100, #F2F2F2);color:var(--sd-black500, #212121)}.sd-autoid-inspector__icon-btn.is-primary{color:var(--sd-primary, #2A66F4)}.sd-autoid-inspector__icon-btn.is-primary:hover{background:var(--sd-primary-light, #EAF1FF);color:var(--sd-primary-dark, #1C4AD9)}.sd-autoid-inspector__icon-btn mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__close-btn{border:none;cursor:pointer;padding:4px;border-radius:50%;width:28px;height:28px;background:transparent;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.sd-autoid-inspector__close-btn:hover{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E)}.sd-autoid-inspector__close-btn mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__body{padding:14px;overflow:auto;flex:1;background:#fff}.sd-autoid-inspector__toast{position:absolute;top:56px;right:14px;background:var(--sd-success, #4CAF50);color:#fff;padding:6px 12px;border-radius:6px;font-size:12px;z-index:2;box-shadow:0 4px 12px #0000002e}.sd-autoid-inspector__audit-toolbar{display:flex;justify-content:flex-end;margin-bottom:12px}.sd-autoid-inspector__toggle{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--sd-black200, #E6E6E6);background:#fff;border-radius:999px;padding:5px 12px 5px 10px;cursor:pointer;font-size:12px;font-weight:500;color:var(--sd-black400, #757575);transition:all .15s ease}.sd-autoid-inspector__toggle:hover{border-color:var(--sd-primary, #2A66F4);color:var(--sd-primary, #2A66F4)}.sd-autoid-inspector__toggle.is-on{border-color:var(--sd-primary, #2A66F4);color:var(--sd-primary, #2A66F4);background:var(--sd-primary-light, #EAF1FF)}.sd-autoid-inspector__toggle mat-icon{font-size:16px;width:16px;height:16px}.sd-autoid-inspector__toggle-state{font-size:10px;font-weight:700;padding:1px 7px;border-radius:999px;background:var(--sd-black200, #E6E6E6);color:var(--sd-black400, #757575)}.is-on .sd-autoid-inspector__toggle-state{background:var(--sd-primary, #2A66F4);color:#fff}.sd-autoid-inspector__summary{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:16px}.sd-autoid-inspector__stat{background:var(--sd-black100, #F2F2F2);border-radius:10px;padding:12px;text-align:center;border:1px solid transparent}.sd-autoid-inspector__stat.is-info{background:var(--sd-info-light, #E7E9FF);border-color:var(--sd-info, #2962FF)}.sd-autoid-inspector__stat.is-info .sd-autoid-inspector__stat-value{color:var(--sd-info, #2962FF)}.sd-autoid-inspector__stat.is-success{background:var(--sd-success-light, #DBEFDC);border-color:var(--sd-success, #4CAF50)}.sd-autoid-inspector__stat.is-success .sd-autoid-inspector__stat-value{color:var(--sd-success-dark, #39833C)}.sd-autoid-inspector__stat.is-warning{background:var(--sd-warning-light, #FFEACC);border-color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__stat.is-warning .sd-autoid-inspector__stat-value{color:var(--sd-warning-dark, #BF7000)}.sd-autoid-inspector__stat.is-error{background:var(--sd-error-light, #FED5D0);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__stat.is-error .sd-autoid-inspector__stat-value{color:var(--sd-error-dark, #BA200E)}.sd-autoid-inspector__stat-value{font-size:22px;font-weight:700;line-height:1;margin-bottom:4px}.sd-autoid-inspector__stat-label{font-size:11px;color:var(--sd-black400, #757575);text-transform:uppercase;letter-spacing:.4px;font-weight:600}.sd-autoid-inspector__section-title{display:flex;align-items:center;gap:6px;margin:14px 0 8px;font-size:13px;font-weight:600;color:var(--sd-black500, #212121)}.sd-autoid-inspector__section-title mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__section-title mat-icon.is-error{color:var(--sd-error, #F82C13)}.sd-autoid-inspector__section-title mat-icon.is-warning{color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__section-title mat-icon.is-info{color:var(--sd-info, #2962FF)}.sd-autoid-inspector__success-card{display:flex;align-items:center;gap:12px;padding:14px 16px;background:var(--sd-success-light, #DBEFDC);border:1px solid var(--sd-success, #4CAF50);border-radius:10px;color:var(--sd-success-dark, #39833C)}.sd-autoid-inspector__success-card mat-icon{font-size:28px;width:28px;height:28px;color:var(--sd-success, #4CAF50)}.sd-autoid-inspector__success-card strong{display:block;font-size:13px;margin-bottom:2px}.sd-autoid-inspector__success-card small{font-size:11px;opacity:.85}.sd-autoid-inspector__table-wrap{border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;overflow:auto;max-height:60vh;background:#fff}.sd-autoid-inspector__table{width:100%;border-collapse:separate;border-spacing:0;font-size:12px}.sd-autoid-inspector__table th,.sd-autoid-inspector__table td{padding:8px 10px;text-align:left;vertical-align:middle;border-bottom:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__table thead th{position:sticky;top:0;z-index:1;background:var(--sd-black100, #F2F2F2);font-weight:600;color:var(--sd-black500, #212121);text-transform:none;font-size:11px;letter-spacing:.3px;border-bottom:none;box-shadow:inset 0 -1px 0 var(--sd-black200, #E6E6E6),0 2px 4px #0000000a;white-space:nowrap}.sd-autoid-inspector__table thead th.is-num{text-align:right;width:50px}.sd-autoid-inspector__table tbody tr{transition:background .1s ease}.sd-autoid-inspector__table tbody tr:hover{background:var(--sd-primary-light, #EAF1FF)}.sd-autoid-inspector__table tbody tr:last-child td{border-bottom:none}.sd-autoid-inspector__table tbody tr.is-error{background:var(--sd-error-light, #FED5D0)}.sd-autoid-inspector__table tbody tr.is-error:hover{background:var(--sd-error-light, #FED5D0);filter:brightness(.98)}.sd-autoid-inspector__table tbody tr.is-warning{background:var(--sd-warning-light, #FFEACC)}.sd-autoid-inspector__table tbody tr.is-warning:hover{background:var(--sd-warning-light, #FFEACC);filter:brightness(.98)}.sd-autoid-inspector__table td.is-num{text-align:right;color:var(--sd-black400, #757575);font-variant-numeric:tabular-nums}.sd-autoid-inspector__table code{font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;background:var(--sd-black100, #F2F2F2);padding:2px 6px;border-radius:4px;color:var(--sd-primary-dark, #1C4AD9);border:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__autoid-cell{display:inline-flex;align-items:center;gap:6px}.sd-autoid-inspector__tag-chip{display:inline-block;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;background:var(--sd-info-light, #E7E9FF);color:var(--sd-info, #2962FF);border:1px solid var(--sd-info, #2962FF);padding:1px 8px;border-radius:999px;font-weight:500}.sd-autoid-inspector__value{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--sd-black400, #757575);font-style:italic}.sd-autoid-inspector__state-cell{display:flex;flex-wrap:wrap;gap:4px;align-items:center;min-width:0}.sd-autoid-inspector__state-chip{display:inline-block;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:10px;background:var(--sd-black100, #F2F2F2);color:var(--sd-black400, #757575);border:1px solid var(--sd-black200, #E6E6E6);padding:1px 6px;border-radius:999px;font-weight:500;white-space:nowrap}.sd-autoid-inspector__state-chip.is-error{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__state-chip.is-warning{background:var(--sd-warning-light, #FFEACC);color:var(--sd-warning-dark, #BF7000);border-color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__state-chip.is-info{background:var(--sd-info-light, #E7E9FF);color:var(--sd-info, #2962FF);border-color:var(--sd-info, #2962FF)}.sd-autoid-inspector__empty{text-align:center;color:var(--sd-black400, #757575);padding:24px;font-style:italic}.sd-autoid-inspector__filter{display:flex;align-items:center;gap:6px;background:var(--sd-black100, #F2F2F2);border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;padding:6px 10px;margin-bottom:12px;transition:border-color .15s ease}.sd-autoid-inspector__filter:focus-within{border-color:var(--sd-primary, #2A66F4);background:#fff}.sd-autoid-inspector__filter input{flex:1;border:none;background:transparent;outline:none;font-size:13px;color:var(--sd-black500, #212121)}.sd-autoid-inspector__filter input::placeholder{color:var(--sd-black300, #BFBFBF)}.sd-autoid-inspector__filter>mat-icon{font-size:18px;width:18px;height:18px;color:var(--sd-black400, #757575)}.sd-autoid-inspector__export-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px}.sd-autoid-inspector__export-grid button{border:1px solid var(--sd-black200, #E6E6E6);background:#fff;border-radius:10px;padding:12px 10px;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-width:0;transition:border-color .15s ease,background .15s ease,transform .12s ease;text-align:center}.sd-autoid-inspector__export-grid button:hover{border-color:var(--sd-primary, #2A66F4);background:var(--sd-primary-light, #EAF1FF);transform:translateY(-1px)}.sd-autoid-inspector__export-grid button span{font-size:12px;font-weight:600;color:var(--sd-black500, #212121);line-height:1.25}.sd-autoid-inspector__export-grid button small{font-size:10px;color:var(--sd-black400, #757575);line-height:1.2}.sd-autoid-inspector__export-grid button mat-icon{font-size:22px;width:22px;height:22px;color:var(--sd-primary, #2A66F4)}\n"] }]
|
|
800
800
|
}], propDecorators: { enabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "enabled", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], onEscape: [{
|
|
@@ -87,10 +87,10 @@ class SdAvatar {
|
|
|
87
87
|
}
|
|
88
88
|
return colors[Math.abs(hash) % colors.length];
|
|
89
89
|
};
|
|
90
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
91
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
90
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAvatar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
91
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdAvatar, isStandalone: true, selector: "sd-avatar", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@let _size = size();\n<div class=\"sd-avatar\" [style.width.px]=\"_size\" [style.height.px]=\"_size\" [style.line-height.px]=\"_size\" [style.backgroundColor]=\"bgColor()\">\n @if (isUrl()) {\n <img [src]=\"src()\" (error)=\"handleError()\" alt=\"avatar\" />\n } @else {\n <span class=\"sd-avatar-text\" [style.fontSize.px]=\"_size / 2.5\">\n {{ initials() }}\n </span>\n }\n</div>\n", styles: [".sd-avatar{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;overflow:hidden;color:#fff;font-weight:500;-webkit-user-select:none;user-select:none;background-size:cover}.sd-avatar img{width:100%;height:100%;object-fit:cover}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
92
92
|
}
|
|
93
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
93
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdAvatar, decorators: [{
|
|
94
94
|
type: Component,
|
|
95
95
|
args: [{ selector: 'sd-avatar', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let _size = size();\n<div class=\"sd-avatar\" [style.width.px]=\"_size\" [style.height.px]=\"_size\" [style.line-height.px]=\"_size\" [style.backgroundColor]=\"bgColor()\">\n @if (isUrl()) {\n <img [src]=\"src()\" (error)=\"handleError()\" alt=\"avatar\" />\n } @else {\n <span class=\"sd-avatar-text\" [style.fontSize.px]=\"_size / 2.5\">\n {{ initials() }}\n </span>\n }\n</div>\n", styles: [".sd-avatar{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;overflow:hidden;color:#fff;font-weight:500;-webkit-user-select:none;user-select:none;background-size:cover}.sd-avatar img{width:100%;height:100%;object-fit:cover}\n"] }]
|
|
96
96
|
}], ctorParameters: () => [], propDecorators: { src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
|