drizzle-cube 0.2.3 → 0.2.4
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.js","sources":["../../node_modules/react-intersection-observer/dist/index.mjs","../../src/client/components/ChartErrorBoundary.tsx","../../src/client/utils/filterUtils.ts","../../src/client/components/AnalyticsPortlet.tsx","../../src/client/components/Modal.tsx","../../src/client/utils/measureIcons.tsx","../../src/client/components/QueryBuilder/CubeMetaExplorer.tsx","../../src/client/components/QueryBuilder/types.ts","../../src/client/components/QueryBuilder/FilterValueSelector.tsx","../../src/client/components/QueryBuilder/utils.ts","../../src/client/components/QueryBuilder/FilterItem.tsx","../../src/client/components/QueryBuilder/FilterGroup.tsx","../../src/client/components/QueryBuilder/FilterBuilder.tsx","../../src/client/components/QueryBuilder/DateRangeSelector.tsx","../../src/client/components/QueryBuilder/DateRangeFilter.tsx","../../src/client/components/QueryBuilder/QueryAnalysisPanel.tsx","../../src/client/components/QueryBuilder/QueryPanel.tsx","../../src/client/charts/chartConfigRegistry.ts","../../src/client/components/ChartTypeSelector.tsx","../../src/client/components/AxisDropZone.tsx","../../src/client/components/ChartConfigPanel.tsx","../../src/client/components/QueryBuilder/ResultsPanel.tsx","../../src/client/components/QueryBuilder/SetupPanel.tsx","../../src/client/components/AIAssistant/constants.ts","../../src/client/components/AIAssistant/utils.ts","../../src/client/components/AIAssistant/AIAssistantModal.tsx","../../node_modules/lz-string/libs/lz-string.js","../../src/client/components/QueryBuilder/shareUtils.ts","../../src/client/components/QueryBuilder/ShareWarningModal.tsx","../../src/client/components/QueryBuilder/index.tsx","../../src/client/components/PortletEditModal.tsx","../../src/client/components/PortletFilterConfigModal.tsx","../../src/client/components/DebugModal.tsx","../../src/client/utils/colorPalettes.ts","../../src/client/components/ColorPaletteSelector.tsx","../../src/client/components/DashboardFilters/FilterEditModal.tsx","../../src/client/components/DashboardFilters/ReadOnlyFilterList.tsx","../../src/client/components/DashboardFilters/EditModeFilterList.tsx","../../src/client/components/DashboardFilterPanel.tsx","../../src/client/components/ScaledGridWrapper.tsx","../../src/client/components/MobileStackedLayout.tsx","../../src/client/components/DashboardGrid.tsx","../../src/client/components/AnalyticsDashboard.tsx","../../src/client/components/PortletContainer.tsx","../../src/client/components/DashboardEditModal.tsx"],"sourcesContent":["\"use client\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n\n// src/InView.tsx\nimport * as React from \"react\";\n\n// src/observe.ts\nvar observerMap = /* @__PURE__ */ new Map();\nvar RootIds = /* @__PURE__ */ new WeakMap();\nvar rootId = 0;\nvar unsupportedValue;\nfunction defaultFallbackInView(inView) {\n unsupportedValue = inView;\n}\nfunction getRootId(root) {\n if (!root) return \"0\";\n if (RootIds.has(root)) return RootIds.get(root);\n rootId += 1;\n RootIds.set(root, rootId.toString());\n return RootIds.get(root);\n}\nfunction optionsToId(options) {\n return Object.keys(options).sort().filter(\n (key) => options[key] !== void 0\n ).map((key) => {\n return `${key}_${key === \"root\" ? getRootId(options.root) : options[key]}`;\n }).toString();\n}\nfunction createObserver(options) {\n const id = optionsToId(options);\n let instance = observerMap.get(id);\n if (!instance) {\n const elements = /* @__PURE__ */ new Map();\n let thresholds;\n const observer = new IntersectionObserver((entries) => {\n entries.forEach((entry) => {\n var _a2;\n const inView = entry.isIntersecting && thresholds.some((threshold) => entry.intersectionRatio >= threshold);\n if (options.trackVisibility && typeof entry.isVisible === \"undefined\") {\n entry.isVisible = inView;\n }\n (_a2 = elements.get(entry.target)) == null ? void 0 : _a2.forEach((callback) => {\n callback(inView, entry);\n });\n });\n }, options);\n thresholds = observer.thresholds || (Array.isArray(options.threshold) ? options.threshold : [options.threshold || 0]);\n instance = {\n id,\n observer,\n elements\n };\n observerMap.set(id, instance);\n }\n return instance;\n}\nfunction observe(element, callback, options = {}, fallbackInView = unsupportedValue) {\n if (typeof window.IntersectionObserver === \"undefined\" && fallbackInView !== void 0) {\n const bounds = element.getBoundingClientRect();\n callback(fallbackInView, {\n isIntersecting: fallbackInView,\n target: element,\n intersectionRatio: typeof options.threshold === \"number\" ? options.threshold : 0,\n time: 0,\n boundingClientRect: bounds,\n intersectionRect: bounds,\n rootBounds: bounds\n });\n return () => {\n };\n }\n const { id, observer, elements } = createObserver(options);\n const callbacks = elements.get(element) || [];\n if (!elements.has(element)) {\n elements.set(element, callbacks);\n }\n callbacks.push(callback);\n observer.observe(element);\n return function unobserve() {\n callbacks.splice(callbacks.indexOf(callback), 1);\n if (callbacks.length === 0) {\n elements.delete(element);\n observer.unobserve(element);\n }\n if (elements.size === 0) {\n observer.disconnect();\n observerMap.delete(id);\n }\n };\n}\n\n// src/InView.tsx\nfunction isPlainChildren(props) {\n return typeof props.children !== \"function\";\n}\nvar InView = class extends React.Component {\n constructor(props) {\n super(props);\n __publicField(this, \"node\", null);\n __publicField(this, \"_unobserveCb\", null);\n __publicField(this, \"lastInView\");\n __publicField(this, \"handleNode\", (node) => {\n if (this.node) {\n this.unobserve();\n if (!node && !this.props.triggerOnce && !this.props.skip) {\n this.setState({ inView: !!this.props.initialInView, entry: void 0 });\n this.lastInView = this.props.initialInView;\n }\n }\n this.node = node ? node : null;\n this.observeNode();\n });\n __publicField(this, \"handleChange\", (inView, entry) => {\n const previousInView = this.lastInView;\n this.lastInView = inView;\n if (previousInView === void 0 && !inView) {\n return;\n }\n if (inView && this.props.triggerOnce) {\n this.unobserve();\n }\n if (!isPlainChildren(this.props)) {\n this.setState({ inView, entry });\n }\n if (this.props.onChange) {\n this.props.onChange(inView, entry);\n }\n });\n this.state = {\n inView: !!props.initialInView,\n entry: void 0\n };\n this.lastInView = props.initialInView;\n }\n componentDidMount() {\n this.unobserve();\n this.observeNode();\n }\n componentDidUpdate(prevProps) {\n if (prevProps.rootMargin !== this.props.rootMargin || prevProps.root !== this.props.root || prevProps.threshold !== this.props.threshold || prevProps.skip !== this.props.skip || prevProps.trackVisibility !== this.props.trackVisibility || prevProps.delay !== this.props.delay) {\n this.unobserve();\n this.observeNode();\n }\n }\n componentWillUnmount() {\n this.unobserve();\n }\n observeNode() {\n if (!this.node || this.props.skip) return;\n const {\n threshold,\n root,\n rootMargin,\n trackVisibility,\n delay,\n fallbackInView\n } = this.props;\n if (this.lastInView === void 0) {\n this.lastInView = this.props.initialInView;\n }\n this._unobserveCb = observe(\n this.node,\n this.handleChange,\n {\n threshold,\n root,\n rootMargin,\n // @ts-expect-error\n trackVisibility,\n delay\n },\n fallbackInView\n );\n }\n unobserve() {\n if (this._unobserveCb) {\n this._unobserveCb();\n this._unobserveCb = null;\n }\n }\n render() {\n const { children } = this.props;\n if (typeof children === \"function\") {\n const { inView, entry } = this.state;\n return children({ inView, entry, ref: this.handleNode });\n }\n const {\n as,\n triggerOnce,\n threshold,\n root,\n rootMargin,\n onChange,\n skip,\n trackVisibility,\n delay,\n initialInView,\n fallbackInView,\n ...props\n } = this.props;\n return React.createElement(\n as || \"div\",\n { ref: this.handleNode, ...props },\n children\n );\n }\n};\n\n// src/useInView.tsx\nimport * as React2 from \"react\";\nfunction useInView({\n threshold,\n delay,\n trackVisibility,\n rootMargin,\n root,\n triggerOnce,\n skip,\n initialInView,\n fallbackInView,\n onChange\n} = {}) {\n var _a2;\n const [ref, setRef] = React2.useState(null);\n const callback = React2.useRef(onChange);\n const lastInViewRef = React2.useRef(initialInView);\n const [state, setState] = React2.useState({\n inView: !!initialInView,\n entry: void 0\n });\n callback.current = onChange;\n React2.useEffect(\n () => {\n if (lastInViewRef.current === void 0) {\n lastInViewRef.current = initialInView;\n }\n if (skip || !ref) return;\n let unobserve;\n unobserve = observe(\n ref,\n (inView, entry) => {\n const previousInView = lastInViewRef.current;\n lastInViewRef.current = inView;\n if (previousInView === void 0 && !inView) {\n return;\n }\n setState({\n inView,\n entry\n });\n if (callback.current) callback.current(inView, entry);\n if (entry.isIntersecting && triggerOnce && unobserve) {\n unobserve();\n unobserve = void 0;\n }\n },\n {\n root,\n rootMargin,\n threshold,\n // @ts-expect-error\n trackVisibility,\n delay\n },\n fallbackInView\n );\n return () => {\n if (unobserve) {\n unobserve();\n }\n };\n },\n // We break the rule here, because we aren't including the actual `threshold` variable\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n // If the threshold is an array, convert it to a string, so it won't change between renders.\n Array.isArray(threshold) ? threshold.toString() : threshold,\n ref,\n root,\n rootMargin,\n triggerOnce,\n skip,\n trackVisibility,\n fallbackInView,\n delay\n ]\n );\n const entryTarget = (_a2 = state.entry) == null ? void 0 : _a2.target;\n const previousEntryTarget = React2.useRef(void 0);\n if (!ref && entryTarget && !triggerOnce && !skip && previousEntryTarget.current !== entryTarget) {\n previousEntryTarget.current = entryTarget;\n setState({\n inView: !!initialInView,\n entry: void 0\n });\n lastInViewRef.current = initialInView;\n }\n const result = [setRef, state.inView, state.entry];\n result.ref = result[0];\n result.inView = result[1];\n result.entry = result[2];\n return result;\n}\n\n// src/useOnInView.tsx\nimport * as React3 from \"react\";\nvar _a, _b;\nvar useSyncEffect = (_b = (_a = React3.useInsertionEffect) != null ? _a : React3.useLayoutEffect) != null ? _b : React3.useEffect;\nvar useOnInView = (onIntersectionChange, {\n threshold,\n root,\n rootMargin,\n trackVisibility,\n delay,\n triggerOnce,\n skip\n} = {}) => {\n const onIntersectionChangeRef = React3.useRef(onIntersectionChange);\n const observedElementRef = React3.useRef(null);\n const observerCleanupRef = React3.useRef(void 0);\n const lastInViewRef = React3.useRef(void 0);\n useSyncEffect(() => {\n onIntersectionChangeRef.current = onIntersectionChange;\n }, [onIntersectionChange]);\n return React3.useCallback(\n (element) => {\n const cleanupExisting = () => {\n if (observerCleanupRef.current) {\n const cleanup = observerCleanupRef.current;\n observerCleanupRef.current = void 0;\n cleanup();\n }\n };\n if (element === observedElementRef.current) {\n return observerCleanupRef.current;\n }\n if (!element || skip) {\n cleanupExisting();\n observedElementRef.current = null;\n lastInViewRef.current = void 0;\n return;\n }\n cleanupExisting();\n observedElementRef.current = element;\n let destroyed = false;\n const destroyObserver = observe(\n element,\n (inView, entry) => {\n const previousInView = lastInViewRef.current;\n lastInViewRef.current = inView;\n if (previousInView === void 0 && !inView) {\n return;\n }\n onIntersectionChangeRef.current(\n inView,\n entry\n );\n if (triggerOnce && inView) {\n stopObserving();\n }\n },\n {\n threshold,\n root,\n rootMargin,\n trackVisibility,\n delay\n }\n );\n function stopObserving() {\n if (destroyed) return;\n destroyed = true;\n destroyObserver();\n observedElementRef.current = null;\n observerCleanupRef.current = void 0;\n lastInViewRef.current = void 0;\n }\n observerCleanupRef.current = stopObserving;\n return observerCleanupRef.current;\n },\n [\n Array.isArray(threshold) ? threshold.toString() : threshold,\n root,\n rootMargin,\n trackVisibility,\n delay,\n triggerOnce,\n skip\n ]\n );\n};\nexport {\n InView,\n defaultFallbackInView,\n observe,\n useInView,\n useOnInView\n};\n//# sourceMappingURL=index.mjs.map","import React, { Component, ReactNode } from 'react'\nimport { getIcon } from '../icons'\n\nconst RefreshIcon = getIcon('refresh')\n\ninterface Props {\n children: ReactNode\n fallback?: ReactNode\n portletTitle?: string\n portletConfig?: any\n cubeQuery?: string\n}\n\ninterface State {\n hasError: boolean\n error: Error | null\n errorInfo: string | null\n}\n\nexport default class ChartErrorBoundary extends Component<Props, State> {\n constructor(props: Props) {\n super(props)\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null\n }\n }\n\n static getDerivedStateFromError(error: Error): State {\n // Update state so the next render will show the fallback UI\n return {\n hasError: true,\n error,\n errorInfo: null\n }\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\n // Update state with error details\n this.setState({\n error,\n errorInfo: errorInfo.componentStack || null\n })\n\n // Log the error for debugging\n console.error('Chart Error Boundary caught a rendering error:', error, errorInfo)\n }\n\n handleReset = () => {\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null\n })\n }\n\n render() {\n if (this.state.hasError) {\n // Custom fallback UI\n if (this.props.fallback) {\n return this.props.fallback\n }\n\n // Default error display\n return (\n <div className=\"flex flex-col items-center justify-center w-full h-full p-6 text-center border border-dashed rounded-lg\"\n style={{ borderColor: 'var(--dc-border)', backgroundColor: 'var(--dc-surface)' }}>\n <div className=\"h-12 w-12 mb-4 text-dc-text-muted\">⚠️</div>\n <h3 className=\"text-lg font-semibold mb-2 text-dc-text\">\n {this.props.portletTitle ? `Unable to render ${this.props.portletTitle}` : 'Unable to render chart'}\n </h3>\n <p className=\"text-sm text-dc-text-secondary mb-4 max-w-md\">\n There was an error rendering this chart component. The error details are shown below.\n </p>\n\n {/* Error details */}\n <div className=\"w-full max-w-2xl mb-4\">\n <div className=\"bg-dc-surface-secondary rounded-lg p-3 text-left\">\n <div className=\"text-xs font-mono mb-2 text-dc-text\">\n <strong>Error:</strong> {this.state.error?.message}\n </div>\n {this.state.error?.name && (\n <div className=\"text-xs font-mono text-dc-text-secondary mb-2\">\n <strong>Type:</strong> {this.state.error.name}\n </div>\n )}\n\n {/* Portlet Config Debug Info */}\n {this.props.portletConfig && (\n <details className=\"text-xs font-mono text-dc-text-secondary mb-2\">\n <summary className=\"cursor-pointer\">Portlet Configuration</summary>\n <pre className=\"mt-2 whitespace-pre-wrap p-2 rounded-sm overflow-auto max-h-32\"\n style={{ backgroundColor: 'rgba(var(--dc-primary-rgb), 0.1)' }}>\n {JSON.stringify(this.props.portletConfig, null, 2)}\n </pre>\n </details>\n )}\n\n {/* Cube Query Debug Info */}\n {this.props.cubeQuery && (\n <details className=\"text-xs font-mono text-dc-text-secondary mb-2\">\n <summary className=\"cursor-pointer\">Cube Query</summary>\n <pre className=\"mt-2 whitespace-pre-wrap p-2 rounded-sm overflow-auto max-h-32\"\n style={{ backgroundColor: '#d1fae5' }}>\n {typeof this.props.cubeQuery === 'string' \n ? JSON.stringify(JSON.parse(this.props.cubeQuery), null, 2)\n : JSON.stringify(this.props.cubeQuery, null, 2)\n }\n </pre>\n </details>\n )}\n\n {this.state.errorInfo && (\n <details className=\"text-xs font-mono text-dc-text-secondary\">\n <summary className=\"cursor-pointer\">Component Stack</summary>\n <pre className=\"mt-2 whitespace-pre-wrap\">{this.state.errorInfo}</pre>\n </details>\n )}\n </div>\n </div>\n\n {/* Reset button */}\n <button\n onClick={this.handleReset}\n className=\"px-3 py-1 text-white rounded-sm text-sm hover:opacity-90 transition-opacity\"\n style={{\n backgroundColor: 'var(--dc-primary)'\n }}\n >\n <RefreshIcon style={{ width: '16px', height: '16px', display: 'inline', marginRight: '4px' }} />Try Again\n </button>\n </div>\n )\n }\n\n return this.props.children\n }\n}","/**\n * Filter utility functions for dashboard-level filtering\n */\n\nimport type { Filter, DashboardFilter, CubeMeta, GroupFilter, DashboardConfig, SimpleFilter } from '../types'\n\n/**\n * Check if a filter should be included in the query (has valid values or doesn't require values)\n * @param filter - The filter to check\n * @returns true if the filter should be included, false otherwise\n */\nfunction shouldIncludeFilter(filter: Filter): boolean {\n // Handle SimpleFilter\n if ('member' in filter && 'operator' in filter) {\n const simpleFilter = filter as SimpleFilter\n\n // Operators that don't require values\n const noValueOperators = ['set', 'notSet', 'isEmpty', 'isNotEmpty']\n if (noValueOperators.includes(simpleFilter.operator)) {\n return true\n }\n\n // For inDateRange, check if dateRange is provided as alternative to values\n if (simpleFilter.operator === 'inDateRange' && simpleFilter.dateRange) {\n return true\n }\n\n // For other operators, check if values exist and are non-empty\n return !!(simpleFilter.values && simpleFilter.values.length > 0)\n }\n\n // Handle GroupFilter - recursively check nested filters\n if ('type' in filter && 'filters' in filter) {\n const groupFilter = filter as GroupFilter\n // Include group filter if at least one nested filter is valid\n const validFilters = groupFilter.filters.filter(f => shouldIncludeFilter(f))\n return validFilters.length > 0\n }\n\n return false\n}\n\n/**\n * Get dashboard filters that should be applied to a portlet based on its mapping configuration\n * @param dashboardFilters - All available dashboard filters\n * @param filterMapping - Array of filter IDs that apply to this portlet\n * @returns Array of filters that should be applied to the portlet\n */\nexport function getApplicableDashboardFilters(\n dashboardFilters: DashboardFilter[] | undefined,\n filterMapping: string[] | undefined\n): Filter[] {\n if (!dashboardFilters || !dashboardFilters.length) {\n return []\n }\n\n // If no mapping is specified, no dashboard filters apply\n if (!filterMapping || !filterMapping.length) {\n return []\n }\n\n // Return filters that are in the mapping AND have valid values\n return dashboardFilters\n .filter(df => filterMapping.includes(df.id))\n .filter(df => shouldIncludeFilter(df.filter))\n .map(df => df.filter)\n}\n\n/**\n * Merge dashboard filters with portlet filters using AND logic\n * Dashboard filters are combined with portlet filters so both sets of filters apply\n * @param dashboardFilters - Filters from dashboard-level configuration\n * @param portletFilters - Filters from portlet query\n * @returns Merged filter array with AND logic\n */\n/**\n * Convert GroupFilter format to server format\n * GroupFilter: { type: 'and', filters: [...] }\n * Server format: { and: [...] } or { or: [...] }\n */\nfunction convertToServerFormat(filter: Filter): any {\n // Handle GroupFilter format\n if ('type' in filter && 'filters' in filter) {\n const groupFilter = filter as GroupFilter\n const convertedFilters = groupFilter.filters.map(convertToServerFormat)\n\n if (groupFilter.type === 'and') {\n return { and: convertedFilters }\n } else {\n return { or: convertedFilters }\n }\n }\n\n // Simple filter - return as-is\n return filter\n}\n\nexport function mergeDashboardAndPortletFilters(\n dashboardFilters: Filter[],\n portletFilters: Filter[] | undefined\n): Filter[] | undefined {\n // If no dashboard filters, return portlet filters as-is\n if (!dashboardFilters || dashboardFilters.length === 0) {\n return portletFilters\n }\n\n // If no portlet filters, return dashboard filters\n if (!portletFilters || portletFilters.length === 0) {\n return dashboardFilters\n }\n\n // Both exist - need to merge with AND logic\n // We need to combine them in a way that both sets of filters apply\n\n // Flatten both filter arrays and convert to server format\n const allFilters = [...dashboardFilters, ...portletFilters].map(convertToServerFormat)\n\n // Wrap all filters in a single AND group using server format\n return [{\n and: allFilters\n } as any]\n}\n\n/**\n * Check if a filter field exists in the cube metadata\n * This helps identify filters that might not apply to a specific portlet's data\n * @param filter - The filter to validate\n * @param cubeMeta - Cube metadata to validate against\n * @returns true if the filter field exists in any cube's measures or dimensions\n */\nexport function validateFilterForCube(\n filter: Filter,\n cubeMeta: CubeMeta | null\n): boolean {\n if (!cubeMeta || !cubeMeta.cubes) {\n // If no metadata available, assume filter is valid (fail open)\n return true\n }\n\n // Extract member names from filter recursively\n const memberNames = extractMemberNamesFromFilter(filter)\n\n // Check if any of the member names exist in cube metadata\n return memberNames.some(memberName => {\n return cubeMeta.cubes.some(cube => {\n // Check measures\n const inMeasures = cube.measures?.some(m => m.name === memberName) ?? false\n // Check dimensions\n const inDimensions = cube.dimensions?.some(d => d.name === memberName) ?? false\n\n return inMeasures || inDimensions\n })\n })\n}\n\n/**\n * Extract all member names from a filter (handles nested group filters)\n * @param filter - The filter to extract members from\n * @returns Array of member names\n */\nfunction extractMemberNamesFromFilter(filter: Filter): string[] {\n if ('member' in filter) {\n // SimpleFilter\n return [filter.member]\n } else if ('type' in filter && 'filters' in filter) {\n // GroupFilter - recursively extract from nested filters\n return filter.filters.flatMap(f => extractMemberNamesFromFilter(f))\n }\n\n return []\n}\n\n/**\n * Validate that all dashboard filters in a portlet's mapping exist and are valid\n * @param dashboardFilters - All available dashboard filters\n * @param filterMapping - The portlet's filter mapping\n * @param cubeMeta - Cube metadata for validation\n * @returns Object with validation result and list of invalid filter IDs\n */\nexport function validatePortletFilterMapping(\n dashboardFilters: DashboardFilter[] | undefined,\n filterMapping: string[] | undefined,\n cubeMeta: CubeMeta | null\n): { isValid: boolean; invalidFilterIds: string[]; missingFilterIds: string[] } {\n if (!filterMapping || !filterMapping.length) {\n return { isValid: true, invalidFilterIds: [], missingFilterIds: [] }\n }\n\n if (!dashboardFilters || !dashboardFilters.length) {\n // Mapping references filters that don't exist\n return {\n isValid: false,\n invalidFilterIds: [],\n missingFilterIds: filterMapping\n }\n }\n\n const invalidFilterIds: string[] = []\n const missingFilterIds: string[] = []\n\n filterMapping.forEach(filterId => {\n const dashboardFilter = dashboardFilters.find(df => df.id === filterId)\n\n if (!dashboardFilter) {\n // Filter ID in mapping doesn't exist in dashboard filters\n missingFilterIds.push(filterId)\n } else {\n // Check if filter is valid for the cube metadata\n const isValid = validateFilterForCube(dashboardFilter.filter, cubeMeta)\n if (!isValid) {\n invalidFilterIds.push(filterId)\n }\n }\n })\n\n return {\n isValid: invalidFilterIds.length === 0 && missingFilterIds.length === 0,\n invalidFilterIds,\n missingFilterIds\n }\n}\n\n/**\n * Extract all unique measures, dimensions, and timeDimensions used across all portlets in a dashboard\n * This helps create a filtered schema view showing only fields relevant to the dashboard\n * @param dashboardConfig - Dashboard configuration\n * @returns Object with unique measures, dimensions, and timeDimensions\n */\nexport function extractDashboardFields(\n dashboardConfig: DashboardConfig\n): { measures: Set<string>; dimensions: Set<string>; timeDimensions: Set<string> } {\n const measures = new Set<string>()\n const dimensions = new Set<string>()\n const timeDimensions = new Set<string>()\n\n // Iterate through all portlets\n dashboardConfig.portlets.forEach(portlet => {\n try {\n // Parse the query JSON\n const query = JSON.parse(portlet.query)\n\n // Extract measures\n if (query.measures && Array.isArray(query.measures)) {\n query.measures.forEach((measure: string) => measures.add(measure))\n }\n\n // Extract dimensions\n if (query.dimensions && Array.isArray(query.dimensions)) {\n query.dimensions.forEach((dimension: string) => dimensions.add(dimension))\n }\n\n // Extract timeDimensions\n if (query.timeDimensions && Array.isArray(query.timeDimensions)) {\n query.timeDimensions.forEach((td: any) => {\n if (td.dimension) {\n timeDimensions.add(td.dimension)\n }\n })\n }\n\n // Also extract from filters to catch any filtered fields\n if (query.filters) {\n extractFieldsFromFilters(query.filters).forEach(field => {\n // Try to determine if it's a measure, dimension, or timeDimension\n // by checking cube metadata or convention (add to dimensions by default)\n dimensions.add(field)\n })\n }\n } catch (e) {\n // Skip portlets with invalid query JSON\n console.warn('Failed to parse portlet query:', portlet.id, e)\n }\n })\n\n return { measures, dimensions, timeDimensions }\n}\n\n/**\n * Extract field names from filters recursively\n * @param filters - Filter array\n * @returns Array of unique field names\n */\nfunction extractFieldsFromFilters(filters: Filter[]): string[] {\n const fields: string[] = []\n\n filters.forEach(filter => {\n if ('member' in filter) {\n // SimpleFilter\n fields.push(filter.member)\n } else if ('type' in filter && 'filters' in filter) {\n // GroupFilter - recurse\n fields.push(...extractFieldsFromFilters(filter.filters))\n }\n })\n\n return [...new Set(fields)] // Return unique fields\n}\n\n/**\n * Time dimension type from CubeQuery\n */\ntype TimeDimension = {\n dimension: string\n granularity?: string\n dateRange?: string[] | string\n}\n\n/**\n * Helper to get date range from a SimpleFilter (backward compatible)\n * Reads from both dateRange and values for compatibility\n * Handles both:\n * - Preset ranges: [\"this quarter\"], [\"last 7 days\"] (single string value)\n * - Custom ranges: [\"2024-01-01\", \"2024-12-31\"] (two date values)\n */\nfunction getDateRangeFromFilter(filter: SimpleFilter): string[] | string | undefined {\n // Prefer dateRange for backward compatibility, fall back to values\n if (filter.dateRange) {\n return filter.dateRange\n }\n if (filter.values && filter.values.length > 0) {\n // Single value = preset like \"this quarter\", return as string\n // Multiple values = custom date range, return as array\n return filter.values.length === 1 ? filter.values[0] : filter.values\n }\n return undefined\n}\n\n/**\n * Apply universal time filters to a portlet's timeDimensions\n * Universal time filters apply their dateRange to ALL time dimensions in the portlet\n *\n * @param dashboardFilters - All dashboard filters\n * @param filterMapping - Filter IDs that apply to this portlet\n * @param portletTimeDimensions - The portlet's existing timeDimensions array\n * @returns Updated timeDimensions array with date ranges applied\n */\nexport function applyUniversalTimeFilters(\n dashboardFilters: DashboardFilter[] | undefined,\n filterMapping: string[] | undefined,\n portletTimeDimensions: TimeDimension[] | undefined\n): TimeDimension[] | undefined {\n // Return as-is if no time dimensions in portlet (skip silently)\n if (!portletTimeDimensions || portletTimeDimensions.length === 0) {\n return portletTimeDimensions\n }\n\n // If no mapping specified, no filters apply\n if (!filterMapping || filterMapping.length === 0) {\n return portletTimeDimensions\n }\n\n // Find applicable universal time filters that have valid date ranges\n const universalTimeFilters = dashboardFilters\n ?.filter(df => df.isUniversalTime && filterMapping.includes(df.id))\n ?.filter(df => {\n // Must be a SimpleFilter with a valid dateRange\n if (!('member' in df.filter)) return false\n const simpleFilter = df.filter as SimpleFilter\n const dateRange = getDateRangeFromFilter(simpleFilter)\n return dateRange !== undefined\n })\n\n if (!universalTimeFilters || universalTimeFilters.length === 0) {\n return portletTimeDimensions\n }\n\n // Use the first universal time filter's dateRange (typically only one)\n const timeFilter = universalTimeFilters[0]\n const simpleFilter = timeFilter.filter as SimpleFilter\n const dateRange = getDateRangeFromFilter(simpleFilter)\n\n // Apply dateRange to ALL time dimensions (dashboard wins - overrides portlet dateRange)\n return portletTimeDimensions.map(td => ({\n ...td,\n dateRange: dateRange\n }))\n}\n","/**\n * Analytics Portlet Component\n * Simplified version with minimal dependencies\n */\n\nimport { useMemo, useState, forwardRef, useImperativeHandle, useEffect, useRef } from 'react'\nimport { useInView } from 'react-intersection-observer'\nimport { useCubeQuery } from '../hooks/useCubeQuery'\nimport { useScrollContainer } from '../providers/ScrollContainerContext'\nimport ChartErrorBoundary from './ChartErrorBoundary'\nimport LoadingIndicator from './LoadingIndicator'\nimport { LazyChart, isValidChartType } from '../charts/ChartLoader'\nimport { useChartConfig } from '../charts/lazyChartConfigRegistry'\nimport type { AnalyticsPortletProps } from '../types'\nimport { getApplicableDashboardFilters, mergeDashboardAndPortletFilters, applyUniversalTimeFilters } from '../utils/filterUtils'\n\n\ninterface AnalyticsPortletRef {\n refresh: () => void\n}\n\nconst AnalyticsPortlet = forwardRef<AnalyticsPortletRef, AnalyticsPortletProps>(({\n query,\n chartType,\n chartConfig,\n displayConfig,\n dashboardFilters,\n dashboardFilterMapping,\n eagerLoad = false,\n isVisible: _isVisible, // Deprecated - visibility now handled internally via useInView\n height = 300,\n title: _title,\n colorPalette,\n loadingComponent,\n onDebugDataReady\n}, ref) => {\n const [refreshCounter, setRefreshCounter] = useState(0)\n const onDebugDataReadyRef = useRef(onDebugDataReady)\n\n // Lazy loading: Use IntersectionObserver to detect when portlet is visible\n // Get scroll container from context (null = viewport, element = container scroll)\n const scrollContainer = useScrollContainer()\n const { ref: inViewRef, inView } = useInView({\n root: scrollContainer,\n rootMargin: '200px', // Start loading 200px before entering viewport\n triggerOnce: true, // Once visible, stay \"visible\" (don't unload data)\n initialInView: false, // Start as not visible, let observer determine actual state\n skip: eagerLoad // Skip observation entirely if eagerLoad is true\n })\n\n // Effective visibility: eagerLoad forces visible, otherwise use inView from IntersectionObserver\n // Note: Batching is handled by BatchCoordinator which collects queries for 100ms before flushing\n const isVisible = eagerLoad || inView\n\n // Update ref when callback changes\n useEffect(() => {\n onDebugDataReadyRef.current = onDebugDataReady\n }, [onDebugDataReady])\n\n // Check if this chart type skips queries (using lazy-loaded config)\n const { config: chartTypeConfig } = useChartConfig(chartType)\n const shouldSkipQuery = chartTypeConfig.skipQuery === true\n\n // Parse query from JSON string, merge dashboard filters, and include refresh counter to force re-query\n const queryObject = useMemo(() => {\n // Skip query parsing for charts that don't need queries\n if (shouldSkipQuery) {\n return null\n }\n\n try {\n const parsed = JSON.parse(query)\n\n // Get applicable dashboard filters (excluding universal time filters - they apply to timeDimensions)\n const regularFilters = dashboardFilters?.filter(df => !df.isUniversalTime)\n const applicableFilters = getApplicableDashboardFilters(regularFilters, dashboardFilterMapping)\n\n // Merge dashboard filters with portlet filters\n const mergedFilters = mergeDashboardAndPortletFilters(applicableFilters, parsed.filters)\n\n // Apply universal time filters to timeDimensions (dashboard wins over portlet dateRange)\n const mergedTimeDimensions = applyUniversalTimeFilters(\n dashboardFilters,\n dashboardFilterMapping,\n parsed.timeDimensions\n )\n\n return {\n ...parsed,\n filters: mergedFilters,\n timeDimensions: mergedTimeDimensions,\n __refresh_counter: refreshCounter\n }\n } catch (e) {\n console.error('AnalyticsPortlet: Invalid query JSON:', e)\n return null\n }\n }, [query, refreshCounter, shouldSkipQuery, dashboardFilters, dashboardFilterMapping])\n\n // Use the cube React hook (skip for charts that don't need queries or not visible for lazy loading)\n // Priority: shouldSkipQuery (chart type) > eagerLoad override > isVisible (lazy loading)\n const shouldSkip = !queryObject || shouldSkipQuery || (!eagerLoad && !isVisible)\n\n const { resultSet, isLoading, error } = useCubeQuery(queryObject, {\n skip: shouldSkip,\n resetResultSetOnChange: true\n })\n\n // Expose refresh function through ref\n useImperativeHandle(ref, () => ({\n refresh: () => {\n setRefreshCounter(prev => prev + 1)\n }\n }), [])\n\n\n // Send debug data to parent when ready (must be before any returns)\n useEffect(() => {\n if (onDebugDataReadyRef.current && chartConfig && queryObject && resultSet && !error) {\n const getData = () => {\n switch (chartType) {\n case 'pie':\n case 'table':\n return resultSet.tablePivot()\n default:\n return resultSet.rawData()\n }\n }\n const data = getData()\n \n if (data) {\n onDebugDataReadyRef.current({\n chartConfig: chartConfig || {},\n displayConfig: displayConfig || {},\n queryObject,\n data,\n chartType\n })\n }\n }\n }, [chartConfig, displayConfig, queryObject, resultSet, chartType, error]) // Use ref for callback to prevent infinite loops\n\n // Validate that chartConfig is provided when required (not required for skipQuery charts)\n // Check if any dropZones are mandatory for this chart type\n const hasMandatoryFields = !shouldSkipQuery && chartTypeConfig.dropZones.some(zone => zone.mandatory === true)\n \n if (!chartConfig && hasMandatoryFields) {\n return (\n <div ref={inViewRef} className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Required</div>\n <div className=\"text-xs text-dc-text-secondary\">Please configure this chart</div>\n </div>\n </div>\n )\n }\n\n // Show placeholder for lazy-loaded portlets that aren't visible yet\n if (!shouldSkipQuery && !eagerLoad && !isVisible) {\n return (\n <div ref={inViewRef} className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"w-8 h-8 mx-auto mb-2 rounded-full bg-dc-surface-secondary animate-pulse\" />\n <div className=\"text-xs text-dc-text-secondary\">Scroll to load</div>\n </div>\n </div>\n )\n }\n\n // Skip loading and error handling for charts that don't need queries\n if (!shouldSkipQuery) {\n if (isLoading || (queryObject && !resultSet && !error)) {\n return (\n <div ref={inViewRef} className=\"flex items-center justify-center w-full\" style={{ height }}>\n {loadingComponent || <LoadingIndicator size=\"md\" />}\n </div>\n )\n }\n\n if (error) {\n return (\n <div ref={inViewRef} className=\"p-4 border rounded-sm\" style={{ height, borderColor: 'var(--dc-border)', backgroundColor: 'var(--dc-surface)' }}>\n <div className=\"mb-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-medium text-sm\" style={{ color: 'var(--dc-text)' }}>⚠️ Query Error</span>\n <button\n onClick={() => setRefreshCounter(prev => prev + 1)}\n className=\"px-2 py-1 text-white rounded-sm text-xs\"\n style={{ backgroundColor: 'var(--dc-primary)' }}\n >\n Retry\n </button>\n </div>\n </div>\n\n <div className=\"mb-3\">\n <div className=\"text-xs p-2 rounded-sm border\" style={{ color: 'var(--dc-text-secondary)', backgroundColor: 'var(--dc-surface)', borderColor: 'var(--dc-border)' }}>\n {error.message || error.toString()}\n </div>\n </div>\n\n <div className=\"space-y-2 text-xs\">\n <details>\n <summary className=\"cursor-pointer font-medium\" style={{ color: 'var(--dc-text-secondary)' }}>Query (with filters applied)</summary>\n <pre className=\"mt-1 p-2 rounded-sm text-xs overflow-auto max-h-20\" style={{ backgroundColor: 'rgba(var(--dc-primary-rgb), 0.1)' }}>\n {queryObject ? JSON.stringify(queryObject, null, 2) : query}\n </pre>\n </details>\n\n <details>\n <summary className=\"cursor-pointer font-medium\" style={{ color: 'var(--dc-text-secondary)' }}>Chart Config</summary>\n <pre className=\"mt-1 p-2 rounded-sm text-xs overflow-auto max-h-20\" style={{ backgroundColor: 'rgba(var(--dc-primary-rgb), 0.05)' }}>\n {JSON.stringify({\n chartType,\n chartConfig,\n displayConfig: displayConfig\n }, null, 2)}\n </pre>\n </details>\n </div>\n </div>\n )\n }\n\n if (!resultSet || !queryObject) {\n return (\n <div ref={inViewRef} className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No data available</div>\n <div className=\"text-xs\">Invalid query or no results</div>\n </div>\n </div>\n )\n }\n }\n\n // Get data based on chart type needs\n const getData = () => {\n // Return empty array for charts that don't use query data\n if (shouldSkipQuery) {\n return []\n }\n \n // Return empty array if no resultSet\n if (!resultSet) {\n return []\n }\n \n switch (chartType) {\n case 'pie':\n case 'table':\n return resultSet.tablePivot()\n default:\n return resultSet.rawData()\n }\n }\n\n const data = getData()\n\n // Render appropriate chart component using lazy loading\n // Each chart type is dynamically imported for code splitting\n const renderChart = () => {\n try {\n const chartHeight = height\n\n // Handle unsupported chart types\n if (!isValidChartType(chartType)) {\n return (\n <div className=\"flex items-center justify-center w-full\" style={{ height }}>\n <div className=\"text-center text-dc-text-muted\">\n <div className=\"text-sm font-semibold mb-1\">Unsupported chart type</div>\n <div className=\"text-xs\">{chartType}</div>\n </div>\n </div>\n )\n }\n\n // For markdown chart, use empty data array\n const chartData = chartType === 'markdown' ? [] : data\n\n return (\n <LazyChart\n chartType={chartType}\n data={chartData}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n queryObject={queryObject ?? undefined}\n height={chartHeight}\n colorPalette={colorPalette}\n fallback={\n <div\n className=\"flex items-center justify-center w-full\"\n style={{ height: typeof chartHeight === 'number' ? `${chartHeight}px` : chartHeight }}\n >\n <div className=\"animate-pulse bg-dc-surface-secondary rounded w-full h-full min-h-[100px]\" />\n </div>\n }\n />\n )\n } catch (error) {\n console.error('Chart rendering error:', error)\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted p-4\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Unable to render chart</div>\n <div className=\"text-xs text-dc-text-secondary\">{error instanceof Error ? error.message : 'Unknown error'}</div>\n </div>\n </div>\n )\n }\n }\n\n return (\n <div ref={inViewRef} className=\"w-full h-full\">\n <ChartErrorBoundary\n portletTitle={_title}\n portletConfig={{\n chartType,\n chartConfig,\n displayConfig,\n height\n }}\n cubeQuery={query}\n >\n <div className=\"w-full h-full flex flex-col flex-1\" style={{ minHeight: '200px' }}>\n {renderChart()}\n </div>\n </ChartErrorBoundary>\n </div>\n )\n})\n\nAnalyticsPortlet.displayName = 'AnalyticsPortlet'\n\nexport default AnalyticsPortlet","import React, { useEffect, useCallback } from 'react'\n\nexport interface ModalProps {\n isOpen: boolean\n onClose: () => void\n title?: string\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'full' | 'fullscreen' | 'fullscreen-mobile'\n closeOnBackdropClick?: boolean\n closeOnEscape?: boolean\n showCloseButton?: boolean\n className?: string\n children: React.ReactNode\n footer?: React.ReactNode\n noPadding?: boolean\n}\n\nconst Modal: React.FC<ModalProps> = ({\n isOpen,\n onClose,\n title,\n size = 'md',\n closeOnBackdropClick = true,\n closeOnEscape = true,\n showCloseButton = true,\n children,\n footer,\n noPadding = false\n}) => {\n // Handle ESC key press\n const handleEscapeKey = useCallback((event: KeyboardEvent) => {\n if (event.key === 'Escape' && closeOnEscape) {\n onClose()\n }\n }, [closeOnEscape, onClose])\n\n\n // Manage ESC key listener and body scroll\n useEffect(() => {\n if (isOpen) {\n // Add ESC key listener\n if (closeOnEscape) {\n document.addEventListener('keydown', handleEscapeKey)\n }\n\n // Prevent body scroll when modal is open\n document.body.style.overflow = 'hidden'\n } else {\n // Restore body scroll\n document.body.style.overflow = 'unset'\n }\n\n // Cleanup\n return () => {\n document.removeEventListener('keydown', handleEscapeKey)\n document.body.style.overflow = 'unset'\n }\n }, [isOpen, closeOnEscape, handleEscapeKey])\n\n\n if (!isOpen) return null\n\n const getSizeClasses = () => {\n switch (size) {\n case 'sm':\n return 'max-w-md'\n case 'md':\n return 'max-w-lg'\n case 'lg':\n return 'max-w-2xl'\n case 'xl':\n return 'max-w-6xl'\n case 'xxl':\n return 'max-w-[1400px]' // Good for retina/mac displays\n case 'full':\n return 'max-w-7xl'\n case 'fullscreen':\n return 'w-[90vw] h-[90vh] max-w-none'\n case 'fullscreen-mobile':\n return 'w-full h-full md:w-[min(90vw,1400px)] md:h-[90vh]'\n default:\n return 'max-w-lg'\n }\n }\n\n return (\n <div\n className={`fixed inset-0 z-50 backdrop-blur-md ${size === 'fullscreen-mobile' ? 'flex md:flex md:items-center md:justify-center' : 'flex items-center justify-center'}`}\n style={{ backgroundColor: 'var(--dc-overlay)' }}\n onClick={closeOnBackdropClick ? onClose : undefined}\n >\n <div\n className={`relative bg-dc-surface border border-dc-border ${size === 'fullscreen-mobile' ? 'rounded-none md:rounded-lg' : 'rounded-lg'} ${size === 'fullscreen' || size === 'fullscreen-mobile' ? '' : 'mx-4'} ${getSizeClasses()} ${size === 'fullscreen' || size === 'fullscreen-mobile' ? '' : 'max-h-[90vh]'} flex flex-col`}\n style={{ boxShadow: 'var(--dc-shadow-2xl)' }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? 'modal-title' : undefined}\n >\n {/* Header */}\n {(title || showCloseButton) && (\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-dc-border\">\n {title && (\n <h2 id=\"modal-title\" className=\"text-xl font-semibold text-dc-text\">\n {title}\n </h2>\n )}\n {showCloseButton && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-dc-text-muted hover:text-dc-text-secondary transition-colors p-2 -mr-2\"\n aria-label=\"Close modal\"\n >\n <svg width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n )}\n </div>\n )}\n\n {/* Content */}\n <div className={`flex-1 overflow-y-auto ${noPadding ? '' : 'px-6 py-4'}`}>\n {children}\n </div>\n\n {/* Footer */}\n {footer && (\n <div className=\"flex items-center justify-end space-x-3 px-6 py-4 border-t border-dc-border bg-dc-surface-secondary\">\n {footer}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default Modal","import React from 'react'\nimport { getMeasureTypeIcon } from '../icons'\n\n/**\n * Get the appropriate icon component for a given measure type\n * All icons use amber coloring for consistency\n */\nexport function getMeasureIcon(\n measureType: string | undefined,\n className: string = 'w-4 h-4'\n): React.ReactElement {\n const IconComponent = getMeasureTypeIcon(measureType)\n return <IconComponent className={className} />\n}\n\n/**\n * Get all available measure type icons\n * Useful for documentation or UI that shows all measure types\n */\nexport function getAllMeasureIcons(): Record<string, React.ReactElement> {\n const types = ['count', 'countDistinct', 'countDistinctApprox', 'sum', 'avg', 'min', 'max', 'runningTotal', 'calculated', 'number']\n const icons: Record<string, React.ReactElement> = {}\n\n for (const type of types) {\n const IconComponent = getMeasureTypeIcon(type)\n icons[type] = <IconComponent className=\"w-4 h-4\" />\n }\n\n return icons\n}\n","/**\n * CubeMetaExplorer Component\n * \n * Displays the cube schema in a collapsible tree view.\n * Users can click on dimensions, measures, and time dimensions to add them to their query.\n */\n\nimport React, { useState, Suspense, lazy } from 'react'\nimport type { CubeMetaExplorerProps, MetaCube, MetaField } from './types'\nimport { getMeasureIcon } from '../../utils/measureIcons'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport { getIcon } from '../../icons'\n\n// Lazy load the relationship diagram (imports reactflow which is large)\nconst CubeRelationshipDiagram = lazy(() =>\n import('../CubeRelationshipDiagram').then(mod => ({ default: mod.CubeRelationshipDiagram }))\n)\n\ntype SchemaViewType = 'tree' | 'diagram'\n\nconst CubeMetaExplorer: React.FC<CubeMetaExplorerProps> = ({\n schema,\n schemaStatus,\n schemaError,\n selectedFields,\n onFieldSelect,\n onFieldDeselect,\n onRetrySchema,\n onOpenSettings,\n onViewTypeChange,\n isExpanded = false\n}) => {\n // Get icons\n const ChevronDownIcon = getIcon('chevronDown')\n const ChevronRightIcon = getIcon('chevronRight')\n const WarningIcon = getIcon('warning')\n const RefreshIcon = getIcon('refresh')\n const SettingsIcon = getIcon('settings')\n const MeasureIcon = getIcon('measure')\n const DimensionIcon = getIcon('dimension')\n const TimeDimensionIcon = getIcon('timeDimension')\n const SegmentIcon = getIcon('segment')\n const MenuIcon = getIcon('menu')\n\n // Get features from context to check if schema diagram is enabled\n const { features } = useCubeContext()\n const showSchemaDiagram = features?.showSchemaDiagram === true\n\n const [expandedCubes, setExpandedCubes] = useState<Set<string>>(new Set())\n const [expandedSections, setExpandedSections] = useState<Set<string>>(new Set())\n const [searchTerm, setSearchTerm] = useState('')\n const [viewType, setViewType] = useState<SchemaViewType>('tree')\n\n // Track the original expansion state before search\n const [preSearchExpandedCubes, setPreSearchExpandedCubes] = useState<Set<string> | null>(null)\n const [preSearchExpandedSections, setPreSearchExpandedSections] = useState<Set<string> | null>(null)\n\n // Auto-switch to diagram view when expanded (only if schema diagram is enabled)\n React.useEffect(() => {\n if (isExpanded && showSchemaDiagram) {\n setViewType('diagram')\n }\n }, [isExpanded, showSchemaDiagram])\n\n // Auto-expand cubes and sections that contain search matches\n React.useEffect(() => {\n if (!schema) {\n return\n }\n\n const hasSearchTerm = searchTerm.trim().length > 0\n\n if (hasSearchTerm) {\n // Save current state before expanding for search (only if not already saved)\n if (preSearchExpandedCubes === null) {\n setPreSearchExpandedCubes(new Set(expandedCubes))\n setPreSearchExpandedSections(new Set(expandedSections))\n }\n\n const newExpandedCubes = new Set<string>()\n const newExpandedSections = new Set<string>()\n\n schema.cubes.forEach((cube: MetaCube) => {\n let cubeHasMatches = false\n\n // Check measures\n const matchingMeasures = cube.measures.filter(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n if (matchingMeasures.length > 0) {\n cubeHasMatches = true\n newExpandedSections.add(`${cube.name}-measures`)\n }\n\n // Check regular dimensions\n const regularDimensions = cube.dimensions.filter(d => d.type !== 'time')\n const matchingDimensions = regularDimensions.filter(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n if (matchingDimensions.length > 0) {\n cubeHasMatches = true\n newExpandedSections.add(`${cube.name}-dimensions`)\n }\n\n // Check time dimensions\n const timeDimensions = cube.dimensions.filter(d => d.type === 'time')\n const matchingTimeDimensions = timeDimensions.filter(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n if (matchingTimeDimensions.length > 0) {\n cubeHasMatches = true\n newExpandedSections.add(`${cube.name}-timeDimensions`)\n }\n\n // If cube has any matches, expand it\n if (cubeHasMatches) {\n newExpandedCubes.add(cube.name)\n }\n })\n\n // Combine pre-search state with search expansions\n const combinedCubes = new Set([...(preSearchExpandedCubes || []), ...newExpandedCubes])\n const combinedSections = new Set([...(preSearchExpandedSections || []), ...newExpandedSections])\n \n setExpandedCubes(combinedCubes)\n setExpandedSections(combinedSections)\n } else {\n // No search term - restore original state if we have it saved\n if (preSearchExpandedCubes !== null && preSearchExpandedSections !== null) {\n setExpandedCubes(preSearchExpandedCubes)\n setExpandedSections(preSearchExpandedSections)\n setPreSearchExpandedCubes(null)\n setPreSearchExpandedSections(null)\n }\n }\n }, [schema, searchTerm, preSearchExpandedCubes, preSearchExpandedSections])\n\n // Loading state\n if (schemaStatus === 'loading') {\n return (\n <div className=\"h-full flex items-center justify-center text-dc-text-muted\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 mx-auto mb-3\" style={{ borderBottomColor: 'var(--dc-primary)' }}></div>\n <div className=\"text-sm font-semibold mb-1\">Loading Schema...</div>\n <div className=\"text-xs\">Fetching cube metadata</div>\n </div>\n </div>\n )\n }\n\n // Error state\n if (schemaStatus === 'error') {\n const isCorsError = schemaError?.toLowerCase().includes('cors') || \n schemaError?.toLowerCase().includes('fetch')\n \n return (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center max-w-sm p-6\">\n <WarningIcon className=\"w-12 h-12 mx-auto text-red-500 mb-4\" />\n <div className=\"text-sm font-semibold text-dc-text mb-2\">\n Failed to Load Schema\n </div>\n <div className=\"text-xs text-dc-text-secondary mb-4\">\n {isCorsError ? (\n <>\n CORS error detected. The API endpoint may be incorrect or not accessible.\n </>\n ) : (\n <>\n {schemaError || 'Unable to connect to the Cube.js API'}\n </>\n )}\n </div>\n \n <div className=\"space-y-2\">\n {onRetrySchema && (\n <button\n onClick={onRetrySchema}\n className=\"w-full flex items-center justify-center space-x-2 px-3 py-2 text-sm font-medium text-blue-700 bg-blue-100 border border-blue-200 rounded-md hover:bg-blue-200 focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n >\n <RefreshIcon className=\"w-4 h-4\" />\n <span>Retry</span>\n </button>\n )}\n\n {onOpenSettings && (\n <button\n onClick={onOpenSettings}\n className=\"w-full flex items-center justify-center space-x-2 px-3 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n >\n <SettingsIcon className=\"w-4 h-4\" />\n <span>Check API Settings</span>\n </button>\n )}\n </div>\n \n {isCorsError && (\n <div className=\"mt-4 p-3 bg-amber-50 border border-amber-200 rounded-md\">\n <div className=\"text-xs text-amber-800\">\n <div className=\"font-medium mb-1\">Common solutions:</div>\n <ul className=\"list-disc list-inside space-y-1\">\n <li>Verify the Base API URL is correct</li>\n <li>Ensure the server supports CORS</li>\n <li>Check if authentication is required</li>\n </ul>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n }\n\n // No schema loaded yet\n if (!schema) {\n return (\n <div className=\"h-full flex items-center justify-center text-dc-text-muted\">\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No Schema</div>\n <div className=\"text-xs\">Schema not loaded</div>\n </div>\n </div>\n )\n }\n\n const toggleCubeExpansion = (cubeName: string) => {\n const newExpanded = new Set(expandedCubes)\n if (newExpanded.has(cubeName)) {\n newExpanded.delete(cubeName)\n } else {\n newExpanded.add(cubeName)\n }\n setExpandedCubes(newExpanded)\n \n // If we're in search mode, also update the pre-search state\n if (preSearchExpandedCubes !== null) {\n const newPreSearchExpanded = new Set(preSearchExpandedCubes)\n if (newPreSearchExpanded.has(cubeName)) {\n newPreSearchExpanded.delete(cubeName)\n } else {\n newPreSearchExpanded.add(cubeName)\n }\n setPreSearchExpandedCubes(newPreSearchExpanded)\n }\n }\n\n const toggleSectionExpansion = (sectionKey: string) => {\n const newExpanded = new Set(expandedSections)\n if (newExpanded.has(sectionKey)) {\n newExpanded.delete(sectionKey)\n } else {\n newExpanded.add(sectionKey)\n }\n setExpandedSections(newExpanded)\n \n // If we're in search mode, also update the pre-search state\n if (preSearchExpandedSections !== null) {\n const newPreSearchExpanded = new Set(preSearchExpandedSections)\n if (newPreSearchExpanded.has(sectionKey)) {\n newPreSearchExpanded.delete(sectionKey)\n } else {\n newPreSearchExpanded.add(sectionKey)\n }\n setPreSearchExpandedSections(newPreSearchExpanded)\n }\n }\n\n const handleFieldClick = (field: MetaField, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n const isSelected = (() => {\n switch (fieldType) {\n case 'measures':\n return selectedFields.measures.includes(field.name)\n case 'dimensions':\n return selectedFields.dimensions.includes(field.name)\n case 'timeDimensions':\n return selectedFields.timeDimensions.includes(field.name)\n default:\n return false\n }\n })()\n\n if (isSelected) {\n onFieldDeselect(field.name, fieldType)\n } else {\n onFieldSelect(field.name, fieldType)\n }\n }\n\n const filterFields = (fields: MetaField[]): MetaField[] => {\n if (!searchTerm) return fields\n return fields.filter(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n }\n\n const cubeHasMatches = (cube: MetaCube): boolean => {\n if (!searchTerm.trim()) return true\n \n const measureMatches = cube.measures.some(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n \n const dimensionMatches = cube.dimensions.some(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n \n return measureMatches || dimensionMatches\n }\n\n const FieldItem: React.FC<{ \n field: MetaField\n fieldType: 'measures' | 'dimensions' | 'timeDimensions'\n icon: React.ReactNode\n }> = ({ field, fieldType, icon }) => {\n const isSelected = (() => {\n switch (fieldType) {\n case 'measures':\n return selectedFields.measures.includes(field.name)\n case 'dimensions':\n return selectedFields.dimensions.includes(field.name)\n case 'timeDimensions':\n return selectedFields.timeDimensions.includes(field.name)\n default:\n return false\n }\n })()\n\n const getSelectedStyles = () => {\n if (!isSelected) return 'hover:bg-dc-surface-hover text-dc-text-secondary'\n\n switch (fieldType) {\n case 'measures':\n return 'bg-amber-100 text-amber-800 border border-amber-200'\n case 'dimensions':\n return 'bg-green-100 text-green-800 border border-green-200'\n case 'timeDimensions':\n return 'bg-blue-100 text-blue-800 border border-blue-200'\n default:\n return 'bg-blue-100 text-blue-800 border border-blue-200'\n }\n }\n\n const getIconColor = () => {\n if (!isSelected) return 'text-dc-text-muted'\n \n switch (fieldType) {\n case 'measures':\n return 'text-amber-600'\n case 'dimensions':\n return 'text-green-600'\n case 'timeDimensions':\n return 'text-blue-600'\n default:\n return 'text-blue-600'\n }\n }\n\n const getCheckmarkColor = () => {\n switch (fieldType) {\n case 'measures':\n return 'text-amber-600'\n case 'dimensions':\n return 'text-green-600'\n case 'timeDimensions':\n return 'text-blue-600'\n default:\n return 'text-blue-600'\n }\n }\n\n return (\n <div\n className={`flex items-center px-2 py-1.5 text-xs cursor-pointer rounded-md transition-colors ${getSelectedStyles()}`}\n onClick={() => handleFieldClick(field, fieldType)}\n title={field.description || field.title}\n >\n <div className={`mr-1.5 ${getIconColor()}`}>\n {React.cloneElement(icon as React.ReactElement, { className: 'w-4 h-4' })}\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"font-medium truncate text-xs\">{field.shortTitle}</div>\n <div className=\"text-xs text-dc-text-muted truncate\">{field.name}</div>\n </div>\n {isSelected && (\n <div className={`ml-1.5 ${getCheckmarkColor()}`}>\n <svg className=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fillRule=\"evenodd\" d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\" clipRule=\"evenodd\" />\n </svg>\n </div>\n )}\n </div>\n )\n }\n\n const SectionHeader: React.FC<{\n title: string\n count: number\n sectionKey: string\n icon: React.ReactNode\n }> = ({ title, count, sectionKey, icon }) => {\n const isExpanded = expandedSections.has(sectionKey)\n \n // Get section type from sectionKey to apply consistent colors\n const getSectionType = (): 'dimensions' | 'timeDimensions' | 'measures' => {\n if (sectionKey.includes('-dimensions') && !sectionKey.includes('-timeDimensions')) {\n return 'dimensions'\n } else if (sectionKey.includes('-timeDimensions')) {\n return 'timeDimensions'\n } else {\n return 'measures'\n }\n }\n \n const getSectionColorClasses = () => {\n const sectionType = getSectionType()\n switch (sectionType) {\n case 'dimensions':\n return 'text-green-800'\n case 'timeDimensions':\n return 'text-blue-800'\n case 'measures':\n return 'text-amber-800'\n default:\n return 'text-gray-700'\n }\n }\n \n return (\n <div\n className={`flex items-center px-2 py-1 text-sm font-semibold cursor-pointer hover:bg-dc-surface-hover rounded-md ${getSectionColorClasses()}`}\n onClick={() => toggleSectionExpansion(sectionKey)}\n >\n <div className=\"mr-1.5\">\n {isExpanded ? (\n <ChevronDownIcon className=\"w-3 h-3\" />\n ) : (\n <ChevronRightIcon className=\"w-3 h-3\" />\n )}\n </div>\n <div className=\"mr-1.5\">\n {icon}\n </div>\n <span className=\"flex-1\">{title}</span>\n <span className=\"text-xs text-dc-text-muted bg-dc-surface-secondary px-1.5 py-0.5 rounded-full\">\n {count}\n </span>\n </div>\n )\n }\n\n const NoMatchesMessage: React.FC = () => (\n <div className=\"flex items-center justify-center py-8 text-center\">\n <div className=\"max-w-sm\">\n <div className=\"text-dc-text-muted mb-2\">\n <svg className=\"w-12 h-12 mx-auto\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5} d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n </div>\n <div className=\"text-sm font-medium text-dc-text mb-1\">No matches found</div>\n <div className=\"text-xs text-dc-text-muted mb-3\">\n No fields match your search term \"{searchTerm}\"\n </div>\n <button\n onClick={() => setSearchTerm('')}\n className=\"inline-flex items-center px-3 py-1.5 text-xs font-medium text-blue-700 bg-blue-100 border border-blue-200 rounded-md hover:bg-blue-200 focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n >\n Clear search\n </button>\n </div>\n </div>\n )\n\n return (\n <div className=\"flex-1 flex flex-col bg-dc-surface border border-dc-border rounded-lg min-h-0\">\n {/* Header */}\n <div className=\"border-b border-dc-border\">\n <div className=\"p-3 pb-0\">\n <div className=\"flex items-center justify-between mb-3\">\n <div>\n <h3 className=\"text-base font-semibold text-dc-text\">\n {viewType === 'diagram' ? 'Schema Diagram' : 'Schema Explorer'}\n </h3>\n </div>\n <div className=\"flex items-center space-x-2\">\n {onOpenSettings && (\n <button\n onClick={onOpenSettings}\n className=\"p-1 text-dc-text-muted hover:text-dc-text-secondary transition-colors\"\n title=\"Open settings\"\n >\n <SettingsIcon className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n </div>\n\n {/* View Type Tabs and Search */}\n <div className=\"flex items-center gap-3 mb-3\">\n {showSchemaDiagram ? (\n <div className=\"flex space-x-1 bg-dc-surface-secondary p-1 rounded-md\">\n <button\n onClick={() => {\n setViewType('tree')\n onViewTypeChange?.('tree')\n }}\n className={`\n flex items-center px-3 py-1.5 rounded text-xs font-medium transition-colors\n ${viewType === 'tree'\n ? 'bg-dc-surface text-dc-text shadow-xs'\n : 'text-dc-text-secondary hover:text-dc-text'\n }\n `}\n >\n <MenuIcon className=\"w-3 h-3 mr-1.5\" />\n Fields\n </button>\n <button\n onClick={() => {\n setViewType('diagram')\n onViewTypeChange?.('diagram')\n }}\n className={`\n flex items-center px-3 py-1.5 rounded text-xs font-medium transition-colors\n ${viewType === 'diagram'\n ? 'bg-dc-surface text-dc-text shadow-xs'\n : 'text-dc-text-secondary hover:text-dc-text'\n }\n `}\n >\n <SegmentIcon className=\"w-3 h-3 mr-1.5\" />\n Schema\n </button>\n </div>\n ) : null}\n\n {/* Search input - visible for both views */}\n <div className=\"flex-1 relative min-w-0\">\n <input\n type=\"text\"\n placeholder=\"Search fields...\"\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n className=\"w-full px-2 py-1.5 border border-dc-border rounded-md text-sm bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n <div className=\"absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none\">\n <svg className=\"h-4 w-4 text-dc-text-muted\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n </div>\n </div>\n </div>\n </div>\n\n </div>\n\n {/* Content */}\n <div className=\"flex-1 min-h-0 overflow-hidden\">\n {viewType === 'diagram' && showSchemaDiagram ? (\n /* Diagram View - schema relationship diagram (only when enabled) */\n <div className=\"h-full\">\n <Suspense fallback={\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"animate-pulse text-dc-text-muted\">Loading diagram...</div>\n </div>\n }>\n <CubeRelationshipDiagram\n className=\"h-full\"\n onCubeClick={(cubeName) => {\n if (!isExpanded) {\n // Auto-expand the clicked cube in tree view\n setExpandedCubes(prev => new Set([...prev, cubeName]))\n // Switch to tree view to show the expanded cube\n setViewType('tree')\n }\n }}\n onFieldClick={(cubeName, fieldName, fieldType) => {\n // Convert field type to QueryBuilder expected type and determine if time dimension\n let qbFieldType: 'measures' | 'dimensions' | 'timeDimensions'\n \n if (fieldType === 'measure') {\n qbFieldType = 'measures'\n } else {\n // For dimensions, check if it's a time dimension by looking at the schema\n const cube = schema?.cubes.find(c => c.name === cubeName)\n const dimension = cube?.dimensions.find(d => \n d.name === `${cubeName}.${fieldName}` || d.name === fieldName\n )\n \n qbFieldType = dimension?.type === 'time' ? 'timeDimensions' : 'dimensions'\n }\n \n const fullFieldName = `${cubeName}.${fieldName}`\n \n // Check if field is already selected\n const isSelected = selectedFields[qbFieldType].includes(fullFieldName)\n \n if (isSelected) {\n // Remove the field from the query\n onFieldDeselect(fullFieldName, qbFieldType)\n } else {\n // Add the field to the query\n onFieldSelect(fullFieldName, qbFieldType)\n }\n }}\n highlightedCubes={[\n ...selectedFields.measures.map(field => field.split('.')[0]),\n ...selectedFields.dimensions.map(field => field.split('.')[0]),\n ...selectedFields.timeDimensions.map(field => field.split('.')[0])\n ].filter((cube, index, arr) => arr.indexOf(cube) === index)} // Remove duplicates\n highlightedFields={[\n ...selectedFields.measures,\n ...selectedFields.dimensions,\n ...selectedFields.timeDimensions\n ]}\n searchTerm={searchTerm}\n />\n </Suspense>\n </div>\n ) : (\n /* Tree View - existing field list */\n <div className=\"h-full p-3 space-y-2 overflow-y-auto\">\n {(() => {\n // Filter cubes to only show those with matches (when searching)\n const filteredCubes = schema.cubes.filter(cubeHasMatches)\n \n // Show \"No matches\" message if searching but no cubes have matches\n if (searchTerm.trim() && filteredCubes.length === 0) {\n return <NoMatchesMessage />\n }\n \n return filteredCubes.map((cube: MetaCube) => {\n const isExpanded = expandedCubes.has(cube.name)\n const timeDimensions = cube.dimensions.filter(d => d.type === 'time')\n const regularDimensions = cube.dimensions.filter(d => d.type !== 'time')\n\n return (\n <div key={cube.name} className=\"border border-dc-border rounded-lg\">\n {/* Cube Header */}\n <div\n className=\"flex items-center px-3 py-2 cursor-pointer hover:bg-dc-surface-hover rounded-t-lg\"\n onClick={() => toggleCubeExpansion(cube.name)}\n >\n <div className=\"mr-2\">\n {isExpanded ? (\n <ChevronDownIcon className=\"w-4 h-4 text-dc-text-secondary\" />\n ) : (\n <ChevronRightIcon className=\"w-4 h-4 text-dc-text-secondary\" />\n )}\n </div>\n <div className=\"flex-1\">\n <div className=\"font-medium text-sm text-dc-text\">{cube.title}</div>\n <div className=\"text-xs text-dc-text-muted\">{cube.description}</div>\n </div>\n </div>\n\n {/* Cube Content */}\n {isExpanded && (\n <div className=\"border-t border-dc-border p-2 space-y-1\">\n {/* Dimensions - First (matching QueryPanel order) */}\n {regularDimensions.length > 0 && filterFields(regularDimensions).length > 0 && (\n <div>\n <SectionHeader\n title=\"Dimensions\"\n count={filterFields(regularDimensions).length}\n sectionKey={`${cube.name}-dimensions`}\n icon={<DimensionIcon className=\"w-4 h-4 text-green-600\" />}\n />\n {expandedSections.has(`${cube.name}-dimensions`) && (\n <div className=\"ml-5 space-y-1 mt-1\">\n {filterFields(regularDimensions).map(dimension => (\n <FieldItem\n key={dimension.name}\n field={dimension}\n fieldType=\"dimensions\"\n icon={<DimensionIcon className=\"w-4 h-4\" />}\n />\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Time Dimensions - Second (matching QueryPanel order) */}\n {timeDimensions.length > 0 && filterFields(timeDimensions).length > 0 && (\n <div>\n <SectionHeader\n title=\"Time Dimensions\"\n count={filterFields(timeDimensions).length}\n sectionKey={`${cube.name}-timeDimensions`}\n icon={<TimeDimensionIcon className=\"w-4 h-4 text-blue-600\" />}\n />\n {expandedSections.has(`${cube.name}-timeDimensions`) && (\n <div className=\"ml-5 space-y-1 mt-1\">\n {filterFields(timeDimensions).map(timeDimension => (\n <FieldItem\n key={timeDimension.name}\n field={timeDimension}\n fieldType=\"timeDimensions\"\n icon={<TimeDimensionIcon className=\"w-4 h-4\" />}\n />\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Measures - Third (matching QueryPanel order) */}\n {cube.measures.length > 0 && filterFields(cube.measures).length > 0 && (\n <div>\n <SectionHeader\n title=\"Measures\"\n count={filterFields(cube.measures).length}\n sectionKey={`${cube.name}-measures`}\n icon={<MeasureIcon className=\"w-4 h-4 text-amber-600\" />}\n />\n {expandedSections.has(`${cube.name}-measures`) && (\n <div className=\"ml-5 space-y-1 mt-1\">\n {filterFields(cube.measures).map(measure => (\n <FieldItem\n key={measure.name}\n field={measure}\n fieldType=\"measures\"\n icon={getMeasureIcon(measure.type, 'w-4 h-4')}\n />\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n )\n })\n })()}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default CubeMetaExplorer","/**\n * Type definitions for QueryBuilder components\n */\n\nimport type { CubeQuery, FilterOperator, Filter, SimpleFilter, GroupFilter, ChartType, ChartAxisConfig, ChartDisplayConfig } from '../../types'\n\n// Meta endpoint response types\nexport interface MetaField {\n name: string // e.g., \"Employees.count\"\n title: string // e.g., \"Total Employees\"\n shortTitle: string // e.g., \"Total Employees\"\n type: string // e.g., \"count\", \"string\", \"time\", \"number\"\n description?: string // Optional description\n}\n\nexport interface MetaCube {\n name: string // e.g., \"Employees\"\n title: string // e.g., \"Employee Analytics\"\n description: string // e.g., \"Employee data and metrics\"\n measures: MetaField[] // e.g., \"Employees.count\"\n dimensions: MetaField[] // e.g., \"Employees.name\"\n segments: MetaField[] // Currently empty in examples\n}\n\nexport interface MetaResponse {\n cubes: MetaCube[]\n}\n\n// Query builder state types\nexport type ValidationStatus = 'idle' | 'validating' | 'valid' | 'invalid'\nexport type ExecutionStatus = 'idle' | 'loading' | 'success' | 'error'\nexport type SchemaStatus = 'idle' | 'loading' | 'success' | 'error'\n\nexport interface QueryBuilderState {\n query: CubeQuery // Current query being built\n schema: MetaResponse | null // Schema from /meta endpoint\n schemaStatus: SchemaStatus // Status of schema loading\n schemaError: string | null // Error from schema loading\n validationStatus: ValidationStatus\n validationError: string | null\n validationSql: { sql: string[], params: any[] } | null // Generated SQL from validation\n executionStatus: ExecutionStatus\n executionResults: any[] | null\n executionError: string | null\n totalRowCount: number | null // Total rows without limit\n totalRowCountStatus: 'idle' | 'loading' | 'success' | 'error'\n}\n\n// Query analysis types for debugging transparency\nexport type PrimaryCubeSelectionReason =\n | 'most_dimensions'\n | 'most_connected'\n | 'alphabetical_fallback'\n | 'single_cube'\n\nexport interface PrimaryCubeCandidate {\n cubeName: string\n dimensionCount: number\n joinCount: number\n canReachAll: boolean\n}\n\nexport interface PrimaryCubeAnalysis {\n selectedCube: string\n reason: PrimaryCubeSelectionReason\n explanation: string\n candidates?: PrimaryCubeCandidate[]\n}\n\nexport interface JoinPathStep {\n fromCube: string\n toCube: string\n relationship: 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany'\n joinType: 'inner' | 'left' | 'right' | 'full'\n joinColumns: Array<{\n sourceColumn: string\n targetColumn: string\n }>\n junctionTable?: {\n tableName: string\n sourceColumns: string[]\n targetColumns: string[]\n }\n}\n\nexport interface JoinPathAnalysis {\n targetCube: string\n pathFound: boolean\n path?: JoinPathStep[]\n pathLength?: number\n error?: string\n visitedCubes?: string[]\n}\n\nexport interface PreAggregationAnalysis {\n cubeName: string\n cteAlias: string\n reason: string\n measures: string[]\n joinKeys: Array<{\n sourceColumn: string\n targetColumn: string\n }>\n}\n\nexport interface QuerySummary {\n queryType: 'single_cube' | 'multi_cube_join' | 'multi_cube_cte'\n joinCount: number\n cteCount: number\n hasPreAggregation: boolean\n}\n\nexport interface QueryAnalysis {\n timestamp: string\n cubeCount: number\n cubesInvolved: string[]\n primaryCube: PrimaryCubeAnalysis\n joinPaths: JoinPathAnalysis[]\n preAggregations: PreAggregationAnalysis[]\n querySummary: QuerySummary\n warnings?: string[]\n}\n\n// Validation response from /dry-run endpoint\nexport interface ValidationResult {\n valid?: boolean // Our custom property (may not be present in official Cube.js)\n error?: string\n query?: CubeQuery\n sql?: {\n sql: string[]\n params: any[]\n }\n queryType?: string // Always present in successful Cube.js responses\n normalizedQueries?: any[]\n queryOrder?: string[]\n transformedQueries?: any[]\n pivotQuery?: any\n complexity?: string\n cubesUsed?: string[]\n joinType?: string\n // Query analysis for debugging transparency\n analysis?: QueryAnalysis\n}\n\n// API Configuration\nexport interface ApiConfig {\n baseApiUrl: string // Base URL for Cube API (default: '/cubejs-api/v1')\n apiToken: string // API token for authentication (default: empty)\n}\n\n// Component props\nexport interface QueryBuilderProps {\n className?: string // Optional CSS classes\n initialQuery?: CubeQuery // Initial query to load (overrides localStorage)\n disableLocalStorage?: boolean // Disable localStorage persistence\n hideSettings?: boolean // Hide the settings/configuration button\n enableSharing?: boolean // Enable share analysis button (default: false)\n onShare?: (url: string) => void // Callback when share URL is generated\n}\n\nexport interface QueryBuilderRef {\n getCurrentQuery: () => CubeQuery\n getValidationState: () => { status: ValidationStatus, result?: ValidationResult }\n getValidationResult: () => ValidationResult | null\n}\n\nexport interface CubeMetaExplorerProps {\n schema: MetaResponse | null\n schemaStatus: SchemaStatus\n schemaError: string | null\n selectedFields: {\n measures: string[]\n dimensions: string[]\n timeDimensions: string[]\n }\n onFieldSelect: (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => void\n onFieldDeselect: (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => void\n onRetrySchema?: () => void\n onOpenSettings?: () => void\n onExpandSchema?: (expanded: boolean) => void\n onViewTypeChange?: (viewType: 'tree' | 'diagram') => void\n isExpanded?: boolean\n}\n\n// Share button states\nexport type ShareButtonState = 'idle' | 'copied' | 'copied-no-chart'\n\nexport interface QueryPanelProps {\n query: CubeQuery\n schema: MetaResponse | null\n validationStatus: ValidationStatus\n validationError: string | null\n validationSql: { sql: string[], params: any[] } | null\n validationAnalysis?: QueryAnalysis | null // Query analysis for debugging transparency\n onValidate: () => void\n onExecute: () => void\n onRemoveField: (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => void\n onTimeDimensionGranularityChange: (dimensionName: string, granularity: string) => void\n onFiltersChange: (filters: Filter[]) => void\n onDateRangeChange: (timeDimension: string, dateRange: string | string[]) => void\n onDateRangeRemove: (timeDimension: string) => void\n onOrderChange: (fieldName: string, direction: 'asc' | 'desc' | null) => void\n onClearQuery?: () => void\n showSettings?: boolean // Show the settings/configuration button\n onSettingsClick?: () => void // Handler for settings button click\n onAIAssistantClick?: () => void // Handler for AI Assistant button click\n onSchemaClick?: () => void // Handler for Schema button click\n onShareClick?: () => void // Handler for share button click\n shareButtonState?: ShareButtonState // Current state of share button\n isViewingShared?: boolean // Whether viewing a shared analysis\n}\n\n// Available fields for chart configuration (derived from validation result)\nexport interface AvailableFields {\n dimensions: string[]\n timeDimensions: string[]\n measures: string[]\n}\n\nexport interface ResultsPanelProps {\n executionStatus: ExecutionStatus\n executionResults: any[] | null\n executionError: string | null\n query: CubeQuery\n displayLimit?: number\n onDisplayLimitChange?: (limit: number) => void\n totalRowCount?: number | null\n totalRowCountStatus?: 'idle' | 'loading' | 'success' | 'error'\n\n // Chart visualization props\n chartType?: ChartType\n chartConfig?: ChartAxisConfig\n displayConfig?: ChartDisplayConfig\n availableFields?: AvailableFields | null\n onChartTypeChange?: (type: ChartType) => void\n onChartConfigChange?: (config: ChartAxisConfig) => void\n onDisplayConfigChange?: (config: ChartDisplayConfig) => void\n\n // View state props\n activeView?: 'table' | 'chart'\n onActiveViewChange?: (view: 'table' | 'chart') => void\n}\n\n// Time dimension granularity options\nexport const TIME_GRANULARITIES = [\n { value: 'hour', label: 'Hour' },\n { value: 'day', label: 'Day' },\n { value: 'week', label: 'Week' },\n { value: 'month', label: 'Month' },\n { value: 'quarter', label: 'Quarter' },\n { value: 'year', label: 'Year' }\n] as const\n\nexport type TimeGranularity = typeof TIME_GRANULARITIES[number]['value']\n\n// Filter operator metadata\nexport interface FilterOperatorMeta {\n label: string\n description: string\n requiresValues: boolean\n supportsMultipleValues: boolean\n valueType: 'string' | 'number' | 'date' | 'boolean' | 'any'\n fieldTypes: string[] // Which field types support this operator\n}\n\nexport const FILTER_OPERATORS: Record<FilterOperator, FilterOperatorMeta> = {\n // String operators\n equals: {\n label: 'equals',\n description: 'Exact match',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'boolean', 'time']\n },\n notEquals: {\n label: 'not equals',\n description: 'Does not match',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'boolean', 'time']\n },\n contains: {\n label: 'contains',\n description: 'Contains text (case insensitive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notContains: {\n label: 'not contains',\n description: 'Does not contain text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n startsWith: {\n label: 'starts with',\n description: 'Starts with text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notStartsWith: {\n label: 'not starts with',\n description: 'Does not start with text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n endsWith: {\n label: 'ends with',\n description: 'Ends with text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notEndsWith: {\n label: 'not ends with',\n description: 'Does not end with text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n like: {\n label: 'like',\n description: 'SQL LIKE pattern matching (case sensitive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notLike: {\n label: 'not like',\n description: 'SQL NOT LIKE pattern matching (case sensitive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n ilike: {\n label: 'ilike',\n description: 'SQL ILIKE pattern matching (case insensitive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n // Numeric operators\n gt: {\n label: 'greater than',\n description: 'Greater than value',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n gte: {\n label: 'greater than or equal',\n description: 'Greater than or equal to value',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n lt: {\n label: 'less than',\n description: 'Less than value',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n lte: {\n label: 'less than or equal',\n description: 'Less than or equal to value',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n between: {\n label: 'between',\n description: 'Between two values (inclusive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n notBetween: {\n label: 'not between',\n description: 'Not between two values',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n // Array operators\n in: {\n label: 'in',\n description: 'Matches any of the provided values',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'boolean']\n },\n notIn: {\n label: 'not in',\n description: 'Does not match any of the provided values',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'boolean']\n },\n // Null/Empty operators\n set: {\n label: 'is set',\n description: 'Is not null/empty',\n requiresValues: false,\n supportsMultipleValues: false,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'time', 'boolean']\n },\n notSet: {\n label: 'is not set',\n description: 'Is null/empty',\n requiresValues: false,\n supportsMultipleValues: false,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'time', 'boolean']\n },\n isEmpty: {\n label: 'is empty',\n description: 'Is empty string or null',\n requiresValues: false,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n isNotEmpty: {\n label: 'is not empty',\n description: 'Is not empty string and not null',\n requiresValues: false,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n // Date operators\n inDateRange: {\n label: 'in date range',\n description: 'Between two dates',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'date',\n fieldTypes: ['time']\n },\n beforeDate: {\n label: 'before date',\n description: 'Before specified date',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'date',\n fieldTypes: ['time']\n },\n afterDate: {\n label: 'after date',\n description: 'After specified date',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'date',\n fieldTypes: ['time']\n },\n // Regex operators\n regex: {\n label: 'matches regex',\n description: 'Matches regular expression pattern',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notRegex: {\n label: 'not matches regex',\n description: 'Does not match regular expression pattern',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n // PostgreSQL array operators\n arrayContains: {\n label: 'array contains all',\n description: 'Array field contains all specified values (PostgreSQL only)',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'string',\n fieldTypes: ['string']\n },\n arrayOverlaps: {\n label: 'array contains any',\n description: 'Array field contains any of the specified values (PostgreSQL only)',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'string',\n fieldTypes: ['string']\n },\n arrayContained: {\n label: 'array values in',\n description: 'All array field values are within specified values (PostgreSQL only)',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'string',\n fieldTypes: ['string']\n }\n}\n\n// Filter builder component props\nexport interface FilterBuilderProps {\n filters: Filter[]\n schema: MetaResponse | null\n query: CubeQuery\n onFiltersChange: (filters: Filter[]) => void\n hideFieldSelector?: boolean // Hide the field selector (for universal time filters)\n}\n\nexport interface FilterItemProps {\n filter: SimpleFilter\n index: number\n onFilterChange: (index: number, filter: SimpleFilter) => void\n onFilterRemove: (index: number) => void\n schema: MetaResponse | null\n query: CubeQuery\n hideFieldSelector?: boolean // Hide the field selector (for read-only filters)\n hideOperatorSelector?: boolean // Hide the operator selector (for read-only filters)\n hideRemoveButton?: boolean // Hide the remove button (for read-only filters)\n}\n\nexport interface FilterGroupProps {\n group: GroupFilter\n index: number\n onGroupChange: (index: number, group: GroupFilter) => void\n onGroupChangeWithUnwrap?: (index: number, group: GroupFilter) => void\n onGroupRemove: (index: number) => void\n schema: MetaResponse | null\n query: CubeQuery\n depth: number\n}\n\nexport interface FilterValueSelectorProps {\n fieldName: string\n operator: FilterOperator\n values: any[]\n onValuesChange: (values: any[]) => void\n schema: MetaResponse | null\n}\n\n// Date range types\nexport type DateRangeType = \n | 'custom'\n | 'today'\n | 'yesterday' \n | 'this_week'\n | 'this_month'\n | 'this_quarter'\n | 'this_year'\n | 'last_7_days'\n | 'last_30_days'\n | 'last_week'\n | 'last_month'\n | 'last_quarter'\n | 'last_year'\n | 'last_12_months'\n | 'last_n_days'\n | 'last_n_weeks'\n | 'last_n_months'\n | 'last_n_quarters'\n | 'last_n_years'\n\nexport interface DateRangeOption {\n value: DateRangeType\n label: string\n}\n\nexport const DATE_RANGE_OPTIONS: DateRangeOption[] = [\n { value: 'custom', label: 'Custom' },\n { value: 'today', label: 'Today' },\n { value: 'yesterday', label: 'Yesterday' },\n { value: 'this_week', label: 'This week' },\n { value: 'this_month', label: 'This month' },\n { value: 'this_quarter', label: 'This quarter' },\n { value: 'this_year', label: 'This year' },\n { value: 'last_7_days', label: 'Last 7 days' },\n { value: 'last_30_days', label: 'Last 30 days' },\n { value: 'last_n_days', label: 'Last N days' },\n { value: 'last_week', label: 'Last week' },\n { value: 'last_n_weeks', label: 'Last N weeks' },\n { value: 'last_month', label: 'Last month' }, \n { value: 'last_12_months', label: 'Last 12 months' },\n { value: 'last_n_months', label: 'Last N months' },\n { value: 'last_quarter', label: 'Last quarter' },\n { value: 'last_n_quarters', label: 'Last N quarters' },\n { value: 'last_year', label: 'Last year' },\n { value: 'last_n_years', label: 'Last N years' }\n] as const\n\nexport interface DateRangeFilter {\n id: string\n timeDimension: string\n rangeType: DateRangeType\n startDate?: string\n endDate?: string\n}\n\n// Date range component props\nexport interface DateRangeSelectorProps {\n timeDimensions: string[]\n onDateRangeChange: (timeDimension: string, dateRange: string | string[]) => void\n onDateRangeRemove: (timeDimension: string) => void\n currentDateRanges: Record<string, string | string[]>\n}\n\nexport interface DateRangeFilterProps {\n timeDimensions: Array<{ dimension: string; granularity?: string; dateRange?: string | string[] }>\n onDateRangeChange: (timeDimension: string, dateRange: string | string[]) => void\n onDateRangeRemove: (timeDimension: string) => void\n}","/**\n * FilterValueSelector Component\n * \n * Smart input component that adapts to operator type:\n * - Combo box for equals/notEquals with API-fetched values\n * - Number input for numeric operators\n * - Date picker for date operators\n * - No input for set/notSet operators\n */\n\nimport React, { useState, useEffect, useRef, useCallback, useMemo } from 'react'\nimport { getIcon } from '../../icons'\nimport { useFilterValues } from '../../hooks/useFilterValues'\nimport { useDebounce } from '../../hooks/useDebounce'\nimport type { FilterValueSelectorProps } from './types'\nimport { FILTER_OPERATORS } from './types'\n\nconst ChevronDownIcon = getIcon('chevronDown')\nconst CloseIcon = getIcon('close')\n\nconst FilterValueSelector: React.FC<FilterValueSelectorProps> = ({\n fieldName,\n operator,\n values,\n onValuesChange,\n schema\n}) => {\n const operatorMeta = FILTER_OPERATORS[operator]\n const [isOpen, setIsOpen] = useState(false)\n const [searchText, setSearchText] = useState('')\n const [hasLoadedInitial, setHasLoadedInitial] = useState(false)\n const dropdownRef = useRef<HTMLDivElement>(null)\n const lastSearchedTerm = useRef<string>('')\n \n // Debounce the search text\n const debouncedSearchText = useDebounce(searchText, 300)\n \n // Check if the field is a dimension (not a measure)\n const isDimension = useMemo(() => schema ? schema.cubes.some(cube => \n cube.dimensions.some(dim => dim.name === fieldName)\n ) : false, [schema, fieldName])\n \n // Check if the field is a time dimension\n const isTimeDimension = useMemo(() => schema ? schema.cubes.some(cube => \n cube.dimensions.some(dim => dim.name === fieldName && dim.type === 'time')\n ) : false, [schema, fieldName])\n \n // Fetch distinct values for combo box (only for equals/notEquals/in/notIn on non-time dimensions)\n const shouldFetchValues = useMemo(() => \n (['equals', 'notEquals', 'in', 'notIn'].includes(operator)) && isDimension && !isTimeDimension,\n [operator, isDimension, isTimeDimension]\n )\n const shouldShowComboBox = shouldFetchValues\n \n const { \n values: distinctValues, \n loading: valuesLoading, \n error: valuesError,\n searchValues\n } = useFilterValues(fieldName, shouldFetchValues)\n \n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false)\n }\n }\n \n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [])\n \n // Load initial values when dropdown opens\n useEffect(() => {\n if (isOpen && shouldFetchValues && searchValues) {\n searchValues('', true) // Force load with empty search\n setHasLoadedInitial(true)\n lastSearchedTerm.current = ''\n }\n }, [isOpen, shouldFetchValues, searchValues])\n \n // Trigger search when debounced search text changes\n useEffect(() => {\n if (hasLoadedInitial && shouldFetchValues && searchValues && debouncedSearchText !== lastSearchedTerm.current) {\n lastSearchedTerm.current = debouncedSearchText\n searchValues(debouncedSearchText)\n }\n }, [debouncedSearchText, hasLoadedInitial, shouldFetchValues, searchValues])\n \n // Handle dropdown toggle\n const handleDropdownToggle = useCallback(() => {\n const newIsOpen = !isOpen\n setIsOpen(newIsOpen)\n \n // Reset search when closing dropdown\n if (!newIsOpen) {\n setSearchText('')\n lastSearchedTerm.current = ''\n }\n }, [isOpen])\n \n // Handle search input change\n const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const newSearchText = e.target.value\n setSearchText(newSearchText)\n }, [])\n \n // Handle value selection for combo box\n const handleValueSelect = useCallback((value: any) => {\n if (operatorMeta.supportsMultipleValues) {\n // Add to selection if not already selected\n if (!values.includes(value)) {\n onValuesChange([...values, value])\n }\n } else {\n // Replace current value\n onValuesChange([value])\n setIsOpen(false)\n }\n // Clear search after selection\n setSearchText('')\n }, [operatorMeta.supportsMultipleValues, values, onValuesChange])\n \n // Handle value removal for multi-select\n const handleValueRemove = useCallback((valueToRemove: any) => {\n onValuesChange(values.filter(v => v !== valueToRemove))\n }, [values, onValuesChange])\n \n // Handle direct text input for non-combo operators\n const handleDirectInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n if (operatorMeta.valueType === 'number') {\n const numValue = parseFloat(value)\n // Accept valid numbers including zero\n if (!isNaN(numValue)) {\n onValuesChange([numValue])\n } else if (value === '' || value === '-') {\n // Allow empty string or just a minus sign for negative numbers being typed\n onValuesChange([])\n }\n } else {\n onValuesChange(value ? [value] : [])\n }\n }, [operatorMeta.valueType, onValuesChange])\n \n // Handle date input\n const handleDateInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n if (operator === 'inDateRange') {\n // For date range, we need two values\n const currentValues = values.length >= 2 ? values : ['', '']\n onValuesChange([value, currentValues[1]])\n } else {\n // Single date value\n onValuesChange(value ? [value] : [])\n }\n }, [operator, values, onValuesChange])\n \n const handleDateRangeEndInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n const currentValues = values.length >= 2 ? values : ['', '']\n onValuesChange([currentValues[0], value])\n }, [values, onValuesChange])\n\n // Handle between/notBetween range inputs (must be defined at top level, not inside conditionals)\n const handleBetweenStartInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = parseFloat(e.target.value)\n const currentValues = values.length >= 2 ? values : ['', '']\n const newValues = [!isNaN(value) ? value : e.target.value === '' ? '' : currentValues[0], currentValues[1]]\n onValuesChange(newValues.filter(v => v !== ''))\n }, [values, onValuesChange])\n\n const handleBetweenEndInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = parseFloat(e.target.value)\n const currentValues = values.length >= 2 ? values : ['', '']\n const newValues = [currentValues[0], !isNaN(value) ? value : e.target.value === '' ? '' : currentValues[1]]\n onValuesChange(newValues.filter(v => v !== ''))\n }, [values, onValuesChange])\n\n // Render based on operator type\n if (!operatorMeta.requiresValues) {\n // No input needed for set/notSet\n return (\n <div className=\"text-sm text-dc-text-muted italic\">\n No value required\n </div>\n )\n }\n \n if (operator === 'inDateRange') {\n // Date range picker\n return (\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"date\"\n value={values[0] || ''}\n onChange={handleDateInput}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n <span className=\"text-sm text-dc-text-muted\">to</span>\n <input\n type=\"date\"\n value={values[1] || ''}\n onChange={handleDateRangeEndInput}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n </div>\n )\n }\n \n if (operator === 'between' || operator === 'notBetween') {\n // Between range picker (for numbers)\n return (\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"number\"\n value={values[0] !== undefined && values[0] !== null ? values[0] : ''}\n onChange={handleBetweenStartInput}\n placeholder=\"Min\"\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n <span className=\"text-sm text-dc-text-muted\">to</span>\n <input\n type=\"number\"\n value={values[1] !== undefined && values[1] !== null ? values[1] : ''}\n onChange={handleBetweenEndInput}\n placeholder=\"Max\"\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n </div>\n )\n }\n \n if (operatorMeta.valueType === 'date') {\n // Single date picker\n return (\n <input\n type=\"date\"\n value={values[0] || ''}\n onChange={handleDateInput}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n )\n }\n \n if (operatorMeta.valueType === 'number') {\n // Number input\n return (\n <input\n type=\"number\"\n value={values[0] !== undefined && values[0] !== null ? values[0] : ''}\n onChange={handleDirectInput}\n placeholder=\"Enter number\"\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n )\n }\n \n // Time dimension with equals/notEquals/in/notIn - use date picker\n if (isTimeDimension && (['equals', 'notEquals', 'in', 'notIn'].includes(operator))) {\n if (operatorMeta.supportsMultipleValues) {\n // Multi-select date picker (for notEquals that supports multiple values)\n return (\n <div className=\"space-y-2\">\n {/* Selected dates display */}\n {values.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {values.map((value, index) => (\n <div\n key={index}\n className=\"inline-flex items-center bg-dc-time-dimension text-dc-time-dimension text-xs px-2 py-1 rounded-sm border border-dc-time-dimension\"\n >\n <span className=\"mr-1\">{String(value)}</span>\n <button\n onClick={() => handleValueRemove(value)}\n className=\"text-blue-600 hover:text-blue-800 focus:outline-hidden\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n \n {/* Add new date */}\n <input\n type=\"date\"\n onChange={(e) => {\n if (e.target.value && !values.includes(e.target.value)) {\n onValuesChange([...values, e.target.value])\n e.target.value = '' // Clear the input\n }\n }}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n placeholder=\"Add date...\"\n />\n </div>\n )\n } else {\n // Single date picker\n return (\n <input\n type=\"date\"\n value={values[0] || ''}\n onChange={handleDateInput}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n )\n }\n }\n \n if (shouldShowComboBox) {\n // Combo box with API-fetched values\n return (\n <div className=\"relative\" ref={dropdownRef}>\n {/* Selected values display (for multi-select) */}\n {operatorMeta.supportsMultipleValues && values.length > 0 && (\n <div className=\"flex flex-wrap gap-1 mb-2\">\n {values.map((value, index) => (\n <div\n key={index}\n className=\"inline-flex items-center bg-dc-time-dimension text-dc-time-dimension text-xs px-2 py-1 rounded-sm border border-dc-time-dimension\"\n >\n <span className=\"mr-1\">{String(value)}</span>\n <button\n onClick={() => handleValueRemove(value)}\n className=\"text-blue-600 hover:text-blue-800 focus:outline-hidden\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n \n {/* Single value display (for single-select) */}\n {!operatorMeta.supportsMultipleValues && values.length > 0 && (\n <div className=\"mb-2\">\n <div className=\"inline-flex items-center bg-dc-time-dimension text-dc-time-dimension text-xs px-2 py-1 rounded-sm border border-dc-time-dimension\">\n <span className=\"mr-1\">{String(values[0])}</span>\n <button\n onClick={() => onValuesChange([])}\n className=\"text-blue-600 hover:text-blue-800 focus:outline-hidden\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n </div>\n )}\n \n {/* Dropdown trigger */}\n <button\n onClick={handleDropdownToggle}\n className=\"w-full text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500 flex items-center justify-between min-w-0\"\n >\n <span className=\"text-dc-text-muted truncate\">\n {valuesLoading && !hasLoadedInitial ? 'Loading values...' : 'Select value...'}\n </span>\n <ChevronDownIcon className=\"w-4 h-4 text-dc-text-muted\" />\n </button>\n\n {/* Dropdown menu */}\n {isOpen && (\n <div className=\"absolute z-30 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {/* Search input */}\n <div className=\"p-2 border-b border-dc-border\">\n <input\n type=\"text\"\n value={searchText}\n onChange={handleSearchChange}\n placeholder=\"Search values...\"\n className=\"w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n autoFocus\n />\n </div>\n\n {/* Values list */}\n <div className=\"max-h-48 overflow-y-auto\">\n {valuesLoading ? (\n <div className=\"p-2 text-sm text-dc-text-muted\">\n {searchText ? 'Searching...' : 'Loading values...'}\n </div>\n ) : valuesError ? (\n <div className=\"p-2 text-sm text-red-600\">\n Error loading values: {valuesError}\n </div>\n ) : distinctValues.length === 0 ? (\n <div className=\"p-2 text-sm text-dc-text-muted\">\n {searchText ? 'No matching values' : 'No values available'}\n </div>\n ) : (\n distinctValues.map((value, index) => {\n const isSelected = values.includes(value)\n\n return (\n <button\n key={`${value}-${index}`}\n onClick={() => handleValueSelect(value)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${\n isSelected ? 'bg-blue-50 text-blue-700' : 'text-dc-text-secondary'\n }`}\n >\n {String(value)}\n {isSelected && (\n <span className=\"float-right text-blue-600\">✓</span>\n )}\n </button>\n )\n })\n )}\n </div>\n </div>\n )}\n </div>\n )\n }\n \n // Fallback to text input\n return (\n <input\n type=\"text\"\n value={values[0] !== undefined && values[0] !== null ? values[0] : ''}\n onChange={handleDirectInput}\n placeholder={`Enter ${operatorMeta.valueType} value`}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n )\n}\n\nexport default FilterValueSelector","/**\n * Utility functions for QueryBuilder components\n */\n\nimport type { CubeQuery, Filter, SimpleFilter, GroupFilter } from '../../types'\nimport type { MetaField, MetaResponse } from './types'\nimport { FILTER_OPERATORS } from './types'\n\n/**\n * Check if a field is selected in the current query\n */\nexport function isFieldSelected(\n fieldName: string, \n fieldType: 'measures' | 'dimensions' | 'timeDimensions',\n query: CubeQuery\n): boolean {\n switch (fieldType) {\n case 'measures':\n return query.measures?.includes(fieldName) || false\n case 'dimensions':\n return query.dimensions?.includes(fieldName) || false\n case 'timeDimensions':\n return query.timeDimensions?.some(td => td.dimension === fieldName) || false\n default:\n return false\n }\n}\n\n/**\n * Get all time dimension fields from schema\n */\nexport function getTimeDimensionFields(schema: MetaResponse): MetaField[] {\n const timeDimensions: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n cube.dimensions.forEach(dimension => {\n if (dimension.type === 'time') {\n timeDimensions.push(dimension)\n }\n })\n })\n \n return timeDimensions\n}\n\n/**\n * Get all non-time dimension fields from schema\n */\nexport function getRegularDimensionFields(schema: MetaResponse): MetaField[] {\n const dimensions: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n cube.dimensions.forEach(dimension => {\n if (dimension.type !== 'time') {\n dimensions.push(dimension)\n }\n })\n })\n \n return dimensions\n}\n\n/**\n * Get all measure fields from schema\n */\nexport function getMeasureFields(schema: MetaResponse): MetaField[] {\n const measures: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n cube.measures.forEach(measure => {\n measures.push(measure)\n })\n })\n \n return measures\n}\n\n/**\n * Check if query has any content (measures, dimensions, or timeDimensions)\n */\nexport function hasQueryContent(query: CubeQuery): boolean {\n return Boolean(\n (query.measures && query.measures.length > 0) ||\n (query.dimensions && query.dimensions.length > 0) ||\n (query.timeDimensions && query.timeDimensions.length > 0)\n )\n}\n\n/**\n * Get count of selected fields across all types\n */\nexport function getSelectedFieldsCount(query: CubeQuery): number {\n let count = 0\n if (query.measures) count += query.measures.length\n if (query.dimensions) count += query.dimensions.length\n if (query.timeDimensions) count += query.timeDimensions.length\n return count\n}\n\n/**\n * Get cube name from field name (e.g., \"Employees.count\" -> \"Employees\")\n */\nexport function getCubeNameFromField(fieldName: string): string {\n return fieldName.split('.')[0]\n}\n\n/**\n * Group fields by cube name\n */\nexport function groupFieldsByCube(fields: MetaField[]): Record<string, MetaField[]> {\n return fields.reduce((groups, field) => {\n const cubeName = getCubeNameFromField(field.name)\n if (!groups[cubeName]) {\n groups[cubeName] = []\n }\n groups[cubeName].push(field)\n return groups\n }, {} as Record<string, MetaField[]>)\n}\n\n/**\n * Clean query object by removing empty arrays\n */\nexport function cleanQuery(query: CubeQuery): CubeQuery {\n const cleanedQuery: CubeQuery = {}\n \n if (query.measures && query.measures.length > 0) {\n cleanedQuery.measures = query.measures\n }\n \n if (query.dimensions && query.dimensions.length > 0) {\n cleanedQuery.dimensions = query.dimensions\n }\n \n if (query.timeDimensions && query.timeDimensions.length > 0) {\n cleanedQuery.timeDimensions = query.timeDimensions\n }\n \n if (query.filters && query.filters.length > 0) {\n cleanedQuery.filters = query.filters\n }\n \n if (query.order) {\n cleanedQuery.order = query.order\n }\n \n if (query.limit) {\n cleanedQuery.limit = query.limit\n }\n \n if (query.offset) {\n cleanedQuery.offset = query.offset\n }\n \n if (query.segments && query.segments.length > 0) {\n cleanedQuery.segments = query.segments\n }\n \n return cleanedQuery\n}\n\n/**\n * Clean a query and transform filters for server compatibility\n * This version transforms GroupFilter to legacy and/or format\n */\nexport function cleanQueryForServer(query: CubeQuery): CubeQuery {\n const cleanedQuery = cleanQuery(query)\n \n // Apply server transformation to filters\n if (cleanedQuery.filters && cleanedQuery.filters.length > 0) {\n cleanedQuery.filters = transformFiltersForServer(cleanedQuery.filters) as any\n }\n \n return cleanedQuery\n}\n\n/**\n * Create an empty query object\n */\nexport function createEmptyQuery(): CubeQuery {\n return {}\n}\n\n/**\n * Filter utility functions\n */\n\n/**\n * Check if a filter is a simple filter\n */\nexport function isSimpleFilter(filter: Filter): filter is SimpleFilter {\n return 'member' in filter && 'operator' in filter && 'values' in filter\n}\n\n/**\n * Check if a filter is a group filter\n */\nexport function isGroupFilter(filter: Filter): filter is GroupFilter {\n return 'type' in filter && 'filters' in filter\n}\n\n/**\n * Check if a filter is an AND filter\n */\nexport function isAndFilter(filter: Filter): filter is GroupFilter {\n return isGroupFilter(filter) && filter.type === 'and'\n}\n\n/**\n * Check if a filter is an OR filter\n */\nexport function isOrFilter(filter: Filter): filter is GroupFilter {\n return isGroupFilter(filter) && filter.type === 'or'\n}\n\n/**\n * Flatten all simple filters from a hierarchical filter structure\n */\nexport function flattenFilters(filters: Filter[]): SimpleFilter[] {\n const simple: SimpleFilter[] = []\n \n const flatten = (filter: Filter) => {\n if (isSimpleFilter(filter)) {\n simple.push(filter)\n } else if (isGroupFilter(filter)) {\n filter.filters.forEach(flatten)\n }\n }\n \n filters.forEach(flatten)\n return simple\n}\n\n/**\n * Get all filterable fields from schema (measures, dimensions, and time dimensions)\n * Returns ALL fields if no query provided, or only query fields if query provided\n */\nexport function getFilterableFields(schema: MetaResponse, query?: CubeQuery): MetaField[] {\n const allFields: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n allFields.push(...cube.measures)\n allFields.push(...cube.dimensions)\n })\n \n // If no query provided, return all fields\n if (!query) {\n return allFields.sort((a, b) => a.name.localeCompare(b.name))\n }\n \n // Get currently selected fields from the query\n const selectedFields = new Set<string>()\n \n // Add measures\n if (query.measures) {\n query.measures.forEach(measure => selectedFields.add(measure))\n }\n \n // Add dimensions\n if (query.dimensions) {\n query.dimensions.forEach(dimension => selectedFields.add(dimension))\n }\n \n // Add time dimensions\n if (query.timeDimensions) {\n query.timeDimensions.forEach(td => selectedFields.add(td.dimension))\n }\n \n // Filter to only include selected fields\n const filterableFields = allFields.filter(field => selectedFields.has(field.name))\n \n return filterableFields.sort((a, b) => a.name.localeCompare(b.name))\n}\n\n/**\n * Get ALL filterable fields from schema, regardless of query selection\n */\nexport function getAllFilterableFields(schema: MetaResponse): MetaField[] {\n const allFields: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n allFields.push(...cube.measures)\n allFields.push(...cube.dimensions)\n })\n \n return allFields.sort((a, b) => a.name.localeCompare(b.name))\n}\n\n/**\n * Get organized filter field options with query fields prioritized at top\n */\nexport function getOrganizedFilterFields(schema: MetaResponse, query?: CubeQuery): {\n queryFields: MetaField[]\n allFields: MetaField[]\n} {\n const allFields = getAllFilterableFields(schema)\n \n if (!query) {\n return {\n queryFields: [],\n allFields\n }\n }\n \n // Get currently selected fields from the query\n const selectedFields = new Set<string>()\n \n // Add measures\n if (query.measures) {\n query.measures.forEach(measure => selectedFields.add(measure))\n }\n \n // Add dimensions\n if (query.dimensions) {\n query.dimensions.forEach(dimension => selectedFields.add(dimension))\n }\n \n // Add time dimensions\n if (query.timeDimensions) {\n query.timeDimensions.forEach(td => selectedFields.add(td.dimension))\n }\n \n // Split fields into query fields and other fields\n const queryFields = allFields.filter(field => selectedFields.has(field.name))\n \n return {\n queryFields,\n allFields\n }\n}\n\n/**\n * Get available operators for a field type\n */\nexport function getAvailableOperators(fieldType: string): Array<{operator: string, label: string}> {\n const operators: Array<{operator: string, label: string}> = []\n \n for (const [operator, meta] of Object.entries(FILTER_OPERATORS)) {\n if (meta.fieldTypes.includes(fieldType)) {\n operators.push({\n operator,\n label: meta.label\n })\n }\n }\n \n return operators\n}\n\n/**\n * Get field type from schema\n */\nexport function getFieldType(fieldName: string, schema: MetaResponse): string {\n for (const cube of schema.cubes) {\n // Check measures\n const measure = cube.measures.find(m => m.name === fieldName)\n if (measure) return measure.type\n \n // Check dimensions\n const dimension = cube.dimensions.find(d => d.name === fieldName)\n if (dimension) return dimension.type\n }\n \n return 'string' // Default fallback\n}\n\n/**\n * Validate a filter\n */\nexport function validateFilter(filter: SimpleFilter, schema: MetaResponse): {\n isValid: boolean\n errors: string[]\n} {\n const errors: string[] = []\n \n // Check if field exists\n const fields = getFilterableFields(schema)\n const fieldExists = fields.some(f => f.name === filter.member)\n \n if (!fieldExists) {\n errors.push(`Field \"${filter.member}\" does not exist`)\n }\n \n // Check if operator is valid for field type\n if (fieldExists) {\n const fieldType = getFieldType(filter.member, schema)\n const operatorMeta = FILTER_OPERATORS[filter.operator]\n \n if (!operatorMeta) {\n errors.push(`Invalid operator \"${filter.operator}\"`)\n } else if (!operatorMeta.fieldTypes.includes(fieldType)) {\n errors.push(`Operator \"${filter.operator}\" is not valid for field type \"${fieldType}\"`)\n } else {\n // Check values\n if (operatorMeta.requiresValues && (!filter.values || filter.values.length === 0)) {\n errors.push(`Operator \"${filter.operator}\" requires values`)\n }\n \n if (!operatorMeta.supportsMultipleValues && filter.values && filter.values.length > 1) {\n errors.push(`Operator \"${filter.operator}\" does not support multiple values`)\n }\n }\n }\n \n return {\n isValid: errors.length === 0,\n errors\n }\n}\n\n/**\n * Count total filters in hierarchical structure\n */\nexport function countFilters(filters: Filter[]): number {\n let count = 0\n \n const countFilter = (filter: Filter) => {\n if (isSimpleFilter(filter)) {\n count++\n } else if (isGroupFilter(filter)) {\n filter.filters.forEach(countFilter)\n }\n }\n \n filters.forEach(countFilter)\n return count\n}\n\n/**\n * Create a new simple filter\n */\nexport function createSimpleFilter(member: string, operator: string = 'equals', values: any[] = []): SimpleFilter {\n return {\n member,\n operator: operator as any,\n values\n }\n}\n\n/**\n * Create a new AND filter group\n */\nexport function createAndFilter(filters: Filter[] = []): GroupFilter {\n return {\n type: 'and',\n filters\n }\n}\n\n/**\n * Create a new OR filter group\n */\nexport function createOrFilter(filters: Filter[] = []): GroupFilter {\n return {\n type: 'or',\n filters\n }\n}\n\n/**\n * Clean up filters by removing any that reference fields not in the current query\n * @deprecated This function is no longer used as we now support filtering on any schema field\n */\nexport function cleanupFilters(filters: Filter[], _query?: CubeQuery): Filter[] {\n // Return filters unchanged - we now support filtering on any field\n return filters || []\n}\n\n/**\n * Clean up filters by removing any that reference fields not in the current query (legacy)\n * Only used for backward compatibility - filters on non-query fields are now supported\n */\nexport function cleanupFiltersLegacy(filters: Filter[], query: CubeQuery): Filter[] {\n if (!filters || filters.length === 0) {\n return []\n }\n \n // Get currently selected fields from the query\n const selectedFields = new Set<string>()\n \n // Add measures\n if (query.measures) {\n query.measures.forEach(measure => selectedFields.add(measure))\n }\n \n // Add dimensions\n if (query.dimensions) {\n query.dimensions.forEach(dimension => selectedFields.add(dimension))\n }\n \n // Add time dimensions\n if (query.timeDimensions) {\n query.timeDimensions.forEach(td => selectedFields.add(td.dimension))\n }\n \n // Recursively clean filters\n const cleanFilter = (filter: Filter): Filter | null => {\n if (isSimpleFilter(filter)) {\n // Remove filter if its field is not selected\n return selectedFields.has(filter.member) ? filter : null\n } else if (isGroupFilter(filter)) {\n // Clean group recursively\n const cleanedFilters = filter.filters.map(cleanFilter).filter(f => f !== null) as Filter[]\n return cleanedFilters.length > 0 ? { type: filter.type, filters: cleanedFilters } : null\n }\n return null\n }\n \n // Clean all filters and remove nulls\n const cleanedFilters = filters.map(cleanFilter).filter(f => f !== null) as Filter[]\n \n return cleanedFilters\n}\n\n/**\n * Transform filters from new GroupFilter format to legacy server format\n * Server expects { and: [...] } and { or: [...] } instead of { type: 'and', filters: [...] }\n */\nexport function transformFiltersForServer(filters: Filter[]): any[] {\n const transformFilter = (filter: Filter): any => {\n if (isSimpleFilter(filter)) {\n return filter\n } else if (isGroupFilter(filter)) {\n const transformedSubFilters = filter.filters.map(transformFilter)\n \n if (filter.type === 'and') {\n return { and: transformedSubFilters }\n } else {\n return { or: transformedSubFilters }\n }\n }\n return filter\n }\n \n return filters.map(transformFilter)\n}\n\n/**\n * Date range utility functions\n */\n\n/**\n * Convert DateRangeType to Cube.js compatible date range format\n */\nexport function convertDateRangeTypeToValue(rangeType: string, number?: number): string {\n const typeMap: Record<string, string> = {\n 'today': 'today',\n 'yesterday': 'yesterday',\n 'this_week': 'this week',\n 'this_month': 'this month',\n 'this_quarter': 'this quarter',\n 'this_year': 'this year',\n 'last_7_days': 'last 7 days',\n 'last_30_days': 'last 30 days',\n 'last_week': 'last week',\n 'last_month': 'last month',\n 'last_quarter': 'last quarter',\n 'last_year': 'last year',\n 'last_12_months': 'last 12 months'\n }\n \n // Handle dynamic ranges with number input\n if (rangeType.startsWith('last_n_') && number !== undefined && number > 0) {\n const unit = rangeType.replace('last_n_', '')\n const unitSingular = unit.slice(0, -1) // Remove 's' for singular form\n return number === 1 ? `last ${unitSingular}` : `last ${number} ${unit}`\n }\n \n return typeMap[rangeType] || rangeType\n}\n\n/**\n * Check if a date range type requires a number input\n */\nexport function requiresNumberInput(rangeType: string): boolean {\n return rangeType.startsWith('last_n_')\n}\n\n/**\n * Format date for Cube.js (YYYY-MM-DD)\n */\nexport function formatDateForCube(date: Date): string {\n return date.toISOString().split('T')[0]\n}\n\n/**\n * Get the time dimensions that have date ranges applied\n */\nexport function getTimeDimensionsWithDateRanges(query: CubeQuery): Record<string, string | string[]> {\n const dateRanges: Record<string, string | string[]> = {}\n \n if (query.timeDimensions) {\n query.timeDimensions.forEach(td => {\n if (td.dateRange) {\n dateRanges[td.dimension] = td.dateRange\n }\n })\n }\n \n return dateRanges\n}\n\n/**\n * Check if a query has any time dimensions\n */\nexport function hasTimeDimensions(query: CubeQuery): boolean {\n return Boolean(query.timeDimensions && query.timeDimensions.length > 0)\n}\n\n/**\n * Transform a Cube.js query from external format to UI internal format\n * This handles format differences between server/API queries and QueryBuilder state\n */\nexport function transformQueryForUI(query: any): CubeQuery {\n if (!query || typeof query !== 'object') {\n return {}\n }\n \n const transformed: CubeQuery = {}\n \n // Copy simple fields if they exist\n if (query.measures) transformed.measures = Array.isArray(query.measures) ? query.measures : []\n if (query.dimensions) transformed.dimensions = Array.isArray(query.dimensions) ? query.dimensions : []\n if (query.timeDimensions) transformed.timeDimensions = Array.isArray(query.timeDimensions) ? query.timeDimensions : []\n if (query.order) transformed.order = query.order\n if (query.limit) transformed.limit = query.limit\n if (query.offset) transformed.offset = query.offset\n if (query.segments) transformed.segments = Array.isArray(query.segments) ? query.segments : []\n \n // Transform filters from server format to UI format\n if (query.filters && Array.isArray(query.filters)) {\n transformed.filters = transformFiltersFromServer(query.filters)\n }\n \n return cleanQuery(transformed)\n}\n\n/**\n * Transform filters from server/API format to UI format\n * Converts {and: [...]} and {or: [...]} to {type: 'and', filters: [...]} format\n */\nfunction transformFiltersFromServer(filters: any[]): Filter[] {\n return filters.map(filter => {\n if (!filter || typeof filter !== 'object') {\n return filter\n }\n \n // Handle legacy {and: [...]} format\n if ('and' in filter && Array.isArray(filter.and)) {\n return {\n type: 'and',\n filters: transformFiltersFromServer(filter.and)\n } as GroupFilter\n }\n \n // Handle legacy {or: [...]} format\n if ('or' in filter && Array.isArray(filter.or)) {\n return {\n type: 'or',\n filters: transformFiltersFromServer(filter.or)\n } as GroupFilter\n }\n \n // Handle new format {type: 'and', filters: [...]} - process recursively\n if ('type' in filter && 'filters' in filter && Array.isArray(filter.filters)) {\n return {\n type: filter.type,\n filters: transformFiltersFromServer(filter.filters)\n } as GroupFilter\n }\n \n // Simple filter - pass through\n return filter as SimpleFilter\n }).filter(Boolean) // Remove any null/undefined values\n}\n\n/**\n * Sorting utility functions\n */\n\n/**\n * Get field title from schema metadata, falling back to field name\n */\nexport function getFieldTitle(fieldName: string, schema: MetaResponse | null): string {\n if (!schema) return fieldName\n \n for (const cube of schema.cubes) {\n // Check measures\n const measure = cube.measures.find(m => m.name === fieldName)\n if (measure) return measure.title || measure.shortTitle || fieldName\n \n // Check dimensions\n const dimension = cube.dimensions.find(d => d.name === fieldName)\n if (dimension) return dimension.title || dimension.shortTitle || fieldName\n }\n \n return fieldName // Fallback to field name if not found\n}\n\n/**\n * Clean up order object by removing fields that are no longer in the query\n */\nexport function cleanupOrder(order: Record<string, 'asc' | 'desc'> | undefined, query: CubeQuery): Record<string, 'asc' | 'desc'> | undefined {\n if (!order) return undefined\n \n const allFields = [\n ...(query.measures || []),\n ...(query.dimensions || []),\n ...(query.timeDimensions || []).map(td => td.dimension)\n ]\n \n const cleanedOrder: Record<string, 'asc' | 'desc'> = {}\n for (const [field, direction] of Object.entries(order)) {\n if (allFields.includes(field)) {\n cleanedOrder[field] = direction\n }\n }\n \n return Object.keys(cleanedOrder).length > 0 ? cleanedOrder : undefined\n}\n\n/**\n * Get sort direction for a field from the order object\n */\nexport function getSortDirection(fieldName: string, order: Record<string, 'asc' | 'desc'> | undefined): 'asc' | 'desc' | null {\n return order?.[fieldName] || null\n}\n\n/**\n * Get tooltip text for sort button based on current direction\n */\nexport function getSortTooltip(direction: 'asc' | 'desc' | null): string {\n switch (direction) {\n case 'asc':\n return 'Sorted ascending (click for descending)'\n case 'desc':\n return 'Sorted descending (click to remove)'\n default:\n return 'Click to sort ascending'\n }\n}\n\n/**\n * Get next sort direction in the cycle: null -> asc -> desc -> null\n */\nexport function getNextSortDirection(current: 'asc' | 'desc' | null): 'asc' | 'desc' | null {\n switch (current) {\n case null:\n return 'asc'\n case 'asc':\n return 'desc'\n case 'desc':\n return null\n default:\n return 'asc'\n }\n}","/**\n * FilterItem Component\n * \n * Renders a single filter with field selection, operator selection, and value input.\n * Handles all the logic for individual filter management.\n */\n\nimport React, { useState, useEffect, useRef } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterValueSelector from './FilterValueSelector'\nimport type { FilterItemProps, MetaField, DateRangeType } from './types'\nimport { getAllFilterableFields, getOrganizedFilterFields, getFieldType, getAvailableOperators, convertDateRangeTypeToValue, formatDateForCube, requiresNumberInput } from './utils'\nimport { getMeasureIcon } from '../../utils/measureIcons'\nimport { DATE_RANGE_OPTIONS } from './types'\n\nconst CloseIcon = getIcon('close')\nconst FilterIcon = getIcon('filter')\nconst ChevronDownIcon = getIcon('chevronDown')\nconst SearchIcon = getIcon('search')\nconst DimensionIcon = getIcon('dimension')\nconst TimeDimensionIcon = getIcon('timeDimension')\n\nconst FilterItem: React.FC<FilterItemProps> = ({\n filter,\n index,\n onFilterChange,\n onFilterRemove,\n schema,\n query,\n hideFieldSelector = false,\n hideOperatorSelector = false,\n hideRemoveButton = false\n}) => {\n const [isFieldDropdownOpen, setIsFieldDropdownOpen] = useState(false)\n const [isOperatorDropdownOpen, setIsOperatorDropdownOpen] = useState(false)\n const [isDateRangeDropdownOpen, setIsDateRangeDropdownOpen] = useState(false)\n const [fieldSearchTerm, setFieldSearchTerm] = useState('')\n const containerRef = useRef<HTMLDivElement>(null)\n const searchInputRef = useRef<HTMLInputElement>(null)\n\n // Date range state - always initialized with defaults (must be before any early returns)\n const [rangeType, setRangeType] = useState<DateRangeType>('this_month')\n const [customDates, setCustomDates] = useState({\n startDate: formatDateForCube(new Date()),\n endDate: formatDateForCube(new Date())\n })\n const [numberValue, setNumberValue] = useState<number>(1)\n\n // Close dropdowns when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsFieldDropdownOpen(false)\n setIsOperatorDropdownOpen(false)\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [])\n\n // Close other dropdowns when opening one\n const handleFieldDropdownToggle = () => {\n setIsOperatorDropdownOpen(false)\n const newOpen = !isFieldDropdownOpen\n setIsFieldDropdownOpen(newOpen)\n setFieldSearchTerm('') // Reset search when toggling\n\n // Focus search input when opening\n if (newOpen) {\n setTimeout(() => searchInputRef.current?.focus(), 50)\n }\n }\n\n const handleOperatorDropdownToggle = () => {\n setIsFieldDropdownOpen(false)\n setIsOperatorDropdownOpen(!isOperatorDropdownOpen)\n }\n\n // Get field info (safe defaults if schema not loaded)\n const allFields = schema ? getAllFilterableFields(schema) : []\n const { queryFields } = schema ? getOrganizedFilterFields(schema, query) : { queryFields: [] }\n const selectedField = allFields.find(f => f.name === filter.member)\n const fieldType = selectedField ? selectedField.type : 'string'\n const availableOperators = getAvailableOperators(fieldType)\n\n // Determine if we should show date range selector (for time fields with inDateRange operator)\n const shouldShowDateRangeSelector = fieldType === 'time' && filter.operator === 'inDateRange'\n\n // Update date range state when filter.dateRange changes (must be before early return)\n useEffect(() => {\n if (!shouldShowDateRangeSelector || !filter.dateRange) return\n\n // Update rangeType\n if (Array.isArray(filter.dateRange)) {\n setRangeType('custom')\n setCustomDates({\n startDate: filter.dateRange[0] || '',\n endDate: filter.dateRange[1] || filter.dateRange[0] || ''\n })\n } else {\n // Check for flexible range patterns\n const flexibleRangeMatch = filter.dateRange.match(/^last (\\d+) (days|weeks|months|quarters|years)$/)\n if (flexibleRangeMatch) {\n const [, num, unit] = flexibleRangeMatch\n const unitPlural = unit === 'days' ? 'days' : unit === 'weeks' ? 'weeks' : unit === 'months' ? 'months' : unit === 'quarters' ? 'quarters' : 'years'\n setRangeType(`last_n_${unitPlural}` as DateRangeType)\n setNumberValue(parseInt(num) || 1)\n } else {\n // Check for predefined ranges\n let found = false\n for (const option of DATE_RANGE_OPTIONS) {\n if (option.value !== 'custom' && !requiresNumberInput(option.value) && convertDateRangeTypeToValue(option.value) === filter.dateRange) {\n setRangeType(option.value)\n found = true\n break\n }\n }\n if (!found) {\n setRangeType('custom')\n }\n }\n }\n }, [filter.dateRange, shouldShowDateRangeSelector])\n\n // Early return AFTER all hooks\n if (!schema) {\n return (\n <div className=\"text-sm text-dc-text-muted\">\n Schema not loaded\n </div>\n )\n }\n \n // Filter fields based on search term\n const filterFieldsBySearch = (fields: MetaField[]) => {\n if (!fieldSearchTerm) return fields\n const searchTerm = fieldSearchTerm.toLowerCase()\n return fields.filter(field => \n field.name.toLowerCase().includes(searchTerm) ||\n field.title.toLowerCase().includes(searchTerm) ||\n field.shortTitle.toLowerCase().includes(searchTerm)\n )\n }\n \n const filteredQueryFields = filterFieldsBySearch(queryFields)\n const filteredAllFields = filterFieldsBySearch(allFields)\n \n // Helper function to get field type icon\n const getFieldTypeIcon = (field: MetaField) => {\n if (field.type === 'time') {\n return <TimeDimensionIcon className=\"w-3 h-3 text-blue-500\" />\n } else if (['count', 'sum', 'avg', 'min', 'max', 'countDistinct', 'countDistinctApprox', 'runningTotal', 'calculated', 'number'].includes(field.type)) {\n // Use dynamic icon based on measure type, with amber color\n const icon = getMeasureIcon(field.type, 'w-3 h-3 text-amber-500')\n return icon\n } else {\n return <DimensionIcon className=\"w-3 h-3 text-green-500\" />\n }\n }\n\n // Helper function to get field type badge\n const getFieldTypeBadge = (field: MetaField) => {\n if (field.type === 'time') {\n return <span className=\"text-xs bg-dc-time-dimension text-dc-time-dimension px-1.5 py-0.5 rounded-sm\">T</span>\n } else if (['count', 'sum', 'avg', 'min', 'max', 'countDistinct', 'number'].includes(field.type)) {\n return <span className=\"text-xs bg-dc-measure text-dc-measure px-1.5 py-0.5 rounded-sm\">M</span>\n } else {\n return <span className=\"text-xs bg-dc-dimension text-dc-dimension px-1.5 py-0.5 rounded-sm\">D</span>\n }\n }\n\n const handleFieldChange = (fieldName: string) => {\n // When field changes, reset operator and values\n const newFieldType = getFieldType(fieldName, schema)\n const newAvailableOperators = getAvailableOperators(newFieldType)\n const defaultOperator = newAvailableOperators[0]?.operator || 'equals'\n\n onFilterChange(index, {\n member: fieldName,\n operator: defaultOperator as any,\n values: [],\n dateRange: undefined // Reset dateRange when field changes\n })\n setIsFieldDropdownOpen(false)\n }\n \n const handleOperatorChange = (operator: string) => {\n onFilterChange(index, {\n ...filter,\n operator: operator as any,\n values: [], // Reset values when operator changes\n dateRange: undefined // Reset dateRange when operator changes\n })\n setIsOperatorDropdownOpen(false)\n }\n \n const handleValuesChange = (values: any[]) => {\n onFilterChange(index, {\n ...filter,\n values\n })\n }\n\n // Date range handlers for time dimension filters\n const handleDateRangeChange = (dateRange: string | string[]) => {\n onFilterChange(index, {\n ...filter,\n dateRange\n })\n }\n\n const handleRangeTypeChange = (newRangeType: DateRangeType) => {\n setIsDateRangeDropdownOpen(false)\n\n if (newRangeType === 'custom') {\n // For custom, use current custom dates or default to today\n if (customDates.startDate && customDates.endDate) {\n const dateRange = customDates.startDate === customDates.endDate\n ? customDates.startDate\n : [customDates.startDate, customDates.endDate]\n handleDateRangeChange(dateRange)\n }\n } else if (requiresNumberInput(newRangeType)) {\n // For number-based ranges, use the number value\n const cubeRangeValue = convertDateRangeTypeToValue(newRangeType, numberValue)\n handleDateRangeChange(cubeRangeValue)\n } else {\n // For predefined ranges, use the converted value\n const cubeRangeValue = convertDateRangeTypeToValue(newRangeType)\n handleDateRangeChange(cubeRangeValue)\n }\n\n setRangeType(newRangeType)\n }\n\n const handleCustomDateChange = (field: 'startDate' | 'endDate', value: string) => {\n const newCustomDates = { ...customDates, [field]: value }\n setCustomDates(newCustomDates)\n\n if (rangeType === 'custom' && newCustomDates.startDate) {\n const dateRange = !newCustomDates.endDate || newCustomDates.startDate === newCustomDates.endDate\n ? newCustomDates.startDate\n : [newCustomDates.startDate, newCustomDates.endDate]\n handleDateRangeChange(dateRange)\n }\n }\n\n const handleNumberChange = (value: number) => {\n setNumberValue(value)\n\n if (requiresNumberInput(rangeType)) {\n const cubeRangeValue = convertDateRangeTypeToValue(rangeType, value)\n handleDateRangeChange(cubeRangeValue)\n }\n }\n\n const selectedRangeLabel = DATE_RANGE_OPTIONS.find(opt => opt.value === rangeType)?.label || 'Custom'\n\n return (\n <div ref={containerRef} className=\"bg-dc-surface border border-dc-border rounded-lg p-3\">\n {/* Responsive layout - stacks on mobile, single row on desktop */}\n <div className=\"flex flex-col sm:flex-row sm:items-center gap-3 min-w-0\">\n {/* Row 1 on mobile: Filter icon and field selection - conditionally hidden */}\n {!hideFieldSelector && (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <FilterIcon className=\"w-4 h-4 text-dc-text-muted shrink-0\" />\n\n {/* Field selection */}\n <div className=\"relative flex-1 min-w-0\">\n <button\n onClick={handleFieldDropdownToggle}\n className=\"w-full flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500 min-w-0\"\n >\n <span className=\"truncate\">\n {selectedField ? (\n <span className=\"font-medium\">{selectedField.name}</span>\n ) : (\n <span className=\"text-dc-text-muted\">Select field...</span>\n )}\n </span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isFieldDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isFieldDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-80 overflow-hidden\">\n {/* Search input */}\n <div className=\"p-2 border-b border-dc-border\">\n <div className=\"relative\">\n <SearchIcon className=\"w-4 h-4 absolute left-2 top-1/2 transform -translate-y-1/2 text-dc-text-muted\" />\n <input\n ref={searchInputRef}\n type=\"text\"\n placeholder=\"Search fields...\"\n value={fieldSearchTerm}\n onChange={(e) => setFieldSearchTerm(e.target.value)}\n className=\"w-full pl-8 pr-3 py-1.5 text-sm border border-dc-border rounded-sm bg-dc-surface text-dc-text focus:ring-1 focus:ring-blue-500 focus:border-blue-500\"\n />\n </div>\n </div>\n\n {/* Fields list */}\n <div className=\"max-h-60 overflow-y-auto\">\n {/* Query fields section */}\n {filteredQueryFields.length > 0 && (\n <div>\n <div className=\"px-3 py-1.5 text-xs font-medium text-dc-text-muted bg-dc-surface-secondary border-b border-dc-border\">\n Fields in Query ({filteredQueryFields.length})\n </div>\n {filteredQueryFields.map((field) => (\n <button\n key={`query-${field.name}`}\n onClick={() => handleFieldChange(field.name)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${\n field.name === filter.member ? 'bg-blue-50 text-blue-700' : 'text-dc-text-secondary'\n }`}\n >\n <div className=\"flex items-center gap-2\">\n {getFieldTypeIcon(field)}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium truncate\">{field.name}</span>\n {getFieldTypeBadge(field)}\n </div>\n {field.title !== field.name && (\n <div className=\"text-xs text-dc-text-muted truncate\">{field.title}</div>\n )}\n </div>\n </div>\n </button>\n ))}\n </div>\n )}\n\n {/* All fields section */}\n <div>\n {filteredQueryFields.length > 0 && (\n <div className=\"px-3 py-1.5 text-xs font-medium text-dc-text-muted bg-dc-surface-secondary border-b border-dc-border\">\n All Available Fields ({filteredAllFields.length})\n </div>\n )}\n {filteredAllFields.map((field) => (\n <button\n key={`all-${field.name}`}\n onClick={() => handleFieldChange(field.name)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${\n field.name === filter.member ? 'bg-blue-50 text-blue-700' : 'text-dc-text-secondary'\n }`}\n >\n <div className=\"flex items-center gap-2\">\n {getFieldTypeIcon(field)}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium truncate\">{field.name}</span>\n {getFieldTypeBadge(field)}\n </div>\n {field.title !== field.name && (\n <div className=\"text-xs text-dc-text-muted truncate\">{field.title}</div>\n )}\n </div>\n </div>\n </button>\n ))}\n </div>\n\n {/* No results message */}\n {filteredAllFields.length === 0 && (\n <div className=\"px-3 py-4 text-sm text-dc-text-muted text-center\">\n No fields found matching \"{fieldSearchTerm}\"\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Row 2 on mobile: Operator and Value selection */}\n {selectedField && (\n <div className=\"flex items-center gap-2 flex-1 sm:flex-initial min-w-0\">\n {/* Operator selection - conditionally hidden */}\n {!hideOperatorSelector && (\n <div className=\"relative shrink-0\">\n <button\n onClick={handleOperatorDropdownToggle}\n className=\"w-full sm:w-32 flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n >\n <span className=\"truncate\">\n {availableOperators.find(op => op.operator === filter.operator)?.label || filter.operator}\n </span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isOperatorDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isOperatorDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {availableOperators.map((operator) => (\n <button\n key={operator.operator}\n onClick={() => handleOperatorChange(operator.operator)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${\n operator.operator === filter.operator ? 'bg-blue-50 text-blue-700' : 'text-dc-text-secondary'\n }`}\n >\n {operator.label}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Value input or Date Range Selector */}\n <div className=\"flex-1 min-w-0\">\n {shouldShowDateRangeSelector ? (\n /* Date Range Selector for time dimensions with inDateRange */\n <div className=\"flex items-center gap-2\">\n {/* Range type selector */}\n <div className=\"relative shrink-0\">\n <button\n onClick={() => {\n setIsOperatorDropdownOpen(false)\n setIsDateRangeDropdownOpen(!isDateRangeDropdownOpen)\n }}\n className=\"w-full sm:w-40 flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n >\n <span className=\"truncate\">{selectedRangeLabel}</span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isDateRangeDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isDateRangeDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {DATE_RANGE_OPTIONS.map((option) => (\n <button\n key={option.value}\n onClick={() => handleRangeTypeChange(option.value)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${\n option.value === rangeType ? 'bg-blue-50 text-blue-700' : 'text-dc-text-secondary'\n }`}\n >\n {option.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Custom date inputs or number input */}\n {rangeType === 'custom' ? (\n <>\n <input\n type=\"date\"\n value={customDates.startDate}\n onChange={(e) => handleCustomDateChange('startDate', e.target.value)}\n placeholder=\"Start date\"\n className=\"flex-1 min-w-0 text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n <input\n type=\"date\"\n value={customDates.endDate}\n onChange={(e) => handleCustomDateChange('endDate', e.target.value)}\n placeholder=\"End date\"\n className=\"flex-1 min-w-0 text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n </>\n ) : requiresNumberInput(rangeType) ? (\n <>\n <input\n type=\"number\"\n min=\"1\"\n max=\"1000\"\n value={numberValue}\n onChange={(e) => handleNumberChange(Math.max(1, parseInt(e.target.value) || 1))}\n placeholder=\"Number\"\n className=\"flex-1 min-w-0 text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n <div className=\"shrink-0 text-sm text-dc-text-secondary\">\n {rangeType.replace('last_n_', '').replace('_', ' ')}\n </div>\n </>\n ) : null}\n </div>\n ) : (\n /* Regular FilterValueSelector for non-dateRange filters */\n <FilterValueSelector\n fieldName={filter.member}\n operator={filter.operator}\n values={filter.values}\n onValuesChange={handleValuesChange}\n schema={schema}\n />\n )}\n </div>\n </div>\n )}\n \n {/* Row 3 on mobile: Remove button - conditionally hidden */}\n {!hideRemoveButton && (\n <div className=\"flex justify-end sm:justify-start\">\n <button\n onClick={() => onFilterRemove(index)}\n className=\"text-dc-text-muted hover:text-red-600 focus:outline-none shrink-0\"\n title=\"Remove filter\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default FilterItem","/**\n * FilterGroup Component\n * \n * Handles AND/OR logical groups with support for infinite nesting.\n * Renders child filters with proper indentation and group controls.\n */\n\nimport React, { useState } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterItem from './FilterItem'\nimport type { FilterGroupProps } from './types'\nimport type { SimpleFilter, GroupFilter } from '../../types'\nimport {\n isSimpleFilter,\n isGroupFilter,\n createSimpleFilter,\n createAndFilter,\n createOrFilter,\n getFilterableFields\n} from './utils'\n\nconst CloseIcon = getIcon('close')\nconst AddIcon = getIcon('add')\n\nconst FilterGroup: React.FC<FilterGroupProps> = ({\n group,\n index,\n onGroupChange,\n onGroupChangeWithUnwrap,\n onGroupRemove,\n schema,\n query,\n depth = 0\n}) => {\n const [showAddMenu, setShowAddMenu] = useState(false)\n \n const isAndGroup = group.type === 'and'\n const groupType = isAndGroup ? 'AND' : 'OR'\n const filters = group.filters\n \n // Style based on depth for visual nesting\n const indentClass = depth > 0 ? `ml-${Math.min(depth * 4, 16)}` : ''\n const borderColor = 'border-slate-200'\n const bgColor = 'bg-slate-50'\n const textColor = 'text-slate-700'\n \n const handleGroupTypeToggle = () => {\n if (isAndGroup) {\n const newGroup = createOrFilter(filters)\n onGroupChange(index, newGroup)\n } else {\n const newGroup = createAndFilter(filters)\n onGroupChange(index, newGroup)\n }\n }\n \n const handleAddSimpleFilter = () => {\n if (!schema) return\n \n // Get the first available field as default\n const filterableFields = getFilterableFields(schema, query)\n const defaultField = filterableFields[0]?.name || ''\n const newFilter = createSimpleFilter(defaultField, 'equals', [])\n const newFilters = [...filters, newFilter]\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n setShowAddMenu(false)\n }\n \n const handleAddAndGroup = () => {\n if (!schema) return\n \n // Get the first available field as default\n const filterableFields = getFilterableFields(schema, query)\n const defaultField = filterableFields[0]?.name || ''\n const newGroup = createAndFilter([createSimpleFilter(defaultField, 'equals', [])])\n const newFilters = [...filters, newGroup]\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n setShowAddMenu(false)\n }\n \n const handleAddOrGroup = () => {\n if (!schema) return\n \n // Get the first available field as default\n const filterableFields = getFilterableFields(schema, query)\n const defaultField = filterableFields[0]?.name || ''\n const newGroup = createOrFilter([createSimpleFilter(defaultField, 'equals', [])])\n const newFilters = [...filters, newGroup]\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n setShowAddMenu(false)\n }\n \n const handleFilterChange = (filterIndex: number, newFilter: SimpleFilter) => {\n const newFilters = [...filters]\n newFilters[filterIndex] = newFilter\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n }\n \n const handleFilterRemove = (filterIndex: number) => {\n const newFilters = filters.filter((_, i) => i !== filterIndex)\n \n // If no filters left, remove the entire group\n if (newFilters.length === 0) {\n onGroupRemove(index)\n return\n }\n \n // If only one filter left, use unwrapping handler if available\n if (newFilters.length === 1) {\n const newGroup = group.type === 'and' ? createAndFilter(newFilters) : createOrFilter(newFilters)\n \n if (onGroupChangeWithUnwrap) {\n // Use the unwrapping handler for removal scenarios\n onGroupChangeWithUnwrap(index, newGroup)\n } else {\n // Fallback to regular handler (for nested groups)\n onGroupChange(index, newGroup)\n }\n return\n }\n \n // Otherwise, update the group with remaining filters (preserve the group type)\n const updatedGroup = group.type === 'and' ? createAndFilter(newFilters) : createOrFilter(newFilters)\n onGroupChange(index, updatedGroup)\n }\n \n const handleNestedGroupChange = (filterIndex: number, newGroup: GroupFilter) => {\n const newFilters = [...filters]\n newFilters[filterIndex] = newGroup\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n }\n \n const handleNestedGroupRemove = (filterIndex: number) => {\n handleFilterRemove(filterIndex)\n }\n \n return (\n <div className={`${indentClass} ${borderColor} border-2 ${bgColor} rounded-lg p-4 space-y-3`}>\n {/* Group header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center space-x-2\">\n <button\n onClick={handleGroupTypeToggle}\n className={`px-3 py-1 rounded-sm text-sm font-semibold ${textColor} border border-current hover:bg-dc-surface hover:bg-opacity-20 focus:outline-hidden focus:ring-2 focus:ring-current focus:ring-opacity-50`}\n >\n {groupType}\n </button>\n <span className=\"text-sm text-dc-text-secondary\">\n {filters.length} condition{filters.length !== 1 ? 's' : ''}\n </span>\n </div>\n\n <div className=\"flex items-center space-x-2\">\n {/* Add menu */}\n <div className=\"relative\">\n <button\n onClick={() => setShowAddMenu(!showAddMenu)}\n className=\"text-dc-text-muted hover:text-dc-text-secondary focus:outline-hidden\"\n title=\"Add condition\"\n >\n <AddIcon className=\"w-4 h-4\" />\n </button>\n\n {showAddMenu && (\n <div className=\"absolute right-0 mt-1 w-48 bg-dc-surface border border-dc-border rounded-md shadow-lg z-30\">\n <button\n onClick={handleAddSimpleFilter}\n className=\"w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover\"\n >\n Add Filter\n </button>\n <button\n onClick={handleAddAndGroup}\n className=\"w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover\"\n >\n Add AND Group\n </button>\n <button\n onClick={handleAddOrGroup}\n className=\"w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover\"\n >\n Add OR Group\n </button>\n </div>\n )}\n </div>\n\n {/* Remove group button */}\n <button\n onClick={() => onGroupRemove(index)}\n className=\"text-dc-text-muted hover:text-red-600 focus:outline-hidden\"\n title=\"Remove group\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n \n {/* Group content */}\n <div className=\"space-y-3\">\n {filters.map((filter, filterIndex) => {\n if (isSimpleFilter(filter)) {\n return (\n <FilterItem\n key={filterIndex}\n filter={filter}\n index={filterIndex}\n onFilterChange={handleFilterChange}\n onFilterRemove={handleFilterRemove}\n schema={schema}\n query={query}\n />\n )\n } else if (isGroupFilter(filter)) {\n return (\n <FilterGroup\n key={filterIndex}\n group={filter}\n index={filterIndex}\n onGroupChange={handleNestedGroupChange}\n onGroupRemove={handleNestedGroupRemove}\n schema={schema}\n query={query}\n depth={depth + 1}\n />\n )\n }\n return null\n })}\n \n {/* Empty state */}\n {filters.length === 0 && (\n <div className=\"text-center py-4 text-dc-text-muted text-sm\">\n No conditions in this group.\n <button\n onClick={handleAddSimpleFilter}\n className=\"ml-2 text-purple-600 hover:text-purple-800 focus:outline-hidden underline\"\n >\n Add a filter\n </button>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default FilterGroup","/**\n * FilterBuilder Component\n * \n * Main component for managing all filters in the query.\n * Handles the top-level filter state and provides controls for adding new filters and groups.\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport FilterItem from './FilterItem'\nimport FilterGroup from './FilterGroup'\nimport type { FilterBuilderProps } from './types'\nimport type { SimpleFilter, GroupFilter } from '../../types'\nimport {\n isSimpleFilter,\n isGroupFilter,\n isAndFilter,\n isOrFilter,\n createSimpleFilter,\n createAndFilter,\n createOrFilter,\n countFilters,\n getAllFilterableFields\n} from './utils'\n\nconst AddIcon = getIcon('add')\nconst FilterIcon = getIcon('filter')\n\nconst FilterBuilder: React.FC<FilterBuilderProps> = ({\n filters,\n schema,\n query,\n onFiltersChange,\n hideFieldSelector = false\n}) => {\n \n \n const totalFilterCount = countFilters(filters)\n \n // Get all filterable fields from schema\n const allFilterableFields = schema ? getAllFilterableFields(schema) : []\n const hasFilterableFields = allFilterableFields.length > 0\n \n const handleAddSimpleFilter = () => {\n if (!hasFilterableFields) return\n \n // Use the first available field as default\n const defaultField = allFilterableFields[0]?.name || ''\n const newFilter = createSimpleFilter(defaultField, 'equals', [])\n \n // Smart filter grouping logic:\n // - First filter: add as simple filter\n // - Second filter: create AND group with first filter + new filter\n // - Additional filters: add to existing group (AND or OR, respecting current type)\n \n if (filters.length === 0) {\n // First filter - add as simple filter\n onFiltersChange([newFilter])\n } else if (filters.length === 1 && isSimpleFilter(filters[0])) {\n // Second filter - create AND group with existing filter + new filter\n const andGroup = createAndFilter([filters[0], newFilter])\n onFiltersChange([andGroup])\n } else if (filters.length === 1 && isAndFilter(filters[0])) {\n // Additional filter - add to existing AND group\n const existingAndGroup = filters[0]\n const updatedAndGroup = createAndFilter([...existingAndGroup.filters, newFilter])\n onFiltersChange([updatedAndGroup])\n } else if (filters.length === 1 && isOrFilter(filters[0])) {\n // Additional filter - add to existing OR group\n const existingOrGroup = filters[0]\n const updatedOrGroup = createOrFilter([...existingOrGroup.filters, newFilter])\n onFiltersChange([updatedOrGroup])\n } else {\n // Fallback: just add to the end (shouldn't happen with new logic)\n onFiltersChange([...filters, newFilter])\n }\n }\n \n \n const handleFilterChange = (index: number, newFilter: SimpleFilter) => {\n const newFilters = [...filters]\n newFilters[index] = newFilter\n onFiltersChange(newFilters)\n }\n \n const handleFilterRemove = (index: number) => {\n // Simple case: just remove the filter\n // The handleGroupChange method will automatically handle unwrapping if needed\n const newFilters = filters.filter((_, i) => i !== index)\n onFiltersChange(newFilters)\n }\n \n const handleGroupChange = (index: number, newGroup: GroupFilter) => {\n const newFilters = [...filters]\n newFilters[index] = newGroup\n onFiltersChange(newFilters)\n }\n \n const handleGroupChangeWithUnwrap = (index: number, newGroup: GroupFilter) => {\n const newFilters = [...filters]\n \n // Check if the group has been reduced to a single filter and should be unwrapped\n // This is only used during filter removal operations\n if (newGroup.filters.length === 1 && isSimpleFilter(newGroup.filters[0])) {\n // Unwrap the single filter from the group\n newFilters[index] = newGroup.filters[0]\n } else {\n newFilters[index] = newGroup\n }\n \n onFiltersChange(newFilters)\n }\n \n const handleGroupRemove = () => {\n // When removing an AND group, we should remove all filters\n onFiltersChange([])\n }\n \n const handleClearAllFilters = () => {\n onFiltersChange([])\n }\n \n return (\n <div className=\"space-y-4 bg-dc-surface-secondary rounded-lg p-4\">\n {/* Header - hidden for universal time filters */}\n {!hideFieldSelector && (\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center\">\n <FilterIcon className=\"w-4 h-4 text-dc-text-muted mr-2\" />\n <h4 className=\"text-sm font-semibold text-dc-text-secondary\">\n Filters ({totalFilterCount})\n </h4>\n </div>\n\n <div className=\"flex items-center space-x-2\">\n {/* Clear all button */}\n {filters.length > 0 && (\n <button\n onClick={handleClearAllFilters}\n className=\"text-xs text-dc-text-muted hover:text-red-600 focus:outline-hidden underline\"\n >\n Clear all\n </button>\n )}\n\n {/* Add Filter button */}\n <button\n onClick={handleAddSimpleFilter}\n disabled={!hasFilterableFields}\n className={`flex items-center space-x-1 px-2 py-1 text-xs font-medium rounded focus:outline-hidden focus:ring-2 ${\n hasFilterableFields\n ? 'text-purple-700 bg-purple-100 border border-purple-200 hover:bg-purple-200 focus:ring-purple-500'\n : 'text-dc-text-muted bg-dc-surface-secondary border border-dc-border cursor-not-allowed'\n }`}\n >\n <AddIcon className=\"w-3 h-3\" />\n <span>Add Filter</span>\n </button>\n </div>\n </div>\n )}\n \n {/* Filters list */}\n {filters.length > 0 && (\n <div className=\"space-y-3\">\n {filters.map((filter, index) => {\n \n if (isSimpleFilter(filter)) {\n return (\n <FilterItem\n key={index}\n filter={filter}\n index={index}\n onFilterChange={handleFilterChange}\n onFilterRemove={handleFilterRemove}\n schema={schema}\n query={query}\n hideFieldSelector={hideFieldSelector}\n hideRemoveButton={hideFieldSelector}\n />\n )\n } else if (isGroupFilter(filter)) {\n return (\n <FilterGroup\n key={index}\n group={filter}\n index={index}\n onGroupChange={handleGroupChange}\n onGroupChangeWithUnwrap={handleGroupChangeWithUnwrap}\n onGroupRemove={handleGroupRemove}\n schema={schema}\n query={query}\n depth={0}\n />\n )\n }\n return null\n })}\n </div>\n )}\n \n </div>\n )\n}\n\nexport default FilterBuilder","/**\n * DateRangeSelector Component\n * \n * Individual date range selector for a specific time dimension\n * Styled to match FilterItem component exactly\n */\n\nimport React, { useState, useEffect, useRef } from 'react'\nimport { getIcon } from '../../icons'\nimport { DATE_RANGE_OPTIONS, type DateRangeType } from './types'\nimport { convertDateRangeTypeToValue, formatDateForCube, requiresNumberInput } from './utils'\n\nconst CloseIcon = getIcon('close')\nconst CalendarIcon = getIcon('timeDimension')\nconst ChevronDownIcon = getIcon('chevronDown')\n\ninterface DateRangeSelectorProps {\n timeDimension: string\n availableTimeDimensions: string[]\n currentDateRange?: string | string[]\n onDateRangeChange: (timeDimension: string, dateRange: string | string[]) => void\n onTimeDimensionChange: (oldTimeDimension: string, newTimeDimension: string) => void\n onRemove: (timeDimension: string) => void\n hideFieldSelector?: boolean // Hide the time dimension field selector (for read-only filters)\n hideRemoveButton?: boolean // Hide the remove button (for read-only filters)\n}\n\nconst DateRangeSelector: React.FC<DateRangeSelectorProps> = ({\n timeDimension,\n availableTimeDimensions,\n currentDateRange,\n onDateRangeChange,\n onTimeDimensionChange,\n onRemove,\n hideFieldSelector = false,\n hideRemoveButton = false\n}) => {\n // Parse current date range to determine the type and custom dates\n const getCurrentRangeType = (): DateRangeType => {\n if (!currentDateRange) return 'this_month'\n \n if (Array.isArray(currentDateRange)) {\n return 'custom'\n }\n \n // Check if it's a flexible range with number (e.g., \"last 9 weeks\")\n const flexibleRangeMatch = currentDateRange.match(/^last (\\d+) (days|weeks|months|quarters|years)$/)\n if (flexibleRangeMatch) {\n const [, , unit] = flexibleRangeMatch\n const unitPlural = unit === 'days' ? 'days' : unit === 'weeks' ? 'weeks' : unit === 'months' ? 'months' : unit === 'quarters' ? 'quarters' : 'years'\n return `last_n_${unitPlural}` as DateRangeType\n }\n \n // Find matching predefined range\n for (const option of DATE_RANGE_OPTIONS) {\n if (option.value !== 'custom' && !requiresNumberInput(option.value) && convertDateRangeTypeToValue(option.value) === currentDateRange) {\n return option.value\n }\n }\n \n return 'custom'\n }\n\n const getCurrentDates = (): { startDate: string; endDate: string } => {\n if (Array.isArray(currentDateRange) && currentDateRange.length >= 1) {\n return {\n startDate: currentDateRange[0] || '',\n endDate: currentDateRange[1] || currentDateRange[0] || ''\n }\n }\n \n // Default to today for custom ranges\n const today = formatDateForCube(new Date())\n return { startDate: today, endDate: today }\n }\n\n const getCurrentNumber = (): number => {\n if (!currentDateRange || Array.isArray(currentDateRange)) return 1\n \n // Check if it's a flexible range with number (e.g., \"last 9 weeks\")\n const flexibleRangeMatch = currentDateRange.match(/^last (\\d+) (days|weeks|months|quarters|years)$/)\n if (flexibleRangeMatch) {\n return parseInt(flexibleRangeMatch[1]) || 1\n }\n \n return 1\n }\n\n const [rangeType, setRangeType] = useState<DateRangeType>(getCurrentRangeType())\n const [customDates, setCustomDates] = useState(getCurrentDates())\n const [numberValue, setNumberValue] = useState<number>(getCurrentNumber())\n const [isRangeDropdownOpen, setIsRangeDropdownOpen] = useState(false)\n const [isTimeDimensionDropdownOpen, setIsTimeDimensionDropdownOpen] = useState(false)\n const containerRef = useRef<HTMLDivElement>(null)\n \n // Close dropdowns when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsRangeDropdownOpen(false)\n setIsTimeDimensionDropdownOpen(false)\n }\n }\n \n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [])\n\n // Close other dropdowns when opening one\n const handleTimeDimensionDropdownToggle = () => {\n setIsRangeDropdownOpen(false)\n setIsTimeDimensionDropdownOpen(!isTimeDimensionDropdownOpen)\n }\n \n const handleRangeDropdownToggle = () => {\n setIsTimeDimensionDropdownOpen(false)\n setIsRangeDropdownOpen(!isRangeDropdownOpen)\n }\n\n const handleRangeTypeChange = (newRangeType: DateRangeType) => {\n setRangeType(newRangeType)\n setIsRangeDropdownOpen(false)\n \n if (newRangeType === 'custom') {\n // For custom, use current custom dates or default to today\n if (customDates.startDate && customDates.endDate) {\n const dateRange = customDates.startDate === customDates.endDate \n ? customDates.startDate\n : [customDates.startDate, customDates.endDate]\n onDateRangeChange(timeDimension, dateRange)\n }\n } else if (requiresNumberInput(newRangeType)) {\n // For number-based ranges, use the number value\n const cubeRangeValue = convertDateRangeTypeToValue(newRangeType, numberValue)\n onDateRangeChange(timeDimension, cubeRangeValue)\n } else {\n // For predefined ranges, use the converted value\n const cubeRangeValue = convertDateRangeTypeToValue(newRangeType)\n onDateRangeChange(timeDimension, cubeRangeValue)\n }\n }\n\n const handleCustomDateChange = (field: 'startDate' | 'endDate', value: string) => {\n const newCustomDates = { ...customDates, [field]: value }\n setCustomDates(newCustomDates)\n \n if (rangeType === 'custom' && newCustomDates.startDate) {\n const dateRange = !newCustomDates.endDate || newCustomDates.startDate === newCustomDates.endDate\n ? newCustomDates.startDate\n : [newCustomDates.startDate, newCustomDates.endDate]\n onDateRangeChange(timeDimension, dateRange)\n }\n }\n\n const handleNumberChange = (value: number) => {\n setNumberValue(value)\n \n if (requiresNumberInput(rangeType)) {\n const cubeRangeValue = convertDateRangeTypeToValue(rangeType, value)\n onDateRangeChange(timeDimension, cubeRangeValue)\n }\n }\n\n const handleTimeDimensionChange = (newTimeDimension: string) => {\n setIsTimeDimensionDropdownOpen(false)\n onTimeDimensionChange(timeDimension, newTimeDimension)\n }\n\n const selectedRangeLabel = DATE_RANGE_OPTIONS.find(opt => opt.value === rangeType)?.label || 'Custom'\n\n return (\n <div ref={containerRef} className=\"bg-dc-surface border border-dc-border rounded-lg p-3\">\n {/* Responsive layout - stacks on mobile, single row on desktop */}\n <div className=\"flex flex-col sm:flex-row sm:items-center gap-3 min-w-0\">\n {/* Row 1: Filter icon and time dimension field - conditionally hidden */}\n {!hideFieldSelector && (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <CalendarIcon className=\"w-4 h-4 text-dc-text-muted shrink-0\" />\n\n {/* Time dimension field selector */}\n <div className=\"relative flex-1 min-w-0\">\n <button\n onClick={handleTimeDimensionDropdownToggle}\n className=\"w-full flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500 min-w-0\"\n >\n <span className=\"truncate\">{timeDimension}</span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 transition-transform ${\n isTimeDimensionDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isTimeDimensionDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {availableTimeDimensions.map((td) => (\n <button\n key={td}\n onClick={() => handleTimeDimensionChange(td)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${\n td === timeDimension ? 'bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300' : 'text-dc-text-secondary'\n }`}\n >\n {td}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Row 2: Date range selector */}\n <div className=\"flex items-center gap-2 flex-1 sm:flex-initial min-w-0\">\n {/* Range type selector with custom dropdown */}\n <div className=\"relative shrink-0\">\n <button\n onClick={handleRangeDropdownToggle}\n className=\"w-full sm:w-40 flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n >\n <span className=\"truncate\">{selectedRangeLabel}</span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isRangeDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isRangeDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {DATE_RANGE_OPTIONS.map((option) => (\n <button\n key={option.value}\n onClick={() => handleRangeTypeChange(option.value)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${\n option.value === rangeType ? 'bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300' : 'text-dc-text-secondary'\n }`}\n >\n {option.label}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* Row 3: Custom date inputs, number input, or remove button */}\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {rangeType === 'custom' ? (\n <>\n {/* Start date */}\n <div className=\"flex-1 min-w-0\">\n <input\n type=\"date\"\n value={customDates.startDate}\n onChange={(e) => handleCustomDateChange('startDate', e.target.value)}\n placeholder=\"dd/mm/yyyy\"\n className=\"w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n </div>\n\n {/* End date (optional) */}\n <div className=\"flex-1 min-w-0\">\n <input\n type=\"date\"\n value={customDates.endDate}\n onChange={(e) => handleCustomDateChange('endDate', e.target.value)}\n placeholder=\"dd/mm/yyyy\"\n className=\"w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n </div>\n </>\n ) : requiresNumberInput(rangeType) ? (\n <>\n {/* Number input for flexible ranges */}\n <div className=\"flex-1 min-w-0\">\n <input\n type=\"number\"\n min=\"1\"\n max=\"1000\"\n value={numberValue}\n onChange={(e) => handleNumberChange(Math.max(1, parseInt(e.target.value) || 1))}\n placeholder=\"Number\"\n className=\"w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n </div>\n\n {/* Unit display */}\n <div className=\"shrink-0 text-sm text-dc-text-secondary\">\n {rangeType.replace('last_n_', '').replace('_', ' ')}\n </div>\n </>\n ) : (\n // Empty placeholder to maintain layout consistency\n <div className=\"flex-1\"></div>\n )}\n\n {/* Remove button - conditionally hidden */}\n {!hideRemoveButton && (\n <button\n onClick={() => onRemove(timeDimension)}\n className=\"text-dc-text-muted hover:text-red-600 focus:outline-hidden shrink-0 p-1\"\n title=\"Remove date range\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n </div>\n </div>\n )\n}\n\nexport default DateRangeSelector","/**\n * DateRangeFilter Component\n * \n * Container component for managing date ranges on time dimensions.\n * Shows all time dimensions with date ranges and provides controls for adding new ones.\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport DateRangeSelector from './DateRangeSelector'\nimport type { DateRangeFilterProps } from './types'\nimport { getTimeDimensionsWithDateRanges } from './utils'\n\nconst AddIcon = getIcon('add')\nconst CalendarIcon = getIcon('timeDimension')\n\nconst DateRangeFilter: React.FC<DateRangeFilterProps> = ({\n timeDimensions,\n onDateRangeChange,\n onDateRangeRemove\n}) => {\n // Get current date ranges from time dimensions\n const currentDateRanges = getTimeDimensionsWithDateRanges({ timeDimensions })\n \n // Get time dimensions that don't have date ranges yet\n const availableTimeDimensions = timeDimensions.filter(td => !td.dateRange)\n \n // Count of time dimensions with date ranges\n const dateRangeCount = Object.keys(currentDateRanges).length\n\n const handleAddDateRange = () => {\n if (availableTimeDimensions.length === 0) return\n \n // Add date range to the first available time dimension with default \"this month\"\n const firstAvailable = availableTimeDimensions[0]\n onDateRangeChange(firstAvailable.dimension, 'this month')\n }\n\n const handleClearAllDateRanges = () => {\n // Remove all date ranges\n Object.keys(currentDateRanges).forEach(timeDimension => {\n onDateRangeRemove(timeDimension)\n })\n }\n\n // Don't render if there are no time dimensions\n if (!timeDimensions || timeDimensions.length === 0) {\n return null\n }\n\n return (\n <div className=\"space-y-4 bg-dc-surface-secondary rounded-lg p-4\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center\">\n <CalendarIcon className=\"w-4 h-4 text-dc-text-muted mr-2\" />\n <h4 className=\"text-sm font-semibold text-dc-text-secondary\">\n Date Ranges ({dateRangeCount})\n </h4>\n </div>\n\n <div className=\"flex items-center space-x-2\">\n {/* Clear all button */}\n {dateRangeCount > 0 && (\n <button\n onClick={handleClearAllDateRanges}\n className=\"text-xs text-dc-text-muted hover:text-red-600 focus:outline-hidden underline\"\n >\n Clear all\n </button>\n )}\n \n {/* Add Date Range button */}\n <button\n onClick={handleAddDateRange}\n disabled={availableTimeDimensions.length === 0}\n className={`flex items-center space-x-1 px-2 py-1 text-xs font-medium rounded focus:outline-hidden focus:ring-2 ${\n availableTimeDimensions.length > 0\n ? 'text-purple-700 dark:text-purple-300 bg-purple-100 dark:bg-purple-900/30 border border-purple-200 dark:border-purple-800 hover:bg-purple-200 dark:hover:bg-purple-900/50 focus:ring-purple-500'\n : 'text-dc-text-muted bg-dc-surface-secondary border border-dc-border cursor-not-allowed'\n }`}\n title={availableTimeDimensions.length === 0 ? 'All time dimensions already have date ranges' : 'Add date range'}\n >\n <AddIcon className=\"w-3 h-3\" />\n <span>Add Date Range</span>\n </button>\n </div>\n </div>\n \n {/* Date Range List */}\n {dateRangeCount > 0 && (\n <div className=\"space-y-3\">\n {timeDimensions.map(td => {\n if (!td.dateRange) return null\n \n const allTimeDimensions = timeDimensions.map(t => t.dimension)\n \n return (\n <DateRangeSelector\n key={td.dimension}\n timeDimension={td.dimension}\n availableTimeDimensions={allTimeDimensions}\n currentDateRange={td.dateRange}\n onDateRangeChange={onDateRangeChange}\n onTimeDimensionChange={(oldTd, newTd) => {\n // Remove date range from old time dimension and add it to new one\n onDateRangeRemove(oldTd)\n onDateRangeChange(newTd, td.dateRange!)\n }}\n onRemove={onDateRangeRemove}\n />\n )\n })}\n </div>\n )}\n \n </div>\n )\n}\n\nexport default DateRangeFilter","/**\n * QueryAnalysisPanel Component\n * Displays query planning analysis for debugging and transparency\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport type { QueryAnalysis } from './types'\n\ninterface QueryAnalysisPanelProps {\n analysis: QueryAnalysis\n}\n\n/**\n * Format reason string for display\n */\nfunction formatReason(reason: string): string {\n return reason.replace(/_/g, ' ')\n}\n\n/**\n * Get badge color based on reason\n */\nfunction getReasonBadgeClasses(reason: string): string {\n switch (reason) {\n case 'most_dimensions':\n return 'bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300'\n case 'most_connected':\n return 'bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300'\n case 'alphabetical_fallback':\n return 'bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-300'\n case 'single_cube':\n return 'bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-300'\n default:\n return 'bg-gray-100 dark:bg-gray-900/30 text-gray-700 dark:text-gray-300'\n }\n}\n\nconst QueryAnalysisPanel: React.FC<QueryAnalysisPanelProps> = ({ analysis }) => {\n const InfoIcon = getIcon('info')\n const ArrowRightIcon = getIcon('chevronRight')\n const WarningIcon = getIcon('warning')\n const TableIcon = getIcon('table')\n const LinkIcon = getIcon('link')\n const SuccessIcon = getIcon('success')\n const ErrorIcon = getIcon('error')\n\n return (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-lg p-4 space-y-4\">\n {/* Query Summary Section */}\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <InfoIcon className=\"w-4 h-4 mr-2\" />\n Query Summary\n </h4>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-2 text-xs\">\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">Type:</span>\n <span className=\"ml-1 font-medium text-dc-text\">\n {formatReason(analysis.querySummary.queryType)}\n </span>\n </div>\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">Cubes:</span>\n <span className=\"ml-1 font-medium text-dc-text\">{analysis.cubeCount}</span>\n </div>\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">Joins:</span>\n <span className=\"ml-1 font-medium text-dc-text\">{analysis.querySummary.joinCount}</span>\n </div>\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">CTEs:</span>\n <span className=\"ml-1 font-medium text-dc-text\">{analysis.querySummary.cteCount}</span>\n </div>\n </div>\n </div>\n\n {/* Primary Cube Section */}\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <TableIcon className=\"w-4 h-4 mr-2\" />\n Primary Cube (FROM table)\n </h4>\n <div className=\"bg-dc-surface p-3 rounded text-sm\">\n <div className=\"flex items-center gap-2 mb-2 flex-wrap\">\n <span className=\"font-mono font-medium text-dc-primary\">\n {analysis.primaryCube.selectedCube}\n </span>\n <span className={`text-xs px-2 py-0.5 rounded ${getReasonBadgeClasses(analysis.primaryCube.reason)}`}>\n {formatReason(analysis.primaryCube.reason)}\n </span>\n </div>\n <p className=\"text-dc-text-secondary text-xs\">\n {analysis.primaryCube.explanation}\n </p>\n {analysis.primaryCube.candidates && analysis.primaryCube.candidates.length > 1 && (\n <details className=\"mt-2\">\n <summary className=\"text-xs text-dc-text-muted cursor-pointer hover:text-dc-text\">\n Show candidates ({analysis.primaryCube.candidates.length})\n </summary>\n <div className=\"mt-2 space-y-1 ml-2\">\n {analysis.primaryCube.candidates.map((c, i) => (\n <div key={i} className=\"text-xs flex items-center gap-2 flex-wrap\">\n <span className={`font-mono ${c.cubeName === analysis.primaryCube.selectedCube ? 'font-bold text-dc-primary' : 'text-dc-text-muted'}`}>\n {c.cubeName}\n </span>\n <span className=\"text-dc-text-muted\">\n dims: {c.dimensionCount}, joins: {c.joinCount}\n </span>\n {c.canReachAll ? (\n <span className=\"text-green-600 dark:text-green-400 flex items-center gap-0.5\">\n <SuccessIcon className=\"w-3 h-3\" />\n reachable\n </span>\n ) : (\n <span className=\"text-red-600 dark:text-red-400 flex items-center gap-0.5\">\n <ErrorIcon className=\"w-3 h-3\" />\n cannot reach all\n </span>\n )}\n </div>\n ))}\n </div>\n </details>\n )}\n </div>\n </div>\n\n {/* Join Paths Section */}\n {analysis.joinPaths.length > 0 && (\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <LinkIcon className=\"w-4 h-4 mr-2\" />\n Join Paths\n </h4>\n <div className=\"space-y-2\">\n {analysis.joinPaths.map((jp, idx) => (\n <div key={idx} className=\"bg-dc-surface p-3 rounded text-sm\">\n <div className=\"flex items-center gap-2 mb-2 flex-wrap\">\n <span className=\"font-mono text-dc-text-secondary\">{analysis.primaryCube.selectedCube}</span>\n <ArrowRightIcon className=\"w-4 h-4 text-dc-text-muted\" />\n <span className=\"font-mono font-medium text-dc-text\">{jp.targetCube}</span>\n {jp.pathFound ? (\n <span className=\"text-xs px-2 py-0.5 bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-300 rounded\">\n {jp.pathLength} step{jp.pathLength !== 1 ? 's' : ''}\n </span>\n ) : (\n <span className=\"text-xs px-2 py-0.5 bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300 rounded\">\n No path\n </span>\n )}\n </div>\n {jp.pathFound && jp.path && jp.path.length > 0 && (\n <div className=\"space-y-1 ml-2\">\n {jp.path.map((step, stepIdx) => (\n <div key={stepIdx} className=\"flex items-center gap-1 text-xs flex-wrap\">\n <span className=\"font-mono text-dc-text-secondary\">{step.fromCube}</span>\n <ArrowRightIcon className=\"w-3 h-3 text-dc-text-muted\" />\n <span className=\"font-mono text-dc-text\">{step.toCube}</span>\n <span className=\"text-dc-text-muted\">\n ({step.relationship}, {step.joinType} join)\n </span>\n {step.joinColumns.length > 0 && (\n <span className=\"text-dc-text-muted\">\n on {step.joinColumns.map(jc => `${jc.sourceColumn}=${jc.targetColumn}`).join(', ')}\n </span>\n )}\n </div>\n ))}\n </div>\n )}\n {!jp.pathFound && jp.error && (\n <p className=\"text-xs text-red-600 dark:text-red-400 mt-1\">{jp.error}</p>\n )}\n {jp.visitedCubes && jp.visitedCubes.length > 0 && !jp.pathFound && (\n <details className=\"mt-1\">\n <summary className=\"text-xs text-dc-text-muted cursor-pointer hover:text-dc-text\">\n Cubes visited during search ({jp.visitedCubes.length})\n </summary>\n <div className=\"mt-1 text-xs text-dc-text-muted ml-2\">\n {jp.visitedCubes.join(' → ')}\n </div>\n </details>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Pre-Aggregations Section */}\n {analysis.preAggregations.length > 0 && (\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <TableIcon className=\"w-4 h-4 mr-2\" />\n Pre-Aggregation CTEs\n </h4>\n <div className=\"space-y-2\">\n {analysis.preAggregations.map((pa, idx) => (\n <div key={idx} className=\"bg-dc-surface p-3 rounded text-sm\">\n <div className=\"flex items-center gap-2 mb-1 flex-wrap\">\n <span className=\"font-mono font-medium text-dc-text\">{pa.cubeName}</span>\n <span className=\"text-xs text-dc-text-muted\">as</span>\n <code className=\"text-xs bg-dc-surface-secondary px-1 rounded font-mono\">{pa.cteAlias}</code>\n </div>\n <p className=\"text-xs text-dc-text-secondary\">{pa.reason}</p>\n <div className=\"mt-1 text-xs text-dc-text-muted\">\n <span className=\"font-medium\">Measures:</span> {pa.measures.join(', ')}\n </div>\n {pa.joinKeys.length > 0 && (\n <div className=\"mt-1 text-xs text-dc-text-muted\">\n <span className=\"font-medium\">Join keys:</span> {pa.joinKeys.map(jk => `${jk.sourceColumn}=${jk.targetColumn}`).join(', ')}\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Warnings Section */}\n {analysis.warnings && analysis.warnings.length > 0 && (\n <div>\n <h4 className=\"text-sm font-semibold text-amber-600 dark:text-amber-400 mb-2 flex items-center\">\n <WarningIcon className=\"w-4 h-4 mr-2\" />\n Warnings\n </h4>\n <ul className=\"list-disc list-inside text-xs text-amber-600 dark:text-amber-400 space-y-1\">\n {analysis.warnings.map((w, i) => (\n <li key={i}>{w}</li>\n ))}\n </ul>\n </div>\n )}\n\n {/* Cubes Involved */}\n {analysis.cubesInvolved.length > 0 && (\n <div className=\"text-xs text-dc-text-muted pt-2 border-t border-dc-border\">\n <span className=\"font-medium\">Cubes involved:</span> {analysis.cubesInvolved.join(', ')}\n </div>\n )}\n </div>\n )\n}\n\nexport default QueryAnalysisPanel\n","/**\n * QueryPanel Component\n * \n * Displays the current query being built, with sections for measures, dimensions, and time dimensions.\n * Includes validation status, JSON preview, and action buttons.\n */\n\nimport React, { useState, useEffect } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterBuilder from './FilterBuilder'\nimport DateRangeFilter from './DateRangeFilter'\nimport QueryAnalysisPanel from './QueryAnalysisPanel'\nimport type { QueryPanelProps } from './types'\nimport { TIME_GRANULARITIES } from './types'\nimport { hasQueryContent, getSelectedFieldsCount, cleanQueryForServer, hasTimeDimensions, getFieldTitle, getSortDirection, getSortTooltip, getNextSortDirection, getFieldType } from './utils'\nimport { getMeasureIcon } from '../../utils/measureIcons'\n\nconst QueryPanel: React.FC<QueryPanelProps> = ({\n query,\n schema,\n validationStatus,\n validationError,\n validationSql,\n validationAnalysis,\n onValidate,\n onExecute,\n onRemoveField,\n onTimeDimensionGranularityChange,\n onFiltersChange,\n onDateRangeChange,\n onDateRangeRemove,\n onOrderChange,\n onClearQuery,\n showSettings,\n onSettingsClick,\n onAIAssistantClick,\n onSchemaClick,\n onShareClick,\n shareButtonState = 'idle',\n isViewingShared = false\n}) => {\n const [showJsonPreview, setShowJsonPreview] = useState(false)\n const [showSqlPreview, setShowSqlPreview] = useState(false)\n const [showAnalysisPreview, setShowAnalysisPreview] = useState(false)\n\n // Trigger Prism highlighting when preview content changes\n useEffect(() => {\n if ((showJsonPreview || showSqlPreview) && typeof window !== 'undefined' && (window as any).Prism) {\n // Use setTimeout to ensure DOM is updated before highlighting\n setTimeout(() => {\n try {\n ;(window as any).Prism.highlightAll()\n } catch (error) {\n // Silently fail if Prism is not available or encounters an error\n }\n }, 0)\n }\n }, [showJsonPreview, showSqlPreview, query, validationSql])\n\n const hasContent = hasQueryContent(query)\n const selectedCount = getSelectedFieldsCount(query)\n\n const CloseIcon = getIcon('close')\n const SuccessIcon = getIcon('success')\n const ErrorIcon = getIcon('error')\n const DeleteIcon = getIcon('delete')\n const CopyIcon = getIcon('copy')\n const SettingsIcon = getIcon('settings')\n const FilterIcon = getIcon('filter')\n const SparklesIcon = getIcon('sparkles')\n const ChevronUpIcon = getIcon('chevronUp')\n const ChevronDownIcon = getIcon('chevronDown')\n const ChevronUpDownIcon = getIcon('chevronUpDown')\n const ShareIcon = getIcon('share')\n const MeasureIcon = getIcon('measure')\n const DimensionIcon = getIcon('dimension')\n const TimeDimensionIcon = getIcon('timeDimension')\n const RunIcon = getIcon('run')\n const CheckIcon = getIcon('check')\n\n const handleCopyQuery = async () => {\n const cleanedQuery = cleanQueryForServer(query)\n try {\n await navigator.clipboard.writeText(JSON.stringify(cleanedQuery, null, 2))\n // You could add a toast notification here if desired\n } catch (error) {\n // Failed to copy query\n // Fallback for older browsers\n const textArea = document.createElement('textarea')\n textArea.value = JSON.stringify(cleanedQuery, null, 2)\n document.body.appendChild(textArea)\n textArea.select()\n document.execCommand('copy')\n document.body.removeChild(textArea)\n }\n }\n\n // Helper function to check if a field has filters applied\n const hasFiltersApplied = (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions'): boolean => {\n if (fieldType === 'timeDimensions') {\n // Check if time dimension has a date range\n return Boolean(query.timeDimensions?.some(td => td.dimension === fieldName && td.dateRange))\n } else {\n // Check if field has regular filters applied\n const currentFilters = query.filters || []\n \n const hasFieldInFilters = (filters: any[]): boolean => {\n return filters.some(filter => {\n if ('member' in filter) {\n // Simple filter\n return filter.member === fieldName\n } else if ('type' in filter && 'filters' in filter) {\n // Group filter - check recursively\n return hasFieldInFilters(filter.filters)\n }\n return false\n })\n }\n \n return hasFieldInFilters(currentFilters)\n }\n }\n\n const handleAddFilterFromField = (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n if (fieldType === 'timeDimensions') {\n // For time dimensions, add a date range instead of a regular filter\n onDateRangeChange(fieldName, 'this month')\n } else {\n // For measures and dimensions, add a regular filter\n // Get current filters and add a new one\n const currentFilters = query.filters || []\n const newFilter = {\n member: fieldName,\n operator: 'equals' as const,\n values: []\n }\n \n // Use the same smart grouping logic as FilterBuilder\n if (currentFilters.length === 0) {\n onFiltersChange([newFilter])\n } else if (currentFilters.length === 1 && 'member' in currentFilters[0]) {\n // Create AND group with existing filter + new filter\n const andGroup = {\n type: 'and' as const,\n filters: [currentFilters[0], newFilter]\n }\n onFiltersChange([andGroup])\n } else if (currentFilters.length === 1 && 'type' in currentFilters[0] && currentFilters[0].type === 'and') {\n // Add to existing AND group\n const existingAndGroup = currentFilters[0]\n const updatedAndGroup = {\n type: 'and' as const,\n filters: [...existingAndGroup.filters, newFilter]\n }\n onFiltersChange([updatedAndGroup])\n } else if (currentFilters.length === 1 && 'type' in currentFilters[0] && currentFilters[0].type === 'or') {\n // Add to existing OR group\n const existingOrGroup = currentFilters[0]\n const updatedOrGroup = {\n type: 'or' as const,\n filters: [...existingOrGroup.filters, newFilter]\n }\n onFiltersChange([updatedOrGroup])\n } else {\n // Fallback: just add to the end\n onFiltersChange([...currentFilters, newFilter])\n }\n }\n }\n\n // Sorting helper functions\n const getSortIcon = (direction: 'asc' | 'desc' | null) => {\n switch (direction) {\n case 'asc':\n return <ChevronUpIcon className={`w-4 h-4 ${direction ? 'stroke-3' : ''}`} />\n case 'desc':\n return <ChevronDownIcon className={`w-4 h-4 ${direction ? 'stroke-3' : ''}`} />\n default:\n return <ChevronUpDownIcon className=\"w-4 h-4\" />\n }\n }\n\n const handleToggleSort = (fieldName: string) => {\n const current = getSortDirection(fieldName, query.order)\n const next = getNextSortDirection(current)\n onOrderChange(fieldName, next)\n }\n\n const getSortButtonClasses = (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n const sortDirection = getSortDirection(fieldName, query.order)\n const baseClasses = 'focus:outline-hidden shrink-0 p-1 transition-colors'\n\n if (sortDirection) {\n // Active sort - use field type colors\n switch (fieldType) {\n case 'measures':\n return `${baseClasses} text-dc-measure hover:opacity-80`\n case 'dimensions':\n return `${baseClasses} text-dc-dimension hover:opacity-80`\n case 'timeDimensions':\n return `${baseClasses} text-dc-time-dimension hover:opacity-80`\n default:\n return `${baseClasses} text-dc-time-dimension hover:opacity-80`\n }\n } else {\n // No sort - gray\n return `${baseClasses} text-dc-text-muted hover:text-dc-text-secondary`\n }\n }\n\n const RemovableChip: React.FC<{ \n label: string\n fieldName: string\n fieldType: 'measures' | 'dimensions' | 'timeDimensions'\n icon: React.ReactNode\n }> = ({ fieldName, fieldType, icon }) => {\n const getChipClasses = () => {\n switch (fieldType) {\n case 'measures':\n return 'bg-dc-measure text-dc-measure border-dc-measure'\n case 'dimensions':\n return 'bg-dc-dimension text-dc-dimension border-dc-dimension'\n case 'timeDimensions':\n return 'bg-dc-time-dimension text-dc-time-dimension border-dc-time-dimension'\n default:\n return 'bg-dc-time-dimension text-dc-time-dimension border-dc-time-dimension'\n }\n }\n\n return (\n <div className={`inline-flex items-center text-sm px-3 py-2 rounded-lg border w-full ${getChipClasses()}`}>\n <div className=\"mr-2 shrink-0\">\n {icon}\n </div>\n <span className=\"flex-1 flex flex-col min-w-0\">\n <span className=\"text-xs font-medium truncate\">{getFieldTitle(fieldName, schema)}</span>\n <span className=\"text-[10px] text-dc-text-muted truncate\">{fieldName}</span>\n </span>\n <div className=\"flex items-center gap-2 ml-2\">\n {/* Filter and Sort buttons - stacked vertically */}\n <div className=\"flex flex-col items-center\">\n {/* Filter button */}\n {(() => {\n const hasFilters = hasFiltersApplied(fieldName, fieldType)\n const getActiveColorClasses = () => {\n switch (fieldType) {\n case 'measures':\n return 'text-dc-measure hover:opacity-80'\n case 'dimensions':\n return 'text-dc-dimension hover:opacity-80'\n case 'timeDimensions':\n return 'text-dc-time-dimension hover:opacity-80'\n default:\n return 'text-dc-time-dimension hover:opacity-80'\n }\n }\n\n return (\n <button\n onClick={() => handleAddFilterFromField(fieldName, fieldType)}\n className={`focus:outline-hidden shrink-0 p-0.5 transition-colors ${\n hasFilters\n ? getActiveColorClasses()\n : 'text-dc-text-muted hover:text-dc-text-secondary'\n }`}\n title={fieldType === 'timeDimensions' ? 'Add date range' : 'Add filter'}\n >\n <FilterIcon className={`w-4 h-4 ${hasFilters ? 'stroke-3' : ''}`} />\n </button>\n )\n })()}\n\n {/* Sort button */}\n <button\n onClick={() => handleToggleSort(fieldName)}\n className={`focus:outline-hidden shrink-0 p-0.5 transition-colors ${getSortButtonClasses(fieldName, fieldType).replace('p-1', 'p-0.5')}`}\n title={getSortTooltip(getSortDirection(fieldName, query.order))}\n >\n {getSortIcon(getSortDirection(fieldName, query.order))}\n </button>\n </div>\n\n {/* Remove button */}\n <button\n onClick={() => onRemoveField(fieldName, fieldType)}\n className=\"text-dc-text-secondary hover:text-red-600 focus:outline-hidden shrink-0\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n )\n }\n\n const TimeDimensionChip: React.FC<{\n timeDimension: { dimension: string; granularity?: string }\n label: string\n }> = ({ timeDimension }) => (\n <div className=\"bg-dc-time-dimension text-dc-time-dimension text-sm px-3 py-2 rounded-lg border border-dc-time-dimension w-full\">\n {/* Top row with icon, label, filter button, sort button, and remove button */}\n <div className=\"flex items-center mb-1\">\n <div className=\"mr-2\">\n <TimeDimensionIcon className=\"w-4 h-4\" />\n </div>\n <span className=\"flex-1 flex flex-col min-w-0\">\n <span className=\"text-xs font-medium truncate\">{getFieldTitle(timeDimension.dimension, schema)}</span>\n <span className=\"text-[10px] text-dc-text-muted truncate\">{timeDimension.dimension}</span>\n </span>\n <div className=\"flex items-center gap-2 ml-2\">\n {/* Filter and Sort buttons - stacked vertically */}\n <div className=\"flex flex-col items-center\">\n {/* Filter button */}\n {(() => {\n const hasDateRange = hasFiltersApplied(timeDimension.dimension, 'timeDimensions')\n return (\n <button\n onClick={() => handleAddFilterFromField(timeDimension.dimension, 'timeDimensions')}\n className={`focus:outline-hidden shrink-0 p-0.5 transition-colors ${\n hasDateRange\n ? 'text-dc-time-dimension hover:opacity-80'\n : 'text-dc-text-muted hover:text-dc-text-secondary'\n }`}\n title=\"Add date range\"\n >\n <FilterIcon className={`w-4 h-4 ${hasDateRange ? 'stroke-3' : ''}`} />\n </button>\n )\n })()}\n\n {/* Sort button */}\n <button\n onClick={() => handleToggleSort(timeDimension.dimension)}\n className={`focus:outline-hidden shrink-0 p-0.5 transition-colors ${getSortButtonClasses(timeDimension.dimension, 'timeDimensions').replace('p-1', 'p-0.5')}`}\n title={getSortTooltip(getSortDirection(timeDimension.dimension, query.order))}\n >\n {getSortIcon(getSortDirection(timeDimension.dimension, query.order))}\n </button>\n </div>\n\n {/* Remove button */}\n <button\n onClick={() => onRemoveField(timeDimension.dimension, 'timeDimensions')}\n className=\"text-dc-text-secondary hover:text-red-600 focus:outline-hidden\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n {/* Bottom row with granularity dropdown */}\n <div className=\"ml-6 flex items-center\">\n <span className=\"text-xs text-dc-time-dimension mr-2\">Granularity:</span>\n <select\n value={timeDimension.granularity || 'month'}\n onChange={(e) => onTimeDimensionGranularityChange(timeDimension.dimension, e.target.value)}\n className=\"bg-dc-time-dimension border-none text-dc-time-dimension text-xs rounded-sm focus:ring-2 focus:ring-blue-500 flex-1\"\n onClick={(e) => e.stopPropagation()}\n >\n {TIME_GRANULARITIES.map(granularity => (\n <option key={granularity.value} value={granularity.value}>\n {granularity.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n )\n\n const ValidationStatusIcon = () => {\n switch (validationStatus) {\n case 'validating':\n return (\n <div className=\"animate-spin rounded-full h-5 w-5 border-b-2 border-blue-600\"></div>\n )\n case 'valid':\n return <SuccessIcon className=\"w-5 h-5 text-green-600\" />\n case 'invalid':\n return <ErrorIcon className=\"w-5 h-5 text-red-600\" />\n default:\n return null\n }\n }\n\n return (\n <div className=\"flex flex-col bg-dc-surface border border-dc-border rounded-lg\">\n {/* Header */}\n <div className=\"p-3 sm:p-4 border-b border-dc-border\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex items-center gap-1 sm:gap-2 min-w-0\">\n <h3 className=\"text-sm sm:text-lg font-semibold text-dc-text truncate\">Query Builder</h3>\n {onSchemaClick && (\n <button\n onClick={onSchemaClick}\n className=\"flex items-center gap-1 px-3 py-2 text-xs font-medium text-blue-700 dark:text-blue-300 bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-800 rounded-lg hover:bg-blue-100 dark:hover:bg-blue-900/50 focus:outline-hidden focus:ring-2 focus:ring-blue-500 transition-all duration-200 shrink-0\"\n title=\"Schema Explorer - View cube relationships and fields\"\n >\n <svg className=\"w-3 h-3 sm:w-4 sm:h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fillRule=\"evenodd\" d=\"M3 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V4zM3 10a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H4a1 1 0 01-1-1v-6zM14 9a1 1 0 00-1 1v6a1 1 0 001 1h2a1 1 0 001-1v-6a1 1 0 00-1-1h-2z\" clipRule=\"evenodd\" />\n </svg>\n <span>Schema</span>\n </button>\n )}\n {onAIAssistantClick && (\n <button\n onClick={onAIAssistantClick}\n className=\"flex items-center gap-1 px-3 py-2 text-xs font-medium text-purple-700 dark:text-purple-300 bg-purple-50 dark:bg-purple-900/30 border border-purple-200 dark:border-purple-800 rounded-lg hover:bg-purple-100 dark:hover:bg-purple-900/50 focus:outline-hidden focus:ring-2 focus:ring-purple-500 transition-all duration-200 shrink-0\"\n title=\"AI Assistant - Generate queries with AI\"\n >\n <SparklesIcon className=\"w-3 h-3 sm:w-4 sm:h-4\" />\n <span>AI Assistant</span>\n </button>\n )}\n </div>\n <div className=\"flex items-center gap-1 shrink-0\">\n {hasContent && (\n <>\n <span className=\"hidden lg:inline text-xs text-dc-text-muted mr-1\">\n {selectedCount} field{selectedCount !== 1 ? 's' : ''} selected\n </span>\n <button\n onClick={handleCopyQuery}\n className=\"flex items-center gap-1 px-3 py-2 text-xs font-medium text-purple-700 dark:text-purple-300 bg-purple-100 dark:bg-purple-900/30 border border-purple-200 dark:border-purple-800 rounded-sm hover:bg-purple-200 dark:hover:bg-purple-900/50 focus:outline-hidden focus:ring-2 focus:ring-purple-500\"\n title=\"Copy query to clipboard\"\n >\n <CopyIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Copy Query</span>\n </button>\n {onShareClick && (\n <button\n onClick={onShareClick}\n className={`flex items-center gap-1 px-3 py-2 text-xs font-medium rounded-sm focus:outline-hidden focus:ring-2 transition-colors ${\n shareButtonState === 'idle'\n ? 'text-blue-700 dark:text-blue-300 bg-blue-100 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-800 hover:bg-blue-200 dark:hover:bg-blue-900/50 focus:ring-blue-500'\n : 'text-green-700 dark:text-green-300 bg-green-100 dark:bg-green-900/30 border border-green-200 dark:border-green-800 focus:ring-green-500'\n }`}\n title={shareButtonState === 'idle' ? 'Share this analysis' : 'Link copied!'}\n disabled={shareButtonState !== 'idle'}\n >\n {shareButtonState === 'idle' ? (\n <>\n <ShareIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Share</span>\n </>\n ) : shareButtonState === 'copied' ? (\n <>\n <CheckIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Copied!</span>\n </>\n ) : (\n <>\n <CheckIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Copied!</span>\n <span className=\"hidden lg:inline text-[10px] opacity-75\">(no chart)</span>\n </>\n )}\n </button>\n )}\n {onClearQuery && (\n <button\n onClick={onClearQuery}\n className=\"text-dc-text-muted hover:text-red-600 focus:outline-hidden p-2\"\n title=\"Clear all fields\"\n >\n <DeleteIcon className=\"w-3 h-3 sm:w-4 sm:h-4\" />\n </button>\n )}\n </>\n )}\n {showSettings && onSettingsClick && (\n <button\n onClick={onSettingsClick}\n className=\"text-dc-text-muted hover:text-dc-text-secondary focus:outline-hidden p-2\"\n title=\"API Configuration\"\n >\n <SettingsIcon className=\"w-3 h-3 sm:w-4 sm:h-4\" />\n </button>\n )}\n <ValidationStatusIcon />\n </div>\n </div>\n </div>\n\n {/* Viewing Shared Indicator */}\n {isViewingShared && (\n <div className=\"px-4 py-2 bg-blue-50 dark:bg-blue-900/20 border-b border-blue-200 dark:border-blue-800 flex items-center gap-2 text-sm text-blue-700 dark:text-blue-300\">\n <ShareIcon className=\"w-4 h-4\" />\n <span>Viewing shared analysis</span>\n </div>\n )}\n\n {/* Content */}\n <div className=\"p-4\">\n {!hasContent ? (\n <div className=\"py-8 flex items-center justify-center text-dc-text-muted\">\n <div className=\"text-center\">\n <MeasureIcon className=\"w-12 h-12 mx-auto text-dc-text-muted mb-3\" />\n <div className=\"text-sm font-semibold mb-1\">No fields selected</div>\n <div className=\"text-xs\">Select measures, dimensions, or time dimensions from the schema explorer</div>\n </div>\n </div>\n ) : (\n <div className=\"space-y-6\">\n {/* Responsive Layout Grid */}\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n {/* Dimensions Column */}\n <div className=\"min-h-24\">\n <h4 className=\"text-sm font-semibold text-dc-dimension mb-3 flex items-center\">\n <DimensionIcon className=\"w-4 h-4 mr-2\" />\n Dimensions ({(query.dimensions || []).length})\n </h4>\n <div className=\"flex flex-col gap-2\">\n {(query.dimensions || []).map(dimension => (\n <RemovableChip\n key={dimension}\n label={dimension}\n fieldName={dimension}\n fieldType=\"dimensions\"\n icon={<DimensionIcon className=\"w-4 h-4\" />}\n />\n ))}\n </div>\n </div>\n\n {/* Time Dimensions Column */}\n <div className=\"min-h-24\">\n <h4 className=\"text-sm font-semibold text-dc-time-dimension mb-3 flex items-center\">\n <TimeDimensionIcon className=\"w-4 h-4 mr-2\" />\n Time Dimensions ({(query.timeDimensions || []).length})\n </h4>\n <div className=\"flex flex-col gap-2\">\n {(query.timeDimensions || []).map(timeDimension => (\n <TimeDimensionChip\n key={timeDimension.dimension}\n timeDimension={timeDimension}\n label={timeDimension.dimension}\n />\n ))}\n </div>\n </div>\n\n {/* Measures Column */}\n <div className=\"min-h-24\">\n <h4 className=\"text-sm font-semibold text-dc-measure mb-3 flex items-center\">\n <MeasureIcon className=\"w-4 h-4 mr-2\" />\n Measures ({(query.measures || []).length})\n </h4>\n <div className=\"flex flex-col gap-2\">\n {(query.measures || []).map(measure => {\n const measureType = schema ? getFieldType(measure, schema) : undefined\n return (\n <RemovableChip\n key={measure}\n label={measure}\n fieldName={measure}\n fieldType=\"measures\"\n icon={getMeasureIcon(measureType, 'w-4 h-4')}\n />\n )\n })}\n </div>\n </div>\n </div>\n\n {/* Date Range Section */}\n {hasTimeDimensions(query) && (\n <div className=\"mt-6\">\n <DateRangeFilter\n timeDimensions={query.timeDimensions || []}\n onDateRangeChange={onDateRangeChange}\n onDateRangeRemove={onDateRangeRemove}\n />\n </div>\n )}\n\n {/* Filters Section */}\n <div className=\"mt-6\">\n <FilterBuilder\n filters={query.filters || []}\n schema={schema}\n query={query}\n onFiltersChange={onFiltersChange}\n />\n </div>\n\n {/* Validation Error */}\n {validationError && (\n <div className=\"bg-red-50 border border-red-200 rounded-lg p-4\">\n <div className=\"flex items-start\">\n <ErrorIcon className=\"w-5 h-5 text-red-600 mr-2 mt-0.5\" />\n <div>\n <h5 className=\"text-sm font-semibold text-red-800\">Validation Error</h5>\n <p className=\"text-sm text-red-700 mt-1\">{validationError}</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Preview Toggles */}\n <div className=\"space-y-3\">\n <div className=\"flex space-x-4 flex-wrap gap-y-2\">\n <button\n onClick={() => {\n const newJsonState = !showJsonPreview\n setShowJsonPreview(newJsonState)\n if (newJsonState) {\n setShowSqlPreview(false)\n setShowAnalysisPreview(false)\n }\n }}\n className=\"text-sm text-dc-text-secondary hover:text-dc-text focus:outline-hidden focus:underline\"\n >\n {showJsonPreview ? 'Hide' : 'Show'} JSON Query\n </button>\n {validationSql && (\n <button\n onClick={() => {\n const newSqlState = !showSqlPreview\n setShowSqlPreview(newSqlState)\n if (newSqlState) {\n setShowJsonPreview(false)\n setShowAnalysisPreview(false)\n }\n }}\n className=\"text-sm text-dc-text-secondary hover:text-dc-text focus:outline-hidden focus:underline\"\n >\n {showSqlPreview ? 'Hide' : 'Show'} SQL Generated\n </button>\n )}\n {validationAnalysis && (\n <button\n onClick={() => {\n const newAnalysisState = !showAnalysisPreview\n setShowAnalysisPreview(newAnalysisState)\n if (newAnalysisState) {\n setShowJsonPreview(false)\n setShowSqlPreview(false)\n }\n }}\n className=\"text-sm text-dc-text-secondary hover:text-dc-text focus:outline-hidden focus:underline\"\n >\n {showAnalysisPreview ? 'Hide' : 'Show'} Query Analysis\n </button>\n )}\n </div>\n\n {showJsonPreview && (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-lg p-4\">\n <div className=\"text-xs font-semibold text-dc-text-secondary mb-2\">JSON Query:</div>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono\" style={{ fontSize: '12px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(cleanQueryForServer(query), null, 2)}</code>\n </pre>\n </div>\n )}\n\n {showSqlPreview && validationSql && (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-lg p-4\">\n <div className=\"text-xs font-semibold text-dc-text-secondary mb-2\">Generated SQL:</div>\n <pre className=\"text-dc-text-secondary overflow-x-auto whitespace-pre-wrap font-mono\" style={{ fontSize: '12px', lineHeight: '1.4' }}>\n <code className=\"language-sql\">{validationSql.sql.join(';\\n\\n')}</code>\n </pre>\n {validationSql.params && validationSql.params.length > 0 && (\n <>\n <div className=\"text-xs font-semibold text-dc-text-secondary mb-2 mt-4\">Parameters:</div>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono\" style={{ fontSize: '12px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(validationSql.params, null, 2)}</code>\n </pre>\n </>\n )}\n </div>\n )}\n\n {showAnalysisPreview && validationAnalysis && (\n <QueryAnalysisPanel analysis={validationAnalysis} />\n )}\n </div>\n </div>\n )}\n </div>\n\n {/* Actions */}\n {(hasContent || validationStatus === 'valid' || validationStatus === 'invalid') && (\n <div className=\"border-t border-dc-border p-4\">\n <div className=\"flex space-x-3\">\n <button\n onClick={onValidate}\n disabled={validationStatus === 'validating'}\n className={`flex-1 flex items-center justify-center px-4 py-2 text-sm font-medium rounded-md transition-colors ${\n validationStatus === 'validating'\n ? 'bg-dc-surface-secondary text-dc-text-muted cursor-not-allowed'\n : validationStatus === 'valid'\n ? 'bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-300 border border-green-200 dark:border-green-800 hover:bg-green-200 dark:hover:bg-green-900/50'\n : validationStatus === 'invalid'\n ? 'bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-300 border border-red-200 dark:border-red-800 hover:bg-red-200 dark:hover:bg-red-900/50'\n : 'bg-purple-100 dark:bg-purple-900/30 text-purple-800 dark:text-purple-300 border border-purple-200 dark:border-purple-800 hover:bg-purple-200 dark:hover:bg-purple-900/50'\n }`}\n >\n {validationStatus === 'validating' ? (\n <>\n <div className=\"animate-spin rounded-full h-4 w-4 border-b-2 border-current mr-2\"></div>\n Validating...\n </>\n ) : validationStatus === 'valid' ? (\n <>\n <CheckIcon className=\"w-4 h-4 mr-2\" />\n Re-validate Query\n </>\n ) : validationStatus === 'invalid' ? (\n <>\n <ErrorIcon className=\"w-4 h-4 mr-2\" />\n Validate Again\n </>\n ) : (\n <>\n <CheckIcon className=\"w-4 h-4 mr-2\" />\n Validate Query\n </>\n )}\n </button>\n\n <button\n onClick={onExecute}\n disabled={validationStatus !== 'valid'}\n className={`flex-1 flex items-center justify-center px-4 py-2 text-sm font-medium rounded-md transition-colors ${\n validationStatus !== 'valid'\n ? 'bg-dc-surface-secondary text-dc-text-muted cursor-not-allowed border border-dc-border'\n : 'text-white border border-green-700 hover:bg-green-700 focus:ring-2 focus:ring-green-500'\n }`}\n style={validationStatus === 'valid' ? { backgroundColor: 'var(--dc-primary)' } : undefined}\n >\n <RunIcon className=\"w-4 h-4 mr-2\" />\n Run Query\n </button>\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport default QueryPanel","import { barChartConfig } from '../components/charts/BarChart.config'\nimport { lineChartConfig } from '../components/charts/LineChart.config'\nimport { areaChartConfig } from '../components/charts/AreaChart.config'\nimport { pieChartConfig } from '../components/charts/PieChart.config'\nimport { scatterChartConfig } from '../components/charts/ScatterChart.config'\nimport { bubbleChartConfig } from '../components/charts/BubbleChart.config'\nimport { radarChartConfig } from '../components/charts/RadarChart.config'\nimport { radialBarChartConfig } from '../components/charts/RadialBarChart.config'\nimport { treemapChartConfig } from '../components/charts/TreeMapChart.config'\nimport { dataTableConfig } from '../components/charts/DataTable.config'\nimport { activityGridChartConfig } from '../components/charts/ActivityGridChart.config'\nimport { kpiNumberConfig } from '../components/charts/KpiNumber.config'\nimport { kpiDeltaConfig } from '../components/charts/KpiDelta.config'\nimport { kpiTextConfig } from '../components/charts/KpiText.config'\nimport { markdownConfig } from '../components/charts/MarkdownChart.config'\nimport type { ChartConfigRegistry } from './chartConfigs'\n\n/**\n * Registry of all chart type configurations\n */\nexport const chartConfigRegistry: ChartConfigRegistry = {\n bar: barChartConfig,\n line: lineChartConfig,\n area: areaChartConfig,\n pie: pieChartConfig,\n scatter: scatterChartConfig,\n bubble: bubbleChartConfig,\n radar: radarChartConfig,\n radialBar: radialBarChartConfig,\n treemap: treemapChartConfig,\n table: dataTableConfig,\n activityGrid: activityGridChartConfig,\n kpiNumber: kpiNumberConfig,\n kpiDelta: kpiDeltaConfig,\n kpiText: kpiTextConfig,\n markdown: markdownConfig\n}","import { useState } from 'react'\nimport { chartConfigRegistry } from '../charts/chartConfigRegistry'\nimport type { ChartType } from '../types'\n\ninterface ChartTypeSelectorProps {\n selectedType: ChartType\n onTypeChange: (type: ChartType) => void\n className?: string\n}\n\nexport default function ChartTypeSelector({ \n selectedType, \n onTypeChange, \n className = '' \n}: ChartTypeSelectorProps) {\n const [isOpen, setIsOpen] = useState(false)\n const chartTypes = Object.entries(chartConfigRegistry) as [ChartType, typeof chartConfigRegistry[keyof typeof chartConfigRegistry]][]\n\n // Chart type display names (fallback if not in config)\n const chartTypeLabels: Record<ChartType, string> = {\n bar: 'Bar Chart',\n line: 'Line Chart', \n area: 'Area Chart',\n pie: 'Pie Chart',\n scatter: 'Scatter Plot',\n bubble: 'Bubble Chart',\n radar: 'Radar Chart',\n radialBar: 'Radial Bar Chart',\n treemap: 'TreeMap',\n table: 'Data Table',\n activityGrid: 'Activity Grid',\n kpiNumber: 'KPI Number',\n kpiDelta: 'KPI Delta',\n kpiText: 'KPI Text',\n markdown: 'Markdown'\n }\n\n const selectedConfig = chartConfigRegistry[selectedType]\n const SelectedIcon = selectedConfig?.icon\n const selectedLabel = chartTypeLabels[selectedType]\n\n return (\n <div className={`${className} relative`}>\n {/* Dropdown Button */}\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n className=\"w-full flex items-center justify-between px-3 py-2 border border-dc-border rounded-md bg-dc-surface hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n >\n <div className=\"flex items-center space-x-2\">\n {SelectedIcon && (\n <SelectedIcon className=\"h-5 w-5 text-dc-text-secondary\" />\n )}\n <span className=\"text-sm font-medium text-dc-text\">{selectedLabel}</span>\n </div>\n <svg\n className={`h-4 w-4 text-dc-text-muted transform transition-transform ${isOpen ? 'rotate-180' : ''}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n\n {/* Dropdown Menu - Grid Layout */}\n {isOpen && (\n <div className=\"absolute z-10 mt-1 w-full min-w-max bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-80 overflow-auto\">\n <div className=\"p-2\">\n <div className=\"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-1.5\">\n {chartTypes.map(([type, config]) => {\n const IconComponent = config.icon\n const label = chartTypeLabels[type]\n const isSelected = selectedType === type\n const description = config.description\n const useCase = config.useCase\n \n // Combine description and use case for tooltip\n const tooltipText = [description, useCase].filter(Boolean).join('. ')\n \n return (\n <button\n key={type}\n type=\"button\"\n onClick={() => {\n onTypeChange(type)\n setIsOpen(false)\n }}\n className={`\n relative p-1.5 rounded border transition-colors duration-150\n text-left group min-h-[30px] flex items-center justify-start\n ${isSelected\n ? 'bg-dc-surface-secondary'\n : 'bg-dc-surface hover:bg-dc-surface-hover'\n }\n `}\n style={{\n borderColor: isSelected ? 'var(--dc-primary)' : 'var(--dc-border)'\n }}\n title={tooltipText}\n >\n <div className=\"flex items-center space-x-1.5\">\n {/* Icon */}\n {IconComponent && (\n <IconComponent\n className={`h-4 w-4 shrink-0 ${isSelected ? 'text-dc-text' : 'text-dc-text-secondary'}`}\n />\n )}\n\n {/* Chart name */}\n <span className={`text-xs font-medium leading-tight truncate ${\n isSelected ? '' : 'text-dc-text'\n }`}\n style={isSelected ? { color: 'var(--dc-primary)' } : undefined}>\n {label}\n </span>\n </div>\n\n {/* Selected indicator - smaller dot */}\n {isSelected && (\n <div className=\"absolute top-0.5 right-0.5\">\n <div className=\"w-1.5 h-1.5 rounded-full\" style={{ backgroundColor: 'var(--dc-primary)' }}></div>\n </div>\n )}\n </button>\n )\n })}\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}","import React, { useState } from 'react'\nimport { getIcon } from '../icons'\nimport type { AxisDropZoneConfig } from '../charts/chartConfigs'\n\nconst CloseIcon = getIcon('close')\n\ninterface FieldStyling {\n IconComponent: React.ComponentType<{ className?: string }>\n baseClasses: string\n hoverClasses: string\n}\n\ninterface AxisDropZoneProps {\n config: AxisDropZoneConfig\n fields: string[]\n onDrop: (e: React.DragEvent<HTMLDivElement>, toKey: string) => void\n onRemove: (field: string, fromKey: string) => void\n onDragStart: (e: React.DragEvent<HTMLDivElement>, field: string, fromKey: string, fromIndex?: number) => void\n onDragEnd?: (e: React.DragEvent<HTMLDivElement>) => void\n onDragOver: (e: React.DragEvent<HTMLDivElement>) => void\n getFieldStyling: (field: string) => FieldStyling\n onReorder?: (fromIndex: number, toIndex: number, axisKey: string) => void\n draggedItem?: { field: string; fromAxis: string; fromIndex?: number } | null\n}\n\nexport default function AxisDropZone({\n config,\n fields,\n onDrop,\n onRemove,\n onDragStart,\n onDragEnd,\n onDragOver,\n getFieldStyling,\n onReorder,\n draggedItem\n}: AxisDropZoneProps) {\n const { key, label, description, mandatory, maxItems, emptyText, icon: IconComponent } = config\n const [dragOverIndex, setDragOverIndex] = useState<number | null>(null)\n const [isDraggedOver, setIsDraggedOver] = useState(false)\n const [isReorderDraggedOver, setIsReorderDraggedOver] = useState(false)\n \n // Calculate acceptance considering what's being dragged\n const getCanAcceptMore = () => {\n let effectiveCount = fields.length\n \n // If we're dragging FROM this axis, we effectively have one less item\n if (draggedItem && draggedItem.fromAxis === key) {\n effectiveCount = Math.max(0, fields.length - 1)\n }\n \n return !maxItems || effectiveCount < maxItems\n }\n \n const getIsFull = () => {\n let effectiveCount = fields.length\n \n // If we're dragging FROM this axis, we effectively have one less item\n if (draggedItem && draggedItem.fromAxis === key) {\n effectiveCount = Math.max(0, fields.length - 1)\n }\n \n return maxItems && effectiveCount >= maxItems\n }\n \n const canAcceptMore = getCanAcceptMore()\n const isFull = getIsFull()\n \n\n // Add a global drag end listener to reset visual state\n React.useEffect(() => {\n const handleGlobalDragEnd = () => {\n setDragOverIndex(null)\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }\n\n document.addEventListener('dragend', handleGlobalDragEnd)\n return () => {\n document.removeEventListener('dragend', handleGlobalDragEnd)\n }\n }, [])\n\n // Clear states when transitioning between different drag operations\n React.useEffect(() => {\n if (draggedItem) {\n // If we have a dragged item but it's not from this axis, clear reorder state\n if (draggedItem.fromAxis !== key) {\n setIsReorderDraggedOver(false)\n setDragOverIndex(null)\n }\n // If we have a dragged item from this axis, clear regular drag state\n else if (draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n setIsDraggedOver(false)\n }\n } else {\n // No dragged item, clear all states\n setDragOverIndex(null)\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }\n }, [draggedItem, key])\n\n const handleReorderDragOver = (e: React.DragEvent<HTMLDivElement>, targetIndex: number) => {\n // Check if this is a reorder operation (same axis) using the draggedItem prop\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n e.preventDefault()\n e.stopPropagation()\n setDragOverIndex(targetIndex)\n setIsReorderDraggedOver(true)\n }\n }\n\n const handleReorderDragLeave = () => {\n // Clear the individual item drag over index\n setDragOverIndex(null)\n // Note: Don't clear isReorderDraggedOver here as it causes flickering\n // Let the global drag end handler clear it when the drag is truly complete\n }\n\n const handleReorderDrop = (e: React.DragEvent<HTMLDivElement>, targetIndex: number) => {\n e.preventDefault()\n e.stopPropagation()\n setDragOverIndex(null)\n setIsReorderDraggedOver(false)\n \n // Handle reordering using either drag data or the draggedItem prop\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined && onReorder) {\n onReorder(draggedItem.fromIndex, targetIndex, key)\n return\n }\n \n // Fallback to parsing drag data\n try {\n const data = JSON.parse(e.dataTransfer.getData('text/plain'))\n if (data.fromAxis === key && onReorder && data.fromIndex !== undefined) {\n onReorder(data.fromIndex, targetIndex, key)\n }\n } catch {\n // If we can't parse the data, ignore\n }\n }\n \n return (\n <div className=\"mb-2\">\n <div className=\"flex items-center gap-2 mb-1\">\n <h4 className=\"text-xs font-semibold text-dc-text-secondary flex items-center\">\n {IconComponent && <IconComponent className=\"w-3 h-3 mr-1 text-dc-text-muted\" />}\n {label}\n {mandatory && <span className=\"text-red-500 ml-1\">*</span>}\n {maxItems && (\n <span className=\"text-dc-text-muted ml-1 font-normal\">\n ({fields.length}/{maxItems})\n </span>\n )}\n </h4>\n {description && (\n <span className=\"text-xs text-dc-text-muted\">\n {description}\n </span>\n )}\n </div>\n \n <div\n data-axis-container={key}\n className={`min-h-[40px] sm:min-h-[32px] border-2 border-dashed rounded-lg p-3 sm:p-1.5 transition-all duration-300 flex items-center ${\n (isDraggedOver && (canAcceptMore || maxItems === 1)) || isReorderDraggedOver\n ? 'shadow-lg scale-110 border-solid animate-pulse'\n : isFull\n ? 'bg-dc-surface-secondary'\n : 'bg-dc-surface-secondary hover:bg-dc-surface-hover'\n }`}\n style={{\n borderColor: (isDraggedOver && (canAcceptMore || maxItems === 1)) || isReorderDraggedOver\n ? 'var(--dc-primary)'\n : 'var(--dc-border)',\n backgroundColor: (isDraggedOver && (canAcceptMore || maxItems === 1)) || isReorderDraggedOver\n ? 'rgba(var(--dc-primary-rgb), 0.1)'\n : undefined\n }}\n onDragOver={(e) => {\n // Check if this is a reorder operation (same axis) - if so, don't interfere\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n return\n }\n \n // Simple acceptance check - either we have space OR it's a single-item replacement\n const canAccept = canAcceptMore || (maxItems === 1)\n \n if (canAccept) {\n setIsDraggedOver(true)\n onDragOver(e)\n } else {\n e.preventDefault()\n e.dataTransfer.dropEffect = 'none'\n }\n }}\n onDragLeave={(e) => {\n // Check if we're truly leaving the container\n const rect = e.currentTarget.getBoundingClientRect()\n const isLeavingContainer = (\n e.clientX < rect.left || \n e.clientX > rect.right || \n e.clientY < rect.top || \n e.clientY > rect.bottom\n )\n \n // Also check if the related target is outside this container\n const relatedTarget = e.relatedTarget as Element | null\n const isRelatedTargetOutside = relatedTarget && !e.currentTarget.contains(relatedTarget)\n \n if (isLeavingContainer || isRelatedTargetOutside || e.currentTarget === e.target) {\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }\n }}\n onDrop={(e) => {\n // Check if this is a reorder operation (same axis) - if so, don't interfere\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n return\n }\n \n // Simple acceptance check - either we have space OR it's a single-item replacement\n const shouldAcceptDrop = canAcceptMore || (maxItems === 1)\n \n if (shouldAcceptDrop) {\n onDrop(e, key)\n } else {\n e.preventDefault()\n }\n \n // Reset drag state on drop\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }}\n >\n {fields.length === 0 ? (\n <div className=\"text-xs text-dc-text-muted text-center w-full\">\n {isFull ? 'Maximum items reached' : (emptyText || `Drop fields here`)}\n </div>\n ) : (\n <div className=\"flex flex-wrap gap-1\">\n {fields.map((field, index) => {\n const { IconComponent: FieldIcon, baseClasses, hoverClasses } = getFieldStyling(field)\n const isDragOver = dragOverIndex === index\n const isBeingDragged = draggedItem && draggedItem.field === field && draggedItem.fromAxis === key\n \n return (\n <div\n key={`${field}-${index}`}\n className={`relative ${isDragOver ? 'transform scale-105' : ''}`}\n >\n {/* Drop indicator line for reordering */}\n {isDragOver && (\n <div className=\"absolute -left-1 top-0 bottom-0 w-1 rounded-full z-10\" style={{ backgroundColor: 'var(--dc-primary)' }} />\n )}\n \n <div\n draggable\n onDragStart={(e) => {\n // Let parent handle drag data with index\n onDragStart(e, field, key, index)\n }}\n onDragEnd={onDragEnd}\n onDragOver={(e) => handleReorderDragOver(e, index)}\n onDragLeave={handleReorderDragLeave}\n onDrop={(e) => handleReorderDrop(e, index)}\n className={`rounded text-xs cursor-move px-3 py-0.5 sm:px-2 sm:py-1 flex items-center transition-transform h-[28px] sm:h-auto ${baseClasses} ${hoverClasses} ${\n isDragOver ? 'bg-opacity-75' : ''\n } ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n >\n <FieldIcon className=\"w-3 h-3 mr-1 shrink-0\" />\n <span className=\"leading-none\">{field}</span>\n <button\n type=\"button\"\n onClick={() => onRemove(field, key)}\n className=\"text-dc-text-secondary hover:text-red-600 ml-1.5 leading-none\"\n title={`Remove from ${label}`}\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n </div>\n )\n })}\n </div>\n )}\n </div>\n \n {mandatory && fields.length === 0 && (\n <div className=\"text-xs text-red-500 mt-0.5\">\n This field is required\n </div>\n )}\n </div>\n )\n}","import React, { useMemo, useEffect, useState } from 'react'\nimport { getIcon } from '../icons'\nimport AxisDropZone from './AxisDropZone'\n\nconst MeasureIcon = getIcon('measure')\nconst DimensionIcon = getIcon('dimension')\nconst TimeDimensionIcon = getIcon('timeDimension')\nimport { chartConfigRegistry } from '../charts/chartConfigRegistry'\nimport { getChartConfig } from '../charts/chartConfigs'\nimport type { ChartType, ChartAxisConfig, ChartDisplayConfig, ColorPalette } from '../types'\n\ninterface ChartConfigPanelProps {\n chartType: ChartType\n chartConfig: ChartAxisConfig\n displayConfig: ChartDisplayConfig\n availableFields: {\n dimensions: string[]\n timeDimensions: string[]\n measures: string[]\n } | null\n colorPalette?: ColorPalette\n onChartConfigChange: (config: ChartAxisConfig) => void\n onDisplayConfigChange: (config: ChartDisplayConfig) => void\n}\n\nexport default function ChartConfigPanel({\n chartType,\n chartConfig,\n displayConfig,\n availableFields,\n colorPalette,\n onChartConfigChange,\n onDisplayConfigChange\n}: ChartConfigPanelProps) {\n \n // Track currently dragging item for immediate state updates\n const [draggedItem, setDraggedItem] = useState<{\n field: string\n fromAxis: string\n fromIndex?: number\n } | null>(null)\n \n // Get configuration for current chart type\n const chartTypeConfig = useMemo(() => \n getChartConfig(chartType, chartConfigRegistry),\n [chartType]\n )\n \n // Check if this chart type skips queries\n const shouldSkipQuery = chartTypeConfig.skipQuery === true\n\n // Get fields for each drop zone\n const getFieldsForDropZone = (key: string): string[] => {\n const value = chartConfig[key as keyof ChartAxisConfig]\n const result = Array.isArray(value) ? value : (typeof value === 'string' ? [value] : [])\n return result\n }\n\n // Clean up chart config when available fields change\n useEffect(() => {\n if (!availableFields) return\n\n const allAvailableFields = [\n ...availableFields.dimensions,\n ...availableFields.timeDimensions,\n ...availableFields.measures\n ]\n\n let hasChanges = false\n const newConfig = { ...chartConfig }\n\n // Check each axis and remove fields that are no longer available\n chartTypeConfig.dropZones.forEach(dropZone => {\n const currentFields = getFieldsForDropZone(dropZone.key)\n const validFields = currentFields.filter(field => allAvailableFields.includes(field))\n \n if (validFields.length !== currentFields.length) {\n hasChanges = true\n if (validFields.length === 0) {\n // Remove the axis property entirely if no valid fields remain\n delete newConfig[dropZone.key as keyof ChartAxisConfig]\n } else if (dropZone.maxItems === 1) {\n // Single field axis - always store as string\n newConfig[dropZone.key as keyof ChartAxisConfig] = validFields[0] as any\n } else {\n // Multi-field axis - always store as array\n newConfig[dropZone.key as keyof ChartAxisConfig] = validFields as any\n }\n }\n })\n\n if (hasChanges) {\n onChartConfigChange(newConfig)\n }\n }, [availableFields, chartConfig, chartTypeConfig.dropZones, onChartConfigChange])\n\n // Helper to determine field type and styling\n const getFieldType = (field: string): 'dimension' | 'timeDimension' | 'measure' => {\n if (!availableFields) return 'dimension'\n if (availableFields.measures.includes(field)) return 'measure'\n if (availableFields.timeDimensions.includes(field)) return 'timeDimension'\n return 'dimension'\n }\n\n const getFieldStyling = (field: string) => {\n const fieldType = getFieldType(field)\n\n switch (fieldType) {\n case 'measure':\n return {\n IconComponent: MeasureIcon,\n baseClasses: 'bg-dc-measure text-dc-measure border border-dc-measure',\n hoverClasses: 'hover:opacity-80'\n }\n case 'timeDimension':\n return {\n IconComponent: TimeDimensionIcon,\n baseClasses: 'bg-dc-time-dimension text-dc-time-dimension border border-dc-time-dimension',\n hoverClasses: 'hover:opacity-80'\n }\n default:\n return {\n IconComponent: DimensionIcon,\n baseClasses: 'bg-dc-dimension text-dc-dimension border border-dc-dimension',\n hoverClasses: 'hover:opacity-80'\n }\n }\n }\n\n // Drag and drop handlers\n const handleDragStart = (e: React.DragEvent<HTMLDivElement>, field: string, fromAxis: string, fromIndex?: number) => {\n e.dataTransfer.setData('text/plain', JSON.stringify({ field, fromAxis, fromIndex }))\n \n // Just track the dragged item - don't remove it yet\n setDraggedItem({ field, fromAxis, fromIndex })\n }\n\n const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n }\n\n const handleDragEnd = () => {\n // Just clear the dragged item tracking - no need to restore since we didn't remove it\n setDraggedItem(null)\n }\n\n const handleDrop = (e: React.DragEvent<HTMLDivElement>, toAxis: string) => {\n e.preventDefault()\n const data = JSON.parse(e.dataTransfer.getData('text/plain'))\n const { field, fromAxis } = data\n \n const newConfig = { ...chartConfig }\n \n // Remove from old location if moving between axes\n if (fromAxis !== 'available' && fromAxis !== toAxis) {\n const fromValue = newConfig[fromAxis as keyof ChartAxisConfig]\n if (Array.isArray(fromValue)) {\n const filteredValue = fromValue.filter(f => f !== field)\n if (filteredValue.length === 0) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n } else {\n newConfig[fromAxis as keyof ChartAxisConfig] = filteredValue as any\n }\n } else if (fromValue === field) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n }\n }\n \n // Add to new location\n const toValue = newConfig[toAxis as keyof ChartAxisConfig]\n const dropZoneConfig = chartTypeConfig.dropZones.find(dz => dz.key === toAxis)\n \n if (dropZoneConfig?.maxItems === 1) {\n // Single field - always store as string\n newConfig[toAxis as keyof ChartAxisConfig] = field as any\n } else {\n // Multiple fields - always store as array\n if (Array.isArray(toValue)) {\n if (!toValue.includes(field)) {\n newConfig[toAxis as keyof ChartAxisConfig] = [...toValue, field] as any\n }\n } else {\n newConfig[toAxis as keyof ChartAxisConfig] = [field] as any\n }\n }\n \n // Clear the dragged item tracking\n setDraggedItem(null)\n onChartConfigChange(newConfig)\n }\n\n const handleRemoveFromAxis = (field: string, fromAxis: string) => {\n const newConfig = { ...chartConfig }\n const value = newConfig[fromAxis as keyof ChartAxisConfig]\n \n if (Array.isArray(value)) {\n const filteredValue = value.filter(f => f !== field)\n if (filteredValue.length === 0) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n } else {\n newConfig[fromAxis as keyof ChartAxisConfig] = filteredValue as any\n }\n } else if (value === field) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n }\n \n onChartConfigChange(newConfig)\n }\n\n const handleReorder = (fromIndex: number, toIndex: number, axisKey: string) => {\n const newConfig = { ...chartConfig }\n const value = newConfig[axisKey as keyof ChartAxisConfig]\n \n // Only reorder if we have an array with multiple items\n if (Array.isArray(value) && value.length > 1 && fromIndex !== toIndex) {\n const newArray = [...value]\n const [movedItem] = newArray.splice(fromIndex, 1)\n newArray.splice(toIndex, 0, movedItem)\n newConfig[axisKey as keyof ChartAxisConfig] = newArray as any\n \n // Clear the dragged item tracking\n setDraggedItem(null)\n onChartConfigChange(newConfig)\n }\n }\n\n // Get unassigned fields\n const getUnassignedFields = () => {\n if (!availableFields) return { dimensions: [], timeDimensions: [], measures: [] }\n \n const assignedFields = new Set<string>()\n chartTypeConfig.dropZones.forEach(dz => {\n getFieldsForDropZone(dz.key).forEach(field => assignedFields.add(field))\n })\n \n // Exclude the currently dragged field only if it's being dragged FROM a configured axis\n // (not from available fields, where it should remain visible)\n if (draggedItem && draggedItem.fromAxis !== 'available') {\n assignedFields.add(draggedItem.field)\n }\n \n return {\n dimensions: availableFields.dimensions.filter(f => !assignedFields.has(f)),\n timeDimensions: availableFields.timeDimensions.filter(f => !assignedFields.has(f)),\n measures: availableFields.measures.filter(f => !assignedFields.has(f))\n }\n }\n\n const unassignedFields = getUnassignedFields()\n\n\n return (\n <div>\n {/* Available Fields - Hidden for skipQuery charts */}\n {!shouldSkipQuery && availableFields && (\n <div className=\"mb-4\">\n <h4 className=\"text-xs font-semibold text-dc-text-secondary mb-2\">Available Fields</h4>\n <div className=\"border border-dc-border rounded-lg p-2 bg-dc-surface-secondary\">\n {(unassignedFields.dimensions.length > 0 ||\n unassignedFields.timeDimensions.length > 0 ||\n unassignedFields.measures.length > 0) ? (\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-2 sm:gap-2 gap-y-4 sm:gap-y-2\">\n {/* Dimensions Column */}\n <div className=\"pb-2 sm:pb-0\">\n <div className=\"text-xs text-dc-text-secondary mb-2 sm:mb-1 flex items-center\">\n <DimensionIcon className=\"w-3 h-3 mr-1 text-dc-text-muted\" />\n Dimensions\n </div>\n <div className=\"space-y-1\">\n {unassignedFields.dimensions.map(dim => {\n const isBeingDragged = draggedItem && draggedItem.field === dim && draggedItem.fromAxis === 'available'\n return (\n <div\n key={dim}\n draggable\n onDragStart={(e) => handleDragStart(e, dim, 'available')}\n onDragEnd={handleDragEnd}\n className={`bg-dc-dimension text-dc-dimension border border-dc-dimension hover:opacity-80 rounded-sm text-xs cursor-move px-3 py-2 sm:px-2 sm:py-1 truncate ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n title={dim}\n >\n {dim}\n </div>\n )\n })}\n {unassignedFields.dimensions.length === 0 && (\n <div className=\"text-xs text-dc-text-muted italic\">None</div>\n )}\n </div>\n </div>\n \n {/* Time Dimensions Column */}\n <div className=\"pb-2 sm:pb-0\">\n <div className=\"text-xs text-dc-text-secondary mb-2 sm:mb-1 flex items-center\">\n <TimeDimensionIcon className=\"w-3 h-3 mr-1 text-dc-text-muted\" />\n Time Dimensions\n </div>\n <div className=\"space-y-1\">\n {unassignedFields.timeDimensions.map(dim => {\n const isBeingDragged = draggedItem && draggedItem.field === dim && draggedItem.fromAxis === 'available'\n return (\n <div\n key={dim}\n draggable\n onDragStart={(e) => handleDragStart(e, dim, 'available')}\n onDragEnd={handleDragEnd}\n className={`bg-dc-time-dimension text-dc-time-dimension border border-dc-time-dimension hover:opacity-80 rounded-sm text-xs cursor-move px-3 py-2 sm:px-2 sm:py-1 truncate ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n title={dim}\n >\n {dim}\n </div>\n )\n })}\n {unassignedFields.timeDimensions.length === 0 && (\n <div className=\"text-xs text-dc-text-muted italic\">None</div>\n )}\n </div>\n </div>\n \n {/* Measures Column */}\n <div className=\"pb-2 sm:pb-0\">\n <div className=\"text-xs text-dc-text-secondary mb-2 sm:mb-1 flex items-center\">\n <MeasureIcon className=\"w-3 h-3 mr-1 text-dc-text-muted\" />\n Measures\n </div>\n <div className=\"space-y-1\">\n {unassignedFields.measures.map(measure => {\n const isBeingDragged = draggedItem && draggedItem.field === measure && draggedItem.fromAxis === 'available'\n return (\n <div\n key={measure}\n draggable\n onDragStart={(e) => handleDragStart(e, measure, 'available')}\n onDragEnd={handleDragEnd}\n className={`bg-dc-measure text-dc-measure border border-dc-measure hover:opacity-80 rounded-sm text-xs cursor-move px-3 py-2 sm:px-2 sm:py-1 truncate ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n title={measure}\n >\n {measure}\n </div>\n )\n })}\n {unassignedFields.measures.length === 0 && (\n <div className=\"text-xs text-dc-text-muted italic\">None</div>\n )}\n </div>\n </div>\n </div>\n ) : (\n <div className=\"text-xs text-dc-text-muted text-center py-2\">\n All fields have been assigned\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Chart Axis Configuration - Dynamic Drop Zones, Hidden for skipQuery charts */}\n {!shouldSkipQuery && (\n <div className=\"mb-4\">\n <h4 className=\"text-xs font-semibold text-dc-text-secondary mb-2\">Chart Configuration</h4>\n <div className=\"space-y-1\">\n {chartTypeConfig.dropZones.map(dropZone => (\n <AxisDropZone\n key={dropZone.key}\n config={dropZone}\n fields={getFieldsForDropZone(dropZone.key)}\n onDrop={handleDrop}\n onRemove={handleRemoveFromAxis}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragOver={handleDragOver}\n getFieldStyling={getFieldStyling}\n onReorder={handleReorder}\n draggedItem={draggedItem}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Display Options */}\n {((chartTypeConfig.displayOptions && chartTypeConfig.displayOptions.length > 0) ||\n (chartTypeConfig.displayOptionsConfig && chartTypeConfig.displayOptionsConfig.length > 0)) && (\n <div className=\"mb-4\">\n <h4 className=\"text-xs font-semibold text-dc-text-secondary mb-2\">Display Options</h4>\n <div className=\"space-y-2\">\n {/* Backward compatibility: Simple boolean display options */}\n {chartTypeConfig.displayOptions?.includes('showLegend') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.showLegend ?? true}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n showLegend: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-blue-500\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Show Legend</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('showGrid') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.showGrid ?? true}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n showGrid: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-blue-500\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Show Grid</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('showTooltip') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.showTooltip ?? true}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n showTooltip: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-blue-500\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Show Tooltip</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('stacked') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.stacked ?? false}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n stacked: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-blue-500\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Stacked</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('hideHeader') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.hideHeader ?? false}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n hideHeader: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-blue-500\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Hide Header</span>\n </label>\n )}\n\n {/* New structured display options */}\n {chartTypeConfig.displayOptionsConfig?.map((option) => (\n <div key={option.key} className=\"space-y-1\">\n {option.type === 'boolean' && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? false}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-blue-500\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">{option.label}</span>\n </label>\n )}\n\n {option.type === 'string' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">\n {option.label}\n {option.key === 'content' && (\n <span className=\"text-xs text-dc-text-muted ml-1\">(only headers, lists and links)</span>\n )}\n </label>\n {option.key === 'content' ? (\n <textarea\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? ''}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n placeholder={option.placeholder}\n rows={8}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-blue-500 focus:border-blue-500 font-mono resize-y bg-dc-surface text-dc-text\"\n />\n ) : (\n <input\n type=\"text\"\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? ''}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n placeholder={option.placeholder}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-blue-500 focus:border-blue-500 bg-dc-surface text-dc-text\"\n />\n )}\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'paletteColor' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <div className=\"flex flex-wrap gap-2\">\n {colorPalette?.colors.map((color, index) => {\n const isSelected = (displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? 0) === index\n return (\n <button\n key={index}\n type=\"button\"\n onClick={() => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: index\n })}\n className={`w-8 h-8 rounded border-2 transition-all duration-200 hover:scale-110 focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:ring-offset-1 ${\n isSelected\n ? 'ring-2 ring-offset-1 scale-110'\n : 'hover:border-dc-text-muted'\n }`}\n style={{\n backgroundColor: color,\n borderColor: isSelected ? 'var(--dc-primary)' : 'var(--dc-border)'\n }}\n title={`Color ${index + 1}: ${color}`}\n />\n )\n }) || [\n // Fallback if no palette available\n <button\n key={0}\n type=\"button\"\n onClick={() => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: 0\n })}\n className=\"w-8 h-8 rounded-sm border-2 ring-2 ring-offset-1\"\n style={{\n backgroundColor: '#8884d8',\n borderColor: 'var(--dc-primary)',\n boxShadow: '0 0 0 2px var(--dc-primary)'\n }}\n title=\"Default Color\"\n />\n ]}\n </div>\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'number' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <input\n type=\"number\"\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? 0}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value === '' ? undefined : Number(e.target.value)\n })}\n placeholder={option.placeholder}\n min={option.min}\n max={option.max}\n step={option.step}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-blue-500 focus:border-blue-500 bg-dc-surface text-dc-text\"\n />\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'select' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <select\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? ''}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-blue-500 focus:border-blue-500 bg-dc-surface text-dc-text\"\n >\n {option.options?.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'color' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"color\"\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? '#8884d8'}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n className=\"w-12 h-8 border border-dc-border rounded-sm cursor-pointer\"\n />\n <input\n type=\"text\"\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? '#8884d8'}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n placeholder={option.placeholder || '#8884d8'}\n className=\"flex-1 px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-blue-500 focus:border-blue-500 bg-dc-surface text-dc-text\"\n />\n </div>\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n )\n}","/**\n * ResultsPanel Component\n *\n * Displays query execution results, loading states, and errors.\n * Supports both table and chart visualization with configurable chart types.\n */\n\nimport React, { useState } from 'react'\nimport { LazyChart, isValidChartType } from '../../charts/ChartLoader'\nimport ChartTypeSelector from '../ChartTypeSelector'\nimport ChartConfigPanel from '../ChartConfigPanel'\nimport type { ResultsPanelProps } from './types'\nimport { getIcon } from '../../icons'\n\nconst ResultsPanel: React.FC<ResultsPanelProps> = ({\n executionStatus,\n executionResults,\n executionError,\n query,\n displayLimit = 10,\n onDisplayLimitChange,\n totalRowCount,\n totalRowCountStatus,\n // Chart visualization props\n chartType = 'table',\n chartConfig = {},\n displayConfig = {},\n availableFields,\n onChartTypeChange,\n onChartConfigChange,\n onDisplayConfigChange,\n // View state props\n activeView: activeViewProp = 'table',\n onActiveViewChange\n}) => {\n // Get icons\n const ErrorIcon = getIcon('error')\n const TimeIcon = getIcon('timeDimension')\n const SuccessIcon = getIcon('success')\n const WarningIcon = getIcon('warning')\n const ChevronDownIcon = getIcon('chevronDown')\n const ChevronUpIcon = getIcon('chevronUp')\n const TableIcon = getIcon('table')\n const MeasureIcon = getIcon('measure')\n const AdjustmentsIcon = getIcon('adjustments')\n\n // Use prop if provided, otherwise use local state for backwards compatibility\n const [localActiveView, setLocalActiveView] = useState<'table' | 'chart'>('table')\n const activeView = onActiveViewChange ? activeViewProp : localActiveView\n const setActiveView = onActiveViewChange || setLocalActiveView\n\n // Local state for config panel visibility\n const [showChartConfig, setShowChartConfig] = useState(false)\n\n const LoadingState = () => (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 mx-auto mb-4\" style={{ borderBottomColor: 'var(--dc-primary)' }}></div>\n <div className=\"text-sm font-semibold text-dc-text-secondary mb-1\">Executing Query...</div>\n <div className=\"text-xs text-dc-text-muted\">Running your query against the cube API</div>\n </div>\n </div>\n )\n\n const ErrorState = () => (\n <div className=\"h-full flex items-center justify-center p-4\">\n <div className=\"text-center max-w-md\">\n <ErrorIcon className=\"w-12 h-12 mx-auto text-red-500 mb-4\" />\n <div className=\"text-sm font-semibold text-dc-text mb-2\">Query Execution Failed</div>\n <div className=\"text-sm text-dc-text-secondary mb-4\">\n There was an error executing your query. Please check the query and try again.\n </div>\n {executionError && (\n <div className=\"bg-red-50 border border-red-200 rounded-lg p-3 text-left\">\n <div className=\"text-xs font-mono text-red-800 break-words\">\n {executionError}\n </div>\n </div>\n )}\n </div>\n </div>\n )\n\n const EmptyState = () => (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center mb-16\">\n <TimeIcon className=\"w-12 h-12 mx-auto text-dc-text-muted mb-3\" />\n <div className=\"text-sm font-semibold text-dc-text-secondary mb-1\">No Results Yet</div>\n <div className=\"text-xs text-dc-text-muted\">Build and run a query to see results here</div>\n </div>\n </div>\n )\n\n // Render the appropriate chart component using lazy loading\n const renderChart = () => {\n if (!executionResults || executionResults.length === 0) {\n return (\n <div className=\"flex items-center justify-center h-full text-dc-text-muted\">\n <div className=\"text-center\">\n <MeasureIcon className=\"w-12 h-12 mx-auto mb-3 opacity-50\" />\n <div className=\"text-sm font-semibold mb-1\">No data to display</div>\n <div className=\"text-xs\">Run a query to see chart visualization</div>\n </div>\n </div>\n )\n }\n\n const chartHeight = 400\n const data = executionResults\n\n try {\n // Check if it's a valid chart type for lazy loading\n if (!isValidChartType(chartType)) {\n return (\n <div className=\"flex items-center justify-center h-full text-dc-text-muted\">\n <div className=\"text-center\">\n <WarningIcon className=\"w-12 h-12 mx-auto mb-3 opacity-50\" />\n <div className=\"text-sm font-semibold mb-1\">Unsupported chart type</div>\n <div className=\"text-xs\">{chartType}</div>\n </div>\n </div>\n )\n }\n\n // For markdown chart, use empty data array\n const chartData = chartType === 'markdown' ? [] : data\n\n return (\n <LazyChart\n chartType={chartType}\n data={chartData}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n queryObject={query}\n height={chartHeight}\n fallback={\n <div className=\"flex items-center justify-center\" style={{ height: chartHeight }}>\n <div className=\"animate-pulse bg-dc-surface-secondary rounded w-full h-full\" />\n </div>\n }\n />\n )\n } catch (error) {\n console.error('Chart rendering error:', error)\n return (\n <div className=\"flex items-center justify-center h-full text-dc-text-muted p-4\">\n <div className=\"text-center\">\n <ErrorIcon className=\"w-12 h-12 mx-auto mb-3 text-red-400\" />\n <div className=\"text-sm font-semibold mb-1\">Unable to render chart</div>\n <div className=\"text-xs text-dc-text-secondary\">{error instanceof Error ? error.message : 'Unknown error'}</div>\n </div>\n </div>\n )\n }\n }\n\n const SuccessState = () => {\n if (!executionResults || executionResults.length === 0) {\n return (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center\">\n <SuccessIcon className=\"w-12 h-12 mx-auto text-green-500 mb-3\" />\n <div className=\"text-sm font-semibold text-gray-700 mb-1\">Query Successful</div>\n <div className=\"text-xs text-gray-500\">No data returned from the query</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"h-full flex flex-col\">\n {/* Results Header with Chart Controls */}\n <div className=\"p-4 border-b border-dc-border bg-dc-surface-secondary\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n {/* Left side: Status and row count */}\n <div className=\"flex items-center\">\n <SuccessIcon className=\"w-5 h-5 text-green-500 mr-2\" />\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-semibold text-dc-text-secondary\">\n Query Results ({executionResults.length} row{executionResults.length !== 1 ? 's' : ''} shown)\n </span>\n {totalRowCountStatus === 'success' && totalRowCount !== null && totalRowCount !== undefined && (\n <span className=\"text-xs text-dc-text-muted\">\n Total: {totalRowCount.toLocaleString()} row{totalRowCount !== 1 ? 's' : ''}\n </span>\n )}\n {totalRowCountStatus === 'loading' && (\n <span className=\"text-xs text-dc-text-muted\">\n Counting total rows...\n </span>\n )}\n </div>\n </div>\n\n {/* Right side: View tabs and display limit */}\n <div className=\"flex items-center gap-3 flex-wrap\">\n {/* View Toggle Tabs */}\n <div className=\"flex items-center bg-dc-surface border border-dc-border rounded-md overflow-hidden\">\n <button\n onClick={() => setActiveView('table')}\n className={`flex items-center gap-1 px-3 py-1.5 text-xs font-medium transition-colors ${\n activeView === 'table'\n ? 'bg-dc-primary text-white'\n : 'text-dc-text-secondary hover:bg-dc-surface-hover'\n }`}\n >\n <TableIcon className=\"w-3.5 h-3.5\" />\n Table\n </button>\n <button\n onClick={() => setActiveView('chart')}\n className={`flex items-center gap-1 px-3 py-1.5 text-xs font-medium transition-colors ${\n activeView === 'chart'\n ? 'bg-dc-primary text-white'\n : 'text-dc-text-secondary hover:bg-dc-surface-hover'\n }`}\n >\n <MeasureIcon className=\"w-3.5 h-3.5\" />\n Chart\n </button>\n </div>\n\n {/* Display Limit (only show for table view) */}\n {activeView === 'table' && onDisplayLimitChange && (\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs text-dc-text-secondary\">Show:</label>\n <select\n value={displayLimit}\n onChange={(e) => onDisplayLimitChange(Number(e.target.value))}\n className=\"text-xs border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:outline-hidden focus:ring-1 focus:ring-blue-500\"\n >\n <option value={10}>10 rows</option>\n <option value={50}>50 rows</option>\n <option value={100}>100 rows</option>\n </select>\n </div>\n )}\n </div>\n </div>\n\n {/* Chart Controls Row (only show when chart view is active) */}\n {activeView === 'chart' && onChartTypeChange && (\n <div className=\"mt-3 pt-3 border-t border-dc-border flex items-center justify-between gap-3 flex-wrap\">\n {/* Chart Type Selector */}\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs text-dc-text-secondary whitespace-nowrap\">Chart Type:</label>\n <ChartTypeSelector\n selectedType={chartType}\n onTypeChange={onChartTypeChange}\n />\n </div>\n\n {/* Configure Chart Button (only show for non-table chart types) */}\n {chartType !== 'table' && onChartConfigChange && onDisplayConfigChange && (\n <button\n onClick={() => setShowChartConfig(!showChartConfig)}\n className={`flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md transition-colors ${\n showChartConfig\n ? 'bg-dc-primary text-white'\n : 'text-dc-text-secondary bg-dc-surface hover:bg-dc-surface-hover border border-dc-border'\n }`}\n >\n <AdjustmentsIcon className=\"w-4 h-4\" />\n {showChartConfig ? 'Hide Config' : 'Configure'}\n {showChartConfig ? (\n <ChevronUpIcon className=\"w-3.5 h-3.5\" />\n ) : (\n <ChevronDownIcon className=\"w-3.5 h-3.5\" />\n )}\n </button>\n )}\n </div>\n )}\n\n {/* Performance Warning */}\n {totalRowCountStatus === 'success' && totalRowCount !== null && totalRowCount !== undefined && totalRowCount > 500 && (\n <div className=\"mt-3 bg-yellow-50 border border-yellow-200 rounded-lg p-3 flex items-start\">\n <WarningIcon className=\"w-5 h-5 text-yellow-600 mr-2 shrink-0 mt-0.5\" />\n <div className=\"text-sm text-yellow-800\">\n <span className=\"font-semibold\">Performance Warning:</span> This query returns {totalRowCount.toLocaleString()} rows,\n which may impact performance. Consider adding filters to reduce the dataset size.\n </div>\n </div>\n )}\n </div>\n\n {/* Collapsible Chart Config Panel (only when chart view is active) */}\n {activeView === 'chart' && showChartConfig && chartType !== 'table' && onChartConfigChange && onDisplayConfigChange && (\n <div className=\"border-b border-dc-border bg-dc-surface-tertiary p-4\">\n <ChartConfigPanel\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n availableFields={availableFields || null}\n onChartConfigChange={onChartConfigChange}\n onDisplayConfigChange={onDisplayConfigChange}\n />\n </div>\n )}\n\n {/* Results Content - Table or Chart based on active view */}\n <div className=\"flex-1 min-h-0\">\n {activeView === 'table' ? (\n <LazyChart\n chartType=\"table\"\n data={executionResults}\n height=\"100%\"\n fallback={\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"animate-pulse bg-dc-surface-secondary rounded w-full h-full\" />\n </div>\n }\n />\n ) : (\n <div className=\"p-4 h-full overflow-auto\">\n {renderChart()}\n </div>\n )}\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"flex-1 flex flex-col bg-dc-surface border border-dc-border rounded-lg min-h-0\">\n {/* Header */}\n <div className=\"px-4 py-3 border-b border-dc-border bg-dc-surface-secondary\">\n <h3 className=\"text-sm font-semibold text-dc-text\">Query Results</h3>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 min-h-0\">\n {executionStatus === 'loading' && <LoadingState />}\n {executionStatus === 'error' && <ErrorState />}\n {executionStatus === 'success' && <SuccessState />}\n {executionStatus === 'idle' && <EmptyState />}\n </div>\n </div>\n )\n}\n\nexport default ResultsPanel\n","/**\n * SetupPanel Component\n * \n * Provides configuration options for API endpoint and authentication.\n * Only shown in standalone QueryBuilder mode, not in modal contexts.\n */\n\nimport React, { useState } from 'react'\nimport { getIcon } from '../../icons'\nimport type { ApiConfig } from './types'\n\nconst ChevronDownIcon = getIcon('chevronDown')\nconst ChevronUpIcon = getIcon('chevronUp')\nconst SettingsIcon = getIcon('settings')\nconst RefreshIcon = getIcon('refresh')\n\ninterface SetupPanelProps {\n isOpen: boolean\n onToggle: () => void\n config: ApiConfig\n onConfigChange: (config: ApiConfig) => void\n onReset: () => void\n}\n\nconst SetupPanel: React.FC<SetupPanelProps> = ({\n isOpen,\n onToggle,\n config,\n onConfigChange,\n onReset\n}) => {\n const [localConfig, setLocalConfig] = useState<ApiConfig>(config)\n\n const handleApply = () => {\n onConfigChange(localConfig)\n }\n\n const handleReset = () => {\n const defaultConfig = {\n baseApiUrl: '/cubejs-api/v1',\n apiToken: ''\n }\n setLocalConfig(defaultConfig)\n onConfigChange(defaultConfig)\n onReset()\n }\n\n const handleInputChange = (field: keyof ApiConfig, value: string) => {\n setLocalConfig(prev => ({\n ...prev,\n [field]: value\n }))\n }\n\n const hasChanges = JSON.stringify(localConfig) !== JSON.stringify(config)\n const isUsingDefaults = config.baseApiUrl === '/cubejs-api/v1' && config.apiToken === ''\n\n return (\n <div className=\"bg-dc-surface border border-dc-border rounded-lg mb-4\">\n {/* Header */}\n <button\n onClick={onToggle}\n className=\"w-full px-4 py-3 flex items-center justify-between text-left bg-dc-surface-secondary rounded-t-lg hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n >\n <div className=\"flex items-center space-x-2\">\n <SettingsIcon className=\"w-5 h-5 text-dc-text-secondary\" />\n <h3 className=\"text-sm font-semibold text-dc-text\">API Configuration</h3>\n {!isUsingDefaults && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-dc-info text-dc-text\">\n Custom\n </span>\n )}\n </div>\n {isOpen ? (\n <ChevronUpIcon className=\"w-4 h-4 text-dc-text-muted\" />\n ) : (\n <ChevronDownIcon className=\"w-4 h-4 text-dc-text-muted\" />\n )}\n </button>\n\n {/* Expandable Content */}\n {isOpen && (\n <div className=\"p-4 border-t border-dc-border\">\n <div className=\"space-y-4\">\n {/* Base API URL */}\n <div>\n <label className=\"block text-sm font-medium text-dc-text-secondary mb-1\">\n Base API URL\n </label>\n <input\n type=\"text\"\n value={localConfig.baseApiUrl}\n onChange={(e) => handleInputChange('baseApiUrl', e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm\"\n placeholder=\"/cubejs-api/v1\"\n />\n <p className=\"text-xs text-dc-text-muted mt-1\">\n The base URL for the Cube.js API endpoints\n </p>\n </div>\n\n {/* API Token */}\n <div>\n <label className=\"block text-sm font-medium text-dc-text-secondary mb-1\">\n API Token\n </label>\n <input\n type=\"password\"\n value={localConfig.apiToken}\n onChange={(e) => handleInputChange('apiToken', e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm\"\n placeholder=\"Leave empty for no authentication\"\n />\n <p className=\"text-xs text-dc-text-muted mt-1\">\n Optional bearer token for API authentication\n </p>\n </div>\n\n {/* Status Indicator */}\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-md p-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h4 className=\"text-xs font-medium text-dc-text-secondary\">Current Configuration</h4>\n <p className=\"text-xs text-dc-text-secondary mt-1\">\n URL: <span className=\"font-mono\">{config.baseApiUrl}</span>\n </p>\n <p className=\"text-xs text-dc-text-secondary\">\n Token: {config.apiToken ? (\n <span className=\"text-green-600\">Configured</span>\n ) : (\n <span className=\"text-dc-text-muted\">Not set</span>\n )}\n </p>\n </div>\n {!isUsingDefaults && (\n <button\n onClick={handleReset}\n className=\"flex items-center space-x-1 px-2 py-1 text-xs font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-sm hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n title=\"Reset to defaults\"\n >\n <RefreshIcon className=\"w-3 h-3\" />\n <span>Reset</span>\n </button>\n )}\n </div>\n </div>\n\n {/* Action Buttons */}\n {hasChanges && (\n <div className=\"flex justify-end space-x-2 pt-2 border-t border-dc-border\">\n <button\n onClick={() => setLocalConfig(config)}\n className=\"px-3 py-1.5 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n >\n Cancel\n </button>\n <button\n onClick={handleApply}\n className=\"px-3 py-1.5 text-sm font-medium text-white border border-transparent rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n style={{ backgroundColor: 'var(--dc-primary)' }}\n >\n Apply Changes\n </button>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport default SetupPanel","/**\n * Constants for AI Assistant\n */\n\nexport const AI_PROXY_BASE_URL = '/api/ai'\nexport const GEMINI_MODEL = 'gemini-2.0-flash'\n\nexport const DEFAULT_SYSTEM_PROMPT_TEMPLATE = `You are a SQL query builder assistant for a semantic layer using Cube.js format.\n\nAvailable cube schema (JSON):\n{CUBE_SCHEMA}\n\nA valid Cube schema can contain things such as below (this is only an example of possible options):\n\n{\n \"measures\": [\"stories.count\"],\n \"dimensions\": [\"stories.category\"],\n \"filters\": [\n {\n \"member\": \"stories.isDraft\",\n \"operator\": \"equals\",\n \"values\": [\"No\"]\n }\n ],\n \"timeDimensions\": [\n {\n \"dimension\": \"stories.time\",\n \"dateRange\": [\"2015-01-01\", \"2015-12-31\"],\n \"granularity\": \"month\"\n }\n ],\n \"limit\": 100,\n \"offset\": 50,\n \"order\": {\n \"stories.time\": \"asc\",\n \"stories.count\": \"desc\"\n }\n}\n\nUser request: {USER_PROMPT}\n\nCRITICAL: You MUST only use field names that exist in the schema above. Do NOT create or invent field names.\n\nGenerate a JSON query object with this structure:\n{\n \"measures\": [\"CubeName.measureName\"],\n \"dimensions\": [\"CubeName.dimensionName\"], \n \"timeDimensions\": [{\n \"dimension\": \"CubeName.timeDimensionName\",\n \"granularity\": \"hour|day|week|month|quarter|year\",\n \"dateRange\": \"last 30 days\"\n }],\n \"filters\": [{\n \"member\": \"CubeName.fieldName\",\n \"operator\": \"equals|contains|gt|gte|lt|lte|inDateRange\",\n \"values\": [\"value1\", \"value2\"]\n }]\n}\n\nRules:\n1. Only use cube names, measure names, and dimension names from the schema\n2. All field references must be in \"CubeName.fieldName\" format\n3. Verify every field exists in the provided schema before using it\n\nRespond with only the JSON query object, no explanation, no markdown formatting, no code blocks, no backtick wrapper.`\n\nexport const AI_STORAGE_KEY = 'drizzle-cube-ai-config'\n\nexport const DEFAULT_AI_CONFIG = {\n provider: 'gemini' as const,\n apiKey: ''\n}","/**\n * Utility functions for AI Assistant\n */\n\nimport type { \n AIQueryRequest,\n AIQueryResponse,\n AIConfig\n} from './types'\nimport { \n AI_STORAGE_KEY,\n DEFAULT_AI_CONFIG\n} from './constants'\n\n/**\n * Send a user prompt to AI proxy (server builds system prompt)\n */\nexport async function sendGeminiMessage(\n apiKey: string,\n userPrompt: string,\n endpoint: string = '/api/ai/generate'\n): Promise<AIQueryResponse> {\n const requestBody: AIQueryRequest = {\n text: userPrompt // Send only the user's prompt, server handles system prompt\n }\n\n // Only add API key header if provided (allow empty string for server key)\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json'\n }\n \n if (apiKey && apiKey.trim()) {\n headers['X-API-Key'] = apiKey\n }\n\n console.log('🤖 Client: Sending user prompt to AI proxy')\n console.log(' URL:', endpoint)\n console.log(' Headers:', headers)\n console.log(' User prompt length:', userPrompt.length)\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody)\n })\n\n console.log('📥 Client: Proxy response')\n console.log(' Status:', response.status)\n console.log(' Status Text:', response.statusText)\n\n if (!response.ok) {\n let errorMessage = `Failed to generate content: ${response.status} ${response.statusText}`\n \n try {\n // Try to parse JSON error response first\n const errorData = await response.json()\n console.error('❌ Client: Proxy error:', errorData)\n \n // Handle rate limit errors specially\n if (response.status === 429 && errorData.error === 'Daily quota exceeded') {\n throw new Error(\n `${errorData.message}\\n\\n${errorData.suggestion || 'Add your own Gemini API key for unlimited access.'}`\n )\n }\n \n // Handle other structured errors\n if (errorData.error) {\n errorMessage = errorData.message || errorData.error\n if (errorData.suggestion) {\n errorMessage += `\\n\\n💡 ${errorData.suggestion}`\n }\n }\n } catch (parseError) {\n // Fallback to text if JSON parsing fails\n try {\n const errorText = await response.text()\n console.error('❌ Client: Proxy text error:', errorText)\n errorMessage = errorText || errorMessage\n } catch (textError) {\n console.error('❌ Client: Could not parse error response')\n }\n }\n \n throw new Error(errorMessage)\n }\n\n const data = await response.json()\n console.log('✅ Client: Successfully generated content')\n return data\n}\n\n// Removed: buildSystemPrompt and formatCubeSchemaForPrompt \n// These functions are now handled server-side for better security\n\n/**\n * Save AI configuration to localStorage\n */\nexport function saveAIConfig(config: AIConfig): void {\n try {\n localStorage.setItem(AI_STORAGE_KEY, JSON.stringify(config))\n } catch (error) {\n console.warn('Failed to save AI config to localStorage:', error)\n }\n}\n\n/**\n * Load AI configuration from localStorage\n */\nexport function loadAIConfig(): AIConfig {\n try {\n const saved = localStorage.getItem(AI_STORAGE_KEY)\n if (saved) {\n const parsed = JSON.parse(saved)\n return { ...DEFAULT_AI_CONFIG, ...parsed }\n }\n } catch (error) {\n console.warn('Failed to load AI config from localStorage:', error)\n }\n return { ...DEFAULT_AI_CONFIG }\n}\n\n/**\n * Extract query text from simplified AI response and clean up formatting\n */\nexport function extractTextFromResponse(response: AIQueryResponse): string {\n const rawText = response.query || ''\n\n // Clean up common markdown formatting that might appear\n return rawText\n .replace(/```json\\s*/g, '') // Remove ```json\n .replace(/```\\s*/g, '') // Remove ```\n .replace(/^\\s*```.*\\n/gm, '') // Remove any remaining code block markers\n .trim()\n}","/**\n * AI Assistant Modal Component\n * \n * Multi-step modal for AI-powered query generation\n * Step 1: API Key input\n * Step 2: Model selection \n * Step 3: Query input and response\n */\n\nimport React, { useState } from 'react'\nimport { getIcon } from '../../icons'\nimport Modal from '../Modal'\n\nconst ErrorIcon = getIcon('error')\nconst SuccessIcon = getIcon('success')\nconst SparklesIcon = getIcon('sparkles')\nimport type { AIAssistantState } from './types'\nimport {\n sendGeminiMessage,\n loadAIConfig,\n extractTextFromResponse\n} from './utils'\nimport { DEFAULT_SYSTEM_PROMPT_TEMPLATE } from './constants'\n\ninterface AIAssistantModalProps {\n isOpen: boolean\n onClose: () => void\n schema?: any\n onQueryLoad?: (query: any) => void\n aiEndpoint?: string\n}\n\nconst AIAssistantModal: React.FC<AIAssistantModalProps> = ({\n isOpen,\n onClose,\n onQueryLoad,\n aiEndpoint = '/api/ai'\n}) => {\n const [state, setState] = useState<AIAssistantState>(() => {\n const savedConfig = loadAIConfig()\n return {\n step: 'query', // Skip API key step and go straight to query\n apiKey: savedConfig.apiKey || '',\n systemPromptTemplate: DEFAULT_SYSTEM_PROMPT_TEMPLATE,\n userPrompt: '',\n isSubmitting: false,\n response: null,\n responseError: null,\n isValidating: false,\n validationResult: null,\n validationError: null\n }\n })\n\n\n const handleQuerySubmit = async (e?: React.FormEvent) => {\n e?.preventDefault()\n if (!state.userPrompt.trim()) return\n\n setState(prev => ({ \n ...prev, \n isSubmitting: true, \n response: null, \n responseError: null,\n validationResult: null,\n validationError: null,\n isValidating: false\n }))\n\n try {\n // Send only the user prompt - server will handle system prompt building\n const response = await sendGeminiMessage(\n state.apiKey,\n state.userPrompt,\n aiEndpoint\n )\n\n const responseText = extractTextFromResponse(response)\n setState(prev => ({ \n ...prev, \n isSubmitting: false, \n response: responseText \n }))\n \n // Automatically validate after successful generation\n setTimeout(() => {\n validateResponse(responseText)\n }, 500)\n } catch (error) {\n setState(prev => ({\n ...prev,\n isSubmitting: false,\n responseError: error instanceof Error ? error.message : 'Failed to process query'\n }))\n }\n }\n\n // Validate a specific response text (used for auto-validation)\n const validateResponse = async (responseText: string) => {\n if (!responseText) {\n console.log('AI Modal: No response text to validate')\n return\n }\n\n console.log('AI Modal: Starting validation with response:', responseText.substring(0, 100) + '...')\n \n setState(prev => ({\n ...prev,\n isValidating: true,\n validationResult: null,\n validationError: null\n }))\n\n try {\n const query = JSON.parse(responseText)\n console.log('AI Modal: Parsed query:', query)\n \n const response = await fetch('/cubejs-api/v1/load', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(query)\n })\n\n console.log('AI Modal: Validation response status:', response.status)\n\n if (response.ok) {\n console.log('AI Modal: Validation SUCCESS')\n setState(prev => ({\n ...prev,\n isValidating: false,\n validationResult: 'valid'\n }))\n } else {\n const errorData = await response.text()\n console.log('AI Modal: Validation FAILED:', errorData)\n setState(prev => ({\n ...prev,\n isValidating: false,\n validationResult: 'invalid',\n validationError: errorData || `HTTP ${response.status}: ${response.statusText}`\n }))\n }\n } catch (error) {\n console.log('AI Modal: Validation ERROR:', error)\n setState(prev => ({\n ...prev,\n isValidating: false,\n validationResult: 'invalid',\n validationError: error instanceof Error ? error.message : 'Failed to validate query'\n }))\n }\n }\n\n const handleValidate = async () => {\n if (!state.response) return\n await validateResponse(state.response)\n }\n\n const handleUseQuery = () => {\n if (!state.response || !onQueryLoad) return\n\n try {\n const query = JSON.parse(state.response)\n onQueryLoad(query)\n handleClose()\n } catch (error) {\n setState(prev => ({\n ...prev,\n validationError: 'Invalid JSON format'\n }))\n }\n }\n\n const handleClose = () => {\n setState(prev => ({\n ...prev,\n response: null,\n responseError: null,\n validationResult: null,\n validationError: null\n }))\n onClose()\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n handleQuerySubmit()\n }\n }\n\n\n\n const renderQueryStep = () => (\n <div className=\"flex flex-col space-y-4\">\n {/* Top: Config Panel - Full Width */}\n <div className=\"shrink-0 p-3 bg-dc-surface-secondary border border-dc-border rounded-md\">\n <div className=\"text-sm text-dc-text-muted\">\n Using: <span className=\"font-medium\">AI Query Generation</span>\n <span className=\"ml-2 px-2 py-1 bg-blue-100 text-blue-700 text-xs rounded-sm\">\n Server-provided AI (Rate Limited)\n </span>\n </div>\n </div>\n \n {/* Middle: Input/Output Row - Takes remaining space */}\n <div className=\"flex flex-col md:flex-row gap-6 flex-1 min-h-0\">\n {/* Left: Query Input */}\n <div className=\"w-full md:w-1/2 flex flex-col\">\n <label htmlFor=\"user-prompt\" className=\"block text-sm font-medium text-dc-text-secondary mb-2\">\n Describe your query in natural language\n </label>\n <textarea\n id=\"user-prompt\"\n value={state.userPrompt}\n onChange={(e) => setState(prev => ({ ...prev, userPrompt: e.target.value }))}\n onKeyDown={handleKeyDown}\n placeholder=\"e.g., Show me the total revenue by month for the last year (Press Enter to generate, Shift+Enter for new line)\"\n className=\"flex-1 w-full px-3 py-2 border border-dc-border rounded-md shadow-xs focus:outline-none focus:ring-blue-500 focus:border-blue-500 resize-none bg-dc-surface text-dc-text\"\n required\n />\n </div>\n \n {/* Right: Output Query */}\n <div className=\"w-full md:w-1/2 flex flex-col\">\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center space-x-2\">\n {state.response ? (\n <>\n <SuccessIcon className=\"w-5 h-5 text-green-500\" />\n <span className=\"text-sm font-medium text-green-700\">AI Generated Query</span>\n </>\n ) : (\n <span className=\"text-sm font-medium text-dc-text-muted\">Generated Query</span>\n )}\n </div>\n {state.response && (\n <button\n onClick={handleValidate}\n disabled={state.isValidating}\n className=\"text-xs text-blue-600 hover:text-blue-800 disabled:opacity-50\"\n title=\"Click to re-validate query\"\n >\n {state.isValidating ? 'Validating...' : 'Re-validate'}\n </button>\n )}\n </div>\n\n {state.response ? (\n <div className=\"flex-1 bg-green-50 border border-green-200 rounded-md p-3\">\n <pre className=\"text-sm text-dc-text whitespace-pre-wrap overflow-auto bg-dc-surface p-3 rounded-sm border h-full\">\n {state.response}\n </pre>\n </div>\n ) : (\n <div className=\"flex-1 flex items-center justify-center text-dc-text-muted border-2 border-dashed border-dc-border rounded-md p-8 min-h-64\">\n <div className=\"text-center\">\n <SparklesIcon className=\"w-12 h-12 mx-auto text-dc-text-muted\" />\n </div>\n </div>\n )}\n </div>\n </div>\n \n {/* Status Messages - Fixed height */}\n <div className=\"shrink-0\">\n {state.responseError && (\n <div className=\"flex items-start space-x-2 p-3 bg-red-50 border border-red-200 rounded-md\">\n <ErrorIcon className=\"w-5 h-5 text-red-500 mt-0.5 shrink-0\" />\n <div className=\"text-sm text-red-700\">{state.responseError}</div>\n </div>\n )}\n \n {state.isValidating && (\n <div className=\"flex items-start space-x-2 p-3 bg-blue-50 border border-blue-200 rounded-md\">\n <div className=\"animate-spin rounded-full h-5 w-5 border-b-2 border-blue-600 mt-0.5 shrink-0\"></div>\n <div className=\"text-sm text-blue-700\">Validating query...</div>\n </div>\n )}\n \n {state.validationResult === 'valid' && !state.isValidating && (\n <div className=\"flex items-start space-x-2 p-3 bg-green-50 border border-green-200 rounded-md\">\n <SuccessIcon className=\"w-5 h-5 text-green-500 mt-0.5 shrink-0\" />\n <div className=\"text-sm text-green-700\">Query is valid and ready to use!</div>\n </div>\n )}\n \n {state.validationResult === 'invalid' && !state.isValidating && (\n <div className=\"flex items-start space-x-2 p-3 bg-red-50 border border-red-200 rounded-md\">\n <ErrorIcon className=\"w-5 h-5 text-red-500 mt-0.5 shrink-0\" />\n <div className=\"text-sm text-red-700\">\n <div className=\"font-medium mb-1\">Query validation failed:</div>\n <div className=\"text-xs\">{state.validationError}</div>\n </div>\n </div>\n )}\n </div>\n \n {/* Bottom: Action Buttons - Right Aligned */}\n <div className=\"shrink-0 flex justify-end space-x-3 pt-3\">\n <button\n type=\"submit\"\n disabled={!state.userPrompt.trim() || state.isSubmitting}\n onClick={handleQuerySubmit}\n className=\"px-4 py-2 text-white text-sm rounded-md hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed flex items-center\"\n style={{\n backgroundColor: 'var(--dc-primary)'\n }}\n >\n {state.isSubmitting ? (\n <>\n <div className=\"animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2\"></div>\n Generating...\n </>\n ) : (\n <>\n <SparklesIcon className=\"w-4 h-4 mr-2\" />\n Generate\n </>\n )}\n </button>\n\n {/* Validation happens automatically after generation */}\n\n <button\n onClick={handleUseQuery}\n disabled={!state.response || !onQueryLoad}\n className=\"px-4 py-2 bg-green-600 text-white text-sm rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed flex items-center\"\n >\n <SuccessIcon className=\"w-4 h-4 mr-2\" />\n Use Query\n </button>\n </div>\n </div>\n )\n\n const getTitle = () => {\n return 'AI Assistant - Generate Query'\n }\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={getTitle()}\n size=\"fullscreen-mobile\"\n >\n {renderQueryStep()}\n </Modal>\n )\n}\n\nexport default AIAssistantModal","// Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>\n// This work is free. You can redistribute it and/or modify it\n// under the terms of the WTFPL, Version 2\n// For more information see LICENSE.txt or http://www.wtfpl.net/\n//\n// For more information, the home page:\n// http://pieroxy.net/blog/pages/lz-string/testing.html\n//\n// LZ-based compression algorithm, version 1.4.5\nvar LZString = (function() {\n\n// private property\nvar f = String.fromCharCode;\nvar keyStrBase64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\nvar keyStrUriSafe = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$\";\nvar baseReverseDic = {};\n\nfunction getBaseValue(alphabet, character) {\n if (!baseReverseDic[alphabet]) {\n baseReverseDic[alphabet] = {};\n for (var i=0 ; i<alphabet.length ; i++) {\n baseReverseDic[alphabet][alphabet.charAt(i)] = i;\n }\n }\n return baseReverseDic[alphabet][character];\n}\n\nvar LZString = {\n compressToBase64 : function (input) {\n if (input == null) return \"\";\n var res = LZString._compress(input, 6, function(a){return keyStrBase64.charAt(a);});\n switch (res.length % 4) { // To produce valid Base64\n default: // When could this happen ?\n case 0 : return res;\n case 1 : return res+\"===\";\n case 2 : return res+\"==\";\n case 3 : return res+\"=\";\n }\n },\n\n decompressFromBase64 : function (input) {\n if (input == null) return \"\";\n if (input == \"\") return null;\n return LZString._decompress(input.length, 32, function(index) { return getBaseValue(keyStrBase64, input.charAt(index)); });\n },\n\n compressToUTF16 : function (input) {\n if (input == null) return \"\";\n return LZString._compress(input, 15, function(a){return f(a+32);}) + \" \";\n },\n\n decompressFromUTF16: function (compressed) {\n if (compressed == null) return \"\";\n if (compressed == \"\") return null;\n return LZString._decompress(compressed.length, 16384, function(index) { return compressed.charCodeAt(index) - 32; });\n },\n\n //compress into uint8array (UCS-2 big endian format)\n compressToUint8Array: function (uncompressed) {\n var compressed = LZString.compress(uncompressed);\n var buf=new Uint8Array(compressed.length*2); // 2 bytes per character\n\n for (var i=0, TotalLen=compressed.length; i<TotalLen; i++) {\n var current_value = compressed.charCodeAt(i);\n buf[i*2] = current_value >>> 8;\n buf[i*2+1] = current_value % 256;\n }\n return buf;\n },\n\n //decompress from uint8array (UCS-2 big endian format)\n decompressFromUint8Array:function (compressed) {\n if (compressed===null || compressed===undefined){\n return LZString.decompress(compressed);\n } else {\n var buf=new Array(compressed.length/2); // 2 bytes per character\n for (var i=0, TotalLen=buf.length; i<TotalLen; i++) {\n buf[i]=compressed[i*2]*256+compressed[i*2+1];\n }\n\n var result = [];\n buf.forEach(function (c) {\n result.push(f(c));\n });\n return LZString.decompress(result.join(''));\n\n }\n\n },\n\n\n //compress into a string that is already URI encoded\n compressToEncodedURIComponent: function (input) {\n if (input == null) return \"\";\n return LZString._compress(input, 6, function(a){return keyStrUriSafe.charAt(a);});\n },\n\n //decompress from an output of compressToEncodedURIComponent\n decompressFromEncodedURIComponent:function (input) {\n if (input == null) return \"\";\n if (input == \"\") return null;\n input = input.replace(/ /g, \"+\");\n return LZString._decompress(input.length, 32, function(index) { return getBaseValue(keyStrUriSafe, input.charAt(index)); });\n },\n\n compress: function (uncompressed) {\n return LZString._compress(uncompressed, 16, function(a){return f(a);});\n },\n _compress: function (uncompressed, bitsPerChar, getCharFromInt) {\n if (uncompressed == null) return \"\";\n var i, value,\n context_dictionary= {},\n context_dictionaryToCreate= {},\n context_c=\"\",\n context_wc=\"\",\n context_w=\"\",\n context_enlargeIn= 2, // Compensate for the first entry which should not count\n context_dictSize= 3,\n context_numBits= 2,\n context_data=[],\n context_data_val=0,\n context_data_position=0,\n ii;\n\n for (ii = 0; ii < uncompressed.length; ii += 1) {\n context_c = uncompressed.charAt(ii);\n if (!Object.prototype.hasOwnProperty.call(context_dictionary,context_c)) {\n context_dictionary[context_c] = context_dictSize++;\n context_dictionaryToCreate[context_c] = true;\n }\n\n context_wc = context_w + context_c;\n if (Object.prototype.hasOwnProperty.call(context_dictionary,context_wc)) {\n context_w = context_wc;\n } else {\n if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate,context_w)) {\n if (context_w.charCodeAt(0)<256) {\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n }\n value = context_w.charCodeAt(0);\n for (i=0 ; i<8 ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n } else {\n value = 1;\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | value;\n if (context_data_position ==bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = 0;\n }\n value = context_w.charCodeAt(0);\n for (i=0 ; i<16 ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n }\n context_enlargeIn--;\n if (context_enlargeIn == 0) {\n context_enlargeIn = Math.pow(2, context_numBits);\n context_numBits++;\n }\n delete context_dictionaryToCreate[context_w];\n } else {\n value = context_dictionary[context_w];\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n\n\n }\n context_enlargeIn--;\n if (context_enlargeIn == 0) {\n context_enlargeIn = Math.pow(2, context_numBits);\n context_numBits++;\n }\n // Add wc to the dictionary.\n context_dictionary[context_wc] = context_dictSize++;\n context_w = String(context_c);\n }\n }\n\n // Output the code for w.\n if (context_w !== \"\") {\n if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate,context_w)) {\n if (context_w.charCodeAt(0)<256) {\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n }\n value = context_w.charCodeAt(0);\n for (i=0 ; i<8 ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n } else {\n value = 1;\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | value;\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = 0;\n }\n value = context_w.charCodeAt(0);\n for (i=0 ; i<16 ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n }\n context_enlargeIn--;\n if (context_enlargeIn == 0) {\n context_enlargeIn = Math.pow(2, context_numBits);\n context_numBits++;\n }\n delete context_dictionaryToCreate[context_w];\n } else {\n value = context_dictionary[context_w];\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n\n\n }\n context_enlargeIn--;\n if (context_enlargeIn == 0) {\n context_enlargeIn = Math.pow(2, context_numBits);\n context_numBits++;\n }\n }\n\n // Mark the end of the stream\n value = 2;\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n\n // Flush the last char\n while (true) {\n context_data_val = (context_data_val << 1);\n if (context_data_position == bitsPerChar-1) {\n context_data.push(getCharFromInt(context_data_val));\n break;\n }\n else context_data_position++;\n }\n return context_data.join('');\n },\n\n decompress: function (compressed) {\n if (compressed == null) return \"\";\n if (compressed == \"\") return null;\n return LZString._decompress(compressed.length, 32768, function(index) { return compressed.charCodeAt(index); });\n },\n\n _decompress: function (length, resetValue, getNextValue) {\n var dictionary = [],\n next,\n enlargeIn = 4,\n dictSize = 4,\n numBits = 3,\n entry = \"\",\n result = [],\n i,\n w,\n bits, resb, maxpower, power,\n c,\n data = {val:getNextValue(0), position:resetValue, index:1};\n\n for (i = 0; i < 3; i += 1) {\n dictionary[i] = i;\n }\n\n bits = 0;\n maxpower = Math.pow(2,2);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n\n switch (next = bits) {\n case 0:\n bits = 0;\n maxpower = Math.pow(2,8);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n c = f(bits);\n break;\n case 1:\n bits = 0;\n maxpower = Math.pow(2,16);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n c = f(bits);\n break;\n case 2:\n return \"\";\n }\n dictionary[3] = c;\n w = c;\n result.push(c);\n while (true) {\n if (data.index > length) {\n return \"\";\n }\n\n bits = 0;\n maxpower = Math.pow(2,numBits);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n\n switch (c = bits) {\n case 0:\n bits = 0;\n maxpower = Math.pow(2,8);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n\n dictionary[dictSize++] = f(bits);\n c = dictSize-1;\n enlargeIn--;\n break;\n case 1:\n bits = 0;\n maxpower = Math.pow(2,16);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n dictionary[dictSize++] = f(bits);\n c = dictSize-1;\n enlargeIn--;\n break;\n case 2:\n return result.join('');\n }\n\n if (enlargeIn == 0) {\n enlargeIn = Math.pow(2, numBits);\n numBits++;\n }\n\n if (dictionary[c]) {\n entry = dictionary[c];\n } else {\n if (c === dictSize) {\n entry = w + w.charAt(0);\n } else {\n return null;\n }\n }\n result.push(entry);\n\n // Add w+entry[0] to the dictionary.\n dictionary[dictSize++] = w + entry.charAt(0);\n enlargeIn--;\n\n w = entry;\n\n if (enlargeIn == 0) {\n enlargeIn = Math.pow(2, numBits);\n numBits++;\n }\n\n }\n }\n};\n return LZString;\n})();\n\nif (typeof define === 'function' && define.amd) {\n define(function () { return LZString; });\n} else if( typeof module !== 'undefined' && module != null ) {\n module.exports = LZString\n} else if( typeof angular !== 'undefined' && angular != null ) {\n angular.module('LZString', [])\n .factory('LZString', function () {\n return LZString;\n });\n}\n","/**\n * Share utilities for QueryBuilder\n *\n * Handles compression, encoding, and URL generation for sharing analysis state.\n * Uses LZ-String for compression which produces URL-safe output.\n */\n\nimport { compressToEncodedURIComponent, decompressFromEncodedURIComponent } from 'lz-string'\nimport type { CubeQuery, ChartType, ChartAxisConfig, ChartDisplayConfig } from '../../types'\n\n/**\n * State that can be shared via URL\n * Query is required, chart config is optional (may be dropped if too large)\n */\nexport interface ShareableState {\n query: CubeQuery\n chartType?: ChartType\n chartConfig?: ChartAxisConfig\n displayConfig?: ChartDisplayConfig\n activeView?: 'table' | 'chart'\n}\n\n/**\n * Result of compression with fallback\n */\nexport interface CompressionResult {\n encoded: string | null\n queryOnly: boolean\n}\n\n// Max safe URL hash length (conservative for browser compatibility)\nconst MAX_HASH_LENGTH = 1800\nconst SHARE_PREFIX = 'share='\n\n/**\n * Compress state to URL-safe encoded string\n */\nexport function compressAndEncode(state: ShareableState): string {\n const json = JSON.stringify(state)\n return compressToEncodedURIComponent(json)\n}\n\n/**\n * Decompress URL-safe encoded string back to state\n * Returns null if decompression or parsing fails\n */\nexport function decodeAndDecompress(encoded: string): ShareableState | null {\n try {\n const json = decompressFromEncodedURIComponent(encoded)\n if (!json) return null\n\n const state = JSON.parse(json) as ShareableState\n\n // Validate required field\n if (!state.query || typeof state.query !== 'object') {\n return null\n }\n\n return state\n } catch {\n return null\n }\n}\n\n/**\n * Check if compressed state fits within URL length limit\n */\nexport function isShareableSize(state: ShareableState): { ok: boolean; size: number; maxSize: number } {\n const encoded = compressAndEncode(state)\n return {\n ok: encoded.length <= MAX_HASH_LENGTH,\n size: encoded.length,\n maxSize: MAX_HASH_LENGTH\n }\n}\n\n/**\n * Compress state with automatic fallback\n * If full state is too large, tries with query only\n * Returns null encoded if even query-only is too large\n */\nexport function compressWithFallback(state: ShareableState): CompressionResult {\n // Try full state first\n const fullEncoded = compressAndEncode(state)\n if (fullEncoded.length <= MAX_HASH_LENGTH) {\n return { encoded: fullEncoded, queryOnly: false }\n }\n\n // Fall back to query only\n const queryOnlyState: ShareableState = { query: state.query }\n const queryOnlyEncoded = compressAndEncode(queryOnlyState)\n\n if (queryOnlyEncoded.length <= MAX_HASH_LENGTH) {\n return { encoded: queryOnlyEncoded, queryOnly: true }\n }\n\n // Even query-only is too large\n return { encoded: null, queryOnly: true }\n}\n\n/**\n * Generate full share URL with compressed state in hash\n */\nexport function generateShareUrl(state: ShareableState): string | null {\n const { encoded } = compressWithFallback(state)\n if (!encoded) return null\n\n return `${window.location.origin}${window.location.pathname}#${SHARE_PREFIX}${encoded}`\n}\n\n/**\n * Parse share hash from current URL\n * Returns encoded string if #share= is present, null otherwise\n */\nexport function parseShareHash(): string | null {\n if (typeof window === 'undefined') return null\n\n const hash = window.location.hash\n if (!hash || !hash.startsWith(`#${SHARE_PREFIX}`)) {\n return null\n }\n\n return hash.slice(SHARE_PREFIX.length + 1) // +1 for the #\n}\n\n/**\n * Clear share hash from URL without page reload\n */\nexport function clearShareHash(): void {\n if (typeof window === 'undefined') return\n\n const url = new URL(window.location.href)\n url.hash = ''\n window.history.replaceState(null, '', url.toString())\n}\n\n/**\n * Get the maximum allowed hash length\n */\nexport function getMaxHashLength(): number {\n return MAX_HASH_LENGTH\n}\n","/**\n * ShareWarningModal Component\n *\n * Displayed when the query is too large to share via URL,\n * even after dropping chart configuration.\n */\n\nimport React from 'react'\nimport Modal from '../Modal'\nimport { getIcon } from '../../icons'\n\nexport interface ShareWarningModalProps {\n isOpen: boolean\n onClose: () => void\n size: number\n maxSize: number\n}\n\nconst ShareWarningModal: React.FC<ShareWarningModalProps> = ({\n isOpen,\n onClose,\n size,\n maxSize\n}) => {\n const percentUsed = Math.min(Math.round((size / maxSize) * 100), 100)\n\n const WarningIcon = getIcon('warning')\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title=\"Query Too Large to Share\"\n size=\"sm\"\n >\n <div className=\"space-y-4\">\n {/* Warning icon and message */}\n <div className=\"flex items-start gap-3\">\n <div className=\"shrink-0 p-2 bg-amber-100 dark:bg-amber-900/30 rounded-full\">\n <WarningIcon className=\"w-5 h-5 text-amber-600 dark:text-amber-400\" />\n </div>\n <div className=\"text-sm text-dc-text-secondary\">\n Your query is too large to fit in a shareable URL. Even after removing chart settings,\n the compressed query exceeds the safe URL length limit.\n </div>\n </div>\n\n {/* Size indicator */}\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-xs text-dc-text-muted\">\n <span>Compressed size</span>\n <span className=\"text-red-600 dark:text-red-400 font-medium\">\n {size.toLocaleString()} / {maxSize.toLocaleString()} chars\n </span>\n </div>\n <div className=\"h-2 bg-dc-surface-secondary rounded-full overflow-hidden\">\n <div\n className=\"h-full bg-red-500 dark:bg-red-400 transition-all duration-300\"\n style={{ width: `${percentUsed}%` }}\n />\n </div>\n </div>\n\n {/* Suggestions */}\n <div className=\"border-t border-dc-border pt-4\">\n <p className=\"text-xs font-medium text-dc-text mb-2\">\n To make your query shareable, try:\n </p>\n <ul className=\"text-xs text-dc-text-secondary space-y-1.5\">\n <li className=\"flex items-start gap-2\">\n <span className=\"text-dc-text-muted\">-</span>\n <span>Remove some filters, especially complex nested filter groups</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <span className=\"text-dc-text-muted\">-</span>\n <span>Reduce the number of dimensions or measures</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <span className=\"text-dc-text-muted\">-</span>\n <span>Simplify date range filters</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <span className=\"text-dc-text-muted\">-</span>\n <span>Use the "Copy Query" button to copy the raw JSON instead</span>\n </li>\n </ul>\n </div>\n\n {/* Close button */}\n <div className=\"flex justify-end pt-2\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-sm font-medium text-white bg-dc-primary hover:bg-dc-primary-hover rounded-md transition-colors\"\n >\n Got it\n </button>\n </div>\n </div>\n </Modal>\n )\n}\n\nexport default ShareWarningModal\n","/**\n * QueryBuilder Component\n * \n * Main component that orchestrates the query building experience.\n * Manages state and coordinates between the meta explorer, query panel, and results panel.\n */\n\nimport { useState, useEffect, useCallback, useRef, forwardRef, useImperativeHandle, useMemo } from 'react'\nimport { getIcon } from '../../icons'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport CubeMetaExplorer from './CubeMetaExplorer'\nimport QueryPanel from './QueryPanel'\nimport ResultsPanel from './ResultsPanel'\nimport SetupPanel from './SetupPanel'\nimport AIAssistantModal from '../AIAssistant/AIAssistantModal'\nimport type {\n QueryBuilderProps,\n QueryBuilderRef,\n QueryBuilderState,\n MetaResponse,\n ValidationResult,\n ApiConfig,\n ShareButtonState\n} from './types'\nimport type { Filter, ChartType, ChartAxisConfig, ChartDisplayConfig } from '../../types'\nimport { createEmptyQuery, hasQueryContent, cleanQuery, cleanQueryForServer, cleanupFilters, transformQueryForUI } from './utils'\nimport { parseShareHash, clearShareHash, decodeAndDecompress, compressWithFallback, getMaxHashLength, type ShareableState } from './shareUtils'\nimport ShareWarningModal from './ShareWarningModal'\n\nconst STORAGE_KEY = 'drizzle-cube-query-builder-state'\nconst API_CONFIG_STORAGE_KEY = 'drizzle-cube-api-config'\n\nconst QueryBuilder = forwardRef<QueryBuilderRef, QueryBuilderProps>(({\n className = '',\n initialQuery,\n disableLocalStorage = false,\n hideSettings = false,\n enableSharing = false,\n onShare\n}, ref) => {\n // Get cube client, update function, and features from context\n const { cubeApi, updateApiConfig, features } = useCubeContext()\n \n // Load initial API configuration from localStorage\n const getInitialApiConfig = (): ApiConfig => {\n if (!disableLocalStorage) {\n try {\n const saved = localStorage.getItem(API_CONFIG_STORAGE_KEY)\n if (saved) {\n return JSON.parse(saved)\n }\n } catch (error) {\n // Failed to load API config from localStorage\n }\n }\n return {\n baseApiUrl: '/cubejs-api/v1',\n apiToken: ''\n }\n }\n\n // Load initial state from localStorage if available, or use provided initialQuery\n const getInitialState = (): QueryBuilderState => {\n // If initialQuery is provided, use it instead of localStorage\n if (initialQuery) {\n return {\n query: transformQueryForUI(initialQuery),\n schema: null,\n schemaStatus: 'idle',\n schemaError: null,\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }\n }\n\n // Only check localStorage if not disabled\n if (!disableLocalStorage) {\n try {\n const saved = localStorage.getItem(STORAGE_KEY)\n if (saved) {\n const parsedState = JSON.parse(saved)\n return {\n query: transformQueryForUI(parsedState.query) || createEmptyQuery(),\n schema: null, // Schema is always loaded fresh\n schemaStatus: 'idle', // Reset schema status\n schemaError: null,\n validationStatus: 'idle', // Reset validation status\n validationError: null,\n validationSql: null,\n executionStatus: 'idle', // Reset execution status\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }\n }\n } catch (error) {\n // Failed to load query from localStorage\n }\n }\n \n return {\n query: createEmptyQuery(),\n schema: null,\n schemaStatus: 'idle',\n schemaError: null,\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }\n }\n\n const [state, setState] = useState<QueryBuilderState>(getInitialState())\n \n // Separate state for display limit (doesn't affect the actual query object)\n const [displayLimit, setDisplayLimit] = useState<number>(10)\n\n // Load initial chart configuration from localStorage\n const getInitialChartState = () => {\n if (!disableLocalStorage) {\n try {\n const saved = localStorage.getItem(STORAGE_KEY)\n if (saved) {\n const parsed = JSON.parse(saved)\n return {\n chartType: parsed.chartType || 'table',\n chartConfig: parsed.chartConfig || {},\n displayConfig: parsed.displayConfig || { showLegend: true, showGrid: true, showTooltip: true },\n activeView: parsed.activeView || 'table'\n }\n }\n } catch (error) {\n // Failed to load chart config from localStorage\n }\n }\n return {\n chartType: 'table' as ChartType,\n chartConfig: {} as ChartAxisConfig,\n displayConfig: { showLegend: true, showGrid: true, showTooltip: true } as ChartDisplayConfig,\n activeView: 'table' as 'table' | 'chart'\n }\n }\n\n // Chart visualization state\n const initialChartState = getInitialChartState()\n const [chartType, setChartType] = useState<ChartType>(initialChartState.chartType)\n const [chartConfig, setChartConfig] = useState<ChartAxisConfig>(initialChartState.chartConfig)\n const [displayConfig, setDisplayConfig] = useState<ChartDisplayConfig>(initialChartState.displayConfig)\n const [activeView, setActiveView] = useState<'table' | 'chart'>(initialChartState.activeView)\n\n // API configuration state\n const [apiConfig, setApiConfig] = useState<ApiConfig>(getInitialApiConfig())\n const [showSetupPanel, setShowSetupPanel] = useState(false)\n const [showSchemaMobile, setShowSchemaMobile] = useState(false)\n const [schemaViewType, setSchemaViewType] = useState<'tree' | 'diagram'>('tree')\n \n // AI Assistant modal state\n const [showAIAssistant, setShowAIAssistant] = useState(false)\n\n // Share functionality state\n const [shareButtonState, setShareButtonState] = useState<ShareButtonState>('idle')\n const [showShareWarning, setShowShareWarning] = useState(false)\n const [shareWarningData, setShareWarningData] = useState({ size: 0, maxSize: 0 })\n const [isViewingShared, setIsViewingShared] = useState(false)\n\n // Update query when initialQuery prop changes (for modal usage)\n useEffect(() => {\n if (initialQuery && JSON.stringify(initialQuery) !== JSON.stringify(state.query)) {\n setState(prev => ({\n ...prev,\n query: transformQueryForUI(initialQuery),\n schemaStatus: 'idle',\n schemaError: null,\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }))\n }\n }, [initialQuery])\n\n // Track the last validated query to avoid resetting validation on unrelated updates\n const lastValidatedQueryRef = useRef<string>('')\n\n // Note: API configuration is kept for backward compatibility but not used \n // since we now use the CubeClient from context\n\n // Store the full validation result for access via ref\n const [fullValidationResult, setFullValidationResult] = useState<ValidationResult | null>(null)\n\n // Compute available fields for chart configuration from validation result\n const availableFields = useMemo(() => {\n if (!fullValidationResult?.pivotQuery?.query) return null\n return {\n dimensions: fullValidationResult.pivotQuery.query.dimensions || [],\n timeDimensions: fullValidationResult.pivotQuery.query.timeDimensions?.map((td: { dimension: string }) => td.dimension) || [],\n measures: fullValidationResult.pivotQuery.query.measures || []\n }\n }, [fullValidationResult])\n\n // Expose query and validation state to parent via ref (only called when Apply is clicked)\n useImperativeHandle(ref, () => ({\n getCurrentQuery: () => cleanQueryForServer(state.query),\n getValidationState: () => ({\n status: state.validationStatus,\n result: state.validationStatus === 'valid' ? {\n valid: true,\n sql: state.validationSql || undefined\n } : state.validationStatus === 'invalid' ? {\n valid: false,\n error: state.validationError || undefined\n } : undefined\n }),\n getValidationResult: () => fullValidationResult\n }), [state.query, state.validationStatus, state.validationError, state.validationSql, fullValidationResult])\n\n // Load schema on mount and when API config changes\n useEffect(() => {\n const loadSchema = async () => {\n setState(prev => ({\n ...prev,\n schemaStatus: 'loading',\n schemaError: null\n }))\n\n try {\n const metaResponse: MetaResponse = await cubeApi.meta()\n setState(prev => ({\n ...prev,\n schema: metaResponse,\n schemaStatus: 'success',\n schemaError: null\n }))\n } catch (error) {\n // Failed to load schema\n const errorMessage = error instanceof Error ? error.message : 'Failed to load schema'\n setState(prev => ({\n ...prev,\n schema: null,\n schemaStatus: 'error',\n schemaError: errorMessage\n }))\n }\n }\n\n loadSchema()\n }, [apiConfig.baseApiUrl, apiConfig.apiToken])\n\n // Save query and chart config to localStorage whenever they change (if not disabled)\n useEffect(() => {\n if (!disableLocalStorage) {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify({\n query: state.query,\n chartType,\n chartConfig,\n displayConfig,\n activeView\n }))\n } catch (error) {\n // Failed to save state to localStorage\n }\n }\n }, [state.query, chartType, chartConfig, displayConfig, activeView, disableLocalStorage])\n\n // Save API config to localStorage whenever it changes (if not disabled)\n useEffect(() => {\n if (!disableLocalStorage) {\n try {\n localStorage.setItem(API_CONFIG_STORAGE_KEY, JSON.stringify(apiConfig))\n } catch (error) {\n // Failed to save API config to localStorage\n }\n }\n }, [apiConfig, disableLocalStorage])\n\n // Track if we need to auto-run after loading shared analysis\n const pendingSharedExecution = useRef(false)\n\n // Parse URL hash for shared analysis on mount (when sharing is enabled)\n useEffect(() => {\n if (!enableSharing) return\n\n const encoded = parseShareHash()\n if (!encoded) return\n\n const decoded = decodeAndDecompress(encoded)\n if (decoded) {\n // Apply query (required)\n setState(prev => ({\n ...prev,\n query: transformQueryForUI(decoded.query),\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }))\n\n // Apply chart config if present, otherwise use defaults\n if (decoded.chartType) setChartType(decoded.chartType)\n if (decoded.chartConfig) setChartConfig(decoded.chartConfig)\n if (decoded.displayConfig) setDisplayConfig(decoded.displayConfig)\n if (decoded.activeView) setActiveView(decoded.activeView)\n\n setIsViewingShared(true)\n pendingSharedExecution.current = true\n }\n\n // Clear hash from URL\n clearShareHash()\n }, [enableSharing])\n\n // Auto re-run query when displayLimit or activeView changes\n useEffect(() => {\n if (state.executionStatus === 'success' && hasQueryContent(state.query) && state.validationStatus === 'valid') {\n handleExecuteQuery()\n }\n }, [displayLimit, activeView]) // Re-run on limit or view change\n\n\n const updateQuery = useCallback((updater: (prev: typeof state.query) => typeof state.query) => {\n setState(prev => {\n const newQuery = updater(prev.query)\n \n // Clean up filters to remove any that reference fields no longer in the query\n const cleanedQuery = {\n ...newQuery,\n filters: newQuery.filters ? cleanupFilters(newQuery.filters, newQuery) : undefined\n }\n \n const queryChanged = JSON.stringify(cleanedQuery) !== JSON.stringify(prev.query)\n \n return {\n ...prev,\n query: cleanedQuery,\n // Only reset validation if query actually changed\n validationStatus: queryChanged ? 'idle' : prev.validationStatus,\n validationError: queryChanged ? null : prev.validationError,\n validationSql: queryChanged ? null : prev.validationSql,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }\n })\n }, [])\n\n const handleFieldSelect = useCallback((fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n updateQuery(prev => {\n const newQuery = { ...prev }\n \n switch (fieldType) {\n case 'measures':\n // Only add if not already present\n if (!(prev.measures || []).includes(fieldName)) {\n newQuery.measures = [...(prev.measures || []), fieldName]\n }\n break\n case 'dimensions':\n // Only add if not already present\n if (!(prev.dimensions || []).includes(fieldName)) {\n newQuery.dimensions = [...(prev.dimensions || []), fieldName]\n }\n break\n case 'timeDimensions':\n // Only add if not already present\n if (!(prev.timeDimensions || []).some(td => td.dimension === fieldName)) {\n newQuery.timeDimensions = [...(prev.timeDimensions || []), { \n dimension: fieldName, \n granularity: 'month' \n }]\n }\n break\n }\n \n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleFieldDeselect = useCallback((fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n updateQuery(prev => {\n const newQuery = { ...prev }\n \n switch (fieldType) {\n case 'measures':\n newQuery.measures = (prev.measures || []).filter(m => m !== fieldName)\n break\n case 'dimensions':\n newQuery.dimensions = (prev.dimensions || []).filter(d => d !== fieldName)\n break\n case 'timeDimensions':\n newQuery.timeDimensions = (prev.timeDimensions || []).filter(td => td.dimension !== fieldName)\n break\n }\n \n // Clean up order if field was sorted\n if (newQuery.order && newQuery.order[fieldName]) {\n const newOrder = { ...newQuery.order }\n delete newOrder[fieldName]\n newQuery.order = Object.keys(newOrder).length > 0 ? newOrder : undefined\n }\n \n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleTimeDimensionGranularityChange = useCallback((dimensionName: string, granularity: string) => {\n updateQuery(prev => {\n const newQuery = {\n ...prev,\n timeDimensions: (prev.timeDimensions || []).map(td => \n td.dimension === dimensionName \n ? { ...td, granularity }\n : td\n )\n }\n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleFiltersChange = useCallback((filters: Filter[]) => {\n updateQuery(prev => {\n const newQuery = {\n ...prev,\n filters\n }\n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleDateRangeChange = useCallback((timeDimension: string, dateRange: string | string[]) => {\n updateQuery(prev => {\n const newQuery = {\n ...prev,\n timeDimensions: (prev.timeDimensions || []).map(td => \n td.dimension === timeDimension \n ? { ...td, dateRange }\n : td\n )\n }\n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleDateRangeRemove = useCallback((timeDimension: string) => {\n updateQuery(prev => {\n const newQuery = {\n ...prev,\n timeDimensions: (prev.timeDimensions || []).map(td => \n td.dimension === timeDimension \n ? { ...td, dateRange: undefined }\n : td\n )\n }\n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleOrderChange = useCallback((fieldName: string, direction: 'asc' | 'desc' | null) => {\n updateQuery(prev => {\n const newOrder = { ...(prev.order || {}) }\n \n if (direction === null) {\n delete newOrder[fieldName]\n } else {\n newOrder[fieldName] = direction\n }\n \n const newQuery = {\n ...prev,\n order: Object.keys(newOrder).length > 0 ? newOrder : undefined\n }\n \n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleValidateQuery = useCallback(async () => {\n if (!hasQueryContent(state.query)) return\n\n // Store the query being validated (cleaned and server-formatted)\n const queryToValidate = cleanQueryForServer(state.query)\n const queryStr = JSON.stringify(queryToValidate)\n \n\n setState(prev => ({\n ...prev,\n validationStatus: 'validating',\n validationError: null,\n validationSql: null\n }))\n\n try {\n const result: ValidationResult = await cubeApi.dryRun(queryToValidate)\n \n // Store the full validation result for parent access\n setFullValidationResult(result)\n \n // Check if validation is successful:\n // 1. Must have queryType (always present in successful Cube.js responses)\n // 2. Must not have an error\n // 3. For compatibility, also check result.valid if present\n const isValid = !result.error && result.queryType && (result.valid !== false)\n \n // Store the validated query to prevent reset\n if (isValid) {\n lastValidatedQueryRef.current = queryStr\n }\n \n setState(prev => {\n return {\n ...prev,\n validationStatus: isValid ? 'valid' : 'invalid',\n validationError: result.error || null,\n validationSql: result.sql || null\n }\n })\n } catch (error) {\n // Validation error\n setFullValidationResult(null)\n setState(prev => ({\n ...prev,\n validationStatus: 'invalid',\n validationError: error instanceof Error ? error.message : 'Network error during validation',\n validationSql: null\n }))\n }\n }, [state.query, cubeApi])\n\n // Auto re-validate query when query changes (with 1s debounce)\n useEffect(() => {\n // Only auto-validate if query has content and validation was previously cleared\n if (!hasQueryContent(state.query) || state.validationStatus !== 'idle') {\n return\n }\n\n const debounceTimer = setTimeout(() => {\n handleValidateQuery()\n }, 200) // 200ms debounce - fast but prevents excessive API calls\n\n return () => clearTimeout(debounceTimer)\n }, [state.query, state.validationStatus, handleValidateQuery]) // Trigger when query changes and validation status is idle\n\n const handleExecuteQuery = useCallback(async () => {\n if (!hasQueryContent(state.query) || state.validationStatus !== 'valid') return\n\n setState(prev => ({\n ...prev,\n executionStatus: 'loading',\n executionResults: null,\n executionError: null,\n totalRowCountStatus: 'loading'\n }))\n\n try {\n // Run both queries in parallel: one with limit and one without for total count\n // Chart view: no limit (show all data for visualization)\n // Table view: apply displayLimit for pagination\n const cleanedQuery = cleanQueryForServer(state.query)\n const effectiveLimit = activeView === 'chart' ? undefined : displayLimit\n\n const [limitedResultSet, totalResultSet] = await Promise.all([\n cubeApi.load(effectiveLimit ? { ...cleanedQuery, limit: effectiveLimit } : cleanedQuery),\n cubeApi.load(cleanedQuery) // No limit for total count\n ])\n\n const limitedData = limitedResultSet.tablePivot()\n const totalData = totalResultSet.tablePivot()\n const totalCount = totalData.length\n\n setState(prev => ({\n ...prev,\n executionStatus: 'success',\n executionResults: limitedData,\n executionError: null,\n totalRowCount: totalCount,\n totalRowCountStatus: 'success'\n }))\n } catch (error) {\n // Query execution error\n setState(prev => ({\n ...prev,\n executionStatus: 'error',\n executionResults: null,\n executionError: error instanceof Error ? error.message : 'Query execution failed',\n totalRowCount: null,\n totalRowCountStatus: 'error'\n }))\n }\n }, [state.query, state.validationStatus, cubeApi, displayLimit, activeView])\n\n // Auto-execute query after loading from shared link once validation succeeds\n useEffect(() => {\n if (pendingSharedExecution.current && state.validationStatus === 'valid' && state.executionStatus === 'idle') {\n pendingSharedExecution.current = false\n handleExecuteQuery()\n }\n }, [state.validationStatus, state.executionStatus, handleExecuteQuery])\n\n const handleClearQuery = useCallback(() => {\n setState(prev => ({\n ...prev,\n query: createEmptyQuery(),\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }))\n }, [])\n\n const handleShare = useCallback(async () => {\n if (!enableSharing) return\n\n const shareableState: ShareableState = {\n query: cleanQueryForServer(state.query),\n chartType,\n chartConfig,\n displayConfig,\n activeView\n }\n\n // Try full state first, fall back to query-only if too large\n const { encoded, queryOnly } = compressWithFallback(shareableState)\n\n // If even query-only is too large, show warning modal\n if (!encoded) {\n const queryOnlyState: ShareableState = { query: shareableState.query }\n const queryOnlySize = JSON.stringify(queryOnlyState).length\n setShareWarningData({ size: queryOnlySize, maxSize: getMaxHashLength() })\n setShowShareWarning(true)\n return\n }\n\n const url = `${window.location.origin}${window.location.pathname}#share=${encoded}`\n\n try {\n await navigator.clipboard.writeText(url)\n } catch {\n // Fallback for older browsers\n const textArea = document.createElement('textarea')\n textArea.value = url\n document.body.appendChild(textArea)\n textArea.select()\n document.execCommand('copy')\n document.body.removeChild(textArea)\n }\n\n // Update button state\n setShareButtonState(queryOnly ? 'copied-no-chart' : 'copied')\n\n // Call onShare callback if provided\n onShare?.(url)\n\n // Reset button state after 2 seconds\n setTimeout(() => {\n setShareButtonState('idle')\n }, 2000)\n }, [enableSharing, state.query, chartType, chartConfig, displayConfig, activeView, onShare])\n\n const handleApiConfigChange = useCallback((newConfig: ApiConfig) => {\n setApiConfig(newConfig)\n \n // Update the CubeProvider's client with new configuration\n updateApiConfig(\n { apiUrl: newConfig.baseApiUrl },\n newConfig.apiToken || undefined\n )\n \n // Reset all state when API config changes\n setState(prev => ({\n ...prev,\n schema: null,\n schemaStatus: 'idle',\n schemaError: null,\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }))\n }, [updateApiConfig])\n\n const handleResetApiConfig = useCallback(() => {\n const defaultConfig = {\n baseApiUrl: '/cubejs-api/v1',\n apiToken: ''\n }\n setApiConfig(defaultConfig)\n \n // Update the CubeProvider's client with reset configuration\n updateApiConfig(\n { apiUrl: defaultConfig.baseApiUrl },\n undefined\n )\n }, [updateApiConfig])\n\n const handleRetrySchema = useCallback(async () => {\n setState(prev => ({\n ...prev,\n schemaStatus: 'loading',\n schemaError: null\n }))\n\n try {\n const metaResponse: MetaResponse = await cubeApi.meta()\n setState(prev => ({\n ...prev,\n schema: metaResponse,\n schemaStatus: 'success',\n schemaError: null\n }))\n } catch (error) {\n // Failed to retry schema\n const errorMessage = error instanceof Error ? error.message : 'Failed to load schema'\n setState(prev => ({\n ...prev,\n schema: null,\n schemaStatus: 'error',\n schemaError: errorMessage\n }))\n }\n }, [cubeApi])\n\n const selectedFields = {\n measures: state.query.measures || [],\n dimensions: state.query.dimensions || [],\n timeDimensions: (state.query.timeDimensions || []).map(td => td.dimension)\n }\n\n const MenuIcon = getIcon('menu')\n const CloseIcon = getIcon('close')\n\n return (\n <div className={`h-full flex flex-col ${className}`} style={{ minHeight: '100%' }}>\n {/* Setup Panel - only show when not in modal and not hidden */}\n {!hideSettings && (\n <div className=\"shrink-0 p-4 pb-0\">\n <SetupPanel\n isOpen={showSetupPanel}\n onToggle={() => setShowSetupPanel(!showSetupPanel)}\n config={apiConfig}\n onConfigChange={handleApiConfigChange}\n onReset={handleResetApiConfig}\n />\n </div>\n )}\n\n {/* Mobile Schema Toggle Button */}\n <div className=\"md:hidden shrink-0 px-4 pb-2\">\n <button\n onClick={() => setShowSchemaMobile(!showSchemaMobile)}\n className=\"flex items-center gap-2 px-3 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface-secondary hover:bg-dc-surface-hover rounded-md transition-colors\"\n >\n {showSchemaMobile ? (\n <><CloseIcon className=\"w-4 h-4\" /> Hide Schema</>\n ) : (\n <><MenuIcon className=\"w-4 h-4\" /> Show Schema</>\n )}\n </button>\n </div>\n\n {/* Mobile Schema Panel Overlay */}\n {showSchemaMobile && (\n <div className=\"md:hidden fixed inset-0 z-50 bg-black bg-opacity-50 flex\">\n <div className=\"w-full max-w-md sm:max-w-lg bg-dc-surface h-full overflow-y-auto\">\n <div className=\"p-4 border-b border-dc-border\">\n <button\n onClick={() => setShowSchemaMobile(false)}\n className=\"flex items-center gap-2 px-3 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface-secondary hover:bg-dc-surface-hover rounded-md transition-colors\"\n >\n <CloseIcon className=\"w-4 h-4\" /> Close Schema\n </button>\n </div>\n <div className=\"p-4\">\n <CubeMetaExplorer\n schema={state.schema}\n schemaStatus={state.schemaStatus}\n schemaError={state.schemaError}\n selectedFields={selectedFields}\n onFieldSelect={(field, type) => {\n handleFieldSelect(field, type)\n setShowSchemaMobile(false)\n }}\n onFieldDeselect={handleFieldDeselect}\n onRetrySchema={handleRetrySchema}\n onOpenSettings={!hideSettings ? () => setShowSetupPanel(true) : undefined}\n onExpandSchema={(expanded) => {\n if (expanded) setShowSchemaMobile(false)\n }}\n />\n </div>\n </div>\n <div className=\"flex-1\" onClick={() => setShowSchemaMobile(false)}></div>\n </div>\n )}\n\n <div className=\"flex-1 flex flex-col md:flex-row gap-4 p-4 min-h-0\" style={{ paddingTop: hideSettings ? '1rem' : '0rem' }}>\n {/* Schema Explorer with dynamic width based on view type */}\n <div className={`hidden md:flex shrink-0 flex-col min-w-0 ${schemaViewType === 'diagram' ? 'w-full' : 'md:w-1/3 max-w-[500px]'}`}>\n <CubeMetaExplorer\n schema={state.schema}\n schemaStatus={state.schemaStatus}\n schemaError={state.schemaError}\n selectedFields={selectedFields}\n onFieldSelect={handleFieldSelect}\n onFieldDeselect={handleFieldDeselect}\n onRetrySchema={handleRetrySchema}\n onOpenSettings={!hideSettings ? () => setShowSetupPanel(true) : undefined}\n onExpandSchema={undefined} // No expand/collapse needed\n onViewTypeChange={setSchemaViewType}\n isExpanded={false} // Always false, handled by tab switching\n />\n </div>\n\n {/* Main Content - Query Builder + Results (hide when diagram is selected) */}\n {schemaViewType === 'tree' && (\n <div className=\"flex-1 flex flex-col gap-4 min-w-0 min-h-0\">\n {/* Query Builder */}\n <div className=\"shrink-0\">\n <QueryPanel\n query={state.query}\n schema={state.schema}\n validationStatus={state.validationStatus}\n validationError={state.validationError}\n validationSql={state.validationSql}\n validationAnalysis={fullValidationResult?.analysis}\n onValidate={handleValidateQuery}\n onExecute={handleExecuteQuery}\n onRemoveField={handleFieldDeselect}\n onTimeDimensionGranularityChange={handleTimeDimensionGranularityChange}\n onFiltersChange={handleFiltersChange}\n onDateRangeChange={handleDateRangeChange}\n onDateRangeRemove={handleDateRangeRemove}\n onOrderChange={handleOrderChange}\n onClearQuery={handleClearQuery}\n showSettings={!hideSettings}\n onSettingsClick={() => setShowSetupPanel(!showSetupPanel)}\n onAIAssistantClick={features?.enableAI !== false ? () => setShowAIAssistant(true) : undefined}\n onShareClick={enableSharing && hasQueryContent(state.query) ? handleShare : undefined}\n shareButtonState={shareButtonState}\n isViewingShared={isViewingShared}\n />\n </div>\n\n {/* Results Panel */}\n <div className={`${state.executionStatus === 'idle' ? 'shrink-0 h-48' : 'flex-1 min-h-0'}`}>\n <ResultsPanel\n executionStatus={state.executionStatus}\n executionResults={state.executionResults}\n executionError={state.executionError}\n query={state.query}\n displayLimit={displayLimit}\n onDisplayLimitChange={setDisplayLimit}\n totalRowCount={state.totalRowCount}\n totalRowCountStatus={state.totalRowCountStatus}\n // Chart visualization props\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n availableFields={availableFields}\n onChartTypeChange={setChartType}\n onChartConfigChange={setChartConfig}\n onDisplayConfigChange={setDisplayConfig}\n // View state props\n activeView={activeView}\n onActiveViewChange={setActiveView}\n />\n </div>\n </div>\n )}\n </div>\n \n {/* AI Assistant Modal - only render if AI is enabled */}\n {features?.enableAI !== false && (\n <AIAssistantModal\n isOpen={showAIAssistant}\n onClose={() => setShowAIAssistant(false)}\n schema={state.schema}\n aiEndpoint={features?.aiEndpoint}\n onQueryLoad={(query) => {\n // Update the query in the builder\n setState(prev => ({\n ...prev,\n query: transformQueryForUI(query),\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }))\n \n // Auto-validate the loaded query after a short delay\n setTimeout(async () => {\n // We need to access handleValidateQuery through a ref or recreate the validation logic\n // For now, let's trigger validation by updating the state to force a validation\n const queryToValidate = cleanQueryForServer(transformQueryForUI(query))\n \n try {\n const result = await cubeApi.dryRun(queryToValidate)\n const isValid = !result.error && result.queryType && (result.valid !== false)\n \n setState(prev => ({\n ...prev,\n validationStatus: isValid ? 'valid' : 'invalid',\n validationError: result.error || null,\n validationSql: result.sql || null\n }))\n \n setFullValidationResult(result)\n } catch (error) {\n // Auto-validation error\n setState(prev => ({\n ...prev,\n validationStatus: 'invalid',\n validationError: error instanceof Error ? error.message : 'Validation failed',\n validationSql: null\n }))\n setFullValidationResult(null)\n }\n }, 200)\n }}\n />\n )}\n\n {/* Share Warning Modal - shown when query is too large to share */}\n <ShareWarningModal\n isOpen={showShareWarning}\n onClose={() => setShowShareWarning(false)}\n size={shareWarningData.size}\n maxSize={shareWarningData.maxSize}\n />\n\n </div>\n )\n})\n\nQueryBuilder.displayName = 'QueryBuilder'\n\nexport default QueryBuilder","import React, { useState, useEffect, useRef } from 'react'\nimport Modal from './Modal'\nimport QueryBuilder from './QueryBuilder'\nimport ChartConfigPanel from './ChartConfigPanel'\nimport ChartTypeSelector from './ChartTypeSelector'\nimport { useCubeContext } from '../providers/CubeProvider'\nimport { chartConfigRegistry } from '../charts/chartConfigRegistry'\nimport { getChartConfig } from '../charts/chartConfigs'\nimport type { PortletConfig, ChartAxisConfig, ChartDisplayConfig, ChartType, ColorPalette } from '../types'\n\ninterface PortletEditModalProps {\n isOpen: boolean\n onClose: () => void\n onSave: (portlet: PortletConfig | Omit<PortletConfig, 'id' | 'x' | 'y'>) => void\n portlet?: PortletConfig | null\n title: string\n submitText: string\n colorPalette?: ColorPalette\n}\n\n\nconst SAMPLE_QUERIES = [\n {\n name: 'Employee Count by Department',\n query: JSON.stringify({\n \"measures\": [\"Employees.count\"],\n \"dimensions\": [\"Departments.name\"],\n \"order\": { \"Employees.count\": \"desc\" }\n }, null, 2)\n },\n {\n name: 'Employee Hiring Trends',\n query: JSON.stringify({\n \"measures\": [\"Employees.count\"],\n \"timeDimensions\": [{\n \"dimension\": \"Employees.createdAt\",\n \"granularity\": \"month\"\n }],\n \"order\": { \"Employees.createdAt\": \"asc\" }\n }, null, 2)\n },\n {\n name: 'Department Budget Analysis',\n query: JSON.stringify({\n \"measures\": [\"Departments.totalBudget\", \"Departments.avgBudget\"],\n \"dimensions\": [\"Departments.name\"],\n \"order\": { \"Departments.totalBudget\": \"desc\" }\n }, null, 2)\n },\n {\n name: 'Daily Productivity Trends',\n query: JSON.stringify({\n \"measures\": [\"Productivity.avgLinesOfCode\", \"Productivity.totalPullRequests\"],\n \"timeDimensions\": [{\n \"dimension\": \"Productivity.date\",\n \"granularity\": \"day\"\n }],\n \"order\": { \"Productivity.date\": \"asc\" }\n }, null, 2)\n },\n {\n name: 'Happiness by Department',\n query: JSON.stringify({\n \"measures\": [\"Productivity.avgHappinessIndex\", \"Productivity.workingDaysCount\"],\n \"dimensions\": [\"Departments.name\"],\n \"order\": { \"Productivity.avgHappinessIndex\": \"desc\" }\n }, null, 2)\n },\n {\n name: 'Employee Salary Overview',\n query: JSON.stringify({\n \"measures\": [\"Employees.count\", \"Employees.avgSalary\", \"Employees.totalSalary\"],\n \"dimensions\": [\"Employees.isActive\"],\n \"order\": { \"Employees.avgSalary\": \"desc\" }\n }, null, 2)\n }\n]\n\nexport default function PortletEditModal({\n isOpen,\n onClose,\n onSave,\n portlet,\n title,\n submitText,\n colorPalette\n}: PortletEditModalProps) {\n // Get cube client from context\n const { cubeApi } = useCubeContext()\n const [formTitle, setFormTitle] = useState('')\n const [query, setQuery] = useState('')\n const [chartType, setChartType] = useState<ChartType>('bar')\n const [dashboardFilterMapping, setDashboardFilterMapping] = useState<string[]>([])\n const [isValidating, setIsValidating] = useState(false)\n const [validationResult, setValidationResult] = useState<{ isValid: boolean; message: string } | null>(null)\n const [lastValidatedQuery, setLastValidatedQuery] = useState<string>('')\n const [dryRunData, setDryRunData] = useState<any>(null)\n const [chartConfig, setChartConfig] = useState<ChartAxisConfig>({ xAxis: [], yAxis: [], series: [] })\n const [displayConfig, setDisplayConfig] = useState<ChartDisplayConfig>({ showLegend: true, showGrid: true, showTooltip: true, stacked: false })\n const [showQueryBuilder, setShowQueryBuilder] = useState(false)\n const [queryBuilderInitialQuery, setQueryBuilderInitialQuery] = useState<any>(null)\n const queryBuilderRef = useRef<any>(null)\n\n // Check if current chart type skips queries\n const chartTypeConfig = getChartConfig(chartType, chartConfigRegistry)\n const shouldSkipQuery = chartTypeConfig.skipQuery === true\n\n // Validation only - no automatic chart config changes\n const autoPopulateChartConfig = (_result: any) => {\n // Do nothing - let the chart configuration panel handle all axis assignments manually\n // This preserves any existing user configuration and doesn't auto-assign fields\n }\n \n // Sensible defaults: slightly larger than 1/3 width with good aspect ratio\n const defaultWidth = 5\n const defaultHeight = 4\n\n\n // Initialize form values when modal opens or portlet changes\n useEffect(() => {\n if (isOpen) {\n if (portlet) {\n // Edit mode - populate with existing data\n setFormTitle(portlet.title)\n const formattedQuery = (() => {\n try {\n return JSON.stringify(JSON.parse(portlet.query), null, 2)\n } catch {\n return portlet.query\n }\n })()\n setQuery(formattedQuery)\n setChartType(portlet.chartType)\n setChartConfig(portlet.chartConfig || { xAxis: [], yAxis: [], series: [] })\n setDisplayConfig(portlet.displayConfig || {})\n setDashboardFilterMapping(portlet.dashboardFilterMapping || [])\n setLastValidatedQuery(formattedQuery)\n setValidationResult({ isValid: true, message: 'Loaded query (assumed valid)' })\n setDryRunData(null)\n\n // Auto-run dry-run validation for edit mode to enable chart configuration (skip for skipQuery charts)\n if (!shouldSkipQuery) {\n setTimeout(() => {\n runDryRunValidation(formattedQuery, true, true)\n }, 100)\n }\n } else {\n // Create mode - clear form\n setFormTitle('')\n setQuery('')\n setChartType('bar')\n setChartConfig({ xAxis: [], yAxis: [], series: [] })\n setDisplayConfig({ showLegend: true, showGrid: true, showTooltip: true, stacked: false })\n setDashboardFilterMapping([])\n setLastValidatedQuery('')\n setValidationResult(null)\n setDryRunData(null)\n }\n setIsValidating(false)\n }\n }, [isOpen, portlet])\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault()\n \n // For skipQuery charts, only validate title\n if (shouldSkipQuery) {\n if (!formTitle.trim()) {\n return\n }\n } else {\n // For normal charts, validate both title and query\n if (!formTitle.trim() || !query.trim()) {\n return\n }\n\n // Require validation before saving only if query has changed\n if (hasQueryChanged || (lastValidatedQuery === '' && query.trim() !== '')) {\n alert('Please validate your query before saving.')\n return\n }\n\n // Validate JSON\n try {\n JSON.parse(query)\n } catch (e) {\n alert('Invalid JSON in query. Please check your syntax.')\n return\n }\n }\n\n // Prepare query - use minimal query for skipQuery charts\n const queryToSave = shouldSkipQuery ? '{\"measures\":[]}' : query.trim()\n\n if (portlet) {\n // Edit mode - return full portlet config\n onSave({\n ...portlet,\n title: formTitle.trim(),\n query: queryToSave,\n chartType,\n chartConfig: Object.keys(chartConfig).length > 0 ? chartConfig : undefined,\n displayConfig: displayConfig,\n dashboardFilterMapping: dashboardFilterMapping.length > 0 ? dashboardFilterMapping : undefined,\n w: portlet.w || defaultWidth,\n h: portlet.h || defaultHeight\n })\n } else {\n // Create mode - return partial config\n onSave({\n title: formTitle.trim(),\n query: queryToSave,\n chartType,\n chartConfig: Object.keys(chartConfig).length > 0 ? chartConfig : undefined,\n displayConfig: displayConfig,\n dashboardFilterMapping: dashboardFilterMapping.length > 0 ? dashboardFilterMapping : undefined,\n w: defaultWidth,\n h: defaultHeight\n })\n }\n }\n\n const handleSampleQuery = (sampleQuery: string) => {\n setQuery(sampleQuery)\n setValidationResult(null)\n setLastValidatedQuery('')\n setDryRunData(null)\n // Sample queries always clear chart config since they're completely different\n setChartConfig({ xAxis: [], yAxis: [], series: [] })\n }\n\n const handleQueryChange = (value: string) => {\n setQuery(value)\n setValidationResult(null)\n setDryRunData(null)\n // Only clear chart config for new portlets, preserve existing config for edits\n if (!portlet) {\n setChartConfig({ xAxis: [], yAxis: [], series: [] })\n }\n }\n\n const runDryRunValidation = async (queryToValidate: string, silent = false, isEditModeLoad = false) => {\n if (!queryToValidate.trim()) {\n if (!silent) {\n setValidationResult({ isValid: false, message: 'Query cannot be empty' })\n }\n return\n }\n\n let parsedQuery\n try {\n parsedQuery = JSON.parse(queryToValidate)\n } catch (e) {\n if (!silent) {\n setValidationResult({ isValid: false, message: 'Invalid JSON syntax' })\n }\n return\n }\n\n if (!silent) {\n setIsValidating(true)\n setValidationResult(null)\n }\n\n try {\n const result = await cubeApi.dryRun(parsedQuery)\n\n // Check if validation is successful:\n // 1. Must have queryType (always present in successful Cube.js responses) \n // 2. Must not have an error\n const isValid = !result.error && result.queryType\n \n if (isValid) {\n setDryRunData(result)\n \n if (!silent) {\n const details = []\n \n if (result.pivotQuery?.query) {\n if (result.pivotQuery.query.measures?.length > 0) {\n details.push(`${result.pivotQuery.query.measures.length} measure${result.pivotQuery.query.measures.length > 1 ? 's' : ''}`)\n }\n if (result.pivotQuery.query.dimensions?.length > 0) {\n details.push(`${result.pivotQuery.query.dimensions.length} dimension${result.pivotQuery.query.dimensions.length > 1 ? 's' : ''}`)\n }\n if (result.pivotQuery.query.filters?.length > 0) {\n details.push(`${result.pivotQuery.query.filters.length} filter${result.pivotQuery.query.filters.length > 1 ? 's' : ''}`)\n }\n if (result.pivotQuery.query.timeDimensions?.length > 0) {\n details.push(`${result.pivotQuery.query.timeDimensions.length} time dimension${result.pivotQuery.query.timeDimensions.length > 1 ? 's' : ''}`)\n }\n }\n\n if (result.complexity) {\n details.push(`${result.complexity} complexity`)\n }\n if (result.sql?.sql) {\n details.push('SQL generated')\n }\n if (result.cubesUsed?.length > 0) {\n details.push(`Cubes: ${result.cubesUsed.join(', ')}`)\n }\n \n const message = details.length > 0 ? `Query validated successfully (${details.join(', ')})` : 'Query validated successfully'\n setValidationResult({ isValid: true, message })\n setLastValidatedQuery(queryToValidate)\n }\n\n // Auto-populate chart config with sensible defaults on successful validation\n if (!isEditModeLoad) {\n autoPopulateChartConfig(result)\n }\n } else {\n if (!silent) {\n const errorMsg = result.error || 'Query validation failed'\n const details = result.details ? ` - ${Array.isArray(result.details) ? result.details.join(', ') : result.details}` : ''\n setValidationResult({ \n isValid: false, \n message: errorMsg + details\n })\n setLastValidatedQuery(queryToValidate)\n }\n }\n } catch (error) {\n if (!silent) {\n setValidationResult({ \n isValid: false, \n message: error instanceof Error ? error.message : 'Network error during validation' \n })\n setLastValidatedQuery(queryToValidate)\n }\n } finally {\n if (!silent) {\n setIsValidating(false)\n }\n }\n }\n\n const handleValidateQuery = async () => {\n await runDryRunValidation(query)\n }\n\n const handleOpenQueryBuilder = () => {\n // Parse the current query and set it as the initial query for QueryBuilder\n const initialQuery = query ? (() => {\n try {\n return JSON.parse(query)\n } catch {\n return {}\n }\n })() : {}\n \n setQueryBuilderInitialQuery(initialQuery)\n setShowQueryBuilder(true)\n }\n\n\n const handleApplyQueryBuilderQuery = (e?: React.MouseEvent) => {\n e?.preventDefault()\n e?.stopPropagation()\n \n if (!queryBuilderRef.current) return\n \n // Get current query and validation state from QueryBuilder\n const currentQuery = queryBuilderRef.current.getCurrentQuery()\n const validationState = queryBuilderRef.current.getValidationState()\n const validationResult = queryBuilderRef.current.getValidationResult()\n \n // Apply the query to the form\n const formattedQuery = JSON.stringify(currentQuery, null, 2)\n setQuery(formattedQuery)\n \n // If QueryBuilder had a valid query, transfer the validation state and dry-run data\n if (validationState?.status === 'valid' && validationResult) {\n setValidationResult({ \n isValid: true, \n message: 'Query validated in Query Builder' \n })\n setLastValidatedQuery(formattedQuery)\n \n // Transfer the dry-run data from QueryBuilder validation result\n setDryRunData(validationResult)\n \n // Auto-populate chart config using the same logic as form validation\n autoPopulateChartConfig(validationResult)\n } else {\n // Reset validation state if query wasn't validated in QueryBuilder\n setValidationResult(null)\n setLastValidatedQuery('')\n setDryRunData(null)\n }\n \n // Return to form view to continue editing\n setShowQueryBuilder(false)\n }\n\n const handleBackToForm = () => {\n setShowQueryBuilder(false)\n setQueryBuilderInitialQuery(null)\n }\n\n const handleClose = () => {\n setFormTitle('')\n setQuery('')\n setChartType('bar')\n setChartConfig({ xAxis: [], yAxis: [], series: [] })\n setDisplayConfig({ showLegend: true, showGrid: true, showTooltip: true, stacked: false })\n setValidationResult(null)\n setIsValidating(false)\n setLastValidatedQuery('')\n setDryRunData(null)\n setShowQueryBuilder(false)\n setQueryBuilderInitialQuery(null)\n onClose()\n }\n\n const isEditMode = !!portlet\n const hasQueryChanged = query.trim() !== lastValidatedQuery.trim() && lastValidatedQuery !== ''\n const isQueryValidAndCurrent = validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n\n\n const availableFields = dryRunData?.pivotQuery?.query ? {\n dimensions: dryRunData.pivotQuery.query.dimensions || [],\n timeDimensions: dryRunData.pivotQuery.query.timeDimensions?.map((td: any) => td.dimension) || [],\n measures: dryRunData.pivotQuery.query.measures || []\n } : null\n\n\n const footer = showQueryBuilder ? (\n <>\n <button\n type=\"button\"\n onClick={handleBackToForm}\n className=\"px-4 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-none focus:ring-2 focus:ring-dc-primary\"\n >\n Back to Form\n </button>\n <button\n type=\"button\"\n onClick={handleApplyQueryBuilderQuery}\n className=\"px-4 py-2 text-sm font-medium border border-transparent rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n style={{ backgroundColor: 'var(--dc-primary)', color: '#ffffff' }}\n title=\"Apply query to form\"\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-primary-hover)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-primary)'}\n >\n Apply Query\n </button>\n </>\n ) : (\n <>\n <button\n type=\"button\"\n onClick={handleClose}\n className=\"px-4 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-none focus:ring-2 focus:ring-dc-primary\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n form=\"portlet-form\"\n className=\"px-4 py-2 text-sm font-medium border border-transparent rounded-md disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-blue-500\"\n style={{ backgroundColor: 'var(--dc-primary)', color: '#ffffff' }}\n disabled={shouldSkipQuery ? !formTitle.trim() : (!formTitle.trim() || !query.trim() || (hasQueryChanged || (lastValidatedQuery === '' && query.trim() !== '')))}\n title={!shouldSkipQuery && (hasQueryChanged || (lastValidatedQuery === '' && query.trim() !== '')) ? \"Please validate your query before saving\" : \"\"}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-primary-hover)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-primary)'}\n >\n {submitText}\n </button>\n </>\n )\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={showQueryBuilder ? \"Query Builder\" : title}\n size=\"fullscreen-mobile\"\n footer={footer}\n noPadding={showQueryBuilder}\n >\n {showQueryBuilder ? (\n <QueryBuilder\n ref={queryBuilderRef}\n initialQuery={queryBuilderInitialQuery}\n disableLocalStorage={true}\n hideSettings={true}\n className=\"flex-1 w-full\"\n />\n ) : (\n <form id=\"portlet-form\" onSubmit={handleSubmit} className=\"space-y-4\">\n {/* Main layout - Responsive: single column on mobile, two columns on desktop */}\n <div className=\"flex flex-col lg:flex-row gap-4\">\n {/* Left side - Title, Chart Type, Query */}\n <div className=\"flex-1 flex flex-col gap-4\">\n {/* Title */}\n <div>\n <label className=\"block text-sm font-semibold text-dc-text-secondary mb-1\">\n Title\n </label>\n <input\n type=\"text\"\n value={formTitle}\n onChange={(e) => setFormTitle(e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary\"\n placeholder=\"Enter portlet title...\"\n required\n />\n </div>\n\n {/* Chart Type */}\n <div>\n <label className=\"block text-sm font-semibold text-dc-text-secondary mb-3\">\n Chart Type\n </label>\n <ChartTypeSelector\n selectedType={chartType}\n onTypeChange={setChartType}\n />\n </div>\n\n\n {/* Query Editor - Hidden for skipQuery charts */}\n {!shouldSkipQuery && (\n <div className=\"flex-1 flex flex-col\">\n <div className=\"flex justify-between items-center mb-1\">\n <label className=\"block text-sm font-semibold text-dc-text-secondary\">\n Cube.js Query (JSON)\n </label>\n <div className=\"flex items-center space-x-2\">\n <button\n type=\"button\"\n onClick={handleOpenQueryBuilder}\n className=\"text-xs px-2 py-1 text-purple-600 dark:text-purple-300 bg-dc-surface hover:bg-purple-50 dark:hover:bg-purple-900/30 rounded-sm border border-purple-600 dark:border-purple-700 hover:border-purple-700 dark:hover:border-purple-600 focus:outline-none focus:ring-2 focus:ring-purple-500\"\n >\n Edit in Query Builder\n </button>\n </div>\n </div>\n <textarea\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n className=\"flex-1 w-full min-h-64 px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary font-mono text-xs resize-y\"\n placeholder={`{\n \"measures\": [\"People.count\"],\n \"dimensions\": [\"People.active\"]\n}`}\n required\n />\n </div>\n )}\n </div>\n\n {/* Right side - Chart Configuration */}\n <div className=\"flex-1 flex flex-col\">\n <label className=\"block text-sm font-semibold text-dc-text-secondary mb-1\">\n {shouldSkipQuery ? 'Chart Configuration' : 'Chart Axis Configuration'}\n </label>\n\n {shouldSkipQuery ? (\n <div className=\"rounded-lg bg-dc-surface p-3 border border-dc-border\">\n <ChartConfigPanel\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n availableFields={null}\n colorPalette={colorPalette}\n onChartConfigChange={setChartConfig}\n onDisplayConfigChange={setDisplayConfig}\n />\n </div>\n ) : (!dryRunData || !isQueryValidAndCurrent) ? (\n <div className=\"flex-1 flex items-center justify-center border-2 border-dashed border-dc-border rounded-lg bg-dc-surface-secondary\">\n <div className=\"text-center text-dc-text-muted\">\n <svg className=\"h-8 w-8 mx-auto mb-2\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" />\n </svg>\n <p className=\"text-sm\">Validate query first to configure chart axes</p>\n </div>\n </div>\n ) : (\n <div className=\"rounded-lg bg-dc-surface p-3 border border-dc-border\">\n <ChartConfigPanel\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n availableFields={availableFields}\n colorPalette={colorPalette}\n onChartConfigChange={setChartConfig}\n onDisplayConfigChange={setDisplayConfig}\n />\n </div>\n )}\n </div>\n </div>\n\n {/* Validation section - Hidden for skipQuery charts */}\n {!shouldSkipQuery && (hasQueryChanged || (lastValidatedQuery === '' && query.trim() !== '') || (validationResult && query.trim() === lastValidatedQuery.trim() && validationResult.message !== 'Loaded query (assumed valid)')) && (\n <div className={`rounded-lg p-4 ${\n validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'bg-green-50 dark:bg-green-900/30'\n : validationResult && !validationResult.isValid\n ? 'bg-red-50 dark:bg-red-900/30'\n : hasQueryChanged\n ? 'bg-amber-50 dark:bg-amber-900/30'\n : 'bg-dc-surface-secondary'\n }`}>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center space-x-3\">\n <div className={`w-2 h-2 rounded-full ${\n validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'bg-green-500'\n : validationResult && !validationResult.isValid\n ? 'bg-red-500'\n : hasQueryChanged\n ? 'bg-amber-500'\n : 'bg-gray-400'\n }`}></div>\n <div>\n <h3 className={`text-sm font-medium ${\n validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'text-green-800 dark:text-green-300'\n : validationResult && !validationResult.isValid\n ? 'text-red-800 dark:text-red-300'\n : hasQueryChanged\n ? 'text-amber-800 dark:text-amber-300'\n : 'text-dc-text-secondary'\n }`}>\n {validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'Query validated successfully'\n : validationResult && !validationResult.isValid\n ? 'Query validation failed'\n : hasQueryChanged\n ? 'Query modified - validation required'\n : 'Query validation required'\n }\n </h3>\n {validationResult && (\n <p className={`text-xs mt-1 ${\n validationResult.isValid ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'\n }`}>\n {validationResult.message}\n </p>\n )}\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={handleValidateQuery}\n disabled={isValidating || !query.trim()}\n className={`px-3 py-1.5 text-sm font-medium rounded-md transition-colors flex items-center space-x-1.5 ${\n validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'bg-green-600 text-white hover:bg-green-700'\n : validationResult && !validationResult.isValid\n ? 'bg-red-600 text-white hover:bg-red-700'\n : 'bg-dc-primary text-white hover:bg-dc-primary-hover'\n } disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-dc-primary`}\n >\n {isValidating ? (\n <>\n <svg className=\"animate-spin h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span>Validating</span>\n </>\n ) : validationResult?.isValid && query.trim() === lastValidatedQuery.trim() ? (\n <>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <span>Validated</span>\n </>\n ) : (\n <>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <span>Validate</span>\n </>\n )}\n </button>\n </div>\n </div>\n )}\n\n {/* Sample Queries - only show for create mode */}\n {!isEditMode && (\n <div>\n <label className=\"block text-sm text-dc-text-muted mb-2\">Sample Queries (click to use)</label>\n <div className=\"flex flex-wrap gap-2 mb-2\">\n {SAMPLE_QUERIES.map((sample, index) => (\n <button\n key={index}\n type=\"button\"\n onClick={() => handleSampleQuery(sample.query)}\n className=\"px-2 py-1 text-xs text-dc-text-secondary bg-dc-surface-secondary border border-dc-border rounded-sm cursor-pointer transition-all duration-200 ease-in-out hover:bg-dc-surface-hover hover:border-dc-border m-0.5\"\n >\n {sample.name}\n </button>\n ))}\n </div>\n </div>\n )}\n </form>\n )}\n </Modal>\n )\n}","/**\n * Portlet Filter Configuration Modal\n * Allows users to configure which dashboard filters apply to a specific portlet\n */\n\nimport { useState, useEffect } from 'react'\nimport type { DashboardFilter } from '../types'\n\ninterface PortletFilterConfigModalProps {\n isOpen: boolean\n onClose: () => void\n dashboardFilters: DashboardFilter[]\n currentMapping: string[]\n onSave: (mapping: string[]) => void\n portletTitle: string\n}\n\nexport default function PortletFilterConfigModal({\n isOpen,\n onClose,\n dashboardFilters = [],\n currentMapping = [],\n onSave,\n portletTitle\n}: PortletFilterConfigModalProps) {\n const [selectedFilters, setSelectedFilters] = useState<string[]>(currentMapping)\n\n // Update local state when props change\n useEffect(() => {\n setSelectedFilters(currentMapping)\n }, [currentMapping, isOpen])\n\n const handleToggleFilter = (filterId: string) => {\n setSelectedFilters(prev => {\n if (prev.includes(filterId)) {\n return prev.filter(id => id !== filterId)\n } else {\n return [...prev, filterId]\n }\n })\n }\n\n const handleSave = () => {\n onSave(selectedFilters)\n onClose()\n }\n\n const handleCancel = () => {\n setSelectedFilters(currentMapping) // Reset to original\n onClose()\n }\n\n // Format filter preview text\n const formatFilterPreview = (filter: DashboardFilter): string => {\n if (!filter.filter) return ''\n\n // Handle simple filters\n if ('member' in filter.filter && filter.filter.member) {\n const values = filter.filter.values || []\n const valuesText = values.length > 0 ? values.join(', ') : 'no value'\n return `${filter.filter.member} ${filter.filter.operator} ${valuesText}`\n }\n\n // Handle group filters (AND/OR)\n if ('type' in filter.filter && filter.filter.type) {\n const filterCount = filter.filter.filters?.length || 0\n return `${filter.filter.type.toUpperCase()} group with ${filterCount} filter${filterCount !== 1 ? 's' : ''}`\n }\n\n return 'Complex filter'\n }\n\n if (!isOpen) return null\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50\" onClick={handleCancel}>\n <div\n className=\"bg-dc-surface border border-dc-border rounded-lg max-w-2xl w-full mx-4 max-h-[80vh] flex flex-col\"\n style={{ boxShadow: 'var(--dc-shadow-lg)' }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"px-6 py-4 border-b border-dc-border bg-dc-surface-secondary rounded-t-lg\">\n <h2 className=\"text-lg font-semibold text-dc-text\">Configure Dashboard Filters</h2>\n <p className=\"text-sm text-dc-text-secondary mt-1\">\n Choose which dashboard filters apply to \"{portletTitle}\"\n </p>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-y-auto px-6 py-4\">\n {dashboardFilters.length === 0 ? (\n <div className=\"text-center py-8 text-dc-text-muted\">\n <svg\n className=\"mx-auto h-12 w-12 mb-3\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z\"\n />\n </svg>\n <p className=\"text-sm font-medium\">No dashboard filters available</p>\n <p className=\"text-xs mt-1\">Add filters at the dashboard level first</p>\n </div>\n ) : (\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between mb-4 pb-2 border-b border-dc-border\">\n <span className=\"text-sm font-medium text-dc-text\">Available Filters</span>\n <span className=\"text-xs text-dc-text-secondary\">\n {selectedFilters.length} of {dashboardFilters.length} selected\n </span>\n </div>\n\n {dashboardFilters.map(filter => {\n const isSelected = selectedFilters.includes(filter.id)\n\n return (\n <label\n key={filter.id}\n className={`flex items-start p-3 rounded-md border cursor-pointer transition-colors ${\n isSelected\n ? 'border-dc-primary bg-dc-surface-secondary'\n : 'border-dc-border hover:bg-dc-surface-hover'\n }`}\n >\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={() => handleToggleFilter(filter.id)}\n className=\"mt-0.5 mr-3 h-4 w-4 rounded border-dc-border focus:ring-2 focus:ring-dc-primary\"\n style={{\n accentColor: 'var(--dc-primary)'\n }}\n />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-sm text-dc-text truncate\">\n {filter.label}\n </span>\n {isSelected && (\n <span\n className=\"px-2 py-0.5 text-xs rounded-full\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n Applied\n </span>\n )}\n </div>\n <div className=\"mt-1 text-xs text-dc-text-secondary break-words\">\n {formatFilterPreview(filter)}\n </div>\n </div>\n </label>\n )\n })}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"px-6 py-4 border-t border-dc-border bg-dc-surface-secondary rounded-b-lg flex justify-end gap-3\">\n <button\n onClick={handleCancel}\n className=\"px-4 py-2 text-sm font-medium rounded-md border border-dc-border bg-dc-surface hover:bg-dc-surface-hover transition-colors text-dc-text\"\n >\n Cancel\n </button>\n <button\n onClick={handleSave}\n className=\"px-4 py-2 text-sm font-medium rounded-md text-white transition-colors\"\n style={{\n backgroundColor: 'var(--dc-primary)'\n }}\n >\n Apply Filters\n </button>\n </div>\n </div>\n </div>\n )\n}\n","import { useState, useEffect } from 'react'\n\ninterface DebugModalProps {\n chartConfig: any\n displayConfig: any\n queryObject: any\n data: any[]\n chartType: string\n}\n\nexport default function DebugModal({ \n chartConfig, \n displayConfig, \n queryObject, \n data, \n chartType \n}: DebugModalProps) {\n const [isOpen, setIsOpen] = useState(false)\n\n // Handle ESC key to close modal\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && isOpen) {\n setIsOpen(false)\n }\n }\n\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [isOpen])\n\n // Trigger Prism highlighting when modal opens and content is rendered\n useEffect(() => {\n if (isOpen && typeof window !== 'undefined' && (window as any).Prism) {\n // Small delay to ensure DOM is updated\n const timer = setTimeout(() => {\n (window as any).Prism.highlightAll()\n }, 10)\n \n return () => clearTimeout(timer)\n }\n }, [isOpen])\n\n\n if (!isOpen) {\n return (\n <button\n onClick={() => setIsOpen(true)}\n className=\"p-1 text-dc-text-muted hover:text-dc-text-secondary transition-colors\"\n title=\"Debug chart configuration\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\n </svg>\n </button>\n )\n }\n\n return (\n <div\n className=\"absolute inset-0 bg-dc-surface border border-dc-border rounded-lg z-50 overflow-auto\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"p-4 h-full flex flex-col\">\n <div className=\"flex justify-between items-center mb-4 shrink-0\">\n <h2 className=\"text-lg font-semibold text-dc-text\">Chart Debug Information</h2>\n <button\n onClick={() => setIsOpen(false)}\n className=\"p-2 text-dc-text-muted hover:text-dc-text-secondary hover:bg-dc-surface-secondary rounded-sm\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4 flex-1 overflow-auto\">\n <div>\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Chart Type</h3>\n <div className=\"bg-dc-surface-secondary p-2 rounded-sm text-sm font-mono border border-dc-border\">\n {chartType}\n </div>\n </div>\n\n <div>\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Field Analysis</h3>\n <div className=\"bg-dc-surface-secondary p-2 rounded-sm text-xs space-y-1 border border-dc-border\">\n <div>\n <strong>xAxis:</strong> {Array.isArray(chartConfig?.xAxis) ? `Array: [${chartConfig.xAxis.join(', ')}]` : `String: \"${chartConfig?.xAxis}\"`}\n </div>\n <div>\n <strong>yAxis:</strong> {Array.isArray(chartConfig?.yAxis) ? `Array: [${chartConfig.yAxis.join(', ')}]` : `String: \"${chartConfig?.yAxis}\"`}\n </div>\n <div>\n <strong>series:</strong> {Array.isArray(chartConfig?.series) ? `Array: [${chartConfig.series.join(', ')}]` : `String: \"${chartConfig?.series}\"`}\n </div>\n {chartConfig?.sizeField && (\n <div>\n <strong>sizeField:</strong> {Array.isArray(chartConfig?.sizeField) ? `Array: [${chartConfig.sizeField.join(', ')}]` : `String: \"${chartConfig?.sizeField}\"`}\n </div>\n )}\n {chartConfig?.colorField && (\n <div>\n <strong>colorField:</strong> {Array.isArray(chartConfig?.colorField) ? `Array: [${chartConfig.colorField.join(', ')}]` : `String: \"${chartConfig?.colorField}\"`}\n </div>\n )}\n </div>\n </div>\n\n <div className=\"lg:col-span-2\">\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Chart Config</h3>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border\" style={{ fontSize: '10px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(chartConfig, null, 2)}</code>\n </pre>\n </div>\n\n <div className=\"lg:col-span-2\">\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Display Config</h3>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border\" style={{ fontSize: '10px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(displayConfig, null, 2)}</code>\n </pre>\n </div>\n\n <div className=\"lg:col-span-2\">\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Query Object</h3>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border\" style={{ fontSize: '10px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(queryObject, null, 2)}</code>\n </pre>\n </div>\n\n <div className=\"lg:col-span-2\">\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Data Sample (first 3 rows)</h3>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border\" style={{ fontSize: '10px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(data?.slice(0, 3) || [], null, 2)}</code>\n </pre>\n </div>\n </div>\n\n <div className=\"mt-4 pt-2 border-t border-dc-border text-xs text-dc-text-muted shrink-0\">\n Press <kbd className=\"px-1 py-0.5 bg-dc-surface-secondary rounded-sm text-xs\">ESC</kbd> to close\n </div>\n </div>\n </div>\n )\n}","/**\n * Unified Color Palette System\n * Each palette contains coordinated series and gradient colors that work well together\n */\n\nexport interface ColorPalette {\n name: string\n label: string\n colors: string[] // For series-based charts (bar, line, pie, area, scatter, radar, etc.)\n gradient: string[] // For gradient-based charts (bubble, activity grid)\n}\n\n// Predefined color palettes with visually coordinated series and gradient colors\nexport const COLOR_PALETTES: ColorPalette[] = [\n {\n name: 'default',\n label: 'Default',\n colors: [\n '#3b82f6', // blue\n '#10b981', // green\n '#f59e0b', // yellow\n '#ef4444', // red\n '#8b5cf6', // purple\n '#f97316', // orange\n '#06b6d4', // cyan\n '#84cc16', // lime\n ],\n gradient: [\n '#440154', // dark purple\n '#414487', // purple-blue\n '#2a788e', // teal\n '#22a884', // green-teal \n '#7ad151', // green\n '#fde725', // yellow\n ]\n },\n {\n name: 'ocean',\n label: 'Ocean',\n colors: [\n '#1e3a8a', // deep blue\n '#1e40af', // blue\n '#2563eb', // bright blue\n '#3b82f6', // light blue\n '#06b6d4', // cyan\n '#0891b2', // dark cyan\n '#0e7490', // teal\n '#0f766e', // dark teal\n ],\n gradient: [\n '#0c4a6e', // very dark blue\n '#075985', // dark blue\n '#0369a1', // medium blue\n '#0284c7', // bright blue\n '#0ea5e9', // light blue\n '#38bdf8', // cyan blue\n ]\n },\n {\n name: 'sunset',\n label: 'Sunset',\n colors: [\n '#dc2626', // red\n '#ea580c', // orange-red\n '#f59e0b', // orange\n '#eab308', // yellow-orange\n '#d97706', // amber\n '#b45309', // dark amber\n '#92400e', // brown\n '#7c2d12', // dark brown\n ],\n gradient: [\n '#7c2d12', // dark brown\n '#92400e', // brown\n '#b45309', // dark amber\n '#d97706', // amber\n '#f59e0b', // orange\n '#fbbf24', // light orange\n ]\n },\n {\n name: 'forest',\n label: 'Forest',\n colors: [\n '#166534', // dark green\n '#15803d', // green\n '#16a34a', // bright green\n '#22c55e', // light green\n '#4ade80', // lighter green\n '#65a30d', // lime green\n '#84cc16', // lime\n '#a3e635', // light lime\n ],\n gradient: [\n '#14532d', // very dark green\n '#166534', // dark green\n '#15803d', // green\n '#16a34a', // bright green\n '#22c55e', // light green\n '#4ade80', // lighter green\n ]\n },\n {\n name: 'purple',\n label: 'Purple',\n colors: [\n '#581c87', // dark purple\n '#7c3aed', // purple\n '#8b5cf6', // bright purple\n '#a855f7', // light purple\n '#c084fc', // lighter purple\n '#e879f9', // magenta\n '#f0abfc', // light magenta\n '#fbbf24', // accent yellow\n ],\n gradient: [\n '#4c1d95', // very dark purple\n '#581c87', // dark purple\n '#6d28d9', // medium purple\n '#7c3aed', // purple\n '#8b5cf6', // bright purple\n '#a855f7', // light purple\n ]\n },\n {\n name: 'monochrome',\n label: 'Monochrome',\n colors: [\n '#1f2937', // very dark gray\n '#374151', // dark gray\n '#4b5563', // medium gray\n '#6b7280', // gray\n '#9ca3af', // light gray\n '#d1d5db', // lighter gray\n '#e5e7eb', // very light gray\n '#f3f4f6', // almost white\n ],\n gradient: [\n '#111827', // black\n '#1f2937', // very dark gray\n '#374151', // dark gray\n '#4b5563', // medium gray\n '#6b7280', // gray\n '#9ca3af', // light gray\n ]\n },\n {\n name: 'pastel',\n label: 'Pastel',\n colors: [\n '#93c5fd', // light blue\n '#86efac', // light green\n '#fde047', // light yellow\n '#fca5a5', // light red\n '#c4b5fd', // light purple\n '#fdba74', // light orange\n '#67e8f9', // light cyan\n '#bef264', // light lime\n ],\n gradient: [\n '#bfdbfe', // very light blue\n '#a7f3d0', // very light green\n '#fef08a', // very light yellow\n '#fecaca', // very light red\n '#ddd6fe', // very light purple\n '#fed7aa', // very light orange\n ]\n },\n {\n name: 'vibrant',\n label: 'Vibrant',\n colors: [\n '#0000ff', // pure blue\n '#00ff00', // pure green\n '#ffff00', // pure yellow\n '#ff0000', // pure red\n '#ff00ff', // pure magenta\n '#ff8000', // pure orange\n '#00ffff', // pure cyan\n '#8000ff', // pure violet\n ],\n gradient: [\n '#4000ff', // blue-violet\n '#0080ff', // blue\n '#00ffff', // cyan\n '#00ff80', // green\n '#80ff00', // lime\n '#ffff00', // yellow\n ]\n },\n {\n name: 'd3Category10',\n label: 'D3 Category 10',\n colors: [\n '#1f77b4', // blue\n '#ff7f0e', // orange\n '#2ca02c', // green\n '#d62728', // red\n '#9467bd', // purple\n '#8c564b', // brown\n '#e377c2', // pink\n '#7f7f7f', // gray\n '#bcbd22', // olive\n '#17becf', // cyan\n ],\n gradient: [\n '#1f77b4', // blue\n '#2ca02c', // green\n '#bcbd22', // olive\n '#ff7f0e', // orange\n '#d62728', // red\n '#9467bd', // purple\n ]\n },\n {\n name: 'd3Tableau10',\n label: 'D3 Tableau 10',\n colors: [\n '#4e79a7', // blue\n '#f28e2c', // orange\n '#e15759', // red\n '#76b7b2', // teal\n '#59a14f', // green\n '#edc949', // yellow\n '#af7aa1', // purple\n '#ff9da7', // pink\n '#9c755f', // brown\n '#bab0ab', // gray\n ],\n gradient: [\n '#4e79a7', // blue\n '#76b7b2', // teal\n '#59a14f', // green\n '#edc949', // yellow\n '#f28e2c', // orange\n '#e15759', // red\n ]\n },\n {\n name: 'colorBrewerSet1',\n label: 'ColorBrewer Set 1',\n colors: [\n '#e41a1c', // red\n '#377eb8', // blue\n '#4daf4a', // green\n '#984ea3', // purple\n '#ff7f00', // orange\n '#ffff33', // yellow\n '#a65628', // brown\n '#f781bf', // pink\n '#999999', // gray\n ],\n gradient: [\n '#377eb8', // blue\n '#4daf4a', // green\n '#ffff33', // yellow\n '#ff7f00', // orange\n '#e41a1c', // red\n '#984ea3', // purple\n ]\n },\n {\n name: 'colorBrewerSet2',\n label: 'ColorBrewer Set 2',\n colors: [\n '#66c2a5', // teal\n '#fc8d62', // orange\n '#8da0cb', // blue\n '#e78ac3', // pink\n '#a6d854', // lime\n '#ffd92f', // yellow\n '#e5c494', // tan\n '#b3b3b3', // gray\n ],\n gradient: [\n '#8da0cb', // blue\n '#66c2a5', // teal\n '#a6d854', // lime\n '#ffd92f', // yellow\n '#fc8d62', // orange\n '#e78ac3', // pink\n ]\n },\n {\n name: 'colorBrewerDark2',\n label: 'ColorBrewer Dark 2',\n colors: [\n '#1b9e77', // dark teal\n '#d95f02', // dark orange\n '#7570b3', // dark blue\n '#e7298a', // dark pink\n '#66a61e', // dark green\n '#e6ab02', // dark yellow\n '#a6761d', // dark brown\n '#666666', // dark gray\n ],\n gradient: [\n '#7570b3', // dark blue\n '#1b9e77', // dark teal\n '#66a61e', // dark green\n '#e6ab02', // dark yellow\n '#d95f02', // dark orange\n '#e7298a', // dark pink\n ]\n },\n {\n name: 'colorBrewerPaired',\n label: 'ColorBrewer Paired',\n colors: [\n '#a6cee3', // light blue\n '#1f78b4', // blue\n '#b2df8a', // light green\n '#33a02c', // green\n '#fb9a99', // light red\n '#e31a1c', // red\n '#fdbf6f', // light orange\n '#ff7f00', // orange\n '#cab2d6', // light purple\n '#6a3d9a', // purple\n '#ffff99', // light yellow\n '#b15928', // brown\n ],\n gradient: [\n '#1f78b4', // blue\n '#33a02c', // green\n '#ffff99', // light yellow\n '#ff7f00', // orange\n '#e31a1c', // red\n '#6a3d9a', // purple\n ]\n },\n {\n name: 'viridis',\n label: 'Viridis',\n colors: [\n '#440154', // dark purple\n '#482677', // purple\n '#3f4a8a', // blue-purple\n '#31678e', // blue\n '#26838f', // teal\n '#1f9d8a', // green-teal\n '#6cce5a', // green\n '#b6de2b', // yellow-green\n ],\n gradient: [\n '#440154', // dark purple\n '#482677', // purple\n '#3f4a8a', // blue-purple\n '#31678e', // blue\n '#26838f', // teal\n '#1f9d8a', // green-teal\n '#6cce5a', // green\n '#b6de2b', // yellow-green\n ]\n },\n {\n name: 'plasma',\n label: 'Plasma',\n colors: [\n '#0c0786', // dark blue\n '#5c01a6', // purple\n '#900da4', // magenta\n '#bf3984', // pink\n '#e16462', // coral\n '#f99b45', // orange\n '#fcce25', // yellow\n '#f0f921', // bright yellow\n ],\n gradient: [\n '#0c0786', // dark blue\n '#5c01a6', // purple\n '#900da4', // magenta\n '#bf3984', // pink\n '#e16462', // coral\n '#f99b45', // orange\n '#fcce25', // yellow\n '#f0f921', // bright yellow\n ]\n },\n {\n name: 'inferno',\n label: 'Inferno',\n colors: [\n '#000003', // black\n '#1f0c47', // dark blue\n '#550f6d', // purple\n '#88226a', // magenta\n '#a83655', // red\n '#cc4f39', // orange-red\n '#e6862a', // orange\n '#fec228', // yellow\n ],\n gradient: [\n '#000003', // black\n '#1f0c47', // dark blue\n '#550f6d', // purple\n '#88226a', // magenta\n '#a83655', // red\n '#cc4f39', // orange-red\n '#e6862a', // orange\n '#fec228', // yellow\n ]\n },\n {\n name: 'magma',\n label: 'Magma',\n colors: [\n '#000003', // black\n '#140b34', // dark purple\n '#3b0f6f', // purple\n '#641a80', // magenta\n '#8b2981', // pink\n '#b63679', // coral\n '#de4968', // red\n '#fd9f6c', // orange\n ],\n gradient: [\n '#000003', // black\n '#140b34', // dark purple\n '#3b0f6f', // purple\n '#641a80', // magenta\n '#8b2981', // pink\n '#b63679', // coral\n '#de4968', // red\n '#fd9f6c', // orange\n ]\n },\n {\n name: 'cividis',\n label: 'Cividis',\n colors: [\n '#00204c', // dark blue\n '#003f5c', // blue\n '#2c4b7a', // blue\n '#51576f', // blue-gray\n '#7f6874', // gray\n '#a8786e', // brown\n '#d2906d', // orange\n '#ffb570', // yellow\n ],\n gradient: [\n '#00204c', // dark blue\n '#003f5c', // blue\n '#2c4b7a', // blue\n '#51576f', // blue-gray\n '#7f6874', // gray\n '#a8786e', // brown\n '#d2906d', // orange\n '#ffb570', // yellow\n ]\n },\n {\n name: 'turbo',\n label: 'Turbo',\n colors: [\n '#30123b', // purple\n '#4454c4', // blue\n '#1dd3c0', // cyan\n '#42f465', // green\n '#b2df22', // lime\n '#faba39', // yellow\n '#f66c19', // orange\n '#c42e02', // red\n ],\n gradient: [\n '#30123b', // purple\n '#4454c4', // blue\n '#1dd3c0', // cyan\n '#42f465', // green\n '#b2df22', // lime\n '#faba39', // yellow\n '#f66c19', // orange\n '#c42e02', // red\n ]\n },\n {\n name: 'warm',\n label: 'Warm',\n colors: [\n '#8b0000', // dark red\n '#b22222', // red\n '#cd5c5c', // light red\n '#ff6347', // tomato\n '#ff8c00', // dark orange\n '#ffa500', // orange\n '#ffd700', // gold\n '#ffff00', // yellow\n ],\n gradient: [\n '#8b0000', // dark red\n '#b22222', // red\n '#ff6347', // tomato\n '#ff8c00', // dark orange\n '#ffa500', // orange\n '#ffd700', // gold\n ]\n },\n {\n name: 'cool',\n label: 'Cool',\n colors: [\n '#000080', // navy\n '#0000ff', // blue\n '#4169e1', // royal blue\n '#00bfff', // deep sky blue\n '#00ffff', // cyan\n '#40e0d0', // turquoise\n '#20b2aa', // light sea green\n '#008b8b', // dark cyan\n ],\n gradient: [\n '#000080', // navy\n '#0000ff', // blue\n '#4169e1', // royal blue\n '#00bfff', // deep sky blue\n '#00ffff', // cyan\n '#40e0d0', // turquoise\n ]\n },\n {\n name: 'earth',\n label: 'Earth',\n colors: [\n '#8b4513', // saddle brown\n '#a0522d', // sienna\n '#cd853f', // peru\n '#daa520', // goldenrod\n '#d2691e', // chocolate\n '#bc8f8f', // rosy brown\n '#f4a460', // sandy brown\n '#deb887', // burlywood\n ],\n gradient: [\n '#8b4513', // saddle brown\n '#a0522d', // sienna\n '#cd853f', // peru\n '#daa520', // goldenrod\n '#d2691e', // chocolate\n '#f4a460', // sandy brown\n ]\n },\n {\n name: 'autumn',\n label: 'Autumn',\n colors: [\n '#8b0000', // dark red\n '#a0522d', // sienna\n '#cd853f', // peru\n '#daa520', // goldenrod\n '#ff8c00', // dark orange\n '#ff4500', // orange red\n '#dc143c', // crimson\n '#b22222', // fire brick\n ],\n gradient: [\n '#8b0000', // dark red\n '#a0522d', // sienna\n '#cd853f', // peru\n '#daa520', // goldenrod\n '#ff8c00', // dark orange\n '#ff4500', // orange red\n ]\n },\n {\n name: 'spring',\n label: 'Spring',\n colors: [\n '#32cd32', // lime green\n '#98fb98', // pale green\n '#90ee90', // light green\n '#ffb6c1', // light pink\n '#ffc0cb', // pink\n '#ffffe0', // light yellow\n '#f0fff0', // honeydew\n '#e0ffff', // light cyan\n ],\n gradient: [\n '#32cd32', // lime green\n '#98fb98', // pale green\n '#ffffe0', // light yellow\n '#ffb6c1', // light pink\n '#ffc0cb', // pink\n '#e0ffff', // light cyan\n ]\n },\n {\n name: 'winter',\n label: 'Winter',\n colors: [\n '#191970', // midnight blue\n '#4682b4', // steel blue\n '#87ceeb', // sky blue\n '#b0e0e6', // powder blue\n '#e0ffff', // light cyan\n '#f0f8ff', // alice blue\n '#c0c0c0', // silver\n '#708090', // slate gray\n ],\n gradient: [\n '#191970', // midnight blue\n '#4682b4', // steel blue\n '#87ceeb', // sky blue\n '#b0e0e6', // powder blue\n '#e0ffff', // light cyan\n '#f0f8ff', // alice blue\n ]\n },\n {\n name: 'neon',\n label: 'Neon',\n colors: [\n '#ff0080', // neon pink\n '#00ff80', // neon green\n '#8000ff', // neon purple\n '#ff8000', // neon orange\n '#0080ff', // neon blue\n '#80ff00', // neon lime\n '#ff0040', // neon red\n '#40ff00', // bright green\n ],\n gradient: [\n '#8000ff', // neon purple\n '#0080ff', // neon blue\n '#00ff80', // neon green\n '#80ff00', // neon lime\n '#ff8000', // neon orange\n '#ff0080', // neon pink\n ]\n },\n {\n name: 'retro',\n label: 'Retro',\n colors: [\n '#ff69b4', // hot pink\n '#ffd700', // gold\n '#32cd32', // lime green\n '#00ced1', // dark turquoise\n '#ff6347', // tomato\n '#9370db', // medium purple\n '#ffa500', // orange\n '#20b2aa', // light sea green\n ],\n gradient: [\n '#9370db', // medium purple\n '#ff69b4', // hot pink\n '#ff6347', // tomato\n '#ffd700', // gold\n '#32cd32', // lime green\n '#00ced1', // dark turquoise\n ]\n },\n {\n name: 'corporate',\n label: 'Corporate',\n colors: [\n '#003366', // dark blue\n '#0066cc', // blue\n '#336699', // steel blue\n '#6699cc', // light blue\n '#4d4d4d', // dark gray\n '#808080', // gray\n '#b3b3b3', // light gray\n '#cccccc', // very light gray\n ],\n gradient: [\n '#003366', // dark blue\n '#0066cc', // blue\n '#336699', // steel blue\n '#6699cc', // light blue\n '#808080', // gray\n '#b3b3b3', // light gray\n ]\n },\n {\n name: 'material',\n label: 'Material Design',\n colors: [\n '#f44336', // red\n '#e91e63', // pink\n '#9c27b0', // purple\n '#673ab7', // deep purple\n '#3f51b5', // indigo\n '#2196f3', // blue\n '#03a9f4', // light blue\n '#00bcd4', // cyan\n ],\n gradient: [\n '#673ab7', // deep purple\n '#3f51b5', // indigo\n '#2196f3', // blue\n '#00bcd4', // cyan\n '#03a9f4', // light blue\n '#e91e63', // pink\n ]\n }\n]\n\n/**\n * Get a color palette by name, with fallback to default\n */\nexport function getColorPalette(paletteName?: string): ColorPalette {\n if (!paletteName) {\n return COLOR_PALETTES[0] // default palette\n }\n \n const palette = COLOR_PALETTES.find(p => p.name === paletteName)\n return palette || COLOR_PALETTES[0] // fallback to default\n}\n\n/**\n * Get just the series colors for a palette\n */\nexport function getSeriesColors(paletteName?: string): string[] {\n return getColorPalette(paletteName).colors\n}\n\n/**\n * Get just the gradient colors for a palette\n */\nexport function getGradientColors(paletteName?: string): string[] {\n return getColorPalette(paletteName).gradient\n}\n\n/**\n * Chart types that use series colors (discrete categories)\n */\nexport const SERIES_CHART_TYPES = [\n 'bar', 'line', 'area', 'pie', 'scatter', 'radar', 'radialBar', 'treeMap'\n] as const\n\n/**\n * Chart types that use gradient colors (continuous values)\n */\nexport const GRADIENT_CHART_TYPES = [\n 'bubble', 'activityGrid'\n] as const\n\n/**\n * Determine if a chart type uses gradient colors\n */\nexport function usesGradientColors(chartType: string): boolean {\n return GRADIENT_CHART_TYPES.includes(chartType as any)\n}","/**\n * Color Palette Selector Component\n * Allows users to select from predefined color palettes for their dashboard\n */\n\nimport { useState, useRef, useEffect } from 'react'\nimport { COLOR_PALETTES, getColorPalette } from '../utils/colorPalettes'\nimport { getIcon } from '../icons'\n\nconst ChevronDownIcon = getIcon('chevronDown')\n\ninterface ColorPaletteSelectorProps {\n currentPalette?: string\n onPaletteChange: (paletteName: string) => void\n className?: string\n}\n\nexport default function ColorPaletteSelector({\n currentPalette = 'default',\n onPaletteChange,\n className = ''\n}: ColorPaletteSelectorProps) {\n const [isOpen, setIsOpen] = useState(false)\n const dropdownRef = useRef<HTMLDivElement>(null)\n \n const currentPaletteObj = getColorPalette(currentPalette)\n\n // Close dropdown when clicking outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen])\n\n const handlePaletteSelect = (paletteName: string) => {\n onPaletteChange(paletteName)\n setIsOpen(false)\n }\n\n return (\n <div className={`relative ${className}`} ref={dropdownRef}>\n {/* Trigger Button */}\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n className=\"inline-flex items-center gap-2 px-3 py-1.5 bg-dc-surface border border-dc-border rounded-md shadow-xs text-sm font-medium text-dc-text-secondary hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-blue-500\"\n >\n {/* Current Palette Preview - Hidden on mobile */}\n <div className=\"hidden md:flex items-center gap-1.5\">\n <div className=\"flex gap-0.5\">\n {currentPaletteObj.colors.slice(0, 4).map((color, index) => (\n <div\n key={index}\n className=\"w-3 h-3 rounded-xs border border-dc-border\"\n style={{ backgroundColor: color }}\n title={`Series Color ${index + 1}`}\n />\n ))}\n </div>\n <span className=\"text-xs text-dc-text-secondary\">|</span>\n <div className=\"flex gap-0.5\">\n {currentPaletteObj.gradient.slice(0, 3).map((color, index) => (\n <div\n key={index}\n className=\"w-2 h-3 border-r first:rounded-l-sm last:rounded-r-sm last:border-r-0\"\n style={{\n backgroundColor: color,\n borderColor: 'var(--dc-border)'\n }}\n title={`Gradient Color ${index + 1}`}\n />\n ))}\n </div>\n </div>\n <span>{currentPaletteObj.label}</span>\n <ChevronDownIcon \n className={`w-4 h-4 transition-transform ${isOpen ? 'rotate-180' : ''}`} \n />\n </button>\n\n {/* Dropdown Menu - Responsive width */}\n {isOpen && (\n <div className=\"absolute top-full left-0 mt-1 w-72 md:w-80 lg:w-96 bg-dc-surface border border-dc-border rounded-md shadow-lg z-50 max-h-80 overflow-y-auto\">\n <div className=\"py-1\">\n {COLOR_PALETTES.slice().sort((a, b) => a.label.localeCompare(b.label)).map((palette) => (\n <button\n key={palette.name}\n type=\"button\"\n onClick={() => handlePaletteSelect(palette.name)}\n className={`w-full px-3 py-2 text-left text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${\n palette.name === currentPalette ? 'bg-dc-surface-secondary' : 'text-dc-text-secondary'\n }`}\n style={palette.name === currentPalette ? { color: 'var(--dc-primary)' } : undefined}\n >\n <div className=\"flex items-center gap-3\">\n {/* Palette Preview - Hidden on mobile */}\n <div className=\"hidden md:flex items-center gap-2\">\n {/* Series Colors */}\n <div className=\"flex gap-0.5\">\n {palette.colors.slice(0, 6).map((color, index) => (\n <div\n key={`series-${index}`}\n className=\"w-3 h-3 rounded-xs border border-dc-border\"\n style={{ backgroundColor: color }}\n />\n ))}\n </div>\n\n {/* Separator */}\n <div className=\"w-px h-4 bg-dc-border\" />\n \n {/* Gradient Colors */}\n <div className=\"flex\">\n {palette.gradient.map((color, index) => (\n <div\n key={`gradient-${index}`}\n className=\"w-2 h-4 first:rounded-l-sm last:rounded-r-sm\"\n style={{ backgroundColor: color }}\n />\n ))}\n </div>\n </div>\n \n {/* Palette Name */}\n <span className=\"font-medium\">{palette.label}</span>\n \n {/* Current Indicator */}\n {palette.name === currentPalette && (\n <div className=\"ml-auto\">\n <div className=\"w-2 h-2 rounded-full\" style={{ backgroundColor: 'var(--dc-primary)' }}></div>\n </div>\n )}\n </div>\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n )\n}","/**\n * FilterEditModal Component\n *\n * Modal for editing dashboard filter details including label, field, operator, and values\n *\n * Pattern: Self-contained modal with local state (matches PortletEditModal pattern)\n * - All editing state is local to the modal\n * - Changes only propagate on \"Done\" button click via onSave callback\n * - Cancel/close resets local state without saving\n */\n\nimport React, { useState, useCallback, useMemo, useEffect } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterBuilder from '../QueryBuilder/FilterBuilder'\n\nconst CloseIcon = getIcon('close')\nconst EyeIcon = getIcon('eye')\nconst EyeOffIcon = getIcon('eyeOff')\nimport DateRangeSelector from '../QueryBuilder/DateRangeSelector'\nimport CubeMetaExplorer from '../QueryBuilder/CubeMetaExplorer'\nimport { extractDashboardFields } from '../../utils/filterUtils'\nimport type { DashboardFilter, CubeMeta, Filter, DashboardConfig, SimpleFilter } from '../../types'\nimport type { MetaResponse } from '../QueryBuilder/types'\n\ninterface FilterEditModalProps {\n filter: DashboardFilter\n schema: CubeMeta | null\n dashboardConfig: DashboardConfig\n isOpen: boolean\n onSave: (filter: DashboardFilter) => void | Promise<void>\n onClose: () => void\n onDelete: () => void\n convertToMetaResponse: (cubeMeta: CubeMeta | null) => MetaResponse | null\n}\n\nconst FilterEditModal: React.FC<FilterEditModalProps> = ({\n filter,\n schema,\n dashboardConfig,\n isOpen,\n onSave,\n onClose,\n onDelete,\n convertToMetaResponse\n}) => {\n // Local state for editing - all changes stay local until \"Done\"\n const [localLabel, setLocalLabel] = useState(filter.label)\n const [localFilter, setLocalFilter] = useState(filter.filter)\n const [showAllFields, setShowAllFields] = useState(false)\n\n // Sync local state when filter prop changes or modal opens\n useEffect(() => {\n if (isOpen) {\n setLocalLabel(filter.label)\n setLocalFilter(filter.filter)\n }\n }, [filter, isOpen])\n\n // Extract fields used in dashboard\n const dashboardFields = useMemo(() => {\n return extractDashboardFields(dashboardConfig)\n }, [dashboardConfig])\n\n // Create filtered schema showing only dashboard fields\n const filteredSchema = useMemo<MetaResponse | null>(() => {\n if (!schema) return null\n\n if (showAllFields) {\n return convertToMetaResponse(schema)\n }\n\n const filteredCubes = schema.cubes\n .map(cube => {\n const cubeName = cube.name\n\n const filteredMeasures = cube.measures.filter(measure => {\n const fullName = measure.name.includes('.')\n ? measure.name\n : `${cubeName}.${measure.name}`\n return dashboardFields.measures.has(fullName)\n })\n\n const filteredDimensions = cube.dimensions.filter(dimension => {\n const fullName = dimension.name.includes('.')\n ? dimension.name\n : `${cubeName}.${dimension.name}`\n return dashboardFields.dimensions.has(fullName) ||\n dashboardFields.timeDimensions.has(fullName)\n })\n\n if (filteredMeasures.length > 0 || filteredDimensions.length > 0) {\n return {\n ...cube,\n measures: filteredMeasures,\n dimensions: filteredDimensions\n }\n }\n\n return null\n })\n .filter((cube): cube is NonNullable<typeof cube> => cube !== null)\n\n const filteredCubeMeta: CubeMeta = {\n ...schema,\n cubes: filteredCubes\n }\n\n return convertToMetaResponse(filteredCubeMeta)\n }, [schema, dashboardFields, showAllFields, convertToMetaResponse])\n\n // Extract the currently selected field to highlight it in the schema\n const selectedFieldInFilter = useMemo(() => {\n if ('member' in localFilter && localFilter.member) {\n return localFilter.member\n }\n return null\n }, [localFilter])\n\n // Handle label change - updates local state only\n const handleLabelChange = useCallback((newLabel: string) => {\n setLocalLabel(newLabel)\n }, [])\n\n // Handle filter changes from FilterBuilder - updates local state only\n const handleFilterBuilderChange = useCallback((filters: Filter[]) => {\n setLocalFilter(filters[0] || localFilter)\n }, [localFilter])\n\n // Handle field selection from schema explorer - updates local state only\n const handleFieldSelect = useCallback((fieldName: string) => {\n if ('member' in localFilter) {\n setLocalFilter({\n ...localFilter,\n member: fieldName,\n values: [] // Reset values when changing field\n })\n }\n }, [localFilter])\n\n // Handle date range change for universal time filters\n const handleDateRangeChange = useCallback((_timeDim: string, dateRange: string | string[]) => {\n if ('member' in localFilter) {\n setLocalFilter({\n ...localFilter,\n values: Array.isArray(dateRange) ? dateRange : [dateRange]\n } as SimpleFilter)\n }\n }, [localFilter])\n\n // Validate filter before saving\n const validateFilter = useCallback((): { isValid: boolean; message?: string } => {\n if (!localLabel.trim()) {\n return { isValid: false, message: 'Filter label is required' }\n }\n\n // Skip member validation for universal time filters (member is placeholder)\n if (!filter.isUniversalTime && 'member' in localFilter && !localFilter.member) {\n return { isValid: false, message: 'Please select a field for the filter' }\n }\n\n return { isValid: true }\n }, [localLabel, localFilter, filter.isUniversalTime])\n\n // Handle save - validate then call onSave with complete filter data\n const handleSave = useCallback(async () => {\n const validation = validateFilter()\n if (!validation.isValid) {\n alert(validation.message)\n return\n }\n\n const updatedFilter: DashboardFilter = {\n id: filter.id,\n label: localLabel,\n filter: localFilter,\n // Preserve isUniversalTime flag if present\n ...(filter.isUniversalTime && { isUniversalTime: true })\n }\n\n try {\n await onSave(updatedFilter)\n onClose()\n } catch (error) {\n console.error('Failed to save filter:', error)\n alert('Failed to save filter. Please try again.')\n }\n }, [filter.id, filter.isUniversalTime, localLabel, localFilter, validateFilter, onSave, onClose])\n\n // Handle cancel/close - reset local state\n const handleCancel = useCallback(() => {\n setLocalLabel(filter.label)\n setLocalFilter(filter.filter)\n onClose()\n }, [filter, onClose])\n\n return (\n <div className=\"fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-2\">\n <div className=\"rounded-lg shadow-xl max-w-7xl w-full h-[95vh] overflow-hidden flex flex-col bg-white dark:bg-gray-900\">\n {/* Modal Header */}\n <div className=\"px-6 py-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between\">\n <div className=\"flex-1\">\n <label className=\"block text-sm font-medium mb-2 text-gray-900 dark:text-gray-100\">\n Filter Label\n </label>\n <input\n type=\"text\"\n value={localLabel}\n onChange={(e) => handleLabelChange(e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100\"\n placeholder=\"Enter filter label\"\n />\n </div>\n <button\n onClick={handleCancel}\n className=\"ml-4 p-2 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-md transition-colors text-gray-700 dark:text-gray-300\"\n >\n <CloseIcon className=\"w-5 h-5\" />\n </button>\n </div>\n\n {/* Modal Body - Two Column Layout (or single column for universal time filters) */}\n <div className=\"flex-1 overflow-hidden flex\">\n {/* Left Column - Schema Explorer (hidden for universal time filters) */}\n {!filter.isUniversalTime && (\n <div className=\"w-80 border-r border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 overflow-auto\">\n <div className=\"p-4\">\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-semibold text-gray-900 dark:text-gray-100\">\n Available Fields\n </h3>\n <button\n onClick={() => setShowAllFields(!showAllFields)}\n className=\"flex items-center gap-1 text-xs px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-600 dark:text-gray-400\"\n title={showAllFields ? 'Show dashboard fields only' : 'Show all fields'}\n >\n {showAllFields ? (\n <>\n <EyeOffIcon className=\"w-3.5 h-3.5\" />\n <span>Dashboard</span>\n </>\n ) : (\n <>\n <EyeIcon className=\"w-3.5 h-3.5\" />\n <span>All</span>\n </>\n )}\n </button>\n </div>\n\n {!showAllFields && (\n <div className=\"text-xs text-gray-500 dark:text-gray-400 mb-3 p-2 bg-blue-50 dark:bg-blue-900/20 rounded\">\n Showing only fields used in this dashboard\n </div>\n )}\n\n {filteredSchema && filteredSchema.cubes.length > 0 ? (\n <CubeMetaExplorer\n schema={filteredSchema}\n schemaStatus=\"success\"\n schemaError={null}\n selectedFields={{\n measures: selectedFieldInFilter ? [selectedFieldInFilter] : [],\n dimensions: selectedFieldInFilter ? [selectedFieldInFilter] : [],\n timeDimensions: selectedFieldInFilter ? [selectedFieldInFilter] : []\n }}\n onFieldSelect={(fieldName) => handleFieldSelect(fieldName)}\n onFieldDeselect={() => {}}\n />\n ) : (\n <div className=\"text-center py-8 text-gray-500 dark:text-gray-400 text-sm\">\n {showAllFields ? (\n <div>\n <p className=\"mb-2\">No schema available</p>\n <p className=\"text-xs\">Check your API connection</p>\n </div>\n ) : (\n <div>\n <p className=\"mb-2\">No fields used in dashboard</p>\n <p className=\"text-xs\">Add portlets to the dashboard first, or toggle to show all fields</p>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Right Column - Filter Builder or Date Range Selector */}\n <div className=\"flex-1 overflow-auto px-6 py-4 bg-gray-50 dark:bg-gray-800\">\n {filter.isUniversalTime ? (\n /* Universal time filter - show DateRangeSelector */\n <div>\n <div className=\"mb-4 p-3 rounded-md bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800\">\n <div className=\"text-sm font-medium text-blue-800 dark:text-blue-200 mb-1\">\n Universal Time Filter\n </div>\n <div className=\"text-xs text-blue-600 dark:text-blue-300\">\n This filter applies to all time dimensions in portlets it's mapped to.\n Select a date range below to filter data across all time-based charts.\n </div>\n </div>\n <div className=\"mt-4\">\n <DateRangeSelector\n timeDimension=\"__universal_time__\"\n availableTimeDimensions={['__universal_time__']}\n currentDateRange={(() => {\n // Handle both dateRange property and values array\n const simpleFilter = localFilter as SimpleFilter\n if (simpleFilter.dateRange) return simpleFilter.dateRange\n if (simpleFilter.values) {\n // Single string value (preset like \"last 30 days\") - pass as string\n if (Array.isArray(simpleFilter.values) && simpleFilter.values.length === 1 && typeof simpleFilter.values[0] === 'string') {\n return simpleFilter.values[0]\n }\n return simpleFilter.values\n }\n return undefined\n })()}\n onDateRangeChange={handleDateRangeChange}\n onTimeDimensionChange={() => {}}\n onRemove={() => {}}\n hideFieldSelector={true}\n hideRemoveButton={true}\n />\n </div>\n </div>\n ) : (\n /* Regular filter - show FilterBuilder */\n <FilterBuilder\n filters={[localFilter]}\n schema={convertToMetaResponse(schema)}\n query={{}} // Empty query object - not needed for standalone filter editing\n onFiltersChange={handleFilterBuilderChange}\n />\n )}\n </div>\n </div>\n\n {/* Modal Footer */}\n <div className=\"px-6 py-4 border-t border-gray-200 dark:border-gray-700 flex items-center justify-between bg-white dark:bg-gray-900\">\n <button\n onClick={onDelete}\n className=\"px-4 py-2 text-sm font-medium text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-md transition-colors\"\n >\n Delete Filter\n </button>\n <button\n onClick={handleSave}\n className=\"px-4 py-2 text-sm font-medium rounded-md transition-colors bg-blue-600 hover:bg-blue-700 text-white\"\n >\n Done\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default FilterEditModal\n","/**\n * ReadOnlyFilterList Component\n *\n * Displays filters in read-only mode with interactive value selectors\n */\n\nimport React, { useCallback } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterItem from '../QueryBuilder/FilterItem'\n\nconst FilterIcon = getIcon('filter')\nconst ClockIcon = getIcon('timeDimension')\nimport DateRangeSelector from '../QueryBuilder/DateRangeSelector'\nimport type { DashboardFilter, CubeMeta, SimpleFilter } from '../../types'\nimport type { MetaResponse } from '../QueryBuilder/types'\n\ninterface ReadOnlyFilterListProps {\n dashboardFilters: DashboardFilter[]\n schema: CubeMeta | null\n onFilterChange: (filterId: string, updatedFilter: DashboardFilter) => void\n onDateRangeChange: (filterId: string, dateRange: string | string[]) => void\n convertToMetaResponse: (cubeMeta: CubeMeta | null) => MetaResponse | null\n isTimeDimensionField: (fieldName: string) => boolean\n}\n\nconst ReadOnlyFilterList: React.FC<ReadOnlyFilterListProps> = ({\n dashboardFilters,\n schema,\n onFilterChange,\n onDateRangeChange,\n convertToMetaResponse,\n isTimeDimensionField\n}) => {\n // Render individual read-only filter\n const renderReadOnlyFilter = useCallback((dashboardFilter: DashboardFilter) => {\n const { id, label, filter, isUniversalTime } = dashboardFilter\n\n // Only render SimpleFilter in read-only mode (skip GroupFilters for now)\n if (!('member' in filter)) {\n return null\n }\n\n const simpleFilter = filter as SimpleFilter\n const isTimeDim = isTimeDimensionField(simpleFilter.member)\n\n // For universal time filters OR time dimensions with inDateRange, use DateRangeSelector\n if (isUniversalTime || (isTimeDim && simpleFilter.operator === 'inDateRange')) {\n // Get date range - handle both dateRange property and values array\n // If values is a single-element array with a preset string, use that string directly\n let dateRangeValue: string | string[] | undefined = simpleFilter.dateRange\n if (!dateRangeValue && simpleFilter.values) {\n if (Array.isArray(simpleFilter.values) && simpleFilter.values.length === 1 && typeof simpleFilter.values[0] === 'string') {\n // Single string value (preset like \"last 30 days\") - pass as string\n dateRangeValue = simpleFilter.values[0]\n } else {\n dateRangeValue = simpleFilter.values\n }\n }\n\n return (\n <div key={id} className=\"flex flex-col gap-1.5\">\n <div className=\"flex items-center gap-1.5 px-1\">\n {isUniversalTime && (\n <ClockIcon className=\"w-3.5 h-3.5 shrink-0\" style={{ color: 'var(--dc-primary)' }} />\n )}\n <label\n className=\"text-xs font-semibold uppercase tracking-wide truncate\"\n style={{ color: 'var(--dc-text-secondary)' }}\n title={isUniversalTime ? `${label} (applies to all time dimensions)` : label}\n >\n {label}\n </label>\n </div>\n <DateRangeSelector\n timeDimension={isUniversalTime ? '__universal_time__' : simpleFilter.member}\n availableTimeDimensions={isUniversalTime ? ['__universal_time__'] : [simpleFilter.member]}\n currentDateRange={dateRangeValue}\n onDateRangeChange={(_timeDim, dateRange) => onDateRangeChange(id, dateRange)}\n onTimeDimensionChange={() => {}} // Not editable in read-only mode\n onRemove={() => {}} // Not removable in read-only mode\n hideFieldSelector={true}\n hideRemoveButton={true}\n />\n </div>\n )\n }\n\n // For regular filters, use FilterItem\n return (\n <div key={id} className=\"flex flex-col gap-1.5\">\n <label\n className=\"text-xs font-semibold uppercase tracking-wide truncate px-1\"\n style={{ color: 'var(--dc-text-secondary)' }}\n title={label}\n >\n {label}\n </label>\n <FilterItem\n filter={simpleFilter}\n index={0} // Not used in read-only mode\n onFilterChange={(_index, updatedFilter) => {\n onFilterChange(id, {\n ...dashboardFilter,\n filter: updatedFilter\n })\n }}\n onFilterRemove={() => {}} // Not removable in read-only mode\n schema={convertToMetaResponse(schema)}\n query={{}} // Empty query object for read-only mode\n hideFieldSelector={true}\n hideOperatorSelector={true}\n hideRemoveButton={true}\n />\n </div>\n )\n }, [schema, convertToMetaResponse, isTimeDimensionField, onFilterChange, onDateRangeChange])\n\n if (dashboardFilters.length === 0) {\n return null\n }\n\n return (\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-3\">\n <FilterIcon className=\"w-4 h-4 shrink-0\" style={{ color: 'var(--dc-primary)' }} />\n <h3 className=\"text-sm font-semibold\" style={{ color: 'var(--dc-text)' }}>\n Filters\n </h3>\n {dashboardFilters.length > 0 && (\n <span\n className=\"px-1.5 py-0.5 rounded-full text-xs font-medium\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n {dashboardFilters.length}\n </span>\n )}\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {dashboardFilters.map(renderReadOnlyFilter)}\n </div>\n </div>\n )\n}\n\nexport default ReadOnlyFilterList\n","/**\n * EditModeFilterList Component\n *\n * Displays filters in edit mode with chips showing filter labels and edit/delete actions\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport type { DashboardFilter } from '../../types'\n\nconst FilterIcon = getIcon('filter')\nconst AddIcon = getIcon('add')\nconst CloseIcon = getIcon('close')\nconst EditIcon = getIcon('edit')\nconst ChevronDownIcon = getIcon('chevronDown')\nconst ClockIcon = getIcon('timeDimension')\n\ninterface EditModeFilterListProps {\n dashboardFilters: DashboardFilter[]\n onAddFilter: () => void\n onAddTimeFilter: () => void\n onEditFilter: (filterId: string) => void\n onRemoveFilter: (filterId: string) => void\n selectedFilterId?: string | null\n onFilterSelect?: (filterId: string) => void\n}\n\nconst EditModeFilterList: React.FC<EditModeFilterListProps> = ({\n dashboardFilters,\n onAddFilter,\n onAddTimeFilter,\n onEditFilter,\n onRemoveFilter,\n selectedFilterId,\n onFilterSelect\n}) => {\n const [isCollapsed, setIsCollapsed] = React.useState(false)\n\n // Render compact filter chip - just label + edit + delete\n const renderFilterChip = (dashboardFilter: DashboardFilter) => {\n const { id, label, isUniversalTime } = dashboardFilter\n const isSelected = selectedFilterId === id\n\n // Use calendar icon for universal time filters, funnel for regular filters\n const IconComponent = isUniversalTime ? ClockIcon : FilterIcon\n\n return (\n <div\n key={id}\n className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md border text-xs transition-all ${\n 'cursor-pointer hover:shadow-md'\n }`}\n style={{\n backgroundColor: isSelected ? 'var(--dc-primary)' : 'var(--dc-surface)',\n borderColor: isSelected ? 'var(--dc-primary)' : 'var(--dc-border)',\n borderWidth: isSelected ? '2px' : '1px',\n color: isSelected ? 'white' : 'var(--dc-text)',\n boxShadow: isSelected ? '0 0 0 3px rgba(var(--dc-primary-rgb), 0.1)' : 'none'\n }}\n onClick={() => {\n if (onFilterSelect) {\n onFilterSelect(id)\n }\n }}\n >\n <IconComponent\n className=\"w-3.5 h-3.5 shrink-0\"\n style={{ color: isSelected ? 'white' : 'var(--dc-primary)' }}\n />\n <span className=\"font-medium truncate\">{label}</span>\n\n {!isSelected && (\n <div className=\"flex items-center gap-0.5 ml-1\" onClick={(e) => e.stopPropagation()}>\n <button\n onClick={() => onEditFilter(id)}\n className=\"p-0.5 hover:bg-dc-hover rounded transition-colors\"\n title=\"Edit filter\"\n >\n <EditIcon className=\"w-3 h-3\" />\n </button>\n <button\n onClick={() => onRemoveFilter(id)}\n className=\"p-0.5 hover:bg-red-50 hover:text-red-600 rounded transition-colors\"\n title=\"Remove filter\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n )}\n </div>\n )\n }\n\n return (\n <>\n {/* Mobile: Header + collapsible content */}\n <div className=\"md:hidden\">\n {/* Header - clickable to toggle */}\n <div\n className=\"px-4 py-2 flex items-center justify-between cursor-pointer\"\n onClick={() => setIsCollapsed(!isCollapsed)}\n >\n <div className=\"flex items-center gap-2\">\n <FilterIcon className=\"w-4 h-4 shrink-0\" style={{ color: 'var(--dc-primary)' }} />\n <h3 className=\"text-sm font-semibold\" style={{ color: 'var(--dc-text)' }}>\n Filters\n </h3>\n {dashboardFilters.length > 0 && (\n <span\n className=\"px-1.5 py-0.5 rounded-full text-xs font-medium\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n {dashboardFilters.length}\n </span>\n )}\n <ChevronDownIcon\n className={`w-4 h-4 transition-transform ${isCollapsed ? '' : 'rotate-180'}`}\n style={{ color: 'var(--dc-text-secondary)' }}\n />\n </div>\n\n <div className=\"flex items-center gap-1\">\n {/* Only show Date Range button if no universal time filter exists */}\n {!dashboardFilters.some(f => f.isUniversalTime) && (\n <button\n onClick={(e) => {\n e.stopPropagation()\n onAddTimeFilter()\n }}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80\"\n style={{\n backgroundColor: 'var(--dc-surface)',\n color: 'var(--dc-primary)',\n border: '1px solid var(--dc-border)'\n }}\n title=\"Add date range filter (applies to all time dimensions)\"\n >\n <AddIcon className=\"w-3.5 h-3.5\" />\n <ClockIcon className=\"w-3.5 h-3.5\" />\n </button>\n )}\n <button\n onClick={(e) => {\n e.stopPropagation()\n onAddFilter()\n }}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n <AddIcon className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n </div>\n\n {/* Mobile Filter Chips - Collapsible */}\n {dashboardFilters.length > 0 && !isCollapsed && (\n <div className=\"px-4 pb-2 flex flex-col gap-2\">\n {dashboardFilters.map(renderFilterChip)}\n </div>\n )}\n\n {/* Mobile Empty State */}\n {dashboardFilters.length === 0 && !isCollapsed && (\n <div className=\"px-4 pb-2\">\n <div\n className=\"text-xs p-2 rounded-md text-center\"\n style={{\n backgroundColor: 'var(--dc-surface-secondary)',\n color: 'var(--dc-text-secondary)'\n }}\n >\n No filters configured. Click \"Add\" to create one.\n </div>\n </div>\n )}\n </div>\n\n {/* Desktop: Single row layout */}\n <div className=\"hidden md:flex md:items-center md:gap-3 px-4 py-2\">\n {/* Header Section */}\n <div className=\"flex items-center gap-2 shrink-0\">\n <FilterIcon className=\"w-4 h-4 shrink-0\" style={{ color: 'var(--dc-primary)' }} />\n <h3 className=\"text-sm font-semibold whitespace-nowrap\" style={{ color: 'var(--dc-text)' }}>\n Filters\n </h3>\n {dashboardFilters.length > 0 && (\n <span\n className=\"px-1.5 py-0.5 rounded-full text-xs font-medium\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n {dashboardFilters.length}\n </span>\n )}\n </div>\n\n {/* Filter Chips Section - grows to fill space */}\n {dashboardFilters.length > 0 ? (\n <div className=\"flex flex-wrap gap-2 flex-1 min-w-0\">\n {dashboardFilters.map(renderFilterChip)}\n </div>\n ) : (\n <div className=\"flex-1 min-w-0\">\n <div\n className=\"text-xs px-3 py-1 rounded-md inline-block\"\n style={{\n backgroundColor: 'var(--dc-surface-secondary)',\n color: 'var(--dc-text-secondary)'\n }}\n >\n No filters configured. Click \"Add\" to create one.\n </div>\n </div>\n )}\n\n {/* Add Button Section */}\n <div className=\"flex items-center gap-1 shrink-0\">\n {/* Only show Date Range button if no universal time filter exists */}\n {!dashboardFilters.some(f => f.isUniversalTime) && (\n <button\n onClick={onAddTimeFilter}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80\"\n style={{\n backgroundColor: 'var(--dc-surface)',\n color: 'var(--dc-primary)',\n border: '1px solid var(--dc-border)'\n }}\n title=\"Add date range filter (applies to all time dimensions)\"\n >\n <AddIcon className=\"w-3.5 h-3.5\" />\n <span>Date Range</span>\n </button>\n )}\n <button\n onClick={onAddFilter}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n <AddIcon className=\"w-3.5 h-3.5\" />\n <span>Filter</span>\n </button>\n </div>\n </div>\n </>\n )\n}\n\nexport default EditModeFilterList\n","/**\n * DashboardFilterPanel Component\n *\n * Orchestrates dashboard-level filtering UI\n * - Edit mode: Shows filter chips with edit/delete actions\n * - View mode: Shows interactive read-only filters\n *\n * Pattern: Simplified coordination layer (matches portlet editing pattern)\n * - No local editing state (modal owns all edit state)\n * - Just tracks which filter is being edited and modal visibility\n * - Delegates to FilterEditModal for all editing logic\n */\n\nimport React, { useState, useCallback } from 'react'\nimport FilterEditModal from './DashboardFilters/FilterEditModal'\nimport ReadOnlyFilterList from './DashboardFilters/ReadOnlyFilterList'\nimport EditModeFilterList from './DashboardFilters/EditModeFilterList'\nimport type { DashboardFilter, CubeMeta, DashboardConfig } from '../types'\nimport type { MetaResponse } from './QueryBuilder/types'\n\ninterface DashboardFilterPanelProps {\n dashboardFilters: DashboardFilter[]\n editable: boolean\n schema: CubeMeta | null\n dashboardConfig: DashboardConfig\n onDashboardFiltersChange: (filters: DashboardFilter[]) => void\n onSaveFilters?: (filters: DashboardFilter[]) => void | Promise<void>\n selectedFilterId?: string | null\n onFilterSelect?: (filterId: string) => void\n isEditMode?: boolean\n}\n\nconst DashboardFilterPanel: React.FC<DashboardFilterPanelProps> = ({\n dashboardFilters,\n editable,\n schema,\n dashboardConfig,\n onDashboardFiltersChange,\n onSaveFilters,\n selectedFilterId,\n onFilterSelect,\n isEditMode = false\n}) => {\n // Track which filter is being edited and modal visibility (no local editing state)\n const [editingFilter, setEditingFilter] = useState<DashboardFilter | null>(null)\n const [showFilterBuilder, setShowFilterBuilder] = useState(false)\n\n // Convert CubeMeta to MetaResponse (QueryBuilder type)\n const convertToMetaResponse = useCallback((cubeMeta: CubeMeta | null): MetaResponse | null => {\n if (!cubeMeta) return null\n\n return {\n cubes: cubeMeta.cubes.map(cube => ({\n name: cube.name,\n title: cube.title || cube.name,\n description: cube.description || '',\n measures: cube.measures.map(m => ({\n name: m.name,\n title: m.title,\n type: m.type,\n description: '',\n shortTitle: m.shortTitle\n })),\n dimensions: cube.dimensions.map(d => ({\n name: d.name,\n title: d.title,\n type: d.type,\n description: '',\n shortTitle: d.shortTitle\n })),\n segments: cube.segments?.map(s => ({\n name: s.name,\n title: s.title,\n type: s.type,\n description: '',\n shortTitle: s.shortTitle\n })) || []\n }))\n }\n }, [])\n\n // Generate unique ID for new filters\n const generateFilterId = useCallback(() => {\n return `df_${Date.now()}_${Math.random().toString(36).substring(7)}`\n }, [])\n\n // Handle adding a new filter - create temporary filter for modal\n const handleAddFilter = useCallback(() => {\n const newFilter: DashboardFilter = {\n id: generateFilterId(),\n label: `Filter ${dashboardFilters.length + 1}`,\n filter: {\n member: '',\n operator: 'equals',\n values: []\n }\n }\n setEditingFilter(newFilter)\n setShowFilterBuilder(true)\n }, [dashboardFilters.length, generateFilterId])\n\n // Handle adding a universal time filter - applies to all time dimensions\n // Creates filter directly without opening modal (fixed name, user just sets date range in view mode)\n const handleAddTimeFilter = useCallback(() => {\n const newFilter: DashboardFilter = {\n id: generateFilterId(),\n label: 'Date Range Filter',\n isUniversalTime: true,\n filter: {\n member: '__universal_time__', // Placeholder, not used in merge logic\n operator: 'inDateRange',\n values: ['last 30 days']\n }\n }\n // Add directly to filters without opening modal\n const updatedFilters = [...dashboardFilters, newFilter]\n onDashboardFiltersChange(updatedFilters)\n }, [generateFilterId, dashboardFilters, onDashboardFiltersChange])\n\n // Handle editing an existing filter - just open modal with filter\n const handleEditFilter = useCallback((filterId: string) => {\n const filterToEdit = dashboardFilters.find(df => df.id === filterId)\n if (filterToEdit) {\n setEditingFilter(filterToEdit)\n setShowFilterBuilder(true)\n }\n }, [dashboardFilters])\n\n // Handle removing a filter - simple filter list update\n const handleRemoveFilter = useCallback((filterId: string) => {\n const updatedFilters = dashboardFilters.filter(df => df.id !== filterId)\n onDashboardFiltersChange(updatedFilters)\n\n // Close modal if we're deleting the filter being edited\n if (editingFilter?.id === filterId) {\n setEditingFilter(null)\n setShowFilterBuilder(false)\n }\n }, [dashboardFilters, editingFilter, onDashboardFiltersChange])\n\n // Handle save from modal - update or add filter and save\n const handleSaveFilter = useCallback(async (filterData: DashboardFilter) => {\n // Check if this is a new filter (not in current list) or an update\n const existingFilterIndex = dashboardFilters.findIndex(f => f.id === filterData.id)\n\n let updatedFilters: DashboardFilter[]\n if (existingFilterIndex >= 0) {\n // Update existing filter\n updatedFilters = dashboardFilters.map(f =>\n f.id === filterData.id ? filterData : f\n )\n } else {\n // Add new filter\n updatedFilters = [...dashboardFilters, filterData]\n }\n\n // Update dashboard state\n onDashboardFiltersChange(updatedFilters)\n\n // Trigger save if callback provided\n if (onSaveFilters) {\n try {\n await onSaveFilters(updatedFilters)\n } catch (error) {\n console.error('Failed to save filters:', error)\n throw error // Re-throw so modal can handle it\n }\n }\n }, [dashboardFilters, onDashboardFiltersChange, onSaveFilters])\n\n // Handle modal close - just clean up state\n const handleCloseFilterBuilder = useCallback(() => {\n setEditingFilter(null)\n setShowFilterBuilder(false)\n }, [])\n\n // Handle date range change in read-only mode\n const handleFilterDateRangeChange = useCallback((filterId: string, dateRange: string | string[]) => {\n const updatedFilters = dashboardFilters.map(df => {\n if (df.id === filterId) {\n const filter = df.filter\n if ('member' in filter) {\n return {\n ...df,\n filter: {\n ...filter,\n dateRange,\n values: Array.isArray(dateRange) ? dateRange : [dateRange]\n }\n }\n }\n }\n return df\n })\n onDashboardFiltersChange(updatedFilters)\n }, [dashboardFilters, onDashboardFiltersChange])\n\n // Handle filter change in read-only mode\n const handleReadOnlyFilterChange = useCallback((filterId: string, updatedFilter: DashboardFilter) => {\n const updatedFilters = dashboardFilters.map(df =>\n df.id === filterId ? updatedFilter : df\n )\n onDashboardFiltersChange(updatedFilters)\n }, [dashboardFilters, onDashboardFiltersChange])\n\n // Check if a field is a time dimension\n const isTimeDimensionField = useCallback((fieldName: string): boolean => {\n if (!schema) return false\n return schema.cubes.some(cube =>\n cube.dimensions.some(dim => dim.name === fieldName && dim.type === 'time')\n )\n }, [schema])\n\n // Hide filter panel completely when not editable (fully embedded mode without filter support)\n if (!editable) {\n return null\n }\n\n // Hide if no filters exist and not in edit mode (nothing to show)\n if (!isEditMode && dashboardFilters.length === 0) {\n return null\n }\n\n return (\n <div\n className=\"mb-4 border rounded-lg\"\n style={{\n borderColor: 'var(--dc-border)',\n backgroundColor: 'var(--dc-surface)',\n boxShadow: 'var(--dc-shadow-sm)'\n }}\n >\n {/* Edit Mode - Filter chips with edit/delete actions */}\n {isEditMode ? (\n <EditModeFilterList\n dashboardFilters={dashboardFilters}\n onAddFilter={handleAddFilter}\n onAddTimeFilter={handleAddTimeFilter}\n onEditFilter={handleEditFilter}\n onRemoveFilter={handleRemoveFilter}\n selectedFilterId={selectedFilterId}\n onFilterSelect={onFilterSelect}\n />\n ) : (\n /* View Mode - Read-only interactive filters */\n <ReadOnlyFilterList\n dashboardFilters={dashboardFilters}\n schema={schema}\n onFilterChange={handleReadOnlyFilterChange}\n onDateRangeChange={handleFilterDateRangeChange}\n convertToMetaResponse={convertToMetaResponse}\n isTimeDimensionField={isTimeDimensionField}\n />\n )}\n\n {/* Filter Edit Modal */}\n {editable && showFilterBuilder && editingFilter && (\n <FilterEditModal\n filter={editingFilter}\n schema={schema}\n dashboardConfig={dashboardConfig}\n isOpen={showFilterBuilder}\n onSave={handleSaveFilter}\n onClose={handleCloseFilterBuilder}\n onDelete={() => handleRemoveFilter(editingFilter.id)}\n convertToMetaResponse={convertToMetaResponse}\n />\n )}\n </div>\n )\n}\n\nexport default DashboardFilterPanel\n","/**\n * ScaledGridWrapper component\n * Applies CSS transform scaling to the dashboard grid for intermediate screen sizes\n * Maintains the exact desktop layout appearance, just proportionally smaller\n */\n\nimport React, { useState, useEffect, useRef } from 'react'\n\ninterface ScaledGridWrapperProps {\n scaleFactor: number\n designWidth: number\n children: React.ReactNode\n}\n\n/**\n * Wrapper component that scales the grid using CSS transform\n * Handles height compensation to prevent overflow/whitespace issues\n */\nexport default function ScaledGridWrapper({\n scaleFactor,\n designWidth,\n children\n}: ScaledGridWrapperProps) {\n const [actualHeight, setActualHeight] = useState(0)\n const innerRef = useRef<HTMLDivElement>(null)\n\n // Measure actual grid height to calculate visible height\n useEffect(() => {\n if (!innerRef.current) return\n\n const observer = new ResizeObserver((entries) => {\n setActualHeight(entries[0]?.contentRect.height ?? 0)\n })\n\n observer.observe(innerRef.current)\n\n // Set initial height\n setActualHeight(innerRef.current.offsetHeight || 0)\n\n return () => observer.disconnect()\n }, [])\n\n // The scaled visual height\n const visualHeight = actualHeight * scaleFactor\n\n return (\n <div\n className=\"scaled-grid-container\"\n style={{\n height: visualHeight > 0 ? visualHeight : 'auto',\n overflow: 'hidden',\n width: '100%'\n }}\n >\n <div\n ref={innerRef}\n className=\"scaled-grid-inner\"\n style={{\n transform: `scale(${scaleFactor})`,\n transformOrigin: 'top left',\n width: designWidth\n }}\n >\n {children}\n </div>\n </div>\n )\n}\n","/**\n * MobileStackedLayout component\n * Simple vertical stack layout for mobile screens (<768px)\n * Read-only view with portlets sorted by grid position\n */\n\nimport { useMemo, useRef, useState, useCallback } from 'react'\nimport { getIcon } from '../icons'\nimport AnalyticsPortlet from './AnalyticsPortlet'\n\nconst RefreshIcon = getIcon('refresh')\nimport { ScrollContainerProvider } from '../providers/ScrollContainerContext'\nimport type { DashboardFilter, DashboardConfig } from '../types'\nimport type { ColorPalette } from '../utils/colorPalettes'\n\n/**\n * Finds the nearest scrollable ancestor of an element.\n */\nfunction findScrollableAncestor(element: HTMLElement | null): HTMLElement | null {\n if (!element) return null\n\n let current = element.parentElement\n\n while (current) {\n const style = window.getComputedStyle(current)\n const overflowY = style.overflowY\n const overflowX = style.overflowX\n\n const hasScrollableOverflow =\n overflowY === 'auto' || overflowY === 'scroll' ||\n overflowX === 'auto' || overflowX === 'scroll'\n\n const hasScrollContent =\n current.scrollHeight > current.clientHeight ||\n current.scrollWidth > current.clientWidth\n\n if (hasScrollableOverflow && hasScrollContent) {\n return current\n }\n\n if (current === document.body) break\n current = current.parentElement\n }\n\n return null\n}\n\ninterface MobileStackedLayoutProps {\n config: DashboardConfig\n colorPalette?: ColorPalette\n dashboardFilters?: DashboardFilter[]\n onPortletRefresh?: (portletId: string) => void\n}\n\n/**\n * Mobile-optimized stacked layout for dashboard portlets\n * Renders portlets in a single column, sorted by grid position\n */\nexport default function MobileStackedLayout({\n config,\n colorPalette,\n dashboardFilters,\n onPortletRefresh\n}: MobileStackedLayoutProps) {\n const portletComponentRefs = useRef<{ [key: string]: { refresh: () => void } | null }>({})\n\n // Scroll container detection for lazy loading\n const [scrollContainer, setScrollContainer] = useState<HTMLElement | null>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n\n const setContainerRef = useCallback((node: HTMLDivElement | null) => {\n containerRef.current = node\n if (node) {\n setScrollContainer(findScrollableAncestor(node))\n }\n }, [])\n\n // Sort portlets by y position, then x position (top-to-bottom, left-to-right)\n const sortedPortlets = useMemo(() => {\n return [...config.portlets].sort((a, b) => {\n if (a.y !== b.y) return a.y - b.y\n return a.x - b.x\n })\n }, [config.portlets])\n\n const handlePortletRefresh = (portletId: string) => {\n // Refresh the specific portlet component\n portletComponentRefs.current[portletId]?.refresh()\n // Also call external handler if provided\n onPortletRefresh?.(portletId)\n }\n\n return (\n <ScrollContainerProvider value={scrollContainer}>\n <div ref={setContainerRef} className=\"mobile-stacked-layout space-y-4 px-2\">\n {sortedPortlets.map(portlet => {\n // Calculate height: use stored h * rowHeight (80px), with minimum\n const portletHeight = Math.max(300, portlet.h * 80)\n // Header is approximately 40px when shown\n const headerHeight = portlet.displayConfig?.hideHeader ? 0 : 40\n // Content height = total - header - padding (py-3 = 24px)\n const contentHeight = portletHeight - headerHeight - 24\n\n return (\n <div\n key={portlet.id}\n data-portlet-id={portlet.id}\n className=\"bg-dc-surface border border-dc-border rounded-lg flex flex-col\"\n style={{\n height: portletHeight,\n boxShadow: 'var(--dc-shadow-sm)'\n }}\n >\n {/* Portlet Header - Simplified for mobile (no edit controls) */}\n {!portlet.displayConfig?.hideHeader && (\n <div className=\"flex items-center justify-between px-3 py-2 border-b border-dc-border shrink-0 bg-dc-surface-secondary rounded-t-lg\">\n <h3 className=\"font-semibold text-sm text-dc-text truncate flex-1\">\n {portlet.title}\n </h3>\n <div className=\"flex items-center gap-1 shrink-0 ml-2\">\n <button\n onClick={() => handlePortletRefresh(portlet.id)}\n className=\"p-1 bg-transparent border-none rounded-sm text-dc-text-secondary cursor-pointer hover:bg-dc-surface-hover transition-colors\"\n title=\"Refresh portlet data\"\n >\n <RefreshIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n </div>\n </div>\n )}\n\n {/* Portlet Content - explicit height for charts to render */}\n <div\n className=\"px-2 py-3 overflow-visible flex flex-col\"\n style={{ height: contentHeight }}\n >\n <AnalyticsPortlet\n ref={el => { portletComponentRefs.current[portlet.id] = el }}\n query={portlet.query}\n chartType={portlet.chartType}\n chartConfig={portlet.chartConfig}\n displayConfig={portlet.displayConfig}\n dashboardFilters={dashboardFilters}\n dashboardFilterMapping={portlet.dashboardFilterMapping}\n eagerLoad={portlet.eagerLoad ?? config.eagerLoad ?? false}\n title={portlet.title}\n height={contentHeight}\n colorPalette={colorPalette}\n />\n </div>\n </div>\n )\n })}\n </div>\n </ScrollContainerProvider>\n )\n}\n","/**\n * Dashboard Grid Component\n * Uses react-grid-layout for responsive grid layout\n * Simplified version without app-specific dependencies\n */\n\nimport { useCallback, useRef, useState, useEffect, type ReactNode } from 'react'\nimport ReactGridLayout, { verticalCompactor, type LayoutItem, type Layout } from 'react-grid-layout'\nimport { getIcon } from '../icons'\nimport AnalyticsPortlet from './AnalyticsPortlet'\n\nconst ChartBarIcon = getIcon('measure')\nconst RefreshIcon = getIcon('refresh')\nconst EditIcon = getIcon('edit')\nconst DeleteIcon = getIcon('delete')\nconst AddIcon = getIcon('add')\nconst CopyIcon = getIcon('copy')\nconst FilterIcon = getIcon('filter')\nconst DesktopIcon = getIcon('desktop')\nimport PortletEditModal from './PortletEditModal'\nimport PortletFilterConfigModal from './PortletFilterConfigModal'\nimport DebugModal from './DebugModal'\nimport ColorPaletteSelector from './ColorPaletteSelector'\nimport DashboardFilterPanel from './DashboardFilterPanel'\nimport ScaledGridWrapper from './ScaledGridWrapper'\nimport MobileStackedLayout from './MobileStackedLayout'\nimport { useResponsiveDashboard } from '../hooks/useResponsiveDashboard'\nimport { ScrollContainerProvider } from '../providers/ScrollContainerContext'\nimport type { ColorPalette } from '../utils/colorPalettes'\n\n/**\n * Finds the nearest scrollable ancestor of an element.\n * Used to detect scroll container for lazy loading IntersectionObserver.\n */\nfunction findScrollableAncestor(element: HTMLElement | null): HTMLElement | null {\n if (!element) return null\n\n let current = element.parentElement\n\n while (current) {\n const style = window.getComputedStyle(current)\n const overflowY = style.overflowY\n const overflowX = style.overflowX\n\n const hasScrollableOverflow =\n overflowY === 'auto' || overflowY === 'scroll' ||\n overflowX === 'auto' || overflowX === 'scroll'\n\n const hasScrollContent =\n current.scrollHeight > current.clientHeight ||\n current.scrollWidth > current.clientWidth\n\n if (hasScrollableOverflow && hasScrollContent) {\n return current\n }\n\n if (current === document.body) break\n current = current.parentElement\n }\n\n return null // Use viewport\n}\nimport type { DashboardConfig, PortletConfig, DashboardFilter, CubeMeta } from '../types'\n\n// CSS for react-grid-layout should be imported by the consuming app\n// import 'react-grid-layout/css/styles.css'\n\ninterface DashboardGridProps {\n config: DashboardConfig\n editable?: boolean\n dashboardFilters?: DashboardFilter[] // Dashboard-level filters to apply to portlets\n loadingComponent?: ReactNode // Custom loading indicator for all portlets\n onConfigChange?: (config: DashboardConfig) => void\n onPortletRefresh?: (portletId: string) => void\n onSave?: (config: DashboardConfig) => Promise<void> | void\n colorPalette?: ColorPalette // Complete palette with both colors and gradient\n schema?: CubeMeta | null // Cube metadata for filter panel\n onDashboardFiltersChange?: (filters: DashboardFilter[]) => void // Handler for filter changes\n}\n\nexport default function DashboardGrid({\n config,\n editable = false,\n dashboardFilters,\n loadingComponent,\n onConfigChange,\n onPortletRefresh,\n onSave,\n colorPalette,\n schema,\n onDashboardFiltersChange\n}: DashboardGridProps) {\n // Responsive dashboard hook for three-tier layout strategy\n const {\n containerRef,\n containerWidth,\n displayMode,\n scaleFactor,\n isEditable: isResponsiveEditable,\n designWidth\n } = useResponsiveDashboard()\n\n // Scroll container detection for lazy loading\n // Null = viewport, element = scrolling container\n const [scrollContainer, setScrollContainer] = useState<HTMLElement | null>(null)\n const containerElementRef = useRef<HTMLDivElement | null>(null)\n\n // Detect scroll container after mount\n useEffect(() => {\n if (containerElementRef.current) {\n setScrollContainer(findScrollableAncestor(containerElementRef.current))\n }\n }, [])\n\n // Combined ref for container\n const combinedContainerRef = useCallback((node: HTMLDivElement | null) => {\n containerElementRef.current = node\n containerRef(node)\n if (node) {\n setScrollContainer(findScrollableAncestor(node))\n }\n }, [containerRef])\n\n // Calculate grid width based on display mode\n // Desktop: use actual container width (allows wider than 1200px)\n // Scaled: use design width (1200px) and apply CSS scaling\n const gridWidth = displayMode === 'desktop' ? containerWidth : designWidth\n\n // Refs to store portlet refs for refresh functionality\n const portletRefs = useRef<{ [key: string]: HTMLDivElement | null }>({})\n const portletComponentRefs = useRef<{ [key: string]: { refresh: () => void } | null }>({})\n\n // Track if component has been initialized to prevent saves during initial load\n const [isInitialized, setIsInitialized] = useState(false)\n const [lastKnownLayout, setLastKnownLayout] = useState<any[]>([])\n\n // Edit mode state - dashboard is readonly by default\n const [isEditMode, setIsEditMode] = useState(false)\n\n // Filter selection mode state\n const [selectedFilterId, setSelectedFilterId] = useState<string | null>(null)\n\n // Exit filter selection mode when leaving edit mode or when switching to non-desktop mode\n useEffect(() => {\n if ((!isEditMode || !isResponsiveEditable) && selectedFilterId) {\n setSelectedFilterId(null)\n }\n }, [isEditMode, isResponsiveEditable, selectedFilterId])\n\n // Exit edit mode when switching to non-desktop view\n useEffect(() => {\n if (!isResponsiveEditable && isEditMode) {\n setIsEditMode(false)\n }\n }, [isResponsiveEditable, isEditMode])\n\n // Track scroll state for sticky header\n const [isScrolled, setIsScrolled] = useState(false)\n\n // Modal states\n const [isPortletModalOpen, setIsPortletModalOpen] = useState(false)\n const [editingPortlet, setEditingPortlet] = useState<PortletConfig | null>(null)\n const [isFilterConfigModalOpen, setIsFilterConfigModalOpen] = useState(false)\n const [filterConfigPortlet, setFilterConfigPortlet] = useState<PortletConfig | null>(null)\n\n // Debug data state - keyed by portlet ID\n const [debugData, setDebugData] = useState<{ [portletId: string]: {\n chartConfig: any\n displayConfig: any\n queryObject: any\n data: any[]\n chartType: string\n } }>({})\n\n // Set up initialization tracking\n useEffect(() => {\n // Mark as initialized after first render to prevent saves during load/resize\n const timer = setTimeout(() => {\n setIsInitialized(true)\n // Store initial layout for comparison\n const initialLayout = config.portlets.map(portlet => ({\n i: portlet.id,\n x: portlet.x,\n y: portlet.y,\n w: portlet.w,\n h: portlet.h\n }))\n setLastKnownLayout(initialLayout)\n }, 200) // Slightly longer delay to ensure responsive grid is fully settled\n\n return () => clearTimeout(timer)\n }, [config.portlets])\n\n // Set up scroll listener for sticky header\n useEffect(() => {\n const handleScroll = () => {\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop\n setIsScrolled(scrollTop > 20) // Add sticky styling after scrolling 20px\n }\n\n window.addEventListener('scroll', handleScroll, { passive: true })\n\n // Check initial scroll position\n handleScroll()\n\n return () => {\n window.removeEventListener('scroll', handleScroll)\n }\n }, [])\n\n // Set up ESC key listener for filter selection mode\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && selectedFilterId) {\n setSelectedFilterId(null)\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [selectedFilterId])\n\n // Helper function to check if layout actually changed (not just reordered due to responsive changes)\n const hasLayoutActuallyChanged = useCallback((newLayout: any[]) => {\n if (!isInitialized || lastKnownLayout.length === 0) return false\n \n // Compare each item's position and size\n for (const newItem of newLayout) {\n const oldItem = lastKnownLayout.find(item => item.i === newItem.i)\n if (!oldItem) continue // New item, this is a change\n \n if (oldItem.x !== newItem.x || oldItem.y !== newItem.y || \n oldItem.w !== newItem.w || oldItem.h !== newItem.h) {\n return true\n }\n }\n return false\n }, [isInitialized, lastKnownLayout])\n\n const handleLayoutChange = useCallback((_layout: Layout) => {\n // This function is called for ALL layout changes\n // We should NOT save here - only update internal state if needed\n // Actual saving only happens in handleDragStop and handleResizeStop for explicit user actions\n\n // Note: We don't call onConfigChange here to prevent saving intermediate layout changes\n // The layout changes are handled by react-grid-layout internally\n }, []) // No dependencies since we're not doing anything\n\n // Handle drag stop - save when user finishes dragging (only if layout actually changed)\n const handleDragStop = useCallback(async (layout: Layout, _oldItem: LayoutItem | null, _newItem: LayoutItem | null, _placeholder: LayoutItem | null, _e: Event, _element: HTMLElement | undefined) => {\n if (!editable || !isEditMode || !onSave || !isInitialized) return\n\n // Only save if the layout actually changed from user interaction\n // Convert readonly Layout to mutable array for comparison\n const mutableLayout = [...layout]\n if (!hasLayoutActuallyChanged(mutableLayout)) {\n return // No actual change, don't save\n }\n\n // Get the current updated config (only called in desktop mode)\n const updatedPortlets = config.portlets.map(portlet => {\n const layoutItem = mutableLayout.find(item => item.i === portlet.id)\n if (layoutItem) {\n return {\n ...portlet,\n x: layoutItem.x,\n y: layoutItem.y,\n w: layoutItem.w,\n h: layoutItem.h\n }\n }\n return portlet\n })\n\n // Preserve existing responsive layouts, only update with new lg layout\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets,\n layouts: {\n ...config.layouts,\n lg: mutableLayout // Only save the large layout, let RGL handle responsive adjustments\n }\n }\n\n // Update our tracking of the last known layout\n setLastKnownLayout(mutableLayout)\n\n // Update config state first\n onConfigChange?.(updatedConfig)\n\n // Auto-save after drag operation\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed after drag:', error)\n }\n }, [config.portlets, config.layouts, editable, isEditMode, onConfigChange, onSave, isInitialized, hasLayoutActuallyChanged])\n\n // Handle resize stop - update config and save (resize is user interaction)\n const handleResizeStop = useCallback(async (layout: Layout, _oldItem: LayoutItem | null, _newItem: LayoutItem | null, _placeholder: LayoutItem | null, _e: Event, _element: HTMLElement | undefined) => {\n if (!editable || !isEditMode || !onConfigChange || !isInitialized) return\n\n // Only proceed if the layout actually changed from user interaction\n // Convert readonly Layout to mutable array for comparison\n const mutableLayout = [...layout]\n if (!hasLayoutActuallyChanged(mutableLayout)) {\n return // No actual change, don't save\n }\n\n // Get the current updated config (only called in desktop mode)\n const updatedPortlets = config.portlets.map(portlet => {\n const layoutItem = mutableLayout.find(item => item.i === portlet.id)\n if (layoutItem) {\n return {\n ...portlet,\n x: layoutItem.x,\n y: layoutItem.y,\n w: layoutItem.w,\n h: layoutItem.h\n }\n }\n return portlet\n })\n\n // Preserve existing responsive layouts, only update with new lg layout\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets,\n layouts: {\n ...config.layouts,\n lg: mutableLayout // Only save the large layout, let RGL handle responsive adjustments\n }\n }\n\n // Update our tracking of the last known layout\n setLastKnownLayout(mutableLayout)\n\n // Update config state\n onConfigChange(updatedConfig)\n\n // Auto-save after resize operation (user deliberately resized)\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed after resize:', error)\n }\n }\n }, [config.portlets, config.layouts, editable, isEditMode, onConfigChange, onSave, isInitialized, hasLayoutActuallyChanged])\n\n // Handle portlet refresh\n const handlePortletRefresh = useCallback((portletId: string) => {\n const portletComponent = portletComponentRefs.current[portletId]\n if (portletComponent && portletComponent.refresh) {\n portletComponent.refresh()\n }\n if (onPortletRefresh) {\n onPortletRefresh(portletId)\n }\n }, [onPortletRefresh])\n\n // Handle adding new portlet\n const handleAddPortlet = useCallback(() => {\n setEditingPortlet(null)\n setIsPortletModalOpen(true)\n }, [])\n\n // Handle editing existing portlet\n const handleEditPortlet = useCallback((portlet: PortletConfig) => {\n setEditingPortlet(portlet)\n setIsPortletModalOpen(true)\n }, [])\n\n // Handle portlet save\n const handlePortletSave = useCallback(async (portletData: PortletConfig | Omit<PortletConfig, 'id' | 'x' | 'y'>) => {\n if (!onConfigChange) return\n\n let updatedPortlets = [...config.portlets]\n let isNewPortlet = false\n let newPortletId: string | null = null\n\n if (editingPortlet) {\n // Editing existing portlet\n const index = updatedPortlets.findIndex(p => p.id === editingPortlet.id)\n if (index !== -1) {\n updatedPortlets[index] = portletData as PortletConfig\n }\n } else {\n // Adding new portlet\n isNewPortlet = true\n const newPortlet: PortletConfig = {\n ...portletData,\n id: `portlet-${Date.now()}`,\n x: 0,\n y: 0\n } as PortletConfig\n\n newPortletId = newPortlet.id\n\n // Find the best position for the new portlet\n const gridLayout = updatedPortlets.map(p => ({ i: p.id, x: p.x, y: p.y, w: p.w, h: p.h }))\n let maxY = 0\n gridLayout.forEach(item => {\n if (item.y + item.h > maxY) {\n maxY = item.y + item.h\n }\n })\n newPortlet.y = maxY\n\n updatedPortlets.push(newPortlet)\n }\n\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n\n setIsPortletModalOpen(false)\n setEditingPortlet(null)\n\n // Scroll to the new portlet after DOM update\n if (isNewPortlet && newPortletId) {\n setTimeout(() => {\n const scrollToPortlet = () => {\n // Try both the ref and DOM query selector\n let portletElement: HTMLElement | null = portletRefs.current[newPortletId!]\n if (!portletElement) {\n portletElement = document.querySelector(`[data-portlet-id=\"${newPortletId}\"]`)\n }\n \n if (portletElement) {\n portletElement.scrollIntoView({ \n behavior: 'smooth', \n block: 'center',\n inline: 'nearest'\n })\n return true\n }\n return false\n }\n \n // Try multiple times with increasing delays\n if (!scrollToPortlet()) {\n setTimeout(() => {\n if (!scrollToPortlet()) {\n setTimeout(() => {\n scrollToPortlet()\n }, 300)\n }\n }, 200)\n }\n }, 200)\n }\n }, [config, editingPortlet, onConfigChange, onSave])\n\n // Handle deleting portlet\n const handleDeletePortlet = useCallback(async (portletId: string) => {\n if (!onConfigChange) return\n \n if (window.confirm('Are you sure you want to delete this portlet?')) {\n const updatedPortlets = config.portlets.filter(p => p.id !== portletId)\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n \n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }\n }, [config, onConfigChange, onSave])\n\n // Handle duplicating portlet\n const handleDuplicatePortlet = useCallback(async (portletId: string) => {\n if (!onConfigChange) return\n \n const originalPortlet = config.portlets.find(p => p.id === portletId)\n if (!originalPortlet) return\n\n // Create duplicated portlet with new ID and updated title\n const duplicatedPortlet: PortletConfig = {\n ...originalPortlet,\n id: `portlet-${Date.now()}`,\n title: `${originalPortlet.title} Duplicated`,\n x: 0,\n y: 0\n }\n\n // Find the best position for the duplicated portlet\n const gridLayout = config.portlets.map(p => ({ i: p.id, x: p.x, y: p.y, w: p.w, h: p.h }))\n let maxY = 0\n gridLayout.forEach(item => {\n if (item.y + item.h > maxY) {\n maxY = item.y + item.h\n }\n })\n duplicatedPortlet.y = maxY\n\n const updatedPortlets = [...config.portlets, duplicatedPortlet]\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n \n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n\n // Scroll to the duplicated portlet after DOM update\n setTimeout(() => {\n const scrollToPortlet = () => {\n // Try both the ref and DOM query selector\n let portletElement: HTMLElement | null = portletRefs.current[duplicatedPortlet.id]\n if (!portletElement) {\n portletElement = document.querySelector(`[data-portlet-id=\"${duplicatedPortlet.id}\"]`)\n }\n \n if (portletElement) {\n portletElement.scrollIntoView({ \n behavior: 'smooth', \n block: 'center',\n inline: 'nearest'\n })\n return true\n }\n return false\n }\n \n // Try multiple times with increasing delays\n if (!scrollToPortlet()) {\n setTimeout(() => {\n if (!scrollToPortlet()) {\n setTimeout(() => {\n scrollToPortlet()\n }, 300)\n }\n }, 200)\n }\n }, 200)\n }, [config, onConfigChange, onSave])\n\n // Handle color palette changes\n const handlePaletteChange = useCallback(async (paletteName: string) => {\n if (!onConfigChange) return\n\n const updatedConfig = {\n ...config,\n colorPalette: paletteName\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }, [config, onConfigChange, onSave])\n\n // Handle opening filter config modal\n const handleOpenFilterConfig = useCallback((portlet: PortletConfig) => {\n setFilterConfigPortlet(portlet)\n setIsFilterConfigModalOpen(true)\n }, [])\n\n // Handle saving filter configuration\n const handleSaveFilterConfig = useCallback(async (mapping: string[]) => {\n if (!onConfigChange || !filterConfigPortlet) return\n\n const updatedPortlets = config.portlets.map(p => {\n if (p.id === filterConfigPortlet.id) {\n return {\n ...p,\n dashboardFilterMapping: mapping\n }\n }\n return p\n })\n\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }, [config, filterConfigPortlet, onConfigChange, onSave])\n\n // Handle toggling filter for a portlet (used in filter selection mode)\n const handleToggleFilterForPortlet = useCallback(async (portletId: string, filterId: string) => {\n if (!onConfigChange) return\n\n const updatedPortlets = config.portlets.map(p => {\n if (p.id === portletId) {\n const currentMapping = p.dashboardFilterMapping || []\n const hasFilter = currentMapping.includes(filterId)\n\n return {\n ...p,\n dashboardFilterMapping: hasFilter\n ? currentMapping.filter(id => id !== filterId)\n : [...currentMapping, filterId]\n }\n }\n return p\n })\n\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }, [config, onConfigChange, onSave])\n\n // Handle filter selection (click on filter chip)\n const handleFilterSelect = useCallback((filterId: string) => {\n // Toggle selection: if already selected, deselect\n setSelectedFilterId(prev => prev === filterId ? null : filterId)\n }, [])\n\n // Handle select all - apply current filter to all portlets\n const handleSelectAllForFilter = useCallback(async (filterId: string) => {\n if (!onConfigChange) return\n\n const updatedPortlets = config.portlets.map(p => {\n const currentMapping = p.dashboardFilterMapping || []\n // Add the filter if it's not already in the mapping\n if (!currentMapping.includes(filterId)) {\n return {\n ...p,\n dashboardFilterMapping: [...currentMapping, filterId]\n }\n }\n return p\n })\n\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }, [config, onConfigChange, onSave])\n\n // Get the selected filter object\n const selectedFilter = selectedFilterId\n ? dashboardFilters?.find(f => f.id === selectedFilterId)\n : null\n\n if (!config.portlets || config.portlets.length === 0) {\n return (\n <>\n <div className=\"flex justify-center items-center min-h-[50vh]\">\n <div className=\"text-center\">\n <ChartBarIcon style={{ width: '64px', height: '64px', color: 'var(--dc-text-muted)', margin: '0 auto 16px auto' }} />\n <h3 className=\"text-lg font-semibold mb-2 text-dc-text\">No Portlets</h3>\n <p className=\"text-sm text-dc-text-secondary mb-4\">Add your first portlet to start visualizing your data</p>\n {editable && (\n <button\n onClick={handleAddPortlet}\n className=\"inline-flex items-center px-4 py-2 border border-dc-border bg-dc-surface rounded-md focus:outline-hidden focus:ring-2\"\n style={{\n color: 'var(--dc-primary)',\n borderColor: 'var(--dc-primary)'\n }}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-surface-hover)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-surface)'}\n >\n <AddIcon className=\"w-5 h-5 mr-2\" />\n Add Portlet\n </button>\n )}\n </div>\n </div>\n \n {/* Portlet Modal */}\n <PortletEditModal\n isOpen={isPortletModalOpen}\n onClose={() => {\n setIsPortletModalOpen(false)\n setEditingPortlet(null)\n }}\n onSave={handlePortletSave}\n portlet={editingPortlet}\n title={editingPortlet ? 'Edit Portlet' : 'Add New Portlet'}\n submitText={editingPortlet ? 'Update Portlet' : 'Add Portlet'}\n colorPalette={colorPalette}\n />\n </>\n )\n }\n\n // Determine if editing is allowed (only in desktop mode)\n const canEdit = editable && isEditMode && isResponsiveEditable && !selectedFilterId\n\n // Generate grid layout from portlets - only use for lg (desktop) breakpoint\n // Let react-grid-layout handle responsive adjustments automatically\n const baseLayout: LayoutItem[] = config.portlets.map(portlet => ({\n i: portlet.id,\n x: portlet.x,\n y: portlet.y,\n w: portlet.w,\n h: portlet.h,\n minW: 2,\n minH: 2, // 2 rows at 80px = 160px minimum\n // Only enable drag/resize in edit mode\n isDraggable: canEdit,\n isResizable: canEdit,\n ...(canEdit ? { resizeHandles: ['s', 'w', 'e', 'n', 'se', 'sw', 'ne', 'nw'] as const } : {})\n }))\n\n // Render the portlet grid content (shared between desktop and scaled modes)\n const renderGridContent = () => (\n <ReactGridLayout\n className=\"layout\"\n layout={baseLayout}\n onLayoutChange={handleLayoutChange}\n onDragStop={handleDragStop}\n onResizeStop={handleResizeStop}\n width={gridWidth}\n gridConfig={{\n cols: 12,\n rowHeight: 80,\n margin: [16, 16],\n containerPadding: [0, 0]\n }}\n dragConfig={{\n enabled: canEdit,\n handle: '.portlet-drag-handle'\n }}\n resizeConfig={{\n enabled: canEdit,\n handles: ['s', 'w', 'e', 'n', 'se', 'sw', 'ne', 'nw'],\n // Invisible but functional resize handles\n handleComponent: (axis, ref) => (\n <div\n ref={ref as React.Ref<HTMLDivElement>}\n className={`react-resizable-handle react-resizable-handle-${axis}`}\n style={{ opacity: 0 }}\n />\n )\n }}\n compactor={verticalCompactor}\n >\n {config.portlets.map(portlet => {\n const hasSelectedFilter = selectedFilterId\n ? (portlet.dashboardFilterMapping || []).includes(selectedFilterId)\n : false\n const isInSelectionMode = !!selectedFilterId\n\n return (\n <div\n key={portlet.id}\n data-portlet-id={portlet.id}\n ref={el => { portletRefs.current[portlet.id] = el }}\n className={`bg-dc-surface border rounded-lg flex flex-col h-full transition-all ${\n isInSelectionMode ? 'cursor-pointer' : ''\n }`}\n style={{\n boxShadow: 'var(--dc-shadow-sm)',\n borderColor: isInSelectionMode && hasSelectedFilter\n ? 'var(--dc-primary)'\n : 'var(--dc-border)',\n borderWidth: isInSelectionMode && hasSelectedFilter ? '2px' : '1px',\n backgroundColor: isInSelectionMode && hasSelectedFilter\n ? 'rgba(var(--dc-primary-rgb), 0.05)'\n : 'var(--dc-surface)',\n opacity: isInSelectionMode && !hasSelectedFilter ? '0.5' : '1'\n }}\n onClick={(e) => {\n if (isInSelectionMode && selectedFilterId) {\n e.stopPropagation()\n handleToggleFilterForPortlet(portlet.id, selectedFilterId)\n }\n }}\n >\n {/* Portlet Header - Conditionally rendered based on displayConfig.hideHeader */}\n {(!portlet.displayConfig?.hideHeader || isEditMode) && (\n <div className={`flex items-center justify-between px-3 py-1.5 md:px-4 md:py-1 border-b border-dc-border shrink-0 bg-dc-surface-secondary rounded-t-lg portlet-drag-handle ${isEditMode ? 'cursor-move' : 'cursor-default'}`}>\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <h3 className=\"font-semibold text-sm text-dc-text truncate\">{portlet.title}</h3>\n {/* Debug button - only show in edit mode */}\n {editable && isEditMode && debugData[portlet.id] && (\n <div\n onMouseDown={(e) => e.stopPropagation()}\n onClick={(e) => e.stopPropagation()}\n onTouchStart={(e) => e.stopPropagation()}\n onTouchEnd={(e) => e.stopPropagation()}\n >\n <DebugModal\n chartConfig={debugData[portlet.id].chartConfig}\n displayConfig={debugData[portlet.id].displayConfig}\n queryObject={debugData[portlet.id].queryObject}\n data={debugData[portlet.id].data}\n chartType={debugData[portlet.id].chartType}\n />\n </div>\n )}\n </div>\n <div\n className=\"flex items-center gap-1 shrink-0 ml-4 -mr-2\"\n onMouseDown={(e) => e.stopPropagation()}\n onClick={(e) => e.stopPropagation()}\n onTouchStart={(e) => e.stopPropagation()}\n onTouchEnd={(e) => e.stopPropagation()}\n >\n <button\n onClick={(e) => {\n e.stopPropagation()\n handlePortletRefresh(portlet.id)\n }}\n onTouchEnd={(e) => {\n e.stopPropagation()\n e.preventDefault()\n handlePortletRefresh(portlet.id)\n }}\n disabled={isInSelectionMode}\n className={`p-1 bg-transparent border-none rounded-sm text-dc-text-secondary transition-colors ${\n isInSelectionMode ? 'cursor-not-allowed opacity-50' : 'cursor-pointer hover:bg-dc-surface-hover'\n }`}\n title=\"Refresh portlet data\"\n >\n <RefreshIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n\n {editable && isEditMode && !isInSelectionMode && (\n <>\n {/* Filter configuration button */}\n <button\n onClick={(e) => {\n e.stopPropagation()\n handleOpenFilterConfig(portlet)\n }}\n onTouchEnd={(e) => {\n e.stopPropagation()\n e.preventDefault()\n handleOpenFilterConfig(portlet)\n }}\n className=\"p-1 bg-transparent border-none rounded-sm cursor-pointer hover:bg-dc-surface-hover transition-colors relative\"\n title={`Configure dashboard filters${portlet.dashboardFilterMapping && portlet.dashboardFilterMapping.length > 0 ? ` (${portlet.dashboardFilterMapping.length} active)` : ''}`}\n style={{\n color: portlet.dashboardFilterMapping && portlet.dashboardFilterMapping.length > 0\n ? 'var(--dc-primary)'\n : 'var(--dc-text-secondary)'\n }}\n >\n <FilterIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n\n <button\n onClick={(e) => {\n e.stopPropagation()\n handleDuplicatePortlet(portlet.id)\n }}\n onTouchEnd={(e) => {\n e.stopPropagation()\n e.preventDefault()\n handleDuplicatePortlet(portlet.id)\n }}\n className=\"p-1 bg-transparent border-none rounded-sm text-dc-text-secondary cursor-pointer hover:bg-dc-surface-hover transition-colors\"\n title=\"Duplicate portlet\"\n >\n <CopyIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation()\n handleEditPortlet(portlet)\n }}\n onTouchEnd={(e) => {\n e.stopPropagation()\n e.preventDefault()\n handleEditPortlet(portlet)\n }}\n className=\"p-1 bg-transparent border-none rounded-sm text-dc-text-secondary cursor-pointer hover:bg-dc-surface-hover transition-colors\"\n title=\"Edit portlet\"\n >\n <EditIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation()\n handleDeletePortlet(portlet.id)\n }}\n onTouchEnd={(e) => {\n e.stopPropagation()\n e.preventDefault()\n handleDeletePortlet(portlet.id)\n }}\n className=\"p-1 mr-0.5 bg-transparent border-none rounded-sm cursor-pointer hover:bg-red-50 transition-colors\"\n style={{ color: '#ef4444' }}\n title=\"Delete portlet\"\n >\n <DeleteIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n </>\n )}\n </div>\n </div>\n )}\n\n {/* Portlet Content */}\n <div className=\"flex-1 px-2 py-3 md:px-4 md:py-4 min-h-0 overflow-visible flex flex-col\">\n <AnalyticsPortlet\n ref={el => { portletComponentRefs.current[portlet.id] = el }}\n query={portlet.query}\n chartType={portlet.chartType}\n chartConfig={portlet.chartConfig}\n displayConfig={portlet.displayConfig}\n dashboardFilters={dashboardFilters}\n dashboardFilterMapping={portlet.dashboardFilterMapping}\n eagerLoad={portlet.eagerLoad ?? config.eagerLoad ?? false}\n title={portlet.title}\n height=\"100%\"\n colorPalette={colorPalette}\n loadingComponent={loadingComponent}\n onDebugDataReady={(data) => {\n setDebugData(prev => ({\n ...prev,\n [portlet.id]: data\n }))\n }}\n />\n </div>\n </div>\n )\n })}\n </ReactGridLayout>\n )\n\n return (\n <ScrollContainerProvider value={scrollContainer}>\n <div ref={combinedContainerRef} className=\"dashboard-grid-container w-full\" style={{ maxWidth: '100%', overflow: 'hidden' }}>\n {editable && (\n <div\n className={`mb-4 flex justify-between items-center sticky top-0 z-10 px-4 py-4 bg-dc-surface-tertiary border border-dc-border rounded-lg transition-all duration-200 ${\n isScrolled ? 'border-b' : ''\n }`}\n style={{\n boxShadow: isScrolled ? 'var(--dc-shadow-md)' : 'var(--dc-shadow-sm)'\n }}\n >\n <div className=\"flex items-center gap-4\">\n <button\n onClick={() => isResponsiveEditable && setIsEditMode(!isEditMode)}\n disabled={!isResponsiveEditable}\n className={`inline-flex items-center px-4 py-2 text-sm font-medium rounded-md transition-colors focus:outline-hidden focus:ring-2 focus:ring-offset-2 ${\n !isResponsiveEditable\n ? 'opacity-50 cursor-not-allowed bg-dc-surface-secondary border border-dc-border'\n : isEditMode\n ? 'bg-dc-surface-secondary border border-dc-border hover:bg-dc-surface-hover'\n : 'bg-dc-surface border border-dc-border hover:bg-dc-surface-hover'\n }`}\n style={{\n color: !isResponsiveEditable ? 'var(--dc-text-muted)' : 'var(--dc-primary)',\n borderColor: !isResponsiveEditable ? 'var(--dc-border)' : isEditMode ? 'var(--dc-border)' : 'var(--dc-primary)'\n }}\n >\n <EditIcon className=\"w-4 h-4 mr-1.5\" />\n {isEditMode ? 'Finished Editing' : 'Edit'}\n </button>\n {!isResponsiveEditable && (\n <div className=\"flex items-center gap-2 text-sm text-dc-text-secondary\">\n <DesktopIcon className=\"w-4 h-4\" />\n <span>Desktop view required for editing</span>\n </div>\n )}\n {isEditMode && isResponsiveEditable && (\n <p className=\"hidden md:block text-sm text-dc-text-secondary\">\n Drag to rearrange • Resize from corners • Changes save automatically\n </p>\n )}\n </div>\n\n {/* Color Palette Selector - Only show in edit mode */}\n <div className=\"flex items-center gap-3\">\n {isEditMode && (\n <ColorPaletteSelector\n currentPalette={config.colorPalette}\n onPaletteChange={handlePaletteChange}\n className=\"shrink-0\"\n />\n )}\n\n <button\n onClick={handleAddPortlet}\n disabled={!isEditMode}\n className={`inline-flex items-center px-4 py-2 text-sm font-medium border rounded-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 ${\n isEditMode\n ? 'border-dc-border bg-dc-surface hover:bg-dc-surface-hover'\n : 'border-dc-border bg-dc-surface-secondary cursor-not-allowed'\n }`}\n style={{\n color: isEditMode ? 'var(--dc-primary)' : 'var(--dc-text-muted)',\n borderColor: isEditMode ? 'var(--dc-primary)' : 'var(--dc-border)'\n }}\n >\n <AddIcon className=\"w-5 h-5 mr-2\" />\n Add Portlet\n </button>\n </div>\n </div>\n )}\n\n {/* Dashboard Filter Panel - Always visible below toolbar */}\n <DashboardFilterPanel\n dashboardFilters={dashboardFilters || []}\n editable={editable}\n schema={schema || null}\n dashboardConfig={config}\n onDashboardFiltersChange={onDashboardFiltersChange || (() => {})}\n onSaveFilters={onSave ? async (filters: DashboardFilter[]) => {\n const updatedConfig = {\n ...config,\n filters\n }\n await onSave(updatedConfig)\n } : undefined}\n selectedFilterId={selectedFilterId}\n onFilterSelect={handleFilterSelect}\n isEditMode={isEditMode}\n />\n\n {/* Filter Selection Mode Banner */}\n {selectedFilterId && selectedFilter && (\n <div\n className=\"mb-4 px-4 py-3 rounded-md border-2 transition-all\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n borderColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n <div className=\"flex items-center justify-between flex-wrap gap-2\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <FilterIcon className=\"w-5 h-5 shrink-0\" />\n <span className=\"font-medium\">\n Filter Selection Mode - Click portlets to toggle '{selectedFilter.label}'\n </span>\n <span className=\"text-sm opacity-90 hidden sm:inline\">• Press ESC to exit</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => handleSelectAllForFilter(selectedFilterId)}\n className=\"px-3 py-1 rounded-md transition-colors text-sm font-medium\"\n style={{\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n color: 'white'\n }}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.3)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.2)'}\n >\n Select All\n </button>\n <button\n onClick={() => setSelectedFilterId(null)}\n className=\"px-3 py-1 rounded-md transition-colors text-sm font-medium\"\n style={{\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n color: 'white'\n }}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.3)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.2)'}\n >\n Exit\n </button>\n </div>\n </div>\n </div>\n )}\n \n {/* Render layout based on display mode */}\n {displayMode === 'mobile' ? (\n <MobileStackedLayout\n config={config}\n colorPalette={colorPalette}\n dashboardFilters={dashboardFilters}\n onPortletRefresh={handlePortletRefresh}\n />\n ) : displayMode === 'scaled' ? (\n <ScaledGridWrapper scaleFactor={scaleFactor} designWidth={designWidth}>\n {renderGridContent()}\n </ScaledGridWrapper>\n ) : (\n renderGridContent()\n )}\n \n {/* Portlet Modal */}\n <PortletEditModal\n isOpen={isPortletModalOpen}\n onClose={() => {\n setIsPortletModalOpen(false)\n setEditingPortlet(null)\n }}\n onSave={handlePortletSave}\n portlet={editingPortlet}\n title={editingPortlet ? 'Edit Portlet' : 'Add New Portlet'}\n submitText={editingPortlet ? 'Update Portlet' : 'Add Portlet'}\n colorPalette={colorPalette}\n />\n\n {/* Filter Configuration Modal */}\n <PortletFilterConfigModal\n isOpen={isFilterConfigModalOpen}\n onClose={() => {\n setIsFilterConfigModalOpen(false)\n setFilterConfigPortlet(null)\n }}\n dashboardFilters={dashboardFilters || []}\n currentMapping={filterConfigPortlet?.dashboardFilterMapping || []}\n onSave={handleSaveFilterConfig}\n portletTitle={filterConfigPortlet?.title || ''}\n />\n </div>\n </ScrollContainerProvider>\n )\n}","/**\n * Analytics Dashboard Component\n * Main dashboard container that uses CubeProvider context\n * Minimal dependencies, designed to be embedded in existing apps\n */\n\nimport { useCallback, useRef, useMemo } from 'react'\nimport DashboardGrid from './DashboardGrid'\nimport { useCubeContext } from '../providers/CubeProvider'\nimport { getColorPalette } from '../utils/colorPalettes'\nimport type { AnalyticsDashboardProps, DashboardConfig, DashboardFilter } from '../types'\n\nexport default function AnalyticsDashboard({\n config,\n editable = false,\n dashboardFilters: propDashboardFilters,\n loadingComponent,\n onConfigChange,\n onSave,\n onDirtyStateChange\n}: AnalyticsDashboardProps) {\n // Get cube metadata for filter building\n const { meta } = useCubeContext()\n\n // Track initial config to prevent saves during initial load\n const initialConfigRef = useRef(config)\n const hasConfigChangedFromInitial = useRef(false)\n\n // Merge programmatic filters (props) with config filters by ID\n // Config provides structure/metadata, props provide value overrides\n const mergedDashboardFilters = useMemo<DashboardFilter[]>(() => {\n const configFilters = config.filters || []\n const propFilters = propDashboardFilters || []\n\n // If no prop filters, use config filters as-is\n if (propFilters.length === 0) {\n return configFilters\n }\n\n // If no config filters, use prop filters as-is\n if (configFilters.length === 0) {\n return propFilters\n }\n\n // Merge by ID: config filters provide structure, prop filters provide values\n const mergedFilters: DashboardFilter[] = configFilters.map(configFilter => {\n // Find matching prop filter by ID\n const propFilter = propFilters.find(pf => pf.id === configFilter.id)\n\n if (propFilter) {\n // Merge: preserve config metadata, use prop filter values\n return {\n ...configFilter, // Preserve id, label, isUniversalTime from config\n filter: propFilter.filter // Use filter values from prop override\n }\n }\n\n // No override for this filter, use config as-is\n return configFilter\n })\n\n // Add any prop filters that don't exist in config (new filters)\n const configIds = new Set(configFilters.map(cf => cf.id))\n const newFilters = propFilters.filter(pf => !configIds.has(pf.id))\n\n return [...mergedFilters, ...newFilters]\n }, [config.filters, propDashboardFilters])\n\n // Enhanced save handler that tracks dirty state and prevents saves during initial load\n const handleSaveWithDirtyTracking = useCallback(async (config: DashboardConfig) => {\n // Don't save if this config hasn't actually changed from the initial load\n if (!hasConfigChangedFromInitial.current) {\n return // Prevent saves during initial load/responsive changes\n }\n \n if (onDirtyStateChange) {\n onDirtyStateChange(true) // Mark as dirty when save starts\n }\n \n try {\n if (onSave) {\n await onSave(config)\n }\n \n // Update our reference point after successful save\n initialConfigRef.current = config\n \n // Mark as clean after successful save\n if (onDirtyStateChange) {\n onDirtyStateChange(false)\n }\n } catch (error) {\n // Keep dirty state if save failed\n console.error('Save failed:', error)\n throw error\n }\n }, [onSave, onDirtyStateChange])\n\n // Enhanced config change handler that marks as dirty (only after initial load)\n const handleConfigChangeWithDirtyTracking = useCallback((config: DashboardConfig) => {\n if (onConfigChange) {\n onConfigChange(config)\n }\n \n // Check if this is a meaningful change from the initial config\n const configString = JSON.stringify(config)\n const initialConfigString = JSON.stringify(initialConfigRef.current)\n \n if (configString !== initialConfigString) {\n hasConfigChangedFromInitial.current = true\n \n if (onDirtyStateChange) {\n onDirtyStateChange(true)\n }\n }\n }, [onConfigChange, onDirtyStateChange])\n\n // Handle dashboard filter changes\n const handleDashboardFiltersChange = useCallback((filters: DashboardFilter[]) => {\n // Only update config if we're not using programmatic filters\n if (!propDashboardFilters || propDashboardFilters.length === 0) {\n const updatedConfig = {\n ...config,\n filters\n }\n handleConfigChangeWithDirtyTracking(updatedConfig)\n } else {\n console.warn('Dashboard filters are controlled via props - config changes ignored')\n }\n }, [config, propDashboardFilters, handleConfigChangeWithDirtyTracking])\n\n // Resolve complete palette object based on config\n const colorPalette = useMemo(() => {\n const paletteName = config.colorPalette\n return getColorPalette(paletteName)\n }, [config.colorPalette])\n\n return (\n <div className=\"w-full\">\n {/* Dashboard Grid (now includes filter panel) */}\n <DashboardGrid\n config={config}\n editable={editable}\n dashboardFilters={mergedDashboardFilters}\n loadingComponent={loadingComponent}\n onConfigChange={handleConfigChangeWithDirtyTracking}\n onSave={handleSaveWithDirtyTracking}\n colorPalette={colorPalette}\n schema={meta}\n onDashboardFiltersChange={handleDashboardFiltersChange}\n />\n </div>\n )\n}","/**\n * Portlet Container Component\n * Simple wrapper for individual portlets\n */\n\nimport { useState } from 'react'\nimport AnalyticsPortlet from './AnalyticsPortlet'\nimport DebugModal from './DebugModal'\nimport type { PortletConfig } from '../types'\n\ninterface PortletContainerProps {\n portlet: PortletConfig\n editable?: boolean\n onEdit?: (portlet: PortletConfig) => void\n onDelete?: (portletId: string) => void\n onRefresh?: (portletId: string) => void\n}\n\nexport default function PortletContainer({ \n portlet, \n editable = false,\n onEdit,\n onDelete,\n onRefresh\n}: PortletContainerProps) {\n const [debugData, setDebugData] = useState<{\n chartConfig: any\n displayConfig: any\n queryObject: any\n data: any[]\n chartType: string\n } | null>(null)\n\n return (\n <div className=\"bg-dc-surface border border-dc-border rounded-lg flex flex-col h-full\" style={{ boxShadow: 'var(--dc-shadow-sm)' }}>\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-dc-border shrink-0 bg-dc-surface-secondary rounded-t-lg px-3 py-2 md:px-6 md:py-3\">\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <h3 className=\"font-semibold text-sm truncate text-dc-text\">{portlet.title}</h3>\n {/* Debug button - right next to title */}\n {debugData && (\n <DebugModal\n chartConfig={debugData.chartConfig}\n displayConfig={debugData.displayConfig}\n queryObject={debugData.queryObject}\n data={debugData.data}\n chartType={debugData.chartType}\n />\n )}\n </div>\n\n <div className=\"flex items-center gap-2 ml-4\">\n\n {editable && (\n <>\n <button\n onClick={() => onRefresh?.(portlet.id)}\n className=\"p-1.5 hover:bg-dc-surface-hover rounded-sm text-dc-text-secondary\"\n title=\"Refresh\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\" />\n </svg>\n </button>\n <button\n onClick={() => onEdit?.(portlet)}\n className=\"p-1.5 hover:bg-dc-surface-hover rounded-sm text-dc-text-secondary\"\n title=\"Edit\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\" />\n </svg>\n </button>\n <button\n onClick={() => onDelete?.(portlet.id)}\n className=\"p-1.5 rounded-sm text-dc-danger\"\n style={{ backgroundColor: 'transparent' }}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-danger-bg)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'transparent'}\n title=\"Delete\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\" />\n </svg>\n </button>\n </>\n )}\n </div>\n </div>\n\n {/* Content */}\n <div className=\"px-2 py-3 md:px-4 md:pt-6 md:pb-4 flex-1 min-h-0\">\n <AnalyticsPortlet\n query={portlet.query}\n chartType={portlet.chartType}\n chartConfig={portlet.chartConfig}\n displayConfig={portlet.displayConfig}\n title={portlet.title}\n height=\"100%\"\n onDebugDataReady={(data) => {\n setDebugData(data)\n }}\n />\n </div>\n </div>\n )\n}","import React, { useState, useEffect } from 'react'\nimport Modal from './Modal'\n\ninterface DashboardEditModalProps {\n isOpen: boolean\n onClose: () => void\n onSave: (data: { name: string; description?: string }) => Promise<void> | void\n title: string\n submitText: string\n initialName?: string\n initialDescription?: string\n}\n\nexport default function DashboardEditModal({\n isOpen,\n onClose,\n onSave,\n title,\n submitText,\n initialName = '',\n initialDescription = ''\n}: DashboardEditModalProps) {\n const [name, setName] = useState('')\n const [description, setDescription] = useState('')\n const [isSaving, setIsSaving] = useState(false)\n\n // Initialize form values when modal opens\n useEffect(() => {\n if (isOpen) {\n setName(initialName)\n setDescription(initialDescription)\n }\n }, [isOpen, initialName, initialDescription])\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n \n if (!name.trim()) {\n return\n }\n\n setIsSaving(true)\n \n try {\n await onSave({\n name: name.trim(),\n description: description.trim() || undefined\n })\n handleClose()\n } catch (error) {\n // Failed to save dashboard\n // Don't close modal on error so user can retry\n } finally {\n setIsSaving(false)\n }\n }\n\n const handleClose = () => {\n setName('')\n setDescription('')\n setIsSaving(false)\n onClose()\n }\n\n const footer = (\n <>\n <button\n type=\"button\"\n onClick={handleClose}\n disabled={isSaving}\n className=\"px-4 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover disabled:opacity-50\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n form=\"dashboard-form\"\n disabled={isSaving || !name.trim()}\n className=\"px-4 py-2 text-sm font-medium text-white bg-dc-primary border border-transparent rounded-md hover:bg-dc-primary-hover disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isSaving ? 'Saving...' : submitText}\n </button>\n </>\n )\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={title}\n size=\"fullscreen-mobile\"\n footer={footer}\n >\n <form id=\"dashboard-form\" onSubmit={handleSubmit} className=\"space-y-4 w-full\">\n <div>\n <label htmlFor=\"dashboard-name\" className=\"block text-sm font-medium text-dc-text-secondary mb-1\">\n Dashboard Name\n </label>\n <input\n type=\"text\"\n id=\"dashboard-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary\"\n placeholder=\"Enter dashboard name...\"\n required\n autoFocus\n />\n </div>\n\n <div>\n <label htmlFor=\"dashboard-description\" className=\"block text-sm font-medium text-dc-text-secondary mb-1\">\n Description (optional)\n </label>\n <textarea\n id=\"dashboard-description\"\n rows={3}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary\"\n placeholder=\"Enter description...\"\n />\n </div>\n </form>\n </Modal>\n )\n}"],"names":["observerMap","RootIds","rootId","unsupportedValue","getRootId","root","optionsToId","options","key","createObserver","id","instance","elements","thresholds","observer","entries","entry","_a2","inView","threshold","callback","observe","element","fallbackInView","bounds","callbacks","useInView","delay","trackVisibility","rootMargin","triggerOnce","skip","initialInView","onChange","ref","setRef","React2","lastInViewRef","state","setState","unobserve","previousInView","entryTarget","previousEntryTarget","result","RefreshIcon","getIcon","ChartErrorBoundary","Component","props","error","errorInfo","jsxs","jsx","shouldIncludeFilter","filter","simpleFilter","f","getApplicableDashboardFilters","dashboardFilters","filterMapping","df","convertToServerFormat","groupFilter","convertedFilters","mergeDashboardAndPortletFilters","portletFilters","extractDashboardFields","dashboardConfig","measures","dimensions","timeDimensions","portlet","query","measure","dimension","td","extractFieldsFromFilters","field","e","filters","fields","getDateRangeFromFilter","applyUniversalTimeFilters","portletTimeDimensions","universalTimeFilters","dateRange","AnalyticsPortlet","forwardRef","chartType","chartConfig","displayConfig","dashboardFilterMapping","eagerLoad","_isVisible","height","_title","colorPalette","loadingComponent","onDebugDataReady","refreshCounter","setRefreshCounter","useState","onDebugDataReadyRef","useRef","scrollContainer","useScrollContainer","inViewRef","isVisible","useEffect","chartTypeConfig","useChartConfig","shouldSkipQuery","queryObject","useMemo","parsed","regularFilters","applicableFilters","mergedFilters","mergedTimeDimensions","shouldSkip","resultSet","isLoading","useCubeQuery","useImperativeHandle","prev","data","getData","hasMandatoryFields","zone","LoadingIndicator","chartHeight","isValidChartType","LazyChart","Modal","isOpen","onClose","title","size","closeOnBackdropClick","closeOnEscape","showCloseButton","children","footer","noPadding","handleEscapeKey","useCallback","event","getMeasureIcon","measureType","className","IconComponent","getMeasureTypeIcon","CubeRelationshipDiagram","lazy","mod","CubeMetaExplorer","schema","schemaStatus","schemaError","selectedFields","onFieldSelect","onFieldDeselect","onRetrySchema","onOpenSettings","onViewTypeChange","isExpanded","ChevronDownIcon","ChevronRightIcon","WarningIcon","SettingsIcon","MeasureIcon","DimensionIcon","TimeDimensionIcon","SegmentIcon","MenuIcon","features","useCubeContext","showSchemaDiagram","expandedCubes","setExpandedCubes","expandedSections","setExpandedSections","searchTerm","setSearchTerm","viewType","setViewType","preSearchExpandedCubes","setPreSearchExpandedCubes","preSearchExpandedSections","setPreSearchExpandedSections","React","newExpandedCubes","newExpandedSections","cube","cubeHasMatches","d","combinedCubes","combinedSections","isCorsError","Fragment","toggleCubeExpansion","cubeName","newExpanded","newPreSearchExpanded","toggleSectionExpansion","sectionKey","handleFieldClick","fieldType","filterFields","measureMatches","dimensionMatches","FieldItem","icon","isSelected","getSelectedStyles","getIconColor","getCheckmarkColor","SectionHeader","count","getSectionType","NoMatchesMessage","Suspense","fieldName","qbFieldType","c","fullFieldName","index","arr","filteredCubes","regularDimensions","timeDimension","TIME_GRANULARITIES","FILTER_OPERATORS","DATE_RANGE_OPTIONS","CloseIcon","FilterValueSelector","operator","values","onValuesChange","operatorMeta","setIsOpen","searchText","setSearchText","hasLoadedInitial","setHasLoadedInitial","dropdownRef","lastSearchedTerm","debouncedSearchText","useDebounce","isDimension","dim","isTimeDimension","shouldFetchValues","shouldShowComboBox","distinctValues","valuesLoading","valuesError","searchValues","useFilterValues","handleClickOutside","handleDropdownToggle","newIsOpen","handleSearchChange","newSearchText","handleValueSelect","value","handleValueRemove","valueToRemove","v","handleDirectInput","numValue","handleDateInput","currentValues","handleDateRangeEndInput","handleBetweenStartInput","newValues","handleBetweenEndInput","hasQueryContent","getSelectedFieldsCount","cleanQuery","cleanedQuery","cleanQueryForServer","transformFiltersForServer","createEmptyQuery","isSimpleFilter","isGroupFilter","isAndFilter","isOrFilter","getFilterableFields","allFields","a","b","getAllFilterableFields","getOrganizedFilterFields","getAvailableOperators","operators","meta","getFieldType","m","countFilters","countFilter","createSimpleFilter","member","createAndFilter","createOrFilter","cleanupFilters","_query","transformFilter","transformedSubFilters","convertDateRangeTypeToValue","rangeType","number","typeMap","unit","unitSingular","requiresNumberInput","formatDateForCube","date","getTimeDimensionsWithDateRanges","dateRanges","hasTimeDimensions","transformQueryForUI","transformed","transformFiltersFromServer","getFieldTitle","getSortDirection","order","getSortTooltip","direction","getNextSortDirection","current","FilterIcon","SearchIcon","FilterItem","onFilterChange","onFilterRemove","hideFieldSelector","hideOperatorSelector","hideRemoveButton","isFieldDropdownOpen","setIsFieldDropdownOpen","isOperatorDropdownOpen","setIsOperatorDropdownOpen","isDateRangeDropdownOpen","setIsDateRangeDropdownOpen","fieldSearchTerm","setFieldSearchTerm","containerRef","searchInputRef","setRangeType","customDates","setCustomDates","numberValue","setNumberValue","handleFieldDropdownToggle","newOpen","handleOperatorDropdownToggle","queryFields","selectedField","availableOperators","shouldShowDateRangeSelector","flexibleRangeMatch","num","found","option","filterFieldsBySearch","filteredQueryFields","filteredAllFields","getFieldTypeIcon","getFieldTypeBadge","handleFieldChange","newFieldType","defaultOperator","handleOperatorChange","handleValuesChange","handleDateRangeChange","handleRangeTypeChange","newRangeType","cubeRangeValue","handleCustomDateChange","newCustomDates","handleNumberChange","selectedRangeLabel","opt","op","AddIcon","FilterGroup","group","onGroupChange","onGroupChangeWithUnwrap","onGroupRemove","depth","showAddMenu","setShowAddMenu","isAndGroup","groupType","indentClass","borderColor","bgColor","textColor","handleGroupTypeToggle","newGroup","handleAddSimpleFilter","defaultField","newFilter","newFilters","handleAddAndGroup","handleAddOrGroup","handleFilterChange","filterIndex","handleFilterRemove","_","i","updatedGroup","handleNestedGroupChange","handleNestedGroupRemove","FilterBuilder","onFiltersChange","totalFilterCount","allFilterableFields","hasFilterableFields","andGroup","existingAndGroup","updatedAndGroup","existingOrGroup","updatedOrGroup","handleGroupChange","handleGroupChangeWithUnwrap","handleGroupRemove","handleClearAllFilters","CalendarIcon","DateRangeSelector","availableTimeDimensions","currentDateRange","onDateRangeChange","onTimeDimensionChange","onRemove","getCurrentRangeType","getCurrentDates","today","getCurrentNumber","isRangeDropdownOpen","setIsRangeDropdownOpen","isTimeDimensionDropdownOpen","setIsTimeDimensionDropdownOpen","handleTimeDimensionDropdownToggle","handleRangeDropdownToggle","handleTimeDimensionChange","newTimeDimension","DateRangeFilter","onDateRangeRemove","currentDateRanges","dateRangeCount","handleAddDateRange","firstAvailable","handleClearAllDateRanges","allTimeDimensions","t","oldTd","newTd","formatReason","reason","getReasonBadgeClasses","QueryAnalysisPanel","analysis","InfoIcon","ArrowRightIcon","TableIcon","LinkIcon","SuccessIcon","ErrorIcon","jp","idx","step","stepIdx","jc","pa","jk","w","QueryPanel","validationStatus","validationError","validationSql","validationAnalysis","onValidate","onExecute","onRemoveField","onTimeDimensionGranularityChange","onOrderChange","onClearQuery","showSettings","onSettingsClick","onAIAssistantClick","onSchemaClick","onShareClick","shareButtonState","isViewingShared","showJsonPreview","setShowJsonPreview","showSqlPreview","setShowSqlPreview","showAnalysisPreview","setShowAnalysisPreview","hasContent","selectedCount","DeleteIcon","CopyIcon","SparklesIcon","ChevronUpIcon","ChevronUpDownIcon","ShareIcon","RunIcon","CheckIcon","handleCopyQuery","textArea","hasFiltersApplied","currentFilters","hasFieldInFilters","handleAddFilterFromField","getSortIcon","handleToggleSort","next","getSortButtonClasses","sortDirection","baseClasses","RemovableChip","hasFilters","TimeDimensionChip","hasDateRange","granularity","newJsonState","newSqlState","newAnalysisState","chartConfigRegistry","barChartConfig","lineChartConfig","areaChartConfig","pieChartConfig","scatterChartConfig","bubbleChartConfig","radarChartConfig","radialBarChartConfig","treemapChartConfig","dataTableConfig","activityGridChartConfig","kpiNumberConfig","kpiDeltaConfig","kpiTextConfig","markdownConfig","ChartTypeSelector","selectedType","onTypeChange","chartTypes","chartTypeLabels","SelectedIcon","selectedLabel","type","config","label","description","useCase","tooltipText","AxisDropZone","onDrop","onDragStart","onDragEnd","onDragOver","getFieldStyling","onReorder","draggedItem","mandatory","maxItems","emptyText","dragOverIndex","setDragOverIndex","isDraggedOver","setIsDraggedOver","isReorderDraggedOver","setIsReorderDraggedOver","getCanAcceptMore","effectiveCount","getIsFull","canAcceptMore","isFull","handleGlobalDragEnd","handleReorderDragOver","targetIndex","handleReorderDragLeave","handleReorderDrop","rect","isLeavingContainer","relatedTarget","isRelatedTargetOutside","FieldIcon","hoverClasses","isDragOver","isBeingDragged","ChartConfigPanel","availableFields","onChartConfigChange","onDisplayConfigChange","setDraggedItem","getChartConfig","getFieldsForDropZone","allAvailableFields","hasChanges","newConfig","dropZone","currentFields","validFields","handleDragStart","fromAxis","fromIndex","handleDragOver","handleDragEnd","handleDrop","toAxis","fromValue","filteredValue","toValue","dz","handleRemoveFromAxis","handleReorder","toIndex","axisKey","newArray","movedItem","unassignedFields","assignedFields","color","ResultsPanel","executionStatus","executionResults","executionError","displayLimit","onDisplayLimitChange","totalRowCount","totalRowCountStatus","onChartTypeChange","activeViewProp","onActiveViewChange","TimeIcon","AdjustmentsIcon","localActiveView","setLocalActiveView","activeView","setActiveView","showChartConfig","setShowChartConfig","LoadingState","ErrorState","EmptyState","renderChart","SetupPanel","onToggle","onConfigChange","onReset","localConfig","setLocalConfig","handleApply","handleReset","defaultConfig","handleInputChange","isUsingDefaults","DEFAULT_SYSTEM_PROMPT_TEMPLATE","AI_STORAGE_KEY","DEFAULT_AI_CONFIG","sendGeminiMessage","apiKey","userPrompt","endpoint","requestBody","headers","response","errorMessage","errorData","errorText","loadAIConfig","saved","extractTextFromResponse","AIAssistantModal","onQueryLoad","aiEndpoint","handleQuerySubmit","responseText","validateResponse","handleValidate","handleUseQuery","handleClose","handleKeyDown","LZString","keyStrBase64","keyStrUriSafe","baseReverseDic","getBaseValue","alphabet","character","input","res","compressed","uncompressed","buf","TotalLen","current_value","bitsPerChar","getCharFromInt","context_dictionary","context_dictionaryToCreate","context_c","context_wc","context_w","context_enlargeIn","context_dictSize","context_numBits","context_data","context_data_val","context_data_position","ii","length","resetValue","getNextValue","dictionary","enlargeIn","dictSize","numBits","bits","resb","maxpower","power","module","MAX_HASH_LENGTH","SHARE_PREFIX","compressAndEncode","json","compressToEncodedURIComponent","decodeAndDecompress","encoded","decompressFromEncodedURIComponent","compressWithFallback","fullEncoded","queryOnlyState","queryOnlyEncoded","parseShareHash","hash","clearShareHash","url","getMaxHashLength","ShareWarningModal","maxSize","percentUsed","STORAGE_KEY","API_CONFIG_STORAGE_KEY","QueryBuilder","initialQuery","disableLocalStorage","hideSettings","enableSharing","onShare","cubeApi","updateApiConfig","getInitialApiConfig","getInitialState","parsedState","setDisplayLimit","initialChartState","setChartType","setChartConfig","setDisplayConfig","apiConfig","setApiConfig","showSetupPanel","setShowSetupPanel","showSchemaMobile","setShowSchemaMobile","schemaViewType","setSchemaViewType","showAIAssistant","setShowAIAssistant","setShareButtonState","showShareWarning","setShowShareWarning","shareWarningData","setShareWarningData","setIsViewingShared","lastValidatedQueryRef","fullValidationResult","setFullValidationResult","metaResponse","pendingSharedExecution","decoded","handleExecuteQuery","updateQuery","updater","newQuery","queryChanged","handleFieldSelect","handleFieldDeselect","newOrder","handleTimeDimensionGranularityChange","dimensionName","handleFiltersChange","handleDateRangeRemove","handleOrderChange","handleValidateQuery","queryToValidate","queryStr","isValid","debounceTimer","effectiveLimit","limitedResultSet","totalResultSet","limitedData","totalCount","handleClearQuery","handleShare","shareableState","queryOnly","queryOnlySize","handleApiConfigChange","handleResetApiConfig","handleRetrySchema","expanded","SAMPLE_QUERIES","PortletEditModal","onSave","submitText","formTitle","setFormTitle","setQuery","setDashboardFilterMapping","isValidating","setIsValidating","validationResult","setValidationResult","lastValidatedQuery","setLastValidatedQuery","dryRunData","setDryRunData","showQueryBuilder","setShowQueryBuilder","queryBuilderInitialQuery","setQueryBuilderInitialQuery","queryBuilderRef","autoPopulateChartConfig","_result","defaultWidth","defaultHeight","formattedQuery","runDryRunValidation","handleSubmit","hasQueryChanged","queryToSave","handleSampleQuery","sampleQuery","handleQueryChange","silent","isEditModeLoad","parsedQuery","details","message","errorMsg","handleOpenQueryBuilder","handleApplyQueryBuilderQuery","currentQuery","validationState","handleBackToForm","isEditMode","isQueryValidAndCurrent","sample","PortletFilterConfigModal","currentMapping","portletTitle","selectedFilters","setSelectedFilters","handleToggleFilter","filterId","handleSave","handleCancel","formatFilterPreview","valuesText","filterCount","DebugModal","timer","COLOR_PALETTES","getColorPalette","paletteName","p","ColorPaletteSelector","currentPalette","onPaletteChange","currentPaletteObj","handlePaletteSelect","palette","EyeIcon","EyeOffIcon","FilterEditModal","onDelete","convertToMetaResponse","localLabel","setLocalLabel","localFilter","setLocalFilter","showAllFields","setShowAllFields","dashboardFields","filteredSchema","filteredMeasures","fullName","filteredDimensions","filteredCubeMeta","selectedFieldInFilter","handleLabelChange","newLabel","handleFilterBuilderChange","_timeDim","validateFilter","validation","updatedFilter","ClockIcon","ReadOnlyFilterList","isTimeDimensionField","renderReadOnlyFilter","dashboardFilter","isUniversalTime","isTimeDim","dateRangeValue","_index","EditIcon","EditModeFilterList","onAddFilter","onAddTimeFilter","onEditFilter","onRemoveFilter","selectedFilterId","onFilterSelect","isCollapsed","setIsCollapsed","renderFilterChip","DashboardFilterPanel","editable","onDashboardFiltersChange","onSaveFilters","editingFilter","setEditingFilter","showFilterBuilder","setShowFilterBuilder","cubeMeta","s","generateFilterId","handleAddFilter","handleAddTimeFilter","updatedFilters","handleEditFilter","filterToEdit","handleRemoveFilter","handleSaveFilter","filterData","existingFilterIndex","handleCloseFilterBuilder","handleFilterDateRangeChange","handleReadOnlyFilterChange","ScaledGridWrapper","scaleFactor","designWidth","actualHeight","setActualHeight","innerRef","visualHeight","findScrollableAncestor","style","overflowY","overflowX","hasScrollableOverflow","hasScrollContent","MobileStackedLayout","onPortletRefresh","portletComponentRefs","setScrollContainer","setContainerRef","node","sortedPortlets","handlePortletRefresh","portletId","ScrollContainerProvider","portletHeight","headerHeight","contentHeight","el","ChartBarIcon","DesktopIcon","DashboardGrid","containerWidth","displayMode","isResponsiveEditable","useResponsiveDashboard","containerElementRef","combinedContainerRef","gridWidth","portletRefs","isInitialized","setIsInitialized","lastKnownLayout","setLastKnownLayout","setIsEditMode","setSelectedFilterId","isScrolled","setIsScrolled","isPortletModalOpen","setIsPortletModalOpen","editingPortlet","setEditingPortlet","isFilterConfigModalOpen","setIsFilterConfigModalOpen","filterConfigPortlet","setFilterConfigPortlet","debugData","setDebugData","initialLayout","handleScroll","scrollTop","hasLayoutActuallyChanged","newLayout","newItem","oldItem","item","handleLayoutChange","_layout","handleDragStop","layout","_oldItem","_newItem","_placeholder","_e","_element","mutableLayout","updatedPortlets","layoutItem","updatedConfig","handleResizeStop","portletComponent","handleAddPortlet","handleEditPortlet","handlePortletSave","portletData","isNewPortlet","newPortletId","newPortlet","gridLayout","maxY","scrollToPortlet","portletElement","handleDeletePortlet","handleDuplicatePortlet","originalPortlet","duplicatedPortlet","handlePaletteChange","handleOpenFilterConfig","handleSaveFilterConfig","mapping","handleToggleFilterForPortlet","hasFilter","handleFilterSelect","handleSelectAllForFilter","selectedFilter","canEdit","baseLayout","renderGridContent","ReactGridLayout","axis","verticalCompactor","hasSelectedFilter","isInSelectionMode","AnalyticsDashboard","propDashboardFilters","onDirtyStateChange","initialConfigRef","hasConfigChangedFromInitial","mergedDashboardFilters","configFilters","propFilters","configFilter","propFilter","pf","configIds","cf","handleSaveWithDirtyTracking","handleConfigChangeWithDirtyTracking","configString","initialConfigString","handleDashboardFiltersChange","PortletContainer","onEdit","onRefresh","DashboardEditModal","initialName","initialDescription","name","setName","setDescription","isSaving","setIsSaving"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AASA,IAAIA,KAA8B,oBAAI,IAAG,GACrCC,KAA0B,oBAAI,QAAO,GACrCC,KAAS,GACTC;AAIJ,SAASC,GAAUC,GAAM;AACvB,SAAKA,KACDJ,GAAQ,IAAII,CAAI,MACpBH,MAAU,GACVD,GAAQ,IAAII,GAAMH,GAAO,SAAQ,CAAE,IAC5BD,GAAQ,IAAII,CAAI,KAJL;AAKpB;AACA,SAASC,GAAYC,GAAS;AAC5B,SAAO,OAAO,KAAKA,CAAO,EAAE,KAAI,EAAG;AAAA,IACjC,CAACC,MAAQD,EAAQC,CAAG,MAAM;AAAA,EAC9B,EAAI,IAAI,CAACA,MACE,GAAGA,CAAG,IAAIA,MAAQ,SAASJ,GAAUG,EAAQ,IAAI,IAAIA,EAAQC,CAAG,CAAC,EACzE,EAAE,SAAQ;AACb;AACA,SAASC,GAAeF,GAAS;AAC/B,QAAMG,IAAKJ,GAAYC,CAAO;AAC9B,MAAII,IAAWX,GAAY,IAAIU,CAAE;AACjC,MAAI,CAACC,GAAU;AACb,UAAMC,IAA2B,oBAAI,IAAG;AACxC,QAAIC;AACJ,UAAMC,IAAW,IAAI,qBAAqB,CAACC,MAAY;AACrD,MAAAA,EAAQ,QAAQ,CAACC,MAAU;AACzB,YAAIC;AACJ,cAAMC,IAASF,EAAM,kBAAkBH,EAAW,KAAK,CAACM,MAAcH,EAAM,qBAAqBG,CAAS;AAC1G,QAAIZ,EAAQ,mBAAmB,OAAOS,EAAM,YAAc,QACxDA,EAAM,YAAYE,KAEnBD,IAAML,EAAS,IAAII,EAAM,MAAM,MAAM,QAAgBC,EAAI,QAAQ,CAACG,MAAa;AAC9E,UAAAA,EAASF,GAAQF,CAAK;AAAA,QACxB,CAAC;AAAA,MACH,CAAC;AAAA,IACH,GAAGT,CAAO;AACV,IAAAM,IAAaC,EAAS,eAAe,MAAM,QAAQP,EAAQ,SAAS,IAAIA,EAAQ,YAAY,CAACA,EAAQ,aAAa,CAAC,IACnHI,IAAW;AAAA,MACT,IAAAD;AAAA,MACA,UAAAI;AAAA,MACA,UAAAF;AAAA,IACN,GACIZ,GAAY,IAAIU,GAAIC,CAAQ;AAAA,EAC9B;AACA,SAAOA;AACT;AACA,SAASU,GAAQC,GAASF,GAAUb,IAAU,CAAA,GAAIgB,IAAiBpB,IAAkB;AACnF,MAAI,OAAO,OAAO,uBAAyB,OAAeoB,MAAmB,QAAQ;AACnF,UAAMC,IAASF,EAAQ,sBAAqB;AAC5C,WAAAF,EAASG,GAAgB;AAAA,MACvB,gBAAgBA;AAAA,MAChB,QAAQD;AAAA,MACR,mBAAmB,OAAOf,EAAQ,aAAc,WAAWA,EAAQ,YAAY;AAAA,MAC/E,MAAM;AAAA,MACN,oBAAoBiB;AAAA,MACpB,kBAAkBA;AAAA,MAClB,YAAYA;AAAA,IAClB,CAAK,GACM,MAAM;AAAA,IACb;AAAA,EACF;AACA,QAAM,EAAE,IAAAd,GAAI,UAAAI,GAAU,UAAAF,EAAQ,IAAKH,GAAeF,CAAO,GACnDkB,IAAYb,EAAS,IAAIU,CAAO,KAAK,CAAA;AAC3C,SAAKV,EAAS,IAAIU,CAAO,KACvBV,EAAS,IAAIU,GAASG,CAAS,GAEjCA,EAAU,KAAKL,CAAQ,GACvBN,EAAS,QAAQQ,CAAO,GACjB,WAAqB;AAC1B,IAAAG,EAAU,OAAOA,EAAU,QAAQL,CAAQ,GAAG,CAAC,GAC3CK,EAAU,WAAW,MACvBb,EAAS,OAAOU,CAAO,GACvBR,EAAS,UAAUQ,CAAO,IAExBV,EAAS,SAAS,MACpBE,EAAS,WAAU,GACnBd,GAAY,OAAOU,CAAE;AAAA,EAEzB;AACF;AAyHA,SAASgB,GAAU;AAAA,EACjB,WAAAP;AAAA,EACA,OAAAQ;AAAA,EACA,iBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,MAAAxB;AAAA,EACA,aAAAyB;AAAA,EACA,MAAAC;AAAA,EACA,eAAAC;AAAA,EACA,gBAAAT;AAAA,EACA,UAAAU;AACF,IAAI,IAAI;AACN,MAAIhB;AACJ,QAAM,CAACiB,GAAKC,CAAM,IAAIC,GAAO,SAAS,IAAI,GACpChB,IAAWgB,GAAO,OAAOH,CAAQ,GACjCI,IAAgBD,GAAO,OAAOJ,CAAa,GAC3C,CAACM,GAAOC,CAAQ,IAAIH,GAAO,SAAS;AAAA,IACxC,QAAQ,CAAC,CAACJ;AAAA,IACV,OAAO;AAAA,EACX,CAAG;AACD,EAAAZ,EAAS,UAAUa,GACnBG,GAAO;AAAA,IACL,MAAM;AAIJ,UAHIC,EAAc,YAAY,WAC5BA,EAAc,UAAUL,IAEtBD,KAAQ,CAACG,EAAK;AAClB,UAAIM;AACJ,aAAAA,IAAYnB;AAAA,QACVa;AAAA,QACA,CAAChB,GAAQF,MAAU;AACjB,gBAAMyB,IAAiBJ,EAAc;AAErC,UADAA,EAAc,UAAUnB,GACpB,EAAAuB,MAAmB,UAAU,CAACvB,OAGlCqB,EAAS;AAAA,YACP,QAAArB;AAAA,YACA,OAAAF;AAAA,UACZ,CAAW,GACGI,EAAS,WAASA,EAAS,QAAQF,GAAQF,CAAK,GAChDA,EAAM,kBAAkBc,KAAeU,MACzCA,EAAS,GACTA,IAAY;AAAA,QAEhB;AAAA,QACA;AAAA,UACE,MAAAnC;AAAA,UACA,YAAAwB;AAAA,UACA,WAAAV;AAAA;AAAA,UAEA,iBAAAS;AAAA,UACA,OAAAD;AAAA,QACV;AAAA,QACQJ;AAAA,MACR,GACa,MAAM;AACX,QAAIiB,KACFA,EAAS;AAAA,MAEb;AAAA,IACF;AAAA;AAAA;AAAA,IAGA;AAAA;AAAA,MAEE,MAAM,QAAQrB,CAAS,IAAIA,EAAU,SAAQ,IAAKA;AAAA,MAClDe;AAAA,MACA7B;AAAA,MACAwB;AAAA,MACAC;AAAA,MACAC;AAAA,MACAH;AAAA,MACAL;AAAA,MACAI;AAAA,IACN;AAAA,EACA;AACE,QAAMe,KAAezB,IAAMqB,EAAM,UAAU,OAAO,SAASrB,EAAI,QACzD0B,IAAsBP,GAAO,OAAO,MAAM;AAChD,EAAI,CAACF,KAAOQ,KAAe,CAACZ,KAAe,CAACC,KAAQY,EAAoB,YAAYD,MAClFC,EAAoB,UAAUD,GAC9BH,EAAS;AAAA,IACP,QAAQ,CAAC,CAACP;AAAA,IACV,OAAO;AAAA,EACb,CAAK,GACDK,EAAc,UAAUL;AAE1B,QAAMY,IAAS,CAACT,GAAQG,EAAM,QAAQA,EAAM,KAAK;AACjD,SAAAM,EAAO,MAAMA,EAAO,CAAC,GACrBA,EAAO,SAASA,EAAO,CAAC,GACxBA,EAAO,QAAQA,EAAO,CAAC,GAChBA;AACT;AC7SA,MAAMC,KAAcC,EAAQ,SAAS;AAgBrC,MAAqBC,WAA2BC,GAAwB;AAAA,EACtE,YAAYC,GAAc;AACxB,UAAMA,CAAK,GACX,KAAK,QAAQ;AAAA,MACX,UAAU;AAAA,MACV,OAAO;AAAA,MACP,WAAW;AAAA,IAAA;AAAA,EAEf;AAAA,EAEA,OAAO,yBAAyBC,GAAqB;AAEnD,WAAO;AAAA,MACL,UAAU;AAAA,MACV,OAAAA;AAAA,MACA,WAAW;AAAA,IAAA;AAAA,EAEf;AAAA,EAEA,kBAAkBA,GAAcC,GAA4B;AAE1D,SAAK,SAAS;AAAA,MACZ,OAAAD;AAAA,MACA,WAAWC,EAAU,kBAAkB;AAAA,IAAA,CACxC,GAGD,QAAQ,MAAM,kDAAkDD,GAAOC,CAAS;AAAA,EAClF;AAAA,EAEA,cAAc,MAAM;AAClB,SAAK,SAAS;AAAA,MACZ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,WAAW;AAAA,IAAA,CACZ;AAAA,EACH;AAAA,EAEA,SAAS;AACP,WAAI,KAAK,MAAM,WAET,KAAK,MAAM,WACN,KAAK,MAAM,WAKlB,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QAAI,WAAU;AAAA,QACb,OAAO,EAAE,aAAa,oBAAoB,iBAAiB,oBAAA;AAAA,QAC3D,UAAA;AAAA,UAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,qCAAoC,UAAA,MAAE;AAAA,UACrD,gBAAAA,EAAC,MAAA,EAAG,WAAU,2CACX,UAAA,KAAK,MAAM,eAAe,oBAAoB,KAAK,MAAM,YAAY,KAAK,0BAC7E;AAAA,UACA,gBAAAA,EAAC,KAAA,EAAE,WAAU,gDAA+C,UAAA,yFAE5D;AAAA,4BAGC,OAAA,EAAI,WAAU,yBACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,oDACb,UAAA;AAAA,YAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,uCACb,UAAA;AAAA,cAAA,gBAAAC,EAAC,YAAO,UAAA,SAAA,CAAM;AAAA,cAAS;AAAA,cAAE,KAAK,MAAM,OAAO;AAAA,YAAA,GAC7C;AAAA,YACC,KAAK,MAAM,OAAO,QACjB,gBAAAD,EAAC,OAAA,EAAI,WAAU,iDACb,UAAA;AAAA,cAAA,gBAAAC,EAAC,YAAO,UAAA,QAAA,CAAK;AAAA,cAAS;AAAA,cAAE,KAAK,MAAM,MAAM;AAAA,YAAA,GAC3C;AAAA,YAID,KAAK,MAAM,iBACV,gBAAAD,EAAC,WAAA,EAAQ,WAAU,iDACjB,UAAA;AAAA,cAAA,gBAAAC,EAAC,WAAA,EAAQ,WAAU,kBAAiB,UAAA,yBAAqB;AAAA,cACzD,gBAAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAAI,WAAU;AAAA,kBACb,OAAO,EAAE,iBAAiB,mCAAA;AAAA,kBACzB,eAAK,UAAU,KAAK,MAAM,eAAe,MAAM,CAAC;AAAA,gBAAA;AAAA,cAAA;AAAA,YACnD,GACF;AAAA,YAID,KAAK,MAAM,aACV,gBAAAD,EAAC,WAAA,EAAQ,WAAU,iDACjB,UAAA;AAAA,cAAA,gBAAAC,EAAC,WAAA,EAAQ,WAAU,kBAAiB,UAAA,cAAU;AAAA,cAC9C,gBAAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAAI,WAAU;AAAA,kBACb,OAAO,EAAE,iBAAiB,UAAA;AAAA,kBACzB,UAAA,OAAO,KAAK,MAAM,aAAc,WAC7B,KAAK,UAAU,KAAK,MAAM,KAAK,MAAM,SAAS,GAAG,MAAM,CAAC,IACxD,KAAK,UAAU,KAAK,MAAM,WAAW,MAAM,CAAC;AAAA,gBAAA;AAAA,cAAA;AAAA,YAElD,GACF;AAAA,YAGD,KAAK,MAAM,aACV,gBAAAD,EAAC,WAAA,EAAQ,WAAU,4CACjB,UAAA;AAAA,cAAA,gBAAAC,EAAC,WAAA,EAAQ,WAAU,kBAAiB,UAAA,mBAAe;AAAA,gCAClD,OAAA,EAAI,WAAU,4BAA4B,UAAA,KAAK,MAAM,UAAA,CAAU;AAAA,YAAA,EAAA,CAClE;AAAA,UAAA,EAAA,CAEJ,EAAA,CACF;AAAA,UAGA,gBAAAD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,KAAK;AAAA,cACd,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,iBAAiB;AAAA,cAAA;AAAA,cAGnB,UAAA;AAAA,gBAAA,gBAAAC,EAACR,IAAA,EAAY,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,SAAS,UAAU,aAAa,MAAA,EAAM,CAAG;AAAA,gBAAE;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAClG;AAAA,MAAA;AAAA,IAAA,IAKC,KAAK,MAAM;AAAA,EACpB;AACF;AC/HA,SAASS,GAAoBC,GAAyB;AAEpD,MAAI,YAAYA,KAAU,cAAcA,GAAQ;AAC9C,UAAMC,IAAeD;AASrB,WANyB,CAAC,OAAO,UAAU,WAAW,YAAY,EAC7C,SAASC,EAAa,QAAQ,KAK/CA,EAAa,aAAa,iBAAiBA,EAAa,YACnD,KAIF,CAAC,EAAEA,EAAa,UAAUA,EAAa,OAAO,SAAS;AAAA,EAChE;AAGA,SAAI,UAAUD,KAAU,aAAaA,IACfA,EAEa,QAAQ,OAAO,CAAAE,MAAKH,GAAoBG,CAAC,CAAC,EACvD,SAAS,IAGxB;AACT;AAQO,SAASC,GACdC,GACAC,GACU;AACV,SAAI,CAACD,KAAoB,CAACA,EAAiB,SAClC,CAAA,IAIL,CAACC,KAAiB,CAACA,EAAc,SAC5B,CAAA,IAIFD,EACJ,OAAO,CAAAE,MAAMD,EAAc,SAASC,EAAG,EAAE,CAAC,EAC1C,OAAO,CAAAA,MAAMP,GAAoBO,EAAG,MAAM,CAAC,EAC3C,IAAI,CAAAA,MAAMA,EAAG,MAAM;AACxB;AAcA,SAASC,GAAsBP,GAAqB;AAElD,MAAI,UAAUA,KAAU,aAAaA,GAAQ;AAC3C,UAAMQ,IAAcR,GACdS,IAAmBD,EAAY,QAAQ,IAAID,EAAqB;AAEtE,WAAIC,EAAY,SAAS,QAChB,EAAE,KAAKC,EAAA,IAEP,EAAE,IAAIA,EAAA;AAAA,EAEjB;AAGA,SAAOT;AACT;AAEO,SAASU,GACdN,GACAO,GACsB;AAEtB,SAAI,CAACP,KAAoBA,EAAiB,WAAW,IAC5CO,IAIL,CAACA,KAAkBA,EAAe,WAAW,IACxCP,IAUF,CAAC;AAAA,IACN,KAJiB,CAAC,GAAGA,GAAkB,GAAGO,CAAc,EAAE,IAAIJ,EAAqB;AAAA,EAI9E,CACC;AACV;AA2GO,SAASK,GACdC,GACiF;AACjF,QAAMC,wBAAe,IAAA,GACfC,wBAAiB,IAAA,GACjBC,wBAAqB,IAAA;AAG3B,SAAAH,EAAgB,SAAS,QAAQ,CAAAI,MAAW;AAC1C,QAAI;AAEF,YAAMC,IAAQ,KAAK,MAAMD,EAAQ,KAAK;AAGtC,MAAIC,EAAM,YAAY,MAAM,QAAQA,EAAM,QAAQ,KAChDA,EAAM,SAAS,QAAQ,CAACC,MAAoBL,EAAS,IAAIK,CAAO,CAAC,GAI/DD,EAAM,cAAc,MAAM,QAAQA,EAAM,UAAU,KACpDA,EAAM,WAAW,QAAQ,CAACE,MAAsBL,EAAW,IAAIK,CAAS,CAAC,GAIvEF,EAAM,kBAAkB,MAAM,QAAQA,EAAM,cAAc,KAC5DA,EAAM,eAAe,QAAQ,CAACG,MAAY;AACxC,QAAIA,EAAG,aACLL,EAAe,IAAIK,EAAG,SAAS;AAAA,MAEnC,CAAC,GAICH,EAAM,WACRI,GAAyBJ,EAAM,OAAO,EAAE,QAAQ,CAAAK,MAAS;AAGvD,QAAAR,EAAW,IAAIQ,CAAK;AAAA,MACtB,CAAC;AAAA,IAEL,SAASC,GAAG;AAEV,cAAQ,KAAK,kCAAkCP,EAAQ,IAAIO,CAAC;AAAA,IAC9D;AAAA,EACF,CAAC,GAEM,EAAE,UAAAV,GAAU,YAAAC,GAAY,gBAAAC,EAAA;AACjC;AAOA,SAASM,GAAyBG,GAA6B;AAC7D,QAAMC,IAAmB,CAAA;AAEzB,SAAAD,EAAQ,QAAQ,CAAAzB,MAAU;AACxB,IAAI,YAAYA,IAEd0B,EAAO,KAAK1B,EAAO,MAAM,IAChB,UAAUA,KAAU,aAAaA,KAE1C0B,EAAO,KAAK,GAAGJ,GAAyBtB,EAAO,OAAO,CAAC;AAAA,EAE3D,CAAC,GAEM,CAAC,GAAG,IAAI,IAAI0B,CAAM,CAAC;AAC5B;AAkBA,SAASC,GAAuB3B,GAAqD;AAEnF,MAAIA,EAAO;AACT,WAAOA,EAAO;AAEhB,MAAIA,EAAO,UAAUA,EAAO,OAAO,SAAS;AAG1C,WAAOA,EAAO,OAAO,WAAW,IAAIA,EAAO,OAAO,CAAC,IAAIA,EAAO;AAGlE;AAWO,SAAS4B,GACdxB,GACAC,GACAwB,GAC6B;AAO7B,MALI,CAACA,KAAyBA,EAAsB,WAAW,KAK3D,CAACxB,KAAiBA,EAAc,WAAW;AAC7C,WAAOwB;AAIT,QAAMC,IAAuB1B,GACzB,OAAO,CAAAE,MAAMA,EAAG,mBAAmBD,EAAc,SAASC,EAAG,EAAE,CAAC,GAChE,OAAO,CAAAA,MAAM;AAEb,QAAI,EAAE,YAAYA,EAAG,QAAS,QAAO;AACrC,UAAML,IAAeK,EAAG;AAExB,WADkBqB,GAAuB1B,CAAY,MAChC;AAAA,EACvB,CAAC;AAEH,MAAI,CAAC6B,KAAwBA,EAAqB,WAAW;AAC3D,WAAOD;AAKT,QAAM5B,IADa6B,EAAqB,CAAC,EACT,QAC1BC,IAAYJ,GAAuB1B,CAAY;AAGrD,SAAO4B,EAAsB,IAAI,CAAAR,OAAO;AAAA,IACtC,GAAGA;AAAA,IACH,WAAAU;AAAA,EAAA,EACA;AACJ;ACnWA,MAAMC,KAAmBC,GAAuD,CAAC;AAAA,EAC/E,OAAAf;AAAA,EACA,WAAAgB;AAAA,EACA,aAAAC;AAAA,EACA,eAAAC;AAAA,EACA,kBAAAhC;AAAA,EACA,wBAAAiC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,WAAWC;AAAA;AAAA,EACX,QAAAC,IAAS;AAAA,EACT,OAAOC;AAAA,EACP,cAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,kBAAAC;AACF,GAAGjE,MAAQ;AACT,QAAM,CAACkE,GAAgBC,CAAiB,IAAIC,EAAS,CAAC,GAChDC,IAAsBC,GAAOL,CAAgB,GAI7CM,IAAkBC,GAAA,GAClB,EAAE,KAAKC,GAAW,QAAAzF,EAAA,IAAWQ,GAAU;AAAA,IAC3C,MAAM+E;AAAA,IACN,YAAY;AAAA;AAAA,IACZ,aAAa;AAAA;AAAA,IACb,eAAe;AAAA;AAAA,IACf,MAAMZ;AAAA;AAAA,EAAA,CACP,GAIKe,IAAYf,KAAa3E;AAG/B,EAAA2F,GAAU,MAAM;AACd,IAAAN,EAAoB,UAAUJ;AAAA,EAChC,GAAG,CAACA,CAAgB,CAAC;AAGrB,QAAM,EAAE,QAAQW,MAAoBC,GAAetB,CAAS,GACtDuB,IAAkBF,EAAgB,cAAc,IAGhDG,IAAcC,GAAQ,MAAM;AAEhC,QAAIF;AACF,aAAO;AAGT,QAAI;AACF,YAAMG,IAAS,KAAK,MAAM1C,CAAK,GAGzB2C,IAAiBzD,GAAkB,OAAO,CAAAE,OAAM,CAACA,GAAG,eAAe,GACnEwD,IAAoB3D,GAA8B0D,GAAgBxB,CAAsB,GAGxF0B,KAAgBrD,GAAgCoD,GAAmBF,EAAO,OAAO,GAGjFI,KAAuBpC;AAAA,QAC3BxB;AAAA,QACAiC;AAAA,QACAuB,EAAO;AAAA,MAAA;AAGT,aAAO;AAAA,QACL,GAAGA;AAAA,QACH,SAASG;AAAA,QACT,gBAAgBC;AAAA,QAChB,mBAAmBnB;AAAA,MAAA;AAAA,IAEvB,SAASrB,GAAG;AACV,qBAAQ,MAAM,yCAAyCA,CAAC,GACjD;AAAA,IACT;AAAA,EACF,GAAG,CAACN,GAAO2B,GAAgBY,GAAiBrD,GAAkBiC,CAAsB,CAAC,GAI/E4B,IAAa,CAACP,KAAeD,KAAoB,CAACnB,KAAa,CAACe,GAEhE,EAAE,WAAAa,GAAW,WAAAC,GAAW,OAAAxE,EAAA,IAAUyE,GAAaV,GAAa;AAAA,IAChE,MAAMO;AAAA,IACN,wBAAwB;AAAA,EAAA,CACzB;AAGD,EAAAI,GAAoB1F,GAAK,OAAO;AAAA,IAC9B,SAAS,MAAM;AACb,MAAAmE,EAAkB,CAAAwB,MAAQA,IAAO,CAAC;AAAA,IACpC;AAAA,EAAA,IACE,CAAA,CAAE,GAINhB,GAAU,MAAM;AACd,QAAIN,EAAoB,WAAWb,KAAeuB,KAAeQ,KAAa,CAACvE,GAAO;AAUpF,YAAM4E,KATU,MAAM;AACpB,gBAAQrC,GAAA;AAAA,UACN,KAAK;AAAA,UACL,KAAK;AACH,mBAAOgC,EAAU,WAAA;AAAA,UACnB;AACE,mBAAOA,EAAU,QAAA;AAAA,QAAQ;AAAA,MAE/B,GACaM;AAEb,MAAID,KACFvB,EAAoB,QAAQ;AAAA,QAC1B,aAAab,KAAe,CAAA;AAAA,QAC5B,eAAeC,KAAiB,CAAA;AAAA,QAChC,aAAAsB;AAAA,QACA,MAAAa;AAAAA,QACA,WAAArC;AAAA,MAAA,CACD;AAAA,IAEL;AAAA,EACF,GAAG,CAACC,GAAaC,GAAesB,GAAaQ,GAAWhC,GAAWvC,CAAK,CAAC;AAIzE,QAAM8E,IAAqB,CAAChB,KAAmBF,EAAgB,UAAU,KAAK,CAAAmB,MAAQA,EAAK,cAAc,EAAI;AAE7G,MAAI,CAACvC,KAAesC;AAClB,WACE,gBAAA3E,EAAC,OAAA,EAAI,KAAKsD,GAAW,WAAU,8DAA6D,OAAO,EAAE,QAAAZ,EAAA,GACnG,UAAA,gBAAA3C,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,0BAAsB;AAAA,MAClE,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCAAiC,UAAA,8BAAA,CAA2B;AAAA,IAAA,EAAA,CAC7E,EAAA,CACF;AAKJ,MAAI,CAAC2D,KAAmB,CAACnB,KAAa,CAACe;AACrC,WACE,gBAAAvD,EAAC,OAAA,EAAI,KAAKsD,GAAW,WAAU,8DAA6D,OAAO,EAAE,QAAAZ,EAAA,GACnG,UAAA,gBAAA3C,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,0EAAA,CAA0E;AAAA,MACzF,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCAAiC,UAAA,iBAAA,CAAc;AAAA,IAAA,EAAA,CAChE,EAAA,CACF;AAKJ,MAAI,CAAC2D,GAAiB;AACpB,QAAIU,KAAcT,KAAe,CAACQ,KAAa,CAACvE;AAC9C,aACE,gBAAAG,EAAC,OAAA,EAAI,KAAKsD,GAAW,WAAU,2CAA0C,OAAO,EAAE,QAAAZ,EAAA,GAC/E,UAAAG,KAAoB,gBAAA7C,EAAC6E,IAAA,EAAiB,MAAK,MAAK,GACnD;AAIJ,QAAIhF;AACF,aACE,gBAAAE,EAAC,OAAA,EAAI,KAAKuD,GAAW,WAAU,yBAAwB,OAAO,EAAE,QAAAZ,GAAQ,aAAa,oBAAoB,iBAAiB,uBACxH,UAAA;AAAA,QAAA,gBAAA1C,EAAC,SAAI,WAAU,QACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,uBAAsB,OAAO,EAAE,OAAO,iBAAA,GAAoB,UAAA,iBAAA,CAAc;AAAA,UACxF,gBAAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAMgD,EAAkB,CAAAwB,MAAQA,IAAO,CAAC;AAAA,cACjD,WAAU;AAAA,cACV,OAAO,EAAE,iBAAiB,oBAAA;AAAA,cAC3B,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAED,EAAA,CACF,EAAA,CACF;AAAA,QAEA,gBAAAxE,EAAC,SAAI,WAAU,QACb,4BAAC,OAAA,EAAI,WAAU,iCAAgC,OAAO,EAAE,OAAO,4BAA4B,iBAAiB,qBAAqB,aAAa,mBAAA,GAC3I,YAAM,WAAWH,EAAM,SAAA,EAAS,CACnC,EAAA,CACF;AAAA,QAEA,gBAAAE,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,WAAA,EACC,UAAA;AAAA,YAAA,gBAAAC,EAAC,WAAA,EAAQ,WAAU,8BAA6B,OAAO,EAAE,OAAO,2BAAA,GAA8B,UAAA,+BAAA,CAA4B;AAAA,8BACzH,OAAA,EAAI,WAAU,sDAAqD,OAAO,EAAE,iBAAiB,mCAAA,GAC3F,UAAA4D,IAAc,KAAK,UAAUA,GAAa,MAAM,CAAC,IAAIxC,EAAA,CACxD;AAAA,UAAA,GACF;AAAA,4BAEC,WAAA,EACC,UAAA;AAAA,YAAA,gBAAApB,EAAC,WAAA,EAAQ,WAAU,8BAA6B,OAAO,EAAE,OAAO,2BAAA,GAA8B,UAAA,eAAA,CAAY;AAAA,YAC1G,gBAAAA,EAAC,OAAA,EAAI,WAAU,sDAAqD,OAAO,EAAE,iBAAiB,oCAAA,GAC3F,UAAA,KAAK,UAAU;AAAA,cACd,WAAAoC;AAAA,cACA,aAAAC;AAAA,cACA,eAAAC;AAAA,YAAA,GACC,MAAM,CAAC,EAAA,CACZ;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,GACF;AAIJ,QAAI,CAAC8B,KAAa,CAACR;AACjB,aACE,gBAAA5D,EAAC,OAAA,EAAI,KAAKsD,GAAW,WAAU,8DAA6D,OAAO,EAAE,QAAAZ,EAAA,GACnG,UAAA,gBAAA3C,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,qBAAiB;AAAA,QAC7D,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAU,UAAA,8BAAA,CAA2B;AAAA,MAAA,EAAA,CACtD,EAAA,CACF;AAAA,EAGN;AAuBA,QAAMyE,KApBU,MAAM;AAEpB,QAAId;AACF,aAAO,CAAA;AAIT,QAAI,CAACS;AACH,aAAO,CAAA;AAGT,YAAQhC,GAAA;AAAA,MACN,KAAK;AAAA,MACL,KAAK;AACH,eAAOgC,EAAU,WAAA;AAAA,MACnB;AACE,eAAOA,EAAU,QAAA;AAAA,IAAQ;AAAA,EAE/B,GAEa;AAuDb,SACE,gBAAApE,EAAC,OAAA,EAAI,KAAKsD,GAAW,WAAU,iBAC7B,UAAA,gBAAAtD;AAAA,IAACN;AAAA,IAAA;AAAA,MACC,cAAciD;AAAA,MACd,eAAe;AAAA,QACb,WAAAP;AAAA,QACA,aAAAC;AAAA,QACA,eAAAC;AAAA,QACA,QAAAI;AAAA,MAAA;AAAA,MAEF,WAAWtB;AAAA,MAEX,UAAA,gBAAApB,EAAC,OAAA,EAAI,WAAU,sCAAqC,OAAO,EAAE,WAAW,QAAA,GACrE,WAhEW,MAAM;AACxB,YAAI;AACF,gBAAM8E,IAAcpC;AAGpB,iBAAKqC,GAAiB3C,CAAS,IAe7B,gBAAApC;AAAA,YAACgF;AAAA,YAAA;AAAA,cACC,WAAA5C;AAAA,cACA,MALcA,MAAc,aAAa,CAAA,IAAKqC;AAAA,cAM9C,aAAApC;AAAA,cACA,eAAAC;AAAA,cACA,aAAasB,KAAe;AAAA,cAC5B,QAAQkB;AAAA,cACR,cAAAlC;AAAA,cACA,UACE,gBAAA5C;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO,EAAE,QAAQ,OAAO8E,KAAgB,WAAW,GAAGA,CAAW,OAAOA,EAAA;AAAA,kBAExE,UAAA,gBAAA9E,EAAC,OAAA,EAAI,WAAU,4EAAA,CAA4E;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC7F;AAAA,UAAA,IA3BF,gBAAAA,EAAC,OAAA,EAAI,WAAU,2CAA0C,OAAO,EAAE,QAAA0C,EAAA,GAChE,UAAA,gBAAA3C,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,0BAAsB;AAAA,YAClE,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAW,UAAAoC,EAAA,CAAU;AAAA,UAAA,EAAA,CACtC,EAAA,CACF;AAAA,QA0BN,SAASvC,GAAO;AACd,yBAAQ,MAAM,0BAA0BA,CAAK,GAE3C,gBAAAG,EAAC,OAAA,EAAI,WAAU,kEAAiE,OAAO,EAAE,QAAA0C,EAAA,GACvF,UAAA,gBAAA3C,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,0BAAsB;AAAA,YAClE,gBAAAA,EAAC,SAAI,WAAU,kCAAkC,UAAAH,aAAiB,QAAQA,EAAM,UAAU,gBAAA,CAAgB;AAAA,UAAA,EAAA,CAC5G,EAAA,CACF;AAAA,QAEJ;AAAA,MACF,GAeS,EAAY,CACf;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ,CAAC;AAEDqC,GAAiB,cAAc;AC5T/B,MAAM+C,KAA8B,CAAC;AAAA,EACnC,QAAAC;AAAA,EACA,SAAAC;AAAA,EACA,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,sBAAAC,IAAuB;AAAA,EACvB,eAAAC,IAAgB;AAAA,EAChB,iBAAAC,IAAkB;AAAA,EAClB,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,WAAAC,IAAY;AACd,MAAM;AAEJ,QAAMC,IAAkBC,EAAY,CAACC,MAAyB;AAC5D,IAAIA,EAAM,QAAQ,YAAYP,KAC5BJ,EAAA;AAAA,EAEJ,GAAG,CAACI,GAAeJ,CAAO,CAAC;AA0B3B,SAtBA3B,GAAU,OACJ0B,KAEEK,KACF,SAAS,iBAAiB,WAAWK,CAAe,GAItD,SAAS,KAAK,MAAM,WAAW,YAG/B,SAAS,KAAK,MAAM,WAAW,SAI1B,MAAM;AACX,aAAS,oBAAoB,WAAWA,CAAe,GACvD,SAAS,KAAK,MAAM,WAAW;AAAA,EACjC,IACC,CAACV,GAAQK,GAAeK,CAAe,CAAC,GAGtCV,IA0BH,gBAAAlF;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,uCAAuCqF,MAAS,sBAAsB,mDAAmD,kCAAkC;AAAA,MACtK,OAAO,EAAE,iBAAiB,oBAAA;AAAA,MAC1B,SAASC,IAAuBH,IAAU;AAAA,MAE1C,UAAA,gBAAApF;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,kDAAkDsF,MAAS,sBAAsB,+BAA+B,YAAY,IAAIA,MAAS,gBAAgBA,MAAS,sBAAsB,KAAK,MAAM,KA9B7L,MAAM;AAC3B,oBAAQA,GAAA;AAAA,cACN,KAAK;AACH,uBAAO;AAAA,cACT,KAAK;AACH,uBAAO;AAAA,cACT,KAAK;AACH,uBAAO;AAAA,cACT,KAAK;AACH,uBAAO;AAAA,cACT,KAAK;AACH,uBAAO;AAAA;AAAA,cACT,KAAK;AACH,uBAAO;AAAA,cACT,KAAK;AACH,uBAAO;AAAA,cACT,KAAK;AACH,uBAAO;AAAA,cACT;AACE,uBAAO;AAAA,YAAA;AAAA,UAEb,IASwO,IAAIA,MAAS,gBAAgBA,MAAS,sBAAsB,KAAK,cAAc;AAAA,UACjT,OAAO,EAAE,WAAW,uBAAA;AAAA,UACpB,SAAS,CAAC3D,MAAMA,EAAE,gBAAA;AAAA,UAClB,MAAK;AAAA,UACL,cAAW;AAAA,UACX,mBAAiB0D,IAAQ,gBAAgB;AAAA,UAGvC,UAAA;AAAA,aAAAA,KAASI,MACT,gBAAAzF,EAAC,OAAA,EAAI,WAAU,yEACZ,UAAA;AAAA,cAAAqF,uBACE,MAAA,EAAG,IAAG,eAAc,WAAU,sCAC5B,UAAAA,GACH;AAAA,cAEDI,KACC,gBAAAxF;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAASmF;AAAA,kBACT,WAAU;AAAA,kBACV,cAAW;AAAA,kBAEX,UAAA,gBAAAnF,EAAC,SAAI,OAAM,MAAK,QAAO,MAAK,MAAK,QAAO,SAAQ,aAAY,QAAO,gBACjE,UAAA,gBAAAA,EAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,uBAAA,CAAuB,EAAA,CAC9F;AAAA,gBAAA;AAAA,cAAA;AAAA,YACF,GAEJ;AAAA,YAIF,gBAAAA,EAAC,SAAI,WAAW,0BAA0B2F,IAAY,KAAK,WAAW,IACnE,UAAAF,GACH;AAAA,YAGCC,KACC,gBAAA1F,EAAC,OAAA,EAAI,WAAU,uGACZ,UAAA0F,EAAA,CACH;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAEJ;AAAA,EAAA,IAzEgB;AA4EtB;AChIO,SAASK,GACdC,GACAC,IAAoB,WACA;AACpB,QAAMC,IAAgBC,GAAmBH,CAAW;AACpD,SAAO,gBAAAhG,EAACkG,KAAc,WAAAD,GAAsB;AAC9C;ACCA,MAAMG,KAA0BC;AAAA,EAAK,MACnC,OAAO,4BAA4B,EAAE,KAAK,QAAQ,EAAE,SAASC,EAAI,0BAA0B;AAC7F,GAIMC,KAAoD,CAAC;AAAA,EACzD,QAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,YAAAC,IAAa;AACf,MAAM;AAEJ,QAAMC,IAAkBzH,EAAQ,aAAa,GACvC0H,IAAmB1H,EAAQ,cAAc,GACzC2H,IAAc3H,EAAQ,SAAS,GAC/BD,IAAcC,EAAQ,SAAS,GAC/B4H,IAAe5H,EAAQ,UAAU,GACjC6H,IAAc7H,EAAQ,SAAS,GAC/B8H,IAAgB9H,EAAQ,WAAW,GACnC+H,IAAoB/H,EAAQ,eAAe,GAC3CgI,IAAchI,EAAQ,SAAS,GAC/BiI,IAAWjI,EAAQ,MAAM,GAGzB,EAAE,UAAAkI,EAAA,IAAaC,GAAA,GACfC,IAAoBF,GAAU,sBAAsB,IAEpD,CAACG,GAAeC,CAAgB,IAAI9E,EAAsB,oBAAI,KAAK,GACnE,CAAC+E,GAAkBC,CAAmB,IAAIhF,EAAsB,oBAAI,KAAK,GACzE,CAACiF,GAAYC,CAAa,IAAIlF,EAAS,EAAE,GACzC,CAACmF,GAAUC,CAAW,IAAIpF,EAAyB,MAAM,GAGzD,CAACqF,GAAwBC,CAAyB,IAAItF,EAA6B,IAAI,GACvF,CAACuF,GAA2BC,CAA4B,IAAIxF,EAA6B,IAAI;AAsFnG,MAnFAyF,GAAM,UAAU,MAAM;AACpB,IAAIzB,KAAcY,KAChBQ,EAAY,SAAS;AAAA,EAEzB,GAAG,CAACpB,GAAYY,CAAiB,CAAC,GAGlCa,GAAM,UAAU,MAAM;AACpB,QAAI,CAAClC;AACH;AAKF,QAFsB0B,EAAW,KAAA,EAAO,SAAS,GAE9B;AAEjB,MAAII,MAA2B,SAC7BC,EAA0B,IAAI,IAAIT,CAAa,CAAC,GAChDW,EAA6B,IAAI,IAAIT,CAAgB,CAAC;AAGxD,YAAMW,wBAAuB,IAAA,GACvBC,yBAA0B,IAAA;AAEhC,MAAApC,EAAO,MAAM,QAAQ,CAACqC,MAAmB;AACvC,YAAIC,IAAiB;AAOrB,QAJyBD,EAAK,SAAS;AAAA,UAAO,QAC5CpH,GAAM,KAAK,YAAA,EAAc,SAASyG,EAAW,YAAA,CAAa,KAC1DzG,GAAM,MAAM,YAAA,EAAc,SAASyG,EAAW,aAAa;AAAA,QAAA,EAExC,SAAS,MAC5BY,IAAiB,IACjBF,GAAoB,IAAI,GAAGC,EAAK,IAAI,WAAW,IAIvBA,EAAK,WAAW,OAAO,CAAAE,OAAKA,GAAE,SAAS,MAAM,EAC1B;AAAA,UAAO,QAClDtH,GAAM,KAAK,YAAA,EAAc,SAASyG,EAAW,YAAA,CAAa,KAC1DzG,GAAM,MAAM,YAAA,EAAc,SAASyG,EAAW,aAAa;AAAA,QAAA,EAEtC,SAAS,MAC9BY,IAAiB,IACjBF,GAAoB,IAAI,GAAGC,EAAK,IAAI,aAAa,IAI5BA,EAAK,WAAW,OAAO,CAAAE,OAAKA,GAAE,SAAS,MAAM,EACtB;AAAA,UAAO,QACnDtH,GAAM,KAAK,YAAA,EAAc,SAASyG,EAAW,YAAA,CAAa,KAC1DzG,GAAM,MAAM,YAAA,EAAc,SAASyG,EAAW,aAAa;AAAA,QAAA,EAElC,SAAS,MAClCY,IAAiB,IACjBF,GAAoB,IAAI,GAAGC,EAAK,IAAI,iBAAiB,IAInDC,KACFH,EAAiB,IAAIE,EAAK,IAAI;AAAA,MAElC,CAAC;AAGD,YAAMG,KAAgB,oBAAI,IAAI,CAAC,GAAIV,KAA0B,CAAA,GAAK,GAAGK,CAAgB,CAAC,GAChFM,IAAmB,oBAAI,IAAI,CAAC,GAAIT,KAA6B,CAAA,GAAK,GAAGI,EAAmB,CAAC;AAE/F,MAAAb,EAAiBiB,EAAa,GAC9Bf,EAAoBgB,CAAgB;AAAA,IACtC;AAEE,MAAIX,MAA2B,QAAQE,MAA8B,SACnET,EAAiBO,CAAsB,GACvCL,EAAoBO,CAAyB,GAC7CD,EAA0B,IAAI,GAC9BE,EAA6B,IAAI;AAAA,EAGvC,GAAG,CAACjC,GAAQ0B,GAAYI,GAAwBE,CAAyB,CAAC,GAGtE/B,MAAiB;AACnB,6BACG,OAAA,EAAI,WAAU,8DACb,UAAA,gBAAA1G,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,SAAI,WAAU,6DAA4D,OAAO,EAAE,mBAAmB,uBAAuB;AAAA,MAC9H,gBAAAA,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,qBAAiB;AAAA,MAC7D,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAU,UAAA,yBAAA,CAAsB;AAAA,IAAA,EAAA,CACjD,EAAA,CACF;AAKJ,MAAIyG,MAAiB,SAAS;AAC5B,UAAMyC,IAAcxC,GAAa,YAAA,EAAc,SAAS,MAAM,KAC3CA,GAAa,cAAc,SAAS,OAAO;AAE9D,6BACG,OAAA,EAAI,WAAU,2CACb,UAAA,gBAAA3G,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,MAAA,gBAAAC,EAACoH,GAAA,EAAY,WAAU,sCAAA,CAAsC;AAAA,MAC7D,gBAAApH,EAAC,OAAA,EAAI,WAAU,2CAA0C,UAAA,yBAEzD;AAAA,MACA,gBAAAA,EAAC,OAAA,EAAI,WAAU,uCACZ,UAAAkJ,IACC,gBAAAlJ,EAAAmJ,IAAA,EAAE,UAAA,4EAAA,CAEF,IAEA,gBAAAnJ,EAAAmJ,IAAA,EACG,UAAAzC,KAAe,uCAAA,CAClB,GAEJ;AAAA,MAEA,gBAAA3G,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,QAAA+G,KACC,gBAAA/G;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS+G;AAAA,YACT,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAA9G,EAACR,GAAA,EAAY,WAAU,UAAA,CAAU;AAAA,cACjC,gBAAAQ,EAAC,UAAK,UAAA,QAAA,CAAK;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAId+G,KACC,gBAAAhH;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAASgH;AAAA,YACT,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAA/G,EAACqH,GAAA,EAAa,WAAU,UAAA,CAAU;AAAA,cAClC,gBAAArH,EAAC,UAAK,UAAA,qBAAA,CAAkB;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAC1B,GAEJ;AAAA,MAECkJ,uBACE,OAAA,EAAI,WAAU,2DACb,UAAA,gBAAAnJ,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,oBAAmB,UAAA,qBAAiB;AAAA,QACnD,gBAAAD,EAAC,MAAA,EAAG,WAAU,mCACZ,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAG,UAAA,qCAAA,CAAkC;AAAA,UACtC,gBAAAA,EAAC,QAAG,UAAA,kCAAA,CAA+B;AAAA,UACnC,gBAAAA,EAAC,QAAG,UAAA,sCAAA,CAAmC;AAAA,QAAA,EAAA,CACzC;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,IAAA,EAAA,CAEJ,EAAA,CACF;AAAA,EAEJ;AAGA,MAAI,CAACwG;AACH,6BACG,OAAA,EAAI,WAAU,8DACb,UAAA,gBAAAzG,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,aAAS;AAAA,MACrD,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAU,UAAA,oBAAA,CAAiB;AAAA,IAAA,EAAA,CAC5C,EAAA,CACF;AAIJ,QAAMoJ,IAAsB,CAACC,MAAqB;AAChD,UAAMC,IAAc,IAAI,IAAIxB,CAAa;AASzC,QARIwB,EAAY,IAAID,CAAQ,IAC1BC,EAAY,OAAOD,CAAQ,IAE3BC,EAAY,IAAID,CAAQ,GAE1BtB,EAAiBuB,CAAW,GAGxBhB,MAA2B,MAAM;AACnC,YAAMiB,KAAuB,IAAI,IAAIjB,CAAsB;AAC3D,MAAIiB,GAAqB,IAAIF,CAAQ,IACnCE,GAAqB,OAAOF,CAAQ,IAEpCE,GAAqB,IAAIF,CAAQ,GAEnCd,EAA0BgB,EAAoB;AAAA,IAChD;AAAA,EACF,GAEMC,KAAyB,CAACC,MAAuB;AACrD,UAAMH,IAAc,IAAI,IAAItB,CAAgB;AAS5C,QARIsB,EAAY,IAAIG,CAAU,IAC5BH,EAAY,OAAOG,CAAU,IAE7BH,EAAY,IAAIG,CAAU,GAE5BxB,EAAoBqB,CAAW,GAG3Bd,MAA8B,MAAM;AACtC,YAAMe,KAAuB,IAAI,IAAIf,CAAyB;AAC9D,MAAIe,GAAqB,IAAIE,CAAU,IACrCF,GAAqB,OAAOE,CAAU,IAEtCF,GAAqB,IAAIE,CAAU,GAErChB,EAA6Bc,EAAoB;AAAA,IACnD;AAAA,EACF,GAEMG,KAAmB,CAACjI,GAAkBkI,MAA4D;AActG,KAboB,MAAM;AACxB,cAAQA,GAAA;AAAA,QACN,KAAK;AACH,iBAAOhD,EAAe,SAAS,SAASlF,EAAM,IAAI;AAAA,QACpD,KAAK;AACH,iBAAOkF,EAAe,WAAW,SAASlF,EAAM,IAAI;AAAA,QACtD,KAAK;AACH,iBAAOkF,EAAe,eAAe,SAASlF,EAAM,IAAI;AAAA,QAC1D;AACE,iBAAO;AAAA,MAAA;AAAA,IAEb,GAAA,IAGEoF,EAAgBpF,EAAM,MAAMkI,CAAS,IAErC/C,EAAcnF,EAAM,MAAMkI,CAAS;AAAA,EAEvC,GAEMC,KAAe,CAAChI,MACfsG,IACEtG,EAAO;AAAA,IAAO,OACnBH,EAAM,KAAK,YAAA,EAAc,SAASyG,EAAW,YAAA,CAAa,KAC1DzG,EAAM,MAAM,YAAA,EAAc,SAASyG,EAAW,aAAa;AAAA,EAAA,IAHrCtG,GAOpBkH,KAAiB,CAACD,MAA4B;AAClD,QAAI,CAACX,EAAW,KAAA,EAAQ,QAAO;AAE/B,UAAM2B,IAAiBhB,EAAK,SAAS;AAAA,MAAK,QACxCpH,GAAM,KAAK,YAAA,EAAc,SAASyG,EAAW,YAAA,CAAa,KAC1DzG,GAAM,MAAM,YAAA,EAAc,SAASyG,EAAW,aAAa;AAAA,IAAA,GAGvD4B,KAAmBjB,EAAK,WAAW;AAAA,MAAK,QAC5CpH,GAAM,KAAK,YAAA,EAAc,SAASyG,EAAW,YAAA,CAAa,KAC1DzG,GAAM,MAAM,YAAA,EAAc,SAASyG,EAAW,aAAa;AAAA,IAAA;AAG7D,WAAO2B,KAAkBC;AAAA,EAC3B,GAEMC,KAID,CAAC,EAAE,OAAAtI,GAAO,WAAAkI,GAAW,MAAAK,SAAW;AACnC,UAAMC,MAAc,MAAM;AACxB,cAAQN,GAAA;AAAA,QACN,KAAK;AACH,iBAAOhD,EAAe,SAAS,SAASlF,EAAM,IAAI;AAAA,QACpD,KAAK;AACH,iBAAOkF,EAAe,WAAW,SAASlF,EAAM,IAAI;AAAA,QACtD,KAAK;AACH,iBAAOkF,EAAe,eAAe,SAASlF,EAAM,IAAI;AAAA,QAC1D;AACE,iBAAO;AAAA,MAAA;AAAA,IAEb,GAAA,GAEMyI,IAAoB,MAAM;AAC9B,UAAI,CAACD,GAAY,QAAO;AAExB,cAAQN,GAAA;AAAA,QACN,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,MAAA;AAAA,IAEb,GAEMQ,IAAe,MAAM;AACzB,UAAI,CAACF,GAAY,QAAO;AAExB,cAAQN,GAAA;AAAA,QACN,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,MAAA;AAAA,IAEb,GAEMS,IAAoB,MAAM;AAC9B,cAAQT,GAAA;AAAA,QACN,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,MAAA;AAAA,IAEb;AAEA,WACE,gBAAA5J;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,qFAAqFmK,EAAA,CAAmB;AAAA,QACnH,SAAS,MAAMR,GAAiBjI,GAAOkI,CAAS;AAAA,QAChD,OAAOlI,EAAM,eAAeA,EAAM;AAAA,QAElC,UAAA;AAAA,UAAA,gBAAAzB,EAAC,OAAA,EAAI,WAAW,UAAUmK,EAAA,CAAc,IACrC,UAAAzB,GAAM,aAAasB,IAA4B,EAAE,WAAW,UAAA,CAAW,GAC1E;AAAA,UACA,gBAAAjK,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,gCAAgC,UAAAyB,EAAM,YAAW;AAAA,YAChE,gBAAAzB,EAAC,OAAA,EAAI,WAAU,uCAAuC,YAAM,KAAA,CAAK;AAAA,UAAA,GACnE;AAAA,UACCiK,MACC,gBAAAjK,EAAC,OAAA,EAAI,WAAW,UAAUoK,GAAmB,IAC3C,UAAA,gBAAApK,EAAC,OAAA,EAAI,WAAU,WAAU,MAAK,gBAAe,SAAQ,aACnD,UAAA,gBAAAA,EAAC,QAAA,EAAK,UAAS,WAAU,GAAE,sHAAqH,UAAS,UAAA,CAAU,EAAA,CACrK,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR,GAEMqK,KAKD,CAAC,EAAE,OAAAjF,GAAO,OAAAkF,GAAO,YAAAb,IAAY,MAAAO,SAAW;AAC3C,UAAM/C,IAAae,EAAiB,IAAIyB,EAAU,GAG5Cc,IAAiB,MACjBd,GAAW,SAAS,aAAa,KAAK,CAACA,GAAW,SAAS,iBAAiB,IACvE,eACEA,GAAW,SAAS,iBAAiB,IACvC,mBAEA;AAkBX,WACE,gBAAA1J;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,0GAhBgB,MAAM;AAEnC,kBADoBwK,EAAA,GACZ;AAAA,YACN,KAAK;AACH,qBAAO;AAAA,YACT,KAAK;AACH,qBAAO;AAAA,YACT,KAAK;AACH,qBAAO;AAAA,YACT;AACE,qBAAO;AAAA,UAAA;AAAA,QAEb,GAIwH,CAAwB;AAAA,QAC5I,SAAS,MAAMf,GAAuBC,EAAU;AAAA,QAEhD,UAAA;AAAA,UAAA,gBAAAzJ,EAAC,OAAA,EAAI,WAAU,UACZ,UAAAiH,IACC,gBAAAjH,EAACkH,GAAA,EAAgB,WAAU,UAAA,CAAU,IAErC,gBAAAlH,EAACmH,GAAA,EAAiB,WAAU,WAAU,GAE1C;AAAA,UACA,gBAAAnH,EAAC,OAAA,EAAI,WAAU,UACZ,UAAAgK,IACH;AAAA,UACA,gBAAAhK,EAAC,QAAA,EAAK,WAAU,UAAU,UAAAoF,GAAM;AAAA,UAChC,gBAAApF,EAAC,QAAA,EAAK,WAAU,iFACb,UAAAsK,EAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN,GAEME,KAA6B,MACjC,gBAAAxK,EAAC,OAAA,EAAI,WAAU,qDACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,IAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qBAAoB,MAAK,QAAO,SAAQ,aAAY,QAAO,gBACxE,UAAA,gBAAAA,EAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,KAAK,GAAE,8CAAA,CAA8C,EAAA,CACvH,EAAA,CACF;AAAA,IACA,gBAAAA,EAAC,OAAA,EAAI,WAAU,yCAAwC,UAAA,oBAAgB;AAAA,IACvE,gBAAAD,EAAC,OAAA,EAAI,WAAU,mCAAkC,UAAA;AAAA,MAAA;AAAA,MACZmI;AAAA,MAAW;AAAA,IAAA,GAChD;AAAA,IACA,gBAAAlI;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS,MAAMmI,EAAc,EAAE;AAAA,QAC/B,WAAU;AAAA,QACX,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAED,EAAA,CACF,EAAA,CACF;AAGF,SACE,gBAAApI,EAAC,OAAA,EAAI,WAAU,iFAEb,UAAA;AAAA,IAAA,gBAAAC,EAAC,SAAI,WAAU,6BACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,OAAA,EACC,4BAAC,MAAA,EAAG,WAAU,wCACX,UAAAoI,MAAa,YAAY,mBAAmB,kBAAA,CAC/C,EAAA,CACF;AAAA,QACA,gBAAApI,EAAC,OAAA,EAAI,WAAU,+BACZ,UAAA+G,KACC,gBAAA/G;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS+G;AAAA,YACT,WAAU;AAAA,YACV,OAAM;AAAA,YAEN,UAAA,gBAAA/G,EAACqH,GAAA,EAAa,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA,EACpC,CAEJ;AAAA,MAAA,GACF;AAAA,MAGA,gBAAAtH,EAAC,OAAA,EAAI,WAAU,gCACZ,UAAA;AAAA,QAAA8H,IACC,gBAAA9H,EAAC,OAAA,EAAI,WAAU,yDACb,UAAA;AAAA,UAAA,gBAAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAM;AACb,gBAAAsI,EAAY,MAAM,GAClBrB,IAAmB,MAAM;AAAA,cAC3B;AAAA,cACA,WAAW;AAAA;AAAA,sBAEPoB,MAAa,SACX,yCACA,2CACJ;AAAA;AAAA,cAGF,UAAA;AAAA,gBAAA,gBAAApI,EAAC0H,GAAA,EAAS,WAAU,iBAAA,CAAiB;AAAA,gBAAE;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGzC,gBAAA3H;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAM;AACb,gBAAAsI,EAAY,SAAS,GACrBrB,IAAmB,SAAS;AAAA,cAC9B;AAAA,cACA,WAAW;AAAA;AAAA,sBAEPoB,MAAa,YACX,yCACA,2CACJ;AAAA;AAAA,cAGF,UAAA;AAAA,gBAAA,gBAAApI,EAACyH,GAAA,EAAY,WAAU,iBAAA,CAAiB;AAAA,gBAAE;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAE5C,EAAA,CACF,IACE;AAAA,QAGJ,gBAAA1H,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,aAAY;AAAA,cACZ,OAAOkI;AAAA,cACP,UAAU,CAACxG,MAAMyG,EAAczG,EAAE,OAAO,KAAK;AAAA,cAC7C,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAEZ,gBAAA1B,EAAC,OAAA,EAAI,WAAU,yEACb,UAAA,gBAAAA,EAAC,SAAI,WAAU,8BAA6B,MAAK,QAAO,SAAQ,aAAY,QAAO,gBACjF,UAAA,gBAAAA,EAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,8CAAA,CAA8C,EAAA,CACrH,EAAA,CACF;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,EAAA,CACF,EAAA,CAEF;AAAA,IAGA,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCACZ,gBAAa,aAAa6H;AAAA;AAAA,wBAExB,OAAA,EAAI,WAAU,UACb,UAAA,gBAAA7H,EAACyK,MAAS,UACR,gBAAAzK,EAAC,OAAA,EAAI,WAAU,2CACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oCAAmC,UAAA,qBAAA,CAAkB,GACtE,GAEF,UAAA,gBAAAA;AAAA,QAACoG;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,aAAa,CAACiD,MAAa;AACzB,YAAKpC,MAEHc,EAAiB,CAAAvD,0BAAY,IAAI,CAAC,GAAGA,GAAM6E,CAAQ,CAAC,CAAC,GAErDhB,EAAY,MAAM;AAAA,UAEtB;AAAA,UACA,cAAc,CAACgB,GAAUqB,GAAWf,OAAc;AAEhD,gBAAIgB;AAEJ,YAAIhB,OAAc,YAChBgB,KAAc,aAQdA,KALanE,GAAQ,MAAM,KAAK,CAAAoE,OAAKA,GAAE,SAASvB,CAAQ,GAChC,WAAW;AAAA,cAAK,CAAAN,OACtCA,GAAE,SAAS,GAAGM,CAAQ,IAAIqB,CAAS,MAAM3B,GAAE,SAAS2B;AAAA,YAAA,GAG7B,SAAS,SAAS,mBAAmB;AAGhE,kBAAMG,IAAgB,GAAGxB,CAAQ,IAAIqB,CAAS;AAK9C,YAFmB/D,EAAegE,EAAW,EAAE,SAASE,CAAa,IAInEhE,EAAgBgE,GAAeF,EAAW,IAG1C/D,EAAciE,GAAeF,EAAW;AAAA,UAE5C;AAAA,UACA,kBAAkB;AAAA,YAChB,GAAGhE,EAAe,SAAS,IAAI,CAAAlF,MAASA,EAAM,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,YAC3D,GAAGkF,EAAe,WAAW,IAAI,CAAAlF,MAASA,EAAM,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,YAC7D,GAAGkF,EAAe,eAAe,IAAI,CAAAlF,MAASA,EAAM,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,UAAA,EACjE,OAAO,CAACoH,GAAMiC,GAAOC,OAAQA,GAAI,QAAQlC,CAAI,MAAMiC,CAAK;AAAA,UAC1D,mBAAmB;AAAA,YACjB,GAAGnE,EAAe;AAAA,YAClB,GAAGA,EAAe;AAAA,YAClB,GAAGA,EAAe;AAAA,UAAA;AAAA,UAEpB,YAAAuB;AAAA,QAAA;AAAA,MAAA,GAEF,EAAA,CACF;AAAA;AAAA;AAAA,MAGA,gBAAAlI,EAAC,OAAA,EAAI,WAAU,wCACX,WAAA,MAAM;AAEN,cAAMgL,IAAgBxE,EAAO,MAAM,OAAOsC,EAAc;AAGxD,eAAIZ,EAAW,KAAA,KAAU8C,EAAc,WAAW,sBACxCR,IAAA,EAAiB,IAGpBQ,EAAc,IAAI,CAACnC,MAAmB;AAC3C,gBAAM5B,KAAaa,EAAc,IAAIe,EAAK,IAAI,GACxC3H,KAAiB2H,EAAK,WAAW,OAAO,CAAAE,MAAKA,EAAE,SAAS,MAAM,GAC9DkC,IAAoBpC,EAAK,WAAW,OAAO,CAAAE,MAAKA,EAAE,SAAS,MAAM;AAEvE,iBACE,gBAAAhJ,EAAC,OAAA,EAAoB,WAAU,sCAE7B,UAAA;AAAA,YAAA,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,SAAS,MAAMqJ,EAAoBP,EAAK,IAAI;AAAA,gBAE5C,UAAA;AAAA,kBAAA,gBAAA7I,EAAC,OAAA,EAAI,WAAU,QACZ,UAAAiH,KACC,gBAAAjH,EAACkH,GAAA,EAAgB,WAAU,iCAAA,CAAiC,IAE5D,gBAAAlH,EAACmH,GAAA,EAAiB,WAAU,kCAAiC,GAEjE;AAAA,kBACA,gBAAApH,EAAC,OAAA,EAAI,WAAU,UACb,UAAA;AAAA,oBAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,oCAAoC,UAAA6I,EAAK,OAAM;AAAA,oBAC9D,gBAAA7I,EAAC,OAAA,EAAI,WAAU,8BAA8B,YAAK,YAAA,CAAY;AAAA,kBAAA,EAAA,CAChE;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAIDiH,MACC,gBAAAlH,EAAC,OAAA,EAAI,WAAU,2CAEZ,UAAA;AAAA,cAAAkL,EAAkB,SAAS,KAAKrB,GAAaqB,CAAiB,EAAE,SAAS,uBACvE,OAAA,EACC,UAAA;AAAA,gBAAA,gBAAAjL;AAAA,kBAACqK;AAAA,kBAAA;AAAA,oBACC,OAAM;AAAA,oBACN,OAAOT,GAAaqB,CAAiB,EAAE;AAAA,oBACvC,YAAY,GAAGpC,EAAK,IAAI;AAAA,oBACxB,MAAM,gBAAA7I,EAACuH,GAAA,EAAc,WAAU,yBAAA,CAAyB;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEzDS,EAAiB,IAAI,GAAGa,EAAK,IAAI,aAAa,KAC7C,gBAAA7I,EAAC,OAAA,EAAI,WAAU,uBACZ,UAAA4J,GAAaqB,CAAiB,EAAE,IAAI,CAAA3J,MACnC,gBAAAtB;AAAA,kBAAC+J;AAAA,kBAAA;AAAA,oBAEC,OAAOzI;AAAA,oBACP,WAAU;AAAA,oBACV,MAAM,gBAAAtB,EAACuH,GAAA,EAAc,WAAU,UAAA,CAAU;AAAA,kBAAA;AAAA,kBAHpCjG,EAAU;AAAA,gBAAA,CAKlB,EAAA,CACH;AAAA,cAAA,GAEJ;AAAA,cAIDJ,GAAe,SAAS,KAAK0I,GAAa1I,EAAc,EAAE,SAAS,KAClE,gBAAAnB,EAAC,OAAA,EACC,UAAA;AAAA,gBAAA,gBAAAC;AAAA,kBAACqK;AAAA,kBAAA;AAAA,oBACC,OAAM;AAAA,oBACN,OAAOT,GAAa1I,EAAc,EAAE;AAAA,oBACpC,YAAY,GAAG2H,EAAK,IAAI;AAAA,oBACxB,MAAM,gBAAA7I,EAACwH,GAAA,EAAkB,WAAU,wBAAA,CAAwB;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAE5DQ,EAAiB,IAAI,GAAGa,EAAK,IAAI,iBAAiB,KACjD,gBAAA7I,EAAC,OAAA,EAAI,WAAU,uBACZ,UAAA4J,GAAa1I,EAAc,EAAE,IAAI,CAAAgK,MAChC,gBAAAlL;AAAA,kBAAC+J;AAAA,kBAAA;AAAA,oBAEC,OAAOmB;AAAA,oBACP,WAAU;AAAA,oBACV,MAAM,gBAAAlL,EAACwH,GAAA,EAAkB,WAAU,UAAA,CAAU;AAAA,kBAAA;AAAA,kBAHxC0D,EAAc;AAAA,gBAAA,CAKtB,EAAA,CACH;AAAA,cAAA,GAEJ;AAAA,cAIDrC,EAAK,SAAS,SAAS,KAAKe,GAAaf,EAAK,QAAQ,EAAE,SAAS,KAChE,gBAAA9I,EAAC,OAAA,EACC,UAAA;AAAA,gBAAA,gBAAAC;AAAA,kBAACqK;AAAA,kBAAA;AAAA,oBACC,OAAM;AAAA,oBACN,OAAOT,GAAaf,EAAK,QAAQ,EAAE;AAAA,oBACnC,YAAY,GAAGA,EAAK,IAAI;AAAA,oBACxC,MAAM,gBAAA7I,EAACsH,GAAA,EAAY,WAAU,yBAAA,CAAyB;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEvCU,EAAiB,IAAI,GAAGa,EAAK,IAAI,WAAW,KAC3C,gBAAA7I,EAAC,OAAA,EAAI,WAAU,uBACZ,UAAA4J,GAAaf,EAAK,QAAQ,EAAE,IAAI,CAAAxH,MAC/B,gBAAArB;AAAA,kBAAC+J;AAAA,kBAAA;AAAA,oBAEC,OAAO1I;AAAA,oBACP,WAAU;AAAA,oBACV,MAAM0E,GAAe1E,EAAQ,MAAM,SAAS;AAAA,kBAAA;AAAA,kBAHvCA,EAAQ;AAAA,gBAAA,CAKhB,EAAA,CACH;AAAA,cAAA,EAAA,CAEJ;AAAA,YAAA,EAAA,CAEJ;AAAA,UAAA,EAAA,GA7FMwH,EAAK,IA+Ff;AAAA,QAEJ,CAAC;AAAA,MACH,KAAG,CACL;AAAA,MAAA,CAEJ;AAAA,EAAA,GACF;AAEJ,GCtfasC,KAAqB;AAAA,EAChC,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,EACxB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,EACvB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,EACxB,EAAE,OAAO,SAAS,OAAO,QAAA;AAAA,EACzB,EAAE,OAAO,WAAW,OAAO,UAAA;AAAA,EAC3B,EAAE,OAAO,QAAQ,OAAO,OAAA;AAC1B,GAcaC,KAA+D;AAAA;AAAA,EAE1E,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,UAAU,UAAU,WAAW,MAAM;AAAA,EAAA;AAAA,EAEpD,WAAW;AAAA,IACT,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,UAAU,UAAU,WAAW,MAAM;AAAA,EAAA;AAAA,EAEpD,UAAU;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA,EAEvB,aAAa;AAAA,IACX,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA,EAEvB,YAAY;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA,EAEvB,eAAe;AAAA,IACb,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA,EAEvB,UAAU;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA,EAEvB,aAAa;AAAA,IACX,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA,EAEvB,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA,EAEvB,SAAS;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA,EAEvB,OAAO;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA;AAAA,EAGvB,IAAI;AAAA,IACF,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,UAAU,SAAS,OAAO,OAAO,OAAO,KAAK;AAAA,EAAA;AAAA,EAE5D,KAAK;AAAA,IACH,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,UAAU,SAAS,OAAO,OAAO,OAAO,KAAK;AAAA,EAAA;AAAA,EAE5D,IAAI;AAAA,IACF,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,UAAU,SAAS,OAAO,OAAO,OAAO,KAAK;AAAA,EAAA;AAAA,EAE5D,KAAK;AAAA,IACH,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,UAAU,SAAS,OAAO,OAAO,OAAO,KAAK;AAAA,EAAA;AAAA,EAE5D,SAAS;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,UAAU,SAAS,OAAO,OAAO,OAAO,KAAK;AAAA,EAAA;AAAA,EAE5D,YAAY;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,UAAU,SAAS,OAAO,OAAO,OAAO,KAAK;AAAA,EAAA;AAAA;AAAA,EAG5D,IAAI;AAAA,IACF,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,UAAU,UAAU,SAAS;AAAA,EAAA;AAAA,EAE5C,OAAO;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,UAAU,UAAU,SAAS;AAAA,EAAA;AAAA;AAAA,EAG5C,KAAK;AAAA,IACH,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,UAAU,UAAU,QAAQ,SAAS;AAAA,EAAA;AAAA,EAEpD,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,UAAU,UAAU,QAAQ,SAAS;AAAA,EAAA;AAAA,EAEpD,SAAS;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA,EAEvB,YAAY;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA;AAAA,EAGvB,aAAa;AAAA,IACX,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,MAAM;AAAA,EAAA;AAAA,EAErB,YAAY;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,MAAM;AAAA,EAAA;AAAA,EAErB,WAAW;AAAA,IACT,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,MAAM;AAAA,EAAA;AAAA;AAAA,EAGrB,OAAO;AAAA,IACL,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA,EAEvB,UAAU;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA;AAAA,EAGvB,eAAe;AAAA,IACb,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA,EAEvB,eAAe;AAAA,IACb,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAAA,EAEvB,gBAAgB;AAAA,IACd,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY,CAAC,QAAQ;AAAA,EAAA;AAEzB,GAqEaC,KAAwC;AAAA,EACnD,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,EAC1B,EAAE,OAAO,SAAS,OAAO,QAAA;AAAA,EACzB,EAAE,OAAO,aAAa,OAAO,YAAA;AAAA,EAC7B,EAAE,OAAO,aAAa,OAAO,YAAA;AAAA,EAC7B,EAAE,OAAO,cAAc,OAAO,aAAA;AAAA,EAC9B,EAAE,OAAO,gBAAgB,OAAO,eAAA;AAAA,EAChC,EAAE,OAAO,aAAa,OAAO,YAAA;AAAA,EAC7B,EAAE,OAAO,eAAe,OAAO,cAAA;AAAA,EAC/B,EAAE,OAAO,gBAAgB,OAAO,eAAA;AAAA,EAChC,EAAE,OAAO,eAAe,OAAO,cAAA;AAAA,EAC/B,EAAE,OAAO,aAAa,OAAO,YAAA;AAAA,EAC7B,EAAE,OAAO,gBAAgB,OAAO,eAAA;AAAA,EAChC,EAAE,OAAO,cAAc,OAAO,aAAA;AAAA,EAC9B,EAAE,OAAO,kBAAkB,OAAO,iBAAA;AAAA,EAClC,EAAE,OAAO,iBAAiB,OAAO,gBAAA;AAAA,EACjC,EAAE,OAAO,gBAAgB,OAAO,eAAA;AAAA,EAChC,EAAE,OAAO,mBAAmB,OAAO,kBAAA;AAAA,EACnC,EAAE,OAAO,aAAa,OAAO,YAAA;AAAA,EAC7B,EAAE,OAAO,gBAAgB,OAAO,eAAA;AAClC,GCjlBMnE,KAAkBzH,EAAQ,aAAa,GACvC6L,KAAY7L,EAAQ,OAAO,GAE3B8L,KAA0D,CAAC;AAAA,EAC/D,WAAAb;AAAA,EACA,UAAAc;AAAA,EACA,QAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,QAAAlF;AACF,MAAM;AACJ,QAAMmF,IAAeP,GAAiBI,CAAQ,GACxC,CAACtG,GAAQ0G,CAAS,IAAI3I,EAAS,EAAK,GACpC,CAAC4I,GAAYC,CAAa,IAAI7I,EAAS,EAAE,GACzC,CAAC8I,GAAkBC,CAAmB,IAAI/I,EAAS,EAAK,GACxDgJ,IAAc9I,GAAuB,IAAI,GACzC+I,IAAmB/I,GAAe,EAAE,GAGpCgJ,IAAsBC,GAAYP,GAAY,GAAG,GAGjDQ,IAAcxI,GAAQ,MAAM2C,IAASA,EAAO,MAAM;AAAA,IAAK,OAC3DqC,EAAK,WAAW,KAAK,CAAAyD,MAAOA,EAAI,SAAS5B,CAAS;AAAA,EAAA,IAChD,IAAO,CAAClE,GAAQkE,CAAS,CAAC,GAGxB6B,IAAkB1I,GAAQ,MAAM2C,IAASA,EAAO,MAAM;AAAA,IAAK,CAAAqC,MAC/DA,EAAK,WAAW,KAAK,CAAAyD,MAAOA,EAAI,SAAS5B,KAAa4B,EAAI,SAAS,MAAM;AAAA,EAAA,IACvE,IAAO,CAAC9F,GAAQkE,CAAS,CAAC,GAGxB8B,IAAoB3I;AAAA,IAAQ,MAC/B,CAAC,UAAU,aAAa,MAAM,OAAO,EAAE,SAAS2H,CAAQ,KAAMa,KAAe,CAACE;AAAA,IAC/E,CAACf,GAAUa,GAAaE,CAAe;AAAA,EAAA,GAEnCE,IAAqBD,GAErB;AAAA,IACJ,QAAQE;AAAA,IACR,SAASC;AAAA,IACT,OAAOC;AAAA,IACP,cAAAC;AAAA,EAAA,IACEC,GAAgBpC,GAAW8B,CAAiB;AAGhD,EAAAhJ,GAAU,MAAM;AACd,UAAMuJ,IAAqB,CAACjH,MAAsB;AAChD,MAAImG,EAAY,WAAW,CAACA,EAAY,QAAQ,SAASnG,EAAM,MAAc,KAC3E8F,EAAU,EAAK;AAAA,IAEnB;AAEA,oBAAS,iBAAiB,aAAamB,CAAkB,GAClD,MAAM,SAAS,oBAAoB,aAAaA,CAAkB;AAAA,EAC3E,GAAG,CAAA,CAAE,GAGLvJ,GAAU,MAAM;AACd,IAAI0B,KAAUsH,KAAqBK,MACjCA,EAAa,IAAI,EAAI,GACrBb,EAAoB,EAAI,GACxBE,EAAiB,UAAU;AAAA,EAE/B,GAAG,CAAChH,GAAQsH,GAAmBK,CAAY,CAAC,GAG5CrJ,GAAU,MAAM;AACd,IAAIuI,KAAoBS,KAAqBK,KAAgBV,MAAwBD,EAAiB,YACpGA,EAAiB,UAAUC,GAC3BU,EAAaV,CAAmB;AAAA,EAEpC,GAAG,CAACA,GAAqBJ,GAAkBS,GAAmBK,CAAY,CAAC;AAG3E,QAAMG,IAAuBnH,EAAY,MAAM;AAC7C,UAAMoH,IAAY,CAAC/H;AACnB,IAAA0G,EAAUqB,CAAS,GAGdA,MACHnB,EAAc,EAAE,GAChBI,EAAiB,UAAU;AAAA,EAE/B,GAAG,CAAChH,CAAM,CAAC,GAGLgI,IAAqBrH,EAAY,CAACnE,MAA2C;AACjF,UAAMyL,IAAgBzL,EAAE,OAAO;AAC/B,IAAAoK,EAAcqB,CAAa;AAAA,EAC7B,GAAG,CAAA,CAAE,GAGCC,IAAoBvH,EAAY,CAACwH,MAAe;AACpD,IAAI1B,EAAa,yBAEVF,EAAO,SAAS4B,CAAK,KACxB3B,EAAe,CAAC,GAAGD,GAAQ4B,CAAK,CAAC,KAInC3B,EAAe,CAAC2B,CAAK,CAAC,GACtBzB,EAAU,EAAK,IAGjBE,EAAc,EAAE;AAAA,EAClB,GAAG,CAACH,EAAa,wBAAwBF,GAAQC,CAAc,CAAC,GAG1D4B,IAAoBzH,EAAY,CAAC0H,MAAuB;AAC5D,IAAA7B,EAAeD,EAAO,OAAO,CAAA+B,MAAKA,MAAMD,CAAa,CAAC;AAAA,EACxD,GAAG,CAAC9B,GAAQC,CAAc,CAAC,GAGrB+B,IAAoB5H,EAAY,CAACnE,MAA2C;AAChF,UAAM2L,IAAQ3L,EAAE,OAAO;AACvB,QAAIiK,EAAa,cAAc,UAAU;AACvC,YAAM+B,IAAW,WAAWL,CAAK;AAEjC,MAAK,MAAMK,CAAQ,KAERL,MAAU,MAAMA,MAAU,QAEnC3B,EAAe,CAAA,CAAE,IAHjBA,EAAe,CAACgC,CAAQ,CAAC;AAAA,IAK7B;AACE,MAAAhC,EAAe2B,IAAQ,CAACA,CAAK,IAAI,CAAA,CAAE;AAAA,EAEvC,GAAG,CAAC1B,EAAa,WAAWD,CAAc,CAAC,GAGrCiC,IAAkB9H,EAAY,CAACnE,MAA2C;AAC9E,UAAM2L,IAAQ3L,EAAE,OAAO;AACvB,QAAI8J,MAAa,eAAe;AAE9B,YAAMoC,IAAgBnC,EAAO,UAAU,IAAIA,IAAS,CAAC,IAAI,EAAE;AAC3D,MAAAC,EAAe,CAAC2B,GAAOO,EAAc,CAAC,CAAC,CAAC;AAAA,IAC1C;AAEE,MAAAlC,EAAe2B,IAAQ,CAACA,CAAK,IAAI,CAAA,CAAE;AAAA,EAEvC,GAAG,CAAC7B,GAAUC,GAAQC,CAAc,CAAC,GAE/BmC,IAA0BhI,EAAY,CAACnE,MAA2C;AACtF,UAAM2L,IAAQ3L,EAAE,OAAO,OACjBkM,IAAgBnC,EAAO,UAAU,IAAIA,IAAS,CAAC,IAAI,EAAE;AAC3D,IAAAC,EAAe,CAACkC,EAAc,CAAC,GAAGP,CAAK,CAAC;AAAA,EAC1C,GAAG,CAAC5B,GAAQC,CAAc,CAAC,GAGrBoC,IAA0BjI,EAAY,CAACnE,MAA2C;AACtF,UAAM2L,IAAQ,WAAW3L,EAAE,OAAO,KAAK,GACjCkM,IAAgBnC,EAAO,UAAU,IAAIA,IAAS,CAAC,IAAI,EAAE,GACrDsC,KAAY,CAAE,MAAMV,CAAK,IAAY3L,EAAE,OAAO,UAAU,KAAK,KAAKkM,EAAc,CAAC,IAApDP,GAAuDO,EAAc,CAAC,CAAC;AAC1G,IAAAlC,EAAeqC,GAAU,OAAO,CAAAP,OAAKA,OAAM,EAAE,CAAC;AAAA,EAChD,GAAG,CAAC/B,GAAQC,CAAc,CAAC,GAErBsC,IAAwBnI,EAAY,CAACnE,MAA2C;AACpF,UAAM2L,IAAQ,WAAW3L,EAAE,OAAO,KAAK,GACjCkM,IAAgBnC,EAAO,UAAU,IAAIA,IAAS,CAAC,IAAI,EAAE,GACrDsC,KAAY,CAACH,EAAc,CAAC,GAAI,MAAMP,CAAK,IAAY3L,EAAE,OAAO,UAAU,KAAK,KAAKkM,EAAc,CAAC,IAApDP,CAAqD;AAC1G,IAAA3B,EAAeqC,GAAU,OAAO,CAAAP,OAAKA,OAAM,EAAE,CAAC;AAAA,EAChD,GAAG,CAAC/B,GAAQC,CAAc,CAAC;AAG3B,SAAKC,EAAa,iBASdH,MAAa,gBAGb,gBAAAzL,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,IAAA,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAOyL,EAAO,CAAC,KAAK;AAAA,QACpB,UAAUkC;AAAA,QACV,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,IAEZ,gBAAA3N,EAAC,QAAA,EAAK,WAAU,8BAA6B,UAAA,MAAE;AAAA,IAC/C,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAOyL,EAAO,CAAC,KAAK;AAAA,QACpB,UAAUoC;AAAA,QACV,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,EACZ,GACF,IAIArC,MAAa,aAAaA,MAAa,eAGvC,gBAAAzL,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,IAAA,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAOyL,EAAO,CAAC,MAAM,UAAaA,EAAO,CAAC,MAAM,OAAOA,EAAO,CAAC,IAAI;AAAA,QACnE,UAAUqC;AAAA,QACV,aAAY;AAAA,QACZ,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,IAEZ,gBAAA9N,EAAC,QAAA,EAAK,WAAU,8BAA6B,UAAA,MAAE;AAAA,IAC/C,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAOyL,EAAO,CAAC,MAAM,UAAaA,EAAO,CAAC,MAAM,OAAOA,EAAO,CAAC,IAAI;AAAA,QACnE,UAAUuC;AAAA,QACV,aAAY;AAAA,QACZ,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,EACZ,GACF,IAIArC,EAAa,cAAc,SAG3B,gBAAA3L;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAOyL,EAAO,CAAC,KAAK;AAAA,MACpB,UAAUkC;AAAA,MACV,WAAU;AAAA,IAAA;AAAA,EAAA,IAKZhC,EAAa,cAAc,WAG3B,gBAAA3L;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAOyL,EAAO,CAAC,MAAM,UAAaA,EAAO,CAAC,MAAM,OAAOA,EAAO,CAAC,IAAI;AAAA,MACnE,UAAUgC;AAAA,MACV,aAAY;AAAA,MACZ,WAAU;AAAA,IAAA;AAAA,EAAA,IAMZlB,KAAoB,CAAC,UAAU,aAAa,MAAM,OAAO,EAAE,SAASf,CAAQ,IAC1EG,EAAa,yBAGb,gBAAA5L,EAAC,OAAA,EAAI,WAAU,aAEZ,UAAA;AAAA,IAAA0L,EAAO,SAAS,KACf,gBAAAzL,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAAyL,EAAO,IAAI,CAAC4B,GAAOvC,MAClB,gBAAA/K;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA,QAEV,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,QAAQ,UAAA,OAAOqN,CAAK,GAAE;AAAA,UACtC,gBAAArN;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAMsN,EAAkBD,CAAK;AAAA,cACtC,WAAU;AAAA,cAEV,UAAA,gBAAArN,EAACsL,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACjC;AAAA,MAAA;AAAA,MATKR;AAAA,IAAA,CAWR,GACH;AAAA,IAIF,gBAAA9K;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,UAAU,CAAC0B,MAAM;AACf,UAAIA,EAAE,OAAO,SAAS,CAAC+J,EAAO,SAAS/J,EAAE,OAAO,KAAK,MACnDgK,EAAe,CAAC,GAAGD,GAAQ/J,EAAE,OAAO,KAAK,CAAC,GAC1CA,EAAE,OAAO,QAAQ;AAAA,QAErB;AAAA,QACA,WAAU;AAAA,QACV,aAAY;AAAA,MAAA;AAAA,IAAA;AAAA,EACd,GACF,IAKA,gBAAA1B;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAOyL,EAAO,CAAC,KAAK;AAAA,MACpB,UAAUkC;AAAA,MACV,WAAU;AAAA,IAAA;AAAA,EAAA,IAMdlB,IAGA,gBAAA1M,EAAC,OAAA,EAAI,WAAU,YAAW,KAAKkM,GAE5B,UAAA;AAAA,IAAAN,EAAa,0BAA0BF,EAAO,SAAS,KACtD,gBAAAzL,EAAC,OAAA,EAAI,WAAU,6BACZ,UAAAyL,EAAO,IAAI,CAAC4B,GAAOvC,MAClB,gBAAA/K;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA,QAEV,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,QAAQ,UAAA,OAAOqN,CAAK,GAAE;AAAA,UACtC,gBAAArN;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAMsN,EAAkBD,CAAK;AAAA,cACtC,WAAU;AAAA,cAEV,UAAA,gBAAArN,EAACsL,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACjC;AAAA,MAAA;AAAA,MATKR;AAAA,IAAA,CAWR,GACH;AAAA,IAID,CAACa,EAAa,0BAA0BF,EAAO,SAAS,KACvD,gBAAAzL,EAAC,OAAA,EAAI,WAAU,QACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,qIACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,UAAK,WAAU,QAAQ,iBAAOyL,EAAO,CAAC,CAAC,GAAE;AAAA,MAC1C,gBAAAzL;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS,MAAM0L,EAAe,EAAE;AAAA,UAChC,WAAU;AAAA,UAEV,UAAA,gBAAA1L,EAACsL,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IACjC,EAAA,CACF,EAAA,CACF;AAAA,IAIF,gBAAAvL;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAASiN;AAAA,QACT,WAAU;AAAA,QAEV,UAAA;AAAA,UAAA,gBAAAhN,EAAC,UAAK,WAAU,+BACb,eAAiB,CAAC+L,IAAmB,sBAAsB,mBAC9D;AAAA,UACA,gBAAA/L,EAACkH,IAAA,EAAgB,WAAU,6BAAA,CAA6B;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAIzDhC,KACC,gBAAAnF,EAAC,OAAA,EAAI,WAAU,yHAEb,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,iCACb,UAAA,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,OAAO6L;AAAA,UACP,UAAUqB;AAAA,UACV,aAAY;AAAA,UACZ,WAAU;AAAA,UACV,WAAS;AAAA,QAAA;AAAA,MAAA,GAEb;AAAA,wBAGC,OAAA,EAAI,WAAU,4BACZ,UAAAP,sBACE,OAAA,EAAI,WAAU,kCACZ,UAAAd,IAAa,iBAAiB,oBAAA,CACjC,IACEe,IACF,gBAAA7M,EAAC,OAAA,EAAI,WAAU,4BAA2B,UAAA;AAAA,QAAA;AAAA,QACjB6M;AAAA,MAAA,GACzB,IACEF,EAAe,WAAW,IAC5B,gBAAA1M,EAAC,SAAI,WAAU,kCACZ,UAAA6L,IAAa,uBAAuB,uBACvC,IAEAa,EAAe,IAAI,CAACW,GAAOvC,MAAU;AACnC,cAAMb,IAAawB,EAAO,SAAS4B,CAAK;AAExC,eACE,gBAAAtN;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,SAAS,MAAMqN,EAAkBC,CAAK;AAAA,YACtC,WAAW,+GACTpD,IAAa,6BAA6B,wBAC5C;AAAA,YAEC,UAAA;AAAA,cAAA,OAAOoD,CAAK;AAAA,cACZpD,KACC,gBAAAjK,EAAC,QAAA,EAAK,WAAU,6BAA4B,UAAA,IAAA,CAAC;AAAA,YAAA;AAAA,UAAA;AAAA,UAR1C,GAAGqN,CAAK,IAAIvC,CAAK;AAAA,QAAA;AAAA,MAY5B,CAAC,EAAA,CAEL;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GAEJ,IAMF,gBAAA9K;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAOyL,EAAO,CAAC,MAAM,UAAaA,EAAO,CAAC,MAAM,OAAOA,EAAO,CAAC,IAAI;AAAA,MACnE,UAAUgC;AAAA,MACV,aAAa,SAAS9B,EAAa,SAAS;AAAA,MAC5C,WAAU;AAAA,IAAA;AAAA,EAAA,IAjPV,gBAAA3L,EAAC,OAAA,EAAI,WAAU,qCAAoC,UAAA,qBAEnD;AAkPN;AC5VO,SAASiO,GAAgB7M,GAA2B;AACzD,SAAO,GACJA,EAAM,YAAYA,EAAM,SAAS,SAAS,KAC1CA,EAAM,cAAcA,EAAM,WAAW,SAAS,KAC9CA,EAAM,kBAAkBA,EAAM,eAAe,SAAS;AAE3D;AAKO,SAAS8M,GAAuB9M,GAA0B;AAC/D,MAAIkJ,IAAQ;AACZ,SAAIlJ,EAAM,aAAUkJ,KAASlJ,EAAM,SAAS,SACxCA,EAAM,eAAYkJ,KAASlJ,EAAM,WAAW,SAC5CA,EAAM,mBAAgBkJ,KAASlJ,EAAM,eAAe,SACjDkJ;AACT;AA0BO,SAAS6D,GAAW/M,GAA6B;AACtD,QAAMgN,IAA0B,CAAA;AAEhC,SAAIhN,EAAM,YAAYA,EAAM,SAAS,SAAS,MAC5CgN,EAAa,WAAWhN,EAAM,WAG5BA,EAAM,cAAcA,EAAM,WAAW,SAAS,MAChDgN,EAAa,aAAahN,EAAM,aAG9BA,EAAM,kBAAkBA,EAAM,eAAe,SAAS,MACxDgN,EAAa,iBAAiBhN,EAAM,iBAGlCA,EAAM,WAAWA,EAAM,QAAQ,SAAS,MAC1CgN,EAAa,UAAUhN,EAAM,UAG3BA,EAAM,UACRgN,EAAa,QAAQhN,EAAM,QAGzBA,EAAM,UACRgN,EAAa,QAAQhN,EAAM,QAGzBA,EAAM,WACRgN,EAAa,SAAShN,EAAM,SAG1BA,EAAM,YAAYA,EAAM,SAAS,SAAS,MAC5CgN,EAAa,WAAWhN,EAAM,WAGzBgN;AACT;AAMO,SAASC,GAAoBjN,GAA6B;AAC/D,QAAMgN,IAAeD,GAAW/M,CAAK;AAGrC,SAAIgN,EAAa,WAAWA,EAAa,QAAQ,SAAS,MACxDA,EAAa,UAAUE,GAA0BF,EAAa,OAAO,IAGhEA;AACT;AAKO,SAASG,KAA8B;AAC5C,SAAO,CAAA;AACT;AASO,SAASC,GAAetO,GAAwC;AACrE,SAAO,YAAYA,KAAU,cAAcA,KAAU,YAAYA;AACnE;AAKO,SAASuO,GAAcvO,GAAuC;AACnE,SAAO,UAAUA,KAAU,aAAaA;AAC1C;AAKO,SAASwO,GAAYxO,GAAuC;AACjE,SAAOuO,GAAcvO,CAAM,KAAKA,EAAO,SAAS;AAClD;AAKO,SAASyO,GAAWzO,GAAuC;AAChE,SAAOuO,GAAcvO,CAAM,KAAKA,EAAO,SAAS;AAClD;AAwBO,SAAS0O,GAAoBpI,GAAsBpF,GAAgC;AACxF,QAAMyN,IAAyB,CAAA;AAQ/B,MANArI,EAAO,MAAM,QAAQ,CAAAqC,MAAQ;AAC3B,IAAAgG,EAAU,KAAK,GAAGhG,EAAK,QAAQ,GAC/BgG,EAAU,KAAK,GAAGhG,EAAK,UAAU;AAAA,EACnC,CAAC,GAGG,CAACzH;AACH,WAAOyN,EAAU,KAAK,CAACC,GAAGC,MAAMD,EAAE,KAAK,cAAcC,EAAE,IAAI,CAAC;AAI9D,QAAMpI,wBAAqB,IAAA;AAG3B,SAAIvF,EAAM,YACRA,EAAM,SAAS,QAAQ,CAAAC,MAAWsF,EAAe,IAAItF,CAAO,CAAC,GAI3DD,EAAM,cACRA,EAAM,WAAW,QAAQ,CAAAE,MAAaqF,EAAe,IAAIrF,CAAS,CAAC,GAIjEF,EAAM,kBACRA,EAAM,eAAe,QAAQ,CAAAG,MAAMoF,EAAe,IAAIpF,EAAG,SAAS,CAAC,GAI5CsN,EAAU,OAAO,CAAApN,MAASkF,EAAe,IAAIlF,EAAM,IAAI,CAAC,EAEzD,KAAK,CAACqN,GAAGC,MAAMD,EAAE,KAAK,cAAcC,EAAE,IAAI,CAAC;AACrE;AAKO,SAASC,GAAuBxI,GAAmC;AACxE,QAAMqI,IAAyB,CAAA;AAE/B,SAAArI,EAAO,MAAM,QAAQ,CAAAqC,MAAQ;AAC3B,IAAAgG,EAAU,KAAK,GAAGhG,EAAK,QAAQ,GAC/BgG,EAAU,KAAK,GAAGhG,EAAK,UAAU;AAAA,EACnC,CAAC,GAEMgG,EAAU,KAAK,CAACC,GAAGC,MAAMD,EAAE,KAAK,cAAcC,EAAE,IAAI,CAAC;AAC9D;AAKO,SAASE,GAAyBzI,GAAsBpF,GAG7D;AACA,QAAMyN,IAAYG,GAAuBxI,CAAM;AAE/C,MAAI,CAACpF;AACH,WAAO;AAAA,MACL,aAAa,CAAA;AAAA,MACb,WAAAyN;AAAA,IAAA;AAKJ,QAAMlI,wBAAqB,IAAA;AAG3B,SAAIvF,EAAM,YACRA,EAAM,SAAS,QAAQ,CAAAC,MAAWsF,EAAe,IAAItF,CAAO,CAAC,GAI3DD,EAAM,cACRA,EAAM,WAAW,QAAQ,CAAAE,MAAaqF,EAAe,IAAIrF,CAAS,CAAC,GAIjEF,EAAM,kBACRA,EAAM,eAAe,QAAQ,CAAAG,MAAMoF,EAAe,IAAIpF,EAAG,SAAS,CAAC,GAM9D;AAAA,IACL,aAHkBsN,EAAU,OAAO,CAAApN,MAASkF,EAAe,IAAIlF,EAAM,IAAI,CAAC;AAAA,IAI1E,WAAAoN;AAAA,EAAA;AAEJ;AAKO,SAASK,GAAsBvF,GAA6D;AACjG,QAAMwF,IAAsD,CAAA;AAE5D,aAAW,CAAC3D,GAAU4D,CAAI,KAAK,OAAO,QAAQhE,EAAgB;AAC5D,IAAIgE,EAAK,WAAW,SAASzF,CAAS,KACpCwF,EAAU,KAAK;AAAA,MACb,UAAA3D;AAAA,MACA,OAAO4D,EAAK;AAAA,IAAA,CACb;AAIL,SAAOD;AACT;AAKO,SAASE,GAAa3E,GAAmBlE,GAA8B;AAC5E,aAAWqC,KAAQrC,EAAO,OAAO;AAE/B,UAAMnF,IAAUwH,EAAK,SAAS,KAAK,CAAAyG,MAAKA,EAAE,SAAS5E,CAAS;AAC5D,QAAIrJ,UAAgBA,EAAQ;AAG5B,UAAMC,IAAYuH,EAAK,WAAW,KAAK,CAAAE,MAAKA,EAAE,SAAS2B,CAAS;AAChE,QAAIpJ,UAAkBA,EAAU;AAAA,EAClC;AAEA,SAAO;AACT;AAiDO,SAASiO,GAAa5N,GAA2B;AACtD,MAAI2I,IAAQ;AAEZ,QAAMkF,IAAc,CAACtP,MAAmB;AACtC,IAAIsO,GAAetO,CAAM,IACvBoK,MACSmE,GAAcvO,CAAM,KAC7BA,EAAO,QAAQ,QAAQsP,CAAW;AAAA,EAEtC;AAEA,SAAA7N,EAAQ,QAAQ6N,CAAW,GACpBlF;AACT;AAKO,SAASmF,GAAmBC,GAAgBlE,IAAmB,UAAUC,IAAgB,CAAA,GAAkB;AAChH,SAAO;AAAA,IACL,QAAAiE;AAAA,IACA,UAAAlE;AAAA,IACA,QAAAC;AAAA,EAAA;AAEJ;AAKO,SAASkE,GAAgBhO,IAAoB,IAAiB;AACnE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAAA;AAAA,EAAA;AAEJ;AAKO,SAASiO,GAAejO,IAAoB,IAAiB;AAClE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAAA;AAAA,EAAA;AAEJ;AAMO,SAASkO,GAAelO,GAAmBmO,GAA8B;AAE9E,SAAOnO,KAAW,CAAA;AACpB;AAoDO,SAAS2M,GAA0B3M,GAA0B;AAClE,QAAMoO,IAAkB,CAAC7P,MAAwB;AAC/C,QAAIsO,GAAetO,CAAM;AACvB,aAAOA;AACT,QAAWuO,GAAcvO,CAAM,GAAG;AAChC,YAAM8P,IAAwB9P,EAAO,QAAQ,IAAI6P,CAAe;AAEhE,aAAI7P,EAAO,SAAS,QACX,EAAE,KAAK8P,EAAA,IAEP,EAAE,IAAIA,EAAA;AAAA,IAEjB;AACA,WAAO9P;AAAA,EACT;AAEA,SAAOyB,EAAQ,IAAIoO,CAAe;AACpC;AASO,SAASE,GAA4BC,GAAmBC,GAAyB;AACtF,QAAMC,IAAkC;AAAA,IACtC,OAAS;AAAA,IACT,WAAa;AAAA,IACb,WAAa;AAAA,IACb,YAAc;AAAA,IACd,cAAgB;AAAA,IAChB,WAAa;AAAA,IACb,aAAe;AAAA,IACf,cAAgB;AAAA,IAChB,WAAa;AAAA,IACb,YAAc;AAAA,IACd,cAAgB;AAAA,IAChB,WAAa;AAAA,IACb,gBAAkB;AAAA,EAAA;AAIpB,MAAIF,EAAU,WAAW,SAAS,KAAKC,MAAW,UAAaA,IAAS,GAAG;AACzE,UAAME,IAAOH,EAAU,QAAQ,WAAW,EAAE,GACtCI,IAAeD,EAAK,MAAM,GAAG,EAAE;AACrC,WAAOF,MAAW,IAAI,QAAQG,CAAY,KAAK,QAAQH,CAAM,IAAIE,CAAI;AAAA,EACvE;AAEA,SAAOD,EAAQF,CAAS,KAAKA;AAC/B;AAKO,SAASK,GAAoBL,GAA4B;AAC9D,SAAOA,EAAU,WAAW,SAAS;AACvC;AAKO,SAASM,GAAkBC,GAAoB;AACpD,SAAOA,EAAK,YAAA,EAAc,MAAM,GAAG,EAAE,CAAC;AACxC;AAKO,SAASC,GAAgCtP,GAAqD;AACnG,QAAMuP,IAAgD,CAAA;AAEtD,SAAIvP,EAAM,kBACRA,EAAM,eAAe,QAAQ,CAAAG,MAAM;AACjC,IAAIA,EAAG,cACLoP,EAAWpP,EAAG,SAAS,IAAIA,EAAG;AAAA,EAElC,CAAC,GAGIoP;AACT;AAKO,SAASC,GAAkBxP,GAA2B;AAC3D,SAAO,GAAQA,EAAM,kBAAkBA,EAAM,eAAe,SAAS;AACvE;AAMO,SAASyP,GAAoBzP,GAAuB;AACzD,MAAI,CAACA,KAAS,OAAOA,KAAU;AAC7B,WAAO,CAAA;AAGT,QAAM0P,IAAyB,CAAA;AAG/B,SAAI1P,EAAM,aAAU0P,EAAY,WAAW,MAAM,QAAQ1P,EAAM,QAAQ,IAAIA,EAAM,WAAW,CAAA,IACxFA,EAAM,eAAY0P,EAAY,aAAa,MAAM,QAAQ1P,EAAM,UAAU,IAAIA,EAAM,aAAa,CAAA,IAChGA,EAAM,mBAAgB0P,EAAY,iBAAiB,MAAM,QAAQ1P,EAAM,cAAc,IAAIA,EAAM,iBAAiB,CAAA,IAChHA,EAAM,UAAO0P,EAAY,QAAQ1P,EAAM,QACvCA,EAAM,UAAO0P,EAAY,QAAQ1P,EAAM,QACvCA,EAAM,WAAQ0P,EAAY,SAAS1P,EAAM,SACzCA,EAAM,aAAU0P,EAAY,WAAW,MAAM,QAAQ1P,EAAM,QAAQ,IAAIA,EAAM,WAAW,CAAA,IAGxFA,EAAM,WAAW,MAAM,QAAQA,EAAM,OAAO,MAC9C0P,EAAY,UAAUC,GAA2B3P,EAAM,OAAO,IAGzD+M,GAAW2C,CAAW;AAC/B;AAMA,SAASC,GAA2BpP,GAA0B;AAC5D,SAAOA,EAAQ,IAAI,CAAAzB,MACb,CAACA,KAAU,OAAOA,KAAW,WACxBA,IAIL,SAASA,KAAU,MAAM,QAAQA,EAAO,GAAG,IACtC;AAAA,IACL,MAAM;AAAA,IACN,SAAS6Q,GAA2B7Q,EAAO,GAAG;AAAA,EAAA,IAK9C,QAAQA,KAAU,MAAM,QAAQA,EAAO,EAAE,IACpC;AAAA,IACL,MAAM;AAAA,IACN,SAAS6Q,GAA2B7Q,EAAO,EAAE;AAAA,EAAA,IAK7C,UAAUA,KAAU,aAAaA,KAAU,MAAM,QAAQA,EAAO,OAAO,IAClE;AAAA,IACL,MAAMA,EAAO;AAAA,IACb,SAAS6Q,GAA2B7Q,EAAO,OAAO;AAAA,EAAA,IAK/CA,CACR,EAAE,OAAO,OAAO;AACnB;AASO,SAAS8Q,GAActG,GAAmBlE,GAAqC;AACpF,MAAI,CAACA,EAAQ,QAAOkE;AAEpB,aAAW7B,KAAQrC,EAAO,OAAO;AAE/B,UAAMnF,IAAUwH,EAAK,SAAS,KAAK,CAAAyG,MAAKA,EAAE,SAAS5E,CAAS;AAC5D,QAAIrJ,EAAS,QAAOA,EAAQ,SAASA,EAAQ,cAAcqJ;AAG3D,UAAMpJ,IAAYuH,EAAK,WAAW,KAAK,CAAAE,MAAKA,EAAE,SAAS2B,CAAS;AAChE,QAAIpJ,EAAW,QAAOA,EAAU,SAASA,EAAU,cAAcoJ;AAAA,EACnE;AAEA,SAAOA;AACT;AA2BO,SAASuG,GAAiBvG,GAAmBwG,GAA0E;AAC5H,SAAOA,IAAQxG,CAAS,KAAK;AAC/B;AAKO,SAASyG,GAAeC,GAA0C;AACvE,UAAQA,GAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EAAA;AAEb;AAKO,SAASC,GAAqBC,GAAuD;AAC1F,UAAQA,GAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EAAA;AAEb;ACruBA,MAAMhG,KAAY7L,EAAQ,OAAO,GAC3B8R,KAAa9R,EAAQ,QAAQ,GAC7ByH,KAAkBzH,EAAQ,aAAa,GACvC+R,KAAa/R,EAAQ,QAAQ,GAC7B8H,KAAgB9H,EAAQ,WAAW,GACnC+H,KAAoB/H,EAAQ,eAAe,GAE3CgS,KAAwC,CAAC;AAAA,EAC7C,QAAAvR;AAAA,EACA,OAAA4K;AAAA,EACA,gBAAA4G;AAAA,EACA,gBAAAC;AAAA,EACA,QAAAnL;AAAA,EACA,OAAApF;AAAA,EACA,mBAAAwQ,IAAoB;AAAA,EACpB,sBAAAC,IAAuB;AAAA,EACvB,kBAAAC,IAAmB;AACrB,MAAM;AACJ,QAAM,CAACC,GAAqBC,CAAsB,IAAI/O,EAAS,EAAK,GAC9D,CAACgP,GAAwBC,CAAyB,IAAIjP,EAAS,EAAK,GACpE,CAACkP,GAAyBC,CAA0B,IAAInP,EAAS,EAAK,GACtE,CAACoP,GAAiBC,CAAkB,IAAIrP,EAAS,EAAE,GACnDsP,IAAepP,GAAuB,IAAI,GAC1CqP,IAAiBrP,GAAyB,IAAI,GAG9C,CAAC+M,GAAWuC,CAAY,IAAIxP,EAAwB,YAAY,GAChE,CAACyP,GAAaC,CAAc,IAAI1P,EAAS;AAAA,IAC7C,WAAWuN,GAAkB,oBAAI,MAAM;AAAA,IACvC,SAASA,GAAkB,oBAAI,KAAA,CAAM;AAAA,EAAA,CACtC,GACK,CAACoC,GAAaC,CAAc,IAAI5P,EAAiB,CAAC;AAGxD,EAAAO,GAAU,MAAM;AACd,UAAMuJ,IAAqB,CAACjH,MAAsB;AAChD,MAAIyM,EAAa,WAAW,CAACA,EAAa,QAAQ,SAASzM,EAAM,MAAc,MAC7EkM,EAAuB,EAAK,GAC5BE,EAA0B,EAAK;AAAA,IAEnC;AAEA,oBAAS,iBAAiB,aAAanF,CAAkB,GAClD,MAAM,SAAS,oBAAoB,aAAaA,CAAkB;AAAA,EAC3E,GAAG,CAAA,CAAE;AAGL,QAAM+F,IAA4B,MAAM;AACtC,IAAAZ,EAA0B,EAAK;AAC/B,UAAMa,IAAU,CAAChB;AACjB,IAAAC,EAAuBe,CAAO,GAC9BT,EAAmB,EAAE,GAGjBS,KACF,WAAW,MAAMP,EAAe,SAAS,MAAA,GAAS,EAAE;AAAA,EAExD,GAEMQ,IAA+B,MAAM;AACzC,IAAAhB,EAAuB,EAAK,GAC5BE,EAA0B,CAACD,CAAsB;AAAA,EACnD,GAGMpD,IAAYrI,IAASwI,GAAuBxI,CAAM,IAAI,CAAA,GACtD,EAAE,aAAAyM,MAAgBzM,IAASyI,GAAyBzI,GAAQpF,CAAK,IAAI,EAAE,aAAa,GAAC,GACrF8R,IAAgBrE,EAAU,KAAK,OAAKzO,EAAE,SAASF,EAAO,MAAM,GAC5DyJ,IAAYuJ,IAAgBA,EAAc,OAAO,UACjDC,IAAqBjE,GAAsBvF,CAAS,GAGpDyJ,IAA8BzJ,MAAc,UAAUzJ,EAAO,aAAa;AAuChF,MApCAsD,GAAU,MAAM;AACd,QAAI,GAAC4P,KAA+B,CAAClT,EAAO;AAG5C,UAAI,MAAM,QAAQA,EAAO,SAAS;AAChC,QAAAuS,EAAa,QAAQ,GACrBE,EAAe;AAAA,UACb,WAAWzS,EAAO,UAAU,CAAC,KAAK;AAAA,UAClC,SAASA,EAAO,UAAU,CAAC,KAAKA,EAAO,UAAU,CAAC,KAAK;AAAA,QAAA,CACxD;AAAA,WACI;AAEL,cAAMmT,IAAqBnT,EAAO,UAAU,MAAM,iDAAiD;AACnG,YAAImT,GAAoB;AACtB,gBAAM,CAAA,EAAGC,GAAKjD,CAAI,IAAIgD;AAEtB,UAAAZ,EAAa,UADMpC,MAAS,SAAS,SAASA,MAAS,UAAU,UAAUA,MAAS,WAAW,WAAWA,MAAS,aAAa,aAAa,OAC5G,EAAmB,GACpDwC,EAAe,SAASS,CAAG,KAAK,CAAC;AAAA,QACnC,OAAO;AAEL,cAAIC,IAAQ;AACZ,qBAAWC,KAAUnI;AACnB,gBAAImI,EAAO,UAAU,YAAY,CAACjD,GAAoBiD,EAAO,KAAK,KAAKvD,GAA4BuD,EAAO,KAAK,MAAMtT,EAAO,WAAW;AACrI,cAAAuS,EAAae,EAAO,KAAK,GACzBD,IAAQ;AACR;AAAA,YACF;AAEF,UAAKA,KACHd,EAAa,QAAQ;AAAA,QAEzB;AAAA,MACF;AAAA,EACF,GAAG,CAACvS,EAAO,WAAWkT,CAA2B,CAAC,GAG9C,CAAC5M;AACH,WACE,gBAAAxG,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,qBAE5C;AAKJ,QAAMyT,IAAuB,CAAC7R,MAAwB;AACpD,QAAI,CAACyQ,EAAiB,QAAOzQ;AAC7B,UAAMsG,IAAamK,EAAgB,YAAA;AACnC,WAAOzQ,EAAO;AAAA,MAAO,CAAAH,MACnBA,EAAM,KAAK,YAAA,EAAc,SAASyG,CAAU,KAC5CzG,EAAM,MAAM,cAAc,SAASyG,CAAU,KAC7CzG,EAAM,WAAW,YAAA,EAAc,SAASyG,CAAU;AAAA,IAAA;AAAA,EAEtD,GAEMwL,IAAsBD,EAAqBR,CAAW,GACtDU,KAAoBF,EAAqB5E,CAAS,GAGlD+E,KAAmB,CAACnS,MACpBA,EAAM,SAAS,SACV,gBAAAzB,EAACwH,IAAA,EAAkB,WAAU,wBAAA,CAAwB,IACnD,CAAC,SAAS,OAAO,OAAO,OAAO,OAAO,iBAAiB,uBAAuB,gBAAgB,cAAc,QAAQ,EAAE,SAAS/F,EAAM,IAAI,IAErIsE,GAAetE,EAAM,MAAM,wBAAwB,IAGzD,gBAAAzB,EAACuH,IAAA,EAAc,WAAU,yBAAA,CAAyB,GAKvDsM,KAAoB,CAACpS,MACrBA,EAAM,SAAS,SACV,gBAAAzB,EAAC,QAAA,EAAK,WAAU,gFAA+E,UAAA,KAAC,IAC9F,CAAC,SAAS,OAAO,OAAO,OAAO,OAAO,iBAAiB,QAAQ,EAAE,SAASyB,EAAM,IAAI,IACtF,gBAAAzB,EAAC,QAAA,EAAK,WAAU,kEAAiE,UAAA,KAAC,IAElF,gBAAAA,EAAC,QAAA,EAAK,WAAU,sEAAqE,UAAA,KAAC,GAI3F8T,KAAoB,CAACpJ,MAAsB;AAE/C,UAAMqJ,IAAe1E,GAAa3E,GAAWlE,CAAM,GAE7CwN,KADwB9E,GAAsB6E,CAAY,EAClB,CAAC,GAAG,YAAY;AAE9D,IAAArC,EAAe5G,GAAO;AAAA,MACpB,QAAQJ;AAAA,MACR,UAAUsJ;AAAA,MACV,QAAQ,CAAA;AAAA,MACR,WAAW;AAAA;AAAA,IAAA,CACZ,GACDhC,EAAuB,EAAK;AAAA,EAC9B,GAEMiC,KAAuB,CAACzI,MAAqB;AACjD,IAAAkG,EAAe5G,GAAO;AAAA,MACpB,GAAG5K;AAAA,MACH,UAAAsL;AAAA,MACA,QAAQ,CAAA;AAAA;AAAA,MACR,WAAW;AAAA;AAAA,IAAA,CACZ,GACD0G,EAA0B,EAAK;AAAA,EACjC,GAEMgC,KAAqB,CAACzI,MAAkB;AAC5C,IAAAiG,EAAe5G,GAAO;AAAA,MACpB,GAAG5K;AAAA,MACH,QAAAuL;AAAA,IAAA,CACD;AAAA,EACH,GAGM0I,KAAwB,CAAClS,MAAiC;AAC9D,IAAAyP,EAAe5G,GAAO;AAAA,MACpB,GAAG5K;AAAA,MACH,WAAA+B;AAAA,IAAA,CACD;AAAA,EACH,GAEMmS,IAAwB,CAACC,MAAgC;AAG7D,QAFAjC,EAA2B,EAAK,GAE5BiC,MAAiB;AAEnB,UAAI3B,EAAY,aAAaA,EAAY,SAAS;AAChD,cAAMzQ,IAAYyQ,EAAY,cAAcA,EAAY,UACpDA,EAAY,YACZ,CAACA,EAAY,WAAWA,EAAY,OAAO;AAC/C,QAAAyB,GAAsBlS,CAAS;AAAA,MACjC;AAAA,eACSsO,GAAoB8D,CAAY,GAAG;AAE5C,YAAMC,IAAiBrE,GAA4BoE,GAAczB,CAAW;AAC5E,MAAAuB,GAAsBG,CAAc;AAAA,IACtC,OAAO;AAEL,YAAMA,IAAiBrE,GAA4BoE,CAAY;AAC/D,MAAAF,GAAsBG,CAAc;AAAA,IACtC;AAEA,IAAA7B,EAAa4B,CAAY;AAAA,EAC3B,GAEME,IAAyB,CAAC9S,GAAgC4L,MAAkB;AAChF,UAAMmH,IAAiB,EAAE,GAAG9B,GAAa,CAACjR,CAAK,GAAG4L,EAAA;AAGlD,QAFAsF,EAAe6B,CAAc,GAEzBtE,MAAc,YAAYsE,EAAe,WAAW;AACtD,YAAMvS,KAAY,CAACuS,EAAe,WAAWA,EAAe,cAAcA,EAAe,UACrFA,EAAe,YACf,CAACA,EAAe,WAAWA,EAAe,OAAO;AACrD,MAAAL,GAAsBlS,EAAS;AAAA,IACjC;AAAA,EACF,GAEMwS,KAAqB,CAACpH,MAAkB;AAG5C,QAFAwF,EAAexF,CAAK,GAEhBkD,GAAoBL,CAAS,GAAG;AAClC,YAAMoE,IAAiBrE,GAA4BC,GAAW7C,CAAK;AACnE,MAAA8G,GAAsBG,CAAc;AAAA,IACtC;AAAA,EACF,GAEMI,KAAqBrJ,GAAmB,KAAK,CAAAsJ,MAAOA,EAAI,UAAUzE,CAAS,GAAG,SAAS;AAE7F,SACE,gBAAAlQ,EAAC,SAAI,KAAKuS,GAAc,WAAU,wDAEhC,UAAA,gBAAAxS,EAAC,OAAA,EAAI,WAAU,2DAEZ,UAAA;AAAA,IAAA,CAAC6R,KACA,gBAAA7R,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,MAAA,gBAAAC,EAACuR,IAAA,EAAW,WAAU,sCAAA,CAAsC;AAAA,MAG5D,gBAAAxR,EAAC,OAAA,EAAI,WAAU,2BACf,UAAA;AAAA,QAAA,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS+S;AAAA,YACT,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAA9S,EAAC,UAAK,WAAU,YACb,UAAAkT,IACC,gBAAAlT,EAAC,UAAK,WAAU,eAAe,UAAAkT,EAAc,KAAA,CAAK,IAElD,gBAAAlT,EAAC,QAAA,EAAK,WAAU,sBAAqB,6BAAe,EAAA,CAExD;AAAA,gCACCkH,IAAA,EAAgB,WAAW,iEAC1B6K,IAAsB,yBAAyB,EACjD,GAAA,CAAI;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGLA,KACC,gBAAAhS,EAAC,OAAA,EAAI,WAAU,yHAEb,UAAA;AAAA,UAAA,gBAAAC,EAAC,SAAI,WAAU,iCACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,YAAA,gBAAAC,EAACwR,IAAA,EAAW,WAAU,gFAAA,CAAgF;AAAA,YACtG,gBAAAxR;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,KAAKwS;AAAA,gBACL,MAAK;AAAA,gBACL,aAAY;AAAA,gBACZ,OAAOH;AAAA,gBACP,UAAU,CAAC3Q,MAAM4Q,EAAmB5Q,EAAE,OAAO,KAAK;AAAA,gBAClD,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ,EAAA,CACF,EAAA,CACF;AAAA,UAGA,gBAAA3B,EAAC,OAAA,EAAI,WAAU,4BAEZ,UAAA;AAAA,YAAA2T,EAAoB,SAAS,KAC5B,gBAAA3T,EAAC,OAAA,EACC,UAAA;AAAA,cAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,wGAAuG,UAAA;AAAA,gBAAA;AAAA,gBAClG2T,EAAoB;AAAA,gBAAO;AAAA,cAAA,GAC/C;AAAA,cACCA,EAAoB,IAAI,CAACjS,MACxB,gBAAAzB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,SAAS,MAAM8T,GAAkBrS,EAAM,IAAI;AAAA,kBAC3C,WAAW,6GACTA,EAAM,SAASvB,EAAO,SAAS,6BAA6B,wBAC9D;AAAA,kBAEA,UAAA,gBAAAH,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,oBAAA6T,GAAiBnS,CAAK;AAAA,oBACvB,gBAAA1B,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,sBAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,wBAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,wBAAwB,UAAAyB,EAAM,MAAK;AAAA,wBAClDoS,GAAkBpS,CAAK;AAAA,sBAAA,GAC1B;AAAA,sBACCA,EAAM,UAAUA,EAAM,0BACpB,OAAA,EAAI,WAAU,uCAAuC,UAAAA,EAAM,MAAA,CAAM;AAAA,oBAAA,EAAA,CAEtE;AAAA,kBAAA,EAAA,CACF;AAAA,gBAAA;AAAA,gBAjBK,SAASA,EAAM,IAAI;AAAA,cAAA,CAmB3B;AAAA,YAAA,GACH;AAAA,8BAID,OAAA,EACE,UAAA;AAAA,cAAAiS,EAAoB,SAAS,KAC5B,gBAAA3T,EAAC,OAAA,EAAI,WAAU,wGAAuG,UAAA;AAAA,gBAAA;AAAA,gBAC7F4T,GAAkB;AAAA,gBAAO;AAAA,cAAA,GAClD;AAAA,cAEDA,GAAkB,IAAI,CAAClS,MACtB,gBAAAzB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,SAAS,MAAM8T,GAAkBrS,EAAM,IAAI;AAAA,kBAC3C,WAAW,6GACTA,EAAM,SAASvB,EAAO,SAAS,6BAA6B,wBAC9D;AAAA,kBAEA,UAAA,gBAAAH,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,oBAAA6T,GAAiBnS,CAAK;AAAA,oBACvB,gBAAA1B,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,sBAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,wBAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,wBAAwB,UAAAyB,EAAM,MAAK;AAAA,wBAClDoS,GAAkBpS,CAAK;AAAA,sBAAA,GAC1B;AAAA,sBACCA,EAAM,UAAUA,EAAM,0BACpB,OAAA,EAAI,WAAU,uCAAuC,UAAAA,EAAM,MAAA,CAAM;AAAA,oBAAA,EAAA,CAEtE;AAAA,kBAAA,EAAA,CACF;AAAA,gBAAA;AAAA,gBAjBK,OAAOA,EAAM,IAAI;AAAA,cAAA,CAmBzB;AAAA,YAAA,GACH;AAAA,YAGCkS,GAAkB,WAAW,KAC5B,gBAAA5T,EAAC,OAAA,EAAI,WAAU,oDAAmD,UAAA;AAAA,cAAA;AAAA,cACrCsS;AAAA,cAAgB;AAAA,YAAA,EAAA,CAC7C;AAAA,UAAA,EAAA,CAEJ;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA,GACA;AAAA,IAIDa,KACC,gBAAAnT,EAAC,OAAA,EAAI,WAAU,0DAEZ,UAAA;AAAA,MAAA,CAAC8R,KACA,gBAAA9R,EAAC,OAAA,EAAI,WAAU,qBACf,UAAA;AAAA,QAAA,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAASiT;AAAA,YACT,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAAhT,EAAC,QAAA,EAAK,WAAU,YACb,UAAAmT,EAAmB,KAAK,CAAAyB,MAAMA,EAAG,aAAa1U,EAAO,QAAQ,GAAG,SAASA,EAAO,UACnF;AAAA,gCACCgH,IAAA,EAAgB,WAAW,iEAC1B+K,IAAyB,yBAAyB,EACpD,GAAA,CAAI;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGLA,uBACE,OAAA,EAAI,WAAU,yHACZ,UAAAkB,EAAmB,IAAI,CAAC3H,MACvB,gBAAAxL;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,SAAS,MAAMiU,GAAqBzI,EAAS,QAAQ;AAAA,YACrD,WAAW,6GACTA,EAAS,aAAatL,EAAO,WAAW,6BAA6B,wBACvE;AAAA,YAEC,UAAAsL,EAAS;AAAA,UAAA;AAAA,UANLA,EAAS;AAAA,QAAA,CAQjB,EAAA,CACH;AAAA,MAAA,GAEF;AAAA,MAIF,gBAAAxL,EAAC,OAAA,EAAI,WAAU,kBACZ,UAAAoT;AAAA;AAAA,QAEC,gBAAArT,EAAC,OAAA,EAAI,WAAU,2BAEb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,YAAA,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAM;AACb,kBAAAmS,EAA0B,EAAK,GAC/BE,EAA2B,CAACD,CAAuB;AAAA,gBACrD;AAAA,gBACA,WAAU;AAAA,gBAEV,UAAA;AAAA,kBAAA,gBAAAnS,EAAC,QAAA,EAAK,WAAU,YAAY,UAAA0U,IAAmB;AAAA,oCAC9CxN,IAAA,EAAgB,WAAW,iEAC1BiL,IAA0B,yBAAyB,EACrD,GAAA,CAAI;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAGLA,uBACE,OAAA,EAAI,WAAU,yHACZ,UAAA9G,GAAmB,IAAI,CAACmI,MACvB,gBAAAxT;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,SAAS,MAAMoU,EAAsBZ,EAAO,KAAK;AAAA,gBACjD,WAAW,6GACTA,EAAO,UAAUtD,IAAY,6BAA6B,wBAC5D;AAAA,gBAEC,UAAAsD,EAAO;AAAA,cAAA;AAAA,cANHA,EAAO;AAAA,YAAA,CAQf,EAAA,CACH;AAAA,UAAA,GAEJ;AAAA,UAGCtD,MAAc,WACb,gBAAAnQ,EAAAoJ,IAAA,EACE,UAAA;AAAA,YAAA,gBAAAnJ;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO0S,EAAY;AAAA,gBACnB,UAAU,CAAChR,MAAM6S,EAAuB,aAAa7S,EAAE,OAAO,KAAK;AAAA,gBACnE,aAAY;AAAA,gBACZ,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAEZ,gBAAA1B;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO0S,EAAY;AAAA,gBACnB,UAAU,CAAChR,MAAM6S,EAAuB,WAAW7S,EAAE,OAAO,KAAK;AAAA,gBACjE,aAAY;AAAA,gBACZ,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ,EAAA,CACF,IACE6O,GAAoBL,CAAS,IAC/B,gBAAAnQ,EAAAoJ,IAAA,EACE,UAAA;AAAA,YAAA,gBAAAnJ;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,KAAI;AAAA,gBACJ,KAAI;AAAA,gBACJ,OAAO4S;AAAA,gBACP,UAAU,CAAClR,MAAM+S,GAAmB,KAAK,IAAI,GAAG,SAAS/S,EAAE,OAAO,KAAK,KAAK,CAAC,CAAC;AAAA,gBAC9E,aAAY;AAAA,gBACZ,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAEZ,gBAAA1B,EAAC,OAAA,EAAI,WAAU,2CACZ,UAAAkQ,EAAU,QAAQ,WAAW,EAAE,EAAE,QAAQ,KAAK,GAAG,EAAA,CACpD;AAAA,UAAA,EAAA,CACF,IACE;AAAA,QAAA,EAAA,CACN;AAAA;AAAA;AAAA,QAGA,gBAAAlQ;AAAA,UAACuL;AAAA,UAAA;AAAA,YACC,WAAWrL,EAAO;AAAA,YAClB,UAAUA,EAAO;AAAA,YACjB,QAAQA,EAAO;AAAA,YACf,gBAAgBgU;AAAA,YAChB,QAAA1N;AAAA,UAAA;AAAA,QAAA;AAAA,QACF,CAEJ;AAAA,IAAA,GACF;AAAA,IAID,CAACsL,KACA,gBAAA9R,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS,MAAM2R,EAAe7G,CAAK;AAAA,QACnC,WAAU;AAAA,QACV,OAAM;AAAA,QAEN,UAAA,gBAAA9K,EAACsL,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,MAAA;AAAA,IAAA,EACjC,CACF;AAAA,EAAA,EAAA,CAEJ,EAAA,CACF;AAEJ,GChfMA,KAAY7L,EAAQ,OAAO,GAC3BoV,KAAUpV,EAAQ,KAAK,GAEvBqV,KAA0C,CAAC;AAAA,EAC/C,OAAAC;AAAA,EACA,OAAAjK;AAAA,EACA,eAAAkK;AAAA,EACA,yBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,QAAA1O;AAAA,EACA,OAAApF;AAAA,EACA,OAAA+T,IAAQ;AACV,MAAM;AACJ,QAAM,CAACC,GAAaC,CAAc,IAAIpS,EAAS,EAAK,GAE9CqS,IAAaP,EAAM,SAAS,OAC5BQ,IAAYD,IAAa,QAAQ,MACjC3T,IAAUoT,EAAM,SAGhBS,IAAcL,IAAQ,IAAI,MAAM,KAAK,IAAIA,IAAQ,GAAG,EAAE,CAAC,KAAK,IAC5DM,IAAc,oBACdC,IAAU,eACVC,IAAY,kBAEZC,IAAwB,MAAM;AAClC,QAAIN,GAAY;AACd,YAAMO,IAAWjG,GAAejO,CAAO;AACvC,MAAAqT,EAAclK,GAAO+K,CAAQ;AAAA,IAC/B,OAAO;AACL,YAAMA,IAAWlG,GAAgBhO,CAAO;AACxC,MAAAqT,EAAclK,GAAO+K,CAAQ;AAAA,IAC/B;AAAA,EACF,GAEMC,IAAwB,MAAM;AAClC,QAAI,CAACtP,EAAQ;AAIb,UAAMuP,IADmBnH,GAAoBpI,GAAQpF,CAAK,EACpB,CAAC,GAAG,QAAQ,IAC5C4U,IAAYvG,GAAmBsG,GAAc,UAAU,CAAA,CAAE,GACzDE,IAAa,CAAC,GAAGtU,GAASqU,CAAS;AAEzC,IAAIV,IACFN,EAAclK,GAAO6E,GAAgBsG,CAAU,CAAC,IAEhDjB,EAAclK,GAAO8E,GAAeqG,CAAU,CAAC,GAEjDZ,EAAe,EAAK;AAAA,EACtB,GAEMa,IAAoB,MAAM;AAC9B,QAAI,CAAC1P,EAAQ;AAIb,UAAMuP,IADmBnH,GAAoBpI,GAAQpF,CAAK,EACpB,CAAC,GAAG,QAAQ,IAC5CyU,IAAWlG,GAAgB,CAACF,GAAmBsG,GAAc,UAAU,CAAA,CAAE,CAAC,CAAC,GAC3EE,IAAa,CAAC,GAAGtU,GAASkU,CAAQ;AAExC,IAAIP,IACFN,EAAclK,GAAO6E,GAAgBsG,CAAU,CAAC,IAEhDjB,EAAclK,GAAO8E,GAAeqG,CAAU,CAAC,GAEjDZ,EAAe,EAAK;AAAA,EACtB,GAEMc,IAAmB,MAAM;AAC7B,QAAI,CAAC3P,EAAQ;AAIb,UAAMuP,IADmBnH,GAAoBpI,GAAQpF,CAAK,EACpB,CAAC,GAAG,QAAQ,IAC5CyU,IAAWjG,GAAe,CAACH,GAAmBsG,GAAc,UAAU,CAAA,CAAE,CAAC,CAAC,GAC1EE,IAAa,CAAC,GAAGtU,GAASkU,CAAQ;AAExC,IAAIP,IACFN,EAAclK,GAAO6E,GAAgBsG,CAAU,CAAC,IAEhDjB,EAAclK,GAAO8E,GAAeqG,CAAU,CAAC,GAEjDZ,EAAe,EAAK;AAAA,EACtB,GAEMe,IAAqB,CAACC,GAAqBL,MAA4B;AAC3E,UAAMC,IAAa,CAAC,GAAGtU,CAAO;AAC9B,IAAAsU,EAAWI,CAAW,IAAIL,GAEtBV,IACFN,EAAclK,GAAO6E,GAAgBsG,CAAU,CAAC,IAEhDjB,EAAclK,GAAO8E,GAAeqG,CAAU,CAAC;AAAA,EAEnD,GAEMK,IAAqB,CAACD,MAAwB;AAClD,UAAMJ,IAAatU,EAAQ,OAAO,CAAC4U,GAAGC,MAAMA,MAAMH,CAAW;AAG7D,QAAIJ,EAAW,WAAW,GAAG;AAC3B,MAAAf,EAAcpK,CAAK;AACnB;AAAA,IACF;AAGA,QAAImL,EAAW,WAAW,GAAG;AAC3B,YAAMJ,IAAWd,EAAM,SAAS,QAAQpF,GAAgBsG,CAAU,IAAIrG,GAAeqG,CAAU;AAE/F,MAAIhB,IAEFA,EAAwBnK,GAAO+K,CAAQ,IAGvCb,EAAclK,GAAO+K,CAAQ;AAE/B;AAAA,IACF;AAGA,UAAMY,IAAe1B,EAAM,SAAS,QAAQpF,GAAgBsG,CAAU,IAAIrG,GAAeqG,CAAU;AACnG,IAAAjB,EAAclK,GAAO2L,CAAY;AAAA,EACnC,GAEMC,IAA0B,CAACL,GAAqBR,MAA0B;AAC9E,UAAMI,IAAa,CAAC,GAAGtU,CAAO;AAC9B,IAAAsU,EAAWI,CAAW,IAAIR,GAEtBP,IACFN,EAAclK,GAAO6E,GAAgBsG,CAAU,CAAC,IAEhDjB,EAAclK,GAAO8E,GAAeqG,CAAU,CAAC;AAAA,EAEnD,GAEMU,IAA0B,CAACN,MAAwB;AACvD,IAAAC,EAAmBD,CAAW;AAAA,EAChC;AAEA,SACE,gBAAAtW,EAAC,SAAI,WAAW,GAAGyV,CAAW,IAAIC,CAAW,aAAaC,CAAO,6BAE/D,UAAA;AAAA,IAAA,gBAAA3V,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,QAAA,gBAAAC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS4V;AAAA,YACT,WAAW,8CAA8CD,CAAS;AAAA,YAEjE,UAAAJ;AAAA,UAAA;AAAA,QAAA;AAAA,QAEH,gBAAAxV,EAAC,QAAA,EAAK,WAAU,kCACb,UAAA;AAAA,UAAA4B,EAAQ;AAAA,UAAO;AAAA,UAAWA,EAAQ,WAAW,IAAI,MAAM;AAAA,QAAA,EAAA,CAC1D;AAAA,MAAA,GACF;AAAA,MAEA,gBAAA5B,EAAC,OAAA,EAAI,WAAU,+BAEb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAMqV,EAAe,CAACD,CAAW;AAAA,cAC1C,WAAU;AAAA,cACV,OAAM;AAAA,cAEN,UAAA,gBAAApV,EAAC6U,IAAA,EAAQ,WAAU,UAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAG9BO,KACC,gBAAArV,EAAC,OAAA,EAAI,WAAU,8FACb,UAAA;AAAA,YAAA,gBAAAC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS8V;AAAA,gBACT,WAAU;AAAA,gBACX,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAGD,gBAAA9V;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAASkW;AAAA,gBACT,WAAU;AAAA,gBACX,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAGD,gBAAAlW;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAASmW;AAAA,gBACT,WAAU;AAAA,gBACX,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UAED,EAAA,CACF;AAAA,QAAA,GAEJ;AAAA,QAGA,gBAAAnW;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAMkV,EAAcpK,CAAK;AAAA,YAClC,WAAU;AAAA,YACV,OAAM;AAAA,YAEN,UAAA,gBAAA9K,EAACsL,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACjC,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAGA,gBAAAvL,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,MAAA4B,EAAQ,IAAI,CAACzB,GAAQmW,MAChB7H,GAAetO,CAAM,IAErB,gBAAAF;AAAA,QAACyR;AAAA,QAAA;AAAA,UAEC,QAAAvR;AAAA,UACA,OAAOmW;AAAA,UACP,gBAAgBD;AAAA,UAChB,gBAAgBE;AAAA,UAChB,QAAA9P;AAAA,UACA,OAAApF;AAAA,QAAA;AAAA,QANKiV;AAAA,MAAA,IASA5H,GAAcvO,CAAM,IAE3B,gBAAAF;AAAA,QAAC8U;AAAA,QAAA;AAAA,UAEC,OAAO5U;AAAA,UACP,OAAOmW;AAAA,UACP,eAAeK;AAAA,UACf,eAAeC;AAAA,UACf,QAAAnQ;AAAA,UACA,OAAApF;AAAA,UACA,OAAO+T,IAAQ;AAAA,QAAA;AAAA,QAPVkB;AAAA,MAAA,IAWJ,IACR;AAAA,MAGA1U,EAAQ,WAAW,KAClB,gBAAA5B,EAAC,OAAA,EAAI,WAAU,+CAA8C,UAAA;AAAA,QAAA;AAAA,QAE3D,gBAAAC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS8V;AAAA,YACT,WAAU;AAAA,YACX,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,EAAA,CACF;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ,GCrPMjB,KAAUpV,EAAQ,KAAK,GACvB8R,KAAa9R,EAAQ,QAAQ,GAE7BmX,KAA8C,CAAC;AAAA,EACnD,SAAAjV;AAAA,EACA,QAAA6E;AAAA,EACA,OAAApF;AAAA,EACA,iBAAAyV;AAAA,EACA,mBAAAjF,IAAoB;AACtB,MAAM;AAGJ,QAAMkF,IAAmBvH,GAAa5N,CAAO,GAGvCoV,IAAsBvQ,IAASwI,GAAuBxI,CAAM,IAAI,CAAA,GAChEwQ,IAAsBD,EAAoB,SAAS,GAEnDjB,IAAwB,MAAM;AAClC,QAAI,CAACkB,EAAqB;AAG1B,UAAMjB,IAAegB,EAAoB,CAAC,GAAG,QAAQ,IAC/Cf,IAAYvG,GAAmBsG,GAAc,UAAU,CAAA,CAAE;AAO/D,QAAIpU,EAAQ,WAAW;AAErB,MAAAkV,EAAgB,CAACb,CAAS,CAAC;AAAA,aAClBrU,EAAQ,WAAW,KAAK6M,GAAe7M,EAAQ,CAAC,CAAC,GAAG;AAE7D,YAAMsV,IAAWtH,GAAgB,CAAChO,EAAQ,CAAC,GAAGqU,CAAS,CAAC;AACxD,MAAAa,EAAgB,CAACI,CAAQ,CAAC;AAAA,IAC5B,WAAWtV,EAAQ,WAAW,KAAK+M,GAAY/M,EAAQ,CAAC,CAAC,GAAG;AAE1D,YAAMuV,IAAmBvV,EAAQ,CAAC,GAC5BwV,IAAkBxH,GAAgB,CAAC,GAAGuH,EAAiB,SAASlB,CAAS,CAAC;AAChF,MAAAa,EAAgB,CAACM,CAAe,CAAC;AAAA,IACnC,WAAWxV,EAAQ,WAAW,KAAKgN,GAAWhN,EAAQ,CAAC,CAAC,GAAG;AAEzD,YAAMyV,IAAkBzV,EAAQ,CAAC,GAC3B0V,IAAiBzH,GAAe,CAAC,GAAGwH,EAAgB,SAASpB,CAAS,CAAC;AAC7E,MAAAa,EAAgB,CAACQ,CAAc,CAAC;AAAA,IAClC;AAEE,MAAAR,EAAgB,CAAC,GAAGlV,GAASqU,CAAS,CAAC;AAAA,EAE3C,GAGMI,IAAqB,CAACtL,GAAekL,MAA4B;AACrE,UAAMC,IAAa,CAAC,GAAGtU,CAAO;AAC9B,IAAAsU,EAAWnL,CAAK,IAAIkL,GACpBa,EAAgBZ,CAAU;AAAA,EAC5B,GAEMK,IAAqB,CAACxL,MAAkB;AAG5C,UAAMmL,IAAatU,EAAQ,OAAO,CAAC4U,GAAGC,MAAMA,MAAM1L,CAAK;AACvD,IAAA+L,EAAgBZ,CAAU;AAAA,EAC5B,GAEMqB,IAAoB,CAACxM,GAAe+K,MAA0B;AAClE,UAAMI,IAAa,CAAC,GAAGtU,CAAO;AAC9B,IAAAsU,EAAWnL,CAAK,IAAI+K,GACpBgB,EAAgBZ,CAAU;AAAA,EAC5B,GAEMsB,IAA8B,CAACzM,GAAe+K,MAA0B;AAC5E,UAAMI,IAAa,CAAC,GAAGtU,CAAO;AAI9B,IAAIkU,EAAS,QAAQ,WAAW,KAAKrH,GAAeqH,EAAS,QAAQ,CAAC,CAAC,IAErEI,EAAWnL,CAAK,IAAI+K,EAAS,QAAQ,CAAC,IAEtCI,EAAWnL,CAAK,IAAI+K,GAGtBgB,EAAgBZ,CAAU;AAAA,EAC5B,GAEMuB,IAAoB,MAAM;AAE9B,IAAAX,EAAgB,CAAA,CAAE;AAAA,EACpB,GAEMY,IAAwB,MAAM;AAClC,IAAAZ,EAAgB,CAAA,CAAE;AAAA,EACpB;AAEA,SACE,gBAAA9W,EAAC,OAAA,EAAI,WAAU,oDAEZ,UAAA;AAAA,IAAA,CAAC6R,KACA,gBAAA7R,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,QAAA,gBAAAC,EAACuR,IAAA,EAAW,WAAU,kCAAA,CAAkC;AAAA,QACxD,gBAAAxR,EAAC,MAAA,EAAG,WAAU,gDAA+C,UAAA;AAAA,UAAA;AAAA,UACjD+W;AAAA,UAAiB;AAAA,QAAA,EAAA,CAC7B;AAAA,MAAA,GACF;AAAA,MAEA,gBAAA/W,EAAC,OAAA,EAAI,WAAU,+BAEZ,UAAA;AAAA,QAAA4B,EAAQ,SAAS,KAChB,gBAAA3B;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAASyX;AAAA,YACT,WAAU;AAAA,YACX,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAMH,gBAAA1X;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS+V;AAAA,YACT,UAAU,CAACkB;AAAA,YACX,WAAW,uGACTA,IACI,qGACA,uFACN;AAAA,YAEA,UAAA;AAAA,cAAA,gBAAAhX,EAAC6U,IAAA,EAAQ,WAAU,UAAA,CAAU;AAAA,cAC7B,gBAAA7U,EAAC,UAAK,UAAA,aAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAClB,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAID2B,EAAQ,SAAS,KAChB,gBAAA3B,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA2B,EAAQ,IAAI,CAACzB,GAAQ4K,MAEhB0D,GAAetO,CAAM,IAErB,gBAAAF;AAAA,MAACyR;AAAA,MAAA;AAAA,QAEC,QAAAvR;AAAA,QACA,OAAA4K;AAAA,QACA,gBAAgBsL;AAAA,QAChB,gBAAgBE;AAAA,QAChB,QAAA9P;AAAA,QACA,OAAApF;AAAA,QACA,mBAAAwQ;AAAA,QACA,kBAAkBA;AAAA,MAAA;AAAA,MARb9G;AAAA,IAAA,IAWA2D,GAAcvO,CAAM,IAE3B,gBAAAF;AAAA,MAAC8U;AAAA,MAAA;AAAA,QAEC,OAAO5U;AAAA,QACP,OAAA4K;AAAA,QACA,eAAewM;AAAA,QACf,yBAAyBC;AAAA,QACzB,eAAeC;AAAA,QACf,QAAAhR;AAAA,QACA,OAAApF;AAAA,QACA,OAAO;AAAA,MAAA;AAAA,MARF0J;AAAA,IAAA,IAYJ,IACR,EAAA,CACH;AAAA,EAAA,GAGJ;AAEJ,GC/LMQ,KAAY7L,EAAQ,OAAO,GAC3BiY,KAAejY,EAAQ,eAAe,GACtCyH,KAAkBzH,EAAQ,aAAa,GAavCkY,KAAsD,CAAC;AAAA,EAC3D,eAAAzM;AAAA,EACA,yBAAA0M;AAAA,EACA,kBAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,uBAAAC;AAAA,EACA,UAAAC;AAAA,EACA,mBAAApG,IAAoB;AAAA,EACpB,kBAAAE,IAAmB;AACrB,MAAM;AAEJ,QAAMmG,IAAsB,MAAqB;AAC/C,QAAI,CAACJ,EAAkB,QAAO;AAE9B,QAAI,MAAM,QAAQA,CAAgB;AAChC,aAAO;AAIT,UAAMxE,IAAqBwE,EAAiB,MAAM,iDAAiD;AACnG,QAAIxE,GAAoB;AACtB,YAAM,CAAA,EAAA,EAAKhD,CAAI,IAAIgD;AAEnB,aAAO,UADYhD,MAAS,SAAS,SAASA,MAAS,UAAU,UAAUA,MAAS,WAAW,WAAWA,MAAS,aAAa,aAAa,OAClH;AAAA,IAC7B;AAGA,eAAWmD,KAAUnI;AACnB,UAAImI,EAAO,UAAU,YAAY,CAACjD,GAAoBiD,EAAO,KAAK,KAAKvD,GAA4BuD,EAAO,KAAK,MAAMqE;AACnH,eAAOrE,EAAO;AAIlB,WAAO;AAAA,EACT,GAEM0E,IAAkB,MAA8C;AACpE,QAAI,MAAM,QAAQL,CAAgB,KAAKA,EAAiB,UAAU;AAChE,aAAO;AAAA,QACL,WAAWA,EAAiB,CAAC,KAAK;AAAA,QAClC,SAASA,EAAiB,CAAC,KAAKA,EAAiB,CAAC,KAAK;AAAA,MAAA;AAK3D,UAAMM,IAAQ3H,GAAkB,oBAAI,MAAM;AAC1C,WAAO,EAAE,WAAW2H,GAAO,SAASA,EAAA;AAAA,EACtC,GAEMC,IAAmB,MAAc;AACrC,QAAI,CAACP,KAAoB,MAAM,QAAQA,CAAgB,EAAG,QAAO;AAGjE,UAAMxE,IAAqBwE,EAAiB,MAAM,iDAAiD;AACnG,WAAIxE,KACK,SAASA,EAAmB,CAAC,CAAC,KAAK;AAAA,EAI9C,GAEM,CAACnD,GAAWuC,CAAY,IAAIxP,EAAwBgV,GAAqB,GACzE,CAACvF,GAAaC,CAAc,IAAI1P,EAASiV,GAAiB,GAC1D,CAACtF,GAAaC,CAAc,IAAI5P,EAAiBmV,GAAkB,GACnE,CAACC,GAAqBC,CAAsB,IAAIrV,EAAS,EAAK,GAC9D,CAACsV,GAA6BC,CAA8B,IAAIvV,EAAS,EAAK,GAC9EsP,IAAepP,GAAuB,IAAI;AAGhD,EAAAK,GAAU,MAAM;AACd,UAAMuJ,IAAqB,CAACjH,MAAsB;AAChD,MAAIyM,EAAa,WAAW,CAACA,EAAa,QAAQ,SAASzM,EAAM,MAAc,MAC7EwS,EAAuB,EAAK,GAC5BE,EAA+B,EAAK;AAAA,IAExC;AAEA,oBAAS,iBAAiB,aAAazL,CAAkB,GAClD,MAAM,SAAS,oBAAoB,aAAaA,CAAkB;AAAA,EAC3E,GAAG,CAAA,CAAE;AAGL,QAAM0L,IAAoC,MAAM;AAC9C,IAAAH,EAAuB,EAAK,GAC5BE,EAA+B,CAACD,CAA2B;AAAA,EAC7D,GAEMG,IAA4B,MAAM;AACtC,IAAAF,EAA+B,EAAK,GACpCF,EAAuB,CAACD,CAAmB;AAAA,EAC7C,GAEMjE,IAAwB,CAACC,MAAgC;AAI7D,QAHA5B,EAAa4B,CAAY,GACzBiE,EAAuB,EAAK,GAExBjE,MAAiB;AAEnB,UAAI3B,EAAY,aAAaA,EAAY,SAAS;AAChD,cAAMzQ,IAAYyQ,EAAY,cAAcA,EAAY,UACpDA,EAAY,YACZ,CAACA,EAAY,WAAWA,EAAY,OAAO;AAC/C,QAAAoF,EAAkB5M,GAAejJ,CAAS;AAAA,MAC5C;AAAA,eACSsO,GAAoB8D,CAAY,GAAG;AAE5C,YAAMC,IAAiBrE,GAA4BoE,GAAczB,CAAW;AAC5E,MAAAkF,EAAkB5M,GAAeoJ,CAAc;AAAA,IACjD,OAAO;AAEL,YAAMA,IAAiBrE,GAA4BoE,CAAY;AAC/D,MAAAyD,EAAkB5M,GAAeoJ,CAAc;AAAA,IACjD;AAAA,EACF,GAEMC,IAAyB,CAAC9S,GAAgC4L,MAAkB;AAChF,UAAMmH,IAAiB,EAAE,GAAG9B,GAAa,CAACjR,CAAK,GAAG4L,EAAA;AAGlD,QAFAsF,EAAe6B,CAAc,GAEzBtE,MAAc,YAAYsE,EAAe,WAAW;AACtD,YAAMvS,IAAY,CAACuS,EAAe,WAAWA,EAAe,cAAcA,EAAe,UACrFA,EAAe,YACf,CAACA,EAAe,WAAWA,EAAe,OAAO;AACrD,MAAAsD,EAAkB5M,GAAejJ,CAAS;AAAA,IAC5C;AAAA,EACF,GAEMwS,IAAqB,CAACpH,MAAkB;AAG5C,QAFAwF,EAAexF,CAAK,GAEhBkD,GAAoBL,CAAS,GAAG;AAClC,YAAMoE,IAAiBrE,GAA4BC,GAAW7C,CAAK;AACnE,MAAAyK,EAAkB5M,GAAeoJ,CAAc;AAAA,IACjD;AAAA,EACF,GAEMqE,IAA4B,CAACC,MAA6B;AAC9D,IAAAJ,EAA+B,EAAK,GACpCT,EAAsB7M,GAAe0N,CAAgB;AAAA,EACvD,GAEMlE,IAAqBrJ,GAAmB,KAAK,CAAAsJ,MAAOA,EAAI,UAAUzE,CAAS,GAAG,SAAS;AAE7F,SACE,gBAAAlQ,EAAC,SAAI,KAAKuS,GAAc,WAAU,wDAEhC,UAAA,gBAAAxS,EAAC,OAAA,EAAI,WAAU,2DAEZ,UAAA;AAAA,IAAA,CAAC6R,KACA,gBAAA7R,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,MAAA,gBAAAC,EAAC0X,IAAA,EAAa,WAAU,sCAAA,CAAsC;AAAA,MAG9D,gBAAA3X,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,QAAA,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS0Y;AAAA,YACT,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAAzY,EAAC,QAAA,EAAK,WAAU,YAAY,UAAAkL,GAAc;AAAA,gCACzChE,IAAA,EAAgB,WAAW,4DAC1BqR,IAA8B,yBAAyB,EACzD,GAAA,CAAI;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGLA,uBACE,OAAA,EAAI,WAAU,yHACZ,UAAAX,EAAwB,IAAI,CAACrW,MAC5B,gBAAAvB;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,SAAS,MAAM2Y,EAA0BpX,CAAE;AAAA,YAC3C,WAAW,+GACTA,MAAO2J,IAAgB,oEAAoE,wBAC7F;AAAA,YAEC,UAAA3J;AAAA,UAAA;AAAA,UANIA;AAAA,QAAA,CAQR,EAAA,CACH;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA,GACF;AAAA,sBAID,OAAA,EAAI,WAAU,0DAEb,UAAA,gBAAAxB,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,MAAA,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS2Y;AAAA,UACT,WAAU;AAAA,UAEV,UAAA;AAAA,YAAA,gBAAA1Y,EAAC,QAAA,EAAK,WAAU,YAAY,UAAA0U,GAAmB;AAAA,8BAC9CxN,IAAA,EAAgB,WAAW,iEAC1BmR,IAAsB,yBAAyB,EACjD,GAAA,CAAI;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAGLA,uBACE,OAAA,EAAI,WAAU,yHACZ,UAAAhN,GAAmB,IAAI,CAACmI,MACvB,gBAAAxT;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,SAAS,MAAMoU,EAAsBZ,EAAO,KAAK;AAAA,UACjD,WAAW,+GACTA,EAAO,UAAUtD,IAAY,oEAAoE,wBACnG;AAAA,UAEC,UAAAsD,EAAO;AAAA,QAAA;AAAA,QANHA,EAAO;AAAA,MAAA,CAQf,EAAA,CACH;AAAA,IAAA,EAAA,CAEJ,EAAA,CACF;AAAA,IAGA,gBAAAzT,EAAC,OAAA,EAAI,WAAU,0CACZ,UAAA;AAAA,MAAAmQ,MAAc,WACb,gBAAAnQ,EAAAoJ,IAAA,EAEE,UAAA;AAAA,QAAA,gBAAAnJ,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO0S,EAAY;AAAA,YACnB,UAAU,CAAChR,MAAM6S,EAAuB,aAAa7S,EAAE,OAAO,KAAK;AAAA,YACnE,aAAY;AAAA,YACZ,WAAU;AAAA,UAAA;AAAA,QAAA,GAEd;AAAA,QAGA,gBAAA1B,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO0S,EAAY;AAAA,YACnB,UAAU,CAAChR,MAAM6S,EAAuB,WAAW7S,EAAE,OAAO,KAAK;AAAA,YACjE,aAAY;AAAA,YACZ,WAAU;AAAA,UAAA;AAAA,QAAA,EACZ,CACF;AAAA,MAAA,EAAA,CACF,IACE6O,GAAoBL,CAAS,IAC/B,gBAAAnQ,EAAAoJ,IAAA,EAEE,UAAA;AAAA,QAAA,gBAAAnJ,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAI;AAAA,YACJ,KAAI;AAAA,YACJ,OAAO4S;AAAA,YACP,UAAU,CAAClR,MAAM+S,EAAmB,KAAK,IAAI,GAAG,SAAS/S,EAAE,OAAO,KAAK,KAAK,CAAC,CAAC;AAAA,YAC9E,aAAY;AAAA,YACZ,WAAU;AAAA,UAAA;AAAA,QAAA,GAEd;AAAA,QAGA,gBAAA1B,EAAC,OAAA,EAAI,WAAU,2CACZ,UAAAkQ,EAAU,QAAQ,WAAW,EAAE,EAAE,QAAQ,KAAK,GAAG,EAAA,CACpD;AAAA,MAAA,GACF;AAAA;AAAA,QAGA,gBAAAlQ,EAAC,OAAA,EAAI,WAAU,SAAA,CAAS;AAAA;AAAA,MAIzB,CAAC8R,KACA,gBAAA9R;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS,MAAMgY,EAAS9M,CAAa;AAAA,UACrC,WAAU;AAAA,UACV,OAAM;AAAA,UAEN,UAAA,gBAAAlL,EAACsL,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IACjC,EAAA,CAEJ;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ,GCtSMuJ,KAAUpV,EAAQ,KAAK,GACvBiY,KAAejY,EAAQ,eAAe,GAEtCoZ,KAAkD,CAAC;AAAA,EACvD,gBAAA3X;AAAA,EACA,mBAAA4W;AAAA,EACA,mBAAAgB;AACF,MAAM;AAEJ,QAAMC,IAAoBrI,GAAgC,EAAE,gBAAAxP,GAAgB,GAGtE0W,IAA0B1W,EAAe,OAAO,CAAAK,MAAM,CAACA,EAAG,SAAS,GAGnEyX,IAAiB,OAAO,KAAKD,CAAiB,EAAE,QAEhDE,IAAqB,MAAM;AAC/B,QAAIrB,EAAwB,WAAW,EAAG;AAG1C,UAAMsB,IAAiBtB,EAAwB,CAAC;AAChD,IAAAE,EAAkBoB,EAAe,WAAW,YAAY;AAAA,EAC1D,GAEMC,IAA2B,MAAM;AAErC,WAAO,KAAKJ,CAAiB,EAAE,QAAQ,CAAA7N,MAAiB;AACtD,MAAA4N,EAAkB5N,CAAa;AAAA,IACjC,CAAC;AAAA,EACH;AAGA,SAAI,CAAChK,KAAkBA,EAAe,WAAW,IACxC,OAIP,gBAAAnB,EAAC,OAAA,EAAI,WAAU,oDAEb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,QAAA,gBAAAC,EAAC0X,IAAA,EAAa,WAAU,kCAAA,CAAkC;AAAA,QAC1D,gBAAA3X,EAAC,MAAA,EAAG,WAAU,gDAA+C,UAAA;AAAA,UAAA;AAAA,UAC7CiZ;AAAA,UAAe;AAAA,QAAA,EAAA,CAC/B;AAAA,MAAA,GACF;AAAA,MAEA,gBAAAjZ,EAAC,OAAA,EAAI,WAAU,+BAEZ,UAAA;AAAA,QAAAiZ,IAAiB,KAChB,gBAAAhZ;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAASmZ;AAAA,YACT,WAAU;AAAA,YACX,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAMH,gBAAApZ;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAASkZ;AAAA,YACT,UAAUrB,EAAwB,WAAW;AAAA,YAC7C,WAAW,uGACTA,EAAwB,SAAS,IAC7B,mMACA,uFACN;AAAA,YACA,OAAOA,EAAwB,WAAW,IAAI,iDAAiD;AAAA,YAE/F,UAAA;AAAA,cAAA,gBAAA5X,EAAC6U,IAAA,EAAQ,WAAU,UAAA,CAAU;AAAA,cAC7B,gBAAA7U,EAAC,UAAK,UAAA,iBAAA,CAAc;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACtB,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAGCgZ,IAAiB,KAChB,gBAAAhZ,EAAC,OAAA,EAAI,WAAU,aACZ,UAAAkB,EAAe,IAAI,CAAAK,MAAM;AACxB,UAAI,CAACA,EAAG,UAAW,QAAO;AAE1B,YAAM6X,IAAoBlY,EAAe,IAAI,CAAAmY,MAAKA,EAAE,SAAS;AAE7D,aACE,gBAAArZ;AAAA,QAAC2X;AAAA,QAAA;AAAA,UAEC,eAAepW,EAAG;AAAA,UAClB,yBAAyB6X;AAAA,UACzB,kBAAkB7X,EAAG;AAAA,UACrB,mBAAAuW;AAAA,UACA,uBAAuB,CAACwB,GAAOC,MAAU;AAEvC,YAAAT,EAAkBQ,CAAK,GACvBxB,EAAkByB,GAAOhY,EAAG,SAAU;AAAA,UACxC;AAAA,UACA,UAAUuX;AAAA,QAAA;AAAA,QAVLvX,EAAG;AAAA,MAAA;AAAA,IAad,CAAC,EAAA,CACH;AAAA,EAAA,GAGJ;AAEJ;ACtGA,SAASiY,GAAaC,GAAwB;AAC5C,SAAOA,EAAO,QAAQ,MAAM,GAAG;AACjC;AAKA,SAASC,GAAsBD,GAAwB;AACrD,UAAQA,GAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EAAA;AAEb;AAEA,MAAME,KAAwD,CAAC,EAAE,UAAAC,QAAe;AAC9E,QAAMC,IAAWpa,EAAQ,MAAM,GACzBqa,IAAiBra,EAAQ,cAAc,GACvC2H,IAAc3H,EAAQ,SAAS,GAC/Bsa,IAAYta,EAAQ,OAAO,GAC3Bua,IAAWva,EAAQ,MAAM,GACzBwa,IAAcxa,EAAQ,SAAS,GAC/Bya,IAAYza,EAAQ,OAAO;AAEjC,SACE,gBAAAM,EAAC,OAAA,EAAI,WAAU,4EAEb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,6DACZ,UAAA;AAAA,QAAA,gBAAAC,EAAC6Z,GAAA,EAAS,WAAU,eAAA,CAAe;AAAA,QAAE;AAAA,MAAA,GAEvC;AAAA,MACA,gBAAA9Z,EAAC,OAAA,EAAI,WAAU,iDACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA,SAAK;AAAA,UAC1C,gBAAAA,EAAC,UAAK,WAAU,iCACb,aAAa4Z,EAAS,aAAa,SAAS,EAAA,CAC/C;AAAA,QAAA,GACF;AAAA,QACA,gBAAA7Z,EAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA,UAAM;AAAA,UAC3C,gBAAAA,EAAC,QAAA,EAAK,WAAU,iCAAiC,YAAS,UAAA,CAAU;AAAA,QAAA,GACtE;AAAA,QACA,gBAAAD,EAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA,UAAM;AAAA,4BAC1C,QAAA,EAAK,WAAU,iCAAiC,UAAA4Z,EAAS,aAAa,UAAA,CAAU;AAAA,QAAA,GACnF;AAAA,QACA,gBAAA7Z,EAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA,SAAK;AAAA,4BACzC,QAAA,EAAK,WAAU,iCAAiC,UAAA4Z,EAAS,aAAa,SAAA,CAAS;AAAA,QAAA,EAAA,CAClF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAGA,gBAAA7Z,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,6DACZ,UAAA;AAAA,QAAA,gBAAAC,EAAC+Z,GAAA,EAAU,WAAU,eAAA,CAAe;AAAA,QAAE;AAAA,MAAA,GAExC;AAAA,MACA,gBAAAha,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,yCACb,UAAA4Z,EAAS,YAAY,cACxB;AAAA,UACA,gBAAA5Z,EAAC,QAAA,EAAK,WAAW,+BAA+B0Z,GAAsBE,EAAS,YAAY,MAAM,CAAC,IAC/F,UAAAJ,GAAaI,EAAS,YAAY,MAAM,EAAA,CAC3C;AAAA,QAAA,GACF;AAAA,0BACC,KAAA,EAAE,WAAU,kCACV,UAAAA,EAAS,YAAY,aACxB;AAAA,QACCA,EAAS,YAAY,cAAcA,EAAS,YAAY,WAAW,SAAS,KAC3E,gBAAA7Z,EAAC,WAAA,EAAQ,WAAU,QACjB,UAAA;AAAA,UAAA,gBAAAA,EAAC,WAAA,EAAQ,WAAU,gEAA+D,UAAA;AAAA,YAAA;AAAA,YAC9D6Z,EAAS,YAAY,WAAW;AAAA,YAAO;AAAA,UAAA,GAC3D;AAAA,UACA,gBAAA5Z,EAAC,OAAA,EAAI,WAAU,uBACZ,YAAS,YAAY,WAAW,IAAI,CAAC4K,GAAG4L,MACvC,gBAAAzW,EAAC,OAAA,EAAY,WAAU,6CACrB,UAAA;AAAA,YAAA,gBAAAC,EAAC,QAAA,EAAK,WAAW,aAAa4K,EAAE,aAAagP,EAAS,YAAY,eAAe,8BAA8B,oBAAoB,IAChI,UAAAhP,EAAE,UACL;AAAA,YACA,gBAAA7K,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA;AAAA,cAAA;AAAA,cAC5B6K,EAAE;AAAA,cAAe;AAAA,cAAUA,EAAE;AAAA,YAAA,GACtC;AAAA,YACCA,EAAE,cACD,gBAAA7K,EAAC,QAAA,EAAK,WAAU,gEACd,UAAA;AAAA,cAAA,gBAAAC,EAACia,GAAA,EAAY,WAAU,UAAA,CAAU;AAAA,cAAE;AAAA,YAAA,EAAA,CAErC,IAEA,gBAAAla,EAAC,QAAA,EAAK,WAAU,4DACd,UAAA;AAAA,cAAA,gBAAAC,EAACka,GAAA,EAAU,WAAU,UAAA,CAAU;AAAA,cAAE;AAAA,YAAA,EAAA,CAEnC;AAAA,UAAA,EAAA,GAhBM1D,CAkBV,CACD,EAAA,CACH;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA,GACF;AAAA,IAGCoD,EAAS,UAAU,SAAS,KAC3B,gBAAA7Z,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,6DACZ,UAAA;AAAA,QAAA,gBAAAC,EAACga,GAAA,EAAS,WAAU,eAAA,CAAe;AAAA,QAAE;AAAA,MAAA,GAEvC;AAAA,MACA,gBAAAha,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA4Z,EAAS,UAAU,IAAI,CAACO,GAAIC,MAC3B,gBAAAra,EAAC,OAAA,EAAc,WAAU,qCACvB,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,oCAAoC,UAAA4Z,EAAS,YAAY,cAAa;AAAA,UACtF,gBAAA5Z,EAAC8Z,GAAA,EAAe,WAAU,6BAAA,CAA6B;AAAA,UACvD,gBAAA9Z,EAAC,QAAA,EAAK,WAAU,sCAAsC,YAAG,YAAW;AAAA,UACnEma,EAAG,YACF,gBAAApa,EAAC,QAAA,EAAK,WAAU,oGACb,UAAA;AAAA,YAAAoa,EAAG;AAAA,YAAW;AAAA,YAAMA,EAAG,eAAe,IAAI,MAAM;AAAA,UAAA,EAAA,CACnD,IAEA,gBAAAna,EAAC,QAAA,EAAK,WAAU,4FAA2F,UAAA,UAAA,CAE3G;AAAA,QAAA,GAEJ;AAAA,QACCma,EAAG,aAAaA,EAAG,QAAQA,EAAG,KAAK,SAAS,KAC3C,gBAAAna,EAAC,OAAA,EAAI,WAAU,kBACZ,UAAAma,EAAG,KAAK,IAAI,CAACE,GAAMC,MAClB,gBAAAva,EAAC,OAAA,EAAkB,WAAU,6CAC3B,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,oCAAoC,UAAAqa,EAAK,UAAS;AAAA,UAClE,gBAAAra,EAAC8Z,GAAA,EAAe,WAAU,6BAAA,CAA6B;AAAA,UACvD,gBAAA9Z,EAAC,QAAA,EAAK,WAAU,0BAA0B,YAAK,QAAO;AAAA,UACtD,gBAAAD,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA;AAAA,YAAA;AAAA,YACjCsa,EAAK;AAAA,YAAa;AAAA,YAAGA,EAAK;AAAA,YAAS;AAAA,UAAA,GACvC;AAAA,UACCA,EAAK,YAAY,SAAS,KACzB,gBAAAta,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA;AAAA,YAAA;AAAA,YAC/Bsa,EAAK,YAAY,IAAI,CAAAE,MAAM,GAAGA,EAAG,YAAY,IAAIA,EAAG,YAAY,EAAE,EAAE,KAAK,IAAI;AAAA,UAAA,EAAA,CACnF;AAAA,QAAA,KAVMD,CAYV,CACD,GACH;AAAA,QAED,CAACH,EAAG,aAAaA,EAAG,2BAClB,KAAA,EAAE,WAAU,+CAA+C,UAAAA,EAAG,MAAA,CAAM;AAAA,QAEtEA,EAAG,gBAAgBA,EAAG,aAAa,SAAS,KAAK,CAACA,EAAG,aACpD,gBAAApa,EAAC,WAAA,EAAQ,WAAU,QACjB,UAAA;AAAA,UAAA,gBAAAA,EAAC,WAAA,EAAQ,WAAU,gEAA+D,UAAA;AAAA,YAAA;AAAA,YAClDoa,EAAG,aAAa;AAAA,YAAO;AAAA,UAAA,GACvD;AAAA,UACA,gBAAAna,EAAC,SAAI,WAAU,wCACZ,YAAG,aAAa,KAAK,KAAK,EAAA,CAC7B;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,GA7CMoa,CA+CV,CACD,EAAA,CACH;AAAA,IAAA,GACF;AAAA,IAIDR,EAAS,gBAAgB,SAAS,KACjC,gBAAA7Z,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,6DACZ,UAAA;AAAA,QAAA,gBAAAC,EAAC+Z,GAAA,EAAU,WAAU,eAAA,CAAe;AAAA,QAAE;AAAA,MAAA,GAExC;AAAA,MACA,gBAAA/Z,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA4Z,EAAS,gBAAgB,IAAI,CAACY,GAAIJ,MACjC,gBAAAra,EAAC,OAAA,EAAc,WAAU,qCACvB,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sCAAsC,UAAAwa,EAAG,UAAS;AAAA,UAClE,gBAAAxa,EAAC,QAAA,EAAK,WAAU,8BAA6B,UAAA,MAAE;AAAA,UAC/C,gBAAAA,EAAC,QAAA,EAAK,WAAU,0DAA0D,YAAG,SAAA,CAAS;AAAA,QAAA,GACxF;AAAA,QACA,gBAAAA,EAAC,KAAA,EAAE,WAAU,kCAAkC,YAAG,QAAO;AAAA,QACzD,gBAAAD,EAAC,OAAA,EAAI,WAAU,mCACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,eAAc,UAAA,aAAS;AAAA,UAAO;AAAA,UAAEwa,EAAG,SAAS,KAAK,IAAI;AAAA,QAAA,GACvE;AAAA,QACCA,EAAG,SAAS,SAAS,KACpB,gBAAAza,EAAC,OAAA,EAAI,WAAU,mCACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,eAAc,UAAA,cAAU;AAAA,UAAO;AAAA,UAAEwa,EAAG,SAAS,IAAI,CAAAC,MAAM,GAAGA,EAAG,YAAY,IAAIA,EAAG,YAAY,EAAE,EAAE,KAAK,IAAI;AAAA,QAAA,EAAA,CAC3H;AAAA,MAAA,EAAA,GAbML,CAeV,CACD,EAAA,CACH;AAAA,IAAA,GACF;AAAA,IAIDR,EAAS,YAAYA,EAAS,SAAS,SAAS,uBAC9C,OAAA,EACC,UAAA;AAAA,MAAA,gBAAA7Z,EAAC,MAAA,EAAG,WAAU,mFACZ,UAAA;AAAA,QAAA,gBAAAC,EAACoH,GAAA,EAAY,WAAU,eAAA,CAAe;AAAA,QAAE;AAAA,MAAA,GAE1C;AAAA,MACA,gBAAApH,EAAC,MAAA,EAAG,WAAU,8EACX,YAAS,SAAS,IAAI,CAAC0a,GAAGlE,MACzB,gBAAAxW,EAAC,MAAA,EAAY,UAAA0a,EAAA,GAAJlE,CAAM,CAChB,EAAA,CACH;AAAA,IAAA,GACF;AAAA,IAIDoD,EAAS,cAAc,SAAS,KAC/B,gBAAA7Z,EAAC,OAAA,EAAI,WAAU,6DACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,eAAc,UAAA,mBAAe;AAAA,MAAO;AAAA,MAAE4Z,EAAS,cAAc,KAAK,IAAI;AAAA,IAAA,EAAA,CACxF;AAAA,EAAA,GAEJ;AAEJ,GClOMe,KAAwC,CAAC;AAAA,EAC7C,OAAAvZ;AAAA,EACA,QAAAoF;AAAA,EACA,kBAAAoU;AAAA,EACA,iBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AAAA,EACA,eAAAC;AAAA,EACA,kCAAAC;AAAA,EACA,iBAAAtE;AAAA,EACA,mBAAAiB;AAAA,EACA,mBAAAgB;AAAA,EACA,eAAAsC;AAAA,EACA,cAAAC;AAAA,EACA,cAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,kBAAAC,IAAmB;AAAA,EACnB,iBAAAC,IAAkB;AACpB,MAAM;AACJ,QAAM,CAACC,GAAiBC,CAAkB,IAAI7Y,EAAS,EAAK,GACtD,CAAC8Y,GAAgBC,CAAiB,IAAI/Y,EAAS,EAAK,GACpD,CAACgZ,GAAqBC,CAAsB,IAAIjZ,EAAS,EAAK;AAGpE,EAAAO,GAAU,MAAM;AACd,KAAKqY,KAAmBE,MAAmB,OAAO,SAAW,OAAgB,OAAe,SAE1F,WAAW,MAAM;AACf,UAAI;AACA,eAAe,MAAM,aAAA;AAAA,MACzB,QAAgB;AAAA,MAEhB;AAAA,IACF,GAAG,CAAC;AAAA,EAER,GAAG,CAACF,GAAiBE,GAAgB3a,GAAO0Z,CAAa,CAAC;AAE1D,QAAMqB,IAAalO,GAAgB7M,CAAK,GAClCgb,IAAgBlO,GAAuB9M,CAAK,GAE5CkK,IAAY7L,EAAQ,OAAO,GAC3Bwa,IAAcxa,EAAQ,SAAS,GAC/Bya,IAAYza,EAAQ,OAAO,GAC3B4c,IAAa5c,EAAQ,QAAQ,GAC7B6c,IAAW7c,EAAQ,MAAM,GACzB4H,KAAe5H,EAAQ,UAAU,GACjC8R,KAAa9R,EAAQ,QAAQ,GAC7B8c,KAAe9c,EAAQ,UAAU,GACjC+c,KAAgB/c,EAAQ,WAAW,GACnCyH,KAAkBzH,EAAQ,aAAa,GACvCgd,KAAoBhd,EAAQ,eAAe,GAC3Cid,KAAYjd,EAAQ,OAAO,GAC3B6H,IAAc7H,EAAQ,SAAS,GAC/B8H,IAAgB9H,EAAQ,WAAW,GACnC+H,KAAoB/H,EAAQ,eAAe,GAC3Ckd,KAAUld,EAAQ,KAAK,GACvBmd,IAAYnd,EAAQ,OAAO,GAE3Bod,IAAkB,YAAY;AAClC,UAAMzO,IAAeC,GAAoBjN,CAAK;AAC9C,QAAI;AACF,YAAM,UAAU,UAAU,UAAU,KAAK,UAAUgN,GAAc,MAAM,CAAC,CAAC;AAAA,IAE3E,QAAgB;AAGd,YAAM0O,KAAW,SAAS,cAAc,UAAU;AAClD,MAAAA,GAAS,QAAQ,KAAK,UAAU1O,GAAc,MAAM,CAAC,GACrD,SAAS,KAAK,YAAY0O,EAAQ,GAClCA,GAAS,OAAA,GACT,SAAS,YAAY,MAAM,GAC3B,SAAS,KAAK,YAAYA,EAAQ;AAAA,IACpC;AAAA,EACF,GAGMC,IAAoB,CAACrS,GAAmBf,OAAqE;AACjH,QAAIA,OAAc;AAEhB,aAAO,EAAQvI,EAAM,gBAAgB,KAAK,CAAAG,OAAMA,GAAG,cAAcmJ,KAAanJ,GAAG,SAAS;AACrF;AAEL,YAAMyb,KAAiB5b,EAAM,WAAW,CAAA,GAElC6b,KAAoB,CAACtb,OAClBA,GAAQ,KAAK,CAAAzB,OACd,YAAYA,KAEPA,GAAO,WAAWwK,IAChB,UAAUxK,MAAU,aAAaA,KAEnC+c,GAAkB/c,GAAO,OAAO,IAElC,EACR;AAGH,aAAO+c,GAAkBD,EAAc;AAAA,IACzC;AAAA,EACF,GAEME,KAA2B,CAACxS,GAAmBf,OAA4D;AAC/G,QAAIA,OAAc;AAEhB,MAAAmO,EAAkBpN,GAAW,YAAY;AAAA,SACpC;AAGL,YAAMsS,KAAiB5b,EAAM,WAAW,CAAA,GAClC4U,KAAY;AAAA,QAChB,QAAQtL;AAAA,QACR,UAAU;AAAA,QACV,QAAQ,CAAA;AAAA,MAAC;AAIX,UAAIsS,GAAe,WAAW;AAC5B,QAAAnG,EAAgB,CAACb,EAAS,CAAC;AAAA,eAClBgH,GAAe,WAAW,KAAK,YAAYA,GAAe,CAAC,GAAG;AAEvE,cAAM/F,KAAW;AAAA,UACf,MAAM;AAAA,UACN,SAAS,CAAC+F,GAAe,CAAC,GAAGhH,EAAS;AAAA,QAAA;AAExC,QAAAa,EAAgB,CAACI,EAAQ,CAAC;AAAA,MAC5B,WAAW+F,GAAe,WAAW,KAAK,UAAUA,GAAe,CAAC,KAAKA,GAAe,CAAC,EAAE,SAAS,OAAO;AAGzG,cAAM7F,KAAkB;AAAA,UACtB,MAAM;AAAA,UACN,SAAS,CAAC,GAHa6F,GAAe,CAAC,EAGT,SAAShH,EAAS;AAAA,QAAA;AAElD,QAAAa,EAAgB,CAACM,EAAe,CAAC;AAAA,MACnC,WAAW6F,GAAe,WAAW,KAAK,UAAUA,GAAe,CAAC,KAAKA,GAAe,CAAC,EAAE,SAAS,MAAM;AAGxG,cAAM3F,KAAiB;AAAA,UACrB,MAAM;AAAA,UACN,SAAS,CAAC,GAHY2F,GAAe,CAAC,EAGT,SAAShH,EAAS;AAAA,QAAA;AAEjD,QAAAa,EAAgB,CAACQ,EAAc,CAAC;AAAA,MAClC;AAEE,QAAAR,EAAgB,CAAC,GAAGmG,IAAgBhH,EAAS,CAAC;AAAA,IAElD;AAAA,EACF,GAGMmH,KAAc,CAAC/L,MAAqC;AACxD,YAAQA,GAAA;AAAA,MACN,KAAK;AACH,iCAAQoL,IAAA,EAAc,WAAW,WAAWpL,IAAY,aAAa,EAAE,IAAI;AAAA,MAC7E,KAAK;AACH,iCAAQlK,IAAA,EAAgB,WAAW,WAAWkK,IAAY,aAAa,EAAE,IAAI;AAAA,MAC/E;AACE,eAAO,gBAAApR,EAACyc,IAAA,EAAkB,WAAU,UAAA,CAAU;AAAA,IAAA;AAAA,EAEpD,GAEMW,KAAmB,CAAC1S,MAAsB;AAC9C,UAAM4G,KAAUL,GAAiBvG,GAAWtJ,EAAM,KAAK,GACjDic,KAAOhM,GAAqBC,EAAO;AACzC,IAAA8J,EAAc1Q,GAAW2S,EAAI;AAAA,EAC/B,GAEMC,KAAuB,CAAC5S,GAAmBf,OAA4D;AAC3G,UAAM4T,KAAgBtM,GAAiBvG,GAAWtJ,EAAM,KAAK,GACvDoc,KAAc;AAEpB,QAAID;AAEF,cAAQ5T,IAAA;AAAA,QACN,KAAK;AACH,iBAAO,GAAG6T,EAAW;AAAA,QACvB,KAAK;AACH,iBAAO,GAAGA,EAAW;AAAA,QACvB,KAAK;AACH,iBAAO,GAAGA,EAAW;AAAA,QACvB;AACE,iBAAO,GAAGA,EAAW;AAAA,MAAA;AAAA;AAIzB,aAAO,GAAGA,EAAW;AAAA,EAEzB,GAEMC,KAKD,CAAC,EAAE,WAAA/S,GAAW,WAAAf,IAAW,MAAAK,2BAezB,OAAA,EAAI,WAAW,wEAdK,MAAM;AAC3B,YAAQL,IAAA;AAAA,MACN,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IAAA;AAAA,EAEb,GAGyF,CAAgB,IACrG,UAAA;AAAA,IAAA,gBAAA3J,EAAC,OAAA,EAAI,WAAU,iBACZ,UAAAgK,IACH;AAAA,IACA,gBAAAjK,EAAC,QAAA,EAAK,WAAU,gCACd,UAAA;AAAA,MAAA,gBAAAC,EAAC,UAAK,WAAU,gCAAgC,UAAAgR,GAActG,GAAWlE,CAAM,GAAE;AAAA,MACjF,gBAAAxG,EAAC,QAAA,EAAK,WAAU,2CAA2C,UAAA0K,EAAA,CAAU;AAAA,IAAA,GACvE;AAAA,IACA,gBAAA3K,EAAC,OAAA,EAAI,WAAU,gCAEb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,8BAEX,UAAA;AAAA,SAAA,MAAM;AACN,gBAAM2d,KAAaX,EAAkBrS,GAAWf,EAAS;AAczD,iBACE,gBAAA3J;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAMkd,GAAyBxS,GAAWf,EAAS;AAAA,cAC5D,WAAW,yDACT+T,MAjBwB,MAAM;AAClC,wBAAQ/T,IAAA;AAAA,kBACN,KAAK;AACH,2BAAO;AAAA,kBACT,KAAK;AACH,2BAAO;AAAA,kBACT,KAAK;AACH,2BAAO;AAAA,kBACT;AACE,2BAAO;AAAA,gBAAA;AAAA,cAEb,GAOU,IACA,iDACN;AAAA,cACA,OAAOA,OAAc,mBAAmB,mBAAmB;AAAA,cAE3D,4BAAC4H,IAAA,EAAW,WAAW,WAAWmM,KAAa,aAAa,EAAE,GAAA,CAAI;AAAA,YAAA;AAAA,UAAA;AAAA,QAGxE,GAAA;AAAA,QAGA,gBAAA1d;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAMod,GAAiB1S,CAAS;AAAA,YACzC,WAAW,yDAAyD4S,GAAqB5S,GAAWf,EAAS,EAAE,QAAQ,OAAO,OAAO,CAAC;AAAA,YACtI,OAAOwH,GAAeF,GAAiBvG,GAAWtJ,EAAM,KAAK,CAAC;AAAA,YAE7D,UAAA+b,GAAYlM,GAAiBvG,GAAWtJ,EAAM,KAAK,CAAC;AAAA,UAAA;AAAA,QAAA;AAAA,MACvD,GACF;AAAA,MAGA,gBAAApB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS,MAAMkb,EAAcxQ,GAAWf,EAAS;AAAA,UACjD,WAAU;AAAA,UAEV,UAAA,gBAAA3J,EAACsL,GAAA,EAAU,WAAU,UAAA,CAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IACjC,EAAA,CACF;AAAA,EAAA,GACF,GAIEqS,KAGD,CAAC,EAAE,eAAAzS,QACN,gBAAAnL,EAAC,OAAA,EAAI,WAAU,mHAEb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,SAAI,WAAU,QACb,4BAACwH,IAAA,EAAkB,WAAU,WAAU,EAAA,CACzC;AAAA,MACA,gBAAAzH,EAAC,QAAA,EAAK,WAAU,gCACd,UAAA;AAAA,QAAA,gBAAAC,EAAC,UAAK,WAAU,gCAAgC,aAAckL,EAAc,WAAW1E,CAAM,GAAE;AAAA,QAC/F,gBAAAxG,EAAC,QAAA,EAAK,WAAU,2CAA2C,YAAc,UAAA,CAAU;AAAA,MAAA,GACrF;AAAA,MACA,gBAAAD,EAAC,OAAA,EAAI,WAAU,gCAEb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,8BAEX,UAAA;AAAA,WAAA,MAAM;AACN,kBAAM6d,KAAeb,EAAkB7R,EAAc,WAAW,gBAAgB;AAChF,mBACE,gBAAAlL;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAMkd,GAAyBhS,EAAc,WAAW,gBAAgB;AAAA,gBACjF,WAAW,yDACT0S,KACI,4CACA,iDACN;AAAA,gBACA,OAAM;AAAA,gBAEN,4BAACrM,IAAA,EAAW,WAAW,WAAWqM,KAAe,aAAa,EAAE,GAAA,CAAI;AAAA,cAAA;AAAA,YAAA;AAAA,UAG1E,GAAA;AAAA,UAGA,gBAAA5d;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAMod,GAAiBlS,EAAc,SAAS;AAAA,cACvD,WAAW,yDAAyDoS,GAAqBpS,EAAc,WAAW,gBAAgB,EAAE,QAAQ,OAAO,OAAO,CAAC;AAAA,cAC3J,OAAOiG,GAAeF,GAAiB/F,EAAc,WAAW9J,EAAM,KAAK,CAAC;AAAA,cAE3E,aAAY6P,GAAiB/F,EAAc,WAAW9J,EAAM,KAAK,CAAC;AAAA,YAAA;AAAA,UAAA;AAAA,QACrE,GACF;AAAA,QAGA,gBAAApB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAMkb,EAAchQ,EAAc,WAAW,gBAAgB;AAAA,YACtE,WAAU;AAAA,YAEV,UAAA,gBAAAlL,EAACsL,GAAA,EAAU,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACjC,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAEA,gBAAAvL,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,uCAAsC,UAAA,gBAAY;AAAA,MAClE,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAOkL,EAAc,eAAe;AAAA,UACpC,UAAU,CAACxJ,OAAMyZ,EAAiCjQ,EAAc,WAAWxJ,GAAE,OAAO,KAAK;AAAA,UACzF,WAAU;AAAA,UACV,SAAS,CAACA,OAAMA,GAAE,gBAAA;AAAA,UAEjB,UAAAyJ,GAAmB,IAAI,CAAA0S,OACtB,gBAAA7d,EAAC,UAAA,EAA+B,OAAO6d,GAAY,OAChD,UAAAA,GAAY,MAAA,GADFA,GAAY,KAEzB,CACD;AAAA,QAAA;AAAA,MAAA;AAAA,IACH,EAAA,CACF;AAAA,EAAA,GACF;AAkBF,SACE,gBAAA9d,EAAC,OAAA,EAAI,WAAU,kEAEb,UAAA;AAAA,IAAA,gBAAAC,EAAC,SAAI,WAAU,wCACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,2CACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,4CACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,0DAAyD,UAAA,iBAAa;AAAA,QACnFyb,KACC,gBAAA1b;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS0b;AAAA,YACT,WAAU;AAAA,YACV,OAAM;AAAA,YAEN,UAAA;AAAA,cAAA,gBAAAzb,EAAC,OAAA,EAAI,WAAU,yBAAwB,MAAK,gBAAe,SAAQ,aACjE,UAAA,gBAAAA,EAAC,QAAA,EAAK,UAAS,WAAU,GAAE,uMAAsM,UAAS,WAAU,GACtP;AAAA,cACA,gBAAAA,EAAC,UAAK,UAAA,SAAA,CAAM;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGfwb,KACC,gBAAAzb;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAASyb;AAAA,YACT,WAAU;AAAA,YACV,OAAM;AAAA,YAEN,UAAA;AAAA,cAAA,gBAAAxb,EAACuc,IAAA,EAAa,WAAU,wBAAA,CAAwB;AAAA,cAChD,gBAAAvc,EAAC,UAAK,UAAA,eAAA,CAAY;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACpB,GAEJ;AAAA,MACA,gBAAAD,EAAC,OAAA,EAAI,WAAU,oCACZ,UAAA;AAAA,QAAAoc,KACC,gBAAApc,EAAAoJ,IAAA,EACE,UAAA;AAAA,UAAA,gBAAApJ,EAAC,QAAA,EAAK,WAAU,oDACb,UAAA;AAAA,YAAAqc;AAAA,YAAc;AAAA,YAAOA,MAAkB,IAAI,MAAM;AAAA,YAAG;AAAA,UAAA,GACvD;AAAA,UACA,gBAAArc;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS8c;AAAA,cACT,WAAU;AAAA,cACV,OAAM;AAAA,cAEN,UAAA;AAAA,gBAAA,gBAAA7c,EAACsc,GAAA,EAAS,WAAU,UAAA,CAAU;AAAA,gBAC9B,gBAAAtc,EAAC,QAAA,EAAK,WAAU,oBAAmB,UAAA,aAAA,CAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAE9C0b,KACC,gBAAA1b;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS0b;AAAA,cACT,WAAW,wHACTC,MAAqB,SACjB,iLACA,yIACN;AAAA,cACA,OAAOA,MAAqB,SAAS,wBAAwB;AAAA,cAC7D,UAAUA,MAAqB;AAAA,cAE9B,UAAAA,MAAqB,SACpB,gBAAA5b,EAAAoJ,IAAA,EACE,UAAA;AAAA,gBAAA,gBAAAnJ,EAAC0c,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,gBAC/B,gBAAA1c,EAAC,QAAA,EAAK,WAAU,oBAAmB,UAAA,QAAA,CAAK;AAAA,cAAA,EAAA,CAC1C,IACE2b,MAAqB,WACvB,gBAAA5b,EAAAoJ,IAAA,EACE,UAAA;AAAA,gBAAA,gBAAAnJ,EAAC4c,GAAA,EAAU,WAAU,UAAA,CAAU;AAAA,gBAC/B,gBAAA5c,EAAC,QAAA,EAAK,WAAU,oBAAmB,UAAA,UAAA,CAAO;AAAA,cAAA,EAAA,CAC5C,IAEA,gBAAAD,EAAAoJ,IAAA,EACE,UAAA;AAAA,gBAAA,gBAAAnJ,EAAC4c,GAAA,EAAU,WAAU,UAAA,CAAU;AAAA,gBAC/B,gBAAA5c,EAAC,QAAA,EAAK,WAAU,oBAAmB,UAAA,WAAO;AAAA,gBAC1C,gBAAAA,EAAC,QAAA,EAAK,WAAU,2CAA0C,UAAA,aAAA,CAAU;AAAA,cAAA,EAAA,CACtE;AAAA,YAAA;AAAA,UAAA;AAAA,UAILqb,KACC,gBAAArb;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAASqb;AAAA,cACT,WAAU;AAAA,cACV,OAAM;AAAA,cAEN,UAAA,gBAAArb,EAACqc,GAAA,EAAW,WAAU,wBAAA,CAAwB;AAAA,YAAA;AAAA,UAAA;AAAA,QAChD,GAEJ;AAAA,QAEDf,KAAgBC,KACf,gBAAAvb;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAASub;AAAA,YACT,WAAU;AAAA,YACV,OAAM;AAAA,YAEN,UAAA,gBAAAvb,EAACqH,IAAA,EAAa,WAAU,wBAAA,CAAwB;AAAA,UAAA;AAAA,QAAA;AAAA,0BA1GjC,MAAM;AACjC,kBAAQuT,GAAA;AAAA,YACN,KAAK;AACH,qBACE,gBAAA5a,EAAC,OAAA,EAAI,WAAU,+DAAA,CAA+D;AAAA,YAElF,KAAK;AACH,qBAAO,gBAAAA,EAACia,GAAA,EAAY,WAAU,yBAAA,CAAyB;AAAA,YACzD,KAAK;AACH,qBAAO,gBAAAja,EAACka,GAAA,EAAU,WAAU,uBAAA,CAAuB;AAAA,YACrD;AACE,qBAAO;AAAA,UAAA;AAAA,QAEb,GAgGW,CAAA,CAAqB;AAAA,MAAA,EAAA,CACxB;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,IAGC0B,KACC,gBAAA7b,EAAC,OAAA,EAAI,WAAU,2JACb,UAAA;AAAA,MAAA,gBAAAC,EAAC0c,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,MAC/B,gBAAA1c,EAAC,UAAK,UAAA,0BAAA,CAAuB;AAAA,IAAA,GAC/B;AAAA,IAIF,gBAAAA,EAAC,OAAA,EAAI,WAAU,OACZ,UAACmc,IASA,gBAAApc,EAAC,OAAA,EAAI,WAAU,aAEb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,yCAEb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,kEACZ,UAAA;AAAA,YAAA,gBAAAC,EAACuH,GAAA,EAAc,WAAU,eAAA,CAAe;AAAA,YAAE;AAAA,aAC5BnG,EAAM,cAAc,CAAA,GAAI;AAAA,YAAO;AAAA,UAAA,GAC/C;AAAA,UACA,gBAAApB,EAAC,SAAI,WAAU,uBACX,aAAM,cAAc,CAAA,GAAI,IAAI,CAAAsB,MAC5B,gBAAAtB;AAAA,YAACyd;AAAA,YAAA;AAAA,cAEC,OAAOnc;AAAA,cACP,WAAWA;AAAA,cACX,WAAU;AAAA,cACV,MAAM,gBAAAtB,EAACuH,GAAA,EAAc,WAAU,UAAA,CAAU;AAAA,YAAA;AAAA,YAJpCjG;AAAA,UAAA,CAMR,EAAA,CACH;AAAA,QAAA,GACF;AAAA,QAGA,gBAAAvB,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,uEACZ,UAAA;AAAA,YAAA,gBAAAC,EAACwH,IAAA,EAAkB,WAAU,eAAA,CAAe;AAAA,YAAE;AAAA,aAC3BpG,EAAM,kBAAkB,CAAA,GAAI;AAAA,YAAO;AAAA,UAAA,GACxD;AAAA,UACA,gBAAApB,EAAC,SAAI,WAAU,uBACX,aAAM,kBAAkB,CAAA,GAAI,IAAI,CAAAkL,MAChC,gBAAAlL;AAAA,YAAC2d;AAAA,YAAA;AAAA,cAEC,eAAAzS;AAAA,cACA,OAAOA,EAAc;AAAA,YAAA;AAAA,YAFhBA,EAAc;AAAA,UAAA,CAItB,EAAA,CACH;AAAA,QAAA,GACF;AAAA,QAGA,gBAAAnL,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,gEACZ,UAAA;AAAA,YAAA,gBAAAC,EAACsH,GAAA,EAAY,WAAU,eAAA,CAAe;AAAA,YAAE;AAAA,aAC5BlG,EAAM,YAAY,CAAA,GAAI;AAAA,YAAO;AAAA,UAAA,GAC3C;AAAA,UACA,gBAAApB,EAAC,SAAI,WAAU,uBACX,aAAM,YAAY,CAAA,GAAI,IAAI,CAAAqB,MAAW;AACrC,kBAAM2E,KAAcQ,IAAS6I,GAAahO,GAASmF,CAAM,IAAI;AAC7D,mBACE,gBAAAxG;AAAA,cAACyd;AAAA,cAAA;AAAA,gBAEC,OAAOpc;AAAA,gBACP,WAAWA;AAAA,gBACX,WAAU;AAAA,gBACV,MAAM0E,GAAeC,IAAa,SAAS;AAAA,cAAA;AAAA,cAJtC3E;AAAA,YAAA;AAAA,UAOX,CAAC,EAAA,CACH;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,GACF;AAAA,MAGCuP,GAAkBxP,CAAK,KACtB,gBAAApB,EAAC,OAAA,EAAI,WAAU,QACb,UAAA,gBAAAA;AAAA,QAAC6Y;AAAA,QAAA;AAAA,UACC,gBAAgBzX,EAAM,kBAAkB,CAAA;AAAA,UACxC,mBAAA0W;AAAA,UACA,mBAAAgB;AAAA,QAAA;AAAA,MAAA,GAEJ;AAAA,MAIF,gBAAA9Y,EAAC,OAAA,EAAI,WAAU,QACb,UAAA,gBAAAA;AAAA,QAAC4W;AAAA,QAAA;AAAA,UACC,SAASxV,EAAM,WAAW,CAAA;AAAA,UAC1B,QAAAoF;AAAA,UACA,OAAApF;AAAA,UACA,iBAAAyV;AAAA,QAAA;AAAA,MAAA,GAEJ;AAAA,MAGCgE,uBACE,OAAA,EAAI,WAAU,kDACb,UAAA,gBAAA9a,EAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAA,gBAAAC,EAACka,GAAA,EAAU,WAAU,mCAAA,CAAmC;AAAA,0BACvD,OAAA,EACC,UAAA;AAAA,UAAA,gBAAAla,EAAC,MAAA,EAAG,WAAU,sCAAqC,UAAA,oBAAgB;AAAA,UACnE,gBAAAA,EAAC,KAAA,EAAE,WAAU,6BAA6B,UAAA6a,EAAA,CAAgB;AAAA,QAAA,EAAA,CAC5D;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,MAIF,gBAAA9a,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oCACb,UAAA;AAAA,UAAA,gBAAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAM;AACb,sBAAM+d,IAAe,CAACjC;AACtB,gBAAAC,EAAmBgC,CAAY,GAC3BA,MACF9B,EAAkB,EAAK,GACvBE,EAAuB,EAAK;AAAA,cAEhC;AAAA,cACA,WAAU;AAAA,cAET,UAAA;AAAA,gBAAAL,IAAkB,SAAS;AAAA,gBAAO;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAEpCf,KACC,gBAAA/a;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAM;AACb,sBAAMge,IAAc,CAAChC;AACrB,gBAAAC,EAAkB+B,CAAW,GACzBA,MACFjC,EAAmB,EAAK,GACxBI,EAAuB,EAAK;AAAA,cAEhC;AAAA,cACA,WAAU;AAAA,cAET,UAAA;AAAA,gBAAAH,IAAiB,SAAS;AAAA,gBAAO;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGrChB,KACC,gBAAAhb;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAM;AACb,sBAAMie,IAAmB,CAAC/B;AAC1B,gBAAAC,EAAuB8B,CAAgB,GACnCA,MACFlC,EAAmB,EAAK,GACxBE,EAAkB,EAAK;AAAA,cAE3B;AAAA,cACA,WAAU;AAAA,cAET,UAAA;AAAA,gBAAAC,IAAsB,SAAS;AAAA,gBAAO;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QACzC,GAEJ;AAAA,QAECJ,KACC,gBAAA9b,EAAC,OAAA,EAAI,WAAU,kEACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,qDAAoD,UAAA,eAAW;AAAA,UAC9E,gBAAAA,EAAC,SAAI,WAAU,oDAAmD,OAAO,EAAE,UAAU,QAAQ,YAAY,MAAA,GACvG,4BAAC,QAAA,EAAK,WAAU,iBAAiB,UAAA,KAAK,UAAUqO,GAAoBjN,CAAK,GAAG,MAAM,CAAC,EAAA,CAAE,EAAA,CACvF;AAAA,QAAA,GACF;AAAA,QAGD2a,KAAkBjB,KACjB,gBAAA/a,EAAC,OAAA,EAAI,WAAU,kEACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,qDAAoD,UAAA,kBAAc;AAAA,UACjF,gBAAAA,EAAC,SAAI,WAAU,wEAAuE,OAAO,EAAE,UAAU,QAAQ,YAAY,SAC3H,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,gBAAgB,UAAA8a,EAAc,IAAI,KAAK;AAAA;AAAA,CAAO,GAAE,EAAA,CAClE;AAAA,UACCA,EAAc,UAAUA,EAAc,OAAO,SAAS,KACrD,gBAAA/a,EAAAoJ,IAAA,EACE,UAAA;AAAA,YAAA,gBAAAnJ,EAAC,OAAA,EAAI,WAAU,0DAAyD,UAAA,eAAW;AAAA,YACnF,gBAAAA,EAAC,SAAI,WAAU,oDAAmD,OAAO,EAAE,UAAU,QAAQ,YAAY,MAAA,GACvG,4BAAC,QAAA,EAAK,WAAU,iBAAiB,UAAA,KAAK,UAAU8a,EAAc,QAAQ,MAAM,CAAC,EAAA,CAAE,EAAA,CACjF;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,GAEJ;AAAA,QAGDmB,KAAuBlB,KACtB,gBAAA/a,EAAC2Z,IAAA,EAAmB,UAAUoB,EAAA,CAAoB;AAAA,MAAA,EAAA,CAEtD;AAAA,IAAA,EAAA,CACF,IAtLA,gBAAA/a,EAAC,OAAA,EAAI,WAAU,4DACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAAC,EAACsH,GAAA,EAAY,WAAU,4CAAA,CAA4C;AAAA,MACnE,gBAAAtH,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,sBAAkB;AAAA,MAC9D,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAU,UAAA,2EAAA,CAAwE;AAAA,IAAA,EAAA,CACnG,EAAA,CACF,EAgLA,CAEJ;AAAA,KAGEmc,KAAcvB,MAAqB,WAAWA,MAAqB,cACnE,gBAAA5a,EAAC,OAAA,EAAI,WAAU,iCACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,MAAA,gBAAAC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAASgb;AAAA,UACT,UAAUJ,MAAqB;AAAA,UAC/B,WAAW,sGACTA,MAAqB,eACjB,kEACAA,MAAqB,UACrB,qKACAA,MAAqB,YACrB,qJACA,0KACN;AAAA,UAEC,UAAAA,MAAqB,eACpB,gBAAA7a,EAAAoJ,IAAA,EACE,UAAA;AAAA,YAAA,gBAAAnJ,EAAC,OAAA,EAAI,WAAU,mEAAA,CAAmE;AAAA,YAAM;AAAA,UAAA,EAAA,CAE1F,IACE4a,MAAqB,UACvB,gBAAA7a,EAAAoJ,IAAA,EACE,UAAA;AAAA,YAAA,gBAAAnJ,EAAC4c,GAAA,EAAU,WAAU,eAAA,CAAe;AAAA,YAAE;AAAA,UAAA,EAAA,CAExC,IACEhC,MAAqB,YACvB,gBAAA7a,EAAAoJ,IAAA,EACE,UAAA;AAAA,YAAA,gBAAAnJ,EAACka,GAAA,EAAU,WAAU,eAAA,CAAe;AAAA,YAAE;AAAA,UAAA,EAAA,CAExC,IAEA,gBAAAna,EAAAoJ,IAAA,EACE,UAAA;AAAA,YAAA,gBAAAnJ,EAAC4c,GAAA,EAAU,WAAU,eAAA,CAAe;AAAA,YAAE;AAAA,UAAA,EAAA,CAExC;AAAA,QAAA;AAAA,MAAA;AAAA,MAIJ,gBAAA7c;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAASkb;AAAA,UACT,UAAUL,MAAqB;AAAA,UAC/B,WAAW,sGACTA,MAAqB,UACjB,0FACA,yFACN;AAAA,UACA,OAAOA,MAAqB,UAAU,EAAE,iBAAiB,wBAAwB;AAAA,UAEjF,UAAA;AAAA,YAAA,gBAAA5a,EAAC2c,IAAA,EAAQ,WAAU,eAAA,CAAe;AAAA,YAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAEtC,EAAA,CACF,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ,GC5sBasB,KAA2C;AAAA,EACtD,KAAKC;AAAA,EACL,MAAMC;AAAA,EACN,MAAMC;AAAA,EACN,KAAKC;AAAA,EACL,SAASC;AAAA,EACT,QAAQC;AAAA,EACR,OAAOC;AAAA,EACP,WAAWC;AAAA,EACX,SAASC;AAAA,EACT,OAAOC;AAAA,EACP,cAAcC;AAAA,EACd,WAAWC;AAAA,EACX,UAAUC;AAAA,EACV,SAASC;AAAA,EACT,UAAUC;AACZ;AC1BA,SAAwBC,GAAkB;AAAA,EACxC,cAAAC;AAAA,EACA,cAAAC;AAAA,EACA,WAAAlZ,IAAY;AACd,GAA2B;AACzB,QAAM,CAACf,GAAQ0G,CAAS,IAAI3I,EAAS,EAAK,GACpCmc,IAAa,OAAO,QAAQnB,EAAmB,GAG/CoB,IAA6C;AAAA,IACjD,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,KAAK;AAAA,IACL,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO;AAAA,IACP,cAAc;AAAA,IACd,WAAW;AAAA,IACX,UAAU;AAAA,IACV,SAAS;AAAA,IACT,UAAU;AAAA,EAAA,GAINC,IADiBrB,GAAoBiB,CAAY,GAClB,MAC/BK,IAAgBF,EAAgBH,CAAY;AAElD,SACE,gBAAAnf,EAAC,OAAA,EAAI,WAAW,GAAGkG,CAAS,aAE1B,UAAA;AAAA,IAAA,gBAAAlG;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,MAAM6L,EAAU,CAAC1G,CAAM;AAAA,QAChC,WAAU;AAAA,QAEV,UAAA;AAAA,UAAA,gBAAAnF,EAAC,OAAA,EAAI,WAAU,+BACZ,UAAA;AAAA,YAAAuf,KACC,gBAAAtf,EAACsf,GAAA,EAAa,WAAU,iCAAA,CAAiC;AAAA,YAE3D,gBAAAtf,EAAC,QAAA,EAAK,WAAU,oCAAoC,UAAAuf,EAAA,CAAc;AAAA,UAAA,GACpE;AAAA,UACA,gBAAAvf;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW,6DAA6DkF,IAAS,eAAe,EAAE;AAAA,cAClG,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,QAAO;AAAA,cAEP,UAAA,gBAAAlF,EAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,iBAAA,CAAiB;AAAA,YAAA;AAAA,UAAA;AAAA,QACxF;AAAA,MAAA;AAAA,IAAA;AAAA,IAIDkF,KACC,gBAAAlF,EAAC,OAAA,EAAI,WAAU,yHACb,UAAA,gBAAAA,EAAC,SAAI,WAAU,OACb,4BAAC,OAAA,EAAI,WAAU,0DACZ,UAAAof,EAAW,IAAI,CAAC,CAACI,GAAMC,CAAM,MAAM;AAClC,YAAMvZ,IAAgBuZ,EAAO,MACvBC,IAAQL,EAAgBG,CAAI,GAC5BvV,IAAaiV,MAAiBM,GAC9BG,IAAcF,EAAO,aACrBG,IAAUH,EAAO,SAGjBI,IAAc,CAACF,GAAaC,CAAO,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAEpE,aACE,gBAAA7f;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,MAAK;AAAA,UACL,SAAS,MAAM;AACb,YAAAof,EAAaK,CAAI,GACjB5T,EAAU,EAAK;AAAA,UACjB;AAAA,UACA,WAAW;AAAA;AAAA;AAAA,wBAGP3B,IACE,4BACA,yCACJ;AAAA;AAAA,UAEF,OAAO;AAAA,YACL,aAAaA,IAAa,sBAAsB;AAAA,UAAA;AAAA,UAElD,OAAO4V;AAAA,UAEP,UAAA;AAAA,YAAA,gBAAA9f,EAAC,OAAA,EAAI,WAAU,iCAEZ,UAAA;AAAA,cAAAmG,KACC,gBAAAlG;AAAA,gBAACkG;AAAA,gBAAA;AAAA,kBACC,WAAW,oBAAoB+D,IAAa,iBAAiB,wBAAwB;AAAA,gBAAA;AAAA,cAAA;AAAA,cAKzF,gBAAAjK;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAAK,WAAW,8CACfiK,IAAa,KAAK,cACpB;AAAA,kBACA,OAAOA,IAAa,EAAE,OAAO,wBAAwB;AAAA,kBAClD,UAAAyV;AAAA,gBAAA;AAAA,cAAA;AAAA,YACH,GACF;AAAA,YAGCzV,KACC,gBAAAjK,EAAC,OAAA,EAAI,WAAU,8BACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,4BAA2B,OAAO,EAAE,iBAAiB,oBAAA,GAAuB,EAAA,CAC7F;AAAA,UAAA;AAAA,QAAA;AAAA,QAxCGwf;AAAA,MAAA;AAAA,IA4CX,CAAC,EAAA,CACH,EAAA,CACF,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;ACjIA,MAAMlU,KAAY7L,EAAQ,OAAO;AAqBjC,SAAwBqgB,GAAa;AAAA,EACnC,QAAAL;AAAA,EACA,QAAA7d;AAAA,EACA,QAAAme;AAAA,EACA,UAAA/H;AAAA,EACA,aAAAgI;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,aAAAC;AACF,GAAsB;AACpB,QAAM,EAAE,KAAAljB,GAAK,OAAAuiB,GAAO,aAAAC,GAAa,WAAAW,GAAW,UAAAC,GAAU,WAAAC,GAAW,MAAMta,EAAA,IAAkBuZ,GACnF,CAACgB,GAAeC,CAAgB,IAAIzd,EAAwB,IAAI,GAChE,CAAC0d,GAAeC,CAAgB,IAAI3d,EAAS,EAAK,GAClD,CAAC4d,GAAsBC,CAAuB,IAAI7d,EAAS,EAAK,GAGhE8d,IAAmB,MAAM;AAC7B,QAAIC,IAAiBpf,EAAO;AAG5B,WAAIye,KAAeA,EAAY,aAAaljB,MAC1C6jB,IAAiB,KAAK,IAAI,GAAGpf,EAAO,SAAS,CAAC,IAGzC,CAAC2e,KAAYS,IAAiBT;AAAA,EACvC,GAEMU,IAAY,MAAM;AACtB,QAAID,IAAiBpf,EAAO;AAG5B,WAAIye,KAAeA,EAAY,aAAaljB,MAC1C6jB,IAAiB,KAAK,IAAI,GAAGpf,EAAO,SAAS,CAAC,IAGzC2e,KAAYS,KAAkBT;AAAA,EACvC,GAEMW,IAAgBH,EAAA,GAChBI,IAASF,EAAA;AAIfvY,EAAAA,GAAM,UAAU,MAAM;AACpB,UAAM0Y,IAAsB,MAAM;AAChC,MAAAV,EAAiB,IAAI,GACrBE,EAAiB,EAAK,GACtBE,EAAwB,EAAK;AAAA,IAC/B;AAEA,oBAAS,iBAAiB,WAAWM,CAAmB,GACjD,MAAM;AACX,eAAS,oBAAoB,WAAWA,CAAmB;AAAA,IAC7D;AAAA,EACF,GAAG,CAAA,CAAE,GAGL1Y,GAAM,UAAU,MAAM;AACpB,IAAI2X,IAEEA,EAAY,aAAaljB,KAC3B2jB,EAAwB,EAAK,GAC7BJ,EAAiB,IAAI,KAGdL,EAAY,aAAaljB,KAAOkjB,EAAY,cAAc,UACjEO,EAAiB,EAAK,KAIxBF,EAAiB,IAAI,GACrBE,EAAiB,EAAK,GACtBE,EAAwB,EAAK;AAAA,EAEjC,GAAG,CAACT,GAAaljB,CAAG,CAAC;AAErB,QAAMkkB,IAAwB,CAAC3f,GAAoC4f,MAAwB;AAEzF,IAAIjB,KAAeA,EAAY,aAAaljB,KAAOkjB,EAAY,cAAc,WAC3E3e,EAAE,eAAA,GACFA,EAAE,gBAAA,GACFgf,EAAiBY,CAAW,GAC5BR,EAAwB,EAAI;AAAA,EAEhC,GAEMS,IAAyB,MAAM;AAEnC,IAAAb,EAAiB,IAAI;AAAA,EAGvB,GAEMc,IAAoB,CAAC9f,GAAoC4f,MAAwB;AAOrF,QANA5f,EAAE,eAAA,GACFA,EAAE,gBAAA,GACFgf,EAAiB,IAAI,GACrBI,EAAwB,EAAK,GAGzBT,KAAeA,EAAY,aAAaljB,KAAOkjB,EAAY,cAAc,UAAaD,GAAW;AACnG,MAAAA,EAAUC,EAAY,WAAWiB,GAAankB,CAAG;AACjD;AAAA,IACF;AAGA,QAAI;AACF,YAAMsH,IAAO,KAAK,MAAM/C,EAAE,aAAa,QAAQ,YAAY,CAAC;AAC5D,MAAI+C,EAAK,aAAatH,KAAOijB,KAAa3b,EAAK,cAAc,UAC3D2b,EAAU3b,EAAK,WAAW6c,GAAankB,CAAG;AAAA,IAE9C,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SACE,gBAAA4C,EAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,gCACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,kEACX,UAAA;AAAA,QAAAmG,KAAiB,gBAAAlG,EAACkG,GAAA,EAAc,WAAU,kCAAA,CAAkC;AAAA,QAC5EwZ;AAAA,QACAY,KAAa,gBAAAtgB,EAAC,QAAA,EAAK,WAAU,qBAAoB,UAAA,KAAC;AAAA,QAClDugB,KACC,gBAAAxgB,EAAC,QAAA,EAAK,WAAU,uCAAsC,UAAA;AAAA,UAAA;AAAA,UAClD6B,EAAO;AAAA,UAAO;AAAA,UAAE2e;AAAA,UAAS;AAAA,QAAA,EAAA,CAC7B;AAAA,MAAA,GAEJ;AAAA,MACCZ,KACC,gBAAA3f,EAAC,QAAA,EAAK,WAAU,8BACb,UAAA2f,EAAA,CACH;AAAA,IAAA,GAEJ;AAAA,IAEA,gBAAA3f;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,uBAAqB7C;AAAA,QACrB,WAAW,6HACRwjB,MAAkBO,KAAiBX,MAAa,MAAOM,IACpD,mDACAM,IACE,4BACA,mDACR;AAAA,QACA,OAAO;AAAA,UACL,aAAcR,MAAkBO,KAAiBX,MAAa,MAAOM,IACjE,sBACA;AAAA,UACJ,iBAAkBF,MAAkBO,KAAiBX,MAAa,MAAOM,IACrE,qCACA;AAAA,QAAA;AAAA,QAEN,YAAY,CAACnf,MAAM;AAEjB,cAAI2e,KAAeA,EAAY,aAAaljB,KAAOkjB,EAAY,cAAc;AAC3E;AAMF,UAFkBa,KAAkBX,MAAa,KAG/CK,EAAiB,EAAI,GACrBV,EAAWxe,CAAC,MAEZA,EAAE,eAAA,GACFA,EAAE,aAAa,aAAa;AAAA,QAEhC;AAAA,QACA,aAAa,CAACA,MAAM;AAElB,gBAAM+f,IAAO/f,EAAE,cAAc,sBAAA,GACvBggB,IACJhgB,EAAE,UAAU+f,EAAK,QACjB/f,EAAE,UAAU+f,EAAK,SACjB/f,EAAE,UAAU+f,EAAK,OACjB/f,EAAE,UAAU+f,EAAK,QAIbE,IAAgBjgB,EAAE,eAClBkgB,IAAyBD,KAAiB,CAACjgB,EAAE,cAAc,SAASigB,CAAa;AAEvF,WAAID,KAAsBE,KAA0BlgB,EAAE,kBAAkBA,EAAE,YACxEkf,EAAiB,EAAK,GACtBE,EAAwB,EAAK;AAAA,QAEjC;AAAA,QACA,QAAQ,CAACpf,MAAM;AAEb,cAAI2e,KAAeA,EAAY,aAAaljB,KAAOkjB,EAAY,cAAc;AAC3E;AAMF,UAFyBa,KAAkBX,MAAa,IAGtDR,EAAOre,GAAGvE,CAAG,IAEbuE,EAAE,eAAA,GAIJkf,EAAiB,EAAK,GACtBE,EAAwB,EAAK;AAAA,QAC/B;AAAA,QAEC,UAAAlf,EAAO,WAAW,IACjB,gBAAA5B,EAAC,SAAI,WAAU,iDACZ,cAAS,0BAA2BwgB,KAAa,oBACpD,IAEA,gBAAAxgB,EAAC,SAAI,WAAU,wBACZ,YAAO,IAAI,CAACyB,GAAOqJ,MAAU;AAC5B,gBAAM,EAAE,eAAe+W,GAAW,aAAArE,GAAa,cAAAsE,EAAA,IAAiB3B,EAAgB1e,CAAK,GAC/EsgB,KAAatB,MAAkB3V,GAC/BkX,KAAiB3B,KAAeA,EAAY,UAAU5e,KAAS4e,EAAY,aAAaljB;AAE9F,iBACE,gBAAA4C;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,WAAW,YAAYgiB,KAAa,wBAAwB,EAAE;AAAA,cAG7D,UAAA;AAAA,gBAAAA,MACC,gBAAA/hB,EAAC,SAAI,WAAU,yDAAwD,OAAO,EAAE,iBAAiB,uBAAuB;AAAA,gBAG1H,gBAAAD;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,WAAS;AAAA,oBACT,aAAa,CAAC2B,OAAM;AAElB,sBAAAse,EAAYte,IAAGD,GAAOtE,GAAK2N,CAAK;AAAA,oBAClC;AAAA,oBACA,WAAAmV;AAAA,oBACA,YAAY,CAACve,OAAM2f,EAAsB3f,IAAGoJ,CAAK;AAAA,oBACjD,aAAayW;AAAA,oBACb,QAAQ,CAAC7f,OAAM8f,EAAkB9f,IAAGoJ,CAAK;AAAA,oBACzC,WAAW,qHAAqH0S,CAAW,IAAIsE,CAAY,IACzJC,KAAa,kBAAkB,EACjC,IAAIC,KAAiB,+BAA+B,EAAE;AAAA,oBAEtD,UAAA;AAAA,sBAAA,gBAAAhiB,EAAC6hB,GAAA,EAAU,WAAU,wBAAA,CAAwB;AAAA,sBAC7C,gBAAA7hB,EAAC,QAAA,EAAK,WAAU,gBAAgB,UAAAyB,GAAM;AAAA,sBACtC,gBAAAzB;AAAA,wBAAC;AAAA,wBAAA;AAAA,0BACC,MAAK;AAAA,0BACL,SAAS,MAAMgY,EAASvW,GAAOtE,CAAG;AAAA,0BAClC,WAAU;AAAA,0BACV,OAAO,eAAeuiB,CAAK;AAAA,0BAE3B,UAAA,gBAAA1f,EAACsL,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,wBAAA;AAAA,sBAAA;AAAA,oBACjC;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACF;AAAA,YAAA;AAAA,YAhCK,GAAG7J,CAAK,IAAIqJ,CAAK;AAAA,UAAA;AAAA,QAmC5B,CAAC,EAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,IAIHwV,KAAa1e,EAAO,WAAW,uBAC7B,OAAA,EAAI,WAAU,+BAA8B,UAAA,yBAAA,CAE7C;AAAA,EAAA,GAEJ;AAEJ;ACpSA,MAAM0F,KAAc7H,EAAQ,SAAS,GAC/B8H,KAAgB9H,EAAQ,WAAW,GACnC+H,KAAoB/H,EAAQ,eAAe;AAmBjD,SAAwBwiB,GAAiB;AAAA,EACvC,WAAA7f;AAAA,EACA,aAAAC;AAAA,EACA,eAAAC;AAAA,EACA,iBAAA4f;AAAA,EACA,cAAAtf;AAAA,EACA,qBAAAuf;AAAA,EACA,uBAAAC;AACF,GAA0B;AAGxB,QAAM,CAAC/B,GAAagC,CAAc,IAAIpf,EAI5B,IAAI,GAGRQ,IAAkBI;AAAA,IAAQ,MAC9Bye,GAAelgB,GAAW6b,EAAmB;AAAA,IAC7C,CAAC7b,CAAS;AAAA,EAAA,GAINuB,IAAkBF,EAAgB,cAAc,IAGhD8e,IAAuB,CAACplB,MAA0B;AACtD,UAAMkQ,IAAQhL,EAAYlF,CAA4B;AAEtD,WADe,MAAM,QAAQkQ,CAAK,IAAIA,IAAS,OAAOA,KAAU,WAAW,CAACA,CAAK,IAAI,CAAA;AAAA,EAEvF;AAGA,EAAA7J,GAAU,MAAM;AACd,QAAI,CAAC0e,EAAiB;AAEtB,UAAMM,IAAqB;AAAA,MACzB,GAAGN,EAAgB;AAAA,MACnB,GAAGA,EAAgB;AAAA,MACnB,GAAGA,EAAgB;AAAA,IAAA;AAGrB,QAAIO,IAAa;AACjB,UAAMC,IAAY,EAAE,GAAGrgB,EAAA;AAGvB,IAAAoB,EAAgB,UAAU,QAAQ,CAAAkf,MAAY;AAC5C,YAAMC,IAAgBL,EAAqBI,EAAS,GAAG,GACjDE,IAAcD,EAAc,OAAO,OAASJ,EAAmB,SAAS/gB,CAAK,CAAC;AAEpF,MAAIohB,EAAY,WAAWD,EAAc,WACvCH,IAAa,IACTI,EAAY,WAAW,IAEzB,OAAOH,EAAUC,EAAS,GAA4B,IAC7CA,EAAS,aAAa,IAE/BD,EAAUC,EAAS,GAA4B,IAAIE,EAAY,CAAC,IAGhEH,EAAUC,EAAS,GAA4B,IAAIE;AAAA,IAGzD,CAAC,GAEGJ,KACFN,EAAoBO,CAAS;AAAA,EAEjC,GAAG,CAACR,GAAiB7f,GAAaoB,EAAgB,WAAW0e,CAAmB,CAAC;AAGjF,QAAM9S,IAAe,CAAC5N,MACfygB,IACDA,EAAgB,SAAS,SAASzgB,CAAK,IAAU,YACjDygB,EAAgB,eAAe,SAASzgB,CAAK,IAAU,kBACpD,cAHsB,aAMzB0e,IAAkB,CAAC1e,MAAkB;AAGzC,YAFkB4N,EAAa5N,CAAK,GAE5B;AAAA,MACN,KAAK;AACH,eAAO;AAAA,UACL,eAAe6F;AAAA,UACf,aAAa;AAAA,UACb,cAAc;AAAA,QAAA;AAAA,MAElB,KAAK;AACH,eAAO;AAAA,UACL,eAAeE;AAAA,UACf,aAAa;AAAA,UACb,cAAc;AAAA,QAAA;AAAA,MAElB;AACE,eAAO;AAAA,UACL,eAAeD;AAAA,UACf,aAAa;AAAA,UACb,cAAc;AAAA,QAAA;AAAA,IAChB;AAAA,EAEN,GAGMub,IAAkB,CAACphB,GAAoCD,GAAeshB,GAAkBC,MAAuB;AACnH,IAAAthB,EAAE,aAAa,QAAQ,cAAc,KAAK,UAAU,EAAE,OAAAD,GAAO,UAAAshB,GAAU,WAAAC,EAAA,CAAW,CAAC,GAGnFX,EAAe,EAAE,OAAA5gB,GAAO,UAAAshB,GAAU,WAAAC,EAAA,CAAW;AAAA,EAC/C,GAEMC,IAAiB,CAACvhB,MAAuC;AAC7D,IAAAA,EAAE,eAAA;AAAA,EACJ,GAEMwhB,IAAgB,MAAM;AAE1B,IAAAb,EAAe,IAAI;AAAA,EACrB,GAEMc,IAAa,CAACzhB,GAAoC0hB,MAAmB;AACzE,IAAA1hB,EAAE,eAAA;AACF,UAAM+C,IAAO,KAAK,MAAM/C,EAAE,aAAa,QAAQ,YAAY,CAAC,GACtD,EAAE,OAAAD,GAAO,UAAAshB,EAAA,IAAate,GAEtBie,IAAY,EAAE,GAAGrgB,EAAA;AAGvB,QAAI0gB,MAAa,eAAeA,MAAaK,GAAQ;AACnD,YAAMC,IAAYX,EAAUK,CAAiC;AAC7D,UAAI,MAAM,QAAQM,CAAS,GAAG;AAC5B,cAAMC,IAAgBD,EAAU,OAAO,CAAAjjB,MAAKA,MAAMqB,CAAK;AACvD,QAAI6hB,EAAc,WAAW,IAC3B,OAAOZ,EAAUK,CAAiC,IAElDL,EAAUK,CAAiC,IAAIO;AAAA,MAEnD,MAAA,CAAWD,MAAc5hB,KACvB,OAAOihB,EAAUK,CAAiC;AAAA,IAEtD;AAGA,UAAMQ,IAAUb,EAAUU,CAA+B;AAGzD,IAFuB3f,EAAgB,UAAU,KAAK,CAAA+f,MAAMA,EAAG,QAAQJ,CAAM,GAEzD,aAAa,IAE/BV,EAAUU,CAA+B,IAAI3hB,IAGzC,MAAM,QAAQ8hB,CAAO,IAClBA,EAAQ,SAAS9hB,CAAK,MACzBihB,EAAUU,CAA+B,IAAI,CAAC,GAAGG,GAAS9hB,CAAK,KAGjEihB,EAAUU,CAA+B,IAAI,CAAC3hB,CAAK,GAKvD4gB,EAAe,IAAI,GACnBF,EAAoBO,CAAS;AAAA,EAC/B,GAEMe,IAAuB,CAAChiB,GAAeshB,MAAqB;AAChE,UAAML,IAAY,EAAE,GAAGrgB,EAAA,GACjBgL,IAAQqV,EAAUK,CAAiC;AAEzD,QAAI,MAAM,QAAQ1V,CAAK,GAAG;AACxB,YAAMiW,IAAgBjW,EAAM,OAAO,CAAAjN,MAAKA,MAAMqB,CAAK;AACnD,MAAI6hB,EAAc,WAAW,IAC3B,OAAOZ,EAAUK,CAAiC,IAElDL,EAAUK,CAAiC,IAAIO;AAAA,IAEnD,MAAA,CAAWjW,MAAU5L,KACnB,OAAOihB,EAAUK,CAAiC;AAGpD,IAAAZ,EAAoBO,CAAS;AAAA,EAC/B,GAEMgB,IAAgB,CAACV,GAAmBW,GAAiBC,MAAoB;AAC7E,UAAMlB,IAAY,EAAE,GAAGrgB,EAAA,GACjBgL,IAAQqV,EAAUkB,CAAgC;AAGxD,QAAI,MAAM,QAAQvW,CAAK,KAAKA,EAAM,SAAS,KAAK2V,MAAcW,GAAS;AACrE,YAAME,IAAW,CAAC,GAAGxW,CAAK,GACpB,CAACyW,CAAS,IAAID,EAAS,OAAOb,GAAW,CAAC;AAChD,MAAAa,EAAS,OAAOF,GAAS,GAAGG,CAAS,GACrCpB,EAAUkB,CAAgC,IAAIC,GAG9CxB,EAAe,IAAI,GACnBF,EAAoBO,CAAS;AAAA,IAC/B;AAAA,EACF,GAwBMqB,KArBsB,MAAM;AAChC,QAAI,CAAC7B,EAAiB,QAAO,EAAE,YAAY,CAAA,GAAI,gBAAgB,CAAA,GAAI,UAAU,GAAC;AAE9E,UAAM8B,wBAAqB,IAAA;AAC3B,WAAAvgB,EAAgB,UAAU,QAAQ,CAAA+f,MAAM;AACtC,MAAAjB,EAAqBiB,EAAG,GAAG,EAAE,QAAQ,OAASQ,EAAe,IAAIviB,CAAK,CAAC;AAAA,IACzE,CAAC,GAIG4e,KAAeA,EAAY,aAAa,eAC1C2D,EAAe,IAAI3D,EAAY,KAAK,GAG/B;AAAA,MACL,YAAY6B,EAAgB,WAAW,OAAO,OAAK,CAAC8B,EAAe,IAAI5jB,CAAC,CAAC;AAAA,MACzE,gBAAgB8hB,EAAgB,eAAe,OAAO,OAAK,CAAC8B,EAAe,IAAI5jB,CAAC,CAAC;AAAA,MACjF,UAAU8hB,EAAgB,SAAS,OAAO,OAAK,CAAC8B,EAAe,IAAI5jB,CAAC,CAAC;AAAA,IAAA;AAAA,EAEzE,GAEyB;AAGzB,2BACG,OAAA,EAEE,UAAA;AAAA,IAAA,CAACuD,KAAmBue,KACnB,gBAAAniB,EAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,qDAAoD,UAAA,oBAAgB;AAAA,wBACjF,OAAA,EAAI,WAAU,kEACX,UAAA+jB,EAAiB,WAAW,SAAS,KACrCA,EAAiB,eAAe,SAAS,KACzCA,EAAiB,SAAS,SAAS,IACnC,gBAAAhkB,EAAC,OAAA,EAAI,WAAU,qEAEb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,iEACb,UAAA;AAAA,YAAA,gBAAAC,EAACuH,IAAA,EAAc,WAAU,kCAAA,CAAkC;AAAA,YAAE;AAAA,UAAA,GAE/D;AAAA,UACA,gBAAAxH,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,YAAAgkB,EAAiB,WAAW,IAAI,CAAAzX,MAAO;AACtC,oBAAM0V,IAAiB3B,KAAeA,EAAY,UAAU/T,KAAO+T,EAAY,aAAa;AAC5F,qBACE,gBAAArgB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAS;AAAA,kBACT,aAAa,CAAC0B,MAAMohB,EAAgBphB,GAAG4K,GAAK,WAAW;AAAA,kBACvD,WAAW4W;AAAA,kBACX,WAAW,mJAAmJlB,IAAiB,+BAA+B,EAAE;AAAA,kBAChN,OAAO1V;AAAA,kBAEN,UAAAA;AAAA,gBAAA;AAAA,gBAPIA;AAAA,cAAA;AAAA,YAUX,CAAC;AAAA,YACAyX,EAAiB,WAAW,WAAW,uBACrC,OAAA,EAAI,WAAU,qCAAoC,UAAA,OAAA,CAAI;AAAA,UAAA,EAAA,CAE3D;AAAA,QAAA,GACF;AAAA,QAGA,gBAAAhkB,EAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,iEACb,UAAA;AAAA,YAAA,gBAAAC,EAACwH,IAAA,EAAkB,WAAU,kCAAA,CAAkC;AAAA,YAAE;AAAA,UAAA,GAEnE;AAAA,UACA,gBAAAzH,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,YAAAgkB,EAAiB,eAAe,IAAI,CAAAzX,MAAO;AAC1C,oBAAM0V,IAAiB3B,KAAeA,EAAY,UAAU/T,KAAO+T,EAAY,aAAa;AAC5F,qBACE,gBAAArgB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAS;AAAA,kBACT,aAAa,CAAC0B,MAAMohB,EAAgBphB,GAAG4K,GAAK,WAAW;AAAA,kBACvD,WAAW4W;AAAA,kBACX,WAAW,kKAAkKlB,IAAiB,+BAA+B,EAAE;AAAA,kBAC/N,OAAO1V;AAAA,kBAEN,UAAAA;AAAA,gBAAA;AAAA,gBAPIA;AAAA,cAAA;AAAA,YAUX,CAAC;AAAA,YACAyX,EAAiB,eAAe,WAAW,uBACzC,OAAA,EAAI,WAAU,qCAAoC,UAAA,OAAA,CAAI;AAAA,UAAA,EAAA,CAE3D;AAAA,QAAA,GACF;AAAA,QAGA,gBAAAhkB,EAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,iEACb,UAAA;AAAA,YAAA,gBAAAC,EAACsH,IAAA,EAAY,WAAU,kCAAA,CAAkC;AAAA,YAAE;AAAA,UAAA,GAE7D;AAAA,UACA,gBAAAvH,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,YAAAgkB,EAAiB,SAAS,IAAI,CAAA1iB,MAAW;AACxC,oBAAM2gB,IAAiB3B,KAAeA,EAAY,UAAUhf,KAAWgf,EAAY,aAAa;AAChG,qBACE,gBAAArgB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAS;AAAA,kBACT,aAAa,CAAC0B,MAAMohB,EAAgBphB,GAAGL,GAAS,WAAW;AAAA,kBAC3D,WAAW6hB;AAAA,kBACX,WAAW,6IAA6IlB,IAAiB,+BAA+B,EAAE;AAAA,kBAC1M,OAAO3gB;AAAA,kBAEN,UAAAA;AAAA,gBAAA;AAAA,gBAPIA;AAAA,cAAA;AAAA,YAUX,CAAC;AAAA,YACA0iB,EAAiB,SAAS,WAAW,uBACnC,OAAA,EAAI,WAAU,qCAAoC,UAAA,OAAA,CAAI;AAAA,UAAA,EAAA,CAE3D;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,GACF,IAEA,gBAAA/jB,EAAC,OAAA,EAAI,WAAU,+CAA8C,2CAE7D,EAAA,CAEJ;AAAA,IAAA,GACF;AAAA,IAID,CAAC2D,KACA,gBAAA5D,EAAC,OAAA,EAAI,WAAU,QACf,UAAA;AAAA,MAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,qDAAoD,UAAA,uBAAmB;AAAA,wBACpF,OAAA,EAAI,WAAU,aACZ,UAAAyD,EAAgB,UAAU,IAAI,CAAAkf,MAC7B,gBAAA3iB;AAAA,QAAC8f;AAAA,QAAA;AAAA,UAEC,QAAQ6C;AAAA,UACR,QAAQJ,EAAqBI,EAAS,GAAG;AAAA,UACzC,QAAQQ;AAAA,UACR,UAAUM;AAAA,UACV,aAAaX;AAAA,UACb,WAAWI;AAAA,UACX,YAAYD;AAAA,UACZ,iBAAA9C;AAAA,UACA,WAAWuD;AAAA,UACX,aAAArD;AAAA,QAAA;AAAA,QAVKsC,EAAS;AAAA,MAAA,CAYjB,EAAA,CACH;AAAA,IAAA,GACF;AAAA,KAIGlf,EAAgB,kBAAkBA,EAAgB,eAAe,SAAS,KAC1EA,EAAgB,wBAAwBA,EAAgB,qBAAqB,SAAS,MACvF,gBAAA1D,EAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,qDAAoD,UAAA,mBAAe;AAAA,MACjF,gBAAAD,EAAC,OAAA,EAAI,WAAU,aAEZ,UAAA;AAAA,QAAA0D,EAAgB,gBAAgB,SAAS,YAAY,KACpD,gBAAA1D,EAAC,SAAA,EAAM,WAAU,+BACf,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAASsC,EAAc,cAAc;AAAA,cACrC,UAAU,CAACZ,MAAM0gB,EAAsB;AAAA,gBACrC,GAAG9f;AAAA,gBACH,YAAYZ,EAAE,OAAO;AAAA,cAAA,CACtB;AAAA,cACD,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,oBAAA;AAAA,YAAoB;AAAA,UAAA;AAAA,UAEtC,gBAAA1B,EAAC,QAAA,EAAK,WAAU,wBAAuB,UAAA,cAAA,CAAW;AAAA,QAAA,GACpD;AAAA,QAGDyD,EAAgB,gBAAgB,SAAS,UAAU,KAClD,gBAAA1D,EAAC,SAAA,EAAM,WAAU,+BACf,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAASsC,EAAc,YAAY;AAAA,cACnC,UAAU,CAACZ,MAAM0gB,EAAsB;AAAA,gBACrC,GAAG9f;AAAA,gBACH,UAAUZ,EAAE,OAAO;AAAA,cAAA,CACpB;AAAA,cACD,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,oBAAA;AAAA,YAAoB;AAAA,UAAA;AAAA,UAEtC,gBAAA1B,EAAC,QAAA,EAAK,WAAU,wBAAuB,UAAA,YAAA,CAAS;AAAA,QAAA,GAClD;AAAA,QAGDyD,EAAgB,gBAAgB,SAAS,aAAa,KACrD,gBAAA1D,EAAC,SAAA,EAAM,WAAU,+BACf,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAASsC,EAAc,eAAe;AAAA,cACtC,UAAU,CAACZ,MAAM0gB,EAAsB;AAAA,gBACrC,GAAG9f;AAAA,gBACH,aAAaZ,EAAE,OAAO;AAAA,cAAA,CACvB;AAAA,cACD,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,oBAAA;AAAA,YAAoB;AAAA,UAAA;AAAA,UAEtC,gBAAA1B,EAAC,QAAA,EAAK,WAAU,wBAAuB,UAAA,eAAA,CAAY;AAAA,QAAA,GACrD;AAAA,QAGDyD,EAAgB,gBAAgB,SAAS,SAAS,KACjD,gBAAA1D,EAAC,SAAA,EAAM,WAAU,+BACf,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAASsC,EAAc,WAAW;AAAA,cAClC,UAAU,CAACZ,MAAM0gB,EAAsB;AAAA,gBACrC,GAAG9f;AAAA,gBACH,SAASZ,EAAE,OAAO;AAAA,cAAA,CACnB;AAAA,cACD,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,oBAAA;AAAA,YAAoB;AAAA,UAAA;AAAA,UAEtC,gBAAA1B,EAAC,QAAA,EAAK,WAAU,wBAAuB,UAAA,UAAA,CAAO;AAAA,QAAA,GAChD;AAAA,QAGDyD,EAAgB,gBAAgB,SAAS,YAAY,KACpD,gBAAA1D,EAAC,SAAA,EAAM,WAAU,+BACf,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAASsC,EAAc,cAAc;AAAA,cACrC,UAAU,CAACZ,MAAM0gB,EAAsB;AAAA,gBACrC,GAAG9f;AAAA,gBACH,YAAYZ,EAAE,OAAO;AAAA,cAAA,CACtB;AAAA,cACD,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,oBAAA;AAAA,YAAoB;AAAA,UAAA;AAAA,UAEtC,gBAAA1B,EAAC,QAAA,EAAK,WAAU,wBAAuB,UAAA,cAAA,CAAW;AAAA,QAAA,GACpD;AAAA,QAIDyD,EAAgB,sBAAsB,IAAI,CAAC+P,MAC1C,gBAAAzT,EAAC,OAAA,EAAqB,WAAU,aAC7B,UAAA;AAAA,UAAAyT,EAAO,SAAS,aACf,gBAAAzT,EAAC,SAAA,EAAM,WAAU,+BACf,UAAA;AAAA,YAAA,gBAAAC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAASsC,EAAckR,EAAO,GAA+B,KAAKA,EAAO,gBAAgB;AAAA,gBACzF,UAAU,CAAC9R,MAAM0gB,EAAsB;AAAA,kBACrC,GAAG9f;AAAA,kBACH,CAACkR,EAAO,GAAG,GAAG9R,EAAE,OAAO;AAAA,gBAAA,CACxB;AAAA,gBACD,WAAU;AAAA,gBACV,OAAO,EAAE,OAAO,oBAAA;AAAA,cAAoB;AAAA,YAAA;AAAA,YAEtC,gBAAA1B,EAAC,QAAA,EAAK,WAAU,wBAAwB,YAAO,MAAA,CAAM;AAAA,UAAA,GACvD;AAAA,UAGDwT,EAAO,SAAS,YACf,gBAAAzT,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,YAAA,gBAAAA,EAAC,SAAA,EAAM,WAAU,kCACd,UAAA;AAAA,cAAAyT,EAAO;AAAA,cACPA,EAAO,QAAQ,+BACb,QAAA,EAAK,WAAU,mCAAkC,UAAA,kCAAA,CAA+B;AAAA,YAAA,GAErF;AAAA,YACCA,EAAO,QAAQ,YACd,gBAAAxT;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAOsC,EAAckR,EAAO,GAA+B,KAAKA,EAAO,gBAAgB;AAAA,gBACvF,UAAU,CAAC9R,MAAM0gB,EAAsB;AAAA,kBACrC,GAAG9f;AAAA,kBACH,CAACkR,EAAO,GAAG,GAAG9R,EAAE,OAAO;AAAA,gBAAA,CACxB;AAAA,gBACD,aAAa8R,EAAO;AAAA,gBACpB,MAAM;AAAA,gBACN,WAAU;AAAA,cAAA;AAAA,YAAA,IAGZ,gBAAAxT;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAOsC,EAAckR,EAAO,GAA+B,KAAKA,EAAO,gBAAgB;AAAA,gBACvF,UAAU,CAAC9R,MAAM0gB,EAAsB;AAAA,kBACrC,GAAG9f;AAAA,kBACH,CAACkR,EAAO,GAAG,GAAG9R,EAAE,OAAO;AAAA,gBAAA,CACxB;AAAA,gBACD,aAAa8R,EAAO;AAAA,gBACpB,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAGbA,EAAO,eACN,gBAAAxT,EAAC,OAAE,WAAU,8BAA8B,YAAO,YAAA,CAAY;AAAA,UAAA,GAElE;AAAA,UAGDwT,EAAO,SAAS,kBACf,gBAAAzT,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,SAAA,EAAM,WAAU,kCAAkC,UAAAwT,EAAO,OAAM;AAAA,YAChE,gBAAAxT,EAAC,SAAI,WAAU,wBACZ,aAAc,OAAO,IAAI,CAACikB,GAAOnZ,MAAU;AAC1C,oBAAMb,KAAc3H,EAAckR,EAAO,GAA+B,KAAKA,EAAO,gBAAgB,OAAO1I;AAC3G,qBACE,gBAAA9K;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,MAAK;AAAA,kBACL,SAAS,MAAMoiB,EAAsB;AAAA,oBACnC,GAAG9f;AAAA,oBACH,CAACkR,EAAO,GAAG,GAAG1I;AAAA,kBAAA,CACf;AAAA,kBACD,WAAW,kJACTb,IACI,mCACA,4BACN;AAAA,kBACA,OAAO;AAAA,oBACL,iBAAiBga;AAAA,oBACjB,aAAaha,IAAa,sBAAsB;AAAA,kBAAA;AAAA,kBAElD,OAAO,SAASa,IAAQ,CAAC,KAAKmZ,CAAK;AAAA,gBAAA;AAAA,gBAf9BnZ;AAAA,cAAA;AAAA,YAkBX,CAAC,KAAK;AAAA;AAAA,cAEJ,gBAAA9K;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,MAAK;AAAA,kBACL,SAAS,MAAMoiB,EAAsB;AAAA,oBACnC,GAAG9f;AAAA,oBACH,CAACkR,EAAO,GAAG,GAAG;AAAA,kBAAA,CACf;AAAA,kBACD,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,iBAAiB;AAAA,oBACjB,aAAa;AAAA,oBACb,WAAW;AAAA,kBAAA;AAAA,kBAEb,OAAM;AAAA,gBAAA;AAAA,gBAZD;AAAA,cAAA;AAAA,YAaP,GAEJ;AAAA,YACCA,EAAO,eACN,gBAAAxT,EAAC,OAAE,WAAU,8BAA8B,YAAO,YAAA,CAAY;AAAA,UAAA,GAElE;AAAA,UAGDwT,EAAO,SAAS,YACf,gBAAAzT,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,SAAA,EAAM,WAAU,kCAAkC,UAAAwT,EAAO,OAAM;AAAA,YAChE,gBAAAxT;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAOsC,EAAckR,EAAO,GAA+B,KAAKA,EAAO,gBAAgB;AAAA,gBACvF,UAAU,CAAC9R,MAAM0gB,EAAsB;AAAA,kBACrC,GAAG9f;AAAA,kBACH,CAACkR,EAAO,GAAG,GAAG9R,EAAE,OAAO,UAAU,KAAK,SAAY,OAAOA,EAAE,OAAO,KAAK;AAAA,gBAAA,CACxE;AAAA,gBACD,aAAa8R,EAAO;AAAA,gBACpB,KAAKA,EAAO;AAAA,gBACZ,KAAKA,EAAO;AAAA,gBACZ,MAAMA,EAAO;AAAA,gBACb,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAEXA,EAAO,eACN,gBAAAxT,EAAC,OAAE,WAAU,8BAA8B,YAAO,YAAA,CAAY;AAAA,UAAA,GAElE;AAAA,UAGDwT,EAAO,SAAS,YACf,gBAAAzT,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,SAAA,EAAM,WAAU,kCAAkC,UAAAwT,EAAO,OAAM;AAAA,YAChE,gBAAAxT;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAOsC,EAAckR,EAAO,GAA+B,KAAKA,EAAO,gBAAgB;AAAA,gBACvF,UAAU,CAAC9R,MAAM0gB,EAAsB;AAAA,kBACrC,GAAG9f;AAAA,kBACH,CAACkR,EAAO,GAAG,GAAG9R,EAAE,OAAO;AAAA,gBAAA,CACxB;AAAA,gBACD,WAAU;AAAA,gBAET,UAAA8R,EAAO,SAAS,IAAI,CAACmB,MACpB,gBAAA3U,EAAC,UAAA,EAAuB,OAAO2U,EAAI,OAChC,UAAAA,EAAI,MAAA,GADMA,EAAI,KAEjB,CACD;AAAA,cAAA;AAAA,YAAA;AAAA,YAEFnB,EAAO,eACN,gBAAAxT,EAAC,OAAE,WAAU,8BAA8B,YAAO,YAAA,CAAY;AAAA,UAAA,GAElE;AAAA,UAGDwT,EAAO,SAAS,WACf,gBAAAzT,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,SAAA,EAAM,WAAU,kCAAkC,UAAAwT,EAAO,OAAM;AAAA,YAChE,gBAAAzT,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,cAAA,gBAAAC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,OAAOsC,EAAckR,EAAO,GAA+B,KAAKA,EAAO,gBAAgB;AAAA,kBACvF,UAAU,CAAC9R,MAAM0gB,EAAsB;AAAA,oBACrC,GAAG9f;AAAA,oBACH,CAACkR,EAAO,GAAG,GAAG9R,EAAE,OAAO;AAAA,kBAAA,CACxB;AAAA,kBACD,WAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEZ,gBAAA1B;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,OAAOsC,EAAckR,EAAO,GAA+B,KAAKA,EAAO,gBAAgB;AAAA,kBACvF,UAAU,CAAC9R,MAAM0gB,EAAsB;AAAA,oBACrC,GAAG9f;AAAA,oBACH,CAACkR,EAAO,GAAG,GAAG9R,EAAE,OAAO;AAAA,kBAAA,CACxB;AAAA,kBACD,aAAa8R,EAAO,eAAe;AAAA,kBACnC,WAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,YACZ,GACF;AAAA,YACCA,EAAO,eACN,gBAAAxT,EAAC,OAAE,WAAU,8BAA8B,YAAO,YAAA,CAAY;AAAA,UAAA,EAAA,CAElE;AAAA,QAAA,EAAA,GAjLMwT,EAAO,GAmLjB,CACD;AAAA,MAAA,EAAA,CACH;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;AChoBA,MAAM0Q,KAA4C,CAAC;AAAA,EACjD,iBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,OAAAjjB;AAAA,EACA,cAAAkjB,IAAe;AAAA,EACf,sBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,qBAAAC;AAAA;AAAA,EAEA,WAAAriB,IAAY;AAAA,EACZ,aAAAC,IAAc,CAAA;AAAA,EACd,eAAAC,IAAgB,CAAA;AAAA,EAChB,iBAAA4f;AAAA,EACA,mBAAAwC;AAAA,EACA,qBAAAvC;AAAA,EACA,uBAAAC;AAAA;AAAA,EAEA,YAAYuC,IAAiB;AAAA,EAC7B,oBAAAC;AACF,MAAM;AAEJ,QAAM1K,IAAYza,EAAQ,OAAO,GAC3BolB,IAAWplB,EAAQ,eAAe,GAClCwa,IAAcxa,EAAQ,SAAS,GAC/B2H,IAAc3H,EAAQ,SAAS,GAC/ByH,IAAkBzH,EAAQ,aAAa,GACvC+c,IAAgB/c,EAAQ,WAAW,GACnCsa,IAAYta,EAAQ,OAAO,GAC3B6H,IAAc7H,EAAQ,SAAS,GAC/BqlB,IAAkBrlB,EAAQ,aAAa,GAGvC,CAACslB,GAAiBC,CAAkB,IAAI/hB,EAA4B,OAAO,GAC3EgiB,IAAaL,IAAqBD,IAAiBI,GACnDG,IAAgBN,KAAsBI,GAGtC,CAACG,GAAiBC,CAAkB,IAAIniB,EAAS,EAAK,GAEtDoiB,IAAe,MACnB,gBAAArlB,EAAC,OAAA,EAAI,WAAU,2CACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,IAAA,gBAAAC,EAAC,SAAI,WAAU,+DAA8D,OAAO,EAAE,mBAAmB,uBAAuB;AAAA,IAChI,gBAAAA,EAAC,OAAA,EAAI,WAAU,qDAAoD,UAAA,sBAAkB;AAAA,IACrF,gBAAAA,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,0CAAA,CAAuC;AAAA,EAAA,EAAA,CACrF,EAAA,CACF,GAGIslB,IAAa,MACjB,gBAAAtlB,EAAC,OAAA,EAAI,WAAU,+CACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,IAAA,gBAAAC,EAACka,GAAA,EAAU,WAAU,sCAAA,CAAsC;AAAA,IAC3D,gBAAAla,EAAC,OAAA,EAAI,WAAU,2CAA0C,UAAA,0BAAsB;AAAA,IAC/E,gBAAAA,EAAC,OAAA,EAAI,WAAU,uCAAsC,UAAA,kFAErD;AAAA,IACCqkB,KACC,gBAAArkB,EAAC,OAAA,EAAI,WAAU,4DACb,4BAAC,OAAA,EAAI,WAAU,8CACZ,UAAAqkB,EAAA,CACH,EAAA,CACF;AAAA,EAAA,EAAA,CAEJ,EAAA,CACF,GAGIkB,IAAa,MACjB,gBAAAvlB,EAAC,OAAA,EAAI,WAAU,2CACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,IAAA,gBAAAC,EAAC6kB,GAAA,EAAS,WAAU,4CAAA,CAA4C;AAAA,IAChE,gBAAA7kB,EAAC,OAAA,EAAI,WAAU,qDAAoD,UAAA,kBAAc;AAAA,IACjF,gBAAAA,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,4CAAA,CAAyC;AAAA,EAAA,EAAA,CACvF,EAAA,CACF,GAIIwlB,KAAc,MAAM;AACxB,QAAI,CAACpB,KAAoBA,EAAiB,WAAW;AACnD,+BACG,OAAA,EAAI,WAAU,8DACb,UAAA,gBAAArkB,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAAC,EAACsH,GAAA,EAAY,WAAU,oCAAA,CAAoC;AAAA,QAC3D,gBAAAtH,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,sBAAkB;AAAA,QAC9D,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAU,UAAA,yCAAA,CAAsC;AAAA,MAAA,EAAA,CACjE,EAAA,CACF;AAIJ,UAAM8E,KAAc,KACdL,KAAO2f;AAEb,QAAI;AAEF,aAAKrf,GAAiB3C,CAAS,IAgB7B,gBAAApC;AAAA,QAACgF;AAAA,QAAA;AAAA,UACC,WAAA5C;AAAA,UACA,MALcA,MAAc,aAAa,CAAA,IAAKqC;AAAA,UAM9C,aAAApC;AAAA,UACA,eAAAC;AAAA,UACA,aAAalB;AAAA,UACb,QAAQ0D;AAAA,UACR,UACE,gBAAA9E,EAAC,OAAA,EAAI,WAAU,oCAAmC,OAAO,EAAE,QAAQ8E,GAAA,GACjE,UAAA,gBAAA9E,EAAC,OAAA,EAAI,WAAU,+DAA8D,EAAA,CAC/E;AAAA,QAAA;AAAA,MAAA,sBAxBD,OAAA,EAAI,WAAU,8DACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAAC,EAACoH,GAAA,EAAY,WAAU,oCAAA,CAAoC;AAAA,QAC3D,gBAAApH,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,0BAAsB;AAAA,QAClE,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAW,UAAAoC,EAAA,CAAU;AAAA,MAAA,EAAA,CACtC,EAAA,CACF;AAAA,IAsBN,SAASvC,IAAO;AACd,qBAAQ,MAAM,0BAA0BA,EAAK,qBAE1C,OAAA,EAAI,WAAU,kEACb,UAAA,gBAAAE,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAAC,EAACka,GAAA,EAAU,WAAU,sCAAA,CAAsC;AAAA,QAC3D,gBAAAla,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,0BAAsB;AAAA,QAClE,gBAAAA,EAAC,SAAI,WAAU,kCAAkC,wBAAiB,QAAQH,GAAM,UAAU,gBAAA,CAAgB;AAAA,MAAA,EAAA,CAC5G,EAAA,CACF;AAAA,IAEJ;AAAA,EACF;AAyKA,SACE,gBAAAE,EAAC,OAAA,EAAI,WAAU,iFAEb,UAAA;AAAA,IAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,+DACb,UAAA,gBAAAA,EAAC,QAAG,WAAU,sCAAqC,2BAAa,EAAA,CAClE;AAAA,IAGA,gBAAAD,EAAC,OAAA,EAAI,WAAU,kBACZ,UAAA;AAAA,MAAAokB,MAAoB,+BAAckB,GAAA,CAAA,CAAa;AAAA,MAC/ClB,MAAoB,WAAW,gBAAAnkB,EAACslB,GAAA,CAAA,CAAW;AAAA,MAC3CnB,MAAoB,aAAa,gBAAAnkB,EAlLnB,MACf,CAACokB,KAAoBA,EAAiB,WAAW,sBAEhD,OAAA,EAAI,WAAU,2CACb,UAAA,gBAAArkB,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAAC,EAACia,GAAA,EAAY,WAAU,wCAAA,CAAwC;AAAA,QAC/D,gBAAAja,EAAC,OAAA,EAAI,WAAU,4CAA2C,UAAA,oBAAgB;AAAA,QAC1E,gBAAAA,EAAC,OAAA,EAAI,WAAU,yBAAwB,UAAA,kCAAA,CAA+B;AAAA,MAAA,EAAA,CACxE,EAAA,CACF,IAKF,gBAAAD,EAAC,OAAA,EAAI,WAAU,wBAEb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,yDACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qDAEb,UAAA;AAAA,YAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,cAAA,gBAAAC,EAACia,GAAA,EAAY,WAAU,8BAAA,CAA8B;AAAA,cACrD,gBAAAla,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,gBAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,gDAA+C,UAAA;AAAA,kBAAA;AAAA,kBAC7CqkB,EAAiB;AAAA,kBAAO;AAAA,kBAAKA,EAAiB,WAAW,IAAI,MAAM;AAAA,kBAAG;AAAA,gBAAA,GACxF;AAAA,gBACCK,MAAwB,aAAaD,MAAkB,QAAQA,MAAkB,UAChF,gBAAAzkB,EAAC,QAAA,EAAK,WAAU,8BAA6B,UAAA;AAAA,kBAAA;AAAA,kBACnCykB,EAAc,eAAA;AAAA,kBAAiB;AAAA,kBAAKA,MAAkB,IAAI,MAAM;AAAA,gBAAA,GAC1E;AAAA,gBAEDC,MAAwB,aACvB,gBAAAzkB,EAAC,QAAA,EAAK,WAAU,8BAA6B,UAAA,yBAAA,CAE7C;AAAA,cAAA,EAAA,CAEJ;AAAA,YAAA,GACF;AAAA,YAGA,gBAAAD,EAAC,OAAA,EAAI,WAAU,qCAEb,UAAA;AAAA,cAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,sFACb,UAAA;AAAA,gBAAA,gBAAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,SAAS,MAAMmlB,EAAc,OAAO;AAAA,oBACpC,WAAW,6EACTD,MAAe,UACX,6BACA,kDACN;AAAA,oBAEA,UAAA;AAAA,sBAAA,gBAAAjlB,EAAC+Z,GAAA,EAAU,WAAU,cAAA,CAAc;AAAA,sBAAE;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAGvC,gBAAAha;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,SAAS,MAAMmlB,EAAc,OAAO;AAAA,oBACpC,WAAW,6EACTD,MAAe,UACX,6BACA,kDACN;AAAA,oBAEA,UAAA;AAAA,sBAAA,gBAAAjlB,EAACsH,GAAA,EAAY,WAAU,cAAA,CAAc;AAAA,sBAAE;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAEzC,GACF;AAAA,cAGC2d,MAAe,WAAWV,KACzB,gBAAAxkB,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,gBAAA,gBAAAC,EAAC,SAAA,EAAM,WAAU,kCAAiC,UAAA,SAAK;AAAA,gBACvD,gBAAAD;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,OAAOukB;AAAA,oBACP,UAAU,CAAC5iB,OAAM6iB,EAAqB,OAAO7iB,GAAE,OAAO,KAAK,CAAC;AAAA,oBAC5D,WAAU;AAAA,oBAEV,UAAA;AAAA,sBAAA,gBAAA1B,EAAC,UAAA,EAAO,OAAO,IAAI,UAAA,WAAO;AAAA,sBAC1B,gBAAAA,EAAC,UAAA,EAAO,OAAO,IAAI,UAAA,WAAO;AAAA,sBAC1B,gBAAAA,EAAC,UAAA,EAAO,OAAO,KAAK,UAAA,WAAA,CAAQ;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAC9B,EAAA,CACF;AAAA,YAAA,EAAA,CAEJ;AAAA,UAAA,GACF;AAAA,UAGCilB,MAAe,WAAWP,KACzB,gBAAA3kB,EAAC,OAAA,EAAI,WAAU,yFAEb,UAAA;AAAA,YAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,cAAA,gBAAAC,EAAC,SAAA,EAAM,WAAU,oDAAmD,UAAA,eAAW;AAAA,cAC/E,gBAAAA;AAAA,gBAACif;AAAA,gBAAA;AAAA,kBACC,cAAc7c;AAAA,kBACd,cAAcsiB;AAAA,gBAAA;AAAA,cAAA;AAAA,YAChB,GACF;AAAA,YAGCtiB,MAAc,WAAW+f,KAAuBC,KAC/C,gBAAAriB;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAMqlB,EAAmB,CAACD,CAAe;AAAA,gBAClD,WAAW,0FACTA,IACI,6BACA,wFACN;AAAA,gBAEA,UAAA;AAAA,kBAAA,gBAAAnlB,EAAC8kB,GAAA,EAAgB,WAAU,UAAA,CAAU;AAAA,kBACpCK,IAAkB,gBAAgB;AAAA,kBAClCA,sBACE3I,GAAA,EAAc,WAAU,eAAc,IAEvC,gBAAAxc,EAACkH,GAAA,EAAgB,WAAU,cAAA,CAAc;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UAE7C,GAEJ;AAAA,UAIDud,MAAwB,aAAaD,MAAkB,QAAQA,MAAkB,UAAaA,IAAgB,OAC7G,gBAAAzkB,EAAC,OAAA,EAAI,WAAU,8EACb,UAAA;AAAA,YAAA,gBAAAC,EAACoH,GAAA,EAAY,WAAU,+CAAA,CAA+C;AAAA,YACtE,gBAAArH,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,cAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,iBAAgB,UAAA,wBAAoB;AAAA,cAAO;AAAA,cAAqBwkB,EAAc,eAAA;AAAA,cAAiB;AAAA,YAAA,EAAA,CAEjH;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,GAEJ;AAAA,QAGCS,MAAe,WAAWE,KAAmB/iB,MAAc,WAAW+f,KAAuBC,KAC5F,gBAAApiB,EAAC,OAAA,EAAI,WAAU,wDACb,UAAA,gBAAAA;AAAA,UAACiiB;AAAA,UAAA;AAAA,YACC,WAAA7f;AAAA,YACA,aAAAC;AAAA,YACA,eAAAC;AAAA,YACA,iBAAiB4f,KAAmB;AAAA,YACpC,qBAAAC;AAAA,YACA,uBAAAC;AAAA,UAAA;AAAA,QAAA,GAEJ;AAAA,QAIF,gBAAApiB,EAAC,OAAA,EAAI,WAAU,kBACZ,gBAAe,UACd,gBAAAA;AAAA,UAACgF;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,MAAMof;AAAA,YACN,QAAO;AAAA,YACP,4BACG,OAAA,EAAI,WAAU,2CACb,UAAA,gBAAApkB,EAAC,OAAA,EAAI,WAAU,8DAAA,CAA8D,EAAA,CAC/E;AAAA,UAAA;AAAA,QAAA,IAIJ,gBAAAA,EAAC,OAAA,EAAI,WAAU,4BACZ,UAAAwlB,GAAA,GACH,EAAA,CAEJ;AAAA,MAAA,GACF,GAeqC,CAAA,CAAa;AAAA,MAC/CrB,MAAoB,UAAU,gBAAAnkB,EAACulB,GAAA,CAAA,CAAW;AAAA,IAAA,EAAA,CAC7C;AAAA,EAAA,GACF;AAEJ,GCxUMre,KAAkBzH,EAAQ,aAAa,GACvC+c,KAAgB/c,EAAQ,WAAW,GACnC4H,KAAe5H,EAAQ,UAAU,GACjCD,KAAcC,EAAQ,SAAS,GAU/BgmB,KAAwC,CAAC;AAAA,EAC7C,QAAAvgB;AAAA,EACA,UAAAwgB;AAAA,EACA,QAAAjG;AAAA,EACA,gBAAAkG;AAAA,EACA,SAAAC;AACF,MAAM;AACJ,QAAM,CAACC,GAAaC,CAAc,IAAI7iB,EAAoBwc,CAAM,GAE1DsG,IAAc,MAAM;AACxB,IAAAJ,EAAeE,CAAW;AAAA,EAC5B,GAEMG,IAAc,MAAM;AACxB,UAAMC,IAAgB;AAAA,MACpB,YAAY;AAAA,MACZ,UAAU;AAAA,IAAA;AAEZ,IAAAH,EAAeG,CAAa,GAC5BN,EAAeM,CAAa,GAC5BL,EAAA;AAAA,EACF,GAEMM,IAAoB,CAACzkB,GAAwB4L,MAAkB;AACnE,IAAAyY,EAAe,CAAAthB,OAAS;AAAA,MACtB,GAAGA;AAAA,MACH,CAAC/C,CAAK,GAAG4L;AAAA,IAAA,EACT;AAAA,EACJ,GAEMoV,IAAa,KAAK,UAAUoD,CAAW,MAAM,KAAK,UAAUpG,CAAM,GAClE0G,IAAkB1G,EAAO,eAAe,oBAAoBA,EAAO,aAAa;AAEtF,SACE,gBAAA1f,EAAC,OAAA,EAAI,WAAU,yDAEb,UAAA;AAAA,IAAA,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS2lB;AAAA,QACT,WAAU;AAAA,QAEV,UAAA;AAAA,UAAA,gBAAA3lB,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,YAAA,gBAAAC,EAACqH,IAAA,EAAa,WAAU,iCAAA,CAAiC;AAAA,YACzD,gBAAArH,EAAC,MAAA,EAAG,WAAU,sCAAqC,UAAA,qBAAiB;AAAA,YACnE,CAACmmB,KACA,gBAAAnmB,EAAC,QAAA,EAAK,WAAU,+FAA8F,UAAA,SAAA,CAE9G;AAAA,UAAA,GAEJ;AAAA,UACCkF,sBACEsX,IAAA,EAAc,WAAU,8BAA6B,IAEtD,gBAAAxc,EAACkH,IAAA,EAAgB,WAAU,6BAAA,CAA6B;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAK3DhC,uBACE,OAAA,EAAI,WAAU,iCACb,UAAA,gBAAAnF,EAAC,OAAA,EAAI,WAAU,aAEb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EACC,UAAA;AAAA,QAAA,gBAAAC,EAAC,SAAA,EAAM,WAAU,yDAAwD,UAAA,gBAEzE;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO6lB,EAAY;AAAA,YACnB,UAAU,CAACnkB,MAAMwkB,EAAkB,cAAcxkB,EAAE,OAAO,KAAK;AAAA,YAC/D,WAAU;AAAA,YACV,aAAY;AAAA,UAAA;AAAA,QAAA;AAAA,QAEd,gBAAA1B,EAAC,KAAA,EAAE,WAAU,mCAAkC,UAAA,6CAAA,CAE/C;AAAA,MAAA,GACF;AAAA,wBAGC,OAAA,EACC,UAAA;AAAA,QAAA,gBAAAA,EAAC,SAAA,EAAM,WAAU,yDAAwD,UAAA,aAEzE;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO6lB,EAAY;AAAA,YACnB,UAAU,CAACnkB,MAAMwkB,EAAkB,YAAYxkB,EAAE,OAAO,KAAK;AAAA,YAC7D,WAAU;AAAA,YACV,aAAY;AAAA,UAAA;AAAA,QAAA;AAAA,QAEd,gBAAA1B,EAAC,KAAA,EAAE,WAAU,mCAAkC,UAAA,+CAAA,CAE/C;AAAA,MAAA,GACF;AAAA,wBAGC,OAAA,EAAI,WAAU,kEACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EACC,UAAA;AAAA,UAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,8CAA6C,UAAA,yBAAqB;AAAA,UAChF,gBAAAD,EAAC,KAAA,EAAE,WAAU,uCAAsC,UAAA;AAAA,YAAA;AAAA,YAC5C,gBAAAC,EAAC,QAAA,EAAK,WAAU,aAAa,YAAO,WAAA,CAAW;AAAA,UAAA,GACtD;AAAA,UACA,gBAAAD,EAAC,KAAA,EAAE,WAAU,kCAAiC,UAAA;AAAA,YAAA;AAAA,YACpC0f,EAAO,WACb,gBAAAzf,EAAC,QAAA,EAAK,WAAU,kBAAiB,UAAA,aAAA,CAAU,IAE3C,gBAAAA,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA,UAAA,CAAO;AAAA,UAAA,EAAA,CAEhD;AAAA,QAAA,GACF;AAAA,QACC,CAACmmB,KACA,gBAAApmB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAASimB;AAAA,YACT,WAAU;AAAA,YACV,OAAM;AAAA,YAEN,UAAA;AAAA,cAAA,gBAAAhmB,EAACR,IAAA,EAAY,WAAU,UAAA,CAAU;AAAA,cACjC,gBAAAQ,EAAC,UAAK,UAAA,QAAA,CAAK;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACb,EAAA,CAEJ,EAAA,CACF;AAAA,MAGCyiB,KACC,gBAAA1iB,EAAC,OAAA,EAAI,WAAU,6DACb,UAAA;AAAA,QAAA,gBAAAC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAM8lB,EAAerG,CAAM;AAAA,YACpC,WAAU;AAAA,YACX,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGD,gBAAAzf;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS+lB;AAAA,YACT,WAAU;AAAA,YACV,OAAO,EAAE,iBAAiB,oBAAA;AAAA,YAC3B,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,EAAA,CACF;AAAA,IAAA,EAAA,CAEJ,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ,GCnKaK,KAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wHA2DjCC,KAAiB,0BAEjBC,KAAoB;AAAA,EAC/B,UAAU;AAAA,EACV,QAAQ;AACV;ACtDA,eAAsBC,GACpBC,GACAC,GACAC,IAAmB,oBACO;AAC1B,QAAMC,IAA8B;AAAA,IAClC,MAAMF;AAAA;AAAA,EAAA,GAIFG,IAAkC;AAAA,IACtC,gBAAgB;AAAA,EAAA;AAGlB,EAAIJ,KAAUA,EAAO,WACnBI,EAAQ,WAAW,IAAIJ,IAGzB,QAAQ,IAAI,4CAA4C,GACxD,QAAQ,IAAI,UAAUE,CAAQ,GAC9B,QAAQ,IAAI,cAAcE,CAAO,GACjC,QAAQ,IAAI,yBAAyBH,EAAW,MAAM;AAEtD,QAAMI,IAAW,MAAM,MAAMH,GAAU;AAAA,IACrC,QAAQ;AAAA,IACR,SAAAE;AAAA,IACA,MAAM,KAAK,UAAUD,CAAW;AAAA,EAAA,CACjC;AAMD,MAJA,QAAQ,IAAI,2BAA2B,GACvC,QAAQ,IAAI,aAAaE,EAAS,MAAM,GACxC,QAAQ,IAAI,kBAAkBA,EAAS,UAAU,GAE7C,CAACA,EAAS,IAAI;AAChB,QAAIC,IAAe,+BAA+BD,EAAS,MAAM,IAAIA,EAAS,UAAU;AAExF,QAAI;AAEF,YAAME,IAAY,MAAMF,EAAS,KAAA;AAIjC,UAHA,QAAQ,MAAM,0BAA0BE,CAAS,GAG7CF,EAAS,WAAW,OAAOE,EAAU,UAAU;AACjD,cAAM,IAAI;AAAA,UACR,GAAGA,EAAU,OAAO;AAAA;AAAA,EAAOA,EAAU,cAAc,mDAAmD;AAAA,QAAA;AAK1G,MAAIA,EAAU,UACZD,IAAeC,EAAU,WAAWA,EAAU,OAC1CA,EAAU,eACZD,KAAgB;AAAA;AAAA,KAAUC,EAAU,UAAU;AAAA,IAGpD,QAAqB;AAEnB,UAAI;AACF,cAAMC,IAAY,MAAMH,EAAS,KAAA;AACjC,gBAAQ,MAAM,+BAA+BG,CAAS,GACtDF,IAAeE,KAAaF;AAAA,MAC9B,QAAoB;AAClB,gBAAQ,MAAM,0CAA0C;AAAA,MAC1D;AAAA,IACF;AAEA,UAAM,IAAI,MAAMA,CAAY;AAAA,EAC9B;AAEA,QAAMriB,IAAO,MAAMoiB,EAAS,KAAA;AAC5B,iBAAQ,IAAI,0CAA0C,GAC/CpiB;AACT;AAmBO,SAASwiB,KAAyB;AACvC,MAAI;AACF,UAAMC,IAAQ,aAAa,QAAQb,EAAc;AACjD,QAAIa,GAAO;AACT,YAAMpjB,IAAS,KAAK,MAAMojB,CAAK;AAC/B,aAAO,EAAE,GAAGZ,IAAmB,GAAGxiB,EAAA;AAAA,IACpC;AAAA,EACF,SAASjE,GAAO;AACd,YAAQ,KAAK,+CAA+CA,CAAK;AAAA,EACnE;AACA,SAAO,EAAE,GAAGymB,GAAA;AACd;AAKO,SAASa,GAAwBN,GAAmC;AAIzE,UAHgBA,EAAS,SAAS,IAI/B,QAAQ,eAAe,EAAE,EACzB,QAAQ,WAAW,EAAE,EACrB,QAAQ,iBAAiB,EAAE,EAC3B,KAAA;AACL;ACxHA,MAAM3M,KAAYza,EAAQ,OAAO,GAC3Bwa,KAAcxa,EAAQ,SAAS,GAC/B8c,KAAe9c,EAAQ,UAAU,GAiBjC2nB,KAAoD,CAAC;AAAA,EACzD,QAAAliB;AAAA,EACA,SAAAC;AAAA,EACA,aAAAkiB;AAAA,EACA,YAAAC,IAAa;AACf,MAAM;AACJ,QAAM,CAACroB,GAAOC,CAAQ,IAAI+D,EAA2B,OAE5C;AAAA,IACL,MAAM;AAAA;AAAA,IACN,QAHkBgkB,GAAA,EAGE,UAAU;AAAA,IAC9B,sBAAsBb;AAAA,IACtB,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,UAAU;AAAA,IACV,eAAe;AAAA,IACf,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,EAAA,EAEpB,GAGKmB,IAAoB,OAAO7lB,MAAwB;AAEvD,QADAA,GAAG,eAAA,GACC,EAACzC,EAAM,WAAW,QAEtB;AAAA,MAAAC,EAAS,CAAAsF,OAAS;AAAA,QAChB,GAAGA;AAAA,QACH,cAAc;AAAA,QACd,UAAU;AAAA,QACV,eAAe;AAAA,QACf,kBAAkB;AAAA,QAClB,iBAAiB;AAAA,QACjB,cAAc;AAAA,MAAA,EACd;AAEF,UAAI;AAEF,cAAMqiB,IAAW,MAAMN;AAAA,UACrBtnB,EAAM;AAAA,UACNA,EAAM;AAAA,UACNqoB;AAAA,QAAA,GAGIE,IAAeL,GAAwBN,CAAQ;AACrD,QAAA3nB,EAAS,CAAAsF,OAAS;AAAA,UAChB,GAAGA;AAAA,UACH,cAAc;AAAA,UACd,UAAUgjB;AAAA,QAAA,EACV,GAGF,WAAW,MAAM;AACf,UAAAC,EAAiBD,CAAY;AAAA,QAC/B,GAAG,GAAG;AAAA,MACR,SAAS3nB,GAAO;AACd,QAAAX,EAAS,CAAAsF,OAAS;AAAA,UAChB,GAAGA;AAAA,UACH,cAAc;AAAA,UACd,eAAe3E,aAAiB,QAAQA,EAAM,UAAU;AAAA,QAAA,EACxD;AAAA,MACJ;AAAA;AAAA,EACF,GAGM4nB,IAAmB,OAAOD,MAAyB;AACvD,QAAI,CAACA,GAAc;AACjB,cAAQ,IAAI,wCAAwC;AACpD;AAAA,IACF;AAEA,YAAQ,IAAI,gDAAgDA,EAAa,UAAU,GAAG,GAAG,IAAI,KAAK,GAElGtoB,EAAS,CAAAsF,OAAS;AAAA,MAChB,GAAGA;AAAA,MACH,cAAc;AAAA,MACd,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,IAAA,EACjB;AAEF,QAAI;AACF,YAAMpD,IAAQ,KAAK,MAAMomB,CAAY;AACrC,cAAQ,IAAI,2BAA2BpmB,CAAK;AAE5C,YAAMylB,IAAW,MAAM,MAAM,uBAAuB;AAAA,QAClD,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAAA;AAAA,QAElB,MAAM,KAAK,UAAUzlB,CAAK;AAAA,MAAA,CAC3B;AAID,UAFA,QAAQ,IAAI,yCAAyCylB,EAAS,MAAM,GAEhEA,EAAS;AACX,gBAAQ,IAAI,8BAA8B,GAC1C3nB,EAAS,CAAAsF,OAAS;AAAA,UAChB,GAAGA;AAAA,UACH,cAAc;AAAA,UACd,kBAAkB;AAAA,QAAA,EAClB;AAAA,WACG;AACL,cAAMuiB,IAAY,MAAMF,EAAS,KAAA;AACjC,gBAAQ,IAAI,gCAAgCE,CAAS,GACrD7nB,EAAS,CAAAsF,OAAS;AAAA,UAChB,GAAGA;AAAA,UACH,cAAc;AAAA,UACd,kBAAkB;AAAA,UAClB,iBAAiBuiB,KAAa,QAAQF,EAAS,MAAM,KAAKA,EAAS,UAAU;AAAA,QAAA,EAC7E;AAAA,MACJ;AAAA,IACF,SAAShnB,GAAO;AACd,cAAQ,IAAI,+BAA+BA,CAAK,GAChDX,EAAS,CAAAsF,OAAS;AAAA,QAChB,GAAGA;AAAA,QACH,cAAc;AAAA,QACd,kBAAkB;AAAA,QAClB,iBAAiB3E,aAAiB,QAAQA,EAAM,UAAU;AAAA,MAAA,EAC1D;AAAA,IACJ;AAAA,EACF,GAEM6nB,IAAiB,YAAY;AACjC,IAAKzoB,EAAM,YACX,MAAMwoB,EAAiBxoB,EAAM,QAAQ;AAAA,EACvC,GAEM0oB,IAAiB,MAAM;AAC3B,QAAI,GAAC1oB,EAAM,YAAY,CAACooB;AAExB,UAAI;AACF,cAAMjmB,IAAQ,KAAK,MAAMnC,EAAM,QAAQ;AACvC,QAAAooB,EAAYjmB,CAAK,GACjBwmB,EAAA;AAAA,MACF,QAAgB;AACd,QAAA1oB,EAAS,CAAAsF,OAAS;AAAA,UAChB,GAAGA;AAAA,UACH,iBAAiB;AAAA,QAAA,EACjB;AAAA,MACJ;AAAA,EACF,GAEMojB,IAAc,MAAM;AACxB,IAAA1oB,EAAS,CAAAsF,OAAS;AAAA,MAChB,GAAGA;AAAA,MACH,UAAU;AAAA,MACV,eAAe;AAAA,MACf,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,IAAA,EACjB,GACFW,EAAA;AAAA,EACF,GAEM0iB,IAAgB,CAACnmB,MAAgD;AACrE,IAAIA,EAAE,QAAQ,WAAW,CAACA,EAAE,aAC1BA,EAAE,eAAA,GACF6lB,EAAA;AAAA,EAEJ;AAuJA,SACE,gBAAAvnB;AAAA,IAACiF;AAAA,IAAA;AAAA,MACC,QAAAC;AAAA,MACA,SAAS0iB;AAAA,MACT,OAPK;AAAA,MAQL,MAAK;AAAA,MAEJ,UAzJH,gBAAA7nB,EAAC,OAAA,EAAI,WAAU,2BAEb,UAAA;AAAA,QAAA,gBAAAC,EAAC,SAAI,WAAU,2EACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA;AAAA,UAAA;AAAA,UACnC,gBAAAC,EAAC,QAAA,EAAK,WAAU,eAAc,UAAA,uBAAmB;AAAA,UACxD,gBAAAA,EAAC,QAAA,EAAK,WAAU,+DAA8D,UAAA,oCAAA,CAE9E;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QAGA,gBAAAD,EAAC,OAAA,EAAI,WAAU,kDAEb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,iCACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,SAAA,EAAM,SAAQ,eAAc,WAAU,yDAAwD,UAAA,2CAE/F;AAAA,YACA,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,OAAOf,EAAM;AAAA,gBACb,UAAU,CAACyC,MAAMxC,EAAS,CAAAsF,OAAS,EAAE,GAAGA,GAAM,YAAY9C,EAAE,OAAO,MAAA,EAAQ;AAAA,gBAC3E,WAAWmmB;AAAA,gBACX,aAAY;AAAA,gBACZ,WAAU;AAAA,gBACV,UAAQ;AAAA,cAAA;AAAA,YAAA;AAAA,UACV,GACF;AAAA,UAGA,gBAAA9nB,EAAC,OAAA,EAAI,WAAU,iCACb,UAAA;AAAA,YAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,cAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,+BACZ,UAAAf,EAAM,WACL,gBAAAc,EAAAoJ,IAAA,EACE,UAAA;AAAA,gBAAA,gBAAAnJ,EAACia,IAAA,EAAY,WAAU,yBAAA,CAAyB;AAAA,gBAChD,gBAAAja,EAAC,QAAA,EAAK,WAAU,sCAAqC,UAAA,qBAAA,CAAkB;AAAA,cAAA,GACzE,IAEA,gBAAAA,EAAC,QAAA,EAAK,WAAU,0CAAyC,6BAAe,GAE5E;AAAA,cACCf,EAAM,YACL,gBAAAe;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,SAAS0nB;AAAA,kBACT,UAAUzoB,EAAM;AAAA,kBAChB,WAAU;AAAA,kBACV,OAAM;AAAA,kBAEL,UAAAA,EAAM,eAAe,kBAAkB;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC1C,GAEJ;AAAA,YAECA,EAAM,WACL,gBAAAe,EAAC,OAAA,EAAI,WAAU,6DACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qGACZ,UAAAf,EAAM,SAAA,CACT,GACF,IAEA,gBAAAe,EAAC,OAAA,EAAI,WAAU,8HACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,eACb,UAAA,gBAAAA,EAACuc,IAAA,EAAa,WAAU,uCAAA,CAAuC,EAAA,CACjE,EAAA,CACF;AAAA,UAAA,EAAA,CAEJ;AAAA,QAAA,GACF;AAAA,QAGA,gBAAAxc,EAAC,OAAA,EAAI,WAAU,YACZ,UAAA;AAAA,UAAAd,EAAM,iBACL,gBAAAc,EAAC,OAAA,EAAI,WAAU,6EACb,UAAA;AAAA,YAAA,gBAAAC,EAACka,IAAA,EAAU,WAAU,uCAAA,CAAuC;AAAA,YAC5D,gBAAAla,EAAC,OAAA,EAAI,WAAU,wBAAwB,YAAM,cAAA,CAAc;AAAA,UAAA,GAC7D;AAAA,UAGDf,EAAM,gBACL,gBAAAc,EAAC,OAAA,EAAI,WAAU,+EACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,+EAAA,CAA+E;AAAA,YAC9F,gBAAAA,EAAC,OAAA,EAAI,WAAU,yBAAwB,UAAA,sBAAA,CAAmB;AAAA,UAAA,GAC5D;AAAA,UAGDf,EAAM,qBAAqB,WAAW,CAACA,EAAM,gBAC5C,gBAAAc,EAAC,OAAA,EAAI,WAAU,iFACb,UAAA;AAAA,YAAA,gBAAAC,EAACia,IAAA,EAAY,WAAU,yCAAA,CAAyC;AAAA,YAChE,gBAAAja,EAAC,OAAA,EAAI,WAAU,0BAAyB,UAAA,mCAAA,CAAgC;AAAA,UAAA,GAC1E;AAAA,UAGDf,EAAM,qBAAqB,aAAa,CAACA,EAAM,gBAC9C,gBAAAc,EAAC,OAAA,EAAI,WAAU,6EACb,UAAA;AAAA,YAAA,gBAAAC,EAACka,IAAA,EAAU,WAAU,uCAAA,CAAuC;AAAA,YAC5D,gBAAAna,EAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,cAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,oBAAmB,UAAA,4BAAwB;AAAA,cAC1D,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAW,YAAM,gBAAA,CAAgB;AAAA,YAAA,EAAA,CAClD;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,GAEJ;AAAA,QAGA,gBAAAD,EAAC,OAAA,EAAI,WAAU,4CACb,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,UAAU,CAACf,EAAM,WAAW,KAAA,KAAUA,EAAM;AAAA,cAC5C,SAASsoB;AAAA,cACT,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,iBAAiB;AAAA,cAAA;AAAA,cAGlB,UAAAtoB,EAAM,eACL,gBAAAc,EAAAoJ,IAAA,EACE,UAAA;AAAA,gBAAA,gBAAAnJ,EAAC,OAAA,EAAI,WAAU,iEAAA,CAAiE;AAAA,gBAAM;AAAA,cAAA,EAAA,CAExF,IAEA,gBAAAD,EAAAoJ,IAAA,EACE,UAAA;AAAA,gBAAA,gBAAAnJ,EAACuc,IAAA,EAAa,WAAU,eAAA,CAAe;AAAA,gBAAE;AAAA,cAAA,EAAA,CAE3C;AAAA,YAAA;AAAA,UAAA;AAAA,UAMJ,gBAAAxc;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS4nB;AAAA,cACT,UAAU,CAAC1oB,EAAM,YAAY,CAACooB;AAAA,cAC9B,WAAU;AAAA,cAEV,UAAA;AAAA,gBAAA,gBAAArnB,EAACia,IAAA,EAAY,WAAU,eAAA,CAAe;AAAA,gBAAE;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAE1C,EAAA,CACF;AAAA,MAAA,GACF;AAAA,IAcmB;AAAA,EAAA;AAGvB;;;;ACvVA,QAAI6N,KAAY,WAAW;AAG3B,UAAI1nB,IAAI,OAAO,cACX2nB,IAAe,qEACfC,IAAgB,qEAChBC,IAAiB,CAAA;AAErB,eAASC,EAAaC,GAAUC,GAAW;AACzC,YAAI,CAACH,EAAeE,CAAQ,GAAG;AAC7B,UAAAF,EAAeE,CAAQ,IAAI,CAAA;AAC3B,mBAAS3R,IAAE,GAAIA,IAAE2R,EAAS,QAAS3R;AACjC,YAAAyR,EAAeE,CAAQ,EAAEA,EAAS,OAAO3R,CAAC,CAAC,IAAIA;AAAA,QAErD;AACE,eAAOyR,EAAeE,CAAQ,EAAEC,CAAS;AAAA,MAC3C;AAEA,UAAIN,IAAW;AAAA,QACb,kBAAmB,SAAUO,GAAO;AAClC,cAAIA,KAAS,KAAM,QAAO;AAC1B,cAAIC,IAAMR,EAAS,UAAUO,GAAO,GAAG,SAASvZ,GAAE;AAAC,mBAAOiZ,EAAa,OAAOjZ,CAAC;AAAA,UAAE,CAAC;AAClF,kBAAQwZ,EAAI,SAAS,GAAC;AAAA;AAAA,YACtB;AAAA;AAAA,YACA,KAAK;AAAI,qBAAOA;AAAA,YAChB,KAAK;AAAI,qBAAOA,IAAI;AAAA,YACpB,KAAK;AAAI,qBAAOA,IAAI;AAAA,YACpB,KAAK;AAAI,qBAAOA,IAAI;AAAA,UACxB;AAAA,QACA;AAAA,QAEE,sBAAuB,SAAUD,GAAO;AACtC,iBAAIA,KAAS,OAAa,KACtBA,KAAS,KAAW,OACjBP,EAAS,YAAYO,EAAM,QAAQ,IAAI,SAASvd,GAAO;AAAE,mBAAOod,EAAaH,GAAcM,EAAM,OAAOvd,CAAK,CAAC;AAAA,WAAI;AAAA,QAC7H;AAAA,QAEE,iBAAkB,SAAUud,GAAO;AACjC,iBAAIA,KAAS,OAAa,KACnBP,EAAS,UAAUO,GAAO,IAAI,SAASvZ,GAAE;AAAC,mBAAO1O,EAAE0O,IAAE,EAAE;AAAA,UAAE,CAAC,IAAI;AAAA,QACzE;AAAA,QAEE,qBAAqB,SAAUyZ,GAAY;AACzC,iBAAIA,KAAc,OAAa,KAC3BA,KAAc,KAAW,OACtBT,EAAS,YAAYS,EAAW,QAAQ,OAAO,SAASzd,GAAO;AAAE,mBAAOyd,EAAW,WAAWzd,CAAK,IAAI;AAAA,UAAG,CAAE;AAAA,QACvH;AAAA;AAAA,QAGE,sBAAsB,SAAU0d,GAAc;AAI5C,mBAHID,IAAaT,EAAS,SAASU,CAAY,GAC3CC,IAAI,IAAI,WAAWF,EAAW,SAAO,CAAC,GAEjC/R,IAAE,GAAGkS,IAASH,EAAW,QAAQ/R,IAAEkS,GAAUlS,KAAK;AACzD,gBAAImS,IAAgBJ,EAAW,WAAW/R,CAAC;AAC3C,YAAAiS,EAAIjS,IAAE,CAAC,IAAImS,MAAkB,GAC7BF,EAAIjS,IAAE,IAAE,CAAC,IAAImS,IAAgB;AAAA,UACnC;AACI,iBAAOF;AAAA,QACX;AAAA;AAAA,QAGE,0BAAyB,SAAUF,GAAY;AAC7C,cAAIA,KAAa;AACb,mBAAOT,EAAS,WAAWS,CAAU;AAGrC,mBADIE,IAAI,IAAI,MAAMF,EAAW,SAAO,CAAC,GAC5B/R,IAAE,GAAGkS,IAASD,EAAI,QAAQjS,IAAEkS,GAAUlS;AAC7C,YAAAiS,EAAIjS,CAAC,IAAE+R,EAAW/R,IAAE,CAAC,IAAE,MAAI+R,EAAW/R,IAAE,IAAE,CAAC;AAG7C,cAAIjX,IAAS,CAAA;AACb,iBAAAkpB,EAAI,QAAQ,SAAU7d,GAAG;AACvB,YAAArL,EAAO,KAAKa,EAAEwK,CAAC,CAAC;AAAA,UAC1B,CAAS,GACMkd,EAAS,WAAWvoB,EAAO,KAAK,EAAE,CAAC;AAAA,QAIlD;AAAA;AAAA,QAIE,+BAA+B,SAAU8oB,GAAO;AAC9C,iBAAIA,KAAS,OAAa,KACnBP,EAAS,UAAUO,GAAO,GAAG,SAASvZ,GAAE;AAAC,mBAAOkZ,EAAc,OAAOlZ,CAAC;AAAA,UAAE,CAAC;AAAA,QACpF;AAAA;AAAA,QAGE,mCAAkC,SAAUuZ,GAAO;AACjD,iBAAIA,KAAS,OAAa,KACtBA,KAAS,KAAW,QACxBA,IAAQA,EAAM,QAAQ,MAAM,GAAG,GACxBP,EAAS,YAAYO,EAAM,QAAQ,IAAI,SAASvd,GAAO;AAAE,mBAAOod,EAAaF,GAAeK,EAAM,OAAOvd,CAAK,CAAC;AAAA,WAAI;AAAA,QAC9H;AAAA,QAEE,UAAU,SAAU0d,GAAc;AAChC,iBAAOV,EAAS,UAAUU,GAAc,IAAI,SAAS1Z,GAAE;AAAC,mBAAO1O,EAAE0O,CAAC;AAAA,UAAE,CAAC;AAAA,QACzE;AAAA,QACE,WAAW,SAAU0Z,GAAcI,GAAaC,GAAgB;AAC9D,cAAIL,KAAgB,KAAM,QAAO;AACjC,cAAIhS,GAAGnJ,GACHyb,IAAoB,CAAA,GACpBC,IAA4B,CAAA,GAC5BC,IAAU,IACVC,IAAW,IACXC,IAAU,IACVC,IAAmB,GACnBC,IAAkB,GAClBC,IAAiB,GACjBC,IAAa,CAAA,GACbC,IAAiB,GACjBC,IAAsB,GACtBC;AAEJ,eAAKA,IAAK,GAAGA,IAAKjB,EAAa,QAAQiB,KAAM;AAQ3C,gBAPAT,IAAYR,EAAa,OAAOiB,CAAE,GAC7B,OAAO,UAAU,eAAe,KAAKX,GAAmBE,CAAS,MACpEF,EAAmBE,CAAS,IAAII,KAChCL,EAA2BC,CAAS,IAAI,KAG1CC,IAAaC,IAAYF,GACrB,OAAO,UAAU,eAAe,KAAKF,GAAmBG,CAAU;AACpE,cAAAC,IAAYD;AAAA,iBACP;AACL,kBAAI,OAAO,UAAU,eAAe,KAAKF,GAA2BG,CAAS,GAAG;AAC9E,oBAAIA,EAAU,WAAW,CAAC,IAAE,KAAK;AAC/B,uBAAK1S,IAAE,GAAIA,IAAE6S,GAAkB7S;AAC7B,oBAAA+S,IAAoBA,KAAoB,GACpCC,KAAyBZ,IAAY,KACvCY,IAAwB,GACxBF,EAAa,KAAKT,EAAeU,CAAgB,CAAC,GAClDA,IAAmB,KAEnBC;AAIJ,uBADAnc,IAAQ6b,EAAU,WAAW,CAAC,GACzB1S,IAAE,GAAIA,IAAE,GAAIA;AACf,oBAAA+S,IAAoBA,KAAoB,IAAMlc,IAAM,GAChDmc,KAAyBZ,IAAY,KACvCY,IAAwB,GACxBF,EAAa,KAAKT,EAAeU,CAAgB,CAAC,GAClDA,IAAmB,KAEnBC,KAEFnc,IAAQA,KAAS;AAAA,gBAE/B,OAAiB;AAEL,uBADAA,IAAQ,GACHmJ,IAAE,GAAIA,IAAE6S,GAAkB7S;AAC7B,oBAAA+S,IAAoBA,KAAoB,IAAKlc,GACzCmc,KAAwBZ,IAAY,KACtCY,IAAwB,GACxBF,EAAa,KAAKT,EAAeU,CAAgB,CAAC,GAClDA,IAAmB,KAEnBC,KAEFnc,IAAQ;AAGV,uBADAA,IAAQ6b,EAAU,WAAW,CAAC,GACzB1S,IAAE,GAAIA,IAAE,IAAKA;AAChB,oBAAA+S,IAAoBA,KAAoB,IAAMlc,IAAM,GAChDmc,KAAyBZ,IAAY,KACvCY,IAAwB,GACxBF,EAAa,KAAKT,EAAeU,CAAgB,CAAC,GAClDA,IAAmB,KAEnBC,KAEFnc,IAAQA,KAAS;AAAA,gBAE/B;AACU,gBAAA8b,KACIA,KAAqB,MACvBA,IAAoB,KAAK,IAAI,GAAGE,CAAe,GAC/CA,MAEF,OAAON,EAA2BG,CAAS;AAAA,cACrD;AAEU,qBADA7b,IAAQyb,EAAmBI,CAAS,GAC/B1S,IAAE,GAAIA,IAAE6S,GAAkB7S;AAC7B,kBAAA+S,IAAoBA,KAAoB,IAAMlc,IAAM,GAChDmc,KAAyBZ,IAAY,KACvCY,IAAwB,GACxBF,EAAa,KAAKT,EAAeU,CAAgB,CAAC,GAClDA,IAAmB,KAEnBC,KAEFnc,IAAQA,KAAS;AAKrB,cAAA8b,KACIA,KAAqB,MACvBA,IAAoB,KAAK,IAAI,GAAGE,CAAe,GAC/CA,MAGFP,EAAmBG,CAAU,IAAIG,KACjCF,IAAY,OAAOF,CAAS;AAAA,YACpC;AAII,cAAIE,MAAc,IAAI;AACpB,gBAAI,OAAO,UAAU,eAAe,KAAKH,GAA2BG,CAAS,GAAG;AAC9E,kBAAIA,EAAU,WAAW,CAAC,IAAE,KAAK;AAC/B,qBAAK1S,IAAE,GAAIA,IAAE6S,GAAkB7S;AAC7B,kBAAA+S,IAAoBA,KAAoB,GACpCC,KAAyBZ,IAAY,KACvCY,IAAwB,GACxBF,EAAa,KAAKT,EAAeU,CAAgB,CAAC,GAClDA,IAAmB,KAEnBC;AAIJ,qBADAnc,IAAQ6b,EAAU,WAAW,CAAC,GACzB1S,IAAE,GAAIA,IAAE,GAAIA;AACf,kBAAA+S,IAAoBA,KAAoB,IAAMlc,IAAM,GAChDmc,KAAyBZ,IAAY,KACvCY,IAAwB,GACxBF,EAAa,KAAKT,EAAeU,CAAgB,CAAC,GAClDA,IAAmB,KAEnBC,KAEFnc,IAAQA,KAAS;AAAA,cAE7B,OAAe;AAEL,qBADAA,IAAQ,GACHmJ,IAAE,GAAIA,IAAE6S,GAAkB7S;AAC7B,kBAAA+S,IAAoBA,KAAoB,IAAKlc,GACzCmc,KAAyBZ,IAAY,KACvCY,IAAwB,GACxBF,EAAa,KAAKT,EAAeU,CAAgB,CAAC,GAClDA,IAAmB,KAEnBC,KAEFnc,IAAQ;AAGV,qBADAA,IAAQ6b,EAAU,WAAW,CAAC,GACzB1S,IAAE,GAAIA,IAAE,IAAKA;AAChB,kBAAA+S,IAAoBA,KAAoB,IAAMlc,IAAM,GAChDmc,KAAyBZ,IAAY,KACvCY,IAAwB,GACxBF,EAAa,KAAKT,EAAeU,CAAgB,CAAC,GAClDA,IAAmB,KAEnBC,KAEFnc,IAAQA,KAAS;AAAA,cAE7B;AACQ,cAAA8b,KACIA,KAAqB,MACvBA,IAAoB,KAAK,IAAI,GAAGE,CAAe,GAC/CA,MAEF,OAAON,EAA2BG,CAAS;AAAA,YACnD;AAEQ,mBADA7b,IAAQyb,EAAmBI,CAAS,GAC/B1S,IAAE,GAAIA,IAAE6S,GAAkB7S;AAC7B,gBAAA+S,IAAoBA,KAAoB,IAAMlc,IAAM,GAChDmc,KAAyBZ,IAAY,KACvCY,IAAwB,GACxBF,EAAa,KAAKT,EAAeU,CAAgB,CAAC,GAClDA,IAAmB,KAEnBC,KAEFnc,IAAQA,KAAS;AAKrB,YAAA8b,KACIA,KAAqB,MACvBA,IAAoB,KAAK,IAAI,GAAGE,CAAe,GAC/CA;AAAA,UAER;AAII,eADAhc,IAAQ,GACHmJ,IAAE,GAAIA,IAAE6S,GAAkB7S;AAC7B,YAAA+S,IAAoBA,KAAoB,IAAMlc,IAAM,GAChDmc,KAAyBZ,IAAY,KACvCY,IAAwB,GACxBF,EAAa,KAAKT,EAAeU,CAAgB,CAAC,GAClDA,IAAmB,KAEnBC,KAEFnc,IAAQA,KAAS;AAInB;AAEE,gBADAkc,IAAoBA,KAAoB,GACpCC,KAAyBZ,IAAY,GAAG;AAC1C,cAAAU,EAAa,KAAKT,EAAeU,CAAgB,CAAC;AAClD;AAAA,YACR,MACW,CAAAC;AAEP,iBAAOF,EAAa,KAAK,EAAE;AAAA,QAC/B;AAAA,QAEE,YAAY,SAAUf,GAAY;AAChC,iBAAIA,KAAc,OAAa,KAC3BA,KAAc,KAAW,OACtBT,EAAS,YAAYS,EAAW,QAAQ,OAAO,SAASzd,GAAO;AAAE,mBAAOyd,EAAW,WAAWzd,CAAK;AAAA,UAAE,CAAE;AAAA,QAClH;AAAA,QAEE,aAAa,SAAU4e,GAAQC,GAAYC,GAAc;AACvD,cAAIC,IAAa,CAAA,GAEbC,IAAY,GACZC,IAAW,GACXC,IAAU,GACVrsB,IAAQ,IACR4B,IAAS,CAAA,GACTiX,GACAkE,GACAuP,GAAMC,GAAMC,GAAUC,GACtBxf,GACAnG,IAAO,EAAC,KAAImlB,EAAa,CAAC,GAAG,UAASD,GAAY,OAAM,EAAC;AAE7D,eAAKnT,IAAI,GAAGA,IAAI,GAAGA,KAAK;AACtB,YAAAqT,EAAWrT,CAAC,IAAIA;AAMlB,eAHAyT,IAAO,GACPE,IAAW,KAAK,IAAI,GAAE,CAAC,GACvBC,IAAM,GACCA,KAAOD;AACZ,YAAAD,IAAOzlB,EAAK,MAAMA,EAAK,UACvBA,EAAK,aAAa,GACdA,EAAK,YAAY,MACnBA,EAAK,WAAWklB,GAChBllB,EAAK,MAAMmlB,EAAanlB,EAAK,OAAO,IAEtCwlB,MAASC,IAAK,IAAI,IAAI,KAAKE,GAC3BA,MAAU;AAGZ,kBAAeH,GAAI;AAAA,YACjB,KAAK;AAID,mBAHAA,IAAO,GACPE,IAAW,KAAK,IAAI,GAAE,CAAC,GACvBC,IAAM,GACCA,KAAOD;AACZ,gBAAAD,IAAOzlB,EAAK,MAAMA,EAAK,UACvBA,EAAK,aAAa,GACdA,EAAK,YAAY,MACnBA,EAAK,WAAWklB,GAChBllB,EAAK,MAAMmlB,EAAanlB,EAAK,OAAO,IAEtCwlB,MAASC,IAAK,IAAI,IAAI,KAAKE,GAC3BA,MAAU;AAEd,cAAAxf,IAAIxK,EAAE6pB,CAAI;AACV;AAAA,YACF,KAAK;AAID,mBAHAA,IAAO,GACPE,IAAW,KAAK,IAAI,GAAE,EAAE,GACxBC,IAAM,GACCA,KAAOD;AACZ,gBAAAD,IAAOzlB,EAAK,MAAMA,EAAK,UACvBA,EAAK,aAAa,GACdA,EAAK,YAAY,MACnBA,EAAK,WAAWklB,GAChBllB,EAAK,MAAMmlB,EAAanlB,EAAK,OAAO,IAEtCwlB,MAASC,IAAK,IAAI,IAAI,KAAKE,GAC3BA,MAAU;AAEd,cAAAxf,IAAIxK,EAAE6pB,CAAI;AACV;AAAA,YACF,KAAK;AACH,qBAAO;AAAA,UACf;AAII,eAHAJ,EAAW,CAAC,IAAIjf,GAChB8P,IAAI9P,GACJrL,EAAO,KAAKqL,CAAC,OACA;AACX,gBAAInG,EAAK,QAAQilB;AACf,qBAAO;AAMT,iBAHAO,IAAO,GACPE,IAAW,KAAK,IAAI,GAAEH,CAAO,GAC7BI,IAAM,GACCA,KAAOD;AACZ,cAAAD,IAAOzlB,EAAK,MAAMA,EAAK,UACvBA,EAAK,aAAa,GACdA,EAAK,YAAY,MACnBA,EAAK,WAAWklB,GAChBllB,EAAK,MAAMmlB,EAAanlB,EAAK,OAAO,IAEtCwlB,MAASC,IAAK,IAAI,IAAI,KAAKE,GAC3BA,MAAU;AAGZ,oBAAQxf,IAAIqf,GAAI;AAAA,cACd,KAAK;AAIH,qBAHAA,IAAO,GACPE,IAAW,KAAK,IAAI,GAAE,CAAC,GACvBC,IAAM,GACCA,KAAOD;AACZ,kBAAAD,IAAOzlB,EAAK,MAAMA,EAAK,UACvBA,EAAK,aAAa,GACdA,EAAK,YAAY,MACnBA,EAAK,WAAWklB,GAChBllB,EAAK,MAAMmlB,EAAanlB,EAAK,OAAO,IAEtCwlB,MAASC,IAAK,IAAI,IAAI,KAAKE,GAC3BA,MAAU;AAGZ,gBAAAP,EAAWE,GAAU,IAAI3pB,EAAE6pB,CAAI,GAC/Brf,IAAImf,IAAS,GACbD;AACA;AAAA,cACF,KAAK;AAIH,qBAHAG,IAAO,GACPE,IAAW,KAAK,IAAI,GAAE,EAAE,GACxBC,IAAM,GACCA,KAAOD;AACZ,kBAAAD,IAAOzlB,EAAK,MAAMA,EAAK,UACvBA,EAAK,aAAa,GACdA,EAAK,YAAY,MACnBA,EAAK,WAAWklB,GAChBllB,EAAK,MAAMmlB,EAAanlB,EAAK,OAAO,IAEtCwlB,MAASC,IAAK,IAAI,IAAI,KAAKE,GAC3BA,MAAU;AAEZ,gBAAAP,EAAWE,GAAU,IAAI3pB,EAAE6pB,CAAI,GAC/Brf,IAAImf,IAAS,GACbD;AACA;AAAA,cACF,KAAK;AACH,uBAAOvqB,EAAO,KAAK,EAAE;AAAA,YAC/B;AAOM,gBALIuqB,KAAa,MACfA,IAAY,KAAK,IAAI,GAAGE,CAAO,GAC/BA,MAGEH,EAAWjf,CAAC;AACd,cAAAjN,IAAQksB,EAAWjf,CAAC;AAAA,qBAEhBA,MAAMmf;AACR,cAAApsB,IAAQ+c,IAAIA,EAAE,OAAO,CAAC;AAAA;AAEtB,qBAAO;AAGX,YAAAnb,EAAO,KAAK5B,CAAK,GAGjBksB,EAAWE,GAAU,IAAIrP,IAAI/c,EAAM,OAAO,CAAC,GAC3CmsB,KAEApP,IAAI/c,GAEAmsB,KAAa,MACfA,IAAY,KAAK,IAAI,GAAGE,CAAO,GAC/BA;AAAA,UAGR;AAAA,QACA;AAAA;AAEE,aAAOlC;AAAA,IACT,GAAC;AAIM,IAAqCuC,KAAU,OACpDA,EAAA,UAAiBvC,IACR,OAAO,UAAY,OAAe,WAAW,QACtD,QAAQ,OAAO,YAAY,CAAA,CAAE,EAC5B,QAAQ,YAAY,WAAY;AAC/B,aAAOA;AAAA,IACX,CAAG;AAAA;;;ACzdH,MAAMwC,KAAkB,MAClBC,KAAe;AAKd,SAASC,GAAkBvrB,GAA+B;AAC/D,QAAMwrB,IAAO,KAAK,UAAUxrB,CAAK;AACjC,SAAOyrB,GAAAA,8BAA8BD,CAAI;AAC3C;AAMO,SAASE,GAAoBC,GAAwC;AAC1E,MAAI;AACF,UAAMH,IAAOI,GAAAA,kCAAkCD,CAAO;AACtD,QAAI,CAACH,EAAM,QAAO;AAElB,UAAMxrB,IAAQ,KAAK,MAAMwrB,CAAI;AAG7B,WAAI,CAACxrB,EAAM,SAAS,OAAOA,EAAM,SAAU,WAClC,OAGFA;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAmBO,SAAS6rB,GAAqB7rB,GAA0C;AAE7E,QAAM8rB,IAAcP,GAAkBvrB,CAAK;AAC3C,MAAI8rB,EAAY,UAAUT;AACxB,WAAO,EAAE,SAASS,GAAa,WAAW,GAAA;AAI5C,QAAMC,IAAiC,EAAE,OAAO/rB,EAAM,MAAA,GAChDgsB,IAAmBT,GAAkBQ,CAAc;AAEzD,SAAIC,EAAiB,UAAUX,KACtB,EAAE,SAASW,GAAkB,WAAW,GAAA,IAI1C,EAAE,SAAS,MAAM,WAAW,GAAA;AACrC;AAgBO,SAASC,KAAgC;AAC9C,MAAI,OAAO,SAAW,IAAa,QAAO;AAE1C,QAAMC,IAAO,OAAO,SAAS;AAC7B,SAAI,CAACA,KAAQ,CAACA,EAAK,WAAW,IAAIZ,EAAY,EAAE,IACvC,OAGFY,EAAK,MAAMZ,GAAa,SAAS,CAAC;AAC3C;AAKO,SAASa,KAAuB;AACrC,MAAI,OAAO,SAAW,IAAa;AAEnC,QAAMC,IAAM,IAAI,IAAI,OAAO,SAAS,IAAI;AACxC,EAAAA,EAAI,OAAO,IACX,OAAO,QAAQ,aAAa,MAAM,IAAIA,EAAI,UAAU;AACtD;AAKO,SAASC,KAA2B;AACzC,SAAOhB;AACT;AC3HA,MAAMiB,KAAsD,CAAC;AAAA,EAC3D,QAAArmB;AAAA,EACA,SAAAC;AAAA,EACA,MAAAE;AAAA,EACA,SAAAmmB;AACF,MAAM;AACJ,QAAMC,IAAc,KAAK,IAAI,KAAK,MAAOpmB,IAAOmmB,IAAW,GAAG,GAAG,GAAG,GAE9DpkB,IAAc3H,EAAQ,SAAS;AAErC,SACE,gBAAAO;AAAA,IAACiF;AAAA,IAAA;AAAA,MACC,QAAAC;AAAA,MACA,SAAAC;AAAA,MACA,OAAM;AAAA,MACN,MAAK;AAAA,MAEL,UAAA,gBAAApF,EAAC,OAAA,EAAI,WAAU,aAEb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,SAAI,WAAU,+DACb,4BAACoH,GAAA,EAAY,WAAU,8CAA6C,EAAA,CACtE;AAAA,UACA,gBAAApH,EAAC,OAAA,EAAI,WAAU,kCAAiC,UAAA,iJAAA,CAGhD;AAAA,QAAA,GACF;AAAA,QAGA,gBAAAD,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,mDACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,UAAK,UAAA,kBAAA,CAAe;AAAA,YACrB,gBAAAD,EAAC,QAAA,EAAK,WAAU,8CACb,UAAA;AAAA,cAAAsF,EAAK,eAAA;AAAA,cAAiB;AAAA,cAAImmB,EAAQ,eAAA;AAAA,cAAiB;AAAA,YAAA,EAAA,CACtD;AAAA,UAAA,GACF;AAAA,UACA,gBAAAxrB,EAAC,OAAA,EAAI,WAAU,4DACb,UAAA,gBAAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,GAAGyrB,CAAW,IAAA;AAAA,YAAI;AAAA,UAAA,EACpC,CACF;AAAA,QAAA,GACF;AAAA,QAGA,gBAAA1rB,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,KAAA,EAAE,WAAU,yCAAwC,UAAA,sCAErD;AAAA,UACA,gBAAAD,EAAC,MAAA,EAAG,WAAU,8CACZ,UAAA;AAAA,YAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,0BACZ,UAAA;AAAA,cAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA,KAAC;AAAA,cACtC,gBAAAA,EAAC,UAAK,UAAA,+DAAA,CAA4D;AAAA,YAAA,GACpE;AAAA,YACA,gBAAAD,EAAC,MAAA,EAAG,WAAU,0BACZ,UAAA;AAAA,cAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA,KAAC;AAAA,cACtC,gBAAAA,EAAC,UAAK,UAAA,8CAAA,CAA2C;AAAA,YAAA,GACnD;AAAA,YACA,gBAAAD,EAAC,MAAA,EAAG,WAAU,0BACZ,UAAA;AAAA,cAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA,KAAC;AAAA,cACtC,gBAAAA,EAAC,UAAK,UAAA,8BAAA,CAA2B;AAAA,YAAA,GACnC;AAAA,YACA,gBAAAD,EAAC,MAAA,EAAG,WAAU,0BACZ,UAAA;AAAA,cAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA,KAAC;AAAA,cACtC,gBAAAA,EAAC,UAAK,UAAA,2DAAA,CAAkE;AAAA,YAAA,EAAA,CAC1E;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,GACF;AAAA,QAGA,gBAAAA,EAAC,OAAA,EAAI,WAAU,yBACb,UAAA,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAASmF;AAAA,YACT,WAAU;AAAA,YACX,UAAA;AAAA,UAAA;AAAA,QAAA,EAED,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN,GCvEMumB,KAAc,oCACdC,KAAyB,2BAEzBC,KAAezpB,GAA+C,CAAC;AAAA,EACnE,WAAA8D,IAAY;AAAA,EACZ,cAAA4lB;AAAA,EACA,qBAAAC,IAAsB;AAAA,EACtB,cAAAC,IAAe;AAAA,EACf,eAAAC,IAAgB;AAAA,EAChB,SAAAC;AACF,GAAGptB,MAAQ;AAET,QAAM,EAAE,SAAAqtB,GAAS,iBAAAC,GAAiB,UAAAxkB,EAAA,IAAaC,GAAA,GAGzCwkB,IAAsB,MAAiB;AAC3C,QAAI,CAACN;AACH,UAAI;AACF,cAAM5E,IAAQ,aAAa,QAAQyE,EAAsB;AACzD,YAAIzE;AACF,iBAAO,KAAK,MAAMA,CAAK;AAAA,MAE3B,QAAgB;AAAA,MAEhB;AAEF,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,UAAU;AAAA,IAAA;AAAA,EAEd,GAGMmF,IAAkB,MAAyB;AAE/C,QAAIR;AACF,aAAO;AAAA,QACL,OAAOhb,GAAoBgb,CAAY;AAAA,QACvC,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,aAAa;AAAA,QACb,kBAAkB;AAAA,QAClB,iBAAiB;AAAA,QACjB,eAAe;AAAA,QACf,iBAAiB;AAAA,QACjB,kBAAkB;AAAA,QAClB,gBAAgB;AAAA,QAChB,eAAe;AAAA,QACf,qBAAqB;AAAA,MAAA;AAKzB,QAAI,CAACC;AACH,UAAI;AACF,cAAM5E,IAAQ,aAAa,QAAQwE,EAAW;AAC9C,YAAIxE,GAAO;AACT,gBAAMoF,IAAc,KAAK,MAAMpF,CAAK;AACpC,iBAAO;AAAA,YACL,OAAOrW,GAAoByb,EAAY,KAAK,KAAK/d,GAAA;AAAA,YACjD,QAAQ;AAAA;AAAA,YACR,cAAc;AAAA;AAAA,YACd,aAAa;AAAA,YACb,kBAAkB;AAAA;AAAA,YAClB,iBAAiB;AAAA,YACjB,eAAe;AAAA,YACf,iBAAiB;AAAA;AAAA,YACjB,kBAAkB;AAAA,YAClB,gBAAgB;AAAA,YAChB,eAAe;AAAA,YACf,qBAAqB;AAAA,UAAA;AAAA,QAEzB;AAAA,MACF,QAAgB;AAAA,MAEhB;AAGF,WAAO;AAAA,MACL,OAAOA,GAAA;AAAA,MACP,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,aAAa;AAAA,MACb,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,qBAAqB;AAAA,IAAA;AAAA,EAEzB,GAEM,CAACtP,GAAOC,CAAQ,IAAI+D,EAA4BopB,GAAiB,GAGjE,CAAC/H,GAAciI,CAAe,IAAItpB,EAAiB,EAAE,GA6BrDupB,KA1BuB,MAAM;AACjC,QAAI,CAACV;AACH,UAAI;AACF,cAAM5E,IAAQ,aAAa,QAAQwE,EAAW;AAC9C,YAAIxE,GAAO;AACT,gBAAMpjB,IAAS,KAAK,MAAMojB,CAAK;AAC/B,iBAAO;AAAA,YACL,WAAWpjB,EAAO,aAAa;AAAA,YAC/B,aAAaA,EAAO,eAAe,CAAA;AAAA,YACnC,eAAeA,EAAO,iBAAiB,EAAE,YAAY,IAAM,UAAU,IAAM,aAAa,GAAA;AAAA,YACxF,YAAYA,EAAO,cAAc;AAAA,UAAA;AAAA,QAErC;AAAA,MACF,QAAgB;AAAA,MAEhB;AAEF,WAAO;AAAA,MACL,WAAW;AAAA,MACX,aAAa,CAAA;AAAA,MACb,eAAe,EAAE,YAAY,IAAM,UAAU,IAAM,aAAa,GAAA;AAAA,MAChE,YAAY;AAAA,IAAA;AAAA,EAEhB,GAG0B,GACpB,CAAC1B,GAAWqqB,CAAY,IAAIxpB,EAAoBupB,EAAkB,SAAS,GAC3E,CAACnqB,GAAaqqB,CAAc,IAAIzpB,EAA0BupB,EAAkB,WAAW,GACvF,CAAClqB,GAAeqqB,CAAgB,IAAI1pB,EAA6BupB,EAAkB,aAAa,GAChG,CAACvH,GAAYC,CAAa,IAAIjiB,EAA4BupB,EAAkB,UAAU,GAGtF,CAACI,GAAWC,CAAY,IAAI5pB,EAAoBmpB,GAAqB,GACrE,CAACU,GAAgBC,CAAiB,IAAI9pB,EAAS,EAAK,GACpD,CAAC+pB,GAAkBC,CAAmB,IAAIhqB,EAAS,EAAK,GACxD,CAACiqB,GAAgBC,CAAiB,IAAIlqB,EAA6B,MAAM,GAGzE,CAACmqB,GAAiBC,EAAkB,IAAIpqB,EAAS,EAAK,GAGtD,CAAC0Y,IAAkB2R,EAAmB,IAAIrqB,EAA2B,MAAM,GAC3E,CAACsqB,IAAkBC,EAAmB,IAAIvqB,EAAS,EAAK,GACxD,CAACwqB,IAAkBC,EAAmB,IAAIzqB,EAAS,EAAE,MAAM,GAAG,SAAS,GAAG,GAC1E,CAAC2Y,GAAiB+R,CAAkB,IAAI1qB,EAAS,EAAK;AAG5D,EAAAO,GAAU,MAAM;AACd,IAAIqoB,KAAgB,KAAK,UAAUA,CAAY,MAAM,KAAK,UAAU5sB,EAAM,KAAK,KAC7EC,EAAS,CAAAsF,OAAS;AAAA,MAChB,GAAGA;AAAA,MACH,OAAOqM,GAAoBgb,CAAY;AAAA,MACvC,cAAc;AAAA,MACd,aAAa;AAAA,MACb,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,qBAAqB;AAAA,IAAA,EACrB;AAAA,EAEN,GAAG,CAACA,CAAY,CAAC;AAGjB,QAAM+B,KAAwBzqB,GAAe,EAAE,GAMzC,CAAC0qB,IAAsBC,CAAuB,IAAI7qB,EAAkC,IAAI,GAGxFif,IAAkBre,GAAQ,MACzBgqB,IAAsB,YAAY,QAChC;AAAA,IACL,YAAYA,GAAqB,WAAW,MAAM,cAAc,CAAA;AAAA,IAChE,gBAAgBA,GAAqB,WAAW,MAAM,gBAAgB,IAAI,CAACtsB,MAA8BA,EAAG,SAAS,KAAK,CAAA;AAAA,IAC1H,UAAUssB,GAAqB,WAAW,MAAM,YAAY,CAAA;AAAA,EAAC,IAJV,MAMpD,CAACA,EAAoB,CAAC;AAGzB,EAAAtpB,GAAoB1F,GAAK,OAAO;AAAA,IAC9B,iBAAiB,MAAMwP,GAAoBpP,EAAM,KAAK;AAAA,IACtD,oBAAoB,OAAO;AAAA,MACzB,QAAQA,EAAM;AAAA,MACd,QAAQA,EAAM,qBAAqB,UAAU;AAAA,QAC3C,OAAO;AAAA,QACP,KAAKA,EAAM,iBAAiB;AAAA,MAAA,IAC1BA,EAAM,qBAAqB,YAAY;AAAA,QACzC,OAAO;AAAA,QACP,OAAOA,EAAM,mBAAmB;AAAA,MAAA,IAC9B;AAAA,IAAA;AAAA,IAEN,qBAAqB,MAAM4uB;AAAA,EAAA,IACzB,CAAC5uB,EAAM,OAAOA,EAAM,kBAAkBA,EAAM,iBAAiBA,EAAM,eAAe4uB,EAAoB,CAAC,GAG3GrqB,GAAU,MAAM;AA4Bd,KA3BmB,YAAY;AAC7B,MAAAtE,EAAS,CAAAsF,OAAS;AAAA,QAChB,GAAGA;AAAA,QACH,cAAc;AAAA,QACd,aAAa;AAAA,MAAA,EACb;AAEF,UAAI;AACF,cAAMupB,IAA6B,MAAM7B,EAAQ,KAAA;AACjD,QAAAhtB,EAAS,CAAAsF,OAAS;AAAA,UAChB,GAAGA;AAAA,UACH,QAAQupB;AAAA,UACR,cAAc;AAAA,UACd,aAAa;AAAA,QAAA,EACb;AAAA,MACJ,SAASluB,GAAO;AAEd,cAAMinB,IAAejnB,aAAiB,QAAQA,EAAM,UAAU;AAC9D,QAAAX,EAAS,CAAAsF,OAAS;AAAA,UAChB,GAAGA;AAAA,UACH,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,aAAasiB;AAAA,QAAA,EACb;AAAA,MACJ;AAAA,IACF,GAEA;AAAA,EACF,GAAG,CAAC8F,EAAU,YAAYA,EAAU,QAAQ,CAAC,GAG7CppB,GAAU,MAAM;AACd,QAAI,CAACsoB;AACH,UAAI;AACF,qBAAa,QAAQJ,IAAa,KAAK,UAAU;AAAA,UAC/C,OAAOzsB,EAAM;AAAA,UACb,WAAAmD;AAAA,UACA,aAAAC;AAAA,UACA,eAAAC;AAAA,UACA,YAAA2iB;AAAA,QAAA,CACD,CAAC;AAAA,MACJ,QAAgB;AAAA,MAEhB;AAAA,EAEJ,GAAG,CAAChmB,EAAM,OAAOmD,GAAWC,GAAaC,GAAe2iB,GAAY6G,CAAmB,CAAC,GAGxFtoB,GAAU,MAAM;AACd,QAAI,CAACsoB;AACH,UAAI;AACF,qBAAa,QAAQH,IAAwB,KAAK,UAAUiB,CAAS,CAAC;AAAA,MACxE,QAAgB;AAAA,MAEhB;AAAA,EAEJ,GAAG,CAACA,GAAWd,CAAmB,CAAC;AAGnC,QAAMkC,IAAyB7qB,GAAO,EAAK;AAG3C,EAAAK,GAAU,MAAM;AACd,QAAI,CAACwoB,EAAe;AAEpB,UAAMpB,IAAUM,GAAA;AAChB,QAAI,CAACN,EAAS;AAEd,UAAMqD,IAAUtD,GAAoBC,CAAO;AAC3C,IAAIqD,MAEF/uB,EAAS,CAAAsF,OAAS;AAAA,MAChB,GAAGA;AAAA,MACH,OAAOqM,GAAoBod,EAAQ,KAAK;AAAA,MACxC,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,qBAAqB;AAAA,IAAA,EACrB,GAGEA,EAAQ,aAAWxB,EAAawB,EAAQ,SAAS,GACjDA,EAAQ,eAAavB,EAAeuB,EAAQ,WAAW,GACvDA,EAAQ,iBAAetB,EAAiBsB,EAAQ,aAAa,GAC7DA,EAAQ,cAAY/I,EAAc+I,EAAQ,UAAU,GAExDN,EAAmB,EAAI,GACvBK,EAAuB,UAAU,KAInC5C,GAAA;AAAA,EACF,GAAG,CAACY,CAAa,CAAC,GAGlBxoB,GAAU,MAAM;AACd,IAAIvE,EAAM,oBAAoB,aAAagP,GAAgBhP,EAAM,KAAK,KAAKA,EAAM,qBAAqB,WACpGivB,GAAA;AAAA,EAEJ,GAAG,CAAC5J,GAAcW,CAAU,CAAC;AAG7B,QAAMkJ,KAActoB,EAAY,CAACuoB,MAA8D;AAC7F,IAAAlvB,EAAS,CAAAsF,MAAQ;AACf,YAAM6pB,IAAWD,EAAQ5pB,EAAK,KAAK,GAG7B4J,IAAe;AAAA,QACnB,GAAGigB;AAAA,QACH,SAASA,EAAS,UAAUxe,GAAewe,EAAS,OAAiB,IAAI;AAAA,MAAA,GAGrEC,IAAe,KAAK,UAAUlgB,CAAY,MAAM,KAAK,UAAU5J,EAAK,KAAK;AAE/E,aAAO;AAAA,QACL,GAAGA;AAAA,QACH,OAAO4J;AAAA;AAAA,QAEP,kBAAkBkgB,IAAe,SAAS9pB,EAAK;AAAA,QAC/C,iBAAiB8pB,IAAe,OAAO9pB,EAAK;AAAA,QAC5C,eAAe8pB,IAAe,OAAO9pB,EAAK;AAAA,QAC1C,iBAAiB;AAAA,QACjB,kBAAkB;AAAA,QAClB,gBAAgB;AAAA,QAChB,eAAe;AAAA,QACf,qBAAqB;AAAA,MAAA;AAAA,IAEzB,CAAC;AAAA,EACH,GAAG,CAAA,CAAE,GAEC+pB,KAAoB1oB,EAAY,CAAC6E,GAAmBf,MAA4D;AACpH,IAAAwkB,GAAY,CAAA3pB,MAAQ;AAClB,YAAM6pB,IAAW,EAAE,GAAG7pB,EAAA;AAEtB,cAAQmF,GAAA;AAAA,QACN,KAAK;AAEH,WAAMnF,EAAK,YAAY,CAAA,GAAI,SAASkG,CAAS,MAC3C2jB,EAAS,WAAW,CAAC,GAAI7pB,EAAK,YAAY,CAAA,GAAKkG,CAAS;AAE1D;AAAA,QACF,KAAK;AAEH,WAAMlG,EAAK,cAAc,CAAA,GAAI,SAASkG,CAAS,MAC7C2jB,EAAS,aAAa,CAAC,GAAI7pB,EAAK,cAAc,CAAA,GAAKkG,CAAS;AAE9D;AAAA,QACF,KAAK;AAEH,WAAMlG,EAAK,kBAAkB,IAAI,KAAK,CAAAjD,MAAMA,EAAG,cAAcmJ,CAAS,MACpE2jB,EAAS,iBAAiB,CAAC,GAAI7pB,EAAK,kBAAkB,CAAA,GAAK;AAAA,YACzD,WAAWkG;AAAA,YACX,aAAa;AAAA,UAAA,CACd;AAEH;AAAA,MAAA;AAGJ,aAAOyD,GAAWkgB,CAAQ;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAACF,EAAW,CAAC,GAEVK,KAAsB3oB,EAAY,CAAC6E,GAAmBf,MAA4D;AACtH,IAAAwkB,GAAY,CAAA3pB,MAAQ;AAClB,YAAM6pB,IAAW,EAAE,GAAG7pB,EAAA;AAEtB,cAAQmF,GAAA;AAAA,QACN,KAAK;AACH,UAAA0kB,EAAS,YAAY7pB,EAAK,YAAY,IAAI,OAAO,CAAA8K,MAAKA,MAAM5E,CAAS;AACrE;AAAA,QACF,KAAK;AACH,UAAA2jB,EAAS,cAAc7pB,EAAK,cAAc,IAAI,OAAO,CAAAuE,MAAKA,MAAM2B,CAAS;AACzE;AAAA,QACF,KAAK;AACH,UAAA2jB,EAAS,kBAAkB7pB,EAAK,kBAAkB,CAAA,GAAI,OAAO,CAAAjD,MAAMA,EAAG,cAAcmJ,CAAS;AAC7F;AAAA,MAAA;AAIJ,UAAI2jB,EAAS,SAASA,EAAS,MAAM3jB,CAAS,GAAG;AAC/C,cAAM+jB,IAAW,EAAE,GAAGJ,EAAS,MAAA;AAC/B,eAAOI,EAAS/jB,CAAS,GACzB2jB,EAAS,QAAQ,OAAO,KAAKI,CAAQ,EAAE,SAAS,IAAIA,IAAW;AAAA,MACjE;AAEA,aAAOtgB,GAAWkgB,CAAQ;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAACF,EAAW,CAAC,GAEVO,KAAuC7oB,EAAY,CAAC8oB,GAAuB9Q,MAAwB;AACvG,IAAAsQ,GAAY,CAAA3pB,MAAQ;AAClB,YAAM6pB,IAAW;AAAA,QACf,GAAG7pB;AAAA,QACH,iBAAiBA,EAAK,kBAAkB,CAAA,GAAI;AAAA,UAAI,CAAAjD,MAC9CA,EAAG,cAAcotB,IACb,EAAE,GAAGptB,GAAI,aAAAsc,MACTtc;AAAA,QAAA;AAAA,MACN;AAEF,aAAO4M,GAAWkgB,CAAQ;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAACF,EAAW,CAAC,GAEVS,KAAsB/oB,EAAY,CAAClE,MAAsB;AAC7D,IAAAwsB,GAAY,CAAA3pB,MAAQ;AAClB,YAAM6pB,IAAW;AAAA,QACf,GAAG7pB;AAAA,QACH,SAAA7C;AAAA,MAAA;AAEF,aAAOwM,GAAWkgB,CAAQ;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAACF,EAAW,CAAC,GAEVha,KAAwBtO,EAAY,CAACqF,GAAuBjJ,MAAiC;AACjG,IAAAksB,GAAY,CAAA3pB,MAAQ;AAClB,YAAM6pB,IAAW;AAAA,QACf,GAAG7pB;AAAA,QACH,iBAAiBA,EAAK,kBAAkB,CAAA,GAAI;AAAA,UAAI,CAAAjD,MAC9CA,EAAG,cAAc2J,IACb,EAAE,GAAG3J,GAAI,WAAAU,MACTV;AAAA,QAAA;AAAA,MACN;AAEF,aAAO4M,GAAWkgB,CAAQ;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAACF,EAAW,CAAC,GAEVU,KAAwBhpB,EAAY,CAACqF,MAA0B;AACnE,IAAAijB,GAAY,CAAA3pB,MAAQ;AAClB,YAAM6pB,IAAW;AAAA,QACf,GAAG7pB;AAAA,QACH,iBAAiBA,EAAK,kBAAkB,CAAA,GAAI;AAAA,UAAI,CAAAjD,MAC9CA,EAAG,cAAc2J,IACb,EAAE,GAAG3J,GAAI,WAAW,WACpBA;AAAA,QAAA;AAAA,MACN;AAEF,aAAO4M,GAAWkgB,CAAQ;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAACF,EAAW,CAAC,GAEVW,IAAoBjpB,EAAY,CAAC6E,GAAmB0G,MAAqC;AAC7F,IAAA+c,GAAY,CAAA3pB,MAAQ;AAClB,YAAMiqB,IAAW,EAAE,GAAIjqB,EAAK,SAAS,CAAA,EAAC;AAEtC,MAAI4M,MAAc,OAChB,OAAOqd,EAAS/jB,CAAS,IAEzB+jB,EAAS/jB,CAAS,IAAI0G;AAGxB,YAAMid,IAAW;AAAA,QACf,GAAG7pB;AAAA,QACH,OAAO,OAAO,KAAKiqB,CAAQ,EAAE,SAAS,IAAIA,IAAW;AAAA,MAAA;AAGvD,aAAOtgB,GAAWkgB,CAAQ;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAACF,EAAW,CAAC,GAEVY,KAAsBlpB,EAAY,YAAY;AAClD,QAAI,CAACoI,GAAgBhP,EAAM,KAAK,EAAG;AAGnC,UAAM+vB,IAAkB3gB,GAAoBpP,EAAM,KAAK,GACjDgwB,IAAW,KAAK,UAAUD,CAAe;AAG/C,IAAA9vB,EAAS,CAAAsF,OAAS;AAAA,MAChB,GAAGA;AAAA,MACH,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,MACjB,eAAe;AAAA,IAAA,EACf;AAEF,QAAI;AACF,YAAMjF,IAA2B,MAAM2sB,EAAQ,OAAO8C,CAAe;AAGrE,MAAAlB,EAAwBvuB,CAAM;AAM9B,YAAM2vB,IAAU,CAAC3vB,EAAO,SAASA,EAAO,aAAcA,EAAO,UAAU;AAGvE,MAAI2vB,MACFtB,GAAsB,UAAUqB,IAGlC/vB,EAAS,CAAAsF,OACA;AAAA,QACL,GAAGA;AAAA,QACH,kBAAkB0qB,IAAU,UAAU;AAAA,QACtC,iBAAiB3vB,EAAO,SAAS;AAAA,QACjC,eAAeA,EAAO,OAAO;AAAA,MAAA,EAEhC;AAAA,IACH,SAASM,GAAO;AAEd,MAAAiuB,EAAwB,IAAI,GAC5B5uB,EAAS,CAAAsF,OAAS;AAAA,QAChB,GAAGA;AAAA,QACH,kBAAkB;AAAA,QAClB,iBAAiB3E,aAAiB,QAAQA,EAAM,UAAU;AAAA,QAC1D,eAAe;AAAA,MAAA,EACf;AAAA,IACJ;AAAA,EACF,GAAG,CAACZ,EAAM,OAAOitB,CAAO,CAAC;AAGzB,EAAA1oB,GAAU,MAAM;AAEd,QAAI,CAACyK,GAAgBhP,EAAM,KAAK,KAAKA,EAAM,qBAAqB;AAC9D;AAGF,UAAMkwB,IAAgB,WAAW,MAAM;AACrC,MAAAJ,GAAA;AAAA,IACF,GAAG,GAAG;AAEN,WAAO,MAAM,aAAaI,CAAa;AAAA,EACzC,GAAG,CAAClwB,EAAM,OAAOA,EAAM,kBAAkB8vB,EAAmB,CAAC;AAE7D,QAAMb,KAAqBroB,EAAY,YAAY;AACjD,QAAI,GAACoI,GAAgBhP,EAAM,KAAK,KAAKA,EAAM,qBAAqB,UAEhE;AAAA,MAAAC,EAAS,CAAAsF,OAAS;AAAA,QAChB,GAAGA;AAAA,QACH,iBAAiB;AAAA,QACjB,kBAAkB;AAAA,QAClB,gBAAgB;AAAA,QAChB,qBAAqB;AAAA,MAAA,EACrB;AAEF,UAAI;AAIF,cAAM4J,IAAeC,GAAoBpP,EAAM,KAAK,GAC9CmwB,IAAiBnK,MAAe,UAAU,SAAYX,GAEtD,CAAC+K,GAAkBC,CAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,UAC3DpD,EAAQ,KAAKkD,IAAiB,EAAE,GAAGhhB,GAAc,OAAOghB,EAAA,IAAmBhhB,CAAY;AAAA,UACvF8d,EAAQ,KAAK9d,CAAY;AAAA;AAAA,QAAA,CAC1B,GAEKmhB,IAAcF,EAAiB,WAAA,GAE/BG,KADYF,EAAe,WAAA,EACJ;AAE7B,QAAApwB,EAAS,CAAAsF,QAAS;AAAA,UAChB,GAAGA;AAAA,UACH,iBAAiB;AAAA,UACjB,kBAAkB+qB;AAAA,UAClB,gBAAgB;AAAA,UAChB,eAAeC;AAAA,UACf,qBAAqB;AAAA,QAAA,EACrB;AAAA,MACJ,SAAS3vB,GAAO;AAEd,QAAAX,EAAS,CAAAsF,OAAS;AAAA,UAChB,GAAGA;AAAA,UACH,iBAAiB;AAAA,UACjB,kBAAkB;AAAA,UAClB,gBAAgB3E,aAAiB,QAAQA,EAAM,UAAU;AAAA,UACzD,eAAe;AAAA,UACf,qBAAqB;AAAA,QAAA,EACrB;AAAA,MACJ;AAAA;AAAA,EACF,GAAG,CAACZ,EAAM,OAAOA,EAAM,kBAAkBitB,GAAS5H,GAAcW,CAAU,CAAC;AAG3E,EAAAzhB,GAAU,MAAM;AACd,IAAIwqB,EAAuB,WAAW/uB,EAAM,qBAAqB,WAAWA,EAAM,oBAAoB,WACpG+uB,EAAuB,UAAU,IACjCE,GAAA;AAAA,EAEJ,GAAG,CAACjvB,EAAM,kBAAkBA,EAAM,iBAAiBivB,EAAkB,CAAC;AAEtE,QAAMuB,KAAmB5pB,EAAY,MAAM;AACzC,IAAA3G,EAAS,CAAAsF,OAAS;AAAA,MAChB,GAAGA;AAAA,MACH,OAAO+J,GAAA;AAAA,MACP,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,qBAAqB;AAAA,IAAA,EACrB;AAAA,EACJ,GAAG,CAAA,CAAE,GAECmhB,KAAc7pB,EAAY,YAAY;AAC1C,QAAI,CAACmmB,EAAe;AAEpB,UAAM2D,IAAiC;AAAA,MACrC,OAAOthB,GAAoBpP,EAAM,KAAK;AAAA,MACtC,WAAAmD;AAAA,MACA,aAAAC;AAAA,MACA,eAAAC;AAAA,MACA,YAAA2iB;AAAA,IAAA,GAII,EAAE,SAAA2F,GAAS,WAAAgF,MAAc9E,GAAqB6E,CAAc;AAGlE,QAAI,CAAC/E,GAAS;AACZ,YAAMI,IAAiC,EAAE,OAAO2E,EAAe,MAAA,GACzDE,KAAgB,KAAK,UAAU7E,CAAc,EAAE;AACrD,MAAA0C,GAAoB,EAAE,MAAMmC,IAAe,SAASvE,GAAA,GAAoB,GACxEkC,GAAoB,EAAI;AACxB;AAAA,IACF;AAEA,UAAMnC,IAAM,GAAG,OAAO,SAAS,MAAM,GAAG,OAAO,SAAS,QAAQ,UAAUT,CAAO;AAEjF,QAAI;AACF,YAAM,UAAU,UAAU,UAAUS,CAAG;AAAA,IACzC,QAAQ;AAEN,YAAMvO,IAAW,SAAS,cAAc,UAAU;AAClD,MAAAA,EAAS,QAAQuO,GACjB,SAAS,KAAK,YAAYvO,CAAQ,GAClCA,EAAS,OAAA,GACT,SAAS,YAAY,MAAM,GAC3B,SAAS,KAAK,YAAYA,CAAQ;AAAA,IACpC;AAGA,IAAAwQ,GAAoBsC,IAAY,oBAAoB,QAAQ,GAG5D3D,IAAUZ,CAAG,GAGb,WAAW,MAAM;AACf,MAAAiC,GAAoB,MAAM;AAAA,IAC5B,GAAG,GAAI;AAAA,EACT,GAAG,CAACtB,GAAe/sB,EAAM,OAAOmD,GAAWC,GAAaC,GAAe2iB,GAAYgH,CAAO,CAAC,GAErF6D,KAAwBjqB,EAAY,CAAC6c,MAAyB;AAClE,IAAAmK,EAAanK,CAAS,GAGtByJ;AAAA,MACE,EAAE,QAAQzJ,EAAU,WAAA;AAAA,MACpBA,EAAU,YAAY;AAAA,IAAA,GAIxBxjB,EAAS,CAAAsF,OAAS;AAAA,MAChB,GAAGA;AAAA,MACH,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,aAAa;AAAA,MACb,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,qBAAqB;AAAA,IAAA,EACrB;AAAA,EACJ,GAAG,CAAC2nB,CAAe,CAAC,GAEd4D,KAAuBlqB,EAAY,MAAM;AAC7C,UAAMogB,IAAgB;AAAA,MACpB,YAAY;AAAA,MACZ,UAAU;AAAA,IAAA;AAEZ,IAAA4G,EAAa5G,CAAa,GAG1BkG;AAAA,MACE,EAAE,QAAQlG,EAAc,WAAA;AAAA,MACxB;AAAA,IAAA;AAAA,EAEJ,GAAG,CAACkG,CAAe,CAAC,GAEd6D,IAAoBnqB,EAAY,YAAY;AAChD,IAAA3G,EAAS,CAAAsF,OAAS;AAAA,MAChB,GAAGA;AAAA,MACH,cAAc;AAAA,MACd,aAAa;AAAA,IAAA,EACb;AAEF,QAAI;AACF,YAAMupB,IAA6B,MAAM7B,EAAQ,KAAA;AACjD,MAAAhtB,EAAS,CAAAsF,OAAS;AAAA,QAChB,GAAGA;AAAA,QACH,QAAQupB;AAAA,QACR,cAAc;AAAA,QACd,aAAa;AAAA,MAAA,EACb;AAAA,IACJ,SAASluB,GAAO;AAEd,YAAMinB,IAAejnB,aAAiB,QAAQA,EAAM,UAAU;AAC9D,MAAAX,EAAS,CAAAsF,OAAS;AAAA,QAChB,GAAGA;AAAA,QACH,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,aAAasiB;AAAA,MAAA,EACb;AAAA,IACJ;AAAA,EACF,GAAG,CAACoF,CAAO,CAAC,GAENvlB,IAAiB;AAAA,IACrB,UAAU1H,EAAM,MAAM,YAAY,CAAA;AAAA,IAClC,YAAYA,EAAM,MAAM,cAAc,CAAA;AAAA,IACtC,iBAAiBA,EAAM,MAAM,kBAAkB,CAAA,GAAI,IAAI,CAAAsC,MAAMA,EAAG,SAAS;AAAA,EAAA,GAGrEmG,KAAWjI,EAAQ,MAAM,GACzB6L,IAAY7L,EAAQ,OAAO;AAEjC,SACE,gBAAAM,EAAC,OAAA,EAAI,WAAW,wBAAwBkG,CAAS,IAAI,OAAO,EAAE,WAAW,OAAA,GAEpE,UAAA;AAAA,IAAA,CAAC8lB,KACA,gBAAA/rB,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA,gBAAAA;AAAA,MAACylB;AAAA,MAAA;AAAA,QACC,QAAQqH;AAAA,QACR,UAAU,MAAMC,EAAkB,CAACD,CAAc;AAAA,QACjD,QAAQF;AAAA,QACR,gBAAgBkD;AAAA,QAChB,SAASC;AAAA,MAAA;AAAA,IAAA,GAEb;AAAA,IAIF,gBAAA/vB,EAAC,OAAA,EAAI,WAAU,gCACb,UAAA,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS,MAAMitB,EAAoB,CAACD,CAAgB;AAAA,QACpD,WAAU;AAAA,QAET,cACC,gBAAAjtB,EAAAoJ,IAAA,EAAE,UAAA;AAAA,UAAA,gBAAAnJ,EAACsL,GAAA,EAAU,WAAU,UAAA,CAAU;AAAA,UAAE;AAAA,QAAA,EAAA,CAAY,IAE/C,gBAAAvL,EAAAoJ,IAAA,EAAE,UAAA;AAAA,UAAA,gBAAAnJ,EAAC0H,IAAA,EAAS,WAAU,UAAA,CAAU;AAAA,UAAE;AAAA,QAAA,EAAA,CAAY;AAAA,MAAA;AAAA,IAAA,GAGpD;AAAA,IAGCslB,KACC,gBAAAjtB,EAAC,OAAA,EAAI,WAAU,4DACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oEACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,iCACb,UAAA,gBAAAD;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAMktB,EAAoB,EAAK;AAAA,YACxC,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAAjtB,EAACsL,GAAA,EAAU,WAAU,UAAA,CAAU;AAAA,cAAE;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA,GAErC;AAAA,QACA,gBAAAtL,EAAC,OAAA,EAAI,WAAU,OACb,UAAA,gBAAAA;AAAA,UAACuG;AAAA,UAAA;AAAA,YACC,QAAQtH,EAAM;AAAA,YACd,cAAcA,EAAM;AAAA,YACpB,aAAaA,EAAM;AAAA,YACnB,gBAAA0H;AAAA,YACA,eAAe,CAAClF,GAAO+d,MAAS;AAC9B,cAAA+O,GAAkB9sB,GAAO+d,CAAI,GAC7ByN,EAAoB,EAAK;AAAA,YAC3B;AAAA,YACA,iBAAiBuB;AAAA,YACjB,eAAewB;AAAA,YACf,gBAAiBjE,IAA+C,SAAhC,MAAMgB,EAAkB,EAAI;AAAA,YAC5D,gBAAgB,CAACkD,MAAa;AAC5B,cAAIA,OAA8B,EAAK;AAAA,YACzC;AAAA,UAAA;AAAA,QAAA,EACF,CACF;AAAA,MAAA,GACF;AAAA,MACA,gBAAAjwB,EAAC,SAAI,WAAU,UAAS,SAAS,MAAMitB,EAAoB,EAAK,EAAA,CAAG;AAAA,IAAA,GACrE;AAAA,IAGF,gBAAAltB,EAAC,OAAA,EAAI,WAAU,sDAAqD,OAAO,EAAE,YAAYgsB,IAAe,SAAS,OAAA,GAEjH,UAAA;AAAA,MAAA,gBAAA/rB,EAAC,SAAI,WAAW,4CAA4CktB,MAAmB,YAAY,WAAW,wBAAwB,IAC5H,UAAA,gBAAAltB;AAAA,QAACuG;AAAA,QAAA;AAAA,UACC,QAAQtH,EAAM;AAAA,UACd,cAAcA,EAAM;AAAA,UACpB,aAAaA,EAAM;AAAA,UACnB,gBAAA0H;AAAA,UACA,eAAe4nB;AAAA,UACf,iBAAiBC;AAAA,UACjB,eAAewB;AAAA,UACf,gBAAiBjE,IAA+C,SAAhC,MAAMgB,EAAkB,EAAI;AAAA,UAC5D,gBAAgB;AAAA,UAChB,kBAAkBI;AAAA,UAClB,YAAY;AAAA,QAAA;AAAA,MAAA,GAEhB;AAAA,MAGCD,MAAmB,UAClB,gBAAAntB,EAAC,OAAA,EAAI,WAAU,8CAEf,UAAA;AAAA,QAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,YACb,UAAA,gBAAAA;AAAA,UAAC2a;AAAA,UAAA;AAAA,YACC,OAAO1b,EAAM;AAAA,YACb,QAAQA,EAAM;AAAA,YACd,kBAAkBA,EAAM;AAAA,YACxB,iBAAiBA,EAAM;AAAA,YACvB,eAAeA,EAAM;AAAA,YACrB,oBAAoB4uB,IAAsB;AAAA,YAC1C,YAAYkB;AAAA,YACZ,WAAWb;AAAA,YACX,eAAeM;AAAA,YACf,kCAAkCE;AAAA,YAClC,iBAAiBE;AAAA,YACjB,mBAAmBza;AAAA,YACnB,mBAAmB0a;AAAA,YACnB,eAAeC;AAAA,YACf,cAAcW;AAAA,YACd,cAAc,CAAC1D;AAAA,YACf,iBAAiB,MAAMgB,EAAkB,CAACD,CAAc;AAAA,YACxD,oBAAoBnlB,GAAU,aAAa,KAAQ,MAAM0lB,GAAmB,EAAI,IAAI;AAAA,YACpF,cAAcrB,KAAiB/d,GAAgBhP,EAAM,KAAK,IAAIywB,KAAc;AAAA,YAC5E,kBAAA/T;AAAA,YACA,iBAAAC;AAAA,UAAA;AAAA,QAAA,GAEJ;AAAA,QAGA,gBAAA5b,EAAC,SAAI,WAAW,GAAGf,EAAM,oBAAoB,SAAS,kBAAkB,gBAAgB,IACtF,UAAA,gBAAAe;AAAA,UAACkkB;AAAA,UAAA;AAAA,YACC,iBAAiBjlB,EAAM;AAAA,YACvB,kBAAkBA,EAAM;AAAA,YACxB,gBAAgBA,EAAM;AAAA,YACtB,OAAOA,EAAM;AAAA,YACb,cAAAqlB;AAAA,YACA,sBAAsBiI;AAAA,YACtB,eAAettB,EAAM;AAAA,YACrB,qBAAqBA,EAAM;AAAA,YAE3B,WAAAmD;AAAA,YACA,aAAAC;AAAA,YACA,eAAAC;AAAA,YACA,iBAAA4f;AAAA,YACA,mBAAmBuK;AAAA,YACnB,qBAAqBC;AAAA,YACrB,uBAAuBC;AAAA,YAEvB,YAAA1H;AAAA,YACA,oBAAoBC;AAAA,UAAA;AAAA,QAAA,EACtB,CACF;AAAA,MAAA,EAAA,CACA;AAAA,IAAA,GAEF;AAAA,IAGCvd,GAAU,aAAa,MACtB,gBAAA3H;AAAA,MAAConB;AAAA,MAAA;AAAA,QACC,QAAQgG;AAAA,QACR,SAAS,MAAMC,GAAmB,EAAK;AAAA,QACvC,QAAQpuB,EAAM;AAAA,QACd,YAAY0I,GAAU;AAAA,QACtB,aAAa,CAACvG,MAAU;AAExB,UAAAlC,EAAS,CAAAsF,OAAS;AAAA,YAChB,GAAGA;AAAA,YACH,OAAOqM,GAAoBzP,CAAK;AAAA,YAChC,kBAAkB;AAAA,YAClB,iBAAiB;AAAA,YACjB,eAAe;AAAA,YACf,iBAAiB;AAAA,YACjB,kBAAkB;AAAA,YAClB,gBAAgB;AAAA,YAChB,eAAe;AAAA,YACf,qBAAqB;AAAA,UAAA,EACrB,GAGF,WAAW,YAAY;AAGrB,kBAAM4tB,IAAkB3gB,GAAoBwC,GAAoBzP,CAAK,CAAC;AAEtE,gBAAI;AACF,oBAAM7B,IAAS,MAAM2sB,EAAQ,OAAO8C,CAAe,GAC7CE,IAAU,CAAC3vB,EAAO,SAASA,EAAO,aAAcA,EAAO,UAAU;AAEvE,cAAAL,EAAS,CAAAsF,OAAS;AAAA,gBAChB,GAAGA;AAAA,gBACH,kBAAkB0qB,IAAU,UAAU;AAAA,gBACtC,iBAAiB3vB,EAAO,SAAS;AAAA,gBACjC,eAAeA,EAAO,OAAO;AAAA,cAAA,EAC7B,GAEFuuB,EAAwBvuB,CAAM;AAAA,YAChC,SAASM,GAAO;AAEd,cAAAX,EAAS,CAAAsF,OAAS;AAAA,gBAChB,GAAGA;AAAA,gBACH,kBAAkB;AAAA,gBAClB,iBAAiB3E,aAAiB,QAAQA,EAAM,UAAU;AAAA,gBAC1D,eAAe;AAAA,cAAA,EACf,GACFiuB,EAAwB,IAAI;AAAA,YAC9B;AAAA,UACF,GAAG,GAAG;AAAA,QACR;AAAA,MAAA;AAAA,IAAA;AAAA,IAKF,gBAAA9tB;AAAA,MAACurB;AAAA,MAAA;AAAA,QACC,QAAQgC;AAAA,QACR,SAAS,MAAMC,GAAoB,EAAK;AAAA,QACxC,MAAMC,GAAiB;AAAA,QACvB,SAASA,GAAiB;AAAA,MAAA;AAAA,IAAA;AAAA,EAC5B,GAEF;AAEN,CAAC;AAED7B,GAAa,cAAc;ACj7B3B,MAAMsE,KAAiB;AAAA,EACrB;AAAA,IACE,MAAM;AAAA,IACN,OAAO,KAAK,UAAU;AAAA,MACpB,UAAY,CAAC,iBAAiB;AAAA,MAC9B,YAAc,CAAC,kBAAkB;AAAA,MACjC,OAAS,EAAE,mBAAmB,OAAA;AAAA,IAAO,GACpC,MAAM,CAAC;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,MAAM;AAAA,IACN,OAAO,KAAK,UAAU;AAAA,MACpB,UAAY,CAAC,iBAAiB;AAAA,MAC9B,gBAAkB,CAAC;AAAA,QACjB,WAAa;AAAA,QACb,aAAe;AAAA,MAAA,CAChB;AAAA,MACD,OAAS,EAAE,uBAAuB,MAAA;AAAA,IAAM,GACvC,MAAM,CAAC;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,MAAM;AAAA,IACN,OAAO,KAAK,UAAU;AAAA,MACpB,UAAY,CAAC,2BAA2B,uBAAuB;AAAA,MAC/D,YAAc,CAAC,kBAAkB;AAAA,MACjC,OAAS,EAAE,2BAA2B,OAAA;AAAA,IAAO,GAC5C,MAAM,CAAC;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,MAAM;AAAA,IACN,OAAO,KAAK,UAAU;AAAA,MACpB,UAAY,CAAC,+BAA+B,gCAAgC;AAAA,MAC5E,gBAAkB,CAAC;AAAA,QACjB,WAAa;AAAA,QACb,aAAe;AAAA,MAAA,CAChB;AAAA,MACD,OAAS,EAAE,qBAAqB,MAAA;AAAA,IAAM,GACrC,MAAM,CAAC;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,MAAM;AAAA,IACN,OAAO,KAAK,UAAU;AAAA,MACpB,UAAY,CAAC,kCAAkC,+BAA+B;AAAA,MAC9E,YAAc,CAAC,kBAAkB;AAAA,MACjC,OAAS,EAAE,kCAAkC,OAAA;AAAA,IAAO,GACnD,MAAM,CAAC;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,MAAM;AAAA,IACN,OAAO,KAAK,UAAU;AAAA,MACpB,UAAY,CAAC,mBAAmB,uBAAuB,uBAAuB;AAAA,MAC9E,YAAc,CAAC,oBAAoB;AAAA,MACnC,OAAS,EAAE,uBAAuB,OAAA;AAAA,IAAO,GACxC,MAAM,CAAC;AAAA,EAAA;AAEd;AAEA,SAAwBC,GAAiB;AAAA,EACvC,QAAAjrB;AAAA,EACA,SAAAC;AAAA,EACA,QAAAirB;AAAA,EACA,SAAAjvB;AAAA,EACA,OAAAiE;AAAA,EACA,YAAAirB;AAAA,EACA,cAAAztB;AACF,GAA0B;AAExB,QAAM,EAAE,SAAAspB,EAAA,IAAYtkB,GAAA,GACd,CAAC0oB,GAAWC,CAAY,IAAIttB,EAAS,EAAE,GACvC,CAAC7B,GAAOovB,CAAQ,IAAIvtB,EAAS,EAAE,GAC/B,CAACb,GAAWqqB,CAAY,IAAIxpB,EAAoB,KAAK,GACrD,CAACV,GAAwBkuB,CAAyB,IAAIxtB,EAAmB,CAAA,CAAE,GAC3E,CAACytB,GAAcC,CAAe,IAAI1tB,EAAS,EAAK,GAChD,CAAC2tB,GAAkBC,CAAmB,IAAI5tB,EAAuD,IAAI,GACrG,CAAC6tB,GAAoBC,CAAqB,IAAI9tB,EAAiB,EAAE,GACjE,CAAC+tB,GAAYC,CAAa,IAAIhuB,EAAc,IAAI,GAChD,CAACZ,GAAaqqB,CAAc,IAAIzpB,EAA0B,EAAE,OAAO,CAAA,GAAI,OAAO,CAAA,GAAI,QAAQ,CAAA,GAAI,GAC9F,CAACX,GAAeqqB,CAAgB,IAAI1pB,EAA6B,EAAE,YAAY,IAAM,UAAU,IAAM,aAAa,IAAM,SAAS,IAAO,GACxI,CAACiuB,GAAkBC,CAAmB,IAAIluB,EAAS,EAAK,GACxD,CAACmuB,GAA0BC,CAA2B,IAAIpuB,EAAc,IAAI,GAC5EquB,IAAkBnuB,GAAY,IAAI,GAIlCQ,IADkB2e,GAAelgB,GAAW6b,EAAmB,EAC7B,cAAc,IAGhDsT,KAA0B,CAACC,OAAiB;AAAA,EAGlD,GAGMC,KAAe,GACfC,KAAgB;AAItB,EAAAluB,GAAU,MAAM;AACd,QAAI0B,GAAQ;AACV,UAAI/D,GAAS;AAEX,QAAAovB,EAAapvB,EAAQ,KAAK;AAC1B,cAAMwwB,MAAkB,MAAM;AAC5B,cAAI;AACF,mBAAO,KAAK,UAAU,KAAK,MAAMxwB,EAAQ,KAAK,GAAG,MAAM,CAAC;AAAA,UAC1D,QAAQ;AACN,mBAAOA,EAAQ;AAAA,UACjB;AAAA,QACF,GAAA;AACA,QAAAqvB,EAASmB,EAAc,GACvBlF,EAAatrB,EAAQ,SAAS,GAC9BurB,EAAevrB,EAAQ,eAAe,EAAE,OAAO,IAAI,OAAO,CAAA,GAAI,QAAQ,CAAA,GAAI,GAC1EwrB,EAAiBxrB,EAAQ,iBAAiB,EAAE,GAC5CsvB,EAA0BtvB,EAAQ,0BAA0B,EAAE,GAC9D4vB,EAAsBY,EAAc,GACpCd,EAAoB,EAAE,SAAS,IAAM,SAAS,gCAAgC,GAC9EI,EAAc,IAAI,GAGbttB,KACH,WAAW,MAAM;AACf,UAAAiuB,GAAoBD,IAAgB,IAAM,EAAI;AAAA,QAChD,GAAG,GAAG;AAAA,MAEV;AAEE,QAAApB,EAAa,EAAE,GACfC,EAAS,EAAE,GACX/D,EAAa,KAAK,GAClBC,EAAe,EAAE,OAAO,CAAA,GAAI,OAAO,IAAI,QAAQ,CAAA,GAAI,GACnDC,EAAiB,EAAE,YAAY,IAAM,UAAU,IAAM,aAAa,IAAM,SAAS,IAAO,GACxF8D,EAA0B,CAAA,CAAE,GAC5BM,EAAsB,EAAE,GACxBF,EAAoB,IAAI,GACxBI,EAAc,IAAI;AAEpB,MAAAN,EAAgB,EAAK;AAAA,IACvB;AAAA,EACF,GAAG,CAACzrB,GAAQ/D,CAAO,CAAC;AAEpB,QAAM0wB,KAAe,CAACnwB,OAAuB;AAI3C,QAHAA,GAAE,eAAA,GAGEiC;AACF,UAAI,CAAC2sB,EAAU;AACb;AAAA,WAEG;AAEL,UAAI,CAACA,EAAU,KAAA,KAAU,CAAClvB,EAAM;AAC9B;AAIF,UAAI0wB,KAAoBhB,MAAuB,MAAM1vB,EAAM,KAAA,MAAW,IAAK;AACzE,cAAM,2CAA2C;AACjD;AAAA,MACF;AAGA,UAAI;AACF,aAAK,MAAMA,CAAK;AAAA,MAClB,QAAY;AACV,cAAM,kDAAkD;AACxD;AAAA,MACF;AAAA,IACF;AAGA,UAAM2wB,KAAcpuB,IAAkB,oBAAoBvC,EAAM,KAAA;AAEhE,IAEEgvB,EAFEjvB,IAEK;AAAA,MACL,GAAGA;AAAA,MACH,OAAOmvB,EAAU,KAAA;AAAA,MACjB,OAAOyB;AAAA,MACP,WAAA3vB;AAAA,MACA,aAAa,OAAO,KAAKC,CAAW,EAAE,SAAS,IAAIA,IAAc;AAAA,MACjE,eAAAC;AAAA,MACA,wBAAwBC,EAAuB,SAAS,IAAIA,IAAyB;AAAA,MACrF,GAAGpB,EAAQ,KAAKswB;AAAA,MAChB,GAAGtwB,EAAQ,KAAKuwB;AAAA,IAAA,IAIX;AAAA,MACL,OAAOpB,EAAU,KAAA;AAAA,MACjB,OAAOyB;AAAA,MACP,WAAA3vB;AAAA,MACA,aAAa,OAAO,KAAKC,CAAW,EAAE,SAAS,IAAIA,IAAc;AAAA,MACjE,eAAAC;AAAA,MACA,wBAAwBC,EAAuB,SAAS,IAAIA,IAAyB;AAAA,MACrF,GAAGkvB;AAAA,MACH,GAAGC;AAAA,IAAA,CAXJ;AAAA,EAcL,GAEMM,KAAoB,CAACC,OAAwB;AACjD,IAAAzB,EAASyB,EAAW,GACpBpB,EAAoB,IAAI,GACxBE,EAAsB,EAAE,GACxBE,EAAc,IAAI,GAElBvE,EAAe,EAAE,OAAO,CAAA,GAAI,OAAO,IAAI,QAAQ,CAAA,GAAI;AAAA,EACrD,GAEMwF,KAAoB,CAAC7kB,OAAkB;AAC3C,IAAAmjB,EAASnjB,EAAK,GACdwjB,EAAoB,IAAI,GACxBI,EAAc,IAAI,GAEb9vB,KACHurB,EAAe,EAAE,OAAO,CAAA,GAAI,OAAO,IAAI,QAAQ,CAAA,GAAI;AAAA,EAEvD,GAEMkF,KAAsB,OAAO5C,IAAyBmD,KAAS,IAAOC,KAAiB,OAAU;AACrG,QAAI,CAACpD,GAAgB,QAAQ;AAC3B,MAAKmD,MACHtB,EAAoB,EAAE,SAAS,IAAO,SAAS,yBAAyB;AAE1E;AAAA,IACF;AAEA,QAAIwB;AACJ,QAAI;AACF,MAAAA,KAAc,KAAK,MAAMrD,EAAe;AAAA,IAC1C,QAAY;AACV,MAAKmD,MACHtB,EAAoB,EAAE,SAAS,IAAO,SAAS,uBAAuB;AAExE;AAAA,IACF;AAEA,IAAKsB,OACHxB,EAAgB,EAAI,GACpBE,EAAoB,IAAI;AAG1B,QAAI;AACF,YAAMtxB,IAAS,MAAM2sB,EAAQ,OAAOmG,EAAW;AAO/C,UAFgB,CAAC9yB,EAAO,SAASA,EAAO,WAE3B;AAGX,YAFA0xB,EAAc1xB,CAAM,GAEhB,CAAC4yB,IAAQ;AACX,gBAAMG,KAAU,CAAA;AAEhB,UAAI/yB,EAAO,YAAY,UACjBA,EAAO,WAAW,MAAM,UAAU,SAAS,KAC7C+yB,GAAQ,KAAK,GAAG/yB,EAAO,WAAW,MAAM,SAAS,MAAM,WAAWA,EAAO,WAAW,MAAM,SAAS,SAAS,IAAI,MAAM,EAAE,EAAE,GAExHA,EAAO,WAAW,MAAM,YAAY,SAAS,KAC/C+yB,GAAQ,KAAK,GAAG/yB,EAAO,WAAW,MAAM,WAAW,MAAM,aAAaA,EAAO,WAAW,MAAM,WAAW,SAAS,IAAI,MAAM,EAAE,EAAE,GAE9HA,EAAO,WAAW,MAAM,SAAS,SAAS,KAC5C+yB,GAAQ,KAAK,GAAG/yB,EAAO,WAAW,MAAM,QAAQ,MAAM,UAAUA,EAAO,WAAW,MAAM,QAAQ,SAAS,IAAI,MAAM,EAAE,EAAE,GAErHA,EAAO,WAAW,MAAM,gBAAgB,SAAS,KACnD+yB,GAAQ,KAAK,GAAG/yB,EAAO,WAAW,MAAM,eAAe,MAAM,kBAAkBA,EAAO,WAAW,MAAM,eAAe,SAAS,IAAI,MAAM,EAAE,EAAE,IAI7IA,EAAO,cACT+yB,GAAQ,KAAK,GAAG/yB,EAAO,UAAU,aAAa,GAE5CA,EAAO,KAAK,OACd+yB,GAAQ,KAAK,eAAe,GAE1B/yB,EAAO,WAAW,SAAS,KAC7B+yB,GAAQ,KAAK,UAAU/yB,EAAO,UAAU,KAAK,IAAI,CAAC,EAAE;AAGtD,gBAAMgzB,KAAUD,GAAQ,SAAS,IAAI,iCAAiCA,GAAQ,KAAK,IAAI,CAAC,MAAM;AAC9F,UAAAzB,EAAoB,EAAE,SAAS,IAAM,SAAA0B,GAAA,CAAS,GAC9CxB,EAAsB/B,EAAe;AAAA,QACvC;AAGA,QAAKoD,MACHb,GAAwBhyB,CAAM;AAAA,MAElC,WACM,CAAC4yB,IAAQ;AACX,cAAMK,KAAWjzB,EAAO,SAAS,2BAC3B+yB,KAAU/yB,EAAO,UAAU,MAAM,MAAM,QAAQA,EAAO,OAAO,IAAIA,EAAO,QAAQ,KAAK,IAAI,IAAIA,EAAO,OAAO,KAAK;AACtH,QAAAsxB,EAAoB;AAAA,UAClB,SAAS;AAAA,UACT,SAAS2B,KAAWF;AAAA,QAAA,CACrB,GACDvB,EAAsB/B,EAAe;AAAA,MACvC;AAAA,IAEJ,SAASnvB,GAAO;AACd,MAAKsyB,OACHtB,EAAoB;AAAA,QAClB,SAAS;AAAA,QACT,SAAShxB,aAAiB,QAAQA,EAAM,UAAU;AAAA,MAAA,CACnD,GACDkxB,EAAsB/B,EAAe;AAAA,IAEzC,UAAA;AACE,MAAKmD,MACHxB,EAAgB,EAAK;AAAA,IAEzB;AAAA,EACF,GAEM5B,IAAsB,YAAY;AACtC,UAAM6C,GAAoBxwB,CAAK;AAAA,EACjC,GAEMqxB,IAAyB,MAAM;AAEnC,UAAM5G,KAAezqB,KAAS,MAAM;AAClC,UAAI;AACF,eAAO,KAAK,MAAMA,CAAK;AAAA,MACzB,QAAQ;AACN,eAAO,CAAA;AAAA,MACT;AAAA,IACF,GAAA,IAAO,CAAA;AAEP,IAAAiwB,EAA4BxF,EAAY,GACxCsF,EAAoB,EAAI;AAAA,EAC1B,GAGMuB,KAA+B,CAAChxB,OAAyB;AAI7D,QAHAA,IAAG,eAAA,GACHA,IAAG,gBAAA,GAEC,CAAC4vB,EAAgB,QAAS;AAG9B,UAAMqB,KAAerB,EAAgB,QAAQ,gBAAA,GACvCsB,KAAkBtB,EAAgB,QAAQ,mBAAA,GAC1CV,KAAmBU,EAAgB,QAAQ,oBAAA,GAG3CK,IAAiB,KAAK,UAAUgB,IAAc,MAAM,CAAC;AAC3D,IAAAnC,EAASmB,CAAc,GAGnBiB,IAAiB,WAAW,WAAWhC,MACzCC,EAAoB;AAAA,MAClB,SAAS;AAAA,MACT,SAAS;AAAA,IAAA,CACV,GACDE,EAAsBY,CAAc,GAGpCV,EAAcL,EAAgB,MAM9BC,EAAoB,IAAI,GACxBE,EAAsB,EAAE,GACxBE,EAAc,IAAI,IAIpBE,EAAoB,EAAK;AAAA,EAC3B,GAEM0B,KAAmB,MAAM;AAC7B,IAAA1B,EAAoB,EAAK,GACzBE,EAA4B,IAAI;AAAA,EAClC,GAEMzJ,IAAc,MAAM;AACxB,IAAA2I,EAAa,EAAE,GACfC,EAAS,EAAE,GACX/D,EAAa,KAAK,GAClBC,EAAe,EAAE,OAAO,CAAA,GAAI,OAAO,IAAI,QAAQ,CAAA,GAAI,GACnDC,EAAiB,EAAE,YAAY,IAAM,UAAU,IAAM,aAAa,IAAM,SAAS,IAAO,GACxFkE,EAAoB,IAAI,GACxBF,EAAgB,EAAK,GACrBI,EAAsB,EAAE,GACxBE,EAAc,IAAI,GAClBE,EAAoB,EAAK,GACzBE,EAA4B,IAAI,GAChClsB,EAAA;AAAA,EACF,GAEM2tB,IAAa,CAAC,CAAC3xB,GACf2wB,IAAkB1wB,EAAM,KAAA,MAAW0vB,EAAmB,KAAA,KAAUA,MAAuB,IACvFiC,KAAyBnC,GAAkB,WAAWxvB,EAAM,KAAA,MAAW0vB,EAAmB,KAAA,GAG1F5O,KAAkB8O,GAAY,YAAY,QAAQ;AAAA,IACtD,YAAYA,EAAW,WAAW,MAAM,cAAc,CAAA;AAAA,IACtD,gBAAgBA,EAAW,WAAW,MAAM,gBAAgB,IAAI,CAACzvB,OAAYA,GAAG,SAAS,KAAK,CAAA;AAAA,IAC9F,UAAUyvB,EAAW,WAAW,MAAM,YAAY,CAAA;AAAA,EAAC,IACjD,MAGEtrB,KAASwrB,IACb,gBAAAnxB,EAAAoJ,IAAA,EACE,UAAA;AAAA,IAAA,gBAAAnJ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS6yB;AAAA,QACT,WAAU;AAAA,QACX,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGD,gBAAA7yB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS0yB;AAAA,QACT,WAAU;AAAA,QACV,OAAO,EAAE,iBAAiB,qBAAqB,OAAO,UAAA;AAAA,QACtD,OAAM;AAAA,QACN,cAAc,CAAChxB,OAAMA,GAAE,cAAc,MAAM,kBAAkB;AAAA,QAC7D,cAAc,CAACA,OAAMA,GAAE,cAAc,MAAM,kBAAkB;AAAA,QAC9D,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAED,EAAA,CACF,IAEA,gBAAA3B,EAAAoJ,IAAA,EACE,UAAA;AAAA,IAAA,gBAAAnJ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS4nB;AAAA,QACT,WAAU;AAAA,QACX,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGD,gBAAA5nB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,MAAK;AAAA,QACL,WAAU;AAAA,QACV,OAAO,EAAE,iBAAiB,qBAAqB,OAAO,UAAA;AAAA,QACtD,UAAU2D,IAAkB,CAAC2sB,EAAU,KAAA,IAAU,CAACA,EAAU,UAAU,CAAClvB,EAAM,UAAW0wB,KAAoBhB,MAAuB,MAAM1vB,EAAM,WAAW;AAAA,QAC1J,OAAO,CAACuC,MAAoBmuB,KAAoBhB,MAAuB,MAAM1vB,EAAM,KAAA,MAAW,MAAO,6CAA6C;AAAA,QAClJ,cAAc,CAACM,OAAMA,GAAE,cAAc,MAAM,kBAAkB;AAAA,QAC7D,cAAc,CAACA,OAAMA,GAAE,cAAc,MAAM,kBAAkB;AAAA,QAE5D,UAAA2uB;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GACF;AAGF,SACE,gBAAArwB;AAAA,IAACiF;AAAA,IAAA;AAAA,MACC,QAAAC;AAAA,MACA,SAAS0iB;AAAA,MACT,OAAOsJ,IAAmB,kBAAkB9rB;AAAA,MAC5C,MAAK;AAAA,MACL,QAAAM;AAAA,MACA,WAAWwrB;AAAA,MAEV,UAAAA,IACC,gBAAAlxB;AAAA,QAAC4rB;AAAA,QAAA;AAAA,UACC,KAAK0F;AAAA,UACL,cAAcF;AAAA,UACd,qBAAqB;AAAA,UACrB,cAAc;AAAA,UACd,WAAU;AAAA,QAAA;AAAA,MAAA,sBAGX,QAAA,EAAK,IAAG,gBAAe,UAAUS,IAAc,WAAU,aAE1D,UAAA;AAAA,QAAA,gBAAA9xB,EAAC,OAAA,EAAI,WAAU,mCAEb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,8BAEb,UAAA;AAAA,YAAA,gBAAAA,EAAC,OAAA,EACC,UAAA;AAAA,cAAA,gBAAAC,EAAC,SAAA,EAAM,WAAU,2DAA0D,UAAA,SAE3E;AAAA,cACA,gBAAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,OAAOswB;AAAA,kBACP,UAAU,CAAC5uB,OAAM6uB,EAAa7uB,GAAE,OAAO,KAAK;AAAA,kBAC5C,WAAU;AAAA,kBACV,aAAY;AAAA,kBACZ,UAAQ;AAAA,gBAAA;AAAA,cAAA;AAAA,YACV,GACF;AAAA,8BAGC,OAAA,EACC,UAAA;AAAA,cAAA,gBAAA1B,EAAC,SAAA,EAAM,WAAU,2DAA0D,UAAA,cAE3E;AAAA,cACA,gBAAAA;AAAA,gBAACif;AAAA,gBAAA;AAAA,kBACC,cAAc7c;AAAA,kBACd,cAAcqqB;AAAA,gBAAA;AAAA,cAAA;AAAA,YAChB,GACF;AAAA,YAIC,CAAC9oB,KACA,gBAAA5D,EAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,cAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,gBAAA,gBAAAC,EAAC,SAAA,EAAM,WAAU,sDAAqD,UAAA,wBAEtE;AAAA,gBACA,gBAAAA,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA,gBAAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAASyyB;AAAA,oBACT,WAAU;AAAA,oBACX,UAAA;AAAA,kBAAA;AAAA,gBAAA,EAED,CACF;AAAA,cAAA,GACF;AAAA,cACA,gBAAAzyB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,OAAOoB;AAAA,kBACP,UAAU,CAACM,OAAMwwB,GAAkBxwB,GAAE,OAAO,KAAK;AAAA,kBACjD,WAAU;AAAA,kBACV,aAAa;AAAA;AAAA;AAAA;AAAA,kBAIb,UAAQ;AAAA,gBAAA;AAAA,cAAA;AAAA,YACV,EAAA,CACF;AAAA,UAAA,GAEJ;AAAA,UAGA,gBAAA3B,EAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,SAAA,EAAM,WAAU,2DACd,UAAA2D,IAAkB,wBAAwB,4BAC7C;AAAA,YAECA,IACC,gBAAA3D,EAAC,OAAA,EAAI,WAAU,wDACb,UAAA,gBAAAA;AAAA,cAACiiB;AAAA,cAAA;AAAA,gBACC,WAAA7f;AAAA,gBACA,aAAAC;AAAA,gBACA,eAAAC;AAAA,gBACA,iBAAiB;AAAA,gBACjB,cAAAM;AAAA,gBACA,qBAAqB8pB;AAAA,gBACrB,uBAAuBC;AAAA,cAAA;AAAA,YAAA,EACzB,CACF,IACG,CAACqE,KAAc,CAAC+B,KACnB,gBAAA/yB,EAAC,OAAA,EAAI,WAAU,sHACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,cAAA,gBAAAC,EAAC,SAAI,WAAU,wBAAuB,MAAK,QAAO,SAAQ,aAAY,QAAO,gBAC3E,4BAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,oDAAmD,EAAA,CAC1H;AAAA,cACA,gBAAAA,EAAC,KAAA,EAAE,WAAU,WAAU,UAAA,+CAAA,CAA4C;AAAA,YAAA,GACrE,EAAA,CACF,IAEA,gBAAAA,EAAC,OAAA,EAAI,WAAU,wDACb,UAAA,gBAAAA;AAAA,cAACiiB;AAAA,cAAA;AAAA,gBACC,WAAA7f;AAAA,gBACA,aAAAC;AAAA,gBACA,eAAAC;AAAA,gBACA,iBAAA4f;AAAA,gBACA,cAAAtf;AAAA,gBACA,qBAAqB8pB;AAAA,gBACrB,uBAAuBC;AAAA,cAAA;AAAA,YAAA,EACzB,CACF;AAAA,UAAA,EAAA,CAEJ;AAAA,QAAA,GACF;AAAA,QAGC,CAAChpB,MAAoBmuB,KAAoBhB,MAAuB,MAAM1vB,EAAM,WAAW,MAAQwvB,KAAoBxvB,EAAM,WAAW0vB,EAAmB,KAAA,KAAUF,EAAiB,YAAY,qDAC5L,OAAA,EAAI,WAAW,kBACdA,GAAkB,WAAWxvB,EAAM,KAAA,MAAW0vB,EAAmB,KAAA,IAC7D,qCACAF,KAAoB,CAACA,EAAiB,UACtC,iCACAkB,IACA,qCACA,yBACN,IACE,UAAA,gBAAA/xB,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,OAAA,EAAI,WAAW,wBACd4wB,GAAkB,WAAWxvB,EAAM,KAAA,MAAW0vB,EAAmB,KAAA,IAC7D,iBACAF,KAAoB,CAACA,EAAiB,UACtC,eACAkB,IACA,iBACA,aACN,IAAI;AAAA,8BACH,OAAA,EACC,UAAA;AAAA,cAAA,gBAAA9xB,EAAC,QAAG,WAAW,uBACb4wB,GAAkB,WAAWxvB,EAAM,KAAA,MAAW0vB,EAAmB,KAAA,IAC7D,uCACAF,KAAoB,CAACA,EAAiB,UACtC,mCACAkB,IACA,uCACA,wBACN,IACG,UAAAlB,GAAkB,WAAWxvB,EAAM,KAAA,MAAW0vB,EAAmB,KAAA,IAC9D,iCACAF,KAAoB,CAACA,EAAiB,UACtC,4BACAkB,IACA,yCACA,6BAEN;AAAA,cACClB,KACC,gBAAA5wB,EAAC,KAAA,EAAE,WAAW,gBACZ4wB,EAAiB,UAAU,uCAAuC,gCACpE,IACG,UAAAA,EAAiB,QAAA,CACpB;AAAA,YAAA,EAAA,CAEJ;AAAA,UAAA,GACF;AAAA,UAEA,gBAAA5wB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS+uB;AAAA,cACT,UAAU2B,KAAgB,CAACtvB,EAAM,KAAA;AAAA,cACjC,WAAW,8FACTwvB,GAAkB,WAAWxvB,EAAM,WAAW0vB,EAAmB,KAAA,IAC7D,+CACAF,KAAoB,CAACA,EAAiB,UACtC,2CACA,oDACN;AAAA,cAEC,cACC,gBAAA7wB,EAAAoJ,IAAA,EACE,UAAA;AAAA,gBAAA,gBAAApJ,EAAC,SAAI,WAAU,wBAAuB,MAAK,QAAO,SAAQ,aACxD,UAAA;AAAA,kBAAA,gBAAAC,EAAC,UAAA,EAAO,WAAU,cAAa,IAAG,MAAK,IAAG,MAAK,GAAE,MAAK,QAAO,gBAAe,aAAY,KAAI;AAAA,oCAC3F,QAAA,EAAK,WAAU,cAAa,MAAK,gBAAe,GAAE,kHAAA,CAAkH;AAAA,gBAAA,GACvK;AAAA,gBACA,gBAAAA,EAAC,UAAK,UAAA,aAAA,CAAU;AAAA,cAAA,EAAA,CAClB,IACE4wB,GAAkB,WAAWxvB,EAAM,WAAW0vB,EAAmB,KAAA,IACnE,gBAAA/wB,EAAAoJ,IAAA,EACE,UAAA;AAAA,gBAAA,gBAAAnJ,EAAC,SAAI,WAAU,WAAU,MAAK,QAAO,SAAQ,aAAY,QAAO,gBAC9D,4BAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,iDAAgD,EAAA,CACvH;AAAA,gBACA,gBAAAA,EAAC,UAAK,UAAA,YAAA,CAAS;AAAA,cAAA,EAAA,CACjB,IAEA,gBAAAD,EAAAoJ,IAAA,EACE,UAAA;AAAA,gBAAA,gBAAAnJ,EAAC,SAAI,WAAU,WAAU,MAAK,QAAO,SAAQ,aAAY,QAAO,gBAC9D,4BAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,iDAAgD,EAAA,CACvH;AAAA,gBACA,gBAAAA,EAAC,UAAK,UAAA,WAAA,CAAQ;AAAA,cAAA,EAAA,CAChB;AAAA,YAAA;AAAA,UAAA;AAAA,QAEJ,EAAA,CACF,EAAA,CACF;AAAA,QAID,CAAC8yB,KACA,gBAAA/yB,EAAC,OAAA,EACC,UAAA;AAAA,UAAA,gBAAAC,EAAC,SAAA,EAAM,WAAU,yCAAwC,UAAA,iCAA6B;AAAA,UACtF,gBAAAA,EAAC,SAAI,WAAU,6BACZ,aAAe,IAAI,CAACgzB,IAAQloB,OAC3B,gBAAA9K;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,MAAK;AAAA,cACL,SAAS,MAAMgyB,GAAkBgB,GAAO,KAAK;AAAA,cAC7C,WAAU;AAAA,cAET,UAAAA,GAAO;AAAA,YAAA;AAAA,YALHloB;AAAA,UAAA,CAOR,EAAA,CACH;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CAEF;AAAA,IAAA;AAAA,EAAA;AAIR;ACrrBA,SAAwBmoB,GAAyB;AAAA,EAC/C,QAAA/tB;AAAA,EACA,SAAAC;AAAA,EACA,kBAAA7E,IAAmB,CAAA;AAAA,EACnB,gBAAA4yB,IAAiB,CAAA;AAAA,EACjB,QAAA9C;AAAA,EACA,cAAA+C;AACF,GAAkC;AAChC,QAAM,CAACC,GAAiBC,CAAkB,IAAIpwB,EAAmBiwB,CAAc;AAG/E,EAAA1vB,GAAU,MAAM;AACd,IAAA6vB,EAAmBH,CAAc;AAAA,EACnC,GAAG,CAACA,GAAgBhuB,CAAM,CAAC;AAE3B,QAAMouB,IAAqB,CAACC,MAAqB;AAC/C,IAAAF,EAAmB,CAAA7uB,MACbA,EAAK,SAAS+uB,CAAQ,IACjB/uB,EAAK,OAAO,CAAAnH,MAAMA,MAAOk2B,CAAQ,IAEjC,CAAC,GAAG/uB,GAAM+uB,CAAQ,CAE5B;AAAA,EACH,GAEMC,IAAa,MAAM;AACvB,IAAApD,EAAOgD,CAAe,GACtBjuB,EAAA;AAAA,EACF,GAEMsuB,IAAe,MAAM;AACzB,IAAAJ,EAAmBH,CAAc,GACjC/tB,EAAA;AAAA,EACF,GAGMuuB,IAAsB,CAACxzB,MAAoC;AAC/D,QAAI,CAACA,EAAO,OAAQ,QAAO;AAG3B,QAAI,YAAYA,EAAO,UAAUA,EAAO,OAAO,QAAQ;AACrD,YAAMuL,IAASvL,EAAO,OAAO,UAAU,CAAA,GACjCyzB,IAAaloB,EAAO,SAAS,IAAIA,EAAO,KAAK,IAAI,IAAI;AAC3D,aAAO,GAAGvL,EAAO,OAAO,MAAM,IAAIA,EAAO,OAAO,QAAQ,IAAIyzB,CAAU;AAAA,IACxE;AAGA,QAAI,UAAUzzB,EAAO,UAAUA,EAAO,OAAO,MAAM;AACjD,YAAM0zB,IAAc1zB,EAAO,OAAO,SAAS,UAAU;AACrD,aAAO,GAAGA,EAAO,OAAO,KAAK,YAAA,CAAa,eAAe0zB,CAAW,UAAUA,MAAgB,IAAI,MAAM,EAAE;AAAA,IAC5G;AAEA,WAAO;AAAA,EACT;AAEA,SAAK1uB,IAGH,gBAAAlF,EAAC,OAAA,EAAI,WAAU,8EAA6E,SAASyzB,GACnG,UAAA,gBAAA1zB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,sBAAA;AAAA,MACpB,SAAS,CAAC2B,MAAMA,EAAE,gBAAA;AAAA,MAGlB,UAAA;AAAA,QAAA,gBAAA3B,EAAC,OAAA,EAAI,WAAU,4EACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,sCAAqC,UAAA,+BAA2B;AAAA,UAC9E,gBAAAD,EAAC,KAAA,EAAE,WAAU,uCAAsC,UAAA;AAAA,YAAA;AAAA,YACPozB;AAAA,YAAa;AAAA,UAAA,EAAA,CACzD;AAAA,QAAA,GACF;AAAA,QAGA,gBAAAnzB,EAAC,OAAA,EAAI,WAAU,oCACZ,UAAAM,EAAiB,WAAW,IAC3B,gBAAAP,EAAC,OAAA,EAAI,WAAU,uCACb,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,QAAO;AAAA,cAEP,UAAA,gBAAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,eAAc;AAAA,kBACd,gBAAe;AAAA,kBACf,aAAa;AAAA,kBACb,GAAE;AAAA,gBAAA;AAAA,cAAA;AAAA,YACJ;AAAA,UAAA;AAAA,UAEF,gBAAAA,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,kCAA8B;AAAA,UACjE,gBAAAA,EAAC,KAAA,EAAE,WAAU,gBAAe,UAAA,2CAAA,CAAwC;AAAA,QAAA,EAAA,CACtE,IAEA,gBAAAD,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,yEACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,oCAAmC,UAAA,qBAAiB;AAAA,YACpE,gBAAAD,EAAC,QAAA,EAAK,WAAU,kCACb,UAAA;AAAA,cAAAqzB,EAAgB;AAAA,cAAO;AAAA,cAAK9yB,EAAiB;AAAA,cAAO;AAAA,YAAA,EAAA,CACvD;AAAA,UAAA,GACF;AAAA,UAECA,EAAiB,IAAI,CAAAJ,MAAU;AAC9B,kBAAM+J,IAAampB,EAAgB,SAASlzB,EAAO,EAAE;AAErD,mBACE,gBAAAH;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAW,2EACTkK,IACI,8CACA,4CACN;AAAA,gBAEA,UAAA;AAAA,kBAAA,gBAAAjK;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,MAAK;AAAA,sBACL,SAASiK;AAAA,sBACT,UAAU,MAAMqpB,EAAmBpzB,EAAO,EAAE;AAAA,sBAC5C,WAAU;AAAA,sBACV,OAAO;AAAA,wBACL,aAAa;AAAA,sBAAA;AAAA,oBACf;AAAA,kBAAA;AAAA,kBAEF,gBAAAH,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,oBAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,sBAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,6CACb,UAAAE,EAAO,OACV;AAAA,sBACC+J,KACC,gBAAAjK;AAAA,wBAAC;AAAA,wBAAA;AAAA,0BACC,WAAU;AAAA,0BACV,OAAO;AAAA,4BACL,iBAAiB;AAAA,4BACjB,OAAO;AAAA,0BAAA;AAAA,0BAEV,UAAA;AAAA,wBAAA;AAAA,sBAAA;AAAA,oBAED,GAEJ;AAAA,sCACC,OAAA,EAAI,WAAU,mDACZ,UAAA0zB,EAAoBxzB,CAAM,EAAA,CAC7B;AAAA,kBAAA,EAAA,CACF;AAAA,gBAAA;AAAA,cAAA;AAAA,cApCKA,EAAO;AAAA,YAAA;AAAA,UAuClB,CAAC;AAAA,QAAA,EAAA,CACH,EAAA,CAEJ;AAAA,QAGA,gBAAAH,EAAC,OAAA,EAAI,WAAU,mGACb,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAASyzB;AAAA,cACT,WAAU;AAAA,cACX,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGD,gBAAAzzB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAASwzB;AAAA,cACT,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,iBAAiB;AAAA,cAAA;AAAA,cAEpB,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAED,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAEJ,IAlHkB;AAoHtB;AClLA,SAAwBK,GAAW;AAAA,EACjC,aAAAxxB;AAAA,EACA,eAAAC;AAAA,EACA,aAAAsB;AAAA,EACA,MAAAa;AAAA,EACA,WAAArC;AACF,GAAoB;AAClB,QAAM,CAAC8C,GAAQ0G,CAAS,IAAI3I,EAAS,EAAK;AA2B1C,SAxBAO,GAAU,MAAM;AACd,UAAMqkB,IAAgB,CAAC/hB,MAAyB;AAC9C,MAAIA,EAAM,QAAQ,YAAYZ,KAC5B0G,EAAU,EAAK;AAAA,IAEnB;AAEA,oBAAS,iBAAiB,WAAWic,CAAa,GAC3C,MAAM,SAAS,oBAAoB,WAAWA,CAAa;AAAA,EACpE,GAAG,CAAC3iB,CAAM,CAAC,GAGX1B,GAAU,MAAM;AACd,QAAI0B,KAAU,OAAO,SAAW,OAAgB,OAAe,OAAO;AAEpE,YAAM4uB,IAAQ,WAAW,MAAM;AAC5B,eAAe,MAAM,aAAA;AAAA,MACxB,GAAG,EAAE;AAEL,aAAO,MAAM,aAAaA,CAAK;AAAA,IACjC;AAAA,EACF,GAAG,CAAC5uB,CAAM,CAAC,GAGNA,IA0BH,gBAAAlF;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,SAAS,CAAC0B,MAAMA,EAAE,gBAAA;AAAA,MAElB,UAAA,gBAAA3B,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,mDACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,sCAAqC,UAAA,2BAAuB;AAAA,UAC1E,gBAAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAM4L,EAAU,EAAK;AAAA,cAC9B,WAAU;AAAA,cAEV,UAAA,gBAAA7L;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,OAAM;AAAA,kBACN,QAAO;AAAA,kBACP,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACL,QAAO;AAAA,kBACP,aAAY;AAAA,kBAEZ,UAAA;AAAA,oBAAA,gBAAAC,EAAC,QAAA,EAAK,IAAG,MAAK,IAAG,KAAI,IAAG,KAAI,IAAG,KAAA,CAAI;AAAA,oBACnC,gBAAAA,EAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,KAAA,CAAI;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YACrC;AAAA,UAAA;AAAA,QACF,GACF;AAAA,QAEA,gBAAAD,EAAC,OAAA,EAAI,WAAU,8DACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EACC,UAAA;AAAA,YAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,mDAAkD,UAAA,cAAU;AAAA,YAC1E,gBAAAA,EAAC,OAAA,EAAI,WAAU,oFACZ,UAAAoC,EAAA,CACH;AAAA,UAAA,GACF;AAAA,4BAEC,OAAA,EACC,UAAA;AAAA,YAAA,gBAAApC,EAAC,MAAA,EAAG,WAAU,mDAAkD,UAAA,kBAAc;AAAA,YAC9E,gBAAAD,EAAC,OAAA,EAAI,WAAU,oFACb,UAAA;AAAA,cAAA,gBAAAA,EAAC,OAAA,EACC,UAAA;AAAA,gBAAA,gBAAAC,EAAC,YAAO,UAAA,SAAA,CAAM;AAAA,gBAAS;AAAA,gBAAE,MAAM,QAAQqC,GAAa,KAAK,IAAI,WAAWA,EAAY,MAAM,KAAK,IAAI,CAAC,MAAM,YAAYA,GAAa,KAAK;AAAA,cAAA,GAC1I;AAAA,gCACC,OAAA,EACC,UAAA;AAAA,gBAAA,gBAAArC,EAAC,YAAO,UAAA,SAAA,CAAM;AAAA,gBAAS;AAAA,gBAAE,MAAM,QAAQqC,GAAa,KAAK,IAAI,WAAWA,EAAY,MAAM,KAAK,IAAI,CAAC,MAAM,YAAYA,GAAa,KAAK;AAAA,cAAA,GAC1I;AAAA,gCACC,OAAA,EACC,UAAA;AAAA,gBAAA,gBAAArC,EAAC,YAAO,UAAA,UAAA,CAAO;AAAA,gBAAS;AAAA,gBAAE,MAAM,QAAQqC,GAAa,MAAM,IAAI,WAAWA,EAAY,OAAO,KAAK,IAAI,CAAC,MAAM,YAAYA,GAAa,MAAM;AAAA,cAAA,GAC9I;AAAA,cACCA,GAAa,aACZ,gBAAAtC,EAAC,OAAA,EACC,UAAA;AAAA,gBAAA,gBAAAC,EAAC,YAAO,UAAA,aAAA,CAAU;AAAA,gBAAS;AAAA,gBAAE,MAAM,QAAQqC,GAAa,SAAS,IAAI,WAAWA,EAAY,UAAU,KAAK,IAAI,CAAC,MAAM,YAAYA,GAAa,SAAS;AAAA,cAAA,GAC1J;AAAA,cAEDA,GAAa,cACZ,gBAAAtC,EAAC,OAAA,EACC,UAAA;AAAA,gBAAA,gBAAAC,EAAC,YAAO,UAAA,cAAA,CAAW;AAAA,gBAAS;AAAA,gBAAE,MAAM,QAAQqC,GAAa,UAAU,IAAI,WAAWA,EAAY,WAAW,KAAK,IAAI,CAAC,MAAM,YAAYA,GAAa,UAAU;AAAA,cAAA,EAAA,CAC9J;AAAA,YAAA,EAAA,CAEJ;AAAA,UAAA,GACF;AAAA,UAEA,gBAAAtC,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,mDAAkD,UAAA,gBAAY;AAAA,YAC5E,gBAAAA,EAAC,SAAI,WAAU,2FAA0F,OAAO,EAAE,UAAU,QAAQ,YAAY,MAAA,GAC9I,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,iBAAiB,UAAA,KAAK,UAAUqC,GAAa,MAAM,CAAC,EAAA,CAAE,EAAA,CACxE;AAAA,UAAA,GACF;AAAA,UAEA,gBAAAtC,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,mDAAkD,UAAA,kBAAc;AAAA,YAC9E,gBAAAA,EAAC,SAAI,WAAU,2FAA0F,OAAO,EAAE,UAAU,QAAQ,YAAY,MAAA,GAC9I,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,iBAAiB,UAAA,KAAK,UAAUsC,GAAe,MAAM,CAAC,EAAA,CAAE,EAAA,CAC1E;AAAA,UAAA,GACF;AAAA,UAEA,gBAAAvC,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,mDAAkD,UAAA,gBAAY;AAAA,YAC5E,gBAAAA,EAAC,SAAI,WAAU,2FAA0F,OAAO,EAAE,UAAU,QAAQ,YAAY,MAAA,GAC9I,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,iBAAiB,UAAA,KAAK,UAAU4D,GAAa,MAAM,CAAC,EAAA,CAAE,EAAA,CACxE;AAAA,UAAA,GACF;AAAA,UAEA,gBAAA7D,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,mDAAkD,UAAA,8BAA0B;AAAA,YAC1F,gBAAAA,EAAC,OAAA,EAAI,WAAU,2FAA0F,OAAO,EAAE,UAAU,QAAQ,YAAY,MAAA,GAC9I,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,iBAAiB,UAAA,KAAK,UAAUyE,GAAM,MAAM,GAAG,CAAC,KAAK,CAAA,GAAI,MAAM,CAAC,EAAA,CAAE,EAAA,CACpF;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,GACF;AAAA,QAEA,gBAAA1E,EAAC,OAAA,EAAI,WAAU,2EAA0E,UAAA;AAAA,UAAA;AAAA,UACjF,gBAAAC,EAAC,OAAA,EAAI,WAAU,0DAAyD,UAAA,OAAG;AAAA,UAAM;AAAA,QAAA,EAAA,CACzF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA,IAlHA,gBAAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,SAAS,MAAM4L,EAAU,EAAI;AAAA,MAC7B,WAAU;AAAA,MACV,OAAM;AAAA,MAEN,UAAA,gBAAA7L;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,QAAO;AAAA,UACP,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,QAAO;AAAA,UACP,aAAY;AAAA,UACZ,eAAc;AAAA,UACd,gBAAe;AAAA,UAEf,UAAA;AAAA,YAAA,gBAAAC,EAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,MAAI;AAAA,YAC9B,gBAAAA,EAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,KAAA,CAAI;AAAA,YACpC,gBAAAA,EAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ,IAAG,KAAA,CAAI;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAC1C;AAAA,EAAA;AAmGR;ACtJO,MAAM+zB,KAAiC;AAAA,EAC5C;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAAA,EAEF;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EACF;AAEJ;AAKO,SAASC,GAAgBC,GAAoC;AAClE,SAAKA,KAIWF,GAAe,KAAK,CAAAG,MAAKA,EAAE,SAASD,CAAW,KAC7CF,GAAe,CAAC;AACpC;AC1rBA,MAAM7sB,KAAkBzH,EAAQ,aAAa;AAQ7C,SAAwB00B,GAAqB;AAAA,EAC3C,gBAAAC,IAAiB;AAAA,EACjB,iBAAAC;AAAA,EACA,WAAApuB,IAAY;AACd,GAA8B;AAC5B,QAAM,CAACf,GAAQ0G,CAAS,IAAI3I,EAAS,EAAK,GACpCgJ,IAAc9I,GAAuB,IAAI,GAEzCmxB,IAAoBN,GAAgBI,CAAc;AAGxD,EAAA5wB,GAAU,MAAM;AACd,aAASuJ,EAAmBjH,GAAmB;AAC7C,MAAImG,EAAY,WAAW,CAACA,EAAY,QAAQ,SAASnG,EAAM,MAAc,KAC3E8F,EAAU,EAAK;AAAA,IAEnB;AAEA,QAAI1G;AACF,sBAAS,iBAAiB,aAAa6H,CAAkB,GAClD,MAAM,SAAS,oBAAoB,aAAaA,CAAkB;AAAA,EAE7E,GAAG,CAAC7H,CAAM,CAAC;AAEX,QAAMqvB,IAAsB,CAACN,MAAwB;AACnD,IAAAI,EAAgBJ,CAAW,GAC3BroB,EAAU,EAAK;AAAA,EACjB;AAEA,2BACG,OAAA,EAAI,WAAW,YAAY3F,CAAS,IAAI,KAAKgG,GAE5C,UAAA;AAAA,IAAA,gBAAAlM;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,MAAM6L,EAAU,CAAC1G,CAAM;AAAA,QAChC,WAAU;AAAA,QAGV,UAAA;AAAA,UAAA,gBAAAnF,EAAC,OAAA,EAAI,WAAU,uCACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,gBACZ,UAAAs0B,EAAkB,OAAO,MAAM,GAAG,CAAC,EAAE,IAAI,CAACrQ,GAAOnZ,MAChD,gBAAA9K;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAU;AAAA,gBACV,OAAO,EAAE,iBAAiBikB,EAAA;AAAA,gBAC1B,OAAO,gBAAgBnZ,IAAQ,CAAC;AAAA,cAAA;AAAA,cAH3BA;AAAA,YAAA,CAKR,GACH;AAAA,YACA,gBAAA9K,EAAC,QAAA,EAAK,WAAU,kCAAiC,UAAA,KAAC;AAAA,YAClD,gBAAAA,EAAC,OAAA,EAAI,WAAU,gBACZ,UAAAs0B,EAAkB,SAAS,MAAM,GAAG,CAAC,EAAE,IAAI,CAACrQ,GAAOnZ,MAClD,gBAAA9K;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,iBAAiBikB;AAAA,kBACjB,aAAa;AAAA,gBAAA;AAAA,gBAEf,OAAO,kBAAkBnZ,IAAQ,CAAC;AAAA,cAAA;AAAA,cAN7BA;AAAA,YAAA,CAQR,EAAA,CACH;AAAA,UAAA,GACF;AAAA,UACA,gBAAA9K,EAAC,QAAA,EAAM,UAAAs0B,EAAkB,MAAA,CAAM;AAAA,UAC/B,gBAAAt0B;AAAA,YAACkH;AAAAA,YAAA;AAAA,cACC,WAAW,gCAAgChC,IAAS,eAAe,EAAE;AAAA,YAAA;AAAA,UAAA;AAAA,QACvE;AAAA,MAAA;AAAA,IAAA;AAAA,IAIDA,KACC,gBAAAlF,EAAC,OAAA,EAAI,WAAU,+IACb,4BAAC,OAAA,EAAI,WAAU,QACZ,UAAA+zB,GAAe,MAAA,EAAQ,KAAK,CAACjlB,GAAGC,MAAMD,EAAE,MAAM,cAAcC,EAAE,KAAK,CAAC,EAAE,IAAI,CAACylB,MAC1E,gBAAAx0B;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,MAAK;AAAA,QACL,SAAS,MAAMu0B,EAAoBC,EAAQ,IAAI;AAAA,QAC/C,WAAW,+GACTA,EAAQ,SAASJ,IAAiB,4BAA4B,wBAChE;AAAA,QACA,OAAOI,EAAQ,SAASJ,IAAiB,EAAE,OAAO,wBAAwB;AAAA,QAE1E,UAAA,gBAAAr0B,EAAC,OAAA,EAAI,WAAU,2BAEb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qCAEb,UAAA;AAAA,YAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,gBACZ,UAAAw0B,EAAQ,OAAO,MAAM,GAAG,CAAC,EAAE,IAAI,CAACvQ,GAAOnZ,MACtC,gBAAA9K;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAU;AAAA,gBACV,OAAO,EAAE,iBAAiBikB,EAAA;AAAA,cAAM;AAAA,cAF3B,UAAUnZ,CAAK;AAAA,YAAA,CAIvB,GACH;AAAA,YAGA,gBAAA9K,EAAC,OAAA,EAAI,WAAU,wBAAA,CAAwB;AAAA,YAGvC,gBAAAA,EAAC,SAAI,WAAU,QACZ,YAAQ,SAAS,IAAI,CAACikB,GAAOnZ,MAC5B,gBAAA9K;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAU;AAAA,gBACV,OAAO,EAAE,iBAAiBikB,EAAA;AAAA,cAAM;AAAA,cAF3B,YAAYnZ,CAAK;AAAA,YAAA,CAIzB,EAAA,CACH;AAAA,UAAA,GACF;AAAA,UAGA,gBAAA9K,EAAC,QAAA,EAAK,WAAU,eAAe,YAAQ,OAAM;AAAA,UAG5Cw0B,EAAQ,SAASJ,KAChB,gBAAAp0B,EAAC,OAAA,EAAI,WAAU,WACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,wBAAuB,OAAO,EAAE,iBAAiB,oBAAA,GAAuB,EAAA,CACzF;AAAA,QAAA,EAAA,CAEJ;AAAA,MAAA;AAAA,MA9CKw0B,EAAQ;AAAA,IAAA,CAgDhB,GACH,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;ACpIA,MAAMlpB,KAAY7L,EAAQ,OAAO,GAC3Bg1B,KAAUh1B,EAAQ,KAAK,GACvBi1B,KAAaj1B,EAAQ,QAAQ,GAkB7Bk1B,KAAkD,CAAC;AAAA,EACvD,QAAAz0B;AAAA,EACA,QAAAsG;AAAA,EACA,iBAAAzF;AAAA,EACA,QAAAmE;AAAA,EACA,QAAAkrB;AAAA,EACA,SAAAjrB;AAAA,EACA,UAAAyvB;AAAA,EACA,uBAAAC;AACF,MAAM;AAEJ,QAAM,CAACC,GAAYC,CAAa,IAAI9xB,EAAS/C,EAAO,KAAK,GACnD,CAAC80B,GAAaC,CAAc,IAAIhyB,EAAS/C,EAAO,MAAM,GACtD,CAACg1B,GAAeC,CAAgB,IAAIlyB,EAAS,EAAK;AAGxD,EAAAO,GAAU,MAAM;AACd,IAAI0B,MACF6vB,EAAc70B,EAAO,KAAK,GAC1B+0B,EAAe/0B,EAAO,MAAM;AAAA,EAEhC,GAAG,CAACA,GAAQgF,CAAM,CAAC;AAGnB,QAAMkwB,IAAkBvxB,GAAQ,MACvB/C,GAAuBC,CAAe,GAC5C,CAACA,CAAe,CAAC,GAGds0B,IAAiBxxB,GAA6B,MAAM;AACxD,QAAI,CAAC2C,EAAQ,QAAO;AAEpB,QAAI0uB;AACF,aAAOL,EAAsBruB,CAAM;AAGrC,UAAMwE,IAAgBxE,EAAO,MAC1B,IAAI,CAAAqC,MAAQ;AACX,YAAMQ,IAAWR,EAAK,MAEhBysB,IAAmBzsB,EAAK,SAAS,OAAO,CAAAxH,MAAW;AACvD,cAAMk0B,IAAWl0B,EAAQ,KAAK,SAAS,GAAG,IACtCA,EAAQ,OACR,GAAGgI,CAAQ,IAAIhI,EAAQ,IAAI;AAC/B,eAAO+zB,EAAgB,SAAS,IAAIG,CAAQ;AAAA,MAC9C,CAAC,GAEKC,IAAqB3sB,EAAK,WAAW,OAAO,CAAAvH,MAAa;AAC7D,cAAMi0B,IAAWj0B,EAAU,KAAK,SAAS,GAAG,IACxCA,EAAU,OACV,GAAG+H,CAAQ,IAAI/H,EAAU,IAAI;AACjC,eAAO8zB,EAAgB,WAAW,IAAIG,CAAQ,KACvCH,EAAgB,eAAe,IAAIG,CAAQ;AAAA,MACpD,CAAC;AAED,aAAID,EAAiB,SAAS,KAAKE,EAAmB,SAAS,IACtD;AAAA,QACL,GAAG3sB;AAAA,QACH,UAAUysB;AAAA,QACV,YAAYE;AAAA,MAAA,IAIT;AAAA,IACT,CAAC,EACA,OAAO,CAAC3sB,MAA2CA,MAAS,IAAI,GAE7D4sB,IAA6B;AAAA,MACjC,GAAGjvB;AAAA,MACH,OAAOwE;AAAA,IAAA;AAGT,WAAO6pB,EAAsBY,CAAgB;AAAA,EAC/C,GAAG,CAACjvB,GAAQ4uB,GAAiBF,GAAeL,CAAqB,CAAC,GAG5Da,IAAwB7xB,GAAQ,MAChC,YAAYmxB,KAAeA,EAAY,SAClCA,EAAY,SAEd,MACN,CAACA,CAAW,CAAC,GAGVW,IAAoB9vB,EAAY,CAAC+vB,MAAqB;AAC1D,IAAAb,EAAca,CAAQ;AAAA,EACxB,GAAG,CAAA,CAAE,GAGCC,IAA4BhwB,EAAY,CAAClE,MAAsB;AACnE,IAAAszB,EAAetzB,EAAQ,CAAC,KAAKqzB,CAAW;AAAA,EAC1C,GAAG,CAACA,CAAW,CAAC,GAGVzG,IAAoB1oB,EAAY,CAAC6E,MAAsB;AAC3D,IAAI,YAAYsqB,KACdC,EAAe;AAAA,MACb,GAAGD;AAAA,MACH,QAAQtqB;AAAA,MACR,QAAQ,CAAA;AAAA;AAAA,IAAC,CACV;AAAA,EAEL,GAAG,CAACsqB,CAAW,CAAC,GAGV7gB,IAAwBtO,EAAY,CAACiwB,GAAkB7zB,MAAiC;AAC5F,IAAI,YAAY+yB,KACdC,EAAe;AAAA,MACb,GAAGD;AAAA,MACH,QAAQ,MAAM,QAAQ/yB,CAAS,IAAIA,IAAY,CAACA,CAAS;AAAA,IAAA,CAC1C;AAAA,EAErB,GAAG,CAAC+yB,CAAW,CAAC,GAGVe,IAAiBlwB,EAAY,MAC5BivB,EAAW,SAKZ,CAAC50B,EAAO,mBAAmB,YAAY80B,KAAe,CAACA,EAAY,SAC9D,EAAE,SAAS,IAAO,SAAS,uCAAA,IAG7B,EAAE,SAAS,GAAA,IART,EAAE,SAAS,IAAO,SAAS,2BAAA,GASnC,CAACF,GAAYE,GAAa90B,EAAO,eAAe,CAAC,GAG9CszB,IAAa3tB,EAAY,YAAY;AACzC,UAAMmwB,IAAaD,EAAA;AACnB,QAAI,CAACC,EAAW,SAAS;AACvB,YAAMA,EAAW,OAAO;AACxB;AAAA,IACF;AAEA,UAAMC,IAAiC;AAAA,MACrC,IAAI/1B,EAAO;AAAA,MACX,OAAO40B;AAAA,MACP,QAAQE;AAAA;AAAA,MAER,GAAI90B,EAAO,mBAAmB,EAAE,iBAAiB,GAAA;AAAA,IAAK;AAGxD,QAAI;AACF,YAAMkwB,EAAO6F,CAAa,GAC1B9wB,EAAA;AAAA,IACF,SAAStF,GAAO;AACd,cAAQ,MAAM,0BAA0BA,CAAK,GAC7C,MAAM,0CAA0C;AAAA,IAClD;AAAA,EACF,GAAG,CAACK,EAAO,IAAIA,EAAO,iBAAiB40B,GAAYE,GAAae,GAAgB3F,GAAQjrB,CAAO,CAAC,GAG1FsuB,IAAe5tB,EAAY,MAAM;AACrC,IAAAkvB,EAAc70B,EAAO,KAAK,GAC1B+0B,EAAe/0B,EAAO,MAAM,GAC5BiF,EAAA;AAAA,EACF,GAAG,CAACjF,GAAQiF,CAAO,CAAC;AAEpB,2BACG,OAAA,EAAI,WAAU,kFACb,UAAA,gBAAApF,EAAC,OAAA,EAAI,WAAU,0GAEb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,6FACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,UACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,SAAA,EAAM,WAAU,mEAAkE,UAAA,gBAEnF;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO80B;AAAA,YACP,UAAU,CAACpzB,MAAMi0B,EAAkBj0B,EAAE,OAAO,KAAK;AAAA,YACjD,WAAU;AAAA,YACV,aAAY;AAAA,UAAA;AAAA,QAAA;AAAA,MACd,GACF;AAAA,MACA,gBAAA1B;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAASyzB;AAAA,UACT,WAAU;AAAA,UAEV,UAAA,gBAAAzzB,EAACsL,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IACjC,GACF;AAAA,IAGA,gBAAAvL,EAAC,OAAA,EAAI,WAAU,+BAEZ,UAAA;AAAA,MAAA,CAACG,EAAO,mBACP,gBAAAF,EAAC,OAAA,EAAI,WAAU,8FACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,OACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,0DAAyD,UAAA,oBAEvE;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS,MAAMm1B,EAAiB,CAACD,CAAa;AAAA,cAC9C,WAAU;AAAA,cACV,OAAOA,IAAgB,+BAA+B;AAAA,cAErD,cACC,gBAAAn1B,EAAAoJ,IAAA,EACE,UAAA;AAAA,gBAAA,gBAAAnJ,EAAC00B,IAAA,EAAW,WAAU,cAAA,CAAc;AAAA,gBACpC,gBAAA10B,EAAC,UAAK,UAAA,YAAA,CAAS;AAAA,cAAA,EAAA,CACjB,IAEA,gBAAAD,EAAAoJ,IAAA,EACE,UAAA;AAAA,gBAAA,gBAAAnJ,EAACy0B,IAAA,EAAQ,WAAU,cAAA,CAAc;AAAA,gBACjC,gBAAAz0B,EAAC,UAAK,UAAA,MAAA,CAAG;AAAA,cAAA,EAAA,CACX;AAAA,YAAA;AAAA,UAAA;AAAA,QAEJ,GACF;AAAA,QAEC,CAACk1B,KACA,gBAAAl1B,EAAC,OAAA,EAAI,WAAU,4FAA2F,UAAA,8CAE1G;AAAA,QAGDq1B,KAAkBA,EAAe,MAAM,SAAS,IAC/C,gBAAAr1B;AAAA,UAACuG;AAAA,UAAA;AAAA,YACC,QAAQ8uB;AAAA,YACR,cAAa;AAAA,YACb,aAAa;AAAA,YACb,gBAAgB;AAAA,cACd,UAAUK,IAAwB,CAACA,CAAqB,IAAI,CAAA;AAAA,cAC5D,YAAYA,IAAwB,CAACA,CAAqB,IAAI,CAAA;AAAA,cAC9D,gBAAgBA,IAAwB,CAACA,CAAqB,IAAI,CAAA;AAAA,YAAC;AAAA,YAErE,eAAe,CAAChrB,MAAc6jB,EAAkB7jB,CAAS;AAAA,YACzD,iBAAiB,MAAM;AAAA,YAAC;AAAA,UAAA;AAAA,QAAA,IAG1B,gBAAA1K,EAAC,OAAA,EAAI,WAAU,6DACZ,UAAAk1B,sBACE,OAAA,EACC,UAAA;AAAA,UAAA,gBAAAl1B,EAAC,KAAA,EAAE,WAAU,QAAO,UAAA,uBAAmB;AAAA,UACvC,gBAAAA,EAAC,KAAA,EAAE,WAAU,WAAU,UAAA,4BAAA,CAAyB;AAAA,QAAA,EAAA,CAClD,sBAEC,OAAA,EACC,UAAA;AAAA,UAAA,gBAAAA,EAAC,KAAA,EAAE,WAAU,QAAO,UAAA,+BAA2B;AAAA,UAC/C,gBAAAA,EAAC,KAAA,EAAE,WAAU,WAAU,UAAA,oEAAA,CAAiE;AAAA,QAAA,EAAA,CAC1F,EAAA,CAEJ;AAAA,MAAA,EAAA,CAEJ,EAAA,CACF;AAAA,MAIF,gBAAAA,EAAC,OAAA,EAAI,WAAU,8DACZ,UAAAE,EAAO;AAAA;AAAA,0BAEL,OAAA,EACC,UAAA;AAAA,UAAA,gBAAAH,EAAC,OAAA,EAAI,WAAU,kGACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,6DAA4D,UAAA,yBAE3E;AAAA,YACA,gBAAAA,EAAC,OAAA,EAAI,WAAU,4CAA2C,UAAA,gJAAA,CAG1D;AAAA,UAAA,GACF;AAAA,UACA,gBAAAA,EAAC,OAAA,EAAI,WAAU,QACb,UAAA,gBAAAA;AAAA,YAAC2X;AAAA,YAAA;AAAA,cACC,eAAc;AAAA,cACd,yBAAyB,CAAC,oBAAoB;AAAA,cAC9C,mBAAmB,MAAM;AAEvB,sBAAMxX,IAAe60B;AACrB,oBAAI70B,EAAa,UAAW,QAAOA,EAAa;AAChD,oBAAIA,EAAa;AAEf,yBAAI,MAAM,QAAQA,EAAa,MAAM,KAAKA,EAAa,OAAO,WAAW,KAAK,OAAOA,EAAa,OAAO,CAAC,KAAM,WACvGA,EAAa,OAAO,CAAC,IAEvBA,EAAa;AAAA,cAGxB,GAAA;AAAA,cACA,mBAAmBgU;AAAA,cACnB,uBAAuB,MAAM;AAAA,cAAC;AAAA,cAC9B,UAAU,MAAM;AAAA,cAAC;AAAA,cACjB,mBAAmB;AAAA,cACnB,kBAAkB;AAAA,YAAA;AAAA,UAAA,EACpB,CACF;AAAA,QAAA,EAAA,CACF;AAAA;AAAA;AAAA,QAGA,gBAAAnU;AAAA,UAAC4W;AAAA,UAAA;AAAA,YACC,SAAS,CAACoe,CAAW;AAAA,YACrB,QAAQH,EAAsBruB,CAAM;AAAA,YACpC,OAAO,CAAA;AAAA,YACP,iBAAiBqvB;AAAA,UAAA;AAAA,QAAA;AAAA,QACnB,CAEJ;AAAA,IAAA,GACF;AAAA,IAGA,gBAAA91B,EAAC,OAAA,EAAI,WAAU,uHACb,UAAA;AAAA,MAAA,gBAAAC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS40B;AAAA,UACT,WAAU;AAAA,UACX,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAGD,gBAAA50B;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAASwzB;AAAA,UACT,WAAU;AAAA,UACX,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ,GC1VMjiB,KAAa9R,EAAQ,QAAQ,GAC7By2B,KAAYz2B,EAAQ,eAAe,GAcnC02B,KAAwD,CAAC;AAAA,EAC7D,kBAAA71B;AAAA,EACA,QAAAkG;AAAA,EACA,gBAAAkL;AAAA,EACA,mBAAAoG;AAAA,EACA,uBAAA+c;AAAA,EACA,sBAAAuB;AACF,MAAM;AAEJ,QAAMC,IAAuBxwB,EAAY,CAACywB,MAAqC;AAC7E,UAAM,EAAE,IAAAj5B,GAAI,OAAAqiB,GAAO,QAAAxf,GAAQ,iBAAAq2B,MAAoBD;AAG/C,QAAI,EAAE,YAAYp2B;AAChB,aAAO;AAGT,UAAMC,IAAeD,GACfs2B,IAAYJ,EAAqBj2B,EAAa,MAAM;AAG1D,QAAIo2B,KAAoBC,KAAar2B,EAAa,aAAa,eAAgB;AAG7E,UAAIs2B,IAAgDt2B,EAAa;AACjE,aAAI,CAACs2B,KAAkBt2B,EAAa,WAC9B,MAAM,QAAQA,EAAa,MAAM,KAAKA,EAAa,OAAO,WAAW,KAAK,OAAOA,EAAa,OAAO,CAAC,KAAM,WAE9Gs2B,IAAiBt2B,EAAa,OAAO,CAAC,IAEtCs2B,IAAiBt2B,EAAa,SAKhC,gBAAAJ,EAAC,OAAA,EAAa,WAAU,yBACtB,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCACZ,UAAA;AAAA,UAAAw2B,KACC,gBAAAv2B,EAACk2B,MAAU,WAAU,wBAAuB,OAAO,EAAE,OAAO,uBAAuB;AAAA,UAErF,gBAAAl2B;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,2BAAA;AAAA,cAChB,OAAOu2B,IAAkB,GAAG7W,CAAK,sCAAsCA;AAAA,cAEtE,UAAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QACH,GACF;AAAA,QACA,gBAAA1f;AAAA,UAAC2X;AAAA,UAAA;AAAA,YACC,eAAe4e,IAAkB,uBAAuBp2B,EAAa;AAAA,YACrE,yBAAyBo2B,IAAkB,CAAC,oBAAoB,IAAI,CAACp2B,EAAa,MAAM;AAAA,YACxF,kBAAkBs2B;AAAA,YAClB,mBAAmB,CAACX,GAAU7zB,MAAc6V,EAAkBza,GAAI4E,CAAS;AAAA,YAC3E,uBAAuB,MAAM;AAAA,YAAC;AAAA,YAC9B,UAAU,MAAM;AAAA,YAAC;AAAA,YACjB,mBAAmB;AAAA,YACnB,kBAAkB;AAAA,UAAA;AAAA,QAAA;AAAA,MACpB,EAAA,GAtBQ5E,CAuBV;AAAA,IAEJ;AAGA,WACE,gBAAA0C,EAAC,OAAA,EAAa,WAAU,yBACtB,UAAA;AAAA,MAAA,gBAAAC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,EAAE,OAAO,2BAAA;AAAA,UAChB,OAAO0f;AAAA,UAEN,UAAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAEH,gBAAA1f;AAAA,QAACyR;AAAA,QAAA;AAAA,UACC,QAAQtR;AAAA,UACR,OAAO;AAAA,UACP,gBAAgB,CAACu2B,GAAQT,MAAkB;AACzC,YAAAvkB,EAAerU,GAAI;AAAA,cACjB,GAAGi5B;AAAA,cACH,QAAQL;AAAA,YAAA,CACT;AAAA,UACH;AAAA,UACA,gBAAgB,MAAM;AAAA,UAAC;AAAA,UACvB,QAAQpB,EAAsBruB,CAAM;AAAA,UACpC,OAAO,CAAA;AAAA,UACP,mBAAmB;AAAA,UACnB,sBAAsB;AAAA,UACtB,kBAAkB;AAAA,QAAA;AAAA,MAAA;AAAA,IACpB,EAAA,GAvBQnJ,CAwBV;AAAA,EAEJ,GAAG,CAACmJ,GAAQquB,GAAuBuB,GAAsB1kB,GAAgBoG,CAAiB,CAAC;AAE3F,SAAIxX,EAAiB,WAAW,IACvB,OAIP,gBAAAP,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,gCACb,UAAA;AAAA,MAAA,gBAAAC,EAACuR,MAAW,WAAU,oBAAmB,OAAO,EAAE,OAAO,uBAAuB;AAAA,MAChF,gBAAAvR,EAAC,QAAG,WAAU,yBAAwB,OAAO,EAAE,OAAO,iBAAA,GAAoB,UAAA,UAAA,CAE1E;AAAA,MACCM,EAAiB,SAAS,KACzB,gBAAAN;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,iBAAiB;AAAA,YACjB,OAAO;AAAA,UAAA;AAAA,UAGR,UAAAM,EAAiB;AAAA,QAAA;AAAA,MAAA;AAAA,IACpB,GAEJ;AAAA,sBACC,OAAA,EAAI,WAAU,wDACZ,UAAAA,EAAiB,IAAI+1B,CAAoB,EAAA,CAC5C;AAAA,EAAA,GACF;AAEJ,GCvIM9kB,KAAa9R,EAAQ,QAAQ,GAC7BoV,KAAUpV,EAAQ,KAAK,GACvB6L,KAAY7L,EAAQ,OAAO,GAC3Bk3B,KAAWl3B,EAAQ,MAAM,GACzByH,KAAkBzH,EAAQ,aAAa,GACvCy2B,KAAYz2B,EAAQ,eAAe,GAYnCm3B,KAAwD,CAAC;AAAA,EAC7D,kBAAAt2B;AAAA,EACA,aAAAu2B;AAAA,EACA,iBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,gBAAAC;AACF,MAAM;AACJ,QAAM,CAACC,GAAaC,CAAc,IAAI1uB,GAAM,SAAS,EAAK,GAGpD2uB,IAAmB,CAACf,MAAqC;AAC7D,UAAM,EAAE,IAAAj5B,GAAI,OAAAqiB,GAAO,iBAAA6W,EAAA,IAAoBD,GACjCrsB,IAAagtB,MAAqB55B;AAKxC,WACE,gBAAA0C;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAW;AAAA,QAGX,OAAO;AAAA,UACL,iBAAiBkK,IAAa,sBAAsB;AAAA,UACpD,aAAaA,IAAa,sBAAsB;AAAA,UAChD,aAAaA,IAAa,QAAQ;AAAA,UAClC,OAAOA,IAAa,UAAU;AAAA,UAC9B,WAAWA,IAAa,+CAA+C;AAAA,QAAA;AAAA,QAEzE,SAAS,MAAM;AACb,UAAIitB,KACFA,EAAe75B,CAAE;AAAA,QAErB;AAAA,QAEA,UAAA;AAAA,UAAA,gBAAA2C;AAAA,YArBkBu2B,IAAkBL,KAAY3kB;AAAAA,YAqB/C;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,OAAOtH,IAAa,UAAU,oBAAA;AAAA,YAAoB;AAAA,UAAA;AAAA,UAE7D,gBAAAjK,EAAC,QAAA,EAAK,WAAU,wBAAwB,UAAA0f,GAAM;AAAA,UAE7C,CAACzV,KACA,gBAAAlK,EAAC,OAAA,EAAI,WAAU,kCAAiC,SAAS,CAAC2B,MAAMA,EAAE,gBAAA,GAChE,UAAA;AAAA,YAAA,gBAAA1B;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAM+2B,EAAa15B,CAAE;AAAA,gBAC9B,WAAU;AAAA,gBACV,OAAM;AAAA,gBAEN,UAAA,gBAAA2C,EAAC22B,IAAA,EAAS,WAAU,UAAA,CAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAEhC,gBAAA32B;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAMg3B,EAAe35B,CAAE;AAAA,gBAChC,WAAU;AAAA,gBACV,OAAM;AAAA,gBAEN,UAAA,gBAAA2C,EAACsL,IAAA,EAAU,WAAU,UAAA,CAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UACjC,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,MAvCGjO;AAAA,IAAA;AAAA,EA2CX;AAEA,SACE,gBAAA0C,EAAAoJ,IAAA,EAEE,UAAA;AAAA,IAAA,gBAAApJ,EAAC,OAAA,EAAI,WAAU,aAEb,UAAA;AAAA,MAAA,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,SAAS,MAAMq3B,EAAe,CAACD,CAAW;AAAA,UAE1C,UAAA;AAAA,YAAA,gBAAAp3B,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,cAAA,gBAAAC,EAACuR,MAAW,WAAU,oBAAmB,OAAO,EAAE,OAAO,uBAAuB;AAAA,cAChF,gBAAAvR,EAAC,QAAG,WAAU,yBAAwB,OAAO,EAAE,OAAO,iBAAA,GAAoB,UAAA,UAAA,CAE1E;AAAA,cACCM,EAAiB,SAAS,KACzB,gBAAAN;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,iBAAiB;AAAA,oBACjB,OAAO;AAAA,kBAAA;AAAA,kBAGR,UAAAM,EAAiB;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGtB,gBAAAN;AAAA,gBAACkH;AAAA,gBAAA;AAAA,kBACC,WAAW,gCAAgCiwB,IAAc,KAAK,YAAY;AAAA,kBAC1E,OAAO,EAAE,OAAO,2BAAA;AAAA,gBAA2B;AAAA,cAAA;AAAA,YAC7C,GACF;AAAA,YAEA,gBAAAp3B,EAAC,OAAA,EAAI,WAAU,2BAEZ,UAAA;AAAA,cAAA,CAACO,EAAiB,KAAK,CAAAF,MAAKA,EAAE,eAAe,KAC5C,gBAAAL;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,SAAS,CAAC2B,MAAM;AACd,oBAAAA,EAAE,gBAAA,GACFo1B,EAAA;AAAA,kBACF;AAAA,kBACA,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,iBAAiB;AAAA,oBACjB,OAAO;AAAA,oBACP,QAAQ;AAAA,kBAAA;AAAA,kBAEV,OAAM;AAAA,kBAEN,UAAA;AAAA,oBAAA,gBAAA92B,EAAC6U,IAAA,EAAQ,WAAU,cAAA,CAAc;AAAA,oBACjC,gBAAA7U,EAACk2B,IAAA,EAAU,WAAU,cAAA,CAAc;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGvC,gBAAAl2B;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,SAAS,CAAC0B,MAAM;AACd,oBAAAA,EAAE,gBAAA,GACFm1B,EAAA;AAAA,kBACF;AAAA,kBACA,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,iBAAiB;AAAA,oBACjB,OAAO;AAAA,kBAAA;AAAA,kBAGT,UAAA,gBAAA72B,EAAC6U,IAAA,EAAQ,WAAU,cAAA,CAAc;AAAA,gBAAA;AAAA,cAAA;AAAA,YACnC,EAAA,CACF;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAIDvU,EAAiB,SAAS,KAAK,CAAC62B,KAC/B,gBAAAn3B,EAAC,OAAA,EAAI,WAAU,iCACZ,UAAAM,EAAiB,IAAI+2B,CAAgB,EAAA,CACxC;AAAA,MAID/2B,EAAiB,WAAW,KAAK,CAAC62B,KACjC,gBAAAn3B,EAAC,OAAA,EAAI,WAAU,aACb,UAAA,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,iBAAiB;AAAA,YACjB,OAAO;AAAA,UAAA;AAAA,UAEV,UAAA;AAAA,QAAA;AAAA,MAAA,EAED,CACF;AAAA,IAAA,GAEJ;AAAA,IAGA,gBAAAD,EAAC,OAAA,EAAI,WAAU,qDAEb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oCACb,UAAA;AAAA,QAAA,gBAAAC,EAACuR,MAAW,WAAU,oBAAmB,OAAO,EAAE,OAAO,uBAAuB;AAAA,QAChF,gBAAAvR,EAAC,QAAG,WAAU,2CAA0C,OAAO,EAAE,OAAO,iBAAA,GAAoB,UAAA,UAAA,CAE5F;AAAA,QACCM,EAAiB,SAAS,KACzB,gBAAAN;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,iBAAiB;AAAA,cACjB,OAAO;AAAA,YAAA;AAAA,YAGR,UAAAM,EAAiB;AAAA,UAAA;AAAA,QAAA;AAAA,MACpB,GAEJ;AAAA,MAGCA,EAAiB,SAAS,IACzB,gBAAAN,EAAC,SAAI,WAAU,uCACZ,UAAAM,EAAiB,IAAI+2B,CAAgB,EAAA,CACxC,IAEA,gBAAAr3B,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,iBAAiB;AAAA,YACjB,OAAO;AAAA,UAAA;AAAA,UAEV,UAAA;AAAA,QAAA;AAAA,MAAA,GAGH;AAAA,MAIF,gBAAAD,EAAC,OAAA,EAAI,WAAU,oCAEZ,UAAA;AAAA,QAAA,CAACO,EAAiB,KAAK,CAAAF,MAAKA,EAAE,eAAe,KAC5C,gBAAAL;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS+2B;AAAA,YACT,WAAU;AAAA,YACV,OAAO;AAAA,cACL,iBAAiB;AAAA,cACjB,OAAO;AAAA,cACP,QAAQ;AAAA,YAAA;AAAA,YAEV,OAAM;AAAA,YAEN,UAAA;AAAA,cAAA,gBAAA92B,EAAC6U,IAAA,EAAQ,WAAU,cAAA,CAAc;AAAA,cACjC,gBAAA7U,EAAC,UAAK,UAAA,aAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGpB,gBAAAD;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS82B;AAAA,YACT,WAAU;AAAA,YACV,OAAO;AAAA,cACL,iBAAiB;AAAA,cACjB,OAAO;AAAA,YAAA;AAAA,YAGT,UAAA;AAAA,cAAA,gBAAA72B,EAAC6U,IAAA,EAAQ,WAAU,cAAA,CAAc;AAAA,cACjC,gBAAA7U,EAAC,UAAK,UAAA,SAAA,CAAM;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACd,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ,GChOMs3B,KAA4D,CAAC;AAAA,EACjE,kBAAAh3B;AAAA,EACA,UAAAi3B;AAAA,EACA,QAAA/wB;AAAA,EACA,iBAAAzF;AAAA,EACA,0BAAAy2B;AAAA,EACA,eAAAC;AAAA,EACA,kBAAAR;AAAA,EACA,gBAAAC;AAAA,EACA,YAAApE,IAAa;AACf,MAAM;AAEJ,QAAM,CAAC4E,GAAeC,CAAgB,IAAI10B,EAAiC,IAAI,GACzE,CAAC20B,GAAmBC,CAAoB,IAAI50B,EAAS,EAAK,GAG1D4xB,IAAwBhvB,EAAY,CAACiyB,MACpCA,IAEE;AAAA,IACL,OAAOA,EAAS,MAAM,IAAI,CAAAjvB,OAAS;AAAA,MACjC,MAAMA,EAAK;AAAA,MACX,OAAOA,EAAK,SAASA,EAAK;AAAA,MAC1B,aAAaA,EAAK,eAAe;AAAA,MACjC,UAAUA,EAAK,SAAS,IAAI,CAAAyG,OAAM;AAAA,QAChC,MAAMA,EAAE;AAAA,QACR,OAAOA,EAAE;AAAA,QACT,MAAMA,EAAE;AAAA,QACR,aAAa;AAAA,QACb,YAAYA,EAAE;AAAA,MAAA,EACd;AAAA,MACF,YAAYzG,EAAK,WAAW,IAAI,CAAAE,OAAM;AAAA,QACpC,MAAMA,EAAE;AAAA,QACR,OAAOA,EAAE;AAAA,QACT,MAAMA,EAAE;AAAA,QACR,aAAa;AAAA,QACb,YAAYA,EAAE;AAAA,MAAA,EACd;AAAA,MACF,UAAUF,EAAK,UAAU,IAAI,CAAAkvB,OAAM;AAAA,QACjC,MAAMA,EAAE;AAAA,QACR,OAAOA,EAAE;AAAA,QACT,MAAMA,EAAE;AAAA,QACR,aAAa;AAAA,QACb,YAAYA,EAAE;AAAA,MAAA,EACd,KAAK,CAAA;AAAA,IAAC,EACR;AAAA,EAAA,IA5BkB,MA8BrB,CAAA,CAAE,GAGCC,IAAmBnyB,EAAY,MAC5B,MAAM,KAAK,IAAA,CAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,CAAC,CAAC,IACjE,CAAA,CAAE,GAGCoyB,IAAkBpyB,EAAY,MAAM;AACxC,UAAMmQ,IAA6B;AAAA,MACjC,IAAIgiB,EAAA;AAAA,MACJ,OAAO,UAAU13B,EAAiB,SAAS,CAAC;AAAA,MAC5C,QAAQ;AAAA,QACN,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,QAAQ,CAAA;AAAA,MAAC;AAAA,IACX;AAEF,IAAAq3B,EAAiB3hB,CAAS,GAC1B6hB,EAAqB,EAAI;AAAA,EAC3B,GAAG,CAACv3B,EAAiB,QAAQ03B,CAAgB,CAAC,GAIxCE,IAAsBryB,EAAY,MAAM;AAC5C,UAAMmQ,IAA6B;AAAA,MACjC,IAAIgiB,EAAA;AAAA,MACJ,OAAO;AAAA,MACP,iBAAiB;AAAA,MACjB,QAAQ;AAAA,QACN,QAAQ;AAAA;AAAA,QACR,UAAU;AAAA,QACV,QAAQ,CAAC,cAAc;AAAA,MAAA;AAAA,IACzB,GAGIG,IAAiB,CAAC,GAAG73B,GAAkB0V,CAAS;AACtD,IAAAwhB,EAAyBW,CAAc;AAAA,EACzC,GAAG,CAACH,GAAkB13B,GAAkBk3B,CAAwB,CAAC,GAG3DY,IAAmBvyB,EAAY,CAAC0tB,MAAqB;AACzD,UAAM8E,IAAe/3B,EAAiB,KAAK,CAAAE,MAAMA,EAAG,OAAO+yB,CAAQ;AACnE,IAAI8E,MACFV,EAAiBU,CAAY,GAC7BR,EAAqB,EAAI;AAAA,EAE7B,GAAG,CAACv3B,CAAgB,CAAC,GAGfg4B,IAAqBzyB,EAAY,CAAC0tB,MAAqB;AAC3D,UAAM4E,IAAiB73B,EAAiB,OAAO,CAAAE,MAAMA,EAAG,OAAO+yB,CAAQ;AACvE,IAAAiE,EAAyBW,CAAc,GAGnCT,GAAe,OAAOnE,MACxBoE,EAAiB,IAAI,GACrBE,EAAqB,EAAK;AAAA,EAE9B,GAAG,CAACv3B,GAAkBo3B,GAAeF,CAAwB,CAAC,GAGxDe,IAAmB1yB,EAAY,OAAO2yB,MAAgC;AAE1E,UAAMC,IAAsBn4B,EAAiB,UAAU,OAAKF,EAAE,OAAOo4B,EAAW,EAAE;AAElF,QAAIL;AAeJ,QAdIM,KAAuB,IAEzBN,IAAiB73B,EAAiB;AAAA,MAAI,CAAAF,MACpCA,EAAE,OAAOo4B,EAAW,KAAKA,IAAap4B;AAAA,IAAA,IAIxC+3B,IAAiB,CAAC,GAAG73B,GAAkBk4B,CAAU,GAInDhB,EAAyBW,CAAc,GAGnCV;AACF,UAAI;AACF,cAAMA,EAAcU,CAAc;AAAA,MACpC,SAASt4B,GAAO;AACd,sBAAQ,MAAM,2BAA2BA,CAAK,GACxCA;AAAA,MACR;AAAA,EAEJ,GAAG,CAACS,GAAkBk3B,GAA0BC,CAAa,CAAC,GAGxDiB,IAA2B7yB,EAAY,MAAM;AACjD,IAAA8xB,EAAiB,IAAI,GACrBE,EAAqB,EAAK;AAAA,EAC5B,GAAG,CAAA,CAAE,GAGCc,IAA8B9yB,EAAY,CAAC0tB,GAAkBtxB,MAAiC;AAClG,UAAMk2B,IAAiB73B,EAAiB,IAAI,CAAAE,MAAM;AAChD,UAAIA,EAAG,OAAO+yB,GAAU;AACtB,cAAMrzB,IAASM,EAAG;AAClB,YAAI,YAAYN;AACd,iBAAO;AAAA,YACL,GAAGM;AAAA,YACH,QAAQ;AAAA,cACN,GAAGN;AAAA,cACH,WAAA+B;AAAA,cACA,QAAQ,MAAM,QAAQA,CAAS,IAAIA,IAAY,CAACA,CAAS;AAAA,YAAA;AAAA,UAC3D;AAAA,MAGN;AACA,aAAOzB;AAAA,IACT,CAAC;AACD,IAAAg3B,EAAyBW,CAAc;AAAA,EACzC,GAAG,CAAC73B,GAAkBk3B,CAAwB,CAAC,GAGzCoB,IAA6B/yB,EAAY,CAAC0tB,GAAkB0C,MAAmC;AACnG,UAAMkC,IAAiB73B,EAAiB;AAAA,MAAI,CAAAE,MAC1CA,EAAG,OAAO+yB,IAAW0C,IAAgBz1B;AAAA,IAAA;AAEvC,IAAAg3B,EAAyBW,CAAc;AAAA,EACzC,GAAG,CAAC73B,GAAkBk3B,CAAwB,CAAC,GAGzCpB,IAAuBvwB,EAAY,CAAC6E,MACnClE,IACEA,EAAO,MAAM;AAAA,IAAK,CAAAqC,MACvBA,EAAK,WAAW,KAAK,CAAAyD,MAAOA,EAAI,SAAS5B,KAAa4B,EAAI,SAAS,MAAM;AAAA,EAAA,IAFvD,IAInB,CAAC9F,CAAM,CAAC;AAQX,SALI,CAAC+wB,KAKD,CAACzE,KAAcxyB,EAAiB,WAAW,IACtC,OAIP,gBAAAP;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO;AAAA,QACL,aAAa;AAAA,QACb,iBAAiB;AAAA,QACjB,WAAW;AAAA,MAAA;AAAA,MAIZ,UAAA;AAAA,QAAA+yB,IACC,gBAAA9yB;AAAA,UAAC42B;AAAA,UAAA;AAAA,YACC,kBAAAt2B;AAAA,YACA,aAAa23B;AAAA,YACb,iBAAiBC;AAAA,YACjB,cAAcE;AAAA,YACd,gBAAgBE;AAAA,YAChB,kBAAArB;AAAA,YACA,gBAAAC;AAAA,UAAA;AAAA,QAAA;AAAA;AAAA,UAIF,gBAAAl3B;AAAA,YAACm2B;AAAA,YAAA;AAAA,cACC,kBAAA71B;AAAA,cACA,QAAAkG;AAAA,cACA,gBAAgBoyB;AAAA,cAChB,mBAAmBD;AAAA,cACnB,uBAAA9D;AAAA,cACA,sBAAAuB;AAAA,YAAA;AAAA,UAAA;AAAA;AAAA,QAKHmB,KAAYK,KAAqBF,KAChC,gBAAA13B;AAAA,UAAC20B;AAAA,UAAA;AAAA,YACC,QAAQ+C;AAAA,YACR,QAAAlxB;AAAA,YACA,iBAAAzF;AAAA,YACA,QAAQ62B;AAAA,YACR,QAAQW;AAAA,YACR,SAASG;AAAA,YACT,UAAU,MAAMJ,EAAmBZ,EAAc,EAAE;AAAA,YACnD,uBAAA7C;AAAA,UAAA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAAA;AAIR;AC5PA,SAAwBgE,GAAkB;AAAA,EACxC,aAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAtzB;AACF,GAA2B;AACzB,QAAM,CAACuzB,GAAcC,CAAe,IAAIh2B,EAAS,CAAC,GAC5Ci2B,IAAW/1B,GAAuB,IAAI;AAG5C,EAAAK,GAAU,MAAM;AACd,QAAI,CAAC01B,EAAS,QAAS;AAEvB,UAAMz7B,IAAW,IAAI,eAAe,CAACC,MAAY;AAC/C,MAAAu7B,EAAgBv7B,EAAQ,CAAC,GAAG,YAAY,UAAU,CAAC;AAAA,IACrD,CAAC;AAED,WAAAD,EAAS,QAAQy7B,EAAS,OAAO,GAGjCD,EAAgBC,EAAS,QAAQ,gBAAgB,CAAC,GAE3C,MAAMz7B,EAAS,WAAA;AAAA,EACxB,GAAG,CAAA,CAAE;AAGL,QAAM07B,IAAeH,IAAeF;AAEpC,SACE,gBAAA94B;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO;AAAA,QACL,QAAQm5B,IAAe,IAAIA,IAAe;AAAA,QAC1C,UAAU;AAAA,QACV,OAAO;AAAA,MAAA;AAAA,MAGT,UAAA,gBAAAn5B;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAKk5B;AAAA,UACL,WAAU;AAAA,UACV,OAAO;AAAA,YACL,WAAW,SAASJ,CAAW;AAAA,YAC/B,iBAAiB;AAAA,YACjB,OAAOC;AAAA,UAAA;AAAA,UAGR,UAAAtzB;AAAA,QAAA;AAAA,MAAA;AAAA,IACH;AAAA,EAAA;AAGN;ACzDA,MAAMjG,KAAcC,EAAQ,SAAS;AAQrC,SAAS25B,GAAuBn7B,GAAiD;AAC/E,MAAI,CAACA,EAAS,QAAO;AAErB,MAAIqT,IAAUrT,EAAQ;AAEtB,SAAOqT,KAAS;AACd,UAAM+nB,IAAQ,OAAO,iBAAiB/nB,CAAO,GACvCgoB,IAAYD,EAAM,WAClBE,IAAYF,EAAM,WAElBG,IACJF,MAAc,UAAUA,MAAc,YACtCC,MAAc,UAAUA,MAAc,UAElCE,IACJnoB,EAAQ,eAAeA,EAAQ,gBAC/BA,EAAQ,cAAcA,EAAQ;AAEhC,QAAIkoB,KAAyBC;AAC3B,aAAOnoB;AAGT,QAAIA,MAAY,SAAS,KAAM;AAC/B,IAAAA,IAAUA,EAAQ;AAAA,EACpB;AAEA,SAAO;AACT;AAaA,SAAwBooB,GAAoB;AAAA,EAC1C,QAAAja;AAAA,EACA,cAAA7c;AAAA,EACA,kBAAAtC;AAAA,EACA,kBAAAq5B;AACF,GAA6B;AAC3B,QAAMC,IAAuBz2B,GAA0D,EAAE,GAGnF,CAACC,GAAiBy2B,CAAkB,IAAI52B,EAA6B,IAAI,GACzEsP,IAAepP,GAA8B,IAAI,GAEjD22B,IAAkBj0B,EAAY,CAACk0B,MAAgC;AACnE,IAAAxnB,EAAa,UAAUwnB,GACnBA,KACFF,EAAmBT,GAAuBW,CAAI,CAAC;AAAA,EAEnD,GAAG,CAAA,CAAE,GAGCC,IAAiBn2B,GAAQ,MACtB,CAAC,GAAG4b,EAAO,QAAQ,EAAE,KAAK,CAAC3Q,GAAGC,MAC/BD,EAAE,MAAMC,EAAE,IAAUD,EAAE,IAAIC,EAAE,IACzBD,EAAE,IAAIC,EAAE,CAChB,GACA,CAAC0Q,EAAO,QAAQ,CAAC,GAEdwa,IAAuB,CAACC,MAAsB;AAElD,IAAAN,EAAqB,QAAQM,CAAS,GAAG,QAAA,GAEzCP,IAAmBO,CAAS;AAAA,EAC9B;AAEA,SACE,gBAAAl6B,EAACm6B,IAAA,EAAwB,OAAO/2B,GAC9B,UAAA,gBAAApD,EAAC,OAAA,EAAI,KAAK85B,GAAiB,WAAU,wCAClC,UAAAE,EAAe,IAAI,CAAA74B,MAAW;AAE/B,UAAMi5B,IAAgB,KAAK,IAAI,KAAKj5B,EAAQ,IAAI,EAAE,GAE5Ck5B,IAAel5B,EAAQ,eAAe,aAAa,IAAI,IAEvDm5B,IAAgBF,IAAgBC,IAAe;AAErD,WACE,gBAAAt6B;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,mBAAiBoB,EAAQ;AAAA,QACzB,WAAU;AAAA,QACV,OAAO;AAAA,UACL,QAAQi5B;AAAA,UACR,WAAW;AAAA,QAAA;AAAA,QAIZ,UAAA;AAAA,UAAA,CAACj5B,EAAQ,eAAe,cACvB,gBAAApB,EAAC,OAAA,EAAI,WAAU,uHACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,sDACX,UAAAmB,EAAQ,OACX;AAAA,YACA,gBAAAnB,EAAC,OAAA,EAAI,WAAU,yCACb,UAAA,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAMi6B,EAAqB94B,EAAQ,EAAE;AAAA,gBAC9C,WAAU;AAAA,gBACV,OAAM;AAAA,gBAEN,UAAA,gBAAAnB,EAACR,IAAA,EAAY,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,OAAO,eAAA,EAAe,CAAG;AAAA,cAAA;AAAA,YAAA,EAChF,CACF;AAAA,UAAA,GACF;AAAA,UAIF,gBAAAQ;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,QAAQs6B,EAAA;AAAA,cAEjB,UAAA,gBAAAt6B;AAAA,gBAACkC;AAAA,gBAAA;AAAA,kBACC,KAAK,CAAAq4B,MAAM;AAAE,oBAAAX,EAAqB,QAAQz4B,EAAQ,EAAE,IAAIo5B;AAAA,kBAAG;AAAA,kBAC3D,OAAOp5B,EAAQ;AAAA,kBACf,WAAWA,EAAQ;AAAA,kBACnB,aAAaA,EAAQ;AAAA,kBACrB,eAAeA,EAAQ;AAAA,kBACvB,kBAAAb;AAAA,kBACA,wBAAwBa,EAAQ;AAAA,kBAChC,WAAWA,EAAQ,aAAase,EAAO,aAAa;AAAA,kBACpD,OAAOte,EAAQ;AAAA,kBACf,QAAQm5B;AAAA,kBACR,cAAA13B;AAAA,gBAAA;AAAA,cAAA;AAAA,YACF;AAAA,UAAA;AAAA,QACF;AAAA,MAAA;AAAA,MA5CKzB,EAAQ;AAAA,IAAA;AAAA,EA+CnB,CAAC,GACD,GACF;AAEJ;ACjJA,MAAMq5B,KAAe/6B,EAAQ,SAAS,GAChCD,KAAcC,EAAQ,SAAS,GAC/Bk3B,KAAWl3B,EAAQ,MAAM,GACzB4c,KAAa5c,EAAQ,QAAQ,GAC7BoV,KAAUpV,EAAQ,KAAK,GACvB6c,KAAW7c,EAAQ,MAAM,GACzB8R,KAAa9R,EAAQ,QAAQ,GAC7Bg7B,KAAch7B,EAAQ,SAAS;AAgBrC,SAAS25B,GAAuBn7B,GAAiD;AAC/E,MAAI,CAACA,EAAS,QAAO;AAErB,MAAIqT,IAAUrT,EAAQ;AAEtB,SAAOqT,KAAS;AACd,UAAM+nB,IAAQ,OAAO,iBAAiB/nB,CAAO,GACvCgoB,IAAYD,EAAM,WAClBE,IAAYF,EAAM,WAElBG,IACJF,MAAc,UAAUA,MAAc,YACtCC,MAAc,UAAUA,MAAc,UAElCE,IACJnoB,EAAQ,eAAeA,EAAQ,gBAC/BA,EAAQ,cAAcA,EAAQ;AAEhC,QAAIkoB,KAAyBC;AAC3B,aAAOnoB;AAGT,QAAIA,MAAY,SAAS,KAAM;AAC/B,IAAAA,IAAUA,EAAQ;AAAA,EACpB;AAEA,SAAO;AACT;AAmBA,SAAwBopB,GAAc;AAAA,EACpC,QAAAjb;AAAA,EACA,UAAA8X,IAAW;AAAA,EACX,kBAAAj3B;AAAA,EACA,kBAAAuC;AAAA,EACA,gBAAA8iB;AAAA,EACA,kBAAAgU;AAAA,EACA,QAAAvJ;AAAA,EACA,cAAAxtB;AAAA,EACA,QAAA4D;AAAA,EACA,0BAAAgxB;AACF,GAAuB;AAErB,QAAM;AAAA,IACJ,cAAAjlB;AAAA,IACA,gBAAAooB;AAAA,IACA,aAAAC;AAAA,IACA,aAAA9B;AAAA,IACA,YAAY+B;AAAA,IACZ,aAAA9B;AAAA,EAAA,IACE+B,GAAA,GAIE,CAAC13B,GAAiBy2B,CAAkB,IAAI52B,EAA6B,IAAI,GACzE83B,IAAsB53B,GAA8B,IAAI;AAG9D,EAAAK,GAAU,MAAM;AACd,IAAIu3B,EAAoB,WACtBlB,EAAmBT,GAAuB2B,EAAoB,OAAO,CAAC;AAAA,EAE1E,GAAG,CAAA,CAAE;AAGL,QAAMC,IAAuBn1B,EAAY,CAACk0B,MAAgC;AACxE,IAAAgB,EAAoB,UAAUhB,GAC9BxnB,EAAawnB,CAAI,GACbA,KACFF,EAAmBT,GAAuBW,CAAI,CAAC;AAAA,EAEnD,GAAG,CAACxnB,CAAY,CAAC,GAKX0oB,IAAYL,MAAgB,YAAYD,IAAiB5B,GAGzDmC,IAAc/3B,GAAiD,EAAE,GACjEy2B,IAAuBz2B,GAA0D,EAAE,GAGnF,CAACg4B,GAAeC,CAAgB,IAAIn4B,EAAS,EAAK,GAClD,CAACo4B,GAAiBC,CAAkB,IAAIr4B,EAAgB,CAAA,CAAE,GAG1D,CAAC6vB,GAAYyI,CAAa,IAAIt4B,EAAS,EAAK,GAG5C,CAACg0B,GAAkBuE,CAAmB,IAAIv4B,EAAwB,IAAI;AAG5E,EAAAO,GAAU,MAAM;AACd,KAAK,CAACsvB,KAAc,CAAC+H,MAAyB5D,KAC5CuE,EAAoB,IAAI;AAAA,EAE5B,GAAG,CAAC1I,GAAY+H,GAAsB5D,CAAgB,CAAC,GAGvDzzB,GAAU,MAAM;AACd,IAAI,CAACq3B,KAAwB/H,KAC3ByI,EAAc,EAAK;AAAA,EAEvB,GAAG,CAACV,GAAsB/H,CAAU,CAAC;AAGrC,QAAM,CAAC2I,GAAYC,CAAa,IAAIz4B,EAAS,EAAK,GAG5C,CAAC04B,GAAoBC,CAAqB,IAAI34B,EAAS,EAAK,GAC5D,CAAC44B,IAAgBC,EAAiB,IAAI74B,EAA+B,IAAI,GACzE,CAAC84B,IAAyBC,EAA0B,IAAI/4B,EAAS,EAAK,GACtE,CAACg5B,IAAqBC,EAAsB,IAAIj5B,EAA+B,IAAI,GAGnF,CAACk5B,IAAWC,CAAY,IAAIn5B,EAM7B,CAAA,CAAE;AAGP,EAAAO,GAAU,MAAM;AAEd,UAAMswB,IAAQ,WAAW,MAAM;AAC7B,MAAAsH,EAAiB,EAAI;AAErB,YAAMiB,IAAgB5c,EAAO,SAAS,IAAI,CAAAte,QAAY;AAAA,QACpD,GAAGA,GAAQ;AAAA,QACX,GAAGA,GAAQ;AAAA,QACX,GAAGA,GAAQ;AAAA,QACX,GAAGA,GAAQ;AAAA,QACX,GAAGA,GAAQ;AAAA,MAAA,EACX;AACF,MAAAm6B,EAAmBe,CAAa;AAAA,IAClC,GAAG,GAAG;AAEN,WAAO,MAAM,aAAavI,CAAK;AAAA,EACjC,GAAG,CAACrU,EAAO,QAAQ,CAAC,GAGpBjc,GAAU,MAAM;AACd,UAAM84B,IAAe,MAAM;AACzB,YAAMC,IAAY,OAAO,eAAe,SAAS,gBAAgB;AACjE,MAAAb,EAAca,IAAY,EAAE;AAAA,IAC9B;AAEA,kBAAO,iBAAiB,UAAUD,GAAc,EAAE,SAAS,IAAM,GAGjEA,EAAA,GAEO,MAAM;AACX,aAAO,oBAAoB,UAAUA,CAAY;AAAA,IACnD;AAAA,EACF,GAAG,CAAA,CAAE,GAGL94B,GAAU,MAAM;AACd,UAAMqkB,IAAgB,CAACnmB,MAAqB;AAC1C,MAAIA,EAAE,QAAQ,YAAYu1B,KACxBuE,EAAoB,IAAI;AAAA,IAE5B;AAEA,kBAAO,iBAAiB,WAAW3T,CAAa,GAEzC,MAAM;AACX,aAAO,oBAAoB,WAAWA,CAAa;AAAA,IACrD;AAAA,EACF,GAAG,CAACoP,CAAgB,CAAC;AAGrB,QAAMuF,IAA2B32B,EAAY,CAAC42B,MAAqB;AACjE,QAAI,CAACtB,KAAiBE,EAAgB,WAAW,EAAG,QAAO;AAG3D,eAAWqB,KAAWD,GAAW;AAC/B,YAAME,KAAUtB,EAAgB,KAAK,OAAQuB,EAAK,MAAMF,EAAQ,CAAC;AACjE,UAAKC,OAEDA,GAAQ,MAAMD,EAAQ,KAAKC,GAAQ,MAAMD,EAAQ,KACjDC,GAAQ,MAAMD,EAAQ,KAAKC,GAAQ,MAAMD,EAAQ;AACnD,eAAO;AAAA,IAEX;AACA,WAAO;AAAA,EACT,GAAG,CAACvB,GAAeE,CAAe,CAAC,GAE7BwB,KAAqBh3B,EAAY,CAACi3B,MAAoB;AAAA,EAO5D,GAAG,CAAA,CAAE,GAGCC,KAAiBl3B,EAAY,OAAOm3B,GAAgBC,GAA6BC,IAA6BC,GAAiCC,GAAWC,MAAsC;AACpM,QAAI,CAAC9F,KAAY,CAACzE,KAAc,CAAC1C,KAAU,CAAC+K,EAAe;AAI3D,UAAMmC,IAAgB,CAAC,GAAGN,CAAM;AAChC,QAAI,CAACR,EAAyBc,CAAa;AACzC;AAIF,UAAMC,IAAkB9d,EAAO,SAAS,IAAI,CAAAte,OAAW;AACrD,YAAMq8B,KAAaF,EAAc,KAAK,QAAQV,GAAK,MAAMz7B,GAAQ,EAAE;AACnE,aAAIq8B,KACK;AAAA,QACL,GAAGr8B;AAAA,QACH,GAAGq8B,GAAW;AAAA,QACd,GAAGA,GAAW;AAAA,QACd,GAAGA,GAAW;AAAA,QACd,GAAGA,GAAW;AAAA,MAAA,IAGXr8B;AAAA,IACT,CAAC,GAGKs8B,IAAgB;AAAA,MACpB,GAAGhe;AAAA,MACH,UAAU8d;AAAA,MACV,SAAS;AAAA,QACP,GAAG9d,EAAO;AAAA,QACV,IAAI6d;AAAA;AAAA,MAAA;AAAA,IACN;AAIF,IAAAhC,EAAmBgC,CAAa,GAGhC3X,IAAiB8X,CAAa;AAG9B,QAAI;AACF,YAAMrN,EAAOqN,CAAa;AAAA,IAC5B,SAAS59B,IAAO;AACd,cAAQ,MAAM,gCAAgCA,EAAK;AAAA,IACrD;AAAA,EACF,GAAG,CAAC4f,EAAO,UAAUA,EAAO,SAAS8X,GAAUzE,GAAYnN,GAAgByK,GAAQ+K,GAAeqB,CAAwB,CAAC,GAGrHkB,IAAmB73B,EAAY,OAAOm3B,GAAgBC,GAA6BC,IAA6BC,GAAiCC,GAAWC,MAAsC;AACtM,QAAI,CAAC9F,KAAY,CAACzE,KAAc,CAACnN,KAAkB,CAACwV,EAAe;AAInE,UAAMmC,IAAgB,CAAC,GAAGN,CAAM;AAChC,QAAI,CAACR,EAAyBc,CAAa;AACzC;AAIF,UAAMC,IAAkB9d,EAAO,SAAS,IAAI,CAAAte,OAAW;AACrD,YAAMq8B,KAAaF,EAAc,KAAK,QAAQV,GAAK,MAAMz7B,GAAQ,EAAE;AACnE,aAAIq8B,KACK;AAAA,QACL,GAAGr8B;AAAA,QACH,GAAGq8B,GAAW;AAAA,QACd,GAAGA,GAAW;AAAA,QACd,GAAGA,GAAW;AAAA,QACd,GAAGA,GAAW;AAAA,MAAA,IAGXr8B;AAAA,IACT,CAAC,GAGKs8B,IAAgB;AAAA,MACpB,GAAGhe;AAAA,MACH,UAAU8d;AAAA,MACV,SAAS;AAAA,QACP,GAAG9d,EAAO;AAAA,QACV,IAAI6d;AAAA;AAAA,MAAA;AAAA,IACN;AAUF,QANAhC,EAAmBgC,CAAa,GAGhC3X,EAAe8X,CAAa,GAGxBrN;AACF,UAAI;AACF,cAAMA,EAAOqN,CAAa;AAAA,MAC5B,SAAS59B,IAAO;AACd,gBAAQ,MAAM,kCAAkCA,EAAK;AAAA,MACvD;AAAA,EAEJ,GAAG,CAAC4f,EAAO,UAAUA,EAAO,SAAS8X,GAAUzE,GAAYnN,GAAgByK,GAAQ+K,GAAeqB,CAAwB,CAAC,GAGrHvC,IAAuBp0B,EAAY,CAACq0B,MAAsB;AAC9D,UAAMyD,IAAmB/D,EAAqB,QAAQM,CAAS;AAC/D,IAAIyD,KAAoBA,EAAiB,WACvCA,EAAiB,QAAA,GAEfhE,KACFA,EAAiBO,CAAS;AAAA,EAE9B,GAAG,CAACP,CAAgB,CAAC,GAGfiE,IAAmB/3B,EAAY,MAAM;AACzC,IAAAi2B,GAAkB,IAAI,GACtBF,EAAsB,EAAI;AAAA,EAC5B,GAAG,CAAA,CAAE,GAGCiC,KAAoBh4B,EAAY,CAAC1E,MAA2B;AAChE,IAAA26B,GAAkB36B,CAAO,GACzBy6B,EAAsB,EAAI;AAAA,EAC5B,GAAG,CAAA,CAAE,GAGCkC,KAAoBj4B,EAAY,OAAOk4B,MAAuE;AAClH,QAAI,CAACpY,EAAgB;AAErB,QAAI4X,IAAkB,CAAC,GAAG9d,EAAO,QAAQ,GACrCue,KAAe,IACfC,IAA8B;AAElC,QAAIpC,IAAgB;AAElB,YAAM/wB,IAAQyyB,EAAgB,UAAU,OAAKrJ,EAAE,OAAO2H,GAAe,EAAE;AACvE,MAAI/wB,MAAU,OACZyyB,EAAgBzyB,CAAK,IAAIizB;AAAA,IAE7B,OAAO;AAEL,MAAAC,KAAe;AACf,YAAME,IAA4B;AAAA,QAChC,GAAGH;AAAA,QACH,IAAI,WAAW,KAAK,IAAA,CAAK;AAAA,QACzB,GAAG;AAAA,QACH,GAAG;AAAA,MAAA;AAGL,MAAAE,IAAeC,EAAW;AAG1B,YAAMC,IAAaZ,EAAgB,IAAI,CAAArJ,OAAM,EAAE,GAAGA,EAAE,IAAI,GAAGA,EAAE,GAAG,GAAGA,EAAE,GAAG,GAAGA,EAAE,GAAG,GAAGA,EAAE,IAAI;AACzF,UAAIkK,IAAO;AACX,MAAAD,EAAW,QAAQ,CAAAvB,MAAQ;AACzB,QAAIA,EAAK,IAAIA,EAAK,IAAIwB,MACpBA,IAAOxB,EAAK,IAAIA,EAAK;AAAA,MAEzB,CAAC,GACDsB,EAAW,IAAIE,GAEfb,EAAgB,KAAKW,CAAU;AAAA,IACjC;AAEA,UAAMT,IAAgB;AAAA,MACpB,GAAGhe;AAAA,MACH,UAAU8d;AAAA,IAAA;AAMZ,QAHA5X,EAAe8X,CAAa,GAGxBrN;AACF,UAAI;AACF,cAAMA,EAAOqN,CAAa;AAAA,MAC5B,SAAS59B,GAAO;AACd,gBAAQ,MAAM,qBAAqBA,CAAK;AAAA,MAC1C;AAGF,IAAA+7B,EAAsB,EAAK,GAC3BE,GAAkB,IAAI,GAGlBkC,MAAgBC,KAClB,WAAW,MAAM;AACf,YAAMI,IAAkB,MAAM;AAE5B,YAAIC,IAAqCpD,EAAY,QAAQ+C,CAAa;AAK1E,eAJKK,MACHA,IAAiB,SAAS,cAAc,qBAAqBL,CAAY,IAAI,IAG3EK,KACFA,EAAe,eAAe;AAAA,UAC5B,UAAU;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,QAAA,CACT,GACM,MAEF;AAAA,MACT;AAGA,MAAKD,OACH,WAAW,MAAM;AACf,QAAKA,OACH,WAAW,MAAM;AACf,UAAAA,EAAA;AAAA,QACF,GAAG,GAAG;AAAA,MAEV,GAAG,GAAG;AAAA,IAEV,GAAG,GAAG;AAAA,EAEV,GAAG,CAAC5e,GAAQoc,IAAgBlW,GAAgByK,CAAM,CAAC,GAG7CmO,KAAsB14B,EAAY,OAAOq0B,MAAsB;AACnE,QAAKvU,KAED,OAAO,QAAQ,+CAA+C,GAAG;AACnE,YAAM4X,IAAkB9d,EAAO,SAAS,OAAO,CAAAyU,MAAKA,EAAE,OAAOgG,CAAS,GAChEuD,KAAgB;AAAA,QACpB,GAAGhe;AAAA,QACH,UAAU8d;AAAA,MAAA;AAMZ,UAHA5X,EAAe8X,EAAa,GAGxBrN;AACF,YAAI;AACF,gBAAMA,EAAOqN,EAAa;AAAA,QAC5B,SAAS59B,GAAO;AACd,kBAAQ,MAAM,qBAAqBA,CAAK;AAAA,QAC1C;AAAA,IAEJ;AAAA,EACF,GAAG,CAAC4f,GAAQkG,GAAgByK,CAAM,CAAC,GAG7BoO,KAAyB34B,EAAY,OAAOq0B,MAAsB;AACtE,QAAI,CAACvU,EAAgB;AAErB,UAAM8Y,IAAkBhf,EAAO,SAAS,KAAK,CAAAyU,MAAKA,EAAE,OAAOgG,CAAS;AACpE,QAAI,CAACuE,EAAiB;AAGtB,UAAMC,KAAmC;AAAA,MACvC,GAAGD;AAAA,MACH,IAAI,WAAW,KAAK,IAAA,CAAK;AAAA,MACzB,OAAO,GAAGA,EAAgB,KAAK;AAAA,MAC/B,GAAG;AAAA,MACH,GAAG;AAAA,IAAA,GAICN,IAAa1e,EAAO,SAAS,IAAI,QAAM,EAAE,GAAGyU,EAAE,IAAI,GAAGA,EAAE,GAAG,GAAGA,EAAE,GAAG,GAAGA,EAAE,GAAG,GAAGA,EAAE,EAAA,EAAI;AACzF,QAAIkK,IAAO;AACX,IAAAD,EAAW,QAAQ,CAAAvB,MAAQ;AACzB,MAAIA,EAAK,IAAIA,EAAK,IAAIwB,MACpBA,IAAOxB,EAAK,IAAIA,EAAK;AAAA,IAEzB,CAAC,GACD8B,GAAkB,IAAIN;AAEtB,UAAMb,IAAkB,CAAC,GAAG9d,EAAO,UAAUif,EAAiB,GACxDjB,IAAgB;AAAA,MACpB,GAAGhe;AAAA,MACH,UAAU8d;AAAA,IAAA;AAMZ,QAHA5X,EAAe8X,CAAa,GAGxBrN;AACF,UAAI;AACF,cAAMA,EAAOqN,CAAa;AAAA,MAC5B,SAAS59B,GAAO;AACd,gBAAQ,MAAM,qBAAqBA,CAAK;AAAA,MAC1C;AAIF,eAAW,MAAM;AACf,YAAMw+B,IAAkB,MAAM;AAE5B,YAAIC,IAAqCpD,EAAY,QAAQwD,GAAkB,EAAE;AAKjF,eAJKJ,MACHA,IAAiB,SAAS,cAAc,qBAAqBI,GAAkB,EAAE,IAAI,IAGnFJ,KACFA,EAAe,eAAe;AAAA,UAC5B,UAAU;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,QAAA,CACT,GACM,MAEF;AAAA,MACT;AAGA,MAAKD,OACH,WAAW,MAAM;AACf,QAAKA,OACH,WAAW,MAAM;AACf,UAAAA,EAAA;AAAA,QACF,GAAG,GAAG;AAAA,MAEV,GAAG,GAAG;AAAA,IAEV,GAAG,GAAG;AAAA,EACR,GAAG,CAAC5e,GAAQkG,GAAgByK,CAAM,CAAC,GAG7BuO,KAAsB94B,EAAY,OAAOouB,MAAwB;AACrE,QAAI,CAACtO,EAAgB;AAErB,UAAM8X,IAAgB;AAAA,MACpB,GAAGhe;AAAA,MACH,cAAcwU;AAAA,IAAA;AAMhB,QAHAtO,EAAe8X,CAAa,GAGxBrN;AACF,UAAI;AACF,cAAMA,EAAOqN,CAAa;AAAA,MAC5B,SAAS59B,IAAO;AACd,gBAAQ,MAAM,qBAAqBA,EAAK;AAAA,MAC1C;AAAA,EAEJ,GAAG,CAAC4f,GAAQkG,GAAgByK,CAAM,CAAC,GAG7BwO,KAAyB/4B,EAAY,CAAC1E,MAA2B;AACrE,IAAA+6B,GAAuB/6B,CAAO,GAC9B66B,GAA2B,EAAI;AAAA,EACjC,GAAG,CAAA,CAAE,GAGC6C,KAAyBh5B,EAAY,OAAOi5B,MAAsB;AACtE,QAAI,CAACnZ,KAAkB,CAACsW,GAAqB;AAE7C,UAAMsB,IAAkB9d,EAAO,SAAS,IAAI,CAAAyU,MACtCA,EAAE,OAAO+H,GAAoB,KACxB;AAAA,MACL,GAAG/H;AAAA,MACH,wBAAwB4K;AAAA,IAAA,IAGrB5K,CACR,GAEKuJ,KAAgB;AAAA,MACpB,GAAGhe;AAAA,MACH,UAAU8d;AAAA,IAAA;AAMZ,QAHA5X,EAAe8X,EAAa,GAGxBrN;AACF,UAAI;AACF,cAAMA,EAAOqN,EAAa;AAAA,MAC5B,SAAS59B,GAAO;AACd,gBAAQ,MAAM,qBAAqBA,CAAK;AAAA,MAC1C;AAAA,EAEJ,GAAG,CAAC4f,GAAQwc,IAAqBtW,GAAgByK,CAAM,CAAC,GAGlD2O,IAA+Bl5B,EAAY,OAAOq0B,GAAmB3G,MAAqB;AAC9F,QAAI,CAAC5N,EAAgB;AAErB,UAAM4X,KAAkB9d,EAAO,SAAS,IAAI,CAAAyU,MAAK;AAC/C,UAAIA,EAAE,OAAOgG,GAAW;AACtB,cAAMhH,IAAiBgB,EAAE,0BAA0B,CAAA,GAC7C8K,IAAY9L,EAAe,SAASK,CAAQ;AAElD,eAAO;AAAA,UACL,GAAGW;AAAA,UACH,wBAAwB8K,IACpB9L,EAAe,OAAO,CAAA71B,MAAMA,MAAOk2B,CAAQ,IAC3C,CAAC,GAAGL,GAAgBK,CAAQ;AAAA,QAAA;AAAA,MAEpC;AACA,aAAOW;AAAA,IACT,CAAC,GAEKuJ,IAAgB;AAAA,MACpB,GAAGhe;AAAA,MACH,UAAU8d;AAAA,IAAA;AAMZ,QAHA5X,EAAe8X,CAAa,GAGxBrN;AACF,UAAI;AACF,cAAMA,EAAOqN,CAAa;AAAA,MAC5B,SAAS59B,GAAO;AACd,gBAAQ,MAAM,qBAAqBA,CAAK;AAAA,MAC1C;AAAA,EAEJ,GAAG,CAAC4f,GAAQkG,GAAgByK,CAAM,CAAC,GAG7B6O,KAAqBp5B,EAAY,CAAC0tB,MAAqB;AAE3D,IAAAiI,EAAoB,CAAAh3B,MAAQA,MAAS+uB,IAAW,OAAOA,CAAQ;AAAA,EACjE,GAAG,CAAA,CAAE,GAGC2L,KAA2Br5B,EAAY,OAAO0tB,MAAqB;AACvE,QAAI,CAAC5N,EAAgB;AAErB,UAAM4X,IAAkB9d,EAAO,SAAS,IAAI,CAAAyU,MAAK;AAC/C,YAAMhB,IAAiBgB,EAAE,0BAA0B,CAAA;AAEnD,aAAKhB,EAAe,SAASK,CAAQ,IAM9BW,IALE;AAAA,QACL,GAAGA;AAAA,QACH,wBAAwB,CAAC,GAAGhB,GAAgBK,CAAQ;AAAA,MAAA;AAAA,IAI1D,CAAC,GAEKkK,KAAgB;AAAA,MACpB,GAAGhe;AAAA,MACH,UAAU8d;AAAA,IAAA;AAMZ,QAHA5X,EAAe8X,EAAa,GAGxBrN;AACF,UAAI;AACF,cAAMA,EAAOqN,EAAa;AAAA,MAC5B,SAAS59B,GAAO;AACd,gBAAQ,MAAM,qBAAqBA,CAAK;AAAA,MAC1C;AAAA,EAEJ,GAAG,CAAC4f,GAAQkG,GAAgByK,CAAM,CAAC,GAG7B+O,KAAiBlI,IACnB32B,GAAkB,KAAK,OAAKF,EAAE,OAAO62B,CAAgB,IACrD;AAEJ,MAAI,CAACxX,EAAO,YAAYA,EAAO,SAAS,WAAW;AACjD,WACE,gBAAA1f,EAAAoJ,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAnJ,EAAC,SAAI,WAAU,iDACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAAC,EAACw6B,IAAA,EAAa,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,OAAO,wBAAwB,QAAQ,mBAAA,EAAmB,CAAG;AAAA,QACnH,gBAAAx6B,EAAC,MAAA,EAAG,WAAU,2CAA0C,UAAA,eAAW;AAAA,QACnE,gBAAAA,EAAC,KAAA,EAAE,WAAU,uCAAsC,UAAA,yDAAqD;AAAA,QACvGu3B,KACC,gBAAAx3B;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS69B;AAAA,YACT,WAAU;AAAA,YACV,OAAO;AAAA,cACL,OAAO;AAAA,cACP,aAAa;AAAA,YAAA;AAAA,YAEf,cAAc,CAACl8B,MAAMA,EAAE,cAAc,MAAM,kBAAkB;AAAA,YAC7D,cAAc,CAACA,MAAMA,EAAE,cAAc,MAAM,kBAAkB;AAAA,YAE7D,UAAA;AAAA,cAAA,gBAAA1B,EAAC6U,IAAA,EAAQ,WAAU,eAAA,CAAe;AAAA,cAAE;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAEtC,EAAA,CAEJ,EAAA,CACF;AAAA,MAGA,gBAAA7U;AAAA,QAACmwB;AAAA,QAAA;AAAA,UACC,QAAQwL;AAAA,UACR,SAAS,MAAM;AACb,YAAAC,EAAsB,EAAK,GAC3BE,GAAkB,IAAI;AAAA,UACxB;AAAA,UACA,QAAQgC;AAAA,UACR,SAASjC;AAAA,UACT,OAAOA,KAAiB,iBAAiB;AAAA,UACzC,YAAYA,KAAiB,mBAAmB;AAAA,UAChD,cAAAj5B;AAAA,QAAA;AAAA,MAAA;AAAA,IACF,GACF;AAKJ,QAAMw8B,KAAU7H,KAAYzE,KAAc+H,KAAwB,CAAC5D,GAI7DoI,KAA2B5f,EAAO,SAAS,IAAI,CAAAte,OAAY;AAAA,IAC/D,GAAGA,EAAQ;AAAA,IACX,GAAGA,EAAQ;AAAA,IACX,GAAGA,EAAQ;AAAA,IACX,GAAGA,EAAQ;AAAA,IACX,GAAGA,EAAQ;AAAA,IACX,MAAM;AAAA,IACN,MAAM;AAAA;AAAA;AAAA,IAEN,aAAai+B;AAAA,IACb,aAAaA;AAAA,IACb,GAAIA,KAAU,EAAE,eAAe,CAAC,KAAK,KAAK,KAAK,KAAK,MAAM,MAAM,MAAM,IAAI,EAAA,IAAe,CAAA;AAAA,EAAC,EAC1F,GAGIE,KAAoB,MACxB,gBAAAt/B;AAAA,IAACu/B;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,QAAQF;AAAA,MACR,gBAAgBxC;AAAA,MAChB,YAAYE;AAAA,MACZ,cAAcW;AAAA,MACd,OAAOzC;AAAA,MACP,YAAY;AAAA,QACV,MAAM;AAAA,QACN,WAAW;AAAA,QACX,QAAQ,CAAC,IAAI,EAAE;AAAA,QACf,kBAAkB,CAAC,GAAG,CAAC;AAAA,MAAA;AAAA,MAEzB,YAAY;AAAA,QACV,SAASmE;AAAA,QACT,QAAQ;AAAA,MAAA;AAAA,MAEV,cAAc;AAAA,QACZ,SAASA;AAAA,QACT,SAAS,CAAC,KAAK,KAAK,KAAK,KAAK,MAAM,MAAM,MAAM,IAAI;AAAA;AAAA,QAEpD,iBAAiB,CAACI,GAAM3gC,MACtB,gBAAAmB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAAnB;AAAA,YACA,WAAW,iDAAiD2gC,CAAI;AAAA,YAChE,OAAO,EAAE,SAAS,EAAA;AAAA,UAAE;AAAA,QAAA;AAAA,MACtB;AAAA,MAGJ,WAAWC;AAAA,MAEV,UAAAhgB,EAAO,SAAS,IAAI,CAAAte,MAAW;AAC9B,cAAMu+B,IAAoBzI,KACrB91B,EAAQ,0BAA0B,IAAI,SAAS81B,CAAgB,IAChE,IACE0I,KAAoB,CAAC,CAAC1I;AAE5B,eACE,gBAAAl3B;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,mBAAiBoB,EAAQ;AAAA,YACzB,KAAK,CAAAo5B,MAAM;AAAE,cAAAW,EAAY,QAAQ/5B,EAAQ,EAAE,IAAIo5B;AAAA,YAAG;AAAA,YAClD,WAAW,uEACToF,KAAoB,mBAAmB,EACzC;AAAA,YACA,OAAO;AAAA,cACL,WAAW;AAAA,cACX,aAAaA,MAAqBD,IAC9B,sBACA;AAAA,cACJ,aAAaC,MAAqBD,IAAoB,QAAQ;AAAA,cAC9D,iBAAiBC,MAAqBD,IAClC,sCACA;AAAA,cACJ,SAASC,MAAqB,CAACD,IAAoB,QAAQ;AAAA,YAAA;AAAA,YAE7D,SAAS,CAACh+B,MAAM;AACd,cAAIi+B,MAAqB1I,MACvBv1B,EAAE,gBAAA,GACFq9B,EAA6B59B,EAAQ,IAAI81B,CAAgB;AAAA,YAE7D;AAAA,YAGE,UAAA;AAAA,eAAA,CAAC91B,EAAQ,eAAe,cAAc2xB,MACtC,gBAAA/yB,EAAC,OAAA,EAAI,WAAW,6JAA6J+yB,IAAa,gBAAgB,gBAAgB,IACxN,UAAA;AAAA,gBAAA,gBAAA/yB,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,kBAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,+CAA+C,UAAAmB,EAAQ,OAAM;AAAA,kBAE1Eo2B,KAAYzE,KAAcqJ,GAAUh7B,EAAQ,EAAE,KAC7C,gBAAAnB;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,aAAa,CAAC0B,MAAMA,EAAE,gBAAA;AAAA,sBACtB,SAAS,CAACA,MAAMA,EAAE,gBAAA;AAAA,sBAClB,cAAc,CAACA,MAAMA,EAAE,gBAAA;AAAA,sBACvB,YAAY,CAACA,MAAMA,EAAE,gBAAA;AAAA,sBAErB,UAAA,gBAAA1B;AAAA,wBAAC6zB;AAAA,wBAAA;AAAA,0BACC,aAAasI,GAAUh7B,EAAQ,EAAE,EAAE;AAAA,0BACnC,eAAeg7B,GAAUh7B,EAAQ,EAAE,EAAE;AAAA,0BACrC,aAAag7B,GAAUh7B,EAAQ,EAAE,EAAE;AAAA,0BACnC,MAAMg7B,GAAUh7B,EAAQ,EAAE,EAAE;AAAA,0BAC5B,WAAWg7B,GAAUh7B,EAAQ,EAAE,EAAE;AAAA,wBAAA;AAAA,sBAAA;AAAA,oBACnC;AAAA,kBAAA;AAAA,gBACF,GAEJ;AAAA,gBACA,gBAAApB;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,WAAU;AAAA,oBACV,aAAa,CAAC2B,MAAMA,EAAE,gBAAA;AAAA,oBACtB,SAAS,CAACA,MAAMA,EAAE,gBAAA;AAAA,oBAClB,cAAc,CAACA,MAAMA,EAAE,gBAAA;AAAA,oBACvB,YAAY,CAACA,MAAMA,EAAE,gBAAA;AAAA,oBAErB,UAAA;AAAA,sBAAA,gBAAA1B;AAAA,wBAAC;AAAA,wBAAA;AAAA,0BACC,SAAS,CAAC0B,MAAM;AACd,4BAAAA,EAAE,gBAAA,GACFu4B,EAAqB94B,EAAQ,EAAE;AAAA,0BACjC;AAAA,0BACA,YAAY,CAACO,MAAM;AACjB,4BAAAA,EAAE,gBAAA,GACFA,EAAE,eAAA,GACFu4B,EAAqB94B,EAAQ,EAAE;AAAA,0BACjC;AAAA,0BACA,UAAUw+B;AAAA,0BACV,WAAW,sFACTA,KAAoB,kCAAkC,0CACxD;AAAA,0BACA,OAAM;AAAA,0BAEN,UAAA,gBAAA3/B,EAACR,IAAA,EAAY,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,OAAO,eAAA,EAAe,CAAG;AAAA,wBAAA;AAAA,sBAAA;AAAA,sBAG/E+3B,KAAYzE,KAAc,CAAC6M,MAC1B,gBAAA5/B,EAAAoJ,IAAA,EAEE,UAAA;AAAA,wBAAA,gBAAAnJ;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,SAAS,CAAC0B,MAAM;AACd,8BAAAA,EAAE,gBAAA,GACFk9B,GAAuBz9B,CAAO;AAAA,4BAChC;AAAA,4BACA,YAAY,CAACO,MAAM;AACjB,8BAAAA,EAAE,gBAAA,GACFA,EAAE,eAAA,GACFk9B,GAAuBz9B,CAAO;AAAA,4BAChC;AAAA,4BACA,WAAU;AAAA,4BACV,OAAO,8BAA8BA,EAAQ,0BAA0BA,EAAQ,uBAAuB,SAAS,IAAI,KAAKA,EAAQ,uBAAuB,MAAM,aAAa,EAAE;AAAA,4BAC5K,OAAO;AAAA,8BACL,OAAOA,EAAQ,0BAA0BA,EAAQ,uBAAuB,SAAS,IAC7E,sBACA;AAAA,4BAAA;AAAA,4BAGN,UAAA,gBAAAnB,EAACuR,IAAA,EAAW,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,OAAO,eAAA,EAAe,CAAG;AAAA,0BAAA;AAAA,wBAAA;AAAA,wBAG/E,gBAAAvR;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,SAAS,CAAC0B,MAAM;AACd,8BAAAA,EAAE,gBAAA,GACF88B,GAAuBr9B,EAAQ,EAAE;AAAA,4BACnC;AAAA,4BACA,YAAY,CAACO,MAAM;AACjB,8BAAAA,EAAE,gBAAA,GACFA,EAAE,eAAA,GACF88B,GAAuBr9B,EAAQ,EAAE;AAAA,4BACnC;AAAA,4BACA,WAAU;AAAA,4BACV,OAAM;AAAA,4BAEN,UAAA,gBAAAnB,EAACsc,IAAA,EAAS,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,OAAO,eAAA,EAAe,CAAG;AAAA,0BAAA;AAAA,wBAAA;AAAA,wBAE7E,gBAAAtc;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,SAAS,CAAC0B,MAAM;AACd,8BAAAA,EAAE,gBAAA,GACFm8B,GAAkB18B,CAAO;AAAA,4BAC3B;AAAA,4BACA,YAAY,CAACO,MAAM;AACjB,8BAAAA,EAAE,gBAAA,GACFA,EAAE,eAAA,GACFm8B,GAAkB18B,CAAO;AAAA,4BAC3B;AAAA,4BACA,WAAU;AAAA,4BACV,OAAM;AAAA,4BAEN,UAAA,gBAAAnB,EAAC22B,IAAA,EAAS,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,OAAO,eAAA,EAAe,CAAG;AAAA,0BAAA;AAAA,wBAAA;AAAA,wBAE7E,gBAAA32B;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,SAAS,CAAC0B,MAAM;AACd,8BAAAA,EAAE,gBAAA,GACF68B,GAAoBp9B,EAAQ,EAAE;AAAA,4BAChC;AAAA,4BACA,YAAY,CAACO,MAAM;AACjB,8BAAAA,EAAE,gBAAA,GACFA,EAAE,eAAA,GACF68B,GAAoBp9B,EAAQ,EAAE;AAAA,4BAChC;AAAA,4BACA,WAAU;AAAA,4BACV,OAAO,EAAE,OAAO,UAAA;AAAA,4BAChB,OAAM;AAAA,4BAEN,UAAA,gBAAAnB,EAACqc,IAAA,EAAW,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,OAAO,eAAA,EAAe,CAAG;AAAA,0BAAA;AAAA,wBAAA;AAAA,sBAC/E,EAAA,CACF;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAEJ,GACF;AAAA,cAIF,gBAAArc,EAAC,OAAA,EAAI,WAAU,2EACb,UAAA,gBAAAA;AAAA,gBAACkC;AAAA,gBAAA;AAAA,kBACC,KAAK,CAAAq4B,MAAM;AAAE,oBAAAX,EAAqB,QAAQz4B,EAAQ,EAAE,IAAIo5B;AAAA,kBAAG;AAAA,kBAC3D,OAAOp5B,EAAQ;AAAA,kBACf,WAAWA,EAAQ;AAAA,kBACnB,aAAaA,EAAQ;AAAA,kBACrB,eAAeA,EAAQ;AAAA,kBACvB,kBAAAb;AAAA,kBACA,wBAAwBa,EAAQ;AAAA,kBAChC,WAAWA,EAAQ,aAAase,EAAO,aAAa;AAAA,kBACpD,OAAOte,EAAQ;AAAA,kBACf,QAAO;AAAA,kBACP,cAAAyB;AAAA,kBACA,kBAAAC;AAAA,kBACA,kBAAkB,CAAC4B,MAAS;AAC1B,oBAAA23B,EAAa,CAAA53B,OAAS;AAAA,sBACpB,GAAGA;AAAA,sBACH,CAACrD,EAAQ,EAAE,GAAGsD;AAAA,oBAAA,EACd;AAAA,kBACJ;AAAA,gBAAA;AAAA,cAAA,EACF,CACF;AAAA,YAAA;AAAA,UAAA;AAAA,UA3KKtD,EAAQ;AAAA,QAAA;AAAA,MA8KnB,CAAC;AAAA,IAAA;AAAA,EAAA;AAIL,2BACGg5B,IAAA,EAAwB,OAAO/2B,GAC9B,UAAA,gBAAArD,EAAC,SAAI,KAAKi7B,GAAsB,WAAU,mCAAkC,OAAO,EAAE,UAAU,QAAQ,UAAU,YAC9G,UAAA;AAAA,IAAAzD,KACD,gBAAAx3B;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,4JACT07B,IAAa,aAAa,EAC5B;AAAA,QACA,OAAO;AAAA,UACL,WAAWA,IAAa,wBAAwB;AAAA,QAAA;AAAA,QAGlD,UAAA;AAAA,UAAA,gBAAA17B,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,YAAA,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAM86B,KAAwBU,EAAc,CAACzI,CAAU;AAAA,gBAChE,UAAU,CAAC+H;AAAA,gBACX,WAAW,6IACRA,IAEG/H,IACE,8EACA,oEAHF,+EAIN;AAAA,gBACA,OAAO;AAAA,kBACL,OAAQ+H,IAAgD,sBAAzB;AAAA,kBAC/B,aAAcA,IAA4C/H,IAAa,qBAAqB,sBAAvD;AAAA,gBAAuD;AAAA,gBAG9F,UAAA;AAAA,kBAAA,gBAAA9yB,EAAC22B,IAAA,EAAS,WAAU,iBAAA,CAAiB;AAAA,kBACpC7D,IAAa,qBAAqB;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAEpC,CAAC+H,KACA,gBAAA96B,EAAC,OAAA,EAAI,WAAU,0DACb,UAAA;AAAA,cAAA,gBAAAC,EAACy6B,IAAA,EAAY,WAAU,UAAA,CAAU;AAAA,cACjC,gBAAAz6B,EAAC,UAAK,UAAA,oCAAA,CAAiC;AAAA,YAAA,GACzC;AAAA,YAED8yB,KAAc+H,KACb,gBAAA76B,EAAC,KAAA,EAAE,WAAU,kDAAiD,UAAA,uEAAA,CAE9D;AAAA,UAAA,GAEJ;AAAA,UAGA,gBAAAD,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,YAAA+yB,KACC,gBAAA9yB;AAAA,cAACm0B;AAAA,cAAA;AAAA,gBACC,gBAAgB1U,EAAO;AAAA,gBACvB,iBAAiBkf;AAAA,gBACjB,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAId,gBAAA5+B;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS69B;AAAA,gBACT,UAAU,CAAC9K;AAAA,gBACX,WAAW,kIACXA,IACI,6DACA,6DACN;AAAA,gBACE,OAAO;AAAA,kBACL,OAAOA,IAAa,sBAAsB;AAAA,kBAC1C,aAAaA,IAAa,sBAAsB;AAAA,gBAAA;AAAA,gBAGpD,UAAA;AAAA,kBAAA,gBAAA9yB,EAAC6U,IAAA,EAAQ,WAAU,eAAA,CAAe;AAAA,kBAAE;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UAEtC,EAAA,CACA;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAKJ,gBAAA7U;AAAA,MAACs3B;AAAA,MAAA;AAAA,QACC,kBAAkBh3B,KAAoB,CAAA;AAAA,QACtC,UAAAi3B;AAAA,QACA,QAAQ/wB,KAAU;AAAA,QAClB,iBAAiBiZ;AAAA,QACjB,0BAA0B+X,MAA6B,MAAM;AAAA,QAAC;AAAA,QAC9D,eAAepH,IAAS,OAAOzuB,MAA+B;AAC5D,gBAAM87B,IAAgB;AAAA,YACpB,GAAGhe;AAAA,YACH,SAAA9d;AAAA,UAAA;AAEF,gBAAMyuB,EAAOqN,CAAa;AAAA,QAC5B,IAAI;AAAA,QACJ,kBAAAxG;AAAA,QACA,gBAAgBgI;AAAA,QAChB,YAAAnM;AAAA,MAAA;AAAA,IAAA;AAAA,IAIDmE,KAAoBkI,MACnB,gBAAAn/B;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO;AAAA,UACL,iBAAiB;AAAA,UACjB,aAAa;AAAA,UACb,OAAO;AAAA,QAAA;AAAA,QAGT,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,qDACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,YAAA,gBAAAC,EAACuR,IAAA,EAAW,WAAU,mBAAA,CAAmB;AAAA,YACzC,gBAAAxR,EAAC,QAAA,EAAK,WAAU,eAAc,UAAA;AAAA,cAAA;AAAA,cACuBo/B,GAAe;AAAA,cAAM;AAAA,YAAA,GAC1E;AAAA,YACA,gBAAAn/B,EAAC,QAAA,EAAK,WAAU,uCAAsC,UAAA,sBAAA,CAAmB;AAAA,UAAA,GAC3E;AAAA,UACA,gBAAAD,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,YAAA,gBAAAC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAMk/B,GAAyBjI,CAAgB;AAAA,gBACxD,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,iBAAiB;AAAA,kBACjB,OAAO;AAAA,gBAAA;AAAA,gBAET,cAAc,CAACv1B,MAAMA,EAAE,cAAc,MAAM,kBAAkB;AAAA,gBAC7D,cAAc,CAACA,MAAMA,EAAE,cAAc,MAAM,kBAAkB;AAAA,gBAC9D,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAGD,gBAAA1B;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAMw7B,EAAoB,IAAI;AAAA,gBACvC,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,iBAAiB;AAAA,kBACjB,OAAO;AAAA,gBAAA;AAAA,gBAET,cAAc,CAAC95B,MAAMA,EAAE,cAAc,MAAM,kBAAkB;AAAA,gBAC7D,cAAc,CAACA,MAAMA,EAAE,cAAc,MAAM,kBAAkB;AAAA,gBAC9D,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UAED,EAAA,CACF;AAAA,QAAA,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,IAKHk5B,MAAgB,WACf,gBAAA56B;AAAA,MAAC05B;AAAA,MAAA;AAAA,QACC,QAAAja;AAAA,QACA,cAAA7c;AAAA,QACA,kBAAAtC;AAAA,QACA,kBAAkB25B;AAAA,MAAA;AAAA,IAAA,IAElBW,MAAgB,WAClB,gBAAA56B,EAAC64B,IAAA,EAAkB,aAAAC,GAA0B,aAAAC,GAC1C,UAAAuG,KAAkB,CACrB,IAEAA,GAAA;AAAA,IAIF,gBAAAt/B;AAAA,MAACmwB;AAAA,MAAA;AAAA,QACC,QAAQwL;AAAA,QACR,SAAS,MAAM;AACb,UAAAC,EAAsB,EAAK,GAC3BE,GAAkB,IAAI;AAAA,QACxB;AAAA,QACA,QAAQgC;AAAA,QACR,SAASjC;AAAA,QACT,OAAOA,KAAiB,iBAAiB;AAAA,QACzC,YAAYA,KAAiB,mBAAmB;AAAA,QAChD,cAAAj5B;AAAA,MAAA;AAAA,IAAA;AAAA,IAIF,gBAAA5C;AAAA,MAACizB;AAAA,MAAA;AAAA,QACC,QAAQ8I;AAAA,QACR,SAAS,MAAM;AACb,UAAAC,GAA2B,EAAK,GAChCE,GAAuB,IAAI;AAAA,QAC7B;AAAA,QACA,kBAAkB57B,KAAoB,CAAA;AAAA,QACtC,gBAAgB27B,IAAqB,0BAA0B,CAAA;AAAA,QAC/D,QAAQ4C;AAAA,QACR,cAAc5C,IAAqB,SAAS;AAAA,MAAA;AAAA,IAAA;AAAA,EAC9C,EAAA,CACA,EAAA,CACF;AAEJ;AC1oCA,SAAwB2D,GAAmB;AAAA,EACzC,QAAAngB;AAAA,EACA,UAAA8X,IAAW;AAAA,EACX,kBAAkBsI;AAAA,EAClB,kBAAAh9B;AAAA,EACA,gBAAA8iB;AAAA,EACA,QAAAyK;AAAA,EACA,oBAAA0P;AACF,GAA4B;AAE1B,QAAM,EAAE,MAAA1wB,EAAA,IAASxH,GAAA,GAGXm4B,IAAmB58B,GAAOsc,CAAM,GAChCugB,IAA8B78B,GAAO,EAAK,GAI1C88B,IAAyBp8B,GAA2B,MAAM;AAC9D,UAAMq8B,IAAgBzgB,EAAO,WAAW,CAAA,GAClC0gB,IAAcN,KAAwB,CAAA;AAG5C,QAAIM,EAAY,WAAW;AACzB,aAAOD;AAIT,QAAIA,EAAc,WAAW;AAC3B,aAAOC;AAIT,UAAMl8B,IAAmCi8B,EAAc,IAAI,CAAAE,MAAgB;AAEzE,YAAMC,IAAaF,EAAY,KAAK,OAAMG,EAAG,OAAOF,EAAa,EAAE;AAEnE,aAAIC,IAEK;AAAA,QACL,GAAGD;AAAA;AAAA,QACH,QAAQC,EAAW;AAAA;AAAA,MAAA,IAKhBD;AAAA,IACT,CAAC,GAGKG,IAAY,IAAI,IAAIL,EAAc,IAAI,CAAAM,MAAMA,EAAG,EAAE,CAAC,GAClDvqB,IAAakqB,EAAY,OAAO,CAAAG,MAAM,CAACC,EAAU,IAAID,EAAG,EAAE,CAAC;AAEjE,WAAO,CAAC,GAAGr8B,GAAe,GAAGgS,CAAU;AAAA,EACzC,GAAG,CAACwJ,EAAO,SAASogB,CAAoB,CAAC,GAGnCY,IAA8B56B,EAAY,OAAO4Z,MAA4B;AAEjF,QAAKugB,EAA4B,SAIjC;AAAA,MAAIF,KACFA,EAAmB,EAAI;AAGzB,UAAI;AACF,QAAI1P,KACF,MAAMA,EAAO3Q,CAAM,GAIrBsgB,EAAiB,UAAUtgB,GAGvBqgB,KACFA,EAAmB,EAAK;AAAA,MAE5B,SAASjgC,GAAO;AAEd,sBAAQ,MAAM,gBAAgBA,CAAK,GAC7BA;AAAA,MACR;AAAA;AAAA,EACF,GAAG,CAACuwB,GAAQ0P,CAAkB,CAAC,GAGzBY,IAAsC76B,EAAY,CAAC4Z,MAA4B;AACnF,IAAIkG,KACFA,EAAelG,CAAM;AAIvB,UAAMkhB,IAAe,KAAK,UAAUlhB,CAAM,GACpCmhB,IAAsB,KAAK,UAAUb,EAAiB,OAAO;AAEnE,IAAIY,MAAiBC,MACnBZ,EAA4B,UAAU,IAElCF,KACFA,EAAmB,EAAI;AAAA,EAG7B,GAAG,CAACna,GAAgBma,CAAkB,CAAC,GAGjCe,IAA+Bh7B,EAAY,CAAClE,MAA+B;AAE/E,QAAI,CAACk+B,KAAwBA,EAAqB,WAAW,GAAG;AAC9D,YAAMpC,IAAgB;AAAA,QACpB,GAAGhe;AAAA,QACH,SAAA9d;AAAA,MAAA;AAEF,MAAA++B,EAAoCjD,CAAa;AAAA,IACnD;AACE,cAAQ,KAAK,qEAAqE;AAAA,EAEtF,GAAG,CAAChe,GAAQogB,GAAsBa,CAAmC,CAAC,GAGhE99B,IAAeiB,GAAQ,MAAM;AACjC,UAAMowB,IAAcxU,EAAO;AAC3B,WAAOuU,GAAgBC,CAAW;AAAA,EACpC,GAAG,CAACxU,EAAO,YAAY,CAAC;AAExB,SACE,gBAAAzf,EAAC,OAAA,EAAI,WAAU,UAEb,UAAA,gBAAAA;AAAA,IAAC06B;AAAA,IAAA;AAAA,MACC,QAAAjb;AAAA,MACA,UAAA8X;AAAA,MACA,kBAAkB0I;AAAA,MAClB,kBAAAp9B;AAAA,MACA,gBAAgB69B;AAAA,MAChB,QAAQD;AAAA,MACR,cAAA79B;AAAA,MACA,QAAQwM;AAAA,MACR,0BAA0ByxB;AAAA,IAAA;AAAA,EAAA,GAE9B;AAEJ;ACvIA,SAAwBC,GAAiB;AAAA,EACvC,SAAA3/B;AAAA,EACA,UAAAo2B,IAAW;AAAA,EACX,QAAAwJ;AAAA,EACA,UAAAnM;AAAA,EACA,WAAAoM;AACF,GAA0B;AACxB,QAAM,CAAC7E,GAAWC,CAAY,IAAIn5B,EAMxB,IAAI;AAEd,SACE,gBAAAlD,EAAC,SAAI,WAAU,yEAAwE,OAAO,EAAE,WAAW,yBAEzG,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,uIACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,+CAA+C,UAAAmB,EAAQ,OAAM;AAAA,QAE1Eg7B,KACC,gBAAAn8B;AAAA,UAAC6zB;AAAA,UAAA;AAAA,YACC,aAAasI,EAAU;AAAA,YACvB,eAAeA,EAAU;AAAA,YACzB,aAAaA,EAAU;AAAA,YACvB,MAAMA,EAAU;AAAA,YAChB,WAAWA,EAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACvB,GAEJ;AAAA,MAEA,gBAAAn8B,EAAC,OAAA,EAAI,WAAU,gCAEZ,eACC,gBAAAD,EAAAoJ,IAAA,EACE,UAAA;AAAA,QAAA,gBAAAnJ;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAMghC,IAAY7/B,EAAQ,EAAE;AAAA,YACrC,WAAU;AAAA,YACV,OAAM;AAAA,YAEN,UAAA,gBAAAnB,EAAC,SAAI,WAAU,WAAU,MAAK,QAAO,SAAQ,aAAY,QAAO,gBAC9D,4BAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,+GAA8G,EAAA,CACrL;AAAA,UAAA;AAAA,QAAA;AAAA,QAEF,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAM+gC,IAAS5/B,CAAO;AAAA,YAC/B,WAAU;AAAA,YACV,OAAM;AAAA,YAEN,UAAA,gBAAAnB,EAAC,SAAI,WAAU,WAAU,MAAK,QAAO,SAAQ,aAAY,QAAO,gBAC9D,4BAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,0HAAyH,EAAA,CAChM;AAAA,UAAA;AAAA,QAAA;AAAA,QAEF,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAM40B,IAAWzzB,EAAQ,EAAE;AAAA,YACpC,WAAU;AAAA,YACV,OAAO,EAAE,iBAAiB,cAAA;AAAA,YAC1B,cAAc,CAACO,MAAMA,EAAE,cAAc,MAAM,kBAAkB;AAAA,YAC7D,cAAc,CAACA,MAAMA,EAAE,cAAc,MAAM,kBAAkB;AAAA,YAC7D,OAAM;AAAA,YAEN,UAAA,gBAAA1B,EAAC,SAAI,WAAU,WAAU,MAAK,QAAO,SAAQ,aAAY,QAAO,gBAC9D,4BAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,gIAA+H,EAAA,CACtM;AAAA,UAAA;AAAA,QAAA;AAAA,MACF,EAAA,CACF,EAAA,CAEJ;AAAA,IAAA,GACF;AAAA,IAGA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oDACb,UAAA,gBAAAA;AAAA,MAACkC;AAAA,MAAA;AAAA,QACC,OAAOf,EAAQ;AAAA,QACf,WAAWA,EAAQ;AAAA,QACnB,aAAaA,EAAQ;AAAA,QACrB,eAAeA,EAAQ;AAAA,QACvB,OAAOA,EAAQ;AAAA,QACf,QAAO;AAAA,QACP,kBAAkB,CAACsD,MAAS;AAC1B,UAAA23B,EAAa33B,CAAI;AAAA,QACnB;AAAA,MAAA;AAAA,IAAA,EACF,CACF;AAAA,EAAA,GACF;AAEJ;AC7FA,SAAwBw8B,GAAmB;AAAA,EACzC,QAAA/7B;AAAA,EACA,SAAAC;AAAA,EACA,QAAAirB;AAAA,EACA,OAAAhrB;AAAA,EACA,YAAAirB;AAAA,EACA,aAAA6Q,IAAc;AAAA,EACd,oBAAAC,IAAqB;AACvB,GAA4B;AAC1B,QAAM,CAACC,GAAMC,CAAO,IAAIp+B,EAAS,EAAE,GAC7B,CAAC0c,GAAa2hB,CAAc,IAAIr+B,EAAS,EAAE,GAC3C,CAACs+B,GAAUC,CAAW,IAAIv+B,EAAS,EAAK;AAG9C,EAAAO,GAAU,MAAM;AACd,IAAI0B,MACFm8B,EAAQH,CAAW,GACnBI,EAAeH,CAAkB;AAAA,EAErC,GAAG,CAACj8B,GAAQg8B,GAAaC,CAAkB,CAAC;AAE5C,QAAMtP,IAAe,OAAOnwB,MAAuB;AAGjD,QAFAA,EAAE,eAAA,GAEE,EAAC0/B,EAAK,QAIV;AAAA,MAAAI,EAAY,EAAI;AAEhB,UAAI;AACF,cAAMpR,EAAO;AAAA,UACX,MAAMgR,EAAK,KAAA;AAAA,UACX,aAAazhB,EAAY,KAAA,KAAU;AAAA,QAAA,CACpC,GACDiI,EAAA;AAAA,MACF,QAAgB;AAAA,MAGhB,UAAA;AACE,QAAA4Z,EAAY,EAAK;AAAA,MACnB;AAAA;AAAA,EACF,GAEM5Z,IAAc,MAAM;AACxB,IAAAyZ,EAAQ,EAAE,GACVC,EAAe,EAAE,GACjBE,EAAY,EAAK,GACjBr8B,EAAA;AAAA,EACF,GAEMO,IACJ,gBAAA3F,EAAAoJ,IAAA,EACE,UAAA;AAAA,IAAA,gBAAAnJ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS4nB;AAAA,QACT,UAAU2Z;AAAA,QACV,WAAU;AAAA,QACX,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGD,gBAAAvhC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,MAAK;AAAA,QACL,UAAUuhC,KAAY,CAACH,EAAK,KAAA;AAAA,QAC5B,WAAU;AAAA,QAET,cAAW,cAAc/Q;AAAA,MAAA;AAAA,IAAA;AAAA,EAC5B,GACF;AAGF,SACE,gBAAArwB;AAAA,IAACiF;AAAA,IAAA;AAAA,MACC,QAAAC;AAAA,MACA,SAAS0iB;AAAA,MACT,OAAAxiB;AAAA,MACA,MAAK;AAAA,MACL,QAAAM;AAAA,MAEA,4BAAC,QAAA,EAAK,IAAG,kBAAiB,UAAUmsB,GAAc,WAAU,oBAC1D,UAAA;AAAA,QAAA,gBAAA9xB,EAAC,OAAA,EACC,UAAA;AAAA,UAAA,gBAAAC,EAAC,SAAA,EAAM,SAAQ,kBAAiB,WAAU,yDAAwD,UAAA,kBAElG;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,IAAG;AAAA,cACH,OAAOohC;AAAA,cACP,UAAU,CAAC1/B,MAAM2/B,EAAQ3/B,EAAE,OAAO,KAAK;AAAA,cACvC,WAAU;AAAA,cACV,aAAY;AAAA,cACZ,UAAQ;AAAA,cACR,WAAS;AAAA,YAAA;AAAA,UAAA;AAAA,QACX,GACF;AAAA,0BAEC,OAAA,EACC,UAAA;AAAA,UAAA,gBAAA1B,EAAC,SAAA,EAAM,SAAQ,yBAAwB,WAAU,yDAAwD,UAAA,0BAEzG;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAM;AAAA,cACN,OAAO2f;AAAA,cACP,UAAU,CAACje,MAAM4/B,EAAe5/B,EAAE,OAAO,KAAK;AAAA,cAC9C,WAAU;AAAA,cACV,aAAY;AAAA,YAAA;AAAA,UAAA;AAAA,QACd,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;","x_google_ignoreList":[0,26]}
|
|
1
|
+
{"version":3,"file":"components.js","sources":["../../node_modules/react-intersection-observer/dist/index.mjs","../../src/client/components/ChartErrorBoundary.tsx","../../src/client/utils/filterUtils.ts","../../src/client/components/AnalyticsPortlet.tsx","../../src/client/components/Modal.tsx","../../src/client/utils/measureIcons.tsx","../../src/client/components/QueryBuilder/CubeMetaExplorer.tsx","../../src/client/components/QueryBuilder/types.ts","../../src/client/components/QueryBuilder/FilterValueSelector.tsx","../../src/client/components/QueryBuilder/utils.ts","../../src/client/components/QueryBuilder/FilterItem.tsx","../../src/client/components/QueryBuilder/FilterGroup.tsx","../../src/client/components/QueryBuilder/FilterBuilder.tsx","../../src/client/components/QueryBuilder/DateRangeSelector.tsx","../../src/client/components/QueryBuilder/DateRangeFilter.tsx","../../src/client/components/QueryBuilder/QueryAnalysisPanel.tsx","../../src/client/components/QueryBuilder/QueryPanel.tsx","../../src/client/charts/chartConfigRegistry.ts","../../src/client/components/ChartTypeSelector.tsx","../../src/client/components/AxisDropZone.tsx","../../src/client/components/ChartConfigPanel.tsx","../../src/client/components/QueryBuilder/ResultsPanel.tsx","../../src/client/components/QueryBuilder/SetupPanel.tsx","../../src/client/components/AIAssistant/constants.ts","../../src/client/components/AIAssistant/utils.ts","../../src/client/components/AIAssistant/AIAssistantModal.tsx","../../node_modules/lz-string/libs/lz-string.js","../../src/client/components/QueryBuilder/shareUtils.ts","../../src/client/components/QueryBuilder/ShareWarningModal.tsx","../../src/client/components/QueryBuilder/index.tsx","../../src/client/components/PortletEditModal.tsx","../../src/client/components/PortletFilterConfigModal.tsx","../../src/client/components/DebugModal.tsx","../../src/client/utils/colorPalettes.ts","../../src/client/components/ColorPaletteSelector.tsx","../../src/client/components/DashboardFilters/FilterEditModal.tsx","../../src/client/components/DashboardFilters/ReadOnlyFilterList.tsx","../../src/client/components/DashboardFilters/EditModeFilterList.tsx","../../src/client/components/DashboardFilterPanel.tsx","../../src/client/components/ScaledGridWrapper.tsx","../../src/client/components/MobileStackedLayout.tsx","../../src/client/components/DashboardGrid.tsx","../../src/client/components/AnalyticsDashboard.tsx","../../src/client/components/PortletContainer.tsx","../../src/client/components/DashboardEditModal.tsx"],"sourcesContent":["\"use client\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n\n// src/InView.tsx\nimport * as React from \"react\";\n\n// src/observe.ts\nvar observerMap = /* @__PURE__ */ new Map();\nvar RootIds = /* @__PURE__ */ new WeakMap();\nvar rootId = 0;\nvar unsupportedValue;\nfunction defaultFallbackInView(inView) {\n unsupportedValue = inView;\n}\nfunction getRootId(root) {\n if (!root) return \"0\";\n if (RootIds.has(root)) return RootIds.get(root);\n rootId += 1;\n RootIds.set(root, rootId.toString());\n return RootIds.get(root);\n}\nfunction optionsToId(options) {\n return Object.keys(options).sort().filter(\n (key) => options[key] !== void 0\n ).map((key) => {\n return `${key}_${key === \"root\" ? getRootId(options.root) : options[key]}`;\n }).toString();\n}\nfunction createObserver(options) {\n const id = optionsToId(options);\n let instance = observerMap.get(id);\n if (!instance) {\n const elements = /* @__PURE__ */ new Map();\n let thresholds;\n const observer = new IntersectionObserver((entries) => {\n entries.forEach((entry) => {\n var _a2;\n const inView = entry.isIntersecting && thresholds.some((threshold) => entry.intersectionRatio >= threshold);\n if (options.trackVisibility && typeof entry.isVisible === \"undefined\") {\n entry.isVisible = inView;\n }\n (_a2 = elements.get(entry.target)) == null ? void 0 : _a2.forEach((callback) => {\n callback(inView, entry);\n });\n });\n }, options);\n thresholds = observer.thresholds || (Array.isArray(options.threshold) ? options.threshold : [options.threshold || 0]);\n instance = {\n id,\n observer,\n elements\n };\n observerMap.set(id, instance);\n }\n return instance;\n}\nfunction observe(element, callback, options = {}, fallbackInView = unsupportedValue) {\n if (typeof window.IntersectionObserver === \"undefined\" && fallbackInView !== void 0) {\n const bounds = element.getBoundingClientRect();\n callback(fallbackInView, {\n isIntersecting: fallbackInView,\n target: element,\n intersectionRatio: typeof options.threshold === \"number\" ? options.threshold : 0,\n time: 0,\n boundingClientRect: bounds,\n intersectionRect: bounds,\n rootBounds: bounds\n });\n return () => {\n };\n }\n const { id, observer, elements } = createObserver(options);\n const callbacks = elements.get(element) || [];\n if (!elements.has(element)) {\n elements.set(element, callbacks);\n }\n callbacks.push(callback);\n observer.observe(element);\n return function unobserve() {\n callbacks.splice(callbacks.indexOf(callback), 1);\n if (callbacks.length === 0) {\n elements.delete(element);\n observer.unobserve(element);\n }\n if (elements.size === 0) {\n observer.disconnect();\n observerMap.delete(id);\n }\n };\n}\n\n// src/InView.tsx\nfunction isPlainChildren(props) {\n return typeof props.children !== \"function\";\n}\nvar InView = class extends React.Component {\n constructor(props) {\n super(props);\n __publicField(this, \"node\", null);\n __publicField(this, \"_unobserveCb\", null);\n __publicField(this, \"lastInView\");\n __publicField(this, \"handleNode\", (node) => {\n if (this.node) {\n this.unobserve();\n if (!node && !this.props.triggerOnce && !this.props.skip) {\n this.setState({ inView: !!this.props.initialInView, entry: void 0 });\n this.lastInView = this.props.initialInView;\n }\n }\n this.node = node ? node : null;\n this.observeNode();\n });\n __publicField(this, \"handleChange\", (inView, entry) => {\n const previousInView = this.lastInView;\n this.lastInView = inView;\n if (previousInView === void 0 && !inView) {\n return;\n }\n if (inView && this.props.triggerOnce) {\n this.unobserve();\n }\n if (!isPlainChildren(this.props)) {\n this.setState({ inView, entry });\n }\n if (this.props.onChange) {\n this.props.onChange(inView, entry);\n }\n });\n this.state = {\n inView: !!props.initialInView,\n entry: void 0\n };\n this.lastInView = props.initialInView;\n }\n componentDidMount() {\n this.unobserve();\n this.observeNode();\n }\n componentDidUpdate(prevProps) {\n if (prevProps.rootMargin !== this.props.rootMargin || prevProps.root !== this.props.root || prevProps.threshold !== this.props.threshold || prevProps.skip !== this.props.skip || prevProps.trackVisibility !== this.props.trackVisibility || prevProps.delay !== this.props.delay) {\n this.unobserve();\n this.observeNode();\n }\n }\n componentWillUnmount() {\n this.unobserve();\n }\n observeNode() {\n if (!this.node || this.props.skip) return;\n const {\n threshold,\n root,\n rootMargin,\n trackVisibility,\n delay,\n fallbackInView\n } = this.props;\n if (this.lastInView === void 0) {\n this.lastInView = this.props.initialInView;\n }\n this._unobserveCb = observe(\n this.node,\n this.handleChange,\n {\n threshold,\n root,\n rootMargin,\n // @ts-expect-error\n trackVisibility,\n delay\n },\n fallbackInView\n );\n }\n unobserve() {\n if (this._unobserveCb) {\n this._unobserveCb();\n this._unobserveCb = null;\n }\n }\n render() {\n const { children } = this.props;\n if (typeof children === \"function\") {\n const { inView, entry } = this.state;\n return children({ inView, entry, ref: this.handleNode });\n }\n const {\n as,\n triggerOnce,\n threshold,\n root,\n rootMargin,\n onChange,\n skip,\n trackVisibility,\n delay,\n initialInView,\n fallbackInView,\n ...props\n } = this.props;\n return React.createElement(\n as || \"div\",\n { ref: this.handleNode, ...props },\n children\n );\n }\n};\n\n// src/useInView.tsx\nimport * as React2 from \"react\";\nfunction useInView({\n threshold,\n delay,\n trackVisibility,\n rootMargin,\n root,\n triggerOnce,\n skip,\n initialInView,\n fallbackInView,\n onChange\n} = {}) {\n var _a2;\n const [ref, setRef] = React2.useState(null);\n const callback = React2.useRef(onChange);\n const lastInViewRef = React2.useRef(initialInView);\n const [state, setState] = React2.useState({\n inView: !!initialInView,\n entry: void 0\n });\n callback.current = onChange;\n React2.useEffect(\n () => {\n if (lastInViewRef.current === void 0) {\n lastInViewRef.current = initialInView;\n }\n if (skip || !ref) return;\n let unobserve;\n unobserve = observe(\n ref,\n (inView, entry) => {\n const previousInView = lastInViewRef.current;\n lastInViewRef.current = inView;\n if (previousInView === void 0 && !inView) {\n return;\n }\n setState({\n inView,\n entry\n });\n if (callback.current) callback.current(inView, entry);\n if (entry.isIntersecting && triggerOnce && unobserve) {\n unobserve();\n unobserve = void 0;\n }\n },\n {\n root,\n rootMargin,\n threshold,\n // @ts-expect-error\n trackVisibility,\n delay\n },\n fallbackInView\n );\n return () => {\n if (unobserve) {\n unobserve();\n }\n };\n },\n // We break the rule here, because we aren't including the actual `threshold` variable\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n // If the threshold is an array, convert it to a string, so it won't change between renders.\n Array.isArray(threshold) ? threshold.toString() : threshold,\n ref,\n root,\n rootMargin,\n triggerOnce,\n skip,\n trackVisibility,\n fallbackInView,\n delay\n ]\n );\n const entryTarget = (_a2 = state.entry) == null ? void 0 : _a2.target;\n const previousEntryTarget = React2.useRef(void 0);\n if (!ref && entryTarget && !triggerOnce && !skip && previousEntryTarget.current !== entryTarget) {\n previousEntryTarget.current = entryTarget;\n setState({\n inView: !!initialInView,\n entry: void 0\n });\n lastInViewRef.current = initialInView;\n }\n const result = [setRef, state.inView, state.entry];\n result.ref = result[0];\n result.inView = result[1];\n result.entry = result[2];\n return result;\n}\n\n// src/useOnInView.tsx\nimport * as React3 from \"react\";\nvar _a, _b;\nvar useSyncEffect = (_b = (_a = React3.useInsertionEffect) != null ? _a : React3.useLayoutEffect) != null ? _b : React3.useEffect;\nvar useOnInView = (onIntersectionChange, {\n threshold,\n root,\n rootMargin,\n trackVisibility,\n delay,\n triggerOnce,\n skip\n} = {}) => {\n const onIntersectionChangeRef = React3.useRef(onIntersectionChange);\n const observedElementRef = React3.useRef(null);\n const observerCleanupRef = React3.useRef(void 0);\n const lastInViewRef = React3.useRef(void 0);\n useSyncEffect(() => {\n onIntersectionChangeRef.current = onIntersectionChange;\n }, [onIntersectionChange]);\n return React3.useCallback(\n (element) => {\n const cleanupExisting = () => {\n if (observerCleanupRef.current) {\n const cleanup = observerCleanupRef.current;\n observerCleanupRef.current = void 0;\n cleanup();\n }\n };\n if (element === observedElementRef.current) {\n return observerCleanupRef.current;\n }\n if (!element || skip) {\n cleanupExisting();\n observedElementRef.current = null;\n lastInViewRef.current = void 0;\n return;\n }\n cleanupExisting();\n observedElementRef.current = element;\n let destroyed = false;\n const destroyObserver = observe(\n element,\n (inView, entry) => {\n const previousInView = lastInViewRef.current;\n lastInViewRef.current = inView;\n if (previousInView === void 0 && !inView) {\n return;\n }\n onIntersectionChangeRef.current(\n inView,\n entry\n );\n if (triggerOnce && inView) {\n stopObserving();\n }\n },\n {\n threshold,\n root,\n rootMargin,\n trackVisibility,\n delay\n }\n );\n function stopObserving() {\n if (destroyed) return;\n destroyed = true;\n destroyObserver();\n observedElementRef.current = null;\n observerCleanupRef.current = void 0;\n lastInViewRef.current = void 0;\n }\n observerCleanupRef.current = stopObserving;\n return observerCleanupRef.current;\n },\n [\n Array.isArray(threshold) ? threshold.toString() : threshold,\n root,\n rootMargin,\n trackVisibility,\n delay,\n triggerOnce,\n skip\n ]\n );\n};\nexport {\n InView,\n defaultFallbackInView,\n observe,\n useInView,\n useOnInView\n};\n//# sourceMappingURL=index.mjs.map","import React, { Component, ReactNode } from 'react'\nimport { getIcon } from '../icons'\n\nconst RefreshIcon = getIcon('refresh')\n\ninterface Props {\n children: ReactNode\n fallback?: ReactNode\n portletTitle?: string\n portletConfig?: any\n cubeQuery?: string\n}\n\ninterface State {\n hasError: boolean\n error: Error | null\n errorInfo: string | null\n}\n\nexport default class ChartErrorBoundary extends Component<Props, State> {\n constructor(props: Props) {\n super(props)\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null\n }\n }\n\n static getDerivedStateFromError(error: Error): State {\n // Update state so the next render will show the fallback UI\n return {\n hasError: true,\n error,\n errorInfo: null\n }\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\n // Update state with error details\n this.setState({\n error,\n errorInfo: errorInfo.componentStack || null\n })\n\n // Log the error for debugging\n console.error('Chart Error Boundary caught a rendering error:', error, errorInfo)\n }\n\n handleReset = () => {\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null\n })\n }\n\n render() {\n if (this.state.hasError) {\n // Custom fallback UI\n if (this.props.fallback) {\n return this.props.fallback\n }\n\n // Default error display\n return (\n <div className=\"flex flex-col items-center justify-center w-full h-full p-6 text-center border border-dashed rounded-lg\"\n style={{ borderColor: 'var(--dc-border)', backgroundColor: 'var(--dc-surface)' }}>\n <div className=\"h-12 w-12 mb-4 text-dc-text-muted\">⚠️</div>\n <h3 className=\"text-lg font-semibold mb-2 text-dc-text\">\n {this.props.portletTitle ? `Unable to render ${this.props.portletTitle}` : 'Unable to render chart'}\n </h3>\n <p className=\"text-sm text-dc-text-secondary mb-4 max-w-md\">\n There was an error rendering this chart component. The error details are shown below.\n </p>\n\n {/* Error details */}\n <div className=\"w-full max-w-2xl mb-4\">\n <div className=\"bg-dc-surface-secondary rounded-lg p-3 text-left\">\n <div className=\"text-xs font-mono mb-2 text-dc-text\">\n <strong>Error:</strong> {this.state.error?.message}\n </div>\n {this.state.error?.name && (\n <div className=\"text-xs font-mono text-dc-text-secondary mb-2\">\n <strong>Type:</strong> {this.state.error.name}\n </div>\n )}\n\n {/* Portlet Config Debug Info */}\n {this.props.portletConfig && (\n <details className=\"text-xs font-mono text-dc-text-secondary mb-2\">\n <summary className=\"cursor-pointer\">Portlet Configuration</summary>\n <pre className=\"mt-2 whitespace-pre-wrap p-2 rounded-sm overflow-auto max-h-32\"\n style={{ backgroundColor: 'rgba(var(--dc-primary-rgb), 0.1)' }}>\n {JSON.stringify(this.props.portletConfig, null, 2)}\n </pre>\n </details>\n )}\n\n {/* Cube Query Debug Info */}\n {this.props.cubeQuery && (\n <details className=\"text-xs font-mono text-dc-text-secondary mb-2\">\n <summary className=\"cursor-pointer\">Cube Query</summary>\n <pre className=\"mt-2 whitespace-pre-wrap p-2 rounded-sm overflow-auto max-h-32\"\n style={{ backgroundColor: '#d1fae5' }}>\n {typeof this.props.cubeQuery === 'string' \n ? JSON.stringify(JSON.parse(this.props.cubeQuery), null, 2)\n : JSON.stringify(this.props.cubeQuery, null, 2)\n }\n </pre>\n </details>\n )}\n\n {this.state.errorInfo && (\n <details className=\"text-xs font-mono text-dc-text-secondary\">\n <summary className=\"cursor-pointer\">Component Stack</summary>\n <pre className=\"mt-2 whitespace-pre-wrap\">{this.state.errorInfo}</pre>\n </details>\n )}\n </div>\n </div>\n\n {/* Reset button */}\n <button\n onClick={this.handleReset}\n className=\"px-3 py-1 text-white rounded-sm text-sm hover:opacity-90 transition-opacity\"\n style={{\n backgroundColor: 'var(--dc-primary)'\n }}\n >\n <RefreshIcon style={{ width: '16px', height: '16px', display: 'inline', marginRight: '4px' }} />Try Again\n </button>\n </div>\n )\n }\n\n return this.props.children\n }\n}","/**\n * Filter utility functions for dashboard-level filtering\n */\n\nimport type { Filter, DashboardFilter, CubeMeta, GroupFilter, DashboardConfig, SimpleFilter } from '../types'\n\n/**\n * Check if a filter should be included in the query (has valid values or doesn't require values)\n * @param filter - The filter to check\n * @returns true if the filter should be included, false otherwise\n */\nfunction shouldIncludeFilter(filter: Filter): boolean {\n // Handle SimpleFilter\n if ('member' in filter && 'operator' in filter) {\n const simpleFilter = filter as SimpleFilter\n\n // Operators that don't require values\n const noValueOperators = ['set', 'notSet', 'isEmpty', 'isNotEmpty']\n if (noValueOperators.includes(simpleFilter.operator)) {\n return true\n }\n\n // For inDateRange, check if dateRange is provided as alternative to values\n if (simpleFilter.operator === 'inDateRange' && simpleFilter.dateRange) {\n return true\n }\n\n // For other operators, check if values exist and are non-empty\n return !!(simpleFilter.values && simpleFilter.values.length > 0)\n }\n\n // Handle GroupFilter - recursively check nested filters\n if ('type' in filter && 'filters' in filter) {\n const groupFilter = filter as GroupFilter\n // Include group filter if at least one nested filter is valid\n const validFilters = groupFilter.filters.filter(f => shouldIncludeFilter(f))\n return validFilters.length > 0\n }\n\n return false\n}\n\n/**\n * Get dashboard filters that should be applied to a portlet based on its mapping configuration\n * @param dashboardFilters - All available dashboard filters\n * @param filterMapping - Array of filter IDs that apply to this portlet\n * @returns Array of filters that should be applied to the portlet\n */\nexport function getApplicableDashboardFilters(\n dashboardFilters: DashboardFilter[] | undefined,\n filterMapping: string[] | undefined\n): Filter[] {\n if (!dashboardFilters || !dashboardFilters.length) {\n return []\n }\n\n // If no mapping is specified, no dashboard filters apply\n if (!filterMapping || !filterMapping.length) {\n return []\n }\n\n // Return filters that are in the mapping AND have valid values\n return dashboardFilters\n .filter(df => filterMapping.includes(df.id))\n .filter(df => shouldIncludeFilter(df.filter))\n .map(df => df.filter)\n}\n\n/**\n * Merge dashboard filters with portlet filters using AND logic\n * Dashboard filters are combined with portlet filters so both sets of filters apply\n * @param dashboardFilters - Filters from dashboard-level configuration\n * @param portletFilters - Filters from portlet query\n * @returns Merged filter array with AND logic\n */\n/**\n * Convert GroupFilter format to server format\n * GroupFilter: { type: 'and', filters: [...] }\n * Server format: { and: [...] } or { or: [...] }\n */\nfunction convertToServerFormat(filter: Filter): any {\n // Handle GroupFilter format\n if ('type' in filter && 'filters' in filter) {\n const groupFilter = filter as GroupFilter\n const convertedFilters = groupFilter.filters.map(convertToServerFormat)\n\n if (groupFilter.type === 'and') {\n return { and: convertedFilters }\n } else {\n return { or: convertedFilters }\n }\n }\n\n // Simple filter - return as-is\n return filter\n}\n\nexport function mergeDashboardAndPortletFilters(\n dashboardFilters: Filter[],\n portletFilters: Filter[] | undefined\n): Filter[] | undefined {\n // If no dashboard filters, return portlet filters as-is\n if (!dashboardFilters || dashboardFilters.length === 0) {\n return portletFilters\n }\n\n // If no portlet filters, return dashboard filters\n if (!portletFilters || portletFilters.length === 0) {\n return dashboardFilters\n }\n\n // Both exist - need to merge with AND logic\n // We need to combine them in a way that both sets of filters apply\n\n // Flatten both filter arrays and convert to server format\n const allFilters = [...dashboardFilters, ...portletFilters].map(convertToServerFormat)\n\n // Wrap all filters in a single AND group using server format\n return [{\n and: allFilters\n } as any]\n}\n\n/**\n * Check if a filter field exists in the cube metadata\n * This helps identify filters that might not apply to a specific portlet's data\n * @param filter - The filter to validate\n * @param cubeMeta - Cube metadata to validate against\n * @returns true if the filter field exists in any cube's measures or dimensions\n */\nexport function validateFilterForCube(\n filter: Filter,\n cubeMeta: CubeMeta | null\n): boolean {\n if (!cubeMeta || !cubeMeta.cubes) {\n // If no metadata available, assume filter is valid (fail open)\n return true\n }\n\n // Extract member names from filter recursively\n const memberNames = extractMemberNamesFromFilter(filter)\n\n // Check if any of the member names exist in cube metadata\n return memberNames.some(memberName => {\n return cubeMeta.cubes.some(cube => {\n // Check measures\n const inMeasures = cube.measures?.some(m => m.name === memberName) ?? false\n // Check dimensions\n const inDimensions = cube.dimensions?.some(d => d.name === memberName) ?? false\n\n return inMeasures || inDimensions\n })\n })\n}\n\n/**\n * Extract all member names from a filter (handles nested group filters)\n * @param filter - The filter to extract members from\n * @returns Array of member names\n */\nfunction extractMemberNamesFromFilter(filter: Filter): string[] {\n if ('member' in filter) {\n // SimpleFilter\n return [filter.member]\n } else if ('type' in filter && 'filters' in filter) {\n // GroupFilter - recursively extract from nested filters\n return filter.filters.flatMap(f => extractMemberNamesFromFilter(f))\n }\n\n return []\n}\n\n/**\n * Validate that all dashboard filters in a portlet's mapping exist and are valid\n * @param dashboardFilters - All available dashboard filters\n * @param filterMapping - The portlet's filter mapping\n * @param cubeMeta - Cube metadata for validation\n * @returns Object with validation result and list of invalid filter IDs\n */\nexport function validatePortletFilterMapping(\n dashboardFilters: DashboardFilter[] | undefined,\n filterMapping: string[] | undefined,\n cubeMeta: CubeMeta | null\n): { isValid: boolean; invalidFilterIds: string[]; missingFilterIds: string[] } {\n if (!filterMapping || !filterMapping.length) {\n return { isValid: true, invalidFilterIds: [], missingFilterIds: [] }\n }\n\n if (!dashboardFilters || !dashboardFilters.length) {\n // Mapping references filters that don't exist\n return {\n isValid: false,\n invalidFilterIds: [],\n missingFilterIds: filterMapping\n }\n }\n\n const invalidFilterIds: string[] = []\n const missingFilterIds: string[] = []\n\n filterMapping.forEach(filterId => {\n const dashboardFilter = dashboardFilters.find(df => df.id === filterId)\n\n if (!dashboardFilter) {\n // Filter ID in mapping doesn't exist in dashboard filters\n missingFilterIds.push(filterId)\n } else {\n // Check if filter is valid for the cube metadata\n const isValid = validateFilterForCube(dashboardFilter.filter, cubeMeta)\n if (!isValid) {\n invalidFilterIds.push(filterId)\n }\n }\n })\n\n return {\n isValid: invalidFilterIds.length === 0 && missingFilterIds.length === 0,\n invalidFilterIds,\n missingFilterIds\n }\n}\n\n/**\n * Extract all unique measures, dimensions, and timeDimensions used across all portlets in a dashboard\n * This helps create a filtered schema view showing only fields relevant to the dashboard\n * @param dashboardConfig - Dashboard configuration\n * @returns Object with unique measures, dimensions, and timeDimensions\n */\nexport function extractDashboardFields(\n dashboardConfig: DashboardConfig\n): { measures: Set<string>; dimensions: Set<string>; timeDimensions: Set<string> } {\n const measures = new Set<string>()\n const dimensions = new Set<string>()\n const timeDimensions = new Set<string>()\n\n // Iterate through all portlets\n dashboardConfig.portlets.forEach(portlet => {\n try {\n // Parse the query JSON\n const query = JSON.parse(portlet.query)\n\n // Extract measures\n if (query.measures && Array.isArray(query.measures)) {\n query.measures.forEach((measure: string) => measures.add(measure))\n }\n\n // Extract dimensions\n if (query.dimensions && Array.isArray(query.dimensions)) {\n query.dimensions.forEach((dimension: string) => dimensions.add(dimension))\n }\n\n // Extract timeDimensions\n if (query.timeDimensions && Array.isArray(query.timeDimensions)) {\n query.timeDimensions.forEach((td: any) => {\n if (td.dimension) {\n timeDimensions.add(td.dimension)\n }\n })\n }\n\n // Also extract from filters to catch any filtered fields\n if (query.filters) {\n extractFieldsFromFilters(query.filters).forEach(field => {\n // Try to determine if it's a measure, dimension, or timeDimension\n // by checking cube metadata or convention (add to dimensions by default)\n dimensions.add(field)\n })\n }\n } catch (e) {\n // Skip portlets with invalid query JSON\n console.warn('Failed to parse portlet query:', portlet.id, e)\n }\n })\n\n return { measures, dimensions, timeDimensions }\n}\n\n/**\n * Extract field names from filters recursively\n * @param filters - Filter array\n * @returns Array of unique field names\n */\nfunction extractFieldsFromFilters(filters: Filter[]): string[] {\n const fields: string[] = []\n\n filters.forEach(filter => {\n if ('member' in filter) {\n // SimpleFilter\n fields.push(filter.member)\n } else if ('type' in filter && 'filters' in filter) {\n // GroupFilter - recurse\n fields.push(...extractFieldsFromFilters(filter.filters))\n }\n })\n\n return [...new Set(fields)] // Return unique fields\n}\n\n/**\n * Time dimension type from CubeQuery\n */\ntype TimeDimension = {\n dimension: string\n granularity?: string\n dateRange?: string[] | string\n}\n\n/**\n * Helper to get date range from a SimpleFilter (backward compatible)\n * Reads from both dateRange and values for compatibility\n * Handles both:\n * - Preset ranges: [\"this quarter\"], [\"last 7 days\"] (single string value)\n * - Custom ranges: [\"2024-01-01\", \"2024-12-31\"] (two date values)\n */\nfunction getDateRangeFromFilter(filter: SimpleFilter): string[] | string | undefined {\n // Prefer dateRange for backward compatibility, fall back to values\n if (filter.dateRange) {\n return filter.dateRange\n }\n if (filter.values && filter.values.length > 0) {\n // Single value = preset like \"this quarter\", return as string\n // Multiple values = custom date range, return as array\n return filter.values.length === 1 ? filter.values[0] : filter.values\n }\n return undefined\n}\n\n/**\n * Apply universal time filters to a portlet's timeDimensions\n * Universal time filters apply their dateRange to ALL time dimensions in the portlet\n *\n * @param dashboardFilters - All dashboard filters\n * @param filterMapping - Filter IDs that apply to this portlet\n * @param portletTimeDimensions - The portlet's existing timeDimensions array\n * @returns Updated timeDimensions array with date ranges applied\n */\nexport function applyUniversalTimeFilters(\n dashboardFilters: DashboardFilter[] | undefined,\n filterMapping: string[] | undefined,\n portletTimeDimensions: TimeDimension[] | undefined\n): TimeDimension[] | undefined {\n // Return as-is if no time dimensions in portlet (skip silently)\n if (!portletTimeDimensions || portletTimeDimensions.length === 0) {\n return portletTimeDimensions\n }\n\n // If no mapping specified, no filters apply\n if (!filterMapping || filterMapping.length === 0) {\n return portletTimeDimensions\n }\n\n // Find applicable universal time filters that have valid date ranges\n const universalTimeFilters = dashboardFilters\n ?.filter(df => df.isUniversalTime && filterMapping.includes(df.id))\n ?.filter(df => {\n // Must be a SimpleFilter with a valid dateRange\n if (!('member' in df.filter)) return false\n const simpleFilter = df.filter as SimpleFilter\n const dateRange = getDateRangeFromFilter(simpleFilter)\n return dateRange !== undefined\n })\n\n if (!universalTimeFilters || universalTimeFilters.length === 0) {\n return portletTimeDimensions\n }\n\n // Use the first universal time filter's dateRange (typically only one)\n const timeFilter = universalTimeFilters[0]\n const simpleFilter = timeFilter.filter as SimpleFilter\n const dateRange = getDateRangeFromFilter(simpleFilter)\n\n // Apply dateRange to ALL time dimensions (dashboard wins - overrides portlet dateRange)\n return portletTimeDimensions.map(td => ({\n ...td,\n dateRange: dateRange\n }))\n}\n","/**\n * Analytics Portlet Component\n * Simplified version with minimal dependencies\n */\n\nimport { useMemo, useState, forwardRef, useImperativeHandle, useEffect, useRef } from 'react'\nimport { useInView } from 'react-intersection-observer'\nimport { useCubeQuery } from '../hooks/useCubeQuery'\nimport { useScrollContainer } from '../providers/ScrollContainerContext'\nimport ChartErrorBoundary from './ChartErrorBoundary'\nimport LoadingIndicator from './LoadingIndicator'\nimport { LazyChart, isValidChartType } from '../charts/ChartLoader'\nimport { useChartConfig } from '../charts/lazyChartConfigRegistry'\nimport type { AnalyticsPortletProps } from '../types'\nimport { getApplicableDashboardFilters, mergeDashboardAndPortletFilters, applyUniversalTimeFilters } from '../utils/filterUtils'\n\n\ninterface AnalyticsPortletRef {\n refresh: () => void\n}\n\nconst AnalyticsPortlet = forwardRef<AnalyticsPortletRef, AnalyticsPortletProps>(({\n query,\n chartType,\n chartConfig,\n displayConfig,\n dashboardFilters,\n dashboardFilterMapping,\n eagerLoad = false,\n isVisible: _isVisible, // Deprecated - visibility now handled internally via useInView\n height = 300,\n title: _title,\n colorPalette,\n loadingComponent,\n onDebugDataReady\n}, ref) => {\n const [refreshCounter, setRefreshCounter] = useState(0)\n const onDebugDataReadyRef = useRef(onDebugDataReady)\n\n // Lazy loading: Use IntersectionObserver to detect when portlet is visible\n // Get scroll container from context (null = viewport, element = container scroll)\n const scrollContainer = useScrollContainer()\n const { ref: inViewRef, inView } = useInView({\n root: scrollContainer,\n rootMargin: '200px', // Start loading 200px before entering viewport\n triggerOnce: true, // Once visible, stay \"visible\" (don't unload data)\n initialInView: false, // Start as not visible, let observer determine actual state\n skip: eagerLoad // Skip observation entirely if eagerLoad is true\n })\n\n // Effective visibility: eagerLoad forces visible, otherwise use inView from IntersectionObserver\n // Note: Batching is handled by BatchCoordinator which collects queries for 100ms before flushing\n const isVisible = eagerLoad || inView\n\n // Update ref when callback changes\n useEffect(() => {\n onDebugDataReadyRef.current = onDebugDataReady\n }, [onDebugDataReady])\n\n // Check if this chart type skips queries (using lazy-loaded config)\n const { config: chartTypeConfig } = useChartConfig(chartType)\n const shouldSkipQuery = chartTypeConfig.skipQuery === true\n\n // Parse query from JSON string, merge dashboard filters, and include refresh counter to force re-query\n const queryObject = useMemo(() => {\n // Skip query parsing for charts that don't need queries\n if (shouldSkipQuery) {\n return null\n }\n\n try {\n const parsed = JSON.parse(query)\n\n // Get applicable dashboard filters (excluding universal time filters - they apply to timeDimensions)\n const regularFilters = dashboardFilters?.filter(df => !df.isUniversalTime)\n const applicableFilters = getApplicableDashboardFilters(regularFilters, dashboardFilterMapping)\n\n // Merge dashboard filters with portlet filters\n const mergedFilters = mergeDashboardAndPortletFilters(applicableFilters, parsed.filters)\n\n // Apply universal time filters to timeDimensions (dashboard wins over portlet dateRange)\n const mergedTimeDimensions = applyUniversalTimeFilters(\n dashboardFilters,\n dashboardFilterMapping,\n parsed.timeDimensions\n )\n\n return {\n ...parsed,\n filters: mergedFilters,\n timeDimensions: mergedTimeDimensions,\n __refresh_counter: refreshCounter\n }\n } catch (e) {\n console.error('AnalyticsPortlet: Invalid query JSON:', e)\n return null\n }\n }, [query, refreshCounter, shouldSkipQuery, dashboardFilters, dashboardFilterMapping])\n\n // Use the cube React hook (skip for charts that don't need queries or not visible for lazy loading)\n // Priority: shouldSkipQuery (chart type) > eagerLoad override > isVisible (lazy loading)\n const shouldSkip = !queryObject || shouldSkipQuery || (!eagerLoad && !isVisible)\n\n const { resultSet, isLoading, error } = useCubeQuery(queryObject, {\n skip: shouldSkip,\n resetResultSetOnChange: true\n })\n\n // Expose refresh function through ref\n useImperativeHandle(ref, () => ({\n refresh: () => {\n setRefreshCounter(prev => prev + 1)\n }\n }), [])\n\n\n // Send debug data to parent when ready (must be before any returns)\n useEffect(() => {\n if (onDebugDataReadyRef.current && chartConfig && queryObject && resultSet && !error) {\n const getData = () => {\n switch (chartType) {\n case 'pie':\n case 'table':\n return resultSet.tablePivot()\n default:\n return resultSet.rawData()\n }\n }\n const data = getData()\n \n if (data) {\n onDebugDataReadyRef.current({\n chartConfig: chartConfig || {},\n displayConfig: displayConfig || {},\n queryObject,\n data,\n chartType\n })\n }\n }\n }, [chartConfig, displayConfig, queryObject, resultSet, chartType, error]) // Use ref for callback to prevent infinite loops\n\n // Validate that chartConfig is provided when required (not required for skipQuery charts)\n // Check if any dropZones are mandatory for this chart type\n const hasMandatoryFields = !shouldSkipQuery && chartTypeConfig.dropZones.some(zone => zone.mandatory === true)\n \n if (!chartConfig && hasMandatoryFields) {\n return (\n <div ref={inViewRef} className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Required</div>\n <div className=\"text-xs text-dc-text-secondary\">Please configure this chart</div>\n </div>\n </div>\n )\n }\n\n // Show placeholder for lazy-loaded portlets that aren't visible yet\n if (!shouldSkipQuery && !eagerLoad && !isVisible) {\n return (\n <div ref={inViewRef} className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"w-8 h-8 mx-auto mb-2 rounded-full bg-dc-surface-secondary animate-pulse\" />\n <div className=\"text-xs text-dc-text-secondary\">Scroll to load</div>\n </div>\n </div>\n )\n }\n\n // Skip loading and error handling for charts that don't need queries\n if (!shouldSkipQuery) {\n if (isLoading || (queryObject && !resultSet && !error)) {\n return (\n <div ref={inViewRef} className=\"flex items-center justify-center w-full\" style={{ height }}>\n {loadingComponent || <LoadingIndicator size=\"md\" />}\n </div>\n )\n }\n\n if (error) {\n return (\n <div ref={inViewRef} className=\"p-4 border rounded-sm\" style={{ height, borderColor: 'var(--dc-border)', backgroundColor: 'var(--dc-surface)' }}>\n <div className=\"mb-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-medium text-sm\" style={{ color: 'var(--dc-text)' }}>⚠️ Query Error</span>\n <button\n onClick={() => setRefreshCounter(prev => prev + 1)}\n className=\"px-2 py-1 text-white rounded-sm text-xs\"\n style={{ backgroundColor: 'var(--dc-primary)' }}\n >\n Retry\n </button>\n </div>\n </div>\n\n <div className=\"mb-3\">\n <div className=\"text-xs p-2 rounded-sm border\" style={{ color: 'var(--dc-text-secondary)', backgroundColor: 'var(--dc-surface)', borderColor: 'var(--dc-border)' }}>\n {error.message || error.toString()}\n </div>\n </div>\n\n <div className=\"space-y-2 text-xs\">\n <details>\n <summary className=\"cursor-pointer font-medium\" style={{ color: 'var(--dc-text-secondary)' }}>Query (with filters applied)</summary>\n <pre className=\"mt-1 p-2 rounded-sm text-xs overflow-auto max-h-20\" style={{ backgroundColor: 'rgba(var(--dc-primary-rgb), 0.1)' }}>\n {queryObject ? JSON.stringify(queryObject, null, 2) : query}\n </pre>\n </details>\n\n <details>\n <summary className=\"cursor-pointer font-medium\" style={{ color: 'var(--dc-text-secondary)' }}>Chart Config</summary>\n <pre className=\"mt-1 p-2 rounded-sm text-xs overflow-auto max-h-20\" style={{ backgroundColor: 'rgba(var(--dc-primary-rgb), 0.05)' }}>\n {JSON.stringify({\n chartType,\n chartConfig,\n displayConfig: displayConfig\n }, null, 2)}\n </pre>\n </details>\n </div>\n </div>\n )\n }\n\n if (!resultSet || !queryObject) {\n return (\n <div ref={inViewRef} className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No data available</div>\n <div className=\"text-xs\">Invalid query or no results</div>\n </div>\n </div>\n )\n }\n }\n\n // Get data based on chart type needs\n const getData = () => {\n // Return empty array for charts that don't use query data\n if (shouldSkipQuery) {\n return []\n }\n \n // Return empty array if no resultSet\n if (!resultSet) {\n return []\n }\n \n switch (chartType) {\n case 'pie':\n case 'table':\n return resultSet.tablePivot()\n default:\n return resultSet.rawData()\n }\n }\n\n const data = getData()\n\n // Render appropriate chart component using lazy loading\n // Each chart type is dynamically imported for code splitting\n const renderChart = () => {\n try {\n const chartHeight = height\n\n // Handle unsupported chart types\n if (!isValidChartType(chartType)) {\n return (\n <div className=\"flex items-center justify-center w-full\" style={{ height }}>\n <div className=\"text-center text-dc-text-muted\">\n <div className=\"text-sm font-semibold mb-1\">Unsupported chart type</div>\n <div className=\"text-xs\">{chartType}</div>\n </div>\n </div>\n )\n }\n\n // For markdown chart, use empty data array\n const chartData = chartType === 'markdown' ? [] : data\n\n return (\n <LazyChart\n chartType={chartType}\n data={chartData}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n queryObject={queryObject ?? undefined}\n height={chartHeight}\n colorPalette={colorPalette}\n fallback={\n <div\n className=\"flex items-center justify-center w-full\"\n style={{ height: typeof chartHeight === 'number' ? `${chartHeight}px` : chartHeight }}\n >\n <div className=\"animate-pulse bg-dc-surface-secondary rounded w-full h-full min-h-[100px]\" />\n </div>\n }\n />\n )\n } catch (error) {\n console.error('Chart rendering error:', error)\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted p-4\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Unable to render chart</div>\n <div className=\"text-xs text-dc-text-secondary\">{error instanceof Error ? error.message : 'Unknown error'}</div>\n </div>\n </div>\n )\n }\n }\n\n return (\n <div ref={inViewRef} className=\"w-full h-full\">\n <ChartErrorBoundary\n portletTitle={_title}\n portletConfig={{\n chartType,\n chartConfig,\n displayConfig,\n height\n }}\n cubeQuery={query}\n >\n <div className=\"w-full h-full flex flex-col flex-1\" style={{ minHeight: '200px' }}>\n {renderChart()}\n </div>\n </ChartErrorBoundary>\n </div>\n )\n})\n\nAnalyticsPortlet.displayName = 'AnalyticsPortlet'\n\nexport default AnalyticsPortlet","import React, { useEffect, useCallback } from 'react'\n\nexport interface ModalProps {\n isOpen: boolean\n onClose: () => void\n title?: string\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'full' | 'fullscreen' | 'fullscreen-mobile'\n closeOnBackdropClick?: boolean\n closeOnEscape?: boolean\n showCloseButton?: boolean\n className?: string\n children: React.ReactNode\n footer?: React.ReactNode\n noPadding?: boolean\n}\n\nconst Modal: React.FC<ModalProps> = ({\n isOpen,\n onClose,\n title,\n size = 'md',\n closeOnBackdropClick = true,\n closeOnEscape = true,\n showCloseButton = true,\n children,\n footer,\n noPadding = false\n}) => {\n // Handle ESC key press\n const handleEscapeKey = useCallback((event: KeyboardEvent) => {\n if (event.key === 'Escape' && closeOnEscape) {\n onClose()\n }\n }, [closeOnEscape, onClose])\n\n\n // Manage ESC key listener and body scroll\n useEffect(() => {\n if (isOpen) {\n // Add ESC key listener\n if (closeOnEscape) {\n document.addEventListener('keydown', handleEscapeKey)\n }\n\n // Prevent body scroll when modal is open\n document.body.style.overflow = 'hidden'\n } else {\n // Restore body scroll\n document.body.style.overflow = 'unset'\n }\n\n // Cleanup\n return () => {\n document.removeEventListener('keydown', handleEscapeKey)\n document.body.style.overflow = 'unset'\n }\n }, [isOpen, closeOnEscape, handleEscapeKey])\n\n\n if (!isOpen) return null\n\n const getSizeClasses = () => {\n switch (size) {\n case 'sm':\n return 'max-w-md'\n case 'md':\n return 'max-w-lg'\n case 'lg':\n return 'max-w-2xl'\n case 'xl':\n return 'max-w-6xl'\n case 'xxl':\n return 'max-w-[1400px]' // Good for retina/mac displays\n case 'full':\n return 'max-w-7xl'\n case 'fullscreen':\n return 'w-[90vw] h-[90vh] max-w-none'\n case 'fullscreen-mobile':\n return 'w-full h-full md:w-[min(90vw,1400px)] md:h-[90vh]'\n default:\n return 'max-w-lg'\n }\n }\n\n return (\n <div\n className={`fixed inset-0 z-50 backdrop-blur-md ${size === 'fullscreen-mobile' ? 'flex md:flex md:items-center md:justify-center' : 'flex items-center justify-center'}`}\n style={{ backgroundColor: 'var(--dc-overlay)' }}\n onClick={closeOnBackdropClick ? onClose : undefined}\n >\n <div\n className={`relative bg-dc-surface border border-dc-border ${size === 'fullscreen-mobile' ? 'rounded-none md:rounded-lg' : 'rounded-lg'} ${size === 'fullscreen' || size === 'fullscreen-mobile' ? '' : 'mx-4'} ${getSizeClasses()} ${size === 'fullscreen' || size === 'fullscreen-mobile' ? '' : 'max-h-[90vh]'} flex flex-col`}\n style={{ boxShadow: 'var(--dc-shadow-2xl)' }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? 'modal-title' : undefined}\n >\n {/* Header */}\n {(title || showCloseButton) && (\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-dc-border\">\n {title && (\n <h2 id=\"modal-title\" className=\"text-xl font-semibold text-dc-text\">\n {title}\n </h2>\n )}\n {showCloseButton && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-dc-text-muted hover:text-dc-text-secondary transition-colors p-2 -mr-2\"\n aria-label=\"Close modal\"\n >\n <svg width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n )}\n </div>\n )}\n\n {/* Content */}\n <div className={`flex-1 overflow-y-auto ${noPadding ? '' : 'px-6 py-4'}`}>\n {children}\n </div>\n\n {/* Footer */}\n {footer && (\n <div className=\"flex items-center justify-end space-x-3 px-6 py-4 border-t border-dc-border bg-dc-surface-secondary\">\n {footer}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default Modal","import React from 'react'\nimport { getMeasureTypeIcon } from '../icons'\n\n/**\n * Get the appropriate icon component for a given measure type\n * All icons use amber coloring for consistency\n */\nexport function getMeasureIcon(\n measureType: string | undefined,\n className: string = 'w-4 h-4'\n): React.ReactElement {\n const IconComponent = getMeasureTypeIcon(measureType)\n return <IconComponent className={className} />\n}\n\n/**\n * Get all available measure type icons\n * Useful for documentation or UI that shows all measure types\n */\nexport function getAllMeasureIcons(): Record<string, React.ReactElement> {\n const types = ['count', 'countDistinct', 'countDistinctApprox', 'sum', 'avg', 'min', 'max', 'runningTotal', 'calculated', 'number']\n const icons: Record<string, React.ReactElement> = {}\n\n for (const type of types) {\n const IconComponent = getMeasureTypeIcon(type)\n icons[type] = <IconComponent className=\"w-4 h-4\" />\n }\n\n return icons\n}\n","/**\n * CubeMetaExplorer Component\n * \n * Displays the cube schema in a collapsible tree view.\n * Users can click on dimensions, measures, and time dimensions to add them to their query.\n */\n\nimport React, { useState, Suspense, lazy } from 'react'\nimport type { CubeMetaExplorerProps, MetaCube, MetaField } from './types'\nimport { getMeasureIcon } from '../../utils/measureIcons'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport { getIcon } from '../../icons'\n\n// Lazy load the relationship diagram (imports reactflow which is large)\nconst CubeRelationshipDiagram = lazy(() =>\n import('../CubeRelationshipDiagram').then(mod => ({ default: mod.CubeRelationshipDiagram }))\n)\n\ntype SchemaViewType = 'tree' | 'diagram'\n\nconst CubeMetaExplorer: React.FC<CubeMetaExplorerProps> = ({\n schema,\n schemaStatus,\n schemaError,\n selectedFields,\n onFieldSelect,\n onFieldDeselect,\n onRetrySchema,\n onOpenSettings,\n onViewTypeChange,\n isExpanded = false\n}) => {\n // Get icons\n const ChevronDownIcon = getIcon('chevronDown')\n const ChevronRightIcon = getIcon('chevronRight')\n const WarningIcon = getIcon('warning')\n const RefreshIcon = getIcon('refresh')\n const SettingsIcon = getIcon('settings')\n const MeasureIcon = getIcon('measure')\n const DimensionIcon = getIcon('dimension')\n const TimeDimensionIcon = getIcon('timeDimension')\n const SegmentIcon = getIcon('segment')\n const MenuIcon = getIcon('menu')\n\n // Get features from context to check if schema diagram is enabled\n const { features } = useCubeContext()\n const showSchemaDiagram = features?.showSchemaDiagram === true\n\n const [expandedCubes, setExpandedCubes] = useState<Set<string>>(new Set())\n const [expandedSections, setExpandedSections] = useState<Set<string>>(new Set())\n const [searchTerm, setSearchTerm] = useState('')\n const [viewType, setViewType] = useState<SchemaViewType>('tree')\n\n // Track the original expansion state before search\n const [preSearchExpandedCubes, setPreSearchExpandedCubes] = useState<Set<string> | null>(null)\n const [preSearchExpandedSections, setPreSearchExpandedSections] = useState<Set<string> | null>(null)\n\n // Auto-switch to diagram view when expanded (only if schema diagram is enabled)\n React.useEffect(() => {\n if (isExpanded && showSchemaDiagram) {\n setViewType('diagram')\n }\n }, [isExpanded, showSchemaDiagram])\n\n // Auto-expand cubes and sections that contain search matches\n React.useEffect(() => {\n if (!schema) {\n return\n }\n\n const hasSearchTerm = searchTerm.trim().length > 0\n\n if (hasSearchTerm) {\n // Save current state before expanding for search (only if not already saved)\n if (preSearchExpandedCubes === null) {\n setPreSearchExpandedCubes(new Set(expandedCubes))\n setPreSearchExpandedSections(new Set(expandedSections))\n }\n\n const newExpandedCubes = new Set<string>()\n const newExpandedSections = new Set<string>()\n\n schema.cubes.forEach((cube: MetaCube) => {\n let cubeHasMatches = false\n\n // Check measures\n const matchingMeasures = cube.measures.filter(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n if (matchingMeasures.length > 0) {\n cubeHasMatches = true\n newExpandedSections.add(`${cube.name}-measures`)\n }\n\n // Check regular dimensions\n const regularDimensions = cube.dimensions.filter(d => d.type !== 'time')\n const matchingDimensions = regularDimensions.filter(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n if (matchingDimensions.length > 0) {\n cubeHasMatches = true\n newExpandedSections.add(`${cube.name}-dimensions`)\n }\n\n // Check time dimensions\n const timeDimensions = cube.dimensions.filter(d => d.type === 'time')\n const matchingTimeDimensions = timeDimensions.filter(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n if (matchingTimeDimensions.length > 0) {\n cubeHasMatches = true\n newExpandedSections.add(`${cube.name}-timeDimensions`)\n }\n\n // If cube has any matches, expand it\n if (cubeHasMatches) {\n newExpandedCubes.add(cube.name)\n }\n })\n\n // Combine pre-search state with search expansions\n const combinedCubes = new Set([...(preSearchExpandedCubes || []), ...newExpandedCubes])\n const combinedSections = new Set([...(preSearchExpandedSections || []), ...newExpandedSections])\n \n setExpandedCubes(combinedCubes)\n setExpandedSections(combinedSections)\n } else {\n // No search term - restore original state if we have it saved\n if (preSearchExpandedCubes !== null && preSearchExpandedSections !== null) {\n setExpandedCubes(preSearchExpandedCubes)\n setExpandedSections(preSearchExpandedSections)\n setPreSearchExpandedCubes(null)\n setPreSearchExpandedSections(null)\n }\n }\n }, [schema, searchTerm, preSearchExpandedCubes, preSearchExpandedSections])\n\n // Loading state\n if (schemaStatus === 'loading') {\n return (\n <div className=\"h-full flex items-center justify-center text-dc-text-muted\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 mx-auto mb-3\" style={{ borderBottomColor: 'var(--dc-primary)' }}></div>\n <div className=\"text-sm font-semibold mb-1\">Loading Schema...</div>\n <div className=\"text-xs\">Fetching cube metadata</div>\n </div>\n </div>\n )\n }\n\n // Error state\n if (schemaStatus === 'error') {\n const isCorsError = schemaError?.toLowerCase().includes('cors') || \n schemaError?.toLowerCase().includes('fetch')\n \n return (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center max-w-sm p-6\">\n <WarningIcon className=\"w-12 h-12 mx-auto text-red-500 mb-4\" />\n <div className=\"text-sm font-semibold text-dc-text mb-2\">\n Failed to Load Schema\n </div>\n <div className=\"text-xs text-dc-text-secondary mb-4\">\n {isCorsError ? (\n <>\n CORS error detected. The API endpoint may be incorrect or not accessible.\n </>\n ) : (\n <>\n {schemaError || 'Unable to connect to the Cube.js API'}\n </>\n )}\n </div>\n \n <div className=\"space-y-2\">\n {onRetrySchema && (\n <button\n onClick={onRetrySchema}\n className=\"w-full flex items-center justify-center space-x-2 px-3 py-2 text-sm font-medium text-blue-700 bg-blue-100 border border-blue-200 rounded-md hover:bg-blue-200 focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n >\n <RefreshIcon className=\"w-4 h-4\" />\n <span>Retry</span>\n </button>\n )}\n\n {onOpenSettings && (\n <button\n onClick={onOpenSettings}\n className=\"w-full flex items-center justify-center space-x-2 px-3 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n >\n <SettingsIcon className=\"w-4 h-4\" />\n <span>Check API Settings</span>\n </button>\n )}\n </div>\n \n {isCorsError && (\n <div className=\"mt-4 p-3 bg-amber-50 border border-amber-200 rounded-md\">\n <div className=\"text-xs text-amber-800\">\n <div className=\"font-medium mb-1\">Common solutions:</div>\n <ul className=\"list-disc list-inside space-y-1\">\n <li>Verify the Base API URL is correct</li>\n <li>Ensure the server supports CORS</li>\n <li>Check if authentication is required</li>\n </ul>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n }\n\n // No schema loaded yet\n if (!schema) {\n return (\n <div className=\"h-full flex items-center justify-center text-dc-text-muted\">\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No Schema</div>\n <div className=\"text-xs\">Schema not loaded</div>\n </div>\n </div>\n )\n }\n\n const toggleCubeExpansion = (cubeName: string) => {\n const newExpanded = new Set(expandedCubes)\n if (newExpanded.has(cubeName)) {\n newExpanded.delete(cubeName)\n } else {\n newExpanded.add(cubeName)\n }\n setExpandedCubes(newExpanded)\n \n // If we're in search mode, also update the pre-search state\n if (preSearchExpandedCubes !== null) {\n const newPreSearchExpanded = new Set(preSearchExpandedCubes)\n if (newPreSearchExpanded.has(cubeName)) {\n newPreSearchExpanded.delete(cubeName)\n } else {\n newPreSearchExpanded.add(cubeName)\n }\n setPreSearchExpandedCubes(newPreSearchExpanded)\n }\n }\n\n const toggleSectionExpansion = (sectionKey: string) => {\n const newExpanded = new Set(expandedSections)\n if (newExpanded.has(sectionKey)) {\n newExpanded.delete(sectionKey)\n } else {\n newExpanded.add(sectionKey)\n }\n setExpandedSections(newExpanded)\n \n // If we're in search mode, also update the pre-search state\n if (preSearchExpandedSections !== null) {\n const newPreSearchExpanded = new Set(preSearchExpandedSections)\n if (newPreSearchExpanded.has(sectionKey)) {\n newPreSearchExpanded.delete(sectionKey)\n } else {\n newPreSearchExpanded.add(sectionKey)\n }\n setPreSearchExpandedSections(newPreSearchExpanded)\n }\n }\n\n const handleFieldClick = (field: MetaField, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n const isSelected = (() => {\n switch (fieldType) {\n case 'measures':\n return selectedFields.measures.includes(field.name)\n case 'dimensions':\n return selectedFields.dimensions.includes(field.name)\n case 'timeDimensions':\n return selectedFields.timeDimensions.includes(field.name)\n default:\n return false\n }\n })()\n\n if (isSelected) {\n onFieldDeselect(field.name, fieldType)\n } else {\n onFieldSelect(field.name, fieldType)\n }\n }\n\n const filterFields = (fields: MetaField[]): MetaField[] => {\n if (!searchTerm) return fields\n return fields.filter(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n }\n\n const cubeHasMatches = (cube: MetaCube): boolean => {\n if (!searchTerm.trim()) return true\n \n const measureMatches = cube.measures.some(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n \n const dimensionMatches = cube.dimensions.some(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n \n return measureMatches || dimensionMatches\n }\n\n const FieldItem: React.FC<{ \n field: MetaField\n fieldType: 'measures' | 'dimensions' | 'timeDimensions'\n icon: React.ReactNode\n }> = ({ field, fieldType, icon }) => {\n const isSelected = (() => {\n switch (fieldType) {\n case 'measures':\n return selectedFields.measures.includes(field.name)\n case 'dimensions':\n return selectedFields.dimensions.includes(field.name)\n case 'timeDimensions':\n return selectedFields.timeDimensions.includes(field.name)\n default:\n return false\n }\n })()\n\n const getSelectedStyles = () => {\n if (!isSelected) return 'hover:bg-dc-surface-hover text-dc-text-secondary'\n\n switch (fieldType) {\n case 'measures':\n return 'bg-amber-100 text-amber-800 border border-amber-200'\n case 'dimensions':\n return 'bg-green-100 text-green-800 border border-green-200'\n case 'timeDimensions':\n return 'bg-blue-100 text-blue-800 border border-blue-200'\n default:\n return 'bg-blue-100 text-blue-800 border border-blue-200'\n }\n }\n\n const getIconColor = () => {\n if (!isSelected) return 'text-dc-text-muted'\n \n switch (fieldType) {\n case 'measures':\n return 'text-amber-600'\n case 'dimensions':\n return 'text-green-600'\n case 'timeDimensions':\n return 'text-blue-600'\n default:\n return 'text-blue-600'\n }\n }\n\n const getCheckmarkColor = () => {\n switch (fieldType) {\n case 'measures':\n return 'text-amber-600'\n case 'dimensions':\n return 'text-green-600'\n case 'timeDimensions':\n return 'text-blue-600'\n default:\n return 'text-blue-600'\n }\n }\n\n return (\n <div\n className={`flex items-center px-2 py-1.5 text-xs cursor-pointer rounded-md transition-colors ${getSelectedStyles()}`}\n onClick={() => handleFieldClick(field, fieldType)}\n title={field.description || field.title}\n >\n <div className={`mr-1.5 ${getIconColor()}`}>\n {React.cloneElement(icon as React.ReactElement, { className: 'w-4 h-4' })}\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"font-medium truncate text-xs\">{field.shortTitle}</div>\n <div className=\"text-xs text-dc-text-muted truncate\">{field.name}</div>\n </div>\n {isSelected && (\n <div className={`ml-1.5 ${getCheckmarkColor()}`}>\n <svg className=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fillRule=\"evenodd\" d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\" clipRule=\"evenodd\" />\n </svg>\n </div>\n )}\n </div>\n )\n }\n\n const SectionHeader: React.FC<{\n title: string\n count: number\n sectionKey: string\n icon: React.ReactNode\n }> = ({ title, count, sectionKey, icon }) => {\n const isExpanded = expandedSections.has(sectionKey)\n \n // Get section type from sectionKey to apply consistent colors\n const getSectionType = (): 'dimensions' | 'timeDimensions' | 'measures' => {\n if (sectionKey.includes('-dimensions') && !sectionKey.includes('-timeDimensions')) {\n return 'dimensions'\n } else if (sectionKey.includes('-timeDimensions')) {\n return 'timeDimensions'\n } else {\n return 'measures'\n }\n }\n \n const getSectionColorClasses = () => {\n const sectionType = getSectionType()\n switch (sectionType) {\n case 'dimensions':\n return 'text-green-800'\n case 'timeDimensions':\n return 'text-blue-800'\n case 'measures':\n return 'text-amber-800'\n default:\n return 'text-gray-700'\n }\n }\n \n return (\n <div\n className={`flex items-center px-2 py-1 text-sm font-semibold cursor-pointer hover:bg-dc-surface-hover rounded-md ${getSectionColorClasses()}`}\n onClick={() => toggleSectionExpansion(sectionKey)}\n >\n <div className=\"mr-1.5\">\n {isExpanded ? (\n <ChevronDownIcon className=\"w-3 h-3\" />\n ) : (\n <ChevronRightIcon className=\"w-3 h-3\" />\n )}\n </div>\n <div className=\"mr-1.5\">\n {icon}\n </div>\n <span className=\"flex-1\">{title}</span>\n <span className=\"text-xs text-dc-text-muted bg-dc-surface-secondary px-1.5 py-0.5 rounded-full\">\n {count}\n </span>\n </div>\n )\n }\n\n const NoMatchesMessage: React.FC = () => (\n <div className=\"flex items-center justify-center py-8 text-center\">\n <div className=\"max-w-sm\">\n <div className=\"text-dc-text-muted mb-2\">\n <svg className=\"w-12 h-12 mx-auto\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5} d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n </div>\n <div className=\"text-sm font-medium text-dc-text mb-1\">No matches found</div>\n <div className=\"text-xs text-dc-text-muted mb-3\">\n No fields match your search term \"{searchTerm}\"\n </div>\n <button\n onClick={() => setSearchTerm('')}\n className=\"inline-flex items-center px-3 py-1.5 text-xs font-medium text-blue-700 bg-blue-100 border border-blue-200 rounded-md hover:bg-blue-200 focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n >\n Clear search\n </button>\n </div>\n </div>\n )\n\n return (\n <div className=\"flex-1 flex flex-col bg-dc-surface border border-dc-border rounded-lg min-h-0\">\n {/* Header */}\n <div className=\"border-b border-dc-border\">\n <div className=\"p-3 pb-0\">\n <div className=\"flex items-center justify-between mb-3\">\n <div>\n <h3 className=\"text-base font-semibold text-dc-text\">\n {viewType === 'diagram' ? 'Schema Diagram' : 'Schema Explorer'}\n </h3>\n </div>\n <div className=\"flex items-center space-x-2\">\n {onOpenSettings && (\n <button\n onClick={onOpenSettings}\n className=\"p-1 text-dc-text-muted hover:text-dc-text-secondary transition-colors\"\n title=\"Open settings\"\n >\n <SettingsIcon className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n </div>\n\n {/* View Type Tabs and Search */}\n <div className=\"flex items-center gap-3 mb-3\">\n {showSchemaDiagram ? (\n <div className=\"flex space-x-1 bg-dc-surface-secondary p-1 rounded-md\">\n <button\n onClick={() => {\n setViewType('tree')\n onViewTypeChange?.('tree')\n }}\n className={`\n flex items-center px-3 py-1.5 rounded text-xs font-medium transition-colors\n ${viewType === 'tree'\n ? 'bg-dc-surface text-dc-text shadow-xs'\n : 'text-dc-text-secondary hover:text-dc-text'\n }\n `}\n >\n <MenuIcon className=\"w-3 h-3 mr-1.5\" />\n Fields\n </button>\n <button\n onClick={() => {\n setViewType('diagram')\n onViewTypeChange?.('diagram')\n }}\n className={`\n flex items-center px-3 py-1.5 rounded text-xs font-medium transition-colors\n ${viewType === 'diagram'\n ? 'bg-dc-surface text-dc-text shadow-xs'\n : 'text-dc-text-secondary hover:text-dc-text'\n }\n `}\n >\n <SegmentIcon className=\"w-3 h-3 mr-1.5\" />\n Schema\n </button>\n </div>\n ) : null}\n\n {/* Search input - visible for both views */}\n <div className=\"flex-1 relative min-w-0\">\n <input\n type=\"text\"\n placeholder=\"Search fields...\"\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n className=\"w-full px-2 py-1.5 border border-dc-border rounded-md text-sm bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n <div className=\"absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none\">\n <svg className=\"h-4 w-4 text-dc-text-muted\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n </div>\n </div>\n </div>\n </div>\n\n </div>\n\n {/* Content */}\n <div className=\"flex-1 min-h-0 overflow-hidden\">\n {viewType === 'diagram' && showSchemaDiagram ? (\n /* Diagram View - schema relationship diagram (only when enabled) */\n <div className=\"h-full\">\n <Suspense fallback={\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"animate-pulse text-dc-text-muted\">Loading diagram...</div>\n </div>\n }>\n <CubeRelationshipDiagram\n className=\"h-full\"\n onCubeClick={(cubeName) => {\n if (!isExpanded) {\n // Auto-expand the clicked cube in tree view\n setExpandedCubes(prev => new Set([...prev, cubeName]))\n // Switch to tree view to show the expanded cube\n setViewType('tree')\n }\n }}\n onFieldClick={(cubeName, fieldName, fieldType) => {\n // Convert field type to QueryBuilder expected type and determine if time dimension\n let qbFieldType: 'measures' | 'dimensions' | 'timeDimensions'\n \n if (fieldType === 'measure') {\n qbFieldType = 'measures'\n } else {\n // For dimensions, check if it's a time dimension by looking at the schema\n const cube = schema?.cubes.find(c => c.name === cubeName)\n const dimension = cube?.dimensions.find(d => \n d.name === `${cubeName}.${fieldName}` || d.name === fieldName\n )\n \n qbFieldType = dimension?.type === 'time' ? 'timeDimensions' : 'dimensions'\n }\n \n const fullFieldName = `${cubeName}.${fieldName}`\n \n // Check if field is already selected\n const isSelected = selectedFields[qbFieldType].includes(fullFieldName)\n \n if (isSelected) {\n // Remove the field from the query\n onFieldDeselect(fullFieldName, qbFieldType)\n } else {\n // Add the field to the query\n onFieldSelect(fullFieldName, qbFieldType)\n }\n }}\n highlightedCubes={[\n ...selectedFields.measures.map(field => field.split('.')[0]),\n ...selectedFields.dimensions.map(field => field.split('.')[0]),\n ...selectedFields.timeDimensions.map(field => field.split('.')[0])\n ].filter((cube, index, arr) => arr.indexOf(cube) === index)} // Remove duplicates\n highlightedFields={[\n ...selectedFields.measures,\n ...selectedFields.dimensions,\n ...selectedFields.timeDimensions\n ]}\n searchTerm={searchTerm}\n />\n </Suspense>\n </div>\n ) : (\n /* Tree View - existing field list */\n <div className=\"h-full p-3 space-y-2 overflow-y-auto\">\n {(() => {\n // Filter cubes to only show those with matches (when searching)\n const filteredCubes = schema.cubes.filter(cubeHasMatches)\n \n // Show \"No matches\" message if searching but no cubes have matches\n if (searchTerm.trim() && filteredCubes.length === 0) {\n return <NoMatchesMessage />\n }\n \n return filteredCubes.map((cube: MetaCube) => {\n const isExpanded = expandedCubes.has(cube.name)\n const timeDimensions = cube.dimensions.filter(d => d.type === 'time')\n const regularDimensions = cube.dimensions.filter(d => d.type !== 'time')\n\n return (\n <div key={cube.name} className=\"border border-dc-border rounded-lg\">\n {/* Cube Header */}\n <div\n className=\"flex items-center px-3 py-2 cursor-pointer hover:bg-dc-surface-hover rounded-t-lg\"\n onClick={() => toggleCubeExpansion(cube.name)}\n >\n <div className=\"mr-2\">\n {isExpanded ? (\n <ChevronDownIcon className=\"w-4 h-4 text-dc-text-secondary\" />\n ) : (\n <ChevronRightIcon className=\"w-4 h-4 text-dc-text-secondary\" />\n )}\n </div>\n <div className=\"flex-1\">\n <div className=\"font-medium text-sm text-dc-text\">{cube.title}</div>\n <div className=\"text-xs text-dc-text-muted\">{cube.description}</div>\n </div>\n </div>\n\n {/* Cube Content */}\n {isExpanded && (\n <div className=\"border-t border-dc-border p-2 space-y-1\">\n {/* Dimensions - First (matching QueryPanel order) */}\n {regularDimensions.length > 0 && filterFields(regularDimensions).length > 0 && (\n <div>\n <SectionHeader\n title=\"Dimensions\"\n count={filterFields(regularDimensions).length}\n sectionKey={`${cube.name}-dimensions`}\n icon={<DimensionIcon className=\"w-4 h-4 text-green-600\" />}\n />\n {expandedSections.has(`${cube.name}-dimensions`) && (\n <div className=\"ml-5 space-y-1 mt-1\">\n {filterFields(regularDimensions).map(dimension => (\n <FieldItem\n key={dimension.name}\n field={dimension}\n fieldType=\"dimensions\"\n icon={<DimensionIcon className=\"w-4 h-4\" />}\n />\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Time Dimensions - Second (matching QueryPanel order) */}\n {timeDimensions.length > 0 && filterFields(timeDimensions).length > 0 && (\n <div>\n <SectionHeader\n title=\"Time Dimensions\"\n count={filterFields(timeDimensions).length}\n sectionKey={`${cube.name}-timeDimensions`}\n icon={<TimeDimensionIcon className=\"w-4 h-4 text-blue-600\" />}\n />\n {expandedSections.has(`${cube.name}-timeDimensions`) && (\n <div className=\"ml-5 space-y-1 mt-1\">\n {filterFields(timeDimensions).map(timeDimension => (\n <FieldItem\n key={timeDimension.name}\n field={timeDimension}\n fieldType=\"timeDimensions\"\n icon={<TimeDimensionIcon className=\"w-4 h-4\" />}\n />\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Measures - Third (matching QueryPanel order) */}\n {cube.measures.length > 0 && filterFields(cube.measures).length > 0 && (\n <div>\n <SectionHeader\n title=\"Measures\"\n count={filterFields(cube.measures).length}\n sectionKey={`${cube.name}-measures`}\n icon={<MeasureIcon className=\"w-4 h-4 text-amber-600\" />}\n />\n {expandedSections.has(`${cube.name}-measures`) && (\n <div className=\"ml-5 space-y-1 mt-1\">\n {filterFields(cube.measures).map(measure => (\n <FieldItem\n key={measure.name}\n field={measure}\n fieldType=\"measures\"\n icon={getMeasureIcon(measure.type, 'w-4 h-4')}\n />\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n )\n })\n })()}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default CubeMetaExplorer","/**\n * Type definitions for QueryBuilder components\n */\n\nimport type { CubeQuery, FilterOperator, Filter, SimpleFilter, GroupFilter, ChartType, ChartAxisConfig, ChartDisplayConfig } from '../../types'\n\n// Meta endpoint response types\nexport interface MetaField {\n name: string // e.g., \"Employees.count\"\n title: string // e.g., \"Total Employees\"\n shortTitle: string // e.g., \"Total Employees\"\n type: string // e.g., \"count\", \"string\", \"time\", \"number\"\n description?: string // Optional description\n}\n\nexport interface MetaCube {\n name: string // e.g., \"Employees\"\n title: string // e.g., \"Employee Analytics\"\n description: string // e.g., \"Employee data and metrics\"\n measures: MetaField[] // e.g., \"Employees.count\"\n dimensions: MetaField[] // e.g., \"Employees.name\"\n segments: MetaField[] // Currently empty in examples\n}\n\nexport interface MetaResponse {\n cubes: MetaCube[]\n}\n\n// Query builder state types\nexport type ValidationStatus = 'idle' | 'validating' | 'valid' | 'invalid'\nexport type ExecutionStatus = 'idle' | 'loading' | 'success' | 'error'\nexport type SchemaStatus = 'idle' | 'loading' | 'success' | 'error'\n\nexport interface QueryBuilderState {\n query: CubeQuery // Current query being built\n schema: MetaResponse | null // Schema from /meta endpoint\n schemaStatus: SchemaStatus // Status of schema loading\n schemaError: string | null // Error from schema loading\n validationStatus: ValidationStatus\n validationError: string | null\n validationSql: { sql: string[], params: any[] } | null // Generated SQL from validation\n executionStatus: ExecutionStatus\n executionResults: any[] | null\n executionError: string | null\n totalRowCount: number | null // Total rows without limit\n totalRowCountStatus: 'idle' | 'loading' | 'success' | 'error'\n}\n\n// Query analysis types for debugging transparency\nexport type PrimaryCubeSelectionReason =\n | 'most_dimensions'\n | 'most_connected'\n | 'alphabetical_fallback'\n | 'single_cube'\n\nexport interface PrimaryCubeCandidate {\n cubeName: string\n dimensionCount: number\n joinCount: number\n canReachAll: boolean\n}\n\nexport interface PrimaryCubeAnalysis {\n selectedCube: string\n reason: PrimaryCubeSelectionReason\n explanation: string\n candidates?: PrimaryCubeCandidate[]\n}\n\nexport interface JoinPathStep {\n fromCube: string\n toCube: string\n relationship: 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany'\n joinType: 'inner' | 'left' | 'right' | 'full'\n joinColumns: Array<{\n sourceColumn: string\n targetColumn: string\n }>\n junctionTable?: {\n tableName: string\n sourceColumns: string[]\n targetColumns: string[]\n }\n}\n\nexport interface JoinPathAnalysis {\n targetCube: string\n pathFound: boolean\n path?: JoinPathStep[]\n pathLength?: number\n error?: string\n visitedCubes?: string[]\n}\n\nexport interface PreAggregationAnalysis {\n cubeName: string\n cteAlias: string\n reason: string\n measures: string[]\n joinKeys: Array<{\n sourceColumn: string\n targetColumn: string\n }>\n}\n\nexport interface QuerySummary {\n queryType: 'single_cube' | 'multi_cube_join' | 'multi_cube_cte'\n joinCount: number\n cteCount: number\n hasPreAggregation: boolean\n}\n\nexport interface QueryAnalysis {\n timestamp: string\n cubeCount: number\n cubesInvolved: string[]\n primaryCube: PrimaryCubeAnalysis\n joinPaths: JoinPathAnalysis[]\n preAggregations: PreAggregationAnalysis[]\n querySummary: QuerySummary\n warnings?: string[]\n}\n\n// Validation response from /dry-run endpoint\nexport interface ValidationResult {\n valid?: boolean // Our custom property (may not be present in official Cube.js)\n error?: string\n query?: CubeQuery\n sql?: {\n sql: string[]\n params: any[]\n }\n queryType?: string // Always present in successful Cube.js responses\n normalizedQueries?: any[]\n queryOrder?: string[]\n transformedQueries?: any[]\n pivotQuery?: any\n complexity?: string\n cubesUsed?: string[]\n joinType?: string\n // Query analysis for debugging transparency\n analysis?: QueryAnalysis\n}\n\n// API Configuration\nexport interface ApiConfig {\n baseApiUrl: string // Base URL for Cube API (default: '/cubejs-api/v1')\n apiToken: string // API token for authentication (default: empty)\n}\n\n// Component props\nexport interface QueryBuilderProps {\n className?: string // Optional CSS classes\n initialQuery?: CubeQuery // Initial query to load (overrides localStorage)\n disableLocalStorage?: boolean // Disable localStorage persistence\n hideSettings?: boolean // Hide the settings/configuration button\n enableSharing?: boolean // Enable share analysis button (default: false)\n onShare?: (url: string) => void // Callback when share URL is generated\n}\n\nexport interface QueryBuilderRef {\n getCurrentQuery: () => CubeQuery\n getValidationState: () => { status: ValidationStatus, result?: ValidationResult }\n getValidationResult: () => ValidationResult | null\n}\n\nexport interface CubeMetaExplorerProps {\n schema: MetaResponse | null\n schemaStatus: SchemaStatus\n schemaError: string | null\n selectedFields: {\n measures: string[]\n dimensions: string[]\n timeDimensions: string[]\n }\n onFieldSelect: (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => void\n onFieldDeselect: (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => void\n onRetrySchema?: () => void\n onOpenSettings?: () => void\n onExpandSchema?: (expanded: boolean) => void\n onViewTypeChange?: (viewType: 'tree' | 'diagram') => void\n isExpanded?: boolean\n}\n\n// Share button states\nexport type ShareButtonState = 'idle' | 'copied' | 'copied-no-chart'\n\nexport interface QueryPanelProps {\n query: CubeQuery\n schema: MetaResponse | null\n validationStatus: ValidationStatus\n validationError: string | null\n validationSql: { sql: string[], params: any[] } | null\n validationAnalysis?: QueryAnalysis | null // Query analysis for debugging transparency\n onValidate: () => void\n onExecute: () => void\n onRemoveField: (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => void\n onTimeDimensionGranularityChange: (dimensionName: string, granularity: string) => void\n onFiltersChange: (filters: Filter[]) => void\n onDateRangeChange: (timeDimension: string, dateRange: string | string[]) => void\n onDateRangeRemove: (timeDimension: string) => void\n onOrderChange: (fieldName: string, direction: 'asc' | 'desc' | null) => void\n onClearQuery?: () => void\n showSettings?: boolean // Show the settings/configuration button\n onSettingsClick?: () => void // Handler for settings button click\n onAIAssistantClick?: () => void // Handler for AI Assistant button click\n onSchemaClick?: () => void // Handler for Schema button click\n onShareClick?: () => void // Handler for share button click\n shareButtonState?: ShareButtonState // Current state of share button\n isViewingShared?: boolean // Whether viewing a shared analysis\n}\n\n// Available fields for chart configuration (derived from validation result)\nexport interface AvailableFields {\n dimensions: string[]\n timeDimensions: string[]\n measures: string[]\n}\n\nexport interface ResultsPanelProps {\n executionStatus: ExecutionStatus\n executionResults: any[] | null\n executionError: string | null\n query: CubeQuery\n displayLimit?: number\n onDisplayLimitChange?: (limit: number) => void\n totalRowCount?: number | null\n totalRowCountStatus?: 'idle' | 'loading' | 'success' | 'error'\n\n // Chart visualization props\n chartType?: ChartType\n chartConfig?: ChartAxisConfig\n displayConfig?: ChartDisplayConfig\n availableFields?: AvailableFields | null\n onChartTypeChange?: (type: ChartType) => void\n onChartConfigChange?: (config: ChartAxisConfig) => void\n onDisplayConfigChange?: (config: ChartDisplayConfig) => void\n\n // View state props\n activeView?: 'table' | 'chart'\n onActiveViewChange?: (view: 'table' | 'chart') => void\n}\n\n// Time dimension granularity options\nexport const TIME_GRANULARITIES = [\n { value: 'hour', label: 'Hour' },\n { value: 'day', label: 'Day' },\n { value: 'week', label: 'Week' },\n { value: 'month', label: 'Month' },\n { value: 'quarter', label: 'Quarter' },\n { value: 'year', label: 'Year' }\n] as const\n\nexport type TimeGranularity = typeof TIME_GRANULARITIES[number]['value']\n\n// Filter operator metadata\nexport interface FilterOperatorMeta {\n label: string\n description: string\n requiresValues: boolean\n supportsMultipleValues: boolean\n valueType: 'string' | 'number' | 'date' | 'boolean' | 'any'\n fieldTypes: string[] // Which field types support this operator\n}\n\nexport const FILTER_OPERATORS: Record<FilterOperator, FilterOperatorMeta> = {\n // String operators\n equals: {\n label: 'equals',\n description: 'Exact match',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'boolean', 'time']\n },\n notEquals: {\n label: 'not equals',\n description: 'Does not match',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'boolean', 'time']\n },\n contains: {\n label: 'contains',\n description: 'Contains text (case insensitive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notContains: {\n label: 'not contains',\n description: 'Does not contain text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n startsWith: {\n label: 'starts with',\n description: 'Starts with text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notStartsWith: {\n label: 'not starts with',\n description: 'Does not start with text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n endsWith: {\n label: 'ends with',\n description: 'Ends with text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notEndsWith: {\n label: 'not ends with',\n description: 'Does not end with text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n like: {\n label: 'like',\n description: 'SQL LIKE pattern matching (case sensitive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notLike: {\n label: 'not like',\n description: 'SQL NOT LIKE pattern matching (case sensitive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n ilike: {\n label: 'ilike',\n description: 'SQL ILIKE pattern matching (case insensitive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n // Numeric operators\n gt: {\n label: 'greater than',\n description: 'Greater than value',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n gte: {\n label: 'greater than or equal',\n description: 'Greater than or equal to value',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n lt: {\n label: 'less than',\n description: 'Less than value',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n lte: {\n label: 'less than or equal',\n description: 'Less than or equal to value',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n between: {\n label: 'between',\n description: 'Between two values (inclusive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n notBetween: {\n label: 'not between',\n description: 'Not between two values',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n // Array operators\n in: {\n label: 'in',\n description: 'Matches any of the provided values',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'boolean']\n },\n notIn: {\n label: 'not in',\n description: 'Does not match any of the provided values',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'boolean']\n },\n // Null/Empty operators\n set: {\n label: 'is set',\n description: 'Is not null/empty',\n requiresValues: false,\n supportsMultipleValues: false,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'time', 'boolean']\n },\n notSet: {\n label: 'is not set',\n description: 'Is null/empty',\n requiresValues: false,\n supportsMultipleValues: false,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'time', 'boolean']\n },\n isEmpty: {\n label: 'is empty',\n description: 'Is empty string or null',\n requiresValues: false,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n isNotEmpty: {\n label: 'is not empty',\n description: 'Is not empty string and not null',\n requiresValues: false,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n // Date operators\n inDateRange: {\n label: 'in date range',\n description: 'Between two dates',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'date',\n fieldTypes: ['time']\n },\n beforeDate: {\n label: 'before date',\n description: 'Before specified date',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'date',\n fieldTypes: ['time']\n },\n afterDate: {\n label: 'after date',\n description: 'After specified date',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'date',\n fieldTypes: ['time']\n },\n // Regex operators\n regex: {\n label: 'matches regex',\n description: 'Matches regular expression pattern',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notRegex: {\n label: 'not matches regex',\n description: 'Does not match regular expression pattern',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n // PostgreSQL array operators\n arrayContains: {\n label: 'array contains all',\n description: 'Array field contains all specified values (PostgreSQL only)',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'string',\n fieldTypes: ['string']\n },\n arrayOverlaps: {\n label: 'array contains any',\n description: 'Array field contains any of the specified values (PostgreSQL only)',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'string',\n fieldTypes: ['string']\n },\n arrayContained: {\n label: 'array values in',\n description: 'All array field values are within specified values (PostgreSQL only)',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'string',\n fieldTypes: ['string']\n }\n}\n\n// Filter builder component props\nexport interface FilterBuilderProps {\n filters: Filter[]\n schema: MetaResponse | null\n query: CubeQuery\n onFiltersChange: (filters: Filter[]) => void\n hideFieldSelector?: boolean // Hide the field selector (for universal time filters)\n}\n\nexport interface FilterItemProps {\n filter: SimpleFilter\n index: number\n onFilterChange: (index: number, filter: SimpleFilter) => void\n onFilterRemove: (index: number) => void\n schema: MetaResponse | null\n query: CubeQuery\n hideFieldSelector?: boolean // Hide the field selector (for read-only filters)\n hideOperatorSelector?: boolean // Hide the operator selector (for read-only filters)\n hideRemoveButton?: boolean // Hide the remove button (for read-only filters)\n}\n\nexport interface FilterGroupProps {\n group: GroupFilter\n index: number\n onGroupChange: (index: number, group: GroupFilter) => void\n onGroupChangeWithUnwrap?: (index: number, group: GroupFilter) => void\n onGroupRemove: (index: number) => void\n schema: MetaResponse | null\n query: CubeQuery\n depth: number\n}\n\nexport interface FilterValueSelectorProps {\n fieldName: string\n operator: FilterOperator\n values: any[]\n onValuesChange: (values: any[]) => void\n schema: MetaResponse | null\n}\n\n// Date range types\nexport type DateRangeType = \n | 'custom'\n | 'today'\n | 'yesterday' \n | 'this_week'\n | 'this_month'\n | 'this_quarter'\n | 'this_year'\n | 'last_7_days'\n | 'last_30_days'\n | 'last_week'\n | 'last_month'\n | 'last_quarter'\n | 'last_year'\n | 'last_12_months'\n | 'last_n_days'\n | 'last_n_weeks'\n | 'last_n_months'\n | 'last_n_quarters'\n | 'last_n_years'\n\nexport interface DateRangeOption {\n value: DateRangeType\n label: string\n}\n\nexport const DATE_RANGE_OPTIONS: DateRangeOption[] = [\n { value: 'custom', label: 'Custom' },\n { value: 'today', label: 'Today' },\n { value: 'yesterday', label: 'Yesterday' },\n { value: 'this_week', label: 'This week' },\n { value: 'this_month', label: 'This month' },\n { value: 'this_quarter', label: 'This quarter' },\n { value: 'this_year', label: 'This year' },\n { value: 'last_7_days', label: 'Last 7 days' },\n { value: 'last_30_days', label: 'Last 30 days' },\n { value: 'last_n_days', label: 'Last N days' },\n { value: 'last_week', label: 'Last week' },\n { value: 'last_n_weeks', label: 'Last N weeks' },\n { value: 'last_month', label: 'Last month' }, \n { value: 'last_12_months', label: 'Last 12 months' },\n { value: 'last_n_months', label: 'Last N months' },\n { value: 'last_quarter', label: 'Last quarter' },\n { value: 'last_n_quarters', label: 'Last N quarters' },\n { value: 'last_year', label: 'Last year' },\n { value: 'last_n_years', label: 'Last N years' }\n] as const\n\nexport interface DateRangeFilter {\n id: string\n timeDimension: string\n rangeType: DateRangeType\n startDate?: string\n endDate?: string\n}\n\n// Date range component props\nexport interface DateRangeSelectorProps {\n timeDimensions: string[]\n onDateRangeChange: (timeDimension: string, dateRange: string | string[]) => void\n onDateRangeRemove: (timeDimension: string) => void\n currentDateRanges: Record<string, string | string[]>\n}\n\nexport interface DateRangeFilterProps {\n timeDimensions: Array<{ dimension: string; granularity?: string; dateRange?: string | string[] }>\n onDateRangeChange: (timeDimension: string, dateRange: string | string[]) => void\n onDateRangeRemove: (timeDimension: string) => void\n}","/**\n * FilterValueSelector Component\n * \n * Smart input component that adapts to operator type:\n * - Combo box for equals/notEquals with API-fetched values\n * - Number input for numeric operators\n * - Date picker for date operators\n * - No input for set/notSet operators\n */\n\nimport React, { useState, useEffect, useRef, useCallback, useMemo } from 'react'\nimport { getIcon } from '../../icons'\nimport { useFilterValues } from '../../hooks/useFilterValues'\nimport { useDebounce } from '../../hooks/useDebounce'\nimport type { FilterValueSelectorProps } from './types'\nimport { FILTER_OPERATORS } from './types'\n\nconst ChevronDownIcon = getIcon('chevronDown')\nconst CloseIcon = getIcon('close')\n\nconst FilterValueSelector: React.FC<FilterValueSelectorProps> = ({\n fieldName,\n operator,\n values,\n onValuesChange,\n schema\n}) => {\n const operatorMeta = FILTER_OPERATORS[operator]\n const [isOpen, setIsOpen] = useState(false)\n const [searchText, setSearchText] = useState('')\n const [hasLoadedInitial, setHasLoadedInitial] = useState(false)\n const dropdownRef = useRef<HTMLDivElement>(null)\n const lastSearchedTerm = useRef<string>('')\n \n // Debounce the search text\n const debouncedSearchText = useDebounce(searchText, 300)\n \n // Check if the field is a dimension (not a measure)\n const isDimension = useMemo(() => schema ? schema.cubes.some(cube => \n cube.dimensions.some(dim => dim.name === fieldName)\n ) : false, [schema, fieldName])\n \n // Check if the field is a time dimension\n const isTimeDimension = useMemo(() => schema ? schema.cubes.some(cube => \n cube.dimensions.some(dim => dim.name === fieldName && dim.type === 'time')\n ) : false, [schema, fieldName])\n \n // Fetch distinct values for combo box (only for equals/notEquals/in/notIn on non-time dimensions)\n const shouldFetchValues = useMemo(() => \n (['equals', 'notEquals', 'in', 'notIn'].includes(operator)) && isDimension && !isTimeDimension,\n [operator, isDimension, isTimeDimension]\n )\n const shouldShowComboBox = shouldFetchValues\n \n const { \n values: distinctValues, \n loading: valuesLoading, \n error: valuesError,\n searchValues\n } = useFilterValues(fieldName, shouldFetchValues)\n \n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false)\n }\n }\n \n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [])\n \n // Load initial values when dropdown opens\n useEffect(() => {\n if (isOpen && shouldFetchValues && searchValues) {\n searchValues('', true) // Force load with empty search\n setHasLoadedInitial(true)\n lastSearchedTerm.current = ''\n }\n }, [isOpen, shouldFetchValues, searchValues])\n \n // Trigger search when debounced search text changes\n useEffect(() => {\n if (hasLoadedInitial && shouldFetchValues && searchValues && debouncedSearchText !== lastSearchedTerm.current) {\n lastSearchedTerm.current = debouncedSearchText\n searchValues(debouncedSearchText)\n }\n }, [debouncedSearchText, hasLoadedInitial, shouldFetchValues, searchValues])\n \n // Handle dropdown toggle\n const handleDropdownToggle = useCallback(() => {\n const newIsOpen = !isOpen\n setIsOpen(newIsOpen)\n \n // Reset search when closing dropdown\n if (!newIsOpen) {\n setSearchText('')\n lastSearchedTerm.current = ''\n }\n }, [isOpen])\n \n // Handle search input change\n const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const newSearchText = e.target.value\n setSearchText(newSearchText)\n }, [])\n \n // Handle value selection for combo box\n const handleValueSelect = useCallback((value: any) => {\n if (operatorMeta.supportsMultipleValues) {\n // Add to selection if not already selected\n if (!values.includes(value)) {\n onValuesChange([...values, value])\n }\n } else {\n // Replace current value\n onValuesChange([value])\n setIsOpen(false)\n }\n // Clear search after selection\n setSearchText('')\n }, [operatorMeta.supportsMultipleValues, values, onValuesChange])\n \n // Handle value removal for multi-select\n const handleValueRemove = useCallback((valueToRemove: any) => {\n onValuesChange(values.filter(v => v !== valueToRemove))\n }, [values, onValuesChange])\n \n // Handle direct text input for non-combo operators\n const handleDirectInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n if (operatorMeta.valueType === 'number') {\n const numValue = parseFloat(value)\n // Accept valid numbers including zero\n if (!isNaN(numValue)) {\n onValuesChange([numValue])\n } else if (value === '' || value === '-') {\n // Allow empty string or just a minus sign for negative numbers being typed\n onValuesChange([])\n }\n } else {\n onValuesChange(value ? [value] : [])\n }\n }, [operatorMeta.valueType, onValuesChange])\n \n // Handle date input\n const handleDateInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n if (operator === 'inDateRange') {\n // For date range, we need two values\n const currentValues = values.length >= 2 ? values : ['', '']\n onValuesChange([value, currentValues[1]])\n } else {\n // Single date value\n onValuesChange(value ? [value] : [])\n }\n }, [operator, values, onValuesChange])\n \n const handleDateRangeEndInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n const currentValues = values.length >= 2 ? values : ['', '']\n onValuesChange([currentValues[0], value])\n }, [values, onValuesChange])\n\n // Handle between/notBetween range inputs (must be defined at top level, not inside conditionals)\n const handleBetweenStartInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = parseFloat(e.target.value)\n const currentValues = values.length >= 2 ? values : ['', '']\n const newValues = [!isNaN(value) ? value : e.target.value === '' ? '' : currentValues[0], currentValues[1]]\n onValuesChange(newValues.filter(v => v !== ''))\n }, [values, onValuesChange])\n\n const handleBetweenEndInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = parseFloat(e.target.value)\n const currentValues = values.length >= 2 ? values : ['', '']\n const newValues = [currentValues[0], !isNaN(value) ? value : e.target.value === '' ? '' : currentValues[1]]\n onValuesChange(newValues.filter(v => v !== ''))\n }, [values, onValuesChange])\n\n // Render based on operator type\n if (!operatorMeta.requiresValues) {\n // No input needed for set/notSet\n return (\n <div className=\"text-sm text-dc-text-muted italic\">\n No value required\n </div>\n )\n }\n \n if (operator === 'inDateRange') {\n // Date range picker\n return (\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"date\"\n value={values[0] || ''}\n onChange={handleDateInput}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n <span className=\"text-sm text-dc-text-muted\">to</span>\n <input\n type=\"date\"\n value={values[1] || ''}\n onChange={handleDateRangeEndInput}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n </div>\n )\n }\n \n if (operator === 'between' || operator === 'notBetween') {\n // Between range picker (for numbers)\n return (\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"number\"\n value={values[0] !== undefined && values[0] !== null ? values[0] : ''}\n onChange={handleBetweenStartInput}\n placeholder=\"Min\"\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n <span className=\"text-sm text-dc-text-muted\">to</span>\n <input\n type=\"number\"\n value={values[1] !== undefined && values[1] !== null ? values[1] : ''}\n onChange={handleBetweenEndInput}\n placeholder=\"Max\"\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n </div>\n )\n }\n \n if (operatorMeta.valueType === 'date') {\n // Single date picker\n return (\n <input\n type=\"date\"\n value={values[0] || ''}\n onChange={handleDateInput}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n )\n }\n \n if (operatorMeta.valueType === 'number') {\n // Number input\n return (\n <input\n type=\"number\"\n value={values[0] !== undefined && values[0] !== null ? values[0] : ''}\n onChange={handleDirectInput}\n placeholder=\"Enter number\"\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n )\n }\n \n // Time dimension with equals/notEquals/in/notIn - use date picker\n if (isTimeDimension && (['equals', 'notEquals', 'in', 'notIn'].includes(operator))) {\n if (operatorMeta.supportsMultipleValues) {\n // Multi-select date picker (for notEquals that supports multiple values)\n return (\n <div className=\"space-y-2\">\n {/* Selected dates display */}\n {values.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {values.map((value, index) => (\n <div\n key={index}\n className=\"inline-flex items-center bg-dc-time-dimension text-dc-time-dimension text-xs px-2 py-1 rounded-sm border border-dc-time-dimension\"\n >\n <span className=\"mr-1\">{String(value)}</span>\n <button\n onClick={() => handleValueRemove(value)}\n className=\"text-blue-600 hover:text-blue-800 focus:outline-hidden\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n \n {/* Add new date */}\n <input\n type=\"date\"\n onChange={(e) => {\n if (e.target.value && !values.includes(e.target.value)) {\n onValuesChange([...values, e.target.value])\n e.target.value = '' // Clear the input\n }\n }}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n placeholder=\"Add date...\"\n />\n </div>\n )\n } else {\n // Single date picker\n return (\n <input\n type=\"date\"\n value={values[0] || ''}\n onChange={handleDateInput}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n )\n }\n }\n \n if (shouldShowComboBox) {\n // Combo box with API-fetched values\n return (\n <div className=\"relative\" ref={dropdownRef}>\n {/* Selected values display (for multi-select) */}\n {operatorMeta.supportsMultipleValues && values.length > 0 && (\n <div className=\"flex flex-wrap gap-1 mb-2\">\n {values.map((value, index) => (\n <div\n key={index}\n className=\"inline-flex items-center bg-dc-time-dimension text-dc-time-dimension text-xs px-2 py-1 rounded-sm border border-dc-time-dimension\"\n >\n <span className=\"mr-1\">{String(value)}</span>\n <button\n onClick={() => handleValueRemove(value)}\n className=\"text-blue-600 hover:text-blue-800 focus:outline-hidden\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n \n {/* Single value display (for single-select) */}\n {!operatorMeta.supportsMultipleValues && values.length > 0 && (\n <div className=\"mb-2\">\n <div className=\"inline-flex items-center bg-dc-time-dimension text-dc-time-dimension text-xs px-2 py-1 rounded-sm border border-dc-time-dimension\">\n <span className=\"mr-1\">{String(values[0])}</span>\n <button\n onClick={() => onValuesChange([])}\n className=\"text-blue-600 hover:text-blue-800 focus:outline-hidden\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n </div>\n )}\n \n {/* Dropdown trigger */}\n <button\n onClick={handleDropdownToggle}\n className=\"w-full text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500 flex items-center justify-between min-w-0\"\n >\n <span className=\"text-dc-text-muted truncate\">\n {valuesLoading && !hasLoadedInitial ? 'Loading values...' : 'Select value...'}\n </span>\n <ChevronDownIcon className=\"w-4 h-4 text-dc-text-muted\" />\n </button>\n\n {/* Dropdown menu */}\n {isOpen && (\n <div className=\"absolute z-30 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {/* Search input */}\n <div className=\"p-2 border-b border-dc-border\">\n <input\n type=\"text\"\n value={searchText}\n onChange={handleSearchChange}\n placeholder=\"Search values...\"\n className=\"w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n autoFocus\n />\n </div>\n\n {/* Values list */}\n <div className=\"max-h-48 overflow-y-auto\">\n {valuesLoading ? (\n <div className=\"p-2 text-sm text-dc-text-muted\">\n {searchText ? 'Searching...' : 'Loading values...'}\n </div>\n ) : valuesError ? (\n <div className=\"p-2 text-sm text-red-600\">\n Error loading values: {valuesError}\n </div>\n ) : distinctValues.length === 0 ? (\n <div className=\"p-2 text-sm text-dc-text-muted\">\n {searchText ? 'No matching values' : 'No values available'}\n </div>\n ) : (\n distinctValues.map((value, index) => {\n const isSelected = values.includes(value)\n\n return (\n <button\n key={`${value}-${index}`}\n onClick={() => handleValueSelect(value)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${\n isSelected ? 'bg-blue-50 text-blue-700' : 'text-dc-text-secondary'\n }`}\n >\n {String(value)}\n {isSelected && (\n <span className=\"float-right text-blue-600\">✓</span>\n )}\n </button>\n )\n })\n )}\n </div>\n </div>\n )}\n </div>\n )\n }\n \n // Fallback to text input\n return (\n <input\n type=\"text\"\n value={values[0] !== undefined && values[0] !== null ? values[0] : ''}\n onChange={handleDirectInput}\n placeholder={`Enter ${operatorMeta.valueType} value`}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n )\n}\n\nexport default FilterValueSelector","/**\n * Utility functions for QueryBuilder components\n */\n\nimport type { CubeQuery, Filter, SimpleFilter, GroupFilter } from '../../types'\nimport type { MetaField, MetaResponse } from './types'\nimport { FILTER_OPERATORS } from './types'\n\n/**\n * Check if a field is selected in the current query\n */\nexport function isFieldSelected(\n fieldName: string, \n fieldType: 'measures' | 'dimensions' | 'timeDimensions',\n query: CubeQuery\n): boolean {\n switch (fieldType) {\n case 'measures':\n return query.measures?.includes(fieldName) || false\n case 'dimensions':\n return query.dimensions?.includes(fieldName) || false\n case 'timeDimensions':\n return query.timeDimensions?.some(td => td.dimension === fieldName) || false\n default:\n return false\n }\n}\n\n/**\n * Get all time dimension fields from schema\n */\nexport function getTimeDimensionFields(schema: MetaResponse): MetaField[] {\n const timeDimensions: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n cube.dimensions.forEach(dimension => {\n if (dimension.type === 'time') {\n timeDimensions.push(dimension)\n }\n })\n })\n \n return timeDimensions\n}\n\n/**\n * Get all non-time dimension fields from schema\n */\nexport function getRegularDimensionFields(schema: MetaResponse): MetaField[] {\n const dimensions: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n cube.dimensions.forEach(dimension => {\n if (dimension.type !== 'time') {\n dimensions.push(dimension)\n }\n })\n })\n \n return dimensions\n}\n\n/**\n * Get all measure fields from schema\n */\nexport function getMeasureFields(schema: MetaResponse): MetaField[] {\n const measures: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n cube.measures.forEach(measure => {\n measures.push(measure)\n })\n })\n \n return measures\n}\n\n/**\n * Check if query has any content (measures, dimensions, or timeDimensions)\n */\nexport function hasQueryContent(query: CubeQuery): boolean {\n return Boolean(\n (query.measures && query.measures.length > 0) ||\n (query.dimensions && query.dimensions.length > 0) ||\n (query.timeDimensions && query.timeDimensions.length > 0)\n )\n}\n\n/**\n * Get count of selected fields across all types\n */\nexport function getSelectedFieldsCount(query: CubeQuery): number {\n let count = 0\n if (query.measures) count += query.measures.length\n if (query.dimensions) count += query.dimensions.length\n if (query.timeDimensions) count += query.timeDimensions.length\n return count\n}\n\n/**\n * Get cube name from field name (e.g., \"Employees.count\" -> \"Employees\")\n */\nexport function getCubeNameFromField(fieldName: string): string {\n return fieldName.split('.')[0]\n}\n\n/**\n * Group fields by cube name\n */\nexport function groupFieldsByCube(fields: MetaField[]): Record<string, MetaField[]> {\n return fields.reduce((groups, field) => {\n const cubeName = getCubeNameFromField(field.name)\n if (!groups[cubeName]) {\n groups[cubeName] = []\n }\n groups[cubeName].push(field)\n return groups\n }, {} as Record<string, MetaField[]>)\n}\n\n/**\n * Clean query object by removing empty arrays\n */\nexport function cleanQuery(query: CubeQuery): CubeQuery {\n const cleanedQuery: CubeQuery = {}\n \n if (query.measures && query.measures.length > 0) {\n cleanedQuery.measures = query.measures\n }\n \n if (query.dimensions && query.dimensions.length > 0) {\n cleanedQuery.dimensions = query.dimensions\n }\n \n if (query.timeDimensions && query.timeDimensions.length > 0) {\n cleanedQuery.timeDimensions = query.timeDimensions\n }\n \n if (query.filters && query.filters.length > 0) {\n cleanedQuery.filters = query.filters\n }\n \n if (query.order) {\n cleanedQuery.order = query.order\n }\n \n if (query.limit) {\n cleanedQuery.limit = query.limit\n }\n \n if (query.offset) {\n cleanedQuery.offset = query.offset\n }\n \n if (query.segments && query.segments.length > 0) {\n cleanedQuery.segments = query.segments\n }\n \n return cleanedQuery\n}\n\n/**\n * Clean a query and transform filters for server compatibility\n * This version transforms GroupFilter to legacy and/or format\n */\nexport function cleanQueryForServer(query: CubeQuery): CubeQuery {\n const cleanedQuery = cleanQuery(query)\n \n // Apply server transformation to filters\n if (cleanedQuery.filters && cleanedQuery.filters.length > 0) {\n cleanedQuery.filters = transformFiltersForServer(cleanedQuery.filters) as any\n }\n \n return cleanedQuery\n}\n\n/**\n * Create an empty query object\n */\nexport function createEmptyQuery(): CubeQuery {\n return {}\n}\n\n/**\n * Filter utility functions\n */\n\n/**\n * Check if a filter is a simple filter\n */\nexport function isSimpleFilter(filter: Filter): filter is SimpleFilter {\n return 'member' in filter && 'operator' in filter && 'values' in filter\n}\n\n/**\n * Check if a filter is a group filter\n */\nexport function isGroupFilter(filter: Filter): filter is GroupFilter {\n return 'type' in filter && 'filters' in filter\n}\n\n/**\n * Check if a filter is an AND filter\n */\nexport function isAndFilter(filter: Filter): filter is GroupFilter {\n return isGroupFilter(filter) && filter.type === 'and'\n}\n\n/**\n * Check if a filter is an OR filter\n */\nexport function isOrFilter(filter: Filter): filter is GroupFilter {\n return isGroupFilter(filter) && filter.type === 'or'\n}\n\n/**\n * Flatten all simple filters from a hierarchical filter structure\n */\nexport function flattenFilters(filters: Filter[]): SimpleFilter[] {\n const simple: SimpleFilter[] = []\n \n const flatten = (filter: Filter) => {\n if (isSimpleFilter(filter)) {\n simple.push(filter)\n } else if (isGroupFilter(filter)) {\n filter.filters.forEach(flatten)\n }\n }\n \n filters.forEach(flatten)\n return simple\n}\n\n/**\n * Get all filterable fields from schema (measures, dimensions, and time dimensions)\n * Returns ALL fields if no query provided, or only query fields if query provided\n */\nexport function getFilterableFields(schema: MetaResponse, query?: CubeQuery): MetaField[] {\n const allFields: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n allFields.push(...cube.measures)\n allFields.push(...cube.dimensions)\n })\n \n // If no query provided, return all fields\n if (!query) {\n return allFields.sort((a, b) => a.name.localeCompare(b.name))\n }\n \n // Get currently selected fields from the query\n const selectedFields = new Set<string>()\n \n // Add measures\n if (query.measures) {\n query.measures.forEach(measure => selectedFields.add(measure))\n }\n \n // Add dimensions\n if (query.dimensions) {\n query.dimensions.forEach(dimension => selectedFields.add(dimension))\n }\n \n // Add time dimensions\n if (query.timeDimensions) {\n query.timeDimensions.forEach(td => selectedFields.add(td.dimension))\n }\n \n // Filter to only include selected fields\n const filterableFields = allFields.filter(field => selectedFields.has(field.name))\n \n return filterableFields.sort((a, b) => a.name.localeCompare(b.name))\n}\n\n/**\n * Get ALL filterable fields from schema, regardless of query selection\n */\nexport function getAllFilterableFields(schema: MetaResponse): MetaField[] {\n const allFields: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n allFields.push(...cube.measures)\n allFields.push(...cube.dimensions)\n })\n \n return allFields.sort((a, b) => a.name.localeCompare(b.name))\n}\n\n/**\n * Get organized filter field options with query fields prioritized at top\n */\nexport function getOrganizedFilterFields(schema: MetaResponse, query?: CubeQuery): {\n queryFields: MetaField[]\n allFields: MetaField[]\n} {\n const allFields = getAllFilterableFields(schema)\n \n if (!query) {\n return {\n queryFields: [],\n allFields\n }\n }\n \n // Get currently selected fields from the query\n const selectedFields = new Set<string>()\n \n // Add measures\n if (query.measures) {\n query.measures.forEach(measure => selectedFields.add(measure))\n }\n \n // Add dimensions\n if (query.dimensions) {\n query.dimensions.forEach(dimension => selectedFields.add(dimension))\n }\n \n // Add time dimensions\n if (query.timeDimensions) {\n query.timeDimensions.forEach(td => selectedFields.add(td.dimension))\n }\n \n // Split fields into query fields and other fields\n const queryFields = allFields.filter(field => selectedFields.has(field.name))\n \n return {\n queryFields,\n allFields\n }\n}\n\n/**\n * Get available operators for a field type\n */\nexport function getAvailableOperators(fieldType: string): Array<{operator: string, label: string}> {\n const operators: Array<{operator: string, label: string}> = []\n \n for (const [operator, meta] of Object.entries(FILTER_OPERATORS)) {\n if (meta.fieldTypes.includes(fieldType)) {\n operators.push({\n operator,\n label: meta.label\n })\n }\n }\n \n return operators\n}\n\n/**\n * Get field type from schema\n */\nexport function getFieldType(fieldName: string, schema: MetaResponse): string {\n for (const cube of schema.cubes) {\n // Check measures\n const measure = cube.measures.find(m => m.name === fieldName)\n if (measure) return measure.type\n \n // Check dimensions\n const dimension = cube.dimensions.find(d => d.name === fieldName)\n if (dimension) return dimension.type\n }\n \n return 'string' // Default fallback\n}\n\n/**\n * Validate a filter\n */\nexport function validateFilter(filter: SimpleFilter, schema: MetaResponse): {\n isValid: boolean\n errors: string[]\n} {\n const errors: string[] = []\n \n // Check if field exists\n const fields = getFilterableFields(schema)\n const fieldExists = fields.some(f => f.name === filter.member)\n \n if (!fieldExists) {\n errors.push(`Field \"${filter.member}\" does not exist`)\n }\n \n // Check if operator is valid for field type\n if (fieldExists) {\n const fieldType = getFieldType(filter.member, schema)\n const operatorMeta = FILTER_OPERATORS[filter.operator]\n \n if (!operatorMeta) {\n errors.push(`Invalid operator \"${filter.operator}\"`)\n } else if (!operatorMeta.fieldTypes.includes(fieldType)) {\n errors.push(`Operator \"${filter.operator}\" is not valid for field type \"${fieldType}\"`)\n } else {\n // Check values\n if (operatorMeta.requiresValues && (!filter.values || filter.values.length === 0)) {\n errors.push(`Operator \"${filter.operator}\" requires values`)\n }\n \n if (!operatorMeta.supportsMultipleValues && filter.values && filter.values.length > 1) {\n errors.push(`Operator \"${filter.operator}\" does not support multiple values`)\n }\n }\n }\n \n return {\n isValid: errors.length === 0,\n errors\n }\n}\n\n/**\n * Count total filters in hierarchical structure\n */\nexport function countFilters(filters: Filter[]): number {\n let count = 0\n \n const countFilter = (filter: Filter) => {\n if (isSimpleFilter(filter)) {\n count++\n } else if (isGroupFilter(filter)) {\n filter.filters.forEach(countFilter)\n }\n }\n \n filters.forEach(countFilter)\n return count\n}\n\n/**\n * Create a new simple filter\n */\nexport function createSimpleFilter(member: string, operator: string = 'equals', values: any[] = []): SimpleFilter {\n return {\n member,\n operator: operator as any,\n values\n }\n}\n\n/**\n * Create a new AND filter group\n */\nexport function createAndFilter(filters: Filter[] = []): GroupFilter {\n return {\n type: 'and',\n filters\n }\n}\n\n/**\n * Create a new OR filter group\n */\nexport function createOrFilter(filters: Filter[] = []): GroupFilter {\n return {\n type: 'or',\n filters\n }\n}\n\n/**\n * Clean up filters by removing any that reference fields not in the current query\n * @deprecated This function is no longer used as we now support filtering on any schema field\n */\nexport function cleanupFilters(filters: Filter[], _query?: CubeQuery): Filter[] {\n // Return filters unchanged - we now support filtering on any field\n return filters || []\n}\n\n/**\n * Clean up filters by removing any that reference fields not in the current query (legacy)\n * Only used for backward compatibility - filters on non-query fields are now supported\n */\nexport function cleanupFiltersLegacy(filters: Filter[], query: CubeQuery): Filter[] {\n if (!filters || filters.length === 0) {\n return []\n }\n \n // Get currently selected fields from the query\n const selectedFields = new Set<string>()\n \n // Add measures\n if (query.measures) {\n query.measures.forEach(measure => selectedFields.add(measure))\n }\n \n // Add dimensions\n if (query.dimensions) {\n query.dimensions.forEach(dimension => selectedFields.add(dimension))\n }\n \n // Add time dimensions\n if (query.timeDimensions) {\n query.timeDimensions.forEach(td => selectedFields.add(td.dimension))\n }\n \n // Recursively clean filters\n const cleanFilter = (filter: Filter): Filter | null => {\n if (isSimpleFilter(filter)) {\n // Remove filter if its field is not selected\n return selectedFields.has(filter.member) ? filter : null\n } else if (isGroupFilter(filter)) {\n // Clean group recursively\n const cleanedFilters = filter.filters.map(cleanFilter).filter(f => f !== null) as Filter[]\n return cleanedFilters.length > 0 ? { type: filter.type, filters: cleanedFilters } : null\n }\n return null\n }\n \n // Clean all filters and remove nulls\n const cleanedFilters = filters.map(cleanFilter).filter(f => f !== null) as Filter[]\n \n return cleanedFilters\n}\n\n/**\n * Transform filters from new GroupFilter format to legacy server format\n * Server expects { and: [...] } and { or: [...] } instead of { type: 'and', filters: [...] }\n */\nexport function transformFiltersForServer(filters: Filter[]): any[] {\n const transformFilter = (filter: Filter): any => {\n if (isSimpleFilter(filter)) {\n return filter\n } else if (isGroupFilter(filter)) {\n const transformedSubFilters = filter.filters.map(transformFilter)\n \n if (filter.type === 'and') {\n return { and: transformedSubFilters }\n } else {\n return { or: transformedSubFilters }\n }\n }\n return filter\n }\n \n return filters.map(transformFilter)\n}\n\n/**\n * Date range utility functions\n */\n\n/**\n * Convert DateRangeType to Cube.js compatible date range format\n */\nexport function convertDateRangeTypeToValue(rangeType: string, number?: number): string {\n const typeMap: Record<string, string> = {\n 'today': 'today',\n 'yesterday': 'yesterday',\n 'this_week': 'this week',\n 'this_month': 'this month',\n 'this_quarter': 'this quarter',\n 'this_year': 'this year',\n 'last_7_days': 'last 7 days',\n 'last_30_days': 'last 30 days',\n 'last_week': 'last week',\n 'last_month': 'last month',\n 'last_quarter': 'last quarter',\n 'last_year': 'last year',\n 'last_12_months': 'last 12 months'\n }\n \n // Handle dynamic ranges with number input\n if (rangeType.startsWith('last_n_') && number !== undefined && number > 0) {\n const unit = rangeType.replace('last_n_', '')\n const unitSingular = unit.slice(0, -1) // Remove 's' for singular form\n return number === 1 ? `last ${unitSingular}` : `last ${number} ${unit}`\n }\n \n return typeMap[rangeType] || rangeType\n}\n\n/**\n * Check if a date range type requires a number input\n */\nexport function requiresNumberInput(rangeType: string): boolean {\n return rangeType.startsWith('last_n_')\n}\n\n/**\n * Format date for Cube.js (YYYY-MM-DD)\n */\nexport function formatDateForCube(date: Date): string {\n return date.toISOString().split('T')[0]\n}\n\n/**\n * Get the time dimensions that have date ranges applied\n */\nexport function getTimeDimensionsWithDateRanges(query: CubeQuery): Record<string, string | string[]> {\n const dateRanges: Record<string, string | string[]> = {}\n \n if (query.timeDimensions) {\n query.timeDimensions.forEach(td => {\n if (td.dateRange) {\n dateRanges[td.dimension] = td.dateRange\n }\n })\n }\n \n return dateRanges\n}\n\n/**\n * Check if a query has any time dimensions\n */\nexport function hasTimeDimensions(query: CubeQuery): boolean {\n return Boolean(query.timeDimensions && query.timeDimensions.length > 0)\n}\n\n/**\n * Transform a Cube.js query from external format to UI internal format\n * This handles format differences between server/API queries and QueryBuilder state\n */\nexport function transformQueryForUI(query: any): CubeQuery {\n if (!query || typeof query !== 'object') {\n return {}\n }\n \n const transformed: CubeQuery = {}\n \n // Copy simple fields if they exist\n if (query.measures) transformed.measures = Array.isArray(query.measures) ? query.measures : []\n if (query.dimensions) transformed.dimensions = Array.isArray(query.dimensions) ? query.dimensions : []\n if (query.timeDimensions) transformed.timeDimensions = Array.isArray(query.timeDimensions) ? query.timeDimensions : []\n if (query.order) transformed.order = query.order\n if (query.limit) transformed.limit = query.limit\n if (query.offset) transformed.offset = query.offset\n if (query.segments) transformed.segments = Array.isArray(query.segments) ? query.segments : []\n \n // Transform filters from server format to UI format\n if (query.filters && Array.isArray(query.filters)) {\n transformed.filters = transformFiltersFromServer(query.filters)\n }\n \n return cleanQuery(transformed)\n}\n\n/**\n * Transform filters from server/API format to UI format\n * Converts {and: [...]} and {or: [...]} to {type: 'and', filters: [...]} format\n */\nfunction transformFiltersFromServer(filters: any[]): Filter[] {\n return filters.map(filter => {\n if (!filter || typeof filter !== 'object') {\n return filter\n }\n \n // Handle legacy {and: [...]} format\n if ('and' in filter && Array.isArray(filter.and)) {\n return {\n type: 'and',\n filters: transformFiltersFromServer(filter.and)\n } as GroupFilter\n }\n \n // Handle legacy {or: [...]} format\n if ('or' in filter && Array.isArray(filter.or)) {\n return {\n type: 'or',\n filters: transformFiltersFromServer(filter.or)\n } as GroupFilter\n }\n \n // Handle new format {type: 'and', filters: [...]} - process recursively\n if ('type' in filter && 'filters' in filter && Array.isArray(filter.filters)) {\n return {\n type: filter.type,\n filters: transformFiltersFromServer(filter.filters)\n } as GroupFilter\n }\n \n // Simple filter - pass through\n return filter as SimpleFilter\n }).filter(Boolean) // Remove any null/undefined values\n}\n\n/**\n * Sorting utility functions\n */\n\n/**\n * Get field title from schema metadata, falling back to field name\n */\nexport function getFieldTitle(fieldName: string, schema: MetaResponse | null): string {\n if (!schema) return fieldName\n \n for (const cube of schema.cubes) {\n // Check measures\n const measure = cube.measures.find(m => m.name === fieldName)\n if (measure) return measure.title || measure.shortTitle || fieldName\n \n // Check dimensions\n const dimension = cube.dimensions.find(d => d.name === fieldName)\n if (dimension) return dimension.title || dimension.shortTitle || fieldName\n }\n \n return fieldName // Fallback to field name if not found\n}\n\n/**\n * Clean up order object by removing fields that are no longer in the query\n */\nexport function cleanupOrder(order: Record<string, 'asc' | 'desc'> | undefined, query: CubeQuery): Record<string, 'asc' | 'desc'> | undefined {\n if (!order) return undefined\n \n const allFields = [\n ...(query.measures || []),\n ...(query.dimensions || []),\n ...(query.timeDimensions || []).map(td => td.dimension)\n ]\n \n const cleanedOrder: Record<string, 'asc' | 'desc'> = {}\n for (const [field, direction] of Object.entries(order)) {\n if (allFields.includes(field)) {\n cleanedOrder[field] = direction\n }\n }\n \n return Object.keys(cleanedOrder).length > 0 ? cleanedOrder : undefined\n}\n\n/**\n * Get sort direction for a field from the order object\n */\nexport function getSortDirection(fieldName: string, order: Record<string, 'asc' | 'desc'> | undefined): 'asc' | 'desc' | null {\n return order?.[fieldName] || null\n}\n\n/**\n * Get tooltip text for sort button based on current direction\n */\nexport function getSortTooltip(direction: 'asc' | 'desc' | null): string {\n switch (direction) {\n case 'asc':\n return 'Sorted ascending (click for descending)'\n case 'desc':\n return 'Sorted descending (click to remove)'\n default:\n return 'Click to sort ascending'\n }\n}\n\n/**\n * Get next sort direction in the cycle: null -> asc -> desc -> null\n */\nexport function getNextSortDirection(current: 'asc' | 'desc' | null): 'asc' | 'desc' | null {\n switch (current) {\n case null:\n return 'asc'\n case 'asc':\n return 'desc'\n case 'desc':\n return null\n default:\n return 'asc'\n }\n}","/**\n * FilterItem Component\n * \n * Renders a single filter with field selection, operator selection, and value input.\n * Handles all the logic for individual filter management.\n */\n\nimport React, { useState, useEffect, useRef } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterValueSelector from './FilterValueSelector'\nimport type { FilterItemProps, MetaField, DateRangeType } from './types'\nimport { getAllFilterableFields, getOrganizedFilterFields, getFieldType, getAvailableOperators, convertDateRangeTypeToValue, formatDateForCube, requiresNumberInput } from './utils'\nimport { getMeasureIcon } from '../../utils/measureIcons'\nimport { DATE_RANGE_OPTIONS } from './types'\n\nconst CloseIcon = getIcon('close')\nconst FilterIcon = getIcon('filter')\nconst ChevronDownIcon = getIcon('chevronDown')\nconst SearchIcon = getIcon('search')\nconst DimensionIcon = getIcon('dimension')\nconst TimeDimensionIcon = getIcon('timeDimension')\n\nconst FilterItem: React.FC<FilterItemProps> = ({\n filter,\n index,\n onFilterChange,\n onFilterRemove,\n schema,\n query,\n hideFieldSelector = false,\n hideOperatorSelector = false,\n hideRemoveButton = false\n}) => {\n const [isFieldDropdownOpen, setIsFieldDropdownOpen] = useState(false)\n const [isOperatorDropdownOpen, setIsOperatorDropdownOpen] = useState(false)\n const [isDateRangeDropdownOpen, setIsDateRangeDropdownOpen] = useState(false)\n const [fieldSearchTerm, setFieldSearchTerm] = useState('')\n const containerRef = useRef<HTMLDivElement>(null)\n const searchInputRef = useRef<HTMLInputElement>(null)\n\n // Date range state - always initialized with defaults (must be before any early returns)\n const [rangeType, setRangeType] = useState<DateRangeType>('this_month')\n const [customDates, setCustomDates] = useState({\n startDate: formatDateForCube(new Date()),\n endDate: formatDateForCube(new Date())\n })\n const [numberValue, setNumberValue] = useState<number>(1)\n\n // Close dropdowns when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsFieldDropdownOpen(false)\n setIsOperatorDropdownOpen(false)\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [])\n\n // Close other dropdowns when opening one\n const handleFieldDropdownToggle = () => {\n setIsOperatorDropdownOpen(false)\n const newOpen = !isFieldDropdownOpen\n setIsFieldDropdownOpen(newOpen)\n setFieldSearchTerm('') // Reset search when toggling\n\n // Focus search input when opening\n if (newOpen) {\n setTimeout(() => searchInputRef.current?.focus(), 50)\n }\n }\n\n const handleOperatorDropdownToggle = () => {\n setIsFieldDropdownOpen(false)\n setIsOperatorDropdownOpen(!isOperatorDropdownOpen)\n }\n\n // Get field info (safe defaults if schema not loaded)\n const allFields = schema ? getAllFilterableFields(schema) : []\n const { queryFields } = schema ? getOrganizedFilterFields(schema, query) : { queryFields: [] }\n const selectedField = allFields.find(f => f.name === filter.member)\n const fieldType = selectedField ? selectedField.type : 'string'\n const availableOperators = getAvailableOperators(fieldType)\n\n // Determine if we should show date range selector (for time fields with inDateRange operator)\n const shouldShowDateRangeSelector = fieldType === 'time' && filter.operator === 'inDateRange'\n\n // Update date range state when filter.dateRange changes (must be before early return)\n useEffect(() => {\n if (!shouldShowDateRangeSelector || !filter.dateRange) return\n\n // Update rangeType\n if (Array.isArray(filter.dateRange)) {\n setRangeType('custom')\n setCustomDates({\n startDate: filter.dateRange[0] || '',\n endDate: filter.dateRange[1] || filter.dateRange[0] || ''\n })\n } else {\n // Check for flexible range patterns\n const flexibleRangeMatch = filter.dateRange.match(/^last (\\d+) (days|weeks|months|quarters|years)$/)\n if (flexibleRangeMatch) {\n const [, num, unit] = flexibleRangeMatch\n const unitPlural = unit === 'days' ? 'days' : unit === 'weeks' ? 'weeks' : unit === 'months' ? 'months' : unit === 'quarters' ? 'quarters' : 'years'\n setRangeType(`last_n_${unitPlural}` as DateRangeType)\n setNumberValue(parseInt(num) || 1)\n } else {\n // Check for predefined ranges\n let found = false\n for (const option of DATE_RANGE_OPTIONS) {\n if (option.value !== 'custom' && !requiresNumberInput(option.value) && convertDateRangeTypeToValue(option.value) === filter.dateRange) {\n setRangeType(option.value)\n found = true\n break\n }\n }\n if (!found) {\n setRangeType('custom')\n }\n }\n }\n }, [filter.dateRange, shouldShowDateRangeSelector])\n\n // Early return AFTER all hooks\n if (!schema) {\n return (\n <div className=\"text-sm text-dc-text-muted\">\n Schema not loaded\n </div>\n )\n }\n \n // Filter fields based on search term\n const filterFieldsBySearch = (fields: MetaField[]) => {\n if (!fieldSearchTerm) return fields\n const searchTerm = fieldSearchTerm.toLowerCase()\n return fields.filter(field => \n field.name.toLowerCase().includes(searchTerm) ||\n field.title.toLowerCase().includes(searchTerm) ||\n field.shortTitle.toLowerCase().includes(searchTerm)\n )\n }\n \n const filteredQueryFields = filterFieldsBySearch(queryFields)\n const filteredAllFields = filterFieldsBySearch(allFields)\n \n // Helper function to get field type icon\n const getFieldTypeIcon = (field: MetaField) => {\n if (field.type === 'time') {\n return <TimeDimensionIcon className=\"w-3 h-3 text-blue-500\" />\n } else if (['count', 'sum', 'avg', 'min', 'max', 'countDistinct', 'countDistinctApprox', 'runningTotal', 'calculated', 'number'].includes(field.type)) {\n // Use dynamic icon based on measure type, with amber color\n const icon = getMeasureIcon(field.type, 'w-3 h-3 text-amber-500')\n return icon\n } else {\n return <DimensionIcon className=\"w-3 h-3 text-green-500\" />\n }\n }\n\n // Helper function to get field type badge\n const getFieldTypeBadge = (field: MetaField) => {\n if (field.type === 'time') {\n return <span className=\"text-xs bg-dc-time-dimension text-dc-time-dimension px-1.5 py-0.5 rounded-sm\">T</span>\n } else if (['count', 'sum', 'avg', 'min', 'max', 'countDistinct', 'number'].includes(field.type)) {\n return <span className=\"text-xs bg-dc-measure text-dc-measure px-1.5 py-0.5 rounded-sm\">M</span>\n } else {\n return <span className=\"text-xs bg-dc-dimension text-dc-dimension px-1.5 py-0.5 rounded-sm\">D</span>\n }\n }\n\n const handleFieldChange = (fieldName: string) => {\n // When field changes, reset operator and values\n const newFieldType = getFieldType(fieldName, schema)\n const newAvailableOperators = getAvailableOperators(newFieldType)\n const defaultOperator = newAvailableOperators[0]?.operator || 'equals'\n\n onFilterChange(index, {\n member: fieldName,\n operator: defaultOperator as any,\n values: [],\n dateRange: undefined // Reset dateRange when field changes\n })\n setIsFieldDropdownOpen(false)\n }\n \n const handleOperatorChange = (operator: string) => {\n onFilterChange(index, {\n ...filter,\n operator: operator as any,\n values: [], // Reset values when operator changes\n dateRange: undefined // Reset dateRange when operator changes\n })\n setIsOperatorDropdownOpen(false)\n }\n \n const handleValuesChange = (values: any[]) => {\n onFilterChange(index, {\n ...filter,\n values\n })\n }\n\n // Date range handlers for time dimension filters\n const handleDateRangeChange = (dateRange: string | string[]) => {\n onFilterChange(index, {\n ...filter,\n dateRange\n })\n }\n\n const handleRangeTypeChange = (newRangeType: DateRangeType) => {\n setIsDateRangeDropdownOpen(false)\n\n if (newRangeType === 'custom') {\n // For custom, use current custom dates or default to today\n if (customDates.startDate && customDates.endDate) {\n const dateRange = customDates.startDate === customDates.endDate\n ? customDates.startDate\n : [customDates.startDate, customDates.endDate]\n handleDateRangeChange(dateRange)\n }\n } else if (requiresNumberInput(newRangeType)) {\n // For number-based ranges, use the number value\n const cubeRangeValue = convertDateRangeTypeToValue(newRangeType, numberValue)\n handleDateRangeChange(cubeRangeValue)\n } else {\n // For predefined ranges, use the converted value\n const cubeRangeValue = convertDateRangeTypeToValue(newRangeType)\n handleDateRangeChange(cubeRangeValue)\n }\n\n setRangeType(newRangeType)\n }\n\n const handleCustomDateChange = (field: 'startDate' | 'endDate', value: string) => {\n const newCustomDates = { ...customDates, [field]: value }\n setCustomDates(newCustomDates)\n\n if (rangeType === 'custom' && newCustomDates.startDate) {\n const dateRange = !newCustomDates.endDate || newCustomDates.startDate === newCustomDates.endDate\n ? newCustomDates.startDate\n : [newCustomDates.startDate, newCustomDates.endDate]\n handleDateRangeChange(dateRange)\n }\n }\n\n const handleNumberChange = (value: number) => {\n setNumberValue(value)\n\n if (requiresNumberInput(rangeType)) {\n const cubeRangeValue = convertDateRangeTypeToValue(rangeType, value)\n handleDateRangeChange(cubeRangeValue)\n }\n }\n\n const selectedRangeLabel = DATE_RANGE_OPTIONS.find(opt => opt.value === rangeType)?.label || 'Custom'\n\n return (\n <div ref={containerRef} className=\"bg-dc-surface border border-dc-border rounded-lg p-3\">\n {/* Responsive layout - stacks on mobile, single row on desktop */}\n <div className=\"flex flex-col sm:flex-row sm:items-center gap-3 min-w-0\">\n {/* Row 1 on mobile: Filter icon and field selection - conditionally hidden */}\n {!hideFieldSelector && (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <FilterIcon className=\"w-4 h-4 text-dc-text-muted shrink-0\" />\n\n {/* Field selection */}\n <div className=\"relative flex-1 min-w-0\">\n <button\n onClick={handleFieldDropdownToggle}\n className=\"w-full flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500 min-w-0\"\n >\n <span className=\"truncate\">\n {selectedField ? (\n <span className=\"font-medium\">{selectedField.name}</span>\n ) : (\n <span className=\"text-dc-text-muted\">Select field...</span>\n )}\n </span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isFieldDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isFieldDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-80 overflow-hidden\">\n {/* Search input */}\n <div className=\"p-2 border-b border-dc-border\">\n <div className=\"relative\">\n <SearchIcon className=\"w-4 h-4 absolute left-2 top-1/2 transform -translate-y-1/2 text-dc-text-muted\" />\n <input\n ref={searchInputRef}\n type=\"text\"\n placeholder=\"Search fields...\"\n value={fieldSearchTerm}\n onChange={(e) => setFieldSearchTerm(e.target.value)}\n className=\"w-full pl-8 pr-3 py-1.5 text-sm border border-dc-border rounded-sm bg-dc-surface text-dc-text focus:ring-1 focus:ring-blue-500 focus:border-blue-500\"\n />\n </div>\n </div>\n\n {/* Fields list */}\n <div className=\"max-h-60 overflow-y-auto\">\n {/* Query fields section */}\n {filteredQueryFields.length > 0 && (\n <div>\n <div className=\"px-3 py-1.5 text-xs font-medium text-dc-text-muted bg-dc-surface-secondary border-b border-dc-border\">\n Fields in Query ({filteredQueryFields.length})\n </div>\n {filteredQueryFields.map((field) => (\n <button\n key={`query-${field.name}`}\n onClick={() => handleFieldChange(field.name)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${\n field.name === filter.member ? 'bg-blue-50 text-blue-700' : 'text-dc-text-secondary'\n }`}\n >\n <div className=\"flex items-center gap-2\">\n {getFieldTypeIcon(field)}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium truncate\">{field.name}</span>\n {getFieldTypeBadge(field)}\n </div>\n {field.title !== field.name && (\n <div className=\"text-xs text-dc-text-muted truncate\">{field.title}</div>\n )}\n </div>\n </div>\n </button>\n ))}\n </div>\n )}\n\n {/* All fields section */}\n <div>\n {filteredQueryFields.length > 0 && (\n <div className=\"px-3 py-1.5 text-xs font-medium text-dc-text-muted bg-dc-surface-secondary border-b border-dc-border\">\n All Available Fields ({filteredAllFields.length})\n </div>\n )}\n {filteredAllFields.map((field) => (\n <button\n key={`all-${field.name}`}\n onClick={() => handleFieldChange(field.name)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${\n field.name === filter.member ? 'bg-blue-50 text-blue-700' : 'text-dc-text-secondary'\n }`}\n >\n <div className=\"flex items-center gap-2\">\n {getFieldTypeIcon(field)}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium truncate\">{field.name}</span>\n {getFieldTypeBadge(field)}\n </div>\n {field.title !== field.name && (\n <div className=\"text-xs text-dc-text-muted truncate\">{field.title}</div>\n )}\n </div>\n </div>\n </button>\n ))}\n </div>\n\n {/* No results message */}\n {filteredAllFields.length === 0 && (\n <div className=\"px-3 py-4 text-sm text-dc-text-muted text-center\">\n No fields found matching \"{fieldSearchTerm}\"\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Row 2 on mobile: Operator and Value selection */}\n {selectedField && (\n <div className=\"flex items-center gap-2 flex-1 sm:flex-initial min-w-0\">\n {/* Operator selection - conditionally hidden */}\n {!hideOperatorSelector && (\n <div className=\"relative shrink-0\">\n <button\n onClick={handleOperatorDropdownToggle}\n className=\"w-full sm:w-32 flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n >\n <span className=\"truncate\">\n {availableOperators.find(op => op.operator === filter.operator)?.label || filter.operator}\n </span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isOperatorDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isOperatorDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {availableOperators.map((operator) => (\n <button\n key={operator.operator}\n onClick={() => handleOperatorChange(operator.operator)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${\n operator.operator === filter.operator ? 'bg-blue-50 text-blue-700' : 'text-dc-text-secondary'\n }`}\n >\n {operator.label}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Value input or Date Range Selector */}\n <div className=\"flex-1 min-w-0\">\n {shouldShowDateRangeSelector ? (\n /* Date Range Selector for time dimensions with inDateRange */\n <div className=\"flex items-center gap-2\">\n {/* Range type selector */}\n <div className=\"relative shrink-0\">\n <button\n onClick={() => {\n setIsOperatorDropdownOpen(false)\n setIsDateRangeDropdownOpen(!isDateRangeDropdownOpen)\n }}\n className=\"w-full sm:w-40 flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n >\n <span className=\"truncate\">{selectedRangeLabel}</span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isDateRangeDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isDateRangeDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {DATE_RANGE_OPTIONS.map((option) => (\n <button\n key={option.value}\n onClick={() => handleRangeTypeChange(option.value)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${\n option.value === rangeType ? 'bg-blue-50 text-blue-700' : 'text-dc-text-secondary'\n }`}\n >\n {option.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Custom date inputs or number input */}\n {rangeType === 'custom' ? (\n <>\n <input\n type=\"date\"\n value={customDates.startDate}\n onChange={(e) => handleCustomDateChange('startDate', e.target.value)}\n placeholder=\"Start date\"\n className=\"flex-1 min-w-0 text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n <input\n type=\"date\"\n value={customDates.endDate}\n onChange={(e) => handleCustomDateChange('endDate', e.target.value)}\n placeholder=\"End date\"\n className=\"flex-1 min-w-0 text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n </>\n ) : requiresNumberInput(rangeType) ? (\n <>\n <input\n type=\"number\"\n min=\"1\"\n max=\"1000\"\n value={numberValue}\n onChange={(e) => handleNumberChange(Math.max(1, parseInt(e.target.value) || 1))}\n placeholder=\"Number\"\n className=\"flex-1 min-w-0 text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n <div className=\"shrink-0 text-sm text-dc-text-secondary\">\n {rangeType.replace('last_n_', '').replace('_', ' ')}\n </div>\n </>\n ) : null}\n </div>\n ) : (\n /* Regular FilterValueSelector for non-dateRange filters */\n <FilterValueSelector\n fieldName={filter.member}\n operator={filter.operator}\n values={filter.values}\n onValuesChange={handleValuesChange}\n schema={schema}\n />\n )}\n </div>\n </div>\n )}\n \n {/* Row 3 on mobile: Remove button - conditionally hidden */}\n {!hideRemoveButton && (\n <div className=\"flex justify-end sm:justify-start\">\n <button\n onClick={() => onFilterRemove(index)}\n className=\"text-dc-text-muted hover:text-red-600 focus:outline-none shrink-0\"\n title=\"Remove filter\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default FilterItem","/**\n * FilterGroup Component\n * \n * Handles AND/OR logical groups with support for infinite nesting.\n * Renders child filters with proper indentation and group controls.\n */\n\nimport React, { useState } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterItem from './FilterItem'\nimport type { FilterGroupProps } from './types'\nimport type { SimpleFilter, GroupFilter } from '../../types'\nimport {\n isSimpleFilter,\n isGroupFilter,\n createSimpleFilter,\n createAndFilter,\n createOrFilter,\n getFilterableFields\n} from './utils'\n\nconst CloseIcon = getIcon('close')\nconst AddIcon = getIcon('add')\n\nconst FilterGroup: React.FC<FilterGroupProps> = ({\n group,\n index,\n onGroupChange,\n onGroupChangeWithUnwrap,\n onGroupRemove,\n schema,\n query,\n depth = 0\n}) => {\n const [showAddMenu, setShowAddMenu] = useState(false)\n \n const isAndGroup = group.type === 'and'\n const groupType = isAndGroup ? 'AND' : 'OR'\n const filters = group.filters\n \n // Style based on depth for visual nesting\n const indentClass = depth > 0 ? `ml-${Math.min(depth * 4, 16)}` : ''\n const borderColor = 'border-slate-200'\n const bgColor = 'bg-slate-50'\n const textColor = 'text-slate-700'\n \n const handleGroupTypeToggle = () => {\n if (isAndGroup) {\n const newGroup = createOrFilter(filters)\n onGroupChange(index, newGroup)\n } else {\n const newGroup = createAndFilter(filters)\n onGroupChange(index, newGroup)\n }\n }\n \n const handleAddSimpleFilter = () => {\n if (!schema) return\n \n // Get the first available field as default\n const filterableFields = getFilterableFields(schema, query)\n const defaultField = filterableFields[0]?.name || ''\n const newFilter = createSimpleFilter(defaultField, 'equals', [])\n const newFilters = [...filters, newFilter]\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n setShowAddMenu(false)\n }\n \n const handleAddAndGroup = () => {\n if (!schema) return\n \n // Get the first available field as default\n const filterableFields = getFilterableFields(schema, query)\n const defaultField = filterableFields[0]?.name || ''\n const newGroup = createAndFilter([createSimpleFilter(defaultField, 'equals', [])])\n const newFilters = [...filters, newGroup]\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n setShowAddMenu(false)\n }\n \n const handleAddOrGroup = () => {\n if (!schema) return\n \n // Get the first available field as default\n const filterableFields = getFilterableFields(schema, query)\n const defaultField = filterableFields[0]?.name || ''\n const newGroup = createOrFilter([createSimpleFilter(defaultField, 'equals', [])])\n const newFilters = [...filters, newGroup]\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n setShowAddMenu(false)\n }\n \n const handleFilterChange = (filterIndex: number, newFilter: SimpleFilter) => {\n const newFilters = [...filters]\n newFilters[filterIndex] = newFilter\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n }\n \n const handleFilterRemove = (filterIndex: number) => {\n const newFilters = filters.filter((_, i) => i !== filterIndex)\n \n // If no filters left, remove the entire group\n if (newFilters.length === 0) {\n onGroupRemove(index)\n return\n }\n \n // If only one filter left, use unwrapping handler if available\n if (newFilters.length === 1) {\n const newGroup = group.type === 'and' ? createAndFilter(newFilters) : createOrFilter(newFilters)\n \n if (onGroupChangeWithUnwrap) {\n // Use the unwrapping handler for removal scenarios\n onGroupChangeWithUnwrap(index, newGroup)\n } else {\n // Fallback to regular handler (for nested groups)\n onGroupChange(index, newGroup)\n }\n return\n }\n \n // Otherwise, update the group with remaining filters (preserve the group type)\n const updatedGroup = group.type === 'and' ? createAndFilter(newFilters) : createOrFilter(newFilters)\n onGroupChange(index, updatedGroup)\n }\n \n const handleNestedGroupChange = (filterIndex: number, newGroup: GroupFilter) => {\n const newFilters = [...filters]\n newFilters[filterIndex] = newGroup\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n }\n \n const handleNestedGroupRemove = (filterIndex: number) => {\n handleFilterRemove(filterIndex)\n }\n \n return (\n <div className={`${indentClass} ${borderColor} border-2 ${bgColor} rounded-lg p-4 space-y-3`}>\n {/* Group header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center space-x-2\">\n <button\n onClick={handleGroupTypeToggle}\n className={`px-3 py-1 rounded-sm text-sm font-semibold ${textColor} border border-current hover:bg-dc-surface hover:bg-opacity-20 focus:outline-hidden focus:ring-2 focus:ring-current focus:ring-opacity-50`}\n >\n {groupType}\n </button>\n <span className=\"text-sm text-dc-text-secondary\">\n {filters.length} condition{filters.length !== 1 ? 's' : ''}\n </span>\n </div>\n\n <div className=\"flex items-center space-x-2\">\n {/* Add menu */}\n <div className=\"relative\">\n <button\n onClick={() => setShowAddMenu(!showAddMenu)}\n className=\"text-dc-text-muted hover:text-dc-text-secondary focus:outline-hidden\"\n title=\"Add condition\"\n >\n <AddIcon className=\"w-4 h-4\" />\n </button>\n\n {showAddMenu && (\n <div className=\"absolute right-0 mt-1 w-48 bg-dc-surface border border-dc-border rounded-md shadow-lg z-30\">\n <button\n onClick={handleAddSimpleFilter}\n className=\"w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover\"\n >\n Add Filter\n </button>\n <button\n onClick={handleAddAndGroup}\n className=\"w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover\"\n >\n Add AND Group\n </button>\n <button\n onClick={handleAddOrGroup}\n className=\"w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover\"\n >\n Add OR Group\n </button>\n </div>\n )}\n </div>\n\n {/* Remove group button */}\n <button\n onClick={() => onGroupRemove(index)}\n className=\"text-dc-text-muted hover:text-red-600 focus:outline-hidden\"\n title=\"Remove group\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n \n {/* Group content */}\n <div className=\"space-y-3\">\n {filters.map((filter, filterIndex) => {\n if (isSimpleFilter(filter)) {\n return (\n <FilterItem\n key={filterIndex}\n filter={filter}\n index={filterIndex}\n onFilterChange={handleFilterChange}\n onFilterRemove={handleFilterRemove}\n schema={schema}\n query={query}\n />\n )\n } else if (isGroupFilter(filter)) {\n return (\n <FilterGroup\n key={filterIndex}\n group={filter}\n index={filterIndex}\n onGroupChange={handleNestedGroupChange}\n onGroupRemove={handleNestedGroupRemove}\n schema={schema}\n query={query}\n depth={depth + 1}\n />\n )\n }\n return null\n })}\n \n {/* Empty state */}\n {filters.length === 0 && (\n <div className=\"text-center py-4 text-dc-text-muted text-sm\">\n No conditions in this group.\n <button\n onClick={handleAddSimpleFilter}\n className=\"ml-2 text-purple-600 hover:text-purple-800 focus:outline-hidden underline\"\n >\n Add a filter\n </button>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default FilterGroup","/**\n * FilterBuilder Component\n * \n * Main component for managing all filters in the query.\n * Handles the top-level filter state and provides controls for adding new filters and groups.\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport FilterItem from './FilterItem'\nimport FilterGroup from './FilterGroup'\nimport type { FilterBuilderProps } from './types'\nimport type { SimpleFilter, GroupFilter } from '../../types'\nimport {\n isSimpleFilter,\n isGroupFilter,\n isAndFilter,\n isOrFilter,\n createSimpleFilter,\n createAndFilter,\n createOrFilter,\n countFilters,\n getAllFilterableFields\n} from './utils'\n\nconst AddIcon = getIcon('add')\nconst FilterIcon = getIcon('filter')\n\nconst FilterBuilder: React.FC<FilterBuilderProps> = ({\n filters,\n schema,\n query,\n onFiltersChange,\n hideFieldSelector = false\n}) => {\n \n \n const totalFilterCount = countFilters(filters)\n \n // Get all filterable fields from schema\n const allFilterableFields = schema ? getAllFilterableFields(schema) : []\n const hasFilterableFields = allFilterableFields.length > 0\n \n const handleAddSimpleFilter = () => {\n if (!hasFilterableFields) return\n \n // Use the first available field as default\n const defaultField = allFilterableFields[0]?.name || ''\n const newFilter = createSimpleFilter(defaultField, 'equals', [])\n \n // Smart filter grouping logic:\n // - First filter: add as simple filter\n // - Second filter: create AND group with first filter + new filter\n // - Additional filters: add to existing group (AND or OR, respecting current type)\n \n if (filters.length === 0) {\n // First filter - add as simple filter\n onFiltersChange([newFilter])\n } else if (filters.length === 1 && isSimpleFilter(filters[0])) {\n // Second filter - create AND group with existing filter + new filter\n const andGroup = createAndFilter([filters[0], newFilter])\n onFiltersChange([andGroup])\n } else if (filters.length === 1 && isAndFilter(filters[0])) {\n // Additional filter - add to existing AND group\n const existingAndGroup = filters[0]\n const updatedAndGroup = createAndFilter([...existingAndGroup.filters, newFilter])\n onFiltersChange([updatedAndGroup])\n } else if (filters.length === 1 && isOrFilter(filters[0])) {\n // Additional filter - add to existing OR group\n const existingOrGroup = filters[0]\n const updatedOrGroup = createOrFilter([...existingOrGroup.filters, newFilter])\n onFiltersChange([updatedOrGroup])\n } else {\n // Fallback: just add to the end (shouldn't happen with new logic)\n onFiltersChange([...filters, newFilter])\n }\n }\n \n \n const handleFilterChange = (index: number, newFilter: SimpleFilter) => {\n const newFilters = [...filters]\n newFilters[index] = newFilter\n onFiltersChange(newFilters)\n }\n \n const handleFilterRemove = (index: number) => {\n // Simple case: just remove the filter\n // The handleGroupChange method will automatically handle unwrapping if needed\n const newFilters = filters.filter((_, i) => i !== index)\n onFiltersChange(newFilters)\n }\n \n const handleGroupChange = (index: number, newGroup: GroupFilter) => {\n const newFilters = [...filters]\n newFilters[index] = newGroup\n onFiltersChange(newFilters)\n }\n \n const handleGroupChangeWithUnwrap = (index: number, newGroup: GroupFilter) => {\n const newFilters = [...filters]\n \n // Check if the group has been reduced to a single filter and should be unwrapped\n // This is only used during filter removal operations\n if (newGroup.filters.length === 1 && isSimpleFilter(newGroup.filters[0])) {\n // Unwrap the single filter from the group\n newFilters[index] = newGroup.filters[0]\n } else {\n newFilters[index] = newGroup\n }\n \n onFiltersChange(newFilters)\n }\n \n const handleGroupRemove = () => {\n // When removing an AND group, we should remove all filters\n onFiltersChange([])\n }\n \n const handleClearAllFilters = () => {\n onFiltersChange([])\n }\n \n return (\n <div className=\"space-y-4 bg-dc-surface-secondary rounded-lg p-4\">\n {/* Header - hidden for universal time filters */}\n {!hideFieldSelector && (\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center\">\n <FilterIcon className=\"w-4 h-4 text-dc-text-muted mr-2\" />\n <h4 className=\"text-sm font-semibold text-dc-text-secondary\">\n Filters ({totalFilterCount})\n </h4>\n </div>\n\n <div className=\"flex items-center space-x-2\">\n {/* Clear all button */}\n {filters.length > 0 && (\n <button\n onClick={handleClearAllFilters}\n className=\"text-xs text-dc-text-muted hover:text-red-600 focus:outline-hidden underline\"\n >\n Clear all\n </button>\n )}\n\n {/* Add Filter button */}\n <button\n onClick={handleAddSimpleFilter}\n disabled={!hasFilterableFields}\n className={`flex items-center space-x-1 px-2 py-1 text-xs font-medium rounded focus:outline-hidden focus:ring-2 ${\n hasFilterableFields\n ? 'text-purple-700 bg-purple-100 border border-purple-200 hover:bg-purple-200 focus:ring-purple-500'\n : 'text-dc-text-muted bg-dc-surface-secondary border border-dc-border cursor-not-allowed'\n }`}\n >\n <AddIcon className=\"w-3 h-3\" />\n <span>Add Filter</span>\n </button>\n </div>\n </div>\n )}\n \n {/* Filters list */}\n {filters.length > 0 && (\n <div className=\"space-y-3\">\n {filters.map((filter, index) => {\n \n if (isSimpleFilter(filter)) {\n return (\n <FilterItem\n key={index}\n filter={filter}\n index={index}\n onFilterChange={handleFilterChange}\n onFilterRemove={handleFilterRemove}\n schema={schema}\n query={query}\n hideFieldSelector={hideFieldSelector}\n hideRemoveButton={hideFieldSelector}\n />\n )\n } else if (isGroupFilter(filter)) {\n return (\n <FilterGroup\n key={index}\n group={filter}\n index={index}\n onGroupChange={handleGroupChange}\n onGroupChangeWithUnwrap={handleGroupChangeWithUnwrap}\n onGroupRemove={handleGroupRemove}\n schema={schema}\n query={query}\n depth={0}\n />\n )\n }\n return null\n })}\n </div>\n )}\n \n </div>\n )\n}\n\nexport default FilterBuilder","/**\n * DateRangeSelector Component\n * \n * Individual date range selector for a specific time dimension\n * Styled to match FilterItem component exactly\n */\n\nimport React, { useState, useEffect, useRef } from 'react'\nimport { getIcon } from '../../icons'\nimport { DATE_RANGE_OPTIONS, type DateRangeType } from './types'\nimport { convertDateRangeTypeToValue, formatDateForCube, requiresNumberInput } from './utils'\n\nconst CloseIcon = getIcon('close')\nconst CalendarIcon = getIcon('timeDimension')\nconst ChevronDownIcon = getIcon('chevronDown')\n\ninterface DateRangeSelectorProps {\n timeDimension: string\n availableTimeDimensions: string[]\n currentDateRange?: string | string[]\n onDateRangeChange: (timeDimension: string, dateRange: string | string[]) => void\n onTimeDimensionChange: (oldTimeDimension: string, newTimeDimension: string) => void\n onRemove: (timeDimension: string) => void\n hideFieldSelector?: boolean // Hide the time dimension field selector (for read-only filters)\n hideRemoveButton?: boolean // Hide the remove button (for read-only filters)\n}\n\nconst DateRangeSelector: React.FC<DateRangeSelectorProps> = ({\n timeDimension,\n availableTimeDimensions,\n currentDateRange,\n onDateRangeChange,\n onTimeDimensionChange,\n onRemove,\n hideFieldSelector = false,\n hideRemoveButton = false\n}) => {\n // Parse current date range to determine the type and custom dates\n const getCurrentRangeType = (): DateRangeType => {\n if (!currentDateRange) return 'this_month'\n \n if (Array.isArray(currentDateRange)) {\n return 'custom'\n }\n \n // Check if it's a flexible range with number (e.g., \"last 9 weeks\")\n const flexibleRangeMatch = currentDateRange.match(/^last (\\d+) (days|weeks|months|quarters|years)$/)\n if (flexibleRangeMatch) {\n const [, , unit] = flexibleRangeMatch\n const unitPlural = unit === 'days' ? 'days' : unit === 'weeks' ? 'weeks' : unit === 'months' ? 'months' : unit === 'quarters' ? 'quarters' : 'years'\n return `last_n_${unitPlural}` as DateRangeType\n }\n \n // Find matching predefined range\n for (const option of DATE_RANGE_OPTIONS) {\n if (option.value !== 'custom' && !requiresNumberInput(option.value) && convertDateRangeTypeToValue(option.value) === currentDateRange) {\n return option.value\n }\n }\n \n return 'custom'\n }\n\n const getCurrentDates = (): { startDate: string; endDate: string } => {\n if (Array.isArray(currentDateRange) && currentDateRange.length >= 1) {\n return {\n startDate: currentDateRange[0] || '',\n endDate: currentDateRange[1] || currentDateRange[0] || ''\n }\n }\n \n // Default to today for custom ranges\n const today = formatDateForCube(new Date())\n return { startDate: today, endDate: today }\n }\n\n const getCurrentNumber = (): number => {\n if (!currentDateRange || Array.isArray(currentDateRange)) return 1\n \n // Check if it's a flexible range with number (e.g., \"last 9 weeks\")\n const flexibleRangeMatch = currentDateRange.match(/^last (\\d+) (days|weeks|months|quarters|years)$/)\n if (flexibleRangeMatch) {\n return parseInt(flexibleRangeMatch[1]) || 1\n }\n \n return 1\n }\n\n const [rangeType, setRangeType] = useState<DateRangeType>(getCurrentRangeType())\n const [customDates, setCustomDates] = useState(getCurrentDates())\n const [numberValue, setNumberValue] = useState<number>(getCurrentNumber())\n const [isRangeDropdownOpen, setIsRangeDropdownOpen] = useState(false)\n const [isTimeDimensionDropdownOpen, setIsTimeDimensionDropdownOpen] = useState(false)\n const containerRef = useRef<HTMLDivElement>(null)\n \n // Close dropdowns when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsRangeDropdownOpen(false)\n setIsTimeDimensionDropdownOpen(false)\n }\n }\n \n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [])\n\n // Close other dropdowns when opening one\n const handleTimeDimensionDropdownToggle = () => {\n setIsRangeDropdownOpen(false)\n setIsTimeDimensionDropdownOpen(!isTimeDimensionDropdownOpen)\n }\n \n const handleRangeDropdownToggle = () => {\n setIsTimeDimensionDropdownOpen(false)\n setIsRangeDropdownOpen(!isRangeDropdownOpen)\n }\n\n const handleRangeTypeChange = (newRangeType: DateRangeType) => {\n setRangeType(newRangeType)\n setIsRangeDropdownOpen(false)\n \n if (newRangeType === 'custom') {\n // For custom, use current custom dates or default to today\n if (customDates.startDate && customDates.endDate) {\n const dateRange = customDates.startDate === customDates.endDate \n ? customDates.startDate\n : [customDates.startDate, customDates.endDate]\n onDateRangeChange(timeDimension, dateRange)\n }\n } else if (requiresNumberInput(newRangeType)) {\n // For number-based ranges, use the number value\n const cubeRangeValue = convertDateRangeTypeToValue(newRangeType, numberValue)\n onDateRangeChange(timeDimension, cubeRangeValue)\n } else {\n // For predefined ranges, use the converted value\n const cubeRangeValue = convertDateRangeTypeToValue(newRangeType)\n onDateRangeChange(timeDimension, cubeRangeValue)\n }\n }\n\n const handleCustomDateChange = (field: 'startDate' | 'endDate', value: string) => {\n const newCustomDates = { ...customDates, [field]: value }\n setCustomDates(newCustomDates)\n \n if (rangeType === 'custom' && newCustomDates.startDate) {\n const dateRange = !newCustomDates.endDate || newCustomDates.startDate === newCustomDates.endDate\n ? newCustomDates.startDate\n : [newCustomDates.startDate, newCustomDates.endDate]\n onDateRangeChange(timeDimension, dateRange)\n }\n }\n\n const handleNumberChange = (value: number) => {\n setNumberValue(value)\n \n if (requiresNumberInput(rangeType)) {\n const cubeRangeValue = convertDateRangeTypeToValue(rangeType, value)\n onDateRangeChange(timeDimension, cubeRangeValue)\n }\n }\n\n const handleTimeDimensionChange = (newTimeDimension: string) => {\n setIsTimeDimensionDropdownOpen(false)\n onTimeDimensionChange(timeDimension, newTimeDimension)\n }\n\n const selectedRangeLabel = DATE_RANGE_OPTIONS.find(opt => opt.value === rangeType)?.label || 'Custom'\n\n return (\n <div ref={containerRef} className=\"bg-dc-surface border border-dc-border rounded-lg p-3\">\n {/* Responsive layout - stacks on mobile, single row on desktop */}\n <div className=\"flex flex-col sm:flex-row sm:items-center gap-3 min-w-0\">\n {/* Row 1: Filter icon and time dimension field - conditionally hidden */}\n {!hideFieldSelector && (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <CalendarIcon className=\"w-4 h-4 text-dc-text-muted shrink-0\" />\n\n {/* Time dimension field selector */}\n <div className=\"relative flex-1 min-w-0\">\n <button\n onClick={handleTimeDimensionDropdownToggle}\n className=\"w-full flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500 min-w-0\"\n >\n <span className=\"truncate\">{timeDimension}</span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 transition-transform ${\n isTimeDimensionDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isTimeDimensionDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {availableTimeDimensions.map((td) => (\n <button\n key={td}\n onClick={() => handleTimeDimensionChange(td)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${\n td === timeDimension ? 'bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300' : 'text-dc-text-secondary'\n }`}\n >\n {td}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Row 2: Date range selector */}\n <div className=\"flex items-center gap-2 flex-1 sm:flex-initial min-w-0\">\n {/* Range type selector with custom dropdown */}\n <div className=\"relative shrink-0\">\n <button\n onClick={handleRangeDropdownToggle}\n className=\"w-full sm:w-40 flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n >\n <span className=\"truncate\">{selectedRangeLabel}</span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isRangeDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isRangeDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {DATE_RANGE_OPTIONS.map((option) => (\n <button\n key={option.value}\n onClick={() => handleRangeTypeChange(option.value)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${\n option.value === rangeType ? 'bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300' : 'text-dc-text-secondary'\n }`}\n >\n {option.label}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* Row 3: Custom date inputs, number input, or remove button */}\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {rangeType === 'custom' ? (\n <>\n {/* Start date */}\n <div className=\"flex-1 min-w-0\">\n <input\n type=\"date\"\n value={customDates.startDate}\n onChange={(e) => handleCustomDateChange('startDate', e.target.value)}\n placeholder=\"dd/mm/yyyy\"\n className=\"w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n </div>\n\n {/* End date (optional) */}\n <div className=\"flex-1 min-w-0\">\n <input\n type=\"date\"\n value={customDates.endDate}\n onChange={(e) => handleCustomDateChange('endDate', e.target.value)}\n placeholder=\"dd/mm/yyyy\"\n className=\"w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n </div>\n </>\n ) : requiresNumberInput(rangeType) ? (\n <>\n {/* Number input for flexible ranges */}\n <div className=\"flex-1 min-w-0\">\n <input\n type=\"number\"\n min=\"1\"\n max=\"1000\"\n value={numberValue}\n onChange={(e) => handleNumberChange(Math.max(1, parseInt(e.target.value) || 1))}\n placeholder=\"Number\"\n className=\"w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n />\n </div>\n\n {/* Unit display */}\n <div className=\"shrink-0 text-sm text-dc-text-secondary\">\n {rangeType.replace('last_n_', '').replace('_', ' ')}\n </div>\n </>\n ) : (\n // Empty placeholder to maintain layout consistency\n <div className=\"flex-1\"></div>\n )}\n\n {/* Remove button - conditionally hidden */}\n {!hideRemoveButton && (\n <button\n onClick={() => onRemove(timeDimension)}\n className=\"text-dc-text-muted hover:text-red-600 focus:outline-hidden shrink-0 p-1\"\n title=\"Remove date range\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n </div>\n </div>\n )\n}\n\nexport default DateRangeSelector","/**\n * DateRangeFilter Component\n * \n * Container component for managing date ranges on time dimensions.\n * Shows all time dimensions with date ranges and provides controls for adding new ones.\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport DateRangeSelector from './DateRangeSelector'\nimport type { DateRangeFilterProps } from './types'\nimport { getTimeDimensionsWithDateRanges } from './utils'\n\nconst AddIcon = getIcon('add')\nconst CalendarIcon = getIcon('timeDimension')\n\nconst DateRangeFilter: React.FC<DateRangeFilterProps> = ({\n timeDimensions,\n onDateRangeChange,\n onDateRangeRemove\n}) => {\n // Get current date ranges from time dimensions\n const currentDateRanges = getTimeDimensionsWithDateRanges({ timeDimensions })\n \n // Get time dimensions that don't have date ranges yet\n const availableTimeDimensions = timeDimensions.filter(td => !td.dateRange)\n \n // Count of time dimensions with date ranges\n const dateRangeCount = Object.keys(currentDateRanges).length\n\n const handleAddDateRange = () => {\n if (availableTimeDimensions.length === 0) return\n \n // Add date range to the first available time dimension with default \"this month\"\n const firstAvailable = availableTimeDimensions[0]\n onDateRangeChange(firstAvailable.dimension, 'this month')\n }\n\n const handleClearAllDateRanges = () => {\n // Remove all date ranges\n Object.keys(currentDateRanges).forEach(timeDimension => {\n onDateRangeRemove(timeDimension)\n })\n }\n\n // Don't render if there are no time dimensions\n if (!timeDimensions || timeDimensions.length === 0) {\n return null\n }\n\n return (\n <div className=\"space-y-4 bg-dc-surface-secondary rounded-lg p-4\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center\">\n <CalendarIcon className=\"w-4 h-4 text-dc-text-muted mr-2\" />\n <h4 className=\"text-sm font-semibold text-dc-text-secondary\">\n Date Ranges ({dateRangeCount})\n </h4>\n </div>\n\n <div className=\"flex items-center space-x-2\">\n {/* Clear all button */}\n {dateRangeCount > 0 && (\n <button\n onClick={handleClearAllDateRanges}\n className=\"text-xs text-dc-text-muted hover:text-red-600 focus:outline-hidden underline\"\n >\n Clear all\n </button>\n )}\n \n {/* Add Date Range button */}\n <button\n onClick={handleAddDateRange}\n disabled={availableTimeDimensions.length === 0}\n className={`flex items-center space-x-1 px-2 py-1 text-xs font-medium rounded focus:outline-hidden focus:ring-2 ${\n availableTimeDimensions.length > 0\n ? 'text-purple-700 dark:text-purple-300 bg-purple-100 dark:bg-purple-900/30 border border-purple-200 dark:border-purple-800 hover:bg-purple-200 dark:hover:bg-purple-900/50 focus:ring-purple-500'\n : 'text-dc-text-muted bg-dc-surface-secondary border border-dc-border cursor-not-allowed'\n }`}\n title={availableTimeDimensions.length === 0 ? 'All time dimensions already have date ranges' : 'Add date range'}\n >\n <AddIcon className=\"w-3 h-3\" />\n <span>Add Date Range</span>\n </button>\n </div>\n </div>\n \n {/* Date Range List */}\n {dateRangeCount > 0 && (\n <div className=\"space-y-3\">\n {timeDimensions.map(td => {\n if (!td.dateRange) return null\n \n const allTimeDimensions = timeDimensions.map(t => t.dimension)\n \n return (\n <DateRangeSelector\n key={td.dimension}\n timeDimension={td.dimension}\n availableTimeDimensions={allTimeDimensions}\n currentDateRange={td.dateRange}\n onDateRangeChange={onDateRangeChange}\n onTimeDimensionChange={(oldTd, newTd) => {\n // Remove date range from old time dimension and add it to new one\n onDateRangeRemove(oldTd)\n onDateRangeChange(newTd, td.dateRange!)\n }}\n onRemove={onDateRangeRemove}\n />\n )\n })}\n </div>\n )}\n \n </div>\n )\n}\n\nexport default DateRangeFilter","/**\n * QueryAnalysisPanel Component\n * Displays query planning analysis for debugging and transparency\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport type { QueryAnalysis } from './types'\n\ninterface QueryAnalysisPanelProps {\n analysis: QueryAnalysis\n}\n\n/**\n * Format reason string for display\n */\nfunction formatReason(reason: string): string {\n return reason.replace(/_/g, ' ')\n}\n\n/**\n * Get badge color based on reason\n */\nfunction getReasonBadgeClasses(reason: string): string {\n switch (reason) {\n case 'most_dimensions':\n return 'bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300'\n case 'most_connected':\n return 'bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300'\n case 'alphabetical_fallback':\n return 'bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-300'\n case 'single_cube':\n return 'bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-300'\n default:\n return 'bg-gray-100 dark:bg-gray-900/30 text-gray-700 dark:text-gray-300'\n }\n}\n\nconst QueryAnalysisPanel: React.FC<QueryAnalysisPanelProps> = ({ analysis }) => {\n const InfoIcon = getIcon('info')\n const ArrowRightIcon = getIcon('chevronRight')\n const WarningIcon = getIcon('warning')\n const TableIcon = getIcon('table')\n const LinkIcon = getIcon('link')\n const SuccessIcon = getIcon('success')\n const ErrorIcon = getIcon('error')\n\n return (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-lg p-4 space-y-4\">\n {/* Query Summary Section */}\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <InfoIcon className=\"w-4 h-4 mr-2\" />\n Query Summary\n </h4>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-2 text-xs\">\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">Type:</span>\n <span className=\"ml-1 font-medium text-dc-text\">\n {formatReason(analysis.querySummary.queryType)}\n </span>\n </div>\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">Cubes:</span>\n <span className=\"ml-1 font-medium text-dc-text\">{analysis.cubeCount}</span>\n </div>\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">Joins:</span>\n <span className=\"ml-1 font-medium text-dc-text\">{analysis.querySummary.joinCount}</span>\n </div>\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">CTEs:</span>\n <span className=\"ml-1 font-medium text-dc-text\">{analysis.querySummary.cteCount}</span>\n </div>\n </div>\n </div>\n\n {/* Primary Cube Section */}\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <TableIcon className=\"w-4 h-4 mr-2\" />\n Primary Cube (FROM table)\n </h4>\n <div className=\"bg-dc-surface p-3 rounded text-sm\">\n <div className=\"flex items-center gap-2 mb-2 flex-wrap\">\n <span className=\"font-mono font-medium text-dc-primary\">\n {analysis.primaryCube.selectedCube}\n </span>\n <span className={`text-xs px-2 py-0.5 rounded ${getReasonBadgeClasses(analysis.primaryCube.reason)}`}>\n {formatReason(analysis.primaryCube.reason)}\n </span>\n </div>\n <p className=\"text-dc-text-secondary text-xs\">\n {analysis.primaryCube.explanation}\n </p>\n {analysis.primaryCube.candidates && analysis.primaryCube.candidates.length > 1 && (\n <details className=\"mt-2\">\n <summary className=\"text-xs text-dc-text-muted cursor-pointer hover:text-dc-text\">\n Show candidates ({analysis.primaryCube.candidates.length})\n </summary>\n <div className=\"mt-2 space-y-1 ml-2\">\n {analysis.primaryCube.candidates.map((c, i) => (\n <div key={i} className=\"text-xs flex items-center gap-2 flex-wrap\">\n <span className={`font-mono ${c.cubeName === analysis.primaryCube.selectedCube ? 'font-bold text-dc-primary' : 'text-dc-text-muted'}`}>\n {c.cubeName}\n </span>\n <span className=\"text-dc-text-muted\">\n dims: {c.dimensionCount}, joins: {c.joinCount}\n </span>\n {c.canReachAll ? (\n <span className=\"text-green-600 dark:text-green-400 flex items-center gap-0.5\">\n <SuccessIcon className=\"w-3 h-3\" />\n reachable\n </span>\n ) : (\n <span className=\"text-red-600 dark:text-red-400 flex items-center gap-0.5\">\n <ErrorIcon className=\"w-3 h-3\" />\n cannot reach all\n </span>\n )}\n </div>\n ))}\n </div>\n </details>\n )}\n </div>\n </div>\n\n {/* Join Paths Section */}\n {analysis.joinPaths.length > 0 && (\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <LinkIcon className=\"w-4 h-4 mr-2\" />\n Join Paths\n </h4>\n <div className=\"space-y-2\">\n {analysis.joinPaths.map((jp, idx) => (\n <div key={idx} className=\"bg-dc-surface p-3 rounded text-sm\">\n <div className=\"flex items-center gap-2 mb-2 flex-wrap\">\n <span className=\"font-mono text-dc-text-secondary\">{analysis.primaryCube.selectedCube}</span>\n <ArrowRightIcon className=\"w-4 h-4 text-dc-text-muted\" />\n <span className=\"font-mono font-medium text-dc-text\">{jp.targetCube}</span>\n {jp.pathFound ? (\n <span className=\"text-xs px-2 py-0.5 bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-300 rounded\">\n {jp.pathLength} step{jp.pathLength !== 1 ? 's' : ''}\n </span>\n ) : (\n <span className=\"text-xs px-2 py-0.5 bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300 rounded\">\n No path\n </span>\n )}\n </div>\n {jp.pathFound && jp.path && jp.path.length > 0 && (\n <div className=\"space-y-1 ml-2\">\n {jp.path.map((step, stepIdx) => (\n <div key={stepIdx} className=\"flex items-center gap-1 text-xs flex-wrap\">\n <span className=\"font-mono text-dc-text-secondary\">{step.fromCube}</span>\n <ArrowRightIcon className=\"w-3 h-3 text-dc-text-muted\" />\n <span className=\"font-mono text-dc-text\">{step.toCube}</span>\n <span className=\"text-dc-text-muted\">\n ({step.relationship}, {step.joinType} join)\n </span>\n {step.joinColumns.length > 0 && (\n <span className=\"text-dc-text-muted\">\n on {step.joinColumns.map(jc => `${jc.sourceColumn}=${jc.targetColumn}`).join(', ')}\n </span>\n )}\n </div>\n ))}\n </div>\n )}\n {!jp.pathFound && jp.error && (\n <p className=\"text-xs text-red-600 dark:text-red-400 mt-1\">{jp.error}</p>\n )}\n {jp.visitedCubes && jp.visitedCubes.length > 0 && !jp.pathFound && (\n <details className=\"mt-1\">\n <summary className=\"text-xs text-dc-text-muted cursor-pointer hover:text-dc-text\">\n Cubes visited during search ({jp.visitedCubes.length})\n </summary>\n <div className=\"mt-1 text-xs text-dc-text-muted ml-2\">\n {jp.visitedCubes.join(' → ')}\n </div>\n </details>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Pre-Aggregations Section */}\n {analysis.preAggregations.length > 0 && (\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <TableIcon className=\"w-4 h-4 mr-2\" />\n Pre-Aggregation CTEs\n </h4>\n <div className=\"space-y-2\">\n {analysis.preAggregations.map((pa, idx) => (\n <div key={idx} className=\"bg-dc-surface p-3 rounded text-sm\">\n <div className=\"flex items-center gap-2 mb-1 flex-wrap\">\n <span className=\"font-mono font-medium text-dc-text\">{pa.cubeName}</span>\n <span className=\"text-xs text-dc-text-muted\">as</span>\n <code className=\"text-xs bg-dc-surface-secondary px-1 rounded font-mono\">{pa.cteAlias}</code>\n </div>\n <p className=\"text-xs text-dc-text-secondary\">{pa.reason}</p>\n <div className=\"mt-1 text-xs text-dc-text-muted\">\n <span className=\"font-medium\">Measures:</span> {pa.measures.join(', ')}\n </div>\n {pa.joinKeys.length > 0 && (\n <div className=\"mt-1 text-xs text-dc-text-muted\">\n <span className=\"font-medium\">Join keys:</span> {pa.joinKeys.map(jk => `${jk.sourceColumn}=${jk.targetColumn}`).join(', ')}\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Warnings Section */}\n {analysis.warnings && analysis.warnings.length > 0 && (\n <div>\n <h4 className=\"text-sm font-semibold text-amber-600 dark:text-amber-400 mb-2 flex items-center\">\n <WarningIcon className=\"w-4 h-4 mr-2\" />\n Warnings\n </h4>\n <ul className=\"list-disc list-inside text-xs text-amber-600 dark:text-amber-400 space-y-1\">\n {analysis.warnings.map((w, i) => (\n <li key={i}>{w}</li>\n ))}\n </ul>\n </div>\n )}\n\n {/* Cubes Involved */}\n {analysis.cubesInvolved.length > 0 && (\n <div className=\"text-xs text-dc-text-muted pt-2 border-t border-dc-border\">\n <span className=\"font-medium\">Cubes involved:</span> {analysis.cubesInvolved.join(', ')}\n </div>\n )}\n </div>\n )\n}\n\nexport default QueryAnalysisPanel\n","/**\n * QueryPanel Component\n * \n * Displays the current query being built, with sections for measures, dimensions, and time dimensions.\n * Includes validation status, JSON preview, and action buttons.\n */\n\nimport React, { useState, useEffect } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterBuilder from './FilterBuilder'\nimport DateRangeFilter from './DateRangeFilter'\nimport QueryAnalysisPanel from './QueryAnalysisPanel'\nimport type { QueryPanelProps } from './types'\nimport { TIME_GRANULARITIES } from './types'\nimport { hasQueryContent, getSelectedFieldsCount, cleanQueryForServer, hasTimeDimensions, getFieldTitle, getSortDirection, getSortTooltip, getNextSortDirection, getFieldType } from './utils'\nimport { getMeasureIcon } from '../../utils/measureIcons'\n\nconst QueryPanel: React.FC<QueryPanelProps> = ({\n query,\n schema,\n validationStatus,\n validationError,\n validationSql,\n validationAnalysis,\n onValidate,\n onExecute,\n onRemoveField,\n onTimeDimensionGranularityChange,\n onFiltersChange,\n onDateRangeChange,\n onDateRangeRemove,\n onOrderChange,\n onClearQuery,\n showSettings,\n onSettingsClick,\n onAIAssistantClick,\n onSchemaClick,\n onShareClick,\n shareButtonState = 'idle',\n isViewingShared = false\n}) => {\n const [showJsonPreview, setShowJsonPreview] = useState(false)\n const [showSqlPreview, setShowSqlPreview] = useState(false)\n const [showAnalysisPreview, setShowAnalysisPreview] = useState(false)\n\n // Trigger Prism highlighting when preview content changes\n useEffect(() => {\n if ((showJsonPreview || showSqlPreview) && typeof window !== 'undefined' && (window as any).Prism) {\n // Use setTimeout to ensure DOM is updated before highlighting\n setTimeout(() => {\n try {\n ;(window as any).Prism.highlightAll()\n } catch (error) {\n // Silently fail if Prism is not available or encounters an error\n }\n }, 0)\n }\n }, [showJsonPreview, showSqlPreview, query, validationSql])\n\n const hasContent = hasQueryContent(query)\n const selectedCount = getSelectedFieldsCount(query)\n\n const CloseIcon = getIcon('close')\n const SuccessIcon = getIcon('success')\n const ErrorIcon = getIcon('error')\n const DeleteIcon = getIcon('delete')\n const CopyIcon = getIcon('copy')\n const SettingsIcon = getIcon('settings')\n const FilterIcon = getIcon('filter')\n const SparklesIcon = getIcon('sparkles')\n const ChevronUpIcon = getIcon('chevronUp')\n const ChevronDownIcon = getIcon('chevronDown')\n const ChevronUpDownIcon = getIcon('chevronUpDown')\n const ShareIcon = getIcon('share')\n const MeasureIcon = getIcon('measure')\n const DimensionIcon = getIcon('dimension')\n const TimeDimensionIcon = getIcon('timeDimension')\n const RunIcon = getIcon('run')\n const CheckIcon = getIcon('check')\n\n const handleCopyQuery = async () => {\n const cleanedQuery = cleanQueryForServer(query)\n try {\n await navigator.clipboard.writeText(JSON.stringify(cleanedQuery, null, 2))\n // You could add a toast notification here if desired\n } catch (error) {\n // Failed to copy query\n // Fallback for older browsers\n const textArea = document.createElement('textarea')\n textArea.value = JSON.stringify(cleanedQuery, null, 2)\n document.body.appendChild(textArea)\n textArea.select()\n document.execCommand('copy')\n document.body.removeChild(textArea)\n }\n }\n\n // Helper function to check if a field has filters applied\n const hasFiltersApplied = (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions'): boolean => {\n if (fieldType === 'timeDimensions') {\n // Check if time dimension has a date range\n return Boolean(query.timeDimensions?.some(td => td.dimension === fieldName && td.dateRange))\n } else {\n // Check if field has regular filters applied\n const currentFilters = query.filters || []\n \n const hasFieldInFilters = (filters: any[]): boolean => {\n return filters.some(filter => {\n if ('member' in filter) {\n // Simple filter\n return filter.member === fieldName\n } else if ('type' in filter && 'filters' in filter) {\n // Group filter - check recursively\n return hasFieldInFilters(filter.filters)\n }\n return false\n })\n }\n \n return hasFieldInFilters(currentFilters)\n }\n }\n\n const handleAddFilterFromField = (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n if (fieldType === 'timeDimensions') {\n // For time dimensions, add a date range instead of a regular filter\n onDateRangeChange(fieldName, 'this month')\n } else {\n // For measures and dimensions, add a regular filter\n // Get current filters and add a new one\n const currentFilters = query.filters || []\n const newFilter = {\n member: fieldName,\n operator: 'equals' as const,\n values: []\n }\n \n // Use the same smart grouping logic as FilterBuilder\n if (currentFilters.length === 0) {\n onFiltersChange([newFilter])\n } else if (currentFilters.length === 1 && 'member' in currentFilters[0]) {\n // Create AND group with existing filter + new filter\n const andGroup = {\n type: 'and' as const,\n filters: [currentFilters[0], newFilter]\n }\n onFiltersChange([andGroup])\n } else if (currentFilters.length === 1 && 'type' in currentFilters[0] && currentFilters[0].type === 'and') {\n // Add to existing AND group\n const existingAndGroup = currentFilters[0]\n const updatedAndGroup = {\n type: 'and' as const,\n filters: [...existingAndGroup.filters, newFilter]\n }\n onFiltersChange([updatedAndGroup])\n } else if (currentFilters.length === 1 && 'type' in currentFilters[0] && currentFilters[0].type === 'or') {\n // Add to existing OR group\n const existingOrGroup = currentFilters[0]\n const updatedOrGroup = {\n type: 'or' as const,\n filters: [...existingOrGroup.filters, newFilter]\n }\n onFiltersChange([updatedOrGroup])\n } else {\n // Fallback: just add to the end\n onFiltersChange([...currentFilters, newFilter])\n }\n }\n }\n\n // Sorting helper functions\n const getSortIcon = (direction: 'asc' | 'desc' | null) => {\n switch (direction) {\n case 'asc':\n return <ChevronUpIcon className={`w-4 h-4 ${direction ? 'stroke-3' : ''}`} />\n case 'desc':\n return <ChevronDownIcon className={`w-4 h-4 ${direction ? 'stroke-3' : ''}`} />\n default:\n return <ChevronUpDownIcon className=\"w-4 h-4\" />\n }\n }\n\n const handleToggleSort = (fieldName: string) => {\n const current = getSortDirection(fieldName, query.order)\n const next = getNextSortDirection(current)\n onOrderChange(fieldName, next)\n }\n\n const getSortButtonClasses = (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n const sortDirection = getSortDirection(fieldName, query.order)\n const baseClasses = 'focus:outline-hidden shrink-0 p-1 transition-colors'\n\n if (sortDirection) {\n // Active sort - use field type colors\n switch (fieldType) {\n case 'measures':\n return `${baseClasses} text-dc-measure hover:opacity-80`\n case 'dimensions':\n return `${baseClasses} text-dc-dimension hover:opacity-80`\n case 'timeDimensions':\n return `${baseClasses} text-dc-time-dimension hover:opacity-80`\n default:\n return `${baseClasses} text-dc-time-dimension hover:opacity-80`\n }\n } else {\n // No sort - gray\n return `${baseClasses} text-dc-text-muted hover:text-dc-text-secondary`\n }\n }\n\n const RemovableChip: React.FC<{ \n label: string\n fieldName: string\n fieldType: 'measures' | 'dimensions' | 'timeDimensions'\n icon: React.ReactNode\n }> = ({ fieldName, fieldType, icon }) => {\n const getChipClasses = () => {\n switch (fieldType) {\n case 'measures':\n return 'bg-dc-measure text-dc-measure border-dc-measure'\n case 'dimensions':\n return 'bg-dc-dimension text-dc-dimension border-dc-dimension'\n case 'timeDimensions':\n return 'bg-dc-time-dimension text-dc-time-dimension border-dc-time-dimension'\n default:\n return 'bg-dc-time-dimension text-dc-time-dimension border-dc-time-dimension'\n }\n }\n\n return (\n <div className={`inline-flex items-center text-sm px-3 py-2 rounded-lg border w-full ${getChipClasses()}`}>\n <div className=\"mr-2 shrink-0\">\n {icon}\n </div>\n <span className=\"flex-1 flex flex-col min-w-0\">\n <span className=\"text-xs font-medium truncate\">{getFieldTitle(fieldName, schema)}</span>\n <span className=\"text-[10px] text-dc-text-muted truncate\">{fieldName}</span>\n </span>\n <div className=\"flex items-center gap-2 ml-2\">\n {/* Filter and Sort buttons - stacked vertically */}\n <div className=\"flex flex-col items-center\">\n {/* Filter button */}\n {(() => {\n const hasFilters = hasFiltersApplied(fieldName, fieldType)\n const getActiveColorClasses = () => {\n switch (fieldType) {\n case 'measures':\n return 'text-dc-measure hover:opacity-80'\n case 'dimensions':\n return 'text-dc-dimension hover:opacity-80'\n case 'timeDimensions':\n return 'text-dc-time-dimension hover:opacity-80'\n default:\n return 'text-dc-time-dimension hover:opacity-80'\n }\n }\n\n return (\n <button\n onClick={() => handleAddFilterFromField(fieldName, fieldType)}\n className={`focus:outline-hidden shrink-0 p-0.5 transition-colors ${\n hasFilters\n ? getActiveColorClasses()\n : 'text-dc-text-muted hover:text-dc-text-secondary'\n }`}\n title={fieldType === 'timeDimensions' ? 'Add date range' : 'Add filter'}\n >\n <FilterIcon className={`w-4 h-4 ${hasFilters ? 'stroke-3' : ''}`} />\n </button>\n )\n })()}\n\n {/* Sort button */}\n <button\n onClick={() => handleToggleSort(fieldName)}\n className={`focus:outline-hidden shrink-0 p-0.5 transition-colors ${getSortButtonClasses(fieldName, fieldType).replace('p-1', 'p-0.5')}`}\n title={getSortTooltip(getSortDirection(fieldName, query.order))}\n >\n {getSortIcon(getSortDirection(fieldName, query.order))}\n </button>\n </div>\n\n {/* Remove button */}\n <button\n onClick={() => onRemoveField(fieldName, fieldType)}\n className=\"text-dc-text-secondary hover:text-red-600 focus:outline-hidden shrink-0\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n )\n }\n\n const TimeDimensionChip: React.FC<{\n timeDimension: { dimension: string; granularity?: string }\n label: string\n }> = ({ timeDimension }) => (\n <div className=\"bg-dc-time-dimension text-dc-time-dimension text-sm px-3 py-2 rounded-lg border border-dc-time-dimension w-full\">\n {/* Top row with icon, label, filter button, sort button, and remove button */}\n <div className=\"flex items-center mb-1\">\n <div className=\"mr-2\">\n <TimeDimensionIcon className=\"w-4 h-4\" />\n </div>\n <span className=\"flex-1 flex flex-col min-w-0\">\n <span className=\"text-xs font-medium truncate\">{getFieldTitle(timeDimension.dimension, schema)}</span>\n <span className=\"text-[10px] text-dc-text-muted truncate\">{timeDimension.dimension}</span>\n </span>\n <div className=\"flex items-center gap-2 ml-2\">\n {/* Filter and Sort buttons - stacked vertically */}\n <div className=\"flex flex-col items-center\">\n {/* Filter button */}\n {(() => {\n const hasDateRange = hasFiltersApplied(timeDimension.dimension, 'timeDimensions')\n return (\n <button\n onClick={() => handleAddFilterFromField(timeDimension.dimension, 'timeDimensions')}\n className={`focus:outline-hidden shrink-0 p-0.5 transition-colors ${\n hasDateRange\n ? 'text-dc-time-dimension hover:opacity-80'\n : 'text-dc-text-muted hover:text-dc-text-secondary'\n }`}\n title=\"Add date range\"\n >\n <FilterIcon className={`w-4 h-4 ${hasDateRange ? 'stroke-3' : ''}`} />\n </button>\n )\n })()}\n\n {/* Sort button */}\n <button\n onClick={() => handleToggleSort(timeDimension.dimension)}\n className={`focus:outline-hidden shrink-0 p-0.5 transition-colors ${getSortButtonClasses(timeDimension.dimension, 'timeDimensions').replace('p-1', 'p-0.5')}`}\n title={getSortTooltip(getSortDirection(timeDimension.dimension, query.order))}\n >\n {getSortIcon(getSortDirection(timeDimension.dimension, query.order))}\n </button>\n </div>\n\n {/* Remove button */}\n <button\n onClick={() => onRemoveField(timeDimension.dimension, 'timeDimensions')}\n className=\"text-dc-text-secondary hover:text-red-600 focus:outline-hidden\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n {/* Bottom row with granularity dropdown */}\n <div className=\"ml-6 flex items-center\">\n <span className=\"text-xs text-dc-time-dimension mr-2\">Granularity:</span>\n <select\n value={timeDimension.granularity || 'month'}\n onChange={(e) => onTimeDimensionGranularityChange(timeDimension.dimension, e.target.value)}\n className=\"bg-dc-time-dimension border-none text-dc-time-dimension text-xs rounded-sm focus:ring-2 focus:ring-blue-500 flex-1\"\n onClick={(e) => e.stopPropagation()}\n >\n {TIME_GRANULARITIES.map(granularity => (\n <option key={granularity.value} value={granularity.value}>\n {granularity.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n )\n\n const ValidationStatusIcon = () => {\n switch (validationStatus) {\n case 'validating':\n return (\n <div className=\"animate-spin rounded-full h-5 w-5 border-b-2 border-blue-600\"></div>\n )\n case 'valid':\n return <SuccessIcon className=\"w-5 h-5 text-green-600\" />\n case 'invalid':\n return <ErrorIcon className=\"w-5 h-5 text-red-600\" />\n default:\n return null\n }\n }\n\n return (\n <div className=\"flex flex-col bg-dc-surface border border-dc-border rounded-lg\">\n {/* Header */}\n <div className=\"p-3 sm:p-4 border-b border-dc-border\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex items-center gap-1 sm:gap-2 min-w-0\">\n <h3 className=\"text-sm sm:text-lg font-semibold text-dc-text truncate\">Query Builder</h3>\n {onSchemaClick && (\n <button\n onClick={onSchemaClick}\n className=\"flex items-center gap-1 px-3 py-2 text-xs font-medium text-blue-700 dark:text-blue-300 bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-800 rounded-lg hover:bg-blue-100 dark:hover:bg-blue-900/50 focus:outline-hidden focus:ring-2 focus:ring-blue-500 transition-all duration-200 shrink-0\"\n title=\"Schema Explorer - View cube relationships and fields\"\n >\n <svg className=\"w-3 h-3 sm:w-4 sm:h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fillRule=\"evenodd\" d=\"M3 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V4zM3 10a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H4a1 1 0 01-1-1v-6zM14 9a1 1 0 00-1 1v6a1 1 0 001 1h2a1 1 0 001-1v-6a1 1 0 00-1-1h-2z\" clipRule=\"evenodd\" />\n </svg>\n <span>Schema</span>\n </button>\n )}\n {onAIAssistantClick && (\n <button\n onClick={onAIAssistantClick}\n className=\"flex items-center gap-1 px-3 py-2 text-xs font-medium text-purple-700 dark:text-purple-300 bg-purple-50 dark:bg-purple-900/30 border border-purple-200 dark:border-purple-800 rounded-lg hover:bg-purple-100 dark:hover:bg-purple-900/50 focus:outline-hidden focus:ring-2 focus:ring-purple-500 transition-all duration-200 shrink-0\"\n title=\"AI Assistant - Generate queries with AI\"\n >\n <SparklesIcon className=\"w-3 h-3 sm:w-4 sm:h-4\" />\n <span>AI Assistant</span>\n </button>\n )}\n </div>\n <div className=\"flex items-center gap-1 shrink-0\">\n {hasContent && (\n <>\n <span className=\"hidden lg:inline text-xs text-dc-text-muted mr-1\">\n {selectedCount} field{selectedCount !== 1 ? 's' : ''} selected\n </span>\n <button\n onClick={handleCopyQuery}\n className=\"flex items-center gap-1 px-3 py-2 text-xs font-medium text-purple-700 dark:text-purple-300 bg-purple-100 dark:bg-purple-900/30 border border-purple-200 dark:border-purple-800 rounded-sm hover:bg-purple-200 dark:hover:bg-purple-900/50 focus:outline-hidden focus:ring-2 focus:ring-purple-500\"\n title=\"Copy query to clipboard\"\n >\n <CopyIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Copy Query</span>\n </button>\n {onShareClick && (\n <button\n onClick={onShareClick}\n className={`flex items-center gap-1 px-3 py-2 text-xs font-medium rounded-sm focus:outline-hidden focus:ring-2 transition-colors ${\n shareButtonState === 'idle'\n ? 'text-blue-700 dark:text-blue-300 bg-blue-100 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-800 hover:bg-blue-200 dark:hover:bg-blue-900/50 focus:ring-blue-500'\n : 'text-green-700 dark:text-green-300 bg-green-100 dark:bg-green-900/30 border border-green-200 dark:border-green-800 focus:ring-green-500'\n }`}\n title={shareButtonState === 'idle' ? 'Share this analysis' : 'Link copied!'}\n disabled={shareButtonState !== 'idle'}\n >\n {shareButtonState === 'idle' ? (\n <>\n <ShareIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Share</span>\n </>\n ) : shareButtonState === 'copied' ? (\n <>\n <CheckIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Copied!</span>\n </>\n ) : (\n <>\n <CheckIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Copied!</span>\n <span className=\"hidden lg:inline text-[10px] opacity-75\">(no chart)</span>\n </>\n )}\n </button>\n )}\n {onClearQuery && (\n <button\n onClick={onClearQuery}\n className=\"text-dc-text-muted hover:text-red-600 focus:outline-hidden p-2\"\n title=\"Clear all fields\"\n >\n <DeleteIcon className=\"w-3 h-3 sm:w-4 sm:h-4\" />\n </button>\n )}\n </>\n )}\n {showSettings && onSettingsClick && (\n <button\n onClick={onSettingsClick}\n className=\"text-dc-text-muted hover:text-dc-text-secondary focus:outline-hidden p-2\"\n title=\"API Configuration\"\n >\n <SettingsIcon className=\"w-3 h-3 sm:w-4 sm:h-4\" />\n </button>\n )}\n <ValidationStatusIcon />\n </div>\n </div>\n </div>\n\n {/* Viewing Shared Indicator */}\n {isViewingShared && (\n <div className=\"px-4 py-2 bg-blue-50 dark:bg-blue-900/20 border-b border-blue-200 dark:border-blue-800 flex items-center gap-2 text-sm text-blue-700 dark:text-blue-300\">\n <ShareIcon className=\"w-4 h-4\" />\n <span>Viewing shared analysis</span>\n </div>\n )}\n\n {/* Content */}\n <div className=\"p-4\">\n {!hasContent ? (\n <div className=\"py-8 flex items-center justify-center text-dc-text-muted\">\n <div className=\"text-center\">\n <MeasureIcon className=\"w-12 h-12 mx-auto text-dc-text-muted mb-3\" />\n <div className=\"text-sm font-semibold mb-1\">No fields selected</div>\n <div className=\"text-xs\">Select measures, dimensions, or time dimensions from the schema explorer</div>\n </div>\n </div>\n ) : (\n <div className=\"space-y-6\">\n {/* Responsive Layout Grid */}\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n {/* Dimensions Column */}\n <div className=\"min-h-24\">\n <h4 className=\"text-sm font-semibold text-dc-dimension mb-3 flex items-center\">\n <DimensionIcon className=\"w-4 h-4 mr-2\" />\n Dimensions ({(query.dimensions || []).length})\n </h4>\n <div className=\"flex flex-col gap-2\">\n {(query.dimensions || []).map(dimension => (\n <RemovableChip\n key={dimension}\n label={dimension}\n fieldName={dimension}\n fieldType=\"dimensions\"\n icon={<DimensionIcon className=\"w-4 h-4\" />}\n />\n ))}\n </div>\n </div>\n\n {/* Time Dimensions Column */}\n <div className=\"min-h-24\">\n <h4 className=\"text-sm font-semibold text-dc-time-dimension mb-3 flex items-center\">\n <TimeDimensionIcon className=\"w-4 h-4 mr-2\" />\n Time Dimensions ({(query.timeDimensions || []).length})\n </h4>\n <div className=\"flex flex-col gap-2\">\n {(query.timeDimensions || []).map(timeDimension => (\n <TimeDimensionChip\n key={timeDimension.dimension}\n timeDimension={timeDimension}\n label={timeDimension.dimension}\n />\n ))}\n </div>\n </div>\n\n {/* Measures Column */}\n <div className=\"min-h-24\">\n <h4 className=\"text-sm font-semibold text-dc-measure mb-3 flex items-center\">\n <MeasureIcon className=\"w-4 h-4 mr-2\" />\n Measures ({(query.measures || []).length})\n </h4>\n <div className=\"flex flex-col gap-2\">\n {(query.measures || []).map(measure => {\n const measureType = schema ? getFieldType(measure, schema) : undefined\n return (\n <RemovableChip\n key={measure}\n label={measure}\n fieldName={measure}\n fieldType=\"measures\"\n icon={getMeasureIcon(measureType, 'w-4 h-4')}\n />\n )\n })}\n </div>\n </div>\n </div>\n\n {/* Date Range Section */}\n {hasTimeDimensions(query) && (\n <div className=\"mt-6\">\n <DateRangeFilter\n timeDimensions={query.timeDimensions || []}\n onDateRangeChange={onDateRangeChange}\n onDateRangeRemove={onDateRangeRemove}\n />\n </div>\n )}\n\n {/* Filters Section */}\n <div className=\"mt-6\">\n <FilterBuilder\n filters={query.filters || []}\n schema={schema}\n query={query}\n onFiltersChange={onFiltersChange}\n />\n </div>\n\n {/* Validation Error */}\n {validationError && (\n <div className=\"bg-red-50 border border-red-200 rounded-lg p-4\">\n <div className=\"flex items-start\">\n <ErrorIcon className=\"w-5 h-5 text-red-600 mr-2 mt-0.5\" />\n <div>\n <h5 className=\"text-sm font-semibold text-red-800\">Validation Error</h5>\n <p className=\"text-sm text-red-700 mt-1\">{validationError}</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Preview Toggles */}\n <div className=\"space-y-3\">\n <div className=\"flex space-x-4 flex-wrap gap-y-2\">\n <button\n onClick={() => {\n const newJsonState = !showJsonPreview\n setShowJsonPreview(newJsonState)\n if (newJsonState) {\n setShowSqlPreview(false)\n setShowAnalysisPreview(false)\n }\n }}\n className=\"text-sm text-dc-text-secondary hover:text-dc-text focus:outline-hidden focus:underline\"\n >\n {showJsonPreview ? 'Hide' : 'Show'} JSON Query\n </button>\n {validationSql && (\n <button\n onClick={() => {\n const newSqlState = !showSqlPreview\n setShowSqlPreview(newSqlState)\n if (newSqlState) {\n setShowJsonPreview(false)\n setShowAnalysisPreview(false)\n }\n }}\n className=\"text-sm text-dc-text-secondary hover:text-dc-text focus:outline-hidden focus:underline\"\n >\n {showSqlPreview ? 'Hide' : 'Show'} SQL Generated\n </button>\n )}\n {validationAnalysis && (\n <button\n onClick={() => {\n const newAnalysisState = !showAnalysisPreview\n setShowAnalysisPreview(newAnalysisState)\n if (newAnalysisState) {\n setShowJsonPreview(false)\n setShowSqlPreview(false)\n }\n }}\n className=\"text-sm text-dc-text-secondary hover:text-dc-text focus:outline-hidden focus:underline\"\n >\n {showAnalysisPreview ? 'Hide' : 'Show'} Query Analysis\n </button>\n )}\n </div>\n\n {showJsonPreview && (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-lg p-4\">\n <div className=\"text-xs font-semibold text-dc-text-secondary mb-2\">JSON Query:</div>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono\" style={{ fontSize: '12px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(cleanQueryForServer(query), null, 2)}</code>\n </pre>\n </div>\n )}\n\n {showSqlPreview && validationSql && (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-lg p-4\">\n <div className=\"text-xs font-semibold text-dc-text-secondary mb-2\">Generated SQL:</div>\n <pre className=\"text-dc-text-secondary overflow-x-auto whitespace-pre-wrap font-mono\" style={{ fontSize: '12px', lineHeight: '1.4' }}>\n <code className=\"language-sql\">{validationSql.sql.join(';\\n\\n')}</code>\n </pre>\n {validationSql.params && validationSql.params.length > 0 && (\n <>\n <div className=\"text-xs font-semibold text-dc-text-secondary mb-2 mt-4\">Parameters:</div>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono\" style={{ fontSize: '12px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(validationSql.params, null, 2)}</code>\n </pre>\n </>\n )}\n </div>\n )}\n\n {showAnalysisPreview && validationAnalysis && (\n <QueryAnalysisPanel analysis={validationAnalysis} />\n )}\n </div>\n </div>\n )}\n </div>\n\n {/* Actions */}\n {(hasContent || validationStatus === 'valid' || validationStatus === 'invalid') && (\n <div className=\"border-t border-dc-border p-4\">\n <div className=\"flex space-x-3\">\n <button\n onClick={onValidate}\n disabled={validationStatus === 'validating'}\n className={`flex-1 flex items-center justify-center px-4 py-2 text-sm font-medium rounded-md transition-colors ${\n validationStatus === 'validating'\n ? 'bg-dc-surface-secondary text-dc-text-muted cursor-not-allowed'\n : validationStatus === 'valid'\n ? 'bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-300 border border-green-200 dark:border-green-800 hover:bg-green-200 dark:hover:bg-green-900/50'\n : validationStatus === 'invalid'\n ? 'bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-300 border border-red-200 dark:border-red-800 hover:bg-red-200 dark:hover:bg-red-900/50'\n : 'bg-purple-100 dark:bg-purple-900/30 text-purple-800 dark:text-purple-300 border border-purple-200 dark:border-purple-800 hover:bg-purple-200 dark:hover:bg-purple-900/50'\n }`}\n >\n {validationStatus === 'validating' ? (\n <>\n <div className=\"animate-spin rounded-full h-4 w-4 border-b-2 border-current mr-2\"></div>\n Validating...\n </>\n ) : validationStatus === 'valid' ? (\n <>\n <CheckIcon className=\"w-4 h-4 mr-2\" />\n Re-validate Query\n </>\n ) : validationStatus === 'invalid' ? (\n <>\n <ErrorIcon className=\"w-4 h-4 mr-2\" />\n Validate Again\n </>\n ) : (\n <>\n <CheckIcon className=\"w-4 h-4 mr-2\" />\n Validate Query\n </>\n )}\n </button>\n\n <button\n onClick={onExecute}\n disabled={validationStatus !== 'valid'}\n className={`flex-1 flex items-center justify-center px-4 py-2 text-sm font-medium rounded-md transition-colors ${\n validationStatus !== 'valid'\n ? 'bg-dc-surface-secondary text-dc-text-muted cursor-not-allowed border border-dc-border'\n : 'text-white border border-green-700 hover:bg-green-700 focus:ring-2 focus:ring-green-500'\n }`}\n style={validationStatus === 'valid' ? { backgroundColor: 'var(--dc-primary)' } : undefined}\n >\n <RunIcon className=\"w-4 h-4 mr-2\" />\n Run Query\n </button>\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport default QueryPanel","import { barChartConfig } from '../components/charts/BarChart.config'\nimport { lineChartConfig } from '../components/charts/LineChart.config'\nimport { areaChartConfig } from '../components/charts/AreaChart.config'\nimport { pieChartConfig } from '../components/charts/PieChart.config'\nimport { scatterChartConfig } from '../components/charts/ScatterChart.config'\nimport { bubbleChartConfig } from '../components/charts/BubbleChart.config'\nimport { radarChartConfig } from '../components/charts/RadarChart.config'\nimport { radialBarChartConfig } from '../components/charts/RadialBarChart.config'\nimport { treemapChartConfig } from '../components/charts/TreeMapChart.config'\nimport { dataTableConfig } from '../components/charts/DataTable.config'\nimport { activityGridChartConfig } from '../components/charts/ActivityGridChart.config'\nimport { kpiNumberConfig } from '../components/charts/KpiNumber.config'\nimport { kpiDeltaConfig } from '../components/charts/KpiDelta.config'\nimport { kpiTextConfig } from '../components/charts/KpiText.config'\nimport { markdownConfig } from '../components/charts/MarkdownChart.config'\nimport type { ChartConfigRegistry } from './chartConfigs'\n\n/**\n * Registry of all chart type configurations\n */\nexport const chartConfigRegistry: ChartConfigRegistry = {\n bar: barChartConfig,\n line: lineChartConfig,\n area: areaChartConfig,\n pie: pieChartConfig,\n scatter: scatterChartConfig,\n bubble: bubbleChartConfig,\n radar: radarChartConfig,\n radialBar: radialBarChartConfig,\n treemap: treemapChartConfig,\n table: dataTableConfig,\n activityGrid: activityGridChartConfig,\n kpiNumber: kpiNumberConfig,\n kpiDelta: kpiDeltaConfig,\n kpiText: kpiTextConfig,\n markdown: markdownConfig\n}","import { useState } from 'react'\nimport { chartConfigRegistry } from '../charts/chartConfigRegistry'\nimport type { ChartType } from '../types'\n\ninterface ChartTypeSelectorProps {\n selectedType: ChartType\n onTypeChange: (type: ChartType) => void\n className?: string\n}\n\nexport default function ChartTypeSelector({ \n selectedType, \n onTypeChange, \n className = '' \n}: ChartTypeSelectorProps) {\n const [isOpen, setIsOpen] = useState(false)\n const chartTypes = Object.entries(chartConfigRegistry) as [ChartType, typeof chartConfigRegistry[keyof typeof chartConfigRegistry]][]\n\n // Chart type display names (fallback if not in config)\n const chartTypeLabels: Record<ChartType, string> = {\n bar: 'Bar Chart',\n line: 'Line Chart', \n area: 'Area Chart',\n pie: 'Pie Chart',\n scatter: 'Scatter Plot',\n bubble: 'Bubble Chart',\n radar: 'Radar Chart',\n radialBar: 'Radial Bar Chart',\n treemap: 'TreeMap',\n table: 'Data Table',\n activityGrid: 'Activity Grid',\n kpiNumber: 'KPI Number',\n kpiDelta: 'KPI Delta',\n kpiText: 'KPI Text',\n markdown: 'Markdown'\n }\n\n const selectedConfig = chartConfigRegistry[selectedType]\n const SelectedIcon = selectedConfig?.icon\n const selectedLabel = chartTypeLabels[selectedType]\n\n return (\n <div className={`${className} relative`}>\n {/* Dropdown Button */}\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n className=\"w-full flex items-center justify-between px-3 py-2 border border-dc-border rounded-md bg-dc-surface hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n >\n <div className=\"flex items-center space-x-2\">\n {SelectedIcon && (\n <SelectedIcon className=\"h-5 w-5 text-dc-text-secondary\" />\n )}\n <span className=\"text-sm font-medium text-dc-text\">{selectedLabel}</span>\n </div>\n <svg\n className={`h-4 w-4 text-dc-text-muted transform transition-transform ${isOpen ? 'rotate-180' : ''}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n\n {/* Dropdown Menu - Grid Layout */}\n {isOpen && (\n <div className=\"absolute z-10 mt-1 w-full min-w-max bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-80 overflow-auto\">\n <div className=\"p-2\">\n <div className=\"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-1.5\">\n {chartTypes.map(([type, config]) => {\n const IconComponent = config.icon\n const label = chartTypeLabels[type]\n const isSelected = selectedType === type\n const description = config.description\n const useCase = config.useCase\n \n // Combine description and use case for tooltip\n const tooltipText = [description, useCase].filter(Boolean).join('. ')\n \n return (\n <button\n key={type}\n type=\"button\"\n onClick={() => {\n onTypeChange(type)\n setIsOpen(false)\n }}\n className={`\n relative p-1.5 rounded border transition-colors duration-150\n text-left group min-h-[30px] flex items-center justify-start\n ${isSelected\n ? 'bg-dc-surface-secondary'\n : 'bg-dc-surface hover:bg-dc-surface-hover'\n }\n `}\n style={{\n borderColor: isSelected ? 'var(--dc-primary)' : 'var(--dc-border)'\n }}\n title={tooltipText}\n >\n <div className=\"flex items-center space-x-1.5\">\n {/* Icon */}\n {IconComponent && (\n <IconComponent\n className={`h-4 w-4 shrink-0 ${isSelected ? 'text-dc-text' : 'text-dc-text-secondary'}`}\n />\n )}\n\n {/* Chart name */}\n <span className={`text-xs font-medium leading-tight truncate ${\n isSelected ? '' : 'text-dc-text'\n }`}\n style={isSelected ? { color: 'var(--dc-primary)' } : undefined}>\n {label}\n </span>\n </div>\n\n {/* Selected indicator - smaller dot */}\n {isSelected && (\n <div className=\"absolute top-0.5 right-0.5\">\n <div className=\"w-1.5 h-1.5 rounded-full\" style={{ backgroundColor: 'var(--dc-primary)' }}></div>\n </div>\n )}\n </button>\n )\n })}\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}","import React, { useState } from 'react'\nimport { getIcon } from '../icons'\nimport type { AxisDropZoneConfig } from '../charts/chartConfigs'\n\nconst CloseIcon = getIcon('close')\n\ninterface FieldStyling {\n IconComponent: React.ComponentType<{ className?: string }>\n baseClasses: string\n hoverClasses: string\n}\n\ninterface AxisDropZoneProps {\n config: AxisDropZoneConfig\n fields: string[]\n onDrop: (e: React.DragEvent<HTMLDivElement>, toKey: string) => void\n onRemove: (field: string, fromKey: string) => void\n onDragStart: (e: React.DragEvent<HTMLDivElement>, field: string, fromKey: string, fromIndex?: number) => void\n onDragEnd?: (e: React.DragEvent<HTMLDivElement>) => void\n onDragOver: (e: React.DragEvent<HTMLDivElement>) => void\n getFieldStyling: (field: string) => FieldStyling\n onReorder?: (fromIndex: number, toIndex: number, axisKey: string) => void\n draggedItem?: { field: string; fromAxis: string; fromIndex?: number } | null\n}\n\nexport default function AxisDropZone({\n config,\n fields,\n onDrop,\n onRemove,\n onDragStart,\n onDragEnd,\n onDragOver,\n getFieldStyling,\n onReorder,\n draggedItem\n}: AxisDropZoneProps) {\n const { key, label, description, mandatory, maxItems, emptyText, icon: IconComponent } = config\n const [dragOverIndex, setDragOverIndex] = useState<number | null>(null)\n const [isDraggedOver, setIsDraggedOver] = useState(false)\n const [isReorderDraggedOver, setIsReorderDraggedOver] = useState(false)\n \n // Calculate acceptance considering what's being dragged\n const getCanAcceptMore = () => {\n let effectiveCount = fields.length\n \n // If we're dragging FROM this axis, we effectively have one less item\n if (draggedItem && draggedItem.fromAxis === key) {\n effectiveCount = Math.max(0, fields.length - 1)\n }\n \n return !maxItems || effectiveCount < maxItems\n }\n \n const getIsFull = () => {\n let effectiveCount = fields.length\n \n // If we're dragging FROM this axis, we effectively have one less item\n if (draggedItem && draggedItem.fromAxis === key) {\n effectiveCount = Math.max(0, fields.length - 1)\n }\n \n return maxItems && effectiveCount >= maxItems\n }\n \n const canAcceptMore = getCanAcceptMore()\n const isFull = getIsFull()\n \n\n // Add a global drag end listener to reset visual state\n React.useEffect(() => {\n const handleGlobalDragEnd = () => {\n setDragOverIndex(null)\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }\n\n document.addEventListener('dragend', handleGlobalDragEnd)\n return () => {\n document.removeEventListener('dragend', handleGlobalDragEnd)\n }\n }, [])\n\n // Clear states when transitioning between different drag operations\n React.useEffect(() => {\n if (draggedItem) {\n // If we have a dragged item but it's not from this axis, clear reorder state\n if (draggedItem.fromAxis !== key) {\n setIsReorderDraggedOver(false)\n setDragOverIndex(null)\n }\n // If we have a dragged item from this axis, clear regular drag state\n else if (draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n setIsDraggedOver(false)\n }\n } else {\n // No dragged item, clear all states\n setDragOverIndex(null)\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }\n }, [draggedItem, key])\n\n const handleReorderDragOver = (e: React.DragEvent<HTMLDivElement>, targetIndex: number) => {\n // Check if this is a reorder operation (same axis) using the draggedItem prop\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n e.preventDefault()\n e.stopPropagation()\n setDragOverIndex(targetIndex)\n setIsReorderDraggedOver(true)\n }\n }\n\n const handleReorderDragLeave = () => {\n // Clear the individual item drag over index\n setDragOverIndex(null)\n // Note: Don't clear isReorderDraggedOver here as it causes flickering\n // Let the global drag end handler clear it when the drag is truly complete\n }\n\n const handleReorderDrop = (e: React.DragEvent<HTMLDivElement>, targetIndex: number) => {\n e.preventDefault()\n e.stopPropagation()\n setDragOverIndex(null)\n setIsReorderDraggedOver(false)\n \n // Handle reordering using either drag data or the draggedItem prop\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined && onReorder) {\n onReorder(draggedItem.fromIndex, targetIndex, key)\n return\n }\n \n // Fallback to parsing drag data\n try {\n const data = JSON.parse(e.dataTransfer.getData('text/plain'))\n if (data.fromAxis === key && onReorder && data.fromIndex !== undefined) {\n onReorder(data.fromIndex, targetIndex, key)\n }\n } catch {\n // If we can't parse the data, ignore\n }\n }\n \n return (\n <div className=\"mb-2\">\n <div className=\"flex items-center gap-2 mb-1\">\n <h4 className=\"text-xs font-semibold text-dc-text-secondary flex items-center\">\n {IconComponent && <IconComponent className=\"w-3 h-3 mr-1 text-dc-text-muted\" />}\n {label}\n {mandatory && <span className=\"text-red-500 ml-1\">*</span>}\n {maxItems && (\n <span className=\"text-dc-text-muted ml-1 font-normal\">\n ({fields.length}/{maxItems})\n </span>\n )}\n </h4>\n {description && (\n <span className=\"text-xs text-dc-text-muted\">\n {description}\n </span>\n )}\n </div>\n \n <div\n data-axis-container={key}\n className={`min-h-[40px] sm:min-h-[32px] border-2 border-dashed rounded-lg p-3 sm:p-1.5 transition-all duration-300 flex items-center ${\n (isDraggedOver && (canAcceptMore || maxItems === 1)) || isReorderDraggedOver\n ? 'shadow-lg scale-110 border-solid animate-pulse'\n : isFull\n ? 'bg-dc-surface-secondary'\n : 'bg-dc-surface-secondary hover:bg-dc-surface-hover'\n }`}\n style={{\n borderColor: (isDraggedOver && (canAcceptMore || maxItems === 1)) || isReorderDraggedOver\n ? 'var(--dc-primary)'\n : 'var(--dc-border)',\n backgroundColor: (isDraggedOver && (canAcceptMore || maxItems === 1)) || isReorderDraggedOver\n ? 'rgba(var(--dc-primary-rgb), 0.1)'\n : undefined\n }}\n onDragOver={(e) => {\n // Check if this is a reorder operation (same axis) - if so, don't interfere\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n return\n }\n \n // Simple acceptance check - either we have space OR it's a single-item replacement\n const canAccept = canAcceptMore || (maxItems === 1)\n \n if (canAccept) {\n setIsDraggedOver(true)\n onDragOver(e)\n } else {\n e.preventDefault()\n e.dataTransfer.dropEffect = 'none'\n }\n }}\n onDragLeave={(e) => {\n // Check if we're truly leaving the container\n const rect = e.currentTarget.getBoundingClientRect()\n const isLeavingContainer = (\n e.clientX < rect.left || \n e.clientX > rect.right || \n e.clientY < rect.top || \n e.clientY > rect.bottom\n )\n \n // Also check if the related target is outside this container\n const relatedTarget = e.relatedTarget as Element | null\n const isRelatedTargetOutside = relatedTarget && !e.currentTarget.contains(relatedTarget)\n \n if (isLeavingContainer || isRelatedTargetOutside || e.currentTarget === e.target) {\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }\n }}\n onDrop={(e) => {\n // Check if this is a reorder operation (same axis) - if so, don't interfere\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n return\n }\n \n // Simple acceptance check - either we have space OR it's a single-item replacement\n const shouldAcceptDrop = canAcceptMore || (maxItems === 1)\n \n if (shouldAcceptDrop) {\n onDrop(e, key)\n } else {\n e.preventDefault()\n }\n \n // Reset drag state on drop\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }}\n >\n {fields.length === 0 ? (\n <div className=\"text-xs text-dc-text-muted text-center w-full\">\n {isFull ? 'Maximum items reached' : (emptyText || `Drop fields here`)}\n </div>\n ) : (\n <div className=\"flex flex-wrap gap-1\">\n {fields.map((field, index) => {\n const { IconComponent: FieldIcon, baseClasses, hoverClasses } = getFieldStyling(field)\n const isDragOver = dragOverIndex === index\n const isBeingDragged = draggedItem && draggedItem.field === field && draggedItem.fromAxis === key\n \n return (\n <div\n key={`${field}-${index}`}\n className={`relative ${isDragOver ? 'transform scale-105' : ''}`}\n >\n {/* Drop indicator line for reordering */}\n {isDragOver && (\n <div className=\"absolute -left-1 top-0 bottom-0 w-1 rounded-full z-10\" style={{ backgroundColor: 'var(--dc-primary)' }} />\n )}\n \n <div\n draggable\n onDragStart={(e) => {\n // Let parent handle drag data with index\n onDragStart(e, field, key, index)\n }}\n onDragEnd={onDragEnd}\n onDragOver={(e) => handleReorderDragOver(e, index)}\n onDragLeave={handleReorderDragLeave}\n onDrop={(e) => handleReorderDrop(e, index)}\n className={`rounded text-xs cursor-move px-3 py-0.5 sm:px-2 sm:py-1 flex items-center transition-transform h-[28px] sm:h-auto ${baseClasses} ${hoverClasses} ${\n isDragOver ? 'bg-opacity-75' : ''\n } ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n >\n <FieldIcon className=\"w-3 h-3 mr-1 shrink-0\" />\n <span className=\"leading-none\">{field}</span>\n <button\n type=\"button\"\n onClick={() => onRemove(field, key)}\n className=\"text-dc-text-secondary hover:text-red-600 ml-1.5 leading-none\"\n title={`Remove from ${label}`}\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n </div>\n )\n })}\n </div>\n )}\n </div>\n \n {mandatory && fields.length === 0 && (\n <div className=\"text-xs text-red-500 mt-0.5\">\n This field is required\n </div>\n )}\n </div>\n )\n}","import React, { useMemo, useEffect, useState } from 'react'\nimport { getIcon } from '../icons'\nimport AxisDropZone from './AxisDropZone'\n\nconst MeasureIcon = getIcon('measure')\nconst DimensionIcon = getIcon('dimension')\nconst TimeDimensionIcon = getIcon('timeDimension')\nimport { chartConfigRegistry } from '../charts/chartConfigRegistry'\nimport { getChartConfig } from '../charts/chartConfigs'\nimport type { ChartType, ChartAxisConfig, ChartDisplayConfig, ColorPalette } from '../types'\n\ninterface ChartConfigPanelProps {\n chartType: ChartType\n chartConfig: ChartAxisConfig\n displayConfig: ChartDisplayConfig\n availableFields: {\n dimensions: string[]\n timeDimensions: string[]\n measures: string[]\n } | null\n colorPalette?: ColorPalette\n onChartConfigChange: (config: ChartAxisConfig) => void\n onDisplayConfigChange: (config: ChartDisplayConfig) => void\n}\n\nexport default function ChartConfigPanel({\n chartType,\n chartConfig,\n displayConfig,\n availableFields,\n colorPalette,\n onChartConfigChange,\n onDisplayConfigChange\n}: ChartConfigPanelProps) {\n \n // Track currently dragging item for immediate state updates\n const [draggedItem, setDraggedItem] = useState<{\n field: string\n fromAxis: string\n fromIndex?: number\n } | null>(null)\n \n // Get configuration for current chart type\n const chartTypeConfig = useMemo(() => \n getChartConfig(chartType, chartConfigRegistry),\n [chartType]\n )\n \n // Check if this chart type skips queries\n const shouldSkipQuery = chartTypeConfig.skipQuery === true\n\n // Get fields for each drop zone\n const getFieldsForDropZone = (key: string): string[] => {\n const value = chartConfig[key as keyof ChartAxisConfig]\n const result = Array.isArray(value) ? value : (typeof value === 'string' ? [value] : [])\n return result\n }\n\n // Clean up chart config when available fields change\n useEffect(() => {\n if (!availableFields) return\n\n const allAvailableFields = [\n ...availableFields.dimensions,\n ...availableFields.timeDimensions,\n ...availableFields.measures\n ]\n\n let hasChanges = false\n const newConfig = { ...chartConfig }\n\n // Check each axis and remove fields that are no longer available\n chartTypeConfig.dropZones.forEach(dropZone => {\n const currentFields = getFieldsForDropZone(dropZone.key)\n const validFields = currentFields.filter(field => allAvailableFields.includes(field))\n \n if (validFields.length !== currentFields.length) {\n hasChanges = true\n if (validFields.length === 0) {\n // Remove the axis property entirely if no valid fields remain\n delete newConfig[dropZone.key as keyof ChartAxisConfig]\n } else if (dropZone.maxItems === 1) {\n // Single field axis - always store as string\n newConfig[dropZone.key as keyof ChartAxisConfig] = validFields[0] as any\n } else {\n // Multi-field axis - always store as array\n newConfig[dropZone.key as keyof ChartAxisConfig] = validFields as any\n }\n }\n })\n\n if (hasChanges) {\n onChartConfigChange(newConfig)\n }\n }, [availableFields, chartConfig, chartTypeConfig.dropZones, onChartConfigChange])\n\n // Helper to determine field type and styling\n const getFieldType = (field: string): 'dimension' | 'timeDimension' | 'measure' => {\n if (!availableFields) return 'dimension'\n if (availableFields.measures.includes(field)) return 'measure'\n if (availableFields.timeDimensions.includes(field)) return 'timeDimension'\n return 'dimension'\n }\n\n const getFieldStyling = (field: string) => {\n const fieldType = getFieldType(field)\n\n switch (fieldType) {\n case 'measure':\n return {\n IconComponent: MeasureIcon,\n baseClasses: 'bg-dc-measure text-dc-measure border border-dc-measure',\n hoverClasses: 'hover:opacity-80'\n }\n case 'timeDimension':\n return {\n IconComponent: TimeDimensionIcon,\n baseClasses: 'bg-dc-time-dimension text-dc-time-dimension border border-dc-time-dimension',\n hoverClasses: 'hover:opacity-80'\n }\n default:\n return {\n IconComponent: DimensionIcon,\n baseClasses: 'bg-dc-dimension text-dc-dimension border border-dc-dimension',\n hoverClasses: 'hover:opacity-80'\n }\n }\n }\n\n // Drag and drop handlers\n const handleDragStart = (e: React.DragEvent<HTMLDivElement>, field: string, fromAxis: string, fromIndex?: number) => {\n e.dataTransfer.setData('text/plain', JSON.stringify({ field, fromAxis, fromIndex }))\n \n // Just track the dragged item - don't remove it yet\n setDraggedItem({ field, fromAxis, fromIndex })\n }\n\n const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n }\n\n const handleDragEnd = () => {\n // Just clear the dragged item tracking - no need to restore since we didn't remove it\n setDraggedItem(null)\n }\n\n const handleDrop = (e: React.DragEvent<HTMLDivElement>, toAxis: string) => {\n e.preventDefault()\n const data = JSON.parse(e.dataTransfer.getData('text/plain'))\n const { field, fromAxis } = data\n \n const newConfig = { ...chartConfig }\n \n // Remove from old location if moving between axes\n if (fromAxis !== 'available' && fromAxis !== toAxis) {\n const fromValue = newConfig[fromAxis as keyof ChartAxisConfig]\n if (Array.isArray(fromValue)) {\n const filteredValue = fromValue.filter(f => f !== field)\n if (filteredValue.length === 0) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n } else {\n newConfig[fromAxis as keyof ChartAxisConfig] = filteredValue as any\n }\n } else if (fromValue === field) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n }\n }\n \n // Add to new location\n const toValue = newConfig[toAxis as keyof ChartAxisConfig]\n const dropZoneConfig = chartTypeConfig.dropZones.find(dz => dz.key === toAxis)\n \n if (dropZoneConfig?.maxItems === 1) {\n // Single field - always store as string\n newConfig[toAxis as keyof ChartAxisConfig] = field as any\n } else {\n // Multiple fields - always store as array\n if (Array.isArray(toValue)) {\n if (!toValue.includes(field)) {\n newConfig[toAxis as keyof ChartAxisConfig] = [...toValue, field] as any\n }\n } else {\n newConfig[toAxis as keyof ChartAxisConfig] = [field] as any\n }\n }\n \n // Clear the dragged item tracking\n setDraggedItem(null)\n onChartConfigChange(newConfig)\n }\n\n const handleRemoveFromAxis = (field: string, fromAxis: string) => {\n const newConfig = { ...chartConfig }\n const value = newConfig[fromAxis as keyof ChartAxisConfig]\n \n if (Array.isArray(value)) {\n const filteredValue = value.filter(f => f !== field)\n if (filteredValue.length === 0) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n } else {\n newConfig[fromAxis as keyof ChartAxisConfig] = filteredValue as any\n }\n } else if (value === field) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n }\n \n onChartConfigChange(newConfig)\n }\n\n const handleReorder = (fromIndex: number, toIndex: number, axisKey: string) => {\n const newConfig = { ...chartConfig }\n const value = newConfig[axisKey as keyof ChartAxisConfig]\n \n // Only reorder if we have an array with multiple items\n if (Array.isArray(value) && value.length > 1 && fromIndex !== toIndex) {\n const newArray = [...value]\n const [movedItem] = newArray.splice(fromIndex, 1)\n newArray.splice(toIndex, 0, movedItem)\n newConfig[axisKey as keyof ChartAxisConfig] = newArray as any\n \n // Clear the dragged item tracking\n setDraggedItem(null)\n onChartConfigChange(newConfig)\n }\n }\n\n // Get unassigned fields\n const getUnassignedFields = () => {\n if (!availableFields) return { dimensions: [], timeDimensions: [], measures: [] }\n \n const assignedFields = new Set<string>()\n chartTypeConfig.dropZones.forEach(dz => {\n getFieldsForDropZone(dz.key).forEach(field => assignedFields.add(field))\n })\n \n // Exclude the currently dragged field only if it's being dragged FROM a configured axis\n // (not from available fields, where it should remain visible)\n if (draggedItem && draggedItem.fromAxis !== 'available') {\n assignedFields.add(draggedItem.field)\n }\n \n return {\n dimensions: availableFields.dimensions.filter(f => !assignedFields.has(f)),\n timeDimensions: availableFields.timeDimensions.filter(f => !assignedFields.has(f)),\n measures: availableFields.measures.filter(f => !assignedFields.has(f))\n }\n }\n\n const unassignedFields = getUnassignedFields()\n\n\n return (\n <div>\n {/* Available Fields - Hidden for skipQuery charts */}\n {!shouldSkipQuery && availableFields && (\n <div className=\"mb-4\">\n <h4 className=\"text-xs font-semibold text-dc-text-secondary mb-2\">Available Fields</h4>\n <div className=\"border border-dc-border rounded-lg p-2 bg-dc-surface-secondary\">\n {(unassignedFields.dimensions.length > 0 ||\n unassignedFields.timeDimensions.length > 0 ||\n unassignedFields.measures.length > 0) ? (\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-2 sm:gap-2 gap-y-4 sm:gap-y-2\">\n {/* Dimensions Column */}\n <div className=\"pb-2 sm:pb-0\">\n <div className=\"text-xs text-dc-text-secondary mb-2 sm:mb-1 flex items-center\">\n <DimensionIcon className=\"w-3 h-3 mr-1 text-dc-text-muted\" />\n Dimensions\n </div>\n <div className=\"space-y-1\">\n {unassignedFields.dimensions.map(dim => {\n const isBeingDragged = draggedItem && draggedItem.field === dim && draggedItem.fromAxis === 'available'\n return (\n <div\n key={dim}\n draggable\n onDragStart={(e) => handleDragStart(e, dim, 'available')}\n onDragEnd={handleDragEnd}\n className={`bg-dc-dimension text-dc-dimension border border-dc-dimension hover:opacity-80 rounded-sm text-xs cursor-move px-3 py-2 sm:px-2 sm:py-1 truncate ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n title={dim}\n >\n {dim}\n </div>\n )\n })}\n {unassignedFields.dimensions.length === 0 && (\n <div className=\"text-xs text-dc-text-muted italic\">None</div>\n )}\n </div>\n </div>\n \n {/* Time Dimensions Column */}\n <div className=\"pb-2 sm:pb-0\">\n <div className=\"text-xs text-dc-text-secondary mb-2 sm:mb-1 flex items-center\">\n <TimeDimensionIcon className=\"w-3 h-3 mr-1 text-dc-text-muted\" />\n Time Dimensions\n </div>\n <div className=\"space-y-1\">\n {unassignedFields.timeDimensions.map(dim => {\n const isBeingDragged = draggedItem && draggedItem.field === dim && draggedItem.fromAxis === 'available'\n return (\n <div\n key={dim}\n draggable\n onDragStart={(e) => handleDragStart(e, dim, 'available')}\n onDragEnd={handleDragEnd}\n className={`bg-dc-time-dimension text-dc-time-dimension border border-dc-time-dimension hover:opacity-80 rounded-sm text-xs cursor-move px-3 py-2 sm:px-2 sm:py-1 truncate ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n title={dim}\n >\n {dim}\n </div>\n )\n })}\n {unassignedFields.timeDimensions.length === 0 && (\n <div className=\"text-xs text-dc-text-muted italic\">None</div>\n )}\n </div>\n </div>\n \n {/* Measures Column */}\n <div className=\"pb-2 sm:pb-0\">\n <div className=\"text-xs text-dc-text-secondary mb-2 sm:mb-1 flex items-center\">\n <MeasureIcon className=\"w-3 h-3 mr-1 text-dc-text-muted\" />\n Measures\n </div>\n <div className=\"space-y-1\">\n {unassignedFields.measures.map(measure => {\n const isBeingDragged = draggedItem && draggedItem.field === measure && draggedItem.fromAxis === 'available'\n return (\n <div\n key={measure}\n draggable\n onDragStart={(e) => handleDragStart(e, measure, 'available')}\n onDragEnd={handleDragEnd}\n className={`bg-dc-measure text-dc-measure border border-dc-measure hover:opacity-80 rounded-sm text-xs cursor-move px-3 py-2 sm:px-2 sm:py-1 truncate ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n title={measure}\n >\n {measure}\n </div>\n )\n })}\n {unassignedFields.measures.length === 0 && (\n <div className=\"text-xs text-dc-text-muted italic\">None</div>\n )}\n </div>\n </div>\n </div>\n ) : (\n <div className=\"text-xs text-dc-text-muted text-center py-2\">\n All fields have been assigned\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Chart Axis Configuration - Dynamic Drop Zones, Hidden for skipQuery charts */}\n {!shouldSkipQuery && (\n <div className=\"mb-4\">\n <h4 className=\"text-xs font-semibold text-dc-text-secondary mb-2\">Chart Configuration</h4>\n <div className=\"space-y-1\">\n {chartTypeConfig.dropZones.map(dropZone => (\n <AxisDropZone\n key={dropZone.key}\n config={dropZone}\n fields={getFieldsForDropZone(dropZone.key)}\n onDrop={handleDrop}\n onRemove={handleRemoveFromAxis}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragOver={handleDragOver}\n getFieldStyling={getFieldStyling}\n onReorder={handleReorder}\n draggedItem={draggedItem}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Display Options */}\n {((chartTypeConfig.displayOptions && chartTypeConfig.displayOptions.length > 0) ||\n (chartTypeConfig.displayOptionsConfig && chartTypeConfig.displayOptionsConfig.length > 0)) && (\n <div className=\"mb-4\">\n <h4 className=\"text-xs font-semibold text-dc-text-secondary mb-2\">Display Options</h4>\n <div className=\"space-y-2\">\n {/* Backward compatibility: Simple boolean display options */}\n {chartTypeConfig.displayOptions?.includes('showLegend') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.showLegend ?? true}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n showLegend: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-blue-500\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Show Legend</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('showGrid') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.showGrid ?? true}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n showGrid: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-blue-500\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Show Grid</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('showTooltip') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.showTooltip ?? true}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n showTooltip: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-blue-500\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Show Tooltip</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('stacked') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.stacked ?? false}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n stacked: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-blue-500\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Stacked</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('hideHeader') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.hideHeader ?? false}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n hideHeader: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-blue-500\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Hide Header</span>\n </label>\n )}\n\n {/* New structured display options */}\n {chartTypeConfig.displayOptionsConfig?.map((option) => (\n <div key={option.key} className=\"space-y-1\">\n {option.type === 'boolean' && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? false}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-blue-500\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">{option.label}</span>\n </label>\n )}\n\n {option.type === 'string' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">\n {option.label}\n {option.key === 'content' && (\n <span className=\"text-xs text-dc-text-muted ml-1\">(only headers, lists and links)</span>\n )}\n </label>\n {option.key === 'content' ? (\n <textarea\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? ''}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n placeholder={option.placeholder}\n rows={8}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-blue-500 focus:border-blue-500 font-mono resize-y bg-dc-surface text-dc-text\"\n />\n ) : (\n <input\n type=\"text\"\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? ''}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n placeholder={option.placeholder}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-blue-500 focus:border-blue-500 bg-dc-surface text-dc-text\"\n />\n )}\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'paletteColor' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <div className=\"flex flex-wrap gap-2\">\n {colorPalette?.colors.map((color, index) => {\n const isSelected = (displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? 0) === index\n return (\n <button\n key={index}\n type=\"button\"\n onClick={() => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: index\n })}\n className={`w-8 h-8 rounded border-2 transition-all duration-200 hover:scale-110 focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:ring-offset-1 ${\n isSelected\n ? 'ring-2 ring-offset-1 scale-110'\n : 'hover:border-dc-text-muted'\n }`}\n style={{\n backgroundColor: color,\n borderColor: isSelected ? 'var(--dc-primary)' : 'var(--dc-border)'\n }}\n title={`Color ${index + 1}: ${color}`}\n />\n )\n }) || [\n // Fallback if no palette available\n <button\n key={0}\n type=\"button\"\n onClick={() => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: 0\n })}\n className=\"w-8 h-8 rounded-sm border-2 ring-2 ring-offset-1\"\n style={{\n backgroundColor: '#8884d8',\n borderColor: 'var(--dc-primary)',\n boxShadow: '0 0 0 2px var(--dc-primary)'\n }}\n title=\"Default Color\"\n />\n ]}\n </div>\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'number' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <input\n type=\"number\"\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? 0}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value === '' ? undefined : Number(e.target.value)\n })}\n placeholder={option.placeholder}\n min={option.min}\n max={option.max}\n step={option.step}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-blue-500 focus:border-blue-500 bg-dc-surface text-dc-text\"\n />\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'select' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <select\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? ''}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-blue-500 focus:border-blue-500 bg-dc-surface text-dc-text\"\n >\n {option.options?.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'color' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"color\"\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? '#8884d8'}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n className=\"w-12 h-8 border border-dc-border rounded-sm cursor-pointer\"\n />\n <input\n type=\"text\"\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? '#8884d8'}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n placeholder={option.placeholder || '#8884d8'}\n className=\"flex-1 px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-blue-500 focus:border-blue-500 bg-dc-surface text-dc-text\"\n />\n </div>\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n )\n}","/**\n * ResultsPanel Component\n *\n * Displays query execution results, loading states, and errors.\n * Supports both table and chart visualization with configurable chart types.\n */\n\nimport React, { useState } from 'react'\nimport { LazyChart, isValidChartType } from '../../charts/ChartLoader'\nimport ChartTypeSelector from '../ChartTypeSelector'\nimport ChartConfigPanel from '../ChartConfigPanel'\nimport type { ResultsPanelProps } from './types'\nimport { getIcon } from '../../icons'\n\nconst ResultsPanel: React.FC<ResultsPanelProps> = ({\n executionStatus,\n executionResults,\n executionError,\n query,\n displayLimit = 10,\n onDisplayLimitChange,\n totalRowCount,\n totalRowCountStatus,\n // Chart visualization props\n chartType = 'table',\n chartConfig = {},\n displayConfig = {},\n availableFields,\n onChartTypeChange,\n onChartConfigChange,\n onDisplayConfigChange,\n // View state props\n activeView: activeViewProp = 'table',\n onActiveViewChange\n}) => {\n // Get icons\n const ErrorIcon = getIcon('error')\n const TimeIcon = getIcon('timeDimension')\n const SuccessIcon = getIcon('success')\n const WarningIcon = getIcon('warning')\n const ChevronDownIcon = getIcon('chevronDown')\n const ChevronUpIcon = getIcon('chevronUp')\n const TableIcon = getIcon('table')\n const MeasureIcon = getIcon('measure')\n const AdjustmentsIcon = getIcon('adjustments')\n\n // Use prop if provided, otherwise use local state for backwards compatibility\n const [localActiveView, setLocalActiveView] = useState<'table' | 'chart'>('table')\n const activeView = onActiveViewChange ? activeViewProp : localActiveView\n const setActiveView = onActiveViewChange || setLocalActiveView\n\n // Local state for config panel visibility\n const [showChartConfig, setShowChartConfig] = useState(false)\n\n const LoadingState = () => (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 mx-auto mb-4\" style={{ borderBottomColor: 'var(--dc-primary)' }}></div>\n <div className=\"text-sm font-semibold text-dc-text-secondary mb-1\">Executing Query...</div>\n <div className=\"text-xs text-dc-text-muted\">Running your query against the cube API</div>\n </div>\n </div>\n )\n\n const ErrorState = () => (\n <div className=\"h-full flex items-center justify-center p-4\">\n <div className=\"text-center max-w-md\">\n <ErrorIcon className=\"w-12 h-12 mx-auto text-red-500 mb-4\" />\n <div className=\"text-sm font-semibold text-dc-text mb-2\">Query Execution Failed</div>\n <div className=\"text-sm text-dc-text-secondary mb-4\">\n There was an error executing your query. Please check the query and try again.\n </div>\n {executionError && (\n <div className=\"bg-red-50 border border-red-200 rounded-lg p-3 text-left\">\n <div className=\"text-xs font-mono text-red-800 break-words\">\n {executionError}\n </div>\n </div>\n )}\n </div>\n </div>\n )\n\n const EmptyState = () => (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center mb-16\">\n <TimeIcon className=\"w-12 h-12 mx-auto text-dc-text-muted mb-3\" />\n <div className=\"text-sm font-semibold text-dc-text-secondary mb-1\">No Results Yet</div>\n <div className=\"text-xs text-dc-text-muted\">Build and run a query to see results here</div>\n </div>\n </div>\n )\n\n // Render the appropriate chart component using lazy loading\n const renderChart = () => {\n if (!executionResults || executionResults.length === 0) {\n return (\n <div className=\"flex items-center justify-center h-full text-dc-text-muted\">\n <div className=\"text-center\">\n <MeasureIcon className=\"w-12 h-12 mx-auto mb-3 opacity-50\" />\n <div className=\"text-sm font-semibold mb-1\">No data to display</div>\n <div className=\"text-xs\">Run a query to see chart visualization</div>\n </div>\n </div>\n )\n }\n\n const chartHeight = 400\n const data = executionResults\n\n try {\n // Check if it's a valid chart type for lazy loading\n if (!isValidChartType(chartType)) {\n return (\n <div className=\"flex items-center justify-center h-full text-dc-text-muted\">\n <div className=\"text-center\">\n <WarningIcon className=\"w-12 h-12 mx-auto mb-3 opacity-50\" />\n <div className=\"text-sm font-semibold mb-1\">Unsupported chart type</div>\n <div className=\"text-xs\">{chartType}</div>\n </div>\n </div>\n )\n }\n\n // For markdown chart, use empty data array\n const chartData = chartType === 'markdown' ? [] : data\n\n return (\n <LazyChart\n chartType={chartType}\n data={chartData}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n queryObject={query}\n height={chartHeight}\n fallback={\n <div className=\"flex items-center justify-center\" style={{ height: chartHeight }}>\n <div className=\"animate-pulse bg-dc-surface-secondary rounded w-full h-full\" />\n </div>\n }\n />\n )\n } catch (error) {\n console.error('Chart rendering error:', error)\n return (\n <div className=\"flex items-center justify-center h-full text-dc-text-muted p-4\">\n <div className=\"text-center\">\n <ErrorIcon className=\"w-12 h-12 mx-auto mb-3 text-red-400\" />\n <div className=\"text-sm font-semibold mb-1\">Unable to render chart</div>\n <div className=\"text-xs text-dc-text-secondary\">{error instanceof Error ? error.message : 'Unknown error'}</div>\n </div>\n </div>\n )\n }\n }\n\n const SuccessState = () => {\n if (!executionResults || executionResults.length === 0) {\n return (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center\">\n <SuccessIcon className=\"w-12 h-12 mx-auto text-green-500 mb-3\" />\n <div className=\"text-sm font-semibold text-gray-700 mb-1\">Query Successful</div>\n <div className=\"text-xs text-gray-500\">No data returned from the query</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"h-full flex flex-col\">\n {/* Results Header with Chart Controls */}\n <div className=\"p-4 border-b border-dc-border bg-dc-surface-secondary\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n {/* Left side: Status and row count */}\n <div className=\"flex items-center\">\n <SuccessIcon className=\"w-5 h-5 text-green-500 mr-2\" />\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-semibold text-dc-text-secondary\">\n Query Results ({executionResults.length} row{executionResults.length !== 1 ? 's' : ''} shown)\n </span>\n {totalRowCountStatus === 'success' && totalRowCount !== null && totalRowCount !== undefined && (\n <span className=\"text-xs text-dc-text-muted\">\n Total: {totalRowCount.toLocaleString()} row{totalRowCount !== 1 ? 's' : ''}\n </span>\n )}\n {totalRowCountStatus === 'loading' && (\n <span className=\"text-xs text-dc-text-muted\">\n Counting total rows...\n </span>\n )}\n </div>\n </div>\n\n {/* Right side: View tabs and display limit */}\n <div className=\"flex items-center gap-3 flex-wrap\">\n {/* View Toggle Tabs */}\n <div className=\"flex items-center bg-dc-surface border border-dc-border rounded-md overflow-hidden\">\n <button\n onClick={() => setActiveView('table')}\n className={`flex items-center gap-1 px-3 py-1.5 text-xs font-medium transition-colors ${\n activeView === 'table'\n ? 'bg-dc-primary text-white'\n : 'text-dc-text-secondary hover:bg-dc-surface-hover'\n }`}\n >\n <TableIcon className=\"w-3.5 h-3.5\" />\n Table\n </button>\n <button\n onClick={() => setActiveView('chart')}\n className={`flex items-center gap-1 px-3 py-1.5 text-xs font-medium transition-colors ${\n activeView === 'chart'\n ? 'bg-dc-primary text-white'\n : 'text-dc-text-secondary hover:bg-dc-surface-hover'\n }`}\n >\n <MeasureIcon className=\"w-3.5 h-3.5\" />\n Chart\n </button>\n </div>\n\n {/* Display Limit (only show for table view) */}\n {activeView === 'table' && onDisplayLimitChange && (\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs text-dc-text-secondary\">Show:</label>\n <select\n value={displayLimit}\n onChange={(e) => onDisplayLimitChange(Number(e.target.value))}\n className=\"text-xs border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:outline-hidden focus:ring-1 focus:ring-blue-500\"\n >\n <option value={10}>10 rows</option>\n <option value={50}>50 rows</option>\n <option value={100}>100 rows</option>\n </select>\n </div>\n )}\n </div>\n </div>\n\n {/* Chart Controls Row (only show when chart view is active) */}\n {activeView === 'chart' && onChartTypeChange && (\n <div className=\"mt-3 pt-3 border-t border-dc-border flex items-center justify-between gap-3 flex-wrap\">\n {/* Chart Type Selector */}\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs text-dc-text-secondary whitespace-nowrap\">Chart Type:</label>\n <ChartTypeSelector\n selectedType={chartType}\n onTypeChange={onChartTypeChange}\n />\n </div>\n\n {/* Configure Chart Button (only show for non-table chart types) */}\n {chartType !== 'table' && onChartConfigChange && onDisplayConfigChange && (\n <button\n onClick={() => setShowChartConfig(!showChartConfig)}\n className={`flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md transition-colors ${\n showChartConfig\n ? 'bg-dc-primary text-white'\n : 'text-dc-text-secondary bg-dc-surface hover:bg-dc-surface-hover border border-dc-border'\n }`}\n >\n <AdjustmentsIcon className=\"w-4 h-4\" />\n {showChartConfig ? 'Hide Config' : 'Configure'}\n {showChartConfig ? (\n <ChevronUpIcon className=\"w-3.5 h-3.5\" />\n ) : (\n <ChevronDownIcon className=\"w-3.5 h-3.5\" />\n )}\n </button>\n )}\n </div>\n )}\n\n {/* Performance Warning */}\n {totalRowCountStatus === 'success' && totalRowCount !== null && totalRowCount !== undefined && totalRowCount > 500 && (\n <div className=\"mt-3 bg-yellow-50 border border-yellow-200 rounded-lg p-3 flex items-start\">\n <WarningIcon className=\"w-5 h-5 text-yellow-600 mr-2 shrink-0 mt-0.5\" />\n <div className=\"text-sm text-yellow-800\">\n <span className=\"font-semibold\">Performance Warning:</span> This query returns {totalRowCount.toLocaleString()} rows,\n which may impact performance. Consider adding filters to reduce the dataset size.\n </div>\n </div>\n )}\n </div>\n\n {/* Collapsible Chart Config Panel (only when chart view is active) */}\n {activeView === 'chart' && showChartConfig && chartType !== 'table' && onChartConfigChange && onDisplayConfigChange && (\n <div className=\"border-b border-dc-border bg-dc-surface-tertiary p-4\">\n <ChartConfigPanel\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n availableFields={availableFields || null}\n onChartConfigChange={onChartConfigChange}\n onDisplayConfigChange={onDisplayConfigChange}\n />\n </div>\n )}\n\n {/* Results Content - Table or Chart based on active view */}\n <div className=\"flex-1 min-h-0\">\n {activeView === 'table' ? (\n <LazyChart\n chartType=\"table\"\n data={executionResults}\n height=\"100%\"\n fallback={\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"animate-pulse bg-dc-surface-secondary rounded w-full h-full\" />\n </div>\n }\n />\n ) : (\n <div className=\"p-4 h-full overflow-auto\">\n {renderChart()}\n </div>\n )}\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"flex-1 flex flex-col bg-dc-surface border border-dc-border rounded-lg min-h-0\">\n {/* Header */}\n <div className=\"px-4 py-3 border-b border-dc-border bg-dc-surface-secondary\">\n <h3 className=\"text-sm font-semibold text-dc-text\">Query Results</h3>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 min-h-0\">\n {executionStatus === 'loading' && <LoadingState />}\n {executionStatus === 'error' && <ErrorState />}\n {executionStatus === 'success' && <SuccessState />}\n {executionStatus === 'idle' && <EmptyState />}\n </div>\n </div>\n )\n}\n\nexport default ResultsPanel\n","/**\n * SetupPanel Component\n * \n * Provides configuration options for API endpoint and authentication.\n * Only shown in standalone QueryBuilder mode, not in modal contexts.\n */\n\nimport React, { useState } from 'react'\nimport { getIcon } from '../../icons'\nimport type { ApiConfig } from './types'\n\nconst ChevronDownIcon = getIcon('chevronDown')\nconst ChevronUpIcon = getIcon('chevronUp')\nconst SettingsIcon = getIcon('settings')\nconst RefreshIcon = getIcon('refresh')\n\ninterface SetupPanelProps {\n isOpen: boolean\n onToggle: () => void\n config: ApiConfig\n onConfigChange: (config: ApiConfig) => void\n onReset: () => void\n}\n\nconst SetupPanel: React.FC<SetupPanelProps> = ({\n isOpen,\n onToggle,\n config,\n onConfigChange,\n onReset\n}) => {\n const [localConfig, setLocalConfig] = useState<ApiConfig>(config)\n\n const handleApply = () => {\n onConfigChange(localConfig)\n }\n\n const handleReset = () => {\n const defaultConfig = {\n baseApiUrl: '/cubejs-api/v1',\n apiToken: ''\n }\n setLocalConfig(defaultConfig)\n onConfigChange(defaultConfig)\n onReset()\n }\n\n const handleInputChange = (field: keyof ApiConfig, value: string) => {\n setLocalConfig(prev => ({\n ...prev,\n [field]: value\n }))\n }\n\n const hasChanges = JSON.stringify(localConfig) !== JSON.stringify(config)\n const isUsingDefaults = config.baseApiUrl === '/cubejs-api/v1' && config.apiToken === ''\n\n return (\n <div className=\"bg-dc-surface border border-dc-border rounded-lg mb-4\">\n {/* Header */}\n <button\n onClick={onToggle}\n className=\"w-full px-4 py-3 flex items-center justify-between text-left bg-dc-surface-secondary rounded-t-lg hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n >\n <div className=\"flex items-center space-x-2\">\n <SettingsIcon className=\"w-5 h-5 text-dc-text-secondary\" />\n <h3 className=\"text-sm font-semibold text-dc-text\">API Configuration</h3>\n {!isUsingDefaults && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-dc-info text-dc-text\">\n Custom\n </span>\n )}\n </div>\n {isOpen ? (\n <ChevronUpIcon className=\"w-4 h-4 text-dc-text-muted\" />\n ) : (\n <ChevronDownIcon className=\"w-4 h-4 text-dc-text-muted\" />\n )}\n </button>\n\n {/* Expandable Content */}\n {isOpen && (\n <div className=\"p-4 border-t border-dc-border\">\n <div className=\"space-y-4\">\n {/* Base API URL */}\n <div>\n <label className=\"block text-sm font-medium text-dc-text-secondary mb-1\">\n Base API URL\n </label>\n <input\n type=\"text\"\n value={localConfig.baseApiUrl}\n onChange={(e) => handleInputChange('baseApiUrl', e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm\"\n placeholder=\"/cubejs-api/v1\"\n />\n <p className=\"text-xs text-dc-text-muted mt-1\">\n The base URL for the Cube.js API endpoints\n </p>\n </div>\n\n {/* API Token */}\n <div>\n <label className=\"block text-sm font-medium text-dc-text-secondary mb-1\">\n API Token\n </label>\n <input\n type=\"password\"\n value={localConfig.apiToken}\n onChange={(e) => handleInputChange('apiToken', e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm\"\n placeholder=\"Leave empty for no authentication\"\n />\n <p className=\"text-xs text-dc-text-muted mt-1\">\n Optional bearer token for API authentication\n </p>\n </div>\n\n {/* Status Indicator */}\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-md p-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h4 className=\"text-xs font-medium text-dc-text-secondary\">Current Configuration</h4>\n <p className=\"text-xs text-dc-text-secondary mt-1\">\n URL: <span className=\"font-mono\">{config.baseApiUrl}</span>\n </p>\n <p className=\"text-xs text-dc-text-secondary\">\n Token: {config.apiToken ? (\n <span className=\"text-green-600\">Configured</span>\n ) : (\n <span className=\"text-dc-text-muted\">Not set</span>\n )}\n </p>\n </div>\n {!isUsingDefaults && (\n <button\n onClick={handleReset}\n className=\"flex items-center space-x-1 px-2 py-1 text-xs font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-sm hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n title=\"Reset to defaults\"\n >\n <RefreshIcon className=\"w-3 h-3\" />\n <span>Reset</span>\n </button>\n )}\n </div>\n </div>\n\n {/* Action Buttons */}\n {hasChanges && (\n <div className=\"flex justify-end space-x-2 pt-2 border-t border-dc-border\">\n <button\n onClick={() => setLocalConfig(config)}\n className=\"px-3 py-1.5 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n >\n Cancel\n </button>\n <button\n onClick={handleApply}\n className=\"px-3 py-1.5 text-sm font-medium text-white border border-transparent rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500\"\n style={{ backgroundColor: 'var(--dc-primary)' }}\n >\n Apply Changes\n </button>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport default SetupPanel","/**\n * Constants for AI Assistant\n */\n\nexport const AI_PROXY_BASE_URL = '/api/ai'\nexport const GEMINI_MODEL = 'gemini-2.0-flash'\n\nexport const DEFAULT_SYSTEM_PROMPT_TEMPLATE = `You are a SQL query builder assistant for a semantic layer using Cube.js format.\n\nAvailable cube schema (JSON):\n{CUBE_SCHEMA}\n\nA valid Cube schema can contain things such as below (this is only an example of possible options):\n\n{\n \"measures\": [\"stories.count\"],\n \"dimensions\": [\"stories.category\"],\n \"filters\": [\n {\n \"member\": \"stories.isDraft\",\n \"operator\": \"equals\",\n \"values\": [\"No\"]\n }\n ],\n \"timeDimensions\": [\n {\n \"dimension\": \"stories.time\",\n \"dateRange\": [\"2015-01-01\", \"2015-12-31\"],\n \"granularity\": \"month\"\n }\n ],\n \"limit\": 100,\n \"offset\": 50,\n \"order\": {\n \"stories.time\": \"asc\",\n \"stories.count\": \"desc\"\n }\n}\n\nUser request: {USER_PROMPT}\n\nCRITICAL: You MUST only use field names that exist in the schema above. Do NOT create or invent field names.\n\nGenerate a JSON query object with this structure:\n{\n \"measures\": [\"CubeName.measureName\"],\n \"dimensions\": [\"CubeName.dimensionName\"], \n \"timeDimensions\": [{\n \"dimension\": \"CubeName.timeDimensionName\",\n \"granularity\": \"hour|day|week|month|quarter|year\",\n \"dateRange\": \"last 30 days\"\n }],\n \"filters\": [{\n \"member\": \"CubeName.fieldName\",\n \"operator\": \"equals|contains|gt|gte|lt|lte|inDateRange\",\n \"values\": [\"value1\", \"value2\"]\n }]\n}\n\nRules:\n1. Only use cube names, measure names, and dimension names from the schema\n2. All field references must be in \"CubeName.fieldName\" format\n3. Verify every field exists in the provided schema before using it\n\nRespond with only the JSON query object, no explanation, no markdown formatting, no code blocks, no backtick wrapper.`\n\nexport const AI_STORAGE_KEY = 'drizzle-cube-ai-config'\n\nexport const DEFAULT_AI_CONFIG = {\n provider: 'gemini' as const,\n apiKey: ''\n}","/**\n * Utility functions for AI Assistant\n */\n\nimport type { \n AIQueryRequest,\n AIQueryResponse,\n AIConfig\n} from './types'\nimport { \n AI_STORAGE_KEY,\n DEFAULT_AI_CONFIG\n} from './constants'\n\n/**\n * Send a user prompt to AI proxy (server builds system prompt)\n */\nexport async function sendGeminiMessage(\n apiKey: string,\n userPrompt: string,\n endpoint: string = '/api/ai/generate'\n): Promise<AIQueryResponse> {\n const requestBody: AIQueryRequest = {\n text: userPrompt // Send only the user's prompt, server handles system prompt\n }\n\n // Only add API key header if provided (allow empty string for server key)\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json'\n }\n \n if (apiKey && apiKey.trim()) {\n headers['X-API-Key'] = apiKey\n }\n\n console.log('🤖 Client: Sending user prompt to AI proxy')\n console.log(' URL:', endpoint)\n console.log(' Headers:', headers)\n console.log(' User prompt length:', userPrompt.length)\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody)\n })\n\n console.log('📥 Client: Proxy response')\n console.log(' Status:', response.status)\n console.log(' Status Text:', response.statusText)\n\n if (!response.ok) {\n let errorMessage = `Failed to generate content: ${response.status} ${response.statusText}`\n \n try {\n // Try to parse JSON error response first\n const errorData = await response.json()\n console.error('❌ Client: Proxy error:', errorData)\n \n // Handle rate limit errors specially\n if (response.status === 429 && errorData.error === 'Daily quota exceeded') {\n throw new Error(\n `${errorData.message}\\n\\n${errorData.suggestion || 'Add your own Gemini API key for unlimited access.'}`\n )\n }\n \n // Handle other structured errors\n if (errorData.error) {\n errorMessage = errorData.message || errorData.error\n if (errorData.suggestion) {\n errorMessage += `\\n\\n💡 ${errorData.suggestion}`\n }\n }\n } catch (parseError) {\n // Fallback to text if JSON parsing fails\n try {\n const errorText = await response.text()\n console.error('❌ Client: Proxy text error:', errorText)\n errorMessage = errorText || errorMessage\n } catch (textError) {\n console.error('❌ Client: Could not parse error response')\n }\n }\n \n throw new Error(errorMessage)\n }\n\n const data = await response.json()\n console.log('✅ Client: Successfully generated content')\n return data\n}\n\n// Removed: buildSystemPrompt and formatCubeSchemaForPrompt \n// These functions are now handled server-side for better security\n\n/**\n * Save AI configuration to localStorage\n */\nexport function saveAIConfig(config: AIConfig): void {\n try {\n localStorage.setItem(AI_STORAGE_KEY, JSON.stringify(config))\n } catch (error) {\n console.warn('Failed to save AI config to localStorage:', error)\n }\n}\n\n/**\n * Load AI configuration from localStorage\n */\nexport function loadAIConfig(): AIConfig {\n try {\n const saved = localStorage.getItem(AI_STORAGE_KEY)\n if (saved) {\n const parsed = JSON.parse(saved)\n return { ...DEFAULT_AI_CONFIG, ...parsed }\n }\n } catch (error) {\n console.warn('Failed to load AI config from localStorage:', error)\n }\n return { ...DEFAULT_AI_CONFIG }\n}\n\n/**\n * Extract query text from simplified AI response and clean up formatting\n */\nexport function extractTextFromResponse(response: AIQueryResponse): string {\n const rawText = response.query || ''\n\n // Clean up common markdown formatting that might appear\n return rawText\n .replace(/```json\\s*/g, '') // Remove ```json\n .replace(/```\\s*/g, '') // Remove ```\n .replace(/^\\s*```.*\\n/gm, '') // Remove any remaining code block markers\n .trim()\n}","/**\n * AI Assistant Modal Component\n * \n * Multi-step modal for AI-powered query generation\n * Step 1: API Key input\n * Step 2: Model selection \n * Step 3: Query input and response\n */\n\nimport React, { useState } from 'react'\nimport { getIcon } from '../../icons'\nimport Modal from '../Modal'\n\nconst ErrorIcon = getIcon('error')\nconst SuccessIcon = getIcon('success')\nconst SparklesIcon = getIcon('sparkles')\nimport type { AIAssistantState } from './types'\nimport {\n sendGeminiMessage,\n loadAIConfig,\n extractTextFromResponse\n} from './utils'\nimport { DEFAULT_SYSTEM_PROMPT_TEMPLATE } from './constants'\n\ninterface AIAssistantModalProps {\n isOpen: boolean\n onClose: () => void\n schema?: any\n onQueryLoad?: (query: any) => void\n aiEndpoint?: string\n}\n\nconst AIAssistantModal: React.FC<AIAssistantModalProps> = ({\n isOpen,\n onClose,\n onQueryLoad,\n aiEndpoint = '/api/ai'\n}) => {\n const [state, setState] = useState<AIAssistantState>(() => {\n const savedConfig = loadAIConfig()\n return {\n step: 'query', // Skip API key step and go straight to query\n apiKey: savedConfig.apiKey || '',\n systemPromptTemplate: DEFAULT_SYSTEM_PROMPT_TEMPLATE,\n userPrompt: '',\n isSubmitting: false,\n response: null,\n responseError: null,\n isValidating: false,\n validationResult: null,\n validationError: null\n }\n })\n\n\n const handleQuerySubmit = async (e?: React.FormEvent) => {\n e?.preventDefault()\n if (!state.userPrompt.trim()) return\n\n setState(prev => ({ \n ...prev, \n isSubmitting: true, \n response: null, \n responseError: null,\n validationResult: null,\n validationError: null,\n isValidating: false\n }))\n\n try {\n // Send only the user prompt - server will handle system prompt building\n const response = await sendGeminiMessage(\n state.apiKey,\n state.userPrompt,\n aiEndpoint\n )\n\n const responseText = extractTextFromResponse(response)\n setState(prev => ({ \n ...prev, \n isSubmitting: false, \n response: responseText \n }))\n \n // Automatically validate after successful generation\n setTimeout(() => {\n validateResponse(responseText)\n }, 500)\n } catch (error) {\n setState(prev => ({\n ...prev,\n isSubmitting: false,\n responseError: error instanceof Error ? error.message : 'Failed to process query'\n }))\n }\n }\n\n // Validate a specific response text (used for auto-validation)\n const validateResponse = async (responseText: string) => {\n if (!responseText) {\n console.log('AI Modal: No response text to validate')\n return\n }\n\n console.log('AI Modal: Starting validation with response:', responseText.substring(0, 100) + '...')\n \n setState(prev => ({\n ...prev,\n isValidating: true,\n validationResult: null,\n validationError: null\n }))\n\n try {\n const query = JSON.parse(responseText)\n console.log('AI Modal: Parsed query:', query)\n \n const response = await fetch('/cubejs-api/v1/load', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(query)\n })\n\n console.log('AI Modal: Validation response status:', response.status)\n\n if (response.ok) {\n console.log('AI Modal: Validation SUCCESS')\n setState(prev => ({\n ...prev,\n isValidating: false,\n validationResult: 'valid'\n }))\n } else {\n const errorData = await response.text()\n console.log('AI Modal: Validation FAILED:', errorData)\n setState(prev => ({\n ...prev,\n isValidating: false,\n validationResult: 'invalid',\n validationError: errorData || `HTTP ${response.status}: ${response.statusText}`\n }))\n }\n } catch (error) {\n console.log('AI Modal: Validation ERROR:', error)\n setState(prev => ({\n ...prev,\n isValidating: false,\n validationResult: 'invalid',\n validationError: error instanceof Error ? error.message : 'Failed to validate query'\n }))\n }\n }\n\n const handleValidate = async () => {\n if (!state.response) return\n await validateResponse(state.response)\n }\n\n const handleUseQuery = () => {\n if (!state.response || !onQueryLoad) return\n\n try {\n const query = JSON.parse(state.response)\n onQueryLoad(query)\n handleClose()\n } catch (error) {\n setState(prev => ({\n ...prev,\n validationError: 'Invalid JSON format'\n }))\n }\n }\n\n const handleClose = () => {\n setState(prev => ({\n ...prev,\n response: null,\n responseError: null,\n validationResult: null,\n validationError: null\n }))\n onClose()\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n handleQuerySubmit()\n }\n }\n\n\n\n const renderQueryStep = () => (\n <div className=\"flex flex-col space-y-4\">\n {/* Top: Config Panel - Full Width */}\n <div className=\"shrink-0 p-3 bg-dc-surface-secondary border border-dc-border rounded-md\">\n <div className=\"text-sm text-dc-text-muted\">\n Using: <span className=\"font-medium\">AI Query Generation</span>\n <span className=\"ml-2 px-2 py-1 bg-blue-100 text-blue-700 text-xs rounded-sm\">\n Server-provided AI (Rate Limited)\n </span>\n </div>\n </div>\n \n {/* Middle: Input/Output Row - Takes remaining space */}\n <div className=\"flex flex-col md:flex-row gap-6 flex-1 min-h-0\">\n {/* Left: Query Input */}\n <div className=\"w-full md:w-1/2 flex flex-col\">\n <label htmlFor=\"user-prompt\" className=\"block text-sm font-medium text-dc-text-secondary mb-2\">\n Describe your query in natural language\n </label>\n <textarea\n id=\"user-prompt\"\n value={state.userPrompt}\n onChange={(e) => setState(prev => ({ ...prev, userPrompt: e.target.value }))}\n onKeyDown={handleKeyDown}\n placeholder=\"e.g., Show me the total revenue by month for the last year (Press Enter to generate, Shift+Enter for new line)\"\n className=\"flex-1 w-full px-3 py-2 border border-dc-border rounded-md shadow-xs focus:outline-none focus:ring-blue-500 focus:border-blue-500 resize-none bg-dc-surface text-dc-text\"\n required\n />\n </div>\n \n {/* Right: Output Query */}\n <div className=\"w-full md:w-1/2 flex flex-col\">\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center space-x-2\">\n {state.response ? (\n <>\n <SuccessIcon className=\"w-5 h-5 text-green-500\" />\n <span className=\"text-sm font-medium text-green-700\">AI Generated Query</span>\n </>\n ) : (\n <span className=\"text-sm font-medium text-dc-text-muted\">Generated Query</span>\n )}\n </div>\n {state.response && (\n <button\n onClick={handleValidate}\n disabled={state.isValidating}\n className=\"text-xs text-blue-600 hover:text-blue-800 disabled:opacity-50\"\n title=\"Click to re-validate query\"\n >\n {state.isValidating ? 'Validating...' : 'Re-validate'}\n </button>\n )}\n </div>\n\n {state.response ? (\n <div className=\"flex-1 bg-green-50 border border-green-200 rounded-md p-3\">\n <pre className=\"text-sm text-dc-text whitespace-pre-wrap overflow-auto bg-dc-surface p-3 rounded-sm border h-full\">\n {state.response}\n </pre>\n </div>\n ) : (\n <div className=\"flex-1 flex items-center justify-center text-dc-text-muted border-2 border-dashed border-dc-border rounded-md p-8 min-h-64\">\n <div className=\"text-center\">\n <SparklesIcon className=\"w-12 h-12 mx-auto text-dc-text-muted\" />\n </div>\n </div>\n )}\n </div>\n </div>\n \n {/* Status Messages - Fixed height */}\n <div className=\"shrink-0\">\n {state.responseError && (\n <div className=\"flex items-start space-x-2 p-3 bg-red-50 border border-red-200 rounded-md\">\n <ErrorIcon className=\"w-5 h-5 text-red-500 mt-0.5 shrink-0\" />\n <div className=\"text-sm text-red-700\">{state.responseError}</div>\n </div>\n )}\n \n {state.isValidating && (\n <div className=\"flex items-start space-x-2 p-3 bg-blue-50 border border-blue-200 rounded-md\">\n <div className=\"animate-spin rounded-full h-5 w-5 border-b-2 border-blue-600 mt-0.5 shrink-0\"></div>\n <div className=\"text-sm text-blue-700\">Validating query...</div>\n </div>\n )}\n \n {state.validationResult === 'valid' && !state.isValidating && (\n <div className=\"flex items-start space-x-2 p-3 bg-green-50 border border-green-200 rounded-md\">\n <SuccessIcon className=\"w-5 h-5 text-green-500 mt-0.5 shrink-0\" />\n <div className=\"text-sm text-green-700\">Query is valid and ready to use!</div>\n </div>\n )}\n \n {state.validationResult === 'invalid' && !state.isValidating && (\n <div className=\"flex items-start space-x-2 p-3 bg-red-50 border border-red-200 rounded-md\">\n <ErrorIcon className=\"w-5 h-5 text-red-500 mt-0.5 shrink-0\" />\n <div className=\"text-sm text-red-700\">\n <div className=\"font-medium mb-1\">Query validation failed:</div>\n <div className=\"text-xs\">{state.validationError}</div>\n </div>\n </div>\n )}\n </div>\n \n {/* Bottom: Action Buttons - Right Aligned */}\n <div className=\"shrink-0 flex justify-end space-x-3 pt-3\">\n <button\n type=\"submit\"\n disabled={!state.userPrompt.trim() || state.isSubmitting}\n onClick={handleQuerySubmit}\n className=\"px-4 py-2 text-white text-sm rounded-md hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed flex items-center\"\n style={{\n backgroundColor: 'var(--dc-primary)'\n }}\n >\n {state.isSubmitting ? (\n <>\n <div className=\"animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2\"></div>\n Generating...\n </>\n ) : (\n <>\n <SparklesIcon className=\"w-4 h-4 mr-2\" />\n Generate\n </>\n )}\n </button>\n\n {/* Validation happens automatically after generation */}\n\n <button\n onClick={handleUseQuery}\n disabled={!state.response || !onQueryLoad}\n className=\"px-4 py-2 bg-green-600 text-white text-sm rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed flex items-center\"\n >\n <SuccessIcon className=\"w-4 h-4 mr-2\" />\n Use Query\n </button>\n </div>\n </div>\n )\n\n const getTitle = () => {\n return 'AI Assistant - Generate Query'\n }\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={getTitle()}\n size=\"fullscreen-mobile\"\n >\n {renderQueryStep()}\n </Modal>\n )\n}\n\nexport default AIAssistantModal","// Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>\n// This work is free. You can redistribute it and/or modify it\n// under the terms of the WTFPL, Version 2\n// For more information see LICENSE.txt or http://www.wtfpl.net/\n//\n// For more information, the home page:\n// http://pieroxy.net/blog/pages/lz-string/testing.html\n//\n// LZ-based compression algorithm, version 1.4.5\nvar LZString = (function() {\n\n// private property\nvar f = String.fromCharCode;\nvar keyStrBase64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\nvar keyStrUriSafe = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$\";\nvar baseReverseDic = {};\n\nfunction getBaseValue(alphabet, character) {\n if (!baseReverseDic[alphabet]) {\n baseReverseDic[alphabet] = {};\n for (var i=0 ; i<alphabet.length ; i++) {\n baseReverseDic[alphabet][alphabet.charAt(i)] = i;\n }\n }\n return baseReverseDic[alphabet][character];\n}\n\nvar LZString = {\n compressToBase64 : function (input) {\n if (input == null) return \"\";\n var res = LZString._compress(input, 6, function(a){return keyStrBase64.charAt(a);});\n switch (res.length % 4) { // To produce valid Base64\n default: // When could this happen ?\n case 0 : return res;\n case 1 : return res+\"===\";\n case 2 : return res+\"==\";\n case 3 : return res+\"=\";\n }\n },\n\n decompressFromBase64 : function (input) {\n if (input == null) return \"\";\n if (input == \"\") return null;\n return LZString._decompress(input.length, 32, function(index) { return getBaseValue(keyStrBase64, input.charAt(index)); });\n },\n\n compressToUTF16 : function (input) {\n if (input == null) return \"\";\n return LZString._compress(input, 15, function(a){return f(a+32);}) + \" \";\n },\n\n decompressFromUTF16: function (compressed) {\n if (compressed == null) return \"\";\n if (compressed == \"\") return null;\n return LZString._decompress(compressed.length, 16384, function(index) { return compressed.charCodeAt(index) - 32; });\n },\n\n //compress into uint8array (UCS-2 big endian format)\n compressToUint8Array: function (uncompressed) {\n var compressed = LZString.compress(uncompressed);\n var buf=new Uint8Array(compressed.length*2); // 2 bytes per character\n\n for (var i=0, TotalLen=compressed.length; i<TotalLen; i++) {\n var current_value = compressed.charCodeAt(i);\n buf[i*2] = current_value >>> 8;\n buf[i*2+1] = current_value % 256;\n }\n return buf;\n },\n\n //decompress from uint8array (UCS-2 big endian format)\n decompressFromUint8Array:function (compressed) {\n if (compressed===null || compressed===undefined){\n return LZString.decompress(compressed);\n } else {\n var buf=new Array(compressed.length/2); // 2 bytes per character\n for (var i=0, TotalLen=buf.length; i<TotalLen; i++) {\n buf[i]=compressed[i*2]*256+compressed[i*2+1];\n }\n\n var result = [];\n buf.forEach(function (c) {\n result.push(f(c));\n });\n return LZString.decompress(result.join(''));\n\n }\n\n },\n\n\n //compress into a string that is already URI encoded\n compressToEncodedURIComponent: function (input) {\n if (input == null) return \"\";\n return LZString._compress(input, 6, function(a){return keyStrUriSafe.charAt(a);});\n },\n\n //decompress from an output of compressToEncodedURIComponent\n decompressFromEncodedURIComponent:function (input) {\n if (input == null) return \"\";\n if (input == \"\") return null;\n input = input.replace(/ /g, \"+\");\n return LZString._decompress(input.length, 32, function(index) { return getBaseValue(keyStrUriSafe, input.charAt(index)); });\n },\n\n compress: function (uncompressed) {\n return LZString._compress(uncompressed, 16, function(a){return f(a);});\n },\n _compress: function (uncompressed, bitsPerChar, getCharFromInt) {\n if (uncompressed == null) return \"\";\n var i, value,\n context_dictionary= {},\n context_dictionaryToCreate= {},\n context_c=\"\",\n context_wc=\"\",\n context_w=\"\",\n context_enlargeIn= 2, // Compensate for the first entry which should not count\n context_dictSize= 3,\n context_numBits= 2,\n context_data=[],\n context_data_val=0,\n context_data_position=0,\n ii;\n\n for (ii = 0; ii < uncompressed.length; ii += 1) {\n context_c = uncompressed.charAt(ii);\n if (!Object.prototype.hasOwnProperty.call(context_dictionary,context_c)) {\n context_dictionary[context_c] = context_dictSize++;\n context_dictionaryToCreate[context_c] = true;\n }\n\n context_wc = context_w + context_c;\n if (Object.prototype.hasOwnProperty.call(context_dictionary,context_wc)) {\n context_w = context_wc;\n } else {\n if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate,context_w)) {\n if (context_w.charCodeAt(0)<256) {\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n }\n value = context_w.charCodeAt(0);\n for (i=0 ; i<8 ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n } else {\n value = 1;\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | value;\n if (context_data_position ==bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = 0;\n }\n value = context_w.charCodeAt(0);\n for (i=0 ; i<16 ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n }\n context_enlargeIn--;\n if (context_enlargeIn == 0) {\n context_enlargeIn = Math.pow(2, context_numBits);\n context_numBits++;\n }\n delete context_dictionaryToCreate[context_w];\n } else {\n value = context_dictionary[context_w];\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n\n\n }\n context_enlargeIn--;\n if (context_enlargeIn == 0) {\n context_enlargeIn = Math.pow(2, context_numBits);\n context_numBits++;\n }\n // Add wc to the dictionary.\n context_dictionary[context_wc] = context_dictSize++;\n context_w = String(context_c);\n }\n }\n\n // Output the code for w.\n if (context_w !== \"\") {\n if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate,context_w)) {\n if (context_w.charCodeAt(0)<256) {\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n }\n value = context_w.charCodeAt(0);\n for (i=0 ; i<8 ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n } else {\n value = 1;\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | value;\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = 0;\n }\n value = context_w.charCodeAt(0);\n for (i=0 ; i<16 ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n }\n context_enlargeIn--;\n if (context_enlargeIn == 0) {\n context_enlargeIn = Math.pow(2, context_numBits);\n context_numBits++;\n }\n delete context_dictionaryToCreate[context_w];\n } else {\n value = context_dictionary[context_w];\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n\n\n }\n context_enlargeIn--;\n if (context_enlargeIn == 0) {\n context_enlargeIn = Math.pow(2, context_numBits);\n context_numBits++;\n }\n }\n\n // Mark the end of the stream\n value = 2;\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n\n // Flush the last char\n while (true) {\n context_data_val = (context_data_val << 1);\n if (context_data_position == bitsPerChar-1) {\n context_data.push(getCharFromInt(context_data_val));\n break;\n }\n else context_data_position++;\n }\n return context_data.join('');\n },\n\n decompress: function (compressed) {\n if (compressed == null) return \"\";\n if (compressed == \"\") return null;\n return LZString._decompress(compressed.length, 32768, function(index) { return compressed.charCodeAt(index); });\n },\n\n _decompress: function (length, resetValue, getNextValue) {\n var dictionary = [],\n next,\n enlargeIn = 4,\n dictSize = 4,\n numBits = 3,\n entry = \"\",\n result = [],\n i,\n w,\n bits, resb, maxpower, power,\n c,\n data = {val:getNextValue(0), position:resetValue, index:1};\n\n for (i = 0; i < 3; i += 1) {\n dictionary[i] = i;\n }\n\n bits = 0;\n maxpower = Math.pow(2,2);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n\n switch (next = bits) {\n case 0:\n bits = 0;\n maxpower = Math.pow(2,8);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n c = f(bits);\n break;\n case 1:\n bits = 0;\n maxpower = Math.pow(2,16);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n c = f(bits);\n break;\n case 2:\n return \"\";\n }\n dictionary[3] = c;\n w = c;\n result.push(c);\n while (true) {\n if (data.index > length) {\n return \"\";\n }\n\n bits = 0;\n maxpower = Math.pow(2,numBits);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n\n switch (c = bits) {\n case 0:\n bits = 0;\n maxpower = Math.pow(2,8);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n\n dictionary[dictSize++] = f(bits);\n c = dictSize-1;\n enlargeIn--;\n break;\n case 1:\n bits = 0;\n maxpower = Math.pow(2,16);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n dictionary[dictSize++] = f(bits);\n c = dictSize-1;\n enlargeIn--;\n break;\n case 2:\n return result.join('');\n }\n\n if (enlargeIn == 0) {\n enlargeIn = Math.pow(2, numBits);\n numBits++;\n }\n\n if (dictionary[c]) {\n entry = dictionary[c];\n } else {\n if (c === dictSize) {\n entry = w + w.charAt(0);\n } else {\n return null;\n }\n }\n result.push(entry);\n\n // Add w+entry[0] to the dictionary.\n dictionary[dictSize++] = w + entry.charAt(0);\n enlargeIn--;\n\n w = entry;\n\n if (enlargeIn == 0) {\n enlargeIn = Math.pow(2, numBits);\n numBits++;\n }\n\n }\n }\n};\n return LZString;\n})();\n\nif (typeof define === 'function' && define.amd) {\n define(function () { return LZString; });\n} else if( typeof module !== 'undefined' && module != null ) {\n module.exports = LZString\n} else if( typeof angular !== 'undefined' && angular != null ) {\n angular.module('LZString', [])\n .factory('LZString', function () {\n return LZString;\n });\n}\n","/**\n * Share utilities for QueryBuilder\n *\n * Handles compression, encoding, and URL generation for sharing analysis state.\n * Uses LZ-String for compression which produces URL-safe output.\n */\n\nimport { compressToEncodedURIComponent, decompressFromEncodedURIComponent } from 'lz-string'\nimport type { CubeQuery, ChartType, ChartAxisConfig, ChartDisplayConfig } from '../../types'\n\n/**\n * State that can be shared via URL\n * Query is required, chart config is optional (may be dropped if too large)\n */\nexport interface ShareableState {\n query: CubeQuery\n chartType?: ChartType\n chartConfig?: ChartAxisConfig\n displayConfig?: ChartDisplayConfig\n activeView?: 'table' | 'chart'\n}\n\n/**\n * Result of compression with fallback\n */\nexport interface CompressionResult {\n encoded: string | null\n queryOnly: boolean\n}\n\n// Max safe URL hash length (conservative for browser compatibility)\nconst MAX_HASH_LENGTH = 1800\nconst SHARE_PREFIX = 'share='\n\n/**\n * Compress state to URL-safe encoded string\n */\nexport function compressAndEncode(state: ShareableState): string {\n const json = JSON.stringify(state)\n return compressToEncodedURIComponent(json)\n}\n\n/**\n * Decompress URL-safe encoded string back to state\n * Returns null if decompression or parsing fails\n */\nexport function decodeAndDecompress(encoded: string): ShareableState | null {\n try {\n const json = decompressFromEncodedURIComponent(encoded)\n if (!json) return null\n\n const state = JSON.parse(json) as ShareableState\n\n // Validate required field\n if (!state.query || typeof state.query !== 'object') {\n return null\n }\n\n return state\n } catch {\n return null\n }\n}\n\n/**\n * Check if compressed state fits within URL length limit\n */\nexport function isShareableSize(state: ShareableState): { ok: boolean; size: number; maxSize: number } {\n const encoded = compressAndEncode(state)\n return {\n ok: encoded.length <= MAX_HASH_LENGTH,\n size: encoded.length,\n maxSize: MAX_HASH_LENGTH\n }\n}\n\n/**\n * Compress state with automatic fallback\n * If full state is too large, tries with query only\n * Returns null encoded if even query-only is too large\n */\nexport function compressWithFallback(state: ShareableState): CompressionResult {\n // Try full state first\n const fullEncoded = compressAndEncode(state)\n if (fullEncoded.length <= MAX_HASH_LENGTH) {\n return { encoded: fullEncoded, queryOnly: false }\n }\n\n // Fall back to query only\n const queryOnlyState: ShareableState = { query: state.query }\n const queryOnlyEncoded = compressAndEncode(queryOnlyState)\n\n if (queryOnlyEncoded.length <= MAX_HASH_LENGTH) {\n return { encoded: queryOnlyEncoded, queryOnly: true }\n }\n\n // Even query-only is too large\n return { encoded: null, queryOnly: true }\n}\n\n/**\n * Generate full share URL with compressed state in hash\n */\nexport function generateShareUrl(state: ShareableState): string | null {\n const { encoded } = compressWithFallback(state)\n if (!encoded) return null\n\n return `${window.location.origin}${window.location.pathname}#${SHARE_PREFIX}${encoded}`\n}\n\n/**\n * Parse share hash from current URL\n * Returns encoded string if #share= is present, null otherwise\n */\nexport function parseShareHash(): string | null {\n if (typeof window === 'undefined') return null\n\n const hash = window.location.hash\n if (!hash || !hash.startsWith(`#${SHARE_PREFIX}`)) {\n return null\n }\n\n return hash.slice(SHARE_PREFIX.length + 1) // +1 for the #\n}\n\n/**\n * Clear share hash from URL without page reload\n */\nexport function clearShareHash(): void {\n if (typeof window === 'undefined') return\n\n const url = new URL(window.location.href)\n url.hash = ''\n window.history.replaceState(null, '', url.toString())\n}\n\n/**\n * Get the maximum allowed hash length\n */\nexport function getMaxHashLength(): number {\n return MAX_HASH_LENGTH\n}\n","/**\n * ShareWarningModal Component\n *\n * Displayed when the query is too large to share via URL,\n * even after dropping chart configuration.\n */\n\nimport React from 'react'\nimport Modal from '../Modal'\nimport { getIcon } from '../../icons'\n\nexport interface ShareWarningModalProps {\n isOpen: boolean\n onClose: () => void\n size: number\n maxSize: number\n}\n\nconst ShareWarningModal: React.FC<ShareWarningModalProps> = ({\n isOpen,\n onClose,\n size,\n maxSize\n}) => {\n const percentUsed = Math.min(Math.round((size / maxSize) * 100), 100)\n\n const WarningIcon = getIcon('warning')\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title=\"Query Too Large to Share\"\n size=\"sm\"\n >\n <div className=\"space-y-4\">\n {/* Warning icon and message */}\n <div className=\"flex items-start gap-3\">\n <div className=\"shrink-0 p-2 bg-amber-100 dark:bg-amber-900/30 rounded-full\">\n <WarningIcon className=\"w-5 h-5 text-amber-600 dark:text-amber-400\" />\n </div>\n <div className=\"text-sm text-dc-text-secondary\">\n Your query is too large to fit in a shareable URL. Even after removing chart settings,\n the compressed query exceeds the safe URL length limit.\n </div>\n </div>\n\n {/* Size indicator */}\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-xs text-dc-text-muted\">\n <span>Compressed size</span>\n <span className=\"text-red-600 dark:text-red-400 font-medium\">\n {size.toLocaleString()} / {maxSize.toLocaleString()} chars\n </span>\n </div>\n <div className=\"h-2 bg-dc-surface-secondary rounded-full overflow-hidden\">\n <div\n className=\"h-full bg-red-500 dark:bg-red-400 transition-all duration-300\"\n style={{ width: `${percentUsed}%` }}\n />\n </div>\n </div>\n\n {/* Suggestions */}\n <div className=\"border-t border-dc-border pt-4\">\n <p className=\"text-xs font-medium text-dc-text mb-2\">\n To make your query shareable, try:\n </p>\n <ul className=\"text-xs text-dc-text-secondary space-y-1.5\">\n <li className=\"flex items-start gap-2\">\n <span className=\"text-dc-text-muted\">-</span>\n <span>Remove some filters, especially complex nested filter groups</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <span className=\"text-dc-text-muted\">-</span>\n <span>Reduce the number of dimensions or measures</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <span className=\"text-dc-text-muted\">-</span>\n <span>Simplify date range filters</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <span className=\"text-dc-text-muted\">-</span>\n <span>Use the "Copy Query" button to copy the raw JSON instead</span>\n </li>\n </ul>\n </div>\n\n {/* Close button */}\n <div className=\"flex justify-end pt-2\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-sm font-medium text-white bg-dc-primary hover:bg-dc-primary-hover rounded-md transition-colors\"\n >\n Got it\n </button>\n </div>\n </div>\n </Modal>\n )\n}\n\nexport default ShareWarningModal\n","/**\n * QueryBuilder Component\n * \n * Main component that orchestrates the query building experience.\n * Manages state and coordinates between the meta explorer, query panel, and results panel.\n */\n\nimport { useState, useEffect, useCallback, useRef, forwardRef, useImperativeHandle, useMemo } from 'react'\nimport { getIcon } from '../../icons'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport CubeMetaExplorer from './CubeMetaExplorer'\nimport QueryPanel from './QueryPanel'\nimport ResultsPanel from './ResultsPanel'\nimport SetupPanel from './SetupPanel'\nimport AIAssistantModal from '../AIAssistant/AIAssistantModal'\nimport type {\n QueryBuilderProps,\n QueryBuilderRef,\n QueryBuilderState,\n MetaResponse,\n ValidationResult,\n ApiConfig,\n ShareButtonState\n} from './types'\nimport type { Filter, ChartType, ChartAxisConfig, ChartDisplayConfig } from '../../types'\nimport { createEmptyQuery, hasQueryContent, cleanQuery, cleanQueryForServer, cleanupFilters, transformQueryForUI } from './utils'\nimport { parseShareHash, clearShareHash, decodeAndDecompress, compressWithFallback, getMaxHashLength, type ShareableState } from './shareUtils'\nimport ShareWarningModal from './ShareWarningModal'\n\nconst STORAGE_KEY = 'drizzle-cube-query-builder-state'\nconst API_CONFIG_STORAGE_KEY = 'drizzle-cube-api-config'\n\nconst QueryBuilder = forwardRef<QueryBuilderRef, QueryBuilderProps>(({\n className = '',\n initialQuery,\n disableLocalStorage = false,\n hideSettings = false,\n enableSharing = false,\n onShare\n}, ref) => {\n // Get cube client, update function, and features from context\n const { cubeApi, updateApiConfig, features } = useCubeContext()\n \n // Load initial API configuration from localStorage\n const getInitialApiConfig = (): ApiConfig => {\n if (!disableLocalStorage) {\n try {\n const saved = localStorage.getItem(API_CONFIG_STORAGE_KEY)\n if (saved) {\n return JSON.parse(saved)\n }\n } catch (error) {\n // Failed to load API config from localStorage\n }\n }\n return {\n baseApiUrl: '/cubejs-api/v1',\n apiToken: ''\n }\n }\n\n // Load initial state from localStorage if available, or use provided initialQuery\n const getInitialState = (): QueryBuilderState => {\n // If initialQuery is provided, use it instead of localStorage\n if (initialQuery) {\n return {\n query: transformQueryForUI(initialQuery),\n schema: null,\n schemaStatus: 'idle',\n schemaError: null,\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }\n }\n\n // Only check localStorage if not disabled\n if (!disableLocalStorage) {\n try {\n const saved = localStorage.getItem(STORAGE_KEY)\n if (saved) {\n const parsedState = JSON.parse(saved)\n return {\n query: transformQueryForUI(parsedState.query) || createEmptyQuery(),\n schema: null, // Schema is always loaded fresh\n schemaStatus: 'idle', // Reset schema status\n schemaError: null,\n validationStatus: 'idle', // Reset validation status\n validationError: null,\n validationSql: null,\n executionStatus: 'idle', // Reset execution status\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }\n }\n } catch (error) {\n // Failed to load query from localStorage\n }\n }\n \n return {\n query: createEmptyQuery(),\n schema: null,\n schemaStatus: 'idle',\n schemaError: null,\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }\n }\n\n const [state, setState] = useState<QueryBuilderState>(getInitialState())\n \n // Separate state for display limit (doesn't affect the actual query object)\n const [displayLimit, setDisplayLimit] = useState<number>(10)\n\n // Load initial chart configuration from localStorage\n const getInitialChartState = () => {\n if (!disableLocalStorage) {\n try {\n const saved = localStorage.getItem(STORAGE_KEY)\n if (saved) {\n const parsed = JSON.parse(saved)\n return {\n chartType: parsed.chartType || 'table',\n chartConfig: parsed.chartConfig || {},\n displayConfig: parsed.displayConfig || { showLegend: true, showGrid: true, showTooltip: true },\n activeView: parsed.activeView || 'table'\n }\n }\n } catch (error) {\n // Failed to load chart config from localStorage\n }\n }\n return {\n chartType: 'table' as ChartType,\n chartConfig: {} as ChartAxisConfig,\n displayConfig: { showLegend: true, showGrid: true, showTooltip: true } as ChartDisplayConfig,\n activeView: 'table' as 'table' | 'chart'\n }\n }\n\n // Chart visualization state\n const initialChartState = getInitialChartState()\n const [chartType, setChartType] = useState<ChartType>(initialChartState.chartType)\n const [chartConfig, setChartConfig] = useState<ChartAxisConfig>(initialChartState.chartConfig)\n const [displayConfig, setDisplayConfig] = useState<ChartDisplayConfig>(initialChartState.displayConfig)\n const [activeView, setActiveView] = useState<'table' | 'chart'>(initialChartState.activeView)\n\n // API configuration state\n const [apiConfig, setApiConfig] = useState<ApiConfig>(getInitialApiConfig())\n const [showSetupPanel, setShowSetupPanel] = useState(false)\n const [showSchemaMobile, setShowSchemaMobile] = useState(false)\n const [schemaViewType, setSchemaViewType] = useState<'tree' | 'diagram'>('tree')\n \n // AI Assistant modal state\n const [showAIAssistant, setShowAIAssistant] = useState(false)\n\n // Share functionality state\n const [shareButtonState, setShareButtonState] = useState<ShareButtonState>('idle')\n const [showShareWarning, setShowShareWarning] = useState(false)\n const [shareWarningData, setShareWarningData] = useState({ size: 0, maxSize: 0 })\n const [isViewingShared, setIsViewingShared] = useState(false)\n\n // Update query when initialQuery prop changes (for modal usage)\n useEffect(() => {\n if (initialQuery && JSON.stringify(initialQuery) !== JSON.stringify(state.query)) {\n setState(prev => ({\n ...prev,\n query: transformQueryForUI(initialQuery),\n schemaStatus: 'idle',\n schemaError: null,\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }))\n }\n }, [initialQuery])\n\n // Track the last validated query to avoid resetting validation on unrelated updates\n const lastValidatedQueryRef = useRef<string>('')\n\n // Note: API configuration is kept for backward compatibility but not used \n // since we now use the CubeClient from context\n\n // Store the full validation result for access via ref\n const [fullValidationResult, setFullValidationResult] = useState<ValidationResult | null>(null)\n\n // Compute available fields for chart configuration from validation result\n const availableFields = useMemo(() => {\n if (!fullValidationResult?.pivotQuery?.query) return null\n return {\n dimensions: fullValidationResult.pivotQuery.query.dimensions || [],\n timeDimensions: fullValidationResult.pivotQuery.query.timeDimensions?.map((td: { dimension: string }) => td.dimension) || [],\n measures: fullValidationResult.pivotQuery.query.measures || []\n }\n }, [fullValidationResult])\n\n // Expose query and validation state to parent via ref (only called when Apply is clicked)\n useImperativeHandle(ref, () => ({\n getCurrentQuery: () => cleanQueryForServer(state.query),\n getValidationState: () => ({\n status: state.validationStatus,\n result: state.validationStatus === 'valid' ? {\n valid: true,\n sql: state.validationSql || undefined\n } : state.validationStatus === 'invalid' ? {\n valid: false,\n error: state.validationError || undefined\n } : undefined\n }),\n getValidationResult: () => fullValidationResult\n }), [state.query, state.validationStatus, state.validationError, state.validationSql, fullValidationResult])\n\n // Load schema on mount and when API config changes\n useEffect(() => {\n const loadSchema = async () => {\n setState(prev => ({\n ...prev,\n schemaStatus: 'loading',\n schemaError: null\n }))\n\n try {\n const metaResponse: MetaResponse = await cubeApi.meta()\n setState(prev => ({\n ...prev,\n schema: metaResponse,\n schemaStatus: 'success',\n schemaError: null\n }))\n } catch (error) {\n // Failed to load schema\n const errorMessage = error instanceof Error ? error.message : 'Failed to load schema'\n setState(prev => ({\n ...prev,\n schema: null,\n schemaStatus: 'error',\n schemaError: errorMessage\n }))\n }\n }\n\n loadSchema()\n }, [apiConfig.baseApiUrl, apiConfig.apiToken])\n\n // Save query and chart config to localStorage whenever they change (if not disabled)\n useEffect(() => {\n if (!disableLocalStorage) {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify({\n query: state.query,\n chartType,\n chartConfig,\n displayConfig,\n activeView\n }))\n } catch (error) {\n // Failed to save state to localStorage\n }\n }\n }, [state.query, chartType, chartConfig, displayConfig, activeView, disableLocalStorage])\n\n // Save API config to localStorage whenever it changes (if not disabled)\n useEffect(() => {\n if (!disableLocalStorage) {\n try {\n localStorage.setItem(API_CONFIG_STORAGE_KEY, JSON.stringify(apiConfig))\n } catch (error) {\n // Failed to save API config to localStorage\n }\n }\n }, [apiConfig, disableLocalStorage])\n\n // Track if we need to auto-run after loading shared analysis\n const pendingSharedExecution = useRef(false)\n\n // Parse URL hash for shared analysis on mount (when sharing is enabled)\n useEffect(() => {\n if (!enableSharing) return\n\n const encoded = parseShareHash()\n if (!encoded) return\n\n const decoded = decodeAndDecompress(encoded)\n if (decoded) {\n // Apply query (required)\n setState(prev => ({\n ...prev,\n query: transformQueryForUI(decoded.query),\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }))\n\n // Apply chart config if present, otherwise use defaults\n if (decoded.chartType) setChartType(decoded.chartType)\n if (decoded.chartConfig) setChartConfig(decoded.chartConfig)\n if (decoded.displayConfig) setDisplayConfig(decoded.displayConfig)\n if (decoded.activeView) setActiveView(decoded.activeView)\n\n setIsViewingShared(true)\n pendingSharedExecution.current = true\n }\n\n // Clear hash from URL\n clearShareHash()\n }, [enableSharing])\n\n // Auto re-run query when displayLimit or activeView changes\n useEffect(() => {\n if (state.executionStatus === 'success' && hasQueryContent(state.query) && state.validationStatus === 'valid') {\n handleExecuteQuery()\n }\n }, [displayLimit, activeView]) // Re-run on limit or view change\n\n\n const updateQuery = useCallback((updater: (prev: typeof state.query) => typeof state.query) => {\n setState(prev => {\n const newQuery = updater(prev.query)\n \n // Clean up filters to remove any that reference fields no longer in the query\n const cleanedQuery = {\n ...newQuery,\n filters: newQuery.filters ? cleanupFilters(newQuery.filters, newQuery) : undefined\n }\n \n const queryChanged = JSON.stringify(cleanedQuery) !== JSON.stringify(prev.query)\n \n return {\n ...prev,\n query: cleanedQuery,\n // Only reset validation if query actually changed\n validationStatus: queryChanged ? 'idle' : prev.validationStatus,\n validationError: queryChanged ? null : prev.validationError,\n validationSql: queryChanged ? null : prev.validationSql,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }\n })\n }, [])\n\n const handleFieldSelect = useCallback((fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n updateQuery(prev => {\n const newQuery = { ...prev }\n \n switch (fieldType) {\n case 'measures':\n // Only add if not already present\n if (!(prev.measures || []).includes(fieldName)) {\n newQuery.measures = [...(prev.measures || []), fieldName]\n }\n break\n case 'dimensions':\n // Only add if not already present\n if (!(prev.dimensions || []).includes(fieldName)) {\n newQuery.dimensions = [...(prev.dimensions || []), fieldName]\n }\n break\n case 'timeDimensions':\n // Only add if not already present\n if (!(prev.timeDimensions || []).some(td => td.dimension === fieldName)) {\n newQuery.timeDimensions = [...(prev.timeDimensions || []), { \n dimension: fieldName, \n granularity: 'month' \n }]\n }\n break\n }\n \n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleFieldDeselect = useCallback((fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n updateQuery(prev => {\n const newQuery = { ...prev }\n \n switch (fieldType) {\n case 'measures':\n newQuery.measures = (prev.measures || []).filter(m => m !== fieldName)\n break\n case 'dimensions':\n newQuery.dimensions = (prev.dimensions || []).filter(d => d !== fieldName)\n break\n case 'timeDimensions':\n newQuery.timeDimensions = (prev.timeDimensions || []).filter(td => td.dimension !== fieldName)\n break\n }\n \n // Clean up order if field was sorted\n if (newQuery.order && newQuery.order[fieldName]) {\n const newOrder = { ...newQuery.order }\n delete newOrder[fieldName]\n newQuery.order = Object.keys(newOrder).length > 0 ? newOrder : undefined\n }\n \n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleTimeDimensionGranularityChange = useCallback((dimensionName: string, granularity: string) => {\n updateQuery(prev => {\n const newQuery = {\n ...prev,\n timeDimensions: (prev.timeDimensions || []).map(td => \n td.dimension === dimensionName \n ? { ...td, granularity }\n : td\n )\n }\n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleFiltersChange = useCallback((filters: Filter[]) => {\n updateQuery(prev => {\n const newQuery = {\n ...prev,\n filters\n }\n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleDateRangeChange = useCallback((timeDimension: string, dateRange: string | string[]) => {\n updateQuery(prev => {\n const newQuery = {\n ...prev,\n timeDimensions: (prev.timeDimensions || []).map(td => \n td.dimension === timeDimension \n ? { ...td, dateRange }\n : td\n )\n }\n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleDateRangeRemove = useCallback((timeDimension: string) => {\n updateQuery(prev => {\n const newQuery = {\n ...prev,\n timeDimensions: (prev.timeDimensions || []).map(td => \n td.dimension === timeDimension \n ? { ...td, dateRange: undefined }\n : td\n )\n }\n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleOrderChange = useCallback((fieldName: string, direction: 'asc' | 'desc' | null) => {\n updateQuery(prev => {\n const newOrder = { ...(prev.order || {}) }\n \n if (direction === null) {\n delete newOrder[fieldName]\n } else {\n newOrder[fieldName] = direction\n }\n \n const newQuery = {\n ...prev,\n order: Object.keys(newOrder).length > 0 ? newOrder : undefined\n }\n \n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleValidateQuery = useCallback(async () => {\n if (!hasQueryContent(state.query)) return\n\n // Store the query being validated (cleaned and server-formatted)\n const queryToValidate = cleanQueryForServer(state.query)\n const queryStr = JSON.stringify(queryToValidate)\n \n\n setState(prev => ({\n ...prev,\n validationStatus: 'validating',\n validationError: null,\n validationSql: null\n }))\n\n try {\n const result: ValidationResult = await cubeApi.dryRun(queryToValidate)\n \n // Store the full validation result for parent access\n setFullValidationResult(result)\n \n // Check if validation is successful:\n // 1. Must have queryType (always present in successful Cube.js responses)\n // 2. Must not have an error\n // 3. For compatibility, also check result.valid if present\n const isValid = !result.error && result.queryType && (result.valid !== false)\n \n // Store the validated query to prevent reset\n if (isValid) {\n lastValidatedQueryRef.current = queryStr\n }\n \n setState(prev => {\n return {\n ...prev,\n validationStatus: isValid ? 'valid' : 'invalid',\n validationError: result.error || null,\n validationSql: result.sql || null\n }\n })\n } catch (error) {\n // Validation error\n setFullValidationResult(null)\n setState(prev => ({\n ...prev,\n validationStatus: 'invalid',\n validationError: error instanceof Error ? error.message : 'Network error during validation',\n validationSql: null\n }))\n }\n }, [state.query, cubeApi])\n\n // Auto re-validate query when query changes (with 1s debounce)\n useEffect(() => {\n // Only auto-validate if query has content and validation was previously cleared\n if (!hasQueryContent(state.query) || state.validationStatus !== 'idle') {\n return\n }\n\n const debounceTimer = setTimeout(() => {\n handleValidateQuery()\n }, 200) // 200ms debounce - fast but prevents excessive API calls\n\n return () => clearTimeout(debounceTimer)\n }, [state.query, state.validationStatus, handleValidateQuery]) // Trigger when query changes and validation status is idle\n\n const handleExecuteQuery = useCallback(async () => {\n if (!hasQueryContent(state.query) || state.validationStatus !== 'valid') return\n\n setState(prev => ({\n ...prev,\n executionStatus: 'loading',\n executionResults: null,\n executionError: null,\n totalRowCountStatus: 'loading'\n }))\n\n try {\n // Run both queries in parallel: one with limit and one without for total count\n // Chart view: no limit (show all data for visualization)\n // Table view: apply displayLimit for pagination\n const cleanedQuery = cleanQueryForServer(state.query)\n const effectiveLimit = activeView === 'chart' ? undefined : displayLimit\n\n const [limitedResultSet, totalResultSet] = await Promise.all([\n cubeApi.load(effectiveLimit ? { ...cleanedQuery, limit: effectiveLimit } : cleanedQuery),\n cubeApi.load(cleanedQuery) // No limit for total count\n ])\n\n const limitedData = limitedResultSet.tablePivot()\n const totalData = totalResultSet.tablePivot()\n const totalCount = totalData.length\n\n setState(prev => ({\n ...prev,\n executionStatus: 'success',\n executionResults: limitedData,\n executionError: null,\n totalRowCount: totalCount,\n totalRowCountStatus: 'success'\n }))\n } catch (error) {\n // Query execution error\n setState(prev => ({\n ...prev,\n executionStatus: 'error',\n executionResults: null,\n executionError: error instanceof Error ? error.message : 'Query execution failed',\n totalRowCount: null,\n totalRowCountStatus: 'error'\n }))\n }\n }, [state.query, state.validationStatus, cubeApi, displayLimit, activeView])\n\n // Auto-execute query after loading from shared link once validation succeeds\n useEffect(() => {\n if (pendingSharedExecution.current && state.validationStatus === 'valid' && state.executionStatus === 'idle') {\n pendingSharedExecution.current = false\n handleExecuteQuery()\n }\n }, [state.validationStatus, state.executionStatus, handleExecuteQuery])\n\n const handleClearQuery = useCallback(() => {\n setState(prev => ({\n ...prev,\n query: createEmptyQuery(),\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }))\n }, [])\n\n const handleShare = useCallback(async () => {\n if (!enableSharing) return\n\n const shareableState: ShareableState = {\n query: cleanQueryForServer(state.query),\n chartType,\n chartConfig,\n displayConfig,\n activeView\n }\n\n // Try full state first, fall back to query-only if too large\n const { encoded, queryOnly } = compressWithFallback(shareableState)\n\n // If even query-only is too large, show warning modal\n if (!encoded) {\n const queryOnlyState: ShareableState = { query: shareableState.query }\n const queryOnlySize = JSON.stringify(queryOnlyState).length\n setShareWarningData({ size: queryOnlySize, maxSize: getMaxHashLength() })\n setShowShareWarning(true)\n return\n }\n\n const url = `${window.location.origin}${window.location.pathname}#share=${encoded}`\n\n try {\n await navigator.clipboard.writeText(url)\n } catch {\n // Fallback for older browsers\n const textArea = document.createElement('textarea')\n textArea.value = url\n document.body.appendChild(textArea)\n textArea.select()\n document.execCommand('copy')\n document.body.removeChild(textArea)\n }\n\n // Update button state\n setShareButtonState(queryOnly ? 'copied-no-chart' : 'copied')\n\n // Call onShare callback if provided\n onShare?.(url)\n\n // Reset button state after 2 seconds\n setTimeout(() => {\n setShareButtonState('idle')\n }, 2000)\n }, [enableSharing, state.query, chartType, chartConfig, displayConfig, activeView, onShare])\n\n const handleApiConfigChange = useCallback((newConfig: ApiConfig) => {\n setApiConfig(newConfig)\n \n // Update the CubeProvider's client with new configuration\n updateApiConfig(\n { apiUrl: newConfig.baseApiUrl },\n newConfig.apiToken || undefined\n )\n \n // Reset all state when API config changes\n setState(prev => ({\n ...prev,\n schema: null,\n schemaStatus: 'idle',\n schemaError: null,\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }))\n }, [updateApiConfig])\n\n const handleResetApiConfig = useCallback(() => {\n const defaultConfig = {\n baseApiUrl: '/cubejs-api/v1',\n apiToken: ''\n }\n setApiConfig(defaultConfig)\n \n // Update the CubeProvider's client with reset configuration\n updateApiConfig(\n { apiUrl: defaultConfig.baseApiUrl },\n undefined\n )\n }, [updateApiConfig])\n\n const handleRetrySchema = useCallback(async () => {\n setState(prev => ({\n ...prev,\n schemaStatus: 'loading',\n schemaError: null\n }))\n\n try {\n const metaResponse: MetaResponse = await cubeApi.meta()\n setState(prev => ({\n ...prev,\n schema: metaResponse,\n schemaStatus: 'success',\n schemaError: null\n }))\n } catch (error) {\n // Failed to retry schema\n const errorMessage = error instanceof Error ? error.message : 'Failed to load schema'\n setState(prev => ({\n ...prev,\n schema: null,\n schemaStatus: 'error',\n schemaError: errorMessage\n }))\n }\n }, [cubeApi])\n\n const selectedFields = {\n measures: state.query.measures || [],\n dimensions: state.query.dimensions || [],\n timeDimensions: (state.query.timeDimensions || []).map(td => td.dimension)\n }\n\n const MenuIcon = getIcon('menu')\n const CloseIcon = getIcon('close')\n\n return (\n <div className={`h-full flex flex-col ${className}`} style={{ minHeight: '100%' }}>\n {/* Setup Panel - only show when not in modal and not hidden */}\n {!hideSettings && (\n <div className=\"shrink-0 p-4 pb-0\">\n <SetupPanel\n isOpen={showSetupPanel}\n onToggle={() => setShowSetupPanel(!showSetupPanel)}\n config={apiConfig}\n onConfigChange={handleApiConfigChange}\n onReset={handleResetApiConfig}\n />\n </div>\n )}\n\n {/* Mobile Schema Toggle Button */}\n <div className=\"md:hidden shrink-0 px-4 pb-2\">\n <button\n onClick={() => setShowSchemaMobile(!showSchemaMobile)}\n className=\"flex items-center gap-2 px-3 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface-secondary hover:bg-dc-surface-hover rounded-md transition-colors\"\n >\n {showSchemaMobile ? (\n <><CloseIcon className=\"w-4 h-4\" /> Hide Schema</>\n ) : (\n <><MenuIcon className=\"w-4 h-4\" /> Show Schema</>\n )}\n </button>\n </div>\n\n {/* Mobile Schema Panel Overlay */}\n {showSchemaMobile && (\n <div className=\"md:hidden fixed inset-0 z-50 bg-black bg-opacity-50 flex\">\n <div className=\"w-full max-w-md sm:max-w-lg bg-dc-surface h-full overflow-y-auto\">\n <div className=\"p-4 border-b border-dc-border\">\n <button\n onClick={() => setShowSchemaMobile(false)}\n className=\"flex items-center gap-2 px-3 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface-secondary hover:bg-dc-surface-hover rounded-md transition-colors\"\n >\n <CloseIcon className=\"w-4 h-4\" /> Close Schema\n </button>\n </div>\n <div className=\"p-4\">\n <CubeMetaExplorer\n schema={state.schema}\n schemaStatus={state.schemaStatus}\n schemaError={state.schemaError}\n selectedFields={selectedFields}\n onFieldSelect={(field, type) => {\n handleFieldSelect(field, type)\n setShowSchemaMobile(false)\n }}\n onFieldDeselect={handleFieldDeselect}\n onRetrySchema={handleRetrySchema}\n onOpenSettings={!hideSettings ? () => setShowSetupPanel(true) : undefined}\n onExpandSchema={(expanded) => {\n if (expanded) setShowSchemaMobile(false)\n }}\n />\n </div>\n </div>\n <div className=\"flex-1\" onClick={() => setShowSchemaMobile(false)}></div>\n </div>\n )}\n\n <div className=\"flex-1 flex flex-col md:flex-row gap-4 p-4 min-h-0\" style={{ paddingTop: hideSettings ? '1rem' : '0rem' }}>\n {/* Schema Explorer with dynamic width based on view type */}\n <div className={`hidden md:flex shrink-0 flex-col min-w-0 ${schemaViewType === 'diagram' ? 'w-full' : 'md:w-1/3 max-w-[500px]'}`}>\n <CubeMetaExplorer\n schema={state.schema}\n schemaStatus={state.schemaStatus}\n schemaError={state.schemaError}\n selectedFields={selectedFields}\n onFieldSelect={handleFieldSelect}\n onFieldDeselect={handleFieldDeselect}\n onRetrySchema={handleRetrySchema}\n onOpenSettings={!hideSettings ? () => setShowSetupPanel(true) : undefined}\n onExpandSchema={undefined} // No expand/collapse needed\n onViewTypeChange={setSchemaViewType}\n isExpanded={false} // Always false, handled by tab switching\n />\n </div>\n\n {/* Main Content - Query Builder + Results (hide when diagram is selected) */}\n {schemaViewType === 'tree' && (\n <div className=\"flex-1 flex flex-col gap-4 min-w-0 min-h-0\">\n {/* Query Builder */}\n <div className=\"shrink-0\">\n <QueryPanel\n query={state.query}\n schema={state.schema}\n validationStatus={state.validationStatus}\n validationError={state.validationError}\n validationSql={state.validationSql}\n validationAnalysis={fullValidationResult?.analysis}\n onValidate={handleValidateQuery}\n onExecute={handleExecuteQuery}\n onRemoveField={handleFieldDeselect}\n onTimeDimensionGranularityChange={handleTimeDimensionGranularityChange}\n onFiltersChange={handleFiltersChange}\n onDateRangeChange={handleDateRangeChange}\n onDateRangeRemove={handleDateRangeRemove}\n onOrderChange={handleOrderChange}\n onClearQuery={handleClearQuery}\n showSettings={!hideSettings}\n onSettingsClick={() => setShowSetupPanel(!showSetupPanel)}\n onAIAssistantClick={features?.enableAI !== false ? () => setShowAIAssistant(true) : undefined}\n onShareClick={enableSharing && hasQueryContent(state.query) ? handleShare : undefined}\n shareButtonState={shareButtonState}\n isViewingShared={isViewingShared}\n />\n </div>\n\n {/* Results Panel */}\n <div className={`${state.executionStatus === 'idle' ? 'shrink-0 h-48' : 'flex-1 min-h-0'}`}>\n <ResultsPanel\n executionStatus={state.executionStatus}\n executionResults={state.executionResults}\n executionError={state.executionError}\n query={state.query}\n displayLimit={displayLimit}\n onDisplayLimitChange={setDisplayLimit}\n totalRowCount={state.totalRowCount}\n totalRowCountStatus={state.totalRowCountStatus}\n // Chart visualization props\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n availableFields={availableFields}\n onChartTypeChange={setChartType}\n onChartConfigChange={setChartConfig}\n onDisplayConfigChange={setDisplayConfig}\n // View state props\n activeView={activeView}\n onActiveViewChange={setActiveView}\n />\n </div>\n </div>\n )}\n </div>\n \n {/* AI Assistant Modal - only render if AI is enabled */}\n {features?.enableAI !== false && (\n <AIAssistantModal\n isOpen={showAIAssistant}\n onClose={() => setShowAIAssistant(false)}\n schema={state.schema}\n aiEndpoint={features?.aiEndpoint}\n onQueryLoad={(query) => {\n // Update the query in the builder\n setState(prev => ({\n ...prev,\n query: transformQueryForUI(query),\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle'\n }))\n \n // Auto-validate the loaded query after a short delay\n setTimeout(async () => {\n // We need to access handleValidateQuery through a ref or recreate the validation logic\n // For now, let's trigger validation by updating the state to force a validation\n const queryToValidate = cleanQueryForServer(transformQueryForUI(query))\n \n try {\n const result = await cubeApi.dryRun(queryToValidate)\n const isValid = !result.error && result.queryType && (result.valid !== false)\n \n setState(prev => ({\n ...prev,\n validationStatus: isValid ? 'valid' : 'invalid',\n validationError: result.error || null,\n validationSql: result.sql || null\n }))\n \n setFullValidationResult(result)\n } catch (error) {\n // Auto-validation error\n setState(prev => ({\n ...prev,\n validationStatus: 'invalid',\n validationError: error instanceof Error ? error.message : 'Validation failed',\n validationSql: null\n }))\n setFullValidationResult(null)\n }\n }, 200)\n }}\n />\n )}\n\n {/* Share Warning Modal - shown when query is too large to share */}\n <ShareWarningModal\n isOpen={showShareWarning}\n onClose={() => setShowShareWarning(false)}\n size={shareWarningData.size}\n maxSize={shareWarningData.maxSize}\n />\n\n </div>\n )\n})\n\nQueryBuilder.displayName = 'QueryBuilder'\n\nexport default QueryBuilder","import React, { useState, useEffect, useRef } from 'react'\nimport Modal from './Modal'\nimport QueryBuilder from './QueryBuilder'\nimport ChartConfigPanel from './ChartConfigPanel'\nimport ChartTypeSelector from './ChartTypeSelector'\nimport { useCubeContext } from '../providers/CubeProvider'\nimport { chartConfigRegistry } from '../charts/chartConfigRegistry'\nimport { getChartConfig } from '../charts/chartConfigs'\nimport type { PortletConfig, ChartAxisConfig, ChartDisplayConfig, ChartType, ColorPalette } from '../types'\n\ninterface PortletEditModalProps {\n isOpen: boolean\n onClose: () => void\n onSave: (portlet: PortletConfig | Omit<PortletConfig, 'id' | 'x' | 'y'>) => void\n portlet?: PortletConfig | null\n title: string\n submitText: string\n colorPalette?: ColorPalette\n}\n\n\nconst SAMPLE_QUERIES = [\n {\n name: 'Employee Count by Department',\n query: JSON.stringify({\n \"measures\": [\"Employees.count\"],\n \"dimensions\": [\"Departments.name\"],\n \"order\": { \"Employees.count\": \"desc\" }\n }, null, 2)\n },\n {\n name: 'Employee Hiring Trends',\n query: JSON.stringify({\n \"measures\": [\"Employees.count\"],\n \"timeDimensions\": [{\n \"dimension\": \"Employees.createdAt\",\n \"granularity\": \"month\"\n }],\n \"order\": { \"Employees.createdAt\": \"asc\" }\n }, null, 2)\n },\n {\n name: 'Department Budget Analysis',\n query: JSON.stringify({\n \"measures\": [\"Departments.totalBudget\", \"Departments.avgBudget\"],\n \"dimensions\": [\"Departments.name\"],\n \"order\": { \"Departments.totalBudget\": \"desc\" }\n }, null, 2)\n },\n {\n name: 'Daily Productivity Trends',\n query: JSON.stringify({\n \"measures\": [\"Productivity.avgLinesOfCode\", \"Productivity.totalPullRequests\"],\n \"timeDimensions\": [{\n \"dimension\": \"Productivity.date\",\n \"granularity\": \"day\"\n }],\n \"order\": { \"Productivity.date\": \"asc\" }\n }, null, 2)\n },\n {\n name: 'Happiness by Department',\n query: JSON.stringify({\n \"measures\": [\"Productivity.avgHappinessIndex\", \"Productivity.workingDaysCount\"],\n \"dimensions\": [\"Departments.name\"],\n \"order\": { \"Productivity.avgHappinessIndex\": \"desc\" }\n }, null, 2)\n },\n {\n name: 'Employee Salary Overview',\n query: JSON.stringify({\n \"measures\": [\"Employees.count\", \"Employees.avgSalary\", \"Employees.totalSalary\"],\n \"dimensions\": [\"Employees.isActive\"],\n \"order\": { \"Employees.avgSalary\": \"desc\" }\n }, null, 2)\n }\n]\n\nexport default function PortletEditModal({\n isOpen,\n onClose,\n onSave,\n portlet,\n title,\n submitText,\n colorPalette\n}: PortletEditModalProps) {\n // Get cube client from context\n const { cubeApi } = useCubeContext()\n const [formTitle, setFormTitle] = useState('')\n const [query, setQuery] = useState('')\n const [chartType, setChartType] = useState<ChartType>('bar')\n const [dashboardFilterMapping, setDashboardFilterMapping] = useState<string[]>([])\n const [isValidating, setIsValidating] = useState(false)\n const [validationResult, setValidationResult] = useState<{ isValid: boolean; message: string } | null>(null)\n const [lastValidatedQuery, setLastValidatedQuery] = useState<string>('')\n const [dryRunData, setDryRunData] = useState<any>(null)\n const [chartConfig, setChartConfig] = useState<ChartAxisConfig>({ xAxis: [], yAxis: [], series: [] })\n const [displayConfig, setDisplayConfig] = useState<ChartDisplayConfig>({ showLegend: true, showGrid: true, showTooltip: true, stacked: false })\n const [showQueryBuilder, setShowQueryBuilder] = useState(false)\n const [queryBuilderInitialQuery, setQueryBuilderInitialQuery] = useState<any>(null)\n const queryBuilderRef = useRef<any>(null)\n\n // Check if current chart type skips queries\n const chartTypeConfig = getChartConfig(chartType, chartConfigRegistry)\n const shouldSkipQuery = chartTypeConfig.skipQuery === true\n\n // Validation only - no automatic chart config changes\n const autoPopulateChartConfig = (_result: any) => {\n // Do nothing - let the chart configuration panel handle all axis assignments manually\n // This preserves any existing user configuration and doesn't auto-assign fields\n }\n \n // Sensible defaults: slightly larger than 1/3 width with good aspect ratio\n const defaultWidth = 5\n const defaultHeight = 4\n\n\n // Initialize form values when modal opens or portlet changes\n useEffect(() => {\n if (isOpen) {\n if (portlet) {\n // Edit mode - populate with existing data\n setFormTitle(portlet.title)\n const formattedQuery = (() => {\n try {\n return JSON.stringify(JSON.parse(portlet.query), null, 2)\n } catch {\n return portlet.query\n }\n })()\n setQuery(formattedQuery)\n setChartType(portlet.chartType)\n setChartConfig(portlet.chartConfig || { xAxis: [], yAxis: [], series: [] })\n setDisplayConfig(portlet.displayConfig || {})\n setDashboardFilterMapping(portlet.dashboardFilterMapping || [])\n setLastValidatedQuery(formattedQuery)\n setValidationResult({ isValid: true, message: 'Loaded query (assumed valid)' })\n setDryRunData(null)\n\n // Auto-run dry-run validation for edit mode to enable chart configuration (skip for skipQuery charts)\n if (!shouldSkipQuery) {\n setTimeout(() => {\n runDryRunValidation(formattedQuery, true, true)\n }, 100)\n }\n } else {\n // Create mode - clear form\n setFormTitle('')\n setQuery('')\n setChartType('bar')\n setChartConfig({ xAxis: [], yAxis: [], series: [] })\n setDisplayConfig({ showLegend: true, showGrid: true, showTooltip: true, stacked: false })\n setDashboardFilterMapping([])\n setLastValidatedQuery('')\n setValidationResult(null)\n setDryRunData(null)\n }\n setIsValidating(false)\n }\n }, [isOpen, portlet])\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault()\n \n // For skipQuery charts, only validate title\n if (shouldSkipQuery) {\n if (!formTitle.trim()) {\n return\n }\n } else {\n // For normal charts, validate both title and query\n if (!formTitle.trim() || !query.trim()) {\n return\n }\n\n // Require validation before saving only if query has changed\n if (hasQueryChanged || (lastValidatedQuery === '' && query.trim() !== '')) {\n alert('Please validate your query before saving.')\n return\n }\n\n // Validate JSON\n try {\n JSON.parse(query)\n } catch (e) {\n alert('Invalid JSON in query. Please check your syntax.')\n return\n }\n }\n\n // Prepare query - use minimal query for skipQuery charts\n const queryToSave = shouldSkipQuery ? '{\"measures\":[]}' : query.trim()\n\n if (portlet) {\n // Edit mode - return full portlet config\n onSave({\n ...portlet,\n title: formTitle.trim(),\n query: queryToSave,\n chartType,\n chartConfig: Object.keys(chartConfig).length > 0 ? chartConfig : undefined,\n displayConfig: displayConfig,\n dashboardFilterMapping: dashboardFilterMapping.length > 0 ? dashboardFilterMapping : undefined,\n w: portlet.w || defaultWidth,\n h: portlet.h || defaultHeight\n })\n } else {\n // Create mode - return partial config\n onSave({\n title: formTitle.trim(),\n query: queryToSave,\n chartType,\n chartConfig: Object.keys(chartConfig).length > 0 ? chartConfig : undefined,\n displayConfig: displayConfig,\n dashboardFilterMapping: dashboardFilterMapping.length > 0 ? dashboardFilterMapping : undefined,\n w: defaultWidth,\n h: defaultHeight\n })\n }\n }\n\n const handleSampleQuery = (sampleQuery: string) => {\n setQuery(sampleQuery)\n setValidationResult(null)\n setLastValidatedQuery('')\n setDryRunData(null)\n // Sample queries always clear chart config since they're completely different\n setChartConfig({ xAxis: [], yAxis: [], series: [] })\n }\n\n const handleQueryChange = (value: string) => {\n setQuery(value)\n setValidationResult(null)\n setDryRunData(null)\n // Only clear chart config for new portlets, preserve existing config for edits\n if (!portlet) {\n setChartConfig({ xAxis: [], yAxis: [], series: [] })\n }\n }\n\n const runDryRunValidation = async (queryToValidate: string, silent = false, isEditModeLoad = false) => {\n if (!queryToValidate.trim()) {\n if (!silent) {\n setValidationResult({ isValid: false, message: 'Query cannot be empty' })\n }\n return\n }\n\n let parsedQuery\n try {\n parsedQuery = JSON.parse(queryToValidate)\n } catch (e) {\n if (!silent) {\n setValidationResult({ isValid: false, message: 'Invalid JSON syntax' })\n }\n return\n }\n\n if (!silent) {\n setIsValidating(true)\n setValidationResult(null)\n }\n\n try {\n const result = await cubeApi.dryRun(parsedQuery)\n\n // Check if validation is successful:\n // 1. Must have queryType (always present in successful Cube.js responses) \n // 2. Must not have an error\n const isValid = !result.error && result.queryType\n \n if (isValid) {\n setDryRunData(result)\n \n if (!silent) {\n const details = []\n \n if (result.pivotQuery?.query) {\n if (result.pivotQuery.query.measures?.length > 0) {\n details.push(`${result.pivotQuery.query.measures.length} measure${result.pivotQuery.query.measures.length > 1 ? 's' : ''}`)\n }\n if (result.pivotQuery.query.dimensions?.length > 0) {\n details.push(`${result.pivotQuery.query.dimensions.length} dimension${result.pivotQuery.query.dimensions.length > 1 ? 's' : ''}`)\n }\n if (result.pivotQuery.query.filters?.length > 0) {\n details.push(`${result.pivotQuery.query.filters.length} filter${result.pivotQuery.query.filters.length > 1 ? 's' : ''}`)\n }\n if (result.pivotQuery.query.timeDimensions?.length > 0) {\n details.push(`${result.pivotQuery.query.timeDimensions.length} time dimension${result.pivotQuery.query.timeDimensions.length > 1 ? 's' : ''}`)\n }\n }\n\n if (result.complexity) {\n details.push(`${result.complexity} complexity`)\n }\n if (result.sql?.sql) {\n details.push('SQL generated')\n }\n if (result.cubesUsed?.length > 0) {\n details.push(`Cubes: ${result.cubesUsed.join(', ')}`)\n }\n \n const message = details.length > 0 ? `Query validated successfully (${details.join(', ')})` : 'Query validated successfully'\n setValidationResult({ isValid: true, message })\n setLastValidatedQuery(queryToValidate)\n }\n\n // Auto-populate chart config with sensible defaults on successful validation\n if (!isEditModeLoad) {\n autoPopulateChartConfig(result)\n }\n } else {\n if (!silent) {\n const errorMsg = result.error || 'Query validation failed'\n const details = result.details ? ` - ${Array.isArray(result.details) ? result.details.join(', ') : result.details}` : ''\n setValidationResult({ \n isValid: false, \n message: errorMsg + details\n })\n setLastValidatedQuery(queryToValidate)\n }\n }\n } catch (error) {\n if (!silent) {\n setValidationResult({ \n isValid: false, \n message: error instanceof Error ? error.message : 'Network error during validation' \n })\n setLastValidatedQuery(queryToValidate)\n }\n } finally {\n if (!silent) {\n setIsValidating(false)\n }\n }\n }\n\n const handleValidateQuery = async () => {\n await runDryRunValidation(query)\n }\n\n const handleOpenQueryBuilder = () => {\n // Parse the current query and set it as the initial query for QueryBuilder\n const initialQuery = query ? (() => {\n try {\n return JSON.parse(query)\n } catch {\n return {}\n }\n })() : {}\n \n setQueryBuilderInitialQuery(initialQuery)\n setShowQueryBuilder(true)\n }\n\n\n const handleApplyQueryBuilderQuery = (e?: React.MouseEvent) => {\n e?.preventDefault()\n e?.stopPropagation()\n \n if (!queryBuilderRef.current) return\n \n // Get current query and validation state from QueryBuilder\n const currentQuery = queryBuilderRef.current.getCurrentQuery()\n const validationState = queryBuilderRef.current.getValidationState()\n const validationResult = queryBuilderRef.current.getValidationResult()\n \n // Apply the query to the form\n const formattedQuery = JSON.stringify(currentQuery, null, 2)\n setQuery(formattedQuery)\n \n // If QueryBuilder had a valid query, transfer the validation state and dry-run data\n if (validationState?.status === 'valid' && validationResult) {\n setValidationResult({ \n isValid: true, \n message: 'Query validated in Query Builder' \n })\n setLastValidatedQuery(formattedQuery)\n \n // Transfer the dry-run data from QueryBuilder validation result\n setDryRunData(validationResult)\n \n // Auto-populate chart config using the same logic as form validation\n autoPopulateChartConfig(validationResult)\n } else {\n // Reset validation state if query wasn't validated in QueryBuilder\n setValidationResult(null)\n setLastValidatedQuery('')\n setDryRunData(null)\n }\n \n // Return to form view to continue editing\n setShowQueryBuilder(false)\n }\n\n const handleBackToForm = () => {\n setShowQueryBuilder(false)\n setQueryBuilderInitialQuery(null)\n }\n\n const handleClose = () => {\n setFormTitle('')\n setQuery('')\n setChartType('bar')\n setChartConfig({ xAxis: [], yAxis: [], series: [] })\n setDisplayConfig({ showLegend: true, showGrid: true, showTooltip: true, stacked: false })\n setValidationResult(null)\n setIsValidating(false)\n setLastValidatedQuery('')\n setDryRunData(null)\n setShowQueryBuilder(false)\n setQueryBuilderInitialQuery(null)\n onClose()\n }\n\n const isEditMode = !!portlet\n const hasQueryChanged = query.trim() !== lastValidatedQuery.trim() && lastValidatedQuery !== ''\n const isQueryValidAndCurrent = validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n\n\n const availableFields = dryRunData?.pivotQuery?.query ? {\n dimensions: dryRunData.pivotQuery.query.dimensions || [],\n timeDimensions: dryRunData.pivotQuery.query.timeDimensions?.map((td: any) => td.dimension) || [],\n measures: dryRunData.pivotQuery.query.measures || []\n } : null\n\n\n const footer = showQueryBuilder ? (\n <>\n <button\n type=\"button\"\n onClick={handleBackToForm}\n className=\"px-4 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-none focus:ring-2 focus:ring-dc-primary\"\n >\n Back to Form\n </button>\n <button\n type=\"button\"\n onClick={handleApplyQueryBuilderQuery}\n className=\"px-4 py-2 text-sm font-medium border border-transparent rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n style={{ backgroundColor: 'var(--dc-primary)', color: '#ffffff' }}\n title=\"Apply query to form\"\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-primary-hover)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-primary)'}\n >\n Apply Query\n </button>\n </>\n ) : (\n <>\n <button\n type=\"button\"\n onClick={handleClose}\n className=\"px-4 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-none focus:ring-2 focus:ring-dc-primary\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n form=\"portlet-form\"\n className=\"px-4 py-2 text-sm font-medium border border-transparent rounded-md disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-blue-500\"\n style={{ backgroundColor: 'var(--dc-primary)', color: '#ffffff' }}\n disabled={shouldSkipQuery ? !formTitle.trim() : (!formTitle.trim() || !query.trim() || (hasQueryChanged || (lastValidatedQuery === '' && query.trim() !== '')))}\n title={!shouldSkipQuery && (hasQueryChanged || (lastValidatedQuery === '' && query.trim() !== '')) ? \"Please validate your query before saving\" : \"\"}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-primary-hover)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-primary)'}\n >\n {submitText}\n </button>\n </>\n )\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={showQueryBuilder ? \"Query Builder\" : title}\n size=\"fullscreen-mobile\"\n footer={footer}\n noPadding={showQueryBuilder}\n >\n {showQueryBuilder ? (\n <QueryBuilder\n ref={queryBuilderRef}\n initialQuery={queryBuilderInitialQuery}\n disableLocalStorage={true}\n hideSettings={true}\n className=\"flex-1 w-full\"\n />\n ) : (\n <form id=\"portlet-form\" onSubmit={handleSubmit} className=\"space-y-4\">\n {/* Main layout - Responsive: single column on mobile, two columns on desktop */}\n <div className=\"flex flex-col lg:flex-row gap-4\">\n {/* Left side - Title, Chart Type, Query */}\n <div className=\"flex-1 flex flex-col gap-4\">\n {/* Title */}\n <div>\n <label className=\"block text-sm font-semibold text-dc-text-secondary mb-1\">\n Title\n </label>\n <input\n type=\"text\"\n value={formTitle}\n onChange={(e) => setFormTitle(e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary\"\n placeholder=\"Enter portlet title...\"\n required\n />\n </div>\n\n {/* Chart Type */}\n <div>\n <label className=\"block text-sm font-semibold text-dc-text-secondary mb-3\">\n Chart Type\n </label>\n <ChartTypeSelector\n selectedType={chartType}\n onTypeChange={setChartType}\n />\n </div>\n\n\n {/* Query Editor - Hidden for skipQuery charts */}\n {!shouldSkipQuery && (\n <div className=\"flex-1 flex flex-col\">\n <div className=\"flex justify-between items-center mb-1\">\n <label className=\"block text-sm font-semibold text-dc-text-secondary\">\n Cube.js Query (JSON)\n </label>\n <div className=\"flex items-center space-x-2\">\n <button\n type=\"button\"\n onClick={handleOpenQueryBuilder}\n className=\"text-xs px-2 py-1 text-purple-600 dark:text-purple-300 bg-dc-surface hover:bg-purple-50 dark:hover:bg-purple-900/30 rounded-sm border border-purple-600 dark:border-purple-700 hover:border-purple-700 dark:hover:border-purple-600 focus:outline-none focus:ring-2 focus:ring-purple-500\"\n >\n Edit in Query Builder\n </button>\n </div>\n </div>\n <textarea\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n className=\"flex-1 w-full min-h-64 px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary font-mono text-xs resize-y\"\n placeholder={`{\n \"measures\": [\"People.count\"],\n \"dimensions\": [\"People.active\"]\n}`}\n required\n />\n </div>\n )}\n </div>\n\n {/* Right side - Chart Configuration */}\n <div className=\"flex-1 flex flex-col\">\n <label className=\"block text-sm font-semibold text-dc-text-secondary mb-1\">\n {shouldSkipQuery ? 'Chart Configuration' : 'Chart Axis Configuration'}\n </label>\n\n {shouldSkipQuery ? (\n <div className=\"rounded-lg bg-dc-surface p-3 border border-dc-border\">\n <ChartConfigPanel\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n availableFields={null}\n colorPalette={colorPalette}\n onChartConfigChange={setChartConfig}\n onDisplayConfigChange={setDisplayConfig}\n />\n </div>\n ) : (!dryRunData || !isQueryValidAndCurrent) ? (\n <div className=\"flex-1 flex items-center justify-center border-2 border-dashed border-dc-border rounded-lg bg-dc-surface-secondary\">\n <div className=\"text-center text-dc-text-muted\">\n <svg className=\"h-8 w-8 mx-auto mb-2\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" />\n </svg>\n <p className=\"text-sm\">Validate query first to configure chart axes</p>\n </div>\n </div>\n ) : (\n <div className=\"rounded-lg bg-dc-surface p-3 border border-dc-border\">\n <ChartConfigPanel\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n availableFields={availableFields}\n colorPalette={colorPalette}\n onChartConfigChange={setChartConfig}\n onDisplayConfigChange={setDisplayConfig}\n />\n </div>\n )}\n </div>\n </div>\n\n {/* Validation section - Hidden for skipQuery charts */}\n {!shouldSkipQuery && (hasQueryChanged || (lastValidatedQuery === '' && query.trim() !== '') || (validationResult && query.trim() === lastValidatedQuery.trim() && validationResult.message !== 'Loaded query (assumed valid)')) && (\n <div className={`rounded-lg p-4 ${\n validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'bg-green-50 dark:bg-green-900/30'\n : validationResult && !validationResult.isValid\n ? 'bg-red-50 dark:bg-red-900/30'\n : hasQueryChanged\n ? 'bg-amber-50 dark:bg-amber-900/30'\n : 'bg-dc-surface-secondary'\n }`}>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center space-x-3\">\n <div className={`w-2 h-2 rounded-full ${\n validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'bg-green-500'\n : validationResult && !validationResult.isValid\n ? 'bg-red-500'\n : hasQueryChanged\n ? 'bg-amber-500'\n : 'bg-gray-400'\n }`}></div>\n <div>\n <h3 className={`text-sm font-medium ${\n validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'text-green-800 dark:text-green-300'\n : validationResult && !validationResult.isValid\n ? 'text-red-800 dark:text-red-300'\n : hasQueryChanged\n ? 'text-amber-800 dark:text-amber-300'\n : 'text-dc-text-secondary'\n }`}>\n {validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'Query validated successfully'\n : validationResult && !validationResult.isValid\n ? 'Query validation failed'\n : hasQueryChanged\n ? 'Query modified - validation required'\n : 'Query validation required'\n }\n </h3>\n {validationResult && (\n <p className={`text-xs mt-1 ${\n validationResult.isValid ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'\n }`}>\n {validationResult.message}\n </p>\n )}\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={handleValidateQuery}\n disabled={isValidating || !query.trim()}\n className={`px-3 py-1.5 text-sm font-medium rounded-md transition-colors flex items-center space-x-1.5 ${\n validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'bg-green-600 text-white hover:bg-green-700'\n : validationResult && !validationResult.isValid\n ? 'bg-red-600 text-white hover:bg-red-700'\n : 'bg-dc-primary text-white hover:bg-dc-primary-hover'\n } disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-dc-primary`}\n >\n {isValidating ? (\n <>\n <svg className=\"animate-spin h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span>Validating</span>\n </>\n ) : validationResult?.isValid && query.trim() === lastValidatedQuery.trim() ? (\n <>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <span>Validated</span>\n </>\n ) : (\n <>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <span>Validate</span>\n </>\n )}\n </button>\n </div>\n </div>\n )}\n\n {/* Sample Queries - only show for create mode */}\n {!isEditMode && (\n <div>\n <label className=\"block text-sm text-dc-text-muted mb-2\">Sample Queries (click to use)</label>\n <div className=\"flex flex-wrap gap-2 mb-2\">\n {SAMPLE_QUERIES.map((sample, index) => (\n <button\n key={index}\n type=\"button\"\n onClick={() => handleSampleQuery(sample.query)}\n className=\"px-2 py-1 text-xs text-dc-text-secondary bg-dc-surface-secondary border border-dc-border rounded-sm cursor-pointer transition-all duration-200 ease-in-out hover:bg-dc-surface-hover hover:border-dc-border m-0.5\"\n >\n {sample.name}\n </button>\n ))}\n </div>\n </div>\n )}\n </form>\n )}\n </Modal>\n )\n}","/**\n * Portlet Filter Configuration Modal\n * Allows users to configure which dashboard filters apply to a specific portlet\n */\n\nimport { useState, useEffect } from 'react'\nimport type { DashboardFilter } from '../types'\n\ninterface PortletFilterConfigModalProps {\n isOpen: boolean\n onClose: () => void\n dashboardFilters: DashboardFilter[]\n currentMapping: string[]\n onSave: (mapping: string[]) => void\n portletTitle: string\n}\n\nexport default function PortletFilterConfigModal({\n isOpen,\n onClose,\n dashboardFilters = [],\n currentMapping = [],\n onSave,\n portletTitle\n}: PortletFilterConfigModalProps) {\n const [selectedFilters, setSelectedFilters] = useState<string[]>(currentMapping)\n\n // Update local state when props change\n useEffect(() => {\n setSelectedFilters(currentMapping)\n }, [currentMapping, isOpen])\n\n const handleToggleFilter = (filterId: string) => {\n setSelectedFilters(prev => {\n if (prev.includes(filterId)) {\n return prev.filter(id => id !== filterId)\n } else {\n return [...prev, filterId]\n }\n })\n }\n\n const handleSave = () => {\n onSave(selectedFilters)\n onClose()\n }\n\n const handleCancel = () => {\n setSelectedFilters(currentMapping) // Reset to original\n onClose()\n }\n\n // Format filter preview text\n const formatFilterPreview = (filter: DashboardFilter): string => {\n if (!filter.filter) return ''\n\n // Handle simple filters\n if ('member' in filter.filter && filter.filter.member) {\n const values = filter.filter.values || []\n const valuesText = values.length > 0 ? values.join(', ') : 'no value'\n return `${filter.filter.member} ${filter.filter.operator} ${valuesText}`\n }\n\n // Handle group filters (AND/OR)\n if ('type' in filter.filter && filter.filter.type) {\n const filterCount = filter.filter.filters?.length || 0\n return `${filter.filter.type.toUpperCase()} group with ${filterCount} filter${filterCount !== 1 ? 's' : ''}`\n }\n\n return 'Complex filter'\n }\n\n if (!isOpen) return null\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50\" onClick={handleCancel}>\n <div\n className=\"bg-dc-surface border border-dc-border rounded-lg max-w-2xl w-full mx-4 max-h-[80vh] flex flex-col\"\n style={{ boxShadow: 'var(--dc-shadow-lg)' }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"px-6 py-4 border-b border-dc-border bg-dc-surface-secondary rounded-t-lg\">\n <h2 className=\"text-lg font-semibold text-dc-text\">Configure Dashboard Filters</h2>\n <p className=\"text-sm text-dc-text-secondary mt-1\">\n Choose which dashboard filters apply to \"{portletTitle}\"\n </p>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-y-auto px-6 py-4\">\n {dashboardFilters.length === 0 ? (\n <div className=\"text-center py-8 text-dc-text-muted\">\n <svg\n className=\"mx-auto h-12 w-12 mb-3\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z\"\n />\n </svg>\n <p className=\"text-sm font-medium\">No dashboard filters available</p>\n <p className=\"text-xs mt-1\">Add filters at the dashboard level first</p>\n </div>\n ) : (\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between mb-4 pb-2 border-b border-dc-border\">\n <span className=\"text-sm font-medium text-dc-text\">Available Filters</span>\n <span className=\"text-xs text-dc-text-secondary\">\n {selectedFilters.length} of {dashboardFilters.length} selected\n </span>\n </div>\n\n {dashboardFilters.map(filter => {\n const isSelected = selectedFilters.includes(filter.id)\n\n return (\n <label\n key={filter.id}\n className={`flex items-start p-3 rounded-md border cursor-pointer transition-colors ${\n isSelected\n ? 'border-dc-primary bg-dc-surface-secondary'\n : 'border-dc-border hover:bg-dc-surface-hover'\n }`}\n >\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={() => handleToggleFilter(filter.id)}\n className=\"mt-0.5 mr-3 h-4 w-4 rounded border-dc-border focus:ring-2 focus:ring-dc-primary\"\n style={{\n accentColor: 'var(--dc-primary)'\n }}\n />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-sm text-dc-text truncate\">\n {filter.label}\n </span>\n {isSelected && (\n <span\n className=\"px-2 py-0.5 text-xs rounded-full\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n Applied\n </span>\n )}\n </div>\n <div className=\"mt-1 text-xs text-dc-text-secondary break-words\">\n {formatFilterPreview(filter)}\n </div>\n </div>\n </label>\n )\n })}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"px-6 py-4 border-t border-dc-border bg-dc-surface-secondary rounded-b-lg flex justify-end gap-3\">\n <button\n onClick={handleCancel}\n className=\"px-4 py-2 text-sm font-medium rounded-md border border-dc-border bg-dc-surface hover:bg-dc-surface-hover transition-colors text-dc-text\"\n >\n Cancel\n </button>\n <button\n onClick={handleSave}\n className=\"px-4 py-2 text-sm font-medium rounded-md text-white transition-colors\"\n style={{\n backgroundColor: 'var(--dc-primary)'\n }}\n >\n Apply Filters\n </button>\n </div>\n </div>\n </div>\n )\n}\n","import { useState, useEffect } from 'react'\n\ninterface DebugModalProps {\n chartConfig: any\n displayConfig: any\n queryObject: any\n data: any[]\n chartType: string\n}\n\nexport default function DebugModal({ \n chartConfig, \n displayConfig, \n queryObject, \n data, \n chartType \n}: DebugModalProps) {\n const [isOpen, setIsOpen] = useState(false)\n\n // Handle ESC key to close modal\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && isOpen) {\n setIsOpen(false)\n }\n }\n\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [isOpen])\n\n // Trigger Prism highlighting when modal opens and content is rendered\n useEffect(() => {\n if (isOpen && typeof window !== 'undefined' && (window as any).Prism) {\n // Small delay to ensure DOM is updated\n const timer = setTimeout(() => {\n (window as any).Prism.highlightAll()\n }, 10)\n \n return () => clearTimeout(timer)\n }\n }, [isOpen])\n\n\n if (!isOpen) {\n return (\n <button\n onClick={() => setIsOpen(true)}\n className=\"p-1 text-dc-text-muted hover:text-dc-text-secondary transition-colors\"\n title=\"Debug chart configuration\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\n </svg>\n </button>\n )\n }\n\n return (\n <div\n className=\"absolute inset-0 bg-dc-surface border border-dc-border rounded-lg z-50 overflow-auto\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"p-4 h-full flex flex-col\">\n <div className=\"flex justify-between items-center mb-4 shrink-0\">\n <h2 className=\"text-lg font-semibold text-dc-text\">Chart Debug Information</h2>\n <button\n onClick={() => setIsOpen(false)}\n className=\"p-2 text-dc-text-muted hover:text-dc-text-secondary hover:bg-dc-surface-secondary rounded-sm\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4 flex-1 overflow-auto\">\n <div>\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Chart Type</h3>\n <div className=\"bg-dc-surface-secondary p-2 rounded-sm text-sm font-mono border border-dc-border\">\n {chartType}\n </div>\n </div>\n\n <div>\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Field Analysis</h3>\n <div className=\"bg-dc-surface-secondary p-2 rounded-sm text-xs space-y-1 border border-dc-border\">\n <div>\n <strong>xAxis:</strong> {Array.isArray(chartConfig?.xAxis) ? `Array: [${chartConfig.xAxis.join(', ')}]` : `String: \"${chartConfig?.xAxis}\"`}\n </div>\n <div>\n <strong>yAxis:</strong> {Array.isArray(chartConfig?.yAxis) ? `Array: [${chartConfig.yAxis.join(', ')}]` : `String: \"${chartConfig?.yAxis}\"`}\n </div>\n <div>\n <strong>series:</strong> {Array.isArray(chartConfig?.series) ? `Array: [${chartConfig.series.join(', ')}]` : `String: \"${chartConfig?.series}\"`}\n </div>\n {chartConfig?.sizeField && (\n <div>\n <strong>sizeField:</strong> {Array.isArray(chartConfig?.sizeField) ? `Array: [${chartConfig.sizeField.join(', ')}]` : `String: \"${chartConfig?.sizeField}\"`}\n </div>\n )}\n {chartConfig?.colorField && (\n <div>\n <strong>colorField:</strong> {Array.isArray(chartConfig?.colorField) ? `Array: [${chartConfig.colorField.join(', ')}]` : `String: \"${chartConfig?.colorField}\"`}\n </div>\n )}\n </div>\n </div>\n\n <div className=\"lg:col-span-2\">\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Chart Config</h3>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border\" style={{ fontSize: '10px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(chartConfig, null, 2)}</code>\n </pre>\n </div>\n\n <div className=\"lg:col-span-2\">\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Display Config</h3>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border\" style={{ fontSize: '10px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(displayConfig, null, 2)}</code>\n </pre>\n </div>\n\n <div className=\"lg:col-span-2\">\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Query Object</h3>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border\" style={{ fontSize: '10px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(queryObject, null, 2)}</code>\n </pre>\n </div>\n\n <div className=\"lg:col-span-2\">\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Data Sample (first 3 rows)</h3>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border\" style={{ fontSize: '10px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(data?.slice(0, 3) || [], null, 2)}</code>\n </pre>\n </div>\n </div>\n\n <div className=\"mt-4 pt-2 border-t border-dc-border text-xs text-dc-text-muted shrink-0\">\n Press <kbd className=\"px-1 py-0.5 bg-dc-surface-secondary rounded-sm text-xs\">ESC</kbd> to close\n </div>\n </div>\n </div>\n )\n}","/**\n * Unified Color Palette System\n * Each palette contains coordinated series and gradient colors that work well together\n */\n\nexport interface ColorPalette {\n name: string\n label: string\n colors: string[] // For series-based charts (bar, line, pie, area, scatter, radar, etc.)\n gradient: string[] // For gradient-based charts (bubble, activity grid)\n}\n\n// Predefined color palettes with visually coordinated series and gradient colors\nexport const COLOR_PALETTES: ColorPalette[] = [\n {\n name: 'default',\n label: 'Default',\n colors: [\n '#3b82f6', // blue\n '#10b981', // green\n '#f59e0b', // yellow\n '#ef4444', // red\n '#8b5cf6', // purple\n '#f97316', // orange\n '#06b6d4', // cyan\n '#84cc16', // lime\n ],\n gradient: [\n '#440154', // dark purple\n '#414487', // purple-blue\n '#2a788e', // teal\n '#22a884', // green-teal \n '#7ad151', // green\n '#fde725', // yellow\n ]\n },\n {\n name: 'ocean',\n label: 'Ocean',\n colors: [\n '#1e3a8a', // deep blue\n '#1e40af', // blue\n '#2563eb', // bright blue\n '#3b82f6', // light blue\n '#06b6d4', // cyan\n '#0891b2', // dark cyan\n '#0e7490', // teal\n '#0f766e', // dark teal\n ],\n gradient: [\n '#0c4a6e', // very dark blue\n '#075985', // dark blue\n '#0369a1', // medium blue\n '#0284c7', // bright blue\n '#0ea5e9', // light blue\n '#38bdf8', // cyan blue\n ]\n },\n {\n name: 'sunset',\n label: 'Sunset',\n colors: [\n '#dc2626', // red\n '#ea580c', // orange-red\n '#f59e0b', // orange\n '#eab308', // yellow-orange\n '#d97706', // amber\n '#b45309', // dark amber\n '#92400e', // brown\n '#7c2d12', // dark brown\n ],\n gradient: [\n '#7c2d12', // dark brown\n '#92400e', // brown\n '#b45309', // dark amber\n '#d97706', // amber\n '#f59e0b', // orange\n '#fbbf24', // light orange\n ]\n },\n {\n name: 'forest',\n label: 'Forest',\n colors: [\n '#166534', // dark green\n '#15803d', // green\n '#16a34a', // bright green\n '#22c55e', // light green\n '#4ade80', // lighter green\n '#65a30d', // lime green\n '#84cc16', // lime\n '#a3e635', // light lime\n ],\n gradient: [\n '#14532d', // very dark green\n '#166534', // dark green\n '#15803d', // green\n '#16a34a', // bright green\n '#22c55e', // light green\n '#4ade80', // lighter green\n ]\n },\n {\n name: 'purple',\n label: 'Purple',\n colors: [\n '#581c87', // dark purple\n '#7c3aed', // purple\n '#8b5cf6', // bright purple\n '#a855f7', // light purple\n '#c084fc', // lighter purple\n '#e879f9', // magenta\n '#f0abfc', // light magenta\n '#fbbf24', // accent yellow\n ],\n gradient: [\n '#4c1d95', // very dark purple\n '#581c87', // dark purple\n '#6d28d9', // medium purple\n '#7c3aed', // purple\n '#8b5cf6', // bright purple\n '#a855f7', // light purple\n ]\n },\n {\n name: 'monochrome',\n label: 'Monochrome',\n colors: [\n '#1f2937', // very dark gray\n '#374151', // dark gray\n '#4b5563', // medium gray\n '#6b7280', // gray\n '#9ca3af', // light gray\n '#d1d5db', // lighter gray\n '#e5e7eb', // very light gray\n '#f3f4f6', // almost white\n ],\n gradient: [\n '#111827', // black\n '#1f2937', // very dark gray\n '#374151', // dark gray\n '#4b5563', // medium gray\n '#6b7280', // gray\n '#9ca3af', // light gray\n ]\n },\n {\n name: 'pastel',\n label: 'Pastel',\n colors: [\n '#93c5fd', // light blue\n '#86efac', // light green\n '#fde047', // light yellow\n '#fca5a5', // light red\n '#c4b5fd', // light purple\n '#fdba74', // light orange\n '#67e8f9', // light cyan\n '#bef264', // light lime\n ],\n gradient: [\n '#bfdbfe', // very light blue\n '#a7f3d0', // very light green\n '#fef08a', // very light yellow\n '#fecaca', // very light red\n '#ddd6fe', // very light purple\n '#fed7aa', // very light orange\n ]\n },\n {\n name: 'vibrant',\n label: 'Vibrant',\n colors: [\n '#0000ff', // pure blue\n '#00ff00', // pure green\n '#ffff00', // pure yellow\n '#ff0000', // pure red\n '#ff00ff', // pure magenta\n '#ff8000', // pure orange\n '#00ffff', // pure cyan\n '#8000ff', // pure violet\n ],\n gradient: [\n '#4000ff', // blue-violet\n '#0080ff', // blue\n '#00ffff', // cyan\n '#00ff80', // green\n '#80ff00', // lime\n '#ffff00', // yellow\n ]\n },\n {\n name: 'd3Category10',\n label: 'D3 Category 10',\n colors: [\n '#1f77b4', // blue\n '#ff7f0e', // orange\n '#2ca02c', // green\n '#d62728', // red\n '#9467bd', // purple\n '#8c564b', // brown\n '#e377c2', // pink\n '#7f7f7f', // gray\n '#bcbd22', // olive\n '#17becf', // cyan\n ],\n gradient: [\n '#1f77b4', // blue\n '#2ca02c', // green\n '#bcbd22', // olive\n '#ff7f0e', // orange\n '#d62728', // red\n '#9467bd', // purple\n ]\n },\n {\n name: 'd3Tableau10',\n label: 'D3 Tableau 10',\n colors: [\n '#4e79a7', // blue\n '#f28e2c', // orange\n '#e15759', // red\n '#76b7b2', // teal\n '#59a14f', // green\n '#edc949', // yellow\n '#af7aa1', // purple\n '#ff9da7', // pink\n '#9c755f', // brown\n '#bab0ab', // gray\n ],\n gradient: [\n '#4e79a7', // blue\n '#76b7b2', // teal\n '#59a14f', // green\n '#edc949', // yellow\n '#f28e2c', // orange\n '#e15759', // red\n ]\n },\n {\n name: 'colorBrewerSet1',\n label: 'ColorBrewer Set 1',\n colors: [\n '#e41a1c', // red\n '#377eb8', // blue\n '#4daf4a', // green\n '#984ea3', // purple\n '#ff7f00', // orange\n '#ffff33', // yellow\n '#a65628', // brown\n '#f781bf', // pink\n '#999999', // gray\n ],\n gradient: [\n '#377eb8', // blue\n '#4daf4a', // green\n '#ffff33', // yellow\n '#ff7f00', // orange\n '#e41a1c', // red\n '#984ea3', // purple\n ]\n },\n {\n name: 'colorBrewerSet2',\n label: 'ColorBrewer Set 2',\n colors: [\n '#66c2a5', // teal\n '#fc8d62', // orange\n '#8da0cb', // blue\n '#e78ac3', // pink\n '#a6d854', // lime\n '#ffd92f', // yellow\n '#e5c494', // tan\n '#b3b3b3', // gray\n ],\n gradient: [\n '#8da0cb', // blue\n '#66c2a5', // teal\n '#a6d854', // lime\n '#ffd92f', // yellow\n '#fc8d62', // orange\n '#e78ac3', // pink\n ]\n },\n {\n name: 'colorBrewerDark2',\n label: 'ColorBrewer Dark 2',\n colors: [\n '#1b9e77', // dark teal\n '#d95f02', // dark orange\n '#7570b3', // dark blue\n '#e7298a', // dark pink\n '#66a61e', // dark green\n '#e6ab02', // dark yellow\n '#a6761d', // dark brown\n '#666666', // dark gray\n ],\n gradient: [\n '#7570b3', // dark blue\n '#1b9e77', // dark teal\n '#66a61e', // dark green\n '#e6ab02', // dark yellow\n '#d95f02', // dark orange\n '#e7298a', // dark pink\n ]\n },\n {\n name: 'colorBrewerPaired',\n label: 'ColorBrewer Paired',\n colors: [\n '#a6cee3', // light blue\n '#1f78b4', // blue\n '#b2df8a', // light green\n '#33a02c', // green\n '#fb9a99', // light red\n '#e31a1c', // red\n '#fdbf6f', // light orange\n '#ff7f00', // orange\n '#cab2d6', // light purple\n '#6a3d9a', // purple\n '#ffff99', // light yellow\n '#b15928', // brown\n ],\n gradient: [\n '#1f78b4', // blue\n '#33a02c', // green\n '#ffff99', // light yellow\n '#ff7f00', // orange\n '#e31a1c', // red\n '#6a3d9a', // purple\n ]\n },\n {\n name: 'viridis',\n label: 'Viridis',\n colors: [\n '#440154', // dark purple\n '#482677', // purple\n '#3f4a8a', // blue-purple\n '#31678e', // blue\n '#26838f', // teal\n '#1f9d8a', // green-teal\n '#6cce5a', // green\n '#b6de2b', // yellow-green\n ],\n gradient: [\n '#440154', // dark purple\n '#482677', // purple\n '#3f4a8a', // blue-purple\n '#31678e', // blue\n '#26838f', // teal\n '#1f9d8a', // green-teal\n '#6cce5a', // green\n '#b6de2b', // yellow-green\n ]\n },\n {\n name: 'plasma',\n label: 'Plasma',\n colors: [\n '#0c0786', // dark blue\n '#5c01a6', // purple\n '#900da4', // magenta\n '#bf3984', // pink\n '#e16462', // coral\n '#f99b45', // orange\n '#fcce25', // yellow\n '#f0f921', // bright yellow\n ],\n gradient: [\n '#0c0786', // dark blue\n '#5c01a6', // purple\n '#900da4', // magenta\n '#bf3984', // pink\n '#e16462', // coral\n '#f99b45', // orange\n '#fcce25', // yellow\n '#f0f921', // bright yellow\n ]\n },\n {\n name: 'inferno',\n label: 'Inferno',\n colors: [\n '#000003', // black\n '#1f0c47', // dark blue\n '#550f6d', // purple\n '#88226a', // magenta\n '#a83655', // red\n '#cc4f39', // orange-red\n '#e6862a', // orange\n '#fec228', // yellow\n ],\n gradient: [\n '#000003', // black\n '#1f0c47', // dark blue\n '#550f6d', // purple\n '#88226a', // magenta\n '#a83655', // red\n '#cc4f39', // orange-red\n '#e6862a', // orange\n '#fec228', // yellow\n ]\n },\n {\n name: 'magma',\n label: 'Magma',\n colors: [\n '#000003', // black\n '#140b34', // dark purple\n '#3b0f6f', // purple\n '#641a80', // magenta\n '#8b2981', // pink\n '#b63679', // coral\n '#de4968', // red\n '#fd9f6c', // orange\n ],\n gradient: [\n '#000003', // black\n '#140b34', // dark purple\n '#3b0f6f', // purple\n '#641a80', // magenta\n '#8b2981', // pink\n '#b63679', // coral\n '#de4968', // red\n '#fd9f6c', // orange\n ]\n },\n {\n name: 'cividis',\n label: 'Cividis',\n colors: [\n '#00204c', // dark blue\n '#003f5c', // blue\n '#2c4b7a', // blue\n '#51576f', // blue-gray\n '#7f6874', // gray\n '#a8786e', // brown\n '#d2906d', // orange\n '#ffb570', // yellow\n ],\n gradient: [\n '#00204c', // dark blue\n '#003f5c', // blue\n '#2c4b7a', // blue\n '#51576f', // blue-gray\n '#7f6874', // gray\n '#a8786e', // brown\n '#d2906d', // orange\n '#ffb570', // yellow\n ]\n },\n {\n name: 'turbo',\n label: 'Turbo',\n colors: [\n '#30123b', // purple\n '#4454c4', // blue\n '#1dd3c0', // cyan\n '#42f465', // green\n '#b2df22', // lime\n '#faba39', // yellow\n '#f66c19', // orange\n '#c42e02', // red\n ],\n gradient: [\n '#30123b', // purple\n '#4454c4', // blue\n '#1dd3c0', // cyan\n '#42f465', // green\n '#b2df22', // lime\n '#faba39', // yellow\n '#f66c19', // orange\n '#c42e02', // red\n ]\n },\n {\n name: 'warm',\n label: 'Warm',\n colors: [\n '#8b0000', // dark red\n '#b22222', // red\n '#cd5c5c', // light red\n '#ff6347', // tomato\n '#ff8c00', // dark orange\n '#ffa500', // orange\n '#ffd700', // gold\n '#ffff00', // yellow\n ],\n gradient: [\n '#8b0000', // dark red\n '#b22222', // red\n '#ff6347', // tomato\n '#ff8c00', // dark orange\n '#ffa500', // orange\n '#ffd700', // gold\n ]\n },\n {\n name: 'cool',\n label: 'Cool',\n colors: [\n '#000080', // navy\n '#0000ff', // blue\n '#4169e1', // royal blue\n '#00bfff', // deep sky blue\n '#00ffff', // cyan\n '#40e0d0', // turquoise\n '#20b2aa', // light sea green\n '#008b8b', // dark cyan\n ],\n gradient: [\n '#000080', // navy\n '#0000ff', // blue\n '#4169e1', // royal blue\n '#00bfff', // deep sky blue\n '#00ffff', // cyan\n '#40e0d0', // turquoise\n ]\n },\n {\n name: 'earth',\n label: 'Earth',\n colors: [\n '#8b4513', // saddle brown\n '#a0522d', // sienna\n '#cd853f', // peru\n '#daa520', // goldenrod\n '#d2691e', // chocolate\n '#bc8f8f', // rosy brown\n '#f4a460', // sandy brown\n '#deb887', // burlywood\n ],\n gradient: [\n '#8b4513', // saddle brown\n '#a0522d', // sienna\n '#cd853f', // peru\n '#daa520', // goldenrod\n '#d2691e', // chocolate\n '#f4a460', // sandy brown\n ]\n },\n {\n name: 'autumn',\n label: 'Autumn',\n colors: [\n '#8b0000', // dark red\n '#a0522d', // sienna\n '#cd853f', // peru\n '#daa520', // goldenrod\n '#ff8c00', // dark orange\n '#ff4500', // orange red\n '#dc143c', // crimson\n '#b22222', // fire brick\n ],\n gradient: [\n '#8b0000', // dark red\n '#a0522d', // sienna\n '#cd853f', // peru\n '#daa520', // goldenrod\n '#ff8c00', // dark orange\n '#ff4500', // orange red\n ]\n },\n {\n name: 'spring',\n label: 'Spring',\n colors: [\n '#32cd32', // lime green\n '#98fb98', // pale green\n '#90ee90', // light green\n '#ffb6c1', // light pink\n '#ffc0cb', // pink\n '#ffffe0', // light yellow\n '#f0fff0', // honeydew\n '#e0ffff', // light cyan\n ],\n gradient: [\n '#32cd32', // lime green\n '#98fb98', // pale green\n '#ffffe0', // light yellow\n '#ffb6c1', // light pink\n '#ffc0cb', // pink\n '#e0ffff', // light cyan\n ]\n },\n {\n name: 'winter',\n label: 'Winter',\n colors: [\n '#191970', // midnight blue\n '#4682b4', // steel blue\n '#87ceeb', // sky blue\n '#b0e0e6', // powder blue\n '#e0ffff', // light cyan\n '#f0f8ff', // alice blue\n '#c0c0c0', // silver\n '#708090', // slate gray\n ],\n gradient: [\n '#191970', // midnight blue\n '#4682b4', // steel blue\n '#87ceeb', // sky blue\n '#b0e0e6', // powder blue\n '#e0ffff', // light cyan\n '#f0f8ff', // alice blue\n ]\n },\n {\n name: 'neon',\n label: 'Neon',\n colors: [\n '#ff0080', // neon pink\n '#00ff80', // neon green\n '#8000ff', // neon purple\n '#ff8000', // neon orange\n '#0080ff', // neon blue\n '#80ff00', // neon lime\n '#ff0040', // neon red\n '#40ff00', // bright green\n ],\n gradient: [\n '#8000ff', // neon purple\n '#0080ff', // neon blue\n '#00ff80', // neon green\n '#80ff00', // neon lime\n '#ff8000', // neon orange\n '#ff0080', // neon pink\n ]\n },\n {\n name: 'retro',\n label: 'Retro',\n colors: [\n '#ff69b4', // hot pink\n '#ffd700', // gold\n '#32cd32', // lime green\n '#00ced1', // dark turquoise\n '#ff6347', // tomato\n '#9370db', // medium purple\n '#ffa500', // orange\n '#20b2aa', // light sea green\n ],\n gradient: [\n '#9370db', // medium purple\n '#ff69b4', // hot pink\n '#ff6347', // tomato\n '#ffd700', // gold\n '#32cd32', // lime green\n '#00ced1', // dark turquoise\n ]\n },\n {\n name: 'corporate',\n label: 'Corporate',\n colors: [\n '#003366', // dark blue\n '#0066cc', // blue\n '#336699', // steel blue\n '#6699cc', // light blue\n '#4d4d4d', // dark gray\n '#808080', // gray\n '#b3b3b3', // light gray\n '#cccccc', // very light gray\n ],\n gradient: [\n '#003366', // dark blue\n '#0066cc', // blue\n '#336699', // steel blue\n '#6699cc', // light blue\n '#808080', // gray\n '#b3b3b3', // light gray\n ]\n },\n {\n name: 'material',\n label: 'Material Design',\n colors: [\n '#f44336', // red\n '#e91e63', // pink\n '#9c27b0', // purple\n '#673ab7', // deep purple\n '#3f51b5', // indigo\n '#2196f3', // blue\n '#03a9f4', // light blue\n '#00bcd4', // cyan\n ],\n gradient: [\n '#673ab7', // deep purple\n '#3f51b5', // indigo\n '#2196f3', // blue\n '#00bcd4', // cyan\n '#03a9f4', // light blue\n '#e91e63', // pink\n ]\n }\n]\n\n/**\n * Get a color palette by name, with fallback to default\n */\nexport function getColorPalette(paletteName?: string): ColorPalette {\n if (!paletteName) {\n return COLOR_PALETTES[0] // default palette\n }\n \n const palette = COLOR_PALETTES.find(p => p.name === paletteName)\n return palette || COLOR_PALETTES[0] // fallback to default\n}\n\n/**\n * Get just the series colors for a palette\n */\nexport function getSeriesColors(paletteName?: string): string[] {\n return getColorPalette(paletteName).colors\n}\n\n/**\n * Get just the gradient colors for a palette\n */\nexport function getGradientColors(paletteName?: string): string[] {\n return getColorPalette(paletteName).gradient\n}\n\n/**\n * Chart types that use series colors (discrete categories)\n */\nexport const SERIES_CHART_TYPES = [\n 'bar', 'line', 'area', 'pie', 'scatter', 'radar', 'radialBar', 'treeMap'\n] as const\n\n/**\n * Chart types that use gradient colors (continuous values)\n */\nexport const GRADIENT_CHART_TYPES = [\n 'bubble', 'activityGrid'\n] as const\n\n/**\n * Determine if a chart type uses gradient colors\n */\nexport function usesGradientColors(chartType: string): boolean {\n return GRADIENT_CHART_TYPES.includes(chartType as any)\n}","/**\n * Color Palette Selector Component\n * Allows users to select from predefined color palettes for their dashboard\n */\n\nimport { useState, useRef, useEffect } from 'react'\nimport { COLOR_PALETTES, getColorPalette } from '../utils/colorPalettes'\nimport { getIcon } from '../icons'\n\nconst ChevronDownIcon = getIcon('chevronDown')\n\ninterface ColorPaletteSelectorProps {\n currentPalette?: string\n onPaletteChange: (paletteName: string) => void\n className?: string\n}\n\nexport default function ColorPaletteSelector({\n currentPalette = 'default',\n onPaletteChange,\n className = ''\n}: ColorPaletteSelectorProps) {\n const [isOpen, setIsOpen] = useState(false)\n const dropdownRef = useRef<HTMLDivElement>(null)\n \n const currentPaletteObj = getColorPalette(currentPalette)\n\n // Close dropdown when clicking outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen])\n\n const handlePaletteSelect = (paletteName: string) => {\n onPaletteChange(paletteName)\n setIsOpen(false)\n }\n\n return (\n <div className={`relative ${className}`} ref={dropdownRef}>\n {/* Trigger Button */}\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n className=\"inline-flex items-center gap-2 px-3 py-1.5 bg-dc-surface border border-dc-border rounded-md shadow-xs text-sm font-medium text-dc-text-secondary hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-blue-500\"\n >\n {/* Current Palette Preview - Hidden on mobile */}\n <div className=\"hidden md:flex items-center gap-1.5\">\n <div className=\"flex gap-0.5\">\n {currentPaletteObj.colors.slice(0, 4).map((color, index) => (\n <div\n key={index}\n className=\"w-3 h-3 rounded-xs border border-dc-border\"\n style={{ backgroundColor: color }}\n title={`Series Color ${index + 1}`}\n />\n ))}\n </div>\n <span className=\"text-xs text-dc-text-secondary\">|</span>\n <div className=\"flex gap-0.5\">\n {currentPaletteObj.gradient.slice(0, 3).map((color, index) => (\n <div\n key={index}\n className=\"w-2 h-3 border-r first:rounded-l-sm last:rounded-r-sm last:border-r-0\"\n style={{\n backgroundColor: color,\n borderColor: 'var(--dc-border)'\n }}\n title={`Gradient Color ${index + 1}`}\n />\n ))}\n </div>\n </div>\n <span>{currentPaletteObj.label}</span>\n <ChevronDownIcon \n className={`w-4 h-4 transition-transform ${isOpen ? 'rotate-180' : ''}`} \n />\n </button>\n\n {/* Dropdown Menu - Responsive width */}\n {isOpen && (\n <div className=\"absolute top-full left-0 mt-1 w-72 md:w-80 lg:w-96 bg-dc-surface border border-dc-border rounded-md shadow-lg z-50 max-h-80 overflow-y-auto\">\n <div className=\"py-1\">\n {COLOR_PALETTES.slice().sort((a, b) => a.label.localeCompare(b.label)).map((palette) => (\n <button\n key={palette.name}\n type=\"button\"\n onClick={() => handlePaletteSelect(palette.name)}\n className={`w-full px-3 py-2 text-left text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${\n palette.name === currentPalette ? 'bg-dc-surface-secondary' : 'text-dc-text-secondary'\n }`}\n style={palette.name === currentPalette ? { color: 'var(--dc-primary)' } : undefined}\n >\n <div className=\"flex items-center gap-3\">\n {/* Palette Preview - Hidden on mobile */}\n <div className=\"hidden md:flex items-center gap-2\">\n {/* Series Colors */}\n <div className=\"flex gap-0.5\">\n {palette.colors.slice(0, 6).map((color, index) => (\n <div\n key={`series-${index}`}\n className=\"w-3 h-3 rounded-xs border border-dc-border\"\n style={{ backgroundColor: color }}\n />\n ))}\n </div>\n\n {/* Separator */}\n <div className=\"w-px h-4 bg-dc-border\" />\n \n {/* Gradient Colors */}\n <div className=\"flex\">\n {palette.gradient.map((color, index) => (\n <div\n key={`gradient-${index}`}\n className=\"w-2 h-4 first:rounded-l-sm last:rounded-r-sm\"\n style={{ backgroundColor: color }}\n />\n ))}\n </div>\n </div>\n \n {/* Palette Name */}\n <span className=\"font-medium\">{palette.label}</span>\n \n {/* Current Indicator */}\n {palette.name === currentPalette && (\n <div className=\"ml-auto\">\n <div className=\"w-2 h-2 rounded-full\" style={{ backgroundColor: 'var(--dc-primary)' }}></div>\n </div>\n )}\n </div>\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n )\n}","/**\n * FilterEditModal Component\n *\n * Modal for editing dashboard filter details including label, field, operator, and values\n *\n * Pattern: Self-contained modal with local state (matches PortletEditModal pattern)\n * - All editing state is local to the modal\n * - Changes only propagate on \"Done\" button click via onSave callback\n * - Cancel/close resets local state without saving\n */\n\nimport React, { useState, useCallback, useMemo, useEffect } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterBuilder from '../QueryBuilder/FilterBuilder'\n\nconst CloseIcon = getIcon('close')\nconst EyeIcon = getIcon('eye')\nconst EyeOffIcon = getIcon('eyeOff')\nimport DateRangeSelector from '../QueryBuilder/DateRangeSelector'\nimport CubeMetaExplorer from '../QueryBuilder/CubeMetaExplorer'\nimport { extractDashboardFields } from '../../utils/filterUtils'\nimport type { DashboardFilter, CubeMeta, Filter, DashboardConfig, SimpleFilter } from '../../types'\nimport type { MetaResponse } from '../QueryBuilder/types'\n\ninterface FilterEditModalProps {\n filter: DashboardFilter\n schema: CubeMeta | null\n dashboardConfig: DashboardConfig\n isOpen: boolean\n onSave: (filter: DashboardFilter) => void | Promise<void>\n onClose: () => void\n onDelete: () => void\n convertToMetaResponse: (cubeMeta: CubeMeta | null) => MetaResponse | null\n}\n\nconst FilterEditModal: React.FC<FilterEditModalProps> = ({\n filter,\n schema,\n dashboardConfig,\n isOpen,\n onSave,\n onClose,\n onDelete,\n convertToMetaResponse\n}) => {\n // Local state for editing - all changes stay local until \"Done\"\n const [localLabel, setLocalLabel] = useState(filter.label)\n const [localFilter, setLocalFilter] = useState(filter.filter)\n const [showAllFields, setShowAllFields] = useState(false)\n\n // Sync local state when filter prop changes or modal opens\n useEffect(() => {\n if (isOpen) {\n setLocalLabel(filter.label)\n setLocalFilter(filter.filter)\n }\n }, [filter, isOpen])\n\n // Extract fields used in dashboard\n const dashboardFields = useMemo(() => {\n return extractDashboardFields(dashboardConfig)\n }, [dashboardConfig])\n\n // Create filtered schema showing only dashboard fields\n const filteredSchema = useMemo<MetaResponse | null>(() => {\n if (!schema) return null\n\n if (showAllFields) {\n return convertToMetaResponse(schema)\n }\n\n const filteredCubes = schema.cubes\n .map(cube => {\n const cubeName = cube.name\n\n const filteredMeasures = cube.measures.filter(measure => {\n const fullName = measure.name.includes('.')\n ? measure.name\n : `${cubeName}.${measure.name}`\n return dashboardFields.measures.has(fullName)\n })\n\n const filteredDimensions = cube.dimensions.filter(dimension => {\n const fullName = dimension.name.includes('.')\n ? dimension.name\n : `${cubeName}.${dimension.name}`\n return dashboardFields.dimensions.has(fullName) ||\n dashboardFields.timeDimensions.has(fullName)\n })\n\n if (filteredMeasures.length > 0 || filteredDimensions.length > 0) {\n return {\n ...cube,\n measures: filteredMeasures,\n dimensions: filteredDimensions\n }\n }\n\n return null\n })\n .filter((cube): cube is NonNullable<typeof cube> => cube !== null)\n\n const filteredCubeMeta: CubeMeta = {\n ...schema,\n cubes: filteredCubes\n }\n\n return convertToMetaResponse(filteredCubeMeta)\n }, [schema, dashboardFields, showAllFields, convertToMetaResponse])\n\n // Extract the currently selected field to highlight it in the schema\n const selectedFieldInFilter = useMemo(() => {\n if ('member' in localFilter && localFilter.member) {\n return localFilter.member\n }\n return null\n }, [localFilter])\n\n // Handle label change - updates local state only\n const handleLabelChange = useCallback((newLabel: string) => {\n setLocalLabel(newLabel)\n }, [])\n\n // Handle filter changes from FilterBuilder - updates local state only\n const handleFilterBuilderChange = useCallback((filters: Filter[]) => {\n setLocalFilter(filters[0] || localFilter)\n }, [localFilter])\n\n // Handle field selection from schema explorer - updates local state only\n const handleFieldSelect = useCallback((fieldName: string) => {\n if ('member' in localFilter) {\n setLocalFilter({\n ...localFilter,\n member: fieldName,\n values: [] // Reset values when changing field\n })\n }\n }, [localFilter])\n\n // Handle date range change for universal time filters\n const handleDateRangeChange = useCallback((_timeDim: string, dateRange: string | string[]) => {\n if ('member' in localFilter) {\n setLocalFilter({\n ...localFilter,\n values: Array.isArray(dateRange) ? dateRange : [dateRange]\n } as SimpleFilter)\n }\n }, [localFilter])\n\n // Validate filter before saving\n const validateFilter = useCallback((): { isValid: boolean; message?: string } => {\n if (!localLabel.trim()) {\n return { isValid: false, message: 'Filter label is required' }\n }\n\n // Skip member validation for universal time filters (member is placeholder)\n if (!filter.isUniversalTime && 'member' in localFilter && !localFilter.member) {\n return { isValid: false, message: 'Please select a field for the filter' }\n }\n\n return { isValid: true }\n }, [localLabel, localFilter, filter.isUniversalTime])\n\n // Handle save - validate then call onSave with complete filter data\n const handleSave = useCallback(async () => {\n const validation = validateFilter()\n if (!validation.isValid) {\n alert(validation.message)\n return\n }\n\n const updatedFilter: DashboardFilter = {\n id: filter.id,\n label: localLabel,\n filter: localFilter,\n // Preserve isUniversalTime flag if present\n ...(filter.isUniversalTime && { isUniversalTime: true })\n }\n\n try {\n await onSave(updatedFilter)\n onClose()\n } catch (error) {\n console.error('Failed to save filter:', error)\n alert('Failed to save filter. Please try again.')\n }\n }, [filter.id, filter.isUniversalTime, localLabel, localFilter, validateFilter, onSave, onClose])\n\n // Handle cancel/close - reset local state\n const handleCancel = useCallback(() => {\n setLocalLabel(filter.label)\n setLocalFilter(filter.filter)\n onClose()\n }, [filter, onClose])\n\n return (\n <div\n className=\"fixed inset-0 z-50 backdrop-blur-md flex items-center justify-center p-2\"\n style={{ backgroundColor: 'var(--dc-overlay)' }}\n >\n <div\n className=\"rounded-lg max-w-7xl w-full h-[95vh] overflow-hidden flex flex-col bg-dc-surface border border-dc-border\"\n style={{ boxShadow: 'var(--dc-shadow-2xl)' }}\n >\n {/* Modal Header */}\n <div className=\"px-6 py-4 border-b border-dc-border flex items-center justify-between\">\n <div className=\"flex-1\">\n <label className=\"block text-sm font-medium mb-2 text-dc-text\">\n Filter Label\n </label>\n <input\n type=\"text\"\n value={localLabel}\n onChange={(e) => handleLabelChange(e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md text-sm bg-dc-surface-secondary text-dc-text\"\n placeholder=\"Enter filter label\"\n />\n </div>\n <button\n onClick={handleCancel}\n className=\"ml-4 p-2 hover:bg-dc-surface-hover rounded-md transition-colors text-dc-text-secondary\"\n >\n <CloseIcon className=\"w-5 h-5\" />\n </button>\n </div>\n\n {/* Modal Body - Two Column Layout (or single column for universal time filters) */}\n <div className=\"flex-1 overflow-hidden flex\">\n {/* Left Column - Schema Explorer (hidden for universal time filters) */}\n {!filter.isUniversalTime && (\n <div className=\"w-80 border-r border-dc-border bg-dc-surface overflow-auto\">\n <div className=\"p-4\">\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-semibold text-dc-text\">\n Available Fields\n </h3>\n <button\n onClick={() => setShowAllFields(!showAllFields)}\n className=\"flex items-center gap-1 text-xs px-2 py-1 rounded hover:bg-dc-surface-hover text-dc-text-muted\"\n title={showAllFields ? 'Show dashboard fields only' : 'Show all fields'}\n >\n {showAllFields ? (\n <>\n <EyeOffIcon className=\"w-3.5 h-3.5\" />\n <span>Dashboard</span>\n </>\n ) : (\n <>\n <EyeIcon className=\"w-3.5 h-3.5\" />\n <span>All</span>\n </>\n )}\n </button>\n </div>\n\n {!showAllFields && (\n <div className=\"text-xs text-dc-info mb-3 p-2 bg-dc-info-bg rounded border border-dc-info-border\">\n Showing only fields used in this dashboard\n </div>\n )}\n\n {filteredSchema && filteredSchema.cubes.length > 0 ? (\n <CubeMetaExplorer\n schema={filteredSchema}\n schemaStatus=\"success\"\n schemaError={null}\n selectedFields={{\n measures: selectedFieldInFilter ? [selectedFieldInFilter] : [],\n dimensions: selectedFieldInFilter ? [selectedFieldInFilter] : [],\n timeDimensions: selectedFieldInFilter ? [selectedFieldInFilter] : []\n }}\n onFieldSelect={(fieldName) => handleFieldSelect(fieldName)}\n onFieldDeselect={() => {}}\n />\n ) : (\n <div className=\"text-center py-8 text-dc-text-muted text-sm\">\n {showAllFields ? (\n <div>\n <p className=\"mb-2\">No schema available</p>\n <p className=\"text-xs\">Check your API connection</p>\n </div>\n ) : (\n <div>\n <p className=\"mb-2\">No fields used in dashboard</p>\n <p className=\"text-xs\">Add portlets to the dashboard first, or toggle to show all fields</p>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Right Column - Filter Builder or Date Range Selector */}\n <div className=\"flex-1 overflow-auto px-6 py-4 bg-dc-surface-secondary\">\n {filter.isUniversalTime ? (\n /* Universal time filter - show DateRangeSelector */\n <div>\n <div className=\"mb-4 p-3 rounded-md bg-dc-info-bg border border-dc-info-border\">\n <div className=\"text-sm font-medium text-dc-info mb-1\">\n Universal Time Filter\n </div>\n <div className=\"text-xs text-dc-text-secondary\">\n This filter applies to all time dimensions in portlets it's mapped to.\n Select a date range below to filter data across all time-based charts.\n </div>\n </div>\n <div className=\"mt-4\">\n <DateRangeSelector\n timeDimension=\"__universal_time__\"\n availableTimeDimensions={['__universal_time__']}\n currentDateRange={(() => {\n // Handle both dateRange property and values array\n const simpleFilter = localFilter as SimpleFilter\n if (simpleFilter.dateRange) return simpleFilter.dateRange\n if (simpleFilter.values) {\n // Single string value (preset like \"last 30 days\") - pass as string\n if (Array.isArray(simpleFilter.values) && simpleFilter.values.length === 1 && typeof simpleFilter.values[0] === 'string') {\n return simpleFilter.values[0]\n }\n return simpleFilter.values\n }\n return undefined\n })()}\n onDateRangeChange={handleDateRangeChange}\n onTimeDimensionChange={() => {}}\n onRemove={() => {}}\n hideFieldSelector={true}\n hideRemoveButton={true}\n />\n </div>\n </div>\n ) : (\n /* Regular filter - show FilterBuilder */\n <FilterBuilder\n filters={[localFilter]}\n schema={convertToMetaResponse(schema)}\n query={{}} // Empty query object - not needed for standalone filter editing\n onFiltersChange={handleFilterBuilderChange}\n />\n )}\n </div>\n </div>\n\n {/* Modal Footer */}\n <div className=\"px-6 py-4 border-t border-dc-border flex items-center justify-between bg-dc-surface\">\n <button\n onClick={onDelete}\n className=\"px-4 py-2 text-sm font-medium text-dc-danger hover:bg-dc-danger-bg rounded-md transition-colors\"\n >\n Delete Filter\n </button>\n <button\n onClick={handleSave}\n className=\"px-4 py-2 text-sm font-medium rounded-md transition-colors bg-dc-primary hover:bg-dc-primary-hover text-dc-primary-content\"\n >\n Done\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default FilterEditModal\n","/**\n * ReadOnlyFilterList Component\n *\n * Displays filters in read-only mode with interactive value selectors\n */\n\nimport React, { useCallback } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterItem from '../QueryBuilder/FilterItem'\n\nconst FilterIcon = getIcon('filter')\nconst ClockIcon = getIcon('timeDimension')\nimport DateRangeSelector from '../QueryBuilder/DateRangeSelector'\nimport type { DashboardFilter, CubeMeta, SimpleFilter } from '../../types'\nimport type { MetaResponse } from '../QueryBuilder/types'\n\ninterface ReadOnlyFilterListProps {\n dashboardFilters: DashboardFilter[]\n schema: CubeMeta | null\n onFilterChange: (filterId: string, updatedFilter: DashboardFilter) => void\n onDateRangeChange: (filterId: string, dateRange: string | string[]) => void\n convertToMetaResponse: (cubeMeta: CubeMeta | null) => MetaResponse | null\n isTimeDimensionField: (fieldName: string) => boolean\n}\n\nconst ReadOnlyFilterList: React.FC<ReadOnlyFilterListProps> = ({\n dashboardFilters,\n schema,\n onFilterChange,\n onDateRangeChange,\n convertToMetaResponse,\n isTimeDimensionField\n}) => {\n // Render individual read-only filter\n const renderReadOnlyFilter = useCallback((dashboardFilter: DashboardFilter) => {\n const { id, label, filter, isUniversalTime } = dashboardFilter\n\n // Only render SimpleFilter in read-only mode (skip GroupFilters for now)\n if (!('member' in filter)) {\n return null\n }\n\n const simpleFilter = filter as SimpleFilter\n const isTimeDim = isTimeDimensionField(simpleFilter.member)\n\n // For universal time filters OR time dimensions with inDateRange, use DateRangeSelector\n if (isUniversalTime || (isTimeDim && simpleFilter.operator === 'inDateRange')) {\n // Get date range - handle both dateRange property and values array\n // If values is a single-element array with a preset string, use that string directly\n let dateRangeValue: string | string[] | undefined = simpleFilter.dateRange\n if (!dateRangeValue && simpleFilter.values) {\n if (Array.isArray(simpleFilter.values) && simpleFilter.values.length === 1 && typeof simpleFilter.values[0] === 'string') {\n // Single string value (preset like \"last 30 days\") - pass as string\n dateRangeValue = simpleFilter.values[0]\n } else {\n dateRangeValue = simpleFilter.values\n }\n }\n\n return (\n <div key={id} className=\"flex flex-col gap-1.5\">\n <div className=\"flex items-center gap-1.5 px-1\">\n {isUniversalTime && (\n <ClockIcon className=\"w-3.5 h-3.5 shrink-0\" style={{ color: 'var(--dc-primary)' }} />\n )}\n <label\n className=\"text-xs font-semibold uppercase tracking-wide truncate\"\n style={{ color: 'var(--dc-text-secondary)' }}\n title={isUniversalTime ? `${label} (applies to all time dimensions)` : label}\n >\n {label}\n </label>\n </div>\n <DateRangeSelector\n timeDimension={isUniversalTime ? '__universal_time__' : simpleFilter.member}\n availableTimeDimensions={isUniversalTime ? ['__universal_time__'] : [simpleFilter.member]}\n currentDateRange={dateRangeValue}\n onDateRangeChange={(_timeDim, dateRange) => onDateRangeChange(id, dateRange)}\n onTimeDimensionChange={() => {}} // Not editable in read-only mode\n onRemove={() => {}} // Not removable in read-only mode\n hideFieldSelector={true}\n hideRemoveButton={true}\n />\n </div>\n )\n }\n\n // For regular filters, use FilterItem\n return (\n <div key={id} className=\"flex flex-col gap-1.5\">\n <label\n className=\"text-xs font-semibold uppercase tracking-wide truncate px-1\"\n style={{ color: 'var(--dc-text-secondary)' }}\n title={label}\n >\n {label}\n </label>\n <FilterItem\n filter={simpleFilter}\n index={0} // Not used in read-only mode\n onFilterChange={(_index, updatedFilter) => {\n onFilterChange(id, {\n ...dashboardFilter,\n filter: updatedFilter\n })\n }}\n onFilterRemove={() => {}} // Not removable in read-only mode\n schema={convertToMetaResponse(schema)}\n query={{}} // Empty query object for read-only mode\n hideFieldSelector={true}\n hideOperatorSelector={true}\n hideRemoveButton={true}\n />\n </div>\n )\n }, [schema, convertToMetaResponse, isTimeDimensionField, onFilterChange, onDateRangeChange])\n\n if (dashboardFilters.length === 0) {\n return null\n }\n\n return (\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-3\">\n <FilterIcon className=\"w-4 h-4 shrink-0\" style={{ color: 'var(--dc-primary)' }} />\n <h3 className=\"text-sm font-semibold\" style={{ color: 'var(--dc-text)' }}>\n Filters\n </h3>\n {dashboardFilters.length > 0 && (\n <span\n className=\"px-1.5 py-0.5 rounded-full text-xs font-medium\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n {dashboardFilters.length}\n </span>\n )}\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {dashboardFilters.map(renderReadOnlyFilter)}\n </div>\n </div>\n )\n}\n\nexport default ReadOnlyFilterList\n","/**\n * EditModeFilterList Component\n *\n * Displays filters in edit mode with chips showing filter labels and edit/delete actions\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport type { DashboardFilter } from '../../types'\n\nconst FilterIcon = getIcon('filter')\nconst AddIcon = getIcon('add')\nconst CloseIcon = getIcon('close')\nconst EditIcon = getIcon('edit')\nconst ChevronDownIcon = getIcon('chevronDown')\nconst ClockIcon = getIcon('timeDimension')\n\ninterface EditModeFilterListProps {\n dashboardFilters: DashboardFilter[]\n onAddFilter: () => void\n onAddTimeFilter: () => void\n onEditFilter: (filterId: string) => void\n onRemoveFilter: (filterId: string) => void\n selectedFilterId?: string | null\n onFilterSelect?: (filterId: string) => void\n}\n\nconst EditModeFilterList: React.FC<EditModeFilterListProps> = ({\n dashboardFilters,\n onAddFilter,\n onAddTimeFilter,\n onEditFilter,\n onRemoveFilter,\n selectedFilterId,\n onFilterSelect\n}) => {\n const [isCollapsed, setIsCollapsed] = React.useState(false)\n\n // Render compact filter chip - just label + edit + delete\n const renderFilterChip = (dashboardFilter: DashboardFilter) => {\n const { id, label, isUniversalTime } = dashboardFilter\n const isSelected = selectedFilterId === id\n\n // Use calendar icon for universal time filters, funnel for regular filters\n const IconComponent = isUniversalTime ? ClockIcon : FilterIcon\n\n return (\n <div\n key={id}\n className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md border text-xs transition-all ${\n 'cursor-pointer hover:shadow-md'\n }`}\n style={{\n backgroundColor: isSelected ? 'var(--dc-primary)' : 'var(--dc-surface)',\n borderColor: isSelected ? 'var(--dc-primary)' : 'var(--dc-border)',\n borderWidth: isSelected ? '2px' : '1px',\n color: isSelected ? 'white' : 'var(--dc-text)',\n boxShadow: isSelected ? '0 0 0 3px rgba(var(--dc-primary-rgb), 0.1)' : 'none'\n }}\n onClick={() => {\n if (onFilterSelect) {\n onFilterSelect(id)\n }\n }}\n >\n <IconComponent\n className=\"w-3.5 h-3.5 shrink-0\"\n style={{ color: isSelected ? 'white' : 'var(--dc-primary)' }}\n />\n <span className=\"font-medium truncate\">{label}</span>\n\n {!isSelected && (\n <div className=\"flex items-center gap-0.5 ml-1\" onClick={(e) => e.stopPropagation()}>\n <button\n onClick={() => onEditFilter(id)}\n className=\"p-0.5 hover:bg-dc-hover rounded transition-colors\"\n title=\"Edit filter\"\n >\n <EditIcon className=\"w-3 h-3\" />\n </button>\n <button\n onClick={() => onRemoveFilter(id)}\n className=\"p-0.5 hover:bg-red-50 hover:text-red-600 rounded transition-colors\"\n title=\"Remove filter\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n )}\n </div>\n )\n }\n\n return (\n <>\n {/* Mobile: Header + collapsible content */}\n <div className=\"md:hidden\">\n {/* Header - clickable to toggle */}\n <div\n className=\"px-4 py-2 flex items-center justify-between cursor-pointer\"\n onClick={() => setIsCollapsed(!isCollapsed)}\n >\n <div className=\"flex items-center gap-2\">\n <FilterIcon className=\"w-4 h-4 shrink-0\" style={{ color: 'var(--dc-primary)' }} />\n <h3 className=\"text-sm font-semibold\" style={{ color: 'var(--dc-text)' }}>\n Filters\n </h3>\n {dashboardFilters.length > 0 && (\n <span\n className=\"px-1.5 py-0.5 rounded-full text-xs font-medium\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n {dashboardFilters.length}\n </span>\n )}\n <ChevronDownIcon\n className={`w-4 h-4 transition-transform ${isCollapsed ? '' : 'rotate-180'}`}\n style={{ color: 'var(--dc-text-secondary)' }}\n />\n </div>\n\n <div className=\"flex items-center gap-1\">\n {/* Only show Date Range button if no universal time filter exists */}\n {!dashboardFilters.some(f => f.isUniversalTime) && (\n <button\n onClick={(e) => {\n e.stopPropagation()\n onAddTimeFilter()\n }}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80\"\n style={{\n backgroundColor: 'var(--dc-surface)',\n color: 'var(--dc-primary)',\n border: '1px solid var(--dc-border)'\n }}\n title=\"Add date range filter (applies to all time dimensions)\"\n >\n <AddIcon className=\"w-3.5 h-3.5\" />\n <ClockIcon className=\"w-3.5 h-3.5\" />\n </button>\n )}\n <button\n onClick={(e) => {\n e.stopPropagation()\n onAddFilter()\n }}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n <AddIcon className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n </div>\n\n {/* Mobile Filter Chips - Collapsible */}\n {dashboardFilters.length > 0 && !isCollapsed && (\n <div className=\"px-4 pb-2 flex flex-col gap-2\">\n {dashboardFilters.map(renderFilterChip)}\n </div>\n )}\n\n {/* Mobile Empty State */}\n {dashboardFilters.length === 0 && !isCollapsed && (\n <div className=\"px-4 pb-2\">\n <div\n className=\"text-xs p-2 rounded-md text-center\"\n style={{\n backgroundColor: 'var(--dc-surface-secondary)',\n color: 'var(--dc-text-secondary)'\n }}\n >\n No filters configured. Click \"Add\" to create one.\n </div>\n </div>\n )}\n </div>\n\n {/* Desktop: Single row layout */}\n <div className=\"hidden md:flex md:items-center md:gap-3 px-4 py-2\">\n {/* Header Section */}\n <div className=\"flex items-center gap-2 shrink-0\">\n <FilterIcon className=\"w-4 h-4 shrink-0\" style={{ color: 'var(--dc-primary)' }} />\n <h3 className=\"text-sm font-semibold whitespace-nowrap\" style={{ color: 'var(--dc-text)' }}>\n Filters\n </h3>\n {dashboardFilters.length > 0 && (\n <span\n className=\"px-1.5 py-0.5 rounded-full text-xs font-medium\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n {dashboardFilters.length}\n </span>\n )}\n </div>\n\n {/* Filter Chips Section - grows to fill space */}\n {dashboardFilters.length > 0 ? (\n <div className=\"flex flex-wrap gap-2 flex-1 min-w-0\">\n {dashboardFilters.map(renderFilterChip)}\n </div>\n ) : (\n <div className=\"flex-1 min-w-0\">\n <div\n className=\"text-xs px-3 py-1 rounded-md inline-block\"\n style={{\n backgroundColor: 'var(--dc-surface-secondary)',\n color: 'var(--dc-text-secondary)'\n }}\n >\n No filters configured. Click \"Add\" to create one.\n </div>\n </div>\n )}\n\n {/* Add Button Section */}\n <div className=\"flex items-center gap-1 shrink-0\">\n {/* Only show Date Range button if no universal time filter exists */}\n {!dashboardFilters.some(f => f.isUniversalTime) && (\n <button\n onClick={onAddTimeFilter}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80\"\n style={{\n backgroundColor: 'var(--dc-surface)',\n color: 'var(--dc-primary)',\n border: '1px solid var(--dc-border)'\n }}\n title=\"Add date range filter (applies to all time dimensions)\"\n >\n <AddIcon className=\"w-3.5 h-3.5\" />\n <span>Date Range</span>\n </button>\n )}\n <button\n onClick={onAddFilter}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n <AddIcon className=\"w-3.5 h-3.5\" />\n <span>Filter</span>\n </button>\n </div>\n </div>\n </>\n )\n}\n\nexport default EditModeFilterList\n","/**\n * DashboardFilterPanel Component\n *\n * Orchestrates dashboard-level filtering UI\n * - Edit mode: Shows filter chips with edit/delete actions\n * - View mode: Shows interactive read-only filters\n *\n * Pattern: Simplified coordination layer (matches portlet editing pattern)\n * - No local editing state (modal owns all edit state)\n * - Just tracks which filter is being edited and modal visibility\n * - Delegates to FilterEditModal for all editing logic\n */\n\nimport React, { useState, useCallback } from 'react'\nimport FilterEditModal from './DashboardFilters/FilterEditModal'\nimport ReadOnlyFilterList from './DashboardFilters/ReadOnlyFilterList'\nimport EditModeFilterList from './DashboardFilters/EditModeFilterList'\nimport type { DashboardFilter, CubeMeta, DashboardConfig } from '../types'\nimport type { MetaResponse } from './QueryBuilder/types'\n\ninterface DashboardFilterPanelProps {\n dashboardFilters: DashboardFilter[]\n editable: boolean\n schema: CubeMeta | null\n dashboardConfig: DashboardConfig\n onDashboardFiltersChange: (filters: DashboardFilter[]) => void\n onSaveFilters?: (filters: DashboardFilter[]) => void | Promise<void>\n selectedFilterId?: string | null\n onFilterSelect?: (filterId: string) => void\n isEditMode?: boolean\n}\n\nconst DashboardFilterPanel: React.FC<DashboardFilterPanelProps> = ({\n dashboardFilters,\n editable,\n schema,\n dashboardConfig,\n onDashboardFiltersChange,\n onSaveFilters,\n selectedFilterId,\n onFilterSelect,\n isEditMode = false\n}) => {\n // Track which filter is being edited and modal visibility (no local editing state)\n const [editingFilter, setEditingFilter] = useState<DashboardFilter | null>(null)\n const [showFilterBuilder, setShowFilterBuilder] = useState(false)\n\n // Convert CubeMeta to MetaResponse (QueryBuilder type)\n const convertToMetaResponse = useCallback((cubeMeta: CubeMeta | null): MetaResponse | null => {\n if (!cubeMeta) return null\n\n return {\n cubes: cubeMeta.cubes.map(cube => ({\n name: cube.name,\n title: cube.title || cube.name,\n description: cube.description || '',\n measures: cube.measures.map(m => ({\n name: m.name,\n title: m.title,\n type: m.type,\n description: '',\n shortTitle: m.shortTitle\n })),\n dimensions: cube.dimensions.map(d => ({\n name: d.name,\n title: d.title,\n type: d.type,\n description: '',\n shortTitle: d.shortTitle\n })),\n segments: cube.segments?.map(s => ({\n name: s.name,\n title: s.title,\n type: s.type,\n description: '',\n shortTitle: s.shortTitle\n })) || []\n }))\n }\n }, [])\n\n // Generate unique ID for new filters\n const generateFilterId = useCallback(() => {\n return `df_${Date.now()}_${Math.random().toString(36).substring(7)}`\n }, [])\n\n // Handle adding a new filter - create temporary filter for modal\n const handleAddFilter = useCallback(() => {\n const newFilter: DashboardFilter = {\n id: generateFilterId(),\n label: `Filter ${dashboardFilters.length + 1}`,\n filter: {\n member: '',\n operator: 'equals',\n values: []\n }\n }\n setEditingFilter(newFilter)\n setShowFilterBuilder(true)\n }, [dashboardFilters.length, generateFilterId])\n\n // Handle adding a universal time filter - applies to all time dimensions\n // Creates filter directly without opening modal (fixed name, user just sets date range in view mode)\n const handleAddTimeFilter = useCallback(() => {\n const newFilter: DashboardFilter = {\n id: generateFilterId(),\n label: 'Date Range Filter',\n isUniversalTime: true,\n filter: {\n member: '__universal_time__', // Placeholder, not used in merge logic\n operator: 'inDateRange',\n values: ['last 30 days']\n }\n }\n // Add directly to filters without opening modal\n const updatedFilters = [...dashboardFilters, newFilter]\n onDashboardFiltersChange(updatedFilters)\n }, [generateFilterId, dashboardFilters, onDashboardFiltersChange])\n\n // Handle editing an existing filter - just open modal with filter\n const handleEditFilter = useCallback((filterId: string) => {\n const filterToEdit = dashboardFilters.find(df => df.id === filterId)\n if (filterToEdit) {\n setEditingFilter(filterToEdit)\n setShowFilterBuilder(true)\n }\n }, [dashboardFilters])\n\n // Handle removing a filter - simple filter list update\n const handleRemoveFilter = useCallback((filterId: string) => {\n const updatedFilters = dashboardFilters.filter(df => df.id !== filterId)\n onDashboardFiltersChange(updatedFilters)\n\n // Close modal if we're deleting the filter being edited\n if (editingFilter?.id === filterId) {\n setEditingFilter(null)\n setShowFilterBuilder(false)\n }\n }, [dashboardFilters, editingFilter, onDashboardFiltersChange])\n\n // Handle save from modal - update or add filter and save\n const handleSaveFilter = useCallback(async (filterData: DashboardFilter) => {\n // Check if this is a new filter (not in current list) or an update\n const existingFilterIndex = dashboardFilters.findIndex(f => f.id === filterData.id)\n\n let updatedFilters: DashboardFilter[]\n if (existingFilterIndex >= 0) {\n // Update existing filter\n updatedFilters = dashboardFilters.map(f =>\n f.id === filterData.id ? filterData : f\n )\n } else {\n // Add new filter\n updatedFilters = [...dashboardFilters, filterData]\n }\n\n // Update dashboard state\n onDashboardFiltersChange(updatedFilters)\n\n // Trigger save if callback provided\n if (onSaveFilters) {\n try {\n await onSaveFilters(updatedFilters)\n } catch (error) {\n console.error('Failed to save filters:', error)\n throw error // Re-throw so modal can handle it\n }\n }\n }, [dashboardFilters, onDashboardFiltersChange, onSaveFilters])\n\n // Handle modal close - just clean up state\n const handleCloseFilterBuilder = useCallback(() => {\n setEditingFilter(null)\n setShowFilterBuilder(false)\n }, [])\n\n // Handle date range change in read-only mode\n const handleFilterDateRangeChange = useCallback((filterId: string, dateRange: string | string[]) => {\n const updatedFilters = dashboardFilters.map(df => {\n if (df.id === filterId) {\n const filter = df.filter\n if ('member' in filter) {\n return {\n ...df,\n filter: {\n ...filter,\n dateRange,\n values: Array.isArray(dateRange) ? dateRange : [dateRange]\n }\n }\n }\n }\n return df\n })\n onDashboardFiltersChange(updatedFilters)\n }, [dashboardFilters, onDashboardFiltersChange])\n\n // Handle filter change in read-only mode\n const handleReadOnlyFilterChange = useCallback((filterId: string, updatedFilter: DashboardFilter) => {\n const updatedFilters = dashboardFilters.map(df =>\n df.id === filterId ? updatedFilter : df\n )\n onDashboardFiltersChange(updatedFilters)\n }, [dashboardFilters, onDashboardFiltersChange])\n\n // Check if a field is a time dimension\n const isTimeDimensionField = useCallback((fieldName: string): boolean => {\n if (!schema) return false\n return schema.cubes.some(cube =>\n cube.dimensions.some(dim => dim.name === fieldName && dim.type === 'time')\n )\n }, [schema])\n\n // Hide filter panel completely when not editable (fully embedded mode without filter support)\n if (!editable) {\n return null\n }\n\n // Hide if no filters exist and not in edit mode (nothing to show)\n if (!isEditMode && dashboardFilters.length === 0) {\n return null\n }\n\n return (\n <div\n className=\"mb-4 border rounded-lg\"\n style={{\n borderColor: 'var(--dc-border)',\n backgroundColor: 'var(--dc-surface)',\n boxShadow: 'var(--dc-shadow-sm)'\n }}\n >\n {/* Edit Mode - Filter chips with edit/delete actions */}\n {isEditMode ? (\n <EditModeFilterList\n dashboardFilters={dashboardFilters}\n onAddFilter={handleAddFilter}\n onAddTimeFilter={handleAddTimeFilter}\n onEditFilter={handleEditFilter}\n onRemoveFilter={handleRemoveFilter}\n selectedFilterId={selectedFilterId}\n onFilterSelect={onFilterSelect}\n />\n ) : (\n /* View Mode - Read-only interactive filters */\n <ReadOnlyFilterList\n dashboardFilters={dashboardFilters}\n schema={schema}\n onFilterChange={handleReadOnlyFilterChange}\n onDateRangeChange={handleFilterDateRangeChange}\n convertToMetaResponse={convertToMetaResponse}\n isTimeDimensionField={isTimeDimensionField}\n />\n )}\n\n {/* Filter Edit Modal */}\n {editable && showFilterBuilder && editingFilter && (\n <FilterEditModal\n filter={editingFilter}\n schema={schema}\n dashboardConfig={dashboardConfig}\n isOpen={showFilterBuilder}\n onSave={handleSaveFilter}\n onClose={handleCloseFilterBuilder}\n onDelete={() => handleRemoveFilter(editingFilter.id)}\n convertToMetaResponse={convertToMetaResponse}\n />\n )}\n </div>\n )\n}\n\nexport default DashboardFilterPanel\n","/**\n * ScaledGridWrapper component\n * Applies CSS transform scaling to the dashboard grid for intermediate screen sizes\n * Maintains the exact desktop layout appearance, just proportionally smaller\n */\n\nimport React, { useState, useEffect, useRef } from 'react'\n\ninterface ScaledGridWrapperProps {\n scaleFactor: number\n designWidth: number\n children: React.ReactNode\n}\n\n/**\n * Wrapper component that scales the grid using CSS transform\n * Handles height compensation to prevent overflow/whitespace issues\n */\nexport default function ScaledGridWrapper({\n scaleFactor,\n designWidth,\n children\n}: ScaledGridWrapperProps) {\n const [actualHeight, setActualHeight] = useState(0)\n const innerRef = useRef<HTMLDivElement>(null)\n\n // Measure actual grid height to calculate visible height\n useEffect(() => {\n if (!innerRef.current) return\n\n const observer = new ResizeObserver((entries) => {\n setActualHeight(entries[0]?.contentRect.height ?? 0)\n })\n\n observer.observe(innerRef.current)\n\n // Set initial height\n setActualHeight(innerRef.current.offsetHeight || 0)\n\n return () => observer.disconnect()\n }, [])\n\n // The scaled visual height\n const visualHeight = actualHeight * scaleFactor\n\n return (\n <div\n className=\"scaled-grid-container\"\n style={{\n height: visualHeight > 0 ? visualHeight : 'auto',\n overflow: 'hidden',\n width: '100%'\n }}\n >\n <div\n ref={innerRef}\n className=\"scaled-grid-inner\"\n style={{\n transform: `scale(${scaleFactor})`,\n transformOrigin: 'top left',\n width: designWidth\n }}\n >\n {children}\n </div>\n </div>\n )\n}\n","/**\n * MobileStackedLayout component\n * Simple vertical stack layout for mobile screens (<768px)\n * Read-only view with portlets sorted by grid position\n */\n\nimport { useMemo, useRef, useState, useCallback } from 'react'\nimport { getIcon } from '../icons'\nimport AnalyticsPortlet from './AnalyticsPortlet'\n\nconst RefreshIcon = getIcon('refresh')\nimport { ScrollContainerProvider } from '../providers/ScrollContainerContext'\nimport type { DashboardFilter, DashboardConfig } from '../types'\nimport type { ColorPalette } from '../utils/colorPalettes'\n\n/**\n * Finds the nearest scrollable ancestor of an element.\n */\nfunction findScrollableAncestor(element: HTMLElement | null): HTMLElement | null {\n if (!element) return null\n\n let current = element.parentElement\n\n while (current) {\n const style = window.getComputedStyle(current)\n const overflowY = style.overflowY\n const overflowX = style.overflowX\n\n const hasScrollableOverflow =\n overflowY === 'auto' || overflowY === 'scroll' ||\n overflowX === 'auto' || overflowX === 'scroll'\n\n const hasScrollContent =\n current.scrollHeight > current.clientHeight ||\n current.scrollWidth > current.clientWidth\n\n if (hasScrollableOverflow && hasScrollContent) {\n return current\n }\n\n if (current === document.body) break\n current = current.parentElement\n }\n\n return null\n}\n\ninterface MobileStackedLayoutProps {\n config: DashboardConfig\n colorPalette?: ColorPalette\n dashboardFilters?: DashboardFilter[]\n onPortletRefresh?: (portletId: string) => void\n}\n\n/**\n * Mobile-optimized stacked layout for dashboard portlets\n * Renders portlets in a single column, sorted by grid position\n */\nexport default function MobileStackedLayout({\n config,\n colorPalette,\n dashboardFilters,\n onPortletRefresh\n}: MobileStackedLayoutProps) {\n const portletComponentRefs = useRef<{ [key: string]: { refresh: () => void } | null }>({})\n\n // Scroll container detection for lazy loading\n const [scrollContainer, setScrollContainer] = useState<HTMLElement | null>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n\n const setContainerRef = useCallback((node: HTMLDivElement | null) => {\n containerRef.current = node\n if (node) {\n setScrollContainer(findScrollableAncestor(node))\n }\n }, [])\n\n // Sort portlets by y position, then x position (top-to-bottom, left-to-right)\n const sortedPortlets = useMemo(() => {\n return [...config.portlets].sort((a, b) => {\n if (a.y !== b.y) return a.y - b.y\n return a.x - b.x\n })\n }, [config.portlets])\n\n const handlePortletRefresh = (portletId: string) => {\n // Refresh the specific portlet component\n portletComponentRefs.current[portletId]?.refresh()\n // Also call external handler if provided\n onPortletRefresh?.(portletId)\n }\n\n return (\n <ScrollContainerProvider value={scrollContainer}>\n <div ref={setContainerRef} className=\"mobile-stacked-layout space-y-4 px-2\">\n {sortedPortlets.map(portlet => {\n // Calculate height: use stored h * rowHeight (80px), with minimum\n const portletHeight = Math.max(300, portlet.h * 80)\n // Header is approximately 40px when shown\n const headerHeight = portlet.displayConfig?.hideHeader ? 0 : 40\n // Content height = total - header - padding (py-3 = 24px)\n const contentHeight = portletHeight - headerHeight - 24\n\n return (\n <div\n key={portlet.id}\n data-portlet-id={portlet.id}\n className=\"bg-dc-surface border border-dc-border rounded-lg flex flex-col\"\n style={{\n height: portletHeight,\n boxShadow: 'var(--dc-shadow-sm)'\n }}\n >\n {/* Portlet Header - Simplified for mobile (no edit controls) */}\n {!portlet.displayConfig?.hideHeader && (\n <div className=\"flex items-center justify-between px-3 py-2 border-b border-dc-border shrink-0 bg-dc-surface-secondary rounded-t-lg\">\n <h3 className=\"font-semibold text-sm text-dc-text truncate flex-1\">\n {portlet.title}\n </h3>\n <div className=\"flex items-center gap-1 shrink-0 ml-2\">\n <button\n onClick={() => handlePortletRefresh(portlet.id)}\n className=\"p-1 bg-transparent border-none rounded-sm text-dc-text-secondary cursor-pointer hover:bg-dc-surface-hover transition-colors\"\n title=\"Refresh portlet data\"\n >\n <RefreshIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n </div>\n </div>\n )}\n\n {/* Portlet Content - explicit height for charts to render */}\n <div\n className=\"px-2 py-3 overflow-visible flex flex-col\"\n style={{ height: contentHeight }}\n >\n <AnalyticsPortlet\n ref={el => { portletComponentRefs.current[portlet.id] = el }}\n query={portlet.query}\n chartType={portlet.chartType}\n chartConfig={portlet.chartConfig}\n displayConfig={portlet.displayConfig}\n dashboardFilters={dashboardFilters}\n dashboardFilterMapping={portlet.dashboardFilterMapping}\n eagerLoad={portlet.eagerLoad ?? config.eagerLoad ?? false}\n title={portlet.title}\n height={contentHeight}\n colorPalette={colorPalette}\n />\n </div>\n </div>\n )\n })}\n </div>\n </ScrollContainerProvider>\n )\n}\n","/**\n * Dashboard Grid Component\n * Uses react-grid-layout for responsive grid layout\n * Simplified version without app-specific dependencies\n */\n\nimport { useCallback, useRef, useState, useEffect, type ReactNode } from 'react'\nimport ReactGridLayout, { verticalCompactor, type LayoutItem, type Layout } from 'react-grid-layout'\nimport { getIcon } from '../icons'\nimport AnalyticsPortlet from './AnalyticsPortlet'\n\nconst ChartBarIcon = getIcon('measure')\nconst RefreshIcon = getIcon('refresh')\nconst EditIcon = getIcon('edit')\nconst DeleteIcon = getIcon('delete')\nconst AddIcon = getIcon('add')\nconst CopyIcon = getIcon('copy')\nconst FilterIcon = getIcon('filter')\nconst DesktopIcon = getIcon('desktop')\nimport PortletEditModal from './PortletEditModal'\nimport PortletFilterConfigModal from './PortletFilterConfigModal'\nimport DebugModal from './DebugModal'\nimport ColorPaletteSelector from './ColorPaletteSelector'\nimport DashboardFilterPanel from './DashboardFilterPanel'\nimport ScaledGridWrapper from './ScaledGridWrapper'\nimport MobileStackedLayout from './MobileStackedLayout'\nimport { useResponsiveDashboard } from '../hooks/useResponsiveDashboard'\nimport { ScrollContainerProvider } from '../providers/ScrollContainerContext'\nimport type { ColorPalette } from '../utils/colorPalettes'\n\n/**\n * Finds the nearest scrollable ancestor of an element.\n * Used to detect scroll container for lazy loading IntersectionObserver.\n */\nfunction findScrollableAncestor(element: HTMLElement | null): HTMLElement | null {\n if (!element) return null\n\n let current = element.parentElement\n\n while (current) {\n const style = window.getComputedStyle(current)\n const overflowY = style.overflowY\n const overflowX = style.overflowX\n\n const hasScrollableOverflow =\n overflowY === 'auto' || overflowY === 'scroll' ||\n overflowX === 'auto' || overflowX === 'scroll'\n\n const hasScrollContent =\n current.scrollHeight > current.clientHeight ||\n current.scrollWidth > current.clientWidth\n\n if (hasScrollableOverflow && hasScrollContent) {\n return current\n }\n\n if (current === document.body) break\n current = current.parentElement\n }\n\n return null // Use viewport\n}\nimport type { DashboardConfig, PortletConfig, DashboardFilter, CubeMeta } from '../types'\n\n// CSS for react-grid-layout should be imported by the consuming app\n// import 'react-grid-layout/css/styles.css'\n\ninterface DashboardGridProps {\n config: DashboardConfig\n editable?: boolean\n dashboardFilters?: DashboardFilter[] // Dashboard-level filters to apply to portlets\n loadingComponent?: ReactNode // Custom loading indicator for all portlets\n onConfigChange?: (config: DashboardConfig) => void\n onPortletRefresh?: (portletId: string) => void\n onSave?: (config: DashboardConfig) => Promise<void> | void\n colorPalette?: ColorPalette // Complete palette with both colors and gradient\n schema?: CubeMeta | null // Cube metadata for filter panel\n onDashboardFiltersChange?: (filters: DashboardFilter[]) => void // Handler for filter changes\n}\n\nexport default function DashboardGrid({\n config,\n editable = false,\n dashboardFilters,\n loadingComponent,\n onConfigChange,\n onPortletRefresh,\n onSave,\n colorPalette,\n schema,\n onDashboardFiltersChange\n}: DashboardGridProps) {\n // Responsive dashboard hook for three-tier layout strategy\n const {\n containerRef,\n containerWidth,\n displayMode,\n scaleFactor,\n isEditable: isResponsiveEditable,\n designWidth\n } = useResponsiveDashboard()\n\n // Scroll container detection for lazy loading\n // Null = viewport, element = scrolling container\n const [scrollContainer, setScrollContainer] = useState<HTMLElement | null>(null)\n const containerElementRef = useRef<HTMLDivElement | null>(null)\n\n // Detect scroll container after mount\n useEffect(() => {\n if (containerElementRef.current) {\n setScrollContainer(findScrollableAncestor(containerElementRef.current))\n }\n }, [])\n\n // Combined ref for container\n const combinedContainerRef = useCallback((node: HTMLDivElement | null) => {\n containerElementRef.current = node\n containerRef(node)\n if (node) {\n setScrollContainer(findScrollableAncestor(node))\n }\n }, [containerRef])\n\n // Calculate grid width based on display mode\n // Desktop: use actual container width (allows wider than 1200px)\n // Scaled: use design width (1200px) and apply CSS scaling\n const gridWidth = displayMode === 'desktop' ? containerWidth : designWidth\n\n // Refs to store portlet refs for refresh functionality\n const portletRefs = useRef<{ [key: string]: HTMLDivElement | null }>({})\n const portletComponentRefs = useRef<{ [key: string]: { refresh: () => void } | null }>({})\n\n // Track if component has been initialized to prevent saves during initial load\n const [isInitialized, setIsInitialized] = useState(false)\n const [lastKnownLayout, setLastKnownLayout] = useState<any[]>([])\n\n // Edit mode state - dashboard is readonly by default\n const [isEditMode, setIsEditMode] = useState(false)\n\n // Filter selection mode state\n const [selectedFilterId, setSelectedFilterId] = useState<string | null>(null)\n\n // Exit filter selection mode when leaving edit mode or when switching to non-desktop mode\n useEffect(() => {\n if ((!isEditMode || !isResponsiveEditable) && selectedFilterId) {\n setSelectedFilterId(null)\n }\n }, [isEditMode, isResponsiveEditable, selectedFilterId])\n\n // Exit edit mode when switching to non-desktop view\n useEffect(() => {\n if (!isResponsiveEditable && isEditMode) {\n setIsEditMode(false)\n }\n }, [isResponsiveEditable, isEditMode])\n\n // Track scroll state for sticky header\n const [isScrolled, setIsScrolled] = useState(false)\n\n // Modal states\n const [isPortletModalOpen, setIsPortletModalOpen] = useState(false)\n const [editingPortlet, setEditingPortlet] = useState<PortletConfig | null>(null)\n const [isFilterConfigModalOpen, setIsFilterConfigModalOpen] = useState(false)\n const [filterConfigPortlet, setFilterConfigPortlet] = useState<PortletConfig | null>(null)\n\n // Debug data state - keyed by portlet ID\n const [debugData, setDebugData] = useState<{ [portletId: string]: {\n chartConfig: any\n displayConfig: any\n queryObject: any\n data: any[]\n chartType: string\n } }>({})\n\n // Set up initialization tracking\n useEffect(() => {\n // Mark as initialized after first render to prevent saves during load/resize\n const timer = setTimeout(() => {\n setIsInitialized(true)\n // Store initial layout for comparison\n const initialLayout = config.portlets.map(portlet => ({\n i: portlet.id,\n x: portlet.x,\n y: portlet.y,\n w: portlet.w,\n h: portlet.h\n }))\n setLastKnownLayout(initialLayout)\n }, 200) // Slightly longer delay to ensure responsive grid is fully settled\n\n return () => clearTimeout(timer)\n }, [config.portlets])\n\n // Set up scroll listener for sticky header\n useEffect(() => {\n const handleScroll = () => {\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop\n setIsScrolled(scrollTop > 20) // Add sticky styling after scrolling 20px\n }\n\n window.addEventListener('scroll', handleScroll, { passive: true })\n\n // Check initial scroll position\n handleScroll()\n\n return () => {\n window.removeEventListener('scroll', handleScroll)\n }\n }, [])\n\n // Set up ESC key listener for filter selection mode\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && selectedFilterId) {\n setSelectedFilterId(null)\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [selectedFilterId])\n\n // Helper function to check if layout actually changed (not just reordered due to responsive changes)\n const hasLayoutActuallyChanged = useCallback((newLayout: any[]) => {\n if (!isInitialized || lastKnownLayout.length === 0) return false\n \n // Compare each item's position and size\n for (const newItem of newLayout) {\n const oldItem = lastKnownLayout.find(item => item.i === newItem.i)\n if (!oldItem) continue // New item, this is a change\n \n if (oldItem.x !== newItem.x || oldItem.y !== newItem.y || \n oldItem.w !== newItem.w || oldItem.h !== newItem.h) {\n return true\n }\n }\n return false\n }, [isInitialized, lastKnownLayout])\n\n const handleLayoutChange = useCallback((_layout: Layout) => {\n // This function is called for ALL layout changes\n // We should NOT save here - only update internal state if needed\n // Actual saving only happens in handleDragStop and handleResizeStop for explicit user actions\n\n // Note: We don't call onConfigChange here to prevent saving intermediate layout changes\n // The layout changes are handled by react-grid-layout internally\n }, []) // No dependencies since we're not doing anything\n\n // Handle drag stop - save when user finishes dragging (only if layout actually changed)\n const handleDragStop = useCallback(async (layout: Layout, _oldItem: LayoutItem | null, _newItem: LayoutItem | null, _placeholder: LayoutItem | null, _e: Event, _element: HTMLElement | undefined) => {\n if (!editable || !isEditMode || !onSave || !isInitialized) return\n\n // Only save if the layout actually changed from user interaction\n // Convert readonly Layout to mutable array for comparison\n const mutableLayout = [...layout]\n if (!hasLayoutActuallyChanged(mutableLayout)) {\n return // No actual change, don't save\n }\n\n // Get the current updated config (only called in desktop mode)\n const updatedPortlets = config.portlets.map(portlet => {\n const layoutItem = mutableLayout.find(item => item.i === portlet.id)\n if (layoutItem) {\n return {\n ...portlet,\n x: layoutItem.x,\n y: layoutItem.y,\n w: layoutItem.w,\n h: layoutItem.h\n }\n }\n return portlet\n })\n\n // Preserve existing responsive layouts, only update with new lg layout\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets,\n layouts: {\n ...config.layouts,\n lg: mutableLayout // Only save the large layout, let RGL handle responsive adjustments\n }\n }\n\n // Update our tracking of the last known layout\n setLastKnownLayout(mutableLayout)\n\n // Update config state first\n onConfigChange?.(updatedConfig)\n\n // Auto-save after drag operation\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed after drag:', error)\n }\n }, [config.portlets, config.layouts, editable, isEditMode, onConfigChange, onSave, isInitialized, hasLayoutActuallyChanged])\n\n // Handle resize stop - update config and save (resize is user interaction)\n const handleResizeStop = useCallback(async (layout: Layout, _oldItem: LayoutItem | null, _newItem: LayoutItem | null, _placeholder: LayoutItem | null, _e: Event, _element: HTMLElement | undefined) => {\n if (!editable || !isEditMode || !onConfigChange || !isInitialized) return\n\n // Only proceed if the layout actually changed from user interaction\n // Convert readonly Layout to mutable array for comparison\n const mutableLayout = [...layout]\n if (!hasLayoutActuallyChanged(mutableLayout)) {\n return // No actual change, don't save\n }\n\n // Get the current updated config (only called in desktop mode)\n const updatedPortlets = config.portlets.map(portlet => {\n const layoutItem = mutableLayout.find(item => item.i === portlet.id)\n if (layoutItem) {\n return {\n ...portlet,\n x: layoutItem.x,\n y: layoutItem.y,\n w: layoutItem.w,\n h: layoutItem.h\n }\n }\n return portlet\n })\n\n // Preserve existing responsive layouts, only update with new lg layout\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets,\n layouts: {\n ...config.layouts,\n lg: mutableLayout // Only save the large layout, let RGL handle responsive adjustments\n }\n }\n\n // Update our tracking of the last known layout\n setLastKnownLayout(mutableLayout)\n\n // Update config state\n onConfigChange(updatedConfig)\n\n // Auto-save after resize operation (user deliberately resized)\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed after resize:', error)\n }\n }\n }, [config.portlets, config.layouts, editable, isEditMode, onConfigChange, onSave, isInitialized, hasLayoutActuallyChanged])\n\n // Handle portlet refresh\n const handlePortletRefresh = useCallback((portletId: string) => {\n const portletComponent = portletComponentRefs.current[portletId]\n if (portletComponent && portletComponent.refresh) {\n portletComponent.refresh()\n }\n if (onPortletRefresh) {\n onPortletRefresh(portletId)\n }\n }, [onPortletRefresh])\n\n // Handle adding new portlet\n const handleAddPortlet = useCallback(() => {\n setEditingPortlet(null)\n setIsPortletModalOpen(true)\n }, [])\n\n // Handle editing existing portlet\n const handleEditPortlet = useCallback((portlet: PortletConfig) => {\n setEditingPortlet(portlet)\n setIsPortletModalOpen(true)\n }, [])\n\n // Handle portlet save\n const handlePortletSave = useCallback(async (portletData: PortletConfig | Omit<PortletConfig, 'id' | 'x' | 'y'>) => {\n if (!onConfigChange) return\n\n let updatedPortlets = [...config.portlets]\n let isNewPortlet = false\n let newPortletId: string | null = null\n\n if (editingPortlet) {\n // Editing existing portlet\n const index = updatedPortlets.findIndex(p => p.id === editingPortlet.id)\n if (index !== -1) {\n updatedPortlets[index] = portletData as PortletConfig\n }\n } else {\n // Adding new portlet\n isNewPortlet = true\n const newPortlet: PortletConfig = {\n ...portletData,\n id: `portlet-${Date.now()}`,\n x: 0,\n y: 0\n } as PortletConfig\n\n newPortletId = newPortlet.id\n\n // Find the best position for the new portlet\n const gridLayout = updatedPortlets.map(p => ({ i: p.id, x: p.x, y: p.y, w: p.w, h: p.h }))\n let maxY = 0\n gridLayout.forEach(item => {\n if (item.y + item.h > maxY) {\n maxY = item.y + item.h\n }\n })\n newPortlet.y = maxY\n\n updatedPortlets.push(newPortlet)\n }\n\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n\n setIsPortletModalOpen(false)\n setEditingPortlet(null)\n\n // Scroll to the new portlet after DOM update\n if (isNewPortlet && newPortletId) {\n setTimeout(() => {\n const scrollToPortlet = () => {\n // Try both the ref and DOM query selector\n let portletElement: HTMLElement | null = portletRefs.current[newPortletId!]\n if (!portletElement) {\n portletElement = document.querySelector(`[data-portlet-id=\"${newPortletId}\"]`)\n }\n \n if (portletElement) {\n portletElement.scrollIntoView({ \n behavior: 'smooth', \n block: 'center',\n inline: 'nearest'\n })\n return true\n }\n return false\n }\n \n // Try multiple times with increasing delays\n if (!scrollToPortlet()) {\n setTimeout(() => {\n if (!scrollToPortlet()) {\n setTimeout(() => {\n scrollToPortlet()\n }, 300)\n }\n }, 200)\n }\n }, 200)\n }\n }, [config, editingPortlet, onConfigChange, onSave])\n\n // Handle deleting portlet\n const handleDeletePortlet = useCallback(async (portletId: string) => {\n if (!onConfigChange) return\n \n if (window.confirm('Are you sure you want to delete this portlet?')) {\n const updatedPortlets = config.portlets.filter(p => p.id !== portletId)\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n \n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }\n }, [config, onConfigChange, onSave])\n\n // Handle duplicating portlet\n const handleDuplicatePortlet = useCallback(async (portletId: string) => {\n if (!onConfigChange) return\n \n const originalPortlet = config.portlets.find(p => p.id === portletId)\n if (!originalPortlet) return\n\n // Create duplicated portlet with new ID and updated title\n const duplicatedPortlet: PortletConfig = {\n ...originalPortlet,\n id: `portlet-${Date.now()}`,\n title: `${originalPortlet.title} Duplicated`,\n x: 0,\n y: 0\n }\n\n // Find the best position for the duplicated portlet\n const gridLayout = config.portlets.map(p => ({ i: p.id, x: p.x, y: p.y, w: p.w, h: p.h }))\n let maxY = 0\n gridLayout.forEach(item => {\n if (item.y + item.h > maxY) {\n maxY = item.y + item.h\n }\n })\n duplicatedPortlet.y = maxY\n\n const updatedPortlets = [...config.portlets, duplicatedPortlet]\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n \n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n\n // Scroll to the duplicated portlet after DOM update\n setTimeout(() => {\n const scrollToPortlet = () => {\n // Try both the ref and DOM query selector\n let portletElement: HTMLElement | null = portletRefs.current[duplicatedPortlet.id]\n if (!portletElement) {\n portletElement = document.querySelector(`[data-portlet-id=\"${duplicatedPortlet.id}\"]`)\n }\n \n if (portletElement) {\n portletElement.scrollIntoView({ \n behavior: 'smooth', \n block: 'center',\n inline: 'nearest'\n })\n return true\n }\n return false\n }\n \n // Try multiple times with increasing delays\n if (!scrollToPortlet()) {\n setTimeout(() => {\n if (!scrollToPortlet()) {\n setTimeout(() => {\n scrollToPortlet()\n }, 300)\n }\n }, 200)\n }\n }, 200)\n }, [config, onConfigChange, onSave])\n\n // Handle color palette changes\n const handlePaletteChange = useCallback(async (paletteName: string) => {\n if (!onConfigChange) return\n\n const updatedConfig = {\n ...config,\n colorPalette: paletteName\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }, [config, onConfigChange, onSave])\n\n // Handle opening filter config modal\n const handleOpenFilterConfig = useCallback((portlet: PortletConfig) => {\n setFilterConfigPortlet(portlet)\n setIsFilterConfigModalOpen(true)\n }, [])\n\n // Handle saving filter configuration\n const handleSaveFilterConfig = useCallback(async (mapping: string[]) => {\n if (!onConfigChange || !filterConfigPortlet) return\n\n const updatedPortlets = config.portlets.map(p => {\n if (p.id === filterConfigPortlet.id) {\n return {\n ...p,\n dashboardFilterMapping: mapping\n }\n }\n return p\n })\n\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }, [config, filterConfigPortlet, onConfigChange, onSave])\n\n // Handle toggling filter for a portlet (used in filter selection mode)\n const handleToggleFilterForPortlet = useCallback(async (portletId: string, filterId: string) => {\n if (!onConfigChange) return\n\n const updatedPortlets = config.portlets.map(p => {\n if (p.id === portletId) {\n const currentMapping = p.dashboardFilterMapping || []\n const hasFilter = currentMapping.includes(filterId)\n\n return {\n ...p,\n dashboardFilterMapping: hasFilter\n ? currentMapping.filter(id => id !== filterId)\n : [...currentMapping, filterId]\n }\n }\n return p\n })\n\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }, [config, onConfigChange, onSave])\n\n // Handle filter selection (click on filter chip)\n const handleFilterSelect = useCallback((filterId: string) => {\n // Toggle selection: if already selected, deselect\n setSelectedFilterId(prev => prev === filterId ? null : filterId)\n }, [])\n\n // Handle select all - apply current filter to all portlets\n const handleSelectAllForFilter = useCallback(async (filterId: string) => {\n if (!onConfigChange) return\n\n const updatedPortlets = config.portlets.map(p => {\n const currentMapping = p.dashboardFilterMapping || []\n // Add the filter if it's not already in the mapping\n if (!currentMapping.includes(filterId)) {\n return {\n ...p,\n dashboardFilterMapping: [...currentMapping, filterId]\n }\n }\n return p\n })\n\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }, [config, onConfigChange, onSave])\n\n // Get the selected filter object\n const selectedFilter = selectedFilterId\n ? dashboardFilters?.find(f => f.id === selectedFilterId)\n : null\n\n if (!config.portlets || config.portlets.length === 0) {\n return (\n <>\n <div className=\"flex justify-center items-center min-h-[50vh]\">\n <div className=\"text-center\">\n <ChartBarIcon style={{ width: '64px', height: '64px', color: 'var(--dc-text-muted)', margin: '0 auto 16px auto' }} />\n <h3 className=\"text-lg font-semibold mb-2 text-dc-text\">No Portlets</h3>\n <p className=\"text-sm text-dc-text-secondary mb-4\">Add your first portlet to start visualizing your data</p>\n {editable && (\n <button\n onClick={handleAddPortlet}\n className=\"inline-flex items-center px-4 py-2 border border-dc-border bg-dc-surface rounded-md focus:outline-hidden focus:ring-2\"\n style={{\n color: 'var(--dc-primary)',\n borderColor: 'var(--dc-primary)'\n }}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-surface-hover)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-surface)'}\n >\n <AddIcon className=\"w-5 h-5 mr-2\" />\n Add Portlet\n </button>\n )}\n </div>\n </div>\n \n {/* Portlet Modal */}\n <PortletEditModal\n isOpen={isPortletModalOpen}\n onClose={() => {\n setIsPortletModalOpen(false)\n setEditingPortlet(null)\n }}\n onSave={handlePortletSave}\n portlet={editingPortlet}\n title={editingPortlet ? 'Edit Portlet' : 'Add New Portlet'}\n submitText={editingPortlet ? 'Update Portlet' : 'Add Portlet'}\n colorPalette={colorPalette}\n />\n </>\n )\n }\n\n // Determine if editing is allowed (only in desktop mode)\n const canEdit = editable && isEditMode && isResponsiveEditable && !selectedFilterId\n\n // Generate grid layout from portlets - only use for lg (desktop) breakpoint\n // Let react-grid-layout handle responsive adjustments automatically\n const baseLayout: LayoutItem[] = config.portlets.map(portlet => ({\n i: portlet.id,\n x: portlet.x,\n y: portlet.y,\n w: portlet.w,\n h: portlet.h,\n minW: 2,\n minH: 2, // 2 rows at 80px = 160px minimum\n // Only enable drag/resize in edit mode\n isDraggable: canEdit,\n isResizable: canEdit,\n ...(canEdit ? { resizeHandles: ['s', 'w', 'e', 'n', 'se', 'sw', 'ne', 'nw'] as const } : {})\n }))\n\n // Render the portlet grid content (shared between desktop and scaled modes)\n const renderGridContent = () => (\n <ReactGridLayout\n className=\"layout\"\n layout={baseLayout}\n onLayoutChange={handleLayoutChange}\n onDragStop={handleDragStop}\n onResizeStop={handleResizeStop}\n width={gridWidth}\n gridConfig={{\n cols: 12,\n rowHeight: 80,\n margin: [16, 16],\n containerPadding: [0, 0]\n }}\n dragConfig={{\n enabled: canEdit,\n handle: '.portlet-drag-handle'\n }}\n resizeConfig={{\n enabled: canEdit,\n handles: ['s', 'w', 'e', 'n', 'se', 'sw', 'ne', 'nw'],\n // Invisible but functional resize handles\n handleComponent: (axis, ref) => (\n <div\n ref={ref as React.Ref<HTMLDivElement>}\n className={`react-resizable-handle react-resizable-handle-${axis}`}\n style={{ opacity: 0 }}\n />\n )\n }}\n compactor={verticalCompactor}\n >\n {config.portlets.map(portlet => {\n const hasSelectedFilter = selectedFilterId\n ? (portlet.dashboardFilterMapping || []).includes(selectedFilterId)\n : false\n const isInSelectionMode = !!selectedFilterId\n\n return (\n <div\n key={portlet.id}\n data-portlet-id={portlet.id}\n ref={el => { portletRefs.current[portlet.id] = el }}\n className={`bg-dc-surface border rounded-lg flex flex-col h-full transition-all ${\n isInSelectionMode ? 'cursor-pointer' : ''\n }`}\n style={{\n boxShadow: 'var(--dc-shadow-sm)',\n borderColor: isInSelectionMode && hasSelectedFilter\n ? 'var(--dc-primary)'\n : 'var(--dc-border)',\n borderWidth: isInSelectionMode && hasSelectedFilter ? '2px' : '1px',\n backgroundColor: isInSelectionMode && hasSelectedFilter\n ? 'rgba(var(--dc-primary-rgb), 0.05)'\n : 'var(--dc-surface)',\n opacity: isInSelectionMode && !hasSelectedFilter ? '0.5' : '1'\n }}\n onClick={(e) => {\n if (isInSelectionMode && selectedFilterId) {\n e.stopPropagation()\n handleToggleFilterForPortlet(portlet.id, selectedFilterId)\n }\n }}\n >\n {/* Portlet Header - Conditionally rendered based on displayConfig.hideHeader */}\n {(!portlet.displayConfig?.hideHeader || isEditMode) && (\n <div className={`flex items-center justify-between px-3 py-1.5 md:px-4 md:py-1 border-b border-dc-border shrink-0 bg-dc-surface-secondary rounded-t-lg portlet-drag-handle ${isEditMode ? 'cursor-move' : 'cursor-default'}`}>\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <h3 className=\"font-semibold text-sm text-dc-text truncate\">{portlet.title}</h3>\n {/* Debug button - only show in edit mode */}\n {editable && isEditMode && debugData[portlet.id] && (\n <div\n onMouseDown={(e) => e.stopPropagation()}\n onClick={(e) => e.stopPropagation()}\n onTouchStart={(e) => e.stopPropagation()}\n onTouchEnd={(e) => e.stopPropagation()}\n >\n <DebugModal\n chartConfig={debugData[portlet.id].chartConfig}\n displayConfig={debugData[portlet.id].displayConfig}\n queryObject={debugData[portlet.id].queryObject}\n data={debugData[portlet.id].data}\n chartType={debugData[portlet.id].chartType}\n />\n </div>\n )}\n </div>\n <div\n className=\"flex items-center gap-1 shrink-0 ml-4 -mr-2\"\n onMouseDown={(e) => e.stopPropagation()}\n onClick={(e) => e.stopPropagation()}\n onTouchStart={(e) => e.stopPropagation()}\n onTouchEnd={(e) => e.stopPropagation()}\n >\n <button\n onClick={(e) => {\n e.stopPropagation()\n handlePortletRefresh(portlet.id)\n }}\n onTouchEnd={(e) => {\n e.stopPropagation()\n e.preventDefault()\n handlePortletRefresh(portlet.id)\n }}\n disabled={isInSelectionMode}\n className={`p-1 bg-transparent border-none rounded-sm text-dc-text-secondary transition-colors ${\n isInSelectionMode ? 'cursor-not-allowed opacity-50' : 'cursor-pointer hover:bg-dc-surface-hover'\n }`}\n title=\"Refresh portlet data\"\n >\n <RefreshIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n\n {editable && isEditMode && !isInSelectionMode && (\n <>\n {/* Filter configuration button */}\n <button\n onClick={(e) => {\n e.stopPropagation()\n handleOpenFilterConfig(portlet)\n }}\n onTouchEnd={(e) => {\n e.stopPropagation()\n e.preventDefault()\n handleOpenFilterConfig(portlet)\n }}\n className=\"p-1 bg-transparent border-none rounded-sm cursor-pointer hover:bg-dc-surface-hover transition-colors relative\"\n title={`Configure dashboard filters${portlet.dashboardFilterMapping && portlet.dashboardFilterMapping.length > 0 ? ` (${portlet.dashboardFilterMapping.length} active)` : ''}`}\n style={{\n color: portlet.dashboardFilterMapping && portlet.dashboardFilterMapping.length > 0\n ? 'var(--dc-primary)'\n : 'var(--dc-text-secondary)'\n }}\n >\n <FilterIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n\n <button\n onClick={(e) => {\n e.stopPropagation()\n handleDuplicatePortlet(portlet.id)\n }}\n onTouchEnd={(e) => {\n e.stopPropagation()\n e.preventDefault()\n handleDuplicatePortlet(portlet.id)\n }}\n className=\"p-1 bg-transparent border-none rounded-sm text-dc-text-secondary cursor-pointer hover:bg-dc-surface-hover transition-colors\"\n title=\"Duplicate portlet\"\n >\n <CopyIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation()\n handleEditPortlet(portlet)\n }}\n onTouchEnd={(e) => {\n e.stopPropagation()\n e.preventDefault()\n handleEditPortlet(portlet)\n }}\n className=\"p-1 bg-transparent border-none rounded-sm text-dc-text-secondary cursor-pointer hover:bg-dc-surface-hover transition-colors\"\n title=\"Edit portlet\"\n >\n <EditIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation()\n handleDeletePortlet(portlet.id)\n }}\n onTouchEnd={(e) => {\n e.stopPropagation()\n e.preventDefault()\n handleDeletePortlet(portlet.id)\n }}\n className=\"p-1 mr-0.5 bg-transparent border-none rounded-sm cursor-pointer hover:bg-red-50 transition-colors\"\n style={{ color: '#ef4444' }}\n title=\"Delete portlet\"\n >\n <DeleteIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n </>\n )}\n </div>\n </div>\n )}\n\n {/* Portlet Content */}\n <div className=\"flex-1 px-2 py-3 md:px-4 md:py-4 min-h-0 overflow-visible flex flex-col\">\n <AnalyticsPortlet\n ref={el => { portletComponentRefs.current[portlet.id] = el }}\n query={portlet.query}\n chartType={portlet.chartType}\n chartConfig={portlet.chartConfig}\n displayConfig={portlet.displayConfig}\n dashboardFilters={dashboardFilters}\n dashboardFilterMapping={portlet.dashboardFilterMapping}\n eagerLoad={portlet.eagerLoad ?? config.eagerLoad ?? false}\n title={portlet.title}\n height=\"100%\"\n colorPalette={colorPalette}\n loadingComponent={loadingComponent}\n onDebugDataReady={(data) => {\n setDebugData(prev => ({\n ...prev,\n [portlet.id]: data\n }))\n }}\n />\n </div>\n </div>\n )\n })}\n </ReactGridLayout>\n )\n\n return (\n <ScrollContainerProvider value={scrollContainer}>\n <div ref={combinedContainerRef} className=\"dashboard-grid-container w-full\" style={{ maxWidth: '100%', overflow: 'hidden' }}>\n {editable && (\n <div\n className={`mb-4 flex justify-between items-center sticky top-0 z-10 px-4 py-4 bg-dc-surface-tertiary border border-dc-border rounded-lg transition-all duration-200 ${\n isScrolled ? 'border-b' : ''\n }`}\n style={{\n boxShadow: isScrolled ? 'var(--dc-shadow-md)' : 'var(--dc-shadow-sm)'\n }}\n >\n <div className=\"flex items-center gap-4\">\n <button\n onClick={() => isResponsiveEditable && setIsEditMode(!isEditMode)}\n disabled={!isResponsiveEditable}\n className={`inline-flex items-center px-4 py-2 text-sm font-medium rounded-md transition-colors focus:outline-hidden focus:ring-2 focus:ring-offset-2 ${\n !isResponsiveEditable\n ? 'opacity-50 cursor-not-allowed bg-dc-surface-secondary border border-dc-border'\n : isEditMode\n ? 'bg-dc-surface-secondary border border-dc-border hover:bg-dc-surface-hover'\n : 'bg-dc-surface border border-dc-border hover:bg-dc-surface-hover'\n }`}\n style={{\n color: !isResponsiveEditable ? 'var(--dc-text-muted)' : 'var(--dc-primary)',\n borderColor: !isResponsiveEditable ? 'var(--dc-border)' : isEditMode ? 'var(--dc-border)' : 'var(--dc-primary)'\n }}\n >\n <EditIcon className=\"w-4 h-4 mr-1.5\" />\n {isEditMode ? 'Finished Editing' : 'Edit'}\n </button>\n {!isResponsiveEditable && (\n <div className=\"flex items-center gap-2 text-sm text-dc-text-secondary\">\n <DesktopIcon className=\"w-4 h-4\" />\n <span>Desktop view required for editing</span>\n </div>\n )}\n {isEditMode && isResponsiveEditable && (\n <p className=\"hidden md:block text-sm text-dc-text-secondary\">\n Drag to rearrange • Resize from corners • Changes save automatically\n </p>\n )}\n </div>\n\n {/* Color Palette Selector - Only show in edit mode */}\n <div className=\"flex items-center gap-3\">\n {isEditMode && (\n <ColorPaletteSelector\n currentPalette={config.colorPalette}\n onPaletteChange={handlePaletteChange}\n className=\"shrink-0\"\n />\n )}\n\n <button\n onClick={handleAddPortlet}\n disabled={!isEditMode}\n className={`inline-flex items-center px-4 py-2 text-sm font-medium border rounded-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 ${\n isEditMode\n ? 'border-dc-border bg-dc-surface hover:bg-dc-surface-hover'\n : 'border-dc-border bg-dc-surface-secondary cursor-not-allowed'\n }`}\n style={{\n color: isEditMode ? 'var(--dc-primary)' : 'var(--dc-text-muted)',\n borderColor: isEditMode ? 'var(--dc-primary)' : 'var(--dc-border)'\n }}\n >\n <AddIcon className=\"w-5 h-5 mr-2\" />\n Add Portlet\n </button>\n </div>\n </div>\n )}\n\n {/* Dashboard Filter Panel - Always visible below toolbar */}\n <DashboardFilterPanel\n dashboardFilters={dashboardFilters || []}\n editable={editable}\n schema={schema || null}\n dashboardConfig={config}\n onDashboardFiltersChange={onDashboardFiltersChange || (() => {})}\n onSaveFilters={onSave ? async (filters: DashboardFilter[]) => {\n const updatedConfig = {\n ...config,\n filters\n }\n await onSave(updatedConfig)\n } : undefined}\n selectedFilterId={selectedFilterId}\n onFilterSelect={handleFilterSelect}\n isEditMode={isEditMode}\n />\n\n {/* Filter Selection Mode Banner */}\n {selectedFilterId && selectedFilter && (\n <div\n className=\"mb-4 px-4 py-3 rounded-md border-2 transition-all\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n borderColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n <div className=\"flex items-center justify-between flex-wrap gap-2\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <FilterIcon className=\"w-5 h-5 shrink-0\" />\n <span className=\"font-medium\">\n Filter Selection Mode - Click portlets to toggle '{selectedFilter.label}'\n </span>\n <span className=\"text-sm opacity-90 hidden sm:inline\">• Press ESC to exit</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => handleSelectAllForFilter(selectedFilterId)}\n className=\"px-3 py-1 rounded-md transition-colors text-sm font-medium\"\n style={{\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n color: 'white'\n }}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.3)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.2)'}\n >\n Select All\n </button>\n <button\n onClick={() => setSelectedFilterId(null)}\n className=\"px-3 py-1 rounded-md transition-colors text-sm font-medium\"\n style={{\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n color: 'white'\n }}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.3)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.2)'}\n >\n Exit\n </button>\n </div>\n </div>\n </div>\n )}\n \n {/* Render layout based on display mode */}\n {displayMode === 'mobile' ? (\n <MobileStackedLayout\n config={config}\n colorPalette={colorPalette}\n dashboardFilters={dashboardFilters}\n onPortletRefresh={handlePortletRefresh}\n />\n ) : displayMode === 'scaled' ? (\n <ScaledGridWrapper scaleFactor={scaleFactor} designWidth={designWidth}>\n {renderGridContent()}\n </ScaledGridWrapper>\n ) : (\n renderGridContent()\n )}\n \n {/* Portlet Modal */}\n <PortletEditModal\n isOpen={isPortletModalOpen}\n onClose={() => {\n setIsPortletModalOpen(false)\n setEditingPortlet(null)\n }}\n onSave={handlePortletSave}\n portlet={editingPortlet}\n title={editingPortlet ? 'Edit Portlet' : 'Add New Portlet'}\n submitText={editingPortlet ? 'Update Portlet' : 'Add Portlet'}\n colorPalette={colorPalette}\n />\n\n {/* Filter Configuration Modal */}\n <PortletFilterConfigModal\n isOpen={isFilterConfigModalOpen}\n onClose={() => {\n setIsFilterConfigModalOpen(false)\n setFilterConfigPortlet(null)\n }}\n dashboardFilters={dashboardFilters || []}\n currentMapping={filterConfigPortlet?.dashboardFilterMapping || []}\n onSave={handleSaveFilterConfig}\n portletTitle={filterConfigPortlet?.title || ''}\n />\n </div>\n </ScrollContainerProvider>\n )\n}","/**\n * Analytics Dashboard Component\n * Main dashboard container that uses CubeProvider context\n * Minimal dependencies, designed to be embedded in existing apps\n */\n\nimport { useCallback, useRef, useMemo } from 'react'\nimport DashboardGrid from './DashboardGrid'\nimport { useCubeContext } from '../providers/CubeProvider'\nimport { getColorPalette } from '../utils/colorPalettes'\nimport type { AnalyticsDashboardProps, DashboardConfig, DashboardFilter } from '../types'\n\nexport default function AnalyticsDashboard({\n config,\n editable = false,\n dashboardFilters: propDashboardFilters,\n loadingComponent,\n onConfigChange,\n onSave,\n onDirtyStateChange\n}: AnalyticsDashboardProps) {\n // Get cube metadata for filter building\n const { meta } = useCubeContext()\n\n // Track initial config to prevent saves during initial load\n const initialConfigRef = useRef(config)\n const hasConfigChangedFromInitial = useRef(false)\n\n // Merge programmatic filters (props) with config filters by ID\n // Config provides structure/metadata, props provide value overrides\n const mergedDashboardFilters = useMemo<DashboardFilter[]>(() => {\n const configFilters = config.filters || []\n const propFilters = propDashboardFilters || []\n\n // If no prop filters, use config filters as-is\n if (propFilters.length === 0) {\n return configFilters\n }\n\n // If no config filters, use prop filters as-is\n if (configFilters.length === 0) {\n return propFilters\n }\n\n // Merge by ID: config filters provide structure, prop filters provide values\n const mergedFilters: DashboardFilter[] = configFilters.map(configFilter => {\n // Find matching prop filter by ID\n const propFilter = propFilters.find(pf => pf.id === configFilter.id)\n\n if (propFilter) {\n // Merge: preserve config metadata, use prop filter values\n return {\n ...configFilter, // Preserve id, label, isUniversalTime from config\n filter: propFilter.filter // Use filter values from prop override\n }\n }\n\n // No override for this filter, use config as-is\n return configFilter\n })\n\n // Add any prop filters that don't exist in config (new filters)\n const configIds = new Set(configFilters.map(cf => cf.id))\n const newFilters = propFilters.filter(pf => !configIds.has(pf.id))\n\n return [...mergedFilters, ...newFilters]\n }, [config.filters, propDashboardFilters])\n\n // Enhanced save handler that tracks dirty state and prevents saves during initial load\n const handleSaveWithDirtyTracking = useCallback(async (config: DashboardConfig) => {\n // Don't save if this config hasn't actually changed from the initial load\n if (!hasConfigChangedFromInitial.current) {\n return // Prevent saves during initial load/responsive changes\n }\n \n if (onDirtyStateChange) {\n onDirtyStateChange(true) // Mark as dirty when save starts\n }\n \n try {\n if (onSave) {\n await onSave(config)\n }\n \n // Update our reference point after successful save\n initialConfigRef.current = config\n \n // Mark as clean after successful save\n if (onDirtyStateChange) {\n onDirtyStateChange(false)\n }\n } catch (error) {\n // Keep dirty state if save failed\n console.error('Save failed:', error)\n throw error\n }\n }, [onSave, onDirtyStateChange])\n\n // Enhanced config change handler that marks as dirty (only after initial load)\n const handleConfigChangeWithDirtyTracking = useCallback((config: DashboardConfig) => {\n if (onConfigChange) {\n onConfigChange(config)\n }\n \n // Check if this is a meaningful change from the initial config\n const configString = JSON.stringify(config)\n const initialConfigString = JSON.stringify(initialConfigRef.current)\n \n if (configString !== initialConfigString) {\n hasConfigChangedFromInitial.current = true\n \n if (onDirtyStateChange) {\n onDirtyStateChange(true)\n }\n }\n }, [onConfigChange, onDirtyStateChange])\n\n // Handle dashboard filter changes\n const handleDashboardFiltersChange = useCallback((filters: DashboardFilter[]) => {\n // Only update config if we're not using programmatic filters\n if (!propDashboardFilters || propDashboardFilters.length === 0) {\n const updatedConfig = {\n ...config,\n filters\n }\n handleConfigChangeWithDirtyTracking(updatedConfig)\n } else {\n console.warn('Dashboard filters are controlled via props - config changes ignored')\n }\n }, [config, propDashboardFilters, handleConfigChangeWithDirtyTracking])\n\n // Resolve complete palette object based on config\n const colorPalette = useMemo(() => {\n const paletteName = config.colorPalette\n return getColorPalette(paletteName)\n }, [config.colorPalette])\n\n return (\n <div className=\"w-full\">\n {/* Dashboard Grid (now includes filter panel) */}\n <DashboardGrid\n config={config}\n editable={editable}\n dashboardFilters={mergedDashboardFilters}\n loadingComponent={loadingComponent}\n onConfigChange={handleConfigChangeWithDirtyTracking}\n onSave={handleSaveWithDirtyTracking}\n colorPalette={colorPalette}\n schema={meta}\n onDashboardFiltersChange={handleDashboardFiltersChange}\n />\n </div>\n )\n}","/**\n * Portlet Container Component\n * Simple wrapper for individual portlets\n */\n\nimport { useState } from 'react'\nimport AnalyticsPortlet from './AnalyticsPortlet'\nimport DebugModal from './DebugModal'\nimport type { PortletConfig } from '../types'\n\ninterface PortletContainerProps {\n portlet: PortletConfig\n editable?: boolean\n onEdit?: (portlet: PortletConfig) => void\n onDelete?: (portletId: string) => void\n onRefresh?: (portletId: string) => void\n}\n\nexport default function PortletContainer({ \n portlet, \n editable = false,\n onEdit,\n onDelete,\n onRefresh\n}: PortletContainerProps) {\n const [debugData, setDebugData] = useState<{\n chartConfig: any\n displayConfig: any\n queryObject: any\n data: any[]\n chartType: string\n } | null>(null)\n\n return (\n <div className=\"bg-dc-surface border border-dc-border rounded-lg flex flex-col h-full\" style={{ boxShadow: 'var(--dc-shadow-sm)' }}>\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-dc-border shrink-0 bg-dc-surface-secondary rounded-t-lg px-3 py-2 md:px-6 md:py-3\">\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <h3 className=\"font-semibold text-sm truncate text-dc-text\">{portlet.title}</h3>\n {/* Debug button - right next to title */}\n {debugData && (\n <DebugModal\n chartConfig={debugData.chartConfig}\n displayConfig={debugData.displayConfig}\n queryObject={debugData.queryObject}\n data={debugData.data}\n chartType={debugData.chartType}\n />\n )}\n </div>\n\n <div className=\"flex items-center gap-2 ml-4\">\n\n {editable && (\n <>\n <button\n onClick={() => onRefresh?.(portlet.id)}\n className=\"p-1.5 hover:bg-dc-surface-hover rounded-sm text-dc-text-secondary\"\n title=\"Refresh\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\" />\n </svg>\n </button>\n <button\n onClick={() => onEdit?.(portlet)}\n className=\"p-1.5 hover:bg-dc-surface-hover rounded-sm text-dc-text-secondary\"\n title=\"Edit\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\" />\n </svg>\n </button>\n <button\n onClick={() => onDelete?.(portlet.id)}\n className=\"p-1.5 rounded-sm text-dc-danger\"\n style={{ backgroundColor: 'transparent' }}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-danger-bg)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'transparent'}\n title=\"Delete\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\" />\n </svg>\n </button>\n </>\n )}\n </div>\n </div>\n\n {/* Content */}\n <div className=\"px-2 py-3 md:px-4 md:pt-6 md:pb-4 flex-1 min-h-0\">\n <AnalyticsPortlet\n query={portlet.query}\n chartType={portlet.chartType}\n chartConfig={portlet.chartConfig}\n displayConfig={portlet.displayConfig}\n title={portlet.title}\n height=\"100%\"\n onDebugDataReady={(data) => {\n setDebugData(data)\n }}\n />\n </div>\n </div>\n )\n}","import React, { useState, useEffect } from 'react'\nimport Modal from './Modal'\n\ninterface DashboardEditModalProps {\n isOpen: boolean\n onClose: () => void\n onSave: (data: { name: string; description?: string }) => Promise<void> | void\n title: string\n submitText: string\n initialName?: string\n initialDescription?: string\n}\n\nexport default function DashboardEditModal({\n isOpen,\n onClose,\n onSave,\n title,\n submitText,\n initialName = '',\n initialDescription = ''\n}: DashboardEditModalProps) {\n const [name, setName] = useState('')\n const [description, setDescription] = useState('')\n const [isSaving, setIsSaving] = useState(false)\n\n // Initialize form values when modal opens\n useEffect(() => {\n if (isOpen) {\n setName(initialName)\n setDescription(initialDescription)\n }\n }, [isOpen, initialName, initialDescription])\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n \n if (!name.trim()) {\n return\n }\n\n setIsSaving(true)\n \n try {\n await onSave({\n name: name.trim(),\n description: description.trim() || undefined\n })\n handleClose()\n } catch (error) {\n // Failed to save dashboard\n // Don't close modal on error so user can retry\n } finally {\n setIsSaving(false)\n }\n }\n\n const handleClose = () => {\n setName('')\n setDescription('')\n setIsSaving(false)\n onClose()\n }\n\n const footer = (\n <>\n <button\n type=\"button\"\n onClick={handleClose}\n disabled={isSaving}\n className=\"px-4 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover disabled:opacity-50\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n form=\"dashboard-form\"\n disabled={isSaving || !name.trim()}\n className=\"px-4 py-2 text-sm font-medium text-white bg-dc-primary border border-transparent rounded-md hover:bg-dc-primary-hover disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isSaving ? 'Saving...' : submitText}\n </button>\n </>\n )\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={title}\n size=\"fullscreen-mobile\"\n footer={footer}\n >\n <form id=\"dashboard-form\" onSubmit={handleSubmit} className=\"space-y-4 w-full\">\n <div>\n <label htmlFor=\"dashboard-name\" className=\"block text-sm font-medium text-dc-text-secondary mb-1\">\n Dashboard Name\n </label>\n <input\n type=\"text\"\n id=\"dashboard-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary\"\n placeholder=\"Enter dashboard name...\"\n required\n autoFocus\n />\n </div>\n\n <div>\n <label htmlFor=\"dashboard-description\" className=\"block text-sm font-medium text-dc-text-secondary mb-1\">\n Description (optional)\n </label>\n <textarea\n id=\"dashboard-description\"\n rows={3}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary\"\n placeholder=\"Enter description...\"\n />\n </div>\n </form>\n </Modal>\n )\n}"],"names":["observerMap","RootIds","rootId","unsupportedValue","getRootId","root","optionsToId","options","key","createObserver","id","instance","elements","thresholds","observer","entries","entry","_a2","inView","threshold","callback","observe","element","fallbackInView","bounds","callbacks","useInView","delay","trackVisibility","rootMargin","triggerOnce","skip","initialInView","onChange","ref","setRef","React2","lastInViewRef","state","setState","unobserve","previousInView","entryTarget","previousEntryTarget","result","RefreshIcon","getIcon","ChartErrorBoundary","Component","props","error","errorInfo","jsxs","jsx","shouldIncludeFilter","filter","simpleFilter","f","getApplicableDashboardFilters","dashboardFilters","filterMapping","df","convertToServerFormat","groupFilter","convertedFilters","mergeDashboardAndPortletFilters","portletFilters","extractDashboardFields","dashboardConfig","measures","dimensions","timeDimensions","portlet","query","measure","dimension","td","extractFieldsFromFilters","field","e","filters","fields","getDateRangeFromFilter","applyUniversalTimeFilters","portletTimeDimensions","universalTimeFilters","dateRange","AnalyticsPortlet","forwardRef","chartType","chartConfig","displayConfig","dashboardFilterMapping","eagerLoad","_isVisible","height","_title","colorPalette","loadingComponent","onDebugDataReady","refreshCounter","setRefreshCounter","useState","onDebugDataReadyRef","useRef","scrollContainer","useScrollContainer","inViewRef","isVisible","useEffect","chartTypeConfig","useChartConfig","shouldSkipQuery","queryObject","useMemo","parsed","regularFilters","applicableFilters","mergedFilters","mergedTimeDimensions","shouldSkip","resultSet","isLoading","useCubeQuery","useImperativeHandle","prev","data","getData","hasMandatoryFields","zone","LoadingIndicator","chartHeight","isValidChartType","LazyChart","Modal","isOpen","onClose","title","size","closeOnBackdropClick","closeOnEscape","showCloseButton","children","footer","noPadding","handleEscapeKey","useCallback","event","getMeasureIcon","measureType","className","IconComponent","getMeasureTypeIcon","CubeRelationshipDiagram","lazy","mod","CubeMetaExplorer","schema","schemaStatus","schemaError","selectedFields","onFieldSelect","onFieldDeselect","onRetrySchema","onOpenSettings","onViewTypeChange","isExpanded","ChevronDownIcon","ChevronRightIcon","WarningIcon","SettingsIcon","MeasureIcon","DimensionIcon","TimeDimensionIcon","SegmentIcon","MenuIcon","features","useCubeContext","showSchemaDiagram","expandedCubes","setExpandedCubes","expandedSections","setExpandedSections","searchTerm","setSearchTerm","viewType","setViewType","preSearchExpandedCubes","setPreSearchExpandedCubes","preSearchExpandedSections","setPreSearchExpandedSections","React","newExpandedCubes","newExpandedSections","cube","cubeHasMatches","d","combinedCubes","combinedSections","isCorsError","Fragment","toggleCubeExpansion","cubeName","newExpanded","newPreSearchExpanded","toggleSectionExpansion","sectionKey","handleFieldClick","fieldType","filterFields","measureMatches","dimensionMatches","FieldItem","icon","isSelected","getSelectedStyles","getIconColor","getCheckmarkColor","SectionHeader","count","getSectionType","NoMatchesMessage","Suspense","fieldName","qbFieldType","c","fullFieldName","index","arr","filteredCubes","regularDimensions","timeDimension","TIME_GRANULARITIES","FILTER_OPERATORS","DATE_RANGE_OPTIONS","CloseIcon","FilterValueSelector","operator","values","onValuesChange","operatorMeta","setIsOpen","searchText","setSearchText","hasLoadedInitial","setHasLoadedInitial","dropdownRef","lastSearchedTerm","debouncedSearchText","useDebounce","isDimension","dim","isTimeDimension","shouldFetchValues","shouldShowComboBox","distinctValues","valuesLoading","valuesError","searchValues","useFilterValues","handleClickOutside","handleDropdownToggle","newIsOpen","handleSearchChange","newSearchText","handleValueSelect","value","handleValueRemove","valueToRemove","v","handleDirectInput","numValue","handleDateInput","currentValues","handleDateRangeEndInput","handleBetweenStartInput","newValues","handleBetweenEndInput","hasQueryContent","getSelectedFieldsCount","cleanQuery","cleanedQuery","cleanQueryForServer","transformFiltersForServer","createEmptyQuery","isSimpleFilter","isGroupFilter","isAndFilter","isOrFilter","getFilterableFields","allFields","a","b","getAllFilterableFields","getOrganizedFilterFields","getAvailableOperators","operators","meta","getFieldType","m","countFilters","countFilter","createSimpleFilter","member","createAndFilter","createOrFilter","cleanupFilters","_query","transformFilter","transformedSubFilters","convertDateRangeTypeToValue","rangeType","number","typeMap","unit","unitSingular","requiresNumberInput","formatDateForCube","date","getTimeDimensionsWithDateRanges","dateRanges","hasTimeDimensions","transformQueryForUI","transformed","transformFiltersFromServer","getFieldTitle","getSortDirection","order","getSortTooltip","direction","getNextSortDirection","current","FilterIcon","SearchIcon","FilterItem","onFilterChange","onFilterRemove","hideFieldSelector","hideOperatorSelector","hideRemoveButton","isFieldDropdownOpen","setIsFieldDropdownOpen","isOperatorDropdownOpen","setIsOperatorDropdownOpen","isDateRangeDropdownOpen","setIsDateRangeDropdownOpen","fieldSearchTerm","setFieldSearchTerm","containerRef","searchInputRef","setRangeType","customDates","setCustomDates","numberValue","setNumberValue","handleFieldDropdownToggle","newOpen","handleOperatorDropdownToggle","queryFields","selectedField","availableOperators","shouldShowDateRangeSelector","flexibleRangeMatch","num","found","option","filterFieldsBySearch","filteredQueryFields","filteredAllFields","getFieldTypeIcon","getFieldTypeBadge","handleFieldChange","newFieldType","defaultOperator","handleOperatorChange","handleValuesChange","handleDateRangeChange","handleRangeTypeChange","newRangeType","cubeRangeValue","handleCustomDateChange","newCustomDates","handleNumberChange","selectedRangeLabel","opt","op","AddIcon","FilterGroup","group","onGroupChange","onGroupChangeWithUnwrap","onGroupRemove","depth","showAddMenu","setShowAddMenu","isAndGroup","groupType","indentClass","borderColor","bgColor","textColor","handleGroupTypeToggle","newGroup","handleAddSimpleFilter","defaultField","newFilter","newFilters","handleAddAndGroup","handleAddOrGroup","handleFilterChange","filterIndex","handleFilterRemove","_","i","updatedGroup","handleNestedGroupChange","handleNestedGroupRemove","FilterBuilder","onFiltersChange","totalFilterCount","allFilterableFields","hasFilterableFields","andGroup","existingAndGroup","updatedAndGroup","existingOrGroup","updatedOrGroup","handleGroupChange","handleGroupChangeWithUnwrap","handleGroupRemove","handleClearAllFilters","CalendarIcon","DateRangeSelector","availableTimeDimensions","currentDateRange","onDateRangeChange","onTimeDimensionChange","onRemove","getCurrentRangeType","getCurrentDates","today","getCurrentNumber","isRangeDropdownOpen","setIsRangeDropdownOpen","isTimeDimensionDropdownOpen","setIsTimeDimensionDropdownOpen","handleTimeDimensionDropdownToggle","handleRangeDropdownToggle","handleTimeDimensionChange","newTimeDimension","DateRangeFilter","onDateRangeRemove","currentDateRanges","dateRangeCount","handleAddDateRange","firstAvailable","handleClearAllDateRanges","allTimeDimensions","t","oldTd","newTd","formatReason","reason","getReasonBadgeClasses","QueryAnalysisPanel","analysis","InfoIcon","ArrowRightIcon","TableIcon","LinkIcon","SuccessIcon","ErrorIcon","jp","idx","step","stepIdx","jc","pa","jk","w","QueryPanel","validationStatus","validationError","validationSql","validationAnalysis","onValidate","onExecute","onRemoveField","onTimeDimensionGranularityChange","onOrderChange","onClearQuery","showSettings","onSettingsClick","onAIAssistantClick","onSchemaClick","onShareClick","shareButtonState","isViewingShared","showJsonPreview","setShowJsonPreview","showSqlPreview","setShowSqlPreview","showAnalysisPreview","setShowAnalysisPreview","hasContent","selectedCount","DeleteIcon","CopyIcon","SparklesIcon","ChevronUpIcon","ChevronUpDownIcon","ShareIcon","RunIcon","CheckIcon","handleCopyQuery","textArea","hasFiltersApplied","currentFilters","hasFieldInFilters","handleAddFilterFromField","getSortIcon","handleToggleSort","next","getSortButtonClasses","sortDirection","baseClasses","RemovableChip","hasFilters","TimeDimensionChip","hasDateRange","granularity","newJsonState","newSqlState","newAnalysisState","chartConfigRegistry","barChartConfig","lineChartConfig","areaChartConfig","pieChartConfig","scatterChartConfig","bubbleChartConfig","radarChartConfig","radialBarChartConfig","treemapChartConfig","dataTableConfig","activityGridChartConfig","kpiNumberConfig","kpiDeltaConfig","kpiTextConfig","markdownConfig","ChartTypeSelector","selectedType","onTypeChange","chartTypes","chartTypeLabels","SelectedIcon","selectedLabel","type","config","label","description","useCase","tooltipText","AxisDropZone","onDrop","onDragStart","onDragEnd","onDragOver","getFieldStyling","onReorder","draggedItem","mandatory","maxItems","emptyText","dragOverIndex","setDragOverIndex","isDraggedOver","setIsDraggedOver","isReorderDraggedOver","setIsReorderDraggedOver","getCanAcceptMore","effectiveCount","getIsFull","canAcceptMore","isFull","handleGlobalDragEnd","handleReorderDragOver","targetIndex","handleReorderDragLeave","handleReorderDrop","rect","isLeavingContainer","relatedTarget","isRelatedTargetOutside","FieldIcon","hoverClasses","isDragOver","isBeingDragged","ChartConfigPanel","availableFields","onChartConfigChange","onDisplayConfigChange","setDraggedItem","getChartConfig","getFieldsForDropZone","allAvailableFields","hasChanges","newConfig","dropZone","currentFields","validFields","handleDragStart","fromAxis","fromIndex","handleDragOver","handleDragEnd","handleDrop","toAxis","fromValue","filteredValue","toValue","dz","handleRemoveFromAxis","handleReorder","toIndex","axisKey","newArray","movedItem","unassignedFields","assignedFields","color","ResultsPanel","executionStatus","executionResults","executionError","displayLimit","onDisplayLimitChange","totalRowCount","totalRowCountStatus","onChartTypeChange","activeViewProp","onActiveViewChange","TimeIcon","AdjustmentsIcon","localActiveView","setLocalActiveView","activeView","setActiveView","showChartConfig","setShowChartConfig","LoadingState","ErrorState","EmptyState","renderChart","SetupPanel","onToggle","onConfigChange","onReset","localConfig","setLocalConfig","handleApply","handleReset","defaultConfig","handleInputChange","isUsingDefaults","DEFAULT_SYSTEM_PROMPT_TEMPLATE","AI_STORAGE_KEY","DEFAULT_AI_CONFIG","sendGeminiMessage","apiKey","userPrompt","endpoint","requestBody","headers","response","errorMessage","errorData","errorText","loadAIConfig","saved","extractTextFromResponse","AIAssistantModal","onQueryLoad","aiEndpoint","handleQuerySubmit","responseText","validateResponse","handleValidate","handleUseQuery","handleClose","handleKeyDown","LZString","keyStrBase64","keyStrUriSafe","baseReverseDic","getBaseValue","alphabet","character","input","res","compressed","uncompressed","buf","TotalLen","current_value","bitsPerChar","getCharFromInt","context_dictionary","context_dictionaryToCreate","context_c","context_wc","context_w","context_enlargeIn","context_dictSize","context_numBits","context_data","context_data_val","context_data_position","ii","length","resetValue","getNextValue","dictionary","enlargeIn","dictSize","numBits","bits","resb","maxpower","power","module","MAX_HASH_LENGTH","SHARE_PREFIX","compressAndEncode","json","compressToEncodedURIComponent","decodeAndDecompress","encoded","decompressFromEncodedURIComponent","compressWithFallback","fullEncoded","queryOnlyState","queryOnlyEncoded","parseShareHash","hash","clearShareHash","url","getMaxHashLength","ShareWarningModal","maxSize","percentUsed","STORAGE_KEY","API_CONFIG_STORAGE_KEY","QueryBuilder","initialQuery","disableLocalStorage","hideSettings","enableSharing","onShare","cubeApi","updateApiConfig","getInitialApiConfig","getInitialState","parsedState","setDisplayLimit","initialChartState","setChartType","setChartConfig","setDisplayConfig","apiConfig","setApiConfig","showSetupPanel","setShowSetupPanel","showSchemaMobile","setShowSchemaMobile","schemaViewType","setSchemaViewType","showAIAssistant","setShowAIAssistant","setShareButtonState","showShareWarning","setShowShareWarning","shareWarningData","setShareWarningData","setIsViewingShared","lastValidatedQueryRef","fullValidationResult","setFullValidationResult","metaResponse","pendingSharedExecution","decoded","handleExecuteQuery","updateQuery","updater","newQuery","queryChanged","handleFieldSelect","handleFieldDeselect","newOrder","handleTimeDimensionGranularityChange","dimensionName","handleFiltersChange","handleDateRangeRemove","handleOrderChange","handleValidateQuery","queryToValidate","queryStr","isValid","debounceTimer","effectiveLimit","limitedResultSet","totalResultSet","limitedData","totalCount","handleClearQuery","handleShare","shareableState","queryOnly","queryOnlySize","handleApiConfigChange","handleResetApiConfig","handleRetrySchema","expanded","SAMPLE_QUERIES","PortletEditModal","onSave","submitText","formTitle","setFormTitle","setQuery","setDashboardFilterMapping","isValidating","setIsValidating","validationResult","setValidationResult","lastValidatedQuery","setLastValidatedQuery","dryRunData","setDryRunData","showQueryBuilder","setShowQueryBuilder","queryBuilderInitialQuery","setQueryBuilderInitialQuery","queryBuilderRef","autoPopulateChartConfig","_result","defaultWidth","defaultHeight","formattedQuery","runDryRunValidation","handleSubmit","hasQueryChanged","queryToSave","handleSampleQuery","sampleQuery","handleQueryChange","silent","isEditModeLoad","parsedQuery","details","message","errorMsg","handleOpenQueryBuilder","handleApplyQueryBuilderQuery","currentQuery","validationState","handleBackToForm","isEditMode","isQueryValidAndCurrent","sample","PortletFilterConfigModal","currentMapping","portletTitle","selectedFilters","setSelectedFilters","handleToggleFilter","filterId","handleSave","handleCancel","formatFilterPreview","valuesText","filterCount","DebugModal","timer","COLOR_PALETTES","getColorPalette","paletteName","p","ColorPaletteSelector","currentPalette","onPaletteChange","currentPaletteObj","handlePaletteSelect","palette","EyeIcon","EyeOffIcon","FilterEditModal","onDelete","convertToMetaResponse","localLabel","setLocalLabel","localFilter","setLocalFilter","showAllFields","setShowAllFields","dashboardFields","filteredSchema","filteredMeasures","fullName","filteredDimensions","filteredCubeMeta","selectedFieldInFilter","handleLabelChange","newLabel","handleFilterBuilderChange","_timeDim","validateFilter","validation","updatedFilter","ClockIcon","ReadOnlyFilterList","isTimeDimensionField","renderReadOnlyFilter","dashboardFilter","isUniversalTime","isTimeDim","dateRangeValue","_index","EditIcon","EditModeFilterList","onAddFilter","onAddTimeFilter","onEditFilter","onRemoveFilter","selectedFilterId","onFilterSelect","isCollapsed","setIsCollapsed","renderFilterChip","DashboardFilterPanel","editable","onDashboardFiltersChange","onSaveFilters","editingFilter","setEditingFilter","showFilterBuilder","setShowFilterBuilder","cubeMeta","s","generateFilterId","handleAddFilter","handleAddTimeFilter","updatedFilters","handleEditFilter","filterToEdit","handleRemoveFilter","handleSaveFilter","filterData","existingFilterIndex","handleCloseFilterBuilder","handleFilterDateRangeChange","handleReadOnlyFilterChange","ScaledGridWrapper","scaleFactor","designWidth","actualHeight","setActualHeight","innerRef","visualHeight","findScrollableAncestor","style","overflowY","overflowX","hasScrollableOverflow","hasScrollContent","MobileStackedLayout","onPortletRefresh","portletComponentRefs","setScrollContainer","setContainerRef","node","sortedPortlets","handlePortletRefresh","portletId","ScrollContainerProvider","portletHeight","headerHeight","contentHeight","el","ChartBarIcon","DesktopIcon","DashboardGrid","containerWidth","displayMode","isResponsiveEditable","useResponsiveDashboard","containerElementRef","combinedContainerRef","gridWidth","portletRefs","isInitialized","setIsInitialized","lastKnownLayout","setLastKnownLayout","setIsEditMode","setSelectedFilterId","isScrolled","setIsScrolled","isPortletModalOpen","setIsPortletModalOpen","editingPortlet","setEditingPortlet","isFilterConfigModalOpen","setIsFilterConfigModalOpen","filterConfigPortlet","setFilterConfigPortlet","debugData","setDebugData","initialLayout","handleScroll","scrollTop","hasLayoutActuallyChanged","newLayout","newItem","oldItem","item","handleLayoutChange","_layout","handleDragStop","layout","_oldItem","_newItem","_placeholder","_e","_element","mutableLayout","updatedPortlets","layoutItem","updatedConfig","handleResizeStop","portletComponent","handleAddPortlet","handleEditPortlet","handlePortletSave","portletData","isNewPortlet","newPortletId","newPortlet","gridLayout","maxY","scrollToPortlet","portletElement","handleDeletePortlet","handleDuplicatePortlet","originalPortlet","duplicatedPortlet","handlePaletteChange","handleOpenFilterConfig","handleSaveFilterConfig","mapping","handleToggleFilterForPortlet","hasFilter","handleFilterSelect","handleSelectAllForFilter","selectedFilter","canEdit","baseLayout","renderGridContent","ReactGridLayout","axis","verticalCompactor","hasSelectedFilter","isInSelectionMode","AnalyticsDashboard","propDashboardFilters","onDirtyStateChange","initialConfigRef","hasConfigChangedFromInitial","mergedDashboardFilters","configFilters","propFilters","configFilter","propFilter","pf","configIds","cf","handleSaveWithDirtyTracking","handleConfigChangeWithDirtyTracking","configString","initialConfigString","handleDashboardFiltersChange","PortletContainer","onEdit","onRefresh","DashboardEditModal","initialName","initialDescription","name","setName","setDescription","isSaving","setIsSaving"],"mappings":"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","x_google_ignoreList":[0,26]}
|