@angular/cdk-experimental 20.2.0-next.3 → 20.2.0-rc.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/fesm2022/accordion.mjs +12 -12
- package/fesm2022/accordion.mjs.map +1 -1
- package/fesm2022/accordion2.mjs.map +1 -1
- package/fesm2022/cdk-experimental.mjs +1 -1
- package/fesm2022/cdk-experimental.mjs.map +1 -1
- package/fesm2022/column-resize.mjs +53 -53
- package/fesm2022/column-resize.mjs.map +1 -1
- package/fesm2022/combobox.mjs +10 -10
- package/fesm2022/combobox.mjs.map +1 -1
- package/fesm2022/deferred-content.mjs +6 -6
- package/fesm2022/deferred-content.mjs.map +1 -1
- package/fesm2022/expansion.mjs.map +1 -1
- package/fesm2022/list-navigation.mjs +6 -2
- package/fesm2022/list-navigation.mjs.map +1 -1
- package/fesm2022/list.mjs.map +1 -1
- package/fesm2022/listbox.mjs +6 -6
- package/fesm2022/listbox.mjs.map +1 -1
- package/fesm2022/option.mjs.map +1 -1
- package/fesm2022/polyfill.mjs.map +1 -1
- package/fesm2022/popover-edit.mjs +43 -43
- package/fesm2022/popover-edit.mjs.map +1 -1
- package/fesm2022/radio-group.mjs +41 -8
- package/fesm2022/radio-group.mjs.map +1 -1
- package/fesm2022/{radio-button.mjs → radio-group2.mjs} +17 -40
- package/fesm2022/radio-group2.mjs.map +1 -0
- package/fesm2022/scrolling.mjs +7 -7
- package/fesm2022/scrolling.mjs.map +1 -1
- package/fesm2022/selection.mjs +19 -19
- package/fesm2022/selection.mjs.map +1 -1
- package/fesm2022/table-scroll-container.mjs +7 -7
- package/fesm2022/table-scroll-container.mjs.map +1 -1
- package/fesm2022/tabs.mjs +15 -15
- package/fesm2022/tabs.mjs.map +1 -1
- package/fesm2022/tabs2.mjs.map +1 -1
- package/fesm2022/toolbar.mjs +168 -0
- package/fesm2022/toolbar.mjs.map +1 -0
- package/fesm2022/toolbar2.mjs +224 -0
- package/fesm2022/toolbar2.mjs.map +1 -0
- package/fesm2022/tree.mjs +65 -72
- package/fesm2022/tree.mjs.map +1 -1
- package/fesm2022/ui-patterns.mjs +2 -1
- package/fesm2022/ui-patterns.mjs.map +1 -1
- package/package.json +6 -2
- package/radio-group/index.d.ts +12 -4
- package/radio-group.d.d.ts +30 -45
- package/toolbar/index.d.ts +89 -0
- package/toolbar.d.d.ts +136 -0
- package/tree/index.d.ts +18 -24
- package/ui-patterns/index.d.ts +2 -1
- package/fesm2022/radio-button.mjs.map +0 -1
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { signal, inject, computed, input, booleanAttribute, afterRenderEffect, Directive, ElementRef } from '@angular/core';
|
|
3
|
+
import { Directionality } from '@angular/cdk/bidi';
|
|
4
|
+
import { _IdGenerator } from '@angular/cdk/a11y';
|
|
5
|
+
import { ToolbarPattern, ToolbarWidgetPattern } from './toolbar2.mjs';
|
|
6
|
+
import './list.mjs';
|
|
7
|
+
import './list-navigation.mjs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Sort directives by their document order.
|
|
11
|
+
*/
|
|
12
|
+
function sortDirectives(a, b) {
|
|
13
|
+
return (a.element().compareDocumentPosition(b.element()) & Node.DOCUMENT_POSITION_PRECEDING) > 0
|
|
14
|
+
? 1
|
|
15
|
+
: -1;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A toolbar widget container.
|
|
19
|
+
*
|
|
20
|
+
* Widgets such as radio groups or buttons are nested within a toolbar to allow for a single
|
|
21
|
+
* place of reference for focus and navigation. The CdkToolbar is meant to be used in conjunction
|
|
22
|
+
* with CdkToolbarWidget and CdkRadioGroup as follows:
|
|
23
|
+
*
|
|
24
|
+
* ```html
|
|
25
|
+
* <div cdkToolbar>
|
|
26
|
+
* <button cdkToolbarWidget>Button</button>
|
|
27
|
+
* <div cdkRadioGroup>
|
|
28
|
+
* <label cdkRadioButton value="1">Option 1</label>
|
|
29
|
+
* <label cdkRadioButton value="2">Option 2</label>
|
|
30
|
+
* <label cdkRadioButton value="3">Option 3</label>
|
|
31
|
+
* </div>
|
|
32
|
+
* </div>
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
class CdkToolbar {
|
|
36
|
+
/** The CdkTabList nested inside of the container. */
|
|
37
|
+
_cdkWidgets = signal(new Set(), ...(ngDevMode ? [{ debugName: "_cdkWidgets" }] : []));
|
|
38
|
+
/** A signal wrapper for directionality. */
|
|
39
|
+
textDirection = inject(Directionality).valueSignal;
|
|
40
|
+
/** Sorted UIPatterns of the child widgets */
|
|
41
|
+
items = computed(() => [...this._cdkWidgets()].sort(sortDirectives).map(widget => widget.pattern), ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
42
|
+
/** Whether the toolbar is vertically or horizontally oriented. */
|
|
43
|
+
orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : []));
|
|
44
|
+
/** Whether disabled items in the group should be skipped when navigating. */
|
|
45
|
+
skipDisabled = input(false, ...(ngDevMode ? [{ debugName: "skipDisabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
46
|
+
/** Whether the toolbar is disabled. */
|
|
47
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
48
|
+
/** Whether focus should wrap when navigating. */
|
|
49
|
+
wrap = input(true, ...(ngDevMode ? [{ debugName: "wrap", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
50
|
+
/** The toolbar UIPattern. */
|
|
51
|
+
pattern = new ToolbarPattern({
|
|
52
|
+
...this,
|
|
53
|
+
activeItem: signal(undefined),
|
|
54
|
+
textDirection: this.textDirection,
|
|
55
|
+
focusMode: signal('roving'),
|
|
56
|
+
});
|
|
57
|
+
/** Whether the toolbar has received focus yet. */
|
|
58
|
+
_hasFocused = signal(false, ...(ngDevMode ? [{ debugName: "_hasFocused" }] : []));
|
|
59
|
+
onFocus() {
|
|
60
|
+
this._hasFocused.set(true);
|
|
61
|
+
}
|
|
62
|
+
constructor() {
|
|
63
|
+
afterRenderEffect(() => {
|
|
64
|
+
if (!this._hasFocused()) {
|
|
65
|
+
this.pattern.setDefaultState();
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
afterRenderEffect(() => {
|
|
69
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
70
|
+
const violations = this.pattern.validate();
|
|
71
|
+
for (const violation of violations) {
|
|
72
|
+
console.error(violation);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
register(widget) {
|
|
78
|
+
const widgets = this._cdkWidgets();
|
|
79
|
+
if (!widgets.has(widget)) {
|
|
80
|
+
widgets.add(widget);
|
|
81
|
+
this._cdkWidgets.set(new Set(widgets));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
unregister(widget) {
|
|
85
|
+
const widgets = this._cdkWidgets();
|
|
86
|
+
if (widgets.delete(widget)) {
|
|
87
|
+
this._cdkWidgets.set(new Set(widgets));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-rc.1", ngImport: i0, type: CdkToolbar, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
91
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.0-rc.1", type: CdkToolbar, isStandalone: true, selector: "[cdkToolbar]", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, skipDisabled: { classPropertyName: "skipDisabled", publicName: "skipDisabled", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "toolbar" }, listeners: { "keydown": "pattern.onKeydown($event)", "pointerdown": "pattern.onPointerdown($event)", "focusin": "onFocus()" }, properties: { "attr.tabindex": "pattern.tabindex()", "attr.aria-disabled": "pattern.disabled()", "attr.aria-orientation": "pattern.orientation()", "attr.aria-activedescendant": "pattern.activedescendant()" }, classAttribute: "cdk-toolbar" }, exportAs: ["cdkToolbar"], ngImport: i0 });
|
|
92
|
+
}
|
|
93
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-rc.1", ngImport: i0, type: CdkToolbar, decorators: [{
|
|
94
|
+
type: Directive,
|
|
95
|
+
args: [{
|
|
96
|
+
selector: '[cdkToolbar]',
|
|
97
|
+
exportAs: 'cdkToolbar',
|
|
98
|
+
host: {
|
|
99
|
+
'role': 'toolbar',
|
|
100
|
+
'class': 'cdk-toolbar',
|
|
101
|
+
'[attr.tabindex]': 'pattern.tabindex()',
|
|
102
|
+
'[attr.aria-disabled]': 'pattern.disabled()',
|
|
103
|
+
'[attr.aria-orientation]': 'pattern.orientation()',
|
|
104
|
+
'[attr.aria-activedescendant]': 'pattern.activedescendant()',
|
|
105
|
+
'(keydown)': 'pattern.onKeydown($event)',
|
|
106
|
+
'(pointerdown)': 'pattern.onPointerdown($event)',
|
|
107
|
+
'(focusin)': 'onFocus()',
|
|
108
|
+
},
|
|
109
|
+
}]
|
|
110
|
+
}], ctorParameters: () => [] });
|
|
111
|
+
/**
|
|
112
|
+
* A widget within a toolbar.
|
|
113
|
+
*
|
|
114
|
+
* A widget is anything that is within a toolbar. It should be applied to any native HTML element
|
|
115
|
+
* that has the purpose of acting as a widget navigatable within a toolbar.
|
|
116
|
+
*/
|
|
117
|
+
class CdkToolbarWidget {
|
|
118
|
+
/** A reference to the widget element. */
|
|
119
|
+
_elementRef = inject(ElementRef);
|
|
120
|
+
/** The parent CdkToolbar. */
|
|
121
|
+
_cdkToolbar = inject(CdkToolbar);
|
|
122
|
+
/** A unique identifier for the widget. */
|
|
123
|
+
_generatedId = inject(_IdGenerator).getId('cdk-toolbar-widget-');
|
|
124
|
+
/** A unique identifier for the widget. */
|
|
125
|
+
id = computed(() => this._generatedId, ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
126
|
+
/** The parent Toolbar UIPattern. */
|
|
127
|
+
parentToolbar = computed(() => this._cdkToolbar.pattern, ...(ngDevMode ? [{ debugName: "parentToolbar" }] : []));
|
|
128
|
+
/** A reference to the widget element to be focused on navigation. */
|
|
129
|
+
element = computed(() => this._elementRef.nativeElement, ...(ngDevMode ? [{ debugName: "element" }] : []));
|
|
130
|
+
/** Whether the widget is disabled. */
|
|
131
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
132
|
+
hardDisabled = computed(() => this.pattern.disabled() && this._cdkToolbar.skipDisabled(), ...(ngDevMode ? [{ debugName: "hardDisabled" }] : []));
|
|
133
|
+
pattern = new ToolbarWidgetPattern({
|
|
134
|
+
...this,
|
|
135
|
+
id: this.id,
|
|
136
|
+
element: this.element,
|
|
137
|
+
disabled: computed(() => this._cdkToolbar.disabled() || this.disabled()),
|
|
138
|
+
parentToolbar: this.parentToolbar,
|
|
139
|
+
});
|
|
140
|
+
ngOnInit() {
|
|
141
|
+
this._cdkToolbar.register(this);
|
|
142
|
+
}
|
|
143
|
+
ngOnDestroy() {
|
|
144
|
+
this._cdkToolbar.unregister(this);
|
|
145
|
+
}
|
|
146
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-rc.1", ngImport: i0, type: CdkToolbarWidget, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
147
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.0-rc.1", type: CdkToolbarWidget, isStandalone: true, selector: "[cdkToolbarWidget]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "button" }, properties: { "class.cdk-active": "pattern.active()", "attr.tabindex": "pattern.tabindex()", "attr.inert": "hardDisabled() ? true : null", "attr.disabled": "hardDisabled() ? true : null", "attr.aria-disabled": "pattern.disabled()", "id": "pattern.id()" }, classAttribute: "cdk-toolbar-widget" }, exportAs: ["cdkToolbarWidget"], ngImport: i0 });
|
|
148
|
+
}
|
|
149
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-rc.1", ngImport: i0, type: CdkToolbarWidget, decorators: [{
|
|
150
|
+
type: Directive,
|
|
151
|
+
args: [{
|
|
152
|
+
selector: '[cdkToolbarWidget]',
|
|
153
|
+
exportAs: 'cdkToolbarWidget',
|
|
154
|
+
host: {
|
|
155
|
+
'role': 'button',
|
|
156
|
+
'class': 'cdk-toolbar-widget',
|
|
157
|
+
'[class.cdk-active]': 'pattern.active()',
|
|
158
|
+
'[attr.tabindex]': 'pattern.tabindex()',
|
|
159
|
+
'[attr.inert]': 'hardDisabled() ? true : null',
|
|
160
|
+
'[attr.disabled]': 'hardDisabled() ? true : null',
|
|
161
|
+
'[attr.aria-disabled]': 'pattern.disabled()',
|
|
162
|
+
'[id]': 'pattern.id()',
|
|
163
|
+
},
|
|
164
|
+
}]
|
|
165
|
+
}] });
|
|
166
|
+
|
|
167
|
+
export { CdkToolbar, CdkToolbarWidget };
|
|
168
|
+
//# sourceMappingURL=toolbar.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolbar.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-c646aa77115d/bin/src/cdk-experimental/toolbar/toolbar.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {\n afterRenderEffect,\n Directive,\n ElementRef,\n inject,\n computed,\n input,\n booleanAttribute,\n signal,\n Signal,\n OnInit,\n OnDestroy,\n} from '@angular/core';\nimport {ToolbarPattern, RadioButtonPattern, ToolbarWidgetPattern} from '../ui-patterns';\nimport {Directionality} from '@angular/cdk/bidi';\nimport {_IdGenerator} from '@angular/cdk/a11y';\n\n/** Interface for a radio button that can be used with a toolbar. Based on radio-button in ui-patterns */\ninterface CdkRadioButtonInterface<V> {\n /** The HTML element associated with the radio button. */\n element: Signal<HTMLElement>;\n /** Whether the radio button is disabled. */\n disabled: Signal<boolean>;\n\n pattern: RadioButtonPattern<V>;\n}\n\ninterface HasElement {\n element: Signal<HTMLElement>;\n}\n\n/**\n * Sort directives by their document order.\n */\nfunction sortDirectives(a: HasElement, b: HasElement) {\n return (a.element().compareDocumentPosition(b.element()) & Node.DOCUMENT_POSITION_PRECEDING) > 0\n ? 1\n : -1;\n}\n\n/**\n * A toolbar widget container.\n *\n * Widgets such as radio groups or buttons are nested within a toolbar to allow for a single\n * place of reference for focus and navigation. The CdkToolbar is meant to be used in conjunction\n * with CdkToolbarWidget and CdkRadioGroup as follows:\n *\n * ```html\n * <div cdkToolbar>\n * <button cdkToolbarWidget>Button</button>\n * <div cdkRadioGroup>\n * <label cdkRadioButton value=\"1\">Option 1</label>\n * <label cdkRadioButton value=\"2\">Option 2</label>\n * <label cdkRadioButton value=\"3\">Option 3</label>\n * </div>\n * </div>\n * ```\n */\n@Directive({\n selector: '[cdkToolbar]',\n exportAs: 'cdkToolbar',\n host: {\n 'role': 'toolbar',\n 'class': 'cdk-toolbar',\n '[attr.tabindex]': 'pattern.tabindex()',\n '[attr.aria-disabled]': 'pattern.disabled()',\n '[attr.aria-orientation]': 'pattern.orientation()',\n '[attr.aria-activedescendant]': 'pattern.activedescendant()',\n '(keydown)': 'pattern.onKeydown($event)',\n '(pointerdown)': 'pattern.onPointerdown($event)',\n '(focusin)': 'onFocus()',\n },\n})\nexport class CdkToolbar<V> {\n /** The CdkTabList nested inside of the container. */\n private readonly _cdkWidgets = signal(new Set<CdkRadioButtonInterface<V> | CdkToolbarWidget>());\n\n /** A signal wrapper for directionality. */\n textDirection = inject(Directionality).valueSignal;\n\n /** Sorted UIPatterns of the child widgets */\n items = computed(() =>\n [...this._cdkWidgets()].sort(sortDirectives).map(widget => widget.pattern),\n );\n\n /** Whether the toolbar is vertically or horizontally oriented. */\n orientation = input<'vertical' | 'horizontal'>('horizontal');\n\n /** Whether disabled items in the group should be skipped when navigating. */\n skipDisabled = input(false, {transform: booleanAttribute});\n\n /** Whether the toolbar is disabled. */\n disabled = input(false, {transform: booleanAttribute});\n\n /** Whether focus should wrap when navigating. */\n readonly wrap = input(true, {transform: booleanAttribute});\n\n /** The toolbar UIPattern. */\n pattern: ToolbarPattern<V> = new ToolbarPattern<V>({\n ...this,\n activeItem: signal(undefined),\n textDirection: this.textDirection,\n focusMode: signal('roving'),\n });\n\n /** Whether the toolbar has received focus yet. */\n private _hasFocused = signal(false);\n\n onFocus() {\n this._hasFocused.set(true);\n }\n\n constructor() {\n afterRenderEffect(() => {\n if (!this._hasFocused()) {\n this.pattern.setDefaultState();\n }\n });\n\n afterRenderEffect(() => {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n const violations = this.pattern.validate();\n for (const violation of violations) {\n console.error(violation);\n }\n }\n });\n }\n\n register(widget: CdkRadioButtonInterface<V> | CdkToolbarWidget) {\n const widgets = this._cdkWidgets();\n if (!widgets.has(widget)) {\n widgets.add(widget);\n this._cdkWidgets.set(new Set(widgets));\n }\n }\n\n unregister(widget: CdkRadioButtonInterface<V> | CdkToolbarWidget) {\n const widgets = this._cdkWidgets();\n if (widgets.delete(widget)) {\n this._cdkWidgets.set(new Set(widgets));\n }\n }\n}\n\n/**\n * A widget within a toolbar.\n *\n * A widget is anything that is within a toolbar. It should be applied to any native HTML element\n * that has the purpose of acting as a widget navigatable within a toolbar.\n */\n@Directive({\n selector: '[cdkToolbarWidget]',\n exportAs: 'cdkToolbarWidget',\n host: {\n 'role': 'button',\n 'class': 'cdk-toolbar-widget',\n '[class.cdk-active]': 'pattern.active()',\n '[attr.tabindex]': 'pattern.tabindex()',\n '[attr.inert]': 'hardDisabled() ? true : null',\n '[attr.disabled]': 'hardDisabled() ? true : null',\n '[attr.aria-disabled]': 'pattern.disabled()',\n '[id]': 'pattern.id()',\n },\n})\nexport class CdkToolbarWidget implements OnInit, OnDestroy {\n /** A reference to the widget element. */\n private readonly _elementRef = inject(ElementRef);\n\n /** The parent CdkToolbar. */\n private readonly _cdkToolbar = inject(CdkToolbar);\n\n /** A unique identifier for the widget. */\n private readonly _generatedId = inject(_IdGenerator).getId('cdk-toolbar-widget-');\n\n /** A unique identifier for the widget. */\n protected id = computed(() => this._generatedId);\n\n /** The parent Toolbar UIPattern. */\n protected parentToolbar = computed(() => this._cdkToolbar.pattern);\n\n /** A reference to the widget element to be focused on navigation. */\n element = computed(() => this._elementRef.nativeElement);\n\n /** Whether the widget is disabled. */\n disabled = input(false, {transform: booleanAttribute});\n\n readonly hardDisabled = computed(\n () => this.pattern.disabled() && this._cdkToolbar.skipDisabled(),\n );\n\n pattern = new ToolbarWidgetPattern({\n ...this,\n id: this.id,\n element: this.element,\n disabled: computed(() => this._cdkToolbar.disabled() || this.disabled()),\n parentToolbar: this.parentToolbar,\n });\n\n ngOnInit() {\n this._cdkToolbar.register(this);\n }\n\n ngOnDestroy() {\n this._cdkToolbar.unregister(this);\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { computed, signal } from '@angular/core';
|
|
2
|
+
import { List } from './list.mjs';
|
|
3
|
+
import { PointerEventManager, KeyboardEventManager } from './list-navigation.mjs';
|
|
4
|
+
|
|
5
|
+
/** Represents a radio button within a radio group. */
|
|
6
|
+
class RadioButtonPattern {
|
|
7
|
+
inputs;
|
|
8
|
+
/** A unique identifier for the radio button. */
|
|
9
|
+
id;
|
|
10
|
+
/** The value associated with the radio button. */
|
|
11
|
+
value;
|
|
12
|
+
/** The position of the radio button within the group. */
|
|
13
|
+
index = computed(() => this.group()?.listBehavior.inputs.items().indexOf(this) ?? -1);
|
|
14
|
+
/** Whether the radio button is currently the active one (focused). */
|
|
15
|
+
active = computed(() => this.group()?.listBehavior.inputs.activeItem() === this);
|
|
16
|
+
/** Whether the radio button is selected. */
|
|
17
|
+
selected = computed(() => !!this.group()?.listBehavior.inputs.value().includes(this.value()));
|
|
18
|
+
/** Whether the radio button is disabled. */
|
|
19
|
+
disabled;
|
|
20
|
+
/** A reference to the parent radio group. */
|
|
21
|
+
group;
|
|
22
|
+
/** The tabindex of the radio button. */
|
|
23
|
+
tabindex = computed(() => this.group()?.listBehavior.getItemTabindex(this));
|
|
24
|
+
/** The HTML element associated with the radio button. */
|
|
25
|
+
element;
|
|
26
|
+
/** The search term for typeahead. */
|
|
27
|
+
searchTerm = () => ''; // Radio groups do not support typeahead.
|
|
28
|
+
constructor(inputs) {
|
|
29
|
+
this.inputs = inputs;
|
|
30
|
+
this.id = inputs.id;
|
|
31
|
+
this.value = inputs.value;
|
|
32
|
+
this.group = inputs.group;
|
|
33
|
+
this.element = inputs.element;
|
|
34
|
+
this.disabled = inputs.disabled;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Controls the state of a toolbar. */
|
|
39
|
+
class ToolbarPattern {
|
|
40
|
+
inputs;
|
|
41
|
+
/** The list behavior for the toolbar. */
|
|
42
|
+
listBehavior;
|
|
43
|
+
/** Whether the tablist is vertically or horizontally oriented. */
|
|
44
|
+
orientation;
|
|
45
|
+
/** Whether the toolbar is disabled. */
|
|
46
|
+
disabled = computed(() => this.listBehavior.disabled());
|
|
47
|
+
/** The tabindex of the toolbar (if using activedescendant). */
|
|
48
|
+
tabindex = computed(() => this.listBehavior.tabindex());
|
|
49
|
+
/** The id of the current active widget (if using activedescendant). */
|
|
50
|
+
activedescendant = computed(() => this.listBehavior.activedescendant());
|
|
51
|
+
/** The key used to navigate to the previous widget. */
|
|
52
|
+
prevKey = computed(() => {
|
|
53
|
+
if (this.inputs.orientation() === 'vertical') {
|
|
54
|
+
return 'ArrowUp';
|
|
55
|
+
}
|
|
56
|
+
return this.inputs.textDirection() === 'rtl' ? 'ArrowRight' : 'ArrowLeft';
|
|
57
|
+
});
|
|
58
|
+
/** The key used to navigate to the next widget. */
|
|
59
|
+
nextKey = computed(() => {
|
|
60
|
+
if (this.inputs.orientation() === 'vertical') {
|
|
61
|
+
return 'ArrowDown';
|
|
62
|
+
}
|
|
63
|
+
return this.inputs.textDirection() === 'rtl' ? 'ArrowLeft' : 'ArrowRight';
|
|
64
|
+
});
|
|
65
|
+
/** The alternate key used to navigate to the previous widget */
|
|
66
|
+
altPrevKey = computed(() => {
|
|
67
|
+
if (this.inputs.orientation() === 'vertical') {
|
|
68
|
+
return this.inputs.textDirection() === 'rtl' ? 'ArrowRight' : 'ArrowLeft';
|
|
69
|
+
}
|
|
70
|
+
return 'ArrowUp';
|
|
71
|
+
});
|
|
72
|
+
/** The alternate key used to navigate to the next widget. */
|
|
73
|
+
altNextKey = computed(() => {
|
|
74
|
+
if (this.inputs.orientation() === 'vertical') {
|
|
75
|
+
return this.inputs.textDirection() === 'rtl' ? 'ArrowLeft' : 'ArrowRight';
|
|
76
|
+
}
|
|
77
|
+
return 'ArrowDown';
|
|
78
|
+
});
|
|
79
|
+
/** The keydown event manager for the toolbar. */
|
|
80
|
+
keydown = computed(() => {
|
|
81
|
+
const manager = new KeyboardEventManager();
|
|
82
|
+
const activeItem = this.inputs.activeItem();
|
|
83
|
+
const isRadioButton = activeItem instanceof RadioButtonPattern;
|
|
84
|
+
if (isRadioButton) {
|
|
85
|
+
manager
|
|
86
|
+
.on(' ', () => this.selectRadioButton())
|
|
87
|
+
.on('Enter', () => this.selectRadioButton())
|
|
88
|
+
.on(this.altNextKey, () => activeItem?.group()?.listBehavior.next())
|
|
89
|
+
.on(this.altPrevKey, () => activeItem?.group()?.listBehavior.prev());
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
manager.on(this.altNextKey, () => this.listBehavior.next());
|
|
93
|
+
manager.on(this.altPrevKey, () => this.listBehavior.prev());
|
|
94
|
+
}
|
|
95
|
+
return manager
|
|
96
|
+
.on(this.prevKey, () => this.listBehavior.prev())
|
|
97
|
+
.on(this.nextKey, () => this.listBehavior.next())
|
|
98
|
+
.on('Home', () => this.listBehavior.first())
|
|
99
|
+
.on('End', () => this.listBehavior.last());
|
|
100
|
+
});
|
|
101
|
+
selectRadioButton() {
|
|
102
|
+
const activeItem = this.inputs.activeItem();
|
|
103
|
+
// activeItem must be a radio button
|
|
104
|
+
const group = activeItem.group();
|
|
105
|
+
if (group && !group.readonly() && !group.disabled()) {
|
|
106
|
+
group.listBehavior.selectOne();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/** The pointerdown event manager for the toolbar. */
|
|
110
|
+
pointerdown = computed(() => new PointerEventManager().on(e => this.goto(e)));
|
|
111
|
+
/** Navigates to the widget associated with the given pointer event. */
|
|
112
|
+
goto(event) {
|
|
113
|
+
const item = this._getItem(event);
|
|
114
|
+
if (!item)
|
|
115
|
+
return;
|
|
116
|
+
if (item instanceof RadioButtonPattern) {
|
|
117
|
+
const group = item.group();
|
|
118
|
+
if (group && !group.disabled()) {
|
|
119
|
+
group.listBehavior.goto(item, { selectOne: !group.readonly() });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
this.listBehavior.goto(item);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Handles keydown events for the toolbar. */
|
|
127
|
+
onKeydown(event) {
|
|
128
|
+
if (!this.disabled()) {
|
|
129
|
+
this.keydown().handle(event);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/** Handles pointerdown events for the toolbar. */
|
|
133
|
+
onPointerdown(event) {
|
|
134
|
+
if (!this.disabled()) {
|
|
135
|
+
this.pointerdown().handle(event);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/** Finds the Toolbar Widget associated with a pointer event target. */
|
|
139
|
+
_getItem(e) {
|
|
140
|
+
if (!(e.target instanceof HTMLElement)) {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
// Assumes the target or its ancestor has role="radio" or role="button"
|
|
144
|
+
const element = e.target.closest('[role="button"], [role="radio"]');
|
|
145
|
+
return this.inputs.items().find(i => i.element() === element);
|
|
146
|
+
}
|
|
147
|
+
constructor(inputs) {
|
|
148
|
+
this.inputs = inputs;
|
|
149
|
+
this.orientation = inputs.orientation;
|
|
150
|
+
this.listBehavior = new List({
|
|
151
|
+
...inputs,
|
|
152
|
+
multi: () => false,
|
|
153
|
+
selectionMode: () => 'explicit',
|
|
154
|
+
value: signal([]),
|
|
155
|
+
typeaheadDelay: () => 0, // Toolbar widgets do not support typeahead.
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Sets the toolbar to its default initial state.
|
|
160
|
+
*
|
|
161
|
+
* Sets the active index to the selected widget if one exists and is focusable.
|
|
162
|
+
* Otherwise, sets the active index to the first focusable widget.
|
|
163
|
+
*/
|
|
164
|
+
setDefaultState() {
|
|
165
|
+
let firstItem = null;
|
|
166
|
+
for (const item of this.inputs.items()) {
|
|
167
|
+
if (this.listBehavior.isFocusable(item)) {
|
|
168
|
+
if (!firstItem) {
|
|
169
|
+
firstItem = item;
|
|
170
|
+
}
|
|
171
|
+
if (item instanceof RadioButtonPattern && item.selected()) {
|
|
172
|
+
this.inputs.activeItem.set(item);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (firstItem) {
|
|
178
|
+
this.inputs.activeItem.set(firstItem);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** Validates the state of the toolbar and returns a list of accessibility violations. */
|
|
182
|
+
validate() {
|
|
183
|
+
const violations = [];
|
|
184
|
+
if (this.inputs.skipDisabled()) {
|
|
185
|
+
for (const item of this.inputs.items()) {
|
|
186
|
+
if (item instanceof RadioButtonPattern && item.selected() && item.disabled()) {
|
|
187
|
+
violations.push("Accessibility Violation: A selected radio button inside the toolbar is disabled while 'skipDisabled' is true, making the selection unreachable via keyboard.");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return violations;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
class ToolbarWidgetPattern {
|
|
195
|
+
inputs;
|
|
196
|
+
/** A unique identifier for the widget. */
|
|
197
|
+
id;
|
|
198
|
+
/** The html element that should receive focus. */
|
|
199
|
+
element;
|
|
200
|
+
/** Whether the widget is disabled. */
|
|
201
|
+
disabled;
|
|
202
|
+
/** A reference to the parent toolbar. */
|
|
203
|
+
parentToolbar;
|
|
204
|
+
/** The tabindex of the widgdet. */
|
|
205
|
+
tabindex = computed(() => this.inputs.parentToolbar().listBehavior.getItemTabindex(this));
|
|
206
|
+
/** The text used by the typeahead search. */
|
|
207
|
+
searchTerm = () => ''; // Unused because toolbar does not support typeahead.
|
|
208
|
+
/** The value associated with the widget. */
|
|
209
|
+
value = () => ''; // Unused because toolbar does not support selection.
|
|
210
|
+
/** The position of the widget within the toolbar. */
|
|
211
|
+
index = computed(() => this.parentToolbar()?.inputs.items().indexOf(this) ?? -1);
|
|
212
|
+
/** Whether the widget is currently the active one (focused). */
|
|
213
|
+
active = computed(() => this.parentToolbar()?.inputs.activeItem() === this);
|
|
214
|
+
constructor(inputs) {
|
|
215
|
+
this.inputs = inputs;
|
|
216
|
+
this.id = inputs.id;
|
|
217
|
+
this.element = inputs.element;
|
|
218
|
+
this.disabled = inputs.disabled;
|
|
219
|
+
this.parentToolbar = inputs.parentToolbar;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export { RadioButtonPattern, ToolbarPattern, ToolbarWidgetPattern };
|
|
224
|
+
//# sourceMappingURL=toolbar2.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolbar2.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-c646aa77115d/bin/src/cdk-experimental/ui-patterns/radio-group/radio-button.ts","../../../../../darwin_arm64-fastbuild-ST-c646aa77115d/bin/src/cdk-experimental/ui-patterns/toolbar/toolbar.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {computed} from '@angular/core';\nimport {SignalLike} from '../behaviors/signal-like/signal-like';\nimport {List, ListItem} from '../behaviors/list/list';\n\n/**\n * Represents the properties exposed by a toolbar widget that need to be accessed by a radio group.\n * This exists to avoid circular dependency errors between the toolbar and radio button.\n */\ntype ToolbarWidgetLike = {\n id: SignalLike<string>;\n index: SignalLike<number>;\n element: SignalLike<HTMLElement>;\n disabled: SignalLike<boolean>;\n searchTerm: SignalLike<any>;\n value: SignalLike<any>;\n};\n\n/**\n * Represents the properties exposed by a radio group that need to be accessed by a radio button.\n * This exists to avoid circular dependency errors between the radio group and radio button.\n */\ninterface RadioGroupLike<V> {\n /** The list behavior for the radio group. */\n listBehavior: List<RadioButtonPattern<V> | ToolbarWidgetLike, V>;\n /** Whether the list is readonly */\n readonly: SignalLike<boolean>;\n /** Whether the radio group is disabled. */\n disabled: SignalLike<boolean>;\n}\n\n/** Represents the required inputs for a radio button in a radio group. */\nexport interface RadioButtonInputs<V> extends Omit<ListItem<V>, 'searchTerm' | 'index'> {\n /** A reference to the parent radio group. */\n group: SignalLike<RadioGroupLike<V> | undefined>;\n}\n\n/** Represents a radio button within a radio group. */\nexport class RadioButtonPattern<V> {\n /** A unique identifier for the radio button. */\n id: SignalLike<string>;\n\n /** The value associated with the radio button. */\n value: SignalLike<V>;\n\n /** The position of the radio button within the group. */\n index: SignalLike<number> = computed(\n () => this.group()?.listBehavior.inputs.items().indexOf(this) ?? -1,\n );\n\n /** Whether the radio button is currently the active one (focused). */\n active = computed(() => this.group()?.listBehavior.inputs.activeItem() === this);\n\n /** Whether the radio button is selected. */\n selected: SignalLike<boolean> = computed(\n () => !!this.group()?.listBehavior.inputs.value().includes(this.value()),\n );\n\n /** Whether the radio button is disabled. */\n disabled: SignalLike<boolean>;\n\n /** A reference to the parent radio group. */\n group: SignalLike<RadioGroupLike<V> | undefined>;\n\n /** The tabindex of the radio button. */\n tabindex = computed(() => this.group()?.listBehavior.getItemTabindex(this));\n\n /** The HTML element associated with the radio button. */\n element: SignalLike<HTMLElement>;\n\n /** The search term for typeahead. */\n readonly searchTerm = () => ''; // Radio groups do not support typeahead.\n\n constructor(readonly inputs: RadioButtonInputs<V>) {\n this.id = inputs.id;\n this.value = inputs.value;\n this.group = inputs.group;\n this.element = inputs.element;\n this.disabled = inputs.disabled;\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {computed, signal} from '@angular/core';\nimport {KeyboardEventManager, PointerEventManager} from '../behaviors/event-manager';\nimport {SignalLike} from '../behaviors/signal-like/signal-like';\nimport {RadioButtonPattern} from '../radio-group/radio-button';\nimport {List, ListInputs, ListItem} from '../behaviors/list/list';\n\n/** Represents the required inputs for a toolbar. */\nexport type ToolbarInputs<V> = Omit<\n ListInputs<ToolbarWidgetPattern | RadioButtonPattern<V>, V>,\n 'multi' | 'typeaheadDelay' | 'value' | 'selectionMode'\n>;\n\n/** Controls the state of a toolbar. */\nexport class ToolbarPattern<V> {\n /** The list behavior for the toolbar. */\n listBehavior: List<ToolbarWidgetPattern | RadioButtonPattern<V>, V>;\n\n /** Whether the tablist is vertically or horizontally oriented. */\n readonly orientation: SignalLike<'vertical' | 'horizontal'>;\n\n /** Whether the toolbar is disabled. */\n disabled = computed(() => this.listBehavior.disabled());\n\n /** The tabindex of the toolbar (if using activedescendant). */\n tabindex = computed(() => this.listBehavior.tabindex());\n\n /** The id of the current active widget (if using activedescendant). */\n activedescendant = computed(() => this.listBehavior.activedescendant());\n\n /** The key used to navigate to the previous widget. */\n prevKey = computed(() => {\n if (this.inputs.orientation() === 'vertical') {\n return 'ArrowUp';\n }\n return this.inputs.textDirection() === 'rtl' ? 'ArrowRight' : 'ArrowLeft';\n });\n\n /** The key used to navigate to the next widget. */\n nextKey = computed(() => {\n if (this.inputs.orientation() === 'vertical') {\n return 'ArrowDown';\n }\n return this.inputs.textDirection() === 'rtl' ? 'ArrowLeft' : 'ArrowRight';\n });\n\n /** The alternate key used to navigate to the previous widget */\n altPrevKey = computed(() => {\n if (this.inputs.orientation() === 'vertical') {\n return this.inputs.textDirection() === 'rtl' ? 'ArrowRight' : 'ArrowLeft';\n }\n return 'ArrowUp';\n });\n\n /** The alternate key used to navigate to the next widget. */\n altNextKey = computed(() => {\n if (this.inputs.orientation() === 'vertical') {\n return this.inputs.textDirection() === 'rtl' ? 'ArrowLeft' : 'ArrowRight';\n }\n return 'ArrowDown';\n });\n\n /** The keydown event manager for the toolbar. */\n keydown = computed(() => {\n const manager = new KeyboardEventManager();\n\n const activeItem = this.inputs.activeItem();\n const isRadioButton = activeItem instanceof RadioButtonPattern;\n\n if (isRadioButton) {\n manager\n .on(' ', () => this.selectRadioButton())\n .on('Enter', () => this.selectRadioButton())\n .on(this.altNextKey, () => activeItem?.group()?.listBehavior.next())\n .on(this.altPrevKey, () => activeItem?.group()?.listBehavior.prev());\n } else {\n manager.on(this.altNextKey, () => this.listBehavior.next());\n manager.on(this.altPrevKey, () => this.listBehavior.prev());\n }\n\n return manager\n .on(this.prevKey, () => this.listBehavior.prev())\n .on(this.nextKey, () => this.listBehavior.next())\n .on('Home', () => this.listBehavior.first())\n .on('End', () => this.listBehavior.last());\n });\n\n selectRadioButton() {\n const activeItem = this.inputs.activeItem() as RadioButtonPattern<V>;\n\n // activeItem must be a radio button\n const group = activeItem!.group();\n if (group && !group.readonly() && !group.disabled()) {\n group.listBehavior.selectOne();\n }\n }\n\n /** The pointerdown event manager for the toolbar. */\n pointerdown = computed(() => new PointerEventManager().on(e => this.goto(e)));\n\n /** Navigates to the widget associated with the given pointer event. */\n goto(event: PointerEvent) {\n const item = this._getItem(event);\n if (!item) return;\n\n if (item instanceof RadioButtonPattern) {\n const group = item.group();\n if (group && !group.disabled()) {\n group.listBehavior.goto(item, {selectOne: !group.readonly()});\n }\n } else {\n this.listBehavior.goto(item);\n }\n }\n\n /** Handles keydown events for the toolbar. */\n onKeydown(event: KeyboardEvent) {\n if (!this.disabled()) {\n this.keydown().handle(event);\n }\n }\n\n /** Handles pointerdown events for the toolbar. */\n onPointerdown(event: PointerEvent) {\n if (!this.disabled()) {\n this.pointerdown().handle(event);\n }\n }\n\n /** Finds the Toolbar Widget associated with a pointer event target. */\n private _getItem(e: PointerEvent): RadioButtonPattern<V> | ToolbarWidgetPattern | undefined {\n if (!(e.target instanceof HTMLElement)) {\n return undefined;\n }\n\n // Assumes the target or its ancestor has role=\"radio\" or role=\"button\"\n const element = e.target.closest('[role=\"button\"], [role=\"radio\"]');\n return this.inputs.items().find(i => i.element() === element);\n }\n\n constructor(readonly inputs: ToolbarInputs<V>) {\n this.orientation = inputs.orientation;\n\n this.listBehavior = new List({\n ...inputs,\n multi: () => false,\n selectionMode: () => 'explicit',\n value: signal([] as any),\n typeaheadDelay: () => 0, // Toolbar widgets do not support typeahead.\n });\n }\n\n /**\n * Sets the toolbar to its default initial state.\n *\n * Sets the active index to the selected widget if one exists and is focusable.\n * Otherwise, sets the active index to the first focusable widget.\n */\n setDefaultState() {\n let firstItem: RadioButtonPattern<V> | ToolbarWidgetPattern | null = null;\n\n for (const item of this.inputs.items()) {\n if (this.listBehavior.isFocusable(item)) {\n if (!firstItem) {\n firstItem = item;\n }\n if (item instanceof RadioButtonPattern && item.selected()) {\n this.inputs.activeItem.set(item);\n return;\n }\n }\n }\n\n if (firstItem) {\n this.inputs.activeItem.set(firstItem);\n }\n }\n\n /** Validates the state of the toolbar and returns a list of accessibility violations. */\n validate(): string[] {\n const violations: string[] = [];\n\n if (this.inputs.skipDisabled()) {\n for (const item of this.inputs.items()) {\n if (item instanceof RadioButtonPattern && item.selected() && item.disabled()) {\n violations.push(\n \"Accessibility Violation: A selected radio button inside the toolbar is disabled while 'skipDisabled' is true, making the selection unreachable via keyboard.\",\n );\n }\n }\n }\n return violations;\n }\n}\n\n/** Represents the required inputs for a toolbar widget in a toolbar. */\nexport interface ToolbarWidgetInputs extends Omit<ListItem<any>, 'searchTerm' | 'value' | 'index'> {\n /** A reference to the parent toolbar. */\n parentToolbar: SignalLike<ToolbarPattern<null>>;\n}\n\nexport class ToolbarWidgetPattern {\n /** A unique identifier for the widget. */\n id: SignalLike<string>;\n\n /** The html element that should receive focus. */\n readonly element: SignalLike<HTMLElement>;\n\n /** Whether the widget is disabled. */\n disabled: SignalLike<boolean>;\n\n /** A reference to the parent toolbar. */\n parentToolbar: SignalLike<ToolbarPattern<null> | undefined>;\n\n /** The tabindex of the widgdet. */\n tabindex = computed(() => this.inputs.parentToolbar().listBehavior.getItemTabindex(this));\n\n /** The text used by the typeahead search. */\n readonly searchTerm = () => ''; // Unused because toolbar does not support typeahead.\n\n /** The value associated with the widget. */\n readonly value = () => '' as any; // Unused because toolbar does not support selection.\n\n /** The position of the widget within the toolbar. */\n index = computed(() => this.parentToolbar()?.inputs.items().indexOf(this) ?? -1);\n\n /** Whether the widget is currently the active one (focused). */\n active = computed(() => this.parentToolbar()?.inputs.activeItem() === this);\n\n constructor(readonly inputs: ToolbarWidgetInputs) {\n this.id = inputs.id;\n this.element = inputs.element;\n this.disabled = inputs.disabled;\n this.parentToolbar = inputs.parentToolbar;\n }\n}\n"],"names":[],"mappings":";;;;AA4CA;MACa,kBAAkB,CAAA;AAmCR,IAAA,MAAA;;AAjCrB,IAAA,EAAE;;AAGF,IAAA,KAAK;;IAGL,KAAK,GAAuB,QAAQ,CAClC,MAAM,IAAI,CAAC,KAAK,EAAE,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CACpE;;IAGD,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,EAAE,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,IAAI,CAAC;;AAGhF,IAAA,QAAQ,GAAwB,QAAQ,CACtC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CACzE;;AAGD,IAAA,QAAQ;;AAGR,IAAA,KAAK;;AAGL,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,EAAE,YAAY,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;;AAG3E,IAAA,OAAO;;AAGE,IAAA,UAAU,GAAG,MAAM,EAAE,CAAC;AAE/B,IAAA,WAAA,CAAqB,MAA4B,EAAA;QAA5B,IAAM,CAAA,MAAA,GAAN,MAAM;AACzB,QAAA,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE;AACnB,QAAA,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK;AACzB,QAAA,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK;AACzB,QAAA,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO;AAC7B,QAAA,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ;;AAElC;;ACnED;MACa,cAAc,CAAA;AA8HJ,IAAA,MAAA;;AA5HrB,IAAA,YAAY;;AAGH,IAAA,WAAW;;AAGpB,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;;AAGvD,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;;AAGvD,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,CAAC;;AAGvE,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;QACtB,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,UAAU,EAAE;AAC5C,YAAA,OAAO,SAAS;;AAElB,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,KAAK,GAAG,YAAY,GAAG,WAAW;AAC3E,KAAC,CAAC;;AAGF,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;QACtB,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,UAAU,EAAE;AAC5C,YAAA,OAAO,WAAW;;AAEpB,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,KAAK,GAAG,WAAW,GAAG,YAAY;AAC3E,KAAC,CAAC;;AAGF,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAK;QACzB,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,UAAU,EAAE;AAC5C,YAAA,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,KAAK,GAAG,YAAY,GAAG,WAAW;;AAE3E,QAAA,OAAO,SAAS;AAClB,KAAC,CAAC;;AAGF,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAK;QACzB,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,UAAU,EAAE;AAC5C,YAAA,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,KAAK,GAAG,WAAW,GAAG,YAAY;;AAE3E,QAAA,OAAO,WAAW;AACpB,KAAC,CAAC;;AAGF,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;AACtB,QAAA,MAAM,OAAO,GAAG,IAAI,oBAAoB,EAAE;QAE1C,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;AAC3C,QAAA,MAAM,aAAa,GAAG,UAAU,YAAY,kBAAkB;QAE9D,IAAI,aAAa,EAAE;YACjB;iBACG,EAAE,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,iBAAiB,EAAE;iBACtC,EAAE,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,iBAAiB,EAAE;AAC1C,iBAAA,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,UAAU,EAAE,KAAK,EAAE,EAAE,YAAY,CAAC,IAAI,EAAE;AAClE,iBAAA,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,UAAU,EAAE,KAAK,EAAE,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC;;aACjE;AACL,YAAA,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;AAC3D,YAAA,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;;AAG7D,QAAA,OAAO;AACJ,aAAA,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;AAC/C,aAAA,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;AAC/C,aAAA,EAAE,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE;AAC1C,aAAA,EAAE,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;AAC9C,KAAC,CAAC;IAEF,iBAAiB,GAAA;QACf,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAA2B;;AAGpE,QAAA,MAAM,KAAK,GAAG,UAAW,CAAC,KAAK,EAAE;AACjC,QAAA,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE;AACnD,YAAA,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE;;;;IAKlC,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,mBAAmB,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;;AAG7E,IAAA,IAAI,CAAC,KAAmB,EAAA;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;AACjC,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,IAAI,IAAI,YAAY,kBAAkB,EAAE;AACtC,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;YAC1B,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE;AAC9B,gBAAA,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAC,SAAS,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAC,CAAC;;;aAE1D;AACL,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;;;;AAKhC,IAAA,SAAS,CAAC,KAAoB,EAAA;AAC5B,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE;YACpB,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;;;;AAKhC,IAAA,aAAa,CAAC,KAAmB,EAAA;AAC/B,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE;YACpB,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;;;;AAK5B,IAAA,QAAQ,CAAC,CAAe,EAAA;QAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,YAAY,WAAW,CAAC,EAAE;AACtC,YAAA,OAAO,SAAS;;;QAIlB,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,iCAAiC,CAAC;QACnE,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,OAAO,CAAC;;AAG/D,IAAA,WAAA,CAAqB,MAAwB,EAAA;QAAxB,IAAM,CAAA,MAAA,GAAN,MAAM;AACzB,QAAA,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW;AAErC,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI,IAAI,CAAC;AAC3B,YAAA,GAAG,MAAM;AACT,YAAA,KAAK,EAAE,MAAM,KAAK;AAClB,YAAA,aAAa,EAAE,MAAM,UAAU;AAC/B,YAAA,KAAK,EAAE,MAAM,CAAC,EAAS,CAAC;AACxB,YAAA,cAAc,EAAE,MAAM,CAAC;AACxB,SAAA,CAAC;;AAGJ;;;;;AAKG;IACH,eAAe,GAAA;QACb,IAAI,SAAS,GAAwD,IAAI;QAEzE,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE;YACtC,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;gBACvC,IAAI,CAAC,SAAS,EAAE;oBACd,SAAS,GAAG,IAAI;;gBAElB,IAAI,IAAI,YAAY,kBAAkB,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;oBACzD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;oBAChC;;;;QAKN,IAAI,SAAS,EAAE;YACb,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;;;;IAKzC,QAAQ,GAAA;QACN,MAAM,UAAU,GAAa,EAAE;AAE/B,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE;YAC9B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE;AACtC,gBAAA,IAAI,IAAI,YAAY,kBAAkB,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;AAC5E,oBAAA,UAAU,CAAC,IAAI,CACb,8JAA8J,CAC/J;;;;AAIP,QAAA,OAAO,UAAU;;AAEpB;MAQY,oBAAoB,CAAA;AA4BV,IAAA,MAAA;;AA1BrB,IAAA,EAAE;;AAGO,IAAA,OAAO;;AAGhB,IAAA,QAAQ;;AAGR,IAAA,aAAa;;IAGb,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,YAAY,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;;AAGhF,IAAA,UAAU,GAAG,MAAM,EAAE,CAAC;;AAGtB,IAAA,KAAK,GAAG,MAAM,EAAS,CAAC;;IAGjC,KAAK,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;;AAGhF,IAAA,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,IAAI,CAAC;AAE3E,IAAA,WAAA,CAAqB,MAA2B,EAAA;QAA3B,IAAM,CAAA,MAAA,GAAN,MAAM;AACzB,QAAA,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE;AACnB,QAAA,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO;AAC7B,QAAA,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ;AAC/B,QAAA,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa;;AAE5C;;;;"}
|