@simplybusiness/mobius 5.9.0 → 5.10.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/CHANGELOG.md +10 -0
- package/dist/cjs/components/Checkbox/CheckboxGroup.js +13 -21
- package/dist/cjs/components/Checkbox/CheckboxGroup.js.map +1 -1
- package/dist/cjs/components/Combobox/Combobox.js +2 -1
- package/dist/cjs/components/Combobox/Combobox.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/components/Checkbox/CheckboxGroup.js +15 -23
- package/dist/esm/components/Checkbox/CheckboxGroup.js.map +1 -1
- package/dist/esm/components/Combobox/Combobox.js +2 -1
- package/dist/esm/components/Combobox/Combobox.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Checkbox/CheckboxGroup.tsx +10 -17
- package/src/components/Combobox/Combobox.test.tsx +7 -0
- package/src/components/Combobox/Combobox.tsx +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -47,34 +47,26 @@ const CheckboxGroup = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
|
47
47
|
const labelId = (0, _react.useId)();
|
|
48
48
|
const handleChange = (event, isLastItem = false)=>{
|
|
49
49
|
const { target: { value, checked } } = event;
|
|
50
|
+
let newValue = [
|
|
51
|
+
...selected
|
|
52
|
+
];
|
|
50
53
|
if (!checked) {
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
if (checked && lastItemDisables && isLastItem) {
|
|
54
|
-
setSelected([
|
|
55
|
-
value
|
|
56
|
-
]);
|
|
57
|
-
return;
|
|
54
|
+
newValue = selected.filter((item)=>item !== value);
|
|
58
55
|
}
|
|
59
56
|
if (checked) {
|
|
60
|
-
|
|
57
|
+
newValue = [
|
|
61
58
|
...selected,
|
|
62
59
|
value
|
|
63
|
-
]
|
|
60
|
+
];
|
|
64
61
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
(0, _react.useEffect)(()=>{
|
|
70
|
-
if (onChange && renderCount > 1) {
|
|
71
|
-
onChange(selected);
|
|
62
|
+
if (checked && lastItemDisables && isLastItem) {
|
|
63
|
+
newValue = [
|
|
64
|
+
value
|
|
65
|
+
];
|
|
72
66
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
renderCount
|
|
77
|
-
]);
|
|
67
|
+
setSelected(newValue);
|
|
68
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
|
|
69
|
+
};
|
|
78
70
|
const childrenArray = _react.Children.toArray(children);
|
|
79
71
|
const lastCheckbox = childrenArray.filter((child)=>/*#__PURE__*/ (0, _react.isValidElement)(child) && child.type === _Checkbox.Checkbox).pop();
|
|
80
72
|
const lastCheckboxIsChecked = lastCheckbox && selected.includes(lastCheckbox.props.value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/Checkbox/CheckboxGroup.tsx"],"sourcesContent":["\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport {\n type ChangeEvent,\n type ReactElement,\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/Checkbox/CheckboxGroup.tsx"],"sourcesContent":["\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport {\n type ChangeEvent,\n type ReactElement,\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n useId,\n useState,\n} from \"react\";\nimport { useValidationClasses } from \"../../hooks\";\nimport { ForwardedRefComponent } from \"../../types/components\";\nimport { spaceDelimitedList } from \"../../utils/spaceDelimitedList\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport { Checkbox } from \"./Checkbox\";\nimport {\n CheckboxElementType,\n CheckboxGroupElementType,\n CheckboxGroupProps,\n CheckboxGroupRef,\n} from \"./types\";\n\nexport const CheckboxGroup: ForwardedRefComponent<\n CheckboxGroupProps,\n CheckboxGroupElementType\n> = forwardRef((props: CheckboxGroupProps, ref: CheckboxGroupRef) => {\n const {\n label,\n isDisabled = false,\n isRequired,\n validationState,\n isInvalid,\n orientation = \"vertical\",\n onChange,\n className,\n errorMessage,\n children,\n defaultValue = [],\n isReadOnly,\n itemsPerRow,\n lastItemDisables = false,\n ...rest\n } = props;\n const [selected, setSelected] = useState<string[]>(defaultValue);\n const checkboxGroupClasses = classNames(\n \"mobius\",\n \"mobius-checkbox-group\",\n className,\n {\n \"--is-horizontal\": orientation === \"horizontal\",\n \"--is-vertical\": orientation === \"vertical\",\n \"--is-required\": typeof isRequired === \"boolean\" && isRequired,\n \"--is-optional\": typeof isRequired === \"boolean\" && !isRequired,\n },\n );\n const validationClasses = useValidationClasses({\n validationState,\n isInvalid,\n });\n const labelClasses = classNames(\n {\n \"--is-disabled\": isDisabled,\n },\n validationClasses,\n );\n const errorMessageId = useId();\n const shouldErrorMessageShow = errorMessage ? errorMessageId : undefined;\n const describedBy = spaceDelimitedList([\n shouldErrorMessageShow,\n props[\"aria-describedby\"],\n ]);\n const labelId = useId();\n\n const handleChange = (\n event: ChangeEvent<CheckboxElementType>,\n isLastItem = false,\n ) => {\n const {\n target: { value, checked },\n } = event;\n let newValue = [...selected];\n\n if (!checked) {\n newValue = selected.filter(item => item !== value);\n }\n\n if (checked) {\n newValue = [...selected, value];\n }\n\n if (checked && lastItemDisables && isLastItem) {\n newValue = [value];\n }\n\n setSelected(newValue);\n onChange?.(newValue);\n };\n\n const childrenArray = Children.toArray(children);\n const lastCheckbox = childrenArray\n .filter(\n child =>\n isValidElement(child) && (child as ReactElement).type === Checkbox,\n )\n .pop() as ReactElement<CheckboxElementType> | undefined;\n const lastCheckboxIsChecked =\n lastCheckbox && selected.includes(lastCheckbox.props.value);\n\n return (\n <div\n {...rest}\n aria-labelledby={props[\"aria-labelledby\"] || labelId}\n ref={ref}\n className={checkboxGroupClasses}\n role=\"group\"\n style={\n {\n \"--checkbox-items-per-row\": itemsPerRow || Children.count(children),\n } as React.CSSProperties\n }\n >\n {label && (\n <Label elementType=\"span\" id={labelId} className={labelClasses}>\n {label}\n </Label>\n )}\n <div className=\"mobius-checkbox-group__wrapper\">\n {childrenArray.map(child => {\n if (isValidElement(child)) {\n // lastItemDisables support\n const isLastItem = child === lastCheckbox;\n const isChildDisabled =\n isDisabled ||\n (lastItemDisables && lastCheckboxIsChecked && !isLastItem);\n\n return cloneElement(child as ReactElement, {\n isDisabled: isChildDisabled,\n isRequired,\n isReadOnly,\n isInvalid,\n isLastItem,\n selected: selected.includes(child.props.value),\n onChange: handleChange,\n \"aria-describedby\": describedBy,\n });\n }\n\n return child;\n })}\n </div>\n {errorMessage && (\n <ErrorMessage id={errorMessageId} errorMessage={errorMessage} />\n )}\n </div>\n );\n});\n"],"names":["CheckboxGroup","forwardRef","props","ref","label","isDisabled","isRequired","validationState","isInvalid","orientation","onChange","className","errorMessage","children","defaultValue","isReadOnly","itemsPerRow","lastItemDisables","rest","selected","setSelected","useState","checkboxGroupClasses","classNames","validationClasses","useValidationClasses","labelClasses","errorMessageId","useId","shouldErrorMessageShow","undefined","describedBy","spaceDelimitedList","labelId","handleChange","event","isLastItem","target","value","checked","newValue","filter","item","childrenArray","Children","toArray","lastCheckbox","child","isValidElement","type","Checkbox","pop","lastCheckboxIsChecked","includes","div","aria-labelledby","role","style","count","Label","elementType","id","map","isChildDisabled","cloneElement","ErrorMessage"],"mappings":"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"}
|
|
@@ -24,7 +24,7 @@ function _interop_require_default(obj) {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
const Combobox = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
27
|
-
const { defaultValue, options, asyncOptions, delay, minLength, onSelected, className, placeholder, icon, ...otherProps } = props;
|
|
27
|
+
const { id, defaultValue, options, asyncOptions, delay, minLength, onSelected, className, placeholder, icon, ...otherProps } = props;
|
|
28
28
|
const fallbackRef = (0, _react.useRef)(null);
|
|
29
29
|
const [inputValue, setInputValue] = (0, _react.useState)(defaultValue || "");
|
|
30
30
|
const [isOpen, setIsOpen] = (0, _react.useState)(false);
|
|
@@ -121,6 +121,7 @@ const Combobox = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
|
121
121
|
"mobius-combobox--is-loading": isLoading
|
|
122
122
|
}, className);
|
|
123
123
|
return /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
|
|
124
|
+
id: id,
|
|
124
125
|
"data-testid": "mobius-combobox__wrapper",
|
|
125
126
|
className: classes,
|
|
126
127
|
children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/Combobox/Combobox.tsx"],"sourcesContent":["import classNames from \"classnames/dedupe\";\nimport { forwardRef, useId, useRef, useState } from \"react\";\nimport { useOnUnmount } from \"../../hooks\";\nimport type { ForwardedRefComponent } from \"../../types\";\nimport { TextField } from \"../TextField\";\nimport { VisuallyHidden } from \"../VisuallyHidden\";\nimport { Listbox } from \"./Listbox\"; // Import Listbox component\nimport type {\n ComboboxElementType,\n ComboboxOption,\n ComboboxProps,\n ComboboxRef,\n} from \"./types\";\nimport { useComboboxHighlight } from \"./useComboboxHighlight\";\nimport { useComboboxOptions } from \"./useComboboxOptions\";\nimport { getOptionValue, isOptionGroup } from \"./utils\";\n\nexport const Combobox: ForwardedRefComponent<\n ComboboxProps,\n ComboboxElementType\n> = forwardRef((props: ComboboxProps, ref: ComboboxRef) => {\n const {\n defaultValue,\n options,\n asyncOptions,\n delay,\n minLength,\n onSelected,\n className,\n placeholder,\n icon,\n ...otherProps\n } = props;\n\n const fallbackRef = useRef<HTMLInputElement>(null);\n const [inputValue, setInputValue] = useState(defaultValue || \"\");\n const [isOpen, setIsOpen] = useState(false);\n const { filteredOptions, isLoading } = useComboboxOptions({\n options,\n asyncOptions,\n inputValue,\n delay,\n minLength,\n });\n const {\n highlightedIndex,\n highlightedGroupIndex,\n highlightNextOption,\n highlightPreviousOption,\n highlightFirstOption,\n highlightLastOption,\n clearHighlight,\n } = useComboboxHighlight(filteredOptions);\n\n const inputRef = ref || fallbackRef;\n const listboxId = useId();\n const statusId = useId();\n const blurTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const showListbox = isOpen && filteredOptions.length > 0;\n\n const handleFocus = () => {\n if (filteredOptions.length === 0) return;\n if (blurTimeoutRef.current) {\n clearTimeout(blurTimeoutRef.current);\n blurTimeoutRef.current = null;\n }\n setIsOpen(true);\n };\n\n const handleBlur = () => {\n blurTimeoutRef.current = setTimeout(() => {\n setIsOpen(false);\n }, 150);\n };\n\n useOnUnmount(() => {\n if (blurTimeoutRef.current) {\n clearTimeout(blurTimeoutRef.current);\n }\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n setInputValue(newValue);\n setIsOpen(true);\n clearHighlight();\n };\n\n const handleOptionSelect = (option: ComboboxOption) => {\n const value = getOptionValue(option);\n if (!value) return;\n setIsOpen(false);\n setInputValue(value);\n onSelected?.(option);\n };\n\n function getHighlightedOption() {\n if (highlightedIndex === -1) return undefined;\n\n if (isOptionGroup(filteredOptions)) {\n const group = filteredOptions[highlightedGroupIndex];\n return group?.options[highlightedIndex];\n }\n\n return filteredOptions[highlightedIndex];\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n setIsOpen(true);\n highlightNextOption();\n break;\n case \"ArrowUp\":\n e.preventDefault();\n setIsOpen(true);\n highlightPreviousOption();\n break;\n case \"Home\":\n e.preventDefault();\n setIsOpen(true);\n highlightFirstOption();\n break;\n case \"End\":\n e.preventDefault();\n setIsOpen(true);\n highlightLastOption();\n break;\n case \"Enter\":\n e.preventDefault();\n if (isOpen) {\n handleOptionSelect(getHighlightedOption()!);\n }\n break;\n case \"Escape\":\n e.preventDefault();\n setIsOpen(false);\n clearHighlight();\n break;\n default:\n // Do nothing\n }\n };\n\n const classes = classNames(\n \"mobius mobius-combobox\",\n {\n \"mobius-combobox--is-expanded\": isOpen,\n \"mobius-combobox--is-loading\": isLoading,\n },\n className,\n );\n\n return (\n <div data-testid=\"mobius-combobox__wrapper\" className={classes}>\n {isLoading && (\n <VisuallyHidden\n role=\"status\"\n aria-live=\"polite\"\n id={statusId}\n elementType=\"div\"\n className=\"mobius-combobox__status\"\n >\n Loading options\n </VisuallyHidden>\n )}\n <TextField\n {...otherProps}\n className=\"mobius-combobox__input\"\n role=\"combobox\"\n value={inputValue}\n placeholder={placeholder}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onChange={handleInputChange}\n autoComplete=\"off\"\n aria-describedby={isLoading ? statusId : undefined}\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n aria-controls={listboxId}\n aria-expanded={isOpen}\n aria-activedescendant={\n highlightedIndex === -1\n ? undefined\n : `${listboxId}-option-${highlightedGroupIndex}-${highlightedIndex}`\n }\n prefixInside={icon}\n ref={inputRef}\n />\n {showListbox && (\n <Listbox\n id={listboxId}\n options={filteredOptions}\n highlightedIndex={highlightedIndex}\n highlightedGroupIndex={highlightedGroupIndex}\n onOptionSelect={handleOptionSelect}\n />\n )}\n </div>\n );\n});\n"],"names":["Combobox","forwardRef","props","ref","defaultValue","options","asyncOptions","delay","minLength","onSelected","className","placeholder","icon","otherProps","fallbackRef","useRef","inputValue","setInputValue","useState","isOpen","setIsOpen","filteredOptions","isLoading","useComboboxOptions","highlightedIndex","highlightedGroupIndex","highlightNextOption","highlightPreviousOption","highlightFirstOption","highlightLastOption","clearHighlight","useComboboxHighlight","inputRef","listboxId","useId","statusId","blurTimeoutRef","showListbox","length","handleFocus","current","clearTimeout","handleBlur","setTimeout","useOnUnmount","handleInputChange","e","newValue","target","value","handleOptionSelect","option","getOptionValue","getHighlightedOption","undefined","isOptionGroup","group","handleKeyDown","key","preventDefault","classes","classNames","div","data-testid","VisuallyHidden","role","aria-live","
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/Combobox/Combobox.tsx"],"sourcesContent":["import classNames from \"classnames/dedupe\";\nimport { forwardRef, useId, useRef, useState } from \"react\";\nimport { useOnUnmount } from \"../../hooks\";\nimport type { ForwardedRefComponent } from \"../../types\";\nimport { TextField } from \"../TextField\";\nimport { VisuallyHidden } from \"../VisuallyHidden\";\nimport { Listbox } from \"./Listbox\"; // Import Listbox component\nimport type {\n ComboboxElementType,\n ComboboxOption,\n ComboboxProps,\n ComboboxRef,\n} from \"./types\";\nimport { useComboboxHighlight } from \"./useComboboxHighlight\";\nimport { useComboboxOptions } from \"./useComboboxOptions\";\nimport { getOptionValue, isOptionGroup } from \"./utils\";\n\nexport const Combobox: ForwardedRefComponent<\n ComboboxProps,\n ComboboxElementType\n> = forwardRef((props: ComboboxProps, ref: ComboboxRef) => {\n const {\n id,\n defaultValue,\n options,\n asyncOptions,\n delay,\n minLength,\n onSelected,\n className,\n placeholder,\n icon,\n ...otherProps\n } = props;\n\n const fallbackRef = useRef<HTMLInputElement>(null);\n const [inputValue, setInputValue] = useState(defaultValue || \"\");\n const [isOpen, setIsOpen] = useState(false);\n const { filteredOptions, isLoading } = useComboboxOptions({\n options,\n asyncOptions,\n inputValue,\n delay,\n minLength,\n });\n const {\n highlightedIndex,\n highlightedGroupIndex,\n highlightNextOption,\n highlightPreviousOption,\n highlightFirstOption,\n highlightLastOption,\n clearHighlight,\n } = useComboboxHighlight(filteredOptions);\n\n const inputRef = ref || fallbackRef;\n const listboxId = useId();\n const statusId = useId();\n const blurTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const showListbox = isOpen && filteredOptions.length > 0;\n\n const handleFocus = () => {\n if (filteredOptions.length === 0) return;\n if (blurTimeoutRef.current) {\n clearTimeout(blurTimeoutRef.current);\n blurTimeoutRef.current = null;\n }\n setIsOpen(true);\n };\n\n const handleBlur = () => {\n blurTimeoutRef.current = setTimeout(() => {\n setIsOpen(false);\n }, 150);\n };\n\n useOnUnmount(() => {\n if (blurTimeoutRef.current) {\n clearTimeout(blurTimeoutRef.current);\n }\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n setInputValue(newValue);\n setIsOpen(true);\n clearHighlight();\n };\n\n const handleOptionSelect = (option: ComboboxOption) => {\n const value = getOptionValue(option);\n if (!value) return;\n setIsOpen(false);\n setInputValue(value);\n onSelected?.(option);\n };\n\n function getHighlightedOption() {\n if (highlightedIndex === -1) return undefined;\n\n if (isOptionGroup(filteredOptions)) {\n const group = filteredOptions[highlightedGroupIndex];\n return group?.options[highlightedIndex];\n }\n\n return filteredOptions[highlightedIndex];\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n setIsOpen(true);\n highlightNextOption();\n break;\n case \"ArrowUp\":\n e.preventDefault();\n setIsOpen(true);\n highlightPreviousOption();\n break;\n case \"Home\":\n e.preventDefault();\n setIsOpen(true);\n highlightFirstOption();\n break;\n case \"End\":\n e.preventDefault();\n setIsOpen(true);\n highlightLastOption();\n break;\n case \"Enter\":\n e.preventDefault();\n if (isOpen) {\n handleOptionSelect(getHighlightedOption()!);\n }\n break;\n case \"Escape\":\n e.preventDefault();\n setIsOpen(false);\n clearHighlight();\n break;\n default:\n // Do nothing\n }\n };\n\n const classes = classNames(\n \"mobius mobius-combobox\",\n {\n \"mobius-combobox--is-expanded\": isOpen,\n \"mobius-combobox--is-loading\": isLoading,\n },\n className,\n );\n\n return (\n <div id={id} data-testid=\"mobius-combobox__wrapper\" className={classes}>\n {isLoading && (\n <VisuallyHidden\n role=\"status\"\n aria-live=\"polite\"\n id={statusId}\n elementType=\"div\"\n className=\"mobius-combobox__status\"\n >\n Loading options\n </VisuallyHidden>\n )}\n <TextField\n {...otherProps}\n className=\"mobius-combobox__input\"\n role=\"combobox\"\n value={inputValue}\n placeholder={placeholder}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onChange={handleInputChange}\n autoComplete=\"off\"\n aria-describedby={isLoading ? statusId : undefined}\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n aria-controls={listboxId}\n aria-expanded={isOpen}\n aria-activedescendant={\n highlightedIndex === -1\n ? undefined\n : `${listboxId}-option-${highlightedGroupIndex}-${highlightedIndex}`\n }\n prefixInside={icon}\n ref={inputRef}\n />\n {showListbox && (\n <Listbox\n id={listboxId}\n options={filteredOptions}\n highlightedIndex={highlightedIndex}\n highlightedGroupIndex={highlightedGroupIndex}\n onOptionSelect={handleOptionSelect}\n />\n )}\n </div>\n );\n});\n"],"names":["Combobox","forwardRef","props","ref","id","defaultValue","options","asyncOptions","delay","minLength","onSelected","className","placeholder","icon","otherProps","fallbackRef","useRef","inputValue","setInputValue","useState","isOpen","setIsOpen","filteredOptions","isLoading","useComboboxOptions","highlightedIndex","highlightedGroupIndex","highlightNextOption","highlightPreviousOption","highlightFirstOption","highlightLastOption","clearHighlight","useComboboxHighlight","inputRef","listboxId","useId","statusId","blurTimeoutRef","showListbox","length","handleFocus","current","clearTimeout","handleBlur","setTimeout","useOnUnmount","handleInputChange","e","newValue","target","value","handleOptionSelect","option","getOptionValue","getHighlightedOption","undefined","isOptionGroup","group","handleKeyDown","key","preventDefault","classes","classNames","div","data-testid","VisuallyHidden","role","aria-live","elementType","TextField","onFocus","onBlur","onKeyDown","onChange","autoComplete","aria-describedby","aria-autocomplete","aria-haspopup","aria-controls","aria-expanded","aria-activedescendant","prefixInside","Listbox","onOptionSelect"],"mappings":";;;;+BAiBaA;;;eAAAA;;;;+DAjBU;uBAC6B;uBACvB;2BAEH;gCACK;yBACP;sCAOa;oCACF;uBACW;;;;;;AAEvC,MAAMA,yBAGTC,IAAAA,iBAAU,EAAC,CAACC,OAAsBC;IACpC,MAAM,EACJC,EAAE,EACFC,YAAY,EACZC,OAAO,EACPC,YAAY,EACZC,KAAK,EACLC,SAAS,EACTC,UAAU,EACVC,SAAS,EACTC,WAAW,EACXC,IAAI,EACJ,GAAGC,YACJ,GAAGZ;IAEJ,MAAMa,cAAcC,IAAAA,aAAM,EAAmB;IAC7C,MAAM,CAACC,YAAYC,cAAc,GAAGC,IAAAA,eAAQ,EAACd,gBAAgB;IAC7D,MAAM,CAACe,QAAQC,UAAU,GAAGF,IAAAA,eAAQ,EAAC;IACrC,MAAM,EAAEG,eAAe,EAAEC,SAAS,EAAE,GAAGC,IAAAA,sCAAkB,EAAC;QACxDlB;QACAC;QACAU;QACAT;QACAC;IACF;IACA,MAAM,EACJgB,gBAAgB,EAChBC,qBAAqB,EACrBC,mBAAmB,EACnBC,uBAAuB,EACvBC,oBAAoB,EACpBC,mBAAmB,EACnBC,cAAc,EACf,GAAGC,IAAAA,0CAAoB,EAACV;IAEzB,MAAMW,WAAW9B,OAAOY;IACxB,MAAMmB,YAAYC,IAAAA,YAAK;IACvB,MAAMC,WAAWD,IAAAA,YAAK;IACtB,MAAME,iBAAiBrB,IAAAA,aAAM,EAAwB;IACrD,MAAMsB,cAAclB,UAAUE,gBAAgBiB,MAAM,GAAG;IAEvD,MAAMC,cAAc;QAClB,IAAIlB,gBAAgBiB,MAAM,KAAK,GAAG;QAClC,IAAIF,eAAeI,OAAO,EAAE;YAC1BC,aAAaL,eAAeI,OAAO;YACnCJ,eAAeI,OAAO,GAAG;QAC3B;QACApB,UAAU;IACZ;IAEA,MAAMsB,aAAa;QACjBN,eAAeI,OAAO,GAAGG,WAAW;YAClCvB,UAAU;QACZ,GAAG;IACL;IAEAwB,IAAAA,mBAAY,EAAC;QACX,IAAIR,eAAeI,OAAO,EAAE;YAC1BC,aAAaL,eAAeI,OAAO;QACrC;IACF;IAEA,MAAMK,oBAAoB,CAACC;QACzB,MAAMC,WAAWD,EAAEE,MAAM,CAACC,KAAK;QAC/BhC,cAAc8B;QACd3B,UAAU;QACVU;IACF;IAEA,MAAMoB,qBAAqB,CAACC;QAC1B,MAAMF,QAAQG,IAAAA,qBAAc,EAACD;QAC7B,IAAI,CAACF,OAAO;QACZ7B,UAAU;QACVH,cAAcgC;QACdxC,uBAAAA,iCAAAA,WAAa0C;IACf;IAEA,SAASE;QACP,IAAI7B,qBAAqB,CAAC,GAAG,OAAO8B;QAEpC,IAAIC,IAAAA,oBAAa,EAAClC,kBAAkB;YAClC,MAAMmC,QAAQnC,eAAe,CAACI,sBAAsB;YACpD,OAAO+B,kBAAAA,4BAAAA,MAAOnD,OAAO,CAACmB,iBAAiB;QACzC;QAEA,OAAOH,eAAe,CAACG,iBAAiB;IAC1C;IAEA,MAAMiC,gBAAgB,CAACX;QACrB,OAAQA,EAAEY,GAAG;YACX,KAAK;gBACHZ,EAAEa,cAAc;gBAChBvC,UAAU;gBACVM;gBACA;YACF,KAAK;gBACHoB,EAAEa,cAAc;gBAChBvC,UAAU;gBACVO;gBACA;YACF,KAAK;gBACHmB,EAAEa,cAAc;gBAChBvC,UAAU;gBACVQ;gBACA;YACF,KAAK;gBACHkB,EAAEa,cAAc;gBAChBvC,UAAU;gBACVS;gBACA;YACF,KAAK;gBACHiB,EAAEa,cAAc;gBAChB,IAAIxC,QAAQ;oBACV+B,mBAAmBG;gBACrB;gBACA;YACF,KAAK;gBACHP,EAAEa,cAAc;gBAChBvC,UAAU;gBACVU;gBACA;YACF;QAEF;IACF;IAEA,MAAM8B,UAAUC,IAAAA,eAAU,EACxB,0BACA;QACE,gCAAgC1C;QAChC,+BAA+BG;IACjC,GACAZ;IAGF,qBACE,sBAACoD;QAAI3D,IAAIA;QAAI4D,eAAY;QAA2BrD,WAAWkD;;YAC5DtC,2BACC,qBAAC0C,8BAAc;gBACbC,MAAK;gBACLC,aAAU;gBACV/D,IAAIgC;gBACJgC,aAAY;gBACZzD,WAAU;0BACX;;0BAIH,qBAAC0D,oBAAS;gBACP,GAAGvD,UAAU;gBACdH,WAAU;gBACVuD,MAAK;gBACLhB,OAAOjC;gBACPL,aAAaA;gBACb0D,SAAS9B;gBACT+B,QAAQ5B;gBACR6B,WAAWd;gBACXe,UAAU3B;gBACV4B,cAAa;gBACbC,oBAAkBpD,YAAYa,WAAWmB;gBACzCqB,qBAAkB;gBAClBC,iBAAc;gBACdC,iBAAe5C;gBACf6C,iBAAe3D;gBACf4D,yBACEvD,qBAAqB,CAAC,IAClB8B,YACA,GAAGrB,UAAU,QAAQ,EAAER,sBAAsB,CAAC,EAAED,kBAAkB;gBAExEwD,cAAcpE;gBACdV,KAAK8B;;YAENK,6BACC,qBAAC4C,gBAAO;gBACN9E,IAAI8B;gBACJ5B,SAASgB;gBACTG,kBAAkBA;gBAClBC,uBAAuBA;gBACvByD,gBAAgBhC;;;;AAK1B"}
|