@memberjunction/ng-action-gallery 2.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # @memberjunction/ng-action-gallery
2
+
3
+ A beautiful, filterable gallery component for browsing and selecting actions in MemberJunction applications.
4
+
5
+ ## Overview
6
+
7
+ The Action Gallery provides an exceptional user experience for discovering, browsing, and selecting actions. It features both grid and list views, category navigation, and powerful search capabilities.
8
+
9
+ ## Features
10
+
11
+ - 🎨 Beautiful grid and list view modes
12
+ - 🌳 Hierarchical category navigation with counts
13
+ - 🔍 Real-time search filtering
14
+ - ✅ Single and multi-selection support
15
+ - 📇 Expandable action cards with details
16
+ - ⚡ Quick test integration
17
+ - 🎯 TypeScript support with full type safety
18
+ - 🌓 Light and dark theme support
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install @memberjunction/ng-action-gallery
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ### Module Import
29
+
30
+ ```typescript
31
+ import { ActionGalleryModule } from '@memberjunction/ng-action-gallery';
32
+
33
+ @NgModule({
34
+ imports: [
35
+ ActionGalleryModule,
36
+ // ... other imports
37
+ ]
38
+ })
39
+ export class YourModule { }
40
+ ```
41
+
42
+ ### Component Usage
43
+
44
+ #### Standalone Gallery
45
+
46
+ ```html
47
+ <mj-action-gallery
48
+ [config]="galleryConfig"
49
+ [preSelectedActions]="selectedIds"
50
+ (actionSelected)="onActionSelected($event)"
51
+ (actionsSelected)="onActionsSelected($event)"
52
+ (actionTestRequested)="onTestRequested($event)">
53
+ </mj-action-gallery>
54
+ ```
55
+
56
+ ```typescript
57
+ galleryConfig: ActionGalleryConfig = {
58
+ selectionMode: true,
59
+ multiSelect: true,
60
+ showCategories: true,
61
+ showSearch: true,
62
+ defaultView: 'grid',
63
+ gridColumns: 3,
64
+ enableQuickTest: true,
65
+ theme: 'light'
66
+ };
67
+
68
+ selectedIds = ['action-id-1', 'action-id-2'];
69
+
70
+ onActionSelected(action: ActionEntity) {
71
+ console.log('Selected action:', action);
72
+ }
73
+
74
+ onActionsSelected(actions: ActionEntity[]) {
75
+ console.log('Selected actions:', actions);
76
+ }
77
+ ```
78
+
79
+ #### Dialog Mode
80
+
81
+ ```typescript
82
+ import { ActionGalleryDialogService } from '@memberjunction/ng-action-gallery';
83
+
84
+ constructor(private actionGallery: ActionGalleryDialogService) {}
85
+
86
+ // Single selection
87
+ selectSingleAction() {
88
+ this.actionGallery.openForSingleSelection({
89
+ title: 'Select an Action',
90
+ showCategories: true,
91
+ enableQuickTest: true
92
+ }).subscribe(action => {
93
+ if (action) {
94
+ console.log('Selected:', action);
95
+ }
96
+ });
97
+ }
98
+
99
+ // Multi-selection
100
+ selectMultipleActions() {
101
+ this.actionGallery.openForMultiSelection({
102
+ title: 'Select Actions',
103
+ preSelectedActions: ['id1', 'id2'],
104
+ showCategories: true,
105
+ submitButtonText: 'Add Selected Actions'
106
+ }).subscribe(actions => {
107
+ console.log('Selected actions:', actions);
108
+ });
109
+ }
110
+
111
+ // Browse only (no selection)
112
+ browseActions() {
113
+ this.actionGallery.openForBrowsing({
114
+ title: 'Action Browser',
115
+ enableQuickTest: true
116
+ });
117
+ }
118
+ ```
119
+
120
+ ## Configuration
121
+
122
+ ### ActionGalleryConfig
123
+
124
+ | Property | Type | Default | Description |
125
+ |----------|------|---------|-------------|
126
+ | selectionMode | `boolean` | `false` | Enable selection mode |
127
+ | multiSelect | `boolean` | `false` | Allow multiple selections |
128
+ | showCategories | `boolean` | `true` | Show category sidebar |
129
+ | showSearch | `boolean` | `true` | Show search bar |
130
+ | defaultView | `'grid' \| 'list'` | `'grid'` | Default view mode |
131
+ | gridColumns | `number` | `3` | Number of grid columns |
132
+ | enableQuickTest | `boolean` | `true` | Show test buttons |
133
+ | theme | `'light' \| 'dark'` | `'light'` | Visual theme |
134
+
135
+ ### ActionGalleryDialogConfig
136
+
137
+ Extends `ActionGalleryConfig` with:
138
+
139
+ | Property | Type | Default | Description |
140
+ |----------|------|---------|-------------|
141
+ | title | `string` | `'Select Actions'` | Dialog title |
142
+ | width | `number` | `1200` | Dialog width |
143
+ | height | `number` | `800` | Dialog height |
144
+ | submitButtonText | `string` | `'Select'` | Submit button text |
145
+ | cancelButtonText | `string` | `'Cancel'` | Cancel button text |
146
+ | preSelectedActions | `string[]` | `[]` | Pre-selected action IDs |
147
+
148
+ ## Features in Detail
149
+
150
+ ### Category Navigation
151
+
152
+ The gallery displays a hierarchical category tree on the left side:
153
+ - Shows action counts per category
154
+ - Supports nested categories
155
+ - Collapsible/expandable nodes
156
+ - "All Actions" and "Uncategorized" special categories
157
+
158
+ ### Action Cards
159
+
160
+ Each action is displayed as an expandable card showing:
161
+ - Action name and icon
162
+ - Category badge
163
+ - Description
164
+ - Quick test button (if enabled)
165
+ - Expanded details:
166
+ - Parameters with types and required status
167
+ - Result codes with descriptions
168
+
169
+ ### Search and Filtering
170
+
171
+ Real-time search across:
172
+ - Action names
173
+ - Descriptions
174
+ - Categories
175
+
176
+ ### View Modes
177
+
178
+ **Grid View**: Visual cards in a responsive grid layout
179
+ **List View**: Compact table format for scanning many actions
180
+
181
+ ## Styling
182
+
183
+ The component uses CSS custom properties for theming:
184
+
185
+ ```scss
186
+ :root {
187
+ --gallery-primary: #007bff;
188
+ --gallery-hover: #0056b3;
189
+ --gallery-selected: #e3f2fd;
190
+ --gallery-background: #ffffff;
191
+ --gallery-text: #212529;
192
+ --gallery-border: #dee2e6;
193
+ }
194
+ ```
195
+
196
+ ## Integration with AI Test Harness
197
+
198
+ The Action Gallery integrates seamlessly with the AI Test Harness:
199
+
200
+ ```typescript
201
+ // In gallery configuration
202
+ enableQuickTest: true
203
+
204
+ // Handle test requests
205
+ onTestRequested(action: ActionEntity) {
206
+ this.testHarness.openForAction(action.ID).subscribe(result => {
207
+ console.log('Test result:', result);
208
+ });
209
+ }
210
+ ```
211
+
212
+ ## Performance
213
+
214
+ - Lazy loads action details on expansion
215
+ - Debounced search for smooth filtering
216
+ - Virtual scrolling ready for large datasets
217
+ - Efficient category tree rendering
218
+
219
+ ## Dependencies
220
+
221
+ - Angular 18.0.2+
222
+ - @memberjunction/core
223
+ - @memberjunction/core-entities
224
+ - @memberjunction/ng-ai-test-harness
225
+ - Kendo UI for Angular
226
+
227
+ ## License
228
+
229
+ ISC
230
+
231
+ ## Contributing
232
+
233
+ Contributions are welcome! Please submit pull requests to the MemberJunction repository.
234
+
235
+ ## Support
236
+
237
+ For issues and questions, please use the MemberJunction GitHub repository.
@@ -0,0 +1,53 @@
1
+ import { ViewContainerRef } from '@angular/core';
2
+ import { DialogService } from '@progress/kendo-angular-dialog';
3
+ import { ActionGalleryConfig } from './action-gallery.component';
4
+ import { ActionEntity } from '@memberjunction/core-entities';
5
+ import { Observable } from 'rxjs';
6
+ import * as i0 from "@angular/core";
7
+ export interface ActionGalleryDialogConfig extends ActionGalleryConfig {
8
+ title?: string;
9
+ width?: number;
10
+ height?: number;
11
+ minWidth?: number;
12
+ minHeight?: number;
13
+ submitButtonText?: string;
14
+ cancelButtonText?: string;
15
+ preSelectedActions?: string[];
16
+ }
17
+ export declare class ActionGalleryDialogService {
18
+ private dialogService;
19
+ private dialogRef;
20
+ constructor(dialogService: DialogService);
21
+ /**
22
+ * Opens the Action Gallery in a dialog for single selection
23
+ * @param config Configuration for the gallery
24
+ * @param viewContainerRef Optional ViewContainerRef for proper positioning
25
+ * @returns Observable that emits the selected action when confirmed
26
+ */
27
+ openForSingleSelection(config?: ActionGalleryDialogConfig, viewContainerRef?: ViewContainerRef): Observable<ActionEntity | null>;
28
+ /**
29
+ * Opens the Action Gallery in a dialog for multiple selection
30
+ * @param config Configuration for the gallery
31
+ * @param viewContainerRef Optional ViewContainerRef for proper positioning
32
+ * @returns Observable that emits the selected actions when confirmed
33
+ */
34
+ openForMultiSelection(config?: ActionGalleryDialogConfig, viewContainerRef?: ViewContainerRef): Observable<ActionEntity[]>;
35
+ /**
36
+ * Opens the Action Gallery in a dialog for browsing only (no selection)
37
+ * @param config Configuration for the gallery
38
+ * @param viewContainerRef Optional ViewContainerRef for proper positioning
39
+ */
40
+ openForBrowsing(config?: ActionGalleryDialogConfig, viewContainerRef?: ViewContainerRef): void;
41
+ /**
42
+ * Closes the currently open dialog
43
+ */
44
+ close(): void;
45
+ /**
46
+ * Checks if a dialog is currently open
47
+ */
48
+ isOpen(): boolean;
49
+ private openDialog;
50
+ static ɵfac: i0.ɵɵFactoryDeclaration<ActionGalleryDialogService, never>;
51
+ static ɵprov: i0.ɵɵInjectableDeclaration<ActionGalleryDialogService>;
52
+ }
53
+ //# sourceMappingURL=action-gallery-dialog.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-gallery-dialog.service.d.ts","sourceRoot":"","sources":["../../src/lib/action-gallery-dialog.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,aAAa,EAA6B,MAAM,gCAAgC,CAAC;AAC1F,OAAO,EAA0B,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;;AAE3C,MAAM,WAAW,yBAA0B,SAAQ,mBAAmB;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,qBAGa,0BAA0B;IAGzB,OAAO,CAAC,aAAa;IAFjC,OAAO,CAAC,SAAS,CAA0B;gBAEvB,aAAa,EAAE,aAAa;IAEhD;;;;;OAKG;IACH,sBAAsB,CACpB,MAAM,GAAE,yBAA8B,EACtC,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC;IA2BlC;;;;;OAKG;IACH,qBAAqB,CACnB,MAAM,GAAE,yBAA8B,EACtC,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,UAAU,CAAC,YAAY,EAAE,CAAC;IA2B7B;;;;OAIG;IACH,eAAe,CACb,MAAM,GAAE,yBAA8B,EACtC,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,IAAI;IAgCP;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB,OAAO,CAAC,UAAU;yCAtIP,0BAA0B;6CAA1B,0BAA0B;CAmKtC"}
@@ -0,0 +1,149 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { ActionGalleryComponent } from './action-gallery.component';
3
+ import { Subject } from 'rxjs';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@progress/kendo-angular-dialog";
6
+ export class ActionGalleryDialogService {
7
+ constructor(dialogService) {
8
+ this.dialogService = dialogService;
9
+ this.dialogRef = null;
10
+ }
11
+ /**
12
+ * Opens the Action Gallery in a dialog for single selection
13
+ * @param config Configuration for the gallery
14
+ * @param viewContainerRef Optional ViewContainerRef for proper positioning
15
+ * @returns Observable that emits the selected action when confirmed
16
+ */
17
+ openForSingleSelection(config = {}, viewContainerRef) {
18
+ const resultSubject = new Subject();
19
+ // Configure for single selection
20
+ const galleryConfig = {
21
+ ...config,
22
+ selectionMode: true,
23
+ multiSelect: false
24
+ };
25
+ this.openDialog(galleryConfig, viewContainerRef, (component) => {
26
+ // Handle dialog result
27
+ this.dialogRef.result.subscribe((result) => {
28
+ if (result && result.action === 'submit') {
29
+ const selectedActions = component.getSelectedActions();
30
+ resultSubject.next(selectedActions[0] || null);
31
+ }
32
+ else {
33
+ resultSubject.next(null);
34
+ }
35
+ resultSubject.complete();
36
+ this.dialogRef = null;
37
+ });
38
+ });
39
+ return resultSubject.asObservable();
40
+ }
41
+ /**
42
+ * Opens the Action Gallery in a dialog for multiple selection
43
+ * @param config Configuration for the gallery
44
+ * @param viewContainerRef Optional ViewContainerRef for proper positioning
45
+ * @returns Observable that emits the selected actions when confirmed
46
+ */
47
+ openForMultiSelection(config = {}, viewContainerRef) {
48
+ const resultSubject = new Subject();
49
+ // Configure for multi selection
50
+ const galleryConfig = {
51
+ ...config,
52
+ selectionMode: true,
53
+ multiSelect: true
54
+ };
55
+ this.openDialog(galleryConfig, viewContainerRef, (component) => {
56
+ // Handle dialog result
57
+ this.dialogRef.result.subscribe((result) => {
58
+ if (result && result.action === 'submit') {
59
+ const selectedActions = component.getSelectedActions();
60
+ resultSubject.next(selectedActions);
61
+ }
62
+ else {
63
+ resultSubject.next([]);
64
+ }
65
+ resultSubject.complete();
66
+ this.dialogRef = null;
67
+ });
68
+ });
69
+ return resultSubject.asObservable();
70
+ }
71
+ /**
72
+ * Opens the Action Gallery in a dialog for browsing only (no selection)
73
+ * @param config Configuration for the gallery
74
+ * @param viewContainerRef Optional ViewContainerRef for proper positioning
75
+ */
76
+ openForBrowsing(config = {}, viewContainerRef) {
77
+ const galleryConfig = {
78
+ ...config,
79
+ selectionMode: false,
80
+ enableQuickTest: true
81
+ };
82
+ const dialogSettings = {
83
+ title: config.title || 'Action Gallery',
84
+ width: config.width || 1200,
85
+ height: config.height || 800,
86
+ minWidth: config.minWidth || 800,
87
+ minHeight: config.minHeight || 600,
88
+ content: ActionGalleryComponent,
89
+ actions: [
90
+ { text: 'Close', themeColor: 'base' }
91
+ ],
92
+ preventAction: () => false
93
+ };
94
+ this.dialogRef = this.dialogService.open(dialogSettings);
95
+ // Configure the component
96
+ const component = this.dialogRef.content.instance;
97
+ component.config = galleryConfig;
98
+ // Handle dialog close
99
+ this.dialogRef.result.subscribe(() => {
100
+ this.dialogRef = null;
101
+ });
102
+ }
103
+ /**
104
+ * Closes the currently open dialog
105
+ */
106
+ close() {
107
+ if (this.dialogRef) {
108
+ this.dialogRef.close();
109
+ this.dialogRef = null;
110
+ }
111
+ }
112
+ /**
113
+ * Checks if a dialog is currently open
114
+ */
115
+ isOpen() {
116
+ return this.dialogRef !== null;
117
+ }
118
+ openDialog(config, viewContainerRef, resultHandler) {
119
+ const dialogSettings = {
120
+ title: config.title || 'Select Actions',
121
+ width: config.width || 1200,
122
+ height: config.height || 800,
123
+ minWidth: config.minWidth || 800,
124
+ minHeight: config.minHeight || 600,
125
+ content: ActionGalleryComponent,
126
+ actions: [
127
+ { text: config.cancelButtonText || 'Cancel' },
128
+ { text: config.submitButtonText || 'Select', themeColor: 'primary', action: 'submit' }
129
+ ],
130
+ preventAction: () => false
131
+ };
132
+ this.dialogRef = this.dialogService.open(dialogSettings);
133
+ // Configure the component
134
+ const component = this.dialogRef.content.instance;
135
+ component.config = config;
136
+ component.preSelectedActions = config.preSelectedActions || [];
137
+ // Handle result
138
+ resultHandler(component);
139
+ }
140
+ static { this.ɵfac = function ActionGalleryDialogService_Factory(t) { return new (t || ActionGalleryDialogService)(i0.ɵɵinject(i1.DialogService)); }; }
141
+ static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: ActionGalleryDialogService, factory: ActionGalleryDialogService.ɵfac, providedIn: 'root' }); }
142
+ }
143
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ActionGalleryDialogService, [{
144
+ type: Injectable,
145
+ args: [{
146
+ providedIn: 'root'
147
+ }]
148
+ }], () => [{ type: i1.DialogService }], null); })();
149
+ //# sourceMappingURL=action-gallery-dialog.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-gallery-dialog.service.js","sourceRoot":"","sources":["../../src/lib/action-gallery-dialog.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { EventEmitter, OnInit, OnDestroy, ElementRef } from '@angular/core';
2
+ import { FormControl } from '@angular/forms';
3
+ import { BehaviorSubject } from 'rxjs';
4
+ import { ActionEntity, ActionCategoryEntity, ActionParamEntity, ActionResultCodeEntity } from '@memberjunction/core-entities';
5
+ import * as i0 from "@angular/core";
6
+ export interface ActionGalleryConfig {
7
+ selectionMode?: boolean;
8
+ multiSelect?: boolean;
9
+ showCategories?: boolean;
10
+ showSearch?: boolean;
11
+ defaultView?: 'grid' | 'list';
12
+ gridColumns?: number;
13
+ enableQuickTest?: boolean;
14
+ theme?: 'light' | 'dark';
15
+ }
16
+ export interface CategoryNode {
17
+ id: string;
18
+ name: string;
19
+ parent?: string;
20
+ children?: CategoryNode[];
21
+ count?: number;
22
+ icon?: string;
23
+ }
24
+ export interface ActionWithDetails extends ActionEntity {
25
+ parameters?: ActionParamEntity[];
26
+ resultCodes?: ActionResultCodeEntity[];
27
+ expanded?: boolean;
28
+ selected?: boolean;
29
+ }
30
+ export declare class ActionGalleryComponent implements OnInit, OnDestroy {
31
+ config: ActionGalleryConfig;
32
+ preSelectedActions: string[];
33
+ actionSelected: EventEmitter<ActionEntity>;
34
+ actionsSelected: EventEmitter<ActionEntity[]>;
35
+ actionTestRequested: EventEmitter<ActionEntity>;
36
+ searchInput: ElementRef<HTMLInputElement>;
37
+ private destroy$;
38
+ actions$: BehaviorSubject<ActionWithDetails[]>;
39
+ categories$: BehaviorSubject<ActionCategoryEntity[]>;
40
+ filteredActions$: BehaviorSubject<ActionWithDetails[]>;
41
+ categoryTree$: BehaviorSubject<CategoryNode[]>;
42
+ selectedCategory$: BehaviorSubject<string>;
43
+ viewMode$: BehaviorSubject<"grid" | "list">;
44
+ isLoading$: BehaviorSubject<boolean>;
45
+ selectedActions$: BehaviorSubject<Set<string>>;
46
+ searchControl: FormControl<string | null>;
47
+ expandedCategories: Set<string>;
48
+ hoveredAction: string | null;
49
+ animateCards: boolean;
50
+ totalActions: number;
51
+ categoryCounts: Map<string, number>;
52
+ constructor();
53
+ ngOnInit(): void;
54
+ ngOnDestroy(): void;
55
+ loadData(): Promise<void>;
56
+ private buildCategoryTree;
57
+ private getCategoryIcon;
58
+ private filterActions;
59
+ private getCategoryName;
60
+ selectCategory(categoryId: string): void;
61
+ toggleCategoryExpanded(categoryId: string): void;
62
+ toggleViewMode(): void;
63
+ toggleActionExpanded(action: ActionWithDetails): Promise<void>;
64
+ loadActionDetails(action: ActionWithDetails): Promise<void>;
65
+ toggleActionSelection(action: ActionWithDetails): void;
66
+ testAction(action: ActionEntity, event: Event): void;
67
+ clearSearch(): void;
68
+ getSelectedActions(): ActionEntity[];
69
+ getActionIcon(action: ActionEntity): string;
70
+ static ɵfac: i0.ɵɵFactoryDeclaration<ActionGalleryComponent, never>;
71
+ static ɵcmp: i0.ɵɵComponentDeclaration<ActionGalleryComponent, "mj-action-gallery", never, { "config": { "alias": "config"; "required": false; }; "preSelectedActions": { "alias": "preSelectedActions"; "required": false; }; }, { "actionSelected": "actionSelected"; "actionsSelected": "actionsSelected"; "actionTestRequested": "actionTestRequested"; }, never, never, false, never>;
72
+ }
73
+ //# sourceMappingURL=action-gallery.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-gallery.component.d.ts","sourceRoot":"","sources":["../../src/lib/action-gallery.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAa,UAAU,EAAE,MAAM,eAAe,CAAC;AACjH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAW,eAAe,EAAgE,MAAM,MAAM,CAAC;AAE9G,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;;AAE9H,MAAM,WAAW,mBAAmB;IAClC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,qBAKa,sBAAuB,YAAW,MAAM,EAAE,SAAS;IACrD,MAAM,EAAE,mBAAmB,CASlC;IAEO,kBAAkB,EAAE,MAAM,EAAE,CAAM;IACjC,cAAc,6BAAoC;IAClD,eAAe,+BAAsC;IACrD,mBAAmB,6BAAoC;IAEpB,WAAW,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAGvF,OAAO,CAAC,QAAQ,CAAuB;IACvC,QAAQ,uCAAgD;IACxD,WAAW,0CAAmD;IAC9D,gBAAgB,uCAAgD;IAChE,aAAa,kCAA2C;IACxD,iBAAiB,0BAAsC;IACvD,SAAS,mCAAgD;IACzD,UAAU,2BAAuC;IACjD,gBAAgB,+BAA+C;IAG/D,aAAa,6BAAuB;IAGpC,kBAAkB,cAAqB;IACvC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IACpC,YAAY,UAAS;IAGrB,YAAY,SAAK;IACjB,cAAc,sBAA6B;;IAI3C,QAAQ;IAgCR,WAAW;IAKL,QAAQ;IAkDd,OAAO,CAAC,iBAAiB;IA4DzB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,aAAa;IA0BrB,OAAO,CAAC,eAAe;IAKvB,cAAc,CAAC,UAAU,EAAE,MAAM;IAIjC,sBAAsB,CAAC,UAAU,EAAE,MAAM;IAQzC,cAAc;IAKR,oBAAoB,CAAC,MAAM,EAAE,iBAAiB;IAS9C,iBAAiB,CAAC,MAAM,EAAE,iBAAiB;IAiCjD,qBAAqB,CAAC,MAAM,EAAE,iBAAiB;IAgC/C,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK;IAW7C,WAAW;IAOX,kBAAkB,IAAI,YAAY,EAAE;IAKpC,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM;yCAjWhC,sBAAsB;2CAAtB,sBAAsB;CAyXlC"}