@design-factory/angular 21.0.0-next.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/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright Amadeus SAS
2
+
3
+ Redistribution and use in source and binary forms, with or without modification,
4
+ are permitted provided that the following conditions are met:
5
+
6
+ 1. Redistributions of source code must retain the above copyright notice, this
7
+ list of conditions and the following disclaimer.
8
+
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation and/or
11
+ other materials provided with the distribution.
12
+
13
+ 3. Neither the name of the copyright holder nor the names of its contributors
14
+ may be used to endorse or promote products derived from this software without
15
+ specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
21
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ <h1 align="center">Amadeus Design Factory Angular implementation</h1>
2
+
3
+ TODO
@@ -0,0 +1,55 @@
1
+ import { provideDfComponentConfig, injectDfComponentConfig } from '@design-factory/angular/internals';
2
+ import * as i0 from '@angular/core';
3
+ import { ChangeDetectionStrategy, Component } from '@angular/core';
4
+
5
+ // the key of the accordion config in the global DF config
6
+ const ACCORDION_CONFIG_KEY = 'accordion';
7
+ /**
8
+ * Provides the configuration for the accordion component.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * \@Component({
13
+ * providers: [provideDfAccordionConfig({ closeOthers: true })]
14
+ * })
15
+ * export class MyHomeComponent {}
16
+ * ```
17
+ *
18
+ * @param config - Partial configuration or a function that receives the parent configuration and returns a partial configuration.
19
+ */
20
+ const provideDfAccordionConfig = provideDfComponentConfig(ACCORDION_CONFIG_KEY);
21
+ /**
22
+ * Injects the configuration for the accordion component.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * \@Component({
27
+ * providers: [provideDfAccordionConfig()]
28
+ * })
29
+ * export class MyAccordionComponent {
30
+ * readonly accordionConfig = injectDfAccordionConfig();
31
+ * }
32
+ * ```
33
+ *
34
+ * @returns A writable signal containing the accordion configuration.
35
+ */
36
+ const injectDfAccordionConfig = injectDfComponentConfig(ACCORDION_CONFIG_KEY);
37
+
38
+ class DfAccordionComponent {
39
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DfAccordionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
40
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: DfAccordionComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
41
+ }
42
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DfAccordionComponent, decorators: [{
43
+ type: Component,
44
+ args: [{
45
+ template: ``,
46
+ changeDetection: ChangeDetectionStrategy.OnPush
47
+ }]
48
+ }] });
49
+
50
+ /**
51
+ * Generated bundle index. Do not edit.
52
+ */
53
+
54
+ export { ACCORDION_CONFIG_KEY, DfAccordionComponent, injectDfAccordionConfig, provideDfAccordionConfig };
55
+ //# sourceMappingURL=design-factory-angular-accordion.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-factory-angular-accordion.mjs","sources":["../../accordion/accordion.config.ts","../../accordion/accordion.ts","../../accordion/design-factory-angular-accordion.ts"],"sourcesContent":["import { injectDfComponentConfig, provideDfComponentConfig } from '@design-factory/angular/internals';\n\n// TODO to fill\nexport type DfAccordionConfig = {\n /**\n * example prop\n */\n closeOthers: boolean;\n};\n\n// the key of the accordion config in the global DF config\nexport const ACCORDION_CONFIG_KEY = 'accordion' as const;\n\n/**\n * Provides the configuration for the accordion component.\n *\n * @example\n * ```ts\n * \\@Component({\n * providers: [provideDfAccordionConfig({ closeOthers: true })]\n * })\n * export class MyHomeComponent {}\n * ```\n *\n * @param config - Partial configuration or a function that receives the parent configuration and returns a partial configuration.\n */\nexport const provideDfAccordionConfig = provideDfComponentConfig<DfAccordionConfig>(ACCORDION_CONFIG_KEY);\n\n/**\n * Injects the configuration for the accordion component.\n *\n * @example\n * ```ts\n * \\@Component({\n * providers: [provideDfAccordionConfig()]\n * })\n * export class MyAccordionComponent {\n * readonly accordionConfig = injectDfAccordionConfig();\n * }\n * ```\n *\n * @returns A writable signal containing the accordion configuration.\n */\nexport const injectDfAccordionConfig = injectDfComponentConfig<DfAccordionConfig>(ACCORDION_CONFIG_KEY);\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\n\n@Component({\n template: ``,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class DfAccordionComponent {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAUA;AACO,MAAM,oBAAoB,GAAG;AAEpC;;;;;;;;;;;;AAYG;MACU,wBAAwB,GAAG,wBAAwB,CAAoB,oBAAoB;AAExG;;;;;;;;;;;;;;AAcG;MACU,uBAAuB,GAAG,uBAAuB,CAAoB,oBAAoB;;MCrCzF,oBAAoB,CAAA;8GAApB,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAApB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,oBAAoB,wEAHrB,CAAA,CAAE,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAGD,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAJhC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,CAAA,CAAE;oBACZ,eAAe,EAAE,uBAAuB,CAAC;AAC1C,iBAAA;;;ACLD;;AAEG;;;;"}
@@ -0,0 +1,22 @@
1
+ import { toAngularWritableSignal } from '@agnos-ui/angular-headless';
2
+ import '@design-factory/angular/accordion';
3
+ import { provideWidgetsConfig, injectWidgetsConfig } from '@design-factory/angular/internals';
4
+
5
+ /**
6
+ * TODO write clear and simple doc
7
+ */
8
+ const provideDfConfig = (config) => provideWidgetsConfig(typeof config === 'function' ? config : (parentConfig) => ({ ...parentConfig, ...(config ?? {}) }));
9
+ /**
10
+ * TODO write clear and simple doc
11
+ */
12
+ const injectDFConfig = () => {
13
+ const widgetsConfigStore = injectWidgetsConfig();
14
+ return toAngularWritableSignal(widgetsConfigStore.own$);
15
+ };
16
+
17
+ /**
18
+ * Generated bundle index. Do not edit.
19
+ */
20
+
21
+ export { injectDFConfig, provideDfConfig };
22
+ //# sourceMappingURL=design-factory-angular-config.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-factory-angular-config.mjs","sources":["../../config/config.ts","../../config/design-factory-angular-config.ts"],"sourcesContent":["import { toAngularWritableSignal, type WidgetsConfigStore, type Partial2Levels } from '@agnos-ui/angular-headless';\nimport type { FactoryProvider } from '@angular/core';\nimport { ACCORDION_CONFIG_KEY, DfAccordionConfig } from '@design-factory/angular/accordion';\nimport { provideWidgetsConfig, injectWidgetsConfig } from '@design-factory/angular/internals';\n\n/**\n * The configuration type for config-customizable DF components.\n */\nexport type DfConfig = {\n [ACCORDION_CONFIG_KEY]: DfAccordionConfig;\n};\n\n/**\n * TODO write clear and simple doc\n */\nexport const provideDfConfig = (\n config?: Partial2Levels<DfConfig> | ((parentConfig: Partial2Levels<DfConfig>) => Partial2Levels<DfConfig>)\n): FactoryProvider =>\n provideWidgetsConfig(\n typeof config === 'function' ? config : (parentConfig) => ({ ...parentConfig, ...(config ?? {}) })\n );\n\n/**\n * TODO write clear and simple doc\n */\nexport const injectDFConfig = () => {\n const widgetsConfigStore = injectWidgetsConfig() as WidgetsConfigStore<DfConfig>;\n return toAngularWritableSignal(widgetsConfigStore.own$);\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAYA;;AAEG;AACI,MAAM,eAAe,GAAG,CAC7B,MAA0G,KAE1G,oBAAoB,CAClB,OAAO,MAAM,KAAK,UAAU,GAAG,MAAM,GAAG,CAAC,YAAY,MAAM,EAAE,GAAG,YAAY,EAAE,IAAI,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;AAGtG;;AAEG;AACI,MAAM,cAAc,GAAG,MAAK;AACjC,IAAA,MAAM,kBAAkB,GAAG,mBAAmB,EAAkC;AAChF,IAAA,OAAO,uBAAuB,CAAC,kBAAkB,CAAC,IAAI,CAAC;AACzD;;AC5BA;;AAEG;;;;"}
@@ -0,0 +1,297 @@
1
+ import { createDrawer, createSimpleClassTransition, createNavManager, UseDirective, UseMultiDirective } from '@agnos-ui/angular-headless';
2
+ import { fadeTransition } from '@agnos-ui/core-bootstrap';
3
+ import { isPlatformBrowser } from '@angular/common';
4
+ import * as i0 from '@angular/core';
5
+ import { input, model, output, inject, PLATFORM_ID, booleanAttribute, linkedSignal, ChangeDetectionStrategy, Component } from '@angular/core';
6
+ import { toSignal } from '@angular/core/rxjs-interop';
7
+ import { AgnosWidgetDirective, callWidgetFactory } from '@design-factory/angular/internals';
8
+ import { DfMedia } from '@design-factory/design-factory';
9
+
10
+ /**
11
+ * Utility method to check if the user agent is a mobile device
12
+ *
13
+ * @param userAgent - The user agent string to check
14
+ * @returns `true` if the user agent corresponds to a mobile device, `false` otherwise
15
+ */
16
+ function isMobileUserAgent(userAgent) {
17
+ return /mobile|android|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
18
+ }
19
+ class DfDrawerComponent extends AgnosWidgetDirective {
20
+ constructor() {
21
+ const widget = callWidgetFactory(createDrawer, {
22
+ defaultConfig: {
23
+ className: '',
24
+ bodyScroll: true,
25
+ backdrop: false,
26
+ transition: createSimpleClassTransition({
27
+ showClasses: ['show']
28
+ }),
29
+ backdropTransition: fadeTransition
30
+ },
31
+ events: {
32
+ onSizeChange: (size) => {
33
+ this.size.set(size);
34
+ this.sizeChange.emit(size);
35
+ },
36
+ onVisibleChange: (visible) => {
37
+ this.visibleChange.emit(visible);
38
+ },
39
+ onMinimizedChange: (isMinimized) => {
40
+ this.minimizedChange.emit(isMinimized);
41
+ },
42
+ onMaximizedChange: (isMaximized) => {
43
+ this.maximizedChange.emit(isMaximized);
44
+ },
45
+ onResizingChange: (isResizing) => {
46
+ this.resizingChange.emit(isResizing);
47
+ }
48
+ }
49
+ });
50
+ super(widget);
51
+ /**
52
+ * CSS classes to be applied on the widget main container
53
+ *
54
+ * @defaultValue ``
55
+ */
56
+ this.className = input('', ...(ngDevMode ? [{ debugName: "className" }] : []));
57
+ /**
58
+ * If `true` allows body scrolling when the drawer is open.
59
+ *
60
+ * @defaultValue `false`
61
+ */
62
+ this.bodyScroll = input(false, ...(ngDevMode ? [{ debugName: "bodyScroll" }] : []));
63
+ /**
64
+ * If `true` displays the backdrop element and disables the body scrolling, otherwise the body of the document is navigable
65
+ *
66
+ * @defaultValue `true`
67
+ */
68
+ this.backdrop = input(true, ...(ngDevMode ? [{ debugName: "backdrop" }] : []));
69
+ /**
70
+ * Which element should contain the drawer and backdrop DOM elements.
71
+ * If it is not null, the drawer and backdrop DOM elements are moved to the specified container.
72
+ * Otherwise, they stay where the widget is located.
73
+ *
74
+ * @defaultValue
75
+ * ```ts
76
+ * typeof window !== 'undefined' ? document.body : null
77
+ * ```
78
+ */
79
+ this.container = input(null, ...(ngDevMode ? [{ debugName: "container" }] : []));
80
+ /**
81
+ * The size of the drawer in pixels.
82
+ *
83
+ * @defaultValue `300`
84
+ */
85
+ this.size = model(300, ...(ngDevMode ? [{ debugName: "size" }] : []));
86
+ /**
87
+ * If `true`, the drawer can be resized by the user.
88
+ *
89
+ * @defaultValue `false`
90
+ */
91
+ this.resizable = input(false, ...(ngDevMode ? [{ debugName: "resizable" }] : []));
92
+ /**
93
+ * If `true`, the drawer is shown; otherwise, it is hidden.
94
+ *
95
+ * @defaultValue `false`
96
+ */
97
+ this.visible = input(false, ...(ngDevMode ? [{ debugName: "visible" }] : []));
98
+ /**
99
+ * An event emitted when the width is changed.
100
+ *
101
+ * Event payload is equal to the newly selected width.
102
+ *
103
+ * @defaultValue
104
+ * ```ts
105
+ * () => {}
106
+ * ```
107
+ */
108
+ this.sizeChange = output();
109
+ /**
110
+ * Event to be triggered when the visible property changes.
111
+ *
112
+ * @param visible - new value of the visible propery
113
+ *
114
+ * @defaultValue
115
+ * ```ts
116
+ * () => {}
117
+ * ```
118
+ */
119
+ this.visibleChange = output();
120
+ /**
121
+ * Event to be triggered when the minimized state changes.
122
+ *
123
+ * @defaultValue
124
+ * ```ts
125
+ * () => {}
126
+ * ```
127
+ */
128
+ this.minimizedChange = output();
129
+ /**
130
+ * Event to be triggered when the maximized state changes.
131
+ *
132
+ * @defaultValue
133
+ * ```ts
134
+ * () => {}
135
+ * ```
136
+ */
137
+ this.maximizedChange = output();
138
+ /**
139
+ * Event to be triggered when the user start or stop moving the drawer.
140
+ *
141
+ * @defaultValue
142
+ * ```ts
143
+ * () => {}
144
+ * ```
145
+ */
146
+ this.resizingChange = output();
147
+ this.navManager = createNavManager();
148
+ this.navManagerConfig = {
149
+ keys: {
150
+ Home: this.navManager.focusFirst,
151
+ End: this.navManager.focusLast
152
+ }
153
+ };
154
+ /**
155
+ * Event to be triggered when the minimum size is reached.
156
+ *
157
+ * @defaultValue `null`
158
+ */
159
+ this.minSize = output();
160
+ /**
161
+ * Event to be triggered when the maximum size is reached.
162
+ *
163
+ * @defaultValue `null`
164
+ */
165
+ this.maxSize = output();
166
+ this.isSmallScreen = toSignal(inject(DfMedia).getObservable(['sm', 'xs']), { initialValue: false });
167
+ this.isMediumScreen = toSignal(inject(DfMedia).getObservable(['md']), { initialValue: false });
168
+ this.isLargeUpScreen = toSignal(inject(DfMedia).getObservable(['lg', 'xl', 'xxl', 'xxxl']), {
169
+ initialValue: false
170
+ });
171
+ this.isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
172
+ /**
173
+ * Flag to enable mobile device detection for responsive behavior
174
+ * @default true
175
+ */
176
+ this.enableMobile = input(true, { ...(ngDevMode ? { debugName: "enableMobile" } : {}), transform: booleanAttribute });
177
+ /**
178
+ * Flag to indicate if the drawer is minimized
179
+ */
180
+ this.isMinimized = linkedSignal(() => {
181
+ // in mobile devices, the default value is true (hiding the drawer) and does not track changes to the screen size
182
+ if (this.isMobileDevice) {
183
+ return true;
184
+ }
185
+ // in desktop, we track the large screen signal in order to reset the minimized state
186
+ // it allows resizing the window and have a more user-friendly behavior
187
+ return !this.isLargeUpScreen();
188
+ }, ...(ngDevMode ? [{ debugName: "isMinimized" }] : []));
189
+ this.isMobileDevice = (() => {
190
+ if (this.isBrowser) {
191
+ return this.enableMobile() && isMobileUserAgent(navigator.userAgent);
192
+ }
193
+ else {
194
+ // SSR: try to get request if available
195
+ try {
196
+ const request = inject(Request, { optional: true });
197
+ if (request && 'headers' in request) {
198
+ const userAgent = request.headers.get('user-agent') || '';
199
+ return this.enableMobile() && isMobileUserAgent(userAgent);
200
+ }
201
+ }
202
+ catch {
203
+ // Request token not available or not in SSR context
204
+ }
205
+ return false;
206
+ }
207
+ })();
208
+ }
209
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DfDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
210
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: DfDrawerComponent, isStandalone: true, selector: "df-drawer", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, bodyScroll: { classPropertyName: "bodyScroll", publicName: "bodyScroll", isSignal: true, isRequired: false, transformFunction: null }, backdrop: { classPropertyName: "backdrop", publicName: "backdrop", isSignal: true, isRequired: false, transformFunction: null }, container: { classPropertyName: "container", publicName: "container", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, enableMobile: { classPropertyName: "enableMobile", publicName: "enableMobile", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { size: "sizeChange", sizeChange: "sizeChange", visibleChange: "visibleChange", minimizedChange: "minimizedChange", maximizedChange: "maximizedChange", resizingChange: "resizingChange", minSize: "minSize", maxSize: "maxSize" }, usesInheritance: true, ngImport: i0, template: `
211
+ <div
212
+ class="df-drawer d-flex"
213
+ [class]="_agnosWidget.state.className()"
214
+ [class.show]="_agnosWidget.state.visible()"
215
+ [auUseMulti]="[_agnosWidget.directives.drawerPortalDirective, _agnosWidget.directives.drawerDirective]"
216
+ [style.--df-drawer-size]="size() !== null ? size() + 'px' : ''"
217
+ >
218
+ <ng-content />
219
+ @if (_agnosWidget.state.resizable()) {
220
+ <div class="df-drawer-splitter" tabindex="-1" [auUse]="_agnosWidget.directives.splitterDirective">
221
+ <button
222
+ #splitterHandle
223
+ class="btn btn-outline-primary df-btn-icononly df-drawer-splitter-handle"
224
+ [class.df-btn-outline-neutral-mirror]="isMediumScreen() && !isMinimized()"
225
+ i18n-aria-label="@@df.drawer.resize.ariaLabel"
226
+ aria-label="Resize drawer"
227
+ [auUse]="[navManager.directive, navManagerConfig]"
228
+ >
229
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 192 512" fill="currentColor">
230
+ <path
231
+ d="M16 32C7.2 32 0 39.2 0 48L0 464c0 8.8 7.2 16 16 16s16-7.2 16-16L32 48c0-8.8-7.2-16-16-16zm160 0c-8.8 0-16 7.2-16 16l0 416c0 8.8 7.2 16 16 16s16-7.2 16-16l0-416c0-8.8-7.2-16-16-16z"
232
+ />
233
+ </svg>
234
+ </button>
235
+ </div>
236
+ }
237
+ </div>
238
+ @if (!_agnosWidget.state.backdropHidden()) {
239
+ <div
240
+ class="df-drawer-backdrop"
241
+ [class.show]="_agnosWidget.state.visible()"
242
+ [auUseMulti]="[_agnosWidget.directives.backdropPortalDirective, _agnosWidget.directives.backdropDirective]"
243
+ ></div>
244
+ }
245
+ `, isInline: true, dependencies: [{ kind: "directive", type: UseDirective, selector: "[auUse]", inputs: ["auUse"] }, { kind: "directive", type: UseMultiDirective, selector: "[auUseMulti]", inputs: ["auUseMulti"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
246
+ }
247
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DfDrawerComponent, decorators: [{
248
+ type: Component,
249
+ args: [{
250
+ selector: 'df-drawer',
251
+ imports: [UseDirective, UseMultiDirective],
252
+ template: `
253
+ <div
254
+ class="df-drawer d-flex"
255
+ [class]="_agnosWidget.state.className()"
256
+ [class.show]="_agnosWidget.state.visible()"
257
+ [auUseMulti]="[_agnosWidget.directives.drawerPortalDirective, _agnosWidget.directives.drawerDirective]"
258
+ [style.--df-drawer-size]="size() !== null ? size() + 'px' : ''"
259
+ >
260
+ <ng-content />
261
+ @if (_agnosWidget.state.resizable()) {
262
+ <div class="df-drawer-splitter" tabindex="-1" [auUse]="_agnosWidget.directives.splitterDirective">
263
+ <button
264
+ #splitterHandle
265
+ class="btn btn-outline-primary df-btn-icononly df-drawer-splitter-handle"
266
+ [class.df-btn-outline-neutral-mirror]="isMediumScreen() && !isMinimized()"
267
+ i18n-aria-label="@@df.drawer.resize.ariaLabel"
268
+ aria-label="Resize drawer"
269
+ [auUse]="[navManager.directive, navManagerConfig]"
270
+ >
271
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 192 512" fill="currentColor">
272
+ <path
273
+ d="M16 32C7.2 32 0 39.2 0 48L0 464c0 8.8 7.2 16 16 16s16-7.2 16-16L32 48c0-8.8-7.2-16-16-16zm160 0c-8.8 0-16 7.2-16 16l0 416c0 8.8 7.2 16 16 16s16-7.2 16-16l0-416c0-8.8-7.2-16-16-16z"
274
+ />
275
+ </svg>
276
+ </button>
277
+ </div>
278
+ }
279
+ </div>
280
+ @if (!_agnosWidget.state.backdropHidden()) {
281
+ <div
282
+ class="df-drawer-backdrop"
283
+ [class.show]="_agnosWidget.state.visible()"
284
+ [auUseMulti]="[_agnosWidget.directives.backdropPortalDirective, _agnosWidget.directives.backdropDirective]"
285
+ ></div>
286
+ }
287
+ `,
288
+ changeDetection: ChangeDetectionStrategy.OnPush
289
+ }]
290
+ }], ctorParameters: () => [], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], bodyScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "bodyScroll", required: false }] }], backdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "backdrop", required: false }] }], container: [{ type: i0.Input, args: [{ isSignal: true, alias: "container", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }, { type: i0.Output, args: ["sizeChange"] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }], sizeChange: [{ type: i0.Output, args: ["sizeChange"] }], visibleChange: [{ type: i0.Output, args: ["visibleChange"] }], minimizedChange: [{ type: i0.Output, args: ["minimizedChange"] }], maximizedChange: [{ type: i0.Output, args: ["maximizedChange"] }], resizingChange: [{ type: i0.Output, args: ["resizingChange"] }], minSize: [{ type: i0.Output, args: ["minSize"] }], maxSize: [{ type: i0.Output, args: ["maxSize"] }], enableMobile: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableMobile", required: false }] }] } });
291
+
292
+ /**
293
+ * Generated bundle index. Do not edit.
294
+ */
295
+
296
+ export { DfDrawerComponent };
297
+ //# sourceMappingURL=design-factory-angular-drawer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-factory-angular-drawer.mjs","sources":["../../drawer/drawer.ts","../../drawer/design-factory-angular-drawer.ts"],"sourcesContent":["import type { DrawerWidget, NavManagerItemConfig } from '@agnos-ui/angular-headless';\nimport {\n createDrawer,\n createNavManager,\n createSimpleClassTransition,\n UseDirective,\n UseMultiDirective\n} from '@agnos-ui/angular-headless';\nimport { fadeTransition } from '@agnos-ui/core-bootstrap';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n inject,\n input,\n linkedSignal,\n model,\n output,\n PLATFORM_ID\n} from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { AgnosWidgetDirective, callWidgetFactory } from '@design-factory/angular/internals';\nimport { DfMedia } from '@design-factory/design-factory';\n\n/**\n * Utility method to check if the user agent is a mobile device\n *\n * @param userAgent - The user agent string to check\n * @returns `true` if the user agent corresponds to a mobile device, `false` otherwise\n */\nfunction isMobileUserAgent(userAgent: string): boolean {\n return /mobile|android|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent);\n}\n\n@Component({\n selector: 'df-drawer',\n imports: [UseDirective, UseMultiDirective],\n template: `\n <div\n class=\"df-drawer d-flex\"\n [class]=\"_agnosWidget.state.className()\"\n [class.show]=\"_agnosWidget.state.visible()\"\n [auUseMulti]=\"[_agnosWidget.directives.drawerPortalDirective, _agnosWidget.directives.drawerDirective]\"\n [style.--df-drawer-size]=\"size() !== null ? size() + 'px' : ''\"\n >\n <ng-content />\n @if (_agnosWidget.state.resizable()) {\n <div class=\"df-drawer-splitter\" tabindex=\"-1\" [auUse]=\"_agnosWidget.directives.splitterDirective\">\n <button\n #splitterHandle\n class=\"btn btn-outline-primary df-btn-icononly df-drawer-splitter-handle\"\n [class.df-btn-outline-neutral-mirror]=\"isMediumScreen() && !isMinimized()\"\n i18n-aria-label=\"@@df.drawer.resize.ariaLabel\"\n aria-label=\"Resize drawer\"\n [auUse]=\"[navManager.directive, navManagerConfig]\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 192 512\" fill=\"currentColor\">\n <path\n d=\"M16 32C7.2 32 0 39.2 0 48L0 464c0 8.8 7.2 16 16 16s16-7.2 16-16L32 48c0-8.8-7.2-16-16-16zm160 0c-8.8 0-16 7.2-16 16l0 416c0 8.8 7.2 16 16 16s16-7.2 16-16l0-416c0-8.8-7.2-16-16-16z\"\n />\n </svg>\n </button>\n </div>\n }\n </div>\n @if (!_agnosWidget.state.backdropHidden()) {\n <div\n class=\"df-drawer-backdrop\"\n [class.show]=\"_agnosWidget.state.visible()\"\n [auUseMulti]=\"[_agnosWidget.directives.backdropPortalDirective, _agnosWidget.directives.backdropDirective]\"\n ></div>\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class DfDrawerComponent extends AgnosWidgetDirective<DrawerWidget> {\n /**\n * CSS classes to be applied on the widget main container\n *\n * @defaultValue ``\n */\n readonly className = input<string>('');\n /**\n * If `true` allows body scrolling when the drawer is open.\n *\n * @defaultValue `false`\n */\n readonly bodyScroll = input<boolean>(false);\n /**\n * If `true` displays the backdrop element and disables the body scrolling, otherwise the body of the document is navigable\n *\n * @defaultValue `true`\n */\n readonly backdrop = input<boolean>(true);\n /**\n * Which element should contain the drawer and backdrop DOM elements.\n * If it is not null, the drawer and backdrop DOM elements are moved to the specified container.\n * Otherwise, they stay where the widget is located.\n *\n * @defaultValue\n * ```ts\n * typeof window !== 'undefined' ? document.body : null\n * ```\n */\n readonly container = input<HTMLElement | null>(null);\n /**\n * The size of the drawer in pixels.\n *\n * @defaultValue `300`\n */\n readonly size = model<number | null>(300);\n /**\n * If `true`, the drawer can be resized by the user.\n *\n * @defaultValue `false`\n */\n readonly resizable = input<boolean>(false);\n /**\n * If `true`, the drawer is shown; otherwise, it is hidden.\n *\n * @defaultValue `false`\n */\n readonly visible = input<boolean>(false);\n\n /**\n * An event emitted when the width is changed.\n *\n * Event payload is equal to the newly selected width.\n *\n * @defaultValue\n * ```ts\n * () => {}\n * ```\n */\n readonly sizeChange = output<number | null>();\n /**\n * Event to be triggered when the visible property changes.\n *\n * @param visible - new value of the visible propery\n *\n * @defaultValue\n * ```ts\n * () => {}\n * ```\n */\n readonly visibleChange = output<boolean>();\n\n /**\n * Event to be triggered when the minimized state changes.\n *\n * @defaultValue\n * ```ts\n * () => {}\n * ```\n */\n readonly minimizedChange = output<boolean>();\n\n /**\n * Event to be triggered when the maximized state changes.\n *\n * @defaultValue\n * ```ts\n * () => {}\n * ```\n */\n readonly maximizedChange = output<boolean>();\n\n /**\n * Event to be triggered when the user start or stop moving the drawer.\n *\n * @defaultValue\n * ```ts\n * () => {}\n * ```\n */\n readonly resizingChange = output<boolean>();\n\n protected readonly navManager = createNavManager();\n\n protected readonly navManagerConfig: NavManagerItemConfig = {\n keys: {\n Home: this.navManager.focusFirst,\n End: this.navManager.focusLast\n }\n };\n\n /**\n * Event to be triggered when the minimum size is reached.\n *\n * @defaultValue `null`\n */\n readonly minSize = output<void>();\n\n /**\n * Event to be triggered when the maximum size is reached.\n *\n * @defaultValue `null`\n */\n readonly maxSize = output<void>();\n\n protected readonly isSmallScreen = toSignal(inject(DfMedia).getObservable(['sm', 'xs']), { initialValue: false });\n protected readonly isMediumScreen = toSignal(inject(DfMedia).getObservable(['md']), { initialValue: false });\n protected readonly isLargeUpScreen = toSignal(inject(DfMedia).getObservable(['lg', 'xl', 'xxl', 'xxxl']), {\n initialValue: false\n });\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /**\n * Flag to enable mobile device detection for responsive behavior\n * @default true\n */\n readonly enableMobile = input(true, { transform: booleanAttribute });\n\n /**\n * Flag to indicate if the drawer is minimized\n */\n readonly isMinimized = linkedSignal(() => {\n // in mobile devices, the default value is true (hiding the drawer) and does not track changes to the screen size\n if (this.isMobileDevice) {\n return true;\n }\n // in desktop, we track the large screen signal in order to reset the minimized state\n // it allows resizing the window and have a more user-friendly behavior\n return !this.isLargeUpScreen();\n });\n\n protected readonly isMobileDevice = (() => {\n if (this.isBrowser) {\n return this.enableMobile() && isMobileUserAgent(navigator.userAgent);\n } else {\n // SSR: try to get request if available\n try {\n const request = inject(Request, { optional: true });\n if (request && 'headers' in request) {\n const userAgent = request.headers.get('user-agent') || '';\n return this.enableMobile() && isMobileUserAgent(userAgent);\n }\n } catch {\n // Request token not available or not in SSR context\n }\n return false;\n }\n })();\n\n constructor() {\n const widget = callWidgetFactory(createDrawer, {\n defaultConfig: {\n className: '',\n bodyScroll: true,\n backdrop: false,\n transition: createSimpleClassTransition({\n showClasses: ['show']\n }),\n backdropTransition: fadeTransition\n },\n events: {\n onSizeChange: (size) => {\n this.size.set(size);\n this.sizeChange.emit(size);\n },\n onVisibleChange: (visible) => {\n this.visibleChange.emit(visible);\n },\n onMinimizedChange: (isMinimized) => {\n this.minimizedChange.emit(isMinimized);\n },\n onMaximizedChange: (isMaximized) => {\n this.maximizedChange.emit(isMaximized);\n },\n onResizingChange: (isResizing) => {\n this.resizingChange.emit(isResizing);\n }\n }\n });\n super(widget);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ import { widgetsConfigFactory, createWidgetsConfig, toAngularWritableSignal } from '@agnos-ui/angular-headless';
2
+ import { asWritable, computed } from '@amadeus-it-group/tansu';
3
+ import * as i0 from '@angular/core';
4
+ import { InjectionToken, Directive } from '@angular/core';
5
+
6
+ const widgetFactories = widgetsConfigFactory(new InjectionToken('dfConfig', {
7
+ providedIn: 'root',
8
+ factory: () => createWidgetsConfig()
9
+ }));
10
+ const provideWidgetsConfig = widgetFactories.provideWidgetsConfig;
11
+ const injectWidgetsConfig = widgetFactories.injectWidgetsConfig;
12
+ /**
13
+ * Creates and initializes a widget using the provided factory and configuration options.
14
+ *
15
+ * The resulting widget can be easily hooked into the lifecycle of an Angular component through {@link BaseWidgetDirective}.
16
+ *
17
+ * @template W - The type of the widget.
18
+ * @param factory - The factory function to create the widget.
19
+ * @param options - The options for creating the widget.
20
+ * @param options.defaultConfig - The default configuration for the widget.
21
+ * @param options.events - The event handlers for the widget.
22
+ * @param options.slotTemplates - A function that returns the slot templates for the widget.
23
+ * @param options.slotChildren - A function that returns the slot children for the widget.
24
+ * @param options.afterInit - A callback function to be called after the widget is initialized.
25
+ * @returns The initialized widget.
26
+ */
27
+ const callWidgetFactory = widgetFactories.callWidgetFactory;
28
+ /**
29
+ * Utility to provide configuration for a specific DF component.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * export const provideDfCollapseConfig = provideDfComponentConfig<DfCollapseConfig>(COLLAPSE_CONFIG_KEY);
34
+ * ```
35
+ *
36
+ * @param componentKey the key of the component in the global configuration
37
+ * @returns the component config provider
38
+ */
39
+ const provideDfComponentConfig = (componentKey) => {
40
+ return (config) => {
41
+ const typedProvideWidgetsConfig = provideWidgetsConfig;
42
+ return typedProvideWidgetsConfig((prevConfig) => ({
43
+ ...prevConfig,
44
+ [componentKey]: {
45
+ ...(prevConfig?.[componentKey] ?? {}),
46
+ ...(typeof config === 'function' ? config(prevConfig?.[componentKey] ?? {}) : (config ?? {}))
47
+ }
48
+ }));
49
+ };
50
+ };
51
+ /**
52
+ * Utility to inject writable configuration for a specific DF component.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * export const injectDfCollapseConfig = injectDfComponentConfig<DfCollapseConfig>(COLLAPSE_CONFIG_KEY);
57
+ * ```
58
+ *
59
+ * @param componentKey the key of the component in the global configuration
60
+ * @returns the inject function that returns the writable component configuration
61
+ */
62
+ const injectDfComponentConfig = (componentKey) => () => {
63
+ const widgetsConfigStore = injectWidgetsConfig();
64
+ const componentConfigStore = asWritable(computed(() => widgetsConfigStore.own$()[componentKey] ?? {}), (newConfig) => {
65
+ widgetsConfigStore.own$.update((currentConfig) => ({ ...currentConfig, [componentKey]: newConfig }));
66
+ });
67
+ return toAngularWritableSignal(componentConfigStore);
68
+ };
69
+
70
+ /**
71
+ * An abstract base class for widget directives, providing common functionality
72
+ * for Angular components that interact with widgets.
73
+ *
74
+ * @template W - The type of the widget.
75
+ */
76
+ class AgnosWidgetDirective {
77
+ // eslint-disable-next-line @angular-eslint/prefer-inject
78
+ constructor(_agnosWidget) {
79
+ this._agnosWidget = _agnosWidget;
80
+ }
81
+ /** @internal */
82
+ ngOnChanges(changes) {
83
+ const patchData = {};
84
+ for (const [key, simpleChange] of Object.entries(changes)) {
85
+ if (simpleChange !== undefined) {
86
+ patchData[key] = simpleChange.currentValue;
87
+ }
88
+ }
89
+ this._agnosWidget.patch(patchData);
90
+ }
91
+ /** @internal */
92
+ ngOnInit() {
93
+ this._agnosWidget.ngInit();
94
+ }
95
+ /** @internal */
96
+ ngAfterContentChecked() {
97
+ this._agnosWidget.updateSlots();
98
+ }
99
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AgnosWidgetDirective, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive }); }
100
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.6", type: AgnosWidgetDirective, isStandalone: true, usesOnChanges: true, ngImport: i0 }); }
101
+ }
102
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AgnosWidgetDirective, decorators: [{
103
+ type: Directive
104
+ }], ctorParameters: () => [{ type: undefined }] });
105
+
106
+ /**
107
+ * Generated bundle index. Do not edit.
108
+ */
109
+
110
+ export { AgnosWidgetDirective, callWidgetFactory, injectDfComponentConfig, injectWidgetsConfig, provideDfComponentConfig, provideWidgetsConfig };
111
+ //# sourceMappingURL=design-factory-angular-internals.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-factory-angular-internals.mjs","sources":["../../internals/config.ts","../../internals/widget.directive.ts","../../internals/design-factory-angular-internals.ts"],"sourcesContent":["import type { WidgetsConfigStore } from '@agnos-ui/angular-headless';\nimport { createWidgetsConfig, toAngularWritableSignal, widgetsConfigFactory } from '@agnos-ui/angular-headless';\nimport { asWritable, computed, type ReadableSignal } from '@amadeus-it-group/tansu';\nimport type { FactoryProvider } from '@angular/core';\nimport { InjectionToken } from '@angular/core';\n\nconst widgetFactories = widgetsConfigFactory(\n new InjectionToken<WidgetsConfigStore<unknown>>('dfConfig', {\n providedIn: 'root',\n factory: () => createWidgetsConfig()\n })\n);\n\nexport const provideWidgetsConfig = widgetFactories.provideWidgetsConfig;\n\nexport const injectWidgetsConfig = widgetFactories.injectWidgetsConfig;\n\n/**\n * Creates and initializes a widget using the provided factory and configuration options.\n *\n * The resulting widget can be easily hooked into the lifecycle of an Angular component through {@link BaseWidgetDirective}.\n *\n * @template W - The type of the widget.\n * @param factory - The factory function to create the widget.\n * @param options - The options for creating the widget.\n * @param options.defaultConfig - The default configuration for the widget.\n * @param options.events - The event handlers for the widget.\n * @param options.slotTemplates - A function that returns the slot templates for the widget.\n * @param options.slotChildren - A function that returns the slot children for the widget.\n * @param options.afterInit - A callback function to be called after the widget is initialized.\n * @returns The initialized widget.\n */\nexport const callWidgetFactory = widgetFactories.callWidgetFactory;\n\n/**\n * Utility to provide configuration for a specific DF component.\n *\n * @example\n * ```typescript\n * export const provideDfCollapseConfig = provideDfComponentConfig<DfCollapseConfig>(COLLAPSE_CONFIG_KEY);\n * ```\n *\n * @param componentKey the key of the component in the global configuration\n * @returns the component config provider\n */\nexport const provideDfComponentConfig = <T>(componentKey: string) => {\n return (config?: Partial<T> | ((prevConfig: Partial<T>) => Partial<T>)) => {\n const typedProvideWidgetsConfig = provideWidgetsConfig as (\n adaptParentConfig?: (parentConfig: { [componentKey]?: Partial<T> }) => { [componentKey]?: Partial<T> }\n ) => FactoryProvider;\n return typedProvideWidgetsConfig((prevConfig) => ({\n ...prevConfig,\n [componentKey]: {\n ...(prevConfig?.[componentKey] ?? {}),\n ...(typeof config === 'function' ? config(prevConfig?.[componentKey] ?? {}) : (config ?? {}))\n }\n }));\n };\n};\n\n/**\n * Utility to inject writable configuration for a specific DF component.\n *\n * @example\n * ```typescript\n * export const injectDfCollapseConfig = injectDfComponentConfig<DfCollapseConfig>(COLLAPSE_CONFIG_KEY);\n * ```\n *\n * @param componentKey the key of the component in the global configuration\n * @returns the inject function that returns the writable component configuration\n */\nexport const injectDfComponentConfig =\n <T>(componentKey: string) =>\n () => {\n const widgetsConfigStore = injectWidgetsConfig() as WidgetsConfigStore<{ [componentKey]?: Partial<T> }>;\n const componentConfigStore = asWritable(\n computed(() => widgetsConfigStore.own$()[componentKey] ?? {}) as ReadableSignal<Partial<T>>,\n (newConfig: Partial<T>) => {\n widgetsConfigStore.own$.update((currentConfig) => ({ ...currentConfig, [componentKey]: newConfig }));\n }\n );\n return toAngularWritableSignal(componentConfigStore);\n };\n","import { AngularWidget, Widget } from '@agnos-ui/angular-headless';\nimport { AfterContentChecked, Directive, OnChanges, OnInit, SimpleChanges } from '@angular/core';\n\n/**\n * An abstract base class for widget directives, providing common functionality\n * for Angular components that interact with widgets.\n *\n * @template W - The type of the widget.\n */\n@Directive()\nexport abstract class AgnosWidgetDirective<W extends Widget> implements OnChanges, OnInit, AfterContentChecked {\n // eslint-disable-next-line @angular-eslint/prefer-inject\n constructor(protected readonly _agnosWidget: AngularWidget<W>) {}\n\n /** @internal */\n ngOnChanges(changes: SimpleChanges): void {\n const patchData: any = {};\n for (const [key, simpleChange] of Object.entries(changes)) {\n if (simpleChange !== undefined) {\n patchData[key] = simpleChange.currentValue;\n }\n }\n this._agnosWidget.patch(patchData);\n }\n\n /** @internal */\n ngOnInit(): void {\n this._agnosWidget.ngInit();\n }\n\n /** @internal */\n ngAfterContentChecked(): void {\n this._agnosWidget.updateSlots();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAMA,MAAM,eAAe,GAAG,oBAAoB,CAC1C,IAAI,cAAc,CAA8B,UAAU,EAAE;AAC1D,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,mBAAmB;AACnC,CAAA,CAAC,CACH;AAEM,MAAM,oBAAoB,GAAG,eAAe,CAAC;AAE7C,MAAM,mBAAmB,GAAG,eAAe,CAAC;AAEnD;;;;;;;;;;;;;;AAcG;AACI,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAEjD;;;;;;;;;;AAUG;AACI,MAAM,wBAAwB,GAAG,CAAI,YAAoB,KAAI;IAClE,OAAO,CAAC,MAA8D,KAAI;QACxE,MAAM,yBAAyB,GAAG,oBAEd;AACpB,QAAA,OAAO,yBAAyB,CAAC,CAAC,UAAU,MAAM;AAChD,YAAA,GAAG,UAAU;YACb,CAAC,YAAY,GAAG;gBACd,IAAI,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;gBACrC,IAAI,OAAO,MAAM,KAAK,UAAU,GAAG,MAAM,CAAC,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,IAAI,MAAM,IAAI,EAAE,CAAC;AAC7F;AACF,SAAA,CAAC,CAAC;AACL,IAAA,CAAC;AACH;AAEA;;;;;;;;;;AAUG;AACI,MAAM,uBAAuB,GAClC,CAAI,YAAoB,KACxB,MAAK;AACH,IAAA,MAAM,kBAAkB,GAAG,mBAAmB,EAAyD;IACvG,MAAM,oBAAoB,GAAG,UAAU,CACrC,QAAQ,CAAC,MAAM,kBAAkB,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,CAA+B,EAC3F,CAAC,SAAqB,KAAI;QACxB,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,aAAa,MAAM,EAAE,GAAG,aAAa,EAAE,CAAC,YAAY,GAAG,SAAS,EAAE,CAAC,CAAC;AACtG,IAAA,CAAC,CACF;AACD,IAAA,OAAO,uBAAuB,CAAC,oBAAoB,CAAC;AACtD;;AC/EF;;;;;AAKG;MAEmB,oBAAoB,CAAA;;AAExC,IAAA,WAAA,CAA+B,YAA8B,EAAA;QAA9B,IAAA,CAAA,YAAY,GAAZ,YAAY;IAAqB;;AAGhE,IAAA,WAAW,CAAC,OAAsB,EAAA;QAChC,MAAM,SAAS,GAAQ,EAAE;AACzB,QAAA,KAAK,MAAM,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;AACzD,YAAA,IAAI,YAAY,KAAK,SAAS,EAAE;AAC9B,gBAAA,SAAS,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,YAAY;YAC5C;QACF;AACA,QAAA,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC;IACpC;;IAGA,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;IAC5B;;IAGA,qBAAqB,GAAA;AACnB,QAAA,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE;IACjC;8GAvBoB,oBAAoB,EAAA,IAAA,EAAA,SAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAApB,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA,CAAA;;2FAApB,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBADzC;;;ACTD;;AAEG;;;;"}