@forgeax/view 0.4.1 → 0.4.2

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.
Files changed (128) hide show
  1. package/README.md +21 -7
  2. package/dist/build-revision.json +1 -1
  3. package/dist/modules/backend.mjs +11 -11
  4. package/dist/modules/browser.mjs +16 -16
  5. package/dist/modules/chunks/{App-E3M52XTQ.mjs → App-4XQ5SNNT.mjs} +2 -2
  6. package/dist/modules/chunks/{chunk-3GIGTM7E.mjs → chunk-27XASYEH.mjs} +2 -2
  7. package/dist/modules/chunks/{chunk-UAGQZPAB.mjs → chunk-2Z5KEV6L.mjs} +2 -2
  8. package/dist/modules/chunks/{chunk-4NGODRIE.mjs → chunk-46UEGAXY.mjs} +4 -4
  9. package/dist/modules/chunks/{chunk-UZHTLAIZ.mjs → chunk-47RJSHLM.mjs} +2 -2
  10. package/dist/modules/chunks/{chunk-L5EV6NEE.mjs → chunk-4JGCYD3Q.mjs} +3 -3
  11. package/dist/modules/chunks/{chunk-ACOMGSSB.mjs → chunk-5PHAXNFO.mjs} +2 -2
  12. package/dist/modules/chunks/{chunk-45ZU2HHR.mjs → chunk-B6QUJ33G.mjs} +27 -23
  13. package/dist/modules/chunks/chunk-B6QUJ33G.mjs.map +7 -0
  14. package/dist/modules/chunks/{chunk-FKLYSAVN.mjs → chunk-CXOD7FW6.mjs} +7 -4
  15. package/dist/modules/chunks/chunk-CXOD7FW6.mjs.map +7 -0
  16. package/dist/modules/chunks/{chunk-CRNEX7YH.mjs → chunk-D25SR5FS.mjs} +2 -2
  17. package/dist/modules/chunks/{chunk-PG4AJFDC.mjs → chunk-DJZGRO7W.mjs} +12 -12
  18. package/dist/modules/chunks/{chunk-MHE5EBU4.mjs → chunk-E3PJGTLI.mjs} +22 -14
  19. package/dist/modules/chunks/chunk-E3PJGTLI.mjs.map +7 -0
  20. package/dist/modules/chunks/{chunk-3Q26HNFS.mjs → chunk-FICPCJKR.mjs} +2 -2
  21. package/dist/modules/chunks/{chunk-CWNB67UF.mjs → chunk-FMCHH5R4.mjs} +2 -2
  22. package/dist/modules/chunks/{chunk-TTFLJHQZ.mjs → chunk-H4UIESCF.mjs} +6 -6
  23. package/dist/modules/chunks/{chunk-TTFLJHQZ.mjs.map → chunk-H4UIESCF.mjs.map} +1 -1
  24. package/dist/modules/chunks/{chunk-MO5LILCP.mjs → chunk-HWZCLROY.mjs} +6 -2
  25. package/dist/modules/chunks/chunk-HWZCLROY.mjs.map +7 -0
  26. package/dist/modules/chunks/{chunk-2VJPRNYB.mjs → chunk-IZAHIOFU.mjs} +4 -4
  27. package/dist/modules/chunks/{chunk-BGK4ZEQ5.mjs → chunk-KX2WU5Z6.mjs} +2 -2
  28. package/dist/modules/chunks/{chunk-TBZZ37VI.mjs → chunk-KYTG2MKV.mjs} +3 -3
  29. package/dist/modules/chunks/{chunk-M5X56JWH.mjs → chunk-PW5CE2Y6.mjs} +3 -3
  30. package/dist/modules/chunks/{chunk-OHVTNEQ2.mjs → chunk-PZIAKZJC.mjs} +2 -2
  31. package/dist/modules/chunks/{chunk-WHVPE2P6.mjs → chunk-Q2ZYLFJM.mjs} +4 -4
  32. package/dist/modules/chunks/{chunk-WHVPE2P6.mjs.map → chunk-Q2ZYLFJM.mjs.map} +1 -1
  33. package/dist/modules/chunks/{chunk-JZ3V27HQ.mjs → chunk-U64FRQKP.mjs} +3 -3
  34. package/dist/modules/chunks/{chunk-W46L4HSP.mjs → chunk-U6UMATPV.mjs} +3 -3
  35. package/dist/modules/chunks/{chunk-7ICJKZYO.mjs → chunk-VKNIYV2W.mjs} +26 -21
  36. package/dist/modules/chunks/chunk-VKNIYV2W.mjs.map +7 -0
  37. package/dist/modules/chunks/{chunk-7R6CGQDU.mjs → chunk-VW2ZF3P4.mjs} +4 -4
  38. package/dist/modules/chunks/{chunk-AIIYGGGC.mjs → chunk-X4NNZ5X6.mjs} +2 -2
  39. package/dist/modules/chunks/{chunk-BCTPTLA6.mjs → chunk-XEE3E42Q.mjs} +3 -3
  40. package/dist/modules/chunks/{chunk-CDO6LELS.mjs → chunk-Y2IAXE2C.mjs} +3 -3
  41. package/dist/modules/chunks/{chunk-6WCG6WPC.mjs → chunk-YNHEYXDG.mjs} +3 -3
  42. package/dist/modules/chunks/{chunk-7MJUWNVI.mjs → chunk-ZGOGO7SS.mjs} +1 -1
  43. package/dist/modules/chunks/{chunk-VXSD4FK5.mjs → chunk-ZHO2G4JR.mjs} +3 -3
  44. package/dist/modules/embedded.mjs +100 -21
  45. package/dist/modules/embedded.mjs.map +3 -3
  46. package/dist/modules/frontend-root.mjs +15 -15
  47. package/dist/modules/index.mjs +21 -21
  48. package/dist/modules/plugin.mjs +11 -11
  49. package/dist/modules/plugins/asset/frontend.mjs +4 -4
  50. package/dist/modules/plugins/asset/identity.mjs +3 -3
  51. package/dist/modules/plugins/asset/ui.mjs +2 -2
  52. package/dist/modules/plugins/content-browser/ui.mjs +2 -2
  53. package/dist/modules/plugins/inspector/ui.mjs +2 -2
  54. package/dist/modules/plugins/material/frontend.mjs +4 -4
  55. package/dist/modules/plugins/material/identity.mjs +3 -3
  56. package/dist/modules/plugins/material/ui.mjs +5 -5
  57. package/dist/modules/plugins/mesh/frontend.mjs +4 -4
  58. package/dist/modules/plugins/mesh/identity.mjs +3 -3
  59. package/dist/modules/plugins/mesh/ui.mjs +5 -5
  60. package/dist/modules/plugins/plugins/ui/panel.mjs +2 -2
  61. package/dist/modules/plugins/plugins/ui.mjs +3 -3
  62. package/dist/modules/plugins/scene-tree/ui.mjs +2 -2
  63. package/dist/modules/plugins/texture/frontend.mjs +4 -4
  64. package/dist/modules/plugins/texture/identity.mjs +3 -3
  65. package/dist/modules/plugins/texture/ui.mjs +5 -5
  66. package/dist/modules/plugins/viewport/frontend.mjs +1 -1
  67. package/dist/modules/product.mjs +11 -11
  68. package/dist/modules/shell/frontend.mjs +1 -1
  69. package/dist/modules/viewer/catalog/backend.mjs +10 -10
  70. package/dist/modules/viewer/catalog/frontend.mjs +14 -14
  71. package/dist/modules/viewer/catalog/shared.mjs +7 -7
  72. package/dist/modules/viewer/catalog.mjs +17 -17
  73. package/dist/modules/viewer-host/frontend.mjs +16 -16
  74. package/dist/modules/viewer.mjs +17 -17
  75. package/dist/modules/workspace/backend.mjs +2 -2
  76. package/dist/modules/workspace/broker.mjs +1 -1
  77. package/dist/modules/workspace/preview-surface.mjs +1 -1
  78. package/dist/modules/workspace/resource-page.mjs +2 -2
  79. package/dist/viewer/assets/{embedded-DWrXFZbD.js → embedded-Ch4NawY-.js} +2 -2
  80. package/dist/viewer/assets/{embedded-DWrXFZbD.js.map → embedded-Ch4NawY-.js.map} +1 -1
  81. package/dist/viewer/assets/main-DUQJ1NlR.js +22 -0
  82. package/dist/viewer/assets/main-DUQJ1NlR.js.map +1 -0
  83. package/dist/viewer/assets/{panels-lazy-CUTQACqc.js → panels-lazy-DbOAvYN1.js} +3 -3
  84. package/dist/viewer/assets/{panels-lazy-CUTQACqc.js.map → panels-lazy-DbOAvYN1.js.map} +1 -1
  85. package/dist/viewer/assets/panels-ui-DICIsCag.js +12 -0
  86. package/dist/viewer/assets/panels-ui-DICIsCag.js.map +1 -0
  87. package/dist/viewer/assets/style-gOtSMZif.css +2 -0
  88. package/dist/viewer/index.html +4 -4
  89. package/dist/viewer/panels.js +1 -1
  90. package/package.json +3 -4
  91. package/scripts/browser-proof-workload.mjs +0 -1
  92. package/scripts/verify-runtime-content-engine.mjs +12 -6
  93. package/dist/modules/chunks/chunk-45ZU2HHR.mjs.map +0 -7
  94. package/dist/modules/chunks/chunk-7ICJKZYO.mjs.map +0 -7
  95. package/dist/modules/chunks/chunk-FKLYSAVN.mjs.map +0 -7
  96. package/dist/modules/chunks/chunk-MHE5EBU4.mjs.map +0 -7
  97. package/dist/modules/chunks/chunk-MO5LILCP.mjs.map +0 -7
  98. package/dist/viewer/assets/main-D0JG9szD.js +0 -22
  99. package/dist/viewer/assets/main-D0JG9szD.js.map +0 -1
  100. package/dist/viewer/assets/panels-ui-Kvu5G7za.js +0 -12
  101. package/dist/viewer/assets/panels-ui-Kvu5G7za.js.map +0 -1
  102. package/dist/viewer/assets/style-BM0losky.css +0 -2
  103. package/scripts/verify-game3d-workspace.mjs +0 -318
  104. /package/dist/modules/chunks/{App-E3M52XTQ.mjs.map → App-4XQ5SNNT.mjs.map} +0 -0
  105. /package/dist/modules/chunks/{chunk-3GIGTM7E.mjs.map → chunk-27XASYEH.mjs.map} +0 -0
  106. /package/dist/modules/chunks/{chunk-UAGQZPAB.mjs.map → chunk-2Z5KEV6L.mjs.map} +0 -0
  107. /package/dist/modules/chunks/{chunk-4NGODRIE.mjs.map → chunk-46UEGAXY.mjs.map} +0 -0
  108. /package/dist/modules/chunks/{chunk-UZHTLAIZ.mjs.map → chunk-47RJSHLM.mjs.map} +0 -0
  109. /package/dist/modules/chunks/{chunk-L5EV6NEE.mjs.map → chunk-4JGCYD3Q.mjs.map} +0 -0
  110. /package/dist/modules/chunks/{chunk-ACOMGSSB.mjs.map → chunk-5PHAXNFO.mjs.map} +0 -0
  111. /package/dist/modules/chunks/{chunk-CRNEX7YH.mjs.map → chunk-D25SR5FS.mjs.map} +0 -0
  112. /package/dist/modules/chunks/{chunk-PG4AJFDC.mjs.map → chunk-DJZGRO7W.mjs.map} +0 -0
  113. /package/dist/modules/chunks/{chunk-3Q26HNFS.mjs.map → chunk-FICPCJKR.mjs.map} +0 -0
  114. /package/dist/modules/chunks/{chunk-CWNB67UF.mjs.map → chunk-FMCHH5R4.mjs.map} +0 -0
  115. /package/dist/modules/chunks/{chunk-2VJPRNYB.mjs.map → chunk-IZAHIOFU.mjs.map} +0 -0
  116. /package/dist/modules/chunks/{chunk-BGK4ZEQ5.mjs.map → chunk-KX2WU5Z6.mjs.map} +0 -0
  117. /package/dist/modules/chunks/{chunk-TBZZ37VI.mjs.map → chunk-KYTG2MKV.mjs.map} +0 -0
  118. /package/dist/modules/chunks/{chunk-M5X56JWH.mjs.map → chunk-PW5CE2Y6.mjs.map} +0 -0
  119. /package/dist/modules/chunks/{chunk-OHVTNEQ2.mjs.map → chunk-PZIAKZJC.mjs.map} +0 -0
  120. /package/dist/modules/chunks/{chunk-JZ3V27HQ.mjs.map → chunk-U64FRQKP.mjs.map} +0 -0
  121. /package/dist/modules/chunks/{chunk-W46L4HSP.mjs.map → chunk-U6UMATPV.mjs.map} +0 -0
  122. /package/dist/modules/chunks/{chunk-7R6CGQDU.mjs.map → chunk-VW2ZF3P4.mjs.map} +0 -0
  123. /package/dist/modules/chunks/{chunk-AIIYGGGC.mjs.map → chunk-X4NNZ5X6.mjs.map} +0 -0
  124. /package/dist/modules/chunks/{chunk-BCTPTLA6.mjs.map → chunk-XEE3E42Q.mjs.map} +0 -0
  125. /package/dist/modules/chunks/{chunk-CDO6LELS.mjs.map → chunk-Y2IAXE2C.mjs.map} +0 -0
  126. /package/dist/modules/chunks/{chunk-6WCG6WPC.mjs.map → chunk-YNHEYXDG.mjs.map} +0 -0
  127. /package/dist/modules/chunks/{chunk-7MJUWNVI.mjs.map → chunk-ZGOGO7SS.mjs.map} +0 -0
  128. /package/dist/modules/chunks/{chunk-VXSD4FK5.mjs.map → chunk-ZHO2G4JR.mjs.map} +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../packages/view-components/src/components.tsx", "../../../packages/view-components/src/menuPlacement.ts", "../../../packages/view-components/src/theme.tsx", "../../../packages/view-components/src/tokens.ts", "../../../packages/view-components/src/useWorkspaceClientConnected.ts", "../../../packages/view-components/src/inspector-form-model.ts", "../../../packages/view-components/src/InspectorForm.tsx", "../../../packages/view-components/src/ErrorNotice.tsx", "../../../packages/view-components/src/PageTabStrip.tsx", "../../../packages/view-components/src/page-tab-icons.ts"],
4
+ "sourcesContent": ["import {\n AlertCircle,\n Check,\n ChevronDown,\n ChevronRight,\n CircleAlert,\n CircleCheck,\n Info,\n LoaderCircle,\n Search,\n X,\n type LucideIcon,\n} from 'lucide-react';\nimport {\n cloneElement,\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n type ComponentPropsWithoutRef,\n type ElementType,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type RefObject,\n type SelectHTMLAttributes,\n type TextareaHTMLAttributes,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n resolveFloatingMenuPosition,\n resolveMenuDropdownPosition,\n type AnchorRect,\n} from './menuPlacement';\n\nconst OverlayRootContext = createContext<HTMLElement | null>(null);\n/** The embedding owner supplies the lifetime and document of all View overlays. */\nexport function OverlayRootProvider({ root, children }: { root: HTMLElement; children: ReactNode }) {\n return <OverlayRootContext.Provider value={root}>{children}</OverlayRootContext.Provider>;\n}\nexport function useOverlayRoot() { return useContext(OverlayRootContext); }\n\nfunction classes(...names: Array<string | false | null | undefined>) {\n return names.filter(Boolean).join(' ');\n}\n\nexport type TextVariant =\n | 'title'\n | 'heading'\n | 'body'\n | 'ui'\n | 'label'\n | 'compact'\n | 'caption'\n | 'code';\n\nexport type TextProps = HTMLAttributes<HTMLElement> & {\n as?: ElementType;\n variant?: TextVariant;\n tone?: 'primary' | 'secondary' | 'muted';\n};\n\nexport function Text({\n as: Component = 'p',\n variant = 'ui',\n tone = 'primary',\n className,\n ...props\n}: TextProps) {\n return (\n <Component\n {...props}\n className={classes(\n 'fx-text',\n `fx-text--${variant}`,\n tone !== 'primary' && `fx-text--${tone}`,\n className,\n )}\n />\n );\n}\n\nexport type SurfaceProps = HTMLAttributes<HTMLDivElement> & {\n tone?: 'canvas' | 'sidebar' | 'raised' | 'inset';\n card?: boolean;\n};\n\nexport const Surface = forwardRef<HTMLDivElement, SurfaceProps>(function Surface(\n { tone = 'canvas', card = false, className, ...props },\n ref,\n) {\n return (\n <div\n {...props}\n ref={ref}\n className={classes('fx-surface', `fx-surface--${tone}`, card && 'fx-surface--card', className)}\n />\n );\n});\n\nexport function Divider(props: ComponentPropsWithoutRef<'hr'>) {\n return <hr {...props} className={classes('fx-divider', props.className)} />;\n}\n\nexport function Icon({\n icon: Glyph,\n label,\n className,\n}: {\n icon: LucideIcon;\n label?: string;\n className?: string;\n}) {\n return (\n <Glyph\n className={classes('fx-icon', className)}\n aria-hidden={label ? undefined : true}\n aria-label={label}\n role={label ? 'img' : undefined}\n />\n );\n}\n\nexport const Link = forwardRef<HTMLAnchorElement, ComponentPropsWithoutRef<'a'>>(function Link(\n { className, ...props },\n ref,\n) {\n return <a {...props} ref={ref} className={classes('fx-link', className)} />;\n});\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'quiet' | 'danger';\nexport type ControlSize = 'compact' | 'default' | 'large';\n\nexport type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n variant?: ButtonVariant;\n size?: ControlSize;\n loading?: boolean;\n leadingIcon?: ReactNode;\n trailingIcon?: ReactNode;\n};\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n variant = 'secondary',\n size = 'default',\n loading = false,\n leadingIcon,\n trailingIcon,\n disabled,\n className,\n children,\n type = 'button',\n ...props\n },\n ref,\n) {\n return (\n <button\n {...props}\n ref={ref}\n type={type}\n disabled={disabled || loading}\n aria-busy={loading || undefined}\n className={classes(\n 'fx-button',\n `fx-button--${variant}`,\n size !== 'default' && `fx-button--${size}`,\n className,\n )}\n >\n {loading ? <LoaderCircle className=\"fx-icon fx-button__spinner\" aria-hidden /> : leadingIcon}\n {children}\n {!loading && trailingIcon}\n </button>\n );\n});\n\nexport type IconButtonProps = Omit<ButtonProps, 'children' | 'leadingIcon' | 'trailingIcon'> & {\n label: string;\n icon: ReactNode;\n};\n\nexport const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(function IconButton(\n { label, icon, className, ...props },\n ref,\n) {\n return (\n <Button\n {...props}\n ref={ref}\n aria-label={label}\n title={props.title ?? label}\n className={classes('fx-button--icon', className)}\n >\n {icon}\n </Button>\n );\n});\n\nexport type FieldProps = HTMLAttributes<HTMLDivElement> & {\n label: ReactNode;\n htmlFor?: string;\n note?: ReactNode;\n error?: ReactNode;\n children: ReactNode;\n};\n\nexport function Field({ label, htmlFor, note, error, children, className, ...props }: FieldProps) {\n return (\n <div {...props} className={classes('fx-field', className)}>\n <label className=\"fx-field__label\" htmlFor={htmlFor}>\n {label}\n </label>\n {children}\n {(error || note) && (\n <p className={classes('fx-field__note', Boolean(error) && 'fx-field__error')} role={error ? 'alert' : undefined}>\n {error ?? note}\n </p>\n )}\n </div>\n );\n}\n\nexport const TextInput = forwardRef<HTMLInputElement, InputHTMLAttributes<HTMLInputElement>>(\n function TextInput({ className, ...props }, ref) {\n return <input {...props} ref={ref} className={classes('fx-input', className)} />;\n },\n);\n\nexport const Select = forwardRef<HTMLSelectElement, SelectHTMLAttributes<HTMLSelectElement>>(\n function Select({ className, children, ...props }, ref) {\n return (\n <select {...props} ref={ref} className={classes('fx-input', className)}>\n {children}\n </select>\n );\n },\n);\n\nexport const TextArea = forwardRef<HTMLTextAreaElement, TextareaHTMLAttributes<HTMLTextAreaElement>>(\n function TextArea({ className, ...props }, ref) {\n return <textarea {...props} ref={ref} className={classes('fx-input', className)} />;\n },\n);\n\nexport type ChoiceTextProps = {\n label: ReactNode;\n description?: ReactNode;\n hideLabel?: boolean;\n};\n\nfunction ChoiceText({ label, description, hideLabel }: ChoiceTextProps) {\n return (\n <span className=\"fx-choice__text\">\n <span className={classes('fx-choice__label', hideLabel && 'fx-visually-hidden')}>{label}</span>\n {description ? (\n <span className={classes('fx-choice__description', hideLabel && 'fx-visually-hidden')}>{description}</span>\n ) : null}\n </span>\n );\n}\n\nexport type CheckboxProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> &\n ChoiceTextProps & {\n indeterminate?: boolean;\n };\n\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(\n { label, description, hideLabel, className, indeterminate, ...props },\n ref,\n) {\n const inputRef = useRef<HTMLInputElement>(null);\n useImperativeHandle(ref, () => inputRef.current as HTMLInputElement);\n\n useEffect(() => {\n if (inputRef.current) inputRef.current.indeterminate = Boolean(indeterminate);\n }, [indeterminate]);\n\n return (\n <label className={classes('fx-choice', 'fx-choice--checkbox', className)}>\n <input {...props} ref={inputRef} type=\"checkbox\" />\n <ChoiceText label={label} description={description} {...(hideLabel === undefined ? {} : { hideLabel })} />\n </label>\n );\n});\n\nexport type CheckboxGroupOption = {\n value: string;\n label: ReactNode;\n description?: ReactNode;\n disabled?: boolean;\n};\n\n// `Omit<...HTMLAttributes...>` drops the template index signature JSX grants\n// intrinsic elements, so prop bags that forward to host elements re-declare\n// `data-*` support explicitly.\ntype DataAttributes = { [attribute: `data-${string}`]: unknown };\n\nexport type CheckboxGroupProps = Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> & {\n name?: string;\n value?: string[];\n defaultValue?: string[];\n options: CheckboxGroupOption[];\n onChange?: (value: string[]) => void;\n layout?: 'horizontal' | 'vertical';\n legend?: ReactNode;\n disabled?: boolean;\n 'aria-label'?: string;\n};\n\nexport function CheckboxGroup({\n name,\n value,\n defaultValue,\n options,\n onChange,\n layout = 'horizontal',\n legend,\n disabled,\n className,\n 'aria-label': ariaLabel,\n ...props\n}: CheckboxGroupProps) {\n const legendId = useId();\n const fallbackName = useId();\n const [internalValue, setInternalValue] = useState<string[]>(defaultValue ?? []);\n const selected = value ?? internalValue;\n const setSelected = (next: string[]) => {\n if (value === undefined) setInternalValue(next);\n onChange?.(next);\n };\n const groupName = name ?? fallbackName;\n\n return (\n <div\n {...props}\n role=\"group\"\n aria-labelledby={legend ? legendId : undefined}\n aria-label={legend ? undefined : ariaLabel}\n className={classes('fx-choice-set', className)}\n >\n {legend ? (\n <span id={legendId} className=\"fx-choice-set__legend\">\n {legend}\n </span>\n ) : null}\n <div className={classes('fx-choice-group', layout === 'vertical' && 'fx-choice-group--vertical')}>\n {options.map((option) => {\n const checked = selected.includes(option.value);\n return (\n <Checkbox\n key={option.value}\n name={groupName}\n value={option.value}\n label={option.label}\n description={option.description}\n checked={checked}\n disabled={disabled || option.disabled}\n onChange={(event) => {\n const next = event.target.checked\n ? [...selected, option.value]\n : selected.filter((entry) => entry !== option.value);\n setSelected(next);\n }}\n />\n );\n })}\n </div>\n </div>\n );\n}\n\nexport type RadioProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> & ChoiceTextProps;\n\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(function Radio(\n { label, description, hideLabel, className, ...props },\n ref,\n) {\n return (\n <label className={classes('fx-choice', 'fx-choice--radio', className)}>\n <input {...props} ref={ref} type=\"radio\" />\n <ChoiceText label={label} description={description} {...(hideLabel === undefined ? {} : { hideLabel })} />\n </label>\n );\n});\n\nexport type RadioOption = {\n value: string;\n label: ReactNode;\n description?: ReactNode;\n disabled?: boolean;\n};\n\nexport type RadioGroupProps = Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> & {\n name: string;\n value?: string;\n defaultValue?: string;\n options: RadioOption[];\n onChange?: (value: string) => void;\n layout?: 'horizontal' | 'vertical';\n legend?: ReactNode;\n disabled?: boolean;\n 'aria-label'?: string;\n};\n\nexport function RadioGroup({\n name,\n value,\n defaultValue,\n options,\n onChange,\n layout = 'horizontal',\n legend,\n disabled,\n className,\n 'aria-label': ariaLabel,\n ...props\n}: RadioGroupProps) {\n const legendId = useId();\n const controlled = value !== undefined;\n\n return (\n <div\n {...props}\n role=\"radiogroup\"\n aria-labelledby={legend ? legendId : undefined}\n aria-label={legend ? undefined : ariaLabel}\n className={classes('fx-choice-set', className)}\n >\n {legend ? (\n <span id={legendId} className=\"fx-choice-set__legend\">\n {legend}\n </span>\n ) : null}\n <div className={classes('fx-choice-group', layout === 'vertical' && 'fx-choice-group--vertical')}>\n {options.map((option) => (\n <Radio\n key={option.value}\n name={name}\n value={option.value}\n label={option.label}\n description={option.description}\n checked={controlled ? value === option.value : undefined}\n defaultChecked={controlled ? undefined : defaultValue === option.value}\n disabled={disabled || option.disabled}\n onChange={() => onChange?.(option.value)}\n />\n ))}\n </div>\n </div>\n );\n}\n\nexport const RangeInput = forwardRef<HTMLInputElement, InputHTMLAttributes<HTMLInputElement>>(\n function RangeInput({ className, type, ...props }, ref) {\n return <input {...props} ref={ref} type={type ?? 'range'} className={classes('fx-range', className)} />;\n },\n);\n\nexport type SwitchProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange'> & {\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n label?: ReactNode;\n hideLabel?: boolean;\n layout?: 'inline' | 'row';\n};\n\nexport const Switch = forwardRef<HTMLButtonElement, SwitchProps>(function Switch(\n {\n checked,\n defaultChecked,\n onCheckedChange,\n label,\n hideLabel,\n layout = 'inline',\n className,\n disabled,\n onClick,\n ...props\n },\n ref,\n) {\n const [internalChecked, setInternalChecked] = useState(Boolean(defaultChecked));\n const isChecked = checked ?? internalChecked;\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented || disabled) return;\n const next = !isChecked;\n if (checked === undefined) setInternalChecked(next);\n onCheckedChange?.(next);\n };\n\n return (\n <button\n {...props}\n ref={ref}\n type=\"button\"\n role=\"switch\"\n aria-checked={isChecked}\n disabled={disabled}\n className={classes('fx-switch', layout === 'row' && 'fx-switch--row', className)}\n onClick={handleClick}\n >\n {label ? (\n <span className={classes('fx-switch__label', hideLabel && 'fx-visually-hidden')}>{label}</span>\n ) : null}\n <span className=\"fx-switch__track\" aria-hidden=\"true\">\n <span className=\"fx-switch__thumb\" />\n </span>\n </button>\n );\n});\n\nexport function Spinner({ label = '\u6B63\u5728\u52A0\u8F7D', className }: { label?: string; className?: string }) {\n return <span className={classes('fx-spinner', className)} role=\"status\" aria-label={label} />;\n}\n\nexport type StatusTone = 'success' | 'warning' | 'error' | 'info';\n\nconst statusIcons: Record<StatusTone, LucideIcon> = {\n success: CircleCheck,\n warning: CircleAlert,\n error: AlertCircle,\n info: Info,\n};\n\nexport type StatusProps = HTMLAttributes<HTMLSpanElement> & {\n tone: StatusTone;\n pill?: boolean;\n icon?: ReactNode;\n showIcon?: boolean;\n};\n\nexport function Status({\n tone,\n pill = false,\n icon,\n showIcon = true,\n children,\n className,\n ...props\n}: StatusProps) {\n const Icon = statusIcons[tone];\n return (\n <span\n {...props}\n className={classes('fx-status', `fx-status--${tone}`, pill && 'fx-status--pill', className)}\n >\n {showIcon ? (icon ?? <Icon className=\"fx-icon\" aria-hidden />) : null}\n {children}\n </span>\n );\n}\n\nexport type InlineFeedbackProps = HTMLAttributes<HTMLDivElement> & {\n tone: StatusTone;\n title: ReactNode;\n action?: ReactNode;\n};\n\nexport function InlineFeedback({\n tone,\n title,\n action,\n children,\n className,\n ...props\n}: InlineFeedbackProps) {\n const Icon = statusIcons[tone];\n return (\n <div\n {...props}\n role={tone === 'error' ? 'alert' : 'status'}\n className={classes('fx-feedback', `fx-status--${tone}`, className)}\n >\n <Icon className=\"fx-icon\" aria-hidden />\n <div className=\"fx-feedback__body\">\n <strong>{title}</strong>\n {children}\n </div>\n {action}\n </div>\n );\n}\n\nexport type EmptyStateProps = HTMLAttributes<HTMLDivElement> & {\n title: ReactNode;\n description: ReactNode;\n icon?: ReactNode;\n action?: ReactNode;\n};\n\nexport function EmptyState({\n title,\n description,\n icon,\n action,\n className,\n ...props\n}: EmptyStateProps) {\n return (\n <div {...props} className={classes('fx-empty', className)}>\n {icon}\n <Text as=\"strong\" variant=\"heading\">{title}</Text>\n <p>{description}</p>\n {action}\n </div>\n );\n}\n\nexport function LoadingState({\n title = '\u6B63\u5728\u52A0\u8F7D',\n description,\n}: {\n title?: ReactNode;\n description?: ReactNode;\n}) {\n return (\n <div className=\"fx-empty\" role=\"status\" aria-live=\"polite\">\n <Spinner label={typeof title === 'string' ? title : '\u6B63\u5728\u52A0\u8F7D'} />\n <Text as=\"strong\" variant=\"heading\">{title}</Text>\n {description && <p>{description}</p>}\n </div>\n );\n}\n\nexport type PanelHeaderProps = HTMLAttributes<HTMLElement> & {\n start?: ReactNode;\n center?: ReactNode;\n end?: ReactNode;\n};\n\nexport function PanelHeader({ start, center, end, className, ...props }: PanelHeaderProps) {\n return (\n <header {...props} className={classes('fx-panel-header', className)}>\n <div className=\"fx-panel-header__slot\">{start}</div>\n <div className=\"fx-panel-header__slot\">{center}</div>\n <div className=\"fx-panel-header__slot\">{end}</div>\n </header>\n );\n}\n\nexport function Toolbar({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div {...props} role={props.role ?? 'toolbar'} className={classes('fx-toolbar', className)} />;\n}\n\nexport type SearchFieldProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> & {\n label?: string;\n onClear?: () => void;\n};\n\nexport const SearchField = forwardRef<HTMLInputElement, SearchFieldProps>(function SearchField(\n { label = '\u641C\u7D22', onClear, value, className, ...props },\n ref,\n) {\n const hasValue = value != null && String(value).length > 0;\n return (\n <div className={classes('fx-search', className)}>\n <Search className=\"fx-icon fx-search__leading\" aria-hidden />\n <TextInput {...props} ref={ref} type=\"search\" value={value} aria-label={label} />\n {hasValue && onClear && (\n <IconButton\n className=\"fx-search__clear\"\n label=\"\u6E05\u9664\u641C\u7D22\"\n icon={<X className=\"fx-icon\" />}\n variant=\"quiet\"\n size=\"compact\"\n onClick={onClear}\n />\n )}\n </div>\n );\n});\n\nexport type MenuItem =\n | { type: 'title'; label: ReactNode }\n | { type: 'separator' }\n | {\n type?: 'item';\n id: string;\n label: ReactNode;\n icon?: ReactNode;\n shortcut?: string;\n disabled?: boolean;\n danger?: boolean;\n selected?: boolean;\n onSelect?: () => void;\n buttonProps?: Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'disabled' | 'onClick'> & DataAttributes;\n };\n\nexport function Menu({\n items,\n label = '\u83DC\u5355',\n className,\n}: {\n items: MenuItem[];\n label?: string;\n className?: string;\n}) {\n return (\n <div className={classes('fx-menu', className)} role=\"menu\" aria-label={label}>\n {items.map((item, index) => {\n if (item.type === 'separator') {\n return <div className=\"fx-menu__separator\" role=\"separator\" key={`separator-${index}`} />;\n }\n if (item.type === 'title') {\n return <div className=\"fx-menu__title\" key={`title-${index}`}>{item.label}</div>;\n }\n const { className: itemClassName, ...buttonProps } = item.buttonProps ?? {};\n return (\n <button\n {...buttonProps}\n type=\"button\"\n role=\"menuitem\"\n key={item.id}\n disabled={item.disabled}\n aria-selected={item.selected || undefined}\n className={classes(\n 'fx-menu__item',\n item.selected && 'fx-menu__item--selected',\n item.danger && 'fx-menu__item--danger',\n itemClassName,\n )}\n onClick={item.onSelect}\n >\n <span className=\"fx-menu__leading\" aria-hidden>\n {item.selected ? <Check className=\"fx-icon\" /> : item.icon}\n </span>\n <span className=\"fx-menu__label\">{item.label}</span>\n {item.shortcut && <kbd className=\"fx-menu__shortcut\">{item.shortcut}</kbd>}\n </button>\n );\n })}\n </div>\n );\n}\n\nexport type FloatingMenuProps = {\n open: boolean;\n anchorRect: AnchorRect | null;\n onClose?: () => void;\n gap?: number;\n className?: string;\n ignorePointerWithin?: RefObject<HTMLElement | null>[];\n containerProps?: Omit<HTMLAttributes<HTMLDivElement>, 'children'> & DataAttributes;\n children: ReactNode;\n};\n\nexport function FloatingMenu({\n open,\n anchorRect,\n onClose,\n gap = 8,\n className,\n ignorePointerWithin,\n containerProps,\n children,\n}: FloatingMenuProps) {\n const overlayRoot = useOverlayRoot();\n const menuRef = useRef<HTMLDivElement>(null);\n const [position, setPosition] = useState({ x: 0, y: 0 });\n const [visible, setVisible] = useState(false);\n\n const updatePosition = useCallback(() => {\n if (!open || !anchorRect || !menuRef.current) return;\n const { width, height } = menuRef.current.getBoundingClientRect();\n const resolved = resolveFloatingMenuPosition(anchorRect, width, height, { gap });\n setPosition({ x: resolved.x, y: resolved.y });\n setVisible(true);\n }, [anchorRect, gap, open]);\n\n useLayoutEffect(() => {\n if (!open) {\n setVisible(false);\n return;\n }\n setVisible(false);\n updatePosition();\n window.addEventListener('resize', updatePosition);\n window.addEventListener('scroll', updatePosition, true);\n return () => {\n window.removeEventListener('resize', updatePosition);\n window.removeEventListener('scroll', updatePosition, true);\n };\n }, [open, updatePosition, children]);\n\n useEffect(() => {\n if (!open || !onClose) return;\n const close = (event: PointerEvent) => {\n const target = event.target as Node;\n if (menuRef.current?.contains(target)) return;\n if (ignorePointerWithin?.some((ref) => ref.current?.contains(target))) return;\n onClose();\n };\n const escape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose();\n };\n window.addEventListener('pointerdown', close);\n window.addEventListener('keydown', escape);\n return () => {\n window.removeEventListener('pointerdown', close);\n window.removeEventListener('keydown', escape);\n };\n }, [ignorePointerWithin, onClose, open]);\n\n if (!open || !anchorRect || typeof document === 'undefined') return null;\n const {\n className: containerClassName,\n style: containerStyle,\n onPointerDown,\n ...restContainerProps\n } = containerProps ?? {};\n return createPortal(\n <div\n {...restContainerProps}\n ref={menuRef}\n className={classes('fx-menu-position', 'fx-ui', className, containerClassName)}\n style={{\n ...containerStyle,\n left: position.x,\n top: position.y,\n visibility: visible ? 'visible' : 'hidden',\n }}\n onPointerDown={(event) => {\n event.stopPropagation();\n onPointerDown?.(event);\n }}\n >\n {children}\n </div>,\n overlayRoot ?? document.body,\n );\n}\n\nexport type ContextMenuProps = {\n open: boolean;\n items: MenuItem[];\n onClose: () => void;\n label?: string;\n containerProps?: Omit<HTMLAttributes<HTMLDivElement>, 'children'> & DataAttributes;\n x?: number;\n y?: number;\n anchorRect?: AnchorRect | null;\n gap?: number;\n};\n\nexport type MenuDropdownProps = {\n label?: string;\n items: MenuItem[];\n align?: 'start' | 'end';\n className?: string;\n trigger: ReactElement<{\n onClick?: (event: MouseEvent<HTMLButtonElement>) => void;\n 'aria-expanded'?: boolean;\n 'aria-haspopup'?: boolean | 'menu';\n }>;\n};\n\nexport function MenuDropdown({ label = '\u83DC\u5355', items, align = 'end', className, trigger }: MenuDropdownProps) {\n const overlayRoot = useOverlayRoot();\n const anchorRef = useRef<HTMLSpanElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const [open, setOpen] = useState(false);\n const [position, setPosition] = useState({ x: 0, y: 0 });\n const [visible, setVisible] = useState(false);\n\n const menuItems = useMemo(\n () =>\n items.map((item) =>\n item.type === undefined || item.type === 'item'\n ? {\n ...item,\n onSelect: () => {\n item.onSelect?.();\n setOpen(false);\n },\n }\n : item,\n ),\n [items],\n );\n\n const repositionMenu = useCallback(() => {\n if (!open || !anchorRef.current || !menuRef.current) return;\n const anchor = anchorRef.current.getBoundingClientRect();\n const { width, height } = menuRef.current.getBoundingClientRect();\n if (width <= 0 || height <= 0) return;\n const resolved = resolveMenuDropdownPosition(anchor, width, height, align, { gap: 4 });\n setPosition(resolved);\n setVisible(true);\n }, [align, open]);\n\n useLayoutEffect(() => {\n if (!open) {\n setVisible(false);\n return;\n }\n setVisible(false);\n repositionMenu();\n const menuEl = menuRef.current;\n const observer = menuEl ? new ResizeObserver(() => repositionMenu()) : null;\n if (menuEl && observer) observer.observe(menuEl);\n const onLayout = () => repositionMenu();\n window.addEventListener('resize', onLayout);\n window.addEventListener('scroll', onLayout, true);\n return () => {\n observer?.disconnect();\n window.removeEventListener('resize', onLayout);\n window.removeEventListener('scroll', onLayout, true);\n };\n }, [open, repositionMenu, menuItems]);\n\n useEffect(() => {\n if (!open) return;\n const close = (event: PointerEvent) => {\n const target = event.target as Node;\n if (anchorRef.current?.contains(target)) return;\n if (menuRef.current?.contains(target)) return;\n setOpen(false);\n };\n const onKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setOpen(false);\n };\n window.addEventListener('pointerdown', close);\n window.addEventListener('keydown', onKey);\n return () => {\n window.removeEventListener('pointerdown', close);\n window.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n const triggerElement = cloneElement(trigger, {\n 'aria-haspopup': 'menu',\n 'aria-expanded': open,\n onClick: (event: MouseEvent<HTMLButtonElement>) => {\n trigger.props.onClick?.(event);\n if (event.defaultPrevented) return;\n setOpen((current) => !current);\n },\n });\n\n return (\n <>\n <span className=\"fx-menu-dropdown__anchor\" ref={anchorRef}>\n {triggerElement}\n </span>\n {open &&\n typeof document !== 'undefined' &&\n createPortal(\n <div\n ref={menuRef}\n className={classes('fx-menu-position', 'fx-ui', className)}\n style={{\n left: position.x,\n top: position.y,\n visibility: visible ? 'visible' : 'hidden',\n }}\n onPointerDown={(event) => event.stopPropagation()}\n >\n <Menu label={label} items={menuItems} />\n </div>,\n overlayRoot ?? document.body,\n )}\n </>\n );\n}\n\nexport function ContextMenu({\n open,\n x = 0,\n y = 0,\n anchorRect = null,\n gap = 8,\n items,\n onClose,\n label,\n containerProps,\n}: ContextMenuProps) {\n const overlayRoot = useOverlayRoot();\n useEffect(() => {\n if (!open || anchorRect) return;\n const close = () => onClose();\n const escape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose();\n };\n window.addEventListener('pointerdown', close);\n window.addEventListener('keydown', escape);\n return () => {\n window.removeEventListener('pointerdown', close);\n window.removeEventListener('keydown', escape);\n };\n }, [anchorRect, onClose, open]);\n\n if (anchorRect) {\n return (\n <FloatingMenu\n open={open}\n anchorRect={anchorRect}\n onClose={onClose}\n gap={gap}\n {...(containerProps === undefined ? {} : { containerProps })}\n >\n <Menu\n {...(label === undefined ? {} : { label })}\n items={items.map((item) =>\n item.type === undefined || item.type === 'item'\n ? { ...item, onSelect: () => { item.onSelect?.(); onClose(); } }\n : item,\n )}\n />\n </FloatingMenu>\n );\n }\n\n if (!open || typeof document === 'undefined') return null;\n const {\n className: containerClassName,\n style: containerStyle,\n onPointerDown,\n ...positionProps\n } = containerProps ?? {};\n return createPortal(\n <div\n {...positionProps}\n className={classes('fx-menu-position', 'fx-ui', containerClassName)}\n style={{ ...containerStyle, left: x, top: y }}\n onPointerDown={(event) => {\n event.stopPropagation();\n onPointerDown?.(event);\n }}\n >\n <Menu\n items={items.map((item) =>\n item.type === undefined || item.type === 'item'\n ? { ...item, onSelect: () => { item.onSelect?.(); onClose(); } }\n : item,\n )}\n {...(label === undefined ? {} : { label })}\n />\n </div>,\n overlayRoot ?? document.body,\n );\n}\n\ntype DialogBaseProps = {\n open: boolean;\n /** Keep the surrounding workspace interactive when false. */\n modal?: boolean;\n title: ReactNode;\n children: ReactNode;\n footer?: ReactNode;\n className?: string;\n initialFocusRef?: RefObject<HTMLElement | null>;\n closeLabel?: string;\n};\n\nexport type DialogProps =\n | (DialogBaseProps & { dismissible?: true; onClose: () => void })\n | (DialogBaseProps & { dismissible: false; onClose?: () => void });\n\nexport function Dialog({\n open,\n modal = true,\n title,\n children,\n footer,\n className,\n dismissible = true,\n onClose,\n initialFocusRef,\n closeLabel = '\u5173\u95ED\u5F39\u7A97',\n}: DialogProps) {\n const ref = useRef<HTMLDialogElement>(null);\n const returnFocusRef = useRef<HTMLElement | null>(null);\n const titleId = useId();\n\n useEffect(() => {\n const dialog = ref.current;\n if (!dialog) return;\n if (open && !dialog.open) {\n returnFocusRef.current = document.activeElement instanceof HTMLElement\n ? document.activeElement\n : null;\n if (modal) dialog.showModal();\n else dialog.show();\n requestAnimationFrame(() => initialFocusRef?.current?.focus());\n }\n if (!open && dialog.open) {\n dialog.close();\n returnFocusRef.current?.focus();\n }\n }, [initialFocusRef, modal, open]);\n\n return (\n <dialog\n ref={ref}\n className={classes('fx-dialog', 'fx-ui', className)}\n aria-labelledby={titleId}\n data-dismissible={dismissible ? 'true' : 'false'}\n closedby={dismissible ? 'closerequest' : 'none'}\n onCancel={(event) => {\n event.preventDefault();\n if (dismissible) onClose?.();\n }}\n onClose={() => {\n if (dismissible) {\n onClose?.();\n return;\n }\n requestAnimationFrame(() => {\n const dialog = ref.current;\n if (open && dialog && !dialog.open) {\n if (modal) dialog.showModal();\n else dialog.show();\n initialFocusRef?.current?.focus();\n }\n });\n }}\n >\n <div className=\"fx-dialog__header\">\n <Text as=\"h2\" id={titleId} variant=\"heading\">{title}</Text>\n {dismissible ? (\n <IconButton label={closeLabel} icon={<X className=\"fx-icon\" />} variant=\"quiet\" onClick={onClose} />\n ) : null}\n </div>\n <div className=\"fx-dialog__body\">{children}</div>\n {footer && <div className=\"fx-dialog__footer\">{footer}</div>}\n </dialog>\n );\n}\n\nexport type TooltipProps = {\n /** Free-form body when title/description are not used. */\n content?: ReactNode;\n /** Primary line; pairs with description for the standard two-line pattern. */\n title?: ReactNode;\n /** Secondary line in muted caption tone. */\n description?: ReactNode;\n children: ReactNode;\n /** Default opens above the anchor; use bottom for top-of-viewport controls. */\n placement?: 'top' | 'bottom';\n /** Render in the supplied overlay root, or document.body for standalone use. */\n portaled?: boolean;\n /** When true, keeps the tooltip visible until unmounted (not dismissed by hover/focus leave). */\n open?: boolean;\n};\n\nfunction TooltipBody({ title, description, content }: Pick<TooltipProps, 'title' | 'description' | 'content'>) {\n if (title != null || description != null) {\n return (\n <div className=\"fx-tooltip__content\">\n {title != null && <div className=\"fx-tooltip__title\">{title}</div>}\n {description != null && <div className=\"fx-tooltip__description\">{description}</div>}\n </div>\n );\n }\n return <div className=\"fx-tooltip__content\">{content}</div>;\n}\n\nconst TOOLTIP_VIEWPORT_MARGIN = 12;\nconst TOOLTIP_ANCHOR_GAP = 10;\n\nfunction clampTooltipPosition(\n anchor: DOMRect,\n tip: DOMRect,\n placement: 'top' | 'bottom',\n): { x: number; y: number; placement: 'top' | 'bottom' } {\n let x = anchor.left + anchor.width / 2;\n const half = tip.width / 2;\n const minX = TOOLTIP_VIEWPORT_MARGIN + half;\n const maxX = window.innerWidth - TOOLTIP_VIEWPORT_MARGIN - half;\n x = Math.min(Math.max(x, minX), maxX);\n\n let resolved = placement;\n let y =\n placement === 'top'\n ? anchor.top - TOOLTIP_ANCHOR_GAP\n : anchor.bottom + TOOLTIP_ANCHOR_GAP;\n\n if (placement === 'bottom') {\n if (y + tip.height > window.innerHeight - TOOLTIP_VIEWPORT_MARGIN) {\n resolved = 'top';\n y = anchor.top - TOOLTIP_ANCHOR_GAP;\n }\n } else if (y - tip.height < TOOLTIP_VIEWPORT_MARGIN) {\n resolved = 'bottom';\n y = anchor.bottom + TOOLTIP_ANCHOR_GAP;\n }\n\n return { x, y, placement: resolved };\n}\n\nexport function Tooltip({\n content,\n title,\n description,\n children,\n placement = 'top',\n portaled = false,\n open = false,\n}: TooltipProps) {\n const overlayRoot = useOverlayRoot();\n const anchorRef = useRef<HTMLSpanElement>(null);\n const tooltipRef = useRef<HTMLSpanElement>(null);\n const [hoverVisible, setHoverVisible] = useState(false);\n const visible = open || hoverVisible;\n const [coords, setCoords] = useState({ x: 0, y: 0 });\n const [resolvedPlacement, setResolvedPlacement] = useState(placement);\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const updateCoords = useCallback(() => {\n const anchor = anchorRef.current?.getBoundingClientRect();\n if (!anchor) return;\n const tip = tooltipRef.current?.getBoundingClientRect();\n if (tip && tip.width > 0) {\n const next = clampTooltipPosition(anchor, tip, placement);\n setCoords({ x: next.x, y: next.y });\n setResolvedPlacement(next.placement);\n return;\n }\n setCoords({\n x: anchor.left + anchor.width / 2,\n y: placement === 'top' ? anchor.top - TOOLTIP_ANCHOR_GAP : anchor.bottom + TOOLTIP_ANCHOR_GAP,\n });\n setResolvedPlacement(placement);\n }, [placement]);\n\n useLayoutEffect(() => {\n if (!visible) return;\n updateCoords();\n if (!portaled) return;\n const onLayout = () => updateCoords();\n window.addEventListener('resize', onLayout);\n window.addEventListener('scroll', onLayout, true);\n return () => {\n window.removeEventListener('resize', onLayout);\n window.removeEventListener('scroll', onLayout, true);\n };\n }, [portaled, updateCoords, visible]);\n\n const show = () => {\n if (open) return;\n timer.current = setTimeout(() => {\n setHoverVisible(true);\n }, 400);\n };\n const hide = () => {\n if (open) return;\n if (timer.current) clearTimeout(timer.current);\n setHoverVisible(false);\n setResolvedPlacement(placement);\n };\n\n const effectivePlacement = portaled ? resolvedPlacement : placement;\n\n const tooltipStyle = portaled\n ? {\n left: coords.x,\n top: coords.y,\n transform:\n effectivePlacement === 'top'\n ? 'translate(-50%, -100%)'\n : 'translate(-50%, 0)',\n }\n : undefined;\n\n const tooltip = visible ? (\n <span\n ref={tooltipRef}\n className={classes(\n 'fx-tooltip',\n effectivePlacement === 'bottom' ? 'fx-tooltip--bottom' : 'fx-tooltip--top',\n portaled && 'fx-tooltip--fixed',\n open && 'fx-tooltip--interactive',\n )}\n style={tooltipStyle}\n role=\"tooltip\"\n >\n <TooltipBody title={title} description={description} content={content} />\n </span>\n ) : null;\n\n return (\n <span\n ref={anchorRef}\n className=\"fx-tooltip-anchor\"\n onMouseEnter={show}\n onMouseLeave={hide}\n onFocus={show}\n onBlur={hide}\n >\n {children}\n {portaled && typeof document !== 'undefined'\n ? tooltip && createPortal(tooltip, overlayRoot ?? document.body)\n : tooltip}\n </span>\n );\n}\n\ntype Toast = {\n id: number;\n tone: StatusTone;\n title: ReactNode;\n description?: ReactNode;\n /** When true, or when duration is 0, the toast stays until the user closes it. */\n persistent?: boolean;\n duration?: number;\n};\n\ntype ToastContextValue = {\n notify: (toast: Omit<Toast, 'id'>) => void;\n};\n\nconst ToastContext = createContext<ToastContextValue | null>(null);\n\nexport function ToastProvider({ children, duration = 4000 }: { children: ReactNode; duration?: number }) {\n const overlayRoot = useOverlayRoot();\n const [toasts, setToasts] = useState<Toast[]>([]);\n const id = useRef(0);\n const dismiss = useCallback((toastId: number) => {\n setToasts((current) => current.filter((toast) => toast.id !== toastId));\n }, []);\n const notify = useCallback(\n (toast: Omit<Toast, 'id'>) => {\n const toastId = ++id.current;\n setToasts((current) => [...current, { ...toast, id: toastId }]);\n const persist = toast.persistent === true || toast.duration === 0;\n if (!persist) {\n window.setTimeout(() => dismiss(toastId), toast.duration ?? duration);\n }\n },\n [dismiss, duration],\n );\n const value = useMemo(() => ({ notify }), [notify]);\n\n return (\n <ToastContext.Provider value={value}>\n {children}\n {typeof document !== 'undefined' &&\n createPortal(\n <div className=\"fx-toast-region fx-ui\" aria-live=\"polite\">\n {toasts.map((toast) => (\n <div\n className={classes('fx-toast', toast.tone === 'error' && 'fx-toast--error')}\n key={toast.id}\n >\n <Status tone={toast.tone} aria-label={toast.tone} />\n <div className=\"fx-toast__body\">\n <strong>{toast.title}</strong>\n {toast.description && <Text variant=\"caption\">{toast.description}</Text>}\n </div>\n <IconButton\n label=\"\u5173\u95ED\u901A\u77E5\"\n icon={<X className=\"fx-icon\" />}\n variant=\"quiet\"\n size=\"compact\"\n onClick={() => dismiss(toast.id)}\n />\n </div>\n ))}\n </div>,\n overlayRoot ?? document.body,\n )}\n </ToastContext.Provider>\n );\n}\n\nexport function useToast() {\n const context = useContext(ToastContext);\n if (!context) throw new Error('useToast must be used inside ToastProvider');\n return context;\n}\n\nexport type NavigationItem = {\n id: string;\n label: string;\n icon: ReactNode;\n disabled?: boolean;\n};\n\nexport function NavigationRail({\n items,\n activeId,\n onSelect,\n label = '\u4E3B\u5BFC\u822A',\n}: {\n items: NavigationItem[];\n activeId: string;\n onSelect: (id: string) => void;\n label?: string;\n}) {\n return (\n <nav className=\"fx-navigation-rail\" aria-label={label}>\n {items.map((item) => (\n <button\n type=\"button\"\n className=\"fx-navigation-rail__item\"\n key={item.id}\n aria-label={item.label}\n title={item.label}\n aria-current={activeId === item.id ? 'page' : undefined}\n disabled={item.disabled}\n onClick={() => onSelect(item.id)}\n >\n {item.icon}\n </button>\n ))}\n </nav>\n );\n}\n\nexport function ConfigPreviewLayout({\n config,\n action,\n preview,\n className,\n}: {\n config: ReactNode;\n action: ReactNode;\n preview: ReactNode;\n className?: string;\n}) {\n return (\n <div className={classes('fx-config-preview', className)}>\n <aside className=\"fx-config-preview__config\">\n <div className=\"fx-config-preview__scroll\">{config}</div>\n <div className=\"fx-config-preview__action\">{action}</div>\n </aside>\n <main className=\"fx-config-preview__preview\">{preview}</main>\n </div>\n );\n}\n\nexport function FileRow({\n icon,\n name,\n status,\n action,\n selected,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement> & {\n icon: ReactNode;\n name: ReactNode;\n status?: ReactNode;\n action?: ReactNode;\n selected?: boolean;\n}) {\n return (\n <div\n {...props}\n className={classes('fx-file-row', className)}\n aria-selected={selected || undefined}\n >\n <span className=\"fx-file-row__icon\">{icon}</span>\n <span className=\"fx-file-row__body\">\n <span className=\"fx-file-row__name\">{name}</span>\n {status && <Text as=\"span\" variant=\"caption\">{status}</Text>}\n </span>\n {action}\n </div>\n );\n}\n\nexport function PropertyRow({\n label,\n children,\n className,\n}: {\n label: ReactNode;\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div className={classes('fx-property-row', className)}>\n <span className=\"fx-property-row__label\">{label}</span>\n <span className=\"fx-property-row__control\">{children}</span>\n </div>\n );\n}\n\nexport function CollapsibleSection({\n title,\n children,\n defaultOpen = true,\n open,\n onOpenChange,\n trailing,\n className,\n triggerProps,\n ...props\n}: Omit<HTMLAttributes<HTMLElement>, 'title'> & {\n title: ReactNode;\n children: ReactNode;\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n trailing?: ReactNode;\n triggerProps?: Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> & DataAttributes;\n}) {\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const expanded = open ?? internalOpen;\n const contentId = useId();\n const toggle = () => {\n const next = !expanded;\n if (open === undefined) setInternalOpen(next);\n onOpenChange?.(next);\n };\n const {\n className: triggerClassName,\n onClick: onTriggerClick,\n ...buttonProps\n } = triggerProps ?? {};\n return (\n <section {...props} className={classes('fx-collapsible', className)}>\n <div className=\"fx-collapsible__heading\">\n <button\n {...buttonProps}\n type=\"button\"\n className={classes('fx-collapsible__trigger', triggerClassName)}\n aria-expanded={expanded}\n aria-controls={contentId}\n onClick={(event) => {\n onTriggerClick?.(event);\n if (!event.defaultPrevented) toggle();\n }}\n >\n {expanded ? <ChevronDown className=\"fx-icon\" /> : <ChevronRight className=\"fx-icon\" />}\n <span className=\"fx-collapsible__title\">{title}</span>\n </button>\n {trailing && <div className=\"fx-collapsible__actions\">{trailing}</div>}\n </div>\n {expanded && <div className=\"fx-collapsible__content\" id={contentId}>{children}</div>}\n </section>\n );\n}\n\nexport type Message = {\n id: string;\n role: 'user' | 'assistant';\n content: ReactNode;\n};\n\nexport function Conversation({ messages, label = '\u5BF9\u8BDD' }: { messages: Message[]; label?: string }) {\n return (\n <div className=\"fx-conversation\" aria-label={label}>\n {messages.map((message) => (\n <article className={classes('fx-message', `fx-message--${message.role}`)} key={message.id}>\n <Text as=\"span\" variant=\"caption\">\n {message.role === 'user' ? '\u4F60' : 'ForgeaX'}\n </Text>\n <div className=\"fx-message__bubble\">{message.content}</div>\n </article>\n ))}\n </div>\n );\n}\n\nexport type ComposerProps = {\n value: string;\n onChange: (value: string) => void;\n onSubmit: () => void;\n placeholder?: string;\n disabled?: boolean;\n tools?: ReactNode;\n submitLabel?: string;\n};\n\nexport function Composer({\n value,\n onChange,\n onSubmit,\n placeholder = '\u63CF\u8FF0\u4F60\u60F3\u505A\u4EC0\u4E48\u2026',\n disabled,\n tools,\n submitLabel = '\u53D1\u9001',\n}: ComposerProps) {\n return (\n <div className=\"fx-composer\">\n <TextArea\n value={value}\n disabled={disabled}\n placeholder={placeholder}\n aria-label=\"\u6D88\u606F\"\n onChange={(event) => onChange(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n if (value.trim() && !disabled) onSubmit();\n }\n }}\n />\n <div className=\"fx-composer__footer\">\n <Toolbar>{tools}</Toolbar>\n <Button variant=\"primary\" disabled={disabled || !value.trim()} onClick={onSubmit}>\n {submitLabel}\n </Button>\n </div>\n </div>\n );\n}\n\nexport const icons = {\n check: Check,\n close: X,\n search: Search,\n};\n", "export type FloatingMenuPlacement = 'right' | 'left' | 'bottom' | 'top';\n\nexport type AnchorRect = Pick<DOMRect, 'top' | 'right' | 'bottom' | 'left' | 'width' | 'height'>;\n\nexport type ResolveFloatingMenuPositionOptions = {\n gap?: number;\n padding?: number;\n preference?: FloatingMenuPlacement[];\n};\n\nconst DEFAULT_PREFERENCE: FloatingMenuPlacement[] = ['right', 'left', 'bottom', 'top'];\n\nfunction viewportSize() {\n return {\n width: window.innerWidth,\n height: window.innerHeight,\n };\n}\n\nfunction candidatePosition(\n placement: FloatingMenuPlacement,\n anchor: AnchorRect,\n menuWidth: number,\n menuHeight: number,\n gap: number,\n) {\n switch (placement) {\n case 'right':\n return { x: anchor.right + gap, y: anchor.top };\n case 'left':\n return { x: anchor.left - gap - menuWidth, y: anchor.top };\n case 'bottom':\n return { x: anchor.left + anchor.width / 2 - menuWidth / 2, y: anchor.bottom + gap };\n case 'top':\n return { x: anchor.left + anchor.width / 2 - menuWidth / 2, y: anchor.top - gap - menuHeight };\n }\n}\n\nfunction fitsHorizontally(x: number, menuWidth: number, padding: number) {\n const { width } = viewportSize();\n return x >= padding && x + menuWidth <= width - padding;\n}\n\nfunction fitsVertically(y: number, menuHeight: number, padding: number) {\n const { height } = viewportSize();\n return y >= padding && y + menuHeight <= height - padding;\n}\n\nfunction fitsViewport(x: number, y: number, menuWidth: number, menuHeight: number, padding: number) {\n return fitsHorizontally(x, menuWidth, padding) && fitsVertically(y, menuHeight, padding);\n}\n\nfunction visibleArea(x: number, y: number, menuWidth: number, menuHeight: number, padding: number) {\n const { width, height } = viewportSize();\n const left = Math.max(x, padding);\n const top = Math.max(y, padding);\n const right = Math.min(x + menuWidth, width - padding);\n const bottom = Math.min(y + menuHeight, height - padding);\n return Math.max(0, right - left) * Math.max(0, bottom - top);\n}\n\nfunction clampForPlacement(\n placement: FloatingMenuPlacement,\n x: number,\n y: number,\n menuWidth: number,\n menuHeight: number,\n padding: number,\n) {\n const { width, height } = viewportSize();\n if (placement === 'right' || placement === 'left') {\n return {\n x: Math.max(padding, Math.min(x, width - padding - menuWidth)),\n y: Math.max(padding, Math.min(y, height - padding - menuHeight)),\n };\n }\n return {\n x: Math.max(padding, Math.min(x, width - padding - menuWidth)),\n y: Math.max(padding, Math.min(y, height - padding - menuHeight)),\n };\n}\n\nexport function resolveFloatingMenuPosition(\n anchor: AnchorRect,\n menuWidth: number,\n menuHeight: number,\n options: ResolveFloatingMenuPositionOptions = {},\n): { x: number; y: number; placement: FloatingMenuPlacement } {\n const gap = options.gap ?? 8;\n const padding = options.padding ?? 8;\n const preference = options.preference ?? DEFAULT_PREFERENCE;\n\n let best = preference[0]!;\n let bestPoint = candidatePosition(best, anchor, menuWidth, menuHeight, gap);\n let bestScore = -1;\n\n for (const placement of preference) {\n const point = candidatePosition(placement, anchor, menuWidth, menuHeight, gap);\n const horizontal = placement === 'right' || placement === 'left';\n const vertical = placement === 'top' || placement === 'bottom';\n if (horizontal && fitsHorizontally(point.x, menuWidth, padding)) {\n return { ...clampForPlacement(placement, point.x, point.y, menuWidth, menuHeight, padding), placement };\n }\n if (vertical && fitsVertically(point.y, menuHeight, padding)) {\n return { ...clampForPlacement(placement, point.x, point.y, menuWidth, menuHeight, padding), placement };\n }\n if (fitsViewport(point.x, point.y, menuWidth, menuHeight, padding)) {\n return { ...point, placement };\n }\n const score = visibleArea(point.x, point.y, menuWidth, menuHeight, padding);\n if (score > bestScore) {\n bestScore = score;\n best = placement;\n bestPoint = point;\n }\n }\n\n const clamped = clampForPlacement(best, bestPoint.x, bestPoint.y, menuWidth, menuHeight, padding);\n return { ...clamped, placement: best };\n}\n\nexport function anchorRectFromPoint(x: number, y: number): AnchorRect {\n return { top: y, right: x, bottom: y, left: x, width: 0, height: 0 };\n}\n\nexport type MenuDropdownAlign = 'start' | 'end';\n\nexport type ResolveMenuDropdownPositionOptions = {\n gap?: number;\n padding?: number;\n};\n\n/** Places a menu below (or above) the anchor, start- or end-aligned to the trigger. */\nexport function resolveMenuDropdownPosition(\n anchor: AnchorRect,\n menuWidth: number,\n menuHeight: number,\n align: MenuDropdownAlign,\n options: ResolveMenuDropdownPositionOptions = {},\n): { x: number; y: number } {\n const gap = options.gap ?? 4;\n const padding = options.padding ?? 8;\n const { width: viewportWidth, height: viewportHeight } = viewportSize();\n\n let x = align === 'end' ? anchor.right - menuWidth : anchor.left;\n let y = anchor.bottom + gap;\n\n const spaceBelow = viewportHeight - padding - anchor.bottom - gap;\n const spaceAbove = anchor.top - gap - padding;\n if (menuHeight > spaceBelow && spaceAbove > spaceBelow) {\n y = anchor.top - gap - menuHeight;\n }\n\n x = Math.max(padding, Math.min(x, viewportWidth - padding - menuWidth));\n y = Math.max(padding, Math.min(y, viewportHeight - padding - menuHeight));\n return { x, y };\n}\n", "import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\n\nimport { themeNames, type ThemeName } from './tokens';\n\nconst THEME_STORAGE_KEY = 'forgeax-view-theme';\n\ntype ThemeContextValue = {\n theme: ThemeName;\n setTheme: (theme: ThemeName) => void;\n toggleTheme: () => void;\n};\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null);\n\nexport type ThemeProviderProps = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {\n children: ReactNode;\n defaultTheme?: ThemeName;\n theme?: ThemeName;\n onThemeChange?: (theme: ThemeName) => void;\n persist?: boolean;\n applyToDocument?: boolean;\n /** Skip the layout wrapper `div` when it would break viewport flex/height chains. */\n unstyled?: boolean;\n};\n\nexport function isThemeName(value: unknown): value is ThemeName {\n return typeof value === 'string' && themeNames.includes(value as ThemeName);\n}\n\nexport function getStoredTheme(fallback: ThemeName = 'light'): ThemeName {\n if (typeof window === 'undefined') return fallback;\n const stored = window.localStorage.getItem(THEME_STORAGE_KEY);\n return isThemeName(stored) ? stored : fallback;\n}\n\nexport function applyTheme(theme: ThemeName, target?: HTMLElement) {\n const element = target ?? (typeof document === 'undefined' ? undefined : document.documentElement);\n if (element) element.dataset.theme = theme;\n}\n\nexport function initializeTheme(fallback: ThemeName = 'light') {\n const theme = getStoredTheme(fallback);\n applyTheme(theme);\n return theme;\n}\n\nexport function ThemeProvider({\n children,\n defaultTheme = 'light',\n theme: controlledTheme,\n onThemeChange,\n persist = false,\n applyToDocument = true,\n unstyled = false,\n className,\n ...props\n}: ThemeProviderProps) {\n const [internalTheme, setInternalTheme] = useState<ThemeName>(() =>\n persist ? getStoredTheme(defaultTheme) : defaultTheme,\n );\n const theme = controlledTheme ?? internalTheme;\n\n const setTheme = useCallback(\n (nextTheme: ThemeName) => {\n if (!controlledTheme) setInternalTheme(nextTheme);\n if (persist && typeof window !== 'undefined') {\n window.localStorage.setItem(THEME_STORAGE_KEY, nextTheme);\n }\n onThemeChange?.(nextTheme);\n },\n [controlledTheme, onThemeChange, persist],\n );\n\n useEffect(() => {\n if (applyToDocument) applyTheme(theme);\n }, [applyToDocument, theme]);\n\n const value = useMemo(\n () => ({\n theme,\n setTheme,\n toggleTheme: () => setTheme(theme === 'light' ? 'dark' : 'light'),\n }),\n [setTheme, theme],\n );\n\n return (\n <ThemeContext.Provider value={value}>\n {unstyled ? (\n children\n ) : (\n <div\n {...props}\n className={['fx-ui', className].filter(Boolean).join(' ')}\n data-theme={applyToDocument ? undefined : theme}\n >\n {children}\n </div>\n )}\n </ThemeContext.Provider>\n );\n}\n\nexport function useTheme() {\n const context = useContext(ThemeContext);\n if (!context) throw new Error('useTheme must be used inside ThemeProvider');\n return context;\n}\n", "export const themeNames = ['light', 'dark'] as const;\nexport type ThemeName = (typeof themeNames)[number];\n\nexport const typographyTokens = {\n title: '--fx-type-title',\n heading: '--fx-type-heading',\n body: '--fx-type-body',\n ui: '--fx-type-ui',\n label: '--fx-type-label',\n compact: '--fx-type-compact',\n caption: '--fx-type-caption',\n code: '--fx-type-code',\n} as const;\n\nexport const colorTokens = {\n surface: {\n canvas: '--fx-color-surface-canvas',\n sidebar: '--fx-color-surface-sidebar',\n raised: '--fx-color-surface-raised',\n inset: '--fx-color-surface-inset',\n hover: '--fx-color-surface-hover',\n selected: '--fx-color-surface-selected',\n },\n text: {\n primary: '--fx-color-text-primary',\n secondary: '--fx-color-text-secondary',\n muted: '--fx-color-text-muted',\n disabled: '--fx-color-text-disabled',\n inverse: '--fx-color-text-inverse',\n link: '--fx-color-text-link',\n },\n border: {\n subtle: '--fx-color-border-subtle',\n default: '--fx-color-border-default',\n control: '--fx-color-border-control',\n strong: '--fx-color-border-strong',\n focus: '--fx-color-border-focus',\n essential: '--fx-color-border-essential',\n },\n action: {\n primaryBackground: '--fx-color-action-primary-bg',\n primaryForeground: '--fx-color-action-primary-fg',\n primaryHover: '--fx-color-action-primary-hover',\n primaryPressed: '--fx-color-action-primary-pressed',\n secondaryBackground: '--fx-color-action-secondary-bg',\n secondaryForeground: '--fx-color-action-secondary-fg',\n secondaryHover: '--fx-color-action-secondary-hover',\n disabledBackground: '--fx-color-action-disabled-bg',\n disabledForeground: '--fx-color-action-disabled-fg',\n dangerBackground: '--fx-color-action-danger-bg',\n dangerForeground: '--fx-color-action-danger-fg',\n },\n selection: {\n background: '--fx-color-selection-bg',\n foreground: '--fx-color-selection-fg',\n indicator: '--fx-color-selection-indicator',\n },\n brand: {\n accent: '--fx-color-brand-accent',\n text: '--fx-color-brand-text',\n soft: '--fx-color-brand-soft',\n onAccent: '--fx-color-brand-on-accent',\n },\n status: {\n successForeground: '--fx-color-status-success-fg',\n successBackground: '--fx-color-status-success-bg',\n warningForeground: '--fx-color-status-warning-fg',\n warningBackground: '--fx-color-status-warning-bg',\n errorForeground: '--fx-color-status-error-fg',\n errorBackground: '--fx-color-status-error-bg',\n infoForeground: '--fx-color-status-info-fg',\n infoBackground: '--fx-color-status-info-bg',\n },\n scrim: '--fx-color-scrim',\n choiceIndicator: '--fx-color-choice-indicator',\n} as const;\n\nexport const surfaceTokens = colorTokens.surface;\n\nexport const statusTokens = {\n success: {\n foreground: '--fx-color-status-success-fg',\n background: '--fx-color-status-success-bg',\n },\n warning: {\n foreground: '--fx-color-status-warning-fg',\n background: '--fx-color-status-warning-bg',\n },\n error: {\n foreground: '--fx-color-status-error-fg',\n background: '--fx-color-status-error-bg',\n },\n info: {\n foreground: '--fx-color-status-info-fg',\n background: '--fx-color-status-info-bg',\n },\n} as const;\n\nexport const spaceTokens = {\n inline: '--fx-space-inline',\n control: '--fx-space-control',\n stack: '--fx-space-stack',\n section: '--fx-space-section',\n page: '--fx-space-page',\n} as const;\n\nexport const shapeTokens = {\n radius: {\n control: '--fx-radius-control',\n card: '--fx-radius-card',\n popover: '--fx-radius-popover',\n dialog: '--fx-radius-dialog',\n composer: '--fx-radius-composer',\n pill: '--fx-radius-pill',\n },\n border: {\n width: '--fx-border-width',\n focusWidth: '--fx-border-focus-width',\n focusOffset: '--fx-border-focus-offset',\n },\n shadow: {\n subtle: '--fx-shadow-subtle',\n floating: '--fx-shadow-floating',\n dialog: '--fx-shadow-dialog',\n },\n} as const;\n\nexport const motionTokens = {\n feedback: '--fx-motion-feedback',\n hover: '--fx-motion-hover',\n expand: '--fx-motion-expand',\n panel: '--fx-motion-panel',\n easing: '--fx-motion-ease',\n} as const;\n\nexport const layerTokens = {\n content: '--fx-layer-content',\n sticky: '--fx-layer-sticky',\n popover: '--fx-layer-popover',\n dialog: '--fx-layer-dialog',\n toast: '--fx-layer-toast',\n tooltip: '--fx-layer-tooltip',\n} as const;\n\nexport const componentTokens = {\n controlHeightCompact: '--fx-component-control-height-compact',\n controlHeightDefault: '--fx-component-control-height-default',\n controlHeightLarge: '--fx-component-control-height-large',\n controlIconSize: '--fx-component-control-icon-size',\n controlIconHitAreaMin: '--fx-component-control-icon-hit-area-min',\n fieldHeightDefault: '--fx-component-field-height-default',\n navigationRowHeight: '--fx-component-navigation-row-height',\n editorRowHeight: '--fx-component-editor-row-height',\n panelHeaderHeight: '--fx-component-panel-header-height',\n navigationRailWidth: '--fx-component-navigation-rail-width',\n panelConfigMinWidth: '--fx-component-panel-config-min-width',\n panelConfigMaxWidth: '--fx-component-panel-config-max-width',\n panelChatMinWidth: '--fx-component-panel-chat-min-width',\n panelChatDefaultWidth: '--fx-component-panel-chat-default-width',\n menuRowHeight: '--fx-component-menu-row-height',\n menuMinWidth: '--fx-component-menu-min-width',\n dialogMaxWidth: '--fx-component-dialog-max-width',\n dialogPadding: '--fx-component-dialog-padding',\n conversationMaxWidth: '--fx-component-conversation-max-width',\n conversationMessageGap: '--fx-component-conversation-message-gap',\n composerRadius: '--fx-component-composer-radius',\n composerMinHeight: '--fx-component-composer-min-height',\n composerTextMaxHeight: '--fx-component-composer-text-max-height',\n tooltipDelay: '--fx-component-tooltip-delay',\n spinnerDuration: '--fx-component-status-spinner-duration',\n buttonRadius: '--fx-component-button-radius',\n choiceSize: '--fx-component-choice-size',\n choiceDotSize: '--fx-component-choice-dot-size',\n} as const;\n\n", "import { useSyncExternalStore } from 'react';\n\ntype WorkspaceConnectionClient = {\n transport?: { connected?: boolean; request?: unknown };\n onDisconnect?: (listener: () => void) => () => void;\n};\n\nfunction readConnected(client?: WorkspaceConnectionClient | null) {\n const transport = client?.transport;\n return Boolean(transport && typeof transport.request === 'function' && transport.connected !== false);\n}\n\nexport function useWorkspaceClientConnected(client?: WorkspaceConnectionClient | null) {\n return useSyncExternalStore(\n (onChange) => client?.onDisconnect?.(onChange) ?? (() => {}),\n () => readConnected(client),\n () => readConnected(client),\n );\n}\n", "import type { InspectorFormField, InspectorFormFieldKind, InspectorFormGroup } from './InspectorForm';\n/** @param {string | number | undefined | null} key */\nexport function formatInspectorFieldLabel(key?: string | number | null) {\n if (key == null) return '';\n const text = String(key);\n if (!text) return '';\n return text\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .split(/[\\s_-]+/)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n}\n\n/** @param {unknown} value */\nfunction numericComponents(value: unknown): number[] | null {\n if (!Array.isArray(value)) return null;\n if (value.length === 0) return null;\n if (!value.every((entry) => typeof entry === 'number' && Number.isFinite(entry))) return null;\n return value;\n}\n\n/** @param {unknown} schema */\nfunction schemaTypeName(schema: unknown) {\n if (typeof schema === 'string') return schema.toLowerCase();\n if (schema && typeof schema === 'object' && 'type' in schema && typeof schema.type === 'string') return schema.type.toLowerCase();\n return '';\n}\n\nconst HEX_COLOR = /^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;\n\n/** @param {unknown} value */\nfunction isAssetRefRecord(value: unknown) {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return false;\n const record = (value as Record<string, unknown>);\n const identity = record.guid ?? record.id;\n if (typeof identity !== 'string' || identity.trim() === '') return false;\n return Object.values(record).every((entry) => entry == null || typeof entry !== 'object');\n}\n\n/**\n * @param {unknown} schema\n * @param {unknown} value\n * @returns {'bool' | 'number' | 'vector3' | 'vector4' | 'color' | 'asset' | 'enum' | 'text'}\n */\nexport function resolveInspectorFieldKind(schema: unknown, value: unknown): InspectorFormFieldKind {\n const type = schemaTypeName(schema);\n\n if (typeof value === 'boolean' || type.includes('bool')) return 'bool';\n if (typeof value === 'number' || type === 'f32' || type === 'f64' || type === 'i32' || type === 'u32' || type === 'number') {\n return 'number';\n }\n\n const array = numericComponents(value);\n if (array?.length === 3) return 'vector3';\n if (array?.length === 4) return 'vector4';\n\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const record = (value as Record<string, unknown>);\n if (typeof record.x === 'number' && typeof record.y === 'number' && typeof record.z === 'number') {\n return typeof record.w === 'number' ? 'vector4' : 'vector3';\n }\n }\n\n if (type.includes('enum') || (schema && typeof schema === 'object' && Array.isArray((schema as Record<string, unknown>).enum))) {\n return 'enum';\n }\n if (type.includes('color') || (typeof value === 'string' && HEX_COLOR.test(value))) return 'color';\n if (type.includes('asset') || type.includes('guid') || type.includes('ref') || isAssetRefRecord(value)) return 'asset';\n\n if (Array.isArray(value) || (value && typeof value === 'object')) return 'text';\n return 'text';\n}\n\n/** @param {unknown} value @param {string} kind */\nexport function normalizeInspectorFieldValue(value: unknown, kind: string): InspectorFormField[\"value\"] {\n if (value === undefined) return 'Unavailable';\n\n if (kind === 'vector3') {\n const array = numericComponents(value);\n if (array?.length === 3) return { x: array[0], y: array[1], z: array[2] };\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const record = (value as Record<string, number>);\n return { x: record.x ?? 0, y: record.y ?? 0, z: record.z ?? 0 };\n }\n return { x: 0, y: 0, z: 0 };\n }\n\n if (kind === 'vector4') {\n const array = numericComponents(value);\n if (array?.length === 4) return { x: array[0], y: array[1], z: array[2], w: array[3] };\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const record = (value as Record<string, number>);\n return { x: record.x ?? 0, y: record.y ?? 0, z: record.z ?? 0, w: record.w ?? 0 };\n }\n return { x: 0, y: 0, z: 0, w: 0 };\n }\n\n if (kind === 'asset' && value && typeof value === 'object' && !Array.isArray(value)) {\n const record = (value as Record<string, unknown>);\n return String(record.name ?? record.guid ?? record.id ?? '');\n }\n\n if (kind === 'bool' || kind === 'number') return value;\n if (typeof value === 'object') return JSON.stringify(value);\n return value;\n}\n\n/** @param {string} key @param {string} label @param {string} kind @param {unknown} value @param {string[] | undefined} [options] */\nfunction freezeField(key: string, label: string, kind: InspectorFormFieldKind, value: unknown, options?: string[]): InspectorFormField {\n return Object.freeze({\n key,\n label,\n kind,\n value: normalizeInspectorFieldValue(value, kind),\n ...(options === undefined ? {} : { options: Object.freeze([...options]) }),\n });\n}\n\nfunction freezeGroup(group: InspectorFormGroup): InspectorFormGroup {\n return Object.freeze({\n key: group.key,\n name: group.name,\n ...(group.category === undefined ? {} : { category: group.category }),\n fields: Object.freeze(group.fields),\n ...(group.groups === undefined ? {} : { groups: Object.freeze(group.groups) }),\n });\n}\n\n/** @param {unknown} value */\nfunction objectListItems(value: unknown): Record<string, unknown>[] | null {\n if (!Array.isArray(value) || value.length === 0) return null;\n if (!value.every((entry) => entry && typeof entry === 'object' && !Array.isArray(entry))) return null;\n return value;\n}\n\n/**\n * @param {Record<string, unknown>} record\n * @param {string} keyPrefix\n */\nfunction partitionRecord(record: Record<string, unknown>, keyPrefix: string): { fields: InspectorFormField[]; groups: InspectorFormGroup[] } {\n const fields: InspectorFormField[] = [];\n const groups: InspectorFormGroup[] = [];\n for (const [key, value] of Object.entries(record)) {\n if (value === undefined || value === null) continue;\n if (typeof value === 'string' && value.trim() === '') continue;\n const path = keyPrefix ? `${keyPrefix}.${key}` : key;\n const name = formatInspectorFieldLabel(key);\n const listed = objectListItems(value);\n if (listed) {\n const child = arrayToGroup(listed, path, name);\n if (child) groups.push(child);\n continue;\n }\n const kind = resolveInspectorFieldKind(undefined, value);\n const nestedObject = value && typeof value === 'object' && !Array.isArray(value)\n && kind !== 'vector3' && kind !== 'vector4' && kind !== 'asset';\n if (nestedObject) {\n const child = recordToGroup((value as Record<string, unknown>), path, name, 'all');\n if (child) groups.push(child);\n continue;\n }\n fields.push(freezeField(key, name, kind, value));\n }\n return { fields, groups };\n}\n\n/** @param {Record<string, unknown>} record @param {string} key @param {string} name @param {'all' | 'type' | 'capability'} category */\nfunction recordToGroup(record: Record<string, unknown>, key: string, name: string, category: NonNullable<InspectorFormGroup[\"category\"]>): InspectorFormGroup | null {\n const partitioned = partitionRecord(record, key);\n if (partitioned.fields.length === 0 && partitioned.groups.length === 0) return null;\n return freezeGroup({\n key,\n name,\n category,\n fields: partitioned.fields,\n groups: partitioned.groups,\n });\n}\n\n/** @param {Record<string, unknown>[]} items @param {string} path @param {string} name */\nfunction arrayToGroup(items: Record<string, unknown>[], path: string, name: string): InspectorFormGroup | null {\n const groups: InspectorFormGroup[] = [];\n for (const [index, item] of items.entries()) {\n const label = item.name ?? item.id ?? item.slotName ?? item.guid ?? String(index);\n const child = recordToGroup(item, `${path}.${index}`, formatInspectorFieldLabel(String(label)), 'type');\n if (child) groups.push(child);\n }\n if (groups.length === 0) return null;\n return freezeGroup({\n key: path,\n name,\n category: 'capability',\n fields: [],\n groups,\n });\n}\n\nfunction identityFactFields(inspection: Record<string, unknown>): InspectorFormField[] {\n const asset = inspection.asset && typeof inspection.asset === 'object' ? inspection.asset as Record<string, unknown> : {};\n const source = inspection.source && typeof inspection.source === 'object' ? inspection.source as Record<string, unknown> : {};\n const ddc = inspection.ddc && typeof inspection.ddc === 'object' ? inspection.ddc as Record<string, unknown> : {};\n const facts: [string, string, unknown][] = [\n ['guid', 'GUID', inspection.guid ?? asset.guid],\n ['kind', 'Kind', asset.kind],\n ['name', 'Name', asset.name],\n ['path', 'Path', asset.path],\n ['source', 'Source', source.path ?? asset.sourcePath],\n ['revision', 'Revision', inspection.revision ?? asset.revision ?? source.revision],\n ['package', 'Package', asset.packageId ?? asset.packageUrl],\n ['ddc', 'DDC', ddc.state],\n ];\n const fields = [];\n for (const [key, label, value] of facts) {\n if (value === undefined || value === null) continue;\n if (typeof value === 'string' && value.trim() === '') continue;\n fields.push(freezeField(key, label, resolveInspectorFieldKind(undefined, value), value));\n }\n return fields;\n}\n\n/**\n * @param {unknown} inspection\n * @param {{ identityTitle?: string }} [options]\n */\nexport function inspectorFormGroupsFromInspection(inspection: unknown, options: { identityTitle?: string } = {}): readonly InspectorFormGroup[] {\n if (!inspection || typeof inspection !== 'object' || Array.isArray(inspection)) {\n return Object.freeze([]);\n }\n const identityTitle = options.identityTitle ?? 'Asset';\n const identityFields = identityFactFields(inspection as Record<string, unknown>);\n const meta = (inspection as Record<string, unknown>).meta;\n let metaFields: InspectorFormField[] = [];\n let nested: InspectorFormGroup[] = [];\n if (meta && typeof meta === 'object' && !Array.isArray(meta)) {\n const partitioned = partitionRecord((meta as Record<string, unknown>), 'meta');\n metaFields = partitioned.fields;\n nested = partitioned.groups;\n }\n const groups: InspectorFormGroup[] = [];\n const fields = [...identityFields, ...metaFields];\n if (fields.length) {\n groups.push(freezeGroup({\n key: 'identity',\n name: identityTitle,\n category: 'type',\n fields,\n groups: [],\n }));\n }\n groups.push(...nested);\n return Object.freeze(groups);\n}\n", "import { Box } from 'lucide-react';\nimport { useState, type ReactNode } from 'react';\n\nimport {\n Checkbox,\n CollapsibleSection,\n PropertyRow,\n Select,\n TextInput,\n} from './components';\nimport { inspectorFormGroupsFromInspection } from './inspector-form-model';\n\nexport type InspectorFormFieldKind =\n | 'vector3'\n | 'vector4'\n | 'number'\n | 'bool'\n | 'text'\n | 'enum'\n | 'color'\n | 'asset';\n\nexport type InspectorFormField = {\n key: string;\n label: string;\n kind: InspectorFormFieldKind;\n value: unknown;\n options?: readonly string[];\n};\n\nexport type InspectorFormGroup = {\n key: string;\n name: string;\n category?: 'all' | 'type' | 'capability';\n fields: readonly InspectorFormField[];\n groups?: readonly InspectorFormGroup[];\n};\n\nconst READ_ONLY = { readOnly: true, tabIndex: -1 as const };\n\nfunction VectorField({\n axes,\n vector,\n}: {\n axes: readonly ('x' | 'y' | 'z' | 'w')[];\n vector: Record<'x' | 'y' | 'z' | 'w', number>;\n}) {\n return (\n <span className={`fx-inspector-form__vec${axes.length > 3 ? ' fx-inspector-form__vec--4' : ''}`}>\n {axes.map((axis) => (\n <span className={`fx-inspector-form__vcell fx-inspector-form__vcell--${axis}`} key={axis}>\n <span className=\"fx-inspector-form__axis\">{axis.toUpperCase()}</span>\n <span className=\"fx-inspector-form__numfield\">\n <TextInput\n className=\"fx-inspector-form__input fx-inspector-form__input--number\"\n type=\"number\"\n value={vector[axis]}\n {...READ_ONLY}\n />\n </span>\n </span>\n ))}\n </span>\n );\n}\n\nexport function InspectorFieldControl({ field }: { field: InspectorFormField }) {\n if (field.kind === 'vector3' && typeof field.value === 'object' && field.value !== null) {\n const vector = field.value as Record<'x' | 'y' | 'z', number>;\n return <VectorField axes={['x', 'y', 'z']} vector={{ ...vector, w: 0 }} />;\n }\n if (field.kind === 'vector4' && typeof field.value === 'object' && field.value !== null) {\n const vector = field.value as Record<'x' | 'y' | 'z' | 'w', number>;\n return <VectorField axes={['x', 'y', 'z', 'w']} vector={vector} />;\n }\n if (field.kind === 'bool') {\n return (\n <Checkbox\n className=\"fx-inspector-form__checkbox\"\n checked={field.value === true}\n disabled\n hideLabel\n label={field.label}\n />\n );\n }\n if (field.kind === 'enum') {\n return (\n <span className=\"fx-inspector-form__select\">\n <Select className=\"fx-inspector-form__input\" value={String(field.value)} disabled>\n {(field.options ?? [String(field.value)]).map((option) => (\n <option value={option} key={option}>{option}</option>\n ))}\n </Select>\n </span>\n );\n }\n if (field.kind === 'color') {\n return (\n <span className=\"fx-inspector-form__color\">\n <span className=\"fx-inspector-form__swatch\" aria-hidden style={{ background: String(field.value) }} />\n <TextInput className=\"fx-inspector-form__input fx-inspector-form__input--hex\" value={String(field.value)} {...READ_ONLY} />\n </span>\n );\n }\n if (field.kind === 'asset') {\n const empty = !String(field.value);\n return (\n <span className=\"fx-inspector-form__asset\">\n <span className={`fx-inspector-form__asset-thumb${empty ? ' is-empty' : ''}`}>{empty ? null : <Box size={16} />}</span>\n <span className=\"fx-inspector-form__asset-body\">\n <span className=\"fx-inspector-form__asset-combo\">\n <span className={`fx-inspector-form__asset-label${empty ? ' is-empty' : ''}`}>{empty ? 'None' : String(field.value)}</span>\n </span>\n </span>\n </span>\n );\n }\n return (\n <span className={field.kind === 'number' ? 'fx-inspector-form__numfield fx-inspector-form__numfield--solo' : undefined}>\n <TextInput\n className={`fx-inspector-form__input ${field.kind === 'number' ? 'fx-inspector-form__input--number' : 'fx-inspector-form__input--text'}`}\n type={field.kind === 'number' ? 'number' : 'text'}\n value={String(field.value)}\n {...READ_ONLY}\n />\n </span>\n );\n}\n\nfunction FormGroup({\n group,\n nested = false,\n}: {\n group: InspectorFormGroup;\n nested?: boolean;\n}) {\n const [open, setOpen] = useState(true);\n const category = group.category === 'all' ? 'all' : group.category === 'capability' ? 'cap' : 'type';\n return (\n <div className={`fx-inspector-form__group fx-inspector-form__group--${category}${nested ? ' is-nested' : ''}`}>\n <CollapsibleSection\n open={open}\n onOpenChange={setOpen}\n title={(\n <span className=\"fx-inspector-form__title\">\n <span className=\"fx-inspector-form__icon\"><Box size={13} strokeWidth={1.7} /></span>\n <span>{group.name}</span>\n </span>\n )}\n >\n <div className=\"fx-inspector-form__fields\">\n {group.fields.map((field) => (\n <div className=\"fx-inspector-form__row\" key={field.key} data-testid={`inspector-form-field-${group.key}-${field.key}`}>\n <PropertyRow className=\"fx-inspector-form__property\" label={<span title={field.key}>{field.label}</span>}>\n <InspectorFieldControl field={field} />\n </PropertyRow>\n </div>\n ))}\n {(group.groups ?? []).map((child) => (\n <FormGroup group={child} key={child.key} nested />\n ))}\n </div>\n </CollapsibleSection>\n </div>\n );\n}\n\nexport function InspectorForm({\n groups,\n inspection,\n identityTitle,\n className,\n empty,\n}: {\n groups?: readonly InspectorFormGroup[];\n inspection?: unknown;\n identityTitle?: string;\n className?: string;\n empty?: ReactNode;\n}) {\n const resolved = groups ?? inspectorFormGroupsFromInspection(\n inspection,\n identityTitle === undefined ? {} : { identityTitle },\n ) as InspectorFormGroup[];\n if (resolved.length === 0) return empty ?? null;\n return (\n <div className={['fx-inspector-form', className].filter(Boolean).join(' ')} data-view-readonly=\"true\">\n {resolved.map((group) => (\n <FormGroup group={group} key={group.key} />\n ))}\n </div>\n );\n}\n", "import { AlertCircle, Check, Copy, X } from 'lucide-react';\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n type CSSProperties,\n type ReactNode,\n} from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { Button, IconButton, Text } from './components';\n\nexport type ErrorNoticeInput = {\n title: ReactNode;\n description?: ReactNode;\n hint?: ReactNode;\n code?: string;\n details?: ReactNode;\n detailsLabel?: string;\n /** Plain text written to the clipboard when the user copies details. */\n copyText?: string;\n copyLabel?: string;\n copiedLabel?: string;\n /** Default true: stays until the user clicks close. */\n persistent?: boolean;\n /** Used only when persistent is false. */\n duration?: number;\n closeLabel?: string;\n onDismiss?: () => void;\n};\n\nexport type ErrorNoticeItem = ErrorNoticeInput & {\n id: number;\n persistent: boolean;\n};\n\nexport type ErrorNoticeProps = ErrorNoticeInput & {\n id?: number;\n onClose: () => void;\n};\n\ntype Listener = () => void;\n\nlet nextId = 0;\nlet notices: ErrorNoticeItem[] = [];\nconst listeners = new Set<Listener>();\nconst timers = new Map<number, ReturnType<typeof setTimeout>>();\n\nfunction emit() {\n for (const listener of listeners) listener();\n}\n\nexport function subscribeErrorNotices(listener: Listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\nexport function getErrorNotices() {\n return notices;\n}\n\nexport function showErrorNotice(input: ErrorNoticeInput): number {\n const id = ++nextId;\n const persistent = input.persistent !== false;\n notices = [...notices, { ...input, id, persistent }];\n emit();\n if (!persistent) {\n const duration = input.duration ?? 8000;\n if (duration > 0) {\n timers.set(\n id,\n setTimeout(() => {\n timers.delete(id);\n dismissErrorNotice(id);\n }, duration),\n );\n }\n }\n return id;\n}\n\nexport function dismissErrorNotice(id: number) {\n const timer = timers.get(id);\n if (timer !== undefined) {\n clearTimeout(timer);\n timers.delete(id);\n }\n const current = notices.find((notice) => notice.id === id);\n if (!current) return;\n notices = notices.filter((notice) => notice.id !== id);\n emit();\n current.onDismiss?.();\n}\n\nfunction resolveCopyText(copyText?: string, details?: ReactNode) {\n if (typeof copyText === 'string' && copyText.trim() !== '') return copyText;\n if (typeof details === 'string' && details.trim() !== '') return details;\n return undefined;\n}\n\nexport function ErrorNotice({\n title,\n description,\n hint,\n code,\n details,\n detailsLabel = '\u8BE6\u7EC6\u4FE1\u606F',\n copyText,\n copyLabel = '\u590D\u5236\u8BE6\u7EC6\u4FE1\u606F',\n copiedLabel = '\u5DF2\u590D\u5236',\n closeLabel = '\u5173\u95ED\u9519\u8BEF\u63D0\u793A',\n onClose,\n}: ErrorNoticeProps) {\n const [copied, setCopied] = useState(false);\n const clipboardText = resolveCopyText(copyText, details);\n\n useEffect(() => {\n if (!copied) return undefined;\n const timer = setTimeout(() => setCopied(false), 2000);\n return () => clearTimeout(timer);\n }, [copied]);\n\n async function handleCopyDetails() {\n if (!clipboardText) return;\n try {\n await navigator.clipboard.writeText(clipboardText);\n setCopied(true);\n } catch {\n // Clipboard may be unavailable; ignore rather than surfacing a second error.\n }\n }\n\n return (\n <div className=\"fx-error-notice fx-status--error\" role=\"alert\">\n <AlertCircle className=\"fx-icon fx-error-notice__icon\" aria-hidden />\n <div className=\"fx-error-notice__body\">\n <strong className=\"fx-error-notice__title\">{title}</strong>\n {code ? (\n <Text as=\"code\" variant=\"code\" className=\"fx-error-notice__code\">\n {code}\n </Text>\n ) : null}\n {description ? (\n <Text variant=\"body\" className=\"fx-error-notice__description\">\n {description}\n </Text>\n ) : null}\n {hint ? (\n <Text variant=\"caption\" className=\"fx-error-notice__hint\">\n {hint}\n </Text>\n ) : null}\n {details ? (\n <details className=\"fx-error-notice__details\" open>\n <summary className=\"fx-error-notice__details-summary\">\n <span>{detailsLabel}</span>\n {clipboardText ? (\n <Button\n type=\"button\"\n variant=\"quiet\"\n size=\"compact\"\n className=\"fx-error-notice__copy\"\n leadingIcon={\n copied ? (\n <Check className=\"fx-icon\" aria-hidden />\n ) : (\n <Copy className=\"fx-icon\" aria-hidden />\n )\n }\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n void handleCopyDetails();\n }}\n >\n {copied ? copiedLabel : copyLabel}\n </Button>\n ) : null}\n </summary>\n <pre className=\"fx-error-notice__details-body\">{details}</pre>\n </details>\n ) : null}\n </div>\n <IconButton\n label={closeLabel}\n icon={<X className=\"fx-icon\" />}\n variant=\"quiet\"\n size=\"compact\"\n onClick={onClose}\n />\n </div>\n );\n}\n\nconst STACK_PEEK = 8;\nconst STACK_GAP = 8;\nconst STACK_MAX_BEHIND = 2;\n\nfunction stackMetrics(items: ErrorNoticeItem[], heights: Record<number, number>, expanded: boolean) {\n const heightOf = (id: number) => heights[id] ?? 0;\n const frontHeight = items[0] ? heightOf(items[0].id) : 0;\n let y = 0;\n const slots = items.map((item, index) => {\n const height = heightOf(item.id);\n const peekIndex = Math.min(index, STACK_MAX_BEHIND);\n const slotY = expanded ? y : Math.max(0, frontHeight - height + peekIndex * STACK_PEEK);\n if (expanded) y += height + STACK_GAP;\n return {\n id: item.id,\n y: slotY,\n z: items.length - index,\n interactive: expanded || index === 0,\n };\n });\n const stackHeight = expanded\n ? items.reduce((sum, item, index) => sum + heightOf(item.id) + (index > 0 ? STACK_GAP : 0), 0)\n : frontHeight + Math.min(Math.max(items.length - 1, 0), STACK_MAX_BEHIND) * STACK_PEEK;\n return { slots, stackHeight };\n}\n\nexport function ErrorNoticeStack({\n items,\n inline = false,\n onClose,\n}: {\n items: ErrorNoticeItem[];\n inline?: boolean;\n onClose: (id: number) => void;\n}) {\n const [expanded, setExpanded] = useState(false);\n const [heights, setHeights] = useState<Record<number, number>>({});\n const slotNodes = useRef(new Map<number, HTMLDivElement>());\n const stacked = items.length > 1;\n const open = stacked && expanded;\n\n const measure = useCallback(() => {\n setHeights((current) => {\n let changed = Object.keys(current).length !== items.length;\n const next: Record<number, number> = {};\n for (const item of items) {\n const height = slotNodes.current.get(item.id)?.offsetHeight ?? 0;\n next[item.id] = height;\n if (current[item.id] !== height) changed = true;\n }\n return changed ? next : current;\n });\n }, [items]);\n\n useLayoutEffect(() => {\n measure();\n const observer = new ResizeObserver(measure);\n for (const item of items) {\n const node = slotNodes.current.get(item.id);\n if (node) observer.observe(node);\n }\n return () => observer.disconnect();\n }, [items, measure]);\n\n const { slots, stackHeight } = useMemo(\n () => stackMetrics(items, heights, open),\n [items, heights, open],\n );\n\n if (items.length === 0) return null;\n\n return (\n <div\n className={['fx-error-notice-region', 'fx-ui', inline && 'fx-error-notice-region--inline']\n .filter(Boolean)\n .join(' ')}\n aria-live=\"assertive\"\n data-count={items.length}\n data-expanded={open ? '' : undefined}\n data-ready={items.every((item) => (heights[item.id] ?? 0) > 0) ? '' : undefined}\n onMouseEnter={stacked ? () => setExpanded(true) : undefined}\n onMouseLeave={stacked ? () => setExpanded(false) : undefined}\n onFocus={stacked ? () => setExpanded(true) : undefined}\n onBlur={\n stacked\n ? (event) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) {\n setExpanded(false);\n }\n }\n : undefined\n }\n style={\n {\n '--fx-error-notice-stack-height': `${stackHeight}px`,\n } as CSSProperties\n }\n >\n {items.map((notice) => {\n const slot = slots.find((entry) => entry.id === notice.id)!;\n return (\n <div\n className=\"fx-error-notice-slot\"\n key={notice.id}\n ref={(node) => {\n if (node) slotNodes.current.set(notice.id, node);\n else slotNodes.current.delete(notice.id);\n }}\n data-inert={slot.interactive ? undefined : ''}\n style={\n {\n '--fx-error-notice-y': `${slot.y}px`,\n '--fx-error-notice-z': slot.z,\n } as CSSProperties\n }\n >\n <ErrorNotice\n {...notice}\n {...(notice.closeLabel === undefined ? {} : { closeLabel: notice.closeLabel })}\n onClose={() => onClose(notice.id)}\n />\n </div>\n );\n })}\n </div>\n );\n}\n\nexport function ErrorNoticeHost() {\n const items = useSyncExternalStore(subscribeErrorNotices, getErrorNotices, getErrorNotices);\n const ordered = useMemo(() => [...items].reverse(), [items]);\n if (typeof document === 'undefined' || ordered.length === 0) return null;\n return createPortal(\n <ErrorNoticeStack items={ordered} onClose={dismissErrorNotice} />,\n document.body,\n );\n}\n", "import {\n ChevronsRight,\n Minus,\n Pin,\n Plus,\n X,\n type LucideIcon,\n} from 'lucide-react';\nimport {\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type PointerEvent as ReactPointerEvent,\n type ReactElement,\n type RefObject,\n} from 'react';\nimport { ContextMenu, type MenuItem } from './components';\nimport { iconForPage } from './page-tab-icons';\n\nexport type PageTabItem = {\n id: string;\n title: string;\n typeId: string;\n icon?: LucideIcon;\n resourcePath?: string;\n closable?: boolean;\n dirty?: boolean;\n tooltip?: string;\n};\n\nexport type PageTabNewTypeOption = {\n typeId: string;\n title: string;\n};\n\nexport type PageTabStripLabels = {\n tabList: string;\n newPage: string;\n allPages: string;\n noOpenableTypes: string;\n closeTab: string;\n contextClose: string;\n contextCloseOthers: string;\n contextCloseToRight: string;\n};\n\nconst DEFAULT_LABELS: PageTabStripLabels = {\n tabList: '\u5DF2\u6253\u5F00\u7684\u9875\u9762',\n newPage: '\u65B0\u5EFA\u9875\u9762',\n allPages: '\u5168\u90E8\u9875\u9762',\n noOpenableTypes: '\u6CA1\u6709\u53EF\u65B0\u5EFA\u7684\u7C7B\u578B',\n closeTab: '\u5173\u95ED\u6807\u7B7E\u9875',\n contextClose: '\u5173\u95ED',\n contextCloseOthers: '\u5173\u95ED\u5176\u4ED6',\n contextCloseToRight: '\u5173\u95ED\u53F3\u4FA7',\n};\n\nfunction classes(...names: Array<string | false | null | undefined>) {\n return names.filter(Boolean).join(' ');\n}\n\nfunction useAnchoredMenu(anchorRef: RefObject<HTMLElement | null>) {\n const [open, setOpen] = useState(false);\n const [position, setPosition] = useState({ x: 0, y: 0 });\n\n const openAtAnchor = useCallback(\n (align: 'start' | 'end' = 'start') => {\n const el = anchorRef.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n setPosition({\n x: align === 'end' ? rect.right : rect.left,\n y: rect.bottom + 4,\n });\n setOpen(true);\n },\n [anchorRef],\n );\n\n return { open, setOpen, position, openAtAnchor };\n}\n\nexport type PageTabStripProps = {\n pages: readonly PageTabItem[];\n activePageId: string | null;\n onSelect: (pageId: string) => void;\n onClose?: (pageId: string) => void;\n onCloseOthers?: (pageId: string) => void;\n onCloseToRight?: (pageId: string) => void;\n onReorder?: (pageId: string, toIndex: number) => void;\n newPageTypes?: readonly PageTabNewTypeOption[];\n onNewPage?: (typeId: string) => void;\n labels?: Partial<PageTabStripLabels>;\n className?: string;\n};\n\nexport function PageTabStrip({\n pages,\n activePageId,\n onSelect,\n onClose,\n onCloseOthers,\n onCloseToRight,\n onReorder,\n newPageTypes = [],\n onNewPage,\n labels: labelOverrides,\n className,\n}: PageTabStripProps): ReactElement | null {\n const labels = { ...DEFAULT_LABELS, ...labelOverrides };\n const listRef = useRef<HTMLDivElement>(null);\n const newButtonRef = useRef<HTMLButtonElement>(null);\n const overflowButtonRef = useRef<HTMLButtonElement>(null);\n const dragKeyRef = useRef<string | null>(null);\n const [draggingKey, setDraggingKey] = useState<string | null>(null);\n const [overflowing, setOverflowing] = useState(false);\n const [contextMenu, setContextMenu] = useState<{ x: number; y: number; pageId: string } | null>(\n null,\n );\n const newMenu = useAnchoredMenu(newButtonRef);\n const overflowMenu = useAnchoredMenu(overflowButtonRef);\n const menuId = useId();\n\n useEffect(() => {\n if (!activePageId) return;\n listRef.current\n ?.querySelector(`[data-page-id=\"${CSS.escape(activePageId)}\"]`)\n ?.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n }, [activePageId]);\n\n useEffect(() => {\n const el = listRef.current;\n if (!el) return;\n const measure = () => setOverflowing(el.scrollWidth - el.clientWidth > 1);\n measure();\n const ro = new ResizeObserver(measure);\n ro.observe(el);\n return () => ro.disconnect();\n }, [pages.length]);\n\n useEffect(() => {\n const end = () => {\n dragKeyRef.current = null;\n setDraggingKey(null);\n };\n window.addEventListener('pointerup', end);\n return () => window.removeEventListener('pointerup', end);\n }, []);\n\n const handleTabClick = useCallback(\n (pageId: string) => {\n if (pageId === activePageId) return;\n onSelect(pageId);\n },\n [activePageId, onSelect],\n );\n\n const handlePointerDown = useCallback((event: ReactPointerEvent, pageId: string) => {\n if (event.button !== 0) return;\n if ((event.target as HTMLElement).closest('[data-page-close]')) return;\n dragKeyRef.current = pageId;\n }, []);\n\n const handlePointerMove = useCallback(\n (event: ReactPointerEvent) => {\n const dragKey = dragKeyRef.current;\n if (!dragKey || event.buttons !== 1 || !onReorder) return;\n const overId = (event.target as HTMLElement)\n .closest('[data-page-id]')\n ?.getAttribute('data-page-id');\n if (!overId || overId === dragKey) return;\n const toIndex = pages.findIndex((page) => page.id === overId);\n if (toIndex < 0) return;\n setDraggingKey(dragKey);\n onReorder(dragKey, toIndex);\n },\n [onReorder, pages],\n );\n\n const closePage = useCallback(\n (pageId: string) => {\n onClose?.(pageId);\n },\n [onClose],\n );\n\n if (pages.length === 0) return null;\n\n const contextPage = contextMenu\n ? pages.find((page) => page.id === contextMenu.pageId)\n : undefined;\n const contextItems: MenuItem[] = contextMenu && contextPage\n ? [\n {\n id: 'close',\n label: labels.contextClose,\n icon: <X className=\"fx-icon\" aria-hidden />,\n disabled: !contextPage.closable,\n onSelect: () => closePage(contextMenu.pageId),\n },\n {\n id: 'close-others',\n label: labels.contextCloseOthers,\n icon: <Minus className=\"fx-icon\" aria-hidden />,\n onSelect: () => {\n onCloseOthers?.(contextMenu.pageId);\n onSelect(contextMenu.pageId);\n },\n },\n {\n id: 'close-right',\n label: labels.contextCloseToRight,\n icon: <ChevronsRight className=\"fx-icon\" aria-hidden />,\n onSelect: () => onCloseToRight?.(contextMenu.pageId),\n },\n ]\n : [];\n\n const newPageMenuItems: MenuItem[] =\n newPageTypes.length === 0\n ? [{ id: 'empty', label: labels.noOpenableTypes, disabled: true }]\n : newPageTypes.map((type) => {\n const Icon = iconForPage({ typeId: type.typeId });\n return {\n id: type.typeId,\n label: type.title,\n icon: <Icon className=\"fx-icon\" aria-hidden />,\n onSelect: () => onNewPage?.(type.typeId),\n };\n });\n\n const overflowMenuItems: MenuItem[] = pages.map((page) => {\n const Icon = page.icon ?? iconForPage({ typeId: page.typeId, ...(page.resourcePath === undefined ? {} : { resourcePath: page.resourcePath }) });\n const mark = activePageId === page.id ? '\u25CF' : '\u25CB';\n const label = page.dirty ? `${page.title} *` : page.title;\n return {\n id: page.id,\n label: (\n <>\n <span className=\"fx-page-tab-menu__mark\">{mark}</span>\n <span className=\"fx-page-tab-menu__label\">{label}</span>\n </>\n ),\n icon: <Icon className=\"fx-icon\" aria-hidden />,\n selected: activePageId === page.id,\n onSelect: () => onSelect(page.id),\n };\n });\n\n return (\n <div className={classes('fx-page-tab-strip', 'fx-ui', className)} data-fx-slot=\"PageTabs\">\n <div className=\"fx-page-tab-strip__scope\">\n <div\n ref={listRef}\n className=\"fx-page-tab-strip__list\"\n role=\"tablist\"\n aria-label={labels.tabList}\n onPointerMove={handlePointerMove}\n >\n {pages.map((page) => {\n const active = activePageId === page.id;\n const Icon =\n page.icon ?? iconForPage({ typeId: page.typeId, ...(page.resourcePath === undefined ? {} : { resourcePath: page.resourcePath }) });\n const closable = page.closable !== false;\n const tabClass = classes(\n 'fx-page-tab',\n active && 'is-active',\n !closable && 'is-pinned',\n page.dirty && 'is-dirty',\n draggingKey === page.id && 'is-drag',\n );\n return (\n <button\n key={page.id}\n type=\"button\"\n className={tabClass}\n role=\"tab\"\n aria-selected={active}\n data-page-id={page.id}\n data-dirty={page.dirty ? '1' : undefined}\n title={page.tooltip ?? page.resourcePath ?? page.title}\n onClick={() => handleTabClick(page.id)}\n onAuxClick={(event) => {\n if (event.button === 1 && closable) {\n event.preventDefault();\n closePage(page.id);\n }\n }}\n onContextMenu={(event) => {\n event.preventDefault();\n setContextMenu({ x: event.clientX, y: event.clientY, pageId: page.id });\n }}\n onPointerDown={(event) => handlePointerDown(event, page.id)}\n >\n <Icon className=\"fx-page-tab__icon\" aria-hidden />\n <span className=\"fx-page-tab__label\">{page.title}</span>\n {page.dirty ? <span className=\"fx-page-tab__dirty\" aria-hidden>*</span> : null}\n {closable ? (\n <span\n className=\"fx-page-tab__close\"\n role=\"button\"\n aria-label={labels.closeTab}\n data-page-close={page.id}\n onClick={(event) => {\n event.stopPropagation();\n closePage(page.id);\n }}\n >\n <X className=\"fx-page-tab__close-icon\" aria-hidden />\n </span>\n ) : (\n <Pin className=\"fx-page-tab__pin\" aria-hidden />\n )}\n </button>\n );\n })}\n </div>\n\n <button\n ref={newButtonRef}\n type=\"button\"\n className=\"fx-page-tab-btn fx-page-tab-btn--new\"\n title={labels.newPage}\n aria-label={labels.newPage}\n aria-haspopup=\"menu\"\n aria-expanded={newMenu.open}\n aria-controls={`${menuId}-new`}\n onClick={() => {\n if (newMenu.open) newMenu.setOpen(false);\n else newMenu.openAtAnchor('start');\n }}\n >\n <Plus className=\"fx-page-tab-btn__icon\" aria-hidden />\n </button>\n\n <div className=\"fx-page-tab-strip__actions\">\n {overflowing ? (\n <button\n ref={overflowButtonRef}\n type=\"button\"\n className=\"fx-page-tab-btn\"\n title={labels.allPages}\n aria-haspopup=\"menu\"\n aria-expanded={overflowMenu.open}\n aria-controls={`${menuId}-overflow`}\n onClick={() => {\n if (overflowMenu.open) overflowMenu.setOpen(false);\n else overflowMenu.openAtAnchor('end');\n }}\n >\n <ChevronsRight className=\"fx-page-tab-btn__icon\" aria-hidden />\n <span>{pages.length}</span>\n </button>\n ) : null}\n </div>\n </div>\n\n <ContextMenu\n open={contextMenu !== null}\n x={contextMenu?.x ?? 0}\n y={contextMenu?.y ?? 0}\n items={contextItems}\n onClose={() => setContextMenu(null)}\n label={contextPage?.title ?? labels.tabList}\n />\n\n <ContextMenu\n open={newMenu.open}\n x={newMenu.position.x}\n y={newMenu.position.y}\n items={newPageMenuItems}\n onClose={() => newMenu.setOpen(false)}\n label={labels.newPage}\n containerProps={{ id: `${menuId}-new` }}\n />\n\n <ContextMenu\n open={overflowMenu.open}\n x={overflowMenu.position.x}\n y={overflowMenu.position.y}\n items={overflowMenuItems}\n onClose={() => overflowMenu.setOpen(false)}\n label={labels.allPages}\n containerProps={{ id: `${menuId}-overflow` }}\n />\n </div>\n );\n}\n", "import {\n Box,\n Clapperboard,\n File,\n FileCode2,\n FileText,\n Image,\n Music,\n Package,\n Puzzle,\n Settings2,\n Type,\n type LucideIcon,\n} from 'lucide-react';\n\nexport type PageKind =\n | 'scene'\n | 'model'\n | 'image'\n | 'audio'\n | 'font'\n | 'pack'\n | 'code'\n | 'doc'\n | 'config'\n | 'plugin';\n\nconst ICON_BY_KIND: Record<PageKind, LucideIcon> = {\n scene: Clapperboard,\n model: Box,\n image: Image,\n audio: Music,\n font: Type,\n pack: Package,\n code: FileCode2,\n doc: FileText,\n config: Settings2,\n plugin: Puzzle,\n};\n\nconst EXT_KIND: ReadonlyArray<readonly [readonly string[], PageKind]> = [\n [['ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs', 'py'], 'code'],\n [['md', 'markdown', 'txt'], 'doc'],\n [['png', 'jpg', 'jpeg', 'webp', 'gif', 'svg', 'ico', 'hdr'], 'image'],\n [['mp3', 'wav', 'ogg', 'flac', 'aac', 'm4a', 'opus'], 'audio'],\n [['glb', 'gltf', 'fbx'], 'model'],\n [['ttf', 'otf', 'woff2'], 'font'],\n];\n\nexport function pageKindOf(input: { typeId: string; resourcePath?: string }): PageKind {\n const path = (input.resourcePath ?? '').toLowerCase();\n if (path) {\n if (path.endsWith('.scene.json')) return 'scene';\n if (path.endsWith('.pack.json')) return path.includes('scene') ? 'scene' : 'pack';\n const ext = path.split(/[?#]/u, 1)[0]?.split('.').pop() ?? '';\n for (const [exts, kind] of EXT_KIND) if (exts.includes(ext)) return kind;\n if (path.endsWith('forge.json') || path.endsWith('package.json')) return 'config';\n }\n const id = input.typeId.toLowerCase();\n for (const kind of Object.keys(ICON_BY_KIND) as PageKind[]) {\n if (id.includes(kind)) return kind;\n }\n if (id.includes('scene') || id.includes('level')) return 'scene';\n if (id.includes('workbench') || id.includes('wb-') || id.includes('plugin')) return 'plugin';\n return 'config';\n}\n\nexport function iconForPage(input: { typeId: string; resourcePath?: string }): LucideIcon {\n const path = (input.resourcePath ?? '').toLowerCase();\n const kind = pageKindOf(input);\n if (!path && kind === 'config' && !input.typeId.toLowerCase().includes('config')) return File;\n return ICON_BY_KIND[kind];\n}\n"],
5
+ "mappings": ";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAYK;AACP,SAAS,oBAAoB;;;AC5B7B,IAAM,qBAA8C,CAAC,SAAS,QAAQ,UAAU,KAAK;AAErF,SAAS,eAAe;AACtB,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,QAAQ,OAAO;AAAA,EACjB;AACF;AAEA,SAAS,kBACP,WACA,QACA,WACA,YACA,KACA;AACA,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,QAAQ,KAAK,GAAG,OAAO,IAAI;AAAA,IAChD,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,OAAO,MAAM,WAAW,GAAG,OAAO,IAAI;AAAA,IAC3D,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,OAAO,OAAO,QAAQ,IAAI,YAAY,GAAG,GAAG,OAAO,SAAS,IAAI;AAAA,IACrF,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,OAAO,OAAO,QAAQ,IAAI,YAAY,GAAG,GAAG,OAAO,MAAM,MAAM,WAAW;AAAA,EACjG;AACF;AAEA,SAAS,iBAAiB,GAAW,WAAmB,SAAiB;AACvE,QAAM,EAAE,MAAM,IAAI,aAAa;AAC/B,SAAO,KAAK,WAAW,IAAI,aAAa,QAAQ;AAClD;AAEA,SAAS,eAAe,GAAW,YAAoB,SAAiB;AACtE,QAAM,EAAE,OAAO,IAAI,aAAa;AAChC,SAAO,KAAK,WAAW,IAAI,cAAc,SAAS;AACpD;AAEA,SAAS,aAAa,GAAW,GAAW,WAAmB,YAAoB,SAAiB;AAClG,SAAO,iBAAiB,GAAG,WAAW,OAAO,KAAK,eAAe,GAAG,YAAY,OAAO;AACzF;AAEA,SAAS,YAAY,GAAW,GAAW,WAAmB,YAAoB,SAAiB;AACjG,QAAM,EAAE,OAAO,OAAO,IAAI,aAAa;AACvC,QAAM,OAAO,KAAK,IAAI,GAAG,OAAO;AAChC,QAAM,MAAM,KAAK,IAAI,GAAG,OAAO;AAC/B,QAAM,QAAQ,KAAK,IAAI,IAAI,WAAW,QAAQ,OAAO;AACrD,QAAM,SAAS,KAAK,IAAI,IAAI,YAAY,SAAS,OAAO;AACxD,SAAO,KAAK,IAAI,GAAG,QAAQ,IAAI,IAAI,KAAK,IAAI,GAAG,SAAS,GAAG;AAC7D;AAEA,SAAS,kBACP,WACA,GACA,GACA,WACA,YACA,SACA;AACA,QAAM,EAAE,OAAO,OAAO,IAAI,aAAa;AACvC,MAAI,cAAc,WAAW,cAAc,QAAQ;AACjD,WAAO;AAAA,MACL,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI,GAAG,QAAQ,UAAU,SAAS,CAAC;AAAA,MAC7D,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI,GAAG,SAAS,UAAU,UAAU,CAAC;AAAA,IACjE;AAAA,EACF;AACA,SAAO;AAAA,IACL,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI,GAAG,QAAQ,UAAU,SAAS,CAAC;AAAA,IAC7D,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI,GAAG,SAAS,UAAU,UAAU,CAAC;AAAA,EACjE;AACF;AAEO,SAAS,4BACd,QACA,WACA,YACA,UAA8C,CAAC,GACa;AAC5D,QAAM,MAAM,QAAQ,OAAO;AAC3B,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,aAAa,QAAQ,cAAc;AAEzC,MAAI,OAAO,WAAW,CAAC;AACvB,MAAI,YAAY,kBAAkB,MAAM,QAAQ,WAAW,YAAY,GAAG;AAC1E,MAAI,YAAY;AAEhB,aAAW,aAAa,YAAY;AAClC,UAAM,QAAQ,kBAAkB,WAAW,QAAQ,WAAW,YAAY,GAAG;AAC7E,UAAM,aAAa,cAAc,WAAW,cAAc;AAC1D,UAAM,WAAW,cAAc,SAAS,cAAc;AACtD,QAAI,cAAc,iBAAiB,MAAM,GAAG,WAAW,OAAO,GAAG;AAC/D,aAAO,EAAE,GAAG,kBAAkB,WAAW,MAAM,GAAG,MAAM,GAAG,WAAW,YAAY,OAAO,GAAG,UAAU;AAAA,IACxG;AACA,QAAI,YAAY,eAAe,MAAM,GAAG,YAAY,OAAO,GAAG;AAC5D,aAAO,EAAE,GAAG,kBAAkB,WAAW,MAAM,GAAG,MAAM,GAAG,WAAW,YAAY,OAAO,GAAG,UAAU;AAAA,IACxG;AACA,QAAI,aAAa,MAAM,GAAG,MAAM,GAAG,WAAW,YAAY,OAAO,GAAG;AAClE,aAAO,EAAE,GAAG,OAAO,UAAU;AAAA,IAC/B;AACA,UAAM,QAAQ,YAAY,MAAM,GAAG,MAAM,GAAG,WAAW,YAAY,OAAO;AAC1E,QAAI,QAAQ,WAAW;AACrB,kBAAY;AACZ,aAAO;AACP,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,QAAM,UAAU,kBAAkB,MAAM,UAAU,GAAG,UAAU,GAAG,WAAW,YAAY,OAAO;AAChG,SAAO,EAAE,GAAG,SAAS,WAAW,KAAK;AACvC;AAEO,SAAS,oBAAoB,GAAW,GAAuB;AACpE,SAAO,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,EAAE;AACrE;AAUO,SAAS,4BACd,QACA,WACA,YACA,OACA,UAA8C,CAAC,GACrB;AAC1B,QAAM,MAAM,QAAQ,OAAO;AAC3B,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,EAAE,OAAO,eAAe,QAAQ,eAAe,IAAI,aAAa;AAEtE,MAAI,IAAI,UAAU,QAAQ,OAAO,QAAQ,YAAY,OAAO;AAC5D,MAAI,IAAI,OAAO,SAAS;AAExB,QAAM,aAAa,iBAAiB,UAAU,OAAO,SAAS;AAC9D,QAAM,aAAa,OAAO,MAAM,MAAM;AACtC,MAAI,aAAa,cAAc,aAAa,YAAY;AACtD,QAAI,OAAO,MAAM,MAAM;AAAA,EACzB;AAEA,MAAI,KAAK,IAAI,SAAS,KAAK,IAAI,GAAG,gBAAgB,UAAU,SAAS,CAAC;AACtE,MAAI,KAAK,IAAI,SAAS,KAAK,IAAI,GAAG,iBAAiB,UAAU,UAAU,CAAC;AACxE,SAAO,EAAE,GAAG,EAAE;AAChB;;;AD5GS,SA04BL,UA14BK,KAuHL,YAvHK;AAkqBC;AArqBV,IAAM,qBAAqB,cAAkC,IAAI;AAE1D,SAAS,oBAAoB,EAAE,MAAM,SAAS,GAA+C;AAClG,SAAO,oBAAC,mBAAmB,UAAnB,EAA4B,OAAO,MAAO,UAAS;AAC7D;AACO,SAAS,iBAAiB;AAAE,SAAO,WAAW,kBAAkB;AAAG;AAE1E,SAAS,WAAW,OAAiD;AACnE,SAAO,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AACvC;AAkBO,SAAS,KAAK;AAAA,EACnB,IAAI,YAAY;AAAA,EAChB,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AAAA,EACA,GAAG;AACL,GAAc;AACZ,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,WAAW;AAAA,QACT;AAAA,QACA,YAAY,OAAO;AAAA,QACnB,SAAS,aAAa,YAAY,IAAI;AAAA,QACtC;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAOO,IAAM,UAAU,WAAyC,SAASA,SACvE,EAAE,OAAO,UAAU,OAAO,OAAO,WAAW,GAAG,MAAM,GACrD,KACA;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,WAAW,QAAQ,cAAc,eAAe,IAAI,IAAI,QAAQ,oBAAoB,SAAS;AAAA;AAAA,EAC/F;AAEJ,CAAC;AAyBM,IAAM,OAAO,WAA6D,SAASC,MACxF,EAAE,WAAW,GAAG,MAAM,GACtB,KACA;AACA,SAAO,oBAAC,OAAG,GAAG,OAAO,KAAU,WAAW,QAAQ,WAAW,SAAS,GAAG;AAC3E,CAAC;AAaM,IAAM,SAAS,WAA2C,SAASC,QACxE;AAAA,EACE,UAAU;AAAA,EACV,OAAO;AAAA,EACP,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,GAAG;AACL,GACA,KACA;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA;AAAA,MACA,UAAU,YAAY;AAAA,MACtB,aAAW,WAAW;AAAA,MACtB,WAAW;AAAA,QACT;AAAA,QACA,cAAc,OAAO;AAAA,QACrB,SAAS,aAAa,cAAc,IAAI;AAAA,QACxC;AAAA,MACF;AAAA,MAEC;AAAA,kBAAU,oBAAC,gBAAa,WAAU,8BAA6B,eAAW,MAAC,IAAK;AAAA,QAChF;AAAA,QACA,CAAC,WAAW;AAAA;AAAA;AAAA,EACf;AAEJ,CAAC;AAOM,IAAM,aAAa,WAA+C,SAASC,YAChF,EAAE,OAAO,MAAM,WAAW,GAAG,MAAM,GACnC,KACA;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,cAAY;AAAA,MACZ,OAAO,MAAM,SAAS;AAAA,MACtB,WAAW,QAAQ,mBAAmB,SAAS;AAAA,MAE9C;AAAA;AAAA,EACH;AAEJ,CAAC;AAUM,SAAS,MAAM,EAAE,OAAO,SAAS,MAAM,OAAO,UAAU,WAAW,GAAG,MAAM,GAAe;AAChG,SACE,qBAAC,SAAK,GAAG,OAAO,WAAW,QAAQ,YAAY,SAAS,GACtD;AAAA,wBAAC,WAAM,WAAU,mBAAkB,SAChC,iBACH;AAAA,IACC;AAAA,KACC,SAAS,SACT,oBAAC,OAAE,WAAW,QAAQ,kBAAkB,QAAQ,KAAK,KAAK,iBAAiB,GAAG,MAAM,QAAQ,UAAU,QACnG,mBAAS,MACZ;AAAA,KAEJ;AAEJ;AAEO,IAAM,YAAY;AAAA,EACvB,SAASC,WAAU,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AAC/C,WAAO,oBAAC,WAAO,GAAG,OAAO,KAAU,WAAW,QAAQ,YAAY,SAAS,GAAG;AAAA,EAChF;AACF;AAEO,IAAM,SAAS;AAAA,EACpB,SAASC,QAAO,EAAE,WAAW,UAAU,GAAG,MAAM,GAAG,KAAK;AACtD,WACE,oBAAC,YAAQ,GAAG,OAAO,KAAU,WAAW,QAAQ,YAAY,SAAS,GAClE,UACH;AAAA,EAEJ;AACF;AAEO,IAAM,WAAW;AAAA,EACtB,SAASC,UAAS,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AAC9C,WAAO,oBAAC,cAAU,GAAG,OAAO,KAAU,WAAW,QAAQ,YAAY,SAAS,GAAG;AAAA,EACnF;AACF;AAQA,SAAS,WAAW,EAAE,OAAO,aAAa,UAAU,GAAoB;AACtE,SACE,qBAAC,UAAK,WAAU,mBACd;AAAA,wBAAC,UAAK,WAAW,QAAQ,oBAAoB,aAAa,oBAAoB,GAAI,iBAAM;AAAA,IACvF,cACC,oBAAC,UAAK,WAAW,QAAQ,0BAA0B,aAAa,oBAAoB,GAAI,uBAAY,IAClG;AAAA,KACN;AAEJ;AAOO,IAAM,WAAW,WAA4C,SAASC,UAC3E,EAAE,OAAO,aAAa,WAAW,WAAW,eAAe,GAAG,MAAM,GACpE,KACA;AACA,QAAM,WAAW,OAAyB,IAAI;AAC9C,sBAAoB,KAAK,MAAM,SAAS,OAA2B;AAEnE,YAAU,MAAM;AACd,QAAI,SAAS,QAAS,UAAS,QAAQ,gBAAgB,QAAQ,aAAa;AAAA,EAC9E,GAAG,CAAC,aAAa,CAAC;AAElB,SACE,qBAAC,WAAM,WAAW,QAAQ,aAAa,uBAAuB,SAAS,GACrE;AAAA,wBAAC,WAAO,GAAG,OAAO,KAAK,UAAU,MAAK,YAAW;AAAA,IACjD,oBAAC,cAAW,OAAc,aAA2B,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU,GAAI;AAAA,KAC1G;AAEJ,CAAC;AA0FM,IAAM,QAAQ,WAAyC,SAASC,OACrE,EAAE,OAAO,aAAa,WAAW,WAAW,GAAG,MAAM,GACrD,KACA;AACA,SACE,qBAAC,WAAM,WAAW,QAAQ,aAAa,oBAAoB,SAAS,GAClE;AAAA,wBAAC,WAAO,GAAG,OAAO,KAAU,MAAK,SAAQ;AAAA,IACzC,oBAAC,cAAW,OAAc,aAA2B,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU,GAAI;AAAA,KAC1G;AAEJ,CAAC;AAqEM,IAAM,aAAa;AAAA,EACxB,SAASC,YAAW,EAAE,WAAW,MAAM,GAAG,MAAM,GAAG,KAAK;AACtD,WAAO,oBAAC,WAAO,GAAG,OAAO,KAAU,MAAM,QAAQ,SAAS,WAAW,QAAQ,YAAY,SAAS,GAAG;AAAA,EACvG;AACF;AAWO,IAAM,SAAS,WAA2C,SAASC,QACxE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GACA,KACA;AACA,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAS,QAAQ,cAAc,CAAC;AAC9E,QAAM,YAAY,WAAW;AAE7B,QAAM,cAAc,CAAC,UAAyC;AAC5D,cAAU,KAAK;AACf,QAAI,MAAM,oBAAoB,SAAU;AACxC,UAAM,OAAO,CAAC;AACd,QAAI,YAAY,OAAW,oBAAmB,IAAI;AAClD,sBAAkB,IAAI;AAAA,EACxB;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,MAAK;AAAA,MACL,MAAK;AAAA,MACL,gBAAc;AAAA,MACd;AAAA,MACA,WAAW,QAAQ,aAAa,WAAW,SAAS,kBAAkB,SAAS;AAAA,MAC/E,SAAS;AAAA,MAER;AAAA,gBACC,oBAAC,UAAK,WAAW,QAAQ,oBAAoB,aAAa,oBAAoB,GAAI,iBAAM,IACtF;AAAA,QACJ,oBAAC,UAAK,WAAU,oBAAmB,eAAY,QAC7C,8BAAC,UAAK,WAAU,oBAAmB,GACrC;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAEM,SAAS,QAAQ,EAAE,QAAQ,4BAAQ,UAAU,GAA2C;AAC7F,SAAO,oBAAC,UAAK,WAAW,QAAQ,cAAc,SAAS,GAAG,MAAK,UAAS,cAAY,OAAO;AAC7F;AAIA,IAAM,cAA8C;AAAA,EAClD,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AACR;AASO,SAAS,OAAO;AAAA,EACrB;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAgB;AACd,QAAM,OAAO,YAAY,IAAI;AAC7B,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,WAAW,QAAQ,aAAa,cAAc,IAAI,IAAI,QAAQ,mBAAmB,SAAS;AAAA,MAEzF;AAAA,mBAAY,QAAQ,oBAAC,QAAK,WAAU,WAAU,eAAW,MAAC,IAAM;AAAA,QAChE;AAAA;AAAA;AAAA,EACH;AAEJ;AAwCO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,SACE,qBAAC,SAAK,GAAG,OAAO,WAAW,QAAQ,YAAY,SAAS,GACrD;AAAA;AAAA,IACD,oBAAC,QAAK,IAAG,UAAS,SAAQ,WAAW,iBAAM;AAAA,IAC3C,oBAAC,OAAG,uBAAY;AAAA,IACf;AAAA,KACH;AAEJ;AAEO,SAAS,aAAa;AAAA,EAC3B,QAAQ;AAAA,EACR;AACF,GAGG;AACD,SACE,qBAAC,SAAI,WAAU,YAAW,MAAK,UAAS,aAAU,UAChD;AAAA,wBAAC,WAAQ,OAAO,OAAO,UAAU,WAAW,QAAQ,4BAAQ;AAAA,IAC5D,oBAAC,QAAK,IAAG,UAAS,SAAQ,WAAW,iBAAM;AAAA,IAC1C,eAAe,oBAAC,OAAG,uBAAY;AAAA,KAClC;AAEJ;AAQO,SAAS,YAAY,EAAE,OAAO,QAAQ,KAAK,WAAW,GAAG,MAAM,GAAqB;AACzF,SACE,qBAAC,YAAQ,GAAG,OAAO,WAAW,QAAQ,mBAAmB,SAAS,GAChE;AAAA,wBAAC,SAAI,WAAU,yBAAyB,iBAAM;AAAA,IAC9C,oBAAC,SAAI,WAAU,yBAAyB,kBAAO;AAAA,IAC/C,oBAAC,SAAI,WAAU,yBAAyB,eAAI;AAAA,KAC9C;AAEJ;AAEO,SAAS,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAmC;AAC/E,SAAO,oBAAC,SAAK,GAAG,OAAO,MAAM,MAAM,QAAQ,WAAW,WAAW,QAAQ,cAAc,SAAS,GAAG;AACrG;AAOO,IAAM,cAAc,WAA+C,SAASC,aACjF,EAAE,QAAQ,gBAAM,SAAS,OAAO,WAAW,GAAG,MAAM,GACpD,KACA;AACA,QAAM,WAAW,SAAS,QAAQ,OAAO,KAAK,EAAE,SAAS;AACzD,SACE,qBAAC,SAAI,WAAW,QAAQ,aAAa,SAAS,GAC5C;AAAA,wBAAC,UAAO,WAAU,8BAA6B,eAAW,MAAC;AAAA,IAC3D,oBAAC,aAAW,GAAG,OAAO,KAAU,MAAK,UAAS,OAAc,cAAY,OAAO;AAAA,IAC9E,YAAY,WACX;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAM;AAAA,QACN,MAAM,oBAAC,KAAE,WAAU,WAAU;AAAA,QAC7B,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,SAAS;AAAA;AAAA,IACX;AAAA,KAEJ;AAEJ,CAAC;AAkBM,SAAS,KAAK;AAAA,EACnB;AAAA,EACA,QAAQ;AAAA,EACR;AACF,GAIG;AACD,SACE,oBAAC,SAAI,WAAW,QAAQ,WAAW,SAAS,GAAG,MAAK,QAAO,cAAY,OACpE,gBAAM,IAAI,CAAC,MAAM,UAAU;AAC1B,QAAI,KAAK,SAAS,aAAa;AAC7B,aAAO,oBAAC,SAAI,WAAU,sBAAqB,MAAK,eAAiB,aAAa,KAAK,EAAI;AAAA,IACzF;AACA,QAAI,KAAK,SAAS,SAAS;AACzB,aAAO,oBAAC,SAAI,WAAU,kBAAyC,eAAK,SAAxB,SAAS,KAAK,EAAgB;AAAA,IAC5E;AACA,UAAM,EAAE,WAAW,eAAe,GAAG,YAAY,IAAI,KAAK,eAAe,CAAC;AAC1E,WACE;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,MAAK;AAAA,QACL,MAAK;AAAA,QACL,KAAK,KAAK;AAAA,QACV,UAAU,KAAK;AAAA,QACf,iBAAe,KAAK,YAAY;AAAA,QAChC,WAAW;AAAA,UACT;AAAA,UACA,KAAK,YAAY;AAAA,UACjB,KAAK,UAAU;AAAA,UACf;AAAA,QACF;AAAA,QACA,SAAS,KAAK;AAAA;AAAA,MAEd,oBAAC,UAAK,WAAU,oBAAmB,eAAW,MAC3C,eAAK,WAAW,oBAAC,SAAM,WAAU,WAAU,IAAK,KAAK,MACxD;AAAA,MACA,oBAAC,UAAK,WAAU,kBAAkB,eAAK,OAAM;AAAA,MAC5C,KAAK,YAAY,oBAAC,SAAI,WAAU,qBAAqB,eAAK,UAAS;AAAA,IACtE;AAAA,EAEJ,CAAC,GACH;AAEJ;AAaO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,cAAc,eAAe;AACnC,QAAM,UAAU,OAAuB,IAAI;AAC3C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AACvD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAE5C,QAAM,iBAAiB,YAAY,MAAM;AACvC,QAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,QAAS;AAC9C,UAAM,EAAE,OAAO,OAAO,IAAI,QAAQ,QAAQ,sBAAsB;AAChE,UAAM,WAAW,4BAA4B,YAAY,OAAO,QAAQ,EAAE,IAAI,CAAC;AAC/E,gBAAY,EAAE,GAAG,SAAS,GAAG,GAAG,SAAS,EAAE,CAAC;AAC5C,eAAW,IAAI;AAAA,EACjB,GAAG,CAAC,YAAY,KAAK,IAAI,CAAC;AAE1B,kBAAgB,MAAM;AACpB,QAAI,CAAC,MAAM;AACT,iBAAW,KAAK;AAChB;AAAA,IACF;AACA,eAAW,KAAK;AAChB,mBAAe;AACf,WAAO,iBAAiB,UAAU,cAAc;AAChD,WAAO,iBAAiB,UAAU,gBAAgB,IAAI;AACtD,WAAO,MAAM;AACX,aAAO,oBAAoB,UAAU,cAAc;AACnD,aAAO,oBAAoB,UAAU,gBAAgB,IAAI;AAAA,IAC3D;AAAA,EACF,GAAG,CAAC,MAAM,gBAAgB,QAAQ,CAAC;AAEnC,YAAU,MAAM;AACd,QAAI,CAAC,QAAQ,CAAC,QAAS;AACvB,UAAM,QAAQ,CAAC,UAAwB;AACrC,YAAM,SAAS,MAAM;AACrB,UAAI,QAAQ,SAAS,SAAS,MAAM,EAAG;AACvC,UAAI,qBAAqB,KAAK,CAAC,QAAQ,IAAI,SAAS,SAAS,MAAM,CAAC,EAAG;AACvE,cAAQ;AAAA,IACV;AACA,UAAM,SAAS,CAAC,UAAyB;AACvC,UAAI,MAAM,QAAQ,SAAU,SAAQ;AAAA,IACtC;AACA,WAAO,iBAAiB,eAAe,KAAK;AAC5C,WAAO,iBAAiB,WAAW,MAAM;AACzC,WAAO,MAAM;AACX,aAAO,oBAAoB,eAAe,KAAK;AAC/C,aAAO,oBAAoB,WAAW,MAAM;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,qBAAqB,SAAS,IAAI,CAAC;AAEvC,MAAI,CAAC,QAAQ,CAAC,cAAc,OAAO,aAAa,YAAa,QAAO;AACpE,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,OAAO;AAAA,IACP;AAAA,IACA,GAAG;AAAA,EACL,IAAI,kBAAkB,CAAC;AACvB,SAAO;AAAA,IACL;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,KAAK;AAAA,QACL,WAAW,QAAQ,oBAAoB,SAAS,WAAW,kBAAkB;AAAA,QAC7E,OAAO;AAAA,UACL,GAAG;AAAA,UACH,MAAM,SAAS;AAAA,UACf,KAAK,SAAS;AAAA,UACd,YAAY,UAAU,YAAY;AAAA,QACpC;AAAA,QACA,eAAe,CAAC,UAAU;AACxB,gBAAM,gBAAgB;AACtB,0BAAgB,KAAK;AAAA,QACvB;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,IACA,eAAe,SAAS;AAAA,EAC1B;AACF;AA0BO,SAAS,aAAa,EAAE,QAAQ,gBAAM,OAAO,QAAQ,OAAO,WAAW,QAAQ,GAAsB;AAC1G,QAAM,cAAc,eAAe;AACnC,QAAM,YAAY,OAAwB,IAAI;AAC9C,QAAM,UAAU,OAAuB,IAAI;AAC3C,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AACvD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAE5C,QAAM,YAAY;AAAA,IAChB,MACE,MAAM;AAAA,MAAI,CAAC,SACT,KAAK,SAAS,UAAa,KAAK,SAAS,SACrC;AAAA,QACE,GAAG;AAAA,QACH,UAAU,MAAM;AACd,eAAK,WAAW;AAChB,kBAAQ,KAAK;AAAA,QACf;AAAA,MACF,IACA;AAAA,IACN;AAAA,IACF,CAAC,KAAK;AAAA,EACR;AAEA,QAAM,iBAAiB,YAAY,MAAM;AACvC,QAAI,CAAC,QAAQ,CAAC,UAAU,WAAW,CAAC,QAAQ,QAAS;AACrD,UAAM,SAAS,UAAU,QAAQ,sBAAsB;AACvD,UAAM,EAAE,OAAO,OAAO,IAAI,QAAQ,QAAQ,sBAAsB;AAChE,QAAI,SAAS,KAAK,UAAU,EAAG;AAC/B,UAAM,WAAW,4BAA4B,QAAQ,OAAO,QAAQ,OAAO,EAAE,KAAK,EAAE,CAAC;AACrF,gBAAY,QAAQ;AACpB,eAAW,IAAI;AAAA,EACjB,GAAG,CAAC,OAAO,IAAI,CAAC;AAEhB,kBAAgB,MAAM;AACpB,QAAI,CAAC,MAAM;AACT,iBAAW,KAAK;AAChB;AAAA,IACF;AACA,eAAW,KAAK;AAChB,mBAAe;AACf,UAAM,SAAS,QAAQ;AACvB,UAAM,WAAW,SAAS,IAAI,eAAe,MAAM,eAAe,CAAC,IAAI;AACvE,QAAI,UAAU,SAAU,UAAS,QAAQ,MAAM;AAC/C,UAAM,WAAW,MAAM,eAAe;AACtC,WAAO,iBAAiB,UAAU,QAAQ;AAC1C,WAAO,iBAAiB,UAAU,UAAU,IAAI;AAChD,WAAO,MAAM;AACX,gBAAU,WAAW;AACrB,aAAO,oBAAoB,UAAU,QAAQ;AAC7C,aAAO,oBAAoB,UAAU,UAAU,IAAI;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,MAAM,gBAAgB,SAAS,CAAC;AAEpC,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AACX,UAAM,QAAQ,CAAC,UAAwB;AACrC,YAAM,SAAS,MAAM;AACrB,UAAI,UAAU,SAAS,SAAS,MAAM,EAAG;AACzC,UAAI,QAAQ,SAAS,SAAS,MAAM,EAAG;AACvC,cAAQ,KAAK;AAAA,IACf;AACA,UAAM,QAAQ,CAAC,UAAyB;AACtC,UAAI,MAAM,QAAQ,SAAU,SAAQ,KAAK;AAAA,IAC3C;AACA,WAAO,iBAAiB,eAAe,KAAK;AAC5C,WAAO,iBAAiB,WAAW,KAAK;AACxC,WAAO,MAAM;AACX,aAAO,oBAAoB,eAAe,KAAK;AAC/C,aAAO,oBAAoB,WAAW,KAAK;AAAA,IAC7C;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,QAAM,iBAAiB,aAAa,SAAS;AAAA,IAC3C,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,SAAS,CAAC,UAAyC;AACjD,cAAQ,MAAM,UAAU,KAAK;AAC7B,UAAI,MAAM,iBAAkB;AAC5B,cAAQ,CAAC,YAAY,CAAC,OAAO;AAAA,IAC/B;AAAA,EACF,CAAC;AAED,SACE,iCACE;AAAA,wBAAC,UAAK,WAAU,4BAA2B,KAAK,WAC7C,0BACH;AAAA,IACC,QACC,OAAO,aAAa,eACpB;AAAA,MACE;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,WAAW,QAAQ,oBAAoB,SAAS,SAAS;AAAA,UACzD,OAAO;AAAA,YACL,MAAM,SAAS;AAAA,YACf,KAAK,SAAS;AAAA,YACd,YAAY,UAAU,YAAY;AAAA,UACpC;AAAA,UACA,eAAe,CAAC,UAAU,MAAM,gBAAgB;AAAA,UAEhD,8BAAC,QAAK,OAAc,OAAO,WAAW;AAAA;AAAA,MACxC;AAAA,MACA,eAAe,SAAS;AAAA,IAC1B;AAAA,KACJ;AAEJ;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,cAAc,eAAe;AACnC,YAAU,MAAM;AACd,QAAI,CAAC,QAAQ,WAAY;AACzB,UAAM,QAAQ,MAAM,QAAQ;AAC5B,UAAM,SAAS,CAAC,UAAyB;AACvC,UAAI,MAAM,QAAQ,SAAU,SAAQ;AAAA,IACtC;AACA,WAAO,iBAAiB,eAAe,KAAK;AAC5C,WAAO,iBAAiB,WAAW,MAAM;AACzC,WAAO,MAAM;AACX,aAAO,oBAAoB,eAAe,KAAK;AAC/C,aAAO,oBAAoB,WAAW,MAAM;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,YAAY,SAAS,IAAI,CAAC;AAE9B,MAAI,YAAY;AACd,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACC,GAAI,mBAAmB,SAAY,CAAC,IAAI,EAAE,eAAe;AAAA,QAE1D;AAAA,UAAC;AAAA;AAAA,YACE,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,MAAM;AAAA,YACxC,OAAO,MAAM;AAAA,cAAI,CAAC,SAChB,KAAK,SAAS,UAAa,KAAK,SAAS,SACrC,EAAE,GAAG,MAAM,UAAU,MAAM;AAAE,qBAAK,WAAW;AAAG,wBAAQ;AAAA,cAAG,EAAE,IAC7D;AAAA,YACN;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,CAAC,QAAQ,OAAO,aAAa,YAAa,QAAO;AACrD,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,OAAO;AAAA,IACP;AAAA,IACA,GAAG;AAAA,EACL,IAAI,kBAAkB,CAAC;AACvB,SAAO;AAAA,IACL;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,WAAW,QAAQ,oBAAoB,SAAS,kBAAkB;AAAA,QAClE,OAAO,EAAE,GAAG,gBAAgB,MAAM,GAAG,KAAK,EAAE;AAAA,QAC5C,eAAe,CAAC,UAAU;AACxB,gBAAM,gBAAgB;AACtB,0BAAgB,KAAK;AAAA,QACvB;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,MAAM;AAAA,cAAI,CAAC,SAChB,KAAK,SAAS,UAAa,KAAK,SAAS,SACrC,EAAE,GAAG,MAAM,UAAU,MAAM;AAAE,qBAAK,WAAW;AAAG,wBAAQ;AAAA,cAAG,EAAE,IAC7D;AAAA,YACN;AAAA,YACC,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,MAAM;AAAA;AAAA,QAC1C;AAAA;AAAA,IACF;AAAA,IACA,eAAe,SAAS;AAAA,EAC1B;AACF;AAkBO,SAAS,OAAO;AAAA,EACrB;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,aAAa;AACf,GAAgB;AACd,QAAM,MAAM,OAA0B,IAAI;AAC1C,QAAM,iBAAiB,OAA2B,IAAI;AACtD,QAAM,UAAU,MAAM;AAEtB,YAAU,MAAM;AACd,UAAM,SAAS,IAAI;AACnB,QAAI,CAAC,OAAQ;AACb,QAAI,QAAQ,CAAC,OAAO,MAAM;AACxB,qBAAe,UAAU,SAAS,yBAAyB,cACvD,SAAS,gBACT;AACJ,UAAI,MAAO,QAAO,UAAU;AAAA,UACvB,QAAO,KAAK;AACjB,4BAAsB,MAAM,iBAAiB,SAAS,MAAM,CAAC;AAAA,IAC/D;AACA,QAAI,CAAC,QAAQ,OAAO,MAAM;AACxB,aAAO,MAAM;AACb,qBAAe,SAAS,MAAM;AAAA,IAChC;AAAA,EACF,GAAG,CAAC,iBAAiB,OAAO,IAAI,CAAC;AAEjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW,QAAQ,aAAa,SAAS,SAAS;AAAA,MAClD,mBAAiB;AAAA,MACjB,oBAAkB,cAAc,SAAS;AAAA,MACzC,UAAU,cAAc,iBAAiB;AAAA,MACzC,UAAU,CAAC,UAAU;AACnB,cAAM,eAAe;AACrB,YAAI,YAAa,WAAU;AAAA,MAC7B;AAAA,MACA,SAAS,MAAM;AACb,YAAI,aAAa;AACf,oBAAU;AACV;AAAA,QACF;AACA,8BAAsB,MAAM;AAC1B,gBAAM,SAAS,IAAI;AACnB,cAAI,QAAQ,UAAU,CAAC,OAAO,MAAM;AAClC,gBAAI,MAAO,QAAO,UAAU;AAAA,gBACvB,QAAO,KAAK;AACjB,6BAAiB,SAAS,MAAM;AAAA,UAClC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA;AAAA,6BAAC,SAAI,WAAU,qBACb;AAAA,8BAAC,QAAK,IAAG,MAAK,IAAI,SAAS,SAAQ,WAAW,iBAAM;AAAA,UACnD,cACC,oBAAC,cAAW,OAAO,YAAY,MAAM,oBAAC,KAAE,WAAU,WAAU,GAAI,SAAQ,SAAQ,SAAS,SAAS,IAChG;AAAA,WACN;AAAA,QACA,oBAAC,SAAI,WAAU,mBAAmB,UAAS;AAAA,QAC1C,UAAU,oBAAC,SAAI,WAAU,qBAAqB,kBAAO;AAAA;AAAA;AAAA,EACxD;AAEJ;AAkBA,SAAS,YAAY,EAAE,OAAO,aAAa,QAAQ,GAA4D;AAC7G,MAAI,SAAS,QAAQ,eAAe,MAAM;AACxC,WACE,qBAAC,SAAI,WAAU,uBACZ;AAAA,eAAS,QAAQ,oBAAC,SAAI,WAAU,qBAAqB,iBAAM;AAAA,MAC3D,eAAe,QAAQ,oBAAC,SAAI,WAAU,2BAA2B,uBAAY;AAAA,OAChF;AAAA,EAEJ;AACA,SAAO,oBAAC,SAAI,WAAU,uBAAuB,mBAAQ;AACvD;AAEA,IAAM,0BAA0B;AAChC,IAAM,qBAAqB;AAE3B,SAAS,qBACP,QACA,KACA,WACuD;AACvD,MAAI,IAAI,OAAO,OAAO,OAAO,QAAQ;AACrC,QAAM,OAAO,IAAI,QAAQ;AACzB,QAAM,OAAO,0BAA0B;AACvC,QAAM,OAAO,OAAO,aAAa,0BAA0B;AAC3D,MAAI,KAAK,IAAI,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI;AAEpC,MAAI,WAAW;AACf,MAAI,IACF,cAAc,QACV,OAAO,MAAM,qBACb,OAAO,SAAS;AAEtB,MAAI,cAAc,UAAU;AAC1B,QAAI,IAAI,IAAI,SAAS,OAAO,cAAc,yBAAyB;AACjE,iBAAW;AACX,UAAI,OAAO,MAAM;AAAA,IACnB;AAAA,EACF,WAAW,IAAI,IAAI,SAAS,yBAAyB;AACnD,eAAW;AACX,QAAI,OAAO,SAAS;AAAA,EACtB;AAEA,SAAO,EAAE,GAAG,GAAG,WAAW,SAAS;AACrC;AAEO,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,OAAO;AACT,GAAiB;AACf,QAAM,cAAc,eAAe;AACnC,QAAM,YAAY,OAAwB,IAAI;AAC9C,QAAM,aAAa,OAAwB,IAAI;AAC/C,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AACtD,QAAM,UAAU,QAAQ;AACxB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AACnD,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAS,SAAS;AACpE,QAAM,QAAQ,OAA6C,IAAI;AAE/D,QAAM,eAAe,YAAY,MAAM;AACrC,UAAM,SAAS,UAAU,SAAS,sBAAsB;AACxD,QAAI,CAAC,OAAQ;AACb,UAAM,MAAM,WAAW,SAAS,sBAAsB;AACtD,QAAI,OAAO,IAAI,QAAQ,GAAG;AACxB,YAAM,OAAO,qBAAqB,QAAQ,KAAK,SAAS;AACxD,gBAAU,EAAE,GAAG,KAAK,GAAG,GAAG,KAAK,EAAE,CAAC;AAClC,2BAAqB,KAAK,SAAS;AACnC;AAAA,IACF;AACA,cAAU;AAAA,MACR,GAAG,OAAO,OAAO,OAAO,QAAQ;AAAA,MAChC,GAAG,cAAc,QAAQ,OAAO,MAAM,qBAAqB,OAAO,SAAS;AAAA,IAC7E,CAAC;AACD,yBAAqB,SAAS;AAAA,EAChC,GAAG,CAAC,SAAS,CAAC;AAEd,kBAAgB,MAAM;AACpB,QAAI,CAAC,QAAS;AACd,iBAAa;AACb,QAAI,CAAC,SAAU;AACf,UAAM,WAAW,MAAM,aAAa;AACpC,WAAO,iBAAiB,UAAU,QAAQ;AAC1C,WAAO,iBAAiB,UAAU,UAAU,IAAI;AAChD,WAAO,MAAM;AACX,aAAO,oBAAoB,UAAU,QAAQ;AAC7C,aAAO,oBAAoB,UAAU,UAAU,IAAI;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,UAAU,cAAc,OAAO,CAAC;AAEpC,QAAM,OAAO,MAAM;AACjB,QAAI,KAAM;AACV,UAAM,UAAU,WAAW,MAAM;AAC/B,sBAAgB,IAAI;AAAA,IACtB,GAAG,GAAG;AAAA,EACR;AACA,QAAM,OAAO,MAAM;AACjB,QAAI,KAAM;AACV,QAAI,MAAM,QAAS,cAAa,MAAM,OAAO;AAC7C,oBAAgB,KAAK;AACrB,yBAAqB,SAAS;AAAA,EAChC;AAEA,QAAM,qBAAqB,WAAW,oBAAoB;AAE1D,QAAM,eAAe,WACjB;AAAA,IACE,MAAM,OAAO;AAAA,IACb,KAAK,OAAO;AAAA,IACZ,WACE,uBAAuB,QACnB,2BACA;AAAA,EACR,IACA;AAEJ,QAAM,UAAU,UACd;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAW;AAAA,QACT;AAAA,QACA,uBAAuB,WAAW,uBAAuB;AAAA,QACzD,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,MACA,OAAO;AAAA,MACP,MAAK;AAAA,MAEL,8BAAC,eAAY,OAAc,aAA0B,SAAkB;AAAA;AAAA,EACzE,IACE;AAEJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAU;AAAA,MACV,cAAc;AAAA,MACd,cAAc;AAAA,MACd,SAAS;AAAA,MACT,QAAQ;AAAA,MAEP;AAAA;AAAA,QACA,YAAY,OAAO,aAAa,cAC7B,WAAW,aAAa,SAAS,eAAe,SAAS,IAAI,IAC7D;AAAA;AAAA;AAAA,EACN;AAEJ;AAgBA,IAAM,eAAe,cAAwC,IAAI;AAuJ1D,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SACE,qBAAC,SAAI,WAAW,QAAQ,mBAAmB,SAAS,GAClD;AAAA,wBAAC,UAAK,WAAU,0BAA0B,iBAAM;AAAA,IAChD,oBAAC,UAAK,WAAU,4BAA4B,UAAS;AAAA,KACvD;AAEJ;AAEO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAQG;AACD,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,WAAW;AAC5D,QAAM,WAAW,QAAQ;AACzB,QAAM,YAAY,MAAM;AACxB,QAAM,SAAS,MAAM;AACnB,UAAM,OAAO,CAAC;AACd,QAAI,SAAS,OAAW,iBAAgB,IAAI;AAC5C,mBAAe,IAAI;AAAA,EACrB;AACA,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,SAAS;AAAA,IACT,GAAG;AAAA,EACL,IAAI,gBAAgB,CAAC;AACrB,SACE,qBAAC,aAAS,GAAG,OAAO,WAAW,QAAQ,kBAAkB,SAAS,GAChE;AAAA,yBAAC,SAAI,WAAU,2BACf;AAAA;AAAA,QAAC;AAAA;AAAA,UACE,GAAG;AAAA,UACJ,MAAK;AAAA,UACL,WAAW,QAAQ,2BAA2B,gBAAgB;AAAA,UAC9D,iBAAe;AAAA,UACf,iBAAe;AAAA,UACf,SAAS,CAAC,UAAU;AAClB,6BAAiB,KAAK;AACtB,gBAAI,CAAC,MAAM,iBAAkB,QAAO;AAAA,UACtC;AAAA,UAEC;AAAA,uBAAW,oBAAC,eAAY,WAAU,WAAU,IAAK,oBAAC,gBAAa,WAAU,WAAU;AAAA,YACpF,oBAAC,UAAK,WAAU,yBAAyB,iBAAM;AAAA;AAAA;AAAA,MACjD;AAAA,MACC,YAAY,oBAAC,SAAI,WAAU,2BAA2B,oBAAS;AAAA,OAChE;AAAA,IACC,YAAY,oBAAC,SAAI,WAAU,2BAA0B,IAAI,WAAY,UAAS;AAAA,KACjF;AAEJ;;;AE3gDA;AAAA,EACE,iBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,OAGK;;;ACTA,IAAM,aAAa,CAAC,SAAS,MAAM;AAcnC,IAAM,cAAc;AAAA,EACzB,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,WAAW;AAAA,IACX,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,WAAW;AAAA,EACb;AAAA,EACA,QAAQ;AAAA,IACN,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,IACrB,qBAAqB;AAAA,IACrB,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,EACpB;AAAA,EACA,WAAW;AAAA,IACT,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,WAAW;AAAA,EACb;AAAA,EACA,OAAO;AAAA,IACL,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ;AAAA,IACN,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,EAClB;AAAA,EACA,OAAO;AAAA,EACP,iBAAiB;AACnB;AAEO,IAAM,gBAAgB,YAAY;;;ADuBjC,gBAAAC,YAAA;AAvFR,IAAM,oBAAoB;AAQ1B,IAAM,eAAeC,eAAwC,IAAI;AAa1D,SAAS,YAAY,OAAoC;AAC9D,SAAO,OAAO,UAAU,YAAY,WAAW,SAAS,KAAkB;AAC5E;AAEO,SAAS,eAAe,WAAsB,SAAoB;AACvE,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,SAAS,OAAO,aAAa,QAAQ,iBAAiB;AAC5D,SAAO,YAAY,MAAM,IAAI,SAAS;AACxC;AAEO,SAAS,WAAW,OAAkB,QAAsB;AACjE,QAAM,UAAU,WAAW,OAAO,aAAa,cAAc,SAAY,SAAS;AAClF,MAAI,QAAS,SAAQ,QAAQ,QAAQ;AACvC;AAEO,SAAS,gBAAgB,WAAsB,SAAS;AAC7D,QAAM,QAAQ,eAAe,QAAQ;AACrC,aAAW,KAAK;AAChB,SAAO;AACT;AAEO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,eAAe;AAAA,EACf,OAAO;AAAA,EACP;AAAA,EACA,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX;AAAA,EACA,GAAG;AACL,GAAuB;AACrB,QAAM,CAAC,eAAe,gBAAgB,IAAIC;AAAA,IAAoB,MAC5D,UAAU,eAAe,YAAY,IAAI;AAAA,EAC3C;AACA,QAAM,QAAQ,mBAAmB;AAEjC,QAAM,WAAWC;AAAA,IACf,CAAC,cAAyB;AACxB,UAAI,CAAC,gBAAiB,kBAAiB,SAAS;AAChD,UAAI,WAAW,OAAO,WAAW,aAAa;AAC5C,eAAO,aAAa,QAAQ,mBAAmB,SAAS;AAAA,MAC1D;AACA,sBAAgB,SAAS;AAAA,IAC3B;AAAA,IACA,CAAC,iBAAiB,eAAe,OAAO;AAAA,EAC1C;AAEA,EAAAC,WAAU,MAAM;AACd,QAAI,gBAAiB,YAAW,KAAK;AAAA,EACvC,GAAG,CAAC,iBAAiB,KAAK,CAAC;AAE3B,QAAM,QAAQC;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,aAAa,MAAM,SAAS,UAAU,UAAU,SAAS,OAAO;AAAA,IAClE;AAAA,IACA,CAAC,UAAU,KAAK;AAAA,EAClB;AAEA,SACE,gBAAAL,KAAC,aAAa,UAAb,EAAsB,OACpB,qBACC,WAEA,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,WAAW,CAAC,SAAS,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MACxD,cAAY,kBAAkB,SAAY;AAAA,MAEzC;AAAA;AAAA,EACH,GAEJ;AAEJ;AAEO,SAAS,WAAW;AACzB,QAAM,UAAUM,YAAW,YAAY;AACvC,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,4CAA4C;AAC1E,SAAO;AACT;;;AEpHA,SAAS,4BAA4B;AAOrC,SAAS,cAAc,QAA2C;AAChE,QAAM,YAAY,QAAQ;AAC1B,SAAO,QAAQ,aAAa,OAAO,UAAU,YAAY,cAAc,UAAU,cAAc,KAAK;AACtG;AAEO,SAAS,4BAA4B,QAA2C;AACrF,SAAO;AAAA,IACL,CAAC,aAAa,QAAQ,eAAe,QAAQ,MAAM,MAAM;AAAA,IAAC;AAAA,IAC1D,MAAM,cAAc,MAAM;AAAA,IAC1B,MAAM,cAAc,MAAM;AAAA,EAC5B;AACF;;;AChBO,SAAS,0BAA0B,KAA8B;AACtE,MAAI,OAAO,KAAM,QAAO;AACxB,QAAM,OAAO,OAAO,GAAG;AACvB,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,KACJ,QAAQ,sBAAsB,OAAO,EACrC,QAAQ,yBAAyB,OAAO,EACxC,MAAM,SAAS,EACf,OAAO,OAAO,EACd,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACxE,KAAK,GAAG;AACb;AAGA,SAAS,kBAAkB,OAAiC;AAC1D,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO;AAClC,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,CAAC,MAAM,MAAM,CAAC,UAAU,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,CAAC,EAAG,QAAO;AACzF,SAAO;AACT;AAGA,SAAS,eAAe,QAAiB;AACvC,MAAI,OAAO,WAAW,SAAU,QAAO,OAAO,YAAY;AAC1D,MAAI,UAAU,OAAO,WAAW,YAAY,UAAU,UAAU,OAAO,OAAO,SAAS,SAAU,QAAO,OAAO,KAAK,YAAY;AAChI,SAAO;AACT;AAEA,IAAM,YAAY;AAGlB,SAAS,iBAAiB,OAAgB;AACxC,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO;AACxE,QAAM,SAAU;AAChB,QAAM,WAAW,OAAO,QAAQ,OAAO;AACvC,MAAI,OAAO,aAAa,YAAY,SAAS,KAAK,MAAM,GAAI,QAAO;AACnE,SAAO,OAAO,OAAO,MAAM,EAAE,MAAM,CAAC,UAAU,SAAS,QAAQ,OAAO,UAAU,QAAQ;AAC1F;AAOO,SAAS,0BAA0B,QAAiB,OAAwC;AACjG,QAAM,OAAO,eAAe,MAAM;AAElC,MAAI,OAAO,UAAU,aAAa,KAAK,SAAS,MAAM,EAAG,QAAO;AAChE,MAAI,OAAO,UAAU,YAAY,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,UAAU;AAC1H,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,kBAAkB,KAAK;AACrC,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,MAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,MAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAC/D,UAAM,SAAU;AAChB,QAAI,OAAO,OAAO,MAAM,YAAY,OAAO,OAAO,MAAM,YAAY,OAAO,OAAO,MAAM,UAAU;AAChG,aAAO,OAAO,OAAO,MAAM,WAAW,YAAY;AAAA,IACpD;AAAA,EACF;AAEA,MAAI,KAAK,SAAS,MAAM,KAAM,UAAU,OAAO,WAAW,YAAY,MAAM,QAAS,OAAmC,IAAI,GAAI;AAC9H,WAAO;AAAA,EACT;AACA,MAAI,KAAK,SAAS,OAAO,KAAM,OAAO,UAAU,YAAY,UAAU,KAAK,KAAK,EAAI,QAAO;AAC3F,MAAI,KAAK,SAAS,OAAO,KAAK,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,KAAK,KAAK,iBAAiB,KAAK,EAAG,QAAO;AAE/G,MAAI,MAAM,QAAQ,KAAK,KAAM,SAAS,OAAO,UAAU,SAAW,QAAO;AACzE,SAAO;AACT;AAGO,SAAS,6BAA6B,OAAgB,MAA2C;AACtG,MAAI,UAAU,OAAW,QAAO;AAEhC,MAAI,SAAS,WAAW;AACtB,UAAM,QAAQ,kBAAkB,KAAK;AACrC,QAAI,OAAO,WAAW,EAAG,QAAO,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,EAAE;AACxE,QAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAC/D,YAAM,SAAU;AAChB,aAAO,EAAE,GAAG,OAAO,KAAK,GAAG,GAAG,OAAO,KAAK,GAAG,GAAG,OAAO,KAAK,EAAE;AAAA,IAChE;AACA,WAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC5B;AAEA,MAAI,SAAS,WAAW;AACtB,UAAM,QAAQ,kBAAkB,KAAK;AACrC,QAAI,OAAO,WAAW,EAAG,QAAO,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,EAAE;AACrF,QAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAC/D,YAAM,SAAU;AAChB,aAAO,EAAE,GAAG,OAAO,KAAK,GAAG,GAAG,OAAO,KAAK,GAAG,GAAG,OAAO,KAAK,GAAG,GAAG,OAAO,KAAK,EAAE;AAAA,IAClF;AACA,WAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAClC;AAEA,MAAI,SAAS,WAAW,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AACnF,UAAM,SAAU;AAChB,WAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,OAAO,MAAM,EAAE;AAAA,EAC7D;AAEA,MAAI,SAAS,UAAU,SAAS,SAAU,QAAO;AACjD,MAAI,OAAO,UAAU,SAAU,QAAO,KAAK,UAAU,KAAK;AAC1D,SAAO;AACT;AAGA,SAAS,YAAY,KAAa,OAAe,MAA8B,OAAgB,SAAwC;AACrI,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,6BAA6B,OAAO,IAAI;AAAA,IAC/C,GAAI,YAAY,SAAY,CAAC,IAAI,EAAE,SAAS,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC,EAAE;AAAA,EAC1E,CAAC;AACH;AAEA,SAAS,YAAY,OAA+C;AAClE,SAAO,OAAO,OAAO;AAAA,IACnB,KAAK,MAAM;AAAA,IACX,MAAM,MAAM;AAAA,IACZ,GAAI,MAAM,aAAa,SAAY,CAAC,IAAI,EAAE,UAAU,MAAM,SAAS;AAAA,IACnE,QAAQ,OAAO,OAAO,MAAM,MAAM;AAAA,IAClC,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,OAAO,OAAO,MAAM,MAAM,EAAE;AAAA,EAC9E,CAAC;AACH;AAGA,SAAS,gBAAgB,OAAkD;AACzE,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,EAAG,QAAO;AACxD,MAAI,CAAC,MAAM,MAAM,CAAC,UAAU,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,CAAC,EAAG,QAAO;AACjG,SAAO;AACT;AAMA,SAAS,gBAAgB,QAAiC,WAAmF;AAC3I,QAAM,SAA+B,CAAC;AACtC,QAAM,SAA+B,CAAC;AACtC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,GAAI;AACtD,UAAM,OAAO,YAAY,GAAG,SAAS,IAAI,GAAG,KAAK;AACjD,UAAM,OAAO,0BAA0B,GAAG;AAC1C,UAAM,SAAS,gBAAgB,KAAK;AACpC,QAAI,QAAQ;AACV,YAAM,QAAQ,aAAa,QAAQ,MAAM,IAAI;AAC7C,UAAI,MAAO,QAAO,KAAK,KAAK;AAC5B;AAAA,IACF;AACA,UAAM,OAAO,0BAA0B,QAAW,KAAK;AACvD,UAAM,eAAe,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,KAC1E,SAAS,aAAa,SAAS,aAAa,SAAS;AAC1D,QAAI,cAAc;AAChB,YAAM,QAAQ,cAAe,OAAmC,MAAM,MAAM,KAAK;AACjF,UAAI,MAAO,QAAO,KAAK,KAAK;AAC5B;AAAA,IACF;AACA,WAAO,KAAK,YAAY,KAAK,MAAM,MAAM,KAAK,CAAC;AAAA,EACjD;AACA,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAGA,SAAS,cAAc,QAAiC,KAAa,MAAc,UAAkF;AACnK,QAAM,cAAc,gBAAgB,QAAQ,GAAG;AAC/C,MAAI,YAAY,OAAO,WAAW,KAAK,YAAY,OAAO,WAAW,EAAG,QAAO;AAC/E,SAAO,YAAY;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,YAAY;AAAA,IACpB,QAAQ,YAAY;AAAA,EACtB,CAAC;AACH;AAGA,SAAS,aAAa,OAAkC,MAAc,MAAyC;AAC7G,QAAM,SAA+B,CAAC;AACtC,aAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC3C,UAAM,QAAQ,KAAK,QAAQ,KAAK,MAAM,KAAK,YAAY,KAAK,QAAQ,OAAO,KAAK;AAChF,UAAM,QAAQ,cAAc,MAAM,GAAG,IAAI,IAAI,KAAK,IAAI,0BAA0B,OAAO,KAAK,CAAC,GAAG,MAAM;AACtG,QAAI,MAAO,QAAO,KAAK,KAAK;AAAA,EAC9B;AACA,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SAAO,YAAY;AAAA,IACjB,KAAK;AAAA,IACL;AAAA,IACA,UAAU;AAAA,IACV,QAAQ,CAAC;AAAA,IACT;AAAA,EACF,CAAC;AACH;AAEA,SAAS,mBAAmB,YAA2D;AACrF,QAAM,QAAQ,WAAW,SAAS,OAAO,WAAW,UAAU,WAAW,WAAW,QAAmC,CAAC;AACxH,QAAM,SAAS,WAAW,UAAU,OAAO,WAAW,WAAW,WAAW,WAAW,SAAoC,CAAC;AAC5H,QAAM,MAAM,WAAW,OAAO,OAAO,WAAW,QAAQ,WAAW,WAAW,MAAiC,CAAC;AAChH,QAAM,QAAqC;AAAA,IACzC,CAAC,QAAQ,QAAQ,WAAW,QAAQ,MAAM,IAAI;AAAA,IAC9C,CAAC,QAAQ,QAAQ,MAAM,IAAI;AAAA,IAC3B,CAAC,QAAQ,QAAQ,MAAM,IAAI;AAAA,IAC3B,CAAC,QAAQ,QAAQ,MAAM,IAAI;AAAA,IAC3B,CAAC,UAAU,UAAU,OAAO,QAAQ,MAAM,UAAU;AAAA,IACpD,CAAC,YAAY,YAAY,WAAW,YAAY,MAAM,YAAY,OAAO,QAAQ;AAAA,IACjF,CAAC,WAAW,WAAW,MAAM,aAAa,MAAM,UAAU;AAAA,IAC1D,CAAC,OAAO,OAAO,IAAI,KAAK;AAAA,EAC1B;AACA,QAAM,SAAS,CAAC;AAChB,aAAW,CAAC,KAAK,OAAO,KAAK,KAAK,OAAO;AACvC,QAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,GAAI;AACtD,WAAO,KAAK,YAAY,KAAK,OAAO,0BAA0B,QAAW,KAAK,GAAG,KAAK,CAAC;AAAA,EACzF;AACA,SAAO;AACT;AAMO,SAAS,kCAAkC,YAAqB,UAAsC,CAAC,GAAkC;AAC9I,MAAI,CAAC,cAAc,OAAO,eAAe,YAAY,MAAM,QAAQ,UAAU,GAAG;AAC9E,WAAO,OAAO,OAAO,CAAC,CAAC;AAAA,EACzB;AACA,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAM,iBAAiB,mBAAmB,UAAqC;AAC/E,QAAM,OAAQ,WAAuC;AACrD,MAAI,aAAmC,CAAC;AACxC,MAAI,SAA+B,CAAC;AACpC,MAAI,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,GAAG;AAC5D,UAAM,cAAc,gBAAiB,MAAkC,MAAM;AAC7E,iBAAa,YAAY;AACzB,aAAS,YAAY;AAAA,EACvB;AACA,QAAM,SAA+B,CAAC;AACtC,QAAM,SAAS,CAAC,GAAG,gBAAgB,GAAG,UAAU;AAChD,MAAI,OAAO,QAAQ;AACjB,WAAO,KAAK,YAAY;AAAA,MACtB,KAAK;AAAA,MACL,MAAM;AAAA,MACN,UAAU;AAAA,MACV;AAAA,MACA,QAAQ,CAAC;AAAA,IACX,CAAC,CAAC;AAAA,EACJ;AACA,SAAO,KAAK,GAAG,MAAM;AACrB,SAAO,OAAO,OAAO,MAAM;AAC7B;;;AC7PA,SAAS,WAAW;AACpB,SAAS,YAAAC,iBAAgC;AAiDjC,SACE,OAAAC,MADF,QAAAC,aAAA;AAZR,IAAM,YAAY,EAAE,UAAU,MAAM,UAAU,GAAY;AAE1D,SAAS,YAAY;AAAA,EACnB;AAAA,EACA;AACF,GAGG;AACD,SACE,gBAAAD,KAAC,UAAK,WAAW,yBAAyB,KAAK,SAAS,IAAI,+BAA+B,EAAE,IAC1F,eAAK,IAAI,CAAC,SACT,gBAAAC,MAAC,UAAK,WAAW,sDAAsD,IAAI,IACzE;AAAA,oBAAAD,KAAC,UAAK,WAAU,2BAA2B,eAAK,YAAY,GAAE;AAAA,IAC9D,gBAAAA,KAAC,UAAK,WAAU,+BACd,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,MAAK;AAAA,QACL,OAAO,OAAO,IAAI;AAAA,QACjB,GAAG;AAAA;AAAA,IACN,GACF;AAAA,OATkF,IAUpF,CACD,GACH;AAEJ;AAEO,SAAS,sBAAsB,EAAE,MAAM,GAAkC;AAC9E,MAAI,MAAM,SAAS,aAAa,OAAO,MAAM,UAAU,YAAY,MAAM,UAAU,MAAM;AACvF,UAAM,SAAS,MAAM;AACrB,WAAO,gBAAAA,KAAC,eAAY,MAAM,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,EAAE,GAAG,QAAQ,GAAG,EAAE,GAAG;AAAA,EAC1E;AACA,MAAI,MAAM,SAAS,aAAa,OAAO,MAAM,UAAU,YAAY,MAAM,UAAU,MAAM;AACvF,UAAM,SAAS,MAAM;AACrB,WAAO,gBAAAA,KAAC,eAAY,MAAM,CAAC,KAAK,KAAK,KAAK,GAAG,GAAG,QAAgB;AAAA,EAClE;AACA,MAAI,MAAM,SAAS,QAAQ;AACzB,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,SAAS,MAAM,UAAU;AAAA,QACzB,UAAQ;AAAA,QACR,WAAS;AAAA,QACT,OAAO,MAAM;AAAA;AAAA,IACf;AAAA,EAEJ;AACA,MAAI,MAAM,SAAS,QAAQ;AACzB,WACE,gBAAAA,KAAC,UAAK,WAAU,6BACd,0BAAAA,KAAC,UAAO,WAAU,4BAA2B,OAAO,OAAO,MAAM,KAAK,GAAG,UAAQ,MAC7E,iBAAM,WAAW,CAAC,OAAO,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,WAC7C,gBAAAA,KAAC,YAAO,OAAO,QAAsB,oBAAT,MAAgB,CAC7C,GACH,GACF;AAAA,EAEJ;AACA,MAAI,MAAM,SAAS,SAAS;AAC1B,WACE,gBAAAC,MAAC,UAAK,WAAU,4BACd;AAAA,sBAAAD,KAAC,UAAK,WAAU,6BAA4B,eAAW,MAAC,OAAO,EAAE,YAAY,OAAO,MAAM,KAAK,EAAE,GAAG;AAAA,MACpG,gBAAAA,KAAC,aAAU,WAAU,0DAAyD,OAAO,OAAO,MAAM,KAAK,GAAI,GAAG,WAAW;AAAA,OAC3H;AAAA,EAEJ;AACA,MAAI,MAAM,SAAS,SAAS;AAC1B,UAAM,QAAQ,CAAC,OAAO,MAAM,KAAK;AACjC,WACE,gBAAAC,MAAC,UAAK,WAAU,4BACd;AAAA,sBAAAD,KAAC,UAAK,WAAW,iCAAiC,QAAQ,cAAc,EAAE,IAAK,kBAAQ,OAAO,gBAAAA,KAAC,OAAI,MAAM,IAAI,GAAG;AAAA,MAChH,gBAAAA,KAAC,UAAK,WAAU,iCACd,0BAAAA,KAAC,UAAK,WAAU,kCACd,0BAAAA,KAAC,UAAK,WAAW,iCAAiC,QAAQ,cAAc,EAAE,IAAK,kBAAQ,SAAS,OAAO,MAAM,KAAK,GAAE,GACtH,GACF;AAAA,OACF;AAAA,EAEJ;AACA,SACE,gBAAAA,KAAC,UAAK,WAAW,MAAM,SAAS,WAAW,kEAAkE,QAC3G,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,4BAA4B,MAAM,SAAS,WAAW,qCAAqC,gCAAgC;AAAA,MACtI,MAAM,MAAM,SAAS,WAAW,WAAW;AAAA,MAC3C,OAAO,OAAO,MAAM,KAAK;AAAA,MACxB,GAAG;AAAA;AAAA,EACN,GACF;AAEJ;AAEA,SAAS,UAAU;AAAA,EACjB;AAAA,EACA,SAAS;AACX,GAGG;AACD,QAAM,CAAC,MAAM,OAAO,IAAIE,UAAS,IAAI;AACrC,QAAM,WAAW,MAAM,aAAa,QAAQ,QAAQ,MAAM,aAAa,eAAe,QAAQ;AAC9F,SACE,gBAAAF,KAAC,SAAI,WAAW,sDAAsD,QAAQ,GAAG,SAAS,eAAe,EAAE,IACzG,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,cAAc;AAAA,MACd,OACE,gBAAAC,MAAC,UAAK,WAAU,4BACd;AAAA,wBAAAD,KAAC,UAAK,WAAU,2BAA0B,0BAAAA,KAAC,OAAI,MAAM,IAAI,aAAa,KAAK,GAAE;AAAA,QAC7E,gBAAAA,KAAC,UAAM,gBAAM,MAAK;AAAA,SACpB;AAAA,MAGF,0BAAAC,MAAC,SAAI,WAAU,6BACZ;AAAA,cAAM,OAAO,IAAI,CAAC,UACjB,gBAAAD,KAAC,SAAI,WAAU,0BAAyC,eAAa,wBAAwB,MAAM,GAAG,IAAI,MAAM,GAAG,IACjH,0BAAAA,KAAC,eAAY,WAAU,+BAA8B,OAAO,gBAAAA,KAAC,UAAK,OAAO,MAAM,KAAM,gBAAM,OAAM,GAC/F,0BAAAA,KAAC,yBAAsB,OAAc,GACvC,KAH2C,MAAM,GAInD,CACD;AAAA,SACC,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,UACzB,gBAAAA,KAAC,aAAU,OAAO,OAAuB,QAAM,QAAjB,MAAM,GAAY,CACjD;AAAA,SACH;AAAA;AAAA,EACF,GACF;AAEJ;AAEO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,QAAM,WAAW,UAAU;AAAA,IACzB;AAAA,IACA,kBAAkB,SAAY,CAAC,IAAI,EAAE,cAAc;AAAA,EACrD;AACA,MAAI,SAAS,WAAW,EAAG,QAAO,SAAS;AAC3C,SACE,gBAAAA,KAAC,SAAI,WAAW,CAAC,qBAAqB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,sBAAmB,QAC5F,mBAAS,IAAI,CAAC,UACb,gBAAAA,KAAC,aAAU,SAAmB,MAAM,GAAK,CAC1C,GACH;AAEJ;;;ACjMA,SAAS,eAAAG,cAAa,SAAAC,QAAO,MAAM,KAAAC,UAAS;AAC5C;AAAA,EACE,eAAAC;AAAA,EACA,aAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,wBAAAC;AAAA,OAGK;AACP,SAAS,gBAAAC,qBAAoB;AAgIvB,gBAAAC,MAoBM,QAAAC,aApBN;AA7FN,IAAI,SAAS;AACb,IAAI,UAA6B,CAAC;AAClC,IAAM,YAAY,oBAAI,IAAc;AACpC,IAAM,SAAS,oBAAI,IAA2C;AAE9D,SAAS,OAAO;AACd,aAAW,YAAY,UAAW,UAAS;AAC7C;AAEO,SAAS,sBAAsB,UAAoB;AACxD,YAAU,IAAI,QAAQ;AACtB,SAAO,MAAM;AACX,cAAU,OAAO,QAAQ;AAAA,EAC3B;AACF;AAEO,SAAS,kBAAkB;AAChC,SAAO;AACT;AAEO,SAAS,gBAAgB,OAAiC;AAC/D,QAAM,KAAK,EAAE;AACb,QAAM,aAAa,MAAM,eAAe;AACxC,YAAU,CAAC,GAAG,SAAS,EAAE,GAAG,OAAO,IAAI,WAAW,CAAC;AACnD,OAAK;AACL,MAAI,CAAC,YAAY;AACf,UAAM,WAAW,MAAM,YAAY;AACnC,QAAI,WAAW,GAAG;AAChB,aAAO;AAAA,QACL;AAAA,QACA,WAAW,MAAM;AACf,iBAAO,OAAO,EAAE;AAChB,6BAAmB,EAAE;AAAA,QACvB,GAAG,QAAQ;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,mBAAmB,IAAY;AAC7C,QAAM,QAAQ,OAAO,IAAI,EAAE;AAC3B,MAAI,UAAU,QAAW;AACvB,iBAAa,KAAK;AAClB,WAAO,OAAO,EAAE;AAAA,EAClB;AACA,QAAM,UAAU,QAAQ,KAAK,CAAC,WAAW,OAAO,OAAO,EAAE;AACzD,MAAI,CAAC,QAAS;AACd,YAAU,QAAQ,OAAO,CAAC,WAAW,OAAO,OAAO,EAAE;AACrD,OAAK;AACL,UAAQ,YAAY;AACtB;AAEA,SAAS,gBAAgB,UAAmB,SAAqB;AAC/D,MAAI,OAAO,aAAa,YAAY,SAAS,KAAK,MAAM,GAAI,QAAO;AACnE,MAAI,OAAO,YAAY,YAAY,QAAQ,KAAK,MAAM,GAAI,QAAO;AACjE,SAAO;AACT;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,aAAa;AAAA,EACb;AACF,GAAqB;AACnB,QAAM,CAAC,QAAQ,SAAS,IAAIC,UAAS,KAAK;AAC1C,QAAM,gBAAgB,gBAAgB,UAAU,OAAO;AAEvD,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,QAAQ,WAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AACrD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,MAAM,CAAC;AAEX,iBAAe,oBAAoB;AACjC,QAAI,CAAC,cAAe;AACpB,QAAI;AACF,YAAM,UAAU,UAAU,UAAU,aAAa;AACjD,gBAAU,IAAI;AAAA,IAChB,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SACE,gBAAAF,MAAC,SAAI,WAAU,oCAAmC,MAAK,SACrD;AAAA,oBAAAD,KAACI,cAAA,EAAY,WAAU,iCAAgC,eAAW,MAAC;AAAA,IACnE,gBAAAH,MAAC,SAAI,WAAU,yBACb;AAAA,sBAAAD,KAAC,YAAO,WAAU,0BAA0B,iBAAM;AAAA,MACjD,OACC,gBAAAA,KAAC,QAAK,IAAG,QAAO,SAAQ,QAAO,WAAU,yBACtC,gBACH,IACE;AAAA,MACH,cACC,gBAAAA,KAAC,QAAK,SAAQ,QAAO,WAAU,gCAC5B,uBACH,IACE;AAAA,MACH,OACC,gBAAAA,KAAC,QAAK,SAAQ,WAAU,WAAU,yBAC/B,gBACH,IACE;AAAA,MACH,UACC,gBAAAC,MAAC,aAAQ,WAAU,4BAA2B,MAAI,MAChD;AAAA,wBAAAA,MAAC,aAAQ,WAAU,oCACjB;AAAA,0BAAAD,KAAC,UAAM,wBAAa;AAAA,UACnB,gBACC,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,WAAU;AAAA,cACV,aACE,SACE,gBAAAA,KAACK,QAAA,EAAM,WAAU,WAAU,eAAW,MAAC,IAEvC,gBAAAL,KAAC,QAAK,WAAU,WAAU,eAAW,MAAC;AAAA,cAG1C,SAAS,CAAC,UAAU;AAClB,sBAAM,eAAe;AACrB,sBAAM,gBAAgB;AACtB,qBAAK,kBAAkB;AAAA,cACzB;AAAA,cAEC,mBAAS,cAAc;AAAA;AAAA,UAC1B,IACE;AAAA,WACN;AAAA,QACA,gBAAAA,KAAC,SAAI,WAAU,iCAAiC,mBAAQ;AAAA,SAC1D,IACE;AAAA,OACN;AAAA,IACA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,MAAM,gBAAAA,KAACM,IAAA,EAAE,WAAU,WAAU;AAAA,QAC7B,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,SAAS;AAAA;AAAA,IACX;AAAA,KACF;AAEJ;AAEA,IAAM,aAAa;AACnB,IAAM,YAAY;AAClB,IAAM,mBAAmB;AAEzB,SAAS,aAAa,OAA0B,SAAiC,UAAmB;AAClG,QAAM,WAAW,CAAC,OAAe,QAAQ,EAAE,KAAK;AAChD,QAAM,cAAc,MAAM,CAAC,IAAI,SAAS,MAAM,CAAC,EAAE,EAAE,IAAI;AACvD,MAAI,IAAI;AACR,QAAM,QAAQ,MAAM,IAAI,CAAC,MAAM,UAAU;AACvC,UAAM,SAAS,SAAS,KAAK,EAAE;AAC/B,UAAM,YAAY,KAAK,IAAI,OAAO,gBAAgB;AAClD,UAAM,QAAQ,WAAW,IAAI,KAAK,IAAI,GAAG,cAAc,SAAS,YAAY,UAAU;AACtF,QAAI,SAAU,MAAK,SAAS;AAC5B,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,GAAG;AAAA,MACH,GAAG,MAAM,SAAS;AAAA,MAClB,aAAa,YAAY,UAAU;AAAA,IACrC;AAAA,EACF,CAAC;AACD,QAAM,cAAc,WAChB,MAAM,OAAO,CAAC,KAAK,MAAM,UAAU,MAAM,SAAS,KAAK,EAAE,KAAK,QAAQ,IAAI,YAAY,IAAI,CAAC,IAC3F,cAAc,KAAK,IAAI,KAAK,IAAI,MAAM,SAAS,GAAG,CAAC,GAAG,gBAAgB,IAAI;AAC9E,SAAO,EAAE,OAAO,YAAY;AAC9B;AAEO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,SAAS;AAAA,EACT;AACF,GAIG;AACD,QAAM,CAAC,UAAU,WAAW,IAAIJ,UAAS,KAAK;AAC9C,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAiC,CAAC,CAAC;AACjE,QAAM,YAAYK,QAAO,oBAAI,IAA4B,CAAC;AAC1D,QAAM,UAAU,MAAM,SAAS;AAC/B,QAAM,OAAO,WAAW;AAExB,QAAM,UAAUC,aAAY,MAAM;AAChC,eAAW,CAAC,YAAY;AACtB,UAAI,UAAU,OAAO,KAAK,OAAO,EAAE,WAAW,MAAM;AACpD,YAAM,OAA+B,CAAC;AACtC,iBAAW,QAAQ,OAAO;AACxB,cAAM,SAAS,UAAU,QAAQ,IAAI,KAAK,EAAE,GAAG,gBAAgB;AAC/D,aAAK,KAAK,EAAE,IAAI;AAChB,YAAI,QAAQ,KAAK,EAAE,MAAM,OAAQ,WAAU;AAAA,MAC7C;AACA,aAAO,UAAU,OAAO;AAAA,IAC1B,CAAC;AAAA,EACH,GAAG,CAAC,KAAK,CAAC;AAEV,EAAAC,iBAAgB,MAAM;AACpB,YAAQ;AACR,UAAM,WAAW,IAAI,eAAe,OAAO;AAC3C,eAAW,QAAQ,OAAO;AACxB,YAAM,OAAO,UAAU,QAAQ,IAAI,KAAK,EAAE;AAC1C,UAAI,KAAM,UAAS,QAAQ,IAAI;AAAA,IACjC;AACA,WAAO,MAAM,SAAS,WAAW;AAAA,EACnC,GAAG,CAAC,OAAO,OAAO,CAAC;AAEnB,QAAM,EAAE,OAAO,YAAY,IAAIC;AAAA,IAC7B,MAAM,aAAa,OAAO,SAAS,IAAI;AAAA,IACvC,CAAC,OAAO,SAAS,IAAI;AAAA,EACvB;AAEA,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,SACE,gBAAAV;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,CAAC,0BAA0B,SAAS,UAAU,gCAAgC,EACtF,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MACX,aAAU;AAAA,MACV,cAAY,MAAM;AAAA,MAClB,iBAAe,OAAO,KAAK;AAAA,MAC3B,cAAY,MAAM,MAAM,CAAC,UAAU,QAAQ,KAAK,EAAE,KAAK,KAAK,CAAC,IAAI,KAAK;AAAA,MACtE,cAAc,UAAU,MAAM,YAAY,IAAI,IAAI;AAAA,MAClD,cAAc,UAAU,MAAM,YAAY,KAAK,IAAI;AAAA,MACnD,SAAS,UAAU,MAAM,YAAY,IAAI,IAAI;AAAA,MAC7C,QACE,UACI,CAAC,UAAU;AACT,YAAI,CAAC,MAAM,cAAc,SAAS,MAAM,aAA4B,GAAG;AACrE,sBAAY,KAAK;AAAA,QACnB;AAAA,MACF,IACA;AAAA,MAEN,OACE;AAAA,QACE,kCAAkC,GAAG,WAAW;AAAA,MAClD;AAAA,MAGD,gBAAM,IAAI,CAAC,WAAW;AACrB,cAAM,OAAO,MAAM,KAAK,CAAC,UAAU,MAAM,OAAO,OAAO,EAAE;AACzD,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YAEV,KAAK,CAAC,SAAS;AACb,kBAAI,KAAM,WAAU,QAAQ,IAAI,OAAO,IAAI,IAAI;AAAA,kBAC1C,WAAU,QAAQ,OAAO,OAAO,EAAE;AAAA,YACzC;AAAA,YACA,cAAY,KAAK,cAAc,SAAY;AAAA,YAC3C,OACE;AAAA,cACE,uBAAuB,GAAG,KAAK,CAAC;AAAA,cAChC,uBAAuB,KAAK;AAAA,YAC9B;AAAA,YAGF,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACE,GAAG;AAAA,gBACH,GAAI,OAAO,eAAe,SAAY,CAAC,IAAI,EAAE,YAAY,OAAO,WAAW;AAAA,gBAC5E,SAAS,MAAM,QAAQ,OAAO,EAAE;AAAA;AAAA,YAClC;AAAA;AAAA,UAjBK,OAAO;AAAA,QAkBd;AAAA,MAEJ,CAAC;AAAA;AAAA,EACH;AAEJ;AAEO,SAAS,kBAAkB;AAChC,QAAM,QAAQW,sBAAqB,uBAAuB,iBAAiB,eAAe;AAC1F,QAAM,UAAUD,SAAQ,MAAM,CAAC,GAAG,KAAK,EAAE,QAAQ,GAAG,CAAC,KAAK,CAAC;AAC3D,MAAI,OAAO,aAAa,eAAe,QAAQ,WAAW,EAAG,QAAO;AACpE,SAAOE;AAAA,IACL,gBAAAZ,KAAC,oBAAiB,OAAO,SAAS,SAAS,oBAAoB;AAAA,IAC/D,SAAS;AAAA,EACX;AACF;;;AChVA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,KAAAa;AAAA,OAEK;AACP;AAAA,EACE,eAAAC;AAAA,EACA,aAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OAIK;;;ACjBP;AAAA,EACE,OAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAcP,IAAM,eAA6C;AAAA,EACjD,OAAO;AAAA,EACP,OAAOA;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,QAAQ;AACV;AAEA,IAAM,WAAkE;AAAA,EACtE,CAAC,CAAC,MAAM,OAAO,MAAM,OAAO,OAAO,OAAO,IAAI,GAAG,MAAM;AAAA,EACvD,CAAC,CAAC,MAAM,YAAY,KAAK,GAAG,KAAK;AAAA,EACjC,CAAC,CAAC,OAAO,OAAO,QAAQ,QAAQ,OAAO,OAAO,OAAO,KAAK,GAAG,OAAO;AAAA,EACpE,CAAC,CAAC,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,MAAM,GAAG,OAAO;AAAA,EAC7D,CAAC,CAAC,OAAO,QAAQ,KAAK,GAAG,OAAO;AAAA,EAChC,CAAC,CAAC,OAAO,OAAO,OAAO,GAAG,MAAM;AAClC;AAEO,SAAS,WAAW,OAA4D;AACrF,QAAM,QAAQ,MAAM,gBAAgB,IAAI,YAAY;AACpD,MAAI,MAAM;AACR,QAAI,KAAK,SAAS,aAAa,EAAG,QAAO;AACzC,QAAI,KAAK,SAAS,YAAY,EAAG,QAAO,KAAK,SAAS,OAAO,IAAI,UAAU;AAC3E,UAAM,MAAM,KAAK,MAAM,SAAS,CAAC,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,IAAI,KAAK;AAC3D,eAAW,CAAC,MAAM,IAAI,KAAK,SAAU,KAAI,KAAK,SAAS,GAAG,EAAG,QAAO;AACpE,QAAI,KAAK,SAAS,YAAY,KAAK,KAAK,SAAS,cAAc,EAAG,QAAO;AAAA,EAC3E;AACA,QAAM,KAAK,MAAM,OAAO,YAAY;AACpC,aAAW,QAAQ,OAAO,KAAK,YAAY,GAAiB;AAC1D,QAAI,GAAG,SAAS,IAAI,EAAG,QAAO;AAAA,EAChC;AACA,MAAI,GAAG,SAAS,OAAO,KAAK,GAAG,SAAS,OAAO,EAAG,QAAO;AACzD,MAAI,GAAG,SAAS,WAAW,KAAK,GAAG,SAAS,KAAK,KAAK,GAAG,SAAS,QAAQ,EAAG,QAAO;AACpF,SAAO;AACT;AAEO,SAAS,YAAY,OAA8D;AACxF,QAAM,QAAQ,MAAM,gBAAgB,IAAI,YAAY;AACpD,QAAM,OAAO,WAAW,KAAK;AAC7B,MAAI,CAAC,QAAQ,SAAS,YAAY,CAAC,MAAM,OAAO,YAAY,EAAE,SAAS,QAAQ,EAAG,QAAO;AACzF,SAAO,aAAa,IAAI;AAC1B;;;AD8HgB,SA0CR,YAAAC,WA1CQ,OAAAC,MA0CR,QAAAC,aA1CQ;AAtJhB,IAAM,iBAAqC;AAAA,EACzC,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,qBAAqB;AACvB;AAEA,SAASC,YAAW,OAAiD;AACnE,SAAO,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AACvC;AAEA,SAAS,gBAAgB,WAA0C;AACjE,QAAM,CAAC,MAAM,OAAO,IAAIC,UAAS,KAAK;AACtC,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AAEvD,QAAM,eAAeC;AAAA,IACnB,CAAC,QAAyB,YAAY;AACpC,YAAM,KAAK,UAAU;AACrB,UAAI,CAAC,GAAI;AACT,YAAM,OAAO,GAAG,sBAAsB;AACtC,kBAAY;AAAA,QACV,GAAG,UAAU,QAAQ,KAAK,QAAQ,KAAK;AAAA,QACvC,GAAG,KAAK,SAAS;AAAA,MACnB,CAAC;AACD,cAAQ,IAAI;AAAA,IACd;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,SAAO,EAAE,MAAM,SAAS,UAAU,aAAa;AACjD;AAgBO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe,CAAC;AAAA,EAChB;AAAA,EACA,QAAQ;AAAA,EACR;AACF,GAA2C;AACzC,QAAM,SAAS,EAAE,GAAG,gBAAgB,GAAG,eAAe;AACtD,QAAM,UAAUC,QAAuB,IAAI;AAC3C,QAAM,eAAeA,QAA0B,IAAI;AACnD,QAAM,oBAAoBA,QAA0B,IAAI;AACxD,QAAM,aAAaA,QAAsB,IAAI;AAC7C,QAAM,CAAC,aAAa,cAAc,IAAIF,UAAwB,IAAI;AAClE,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,KAAK;AACpD,QAAM,CAAC,aAAa,cAAc,IAAIA;AAAA,IACpC;AAAA,EACF;AACA,QAAM,UAAU,gBAAgB,YAAY;AAC5C,QAAM,eAAe,gBAAgB,iBAAiB;AACtD,QAAM,SAASG,OAAM;AAErB,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,aAAc;AACnB,YAAQ,SACJ,cAAc,kBAAkB,IAAI,OAAO,YAAY,CAAC,IAAI,GAC5D,eAAe,EAAE,OAAO,WAAW,QAAQ,UAAU,CAAC;AAAA,EAC5D,GAAG,CAAC,YAAY,CAAC;AAEjB,EAAAA,WAAU,MAAM;AACd,UAAM,KAAK,QAAQ;AACnB,QAAI,CAAC,GAAI;AACT,UAAM,UAAU,MAAM,eAAe,GAAG,cAAc,GAAG,cAAc,CAAC;AACxE,YAAQ;AACR,UAAM,KAAK,IAAI,eAAe,OAAO;AACrC,OAAG,QAAQ,EAAE;AACb,WAAO,MAAM,GAAG,WAAW;AAAA,EAC7B,GAAG,CAAC,MAAM,MAAM,CAAC;AAEjB,EAAAA,WAAU,MAAM;AACd,UAAM,MAAM,MAAM;AAChB,iBAAW,UAAU;AACrB,qBAAe,IAAI;AAAA,IACrB;AACA,WAAO,iBAAiB,aAAa,GAAG;AACxC,WAAO,MAAM,OAAO,oBAAoB,aAAa,GAAG;AAAA,EAC1D,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAiBH;AAAA,IACrB,CAAC,WAAmB;AAClB,UAAI,WAAW,aAAc;AAC7B,eAAS,MAAM;AAAA,IACjB;AAAA,IACA,CAAC,cAAc,QAAQ;AAAA,EACzB;AAEA,QAAM,oBAAoBA,aAAY,CAAC,OAA0B,WAAmB;AAClF,QAAI,MAAM,WAAW,EAAG;AACxB,QAAK,MAAM,OAAuB,QAAQ,mBAAmB,EAAG;AAChE,eAAW,UAAU;AAAA,EACvB,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoBA;AAAA,IACxB,CAAC,UAA6B;AAC5B,YAAM,UAAU,WAAW;AAC3B,UAAI,CAAC,WAAW,MAAM,YAAY,KAAK,CAAC,UAAW;AACnD,YAAM,SAAU,MAAM,OACnB,QAAQ,gBAAgB,GACvB,aAAa,cAAc;AAC/B,UAAI,CAAC,UAAU,WAAW,QAAS;AACnC,YAAM,UAAU,MAAM,UAAU,CAAC,SAAS,KAAK,OAAO,MAAM;AAC5D,UAAI,UAAU,EAAG;AACjB,qBAAe,OAAO;AACtB,gBAAU,SAAS,OAAO;AAAA,IAC5B;AAAA,IACA,CAAC,WAAW,KAAK;AAAA,EACnB;AAEA,QAAM,YAAYA;AAAA,IAChB,CAAC,WAAmB;AAClB,gBAAU,MAAM;AAAA,IAClB;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,QAAM,cAAc,cAChB,MAAM,KAAK,CAAC,SAAS,KAAK,OAAO,YAAY,MAAM,IACnD;AACJ,QAAM,eAA2B,eAAe,cAC5C;AAAA,IACE;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,OAAO;AAAA,MACd,MAAM,gBAAAJ,KAACQ,IAAA,EAAE,WAAU,WAAU,eAAW,MAAC;AAAA,MACzC,UAAU,CAAC,YAAY;AAAA,MACvB,UAAU,MAAM,UAAU,YAAY,MAAM;AAAA,IAC9C;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,OAAO;AAAA,MACd,MAAM,gBAAAR,KAAC,SAAM,WAAU,WAAU,eAAW,MAAC;AAAA,MAC7C,UAAU,MAAM;AACd,wBAAgB,YAAY,MAAM;AAClC,iBAAS,YAAY,MAAM;AAAA,MAC7B;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,OAAO;AAAA,MACd,MAAM,gBAAAA,KAAC,iBAAc,WAAU,WAAU,eAAW,MAAC;AAAA,MACrD,UAAU,MAAM,iBAAiB,YAAY,MAAM;AAAA,IACrD;AAAA,EACF,IACA,CAAC;AAEL,QAAM,mBACJ,aAAa,WAAW,IACpB,CAAC,EAAE,IAAI,SAAS,OAAO,OAAO,iBAAiB,UAAU,KAAK,CAAC,IAC/D,aAAa,IAAI,CAAC,SAAS;AACzB,UAAM,OAAO,YAAY,EAAE,QAAQ,KAAK,OAAO,CAAC;AAChD,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,OAAO,KAAK;AAAA,MACZ,MAAM,gBAAAA,KAAC,QAAK,WAAU,WAAU,eAAW,MAAC;AAAA,MAC5C,UAAU,MAAM,YAAY,KAAK,MAAM;AAAA,IACzC;AAAA,EACF,CAAC;AAEP,QAAM,oBAAgC,MAAM,IAAI,CAAC,SAAS;AACxD,UAAM,OAAO,KAAK,QAAQ,YAAY,EAAE,QAAQ,KAAK,QAAQ,GAAI,KAAK,iBAAiB,SAAY,CAAC,IAAI,EAAE,cAAc,KAAK,aAAa,EAAG,CAAC;AAC9I,UAAM,OAAO,iBAAiB,KAAK,KAAK,WAAM;AAC9C,UAAM,QAAQ,KAAK,QAAQ,GAAG,KAAK,KAAK,OAAO,KAAK;AACpD,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,OACE,gBAAAC,MAAAF,WAAA,EACE;AAAA,wBAAAC,KAAC,UAAK,WAAU,0BAA0B,gBAAK;AAAA,QAC/C,gBAAAA,KAAC,UAAK,WAAU,2BAA2B,iBAAM;AAAA,SACnD;AAAA,MAEF,MAAM,gBAAAA,KAAC,QAAK,WAAU,WAAU,eAAW,MAAC;AAAA,MAC5C,UAAU,iBAAiB,KAAK;AAAA,MAChC,UAAU,MAAM,SAAS,KAAK,EAAE;AAAA,IAClC;AAAA,EACF,CAAC;AAED,SACE,gBAAAC,MAAC,SAAI,WAAWC,SAAQ,qBAAqB,SAAS,SAAS,GAAG,gBAAa,YAC7E;AAAA,oBAAAD,MAAC,SAAI,WAAU,4BACb;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,WAAU;AAAA,UACV,MAAK;AAAA,UACL,cAAY,OAAO;AAAA,UACnB,eAAe;AAAA,UAEd,gBAAM,IAAI,CAAC,SAAS;AACnB,kBAAM,SAAS,iBAAiB,KAAK;AACrC,kBAAM,OACJ,KAAK,QAAQ,YAAY,EAAE,QAAQ,KAAK,QAAQ,GAAI,KAAK,iBAAiB,SAAY,CAAC,IAAI,EAAE,cAAc,KAAK,aAAa,EAAG,CAAC;AACnI,kBAAM,WAAW,KAAK,aAAa;AACnC,kBAAM,WAAWE;AAAA,cACf;AAAA,cACA,UAAU;AAAA,cACV,CAAC,YAAY;AAAA,cACb,KAAK,SAAS;AAAA,cACd,gBAAgB,KAAK,MAAM;AAAA,YAC7B;AACA,mBACE,gBAAAD;AAAA,cAAC;AAAA;AAAA,gBAEC,MAAK;AAAA,gBACL,WAAW;AAAA,gBACX,MAAK;AAAA,gBACL,iBAAe;AAAA,gBACf,gBAAc,KAAK;AAAA,gBACnB,cAAY,KAAK,QAAQ,MAAM;AAAA,gBAC/B,OAAO,KAAK,WAAW,KAAK,gBAAgB,KAAK;AAAA,gBACjD,SAAS,MAAM,eAAe,KAAK,EAAE;AAAA,gBACrC,YAAY,CAAC,UAAU;AACrB,sBAAI,MAAM,WAAW,KAAK,UAAU;AAClC,0BAAM,eAAe;AACrB,8BAAU,KAAK,EAAE;AAAA,kBACnB;AAAA,gBACF;AAAA,gBACA,eAAe,CAAC,UAAU;AACxB,wBAAM,eAAe;AACrB,iCAAe,EAAE,GAAG,MAAM,SAAS,GAAG,MAAM,SAAS,QAAQ,KAAK,GAAG,CAAC;AAAA,gBACxE;AAAA,gBACA,eAAe,CAAC,UAAU,kBAAkB,OAAO,KAAK,EAAE;AAAA,gBAE1D;AAAA,kCAAAD,KAAC,QAAK,WAAU,qBAAoB,eAAW,MAAC;AAAA,kBAChD,gBAAAA,KAAC,UAAK,WAAU,sBAAsB,eAAK,OAAM;AAAA,kBAChD,KAAK,QAAQ,gBAAAA,KAAC,UAAK,WAAU,sBAAqB,eAAW,MAAC,eAAC,IAAU;AAAA,kBACzE,WACC,gBAAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,WAAU;AAAA,sBACV,MAAK;AAAA,sBACL,cAAY,OAAO;AAAA,sBACnB,mBAAiB,KAAK;AAAA,sBACtB,SAAS,CAAC,UAAU;AAClB,8BAAM,gBAAgB;AACtB,kCAAU,KAAK,EAAE;AAAA,sBACnB;AAAA,sBAEA,0BAAAA,KAACQ,IAAA,EAAE,WAAU,2BAA0B,eAAW,MAAC;AAAA;AAAA,kBACrD,IAEA,gBAAAR,KAAC,OAAI,WAAU,oBAAmB,eAAW,MAAC;AAAA;AAAA;AAAA,cAtC3C,KAAK;AAAA,YAwCZ;AAAA,UAEJ,CAAC;AAAA;AAAA,MACH;AAAA,MAEA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAO,OAAO;AAAA,UACd,cAAY,OAAO;AAAA,UACnB,iBAAc;AAAA,UACd,iBAAe,QAAQ;AAAA,UACvB,iBAAe,GAAG,MAAM;AAAA,UACxB,SAAS,MAAM;AACb,gBAAI,QAAQ,KAAM,SAAQ,QAAQ,KAAK;AAAA,gBAClC,SAAQ,aAAa,OAAO;AAAA,UACnC;AAAA,UAEA,0BAAAA,KAAC,QAAK,WAAU,yBAAwB,eAAW,MAAC;AAAA;AAAA,MACtD;AAAA,MAEA,gBAAAA,KAAC,SAAI,WAAU,8BACZ,wBACC,gBAAAC;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAO,OAAO;AAAA,UACd,iBAAc;AAAA,UACd,iBAAe,aAAa;AAAA,UAC5B,iBAAe,GAAG,MAAM;AAAA,UACxB,SAAS,MAAM;AACb,gBAAI,aAAa,KAAM,cAAa,QAAQ,KAAK;AAAA,gBAC5C,cAAa,aAAa,KAAK;AAAA,UACtC;AAAA,UAEA;AAAA,4BAAAD,KAAC,iBAAc,WAAU,yBAAwB,eAAW,MAAC;AAAA,YAC7D,gBAAAA,KAAC,UAAM,gBAAM,QAAO;AAAA;AAAA;AAAA,MACtB,IACE,MACN;AAAA,OACF;AAAA,IAEA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,gBAAgB;AAAA,QACtB,GAAG,aAAa,KAAK;AAAA,QACrB,GAAG,aAAa,KAAK;AAAA,QACrB,OAAO;AAAA,QACP,SAAS,MAAM,eAAe,IAAI;AAAA,QAClC,OAAO,aAAa,SAAS,OAAO;AAAA;AAAA,IACtC;AAAA,IAEA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,QAAQ;AAAA,QACd,GAAG,QAAQ,SAAS;AAAA,QACpB,GAAG,QAAQ,SAAS;AAAA,QACpB,OAAO;AAAA,QACP,SAAS,MAAM,QAAQ,QAAQ,KAAK;AAAA,QACpC,OAAO,OAAO;AAAA,QACd,gBAAgB,EAAE,IAAI,GAAG,MAAM,OAAO;AAAA;AAAA,IACxC;AAAA,IAEA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,aAAa;AAAA,QACnB,GAAG,aAAa,SAAS;AAAA,QACzB,GAAG,aAAa,SAAS;AAAA,QACzB,OAAO;AAAA,QACP,SAAS,MAAM,aAAa,QAAQ,KAAK;AAAA,QACzC,OAAO,OAAO;AAAA,QACd,gBAAgB,EAAE,IAAI,GAAG,MAAM,YAAY;AAAA;AAAA,IAC7C;AAAA,KACF;AAEJ;",
6
+ "names": ["Surface", "Link", "Button", "IconButton", "TextInput", "Select", "TextArea", "Checkbox", "Radio", "RangeInput", "Switch", "SearchField", "createContext", "useCallback", "useContext", "useEffect", "useMemo", "useState", "jsx", "createContext", "useState", "useCallback", "useEffect", "useMemo", "useContext", "useState", "jsx", "jsxs", "useState", "AlertCircle", "Check", "X", "useCallback", "useEffect", "useLayoutEffect", "useMemo", "useRef", "useState", "useSyncExternalStore", "createPortal", "jsx", "jsxs", "useState", "useEffect", "AlertCircle", "Check", "X", "useRef", "useCallback", "useLayoutEffect", "useMemo", "useSyncExternalStore", "createPortal", "X", "useCallback", "useEffect", "useId", "useRef", "useState", "Box", "Fragment", "jsx", "jsxs", "classes", "useState", "useCallback", "useRef", "useId", "useEffect", "X"]
7
+ }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  RESOURCE_FALLBACK_LAYOUT
3
- } from "./chunk-BGK4ZEQ5.mjs";
3
+ } from "./chunk-KX2WU5Z6.mjs";
4
4
  import {
5
5
  VIEW_PAGE_TYPES
6
6
  } from "./chunk-E3Z7GLFU.mjs";
@@ -55,4 +55,4 @@ export {
55
55
  PROPERTIES_TITLE_I18N_KEY,
56
56
  identity_exports
57
57
  };
58
- //# sourceMappingURL=chunk-CRNEX7YH.mjs.map
58
+ //# sourceMappingURL=chunk-D25SR5FS.mjs.map
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  frontend_default as frontend_default11
3
- } from "./chunk-MHE5EBU4.mjs";
3
+ } from "./chunk-E3PJGTLI.mjs";
4
4
  import {
5
5
  frontend_default as frontend_default10
6
- } from "./chunk-6WCG6WPC.mjs";
6
+ } from "./chunk-YNHEYXDG.mjs";
7
7
  import {
8
8
  frontend_default as frontend_default8
9
- } from "./chunk-JZ3V27HQ.mjs";
9
+ } from "./chunk-U64FRQKP.mjs";
10
10
  import {
11
11
  frontend_default as frontend_default9
12
- } from "./chunk-W46L4HSP.mjs";
12
+ } from "./chunk-U6UMATPV.mjs";
13
13
  import {
14
14
  frontend_default as frontend_default6
15
15
  } from "./chunk-YFQGSDK3.mjs";
16
16
  import {
17
17
  frontend_default as frontend_default7
18
- } from "./chunk-VXSD4FK5.mjs";
18
+ } from "./chunk-ZHO2G4JR.mjs";
19
19
  import {
20
20
  frontend_default as frontend_default4
21
21
  } from "./chunk-CX5WREJC.mjs";
@@ -35,10 +35,10 @@ import {
35
35
  VIEW_PLUGIN_VERSION,
36
36
  VIEW_PRODUCT_PLUGINS,
37
37
  VIEW_WORKSPACE_CORE
38
- } from "./chunk-TTFLJHQZ.mjs";
38
+ } from "./chunk-H4UIESCF.mjs";
39
39
  import {
40
40
  FRONTEND_MODULE as FRONTEND_MODULE9
41
- } from "./chunk-CRNEX7YH.mjs";
41
+ } from "./chunk-D25SR5FS.mjs";
42
42
  import {
43
43
  FRONTEND_MODULE
44
44
  } from "./chunk-AGVLPYVE.mjs";
@@ -47,16 +47,16 @@ import {
47
47
  } from "./chunk-EWSCJF77.mjs";
48
48
  import {
49
49
  FRONTEND_MODULE as FRONTEND_MODULE7
50
- } from "./chunk-AIIYGGGC.mjs";
50
+ } from "./chunk-X4NNZ5X6.mjs";
51
51
  import {
52
52
  FRONTEND_MODULE as FRONTEND_MODULE8
53
- } from "./chunk-CWNB67UF.mjs";
53
+ } from "./chunk-FMCHH5R4.mjs";
54
54
  import {
55
55
  FRONTEND_MODULE as FRONTEND_MODULE5
56
56
  } from "./chunk-STQPRNEO.mjs";
57
57
  import {
58
58
  FRONTEND_MODULE as FRONTEND_MODULE6
59
- } from "./chunk-OHVTNEQ2.mjs";
59
+ } from "./chunk-PZIAKZJC.mjs";
60
60
  import {
61
61
  FRONTEND_MODULE as FRONTEND_MODULE3
62
62
  } from "./chunk-QUFVUMSY.mjs";
@@ -80,7 +80,7 @@ import {
80
80
  } from "./chunk-P5XMFZY4.mjs";
81
81
  import {
82
82
  shell_default
83
- } from "./chunk-7MJUWNVI.mjs";
83
+ } from "./chunk-ZGOGO7SS.mjs";
84
84
  import {
85
85
  SHELL_MODULE
86
86
  } from "./chunk-QAXALJEY.mjs";
@@ -132,4 +132,4 @@ for (const [name, plugin] of [[SHELL_MODULE, shell_default], [PRESENTATION_MODUL
132
132
  export {
133
133
  VIEW_PRODUCT_FRONTEND_CATALOG
134
134
  };
135
- //# sourceMappingURL=chunk-PG4AJFDC.mjs.map
135
+ //# sourceMappingURL=chunk-DJZGRO7W.mjs.map
@@ -93,30 +93,37 @@ function mountPlayToolbar({ document, element, client }) {
93
93
  const args = () => ({ targetId: state.play.target.targetId, targetGeneration: state.play.target.generation });
94
94
  const control = () => state?.targetBinding === "play" ? state?.preview?.camera?.control : void 0;
95
95
  const running = () => state?.play?.phase === "running" && state?.targetBinding === "play";
96
- const add = (label, run, available) => {
96
+ const add = (name, run, available) => {
97
+ const label = typeof name === "string" ? () => name : name;
97
98
  const button2 = document.createElement("button");
98
- button2.textContent = label;
99
+ button2.textContent = label();
99
100
  button2.type = "button";
100
101
  button2.className = "fx-button fx-button--compact";
101
- button2.setAttribute("data-action", `editor.${label.toLowerCase()}`);
102
+ button2.setAttribute("data-action", `editor.${label().toLowerCase()}`);
102
103
  button2.addEventListener("click", async () => {
103
- pending.add(label);
104
+ const action = label();
105
+ pending.add(action);
104
106
  errorText = "";
105
107
  render();
106
108
  try {
107
- await run();
109
+ await run(action);
108
110
  if (!disposed) state = await client.getState();
109
111
  } catch (error) {
110
112
  if (!disposed) errorText = error instanceof Error ? "hint" in error && typeof error.hint === "string" ? error.hint : error.message : String(error);
111
113
  } finally {
112
- pending.delete(label);
114
+ pending.delete(action);
113
115
  if (!disposed) render();
114
116
  }
115
117
  });
116
118
  buttons.push({ button: button2, label, available });
117
119
  toolbar.append(button2);
118
120
  };
119
- add("Play", async () => {
121
+ add(() => state?.play || pending.has("Play") ? "Stop" : "Play", async (action) => {
122
+ if (action === "Stop") {
123
+ playRequest?.abort();
124
+ if (state?.play) await client.call("play.stop", args());
125
+ return;
126
+ }
120
127
  const controller = new AbortController();
121
128
  const started = performance.now();
122
129
  const log = (stage) => console.info("[forgeax.play]", JSON.stringify({
@@ -150,11 +157,7 @@ function mountPlayToolbar({ document, element, client }) {
150
157
  playStage = "";
151
158
  if (playRequest === controller) playRequest = void 0;
152
159
  }
153
- }, () => !!state?.project && !state?.play);
154
- add("Stop", async () => {
155
- playRequest?.abort();
156
- if (state?.play) await client.call("play.stop", args());
157
- }, () => !!state?.play || pending.has("Play"));
160
+ }, () => !!state?.project || !!state?.play || pending.has("Play"));
158
161
  add("Eject", () => client.call("target.control", { ...args(), mode: "observer" }), () => running() && control() !== "observer");
159
162
  add("Possess", () => client.call("target.control", { ...args(), mode: "player" }), () => running() && control() === "observer");
160
163
  add("Editor", () => client.call("target.select", { targetId: state.editorPreview.target.targetId }), () => !!state?.editorPreview && state?.targetBinding === "play");
@@ -165,7 +168,12 @@ function mountPlayToolbar({ document, element, client }) {
165
168
  toolbar.append(status);
166
169
  const render = () => {
167
170
  for (const { button: button2, label, available } of buttons) {
168
- const disabled = pending.has(label) || pending.size > 0 && label !== "Stop" || !available();
171
+ const action = label();
172
+ if (button2.textContent !== action) {
173
+ button2.textContent = action;
174
+ button2.setAttribute("data-action", `editor.${action.toLowerCase()}`);
175
+ }
176
+ const disabled = pending.has(action) || pending.size > 0 && action !== "Stop" || !available();
169
177
  if (button2.disabled !== disabled) button2.disabled = disabled;
170
178
  }
171
179
  const target = state?.targetBinding ?? "editor";
@@ -485,4 +493,4 @@ export {
485
493
  viewViewportFrontendPlugin,
486
494
  frontend_default
487
495
  };
488
- //# sourceMappingURL=chunk-MHE5EBU4.mjs.map
496
+ //# sourceMappingURL=chunk-E3PJGTLI.mjs.map