@sanity/vision 6.20.0 → 6.21.0-next.103
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/{CodeDiff-Bj_o50Qy.js → CodeDiff-MkS3Q87A.js} +14 -13
- package/lib/CodeDiff-MkS3Q87A.js.map +1 -0
- package/lib/{SanityVision-ePOzvdmp.js → SanityVision-tHhBPbsg.js} +209 -207
- package/lib/SanityVision-tHhBPbsg.js.map +1 -0
- package/lib/{VistaGui-DmXZyJ6k.js → VistaGui-D3NHSIsK.js} +942 -483
- package/lib/VistaGui-D3NHSIsK.js.map +1 -0
- package/lib/bundle.css +221 -210
- package/lib/{i18n-JS8KzGj8.js → i18n-BGSN3nAJ.js} +2 -2
- package/lib/{i18n-JS8KzGj8.js.map → i18n-BGSN3nAJ.js.map} +1 -1
- package/lib/index.d.ts +32 -4
- package/lib/index.js +2 -2
- package/lib/{resources-DFprICyb.js → resources-DpvWKOpU.js} +33 -5
- package/lib/resources-DpvWKOpU.js.map +1 -0
- package/package.json +19 -17
- package/lib/CodeDiff-Bj_o50Qy.js.map +0 -1
- package/lib/SanityVision-ePOzvdmp.js.map +0 -1
- package/lib/VistaGui-DmXZyJ6k.js.map +0 -1
- package/lib/resources-DFprICyb.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SanityVision-ePOzvdmp.js","names":["createTheme(theme)","useMemo(() => createTheme(theme), [theme])","syntaxHighlighting(createHighlight(theme))","useMemo(() => syntaxHighlighting(createHighlight(theme)), [theme])","[cmTheme, cmHighlight]","_c","t","{\n autoHeight,\n underHeader,\n children,\n}: {\n autoHeight: boolean\n underHeader: boolean\n children: ReactNode\n}","rem(sanity.space[3])","3","rem(sanity.space[4])","4","rem(sanity.space[underHeader ? 3 : 5])","sanity.space[underHeader ? 3 : 5]","assignInlineVars({\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [linePaddingLeftVar]: `${rem(sanity.space[3])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentBorderRightWidthVar]: `${rem(sanity.space[4])}`,\n // The tall top padding makes room for the label floating over a pane-filling editor\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentPaddingTopVar]: `${rem(sanity.space[underHeader ? 3 : 5])}`,\n })","`${rem(sanity.space[3])}`","`${rem(sanity.space[4])}`","`${rem(sanity.space[underHeader ? 3 : 5])}`","<div\n className={autoHeight ? `${editorRoot} ${editorRootAutoHeight}` : editorRoot}\n style={assignInlineVars({\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [linePaddingLeftVar]: `${rem(sanity.space[3])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentBorderRightWidthVar]: `${rem(sanity.space[4])}`,\n // The tall top padding makes room for the label floating over a pane-filling editor\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentPaddingTopVar]: `${rem(sanity.space[underHeader ? 3 : 5])}`,\n })}\n >\n {children}\n </div>","autoHeight ? `${editorRoot} ${editorRootAutoHeight}` : editorRoot","{\n ref,\n onChange,\n initialValue: initialValueProp,\n extensions,\n autoHeight = false,\n underHeader = autoHeight,\n}: Pick<ReactCodeMirrorProps, 'onChange'> & {\n initialValue: ReactCodeMirrorProps['value']\n extensions: Extension[]\n /**\n * Sizes the editor to its document instead of filling its container, for an editor that sits\n * under a header (so `underHeader` too)\n */\n autoHeight?: boolean\n /**\n * The editor sits under a header rather than under a label floating over it, so its content\n * needs less top padding\n */\n underHeader?: boolean\n} & RefAttributes<VisionCodeMirrorHandle>","autoHeight = false","underHeader = autoHeight","() => setHasView(true)","useCallback(() => setHasView(true), [])","() => {\n // The view is destroyed by the child's effect cleanups, which run along with this one\n return () => setHasView(false)\n }","[]","(nextValue, viewUpdate) => {\n setValue(nextValue)\n onChange?.(nextValue, viewUpdate)\n }","useCallback<NonNullable<ReactCodeMirrorProps['onChange']>>(\n (nextValue, viewUpdate) => {\n setValue(nextValue)\n onChange?.(nextValue, viewUpdate)\n },\n [onChange],\n )","(newContent: string) => {\n // Mirrored first, so a call made while there is no view still reaches the next one\n setValue(newContent)\n const editorView = codeMirrorRef.current?.view\n if (!editorView) return\n\n const currentDoc = editorView.state.doc.toString()\n if (newContent !== currentDoc) {\n editorView.dispatch({\n changes: {from: 0, to: currentDoc.length, insert: newContent},\n selection: EditorSelection.cursor(newContent.length), // Place cursor at end\n })\n // Show the new content from its start; longer lines in the replaced content may have\n // left the editor scrolled sideways\n editorView.scrollDOM.scrollTop = 0\n editorView.scrollDOM.scrollLeft = 0\n }\n }","useCallback((newContent: string) => {\n // Mirrored first, so a call made while there is no view still reaches the next one\n setValue(newContent)\n const editorView = codeMirrorRef.current?.view\n if (!editorView) return\n\n const currentDoc = editorView.state.doc.toString()\n if (newContent !== currentDoc) {\n editorView.dispatch({\n changes: {from: 0, to: currentDoc.length, insert: newContent},\n selection: EditorSelection.cursor(newContent.length), // Place cursor at end\n })\n // Show the new content from its start; longer lines in the replaced content may have\n // left the editor scrolled sideways\n editorView.scrollDOM.scrollTop = 0\n editorView.scrollDOM.scrollLeft = 0\n }\n }, [])","(changes: readonly {from: number; to: number; insert: string}[]) => {\n codeMirrorRef.current?.view?.dispatch({changes: [...changes], userEvent: 'input'})\n }","useCallback(\n (changes: readonly {from: number; to: number; insert: string}[]) => {\n codeMirrorRef.current?.view?.dispatch({changes: [...changes], userEvent: 'input'})\n },\n [],\n )","(command: Command) => {\n const editorView = codeMirrorRef.current?.view\n return editorView ? command(editorView) : false\n }","editorView","useCallback((command: Command) => {\n const editorView = codeMirrorRef.current?.view\n return editorView ? command(editorView) : false\n }, [])","(from: number, to: number) => {\n const editorView = codeMirrorRef.current?.view\n if (!editorView) return\n\n const length = editorView.state.doc.length\n editorView.dispatch({\n selection: EditorSelection.range(Math.min(from, length), Math.min(to, length)),\n scrollIntoView: true,\n })\n editorView.focus()\n }","useCallback((from: number, to: number) => {\n const editorView = codeMirrorRef.current?.view\n if (!editorView) return\n\n const length = editorView.state.doc.length\n editorView.dispatch({\n selection: EditorSelection.range(Math.min(from, length), Math.min(to, length)),\n scrollIntoView: true,\n })\n editorView.focus()\n }, [])","(lines?: number) => {\n const editorView = codeMirrorRef.current?.view\n return editorView ? getVisibleColumns(editorView, {lines}) : undefined\n }","useCallback((lines?: number) => {\n const editorView = codeMirrorRef.current?.view\n return editorView ? getVisibleColumns(editorView, {lines}) : undefined\n }, [])","() => ({\n resetEditorContent,\n applyChanges,\n runCommand,\n selectRange,\n getVisibleColumns: getVisibleColumnsOfEditor,\n })","[resetEditorContent, applyChanges, runCommand, selectRange, getVisibleColumnsOfEditor]","<CodeMirror\n ref={codeMirrorRef}\n basicSetup={false}\n theme={theme}\n extensions={extensions}\n value={value}\n onChange={handleChange}\n onCreateEditor={handleCreateEditor}\n />","<EditorRoot autoHeight={autoHeight} underHeader={underHeader}>\n <CodeMirror\n ref={codeMirrorRef}\n basicSetup={false}\n theme={theme}\n extensions={extensions}\n value={value}\n onChange={handleChange}\n onCreateEditor={handleCreateEditor}\n />\n </EditorRoot>","_c","EditorSelection","{\n ref,\n ...props\n}: ComponentPropsWithoutRef<typeof Flex> & RefAttributes<HTMLDivElement>","<Flex {...props} ref={ref} className={root} />","<Card {...props} className={header} />","<Label {...props} className={styledLabel} />","<Box {...props} className={splitpaneContainer} />","<Flex {...props} flexDirection=\"column\" className={queryRecallPaneContainer} />","<Flex\n {...props}\n flexDirection=\"column\"\n flexBasis=\"0%\"\n flexGrow={1}\n overflow=\"hidden\"\n className={queryRecallPaneWrapper}\n />","<a {...props} className={queryCopyLink} />","<Box {...props} className={inputBackgroundContainer} />","<Box {...props} className={`${inputBackgroundContainer} ${inputBackgroundContainerLeft}`} />","<Card {...props} className={inputContainer} />","<Flex {...props} className={resultOuterContainer} />","<Box {...props} className={resultInnerContainer} />","{\n isInvalid,\n ...props\n}: ComponentProps<typeof Card> & {isInvalid: boolean}","<Card\n {...props}\n className={isInvalid ? `${resultContainer} ${resultContainerInvalid}` : resultContainer}\n />","isInvalid ? `${resultContainer} ${resultContainerInvalid}` : resultContainer","<Box {...props} className={result} />","<Flex {...props} className={resultFooter} />","<Card {...props} className={timingsCard} />","rem(\n space[3] * 2 + textSize.lineHeight - textSize.ascenderHeight - textSize.descenderHeight,\n )","space[3] * 2 + textSize.lineHeight - textSize.ascenderHeight - textSize.descenderHeight","assignInlineVars({[timingsTextMinHeightVar]: `${minHeight}`})","`${minHeight}`","<Flex\n {...props}\n className={timingsTextContainer}\n style={assignInlineVars({[timingsTextMinHeightVar]: `${minHeight}`})}\n />","<Card {...props} className={downloadsCard} />","rem(space[3])","3","assignInlineVars({[saveResultSpanGapVar]: `${rem(space[3])}`})","`${rem(space[3])}`","<Text\n {...props}\n className={saveResultLabel}\n style={assignInlineVars({[saveResultSpanGapVar]: `${rem(space[3])}`})}\n />","<Box {...props} className={controlsContainer} />","_c","useThemeV2","minHeight","(newValue: string) => {\n onChange(newValue)\n }","useCallback(\n (newValue: string) => {\n onChange(newValue)\n },\n [onChange],\n )","debounce(handleChangeRaw, 333)","useMemo(() => debounce(handleChangeRaw, 333), [handleChangeRaw])","t('params.label')","<StyledLabel muted>{t('params.label')}</StyledLabel>","paramsError && (\n <Tooltip animate placement=\"top\" portal content={<Text size={1}>{paramsError}</Text>}>\n <Box padding={1} marginX={2}>\n <Text>\n <ErrorOutlineIcon />\n </Text>\n </Box>\n </Tooltip>\n )","<InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('params.label')}</StyledLabel>\n {paramsError && (\n <Tooltip animate placement=\"top\" portal content={<Text size={1}>{paramsError}</Text>}>\n <Box padding={1} marginX={2}>\n <Text>\n <ErrorOutlineIcon />\n </Text>\n </Box>\n </Tooltip>\n )}\n </Flex>\n </InputBackgroundContainerLeft>","<VisionCodeMirror\n ref={editorRef}\n initialValue={props.value || defaultValue}\n onChange={handleChange}\n extensions={paramsExtensions}\n />","props.value || defaultValue","<Card flex={1} tone={hasValidParams ? 'default' : 'critical'} data-testid=\"params-editor\">\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('params.label')}</StyledLabel>\n {paramsError && (\n <Tooltip animate placement=\"top\" portal content={<Text size={1}>{paramsError}</Text>}>\n <Box padding={1} marginX={2}>\n <Text>\n <ErrorOutlineIcon />\n </Text>\n </Box>\n </Tooltip>\n )}\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n ref={editorRef}\n initialValue={props.value || defaultValue}\n onChange={handleChange}\n extensions={paramsExtensions}\n />\n </Card>","hasValidParams ? 'default' : 'critical'","defaultValue","_c","{apiVersion: DEFAULT_API_VERSION}","[]","Promise.resolve()","new Map<string, Promise<void>>()","keyValueStore.getKey(keyValueStoreKey)","useMemo(() => {\n return keyValueStore.getKey(keyValueStoreKey)\n }, [keyValueStore])","(docs: SharedQueryDocument[]): QueryConfig[] => {\n const currentUserId = currentUser?.id\n\n return docs.map((doc) => ({\n _key: doc._id,\n authorId: doc.authorId,\n isOwnedByCurrentUser: doc.authorId === currentUserId,\n savedAt: doc.savedAt,\n shared: true,\n title: doc.title,\n url: doc.url,\n }))\n }","id","useCallback(\n (docs: SharedQueryDocument[]): QueryConfig[] => {\n const currentUserId = currentUser?.id\n\n return docs.map((doc) => ({\n _key: doc._id,\n authorId: doc.authorId,\n isOwnedByCurrentUser: doc.authorId === currentUserId,\n savedAt: doc.savedAt,\n shared: true,\n title: doc.title,\n url: doc.url,\n }))\n },\n [currentUser],\n )","() => {\n // The store emits its localStorage copy synchronously (`null` without one), the server's\n // list once read, and then every write. Nothing is prepended: this effect runs again when a\n // hidden `<Activity>` shows the tool again, and an initial value would reset the list, and\n // with it the base the next write starts from, to empty. Each subscription starts a new\n // server read, and the store's events reach it only once that read is done\n storeEventsLiveRef.current = false\n let subscribing = true\n const sub = personalQueries.subscribe({\n next: (data) => {\n const stored = data ? (data as unknown as StoredQueries) : null\n const ownWrites = ownWritesRef.current\n if (ownWrites && !storeEventsLiveRef.current) {\n if (!reflectsOwnWrites(stored?.queries ?? defaultValue.queries, ownWrites)) return\n // The localStorage copy comes synchronously while subscribing, ahead of the read;\n // anything after it is the read or an event, both of which mean the read is done\n if (!subscribing) storeEventsLiveRef.current = true\n }\n if (pendingPersonalWritesRef.current > 0) return\n // A list taken from the store while its events are live is the store's own, with nothing\n // of this hook's left to see reflected\n if (storeEventsLiveRef.current) ownWritesRef.current = null\n if (!stored) {\n // No localStorage copy; the server's answer follows, and a list already shown stays\n if (loadedPersonalQueriesRef.current) return\n latestQueriesRef.current = defaultValue.queries\n setValue(defaultValue)\n return\n }\n loadedPersonalQueriesRef.current = true\n latestQueriesRef.current = stored.queries\n setValue(stored)\n },\n error: (err) => setError(err as Error),\n })\n subscribing = false\n\n return () => sub.unsubscribe()\n }","[personalQueries]","() => {\n let cancelled = false\n\n const fetchSharedQueries = async () => {\n const docs = await workspaceClient.fetch<SharedQueryDocument[]>(SHARED_QUERIES_QUERY, {\n sharedQueryType: SHARED_QUERY_DOCUMENT_TYPE,\n })\n const nextDocs = docs || []\n if (!cancelled) {\n setSharedQueries(mapSharedQueries(nextDocs))\n }\n }\n\n void fetchSharedQueries().catch((err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n })\n\n const sub = workspaceClient.observable\n .listen(\n `*[_type == $sharedQueryType]`,\n {\n sharedQueryType: SHARED_QUERY_DOCUMENT_TYPE,\n },\n SHARED_QUERY_LISTEN_OPTIONS,\n )\n .subscribe({\n next: () => {\n void fetchSharedQueries().catch((err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n })\n },\n error: (err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n },\n })\n\n return () => {\n cancelled = true\n sub.unsubscribe()\n }\n }","[workspaceClient, mapSharedQueries]","docs","err","sub","<T>(task: () => Promise<T>): Promise<T> => {\n pendingPersonalWritesRef.current += 1\n const run = () =>\n task().finally(() => {\n pendingPersonalWritesRef.current -= 1\n })\n const result = personalWritesRef.current.then(run, run)\n personalWritesRef.current = result.catch(() => undefined)\n return result\n }","() => undefined","useCallback(<T>(task: () => Promise<T>): Promise<T> => {\n pendingPersonalWritesRef.current += 1\n const run = () =>\n task().finally(() => {\n pendingPersonalWritesRef.current -= 1\n })\n const result = personalWritesRef.current.then(run, run)\n personalWritesRef.current = result.catch(() => undefined)\n return result\n }, [])","(before: QueryConfig[], attempted: QueryConfig[], kept: QueryConfig[]) => {\n const keys = new Set(ownWritesRef.current?.keys)\n for (const key of changedKeys(before, attempted)) keys.add(key)\n ownWritesRef.current = {latest: kept, keys}\n }","useCallback(\n (before: QueryConfig[], attempted: QueryConfig[], kept: QueryConfig[]) => {\n const keys = new Set(ownWritesRef.current?.keys)\n for (const key of changedKeys(before, attempted)) keys.add(key)\n ownWritesRef.current = {latest: kept, keys}\n },\n [],\n )","async (queries: QueryConfig[]) => {\n const stored = await keyValueStore.setKey(keyValueStoreKey, {\n queries,\n } as unknown as KeyValueStoreValue)\n if (stored === null) {\n throw new Error('The saved queries could not be stored.')\n }\n }","stored","useCallback(\n async (queries: QueryConfig[]) => {\n const stored = await keyValueStore.setKey(keyValueStoreKey, {\n queries,\n } as unknown as KeyValueStoreValue)\n if (stored === null) {\n throw new Error('The saved queries could not be stored.')\n }\n },\n [keyValueStore],\n )","(update: (queries: QueryConfig[]) => QueryConfig[]): Promise<QueryConfig[]> =>\n enqueuePersonalWrite(async () => {\n const before = latestQueriesRef.current\n const next = update(before)\n recordOwnWrite(before, next, next)\n latestQueriesRef.current = next\n setValue({queries: next})\n try {\n await storePersonalQueries(next)\n } catch (err) {\n // The store kept the previous list, so the UI shows it again\n recordOwnWrite(before, next, before)\n latestQueriesRef.current = before\n setValue({queries: before})\n throw err\n }\n return next\n })","before","useCallback(\n (update: (queries: QueryConfig[]) => QueryConfig[]): Promise<QueryConfig[]> =>\n enqueuePersonalWrite(async () => {\n const before = latestQueriesRef.current\n const next = update(before)\n recordOwnWrite(before, next, next)\n latestQueriesRef.current = next\n setValue({queries: next})\n try {\n await storePersonalQueries(next)\n } catch (err) {\n // The store kept the previous list, so the UI shows it again\n recordOwnWrite(before, next, before)\n latestQueriesRef.current = before\n setValue({queries: before})\n throw err\n }\n return next\n }),\n [enqueuePersonalWrite, recordOwnWrite, storePersonalQueries],\n )","[...sharedQueries, ...value.queries].sort((a, b) => {\n return new Date(b.savedAt || 0).getTime() - new Date(a.savedAt || 0).getTime()\n })","queries","(a, b) => {\n return new Date(b.savedAt || 0).getTime() - new Date(a.savedAt || 0).getTime()\n }","useMemo(() => {\n return [...sharedQueries, ...value.queries].sort((a, b) => {\n return new Date(b.savedAt || 0).getTime() - new Date(a.savedAt || 0).getTime()\n })\n }, [sharedQueries, value.queries])","<T>(task: () => Promise<T>): Promise<T> => {\n setPendingSaves((count) => count + 1)\n setSaveQueryError(undefined)\n return task()\n .catch((err: unknown) => {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n throw saveError\n })\n .finally(() => setPendingSaves((count) => count - 1))\n }","(count) => count + 1","task","(count) => count - 1","useCallback(<T>(task: () => Promise<T>): Promise<T> => {\n setPendingSaves((count) => count + 1)\n setSaveQueryError(undefined)\n return task()\n .catch((err: unknown) => {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n throw saveError\n })\n .finally(() => setPendingSaves((count) => count - 1))\n }, [])","(query: Omit<QueryConfig, '_key'>): Promise<string> =>\n runSave(async () => {\n if (query.shared) {\n if (!currentUser?.id) {\n throw new Error('No current user found. Unable to save shared query.')\n }\n const createdDoc = (await workspaceClient.create({\n _type: SHARED_QUERY_DOCUMENT_TYPE,\n authorId: currentUser.id,\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })) as SharedQueryDocument\n setSharedQueries((prev) => [...mapSharedQueries([createdDoc]), ...prev])\n return createdDoc._id\n }\n\n const newQuery = {...query, _key: uuid()}\n await writePersonalQueries((queries) => [newQuery, ...queries])\n return newQuery._key\n })","currentUser?.id","useCallback(\n (query: Omit<QueryConfig, '_key'>): Promise<string> =>\n runSave(async () => {\n if (query.shared) {\n if (!currentUser?.id) {\n throw new Error('No current user found. Unable to save shared query.')\n }\n const createdDoc = (await workspaceClient.create({\n _type: SHARED_QUERY_DOCUMENT_TYPE,\n authorId: currentUser.id,\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })) as SharedQueryDocument\n setSharedQueries((prev) => [...mapSharedQueries([createdDoc]), ...prev])\n return createdDoc._id\n }\n\n const newQuery = {...query, _key: uuid()}\n await writePersonalQueries((queries) => [newQuery, ...queries])\n return newQuery._key\n }),\n [currentUser, workspaceClient, mapSharedQueries, runSave, writePersonalQueries],\n )","(query: QueryConfig): Promise<void> =>\n runSave(async () => {\n if (query.shared) {\n if (!currentUser?.id || query.authorId !== currentUser.id) {\n throw new Error('Only the author can update a shared query.')\n }\n const updatedDoc = (await workspaceClient\n .patch(query._key)\n .set({\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })\n .commit()) as SharedQueryDocument\n\n const [updatedSharedQuery] = mapSharedQueries([updatedDoc])\n setSharedQueries((prev) =>\n prev.map((existingQuery) =>\n existingQuery._key === query._key ? updatedSharedQuery : existingQuery,\n ),\n )\n return\n }\n\n await writePersonalQueries((queries) =>\n queries.map((q) => (q._key === query._key ? {...q, ...query} : q)),\n )\n })","query","prev","useCallback(\n (query: QueryConfig): Promise<void> =>\n runSave(async () => {\n if (query.shared) {\n if (!currentUser?.id || query.authorId !== currentUser.id) {\n throw new Error('Only the author can update a shared query.')\n }\n const updatedDoc = (await workspaceClient\n .patch(query._key)\n .set({\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })\n .commit()) as SharedQueryDocument\n\n const [updatedSharedQuery] = mapSharedQueries([updatedDoc])\n setSharedQueries((prev) =>\n prev.map((existingQuery) =>\n existingQuery._key === query._key ? updatedSharedQuery : existingQuery,\n ),\n )\n return\n }\n\n await writePersonalQueries((queries) =>\n queries.map((q) => (q._key === query._key ? {...q, ...query} : q)),\n )\n }),\n [workspaceClient, currentUser, mapSharedQueries, runSave, writePersonalQueries],\n )","async (key: string) => {\n const sharedQuery = sharedQueries.find((query) => query._key === key && query.shared)\n if (!sharedQuery) {\n throw new Error(`No shared query with key \"${key}\"`)\n }\n if (!currentUser?.id || sharedQuery.authorId !== currentUser.id) {\n throw new Error('Only the author can delete a shared query.')\n }\n await workspaceClient.delete(key)\n setSharedQueries((prev) => prev.filter((query) => query._key !== key))\n }","key","useCallback(\n async (key: string) => {\n const sharedQuery = sharedQueries.find((query) => query._key === key && query.shared)\n if (!sharedQuery) {\n throw new Error(`No shared query with key \"${key}\"`)\n }\n if (!currentUser?.id || sharedQuery.authorId !== currentUser.id) {\n throw new Error('Only the author can delete a shared query.')\n }\n await workspaceClient.delete(key)\n setSharedQueries((prev) => prev.filter((query) => query._key !== key))\n },\n [currentUser, sharedQueries, workspaceClient],\n )","async (key: string) => {\n await writePersonalQueries((queries) => queries.filter((q) => q._key !== key))\n }","q","useCallback(\n async (key: string) => {\n await writePersonalQueries((queries) => queries.filter((q) => q._key !== key))\n },\n [writePersonalQueries],\n )","async (key: string) => {\n setDeleting((prev) => [...prev, key])\n setDeleteQueryError(undefined)\n try {\n if (sharedQueries.some((query) => query._key === key && query.shared)) {\n await deleteSharedQuery(key)\n } else {\n await deletePersonalQuery(key)\n }\n } catch (err) {\n setDeleteQueryError(err instanceof Error ? err : new Error(String(err)))\n }\n setDeleting((prev) => prev.filter((k) => k !== key))\n }","useCallback(\n async (key: string) => {\n setDeleting((prev) => [...prev, key])\n setDeleteQueryError(undefined)\n try {\n if (sharedQueries.some((query) => query._key === key && query.shared)) {\n await deleteSharedQuery(key)\n } else {\n await deletePersonalQuery(key)\n }\n } catch (err) {\n setDeleteQueryError(err instanceof Error ? err : new Error(String(err)))\n }\n setDeleting((prev) => prev.filter((k) => k !== key))\n },\n [deletePersonalQuery, deleteSharedQuery, sharedQueries],\n )","(key: string, move: (alsoMoving: (copyKey: string) => void) => Promise<void>) => {\n const pending = movesRef.current.get(key)\n if (pending) {\n return pending\n }\n const keys = new Set([key])\n const alsoMoving = (copyKey: string) => {\n const thisMove = movesRef.current.get(key)\n if (thisMove) movesRef.current.set(copyKey, thisMove)\n keys.add(copyKey)\n setMoving((prev) => [...prev, copyKey])\n }\n setMoving((prev) => [...prev, key])\n const result = move(alsoMoving).finally(() => {\n for (const moved of keys) movesRef.current.delete(moved)\n setMoving((prev) => prev.filter((moved) => !keys.has(moved)))\n })\n movesRef.current.set(key, result)\n return result\n }","keys","result","moved","useCallback(\n (key: string, move: (alsoMoving: (copyKey: string) => void) => Promise<void>) => {\n const pending = movesRef.current.get(key)\n if (pending) {\n return pending\n }\n const keys = new Set([key])\n const alsoMoving = (copyKey: string) => {\n const thisMove = movesRef.current.get(key)\n if (thisMove) movesRef.current.set(copyKey, thisMove)\n keys.add(copyKey)\n setMoving((prev) => [...prev, copyKey])\n }\n setMoving((prev) => [...prev, key])\n const result = move(alsoMoving).finally(() => {\n for (const moved of keys) movesRef.current.delete(moved)\n setMoving((prev) => prev.filter((moved) => !keys.has(moved)))\n })\n movesRef.current.set(key, result)\n return result\n },\n [],\n )","(key: string) =>\n runMove(key, async (alsoMoving) => {\n const query = latestQueriesRef.current.find((q) => q._key === key)\n if (!query) {\n throw new Error(`No personal saved query with key \"${key}\"`)\n }\n const sharedKey = await saveQuery({\n shared: true,\n title: query.title,\n url: query.url,\n savedAt: new Date().toISOString(),\n })\n alsoMoving(sharedKey)\n try {\n await deletePersonalQuery(key)\n } catch (err) {\n try {\n await workspaceClient.delete(sharedKey)\n setSharedQueries((prev) => prev.filter((q) => q._key !== sharedKey))\n } catch {\n throw moveLeftBothCopies(err, 'shared')\n }\n throw err\n }\n })","useCallback(\n (key: string) =>\n runMove(key, async (alsoMoving) => {\n const query = latestQueriesRef.current.find((q) => q._key === key)\n if (!query) {\n throw new Error(`No personal saved query with key \"${key}\"`)\n }\n const sharedKey = await saveQuery({\n shared: true,\n title: query.title,\n url: query.url,\n savedAt: new Date().toISOString(),\n })\n alsoMoving(sharedKey)\n try {\n await deletePersonalQuery(key)\n } catch (err) {\n try {\n await workspaceClient.delete(sharedKey)\n setSharedQueries((prev) => prev.filter((q) => q._key !== sharedKey))\n } catch {\n throw moveLeftBothCopies(err, 'shared')\n }\n throw err\n }\n }),\n [deletePersonalQuery, runMove, saveQuery, workspaceClient],\n )","(key: string) =>\n runMove(key, async (alsoMoving) => {\n const query = sharedQueries.find((q) => q._key === key)\n if (!query) {\n throw new Error(`No shared query with key \"${key}\"`)\n }\n const personalKey = await saveQuery({\n shared: false,\n title: query.title,\n url: query.url,\n savedAt: new Date().toISOString(),\n })\n alsoMoving(personalKey)\n try {\n await deleteSharedQuery(key)\n } catch (err) {\n try {\n await deletePersonalQuery(personalKey)\n } catch {\n throw moveLeftBothCopies(err, 'personal')\n }\n throw err\n }\n })","useCallback(\n (key: string) =>\n runMove(key, async (alsoMoving) => {\n const query = sharedQueries.find((q) => q._key === key)\n if (!query) {\n throw new Error(`No shared query with key \"${key}\"`)\n }\n const personalKey = await saveQuery({\n shared: false,\n title: query.title,\n url: query.url,\n savedAt: new Date().toISOString(),\n })\n alsoMoving(personalKey)\n try {\n await deleteSharedQuery(key)\n } catch (err) {\n try {\n await deletePersonalQuery(personalKey)\n } catch {\n throw moveLeftBothCopies(err, 'personal')\n }\n throw err\n }\n }),\n [deletePersonalQuery, deleteSharedQuery, runMove, saveQuery, sharedQueries],\n )","() =>\n enqueuePersonalWrite(async () => {\n // Nothing disappears from the list until the store confirms the write\n const before = latestQueriesRef.current\n recordOwnWrite(before, defaultValue.queries, defaultValue.queries)\n try {\n await storePersonalQueries(defaultValue.queries)\n } catch (err) {\n recordOwnWrite(before, defaultValue.queries, before)\n throw err\n }\n latestQueriesRef.current = defaultValue.queries\n setValue(defaultValue)\n })","useCallback(\n () =>\n enqueuePersonalWrite(async () => {\n // Nothing disappears from the list until the store confirms the write\n const before = latestQueriesRef.current\n recordOwnWrite(before, defaultValue.queries, defaultValue.queries)\n try {\n await storePersonalQueries(defaultValue.queries)\n } catch (err) {\n recordOwnWrite(before, defaultValue.queries, before)\n throw err\n }\n latestQueriesRef.current = defaultValue.queries\n setValue(defaultValue)\n }),\n [enqueuePersonalWrite, recordOwnWrite, storePersonalQueries],\n )","{\n queries,\n saveQuery,\n updateQuery,\n deleteQuery,\n shareQuery,\n unshareQuery,\n clearQueries,\n saving: pendingSaves > 0,\n deleting,\n moving,\n saveQueryError,\n deleteQueryError,\n error,\n }","pendingSaves > 0","count","isEqual","_c","_temp","_temp2","_temp3","<VStack {...props} className={fixedHeader} />","<Flex\n {...props}\n flexDirection=\"column\"\n flexBasis=\"0%\"\n flexGrow={1}\n overflow=\"hidden\"\n className={scrollContainer}\n />","<Box {...props} flexBasis=\"0%\" flexGrow={1} overflow=\"auto\" className={queryList} />","{\n url,\n getStateFromUrl,\n setStateFromParsedUrl,\n currentQuery,\n currentParams,\n generateUrl,\n compactMode = false,\n}: {\n url?: string\n getStateFromUrl: (data: string) => ParsedUrlState | null\n setStateFromParsedUrl: (parsedUrlObj: ParsedUrlState) => void\n currentQuery: string\n currentParams: Record<string, unknown>\n generateUrl: (query: string, params: Record<string, unknown>) => string\n compactMode?: boolean\n}","compactMode = false","{\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n }","{}","[]","async () => {\n // Generate the correct URL first\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(new Date(duplicateQuery?.savedAt || ''))}`,\n })\n return\n }\n\n if (!newUrl) return\n\n try {\n await saveQuery({\n shared: false,\n url: newUrl,\n savedAt: new Date().toISOString(),\n title: t('label.untitled-query'),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n }","queries?.some","q","savedQueryObj","err","useCallback(async () => {\n // Generate the correct URL first\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(new Date(duplicateQuery?.savedAt || ''))}`,\n })\n return\n }\n\n if (!newUrl) return\n\n try {\n await saveQuery({\n shared: false,\n url: newUrl,\n savedAt: new Date().toISOString(),\n title: t('label.untitled-query'),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n }, [\n queries,\n toast,\n t,\n currentQuery,\n currentParams,\n getStateFromUrl,\n generateUrl,\n formatDate,\n saveQuery,\n ])","(query: QueryConfig) => {\n setShareDialogQuery(query)\n }","useCallback((query: QueryConfig) => {\n setShareDialogQuery(query)\n }, [])","async () => {\n if (!shareDialogQuery) return\n\n try {\n // One move: when removing the personal copy fails, the shared one is taken back and the\n // move rejects, rather than the query staying in both lists behind a success toast\n await shareQuery(shareDialogQuery._key)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.shared-success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n setShareDialogQuery(null)\n }","useCallback(async () => {\n if (!shareDialogQuery) return\n\n try {\n // One move: when removing the personal copy fails, the shared one is taken back and the\n // move rejects, rather than the query staying in both lists behind a success toast\n await shareQuery(shareDialogQuery._key)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.shared-success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n setShareDialogQuery(null)\n }, [shareDialogQuery, shareQuery, t, toast])","async (query: QueryConfig) => {\n setPendingUnshareKeys((prev) => [...prev, query._key])\n const clearPending = () =>\n setPendingUnshareKeys((prev) => prev.filter((key) => key !== query._key))\n const nextQueryObj = getStateFromUrl(query.url)\n const duplicatePersonalQuery = queries?.find((existingQuery) => {\n if (existingQuery._key === query._key) return false\n if (existingQuery.shared) return false\n const existingQueryObj = getStateFromUrl(existingQuery.url)\n return (\n nextQueryObj &&\n existingQueryObj &&\n existingQueryObj.query === nextQueryObj.query &&\n isEqual(existingQueryObj.params, nextQueryObj.params)\n )\n })\n if (duplicatePersonalQuery) {\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicatePersonalQuery.title} - ${formatDate.format(\n new Date(duplicatePersonalQuery.savedAt || ''),\n )}`,\n })\n clearPending()\n return\n }\n\n try {\n // One move, like sharing: a personal copy that cannot replace the shared one is taken back\n await unshareQuery(query._key)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.unshared-success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n clearPending()\n }","queries?.find","query","prev","useCallback(\n async (query: QueryConfig) => {\n setPendingUnshareKeys((prev) => [...prev, query._key])\n const clearPending = () =>\n setPendingUnshareKeys((prev) => prev.filter((key) => key !== query._key))\n const nextQueryObj = getStateFromUrl(query.url)\n const duplicatePersonalQuery = queries?.find((existingQuery) => {\n if (existingQuery._key === query._key) return false\n if (existingQuery.shared) return false\n const existingQueryObj = getStateFromUrl(existingQuery.url)\n return (\n nextQueryObj &&\n existingQueryObj &&\n existingQueryObj.query === nextQueryObj.query &&\n isEqual(existingQueryObj.params, nextQueryObj.params)\n )\n })\n if (duplicatePersonalQuery) {\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicatePersonalQuery.title} - ${formatDate.format(\n new Date(duplicatePersonalQuery.savedAt || ''),\n )}`,\n })\n clearPending()\n return\n }\n\n try {\n // One move, like sharing: a personal copy that cannot replace the shared one is taken back\n await unshareQuery(query._key)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.unshared-success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n clearPending()\n },\n [formatDate, getStateFromUrl, queries, t, toast, unshareQuery],\n )","async (query: QueryConfig, newTitle: string) => {\n setEditingKey(null)\n setOptimisticTitles((prev) => ({...prev, [query._key]: newTitle}))\n\n try {\n await updateQuery({\n ...query,\n title: newTitle,\n })\n // Clear optimistic title on success\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n } catch (err) {\n // Clear optimistic title on error\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n }","next","useCallback(\n async (query: QueryConfig, newTitle: string) => {\n setEditingKey(null)\n setOptimisticTitles((prev) => ({...prev, [query._key]: newTitle}))\n\n try {\n await updateQuery({\n ...query,\n title: newTitle,\n })\n // Clear optimistic title on success\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n } catch (err) {\n // Clear optimistic title on error\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n },\n [updateQuery, toast, t],\n )","async (query: QueryConfig) => {\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n // Skip the current query when checking for duplicates\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(\n new Date(duplicateQuery?.savedAt || ''),\n )}`,\n })\n return\n }\n\n try {\n await updateQuery({\n ...query,\n url: newUrl,\n savedAt: new Date().toISOString(),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n }","newUrl","isDuplicate","duplicateQuery","useCallback(\n async (query: QueryConfig) => {\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n // Skip the current query when checking for duplicates\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(\n new Date(duplicateQuery?.savedAt || ''),\n )}`,\n })\n return\n }\n\n try {\n await updateQuery({\n ...query,\n url: newUrl,\n savedAt: new Date().toISOString(),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n },\n [\n currentQuery,\n currentParams,\n formatDate,\n generateUrl,\n updateQuery,\n toast,\n t,\n queries,\n getStateFromUrl,\n ],\n )","Flex","QueryList","ScrollContainer","3","\"column\"","filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <VStack gap={compactMode ? 2 : 3}>\n <Flex\n justifyContent=\"space-between\"\n alignItems={'center'}\n style={{minHeight: '25px'}}\n >\n <Flex alignItems=\"center\" gap={2} paddingRight={1} style={{flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex alignItems=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{\n animate: true,\n portal: true,\n placement: 'bottom-end',\n tone: 'default',\n }}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n animate\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <VStack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex alignItems=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </VStack>\n ) : (\n <Flex\n alignItems=\"center\"\n gap={2}\n style={{paddingTop: '2px', minHeight: '20px'}}\n >\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </VStack>\n </Card>\n )\n })","\"vision-query-recall-list\"","<FixedHeader gap={3}>\n <Flex\n padding={3}\n paddingTop={2}\n paddingBottom={0}\n justifyContent=\"space-between\"\n alignItems=\"center\"\n >\n <StyledLabel muted>{t('label.saved-queries')}</StyledLabel>\n <Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />\n </Flex>\n <Box padding={3} paddingTop={0}>\n <TextInput\n placeholder={t('label.search-queries')}\n icon={SearchIcon}\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.currentTarget.value)}\n />\n </Box>\n <Box paddingX={3} paddingBottom={2}>\n <TabList gap={1}>\n <Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />\n <Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />\n <Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />\n </TabList>\n </Box>\n </FixedHeader>","queries?.filter","t('label.saved-queries')","<StyledLabel muted>{t('label.saved-queries')}</StyledLabel>","t('action.save-query')","() => void handleSave()","<Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />","<Flex\n padding={3}\n paddingTop={2}\n paddingBottom={0}\n justifyContent=\"space-between\"\n alignItems=\"center\"\n >\n <StyledLabel muted>{t('label.saved-queries')}</StyledLabel>\n <Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />\n </Flex>","t('label.search-queries')","(event) => setSearchQuery(event.currentTarget.value)","<Box padding={3} paddingTop={0}>\n <TextInput\n placeholder={t('label.search-queries')}\n icon={SearchIcon}\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.currentTarget.value)}\n />\n </Box>","t('label.all')","() => setQueryFilter('all')","<Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />","queryFilter === 'all'","t('label.personal')","() => setQueryFilter('personal')","<Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />","queryFilter === 'personal'","t('label.shared')","() => setQueryFilter('shared')","<Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />","queryFilter === 'shared'","<Box paddingX={3} paddingBottom={2}>\n <TabList gap={1}>\n <Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />\n <Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />\n <Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />\n </TabList>\n </Box>","event","<Flex paddingY={3} flexDirection=\"column\">\n {filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <VStack gap={compactMode ? 2 : 3}>\n <Flex\n justifyContent=\"space-between\"\n alignItems={'center'}\n style={{minHeight: '25px'}}\n >\n <Flex alignItems=\"center\" gap={2} paddingRight={1} style={{flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex alignItems=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{\n animate: true,\n portal: true,\n placement: 'bottom-end',\n tone: 'default',\n }}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n animate\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <VStack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex alignItems=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </VStack>\n ) : (\n <Flex\n alignItems=\"center\"\n gap={2}\n style={{paddingTop: '2px', minHeight: '20px'}}\n >\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </VStack>\n </Card>\n )\n })}\n </Flex>","<QueryList id=\"vision-query-recall-list\">\n <Flex paddingY={3} flexDirection=\"column\">\n {filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <VStack gap={compactMode ? 2 : 3}>\n <Flex\n justifyContent=\"space-between\"\n alignItems={'center'}\n style={{minHeight: '25px'}}\n >\n <Flex alignItems=\"center\" gap={2} paddingRight={1} style={{flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex alignItems=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{\n animate: true,\n portal: true,\n placement: 'bottom-end',\n tone: 'default',\n }}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n animate\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <VStack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex alignItems=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </VStack>\n ) : (\n <Flex\n alignItems=\"center\"\n gap={2}\n style={{paddingTop: '2px', minHeight: '20px'}}\n >\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </VStack>\n </Card>\n )\n })}\n </Flex>\n </QueryList>","shareDialogQuery && (\n <Dialog\n animate\n id=\"vision-query-recall-share-dialog\"\n width={1}\n header={t('label.share')}\n onClose={() => setShareDialogQuery(null)}\n footer={\n <Flex justifyContent=\"flex-end\" gap={3} padding={3} alignItems=\"center\">\n <Button\n mode=\"bleed\"\n padding={2}\n text={t('action.query-cancel')}\n onClick={() => setShareDialogQuery(null)}\n />\n <Button\n padding={2}\n tone=\"primary\"\n text={t('action.save-shared-query')}\n onClick={() => void handleConfirmShareQuery()}\n />\n </Flex>\n }\n >\n <Box padding={4}>\n <Text size={2}>{t('save-query.share-warning')}</Text>\n </Box>\n </Dialog>\n )","<ScrollContainer>\n <FixedHeader gap={3}>\n <Flex\n padding={3}\n paddingTop={2}\n paddingBottom={0}\n justifyContent=\"space-between\"\n alignItems=\"center\"\n >\n <StyledLabel muted>{t('label.saved-queries')}</StyledLabel>\n <Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />\n </Flex>\n <Box padding={3} paddingTop={0}>\n <TextInput\n placeholder={t('label.search-queries')}\n icon={SearchIcon}\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.currentTarget.value)}\n />\n </Box>\n <Box paddingX={3} paddingBottom={2}>\n <TabList gap={1}>\n <Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />\n <Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />\n <Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />\n </TabList>\n </Box>\n </FixedHeader>\n <QueryList id=\"vision-query-recall-list\">\n <Flex paddingY={3} flexDirection=\"column\">\n {filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <VStack gap={compactMode ? 2 : 3}>\n <Flex\n justifyContent=\"space-between\"\n alignItems={'center'}\n style={{minHeight: '25px'}}\n >\n <Flex alignItems=\"center\" gap={2} paddingRight={1} style={{flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex alignItems=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{\n animate: true,\n portal: true,\n placement: 'bottom-end',\n tone: 'default',\n }}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n animate\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <VStack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex alignItems=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </VStack>\n ) : (\n <Flex\n alignItems=\"center\"\n gap={2}\n style={{paddingTop: '2px', minHeight: '20px'}}\n >\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </VStack>\n </Card>\n )\n })}\n </Flex>\n </QueryList>\n {shareDialogQuery && (\n <Dialog\n animate\n id=\"vision-query-recall-share-dialog\"\n width={1}\n header={t('label.share')}\n onClose={() => setShareDialogQuery(null)}\n footer={\n <Flex justifyContent=\"flex-end\" gap={3} padding={3} alignItems=\"center\">\n <Button\n mode=\"bleed\"\n padding={2}\n text={t('action.query-cancel')}\n onClick={() => setShareDialogQuery(null)}\n />\n <Button\n padding={2}\n tone=\"primary\"\n text={t('action.save-shared-query')}\n onClick={() => void handleConfirmShareQuery()}\n />\n </Flex>\n }\n >\n <Box padding={4}>\n <Text size={2}>{t('save-query.share-warning')}</Text>\n </Box>\n </Dialog>\n )}\n </ScrollContainer>","_c","isEqual","{\n visionRootRef,\n}: {\n visionRootRef: React.RefObject<HTMLDivElement | null>\n}","() => ({\n width: typeof window !== 'undefined' ? window.innerWidth : 1000,\n height: typeof window !== 'undefined' ? window.innerHeight : 800,\n })","() => narrowBreakpoint()","() =>\n calculatePaneSizeOptions(undefined)","() => {\n if (!visionRootRef.current) {\n return undefined\n }\n const handleResize = (entries: ResizeObserverEntry[]) => {\n const entry = entries?.[0]\n if (entry) {\n setRootSize({width: entry.contentRect.width, height: entry.contentRect.height})\n setIsNarrowBreakpoint(entry.contentRect.width > 600)\n setPaneSizeOptions(calculatePaneSizeOptions(entry.contentRect.height))\n }\n }\n const resizeObserver = new ResizeObserver(handleResize)\n resizeObserver.observe(visionRootRef.current)\n\n return () => {\n resizeObserver.disconnect()\n }\n }","[visionRootRef]","visionRootRef.current","{paneSizeOptions, isNarrowBreakpoint, rootSize}","_c","_temp","_temp2","_temp3","{\n hasValidParams,\n listenInProgress,\n queryInProgress,\n onQueryExecution,\n onListenExecution,\n onSwitchToRedesign,\n}: VisionGuiControlsProps","t('params.error.params-invalid-json')","<Card radius={4}>\n <Text size={1} muted>\n {t('params.error.params-invalid-json')}\n </Text>\n </Card>","<Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>","queryInProgress ? t('action.query-cancel') : t('action.query-execute')","<Box flexBasis=\"0%\" flexGrow={1}>\n <Tooltip\n animate\n content={\n <Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>\n }\n placement=\"top\"\n portal\n >\n <Button\n width=\"fill\"\n onClick={onQueryExecution}\n type=\"button\"\n icon={queryInProgress ? StopIcon : PlayIcon}\n disabled={listenInProgress || !hasValidParams}\n tone={queryInProgress ? 'positive' : 'primary'}\n text={queryInProgress ? t('action.query-cancel') : t('action.query-execute')}\n />\n </Tooltip>\n </Box>","queryInProgress ? StopIcon : PlayIcon","listenInProgress || !hasValidParams","queryInProgress ? 'positive' : 'primary'","listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')","<Box flexBasis=\"0%\" flexGrow={1} marginLeft={3}>\n <Button\n width=\"fill\"\n onClick={onListenExecution}\n type=\"button\"\n icon={listenInProgress ? StopIcon : PlayIcon}\n text={listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')}\n mode=\"ghost\"\n disabled={!hasValidParams}\n tone={listenInProgress ? 'positive' : 'default'}\n />\n </Box>","!hasValidParams","listenInProgress ? 'positive' : 'default'","listenInProgress ? StopIcon : PlayIcon","onSwitchToRedesign && (\n <Box flexShrink={0} marginLeft={3}>\n <Tooltip\n animate\n content={<Text size={1}>{t('vista.redesign.try.description')}</Text>}\n placement=\"top\"\n portal\n >\n <Button\n aria-label={t('vista.redesign.try')}\n data-testid=\"vision-try-redesign\"\n icon={RocketIcon}\n mode=\"bleed\"\n onClick={onSwitchToRedesign}\n tone=\"primary\"\n type=\"button\"\n />\n </Tooltip>\n </Box>\n )","<Flex justifyContent=\"space-evenly\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <Tooltip\n animate\n content={\n <Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>\n }\n placement=\"top\"\n portal\n >\n <Button\n width=\"fill\"\n onClick={onQueryExecution}\n type=\"button\"\n icon={queryInProgress ? StopIcon : PlayIcon}\n disabled={listenInProgress || !hasValidParams}\n tone={queryInProgress ? 'positive' : 'primary'}\n text={queryInProgress ? t('action.query-cancel') : t('action.query-execute')}\n />\n </Tooltip>\n </Box>\n <Box flexBasis=\"0%\" flexGrow={1} marginLeft={3}>\n <Button\n width=\"fill\"\n onClick={onListenExecution}\n type=\"button\"\n icon={listenInProgress ? StopIcon : PlayIcon}\n text={listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')}\n mode=\"ghost\"\n disabled={!hasValidParams}\n tone={listenInProgress ? 'positive' : 'default'}\n />\n </Box>\n {onSwitchToRedesign && (\n <Box flexShrink={0} marginLeft={3}>\n <Tooltip\n animate\n content={<Text size={1}>{t('vista.redesign.try.description')}</Text>}\n placement=\"top\"\n portal\n >\n <Button\n aria-label={t('vista.redesign.try')}\n data-testid=\"vision-try-redesign\"\n icon={RocketIcon}\n mode=\"bleed\"\n onClick={onSwitchToRedesign}\n tone=\"primary\"\n type=\"button\"\n />\n </Tooltip>\n </Box>\n )}\n </Flex>","<ControlsContainer>\n <Card padding={3} paddingX={3}>\n <Tooltip\n animate\n content={\n <Card radius={4}>\n <Text size={1} muted>\n {t('params.error.params-invalid-json')}\n </Text>\n </Card>\n }\n placement=\"top\"\n disabled={hasValidParams}\n portal\n >\n <Flex justifyContent=\"space-evenly\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <Tooltip\n animate\n content={\n <Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>\n }\n placement=\"top\"\n portal\n >\n <Button\n width=\"fill\"\n onClick={onQueryExecution}\n type=\"button\"\n icon={queryInProgress ? StopIcon : PlayIcon}\n disabled={listenInProgress || !hasValidParams}\n tone={queryInProgress ? 'positive' : 'primary'}\n text={queryInProgress ? t('action.query-cancel') : t('action.query-execute')}\n />\n </Tooltip>\n </Box>\n <Box flexBasis=\"0%\" flexGrow={1} marginLeft={3}>\n <Button\n width=\"fill\"\n onClick={onListenExecution}\n type=\"button\"\n icon={listenInProgress ? StopIcon : PlayIcon}\n text={listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')}\n mode=\"ghost\"\n disabled={!hasValidParams}\n tone={listenInProgress ? 'positive' : 'default'}\n />\n </Box>\n {onSwitchToRedesign && (\n <Box flexShrink={0} marginLeft={3}>\n <Tooltip\n animate\n content={<Text size={1}>{t('vista.redesign.try.description')}</Text>}\n placement=\"top\"\n portal\n >\n <Button\n aria-label={t('vista.redesign.try')}\n data-testid=\"vision-try-redesign\"\n icon={RocketIcon}\n mode=\"bleed\"\n onClick={onSwitchToRedesign}\n tone=\"primary\"\n type=\"button\"\n />\n </Tooltip>\n </Box>\n )}\n </Flex>\n </Tooltip>\n </Card>\n </ControlsContainer>","_c","<Box {...props} className={perspectivePopoverContent} />","<a {...props} className={perspectivePopoverLink} />","{tone}: {tone: CardTone}","<div className={dot} style={{backgroundColor: `var(--card-badge-${tone}-dot-color)`}} />","`var(--card-badge-${tone}-dot-color)`","() => setOpen((o) => !o)","(o) => !o","useCallback(() => setOpen((o) => !o), [])","() => setOpen(false)","() => [buttonRef.current, popoverRef.current]","t('settings.perspectives.title')","<Inline gap={2}>\n <Text weight=\"medium\">{t('settings.perspectives.title')}</Text>\n </Inline>","t('settings.perspectives.description')","<Card>\n <Text muted>{t('settings.perspectives.description')}</Text>\n </Card>","t('label.new')","<Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>","<Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>","<Card>\n <VStack gap={2}>\n <Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>\n <Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>\n </VStack>\n </Card>","SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? (\n <Card>\n <Badge tone=\"caution\">{t('label.new')}</Badge>\n <Card>\n <Text muted>\n <Translate t={t} i18nKey=\"settings.perspectives.new-default.description\" />\n </Text>\n </Card>\n </Card>\n ) : null","t('settings.perspectives.action.docs-link')","<Card>\n <Text>\n <PerspectivePopoverLink\n href=\"https://www.sanity.io/docs/perspectives\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t('settings.perspectives.action.docs-link')} →\n </PerspectivePopoverLink>\n </Text>\n </Card>","<PerspectivePopoverContent>\n <VStack gap={4}>\n <Inline gap={2}>\n <Text weight=\"medium\">{t('settings.perspectives.title')}</Text>\n </Inline>\n\n <Card>\n <Text muted>{t('settings.perspectives.description')}</Text>\n </Card>\n <Card>\n <VStack gap={2}>\n <Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>\n <Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>\n </VStack>\n </Card>\n {SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? (\n <Card>\n <Badge tone=\"caution\">{t('label.new')}</Badge>\n <Card>\n <Text muted>\n <Translate t={t} i18nKey=\"settings.perspectives.new-default.description\" />\n </Text>\n </Card>\n </Card>\n ) : null}\n\n <Card>\n <Text>\n <PerspectivePopoverLink\n href=\"https://www.sanity.io/docs/perspectives\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t('settings.perspectives.action.docs-link')} →\n </PerspectivePopoverLink>\n </Text>\n </Card>\n </VStack>\n </PerspectivePopoverContent>","<Dot tone={SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? 'caution' : 'primary'} />","<Button\n icon={HelpCircleIcon}\n mode=\"bleed\"\n padding={2}\n paddingRight={1}\n tone=\"primary\"\n fontSize={1}\n ref={buttonRef}\n onClick={handleClick}\n selected={open}\n >\n <Dot tone={SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? 'caution' : 'primary'} />\n </Button>","<Popover\n animate\n content={\n <PerspectivePopoverContent>\n <VStack gap={4}>\n <Inline gap={2}>\n <Text weight=\"medium\">{t('settings.perspectives.title')}</Text>\n </Inline>\n\n <Card>\n <Text muted>{t('settings.perspectives.description')}</Text>\n </Card>\n <Card>\n <VStack gap={2}>\n <Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>\n <Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>\n </VStack>\n </Card>\n {SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? (\n <Card>\n <Badge tone=\"caution\">{t('label.new')}</Badge>\n <Card>\n <Text muted>\n <Translate t={t} i18nKey=\"settings.perspectives.new-default.description\" />\n </Text>\n </Card>\n </Card>\n ) : null}\n\n <Card>\n <Text>\n <PerspectivePopoverLink\n href=\"https://www.sanity.io/docs/perspectives\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t('settings.perspectives.action.docs-link')} →\n </PerspectivePopoverLink>\n </Text>\n </Card>\n </VStack>\n </PerspectivePopoverContent>\n }\n placement=\"bottom-start\"\n portal\n padding={3}\n ref={popoverRef}\n open={open}\n >\n <Button\n icon={HelpCircleIcon}\n mode=\"bleed\"\n padding={2}\n paddingRight={1}\n tone=\"primary\"\n fontSize={1}\n ref={buttonRef}\n onClick={handleClick}\n selected={open}\n >\n <Dot tone={SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? 'caution' : 'primary'} />\n </Button>\n </Popover>","_c","_temp","{pinnedPerspective, t}","variant ? getVariantTitle(variant) : variantName","selectedVariantNames","selectedVariants","getDefaultVariant(pinnedPerspective.selectedVariantNames)","hasPinnedPerspective(pinnedPerspective)\n ? `(${t('settings.perspectives.pinned-release-label')})`\n : t('settings.perspectives.pinned-release-label')","[name, variantTitle ? `· ${variantTitle}` : undefined, label]\n .filter((value) => typeof value !== 'undefined')","variantTitle ? `· ${variantTitle}` : undefined","(value) => typeof value !== 'undefined'","hasPinnedPerspective(pinnedPerspective)","<option value=\"pinnedRelease\" disabled={!hasPinnedPerspective(pinnedPerspective)}>\n {text}\n </option>","!hasPinnedPerspective(pinnedPerspective)","{\n onChangeDataset,\n dataset,\n customApiVersion,\n apiVersion,\n onChangeApiVersion,\n datasets,\n customApiVersionElementRef,\n onCustomApiVersionChange,\n isValidApiVersion,\n onChangePerspective,\n url,\n perspective,\n isScheduledDraftsEnabled,\n}: VisionGuiHeaderProps","getActiveVariant(perspective, getDefaultVariant(pinnedPerspective.selectedVariantNames))","() => {\n const el = operationUrlElement.current\n if (!el) return\n\n try {\n el.select()\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n document.execCommand('copy')\n } catch {\n console.error('Unable to copy to clipboard :(')\n }\n }","useCallback(() => {\n const el = operationUrlElement.current\n if (!el) return\n\n try {\n el.select()\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n document.execCommand('copy')\n } catch {\n console.error('Unable to copy to clipboard :(')\n }\n }, [])","[\n 'repeat(1, minmax(0, 1fr))',\n 'repeat(4, minmax(0, 1fr))',\n 'repeat(8, minmax(0, 1fr))',\n 'repeat(12, minmax(0, 1fr))',\n ]","['span 1 / span 1', 'span 2 / span 2']","t('settings.dataset-label')","<Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.dataset-label')}</StyledLabel>\n </Card>","datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))","(ds: string) => (\n <option key={ds}>{ds}</option>\n )","<Select value={dataset} onChange={onChangeDataset}>\n {datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))}\n </Select>","<Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <VStack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.dataset-label')}</StyledLabel>\n </Card>\n <Select value={dataset} onChange={onChangeDataset}>\n {datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))}\n </Select>\n </VStack>\n </Box>","t('settings.api-version-label')","<Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.api-version-label')}</StyledLabel>\n </Card>","t('settings.api-version-locked-for-variant')","<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>","API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))","(version) => (\n <option key={version}>{version}</option>\n )","t('settings.other-api-version-label')","<option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>","<Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>","customApiVersion === false ? apiVersion : 'other'","<Tooltip\n animate\n content={<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>}\n disabled={!isApiVersionLocked}\n placement=\"bottom\"\n portal\n >\n <Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>\n </Tooltip>","!isApiVersionLocked","<Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <VStack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.api-version-label')}</StyledLabel>\n </Card>\n <Tooltip\n animate\n content={<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>}\n disabled={!isApiVersionLocked}\n placement=\"bottom\"\n portal\n >\n <Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>\n </Tooltip>\n </VStack>\n </Box>","!isApiVersionLocked && customApiVersion !== false && (\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <VStack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel textOverflow=\"ellipsis\">\n {t('settings.custom-api-version-label')}\n </StyledLabel>\n </Card>\n\n <TextInput\n ref={customApiVersionElementRef}\n value={customApiVersion}\n onChange={onCustomApiVersionChange}\n customValidity={\n isValidApiVersion ? undefined : t('settings.error.invalid-api-version')\n }\n maxLength={11}\n />\n </VStack>\n </Box>\n )","t('settings.perspective-label')","<Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>","<Box>\n <PerspectivePopover />\n </Box>","<Card paddingBottom={1}>\n <Inline gap={1}>\n <Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>\n\n <Box>\n <PerspectivePopover />\n </Box>\n </Inline>\n </Card>","SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })","<Select\n data-testid=\"perspective-selector\"\n value={perspective || 'default'}\n onChange={onChangePerspective}\n >\n {SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })}\n </Select>","perspective || 'default'","<Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <VStack>\n <Card paddingBottom={1}>\n <Inline gap={1}>\n <Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>\n\n <Box>\n <PerspectivePopover />\n </Box>\n </Inline>\n </Card>\n <Select\n data-testid=\"perspective-selector\"\n value={perspective || 'default'}\n onChange={onChangePerspective}\n >\n {SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })}\n </Select>\n </VStack>\n </Box>","typeof url === 'string' ? (\n <Box\n padding={1}\n flexBasis=\"0%\"\n flexGrow={1}\n gridColumn={[\n 'span 1 / span 1',\n customApiVersion === false ? 'span 6 / span 6' : 'span 4 / span 4',\n ]}\n >\n <VStack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>\n {t('query.url')} \n <QueryCopyLink\n href={url}\n onClick={(event) => {\n // This is a copy-to-clipboard action, not a navigation\n event.preventDefault()\n handleCopyUrl()\n }}\n >\n [{t('action.copy-url-to-clipboard')}]\n </QueryCopyLink>\n </StyledLabel>\n </Card>\n <Flex flexBasis=\"0%\" flexGrow={1} gap={1}>\n <Box flexBasis=\"0%\" flexGrow={1}>\n <TextInput\n data-testid=\"vision-query-url\"\n readOnly\n type=\"url\"\n ref={operationUrlElement}\n value={url}\n />\n </Box>\n <Tooltip animate content={t('action.copy-url-to-clipboard')}>\n <Button\n aria-label={t('action.copy-url-to-clipboard')}\n type=\"button\"\n mode=\"ghost\"\n icon={CopyIcon}\n onClick={handleCopyUrl}\n />\n </Tooltip>\n </Flex>\n </VStack>\n </Box>\n ) : (\n <Box flexBasis=\"0%\" flexGrow={1} />\n )","<Header paddingX={3} paddingY={2}>\n <Grid\n gridTemplateColumns={[\n 'repeat(1, minmax(0, 1fr))',\n 'repeat(4, minmax(0, 1fr))',\n 'repeat(8, minmax(0, 1fr))',\n 'repeat(12, minmax(0, 1fr))',\n ]}\n >\n {/* Dataset selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <VStack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.dataset-label')}</StyledLabel>\n </Card>\n <Select value={dataset} onChange={onChangeDataset}>\n {datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))}\n </Select>\n </VStack>\n </Box>\n\n {/* API version selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <VStack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.api-version-label')}</StyledLabel>\n </Card>\n <Tooltip\n animate\n content={<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>}\n disabled={!isApiVersionLocked}\n placement=\"bottom\"\n portal\n >\n <Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>\n </Tooltip>\n </VStack>\n </Box>\n\n {/* Custom API version input */}\n {!isApiVersionLocked && customApiVersion !== false && (\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <VStack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel textOverflow=\"ellipsis\">\n {t('settings.custom-api-version-label')}\n </StyledLabel>\n </Card>\n\n <TextInput\n ref={customApiVersionElementRef}\n value={customApiVersion}\n onChange={onCustomApiVersionChange}\n customValidity={\n isValidApiVersion ? undefined : t('settings.error.invalid-api-version')\n }\n maxLength={11}\n />\n </VStack>\n </Box>\n )}\n\n {/* Perspective selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <VStack>\n <Card paddingBottom={1}>\n <Inline gap={1}>\n <Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>\n\n <Box>\n <PerspectivePopover />\n </Box>\n </Inline>\n </Card>\n <Select\n data-testid=\"perspective-selector\"\n value={perspective || 'default'}\n onChange={onChangePerspective}\n >\n {SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })}\n </Select>\n </VStack>\n </Box>\n\n {/* Query URL (for copying) */}\n {typeof url === 'string' ? (\n <Box\n padding={1}\n flexBasis=\"0%\"\n flexGrow={1}\n gridColumn={[\n 'span 1 / span 1',\n customApiVersion === false ? 'span 6 / span 6' : 'span 4 / span 4',\n ]}\n >\n <VStack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>\n {t('query.url')} \n <QueryCopyLink\n href={url}\n onClick={(event) => {\n // This is a copy-to-clipboard action, not a navigation\n event.preventDefault()\n handleCopyUrl()\n }}\n >\n [{t('action.copy-url-to-clipboard')}]\n </QueryCopyLink>\n </StyledLabel>\n </Card>\n <Flex flexBasis=\"0%\" flexGrow={1} gap={1}>\n <Box flexBasis=\"0%\" flexGrow={1}>\n <TextInput\n data-testid=\"vision-query-url\"\n readOnly\n type=\"url\"\n ref={operationUrlElement}\n value={url}\n />\n </Box>\n <Tooltip animate content={t('action.copy-url-to-clipboard')}>\n <Button\n aria-label={t('action.copy-url-to-clipboard')}\n type=\"button\"\n mode=\"ghost\"\n icon={CopyIcon}\n onClick={handleCopyUrl}\n />\n </Tooltip>\n </Flex>\n </VStack>\n </Box>\n ) : (\n <Box flexBasis=\"0%\" flexGrow={1} />\n )}\n </Grid>\n </Header>","_c","variantName","_temp","_temp2","_temp3","() => {\n const timer = setTimeout(() => setShow(true), props.delay || 500)\n return () => clearTimeout(timer)\n }","[props.delay]","delay","show ? <Spinner muted size={4} /> : null","_c","<Code {...props} className={errorCode} />","_c","{error}: {error: ContentLakeQueryError | Error}","ErrorCode","details.line","dashLine(\n details.column,\n details.columnEnd,\n )","1","details","error.details","<ErrorCode size={1}>{`${details.line}\\n${dashLine(\n details.column,\n details.columnEnd,\n )}`}</ErrorCode>","`${details.line}\\n${dashLine(\n details.column,\n details.columnEnd,\n )}`","t('query.error.line')","t(\n 'query.error.column',\n )","details.lineNumber","<Box marginTop={4}>\n <ErrorCode size={1}>{`${t('query.error.line')}: ${details.lineNumber}\\n${t(\n 'query.error.column',\n )}: ${details.column}`}</ErrorCode>\n </Box>","`${t('query.error.line')}: ${details.lineNumber}\\n${t(\n 'query.error.column',\n )}: ${details.column}`","<div>\n <ErrorCode size={1}>{`${details.line}\\n${dashLine(\n details.column,\n details.columnEnd,\n )}`}</ErrorCode>\n <Box marginTop={4}>\n <ErrorCode size={1}>{`${t('query.error.line')}: ${details.lineNumber}\\n${t(\n 'query.error.column',\n )}: ${details.column}`}</ErrorCode>\n </Box>\n </div>","_c","Flex","5","2","\"column\"","unsatisfiedCapability ? (\n <Text data-testid=\"query-error-api-version-capability-hint\" size={1}>\n {t(unsatisfiedCapability.explanationKey, {\n apiVersion: prefixApiVersion(unsatisfiedCapability.requiredApiVersion),\n })}\n </Text>\n ) : null","<ErrorCode size={1}>{error.message}</ErrorCode>","message","<QueryErrorDetails error={error} />","<Flex gap={5} marginTop={2} flexDirection=\"column\">\n {unsatisfiedCapability ? (\n <Text data-testid=\"query-error-api-version-capability-hint\" size={1}>\n {t(unsatisfiedCapability.explanationKey, {\n apiVersion: prefixApiVersion(unsatisfiedCapability.requiredApiVersion),\n })}\n </Text>\n ) : null}\n <ErrorCode size={1}>{error.message}</ErrorCode>\n <QueryErrorDetails error={error} />\n </Flex>","_c","{children, copyable}: {children: ReactNode; copyable?: boolean}","rem(space[0])","0","rem(space[2])","2","rem(space[4])","4","rem(space[4] / 2)","space[4] / 2","assignInlineVars({\n [codeFamilyVar]: font.code.family,\n [codeFontSizeVar]: `${codeSize.fontSize}px`,\n [codeLineHeightVar]: `${codeSize.lineHeight}px`,\n [space0Var]: `${rem(space[0])}`,\n [space2Var]: `${rem(space[2])}`,\n [space4Var]: `${rem(space[4])}`,\n [space4HalfVar]: `${rem(space[4] / 2)}`,\n [syntaxPropertyVar]: color.syntax.property,\n [syntaxConstantVar]: color.syntax.constant,\n [syntaxStringVar]: color.syntax.string,\n [syntaxBooleanVar]: color.syntax.boolean,\n [syntaxNumberVar]: color.syntax.number,\n })","boolean","constant","number","property","string","family","`${rem(space[4])}`","`${rem(space[4] / 2)}`","`${codeSize.fontSize}px`","`${codeSize.lineHeight}px`","`${rem(space[0])}`","`${rem(space[2])}`","font.code.family","<div\n className={copyable ? `${resultViewWrapper} ${copyableResult}` : resultViewWrapper}\n style={assignInlineVars({\n [codeFamilyVar]: font.code.family,\n [codeFontSizeVar]: `${codeSize.fontSize}px`,\n [codeLineHeightVar]: `${codeSize.lineHeight}px`,\n [space0Var]: `${rem(space[0])}`,\n [space2Var]: `${rem(space[2])}`,\n [space4Var]: `${rem(space[4])}`,\n [space4HalfVar]: `${rem(space[4] / 2)}`,\n [syntaxPropertyVar]: color.syntax.property,\n [syntaxConstantVar]: color.syntax.constant,\n [syntaxStringVar]: color.syntax.string,\n [syntaxBooleanVar]: color.syntax.boolean,\n [syntaxNumberVar]: color.syntax.number,\n })}\n >\n {children}\n </div>","copyable ? `${resultViewWrapper} ${copyableResult}` : resultViewWrapper","{data, copy, linkDocuments}","useMemo(() => ({data, copy, linkDocuments}), [copy, data, linkDocuments])","<JsonInspector\n data={data}\n search={false}\n isExpanded={isExpanded}\n onClick={toggleExpanded}\n interactiveLabel={copy || linkDocuments ? InteractiveLabel : undefined}\n />","copy || linkDocuments ? InteractiveLabel : undefined","<ResultLabelContext value={labelContext}>\n <JsonInspector\n data={data}\n search={false}\n isExpanded={isExpanded}\n onClick={toggleExpanded}\n interactiveLabel={copy || linkDocuments ? InteractiveLabel : undefined}\n />\n </ResultLabelContext>","<ResultViewWrapper copyable={Boolean(copy)}>\n <ResultLabelContext value={labelContext}>\n <JsonInspector\n data={data}\n search={false}\n isExpanded={isExpanded}\n onClick={toggleExpanded}\n interactiveLabel={copy || linkDocuments ? InteractiveLabel : undefined}\n />\n </ResultLabelContext>\n </ResultViewWrapper>","Boolean(copy)","JSON.stringify(data)","<Code language=\"json\">{JSON.stringify(data)}</Code>","context?.copy ? (\n <CopyNodeButton copy={context.copy} data={context.data} keypath={props.keypath} />\n ) : null","keypath","context?.copy","context?.linkDocuments ? <DocumentEditLabel {...props} /> : null","linkDocuments","(event) => {\n // The button sits in the line's label, which toggles the node when clicked\n event.preventDefault()\n event.stopPropagation()\n const found = getAtKeypath(data, keypath)\n if (found) copy.onCopy(found.value, keypath)\n }","<CopyIcon />","<button\n aria-label={copy.label}\n className={copyNodeButton}\n data-testid=\"result-copy-node\"\n onClick={(event) => {\n // The button sits in the line's label, which toggles the node when clicked\n event.preventDefault()\n event.stopPropagation()\n const found = getAtKeypath(data, keypath)\n if (found) copy.onCopy(found.value, keypath)\n }}\n title={copy.label}\n type=\"button\"\n >\n <CopyIcon />\n </button>","label","{id: props.value}","value","<LinkIcon />","<IntentLink intent=\"edit\" params={{id: props.value}}>\n <LinkIcon />\n </IntentLink>","_c","useThemeV2","{blobUrl}: SaveButtonProps","t('result.save-result-as-csv.not-csv-encodable')","<Button\n disabled\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />","<Tooltip animate content={t('result.save-result-as-csv.not-csv-encodable')} placement=\"top\">\n <Button\n disabled\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />\n </Tooltip>","<Button\n as=\"a\"\n download=\"query-result.csv\"\n href={blobUrl}\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />","<Button\n as=\"a\"\n download={'query-result.json'}\n href={blobUrl}\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"JSON\" // String is a File extension\n tone=\"default\"\n />","_c","{\n error,\n apiVersion,\n perspective,\n variant,\n queryInProgress,\n queryResult,\n listenInProgress,\n listenMutations,\n dataset,\n queryTime,\n e2eTime,\n compactFooter = false,\n}: VisionGuiResultProps","compactFooter = false","t('result.label')","<InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>","(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )","listenMutations.length","error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )","hasResult && <ResultView data={queryResult} datasetName={dataset} />","listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )","<Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>","<Result overflow=\"auto\">\n <InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>\n <Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>\n </Result>","<ResultInnerContainer flexBasis=\"0%\" flexGrow={1}>\n <ResultContainer\n flex={1}\n overflow=\"hidden\"\n tone={error ? 'critical' : 'default'}\n isInvalid={Boolean(error)}\n >\n <Result overflow=\"auto\">\n <InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>\n <Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>\n </Result>\n </ResultContainer>\n </ResultInnerContainer>","error ? 'critical' : 'default'","Boolean(error)","compactFooter ? 'column' : ['column', 'column', 'row']","compactFooter ? {width: '100%'} : {minWidth: 0}","t('result.execution-time-label')","typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')","<Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>","compactFooter ? 1 : 2","t('result.end-to-end-time-label')","typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')","<Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>","<Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>","compactFooter ? 3 : 4","<TimingsTextContainer alignItems=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>","<TimingsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {minWidth: 0}}\n >\n <TimingsTextContainer alignItems=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>\n </TimingsCard>","compactFooter ? 2 : 3","hasResult && (\n <DownloadsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {marginLeft: 'auto', minWidth: 0}}\n >\n <SaveResultLabel muted size={compactFooter ? 1 : 2}>\n <Translate\n components={{SaveResultButtons}}\n componentProps={{queryResult}}\n i18nKey=\"result.save-result-as-format\"\n t={t}\n />\n </SaveResultLabel>\n </DownloadsCard>\n )","<ResultFooter\n justifyContent={compactFooter ? 'flex-start' : 'space-between'}\n alignItems={compactFooter ? 'stretch' : undefined}\n flexDirection={compactFooter ? 'column' : ['column', 'column', 'row']}\n >\n <TimingsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {minWidth: 0}}\n >\n <TimingsTextContainer alignItems=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>\n </TimingsCard>\n\n {hasResult && (\n <DownloadsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {marginLeft: 'auto', minWidth: 0}}\n >\n <SaveResultLabel muted size={compactFooter ? 1 : 2}>\n <Translate\n components={{SaveResultButtons}}\n componentProps={{queryResult}}\n i18nKey=\"result.save-result-as-format\"\n t={t}\n />\n </SaveResultLabel>\n </DownloadsCard>\n )}\n </ResultFooter>","compactFooter ? 'flex-start' : 'space-between'","compactFooter ? 'stretch' : undefined","<ResultOuterContainer flexDirection=\"column\" data-testid=\"vision-result\">\n <ResultInnerContainer flexBasis=\"0%\" flexGrow={1}>\n <ResultContainer\n flex={1}\n overflow=\"hidden\"\n tone={error ? 'critical' : 'default'}\n isInvalid={Boolean(error)}\n >\n <Result overflow=\"auto\">\n <InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>\n <Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>\n </Result>\n </ResultContainer>\n </ResultInnerContainer>\n {/* Execution time */}\n <ResultFooter\n justifyContent={compactFooter ? 'flex-start' : 'space-between'}\n alignItems={compactFooter ? 'stretch' : undefined}\n flexDirection={compactFooter ? 'column' : ['column', 'column', 'row']}\n >\n <TimingsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {minWidth: 0}}\n >\n <TimingsTextContainer alignItems=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>\n </TimingsCard>\n\n {hasResult && (\n <DownloadsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {marginLeft: 'auto', minWidth: 0}}\n >\n <SaveResultLabel muted size={compactFooter ? 1 : 2}>\n <Translate\n components={{SaveResultButtons}}\n componentProps={{queryResult}}\n i18nKey=\"result.save-result-as-format\"\n t={t}\n />\n </SaveResultLabel>\n </DownloadsCard>\n )}\n </ResultFooter>\n </ResultOuterContainer>","{queryResult}: {queryResult: unknown}","getJsonBlobUrl(queryResult)","getCsvBlobUrl(queryResult)","<SaveJsonButton blobUrl={jsonUrl} />","<SaveCsvButton blobUrl={csvUrl} />","<>\n <SaveJsonButton blobUrl={jsonUrl} />\n <SaveCsvButton blobUrl={csvUrl} />\n </>","_c","_Fragment","releases = []","() => getLocalStorage(projectId || 'default')","localStorage.get('dataset', defaultDataset)","localStorage.get(\n 'apiVersion',\n prefixApiVersion(`${config.defaultApiVersion}`),\n )","defaultApiVersion","localStorage.get('query', '')","localStorage.get('params', '{\\n \\n}')","localStorage.get<SupportedPerspective | undefined>(\n 'perspective',\n undefined,\n )","() => {\n if (datasets.includes(storedDataset)) {\n return storedDataset\n }\n if (datasets.includes(defaultDataset)) {\n return defaultDataset\n }\n return datasets[0]\n }","() =>\n activeVariant\n ? VARIANTS_API_VERSION\n : API_VERSIONS.includes(storedApiVersion)\n ? storedApiVersion\n : DEFAULT_API_VERSION","() =>\n activeVariant || API_VERSIONS.includes(storedApiVersion) ? false : storedApiVersion","customApiVersion ? validateApiVersion(customApiVersion) : true","() =>\n typeof storedQuery === 'string' ? storedQuery : ''","parseParams(rawParams, t)","useMemo(() => parseParams(rawParams, t), [rawParams, t])","[]","{visionRootRef}","useMemo((): PerspectiveStack | undefined => {\n if (!isScheduledDraftsEnabled) return undefined\n\n const scheduledDraftReleases = releases.filter(\n (release: ReleaseDocument) =>\n isCardinalityOneRelease(release) && release.state === 'scheduled',\n )\n const sorted = sortReleases(scheduledDraftReleases)\n const releaseIds = sorted.map((release: ReleaseDocument) =>\n getReleaseIdFromReleaseDocumentId(release._id),\n )\n const defaultPerspective = isDraftModelEnabled ? ['drafts'] : ['published']\n return [...releaseIds, ...defaultPerspective] as PerspectiveStack\n }, [releases, isDraftModelEnabled, isScheduledDraftsEnabled])","[...releaseIds, ...defaultPerspective]","(release: ReleaseDocument) =>\n isCardinalityOneRelease(release) && release.state === 'scheduled'","(release: ReleaseDocument) =>\n getReleaseIdFromReleaseDocumentId(release._id)","isDraftModelEnabled ? ['drafts'] : ['published']","{\n apiVersion: userApiVersion,\n }","_client.withConfig({\n apiVersion: userApiVersion,\n perspective: getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n dataset,\n variant: activeVariant,\n allowReconfigure: true,\n })","useMemo(() => {\n return _client.withConfig({\n apiVersion: userApiVersion,\n perspective: getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n dataset,\n variant: activeVariant,\n allowReconfigure: true,\n })\n }, [\n perspectiveStack,\n scheduledDraftsStack,\n perspective,\n userApiVersion,\n dataset,\n _client,\n activeVariant,\n ])","() => {\n if (!querySubscriptionRef.current) {\n return\n }\n querySubscriptionRef.current.unsubscribe()\n querySubscriptionRef.current = undefined\n }","useCallback(() => {\n if (!querySubscriptionRef.current) {\n return\n }\n querySubscriptionRef.current.unsubscribe()\n querySubscriptionRef.current = undefined\n }, [])","() => {\n if (!listenSubscriptionRef.current) {\n return\n }\n listenSubscriptionRef.current.unsubscribe()\n listenSubscriptionRef.current = undefined\n }","useCallback(() => {\n if (!listenSubscriptionRef.current) {\n return\n }\n listenSubscriptionRef.current.unsubscribe()\n listenSubscriptionRef.current = undefined\n }, [])","(options?: QueryExecutionOptions) => {\n if (queryInProgress) {\n cancelQuerySubscription()\n cancelListenerSubscription()\n setQueryInProgress(false)\n return\n }\n\n const visionPerspective =\n options && 'perspective' in options ? options.perspective : perspective\n const queryVariant = getActiveVariant(visionPerspective, selectedVariantName)\n\n const context: Required<Omit<QueryExecutionOptions, 'params' | 'perspective'>> & {\n params: Params\n perspective: ClientPerspective | undefined\n variant: string | undefined\n } = {\n query: options?.query || query,\n dataset: options?.dataset || dataset,\n params: parseParams(JSON.stringify(options?.params || params.parsed, null, 2), t),\n perspective: getActivePerspective({\n visionPerspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n apiVersion:\n options?.apiVersion ||\n (queryVariant\n ? VARIANTS_API_VERSION\n : customApiVersion && isValidApiVersion\n ? customApiVersion\n : apiVersion),\n variant: queryVariant,\n }\n\n localStorage.set('query', context.query)\n localStorage.set('params', context.params.raw)\n\n cancelListenerSubscription()\n\n const hasQuery = context.query.trim().length > 0\n\n setQueryInProgress(!context.params.error && hasQuery)\n setListenInProgress(false)\n setListenMutations([])\n setError(context.params.error ? new Error(context.params.error) : undefined)\n setQueryResult(undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (context.params.error || !hasQuery) {\n return\n }\n\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective: context.perspective ?? [],\n ...(context.variant ? {variant: context.variant} : {}),\n }\n\n const ctxClient = client.withConfig({\n apiVersion: context.apiVersion,\n dataset: context.dataset,\n perspective: context.perspective,\n variant: context.variant,\n })\n\n const newUrl = ctxClient.getUrl(\n ctxClient.getDataUrl(\n 'query',\n encodeQueryString(context.query, context.params.parsed, urlQueryOpts),\n ),\n )\n setUrl(newUrl)\n\n const queryStart = Date.now()\n\n querySubscriptionRef.current = ctxClient.observable\n .fetch(context.query, context.params.parsed, {filterResponse: false, tag: 'vision'})\n .subscribe({\n next: (res) => {\n setQueryTime(res.ms)\n setE2eTime(Date.now() - queryStart)\n setQueryResult(res.result)\n setQueryInProgress(false)\n setError(undefined)\n },\n error: (err) => {\n setError(err)\n setQueryInProgress(false)\n },\n })\n }","parsed","useCallback(\n (options?: QueryExecutionOptions) => {\n if (queryInProgress) {\n cancelQuerySubscription()\n cancelListenerSubscription()\n setQueryInProgress(false)\n return\n }\n\n const visionPerspective =\n options && 'perspective' in options ? options.perspective : perspective\n const queryVariant = getActiveVariant(visionPerspective, selectedVariantName)\n\n const context: Required<Omit<QueryExecutionOptions, 'params' | 'perspective'>> & {\n params: Params\n perspective: ClientPerspective | undefined\n variant: string | undefined\n } = {\n query: options?.query || query,\n dataset: options?.dataset || dataset,\n params: parseParams(JSON.stringify(options?.params || params.parsed, null, 2), t),\n perspective: getActivePerspective({\n visionPerspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n apiVersion:\n options?.apiVersion ||\n (queryVariant\n ? VARIANTS_API_VERSION\n : customApiVersion && isValidApiVersion\n ? customApiVersion\n : apiVersion),\n variant: queryVariant,\n }\n\n localStorage.set('query', context.query)\n localStorage.set('params', context.params.raw)\n\n cancelListenerSubscription()\n\n const hasQuery = context.query.trim().length > 0\n\n setQueryInProgress(!context.params.error && hasQuery)\n setListenInProgress(false)\n setListenMutations([])\n setError(context.params.error ? new Error(context.params.error) : undefined)\n setQueryResult(undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (context.params.error || !hasQuery) {\n return\n }\n\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective: context.perspective ?? [],\n ...(context.variant ? {variant: context.variant} : {}),\n }\n\n const ctxClient = client.withConfig({\n apiVersion: context.apiVersion,\n dataset: context.dataset,\n perspective: context.perspective,\n variant: context.variant,\n })\n\n const newUrl = ctxClient.getUrl(\n ctxClient.getDataUrl(\n 'query',\n encodeQueryString(context.query, context.params.parsed, urlQueryOpts),\n ),\n )\n setUrl(newUrl)\n\n const queryStart = Date.now()\n\n querySubscriptionRef.current = ctxClient.observable\n .fetch(context.query, context.params.parsed, {filterResponse: false, tag: 'vision'})\n .subscribe({\n next: (res) => {\n setQueryTime(res.ms)\n setE2eTime(Date.now() - queryStart)\n setQueryResult(res.result)\n setQueryInProgress(false)\n setError(undefined)\n },\n error: (err) => {\n setError(err)\n setQueryInProgress(false)\n },\n })\n },\n [\n queryInProgress,\n query,\n dataset,\n params.parsed,\n t,\n perspective,\n perspectiveStack,\n scheduledDraftsStack,\n selectedVariantName,\n customApiVersion,\n isValidApiVersion,\n apiVersion,\n localStorage,\n cancelListenerSubscription,\n client,\n cancelQuerySubscription,\n ],\n )","(newPerspective: string | undefined): void => {\n if (newPerspective !== undefined && !isSupportedPerspective(newPerspective)) {\n return\n }\n\n setPerspectiveState(newPerspective)\n localStorage.set('perspective', newPerspective)\n\n handleQueryExecution({perspective: newPerspective})\n }","useCallback(\n (newPerspective: string | undefined): void => {\n if (newPerspective !== undefined && !isSupportedPerspective(newPerspective)) {\n return\n }\n\n setPerspectiveState(newPerspective)\n localStorage.set('perspective', newPerspective)\n\n handleQueryExecution({perspective: newPerspective})\n },\n [localStorage, handleQueryExecution, setPerspectiveState],\n )","(evt: ChangeEvent<HTMLSelectElement>) => {\n const newDataset = evt.target.value\n localStorage.set('dataset', newDataset)\n setDataset(newDataset)\n handleQueryExecution({dataset: newDataset})\n }","useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n const newDataset = evt.target.value\n localStorage.set('dataset', newDataset)\n setDataset(newDataset)\n handleQueryExecution({dataset: newDataset})\n },\n [localStorage, handleQueryExecution, setDataset],\n )","(newApiVersion: string) => {\n if (newApiVersion.toLowerCase() === 'other') {\n setCustomApiVersion('v')\n customApiVersionElementRef.current?.focus()\n return\n }\n\n setApiVersion(newApiVersion)\n setCustomApiVersion(false)\n localStorage.set('apiVersion', newApiVersion)\n handleQueryExecution({apiVersion: newApiVersion})\n }","useCallback(\n (newApiVersion: string) => {\n if (newApiVersion.toLowerCase() === 'other') {\n setCustomApiVersion('v')\n customApiVersionElementRef.current?.focus()\n return\n }\n\n setApiVersion(newApiVersion)\n setCustomApiVersion(false)\n localStorage.set('apiVersion', newApiVersion)\n handleQueryExecution({apiVersion: newApiVersion})\n },\n [localStorage, handleQueryExecution],\n )","(evt: ChangeEvent<HTMLSelectElement>) => {\n changeApiVersion(evt.target.value)\n }","evt","useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n changeApiVersion(evt.target.value)\n },\n [changeApiVersion],\n )","(evt: ChangeEvent<HTMLInputElement>) => {\n const newCustomApiVersion = evt.target.value || ''\n setCustomApiVersion(newCustomApiVersion || 'v')\n\n if (validateApiVersion(newCustomApiVersion)) {\n setApiVersion(newCustomApiVersion)\n localStorage.set('apiVersion', newCustomApiVersion)\n handleQueryExecution({apiVersion: newCustomApiVersion})\n }\n }","useCallback(\n (evt: ChangeEvent<HTMLInputElement>) => {\n const newCustomApiVersion = evt.target.value || ''\n setCustomApiVersion(newCustomApiVersion || 'v')\n\n if (validateApiVersion(newCustomApiVersion)) {\n setApiVersion(newCustomApiVersion)\n localStorage.set('apiVersion', newCustomApiVersion)\n handleQueryExecution({apiVersion: newCustomApiVersion})\n }\n },\n [localStorage, handleQueryExecution],\n )","(evt: ChangeEvent<HTMLSelectElement>) => {\n const newPerspective = evt.target.value\n setPerspective(newPerspective === 'default' ? undefined : newPerspective)\n }","newPerspective","useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n const newPerspective = evt.target.value\n setPerspective(newPerspective === 'default' ? undefined : newPerspective)\n },\n [setPerspective],\n )","(evt: ListenEvent<any>) => {\n if (evt.type !== 'mutation') {\n return\n }\n\n setListenMutations((prevMutations) =>\n prevMutations.length === 50 ? [evt, ...prevMutations.slice(0, 49)] : [evt, ...prevMutations],\n )\n }","useCallback((evt: ListenEvent<any>) => {\n if (evt.type !== 'mutation') {\n return\n }\n\n setListenMutations((prevMutations) =>\n prevMutations.length === 50 ? [evt, ...prevMutations.slice(0, 49)] : [evt, ...prevMutations],\n )\n }, [])","() => {\n if (listenInProgress) {\n cancelListenerSubscription()\n setListenInProgress(false)\n return\n }\n\n const newUrl = client.getDataUrl('listen', encodeQueryString(query, params.parsed, {}))\n\n const shouldExecute = !params.error && query.trim().length > 0\n\n localStorage.set('query', query)\n localStorage.set('params', params.raw)\n\n cancelQuerySubscription()\n\n setUrl(newUrl)\n setListenMutations([])\n setQueryInProgress(false)\n setQueryResult(undefined)\n setListenInProgress(shouldExecute)\n setError(params.error ? new Error(params.error) : undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (!shouldExecute) {\n return\n }\n\n listenSubscriptionRef.current = client\n .listen(query, params.parsed, {events: ['mutation', 'welcome'], includeAllVersions: true})\n .subscribe({\n next: handleListenerEvent,\n error: (err) => {\n setError(err)\n setListenInProgress(false)\n },\n })\n }","error","raw","newUrl","err","useCallback(() => {\n if (listenInProgress) {\n cancelListenerSubscription()\n setListenInProgress(false)\n return\n }\n\n const newUrl = client.getDataUrl('listen', encodeQueryString(query, params.parsed, {}))\n\n const shouldExecute = !params.error && query.trim().length > 0\n\n localStorage.set('query', query)\n localStorage.set('params', params.raw)\n\n cancelQuerySubscription()\n\n setUrl(newUrl)\n setListenMutations([])\n setQueryInProgress(false)\n setQueryResult(undefined)\n setListenInProgress(shouldExecute)\n setError(params.error ? new Error(params.error) : undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (!shouldExecute) {\n return\n }\n\n listenSubscriptionRef.current = client\n .listen(query, params.parsed, {events: ['mutation', 'welcome'], includeAllVersions: true})\n .subscribe({\n next: handleListenerEvent,\n error: (err) => {\n setError(err)\n setListenInProgress(false)\n },\n })\n }, [\n listenInProgress,\n params,\n query,\n localStorage,\n cancelQuerySubscription,\n handleListenerEvent,\n cancelListenerSubscription,\n client,\n ])","(value: string) => {\n setRawParams(value)\n localStorage.set('params', value)\n }","useCallback(\n (value: string) => {\n setRawParams(value)\n localStorage.set('params', value)\n },\n [localStorage],\n )","(data: string): ParsedUrlState | null => {\n const match = data.match(SANITY_QUERY_URL)\n if (!match) {\n return null\n }\n\n const [, usedApiVersion, usedDataset, urlQuery] = match\n\n const qs = new URLSearchParams(urlQuery)\n const parts: ParsedApiQueryString = parseApiQueryString(qs)\n if (!parts) return null\n let newApiVersion: string | undefined\n let newCustomApiVersion: string | false | undefined\n\n if (validateApiVersion(usedApiVersion)) {\n if (API_VERSIONS.includes(usedApiVersion)) {\n newApiVersion = usedApiVersion\n newCustomApiVersion = false\n } else {\n newCustomApiVersion = usedApiVersion\n }\n }\n\n const newPerspective =\n isSupportedPerspective(parts.options.perspective) &&\n !isVirtualPerspective(parts.options.perspective)\n ? parts.options.perspective\n : undefined\n\n if (\n newPerspective &&\n (!isSupportedPerspective(parts.options.perspective) ||\n isVirtualPerspective(parts.options.perspective))\n ) {\n toast.push({\n closable: true,\n id: 'vision-paste-unsupported-perspective',\n status: 'warning',\n title: 'Perspective in pasted url is currently not supported. Falling back to \"raw\"',\n })\n }\n\n return {\n query: parts.query,\n params: parts.params,\n rawParams: JSON.stringify(parts.params, null, 2),\n dataset: datasets.includes(usedDataset) ? usedDataset : dataset,\n apiVersion: newApiVersion || apiVersion,\n customApiVersion: newCustomApiVersion,\n perspective: newPerspective || perspective,\n url: data,\n }\n }","newApiVersion","newCustomApiVersion","useCallback(\n (data: string): ParsedUrlState | null => {\n const match = data.match(SANITY_QUERY_URL)\n if (!match) {\n return null\n }\n\n const [, usedApiVersion, usedDataset, urlQuery] = match\n\n const qs = new URLSearchParams(urlQuery)\n const parts: ParsedApiQueryString = parseApiQueryString(qs)\n if (!parts) return null\n let newApiVersion: string | undefined\n let newCustomApiVersion: string | false | undefined\n\n if (validateApiVersion(usedApiVersion)) {\n if (API_VERSIONS.includes(usedApiVersion)) {\n newApiVersion = usedApiVersion\n newCustomApiVersion = false\n } else {\n newCustomApiVersion = usedApiVersion\n }\n }\n\n const newPerspective =\n isSupportedPerspective(parts.options.perspective) &&\n !isVirtualPerspective(parts.options.perspective)\n ? parts.options.perspective\n : undefined\n\n if (\n newPerspective &&\n (!isSupportedPerspective(parts.options.perspective) ||\n isVirtualPerspective(parts.options.perspective))\n ) {\n toast.push({\n closable: true,\n id: 'vision-paste-unsupported-perspective',\n status: 'warning',\n title: 'Perspective in pasted url is currently not supported. Falling back to \"raw\"',\n })\n }\n\n return {\n query: parts.query,\n params: parts.params,\n rawParams: JSON.stringify(parts.params, null, 2),\n dataset: datasets.includes(usedDataset) ? usedDataset : dataset,\n apiVersion: newApiVersion || apiVersion,\n customApiVersion: newCustomApiVersion,\n perspective: newPerspective || perspective,\n url: data,\n }\n },\n [datasets, dataset, apiVersion, perspective, toast],\n )","(parsedUrlObj: ParsedUrlState) => {\n // Update state with pasted values\n setDataset(parsedUrlObj.dataset)\n setQuery(parsedUrlObj.query)\n setRawParams(parsedUrlObj.rawParams)\n setApiVersion(parsedUrlObj.apiVersion)\n if (parsedUrlObj.customApiVersion) {\n setCustomApiVersion(parsedUrlObj.customApiVersion)\n }\n setPerspectiveState(parsedUrlObj.perspective)\n setUrl(parsedUrlObj.url)\n // Update the codemirror editor content\n editorQueryRef.current?.resetEditorContent(parsedUrlObj.query)\n editorParamsRef.current?.resetEditorContent(parsedUrlObj.rawParams)\n\n // Update localStorage and client config\n localStorage.merge({\n query: parsedUrlObj.query,\n params: parsedUrlObj.rawParams,\n dataset: parsedUrlObj.dataset,\n apiVersion: parsedUrlObj.customApiVersion || parsedUrlObj.apiVersion,\n perspective: parsedUrlObj.perspective,\n })\n\n // Execute query with new values\n handleQueryExecution(parsedUrlObj)\n }","useCallback(\n (parsedUrlObj: ParsedUrlState) => {\n // Update state with pasted values\n setDataset(parsedUrlObj.dataset)\n setQuery(parsedUrlObj.query)\n setRawParams(parsedUrlObj.rawParams)\n setApiVersion(parsedUrlObj.apiVersion)\n if (parsedUrlObj.customApiVersion) {\n setCustomApiVersion(parsedUrlObj.customApiVersion)\n }\n setPerspectiveState(parsedUrlObj.perspective)\n setUrl(parsedUrlObj.url)\n // Update the codemirror editor content\n editorQueryRef.current?.resetEditorContent(parsedUrlObj.query)\n editorParamsRef.current?.resetEditorContent(parsedUrlObj.rawParams)\n\n // Update localStorage and client config\n localStorage.merge({\n query: parsedUrlObj.query,\n params: parsedUrlObj.rawParams,\n dataset: parsedUrlObj.dataset,\n apiVersion: parsedUrlObj.customApiVersion || parsedUrlObj.apiVersion,\n perspective: parsedUrlObj.perspective,\n })\n\n // Execute query with new values\n handleQueryExecution(parsedUrlObj)\n },\n [localStorage, handleQueryExecution, setDataset, setPerspectiveState],\n )","(evt: ClipboardEvent) => {\n if (!evt.clipboardData || !isVisionPasteTarget(visionRootRef.current, evt)) {\n return\n }\n\n const urlState = getStateFromUrl(evt.clipboardData.getData('text/plain'))\n if (!urlState) {\n return\n }\n\n // Only cancel the native paste once the clipboard is known to hold a query URL Vision can\n // load, so unrelated content still pastes as usual.\n evt.preventDefault()\n setStateFromParsedUrl(urlState)\n toast.push({\n closable: true,\n id: 'vision-paste',\n status: 'info',\n title: 'Parsed URL to query',\n })\n }","useCallback(\n (evt: ClipboardEvent) => {\n if (!evt.clipboardData || !isVisionPasteTarget(visionRootRef.current, evt)) {\n return\n }\n\n const urlState = getStateFromUrl(evt.clipboardData.getData('text/plain'))\n if (!urlState) {\n return\n }\n\n // Only cancel the native paste once the clipboard is known to hold a query URL Vision can\n // load, so unrelated content still pastes as usual.\n evt.preventDefault()\n setStateFromParsedUrl(urlState)\n toast.push({\n closable: true,\n id: 'vision-paste',\n status: 'info',\n title: 'Parsed URL to query',\n })\n },\n [getStateFromUrl, setStateFromParsedUrl, toast],\n )","(event: KeyboardEvent) => {\n const isWithinRoot =\n visionRootRef.current && nodeContains(visionRootRef.current, event.target)\n if (isRunHotkey(event) && isWithinRoot && params.valid) {\n handleQueryExecution()\n event.preventDefault()\n event.stopPropagation()\n }\n }","valid","useCallback(\n (event: KeyboardEvent) => {\n const isWithinRoot =\n visionRootRef.current && nodeContains(visionRootRef.current, event.target)\n if (isRunHotkey(event) && isWithinRoot && params.valid) {\n handleQueryExecution()\n event.preventDefault()\n event.stopPropagation()\n }\n },\n [params.valid, handleQueryExecution],\n )","() => {\n window.document.addEventListener('paste', handlePaste)\n window.document.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.document.removeEventListener('paste', handlePaste)\n window.document.removeEventListener('keydown', handleKeyDown)\n }\n }","[handleKeyDown, handlePaste]","() => {\n return () => {\n cancelQuerySubscription()\n cancelListenerSubscription()\n }\n }","[cancelQuerySubscription, cancelListenerSubscription]","() => {\n if (perspective !== 'pinnedRelease') {\n return\n }\n // changeApiVersion already re-runs the query with vX.\n changeApiVersion(VARIANTS_API_VERSION)\n }","() => {\n if (!activeVariant) {\n return\n }\n handleStudioVariantChange()\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- pre-existing violation, to be fixed in a follow-up\n }","[activeVariant]","(stack: StackablePerspective[]) => {\n if (stack.length > 0) {\n setPerspective('pinnedRelease')\n }\n }","() => {\n handleStudioPerspectiveChange(perspectiveStack)\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- pre-existing violation, to be fixed in a follow-up\n }","[perspectiveStack]","(queryString: string, queryParams: Record<string, unknown>) => {\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective:\n getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }) ?? [],\n ...(activeVariant ? {variant: activeVariant} : {}),\n }\n return client.getUrl(\n client.getDataUrl('query', encodeQueryString(queryString, queryParams, urlQueryOpts)),\n )\n }","urlQueryOpts","useCallback(\n (queryString: string, queryParams: Record<string, unknown>) => {\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective:\n getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }) ?? [],\n ...(activeVariant ? {variant: activeVariant} : {}),\n }\n return client.getUrl(\n client.getDataUrl('query', encodeQueryString(queryString, queryParams, urlQueryOpts)),\n )\n },\n [activeVariant, client, perspective, perspectiveStack, scheduledDraftsStack],\n )","<VisionGuiHeader\n apiVersion={activeVariant ? VARIANTS_API_VERSION : apiVersion}\n customApiVersion={activeVariant ? false : customApiVersion}\n dataset={dataset}\n datasets={datasets}\n onChangeDataset={handleChangeDataset}\n onChangeApiVersion={handleChangeApiVersion}\n customApiVersionElementRef={customApiVersionElementRef}\n onCustomApiVersionChange={handleCustomApiVersionChange}\n isValidApiVersion={isValidApiVersion}\n onChangePerspective={handleChangePerspective}\n url={url}\n perspective={perspective}\n isScheduledDraftsEnabled={isScheduledDraftsEnabled}\n />","activeVariant ? VARIANTS_API_VERSION : apiVersion","activeVariant ? false : customApiVersion","t('query.label')","<InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>","<VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />","<InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>","<ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />","<VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n onSwitchToRedesign={onSwitchToRedesign}\n />","<InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n onSwitchToRedesign={onSwitchToRedesign}\n />\n </InputContainer>","<Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n onSwitchToRedesign={onSwitchToRedesign}\n />\n </InputContainer>\n </SplitPane>\n </Box>","allowResize","maxSize","size","isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize","isNarrowBreakpoint ? paneSizeOptions.minSize : 100","paneSizeOptions.size","paneSizeOptions.allowResize","paneSizeOptions.maxSize","getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })","<VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />","<Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n split={isNarrowBreakpoint ? 'vertical' : 'horizontal'}\n minSize={300}\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n onSwitchToRedesign={onSwitchToRedesign}\n />\n </InputContainer>\n </SplitPane>\n </Box>\n <VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />\n </SplitPane>\n </Box>","isNarrowBreakpoint ? 'vertical' : 'horizontal'","{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }","() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)","{display: 'flex', alignItems: 'center', height: '100%'}","<div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>","<Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>","params.parsed || {}","<QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>","<QueryRecallPaneContainer>\n <Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>\n <QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>\n </QueryRecallPaneContainer>","<SplitpaneContainer flexBasis=\"auto\" flexGrow={1} flexShrink={1}>\n <SplitPane\n minSize={800}\n defaultSize={window.innerWidth - 275}\n size={isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275}\n maxSize={-225}\n primary=\"first\"\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n split={isNarrowBreakpoint ? 'vertical' : 'horizontal'}\n minSize={300}\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n onSwitchToRedesign={onSwitchToRedesign}\n />\n </InputContainer>\n </SplitPane>\n </Box>\n <VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />\n </SplitPane>\n </Box>\n <QueryRecallPaneContainer>\n <Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>\n <QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>\n </QueryRecallPaneContainer>\n </SplitPane>\n </SplitpaneContainer>","isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275","<Root\n flexDirection=\"column\"\n height=\"100%\"\n ref={visionRootRef}\n overflow=\"hidden\"\n data-testid=\"vision-root\"\n >\n <VisionGuiHeader\n apiVersion={activeVariant ? VARIANTS_API_VERSION : apiVersion}\n customApiVersion={activeVariant ? false : customApiVersion}\n dataset={dataset}\n datasets={datasets}\n onChangeDataset={handleChangeDataset}\n onChangeApiVersion={handleChangeApiVersion}\n customApiVersionElementRef={customApiVersionElementRef}\n onCustomApiVersionChange={handleCustomApiVersionChange}\n isValidApiVersion={isValidApiVersion}\n onChangePerspective={handleChangePerspective}\n url={url}\n perspective={perspective}\n isScheduledDraftsEnabled={isScheduledDraftsEnabled}\n />\n\n <SplitpaneContainer flexBasis=\"auto\" flexGrow={1} flexShrink={1}>\n <SplitPane\n minSize={800}\n defaultSize={window.innerWidth - 275}\n size={isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275}\n maxSize={-225}\n primary=\"first\"\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n split={isNarrowBreakpoint ? 'vertical' : 'horizontal'}\n minSize={300}\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n onSwitchToRedesign={onSwitchToRedesign}\n />\n </InputContainer>\n </SplitPane>\n </Box>\n <VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />\n </SplitPane>\n </Box>\n <QueryRecallPaneContainer>\n <Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>\n <QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>\n </QueryRecallPaneContainer>\n </SplitPane>\n </SplitpaneContainer>\n </Root>","release","_c","_temp","_temp2","{\n client,\n datasets: configDatasets,\n}: {\n client: SanityClient\n datasets: VisionConfig['datasets']\n}","useMemo(() => {\n if (Array.isArray(configDatasets)) {\n return of(configDatasets)\n }\n return client.observable.datasets.list().pipe(\n map((result) => {\n if (typeof configDatasets == 'function') {\n return configDatasets(result).map((d) => d.name)\n }\n return result.map((ds) => ds.name)\n }),\n catchError((err) => of(err)),\n )\n }, [client, configDatasets])","of(configDatasets)","client.observable.datasets.list().pipe(\n map((result) => {\n if (typeof configDatasets == 'function') {\n return configDatasets(result).map((d) => d.name)\n }\n return result.map((ds) => ds.name)\n }),\n catchError((err) => of(err)),\n )","datasets","(result) => {\n if (typeof configDatasets == 'function') {\n return configDatasets(result).map((d) => d.name)\n }\n return result.map((ds) => ds.name)\n }","(d) => d.name","(ds) => ds.name","(err) => of(err)","_c","_temp","datasets$","{apiVersion: 'v2025-06-27'}","{client: datasetsClient, datasets: props.config.datasets}","datasets","<Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <DelayedSpinner />\n </Flex>","<Suspense\n fallback={\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <DelayedSpinner />\n </Flex>\n }\n >\n <LoadedVisionContainer {...props} datasetsPromise={datasetsPromise} />\n </Suspense>","{\n children,\n client,\n config,\n datasetsPromise,\n}: VisionContainerProps & {datasetsPromise: ObservablePromise<string[] | Error>}","Fragment","projectId","children({datasets, projectId, defaultDataset})","defaultDataset","<Fragment key={projectId}>{children({datasets, projectId, defaultDataset})}</Fragment>","_c","<LazyComponent {...props} />","_c","<Text size={1}>{description}</Text>","<Button\n data-testid=\"vision-redesign-accept\"\n fontSize={1}\n onClick={onAccept}\n padding={2}\n text={acceptLabel}\n tone=\"primary\"\n />","<Button\n data-testid=\"vision-redesign-dismiss\"\n fontSize={1}\n mode=\"bleed\"\n onClick={onDismiss}\n padding={2}\n text={dismissLabel}\n />","<Flex gap={2}>\n <Button\n data-testid=\"vision-redesign-accept\"\n fontSize={1}\n onClick={onAccept}\n padding={2}\n text={acceptLabel}\n tone=\"primary\"\n />\n <Button\n data-testid=\"vision-redesign-dismiss\"\n fontSize={1}\n mode=\"bleed\"\n onClick={onDismiss}\n padding={2}\n text={dismissLabel}\n />\n </Flex>","<Stack gap={3} paddingTop={1}>\n <Text size={1}>{description}</Text>\n <Flex gap={2}>\n <Button\n data-testid=\"vision-redesign-accept\"\n fontSize={1}\n onClick={onAccept}\n padding={2}\n text={acceptLabel}\n tone=\"primary\"\n />\n <Button\n data-testid=\"vision-redesign-dismiss\"\n fontSize={1}\n mode=\"bleed\"\n onClick={onDismiss}\n padding={2}\n text={dismissLabel}\n />\n </Flex>\n </Stack>","{onAccept, onDismiss}: RedesignToastProps","() => {\n // `@sanity/ui` toasts auto-dismiss unless the duration is infinite, and the provider does not\n // forward `onClose`, so the toast carries its own accept and dismiss buttons instead of an X\n const remove = () => {\n toast.push({id: TOAST_ID, duration: 0.01})\n }\n toast.push({\n id: TOAST_ID,\n closable: false,\n duration: Infinity,\n status: 'info',\n title: t('vista.redesign.toast.title'),\n description: (\n <RedesignToastActions\n acceptLabel={t('vista.redesign.toast.accept')}\n description={t('vista.redesign.toast.description')}\n dismissLabel={t('vista.redesign.toast.dismiss')}\n onAccept={() => {\n remove()\n accept()\n }}\n onDismiss={() => {\n remove()\n dismiss()\n }}\n />\n ),\n })\n return remove\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- useEffectEvent callbacks must not be listed\n }","[t, toast]","_c","() => readRedesignPreference(projectId)","() => DEFAULT_PREFERENCE","_c","{apiVersion: '1'}","{\n defaultApiVersion: DEFAULT_API_VERSION,\n ...props.tool.options,\n }","options","client.config().projectId || 'default'","() => writeRedesignPreference(projectId, {optedIn: true, dismissed: false})","useCallback(\n () => writeRedesignPreference(projectId, {optedIn: true, dismissed: false}),\n [projectId],\n )","() => writeRedesignPreference(projectId, {dismissed: true})","useCallback(\n () => writeRedesignPreference(projectId, {dismissed: true}),\n [projectId],\n )","() => writeRedesignPreference(projectId, {optedIn: false, dismissed: false})","useCallback(\n () => writeRedesignPreference(projectId, {optedIn: false, dismissed: false}),\n [projectId],\n )","(loaded) =>\n showRedesign ? (\n <VistaGuiLoader {...loaded} config={config} onSwitchToClassic={switchToClassic} />\n ) : (\n <VisionGui\n {...loaded}\n client={client}\n config={config}\n onSwitchToRedesign={redesignEnabled ? optIn : undefined}\n />\n )","<VisionContainer client={client} config={config}>\n {(loaded) =>\n showRedesign ? (\n <VistaGuiLoader {...loaded} config={config} onSwitchToClassic={switchToClassic} />\n ) : (\n <VisionGui\n {...loaded}\n client={client}\n config={config}\n onSwitchToRedesign={redesignEnabled ? optIn : undefined}\n />\n )\n }\n </VisionContainer>","redesignEnabled && !showRedesign && !preference.dismissed && (\n <RedesignToast onAccept={optIn} onDismiss={dismiss} />\n )","preference.dismissed","<VisionErrorBoundary onRetry={vistaGui.retry}>\n <VisionContainer client={client} config={config}>\n {(loaded) =>\n showRedesign ? (\n <VistaGuiLoader {...loaded} config={config} onSwitchToClassic={switchToClassic} />\n ) : (\n <VisionGui\n {...loaded}\n client={client}\n config={config}\n onSwitchToRedesign={redesignEnabled ? optIn : undefined}\n />\n )\n }\n </VisionContainer>\n {redesignEnabled && !showRedesign && !preference.dismissed && (\n <RedesignToast onAccept={optIn} onDismiss={dismiss} />\n )}\n </VisionErrorBoundary>","_c"],"sources":["../src/util/prefixApiVersion.ts","../src/apiVersions.ts","../src/codemirror/extensions.ts","../src/codemirror/useCodemirrorTheme.ts","../src/codemirror/visibleColumns.ts","../src/codemirror/VisionCodeMirror.css.ts","../src/codemirror/VisionCodeMirror.tsx","../src/perspectives.ts","../src/util/encodeQueryString.ts","../src/util/isVisionPasteTarget.ts","../src/util/isPlainObject.ts","../src/util/localStorage.ts","../src/util/parseApiQueryString.ts","../src/util/validateApiVersion.ts","../src/util/parseQueryUrl.ts","../src/util/tryParseParams.ts","../src/components/VisionGui.css.ts","../src/components/VisionGui.styled.tsx","../src/components/ParamsEditor.tsx","../src/hooks/useSavedQueries.ts","../src/components/QueryRecall.css.ts","../src/components/QueryRecall.tsx","../src/components/usePaneSize.ts","../src/components/VisionGuiControls.tsx","../src/components/PerspectivePopover.css.ts","../src/components/PerspectivePopover.tsx","../src/components/VisionGuiHeader.tsx","../src/util/getBlobUrl.ts","../src/components/DelayedSpinner.tsx","../src/util/compareApiVersion.ts","../src/util/apiVersionCapabilities.ts","../src/components/QueryErrorDialog.css.ts","../src/components/QueryErrorDialog.styled.tsx","../src/components/QueryErrorDetails.tsx","../src/components/QueryErrorDialog.tsx","../src/util/getAtKeypath.ts","../src/components/ResultView.css.ts","../src/components/ResultView.tsx","../src/components/SaveResultButtons.tsx","../src/components/VisionGuiResult.tsx","../src/components/VisionGui.tsx","../src/hooks/useDatasets.ts","../src/containers/VisionContainer.tsx","../src/containers/VisionErrorBoundary.tsx","../src/util/createRetryableLazy.tsx","../src/vista/components/RedesignToast.tsx","../src/vista/redesignPreference.ts","../src/SanityVision.tsx"],"sourcesContent":["export function prefixApiVersion(version: string): string {\n if (version[0] !== 'v' && version !== 'other') {\n return `v${version}`\n }\n\n return version\n}\n","import {VARIANTS_STUDIO_CLIENT_OPTIONS} from 'sanity'\n\nimport {prefixApiVersion} from './util/prefixApiVersion'\n\nexport const API_VERSIONS = [\n 'v1',\n 'vX',\n 'v2021-03-25',\n 'v2021-10-21',\n 'v2022-03-07',\n 'v2025-02-19',\n `v${new Date().toISOString().split('T')[0]}`,\n]\nexport const [DEFAULT_API_VERSION] = API_VERSIONS.slice(-1)\n\n/** Variants only exist on the experimental API, so a selected variant forces this version */\nexport const VARIANTS_API_VERSION = prefixApiVersion(VARIANTS_STUDIO_CLIENT_OPTIONS.apiVersion)\n","import {closeBrackets} from '@codemirror/autocomplete'\nimport {defaultKeymap, history, historyKeymap} from '@codemirror/commands'\nimport {javascriptLanguage} from '@codemirror/lang-javascript'\nimport {\n bracketMatching,\n defaultHighlightStyle,\n foldGutter,\n indentOnInput,\n syntaxHighlighting,\n} from '@codemirror/language'\nimport {highlightSelectionMatches} from '@codemirror/search'\nimport {EditorState, type Extension} from '@codemirror/state'\nimport {\n drawSelection,\n highlightActiveLine,\n highlightActiveLineGutter,\n highlightSpecialChars,\n keymap,\n lineNumbers,\n type KeyBinding,\n} from '@codemirror/view'\nimport {groq} from '@sanity/lezer-groq'\n\nconst sharedExtensions: Extension[] = [\n lineNumbers(),\n highlightActiveLine(),\n highlightActiveLineGutter(),\n highlightSelectionMatches(),\n highlightSpecialChars(),\n indentOnInput(),\n bracketMatching(),\n closeBrackets(),\n history(),\n drawSelection(),\n syntaxHighlighting(defaultHighlightStyle, {fallback: true}),\n keymap.of([\n // Override the default keymap for Mod-Enter to not insert a new line, we have a custom event handler for executing queries\n {key: 'Mod-Enter', run: () => true},\n\n // Add the default keymap and history keymap\n ...defaultKeymap,\n ...historyKeymap,\n ] as unknown as readonly KeyBinding[]),\n]\n\nexport const groqExtensions: Extension[] = [groq(), ...sharedExtensions]\n\nexport const paramsExtensions: Extension[] = [javascriptLanguage, ...sharedExtensions]\n\n/** A result's JSON: read only, but focusable and selectable, with its objects and arrays foldable */\nexport const resultJsonExtensions: Extension[] = [\n javascriptLanguage,\n ...sharedExtensions,\n foldGutter(),\n EditorState.readOnly.of(true),\n]\n","import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'\nimport {type Extension} from '@codemirror/state'\nimport {EditorView} from '@codemirror/view'\nimport {tags as t} from '@lezer/highlight'\nimport {hues} from '@sanity/color'\nimport {rem, type Theme} from '@sanity/ui'\nimport {useMemo} from 'react'\n\n// The explicit return type keeps declaration emit portable (TS2883): without it the inferred\n// type references `Extension` from @codemirror/state through a non-portable .pnpm path\n// oxlint-disable-next-line no-deprecated -- will fix in follow up PR\nexport function useCodemirrorTheme(theme: Theme): Extension[] {\n const cmTheme = useMemo(() => createTheme(theme), [theme])\n const cmHighlight = useMemo(() => syntaxHighlighting(createHighlight(theme)), [theme])\n\n return [cmTheme, cmHighlight]\n}\n\n// oxlint-disable-next-line no-deprecated -- will fix in follow up PR\nfunction createTheme(theme: Theme) {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const {color, fonts} = theme.sanity\n const card = color.card.enabled\n const cursor = hues.blue[color.dark ? 400 : 500].hex\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const selection = hues.gray[theme.sanity.color.dark ? 900 : 100].hex\n\n return EditorView.theme(\n {\n '&': {\n color: card.fg,\n backgroundColor: card.bg,\n },\n\n '.cm-content': {\n caretColor: cursor,\n },\n\n '.cm-editor': {\n fontFamily: fonts.code.family,\n fontSize: rem(fonts.code.sizes[1].fontSize),\n lineHeight: 'inherit',\n },\n\n '.cm-cursor, .cm-dropCursor': {borderLeftColor: cursor},\n '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {\n backgroundColor: selection,\n },\n\n '.cm-panels': {backgroundColor: card.bg, color: card.fg},\n '.cm-panels.cm-panels-top': {borderBottom: `2px solid ${card.border}`},\n '.cm-panels.cm-panels-bottom': {borderTop: `2px solid ${card.border}`},\n\n // Lint diagnostics hover tooltips and the lint panel's entries\n '.cm-tooltip': {\n backgroundColor: card.bg,\n color: card.fg,\n border: `1px solid ${card.border}`,\n borderRadius: '3px',\n },\n // Rule messages quote whole rewrites of the query; wrap them rather than span the screen\n // (in a hover tooltip the lint content is a section of the shared tooltip element)\n '.cm-tooltip-lint': {fontFamily: fonts.text.family, maxWidth: '520px'},\n '.cm-panel.cm-panel-lint ul [aria-selected]': {backgroundColor: selection},\n '.cm-panel.cm-panel-lint ul [aria-selected] .cm-diagnostic': {color: card.fg},\n\n // Function documentation on hover and next to completions, and the extract button\n '.cm-vista-function-doc, .cm-vista-extract-button': {\n fontFamily: fonts.text.family,\n fontSize: rem(fonts.text.sizes[1].fontSize),\n },\n '.cm-vista-function-code, .cm-vista-function-doc code': {\n fontFamily: fonts.code.family,\n fontSize: rem(fonts.code.sizes[1].fontSize),\n },\n '.cm-vista-function-note': {color: card.muted.fg},\n '.cm-vista-function-link': {color: card.link.fg},\n '.cm-vista-extract-button:hover, .cm-vista-extract-button:focus-visible': {\n backgroundColor: selection,\n },\n '.cm-tooltip.cm-tooltip-autocomplete > ul': {fontFamily: fonts.code.family},\n '.cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]': {\n backgroundColor: selection,\n color: card.fg,\n },\n '.cm-completionDetail': {color: card.muted.fg, fontStyle: 'normal', marginLeft: '1em'},\n },\n {dark: color.dark},\n )\n}\n\n// oxlint-disable-next-line no-deprecated -- will fix in follow up PR\nfunction createHighlight(theme: Theme) {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const c = theme.sanity.color.base\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const s = theme.sanity.color.syntax\n return HighlightStyle.define([\n {tag: t.keyword, color: s.keyword},\n {tag: [t.propertyName, t.name, t.deleted, t.character, t.macroName], color: s.property},\n {tag: [t.function(t.variableName), t.labelName], color: s.function},\n {tag: [t.color, t.constant(t.name), t.standard(t.name)], color: s.variable},\n {tag: [t.definition(t.name), t.separator], color: s.constant},\n {\n tag: [\n t.typeName,\n t.className,\n t.number,\n t.changed,\n t.annotation,\n t.modifier,\n t.self,\n t.namespace,\n ],\n color: s.number,\n },\n {\n tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)],\n color: s.operator,\n },\n {tag: [t.meta, t.comment], color: s.comment},\n {tag: t.strong, fontWeight: 'bold'},\n {tag: t.emphasis, fontStyle: 'italic'},\n {tag: t.strikethrough, textDecoration: 'line-through'},\n {tag: t.heading, fontWeight: 'bold', color: s.property},\n {tag: [t.atom, t.bool, t.special(t.variableName)], color: s.boolean},\n {tag: [t.processingInstruction, t.string, t.inserted], color: s.string},\n {tag: t.invalid, color: c.fg},\n ])\n}\n","import {type EditorView} from '@codemirror/view'\n\n/** What the measurement needs from an editor view */\nexport type MeasurableEditorView = Pick<\n EditorView,\n 'scrollDOM' | 'contentDOM' | 'defaultCharacterWidth' | 'defaultLineHeight'\n> & {state: {doc: {lines: number}}}\n\nexport interface VisibleColumnsOptions {\n /**\n * The number of lines the document is about to have (formatting changes it). The\n * line-number gutter grows with the digits of that count, and a document taller than the\n * editor gets a vertical scrollbar; both take columns from the text.\n */\n lines?: number\n /** The width a classic (non-overlay) vertical scrollbar takes; measured from the page by default */\n scrollbarWidth?: number\n}\n\nfunction insets(element: Element, sides: readonly ('Left' | 'Right' | 'Top' | 'Bottom')[]): number {\n const style = getComputedStyle(element)\n let total = 0\n for (const side of sides) {\n total +=\n (parseFloat(style[`padding${side}`]) || 0) + (parseFloat(style[`border${side}Width`]) || 0)\n }\n return total\n}\n\n/** How many digits CodeMirror's line-number gutter reserves for a document of `lines` lines: 9, 99, 999, ... */\nexport function lineNumberDigits(lines: number): number {\n let widest = 9\n while (widest < lines) widest = widest * 10 + 9\n return String(widest).length\n}\n\nlet measuredScrollbarWidth: number | undefined\n\n/** The width of a classic vertical scrollbar; 0 where scrollbars are overlaid (macOS, phones) */\nfunction getScrollbarWidth(): number {\n if (measuredScrollbarWidth === undefined) {\n const probe = document.createElement('div')\n probe.style.cssText =\n 'position:absolute;top:-9999px;left:-9999px;width:100px;height:100px;overflow:scroll;visibility:hidden'\n document.body.append(probe)\n measuredScrollbarWidth = Math.max(0, probe.offsetWidth - probe.clientWidth)\n probe.remove()\n }\n return measuredScrollbarWidth\n}\n\n/**\n * How many default-width characters fit on a line of the editor without scrolling sideways: the\n * scroller's visible width less its gutters and the insets around the text (the content's\n * padding and borders, and the line's padding). With `lines`, the width is the one the editor\n * will have once the document has that many lines: a wider line-number gutter, and a vertical\n * scrollbar where the document will no longer fit the editor's height. `undefined` while the\n * editor has no layout, as when it is hidden or has not measured its font yet.\n */\nexport function getVisibleColumns(\n view: MeasurableEditorView,\n {lines, scrollbarWidth}: VisibleColumnsOptions = {},\n): number | undefined {\n const {scrollDOM, contentDOM, defaultCharacterWidth, defaultLineHeight} = view\n const gutters = scrollDOM.querySelector('.cm-gutters')\n const line = contentDOM.querySelector('.cm-line')\n const currentLines = view.state.doc.lines\n const nextLines = lines ?? currentLines\n\n const gutterGrowth =\n (lineNumberDigits(nextLines) - lineNumberDigits(currentLines)) * defaultCharacterWidth\n const willOverflowVertically =\n nextLines * defaultLineHeight + insets(contentDOM, ['Top', 'Bottom']) > scrollDOM.clientHeight\n const hasVerticalScrollbar = scrollDOM.scrollHeight > scrollDOM.clientHeight\n const scrollbarReserve =\n willOverflowVertically && !hasVerticalScrollbar ? (scrollbarWidth ?? getScrollbarWidth()) : 0\n\n const width =\n scrollDOM.clientWidth -\n (gutters instanceof HTMLElement ? gutters.offsetWidth : 0) -\n gutterGrowth -\n insets(contentDOM, ['Left', 'Right']) -\n (line ? insets(line, ['Left', 'Right']) : 0) -\n scrollbarReserve\n const columns = Math.floor(width / defaultCharacterWidth)\n return Number.isFinite(columns) && columns > 0 ? columns : undefined\n}\n","import {createVar, globalStyle, style} from '@vanilla-extract/css'\n\nexport const linePaddingLeftVar = createVar()\nexport const contentBorderRightWidthVar = createVar()\nexport const contentPaddingTopVar = createVar()\n\nexport const editorRoot = style({\n width: '100%',\n boxSizing: 'border-box',\n height: '100%',\n overflow: ['hidden', 'clip'],\n position: 'relative',\n display: 'flex',\n})\n\nglobalStyle(`${editorRoot} .cm-theme`, {\n width: '100%',\n})\n\nglobalStyle(`${editorRoot} .cm-editor`, {\n height: '100%',\n fontSize: '16px',\n lineHeight: '21px',\n})\n\nglobalStyle(`${editorRoot} .cm-line`, {\n paddingLeft: linePaddingLeftVar,\n})\n\nglobalStyle(`${editorRoot} .cm-content`, {\n borderRightWidth: `${contentBorderRightWidthVar} !important`,\n paddingTop: contentPaddingTopVar,\n})\n\n/** An editor that is as tall as its document, for use under a header rather than in a fixed pane */\nexport const editorRootAutoHeight = style({\n height: 'auto',\n})\n\nglobalStyle(`${editorRootAutoHeight} .cm-editor`, {\n height: 'auto',\n})\n","import {type Extension} from '@codemirror/state'\nimport {type Command} from '@codemirror/view'\nimport {rem, useTheme} from '@sanity/ui'\nimport CodeMirror, {\n EditorSelection,\n type ReactCodeMirrorProps,\n type ReactCodeMirrorRef,\n} from '@uiw/react-codemirror'\nimport {assignInlineVars} from '@vanilla-extract/dynamic'\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n type RefAttributes,\n} from 'react'\n\nimport {useCodemirrorTheme} from './useCodemirrorTheme'\nimport {getVisibleColumns} from './visibleColumns'\nimport {\n contentBorderRightWidthVar,\n contentPaddingTopVar,\n editorRoot,\n editorRootAutoHeight,\n linePaddingLeftVar,\n} from './VisionCodeMirror.css'\n\nfunction EditorRoot({\n autoHeight,\n underHeader,\n children,\n}: {\n autoHeight: boolean\n underHeader: boolean\n children: ReactNode\n}) {\n const {sanity} = useTheme()\n\n return (\n <div\n className={autoHeight ? `${editorRoot} ${editorRootAutoHeight}` : editorRoot}\n style={assignInlineVars({\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [linePaddingLeftVar]: `${rem(sanity.space[3])}`,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentBorderRightWidthVar]: `${rem(sanity.space[4])}`,\n // The tall top padding makes room for the label floating over a pane-filling editor\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n [contentPaddingTopVar]: `${rem(sanity.space[underHeader ? 3 : 5])}`,\n })}\n >\n {children}\n </div>\n )\n}\n\nexport interface VisionCodeMirrorHandle {\n resetEditorContent: (newContent: string) => void\n /** Edits the document like typing would: undoable, the selection mapped through the edits */\n applyChanges: (changes: readonly {from: number; to: number; insert: string}[]) => void\n /** Runs an editor command, as a key binding would; `false` when it did nothing or there is no editor */\n runCommand: (command: Command) => boolean\n /** Selects a range of the document, scrolls it into view and focuses the editor */\n selectRange: (from: number, to: number) => void\n /**\n * How many characters fit on a line without scrolling sideways, for the document as it is or,\n * with `lines`, as it will be with that many lines (a wider line-number gutter, a vertical\n * scrollbar); `undefined` while the editor has no layout (hidden, or not mounted yet)\n */\n getVisibleColumns: (lines?: number) => number | undefined\n}\n\nexport function VisionCodeMirror({\n ref,\n onChange,\n initialValue: initialValueProp,\n extensions,\n autoHeight = false,\n underHeader = autoHeight,\n}: Pick<ReactCodeMirrorProps, 'onChange'> & {\n initialValue: ReactCodeMirrorProps['value']\n extensions: Extension[]\n /**\n * Sizes the editor to its document instead of filling its container, for an editor that sits\n * under a header (so `underHeader` too)\n */\n autoHeight?: boolean\n /**\n * The editor sits under a header rather than under a label floating over it, so its content\n * needs less top padding\n */\n underHeader?: boolean\n} & RefAttributes<VisionCodeMirrorHandle>) {\n // While the view is alive its document is the source of truth: the `initialValue` prop only\n // seeded it, edits reach the parent through `onChange`, and parent updates come back through\n // `resetEditorContent`. The document is mirrored into `value` because `@uiw/react-codemirror`\n // destroys its `EditorView` when its effects are cleaned up and creates a new one from `value`\n // when they run again, which happens without a remount when the tool is hidden and shown again\n // inside an `<Activity>` boundary (`beta.reactActivityMode`). While the view is alive `value`\n // always equals its document, so the value sync never dispatches. Without a view the prop\n // leads instead: the handle is detached along with the effects, so a query formatted while the\n // tool is hidden only reaches this component as a new `initialValue`, and the next view must\n // show it rather than the document from before hiding.\n const [value, setValue] = useState(initialValueProp)\n const [hasView, setHasView] = useState(false)\n const [seenInitialValue, setSeenInitialValue] = useState(initialValueProp)\n if (initialValueProp !== seenInitialValue) {\n setSeenInitialValue(initialValueProp)\n if (!hasView) setValue(initialValueProp)\n }\n const handleCreateEditor = useCallback(() => setHasView(true), [])\n useEffect(() => {\n // The view is destroyed by the child's effect cleanups, which run along with this one\n return () => setHasView(false)\n }, [])\n\n const handleChange = useCallback<NonNullable<ReactCodeMirrorProps['onChange']>>(\n (nextValue, viewUpdate) => {\n setValue(nextValue)\n onChange?.(nextValue, viewUpdate)\n },\n [onChange],\n )\n const sanityTheme = useTheme()\n const theme = useCodemirrorTheme(sanityTheme)\n const codeMirrorRef = useRef<ReactCodeMirrorRef>(null)\n\n const resetEditorContent = useCallback((newContent: string) => {\n // Mirrored first, so a call made while there is no view still reaches the next one\n setValue(newContent)\n const editorView = codeMirrorRef.current?.view\n if (!editorView) return\n\n const currentDoc = editorView.state.doc.toString()\n if (newContent !== currentDoc) {\n editorView.dispatch({\n changes: {from: 0, to: currentDoc.length, insert: newContent},\n selection: EditorSelection.cursor(newContent.length), // Place cursor at end\n })\n // Show the new content from its start; longer lines in the replaced content may have\n // left the editor scrolled sideways\n editorView.scrollDOM.scrollTop = 0\n editorView.scrollDOM.scrollLeft = 0\n }\n }, [])\n\n const applyChanges = useCallback(\n (changes: readonly {from: number; to: number; insert: string}[]) => {\n codeMirrorRef.current?.view?.dispatch({changes: [...changes], userEvent: 'input'})\n },\n [],\n )\n\n const runCommand = useCallback((command: Command) => {\n const editorView = codeMirrorRef.current?.view\n return editorView ? command(editorView) : false\n }, [])\n\n const selectRange = useCallback((from: number, to: number) => {\n const editorView = codeMirrorRef.current?.view\n if (!editorView) return\n\n const length = editorView.state.doc.length\n editorView.dispatch({\n selection: EditorSelection.range(Math.min(from, length), Math.min(to, length)),\n scrollIntoView: true,\n })\n editorView.focus()\n }, [])\n\n const getVisibleColumnsOfEditor = useCallback((lines?: number) => {\n const editorView = codeMirrorRef.current?.view\n return editorView ? getVisibleColumns(editorView, {lines}) : undefined\n }, [])\n\n useImperativeHandle(\n ref,\n () => ({\n resetEditorContent,\n applyChanges,\n runCommand,\n selectRange,\n getVisibleColumns: getVisibleColumnsOfEditor,\n }),\n [resetEditorContent, applyChanges, runCommand, selectRange, getVisibleColumnsOfEditor],\n )\n\n return (\n <EditorRoot autoHeight={autoHeight} underHeader={underHeader}>\n <CodeMirror\n ref={codeMirrorRef}\n basicSetup={false}\n theme={theme}\n extensions={extensions}\n value={value}\n onChange={handleChange}\n onCreateEditor={handleCreateEditor}\n />\n </EditorRoot>\n )\n}\n","import {type ClientPerspective} from '@sanity/client'\nimport {type PerspectiveContextValue, type PerspectiveStack} from 'sanity'\n\nexport const SUPPORTED_PERSPECTIVES = [\n 'pinnedRelease',\n 'scheduledDrafts',\n 'raw',\n 'published',\n 'drafts',\n] as const\n\nexport type SupportedPerspective = (typeof SUPPORTED_PERSPECTIVES)[number]\n\n/**\n * Virtual perspectives are recognised by Vision, but do not concretely reflect the names of real\n * perspectives. Virtual perspectives are transformed into real perspectives before being used to\n * interact with data.\n *\n * For example, the `pinnedRelease` virtual perspective is transformed to the real perspective\n * currently pinned in Studio, and `scheduledDrafts` is transformed to a stack of all scheduled\n * draft release IDs.\n */\nexport const VIRTUAL_PERSPECTIVES = ['pinnedRelease', 'scheduledDrafts'] as const\n\nexport type VirtualPerspective = (typeof VIRTUAL_PERSPECTIVES)[number]\n\nexport function isSupportedPerspective(p: string): p is SupportedPerspective {\n return SUPPORTED_PERSPECTIVES.includes(p as SupportedPerspective)\n}\n\nexport function isVirtualPerspective(\n maybeVirtualPerspective: unknown,\n): maybeVirtualPerspective is VirtualPerspective {\n return (\n typeof maybeVirtualPerspective === 'string' &&\n VIRTUAL_PERSPECTIVES.includes(maybeVirtualPerspective as VirtualPerspective)\n )\n}\n\nexport function hasPinnedPerspective({selectedPerspectiveName}: PerspectiveContextValue): boolean {\n return typeof selectedPerspectiveName !== 'undefined'\n}\n\nexport function getActivePerspective({\n visionPerspective,\n perspectiveStack,\n scheduledDraftsStack,\n}: {\n visionPerspective: ClientPerspective | SupportedPerspective | undefined\n perspectiveStack: PerspectiveContextValue['perspectiveStack']\n scheduledDraftsStack?: PerspectiveStack\n}): ClientPerspective | undefined {\n if (visionPerspective === 'pinnedRelease') {\n return perspectiveStack\n }\n if (visionPerspective === 'scheduledDrafts') {\n return scheduledDraftsStack\n }\n return visionPerspective\n}\n\n/**\n * The navbar variant is only sent with Vision queries when the virtual \"Pinned release\"\n * perspective is selected. Other Vision perspectives stay local and do not attach a variant.\n */\nexport function getActiveVariant(\n visionPerspective: ClientPerspective | SupportedPerspective | undefined,\n selectedVariantName: string | undefined,\n): string | undefined {\n if (visionPerspective !== 'pinnedRelease') {\n return undefined\n }\n return selectedVariantName\n}\n","export function encodeQueryString(\n query: string,\n params: Record<string, unknown> = {},\n options: Record<string, string | string[]> = {},\n): string {\n const searchParams = new URLSearchParams()\n searchParams.set('query', query)\n\n for (const [key, value] of Object.entries(params)) {\n searchParams.set(`$${key}`, JSON.stringify(value))\n }\n\n for (const [key, value] of Object.entries(options)) {\n if (value) searchParams.set(key, `${value}`)\n }\n\n return `?${searchParams}`\n}\n","function acceptsNativePaste(node: EventTarget | undefined): boolean {\n const element = node as Partial<HTMLInputElement | HTMLTextAreaElement> | undefined\n const isTextField = element?.tagName === 'INPUT' || element?.tagName === 'TEXTAREA'\n return isTextField && element?.readOnly === false\n}\n\n/**\n * Whether a paste seen by Vision's `document` level listener was meant for Vision. The listener is\n * global, so it also observes pastes aimed at unrelated elements such as the Studio search field.\n *\n * Uses the dispatch path rather than `event.target`, because CodeMirror handles the paste and\n * re-renders the pasted line before the event reaches `document`, detaching the original target.\n */\nexport function isVisionPasteTarget(root: Node | null, event: ClipboardEvent): boolean {\n const path = event.composedPath()\n const [target] = path\n\n // A readonly field keeps focus after Copy URL but drops the paste, so Vision still claims it\n if (acceptsNativePaste(target)) {\n return false\n }\n\n // Nothing focused\n if (target === window.document || target === window.document.body) {\n return true\n }\n\n return root !== null && path.includes(root)\n}\n","export function isPlainObject(obj: unknown): obj is Record<string, unknown> {\n return (\n !!obj && typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Object]'\n )\n}\n","import {isPlainObject} from './isPlainObject'\n\n/** Every `localStorage` key Vision writes (classic and redesign alike) starts with this prefix */\nexport const VISION_STORAGE_KEY_PREFIX = 'sanityVision:'\n\nconst hasLocalStorage = supportsLocalStorage()\nconst clearListeners = new Set<() => void>()\n\nexport interface LocalStorageish {\n get: <T>(key: string, defaultVal: T) => T\n set: <T>(key: string, value: T) => T\n merge: <T>(props: T) => T\n}\n\n/** The `localStorage` instance when it is available and writable, `undefined` otherwise */\nexport function getStorage(): Storage | undefined {\n return hasLocalStorage ? globalThis.localStorage : undefined\n}\n\n/** Runs `listener` after `clearLocalStorage`, so in-memory copies of stored values can drop too */\nexport function onLocalStorageCleared(listener: () => void): () => void {\n clearListeners.add(listener)\n return () => {\n clearListeners.delete(listener)\n }\n}\n\nexport function clearLocalStorage() {\n const storage = getStorage()\n if (storage) {\n // Collect first: removing while iterating shifts the indices and skips every other key\n const keys: string[] = []\n for (let i = 0; i < storage.length; i++) {\n const key = storage.key(i)\n if (key?.startsWith(VISION_STORAGE_KEY_PREFIX)) {\n keys.push(key)\n }\n }\n keys.forEach((key) => storage.removeItem(key))\n }\n // In-memory copies exist even without a storage backend, so they are told either way\n clearListeners.forEach((listener) => listener())\n}\n\nexport function getLocalStorage(namespace: string): LocalStorageish {\n const storageKey = `${VISION_STORAGE_KEY_PREFIX}${namespace}`\n let loadedState: Record<string, unknown> | null = null\n\n return {get, set, merge}\n\n function get<T>(key: string, defaultVal: T): T {\n const state = ensureState()\n return typeof state[key] === 'undefined' ? defaultVal : (state[key] as T)\n }\n\n function set<T>(key: string, value: T): T {\n const state = ensureState()\n state[key] = value\n localStorage.setItem(storageKey, JSON.stringify(loadedState))\n return value\n }\n\n function merge<T>(props: T): T {\n const state = {...ensureState(), ...props}\n localStorage.setItem(storageKey, JSON.stringify(state))\n return state\n }\n\n function ensureState(): Record<string, unknown> {\n if (loadedState === null) {\n loadedState = loadState()\n }\n\n return loadedState\n }\n\n function loadState() {\n if (!hasLocalStorage) {\n return {}\n }\n\n try {\n const stored = JSON.parse(localStorage.getItem(storageKey) || '{}')\n return isPlainObject(stored) ? stored : {}\n } catch {\n return {}\n }\n }\n}\n\nfunction supportsLocalStorage() {\n const mod = 'lsCheck'\n try {\n localStorage.setItem(mod, mod)\n localStorage.removeItem(mod)\n return true\n } catch {\n return false\n }\n}\n","export interface ParsedApiQueryString {\n query: string\n params: Record<string, unknown>\n options: Record<string, string>\n}\n\nexport function parseApiQueryString(qs: URLSearchParams): ParsedApiQueryString {\n const params: Record<string, unknown> = {}\n const options: Record<string, string> = {}\n\n for (const [key, value] of qs.entries()) {\n if (key[0] === '$') {\n // Defined rather than assigned: `$__proto__` is a valid GROQ parameter, and assigning that\n // key would set the object's prototype instead of adding the parameter\n Object.defineProperty(params, key.slice(1), {\n value: JSON.parse(value),\n enumerable: true,\n configurable: true,\n writable: true,\n })\n continue\n }\n\n if (key === 'perspective' || key === 'variant' || key === 'resultSourceMap') {\n options[key] = value\n continue\n }\n }\n\n return {query: qs.get('query') || '', params, options}\n}\n","export function validateApiVersion(apiVersion: string): boolean {\n const parseableApiVersion = apiVersion.replace(/^v/, '').trim().toUpperCase()\n\n const isValidApiVersion =\n parseableApiVersion.length > 0 &&\n (parseableApiVersion === 'X' ||\n parseableApiVersion === '1' ||\n (/^\\d{4}-\\d{2}-\\d{2}$/.test(parseableApiVersion) && !isNaN(Date.parse(parseableApiVersion))))\n\n return isValidApiVersion\n}\n","import {\n isSupportedPerspective,\n isVirtualPerspective,\n type SupportedPerspective,\n} from '../perspectives'\nimport {parseApiQueryString} from './parseApiQueryString'\nimport {validateApiVersion} from './validateApiVersion'\n\n/**\n * Matches Content Lake query and listen URLs on any domain (custom CDN domains included),\n * capturing the API version, the dataset and the query string. Not anchored: the classic tool's\n * paste handler has always picked the URL out of the pasted text with it. `parseQueryUrl` is\n * stricter and takes the whole text to be the URL.\n */\nexport const SANITY_QUERY_URL = /\\/(vX|v1|v\\d{4}-\\d\\d-\\d\\d)\\/.*?(?:query|listen)\\/(.*?)\\?(.*)/\n\n/**\n * The path of a query or listen URL: the API version, whole segments in between (`data`), the\n * `query` or `listen` segment and the dataset\n */\nconst QUERY_URL_PATHNAME = /^\\/(vX|v1|v\\d{4}-\\d\\d-\\d\\d)\\/(?:[^/]+\\/)*(?:query|listen)\\/([^/]+)\\/?$/\n\nexport interface ParsedQueryUrl {\n query: string\n params: Record<string, unknown>\n rawParams: string\n /** The dataset the URL names */\n dataset: string\n /**\n * Whether that dataset is one the tool knows about; a tab only pins a known one (the URL may\n * come from another project, or name a dataset the user cannot see)\n */\n isKnownDataset: boolean\n apiVersion: string | undefined\n /** The perspective exactly as the URL states it (a release stack included), if any */\n urlPerspective: string | undefined\n /** Only set for perspectives the tool can represent (`raw`, `published`, `drafts`) */\n perspective: SupportedPerspective | undefined\n /** The URL carried a perspective that could not be mapped (for instance a release stack) */\n hasUnsupportedPerspective: boolean\n /** The content variant the request was sent with, if any */\n variant: string | undefined\n /** Whether the request asked for a content source map (`resultSourceMap=true`) */\n includeSourceMap: boolean\n /** The request went to the API CDN, `<project>.apicdn.sanity.io` (a custom domain cannot tell) */\n useCdn: boolean\n url: string\n}\n\nconst API_CDN_HOST = /(?:^|\\.)apicdn\\.sanity\\.(?:io|work)$/\n\n/** `<project>.apicdn.sanity.io`, where `useCdn` sends queries */\nexport function isApiCdnHost(hostname: string): boolean {\n return API_CDN_HOST.test(hostname)\n}\n\n/**\n * Parses a Content Lake query (or listen) URL, as pasted from the browser's network tab, into the\n * pieces of a tab. Returns `null` when the text is not such a URL: the whole text has to be one\n * http(s) URL, since a query URL quoted inside other text is not a paste of that URL, and the\n * redesign claims a paste it parses and replaces the tab's query with it.\n */\nexport function parseQueryUrl(data: string, datasets: readonly string[]): ParsedQueryUrl | null {\n const trimmed = data.trim()\n const url = parseHttpUrl(trimmed)\n const match = url?.pathname.match(QUERY_URL_PATHNAME)\n if (!url || !match) {\n return null\n }\n\n const [, usedApiVersion, usedDataset] = match\n\n let parts\n try {\n parts = parseApiQueryString(url.searchParams)\n } catch {\n return null\n }\n if (!parts.query) {\n return null\n }\n\n const urlPerspective = parts.options.perspective\n const perspective =\n urlPerspective &&\n isSupportedPerspective(urlPerspective) &&\n !isVirtualPerspective(urlPerspective)\n ? urlPerspective\n : undefined\n // `@sanity/client` writes the option only when it asked for a source map, as `true` or as the\n // `withKeyArraySelector` mode its stega encoding and Presentation's loaders use\n const {resultSourceMap} = parts.options\n const includeSourceMap = resultSourceMap === 'true' || resultSourceMap === 'withKeyArraySelector'\n\n return {\n query: parts.query,\n params: parts.params,\n rawParams: JSON.stringify(parts.params, null, 2),\n dataset: usedDataset,\n isKnownDataset: datasets.includes(usedDataset),\n apiVersion: validateApiVersion(usedApiVersion) ? usedApiVersion : undefined,\n urlPerspective: urlPerspective || undefined,\n perspective,\n hasUnsupportedPerspective: Boolean(urlPerspective) && perspective === undefined,\n variant: parts.options.variant || undefined,\n includeSourceMap,\n useCdn: isApiCdnHost(url.hostname),\n url: trimmed,\n }\n}\n\nfunction parseHttpUrl(text: string): URL | null {\n try {\n const url = new URL(text)\n return url.protocol === 'http:' || url.protocol === 'https:' ? url : null\n } catch {\n return null\n }\n}\n","import JSON5 from 'json5'\nimport {type TFunction} from 'sanity'\n\nexport function tryParseParams(\n val: string,\n t: TFunction<'vision'>,\n): Record<string, unknown> | Error {\n try {\n const parsed = val ? JSON5.parse(val) : {}\n return typeof parsed === 'object' && parsed && !Array.isArray(parsed) ? parsed : {}\n } catch (err) {\n // JSON5 always prefixes the error message with JSON5:, so we remove it\n // to clean up the error tooltip\n err.message = `${t('params.error.params-invalid-json')}:\\n\\n${err.message.replace(\n 'JSON5:',\n '',\n )}`\n return err\n }\n}\n","import {createVar, globalStyle, style} from '@vanilla-extract/css'\n\nexport const root = style({})\n\nglobalStyle(`${root} .sidebarPanes .Pane`, {\n overflowY: 'auto',\n overflowX: 'hidden',\n})\n\nexport const queryRecallPaneContainer = style({\n position: 'absolute',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n})\n\nexport const queryRecallPaneWrapper = style({\n minHeight: 0,\n})\n\nglobalStyle(`${root} .Resizer`, {\n background: 'var(--card-border-color)',\n opacity: 1,\n zIndex: 1,\n boxSizing: 'border-box',\n backgroundClip: 'padding-box',\n border: 'solid transparent',\n})\n\nglobalStyle(`${root} .Resizer:hover`, {\n borderColor: 'var(--card-shadow-ambient-color)',\n})\n\nglobalStyle(`${root} .Resizer.horizontal`, {\n height: '11px',\n margin: '-5px 0',\n borderWidth: '5px 0',\n cursor: 'row-resize',\n width: '100%',\n zIndex: 4,\n})\n\nglobalStyle(`${root} .Resizer.vertical`, {\n width: '11px',\n margin: '0 -5px',\n borderWidth: '0 5px',\n cursor: 'col-resize',\n zIndex: 2 /* To prevent the resizer from being hidden behind CodeMirror scroll area */,\n})\n\nglobalStyle(`${root} .Resizer.disabled`, {\n cursor: 'not-allowed',\n})\n\nglobalStyle(`${root} .Resizer.disabled:hover`, {\n borderColor: 'transparent',\n})\n\nexport const header = style({\n position: 'relative',\n flexShrink: 0,\n zIndex: 6,\n overflow: 'visible',\n borderBottom: '1px solid var(--card-border-color)',\n selectors: {\n // Override the background-color @sanity/ui's Card sets on itself\n '&&': {\n background: 'var(--card-bg-color)',\n },\n },\n})\n\nexport const styledLabel = style({\n flex: 1,\n})\n\nexport const splitpaneContainer = style({\n position: 'relative',\n minHeight: 0,\n zIndex: 1,\n})\n\nexport const queryCopyLink = style({\n cursor: 'pointer',\n marginRight: 'auto',\n})\n\nexport const inputBackgroundContainer = style({\n position: 'absolute',\n top: '1rem',\n left: 0,\n padding: 0,\n margin: 0,\n zIndex: 10,\n right: 0,\n})\n\nglobalStyle(`${inputBackgroundContainer} ${styledLabel}`, {\n userSelect: 'none',\n})\n\nexport const inputBackgroundContainerLeft = style({\n // This is so its aligned with the gutters of CodeMirror\n left: '33px',\n})\n\nexport const inputContainer = style({\n width: '100%',\n height: '100%',\n position: 'relative',\n flexDirection: 'column',\n})\n\nexport const resultOuterContainer = style({\n height: '100%',\n})\n\nexport const resultInnerContainer = style({\n position: 'relative',\n})\n\nexport const resultContainer = style({\n height: '100%',\n width: '100%',\n position: 'absolute',\n maxWidth: '100%',\n})\n\nexport const resultContainerInvalid = style({\n selectors: {\n '&&::after': {\n backgroundColor: 'var(--card-bg-color)',\n content: '\"\"',\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: 0,\n width: '100%',\n },\n },\n})\n\nexport const result = style({\n position: 'relative',\n width: '100%',\n height: '100%',\n zIndex: 20,\n})\n\nexport const resultFooter = style({\n borderTop: '1px solid var(--card-border-color)',\n flexWrap: 'wrap',\n})\n\nexport const timingsCard = style({\n position: 'relative',\n})\n\nexport const timingsTextMinHeightVar = createVar()\n\nexport const timingsTextContainer = style({\n height: '100%',\n minHeight: timingsTextMinHeightVar,\n})\n\nexport const downloadsCard = style({\n position: 'relative',\n})\n\nexport const saveResultSpanGapVar = createVar()\n\nexport const saveResultLabel = style({\n selectors: {\n // Override the transform/pseudo-elements @sanity/ui's Text applies for baseline trimming\n '&&': {\n transform: 'initial',\n },\n '&&::before': {\n content: 'none',\n },\n '&&::after': {\n content: 'none',\n },\n },\n})\n\nglobalStyle(`${saveResultLabel} > span`, {\n display: 'flex !important',\n flexWrap: 'wrap',\n gap: saveResultSpanGapVar,\n alignItems: 'center',\n})\n\nexport const controlsContainer = style({\n borderTop: '1px solid var(--card-border-color)',\n})\n","import {Card, Label, rem, Text, useTheme_v2 as useThemeV2} from '@sanity/ui'\nimport {assignInlineVars} from '@vanilla-extract/dynamic'\nimport {type ComponentProps, type ComponentPropsWithoutRef, type RefAttributes} from 'react'\nimport {Flex, Box} from 'ui5'\n\nimport {\n controlsContainer,\n downloadsCard,\n header,\n inputBackgroundContainer,\n inputBackgroundContainerLeft,\n inputContainer,\n queryCopyLink,\n queryRecallPaneContainer,\n queryRecallPaneWrapper,\n result,\n resultContainer,\n resultContainerInvalid,\n resultFooter,\n resultInnerContainer,\n resultOuterContainer,\n root,\n saveResultLabel,\n saveResultSpanGapVar,\n splitpaneContainer,\n styledLabel,\n timingsCard,\n timingsTextContainer,\n timingsTextMinHeightVar,\n} from './VisionGui.css'\n\nexport function Root({\n ref,\n ...props\n}: ComponentPropsWithoutRef<typeof Flex> & RefAttributes<HTMLDivElement>) {\n return <Flex {...props} ref={ref} className={root} />\n}\n\nexport function Header(props: ComponentProps<typeof Card>) {\n return <Card {...props} className={header} />\n}\n\nexport function StyledLabel(props: ComponentProps<typeof Label>) {\n return <Label {...props} className={styledLabel} />\n}\n\nexport function SplitpaneContainer(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={splitpaneContainer} />\n}\n\nexport function QueryRecallPaneContainer(props: ComponentProps<typeof Flex>) {\n return <Flex {...props} flexDirection=\"column\" className={queryRecallPaneContainer} />\n}\n\nexport function QueryRecallPaneWrapper(props: ComponentProps<typeof Flex>) {\n return (\n <Flex\n {...props}\n flexDirection=\"column\"\n flexBasis=\"0%\"\n flexGrow={1}\n overflow=\"hidden\"\n className={queryRecallPaneWrapper}\n />\n )\n}\n\nexport function QueryCopyLink(props: ComponentProps<'a'>) {\n return <a {...props} className={queryCopyLink} />\n}\n\nexport function InputBackgroundContainer(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={inputBackgroundContainer} />\n}\n\nexport function InputBackgroundContainerLeft(props: ComponentProps<typeof Box>) {\n return (\n <Box {...props} className={`${inputBackgroundContainer} ${inputBackgroundContainerLeft}`} />\n )\n}\n\nexport function InputContainer(props: ComponentProps<typeof Card>) {\n return <Card {...props} className={inputContainer} />\n}\n\nexport function ResultOuterContainer(props: ComponentProps<typeof Flex>) {\n return <Flex {...props} className={resultOuterContainer} />\n}\n\nexport function ResultInnerContainer(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={resultInnerContainer} />\n}\n\nexport function ResultContainer({\n isInvalid,\n ...props\n}: ComponentProps<typeof Card> & {isInvalid: boolean}) {\n return (\n <Card\n {...props}\n className={isInvalid ? `${resultContainer} ${resultContainerInvalid}` : resultContainer}\n />\n )\n}\n\nexport function Result(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={result} />\n}\n\nexport function ResultFooter(props: ComponentProps<typeof Flex>) {\n return <Flex {...props} className={resultFooter} />\n}\n\nexport function TimingsCard(props: ComponentProps<typeof Card>) {\n return <Card {...props} className={timingsCard} />\n}\n\nexport function TimingsTextContainer(props: ComponentProps<typeof Flex>) {\n const {space, font} = useThemeV2()\n const textSize = font.text.sizes[2]\n const minHeight = rem(\n space[3] * 2 + textSize.lineHeight - textSize.ascenderHeight - textSize.descenderHeight,\n )\n\n return (\n <Flex\n {...props}\n className={timingsTextContainer}\n style={assignInlineVars({[timingsTextMinHeightVar]: `${minHeight}`})}\n />\n )\n}\n\nexport function DownloadsCard(props: ComponentProps<typeof Card>) {\n return <Card {...props} className={downloadsCard} />\n}\n\nexport function SaveResultLabel(props: ComponentProps<typeof Text>) {\n const {space} = useThemeV2()\n\n return (\n <Text\n {...props}\n className={saveResultLabel}\n style={assignInlineVars({[saveResultSpanGapVar]: `${rem(space[3])}`})}\n />\n )\n}\n\nexport function ControlsContainer(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={controlsContainer} />\n}\n","import {ErrorOutlineIcon} from '@sanity/icons/ErrorOutline'\nimport {Card, Text} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport debounce from 'lodash-es/debounce.js'\nimport {type RefObject, useCallback, useMemo} from 'react'\nimport {type TFunction, useTranslation} from 'sanity'\nimport {Flex, Box} from 'ui5'\n\nimport {paramsExtensions} from '../codemirror/extensions'\nimport {VisionCodeMirror, type VisionCodeMirrorHandle} from '../codemirror/VisionCodeMirror'\nimport {visionLocaleNamespace} from '../i18n'\nimport {tryParseParams} from '../util/tryParseParams'\nimport {type Params} from './VisionGui'\nimport {InputBackgroundContainerLeft, StyledLabel} from './VisionGui.styled'\n\nconst defaultValue = `{\\n \\n}`\n\nexport interface ParamsEditorProps {\n value: string\n onChange: (changeEvt: string) => void\n paramsError: string | undefined\n hasValidParams: boolean\n editorRef: RefObject<VisionCodeMirrorHandle | null>\n}\n\nexport function ParamsEditor(props: ParamsEditorProps) {\n const {onChange, paramsError, hasValidParams, editorRef} = props\n const {t} = useTranslation(visionLocaleNamespace)\n\n const handleChangeRaw = useCallback(\n (newValue: string) => {\n onChange(newValue)\n },\n [onChange],\n )\n\n const handleChange = useMemo(() => debounce(handleChangeRaw, 333), [handleChangeRaw])\n return (\n <Card flex={1} tone={hasValidParams ? 'default' : 'critical'} data-testid=\"params-editor\">\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('params.label')}</StyledLabel>\n {paramsError && (\n <Tooltip animate placement=\"top\" portal content={<Text size={1}>{paramsError}</Text>}>\n <Box padding={1} marginX={2}>\n <Text>\n <ErrorOutlineIcon />\n </Text>\n </Box>\n </Tooltip>\n )}\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n ref={editorRef}\n initialValue={props.value || defaultValue}\n onChange={handleChange}\n extensions={paramsExtensions}\n />\n </Card>\n )\n}\n\nexport function parseParams(value: string, t: TFunction<typeof visionLocaleNamespace>): Params {\n const parsedParams = tryParseParams(value, t)\n const params = parsedParams instanceof Error ? {} : parsedParams\n const validationError = parsedParams instanceof Error ? parsedParams.message : undefined\n const isValid = !validationError\n\n return {\n parsed: params,\n raw: value,\n valid: isValid,\n error: validationError,\n }\n}\n","import {type ListenOptions} from '@sanity/client'\nimport {uuid} from '@sanity/uuid' // Import the UUID library\nimport {dequal as isEqual} from 'dequal/lite'\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react'\nimport {type KeyValueStoreValue, useClient, useCurrentUser, useKeyValueStore} from 'sanity'\n\nimport {DEFAULT_API_VERSION} from '../apiVersions'\n\nconst STORED_QUERIES_NAMESPACE = 'studio.vision-tool.saved-queries'\nconst SHARED_QUERY_DOCUMENT_TYPE = 'vision.sharedQuery'\nconst SHARED_QUERIES_QUERY = `*[_type == $sharedQueryType]{\n _id,\n authorId,\n savedAt,\n title,\n url\n} | order(savedAt desc)`\nconst SHARED_QUERY_LISTEN_OPTIONS: ListenOptions = {\n events: ['welcome', 'mutation', 'reconnect'],\n includeResult: true,\n visibility: 'query',\n}\n\nexport interface QueryConfig {\n _key: string\n url: string\n savedAt: string\n title?: string\n shared?: boolean\n authorId?: string\n isOwnedByCurrentUser?: boolean\n}\n\nexport interface StoredQueries {\n queries: QueryConfig[]\n}\n\nconst defaultValue = {\n queries: [],\n}\nconst keyValueStoreKey = STORED_QUERIES_NAMESPACE\n\ninterface SharedQueryDocument {\n _id: string\n _type?: string\n authorId: string\n savedAt: string\n title?: string\n url: string\n}\n\n/** What one hook instance has written to the personal list since the list it last took from the store */\ninterface OwnWrites {\n /** The list the store holds as far as the hook knows: its last write that went through */\n latest: QueryConfig[]\n /** The keys its writes changed, or tried to; an emission has to show them as in `latest` */\n keys: Set<string>\n}\n\n/** The keys whose entry differs between two lists */\nfunction changedKeys(before: QueryConfig[], after: QueryConfig[]): string[] {\n const was = new Map(before.map((query) => [query._key, query]))\n const is = new Map(after.map((query) => [query._key, query]))\n return [...new Set([...was.keys(), ...is.keys()])].filter(\n (key) => !isEqual(was.get(key), is.get(key)),\n )\n}\n\n/**\n * Whether `queries` shows every entry the hook's writes touched as the hook last wrote it, or\n * as the store kept it when a write failed. The store's initial read predates the writes and\n * never does, and neither does an echo of a write that failed; an own echo of a write that went\n * through, or another instance's write built on it, does.\n */\nfunction reflectsOwnWrites(queries: QueryConfig[], {latest, keys}: OwnWrites): boolean {\n const shown = new Map(queries.map((query) => [query._key, query]))\n const wanted = new Map(latest.map((query) => [query._key, query]))\n for (const key of keys) {\n if (!isEqual(shown.get(key), wanted.get(key))) return false\n }\n return true\n}\n\n/** The error for a failed move whose rollback failed too: the query is now in both lists */\nfunction moveLeftBothCopies(error: unknown, keptCopy: 'shared' | 'personal'): Error {\n const message = error instanceof Error ? error.message : String(error)\n return new Error(\n `${message} Removing the ${keptCopy} copy made for the move failed as well, so the query is now in both lists; delete the one you do not want.`,\n {cause: error},\n )\n}\n\nexport function useSavedQueries(): {\n queries: QueryConfig[]\n /** Resolves with the key of the saved query (the document id of a shared one) */\n saveQuery: (query: Omit<QueryConfig, '_key'>) => Promise<string>\n updateQuery: (query: QueryConfig) => Promise<void>\n deleteQuery: (key: string) => Promise<void>\n /** Moves a personal query to the shared list, keeping its title */\n shareQuery: (key: string) => Promise<void>\n /** Moves a shared query the current user owns back to their personal list */\n unshareQuery: (key: string) => Promise<void>\n /** Removes every personal query; shared ones are left alone */\n clearQueries: () => Promise<void>\n saving: boolean\n deleting: string[]\n /** Keys of the queries a share or unshare is moving right now */\n moving: string[]\n saveQueryError: Error | undefined\n deleteQueryError: Error | undefined\n error: Error | undefined\n} {\n const keyValueStore = useKeyValueStore()\n const workspaceClient = useClient({apiVersion: DEFAULT_API_VERSION})\n const currentUser = useCurrentUser()\n\n const [value, setValue] = useState<StoredQueries>(defaultValue)\n const [sharedQueries, setSharedQueries] = useState<QueryConfig[]>([])\n // Saves and updates may overlap (a share's save next to a user's own), so `saving` is derived\n // from how many are in flight rather than cleared by whichever one settles first\n const [pendingSaves, setPendingSaves] = useState(0)\n const [deleting, setDeleting] = useState<string[]>([])\n const [moving, setMoving] = useState<string[]>([])\n const [saveQueryError, setSaveQueryError] = useState<Error | undefined>()\n const [deleteQueryError, setDeleteQueryError] = useState<Error | undefined>()\n const [error, setError] = useState<Error | undefined>()\n\n // The personal list is one key-value entry that every mutation rewrites whole, so the writes\n // are queued and each one starts from the list the previous write produced rather than from a\n // render's snapshot: overlapping saves, deletes and moves cannot lose each other's changes\n const latestQueriesRef = useRef<QueryConfig[]>(defaultValue.queries)\n const personalWritesRef = useRef<Promise<unknown>>(Promise.resolve())\n // The store's emissions are not that base while a write is pending: the write's outcome is.\n // Nor is a server read from before this hook's writes: the store forwards writes (this hook's,\n // and those of another Vision instance kept mounted under `<Activity>`, which shares it) only\n // after a subscription's initial read is done, so a write made before has its events dropped\n // for that subscriber and the read arrives afterwards with the list from before the write; and\n // the read of a subscription started while a write is in flight (a hidden tool shown again) is\n // the same request the write raced. Such a read is the one emission that does not reflect the\n // writes this hook has made since the list it last took from the store, so those are kept\n // until an emission reflects them (an own echo, another instance's write built on them), which\n // proves the read is done and every later emission a live write and the base the next one\n // starts from. Each subscription has its own read to wait out\n const pendingPersonalWritesRef = useRef(0)\n const ownWritesRef = useRef<OwnWrites | null>(null)\n const storeEventsLiveRef = useRef(false)\n const loadedPersonalQueriesRef = useRef(false)\n // The moves in progress, by the key of the query being moved. A move copies the query first\n // and removes the original last, so until it settles the original is still there to be moved\n // again; a second share or unshare of it joins the pending move instead of making another copy\n const movesRef = useRef(new Map<string, Promise<void>>())\n\n const personalQueries = useMemo(() => {\n return keyValueStore.getKey(keyValueStoreKey)\n }, [keyValueStore])\n\n const mapSharedQueries = useCallback(\n (docs: SharedQueryDocument[]): QueryConfig[] => {\n const currentUserId = currentUser?.id\n\n return docs.map((doc) => ({\n _key: doc._id,\n authorId: doc.authorId,\n isOwnedByCurrentUser: doc.authorId === currentUserId,\n savedAt: doc.savedAt,\n shared: true,\n title: doc.title,\n url: doc.url,\n }))\n },\n [currentUser],\n )\n\n useEffect(() => {\n // The store emits its localStorage copy synchronously (`null` without one), the server's\n // list once read, and then every write. Nothing is prepended: this effect runs again when a\n // hidden `<Activity>` shows the tool again, and an initial value would reset the list, and\n // with it the base the next write starts from, to empty. Each subscription starts a new\n // server read, and the store's events reach it only once that read is done\n storeEventsLiveRef.current = false\n let subscribing = true\n const sub = personalQueries.subscribe({\n next: (data) => {\n const stored = data ? (data as unknown as StoredQueries) : null\n const ownWrites = ownWritesRef.current\n if (ownWrites && !storeEventsLiveRef.current) {\n if (!reflectsOwnWrites(stored?.queries ?? defaultValue.queries, ownWrites)) return\n // The localStorage copy comes synchronously while subscribing, ahead of the read;\n // anything after it is the read or an event, both of which mean the read is done\n if (!subscribing) storeEventsLiveRef.current = true\n }\n if (pendingPersonalWritesRef.current > 0) return\n // A list taken from the store while its events are live is the store's own, with nothing\n // of this hook's left to see reflected\n if (storeEventsLiveRef.current) ownWritesRef.current = null\n if (!stored) {\n // No localStorage copy; the server's answer follows, and a list already shown stays\n if (loadedPersonalQueriesRef.current) return\n latestQueriesRef.current = defaultValue.queries\n setValue(defaultValue)\n return\n }\n loadedPersonalQueriesRef.current = true\n latestQueriesRef.current = stored.queries\n setValue(stored)\n },\n error: (err) => setError(err as Error),\n })\n subscribing = false\n\n return () => sub.unsubscribe()\n }, [personalQueries])\n\n useEffect(() => {\n let cancelled = false\n\n const fetchSharedQueries = async () => {\n const docs = await workspaceClient.fetch<SharedQueryDocument[]>(SHARED_QUERIES_QUERY, {\n sharedQueryType: SHARED_QUERY_DOCUMENT_TYPE,\n })\n const nextDocs = docs || []\n if (!cancelled) {\n setSharedQueries(mapSharedQueries(nextDocs))\n }\n }\n\n void fetchSharedQueries().catch((err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n })\n\n const sub = workspaceClient.observable\n .listen(\n `*[_type == $sharedQueryType]`,\n {\n sharedQueryType: SHARED_QUERY_DOCUMENT_TYPE,\n },\n SHARED_QUERY_LISTEN_OPTIONS,\n )\n .subscribe({\n next: () => {\n void fetchSharedQueries().catch((err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n })\n },\n error: (err) => {\n if (!cancelled) {\n setError(err as Error)\n }\n },\n })\n\n return () => {\n cancelled = true\n sub.unsubscribe()\n }\n }, [workspaceClient, mapSharedQueries])\n\n /** Runs `task` after every personal write queued so far, whatever their outcome */\n const enqueuePersonalWrite = useCallback(<T>(task: () => Promise<T>): Promise<T> => {\n pendingPersonalWritesRef.current += 1\n const run = () =>\n task().finally(() => {\n pendingPersonalWritesRef.current -= 1\n })\n const result = personalWritesRef.current.then(run, run)\n personalWritesRef.current = result.catch(() => undefined)\n return result\n }, [])\n\n /**\n * Records a write of `attempted` over `before`, and `kept` as the list the store holds as a\n * result: `attempted` itself, or `before` again once the write has failed\n */\n const recordOwnWrite = useCallback(\n (before: QueryConfig[], attempted: QueryConfig[], kept: QueryConfig[]) => {\n const keys = new Set(ownWritesRef.current?.keys)\n for (const key of changedKeys(before, attempted)) keys.add(key)\n ownWritesRef.current = {latest: kept, keys}\n },\n [],\n )\n\n /**\n * Writes the personal list to the store. A failed server write does not reject there: the\n * store logs it and resolves `null`, which is turned back into an error here so callers can\n * roll back and report it.\n */\n const storePersonalQueries = useCallback(\n async (queries: QueryConfig[]) => {\n const stored = await keyValueStore.setKey(keyValueStoreKey, {\n queries,\n } as unknown as KeyValueStoreValue)\n if (stored === null) {\n throw new Error('The saved queries could not be stored.')\n }\n },\n [keyValueStore],\n )\n\n /**\n * Replaces the personal list with `update(latest)`, optimistically in the UI and then in the\n * store; a failed store write puts the previous list back. Resolves with the written list.\n */\n const writePersonalQueries = useCallback(\n (update: (queries: QueryConfig[]) => QueryConfig[]): Promise<QueryConfig[]> =>\n enqueuePersonalWrite(async () => {\n const before = latestQueriesRef.current\n const next = update(before)\n recordOwnWrite(before, next, next)\n latestQueriesRef.current = next\n setValue({queries: next})\n try {\n await storePersonalQueries(next)\n } catch (err) {\n // The store kept the previous list, so the UI shows it again\n recordOwnWrite(before, next, before)\n latestQueriesRef.current = before\n setValue({queries: before})\n throw err\n }\n return next\n }),\n [enqueuePersonalWrite, recordOwnWrite, storePersonalQueries],\n )\n\n const queries = useMemo(() => {\n return [...sharedQueries, ...value.queries].sort((a, b) => {\n return new Date(b.savedAt || 0).getTime() - new Date(a.savedAt || 0).getTime()\n })\n }, [sharedQueries, value.queries])\n\n /**\n * Runs a save or update as one of the saves in flight (`saving` holds until the last of them\n * has settled) and reports its failure through `saveQueryError` before rejecting with it\n */\n const runSave = useCallback(<T>(task: () => Promise<T>): Promise<T> => {\n setPendingSaves((count) => count + 1)\n setSaveQueryError(undefined)\n return task()\n .catch((err: unknown) => {\n const saveError = err instanceof Error ? err : new Error(String(err))\n setSaveQueryError(saveError)\n throw saveError\n })\n .finally(() => setPendingSaves((count) => count - 1))\n }, [])\n\n // Resolves with the key of the saved query (the document id of a shared one)\n const saveQuery = useCallback(\n (query: Omit<QueryConfig, '_key'>): Promise<string> =>\n runSave(async () => {\n if (query.shared) {\n if (!currentUser?.id) {\n throw new Error('No current user found. Unable to save shared query.')\n }\n const createdDoc = (await workspaceClient.create({\n _type: SHARED_QUERY_DOCUMENT_TYPE,\n authorId: currentUser.id,\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })) as SharedQueryDocument\n setSharedQueries((prev) => [...mapSharedQueries([createdDoc]), ...prev])\n return createdDoc._id\n }\n\n const newQuery = {...query, _key: uuid()}\n await writePersonalQueries((queries) => [newQuery, ...queries])\n return newQuery._key\n }),\n [currentUser, workspaceClient, mapSharedQueries, runSave, writePersonalQueries],\n )\n\n const updateQuery = useCallback(\n (query: QueryConfig): Promise<void> =>\n runSave(async () => {\n if (query.shared) {\n if (!currentUser?.id || query.authorId !== currentUser.id) {\n throw new Error('Only the author can update a shared query.')\n }\n const updatedDoc = (await workspaceClient\n .patch(query._key)\n .set({\n savedAt: query.savedAt,\n title: query.title,\n url: query.url,\n })\n .commit()) as SharedQueryDocument\n\n const [updatedSharedQuery] = mapSharedQueries([updatedDoc])\n setSharedQueries((prev) =>\n prev.map((existingQuery) =>\n existingQuery._key === query._key ? updatedSharedQuery : existingQuery,\n ),\n )\n return\n }\n\n await writePersonalQueries((queries) =>\n queries.map((q) => (q._key === query._key ? {...q, ...query} : q)),\n )\n }),\n [workspaceClient, currentUser, mapSharedQueries, runSave, writePersonalQueries],\n )\n\n // Rejects when the document could not be deleted; `deleteQuery` turns that into state\n const deleteSharedQuery = useCallback(\n async (key: string) => {\n const sharedQuery = sharedQueries.find((query) => query._key === key && query.shared)\n if (!sharedQuery) {\n throw new Error(`No shared query with key \"${key}\"`)\n }\n if (!currentUser?.id || sharedQuery.authorId !== currentUser.id) {\n throw new Error('Only the author can delete a shared query.')\n }\n await workspaceClient.delete(key)\n setSharedQueries((prev) => prev.filter((query) => query._key !== key))\n },\n [currentUser, sharedQueries, workspaceClient],\n )\n\n // Optimistic like the other personal mutations; rejects when the store write fails\n const deletePersonalQuery = useCallback(\n async (key: string) => {\n await writePersonalQueries((queries) => queries.filter((q) => q._key !== key))\n },\n [writePersonalQueries],\n )\n\n const deleteQuery = useCallback(\n async (key: string) => {\n setDeleting((prev) => [...prev, key])\n setDeleteQueryError(undefined)\n try {\n if (sharedQueries.some((query) => query._key === key && query.shared)) {\n await deleteSharedQuery(key)\n } else {\n await deletePersonalQuery(key)\n }\n } catch (err) {\n setDeleteQueryError(err instanceof Error ? err : new Error(String(err)))\n }\n setDeleting((prev) => prev.filter((k) => k !== key))\n },\n [deletePersonalQuery, deleteSharedQuery, sharedQueries],\n )\n\n /**\n * Runs `move` for `key` unless one is pending already, in which case that one is returned. The\n * move reports the copy it makes in the other list through `alsoMoving`: that copy shows up\n * before the original is removed, and is moving (a second move of it joins this one, and the\n * lists offer it no actions) until the move settles, since a failure takes it back.\n */\n const runMove = useCallback(\n (key: string, move: (alsoMoving: (copyKey: string) => void) => Promise<void>) => {\n const pending = movesRef.current.get(key)\n if (pending) {\n return pending\n }\n const keys = new Set([key])\n const alsoMoving = (copyKey: string) => {\n const thisMove = movesRef.current.get(key)\n if (thisMove) movesRef.current.set(copyKey, thisMove)\n keys.add(copyKey)\n setMoving((prev) => [...prev, copyKey])\n }\n setMoving((prev) => [...prev, key])\n const result = move(alsoMoving).finally(() => {\n for (const moved of keys) movesRef.current.delete(moved)\n setMoving((prev) => prev.filter((moved) => !keys.has(moved)))\n })\n movesRef.current.set(key, result)\n return result\n },\n [],\n )\n\n // Moving a query between the personal store and the shared documents takes two writes to two\n // stores, so it cannot be atomic. When the second write fails, the first is taken back so the\n // query does not end up in both places and a retry cannot pile up copies; the move then rejects\n // with the original error. Should taking it back fail as well, both copies stay in the lists,\n // as they do in the stores, and the error says so.\n const shareQuery = useCallback(\n (key: string) =>\n runMove(key, async (alsoMoving) => {\n const query = latestQueriesRef.current.find((q) => q._key === key)\n if (!query) {\n throw new Error(`No personal saved query with key \"${key}\"`)\n }\n const sharedKey = await saveQuery({\n shared: true,\n title: query.title,\n url: query.url,\n savedAt: new Date().toISOString(),\n })\n alsoMoving(sharedKey)\n try {\n await deletePersonalQuery(key)\n } catch (err) {\n try {\n await workspaceClient.delete(sharedKey)\n setSharedQueries((prev) => prev.filter((q) => q._key !== sharedKey))\n } catch {\n throw moveLeftBothCopies(err, 'shared')\n }\n throw err\n }\n }),\n [deletePersonalQuery, runMove, saveQuery, workspaceClient],\n )\n\n const unshareQuery = useCallback(\n (key: string) =>\n runMove(key, async (alsoMoving) => {\n const query = sharedQueries.find((q) => q._key === key)\n if (!query) {\n throw new Error(`No shared query with key \"${key}\"`)\n }\n const personalKey = await saveQuery({\n shared: false,\n title: query.title,\n url: query.url,\n savedAt: new Date().toISOString(),\n })\n alsoMoving(personalKey)\n try {\n await deleteSharedQuery(key)\n } catch (err) {\n try {\n await deletePersonalQuery(personalKey)\n } catch {\n throw moveLeftBothCopies(err, 'personal')\n }\n throw err\n }\n }),\n [deletePersonalQuery, deleteSharedQuery, runMove, saveQuery, sharedQueries],\n )\n\n const clearQueries = useCallback(\n () =>\n enqueuePersonalWrite(async () => {\n // Nothing disappears from the list until the store confirms the write\n const before = latestQueriesRef.current\n recordOwnWrite(before, defaultValue.queries, defaultValue.queries)\n try {\n await storePersonalQueries(defaultValue.queries)\n } catch (err) {\n recordOwnWrite(before, defaultValue.queries, before)\n throw err\n }\n latestQueriesRef.current = defaultValue.queries\n setValue(defaultValue)\n }),\n [enqueuePersonalWrite, recordOwnWrite, storePersonalQueries],\n )\n\n return {\n queries,\n saveQuery,\n updateQuery,\n deleteQuery,\n shareQuery,\n unshareQuery,\n clearQueries,\n saving: pendingSaves > 0,\n deleting,\n moving,\n saveQueryError,\n deleteQueryError,\n error,\n }\n}\n","import {style} from '@vanilla-extract/css'\n\nexport const fixedHeader = style({\n flexShrink: 0,\n background: 'var(--card-bg-color)',\n zIndex: 1,\n})\n\nexport const scrollContainer = style({\n minHeight: 0,\n width: '100%',\n minWidth: 0,\n})\n\nexport const queryList = style({\n minHeight: 0,\n})\n","import {AddIcon} from '@sanity/icons/Add'\nimport {LockIcon} from '@sanity/icons/Lock'\nimport {SearchIcon} from '@sanity/icons/Search'\nimport {TrashIcon} from '@sanity/icons/Trash'\nimport {UnpublishIcon} from '@sanity/icons/Unpublish'\nimport {UsersIcon} from '@sanity/icons/Users'\nimport {Badge, Button, Card, Dialog, Tab, TabList, Text, TextInput} from '@sanity/ui'\nimport {Code} from '@sanity/ui/code'\nimport {Menu, MenuButton, MenuItem} from '@sanity/ui/menu'\nimport {useToast} from '@sanity/ui/toast'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport {dequal as isEqual} from 'dequal/lite'\nimport {type ComponentProps, type ReactElement, useCallback, useState} from 'react'\nimport {ContextMenuButton, UserAvatar, useDateTimeFormat, useTranslation} from 'sanity'\nimport {Flex, Box, VStack} from 'ui5'\n\nimport {type QueryConfig, useSavedQueries} from '../hooks/useSavedQueries'\nimport {visionLocaleNamespace} from '../i18n'\nimport {fixedHeader, queryList, scrollContainer} from './QueryRecall.css'\nimport {type ParsedUrlState} from './VisionGui'\nimport {StyledLabel} from './VisionGui.styled'\n\nfunction FixedHeader(props: ComponentProps<typeof VStack>) {\n return <VStack {...props} className={fixedHeader} />\n}\n\nfunction ScrollContainer(props: ComponentProps<typeof Flex>) {\n return (\n <Flex\n {...props}\n flexDirection=\"column\"\n flexBasis=\"0%\"\n flexGrow={1}\n overflow=\"hidden\"\n className={scrollContainer}\n />\n )\n}\n\nfunction QueryList(props: ComponentProps<typeof Box>) {\n return <Box {...props} flexBasis=\"0%\" flexGrow={1} overflow=\"auto\" className={queryList} />\n}\n\nexport function QueryRecall({\n url,\n getStateFromUrl,\n setStateFromParsedUrl,\n currentQuery,\n currentParams,\n generateUrl,\n compactMode = false,\n}: {\n url?: string\n getStateFromUrl: (data: string) => ParsedUrlState | null\n setStateFromParsedUrl: (parsedUrlObj: ParsedUrlState) => void\n currentQuery: string\n currentParams: Record<string, unknown>\n generateUrl: (query: string, params: Record<string, unknown>) => string\n compactMode?: boolean\n}): ReactElement {\n type QueryFilter = 'all' | 'personal' | 'shared'\n const toast = useToast()\n const {saveQuery, updateQuery, queries, deleteQuery, shareQuery, unshareQuery, saving, deleting} =\n useSavedQueries()\n const {t} = useTranslation(visionLocaleNamespace)\n const formatDate = useDateTimeFormat({\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n })\n const [editingKey, setEditingKey] = useState<string | null>(null)\n const [editingTitle, setEditingTitle] = useState('')\n const [optimisticTitles, setOptimisticTitles] = useState<Record<string, string>>({})\n const [searchQuery, setSearchQuery] = useState('')\n const [queryFilter, setQueryFilter] = useState<QueryFilter>('all')\n const [selectedUrl, setSelectedUrl] = useState<string | undefined>(url)\n const [pendingUnshareKeys, setPendingUnshareKeys] = useState<string[]>([])\n const [shareDialogQuery, setShareDialogQuery] = useState<QueryConfig | null>(null)\n\n const handleSave = useCallback(async () => {\n // Generate the correct URL first\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q.shared) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(new Date(duplicateQuery?.savedAt || ''))}`,\n })\n return\n }\n\n if (!newUrl) return\n\n try {\n await saveQuery({\n shared: false,\n url: newUrl,\n savedAt: new Date().toISOString(),\n title: t('label.untitled-query'),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n }, [\n queries,\n toast,\n t,\n currentQuery,\n currentParams,\n getStateFromUrl,\n generateUrl,\n formatDate,\n saveQuery,\n ])\n\n const handleShareQuery = useCallback((query: QueryConfig) => {\n setShareDialogQuery(query)\n }, [])\n\n const handleConfirmShareQuery = useCallback(async () => {\n if (!shareDialogQuery) return\n\n try {\n // One move: when removing the personal copy fails, the shared one is taken back and the\n // move rejects, rather than the query staying in both lists behind a success toast\n await shareQuery(shareDialogQuery._key)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.shared-success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n setShareDialogQuery(null)\n }, [shareDialogQuery, shareQuery, t, toast])\n\n const handleUnshareQuery = useCallback(\n async (query: QueryConfig) => {\n setPendingUnshareKeys((prev) => [...prev, query._key])\n const clearPending = () =>\n setPendingUnshareKeys((prev) => prev.filter((key) => key !== query._key))\n const nextQueryObj = getStateFromUrl(query.url)\n const duplicatePersonalQuery = queries?.find((existingQuery) => {\n if (existingQuery._key === query._key) return false\n if (existingQuery.shared) return false\n const existingQueryObj = getStateFromUrl(existingQuery.url)\n return (\n nextQueryObj &&\n existingQueryObj &&\n existingQueryObj.query === nextQueryObj.query &&\n isEqual(existingQueryObj.params, nextQueryObj.params)\n )\n })\n if (duplicatePersonalQuery) {\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicatePersonalQuery.title} - ${formatDate.format(\n new Date(duplicatePersonalQuery.savedAt || ''),\n )}`,\n })\n clearPending()\n return\n }\n\n try {\n // One move, like sharing: a personal copy that cannot replace the shared one is taken back\n await unshareQuery(query._key)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.unshared-success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err instanceof Error ? err.message : String(err),\n })\n }\n clearPending()\n },\n [formatDate, getStateFromUrl, queries, t, toast, unshareQuery],\n )\n\n const handleTitleSave = useCallback(\n async (query: QueryConfig, newTitle: string) => {\n setEditingKey(null)\n setOptimisticTitles((prev) => ({...prev, [query._key]: newTitle}))\n\n try {\n await updateQuery({\n ...query,\n title: newTitle,\n })\n // Clear optimistic title on success\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n } catch (err) {\n // Clear optimistic title on error\n setOptimisticTitles((prev) => {\n const next = {...prev}\n delete next[query._key]\n return next\n })\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n },\n [updateQuery, toast, t],\n )\n\n const handleUpdate = useCallback(\n async (query: QueryConfig) => {\n const newUrl = generateUrl(currentQuery, currentParams)\n\n // Check for duplicates by comparing query content and params\n const isDuplicate = queries?.some((q) => {\n // Skip the current query when checking for duplicates\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n\n if (isDuplicate) {\n const duplicateQuery = queries?.find((q) => {\n if (q._key === query._key) return false\n const savedQueryObj = getStateFromUrl(q.url)\n return (\n savedQueryObj &&\n savedQueryObj.query === currentQuery &&\n isEqual(savedQueryObj.params, currentParams)\n )\n })\n toast.push({\n closable: true,\n status: 'warning',\n title: t('save-query.already-saved'),\n description: `${duplicateQuery?.title} - ${formatDate.format(\n new Date(duplicateQuery?.savedAt || ''),\n )}`,\n })\n return\n }\n\n try {\n await updateQuery({\n ...query,\n url: newUrl,\n savedAt: new Date().toISOString(),\n })\n setSelectedUrl(newUrl)\n toast.push({\n closable: true,\n status: 'success',\n title: t('save-query.success'),\n })\n } catch (err) {\n toast.push({\n closable: true,\n status: 'error',\n title: t('save-query.error'),\n description: err.message,\n })\n }\n },\n [\n currentQuery,\n currentParams,\n formatDate,\n generateUrl,\n updateQuery,\n toast,\n t,\n queries,\n getStateFromUrl,\n ],\n )\n\n const visibleQueries = queries?.filter((q) => !pendingUnshareKeys.includes(q._key))\n\n const filteredQueries = visibleQueries?.filter((q) => {\n const matchesSearch = (q.title ?? '').toLowerCase().includes(searchQuery.toLowerCase())\n const matchesFilter =\n queryFilter === 'all' ||\n (queryFilter === 'personal' && !q.shared) ||\n (queryFilter === 'shared' && q.shared)\n return matchesSearch && matchesFilter\n })\n\n return (\n <ScrollContainer>\n <FixedHeader gap={3}>\n <Flex\n padding={3}\n paddingTop={2}\n paddingBottom={0}\n justifyContent=\"space-between\"\n alignItems=\"center\"\n >\n <StyledLabel muted>{t('label.saved-queries')}</StyledLabel>\n <Button\n aria-label={t('action.save-query')}\n icon={AddIcon}\n disabled={saving}\n onClick={() => void handleSave()}\n mode=\"bleed\"\n />\n </Flex>\n <Box padding={3} paddingTop={0}>\n <TextInput\n placeholder={t('label.search-queries')}\n icon={SearchIcon}\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.currentTarget.value)}\n />\n </Box>\n <Box paddingX={3} paddingBottom={2}>\n <TabList gap={1}>\n <Tab\n id=\"query-filter-all\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.all')}\n selected={queryFilter === 'all'}\n onClick={() => setQueryFilter('all')}\n />\n <Tab\n id=\"query-filter-personal\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.personal')}\n selected={queryFilter === 'personal'}\n onClick={() => setQueryFilter('personal')}\n />\n <Tab\n id=\"query-filter-shared\"\n aria-controls=\"vision-query-recall-list\"\n label={t('label.shared')}\n selected={queryFilter === 'shared'}\n onClick={() => setQueryFilter('shared')}\n />\n </TabList>\n </Box>\n </FixedHeader>\n <QueryList id=\"vision-query-recall-list\">\n <Flex paddingY={3} flexDirection=\"column\">\n {filteredQueries?.map((q, index) => {\n const queryObj = getStateFromUrl(q.url)\n const fullQueryPreview = queryObj?.query || ''\n const shortQueryPreview = fullQueryPreview.split('{')[0]\n const isSelected = selectedUrl === q.url\n const canMutateQuery = !q.shared || q.isOwnedByCurrentUser\n\n // Compare against current live state\n const areQueriesEqual =\n queryObj && currentQuery === queryObj.query && isEqual(currentParams, queryObj.params)\n\n const isEdited = isSelected && !areQueriesEqual && canMutateQuery\n return (\n <Card\n key={q._key}\n paddingX={compactMode ? 3 : 4}\n paddingY={compactMode ? 3 : 4}\n tone=\"default\"\n onClick={(event) => {\n const target = event.target as HTMLElement | null\n if (target?.closest('[data-query-actions=\"true\"]')) {\n return\n }\n setSelectedUrl(q.url) // Update the selected query immediately\n const parsedUrl = getStateFromUrl(q.url)\n if (parsedUrl) {\n setStateFromParsedUrl(parsedUrl)\n }\n }}\n style={{\n borderTop: index === 0 ? '1px solid var(--card-border-color)' : undefined,\n position: 'relative',\n borderBottom: '1px solid var(--card-border-color)',\n borderLeft: isSelected\n ? '2px solid var(--card-muted-fg-color)'\n : '2px solid transparent',\n cursor: 'pointer',\n }}\n >\n <VStack gap={compactMode ? 2 : 3}>\n <Flex\n justifyContent=\"space-between\"\n alignItems={'center'}\n style={{minHeight: '25px'}}\n >\n <Flex alignItems=\"center\" gap={2} paddingRight={1} style={{flex: 1}}>\n {editingKey === q._key ? (\n <TextInput\n value={editingTitle}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n void handleTitleSave(q, editingTitle)\n } else if (event.key === 'Escape') {\n setEditingKey(null)\n }\n }}\n onBlur={() => handleTitleSave(q, editingTitle)}\n autoFocus\n style={{maxWidth: '170px', height: '24px'}}\n />\n ) : (\n <Text\n weight=\"bold\"\n size={compactMode ? 2 : 3}\n textOverflow=\"ellipsis\"\n style={{\n maxWidth: compactMode ? '180px' : '220px',\n cursor: canMutateQuery ? 'pointer' : 'default',\n padding: '2px 0',\n }}\n title={\n optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)\n }\n onClick={\n canMutateQuery\n ? () => {\n setEditingKey(q._key)\n setEditingTitle(q.title || q._key.slice(0, 5))\n }\n : undefined\n }\n >\n {optimisticTitles[q._key] ||\n q.title ||\n q._key.slice(q._key.length - 5, q._key.length)}\n </Text>\n )}\n {isEdited && (\n <Box\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--card-focus-ring-color)',\n }}\n />\n )}\n </Flex>\n <Flex alignItems=\"center\" gap={2}>\n <Box\n data-query-actions=\"true\"\n style={{\n width: '25px',\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n {(!q.shared || canMutateQuery) && (\n <MenuButton\n button={<ContextMenuButton />}\n id={`${q._key}-menu`}\n menu={\n <Menu>\n {!q.shared && (\n <MenuItem\n icon={UsersIcon}\n padding={3}\n text={t('label.share')}\n onClick={(event) => {\n event.stopPropagation()\n handleShareQuery(q)\n }}\n />\n )}\n {q.shared && canMutateQuery && (\n <MenuItem\n icon={UnpublishIcon}\n padding={3}\n text={t('action.unshare')}\n onClick={(event) => {\n event.stopPropagation()\n void handleUnshareQuery(q)\n }}\n />\n )}\n {canMutateQuery && (\n <MenuItem\n tone=\"critical\"\n padding={3}\n icon={TrashIcon}\n text={t('action.delete')}\n onClick={(event) => {\n event.stopPropagation()\n void deleteQuery(q._key)\n }}\n />\n )}\n </Menu>\n }\n popover={{\n animate: true,\n portal: true,\n placement: 'bottom-end',\n tone: 'default',\n }}\n />\n )}\n </Box>\n </Flex>\n </Flex>\n\n {fullQueryPreview ? (\n <Tooltip\n animate\n content={\n <Box\n padding={2}\n style={{maxWidth: '420px', maxHeight: '220px', overflow: 'auto'}}\n >\n <Code size={1}>{fullQueryPreview}</Code>\n </Box>\n }\n placement=\"top\"\n portal\n >\n <Code size={1}>{shortQueryPreview}</Code>\n </Tooltip>\n ) : (\n <Code />\n )}\n\n {compactMode ? (\n <VStack gap={1} style={{paddingTop: 0, minHeight: '30px'}}>\n <Flex alignItems=\"center\" gap={2} style={{minHeight: '18px'}}>\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n </Flex>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </VStack>\n ) : (\n <Flex\n alignItems=\"center\"\n gap={2}\n style={{paddingTop: '2px', minHeight: '20px'}}\n >\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '17px',\n height: '17px',\n }}\n >\n {q.shared ? (\n <UserAvatar size={0} user={q.authorId || ''} withTooltip />\n ) : (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n color: 'var(--card-muted-fg-color)',\n }}\n >\n <LockIcon />\n </Box>\n )}\n </Box>\n <Badge\n tone={q.shared ? 'primary' : 'default'}\n style={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {q.shared ? t('label.shared') : t('label.personal')}\n </Badge>\n <Text size={1} muted>\n •\n </Text>\n <Text size={1} muted>\n {formatDate.format(new Date(q.savedAt || ''))}\n </Text>\n </Flex>\n )}\n\n {isEdited && (\n <Button\n mode=\"ghost\"\n tone=\"default\"\n padding={2}\n style={{\n height: '24px',\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n fontSize: '12px',\n }}\n text={t('action.update')}\n onClick={(e) => {\n e.stopPropagation()\n void handleUpdate(q)\n }}\n />\n )}\n </VStack>\n </Card>\n )\n })}\n </Flex>\n </QueryList>\n {shareDialogQuery && (\n <Dialog\n animate\n id=\"vision-query-recall-share-dialog\"\n width={1}\n header={t('label.share')}\n onClose={() => setShareDialogQuery(null)}\n footer={\n <Flex justifyContent=\"flex-end\" gap={3} padding={3} alignItems=\"center\">\n <Button\n mode=\"bleed\"\n padding={2}\n text={t('action.query-cancel')}\n onClick={() => setShareDialogQuery(null)}\n />\n <Button\n padding={2}\n tone=\"primary\"\n text={t('action.save-shared-query')}\n onClick={() => void handleConfirmShareQuery()}\n />\n </Flex>\n }\n >\n <Box padding={4}>\n <Text size={2}>{t('save-query.share-warning')}</Text>\n </Box>\n </Dialog>\n )}\n </ScrollContainer>\n )\n}\n","import {useEffect, useState} from 'react'\n\ninterface PaneSizeOptions {\n defaultSize: number\n size?: number\n allowResize: boolean\n minSize: number\n maxSize: number\n}\n\ninterface RootSize {\n width: number\n height: number\n}\nfunction narrowBreakpoint(): boolean {\n return typeof window !== 'undefined' && window.innerWidth > 600\n}\n\nfunction calculatePaneSizeOptions(height: number | undefined): PaneSizeOptions {\n let rootHeight = height\n\n if (!rootHeight) {\n // Initial root height without header\n rootHeight =\n typeof window !== 'undefined' && typeof document !== 'undefined'\n ? document.body.getBoundingClientRect().height - 60\n : 0\n }\n return {\n defaultSize: rootHeight / (narrowBreakpoint() ? 2 : 1),\n size: rootHeight > 550 ? undefined : rootHeight * 0.4,\n allowResize: rootHeight > 550,\n minSize: Math.min(170, Math.max(170, rootHeight / 2)),\n maxSize: rootHeight > 650 ? rootHeight * 0.7 : rootHeight * 0.6,\n }\n}\n\nexport function usePaneSize({\n visionRootRef,\n}: {\n visionRootRef: React.RefObject<HTMLDivElement | null>\n}) {\n const [rootSize, setRootSize] = useState<RootSize>(() => ({\n width: typeof window !== 'undefined' ? window.innerWidth : 1000,\n height: typeof window !== 'undefined' ? window.innerHeight : 800,\n }))\n const [isNarrowBreakpoint, setIsNarrowBreakpoint] = useState(() => narrowBreakpoint())\n const [paneSizeOptions, setPaneSizeOptions] = useState<PaneSizeOptions>(() =>\n calculatePaneSizeOptions(undefined),\n )\n\n useEffect(() => {\n if (!visionRootRef.current) {\n return undefined\n }\n const handleResize = (entries: ResizeObserverEntry[]) => {\n const entry = entries?.[0]\n if (entry) {\n setRootSize({width: entry.contentRect.width, height: entry.contentRect.height})\n setIsNarrowBreakpoint(entry.contentRect.width > 600)\n setPaneSizeOptions(calculatePaneSizeOptions(entry.contentRect.height))\n }\n }\n const resizeObserver = new ResizeObserver(handleResize)\n resizeObserver.observe(visionRootRef.current)\n\n return () => {\n resizeObserver.disconnect()\n }\n }, [visionRootRef])\n\n return {paneSizeOptions, isNarrowBreakpoint, rootSize}\n}\n","import {PlayIcon} from '@sanity/icons/Play'\nimport {RocketIcon} from '@sanity/icons/Rocket'\nimport {StopIcon} from '@sanity/icons/Stop'\nimport {Button, Card, Hotkeys, Text} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport {useTranslation} from 'sanity'\nimport {Flex, Box} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {ControlsContainer} from './VisionGui.styled'\n\nexport interface VisionGuiControlsProps {\n hasValidParams: boolean\n queryInProgress: boolean\n listenInProgress: boolean\n onQueryExecution: () => void\n onListenExecution: () => void\n /**\n * Opens the redesigned Vision. Offered here for good while the beta flag is on, since the\n * invitation toast stays away once dismissed\n */\n onSwitchToRedesign?: () => void\n}\n\n/**\n * Vision GUI controls\n * To handle query and listen execution.\n */\nexport function VisionGuiControls({\n hasValidParams,\n listenInProgress,\n queryInProgress,\n onQueryExecution,\n onListenExecution,\n onSwitchToRedesign,\n}: VisionGuiControlsProps) {\n const {t} = useTranslation(visionLocaleNamespace)\n\n return (\n <ControlsContainer>\n <Card padding={3} paddingX={3}>\n <Tooltip\n animate\n content={\n <Card radius={4}>\n <Text size={1} muted>\n {t('params.error.params-invalid-json')}\n </Text>\n </Card>\n }\n placement=\"top\"\n disabled={hasValidParams}\n portal\n >\n <Flex justifyContent=\"space-evenly\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <Tooltip\n animate\n content={\n <Card radius={4}>\n <Hotkeys keys={['Ctrl', 'Enter']} />\n </Card>\n }\n placement=\"top\"\n portal\n >\n <Button\n width=\"fill\"\n onClick={onQueryExecution}\n type=\"button\"\n icon={queryInProgress ? StopIcon : PlayIcon}\n disabled={listenInProgress || !hasValidParams}\n tone={queryInProgress ? 'positive' : 'primary'}\n text={queryInProgress ? t('action.query-cancel') : t('action.query-execute')}\n />\n </Tooltip>\n </Box>\n <Box flexBasis=\"0%\" flexGrow={1} marginLeft={3}>\n <Button\n width=\"fill\"\n onClick={onListenExecution}\n type=\"button\"\n icon={listenInProgress ? StopIcon : PlayIcon}\n text={listenInProgress ? t('action.listen-cancel') : t('action.listen-execute')}\n mode=\"ghost\"\n disabled={!hasValidParams}\n tone={listenInProgress ? 'positive' : 'default'}\n />\n </Box>\n {onSwitchToRedesign && (\n <Box flexShrink={0} marginLeft={3}>\n <Tooltip\n animate\n content={<Text size={1}>{t('vista.redesign.try.description')}</Text>}\n placement=\"top\"\n portal\n >\n <Button\n aria-label={t('vista.redesign.try')}\n data-testid=\"vision-try-redesign\"\n icon={RocketIcon}\n mode=\"bleed\"\n onClick={onSwitchToRedesign}\n tone=\"primary\"\n type=\"button\"\n />\n </Tooltip>\n </Box>\n )}\n </Flex>\n </Tooltip>\n </Card>\n </ControlsContainer>\n )\n}\n","import {style} from '@vanilla-extract/css'\n\nexport const perspectivePopoverContent = style({\n /* This limits the width of the popover content */\n maxWidth: '240px',\n})\n\nexport const perspectivePopoverLink = style({\n cursor: 'pointer',\n marginRight: 'auto',\n})\n\nexport const dot = style({\n width: '4px',\n height: '4px',\n borderRadius: '3px',\n boxShadow: '0 0 0 1px var(--card-bg-color)',\n})\n","import {HelpCircleIcon} from '@sanity/icons/HelpCircle'\nimport {Badge, Button, Card, type CardTone, Inline, Text, useClickOutsideEvent} from '@sanity/ui'\nimport {Popover} from '@sanity/ui/popover'\nimport {type ComponentProps, useCallback, useRef, useState} from 'react'\nimport {Translate, useTranslation} from 'sanity'\nimport {Box, VStack} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {dot, perspectivePopoverContent, perspectivePopoverLink} from './PerspectivePopover.css'\n\nfunction PerspectivePopoverContent(props: ComponentProps<typeof Box>) {\n return <Box {...props} className={perspectivePopoverContent} />\n}\n\nfunction PerspectivePopoverLink(props: ComponentProps<'a'>) {\n return <a {...props} className={perspectivePopoverLink} />\n}\n\nfunction Dot({tone}: {tone: CardTone}) {\n return <div className={dot} style={{backgroundColor: `var(--card-badge-${tone}-dot-color)`}} />\n}\n\nconst SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION = false\n\nexport function PerspectivePopover() {\n const [open, setOpen] = useState(false)\n const buttonRef = useRef<HTMLButtonElement | null>(null)\n const popoverRef = useRef<HTMLDivElement | null>(null)\n\n const handleClick = useCallback(() => setOpen((o) => !o), [])\n\n const {t} = useTranslation(visionLocaleNamespace)\n\n useClickOutsideEvent(\n () => setOpen(false),\n () => [buttonRef.current, popoverRef.current],\n )\n\n return (\n <Popover\n animate\n content={\n <PerspectivePopoverContent>\n <VStack gap={4}>\n <Inline gap={2}>\n <Text weight=\"medium\">{t('settings.perspectives.title')}</Text>\n </Inline>\n\n <Card>\n <Text muted>{t('settings.perspectives.description')}</Text>\n </Card>\n <Card>\n <VStack gap={2}>\n <Box>\n <Badge tone=\"primary\">{t('label.new')}</Badge>\n </Box>\n <Text muted>\n <Translate\n t={t}\n i18nKey=\"settings.perspective.preview-drafts-renamed-to-drafts.description\"\n />\n </Text>\n </VStack>\n </Card>\n {SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? (\n <Card>\n <Badge tone=\"caution\">{t('label.new')}</Badge>\n <Card>\n <Text muted>\n <Translate t={t} i18nKey=\"settings.perspectives.new-default.description\" />\n </Text>\n </Card>\n </Card>\n ) : null}\n\n <Card>\n <Text>\n <PerspectivePopoverLink\n href=\"https://www.sanity.io/docs/perspectives\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {t('settings.perspectives.action.docs-link')} →\n </PerspectivePopoverLink>\n </Text>\n </Card>\n </VStack>\n </PerspectivePopoverContent>\n }\n placement=\"bottom-start\"\n portal\n padding={3}\n ref={popoverRef}\n open={open}\n >\n <Button\n icon={HelpCircleIcon}\n mode=\"bleed\"\n padding={2}\n paddingRight={1}\n tone=\"primary\"\n fontSize={1}\n ref={buttonRef}\n onClick={handleClick}\n selected={open}\n >\n <Dot tone={SHOW_DEFAULT_PERSPECTIVE_NOTIFICATION ? 'caution' : 'primary'} />\n </Button>\n </Popover>\n )\n}\n","import {CopyIcon} from '@sanity/icons/Copy'\nimport {Button, Card, Inline, Select, Text, TextInput} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport {\n type ChangeEvent,\n type ComponentType,\n Fragment,\n type RefObject,\n useCallback,\n useMemo,\n useRef,\n} from 'react'\nimport {\n getDefaultVariant,\n getVariantTitle,\n type PerspectiveContextValue,\n type TFunction,\n usePerspective,\n useTranslation,\n} from 'sanity'\nimport {Box, Flex, Grid, VStack} from 'ui5'\n\nimport {API_VERSIONS} from '../apiVersions'\nimport {visionLocaleNamespace} from '../i18n'\nimport {\n getActiveVariant,\n hasPinnedPerspective,\n SUPPORTED_PERSPECTIVES,\n type SupportedPerspective,\n} from '../perspectives'\nimport {PerspectivePopover} from './PerspectivePopover'\nimport {Header, QueryCopyLink, StyledLabel} from './VisionGui.styled'\n\nconst PinnedReleasePerspectiveOption: ComponentType<{\n pinnedPerspective: PerspectiveContextValue\n t: TFunction\n}> = ({pinnedPerspective, t}) => {\n const name =\n typeof pinnedPerspective.selectedPerspective === 'object'\n ? pinnedPerspective.selectedPerspective.metadata.title\n : pinnedPerspective.selectedPerspectiveName\n\n const variant = getDefaultVariant(pinnedPerspective.selectedVariants)\n const variantName = getDefaultVariant(pinnedPerspective.selectedVariantNames)\n const variantTitle = variant ? getVariantTitle(variant) : variantName\n\n const label = hasPinnedPerspective(pinnedPerspective)\n ? `(${t('settings.perspectives.pinned-release-label')})`\n : t('settings.perspectives.pinned-release-label')\n\n const text = useMemo(\n () =>\n [name, variantTitle ? `· ${variantTitle}` : undefined, label]\n .filter((value) => typeof value !== 'undefined')\n .join(' '),\n [label, name, variantTitle],\n )\n\n return (\n <option value=\"pinnedRelease\" disabled={!hasPinnedPerspective(pinnedPerspective)}>\n {text}\n </option>\n )\n}\n\nexport interface VisionGuiHeaderProps {\n onChangeDataset: (evt: ChangeEvent<HTMLSelectElement>) => void\n dataset: string\n customApiVersion: string | false\n apiVersion: string\n onChangeApiVersion: (evt: ChangeEvent<HTMLSelectElement>) => void\n datasets: string[]\n customApiVersionElementRef: RefObject<HTMLInputElement | null>\n onCustomApiVersionChange: (evt: ChangeEvent<HTMLInputElement>) => void\n isValidApiVersion: boolean\n onChangePerspective: (evt: ChangeEvent<HTMLSelectElement>) => void\n url?: string\n perspective?: SupportedPerspective\n isScheduledDraftsEnabled: boolean\n}\n\nexport function VisionGuiHeader({\n onChangeDataset,\n dataset,\n customApiVersion,\n apiVersion,\n onChangeApiVersion,\n datasets,\n customApiVersionElementRef,\n onCustomApiVersionChange,\n isValidApiVersion,\n onChangePerspective,\n url,\n perspective,\n isScheduledDraftsEnabled,\n}: VisionGuiHeaderProps) {\n const pinnedPerspective = usePerspective()\n const isApiVersionLocked = Boolean(\n getActiveVariant(perspective, getDefaultVariant(pinnedPerspective.selectedVariantNames)),\n )\n const {t} = useTranslation(visionLocaleNamespace)\n const operationUrlElement = useRef<HTMLInputElement | null>(null)\n const handleCopyUrl = useCallback(() => {\n const el = operationUrlElement.current\n if (!el) return\n\n try {\n el.select()\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n document.execCommand('copy')\n } catch {\n console.error('Unable to copy to clipboard :(')\n }\n }, [])\n\n return (\n <Header paddingX={3} paddingY={2}>\n <Grid\n gridTemplateColumns={[\n 'repeat(1, minmax(0, 1fr))',\n 'repeat(4, minmax(0, 1fr))',\n 'repeat(8, minmax(0, 1fr))',\n 'repeat(12, minmax(0, 1fr))',\n ]}\n >\n {/* Dataset selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <VStack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.dataset-label')}</StyledLabel>\n </Card>\n <Select value={dataset} onChange={onChangeDataset}>\n {datasets.map((ds: string) => (\n <option key={ds}>{ds}</option>\n ))}\n </Select>\n </VStack>\n </Box>\n\n {/* API version selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <VStack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>{t('settings.api-version-label')}</StyledLabel>\n </Card>\n <Tooltip\n animate\n content={<Text size={1}>{t('settings.api-version-locked-for-variant')}</Text>}\n disabled={!isApiVersionLocked}\n placement=\"bottom\"\n portal\n >\n <Box data-testid=\"api-version-selector-wrap\">\n <Select\n data-testid=\"api-version-selector\"\n value={customApiVersion === false ? apiVersion : 'other'}\n onChange={onChangeApiVersion}\n disabled={isApiVersionLocked}\n >\n {API_VERSIONS.map((version) => (\n <option key={version}>{version}</option>\n ))}\n <option key=\"other\" value=\"other\">\n {t('settings.other-api-version-label')}\n </option>\n </Select>\n </Box>\n </Tooltip>\n </VStack>\n </Box>\n\n {/* Custom API version input */}\n {!isApiVersionLocked && customApiVersion !== false && (\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <VStack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel textOverflow=\"ellipsis\">\n {t('settings.custom-api-version-label')}\n </StyledLabel>\n </Card>\n\n <TextInput\n ref={customApiVersionElementRef}\n value={customApiVersion}\n onChange={onCustomApiVersionChange}\n customValidity={\n isValidApiVersion ? undefined : t('settings.error.invalid-api-version')\n }\n maxLength={11}\n />\n </VStack>\n </Box>\n )}\n\n {/* Perspective selector */}\n <Box padding={1} gridColumn={['span 1 / span 1', 'span 2 / span 2']}>\n <VStack>\n <Card paddingBottom={1}>\n <Inline gap={1}>\n <Box>\n <StyledLabel>{t('settings.perspective-label')}</StyledLabel>\n </Box>\n\n <Box>\n <PerspectivePopover />\n </Box>\n </Inline>\n </Card>\n <Select\n data-testid=\"perspective-selector\"\n value={perspective || 'default'}\n onChange={onChangePerspective}\n >\n {SUPPORTED_PERSPECTIVES.map((perspectiveName) => {\n if (perspectiveName === 'pinnedRelease') {\n return (\n <Fragment key=\"pinnedRelease\">\n <PinnedReleasePerspectiveOption pinnedPerspective={pinnedPerspective} t={t} />\n <option key=\"default\" value=\"default\">\n {t('settings.perspectives.default')}\n </option>\n <hr />\n </Fragment>\n )\n }\n if (perspectiveName === 'scheduledDrafts') {\n if (!isScheduledDraftsEnabled) return null\n return (\n <option key=\"scheduledDrafts\" value=\"scheduledDrafts\">\n {t('settings.perspectives.scheduled-drafts')}\n </option>\n )\n }\n return <option key={perspectiveName}>{perspectiveName}</option>\n })}\n </Select>\n </VStack>\n </Box>\n\n {/* Query URL (for copying) */}\n {typeof url === 'string' ? (\n <Box\n padding={1}\n flexBasis=\"0%\"\n flexGrow={1}\n gridColumn={[\n 'span 1 / span 1',\n customApiVersion === false ? 'span 6 / span 6' : 'span 4 / span 4',\n ]}\n >\n <VStack>\n <Card paddingTop={2} paddingBottom={3}>\n <StyledLabel>\n {t('query.url')} \n <QueryCopyLink\n href={url}\n onClick={(event) => {\n // This is a copy-to-clipboard action, not a navigation\n event.preventDefault()\n handleCopyUrl()\n }}\n >\n [{t('action.copy-url-to-clipboard')}]\n </QueryCopyLink>\n </StyledLabel>\n </Card>\n <Flex flexBasis=\"0%\" flexGrow={1} gap={1}>\n <Box flexBasis=\"0%\" flexGrow={1}>\n <TextInput\n data-testid=\"vision-query-url\"\n readOnly\n type=\"url\"\n ref={operationUrlElement}\n value={url}\n />\n </Box>\n <Tooltip animate content={t('action.copy-url-to-clipboard')}>\n <Button\n aria-label={t('action.copy-url-to-clipboard')}\n type=\"button\"\n mode=\"ghost\"\n icon={CopyIcon}\n onClick={handleCopyUrl}\n />\n </Tooltip>\n </Flex>\n </VStack>\n </Box>\n ) : (\n <Box flexBasis=\"0%\" flexGrow={1} />\n )}\n </Grid>\n </Header>\n )\n}\n","import {json2csv} from 'json-2-csv'\n\nfunction getBlobUrl(content: string, mimeType: string): string {\n return URL.createObjectURL(\n new Blob([content], {\n type: mimeType,\n }),\n )\n}\n\nconst NOTHING = Symbol('nothing')\n\n/**\n * One blob URL per encoder, replaced (and the previous one revoked) when the encoded content\n * changes. The value last encoded is remembered as well, so asking for the same result again\n * costs nothing: results are never mutated, and encoding one only to compare it is the expensive\n * part for a large result.\n */\nfunction getMemoizedBlobUrlResolver(mimeType: string, stringEncoder: (input: any) => string) {\n return (() => {\n let prevInput: unknown = NOTHING\n let prevResult = ''\n let prevContent = ''\n return (input: unknown) => {\n if (input === prevInput && prevResult) {\n return prevResult\n }\n\n const content = stringEncoder(input)\n if (typeof content !== 'string' || content === '') {\n return undefined\n }\n\n prevInput = input\n if (content === prevContent) {\n return prevResult\n }\n\n prevContent = content\n if (prevResult) {\n URL.revokeObjectURL(prevResult)\n }\n\n prevResult = getBlobUrl(content, mimeType)\n return prevResult\n }\n })()\n}\n\nexport const getJsonBlobUrl = getMemoizedBlobUrlResolver('application/json', (input) =>\n JSON.stringify(input, null, 2),\n)\n\nexport const getCsvBlobUrl = getMemoizedBlobUrlResolver('text/csv', (input) => {\n return json2csv(Array.isArray(input) ? input : [input]).trim()\n})\n\n/**\n * Whether `getCsvBlobUrl` can produce anything for a result: `json2csv` yields nothing unless at\n * least one item is an object. A look at the shape, so a download button can be disabled without\n * converting a result nobody asked to download.\n */\nexport function canEncodeCsv(input: unknown): boolean {\n const items = Array.isArray(input) ? input : [input]\n return items.some((item) => typeof item === 'object' && item !== null && !Array.isArray(item))\n}\n","import {Spinner} from '@sanity/ui'\nimport {useEffect, useState} from 'react'\n\ninterface DelayedSpinnerProps {\n delay?: number\n}\n\n// Waits for X ms before showing a spinner\nexport function DelayedSpinner(props: DelayedSpinnerProps) {\n const [show, setShow] = useState(false)\n\n useEffect(() => {\n const timer = setTimeout(() => setShow(true), props.delay || 500)\n return () => clearTimeout(timer)\n }, [props.delay])\n\n return show ? <Spinner muted size={4} /> : null\n}\n","type ParsedApiVersion =\n | {kind: 'experimental'}\n | {kind: 'legacy'}\n | {kind: 'dated'; value: string}\n | {kind: 'unknown'}\n\n/**\n * Returns true when `selected` does not satisfy `required`.\n *\n * `X` is the experimental API: it satisfies every requirement, and when it is\n * the requirement only `X` satisfies it. Dated versions compare\n * lexicographically. `v1` sits below every dated version and `X`.\n */\nexport function isApiVersionBelow(selected: string, required: string): boolean {\n const parsedSelected = parseApiVersion(selected)\n const parsedRequired = parseApiVersion(required)\n\n if (parsedSelected.kind === 'unknown' || parsedRequired.kind === 'unknown') {\n return false\n }\n\n if (parsedSelected.kind === 'experimental') {\n return false\n }\n\n if (parsedRequired.kind === 'experimental') {\n return true\n }\n\n if (parsedSelected.kind === 'legacy') {\n return parsedRequired.kind !== 'legacy'\n }\n\n if (parsedRequired.kind === 'legacy') {\n return false\n }\n\n return parsedSelected.value < parsedRequired.value\n}\n\nfunction parseApiVersion(version: string): ParsedApiVersion {\n const normalized = version.replace(/^v/i, '').trim()\n\n if (!normalized) {\n return {kind: 'unknown'}\n }\n\n if (normalized.toUpperCase() === 'X') {\n return {kind: 'experimental'}\n }\n\n if (normalized === '1') {\n return {kind: 'legacy'}\n }\n\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(normalized)) {\n return {kind: 'dated', value: normalized}\n }\n\n return {kind: 'unknown'}\n}\n","import {type ClientPerspective} from '@sanity/client'\nimport {RELEASES_STUDIO_CLIENT_OPTIONS, VARIANTS_STUDIO_CLIENT_OPTIONS} from 'sanity'\n\nimport {type VisionLocaleResourceKeys} from '../i18n/resources'\nimport {isApiVersionBelow} from './compareApiVersion'\n\nconst NAMED_PERSPECTIVES = new Set(['raw', 'published', 'drafts', 'previewDrafts'])\n\nexport interface ApiVersionCapabilityContext {\n statusCode: number | undefined\n apiVersion: string\n perspective: ClientPerspective | undefined\n variant: string | undefined\n}\n\nexport interface ApiVersionCapabilityRequirement {\n id: string\n requiredApiVersion: string\n explanationKey: VisionLocaleResourceKeys\n applies: (context: ApiVersionCapabilityContext) => boolean\n}\n\n/**\n * Capability floors for Vision error copy. Order is precedence: the first\n * unsatisfied entry wins.\n *\n * Variant before releases matches `variantApiVersion()` in\n * `packages/sanity/src/core/variants/util/variantApiVersion.ts` — a variant\n * requirement takes precedence over the releases version for stacked\n * perspectives.\n *\n * Add a capability by appending an entry. Do not add a branch in the error\n * dialog.\n */\nexport const API_VERSION_CAPABILITIES: readonly ApiVersionCapabilityRequirement[] = [\n {\n id: 'variants',\n // `query.error.unsupported-variant` names the experimental API; reword it if this floor becomes dated.\n requiredApiVersion: VARIANTS_STUDIO_CLIENT_OPTIONS.apiVersion,\n explanationKey: 'query.error.unsupported-variant',\n applies: ({variant}) => Boolean(variant),\n },\n {\n id: 'releases',\n // Matches any stacked perspective, including scheduled drafts and agent bundles, so the copy\n // stays generic rather than naming releases.\n requiredApiVersion: RELEASES_STUDIO_CLIENT_OPTIONS.apiVersion,\n explanationKey: 'query.error.unsupported-release-perspective',\n applies: ({perspective}) => hasReleaseInPerspective(perspective),\n },\n]\n\nexport function hasReleaseInPerspective(perspective: ClientPerspective | undefined): boolean {\n if (!Array.isArray(perspective)) {\n return false\n }\n\n return perspective.some((entry) => !NAMED_PERSPECTIVES.has(entry))\n}\n\nexport function getUnsatisfiedApiVersionCapability(\n context: ApiVersionCapabilityContext,\n capabilities: readonly ApiVersionCapabilityRequirement[] = API_VERSION_CAPABILITIES,\n): ApiVersionCapabilityRequirement | undefined {\n if (context.statusCode !== 400) {\n return undefined\n }\n\n return capabilities.find(\n (capability) =>\n capability.applies(context) &&\n isApiVersionBelow(context.apiVersion, capability.requiredApiVersion),\n )\n}\n","import {style} from '@vanilla-extract/css'\n\n// `ErrorCode` always renders inside a critical-tone `Card`, so the card sets\n// `--card-muted-fg-color` to the muted critical foreground color we want here.\n// `&&` is needed to override the color @sanity/ui's Code sets on itself.\nexport const errorCode = style({\n selectors: {\n '&&': {\n color: 'var(--card-muted-fg-color)',\n },\n },\n})\n","import {Code} from '@sanity/ui/code'\nimport {type ComponentProps} from 'react'\n\nimport {errorCode} from './QueryErrorDialog.css'\n\nexport function ErrorCode(props: ComponentProps<typeof Code>) {\n return <Code {...props} className={errorCode} />\n}\n","import {useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {ErrorCode} from './QueryErrorDialog.styled'\n\ninterface ContentLakeQueryError {\n details: {\n query: string\n start: number\n end: number\n\n lineNumber?: number\n column?: number\n }\n}\n\nexport function QueryErrorDetails({error}: {error: ContentLakeQueryError | Error}) {\n const {t} = useTranslation(visionLocaleNamespace)\n\n if (!('details' in error)) {\n return null\n }\n\n const details = {...error.details, ...mapToLegacyDetails(error.details)}\n if (!details.line) {\n return null\n }\n\n return (\n <div>\n <ErrorCode size={1}>{`${details.line}\\n${dashLine(\n details.column,\n details.columnEnd,\n )}`}</ErrorCode>\n <Box marginTop={4}>\n <ErrorCode size={1}>{`${t('query.error.line')}: ${details.lineNumber}\\n${t(\n 'query.error.column',\n )}: ${details.column}`}</ErrorCode>\n </Box>\n </div>\n )\n}\n\nfunction mapToLegacyDetails(details: ContentLakeQueryError['details']) {\n if (!details || typeof details.query !== 'string' || typeof details.start !== 'number') {\n return {}\n }\n\n const {query, start, end} = details\n const lineStart = query.slice(0, start).lastIndexOf('\\n') + 1\n const lineNumber = (query.slice(0, lineStart).match(/\\n/g) || []).length\n const line = query.slice(lineStart, query.indexOf('\\n', lineStart))\n const column = start - lineStart\n const columnEnd = typeof end === 'number' ? end - lineStart : undefined\n\n return {line, lineNumber, column, columnEnd}\n}\n\nfunction dashLine(column: number, columnEnd: number | undefined): string {\n const line = '-'.repeat(column)\n const hats = `^`.repeat(columnEnd ? columnEnd - column : 1)\n return `${line}${hats}`\n}\n","import {type ClientPerspective, isHttpError} from '@sanity/client'\nimport {Text} from '@sanity/ui'\nimport {useTranslation} from 'sanity'\nimport {Flex} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {getUnsatisfiedApiVersionCapability} from '../util/apiVersionCapabilities'\nimport {prefixApiVersion} from '../util/prefixApiVersion'\nimport {QueryErrorDetails} from './QueryErrorDetails'\nimport {ErrorCode} from './QueryErrorDialog.styled'\n\ninterface QueryErrorDialogProps {\n error: Error\n apiVersion: string\n perspective: ClientPerspective | undefined\n variant: string | undefined\n}\n\nexport function QueryErrorDialog(props: QueryErrorDialogProps) {\n const {error, apiVersion, perspective, variant} = props\n const {t} = useTranslation(visionLocaleNamespace)\n const unsatisfiedCapability = getUnsatisfiedApiVersionCapability({\n statusCode: isHttpError(error) ? error.statusCode : undefined,\n apiVersion,\n perspective,\n variant,\n })\n\n return (\n <Flex gap={5} marginTop={2} flexDirection=\"column\">\n {unsatisfiedCapability ? (\n <Text data-testid=\"query-error-api-version-capability-hint\" size={1}>\n {t(unsatisfiedCapability.explanationKey, {\n apiVersion: prefixApiVersion(unsatisfiedCapability.requiredApiVersion),\n })}\n </Text>\n ) : null}\n <ErrorCode size={1}>{error.message}</ErrorCode>\n <QueryErrorDetails error={error} />\n </Flex>\n )\n}\n","/** A dotted key path written the way it reads in code: `0.author.tags.1` as `[0].author.tags[1]` */\nexport function describeKeypath(keypath: string): string {\n return keypath\n .split('.')\n .map((segment, index) =>\n /^\\d+$/.test(segment) ? `[${segment}]` : index === 0 ? segment : `.${segment}`,\n )\n .join('')\n}\n\n/**\n * The value at one of `@rexxars/react-json-inspector`'s dotted key paths (`0.author.name`; empty\n * for the root). A key may contain dots itself, so at each step the longest run of segments that\n * names a property wins. Undefined when the path leads nowhere.\n */\nexport function getAtKeypath(data: unknown, keypath: string): {value: unknown} | undefined {\n if (keypath === '') return {value: data}\n const segments = keypath.split('.')\n let current = data\n let index = 0\n while (index < segments.length) {\n const container = current\n if (container === null || typeof container !== 'object') return undefined\n let end = segments.length\n while (end > index && !Object.hasOwn(container, segments.slice(index, end).join('.'))) end--\n if (end === index) return undefined\n current = Reflect.get(container, segments.slice(index, end).join('.'))\n index = end\n }\n return {value: current}\n}\n","import {createVar, globalStyle, style} from '@vanilla-extract/css'\n\nexport const codeFamilyVar = createVar()\nexport const codeFontSizeVar = createVar()\nexport const codeLineHeightVar = createVar()\nexport const space0Var = createVar()\nexport const space2Var = createVar()\nexport const space4Var = createVar()\nexport const space4HalfVar = createVar()\nexport const syntaxPropertyVar = createVar()\nexport const syntaxConstantVar = createVar()\nexport const syntaxStringVar = createVar()\nexport const syntaxBooleanVar = createVar()\nexport const syntaxNumberVar = createVar()\n\nexport const resultViewWrapper = style({})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector, ${resultViewWrapper} .json-inspector .json-inspector__selection`,\n {\n fontFamily: codeFamilyVar,\n fontSize: codeFontSizeVar,\n lineHeight: codeLineHeightVar,\n color: 'var(--card-code-fg-color)',\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__leaf`, {\n paddingLeft: space4Var,\n})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__leaf.json-inspector__leaf_root`,\n {\n paddingTop: space0Var,\n paddingLeft: 0,\n },\n)\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector > .json-inspector__leaf_root > .json-inspector__line > .json-inspector__key`,\n {\n display: 'none',\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__line`, {\n display: 'block',\n position: 'relative',\n cursor: 'default',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__line::after`, {\n content: '\"\"',\n position: 'absolute',\n top: 0,\n left: '-200px',\n right: '-50px',\n bottom: 0,\n zIndex: -1,\n pointerEvents: 'none',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__line:hover::after`, {\n background: 'var(--card-code-bg-color)',\n})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__leaf_composite > .json-inspector__line`,\n {\n cursor: 'pointer',\n },\n)\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__leaf_composite > .json-inspector__line::before`,\n {\n content: \"'▸ '\",\n marginLeft: `calc(0px - ${space4Var})`,\n fontSize: codeFontSizeVar,\n lineHeight: codeLineHeightVar,\n },\n)\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__leaf_expanded.json-inspector__leaf_composite > .json-inspector__line::before`,\n {\n content: \"'▾ '\",\n fontSize: codeFontSizeVar,\n lineHeight: codeLineHeightVar,\n },\n)\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__radio, ${resultViewWrapper} .json-inspector .json-inspector__flatpath`,\n {\n display: 'none',\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__value`, {\n marginLeft: space4HalfVar,\n})\n\n/** Set on the wrapper when every property has a copy button */\nexport const copyableResult = style({})\n\n/**\n * Copies the value of the property on its line. It sits at the line's end, out of the flow so\n * the tree's layout is the same with or without it, and shows while the line is hovered or the\n * button focused.\n */\nexport const copyNodeButton = style({\n appearance: 'none',\n background: 'none',\n border: 0,\n borderRadius: '2px',\n color: 'var(--card-muted-fg-color)',\n cursor: 'pointer',\n display: 'inline-flex',\n fontSize: '1.2em',\n lineHeight: codeLineHeightVar,\n opacity: 0,\n padding: 0,\n position: 'absolute',\n right: 0,\n top: 0,\n selectors: {\n '&:hover': {color: 'var(--card-fg-color)'},\n '&:focus-visible': {opacity: 1, outline: '1px solid var(--card-focus-ring-color)'},\n },\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__line:hover ${copyNodeButton}`, {\n opacity: 1,\n})\n\n// Long values wrap before the button rather than under it\nglobalStyle(`${copyableResult} .json-inspector .json-inspector__line`, {\n paddingRight: '1.5em',\n})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector > .json-inspector__leaf_root > .json-inspector__line > .json-inspector__key + .json-inspector__value`,\n {\n margin: 0,\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__key`, {\n color: syntaxPropertyVar,\n})\n\nglobalStyle(\n `${resultViewWrapper} .json-inspector .json-inspector__value_helper, ${resultViewWrapper} .json-inspector .json-inspector__value_null`,\n {\n color: syntaxConstantVar,\n },\n)\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__not-found`, {\n paddingTop: space2Var,\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__value_string`, {\n color: syntaxStringVar,\n wordBreak: 'break-word',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__value_boolean`, {\n color: syntaxBooleanVar,\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__value_number`, {\n color: syntaxNumberVar,\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__show-original`, {\n display: 'inline-block',\n padding: '0 6px',\n cursor: 'pointer',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__show-original:hover`, {\n color: 'inherit',\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__show-original::before`, {\n content: \"'↔'\",\n})\n\nglobalStyle(`${resultViewWrapper} .json-inspector .json-inspector__show-original:hover::after`, {\n content: \"' expand'\",\n})\n","import {JsonInspector} from '@rexxars/react-json-inspector'\nimport {CopyIcon} from '@sanity/icons/Copy'\nimport {LinkIcon} from '@sanity/icons/Link'\nimport {rem, useTheme_v2 as useThemeV2} from '@sanity/ui'\nimport {Code} from '@sanity/ui/code'\nimport {assignInlineVars} from '@vanilla-extract/dynamic'\nimport LRU from 'quick-lru'\nimport {createContext, type ReactNode, use, useMemo} from 'react'\nimport {useDataset} from 'sanity'\nimport {IntentLink} from 'sanity/router'\n\nimport {getAtKeypath} from '../util/getAtKeypath'\nimport {\n codeFamilyVar,\n codeFontSizeVar,\n codeLineHeightVar,\n copyableResult,\n copyNodeButton,\n resultViewWrapper,\n space0Var,\n space2Var,\n space4HalfVar,\n space4Var,\n syntaxBooleanVar,\n syntaxConstantVar,\n syntaxNumberVar,\n syntaxPropertyVar,\n syntaxStringVar,\n} from './ResultView.css'\n\nconst lru = new LRU({maxSize: 50000})\n\nfunction ResultViewWrapper({children, copyable}: {children: ReactNode; copyable?: boolean}) {\n const {color, font, space} = useThemeV2()\n const codeSize = font.code.sizes[2]\n\n return (\n <div\n className={copyable ? `${resultViewWrapper} ${copyableResult}` : resultViewWrapper}\n style={assignInlineVars({\n [codeFamilyVar]: font.code.family,\n [codeFontSizeVar]: `${codeSize.fontSize}px`,\n [codeLineHeightVar]: `${codeSize.lineHeight}px`,\n [space0Var]: `${rem(space[0])}`,\n [space2Var]: `${rem(space[2])}`,\n [space4Var]: `${rem(space[4])}`,\n [space4HalfVar]: `${rem(space[4] / 2)}`,\n [syntaxPropertyVar]: color.syntax.property,\n [syntaxConstantVar]: color.syntax.constant,\n [syntaxStringVar]: color.syntax.string,\n [syntaxBooleanVar]: color.syntax.boolean,\n [syntaxNumberVar]: color.syntax.number,\n })}\n >\n {children}\n </div>\n )\n}\n\n/** A copy button next to every property of the tree, copying the property's value */\nexport interface ResultViewCopy {\n /** Accessible name and tooltip of the buttons */\n label: string\n /** `keypath` is the property's dotted path from the root, empty for the root itself */\n onCopy: (value: unknown, keypath: string) => void\n}\n\ninterface ResultLabelContextValue {\n data: unknown\n copy: ResultViewCopy | undefined\n /** `_id` and `_ref` values link to their documents when the result is the workspace's */\n linkDocuments: boolean\n}\n\n// The inspector takes one component for every label, so what it needs comes through context\nconst ResultLabelContext = createContext<ResultLabelContextValue | null>(null)\n\nexport function ResultView(props: {\n data: unknown\n datasetName: string\n copy?: ResultViewCopy\n}): React.JSX.Element {\n const {data, datasetName, copy} = props\n const workspaceDataset = useDataset()\n const linkDocuments = workspaceDataset === datasetName\n const labelContext = useMemo(() => ({data, copy, linkDocuments}), [copy, data, linkDocuments])\n\n if (isRecord(data) || Array.isArray(data)) {\n return (\n <ResultViewWrapper copyable={Boolean(copy)}>\n <ResultLabelContext value={labelContext}>\n <JsonInspector\n data={data}\n search={false}\n isExpanded={isExpanded}\n onClick={toggleExpanded}\n interactiveLabel={copy || linkDocuments ? InteractiveLabel : undefined}\n />\n </ResultLabelContext>\n </ResultViewWrapper>\n )\n }\n\n return <Code language=\"json\">{JSON.stringify(data)}</Code>\n}\n\nfunction InteractiveLabel(props: {value: string; isKey: boolean; keypath: string}) {\n const context = use(ResultLabelContext)\n if (props.isKey) {\n return context?.copy ? (\n <CopyNodeButton copy={context.copy} data={context.data} keypath={props.keypath} />\n ) : null\n }\n return context?.linkDocuments ? <DocumentEditLabel {...props} /> : null\n}\n\nfunction CopyNodeButton(props: {copy: ResultViewCopy; data: unknown; keypath: string}) {\n const {copy, data, keypath} = props\n return (\n <button\n aria-label={copy.label}\n className={copyNodeButton}\n data-testid=\"result-copy-node\"\n onClick={(event) => {\n // The button sits in the line's label, which toggles the node when clicked\n event.preventDefault()\n event.stopPropagation()\n const found = getAtKeypath(data, keypath)\n if (found) copy.onCopy(found.value, keypath)\n }}\n title={copy.label}\n type=\"button\"\n >\n <CopyIcon />\n </button>\n )\n}\n\nfunction DocumentEditLabel(props: {value: string; isKey: boolean; keypath: string}) {\n if (props.isKey || (!props.keypath.endsWith('_id') && !props.keypath.endsWith('_ref'))) {\n return null\n }\n\n return (\n <IntentLink intent=\"edit\" params={{id: props.value}}>\n <LinkIcon />\n </IntentLink>\n )\n}\n\nfunction isExpanded(keyPath: string, value: unknown): boolean {\n const depthLimit = 4\n const cached = lru.get(keyPath) as boolean | undefined\n\n if (typeof cached === 'boolean') {\n return cached\n }\n\n const segments = keyPath.split('.', depthLimit)\n if (segments.length === depthLimit) {\n return false\n }\n\n if (Array.isArray(value)) {\n return true\n }\n\n return isRecord(value) && !segments.some((key) => isArrayKeyOverLimit(key))\n}\n\nfunction toggleExpanded(event: {path: string}): void {\n const {path} = event\n const current = lru.get(path)\n\n if (current === undefined) {\n // something is wrong\n return\n }\n\n lru.set(path, !current)\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nconst numeric = /^\\d+$/\nfunction isArrayKeyOverLimit(segment: string, limit = 10) {\n return numeric.test(segment) && parseInt(segment, 10) > limit\n}\n","import {DocumentSheetIcon} from '@sanity/icons/DocumentSheet'\nimport {Button} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\nimport {useTranslation} from 'sanity'\n\nimport {visionLocaleNamespace} from '../i18n'\n\ninterface SaveButtonProps {\n blobUrl: string | undefined\n}\n\nexport function SaveCsvButton({blobUrl}: SaveButtonProps) {\n const {t} = useTranslation(visionLocaleNamespace)\n\n // An anchor cannot be disabled, so when there is nothing to download we render a plain\n // disabled button (which also prevents the click natively) instead of a disabled link.\n if (!blobUrl) {\n return (\n <Tooltip animate content={t('result.save-result-as-csv.not-csv-encodable')} placement=\"top\">\n <Button\n disabled\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />\n </Tooltip>\n )\n }\n\n return (\n <Button\n as=\"a\"\n download=\"query-result.csv\"\n href={blobUrl}\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"CSV\" // String is a File extension\n tone=\"default\"\n />\n )\n}\n\nexport function SaveJsonButton({blobUrl}: SaveButtonProps) {\n return (\n <Button\n as=\"a\"\n download={'query-result.json'}\n href={blobUrl}\n icon={DocumentSheetIcon}\n mode=\"ghost\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n text=\"JSON\" // String is a File extension\n tone=\"default\"\n />\n )\n}\n","import {type ClientPerspective, type MutationEvent} from '@sanity/client'\nimport {Text} from '@sanity/ui'\nimport {Translate, useTranslation} from 'sanity'\nimport {Box} from 'ui5'\n\nimport {visionLocaleNamespace} from '../i18n'\nimport {getCsvBlobUrl, getJsonBlobUrl} from '../util/getBlobUrl'\nimport {DelayedSpinner} from './DelayedSpinner'\nimport {QueryErrorDialog} from './QueryErrorDialog'\nimport {ResultView} from './ResultView'\nimport {SaveCsvButton, SaveJsonButton} from './SaveResultButtons'\nimport {\n DownloadsCard,\n InputBackgroundContainer,\n Result,\n ResultContainer,\n ResultFooter,\n ResultInnerContainer,\n ResultOuterContainer,\n SaveResultLabel,\n StyledLabel,\n TimingsCard,\n TimingsTextContainer,\n} from './VisionGui.styled'\n\ninterface VisionGuiResultProps {\n error?: Error | undefined\n apiVersion: string\n perspective: ClientPerspective | undefined\n variant: string | undefined\n queryInProgress: boolean\n queryResult?: unknown | undefined\n listenInProgress: boolean\n listenMutations: MutationEvent[]\n dataset: string\n queryTime: number | undefined\n e2eTime: number | undefined\n compactFooter?: boolean\n}\n\nexport function VisionGuiResult({\n error,\n apiVersion,\n perspective,\n variant,\n queryInProgress,\n queryResult,\n listenInProgress,\n listenMutations,\n dataset,\n queryTime,\n e2eTime,\n compactFooter = false,\n}: VisionGuiResultProps) {\n const {t} = useTranslation(visionLocaleNamespace)\n const hasResult = !error && !queryInProgress && typeof queryResult !== 'undefined'\n\n return (\n <ResultOuterContainer flexDirection=\"column\" data-testid=\"vision-result\">\n <ResultInnerContainer flexBasis=\"0%\" flexGrow={1}>\n <ResultContainer\n flex={1}\n overflow=\"hidden\"\n tone={error ? 'critical' : 'default'}\n isInvalid={Boolean(error)}\n >\n <Result overflow=\"auto\">\n <InputBackgroundContainer>\n <Box marginLeft={3}>\n <StyledLabel muted>{t('result.label')}</StyledLabel>\n </Box>\n </InputBackgroundContainer>\n <Box padding={3} paddingTop={5}>\n {(queryInProgress || (listenInProgress && listenMutations.length === 0)) && (\n <Box marginTop={3}>\n <DelayedSpinner />\n </Box>\n )}\n {error && (\n <QueryErrorDialog\n apiVersion={apiVersion}\n error={error}\n perspective={perspective}\n variant={variant}\n />\n )}\n {hasResult && <ResultView data={queryResult} datasetName={dataset} />}\n {listenInProgress && listenMutations.length > 0 && (\n <ResultView data={listenMutations} datasetName={dataset} />\n )}\n </Box>\n </Result>\n </ResultContainer>\n </ResultInnerContainer>\n {/* Execution time */}\n <ResultFooter\n justifyContent={compactFooter ? 'flex-start' : 'space-between'}\n alignItems={compactFooter ? 'stretch' : undefined}\n flexDirection={compactFooter ? 'column' : ['column', 'column', 'row']}\n >\n <TimingsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {minWidth: 0}}\n >\n <TimingsTextContainer alignItems=\"center\">\n <Box>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.execution-time-label')}:{' '}\n {typeof queryTime === 'number'\n ? `${queryTime}ms`\n : t('result.timing-not-applicable')}\n </Text>\n </Box>\n <Box marginLeft={compactFooter ? 3 : 4}>\n <Text muted size={compactFooter ? 1 : 2}>\n {t('result.end-to-end-time-label')}:{' '}\n {typeof e2eTime === 'number' ? `${e2eTime}ms` : t('result.timing-not-applicable')}\n </Text>\n </Box>\n </TimingsTextContainer>\n </TimingsCard>\n\n {hasResult && (\n <DownloadsCard\n paddingX={compactFooter ? 3 : 4}\n paddingY={compactFooter ? 2 : 3}\n sizing=\"border\"\n style={compactFooter ? {width: '100%'} : {marginLeft: 'auto', minWidth: 0}}\n >\n <SaveResultLabel muted size={compactFooter ? 1 : 2}>\n <Translate\n components={{SaveResultButtons}}\n componentProps={{queryResult}}\n i18nKey=\"result.save-result-as-format\"\n t={t}\n />\n </SaveResultLabel>\n </DownloadsCard>\n )}\n </ResultFooter>\n </ResultOuterContainer>\n )\n}\n\nfunction SaveResultButtons({queryResult}: {queryResult: unknown}) {\n // This only renders when `hasResult` is true, and falsy values like `null`, `0`, `false` or ''\n // are valid GROQ results — the resolvers themselves return `undefined` for non-encodable input.\n const jsonUrl = getJsonBlobUrl(queryResult)\n const csvUrl = getCsvBlobUrl(queryResult)\n\n return (\n <>\n <SaveJsonButton blobUrl={jsonUrl} />\n <SaveCsvButton blobUrl={csvUrl} />\n </>\n )\n}\n","import {SplitPane} from '@rexxars/react-split-pane'\nimport {\n type ClientPerspective,\n type ListenEvent,\n type MutationEvent,\n type ReleaseDocument,\n type StackablePerspective,\n} from '@sanity/client'\nimport {ChevronLeftIcon} from '@sanity/icons/ChevronLeft'\nimport {ChevronRightIcon} from '@sanity/icons/ChevronRight'\nimport {Button} from '@sanity/ui'\nimport {useToast} from '@sanity/ui/toast'\nimport {isHotkey} from 'is-hotkey-esm'\nimport {type ChangeEvent, useCallback, useEffect, useMemo, useRef, useState} from 'react'\nimport {\n getDefaultVariant,\n getReleaseIdFromReleaseDocumentId,\n isCardinalityOneRelease,\n type PerspectiveStack,\n sortReleases,\n useActiveReleases,\n useClient,\n usePerspective,\n useScheduledDraftsEnabled,\n useTranslation,\n useWorkspace,\n} from 'sanity'\nimport {Flex, Box} from 'ui5'\nimport {useEffectEvent} from 'use-effect-event'\n\nimport {API_VERSIONS, DEFAULT_API_VERSION, VARIANTS_API_VERSION} from '../apiVersions'\nimport {groqExtensions} from '../codemirror/extensions'\nimport {VisionCodeMirror, type VisionCodeMirrorHandle} from '../codemirror/VisionCodeMirror'\nimport {visionLocaleNamespace} from '../i18n'\nimport {\n getActivePerspective,\n getActiveVariant,\n isSupportedPerspective,\n isVirtualPerspective,\n type SupportedPerspective,\n} from '../perspectives'\nimport {type VisionProps} from '../types'\nimport {encodeQueryString} from '../util/encodeQueryString'\nimport {isVisionPasteTarget} from '../util/isVisionPasteTarget'\nimport {getLocalStorage} from '../util/localStorage'\nimport {parseApiQueryString, type ParsedApiQueryString} from '../util/parseApiQueryString'\nimport {SANITY_QUERY_URL} from '../util/parseQueryUrl'\nimport {prefixApiVersion} from '../util/prefixApiVersion'\nimport {validateApiVersion} from '../util/validateApiVersion'\nimport {ParamsEditor, parseParams} from './ParamsEditor'\nimport {QueryRecall} from './QueryRecall'\nimport {usePaneSize} from './usePaneSize'\nimport {\n InputBackgroundContainerLeft,\n InputContainer,\n QueryRecallPaneContainer,\n QueryRecallPaneWrapper,\n Root,\n SplitpaneContainer,\n StyledLabel,\n} from './VisionGui.styled'\nimport {VisionGuiControls} from './VisionGuiControls'\nimport {VisionGuiHeader} from './VisionGuiHeader'\nimport {VisionGuiResult} from './VisionGuiResult'\n\nfunction nodeContains(node: Node, other: EventTarget | Node | null): boolean {\n if (!node || !other) {\n return false\n }\n\n return node === other || !!(node.compareDocumentPosition(other as Node) & 16)\n}\n\nconst isRunHotkey = (event: KeyboardEvent) =>\n isHotkey('ctrl+enter', event) || isHotkey('mod+enter', event)\n\ninterface Subscription {\n unsubscribe: () => void\n}\nexport interface Params {\n raw: string\n parsed: Record<string, unknown> | undefined\n valid: boolean\n error: string | undefined\n}\n\ninterface QueryExecutionOptions {\n apiVersion?: string\n dataset?: string\n perspective?: SupportedPerspective | undefined\n query?: string\n params?: Record<string, unknown>\n}\n\ninterface VisionGuiProps extends VisionProps {\n datasets: string[]\n projectId: string | undefined\n defaultDataset: string\n /** Opens the redesigned Vision; only passed while `beta.redesign.enabled` offers it */\n onSwitchToRedesign?: () => void\n}\n\nexport interface ParsedUrlState {\n query: string\n params: Record<string, unknown>\n rawParams: string\n dataset: string\n apiVersion: string\n customApiVersion: string | false | undefined\n perspective: SupportedPerspective | undefined\n url: string\n}\n\nexport function VisionGui(props: VisionGuiProps) {\n const {datasets, config, projectId, defaultDataset, onSwitchToRedesign} = props\n const toast = useToast()\n const {t} = useTranslation(visionLocaleNamespace)\n const {perspectiveStack, selectedVariantNames} = usePerspective()\n const selectedVariantName = getDefaultVariant(selectedVariantNames)\n const isScheduledDraftsEnabled = useScheduledDraftsEnabled()\n const {data: releases = []} = useActiveReleases()\n const workspace = useWorkspace()\n const isDraftModelEnabled = workspace.document.drafts.enabled\n\n const editorQueryRef = useRef<VisionCodeMirrorHandle>(null)\n const editorParamsRef = useRef<VisionCodeMirrorHandle>(null)\n const visionRootRef = useRef<HTMLDivElement | null>(null)\n const customApiVersionElementRef = useRef<HTMLInputElement | null>(null)\n const querySubscriptionRef = useRef<Subscription | undefined>(undefined)\n const listenSubscriptionRef = useRef<Subscription | undefined>(undefined)\n\n const [localStorage] = useState(() => getLocalStorage(projectId || 'default'))\n\n const storedDataset = localStorage.get('dataset', defaultDataset)\n const storedApiVersion = localStorage.get(\n 'apiVersion',\n prefixApiVersion(`${config.defaultApiVersion}`),\n )\n const storedQuery = localStorage.get('query', '')\n const storedParams = localStorage.get('params', '{\\n \\n}')\n const storedPerspective = localStorage.get<SupportedPerspective | undefined>(\n 'perspective',\n undefined,\n )\n\n const [dataset, setDataset] = useState<string>(() => {\n if (datasets.includes(storedDataset)) {\n return storedDataset\n }\n if (datasets.includes(defaultDataset)) {\n return defaultDataset\n }\n return datasets[0]\n })\n const [perspective, setPerspectiveState] = useState<SupportedPerspective | undefined>(\n storedPerspective || 'raw',\n )\n const activeVariant = getActiveVariant(perspective, selectedVariantName)\n\n const [apiVersion, setApiVersion] = useState<string>(() =>\n activeVariant\n ? VARIANTS_API_VERSION\n : API_VERSIONS.includes(storedApiVersion)\n ? storedApiVersion\n : DEFAULT_API_VERSION,\n )\n const [customApiVersion, setCustomApiVersion] = useState<string | false>(() =>\n activeVariant || API_VERSIONS.includes(storedApiVersion) ? false : storedApiVersion,\n )\n const isValidApiVersion = customApiVersion ? validateApiVersion(customApiVersion) : true\n\n const [url, setUrl] = useState<string | undefined>(undefined)\n const [query, setQuery] = useState<string>(() =>\n typeof storedQuery === 'string' ? storedQuery : '',\n )\n const [rawParams, setRawParams] = useState<string>(storedParams)\n const params = useMemo(() => parseParams(rawParams, t), [rawParams, t])\n const [queryResult, setQueryResult] = useState<unknown | undefined>(undefined)\n const [listenMutations, setListenMutations] = useState<MutationEvent[]>([])\n const [error, setError] = useState<Error | undefined>(undefined)\n const [queryTime, setQueryTime] = useState<number | undefined>(undefined)\n const [e2eTime, setE2eTime] = useState<number | undefined>(undefined)\n const [queryInProgress, setQueryInProgress] = useState<boolean>(false)\n const [listenInProgress, setListenInProgress] = useState<boolean>(false)\n const [isQueryRecallCollapsed, setIsQueryRecallCollapsed] = useState(false)\n\n const {paneSizeOptions, isNarrowBreakpoint} = usePaneSize({visionRootRef})\n\n // Compute scheduled drafts perspective stack\n const scheduledDraftsStack = useMemo((): PerspectiveStack | undefined => {\n if (!isScheduledDraftsEnabled) return undefined\n\n const scheduledDraftReleases = releases.filter(\n (release: ReleaseDocument) =>\n isCardinalityOneRelease(release) && release.state === 'scheduled',\n )\n const sorted = sortReleases(scheduledDraftReleases)\n const releaseIds = sorted.map((release: ReleaseDocument) =>\n getReleaseIdFromReleaseDocumentId(release._id),\n )\n const defaultPerspective = isDraftModelEnabled ? ['drafts'] : ['published']\n return [...releaseIds, ...defaultPerspective] as PerspectiveStack\n }, [releases, isDraftModelEnabled, isScheduledDraftsEnabled])\n\n const userApiVersion = activeVariant\n ? VARIANTS_API_VERSION\n : isValidApiVersion && customApiVersion\n ? customApiVersion\n : apiVersion\n\n // Client with memoized initial value\n const _client = useClient({\n apiVersion: userApiVersion,\n })\n const client = useMemo(() => {\n return _client.withConfig({\n apiVersion: userApiVersion,\n perspective: getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n dataset,\n variant: activeVariant,\n allowReconfigure: true,\n })\n }, [\n perspectiveStack,\n scheduledDraftsStack,\n perspective,\n userApiVersion,\n dataset,\n _client,\n activeVariant,\n ])\n\n const cancelQuerySubscription = useCallback(() => {\n if (!querySubscriptionRef.current) {\n return\n }\n querySubscriptionRef.current.unsubscribe()\n querySubscriptionRef.current = undefined\n }, [])\n\n const cancelListenerSubscription = useCallback(() => {\n if (!listenSubscriptionRef.current) {\n return\n }\n listenSubscriptionRef.current.unsubscribe()\n listenSubscriptionRef.current = undefined\n }, [])\n\n const handleQueryExecution = useCallback(\n (options?: QueryExecutionOptions) => {\n if (queryInProgress) {\n cancelQuerySubscription()\n cancelListenerSubscription()\n setQueryInProgress(false)\n return\n }\n\n const visionPerspective =\n options && 'perspective' in options ? options.perspective : perspective\n const queryVariant = getActiveVariant(visionPerspective, selectedVariantName)\n\n const context: Required<Omit<QueryExecutionOptions, 'params' | 'perspective'>> & {\n params: Params\n perspective: ClientPerspective | undefined\n variant: string | undefined\n } = {\n query: options?.query || query,\n dataset: options?.dataset || dataset,\n params: parseParams(JSON.stringify(options?.params || params.parsed, null, 2), t),\n perspective: getActivePerspective({\n visionPerspective,\n perspectiveStack,\n scheduledDraftsStack,\n }),\n apiVersion:\n options?.apiVersion ||\n (queryVariant\n ? VARIANTS_API_VERSION\n : customApiVersion && isValidApiVersion\n ? customApiVersion\n : apiVersion),\n variant: queryVariant,\n }\n\n localStorage.set('query', context.query)\n localStorage.set('params', context.params.raw)\n\n cancelListenerSubscription()\n\n const hasQuery = context.query.trim().length > 0\n\n setQueryInProgress(!context.params.error && hasQuery)\n setListenInProgress(false)\n setListenMutations([])\n setError(context.params.error ? new Error(context.params.error) : undefined)\n setQueryResult(undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (context.params.error || !hasQuery) {\n return\n }\n\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective: context.perspective ?? [],\n ...(context.variant ? {variant: context.variant} : {}),\n }\n\n const ctxClient = client.withConfig({\n apiVersion: context.apiVersion,\n dataset: context.dataset,\n perspective: context.perspective,\n variant: context.variant,\n })\n\n const newUrl = ctxClient.getUrl(\n ctxClient.getDataUrl(\n 'query',\n encodeQueryString(context.query, context.params.parsed, urlQueryOpts),\n ),\n )\n setUrl(newUrl)\n\n const queryStart = Date.now()\n\n querySubscriptionRef.current = ctxClient.observable\n .fetch(context.query, context.params.parsed, {filterResponse: false, tag: 'vision'})\n .subscribe({\n next: (res) => {\n setQueryTime(res.ms)\n setE2eTime(Date.now() - queryStart)\n setQueryResult(res.result)\n setQueryInProgress(false)\n setError(undefined)\n },\n error: (err) => {\n setError(err)\n setQueryInProgress(false)\n },\n })\n },\n [\n queryInProgress,\n query,\n dataset,\n params.parsed,\n t,\n perspective,\n perspectiveStack,\n scheduledDraftsStack,\n selectedVariantName,\n customApiVersion,\n isValidApiVersion,\n apiVersion,\n localStorage,\n cancelListenerSubscription,\n client,\n cancelQuerySubscription,\n ],\n )\n\n const setPerspective = useCallback(\n (newPerspective: string | undefined): void => {\n if (newPerspective !== undefined && !isSupportedPerspective(newPerspective)) {\n return\n }\n\n setPerspectiveState(newPerspective)\n localStorage.set('perspective', newPerspective)\n\n handleQueryExecution({perspective: newPerspective})\n },\n [localStorage, handleQueryExecution, setPerspectiveState],\n )\n\n const handleChangeDataset = useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n const newDataset = evt.target.value\n localStorage.set('dataset', newDataset)\n setDataset(newDataset)\n handleQueryExecution({dataset: newDataset})\n },\n [localStorage, handleQueryExecution, setDataset],\n )\n\n const changeApiVersion = useCallback(\n (newApiVersion: string) => {\n if (newApiVersion.toLowerCase() === 'other') {\n setCustomApiVersion('v')\n customApiVersionElementRef.current?.focus()\n return\n }\n\n setApiVersion(newApiVersion)\n setCustomApiVersion(false)\n localStorage.set('apiVersion', newApiVersion)\n handleQueryExecution({apiVersion: newApiVersion})\n },\n [localStorage, handleQueryExecution],\n )\n\n const handleChangeApiVersion = useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n changeApiVersion(evt.target.value)\n },\n [changeApiVersion],\n )\n\n // Handle custom API version change\n const handleCustomApiVersionChange = useCallback(\n (evt: ChangeEvent<HTMLInputElement>) => {\n const newCustomApiVersion = evt.target.value || ''\n setCustomApiVersion(newCustomApiVersion || 'v')\n\n if (validateApiVersion(newCustomApiVersion)) {\n setApiVersion(newCustomApiVersion)\n localStorage.set('apiVersion', newCustomApiVersion)\n handleQueryExecution({apiVersion: newCustomApiVersion})\n }\n },\n [localStorage, handleQueryExecution],\n )\n\n // Handle perspective change\n const handleChangePerspective = useCallback(\n (evt: ChangeEvent<HTMLSelectElement>) => {\n const newPerspective = evt.target.value\n setPerspective(newPerspective === 'default' ? undefined : newPerspective)\n },\n [setPerspective],\n )\n\n const handleListenerEvent = useCallback((evt: ListenEvent<any>) => {\n if (evt.type !== 'mutation') {\n return\n }\n\n setListenMutations((prevMutations) =>\n prevMutations.length === 50 ? [evt, ...prevMutations.slice(0, 49)] : [evt, ...prevMutations],\n )\n }, [])\n const handleListenExecution = useCallback(() => {\n if (listenInProgress) {\n cancelListenerSubscription()\n setListenInProgress(false)\n return\n }\n\n const newUrl = client.getDataUrl('listen', encodeQueryString(query, params.parsed, {}))\n\n const shouldExecute = !params.error && query.trim().length > 0\n\n localStorage.set('query', query)\n localStorage.set('params', params.raw)\n\n cancelQuerySubscription()\n\n setUrl(newUrl)\n setListenMutations([])\n setQueryInProgress(false)\n setQueryResult(undefined)\n setListenInProgress(shouldExecute)\n setError(params.error ? new Error(params.error) : undefined)\n setQueryTime(undefined)\n setE2eTime(undefined)\n\n if (!shouldExecute) {\n return\n }\n\n listenSubscriptionRef.current = client\n .listen(query, params.parsed, {events: ['mutation', 'welcome'], includeAllVersions: true})\n .subscribe({\n next: handleListenerEvent,\n error: (err) => {\n setError(err)\n setListenInProgress(false)\n },\n })\n }, [\n listenInProgress,\n params,\n query,\n localStorage,\n cancelQuerySubscription,\n handleListenerEvent,\n cancelListenerSubscription,\n client,\n ])\n\n const handleParamsChange = useCallback(\n (value: string) => {\n setRawParams(value)\n localStorage.set('params', value)\n },\n [localStorage],\n )\n\n // Get object of state values from provided URL\n const getStateFromUrl = useCallback(\n (data: string): ParsedUrlState | null => {\n const match = data.match(SANITY_QUERY_URL)\n if (!match) {\n return null\n }\n\n const [, usedApiVersion, usedDataset, urlQuery] = match\n\n const qs = new URLSearchParams(urlQuery)\n const parts: ParsedApiQueryString = parseApiQueryString(qs)\n if (!parts) return null\n let newApiVersion: string | undefined\n let newCustomApiVersion: string | false | undefined\n\n if (validateApiVersion(usedApiVersion)) {\n if (API_VERSIONS.includes(usedApiVersion)) {\n newApiVersion = usedApiVersion\n newCustomApiVersion = false\n } else {\n newCustomApiVersion = usedApiVersion\n }\n }\n\n const newPerspective =\n isSupportedPerspective(parts.options.perspective) &&\n !isVirtualPerspective(parts.options.perspective)\n ? parts.options.perspective\n : undefined\n\n if (\n newPerspective &&\n (!isSupportedPerspective(parts.options.perspective) ||\n isVirtualPerspective(parts.options.perspective))\n ) {\n toast.push({\n closable: true,\n id: 'vision-paste-unsupported-perspective',\n status: 'warning',\n title: 'Perspective in pasted url is currently not supported. Falling back to \"raw\"',\n })\n }\n\n return {\n query: parts.query,\n params: parts.params,\n rawParams: JSON.stringify(parts.params, null, 2),\n dataset: datasets.includes(usedDataset) ? usedDataset : dataset,\n apiVersion: newApiVersion || apiVersion,\n customApiVersion: newCustomApiVersion,\n perspective: newPerspective || perspective,\n url: data,\n }\n },\n [datasets, dataset, apiVersion, perspective, toast],\n )\n\n // Use state object from parsed URL to update state\n const setStateFromParsedUrl = useCallback(\n (parsedUrlObj: ParsedUrlState) => {\n // Update state with pasted values\n setDataset(parsedUrlObj.dataset)\n setQuery(parsedUrlObj.query)\n setRawParams(parsedUrlObj.rawParams)\n setApiVersion(parsedUrlObj.apiVersion)\n if (parsedUrlObj.customApiVersion) {\n setCustomApiVersion(parsedUrlObj.customApiVersion)\n }\n setPerspectiveState(parsedUrlObj.perspective)\n setUrl(parsedUrlObj.url)\n // Update the codemirror editor content\n editorQueryRef.current?.resetEditorContent(parsedUrlObj.query)\n editorParamsRef.current?.resetEditorContent(parsedUrlObj.rawParams)\n\n // Update localStorage and client config\n localStorage.merge({\n query: parsedUrlObj.query,\n params: parsedUrlObj.rawParams,\n dataset: parsedUrlObj.dataset,\n apiVersion: parsedUrlObj.customApiVersion || parsedUrlObj.apiVersion,\n perspective: parsedUrlObj.perspective,\n })\n\n // Execute query with new values\n handleQueryExecution(parsedUrlObj)\n },\n [localStorage, handleQueryExecution, setDataset, setPerspectiveState],\n )\n\n const handlePaste = useCallback(\n (evt: ClipboardEvent) => {\n if (!evt.clipboardData || !isVisionPasteTarget(visionRootRef.current, evt)) {\n return\n }\n\n const urlState = getStateFromUrl(evt.clipboardData.getData('text/plain'))\n if (!urlState) {\n return\n }\n\n // Only cancel the native paste once the clipboard is known to hold a query URL Vision can\n // load, so unrelated content still pastes as usual.\n evt.preventDefault()\n setStateFromParsedUrl(urlState)\n toast.push({\n closable: true,\n id: 'vision-paste',\n status: 'info',\n title: 'Parsed URL to query',\n })\n },\n [getStateFromUrl, setStateFromParsedUrl, toast],\n )\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n const isWithinRoot =\n visionRootRef.current && nodeContains(visionRootRef.current, event.target)\n if (isRunHotkey(event) && isWithinRoot && params.valid) {\n handleQueryExecution()\n event.preventDefault()\n event.stopPropagation()\n }\n },\n [params.valid, handleQueryExecution],\n )\n\n useEffect(() => {\n window.document.addEventListener('paste', handlePaste)\n window.document.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.document.removeEventListener('paste', handlePaste)\n window.document.removeEventListener('keydown', handleKeyDown)\n }\n }, [handleKeyDown, handlePaste])\n\n useEffect(() => {\n return () => {\n cancelQuerySubscription()\n cancelListenerSubscription()\n }\n }, [cancelQuerySubscription, cancelListenerSubscription])\n\n const handleStudioVariantChange = useEffectEvent(() => {\n if (perspective !== 'pinnedRelease') {\n return\n }\n // changeApiVersion already re-runs the query with vX.\n changeApiVersion(VARIANTS_API_VERSION)\n })\n\n useEffect(() => {\n if (!activeVariant) {\n return\n }\n handleStudioVariantChange()\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- pre-existing violation, to be fixed in a follow-up\n }, [activeVariant])\n\n const handleStudioPerspectiveChange = useEffectEvent((stack: StackablePerspective[]) => {\n if (stack.length > 0) {\n setPerspective('pinnedRelease')\n }\n })\n // Handle pinned perspective changes\n useEffect(() => {\n handleStudioPerspectiveChange(perspectiveStack)\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- pre-existing violation, to be fixed in a follow-up\n }, [perspectiveStack])\n\n const generateUrl = useCallback(\n (queryString: string, queryParams: Record<string, unknown>) => {\n const urlQueryOpts: Record<string, string | string[]> = {\n perspective:\n getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n }) ?? [],\n ...(activeVariant ? {variant: activeVariant} : {}),\n }\n return client.getUrl(\n client.getDataUrl('query', encodeQueryString(queryString, queryParams, urlQueryOpts)),\n )\n },\n [activeVariant, client, perspective, perspectiveStack, scheduledDraftsStack],\n )\n\n return (\n <Root\n flexDirection=\"column\"\n height=\"100%\"\n ref={visionRootRef}\n overflow=\"hidden\"\n data-testid=\"vision-root\"\n >\n <VisionGuiHeader\n apiVersion={activeVariant ? VARIANTS_API_VERSION : apiVersion}\n customApiVersion={activeVariant ? false : customApiVersion}\n dataset={dataset}\n datasets={datasets}\n onChangeDataset={handleChangeDataset}\n onChangeApiVersion={handleChangeApiVersion}\n customApiVersionElementRef={customApiVersionElementRef}\n onCustomApiVersionChange={handleCustomApiVersionChange}\n isValidApiVersion={isValidApiVersion}\n onChangePerspective={handleChangePerspective}\n url={url}\n perspective={perspective}\n isScheduledDraftsEnabled={isScheduledDraftsEnabled}\n />\n\n <SplitpaneContainer flexBasis=\"auto\" flexGrow={1} flexShrink={1}>\n <SplitPane\n minSize={800}\n defaultSize={window.innerWidth - 275}\n size={isQueryRecallCollapsed ? window.innerWidth : window.innerWidth - 275}\n maxSize={-225}\n primary=\"first\"\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n // oxlint-disable-next-line @sanity/i18n/no-attribute-string-literals\n split={isNarrowBreakpoint ? 'vertical' : 'horizontal'}\n minSize={300}\n >\n <Box height=\"stretch\" flexBasis=\"0%\" flexGrow={1}>\n <SplitPane\n className=\"sidebarPanes\"\n split=\"horizontal\"\n defaultSize={\n isNarrowBreakpoint ? paneSizeOptions.defaultSize : paneSizeOptions.minSize\n }\n size={paneSizeOptions.size}\n allowResize={paneSizeOptions.allowResize}\n minSize={isNarrowBreakpoint ? paneSizeOptions.minSize : 100}\n maxSize={paneSizeOptions.maxSize}\n primary=\"first\"\n >\n <InputContainer display=\"flex\" data-testid=\"vision-query-editor\">\n <Box flexBasis=\"0%\" flexGrow={1}>\n <InputBackgroundContainerLeft>\n <Flex>\n <StyledLabel muted>{t('query.label')}</StyledLabel>\n </Flex>\n </InputBackgroundContainerLeft>\n <VisionCodeMirror\n initialValue={query}\n onChange={setQuery}\n ref={editorQueryRef}\n extensions={groqExtensions}\n />\n </Box>\n </InputContainer>\n <InputContainer display=\"flex\">\n <ParamsEditor\n value={params.raw}\n onChange={handleParamsChange}\n paramsError={params.error}\n hasValidParams={params.valid}\n editorRef={editorParamsRef}\n />\n\n <VisionGuiControls\n hasValidParams={params.valid}\n queryInProgress={queryInProgress}\n listenInProgress={listenInProgress}\n onQueryExecution={handleQueryExecution}\n onListenExecution={handleListenExecution}\n onSwitchToRedesign={onSwitchToRedesign}\n />\n </InputContainer>\n </SplitPane>\n </Box>\n <VisionGuiResult\n error={error}\n apiVersion={userApiVersion}\n perspective={getActivePerspective({\n visionPerspective: perspective,\n perspectiveStack,\n scheduledDraftsStack,\n })}\n variant={activeVariant}\n queryInProgress={queryInProgress}\n queryResult={queryResult}\n listenInProgress={listenInProgress}\n listenMutations={listenMutations}\n dataset={dataset}\n queryTime={queryTime}\n e2eTime={e2eTime}\n />\n </SplitPane>\n </Box>\n <QueryRecallPaneContainer>\n <Button\n mode=\"ghost\"\n padding={2}\n style={{\n position: 'absolute',\n left: -32,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 100,\n pointerEvents: 'auto',\n }}\n onClick={() => setIsQueryRecallCollapsed(!isQueryRecallCollapsed)}\n >\n <div style={{display: 'flex', alignItems: 'center', height: '100%'}}>\n {isQueryRecallCollapsed ? <ChevronLeftIcon /> : <ChevronRightIcon />}\n </div>\n </Button>\n <QueryRecallPaneWrapper>\n <QueryRecall\n url={url}\n getStateFromUrl={getStateFromUrl}\n setStateFromParsedUrl={setStateFromParsedUrl}\n currentQuery={query}\n currentParams={params.parsed || {}}\n generateUrl={generateUrl}\n />\n </QueryRecallPaneWrapper>\n </QueryRecallPaneContainer>\n </SplitPane>\n </SplitpaneContainer>\n </Root>\n )\n}\n","import {type SanityClient} from '@sanity/client'\nimport {useMemo} from 'react'\nimport {type ObservablePromise, useObservablePromise} from 'react-rx'\nimport {catchError, map, type Observable, of} from 'rxjs'\n\nimport {type VisionConfig} from '../types'\n\nexport function useDatasets({\n client,\n datasets: configDatasets,\n}: {\n client: SanityClient\n datasets: VisionConfig['datasets']\n}): ObservablePromise<string[] | Error> {\n const datasets$: Observable<string[] | Error> = useMemo(() => {\n if (Array.isArray(configDatasets)) {\n return of(configDatasets)\n }\n return client.observable.datasets.list().pipe(\n map((result) => {\n if (typeof configDatasets == 'function') {\n return configDatasets(result).map((d) => d.name)\n }\n return result.map((ds) => ds.name)\n }),\n catchError((err) => of(err)),\n )\n }, [client, configDatasets])\n\n return useObservablePromise(datasets$)\n}\n","import {Fragment, type ReactNode, Suspense, use} from 'react'\nimport {type ObservablePromise} from 'react-rx'\nimport {useClient} from 'sanity'\nimport {Flex} from 'ui5'\n\nimport {DelayedSpinner} from '../components/DelayedSpinner'\nimport {useDatasets} from '../hooks/useDatasets'\nimport {type VisionProps} from '../types'\n\n/** What both Vision experiences need to know about the project before they can render */\nexport interface LoadedVisionProps {\n datasets: string[]\n projectId: string\n defaultDataset: string\n}\n\nexport interface VisionContainerProps extends VisionProps {\n /** Rendered once the datasets are known, and remounted when the project changes */\n children: (loaded: LoadedVisionProps) => ReactNode\n}\n\nexport function VisionContainer(props: VisionContainerProps) {\n const datasetsClient = useClient({apiVersion: 'v2025-06-27'})\n const datasetsPromise = useDatasets({client: datasetsClient, datasets: props.config.datasets})\n\n return (\n <Suspense\n fallback={\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <DelayedSpinner />\n </Flex>\n }\n >\n <LoadedVisionContainer {...props} datasetsPromise={datasetsPromise} />\n </Suspense>\n )\n}\n\nfunction LoadedVisionContainer({\n children,\n client,\n config,\n datasetsPromise,\n}: VisionContainerProps & {datasetsPromise: ObservablePromise<string[] | Error>}) {\n const loadedDatasets = use(datasetsPromise)\n const clientConfig = client.config()\n\n const datasets =\n loadedDatasets instanceof Error\n ? // On error, use the clients configured dataset\n [clientConfig.dataset || 'production']\n : // Otherwise use the loaded list, obviously\n loadedDatasets\n\n const projectId = clientConfig.projectId || 'default'\n const defaultDataset = config.defaultDataset || clientConfig.dataset || datasets[0]\n\n return <Fragment key={projectId}>{children({datasets, projectId, defaultDataset})}</Fragment>\n}\n","/* oxlint-disable @sanity/i18n/no-attribute-string-literals */\n/* oxlint-disable i18next/no-literal-string */\nimport {Button, Card, Heading} from '@sanity/ui'\nimport {Code} from '@sanity/ui/code'\nimport {Component, type PropsWithChildren} from 'react'\nimport {Container, VStack} from 'ui5'\n\nimport {clearLocalStorage} from '../util/localStorage'\n\n/**\n * @internal\n */\nexport type VisionErrorBoundaryProps = PropsWithChildren<{\n /** Called before the children are rendered again, so a failed lazy import gets another try */\n onRetry?: () => void\n}>\n\n/**\n * @internal\n */\ninterface VisionErrorBoundaryState {\n error: string | null\n numRetries: number\n}\n\n/**\n * @internal\n */\nexport class VisionErrorBoundary extends Component<\n VisionErrorBoundaryProps,\n VisionErrorBoundaryState\n> {\n constructor(props: VisionErrorBoundaryProps) {\n super(props)\n this.state = {error: null, numRetries: 0}\n }\n\n static getDerivedStateFromError(error: unknown) {\n // oxlint-disable-next-line restrict-template-expressions - @TODO use new Error(msg, {cause: error}) instead of casting to string, and console.error() the full error\n return {error: error instanceof Error ? error.message : `${error}`}\n }\n\n handleRetryRender = () => {\n this.props.onRetry?.()\n this.setState((prev) => ({error: null, numRetries: prev.numRetries + 1}))\n }\n\n handleRetryWithCacheClear = () => {\n clearLocalStorage()\n this.handleRetryRender()\n }\n\n render() {\n if (!this.state.error) {\n return this.props.children\n }\n\n const message = this.state.error\n const withCacheClear = this.state.numRetries > 0\n\n return (\n <Card\n height=\"fill\"\n overflow=\"auto\"\n paddingY={[4, 5, 6, 7]}\n paddingX={4}\n sizing=\"border\"\n tone=\"critical\"\n >\n <Container size={3}>\n <VStack gap={4}>\n <div>\n <Button\n onClick={withCacheClear ? this.handleRetryWithCacheClear : this.handleRetryRender}\n text={withCacheClear ? 'Clear cache and retry' : 'Retry'}\n tone=\"default\"\n />\n </div>\n\n <Heading>An error occurred</Heading>\n\n <Card border radius={2} overflow=\"auto\" padding={4} tone=\"inherit\">\n <VStack gap={4}>\n {message && (\n <Code size={1}>\n <strong>Error: {message}</strong>\n </Code>\n )}\n </VStack>\n </Card>\n </VStack>\n </Container>\n </Card>\n )\n }\n}\n","import {type ComponentType, lazy} from 'react'\n\n/**\n * A `lazy()` component whose failed import can be tried again. React keeps a rejected `lazy()`\n * for good, so `retry` (for the error boundary's Retry) swaps in a fresh one. The rejected one\n * stays until then: swapped as soon as the import fails, the Suspense boundary's next render\n * would start another import instead of surfacing the error, so a chunk that keeps failing\n * would be fetched over and over and never reach the error boundary.\n */\nexport function createRetryableLazy<Props extends object>(\n load: () => Promise<{default: ComponentType<Props>}>,\n): {Component: ComponentType<Props>; retry: () => void} {\n let failed = false\n const attempt = () =>\n load().catch((error: unknown) => {\n failed = true\n throw error\n })\n // Capitalized and rendered as it is: the React Compiler inlines a capitalized alias of a\n // lowercase variable back to that variable, which JSX then takes for an HTML element\n let LazyComponent = lazy(attempt)\n\n // A component of its own, so the lazy component is read at render time rather than captured\n function RetryableLazy(props: Props) {\n return <LazyComponent {...props} />\n }\n\n return {\n Component: RetryableLazy,\n retry: () => {\n if (!failed) return\n failed = false\n LazyComponent = lazy(attempt)\n },\n }\n}\n","import {Button, Stack, Text} from '@sanity/ui'\nimport {useToast} from '@sanity/ui/toast'\nimport {useEffect} from 'react'\nimport {useTranslation} from 'sanity'\nimport {Flex} from 'ui5'\nimport {useEffectEvent} from 'use-effect-event'\n\nimport {visionLocaleNamespace} from '../../i18n'\n\nconst TOAST_ID = 'vision-redesign-invitation'\n\ninterface RedesignToastActionsProps {\n description: string\n acceptLabel: string\n dismissLabel: string\n onAccept: () => void\n onDismiss: () => void\n}\n\n/**\n * The toast's body. It renders in the studio's toast layer, which can sit outside the locale\n * provider that has Vision's strings, so it is handed them translated\n */\nfunction RedesignToastActions(props: RedesignToastActionsProps) {\n const {description, acceptLabel, dismissLabel, onAccept, onDismiss} = props\n return (\n <Stack gap={3} paddingTop={1}>\n <Text size={1}>{description}</Text>\n <Flex gap={2}>\n <Button\n data-testid=\"vision-redesign-accept\"\n fontSize={1}\n onClick={onAccept}\n padding={2}\n text={acceptLabel}\n tone=\"primary\"\n />\n <Button\n data-testid=\"vision-redesign-dismiss\"\n fontSize={1}\n mode=\"bleed\"\n onClick={onDismiss}\n padding={2}\n text={dismissLabel}\n />\n </Flex>\n </Stack>\n )\n}\n\nexport interface RedesignToastProps {\n onAccept: () => void\n onDismiss: () => void\n}\n\n/**\n * Invites the user to try the redesigned Vision. Renders nothing itself: it pushes a persistent\n * toast while mounted and removes it again on unmount, so it disappears as soon as the user opts\n * in or leaves the tool.\n */\nexport function RedesignToast({onAccept, onDismiss}: RedesignToastProps) {\n const toast = useToast()\n const {t} = useTranslation(visionLocaleNamespace)\n const accept = useEffectEvent(onAccept)\n const dismiss = useEffectEvent(onDismiss)\n\n useEffect(() => {\n // `@sanity/ui` toasts auto-dismiss unless the duration is infinite, and the provider does not\n // forward `onClose`, so the toast carries its own accept and dismiss buttons instead of an X\n const remove = () => {\n toast.push({id: TOAST_ID, duration: 0.01})\n }\n toast.push({\n id: TOAST_ID,\n closable: false,\n duration: Infinity,\n status: 'info',\n title: t('vista.redesign.toast.title'),\n description: (\n <RedesignToastActions\n acceptLabel={t('vista.redesign.toast.accept')}\n description={t('vista.redesign.toast.description')}\n dismissLabel={t('vista.redesign.toast.dismiss')}\n onAccept={() => {\n remove()\n accept()\n }}\n onDismiss={() => {\n remove()\n dismiss()\n }}\n />\n ),\n })\n return remove\n // oxlint-disable-next-line react/exhaustive-effect-dependencies -- useEffectEvent callbacks must not be listed\n }, [t, toast])\n\n return null\n}\n","import {useSyncExternalStore} from 'react'\n\nimport {isPlainObject} from '../util/isPlainObject'\nimport {getStorage, onLocalStorageCleared, VISION_STORAGE_KEY_PREFIX} from '../util/localStorage'\n\n/**\n * Whether a user chose the redesigned Vision experience for a project, and whether they dismissed\n * the invitation toast. Stored in `localStorage`, so the choice is per browser and per project.\n */\nexport interface RedesignPreference {\n optedIn: boolean\n dismissed: boolean\n}\n\nconst DEFAULT_PREFERENCE: RedesignPreference = {optedIn: false, dismissed: false}\n\n/**\n * Storage is the source of truth (so \"Clear cache and retry\" in the error boundary is honoured);\n * the parsed object is cached per raw string only to keep `useSyncExternalStore` snapshots stable.\n */\nconst cache = new Map<string, {raw: string | null; preference: RedesignPreference}>()\nconst listeners = new Set<() => void>()\n\nfunction storageKey(projectId: string): string {\n return `${VISION_STORAGE_KEY_PREFIX}redesign:${projectId}`\n}\n\nfunction notify(): void {\n listeners.forEach((listener) => listener())\n}\n\nfunction subscribe(listener: () => void): () => void {\n listeners.add(listener)\n // \"Clear cache\" must also forget in-memory choices, which is all there is without storage\n const unsubscribeClear = onLocalStorageCleared(() => {\n cache.clear()\n listener()\n })\n return () => {\n listeners.delete(listener)\n unsubscribeClear()\n }\n}\n\nfunction parsePreference(raw: string | null): RedesignPreference {\n if (raw === null) {\n return DEFAULT_PREFERENCE\n }\n try {\n const stored: unknown = JSON.parse(raw)\n return isPlainObject(stored)\n ? {optedIn: stored.optedIn === true, dismissed: stored.dismissed === true}\n : DEFAULT_PREFERENCE\n } catch {\n return DEFAULT_PREFERENCE\n }\n}\n\nexport function readRedesignPreference(projectId: string): RedesignPreference {\n const storage = getStorage()\n const cached = cache.get(projectId)\n if (!storage) {\n // Without storage the in-memory choice is all there is\n return cached?.preference ?? DEFAULT_PREFERENCE\n }\n const raw = storage.getItem(storageKey(projectId))\n if (cached && cached.raw === raw) {\n return cached.preference\n }\n const preference = parsePreference(raw)\n cache.set(projectId, {raw, preference})\n return preference\n}\n\nexport function writeRedesignPreference(\n projectId: string,\n patch: Partial<RedesignPreference>,\n): RedesignPreference {\n const next = {...readRedesignPreference(projectId), ...patch}\n const storage = getStorage()\n let raw: string | null = JSON.stringify(next)\n try {\n storage?.setItem(storageKey(projectId), raw)\n } catch {\n // Quota exceeded: the choice still applies for this session, keyed on what storage holds\n raw = storage?.getItem(storageKey(projectId)) ?? null\n }\n cache.set(projectId, {raw, preference: next})\n notify()\n return next\n}\n\n/** Forgets both the opt-in and the dismissal, so the classic tool offers the redesign again */\nexport function clearRedesignPreference(projectId: string): void {\n getStorage()?.removeItem(storageKey(projectId))\n cache.delete(projectId)\n notify()\n}\n\nexport function useRedesignPreference(projectId: string): RedesignPreference {\n return useSyncExternalStore(\n subscribe,\n () => readRedesignPreference(projectId),\n () => DEFAULT_PREFERENCE,\n )\n}\n","import {type ComponentProps, useCallback} from 'react'\nimport {type Tool, useClient} from 'sanity'\n\nimport {DEFAULT_API_VERSION} from './apiVersions'\nimport {VisionGui} from './components/VisionGui'\nimport {VisionContainer} from './containers/VisionContainer'\nimport {VisionErrorBoundary} from './containers/VisionErrorBoundary'\nimport {type VisionConfig} from './types'\nimport {createRetryableLazy} from './util/createRetryableLazy'\nimport {RedesignToast} from './vista/components/RedesignToast'\nimport {type VistaGui} from './vista/components/VistaGui'\nimport {useRedesignPreference, writeRedesignPreference} from './vista/redesignPreference'\n\n// The redesign (XState, groq-js type evaluation, its own UI) only loads once someone opts in,\n// and a failed load can be retried from the error boundary\nconst vistaGui = createRetryableLazy<ComponentProps<typeof VistaGui>>(() =>\n import('./vista/components/VistaGui').then((module) => ({default: module.VistaGui})),\n)\nconst VistaGuiLoader = vistaGui.Component\n\ninterface SanityVisionProps {\n tool: Tool<VisionConfig>\n}\n\nfunction SanityVision(props: SanityVisionProps) {\n const client = useClient({apiVersion: '1'})\n const config: VisionConfig = {\n defaultApiVersion: DEFAULT_API_VERSION,\n ...props.tool.options,\n }\n const projectId = client.config().projectId || 'default'\n const redesignEnabled = config.beta?.redesign?.enabled === true\n const preference = useRedesignPreference(projectId)\n const showRedesign = redesignEnabled && preference.optedIn\n\n const optIn = useCallback(\n () => writeRedesignPreference(projectId, {optedIn: true, dismissed: false}),\n [projectId],\n )\n const dismiss = useCallback(\n () => writeRedesignPreference(projectId, {dismissed: true}),\n [projectId],\n )\n const switchToClassic = useCallback(\n () => writeRedesignPreference(projectId, {optedIn: false, dismissed: false}),\n [projectId],\n )\n\n return (\n <VisionErrorBoundary onRetry={vistaGui.retry}>\n <VisionContainer client={client} config={config}>\n {(loaded) =>\n showRedesign ? (\n <VistaGuiLoader {...loaded} config={config} onSwitchToClassic={switchToClassic} />\n ) : (\n <VisionGui\n {...loaded}\n client={client}\n config={config}\n onSwitchToRedesign={redesignEnabled ? optIn : undefined}\n />\n )\n }\n </VisionContainer>\n {redesignEnabled && !showRedesign && !preference.dismissed && (\n <RedesignToast onAccept={optIn} onDismiss={dismiss} />\n )}\n </VisionErrorBoundary>\n )\n}\n\nexport default SanityVision\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAgB,iBAAiB,SAAyB;CAKxD,OAJI,QAAQ,OAAO,OAAO,YAAY,UAC7B,IAAI,YAGN;AACT;ACFA,MAAa,eAAe;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA,qBAAI,IAAI,KAAK,EAAA,CAAE,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AAC1C,GACa,CAAC,uBAAuB,aAAa,MAAM,EAAE,GAG7C,uBAAuB,iBAAiB,+BAA+B,UAAU,GCOxF,mBAAgC;CACpC,YAAY;CACZ,oBAAoB;CACpB,0BAA0B;CAC1B,0BAA0B;CAC1B,sBAAsB;CACtB,cAAc;CACd,gBAAgB;CAChB,cAAc;CACd,QAAQ;CACR,cAAc;CACd,mBAAmB,uBAAuB,EAAC,UAAU,GAAI,CAAC;CAC1D,OAAO,GAAG;EAER;GAAC,KAAK;GAAa,WAAW;EAAI;EAGlC,GAAG;EACH,GAAG;CACL,CAAqC;AACvC,GAEa,iBAA8B,CAAC,KAAK,GAAG,GAAG,gBAAgB,GAE1D,mBAAgC,CAAC,oBAAoB,GAAG,gBAAgB,GAGxE,uBAAoC;CAC/C;CACA,GAAG;CACH,WAAW;CACX,YAAY,SAAS,GAAG,EAAI;AAC9B;AC5CA,SAAgB,mBAAmB,OAA2B;C,cAC9BA;CAAY,AAAA,EAAA,OAAA,Q,aAAZ,KAAA,YAAY,KAAK,GAAL,EAAA,KAAA,O;CAA1C,IAAM,UAAUC,IACkBC;CAAmC,AAAA,EAAA,OAAA,Q,aAAnC,KAAA,mBAAmB,gBAAgB,KAAK,CAAC,GAAN,EAAA,KAAA,O;CAArE,IAAM,cAAcC,IAEbC;CAAP,OAAiB,EAAA,OAAA,eAAA,EAAA,OAAT,WAAD,KAAA,CAAC,SAAS,WAAW,GAAX,EAAA,KAAA,aAAT,EAAA,KAAA,S,wBAADA;AACT;AAGA,SAAS,YAAY,OAAc;CAEjC,IAAM,EAAC,OAAO,UAAS,MAAM,QACvB,OAAO,MAAM,KAAK,SAClB,SAAS,KAAK,KAAK,MAAM,OAAO,MAAM,IAAI,CAAC,KAE3C,YAAY,KAAK,KAAK,MAAM,OAAO,MAAM,OAAO,MAAM,IAAI,CAAC;CAEjE,OAAO,WAAW,MAChB;EACE,KAAK;GACH,OAAO,KAAK;GACZ,iBAAiB,KAAK;EACxB;EAEA,eAAe,EACb,YAAY,OACd;EAEA,cAAc;GACZ,YAAY,MAAM,KAAK;GACvB,UAAU,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC,QAAQ;GAC1C,YAAY;EACd;EAEA,8BAA8B,EAAC,iBAAiB,OAAM;EACtD,0FAA0F,EACxF,iBAAiB,UACnB;EAEA,cAAc;GAAC,iBAAiB,KAAK;GAAI,OAAO,KAAK;EAAE;EACvD,4BAA4B,EAAC,cAAc,aAAa,KAAK,SAAQ;EACrE,+BAA+B,EAAC,WAAW,aAAa,KAAK,SAAQ;EAGrE,eAAe;GACb,iBAAiB,KAAK;GACtB,OAAO,KAAK;GACZ,QAAQ,aAAa,KAAK;GAC1B,cAAc;EAChB;EAGA,oBAAoB;GAAC,YAAY,MAAM,KAAK;GAAQ,UAAU;EAAO;EACrE,8CAA8C,EAAC,iBAAiB,UAAS;EACzE,6DAA6D,EAAC,OAAO,KAAK,GAAE;EAG5E,oDAAoD;GAClD,YAAY,MAAM,KAAK;GACvB,UAAU,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC,QAAQ;EAC5C;EACA,wDAAwD;GACtD,YAAY,MAAM,KAAK;GACvB,UAAU,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC,QAAQ;EAC5C;EACA,2BAA2B,EAAC,OAAO,KAAK,MAAM,GAAE;EAChD,2BAA2B,EAAC,OAAO,KAAK,KAAK,GAAE;EAC/C,0EAA0E,EACxE,iBAAiB,UACnB;EACA,4CAA4C,EAAC,YAAY,MAAM,KAAK,OAAM;EAC1E,gEAAgE;GAC9D,iBAAiB;GACjB,OAAO,KAAK;EACd;EACA,wBAAwB;GAAC,OAAO,KAAK,MAAM;GAAI,WAAW;GAAU,YAAY;EAAK;CACvF,GACA,EAAC,MAAM,MAAM,KAAI,CACnB;AACF;AAGA,SAAS,gBAAgB,OAAc;CAErC,IAAM,IAAI,MAAM,OAAO,MAAM,MAEvB,IAAI,MAAM,OAAO,MAAM;CAC7B,OAAO,eAAe,OAAO;EAC3B;GAAC,KAAKE,KAAE;GAAS,OAAO,EAAE;EAAO;EACjC;GAAC,KAAK;IAACA,KAAE;IAAcA,KAAE;IAAMA,KAAE;IAASA,KAAE;IAAWA,KAAE;GAAS;GAAG,OAAO,EAAE;EAAQ;EACtF;GAAC,KAAK,CAACA,KAAE,SAASA,KAAE,YAAY,GAAGA,KAAE,SAAS;GAAG,OAAO,EAAE;EAAQ;EAClE;GAAC,KAAK;IAACA,KAAE;IAAOA,KAAE,SAASA,KAAE,IAAI;IAAGA,KAAE,SAASA,KAAE,IAAI;GAAC;GAAG,OAAO,EAAE;EAAQ;EAC1E;GAAC,KAAK,CAACA,KAAE,WAAWA,KAAE,IAAI,GAAGA,KAAE,SAAS;GAAG,OAAO,EAAE;EAAQ;EAC5D;GACE,KAAK;IACHA,KAAE;IACFA,KAAE;IACFA,KAAE;IACFA,KAAE;IACFA,KAAE;IACFA,KAAE;IACFA,KAAE;IACFA,KAAE;GACJ;GACA,OAAO,EAAE;EACX;EACA;GACE,KAAK;IAACA,KAAE;IAAUA,KAAE;IAAiBA,KAAE;IAAKA,KAAE;IAAQA,KAAE;IAAQA,KAAE;IAAMA,KAAE,QAAQA,KAAE,MAAM;GAAC;GAC3F,OAAO,EAAE;EACX;EACA;GAAC,KAAK,CAACA,KAAE,MAAMA,KAAE,OAAO;GAAG,OAAO,EAAE;EAAO;EAC3C;GAAC,KAAKA,KAAE;GAAQ,YAAY;EAAM;EAClC;GAAC,KAAKA,KAAE;GAAU,WAAW;EAAQ;EACrC;GAAC,KAAKA,KAAE;GAAe,gBAAgB;EAAc;EACrD;GAAC,KAAKA,KAAE;GAAS,YAAY;GAAQ,OAAO,EAAE;EAAQ;EACtD;GAAC,KAAK;IAACA,KAAE;IAAMA,KAAE;IAAMA,KAAE,QAAQA,KAAE,YAAY;GAAC;GAAG,OAAO,EAAE;EAAO;EACnE;GAAC,KAAK;IAACA,KAAE;IAAuBA,KAAE;IAAQA,KAAE;GAAQ;GAAG,OAAO,EAAE;EAAM;EACtE;GAAC,KAAKA,KAAE;GAAS,OAAO,EAAE;EAAE;CAC9B,CAAC;AACH;AC9GA,SAAS,OAAO,SAAkB,OAAiE;CACjG,IAAM,QAAQ,iBAAiB,OAAO,GAClC,QAAQ;CACZ,KAAK,IAAM,QAAQ,OACjB,UACG,WAAW,MAAM,UAAU,OAAO,KAAK,MAAM,WAAW,MAAM,SAAS,KAAK,OAAO,KAAK;CAE7F,OAAO;AACT;;AAGA,SAAgB,iBAAiB,OAAuB;CACtD,IAAI,SAAS;CACb,OAAO,SAAS,QAAO,SAAS,SAAS,KAAK;CAC9C,OAAO,OAAO,MAAM,CAAC,CAAC;AACxB;AAEA,IAAI;;AAGJ,SAAS,oBAA4B;CACnC,IAAI,2BAA2B,KAAA,GAAW;EACxC,IAAM,QAAQ,SAAS,cAAc,KAAK;EAK1C,AAJA,MAAM,MAAM,UACV,yGACF,SAAS,KAAK,OAAO,KAAK,GAC1B,yBAAyB,KAAK,IAAI,GAAG,MAAM,cAAc,MAAM,WAAW,GAC1E,MAAM,OAAO;CACf;CACA,OAAO;AACT;;;;;;;;;AAUA,SAAgB,kBACd,MACA,EAAC,OAAO,mBAAyC,CAAC,GAC9B;CACpB,IAAM,EAAC,WAAW,YAAY,uBAAuB,sBAAqB,MACpE,UAAU,UAAU,cAAc,aAAa,GAC/C,OAAO,WAAW,cAAc,UAAU,GAC1C,eAAe,KAAK,MAAM,IAAI,OAC9B,YAAY,SAAS,cAErB,gBACH,iBAAiB,SAAS,IAAI,iBAAiB,YAAY,KAAK,uBAC7D,yBACJ,YAAY,oBAAoB,OAAO,YAAY,CAAC,OAAO,QAAQ,CAAC,IAAI,UAAU,cAC9E,uBAAuB,UAAU,eAAe,UAAU,cAC1D,mBACJ,0BAA0B,CAAC,uBAAwB,kBAAkB,kBAAkB,IAAK,GAExF,QACJ,UAAU,eACT,mBAAmB,cAAc,QAAQ,cAAc,KACxD,eACA,OAAO,YAAY,CAAC,QAAQ,OAAO,CAAC,KACnC,OAAO,OAAO,MAAM,CAAC,QAAQ,OAAO,CAAC,IAAI,KAC1C,kBACI,UAAU,KAAK,MAAM,QAAQ,qBAAqB;CACxD,OAAO,OAAO,SAAS,OAAO,KAAK,UAAU,IAAI,UAAU,KAAA;AAC7D;;AEzDA,SAAS,WAAA,IAQN;C,eARiB,EAClB,YACA,aACA,aAHkBC,IASZ,EAAC,WAAU,SAAS,GAIX,KAAA,aAAa,GAAG,WAAW,GAAG,yBAAyB,YAGvCC;CAAiBC,AAAAA,EAAAA,OAAAA,OAAN,MAAM,K,aAAjB,KAAA,IAAI,OAAO,MAAM,EAAE,GAAFA,EAAAA,KAAAA,OAAN,MAAM,I;CAApB,IAAA,KAAA,GAAGD,MAEQE;CAAiBC,AAAAA,EAAAA,OAAAA,OAAN,MAAM,K,aAAjB,KAAA,IAAI,OAAO,MAAM,EAAE,GAAFA,EAAAA,KAAAA,OAAN,MAAM,I;CAApB,IAAA,KAAA,GAAGD,MAGF,KAAA,OAAO,MAAM,cAAc,IAAI,IAAnCE;CAAIC,AAAAA,EAAAA,OAAAA,K,aAAJ,KAAA,IAAIA,EAAiC,GAAjCA,EAAAA,KAAAA,I;CAAP,IAAA,KAAA,GAAGD,MAPtBE;CAEiBC,AAAAA,EAAAA,OAAAA,MAAAA,EAAAA,OAEQC,MAAAA,EAAAA,OAGNC,MAPnB,KAAA,iBAAiB;GAErB,qBAAqBF;GAErB,6BAA6BC;GAG7B,uBAAuBC;CAC1B,CAAC,GANuBF,EAAAA,KAAAA,IAEQC,EAAAA,KAAAA,IAGNC,EAAAA,KAAAA,I;CAT5BC,IAAAA;CADF,OAaK,EAAA,QAAA,YAAA,EAAA,QAXUC,MAAAA,EAAAA,QACJL,MAFT,MAAA,oBAAC,OAAD;EACE,WAAWK;EACX,OAAOL;EAUN;CACE,CAAA,GADF,EAAA,MAAA,UAXUK,EAAAA,MAAAA,IACJL,EAAAA,MAAAA,I,4BAFTI;AAeJ;AAkBA,SAAgB,iBAAA,IAoB2B;C,eApBV,EAC/B,KACA,UACA,cAAc,kBACd,YACA,YAAA,IACA,aAAA,OAN+BE,IAK/B,aAAA,OAAA,KAAA,KAAAC,IACA,cAAA,OAAA,KAAA,IAAc,aAAdC,IAyBM,CAAC,OAAO,YAAY,SAAS,gBAAgB,GAC7C,CAAC,SAAS,cAAc,SAAS,EAAK,GACtC,CAAC,kBAAkB,uBAAuB,SAAS,gBAAgB;CACzE,AAAI,qBAAqB,qBACvB,oBAAoB,gBAAgB,GAC/B,WAAS,SAAS,gBAAgB;CAEFC,IAAAA;C,oDAAM,WAAA,WAAW,EAAI,G;CAA5D,IAAM,qBAAqBC,IACjBC,IAGPC;CAHH,A,oDAAU,iBAEK,WAAW,EAAK,GAC5B,KAAA,CAAC,G,gDAHJ,UAAUD,IAGPC,EAAE;CAGHC,IAAAA;CAEE,AAAA,EAAA,OAAA,W,aAFF,MAAC,WAAW,eAAe;EAEzB,AADA,SAAS,SAAS,GAClB,WAAW,WAAW,UAAU;CAClC,GADE,EAAA,KAAA,U;CAHJ,IAAM,eAAeC,IAQf,QAAQ,mBADM,SACa,CAAW,GACtC,gBAAgB,OAA2B,IAAI,GAEdC;C,oDAAC,MAAA,eAAuB;EAE7D,SAAS,UAAU;EACnB,IAAM,aAAa,cAAc,SAAS;EAC1C,IAAI,CAAC,YAAY;EAEjB,IAAM,aAAa,WAAW,MAAM,IAAI,SAAS;EACjD,AAAI,eAAe,eACjB,WAAW,SAAS;GAClB,SAAS;IAAC,MAAM;IAAG,IAAI,WAAW;IAAQ,QAAQ;GAAU;GAC5D,WAAWgB,kBAAgB,OAAO,WAAW,MAAM;EACrD,CAAC,GAGD,WAAW,UAAU,YAAY,GACjC,WAAW,UAAU,aAAa;CAEtC,G;CAjBA,IAAM,qBAAqBf,IAoBzBC;C,oDAAC,MAAA,YAAmE;EAClE,cAAc,SAAS,MAAM,SAAS;GAAC,SAAS,CAAC,GAAG,OAAO;GAAG,WAAW;EAAO,CAAC;CACnF,G;CAHF,IAAM,eAAeC,IAOUC;C,oDAAC,MAAA,YAAqB;EACnD,IAAMC,eAAa,cAAc,SAAS;EAC1C,OAAOA,eAAa,QAAQA,YAAU,IAAI;CAC5C,G;CAHA,IAAM,aAAaC,IAKaC;C,oDAAC,OAAA,MAAc,OAAe;EAC5D,IAAMF,eAAa,cAAc,SAAS;EAC1C,IAAI,CAACA,cAAY;EAEjB,IAAM,SAASA,aAAW,MAAM,IAAI;EAKpC,AAJA,aAAW,SAAS;GAClB,WAAWW,kBAAgB,MAAM,KAAK,IAAI,MAAM,MAAM,GAAG,KAAK,IAAI,IAAI,MAAM,CAAC;GAC7E,gBAAgB;EAClB,CAAC,GACD,aAAW,MAAM;CACnB,G;CAVA,IAAM,cAAcR,KAY0BC;C,oDAAC,OAAA,UAAmB;EAChE,IAAMJ,eAAa,cAAc,SAAS;EAC1C,OAAOA,eAAa,kBAAkBA,cAAY,EAAC,MAAK,CAAC,IAAI,KAAA;CAC/D,G;CAHA,IAAM,4BAA4BK,KAOhCC,KAOAC;CATF,A,qDAEE,aAAO;EACL;EACA;EACA;EACA;EACA,mBAAmB;CACrB,IACA,MAAA;EAAC;EAAoB;EAAc;EAAY;EAAa;CAAyB,G,wDATvF,oBACE,KACAD,KAOAC,GACF;CAIIC,IAAAA;CAIc,AAAA,EAAA,QAAA,cAAA,EAAA,QAEF,gBAAA,EAAA,QAHH,SAAA,EAAA,QAEA,SALT,MAAA,oBAAC,YAAD;EACE,KAAK;EACL,YAAY;EACL;EACK;EACL;EACP,UAAU;EACV,gBAAgB;CACjB,CAAA,GAJa,EAAA,MAAA,YAEF,EAAA,MAAA,cAHH,EAAA,MAAA,OAEA,EAAA,MAAA,O;CANXC,IAAAA;CADF,OAC0B,EAAA,QAAA,cAAA,EAAA,QACtBD,OAAAA,EAAAA,QAD+C,eAAjD,MAAA,oBAAC,YAAD;EAAwB;EAAyB;EAC/CA,UAAAA;CASU,CAAA,GAVY,EAAA,MAAA,YACtBA,EAAAA,MAAAA,KAD+C,EAAA,MAAA,a,4BAAjDC;AAYJ;ACvMA,MAAa,yBAAyB;CACpC;CACA;CACA;CACA;CACA;AACF,GAaa,uBAAuB,CAAC,iBAAiB,iBAAiB;AAIvE,SAAgB,uBAAuB,GAAsC;CAC3E,OAAO,uBAAuB,SAAS,CAAyB;AAClE;AAEA,SAAgB,qBACd,yBAC+C;CAC/C,OACE,OAAO,2BAA4B,YACnC,qBAAqB,SAAS,uBAA6C;AAE/E;AAEA,SAAgB,qBAAqB,EAAC,2BAA4D;CAChG,OAAc,4BAA4B;AAC5C;AAEA,SAAgB,qBAAqB,EACnC,mBACA,kBACA,wBAKgC;CAOhC,OANI,sBAAsB,kBACjB,mBAEL,sBAAsB,oBACjB,uBAEF;AACT;;;;;AAMA,SAAgB,iBACd,mBACA,qBACoB;CACpB,IAAI,sBAAsB,iBAG1B,OAAO;AACT;ACzEA,SAAgB,kBACd,OACA,SAAkC,CAAC,GACnC,UAA6C,CAAC,GACtC;CACR,IAAM,eAAe,IAAI,gBAAgB;CACzC,aAAa,IAAI,SAAS,KAAK;CAE/B,KAAK,IAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAC9C,aAAa,IAAI,IAAI,OAAO,KAAK,UAAU,KAAK,CAAC;CAGnD,KAAK,IAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,GAC/C,AAAI,SAAO,aAAa,IAAI,KAAK,GAAG,OAAO;CAG7C,OAAO,IAAI;AACb;ACjBA,SAAS,mBAAmB,MAAwC;CAClE,IAAM,UAAU;CAEhB,QADoB,SAAS,YAAY,WAAW,SAAS,YAAY,eACnD,SAAS,aAAa;AAC9C;;;;;;;;AASA,SAAgB,oBAAoB,MAAmB,OAAgC;CACrF,IAAM,OAAO,MAAM,aAAa,GAC1B,CAAC,UAAU;CAYjB,OATI,mBAAmB,MAAM,IACpB,KAIL,WAAW,OAAO,YAAY,WAAW,OAAO,SAAS,QAItD,SAAS,QAAQ,KAAK,SAAS,IAAI;AAC5C;AC5BA,SAAgB,cAAc,KAA8C;CAC1E,OACE,CAAC,CAAC,OAAO,OAAO,OAAQ,YAAY,OAAO,UAAU,SAAS,KAAK,GAAG,MAAM;AAEhF;;ACDA,MAAa,4BAA4B,iBAEnC,kBAAkB,qBAAqB,GACvC,iCAAiB,IAAI,IAAgB;;AAS3C,SAAgB,aAAkC;CAChD,OAAO,kBAAkB,WAAW,eAAe,KAAA;AACrD;;AAGA,SAAgB,sBAAsB,UAAkC;CAEtE,OADA,eAAe,IAAI,QAAQ,SACd;EACX,eAAe,OAAO,QAAQ;CAChC;AACF;AAEA,SAAgB,oBAAoB;CAClC,IAAM,UAAU,WAAW;CAC3B,IAAI,SAAS;EAEX,IAAM,OAAiB,CAAC;EACxB,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,IAAM,MAAM,QAAQ,IAAI,CAAC;GACzB,AAAI,KAAK,WAAA,eAAoC,KAC3C,KAAK,KAAK,GAAG;EAEjB;EACA,KAAK,SAAS,QAAQ,QAAQ,WAAW,GAAG,CAAC;CAC/C;CAEA,eAAe,SAAS,aAAa,SAAS,CAAC;AACjD;AAEA,SAAgB,gBAAgB,WAAoC;CAClE,IAAM,aAAa,GAAG,4BAA4B,aAC9C,cAA8C;CAElD,OAAO;EAAC;EAAK;EAAK;CAAK;CAEvB,SAAS,IAAO,KAAa,YAAkB;EAC7C,IAAM,QAAQ,YAAY;EAC1B,OAAc,MAAM,SAAS,SAAc,aAAc,MAAM;CACjE;CAEA,SAAS,IAAO,KAAa,OAAa;EACxC,IAAM,QAAQ,YAAY;EAG1B,OAFA,MAAM,OAAO,OACb,aAAa,QAAQ,YAAY,KAAK,UAAU,WAAW,CAAC,GACrD;CACT;CAEA,SAAS,MAAS,OAAa;EAC7B,IAAM,QAAQ;GAAC,GAAG,YAAY;GAAG,GAAG;EAAK;EAEzC,OADA,aAAa,QAAQ,YAAY,KAAK,UAAU,KAAK,CAAC,GAC/C;CACT;CAEA,SAAS,cAAuC;EAK9C,OAJI,gBAAgB,SAClB,cAAc,UAAU,IAGnB;CACT;CAEA,SAAS,YAAY;EACnB,IAAI,CAAC,iBACH,OAAO,CAAC;EAGV,IAAI;GACF,IAAM,SAAS,KAAK,MAAM,aAAa,QAAQ,UAAU,KAAK,IAAI;GAClE,OAAO,cAAc,MAAM,IAAI,SAAS,CAAC;EAC3C,QAAQ;GACN,OAAO,CAAC;EACV;CACF;AACF;AAEA,SAAS,uBAAuB;CAC9B,IAAM,MAAM;CACZ,IAAI;EAGF,OAFA,aAAa,QAAQ,KAAK,GAAG,GAC7B,aAAa,WAAW,GAAG,GACpB;CACT,QAAQ;EACN,OAAO;CACT;AACF;AC7FA,SAAgB,oBAAoB,IAA2C;CAC7E,IAAM,SAAkC,CAAC,GACnC,UAAkC,CAAC;CAEzC,KAAK,IAAM,CAAC,KAAK,UAAU,GAAG,QAAQ,GACpC,AAAI,IAAI,OAAO,MAGb,OAAO,eAAe,QAAQ,IAAI,MAAM,CAAC,GAAG;EAC1C,OAAO,KAAK,MAAM,KAAK;EACvB,YAAY;EACZ,cAAc;EACd,UAAU;CACZ,CAAC,KAIC,QAAQ,iBAAiB,QAAQ,aAAa,QAAQ,uBACxD,QAAQ,OAAO;CAKnB,OAAO;EAAC,OAAO,GAAG,IAAI,OAAO,KAAK;EAAI;EAAQ;CAAO;AACvD;AC9BA,SAAgB,mBAAmB,YAA6B;CAC9D,IAAM,sBAAsB,WAAW,QAAQ,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY;CAQ5E,OALE,oBAAoB,SAAS,MAC5B,wBAAwB,OACvB,wBAAwB,OACvB,sBAAsB,KAAK,mBAAmB,KAAK,CAAC,MAAM,KAAK,MAAM,mBAAmB,CAAC;AAGhG;;;;;;;ACIA,MAAa,mBAAmB,gEAM1B,qBAAqB,0EA6BrB,eAAe;;AAGrB,SAAgB,aAAa,UAA2B;CACtD,OAAO,aAAa,KAAK,QAAQ;AACnC;;;;;;;AAQA,SAAgB,cAAc,MAAc,UAAoD;CAC9F,IAAM,UAAU,KAAK,KAAK,GACpB,MAAM,aAAa,OAAO,GAC1B,QAAQ,KAAK,SAAS,MAAM,kBAAkB;CACpD,IAAI,CAAC,OAAO,CAAC,OACX,OAAO;CAGT,IAAM,GAAG,gBAAgB,eAAe,OAEpC;CACJ,IAAI;EACF,QAAQ,oBAAoB,IAAI,YAAY;CAC9C,QAAQ;EACN,OAAO;CACT;CACA,IAAI,CAAC,MAAM,OACT,OAAO;CAGT,IAAM,iBAAiB,MAAM,QAAQ,aAC/B,cACJ,kBACA,uBAAuB,cAAc,KACrC,CAAC,qBAAqB,cAAc,IAChC,iBACA,KAAA,GAGA,EAAC,oBAAmB,MAAM,SAC1B,mBAAmB,oBAAoB,UAAU,oBAAoB;CAE3E,OAAO;EACL,OAAO,MAAM;EACb,QAAQ,MAAM;EACd,WAAW,KAAK,UAAU,MAAM,QAAQ,MAAM,CAAC;EAC/C,SAAS;EACT,gBAAgB,SAAS,SAAS,WAAW;EAC7C,YAAY,mBAAmB,cAAc,IAAI,iBAAiB,KAAA;EAClE,gBAAgB,kBAAkB,KAAA;EAClC;EACA,2BAA2B,EAAQ,kBAAmB,gBAAgB,KAAA;EACtE,SAAS,MAAM,QAAQ,WAAW,KAAA;EAClC;EACA,QAAQ,aAAa,IAAI,QAAQ;EACjC,KAAK;CACP;AACF;AAEA,SAAS,aAAa,MAA0B;CAC9C,IAAI;EACF,IAAM,MAAM,IAAI,IAAI,IAAI;EACxB,OAAO,IAAI,aAAa,WAAW,IAAI,aAAa,WAAW,MAAM;CACvE,QAAQ;EACN,OAAO;CACT;AACF;ACnHA,SAAgB,eACd,KACA,GACiC;CACjC,IAAI;EACF,IAAM,SAAS,MAAM,MAAM,MAAM,GAAG,IAAI,CAAC;EACzC,OAAO,OAAO,UAAW,YAAY,UAAU,CAAC,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;CACpF,SAAS,KAAK;EAOZ,OAJA,IAAI,UAAU,GAAG,EAAE,kCAAkC,EAAE,OAAO,IAAI,QAAQ,QACxE,UACA,EACF,KACO;CACT;AACF;;AEYA,SAAgB,KAAA,IAG0D;C,cADrE,OADH;CADmBG,AAAAA,EAAAA,OAAAA,M,6BACnB,CAAA,KACA,GAAA,SAFmBA,I;CAIZC,IAAAA;CAAP,OAAiB,EAAA,OAAA,SAAA,EAAA,OAAY,OAAtB,KAAA,oBAAC,MAAD;EAAM,GAAI;EAAY;EAAK,WAAW;CAAO,CAAA,GAAnC,EAAA,KAAA,OAAY,EAAA,KAAA,K,wBAAtBA;AACT;AAEA,SAAgB,OAAO,OAAoC;C,cAClDC;CAAP,OAAiB,EAAA,OAAA,Q,aAAV,KAAA,oBAAC,MAAD;EAAM,GAAI;EAAO,WAAW;CAAS,CAAA,GAA3B,EAAA,KAAA,O,YAAVA;AACT;AAEA,SAAgB,YAAY,OAAqC;C,cACxDC;CAAP,OAAkB,EAAA,OAAA,Q,aAAX,KAAA,oBAAC,OAAD;EAAO,GAAI;EAAO,WAAW;CAAc,CAAA,GAAhC,EAAA,KAAA,O,YAAXA;AACT;AAEA,SAAgB,mBAAmB,OAAmC;C,cAC7DC;CAAP,OAAgB,EAAA,OAAA,Q,aAAT,KAAA,oBAAC,KAAD;EAAK,GAAI;EAAO,WAAW;CAAqB,CAAA,GAAvC,EAAA,KAAA,O,YAATA;AACT;AAEA,SAAgB,yBAAyB,OAAoC;C,cACpEC;CAAP,OAAiB,EAAA,OAAA,Q,aAAV,KAAA,oBAAC,MAAD;EAAM,GAAI;EAAO,eAAc;EAAS,WAAW;CAA2B,CAAA,GAApE,EAAA,KAAA,O,YAAVA;AACT;AAEA,SAAgB,uBAAuB,OAAoC;C,cAEvEC;CADF,OAEQ,EAAA,OAAA,Q,aADN,KAAA,oBAAC,MAAD;EACE,GAAI;EACJ,eAAc;EACd,WAAU;EACV,UAAU;EACV,UAAS;EACT,WAAW;CACZ,CAAA,GANK,EAAA,KAAA,O,YADNA;AASJ;AAEA,SAAgB,cAAc,OAA4B;C,cACjDC;CAAP,OAAc,EAAA,OAAA,Q,aAAP,KAAA,oBAAC,KAAD;EAAG,GAAI;EAAO,WAAW;CAAgB,CAAA,GAAlC,EAAA,KAAA,O,YAAPA;AACT;AAEA,SAAgB,yBAAyB,OAAmC;C,cACnEC;CAAP,OAAgB,EAAA,OAAA,Q,aAAT,KAAA,oBAAC,KAAD;EAAK,GAAI;EAAO,WAAW;CAA2B,CAAA,GAA7C,EAAA,KAAA,O,YAATA;AACT;AAEA,SAAgB,6BAA6B,OAAmC;C,cAE5EC;CADF,OACW,EAAA,OAAA,Q,aAAT,KAAA,oBAAC,KAAD;EAAK,GAAI;EAAO,WAAW,GAAG,yBAAyB,GAAG;CAAiC,CAAA,GAAlF,EAAA,KAAA,O,YAATA;AAEJ;AAEA,SAAgB,eAAe,OAAoC;C,cAC1DC;CAAP,OAAiB,EAAA,OAAA,Q,aAAV,KAAA,oBAAC,MAAD;EAAM,GAAI;EAAO,WAAW;CAAiB,CAAA,GAAnC,EAAA,KAAA,O,YAAVA;AACT;AAEA,SAAgB,qBAAqB,OAAoC;C,cAChEC;CAAP,OAAiB,EAAA,OAAA,Q,aAAV,KAAA,oBAAC,MAAD;EAAM,GAAI;EAAO,WAAW;CAAuB,CAAA,GAAzC,EAAA,KAAA,O,YAAVA;AACT;AAEA,SAAgB,qBAAqB,OAAmC;C,cAC/DC;CAAP,OAAgB,EAAA,OAAA,Q,aAAT,KAAA,oBAAC,KAAD;EAAK,GAAI;EAAO,WAAW;CAAuB,CAAA,GAAzC,EAAA,KAAA,O,YAATA;AACT;AAEA,SAAgB,gBAAA,IAGuC;C,cAFrD,WACG;CAF2BC,AAAAA,EAAAA,OAAAA,M,mCAC9B,CAAA,WACA,GAAA,SAF8BA,I;CAOf,IAAA,KAAA,YAAY,GAAG,gBAAgB,GAAG,2BAA2B,iBAF1EC;CADF,OAEQ,EAAA,OAAA,SAAA,EAAA,OACOC,MAFb,KAAA,oBAAC,MAAD;EACE,GAAI;EACJ,WAAWA;CACZ,CAAA,GAFK,EAAA,KAAA,OACOA,EAAAA,KAAAA,I,wBAFbD;AAKJ;AAEA,SAAgB,OAAO,OAAmC;C,cACjDE;CAAP,OAAgB,EAAA,OAAA,Q,aAAT,KAAA,oBAAC,KAAD;EAAK,GAAI;EAAO,WAAW;CAAS,CAAA,GAA3B,EAAA,KAAA,O,YAATA;AACT;AAEA,SAAgB,aAAa,OAAoC;C,cACxDC;CAAP,OAAiB,EAAA,OAAA,Q,aAAV,KAAA,oBAAC,MAAD;EAAM,GAAI;EAAO,WAAW;CAAe,CAAA,GAAjC,EAAA,KAAA,O,YAAVA;AACT;AAEA,SAAgB,YAAY,OAAoC;C,cACvDC;CAAP,OAAiB,EAAA,OAAA,Q,aAAV,KAAA,oBAAC,MAAD;EAAM,GAAI;EAAO,WAAW;CAAc,CAAA,GAAhC,EAAA,KAAA,O,YAAVA;AACT;AAEA,SAAgB,qBAAqB,OAAoC;C,cACjE,EAAC,OAAO,SAAQc,YAAW,GAC3B,WAAW,KAAK,KAAK,MAAM,IAE/B,KAAA,MAAM,KAAK,IAAI,SAAS,aAAa,SAAS,iBAAiB,SAAS,iBADxDb;CAChBC,AAAAA,EAAAA,OAAAA,K,aADgB,KAAA,IAChBA,EACF,GADEA,EAAAA,KAAAA,I;CAOsD,IAAA,KAAA,GAAGa,MAAhDZ;CAA6CC,AAAAA,EAAAA,OAAAA,K,aAA7C,KAAA,iBAAiB,GAAE,0BAA0BA,GAAc,CAAC,GAAfA,EAAAA,KAAAA,I;CAHtDC,IAAAA;CADF,OAEQ,EAAA,OAAA,SAAA,EAAA,OAEGF,MAHT,KAAA,oBAAC,MAAD;EACE,GAAI;EACJ,WAAW;EACX,OAAOA;CACR,CAAA,GAHK,EAAA,KAAA,OAEGA,EAAAA,KAAAA,I,wBAHTE;AAMJ;AAEA,SAAgB,cAAc,OAAoC;C,cACzDC;CAAP,OAAiB,EAAA,OAAA,Q,aAAV,KAAA,oBAAC,MAAD;EAAM,GAAI;EAAO,WAAW;CAAgB,CAAA,GAAlC,EAAA,KAAA,O,YAAVA;AACT;AAEA,SAAgB,gBAAgB,OAAoC;C,cAC5D,EAAC,UAASQ,YAAW,GAM6BP;CAAUC,AAAAA,EAAAA,OAAAA,MAAAA,K,aAAV,KAAA,IAAI,MAAM,EAAE,GAAFA,EAAAA,KAAAA,MAAAA,I;CAAb,IAAA,KAAA,GAAGD,MAA7CE;CAA0CC,AAAAA,EAAAA,OAAAA,K,aAA1C,KAAA,iBAAiB,GAAE,uBAAuBA,GAAkB,CAAC,GAAnBA,EAAAA,KAAAA,I;CAHnDC,IAAAA;CADF,OAEQ,EAAA,OAAA,SAAA,EAAA,OAEGF,MAHT,KAAA,oBAAC,MAAD;EACE,GAAI;EACJ,WAAW;EACX,OAAOA;CACR,CAAA,GAHK,EAAA,KAAA,OAEGA,EAAAA,KAAAA,I,wBAHTE;AAMJ;AAEA,SAAgB,kBAAkB,OAAmC;C,cAC5DC;CAAP,OAAgB,EAAA,OAAA,Q,aAAT,KAAA,oBAAC,KAAD;EAAK,GAAI;EAAO,WAAW;CAAoB,CAAA,GAAtC,EAAA,KAAA,O,YAATA;AACT;AC9HA,SAAgB,aAAa,OAA0B;C,eAC/C,EAAC,UAAU,aAAa,gBAAgB,cAAa,OACrD,EAAC,MAAK,eAAe,qBAAqB,GAG9CI;CACE,AAAA,EAAA,OAAA,W,aADF,MAAC,aAAqB;EACpB,SAAS,QAAQ;CACnB,GADE,EAAA,KAAA,U;CAFJ,IAAM,kBAAkBC,IAOWC;CAAS,AAAA,EAAA,OAAA,kB,aAAT,KAAA,SAAS,iBAAiB,GAAG,GAApB,EAAA,KAAA,iB;CAA5C,IAAM,eAAeC,IAEE,KAAA,iBAAiB,YAAY,YAGxBC;C,0BAAE,KAAA,EAAA,cAAc,GAAhB,EAAA,KAAA,G;CAApBC,IAAAA;CAAoBD,AAAAA,EAAAA,OAAAA,K,aAApB,KAAA,oBAAC,aAAD;EAAa,OAAA;EAAOA,UAAAA;CAA+B,CAAA,GAA/BA,EAAAA,KAAAA,I;CACnBE,IAAAA;C,oCACC,KAAA,eAAA,oBAAC,SAAD;EAAS,SAAA;EAAQ,WAAU;EAAM,QAAA;EAAO,SAAS,oBAAC,MAAD;GAAM,MAAM;GAAI,UAAA;EAAkB,CAAA;EACjF,UAAA,oBAAC,KAAD;GAAK,SAAS;GAAG,SAAS;GACxB,UAAA,oBAAC,MAAD,EAAA,UACE,oBAAC,kBAAD,CAAmB,CAAA,EACf,CAAA;EACH,CAAA;CACE,CAAA,GAPV,EAAA,KAAA,a;CAHLC,IAAAA;CAEIF,AAAAA,EAAAA,QAAAA,MAAAA,EAAAA,QACCC,MAHL,KAAA,oBAAC,8BAAD,EAAA,UACE,qBAAC,MAAD,EAAA,UAAA,CACED,IACCC,EASG,EAAA,CAAA,EACsB,CAAA,GAX1BD,EAAAA,MAAAA,IACCC,EAAAA,MAAAA,I;CAaW,IAAA,KAAA,MAAM,SAASM,YAF/BJ;CACO,AAAA,EAAA,QAAA,aAAA,EAAA,QAEK,gBAAA,EAAA,QADIC,MAFhB,KAAA,oBAAC,kBAAD;EACE,KAAK;EACL,cAAcA;EACd,UAAU;EACV,YAAY;CACb,CAAA,GAJM,EAAA,MAAA,WAEK,EAAA,MAAA,cADIA,EAAAA,MAAAA,I;CAjBlBC,IAAAA;CADF,OACuBC,EAAAA,QAAAA,MAAAA,EAAAA,QACnBJ,MAAAA,EAAAA,QAcAC,MAfF,KAAA,qBAAC,MAAD;EAAM,MAAM;EAAG,MAAMG;EAAyC,eAAY;EAA1E,UAAA,CACEJ,IAcAC,EAMI;C,IArBeG,EAAAA,MAAAA,IACnBJ,EAAAA,MAAAA,IAcAC,EAAAA,MAAAA,I,0BAfFE;AAuBJ;AAEA,SAAgB,YAAY,OAAe,GAAoD;CAC7F,IAAM,eAAe,eAAe,OAAO,CAAC,GACtC,SAAS,wBAAwB,QAAQ,CAAC,IAAI,cAC9C,kBAAkB,wBAAwB,QAAQ,aAAa,UAAU,KAAA;CAG/E,OAAO;EACL,QAAQ;EACR,KAAK;EACL,OAAO,CALQ;EAMf,OAAO;CACT;AACF;ACnEA,MACM,6BAA6B,sBAQ7B,8BAA6C;CACjD,QAAQ;EAAC;EAAW;EAAY;CAAW;CAC3C,eAAe;CACf,YAAY;AACd,GAgBM,eAAe,EACnB,SAAS,CAAC,EACZ,GACM,mBAAmB;;AAoBzB,SAAS,YAAY,QAAuB,OAAgC;CAC1E,IAAM,MAAM,IAAI,IAAI,OAAO,KAAK,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC,GACxD,KAAK,IAAI,IAAI,MAAM,KAAK,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC;CAC5D,OAAO,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,IAAI,KAAK,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAChD,QAAQ,CAACqE,OAAQ,IAAI,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC,CAC7C;AACF;;;;;;;AAQA,SAAS,kBAAkB,SAAwB,EAAC,QAAQ,QAA2B;CACrF,IAAM,QAAQ,IAAI,IAAI,QAAQ,KAAK,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC,GAC3D,SAAS,IAAI,IAAI,OAAO,KAAK,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC;CACjE,KAAK,IAAM,OAAO,MAChB,IAAI,CAACA,OAAQ,MAAM,IAAI,GAAG,GAAG,OAAO,IAAI,GAAG,CAAC,GAAG,OAAO;CAExD,OAAO;AACT;;AAGA,SAAS,mBAAmB,OAAgB,UAAwC;CAClF,IAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CACrE,OAAW,MACT,GAAG,QAAQ,gBAAgB,SAAS,6GACpC,EAAC,OAAO,MAAK,CACf;AACF;AAEA,SAAgB,kBAmBd;C,eACM,gBAAgB,iBAAiB,GACLjE;C,oDAAC,KAAA,EAAA,YAAY,oBAAmB,G;CAAlE,IAAM,kBAAkB,UAAUA,EAAiC,GAC7D,cAAc,eAAe,GAE7B,CAAC,OAAO,YAAY,SAAwB,YAAY,GACIC;C,oDAAC,KAAA,CAAA,G;CAAnE,IAAM,CAAC,eAAe,oBAAoB,SAAwBA,EAAE,GAG9D,CAAC,cAAc,mBAAmB,SAAS,CAAC,GACCA;C,oDAAC,KAAA,CAAA,G;CAApD,IAAM,CAAC,UAAU,eAAe,SAAmBA,EAAE,GACNA;C,oDAAC,KAAA,CAAA,G;CAAhD,IAAM,CAAC,QAAQ,aAAa,SAAmBA,EAAE,GAC3C,CAAC,gBAAgB,qBAAqB,SAA4B,GAClE,CAAC,kBAAkB,uBAAuB,SAA4B,GACtE,CAAC,OAAO,YAAY,SAA4B,GAKhD,mBAAmB,OAAsB,aAAa,OAAO,GAChBC;C,oDAAQ,KAAA,QAAA,QAAQ,G;CAAnE,IAAM,oBAAoB,OAAyBA,EAAiB,GAY9D,2BAA2B,OAAO,CAAC,GACnC,eAAe,OAAyB,IAAI,GAC5C,qBAAqB,OAAO,EAAK,GACjC,2BAA2B,OAAO,EAAK,GAIrBC;C,oDAAI,qBAAA,IAAA,IAA2B,G;CAAvD,IAAM,WAAW,OAAOA,EAAgC,GAG/CC;C,sCAAc,KAAA,cAAA,OAAO,gBAAgB,GAArC,EAAA,KAAA,e;CADT,IAAM,kBAAkBC,IAKtBC;CACqCC,AAAAA,EAAAA,OAAAA,aAAAA,K,aADrC,MAAC,SAA+C;EAC9C,IAAM,gBAAgB,aAAa;EAEnC,OAAO,KAAK,KAAK,SAAS;GACxB,MAAM,IAAI;GACV,UAAU,IAAI;GACd,sBAAsB,IAAI,aAAa;GACvC,SAAS,IAAI;GACb,QAAQ;GACR,OAAO,IAAI;GACX,KAAK,IAAI;EACX,EAAE;CACJ,GAXqCA,EAAAA,KAAAA,aAAAA,I;CAFvC,IAAM,mBAAmBC,IAiBfC,IAsCPC;CAtCH,AAQc,EAAA,QAAA,mB,2BARJ,WAAM;EAMd,mBAAmB,UAAU;EAC7B,IAAI,cAAc,IACZ,MAAM,gBAAgB,UAAU;GACpC,OAAO,SAAS;IACd,IAAM,SAAS,QAA4C,MACrD,YAAY,aAAa;IAC/B,IAAI,aAAa,CAAC,mBAAmB,SAAS;KAC5C,IAAI,CAAC,kBAAkB,QAAQ,WAAW,aAAa,SAAS,SAAS,GAAG;KAG5E,AAAK,gBAAa,mBAAmB,UAAU;IACjD;IACA,IAAI,2BAAyB,UAAU,IAIvC;SADI,mBAAmB,YAAS,aAAa,UAAU,OACnD,CAAC,QAAQ;MAEX,IAAI,yBAAyB,SAAS;MAEtC,AADA,iBAAiB,UAAU,aAAa,SACxC,SAAS,YAAY;KAEvB,OAGA,AAFA,yBAAyB,UAAU,IACnC,iBAAiB,UAAU,OAAO,SAClC,SAAS,MAAM;IAHf;GAIF;GACA,QAAQ,QAAQ,SAAS,GAAY;EACvC,CAAC;EAGD,OAFA,cAAc,UAED,IAAI,YAAY;CAC/B,GAAG,KAAA,CAAC,eAAe,GA9BL,EAAA,MAAA,iB,yBARd,UAAUD,IAsCPC,EAAiB;CAEVC,IAAAA,KA8CPC;CA9CH,AASuB,EAAA,QAAA,oBAAA,EAAA,QALA,mBAJb,YAAM;EACd,IAAI,YAAY,IAEV,qBAAqB,YAAY;GAIrC,IAAM,WAAWC,MAHE,gBAAgB,MAA6B,4GAAsB,EACpF,iBAAiB,2BACnB,CAAC,KACwB,CAAC;GAC1B,AAAK,aACH,iBAAiB,iBAAiB,QAAQ,CAAC;EAE/C;EAEK,mBAAmB,CAAC,CAAC,OAAO,UAAQ;GACvC,AAAK,aACH,SAASC,KAAY;EAEzB,CAAC;EAED,IAAMC,QAAM,gBAAgB,WACzB,OACC,gCACA,EACE,iBAAiB,2BACnB,GACA,2BACF,CAAC,CACA,UAAU;GACT,YAAY;IACL,mBAAmB,CAAC,CAAC,OAAO,UAAQ;KACvC,AAAK,aACH,SAASD,KAAY;IAEzB,CAAC;GACH;GACA,QAAQ,UAAQ;IACd,AAAK,aACH,SAASA,KAAY;GAEzB;EACF,CAAC;EAEH,aAAa;GAEX,AADA,YAAY,IACZ,MAAI,YAAY;EAClB;CACF,GAAG,MAAA,CAAC,iBAAiB,gBAAgB,GArCd,EAAA,MAAA,kBALA,EAAA,MAAA,iB,wDAJvB,UAAUH,KA8CPC,GAAmC;CAGGI,IAAAA;C,qDAAI,OAAA,SAAuC;EAClF,yBAAyB,WAAW;EACpC,IAAM,YACJ,KAAK,CAAC,CAAC,cAAc;GACnB,2BAAyB;EAC3B,CAAC,GACG,SAAS,kBAAkB,QAAQ,KAAK,KAAK,GAAG;EAEtD,OADA,kBAAkB,UAAU,OAAO,MAAMC,OAAe,GACjD;CACT,G;CATA,IAAM,uBAAuBC,KAgB3BC;C,qDAAC,OAAA,QAAuB,WAA0B,SAAwB;EACxE,IAAM,OAAO,IAAI,IAAI,aAAa,SAAS,IAAI;EAC/C,KAAK,IAAM,OAAO,YAAY,QAAQ,SAAS,GAAG,KAAK,IAAI,GAAG;EAC9D,aAAa,UAAU;GAAC,QAAQ;GAAM;EAAI;CAC5C,G;CALF,IAAM,iBAAiBC,KAerBC;CACuB,AAAA,EAAA,QAAA,gB,eADvB,MAAA,OAAO,YAA2B;EAIhC,IAAIC,MAHiB,cAAc,OAAO,kBAAkB,EAC1D,QACF,CAAkC,MACnB,MACb,MAAU,MAAM,wCAAwC;CAE5D,GANuB,EAAA,MAAA,e;CAFzB,IAAM,uBAAuBC,KAiB3BC;CAQY,AAAA,EAAA,QAAA,uB,eARZ,OAAC,WACC,qBAAqB,YAAY;EAC/B,IAAMC,WAAS,iBAAiB,SAC1B,OAAO,OAAOA,QAAM;EAG1B,AAFA,eAAeA,UAAQ,MAAM,IAAI,GACjC,iBAAiB,UAAU,MAC3B,SAAS,EAAC,SAAS,KAAI,CAAC;EACxB,IAAI;GACF,MAAM,qBAAqB,IAAI;EACjC,SAASX,KAAK;GAAL,IAAA,QAAA;GAKP,MAHA,eAAeW,UAAQ,MAAMA,QAAM,GACnC,iBAAiB,UAAUA,UAC3B,SAAS,EAAC,SAASA,SAAM,CAAC,GACpBX;EACR;EACA,OAAO;CACT,CAAC,GATS,EAAA,MAAA,sB;CATd,IAAM,uBAAuBY,KAuBpBC;CAAI,AAAA,EAAA,QAAA,iBAAA,EAAA,QAAwBC,MAAAA,WAA5B,MAAA,CAAC,GAAG,eAAe,GAAG,MAAM,OAAO,CAAC,CAAC,KAAKC,QAEhD,GAFU,EAAA,MAAA,eAAwBD,EAAAA,MAAAA,MAAAA,S;CADrC,IAAMA,YAAUE,KAUYC;C,qDAAI,OAAA,YAC9B,gBAAgBC,QAAoB,GACpC,kBAAkB,KAAA,CAAS,GACpBC,OAAK,CAAC,CACV,OAAO,UAAiB;EACvB,IAAM,YAAYnB,iBAAe,QAAQA,QAAU,MAAM,OAAOA,KAAG,CAAC;EAEpE,MADA,kBAAkB,SAAS,GACrB;CACR,CAAC,CAAC,CACD,cAAc,gBAAgBoB,MAAoB,CAAC,I;CATxD,IAAM,UAAUC,KAcdC;CAGWC,AAAAA,EAAAA,QAAAA,eAAAA,EAAAA,QAU0B,oBAAA,EAAA,QAPL,mBAAA,EAAA,QAYtB,wBAlBV,OAAC,UACC,QAAQ,YAAY;EAClB,IAAI,MAAM,QAAQ;GAChB,IAAI,CAAC,aAAa,IAChB,MAAU,MAAM,qDAAqD;GAEvE,IAAM,aAAc,MAAM,gBAAgB,OAAO;IAC/C,OAAO;IACP,UAAU,YAAY;IACtB,SAAS,MAAM;IACf,OAAO,MAAM;IACb,KAAK,MAAM;GACb,CAAC;GAED,OADA,kBAAkB,SAAS,CAAC,GAAG,iBAAiB,CAAC,UAAU,CAAC,GAAG,GAAG,IAAI,CAAC,GAChE,WAAW;EACpB;EAEA,IAAM,WAAW;GAAC,GAAG;GAAO,MAAM,KAAK;EAAC;EAExC,OADA,MAAM,sBAAsB,cAAY,CAAC,UAAU,GAAGT,SAAO,CAAC,GACvD,SAAS;CAClB,CAAC,GAjBQS,EAAAA,MAAAA,aAU0B,EAAA,MAAA,kBAPL,EAAA,MAAA,iBAYtB,EAAA,MAAA,sB;CAnBZ,IAAM,YAAYC,KA0BhBC;CAGWF,AAAAA,EAAAA,QAAAA,eAAAA,EAAAA,QAYwB,oBAAA,EAAA,QATH,mBAAA,EAAA,QAkBtB,wBAxBV,OAAC,YACC,QAAQ,YAAY;EAClB,IAAIG,QAAM,QAAQ;GAChB,IAAI,CAAC,aAAa,MAAMA,QAAM,aAAa,YAAY,IACrD,MAAU,MAAM,4CAA4C;GAE9D,IAAM,aAAc,MAAM,gBACvB,MAAMA,QAAM,IAAI,CAAC,CACjB,IAAI;IACH,SAASA,QAAM;IACf,OAAOA,QAAM;IACb,KAAKA,QAAM;GACb,CAAC,CAAC,CACD,OAAO,GAEJ,CAAC,sBAAsB,iBAAiB,CAAC,UAAU,CAAC;GAC1D,kBAAkB,WAChBC,OAAK,KAAK,kBACR,cAAc,SAASD,QAAM,OAAO,qBAAqB,aAC3D,CACF;EAEF,OAEA,MAAM,sBAAsB,cAC1BZ,UAAQ,KAAK,MAAO,EAAE,SAASY,QAAM,OAAO;GAAC,GAAG;GAAG,GAAGA;EAAK,IAAI,CAAE,CACnE;CACF,CAAC,GAxBQH,EAAAA,MAAAA,aAYwB,EAAA,MAAA,kBATH,EAAA,MAAA,iBAkBtB,EAAA,MAAA,sB;CAzBZ,IAAM,cAAcK,KAkClBC;CAKON,AAAAA,EAAAA,QAAAA,eAAAA,EAAAA,QAJe,iBAAA,EAAA,QAOd,mBARR,MAAA,OAAO,UAAgB;EACrB,IAAM,cAAc,cAAc,MAAM,YAAUG,QAAM,SAASI,SAAOJ,QAAM,MAAM;EACpF,IAAI,CAAC,aACH,MAAU,MAAM,6BAA6BI,MAAI,EAAE;EAErD,IAAI,CAAC,aAAa,MAAM,YAAY,aAAa,YAAY,IAC3D,MAAU,MAAM,4CAA4C;EAG9D,AADA,MAAM,gBAAgB,OAAOA,KAAG,GAChC,kBAAkB,WAASH,OAAK,QAAQ,YAAUD,QAAM,SAASI,KAAG,CAAC;CACvE,GALOP,EAAAA,MAAAA,aAJe,EAAA,MAAA,eAOd,EAAA,MAAA,iB;CATV,IAAM,oBAAoBQ,KAiBxBC;CACQ,AAAA,EAAA,QAAA,uB,eADR,MAAA,OAAO,UAAgB;EACrB,MAAM,sBAAsB,cAAYlB,UAAQ,QAAQ,QAAMmB,IAAE,SAASH,KAAG,CAAC;CAC/E,GADQ,EAAA,MAAA,sB;CAFV,IAAM,sBAAsBI,KAQ1BC;CAOY,AAAA,EAAA,QAAA,uBAAA,EAAA,QAFA,qBAAA,EAAA,QADJ,iBAJR,MAAA,OAAO,UAAgB;EAErB,AADA,aAAa,WAAS,CAAC,GAAGR,QAAMG,KAAG,CAAC,GACpC,oBAAoB,KAAA,CAAS;EAC7B,IAAI;GACF,AAAI,cAAc,MAAM,YAAUJ,QAAM,SAASI,SAAOJ,QAAM,MAAM,IAClE,MAAM,kBAAkBI,KAAG,IAE3B,MAAM,oBAAoBA,KAAG;EAEjC,SAAS9B,KAAK;GAAL,IAAA,QAAA;GACP,oBAAoBA,iBAAe,QAAQA,QAAU,MAAM,OAAOA,KAAG,CAAC,CAAC;EACzE;EACA,aAAa,WAAS2B,OAAK,QAAQ,MAAM,MAAMG,KAAG,CAAC;CACrD,GANY,EAAA,MAAA,qBAFA,EAAA,MAAA,mBADJ,EAAA,MAAA,e;CALV,IAAM,cAAcM,KAyBlBC;C,qDAAC,OAAA,OAAa,SAAmE;EAC/E,IAAM,UAAU,SAAS,QAAQ,IAAIP,KAAG;EACxC,IAAI,SACF,OAAO;EAET,IAAMQ,yBAAO,IAAI,IAAI,CAACR,KAAG,CAAC,GACpB,cAAc,YAAoB;GACtC,IAAM,WAAW,SAAS,QAAQ,IAAIA,KAAG;GAGzC,AAFI,YAAU,SAAS,QAAQ,IAAI,SAAS,QAAQ,GACpD,OAAK,IAAI,OAAO,GAChB,WAAW,WAAS,CAAC,GAAGH,QAAM,OAAO,CAAC;EACxC;EACA,WAAW,WAAS,CAAC,GAAGA,QAAMG,KAAG,CAAC;EAClC,IAAMS,WAAS,KAAK,UAAU,CAAC,CAAC,cAAc;GAC5C,KAAK,IAAM,SAASD,QAAM,SAAS,QAAQ,OAAO,KAAK;GACvD,WAAW,WAASX,OAAK,QAAQ,YAAU,CAACW,OAAK,IAAIE,OAAK,CAAC,CAAC;EAC9D,CAAC;EAED,OADA,SAAS,QAAQ,IAAIV,OAAKS,QAAM,GACzBA;CACT,G;CApBF,IAAM,UAAUE,KA8BdC;CAcY,AAAA,EAAA,QAAA,uBAAA,EAAA,QARgB,aAAA,EAAA,QAWd,mBAjBd,OAAC,UACC,QAAQZ,OAAK,OAAO,iBAAe;EACjC,IAAMJ,UAAQ,iBAAiB,QAAQ,MAAM,QAAMO,IAAE,SAASH,KAAG;EACjE,IAAI,CAACJ,SACH,MAAU,MAAM,qCAAqCI,MAAI,EAAE;EAE7D,IAAM,YAAY,MAAM,UAAU;GAChC,QAAQ;GACR,OAAOJ,QAAM;GACb,KAAKA,QAAM;GACX,0BAAS,IAAI,KAAK,EAAA,CAAE,YAAY;EAClC,CAAC;EACD,aAAW,SAAS;EACpB,IAAI;GACF,MAAM,oBAAoBI,KAAG;EAC/B,SAAS9B,KAAK;GAAL,IAAA,QAAA;GACP,IAAI;IAEF,AADA,MAAM,gBAAgB,OAAO,SAAS,GACtC,kBAAkB,WAAS2B,OAAK,QAAQ,QAAMM,IAAE,SAAS,SAAS,CAAC;GACrE,QAAQ;IACN,MAAM,mBAAmBjC,OAAK,QAAQ;GACxC;GACA,MAAMA;EACR;CACF,CAAC,GAVS,EAAA,MAAA,qBARgB,EAAA,MAAA,WAWd,EAAA,MAAA,iB;CAlBhB,IAAM,aAAa2C,KA8BjBC;CAiBc,AAAA,EAAA,QAAA,uBAAA,EAAA,QAHF,qBAAA,EAAA,QARkB,aAAA,EAAA,QAJZ,iBAFlB,OAAC,UACC,QAAQd,OAAK,OAAO,iBAAe;EACjC,IAAMJ,UAAQ,cAAc,MAAM,QAAMO,IAAE,SAASH,KAAG;EACtD,IAAI,CAACJ,SACH,MAAU,MAAM,6BAA6BI,MAAI,EAAE;EAErD,IAAM,cAAc,MAAM,UAAU;GAClC,QAAQ;GACR,OAAOJ,QAAM;GACb,KAAKA,QAAM;GACX,0BAAS,IAAI,KAAK,EAAA,CAAE,YAAY;EAClC,CAAC;EACD,aAAW,WAAW;EACtB,IAAI;GACF,MAAM,kBAAkBI,KAAG;EAC7B,SAAS9B,KAAK;GAAL,IAAA,QAAA;GACP,IAAI;IACF,MAAM,oBAAoB,WAAW;GACvC,QAAQ;IACN,MAAM,mBAAmBA,OAAK,UAAU;GAC1C;GACA,MAAMA;EACR;CACF,CAAC,GANW,EAAA,MAAA,qBAHF,EAAA,MAAA,mBARkB,EAAA,MAAA,WAJZ,EAAA,MAAA,e;CAHpB,IAAM,eAAe6C,KA6BnBC;CAMY,AAAA,EAAA,QAAA,uB,eANZ,YACE,qBAAqB,YAAY;EAE/B,IAAMnC,WAAS,iBAAiB;EAChC,eAAeA,UAAQ,aAAa,SAAS,aAAa,OAAO;EACjE,IAAI;GACF,MAAM,qBAAqB,aAAa,OAAO;EACjD,SAASX,KAAK;GAAL,IAAA,QAAA;GAEP,MADA,eAAeW,UAAQ,aAAa,SAASA,QAAM,GAC7CX;EACR;EAEA,AADA,iBAAiB,UAAU,aAAa,SACxC,SAAS,YAAY;CACvB,CAAC,GAPS,EAAA,MAAA,sB;CAPd,IAAM,eAAe+C,KA0BX,MAAA,eAAe,GARlBC;CAAP,OAOE,EAAA,QAAA,gBAAA,EAAA,QAHA,eAAA,EAAA,QAQA,oBAAA,EAAA,QAHA,YAAA,EAAA,QAIA,SAAA,EAAA,QAHA,UAAA,EAAA,QATAlC,aAAAA,EAAAA,QACA,aAAA,EAAA,QASA,kBAAA,EAAA,QANA,cAAA,EAAA,QAGQmC,OAAAA,EAAAA,QAFR,gBAAA,EAAA,QAHA,eAHK,MAAA;EACL,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,QAAQA;EACR;EACA;EACA;EACA;EACA;CACF,GAPE,EAAA,MAAA,cAHA,EAAA,MAAA,aAQA,EAAA,MAAA,kBAHA,EAAA,MAAA,UAIA,EAAA,MAAA,OAHA,EAAA,MAAA,QATAnC,EAAAA,MAAAA,WACA,EAAA,MAAA,WASA,EAAA,MAAA,gBANA,EAAA,MAAA,YAGQmC,EAAAA,MAAAA,KAFR,EAAA,MAAA,cAHA,EAAA,MAAA,a,4BAHKD;AAeT;AApOqC,SAAA,OAAC,SAAA;CAAUE,OAAAA,UAAQ;;AARpC,SAAAK,SAAC,OAAA;CAAU,OAAA,QAAQ;;AAVc,SAAAD,SAAC,GAAG,GAAM;CACzD,OAAO,IAAI,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ;AAC/E;AA/DyC,SAAAD,UAAA,CAAA;;AEvP7C,SAAS,YAAY,OAAsC;C,cAClDG;CAAP,OAAmB,EAAA,OAAA,Q,aAAZ,KAAA,oBAAC,QAAD;EAAQ,GAAI;EAAO,WAAW;CAAc,CAAA,GAAhC,EAAA,KAAA,O,YAAZA;AACT;AAEA,SAAS,gBAAgB,OAAoC;C,cAEzDC;CADF,OAEQ,EAAA,OAAA,Q,aADN,KAAA,oBAAC,MAAD;EACE,GAAI;EACJ,eAAc;EACd,WAAU;EACV,UAAU;EACV,UAAS;EACT,WAAW;CACZ,CAAA,GANK,EAAA,KAAA,O,YADNA;AASJ;AAEA,SAAS,UAAU,OAAmC;C,cAC7CC;CAAP,OAAgB,EAAA,OAAA,Q,aAAT,KAAA,oBAAC,KAAD;EAAK,GAAI;EAAO,WAAU;EAAK,UAAU;EAAG,UAAS;EAAO,WAAW;CAAY,CAAA,GAA1E,EAAA,KAAA,O,YAATA;AACT;AAEA,SAAgB,YAAA,IAgBC;C,gBAhBW,EAC1B,KACA,iBACA,uBACA,cACA,eACA,aACA,aAAA,OAP0BC,IAO1B,cAAA,OAAA,KAAA,KAAAC,IAWM,QAAQ,SAAS,GACjB,EAAC,WAAW,aAAa,SAAS,aAAa,YAAY,cAAc,WAC7E,gBAAgB,GACZ,EAAC,MAAK,eAAe,qBAAqB,GACXC;;EACnC,OAAO;EACP,KAAK;EACL,MAAM;EACN,MAAM;EACN,QAAQ;EACR,QAAQ;CACV,G;CAPA,IAAM,aAAa,kBAAkBA,EAOpC,GACK,CAAC,YAAY,iBAAiB,SAAwB,IAAI,GAC1D,CAAC,cAAc,mBAAmB,SAAS,EAAE,GAC8BC;C,oDAAC,KAAA,CAAA,G;CAAlF,IAAM,CAAC,kBAAkB,uBAAuB,SAAiCA,EAAE,GAC7E,CAAC,aAAa,kBAAkB,SAAS,EAAE,GAC3C,CAAC,aAAa,kBAAkB,SAAsB,KAAK,GAC3D,CAAC,aAAa,kBAAkB,SAA6B,GAAG,GACCC;C,oDAAC,KAAA,CAAA,G;CAAxE,IAAM,CAAC,oBAAoB,yBAAyB,SAAmBA,EAAE,GACnE,CAAC,kBAAkB,uBAAuB,SAA6B,IAAI,GAElDC;CAEY,AAAA,EAAA,OAAA,iBAAA,EAAA,OAAd,gBAAA,EAAA,OA2BoB,cAAA,EAAA,OA3BhC,eAAA,EAAA,OAKS,mBAAA,EAAA,OAFJC,WAAAA,EAAAA,OAgCZ,aAAA,EAAA,QATG,KAAA,EAAA,QAHT,SAzB2B,KAAA,YAAY;EAEzC,IAAM,SAAS,YAAY,cAAc,aAAa;EAatD,IAVoB,SAAS,MAAM,MAAM;GACvC,IAAI,EAAE,QAAQ,OAAO;GACrB,IAAM,gBAAgB,gBAAgB,EAAE,GAAG;GAC3C,OACE,iBACA,cAAc,UAAU,gBACxB2D,OAAQ,cAAc,QAAQ,aAAa;EAE/C,CAAC,GAEgB;GACf,IAAM,iBAAiB,SAAS,MAAM,QAAM;IAC1C,IAAI1D,IAAE,QAAQ,OAAO;IACrB,IAAMC,kBAAgB,gBAAgBD,IAAE,GAAG;IAC3C,OACEC,mBACAA,gBAAc,UAAU,gBACxByD,OAAQzD,gBAAc,QAAQ,aAAa;GAE/C,CAAC;GACD,MAAM,KAAK;IACT,UAAU;IACV,QAAQ;IACR,OAAO,EAAE,0BAA0B;IACnC,aAAa,GAAG,gBAAgB,MAAM,KAAK,WAAW,OAAO,IAAI,KAAK,gBAAgB,WAAW,EAAE,CAAC;GACtG,CAAC;EAEH,OAEA,IAAK,QAEL,IAAI;GAQF,AAPA,MAAM,UAAU;IACd,QAAQ;IACR,KAAK;IACL,0BAAS,IAAI,KAAK,EAAA,CAAE,YAAY;IAChC,OAAO,EAAE,sBAAsB;GACjC,CAAC,GACD,eAAe,MAAM,GACrB,MAAM,KAAK;IACT,UAAU;IACV,QAAQ;IACR,OAAO,EAAE,oBAAoB;GAC/B,CAAC;EACH,SAASC,IAAK;GAAL,IAAA,MAAA;GACP,MAAM,KAAK;IACT,UAAU;IACV,QAAQ;IACR,OAAO,EAAE,kBAAkB;IAC3B,aAAa,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;GAC9D,CAAC;EACH;CACF,GAvD2C,EAAA,KAAA,eAAd,EAAA,KAAA,cA2BoB,EAAA,KAAA,YA3BhC,EAAA,KAAA,aAKS,EAAA,KAAA,iBAFJH,EAAAA,KAAAA,SAgCZ,EAAA,KAAA,WATG,EAAA,MAAA,GAHT,EAAA,MAAA,O;CAzBJ,IAAM,aAAaI,IAqEkBC;C,qDAAC,MAAA,UAAuB;EAC3D,oBAAoB,KAAK;CAC3B,G;CAFA,IAAM,mBAAmBC,IAImBC;CACrC,AAAA,EAAA,QAAA,oBAAA,EAAA,QAKG,cAAA,EAAA,QAIG,KAAA,EAAA,QAHT,SAPwC,KAAA,YAAY;EACtD,IAAK,kBAEL;OAAI;IAIF,AADA,MAAM,WAAW,iBAAiB,IAAI,GACtC,MAAM,KAAK;KACT,UAAU;KACV,QAAQ;KACR,OAAO,EAAE,2BAA2B;IACtC,CAAC;GACH,SAASJ,IAAK;IAAL,IAAA,QAAA;IACP,MAAM,KAAK;KACT,UAAU;KACV,QAAQ;KACR,OAAO,EAAE,kBAAkB;KAC3B,aAAaA,iBAAe,QAAQA,MAAI,UAAU,OAAOA,KAAG;IAC9D,CAAC;GACH;GACA,oBAAoB,IAAI;EADxB;CAEF,GApBO,EAAA,MAAA,kBAKG,EAAA,MAAA,YAIG,EAAA,MAAA,GAHT,EAAA,MAAA,O;CAPJ,IAAM,0BAA0BK,IAwB9BC;CAqBwD,AAAA,EAAA,QAAA,cAAA,EAAA,QAjBjC,mBAAA,EAAA,QACUC,WAAAA,EAAAA,QAepB,KAAA,EAAA,QAHT,SAAA,EAAA,QAcM,gBA/BV,KAAA,OAAO,YAAuB;EAC5B,uBAAuB,SAAS,CAAC,GAAG,MAAMC,QAAM,IAAI,CAAC;EACrD,IAAM,qBACJ,uBAAuB,WAASC,OAAK,QAAQ,QAAQ,QAAQD,QAAM,IAAI,CAAC,GACpE,eAAe,gBAAgBA,QAAM,GAAG,GACxC,yBAAyB,SAAS,MAAM,kBAAkB;GAE9D,IADI,cAAc,SAASA,QAAM,QAC7B,cAAc,QAAQ,OAAO;GACjC,IAAM,mBAAmB,gBAAgB,cAAc,GAAG;GAC1D,OACE,gBACA,oBACA,iBAAiB,UAAU,aAAa,SACxCgD,OAAQ,iBAAiB,QAAQ,aAAa,MAAM;EAExD,CAAC;EACD,IAAI,wBASF,AARA,MAAM,KAAK;GACT,UAAU;GACV,QAAQ;GACR,OAAO,EAAE,0BAA0B;GACnC,aAAa,GAAG,uBAAuB,MAAM,KAAK,WAAW,OAC3D,IAAI,KAAK,uBAAuB,WAAW,EAAE,CAC/C;EACF,CAAC,GACD,aAAa;OAIf;OAAI;IAGF,AADA,MAAM,aAAahD,QAAM,IAAI,GAC7B,MAAM,KAAK;KACT,UAAU;KACV,QAAQ;KACR,OAAO,EAAE,6BAA6B;IACxC,CAAC;GACH,SAASR,IAAK;IAAL,IAAA,QAAA;IACP,MAAM,KAAK;KACT,UAAU;KACV,QAAQ;KACR,OAAO,EAAE,kBAAkB;KAC3B,aAAaA,iBAAe,QAAQA,MAAI,UAAU,OAAOA,KAAG;IAC9D,CAAC;GACH;GACA,aAAa;EADb;CAEF,GAzBwD,EAAA,MAAA,YAjBjC,EAAA,MAAA,iBACUO,EAAAA,MAAAA,SAepB,EAAA,MAAA,GAHT,EAAA,MAAA,OAcM,EAAA,MAAA,c;CAhCZ,IAAM,qBAAqBG,IAoDzBC;CAyBa,AAAA,EAAA,QAAA,KAAA,EAAA,QAHT,SAAA,EAAA,QAjBM,eALV,KAAA,OAAO,SAAoB,aAAqB;EAE9C,AADA,cAAc,IAAI,GAClB,qBAAqB,YAAU;GAAC,GAAGF;IAAOD,QAAM,OAAO;EAAQ,EAAE;EAEjE,IAAI;GAMF,AALA,MAAM,YAAY;IAChB,GAAGA;IACH,OAAO;GACT,CAAC,GAED,qBAAqB,WAAS;IAC5B,IAAMI,SAAO,EAAC,GAAGH,OAAI;IAErB,OADA,OAAOG,OAAKJ,QAAM,OACXI;GACT,CAAC;EACH,SAASZ,KAAK;GAAL,IAAA,QAAA;GAOP,AALA,qBAAqB,WAAS;IAC5B,IAAM,OAAO,EAAC,GAAGS,OAAI;IAErB,OADA,OAAO,KAAKD,QAAM,OACX;GACT,CAAC,GACD,MAAM,KAAK;IACT,UAAU;IACV,QAAQ;IACR,OAAO,EAAE,kBAAkB;IAC3B,aAAaR,MAAI;GACnB,CAAC;EACH;CACF,GAJa,EAAA,MAAA,GAHT,EAAA,MAAA,OAjBM,EAAA,MAAA,a;CANZ,IAAM,kBAAkBa,IAmCtBC;CAC2C,AAAA,EAAA,QAAA,iBAAA,EAAA,QAAd,gBAAA,EAAA,QA4BoB,cAAA,EAAA,QA5BhC,eAAA,EAAA,QAMS,mBAAA,EAAA,QAHJjB,WAAAA,EAAAA,QAwBT,KAAA,EAAA,QAHT,SAAA,EAAA,QAYM,eArCV,MAAA,OAAO,YAAuB;EAC5B,IAAMkB,WAAS,YAAY,cAAc,aAAa;EActD,IAXoB,SAAS,MAAM,QAAM;GAEvC,IAAIjB,IAAE,SAASU,QAAM,MAAM,OAAO;GAClC,IAAMT,kBAAgB,gBAAgBD,IAAE,GAAG;GAC3C,OACEC,mBACAA,gBAAc,UAAU,gBACxByD,OAAQzD,gBAAc,QAAQ,aAAa;EAE/C,CAAC,GAEgB;GACf,IAAMkB,mBAAiB,SAAS,MAAM,QAAM;IAC1C,IAAInB,IAAE,SAASU,QAAM,MAAM,OAAO;IAClC,IAAMT,kBAAgB,gBAAgBD,IAAE,GAAG;IAC3C,OACEC,mBACAA,gBAAc,UAAU,gBACxByD,OAAQzD,gBAAc,QAAQ,aAAa;GAE/C,CAAC;GACD,MAAM,KAAK;IACT,UAAU;IACV,QAAQ;IACR,OAAO,EAAE,0BAA0B;IACnC,aAAa,GAAGkB,kBAAgB,MAAM,KAAK,WAAW,OACpD,IAAI,KAAKA,kBAAgB,WAAW,EAAE,CACxC;GACF,CAAC;EAEH,OAEA,IAAI;GAOF,AANA,MAAM,YAAY;IAChB,GAAGT;IACH,KAAKO;IACL,0BAAS,IAAI,KAAK,EAAA,CAAE,YAAY;GAClC,CAAC,GACD,eAAeA,QAAM,GACrB,MAAM,KAAK;IACT,UAAU;IACV,QAAQ;IACR,OAAO,EAAE,oBAAoB;GAC/B,CAAC;EACH,SAASf,KAAK;GAAL,IAAA,QAAA;GACP,MAAM,KAAK;IACT,UAAU;IACV,QAAQ;IACR,OAAO,EAAE,kBAAkB;IAC3B,aAAaA,MAAI;GACnB,CAAC;EACH;CACF,GAvD2C,EAAA,MAAA,eAAd,EAAA,MAAA,cA4BoB,EAAA,MAAA,YA5BhC,EAAA,MAAA,aAMS,EAAA,MAAA,iBAHJH,EAAAA,MAAAA,SAwBT,EAAA,MAAA,GAHT,EAAA,MAAA,OAYM,EAAA,MAAA,a;CAtCZ,IAAM,eAAeqB,KAwIdC,IADFC,IApDFC,IAqDmBC,KAAiBC,KAC9BC,KAFSC,KAnDdC;CAoEoB,IAAA,EAAA,QAAA,eAAA,EAAA,QAN2C,iBAAA,EAAA,QAA3C,gBAAA,EAAA,QA0IiB,eAAA,EAAA,QArGpB,cAAA,EAAA,QAM+B,gBAAA,EAAA,QA6K7B,cAAA,EAAA,QAhOI,mBAAA,EAAA,QAzCG,cAAA,EAAA,QA4FG,mBAAA,EAAA,QAmFQ,sBAAA,EAAA,QA8Jd,gBAAA,EAAA,QA7ND,oBAAA,EAAA,QA1IqB,sBAAA,EAAA,QAAxBC,WAAAA,EAAAA,QAKnB,eAAA,EAAA,QAoBgB,UAAA,EAAA,QAtB2C,eAAA,EAAA,QAmElC,eAAA,EAAA,QAsBX,yBAAA,EAAA,QAvEU,GAAA;EAnB5B,IAAM,mBAFiB,SAAS,QAAQ,QAAM,CAAC,mBAAmB,SAAS7B,IAAE,IAAI,CAAC,EAAA,EAE1C,QAAQ,QAAM;GACpD,IAAM,iBAAiBA,IAAE,SAAS,GAAA,CAAI,YAAY,CAAC,CAAC,SAAS,YAAY,YAAY,CAAC,GAChF,gBACJ,gBAAgB,SACf,gBAAgB,cAAc,CAACA,IAAE,UACjC,gBAAgB,YAAYA,IAAE;GACjC,OAAO,iBAAiB;EAC1B,CAAC;EAGE,KAAA;EASyB8B,IAAAA;E,6BAAE,MAAA,EAAA,qBAAqB,GAAvB,EAAA,MAAA,G;EAApBC,IAAAA;EAAoBD,AAAAA,EAAAA,QAAAA,M,eAApB,MAAA,oBAAC,aAAD;GAAa,OAAA;GAAOA,UAAAA;EAAsC,CAAA,GAAtCA,EAAAA,MAAAA,K;EAENE,IAAAA;E,6BAAE,MAAA,EAAA,mBAAmB,GAArB,EAAA,MAAA,G;EAGHC,IAAAA;EAAW,AAAA,EAAA,QAAA,a,eAAX,YAAM,KAAK,WAAW,GAAX,EAAA,MAAA,Y;EAJtBC,IAAAA;EAGY,AAAA,EAAA,QAAA,UAAA,EAAA,QAFEF,OAAAA,EAAAA,QAGHC,OAJX,MAAA,oBAAC,QAAD;GACE,cAAYD;GACZ,MAAM;GACN,UAAU;GACV,SAASC;GACT,MAAK;EACN,CAAA,GAHW,EAAA,MAAA,QAFED,EAAAA,MAAAA,KAGHC,EAAAA,MAAAA,K;EAZbE,IAAAA;EAOEJ,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QACAG,OARF,MAAA,qBAAC,MAAD;GACE,SAAS;GACT,YAAY;GACZ,eAAe;GACf,gBAAe;GACf,YAAW;GALb,UAAA,CAOEH,KACAG,GAOI;E,IARJH,EAAAA,MAAAA,KACAG,EAAAA,MAAAA,K;EAUeE,IAAAA;E,6BAAE,MAAA,EAAA,sBAAsB,GAAxB,EAAA,MAAA,G;EAGHC,IAAAA;E,qDAAC,OAAA,UAAU,eAAe,MAAM,cAAc,KAAK,G;EALjEC,IAAAA;EAIW,AAAA,EAAA,QAAA,eAAA,EAAA,QAFMF,OAFjB,MAAA,oBAAC,KAAD;GAAK,SAAS;GAAG,YAAY;GAC3B,UAAA,oBAAC,WAAD;IACE,aAAaA;IACb,MAAM;IACN,OAAO;IACP,UAAUC;GACX,CAAA;EACE,CAAA,GAHM,EAAA,MAAA,aAFMD,EAAAA,MAAAA,K;EAWJG,IAAAA;E,6BAAE,MAAA,EAAA,WAAW,GAAb,EAAA,MAAA,G;EACG,IAAA,MAAA,gBAAgB,OACjBC;E,qDAAM,YAAA,eAAe,KAAK,G;EALrCC,IAAAA;EAGSF,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QACGG,OAJZ,MAAA,oBAAC,KAAD;GACE,IAAG;GACH,iBAAc;GACd,OAAOH;GACP,UAAUG;GACV,SAASF;EACV,CAAA,GAHQD,EAAAA,MAAAA,KACGG,EAAAA,MAAAA,K;EAMHC,IAAAA;E,6BAAE,MAAA,EAAA,gBAAgB,GAAlB,EAAA,MAAA,G;EACG,IAAA,MAAA,gBAAgB,YACjBC;E,qDAAM,YAAA,eAAe,UAAU,G;EAL1CC,IAAAA;EAGSF,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,SACGG,OAJZ,MAAA,oBAAC,KAAD;GACE,IAAG;GACH,iBAAc;GACd,OAAOH;GACP,UAAUG;GACV,SAASF;EACV,CAAA,GAHQD,EAAAA,MAAAA,KACGG,EAAAA,OAAAA,K;EAMHC,IAAAA;E,+BAAE,MAAA,EAAA,cAAc,GAAhB,EAAA,OAAA,G;EACG,IAAA,MAAA,gBAAgB,UACjBC;E,sDAAM,YAAA,eAAe,QAAQ,G;EALxCC,IAAAA;EAGSF,AAAAA,EAAAA,SAAAA,OAAAA,EAAAA,SACGG,OAJZ,MAAA,oBAAC,KAAD;GACE,IAAG;GACH,iBAAc;GACd,OAAOH;GACP,UAAUG;GACV,SAASF;EACV,CAAA,GAHQD,EAAAA,OAAAA,KACGG,EAAAA,OAAAA,K;EApBhBC,IAAAA;E,AAEIV,EAAAA,SAAAA,OAAAA,EAAAA,SAOAI,OAAAA,EAAAA,SAOAI,OAhBJ,MAAA,oBAAC,KAAD;GAAK,UAAU;GAAG,eAAe;GAC/B,UAAA,qBAAC,SAAD;IAAS,KAAK;IAAd,UAAA;KACER;KAOAI;KAOAI;IAOO;;EACN,CAAA,GAtBDR,EAAAA,OAAAA,KAOAI,EAAAA,OAAAA,KAOAI,EAAAA,OAAAA,K,8BAxCJd,EAAAA,SAAAA,OAAAA,EAAAA,SAgBAG,OAAAA,EAAAA,SAQAa,OAzBF,MAAA,qBAAC,aAAD;GAAa,KAAK;GAAlB,UAAA;IACEhB;IAgBAG;IAQAa;GAyBW;E,IAjDXhB,EAAAA,OAAAA,KAgBAG,EAAAA,OAAAA,KAQAa,EAAAA,OAAAA,K,8BA0BD,KAAA,WAAa,MAAA,4BACX,KAAA,MAAe,MAAA,GAAiB,MAAA,UAC9B,MAAA,iBAAiB,KAAK,KAAG,UAAU;GAClC,IAAM,WAAW,gBAAgBnD,IAAE,GAAG,GAChC,mBAAmB,UAAU,SAAS,IACtC,oBAAoB,iBAAiB,MAAM,GAAG,CAAC,CAAC,IAChD,aAAa,gBAAgBA,IAAE,KAC/B,iBAAiB,CAACA,IAAE,UAAUA,IAAE,sBAGhC,kBACJ,YAAY,iBAAiB,SAAS,SAAS0D,OAAQ,eAAe,SAAS,MAAM,GAEjF,WAAW,cAAc,CAAC,mBAAmB;GACnD,OACE,oBAAC,MAAD;IAEE,UAAU,cAAc,IAAI;IAC5B,UAAU,cAAc,IAAI;IAC5B,MAAK;IACL,UAAU,YAAU;KAElB,IADeN,QAAM,QACT,QAAQ,+BAA6B,GAC/C;KAEF,eAAepD,IAAE,GAAG;KACpB,IAAM,YAAY,gBAAgBA,IAAE,GAAG;KACvC,AAAI,aACF,sBAAsB,SAAS;IAEnC;IACA,OAAO;KACL,WAAW,UAAU,IAAI,uCAAuC,KAAA;KAChE,UAAU;KACV,cAAc;KACd,YAAY,aACR,yCACA;KACJ,QAAQ;IACV;IAEA,UAAA,qBAAC,QAAD;KAAQ,KAAK,cAAc,IAAI;KAA/B,UAAA;MACE,qBAAC,MAAD;OACE,gBAAe;OACf,YAAY;OACZ,OAAO,EAAC,WAAW,OAAM;OAH3B,UAAA,CAKE,qBAAC,MAAD;QAAM,YAAW;QAAS,KAAK;QAAG,cAAc;QAAG,OAAO,EAAC,MAAM,EAAC;QAAlE,UAAA,CACG,eAAeA,IAAE,OAChB,oBAAC,WAAD;SACE,OAAO;SACP,WAAW,YAAU,gBAAgBoD,QAAM,cAAc,KAAK;SAC9D,YAAY,YAAU;UACpB,AAAIA,QAAM,QAAQ,UACX,gBAAgBpD,KAAG,YAAY,IAC3BoD,QAAM,QAAQ,YACvB,cAAc,IAAI;SAEtB;SACA,cAAc,gBAAgBpD,KAAG,YAAY;SAC7C,WAAA;SACA,OAAO;UAAC,UAAU;UAAS,QAAQ;SAAM;QAC1C,CAAA,IAED,oBAAC,MAAD;SACE,QAAO;SACP,MAAM,cAAc,IAAI;SACxB,cAAa;SACb,OAAO;UACL,UAAU,cAAc,UAAU;UAClC,QAAQ,iBAAiB,YAAY;UACrC,SAAS;SACX;SACA,OACE,iBAAiBA,IAAE,SACnBA,IAAE,SACFA,IAAE,KAAK,MAAMA,IAAE,KAAK,SAAS,GAAGA,IAAE,KAAK,MAAM;SAE/C,SACE,uBACU;UAEJ,AADA,cAAcA,IAAE,IAAI,GACpB,gBAAgBA,IAAE,SAASA,IAAE,KAAK,MAAM,GAAG,CAAC,CAAC;SAC/C,IACA,KAAA;SAGL,UAAA,iBAAiBA,IAAE,SAClBA,IAAE,SACFA,IAAE,KAAK,MAAMA,IAAE,KAAK,SAAS,GAAGA,IAAE,KAAK,MAAM;QAC3C,CAAA,GAEP,YACC,oBAAC,KAAD,EACE,OAAO;SACL,OAAO;SACP,QAAQ;SACR,cAAc;SACd,iBAAiB;QACnB,EACD,CAAA,CAEC;OACN,CAAA,GAAA,oBAAC,MAAD;QAAM,YAAW;QAAS,KAAK;QAC7B,UAAA,oBAAC,KAAD;SACE,sBAAmB;SACnB,OAAO;UACL,OAAO;UACP,QAAQ;UACR,SAAS;UACT,YAAY;SACd;SAEE,WAAA,CAACA,IAAE,UAAU,mBACb,oBAAC,YAAD;UACE,QAAQ,oBAAC,mBAAD,CAAoB,CAAA;UAC5B,IAAI,GAAGA,IAAE,KAAK;UACd,MACE,qBAAC,MAAD,EAAA,UAAA;WACG,CAACA,IAAE,UACF,oBAAC,UAAD;YACE,MAAM;YACN,SAAS;YACT,MAAM,EAAE,aAAa;YACrB,UAAU,YAAU;aAElB,AADA,QAAM,gBAAgB,GACtB,iBAAiBA,GAAC;YACpB;WACD,CAAA;WAEFA,IAAE,UAAU,kBACX,oBAAC,UAAD;YACE,MAAM;YACN,SAAS;YACT,MAAM,EAAE,gBAAgB;YACxB,UAAU,YAAU;aAEb,AADL,QAAM,gBAAgB,GACjB,mBAAmBA,GAAC;YAC3B;WACD,CAAA;WAEF,kBACC,oBAAC,UAAD;YACE,MAAK;YACL,SAAS;YACT,MAAM;YACN,MAAM,EAAE,eAAe;YACvB,UAAU,YAAU;aAEb,AADL,QAAM,gBAAgB,GACjB,YAAYA,IAAE,IAAI;YACzB;WACD,CAAA;UAEC,EAAA,CAAA;UAER,SAAS;WACP,SAAS;WACT,QAAQ;WACR,WAAW;WACX,MAAM;UACR;SACD,CAAA;QAEA,CAAA;OACD,CAAA,CACF;;MAEL,mBACC,oBAAC,SAAD;OACE,SAAA;OACA,SACE,oBAAC,KAAD;QACE,SAAS;QACT,OAAO;SAAC,UAAU;SAAS,WAAW;SAAS,UAAU;QAAM;QAE/D,UAAA,oBAAC,MAAD;SAAM,MAAM;SAAI,UAAA;QAAuB,CAAA;OACpC,CAAA;OAEP,WAAU;OACV,QAAA;OAEA,UAAA,oBAAC,MAAD;QAAM,MAAM;QAAI,UAAA;OAAwB,CAAA;MACjC,CAAA,IAET,oBAAC,MAAD,CAAO,CAAA;MAGR,cACC,qBAAC,QAAD;OAAQ,KAAK;OAAG,OAAO;QAAC,YAAY;QAAG,WAAW;OAAM;OAAxD,UAAA,CACE,qBAAC,MAAD;QAAM,YAAW;QAAS,KAAK;QAAG,OAAO,EAAC,WAAW,OAAM;QAA3D,UAAA,CACE,oBAAC,KAAD;SACE,OAAO;UACL,SAAS;UACT,YAAY;UACZ,gBAAgB;UAChB,OAAO;UACP,QAAQ;SACV;SAECA,UAAAA,IAAE,SACD,oBAAC,YAAD;UAAY,MAAM;UAAG,MAAMA,IAAE,YAAY;UAAI,aAAA;SAAa,CAAA,IAE1D,oBAAC,KAAD;UACE,OAAO;WACL,SAAS;WACT,YAAY;WACZ,gBAAgB;WAChB,YAAY;WACZ,OAAO;UACT;UAEA,UAAA,oBAAC,UAAD,CAAW,CAAA;SACR,CAAA;QAEJ,CAAA,GACL,oBAAC,OAAD;SACE,MAAMA,IAAE,SAAS,YAAY;SAC7B,OAAO;UACL,YAAY;UACZ,UAAU;UACV,cAAc;SAChB;SAECA,UAAAA,IAAE,SAAS,EAAE,cAAc,IAAI,EAAE,gBAAgB;QAC7C,CAAA,CACH;OACN,CAAA,GAAA,oBAAC,MAAD;QAAM,MAAM;QAAG,OAAA;QACZ,UAAA,WAAW,OAAO,IAAI,KAAKA,IAAE,WAAW,EAAE,CAAC;OACxC,CAAA,CACA;MAER,CAAA,IAAA,qBAAC,MAAD;OACE,YAAW;OACX,KAAK;OACL,OAAO;QAAC,YAAY;QAAO,WAAW;OAAM;OAH9C,UAAA;QAKE,oBAAC,KAAD;SACE,OAAO;UACL,SAAS;UACT,YAAY;UACZ,gBAAgB;UAChB,OAAO;UACP,QAAQ;SACV;SAECA,UAAAA,IAAE,SACD,oBAAC,YAAD;UAAY,MAAM;UAAG,MAAMA,IAAE,YAAY;UAAI,aAAA;SAAa,CAAA,IAE1D,oBAAC,KAAD;UACE,OAAO;WACL,SAAS;WACT,YAAY;WACZ,gBAAgB;WAChB,YAAY;WACZ,OAAO;UACT;UAEA,UAAA,oBAAC,UAAD,CAAW,CAAA;SACR,CAAA;QAEJ,CAAA;QACL,oBAAC,OAAD;SACE,MAAMA,IAAE,SAAS,YAAY;SAC7B,OAAO;UACL,YAAY;UACZ,UAAU;UACV,cAAc;SAChB;SAECA,UAAAA,IAAE,SAAS,EAAE,cAAc,IAAI,EAAE,gBAAgB;QAC7C,CAAA;QACP,oBAAC,MAAD;SAAM,MAAM;SAAG,OAAA;SACb,UAAA;QACI,CAAA;QACN,oBAAC,MAAD;SAAM,MAAM;SAAG,OAAA;SACZ,UAAA,WAAW,OAAO,IAAI,KAAKA,IAAE,WAAW,EAAE,CAAC;QACxC,CAAA;OACF;;MAGP,YACC,oBAAC,QAAD;OACE,MAAK;OACL,MAAK;OACL,SAAS;OACT,OAAO;QACL,QAAQ;QACR,UAAU;QACV,OAAO;QACP,QAAQ;QACR,UAAU;OACZ;OACA,MAAM,EAAE,eAAe;OACvB,UAAU,MAAM;QAET,AADL,EAAE,gBAAgB,GACb,aAAaA,GAAC;OACrB;MACD,CAAA;KAEG;;GACJ,GA5RCA,IAAE,IA4RH;EAEV,CAAC,GA7Re,EAAA,MAAA,aAN2C,EAAA,MAAA,eAA3C,EAAA,MAAA,cA0IiB,EAAA,MAAA,aArGpB,EAAA,MAAA,YAM+B,EAAA,MAAA,cA6K7B,EAAA,MAAA,YAhOI,EAAA,MAAA,iBAzCG,EAAA,MAAA,YA4FG,EAAA,MAAA,iBAmFQ,EAAA,MAAA,oBA8Jd,EAAA,MAAA,cA7ND,EAAA,MAAA,kBA1IqB,EAAA,MAAA,oBAAxB6B,EAAAA,MAAAA,SAKnB,EAAA,MAAA,aAoBgB,EAAA,MAAA,QAtB2C,EAAA,MAAA,aAmElC,EAAA,MAAA,aAsBX,EAAA,MAAA,uBAvEU,EAAA,MAAA,G;;CA4CtBwB,IAAAA;CAAChC,AAAAA,EAAAA,SAAAA,MAAAA,EAAAA,SAAeG,OAAAA,EAAAA,SAAiBC,OAAAA,EAAAA,SAC9BC,OADH,MAAA,oBAACL,IAAD;EAAM,UAAUG;EAAG,eAAcC;EAC9BC,UAAAA;CA6SG,CAAA,GA9SLL,EAAAA,OAAAA,IAAeG,EAAAA,OAAAA,KAAiBC,EAAAA,OAAAA,KAC9BC,EAAAA,OAAAA,K;CAFL4B,IAAAA;CAAChC,AAAAA,EAAAA,SAAAA,MAAAA,EAAAA,SAAaK,OAAAA,EAAAA,SACZ0B,OADF,MAAA,oBAAC/B,IAAD;EAAW,IAAGK;EACZ0B,UAAAA;CA+SS,CAAA,GAhTV/B,EAAAA,OAAAA,IAAaK,EAAAA,OAAAA,KACZ0B,EAAAA,OAAAA,K;CAgTDE,IAAAA;CAmB6B,AAAA,EAAA,SAAA,2BAAA,EAAA,SAnB7B,oBAAA,EAAA,SAKW,KALX,MAAA,oBACC,oBAAC,QAAD;EACE,SAAA;EACA,IAAG;EACH,OAAO;EACP,QAAQ,EAAE,aAAa;EACvB,eAAe,oBAAoB,IAAI;EACvC,QACE,qBAAC,MAAD;GAAM,gBAAe;GAAW,KAAK;GAAG,SAAS;GAAG,YAAW;GAA/D,UAAA,CACE,oBAAC,QAAD;IACE,MAAK;IACL,SAAS;IACT,MAAM,EAAE,qBAAqB;IAC7B,eAAe,oBAAoB,IAAI;GACxC,CAAA,GACD,oBAAC,QAAD;IACE,SAAS;IACT,MAAK;IACL,MAAM,EAAE,0BAA0B;IAClC,eAAe,KAAK,wBAAwB;GAC7C,CAAA,CACG;;EAGR,UAAA,oBAAC,KAAD;GAAK,SAAS;GACZ,UAAA,oBAAC,MAAD;IAAM,MAAM;IAAI,UAAA,EAAE,0BAA0B;GAAQ,CAAA;EACjD,CAAA;CACC,CAAA,GARoB,EAAA,OAAA,yBAnB7B,EAAA,OAAA,kBAKW,EAAA,OAAA,G;CA1WdC,IAAAA;CADF,OACGjC,EAAAA,SAAAA,MAAAA,EAAAA,SACCK,OAAAA,EAAAA,SAmDA0B,OAAAA,EAAAA,SAiTCC,OArWH,MAAA,qBAAChC,IAAD,EAAA,UAAA;EACEK;EAmDA0B;EAiTCC;CA6Bc,EAAA,CAAA,GAlYhBhC,EAAAA,OAAAA,IACCK,EAAAA,OAAAA,KAmDA0B,EAAAA,OAAAA,KAiTCC,EAAAA,OAAAA,K,8BArWHC;AAoYJ;AChtBA,SAAS,mBAA4B;CACnC,OAAO,OAAO,SAAW,OAAe,OAAO,aAAa;AAC9D;AAEA,SAAS,yBAAyB,QAA6C;CAC7E,IAAI,aAAa;CASjB,OAPA,AAEE,eACE,OAAO,SAAW,OAAe,OAAO,WAAa,MACjD,SAAS,KAAK,sBAAsB,CAAC,CAAC,SAAS,KAC/C,GAED;EACL,aAAa,cAAc,iBAAiB,IAAI,IAAI;EACpD,MAAM,aAAa,MAAM,KAAA,IAAY,aAAa;EAClD,aAAa,aAAa;EAC1B,SAAS,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,aAAa,CAAC,CAAC;EACpD,SAAS,aAAa,MAAM,aAAa,KAAM,aAAa;CAC9D;AACF;AAEA,SAAgB,YAAA,IAIb;C,cAJyB,EAC1B,kBAD0BG,IAKpB,CAAC,UAAU,eAAe,SAAmBC,OAGjD,GACI,CAAC,oBAAoB,yBAAyB,SAASC,QAAwB,GAC/E,CAAC,iBAAiB,sBAAsB,SAA0BC,QAExE,GAEUC,IAkBPC;CAlBH,AACOC,EAAAA,OAAAA,iB,yBADG,WAAM;EACd,IAAI,CAAC,cAAc,SACjB;EAEF,IAAM,gBAAgB,YAAmC;GACvD,IAAM,QAAQ,UAAU;GACxB,AAAI,UACF,YAAY;IAAC,OAAO,MAAM,YAAY;IAAO,QAAQ,MAAM,YAAY;GAAM,CAAC,GAC9E,sBAAsB,MAAM,YAAY,QAAQ,GAAG,GACnD,mBAAmB,yBAAyB,MAAM,YAAY,MAAM,CAAC;EAEzE,GACM,iBAAiB,IAAI,eAAe,YAAY;EAGtD,OAFA,eAAe,QAAQ,cAAc,OAAO,SAE/B;GACX,eAAe,WAAW;EAC5B;CACF,GAAG,KAAA,CAAC,aAAa,GAjBVA,EAAAA,KAAAA,e,uBADP,UAAUF,IAkBPC,EAAe;CAEXE,IAAAA;CAAP,OAAyB,EAAA,OAAA,sBAAA,EAAA,OAAjB,mBAAA,EAAA,OAAqC,YAAtC,KAAA;EAAC;EAAiB;EAAoB;CAAQ,GAA5B,EAAA,KAAA,oBAAjB,EAAA,KAAA,iBAAqC,EAAA,KAAA,U,wBAAtCA;AACT;AAzB0E,SAAAI,WAAA;CACtE,OAAA,yBAAyB,KAAA,CAAS;;AAFyB,SAAAD,WAAA;CAAM,OAAA,iBAAiB;;AAJjC,SAAAD,UAAA;CAAO,OAAA;EACxD,OAAO,OAAO,SAAW,MAAc,OAAO,aAAa;EAC3D,QAAQ,OAAO,SAAW,MAAc,OAAO,cAAc;CAC/D;;;;;;ACjBF,SAAgB,kBAAA,IAOW;C,eAPO,EAChC,gBACA,kBACA,iBACA,kBACA,mBACA,uBANgCG,IAQ1B,EAAC,MAAK,eAAe,qBAAqB,GAUjCC;C,0BAAE,KAAA,EAAA,kCAAkC,GAApC,EAAA,KAAA,G;CAFLC,IAAAA;CAEKD,AAAAA,EAAAA,OAAAA,K,aAFL,KAAA,oBAAC,MAAD;EAAM,QAAQ;EACZ,UAAA,oBAAC,MAAD;GAAM,MAAM;GAAG,OAAA;GACZA,UAAAA;EACG,CAAA;CACF,CAAA,GAFDA,EAAAA,KAAAA,I;CAaCE,IAAAA;C,oDAAC,KAAA,oBAAA,MAAD;EAAM,QAAQ;EACZ,UAAA,oBAAC,SAAD,EAAS,MAAM,CAAC,QAAQ,OAAO,EAAI,CAAA;CAC/B,CAAA,G;CASA,IAAA,KAAA,kBAAkB,WAAW,UACzB,KAAA,oBAAoB,CAAC,gBACzB,KAAA,kBAAkB,aAAa,WAC/BC;CAAkB,AAAA,EAAA,OAAA,mBAAA,EAAA,OAAA,KAAlB,KAAkB,EAAlB,kBAAoB,wBAA2B,sBAAsB,GAArE,EAAA,KAAA,iBAAkB,EAAA,KAAA,G;CAlB9BC,IAAAA;CAae,AAAA,EAAA,OAAA,oBAAA,EAAA,OAEHC,MAAAA,EAAAA,QACIC,MAAAA,EAAAA,QACJC,MAAAA,EAAAA,QACAJ,MAlBZ,KAAA,oBAAC,KAAD;EAAK,WAAU;EAAK,UAAU;EAC5B,UAAA,oBAAC,SAAD;GACE,SAAA;GACA,SACED;GAIF,WAAU;GACV,QAAA;GAEA,UAAA,oBAAC,QAAD;IACE,OAAM;IACN,SAAS;IACT,MAAK;IACL,MAAMG;IACN,UAAUC;IACV,MAAMC;IACN,MAAMJ;GACP,CAAA;EACM,CAAA;CACN,CAAA,GARU,EAAA,KAAA,kBAEHE,EAAAA,KAAAA,IACIC,EAAAA,MAAAA,IACJC,EAAAA,MAAAA,IACAJ,EAAAA,MAAAA,I;CASF,IAAA,KAAA,mBAAmB,WAAW,UAC9BK;CAAmB,AAAA,EAAA,QAAA,oBAAA,EAAA,QAAA,KAAnB,MAAmB,EAAnB,mBAAqB,yBAA4B,uBAAuB,GAAxE,EAAA,MAAA,kBAAmB,EAAA,MAAA,G;CAEf,IAAA,MAAA,CAAC,gBACL,MAAA,mBAAmB,aAAa,WAT1CC;CAGa,AAAA,EAAA,QAAA,qBAAA,EAAA,QAGHD,OAAAA,EAAAA,QAEIE,OAAAA,EAAAA,QACJC,OAAAA,EAAAA,QAJAC,MALV,MAAA,oBAAC,KAAD;EAAK,WAAU;EAAK,UAAU;EAAG,YAAY;EAC3C,UAAA,oBAAC,QAAD;GACE,OAAM;GACN,SAAS;GACT,MAAK;GACL,MAAMA;GACN,MAAMJ;GACN,MAAK;GACL,UAAUE;GACV,MAAMC;EACP,CAAA;CACE,CAAA,GARQ,EAAA,MAAA,mBAGHH,EAAAA,MAAAA,KAEIE,EAAAA,MAAAA,KACJC,EAAAA,MAAAA,KAJAC,EAAAA,MAAAA,I;CAOTC,IAAAA;CAI8B,AAAA,EAAA,QAAA,sBAAA,EAAA,QAAA,KAJ9B,MAAA,sBACC,oBAAC,KAAD;EAAK,YAAY;EAAG,YAAY;EAC9B,UAAA,oBAAC,SAAD;GACE,SAAA;GACA,SAAS,oBAAC,MAAD;IAAM,MAAM;IAAI,UAAA,EAAE,gCAAgC;GAAQ,CAAA;GACnE,WAAU;GACV,QAAA;GAEA,UAAA,oBAAC,QAAD;IACE,cAAY,EAAE,oBAAoB;IAClC,eAAY;IACZ,MAAM;IACN,MAAK;IACL,SAAS;IACT,MAAK;IACL,MAAK;GACN,CAAA;EACM,CAAA;CACN,CAAA,GAlBN,EAAA,MAAA,oBAI8B,EAAA,MAAA,G;CAvCjCC,IAAAA;CAuBEL,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QAYCI,OAAAA,EAAAA,QAlCDT,MADF,MAAA,qBAAC,MAAD;EAAM,gBAAe;EAArB,UAAA;GACEA;GAsBAK;GAYCI;EAoBG;C,IAhCJJ,EAAAA,MAAAA,KAYCI,EAAAA,MAAAA,KAlCDT,EAAAA,MAAAA,I;CAhBRW,IAAAA;CADF,OAakB,EAAA,QAAA,kBAAA,EAAA,QAGVD,OAAAA,EAAAA,QAVEb,MALR,MAAA,oBAAC,mBAAD,EAAA,UACE,oBAAC,MAAD;EAAM,SAAS;EAAG,UAAU;EAC1B,UAAA,oBAAC,SAAD;GACE,SAAA;GACA,SACEA;GAMF,WAAU;GACV,UAAU;GACV,QAAA;GAEAa,UAAAA;EAwDO,CAAA;CACL,CAAA,EACW,CAAA,GA7DH,EAAA,MAAA,gBAGVA,EAAAA,MAAAA,KAVEb,EAAAA,MAAAA,I,4BALRc;AA2EJ;;AExGA,SAAS,0BAA0B,OAAmC;C,cAC7DE;CAAP,OAAgB,EAAA,OAAA,Q,aAAT,KAAA,oBAAC,KAAD;EAAK,GAAI;EAAO,WAAW;CAA4B,CAAA,GAA9C,EAAA,KAAA,O,YAATA;AACT;AAEA,SAAS,uBAAuB,OAA4B;C,cACnDC;CAAP,OAAc,EAAA,OAAA,Q,aAAP,KAAA,oBAAC,KAAD;EAAG,GAAI;EAAO,WAAW;CAAyB,CAAA,GAA3C,EAAA,KAAA,O,YAAPA;AACT;AAEA,SAAS,IAAA,IAA8B;C,cAA1B,EAAC,SAADC,IAC0C,KAAA,oBAAoB,KAAK,cAAvEC;CAAP,OAAqDC,EAAAA,OAAAA,K,aAA9C,KAAA,oBAAC,OAAD;EAAK,WAAW;EAAK,OAAO,EAAC,iBAAiBA,GAAqC;CAAI,CAAA,GAAzCA,EAAAA,KAAAA,I,YAA9CD;AACT;AAIA,SAAgB,qBAAqB;C,eAC7B,CAAC,MAAM,WAAW,SAAS,EAAK,GAChC,YAAY,OAAiC,IAAI,GACjD,aAAa,OAA8B,IAAI,GAErBE;C,oDAAM,WAAA,QAAQC,OAAS,G;CAAvD,IAAM,cAAcC,IAEd,EAAC,MAAK,eAAe,qBAAqB,GAG9CC,IACAC;CAFF,A,oDACE,WAAM,QAAQ,EAAK,GACnB,WAAM,CAAC,UAAU,SAAS,WAAW,OAAO,G,gDAF9C,qBACED,IACAC,EACF;CASmCC,IAAAA;C,0BAAE,KAAA,EAAA,6BAA6B,GAA/B,EAAA,KAAA,G;CADzBC,IAAAA;CACyBD,AAAAA,EAAAA,OAAAA,K,aADzB,KAAA,oBAAC,QAAD;EAAQ,KAAK;EACX,UAAA,oBAAC,MAAD;GAAM,QAAO;GAAUA,UAAAA;EAAuC,CAAA;CACxD,CAAA,GADiBA,EAAAA,KAAAA,I;CAIVE,IAAAA;C,0BAAE,KAAA,EAAA,mCAAmC,GAArC,EAAA,KAAA,G;CADfC,IAAAA;CACeD,AAAAA,EAAAA,OAAAA,K,cADf,KAAA,oBAAC,MAAD,EAAA,UACE,oBAAC,MAAD;EAAM,OAAA;EAAOA,UAAAA;CAA6C,CAAA,EACtD,CAAA,GADSA,EAAAA,KAAAA,I;CAKcE,IAAAA;C,4BAAE,KAAA,EAAA,WAAW,GAAb,EAAA,MAAA,G;CADzBC,IAAAA;CACyBD,AAAAA,EAAAA,QAAAA,K,cADzB,KAAA,oBAAC,KAAD,EAAA,UACE,oBAAC,OAAD;EAAO,MAAK;EAAWA,UAAAA;CAAsB,CAAA,EAC1C,CAAA,GADoBA,EAAAA,MAAAA,I;CAEzBE,IAAAA;CAEO,AAAA,EAAA,QAAA,I,cAFP,KAAA,oBAAC,MAAD;EAAM,OAAA;EACJ,UAAA,oBAAC,WAAD;GACK;GACH,SAAQ;EACT,CAAA;CACG,CAAA,GAHC,EAAA,MAAA,G;CAPXC,IAAAA;CAEIF,AAAAA,EAAAA,QAAAA,MAAAA,EAAAA,QAGAC,MALJ,MAAA,oBAAC,MAAD,EAAA,UACE,qBAAC,QAAD;EAAQ,KAAK;EAAb,UAAA,CACED,IAGAC,EAMM;CACJ,CAAA,EAAA,CAAA,GAVFD,EAAAA,MAAAA,IAGAC,EAAAA,MAAAA,I;CAQHE,IAAAA;CAE0B,AAAA,EAAA,QAAA,I,eAF1B,MASG,MAPuB,EAAA,MAAA,G;CAgBpBC,IAAAA;C,6BAAE,MAAA,EAAA,wCAAwC,GAA1C,EAAA,MAAA,G;CAPPC,IAAAA;CAOOD,AAAAA,EAAAA,QAAAA,M,eAPP,MAAA,oBAAC,MAAD,EAAA,UACE,oBAAC,MAAD,EAAA,UACE,qBAAC,wBAAD;EACE,MAAK;EACL,QAAO;EACP,KAAI;EAHN,UAAA,CAKGA,KAA4C,IACvB;CACpB,CAAA,EAAA,CAAA,EACF,CAAA,GAHCA,EAAAA,MAAAA,K;CAxCXE,IAAAA;CASIJ,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QAaCC,OAAAA,EAAAA,QAWDE,OAAAA,EAAAA,QA/BAT,MAAAA,EAAAA,QAIAE,MANJ,MAAA,oBAAC,2BAAD,EAAA,UACE,qBAAC,QAAD;EAAQ,KAAK;EAAb,UAAA;GACEF;GAIAE;GAGAI;GAaCC;GAWDE;EAWM;CACiB,CAAA,EAAA,CAAA,GApCvBH,EAAAA,MAAAA,KAaCC,EAAAA,MAAAA,KAWDE,EAAAA,MAAAA,KA/BAT,EAAAA,MAAAA,IAIAE,EAAAA,MAAAA,I;CA0DJS,IAAAA;C,qDAAC,MAAA,oBAAA,KAAD,EAAK,MAA0D,UAAY,CAAA,G;CAX7EC,IAAAA;CASY,AAAA,EAAA,QAAA,O,eATZ,MAAA,oBAAC,QAAD;EACE,MAAM;EACN,MAAK;EACL,SAAS;EACT,cAAc;EACd,MAAK;EACL,UAAU;EACV,KAAK;EACL,SAAS;EACT,UAAU;EAEVD,UAAAA;CACM,CAAA,GAHI,EAAA,MAAA,M;CAjEdE,IAAAA;CADF,OAuDU,EAAA,QAAA,QAAA,EAAA,QAnDJH,OAAAA,EAAAA,QAqDFE,OAxDF,MAAA,oBAAC,SAAD;EACE,SAAA;EACA,SACEF;EA+CF,WAAU;EACV,QAAA;EACA,SAAS;EACT,KAAK;EACC;EAENE,UAAAA;CAaO,CAAA,GAfD,EAAA,MAAA,MAnDJF,EAAAA,MAAAA,KAqDFE,EAAAA,MAAAA,K,4BAxDFC;AAuEJ;AAjFgD,SAAAE,QAAC,GAAA;CAAM,OAAA,CAAC;;ACIxD,MAAM,kCAAA,OAG2B;C,eAA3B,EAAC,mBAAmB,MAApBC,IACE,OACJ,OAAO,kBAAkB,uBAAwB,WAC7C,kBAAkB,oBAAoB,SAAS,QAC/C,kBAAkB,yBAIHC;CADmCC,IAAAA,EAAAA,OAAAA,kBAAAA,wBAAAA,EAAAA,OADJC,kBAAAA,kBAAAA;EAApD,IAAM,UAAU,kBAAkB,kBAAkB,gBAAgB,GAChDC;E,AAAoCF,EAAAA,OAAAA,kBAAAA,uB,aAApC,KAAA,kBAAkB,kBAAkB,oBAAoB,GAApBA,EAAAA,KAAAA,kBAAAA,sB,YACnC,KAAA,UAAU,gBAAgB,OAAO,IAAI+C,IADF/C,EAAAA,KAAAA,kBAAAA,sBADJC,EAAAA,KAAAA,kBAAAA,kB;;CAEpD,IAAM,eAAeF,IAEPI;CAAqB,AAAA,EAAA,OAAA,qBAAA,EAAA,OAC3B,KADM,KAAA,qBAAqB,iBAAiB,IAChD,IAAI,EAAE,4CAA4C,EAAE,KACpD,EAAE,4CAA4C,GAFf,EAAA,KAAA,mBAC3B,EAAA,KAAA,G;CADR,IAAM,QAAQA,IAMH,KAAA,eAAe,KAAK,iBAAiB,KAAA,GAA5CC;CAAuD,AAAA,EAAA,OAAA,SAAA,EAAA,OAAtD,QAAA,EAAA,QAAMC,MAAP,KAAA;EAAC;EAAMA;EAAgD;CAAK,CAAC,CAC1D,OAAOC,OAAuC,GADM,EAAA,KAAA,OAAtD,EAAA,KAAA,MAAMD,EAAAA,MAAAA,I;CAFX,IAAM,OAEFD,GAEG,KAAK,GAEZ,GAG2CG;CAAqB,AAAA,EAAA,QAAA,oB,cAArB,KAAA,qBAAqB,iBAAiB,GAAjB,EAAA,MAAA,mB;CAAtB,IAAA,KAAA,CAACA,IAAzCC;CADF,OAC0CC,EAAAA,QAAAA,MAAAA,EAAAA,QACrC,QADH,KAAA,oBAAC,UAAD;EAAQ,OAAM;EAAgB,UAAUA;EACrC,UAAA;CACK,CAAA,GAFgCA,EAAAA,MAAAA,IACrC,EAAA,MAAA,M,0BADHD;AAIJ;AAkBA,SAAgB,gBAAA,IAcS;C,eAdO,EAC9B,iBACA,SACA,kBACA,YACA,oBACA,UACA,4BACA,0BACA,mBACA,qBACA,KACA,aACA,6BAb8BE,IAexB,oBAAoB,eAAe,GAEvCC;CAAiB,AAAA,EAAA,OAAA,eAAA,EAAA,OAAiDX,kBAAAA,wBAAlE,KAAA,iBAAiB,aAAa,kBAAkB,kBAAkB,oBAAoB,CAAC,GAAtE,EAAA,KAAA,aAAiDA,EAAAA,KAAAA,kBAAAA,sB;CADpE,IAAM,qBAAqB,EACzBW,IAEI,EAAC,MAAK,eAAe,qBAAqB,GAC1C,sBAAsB,OAAgC,IAAI,GAC9BC;C,oDAAM,WAAA;EACtC,IAAM,KAAK,oBAAoB;EAC/B,IAAK,IAEL,IAAI;GAGF,AAFA,GAAG,OAAO,GAEV,SAAS,YAAY,MAAM;EAC7B,QAAQ;GACN,QAAQ,MAAM,gCAAgC;EAChD;CACF,G;CAXA,IAAM,gBAAgBC,IAgBKC;;EACnB;EACA;EACA;EACA;CACF,G;CAG6BC,IAAAA;C,oDAAC,KAAA,CAAA,mBAAmB,iBAAiB,G;CAG9CC,IAAAA;C,0BAAE,KAAA,EAAA,wBAAwB,GAA1B,EAAA,KAAA,G;CADhBC,IAAAA;CACgBD,AAAAA,EAAAA,OAAAA,K,aADhB,KAAA,oBAAC,MAAD;EAAM,YAAY;EAAG,eAAe;EAClC,UAAA,oBAAC,aAAD,EAAA,UAAcA,GAAyC,CAAA;CACnD,CAAA,GADUA,EAAAA,KAAAA,I;CAGbE,IAAAA;C,mCAAS,KAAA,SAAA,IAAIC,QAEb,GAFA,EAAA,MAAA,U;CADHC,IAAAA;CAAe,AAAA,EAAA,QAAA,WAAA,EAAA,QAAmB,mBAAA,EAAA,QAC/BF,MADH,KAAA,oBAAC,QAAD;EAAQ,OAAO;EAAS,UAAU;EAC/BA,UAAAA;CAGK,CAAA,GAJO,EAAA,MAAA,SAAmB,EAAA,MAAA,iBAC/BA,EAAAA,MAAAA,I;CANPG,IAAAA;CAEIJ,AAAAA,EAAAA,QAAAA,MAAAA,EAAAA,QAGAG,MALJ,KAAA,oBAAC,KAAD;EAAK,SAAS;EAAG,YAAYL;EAC3B,UAAA,qBAAC,QAAD,EAAA,UAAA,CACEE,IAGAG,EAKM,EAAA,CAAA;CACL,CAAA,GATDH,EAAAA,MAAAA,IAGAG,EAAAA,MAAAA,I;CASyBL,IAAAA;C,qDAAC,MAAA,CAAA,mBAAmB,iBAAiB,G;CAG9CO,IAAAA;C,6BAAE,MAAA,EAAA,4BAA4B,GAA9B,EAAA,MAAA,G;CADhBC,IAAAA;CACgBD,AAAAA,EAAAA,QAAAA,M,eADhB,MAAA,oBAAC,MAAD;EAAM,YAAY;EAAG,eAAe;EAClC,UAAA,oBAAC,aAAD,EAAA,UAAcA,IAA6C,CAAA;CACvD,CAAA,GADUA,EAAAA,MAAAA,K;CAIWE,IAAAA;C,6BAAE,MAAA,EAAA,yCAAyC,GAA3C,EAAA,MAAA,G;CAAhBC,IAAAA;CAAgBD,AAAAA,EAAAA,QAAAA,M,eAAhB,MAAA,oBAAC,MAAD;EAAM,MAAM;EAAIA,UAAAA;CAAmD,CAAA,GAAnDA,EAAAA,MAAAA,K;CACf,IAAA,MAAA,CAAC,oBAOA,MAAA,qBAAqB,KAAQ,aAAa,SAIhDE;C,qDAAa,MAAA,aAAA,IAAIC,QAEjB,G;CAEEC,IAAAA;C,6BAAE,MAAA,EAAA,kCAAkC,GAApC,EAAA,MAAA,G;CADHC,IAAAA;CACGD,AAAAA,EAAAA,QAAAA,M,eADH,MAAA,oBAAC,UAAD;EAAoB,OAAM;EACvBA,UAAAA;CACK,GAFI,OAEJ,GADLA,EAAAA,MAAAA,K;CAXPE,IAAAA;CAKc,AAAA,EAAA,QAAA,sBAAA,EAAA,QADA,sBAAA,EAAA,QADHC,OAAAA,EAAAA,QAOPF,OAVJ,MAAA,oBAAC,KAAD;EAAK,eAAY;EACf,UAAA,qBAAC,QAAD;GACE,eAAY;GACZ,OAAOE;GACP,UAAU;GACV,UAAU;GAJZ,UAAA,CAMGL,KAGDG,GAGM;;CACL,CAAA,GATS,EAAA,MAAA,oBADA,EAAA,MAAA,oBADHE,EAAAA,MAAAA,KAOPF,EAAAA,MAAAA,K;CAjBNG,IAAAA;CAEWP,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QACCQ,OAAAA,EAAAA,QAIVH,OAPF,MAAA,oBAAC,SAAD;EACE,SAAA;EACA,SAASL;EACT,UAAUQ;EACV,WAAU;EACV,QAAA;EAEAH,UAAAA;CAeO,CAAA,GApBEL,EAAAA,MAAAA,KACCQ,EAAAA,MAAAA,KAIVH,EAAAA,MAAAA,K;CAZNI,IAAAA;CAEIX,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QAGAS,OALJ,MAAA,oBAAC,KAAD;EAAK,SAAS;EAAG,YAAYjB;EAC3B,UAAA,qBAAC,QAAD,EAAA,UAAA,CACEQ,KAGAS,GAuBM,EAAA,CAAA;CACL,CAAA,GA3BDT,EAAAA,MAAAA,KAGAS,EAAAA,MAAAA,K;CA2BHG,IAAAA;CAAuB,AAAA,EAAA,QAAA,oBAAA,EAAA,QAUX,8BAAA,EAAA,QAVX,sBAAA,EAAA,QAcQ,qBAAA,EAAA,QAFQ,4BAAA,EAAA,QAPP,KALV,MAAA,CAAC,sBAAsB,qBAAqB,MAC3C,oBAAC,KAAD;EAAK,SAAS;EAAG,YAAY,CAAC,mBAAmB,iBAAiB;EAChE,UAAA,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,MAAD;GAAM,YAAY;GAAG,eAAe;GAClC,UAAA,oBAAC,aAAD;IAAa,cAAa;IACvB,UAAA,EAAE,mCAAmC;GAC3B,CAAA;EACT,CAAA,GAEN,oBAAC,WAAD;GACE,KAAK;GACL,OAAO;GACP,UAAU;GACV,gBACE,oBAAoB,KAAA,IAAY,EAAE,oCAAoC;GAExE,WAAW;EACZ,CAAA,CACK,EAAA,CAAA;CACL,CAAA,GAnBiB,EAAA,MAAA,kBAUX,EAAA,MAAA,4BAVX,EAAA,MAAA,oBAcQ,EAAA,MAAA,mBAFQ,EAAA,MAAA,0BAPP,EAAA,MAAA,G;CAkBkBpB,IAAAA;C,qDAAC,MAAA,CAAA,mBAAmB,iBAAiB,G;CAK1CqB,IAAAA;C,6BAAE,MAAA,EAAA,4BAA4B,GAA9B,EAAA,MAAA,G;CADhBC,IAAAA;CACgBD,AAAAA,EAAAA,QAAAA,M,eADhB,MAAA,oBAAC,KAAD,EAAA,UACE,oBAAC,aAAD,EAAA,UAAcA,IAA6C,CAAA,EACxD,CAAA,GADWA,EAAAA,MAAAA,K;CAGhBE,IAAAA;C,qDAAC,MAAA,oBAAA,KAAD,EAAA,UACE,oBAAC,oBAAD,CAAqB,CAAA,EAClB,CAAA,G;CARTC,IAAAA;CAEIF,AAAAA,EAAAA,QAAAA,M,eAFJ,MAAA,oBAAC,MAAD;EAAM,eAAe;EACnB,UAAA,qBAAC,QAAD;GAAQ,KAAK;GAAb,UAAA,CACEA,KAIAC,GAGM;;CACJ,CAAA,GARFD,EAAAA,MAAAA,K;CAWK,IAAA,MAAA,eAAe,WAGrBG;CAaQ,AAAA,EAAA,QAAA,4BAAA,EAAA,QATkD,qBAAA,EAAA,QAAsB,KAJhF,MAAA,uBAAuB,KAAK,oBACvB,oBAAoB,kBAEpB,qBAAC,UAAD,EAAA,UAAA;EACE,oBAAC,gCAAD;GAAmD;GAAsB;EAAI,CAAA;EAC7E,oBAAC,UAAD;GAAsB,OAAM;GACzB,UAAA,EAAE,+BAA+B;EAC5B,GAFI,SAEJ;EACR,oBAAC,MAAD,CAAK,CAAA;CACG,EAAA,GANI,eAMJ,IAGV,oBAAoB,oBACjB,2BAEH,oBAAC,UAAD;EAA8B,OAAM;EACjC,UAAA,EAAE,wCAAwC;CACrC,GAFI,iBAEJ,IAJ4B,OAOjC,oBAAC,UAAD,EAAA,UAA+B,gBAAwB,GAA1C,eAA0C,CAC/D,GARQ,EAAA,MAAA,0BATkD,EAAA,MAAA,mBAAsB,EAAA,MAAA,G;CATnFC,IAAAA;CAGY,AAAA,EAAA,QAAA,uBAAA,EAAA,QADHC,OAAAA,EAAAA,QAGNF,OALH,MAAA,oBAAC,QAAD;EACE,eAAY;EACZ,OAAOE;EACP,UAAU;EAETF,UAAAA;CAsBK,CAAA,GAxBI,EAAA,MAAA,qBADHE,EAAAA,MAAAA,KAGNF,EAAAA,MAAAA,K;CAlBPG,IAAAA;CAEIJ,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QAWAE,OAbJ,MAAA,oBAAC,KAAD;EAAK,SAAS;EAAG,YAAY1B;EAC3B,UAAA,qBAAC,QAAD,EAAA,UAAA,CACEwB,KAWAE,GA4BM,EAAA,CAAA;CACL,CAAA,GAxCDF,EAAAA,MAAAA,KAWAE,EAAAA,MAAAA,K;CAgCHG,IAAAA;CAOK,AAAA,EAAA,QAAA,oBAAA,EAAA,QAMK,KAAA,EAAA,QAbH,OAAP,MAAA,OAAO,OAAQ,WACd,oBAAC,KAAD;EACE,SAAS;EACT,WAAU;EACV,UAAU;EACV,YAAY,CACV,mBACA,qBAAqB,KAAQ,oBAAoB,iBACnD;EAEA,UAAA,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,MAAD;GAAM,YAAY;GAAG,eAAe;GAClC,UAAA,qBAAC,aAAD,EAAA,UAAA;IACG,EAAE,WAAW;IAAE;IAChB,qBAAC,eAAD;KACE,MAAM;KACN,UAAU,UAAU;MAGlB,AADA,MAAM,eAAe,GACrB,cAAc;KAChB;KANF,UAAA;MAQE;MAAE,EAAE,8BAA8B;MAAE;KACvB;;GACJ,EAAA,CAAA;EACT,CAAA,GACN,qBAAC,MAAD;GAAM,WAAU;GAAK,UAAU;GAAG,KAAK;GAAvC,UAAA,CACE,oBAAC,KAAD;IAAK,WAAU;IAAK,UAAU;IAC5B,UAAA,oBAAC,WAAD;KACE,eAAY;KACZ,UAAA;KACA,MAAK;KACL,KAAK;KACL,OAAO;IACR,CAAA;GACE,CAAA,GACL,oBAAC,SAAD;IAAS,SAAA;IAAQ,SAAS,EAAE,8BAA8B;IACxD,UAAA,oBAAC,QAAD;KACE,cAAY,EAAE,8BAA8B;KAC5C,MAAK;KACL,MAAK;KACL,MAAM;KACN,SAAS;IACV,CAAA;GACM,CAAA,CACL;EACA,CAAA,CAAA,EAAA,CAAA;CACL,CAAA,IAEL,oBAAC,KAAD;EAAK,WAAU;EAAK,UAAU;CAAI,CAAA,GA1C9B,EAAA,MAAA,kBAMK,EAAA,MAAA,GAbH,EAAA,MAAA,K;CA5HZC,IAAAA;CADF,OAyBMX,EAAAA,QAAAA,OAAAA,EAAAA,QAgCCC,OAAAA,EAAAA,QAuBDQ,OAAAA,EAAAA,QA6CCC,OAAAA,EAAAA,QAlHDvB,MAVJ,MAAA,oBAAC,QAAD;EAAQ,UAAU;EAAG,UAAU;EAC7B,UAAA,qBAAC,MAAD;GACE,qBAAqBP;GADvB,UAAA;IASEO;IAcAa;IAgCCC;IAuBDQ;IA6CCC;GAmDG;;CACA,CAAA,GAxJJV,EAAAA,MAAAA,KAgCCC,EAAAA,MAAAA,KAuBDQ,EAAAA,MAAAA,KA6CCC,EAAAA,MAAAA,KAlHDvB,EAAAA,MAAAA,I,4BAVJwB;AAkLJ;AAvIoC,SAAAK,SAAC,SAAA;CACjB,OAAA,oBAAC,UAAD,EAAA,UAAuB,QAAgB,GAA1B,OAA0B;;AA5B/B,SAAAD,SAAC,IAAA;CACb,OAAA,oBAAC,UAAD,EAAA,UAAkB,GAAW,GAAhB,EAAgB;;AAhF7B,SAAAD,QAAC,OAAA;CAAU,OAAO,UAAU;;ACnD5C,SAAS,WAAW,SAAiB,UAA0B;CAC7D,OAAO,IAAI,gBACT,IAAI,KAAK,CAAC,OAAO,GAAG,EAClB,MAAM,SACR,CAAC,CACH;AACF;AAEA,MAAM,UAAU,OAAO,SAAS;;;;;;;AAQhC,SAAS,2BAA2B,UAAkB,eAAuC;CAC3F,cAAc;EACZ,IAAI,YAAqB,SACrB,aAAa,IACb,cAAc;EAClB,QAAQ,UAAmB;GACzB,IAAI,UAAU,aAAa,YACzB,OAAO;GAGT,IAAM,UAAU,cAAc,KAAK;GACnC,IAAI,OAAO,WAAY,YAAY,YAAY,IAe/C,OAXA,YAAY,OACR,YAAY,gBAIhB,cAAc,SACV,cACF,IAAI,gBAAgB,UAAU,GAGhC,aAAa,WAAW,SAAS,QAAQ,IAClC;EACT;CACF,EAAA,CAAG;AACL;AAEA,MAAa,iBAAiB,2BAA2B,qBAAqB,UAC5E,KAAK,UAAU,OAAO,MAAM,CAAC,CAC/B,GAEa,gBAAgB,2BAA2B,aAAa,UAC5D,SAAS,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAC9D;;;;;;AAOD,SAAgB,aAAa,OAAyB;CAEpD,QADc,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAA,CACtC,MAAM,SAAS,OAAO,QAAS,cAAY,QAAiB,CAAC,MAAM,QAAQ,IAAI,CAAC;AAC/F;ACzDA,SAAgB,eAAe,OAA4B;C,cACnD,CAAC,MAAM,WAAW,SAAS,EAAK,GAE5BG,IAGPC;CAHH,AACsDC,EAAAA,OAAAA,MAAAA,S,yBAD5C,WAAM;EACd,IAAM,QAAQ,iBAAiB,QAAQ,EAAI,GAAG,MAAM,SAAS,GAAG;EAChE,aAAa,aAAa,KAAK;CACjC,GAAG,KAAA,CAAC,MAAM,KAAK,GAFuCA,EAAAA,KAAAA,MAAAA,O,uBADtD,UAAUF,IAGPC,EAAa;CAETE,IAAAA;CAAP,O,6BAAc,KAAA,OAAA,oBAAC,SAAD;EAAS,OAAA;EAAM,MAAM;CAAI,CAAA,IAAI,MAApC,EAAA,KAAA,M,YAAAA;AACT;;;;;;;;ACJA,SAAgB,kBAAkB,UAAkB,UAA2B;CAC7E,IAAM,iBAAiB,gBAAgB,QAAQ,GACzC,iBAAiB,gBAAgB,QAAQ;CAsB/C,OApBI,eAAe,SAAS,aAAa,eAAe,SAAS,aAI7D,eAAe,SAAS,iBACnB,KAGL,eAAe,SAAS,iBACnB,KAGL,eAAe,SAAS,WACnB,eAAe,SAAS,WAG7B,eAAe,SAAS,YAIrB,eAAe,QAAQ,eAAe;AAC/C;AAEA,SAAS,gBAAgB,SAAmC;CAC1D,IAAM,aAAa,QAAQ,QAAQ,OAAO,EAAE,CAAC,CAAC,KAAK;CAkBnD,OAhBK,aAID,WAAW,YAAY,MAAM,MACxB,EAAC,MAAM,eAAc,IAG1B,eAAe,MACV,EAAC,MAAM,SAAQ,IAGpB,sBAAsB,KAAK,UAAU,IAChC;EAAC,MAAM;EAAS,OAAO;CAAU,IAGnC,EAAC,MAAM,UAAS,IAfd,EAAC,MAAM,UAAS;AAgB3B;ACtDA,MAAM,qCAAqB,IAAI,IAAI;CAAC;CAAO;CAAa;CAAU;AAAe,CAAC,GA4BrE,2BAAuE,CAClF;CACE,IAAI;CAEJ,oBAAoB,+BAA+B;CACnD,gBAAgB;CAChB,UAAU,EAAC,cAAa,EAAQ;AAClC,GACA;CACE,IAAI;CAGJ,oBAAoB,+BAA+B;CACnD,gBAAgB;CAChB,UAAU,EAAC,kBAAiB,wBAAwB,WAAW;AACjE,CACF;AAEA,SAAgB,wBAAwB,aAAqD;CAK3F,OAJK,MAAM,QAAQ,WAAW,IAIvB,YAAY,MAAM,UAAU,CAAC,mBAAmB,IAAI,KAAK,CAAC,IAHxD;AAIX;AAEA,SAAgB,mCACd,SACA,eAA2D,0BACd;CAC7C,IAAI,QAAQ,eAAe,KAI3B,OAAO,aAAa,MACjB,eACC,WAAW,QAAQ,OAAO,KAC1B,kBAAkB,QAAQ,YAAY,WAAW,kBAAkB,CACvE;AACF;;AEpEA,SAAgB,UAAU,OAAoC;C,cACrDE;CAAP,OAAiB,EAAA,OAAA,Q,aAAV,KAAA,oBAAC,MAAD;EAAM,GAAI;EAAO,WAAW;CAAY,CAAA,GAA9B,EAAA,KAAA,O,YAAVA;AACT;ACUA,SAAgB,kBAAA,IAAmE;C,eAAjD,EAAC,UAADE,IAC1B,EAAC,MAAK,eAAe,qBAAqB;CAEhD,IAAI,EAAE,aAAa,QACjB,OAAO;CAGW,IAAA,KAAA,MAAM,SAOrBC,IAPC,SAOsBC,IAAiBC,IAAxBC,I;CAP0CC,IAAAA,EAAAA,OAAAA,MAAAA,SAAAA;;;GAC/D,IADA,UAAgB;IAAC,GAAGC;IAAe,GAAG,mBAAmB,MAAM,OAAO;GAAC,GACnE,CAAC,QAAQ,MAAM;IACV,KAAA;;GACT;GAI6C,AAAxC,KAAA,WAAgB,KAAA,GAAO,KAAA,QAAQ,MAAS,KAAA,SACvC,QAAQ,QACR,QAAQ,SACV;;E,AAV2DD,EAAAA,KAAAA,MAAAA,S;;;CAOtC,IAAA,KAAA,GAAGH,GAAa,IAAIC,MAAzCI;CAACN,AAAAA,EAAAA,OAAAA,MAAAA,EAAAA,OAAgBG,MAAAA,EAAAA,OAAII,MAArB,KAAA,oBAACP,IAAD;EAAW,MAAMG;EAAII,UAAAA;CAGN,CAAA,GAHdP,EAAAA,KAAAA,IAAgBG,EAAAA,KAAAA,IAAII,EAAAA,KAAAA,I;CAKKC,IAAAA;C,4BAAE,KAAA,EAAA,kBAAkB,GAApB,EAAA,MAAA,G;CAA4B,IAAA,KAAA,QAAQ,YAAeC;C,6BACzE,MAAA,EAAA,oBACF,GAF2E,EAAA,MAAA,G;CAAtD,IAAA,MAAA,GAAGD,GAAsB,MAAME,GAAmB,IAAID,IAEzE,IAAI,QAAQ,UAHhBE;CACuBC,AAAAA,EAAAA,QAAAA,M,eADvB,MAAA,oBAAC,KAAD;EAAK,WAAW;EACd,UAAA,oBAAC,WAAD;GAAW,MAAM;GAAIA,UAAAA;EAEa,CAAA;CAC/B,CAAA,GAHkBA,EAAAA,MAAAA,K;CANzBC,IAAAA;CADF,OAMIF,EAAAA,QAAAA,OAAAA,EAAAA,QAJAL,MADF,MAAA,qBAAC,OAAD,EAAA,UAAA,CACEA,IAIAK,GAKG,EAAA,CAAA,GALHA,EAAAA,MAAAA,KAJAL,EAAAA,MAAAA,I,4BADFO;AAYJ;AAEA,SAAS,mBAAmB,SAA2C;CACrE,IAAI,CAAC,WAAW,OAAO,QAAQ,SAAU,YAAY,OAAO,QAAQ,SAAU,UAC5E,OAAO,CAAC;CAGV,IAAM,EAAC,OAAO,OAAO,QAAO,SACtB,YAAY,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,YAAY,IAAI,IAAI,GACtD,cAAc,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,EAAA,CAAG;CAKlE,OAAO;EAAC,MAJK,MAAM,MAAM,WAAW,MAAM,QAAQ,MAAM,SAAS,CAIzD;EAAM;EAAY,QAHX,QAAQ;EAGW,WAFhB,OAAO,OAAQ,WAAW,MAAM,YAAY,KAAA;CAEnB;AAC7C;AAEA,SAAS,SAAS,QAAgB,WAAuC;CAGvE,OAAO,GAFM,IAAI,OAAO,MAEd,IADG,IAAI,OAAO,YAAY,YAAY,SAAS,CACxC;AACnB;AC7CA,SAAgB,iBAAiB,OAA8B;C,eACvD,EAAC,OAAO,YAAY,aAAa,YAAW,OAC5C,EAAC,MAAK,eAAe,qBAAqB,GAS7CE,IAAUC,IAAcC,IAAiBC,IACvCC;CAPH,IAAA,EAAA,OAAA,cAAA,EAAA,OADwB,SAAA,EAAA,OAExB,eAAA,EAAA,OAQO,KAAA,EAAA,OAPP,SAAA;EAJF,IAAM,wBAAwB,mCAAmC;GAC/D,YAAY,YAAY,KAAK,IAAI,MAAM,aAAa,KAAA;GACpD;GACA;GACA;EACF,CAAC;E,AAGE,KAAA,MAAU,KAAA,GAAc,KAAA,GAAiB,KAAA,UACvC,KAAA,wBACC,oBAAC,MAAD;GAAM,eAAY;GAA0C,MAAM;GAC/D,UAAA,EAAE,sBAAsB,gBAAgB,EACvC,YAAY,iBAAiB,sBAAsB,kBAAkB,EACvE,CAAC;EACG,CAAA,IACJ,MAbN,EAAA,KAAA,YADwB,EAAA,KAAA,OAExB,EAAA,KAAA,aAQO,EAAA,KAAA,GAPP,EAAA,KAAA,S;;CAYEC,IAAAA;CAA2BC,AAAAA,EAAAA,QAAAA,MAAAA,U,cAA3B,KAAA,oBAAC,WAAD;EAAW,MAAM;EAAI,UAAA,MAAM;CAAmB,CAAA,GAAnBA,EAAAA,MAAAA,MAAAA,S;CAC3BC,IAAAA;CAA0B,AAAA,EAAA,QAAA,Q,cAA1B,KAAA,oBAAC,mBAAD,EAA0B,MAAQ,CAAA,GAAR,EAAA,MAAA,O;CAT5BC,IAAAA;CADF,OACGR,EAAAA,QAAAA,MAAAA,EAAAA,QAAUC,MAAAA,EAAAA,QAAcC,MAAAA,EAAAA,QAAiBC,MAAAA,EAAAA,QACvCC,MAAAA,EAAAA,QAODC,MAAAA,EAAAA,QACAE,MATF,KAAA,qBAACP,IAAD;EAAM,KAAKC;EAAG,WAAWC;EAAG,eAAcC;EAA1C,UAAA;GACGC;GAODC;GACAE;EACI;C,IAVLP,EAAAA,MAAAA,IAAUC,EAAAA,MAAAA,IAAcC,EAAAA,MAAAA,IAAiBC,EAAAA,MAAAA,IACvCC,EAAAA,MAAAA,IAODC,EAAAA,MAAAA,IACAE,EAAAA,MAAAA,I,0BATFC;AAYJ;;ACxCA,SAAgB,gBAAgB,SAAyB;CACvD,OAAO,QACJ,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,UACb,QAAQ,KAAK,OAAO,IAAI,IAAI,QAAQ,KAAK,UAAU,IAAI,UAAU,IAAI,SACvE,CAAC,CACA,KAAK,EAAE;AACZ;;;;;;AAOA,SAAgB,aAAa,MAAe,SAA+C;CACzF,IAAI,YAAY,IAAI,OAAO,EAAC,OAAO,KAAI;CACvC,IAAM,WAAW,QAAQ,MAAM,GAAG,GAC9B,UAAU,MACV,QAAQ;CACZ,OAAO,QAAQ,SAAS,SAAQ;EAC9B,IAAM,YAAY;EAClB,IAA0B,OAAO,aAAc,aAA3C,WAAqD;EACzD,IAAI,MAAM,SAAS;EACnB,OAAO,MAAM,SAAS,CAAC,OAAO,OAAO,WAAW,SAAS,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,IAAG;EACvF,IAAI,QAAQ,OAAO;EAEnB,AADA,UAAU,QAAQ,IAAI,WAAW,SAAS,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,GACrE,QAAQ;CACV;CACA,OAAO,EAAC,OAAO,QAAO;AACxB;;AEAA,MAAM,MAAM,IAAI,IAAI,EAAC,SAAS,IAAK,CAAC;AAEpC,SAAS,kBAAA,IAAmF;C,eAAjE,EAAC,UAAU,aAAXE,IACnB,EAAC,OAAO,MAAM,UAASgD,YAAW,GAClC,WAAW,KAAK,KAAK,MAAM,IAIlB,KAAA,WAAW,GAAG,kBAAkB,GAAG,mBAAmB,mBAE9C,KAAA,KAAK,KAAK,QACR,KAAA,GAAG,SAAS,SAAS,KACnB,KAAA,GAAG,SAAS,WAAW,KAC5B/C;CAAUC,AAAAA,EAAAA,OAAAA,MAAAA,K,aAAV,KAAA,IAAI,MAAM,EAAE,GAAFA,EAAAA,KAAAA,MAAAA,I;CAAb,IAAA,KAAA,GAAGD,MACAE;CAAUC,AAAAA,EAAAA,OAAAA,MAAAA,K,aAAV,KAAA,IAAI,MAAM,EAAE,GAAFA,EAAAA,KAAAA,MAAAA,I;CAAb,IAAA,KAAA,GAAGD,MACAE;CAAUC,AAAAA,EAAAA,OAAAA,MAAAA,K,aAAV,KAAA,IAAI,MAAM,EAAE,GAAFA,EAAAA,KAAAA,MAAAA,I;CAAb,IAAA,MAAA,GAAGD,MACQ,MAAA,MAAM,KAAK,GAAfE;CAAIC,AAAAA,EAAAA,OAAAA,M,cAAJ,MAAA,IAAIA,GAAY,GAAZA,EAAAA,KAAAA,K;CAAP,IAAA,MAAA,GAAGD,OAPfE;CAW4BC,AAAAA,EAAAA,OAAAA,MAHN,OAGM,WAAA,EAAA,OAFCC,MADP,OACO,YAAA,EAAA,QAGFC,MAJL,OAIK,UAAA,EAAA,QAJEC,MAAP,OAAO,YAAA,EAAA,QAEFC,MAFL,OAEK,UAAA,EAAA,QATLC,KAAL,KAAK,UAAA,EAAA,QAKdC,OAAAA,EAAAA,QACIC,OAAAA,EAAAA,QALEC,MAAAA,EAAAA,QACEC,MAAAA,EAAAA,QACRC,MAAAA,EAAAA,QACAC,MALR,MAAA,iBAAiB;GACrB,gBAAgBC;GAChB,kBAAkBJ;GAClB,oBAAoBC;GACpB,YAAYC;GACZ,YAAYC;GACZ,YAAYL;GACZ,gBAAgBC;GAChB,oBAAoB,MAAM,OAAO;GACjC,oBAAoB,MAAM,OAAO;GACjC,kBAAkB,MAAM,OAAO;GAC/B,mBAAmB,MAAM,OAAO;GAChC,kBAAkB,MAAM,OAAO;CAClC,CAAC,GAFkCP,EAAAA,KAAAA,MAHN,OAGM,SAFCC,EAAAA,KAAAA,MADP,OACO,UAGFC,EAAAA,MAAAA,MAJL,OAIK,QAJEC,EAAAA,MAAAA,MAAP,OAAO,UAEFC,EAAAA,MAAAA,MAFL,OAEK,QATLC,EAAAA,MAAAA,KAAL,KAAK,QAKdC,EAAAA,MAAAA,KACIC,EAAAA,MAAAA,KALEC,EAAAA,MAAAA,IACEC,EAAAA,MAAAA,IACRC,EAAAA,MAAAA,IACAC,EAAAA,MAAAA,I;CAPjBE,IAAAA;CADF,OAkBK,EAAA,QAAA,YAAA,EAAA,QAhBUC,MAAAA,EAAAA,QACJf,OAFT,MAAA,oBAAC,OAAD;EACE,WAAWe;EACX,OAAOf;EAeN;CACE,CAAA,GADF,EAAA,MAAA,UAhBUe,EAAAA,MAAAA,IACJf,EAAAA,MAAAA,K,4BAFTc;AAoBJ;AAkBA,MAAM,qBAAqB,cAA8C,IAAI;AAE7E,SAAgB,WAAW,OAIL;C,eACd,EAAC,MAAM,aAAa,SAAQ,OAE5B,gBADmB,WACH,MAAqB,aACPE;CAAO,AAAA,EAAA,OAAA,QAAA,EAAA,OAAN,QAAA,EAAA,OAAY,iBAAb,KAAA;EAAC;EAAM;EAAM;CAAa,GAAnB,EAAA,KAAA,MAAN,EAAA,KAAA,MAAY,EAAA,KAAA,e;CAAjD,IAAM,eAAeC;CAErB,IAAI,SAAS,IAAI,KAAK,MAAM,QAAQ,IAAI,GAAG;EAEV,IAAA,KAAA,EAAQ,MAOb,KAAA,QAAQ,gBAAgB,mBAAmB,KAAA,GAL/DC;EACQ,AAAA,EAAA,OAAA,QAAA,EAAA,OAIYC,MALpB,KAAA,oBAAC,eAAD;GACQ;GACN,QAAQ;GACI;GACZ,SAAS;GACT,kBAAkBA;EACnB,CAAA,GALO,EAAA,KAAA,MAIYA,EAAAA,KAAAA,I;EANtBC,IAAAA;EAA2B,AAAA,EAAA,OAAA,gBAAA,EAAA,OACzBF,MADF,KAAA,oBAAC,oBAAD;GAAoB,OAAO;GACzBA,UAAAA;EAOkB,CAAA,GARO,EAAA,KAAA,cACzBA,EAAAA,KAAAA,I;EAFJG,IAAAA;EADF,OAC+BC,EAAAA,QAAAA,MAAAA,EAAAA,QAC3BF,MADF,KAAA,oBAAC,mBAAD;GAAmB,UAAUE;GAC3BF,UAAAA;EASiB,CAAA,GAVUE,EAAAA,MAAAA,IAC3BF,EAAAA,MAAAA,I,0BADFC;CAYJ;CAE8BE,IAAAA;CAAe,AAAA,EAAA,QAAA,O,cAAf,KAAA,KAAK,UAAU,IAAI,GAAJ,EAAA,MAAA,M;CAAtCC,IAAAA;CAAP,OAA8BD,EAAAA,QAAAA,K,cAAvB,KAAA,oBAAC,MAAD;EAAM,UAAS;EAAQA,UAAAA;CAA2B,CAAA,GAA3BA,EAAAA,MAAAA,I,aAAvBC;AACT;AAEA,SAAS,iBAAiB,OAAyD;C,cAC3E,UAAU,IAAI,kBAAkB;CACtC,IAAI,MAAM,OAAO;EACRC,IAAAA;EAAP,OACyEC,EAAAA,OAAAA,WAAAA,EAAAA,OAAAA,MAAAA,WADlE,KAAA,SAAS,OACd,oBAAC,gBAAD;GAAgB,MAAM,QAAQ;GAAM,MAAM,QAAQ;GAAM,SAAS,MAAM;EAAU,CAAA,IAC/E,MAFGC,EAAAA,KAAAA,SACkED,EAAAA,KAAAA,MAAAA,S,wBADlED;CAGT;CACOG,IAAAA;CAAP,OAAgBC,EAAAA,OAAAA,SAAAA,iBAAAA,EAAAA,OAAuC,SAAhD,KAAA,SAAS,gBAAgB,oBAAC,mBAAD,EAAmB,GAAI,MAAQ,CAAA,IAAI,MAAnDA,EAAAA,KAAAA,SAAAA,eAAuC,EAAA,KAAA,O,wBAAhDD;AACT;AAEA,SAAS,eAAe,OAA+D;C,cAC/E,EAAC,MAAM,MAAM,YAAW,OAMjBE;CAKI,AAAA,EAAA,OAAA,QAAA,EAAA,OADgB,QAAA,EAAA,OAAM,WAJ1B,MAAC,UAAU;EAGlB,AADA,MAAM,eAAe,GACrB,MAAM,gBAAgB;EACtB,IAAM,QAAQ,aAAa,MAAM,OAAO;EACxC,AAAI,SAAO,KAAK,OAAO,MAAM,OAAO,OAAO;CAC7C,GADa,EAAA,KAAA,MADgB,EAAA,KAAA,MAAM,EAAA,KAAA,S;CAMnCC,IAAAA;C,oDAAC,KAAA,oBAAA,UAAD,CAAW,CAAA,G;CAdbC,IAAAA;CADF,OAEqBC,EAAAA,OAAAA,KAAAA,SAAAA,EAAAA,OAGRH,MAJX,KAAA,oBAAC,UAAD;EACE,cAAY,KAAK;EACjB,WAAW;EACX,eAAY;EACZ,SAASA;EAOT,OAAO,KAAK;EACZ,MAAK;EAELC,UAAAA;CACM,CAAA,GAdWE,EAAAA,KAAAA,KAAAA,OAGRH,EAAAA,KAAAA,I,wBAJXE;AAiBJ;AAEA,SAAS,kBAAkB,OAAyD;;CAClF,IAAI,MAAM,SAAU,CAAC,MAAM,QAAQ,SAAS,KAAK,KAAK,CAAC,MAAM,QAAQ,SAAS,MAAM,GAClF,OAAO;CAI2BE,IAAAA;CAAWC,AAAAA,EAAAA,OAAAA,MAAAA,Q,aAAX,KAAA,EAAC,IAAI,MAAM,MAAK,GAALA,EAAAA,KAAAA,MAAAA,O;CAC3CC,IAAAA;C,oDAAC,KAAA,oBAAA,UAAD,CAAW,CAAA,G;CADbC,IAAAA;CADF,OACoCH,EAAAA,OAAAA,K,aAAlC,KAAA,oBAAC,YAAD;EAAY,QAAO;EAAO,QAAQA;EAChCE,UAAAA;CACU,CAAA,GAFsBF,EAAAA,KAAAA,I,YAAlCG;AAIJ;AAEA,SAAS,WAAW,SAAiB,OAAyB;CAC5D,IACM,SAAS,IAAI,IAAI,OAAO;CAE9B,IAAI,OAAO,UAAW,WACpB,OAAO;CAGT,IAAM,WAAW,QAAQ,MAAM,KAAK,CAAU;CAS9C,OARI,SAAS,WAAW,IACf,KAGL,MAAM,QAAQ,KAAK,IACd,KAGF,SAAS,KAAK,KAAK,CAAC,SAAS,MAAM,QAAQ,oBAAoB,GAAG,CAAC;AAC5E;AAEA,SAAS,eAAe,OAA6B;CACnD,IAAM,EAAC,SAAQ,OACT,UAAU,IAAI,IAAI,IAAI;CAE5B,AAAI,YAAY,KAAA,KAKhB,IAAI,IAAI,MAAM,CAAC,OAAO;AACxB;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAyB,OAAO,SAAU,cAAnC,SAA+C,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,MAAM,UAAU;AAChB,SAAS,oBAAoB,SAAiB,QAAQ,IAAI;CACxD,OAAO,QAAQ,KAAK,OAAO,KAAK,SAAS,SAAS,EAAE,IAAI;AAC1D;AClLA,SAAgB,cAAA,IAA0C;C,cAA5B,EAAC,YAADG,IACtB,EAAC,MAAK,eAAe,qBAAqB;CAIhD,IAAI,CAAC,SAAS;EAEgBC,IAAAA;E,0BAAE,KAAA,EAAA,6CAA6C,GAA/C,EAAA,KAAA,G;EACxBC,IAAAA;E,oDAAC,KAAA,oBAAA,QAAD;GACE,UAAA;GACA,MAAM;GACN,MAAK;GAEL,MAAK;GACL,MAAK;EACN,CAAA,G;EARHC,IAAAA;EADF,OAC4BF,EAAAA,OAAAA,K,aAA1B,KAAA,oBAAC,SAAD;GAAS,SAAA;GAAQ,SAASA;GAAkD,WAAU;GACpFC,UAAAA;EAQO,CAAA,GATiBD,EAAAA,KAAAA,I,YAA1BE;CAWJ;CAGEC,IAAAA;CADF,OAIU,EAAA,OAAA,U,aAHR,KAAA,oBAAC,QAAD;EACE,IAAG;EACH,UAAS;EACT,MAAM;EACN,MAAM;EACN,MAAK;EAEL,MAAK;EACL,MAAK;CACN,CAAA,GANO,EAAA,KAAA,S,YAHRA;AAWJ;AAEA,SAAgB,eAAA,IAA2C;C,cAA5B,EAAC,YAADJ,IAE3BK;CADF,OAIU,EAAA,OAAA,U,aAHR,KAAA,oBAAC,QAAD;EACE,IAAG;EACH,UAAU;EACV,MAAM;EACN,MAAM;EACN,MAAK;EAEL,MAAK;EACL,MAAK;CACN,CAAA,GANO,EAAA,KAAA,S,YAHRA;AAWJ;AClBA,SAAgB,gBAAA,IAaS;C,eAbO,EAC9B,OACA,YACA,aACA,SACA,iBACA,aACA,kBACA,iBACA,SACA,WACA,SACA,eAAA,OAZ8BE,IAY9B,gBAAA,OAAA,KAAA,KAAAC,IAEM,EAAC,MAAK,eAAe,qBAAqB,GAC1C,YAAY,CAAC,SAAS,CAAC,mBAA0B,gBAAgB,QAQzD,KAAA,QAAQ,aAAa,WAChB,KAAA,EAAQ,OAKOC;C,0BAAE,KAAA,EAAA,cAAc,GAAhB,EAAA,KAAA,G;CAFxBC,IAAAA;CAEwBD,AAAAA,EAAAA,OAAAA,K,aAFxB,KAAA,oBAAC,0BAAD,EAAA,UACE,oBAAC,KAAD;EAAK,YAAY;EACf,UAAA,oBAAC,aAAD;GAAa,OAAA;GAAOA,UAAAA;EAA+B,CAAA;CAChD,CAAA,EACmB,CAAA,GAFFA,EAAAA,KAAAA,I;CAIrBE,IAAAA;CAAqB,AAAA,EAAA,OAAA,oBAAA,EAAA,OAAoBC,mBAAAA,EAAAA,OAAxC,mBAAD,MAAC,mBAAoB,oBAAoB,gBAAgB,WAAW,MACnE,oBAAC,KAAD;EAAK,WAAW;EACd,UAAA,oBAAC,gBAAD,CAAiB,CAAA;CACd,CAAA,GAHe,EAAA,KAAA,kBAAoBA,EAAAA,KAAAA,iBAAxC,EAAA,KAAA,iB;CAKDC,IAAAA;CAEe,AAAA,EAAA,OAAA,cAAA,EAAA,OAFf,SAAA,EAAA,QAIgB,eAAA,EAAA,QACJ,WALZ,KAAA,SACC,oBAAC,kBAAD;EACc;EACL;EACM;EACJ;CACV,CAAA,GAJa,EAAA,KAAA,YAFf,EAAA,KAAA,OAIgB,EAAA,MAAA,aACJ,EAAA,MAAA,S;CAGZC,IAAAA;CAAyD,AAAA,EAAA,QAAA,WAAA,EAAA,QAAzD,aAAA,EAAA,QAA+B,eAA/B,KAAA,aAAa,oBAAC,YAAD;EAAY,MAAM;EAAa,aAAa;CAAU,CAAA,GAAV,EAAA,MAAA,SAAzD,EAAA,MAAA,WAA+B,EAAA,MAAA,a;CAC/BC,IAAAA;CACiD,AAAA,EAAA,QAAA,WAAA,EAAA,QADjD,oBAAA,EAAA,QAAoBH,mBAApB,KAAA,oBAAoB,gBAAgB,SAAS,KAC5C,oBAAC,YAAD;EAAY,MAAM;EAAiB,aAAa;CAAU,CAAA,GAAV,EAAA,MAAA,SADjD,EAAA,MAAA,kBAAoBA,EAAAA,MAAAA,iB;CAfvBI,IAAAA;CACGL,AAAAA,EAAAA,QAAAA,MAAAA,EAAAA,QAKAE,MAAAA,EAAAA,QAQAC,MAAAA,EAAAA,QACAC,MAfH,MAAA,qBAAC,KAAD;EAAK,SAAS;EAAG,YAAY;EAA7B,UAAA;GACGJ;GAKAE;GAQAC;GACAC;EAGE;C,IAjBFJ,EAAAA,MAAAA,IAKAE,EAAAA,MAAAA,IAQAC,EAAAA,MAAAA,IACAC,EAAAA,MAAAA,I;CArBLE,IAAAA;CAMED,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QALAN,MADF,MAAA,qBAAC,QAAD;EAAQ,UAAS;EAAjB,UAAA,CACEA,IAKAM,GAmBM;C,IAnBNA,EAAAA,MAAAA,KALAN,EAAAA,MAAAA,I;CARNQ,IAAAA;CAOID,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QAHME,MAAAA,EAAAA,QACKC,MALf,MAAA,oBAAC,sBAAD;EAAsB,WAAU;EAAK,UAAU;EAC7C,UAAA,oBAAC,iBAAD;GACE,MAAM;GACN,UAAS;GACT,MAAMD;GACN,WAAWC;GAEXH,UAAAA;EA0Be,CAAA;CACG,CAAA,GA3BlBA,EAAAA,MAAAA,KAHME,EAAAA,MAAAA,IACKC,EAAAA,MAAAA,I;CAgCG,IAAA,MAAA,gBAAgB,eAAe,iBACnC,MAAA,gBAAgB,YAAY,KAAA,GACzBC;C,yCAAgB,MAAA,gBAAA,WAAW;EAAC;EAAU;EAAU;CAAK,GAArD,EAAA,MAAA,e;CAGH,IAAA,MAAA,gBAAgB,IAAI,GACpB,MAAA,gBAAgB,IAAI,GAEvBC;C,yCAAgB,MAAA,gBAAA,EAAC,OAAO,OAAM,IAAI,EAAC,UAAU,EAAC,GAA9C,EAAA,MAAA,e;CAIe,IAAA,MAAA,gBAAgB,IAAI,GACnCC;C,6BAAE,MAAA,EAAA,6BAA6B,GAA/B,EAAA,MAAA,G;CACAC,IAAAA;CAAO,AAAA,EAAA,QAAA,aAAA,EAAA,QAEJ,KAFH,MAAA,OAAO,aAAc,WAClB,GAAG,UAAU,MACb,EAAE,8BAA8B,GAF5B,EAAA,MAAA,WAEJ,EAAA,MAAA,G;CALRC,IAAAA;CACoBC,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QACfH,OAAAA,EAAAA,QACAC,OAHL,MAAA,oBAAC,KAAD,EAAA,UACE,qBAAC,MAAD;EAAM,OAAA;EAAM,MAAME;EAAlB,UAAA;GACGH;GAAiC;GAAE;GACnCC;EAGG;CACH,CAAA,EAAA,CAAA,GANeE,EAAAA,MAAAA,KACfH,EAAAA,MAAAA,KACAC,EAAAA,MAAAA,K;CAKY,IAAA,MAAA,gBAAgB,IAAI,GACjB,MAAA,gBAAgB,IAAI,GACnCG;C,6BAAE,MAAA,EAAA,8BAA8B,GAAhC,EAAA,MAAA,G;CACAC,IAAAA;CAAO,AAAA,EAAA,QAAA,WAAA,EAAA,QAAwC,KAA/C,MAAA,OAAO,WAAY,WAAW,GAAG,QAAQ,MAAM,EAAE,8BAA8B,GAAxE,EAAA,MAAA,SAAwC,EAAA,MAAA,G;CAFlDC,IAAAA;CAAkBH,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QACfC,OAAAA,EAAAA,QACAC,OAFH,MAAA,qBAAC,MAAD;EAAM,OAAA;EAAM,MAAMF;EAAlB,UAAA;GACGC;GAAkC;GAAE;GACpCC;EACG;C,IAHYF,EAAAA,MAAAA,KACfC,EAAAA,MAAAA,KACAC,EAAAA,MAAAA,K;CAHLE,IAAAA;CAAiBC,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QACfF,OADF,MAAA,oBAAC,KAAD;EAAK,YAAYE;EACfF,UAAAA;CAIG,CAAA,GALYE,EAAAA,MAAAA,KACfF,EAAAA,MAAAA,K;CAVJG,IAAAA;CACEP,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QAQAK,OATF,MAAA,qBAAC,sBAAD;EAAsB,YAAW;EAAjC,UAAA,CACEL,KAQAK,GAMoB;C,IAdpBL,EAAAA,MAAAA,KAQAK,EAAAA,MAAAA,K;CAfJG,IAAAA;CACYF,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QACAG,OAAAA,EAAAA,QAEHZ,OAAAA,EAAAA,QAEPU,OANF,MAAA,oBAAC,aAAD;EACE,UAAUD;EACV,UAAUG;EACV,QAAO;EACP,OAAOZ;EAEPU,UAAAA;CAgBW,CAAA,GArBDD,EAAAA,MAAAA,KACAG,EAAAA,MAAAA,KAEHZ,EAAAA,MAAAA,KAEPU,EAAAA,MAAAA,K;CAkBDG,IAAAA;CAEa,AAAA,EAAA,QAAA,iBAAA,EAAA,QAFb,aAAA,EAAA,QAUwB,eAAA,EAAA,QAEd,KAZV,MAAA,aACC,oBAAC,eAAD;EACE,UAAU,gBAAgB,IAAI;EAC9B,UAAU,gBAAgB,IAAI;EAC9B,QAAO;EACP,OAAO,gBAAgB,EAAC,OAAO,OAAM,IAAI;GAAC,YAAY;GAAQ,UAAU;EAAC;EAEzE,UAAA,oBAAC,iBAAD;GAAiB,OAAA;GAAM,MAAM,gBAAgB,IAAI;GAC/C,UAAA,oBAAC,WAAD;IACE,YAAY,EAAC,kBAAiB;IAC9B,gBAAgB,EAAC,YAAW;IAC5B,SAAQ;IACL;GACJ,CAAA;EACc,CAAA;CACJ,CAAA,GAbH,EAAA,MAAA,eAFb,EAAA,MAAA,WAUwB,EAAA,MAAA,aAEd,EAAA,MAAA,G;CAzCbC,IAAAA;CACkBC,AAAAA,EAAAA,QAAAA,OAAAA,EAAAA,QACJC,OAAAA,EAAAA,QACGjB,OAAAA,EAAAA,QAEfY,OAAAA,EAAAA,QAwBCE,OA7BH,MAAA,qBAAC,cAAD;EACE,gBAAgBE;EAChB,YAAYC;EACZ,eAAejB;EAHjB,UAAA,CAKEY,KAwBCE,GAiBW;C,IA7CIE,EAAAA,MAAAA,KACJC,EAAAA,MAAAA,KACGjB,EAAAA,MAAAA,KAEfY,EAAAA,MAAAA,KAwBCE,EAAAA,MAAAA,K;CAlELI,IAAAA;CADF,OAEIrB,EAAAA,QAAAA,OAAAA,EAAAA,QAoCAkB,OArCF,MAAA,qBAAC,sBAAD;EAAsB,eAAc;EAAS,eAAY;EAAzD,UAAA,CACElB,KAoCAkB,GA+CoB;C,IAnFpBlB,EAAAA,MAAAA,KAoCAkB,EAAAA,MAAAA,K,4BArCFG;AAsFJ;AAEA,SAAS,kBAAA,IAAyD;C,eAAvC,EAAC,gBAADC,IAGTC;CAAe,AAAA,EAAA,OAAA,c,aAAf,KAAA,eAAe,WAAW,GAAX,EAAA,KAAA,a;CAA/B,IAAM,UAAUA,IACDC;CAAc,AAAA,EAAA,OAAA,c,aAAd,KAAA,cAAc,WAAW,GAAX,EAAA,KAAA,a;CAA7B,IAAM,SAASA,IAIXC;CAAyB,AAAA,EAAA,OAAA,U,aAAzB,KAAA,oBAAC,gBAAD,EAAgB,SAAS,QAAU,CAAA,GAAV,EAAA,KAAA,S;CACzBC,IAAAA;CAAwB,AAAA,EAAA,OAAA,S,aAAxB,KAAA,oBAAC,eAAD,EAAe,SAAS,OAAS,CAAA,GAAT,EAAA,KAAA,Q;CAF1BC,IAAAA;CADF,OAEIF,EAAAA,OAAAA,MAAAA,EAAAA,OACAC,MAFF,KAAA,qBAAAG,YAAA,EAAA,UAAA,CACEJ,IACAC,EACA,EAAA,CAAA,GAFAD,EAAAA,KAAAA,IACAC,EAAAA,KAAAA,I,0BAFFC;AAKJ;AC7FA,SAAS,aAAa,MAAY,OAA2C;CAK3E,OAJI,CAAC,QAAQ,CAAC,QACL,KAGF,SAAS,SAAS,CAAC,EAAE,KAAK,wBAAwB,KAAa,IAAI;AAC5E;AAEA,MAAM,eAAe,UACnB,SAAS,cAAc,KAAK,KAAK,SAAS,aAAa,KAAK;AAuC9D,SAAgB,UAAU,OAAuB;C,gBACzC,EAAC,UAAU,QAAQ,WAAW,gBAAgB,uBAAsB,OACpE,QAAQ,SAAS,GACjB,EAAC,MAAK,eAAe,qBAAqB,GAC1C,EAAC,kBAAkB,yBAAwB,eAAe,GAC1D,sBAAsB,kBAAkB,oBAAoB,GAC5D,2BAA2B,0BAA0B,GACrD,EAAC,MAAMG,OAAiB,kBAAkB,GAAnCA;C,2BAAW,KAAA,OAAA,KAAA,IAAA,CAAC,IAAZA,I;C,mBAEP,sBADY,aACU,CAAA,CAAU,SAAS,OAAO,SAEhD,iBAAiB,OAA+B,IAAI,GACpD,kBAAkB,OAA+B,IAAI,GACrD,gBAAgB,OAA8B,IAAI,GAClD,6BAA6B,OAAgC,IAAI,GACjE,uBAAuB,OAAiC,KAAA,CAAS,GACjE,wBAAwB,OAAiC,KAAA,CAAS,GAExCC;CAAsB,AAAA,EAAA,OAAA,Y,aAAtB,WAAM,gBAAgB,aAAa,SAAS,GAAtB,EAAA,KAAA,W;CAAtD,IAAM,CAAC,gBAAgB,SAASA,EAA6C,GAEvDC;CAA4B,AAAA,EAAA,OAAA,kBAAA,EAAA,OAA5B,gBAAa,KAAA,aAAA,IAAI,WAAW,cAAc,GAAd,EAAA,KAAA,gBAA5B,EAAA,KAAA,c;CAAtB,IAAM,gBAAgBA,IACGC;CAEIC,AAAAA,EAAAA,OAAAA,OAAAA,qBAAAA,EAAAA,OAFJ,gBAAa,KAAA,aAAA,IACpC,cACA,iBAAiB,GAAG,OAAO,mBAAmB,CAChD,GAD6BA,EAAAA,KAAAA,OAAAA,mBAFJ,EAAA,KAAA,c;CAAzB,IAAM,mBAAmBD,IAILE;C,uCAAa,KAAA,aAAA,IAAI,SAAS,EAAE,GAA5B,EAAA,MAAA,c;CAApB,IAAM,cAAcA,IACCC;C,uCAAa,KAAA,aAAA,IAAI,UAAU,UAAU,GAArC,EAAA,MAAA,c;CAArB,IAAM,eAAeA,IACKC;C,uCAAa,KAAA,aAAA,IACrC,eACA,KAAA,CACF,GAH0B,EAAA,MAAA,c;CAA1B,IAAM,oBAAoBA,IAKqBC;CACzC,AAAA,EAAA,QAAA,YAAA,EAAA,QAGkB,kBAAA,EAAA,QAHA,iBADuB,WACzC,SAAS,SAAS,aAAa,IAC1B,gBAEL,SAAS,SAAS,cAAc,IAC3B,iBAEF,SAAS,IANZ,EAAA,MAAA,UAGkB,EAAA,MAAA,gBAHA,EAAA,MAAA,e;CADxB,IAAM,CAAC,SAAS,cAAc,SAAiBA,EAQ9C,GACK,CAAC,aAAa,uBAAuB,SACzC,qBAAqB,KACvB,GACM,gBAAgB,iBAAiB,aAAa,mBAAmB,GAElBC;CACnD,AAAA,EAAA,QAAA,iBAAA,EAAA,QAE0B,oBAHyB,WACnD,gBACI,uBACA,aAAa,SAAS,gBAAgB,IACpC,mBACA,qBAJN,EAAA,MAAA,eAE0B,EAAA,MAAA,kB;CAH5B,IAAM,CAAC,YAAY,iBAAiB,SAAiBA,EAMrD,GACyEC;CACvE,AAAA,EAAA,QAAA,iBAAA,EAAA,QAAuC,oBADgC,YACvE,iBAAiB,aAAa,SAAS,gBAAgB,IAAI,KAAQ,kBAAnE,EAAA,MAAA,eAAuC,EAAA,MAAA,kB;CADzC,IAAM,CAAC,kBAAkB,uBAAuB,SAAyBA,GAEzE,GAC0BC;C,4CAAmB,MAAA,qBAAA,mBAAmB,gBAAgB,GAAtD,EAAA,MAAA,kB;CAA1B,IAAM,oBAAoBA,KAEpB,CAAC,KAAK,UAAU,SAA6B,KAAA,CAAS,GACjBC;CAClC,AAAA,EAAA,QAAA,c,eADkC,YACzC,OAAO,eAAgB,WAAW,cAAc,IAAzC,EAAA,MAAA,a;CADT,IAAM,CAAC,OAAO,YAAY,SAAiBA,GAE3C,GACM,CAAC,WAAW,gBAAgB,SAAiB,YAAY,GAClCC;CAAY,AAAA,EAAA,QAAA,aAAA,EAAA,QAAW,KAAvB,MAAA,YAAY,WAAW,CAAC,GAAZ,EAAA,MAAA,WAAW,EAAA,MAAA,G;CAApD,IAAM,SAASC,KACT,CAAC,aAAa,kBAAkB,SAA8B,KAAA,CAAS,GACLC;C,qDAAC,MAAA,CAAA,G;CAAzE,IAAM,CAAC,iBAAiB,sBAAsB,SAA0BA,GAAE,GACpE,CAAC,OAAO,YAAY,SAA4B,KAAA,CAAS,GACzD,CAAC,WAAW,gBAAgB,SAA6B,KAAA,CAAS,GAClE,CAAC,SAAS,cAAc,SAA6B,KAAA,CAAS,GAC9D,CAAC,iBAAiB,sBAAsB,SAAkB,EAAK,GAC/D,CAAC,kBAAkB,uBAAuB,SAAkB,EAAK,GACjE,CAAC,wBAAwB,6BAA6B,SAAS,EAAK,GAEhBC;C,qDAAC,MAAA,EAAA,cAAa,G;CAAxE,IAAM,EAAC,iBAAiB,uBAAsB,YAAYA,GAAe,GAG5CC;;EAC3B,IAAI,CAAC,0BAAA;GAA0B,MAAO,KAAA;GAAP,MAAA;;EAWxBC,IAAAA;EADoB,IAAA,EAAA,QAAA,uBAAA,EAAA,QARI,UAAA;GAA/B,IAAM,yBAAyB,SAAS,OACtCC,OAEF,GAEM,aADS,aAAa,sBACT,CAAA,CAAO,IAAIC,QAE9B,GAC2BC;G,+CAAsB,MAAA,sBAAA,CAAC,QAAQ,IAAI,CAAC,WAAW,GAA/C,EAAA,MAAA,qB;GAA3B,IAAM,qBAAqBA;G,AACpB,MAAA,CAAC,GAAG,YAAY,GAAG,kBAAkB,GADjB,EAAA,MAAA,qBARI,EAAA,MAAA,U;;EAS/B,MAAOH;;CAZT,IAAM,uBAAuBD,KAevB,iBAAiB,gBACnB,uBACA,qBAAqB,mBACnB,mBACA,YAGoBK;CACZ,AAAA,EAAA,QAAA,iB,eADY,MAAA,EACxB,YAAY,eACd,GADc,EAAA,MAAA,gB;CADd,IAAM,UAAU,UAAUA,GAEzB,GAEQC;CAQI,AAAA,EAAA,QAAA,WAAA,EAAA,QAAA,iBAAA,EAAA,QADT,WAAA,EAAA,QAJqB,eAAA,EAAA,QACnB,oBAAA,EAAA,QACA,wBAAA,EAAA,QAJU,kBADP,MAAA,QAAQ,WAAW;EACxB,YAAY;EACZ,aAAa,qBAAqB;GAChC,mBAAmB;GACnB;GACA;EACF,CAAC;EACD;EACA,SAAS;EACT,kBAAkB;CACpB,CAAC,GAVM,EAAA,MAAA,SAQI,EAAA,MAAA,eADT,EAAA,MAAA,SAJqB,EAAA,MAAA,aACnB,EAAA,MAAA,kBACA,EAAA,MAAA,sBAJU,EAAA,MAAA,gB;CAFhB,IAAM,SAASC,KAsB6BC;C,qDAAM,YAAA;EAChD,AAIA,qBAAqB,aADrB,qBAAqB,QAAQ,YAAY,GACV,KAAA;CACjC,G;CANA,IAAM,0BAA0BC,KAQeC;C,qDAAM,YAAA;EACnD,AAIA,sBAAsB,aADtB,sBAAsB,QAAQ,YAAY,GACV,KAAA;CAClC,G;CANA,IAAM,6BAA6BC,KASjCC;CA+BY,AAAA,EAAA,QAAA,cAAA,EAAA,QA4BQ,UAAA,EAAA,QA9BV,oBAAA,EAAA,QAXuB,WAAA,EAAA,QAWH,qBAAA,EAAA,QAM5B,gBAAA,EAAA,QAhB+DC,OAAAA,UAAAA,EAAAA,QAVD,eAAA,EAAA,QAa1D,oBAAA,EAAA,QALuB,SAAA,EAAA,QAhBvB,mBAAA,EAAA,QAsBA,wBAAA,EAAA,QAbqD,uBAAA,EAAA,QASwB,KAnBnF,OAAC,YAAoC;EACnC,IAAI,iBAAiB;GAGnB,AAFA,wBAAwB,GACxB,2BAA2B,GAC3B,mBAAmB,EAAK;GACxB;EACF;EAEA,IAAM,oBACJ,WAAW,iBAAiB,UAAU,QAAQ,cAAc,aACxD,eAAe,iBAAiB,mBAAmB,mBAAmB,GAEtE,UAIF;GACF,OAAO,SAAS,SAAS;GACzB,SAAS,SAAS,WAAW;GAC7B,QAAQ,YAAY,KAAK,UAAU,SAAS,UAAU,OAAO,QAAQ,MAAM,CAAC,GAAG,CAAC;GAChF,aAAa,qBAAqB;IAChC;IACA;IACA;GACF,CAAC;GACD,YACE,SAAS,eACR,eACG,uBACA,oBAAoB,oBAClB,mBACA;GACR,SAAS;EACX;EAKA,AAHA,aAAa,IAAI,SAAS,QAAQ,KAAK,GACvC,aAAa,IAAI,UAAU,QAAQ,OAAO,GAAG,GAE7C,2BAA2B;EAE3B,IAAM,WAAW,QAAQ,MAAM,KAAK,CAAC,CAAC,SAAS;EAU/C,IARA,mBAAmB,CAAC,QAAQ,OAAO,SAAS,QAAQ,GACpD,oBAAoB,EAAK,GACzB,mBAAmB,CAAC,CAAC,GACrB,SAAS,QAAQ,OAAO,QAAY,MAAM,QAAQ,OAAO,KAAK,IAAI,KAAA,CAAS,GAC3E,eAAe,KAAA,CAAS,GACxB,aAAa,KAAA,CAAS,GACtB,WAAW,KAAA,CAAS,GAEhB,QAAQ,OAAO,SAAS,CAAC,UAC3B;EAGF,IAAM,eAAkD;GACtD,aAAa,QAAQ,eAAe,CAAC;GACrC,GAAI,QAAQ,UAAU,EAAC,SAAS,QAAQ,QAAO,IAAI,CAAC;EACtD,GAEM,YAAY,OAAO,WAAW;GAClC,YAAY,QAAQ;GACpB,SAAS,QAAQ;GACjB,aAAa,QAAQ;GACrB,SAAS,QAAQ;EACnB,CAAC,GAEK,SAAS,UAAU,OACvB,UAAU,WACR,SACA,kBAAkB,QAAQ,OAAO,QAAQ,OAAO,QAAQ,YAAY,CACtE,CACF;EACA,OAAO,MAAM;EAEb,IAAM,aAAa,KAAK,IAAI;EAE5B,qBAAqB,UAAU,UAAU,WACtC,MAAM,QAAQ,OAAO,QAAQ,OAAO,QAAQ;GAAC,gBAAgB;GAAO,KAAK;EAAQ,CAAC,CAAC,CACnF,UAAU;GACT,OAAO,QAAQ;IAKb,AAJA,aAAa,IAAI,EAAE,GACnB,WAAW,KAAK,IAAI,IAAI,UAAU,GAClC,eAAe,IAAI,MAAM,GACzB,mBAAmB,EAAK,GACxB,SAAS,KAAA,CAAS;GACpB;GACA,QAAQ,QAAQ;IAEd,AADA,SAAS,GAAG,GACZ,mBAAmB,EAAK;GAC1B;EACF,CAAC;CACL,GA5DY,EAAA,MAAA,YA4BQ,EAAA,MAAA,QA9BV,EAAA,MAAA,kBAXuB,EAAA,MAAA,SAWH,EAAA,MAAA,mBAM5B,EAAA,MAAA,cAhB+DA,EAAAA,MAAAA,OAAAA,QAVD,EAAA,MAAA,aAa1D,EAAA,MAAA,kBALuB,EAAA,MAAA,OAhBvB,EAAA,MAAA,iBAsBA,EAAA,MAAA,sBAbqD,EAAA,MAAA,qBASwB,EAAA,MAAA,G;CApBrF,IAAM,uBAAuBC,KAkH3BC;CAQE,AAAA,EAAA,QAAA,wBAAA,EAAA,QAFA,gBAAA,EAAA,QADA,uBALF,OAAC,mBAA6C;EAC5C,CAAI,mBAAmB,KAAA,KAAc,uBAAuB,cAAc,OAI1E,oBAAoB,cAAc,GAClC,aAAa,IAAI,eAAe,cAAc,GAE9C,qBAAqB,EAAC,aAAa,eAAc,CAAC;CACpD,GADE,EAAA,MAAA,sBAFA,EAAA,MAAA,cADA,EAAA,MAAA,qB;CANJ,IAAM,iBAAiBC,KAerBC;CAIE,AAAA,EAAA,QAAA,wBAAA,EAAA,QAFA,gBAAA,EAAA,QACA,cAHF,OAAC,QAAwC;EACvC,IAAM,aAAa,IAAI,OAAO;EAG9B,AAFA,aAAa,IAAI,WAAW,UAAU,GACtC,WAAW,UAAU,GACrB,qBAAqB,EAAC,SAAS,WAAU,CAAC;CAC5C,GADE,EAAA,MAAA,sBAFA,EAAA,MAAA,cACA,EAAA,MAAA,Y;CAJJ,IAAM,sBAAsBC,KAW1BC;CAUE,AAAA,EAAA,QAAA,wBAAA,EAAA,QADA,gBATF,OAAC,kBAA0B;EACzB,AAAI,cAAc,YAAY,MAAM,WAClC,oBAAoB,GAAG,GACvB,2BAA2B,SAAS,MAAM,MAI5C,cAAc,aAAa,GAC3B,oBAAoB,EAAK,GACzB,aAAa,IAAI,cAAc,aAAa,GAC5C,qBAAqB,EAAC,YAAY,cAAa,CAAC;CAClD,GADE,EAAA,MAAA,sBADA,EAAA,MAAA,c;CAVJ,IAAM,mBAAmBC,KAiBvBC;CACE,AAAA,EAAA,QAAA,mB,eADF,OAAC,UAAwC;EACvC,iBAAiBC,MAAI,OAAO,KAAK;CACnC,GADE,EAAA,MAAA,kB;CAFJ,IAAM,yBAAyBC,KAS7BC;CAOI,AAAA,EAAA,QAAA,wBAAA,EAAA,QADA,gBANJ,OAAC,UAAuC;EACtC,IAAM,sBAAsBF,MAAI,OAAO,SAAS;EAGhD,AAFA,oBAAoB,uBAAuB,GAAG,GAE1C,mBAAmB,mBAAmB,MACxC,cAAc,mBAAmB,GACjC,aAAa,IAAI,cAAc,mBAAmB,GAClD,qBAAqB,EAAC,YAAY,oBAAmB,CAAC;CAE1D,GAFI,EAAA,MAAA,sBADA,EAAA,MAAA,c;CAPN,IAAM,+BAA+BG,KAgBnCC;CAEE,AAAA,EAAA,QAAA,iB,eAFF,OAAC,UAAwC;EACvC,IAAMC,mBAAiBL,MAAI,OAAO;EAClC,eAAeK,qBAAmB,YAAY,KAAA,IAAYA,gBAAc;CAC1E,GADE,EAAA,MAAA,gB;CAHJ,IAAM,0BAA0BC,KAQQC;C,qDAAC,OAAA,UAA0B;EACjE,AAAIP,MAAI,SAAS,cAIjB,oBAAoB,kBAClB,cAAc,WAAW,KAAK,CAACA,OAAK,GAAG,cAAc,MAAM,GAAG,EAAE,CAAC,IAAI,CAACA,OAAK,GAAG,aAAa,CAC7F;CACF,G;CARA,IAAM,sBAAsBQ,KAScC;CAOzB,AAAA,EAAA,QAAA,UAAA,EAAA,QANX,oBAAA,EAAA,QAUJ,gBAAA,EAAA,QAF8BC,OAAAA,SAAAA,EAAAA,QAF6CnB,OAAAA,UAAAA,EAAAA,QAKzCoB,OAAAA,OAAAA,EAAAA,QAL2B,SAPrB,YAAM;EAC9C,IAAI,kBAAkB;GAEpB,AADA,2BAA2B,GAC3B,oBAAoB,EAAK;GACzB;EACF;EAEA,IAAMC,WAAS,OAAO,WAAW,UAAU,kBAAkB,OAAO,OAAO,QAAQ,CAAC,CAAC,CAAC,GAEhF,gBAAgB,CAAC,OAAO,SAAS,MAAM,KAAK,CAAC,CAAC,SAAS;EAgB7D,AAdA,aAAa,IAAI,SAAS,KAAK,GAC/B,aAAa,IAAI,UAAU,OAAO,GAAG,GAErC,wBAAwB,GAExB,OAAOA,QAAM,GACb,mBAAmB,CAAC,CAAC,GACrB,mBAAmB,EAAK,GACxB,eAAe,KAAA,CAAS,GACxB,oBAAoB,aAAa,GACjC,SAAS,OAAO,QAAY,MAAM,OAAO,KAAK,IAAI,KAAA,CAAS,GAC3D,aAAa,KAAA,CAAS,GACtB,WAAW,KAAA,CAAS,GAEf,kBAIL,sBAAsB,UAAU,OAC7B,OAAO,OAAO,OAAO,QAAQ;GAAC,QAAQ,CAAC,YAAY,SAAS;GAAG,oBAAoB;EAAI,CAAC,CAAC,CACzF,UAAU;GACT,MAAM;GACN,QAAQ,UAAQ;IAEd,AADA,SAASC,KAAG,GACZ,oBAAoB,EAAK;GAC3B;EACF,CAAC;CACL,GA/BiB,EAAA,MAAA,QANX,EAAA,MAAA,kBAUJ,EAAA,MAAA,cAF8BH,EAAAA,MAAAA,OAAAA,OAF6CnB,EAAAA,MAAAA,OAAAA,QAKzCoB,EAAAA,MAAAA,OAAAA,KAL2B,EAAA,MAAA,O;CAP/D,IAAM,wBAAwBG,KAkD5BC;CAEE,AAAA,EAAA,QAAA,e,eAFF,OAAC,UAAkB;EAEjB,AADA,aAAa,KAAK,GAClB,aAAa,IAAI,UAAU,KAAK;CAClC,GADE,EAAA,MAAA,c;CAHJ,IAAM,qBAAqBC,KAUzBC;CA+CiC,AAAA,EAAA,QAAA,cAAA,EAAA,QAD2B,WAAA,EAAA,QAA/C,YAAA,EAAA,QAGsB,eAAA,EAAA,SAf/B,SAlCJ,OAAC,SAAwC;EACvC,IAAM,QAAQ,KAAK,MAAM,gBAAgB;EACzC,IAAI,CAAC,OACH,OAAO;EAGT,IAAM,GAAG,gBAAgB,aAAa,YAAY,OAG5C,QAA8B,oBAAoB,IADzC,gBAAgB,QACyB,CAAE;EAC1D,IAAI,CAAC,OAAO,OAAO;EACf,IAAA,iBACA;EAEJ,AAAI,mBAAmB,cAAc,MAC/B,aAAa,SAAS,cAAc,KACtC,kBAAgB,gBAChB,wBAAsB,MAEtB,wBAAsB;EAI1B,IAAMZ,mBACJ,uBAAuB,MAAM,QAAQ,WAAW,KAChD,CAAC,qBAAqB,MAAM,QAAQ,WAAW,IAC3C,MAAM,QAAQ,cACd,KAAA;EAeN,OAZEA,qBACC,CAAC,uBAAuB,MAAM,QAAQ,WAAW,KAChD,qBAAqB,MAAM,QAAQ,WAAW,MAEhD,MAAM,KAAK;GACT,UAAU;GACV,IAAI;GACJ,QAAQ;GACR,OAAO;EACT,CAAC,GAGI;GACL,OAAO,MAAM;GACb,QAAQ,MAAM;GACd,WAAW,KAAK,UAAU,MAAM,QAAQ,MAAM,CAAC;GAC/C,SAAS,SAAS,SAAS,WAAW,IAAI,cAAc;GACxD,YAAYa,mBAAiB;GAC7B,kBAAkBC;GAClB,aAAad,oBAAkB;GAC/B,KAAK;EACP;CACF,GALiC,EAAA,MAAA,YAD2B,EAAA,MAAA,SAA/C,EAAA,MAAA,UAGsB,EAAA,MAAA,aAf/B,EAAA,OAAA,O;CAnCN,IAAM,kBAAkBe,KA2DtBC;CAyBE,AAAA,EAAA,SAAA,wBAAA,EAAA,SATA,gBAAA,EAAA,SAdA,cAAA,EAAA,SAOA,uBATF,OAAC,iBAAiC;EAyBhC,AAvBA,WAAW,aAAa,OAAO,GAC/B,SAAS,aAAa,KAAK,GAC3B,aAAa,aAAa,SAAS,GACnC,cAAc,aAAa,UAAU,GACjC,aAAa,oBACf,oBAAoB,aAAa,gBAAgB,GAEnD,oBAAoB,aAAa,WAAW,GAC5C,OAAO,aAAa,GAAG,GAEvB,eAAe,SAAS,mBAAmB,aAAa,KAAK,GAC7D,gBAAgB,SAAS,mBAAmB,aAAa,SAAS,GAGlE,aAAa,MAAM;GACjB,OAAO,aAAa;GACpB,QAAQ,aAAa;GACrB,SAAS,aAAa;GACtB,YAAY,aAAa,oBAAoB,aAAa;GAC1D,aAAa,aAAa;EAC5B,CAAC,GAGD,qBAAqB,YAAY;CACnC,GADE,EAAA,OAAA,sBATA,EAAA,OAAA,cAdA,EAAA,OAAA,YAOA,EAAA,OAAA,qB;CAVJ,IAAM,wBAAwBC,KAgC5BC;CAKmB,AAAA,EAAA,SAAA,mBAAA,EAAA,SAQjB,yBAAA,EAAA,SACA,SAdF,OAAC,UAAwB;EACvB,IAAI,CAACvB,MAAI,iBAAiB,CAAC,oBAAoB,cAAc,SAASA,KAAG,GACvE;EAGF,IAAM,WAAW,gBAAgBA,MAAI,cAAc,QAAQ,YAAY,CAAC;EACxE,AAAK,aAML,MAAI,eAAe,GACnB,sBAAsB,QAAQ,GAC9B,MAAM,KAAK;GACT,UAAU;GACV,IAAI;GACJ,QAAQ;GACR,OAAO;EACT,CAAC;CACH,GAfmB,EAAA,OAAA,iBAQjB,EAAA,OAAA,uBACA,EAAA,OAAA,O;CAfJ,IAAM,cAAcwB,KA0BlBC;CAII,AAAA,EAAA,SAAA,wBAAA,EAAA,SAD+CC,OAAAA,SAHnD,OAAC,UAAyB;EACxB,IAAM,eACJ,cAAc,WAAW,aAAa,cAAc,SAAS,MAAM,MAAM;EAC3E,AAAI,YAAY,KAAK,KAAK,gBAAgB,OAAO,UAC/C,qBAAqB,GACrB,MAAM,eAAe,GACrB,MAAM,gBAAgB;CAE1B,GAJI,EAAA,OAAA,sBAD+CA,EAAAA,OAAAA,OAAAA,O;CAJrD,IAAM,gBAAgBC,KAaZC,KAQPC;CARH,AAE8C,EAAA,SAAA,iBAAA,EAAA,SADF,eADlC,aACR,OAAO,SAAS,iBAAiB,SAAS,WAAW,GACrD,OAAO,SAAS,iBAAiB,WAAW,aAAa,SAE5C;EAEX,AADA,OAAO,SAAS,oBAAoB,SAAS,WAAW,GACxD,OAAO,SAAS,oBAAoB,WAAW,aAAa;CAC9D,IACC,MAAA,CAAC,eAAe,WAAW,GANgB,EAAA,OAAA,eADF,EAAA,OAAA,a,4DAD5C,UAAUD,KAQPC,GAA4B;CAErBC,IAAAA,KAKPC;CALH,A,sDAAU,kBACK;EAEX,AADA,wBAAwB,GACxB,2BAA2B;CAC7B,GACC,MAAA,CAAC,yBAAyB,0BAA0B,G,4DALvD,UAAUD,KAKPC,GAAqD;CAEPC,IAAAA;CAK/C,AAAA,EAAA,SAAA,oBAAA,EAAA,SAJI,eAD2C,YAAM;EACrD,AAAI,gBAAgB,mBAIpB,iBAAiB,oBAAoB;CACvC,GADE,EAAA,OAAA,kBAJI,EAAA,OAAA,a;CADN,IAAM,4BAA4B,eAAeA,GAMhD,GAESC;CACH,AAAA,EAAA,SAAA,iBAAA,EAAA,SAGL,6BAJQ,YAAM;EACd,AAAK,iBAGL,0BAA0B;CAE5B,GALO,EAAA,OAAA,eAGL,EAAA,OAAA,2B;CAECC,IAAAA;CANH,AAMI,EAAA,SAAA,gB,gBAAD,MAAA,CAAC,aAAa,GAAb,EAAA,OAAA,e,eANJ,UAAUD,KAMPC,GAAe;CAEmCC,IAAAA;CAEjD,AAAA,EAAA,SAAA,iB,gBAFiD,OAAC,UAAkC;EACtF,AAAI,MAAM,SAAS,KACjB,eAAe,eAAe;CAElC,GAFI,EAAA,OAAA,gB;CAFJ,IAAM,gCAAgC,eAAeA,GAIpD,GAESC;CACR,AAAA,EAAA,SAAA,iCAAA,EAAA,SAA8B,oBADtB,YAAM;EACd,8BAA8B,gBAAgB;CAEhD,GAFE,EAAA,OAAA,+BAA8B,EAAA,OAAA,kB;CAE7BC,IAAAA;CAHH,AAGI,EAAA,SAAA,mB,gBAAD,MAAA,CAAC,gBAAgB,GAAhB,EAAA,OAAA,kB,eAHJ,UAAUD,KAGPC,GAAkB;CAGnBC,IAAAA;CAQQ,AAAA,EAAA,SAAA,iBAAA,EAAA,SAGJ,UAAA,EAAA,SAPuB,eAAA,EAAA,SACnB,oBAAA,EAAA,SACA,wBANR,OAAC,aAAqB,gBAAyC;EAC7D,IAAMC,iBAAkD;GACtD,aACE,qBAAqB;IACnB,mBAAmB;IACnB;IACA;GACF,CAAC,KAAK,CAAC;GACT,GAAI,gBAAgB,EAAC,SAAS,cAAa,IAAI,CAAC;EAClD;EACA,OAAO,OAAO,OACZ,OAAO,WAAW,SAAS,kBAAkB,aAAa,aAAaA,cAAY,CAAC,CACtF;CACF,GALQ,EAAA,OAAA,eAGJ,EAAA,OAAA,QAPuB,EAAA,OAAA,aACnB,EAAA,OAAA,kBACA,EAAA,OAAA,sB;CAPV,IAAM,cAAcC,KA2BF,MAAA,gBAAgB,uBAAuB,YACjC,MAAA,kBAAwB,kBAF5CC;CAGW,AAAA,EAAA,SAAA,WAAA,EAAA,SACC,YAAA,EAAA,SAEU,0BAAA,EAAA,SADH,uBAAA,EAAA,SAKI,2BAAA,EAAA,SAFK,gCAAA,EAAA,SAKA,4BAAA,EAAA,SAJP,qBAAA,EAAA,SAGN,eAAA,EAAA,SAXDC,OAAAA,EAAAA,SACMC,OAAAA,EAAAA,SASb,OAXP,MAAA,oBAAC,iBAAD;EACE,YAAYD;EACZ,kBAAkBC;EACT;EACC;EACV,iBAAiB;EACjB,oBAAoB;EACQ;EAC5B,0BAA0B;EACP;EACnB,qBAAqB;EAChB;EACQ;EACa;CAC3B,CAAA,GAXU,EAAA,OAAA,SACC,EAAA,OAAA,UAEU,EAAA,OAAA,wBADH,EAAA,OAAA,qBAKI,EAAA,OAAA,yBAFK,EAAA,OAAA,8BAKA,EAAA,OAAA,0BAJP,EAAA,OAAA,mBAGN,EAAA,OAAA,aAXDD,EAAAA,OAAAA,KACMC,EAAAA,OAAAA,KASb,EAAA,OAAA,K;CASG,IAAA,MAAA,yBAAyB,OAAO,aAAa,OAAO,aAAa,KAQ5D,MAAA,qBAAqB,aAAa,cAQnC,MAAA,qBAAqB,gBAAgB,cAAc,gBAAgB,SAE/D,MAAA,gBAAgB,MACT,MAAA,gBAAgB,aACpB,MAAA,qBAAqB,gBAAgB,UAAU,KAC/C,MAAA,gBAAgB,SAOGC;C,+BAAE,MAAA,EAAA,aAAa,GAAf,EAAA,OAAA,G;CAFxBC,IAAAA;CAEwBD,AAAAA,EAAAA,SAAAA,M,gBAFxB,MAAA,oBAAC,8BAAD,EAAA,UACE,oBAAC,MAAD,EAAA,UACE,oBAAC,aAAD;EAAa,OAAA;EAAOA,UAAAA;CAA8B,CAAA,EAC9C,CAAA,EACsB,CAAA,GAFNA,EAAAA,OAAAA,K;CAGxBE,IAAAA;CACgB,AAAA,EAAA,SAAA,Q,gBADhB,MAAA,oBAAC,kBAAD;EACE,cAAc;EACd,UAAU;EACV,KAAK;EACL,YAAY;CACb,CAAA,GAJe,EAAA,OAAA,O;CARpBC,IAAAA;CAEIF,AAAAA,EAAAA,SAAAA,OAAAA,EAAAA,SAKAC,OAPJ,MAAA,oBAAC,gBAAD;EAAgB,SAAQ;EAAO,eAAY;EACzC,UAAA,qBAAC,KAAD;GAAK,WAAU;GAAK,UAAU;GAA9B,UAAA,CACED,KAKAC,GAMG;;CACS,CAAA,GAZZD,EAAAA,OAAAA,KAKAC,EAAAA,OAAAA,K;CASFE,IAAAA;CAEY,AAAA,EAAA,SAAA,sBAAA,EAAA,SACUtC,OAAAA,SAAAA,EAAAA,SAFNC,OAAAA,OAAAA,EAAAA,SAGSe,OAAAA,SAJzB,MAAA,oBAAC,cAAD;EACE,OAAO,OAAO;EACd,UAAU;EACV,aAAa,OAAO;EACpB,gBAAgB,OAAO;EACvB,WAAW;CACZ,CAAA,GAJW,EAAA,OAAA,oBACUhB,EAAAA,OAAAA,OAAAA,OAFNC,EAAAA,OAAAA,OAAAA,KAGSe,EAAAA,OAAAA,OAAAA,O;CAIzBuB,IAAAA;CAKqB,AAAA,EAAA,SAAA,yBAAA,EAAA,SADD,wBAAA,EAAA,SADA,oBAAA,EAAA,SAGE,sBAAA,EAAA,SALGvB,OAAAA,SAAAA,EAAAA,SACN,mBAFnB,MAAA,oBAAC,mBAAD;EACE,gBAAgB,OAAO;EACN;EACC;EAClB,kBAAkB;EAClB,mBAAmB;EACC;CACrB,CAAA,GAFoB,EAAA,OAAA,uBADD,EAAA,OAAA,sBADA,EAAA,OAAA,kBAGE,EAAA,OAAA,oBALGA,EAAAA,OAAAA,OAAAA,OACN,EAAA,OAAA,iB;CAXrBwB,IAAAA;CACEF,AAAAA,EAAAA,SAAAA,OAAAA,EAAAA,SAQAC,OATF,MAAA,qBAAC,gBAAD;EAAgB,SAAQ;EAAxB,UAAA,CACED,KAQAC,GAQc;C,IAhBdD,EAAAA,OAAAA,KAQAC,EAAAA,OAAAA,K;CArCNE,IAAAA;CAQiCC,AAAAA,EAAAA,SAAAA,gBAAAA,eAAAA,EAAAA,SAEJC,gBAAAA,WAAAA,EAAAA,SAHHC,gBAAAA,QAAAA,EAAAA,SAFpBC,OAAAA,EAAAA,SAIOC,OAAAA,EAAAA,SAITT,OAAAA,EAAAA,SAeAG,OA5BJ,MAAA,oBAAC,KAAD;EAAK,QAAO;EAAU,WAAU;EAAK,UAAU;EAC7C,UAAA,qBAAC,WAAD;GACE,WAAU;GACV,OAAM;GACN,aACEK;GAEF,MAAME;GACN,aAAaC;GACb,SAASF;GACT,SAASG;GACT,SAAQ;GAVV,UAAA,CAYEZ,KAeAG,GAkBS;;CACR,CAAA,GAvC4BE,EAAAA,OAAAA,gBAAAA,aAEJC,EAAAA,OAAAA,gBAAAA,SAHHC,EAAAA,OAAAA,gBAAAA,MAFpBC,EAAAA,OAAAA,KAIOC,EAAAA,OAAAA,KAITT,EAAAA,OAAAA,KAeAG,EAAAA,OAAAA,K;CAuBWU,IAAAA;CACQ,AAAA,EAAA,SAAA,eAAA,EAAA,SACnB,oBAAA,EAAA,SACA,wBAHW,MAAA,qBAAqB;EAChC,mBAAmB;EACnB;EACA;CACF,CAAC,GAHoB,EAAA,OAAA,aACnB,EAAA,OAAA,kBACA,EAAA,OAAA,sB;CANJC,IAAAA;CAQW,AAAA,EAAA,SAAA,iBAAA,EAAA,SAKA,WAAA,EAAA,SAEA,WAAA,EAAA,SAdF,SAAA,EAAA,SAUW,oBAAA,EAAA,SACD,mBAAA,EAAA,SAHA,mBAAA,EAAA,SACJ,eAAA,EAAA,SAIF,aAAA,EAAA,SAXED,OAAAA,EAAAA,SADD,kBAFd,MAAA,oBAAC,iBAAD;EACS;EACP,YAAY;EACZ,aAAaA;EAKb,SAAS;EACQ;EACJ;EACK;EACD;EACR;EACE;EACF;CACV,CAAA,GARU,EAAA,OAAA,eAKA,EAAA,OAAA,SAEA,EAAA,OAAA,SAdF,EAAA,OAAA,OAUW,EAAA,OAAA,kBACD,EAAA,OAAA,iBAHA,EAAA,OAAA,iBACJ,EAAA,OAAA,aAIF,EAAA,OAAA,WAXEA,EAAAA,OAAAA,KADD,EAAA,OAAA,gB;CAzDlBE,IAAAA;CAIWC,AAAAA,EAAAA,SAAAA,OAAAA,EAAAA,SAGPZ,OAAAA,EAAAA,SAgDAU,OAvDJ,MAAA,oBAAC,KAAD;EAAK,QAAO;EAAU,WAAU;EAAK,UAAU;EAC7C,UAAA,qBAAC,WAAD;GACE,WAAU;GAEV,OAAOE;GACP,SAAS;GAJX,UAAA,CAMEZ,KAgDAU,GAiBS;;CACR,CAAA,GArEME,EAAAA,OAAAA,KAGPZ,EAAAA,OAAAA,KAgDAU,EAAAA,OAAAA,K;CAuBOG,IAAAA;;EACL,UAAU;EACV,MAAM;EACN,KAAK;EACL,WAAW;EACX,QAAQ;EACR,eAAe;CACjB,G;CACSC,IAAAA;CAAiC,AAAA,EAAA,SAAA,yB,gBAAjC,YAAM,0BAA0B,CAAC,sBAAsB,GAAtB,EAAA,OAAA,wB;CAE9BC,IAAAA;;EAAC,SAAS;EAAQ,YAAY;EAAU,QAAQ;CAAM,G;CAAlEC,IAAAA;CACG,AAAA,EAAA,SAAA,yB,gBADH,MAAA,oBAAC,OAAD;EAAK,OAAOD;EACT,UAAyB,IAAzB,yBAA0B,kBAAsB,kBAAvB,CAAkB,CAAuB;CAChE,CAAA,GADF,EAAA,OAAA,wB;CAdLE,IAAAA;CAWWH,AAAAA,EAAAA,SAAAA,OAAAA,EAAAA,SAETE,OAbF,MAAA,oBAAC,QAAD;EACE,MAAK;EACL,SAAS;EACT,OAAOH;EAQP,SAASC;EAETE,UAAAA;CAGM,CAAA,GALGF,EAAAA,OAAAA,KAETE,EAAAA,OAAAA,K;CAUiBE,IAAAA;CAAO9E,AAAAA,EAAAA,SAAAA,OAAAA,S,gBAAP,MAAA,OAAO,UAAU,CAAC,GAAXA,EAAAA,OAAAA,OAAAA,Q;CAN1B+E,IAAAA;CAOiB,AAAA,EAAA,SAAA,eAAA,EAAA,SAJI,mBAAA,EAAA,SAEH,SAAA,EAAA,SADS,yBAAA,EAAA,SAERD,OAAAA,EAAAA,SAJV,OAFT,MAAA,oBAAC,wBAAD,EAAA,UACE,oBAAC,aAAD;EACO;EACY;EACM;EACvB,cAAc;EACd,eAAeA;EACF;CACd,CAAA,EACqB,CAAA,GAFP,EAAA,OAAA,aAJI,EAAA,OAAA,iBAEH,EAAA,OAAA,OADS,EAAA,OAAA,uBAERA,EAAAA,OAAAA,KAJV,EAAA,OAAA,K;CApBXE,IAAAA;CACEH,AAAAA,EAAAA,SAAAA,OAAAA,EAAAA,SAiBAE,OAlBF,MAAA,qBAAC,0BAAD,EAAA,UAAA,CACEF,KAiBAE,GAUwB,EAAA,CAAA,GA3BxBF,EAAAA,OAAAA,KAiBAE,EAAAA,OAAAA,K;CApGNE,IAAAA;CAIUC,AAAAA,EAAAA,SAAAA,OAAAA,EAAAA,SAINX,OAAAA,EAAAA,SA0EAS,OAlFJ,MAAA,oBAAC,oBAAD;EAAoB,WAAU;EAAO,UAAU;EAAG,YAAY;EAC5D,UAAA,qBAAC,WAAD;GACE,SAAS;GACT,aAAa,OAAO,aAAa;GACjC,MAAME;GACN,SAAS;GACT,SAAQ;GALV,UAAA,CAOEX,KA0EAS,GA6BS;;CACO,CAAA,GA5GVE,EAAAA,OAAAA,KAINX,EAAAA,OAAAA,KA0EAS,EAAAA,OAAAA,K;CAzGNG,IAAAA;CADF,OAQIjC,EAAAA,SAAAA,OAAAA,EAAAA,SAgBA+B,OAvBF,MAAA,qBAAC,MAAD;EACE,eAAc;EACd,QAAO;EACP,KAAK;EACL,UAAS;EACT,eAAY;EALd,UAAA,CAOE/B,KAgBA+B,GAiHI;C,IAjIJ/B,EAAAA,OAAAA,KAgBA+B,EAAAA,OAAAA,K,8BAvBFE;AA0IJ;AA1nBkC,SAAAI,SAAC,WAAA;CAC7B,OAAA,kCAAkCH,UAAQ,GAAG;;AAL7C,SAAAE,QAAC,SAAA;CACC,OAAA,wBAAwB,OAAO,KAAK,QAAQ,UAAU;;AC3L9D,SAAgB,YAAA,IAMwB;C,cANZ,EAC1B,QACA,UAAU,mBAFgBE,IAOsBC;;EAC9C,IAAI,MAAM,QAAQ,cAAc,GAAG;GAC1BC,IAAAA;GAAP,AAAU,EAAA,OAAA,iB,aAAH,KAAA,GAAG,cAAc,GAAd,EAAA,KAAA,gB,YAAV,KAAOA;GAAP,MAAA;EACF;EACOC,IAAAA;EAAkBC,IAAAA,EAAAA,OAAAA,OAAX,WAAW,YAAA,EAAA,OAEV,gBAAA;GADTC,IAAAA;G,AACS,EAAA,OAAA,iB,aADT,MAAC,WACC,OAAO,kBAAkB,aACpB,eAAe,MAAM,CAAC,CAAC,IAAIC,OAAa,IAE1C,OAAO,IAAIC,MAAe,GAHtB,EAAA,KAAA,gB,YAFR,KAAA,OAAO,WAAW,SAAS,KAAK,CAAC,CAAC,KACvC,IAAIF,EAKH,GACD,WAAWG,MAAgB,CAC7B,GARyBJ,EAAAA,KAAAA,OAAX,WAAW,UAEV,EAAA,KAAA,gB;;EAFf,KAAOD;;CAWT,OAAO,qBAAqBQ,EAAS;AACvC;AALiB,SAAA,OAAC,KAAA;CAAQ,OAAA,GAAG,GAAG;;AAFN,SAAA,OAAC,IAAA;CAAO,OAAA,GAAG;;AAFO,SAAAD,QAAC,GAAA;CAAM,OAAA,EAAE;;ACArD,SAAgB,gBAAgB,OAA6B;C,cAC1BE;C,oDAAC,KAAA,EAAA,YAAY,cAAa,G;CAA3D,IAAM,iBAAiB,UAAUA,EAA2B,GACxBC;CAAS,AAAA,EAAA,OAAA,kBAAA,EAAA,OAAuCC,MAAP,OAAO,YAAhD,KAAA;EAAC,QAAQ;EAAgB,UAAU,MAAM,OAAO;CAAQ,GAA/C,EAAA,KAAA,gBAAuCA,EAAAA,KAAAA,MAAP,OAAO,U;CAApF,IAAM,kBAAkB,YAAYD,EAAyD,GAKvFE;C,oDAAC,KAAA,oBAAA,MAAD;EAAM,YAAW;EAAS,QAAO;EAAO,gBAAe;EACrD,UAAA,oBAAC,gBAAD,CAAiB,CAAA;CACb,CAAA,G;CAJVC,IAAAA;CADF,OAQuD,EAAA,OAAA,mBAAA,EAAA,OAAxB,SAP7B,KAAA,oBAAC,UAAD;EACE,UACED;EAKF,UAAA,oBAAC,uBAAD;GAAuB,GAAI;GAAwB;EAAkB,CAAA;CAC7D,CAAA,GAD2C,EAAA,KAAA,iBAAxB,EAAA,KAAA,O,wBAP7BC;AAUJ;AAEA,SAAS,sBAAA,IAKyE;C,eALnD,EAC7B,UACA,QACA,QACA,oBAJ6BC,IAMvB,iBAAiB,IAAI,eAAe,GAalCC,IAAcC,IAAYC;CAZb,IAAA,EAAA,OAAA,YAAA,EAAA,OAAA,UAAA,EAAA,OAUSC,OAAAA,kBAAAA,EAAAA,OAP5B,gBAAA;EAHF,IAAM,eAAe,OAAO,OAAO,GAE7B,WACJ,0BAA0B,QAEtB,CAAC,aAAa,WAAW,YAAY,IAErC,gBAEA,YAAY,aAAa,aAAa,WACtC,iBAAiB,OAAO,kBAAkB,aAAa,WAAW,SAAS;E,AAEzE,KAAA,UAAc,KAAA,WAAY,KAAA,SAAS;GAAC;GAAU;GAAW;EAAc,CAAC,GAA9C,EAAA,KAAA,UAZb,EAAA,KAAA,QAUSA,EAAAA,KAAAA,OAAAA,gBAP5B,EAAA,KAAA,gB;;CASKC,IAAAA;CAAP,OAAQJ,EAAAA,OAAAA,MAAAA,EAAAA,OAAcC,MAAAA,EAAAA,OAAYC,MAA3B,KAAA,oBAACF,IAAD,EAAA,UAA2BE,GAA0D,GAAtED,EAAsE,GAApFD,EAAAA,KAAAA,IAAcC,EAAAA,KAAAA,IAAYC,EAAAA,KAAAA,I,0BAA3BE;AACT;;;;AC9BA,IAAa,sBAAb,cAAyC,UAGvC;CACA,YAAY,OAAiC;EAE3C,AADA,MAAM,KAAK,GACX,KAAK,QAAQ;GAAC,OAAO;GAAM,YAAY;EAAC;CAC1C;CAEA,OAAO,yBAAyB,OAAgB;EAE9C,OAAO,EAAC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,GAAG,QAAO;CACpE;CAEA,0BAA0B;EAExB,AADA,KAAK,MAAM,UAAU,GACrB,KAAK,UAAU,UAAU;GAAC,OAAO;GAAM,YAAY,KAAK,aAAa;EAAC,EAAE;CAC1E;CAEA,kCAAkC;EAEhC,AADA,kBAAkB,GAClB,KAAK,kBAAkB;CACzB;CAEA,SAAS;EACP,IAAI,CAAC,KAAK,MAAM,OACd,OAAO,KAAK,MAAM;EAGpB,IAAM,UAAU,KAAK,MAAM,OACrB,iBAAiB,KAAK,MAAM,aAAa;EAE/C,OACE,oBAAC,MAAD;GACE,QAAO;GACP,UAAS;GACT,UAAU;IAAC;IAAG;IAAG;IAAG;GAAC;GACrB,UAAU;GACV,QAAO;GACP,MAAK;GAEL,UAAA,oBAAC,WAAD;IAAW,MAAM;IACf,UAAA,qBAAC,QAAD;KAAQ,KAAK;KAAb,UAAA;MACE,oBAAC,OAAD,EAAA,UACE,oBAAC,QAAD;OACE,SAAS,iBAAiB,KAAK,4BAA4B,KAAK;OAChE,MAAM,iBAAiB,0BAA0B;OACjD,MAAK;MACN,CAAA,EACE,CAAA;MAEL,oBAAC,SAAD,EAAA,UAAS,oBAA0B,CAAA;MAEnC,oBAAC,MAAD;OAAM,QAAA;OAAO,QAAQ;OAAG,UAAS;OAAO,SAAS;OAAG,MAAK;OACvD,UAAA,oBAAC,QAAD;QAAQ,KAAK;QACV,UAAA,WACC,oBAAC,MAAD;SAAM,MAAM;SACV,UAAA,qBAAC,UAAD,EAAA,UAAA,CAAQ,WAAQ,OAAgB,EAAA,CAAA;QAC5B,CAAA;OAEF,CAAA;MACJ,CAAA;KACA;;GACC,CAAA;EACP,CAAA;CAEV;AACF;;;;;;;;ACtFA,SAAgB,oBACd,MACsD;CACtD,IAAI,SAAS,IACP,gBACJ,KAAK,CAAC,CAAC,OAAO,UAAmB;EAE/B,MADA,SAAS,IACH;CACR,CAAC,GAGC,gBAAgB,KAAK,OAAO;CAGhC,SAAS,cAAc,OAAc;E,cAC5BE;EAAP,OAA0B,EAAA,OAAA,Q,aAAnB,KAAA,oBAAC,eAAD,EAAe,GAAI,MAAQ,CAAA,GAAR,EAAA,KAAA,O,YAAnBA;CACT;CAEA,OAAO;EACL,WAAW;EACX,aAAa;GACX,AAAK,WACL,SAAS,IACT,gBAAgB,KAAK,OAAO;EAC9B;CACF;AACF;AC1BA,MAAM,WAAW;;;;;AAcjB,SAAS,qBAAqB,OAAkC;C,eACxD,EAAC,aAAa,aAAa,cAAc,UAAU,cAAa,OAGlEE;CAAgB,AAAA,EAAA,OAAA,c,aAAhB,KAAA,oBAAC,MAAD;EAAM,MAAM;EAAI,UAAA;CAAkB,CAAA,GAAlB,EAAA,KAAA,a;CAEdC,IAAAA;CAKQ,AAAA,EAAA,OAAA,eAAA,EAAA,OAFG,YAHX,KAAA,oBAAC,QAAD;EACE,eAAY;EACZ,UAAU;EACV,SAAS;EACT,SAAS;EACT,MAAM;EACN,MAAK;CACN,CAAA,GAFO,EAAA,KAAA,aAFG,EAAA,KAAA,U;CAKXC,IAAAA;CAMQ,AAAA,EAAA,OAAA,gBAAA,EAAA,OAFG,aAJX,KAAA,oBAAC,QAAD;EACE,eAAY;EACZ,UAAU;EACV,MAAK;EACL,SAAS;EACT,SAAS;EACT,MAAM;CACP,CAAA,GADO,EAAA,KAAA,cAFG,EAAA,KAAA,W;CAbbC,IAAAA;CACEF,AAAAA,EAAAA,OAAAA,MAAAA,EAAAA,OAQAC,MATF,KAAA,qBAAC,MAAD;EAAM,KAAK;EAAX,UAAA,CACED,IAQAC,EAQI;C,IAhBJD,EAAAA,KAAAA,IAQAC,EAAAA,KAAAA,I;CAXJE,IAAAA;CADF,OAEIJ,EAAAA,QAAAA,MAAAA,EAAAA,QACAG,MAFF,KAAA,qBAAC,OAAD;EAAO,KAAK;EAAG,YAAY;EAA3B,UAAA,CACEH,IACAG,EAkBK;C,IAnBLH,EAAAA,MAAAA,IACAG,EAAAA,MAAAA,I,0BAFFC;AAsBJ;;;;;;AAYA,SAAgB,cAAA,IAAyD;C,cAA3C,EAAC,UAAU,cAAXC,IACtB,QAAQ,SAAS,GACjB,EAAC,MAAK,eAAe,qBAAqB,GAC1C,SAAS,eAAe,QAAQ,GAChC,UAAU,eAAe,SAAS,GAE9BC;CAmBA,AAAA,EAAA,OAAA,UAAA,EAAA,OAIA,WAAA,EAAA,OAZC,KAAA,EAAA,OAPP,SAJM,WAAM;EAGd,IAAM,eAAe;GACnB,MAAM,KAAK;IAAC,IAAI;IAAU,UAAU;GAAI,CAAC;EAC3C;EAuBA,OAtBA,MAAM,KAAK;GACT,IAAI;GACJ,UAAU;GACV,UAAU;GACV,QAAQ;GACR,OAAO,EAAE,4BAA4B;GACrC,aACE,oBAAC,sBAAD;IACE,aAAa,EAAE,6BAA6B;IAC5C,aAAa,EAAE,kCAAkC;IACjD,cAAc,EAAE,8BAA8B;IAC9C,gBAAgB;KAEd,AADA,OAAO,GACP,OAAO;IACT;IACA,iBAAiB;KAEf,AADA,OAAO,GACP,QAAQ;IACV;GACD,CAAA;EAEL,CAAC,GACM;CAET,GAXU,EAAA,KAAA,QAIA,EAAA,KAAA,SAZC,EAAA,KAAA,GAPP,EAAA,KAAA,O;CA0BDC,IAAAA;CAEH,OAFI,EAAA,OAAA,KAAA,EAAA,OAAG,SAAJ,KAAA,CAAC,GAAG,KAAK,GAAR,EAAA,KAAA,GAAG,EAAA,KAAA,O,wBA9BP,UAAUD,IA8BPC,EAAU,GAEN;AACT;ACrFA,MAAM,qBAAyC;CAAC,SAAS;CAAO,WAAW;AAAK,GAM1E,wBAAQ,IAAI,IAAkE,GAC9E,4BAAY,IAAI,IAAgB;AAEtC,SAAS,WAAW,WAA2B;CAC7C,OAAO,GAAG,0BAA0B,WAAW;AACjD;AAEA,SAAS,SAAe;CACtB,UAAU,SAAS,aAAa,SAAS,CAAC;AAC5C;AAEA,SAAS,UAAU,UAAkC;CACnD,UAAU,IAAI,QAAQ;CAEtB,IAAM,mBAAmB,4BAA4B;EAEnD,AADA,MAAM,MAAM,GACZ,SAAS;CACX,CAAC;CACD,aAAa;EAEX,AADA,UAAU,OAAO,QAAQ,GACzB,iBAAiB;CACnB;AACF;AAEA,SAAS,gBAAgB,KAAwC;CAC/D,IAAI,QAAQ,MACV,OAAO;CAET,IAAI;EACF,IAAM,SAAkB,KAAK,MAAM,GAAG;EACtC,OAAO,cAAc,MAAM,IACvB;GAAC,SAAS,OAAO,YAAY;GAAM,WAAW,OAAO,cAAc;EAAI,IACvE;CACN,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,uBAAuB,WAAuC;CAC5E,IAAM,UAAU,WAAW,GACrB,SAAS,MAAM,IAAI,SAAS;CAClC,IAAI,CAAC,SAEH,OAAO,QAAQ,cAAc;CAE/B,IAAM,MAAM,QAAQ,QAAQ,WAAW,SAAS,CAAC;CACjD,IAAI,UAAU,OAAO,QAAQ,KAC3B,OAAO,OAAO;CAEhB,IAAM,aAAa,gBAAgB,GAAG;CAEtC,OADA,MAAM,IAAI,WAAW;EAAC;EAAK;CAAU,CAAC,GAC/B;AACT;AAEA,SAAgB,wBACd,WACA,OACoB;CACpB,IAAM,OAAO;EAAC,GAAG,uBAAuB,SAAS;EAAG,GAAG;CAAK,GACtD,UAAU,WAAW,GACvB,MAAqB,KAAK,UAAU,IAAI;CAC5C,IAAI;EACF,SAAS,QAAQ,WAAW,SAAS,GAAG,GAAG;CAC7C,QAAQ;EAEN,MAAM,SAAS,QAAQ,WAAW,SAAS,CAAC,KAAK;CACnD;CAGA,OAFA,MAAM,IAAI,WAAW;EAAC;EAAK,YAAY;CAAI,CAAC,GAC5C,OAAO,GACA;AACT;AASA,SAAgB,sBAAsB,WAAuC;C,cAGzEE;CAFF,OAE+B,EAAA,OAAA,Y,aAA7B,WAAM,uBAAuB,SAAS,GAAT,EAAA,KAAA,W,YAFxB,qBACL,WACAA,IACAC,KACF;AACF;AAFI,SAAA,QAAA;CAAM,OAAA;;;ACxFV,MAAM,WAAW,0BACf,OAAO,yBAA8B,CAAC,MAAM,YAAY,EAAC,SAAS,OAAO,SAAQ,EAAE,CACrF,GACM,iBAAiB,SAAS;AAMhC,SAAS,aAAa,OAA0B;C,eACrBE;C,oDAAC,KAAA,EAAA,YAAY,IAAG,G;CAAzC,IAAM,SAAS,UAAUA,EAAiB,GACbC;CAEbC,AAAAA,EAAAA,OAAAA,MAAL,KAAK,U,aAFa,KAAA;EAC3B,mBAAmB;EACnB,GAAG,MAAM,KAAK;CAChB,GADgBA,EAAAA,KAAAA,MAAL,KAAK,S;CAFhB,IAAM,SAAuBD,IAIXE;C,+BAAO,KAAA,OAAA,OAAO,CAAC,CAAC,aAAa,WAA7B,EAAA,KAAA,Q;CAAlB,IAAM,YAAYA,IACZ,kBAAkB,OAAO,MAAM,UAAU,YAAY,IACrD,aAAa,sBAAsB,SAAS,GAC5C,eAAe,mBAAmB,WAAW,SAGjDC;CAA8B,AAAA,EAAA,OAAA,Y,aAA9B,WAAM,wBAAwB,WAAW;EAAC,SAAS;EAAM,WAAW;CAAK,CAAC,GAA5C,EAAA,KAAA,W;CADhC,IAAM,QAAQC,IAKZC;CAA8B,AAAA,EAAA,OAAA,Y,aAA9B,WAAM,wBAAwB,WAAW,EAAC,WAAW,GAAI,CAAC,GAA5B,EAAA,KAAA,W;CADhC,IAAM,UAAUC,IAKdC;CAA8B,AAAA,EAAA,OAAA,Y,cAA9B,WAAM,wBAAwB,WAAW;EAAC,SAAS;EAAO,WAAW;CAAK,CAAC,GAA7C,EAAA,KAAA,W;CADhC,IAAM,kBAAkBC,IAQjBC;CAMa,AAAA,EAAA,QAAA,UAAA,EAAA,QAJ0B,UAAA,EAAA,QAMI,SAAA,EAAA,QAAlB,mBAAA,EAAA,QAPxB,gBAAA,EAAA,QACiE,mBAFlE,MAAC,WACA,eACE,oBAAC,gBAAD;EAAgB,GAAI;EAAgB;EAAQ,mBAAmB;CAAkB,CAAA,IAEjF,oBAAC,WAAD;EACE,GAAI;EACI;EACA;EACR,oBAAoB,kBAAkB,QAAQ,KAAA;CAC/C,CAAA,GAHS,EAAA,MAAA,QAJ0B,EAAA,MAAA,QAMI,EAAA,MAAA,OAAlB,EAAA,MAAA,iBAPxB,EAAA,MAAA,cACiE,EAAA,MAAA,iB;CAHrEC,IAAAA;CAAyB,AAAA,EAAA,QAAA,UAAA,EAAA,QAAgB,UAAA,EAAA,QACtCD,MADH,KAAA,oBAAC,iBAAD;EAAyB;EAAgB;EACtCA,UAAAA;CAYc,CAAA,GAbQ,EAAA,MAAA,QAAgB,EAAA,MAAA,QACtCA,EAAAA,MAAAA,I;CAaFE,IAAAA;CAC4C,AAAA,EAAA,QAAA,WAAA,EAAA,QAAlB,SAAA,EAAA,QADWC,cAAAA,EAAAA,QAArC,mBAAA,EAAA,QAAoB,gBAApB,KAAA,mBAAmB,CAAC,gBAAgB,CAAC,WAAW,aAC/C,oBAAC,eAAD;EAAe,UAAU;EAAO,WAAW;CAAU,CAAA,GAAV,EAAA,MAAA,SAAlB,EAAA,MAAA,OADWA,EAAAA,MAAAA,YAArC,EAAA,MAAA,iBAAoB,EAAA,MAAA,c;CAfvBC,IAAAA;CADF,OAEIH,EAAAA,QAAAA,MAAAA,EAAAA,QAcCC,MAfH,KAAA,qBAAC,qBAAD;EAAqB,SAAS,SAAS;EAAvC,UAAA,CACED,IAcCC,EAGkB;C,IAjBnBD,EAAAA,MAAAA,IAcCC,EAAAA,MAAAA,I,0BAfHE;AAoBJ"}
|