sanity-plugin-mux-input 2.17.0 → 2.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/components/icons/ToolIcon.tsx","../src/context/DrmPlaybackWarningContext.tsx","../src/hooks/useClient.ts","../src/util/createSearchFilter.ts","../src/hooks/useAssets.ts","../src/hooks/useDialogState.ts","../src/actions/secrets.ts","../src/hooks/useSaveSecrets.ts","../src/util/constants.ts","../src/hooks/useSecretsDocumentValues.ts","../src/hooks/useSecretsFormState.ts","../src/util/readSecrets.ts","../src/components/MuxLogo.tsx","../src/components/ConfigureApi.styled.tsx","../src/components/FormField.tsx","../src/components/ConfigureApi.tsx","../src/util/assetTitlePlaceholder.ts","../src/util/parsers.ts","../src/actions/assets.ts","../src/hooks/useMuxAssets.ts","../src/hooks/useImportMuxAssets.ts","../src/hooks/useInView.ts","../src/util/getPlaybackPolicy.ts","../src/util/generateJwt.ts","../src/util/createUrlParamsObject.ts","../src/util/getAnimatedPosterSrc.ts","../src/util/getPosterSrc.ts","../src/util/tryWithSuspend.ts","../src/components/VideoThumbnail.tsx","../src/components/ImportVideosFromMux.tsx","../src/components/PageSelector.tsx","../src/util/addKeysToMuxData.ts","../src/hooks/useResyncMuxMetadata.ts","../src/components/ResyncMetadata.tsx","../src/components/SelectSortOptions.tsx","../src/components/SpinnerBox.tsx","../src/components/IconInfo.tsx","../src/components/icons/Resolution.tsx","../src/components/icons/StopWatch.tsx","../src/hooks/useResyncAsset.ts","../src/util/textTracks.ts","../src/util/types.ts","../src/components/AddCaptionDialog.tsx","../src/components/EditCaptionDialog.tsx","../src/components/TextTracksManager.tsx","../src/context/DialogStateContext.tsx","../src/util/getVideoSrc.ts","../src/components/CaptionsDialog.tsx","../node_modules/use-device-pixel-ratio/dist/index.module.js","../src/util/formatSeconds.ts","../src/components/EditThumbnailDialog.tsx","../src/components/icons/Audio.tsx","../src/components/VideoPlayer.tsx","../src/components/documentPreview/MissingSchemaType.tsx","../src/components/documentPreview/TimeAgo.tsx","../src/components/documentPreview/DraftStatus.tsx","../src/components/documentPreview/PublishedStatus.tsx","../src/components/documentPreview/PaneItemPreview.tsx","../src/components/documentPreview/DocumentPreview.tsx","../src/components/VideoDetails/VideoReferences.tsx","../src/components/VideoDetails/DeleteDialog.tsx","../src/hooks/useDocReferences.ts","../src/util/getVideoMetadata.ts","../src/components/VideoDetails/useVideoDetails.ts","../src/components/VideoDetails/VideoDetails.tsx","../src/components/VideoMetadata.tsx","../src/components/VideoInBrowser.tsx","../src/components/VideosBrowser.tsx","../src/components/StudioTool.tsx","../src/hooks/useAccessControl.ts","../src/hooks/useAssetDocumentValues.ts","../src/hooks/useMuxPolling.ts","../node_modules/use-error-boundary/lib/index.module.js","../src/components/ErrorBoundaryCard.tsx","../src/components/Input.styled.tsx","../src/components/Onboard.tsx","../src/clients/upChunkObservable.ts","../src/util/roundPxString.ts","../src/actions/upload.ts","../src/util/asserters.ts","../src/util/extractFiles.ts","../src/components/SelectAsset.tsx","../src/components/InputBrowser.tsx","../src/hooks/useCancelUpload.ts","../src/components/Player.styled.tsx","../src/components/UploadProgress.tsx","../src/components/Player.tsx","../src/components/withFocusRing/helpers.ts","../src/components/FileInputMenuItem.styled.tsx","../src/components/FileInputMenuItem.tsx","../src/components/PlayerActionsMenu.tsx","../src/hooks/useFetchFileSize.ts","../src/hooks/useMediaMetadata.ts","../src/util/convertWatermarkToMux.ts","../src/util/formatBytes.ts","../src/components/DraggableWatermark.tsx","../src/components/TextTracksEditor.tsx","../src/components/uploadConfiguration/PlaybackPolicyOption.tsx","../src/components/uploadConfiguration/PlaybackPolicyWarning.tsx","../src/components/uploadConfiguration/PlaybackPolicy.tsx","../src/components/uploadConfiguration/ResolutionTierSelector.tsx","../src/components/uploadConfiguration/StaticRenditionSelector.tsx","../src/components/UploadConfiguration.tsx","../src/components/withFocusRing/withFocusRing.ts","../src/components/Uploader.styled.tsx","../src/components/FileInputButton.tsx","../src/components/UploadPlaceholder.tsx","../src/components/Uploader.tsx","../src/components/Input.tsx","../src/plugin.tsx","../src/schema.ts","../src/_exports/index.ts"],"sourcesContent":["/**\n * Icon of a monitor with a play button.\n * Credits: material design icons & react-icons\n */\nconst ToolIcon = () => (\n <svg\n stroke=\"currentColor\"\n fill=\"currentColor\"\n strokeWidth=\"0\"\n viewBox=\"0 0 24 24\"\n height=\"1em\"\n width=\"1em\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z\" />\n </svg>\n)\n\nexport default ToolIcon\n","import {Button, Card, Dialog, Stack, Text} from '@sanity/ui'\nimport React, {createContext, useContext, useState} from 'react'\n\nimport {PluginConfig} from '../util/types'\n\nconst LOCAL_STORAGE_HAS_SHOWN_WARNING_KEY = 'mux-plugin-has-shown-drm-playback-warning'\n\ntype DrmPlaybackWarningContextContextProps = {\n hasShownWarning: boolean\n setHasWarnedAboutDrmPlayback: (b: boolean) => void\n}\n\nconst DrmPlaybackWarningContext = createContext<DrmPlaybackWarningContextContextProps>({\n hasShownWarning: false,\n setHasWarnedAboutDrmPlayback: () => {\n return null\n },\n})\n\ninterface DrmPlaybackWarningContextProviderProps {\n config?: PluginConfig\n children: React.ReactNode\n}\n\nexport const DrmPlaybackWarningContextProvider = ({\n config,\n children,\n}: DrmPlaybackWarningContextProviderProps) => {\n const warningDisabled = config?.disableDrmPlaybackWarning ?? false\n const hasWarned: boolean =\n warningDisabled || window.localStorage.getItem(LOCAL_STORAGE_HAS_SHOWN_WARNING_KEY) === 'true'\n const [hasWarnedAboutDrmPlayback, setHasWarnedAboutDrmPlayback] = useState(hasWarned)\n\n const setHasShownWarning = (b: boolean) => {\n window.localStorage.setItem(LOCAL_STORAGE_HAS_SHOWN_WARNING_KEY, b.toString())\n setHasWarnedAboutDrmPlayback(b)\n }\n return (\n <DrmPlaybackWarningContext.Provider\n value={{\n hasShownWarning: hasWarnedAboutDrmPlayback,\n setHasWarnedAboutDrmPlayback: setHasShownWarning,\n }}\n >\n {children}\n </DrmPlaybackWarningContext.Provider>\n )\n}\n\nexport const useDrmPlaybackWarningContext = () => {\n const context = useContext(DrmPlaybackWarningContext)\n return context\n}\n\nexport const DRMWarningDialog = ({onClose}: {onClose: () => void}) => {\n const {setHasWarnedAboutDrmPlayback} = useDrmPlaybackWarningContext()\n const _onClose = () => {\n setHasWarnedAboutDrmPlayback(true)\n onClose()\n }\n return (\n <Dialog\n open\n id=\"drm-playback-warn\"\n onClose={_onClose}\n header=\"DRM Playback Warning\"\n footer={\n <Stack padding={3}>\n <Button mode=\"ghost\" tone=\"primary\" onClick={_onClose} text=\"Ok\" />\n </Stack>\n }\n >\n <Stack space={3} padding={3}>\n <Card padding={[3, 3, 3]} radius={2}>\n <Stack space={3}>\n <Text size={1} weight=\"semibold\">\n DRM-protected playback will generate a license with a small associated cost. The\n plugin will attempt to play signed or public playback IDs instead whenever possible.\n </Text>\n </Stack>\n </Card>\n <Card padding={[3, 3, 3]} radius={2} tone=\"suggest\">\n <Stack space={3}>\n <Text size={1} weight=\"semibold\">\n This is a one time warning. If it persists, you can disable it from your plugin\n configuration.\n </Text>\n </Stack>\n </Card>\n </Stack>\n </Dialog>\n )\n}\n","// As it's required to specify the API Version this custom hook ensures it's all using the same version\nimport {useClient as useSanityClient} from 'sanity'\n\nexport const SANITY_API_VERSION = '2024-03-05'\n\nexport function useClient() {\n return useSanityClient({apiVersion: SANITY_API_VERSION})\n}\n","// Adaptation of Sanity's createSearchQuery for our limited use case:\n// https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/core/search/weighted/createSearchQuery.ts\nimport {compact, toLower, trim, uniq, words} from 'lodash'\n\nconst SPECIAL_CHARS = /([^!@#$%^&*(),\\\\/?\";:{}|[\\]+<>\\s-])+/g\nconst STRIP_EDGE_CHARS = /(^[.]+)|([.]+$)/\n\nfunction tokenize(string: string): string[] {\n return (string.match(SPECIAL_CHARS) || []).map((token) => token.replace(STRIP_EDGE_CHARS, ''))\n}\n\nfunction toGroqParams(terms: string[]): Record<string, string> {\n const params: Record<string, string> = {}\n return terms.reduce((acc, term, i) => {\n acc[`t${i}`] = `*${term}*` // \"t\" is short for term\n return acc\n }, params)\n}\n\n/**\n * Convert a string into an array of tokenized terms.\n *\n * Any (multi word) text wrapped in double quotes will be treated as \"phrases\", or separate tokens that\n * will not have its special characters removed.\n * E.g.`\"the\" \"fantastic mr\" fox fox book` =\\> [\"the\", `\"fantastic mr\"`, \"fox\", \"book\"]\n *\n * Phrases wrapped in quotes are assigned relevance scoring differently from regular words.\n *\n * @internal\n */\nfunction extractTermsFromQuery(query: string): string[] {\n const quotedQueries = [] as string[]\n const unquotedQuery = query.replace(/(\"[^\"]*\")/g, (match) => {\n if (words(match).length > 1) {\n quotedQueries.push(match)\n return ''\n }\n return match\n })\n\n // Lowercase and trim quoted queries\n const quotedTerms = quotedQueries.map((str) => trim(toLower(str)))\n\n /**\n * Convert (remaining) search query into an array of deduped, sanitized tokens.\n * All white space and special characters are removed.\n * e.g. \"The saint of Saint-Germain-des-Prés\" =\\> ['the', 'saint', 'of', 'germain', 'des', 'pres']\n */\n const remainingTerms = uniq(compact(tokenize(toLower(unquotedQuery))))\n\n return [...quotedTerms, ...remainingTerms]\n}\n\n/**\n * Create GROQ constraints, given search terms and the full spec of available document types and fields.\n * Essentially a large list of all possible fields (joined by logical OR) to match our search terms against.\n */\nfunction createConstraints(terms: string[], includeAssetId: boolean) {\n const searchPaths = includeAssetId ? ['filename', 'assetId'] : ['filename']\n const constraints = terms\n .map((_term, i) => searchPaths.map((joinedPath) => `${joinedPath} match $t${i}`))\n .filter((constraint) => constraint.length > 0)\n\n return constraints.map((constraint) => `(${constraint.join(' || ')})`)\n}\n\nexport function createSearchFilter(query: string) {\n const terms = extractTermsFromQuery(query)\n\n return {\n filter: createConstraints(terms, query.length >= 8), // if the search is big enough, include the assetId (mux id) in the results\n params: {\n ...toGroqParams(terms),\n },\n }\n}\n","import {useMemo, useState} from 'react'\nimport {collate, createHookFromObservableFactory, DocumentStore, useDocumentStore} from 'sanity'\n\nimport {SANITY_API_VERSION} from '../hooks/useClient'\nimport {createSearchFilter} from '../util/createSearchFilter'\nimport type {VideoAssetDocument} from '../util/types'\n\nexport const ASSET_SORT_OPTIONS = {\n createdDesc: {groq: '_createdAt desc', label: 'Newest first'},\n createdAsc: {groq: '_createdAt asc', label: 'First created (oldest)'},\n filenameAsc: {groq: 'filename asc', label: 'By filename (A-Z)'},\n filenameDesc: {groq: 'filename desc', label: 'By filename (Z-A)'},\n}\n\nexport type SortOption = keyof typeof ASSET_SORT_OPTIONS\n\nconst useAssetDocuments = createHookFromObservableFactory<\n VideoAssetDocument[],\n {\n documentStore: DocumentStore\n sort: SortOption\n searchQuery: string\n }\n>(({documentStore, sort, searchQuery}) => {\n const search = createSearchFilter(searchQuery)\n const filter = [`_type == \"mux.videoAsset\"`, ...search.filter].filter(Boolean).join(' && ')\n\n const sortFragment = ASSET_SORT_OPTIONS[sort].groq\n return documentStore.listenQuery(\n /* groq */ `*[${filter}] | order(${sortFragment})`,\n search.params,\n {\n apiVersion: SANITY_API_VERSION,\n }\n )\n})\n\nexport default function useAssets() {\n const documentStore = useDocumentStore()\n const [sort, setSort] = useState<SortOption>('createdDesc')\n const [searchQuery, setSearchQuery] = useState('')\n\n const [assetDocuments = [], isLoading] = useAssetDocuments(\n useMemo(() => ({documentStore, sort, searchQuery}), [documentStore, sort, searchQuery])\n )\n\n const assets = useMemo(\n () =>\n // Avoid displaying both drafts & published assets by collating them together and giving preference to drafts\n collate<VideoAssetDocument>(assetDocuments).map(\n (collated) =>\n ({\n ...(collated.draft || collated.published || {}),\n _id: collated.id,\n }) as VideoAssetDocument\n ),\n [assetDocuments]\n )\n\n return {\n assets,\n isLoading,\n sort,\n searchQuery,\n setSort,\n setSearchQuery,\n }\n}\n","// Handy little state machine to simplify managing which root level dialog to open\n\nimport {useState} from 'react'\n\nexport type DialogState = 'secrets' | 'select-video' | 'edit-thumbnail' | 'edit-captions' | false\n\nexport function useDialogState() {\n return useState<DialogState>(false)\n}\n\nexport type SetDialogState = ReturnType<typeof useDialogState>[1]\n","import {defer} from 'rxjs'\nimport type {SanityClient} from 'sanity'\n\ninterface SecretsDocument {\n _id: 'secrets.mux'\n _type: 'mux.apiKey'\n token: string\n secretKey: string\n enableSignedUrls: boolean\n signingKeyId: string\n signingKeyPrivate: string\n drmConfigId: string\n}\n// eslint-disable-next-line max-params\nexport function saveSecrets(\n client: SanityClient,\n token: string,\n secretKey: string,\n enableSignedUrls: boolean,\n signingKeyId: string,\n signingKeyPrivate: string,\n drmConfigId: string\n): Promise<SecretsDocument> {\n const doc: SecretsDocument = {\n _id: 'secrets.mux',\n _type: 'mux.apiKey',\n token,\n secretKey,\n enableSignedUrls,\n signingKeyId,\n signingKeyPrivate,\n drmConfigId,\n }\n doc.signingKeyId = enableSignedUrls ? signingKeyId : ''\n doc.signingKeyPrivate = enableSignedUrls ? signingKeyPrivate : ''\n\n return client.createOrReplace(doc)\n}\n\nexport async function createSigningKeys(client: SanityClient) {\n try {\n const {dataset} = client.config()\n const res = await client.request<{\n data: {private_key: string; id: string; created_at: string}\n }>({\n url: `/addons/mux/signing-keys/${dataset}`,\n withCredentials: true,\n method: 'POST',\n })\n return res\n } catch (error: any) {\n console.error('Error creating signing keys', error)\n const message =\n error.response?.statusCode === 401\n ? 'Unauthorized - Failed to create the Signing Key. Please ensure that the token has \"System\" permissions'\n : error.message\n throw new Error(message)\n }\n}\n\nexport function testSecrets(client: SanityClient) {\n const {dataset} = client.config()\n return client.request<{status: boolean}>({\n url: `/addons/mux/secrets/${dataset}/test`,\n withCredentials: true,\n method: 'GET',\n })\n}\n\nexport async function haveValidSigningKeys(\n client: SanityClient,\n signingKeyId: string,\n signingKeyPrivate: string\n) {\n if (!(signingKeyId && signingKeyPrivate)) {\n return false\n }\n\n const {dataset} = client.config()\n try {\n const res = await client.request<{data: {id: string; created_at: string}}>({\n url: `/addons/mux/signing-keys/${dataset}/${signingKeyId}`,\n withCredentials: true,\n method: 'GET',\n })\n //\n // if this signing key is valid it will return { data: { id: 'xxxx' } }\n //\n return !!(res.data && res.data.id)\n } catch (e) {\n console.error('Error fetching signingKeyId', signingKeyId, 'assuming it is not valid')\n return false\n }\n}\n\nexport function testSecretsObservable(client: SanityClient) {\n const {dataset} = client.config()\n return defer(() =>\n client.observable.request<{status: boolean}>({\n url: `/addons/mux/secrets/${dataset}/test`,\n withCredentials: true,\n method: 'GET',\n })\n )\n}\n","import {useCallback} from 'react'\nimport type {SanityClient} from 'sanity'\n\nimport {createSigningKeys, haveValidSigningKeys, saveSecrets, testSecrets} from '../actions/secrets'\nimport type {Secrets} from '../util/types'\n\nexport const useSaveSecrets = (client: SanityClient, secrets: Secrets) => {\n return useCallback(\n async ({\n token,\n secretKey,\n enableSignedUrls,\n drmConfigId,\n }: Pick<\n Secrets,\n 'token' | 'secretKey' | 'enableSignedUrls' | 'drmConfigId'\n >): Promise<Secrets> => {\n let {signingKeyId, signingKeyPrivate} = secrets\n\n try {\n await saveSecrets(\n client,\n token!,\n secretKey!,\n enableSignedUrls,\n signingKeyId!,\n signingKeyPrivate!,\n drmConfigId!\n )\n const valid = await testSecrets(client)\n if (!valid?.status && token && secretKey) {\n throw new Error('Invalid secrets')\n }\n } catch (err) {\n console.error('Error while trying to save secrets:', err)\n throw err\n }\n\n if (enableSignedUrls) {\n const hasValidSigningKeys = await haveValidSigningKeys(\n client,\n signingKeyId!,\n signingKeyPrivate!\n )\n\n if (!hasValidSigningKeys) {\n try {\n const {data} = await createSigningKeys(client)\n signingKeyId = data.id\n signingKeyPrivate = data.private_key\n await saveSecrets(\n client,\n token!,\n secretKey!,\n enableSignedUrls,\n signingKeyId,\n signingKeyPrivate,\n drmConfigId ?? ''\n )\n } catch (err: any) {\n // eslint-disable-next-line no-console\n console.log('Error while creating and saving signing key:', err?.message)\n throw err\n }\n }\n }\n return {\n token,\n secretKey,\n enableSignedUrls,\n signingKeyId,\n signingKeyPrivate,\n drmConfigId,\n }\n },\n [client, secrets]\n )\n}\n","export const name = 'mux-input' as const\n\n// Caching namespace, as suspend-react might be in use by other components on the page we must ensure we don't collide\nexport const cacheNs = 'sanity-plugin-mux-input' as const\n\nexport const muxSecretsDocumentId = 'secrets.mux' as const\n\nexport const DIALOGS_Z_INDEX = 60_000\n\nexport const THUMBNAIL_ASPECT_RATIO = 16 / 9\n\n/** To prevent excessive height, thumbnails and input should not go beyond to this aspect ratio. */\nexport const MIN_ASPECT_RATIO = 5 / 4\n\nexport const AUDIO_ASPECT_RATIO = 5 / 1\n","import {useMemo} from 'react'\nimport {useDocumentValues} from 'sanity'\n\nimport {muxSecretsDocumentId} from '../util/constants'\nimport type {Secrets} from '../util/types'\n\nconst path = [\n 'token',\n 'secretKey',\n 'enableSignedUrls',\n 'signingKeyId',\n 'signingKeyPrivate',\n 'drmConfigId',\n]\nexport const useSecretsDocumentValues = () => {\n const {error, isLoading, value} = useDocumentValues<Partial<Secrets> | null | undefined>(\n muxSecretsDocumentId,\n path\n )\n const cache = useMemo(() => {\n const exists = Boolean(value)\n const secrets: Secrets = {\n token: value?.token || null,\n secretKey: value?.secretKey || null,\n enableSignedUrls: value?.enableSignedUrls || false,\n signingKeyId: value?.signingKeyId || null,\n signingKeyPrivate: value?.signingKeyPrivate || null,\n drmConfigId: value?.drmConfigId || null,\n }\n return {\n isInitialSetup: !exists,\n needsSetup: !secrets?.token || !secrets?.secretKey,\n secrets,\n }\n }, [value])\n\n return {error, isLoading, value: cache}\n}\n","import {useReducer} from 'react'\n\nimport type {Secrets} from '../util/types'\n\nexport interface State\n extends Pick<Secrets, 'token' | 'secretKey' | 'enableSignedUrls' | 'drmConfigId'> {\n submitting: boolean\n error: string | null\n}\nexport type Action =\n | {type: 'submit'}\n | {type: 'error'; payload: string}\n | {type: 'reset'; payload: Secrets}\n | {type: 'change'; payload: {name: 'token'; value: string}}\n | {type: 'change'; payload: {name: 'secretKey'; value: string}}\n | {type: 'change'; payload: {name: 'enableSignedUrls'; value: boolean}}\n | {type: 'change'; payload: {name: 'drmConfigId'; value: string}}\nfunction init({token, secretKey, enableSignedUrls, drmConfigId}: Secrets): State {\n return {\n submitting: false,\n error: null,\n // Form inputs don't set the state back to null when clearing a field, but uses empty strings\n // This ensures the `dirty` check works correctly\n token: token ?? '',\n secretKey: secretKey ?? '',\n enableSignedUrls: enableSignedUrls ?? false,\n drmConfigId: drmConfigId ?? '',\n }\n}\nfunction reducer(state: State, action: Action) {\n switch (action?.type) {\n case 'submit':\n return {...state, submitting: true, error: null}\n case 'error':\n return {...state, submitting: false, error: action.payload}\n case 'reset':\n return init(action.payload)\n case 'change':\n return {...state, [action.payload.name]: action.payload.value}\n default:\n throw new Error(`Unknown action type: ${(action as unknown as Action)?.type}`)\n }\n}\n\nexport const useSecretsFormState = (secrets: Secrets) => useReducer(reducer, secrets, init)\n","// Utils with a readName prefix are suspendable and should only be called in the render body\n// Not inside event callbacks or a useEffect.\n// They may be called dynamically, unlike useEffect\n\n// @TODO rename to readSigningPair\n\nimport type {SanityClient} from 'sanity'\nimport {suspend} from 'suspend-react'\n\nimport {cacheNs} from '../util/constants'\nimport {type Secrets} from '../util/types'\n\nexport const _id = 'secrets.mux' as const\n\nexport function readSecrets(client: SanityClient): Secrets {\n const {projectId, dataset} = client.config()\n return suspend(async () => {\n const data = await client.fetch(\n /* groq */ `*[_id == $_id][0]{\n token,\n secretKey,\n enableSignedUrls,\n signingKeyId,\n signingKeyPrivate,\n drmConfigId\n }`,\n {_id}\n )\n return {\n token: data?.token || null,\n secretKey: data?.secretKey || null,\n enableSignedUrls: Boolean(data?.enableSignedUrls) || false,\n signingKeyId: data?.signingKeyId || null,\n signingKeyPrivate: data?.signingKeyPrivate || null,\n drmConfigId: data?.drmConfigId || null,\n }\n }, [cacheNs, _id, projectId, dataset])\n}\n","import {useTheme_v2} from '@sanity/ui'\nimport {CSSProperties, useId, useMemo} from 'react'\n\nexport interface Props {\n height?: number\n}\nexport default function MuxLogo({height = 26}: Props) {\n const id = useId()\n const theme = useTheme_v2()\n const fillColor = theme.color._dark ? 'white' : 'black'\n const titleId = useMemo(() => `${id}-title`, [id])\n\n const pathStyle: CSSProperties = {\n fillRule: 'nonzero',\n }\n\n return (\n <svg\n aria-labelledby={titleId}\n style={{height: `${height}px`}}\n viewBox=\"0 0 1600 500\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlSpace=\"preserve\"\n >\n <g id=\"Layer-1\" fill={fillColor}>\n <path\n d=\"M994.287,93.486c-17.121,-0 -31,-13.879 -31,-31c0,-17.121 13.879,-31 31,-31c17.121,-0 31,13.879 31,31c0,17.121 -13.879,31 -31,31m0,-93.486c-34.509,-0 -62.484,27.976 -62.484,62.486l0,187.511c0,68.943 -56.09,125.033 -125.032,125.033c-68.942,-0 -125.03,-56.09 -125.03,-125.033l0,-187.511c0,-34.51 -27.976,-62.486 -62.485,-62.486c-34.509,-0 -62.484,27.976 -62.484,62.486l0,187.511c0,137.853 112.149,250.003 249.999,250.003c137.851,-0 250.001,-112.15 250.001,-250.003l0,-187.511c0,-34.51 -27.976,-62.486 -62.485,-62.486\"\n style={pathStyle}\n />\n <path\n d=\"M1537.51,468.511c-17.121,-0 -31,-13.879 -31,-31c0,-17.121 13.879,-31 31,-31c17.121,-0 31,13.879 31,31c0,17.121 -13.879,31 -31,31m-275.883,-218.509l-143.33,143.329c-24.402,24.402 -24.402,63.966 0,88.368c24.402,24.402 63.967,24.402 88.369,-0l143.33,-143.329l143.328,143.329c24.402,24.4 63.967,24.402 88.369,-0c24.403,-24.402 24.403,-63.966 0.001,-88.368l-143.33,-143.329l0.001,-0.004l143.329,-143.329c24.402,-24.402 24.402,-63.965 0,-88.367c-24.402,-24.402 -63.967,-24.402 -88.369,-0l-143.329,143.328l-143.329,-143.328c-24.402,-24.401 -63.967,-24.402 -88.369,-0c-24.402,24.402 -24.402,63.965 0,88.367l143.329,143.329l0,0.004Z\"\n style={pathStyle}\n />\n <path\n d=\"M437.511,468.521c-17.121,-0 -31,-13.879 -31,-31c0,-17.121 13.879,-31 31,-31c17.121,-0 31,13.879 31,31c0,17.121 -13.879,31 -31,31m23.915,-463.762c-23.348,-9.672 -50.226,-4.327 -68.096,13.544l-143.331,143.329l-143.33,-143.329c-17.871,-17.871 -44.747,-23.216 -68.096,-13.544c-23.349,9.671 -38.574,32.455 -38.574,57.729l0,375.026c0,34.51 27.977,62.486 62.487,62.486c34.51,-0 62.486,-27.976 62.486,-62.486l0,-224.173l80.843,80.844c24.404,24.402 63.965,24.402 88.369,-0l80.843,-80.844l0,224.173c0,34.51 27.976,62.486 62.486,62.486c34.51,-0 62.486,-27.976 62.486,-62.486l0,-375.026c0,-25.274 -15.224,-48.058 -38.573,-57.729\"\n style={pathStyle}\n />\n </g>\n </svg>\n )\n}\n","import {styled} from 'styled-components'\n\nimport MuxLogo from './MuxLogo'\n\nconst Logo = styled.span`\n display: inline-block;\n height: 0.8em;\n margin-right: 1em;\n transform: translate(0.3em, -0.2em);\n`\n\nexport const Header = () => (\n <>\n <Logo>\n <MuxLogo height={13} />\n </Logo>\n API Credentials\n </>\n)\n","import {Box, Flex, Stack, Text} from '@sanity/ui'\nimport React, {memo} from 'react'\n\n// @TODO: get rid of this once v3 core is stable\n\nexport interface Props {\n children: React.ReactNode\n title: React.ReactNode\n description?: React.ReactNode\n inputId: string\n}\n\nfunction FormField(props: Props) {\n const {children, title, description, inputId} = props\n\n return (\n <Stack space={1}>\n <Flex align=\"flex-end\">\n <Box flex={1} paddingY={2}>\n <Stack space={2}>\n <Text as=\"label\" htmlFor={inputId} weight=\"semibold\" size={1}>\n {title || <em>Untitled</em>}\n </Text>\n\n {description && (\n <Text muted size={1}>\n {description}\n </Text>\n )}\n </Stack>\n </Box>\n </Flex>\n <div>{children}</div>\n </Stack>\n )\n}\n\nexport default memo(FormField)\n","import {\n Box,\n Button,\n Card,\n Checkbox,\n Code,\n Dialog,\n Flex,\n Inline,\n Stack,\n Text,\n TextInput,\n} from '@sanity/ui'\nimport {useCallback, useEffect, useId, useMemo, useRef} from 'react'\nimport {clear, preload} from 'suspend-react'\n\nimport {useClient} from '../hooks/useClient'\nimport type {SetDialogState} from '../hooks/useDialogState'\nimport {useDialogState} from '../hooks/useDialogState'\nimport {useSaveSecrets} from '../hooks/useSaveSecrets'\nimport {useSecretsDocumentValues} from '../hooks/useSecretsDocumentValues'\nimport {useSecretsFormState} from '../hooks/useSecretsFormState'\nimport {cacheNs, DIALOGS_Z_INDEX} from '../util/constants'\nimport {_id as secretsId} from '../util/readSecrets'\nimport type {Secrets} from '../util/types'\nimport {Header} from './ConfigureApi.styled'\nimport FormField from './FormField'\n\n// Props for the dialog component when used with external state management\nexport interface ConfigureApiDialogProps {\n setDialogState: SetDialogState\n secrets: Secrets\n}\n\nconst fieldNames = ['token', 'secretKey', 'enableSignedUrls', 'drmConfigId'] as const\n\n// Internal dialog component that can be used with external state\nexport function ConfigureApiDialog({secrets, setDialogState}: ConfigureApiDialogProps) {\n const client = useClient()\n const [state, dispatch] = useSecretsFormState(secrets)\n const hasSecretsInitially = useMemo(() => secrets.token && secrets.secretKey, [secrets])\n const handleClose = useCallback(() => setDialogState(false), [setDialogState])\n const dirty = useMemo(\n () =>\n secrets.token !== state.token ||\n secrets.secretKey !== state.secretKey ||\n secrets.enableSignedUrls !== state.enableSignedUrls ||\n secrets.drmConfigId !== state.drmConfigId,\n [secrets, state]\n )\n const id = `ConfigureApi${useId()}`\n const [tokenId, secretKeyId, enableSignedUrlsId, drmConfigIdId] = useMemo<typeof fieldNames>(\n () => fieldNames.map((field) => `${id}-${field}`) as unknown as typeof fieldNames,\n [id]\n )\n const firstField = useRef<HTMLInputElement>(null)\n const handleSaveSecrets = useSaveSecrets(client, secrets)\n const saving = useRef(false)\n\n const handleSubmit = useCallback(\n (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n\n if (!saving.current && event.currentTarget.reportValidity()) {\n saving.current = true\n dispatch({type: 'submit'})\n const {token, secretKey, enableSignedUrls, drmConfigId} = state\n handleSaveSecrets({token, secretKey, enableSignedUrls, drmConfigId})\n .then((savedSecrets) => {\n const {projectId, dataset} = client.config()\n clear([cacheNs, secretsId, projectId, dataset])\n preload(() => Promise.resolve(savedSecrets), [cacheNs, secretsId, projectId, dataset])\n setDialogState(false)\n })\n .catch((err) => dispatch({type: 'error', payload: err.message}))\n .finally(() => {\n saving.current = false\n })\n }\n },\n [client, dispatch, handleSaveSecrets, setDialogState, state]\n )\n const handleChangeToken = useCallback(\n (event: React.FormEvent<HTMLInputElement>) => {\n dispatch({\n type: 'change',\n payload: {name: 'token', value: event.currentTarget.value},\n })\n },\n [dispatch]\n )\n const handleChangeSecretKey = useCallback(\n (event: React.FormEvent<HTMLInputElement>) => {\n dispatch({\n type: 'change',\n payload: {name: 'secretKey', value: event.currentTarget.value},\n })\n },\n [dispatch]\n )\n const handleChangeEnableSignedUrls = useCallback(\n (event: React.FormEvent<HTMLInputElement>) => {\n dispatch({\n type: 'change',\n payload: {name: 'enableSignedUrls', value: event.currentTarget.checked},\n })\n },\n [dispatch]\n )\n const handleChangeDrmConfigId = useCallback(\n (event: React.FormEvent<HTMLInputElement>) => {\n dispatch({\n type: 'change',\n payload: {name: 'drmConfigId', value: event.currentTarget.value},\n })\n },\n [dispatch]\n )\n\n useEffect(() => {\n if (firstField.current) {\n firstField.current.focus()\n }\n }, [firstField])\n\n return (\n <Dialog\n animate\n id={id}\n onClose={handleClose}\n onClickOutside={handleClose}\n header={<Header />}\n zOffset={DIALOGS_Z_INDEX}\n position=\"fixed\"\n width={1}\n >\n <Box padding={3}>\n <form onSubmit={handleSubmit} noValidate>\n <Stack space={4}>\n {!hasSecretsInitially && (\n <Card padding={[3, 3, 3]} radius={2} shadow={1} tone=\"primary\">\n <Stack space={3}>\n <Text size={1}>\n To set up a new access token, go to your{' '}\n <a\n href=\"https://dashboard.mux.com/settings/access-tokens\"\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n >\n account on mux.com\n </a>\n .\n </Text>\n <Text size={1}>\n The access token needs permissions: <strong>Mux Video </strong>\n (Full Access) and <strong>Mux Data</strong> (Read)\n <br />\n To use Signed URLs, the token must also have System permissions.\n <br />\n The credentials will be stored safely in a hidden document only available to\n editors.\n </Text>\n </Stack>\n </Card>\n )}\n <FormField title=\"Access Token\" inputId={tokenId}>\n <TextInput\n id={tokenId}\n ref={firstField}\n onChange={handleChangeToken}\n type=\"text\"\n value={state.token ?? ''}\n required={!!state.secretKey || state.enableSignedUrls}\n />\n </FormField>\n <FormField title=\"Secret Key\" inputId={secretKeyId}>\n <TextInput\n id={secretKeyId}\n onChange={handleChangeSecretKey}\n type=\"text\"\n value={state.secretKey ?? ''}\n required={!!state.token || state.enableSignedUrls}\n />\n </FormField>\n\n <Stack space={4}>\n <Flex align=\"center\">\n <Checkbox\n id={enableSignedUrlsId}\n onChange={handleChangeEnableSignedUrls}\n checked={state.enableSignedUrls}\n style={{display: 'block'}}\n />\n <Box flex={1} paddingLeft={3}>\n <Text>\n <label htmlFor={enableSignedUrlsId}>Enable Signed Urls</label>\n </Text>\n </Box>\n </Flex>\n {secrets.signingKeyId && state.enableSignedUrls ? (\n <Card padding={[3, 3, 3]} radius={2} shadow={1} tone=\"caution\">\n <Stack space={3}>\n <Text size={1}>The signing key ID that Sanity will use is:</Text>\n <Code size={1}>{secrets.signingKeyId}</Code>\n <Text size={1}>\n This key is only used for previewing content in the Sanity UI.\n <br />\n You should generate a different key to use in your application server.\n </Text>\n </Stack>\n </Card>\n ) : null}\n </Stack>\n\n <FormField title=\"DRM Configuration ID\" inputId={drmConfigIdId}>\n <TextInput\n id={drmConfigIdId}\n onChange={handleChangeDrmConfigId}\n type=\"text\"\n value={state.drmConfigId ?? ''}\n required={false}\n />\n </FormField>\n <Card padding={[3, 3, 3]} radius={2} shadow={1} tone=\"neutral\">\n <Stack space={3}>\n <Text size={1}>\n DRM (Digital Rights Management) provides an extra layer of content security for\n video content streamed from Mux. For additional information check out our{' '}\n <a\n href=\"https://www.mux.com/docs/guides/protect-videos-with-drm#play-drm-protected-videos\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n DRM Guide\n </a>\n .\n </Text>\n <Text size={1}>\n <a\n href=\"https://www.mux.com/support/human\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Contact us\n </a>{' '}\n to get started using DRM.\n </Text>\n </Stack>\n </Card>\n\n <Inline space={2}>\n <Button\n text=\"Save\"\n disabled={!dirty}\n loading={state.submitting}\n tone=\"primary\"\n mode=\"default\"\n type=\"submit\"\n />\n <Button\n disabled={state.submitting}\n text=\"Cancel\"\n mode=\"bleed\"\n onClick={handleClose}\n />\n </Inline>\n {state.error && (\n <Card padding={[3, 3, 3]} radius={2} shadow={1} tone=\"critical\">\n <Text>{state.error}</Text>\n </Card>\n )}\n </Stack>\n </form>\n </Box>\n </Dialog>\n )\n}\n\n// Wrapper component that manages its own dialog state (used in VideosBrowser)\nexport default function ConfigureApi() {\n const [dialogOpen, setDialogOpen] = useDialogState()\n const secretDocumentValues = useSecretsDocumentValues()\n\n const openDialog = useCallback(() => setDialogOpen('secrets'), [setDialogOpen])\n\n if (dialogOpen === 'secrets') {\n return (\n <ConfigureApiDialog\n secrets={secretDocumentValues.value.secrets}\n setDialogState={setDialogOpen}\n />\n )\n }\n\n return <Button mode=\"bleed\" text=\"Configure plugin\" onClick={openDialog} />\n}\n","import {truncateString} from 'sanity'\n\n/**\n * Generates a placeholder title for a Mux asset when no title is available.\n * This format is used when importing assets that don't have a title in Mux.\n *\n * @param assetId - The Mux asset ID\n * @returns A placeholder title in the format \"Asset #[truncated-id]\"\n */\nexport function generateAssetPlaceholder(assetId: string): string {\n return `Asset #${truncateString(assetId, 15)}`\n}\n\n/**\n * Checks if a filename is empty or has the placeholder format.\n * This is used to determine if a video title should be updated during metadata sync.\n *\n * @param filename - The current filename/title of the video\n * @param assetId - The Mux asset ID to check against\n * @returns true if the filename is empty or matches the placeholder format\n */\nexport function isEmptyOrPlaceholderTitle(filename: string | undefined, assetId: string): boolean {\n // Check if filename is empty/undefined\n if (!filename || filename.trim() === '') {\n return true\n }\n\n // Check if filename matches the placeholder format for this asset\n const placeholder = generateAssetPlaceholder(assetId)\n return filename === placeholder\n}\n","import type {MuxAsset} from './types'\n\nexport function parseMuxDate(date: MuxAsset['created_at']): Date {\n return new Date(Number(date) * 1000)\n}\n","import type {SanityClient} from 'sanity'\n\nimport type {MuxAsset, VideoAssetDocument} from '../util/types'\n\nexport function deleteAssetOnMux(client: SanityClient, assetId: string) {\n const {dataset} = client.config()\n return client.request<void>({\n url: `/addons/mux/assets/${dataset}/${assetId}`,\n withCredentials: true,\n method: 'DELETE',\n })\n}\n\nexport async function deleteAsset({\n client,\n asset,\n deleteOnMux,\n}: {\n client: SanityClient\n asset: VideoAssetDocument\n deleteOnMux: boolean\n}) {\n if (!asset?._id) return true\n\n try {\n await client.delete(asset._id)\n } catch (error) {\n return 'failed-sanity'\n }\n\n if (deleteOnMux && asset?.assetId) {\n try {\n await deleteAssetOnMux(client, asset.assetId)\n } catch (error) {\n return 'failed-mux'\n }\n }\n\n return true\n}\n\nexport function getAsset(client: SanityClient, assetId: string) {\n const {dataset} = client.config()\n return client.request<{data: MuxAsset}>({\n url: `/addons/mux/assets/${dataset}/data/${assetId}`,\n withCredentials: true,\n method: 'GET',\n })\n}\n\nexport function listAssets(\n client: SanityClient,\n options: {limit?: number; cursor?: string | null}\n) {\n const {dataset} = client.config()\n const query: {limit?: string; cursor?: string} = {}\n\n if (options.limit) {\n query.limit = options.limit.toString()\n }\n if (options.cursor) {\n query.cursor = options.cursor\n }\n\n return client.request<{data: MuxAsset[]; next_cursor?: string | null}>({\n url: `/addons/mux/assets/${dataset}/data/list`,\n withCredentials: true,\n method: 'GET',\n query,\n })\n}\n\n/**\n * Adds a new text track to an existing asset using a VTT file URL\n */\nexport function addTextTrackFromUrl(\n client: SanityClient,\n assetId: string,\n vttUrl: string,\n options: {\n language_code: string\n name: string\n text_type?: 'subtitles'\n }\n) {\n const {dataset} = client.config()\n\n return client.request<{data: MuxAsset}>({\n url: `/addons/mux/assets/${dataset}/${assetId}/tracks`,\n withCredentials: true,\n method: 'POST',\n body: {\n url: vttUrl,\n type: 'text',\n language_code: options.language_code,\n name: options.name,\n text_type: options.text_type || 'subtitles',\n },\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n}\n\n/**\n * Generates subtitles automatically for an audio track\n */\nexport function generateSubtitles(\n client: SanityClient,\n assetId: string,\n audioTrackId: string,\n options: {\n language_code: string\n name: string\n }\n) {\n const {dataset} = client.config()\n return client.request<{data: MuxAsset}>({\n url: `/addons/mux/assets/${dataset}/${assetId}/tracks/${audioTrackId}/generate-subtitles`,\n withCredentials: true,\n method: 'POST',\n body: {\n generated_subtitles: [\n {\n language_code: options.language_code,\n name: options.name,\n },\n ],\n },\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n}\n\n/**\n * Deletes a text track from an asset\n */\nexport function deleteTextTrack(client: SanityClient, assetId: string, trackId: string) {\n const {dataset} = client.config()\n return client.request<{data: MuxAsset}>({\n url: `/addons/mux/assets/${dataset}/${assetId}/tracks/${trackId}`,\n withCredentials: true,\n method: 'DELETE',\n })\n}\n","import {useEffect, useState} from 'react'\nimport {defer, of, timer} from 'rxjs'\nimport {concatMap, expand, tap} from 'rxjs/operators'\nimport type {SanityClient} from 'sanity'\n\nimport {listAssets} from '../actions/assets'\nimport type {MuxAsset} from '../util/types'\n\nconst ASSETS_PER_PAGE = 100\n\ntype MuxAssetsState = {\n cursor: string | null\n loading: boolean\n data?: MuxAsset[]\n error?: FetchError\n hasSkippedAssetsWithoutPlayback?: boolean\n}\n\ntype FetchError =\n | {\n _tag: 'FetchError'\n }\n | {_tag: 'MuxError'; error: unknown}\n\ntype PageResult = (\n | {\n data: MuxAsset[]\n next_cursor: string | null\n }\n | {\n error: FetchError\n }\n) & {\n cursor: string | null\n}\n\n/**\n * @docs {@link https://docs.mux.com/api-reference#video/operation/list-assets}\n */\nasync function fetchMuxAssetsPage(\n client: SanityClient,\n cursor: string | null\n): Promise<PageResult> {\n try {\n const response = await listAssets(client, {\n limit: ASSETS_PER_PAGE,\n cursor,\n })\n\n return {\n cursor,\n data: response.data as MuxAsset[],\n next_cursor: response.next_cursor || null,\n }\n } catch (error) {\n return {\n cursor,\n error: {_tag: 'FetchError'},\n }\n }\n}\n\nfunction accumulateIntermediateState(\n currentState: MuxAssetsState,\n pageResult: PageResult\n): MuxAssetsState {\n const currentData = ('data' in currentState && currentState.data) || []\n const newAssets = ('data' in pageResult && pageResult.data) || []\n\n // Filter assets and check for skipped items\n const {validAssets, skippedInThisPage} = newAssets.reduce<{\n validAssets: MuxAsset[]\n skippedInThisPage: boolean\n }>(\n (acc, asset) => {\n const hasPlaybackIds = asset.playback_ids && asset.playback_ids.length > 0\n const isDuplicate = currentData.some((a) => a.id === asset.id)\n\n if (!hasPlaybackIds) {\n acc.skippedInThisPage = true\n }\n\n if (hasPlaybackIds && !isDuplicate) {\n acc.validAssets.push(asset)\n }\n\n return acc\n },\n {validAssets: [], skippedInThisPage: false}\n )\n\n return {\n ...currentState,\n data: [...currentData, ...validAssets],\n error:\n 'error' in pageResult\n ? pageResult.error\n : // Reset error if current page is successful\n undefined,\n cursor: 'next_cursor' in pageResult ? pageResult.next_cursor : pageResult.cursor,\n loading: true,\n hasSkippedAssetsWithoutPlayback:\n currentState.hasSkippedAssetsWithoutPlayback || skippedInThisPage,\n }\n}\n\nfunction hasMorePages(pageResult: PageResult) {\n return (\n typeof pageResult === 'object' && 'next_cursor' in pageResult && pageResult.next_cursor !== null\n )\n}\n\n/**\n * Fetches all assets from a Mux environment. Rules:\n * - One page at a time\n * - Uses cursor-based pagination\n * - We've finished fetching when `next_cursor` is null\n * - Rate limiting to one request per 2 seconds\n * - Update state while still fetching to give feedback to users\n */\nexport default function useMuxAssets({client, enabled}: {client: SanityClient; enabled: boolean}) {\n const [state, setState] = useState<MuxAssetsState>({loading: true, cursor: null})\n\n useEffect(() => {\n if (!enabled) return\n\n const subscription = defer(() =>\n fetchMuxAssetsPage(\n client,\n // When we've already successfully loaded before (fully or partially), we start from the next cursor to avoid re-fetching\n 'data' in state && state.data && state.data.length > 0 && !state.error ? state.cursor : null\n )\n )\n .pipe(\n // Here we use \"expand\" to recursively fetch next pages\n expand((pageResult) => {\n // if fetched page has next_cursor, we continue emitting, requesting the next page\n // after 2s to avoid rate limiting\n if (hasMorePages(pageResult)) {\n return timer(2000).pipe(\n concatMap(() =>\n // eslint-disable-next-line max-nested-callbacks\n defer(() =>\n fetchMuxAssetsPage(\n client,\n 'next_cursor' in pageResult ? pageResult.next_cursor : null\n )\n )\n )\n )\n }\n\n // Else, we stop emitting\n return of()\n }),\n\n // On each iteration, persist intermediate states to give feedback to users\n tap((pageResult) =>\n setState((prevState) => accumulateIntermediateState(prevState, pageResult))\n )\n )\n .subscribe({\n // Once done, let the user know we've stopped loading\n complete: () => {\n setState((prev) => ({\n ...prev,\n loading: false,\n }))\n },\n })\n\n // Unsubscribe on component unmount to prevent memory leaks or fetching unnecessarily\n // eslint-disable-next-line consistent-return\n return () => subscription.unsubscribe()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled])\n\n return state\n}\n","import {uuid} from '@sanity/uuid'\nimport {useMemo, useState} from 'react'\nimport {\n createHookFromObservableFactory,\n type DocumentStore,\n useClient,\n useDocumentStore,\n} from 'sanity'\n\nimport {generateAssetPlaceholder} from '../util/assetTitlePlaceholder'\nimport {parseMuxDate} from '../util/parsers'\nimport type {MuxAsset, VideoAssetDocument} from '../util/types'\nimport {SANITY_API_VERSION} from './useClient'\nimport useMuxAssets from './useMuxAssets'\nimport {useSecretsDocumentValues} from './useSecretsDocumentValues'\n\ntype ImportState = 'closed' | 'idle' | 'importing' | 'done' | 'error'\n\nexport type AssetInSanity = {\n uploadId: string\n assetId: string\n}\n\nexport default function useImportMuxAssets() {\n const documentStore = useDocumentStore()\n const client = useClient({\n apiVersion: SANITY_API_VERSION,\n })\n\n const [assetsInSanity, assetsInSanityLoading] = useAssetsInSanity(documentStore)\n\n const secretDocumentValues = useSecretsDocumentValues()\n const hasSecrets = !!secretDocumentValues.value.secrets?.secretKey\n\n const [importError, setImportError] = useState<unknown>()\n const [importState, setImportState] = useState<ImportState>('closed')\n const dialogOpen = importState !== 'closed'\n\n const muxAssets = useMuxAssets({\n client,\n enabled: hasSecrets && dialogOpen,\n })\n\n const missingAssets = useMemo(() => {\n return assetsInSanity && muxAssets.data\n ? muxAssets.data.filter((a) => !assetExistsInSanity(a, assetsInSanity))\n : undefined\n }, [assetsInSanity, muxAssets.data])\n\n const [selectedAssets, setSelectedAssets] = useState<MuxAsset[]>([])\n\n const closeDialog = () => {\n if (importState !== 'importing') setImportState('closed')\n }\n const openDialog = () => {\n if (importState === 'closed') setImportState('idle')\n }\n\n async function importAssets() {\n setImportState('importing')\n const documents = selectedAssets.flatMap((asset) => muxAssetToSanityDocument(asset) || [])\n\n const tx = client.transaction()\n documents.forEach((doc) => tx.create(doc))\n\n try {\n await tx.commit({returnDocuments: false})\n setSelectedAssets([])\n setImportState('done')\n } catch (error) {\n setImportState('error')\n setImportError(error)\n }\n }\n\n return {\n assetsInSanityLoading,\n closeDialog,\n dialogOpen,\n importState,\n importError,\n hasSecrets,\n importAssets,\n missingAssets,\n muxAssets,\n openDialog,\n selectedAssets,\n setSelectedAssets,\n }\n}\n\nfunction muxAssetToSanityDocument(asset: MuxAsset): VideoAssetDocument | undefined {\n const playbackId = (asset.playback_ids || []).find((p) => p.id)?.id\n\n if (!playbackId) return undefined\n\n return {\n _id: uuid(),\n _type: 'mux.videoAsset',\n _updatedAt: new Date().toISOString(),\n _createdAt: parseMuxDate(asset.created_at).toISOString(),\n assetId: asset.id,\n playbackId,\n filename: asset.meta?.title ?? generateAssetPlaceholder(asset.id),\n status: asset.status,\n data: asset,\n }\n}\n\nconst useAssetsInSanity = createHookFromObservableFactory<AssetInSanity[], DocumentStore>(\n (documentStore) => {\n return documentStore.listenQuery(\n /* groq */ `*[_type == \"mux.videoAsset\"] {\n \"uploadId\": coalesce(uploadId, data.upload_id),\n \"assetId\": coalesce(assetId, data.id),\n }`,\n {},\n {\n apiVersion: SANITY_API_VERSION,\n }\n )\n }\n)\n\nfunction assetExistsInSanity(asset: MuxAsset, existingAssets: AssetInSanity[]) {\n // Don't allow importing assets that are not ready\n if (asset.status !== 'ready') return false\n\n return existingAssets.some(\n (existing) => existing.assetId === asset.id || existing.uploadId === asset.upload_id\n )\n}\n","import {useEffect, useState} from 'react'\n\ntype IntersectionOptions = {\n root?: Element | null\n rootMargin?: string\n threshold?: number\n onChange?: (inView: boolean) => void\n}\n\nexport function useInView(\n ref: React.RefObject<HTMLDivElement | null>,\n options: IntersectionOptions = {}\n) {\n const [inView, setInView] = useState(false)\n\n useEffect(() => {\n if (!ref.current) return\n\n const observer = new IntersectionObserver(([entry], obs) => {\n // ==== from react-intersection-observer ====\n // While it would be nice if you could just look at isIntersecting to determine if the component is inside the viewport, browsers can't agree on how to use it.\n // -Firefox ignores `threshold` when considering `isIntersecting`, so it will never be false again if `threshold` is > 0\n const nowInView =\n entry.isIntersecting &&\n obs.thresholds.some((threshold) => entry.intersectionRatio >= threshold)\n\n // Update our state when observer callback fires\n setInView(nowInView)\n options?.onChange?.(nowInView)\n }, options)\n\n const toObserve = ref.current\n observer.observe(toObserve)\n\n // eslint-disable-next-line\n return () => {\n if (toObserve) observer.unobserve(toObserve)\n }\n }, [options, ref])\n\n return inView\n}\n","import type {\n AdvancedPlaybackPolicy,\n MuxPlaybackId,\n PlaybackPolicy,\n VideoAssetDocument,\n} from './types'\n\n/* - Returns the playback id of the asset based on the specified priority.\n By default chooses the \"strongest\" policy\n - Otherwise, returns the first playback id in the array.\n */\nexport function getPlaybackId(\n asset: Pick<VideoAssetDocument, 'data'>,\n priority: string[] = ['drm', 'signed', 'public']\n): string {\n try {\n if (!asset) {\n throw new TypeError('Tried to get playback Id with no asset')\n }\n\n const playbackIds = asset.data?.playback_ids\n if (playbackIds && playbackIds.length > 0) {\n for (const policy of priority) {\n const match = playbackIds.find((entry) => entry.policy === policy)\n if (match) {\n return match.id\n }\n }\n\n return playbackIds[0].id\n }\n\n throw new TypeError('Missing playbackId')\n } catch (e) {\n console.error('Asset is missing a playbackId', {asset}, e)\n throw e\n }\n}\n\nexport function getPlaybackPolicy(\n asset: Pick<VideoAssetDocument, 'data' | 'playbackId'>\n): MuxPlaybackId | undefined {\n return (\n asset.data?.playback_ids?.find(\n (playbackId) => getPlaybackId(asset, ['drm', 'signed', 'public']) === playbackId.id\n ) ?? {id: '', policy: 'public'}\n )\n}\n\nexport function getPlaybackPolicyById(\n asset: Pick<VideoAssetDocument, 'data'>,\n playbackId: string\n): MuxPlaybackId | undefined {\n return asset.data?.playback_ids?.find((entry) => playbackId === entry.id)\n}\n\nexport function hasPlaybackPolicy(\n data: Partial<{\n playback_policy?: PlaybackPolicy[]\n advanced_playback_policies: AdvancedPlaybackPolicy[]\n }>,\n policy: PlaybackPolicy\n) {\n return (\n (data.advanced_playback_policies &&\n data.advanced_playback_policies.find((p) => p.policy === policy)) ||\n data.playback_policy?.find((p) => p === policy)\n )\n}\n","import type {SanityClient} from 'sanity'\nimport {suspend} from 'suspend-react'\n\nimport {readSecrets} from './readSecrets'\nimport type {AnimatedThumbnailOptions, ThumbnailOptions} from './types'\n\nexport type Audience = 'g' | 's' | 't' | 'v' | 'd'\n\nexport type Payload<T extends Audience> = T extends 'g'\n ? AnimatedThumbnailOptions\n : T extends 's'\n ? never\n : T extends 't'\n ? ThumbnailOptions\n : T extends 'v'\n ? never\n : T extends 'd'\n ? never\n : never\n\n/**\n * Uses suspend. Call this with {@link tryWithSuspend} or rethrow the Promise\n */\nexport function generateJwt<T extends Audience>(\n client: SanityClient,\n playbackId: string,\n aud: T,\n payload?: Payload<T>\n): string {\n const {signingKeyId, signingKeyPrivate} = readSecrets(client)\n if (!signingKeyId) {\n throw new TypeError(\"Missing `signingKeyId`.\\n Check your plugin's configuration\")\n }\n if (!signingKeyPrivate) {\n throw new TypeError(\"Missing `signingKeyPrivate`.\\n Check your plugin's configuration\")\n }\n\n /* Using suspend means we need to use Suspense on parent components. \n Also, this will throw a Promise under the hood (apparently common in React), \n so if we want to catch errors we have to take this into account in catch blocks\n and rethrow promises. */\n // @ts-expect-error - handle missing typings for this package\n const {default: sign} = suspend(() => import('jsonwebtoken-esm/sign'), ['jsonwebtoken-esm/sign'])\n\n return sign(\n payload ? JSON.parse(JSON.stringify(payload, (_, v) => v ?? undefined)) : {},\n atob(signingKeyPrivate),\n {\n algorithm: 'RS256',\n keyid: signingKeyId,\n audience: aud,\n subject: playbackId,\n noTimestamp: true,\n expiresIn: '12h',\n }\n )\n}\n","import type {SanityClient} from 'sanity'\n\nimport {getPlaybackId} from '../util/getPlaybackPolicy'\nimport {Audience, generateJwt} from './generateJwt'\nimport {getPlaybackPolicyById} from './getPlaybackPolicy'\nimport type {AssetThumbnailOptions} from './types'\n\n/**\n * May throw a Promise. Call this with {@link tryWithSuspend} or rethrow the Promise\n */\nexport function createUrlParamsObject(\n client: SanityClient,\n asset: AssetThumbnailOptions['asset'],\n params: object,\n audience: Audience\n) {\n const playbackId = getPlaybackId(asset)\n\n let searchParams = new URLSearchParams(\n JSON.parse(JSON.stringify(params, (_, v) => v ?? undefined))\n )\n const playbackPolicy = getPlaybackPolicyById(asset, playbackId)?.policy\n if (playbackPolicy === 'signed' || playbackPolicy === 'drm') {\n const token = generateJwt(client, playbackId, audience, params)\n searchParams = new URLSearchParams({token})\n }\n\n return {playbackId, searchParams}\n}\n","import type {SanityClient} from 'sanity'\n\nimport {createUrlParamsObject} from './createUrlParamsObject'\nimport type {AnimatedThumbnailOptions, MuxAnimatedThumbnailUrl} from './types'\nimport {AssetThumbnailOptions} from './types'\n\nexport interface AnimatedPosterSrcOptions extends AnimatedThumbnailOptions {\n asset: AssetThumbnailOptions['asset']\n client: SanityClient\n}\n\nexport function getAnimatedPosterSrc({\n asset,\n client,\n height,\n width,\n start = asset.thumbTime ? Math.max(0, asset.thumbTime - 2.5) : 0,\n end = start + 5,\n fps = 15,\n}: AnimatedPosterSrcOptions): MuxAnimatedThumbnailUrl {\n const params = {height, width, start, end, fps}\n\n const {playbackId, searchParams} = createUrlParamsObject(client, asset, params, 'g')\n\n return `https://image.mux.com/${playbackId}/animated.gif?${searchParams}`\n}\n","import type {SanityClient} from 'sanity'\n\nimport {createUrlParamsObject} from './createUrlParamsObject'\nimport type {MuxThumbnailUrl, ThumbnailOptions} from './types'\nimport {AssetThumbnailOptions} from './types'\n\nexport interface PosterSrcOptions extends ThumbnailOptions {\n asset: AssetThumbnailOptions['asset']\n client: SanityClient\n}\n\nexport function getPosterSrc({\n asset,\n client,\n fit_mode,\n height,\n time = asset.thumbTime ?? undefined,\n width,\n}: PosterSrcOptions): MuxThumbnailUrl {\n const params = {fit_mode, height, width}\n if (time !== undefined) {\n ;(params as any).time = time\n }\n\n const {playbackId, searchParams} = createUrlParamsObject(client, asset, params, 't')\n\n return `https://image.mux.com/${playbackId}/thumbnail.png?${searchParams}`\n}\n","/**\n * When running `suspend()` from react-suspend a function may throw a Promise\n * causing unexpected behavior when catching.\n * @param block Your block of code that uses suspend\n * @param onError (optional) How to handle a regular Error\n * @returns Whatever is returned by the block if it succeeds, otherwise whatever is resolved by onError if defined\n * @throws rethrows the caught Promise to comply with Suspense logic\n */\nexport function tryWithSuspend<T, E>(\n block: () => T,\n onError?: (error: Error) => E\n): T | E | undefined {\n try {\n return block()\n } catch (errorOrPromise) {\n if (errorOrPromise instanceof Promise) {\n // react-suspend will throw a Promise\n throw errorOrPromise\n }\n return onError ? onError(errorOrPromise as Error) : undefined\n }\n}\n","import {ErrorOutlineIcon} from '@sanity/icons'\nimport {Box, Card, CardTone, Spinner, Stack, Text} from '@sanity/ui'\nimport {Suspense, useMemo, useRef, useState} from 'react'\nimport {styled} from 'styled-components'\n\nimport {useClient} from '../hooks/useClient'\nimport {useInView} from '../hooks/useInView'\nimport {THUMBNAIL_ASPECT_RATIO} from '../util/constants'\nimport {getAnimatedPosterSrc} from '../util/getAnimatedPosterSrc'\nimport {getPosterSrc} from '../util/getPosterSrc'\nimport {tryWithSuspend} from '../util/tryWithSuspend'\nimport {AssetThumbnailOptions, MuxAnimatedThumbnailUrl, MuxThumbnailUrl} from '../util/types'\n\nconst Image = styled.img`\n transition: opacity 0.175s ease-out 0s;\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n object-position: center center;\n`\n\ntype ImageStatus = 'loading' | 'error' | 'loaded'\n\nconst STATUS_TO_TONE: Record<ImageStatus, CardTone> = {\n loading: 'transparent',\n error: 'critical',\n loaded: 'default',\n}\n\nexport default function VideoThumbnail({\n asset,\n width,\n staticImage = false,\n}: {\n asset: AssetThumbnailOptions['asset']\n width?: number\n staticImage?: boolean\n}) {\n const posterWidth = width || 250\n const client = useClient()\n const ref = useRef<HTMLDivElement | null>(null)\n const inView = useInView(ref)\n\n const [status, setStatus] = useState<ImageStatus>('loading')\n const [error, setError] = useState<string | null>(null)\n\n const thumbnailSrc = useMemo(() => {\n return tryWithSuspend(\n () => {\n let thumbnail: MuxAnimatedThumbnailUrl | MuxThumbnailUrl | undefined\n\n if (staticImage) thumbnail = getPosterSrc({asset, client, width: posterWidth})\n else thumbnail = getAnimatedPosterSrc({asset, client, width: posterWidth})\n return thumbnail\n },\n (err: Error) => {\n handleError(err.message)\n return undefined\n }\n )\n }, [asset, client, posterWidth, staticImage])\n\n function handleLoad() {\n setStatus('loaded')\n }\n\n function handleError(err?: string) {\n setStatus('error')\n if (err) {\n setError(err)\n } else {\n setError('Failed loading thumbnail')\n }\n }\n\n return (\n <Suspense fallback={<span>Preparing thumbnail</span>}>\n <Card\n style={{\n aspectRatio: THUMBNAIL_ASPECT_RATIO,\n position: 'relative',\n maxWidth: width ? `${width}px` : undefined,\n width: '100%',\n flex: 1,\n }}\n border\n radius={2}\n ref={ref}\n tone={STATUS_TO_TONE[status]}\n >\n {inView ? (\n <>\n {status === 'loading' && (\n <Box\n style={{\n position: 'absolute',\n left: '50%',\n top: '50%',\n transform: 'translate(-50%, -50%)',\n }}\n >\n <Spinner />\n </Box>\n )}\n {status === 'error' && (\n <Stack\n space={4}\n style={{\n position: 'absolute',\n width: '100%',\n left: 0,\n top: '50%',\n transform: 'translateY(-50%)',\n justifyItems: 'center',\n }}\n >\n <Text size={4} muted>\n <ErrorOutlineIcon style={{fontSize: '1.75em'}} />\n </Text>\n <Text muted align=\"center\">\n {error}\n </Text>\n </Stack>\n )}\n <Image\n src={thumbnailSrc ?? undefined}\n alt={`Preview for ${staticImage ? 'image' : 'video'} ${asset.filename || asset.assetId}`}\n onLoad={handleLoad}\n onError={() => handleError()}\n style={{opacity: status === 'loaded' ? 1 : 0}}\n />\n </>\n ) : null}\n </Card>\n </Suspense>\n )\n}\n","import {\n CheckmarkCircleIcon,\n ErrorOutlineIcon,\n InfoOutlineIcon,\n RetrieveIcon,\n RetryIcon,\n} from '@sanity/icons'\nimport {\n Box,\n Button,\n Card,\n Checkbox,\n Code,\n Dialog,\n Flex,\n Heading,\n Spinner,\n Stack,\n Text,\n} from '@sanity/ui'\nimport {truncateString, useFormattedDuration} from 'sanity'\nimport {styled} from 'styled-components'\n\nimport useImportMuxAssets from '../hooks/useImportMuxAssets'\nimport {DIALOGS_Z_INDEX} from '../util/constants'\nimport type {MuxAsset} from '../util/types'\nimport VideoThumbnail from './VideoThumbnail'\n\nconst MissingAssetCheckbox = styled(Checkbox)`\n position: static !important;\n\n input::after {\n content: '';\n position: absolute;\n inset: 0;\n display: block;\n cursor: pointer;\n z-index: 1000;\n }\n`\n\nfunction MissingAsset({\n asset,\n selectAsset,\n selected,\n}: {\n asset: MuxAsset\n selectAsset: (selected: boolean) => void\n selected: boolean\n}) {\n const duration = useFormattedDuration(asset.duration * 1000)\n\n return (\n <Card\n key={asset.id}\n tone={selected ? 'positive' : undefined}\n border\n paddingX={2}\n paddingY={3}\n style={{position: 'relative'}}\n radius={1}\n >\n <Flex align=\"center\" gap={2}>\n <MissingAssetCheckbox\n checked={selected}\n onChange={(e) => {\n selectAsset(e.currentTarget.checked)\n }}\n aria-label={selected ? `Import video ${asset.id}` : `Skip import of video ${asset.id}`}\n />\n <VideoThumbnail\n asset={{\n assetId: asset.id,\n data: asset,\n filename: asset.id,\n playbackId: asset.playback_ids.find((p) => p.id)?.id,\n }}\n width={150}\n />\n <Stack space={2}>\n <Flex align=\"center\" gap={1}>\n <Code size={2}>{truncateString(asset.id, 15)}</Code>{' '}\n <Text muted size={2}>\n ({duration.formatted})\n </Text>\n </Flex>\n <Text size={1}>\n Uploaded at{' '}\n {new Date(Number(asset.created_at) * 1000).toLocaleDateString('en', {\n year: 'numeric',\n day: '2-digit',\n month: '2-digit',\n })}\n </Text>\n </Stack>\n </Flex>\n </Card>\n )\n}\n\n// eslint-disable-next-line complexity\nfunction ImportVideosDialog(props: ReturnType<typeof useImportMuxAssets>) {\n const {importState} = props\n\n const canTriggerImport =\n (importState === 'idle' || importState === 'error') && props.selectedAssets.length > 0\n const isImporting = importState === 'importing'\n const noAssetsToImport =\n props.missingAssets?.length === 0 && !props.muxAssets.loading && !props.assetsInSanityLoading\n\n return (\n <Dialog\n animate\n header={'Import videos from Mux'}\n zOffset={DIALOGS_Z_INDEX}\n id=\"video-details-dialog\"\n onClose={props.closeDialog}\n onClickOutside={props.closeDialog}\n width={1}\n position=\"fixed\"\n footer={\n importState !== 'done' &&\n !noAssetsToImport && (\n <Card padding={3}>\n <Flex justify=\"space-between\" align=\"center\">\n <Button\n fontSize={2}\n padding={3}\n mode=\"ghost\"\n text=\"Cancel\"\n tone=\"critical\"\n onClick={props.closeDialog}\n disabled={isImporting}\n />\n {props.missingAssets && (\n <Button\n icon={RetrieveIcon}\n fontSize={2}\n padding={3}\n mode=\"ghost\"\n text={\n props.selectedAssets?.length > 0\n ? `Import ${props.selectedAssets.length} video(s)`\n : 'No video(s) selected'\n }\n tone=\"positive\"\n onClick={props.importAssets}\n iconRight={isImporting && Spinner}\n disabled={!canTriggerImport}\n />\n )}\n </Flex>\n </Card>\n )\n }\n >\n <Box padding={3}>\n {/* WARNING: SKIPPED ASSETS WITHOUT PLAYBACK */}\n {props.muxAssets.hasSkippedAssetsWithoutPlayback && (\n <Card tone=\"caution\" marginBottom={5} padding={3} border>\n <Flex align=\"center\" gap={2}>\n <InfoOutlineIcon fontSize={36} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n Some videos were skipped\n </Text>\n <Text size={1}>\n Videos without playback IDs cannot be imported and have been excluded from the\n list.\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* LOADING ASSETS STATE */}\n {(props.muxAssets.loading || props.assetsInSanityLoading) && (\n <Card tone=\"primary\" marginBottom={5} padding={3} border>\n <Flex align=\"center\" gap={4}>\n <Spinner muted size={4} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n Loading assets from Mux\n </Text>\n <Text size={1}>\n This may take a while.\n {props.missingAssets &&\n props.missingAssets.length > 0 &&\n ` There are at least ${props.missingAssets.length} video${props.missingAssets.length > 1 ? 's' : ''} currently not in Sanity...`}\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* ERROR LOADING MUX */}\n {props.muxAssets.error && (\n <Card tone=\"critical\" marginBottom={5} padding={3} border>\n <Flex align=\"center\" gap={2}>\n <ErrorOutlineIcon fontSize={36} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n There was an error getting all data from Mux\n </Text>\n <Text size={1}>\n {props.missingAssets\n ? `But we've found ${props.missingAssets.length} video${props.missingAssets.length > 1 ? 's' : ''} not in Sanity, which you can start importing now.`\n : 'Please try again or contact a developer for help.'}\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* IMPORTING STATE */}\n {importState === 'importing' && (\n <Card tone=\"primary\" marginBottom={5} padding={3} border>\n <Flex align=\"center\" gap={4}>\n <Spinner muted size={4} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n Importing {props.selectedAssets.length} video\n {props.selectedAssets.length > 1 && 's'} from Mux\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* ERROR IMPORTING */}\n {importState === 'error' && (\n <Card tone=\"critical\" marginBottom={5} padding={3} border>\n <Flex align=\"center\" gap={2}>\n <ErrorOutlineIcon fontSize={36} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n There was an error importing videos\n </Text>\n <Text size={1}>\n {props.importError\n ? `Error: ${props.importError}`\n : 'Please try again or contact a developer for help.'}\n </Text>\n <Box marginTop={1}>\n <Button\n icon={RetryIcon}\n text=\"Retry\"\n tone=\"primary\"\n onClick={props.importAssets}\n />\n </Box>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* NO ASSETS TO IMPORT or SUCESS STATE */}\n {(noAssetsToImport || importState === 'done') && (\n <Stack paddingY={5} marginBottom={4} space={3} style={{textAlign: 'center'}}>\n <Box>\n <CheckmarkCircleIcon fontSize={48} />\n </Box>\n <Heading size={2}>\n {importState === 'done'\n ? `Videos imported successfully`\n : 'There are no Mux videos to import'}\n </Heading>\n <Text size={2}>\n {importState === 'done'\n ? 'You can now use them in your Sanity content.'\n : \"They're all in Sanity and ready to be used in your content.\"}\n </Text>\n </Stack>\n )}\n\n {/* MISSING ASSETS SELECTOR */}\n {props.missingAssets &&\n props.missingAssets.length > 0 &&\n (importState === 'idle' || importState === 'error') && (\n <Stack space={4}>\n <Heading size={1}>\n There are {props.missingAssets.length}\n {props.muxAssets.loading && '+'} Mux video{props.missingAssets.length > 1 && 's'}{' '}\n not in Sanity\n </Heading>\n {!props.muxAssets.loading && (\n <Flex align=\"center\" paddingX={2}>\n <Checkbox\n id=\"import-all\"\n style={{display: 'block'}}\n onClick={(e) => {\n const selectAll = e.currentTarget.checked\n if (selectAll) {\n // eslint-disable-next-line no-unused-expressions\n props.missingAssets && props.setSelectedAssets(props.missingAssets)\n } else {\n props.setSelectedAssets([])\n }\n }}\n checked={props.selectedAssets.length === props.missingAssets.length}\n />\n <Box flex={1} paddingLeft={3} as=\"label\" htmlFor=\"import-all\">\n <Text>Import all</Text>\n </Box>\n </Flex>\n )}\n {props.missingAssets.map((asset) => (\n <MissingAsset\n key={asset.id}\n asset={asset}\n selectAsset={(selected) => {\n if (selected) {\n props.setSelectedAssets([...props.selectedAssets, asset])\n } else {\n props.setSelectedAssets(props.selectedAssets.filter((a) => a.id !== asset.id))\n }\n }}\n selected={props.selectedAssets.some((a) => a.id === asset.id)}\n />\n ))}\n </Stack>\n )}\n </Box>\n </Dialog>\n )\n}\n\nexport default function ImportVideosFromMux() {\n const importAssets = useImportMuxAssets()\n\n if (!importAssets.hasSecrets) {\n return\n }\n\n if (importAssets.dialogOpen) {\n // eslint-disable-next-line consistent-return\n return <ImportVideosDialog {...importAssets} />\n }\n\n // eslint-disable-next-line consistent-return\n return <Button mode=\"bleed\" text=\"Import from Mux\" onClick={importAssets.openDialog} />\n}\n","import {ChevronLeftIcon, ChevronRightIcon} from '@sanity/icons'\nimport {Button, Label} from '@sanity/ui'\nimport {Dispatch, SetStateAction, useEffect} from 'react'\n\nconst PageSelector = (props: {\n page: number\n setPage: Dispatch<SetStateAction<number>>\n total: number\n}) => {\n const page = props.page\n const setPage = props.setPage\n\n useEffect(() => {\n // Constraint in bounds.\n const clamped = Math.min(props.total - 1, Math.max(0, page))\n if (page !== clamped) {\n setPage(clamped)\n }\n }, [page, props.total, setPage])\n\n return (\n <>\n <Button\n icon={ChevronLeftIcon}\n mode=\"bleed\"\n padding={3}\n style={{cursor: 'pointer'}}\n disabled={page <= 0}\n onClick={() => {\n setPage((p) => {\n return Math.min(props.total - 1, Math.max(0, p - 1))\n })\n }}\n />\n <Label muted>\n Page {page + 1}/{props.total}\n </Label>\n <Button\n icon={ChevronRightIcon}\n mode=\"bleed\"\n padding={3}\n style={{cursor: 'pointer'}}\n disabled={page >= props.total - 1}\n onClick={() => {\n setPage((p) => {\n return Math.min(props.total - 1, Math.max(0, p + 1))\n })\n }}\n />\n </>\n )\n}\n\nexport default PageSelector\n","import {uuid} from '@sanity/uuid'\n\nimport type {MuxAsset} from './types'\n\n/**\n * Adds _key to array items in MuxAsset data for Sanity compatibility.\n * Sanity requires _key on array items for proper editing support.\n */\nexport function addKeysToMuxData(data: MuxAsset): MuxAsset {\n return {\n ...data,\n tracks: data.tracks?.map((track) => ({\n ...track,\n _key: uuid(),\n })),\n playback_ids: data.playback_ids?.map((playbackId) => ({\n ...playbackId,\n _key: uuid(),\n })),\n static_renditions: data.static_renditions\n ? {\n ...data.static_renditions,\n files: data.static_renditions.files?.map((file) => ({\n ...file,\n _key: uuid(),\n })),\n }\n : undefined,\n }\n}\n","import {useMemo, useState} from 'react'\nimport {\n createHookFromObservableFactory,\n type DocumentStore,\n useClient,\n useDocumentStore,\n} from 'sanity'\n\nimport {addKeysToMuxData} from '../util/addKeysToMuxData'\nimport {isEmptyOrPlaceholderTitle} from '../util/assetTitlePlaceholder'\nimport type {MuxAsset, VideoAssetDocument} from '../util/types'\nimport {SANITY_API_VERSION} from './useClient'\nimport useMuxAssets from './useMuxAssets'\nimport {useSecretsDocumentValues} from './useSecretsDocumentValues'\n\ntype ResyncState = 'closed' | 'idle' | 'syncing' | 'done' | 'error'\n\nexport type MatchedAsset = {\n sanityDoc: VideoAssetDocument\n muxAsset: MuxAsset | undefined\n muxTitle: string | undefined\n currentTitle: string | undefined\n}\n\nexport default function useResyncMuxMetadata() {\n const documentStore = useDocumentStore()\n const client = useClient({\n apiVersion: SANITY_API_VERSION,\n })\n\n const [sanityAssets, sanityAssetsLoading] = useSanityAssets(documentStore)\n\n const secretDocumentValues = useSecretsDocumentValues()\n const hasSecrets = !!secretDocumentValues.value.secrets?.secretKey\n\n const [resyncError, setResyncError] = useState<unknown>()\n const [resyncState, setResyncState] = useState<ResyncState>('closed')\n const dialogOpen = resyncState !== 'closed'\n\n const muxAssets = useMuxAssets({\n client,\n enabled: hasSecrets && dialogOpen,\n })\n\n const matchedAssets = useMemo(() => {\n return sanityAssets && muxAssets.data\n ? sanityAssets.map((sanityDoc) => {\n const muxAsset = muxAssets.data?.find(\n (m) => m.id === sanityDoc.assetId || m.id === sanityDoc.data?.id\n )\n return {\n sanityDoc,\n muxAsset,\n muxTitle: muxAsset?.meta?.title,\n currentTitle: sanityDoc.filename,\n }\n })\n : undefined\n }, [sanityAssets, muxAssets.data])\n\n const closeDialog = () => {\n if (resyncState !== 'syncing') setResyncState('closed')\n }\n\n const openDialog = () => {\n if (resyncState === 'closed') setResyncState('idle')\n }\n\n async function syncAllVideos() {\n if (!matchedAssets) return\n\n setResyncState('syncing')\n\n try {\n const tx = client.transaction()\n\n matchedAssets.forEach((matched) => {\n // Update all videos with the Mux title, even if it's undefined/empty\n const newTitle = matched.muxTitle || ''\n tx.patch(matched.sanityDoc._id, {set: {filename: newTitle}})\n })\n\n await tx.commit({returnDocuments: false})\n setResyncState('done')\n } catch (error) {\n setResyncState('error')\n setResyncError(error)\n }\n }\n\n async function syncOnlyEmpty() {\n if (!matchedAssets) return\n\n setResyncState('syncing')\n\n try {\n const tx = client.transaction()\n\n matchedAssets.forEach((matched) => {\n // Only update if the current title is empty or has the placeholder format\n // AND there's a new title available from Mux\n if (\n matched.muxAsset &&\n matched.muxTitle &&\n isEmptyOrPlaceholderTitle(matched.currentTitle, matched.muxAsset.id)\n ) {\n tx.patch(matched.sanityDoc._id, {set: {filename: matched.muxTitle}})\n }\n })\n\n await tx.commit({returnDocuments: false})\n setResyncState('done')\n } catch (error) {\n setResyncState('error')\n setResyncError(error)\n }\n }\n\n async function syncFullData() {\n if (!matchedAssets) return\n\n setResyncState('syncing')\n\n try {\n const tx = client.transaction()\n\n matchedAssets.forEach((matched) => {\n if (!matched.muxAsset) return\n\n const dataWithKeys = addKeysToMuxData(matched.muxAsset)\n\n // Update all fields: filename, status, and full data from Mux\n tx.patch(matched.sanityDoc._id, {\n set: {\n filename: matched.muxTitle || matched.currentTitle || '',\n status: matched.muxAsset.status,\n data: dataWithKeys,\n },\n })\n })\n\n await tx.commit({returnDocuments: false})\n setResyncState('done')\n } catch (error) {\n setResyncState('error')\n setResyncError(error)\n }\n }\n\n return {\n sanityAssetsLoading,\n closeDialog,\n dialogOpen,\n resyncState,\n resyncError,\n hasSecrets,\n syncAllVideos,\n syncOnlyEmpty,\n syncFullData,\n matchedAssets,\n muxAssets,\n openDialog,\n }\n}\n\nconst useSanityAssets = createHookFromObservableFactory<VideoAssetDocument[], DocumentStore>(\n (documentStore) => {\n return documentStore.listenQuery(\n /* groq */ `*[_type == \"mux.videoAsset\"]`,\n {},\n {\n apiVersion: SANITY_API_VERSION,\n }\n )\n }\n)\n","import {CheckmarkCircleIcon, ErrorOutlineIcon, SyncIcon} from '@sanity/icons'\nimport {Box, Button, Card, Dialog, Flex, Heading, Radio, Spinner, Stack, Text} from '@sanity/ui'\nimport {useState} from 'react'\n\nimport useResyncMuxMetadata from '../hooks/useResyncMuxMetadata'\nimport {isEmptyOrPlaceholderTitle} from '../util/assetTitlePlaceholder'\nimport {DIALOGS_Z_INDEX} from '../util/constants'\n\ntype SyncOption = 'fillEmpty' | 'syncTitles' | 'fullResync'\n\ninterface OptionCardProps {\n id: SyncOption\n selected: boolean\n onSelect: (id: SyncOption) => void\n title: string\n count: number\n description: string\n disabled?: boolean\n}\n\nfunction OptionCard({\n id,\n selected,\n onSelect,\n title,\n count,\n description,\n disabled,\n}: OptionCardProps) {\n return (\n <Card\n as=\"label\"\n padding={3}\n radius={2}\n border\n tone={selected ? 'primary' : 'default'}\n style={{\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n }}\n >\n <Flex gap={3} align=\"flex-start\">\n <Box paddingTop={1}>\n <Radio\n checked={selected}\n onChange={() => onSelect(id)}\n disabled={disabled}\n name=\"sync-option\"\n />\n </Box>\n <Stack space={2} flex={1}>\n <Flex align=\"center\" gap={2}>\n <Text size={2} weight=\"semibold\">\n {title} ({count})\n </Text>\n </Flex>\n <Text size={1} muted>\n {description}\n </Text>\n </Stack>\n </Flex>\n </Card>\n )\n}\n\nfunction ResyncMetadataDialog(props: ReturnType<typeof useResyncMuxMetadata>) {\n const {resyncState} = props\n\n const videosToUpdate = props.matchedAssets?.filter((m) => m.muxAsset).length || 0\n const videosWithEmptyOrPlaceholder =\n props.matchedAssets?.filter(\n (m) => m.muxAsset && m.muxTitle && isEmptyOrPlaceholderTitle(m.currentTitle, m.muxAsset.id)\n ).length || 0\n\n const hasEmptyTitles = videosWithEmptyOrPlaceholder > 0\n const defaultOption: SyncOption = hasEmptyTitles ? 'fillEmpty' : 'syncTitles'\n const [selectedOption, setSelectedOption] = useState<SyncOption>(defaultOption)\n\n const canTriggerResync = resyncState === 'idle' || resyncState === 'error'\n const isResyncing = resyncState === 'syncing'\n const isDone = resyncState === 'done'\n const isLoading = props.muxAssets.loading || props.sanityAssetsLoading\n\n const handleSync = () => {\n switch (selectedOption) {\n case 'fillEmpty':\n props.syncOnlyEmpty()\n break\n case 'syncTitles':\n props.syncAllVideos()\n break\n case 'fullResync':\n props.syncFullData()\n break\n default:\n break\n }\n }\n\n return (\n <Dialog\n animate\n header=\"Sync with Mux\"\n zOffset={DIALOGS_Z_INDEX}\n id=\"resync-metadata-dialog\"\n onClose={props.closeDialog}\n onClickOutside={props.closeDialog}\n width={1}\n position=\"fixed\"\n footer={\n !isDone && (\n <Card padding={3}>\n <Flex justify=\"flex-end\" gap={2}>\n <Button\n fontSize={2}\n padding={3}\n mode=\"ghost\"\n text=\"Cancel\"\n onClick={props.closeDialog}\n disabled={isResyncing}\n />\n <Button\n icon={SyncIcon}\n fontSize={2}\n padding={3}\n text=\"Run sync\"\n tone=\"primary\"\n onClick={handleSync}\n iconRight={isResyncing && Spinner}\n disabled={!canTriggerResync || isLoading}\n />\n </Flex>\n </Card>\n )\n }\n >\n <Box padding={4}>\n {/* LOADING ASSETS STATE */}\n {isLoading && (\n <Card tone=\"primary\" marginBottom={4} padding={3} border radius={2}>\n <Flex align=\"center\" gap={4}>\n <Spinner muted size={4} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n Loading assets from Mux\n </Text>\n <Text size={1} muted>\n This may take a while.\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* ERROR LOADING MUX */}\n {props.muxAssets.error && (\n <Card tone=\"critical\" marginBottom={4} padding={3} border radius={2}>\n <Flex align=\"center\" gap={2}>\n <ErrorOutlineIcon fontSize={36} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n There was an error getting data from Mux\n </Text>\n <Text size={1}>Please try again or contact a developer for help.</Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* SYNCING STATE */}\n {resyncState === 'syncing' && (\n <Card tone=\"primary\" marginBottom={4} padding={3} border radius={2}>\n <Flex align=\"center\" gap={4}>\n <Spinner muted size={4} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n Syncing metadata\n </Text>\n <Text size={1} muted>\n Updating videos from Mux...\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* ERROR SYNCING */}\n {resyncState === 'error' && (\n <Card tone=\"critical\" marginBottom={4} padding={3} border radius={2}>\n <Flex align=\"center\" gap={2}>\n <ErrorOutlineIcon fontSize={36} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n There was an error syncing metadata\n </Text>\n <Text size={1}>\n {props.resyncError\n ? `Error: ${props.resyncError}`\n : 'Please try again or contact a developer for help.'}\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* SUCCESS STATE */}\n {resyncState === 'done' && (\n <Stack paddingY={5} space={3} style={{textAlign: 'center'}}>\n <Box>\n <CheckmarkCircleIcon fontSize={48} />\n </Box>\n <Heading size={2}>Sync completed</Heading>\n <Text size={2} muted>\n Videos have been updated from Mux.\n </Text>\n </Stack>\n )}\n\n {/* OPTIONS */}\n {!isDone && !isLoading && !props.muxAssets.error && (\n <Stack space={4}>\n <Text size={1} muted>\n Found {videosToUpdate} video{videosToUpdate === 1 ? '' : 's'} linked to Mux.\n </Text>\n\n <Stack space={3}>\n {hasEmptyTitles && (\n <OptionCard\n id=\"fillEmpty\"\n selected={selectedOption === 'fillEmpty'}\n onSelect={setSelectedOption}\n title=\"Fill missing titles only\"\n count={videosWithEmptyOrPlaceholder}\n description=\"Updates only videos without a title or with placeholder titles (e.g., 'Asset #123') using the title from Mux.\"\n disabled={isResyncing}\n />\n )}\n\n <OptionCard\n id=\"syncTitles\"\n selected={selectedOption === 'syncTitles'}\n onSelect={setSelectedOption}\n title=\"Sync all titles\"\n count={videosToUpdate}\n description=\"Replaces the title in Sanity with the title from Mux for all videos.\"\n disabled={isResyncing}\n />\n\n <OptionCard\n id=\"fullResync\"\n selected={selectedOption === 'fullResync'}\n onSelect={setSelectedOption}\n title=\"Full resync\"\n count={videosToUpdate}\n description=\"Updates all fields from Mux including status, duration, tracks, captions, and renditions.\"\n disabled={isResyncing}\n />\n </Stack>\n </Stack>\n )}\n </Box>\n </Dialog>\n )\n}\n\nexport default function ResyncMetadata() {\n const resyncMetadata = useResyncMuxMetadata()\n\n if (!resyncMetadata.hasSecrets) {\n return\n }\n\n if (resyncMetadata.dialogOpen) {\n // eslint-disable-next-line consistent-return\n return <ResyncMetadataDialog {...resyncMetadata} />\n }\n\n // eslint-disable-next-line consistent-return\n return <Button mode=\"bleed\" text=\"Sync with Mux\" onClick={resyncMetadata.openDialog} />\n}\n","import {SortIcon} from '@sanity/icons'\nimport {Button, Menu, MenuButton, MenuItem, PopoverProps} from '@sanity/ui'\nimport {useId} from 'react'\n\nimport {ASSET_SORT_OPTIONS, SortOption} from '../hooks/useAssets'\n\nexport const CONTEXT_MENU_POPOVER_PROPS: PopoverProps = {\n constrainSize: true,\n placement: 'bottom',\n portal: true,\n width: 0,\n}\n\n/**\n * @sanity/ui components adapted from:\n * https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/pane/PaneContextMenuButton.tsx#L19\n */\nexport function SelectSortOptions(props: {sort: SortOption; setSort: (s: SortOption) => void}) {\n const id = useId()\n\n return (\n <MenuButton\n button={\n <Button text=\"Sort\" icon={SortIcon} mode=\"bleed\" padding={3} style={{cursor: 'pointer'}} />\n }\n id={id}\n menu={\n <Menu>\n {Object.entries(ASSET_SORT_OPTIONS).map(([type, {label}]) => (\n <MenuItem\n key={type}\n data-as=\"button\"\n onClick={() => props.setSort(type as SortOption)}\n padding={3}\n tone=\"default\"\n text={label}\n pressed={type === props.sort}\n />\n ))}\n </Menu>\n }\n popover={CONTEXT_MENU_POPOVER_PROPS}\n />\n )\n}\n","import {Box, Spinner} from '@sanity/ui'\n\nconst SpinnerBox: React.FC = () => (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '150px',\n }}\n >\n <Spinner />\n </Box>\n)\n\nexport default SpinnerBox\n","import {Flex, Text} from '@sanity/ui'\n\nconst IconInfo: React.FC<{\n text: string\n icon: React.FC\n size?: number\n muted?: boolean\n}> = (props) => {\n const Icon = props.icon\n return (\n <Flex gap={2} align=\"center\" padding={1}>\n <Text size={(props.size || 1) + 1} muted>\n <Icon />\n </Text>\n <Text size={props.size || 1} muted={props.muted}>\n {props.text}\n </Text>\n </Flex>\n )\n}\n\nexport default IconInfo\n","import type {SVGProps} from 'react'\n\nexport function ResolutionIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M20 9V6h-3V4h5v5h-2ZM2 9V4h5v2H4v3H2Zm15 11v-2h3v-3h2v5h-5ZM2 20v-5h2v3h3v2H2Zm4-4V8h12v8H6Zm2-2h8v-4H8v4Zm0 0v-4v4Z\"\n />\n </svg>\n )\n}\n","import type {SVGProps} from 'react'\n\nexport function StopWatchIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 512 512\"\n {...props}\n >\n <path d=\"M232 306.667h48V176h-48v130.667z\" fill=\"currentColor\" />\n <path\n d=\"M407.67 170.271l30.786-30.786-33.942-33.941-30.785 30.786C341.217 111.057 300.369 96 256 96 149.961 96 64 181.961 64 288s85.961 192 192 192 192-85.961 192-192c0-44.369-15.057-85.217-40.33-117.729zm-45.604 223.795C333.734 422.398 296.066 438 256 438s-77.735-15.602-106.066-43.934C121.602 365.735 106 328.066 106 288s15.602-77.735 43.934-106.066C178.265 153.602 215.934 138 256 138s77.734 15.602 106.066 43.934C390.398 210.265 406 247.934 406 288s-15.602 77.735-43.934 106.066z\"\n fill=\"currentColor\"\n />\n <path d=\"M192 32h128v48H192z\" fill=\"currentColor\" />\n </svg>\n )\n}\n","import {useToast} from '@sanity/ui'\nimport {useCallback, useState} from 'react'\n\nimport {getAsset} from '../actions/assets'\nimport {addKeysToMuxData} from '../util/addKeysToMuxData'\nimport type {MuxAsset, VideoAssetDocument} from '../util/types'\nimport {useClient} from './useClient'\n\ntype ResyncAssetState = 'idle' | 'syncing' | 'success' | 'error'\n\ninterface UseResyncAssetOptions {\n showToast?: boolean\n onSuccess?: (updatedData: MuxAsset) => void\n onError?: (error: unknown) => void\n}\n\ninterface UseResyncAssetReturn {\n resyncState: ResyncAssetState\n resyncError: unknown\n resyncAsset: (asset: VideoAssetDocument) => Promise<MuxAsset | undefined>\n isResyncing: boolean\n}\n\nexport function useResyncAsset(options?: UseResyncAssetOptions): UseResyncAssetReturn {\n const client = useClient()\n const toast = useToast()\n const [resyncState, setResyncState] = useState<ResyncAssetState>('idle')\n const [resyncError, setResyncError] = useState<unknown>(null)\n\n const showToast = options?.showToast ?? false\n\n const resyncAsset = useCallback(\n async (asset: VideoAssetDocument) => {\n if (!asset.assetId) {\n if (showToast) {\n toast.push({\n title: 'Cannot resync',\n description: 'Asset has no Mux ID',\n status: 'error',\n })\n }\n options?.onError?.(new Error('Asset has no Mux ID'))\n return undefined\n }\n\n if (!asset._id) {\n if (showToast) {\n toast.push({\n title: 'Cannot resync',\n description: 'Asset has no document ID',\n status: 'error',\n })\n }\n options?.onError?.(new Error('Asset has no document ID'))\n return undefined\n }\n\n setResyncState('syncing')\n setResyncError(null)\n\n try {\n const response = await getAsset(client, asset.assetId)\n const muxData = response.data\n const dataWithKeys = addKeysToMuxData(muxData)\n\n await client\n .patch(asset._id)\n .set({\n status: muxData.status,\n data: dataWithKeys,\n ...(muxData.meta?.title && {filename: muxData.meta.title}),\n })\n .commit({returnDocuments: false})\n\n setResyncState('success')\n if (showToast) {\n toast.push({\n title: 'Asset synced',\n description: 'Data has been updated from Mux',\n status: 'success',\n })\n }\n\n options?.onSuccess?.(muxData)\n return muxData\n } catch (error) {\n setResyncState('error')\n setResyncError(error)\n console.error('Failed to refresh asset data:', error)\n if (showToast) {\n toast.push({\n title: 'Sync failed',\n description: 'Could not sync asset from Mux',\n status: 'error',\n })\n }\n options?.onError?.(error)\n return undefined\n }\n },\n [client, toast, options, showToast]\n )\n\n return {\n resyncState,\n resyncError,\n resyncAsset,\n isResyncing: resyncState === 'syncing',\n }\n}\n","import type {SanityClient} from '@sanity/client'\n\nimport {getAsset} from '../actions/assets'\nimport {generateJwt} from './generateJwt'\nimport {getPlaybackId} from './getPlaybackPolicy'\nimport {getPlaybackPolicy} from './getPlaybackPolicy'\nimport type {MuxTextTrack, VideoAssetDocument} from './types'\n\nexport function extractErrorMessage(\n error: unknown,\n defaultMessage = 'Failed to process request'\n): string {\n let message = ''\n\n if (error && typeof error === 'object') {\n const err = error as {response?: {body?: {message?: string}}; message?: string}\n message = err.response?.body?.message || err.message || ''\n } else if (typeof error === 'string') {\n message = error\n }\n\n if (!message) {\n return defaultMessage\n }\n\n const match = message.match(/\\(([^)]+)\\)/)\n if (match && match[1]) {\n return match[1]\n }\n\n if (message.includes('responded with')) {\n const parts = message.split('(')\n if (parts.length > 1) {\n return parts[parts.length - 1].replace(')', '').trim()\n }\n }\n\n return message\n}\n\nexport interface PollTrackStatusOptions {\n client: SanityClient\n assetId: string\n trackName: string\n trackLanguageCode: string\n maxAttempts?: number\n onTrackFound?: (track: MuxTextTrack) => void\n onTrackErrored?: (track: MuxTextTrack) => void\n onTrackReady?: (track: MuxTextTrack) => void\n}\n\nexport interface PollTrackStatusResult {\n track: MuxTextTrack | undefined\n found: boolean\n status: 'ready' | 'preparing' | 'errored' | 'not-found'\n}\n\n/**\n * Polls Mux API to find and track the status of a newly added text track.\n * The track may be in \"preparing\" state initially, then become \"ready\" or \"errored\".\n *\n * @param options - Configuration options for polling\n * @returns Promise resolving to the poll result\n */\nexport async function pollTrackStatus(\n options: PollTrackStatusOptions\n): Promise<PollTrackStatusResult> {\n const {\n client,\n assetId,\n trackName,\n trackLanguageCode,\n maxAttempts = 10,\n onTrackFound,\n onTrackErrored,\n onTrackReady,\n } = options\n\n const trimmedName = trackName.trim()\n const trimmedLanguageCode = trackLanguageCode.trim()\n let newTrack: MuxTextTrack | undefined\n let attempts = 0\n let trackFound = false\n\n const findTrack = (textTracks: MuxTextTrack[]): MuxTextTrack | undefined => {\n let foundTrack = textTracks.find(\n (track) => track.name === trimmedName && track.language_code === trimmedLanguageCode\n )\n\n if (!foundTrack) {\n foundTrack = textTracks.find((track) => track.language_code === trimmedLanguageCode)\n }\n\n if (!foundTrack && textTracks.length > 0) {\n foundTrack = textTracks[textTracks.length - 1]\n }\n\n return foundTrack\n }\n\n while (attempts < maxAttempts) {\n try {\n if (attempts > 0) {\n await new Promise((resolve) => setTimeout(resolve, 1000))\n }\n\n const assetData = await getAsset(client, assetId)\n const textTracks =\n assetData.data.tracks?.filter((track): track is MuxTextTrack => track.type === 'text') || []\n\n const foundTrack = findTrack(textTracks)\n\n if (!foundTrack) {\n attempts++\n continue\n }\n\n trackFound = true\n newTrack = foundTrack\n\n if (onTrackFound) {\n onTrackFound(foundTrack)\n }\n\n if (foundTrack.status === 'ready') {\n if (onTrackReady) {\n onTrackReady(foundTrack)\n }\n break\n }\n\n if (foundTrack.status === 'errored') {\n if (onTrackErrored) {\n onTrackErrored(foundTrack)\n }\n return {\n track: foundTrack,\n found: true,\n status: 'errored',\n }\n }\n } catch (error) {\n console.error('Failed to fetch updated asset:', error)\n }\n\n attempts++\n }\n\n if (!newTrack || !trackFound) {\n return {\n track: undefined,\n found: false,\n status: 'not-found',\n }\n }\n\n if (newTrack.status === 'preparing') {\n return {\n track: newTrack,\n found: true,\n status: 'preparing',\n }\n }\n\n return {\n track: newTrack,\n found: true,\n status: 'ready',\n }\n}\n\n/**\n * May throw a Promise. Call this with {@link tryWithSuspend} or rethrow the Promise\n */\nexport async function downloadVttFile(\n client: SanityClient,\n asset: VideoAssetDocument,\n track: MuxTextTrack\n): Promise<void> {\n if (!track.id) {\n throw new Error('Track ID is missing')\n }\n\n if (track.status !== 'ready') {\n throw new Error(`Track is not ready yet. Status: ${track.status}`)\n }\n\n if (!asset.assetId) {\n throw new Error('Asset ID is required')\n }\n\n const playbackId = getPlaybackId(asset)\n if (!playbackId) {\n throw new Error('Playback ID is required')\n }\n\n const playbackPolicy = getPlaybackPolicy(asset)?.policy\n\n let downloadUrl = `https://stream.mux.com/${playbackId}/text/${track.id}.vtt`\n\n if (playbackPolicy === 'signed' || playbackPolicy === 'drm') {\n const token = generateJwt(client, playbackId, 'v')\n downloadUrl += `?token=${token}`\n }\n\n const response = await fetch(downloadUrl)\n if (!response.ok) {\n throw new Error(`Failed to download file: ${response.statusText}`)\n }\n\n const blob = await response.blob()\n const blobUrl = URL.createObjectURL(blob)\n\n const link = document.createElement('a')\n link.href = blobUrl\n link.download = `${asset.filename || 'captions'}-${track.language_code || 'en'}.vtt`\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n\n URL.revokeObjectURL(blobUrl)\n}\n","import type MuxPlayerElement from '@mux/mux-player'\nimport type {ObjectInputProps, PreviewLayoutKey, PreviewProps, SchemaType} from 'sanity'\nimport type {PartialDeep} from 'type-fest'\n\n/**\n * Standard static rendition options available for plugin configuration defaults\n */\nexport type StandardRendition = 'highest' | 'audio-only'\n\n/**\n * All static rendition resolution options supported by Mux\n */\nexport type StaticRenditionResolution =\n | 'highest'\n | 'audio-only'\n | '270p'\n | '360p'\n | '480p'\n | '540p'\n | '720p'\n | '1080p'\n | '1440p'\n | '2160p'\n\nexport interface MuxInputConfig {\n /**\n * Enable static renditions by default. Can be overwritten on a per-asset basis.\n * Supports:\n * - Standard mode: 'highest' (up to 4K MP4) and/or 'audio-only' (M4A)\n * - Advanced mode: Specific resolutions ('270p', '360p', '480p', '540p', '720p', '1080p', '1440p', '2160p') and/or 'audio-only'\n *\n * **Important**: 'highest' cannot be mixed with specific resolutions. If both are provided, only 'highest' will be used.\n *\n * @see {@link https://docs.mux.com/guides/video/enable-static-mp4-renditions}\n * @defaultValue []\n */\n static_renditions: StaticRenditionResolution[]\n\n /**\n * @deprecated Use `static_renditions` instead. This field is kept for backward compatibility.\n * Enable static renditions by setting this to 'standard'. Can be overwritten on a per-asset basis.\n * Requires `\"video_quality\": \"plus\"`\n * @see {@link https://docs.mux.com/guides/video/enable-static-mp4-renditions#why-enable-mp4-support}\n * @defaultValue 'none'\n */\n mp4_support: 'none' | 'standard'\n\n /**\n * Max resolution tier can be used to control the maximum resolution_tier your asset is encoded, stored, and streamed at.\n * Requires `\"video_quality\": \"plus\"`\n * @see {@link https://docs.mux.com/guides/stream-videos-in-4k}\n * @defaultValue '1080p'\n */\n max_resolution_tier: '2160p' | '1440p' | '1080p'\n\n /**\n * @deprecated Use {@link video_quality}\n * <br>\n * The encoding tier informs the cost, quality, and available platform features for the asset.\n * @see {@link https://docs.mux.com/guides/use-encoding-tiers}\n * @defaultValue 'smart'\n */\n encoding_tier?: 'baseline' | 'smart'\n\n /**\n * The video quality level informs the cost, quality, and available platform features for the asset.\n * @see {@link https://www.mux.com/docs/guides/use-video-quality-levels}\n * @defaultValue 'plus'\n */\n video_quality: 'basic' | 'plus' | 'premium'\n\n /**\n * Normalize the audio track loudness level.\n * @see {@link https://docs.mux.com/guides/adjust-audio-levels#how-to-turn-on-audio-normalization}\n * @defaultValue false\n */\n normalize_audio: boolean\n\n /**\n * Enables signed URLs by default, if you configured them with your API token.\n * @see {@link https://docs.mux.com/guides/secure-video-playback}\n * @defaultValue false\n */\n defaultSigned?: boolean\n\n /**\n * Enables public URLs by default.\n * @defaultValue true\n */\n defaultPublic?: boolean\n\n /**\n * Enables DRM Protection by default, if you configured your DRM Configuration Id.\n * @see {@link https://www.mux.com/docs/guides/protect-videos-with-drm}\n * @defaultValue true\n */\n defaultDrm?: boolean\n\n /**\n * Auto-generate captions for these languages by default.\n * Requires `\"video_quality\": \"plus\"`\n *\n * @see {@link https://docs.mux.com/guides/add-autogenerated-captions-and-use-transcripts}\n * @deprecated use `defaultAutogeneratedSubtitleLang` instead. Only a single autogenerated\n */\n defaultAutogeneratedSubtitleLangs?: SupportedMuxLanguage[]\n\n /**\n * Auto-generate captions for this language by default. Users can still\n * Requires `\"video_quality\": \"plus\"`\n *\n * @see {@link https://docs.mux.com/guides/add-autogenerated-captions-and-use-transcripts}\n */\n defaultAutogeneratedSubtitleLang?: SupportedMuxLanguage\n\n /**\n * Whether or not to allow content editors to override asset upload\n * configuration settings when uploading a video to Mux.\n *\n * @see {@link https://docs.mux.com/guides/secure-video-playback}\n * @defaultValue false\n */\n disableUploadConfig?: boolean\n\n /**\n * Whether or not to allow content editors to add text tracks alongside their\n * asset when uploading a video to Mux.\n *\n * @see {@link https://docs.mux.com/guides/secure-video-playback}\n * @defaultValue false\n */\n disableTextTrackConfig?: boolean\n\n /**\n * Whether or not to show the playback warning when trying to watch DRM content for the first time.\n *\n * @defaultValue false\n */\n disableDrmPlaybackWarning?: boolean\n\n /**\n * The mime types that are accepted by the input.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/accept}\n * @defaultValue ['video/*','audio/*']\n\n */\n acceptedMimeTypes?: ('audio/*' | 'video/*')[]\n\n /**\n * Maximum file size allowed for video uploads in bytes.\n * If not specified, no file size validation will be performed.\n *\n * @example 1024 * 1024 * 1024 // 1 GB\n * @defaultValue undefined\n */\n maxAssetFileSize?: number\n\n /**\n * Maximum video duration allowed in seconds.\n * If not specified, no duration validation will be performed.\n *\n * @example 2 * 60 * 60 // 2 hours\n * @defaultValue undefined\n */\n maxAssetDuration?: number\n\n /**\n * HLS.js configuration options to be passed to the Mux Player.\n * These options allow you to customize the underlying HLS.js playback engine behavior.\n *\n * @see {@link https://github.com/video-dev/hls.js/blob/master/docs/API.md#fine-tuning}\n * @defaultValue undefined\n * @example\n * ```ts\n * {\n * maxBufferLength: 30,\n * lowLatencyMode: true,\n * capLevelToPlayerSize: true\n * }\n * ```\n */\n hlsConfig?: MuxPlayerElement['_hlsConfig']\n}\n\nexport interface PluginConfig extends MuxInputConfig {\n /**\n * How the videos browser should appear as a studio tool in Sanity's top navigation\n *\n * Pass `false` if you want to disable it.\n * @defaultValue {title: 'Videos', icon: VideoIcon}\n **/\n tool:\n | false\n | {\n title?: string\n icon?: React.ComponentType\n }\n\n /**\n * The roles that are allowed to configure the plugin.\n *\n * If not set, all roles will be allowed to configure the plugin.\n * @defaultValue []\n */\n allowedRolesForConfiguration: string[]\n}\n\nexport const SUPPORTED_MUX_LANGUAGES = [\n {label: 'English', code: 'en', state: 'Stable'},\n {label: 'Spanish', code: 'es', state: 'Stable'},\n {label: 'Italian', code: 'it', state: 'Stable'},\n {label: 'Portuguese', code: 'pt', state: 'Stable'},\n {label: 'German', code: 'de', state: 'Stable'},\n {label: 'French', code: 'fr', state: 'Stable'},\n {label: 'Polish', code: 'pl', state: 'Beta'},\n {label: 'Russian', code: 'ru', state: 'Beta'},\n {label: 'Dutch', code: 'nl', state: 'Beta'},\n {label: 'Catalan', code: 'ca', state: 'Beta'},\n {label: 'Turkish', code: 'tr', state: 'Beta'},\n {label: 'Swedish', code: 'sv', state: 'Beta'},\n {label: 'Ukrainian', code: 'uk', state: 'Beta'},\n {label: 'Norwegian', code: 'no', state: 'Beta'},\n {label: 'Finnish', code: 'fi', state: 'Beta'},\n {label: 'Slovak', code: 'sk', state: 'Beta'},\n {label: 'Greek', code: 'el', state: 'Beta'},\n {label: 'Czech', code: 'cs', state: 'Beta'},\n {label: 'Croatian', code: 'hr', state: 'Beta'},\n {label: 'Danish', code: 'da', state: 'Beta'},\n {label: 'Romanian', code: 'ro', state: 'Beta'},\n {label: 'Bulgarian', code: 'bg', state: 'Beta'},\n] as const\n\nexport const VIDEO_QUALITY_LEVELS = [\n {label: 'Basic', value: 'basic'},\n {label: 'Plus', value: 'plus'},\n {label: 'Premium', value: 'premium'},\n] as const\n\nexport const SUPPORTED_MUX_LANGUAGES_VALUES = SUPPORTED_MUX_LANGUAGES.map((l) => l.code)\n\nexport type SupportedMuxLanguage = (typeof SUPPORTED_MUX_LANGUAGES_VALUES)[number]\n\nexport interface TextTrack {\n _id: string\n name: string\n}\n\nexport interface AutogeneratedTextTrack extends TextTrack {\n type: 'autogenerated'\n language_code: SupportedMuxLanguage\n}\n\nexport interface CustomTextTrack extends TextTrack {\n type: 'subtitles' | 'captions'\n language_code: string\n file: {\n contents: string\n type: string\n name: string\n size: number\n }\n}\n\nexport function isCustomTextTrack(track: Partial<UploadTextTrack>): track is CustomTextTrack {\n return track.type !== 'autogenerated'\n}\n\nexport function isAutogeneratedTrack(\n track: Partial<UploadTextTrack>\n): track is AutogeneratedTextTrack {\n return track.type === 'autogenerated'\n}\n\nexport type UploadTextTrack = AutogeneratedTextTrack | CustomTextTrack\n\n/**\n * Watermark configuration for UI (draggable position)\n */\nexport interface WatermarkConfig {\n enabled: boolean\n imageUrl?: string\n /**\n * Aspect ratio (width / height) of the watermark image.\n * Used to convert between our center-based UI coords and Mux overlay margins.\n */\n imageAspectRatio?: number\n /**\n * Optional explicit Mux `overlay_settings`.\n * When set, these values should be used as-is for the upload request and preview.\n * @see {@link https://www.mux.com/docs/guides/add-watermarks-to-your-videos}\n */\n overlay_settings?: MuxOverlaySettings\n position?: {\n x: number // percentage (0-100)\n y: number // percentage (0-100)\n }\n size?: number // percentage of video width (0-100)\n opacity?: number // 0-1 (converted to percentage string for Mux API)\n}\n\n/**\n * Mux overlay_settings format for watermark API\n * @see {@link https://www.mux.com/docs/guides/add-watermarks-to-your-videos}\n */\nexport interface MuxOverlaySettings {\n vertical_align: 'top' | 'middle' | 'bottom'\n vertical_margin: string // percentage (e.g., \"10%\") or pixels (e.g., \"40px\")\n horizontal_align: 'left' | 'center' | 'right'\n horizontal_margin: string // percentage (e.g., \"10%\") or pixels (e.g., \"40px\")\n width?: string // percentage (e.g., \"25%\") or pixels (e.g., \"80px\")\n height?: string // percentage or pixels\n opacity?: string // percentage string (e.g., \"90%\")\n}\n\nexport interface UploadConfig\n extends Pick<MuxInputConfig, 'max_resolution_tier' | 'normalize_audio' | 'video_quality'> {\n static_renditions: StaticRenditionResolution[]\n text_tracks: UploadTextTrack[]\n signed_policy: boolean\n public_policy: boolean\n watermark?: WatermarkConfig\n drm_policy: boolean\n}\n\n/**\n * Data sent to Mux to create a new asset.\n * @docs {@link https://docs.mux.com/api-reference#video/operation/create-direct-upload}\n */\nexport interface MuxNewAssetSettings\n extends Pick<MuxInputConfig, 'max_resolution_tier' | 'normalize_audio' | 'video_quality'> {\n /** Static renditions configuration for downloadable files */\n static_renditions?: {resolution: StaticRenditionResolution}[]\n /** An array of objects that each describe an input file to be used to create the asset.*/\n input?: {\n /** The URL of the file that Mux should download and use. */\n url?: string\n /** Generate subtitle tracks using automatic speech recognition with this configuration. This may only be provided for the first input object (the main input file). */\n generated_subtitles?: {\n /** A name for this subtitle track. */\n name: string\n /** Arbitrary metadata set for the subtitle track. Max 255 characters. */\n passthrough?: string\n /** The language to generate subtitles in. */\n language_code: SupportedMuxLanguage\n }[]\n /** The time offset in seconds from the beginning of the video indicating the clip's starting marker. */\n start_time?: number\n /** The time offset in seconds from the beginning of the video indicating the clip's ending marker. */\n end_time?: number\n /** This parameter is required for text type tracks. */\n type?: 'video' | 'audio' | 'text'\n /** Type of text track. This parameter only supports subtitles value. */\n text_type?: 'subtitles'\n /** The language code value must be a valid BCP 47 specification compliant value. */\n language_code?: string\n /** The name of the track containing a human-readable description. This value must be unique within each group of text or audio track types. */\n name?: string\n /** Indicates the track provides Subtitles for the Deaf or Hard-of-hearing (SDH). */\n closed_captions?: boolean\n /** This optional parameter should be used tracks with type of text and text_type set to subtitles. */\n passthrough?: string\n /** Overlay settings for watermarks. Used when adding a watermark image as a second input. */\n overlay_settings?: MuxOverlaySettings\n }[]\n\n /** An array of playback policy names that you want applied to this asset and available through playback_ids. */\n playback_policy?: PlaybackPolicy[]\n\n /** An array of playback policy objects that you want applied to this asset and available through playback_ids. advanced_playback_policies must be used instead of playback_policies when creating a DRM playback ID. */\n advanced_playback_policies: AdvancedPlaybackPolicy[]\n\n /** Arbitrary user-supplied metadata that will be included in the asset details and related webhooks. */\n passthrough?: string\n}\n\n/** Used by advanced_playback_policies, allows to define DRM config. */\nexport type AdvancedPlaybackPolicy = {\n policy: PlaybackPolicy\n drm_configuration_id?: string\n}\n\nexport interface Secrets {\n token: string | null\n secretKey: string | null\n enableSignedUrls: boolean\n signingKeyId: string | null\n signingKeyPrivate: string | null\n drmConfigId: string | null\n}\n\n// This narrowed type indicates that there may be assets that are signed, and we have the secrets to access them\n// enabledSignedUrls might be false but that's only relevant for future uploads and their playback policy\nexport interface SignableSecrets extends Omit<Secrets, 'signingKeyId' | 'signingKeyPrivate'> {\n signingKeyId: string\n signingKeyPrivate: string\n}\n\nexport type MuxImageOrigin = `https://image.mux.com`\nexport type MuxThumbnailUrl = `${MuxImageOrigin}/${string}/thumbnail.png?${string}`\nexport type MuxAnimatedThumbnailUrl = `${MuxImageOrigin}/${string}/animated.gif?${string}`\nexport type MuxStoryboardUrl = `${MuxImageOrigin}/${string}/storyboard.vtt?${string}`\nexport type MuxVideoOrigin = `https://stream.mux.com`\nexport type MuxVideoUrl = `${MuxVideoOrigin}/${string}.m3u8?${string}`\nexport type MuxApiUrl = MuxThumbnailUrl | MuxAnimatedThumbnailUrl | MuxStoryboardUrl | MuxVideoUrl\n\n// 'preserve' by default\n// @url: https://docs.mux.com/guides/video/get-images-from-a-video#thumbnail-query-string-parameters\nexport type FitMode = 'preserve' | 'crop' | 'smartcrop' | 'pad'\n\nexport interface ThumbnailOptions {\n fit_mode?: FitMode\n height?: number\n time?: number\n width?: number\n}\n\nexport interface AnimatedThumbnailOptions {\n // Starting time code for the animation, if no end is set it'll have a 5s duration\n // The start and end timecodes uses `asset.thumbTime` to create an iOS `Live Photo` effect by showing you the 5 secodnds before, and after, the thumb time`\n start?: number\n // End code, can't be longer than 10s after the start code\n end?: number\n // Max 640px, 320px by default\n width?: number\n // Preserves aspect ratio, like width, you can't set both the height and width, max 640\n height?: number\n // The fps is 15 by default, but can go up to 30\n fps?: number\n}\n\nexport interface AssetThumbnailOptions {\n asset: Pick<VideoAssetDocument, 'playbackId' | 'data' | 'thumbTime' | 'filename' | 'assetId'>\n}\n\nexport type PlaybackPolicy = 'signed' | 'public' | 'drm'\n\nexport interface MuxErrors {\n type: string\n messages: string[]\n}\n\nexport interface MuxPlaybackId {\n id: string\n policy: PlaybackPolicy\n}\n\nexport interface MuxVideoTrack {\n type: 'video'\n id: string\n max_width: number\n max_height: number\n // if the fps can't be reliably determined, this will be -1\n max_frame_rate: -1 | number\n // top-level duration is always set, while track level duration is not\n duration?: number\n}\nexport interface MuxAudioTrack {\n type: 'audio'\n id: string\n duration?: number\n max_channels: number\n max_channel_layout: 'stereo' | string\n}\nexport interface MuxTextTrack {\n type: 'text'\n id: string\n text_type?: 'subtitles'\n // https://docs.mux.com/api-reference/video#operation/list-assets:~:text=text%20type%20tracks.-,tracks%5B%5D.,text_source,-string\n text_source?:\n | 'uploaded'\n | 'embedded'\n | 'generated_live'\n | 'generated_live_final'\n | 'generated_vod'\n // BCP 47 language code\n language_code?: 'en' | 'en-US' | string\n // The name of the track containing a human-readable description. The hls manifest will associate a subtitle text track with this value\n name?: 'English' | string\n closed_captions?: boolean\n // Max 255 characters\n passthrough?: string\n status: 'preparing' | 'ready' | 'errored'\n error?: {\n type: string\n messages?: string[]\n }\n}\nexport type MuxTrack = MuxVideoTrack | MuxAudioTrack | MuxTextTrack\n// Typings lifted from https://docs.mux.com/api-reference/video#tag/assets\nexport interface MuxAsset {\n id: string\n /** In seconds (instead of JS's default milliseconds) */\n created_at: string\n status: 'preparing' | 'ready' | 'errored'\n duration: number\n max_stored_resolution: 'Audio only' | 'SD' | 'HD' | 'FHD' | 'UHD'\n // if the fps can't be reliably determined, this will be -1\n max_stored_frame_rate: -1 | number\n // The aspect ratio of the asset in the form of width:height, for example 16:9\n aspect_ratio: `${number}:${number}`\n playback_ids: MuxPlaybackId[]\n tracks: MuxTrack[]\n errors?: MuxErrors\n upload_id: string\n is_live?: boolean\n // We use passthrough to set the mux.videoAsset._id of the asset that originally uploaded the video\n passthrough: string\n live_stream_id?: string\n master?: {\n status: 'ready' | 'preparing' | 'errored'\n // Temporary URL to master MP4, expires after 24 hours\n url: string\n }\n master_access: 'temporary' | 'none'\n mp4_support: 'standard' | 'none'\n // Asset Identifier of the video used as the source for creating the clip.\n source_asset_id?: string\n // Normalize the audio track loudness level. This parameter is only applicable to on-demand (not live) assets., default false\n normalize_audio?: boolean\n // The object does not exist if no static renditions have been requested\n static_renditions?: {\n status: 'ready' | 'preparing' | 'disabled' | 'errored'\n files: {\n name: string\n ext: 'mp4' | 'm4a'\n height: number\n width: number\n bitrate: number\n filesize: string\n type: 'standard' | 'advanced'\n status: 'ready' | 'preparing' | 'skipped' | 'errored'\n resolution_tier?: string\n resolution?: string\n id: string\n passthrough?: string\n }[]\n }\n recording_times?: {\n started_at: string\n duration: number\n type: 'content' | 'slate'\n }[]\n // https://docs.mux.com/guides/video/minimize-processing-time\n non_standard_input_reasons?: {\n video_codec?: string\n audio_codec?: string\n video_gop_size?: 'high'\n video_frame_rate?: string\n video_resolution?: string\n video_bitrate?: 'high'\n pixel_aspect_ratio?: string\n video_edit_list?: 'non-standard'\n audio_edit_list?: 'non-standard'\n unexpected_media_file_parameters?: 'non-standard'\n test?: boolean\n }\n meta?: {\n title?: string\n }\n}\n\nexport interface VideoAssetDocument {\n _id: string\n _type: 'mux.videoAsset'\n _createdAt: string\n _updatedAt?: string\n status?: string\n assetId?: string\n playbackId?: string\n filename?: string\n thumbTime?: number\n // Docs for what goes in `data` https://docs.mux.com/api-reference/video#tag/assets\n data?: PartialDeep<MuxAsset>\n}\n\nexport type Reference = {_type: 'reference'; _ref: string}\n\n// @TODO add Reference, and ReferenceSchemaType in the generic\nexport type MuxInputProps = ObjectInputProps<{\n asset?: Reference\n}>\n\nexport interface MuxInputPreviewProps extends Omit<PreviewProps<PreviewLayoutKey>, 'value'> {\n schemaType: SchemaType\n value?: {\n asset?: Reference\n } | null\n}\n\n/** Whether the VideosBrowser was opened from a field in a document, or from the standalone studio tool */\nexport type PluginPlacement = 'input' | 'tool'\n","import {TranslateIcon, UploadIcon} from '@sanity/icons'\nimport {\n Autocomplete,\n Button,\n Card,\n Checkbox,\n Dialog,\n Flex,\n Label,\n Spinner,\n Stack,\n Text,\n TextInput,\n useToast,\n} from '@sanity/ui'\nimport LanguagesList from 'iso-639-1'\nimport {useId, useRef, useState} from 'react'\n\nimport {addTextTrackFromUrl, generateSubtitles, getAsset} from '../actions/assets'\nimport {useClient} from '../hooks/useClient'\nimport {extractErrorMessage, pollTrackStatus} from '../util/textTracks'\nimport {type MuxTextTrack, SUPPORTED_MUX_LANGUAGES, type VideoAssetDocument} from '../util/types'\n\nconst LANGUAGE_OPTIONS = LanguagesList.getAllCodes().map((code) => ({\n value: code,\n label: LanguagesList.getNativeName(code),\n}))\n\nconst MUX_LANGUAGE_OPTIONS = SUPPORTED_MUX_LANGUAGES.map((lang) => ({\n value: lang.code,\n label: lang.label,\n}))\n\nexport interface Props {\n asset: VideoAssetDocument\n onAdd: (track: MuxTextTrack) => void\n onClose: () => void\n}\n\nexport default function AddCaptionDialog({asset, onAdd, onClose}: Props) {\n const client = useClient()\n const toast = useToast()\n const dialogId = `AddCaptionDialog${useId()}`\n\n const [isAutogenerated, setIsAutogenerated] = useState(false)\n const [vttUrl, setVttUrl] = useState('')\n const [languageCode, setLanguageCode] = useState('')\n const [selectedLanguage, setSelectedLanguage] = useState<{value: string; label: string} | null>(\n null\n )\n const [name, setName] = useState('')\n const [isSubmitting, setIsSubmitting] = useState(false)\n const [selectedFile, setSelectedFile] = useState<File | null>(null)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const uploadVttFile = async (file: File): Promise<string> => {\n const assetDocument = await client.assets.upload('file', file, {\n filename: file.name,\n })\n return assetDocument.url\n }\n\n const handleAddTrackFromUrl = async () => {\n if (!asset.assetId) {\n throw new Error('Asset ID is required')\n }\n\n const trimmedName = name.trim()\n const trimmedLanguageCode = languageCode.trim()\n\n let vttUrlToUse = vttUrl.trim()\n\n if (selectedFile) {\n try {\n vttUrlToUse = await uploadVttFile(selectedFile)\n } catch (uploadError) {\n toast.push({\n title: 'Failed to upload VTT file',\n status: 'error',\n description: 'Could not upload the VTT file to Sanity. Please try again.',\n })\n setIsSubmitting(false)\n throw uploadError\n }\n }\n\n await addTextTrackFromUrl(client, asset.assetId, vttUrlToUse, {\n language_code: trimmedLanguageCode,\n name: trimmedName,\n text_type: 'subtitles',\n })\n\n const result = await pollTrackStatus({\n client,\n assetId: asset.assetId,\n trackName: trimmedName,\n trackLanguageCode: trimmedLanguageCode,\n onTrackErrored: (track) => {\n const errorMessage =\n track.error?.messages?.[0] ||\n track.error?.type ||\n 'The track failed to download from the provided URL'\n toast.push({\n title: 'Caption track failed',\n status: 'error',\n description: errorMessage,\n })\n onAdd(track)\n onClose()\n },\n })\n\n if (!result.found || !result.track) {\n toast.push({\n title: 'Caption track may have been added',\n status: 'warning',\n description:\n 'The track was created but its status could not be determined. It may still be processing. Please refresh the page to see if it appears.',\n })\n onClose()\n return\n }\n\n if (result.status === 'errored') {\n return\n }\n\n if (result.status === 'preparing') {\n toast.push({\n title: 'Caption track is processing',\n status: 'info',\n description:\n 'The track was created and is being processed. It will appear in the list shortly.',\n })\n onAdd(result.track)\n onClose()\n return\n }\n\n toast.push({\n title: 'Caption track added',\n status: 'success',\n description: 'Caption track added successfully',\n })\n\n onAdd(result.track)\n onClose()\n }\n\n const handleGenerateSubtitles = async () => {\n if (!asset.assetId) {\n throw new Error('Asset ID is required')\n }\n\n const assetData = await getAsset(client, asset.assetId)\n const audioTrack = assetData.data.tracks?.find((track) => track.type === 'audio')\n\n if (!audioTrack || !audioTrack.id) {\n toast.push({\n title: 'No audio track found',\n status: 'error',\n description:\n 'The asset does not have an audio track. Auto-generated subtitles require an audio track.',\n })\n throw new Error('No audio track found')\n }\n\n await generateSubtitles(client, asset.assetId, audioTrack.id, {\n language_code: languageCode.trim(),\n name: name.trim(),\n })\n\n const mockTrackId = `generating-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`\n const mockTrack: MuxTextTrack = {\n type: 'text',\n id: mockTrackId,\n text_type: 'subtitles',\n text_source: 'generated_live',\n language_code: languageCode.trim(),\n name: name.trim(),\n status: 'preparing',\n }\n\n toast.push({\n title: 'Generating subtitles',\n status: 'success',\n description: 'This may take a few minutes',\n })\n\n onAdd(mockTrack)\n onClose()\n }\n\n const handleSubmit = async () => {\n if (!isAutogenerated) {\n if (!selectedFile && !vttUrl.trim()) {\n toast.push({\n title: 'VTT file or URL required',\n status: 'error',\n description: 'Please select a VTT file or enter a VTT file URL',\n })\n return\n }\n\n if (vttUrl.trim() && !selectedFile) {\n try {\n void new URL(vttUrl.trim())\n } catch {\n toast.push({\n title: 'Invalid URL',\n status: 'error',\n description: 'Please enter a valid URL (e.g., https://example.com/subtitles.vtt)',\n })\n return\n }\n }\n }\n\n if (!name.trim()) {\n toast.push({\n title: 'Audio name required',\n status: 'error',\n description: 'Please enter an audio name for this caption track',\n })\n return\n }\n\n if (!languageCode.trim()) {\n toast.push({\n title: 'Language code required',\n status: 'error',\n description: 'Please enter a language code (e.g., en, es, fr)',\n })\n return\n }\n\n setIsSubmitting(true)\n\n try {\n if (isAutogenerated) {\n await handleGenerateSubtitles()\n } else {\n await handleAddTrackFromUrl()\n }\n } catch (error) {\n toast.push({\n title: 'Failed to add caption track',\n status: 'error',\n description: extractErrorMessage(error, 'Failed to add caption track'),\n })\n } finally {\n setIsSubmitting(false)\n }\n }\n\n return (\n <Dialog\n id={dialogId}\n header=\"Add Caption Track\"\n onClose={onClose}\n width={1}\n onClickOutside={onClose}\n >\n <Stack padding={4} space={4}>\n <Stack space={2}>\n <Flex align=\"center\" marginBottom={3}>\n <Checkbox\n id=\"autogenerated-checkbox\"\n style={{display: 'block'}}\n checked={isAutogenerated}\n onChange={(e) => {\n setIsAutogenerated(e.currentTarget.checked)\n if (e.currentTarget.checked) {\n setVttUrl('')\n }\n }}\n disabled={isSubmitting}\n />\n <Flex flex={1} paddingLeft={2}>\n <Text>\n <label htmlFor=\"autogenerated-checkbox\">Generate captions</label>\n </Text>\n </Flex>\n </Flex>\n {!isAutogenerated && (\n <Stack space={2}>\n <Card padding={3} marginBottom={2} tone=\"transparent\" border radius={2}>\n <Flex align=\"center\" justify=\"space-between\">\n <Text size={1} muted>\n {selectedFile ? `Selected: ${selectedFile.name}` : 'No file selected'}\n </Text>\n <Button\n icon={UploadIcon}\n text=\"Select File\"\n mode=\"ghost\"\n tone=\"primary\"\n fontSize={1}\n padding={2}\n onClick={() => fileInputRef.current?.click()}\n disabled={isSubmitting}\n />\n </Flex>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".vtt,text/vtt\"\n style={{display: 'none'}}\n onChange={(e) => {\n if (e.target.files && e.target.files.length > 0 && !isSubmitting) {\n setSelectedFile(e.target.files[0])\n setVttUrl('')\n }\n }}\n />\n </Card>\n <Text size={1} muted style={{textAlign: 'center'}}>\n Or enter the VTT file URL\n </Text>\n <Stack space={2}>\n <Label htmlFor=\"vtt-url\">VTT File URL</Label>\n <TextInput\n id=\"vtt-url\"\n placeholder=\"https://example.com/subtitles.vtt\"\n value={vttUrl}\n onChange={(e) => {\n setVttUrl(e.currentTarget.value)\n setSelectedFile(null)\n }}\n disabled={isSubmitting}\n />\n </Stack>\n </Stack>\n )}\n </Stack>\n\n <Stack space={2}>\n <Label htmlFor=\"caption-name\">Audio name</Label>\n <Autocomplete\n id=\"caption-name\"\n value={selectedLanguage?.value || ''}\n onChange={(newValue) => {\n const options = isAutogenerated ? MUX_LANGUAGE_OPTIONS : LANGUAGE_OPTIONS\n const selected = options.find((opt) => opt.value === newValue)\n if (selected) {\n setSelectedLanguage(selected)\n setLanguageCode(selected.value)\n setName(selected.label)\n }\n }}\n options={isAutogenerated ? MUX_LANGUAGE_OPTIONS : LANGUAGE_OPTIONS}\n icon={TranslateIcon}\n placeholder=\"Select language\"\n filterOption={(query, option) =>\n option.label.toLowerCase().indexOf(query.toLowerCase()) > -1 ||\n option.value.toLowerCase().indexOf(query.toLowerCase()) > -1\n }\n openButton\n renderValue={(value) =>\n (isAutogenerated ? MUX_LANGUAGE_OPTIONS : LANGUAGE_OPTIONS).find(\n (l) => l.value === value\n )?.label || value\n }\n renderOption={(option) => (\n <Card data-as=\"button\" padding={3} radius={2} tone=\"inherit\">\n <Text size={2} textOverflow=\"ellipsis\">\n {option.label} ({option.value})\n </Text>\n </Card>\n )}\n disabled={isSubmitting}\n />\n </Stack>\n\n <Stack space={2}>\n <Label htmlFor=\"caption-language\">Language Code</Label>\n <TextInput\n id=\"caption-language\"\n placeholder=\"en-US\"\n value={languageCode}\n onChange={(e) => {\n setLanguageCode(e.currentTarget.value)\n if (selectedLanguage && selectedLanguage.value !== e.currentTarget.value) {\n setSelectedLanguage(null)\n if (!name || name === selectedLanguage.label) {\n setName('')\n }\n }\n }}\n disabled={isSubmitting}\n />\n </Stack>\n\n <Flex gap={2} justify=\"flex-end\" marginTop={2}>\n <Button text=\"Cancel\" mode=\"ghost\" onClick={onClose} disabled={isSubmitting} />\n <Button\n text=\"Add Caption Track\"\n tone=\"primary\"\n icon={\n isSubmitting ? (\n <Spinner\n style={{\n verticalAlign: 'middle',\n display: 'inline-block',\n marginBottom: '-3px',\n width: '1em',\n height: '1em',\n marginRight: '-6px',\n }}\n />\n ) : (\n <UploadIcon />\n )\n }\n onClick={handleSubmit}\n disabled={isSubmitting}\n />\n </Flex>\n </Stack>\n </Dialog>\n )\n}\n","import {DownloadIcon, TranslateIcon, UploadIcon} from '@sanity/icons'\nimport {\n Autocomplete,\n Button,\n Card,\n Dialog,\n Flex,\n Label,\n Spinner,\n Stack,\n Text,\n TextInput,\n useToast,\n} from '@sanity/ui'\nimport LanguagesList from 'iso-639-1'\nimport {useEffect, useId, useRef, useState} from 'react'\n\nimport {addTextTrackFromUrl, deleteTextTrack, getAsset} from '../actions/assets'\nimport {useClient} from '../hooks/useClient'\nimport {generateJwt} from '../util/generateJwt'\nimport {getPlaybackId} from '../util/getPlaybackPolicy'\nimport {getPlaybackPolicy} from '../util/getPlaybackPolicy'\nimport {downloadVttFile, extractErrorMessage, pollTrackStatus} from '../util/textTracks'\nimport type {MuxTextTrack, VideoAssetDocument} from '../util/types'\n\nconst LANGUAGE_OPTIONS = LanguagesList.getAllCodes().map((code) => ({\n value: code,\n label: LanguagesList.getNativeName(code),\n}))\n\nexport interface Props {\n asset: VideoAssetDocument\n track: MuxTextTrack\n onUpdate: (track: MuxTextTrack, oldTrackId?: string) => void\n onClose: () => void\n}\n\nexport default function EditCaptionDialog({asset, track, onUpdate, onClose}: Props) {\n const client = useClient()\n const toast = useToast()\n const dialogId = `EditCaptionDialog${useId()}`\n\n const isAutogenerated =\n track.text_source === 'generated_live' ||\n track.text_source === 'generated_live_final' ||\n track.text_source === 'generated_vod'\n\n const [vttUrl, setVttUrl] = useState('')\n const [languageCode, setLanguageCode] = useState(track.language_code || '')\n const [selectedLanguage, setSelectedLanguage] = useState<{value: string; label: string} | null>(\n () => {\n const baseCode = track.language_code?.split('-')[0]\n const found = LANGUAGE_OPTIONS.find(\n (opt) => opt.value === track.language_code || opt.value === baseCode\n )\n if (found) return found\n if (track.name) {\n const foundByName = LANGUAGE_OPTIONS.find((opt) => opt.label === track.name)\n if (foundByName) return foundByName\n }\n return null\n }\n )\n const [name, setName] = useState(track.name || '')\n const [isSubmitting, setIsSubmitting] = useState(false)\n const [downloading, setDownloading] = useState(false)\n const [selectedFile, setSelectedFile] = useState<File | null>(null)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n useEffect(() => {\n setLanguageCode(track.language_code || '')\n setName(track.name || '')\n setVttUrl('')\n const baseCode = track.language_code?.split('-')[0]\n const foundByCode = LANGUAGE_OPTIONS.find(\n (opt) => opt.value === track.language_code || opt.value === baseCode\n )\n const foundByName = track.name ? LANGUAGE_OPTIONS.find((opt) => opt.label === track.name) : null\n setSelectedLanguage(foundByCode || foundByName || null)\n }, [track, asset, client])\n\n const handleDownloadCurrentFile = async () => {\n setDownloading(true)\n try {\n await downloadVttFile(client, asset, track)\n } catch (error) {\n let errorMessage = 'Please try again'\n let title = 'Failed to download VTT file'\n\n if (error instanceof Error) {\n errorMessage = error.message\n if (error.message.includes('Track')) {\n title = 'Cannot download'\n }\n } else if (error === 'Track ID is missing' || error === 'Track is not ready yet') {\n errorMessage = String(error)\n title = 'Cannot download'\n }\n\n toast.push({\n title,\n status: 'error',\n description: errorMessage,\n })\n } finally {\n setDownloading(false)\n }\n }\n\n const getCurrentFileName = () => {\n if (track.id && asset.filename) {\n return `${asset.filename}-${track.language_code || 'en'}.vtt`\n }\n return `captions-${track.language_code || 'en'}.vtt`\n }\n\n const uploadVttFile = async (file: File): Promise<string> => {\n const assetDocument = await client.assets.upload('file', file, {\n filename: file.name,\n })\n return assetDocument.url\n }\n\n const refreshAssetData = async () => {\n if (!asset._id || !asset.assetId) return\n try {\n const latestAssetData = await getAsset(client, asset.assetId)\n await client\n .patch(asset._id)\n .set({data: latestAssetData.data, status: latestAssetData.data.status})\n .commit()\n } catch (refreshError) {\n console.error('Failed to refresh asset data:', refreshError)\n }\n }\n\n const handleUpdateTrackWithNewUrl = async () => {\n if (!asset.assetId) {\n throw new Error('Asset ID is required')\n }\n\n const trimmedName = name.trim()\n const trimmedLanguageCode = languageCode.trim()\n\n const oldTrackId = track.id\n\n try {\n await deleteTextTrack(client, asset.assetId, oldTrackId)\n } catch (deleteError) {\n toast.push({\n title: 'Failed to delete old track',\n status: 'error',\n description: 'Could not delete the old track. Please try again or delete it manually.',\n })\n setIsSubmitting(false)\n throw deleteError\n }\n\n let vttUrlToUse = vttUrl.trim()\n\n if (selectedFile) {\n try {\n vttUrlToUse = await uploadVttFile(selectedFile)\n } catch (uploadError) {\n toast.push({\n title: 'Failed to upload VTT file',\n status: 'error',\n description: 'Could not upload the VTT file to Sanity. Please try again.',\n })\n setIsSubmitting(false)\n throw uploadError\n }\n }\n\n try {\n await addTextTrackFromUrl(client, asset.assetId, vttUrlToUse, {\n language_code: trimmedLanguageCode,\n name: trimmedName,\n text_type: 'subtitles',\n })\n } catch (error: unknown) {\n toast.push({\n title: 'Failed to update caption track',\n status: 'error',\n description: extractErrorMessage(error, 'Failed to update caption track'),\n })\n setIsSubmitting(false)\n throw error\n }\n\n const result = await pollTrackStatus({\n client,\n assetId: asset.assetId,\n trackName: trimmedName,\n trackLanguageCode: trimmedLanguageCode,\n onTrackErrored: async (erroredTrack) => {\n const errorMessage =\n erroredTrack.error?.messages?.[0] ||\n erroredTrack.error?.type ||\n 'The track failed to download from the provided URL'\n toast.push({\n title: 'Caption track failed',\n status: 'error',\n description: errorMessage,\n })\n await refreshAssetData()\n onUpdate(erroredTrack, oldTrackId)\n setIsSubmitting(false)\n },\n })\n\n if (!result.found || !result.track) {\n toast.push({\n title: 'Caption track may have been updated',\n status: 'warning',\n description:\n 'The track was updated but its status could not be determined. It may still be processing. Please refresh the page to see if it appears.',\n })\n setIsSubmitting(false)\n return\n }\n\n if (result.status === 'errored') {\n return\n }\n\n await refreshAssetData()\n\n if (result.status === 'preparing') {\n toast.push({\n title: 'Caption track is processing',\n status: 'info',\n description:\n 'The track was updated and is being processed. It will appear in the list shortly.',\n })\n } else {\n toast.push({\n title: 'Caption track updated',\n status: 'success',\n description: 'Caption track updated successfully',\n })\n }\n\n onUpdate(result.track, oldTrackId)\n setIsSubmitting(false)\n }\n\n const handleSubmit = async () => {\n if (!name.trim()) {\n toast.push({\n title: 'Audio name required',\n status: 'error',\n description: 'Please enter an audio name for this caption track',\n })\n return\n }\n\n if (!languageCode.trim()) {\n toast.push({\n title: 'Language code required',\n status: 'error',\n description: 'Please enter a language code (e.g., en, es, fr)',\n })\n return\n }\n\n setIsSubmitting(true)\n\n try {\n if (!asset.assetId) {\n throw new Error('Asset ID is required')\n }\n\n const originalVttUrl = (() => {\n if (isAutogenerated || !track.id) return ''\n const playbackId = getPlaybackId(asset)\n if (!playbackId) return ''\n let url = `https://stream.mux.com/${playbackId}/text/${track.id}.vtt`\n if (getPlaybackPolicy(asset)?.policy === 'signed') {\n const token = generateJwt(client, playbackId, 'v')\n url += `?token=${token}`\n }\n return url\n })()\n\n const urlChanged =\n selectedFile !== null || (vttUrl.trim() && vttUrl.trim() !== originalVttUrl)\n\n if (!urlChanged) {\n toast.push({\n title: 'No changes',\n status: 'info',\n description:\n 'Please provide a new VTT file or URL using the \"Replace\" button or URL field to update the track.',\n })\n setIsSubmitting(false)\n return\n }\n\n if (urlChanged) {\n if (!selectedFile && vttUrl.trim()) {\n try {\n void new URL(vttUrl.trim())\n } catch {\n toast.push({\n title: 'Invalid URL',\n status: 'error',\n description: 'Please enter a valid URL (e.g., https://example.com/subtitles.vtt)',\n })\n setIsSubmitting(false)\n return\n }\n }\n\n if (!selectedFile && !vttUrl.trim()) {\n toast.push({\n title: 'VTT file or URL required',\n status: 'error',\n description: 'Please select a VTT file or enter a VTT file URL',\n })\n setIsSubmitting(false)\n return\n }\n\n await handleUpdateTrackWithNewUrl()\n }\n\n onClose()\n } catch (error) {\n toast.push({\n title: 'Failed to update caption track',\n status: 'error',\n description: error instanceof Error ? error.message : 'Please try again',\n })\n } finally {\n setIsSubmitting(false)\n }\n }\n\n return (\n <Dialog\n id={dialogId}\n header=\"Edit Caption Track\"\n onClose={onClose}\n width={1}\n onClickOutside={onClose}\n >\n <Stack padding={4} space={4}>\n <Stack space={2}>\n <Card padding={3} marginBottom={2} tone=\"transparent\" border radius={2}>\n <Flex align=\"center\" justify=\"space-between\">\n <Text>{getCurrentFileName()}</Text>\n <Flex gap={2}>\n {track.status !== 'errored' && (\n <Button\n icon={\n downloading ? (\n <Spinner\n style={{\n verticalAlign: 'middle',\n display: 'inline-block',\n marginTop: '-2px',\n width: '0.5em',\n height: '0.5em',\n }}\n />\n ) : (\n <DownloadIcon />\n )\n }\n text=\"Download\"\n mode=\"ghost\"\n tone=\"primary\"\n fontSize={1}\n padding={2}\n onClick={handleDownloadCurrentFile}\n disabled={downloading || isSubmitting}\n />\n )}\n <Button\n icon={UploadIcon}\n text=\"Replace\"\n mode=\"ghost\"\n tone=\"primary\"\n fontSize={1}\n padding={2}\n onClick={() => fileInputRef.current?.click()}\n disabled={isSubmitting}\n />\n </Flex>\n </Flex>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".vtt,text/vtt\"\n style={{display: 'none'}}\n onChange={(e) => {\n if (e.target.files && e.target.files.length > 0 && !isSubmitting) {\n setSelectedFile(e.target.files[0])\n setVttUrl('')\n }\n }}\n />\n {selectedFile && (\n <Text size={1} muted style={{marginTop: 8}}>\n Selected: {selectedFile.name}\n </Text>\n )}\n </Card>\n <Stack space={2}>\n <Label htmlFor=\"vtt-url\">VTT File URL</Label>\n <TextInput\n id=\"vtt-url\"\n placeholder=\"https://example.com/subtitles.vtt\"\n value={vttUrl}\n onChange={(e) => {\n setVttUrl(e.currentTarget.value)\n setSelectedFile(null)\n }}\n disabled={isSubmitting}\n />\n <Text size={1} muted>\n Add a URL to replace the existing VTT file with a new one\n </Text>\n </Stack>\n </Stack>\n\n <Stack space={2}>\n <Label htmlFor=\"caption-name\">Audio name</Label>\n <Autocomplete\n id=\"caption-name\"\n value={selectedLanguage?.value || ''}\n onChange={(newValue) => {\n const selected = LANGUAGE_OPTIONS.find((opt) => opt.value === newValue)\n if (selected) {\n setSelectedLanguage(selected)\n setLanguageCode(selected.value)\n setName(selected.label)\n }\n }}\n options={LANGUAGE_OPTIONS}\n icon={TranslateIcon}\n placeholder=\"Select language\"\n filterOption={(query, option) =>\n option.label.toLowerCase().indexOf(query.toLowerCase()) > -1 ||\n option.value.toLowerCase().indexOf(query.toLowerCase()) > -1\n }\n openButton\n renderValue={(value) => LANGUAGE_OPTIONS.find((l) => l.value === value)?.label || value}\n renderOption={(option) => (\n <Card data-as=\"button\" padding={3} radius={2} tone=\"inherit\">\n <Text size={2} textOverflow=\"ellipsis\">\n {option.label} ({option.value})\n </Text>\n </Card>\n )}\n disabled={isSubmitting}\n />\n </Stack>\n\n <Stack space={2}>\n <Label htmlFor=\"caption-language\">Language Code</Label>\n <TextInput\n id=\"caption-language\"\n placeholder=\"en-US\"\n value={languageCode}\n onChange={(e) => {\n setLanguageCode(e.currentTarget.value)\n if (selectedLanguage && selectedLanguage.value !== e.currentTarget.value) {\n setSelectedLanguage(null)\n if (!name || name === selectedLanguage.label) {\n setName('')\n }\n }\n }}\n disabled={isSubmitting}\n />\n </Stack>\n\n <Flex gap={2} justify=\"flex-end\" marginTop={2}>\n <Button text=\"Cancel\" mode=\"ghost\" onClick={onClose} disabled={isSubmitting} />\n <Button\n text=\"Update Caption Track\"\n tone=\"primary\"\n icon={\n isSubmitting ? (\n <Spinner\n style={{\n verticalAlign: 'middle',\n display: 'inline-block',\n marginBottom: '-3px',\n width: '1em',\n height: '1em',\n marginRight: '-6px',\n }}\n />\n ) : (\n UploadIcon\n )\n }\n onClick={handleSubmit}\n disabled={isSubmitting}\n />\n </Flex>\n </Stack>\n </Dialog>\n )\n}\n","import {\n AddIcon,\n ChevronDownIcon,\n ChevronUpIcon,\n DownloadIcon,\n EditIcon,\n ErrorOutlineIcon,\n TrashIcon,\n} from '@sanity/icons'\nimport {Box, Button, Card, Dialog, Flex, Heading, Spinner, Stack, Text, useToast} from '@sanity/ui'\nimport {useEffect, useId, useMemo, useState} from 'react'\n\nimport {deleteTextTrack} from '../actions/assets'\nimport {useClient} from '../hooks/useClient'\nimport {useResyncAsset} from '../hooks/useResyncAsset'\nimport {downloadVttFile} from '../util/textTracks'\nimport type {MuxTextTrack, VideoAssetDocument} from '../util/types'\nimport AddCaptionDialog from './AddCaptionDialog'\nimport EditCaptionDialog from './EditCaptionDialog'\n\ninterface TrackCardProps {\n track: MuxTextTrack\n iconOnly: boolean\n downloadingTrackId: string | null\n deletingTrackId: string | null\n trackToEdit: MuxTextTrack | null\n getTrackSourceLabel: (track: MuxTextTrack) => string\n handleDownload: (track: MuxTextTrack) => void\n setTrackToEdit: (track: MuxTextTrack) => void\n setTrackToDelete: (track: MuxTextTrack) => void\n}\n\nfunction TrackCard({\n track,\n iconOnly,\n downloadingTrackId,\n deletingTrackId,\n trackToEdit,\n getTrackSourceLabel,\n handleDownload,\n setTrackToEdit,\n setTrackToDelete,\n}: TrackCardProps) {\n const isDisabled = (action: 'download' | 'edit' | 'delete') => {\n if (action === 'download') {\n return (\n downloadingTrackId !== null || deletingTrackId === track.id || trackToEdit?.id === track.id\n )\n }\n if (action === 'edit') {\n return (\n downloadingTrackId === track.id ||\n deletingTrackId === track.id ||\n trackToEdit?.id === track.id\n )\n }\n return (\n downloadingTrackId === track.id || deletingTrackId !== null || trackToEdit?.id === track.id\n )\n }\n\n const renderActionButtons = () => {\n if (track.status === 'preparing') {\n return (\n <Flex align=\"center\" gap={2}>\n <Spinner\n muted\n style={{\n width: '0.75em',\n height: '0.75em',\n verticalAlign: 'middle',\n display: 'inline-block',\n marginBottom: '-2px',\n }}\n />\n <Text size={1} muted>\n Processing...\n </Text>\n </Flex>\n )\n }\n\n return (\n <Flex gap={2}>\n {track.status !== 'errored' && (\n <Button\n icon={\n downloadingTrackId === track.id ? (\n <Spinner\n style={{\n verticalAlign: 'middle',\n display: 'inline-block',\n marginTop: '-2px',\n width: '0.5em',\n height: '0.5em',\n }}\n />\n ) : (\n <DownloadIcon />\n )\n }\n text={iconOnly ? undefined : 'Download'}\n mode=\"ghost\"\n tone=\"primary\"\n fontSize={1}\n padding={2}\n onClick={() => handleDownload(track)}\n disabled={isDisabled('download')}\n title=\"Download\"\n />\n )}\n <Button\n icon={<EditIcon />}\n text={iconOnly ? undefined : 'Edit'}\n mode=\"ghost\"\n tone=\"primary\"\n fontSize={1}\n padding={2}\n disabled={isDisabled('edit')}\n onClick={() => setTrackToEdit(track)}\n title=\"Edit\"\n />\n <Button\n icon={\n deletingTrackId === track.id ? (\n <Spinner\n style={{\n verticalAlign: 'middle',\n display: 'inline-block',\n marginTop: '-2px',\n width: '0.5em',\n height: '0.5em',\n }}\n />\n ) : (\n <TrashIcon />\n )\n }\n text={iconOnly ? undefined : 'Delete'}\n mode=\"ghost\"\n tone=\"critical\"\n fontSize={1}\n padding={2}\n disabled={isDisabled('delete')}\n onClick={() => setTrackToDelete(track)}\n title=\"Delete\"\n />\n </Flex>\n )\n }\n\n return (\n <Card\n padding={3}\n radius={2}\n tone={track.status === 'errored' ? 'caution' : 'transparent'}\n border\n >\n <Flex align=\"center\" justify=\"space-between\" gap={3}>\n <Stack space={2} flex={1}>\n <Flex align=\"center\" gap={2}>\n <Text weight=\"semibold\">{track.name || 'Untitled'}</Text>\n <Text size={1} muted>\n ({getTrackSourceLabel(track)})\n </Text>\n {track.status === 'errored' && (\n <ErrorOutlineIcon\n style={{color: 'var(--card-critical-color)'}}\n aria-label=\"Error\"\n fontSize={20}\n />\n )}\n </Flex>\n {track.language_code && (\n <Text size={1} muted>\n Language: {track.language_code}\n </Text>\n )}\n {track.status === 'errored' && track.error && (\n <Text size={1} style={{color: 'var(--card-critical-color)'}}>\n {track.error.messages?.[0] || track.error.type || 'Failed to process track'}\n </Text>\n )}\n </Stack>\n {renderActionButtons()}\n </Flex>\n </Card>\n )\n}\n\ninterface TextTracksManagerProps {\n asset: VideoAssetDocument\n iconOnly?: boolean\n tracks?: MuxTextTrack[]\n collapseTracks?: boolean\n}\n\nexport default function TextTracksManager({\n asset,\n iconOnly = false,\n tracks: propTracks,\n collapseTracks = false,\n}: TextTracksManagerProps) {\n const client = useClient()\n const toast = useToast()\n const dialogId = `DeleteCaptionDialog${useId()}`\n const {resyncAsset} = useResyncAsset()\n const [downloadingTrackId, setDownloadingTrackId] = useState<string | null>(null)\n const [deletingTrackId, setDeletingTrackId] = useState<string | null>(null)\n const [addedTracks, setAddedTracks] = useState<MuxTextTrack[]>([])\n const [updatedTracks, setUpdatedTracks] = useState<Map<string, MuxTextTrack>>(new Map())\n const [trackActivityOrder, setTrackActivityOrder] = useState<Map<string, number>>(new Map())\n const [autogeneratedTrackIds, setAutogeneratedTrackIds] = useState<Set<string>>(new Set())\n const [trackToDelete, setTrackToDelete] = useState<MuxTextTrack | null>(null)\n const [trackToEdit, setTrackToEdit] = useState<MuxTextTrack | null>(null)\n const [showAddDialog, setShowAddDialog] = useState(false)\n const [isExpanded, setIsExpanded] = useState(false)\n\n const MAX_VISIBLE_TRACKS = 4\n\n const realTracks: MuxTextTrack[] = propTracks\n ? propTracks\n : asset.data?.tracks?.filter((track): track is MuxTextTrack => track.type === 'text') || []\n\n const activeTracks = realTracks.filter(\n (track) =>\n track.id &&\n (track.status === 'ready' || track.status === 'preparing' || track.status === 'errored')\n )\n\n const allTracks = useMemo(() => {\n const tracksWithUpdates = activeTracks.map((track) => {\n const updated = updatedTracks.get(track.id)\n return updated || track\n })\n\n const isMockTrackReplaced = (mockTrack: MuxTextTrack, realTracksList: MuxTextTrack[]) => {\n if (!mockTrack.id || !mockTrack.id.startsWith('generating-')) {\n return false\n }\n return realTracksList.some((realTrack) => {\n const nameMatches = realTrack.name === mockTrack.name\n const languageMatches = realTrack.language_code === mockTrack.language_code\n if (!nameMatches || !languageMatches) {\n return false\n }\n if (realTrack.status === 'ready') {\n const isGenerated =\n realTrack.text_source === 'generated_live' ||\n realTrack.text_source === 'generated_live_final' ||\n realTrack.text_source === 'generated_vod'\n return isGenerated\n }\n if (realTrack.status === 'preparing') {\n return true\n }\n return false\n })\n }\n\n const isTrackAlreadyInRealTracks = (\n addedTrack: MuxTextTrack,\n realTracksList: MuxTextTrack[]\n ) => {\n if (!addedTrack.id) return false\n if (addedTrack.id.startsWith('generating-')) {\n return isMockTrackReplaced(addedTrack, realTracksList)\n }\n return realTracksList.some((realTrack) => realTrack.id === addedTrack.id)\n }\n\n const tracksToKeep = addedTracks.filter((addedTrack) => {\n if (addedTrack.id && addedTrack.id.startsWith('generating-')) {\n return !isMockTrackReplaced(addedTrack, tracksWithUpdates)\n }\n return !isTrackAlreadyInRealTracks(addedTrack, tracksWithUpdates)\n })\n\n return [...tracksWithUpdates, ...tracksToKeep]\n }, [activeTracks, addedTracks, updatedTracks])\n\n useEffect(() => {\n const newAutogeneratedIds = new Set<string>()\n\n activeTracks.forEach((track) => {\n if (\n track.id &&\n (track.text_source === 'generated_live' ||\n track.text_source === 'generated_live_final' ||\n track.text_source === 'generated_vod')\n ) {\n newAutogeneratedIds.add(track.id)\n }\n })\n\n addedTracks.forEach((mockTrack) => {\n if (mockTrack.id && mockTrack.id.startsWith('generating-')) {\n const realTrack = activeTracks.find((rt) => {\n const nameMatches = rt.name === mockTrack.name\n const languageMatches = rt.language_code === mockTrack.language_code\n return nameMatches && languageMatches\n })\n if (realTrack?.id) {\n newAutogeneratedIds.add(realTrack.id)\n }\n }\n })\n\n setAutogeneratedTrackIds((prev) => {\n let hasNew = false\n const updated = new Set(prev)\n newAutogeneratedIds.forEach((id) => {\n if (!prev.has(id)) {\n updated.add(id)\n hasNew = true\n }\n })\n return hasNew ? updated : prev\n })\n }, [activeTracks, addedTracks])\n\n useEffect(() => {\n const preparingTracks = allTracks.filter((track) => track.status === 'preparing')\n if (preparingTracks.length === 0 || !asset.assetId || !asset._id) {\n return undefined\n }\n\n const interval = setInterval(async () => {\n try {\n const muxData = await resyncAsset(asset)\n if (!muxData) return\n\n const fetchedTracks =\n muxData.tracks?.filter((track): track is MuxTextTrack => track.type === 'text') || []\n\n const isMockTrackReplaced = (\n mockTrack: MuxTextTrack,\n fetchedTracksList: MuxTextTrack[]\n ) => {\n if (!mockTrack.id || !mockTrack.id.startsWith('generating-')) {\n return false\n }\n return fetchedTracksList.some((realTrack) => {\n const nameMatches = realTrack.name === mockTrack.name\n const languageMatches = realTrack.language_code === mockTrack.language_code\n if (!nameMatches || !languageMatches) {\n return false\n }\n if (realTrack.status === 'ready') {\n const isGenerated =\n realTrack.text_source === 'generated_live' ||\n realTrack.text_source === 'generated_live_final' ||\n realTrack.text_source === 'generated_vod'\n return isGenerated\n }\n if (realTrack.status === 'preparing') {\n return true\n }\n return false\n })\n }\n\n const newAutogeneratedIds = new Set<string>()\n fetchedTracks.forEach((track) => {\n if (\n track.id &&\n (track.text_source === 'generated_live' ||\n track.text_source === 'generated_live_final' ||\n track.text_source === 'generated_vod')\n ) {\n newAutogeneratedIds.add(track.id)\n }\n })\n\n const findMatchingRealTrack = (mockTrack: MuxTextTrack, tracksList: MuxTextTrack[]) => {\n return tracksList.find((rt) => {\n const nameMatches = rt.name === mockTrack.name\n const languageMatches = rt.language_code === mockTrack.language_code\n return nameMatches && languageMatches\n })\n }\n\n setAddedTracks((prev) => {\n return prev.filter((mockTrack) => {\n if (mockTrack.id && mockTrack.id.startsWith('generating-')) {\n const replaced = isMockTrackReplaced(mockTrack, fetchedTracks)\n if (replaced) {\n const realTrack = findMatchingRealTrack(mockTrack, fetchedTracks)\n if (realTrack?.id) {\n newAutogeneratedIds.add(realTrack.id)\n setTrackActivityOrder((prevOrder) => {\n const mockOrder = prevOrder.get(mockTrack.id)\n if (mockOrder) {\n const newMap = new Map(prevOrder)\n newMap.set(realTrack.id, mockOrder)\n return newMap\n }\n return prevOrder\n })\n }\n }\n return !replaced\n }\n return true\n })\n })\n\n if (newAutogeneratedIds.size > 0) {\n setAutogeneratedTrackIds((prevIds) => {\n const updated = new Set(prevIds)\n newAutogeneratedIds.forEach((id) => updated.add(id))\n return updated\n })\n }\n } catch (error) {\n console.error('Failed to refresh asset data:', error)\n }\n }, 3000) // Poll every 3 seconds\n\n return () => clearInterval(interval)\n }, [allTracks, asset, resyncAsset])\n\n const visibleTracks = allTracks\n .filter(\n (track) =>\n track.status === 'ready' || track.status === 'preparing' || track.status === 'errored'\n )\n .sort((a, b) => {\n const orderA = trackActivityOrder.get(a.id) || 0\n const orderB = trackActivityOrder.get(b.id) || 0\n\n if (orderA > 0 && orderB > 0) {\n return orderB - orderA\n }\n\n if (orderA > 0) return -1\n if (orderB > 0) return 1\n\n const aIsPreparing = a.status === 'preparing'\n const bIsPreparing = b.status === 'preparing'\n if (aIsPreparing && !bIsPreparing) return -1\n if (!aIsPreparing && bIsPreparing) return 1\n\n const aIsAutogenerated =\n (a.id && a.id.startsWith('generating-')) || (a.id && autogeneratedTrackIds.has(a.id))\n const bIsAutogenerated =\n (b.id && b.id.startsWith('generating-')) || (b.id && autogeneratedTrackIds.has(b.id))\n if (aIsAutogenerated && !bIsAutogenerated) return -1\n if (!aIsAutogenerated && bIsAutogenerated) return 1\n\n return 0\n })\n\n const handleDownload = async (track: MuxTextTrack) => {\n if (!track.id) return\n\n setDownloadingTrackId(track.id)\n try {\n await downloadVttFile(client, asset, track)\n } catch (error) {\n toast.push({\n title: 'Failed to download VTT file',\n status: 'error',\n description: error instanceof Error ? error.message : 'Please try again',\n })\n } finally {\n setDownloadingTrackId(null)\n }\n }\n\n const confirmDelete = async () => {\n if (!trackToDelete || !trackToDelete.id) return\n\n const track = trackToDelete\n setTrackToDelete(null)\n setDeletingTrackId(track.id)\n try {\n if (!asset.assetId) {\n throw new Error('Asset ID is required')\n }\n await deleteTextTrack(client, asset.assetId, track.id)\n\n // Refresh asset data after deletion\n await resyncAsset(asset)\n\n toast.push({\n title: 'Successfully deleted caption track',\n status: 'success',\n })\n\n setAddedTracks((prev) => prev.filter((t) => t.id !== track.id))\n setUpdatedTracks((prev) => {\n const newMap = new Map(prev)\n newMap.delete(track.id)\n return newMap\n })\n setTrackActivityOrder((prev) => {\n const newMap = new Map(prev)\n newMap.delete(track.id)\n return newMap\n })\n setAutogeneratedTrackIds((prev) => {\n const updated = new Set(prev)\n updated.delete(track.id)\n return updated\n })\n } catch (error) {\n toast.push({\n title: 'Failed to delete caption track',\n status: 'error',\n description: error instanceof Error ? error.message : 'Please try again',\n })\n } finally {\n setDeletingTrackId(null)\n }\n }\n\n const handleAddTrack = (track: MuxTextTrack) => {\n setAddedTracks((prev) => [...prev, track])\n setTrackActivityOrder((prev) => {\n const newMap = new Map(prev)\n newMap.set(track.id, prev.size + 1)\n return newMap\n })\n setShowAddDialog(false)\n }\n\n const handleUpdateTrack = async (updatedTrack: MuxTextTrack, oldTrackId?: string) => {\n if (oldTrackId) {\n setAddedTracks((prev) => prev.filter((t) => t.id !== oldTrackId))\n setUpdatedTracks((prev) => {\n const newMap = new Map(prev)\n newMap.delete(oldTrackId)\n return newMap\n })\n setTrackActivityOrder((prev) => {\n const newMap = new Map(prev)\n newMap.delete(oldTrackId)\n return newMap\n })\n setAutogeneratedTrackIds((prev) => {\n const updated = new Set(prev)\n updated.delete(oldTrackId)\n return updated\n })\n }\n\n const isAddedTrack = addedTracks.some((t) => t.id === updatedTrack.id)\n\n if (isAddedTrack) {\n setAddedTracks((prev) => prev.map((t) => (t.id === updatedTrack.id ? updatedTrack : t)))\n } else {\n setUpdatedTracks((prev) => {\n const newMap = new Map(prev)\n newMap.set(updatedTrack.id, updatedTrack)\n return newMap\n })\n }\n\n setTrackActivityOrder((prev) => {\n const newMap = new Map(prev)\n newMap.set(updatedTrack.id, prev.size + 1)\n return newMap\n })\n\n setTrackToEdit(null)\n\n // Refresh asset data after update\n await resyncAsset(asset)\n }\n\n const getTrackSourceLabel = (track: MuxTextTrack) => {\n if (track.id && track.id.startsWith('generating-')) {\n return 'Auto-generated'\n }\n if (track.id && autogeneratedTrackIds.has(track.id)) {\n return 'Auto-generated'\n }\n if (\n track.text_source === 'generated_live_final' ||\n track.text_source === 'generated_live' ||\n track.text_source === 'generated_vod'\n ) {\n return 'Auto-generated'\n }\n if (track.text_source === 'uploaded') {\n return 'Uploaded'\n }\n return 'Custom'\n }\n\n if (visibleTracks.length === 0 && !showAddDialog) {\n return (\n <Stack space={3}>\n <Flex justify=\"flex-end\">\n <Button\n icon={AddIcon}\n text=\"Add Caption\"\n tone=\"primary\"\n onClick={() => setShowAddDialog(true)}\n />\n </Flex>\n <Card padding={4} radius={2} tone=\"transparent\" border>\n <Text size={1} muted>\n No captions available. Add captions when uploading a video or add them manually.\n </Text>\n </Card>\n {showAddDialog && (\n <AddCaptionDialog\n asset={asset}\n onAdd={handleAddTrack}\n onClose={() => setShowAddDialog(false)}\n />\n )}\n </Stack>\n )\n }\n\n const displayedTracks =\n collapseTracks && !isExpanded ? visibleTracks.slice(0, MAX_VISIBLE_TRACKS) : visibleTracks\n const hasMoreTracks = collapseTracks && visibleTracks.length > MAX_VISIBLE_TRACKS\n\n return (\n <Stack space={3}>\n <Flex justify=\"flex-end\">\n <Button\n icon={AddIcon}\n text=\"Add Caption\"\n tone=\"primary\"\n onClick={() => setShowAddDialog(true)}\n />\n </Flex>\n\n {displayedTracks.map((track) => (\n <TrackCard\n key={track.id}\n track={track}\n iconOnly={iconOnly}\n downloadingTrackId={downloadingTrackId}\n deletingTrackId={deletingTrackId}\n trackToEdit={trackToEdit}\n getTrackSourceLabel={getTrackSourceLabel}\n handleDownload={handleDownload}\n setTrackToEdit={setTrackToEdit}\n setTrackToDelete={setTrackToDelete}\n />\n ))}\n\n {hasMoreTracks && (\n <Flex justify=\"center\">\n <Button\n icon={isExpanded ? ChevronUpIcon : ChevronDownIcon}\n text={\n isExpanded ? 'Show less' : `Show ${visibleTracks.length - MAX_VISIBLE_TRACKS} more`\n }\n mode=\"ghost\"\n tone=\"primary\"\n onClick={() => setIsExpanded(!isExpanded)}\n />\n </Flex>\n )}\n\n {trackToDelete && (\n <Dialog\n animate\n id={dialogId}\n header=\"Delete track\"\n onClose={() => setTrackToDelete(null)}\n onClickOutside={() => setTrackToDelete(null)}\n width={1}\n >\n <Card\n padding={3}\n style={{\n minHeight: '150px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Stack space={3}>\n <Heading size={2}>\n Are you sure you want to delete &quot;\n {trackToDelete.name || trackToDelete.language_code || 'Untitled'}&quot;?\n </Heading>\n <Text size={2}>This action is irreversible</Text>\n <Stack space={4} marginY={4}>\n <Box>\n <Button\n icon={\n deletingTrackId === trackToDelete.id ? (\n <Spinner\n style={{\n verticalAlign: 'middle',\n display: 'inline-block',\n marginTop: '-2px',\n width: '0.5em',\n height: '0.5em',\n }}\n />\n ) : (\n <TrashIcon />\n )\n }\n fontSize={2}\n padding={3}\n text=\"Delete track\"\n tone=\"critical\"\n onClick={confirmDelete}\n disabled={deletingTrackId !== null}\n />\n </Box>\n </Stack>\n </Stack>\n </Card>\n </Dialog>\n )}\n\n {showAddDialog && (\n <AddCaptionDialog\n asset={asset}\n onAdd={handleAddTrack}\n onClose={() => setShowAddDialog(false)}\n />\n )}\n\n {trackToEdit && (\n <EditCaptionDialog\n asset={asset}\n track={trackToEdit}\n onUpdate={handleUpdateTrack}\n onClose={() => setTrackToEdit(null)}\n />\n )}\n </Stack>\n )\n}\n","import React, {createContext, useContext} from 'react'\n\nimport {type DialogState, type SetDialogState} from '../hooks/useDialogState'\n\ntype DialogStateContextProps = {\n dialogState: DialogState\n setDialogState: SetDialogState\n}\n\nconst DialogStateContext = createContext<DialogStateContextProps>({\n dialogState: false,\n setDialogState: () => {\n return null\n },\n})\n\ninterface DialogStateProviderProps extends DialogStateContextProps {\n children: React.ReactNode\n}\n\nexport const DialogStateProvider = ({\n dialogState,\n setDialogState,\n children,\n}: DialogStateProviderProps) => {\n return (\n <DialogStateContext.Provider value={{dialogState, setDialogState}}>\n {children}\n </DialogStateContext.Provider>\n )\n}\n\nexport const useDialogStateContext = () => {\n const context = useContext(DialogStateContext)\n return context\n}\n","import type {SanityClient} from 'sanity'\n\nimport {generateJwt} from './generateJwt'\nimport type {MuxPlaybackId, MuxVideoUrl} from './types'\n\ninterface VideoSrcOptions {\n muxPlaybackId: MuxPlaybackId\n client: SanityClient\n}\n\n/**\n * May throw a Promise. Call this with {@link tryWithSuspend} or rethrow the Promise\n */\nexport function getVideoSrc({client, muxPlaybackId}: VideoSrcOptions): MuxVideoUrl {\n const searchParams = new URLSearchParams()\n\n if (muxPlaybackId.policy === 'signed' || muxPlaybackId.policy === 'drm') {\n const token = generateJwt(client, muxPlaybackId.id, 'v')\n searchParams.set('token', token)\n }\n\n return `https://stream.mux.com/${muxPlaybackId.id}.m3u8?${searchParams}`\n}\n","import {Dialog, Stack} from '@sanity/ui'\nimport {useId} from 'react'\n\nimport {useDialogStateContext} from '../context/DialogStateContext'\nimport type {VideoAssetDocument} from '../util/types'\nimport TextTracksManager from './TextTracksManager'\n\nexport interface Props {\n asset: VideoAssetDocument\n}\n\nexport default function CaptionsDialog({asset}: Props) {\n const {setDialogState} = useDialogStateContext()\n const dialogId = `CaptionsDialog${useId()}`\n\n return (\n <Dialog id={dialogId} header=\"Edit Captions\" onClose={() => setDialogState(false)} width={1}>\n <Stack padding={4}>\n <TextTracksManager asset={asset} />\n </Stack>\n </Dialog>\n )\n}\n","import { useState, useEffect } from 'react';\n\n/**\r\n * Get the device pixel ratio, potentially rounded and capped.\r\n * Will emit new values if it changes.\r\n *\r\n * @param options\r\n * @returns The current device pixel ratio, or the default if none can be resolved\r\n */\n\nfunction useDevicePixelRatio(options) {\n const dpr = getDevicePixelRatio(options);\n const [currentDpr, setCurrentDpr] = useState(dpr);\n const {\n defaultDpr,\n maxDpr,\n round\n } = options || {};\n useEffect(() => {\n const canListen = typeof window !== 'undefined' && 'matchMedia' in window;\n\n if (!canListen) {\n return;\n }\n\n const updateDpr = () => setCurrentDpr(getDevicePixelRatio({\n defaultDpr,\n maxDpr,\n round\n }));\n\n const mediaMatcher = window.matchMedia(`screen and (resolution: ${currentDpr}dppx)`); // Safari 13.1 does not have `addEventListener`, but does have `addListener`\n\n if (mediaMatcher.addEventListener) {\n mediaMatcher.addEventListener('change', updateDpr);\n } else {\n mediaMatcher.addListener(updateDpr);\n }\n\n return () => {\n if (mediaMatcher.removeEventListener) {\n mediaMatcher.removeEventListener('change', updateDpr);\n } else {\n mediaMatcher.removeListener(updateDpr);\n }\n };\n }, [currentDpr, defaultDpr, maxDpr, round]);\n return currentDpr;\n}\n/**\r\n * Returns the current device pixel ratio (DPR) given the passed options\r\n *\r\n * @param options\r\n * @returns current device pixel ratio\r\n */\n\nfunction getDevicePixelRatio(options) {\n const {\n defaultDpr = 1,\n maxDpr = 3,\n round = true\n } = options || {};\n const hasDprProp = typeof window !== 'undefined' && typeof window.devicePixelRatio === 'number';\n const dpr = hasDprProp ? window.devicePixelRatio : defaultDpr;\n const rounded = Math.min(Math.max(1, round ? Math.floor(dpr) : dpr), maxDpr);\n return rounded;\n}\n\nexport { getDevicePixelRatio, useDevicePixelRatio };\n//# sourceMappingURL=index.module.js.map\n","/* eslint-disable */\n// From: https://stackoverflow.com/a/11486026/10433647\nexport function formatSeconds(seconds: number): string {\n if (typeof seconds !== 'number' || Number.isNaN(seconds)) {\n return ''\n }\n // Hours, minutes and seconds\n const hrs = ~~(seconds / 3600)\n const mins = ~~((seconds % 3600) / 60)\n const secs = ~~seconds % 60\n\n // Output like \"1:01\" or \"4:03:59\" or \"123:03:59\"\n let ret = ''\n\n if (hrs > 0) {\n ret += '' + hrs + ':' + (mins < 10 ? '0' : '')\n }\n\n ret += '' + mins + ':' + (secs < 10 ? '0' : '')\n ret += '' + secs\n return ret\n}\n\n// Output like \"05:14:01\"\nexport function formatSecondsToHHMMSS(seconds: number): string {\n const hrs = Math.floor(seconds / 3600)\n .toString()\n .padStart(2, '0')\n const mins = Math.floor((seconds % 3600) / 60)\n .toString()\n .padStart(2, '0')\n const secs = Math.floor(seconds % 60)\n .toString()\n .padStart(2, '0')\n\n return `${hrs}:${mins}:${secs}`\n}\n\n// Checks if time has a HH:MM:SS format like \"05:14:01\"\nexport function isValidTimeFormat(time: string) {\n const regex = /^([0-1]?[0-9]|2[0-3]):([0-5]?[0-9]):([0-5]?[0-9])$/\n return regex.test(time) || time === ''\n}\n\n// Converts a time like \"05:14:01\" to seconds\nexport function getSecondsFromTimeFormat(time: string): number {\n const [hh = 0, mm = 0, ss = 0] = time.split(':').map(Number)\n return hh * 3600 + mm * 60 + ss\n}\n","import {Button, Dialog, Flex, Stack, Text, TextInput} from '@sanity/ui'\nimport React, {useId, useMemo, useState} from 'react'\nimport {getDevicePixelRatio} from 'use-device-pixel-ratio'\n\nimport {useDialogStateContext} from '../context/DialogStateContext'\nimport {useClient} from '../hooks/useClient'\nimport {\n formatSecondsToHHMMSS,\n getSecondsFromTimeFormat,\n isValidTimeFormat,\n} from '../util/formatSeconds'\nimport type {VideoAssetDocument} from '../util/types'\nimport VideoThumbnail from './VideoThumbnail'\n\nexport interface Props {\n asset: VideoAssetDocument\n currentTime?: number\n}\n\nexport default function EditThumbnailDialog({asset, currentTime = 0}: Props) {\n const client = useClient()\n\n const {setDialogState} = useDialogStateContext()\n const dialogId = `EditThumbnailDialog${useId()}`\n\n const [timeFormatted, setTimeFormatted] = useState<string>(() =>\n formatSecondsToHHMMSS(currentTime)\n )\n const [nextTime, setNextTime] = useState<number>(currentTime)\n const [inputError, setInputError] = useState<string>('')\n\n const assetWithNewThumbnail = useMemo(() => ({...asset, thumbTime: nextTime}), [asset, nextTime])\n const [saving, setSaving] = useState(false)\n const [saveThumbnailError, setSaveThumbnailError] = useState<Error | null>(null)\n const handleSave = () => {\n setSaving(true)\n client\n .patch(asset._id!)\n .set({thumbTime: nextTime})\n .commit({returnDocuments: false})\n .then(() => void setDialogState(false))\n .catch(setSaveThumbnailError)\n .finally(() => void setSaving(false))\n }\n const width = 300 * getDevicePixelRatio({maxDpr: 2})\n\n if (saveThumbnailError) {\n // eslint-disable-next-line no-warning-comments\n // @TODO handle errors more gracefully\n throw saveThumbnailError\n }\n\n const handleInputChange = (event: React.FormEvent<HTMLInputElement>) => {\n const value = event.currentTarget.value\n setTimeFormatted(value)\n\n if (isValidTimeFormat(value)) {\n setInputError('')\n const totalSeconds = getSecondsFromTimeFormat(value)\n setNextTime(totalSeconds)\n } else {\n setInputError('Invalid time format')\n }\n }\n\n return (\n <Dialog\n id={dialogId}\n header=\"Edit thumbnail\"\n onClose={() => setDialogState(false)}\n footer={\n <Stack padding={3}>\n <Button\n key=\"thumbnail\"\n disabled={inputError !== ''}\n mode=\"ghost\"\n tone=\"primary\"\n loading={saving}\n onClick={handleSave}\n text=\"Set new thumbnail\"\n />\n </Stack>\n }\n >\n <Stack space={3} padding={3}>\n <Stack space={2}>\n <Text size={1} weight=\"semibold\">\n Current:\n </Text>\n <VideoThumbnail asset={asset} width={width} staticImage />\n </Stack>\n <Stack space={2}>\n <Text size={1} weight=\"semibold\">\n New:\n </Text>\n <VideoThumbnail asset={assetWithNewThumbnail} width={width} staticImage />\n </Stack>\n\n <Stack space={2}>\n <Flex align={'center'} justify={'center'}>\n <Text size={5} weight=\"semibold\">\n Or\n </Text>\n </Flex>\n </Stack>\n\n <Stack space={2}>\n <Text size={1} weight=\"semibold\">\n Selected time for thumbnail (hh:mm:ss):\n </Text>\n <TextInput\n size={1}\n value={timeFormatted}\n placeholder=\"hh:mm:ss\"\n onChange={handleInputChange}\n customValidity={inputError}\n />\n </Stack>\n </Stack>\n </Dialog>\n )\n}\n","import type {SVGProps} from 'react'\n\nexport function AudioIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n style={{opacity: '0.65'}}\n d=\"M10.75 19q.95 0 1.6-.65t.65-1.6V13h3v-2h-4v3.875q-.275-.2-.587-.288t-.663-.087q-.95 0-1.6.65t-.65 1.6t.65 1.6t1.6.65M6 22q-.825 0-1.412-.587T4 20V4q0-.825.588-1.412T6 2h8l6 6v12q0 .825-.587 1.413T18 22zm7-13V4H6v16h12V9zM6 4v5zv16z\"\n />\n </svg>\n )\n}\n","import {type MuxPlayerProps, type MuxPlayerRefAttributes} from '@mux/mux-player-react'\nimport MuxPlayer from '@mux/mux-player-react/lazy'\nimport {ErrorOutlineIcon} from '@sanity/icons'\nimport {Card, Text} from '@sanity/ui'\nimport {type PropsWithChildren, Suspense, useMemo, useRef, useState} from 'react'\n\nimport {useDialogStateContext} from '../context/DialogStateContext'\nimport {useClient} from '../hooks/useClient'\nimport {AUDIO_ASPECT_RATIO, MIN_ASPECT_RATIO} from '../util/constants'\nimport {generateJwt} from '../util/generateJwt'\nimport {getPlaybackId} from '../util/getPlaybackPolicy'\nimport {getPlaybackPolicyById} from '../util/getPlaybackPolicy'\nimport {getPosterSrc} from '../util/getPosterSrc'\nimport {getVideoSrc} from '../util/getVideoSrc'\nimport {tryWithSuspend} from '../util/tryWithSuspend'\nimport type {VideoAssetDocument} from '../util/types'\nimport CaptionsDialog from './CaptionsDialog'\nimport EditThumbnailDialog from './EditThumbnailDialog'\nimport {AudioIcon} from './icons/Audio'\n\nexport default function VideoPlayer({\n asset,\n thumbnailWidth = 250,\n children,\n hlsConfig,\n ...props\n}: PropsWithChildren<\n {\n asset: VideoAssetDocument\n thumbnailWidth?: number\n forceAspectRatio?: number\n hlsConfig?: MuxPlayerProps['_hlsConfig']\n } & Partial<Pick<MuxPlayerProps, 'autoPlay'>>\n>) {\n const client = useClient()\n const {dialogState} = useDialogStateContext()\n\n const isAudio = assetIsAudio(asset)\n const muxPlayer = useRef<MuxPlayerRefAttributes>(null)\n const playerContainerRef = useRef<HTMLDivElement>(null)\n const [error, setError] = useState<Error>()\n\n /* Playback ID that will be used to play the video */\n const playbackId = useMemo(() => {\n try {\n return getPlaybackId(asset, ['public', 'signed', 'drm'])\n } catch (e) {\n setError(new TypeError('Asset has no playback ID'))\n return undefined\n }\n }, [asset])\n\n const muxPlaybackId = useMemo(() => {\n if (!playbackId) return undefined\n return getPlaybackPolicyById(asset, playbackId)\n }, [asset, playbackId])\n\n const src = useMemo(() => {\n if (!playbackId) return undefined\n if (!muxPlaybackId) return undefined\n return tryWithSuspend(\n () => getVideoSrc({muxPlaybackId, client}),\n (e: Error) => {\n setError(e)\n return undefined\n }\n )\n }, [muxPlaybackId, playbackId, client])\n\n const poster = useMemo(() => {\n return tryWithSuspend(\n () => getPosterSrc({asset, client, width: thumbnailWidth}),\n (e: Error) => {\n setError(e)\n return undefined\n }\n )\n }, [asset, client, thumbnailWidth])\n\n const signedToken = useMemo(() => {\n try {\n const url = new URL(src!)\n return url.searchParams.get('token')\n } catch {\n return undefined\n }\n }, [src])\n const drmToken = useMemo(() => {\n if (!playbackId) return undefined\n if (muxPlaybackId?.policy !== 'drm') return undefined\n\n return tryWithSuspend(\n () => generateJwt(client, playbackId, 'd'),\n (e: Error) => {\n setError(e)\n return undefined\n }\n )\n }, [client, muxPlaybackId?.policy, playbackId])\n const tokens:\n | Partial<{\n playback?: string\n thumbnail?: string\n storyboard?: string\n drm?: string\n }>\n | undefined = useMemo(() => {\n try {\n const partialTokens: {\n playback?: string\n thumbnail?: string\n storyboard?: string\n drm?: string\n } = {\n playback: undefined,\n thumbnail: undefined,\n storyboard: undefined,\n drm: undefined,\n }\n\n if (signedToken) {\n partialTokens.playback = signedToken\n partialTokens.thumbnail = signedToken\n partialTokens.storyboard = signedToken\n }\n\n if (drmToken) {\n partialTokens.drm = drmToken\n }\n\n return {...partialTokens}\n } catch {\n return undefined\n }\n }, [signedToken, drmToken])\n\n const [width, height] = (asset?.data?.aspect_ratio ?? '16:9').split(':').map(Number)\n const targetAspectRatio =\n props.forceAspectRatio || (Number.isNaN(width) ? 16 / 9 : width / height)\n let aspectRatio = Math.max(MIN_ASPECT_RATIO, targetAspectRatio)\n if (isAudio) {\n aspectRatio = props.forceAspectRatio\n ? // Make it wider when forcing aspect ratio to balance with videos' rendering height (audio players overflow a bit)\n props.forceAspectRatio * 1.2\n : AUDIO_ASPECT_RATIO\n }\n\n /* We use Suspense here because `generateJwt` and related functions use suspend()\n under the hood */\n return (\n <>\n <Card\n ref={playerContainerRef}\n tone=\"transparent\"\n style={{\n aspectRatio: aspectRatio,\n position: 'relative',\n ...(isAudio && {display: 'flex', alignItems: 'flex-end'}),\n }}\n >\n {src && poster && (\n <>\n {isAudio && (\n <AudioIcon\n style={{\n padding: '0.5em',\n width: '2.2em',\n height: '2.2em',\n position: 'absolute',\n top: 0,\n left: 0,\n zIndex: 1,\n }}\n />\n )}\n <Suspense fallback={null}>\n <MuxPlayer\n poster={isAudio ? undefined : poster}\n ref={muxPlayer}\n {...props}\n playsInline\n playbackId={playbackId}\n tokens={tokens}\n preload=\"metadata\"\n crossOrigin=\"anonymous\"\n metadata={{\n player_name: 'Sanity Admin Dashboard',\n player_version: process.env.PKG_VERSION,\n page_type: 'Preview Player',\n }}\n audio={isAudio}\n _hlsConfig={hlsConfig}\n style={{\n ...(!isAudio && {height: '100%'}),\n width: '100%',\n display: 'block',\n objectFit: 'contain',\n ...(isAudio && {alignSelf: 'end'}),\n }}\n />\n {children}\n </Suspense>\n </>\n )}\n {error ? (\n <div\n style={{\n position: 'absolute',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n }}\n >\n <Text muted>\n <ErrorOutlineIcon style={{marginRight: '0.15em'}} />\n {typeof error === 'object' && 'message' in error && typeof error.message === 'string'\n ? error.message\n : 'Error loading video'}\n </Text>\n </div>\n ) : null}\n {children}\n </Card>\n\n {dialogState === 'edit-thumbnail' && (\n <EditThumbnailDialog asset={asset} currentTime={muxPlayer?.current?.currentTime} />\n )}\n {dialogState === 'edit-captions' && <CaptionsDialog asset={asset} />}\n </>\n )\n}\n\nexport function assetIsAudio(asset: VideoAssetDocument) {\n return asset.data?.max_stored_resolution === 'Audio only'\n}\n","// Adapted from https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/MissingSchemaType.tsx\nimport {WarningOutlineIcon} from '@sanity/icons'\nimport type {SanityDocument} from 'sanity'\nimport type {GeneralPreviewLayoutKey} from 'sanity'\nimport {SanityDefaultPreview} from 'sanity'\n\nexport interface MissingSchemaTypeProps {\n layout?: GeneralPreviewLayoutKey\n value: SanityDocument\n}\n\nconst getUnknownTypeFallback = (id: string, typeName: string) => ({\n title: (\n <em>\n No schema found for type <code>{typeName}</code>\n </em>\n ),\n subtitle: (\n <em>\n Document: <code>{id}</code>\n </em>\n ),\n media: () => <WarningOutlineIcon />,\n})\n\nexport function MissingSchemaType(props: MissingSchemaTypeProps) {\n const {layout, value} = props\n\n return (\n <SanityDefaultPreview {...getUnknownTypeFallback(value._id, value._type)} layout={layout} />\n )\n}\n","// Adapted from https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/TimeAgo.tsx\nimport {useTimeAgo} from 'sanity'\n\nexport interface TimeAgoProps {\n time: string | Date\n}\n\nexport function TimeAgo({time}: TimeAgoProps) {\n const timeAgo = useTimeAgo(time)\n\n return <span title={timeAgo}>{timeAgo} ago</span>\n}\n","// Adapted from https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/DraftStatus.tsx\nimport {EditIcon} from '@sanity/icons'\nimport {Box, Text, Tooltip} from '@sanity/ui'\nimport type {PreviewValue, SanityDocument} from 'sanity'\nimport {TextWithTone} from 'sanity'\n\nimport {TimeAgo} from './TimeAgo'\n\nexport function DraftStatus(props: {document?: PreviewValue | Partial<SanityDocument> | null}) {\n const {document} = props\n const updatedAt = document && '_updatedAt' in document && document._updatedAt\n\n return (\n <Tooltip\n animate\n portal\n content={\n <Box padding={2}>\n <Text size={1}>\n {document ? (\n <>Edited {updatedAt && <TimeAgo time={updatedAt} />}</>\n ) : (\n <>No unpublished edits</>\n )}\n </Text>\n </Box>\n }\n >\n <TextWithTone tone=\"caution\" dimmed={!document} muted={!document} size={1}>\n <EditIcon />\n </TextWithTone>\n </Tooltip>\n )\n}\n","// Adapted from https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/PublishedStatus.tsx\n\nimport {PublishIcon} from '@sanity/icons'\nimport {Box, Text, Tooltip} from '@sanity/ui'\nimport type {PreviewValue, SanityDocument} from 'sanity'\nimport {TextWithTone} from 'sanity'\n\nimport {TimeAgo} from './TimeAgo'\n\nexport function PublishedStatus(props: {document?: PreviewValue | Partial<SanityDocument> | null}) {\n const {document} = props\n const updatedAt = document && '_updatedAt' in document && document._updatedAt\n\n return (\n <Tooltip\n animate\n portal\n content={\n <Box padding={2}>\n <Text size={1}>\n {document ? (\n <>Published {updatedAt && <TimeAgo time={updatedAt} />}</>\n ) : (\n <>Not published</>\n )}\n </Text>\n </Box>\n }\n >\n <TextWithTone tone=\"positive\" dimmed={!document} muted={!document} size={1}>\n <PublishIcon />\n </TextWithTone>\n </Tooltip>\n )\n}\n","// Adapted from:\n// https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/paneItem/PaneItemPreview.tsx\nimport {Inline} from '@sanity/ui'\nimport {isNumber, isString} from 'lodash'\nimport {isValidElement, useMemo} from 'react'\nimport {useObservable} from 'react-rx'\nimport type {SanityDocument, SchemaType} from 'sanity'\nimport type {PreviewValue} from 'sanity'\nimport {\n type DocumentPresence,\n DocumentPreviewPresence,\n type DocumentPreviewStore,\n type GeneralPreviewLayoutKey,\n getPreviewStateObservable,\n getPreviewValueWithFallback,\n isRecord,\n SanityDefaultPreview,\n} from 'sanity'\n\nimport {DraftStatus} from './DraftStatus'\nimport {PublishedStatus} from './PublishedStatus'\n\nexport interface PaneItemPreviewState {\n isLoading?: boolean\n draft?: PreviewValue | Partial<SanityDocument> | null\n published?: PreviewValue | Partial<SanityDocument> | null\n}\n\nexport interface PaneItemPreviewProps {\n documentPreviewStore: DocumentPreviewStore\n icon: React.ComponentType | false\n layout: GeneralPreviewLayoutKey\n presence?: DocumentPresence[]\n schemaType: SchemaType\n value: SanityDocument\n}\n\nexport function PaneItemPreview(props: PaneItemPreviewProps) {\n const {icon, layout, presence, schemaType, value} = props\n const title =\n (isRecord(value.title) && isValidElement(value.title)) ||\n isString(value.title) ||\n isNumber(value.title)\n ? value.title\n : null\n\n const observable = useMemo(\n () => getPreviewStateObservable(props.documentPreviewStore, schemaType, value._id),\n [props.documentPreviewStore, schemaType, value._id]\n )\n const {snapshot, original, isLoading} = useObservable(observable, {\n isLoading: true,\n snapshot: null,\n original: null,\n })\n\n const status = isLoading ? null : (\n <Inline space={4}>\n {presence && presence.length > 0 && <DocumentPreviewPresence presence={presence} />}\n <PublishedStatus document={original} />\n <DraftStatus document={snapshot} />\n </Inline>\n )\n\n return (\n <SanityDefaultPreview\n {...(getPreviewValueWithFallback({snapshot, original, fallback: {title}}) as any)}\n isPlaceholder={isLoading}\n icon={icon}\n layout={layout}\n status={status}\n />\n )\n}\n","// Adapted from https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/paneItem/PaneItem.tsx\n\nimport {DocumentIcon} from '@sanity/icons'\nimport type {PropsWithChildren} from 'react'\nimport React, {useMemo} from 'react'\nimport type {CollatedHit, FIXME, SanityDocument, SchemaType} from 'sanity'\nimport {PreviewCard, useDocumentPresence, useDocumentPreviewStore, useSchema} from 'sanity'\nimport {IntentLink} from 'sanity/router'\n\nimport {MissingSchemaType} from './MissingSchemaType'\nimport {PaneItemPreview} from './PaneItemPreview'\n\ninterface DocumentPreviewProps {\n schemaType?: SchemaType\n documentPair: CollatedHit<SanityDocument>\n}\n\n/**\n * Return `false` if we explicitly disable the icon.\n * Otherwise return the passed icon or the schema type icon as a backup.\n */\nexport function getIconWithFallback(\n icon: React.ComponentType<any> | false | undefined,\n schemaType: SchemaType | undefined,\n defaultIcon: React.ComponentType<any>\n): React.ComponentType<any> | false {\n if (icon === false) {\n return false\n }\n\n return icon || ((schemaType && schemaType.icon) as any) || defaultIcon || false\n}\n\nfunction DocumentPreviewLink(props: DocumentPreviewProps) {\n return (linkProps: PropsWithChildren) => (\n <IntentLink intent=\"edit\" params={{id: props.documentPair.id}}>\n {linkProps.children}\n </IntentLink>\n )\n}\n\nexport function DocumentPreview(props: DocumentPreviewProps) {\n const {schemaType, documentPair} = props\n const doc = documentPair?.draft || documentPair?.published\n const id = documentPair.id || ''\n const documentPreviewStore = useDocumentPreviewStore()\n const schema = useSchema()\n const documentPresence = useDocumentPresence(id)\n const hasSchemaType = Boolean(schemaType && schemaType.name && schema.get(schemaType.name))\n\n const PreviewComponent = useMemo(() => {\n if (!doc) return null\n\n if (!schemaType || !hasSchemaType) {\n return <MissingSchemaType value={doc as SanityDocument} />\n }\n\n return (\n <PaneItemPreview\n documentPreviewStore={documentPreviewStore}\n icon={getIconWithFallback(undefined, schemaType, DocumentIcon)}\n schemaType={schemaType}\n layout=\"default\"\n value={doc}\n presence={documentPresence}\n />\n )\n }, [hasSchemaType, schemaType, documentPresence, doc, documentPreviewStore])\n\n return (\n <PreviewCard\n __unstable_focusRing\n as={DocumentPreviewLink(props) as FIXME}\n data-as=\"a\"\n data-ui=\"PaneItem\"\n padding={2}\n radius={2}\n tone=\"inherit\"\n >\n {PreviewComponent}\n </PreviewCard>\n )\n}\n","import type {SanityDocument} from '@sanity/client'\nimport {Box, Card, Text} from '@sanity/ui'\nimport {collate, useSchema} from 'sanity'\nimport {styled} from 'styled-components'\n\nimport {DocumentPreview} from '../documentPreview/DocumentPreview'\nimport SpinnerBox from '../SpinnerBox'\n\nconst Container = styled(Box)`\n * {\n color: ${(props: any) => props.theme.sanity.color.base.fg};\n }\n a {\n text-decoration: none;\n }\n h2 {\n font-size: ${(props: any) => props.theme.sanity.fonts.text.sizes[1]};\n }\n`\n\nconst VideoReferences: React.FC<{\n references?: SanityDocument[]\n isLoaded: boolean\n}> = (props) => {\n const schema = useSchema()\n if (!props.isLoaded) {\n return <SpinnerBox />\n }\n\n if (!props.references?.length) {\n return (\n <Card border radius={3} padding={3}>\n <Text size={2}>No documents are using this video</Text>\n </Card>\n )\n }\n\n const documentPairs = collate(props.references || [])\n return (\n <Container>\n {documentPairs?.map((documentPair) => {\n const schemaType = schema.get(documentPair.type)\n\n return (\n <Card\n key={documentPair.id}\n marginBottom={2}\n padding={2}\n radius={2}\n shadow={1}\n style={{overflow: 'hidden'}}\n >\n <Box>\n <DocumentPreview documentPair={documentPair} schemaType={schemaType} />\n </Box>\n </Card>\n )\n })}\n </Container>\n )\n}\n\nexport default VideoReferences\n","import {TrashIcon} from '@sanity/icons'\nimport {Box, Button, Card, Checkbox, Dialog, Flex, Heading, Stack, Text, useToast} from '@sanity/ui'\nimport {useEffect, useState} from 'react'\nimport type {SanityDocument} from 'sanity'\n\nimport {deleteAsset} from '../../actions/assets'\nimport {useClient} from '../../hooks/useClient'\nimport {DIALOGS_Z_INDEX} from '../../util/constants'\nimport type {VideoAssetDocument} from '../../util/types'\nimport SpinnerBox from '../SpinnerBox'\nimport VideoReferences from './VideoReferences'\n\nexport default function DeleteDialog({\n asset,\n references,\n referencesLoading,\n cancelDelete,\n succeededDeleting,\n}: {\n asset: VideoAssetDocument\n references?: SanityDocument[]\n referencesLoading: boolean\n cancelDelete: () => void\n succeededDeleting: () => void\n}) {\n const client = useClient()\n const [state, setState] = useState<\n 'processing_deletion' | 'checkingReferences' | 'error_deleting' | 'cantDelete' | 'confirm'\n >('checkingReferences')\n const [deleteOnMux, setDeleteOnMux] = useState(true)\n const toast = useToast()\n\n useEffect(() => {\n if (state !== 'checkingReferences' || referencesLoading) return\n\n setState(references?.length ? 'cantDelete' : 'confirm')\n }, [state, references, referencesLoading])\n\n async function confirmDelete() {\n if (state !== 'confirm') return\n\n setState('processing_deletion')\n const worked = await deleteAsset({client, asset, deleteOnMux})\n if (worked === true) {\n toast.push({title: 'Successfully deleted video', status: 'success'})\n succeededDeleting()\n } else if (worked === 'failed-mux') {\n toast.push({\n title: 'Deleted video in Sanity',\n description: \"But it wasn't deleted in Mux\",\n status: 'warning',\n })\n succeededDeleting()\n } else {\n toast.push({title: 'Failed deleting video', status: 'error'})\n\n setState('error_deleting')\n }\n }\n\n return (\n <Dialog\n animate\n header={'Delete video'}\n zOffset={DIALOGS_Z_INDEX}\n id=\"deleting-video-details-dialog\"\n onClose={cancelDelete}\n onClickOutside={cancelDelete}\n width={1}\n position=\"fixed\"\n >\n <Card\n padding={3}\n style={{\n minHeight: '150px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Stack space={3}>\n {state === 'checkingReferences' && (\n <>\n <Heading size={2}>Checking if video can be deleted</Heading>\n <SpinnerBox />\n </>\n )}\n {state === 'cantDelete' && (\n <>\n <Heading size={2}>Video can&apos;t be deleted</Heading>\n <Text size={2} style={{marginBottom: '2rem'}}>\n There are {references?.length} document{references && references.length > 0 && 's'}{' '}\n pointing to this video. Remove their references to this file or delete them before\n proceeding.\n </Text>\n <VideoReferences references={references} isLoaded={!referencesLoading} />\n </>\n )}\n {state === 'confirm' && (\n <>\n <Heading size={2}>Are you sure you want to delete this video?</Heading>\n <Text size={2}>This action is irreversible</Text>\n <Stack space={4} marginY={4}>\n <Flex align=\"center\" as=\"label\">\n <Checkbox\n checked={deleteOnMux}\n onChange={() => setDeleteOnMux((prev) => !prev)}\n />\n <Text style={{margin: '0 10px'}}>Delete asset on Mux</Text>\n </Flex>\n <Flex align=\"center\" as=\"label\">\n <Checkbox disabled checked />\n <Text style={{margin: '0 10px'}}>Delete video from dataset</Text>\n </Flex>\n <Box>\n <Button\n icon={TrashIcon}\n fontSize={2}\n padding={3}\n text=\"Delete video\"\n tone=\"critical\"\n onClick={confirmDelete}\n disabled={['processing_deletion', 'checkingReferences', 'cantDelete'].some(\n (s) => s === state\n )}\n />\n </Box>\n </Stack>\n </>\n )}\n {state === 'processing_deletion' && (\n <>\n <Heading size={2}>Deleting video...</Heading>\n <SpinnerBox />\n </>\n )}\n {state === 'error_deleting' && (\n <>\n <Heading size={2}>Something went wrong!</Heading>\n <Text size={2}>Try deleting the video again by clicking the button below</Text>\n </>\n )}\n </Stack>\n </Card>\n </Dialog>\n )\n}\n","import {createHookFromObservableFactory, DocumentStore, SanityDocument} from 'sanity'\n\nimport {SANITY_API_VERSION} from './useClient'\n\nconst useDocReferences = createHookFromObservableFactory<\n SanityDocument[],\n {\n documentStore: DocumentStore\n id: string\n }\n>(({documentStore, id}) => {\n return documentStore.listenQuery(\n /* groq */ '*[references($id)]{_id, _type, _rev, _updatedAt, _createdAt}',\n {id},\n {\n apiVersion: SANITY_API_VERSION,\n }\n )\n})\n\nexport default useDocReferences\n","import {formatSeconds} from './formatSeconds'\nimport type {MuxTextTrack, VideoAssetDocument} from './types'\n\nexport default function getVideoMetadata(doc: VideoAssetDocument) {\n const id = doc.assetId || doc._id || ''\n const date = doc.data?.created_at\n ? new Date(Number(doc.data.created_at) * 1000)\n : new Date(doc._createdAt || doc._updatedAt || Date.now())\n\n return {\n title: doc.filename || id.slice(0, 12),\n id: id,\n playbackId: doc.playbackId,\n createdAt: date,\n duration: doc.data?.duration ? formatSeconds(doc.data?.duration) : undefined,\n playback_ids: doc.data?.playback_ids,\n aspect_ratio: doc.data?.aspect_ratio,\n max_stored_resolution: doc.data?.max_stored_resolution,\n max_stored_frame_rate: doc.data?.max_stored_frame_rate,\n text_tracks:\n doc.data?.tracks?.filter((track): track is MuxTextTrack => track.type === 'text') || [],\n }\n}\n","import {useToast} from '@sanity/ui'\nimport {useMemo, useState} from 'react'\nimport {useDocumentStore} from 'sanity'\n\nimport {useClient} from '../../hooks/useClient'\nimport useDocReferences from '../../hooks/useDocReferences'\nimport {useResyncAsset} from '../../hooks/useResyncAsset'\nimport getVideoMetadata from '../../util/getVideoMetadata'\nimport {VideoAssetDocument} from '../../util/types'\n\ntype VideoDetailsState = 'idle' | 'saving' | 'deleting' | 'closing' | 'resyncing'\n\nexport interface VideoDetailsProps {\n closeDialog: () => void\n asset: VideoAssetDocument & {autoPlay?: boolean}\n}\n\nexport default function useVideoDetails(props: VideoDetailsProps) {\n const documentStore = useDocumentStore()\n const toast = useToast()\n const client = useClient()\n\n const [references, referencesLoading] = useDocReferences(\n useMemo(() => ({documentStore, id: props.asset._id}), [documentStore, props.asset._id])\n )\n\n const [originalAsset, setOriginalAsset] = useState(() => props.asset)\n const [filename, setFilename] = useState(props.asset.filename)\n const modified = filename !== originalAsset.filename\n\n const displayInfo = getVideoMetadata({...props.asset, filename})\n\n const [state, setState] = useState<VideoDetailsState>('idle')\n\n const {resyncAsset, isResyncing} = useResyncAsset({showToast: true})\n\n async function handleResync() {\n if (state !== 'idle') return\n setState('resyncing')\n await resyncAsset(props.asset)\n setState('idle')\n }\n\n function handleClose() {\n if (state !== 'idle') return\n\n if (modified) {\n setState('closing')\n return\n }\n\n props.closeDialog()\n }\n\n function confirmClose(shouldClose: boolean) {\n if (state !== 'closing') return\n\n if (shouldClose) props.closeDialog()\n\n setState('idle')\n }\n\n async function saveChanges() {\n if (state !== 'idle') return\n setState('saving')\n\n try {\n await client.patch(props.asset._id).set({filename}).commit()\n setOriginalAsset((prev) => ({...prev, filename}))\n toast.push({\n title: 'Video title updated',\n description: `New title: ${filename}`,\n status: 'success',\n })\n props.closeDialog()\n } catch (error) {\n toast.push({\n title: 'Failed updating file name',\n status: 'error',\n description: typeof error === 'string' ? error : 'Please try again',\n })\n setFilename(originalAsset.filename)\n }\n\n setState('idle')\n }\n\n return {\n references,\n referencesLoading,\n modified,\n filename,\n setFilename,\n displayInfo,\n state,\n setState,\n handleClose,\n confirmClose,\n saveChanges,\n handleResync,\n isResyncing,\n }\n}\n","import {\n CalendarIcon,\n CheckmarkIcon,\n ClockIcon,\n CropIcon,\n EditIcon,\n ErrorOutlineIcon,\n RevertIcon,\n SearchIcon,\n SyncIcon,\n TagIcon,\n TrashIcon,\n} from '@sanity/icons'\nimport {\n Button,\n Card,\n Dialog,\n Flex,\n Heading,\n Spinner,\n Stack,\n Tab,\n TabList,\n TabPanel,\n Text,\n TextInput,\n} from '@sanity/ui'\nimport React, {useEffect, useState} from 'react'\n\nimport {DIALOGS_Z_INDEX} from '../../util/constants'\nimport {MuxPlaybackId, MuxTextTrack, PlaybackPolicy} from '../../util/types'\nimport FormField from '../FormField'\nimport IconInfo from '../IconInfo'\nimport {ResolutionIcon} from '../icons/Resolution'\nimport {StopWatchIcon} from '../icons/StopWatch'\nimport TextTracksManager from '../TextTracksManager'\nimport VideoPlayer from '../VideoPlayer'\nimport DeleteDialog from './DeleteDialog'\nimport useVideoDetails, {VideoDetailsProps} from './useVideoDetails'\nimport VideoReferences from './VideoReferences'\n\nconst AssetInput: React.FC<{\n label: string\n description?: string\n placeholder?: string\n value: string\n onInput: (e: React.FormEvent<HTMLInputElement>) => void\n disabled?: boolean\n}> = (props) => (\n <FormField title={props.label} description={props.description} inputId={props.label}>\n <TextInput\n id={props.label}\n value={props.value}\n placeholder={props.placeholder}\n onInput={props.onInput}\n disabled={props.disabled}\n />\n </FormField>\n)\n\nconst VideoDetails: React.FC<VideoDetailsProps> = (props) => {\n const [tab, setTab] = useState<'details' | 'references'>('details')\n const {\n displayInfo,\n filename,\n modified,\n references,\n referencesLoading,\n setFilename,\n state,\n setState,\n handleClose,\n confirmClose,\n saveChanges,\n handleResync,\n isResyncing,\n } = useVideoDetails(props)\n\n const isSaving = state === 'saving'\n\n // Avoid layout shifts in large screens' 2-column dialog by setting their `minHeight` to the container's\n const [containerHeight, setContainerHeight] = useState<number | null>(null)\n const contentsRef = React.useRef<HTMLDivElement>(null)\n useEffect(() => {\n if (!contentsRef.current || !('getBoundingClientRect' in contentsRef.current)) return\n\n setContainerHeight(contentsRef.current.getBoundingClientRect().height)\n }, [])\n\n return (\n <Dialog\n animate\n header={displayInfo.title}\n zOffset={DIALOGS_Z_INDEX}\n id=\"video-details-dialog\"\n onClose={handleClose}\n onClickOutside={handleClose}\n width={2}\n position=\"fixed\"\n footer={\n <Card padding={3}>\n <Flex justify=\"space-between\" align=\"center\">\n <Flex gap={2}>\n <Button\n icon={TrashIcon}\n fontSize={2}\n padding={3}\n mode=\"bleed\"\n text=\"Delete\"\n tone=\"critical\"\n onClick={() => setState('deleting')}\n disabled={isSaving || isResyncing}\n />\n <Button\n icon={SyncIcon}\n fontSize={2}\n padding={3}\n mode=\"bleed\"\n text=\"Resync\"\n tone=\"primary\"\n onClick={handleResync}\n disabled={isSaving || isResyncing}\n iconRight={isResyncing && Spinner}\n />\n </Flex>\n {modified && (\n <Button\n icon={CheckmarkIcon}\n fontSize={2}\n padding={3}\n mode=\"ghost\"\n text=\"Save and close\"\n tone=\"positive\"\n onClick={saveChanges}\n iconRight={isSaving && Spinner}\n disabled={isSaving || isResyncing}\n />\n )}\n </Flex>\n </Card>\n }\n >\n {/* DELETION DIALOG */}\n {state === 'deleting' && (\n <DeleteDialog\n asset={props.asset}\n cancelDelete={() => setState('idle')}\n referencesLoading={referencesLoading}\n references={references}\n succeededDeleting={() => {\n props.closeDialog()\n }}\n />\n )}\n\n {/* CONFIRM CLOSING DIALOG */}\n {state === 'closing' && (\n <Dialog\n animate\n header={'You have unsaved changes'}\n zOffset={DIALOGS_Z_INDEX}\n id=\"closing-video-details-dialog\"\n onClose={() => confirmClose(false)}\n onClickOutside={() => confirmClose(false)}\n width={1}\n position=\"fixed\"\n footer={\n <Card padding={3}>\n <Flex justify=\"space-between\" align=\"center\">\n <Button\n icon={ErrorOutlineIcon}\n fontSize={2}\n padding={3}\n text=\"Discard changes\"\n tone=\"critical\"\n onClick={() => confirmClose(true)}\n />\n {modified && (\n <Button\n icon={RevertIcon}\n fontSize={2}\n padding={3}\n mode=\"ghost\"\n text=\"Keep editing\"\n tone=\"primary\"\n onClick={() => confirmClose(false)}\n />\n )}\n </Flex>\n </Card>\n }\n >\n <Card padding={5}>\n <Stack style={{textAlign: 'center'}} space={3}>\n <Heading size={2}>Unsaved changes will be lost</Heading>\n <Text size={2}>Are you sure you want to discard them?</Text>\n </Stack>\n </Card>\n </Dialog>\n )}\n <Card\n padding={4}\n sizing=\"border\"\n style={{\n containerType: 'inline-size',\n }}\n >\n <Flex\n sizing=\"border\"\n gap={4}\n direction={['column', 'column', 'row']}\n align=\"flex-start\"\n ref={contentsRef}\n style={\n typeof containerHeight === 'number'\n ? {\n minHeight: containerHeight,\n }\n : undefined\n }\n >\n <Stack space={4} flex={1} sizing=\"border\">\n <VideoPlayer asset={props.asset} autoPlay={props.asset.autoPlay || false} />\n {tab === 'details' && (\n <TextTracksManager\n asset={props.asset}\n iconOnly\n collapseTracks\n tracks={\n displayInfo?.text_tracks ||\n props.asset.data?.tracks?.filter(\n (track): track is MuxTextTrack => track.type === 'text'\n ) ||\n []\n }\n />\n )}\n </Stack>\n <Stack space={4} flex={1} sizing=\"border\">\n <TabList space={2}>\n <Tab\n aria-controls=\"details-panel\"\n icon={EditIcon}\n id=\"details-tab\"\n label=\"Details\"\n onClick={() => setTab('details')}\n selected={tab === 'details'}\n />\n <Tab\n aria-controls=\"references-panel\"\n icon={SearchIcon}\n id=\"references-tab\"\n label={`Used by ${references ? `(${references.length})` : ''}`}\n onClick={() => setTab('references')}\n selected={tab === 'references'}\n />\n </TabList>\n <TabPanel\n aria-labelledby=\"details-tab\"\n id=\"details-panel\"\n hidden={tab !== 'details'}\n style={{wordBreak: 'break-word'}}\n >\n <Stack space={4}>\n <AssetInput\n label=\"Video title or file name\"\n description=\"Not visible to users. Useful for finding videos later.\"\n value={filename || ''}\n onInput={(e) => setFilename(e.currentTarget.value)}\n disabled={state !== 'idle'}\n />\n <Stack space={3}>\n {displayInfo?.duration && (\n <IconInfo\n text={`Duration: ${displayInfo.duration}`}\n icon={ClockIcon}\n size={2}\n />\n )}\n {displayInfo?.max_stored_resolution && (\n <IconInfo\n text={`Max Resolution: ${displayInfo.max_stored_resolution}`}\n icon={ResolutionIcon}\n size={2}\n />\n )}\n {displayInfo?.max_stored_frame_rate && (\n <IconInfo\n text={`Frame rate: ${displayInfo.max_stored_frame_rate}`}\n icon={StopWatchIcon}\n size={2}\n />\n )}\n {displayInfo?.aspect_ratio && (\n <IconInfo\n text={`Aspect Ratio: ${displayInfo.aspect_ratio}`}\n icon={CropIcon}\n size={2}\n />\n )}\n <IconInfo\n text={`Uploaded on: ${displayInfo.createdAt.toLocaleDateString('en', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n hour12: true,\n })}`}\n icon={CalendarIcon}\n size={2}\n />\n <IconInfo text={`Mux ID: \\n${displayInfo.id}`} icon={TagIcon} size={2} />\n <PlaybackIds playback_ids={displayInfo.playback_ids} />\n </Stack>\n </Stack>\n </TabPanel>\n <TabPanel\n aria-labelledby=\"references-tab\"\n id=\"references-panel\"\n hidden={tab !== 'references'}\n >\n <VideoReferences references={references} isLoaded={!referencesLoading} />\n </TabPanel>\n </Stack>\n </Flex>\n </Card>\n </Dialog>\n )\n}\n\nconst PlaybackIds = ({playback_ids}: {playback_ids?: MuxPlaybackId[]}) => {\n if (playback_ids) {\n return playback_ids.map((entry) => (\n <IconInfo\n key={entry.id}\n text={`Playback ID [${policyToText(entry.policy)}]: ${entry.id}`}\n icon={TagIcon}\n size={2}\n />\n ))\n }\n return <IconInfo text={'No Playback ID'} icon={TagIcon} size={2} />\n}\n\nconst policyToText = (policy: PlaybackPolicy) => {\n switch (policy) {\n case 'drm':\n return 'DRM'\n case 'signed':\n return 'Signed'\n case 'public':\n return 'Public'\n default:\n return policy\n }\n}\nexport default VideoDetails\n","import {CalendarIcon, ClockIcon, TagIcon} from '@sanity/icons'\nimport {Inline, Stack, Text} from '@sanity/ui'\n\nimport getVideoMetadata from '../util/getVideoMetadata'\nimport type {VideoAssetDocument} from '../util/types'\nimport IconInfo from './IconInfo'\n\nconst VideoMetadata = (props: {asset: VideoAssetDocument}) => {\n if (!props.asset) {\n return null\n }\n\n const displayInfo = getVideoMetadata(props.asset)\n return (\n <Stack space={2}>\n {displayInfo.title && (\n <Text\n size={1}\n weight=\"semibold\"\n style={{\n wordWrap: 'break-word',\n }}\n >\n {displayInfo.title}\n </Text>\n )}\n <Inline space={3}>\n {displayInfo?.duration && (\n <IconInfo text={displayInfo.duration} icon={ClockIcon} size={1} muted />\n )}\n <IconInfo\n text={displayInfo.createdAt.toISOString().split('T')[0]}\n icon={CalendarIcon}\n size={1}\n muted\n />\n {displayInfo.title != displayInfo.id.slice(0, 12) && (\n <IconInfo text={displayInfo.id.slice(0, 12)} icon={TagIcon} size={1} muted />\n )}\n </Inline>\n </Stack>\n )\n}\n\nexport default VideoMetadata\n","import {CheckmarkIcon, EditIcon, LockIcon, PlayIcon} from '@sanity/icons'\nimport {Button, Card, Stack, Text, Tooltip} from '@sanity/ui'\nimport React, {useState} from 'react'\nimport {styled} from 'styled-components'\n\nimport {DRMWarningDialog, useDrmPlaybackWarningContext} from '../context/DrmPlaybackWarningContext'\nimport {THUMBNAIL_ASPECT_RATIO} from '../util/constants'\nimport {getPlaybackPolicy} from '../util/getPlaybackPolicy'\nimport {VideoAssetDocument} from '../util/types'\nimport IconInfo from './IconInfo'\nimport {AudioIcon} from './icons/Audio'\nimport VideoMetadata from './VideoMetadata'\nimport VideoPlayer, {assetIsAudio} from './VideoPlayer'\nimport VideoThumbnail from './VideoThumbnail'\n\nconst PlayButton = styled.button`\n display: block;\n padding: 0;\n margin: 0;\n border: none;\n border-radius: 0.1875rem;\n position: relative;\n cursor: pointer;\n\n &::after {\n content: '';\n background: var(--card-fg-color);\n opacity: 0;\n display: block;\n position: absolute;\n inset: 0;\n z-index: 10;\n transition: 0.15s ease-out;\n border-radius: inherit;\n }\n\n > div[data-play] {\n z-index: 11;\n opacity: 0;\n transition: 0.15s 0.05s ease-out;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n color: var(--card-fg-color);\n background: var(--card-bg-color);\n width: auto;\n height: 30%;\n aspect-ratio: 1;\n border-radius: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n box-sizing: border-box;\n > svg {\n display: block;\n width: 70%;\n height: auto;\n // Visual balance to center-align the icon\n transform: translateX(5%);\n }\n }\n\n &:hover,\n &:focus {\n &::after {\n opacity: 0.3;\n }\n > div[data-play] {\n opacity: 1;\n }\n }\n`\n\ntype RenderState = 'render-video' | 'pre-render-warn' | false\n\nexport default function VideoInBrowser({\n onSelect,\n onEdit,\n asset,\n}: {\n onSelect?: (asset: VideoAssetDocument) => void\n onEdit?: (asset: VideoAssetDocument) => void\n asset: VideoAssetDocument\n}) {\n const [renderVideo, setRenderVideo] = useState<RenderState>(false)\n const select = React.useCallback(() => onSelect?.(asset), [onSelect, asset])\n const edit = React.useCallback(() => onEdit?.(asset), [onEdit, asset])\n const {hasShownWarning} = useDrmPlaybackWarningContext()\n\n if (!asset) {\n return null\n }\n\n const playbackPolicy = getPlaybackPolicy(asset)\n const onClickPlay = () => {\n if (playbackPolicy?.policy === 'drm' && !hasShownWarning) {\n setRenderVideo('pre-render-warn')\n } else {\n setRenderVideo('render-video')\n }\n }\n return (\n <Card\n border\n padding={2}\n sizing=\"border\"\n radius={2}\n style={{\n position: 'relative',\n }}\n >\n {playbackPolicy?.policy === 'signed' && (\n <Tooltip\n animate\n content={\n <Card padding={2} radius={2}>\n <IconInfo icon={LockIcon} text=\"Signed playback policy\" size={2} />\n </Card>\n }\n placement=\"right\"\n fallbackPlacements={['top', 'bottom']}\n portal\n >\n <Card\n tone=\"caution\"\n style={{\n borderRadius: '100%',\n position: 'absolute',\n left: '1em',\n top: '1em',\n zIndex: 11,\n }}\n padding={2}\n border\n >\n <Text muted size={1}>\n <LockIcon />\n </Text>\n </Card>\n </Tooltip>\n )}\n {playbackPolicy?.policy === 'drm' && (\n <Tooltip\n animate\n content={\n <Card padding={2} radius={2}>\n <IconInfo icon={LockIcon} text=\"DRM playback policy\" size={2} />\n </Card>\n }\n placement=\"right\"\n fallbackPlacements={['top', 'bottom']}\n portal\n >\n <Card\n tone=\"caution\"\n style={{\n borderRadius: '0.25rem',\n position: 'absolute',\n left: '1em',\n top: '1em',\n zIndex: 11,\n }}\n padding={2}\n border\n >\n <Text muted size={1} weight=\"semibold\" style={{color: 'var(--card-icon-color)'}}>\n DRM\n </Text>\n </Card>\n </Tooltip>\n )}\n <Stack\n space={3}\n height=\"fill\"\n style={{\n gridTemplateRows: 'min-content min-content 1fr',\n }}\n >\n {renderVideo === 'pre-render-warn' && (\n <DRMWarningDialog\n onClose={() => {\n setRenderVideo('render-video')\n }}\n />\n )}\n {renderVideo === 'render-video' ? (\n <VideoPlayer asset={asset} autoPlay forceAspectRatio={THUMBNAIL_ASPECT_RATIO} />\n ) : (\n <PlayButton onClick={onClickPlay}>\n <div data-play>\n <PlayIcon />\n </div>\n {assetIsAudio(asset) ? (\n <div\n style={{\n aspectRatio: THUMBNAIL_ASPECT_RATIO,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <AudioIcon width=\"3em\" height=\"3em\" />\n </div>\n ) : (\n <VideoThumbnail asset={asset} />\n )}\n </PlayButton>\n )}\n <VideoMetadata asset={asset} />\n <div\n style={{\n display: 'flex',\n width: '100%',\n alignItems: 'flex-end',\n justifyContent: 'flex-start',\n gap: '.35rem',\n }}\n >\n {onSelect && (\n <Button\n icon={CheckmarkIcon}\n fontSize={2}\n padding={2}\n mode=\"ghost\"\n text=\"Select\"\n style={{flex: 1}}\n tone=\"positive\"\n onClick={select}\n />\n )}\n <Button\n icon={EditIcon}\n fontSize={2}\n padding={2}\n mode=\"ghost\"\n text=\"Details\"\n style={{flex: 1}}\n onClick={edit}\n />\n </div>\n </Stack>\n </Card>\n )\n}\n","import {SearchIcon} from '@sanity/icons'\nimport {Card, Flex, Grid, Inline, Label, Stack, Text, TextInput} from '@sanity/ui'\nimport {useMemo, useState} from 'react'\n\nimport {DrmPlaybackWarningContextProvider} from '../context/DrmPlaybackWarningContext'\nimport useAssets from '../hooks/useAssets'\nimport type {PluginConfig, VideoAssetDocument} from '../util/types'\nimport ConfigureApi from './ConfigureApi'\nimport ImportVideosFromMux from './ImportVideosFromMux'\nimport PageSelector from './PageSelector'\nimport ResyncMetadata from './ResyncMetadata'\nimport {SelectSortOptions} from './SelectSortOptions'\nimport SpinnerBox from './SpinnerBox'\nimport type {VideoDetailsProps} from './VideoDetails/useVideoDetails'\nimport VideoDetails from './VideoDetails/VideoDetails'\nimport VideoInBrowser from './VideoInBrowser'\n\nexport interface VideosBrowserProps {\n config: PluginConfig\n onSelect?: (asset: VideoAssetDocument) => void\n}\n\nexport default function VideosBrowser({onSelect, config}: VideosBrowserProps) {\n const {assets, isLoading, searchQuery, setSearchQuery, setSort, sort} = useAssets()\n const [page, setPage] = useState<number>(0)\n const pageLimit = 20\n const pageTotal = Math.floor(assets.length / pageLimit) + 1\n const [editedAsset, setEditedAsset] = useState<VideoDetailsProps['asset'] | null>(null)\n const freshEditedAsset = useMemo(\n () => assets.find((a) => a._id === editedAsset?._id) || editedAsset,\n [editedAsset, assets]\n )\n\n const pageStart = page * pageLimit\n const pageEnd = pageStart + pageLimit\n\n const placement = onSelect ? 'input' : 'tool'\n return (\n <DrmPlaybackWarningContextProvider config={config}>\n <Stack padding={4} space={4} style={{minHeight: '50vh'}}>\n <Flex justify=\"space-between\" align=\"center\">\n <Flex align=\"center\" gap={3}>\n <TextInput\n value={searchQuery}\n icon={SearchIcon}\n onInput={(e: React.FormEvent<HTMLInputElement>) =>\n setSearchQuery(e.currentTarget.value)\n }\n placeholder=\"Search videos\"\n />\n <SelectSortOptions setSort={setSort} sort={sort} />\n <PageSelector page={page} setPage={setPage} total={pageTotal} />\n </Flex>\n {placement === 'tool' && (\n <Inline space={2}>\n <ImportVideosFromMux />\n <ResyncMetadata />\n <ConfigureApi />\n </Inline>\n )}\n </Flex>\n <Stack space={3}>\n {assets?.length > 0 && (\n <Label muted>\n {assets.length} video{assets.length > 1 ? 's' : null}{' '}\n {searchQuery ? `matching \"${searchQuery}\"` : 'found'}\n </Label>\n )}\n <Grid\n gap={2}\n style={{\n gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))',\n }}\n >\n {assets.slice(pageStart, pageEnd).map((asset) => (\n <VideoInBrowser\n key={asset._id}\n asset={asset}\n onEdit={setEditedAsset}\n onSelect={onSelect}\n />\n ))}\n </Grid>\n </Stack>\n {isLoading && <SpinnerBox />}\n\n {!isLoading && assets.length === 0 && (\n <Card marginY={4} paddingX={4} paddingY={6} border radius={2} tone=\"transparent\">\n <Text align=\"center\" muted size={3}>\n {searchQuery ? `No videos found for \"${searchQuery}\"` : 'No videos in this dataset'}\n </Text>\n </Card>\n )}\n </Stack>\n {freshEditedAsset && (\n <VideoDetails closeDialog={() => setEditedAsset(null)} asset={freshEditedAsset} />\n )}\n </DrmPlaybackWarningContextProvider>\n )\n}\n","import type {Tool} from 'sanity'\n\nimport type {PluginConfig} from '../util/types'\nimport ToolIcon from './icons/ToolIcon'\nimport VideosBrowser from './VideosBrowser'\n\nconst StudioTool: React.FC<PluginConfig> = (config) => {\n return <VideosBrowser config={config} />\n}\n\nexport const DEFAULT_TOOL_CONFIG = {\n icon: ToolIcon,\n title: 'Videos',\n}\n\nexport default function createStudioTool(config: PluginConfig): Tool {\n const toolConfig = typeof config.tool === 'object' ? config.tool : DEFAULT_TOOL_CONFIG\n return {\n name: 'mux',\n icon: toolConfig.icon || DEFAULT_TOOL_CONFIG.icon,\n title: toolConfig.title || DEFAULT_TOOL_CONFIG.title,\n component: (props: any) => <StudioTool {...config} {...props} />,\n }\n}\n","import {useCurrentUser} from 'sanity'\n\nimport {PluginConfig} from '../util/types'\n\nexport const useAccessControl = (config: PluginConfig) => {\n const user = useCurrentUser()\n\n const hasConfigAccess =\n !config?.allowedRolesForConfiguration?.length ||\n user?.roles?.some((role) => config.allowedRolesForConfiguration.includes(role.name))\n\n return {hasConfigAccess}\n}\n","import {isReference} from 'sanity'\nimport {useDocumentValues} from 'sanity'\n\nimport type {Reference, VideoAssetDocument} from '../util/types'\n\nconst path = ['assetId', 'data', 'playbackId', 'status', 'thumbTime', 'filename']\nexport const useAssetDocumentValues = (asset: Reference | null | undefined) =>\n useDocumentValues<VideoAssetDocument | null | undefined>(\n isReference(asset) ? asset._ref! : '',\n path\n )\n","import {useMemo} from 'react'\nimport {useDataset, useProjectId} from 'sanity'\nimport useSWR from 'swr'\n\nimport {useClient} from '../hooks/useClient'\nimport type {MuxAsset, VideoAssetDocument} from '../util/types'\n\n// Poll MUX if it's preparing the main document or its own static renditions\nexport const useMuxPolling = (asset?: VideoAssetDocument) => {\n const client = useClient()\n const projectId = useProjectId()\n const dataset = useDataset()\n const isPreparingStaticRenditions = useMemo(() => {\n // Legacy: If static_renditions has a status field, it was created with mp4_support (deprecated)\n // We don't process this old format, just return false\n // Note: 'disabled' status is valid in the new format when no renditions were requested\n if (\n asset?.data?.static_renditions?.status &&\n asset?.data?.static_renditions?.status !== 'disabled'\n ) {\n return false\n }\n\n const files = asset?.data?.static_renditions?.files\n if (!files || files.length === 0) {\n return false\n }\n return files.some((file) => file.status === 'preparing')\n }, [asset?.data?.static_renditions?.status, asset?.data?.static_renditions?.files])\n\n const shouldFetch = useMemo(\n () => !!asset?.assetId && (asset?.status === 'preparing' || isPreparingStaticRenditions),\n [asset?.assetId, asset?.status, isPreparingStaticRenditions]\n )\n return useSWR(\n shouldFetch ? `/${projectId}/addons/mux/assets/${dataset}/data/${asset?.assetId}` : null,\n async () => {\n const {data} = await client.request<{data: MuxAsset}>({\n url: `/addons/mux/assets/${dataset}/data/${asset!.assetId}`,\n withCredentials: true,\n method: 'GET',\n })\n client.patch(asset!._id!).set({status: data.status, data}).commit({returnDocuments: false})\n },\n {refreshInterval: 2000, refreshWhenHidden: true, dedupingInterval: 1000}\n )\n}\n","import r,{PureComponent as t,useReducer as e,useRef as n,useCallback as o}from\"react\";var c=function(r){var t,e;function n(t){var e;return(e=r.call(this,t)||this).state={hasError:!1,error:null},e}e=r,(t=n).prototype=Object.create(e.prototype),t.prototype.constructor=t,t.__proto__=e,n.getDerivedStateFromError=function(r){return{hasError:!0,error:r}};var o=n.prototype;return o.componentDidCatch=function(r,t){return this.props.onDidCatch(r,t)},o.render=function(){var r=this.state,t=this.props,e=t.render,n=t.children,o=t.renderError;return r.hasError?o?o({error:r.error}):null:e?e():n||null},n}(t),u=function(r,t){switch(t.type){case\"catch\":return{didCatch:!0,error:t.error};case\"reset\":return{didCatch:!1,error:null};default:return r}};function a(t){var a=e(u,{didCatch:!1,error:null}),i=a[0],d=a[1],h=n(null);function l(){return e=function(r,e){d({type:\"catch\",error:r}),t&&t.onDidCatch&&t.onDidCatch(r,e)},function(t){return r.createElement(c,{onDidCatch:e,children:t.children,render:t.render,renderError:t.renderError})};var e}var p,s=o(function(){h.current=l(),d({type:\"reset\"})},[]);return{ErrorBoundary:(p=h.current,null!==p?p:(h.current=l(),h.current)),didCatch:i.didCatch,error:i.error,reset:s}}export default a;export{a as useErrorBoundary};\n//# sourceMappingURL=index.module.js.map\n","/* eslint-disable no-console */\nimport {Button, Card, Flex, Grid, Heading, Inline, Text, useToast} from '@sanity/ui'\nimport React, {memo, useCallback, useRef} from 'react'\nimport scrollIntoView from 'scroll-into-view-if-needed'\nimport {clear} from 'suspend-react'\nimport {useErrorBoundary} from 'use-error-boundary'\n\nimport {name} from '../util/constants'\nimport {type MuxInputProps} from '../util/types'\n\nexport interface Props extends Pick<MuxInputProps, 'schemaType'> {\n children: React.ReactNode\n}\nfunction ErrorBoundaryCard(props: Props) {\n const {children, schemaType} = props\n const {push: pushToast} = useToast()\n const errorRef = useRef(null)\n const {ErrorBoundary, didCatch, error, reset} = useErrorBoundary({\n onDidCatch: (err, errorInfo) => {\n console.group(err.toString())\n console.groupCollapsed('console.error')\n console.error(err)\n console.groupEnd()\n if (err.stack) {\n console.groupCollapsed('error.stack')\n console.log(err.stack)\n console.groupEnd()\n }\n if (errorInfo?.componentStack) {\n console.groupCollapsed('errorInfo.componentStack')\n console.log(errorInfo.componentStack)\n console.groupEnd()\n }\n console.groupEnd()\n pushToast({\n status: 'error',\n title: 'Plugin crashed',\n description: (\n <Flex align=\"center\">\n <Inline space={1}>\n An error happened while rendering\n <Button\n padding={1}\n fontSize={1}\n style={{transform: 'translateY(1px)'}}\n mode=\"ghost\"\n text={schemaType.title}\n onClick={() => {\n if (errorRef.current) {\n scrollIntoView(errorRef.current, {\n behavior: 'smooth',\n scrollMode: 'if-needed',\n block: 'center',\n })\n }\n }}\n />\n </Inline>\n </Flex>\n ),\n })\n },\n })\n const handleRetry = useCallback(() => {\n // Purge request cache before retrying, otherwise the cached errors will rethrow\n clear([name])\n\n reset()\n }, [reset])\n\n if (didCatch) {\n return (\n <Card ref={errorRef} paddingX={[2, 3, 4, 4]} height=\"fill\" shadow={1} overflow=\"auto\">\n <Flex justify=\"flex-start\" align=\"center\" height=\"fill\">\n <Grid columns={1} gap={[2, 3, 4, 4]}>\n <Heading as=\"h1\">\n The <code>{name}</code> plugin crashed\n </Heading>\n {error?.message && (\n <Card padding={3} tone=\"critical\" shadow={1} radius={2}>\n <Text>{error.message}</Text>\n </Card>\n )}\n <Inline>\n <Button onClick={handleRetry} text=\"Retry\" />\n </Inline>\n </Grid>\n </Flex>\n </Card>\n )\n }\n\n return <ErrorBoundary>{children}</ErrorBoundary>\n}\n\nexport default memo(ErrorBoundaryCard)\n","import {Box, Card, Flex, Spinner, Text} from '@sanity/ui'\n\nexport const InputFallback = () => {\n return (\n <div style={{padding: 1}}>\n <Card\n shadow={1}\n sizing=\"border\"\n style={{aspectRatio: '16/9', width: '100%', borderRadius: '1px'}}\n >\n <Flex align=\"center\" direction=\"column\" height=\"fill\" justify=\"center\">\n <Spinner muted />\n <Box marginTop={3}>\n <Text align=\"center\" muted size={1}>\n Loading…\n </Text>\n </Box>\n </Flex>\n </Card>\n </div>\n )\n}\n","import {PlugIcon} from '@sanity/icons'\nimport {Button, Card, Flex, Grid, Heading, Inline, Text} from '@sanity/ui'\nimport {useCallback} from 'react'\n\nimport {useAccessControl} from '../hooks/useAccessControl'\nimport type {SetDialogState} from '../hooks/useDialogState'\nimport {PluginConfig} from '../util/types'\nimport MuxLogo from './MuxLogo'\n\ninterface OnboardProps {\n setDialogState: SetDialogState\n config: PluginConfig\n}\n\nexport default function Onboard(props: OnboardProps) {\n const {setDialogState} = props\n const handleOpen = useCallback(() => setDialogState('secrets'), [setDialogState])\n const {hasConfigAccess} = useAccessControl(props.config)\n\n return (\n <>\n <div style={{padding: 2}}>\n <Card\n display=\"flex\"\n sizing=\"border\"\n style={{\n aspectRatio: '16/9',\n width: '100%',\n boxShadow: 'var(--card-bg-color) 0 0 0 2px',\n }}\n paddingX={[2, 3, 4, 4]}\n radius={1}\n tone=\"transparent\"\n >\n <Flex justify=\"flex-start\" align=\"center\">\n <Grid columns={1} gap={[2, 3, 4, 4]}>\n <Inline paddingY={1}>\n <div style={{height: '32px'}}>\n <MuxLogo />\n </div>\n </Inline>\n <Inline paddingY={1}>\n <Heading size={[0, 1, 2, 2]}>\n Upload and preview videos directly from your studio.\n </Heading>\n </Inline>\n <Inline paddingY={1}>\n {hasConfigAccess ? (\n <Button mode=\"ghost\" icon={PlugIcon} text=\"Configure API\" onClick={handleOpen} />\n ) : (\n <Card padding={[3, 3, 3]} radius={2} shadow={1} tone=\"critical\">\n <Text>\n You do not have access to configure the Mux API. Please contact your\n administrator.\n </Text>\n </Card>\n )}\n </Inline>\n </Grid>\n </Flex>\n </Card>\n </div>\n </>\n )\n}\n","import {UpChunk} from '@mux/upchunk'\nimport {Observable} from 'rxjs'\n\nexport function createUpChunkObservable(uuid: string, uploadUrl: string, source: File) {\n return new Observable<\n | {type: 'pause' | 'resume'; id: string}\n | {type: 'success'; id: string}\n | {type: 'progress'; percent: number}\n >((subscriber) => {\n const upchunk = UpChunk.createUpload({\n endpoint: uploadUrl,\n file: source,\n dynamicChunkSize: true, // changes the chunk size based on network speeds\n })\n\n const successHandler = () => {\n subscriber.next({\n type: 'success',\n id: uuid,\n })\n subscriber.complete()\n }\n\n const errorHandler = (data: CustomEvent) => subscriber.error(new Error(data.detail.message))\n\n const progressHandler = (data: CustomEvent) => {\n return subscriber.next({type: 'progress', percent: data.detail})\n }\n\n const offlineHandler = () => {\n upchunk.pause()\n subscriber.next({\n type: 'pause',\n id: uuid,\n })\n }\n\n const onlineHandler = () => {\n upchunk.resume()\n subscriber.next({\n type: 'resume',\n id: uuid,\n })\n }\n\n upchunk.on('success', successHandler)\n upchunk.on('error', errorHandler)\n upchunk.on('progress', progressHandler)\n upchunk.on('offline', offlineHandler)\n upchunk.on('online', onlineHandler)\n\n return () => upchunk.abort()\n })\n}\n","/**\n * Rounds the numeric part of a px string to the nearest integer.\n * Returns undefined if the value is not a valid px string or not a finite number.\n * Avoids sending 0px (and JS -0); snaps to ±1 instead.\n */\nexport function roundPxString(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n if (!trimmed.endsWith('px')) return undefined\n const n = Number(trimmed.slice(0, -2))\n if (!Number.isFinite(n)) return undefined\n let rounded = Math.round(n)\n // Avoid sending 0px (and JS -0); keep sign when negative.\n if (rounded === 0) rounded = n < 0 ? -1 : 1\n return `${rounded}px`\n}\n","import {uuid as generateUuid} from '@sanity/uuid'\nimport {concat, defer, from, type Observable, of, throwError} from 'rxjs'\nimport {catchError, mergeMap, mergeMapTo, switchMap} from 'rxjs/operators'\nimport type {SanityClient} from 'sanity'\n\nimport {createUpChunkObservable} from '../clients/upChunkObservable'\nimport {roundPxString} from '../util/roundPxString'\nimport type {MuxAsset, MuxNewAssetSettings, WatermarkConfig} from '../util/types'\nimport {getAsset} from './assets'\nimport {testSecretsObservable} from './secrets'\n\nfunction sanitizeOverlaySettingsInPlace(settings: MuxNewAssetSettings) {\n const inputs = settings.input\n if (!inputs) return\n for (const input of inputs) {\n const overlay = (input as {overlay_settings?: Record<string, unknown>}).overlay_settings\n if (!overlay) continue\n\n const hm = roundPxString(overlay.horizontal_margin)\n const vm = roundPxString(overlay.vertical_margin)\n const w = roundPxString(overlay.width)\n\n if (hm) overlay.horizontal_margin = hm\n if (vm) overlay.vertical_margin = vm\n if (w) overlay.width = w\n }\n}\n\nfunction sanitizePxStringsInJson(json: string): string {\n return json.replace(/\"(-?\\d+(?:\\.\\d+)?)px\"/g, (_match, num) => {\n const n = Number(num)\n if (!Number.isFinite(n)) return _match\n let rounded = Math.round(n)\n if (rounded === 0) rounded = n < 0 ? -1 : 1\n return `\"${rounded}px\"`\n })\n}\n\nexport function cancelUpload(client: SanityClient, uuid: string) {\n return client.observable.request({\n url: `/addons/mux/uploads/${client.config().dataset}/${uuid}`,\n withCredentials: true,\n method: 'DELETE',\n })\n}\n\nexport function uploadUrl({\n url,\n settings,\n client,\n watermark,\n}: {\n url: string\n settings: MuxNewAssetSettings\n client: SanityClient\n watermark?: WatermarkConfig\n}) {\n return testUrl(url).pipe(\n switchMap((validUrl) => {\n return concat(\n of({type: 'url' as const, url: validUrl}),\n testSecretsObservable(client).pipe(\n switchMap((json) => {\n if (!json || !json.status) {\n return throwError(new Error('Invalid credentials'))\n }\n const uuid = generateUuid()\n const muxBody = settings\n if (!muxBody.input) muxBody.input = [{type: 'video'}]\n muxBody.input[0].url = validUrl\n sanitizeOverlaySettingsInPlace(muxBody)\n\n const query = {\n muxBody: sanitizePxStringsInJson(JSON.stringify(muxBody)),\n filename: validUrl.split('/').slice(-1)[0],\n }\n\n const dataset = client.config().dataset\n return defer(() =>\n client.observable.request({\n url: `/addons/mux/assets/${dataset}`,\n withCredentials: true,\n method: 'POST',\n headers: {\n 'MUX-Proxy-UUID': uuid,\n 'Content-Type': 'application/json',\n },\n query,\n })\n ).pipe(\n mergeMap((result) => {\n const asset =\n (result && result.results && result.results[0] && result.results[0].document) ||\n null\n\n if (!asset) {\n return throwError(new Error('No asset document returned'))\n }\n return of({type: 'success' as const, id: uuid, asset})\n })\n )\n })\n )\n )\n })\n )\n}\n\nexport function uploadFile({\n settings,\n client,\n file,\n watermark,\n}: {\n settings: MuxNewAssetSettings\n client: SanityClient\n file: File\n watermark?: WatermarkConfig\n}) {\n return testFile(file).pipe(\n switchMap((fileOptions) => {\n return concat(\n of({type: 'file' as const, file: fileOptions}),\n testSecretsObservable(client).pipe(\n switchMap((json) => {\n if (!json || !json.status) {\n return throwError(() => new Error('Invalid credentials'))\n }\n const uuid = generateUuid()\n const body = settings\n sanitizeOverlaySettingsInPlace(body)\n\n return concat(\n of({type: 'uuid' as const, uuid}),\n defer(() =>\n client.observable.request<{\n sanityAssetId: string\n upload: {\n cors_origin: string\n id: string\n new_asset_settings: MuxNewAssetSettings\n status: 'waiting'\n timeout: number\n url: string\n }\n }>({\n url: `/addons/mux/uploads/${client.config().dataset}`,\n withCredentials: true,\n method: 'POST',\n headers: {\n 'MUX-Proxy-UUID': uuid,\n 'Content-Type': 'application/json',\n },\n body,\n })\n ).pipe(\n mergeMap((result) => {\n return createUpChunkObservable(uuid, result.upload.url, file).pipe(\n // eslint-disable-next-line no-warning-comments\n // @TODO type the observable events\n // eslint-disable-next-line max-nested-callbacks\n mergeMap((event) => {\n if (event.type !== 'success') {\n return of(event)\n }\n return from(updateAssetDocumentFromUpload(client, uuid, watermark)).pipe(\n // eslint-disable-next-line max-nested-callbacks\n mergeMap((doc) => of({...event, asset: doc}))\n )\n }),\n // eslint-disable-next-line max-nested-callbacks\n catchError((err) => {\n // Delete asset document\n return cancelUpload(client, uuid).pipe(mergeMapTo(throwError(err)))\n })\n )\n })\n )\n )\n })\n )\n )\n })\n )\n}\n\ntype UploadResponse = {\n data: {\n asset_id: string\n cors_origin: string\n id: string\n new_asset_settings: {\n static_renditions?: {resolution: string}[]\n passthrough: string\n playback_policies: ['public' | 'signed' | 'drm']\n }\n status: string\n timeout: number\n }\n}\nexport function getUpload(client: SanityClient, assetId: string) {\n const {dataset} = client.config()\n return client.request<UploadResponse>({\n url: `/addons/mux/uploads/${dataset}/${assetId}`,\n withCredentials: true,\n method: 'GET',\n })\n}\n\nfunction pollUpload(client: SanityClient, uuid: string): Promise<UploadResponse> {\n const maxTries = 10\n let pollInterval: number\n let tries = 0\n let assetId: string\n let upload: UploadResponse\n return new Promise((resolve, reject) => {\n pollInterval = (setInterval as typeof window.setInterval)(async () => {\n try {\n upload = await getUpload(client, uuid)\n } catch (err) {\n reject(err)\n return\n }\n assetId = upload && upload.data && upload.data.asset_id\n if (assetId) {\n clearInterval(pollInterval)\n resolve(upload)\n }\n if (tries > maxTries) {\n clearInterval(pollInterval)\n reject(new Error('Upload did not finish'))\n }\n tries++\n }, 2000)\n })\n}\n\nasync function updateAssetDocumentFromUpload(\n client: SanityClient,\n uuid: string,\n _watermark?: WatermarkConfig\n) {\n let upload: UploadResponse\n let asset: {data: MuxAsset}\n try {\n upload = await pollUpload(client, uuid)\n } catch (err) {\n return Promise.reject(err)\n }\n try {\n asset = await getAsset(client, upload.data.asset_id)\n } catch (err) {\n return Promise.reject(err)\n }\n\n const doc = {\n _id: uuid,\n _type: 'mux.videoAsset',\n status: asset.data.status,\n data: asset.data,\n assetId: asset.data.id,\n playbackId: asset.data.playback_ids[0].id,\n uploadId: upload.data.id,\n }\n return client.createOrReplace(doc).then(() => {\n return doc\n })\n}\n\nexport function testFile(file: File) {\n if (typeof window !== 'undefined' && file instanceof window.File) {\n const fileOptions = optionsFromFile({}, file)\n return of(fileOptions)\n }\n return throwError(new Error('Invalid file'))\n}\n\nexport function testUrl(url: string): Observable<string> {\n const error = new Error('Invalid URL')\n if (typeof url !== 'string') {\n return throwError(error)\n }\n const trimmedUrl = url.trim()\n let parsed\n try {\n parsed = new URL(trimmedUrl)\n } catch (err) {\n return throwError(error)\n }\n if (parsed && !parsed.protocol.match(/http:|https:/)) {\n return throwError(error)\n }\n return of(trimmedUrl)\n}\n\nfunction optionsFromFile(opts: {preserveFilename?: boolean}, file: File) {\n if (typeof window === 'undefined' || !(file instanceof window.File)) {\n return undefined\n }\n return {\n name: opts.preserveFilename === false ? undefined : file.name,\n type: file.type,\n }\n}\n","import {ServerError} from '@sanity/client'\nimport {type InputProps, isObjectInputProps, type PreviewLayoutKey, type PreviewProps} from 'sanity'\n\nimport type {MuxInputPreviewProps, MuxInputProps} from './types'\n\nexport function isMuxInputProps(props: InputProps): props is MuxInputProps {\n return isObjectInputProps(props) && props.schemaType.type?.name === 'mux.video'\n}\n\nexport function isMuxInputPreviewProps(\n props: PreviewProps<PreviewLayoutKey>\n): props is MuxInputPreviewProps {\n return props.schemaType?.type?.name === 'mux.video'\n}\n\nexport function isValidUrl(url: string): boolean {\n try {\n const parsed = new URL(url)\n return parsed && !!parsed.protocol.match(/http:|https:/)\n } catch {\n return false\n }\n}\n\n/**\n * We consider a server error one with status code 5XX.\n * Used mainly to handle unknown Proxy issues.\n */\nexport function isServerError(error: Error): error is ServerError {\n return (\n 'statusCode' in error &&\n typeof error.statusCode === 'number' &&\n 500 <= error.statusCode &&\n error.statusCode <= 600\n )\n}\n","/**\n * Utilities for extracting files from dataTransfer in a predictable cross-browser fashion.\n * Also recursively extracts files from a directory\n * Inspired by https://github.com/component/normalized-upload\n */\n\nexport function extractDroppedFiles(dataTransfer: DataTransfer) {\n const files = Array.from(dataTransfer.files || [])\n const items = Array.from(dataTransfer.items || [])\n if (files && files.length > 0) {\n return Promise.resolve(files)\n }\n return normalizeItems(items).then((arr) => arr.flat())\n}\n\nfunction normalizeItems(items: DataTransferItem[]) {\n return Promise.all(\n items.map((item) => {\n // directory\n if (item.kind === 'file' && item.webkitGetAsEntry) {\n let entry: FileSystemEntry | File[] | null\n // Edge throws\n try {\n entry = item.webkitGetAsEntry()\n } catch (err) {\n return [item.getAsFile()]\n }\n if (!entry) {\n return []\n }\n return entry.isDirectory ? walk(entry) : [item.getAsFile()]\n }\n\n // file\n if (item.kind === 'file') {\n const file = item.getAsFile()\n return Promise.resolve(file ? [file] : [])\n }\n\n // others\n return new Promise((resolve) => item.getAsString(resolve)).then((str?: any) =>\n str ? [new File([str], 'unknown.txt', {type: item.type})] : []\n )\n })\n )\n}\n\nfunction isFile(entry: FileSystemEntry): entry is FileSystemFileEntry {\n return entry.isFile\n}\nfunction isDirectory(entry: FileSystemEntry): entry is FileSystemDirectoryEntry {\n return entry.isDirectory\n}\n\nfunction walk(entry: FileSystemEntry): any {\n if (isFile(entry)) {\n return new Promise((resolve) => entry.file(resolve)).then((file) => [file])\n }\n\n if (isDirectory(entry)) {\n const dir = entry.createReader()\n return new Promise<any>((resolve) => dir.readEntries(resolve))\n .then((entries: FileSystemEntry[]) => entries.filter((entr) => !entr.name.startsWith('.')))\n .then((entries) => Promise.all(entries.map(walk)).then((arr) => arr.flat()))\n }\n return Promise.resolve([])\n}\n","import {useCallback} from 'react'\nimport {PatchEvent, set, setIfMissing, unset} from 'sanity'\n\nimport type {SetDialogState} from '../hooks/useDialogState'\nimport type {MuxInputProps, PluginConfig, VideoAssetDocument} from '../util/types'\nimport VideosBrowser, {type VideosBrowserProps} from './VideosBrowser'\n\nexport interface Props extends Pick<MuxInputProps, 'onChange'> {\n asset?: VideoAssetDocument | null | undefined\n setDialogState: SetDialogState\n config: PluginConfig\n}\n\nexport default function SelectAssets({\n asset: selectedAsset,\n onChange,\n setDialogState,\n config,\n}: Props) {\n const handleSelect = useCallback<Required<VideosBrowserProps>['onSelect']>(\n (chosenAsset) => {\n if (!chosenAsset?._id) {\n onChange(PatchEvent.from([unset(['asset'])]))\n }\n if (chosenAsset._id !== selectedAsset?._id) {\n onChange(\n PatchEvent.from([\n setIfMissing({asset: {}, _type: 'mux.video'}),\n set({_type: 'reference', _weak: true, _ref: chosenAsset._id}, ['asset']),\n ])\n )\n }\n setDialogState(false)\n },\n [onChange, setDialogState, selectedAsset]\n )\n\n return <VideosBrowser onSelect={handleSelect} config={config} />\n}\n","import {Dialog} from '@sanity/ui'\nimport {useCallback, useId} from 'react'\nimport {styled} from 'styled-components'\n\nimport type {SetDialogState} from '../hooks/useDialogState'\nimport SelectAsset, {type Props as SelectAssetProps} from './SelectAsset'\n\n/** To prevent Content Layout Shift (CLS), ensure that the dialog always occupies the entire available height. */\nconst StyledDialog = styled(Dialog)`\n > div[data-ui='DialogCard'] > div[data-ui='Card'] {\n height: 100%;\n }\n`\n\nexport default function InputBrowser({\n setDialogState,\n asset,\n onChange,\n config,\n}: Pick<SelectAssetProps, 'onChange' | 'asset' | 'config'> & {\n setDialogState: SetDialogState\n}) {\n const id = `InputBrowser${useId()}`\n const handleClose = useCallback(() => setDialogState(false), [setDialogState])\n return (\n <StyledDialog\n __unstable_autoFocus\n header=\"Select video\"\n id={id}\n onClose={handleClose}\n width={2}\n >\n <SelectAsset\n config={config}\n asset={asset}\n onChange={onChange}\n setDialogState={setDialogState}\n />\n </StyledDialog>\n )\n}\n","import {useCallback} from 'react'\nimport {PatchEvent, unset} from 'sanity'\n\nimport {deleteAssetOnMux} from '../actions/assets'\nimport {useClient} from '../hooks/useClient'\nimport type {MuxInputProps, VideoAssetDocument} from '../util/types'\n\nexport const useCancelUpload = (asset: VideoAssetDocument, onChange: MuxInputProps['onChange']) => {\n const client = useClient()\n return useCallback(() => {\n if (!asset) {\n return\n }\n onChange(PatchEvent.from(unset()))\n if (asset.assetId) {\n deleteAssetOnMux(client, asset.assetId)\n }\n if (asset._id) {\n client.delete(asset._id)\n }\n }, [asset, client, onChange])\n}\n","import {Suspense, useState} from 'react'\nimport {styled} from 'styled-components'\n\nimport {useClient} from '../hooks/useClient'\nimport {getStoryboardSrc} from '../util/getStoryboardSrc'\nimport type {VideoAssetDocument} from '../util/types'\n\nexport const StyledCenterControls = styled.div`\n && {\n --media-background-color: transparent;\n --media-button-icon-width: 100%;\n --media-button-icon-height: auto;\n pointer-events: none;\n width: 100%;\n display: flex;\n flex-flow: row;\n align-items: center;\n justify-content: center;\n media-play-button {\n --media-control-background: transparent;\n --media-control-hover-background: transparent;\n padding: 0;\n width: max(27px, min(9%, 90px));\n }\n }\n`\n\nexport const TopControls = styled.div`\n position: absolute;\n top: 0;\n right: 0;\n justify-content: flex-end;\n button {\n height: auto;\n }\n`\n\nexport interface PosterImageProps {\n asset: VideoAssetDocument\n}\nexport interface ThumbnailsMetadataTrackProps {\n asset: VideoAssetDocument\n}\nexport function ThumbnailsMetadataTrack({asset}: ThumbnailsMetadataTrackProps) {\n const client = useClient()\n // Why useState instead of useMemo? Because we really really only want to run it exactly once and useMemo doesn't make that guarantee\n const [src] = useState<string>(() => getStoryboardSrc({asset, client}))\n\n return (\n /* We use Suspense here because `getStoryboardSrc` uses suspend() under the hood */\n <Suspense fallback={null}>\n <track label=\"thumbnails\" default kind=\"metadata\" src={src} />\n </Suspense>\n )\n}\n","// Lifted from sanity/form/inputs/files/common/UploadProgress\n\nimport {Button, Card, Code, Flex, Inline, Stack, Text} from '@sanity/ui'\nimport {LinearProgress} from 'sanity'\nimport {styled} from 'styled-components'\n\nexport const CardWrapper = styled(Card)`\n min-height: 82px;\n box-sizing: border-box;\n`\n\nexport const FlexWrapper = styled(Flex)`\n text-overflow: ellipsis;\n overflow: hidden;\n`\n\nexport const LeftSection = styled(Stack)`\n position: relative;\n width: 60%;\n`\n\nexport const CodeWrapper = styled(Code)`\n position: relative;\n width: 100%;\n\n code {\n overflow: hidden;\n text-overflow: ellipsis;\n position: relative;\n max-width: 200px;\n }\n`\n\nexport const UploadProgress = ({\n progress = 100,\n onCancel,\n filename,\n text = 'Uploading',\n}: {\n progress: number\n filename?: React.ReactNode\n onCancel?: React.MouseEventHandler<HTMLButtonElement>\n text?: React.ReactNode\n}) => {\n // Disable cancel button when upload is 90% or more complete\n // to prevent inconsistency between Mux and Sanity\n const isCancelDisabled = progress >= 90\n\n return (\n <CardWrapper tone=\"primary\" padding={4} border height=\"fill\">\n <FlexWrapper align=\"center\" justify=\"space-between\" height=\"fill\" direction=\"row\" gap={2}>\n <LeftSection>\n <Flex justify=\"center\" gap={[3, 3, 2, 2]} direction={['column', 'column', 'row']}>\n <Text size={1}>\n <Inline space={2}>\n {text}\n <CodeWrapper size={1}>{filename ? filename : '...'}</CodeWrapper>\n </Inline>\n </Text>\n </Flex>\n\n <Card marginTop={3} radius={5} shadow={1}>\n <LinearProgress value={progress} />\n </Card>\n </LeftSection>\n\n {onCancel ? (\n <Button\n fontSize={2}\n text=\"Cancel upload\"\n mode=\"ghost\"\n tone=\"critical\"\n onClick={onCancel}\n disabled={isCancelDisabled}\n />\n ) : null}\n </FlexWrapper>\n </CardWrapper>\n )\n}\n","import {Card, Text} from '@sanity/ui'\nimport React, {useEffect, useMemo, useRef} from 'react'\n\nimport {useCancelUpload} from '../hooks/useCancelUpload'\nimport type {MuxInputProps, PluginConfig, VideoAssetDocument} from '../util/types'\nimport {TopControls} from './Player.styled'\nimport {UploadProgress} from './UploadProgress'\nimport VideoPlayer from './VideoPlayer'\n\ninterface Props extends Pick<MuxInputProps, 'onChange' | 'readOnly'> {\n buttons?: React.ReactNode\n asset: VideoAssetDocument\n config?: PluginConfig\n}\n\nconst Player = ({asset, buttons, readOnly, onChange, config}: Props) => {\n const isLoading = useMemo<boolean | string>(() => {\n if (asset?.status === 'preparing') {\n return 'Preparing the video'\n }\n if (asset?.status === 'waiting_for_upload') {\n return 'Waiting for upload to start'\n }\n if (asset?.status === 'waiting') {\n return 'Processing upload'\n }\n if (asset?.status === 'ready') {\n return false\n }\n if (typeof asset?.status === 'undefined') {\n return false\n }\n\n return true\n }, [asset])\n const isPreparingStaticRenditions = useMemo<boolean>(() => {\n // Legacy: If static_renditions has a status field, it was created with mp4_support (deprecated)\n // We don't process this old format, just return false\n // Note: 'disabled' status is valid in the new format when no renditions were requested\n if (\n asset?.data?.static_renditions?.status &&\n asset?.data?.static_renditions?.status !== 'disabled'\n ) {\n return false\n }\n\n // Check if any file in static_renditions is still preparing\n const files = asset?.data?.static_renditions?.files\n if (!files || files.length === 0) {\n return false\n }\n return files.some((file) => file.status === 'preparing')\n }, [asset?.data?.static_renditions?.status, asset?.data?.static_renditions?.files])\n const playRef = useRef<HTMLDivElement>(null)\n const muteRef = useRef<HTMLDivElement>(null)\n const handleCancelUpload = useCancelUpload(asset, onChange)\n\n useEffect(() => {\n const style = document.createElement('style')\n style.innerHTML = 'button svg { vertical-align: middle; }'\n\n if (playRef.current?.shadowRoot) {\n playRef.current.shadowRoot.appendChild(style)\n }\n if (muteRef?.current?.shadowRoot) {\n muteRef.current.shadowRoot.appendChild(style.cloneNode(true))\n }\n }, [])\n\n useEffect(() => {\n if (asset?.status === 'errored') {\n handleCancelUpload()\n // eslint-disable-next-line no-warning-comments\n // @TODO use better error handling\n throw new Error(asset.data?.errors?.messages?.join(' '))\n }\n }, [asset.data?.errors?.messages, asset?.status, handleCancelUpload])\n\n if (!asset || !asset.status) {\n return null\n }\n\n if (isLoading) {\n return (\n <UploadProgress\n progress={100}\n filename={asset?.filename}\n text={(isLoading !== true && isLoading) || 'Waiting for Mux to complete the upload'}\n onCancel={readOnly ? undefined : () => handleCancelUpload()}\n />\n )\n }\n\n return (\n <VideoPlayer asset={asset} hlsConfig={config?.hlsConfig}>\n {buttons && <TopControls slot=\"top-chrome\">{buttons}</TopControls>}\n {isPreparingStaticRenditions && (\n <Card\n padding={2}\n radius={1}\n style={{\n background: 'var(--card-fg-color)',\n position: 'absolute',\n top: '0.5em',\n left: '0.5em',\n }}\n >\n <Text size={1} style={{color: 'var(--card-bg-color)'}}>\n MUX is preparing static renditions, please stand by\n </Text>\n </Card>\n )}\n </VideoPlayer>\n )\n}\n\nexport default Player\n","// todo: get these utils from @sanity/ui instead\nexport function focusRingBorderStyle(border: {color: string; width: number}): string {\n return `inset 0 0 0 ${border.width}px ${border.color}`\n}\n\nexport function focusRingStyle(opts: {\n base?: {bg: string}\n border?: {color: string; width: number}\n focusRing: {offset: number; width: number}\n}): string {\n const {base, border, focusRing} = opts\n const focusRingOutsetWidth = focusRing.offset + focusRing.width\n const focusRingInsetWidth = 0 - focusRing.offset\n const bgColor = base ? base.bg : 'var(--card-bg-color)'\n\n return [\n focusRingInsetWidth > 0 && `inset 0 0 0 ${focusRingInsetWidth}px var(--card-focus-ring-color)`,\n border && focusRingBorderStyle(border),\n focusRingInsetWidth < 0 && `0 0 0 ${0 - focusRingInsetWidth}px ${bgColor}`,\n focusRingOutsetWidth > 0 && `0 0 0 ${focusRingOutsetWidth}px var(--card-focus-ring-color)`,\n ]\n .filter(Boolean)\n .join(',')\n}\n","import {MenuItem} from '@sanity/ui'\nimport {css, styled} from 'styled-components'\n\nimport {focusRingStyle} from './withFocusRing/helpers'\n\nexport const FileButton = styled(MenuItem)(({theme}) => {\n const {focusRing} = theme.sanity\n const base = theme.sanity.color.base\n const border = {width: 1, color: 'var(--card-border-color)'}\n\n return css`\n position: relative;\n\n &:not([data-disabled='true']) {\n &:focus-within {\n box-shadow: ${focusRingStyle({base, border, focusRing})};\n }\n }\n\n & input {\n overflow: hidden;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n position: absolute;\n min-width: 0;\n display: block;\n appearance: none;\n padding: 0;\n margin: 0;\n border: 0;\n opacity: 0;\n }\n `\n})\n","import {Box, ButtonProps, Flex, Text} from '@sanity/ui'\nimport React, {createElement, isValidElement, useId} from 'react'\nimport {isValidElementType} from 'react-is'\n\nimport {FileButton} from './FileInputMenuItem.styled'\n\nexport interface FileInputMenuItemProps extends ButtonProps {\n accept?: string\n capture?: 'user' | 'environment'\n multiple?: boolean\n onSelect?: (files: File[]) => void\n disabled?: boolean\n}\n\nexport const FileInputMenuItem = React.forwardRef(function FileInputMenuItem(\n props: FileInputMenuItemProps &\n Omit<React.HTMLProps<HTMLButtonElement>, 'as' | 'ref' | 'type' | 'value' | 'onSelect'>,\n forwardedRef: React.ForwardedRef<HTMLInputElement>\n) {\n const {\n icon,\n id: idProp,\n accept,\n capture,\n fontSize,\n multiple,\n onSelect,\n space = 3,\n textAlign,\n text,\n disabled,\n ...rest\n } = props\n const idHook = useId()\n const id = idProp || idHook\n\n const handleChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n if (onSelect && event.target.files) {\n onSelect(Array.from(event.target.files))\n }\n },\n [onSelect]\n )\n\n const content = (\n <Flex align=\"center\" justify=\"flex-start\">\n {/* Icon */}\n {icon && (\n <Box marginRight={text ? space : undefined}>\n <Text size={fontSize}>\n {isValidElement(icon) && icon}\n {isValidElementType(icon) && createElement(icon)}\n </Text>\n </Box>\n )}\n\n {/* Text */}\n {text && (\n <Text align={textAlign} size={fontSize} textOverflow=\"ellipsis\">\n {text}\n </Text>\n )}\n </Flex>\n )\n\n return (\n <FileButton {...rest} htmlFor={id} disabled={disabled} ref={forwardedRef}>\n {content}\n\n {/* Visibly hidden input */}\n <input\n data-testid=\"file-button-input\"\n accept={accept}\n capture={capture}\n id={id}\n multiple={multiple}\n onChange={handleChange}\n type=\"file\"\n value=\"\"\n disabled={disabled}\n />\n </FileButton>\n )\n})\n","import {\n EllipsisHorizontalIcon,\n ImageIcon,\n LockIcon,\n PlugIcon,\n ResetIcon,\n SearchIcon,\n SyncIcon,\n TranslateIcon,\n UploadIcon,\n} from '@sanity/icons'\nimport {\n Box,\n Button,\n Card,\n Inline,\n Label,\n Menu,\n MenuDivider,\n MenuItem,\n Popover,\n Text,\n Tooltip,\n useClickOutsideEvent,\n} from '@sanity/ui'\nimport {memo, useCallback, useEffect, useMemo, useState} from 'react'\nimport {PatchEvent, unset} from 'sanity'\nimport {styled} from 'styled-components'\n\nimport {useAccessControl} from '../hooks/useAccessControl'\nimport {type DialogState, type SetDialogState} from '../hooks/useDialogState'\nimport {useResyncAsset} from '../hooks/useResyncAsset'\nimport {getPlaybackPolicy} from '../util/getPlaybackPolicy'\nimport type {MuxInputProps, PluginConfig, VideoAssetDocument} from '../util/types'\nimport {FileInputMenuItem} from './FileInputMenuItem'\n\nconst LockCard = styled(Card)`\n position: absolute;\n top: 0;\n left: 0;\n opacity: 0.6;\n mix-blend-mode: screen;\n background: transparent;\n`\n\nconst LockButton = styled(Button)`\n background: transparent;\n color: white;\n`\n\n// @TODO: add support for audio type (asset._type) when uploading an audio file so we can hide the thumbnail option.\nconst isVideoAsset = (asset: VideoAssetDocument) => {\n return asset._type === 'mux.videoAsset'\n}\n\nfunction PlayerActionsMenu(\n props: Pick<MuxInputProps, 'onChange' | 'readOnly'> & {\n asset: VideoAssetDocument\n onSelect: (files: File[]) => void\n dialogState: DialogState\n setDialogState: SetDialogState\n config: PluginConfig\n accept: string\n }\n) {\n const {asset, readOnly, dialogState, setDialogState, onChange, onSelect, accept} = props\n const [open, setOpen] = useState(false)\n const [menuElement, setMenuRef] = useState<HTMLDivElement | null>(null)\n const isSigned = useMemo(() => getPlaybackPolicy(asset)?.policy === 'signed', [asset])\n const {hasConfigAccess} = useAccessControl(props.config)\n const {resyncAsset, isResyncing} = useResyncAsset({showToast: true})\n\n const onReset = useCallback(() => onChange(PatchEvent.from(unset([]))), [onChange])\n\n const handleResync = useCallback(async () => {\n setOpen(false)\n await resyncAsset(asset)\n }, [resyncAsset, asset])\n\n useEffect(() => {\n if (open && dialogState) {\n setOpen(false)\n }\n }, [dialogState, open])\n\n useClickOutsideEvent(\n () => setOpen(false),\n () => [menuElement]\n )\n\n return (\n <Inline space={1} padding={2}>\n {isSigned && (\n <Tooltip\n animate\n content={\n <Box padding={2}>\n <Text muted size={1}>\n Signed playback policy\n </Text>\n </Box>\n }\n placement=\"right\"\n portal\n >\n <LockCard radius={2} margin={2} scheme=\"dark\" tone=\"positive\">\n <LockButton icon={LockIcon} mode=\"bleed\" tone=\"positive\" />\n </LockCard>\n </Tooltip>\n )}\n <Popover\n animate\n content={\n <Menu ref={setMenuRef}>\n <Box padding={2}>\n <Label muted size={1}>\n Replace\n </Label>\n </Box>\n <FileInputMenuItem\n accept={accept}\n icon={UploadIcon}\n onSelect={onSelect}\n text=\"Upload\"\n disabled={readOnly}\n fontSize={1}\n />\n <MenuItem\n icon={SearchIcon}\n text=\"Browse\"\n onClick={() => setDialogState('select-video')}\n />\n {isVideoAsset(asset) && (\n <>\n <MenuItem\n icon={ImageIcon}\n text=\"Thumbnail\"\n onClick={() => setDialogState('edit-thumbnail')}\n />\n <MenuItem\n icon={TranslateIcon}\n text=\"Captions\"\n onClick={() => setDialogState('edit-captions')}\n />\n <MenuItem\n icon={SyncIcon}\n text=\"Resync from Mux\"\n onClick={handleResync}\n disabled={readOnly || isResyncing}\n />\n </>\n )}\n <MenuDivider />\n {hasConfigAccess && (\n <>\n <MenuItem\n icon={PlugIcon}\n text=\"Configure API\"\n onClick={() => setDialogState('secrets')}\n />\n <MenuDivider />\n </>\n )}\n <MenuItem\n tone=\"critical\"\n icon={ResetIcon}\n text=\"Clear field\"\n onClick={onReset}\n disabled={readOnly}\n />\n </Menu>\n }\n portal\n open={open}\n >\n <Button\n icon={EllipsisHorizontalIcon}\n mode=\"ghost\"\n fontSize={1}\n onClick={() => {\n setDialogState(false)\n setOpen(true)\n }}\n />\n </Popover>\n </Inline>\n )\n}\n\nexport default memo(PlayerActionsMenu)\n","import {useEffect, useState} from 'react'\n\nimport {StagedUpload} from '../components/Uploader'\n\nexport function useFetchFileSize(stagedUpload: StagedUpload, maxFileSize?: number) {\n const [fileSize, setFileSize] = useState<number | null>(null)\n const [isLoadingFileSize, setIsLoadingFileSize] = useState(false)\n const [canSkipFileSizeValidation, setCanSkipFileSizeValidation] = useState(false)\n\n useEffect(() => {\n // Fetch URL Upload file size\n if (stagedUpload.type === 'url') {\n setIsLoadingFileSize(false)\n setCanSkipFileSizeValidation(false)\n setFileSize(null)\n const url = stagedUpload.url\n\n // Get file size from URL\n const fetchFileSize = async () => {\n setIsLoadingFileSize(true)\n try {\n const response = await fetch(url, {method: 'HEAD'})\n const contentLength = response.headers.get('content-length')\n const newFileSize = contentLength ? parseInt(contentLength, 10) : null\n\n setIsLoadingFileSize(false)\n if (newFileSize) {\n setFileSize(newFileSize)\n }\n if (newFileSize === null && maxFileSize !== undefined) {\n // Size unknown but size limit is configured - skip file size validation\n setCanSkipFileSizeValidation(true)\n }\n } catch {\n console.warn('Could not validate file size from URL')\n // Skip validation of file size, but still validate duration\n setCanSkipFileSizeValidation(true)\n setIsLoadingFileSize(false)\n }\n }\n\n fetchFileSize()\n }\n if (stagedUpload.type === 'file') {\n setFileSize(stagedUpload.files[0].size)\n }\n }, [maxFileSize, stagedUpload, stagedUpload.type])\n\n return {\n fileSize,\n isLoadingFileSize,\n canSkipFileSizeValidation,\n }\n}\n","import {useEffect, useState} from 'react'\n\nimport {StagedUpload} from '../components/Uploader'\n\nexport interface VideoAssetMetadata {\n width?: number\n height?: number\n isAudioOnly?: boolean\n duration?: number\n size?: number\n aspectRatio?: number\n}\n\nexport function useMediaMetadata(stagedUpload: StagedUpload) {\n const [videoAssetMetadata, setVideoAssetMetadata] = useState<VideoAssetMetadata | null>(null)\n const [isLoadingMetadata, setIsLoadingMetadata] = useState(false)\n useEffect(() => {\n let videoSrc = null\n // Validate file uploads\n if (stagedUpload.type === 'file') {\n const file = stagedUpload.files[0]\n videoSrc = URL.createObjectURL(file)\n }\n\n // Validate URL uploads\n if (stagedUpload.type === 'url') {\n videoSrc = stagedUpload.url\n }\n\n setVideoAssetMetadata((old) => ({\n ...old,\n duration: undefined,\n width: undefined,\n height: undefined,\n }))\n\n if (!videoSrc) return () => null\n\n setIsLoadingMetadata(true)\n const videoElement = document.createElement('video')\n videoElement.preload = 'metadata'\n\n const metadataListeners = [\n () => {\n setIsLoadingMetadata(false)\n },\n () => {\n const duration = videoElement.duration\n const width = videoElement.videoWidth\n const height = videoElement.videoHeight\n const isAudioOnly = width <= 0 && height <= 0\n const aspectRatio = width / height\n setVideoAssetMetadata((old) => {\n return {\n ...old,\n duration: duration,\n width: width,\n height: height,\n isAudioOnly: isAudioOnly,\n aspectRatio: aspectRatio,\n }\n })\n },\n ]\n\n const cleanupVideo = (videoEl: HTMLVideoElement) => {\n const currentVideoSrc = videoEl?.src\n if (videoEl) {\n metadataListeners.forEach((listener) =>\n videoEl.removeEventListener('loadedmetadata', listener)\n )\n videoEl.onerror = null\n videoEl.src = ''\n videoEl.load()\n }\n if (currentVideoSrc?.startsWith('blob:')) {\n URL.revokeObjectURL(currentVideoSrc)\n }\n }\n metadataListeners.push(() => setTimeout(() => cleanupVideo(videoElement), 0))\n\n videoElement.onerror = () => {\n setIsLoadingMetadata(false)\n console.warn('Could not read video metadata for validation')\n cleanupVideo(videoElement)\n }\n\n metadataListeners.forEach((listener) =>\n videoElement.addEventListener('loadedmetadata', listener)\n )\n videoElement.src = videoSrc\n\n return () => {\n cleanupVideo(videoElement)\n }\n }, [stagedUpload.type, stagedUpload])\n\n return {\n videoAssetMetadata,\n setVideoAssetMetadata,\n isLoadingMetadata,\n }\n}\n","import {roundPxString} from './roundPxString'\nimport type {MuxOverlaySettings, WatermarkConfig} from './types'\n\n/**\n * Converts a draggable watermark position (x, y percentages) to Mux's overlay_settings format.\n *\n * @param watermark - The watermark configuration with position, size, and opacity\n * @returns Mux overlay_settings object\n * @see {@link https://www.mux.com/docs/guides/add-watermarks-to-your-videos}\n */\nexport function convertWatermarkToMuxOverlay(\n watermark: WatermarkConfig,\n options?: {\n /**\n * Video aspect ratio (width / height). Needed for correct vertical positioning,\n * especially on vertical videos.\n */\n videoAspectRatio?: number\n /**\n * Unit to emit for margins/width when generating overlay_settings from Canvas mode.\n * - 'px' will generate pixel strings according to Mux's scaling rules:\n * values are applied as if the video were scaled to 1920x1080 (horizontal)\n * or 1080x1920 (vertical).\n * - '%' preserves existing behavior.\n */\n units?: '%' | 'px'\n }\n): MuxOverlaySettings | null {\n if (!watermark.enabled || !watermark.imageUrl) {\n return null\n }\n\n const size = watermark.size || 20\n const opacity = watermark.opacity ?? 0.7\n\n /**\n * Convert a percentage to whole-pixel string, using Mux's base dimensions:\n * - Horizontal video: 1920x1080\n * - Vertical video: 1080x1920\n */\n const toPxString = (valuePercent: number, axis: 'x' | 'y') => {\n const videoAspectRatio = options?.videoAspectRatio ?? 16 / 9\n const isVertical = videoAspectRatio > 0 && videoAspectRatio < 1\n const baseW = isVertical ? 1080 : 1920\n const baseH = isVertical ? 1920 : 1080\n const base = axis === 'x' ? baseW : baseH\n const px = (valuePercent / 100) * base\n let rounded = Math.round(px)\n // Avoid sending 0px (and JS -0); keep sign for negative margins.\n if (rounded === 0) rounded = px < 0 ? -1 : 1\n return `${rounded}px`\n }\n\n const normalizeToPixels = (value: string | undefined, axis: 'x' | 'y'): string | undefined => {\n if (!value) return value\n const trimmed = value.trim()\n if (trimmed.endsWith('px')) {\n return roundPxString(trimmed)\n }\n if (trimmed.endsWith('%')) {\n const n = Number(trimmed.slice(0, -1))\n if (!Number.isFinite(n)) return value\n return toPxString(n, axis)\n }\n return value\n }\n\n // If user provided explicit overlay settings, use them (Mux-documented format).\n // When `options.units === 'px'`, we normalize both % and px to whole-pixel strings,\n // honoring vertical vs horizontal video bases.\n if (watermark.overlay_settings) {\n const widthValue = watermark.overlay_settings.width\n const widthNormalized =\n options?.units === 'px' ? normalizeToPixels(widthValue, 'x') : widthValue\n return {\n ...watermark.overlay_settings,\n horizontal_margin:\n options?.units === 'px'\n ? (normalizeToPixels(watermark.overlay_settings.horizontal_margin, 'x') ??\n watermark.overlay_settings.horizontal_margin)\n : watermark.overlay_settings.horizontal_margin,\n vertical_margin:\n options?.units === 'px'\n ? (normalizeToPixels(watermark.overlay_settings.vertical_margin, 'y') ??\n watermark.overlay_settings.vertical_margin)\n : watermark.overlay_settings.vertical_margin,\n width: widthNormalized ?? `${size}%`,\n opacity: watermark.overlay_settings.opacity ?? `${Math.round(opacity * 100)}%`,\n }\n }\n\n const position = watermark.position || {x: 50, y: 50}\n\n /**\n * Our UI stores watermark position as the *center point* in percentages.\n * Mux margins are interpreted relative to an *edge* (based on align).\n *\n * To make \"corner\" placements match what the user dragged, we convert from\n * center-position to top-left margins by subtracting half the watermark size.\n *\n * Note: `size` is a percentage of video width. Mux `width` is also expressed\n * as a percentage of the video width, so we can reuse it for horizontal math.\n * For vertical math, we approximate using the same percentage to keep behavior\n * consistent with the current draggable UI (which also uses `size` in both axes\n * for bounds).\n */\n // Allow negative margins to compensate for rounding / letterboxing edge-cases.\n // We still clamp to a sane range so values don't explode.\n const clampPercent = (value: number) => Math.max(-100, Math.min(100, value))\n\n // Mux accepts percentage strings; avoid sending an exact \"0%\" by nudging to 0.01%.\n // This also handles the JS -0 edge case and tiny floating point remnants.\n const toPercentString = (value: number) => {\n const epsilon = 1e-9\n const isZeroish = value === 0 || Object.is(value, -0) || Math.abs(value) < epsilon\n return `${isZeroish ? 0.01 : value}%`\n }\n\n const watermarkWidthPercentOfVideoWidth = size\n\n /**\n * Convert watermark height into % of video height.\n * height% = (watermarkWidthPx / imageAspectRatio) / videoHeightPx\n * = (size% * videoWidthPx / imageAspectRatio) / videoHeightPx\n * = size% * (videoWidthPx/videoHeightPx) / imageAspectRatio\n * = size% * videoAspectRatio / imageAspectRatio\n */\n const videoAspectRatio = options?.videoAspectRatio ?? 16 / 9\n const imageAspectRatio = watermark.imageAspectRatio ?? 1\n const watermarkHeightPercentOfVideoHeight = Math.max(\n 0,\n Math.min(100, (size * videoAspectRatio) / imageAspectRatio)\n )\n\n const halfWidth = watermarkWidthPercentOfVideoWidth / 2\n const halfHeight = watermarkHeightPercentOfVideoHeight / 2\n\n const leftMargin = clampPercent(\n Math.min(position.x - halfWidth, 100 - watermarkWidthPercentOfVideoWidth)\n )\n const topMargin = clampPercent(\n Math.min(position.y - halfHeight, 100 - watermarkHeightPercentOfVideoHeight)\n )\n\n const units = options?.units ?? '%'\n const marginX = units === 'px' ? toPxString(leftMargin, 'x') : toPercentString(leftMargin)\n const marginY = units === 'px' ? toPxString(topMargin, 'y') : toPercentString(topMargin)\n const width = units === 'px' ? toPxString(size, 'x') : `${size}%`\n\n const overlaySettings: MuxOverlaySettings = {\n vertical_align: 'top',\n vertical_margin: marginY,\n horizontal_align: 'left',\n horizontal_margin: marginX,\n width,\n opacity: `${Math.round(opacity * 100)}%`,\n }\n\n return overlaySettings\n}\n","/* eslint-disable */\n// From: https://stackoverflow.com/questions/10420352/converting-file-size-in-bytes-to-human-readable-string\n/**\n * Format bytes as human-readable text.\n *\n * @param bytes Number of bytes.\n * @param si True to use metric (SI) units, aka powers of 1000. False to use\n * binary (IEC), aka powers of 1024.\n * @param dp Number of decimal places to display.\n *\n * @return Formatted string.\n */\nexport default function formatBytes(bytes: number, si = false, dp = 1) {\n const thresh = si ? 1000 : 1024\n\n if (Math.abs(bytes) < thresh) {\n return bytes + ' B'\n }\n\n const units = si\n ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']\n let u = -1\n const r = 10 ** dp\n\n do {\n bytes /= thresh\n ++u\n } while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1)\n\n return bytes.toFixed(dp) + ' ' + units[u]\n}\n","import {CheckmarkCircleIcon, ErrorOutlineIcon} from '@sanity/icons'\nimport {Box, Button, Card, Flex, Grid, Stack, Text, TextInput} from '@sanity/ui'\nimport {useCallback, useEffect, useRef, useState} from 'react'\nimport {styled} from 'styled-components'\n\nimport {convertWatermarkToMuxOverlay} from '../util/convertWatermarkToMux'\nimport type {MuxOverlaySettings, WatermarkConfig} from '../util/types'\n\nconst RangeInput = styled.input`\n width: 100%;\n height: 4px;\n border-radius: 2px;\n background: var(--card-border-color);\n outline: none;\n -webkit-appearance: none;\n appearance: none;\n\n &::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--card-focus-ring-color, #2276fc);\n cursor: pointer;\n border: 2px solid white;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n }\n\n &::-moz-range-thumb {\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--card-focus-ring-color, #2276fc);\n cursor: pointer;\n border: 2px solid white;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n }\n\n &:hover::-webkit-slider-thumb {\n background: var(--card-focus-ring-color, #1a5fc7);\n }\n\n &:hover::-moz-range-thumb {\n background: var(--card-focus-ring-color, #1a5fc7);\n }\n`\n\nconst WatermarkOverlay = styled.div<{$opacity: number}>`\n position: absolute;\n max-width: 200px;\n opacity: ${(props) => props.$opacity};\n cursor: move;\n user-select: none;\n z-index: 10;\n pointer-events: auto;\n\n img {\n width: 100%;\n height: auto;\n display: block;\n pointer-events: none;\n }\n\n &:hover {\n outline: 2px dashed rgba(255, 255, 255, 0.8);\n outline-offset: 4px;\n }\n`\n\ninterface DraggableWatermarkProps {\n watermark: WatermarkConfig\n onChange: (watermark: WatermarkConfig) => void\n containerRef?: React.RefObject<HTMLDivElement>\n videoElementRef?: React.RefObject<HTMLVideoElement>\n}\n\nexport default function DraggableWatermark({\n watermark,\n onChange,\n containerRef,\n videoElementRef,\n}: DraggableWatermarkProps) {\n const [isDragging, setIsDragging] = useState(false)\n const [dragStart, setDragStart] = useState({x: 0, y: 0})\n const [startPosition, setStartPosition] = useState({x: 0, y: 0})\n const watermarkRef = useRef<HTMLDivElement>(null)\n const debounceTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n const [localPosition, setLocalPosition] = useState(watermark.position || {x: 50, y: 50})\n\n const position = localPosition\n const size = watermark.size || 20\n const opacity = watermark.opacity ?? 0.7\n\n const parseOpacityPercent = (value: string | undefined): number | null => {\n if (!value) return null\n const trimmed = value.trim()\n if (!trimmed.endsWith('%')) return null\n const num = Number(trimmed.slice(0, -1))\n if (!Number.isFinite(num)) return null\n return Math.max(0, Math.min(1, num / 100))\n }\n\n const getVideoContentBox = useCallback(() => {\n const container = containerRef?.current\n if (!container) return {x: 0, y: 0, width: 0, height: 0}\n\n const rect = container.getBoundingClientRect()\n const containerW = rect.width\n const containerH = rect.height\n\n const videoEl = videoElementRef?.current\n const videoW = videoEl?.videoWidth || 0\n const videoH = videoEl?.videoHeight || 0\n\n if (!videoW || !videoH || !containerW || !containerH) {\n return {x: 0, y: 0, width: containerW, height: containerH}\n }\n\n // object-fit: contain sizing\n const scale = Math.min(containerW / videoW, containerH / videoH)\n const contentW = videoW * scale\n const contentH = videoH * scale\n const offsetX = (containerW - contentW) / 2\n const offsetY = (containerH - contentH) / 2\n\n return {x: offsetX, y: offsetY, width: contentW, height: contentH}\n }, [containerRef, videoElementRef])\n\n const parseOverlayValue = (value: string | undefined): {n: number; unit: '%' | 'px'} | null => {\n if (!value) return null\n const trimmed = value.trim()\n const px = trimmed.endsWith('px')\n const pct = trimmed.endsWith('%')\n const num = Number(trimmed.replace(/px|%/g, ''))\n if (!Number.isFinite(num)) return null\n if (px) return {n: num, unit: 'px'}\n if (pct) return {n: num, unit: '%'}\n return null\n }\n\n const computeManualStyle = (overlay: MuxOverlaySettings) => {\n const rect = containerRef?.current?.getBoundingClientRect()\n const w = rect?.width ?? 0\n const h = rect?.height ?? 0\n const isVertical = h > w\n const baseW = isVertical ? 1080 : 1920\n const baseH = isVertical ? 1920 : 1080\n\n const hm = parseOverlayValue(overlay.horizontal_margin)\n const vm = parseOverlayValue(overlay.vertical_margin)\n const ww = parseOverlayValue(overlay.width)\n const manualOpacity = parseOpacityPercent(overlay.opacity)\n\n const toCss = (v: {n: number; unit: '%' | 'px'} | null, axis: 'x' | 'y') => {\n if (!v) return undefined\n if (v.unit === '%') return `${v.n}%`\n if (axis === 'x') return `${(v.n * w) / baseW}px`\n return `${(v.n * h) / baseH}px`\n }\n\n const computeHorizontalStyle = () => {\n if (overlay.horizontal_align === 'left') {\n return {left: toCss(hm, 'x'), right: undefined, transform: 'translate(0, 0)'}\n }\n if (overlay.horizontal_align === 'right') {\n return {right: toCss(hm, 'x'), left: undefined, transform: 'translate(0, 0)'}\n }\n return {left: '50%', right: undefined, transform: 'translate(-50%, 0)'}\n }\n\n const computeVerticalStyle = () => {\n if (overlay.vertical_align === 'top') {\n return {top: toCss(vm, 'y'), bottom: undefined}\n }\n if (overlay.vertical_align === 'bottom') {\n return {bottom: toCss(vm, 'y'), top: undefined}\n }\n return {top: '50%', bottom: undefined}\n }\n\n const hStyle = computeHorizontalStyle()\n const vStyle = computeVerticalStyle()\n\n let transform = hStyle.transform\n if (overlay.vertical_align === 'middle') {\n transform =\n overlay.horizontal_align === 'center' ? 'translate(-50%, -50%)' : 'translate(0, -50%)'\n }\n\n return {\n position: 'absolute' as const,\n ...hStyle,\n ...vStyle,\n transform,\n width: ww ? toCss(ww, 'x') : `${size}%`,\n opacity: manualOpacity ?? opacity,\n cursor: 'default',\n }\n }\n\n const debouncedOnChange = useCallback(\n (newWatermark: WatermarkConfig) => {\n if (debounceTimeoutRef.current) {\n clearTimeout(debounceTimeoutRef.current)\n }\n debounceTimeoutRef.current = setTimeout(() => {\n onChange(newWatermark)\n }, 300)\n },\n [onChange]\n )\n\n useEffect(() => {\n return () => {\n if (debounceTimeoutRef.current) {\n clearTimeout(debounceTimeoutRef.current)\n }\n }\n }, [])\n\n useEffect(() => {\n if (!isDragging && watermark.position) {\n setLocalPosition(watermark.position)\n }\n }, [watermark.position, isDragging])\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault()\n setIsDragging(true)\n setDragStart({x: e.clientX, y: e.clientY})\n setStartPosition({x: position.x, y: position.y})\n },\n [position]\n )\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => {\n if (!isDragging || !containerRef?.current) return\n\n const container = containerRef.current\n const rect = container.getBoundingClientRect()\n const content = getVideoContentBox()\n const contentW = content.width || rect.width\n const contentH = content.height || rect.height\n const dx = e.clientX - dragStart.x\n const dy = e.clientY - dragStart.y\n\n const deltaXPercent = (dx / contentW) * 100\n const deltaYPercent = (dy / contentH) * 100\n\n let newX = startPosition.x + deltaXPercent\n let newY = startPosition.y + deltaYPercent\n\n newX = Math.max(0, Math.min(100, newX))\n newY = Math.max(0, Math.min(100, newY))\n\n setLocalPosition({x: newX, y: newY})\n\n debouncedOnChange({\n ...watermark,\n position: {x: newX, y: newY},\n })\n },\n [\n isDragging,\n dragStart,\n startPosition,\n containerRef,\n watermark,\n debouncedOnChange,\n getVideoContentBox,\n ]\n )\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false)\n if (debounceTimeoutRef.current) {\n clearTimeout(debounceTimeoutRef.current)\n debounceTimeoutRef.current = null\n }\n onChange({\n ...watermark,\n position: localPosition,\n })\n }, [watermark, localPosition, onChange])\n\n useEffect(() => {\n if (isDragging) {\n document.addEventListener('mousemove', handleMouseMove)\n document.addEventListener('mouseup', handleMouseUp)\n return () => {\n document.removeEventListener('mousemove', handleMouseMove)\n document.removeEventListener('mouseup', handleMouseUp)\n }\n }\n return undefined\n }, [isDragging, handleMouseMove, handleMouseUp])\n\n if (!watermark.imageUrl) {\n return null\n }\n\n const hasManualOverlay = Boolean(watermark.overlay_settings)\n const opacityForRender = hasManualOverlay\n ? (parseOpacityPercent(watermark.overlay_settings?.opacity) ?? opacity)\n : opacity\n const contentBox = getVideoContentBox()\n const hasContentBox = contentBox.width > 0 && contentBox.height > 0\n\n const computeWatermarkStyle = () => {\n if (hasManualOverlay) {\n return computeManualStyle(watermark.overlay_settings!)\n }\n if (hasContentBox) {\n return {\n left: `${contentBox.x + (position.x / 100) * contentBox.width}px`,\n top: `${contentBox.y + (position.y / 100) * contentBox.height}px`,\n transform: 'translate(-50%, -50%)',\n width: `${Math.max(1, (size / 100) * contentBox.width)}px`,\n cursor: isDragging ? 'grabbing' : 'grab',\n }\n }\n return {\n left: `${position.x}%`,\n top: `${position.y}%`,\n transform: 'translate(-50%, -50%)',\n width: `${size}%`,\n cursor: isDragging ? 'grabbing' : 'grab',\n }\n }\n\n return (\n <WatermarkOverlay\n ref={watermarkRef}\n $opacity={opacityForRender}\n onMouseDown={hasManualOverlay ? undefined : handleMouseDown}\n style={computeWatermarkStyle()}\n >\n <img src={watermark.imageUrl} alt=\"Watermark\" draggable={false} />\n </WatermarkOverlay>\n )\n}\n\ninterface WatermarkControlsProps {\n watermark: WatermarkConfig\n onChange: (watermark: WatermarkConfig) => void\n onValidationChange?: (error: string | null) => void\n previewContainerRef?: React.RefObject<HTMLDivElement | null>\n previewVideoRef?: React.RefObject<HTMLVideoElement | null>\n}\n\nexport function WatermarkControls({\n watermark,\n onChange,\n onValidationChange,\n previewContainerRef,\n previewVideoRef,\n}: WatermarkControlsProps) {\n const [urlInput, setUrlInput] = useState(watermark.imageUrl || '')\n const [urlError, setUrlError] = useState<string | null>(null)\n const [isValidating, setIsValidating] = useState(false)\n const [isValid, setIsValid] = useState<boolean | null>(null)\n const validationTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n const [mode, setMode] = useState<'canvas' | 'manual'>(\n watermark.overlay_settings ? 'manual' : 'canvas'\n )\n\n const isUpdatingRef = useRef(false)\n\n const isValidExtension = (extension: string) => {\n return extension.endsWith('.png') || extension.endsWith('.jpg') || extension.endsWith('.jpeg')\n }\n\n const validateUrl = useCallback(\n (url: string) => {\n if (validationTimeoutRef.current) {\n clearTimeout(validationTimeoutRef.current)\n }\n\n if (!url) {\n setUrlError(null)\n setIsValid(null)\n setIsValidating(false)\n onValidationChange?.(null)\n isUpdatingRef.current = true\n onChange({\n ...watermark,\n enabled: false,\n imageUrl: undefined,\n overlay_settings: undefined,\n })\n return\n }\n\n setIsValidating(true)\n setIsValid(null)\n setUrlError(null)\n\n validationTimeoutRef.current = setTimeout(() => {\n try {\n const urlObj = new URL(url)\n const pathname = urlObj.pathname.toLowerCase()\n if (isValidExtension(pathname)) {\n setIsValid(true)\n setUrlError(null)\n onValidationChange?.(null)\n const img = new Image()\n img.onload = () => {\n const imageAspectRatio =\n img.naturalWidth && img.naturalHeight ? img.naturalWidth / img.naturalHeight : 1\n isUpdatingRef.current = true\n onChange({\n ...watermark,\n enabled: true,\n imageUrl: url,\n imageAspectRatio,\n })\n }\n img.onerror = () => {\n isUpdatingRef.current = true\n onChange({\n ...watermark,\n enabled: true,\n imageUrl: url,\n imageAspectRatio: watermark.imageAspectRatio,\n })\n }\n img.src = url\n } else {\n const errorMsg =\n 'Mux only supports PNG and JPG watermark images. Please use a .png or .jpg file.'\n setIsValid(false)\n setUrlError(errorMsg)\n onValidationChange?.(errorMsg)\n isUpdatingRef.current = true\n onChange({\n ...watermark,\n enabled: false,\n imageUrl: undefined,\n imageAspectRatio: undefined,\n overlay_settings: undefined,\n })\n }\n } catch {\n setIsValid(false)\n const errorMsg = 'Please enter a valid URL (e.g., https://example.com/watermark.png)'\n setUrlError(errorMsg)\n onValidationChange?.(errorMsg)\n isUpdatingRef.current = true\n onChange({\n ...watermark,\n enabled: false,\n imageUrl: undefined,\n imageAspectRatio: undefined,\n overlay_settings: undefined,\n })\n } finally {\n setIsValidating(false)\n }\n }, 500)\n },\n [watermark, onChange, onValidationChange]\n )\n\n useEffect(() => {\n return () => {\n if (validationTimeoutRef.current) {\n clearTimeout(validationTimeoutRef.current)\n }\n }\n }, [])\n\n useEffect(() => {\n setMode(watermark.overlay_settings ? 'manual' : 'canvas')\n }, [watermark.overlay_settings])\n\n const handleUrlChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const url = e.target.value\n setUrlInput(url)\n\n if (watermark.imageUrl && url !== watermark.imageUrl) {\n isUpdatingRef.current = true\n onChange({\n ...watermark,\n enabled: false,\n imageUrl: undefined,\n imageAspectRatio: undefined,\n overlay_settings: undefined,\n })\n }\n\n validateUrl(url)\n }\n\n const normalizeZeroPercent = (value: string | undefined) => {\n if (!value) return value\n const trimmed = value.trim()\n if (!trimmed.endsWith('%')) return value\n const n = Number(trimmed.slice(0, -1))\n if (!Number.isFinite(n)) return value\n const epsilon = 1e-9\n if (n === 0 || Object.is(n, -0) || Math.abs(n) < epsilon) return '0.01%'\n return `${n}%`\n }\n\n const updateOverlaySettings = (next: Partial<MuxOverlaySettings>) => {\n const prev = watermark.overlay_settings\n const base: MuxOverlaySettings = prev ?? {\n vertical_align: 'bottom',\n vertical_margin: '2%',\n horizontal_align: 'right',\n horizontal_margin: '2%',\n width: `${watermark.size ?? 20}%`,\n opacity: `${Math.round((watermark.opacity ?? 0.7) * 100)}%`,\n }\n\n const merged: MuxOverlaySettings = {\n ...base,\n ...next,\n }\n\n onChange({\n ...watermark,\n enabled: true,\n overlay_settings: {\n ...merged,\n horizontal_margin:\n normalizeZeroPercent(merged.horizontal_margin) || merged.horizontal_margin,\n vertical_margin: normalizeZeroPercent(merged.vertical_margin) || merged.vertical_margin,\n },\n })\n }\n\n const getVideoContentBox = () => {\n const container = previewContainerRef?.current\n if (!container) return {x: 0, y: 0, width: 0, height: 0}\n\n const rect = container.getBoundingClientRect()\n const containerW = rect.width\n const containerH = rect.height\n\n const videoEl = previewVideoRef?.current\n const videoW = videoEl?.videoWidth || 0\n const videoH = videoEl?.videoHeight || 0\n\n if (!videoW || !videoH || !containerW || !containerH) {\n return {x: 0, y: 0, width: containerW, height: containerH}\n }\n\n const scale = Math.min(containerW / videoW, containerH / videoH)\n const contentW = videoW * scale\n const contentH = videoH * scale\n const offsetX = (containerW - contentW) / 2\n const offsetY = (containerH - contentH) / 2\n\n return {x: offsetX, y: offsetY, width: contentW, height: contentH}\n }\n\n return (\n <Stack space={3}>\n <Stack space={2}>\n <Text size={1} weight=\"medium\">\n Watermark Image URL\n </Text>\n <Text size={0} muted>\n Enter a URL to a PNG or JPG image. Mux will download this image and overlay it on your\n video.\n </Text>\n <Box style={{position: 'relative', width: '100%'}}>\n <input\n type=\"url\"\n value={urlInput}\n onChange={handleUrlChange}\n placeholder=\"https://example.com/watermark.png\"\n style={{\n padding: '8px 12px',\n paddingRight: (() => {\n if (urlInput) return '96px'\n if (isValid !== null) return '36px'\n return '12px'\n })(),\n border: (() => {\n if (urlError || isValid === false) return '1px solid #e74c3c'\n if (isValid === true) return '1px solid #4caf50'\n return '1px solid #ccc'\n })(),\n borderRadius: '4px',\n width: '100%',\n maxWidth: '100%',\n boxSizing: 'border-box',\n fontSize: '14px',\n }}\n />\n {(urlInput || isValidating || isValid !== null) && (\n <Box\n style={{\n position: 'absolute',\n right: '8px',\n top: '50%',\n transform: 'translateY(-50%)',\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n {urlInput && (\n <Button\n text=\"Clear\"\n mode=\"bleed\"\n tone=\"critical\"\n onClick={() => {\n setUrlInput('')\n validateUrl('')\n }}\n disabled={isValidating}\n style={{fontSize: '11px', height: '24px'}}\n />\n )}\n {isValidating && (\n <Text size={0} muted>\n Validating...\n </Text>\n )}\n {isValid === true && !isValidating && (\n <CheckmarkCircleIcon style={{color: '#4caf50', fontSize: '18px'}} />\n )}\n {isValid === false && !isValidating && (\n <ErrorOutlineIcon style={{color: '#e74c3c', fontSize: '18px'}} />\n )}\n </Box>\n )}\n </Box>\n {urlError && (\n <Card padding={2} tone=\"critical\" radius={2}>\n <Flex align=\"center\" gap={2}>\n <ErrorOutlineIcon style={{color: '#e74c3c', flexShrink: 0}} />\n <Text size={0} style={{color: '#e74c3c'}}>\n {urlError}\n </Text>\n </Flex>\n </Card>\n )}\n </Stack>\n\n {watermark.imageUrl && (\n <Stack space={2}>\n <Card padding={3} tone=\"transparent\" border radius={2}>\n <Flex\n align=\"center\"\n justify=\"space-between\"\n gap={3}\n style={{flexWrap: 'wrap', alignItems: 'flex-start'}}\n >\n <Stack space={2} style={{minWidth: 240, flex: 1}}>\n <Text size={1} weight=\"medium\">\n Positioning mode\n </Text>\n <Text size={0} muted>\n Choose between dragging on the canvas or manually editing the Mux{' '}\n <code>overlay_settings</code> fields (as in{' '}\n <a\n href=\"https://www.mux.com/docs/guides/add-watermarks-to-your-videos\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n the docs\n </a>\n ).\n </Text>\n </Stack>\n <Flex gap={2} style={{flexWrap: 'wrap'}}>\n <Button\n text=\"Canvas\"\n mode={mode === 'canvas' ? 'default' : 'ghost'}\n onClick={() => {\n setMode('canvas')\n onChange({...watermark, enabled: true, overlay_settings: undefined})\n }}\n />\n <Button\n text=\"Manual\"\n mode={mode === 'manual' ? 'default' : 'ghost'}\n onClick={() => {\n setMode('manual')\n const overlay = convertWatermarkToMuxOverlay({...watermark, enabled: true})\n updateOverlaySettings(overlay ?? {})\n }}\n />\n </Flex>\n </Flex>\n </Card>\n\n {mode === 'manual' && (\n <Card padding={3} tone=\"transparent\" border radius={2}>\n <Stack space={3}>\n <Text size={1} weight=\"medium\">\n Mux overlay_settings\n </Text>\n <Grid columns={[1, 2]} gap={3} style={{width: '100%'}}>\n <Stack space={2} style={{minWidth: 0}}>\n <Text size={0} muted>\n horizontal_align\n </Text>\n <select\n value={watermark.overlay_settings?.horizontal_align || 'right'}\n onChange={(e) =>\n updateOverlaySettings({\n horizontal_align: (e.target.value ||\n 'right') as MuxOverlaySettings['horizontal_align'],\n })\n }\n style={{\n width: '100%',\n padding: '8px 10px',\n border: '1px solid #ccc',\n borderRadius: 4,\n }}\n >\n <option value=\"left\">left</option>\n <option value=\"center\">center</option>\n <option value=\"right\">right</option>\n </select>\n </Stack>\n <Stack space={2} style={{minWidth: 0}}>\n <Text size={0} muted>\n horizontal_margin (e.g. 2% or 40px)\n </Text>\n <TextInput\n value={watermark.overlay_settings?.horizontal_margin || '2%'}\n onChange={(e) =>\n updateOverlaySettings({horizontal_margin: e.currentTarget.value})\n }\n />\n </Stack>\n <Stack space={2} style={{minWidth: 0}}>\n <Text size={0} muted>\n vertical_align\n </Text>\n <select\n value={watermark.overlay_settings?.vertical_align || 'bottom'}\n onChange={(e) =>\n updateOverlaySettings({\n vertical_align: (e.target.value ||\n 'bottom') as MuxOverlaySettings['vertical_align'],\n })\n }\n style={{\n width: '100%',\n padding: '8px 10px',\n border: '1px solid #ccc',\n borderRadius: 4,\n }}\n >\n <option value=\"top\">top</option>\n <option value=\"middle\">middle</option>\n <option value=\"bottom\">bottom</option>\n </select>\n </Stack>\n <Stack space={2} style={{minWidth: 0}}>\n <Text size={0} muted>\n vertical_margin (e.g. 2% or 40px)\n </Text>\n <TextInput\n value={watermark.overlay_settings?.vertical_margin || '2%'}\n onChange={(e) =>\n updateOverlaySettings({vertical_margin: e.currentTarget.value})\n }\n />\n </Stack>\n <Stack space={2} style={{minWidth: 0}}>\n <Text size={0} muted>\n width (e.g. 25% or 80px)\n </Text>\n <TextInput\n value={watermark.overlay_settings?.width || `${watermark.size ?? 20}%`}\n onChange={(e) => updateOverlaySettings({width: e.currentTarget.value})}\n />\n </Stack>\n <Stack space={2} style={{minWidth: 0}}>\n <Text size={0} muted>\n opacity (e.g. 90%)\n </Text>\n <TextInput\n value={\n watermark.overlay_settings?.opacity ||\n `${Math.round((watermark.opacity ?? 0.7) * 100)}%`\n }\n onChange={(e) => updateOverlaySettings({opacity: e.currentTarget.value})}\n />\n </Stack>\n </Grid>\n <Text size={0} muted>\n Margins and width accept either percentages or pixels, per the Mux guide.\n </Text>\n </Stack>\n </Card>\n )}\n\n {mode === 'canvas' && (\n <>\n <Box>\n <Text size={1} weight=\"medium\">\n {(() => {\n const sizePct = watermark.size || 20\n const contentW = getVideoContentBox().width\n if (!contentW) return `Size: ${sizePct}%`\n const px = Math.max(1, Math.round((sizePct / 100) * contentW))\n return `Size: ${px}px`\n })()}\n </Text>\n <RangeInput\n type=\"range\"\n value={(() => {\n const sizePct = watermark.size || 20\n const contentW = getVideoContentBox().width\n if (!contentW) return sizePct\n return Math.max(1, Math.round((sizePct / 100) * contentW))\n })()}\n min={(() => {\n const contentW = getVideoContentBox().width\n if (!contentW) return 5\n return Math.max(1, Math.round(contentW * 0.05))\n })()}\n max={(() => {\n const contentW = getVideoContentBox().width\n if (!contentW) return 50\n return Math.max(1, Math.round(contentW * 0.5))\n })()}\n step={1}\n onChange={(e) => {\n const raw = Number(e.target.value)\n const contentW = getVideoContentBox().width\n const nextPct = contentW ? (raw / contentW) * 100 : raw\n const clampedPct = Math.max(5, Math.min(50, nextPct))\n onChange({\n ...watermark,\n size: clampedPct,\n })\n }}\n />\n </Box>\n\n <Box>\n <Text size={1} weight=\"medium\">\n Opacity: {Math.round((watermark.opacity ?? 0.7) * 100)}%\n </Text>\n <RangeInput\n type=\"range\"\n value={watermark.opacity ?? 0.7}\n min={0}\n max={1}\n step={0.05}\n onChange={(e) =>\n onChange({\n ...watermark,\n opacity: Number(e.target.value),\n })\n }\n />\n </Box>\n </>\n )}\n\n <Card padding={2} tone=\"transparent\" border radius={2}>\n <Text size={0} muted>\n {mode === 'manual'\n ? 'Manual mode: edit the overlay_settings fields above'\n : '💡 Drag the watermark on the preview to position it'}\n </Text>\n </Card>\n </Stack>\n )}\n </Stack>\n )\n}\n","import {TranslateIcon} from '@sanity/icons'\nimport {Autocomplete, Box, Card, Checkbox, Flex, Stack, Text} from '@sanity/ui'\nimport {uuid} from '@sanity/uuid'\nimport LanguagesList from 'iso-639-1'\nimport {Dispatch} from 'react'\nimport {FormField} from 'sanity'\n\nimport {type PluginConfig, SUPPORTED_MUX_LANGUAGES, UploadTextTrack} from '../util/types'\n\nconst ALL_LANGUAGE_CODES = LanguagesList.getAllCodes().map((code) => ({\n value: code,\n label: LanguagesList.getNativeName(code),\n}))\n\nconst SUBTITLE_LANGUAGES: Record<\n Extract<UploadTextTrack, {language_code: any}>['type'],\n {value: string; label: string}[]\n> = {\n autogenerated: SUPPORTED_MUX_LANGUAGES.map((lang) => ({\n value: lang.code,\n label: lang.label,\n })),\n subtitles: ALL_LANGUAGE_CODES,\n captions: ALL_LANGUAGE_CODES,\n}\n\ntype TrackSubAction =\n | {subAction: 'add'; value: Partial<UploadTextTrack>}\n | {subAction: 'update'; value: Partial<UploadTextTrack>}\n | {subAction: 'delete'}\n\nexport type TrackAction = {action: 'track'; id: string} & TrackSubAction\n\nexport default function TextTracksEditor({\n tracks,\n dispatch,\n defaultLang,\n}: {\n /**\n * Although the schema for tracks is an array, which we'll eventually support to allow uploading\n * multiple custom subtitles, for now we only support a single auto-generated track.\n */\n tracks: (Partial<UploadTextTrack> & {_id: string})[]\n dispatch: Dispatch<TrackAction>\n defaultLang: PluginConfig['defaultAutogeneratedSubtitleLang']\n}) {\n const track = tracks[0]\n return (\n <FormField title=\"Auto-generated subtitle or caption\">\n <Stack space={2}>\n <Flex align=\"center\">\n <Checkbox\n id=\"include-autogenerated-track\"\n style={{display: 'block'}}\n checked={!!track?.language_code}\n onChange={() => {\n if (track) {\n dispatch({action: 'track', id: track._id, subAction: 'delete'})\n } else {\n dispatch({\n action: 'track',\n id: uuid(),\n subAction: 'add',\n value: {\n type: 'autogenerated',\n name: defaultLang || undefined,\n language_code: defaultLang || undefined,\n },\n })\n }\n }}\n />\n <Box flex={1} paddingLeft={3}>\n <Text>\n <label htmlFor=\"checkbox\">Generate captions</label>\n </Text>\n </Box>\n </Flex>\n {track && (\n <Autocomplete\n id={`text-tract-editor--language`}\n value={track.language_code}\n onChange={(newValue) =>\n dispatch({\n action: 'track',\n id: track._id,\n subAction: 'update',\n value: {\n language_code: newValue,\n name: LanguagesList.getNativeName(newValue),\n },\n })\n }\n options={SUBTITLE_LANGUAGES[track.type!]}\n icon={TranslateIcon}\n placeholder=\"Select language\"\n filterOption={(query, option) =>\n option.label.toLowerCase().indexOf(query.toLowerCase()) > -1 ||\n option.value.toLowerCase().indexOf(query.toLowerCase()) > -1\n }\n openButton\n renderValue={(value) =>\n SUBTITLE_LANGUAGES[track.type!].find((l) => l.value === value)?.label || value\n }\n renderOption={(option) => (\n <Card data-as=\"button\" padding={3} radius={2} tone=\"inherit\">\n <Text size={2} textOverflow=\"ellipsis\">\n {option.label} ({option.value})\n </Text>\n </Card>\n )}\n />\n )}\n </Stack>\n </FormField>\n )\n}\n","import {Checkbox, Flex, Grid, Text} from '@sanity/ui'\nimport {ActionDispatch, CSSProperties, ReactNode, useState} from 'react'\n\nimport {UploadConfigurationStateAction} from '../UploadConfiguration'\n\nexport default function PlaybackPolicyOption({\n id,\n checked,\n optionName,\n description,\n dispatch,\n action,\n disabled,\n}: {\n id: string\n checked: boolean\n optionName: string\n description: string | ReactNode\n dispatch: ActionDispatch<[action: UploadConfigurationStateAction]>\n action?: 'public_policy' | 'signed_policy' | 'drm_policy'\n disabled?: boolean\n}) {\n const [scale, setScale] = useState(1)\n\n const boxStyle: CSSProperties = {\n outline: '0.01rem solid grey',\n transform: `scale(${scale})`,\n transition: 'transform 0.1s ease-in-out',\n cursor: disabled ? 'not-allowed' : 'pointer',\n borderRadius: '0.25rem',\n }\n\n const triggerAnimation = () => {\n setScale(0.98)\n setTimeout(() => {\n setScale(1)\n }, 100)\n }\n\n const handleBoxClick = () => {\n if (!action) return\n triggerAnimation()\n dispatch({\n action,\n value: !checked,\n })\n }\n\n const descriptionJsx =\n typeof description === 'string' ? (\n <Text size={2} muted>\n {description}\n </Text>\n ) : (\n description\n )\n return (\n <label>\n <Flex gap={3} padding={3} style={boxStyle}>\n <Checkbox\n id={id}\n required\n checked={checked}\n onChange={handleBoxClick}\n disabled={disabled}\n />\n <Grid gap={3}>\n <Text size={3} weight=\"bold\">\n {optionName}\n </Text>\n {descriptionJsx}\n </Grid>\n </Flex>\n </label>\n )\n}\n","import {WarningFilledIcon} from '@sanity/icons'\nimport {Box, Flex, Text} from '@sanity/ui'\nimport {CSSProperties} from 'react'\n\nexport default function PlaybackPolicyWarning() {\n const textStyle: CSSProperties = {\n color: '#13141A',\n fontWeight: 500,\n }\n\n const boxStyle: CSSProperties = {\n outline: '0.01rem solid grey',\n backgroundColor: '#979cb0',\n borderRadius: '0.5rem',\n width: 'max-content',\n color: '#13141A',\n }\n\n return (\n <Box padding={2} style={boxStyle}>\n <Flex align=\"center\" gap={2}>\n <WarningFilledIcon />\n <Text size={1} style={textStyle}>\n Please select at least one Playback Policy\n </Text>\n </Flex>\n </Box>\n )\n}\n","import {Code, Grid, Text} from '@sanity/ui'\nimport {ActionDispatch} from 'react'\n\nimport {Secrets, UploadConfig} from '../../util/types'\nimport {UploadConfigurationStateAction} from '../UploadConfiguration'\nimport PlaybackPolicyOption from './PlaybackPolicyOption'\nimport PlaybackPolicyWarning from './PlaybackPolicyWarning'\n\nexport default function PlaybackPolicy({\n id,\n config,\n secrets,\n dispatch,\n}: {\n id: string\n config: UploadConfig\n secrets: Secrets\n dispatch: ActionDispatch<[action: UploadConfigurationStateAction]>\n}) {\n const noPolicySelected = !(config.public_policy || config.signed_policy || config.drm_policy)\n const drmPolicyDisabled = !secrets.drmConfigId\n return (\n <Grid gap={3}>\n <Text weight=\"bold\">Advanced Playback Policies</Text>\n <PlaybackPolicyOption\n id={`${id}--public`}\n checked={config.public_policy}\n optionName=\"Public\"\n description={\n <>\n <Text size={2} muted>\n Playback IDs are accessible by constructing an HLS URL like\n </Text>\n <Code>{'https://stream.mux.com/{PLAYBACK_ID}'}</Code>\n </>\n }\n dispatch={dispatch}\n action=\"public_policy\"\n />\n {secrets.enableSignedUrls && (\n <PlaybackPolicyOption\n id={`${id}--signed`}\n checked={config.signed_policy}\n optionName=\"Signed\"\n description={\n <>\n <Text size={2} muted>\n Playback IDs should be used with tokens\n </Text>\n <Code>{'https://stream.mux.com/{PLAYBACK_ID}?token={TOKEN}'}</Code>\n <Text size={2} muted>\n See{' '}\n <a\n href=\"https://www.mux.com/docs/guides/secure-video-playback\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Secure video playback\n </a>{' '}\n for details about creating tokens.\n </Text>\n </>\n }\n // See Secure video playback for details about creating tokens.\"\n dispatch={dispatch}\n action=\"signed_policy\"\n />\n )}\n {drmPolicyDisabled ? (\n <PlaybackPolicyOption\n id={`${id}--drm`}\n checked={false}\n optionName=\"DRM - Disabled\"\n description={\n <>\n <Text size={2} muted>\n To enable DRM add your DRM Configuration Id to your plugin configuration in the API\n Credentials view.{' '}\n <a\n href=\"https://www.mux.com/support/human\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Contact us\n </a>{' '}\n to get started using DRM.\n </Text>\n </>\n }\n dispatch={dispatch}\n disabled\n />\n ) : (\n <PlaybackPolicyOption\n id={`${id}--drm`}\n checked={config.drm_policy}\n optionName=\"DRM\"\n description={\n <>\n <Text size={2} muted>\n Playback IDs should be used with tokens as with Signed playback, but require extra\n configuration.\n </Text>\n <Code>{'https://stream.mux.com/{PLAYBACK_ID}?token={TOKEN}'}</Code>\n <Text size={2} muted>\n See{' '}\n <a\n href=\"https://www.mux.com/docs/guides/protect-videos-with-drm#play-drm-protected-videos\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Protect videos with DRM\n </a>{' '}\n for details about configuring your player for DRM playback and{' '}\n <a\n href=\"https://www.mux.com/docs/guides/secure-video-playback\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Secure video playback\n </a>{' '}\n for details about creating tokens.\n </Text>\n </>\n }\n dispatch={dispatch}\n action=\"drm_policy\"\n />\n )}\n {noPolicySelected && <PlaybackPolicyWarning />}\n </Grid>\n )\n}\n","import {Flex, Radio, Text} from '@sanity/ui'\nimport {ActionDispatch} from 'react'\nimport {FormField} from 'sanity'\n\nimport {type UploadConfig} from '../../util/types'\nimport {UploadConfigurationStateAction} from '../UploadConfiguration'\n\nexport const RESOLUTION_TIERS = [\n {value: '1080p', label: '1080p'},\n {value: '1440p', label: '1440p (2k)'},\n {value: '2160p', label: '2160p (4k)'},\n] as const satisfies {value: UploadConfig['max_resolution_tier']; label: string}[]\n\nexport const ResolutionTierSelector = ({\n id,\n config,\n dispatch,\n maxSupportedResolution,\n}: {\n id: string\n config: UploadConfig\n dispatch: ActionDispatch<[action: UploadConfigurationStateAction]>\n maxSupportedResolution: number\n}) => {\n return (\n <FormField\n title=\"Resolution Tier\"\n description={\n <>\n The maximum{' '}\n <a\n href=\"https://docs.mux.com/api-reference#video/operation/create-direct-upload\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n resolution_tier\n </a>{' '}\n your asset is encoded, stored, and streamed at.\n </>\n }\n >\n <Flex gap={3} wrap={'wrap'}>\n {RESOLUTION_TIERS.map(({value, label}, index) => {\n const inputId = `${id}--type-${value}`\n\n if (index > maxSupportedResolution) return null\n\n return (\n <Flex key={value} align=\"center\" gap={2}>\n <Radio\n checked={config.max_resolution_tier === value}\n name=\"asset-resolutiontier\"\n onChange={(e) =>\n dispatch({\n action: 'max_resolution_tier',\n value: e.currentTarget.value as UploadConfig['max_resolution_tier'],\n })\n }\n value={value}\n id={inputId}\n />\n <Text as=\"label\" htmlFor={inputId}>\n {label}\n </Text>\n </Flex>\n )\n })}\n </Flex>\n </FormField>\n )\n}\n","import {Checkbox, Flex, Label, Radio, Stack, Text} from '@sanity/ui'\nimport {ActionDispatch, useMemo, useState} from 'react'\nimport {FormField} from 'sanity'\n\nimport {type StaticRenditionResolution, type UploadConfig} from '../../util/types'\nimport {UploadConfigurationStateAction} from '../UploadConfiguration'\n\nconst ADVANCED_RESOLUTIONS: {value: StaticRenditionResolution; label: string}[] = [\n {value: '270p', label: '270p'},\n {value: '360p', label: '360p'},\n {value: '480p', label: '480p'},\n {value: '540p', label: '540p'},\n {value: '720p', label: '720p'},\n {value: '1080p', label: '1080p'},\n {value: '1440p', label: '1440p'},\n {value: '2160p', label: '2160p'},\n]\n\nexport const StaticRenditionSelector = ({\n id,\n config,\n dispatch,\n}: {\n id: string\n config: UploadConfig\n dispatch: ActionDispatch<[action: UploadConfigurationStateAction]>\n}) => {\n // Determine if user is in advanced mode based on selected renditions\n const isAdvancedMode = useMemo(() => {\n const specificResolutions = config.static_renditions.filter(\n (r) => r !== 'highest' && r !== 'audio-only'\n )\n return specificResolutions.length > 0\n }, [config.static_renditions])\n\n const [renditionMode, setRenditionMode] = useState<'standard' | 'advanced'>(\n isAdvancedMode ? 'advanced' : 'standard'\n )\n\n // Helper to toggle a rendition\n const toggleRendition = (rendition: StaticRenditionResolution) => {\n const current = config.static_renditions\n const hasRendition = current.includes(rendition)\n\n if (hasRendition) {\n dispatch({\n action: 'static_renditions',\n value: current.filter((r) => r !== rendition),\n })\n } else {\n dispatch({\n action: 'static_renditions',\n value: [...current, rendition],\n })\n }\n }\n\n // When switching modes, clear renditions that don't apply\n const handleModeChange = (mode: 'standard' | 'advanced') => {\n setRenditionMode(mode)\n if (mode === 'standard') {\n // Remove specific resolutions, keep only highest and audio-only\n dispatch({\n action: 'static_renditions',\n value: config.static_renditions.filter((r) => r === 'highest' || r === 'audio-only'),\n })\n } else {\n // Remove highest, keep specific resolutions and audio-only\n dispatch({\n action: 'static_renditions',\n value: config.static_renditions.filter((r) => r !== 'highest'),\n })\n }\n }\n return (\n <Stack space={3}>\n <FormField\n title=\"Static Renditions\"\n description=\"Generate downloadable MP4 or M4A files. Note: Mux will not upscale to produce MP4 renditions - renditions that would cause upscaling are skipped.\"\n >\n <Stack space={3}>\n {/* Mode Selector */}\n <Flex gap={3}>\n <Flex align=\"center\" gap={2}>\n <Radio\n checked={renditionMode === 'standard'}\n name=\"rendition-mode\"\n onChange={() => handleModeChange('standard')}\n value=\"standard\"\n id={`${id}--mode-standard`}\n />\n <Text as=\"label\" htmlFor={`${id}--mode-standard`}>\n Standard\n </Text>\n </Flex>\n <Flex align=\"center\" gap={2}>\n <Radio\n checked={renditionMode === 'advanced'}\n name=\"rendition-mode\"\n onChange={() => handleModeChange('advanced')}\n value=\"advanced\"\n id={`${id}--mode-advanced`}\n />\n <Text as=\"label\" htmlFor={`${id}--mode-advanced`}>\n Advanced\n </Text>\n </Flex>\n </Flex>\n\n {/* Standard Mode Options */}\n {renditionMode === 'standard' && (\n <Stack space={2}>\n <Flex align=\"center\" gap={2} padding={[0, 2]}>\n <Checkbox\n id={`${id}--highest`}\n style={{display: 'block'}}\n checked={config.static_renditions.includes('highest')}\n onChange={() => toggleRendition('highest')}\n />\n <Text as=\"label\" htmlFor={`${id}--highest`}>\n Highest Resolution (up to 4K)\n </Text>\n </Flex>\n <Flex align=\"center\" gap={2} padding={[0, 2]}>\n <Checkbox\n id={`${id}--audio-only-standard`}\n style={{display: 'block'}}\n checked={config.static_renditions.includes('audio-only')}\n onChange={() => toggleRendition('audio-only')}\n />\n <Text as=\"label\" htmlFor={`${id}--audio-only-standard`}>\n Audio Only (M4A)\n </Text>\n </Flex>\n </Stack>\n )}\n\n {/* Advanced Mode Options */}\n {renditionMode === 'advanced' && (\n <Stack space={2}>\n <Label size={1} muted>\n Select specific resolutions:\n </Label>\n <Flex gap={2} wrap=\"wrap\">\n {ADVANCED_RESOLUTIONS.map(({value, label}) => {\n const inputId = `${id}--resolution-${value}`\n return (\n <Flex key={value} align=\"center\" gap={2}>\n <Checkbox\n id={inputId}\n style={{display: 'block'}}\n checked={config.static_renditions.includes(value)}\n onChange={() => toggleRendition(value)}\n />\n <Text as=\"label\" htmlFor={inputId} size={1}>\n {label}\n </Text>\n </Flex>\n )\n })}\n </Flex>\n <Flex align=\"center\" gap={2} padding={[2, 2, 0, 2]}>\n <Checkbox\n id={`${id}--audio-only-advanced`}\n style={{display: 'block'}}\n checked={config.static_renditions.includes('audio-only')}\n onChange={() => toggleRendition('audio-only')}\n />\n <Text as=\"label\" htmlFor={`${id}--audio-only-advanced`}>\n Audio Only (M4A)\n </Text>\n </Flex>\n </Stack>\n )}\n </Stack>\n </FormField>\n </Stack>\n )\n}\n","import {DocumentVideoIcon, ErrorOutlineIcon, UploadIcon} from '@sanity/icons'\nimport {Box, Button, Card, Dialog, Flex, Label, Radio, Stack, Text} from '@sanity/ui'\nimport {uuid} from '@sanity/uuid'\nimport LanguagesList from 'iso-639-1'\nimport {memo, useEffect, useId, useReducer, useRef, useState} from 'react'\nimport {FormField} from 'sanity'\n\nimport {useFetchFileSize} from '../hooks/useFetchFileSize'\nimport {useMediaMetadata, type VideoAssetMetadata} from '../hooks/useMediaMetadata'\nimport {convertWatermarkToMuxOverlay} from '../util/convertWatermarkToMux'\nimport formatBytes from '../util/formatBytes'\nimport {formatSeconds} from '../util/formatSeconds'\nimport {\n type AutogeneratedTextTrack,\n type CustomTextTrack,\n isAutogeneratedTrack,\n isCustomTextTrack,\n type MuxNewAssetSettings,\n type PluginConfig,\n type Secrets,\n type StaticRenditionResolution,\n type SupportedMuxLanguage,\n type UploadConfig,\n type UploadTextTrack,\n WatermarkConfig,\n} from '../util/types'\nimport DraggableWatermark, {WatermarkControls} from './DraggableWatermark'\nimport TextTracksEditor, {type TrackAction} from './TextTracksEditor'\nimport PlaybackPolicy from './uploadConfiguration/PlaybackPolicy'\nimport {\n RESOLUTION_TIERS,\n ResolutionTierSelector,\n} from './uploadConfiguration/ResolutionTierSelector'\nimport {StaticRenditionSelector} from './uploadConfiguration/StaticRenditionSelector'\nimport type {StagedUpload} from './Uploader'\n\nexport type UploadConfigurationStateAction =\n | {action: 'video_quality'; value: UploadConfig['video_quality']}\n | {action: 'max_resolution_tier'; value: UploadConfig['max_resolution_tier']}\n | {action: 'static_renditions'; value: UploadConfig['static_renditions']}\n | {action: 'normalize_audio'; value: UploadConfig['normalize_audio']}\n | {action: 'signed_policy'; value: UploadConfig['signed_policy']}\n | {action: 'public_policy'; value: UploadConfig['public_policy']}\n | {action: 'drm_policy'; value: UploadConfig['drm_policy']}\n | {action: 'watermark'; value: WatermarkConfig}\n | TrackAction\n\nconst VIDEO_QUALITY_LEVELS = [\n {value: 'basic', label: 'Basic'},\n {value: 'plus', label: 'Plus'},\n {value: 'premium', label: 'Premium'},\n] as const satisfies {value: UploadConfig['video_quality']; label: string}[]\n\n/**\n * Sanitizes static renditions configuration to ensure 'highest' is not mixed with specific resolutions.\n * If both are present, only 'highest' (and 'audio-only' if present) will be kept.\n */\nfunction sanitizeStaticRenditions(\n renditions: StaticRenditionResolution[]\n): StaticRenditionResolution[] {\n const hasHighest = renditions.includes('highest')\n const hasSpecificResolutions = renditions.some((r) => r !== 'highest' && r !== 'audio-only')\n\n if (hasHighest && hasSpecificResolutions) {\n return renditions.filter((r) => r === 'highest' || r === 'audio-only')\n }\n\n return renditions\n}\n\n/**\n * The modal for configuring a staged upload. Handles triggering of the asset\n * upload, even if no modal needs to be shown.\n *\n * @returns\n */\nexport default function UploadConfiguration({\n stagedUpload,\n secrets,\n pluginConfig,\n startUpload,\n onClose,\n}: {\n stagedUpload: StagedUpload\n secrets: Secrets\n pluginConfig: PluginConfig\n startUpload: (settings: MuxNewAssetSettings, watermark: WatermarkConfig | undefined) => void\n onClose: () => void\n}) {\n const id = useId()\n const [watermarkValidationError, setWatermarkValidationError] = useState<string | null>(null)\n const watermarkPreviewContainerRef = useRef<HTMLDivElement>(null)\n const watermarkPreviewVideoRef = useRef<HTMLVideoElement>(null)\n const autoTextTracks = useRef<NonNullable<UploadConfig['text_tracks']>>(\n pluginConfig.video_quality === 'plus' && pluginConfig.defaultAutogeneratedSubtitleLang\n ? [\n {\n _id: uuid(),\n type: 'autogenerated',\n language_code: pluginConfig.defaultAutogeneratedSubtitleLang,\n name: LanguagesList.getNativeName(pluginConfig.defaultAutogeneratedSubtitleLang),\n } satisfies AutogeneratedTextTrack,\n ]\n : []\n ).current\n\n const [config, dispatch] = useReducer(\n (prev: UploadConfig, action: UploadConfigurationStateAction) => {\n switch (action.action) {\n case 'video_quality':\n // If video quality level switches to basic, remove plus-only features\n if (action.value === 'basic') {\n return Object.assign({}, prev, {\n video_quality: action.value,\n static_renditions: [],\n max_resolution_tier: '1080p',\n text_tracks: prev.text_tracks?.filter(({type}) => type !== 'autogenerated'),\n public_policy: true,\n signed_policy: false,\n drm_policy: false,\n })\n // If video quality level switches to plus, add back in default plus features\n }\n return Object.assign({}, prev, {\n video_quality: action.value,\n static_renditions: sanitizeStaticRenditions(pluginConfig.static_renditions || []),\n max_resolution_tier: pluginConfig.max_resolution_tier,\n text_tracks: [...autoTextTracks, ...(prev.text_tracks || [])],\n })\n\n case 'static_renditions':\n case 'max_resolution_tier':\n case 'normalize_audio':\n case 'signed_policy':\n return Object.assign({}, prev, {[action.action]: action.value})\n case 'public_policy':\n return Object.assign({}, prev, {[action.action]: action.value})\n case 'drm_policy':\n return Object.assign({}, prev, {[action.action]: action.value})\n case 'watermark':\n return Object.assign({}, prev, {watermark: action.value})\n // Updating individual tracks\n case 'track': {\n const text_tracks = [...prev.text_tracks]\n const target_track_i = text_tracks.findIndex(({_id}) => _id === action.id)\n // eslint-disable-next-line default-case\n switch (action.subAction) {\n case 'add':\n // Exit early if track already exists\n if (target_track_i !== -1) break\n text_tracks.push({\n _id: action.id,\n ...action.value,\n } as AutogeneratedTextTrack)\n break\n case 'update':\n if (target_track_i === -1) break\n text_tracks[target_track_i] = {\n ...text_tracks[target_track_i],\n ...action.value,\n } as UploadTextTrack\n break\n case 'delete':\n if (target_track_i === -1) break\n text_tracks.splice(target_track_i, 1)\n break\n }\n return Object.assign({}, prev, {text_tracks})\n }\n default:\n return prev\n }\n },\n {\n video_quality: pluginConfig.video_quality,\n max_resolution_tier: pluginConfig.max_resolution_tier,\n static_renditions: sanitizeStaticRenditions(pluginConfig.static_renditions || []),\n signed_policy: secrets.enableSignedUrls && pluginConfig.defaultSigned,\n public_policy: pluginConfig.defaultPublic,\n drm_policy: pluginConfig.defaultDrm && !!secrets.drmConfigId,\n normalize_audio: pluginConfig.normalize_audio,\n text_tracks: autoTextTracks,\n } as UploadConfig\n )\n\n // Video validations\n const [validationError, setValidationError] = useState<string | null>(null)\n const MAX_FILE_SIZE = pluginConfig.maxAssetFileSize\n const MAX_DURATION_SECONDS = pluginConfig.maxAssetDuration\n\n const {fileSize, isLoadingFileSize, canSkipFileSizeValidation} = useFetchFileSize(\n stagedUpload,\n MAX_FILE_SIZE\n )\n const {videoAssetMetadata, setVideoAssetMetadata, isLoadingMetadata} =\n useMediaMetadata(stagedUpload)\n\n useEffect(() => {\n if (fileSize) {\n setVideoAssetMetadata((old) => ({...old, size: fileSize}))\n }\n }, [fileSize, setVideoAssetMetadata])\n\n useEffect(() => {\n const validateDuration = (duration: number) => {\n if (MAX_DURATION_SECONDS && duration > MAX_DURATION_SECONDS) {\n setValidationError(\n `Video duration (${formatSeconds(duration)}) exceeds maximum allowed duration of ${formatSeconds(MAX_DURATION_SECONDS)}`\n )\n return false\n }\n return true\n }\n\n const validateFileSize = (size: number): boolean => {\n if (MAX_FILE_SIZE === undefined || size <= MAX_FILE_SIZE) {\n return true\n }\n\n setValidationError(\n `File size (${formatBytes(size)}) exceeds maximum allowed size of ${formatBytes(MAX_FILE_SIZE)}`\n )\n return false\n }\n\n const validateDrmAvailability = (isAudioOnly: boolean) => {\n if (config.drm_policy && isAudioOnly) {\n setValidationError('Audio-only asset cannot be DRM protected')\n return false\n }\n return true\n }\n\n let valid = true\n if (videoAssetMetadata?.size) {\n valid = valid && (canSkipFileSizeValidation || validateFileSize(videoAssetMetadata.size))\n }\n if (videoAssetMetadata?.duration) {\n valid = valid && validateDuration(videoAssetMetadata.duration)\n }\n if (videoAssetMetadata?.isAudioOnly != undefined) {\n valid = valid && validateDrmAvailability(videoAssetMetadata.isAudioOnly)\n }\n if (valid) {\n setValidationError(null)\n }\n }, [\n MAX_FILE_SIZE,\n MAX_DURATION_SECONDS,\n canSkipFileSizeValidation,\n videoAssetMetadata?.duration,\n videoAssetMetadata?.size,\n videoAssetMetadata?.height,\n videoAssetMetadata?.width,\n videoAssetMetadata,\n config.drm_policy,\n validationError,\n ])\n\n // If user-provided config is disabled, begin the upload immediately with\n // the developer-specified values from the schema or config or defaults.\n // This can include auto-generated subtitles!\n const {disableTextTrackConfig, disableUploadConfig} = pluginConfig\n const skipConfig = disableTextTrackConfig && disableUploadConfig\n useEffect(() => {\n if (skipConfig) {\n const {settings, watermark} = formatUploadConfig(config, secrets, {\n videoAspectRatio: videoAssetMetadata?.aspectRatio,\n })\n startUpload(settings, watermark)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n if (skipConfig) return null\n\n const basicConfig = config.video_quality !== 'plus' && config.video_quality !== 'premium'\n const playbackPolicySelected = config.public_policy || config.signed_policy || config.drm_policy\n const maxSupportedResolution = RESOLUTION_TIERS.findIndex(\n (rt) => rt.value === pluginConfig.max_resolution_tier\n )\n return (\n <Dialog\n animate\n open\n id=\"upload-configuration\"\n zOffset={1000}\n width={1}\n header=\"Configure Mux Upload\"\n onClose={onClose}\n >\n <Stack padding={4} space={2}>\n {(validationError || watermarkValidationError) && (\n <Card padding={3} tone=\"critical\" radius={2} marginBottom={2}>\n <Flex gap={2} align=\"flex-start\">\n <ErrorOutlineIcon width={20} height={20} />\n <Stack space={2}>\n <Text size={1} weight=\"semibold\">\n Validation Error\n </Text>\n <Text size={1}>{validationError || watermarkValidationError}</Text>\n </Stack>\n </Flex>\n </Card>\n )}\n <Label size={3}>FILE TO UPLOAD</Label>\n <Card\n tone=\"transparent\"\n border\n padding={3}\n paddingY={4}\n style={{borderRadius: '0.1865rem'}}\n >\n <Flex gap={2}>\n <DocumentVideoIcon fontSize=\"2em\" />\n <Stack space={2}>\n <Text textOverflow=\"ellipsis\" as=\"h2\" size={3}>\n {stagedUpload.type === 'file' ? stagedUpload.files[0].name : stagedUpload.url}\n </Text>\n <Text as=\"p\" size={1} muted>\n {stagedUpload.type === 'file'\n ? `Direct File Upload (${formatBytes(stagedUpload.files[0].size)})`\n : (() => {\n if (videoAssetMetadata?.size) {\n return `File From URL (${formatBytes(videoAssetMetadata.size)})`\n }\n if (isLoadingFileSize) {\n return 'File From URL (Loading size...)'\n }\n return 'File From URL (Unknown size)'\n })()}\n </Text>\n {stagedUpload.type === 'file' && (\n <Stack space={1}>\n {isLoadingMetadata && (\n <Text as=\"p\" size={1} muted>\n Reading video metadata...\n </Text>\n )}\n {videoAssetMetadata?.duration && !validationError && (\n <Text as=\"p\" size={1} muted>\n Duration: {formatSeconds(videoAssetMetadata.duration)}\n </Text>\n )}\n </Stack>\n )}\n </Stack>\n </Flex>\n </Card>\n {!disableUploadConfig && (\n <Stack space={3} paddingBottom={2}>\n <FormField\n title=\"Video Quality Level\"\n description={\n <>\n The video quality level informs the cost, quality, and available platform features\n for the asset.{' '}\n <a\n href=\"https://docs.mux.com/guides/use-encoding-tiers\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n See the Mux guide for more details.\n </a>\n </>\n }\n >\n <Flex gap={3}>\n {VIDEO_QUALITY_LEVELS.map(({value, label}) => {\n const inputId = `${id}--encodingtier-${value}`\n return (\n <Flex key={value} align=\"center\" gap={2}>\n <Radio\n checked={config.video_quality === value}\n name=\"asset-encodingtier\"\n onChange={(e) =>\n dispatch({\n action: 'video_quality' as const,\n value: e.currentTarget.value as UploadConfig['video_quality'],\n })\n }\n value={value}\n id={inputId}\n />\n <Text as=\"label\" htmlFor={inputId}>\n {label}\n </Text>\n </Flex>\n )\n })}\n </Flex>\n </FormField>\n\n {!basicConfig && (\n <>\n <FormField title=\"Additional Configuration\">\n <Stack space={3}>\n <PlaybackPolicy id={id} config={config} secrets={secrets} dispatch={dispatch} />\n {maxSupportedResolution > 0 && (\n <ResolutionTierSelector\n id={id}\n config={config}\n dispatch={dispatch}\n maxSupportedResolution={maxSupportedResolution}\n />\n )}\n <StaticRenditionSelector id={id} config={config} dispatch={dispatch} />\n {!disableTextTrackConfig && (\n <TextTracksEditor\n tracks={config.text_tracks}\n dispatch={dispatch}\n defaultLang={pluginConfig.defaultAutogeneratedSubtitleLang}\n />\n )}\n </Stack>\n </FormField>\n <WatermarkSection\n config={config}\n dispatch={dispatch}\n stagedUpload={stagedUpload}\n videoAssetMetadata={videoAssetMetadata}\n watermarkPreviewContainerRef={watermarkPreviewContainerRef}\n watermarkPreviewVideoRef={watermarkPreviewVideoRef}\n onValidationChange={setWatermarkValidationError}\n />\n </>\n )}\n </Stack>\n )}\n\n <Box marginTop={4}>\n <Button\n disabled={\n (!basicConfig && !playbackPolicySelected) ||\n validationError !== null ||\n isLoadingMetadata ||\n (isLoadingFileSize && !canSkipFileSizeValidation)\n }\n icon={UploadIcon}\n text=\"Upload\"\n tone=\"positive\"\n onClick={() => {\n if (!validationError) {\n const {settings, watermark} = formatUploadConfig(config, secrets, {\n videoAspectRatio: videoAssetMetadata?.aspectRatio,\n })\n startUpload(settings, watermark)\n }\n }}\n />\n </Box>\n </Stack>\n </Dialog>\n )\n}\n\nfunction setAdvancedPlaybackPolicy(\n config: UploadConfig,\n secrets: Secrets\n): MuxNewAssetSettings['advanced_playback_policies'] {\n const advanced_playback_policies: MuxNewAssetSettings['advanced_playback_policies'] = []\n if (config.public_policy) {\n advanced_playback_policies.push({policy: 'public'})\n }\n if (config.signed_policy) {\n advanced_playback_policies.push({policy: 'signed'})\n }\n if (config.drm_policy) {\n if (secrets.drmConfigId)\n advanced_playback_policies.push({\n policy: 'drm',\n drm_configuration_id: secrets.drmConfigId ?? undefined,\n })\n else {\n console.error('Selected DRM Policy but missing DRM Configuration Id')\n }\n }\n return advanced_playback_policies\n}\n\nfunction formatUploadConfig(\n config: UploadConfig,\n secrets: Secrets,\n options?: {videoAspectRatio?: number | null}\n): {\n settings: MuxNewAssetSettings\n watermark?: WatermarkConfig\n} {\n const generated_subtitles = config.text_tracks\n .filter<AutogeneratedTextTrack>(isAutogeneratedTrack)\n .map<{name: string; language_code: SupportedMuxLanguage}>((track) => ({\n name: track.name,\n language_code: track.language_code,\n }))\n\n const inputs: NonNullable<MuxNewAssetSettings['input']> = [\n {\n type: 'video',\n generated_subtitles: generated_subtitles.length > 0 ? generated_subtitles : undefined,\n },\n ...config.text_tracks.filter<CustomTextTrack>(isCustomTextTrack).reduce(\n (acc, track) => {\n if (track.language_code && track.file && track.name) {\n acc.push({\n url: track.file.contents,\n type: 'text',\n text_type: track.type === 'subtitles' ? 'subtitles' : undefined,\n language_code: track.language_code,\n name: track.name,\n closed_captions: track.type === 'captions',\n })\n }\n return acc\n },\n [] as NonNullable<MuxNewAssetSettings['input']>\n ),\n ]\n\n if (config.watermark?.imageUrl) {\n const watermarkForMux: WatermarkConfig = {...config.watermark, enabled: true}\n const overlaySettings = convertWatermarkToMuxOverlay(watermarkForMux, {\n videoAspectRatio: options?.videoAspectRatio ?? undefined,\n units: 'px',\n })\n if (overlaySettings) {\n inputs.push({\n url: config.watermark.imageUrl,\n overlay_settings: overlaySettings,\n } as NonNullable<MuxNewAssetSettings['input']>[number])\n }\n }\n\n return {\n settings: {\n input: inputs,\n static_renditions:\n config.static_renditions.length > 0\n ? config.static_renditions.map((resolution) => ({resolution}))\n : undefined,\n advanced_playback_policies: setAdvancedPlaybackPolicy(config, secrets),\n max_resolution_tier: config.max_resolution_tier,\n video_quality: config.video_quality,\n normalize_audio: config.normalize_audio,\n },\n watermark: config.watermark?.imageUrl\n ? ({...config.watermark, enabled: true} as WatermarkConfig)\n : undefined,\n }\n}\n\nfunction WatermarkSection({\n config,\n dispatch,\n stagedUpload,\n videoAssetMetadata,\n watermarkPreviewContainerRef,\n watermarkPreviewVideoRef,\n onValidationChange,\n}: {\n config: UploadConfig\n dispatch: (action: UploadConfigurationStateAction) => void\n stagedUpload: StagedUpload\n videoAssetMetadata: VideoAssetMetadata | null\n watermarkPreviewContainerRef: React.RefObject<HTMLDivElement | null>\n watermarkPreviewVideoRef: React.RefObject<HTMLVideoElement | null>\n onValidationChange: (error: string | null) => void\n}) {\n if (videoAssetMetadata?.isAudioOnly !== false) return null\n return (\n <FormField\n title=\"Watermark\"\n description={\n <>\n Add a watermark overlay to your video using Mux&apos;s native watermark support.{' '}\n <a\n href=\"https://www.mux.com/docs/guides/add-watermarks-to-your-videos\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Learn more about Mux watermarks.\n </a>\n </>\n }\n >\n <Stack space={3}>\n <WatermarkControls\n watermark={config.watermark || {enabled: false}}\n onChange={(watermark) => {\n dispatch({action: 'watermark', value: watermark})\n }}\n onValidationChange={onValidationChange}\n previewContainerRef={watermarkPreviewContainerRef}\n previewVideoRef={watermarkPreviewVideoRef}\n />\n {config.watermark?.imageUrl &&\n stagedUpload.type === 'file' &&\n // Canvas preview is only shown in \"Canvas\" mode (no explicit overlay_settings)\n !config.watermark.overlay_settings && (\n <WatermarkPreview\n stagedUpload={stagedUpload}\n watermark={config.watermark}\n videoAspectRatio={videoAssetMetadata.aspectRatio}\n onWatermarkChange={(watermark) => {\n dispatch({action: 'watermark', value: watermark})\n }}\n previewContainerRef={watermarkPreviewContainerRef}\n videoRef={watermarkPreviewVideoRef}\n />\n )}\n </Stack>\n </FormField>\n )\n}\n\n// Memoized preview component to prevent unnecessary re-renders\nconst WatermarkPreview = memo(function WatermarkPreview({\n stagedUpload,\n watermark,\n onWatermarkChange,\n videoAspectRatio,\n previewContainerRef,\n videoRef,\n}: {\n stagedUpload: StagedUpload\n watermark: WatermarkConfig\n onWatermarkChange: (watermark: WatermarkConfig) => void\n videoAspectRatio?: number | null\n previewContainerRef: React.RefObject<HTMLDivElement | null>\n videoRef: React.RefObject<HTMLVideoElement | null>\n}) {\n // Initialize video source only once\n useEffect(() => {\n if (videoRef.current && stagedUpload.type === 'file') {\n const file = stagedUpload.files[0]\n const url = URL.createObjectURL(file)\n videoRef.current.src = url\n\n return () => {\n URL.revokeObjectURL(url)\n }\n }\n return undefined\n }, [stagedUpload, videoRef])\n\n const isVertical =\n videoAspectRatio !== null && videoAspectRatio !== undefined && videoAspectRatio < 1\n\n return (\n <Card\n tone=\"transparent\"\n border\n style={{\n overflow: 'hidden',\n // For vertical videos, center the preview and limit its width\n display: 'flex',\n justifyContent: 'center',\n }}\n >\n {/* Inner container that exactly matches the video aspect ratio - no padding, no letterbox */}\n <div\n ref={previewContainerRef}\n style={{\n position: 'relative',\n // For vertical videos: limit width so the preview doesn't get too tall\n // For horizontal videos: use full width\n width: isVertical ? 'auto' : '100%',\n aspectRatio: videoAspectRatio ? String(videoAspectRatio) : '16/9',\n ...(isVertical ? {height: '400px', maxHeight: '50vh'} : {minHeight: '200px'}),\n overflow: 'hidden',\n }}\n >\n <video\n ref={videoRef}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n objectFit: 'fill',\n display: 'block',\n }}\n />\n <DraggableWatermark\n watermark={watermark}\n onChange={onWatermarkChange}\n containerRef={previewContainerRef as React.RefObject<HTMLDivElement>}\n videoElementRef={videoRef as React.RefObject<HTMLVideoElement>}\n />\n </div>\n </Card>\n )\n})\n","import {rem} from '@sanity/ui'\nimport type {ComponentType} from 'react'\nimport {css, styled} from 'styled-components'\n\nimport {focusRingBorderStyle, focusRingStyle} from './helpers'\n\nexport function withFocusRing<Props>(component: ComponentType<Props>) {\n return styled(component as unknown as any)<Props & {$border?: boolean}>((props) => {\n const border = {\n width: props.$border ? 1 : 0,\n color: 'var(--card-border-color)',\n }\n\n return css`\n --card-focus-box-shadow: ${focusRingBorderStyle(border)};\n\n border-radius: ${rem(props.theme.sanity.radius[1])};\n outline: none;\n box-shadow: var(--card-focus-box-shadow);\n\n &:focus {\n --card-focus-box-shadow: ${focusRingStyle({\n base: props.theme.sanity.color.base,\n border,\n focusRing: props.theme.sanity.focusRing,\n })};\n }\n `\n })\n}\n","/* eslint-disable no-nested-ternary */\nimport {Card, type CardTone} from '@sanity/ui'\nimport React, {forwardRef, useCallback, useRef} from 'react'\nimport {styled} from 'styled-components'\n\nimport {withFocusRing} from './withFocusRing'\n\nconst UploadCardWithFocusRing = withFocusRing(Card)\n\ninterface UploadCardProps {\n tone?: CardTone\n children: React.ReactNode\n onPaste: React.ClipboardEventHandler<HTMLInputElement>\n onDrop: React.DragEventHandler<HTMLDivElement>\n onDragOver: React.DragEventHandler<HTMLDivElement>\n onDragLeave: React.DragEventHandler<HTMLDivElement>\n onDragEnter: React.DragEventHandler<HTMLDivElement>\n}\nexport const UploadCard = forwardRef<HTMLDivElement, UploadCardProps>(\n ({children, tone, onPaste, onDrop, onDragEnter, onDragLeave, onDragOver}, forwardedRef) => {\n const inputRef = useRef<HTMLInputElement>(null)\n const handleKeyDown = useCallback<React.KeyboardEventHandler<HTMLDivElement>>((event) => {\n const target = event.target as HTMLElement\n\n // Don't steal focus when pasting into the VTT input\n if (target.closest('#vtt-url')) {\n return\n }\n\n if ((event.ctrlKey || event.metaKey) && event.key === 'v') {\n inputRef.current!.focus()\n }\n }, [])\n\n return (\n <UploadCardWithFocusRing\n tone={tone}\n ref={forwardedRef}\n padding={0}\n radius={2}\n shadow={0}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n onPaste={onPaste}\n onDrop={onDrop}\n onDragEnter={onDragEnter}\n onDragLeave={onDragLeave}\n onDragOver={onDragOver}\n >\n <HiddenInput ref={inputRef} />\n {children}\n </UploadCardWithFocusRing>\n )\n }\n)\n\nconst HiddenInput = styled.input.attrs({type: 'text'})`\n position: absolute;\n border: 0;\n color: white;\n opacity: 0;\n\n &:focus {\n outline: none;\n }\n`\n","import {Button, type ButtonProps} from '@sanity/ui'\nimport React, {useCallback, useId, useRef} from 'react'\nimport {styled} from 'styled-components'\n\nconst HiddenInput = styled.input`\n overflow: hidden;\n width: 0.1px;\n height: 0.1px;\n opacity: 0;\n position: absolute;\n z-index: -1;\n`\n\nconst Label = styled.label`\n position: relative;\n`\n\nexport interface FileInputButtonProps extends ButtonProps {\n onSelect: (files: FileList) => void\n accept: string\n}\nexport const FileInputButton = ({onSelect, accept, ...props}: FileInputButtonProps) => {\n const inputId = `FileSelect${useId()}`\n const inputRef = useRef<HTMLInputElement>(null)\n const handleSelect = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n (event) => {\n if (onSelect) {\n onSelect(event.target.files!)\n }\n },\n [onSelect]\n )\n const handleButtonClick = useCallback(() => inputRef.current?.click(), [])\n return (\n <Label htmlFor={inputId}>\n <HiddenInput\n accept={accept}\n ref={inputRef}\n tabIndex={0}\n type=\"file\"\n id={inputId}\n onChange={handleSelect}\n value=\"\"\n />\n <Button\n onClick={handleButtonClick}\n mode=\"default\"\n tone=\"primary\"\n style={{width: '100%'}}\n {...props}\n />\n </Label>\n )\n}\n","import {DocumentVideoIcon, PlugIcon, SearchIcon, UploadIcon} from '@sanity/icons'\nimport {Button, Card, Flex, Inline, Text} from '@sanity/ui'\nimport {useCallback} from 'react'\n\nimport {useAccessControl} from '../hooks/useAccessControl'\nimport type {SetDialogState} from '../hooks/useDialogState'\nimport {PluginConfig} from '../util/types'\nimport {FileInputButton, type FileInputButtonProps} from './FileInputButton'\n\nfunction formatAcceptString(accept: string): string {\n return accept\n .split(',')\n .map((type) => type.trim().replace('/*', ''))\n .join(' or ')\n}\n\ninterface UploadPlaceholderProps {\n setDialogState: SetDialogState\n readOnly: boolean\n hovering: boolean\n needsSetup: boolean\n onSelect: FileInputButtonProps['onSelect']\n config: PluginConfig\n accept: string\n}\nexport default function UploadPlaceholder(props: UploadPlaceholderProps) {\n const {setDialogState, readOnly, onSelect, hovering, needsSetup, accept} = props\n const handleBrowse = useCallback(() => setDialogState('select-video'), [setDialogState])\n const handleConfigureApi = useCallback(() => setDialogState('secrets'), [setDialogState])\n const {hasConfigAccess} = useAccessControl(props.config)\n\n return (\n <Card\n sizing=\"border\"\n tone={readOnly ? 'transparent' : 'inherit'}\n border\n radius={2}\n paddingX={3}\n paddingY={1}\n style={hovering ? {borderColor: 'transparent'} : undefined}\n >\n <Flex\n align=\"center\"\n justify=\"space-between\"\n gap={4}\n direction={['column', 'column', 'row']}\n paddingY={2}\n sizing=\"border\"\n >\n <Flex align=\"center\" justify=\"flex-start\" gap={2} flex={1}>\n <Flex justify=\"center\">\n <Text muted>\n <DocumentVideoIcon />\n </Text>\n </Flex>\n <Flex justify=\"center\">\n <Text size={1} muted>\n Drag {formatAcceptString(accept)} file or paste URL here\n </Text>\n </Flex>\n </Flex>\n <Inline space={2}>\n <FileInputButton\n accept={accept}\n mode=\"bleed\"\n tone=\"default\"\n icon={UploadIcon}\n text=\"Upload\"\n onSelect={onSelect}\n />\n <Button mode=\"bleed\" icon={SearchIcon} text=\"Select\" onClick={handleBrowse} />\n\n {hasConfigAccess && (\n <Button\n padding={3}\n radius={3}\n tone={needsSetup ? 'critical' : undefined}\n onClick={handleConfigureApi}\n icon={PlugIcon}\n mode=\"bleed\"\n title=\"Configure plugin credentials\"\n />\n )}\n </Inline>\n </Flex>\n </Card>\n )\n}\n","import {ErrorOutlineIcon} from '@sanity/icons'\nimport {Button, CardTone, Flex, Text, useToast} from '@sanity/ui'\nimport React, {useCallback, useEffect, useReducer, useRef, useState} from 'react'\nimport {type Observable, Subject, Subscription} from 'rxjs'\nimport {takeUntil, tap} from 'rxjs/operators'\nimport type {SanityClient} from 'sanity'\nimport {PatchEvent, set, setIfMissing} from 'sanity'\n\nimport {uploadFile, uploadUrl} from '../actions/upload'\nimport {DialogStateProvider} from '../context/DialogStateContext'\nimport {type DialogState, type SetDialogState} from '../hooks/useDialogState'\nimport {isServerError, isValidUrl} from '../util/asserters'\nimport {extractDroppedFiles} from '../util/extractFiles'\nimport {hasPlaybackPolicy} from '../util/getPlaybackPolicy'\nimport type {\n MuxInputProps,\n MuxNewAssetSettings,\n PluginConfig,\n Secrets,\n VideoAssetDocument,\n} from '../util/types'\nimport InputBrowser from './InputBrowser'\nimport Player from './Player'\nimport PlayerActionsMenu from './PlayerActionsMenu'\nimport UploadConfiguration from './UploadConfiguration'\nimport {UploadCard} from './Uploader.styled'\nimport UploadPlaceholder from './UploadPlaceholder'\nimport {UploadProgress} from './UploadProgress'\n\ninterface Props extends Pick<MuxInputProps, 'onChange' | 'readOnly'> {\n config: PluginConfig\n client: SanityClient\n secrets: Secrets\n asset: VideoAssetDocument | null | undefined\n dialogState: DialogState\n setDialogState: SetDialogState\n needsSetup: boolean\n}\n\nexport type StagedUpload = {type: 'file'; files: FileList | File[]} | {type: 'url'; url: string}\ntype UploadStatus = {\n progress: number\n file?: {name: string | undefined; type: string}\n uuid?: string\n url?: string\n}\n\ninterface State {\n stagedUpload: StagedUpload | null\n uploadStatus: UploadStatus | null\n error: Error | null\n}\n\nconst INITIAL_STATE: State = {\n stagedUpload: null,\n uploadStatus: null,\n error: null,\n}\n\ntype UploadFileEvent = ReturnType<typeof uploadFile> extends Observable<infer T> ? T : never\ntype UploadUrlEvent = ReturnType<typeof uploadUrl> extends Observable<infer T> ? T : never\ntype UploaderStateAction =\n | {action: 'stageUpload'; input: NonNullable<State['stagedUpload']>}\n | {action: 'commitUpload'}\n | ({action: 'progressInfo'} & (\n | Extract<UploadFileEvent, {type: 'uuid' | 'file'}>\n | Extract<UploadUrlEvent, {type: 'url'}>\n ))\n | {action: 'progress'; percent: number}\n | {action: 'error'; error: Error; settings: MuxNewAssetSettings}\n | {action: 'complete' | 'reset'}\n\n/**\n * The main interface for inputting a Mux Video. It handles staging an upload\n * file, setting its configuration, displaying upload progress, and showing\n * the preview player.\n */\nexport default function Uploader(props: Props) {\n const toast = useToast()\n const containerRef = useRef<HTMLDivElement>(null)\n\n const dragEnteredEls = useRef<EventTarget[]>([])\n const [dragState, setDragState] = useState<'valid' | 'invalid' | null>(null)\n\n const cancelUploadButton = useRef(\n (() => {\n const events$ = new Subject()\n return {\n observable: events$.asObservable(),\n handleClick: ((event) => events$.next(event)) as React.MouseEventHandler<HTMLButtonElement>,\n }\n })()\n ).current\n\n const uploadRef = useRef<Subscription | null>(null)\n const uploadingDocumentId = useRef<string | null>(null)\n const [state, dispatch] = useReducer(\n (prev: State, action: UploaderStateAction) => {\n switch (action.action) {\n case 'stageUpload':\n return Object.assign({}, INITIAL_STATE, {stagedUpload: action.input})\n case 'commitUpload':\n return Object.assign({}, prev, {uploadStatus: {progress: 0}})\n case 'progressInfo': {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {type, action: _, ...payload} = action\n return Object.assign({}, prev, {\n uploadStatus: {\n ...prev.uploadStatus,\n progress: prev.uploadStatus!.progress,\n ...payload,\n },\n } satisfies Pick<typeof prev, 'uploadStatus'>)\n }\n case 'progress':\n return Object.assign({}, prev, {\n uploadStatus: {\n ...prev.uploadStatus,\n progress: action.percent,\n },\n } satisfies Pick<typeof prev, 'uploadStatus'>)\n case 'reset':\n case 'complete':\n // Clear upload observable on completion\n uploadRef.current?.unsubscribe()\n uploadRef.current = null\n uploadingDocumentId.current = null\n return INITIAL_STATE\n case 'error': {\n // Clear upload observable on error\n uploadRef.current?.unsubscribe()\n uploadRef.current = null\n uploadingDocumentId.current = null\n\n let error = action.error\n if (isServerError(action.error) && hasPlaybackPolicy(action.settings, 'drm')) {\n error = new Error(\n 'Unknown Error while uploading DRM protected content. Make sure your DRM configuration ID is valid and set correctly'\n )\n }\n\n return Object.assign({}, INITIAL_STATE, {error: error})\n }\n default:\n return prev\n }\n },\n {\n stagedUpload: null,\n uploadStatus: null,\n error: null,\n }\n )\n\n // Make sure we close out the upload observer on dismount\n // and cleanup orphaned documents if upload was in progress\n useEffect(() => {\n const cleanup = () => {\n // Cancel subscription\n if (uploadRef.current && !uploadRef.current.closed) {\n uploadRef.current.unsubscribe()\n }\n\n // Delete orphaned document if upload was in progress and document is different from the saved asset\n if (uploadingDocumentId.current && props.asset?._id !== uploadingDocumentId.current) {\n const docId = uploadingDocumentId.current\n uploadingDocumentId.current = null\n\n props.client.delete(docId).catch((err) => {\n console.warn('Failed to cleanup orphaned upload document:', err)\n })\n }\n }\n\n const handleBeforeUnload = () => {\n cleanup()\n }\n\n window.addEventListener('beforeunload', handleBeforeUnload)\n window.addEventListener('pagehide', handleBeforeUnload)\n\n return () => {\n window.removeEventListener('beforeunload', handleBeforeUnload)\n window.removeEventListener('pagehide', handleBeforeUnload)\n cleanup()\n }\n }, [props.client, props.asset?._id])\n\n /* -------------------------------------------------------------------------- */\n /* Uploading */\n /* -------------------------------------------------------------------------- */\n\n /**\n * Begins a file or URL upload with the staged files or URL.\n *\n * Should only be called from the UploadConfiguration component, which provides\n * the Mux configuration for the direct asset upload.\n *\n * @param settings The Mux new_asset_settings object to send to Sanity\n * @param watermark Optional watermark configuration\n * @returns\n */\n const startUpload = (\n settings: MuxNewAssetSettings,\n watermark?: import('../util/types').WatermarkConfig\n ) => {\n const {stagedUpload} = state\n if (!stagedUpload || uploadRef.current) return\n dispatch({action: 'commitUpload'})\n let uploadObservable: Observable<UploadFileEvent | UploadUrlEvent>\n // eslint-disable-next-line default-case\n switch (stagedUpload.type) {\n case 'url':\n uploadObservable = uploadUrl({\n client: props.client,\n url: stagedUpload.url,\n settings,\n watermark,\n })\n break\n case 'file':\n uploadObservable = uploadFile({\n client: props.client,\n file: stagedUpload.files[0],\n settings,\n watermark,\n }).pipe(\n takeUntil(\n cancelUploadButton.observable.pipe(\n tap(() => {\n if (uploadingDocumentId.current) {\n props.client.delete(uploadingDocumentId.current)\n uploadingDocumentId.current = null\n }\n })\n )\n )\n )\n break\n }\n uploadRef.current = uploadObservable.subscribe({\n next: (event) => {\n switch (event.type) {\n case 'uuid':\n // Track the document ID for cleanup on unmount\n uploadingDocumentId.current = event.uuid\n dispatch({action: 'progressInfo', ...event})\n break\n case 'file':\n case 'url':\n dispatch({action: 'progressInfo', ...event})\n break\n case 'progress':\n dispatch({action: 'progress', percent: event.percent})\n break\n case 'success':\n dispatch({action: 'progress', percent: 100})\n uploadingDocumentId.current = null\n props.onChange(\n PatchEvent.from([\n setIfMissing({asset: {}}),\n set({_type: 'reference', _weak: true, _ref: event.asset._id}, ['asset']),\n ])\n )\n break\n case 'pause':\n case 'resume':\n default:\n break\n }\n },\n complete: () => dispatch({action: 'complete'}),\n error: (error) => dispatch({action: 'error', error, settings}),\n })\n }\n\n const invalidFileToast = useCallback(() => {\n toast.push({\n status: 'error',\n title: `Invalid file type. Accepted types: ${props.config.acceptedMimeTypes?.join(', ')}`,\n })\n }, [props.config.acceptedMimeTypes, toast])\n\n /**\n * Validates if any file in the provided FileList or File array has an unsupported MIME type\n * @param files - FileList or File array to validate\n * @returns true if any file has an invalid MIME type, false if all files are valid\n */\n const isInvalidFile = (files: FileList | File[]) => {\n const isInvalid = Array.from(files).some((file) => {\n return !props.config.acceptedMimeTypes?.some((acceptedType) => {\n // Convert mime type pattern to regex (e.g., 'audio/*' -> /^audio\\/.*$/)\n const pattern = `^${acceptedType.replace('*', '.*')}$`\n return new RegExp(pattern).test(file.type)\n })\n })\n\n return isInvalid\n }\n\n /* -------------------------- Upload Initialization ------------------------- */\n // The below populate the uploadInput state field, which then triggers the\n // upload configuration, or the startUpload function if no config is required.\n\n // Stages an upload from the file selector\n const handleUpload = (files: FileList | File[]) => {\n if (isInvalidFile(files)) return\n dispatch({\n action: 'stageUpload',\n input: {type: 'file', files},\n })\n }\n\n // Stages and validates an upload from pasting an asset URL\n const handlePaste: React.ClipboardEventHandler<HTMLInputElement> = (event) => {\n const target = event.target as HTMLElement\n\n // Ignore paste coming from the VTT URL input\n if (target.closest('#vtt-url')) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n const clipboardData =\n event.clipboardData || (window as Window & {clipboardData?: DataTransfer}).clipboardData\n const url = clipboardData?.getData('text')?.trim()\n if (!isValidUrl(url)) {\n toast.push({status: 'error', title: 'Invalid URL for Mux video input.'})\n return\n }\n dispatch({action: 'stageUpload', input: {type: 'url', url: url}})\n }\n\n // Stages and validates an upload from dragging+dropping files or folders\n const handleDrop: React.DragEventHandler<HTMLDivElement> = (event) => {\n event.preventDefault()\n event.stopPropagation()\n if (dragState === 'invalid') {\n invalidFileToast()\n setDragState(null)\n return\n }\n setDragState(null)\n extractDroppedFiles(event.nativeEvent.dataTransfer!).then((files) => {\n dispatch({\n action: 'stageUpload',\n input: {type: 'file', files},\n })\n })\n }\n\n /* ------------------------------- Drag State ------------------------------- */\n\n const handleDragOver: React.DragEventHandler<HTMLDivElement> = (event) => {\n event.preventDefault()\n event.stopPropagation()\n }\n\n const handleDragEnter: React.DragEventHandler<HTMLDivElement> = (event) => {\n event.stopPropagation()\n dragEnteredEls.current.push(event.target)\n const type = event.dataTransfer.items?.[0]?.type\n const mimeTypes = props.config.acceptedMimeTypes\n\n // Check if the dragged file type matches any of the accepted mime types\n const isValidType = mimeTypes?.some((acceptedType) => {\n // Convert mime type pattern to regex (e.g., 'video/*' -> /^video\\/.*$/)\n const pattern = `^${acceptedType.replace('*', '.*')}$`\n return new RegExp(pattern).test(type)\n })\n\n setDragState(isValidType ? 'valid' : 'invalid')\n }\n\n const handleDragLeave: React.DragEventHandler<HTMLDivElement> = (event) => {\n event.stopPropagation()\n const idx = dragEnteredEls.current.indexOf(event.target)\n if (idx > -1) {\n dragEnteredEls.current.splice(idx, 1)\n }\n if (dragEnteredEls.current.length === 0) {\n setDragState(null)\n }\n }\n\n /* -------------------------------- Rendering ------------------------------- */\n\n // Upload has errored\n if (state.error !== null) {\n const error = state.error\n return (\n <Flex gap={3} direction=\"column\" justify=\"center\" align=\"center\">\n <Text size={5} muted>\n <ErrorOutlineIcon />\n </Text>\n <Text>Something went wrong</Text>\n {error instanceof Error && error.message && (\n <Text size={1} muted weight=\"semibold\" style={{textAlign: 'center'}}>\n {error.message}\n </Text>\n )}\n <Button text=\"Upload another file\" onClick={() => dispatch({action: 'reset'})} />\n </Flex>\n )\n }\n\n // Upload is in progress\n if (state.uploadStatus !== null) {\n const {uploadStatus} = state\n return (\n <UploadProgress\n onCancel={cancelUploadButton.handleClick}\n progress={uploadStatus.progress}\n filename={uploadStatus.file?.name || uploadStatus.url}\n />\n )\n }\n\n // Upload needs configuration\n if (state.stagedUpload !== null) {\n return (\n <UploadConfiguration\n stagedUpload={state.stagedUpload}\n pluginConfig={props.config}\n secrets={props.secrets}\n startUpload={startUpload}\n onClose={() => dispatch({action: 'reset'})}\n />\n )\n }\n\n // Default: No staged upload\n let tone: CardTone | undefined\n if (dragState) tone = dragState === 'valid' ? 'positive' : 'critical'\n\n const acceptMimeString = props.config?.acceptedMimeTypes?.length\n ? props.config.acceptedMimeTypes.join(',')\n : 'video/*, audio/*'\n\n return (\n <>\n <UploadCard\n tone={tone}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDragEnter={handleDragEnter}\n onPaste={handlePaste}\n ref={containerRef}\n >\n {props.asset ? (\n <DialogStateProvider\n dialogState={props.dialogState}\n setDialogState={props.setDialogState}\n >\n <Player\n readOnly={props.readOnly}\n asset={props.asset}\n onChange={props.onChange}\n config={props.config}\n buttons={\n <PlayerActionsMenu\n accept={acceptMimeString}\n asset={props.asset}\n dialogState={props.dialogState}\n setDialogState={props.setDialogState}\n onChange={props.onChange}\n onSelect={handleUpload}\n readOnly={props.readOnly}\n config={props.config}\n />\n }\n />\n </DialogStateProvider>\n ) : (\n <UploadPlaceholder\n accept={acceptMimeString}\n hovering={dragState !== null}\n onSelect={handleUpload}\n readOnly={!!props.readOnly}\n setDialogState={props.setDialogState}\n needsSetup={props.needsSetup}\n config={props.config}\n />\n )}\n </UploadCard>\n {props.dialogState === 'select-video' && (\n <InputBrowser\n config={props.config}\n asset={props.asset}\n onChange={props.onChange}\n setDialogState={props.setDialogState}\n />\n )}\n </>\n )\n}\n","import {Card} from '@sanity/ui'\nimport {memo, Suspense} from 'react'\n\nimport {useAccessControl} from '../hooks/useAccessControl'\nimport {useAssetDocumentValues} from '../hooks/useAssetDocumentValues'\nimport {useClient} from '../hooks/useClient'\nimport {useDialogState} from '../hooks/useDialogState'\nimport {useMuxPolling} from '../hooks/useMuxPolling'\nimport {useSecretsDocumentValues} from '../hooks/useSecretsDocumentValues'\nimport type {MuxInputProps, PluginConfig} from '../util/types'\nimport {ConfigureApiDialog} from './ConfigureApi'\nimport ErrorBoundaryCard from './ErrorBoundaryCard'\nimport {InputFallback} from './Input.styled'\nimport Onboard from './Onboard'\nimport Uploader from './Uploader'\n\nexport interface InputProps extends MuxInputProps {\n config: PluginConfig\n}\nconst Input = (props: InputProps) => {\n const client = useClient()\n const secretDocumentValues = useSecretsDocumentValues()\n const assetDocumentValues = useAssetDocumentValues(props.value?.asset)\n const poll = useMuxPolling(props.readOnly ? undefined : assetDocumentValues?.value || undefined)\n const [dialogState, setDialogState] = useDialogState()\n const {hasConfigAccess} = useAccessControl(props.config)\n\n const error = secretDocumentValues.error || assetDocumentValues.error || poll.error /*||\n // @TODO move errored logic to Uploader, where handleRemoveVideo can be called\n (assetDocumentValues.value?.status === 'errored'\n ? new Error(assetDocumentValues.value.data?.errors?.messages?.join(' '))\n : undefined)\n // */\n if (error) {\n // @TODO deal with it more gracefully\n throw error\n }\n const isLoading = secretDocumentValues.isLoading || assetDocumentValues.isLoading\n\n return (\n <Card>\n <ErrorBoundaryCard schemaType={props.schemaType}>\n <Suspense fallback={<InputFallback />}>\n {isLoading ? (\n <InputFallback />\n ) : (\n <>\n {secretDocumentValues.value.needsSetup && !assetDocumentValues.value ? (\n <Onboard setDialogState={setDialogState} config={props.config} />\n ) : (\n <Uploader\n {...props}\n config={props.config}\n onChange={props.onChange}\n client={client}\n secrets={secretDocumentValues.value.secrets}\n asset={assetDocumentValues.value}\n dialogState={dialogState}\n setDialogState={setDialogState}\n needsSetup={secretDocumentValues.value.needsSetup}\n />\n )}\n\n {dialogState === 'secrets' && hasConfigAccess && (\n <ConfigureApiDialog\n setDialogState={setDialogState}\n secrets={secretDocumentValues.value.secrets}\n />\n )}\n </>\n )}\n </Suspense>\n </ErrorBoundaryCard>\n </Card>\n )\n}\n\nexport default memo(Input)\n","import Input from './components/Input'\nimport VideoThumbnail from './components/VideoThumbnail'\nimport type {MuxInputProps, PluginConfig, VideoAssetDocument} from './util/types'\n\nexport function muxVideoCustomRendering(config: PluginConfig) {\n return {\n components: {\n input: (props: MuxInputProps) => (\n <Input config={{...config, ...props.schemaType.options}} {...props} />\n ),\n },\n preview: {\n select: {\n filename: 'asset.filename',\n playbackId: 'asset.playbackId',\n status: 'asset.status',\n assetId: 'asset.assetId',\n thumbTime: 'asset.thumbTime',\n data: 'asset.data',\n },\n prepare: (asset: Partial<VideoAssetDocument>) => {\n const {filename, playbackId, status} = asset\n return {\n title: filename || playbackId || '',\n subtitle: status ? `status: ${status}` : null,\n media: asset.playbackId ? <VideoThumbnail asset={asset} width={64} /> : null,\n }\n },\n },\n }\n}\n","export const muxVideoSchema = {\n name: 'mux.video',\n type: 'object',\n title: 'Video asset reference',\n fields: [\n {\n title: 'Video',\n name: 'asset',\n type: 'reference',\n weak: true,\n to: [{type: 'mux.videoAsset'}],\n },\n ],\n}\n\nconst muxTrack = {\n name: 'mux.track',\n type: 'object',\n fields: [\n {type: 'string', name: 'id'},\n {type: 'string', name: 'type'},\n {type: 'number', name: 'max_width'},\n {type: 'number', name: 'max_frame_rate'},\n {type: 'number', name: 'duration'},\n {type: 'number', name: 'max_height'},\n {type: 'string', name: 'language_code'},\n {type: 'string', name: 'name'},\n {type: 'string', name: 'status'},\n {type: 'string', name: 'text_source'},\n {type: 'string', name: 'text_type'},\n ],\n}\n\nconst muxPlaybackId = {\n name: 'mux.playbackId',\n type: 'object',\n fields: [\n {type: 'string', name: 'id'},\n {type: 'string', name: 'policy'},\n ],\n}\n\nconst muxStaticRenditionFile = {\n name: 'mux.staticRenditionFile',\n type: 'object',\n fields: [\n {type: 'string', name: 'name'},\n {type: 'string', name: 'ext'},\n {type: 'number', name: 'height'},\n {type: 'number', name: 'width'},\n {type: 'number', name: 'bitrate'},\n {type: 'string', name: 'filesize'},\n {type: 'string', name: 'type'},\n {type: 'string', name: 'status'},\n {type: 'string', name: 'resolution_tier'},\n {type: 'string', name: 'resolution'},\n {type: 'string', name: 'id'},\n {type: 'string', name: 'passthrough'},\n ],\n}\n\nconst muxStaticRenditions = {\n name: 'mux.staticRenditions',\n type: 'object',\n fields: [\n {type: 'string', name: 'status'},\n {\n name: 'files',\n type: 'array',\n of: [{type: 'mux.staticRenditionFile'}],\n },\n ],\n}\n\nconst muxAssetData = {\n name: 'mux.assetData',\n title: 'Mux asset data',\n type: 'object',\n fields: [\n {\n type: 'string',\n name: 'resolution_tier',\n },\n {\n type: 'string',\n name: 'upload_id',\n },\n {\n type: 'string',\n name: 'created_at',\n },\n {\n type: 'string',\n name: 'id',\n },\n {\n type: 'string',\n name: 'status',\n },\n {\n type: 'string',\n name: 'max_stored_resolution',\n },\n {\n type: 'string',\n name: 'passthrough',\n },\n {\n type: 'string',\n name: 'encoding_tier',\n },\n {\n type: 'string',\n name: 'video_quality',\n },\n {\n type: 'string',\n name: 'master_access',\n },\n {\n type: 'string',\n name: 'aspect_ratio',\n },\n {\n type: 'number',\n name: 'duration',\n },\n {\n type: 'number',\n name: 'max_stored_frame_rate',\n },\n {\n type: 'string',\n name: 'mp4_support',\n },\n {\n type: 'string',\n name: 'max_resolution_tier',\n },\n {\n name: 'tracks',\n type: 'array',\n of: [{type: 'mux.track'}],\n },\n {\n name: 'playback_ids',\n type: 'array',\n of: [{type: 'mux.playbackId'}],\n },\n {\n name: 'static_renditions',\n type: 'mux.staticRenditions',\n },\n ],\n}\n\nconst muxVideoAsset = {\n name: 'mux.videoAsset',\n type: 'document',\n title: 'Video asset',\n fields: [\n {\n type: 'string',\n name: 'status',\n },\n {\n type: 'string',\n name: 'assetId',\n },\n {\n type: 'string',\n name: 'playbackId',\n },\n {\n type: 'string',\n name: 'filename',\n },\n {\n type: 'number',\n name: 'thumbTime',\n },\n {\n type: 'mux.assetData',\n name: 'data',\n },\n ],\n}\n\nexport const schemaTypes = [\n muxTrack,\n muxPlaybackId,\n muxStaticRenditionFile,\n muxStaticRenditions,\n muxAssetData,\n muxVideoAsset,\n]\n","import {definePlugin} from 'sanity'\n\nimport createStudioTool, {DEFAULT_TOOL_CONFIG} from '../components/StudioTool'\nimport {muxVideoCustomRendering} from '../plugin'\nimport {muxVideoSchema, schemaTypes} from '../schema'\nimport type {PluginConfig, StaticRenditionResolution} from '../util/types'\nexport type {VideoAssetDocument} from '../util/types'\n\nexport const defaultConfig: PluginConfig = {\n static_renditions: [],\n mp4_support: 'none',\n video_quality: 'plus',\n max_resolution_tier: '1080p',\n normalize_audio: false,\n defaultPublic: true,\n defaultSigned: false,\n defaultDrm: false,\n tool: DEFAULT_TOOL_CONFIG,\n allowedRolesForConfiguration: [],\n acceptedMimeTypes: ['video/*', 'audio/*'],\n}\n\n/**\n * Converts legacy mp4_support configuration to static_renditions format\n */\nfunction convertLegacyConfig(config: Partial<PluginConfig>): {\n static_renditions: StaticRenditionResolution[]\n} {\n // If static_renditions is already provided, use it\n if (config.static_renditions && config.static_renditions.length > 0) {\n return {static_renditions: config.static_renditions}\n }\n\n // Convert legacy mp4_support to static_renditions\n if (config.mp4_support === 'standard') {\n return {static_renditions: ['highest']}\n }\n\n return {static_renditions: []}\n}\n\nexport const muxInput = definePlugin<Partial<PluginConfig> | void>((userConfig) => {\n // TODO: Remove this on next major version when we end support for encoding_tier\n if (typeof userConfig === 'object' && 'encoding_tier' in userConfig) {\n const deprecated_encoding_tier = userConfig.encoding_tier\n if (!userConfig.video_quality) {\n if (deprecated_encoding_tier === 'baseline') {\n userConfig.video_quality = 'basic'\n }\n if (deprecated_encoding_tier === 'smart') {\n userConfig.video_quality = 'plus'\n }\n }\n }\n const config: PluginConfig = {\n ...defaultConfig,\n ...(userConfig || {}),\n ...convertLegacyConfig(userConfig || {}),\n }\n return {\n name: 'mux-input',\n schema: {\n types: [\n ...schemaTypes,\n {\n ...muxVideoSchema,\n ...muxVideoCustomRendering(config),\n },\n ],\n },\n tools: config.tool === false ? undefined : [createStudioTool(config)],\n }\n})\n"],"names":["jsx","createContext","useState","useContext","Dialog","Stack","Button","jsxs","Card","Text","useSanityClient","words","trim","toLower","uniq","compact","createHookFromObservableFactory","useDocumentStore","useMemo","collate","defer","useCallback","path","useDocumentValues","useReducer","suspend","useId","useTheme_v2","styled","Fragment","Flex","Box","memo","useRef","clear","secretsId","preload","useEffect","FormField","TextInput","Checkbox","Code","Inline","truncateString","a","expand","timer","concatMap","of","tap","useClient","uuid","Image","Suspense","Spinner","ErrorOutlineIcon","useFormattedDuration","RetrieveIcon","InfoOutlineIcon","RetryIcon","CheckmarkCircleIcon","Heading","ChevronLeftIcon","Label","ChevronRightIcon","Radio","SyncIcon","MenuButton","SortIcon","Menu","MenuItem","useToast","LANGUAGE_OPTIONS","LanguagesList","name","UploadIcon","Autocomplete","TranslateIcon","DownloadIcon","EditIcon","TrashIcon","AddIcon","ChevronUpIcon","ChevronDownIcon","muxPlaybackId","MuxPlayer","WarningOutlineIcon","SanityDefaultPreview","useTimeAgo","document","Tooltip","TextWithTone","PublishIcon","isRecord","isValidElement","isString","isNumber","getPreviewStateObservable","useObservable","DocumentPreviewPresence","getPreviewValueWithFallback","IntentLink","useDocumentPreviewStore","useSchema","useDocumentPresence","DocumentIcon","PreviewCard","React","CheckmarkIcon","RevertIcon","TabList","Tab","SearchIcon","TabPanel","ClockIcon","CropIcon","CalendarIcon","TagIcon","LockIcon","PlayIcon","Grid","useCurrentUser","isReference","useProjectId","useDataset","useSWR","t","e","r","n","o","useErrorBoundary","scrollIntoView","PlugIcon","uploadUrl","Observable","upchunk","UpChunk","switchMap","concat","throwError","generateUuid","mergeMap","from","catchError","mergeMapTo","PatchEvent","unset","setIfMissing","set","SelectAsset","LinearProgress","css","isValidElementType","createElement","useClickOutsideEvent","Popover","ImageIcon","MenuDivider","ResetIcon","EllipsisHorizontalIcon","videoAspectRatio","u","WarningFilledIcon","_id","DocumentVideoIcon","rem","forwardRef","HiddenInput","Subject","takeUntil","PlayerActionsMenu","ErrorBoundaryCard","Input","definePlugin"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,MAAM,WAAW,MACfA,2BAAAA;AAAAA,EAAC;AAAA,EAAA;AAAA,IACC,QAAO;AAAA,IACP,MAAK;AAAA,IACL,aAAY;AAAA,IACZ,SAAQ;AAAA,IACR,QAAO;AAAA,IACP,OAAM;AAAA,IACN,OAAM;AAAA,IAEN,UAAAA,2BAAAA,IAAC,QAAA,EAAK,GAAE,iIAAA,CAAiI;AAAA,EAAA;AAC3I,GCVI,sCAAsC,6CAOtC,4BAA4BC,oBAAqD;AAAA,EACrF,iBAAiB;AAAA,EACjB,8BAA8B,MACrB;AAEX,CAAC,GAOY,oCAAoC,CAAC;AAAA,EAChD;AAAA,EACA;AACF,MAA8C;AAE5C,QAAM,aADkB,QAAQ,6BAA6B,OAExC,OAAO,aAAa,QAAQ,mCAAmC,MAAM,QACpF,CAAC,2BAA2B,4BAA4B,IAAIC,MAAAA,SAAS,SAAS,GAE9E,qBAAqB,CAAC,MAAe;AACzC,WAAO,aAAa,QAAQ,qCAAqC,EAAE,UAAU,GAC7E,6BAA6B,CAAC;AAAA,EAChC;AACA,SACEF,2BAAAA;AAAAA,IAAC,0BAA0B;AAAA,IAA1B;AAAA,MACC,OAAO;AAAA,QACL,iBAAiB;AAAA,QACjB,8BAA8B;AAAA,MAAA;AAAA,MAG/B;AAAA,IAAA;AAAA,EAAA;AAGP,GAEa,+BAA+B,MAC1BG,iBAAW,yBAAyB,GAIzC,mBAAmB,CAAC,EAAC,cAAoC;AACpE,QAAM,EAAC,6BAAA,IAAgC,6BAAA,GACjC,WAAW,MAAM;AACrB,iCAA6B,EAAI,GACjC,QAAA;AAAA,EACF;AACA,SACEH,2BAAAA;AAAAA,IAACI,GAAAA;AAAAA,IAAA;AAAA,MACC,MAAI;AAAA,MACJ,IAAG;AAAA,MACH,SAAS;AAAA,MACT,QAAO;AAAA,MACP,QACEJ,2BAAAA,IAACK,GAAAA,OAAA,EAAM,SAAS,GACd,UAAAL,2BAAAA,IAACM,WAAA,EAAO,MAAK,SAAQ,MAAK,WAAU,SAAS,UAAU,MAAK,MAAK,GACnE;AAAA,MAGF,UAAAC,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GAAG,SAAS,GACxB,UAAA;AAAA,QAAAL,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,QAAQ,GAChC,UAAAR,2BAAAA,IAACK,GAAAA,SAAM,OAAO,GACZ,yCAACI,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,wKAAA,CAGjC,EAAA,CACF,EAAA,CACF;AAAA,QACAT,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,QAAQ,GAAG,MAAK,WACxC,yCAACH,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAAL,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,iGAAA,CAGjC,EAAA,CACF,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN,GCzFa,qBAAqB;AAE3B,SAAS,YAAY;AAC1B,SAAOC,iBAAgB,EAAC,YAAY,oBAAmB;AACzD;ACHA,MAAM,gBAAgB,yCAChB,mBAAmB;AAEzB,SAAS,SAAS,QAA0B;AAC1C,UAAQ,OAAO,MAAM,aAAa,KAAK,CAAA,GAAI,IAAI,CAAC,UAAU,MAAM,QAAQ,kBAAkB,EAAE,CAAC;AAC/F;AAEA,SAAS,aAAa,OAAyC;AAC7D,QAAM,SAAiC,CAAA;AACvC,SAAO,MAAM,OAAO,CAAC,KAAK,MAAM,OAC9B,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,IAAI,KAChB,MACN,MAAM;AACX;AAaA,SAAS,sBAAsB,OAAyB;AACtD,QAAM,gBAAgB,CAAA,GAChB,gBAAgB,MAAM,QAAQ,cAAc,CAAC,UAC7CC,eAAAA,QAAM,KAAK,EAAE,SAAS,KACxB,cAAc,KAAK,KAAK,GACjB,MAEF,KACR,GAGK,cAAc,cAAc,IAAI,CAAC,QAAQC,cAAAA,QAAKC,iBAAAA,QAAQ,GAAG,CAAC,CAAC,GAO3D,iBAAiBC,cAAAA,QAAKC,iBAAAA,QAAQ,SAASF,yBAAQ,aAAa,CAAC,CAAC,CAAC;AAErE,SAAO,CAAC,GAAG,aAAa,GAAG,cAAc;AAC3C;AAMA,SAAS,kBAAkB,OAAiB,gBAAyB;AACnE,QAAM,cAAc,iBAAiB,CAAC,YAAY,SAAS,IAAI,CAAC,UAAU;AAK1E,SAJoB,MACjB,IAAI,CAAC,OAAO,MAAM,YAAY,IAAI,CAAC,eAAe,GAAG,UAAU,YAAY,CAAC,EAAE,CAAC,EAC/E,OAAO,CAAC,eAAe,WAAW,SAAS,CAAC,EAE5B,IAAI,CAAC,eAAe,IAAI,WAAW,KAAK,MAAM,CAAC,GAAG;AACvE;AAEO,SAAS,mBAAmB,OAAe;AAChD,QAAM,QAAQ,sBAAsB,KAAK;AAEzC,SAAO;AAAA,IACL,QAAQ,kBAAkB,OAAO,MAAM,UAAU,CAAC;AAAA;AAAA,IAClD,QAAQ;AAAA,MACN,GAAG,aAAa,KAAK;AAAA,IAAA;AAAA,EACvB;AAEJ;ACpEO,MAAM,qBAAqB;AAAA,EAChC,aAAa,EAAC,MAAM,mBAAmB,OAAO,eAAA;AAAA,EAC9C,YAAY,EAAC,MAAM,kBAAkB,OAAO,yBAAA;AAAA,EAC5C,aAAa,EAAC,MAAM,gBAAgB,OAAO,oBAAA;AAAA,EAC3C,cAAc,EAAC,MAAM,iBAAiB,OAAO,oBAAA;AAC/C,GAIM,oBAAoBG,OAAAA,gCAOxB,CAAC,EAAC,eAAe,MAAM,kBAAiB;AACxC,QAAM,SAAS,mBAAmB,WAAW,GACvC,SAAS,CAAC,6BAA6B,GAAG,OAAO,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK,MAAM,GAEpF,eAAe,mBAAmB,IAAI,EAAE;AAC9C,SAAO,cAAc;AAAA;AAAA,IACR,KAAK,MAAM,aAAa,YAAY;AAAA,IAC/C,OAAO;AAAA,IACP;AAAA,MACE,YAAY;AAAA,IAAA;AAAA,EACd;AAEJ,CAAC;AAED,SAAwB,YAAY;AAClC,QAAM,gBAAgBC,OAAAA,oBAChB,CAAC,MAAM,OAAO,IAAIf,MAAAA,SAAqB,aAAa,GACpD,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAS,EAAE,GAE3C,CAAC,iBAAiB,CAAA,GAAI,SAAS,IAAI;AAAA,IACvCgB,cAAQ,OAAO,EAAC,eAAe,MAAM,YAAA,IAAe,CAAC,eAAe,MAAM,WAAW,CAAC;AAAA,EAAA;AAgBxF,SAAO;AAAA,IACL,QAdaA,MAAAA;AAAAA,MACb;AAAA;AAAA,QAEEC,OAAAA,QAA4B,cAAc,EAAE;AAAA,UAC1C,CAAC,cACE;AAAA,YACC,GAAI,SAAS,SAAS,SAAS,aAAa,CAAA;AAAA,YAC5C,KAAK,SAAS;AAAA,UAAA;AAAA,QAChB;AAAA;AAAA,MAEN,CAAC,cAAc;AAAA,IAAA;AAAA,IAKf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AC7DO,SAAS,iBAAiB;AAC/B,SAAOjB,MAAAA,SAAsB,EAAK;AACpC;ACMO,SAAS,YACd,QACA,OACA,WACA,kBACA,cACA,mBACA,aAC0B;AAC1B,QAAM,MAAuB;AAAA,IAC3B,KAAK;AAAA,IACL,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEF,SAAA,IAAI,eAAe,mBAAmB,eAAe,IACrD,IAAI,oBAAoB,mBAAmB,oBAAoB,IAExD,OAAO,gBAAgB,GAAG;AACnC;AAEA,eAAsB,kBAAkB,QAAsB;AAC5D,MAAI;AACF,UAAM,EAAC,QAAA,IAAW,OAAO,OAAA;AAQzB,WAPY,MAAM,OAAO,QAEtB;AAAA,MACD,KAAK,4BAA4B,OAAO;AAAA,MACxC,iBAAiB;AAAA,MACjB,QAAQ;AAAA,IAAA,CACT;AAAA,EAEH,SAAS,OAAY;AACnB,YAAQ,MAAM,+BAA+B,KAAK;AAClD,UAAM,UACJ,MAAM,UAAU,eAAe,MAC3B,2GACA,MAAM;AACZ,UAAM,IAAI,MAAM,OAAO;AAAA,EACzB;AACF;AAEO,SAAS,YAAY,QAAsB;AAChD,QAAM,EAAC,QAAA,IAAW,OAAO,OAAA;AACzB,SAAO,OAAO,QAA2B;AAAA,IACvC,KAAK,uBAAuB,OAAO;AAAA,IACnC,iBAAiB;AAAA,IACjB,QAAQ;AAAA,EAAA,CACT;AACH;AAEA,eAAsB,qBACpB,QACA,cACA,mBACA;AACA,MAAI,EAAE,gBAAgB;AACpB,WAAO;AAGT,QAAM,EAAC,QAAA,IAAW,OAAO,OAAA;AACzB,MAAI;AACF,UAAM,MAAM,MAAM,OAAO,QAAkD;AAAA,MACzE,KAAK,4BAA4B,OAAO,IAAI,YAAY;AAAA,MACxD,iBAAiB;AAAA,MACjB,QAAQ;AAAA,IAAA,CACT;AAID,WAAO,CAAC,EAAE,IAAI,QAAQ,IAAI,KAAK;AAAA,EACjC,QAAY;AACV,WAAA,QAAQ,MAAM,+BAA+B,cAAc,0BAA0B,GAC9E;AAAA,EACT;AACF;AAEO,SAAS,sBAAsB,QAAsB;AAC1D,QAAM,EAAC,QAAA,IAAW,OAAO,OAAA;AACzB,SAAOkB,KAAAA;AAAAA,IAAM,MACX,OAAO,WAAW,QAA2B;AAAA,MAC3C,KAAK,uBAAuB,OAAO;AAAA,MACnC,iBAAiB;AAAA,MACjB,QAAQ;AAAA,IAAA,CACT;AAAA,EAAA;AAEL;AClGO,MAAM,iBAAiB,CAAC,QAAsB,YAC5CC,MAAAA;AAAAA,EACL,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,MAIsB;AACtB,QAAI,EAAC,cAAc,kBAAA,IAAqB;AAExC,QAAI;AAWF,UAVA,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,GAGE,EADU,MAAM,YAAY,MAAM,IAC1B,UAAU,SAAS;AAC7B,cAAM,IAAI,MAAM,iBAAiB;AAAA,IAErC,SAAS,KAAK;AACZ,YAAA,QAAQ,MAAM,uCAAuC,GAAG,GAClD;AAAA,IACR;AAEA,QAAI,oBAOE,CANwB,MAAM;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAIA,UAAI;AACF,cAAM,EAAC,KAAA,IAAQ,MAAM,kBAAkB,MAAM;AAC7C,uBAAe,KAAK,IACpB,oBAAoB,KAAK,aACzB,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,eAAe;AAAA,QAAA;AAAA,MAEnB,SAAS,KAAU;AAEjB,cAAA,QAAQ,IAAI,gDAAgD,KAAK,OAAO,GAClE;AAAA,MACR;AAGJ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA,EACA,CAAC,QAAQ,OAAO;AAClB,GC5EW,OAAO,aAGP,UAAU,2BAEV,uBAAuB,eAEvB,kBAAkB,KAElB,yBAAyB,oBAGzB,mBAAmB,IAAI,GAEvB,qBAAqB,IAAI,GCRhCC,SAAO;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GACa,2BAA2B,MAAM;AAC5C,QAAM,EAAC,OAAO,WAAW,MAAA,IAASC,OAAAA;AAAAA,IAChC;AAAA,IACAD;AAAAA,EAAA,GAEI,QAAQJ,MAAAA,QAAQ,MAAM;AAC1B,UAAM,SAAS,CAAA,CAAQ,OACjB,UAAmB;AAAA,MACvB,OAAO,OAAO,SAAS;AAAA,MACvB,WAAW,OAAO,aAAa;AAAA,MAC/B,kBAAkB,OAAO,oBAAoB;AAAA,MAC7C,cAAc,OAAO,gBAAgB;AAAA,MACrC,mBAAmB,OAAO,qBAAqB;AAAA,MAC/C,aAAa,OAAO,eAAe;AAAA,IAAA;AAErC,WAAO;AAAA,MACL,gBAAgB,CAAC;AAAA,MACjB,YAAY,CAAC,SAAS,SAAS,CAAC,SAAS;AAAA,MACzC;AAAA,IAAA;AAAA,EAEJ,GAAG,CAAC,KAAK,CAAC;AAEV,SAAO,EAAC,OAAO,WAAW,OAAO,MAAA;AACnC;ACpBA,SAAS,KAAK,EAAC,OAAO,WAAW,kBAAkB,eAA8B;AAC/E,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,OAAO;AAAA;AAAA;AAAA,IAGP,OAAO,SAAS;AAAA,IAChB,WAAW,aAAa;AAAA,IACxB,kBAAkB,oBAAoB;AAAA,IACtC,aAAa,eAAe;AAAA,EAAA;AAEhC;AACA,SAAS,QAAQ,OAAc,QAAgB;AAC7C,UAAQ,QAAQ,MAAA;AAAA,IACd,KAAK;AACH,aAAO,EAAC,GAAG,OAAO,YAAY,IAAM,OAAO,KAAA;AAAA,IAC7C,KAAK;AACH,aAAO,EAAC,GAAG,OAAO,YAAY,IAAO,OAAO,OAAO,QAAA;AAAA,IACrD,KAAK;AACH,aAAO,KAAK,OAAO,OAAO;AAAA,IAC5B,KAAK;AACH,aAAO,EAAC,GAAG,OAAO,CAAC,OAAO,QAAQ,IAAI,GAAG,OAAO,QAAQ,MAAA;AAAA,IAC1D;AACE,YAAM,IAAI,MAAM,wBAAyB,QAA8B,IAAI,EAAE;AAAA,EAAA;AAEnF;AAEO,MAAM,sBAAsB,CAAC,YAAqBM,MAAAA,WAAW,SAAS,SAAS,IAAI,GChC7E,MAAM;AAEZ,SAAS,YAAY,QAA+B;AACzD,QAAM,EAAC,WAAW,YAAW,OAAO,OAAA;AACpC,SAAOC,aAAAA,QAAQ,YAAY;AACzB,UAAM,OAAO,MAAM,OAAO;AAAA;AAAA,MACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQX,EAAC,IAAA;AAAA,IAAG;AAEN,WAAO;AAAA,MACL,OAAO,MAAM,SAAS;AAAA,MACtB,WAAW,MAAM,aAAa;AAAA,MAC9B,kBAAkB,CAAA,CAAQ,MAAM,oBAAqB;AAAA,MACrD,cAAc,MAAM,gBAAgB;AAAA,MACpC,mBAAmB,MAAM,qBAAqB;AAAA,MAC9C,aAAa,MAAM,eAAe;AAAA,IAAA;AAAA,EAEtC,GAAG,CAAC,SAAS,KAAK,WAAW,OAAO,CAAC;AACvC;AC/BA,SAAwB,QAAQ,EAAC,SAAS,MAAY;AACpD,QAAM,KAAKC,MAAAA,SAEL,YADQC,GAAAA,cACU,MAAM,QAAQ,UAAU,SAC1C,UAAUT,MAAAA,QAAQ,MAAM,GAAG,EAAE,UAAU,CAAC,EAAE,CAAC,GAE3C,YAA2B;AAAA,IAC/B,UAAU;AAAA,EAAA;AAGZ,SACElB,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,mBAAiB;AAAA,MACjB,OAAO,EAAC,QAAQ,GAAG,MAAM,KAAA;AAAA,MACzB,SAAQ;AAAA,MACR,SAAQ;AAAA,MACR,OAAM;AAAA,MACN,UAAS;AAAA,MAET,UAAAO,2BAAAA,KAAC,KAAA,EAAE,IAAG,WAAU,MAAM,WACpB,UAAA;AAAA,QAAAP,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,GAAE;AAAA,YACF,OAAO;AAAA,UAAA;AAAA,QAAA;AAAA,QAETA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,GAAE;AAAA,YACF,OAAO;AAAA,UAAA;AAAA,QAAA;AAAA,QAETA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,GAAE;AAAA,YACF,OAAO;AAAA,UAAA;AAAA,QAAA;AAAA,MACT,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;ACrCA,MAAM,OAAO4B,iBAAAA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,GAOP,SAAS,MACpBrB,2BAAAA,KAAAsB,WAAAA,UAAA,EACE,UAAA;AAAA,EAAA7B,+BAAC,MAAA,EACC,UAAAA,2BAAAA,IAAC,SAAA,EAAQ,QAAQ,IAAI,GACvB;AAAA,EAAO;AAAA,GAET;ACLF,SAAS,UAAU,OAAc;AAC/B,QAAM,EAAC,UAAU,OAAO,aAAa,YAAW;AAEhD,SACEO,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,IAAAL,+BAAC8B,GAAAA,MAAA,EAAK,OAAM,YACV,UAAA9B,2BAAAA,IAAC+B,GAAAA,KAAA,EAAI,MAAM,GAAG,UAAU,GACtB,UAAAxB,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,MAAAL,+BAACS,GAAAA,MAAA,EAAK,IAAG,SAAQ,SAAS,SAAS,QAAO,YAAW,MAAM,GACxD,UAAA,SAAST,+BAAC,MAAA,EAAG,sBAAQ,GACxB;AAAA,MAEC,eACCA,2BAAAA,IAACS,GAAAA,MAAA,EAAK,OAAK,IAAC,MAAM,GACf,UAAA,YAAA,CACH;AAAA,IAAA,EAAA,CAEJ,GACF,GACF;AAAA,IACAT,+BAAC,SAAK,SAAA,CAAS;AAAA,EAAA,GACjB;AAEJ;AAEA,IAAA,cAAegC,MAAAA,KAAK,SAAS;ACH7B,MAAM,aAAa,CAAC,SAAS,aAAa,oBAAoB,aAAa;AAGpE,SAAS,mBAAmB,EAAC,SAAS,kBAA0C;AACrF,QAAM,SAAS,UAAA,GACT,CAAC,OAAO,QAAQ,IAAI,oBAAoB,OAAO,GAC/C,sBAAsBd,cAAQ,MAAM,QAAQ,SAAS,QAAQ,WAAW,CAAC,OAAO,CAAC,GACjF,cAAcG,MAAAA,YAAY,MAAM,eAAe,EAAK,GAAG,CAAC,cAAc,CAAC,GACvE,QAAQH,MAAAA;AAAAA,IACZ,MACE,QAAQ,UAAU,MAAM,SACxB,QAAQ,cAAc,MAAM,aAC5B,QAAQ,qBAAqB,MAAM,oBACnC,QAAQ,gBAAgB,MAAM;AAAA,IAChC,CAAC,SAAS,KAAK;AAAA,EAAA,GAEX,KAAK,eAAeQ,MAAAA,OAAO,IAC3B,CAAC,SAAS,aAAa,oBAAoB,aAAa,IAAIR,MAAAA;AAAAA,IAChE,MAAM,WAAW,IAAI,CAAC,UAAU,GAAG,EAAE,IAAI,KAAK,EAAE;AAAA,IAChD,CAAC,EAAE;AAAA,EAAA,GAEC,aAAae,MAAAA,OAAyB,IAAI,GAC1C,oBAAoB,eAAe,QAAQ,OAAO,GAClD,SAASA,MAAAA,OAAO,EAAK,GAErB,eAAeZ,MAAAA;AAAAA,IACnB,CAAC,UAA4C;AAG3C,UAFA,MAAM,kBAEF,CAAC,OAAO,WAAW,MAAM,cAAc,kBAAkB;AAC3D,eAAO,UAAU,IACjB,SAAS,EAAC,MAAM,UAAS;AACzB,cAAM,EAAC,OAAO,WAAW,kBAAkB,gBAAe;AAC1D,0BAAkB,EAAC,OAAO,WAAW,kBAAkB,aAAY,EAChE,KAAK,CAAC,iBAAiB;AACtB,gBAAM,EAAC,WAAW,YAAW,OAAO,OAAA;AACpCa,6BAAM,CAAC,SAASC,KAAW,WAAW,OAAO,CAAC,GAC9CC,aAAAA,QAAQ,MAAM,QAAQ,QAAQ,YAAY,GAAG,CAAC,SAASD,KAAW,WAAW,OAAO,CAAC,GACrF,eAAe,EAAK;AAAA,QACtB,CAAC,EACA,MAAM,CAAC,QAAQ,SAAS,EAAC,MAAM,SAAS,SAAS,IAAI,QAAA,CAAQ,CAAC,EAC9D,QAAQ,MAAM;AACb,iBAAO,UAAU;AAAA,QACnB,CAAC;AAAA,MACL;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,UAAU,mBAAmB,gBAAgB,KAAK;AAAA,EAAA,GAEvD,oBAAoBd,MAAAA;AAAAA,IACxB,CAAC,UAA6C;AAC5C,eAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS,EAAC,MAAM,SAAS,OAAO,MAAM,cAAc,MAAA;AAAA,MAAK,CAC1D;AAAA,IACH;AAAA,IACA,CAAC,QAAQ;AAAA,EAAA,GAEL,wBAAwBA,MAAAA;AAAAA,IAC5B,CAAC,UAA6C;AAC5C,eAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS,EAAC,MAAM,aAAa,OAAO,MAAM,cAAc,MAAA;AAAA,MAAK,CAC9D;AAAA,IACH;AAAA,IACA,CAAC,QAAQ;AAAA,EAAA,GAEL,+BAA+BA,MAAAA;AAAAA,IACnC,CAAC,UAA6C;AAC5C,eAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS,EAAC,MAAM,oBAAoB,OAAO,MAAM,cAAc,QAAA;AAAA,MAAO,CACvE;AAAA,IACH;AAAA,IACA,CAAC,QAAQ;AAAA,EAAA,GAEL,0BAA0BA,MAAAA;AAAAA,IAC9B,CAAC,UAA6C;AAC5C,eAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS,EAAC,MAAM,eAAe,OAAO,MAAM,cAAc,MAAA;AAAA,MAAK,CAChE;AAAA,IACH;AAAA,IACA,CAAC,QAAQ;AAAA,EAAA;AAGX,SAAAgB,MAAAA,UAAU,MAAM;AACV,eAAW,WACb,WAAW,QAAQ,MAAA;AAAA,EAEvB,GAAG,CAAC,UAAU,CAAC,GAGbrC,2BAAAA;AAAAA,IAACI,GAAAA;AAAAA,IAAA;AAAA,MACC,SAAO;AAAA,MACP;AAAA,MACA,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,uCAAS,QAAA,EAAO;AAAA,MAChB,SAAS;AAAA,MACT,UAAS;AAAA,MACT,OAAO;AAAA,MAEP,UAAAJ,2BAAAA,IAAC+B,GAAAA,KAAA,EAAI,SAAS,GACZ,UAAA/B,+BAAC,QAAA,EAAK,UAAU,cAAc,YAAU,IACtC,UAAAO,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACX,UAAA;AAAA,QAAA,CAAC,uBACAL,+BAACQ,GAAAA,MAAA,EAAK,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAK,WACnD,UAAAD,gCAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAE,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA;AAAA,YAAA;AAAA,YAC4B;AAAA,YACzCT,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,QAAO;AAAA,gBACP,KAAI;AAAA,gBACL,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAEG;AAAA,UAAA,GAEN;AAAA,UACAO,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA;AAAA,YAAA;AAAA,YACuBT,2BAAAA,IAAC,YAAO,UAAA,aAAA,CAAU;AAAA,YAAS;AAAA,YAC7CA,2BAAAA,IAAC,YAAO,UAAA,WAAA,CAAQ;AAAA,YAAS;AAAA,2CAC1C,MAAA,EAAG;AAAA,YAAE;AAAA,2CAEL,MAAA,EAAG;AAAA,YAAE;AAAA,UAAA,EAAA,CAGR;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QAEFA,2BAAAA,IAACsC,aAAA,EAAU,OAAM,gBAAe,SAAS,SACvC,UAAAtC,2BAAAA;AAAAA,UAACuC,GAAAA;AAAAA,UAAA;AAAA,YACC,IAAI;AAAA,YACJ,KAAK;AAAA,YACL,UAAU;AAAA,YACV,MAAK;AAAA,YACL,OAAO,MAAM,SAAS;AAAA,YACtB,UAAU,CAAC,CAAC,MAAM,aAAa,MAAM;AAAA,UAAA;AAAA,QAAA,GAEzC;AAAA,QACAvC,2BAAAA,IAACsC,aAAA,EAAU,OAAM,cAAa,SAAS,aACrC,UAAAtC,2BAAAA;AAAAA,UAACuC,GAAAA;AAAAA,UAAA;AAAA,YACC,IAAI;AAAA,YACJ,UAAU;AAAA,YACV,MAAK;AAAA,YACL,OAAO,MAAM,aAAa;AAAA,YAC1B,UAAU,CAAC,CAAC,MAAM,SAAS,MAAM;AAAA,UAAA;AAAA,QAAA,GAErC;AAAA,QAEAhC,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAE,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UACV,UAAA;AAAA,YAAA9B,2BAAAA;AAAAA,cAACwC,GAAAA;AAAAA,cAAA;AAAA,gBACC,IAAI;AAAA,gBACJ,UAAU;AAAA,gBACV,SAAS,MAAM;AAAA,gBACf,OAAO,EAAC,SAAS,QAAA;AAAA,cAAO;AAAA,YAAA;AAAA,YAE1BxC,+BAAC+B,GAAAA,KAAA,EAAI,MAAM,GAAG,aAAa,GACzB,UAAA/B,2BAAAA,IAACS,GAAAA,MAAA,EACC,UAAAT,2BAAAA,IAAC,SAAA,EAAM,SAAS,oBAAoB,UAAA,sBAAkB,GACxD,EAAA,CACF;AAAA,UAAA,GACF;AAAA,UACC,QAAQ,gBAAgB,MAAM,kDAC5BQ,SAAA,EAAK,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAK,WACnD,UAAAD,2BAAAA,KAACF,UAAA,EAAM,OAAO,GACZ,UAAA;AAAA,YAAAL,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA,+CAA2C;AAAA,YAC1DT,2BAAAA,IAACyC,GAAAA,MAAA,EAAK,MAAM,GAAI,kBAAQ,cAAa;AAAA,YACrClC,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA;AAAA,cAAA;AAAA,6CAEZ,MAAA,EAAG;AAAA,cAAE;AAAA,YAAA,EAAA,CAER;AAAA,UAAA,EAAA,CACF,GACF,IACE;AAAA,QAAA,GACN;AAAA,QAEAT,2BAAAA,IAACsC,aAAA,EAAU,OAAM,wBAAuB,SAAS,eAC/C,UAAAtC,2BAAAA;AAAAA,UAACuC,GAAAA;AAAAA,UAAA;AAAA,YACC,IAAI;AAAA,YACJ,UAAU;AAAA,YACV,MAAK;AAAA,YACL,OAAO,MAAM,eAAe;AAAA,YAC5B,UAAU;AAAA,UAAA;AAAA,QAAA,GAEd;AAAA,uCACC/B,GAAAA,MAAA,EAAK,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAK,WACnD,UAAAD,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAE,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA;AAAA,YAAA;AAAA,YAE6D;AAAA,YAC1ET,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,QAAO;AAAA,gBACP,KAAI;AAAA,gBACL,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAEG;AAAA,UAAA,GAEN;AAAA,UACAO,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GACV,UAAA;AAAA,YAAAT,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,QAAO;AAAA,gBACP,KAAI;AAAA,gBACL,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAEI;AAAA,YAAI;AAAA,UAAA,EAAA,CAEX;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QAEAO,2BAAAA,KAACmC,GAAAA,QAAA,EAAO,OAAO,GACb,UAAA;AAAA,UAAA1C,2BAAAA;AAAAA,YAACM,GAAAA;AAAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,UAAU,CAAC;AAAA,cACX,SAAS,MAAM;AAAA,cACf,MAAK;AAAA,cACL,MAAK;AAAA,cACL,MAAK;AAAA,YAAA;AAAA,UAAA;AAAA,UAEPN,2BAAAA;AAAAA,YAACM,GAAAA;AAAAA,YAAA;AAAA,cACC,UAAU,MAAM;AAAA,cAChB,MAAK;AAAA,cACL,MAAK;AAAA,cACL,SAAS;AAAA,YAAA;AAAA,UAAA;AAAA,QACX,GACF;AAAA,QACC,MAAM,SACLN,+BAACQ,GAAAA,MAAA,EAAK,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAK,YACnD,yCAACC,GAAAA,MAAA,EAAM,UAAA,MAAM,OAAM,EAAA,CACrB;AAAA,MAAA,EAAA,CAEJ,GACF,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;AAGA,SAAwB,eAAe;AACrC,QAAM,CAAC,YAAY,aAAa,IAAI,eAAA,GAC9B,uBAAuB,yBAAA,GAEvB,aAAaY,MAAAA,YAAY,MAAM,cAAc,SAAS,GAAG,CAAC,aAAa,CAAC;AAE9E,SAAI,eAAe,YAEfrB,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,SAAS,qBAAqB,MAAM;AAAA,MACpC,gBAAgB;AAAA,IAAA;AAAA,EAAA,mCAKdM,WAAA,EAAO,MAAK,SAAQ,MAAK,oBAAmB,SAAS,YAAY;AAC3E;AC9RO,SAAS,yBAAyB,SAAyB;AAChE,SAAO,UAAUqC,OAAAA,eAAe,SAAS,EAAE,CAAC;AAC9C;AAUO,SAAS,0BAA0B,UAA8B,SAA0B;AAEhG,MAAI,CAAC,YAAY,SAAS,KAAA,MAAW;AACnC,WAAO;AAIT,QAAM,cAAc,yBAAyB,OAAO;AACpD,SAAO,aAAa;AACtB;AC5BO,SAAS,aAAa,MAAoC;AAC/D,SAAO,IAAI,KAAK,OAAO,IAAI,IAAI,GAAI;AACrC;ACAO,SAAS,iBAAiB,QAAsB,SAAiB;AACtE,QAAM,EAAC,QAAA,IAAW,OAAO,OAAA;AACzB,SAAO,OAAO,QAAc;AAAA,IAC1B,KAAK,sBAAsB,OAAO,IAAI,OAAO;AAAA,IAC7C,iBAAiB;AAAA,IACjB,QAAQ;AAAA,EAAA,CACT;AACH;AAEA,eAAsB,YAAY;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,MAAI,CAAC,OAAO,IAAK,QAAO;AAExB,MAAI;AACF,UAAM,OAAO,OAAO,MAAM,GAAG;AAAA,EAC/B,QAAgB;AACd,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,OAAO;AACxB,QAAI;AACF,YAAM,iBAAiB,QAAQ,MAAM,OAAO;AAAA,IAC9C,QAAgB;AACd,aAAO;AAAA,IACT;AAGF,SAAO;AACT;AAEO,SAAS,SAAS,QAAsB,SAAiB;AAC9D,QAAM,EAAC,QAAA,IAAW,OAAO,OAAA;AACzB,SAAO,OAAO,QAA0B;AAAA,IACtC,KAAK,sBAAsB,OAAO,SAAS,OAAO;AAAA,IAClD,iBAAiB;AAAA,IACjB,QAAQ;AAAA,EAAA,CACT;AACH;AAEO,SAAS,WACd,QACA,SACA;AACA,QAAM,EAAC,QAAA,IAAW,OAAO,OAAA,GACnB,QAA2C,CAAA;AAEjD,SAAI,QAAQ,UACV,MAAM,QAAQ,QAAQ,MAAM,SAAA,IAE1B,QAAQ,WACV,MAAM,SAAS,QAAQ,SAGlB,OAAO,QAAyD;AAAA,IACrE,KAAK,sBAAsB,OAAO;AAAA,IAClC,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR;AAAA,EAAA,CACD;AACH;AAKO,SAAS,oBACd,QACA,SACA,QACA,SAKA;AACA,QAAM,EAAC,QAAA,IAAW,OAAO,OAAA;AAEzB,SAAO,OAAO,QAA0B;AAAA,IACtC,KAAK,sBAAsB,OAAO,IAAI,OAAO;AAAA,IAC7C,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,MAAM;AAAA,MACJ,KAAK;AAAA,MACL,MAAM;AAAA,MACN,eAAe,QAAQ;AAAA,MACvB,MAAM,QAAQ;AAAA,MACd,WAAW,QAAQ,aAAa;AAAA,IAAA;AAAA,IAElC,SAAS;AAAA,MACP,gBAAgB;AAAA,IAAA;AAAA,EAClB,CACD;AACH;AAKO,SAAS,kBACd,QACA,SACA,cACA,SAIA;AACA,QAAM,EAAC,QAAA,IAAW,OAAO,OAAA;AACzB,SAAO,OAAO,QAA0B;AAAA,IACtC,KAAK,sBAAsB,OAAO,IAAI,OAAO,WAAW,YAAY;AAAA,IACpE,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,MAAM;AAAA,MACJ,qBAAqB;AAAA,QACnB;AAAA,UACE,eAAe,QAAQ;AAAA,UACvB,MAAM,QAAQ;AAAA,QAAA;AAAA,MAChB;AAAA,IACF;AAAA,IAEF,SAAS;AAAA,MACP,gBAAgB;AAAA,IAAA;AAAA,EAClB,CACD;AACH;AAKO,SAAS,gBAAgB,QAAsB,SAAiB,SAAiB;AACtF,QAAM,EAAC,QAAA,IAAW,OAAO,OAAA;AACzB,SAAO,OAAO,QAA0B;AAAA,IACtC,KAAK,sBAAsB,OAAO,IAAI,OAAO,WAAW,OAAO;AAAA,IAC/D,iBAAiB;AAAA,IACjB,QAAQ;AAAA,EAAA,CACT;AACH;ACzIA,MAAM,kBAAkB;AA+BxB,eAAe,mBACb,QACA,QACqB;AACrB,MAAI;AACF,UAAM,WAAW,MAAM,WAAW,QAAQ;AAAA,MACxC,OAAO;AAAA,MACP;AAAA,IAAA,CACD;AAED,WAAO;AAAA,MACL;AAAA,MACA,MAAM,SAAS;AAAA,MACf,aAAa,SAAS,eAAe;AAAA,IAAA;AAAA,EAEzC,QAAgB;AACd,WAAO;AAAA,MACL;AAAA,MACA,OAAO,EAAC,MAAM,aAAA;AAAA,IAAY;AAAA,EAE9B;AACF;AAEA,SAAS,4BACP,cACA,YACgB;AAChB,QAAM,cAAe,UAAU,gBAAgB,aAAa,QAAS,CAAA,GAC/D,YAAa,UAAU,cAAc,WAAW,QAAS,CAAA,GAGzD,EAAC,aAAa,kBAAA,IAAqB,UAAU;AAAA,IAIjD,CAAC,KAAK,UAAU;AACd,YAAM,iBAAiB,MAAM,gBAAgB,MAAM,aAAa,SAAS,GACnE,cAAc,YAAY,KAAK,CAACC,OAAMA,GAAE,OAAO,MAAM,EAAE;AAE7D,aAAK,mBACH,IAAI,oBAAoB,KAGtB,kBAAkB,CAAC,eACrB,IAAI,YAAY,KAAK,KAAK,GAGrB;AAAA,IACT;AAAA,IACA,EAAC,aAAa,IAAI,mBAAmB,GAAA;AAAA,EAAK;AAG5C,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM,CAAC,GAAG,aAAa,GAAG,WAAW;AAAA,IACrC,OACE,WAAW,aACP,WAAW;AAAA;AAAA,MAEX;AAAA;AAAA,IACN,QAAQ,iBAAiB,aAAa,WAAW,cAAc,WAAW;AAAA,IAC1E,SAAS;AAAA,IACT,iCACE,aAAa,mCAAmC;AAAA,EAAA;AAEtD;AAEA,SAAS,aAAa,YAAwB;AAC5C,SACE,OAAO,cAAe,YAAY,iBAAiB,cAAc,WAAW,gBAAgB;AAEhG;AAUA,SAAwB,aAAa,EAAC,QAAQ,WAAoD;AAChG,QAAM,CAAC,OAAO,QAAQ,IAAI1C,MAAAA,SAAyB,EAAC,SAAS,IAAM,QAAQ,MAAK;AAEhF,SAAAmC,MAAAA,UAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,UAAM,eAAejB,KAAAA;AAAAA,MAAM,MACzB;AAAA,QACE;AAAA;AAAA,QAEA,UAAU,SAAS,MAAM,QAAQ,MAAM,KAAK,SAAS,KAAK,CAAC,MAAM,QAAQ,MAAM,SAAS;AAAA,MAAA;AAAA,IAC1F,EAEC;AAAA;AAAA,MAECyB,UAAAA,OAAO,CAAC,eAGF,aAAa,UAAU,IAClBC,KAAAA,MAAM,GAAI,EAAE;AAAA,QACjBC,UAAAA;AAAAA,UAAU;AAAA;AAAA,YAER3B,KAAAA;AAAAA,cAAM,MACJ;AAAA,gBACE;AAAA,gBACA,iBAAiB,aAAa,WAAW,cAAc;AAAA,cAAA;AAAA,YACzD;AAAA;AAAA,QACF;AAAA,MACF,IAKG4B,KAAAA,IACR;AAAA;AAAA,MAGDC,UAAAA;AAAAA,QAAI,CAAC,eACH,SAAS,CAAC,cAAc,4BAA4B,WAAW,UAAU,CAAC;AAAA,MAAA;AAAA,IAC5E,EAED,UAAU;AAAA;AAAA,MAET,UAAU,MAAM;AACd,iBAAS,CAAC,UAAU;AAAA,UAClB,GAAG;AAAA,UACH,SAAS;AAAA,QAAA,EACT;AAAA,MACJ;AAAA,IAAA,CACD;AAIH,WAAO,MAAM,aAAa,YAAA;AAAA,EAE5B,GAAG,CAAC,OAAO,CAAC,GAEL;AACT;AC3JA,SAAwB,qBAAqB;AAC3C,QAAM,gBAAgBhC,OAAAA,oBAChB,SAASiC,OAAAA,UAAU;AAAA,IACvB,YAAY;AAAA,EAAA,CACb,GAEK,CAAC,gBAAgB,qBAAqB,IAAI,kBAAkB,aAAa,GAGzE,aAAa,CAAC,CADS,yBAAA,EACa,MAAM,SAAS,WAEnD,CAAC,aAAa,cAAc,IAAIhD,MAAAA,SAAA,GAChC,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAsB,QAAQ,GAC9D,aAAa,gBAAgB,UAE7B,YAAY,aAAa;AAAA,IAC7B;AAAA,IACA,SAAS,cAAc;AAAA,EAAA,CACxB,GAEK,gBAAgBgB,MAAAA,QAAQ,MACrB,kBAAkB,UAAU,OAC/B,UAAU,KAAK,OAAO,CAAC0B,OAAM,CAAC,oBAAoBA,IAAG,cAAc,CAAC,IACpE,QACH,CAAC,gBAAgB,UAAU,IAAI,CAAC,GAE7B,CAAC,gBAAgB,iBAAiB,IAAI1C,MAAAA,SAAqB,CAAA,CAAE,GAE7D,cAAc,MAAM;AACpB,oBAAgB,eAAa,eAAe,QAAQ;AAAA,EAC1D,GACM,aAAa,MAAM;AACnB,oBAAgB,YAAU,eAAe,MAAM;AAAA,EACrD;AAEA,iBAAe,eAAe;AAC5B,mBAAe,WAAW;AAC1B,UAAM,YAAY,eAAe,QAAQ,CAAC,UAAU,yBAAyB,KAAK,KAAK,CAAA,CAAE,GAEnF,KAAK,OAAO,YAAA;AAClB,cAAU,QAAQ,CAAC,QAAQ,GAAG,OAAO,GAAG,CAAC;AAEzC,QAAI;AACF,YAAM,GAAG,OAAO,EAAC,iBAAiB,IAAM,GACxC,kBAAkB,CAAA,CAAE,GACpB,eAAe,MAAM;AAAA,IACvB,SAAS,OAAO;AACd,qBAAe,OAAO,GACtB,eAAe,KAAK;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AAEA,SAAS,yBAAyB,OAAiD;AACjF,QAAM,cAAc,MAAM,gBAAgB,CAAA,GAAI,KAAK,CAAC,MAAM,EAAE,EAAE,GAAG;AAEjE,MAAK;AAEL,WAAO;AAAA,MACL,KAAKiD,KAAAA,KAAA;AAAA,MACL,OAAO;AAAA,MACP,aAAY,oBAAI,KAAA,GAAO,YAAA;AAAA,MACvB,YAAY,aAAa,MAAM,UAAU,EAAE,YAAA;AAAA,MAC3C,SAAS,MAAM;AAAA,MACf;AAAA,MACA,UAAU,MAAM,MAAM,SAAS,yBAAyB,MAAM,EAAE;AAAA,MAChE,QAAQ,MAAM;AAAA,MACd,MAAM;AAAA,IAAA;AAEV;AAEA,MAAM,oBAAoBnC,OAAAA;AAAAA,EACxB,CAAC,kBACQ,cAAc;AAAA;AAAA,IACR;AAAA;AAAA;AAAA;AAAA,IAIX,CAAA;AAAA,IACA;AAAA,MACE,YAAY;AAAA,IAAA;AAAA,EACd;AAGN;AAEA,SAAS,oBAAoB,OAAiB,gBAAiC;AAE7E,SAAI,MAAM,WAAW,UAAgB,KAE9B,eAAe;AAAA,IACpB,CAAC,aAAa,SAAS,YAAY,MAAM,MAAM,SAAS,aAAa,MAAM;AAAA,EAAA;AAE/E;AC1HO,SAAS,UACd,KACA,UAA+B,IAC/B;AACA,QAAM,CAAC,QAAQ,SAAS,IAAId,MAAAA,SAAS,EAAK;AAE1C,SAAAmC,MAAAA,UAAU,MAAM;AACd,QAAI,CAAC,IAAI,QAAS;AAElB,UAAM,WAAW,IAAI,qBAAqB,CAAC,CAAC,KAAK,GAAG,QAAQ;AAI1D,YAAM,YACJ,MAAM,kBACN,IAAI,WAAW,KAAK,CAAC,cAAc,MAAM,qBAAqB,SAAS;AAGzE,gBAAU,SAAS,GACnB,SAAS,WAAW,SAAS;AAAA,IAC/B,GAAG,OAAO,GAEJ,YAAY,IAAI;AACtB,WAAA,SAAS,QAAQ,SAAS,GAGnB,MAAM;AACP,mBAAW,SAAS,UAAU,SAAS;AAAA,IAC7C;AAAA,EACF,GAAG,CAAC,SAAS,GAAG,CAAC,GAEV;AACT;AC9BO,SAAS,cACd,OACA,WAAqB,CAAC,OAAO,UAAU,QAAQ,GACvC;AACR,MAAI;AACF,QAAI,CAAC;AACH,YAAM,IAAI,UAAU,wCAAwC;AAG9D,UAAM,cAAc,MAAM,MAAM;AAChC,QAAI,eAAe,YAAY,SAAS,GAAG;AACzC,iBAAW,UAAU,UAAU;AAC7B,cAAM,QAAQ,YAAY,KAAK,CAAC,UAAU,MAAM,WAAW,MAAM;AACjE,YAAI;AACF,iBAAO,MAAM;AAAA,MAEjB;AAEA,aAAO,YAAY,CAAC,EAAE;AAAA,IACxB;AAEA,UAAM,IAAI,UAAU,oBAAoB;AAAA,EAC1C,SAAS,GAAG;AACV,UAAA,QAAQ,MAAM,iCAAiC,EAAC,MAAA,GAAQ,CAAC,GACnD;AAAA,EACR;AACF;AAEO,SAAS,kBACd,OAC2B;AAC3B,SACE,MAAM,MAAM,cAAc;AAAA,IACxB,CAAC,eAAe,cAAc,OAAO,CAAC,OAAO,UAAU,QAAQ,CAAC,MAAM,WAAW;AAAA,EAAA,KAC9E,EAAC,IAAI,IAAI,QAAQ,SAAA;AAE1B;AAEO,SAAS,sBACd,OACA,YAC2B;AAC3B,SAAO,MAAM,MAAM,cAAc,KAAK,CAAC,UAAU,eAAe,MAAM,EAAE;AAC1E;AAEO,SAAS,kBACd,MAIA,QACA;AACA,SACG,KAAK,8BACJ,KAAK,2BAA2B,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM,KACjE,KAAK,iBAAiB,KAAK,CAAC,MAAM,MAAM,MAAM;AAElD;AC7CO,SAAS,YACd,QACA,YACA,KACA,SACQ;AACR,QAAM,EAAC,cAAc,sBAAqB,YAAY,MAAM;AAC5D,MAAI,CAAC;AACH,UAAM,IAAI,UAAU,6DAA6D;AAEnF,MAAI,CAAC;AACH,UAAM,IAAI,UAAU,kEAAkE;AAQxF,QAAM,EAAC,SAAS,SAAQZ,aAAAA,QAAQ,MAAM,OAAO,uBAAuB,GAAG,CAAC,uBAAuB,CAAC;AAEhG,SAAO;AAAA,IACL,UAAU,KAAK,MAAM,KAAK,UAAU,SAAS,CAAC,GAAG,MAAM,KAAK,MAAS,CAAC,IAAI,CAAA;AAAA,IAC1E,KAAK,iBAAiB;AAAA,IACtB;AAAA,MACE,WAAW;AAAA,MACX,OAAO;AAAA,MACP,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW;AAAA,IAAA;AAAA,EACb;AAEJ;AC9CO,SAAS,sBACd,QACA,OACA,QACA,UACA;AACA,QAAM,aAAa,cAAc,KAAK;AAEtC,MAAI,eAAe,IAAI;AAAA,IACrB,KAAK,MAAM,KAAK,UAAU,QAAQ,CAAC,GAAG,MAAM,KAAK,MAAS,CAAC;AAAA,EAAA;AAE7D,QAAM,iBAAiB,sBAAsB,OAAO,UAAU,GAAG;AACjE,MAAI,mBAAmB,YAAY,mBAAmB,OAAO;AAC3D,UAAM,QAAQ,YAAY,QAAQ,YAAY,UAAU,MAAM;AAC9D,mBAAe,IAAI,gBAAgB,EAAC,OAAM;AAAA,EAC5C;AAEA,SAAO,EAAC,YAAY,aAAA;AACtB;ACjBO,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ,MAAM,YAAY,KAAK,IAAI,GAAG,MAAM,YAAY,GAAG,IAAI;AAAA,EAC/D,MAAM,QAAQ;AAAA,EACd,MAAM;AACR,GAAsD;AACpD,QAAM,SAAS,EAAC,QAAQ,OAAO,OAAO,KAAK,IAAA,GAErC,EAAC,YAAY,iBAAgB,sBAAsB,QAAQ,OAAO,QAAQ,GAAG;AAEnF,SAAO,yBAAyB,UAAU,iBAAiB,YAAY;AACzE;ACdO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO,MAAM,aAAa;AAAA,EAC1B;AACF,GAAsC;AACpC,QAAM,SAAS,EAAC,UAAU,QAAQ,MAAA;AAC9B,WAAS,WACT,OAAe,OAAO;AAG1B,QAAM,EAAC,YAAY,iBAAgB,sBAAsB,QAAQ,OAAO,QAAQ,GAAG;AAEnF,SAAO,yBAAyB,UAAU,kBAAkB,YAAY;AAC1E;ACnBO,SAAS,eACd,OACA,SACmB;AACnB,MAAI;AACF,WAAO,MAAA;AAAA,EACT,SAAS,gBAAgB;AACvB,QAAI,0BAA0B;AAE5B,YAAM;AAER,WAAO,UAAU,QAAQ,cAAuB,IAAI;AAAA,EACtD;AACF;ACRA,MAAM2B,UAAQxB,iBAAAA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAWf,iBAAgD;AAAA,EACpD,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AACV;AAEA,SAAwB,eAAe;AAAA,EACrC;AAAA,EACA;AAAA,EACA,cAAc;AAChB,GAIG;AACD,QAAM,cAAc,SAAS,KACvB,SAAS,UAAA,GACT,MAAMK,MAAAA,OAA8B,IAAI,GACxC,SAAS,UAAU,GAAG,GAEtB,CAAC,QAAQ,SAAS,IAAI/B,MAAAA,SAAsB,SAAS,GACrD,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAwB,IAAI,GAEhD,eAAegB,MAAAA,QAAQ,MACpB;AAAA,IACL,MAAM;AACJ,UAAI;AAEJ,aAAI,cAAa,YAAY,aAAa,EAAC,OAAO,QAAQ,OAAO,YAAA,CAAY,IACxE,YAAY,qBAAqB,EAAC,OAAO,QAAQ,OAAO,YAAA,CAAY,GAClE;AAAA,IACT;AAAA,IACA,CAAC,QAAe;AACd,kBAAY,IAAI,OAAO;AAAA,IAEzB;AAAA,EAAA,GAED,CAAC,OAAO,QAAQ,aAAa,WAAW,CAAC;AAE5C,WAAS,aAAa;AACpB,cAAU,QAAQ;AAAA,EACpB;AAEA,WAAS,YAAY,KAAc;AACjC,cAAU,OAAO,GAEf,SADE,OAGO,0BAFG;AAAA,EAIhB;AAEA,wCACGmC,MAAAA,UAAA,EAAS,UAAUrD,2BAAAA,IAAC,QAAA,EAAK,iCAAmB,GAC3C,UAAAA,2BAAAA;AAAAA,IAACQ,GAAAA;AAAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,aAAa;AAAA,QACb,UAAU;AAAA,QACV,UAAU,QAAQ,GAAG,KAAK,OAAO;AAAA,QACjC,OAAO;AAAA,QACP,MAAM;AAAA,MAAA;AAAA,MAER,QAAM;AAAA,MACN,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,eAAe,MAAM;AAAA,MAE1B,mBACCD,2BAAAA,KAAAsB,WAAAA,UAAA,EACG,UAAA;AAAA,QAAA,WAAW,aACV7B,2BAAAA;AAAAA,UAAC+B,GAAAA;AAAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,MAAM;AAAA,cACN,KAAK;AAAA,cACL,WAAW;AAAA,YAAA;AAAA,YAGb,yCAACuB,GAAAA,SAAA,CAAA,CAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,QAGZ,WAAW,WACV/C,2BAAAA;AAAAA,UAACF,GAAAA;AAAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,MAAM;AAAA,cACN,KAAK;AAAA,cACL,WAAW;AAAA,cACX,cAAc;AAAA,YAAA;AAAA,YAGhB,UAAA;AAAA,cAAAL,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAClB,UAAAT,2BAAAA,IAACuD,MAAAA,kBAAA,EAAiB,OAAO,EAAC,UAAU,SAAA,EAAQ,CAAG,GACjD;AAAA,6CACC9C,GAAAA,MAAA,EAAK,OAAK,IAAC,OAAM,UACf,UAAA,MAAA,CACH;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGJT,2BAAAA;AAAAA,UAACoD;AAAAA,UAAA;AAAA,YACC,KAAK,gBAAgB;AAAA,YACrB,KAAK,eAAe,cAAc,UAAU,OAAO,IAAI,MAAM,YAAY,MAAM,OAAO;AAAA,YACtF,QAAQ;AAAA,YACR,SAAS,MAAM,YAAA;AAAA,YACf,OAAO,EAAC,SAAS,WAAW,WAAW,IAAI,EAAA;AAAA,UAAC;AAAA,QAAA;AAAA,MAC9C,EAAA,CACF,IACE;AAAA,IAAA;AAAA,EAAA,GAER;AAEJ;AC7GA,MAAM,uBAAuBxB,iBAAAA,OAAOY,WAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAa5C,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,WAAWgB,OAAAA,qBAAqB,MAAM,WAAW,GAAI;AAE3D,SACExD,2BAAAA;AAAAA,IAACQ,GAAAA;AAAAA,IAAA;AAAA,MAEC,MAAM,WAAW,aAAa;AAAA,MAC9B,QAAM;AAAA,MACN,UAAU;AAAA,MACV,UAAU;AAAA,MACV,OAAO,EAAC,UAAU,WAAA;AAAA,MAClB,QAAQ;AAAA,MAER,UAAAD,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,QAAA9B,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS;AAAA,YACT,UAAU,CAAC,MAAM;AACf,0BAAY,EAAE,cAAc,OAAO;AAAA,YACrC;AAAA,YACA,cAAY,WAAW,gBAAgB,MAAM,EAAE,KAAK,wBAAwB,MAAM,EAAE;AAAA,UAAA;AAAA,QAAA;AAAA,QAEtFA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS,MAAM;AAAA,cACf,MAAM;AAAA,cACN,UAAU,MAAM;AAAA,cAChB,YAAY,MAAM,aAAa,KAAK,CAAC,MAAM,EAAE,EAAE,GAAG;AAAA,YAAA;AAAA,YAEpD,OAAO;AAAA,UAAA;AAAA,QAAA;AAAA,QAETO,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAE,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,YAAA9B,2BAAAA,IAACyC,GAAAA,QAAK,MAAM,GAAI,gCAAe,MAAM,IAAI,EAAE,GAAE;AAAA,YAAQ;AAAA,YACrDlC,2BAAAA,KAACE,GAAAA,MAAA,EAAK,OAAK,IAAC,MAAM,GAAG,UAAA;AAAA,cAAA;AAAA,cACjB,SAAS;AAAA,cAAU;AAAA,YAAA,EAAA,CACvB;AAAA,UAAA,GACF;AAAA,UACAF,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA;AAAA,YAAA;AAAA,YACD;AAAA,YACX,IAAI,KAAK,OAAO,MAAM,UAAU,IAAI,GAAI,EAAE,mBAAmB,MAAM;AAAA,cAClE,MAAM;AAAA,cACN,KAAK;AAAA,cACL,OAAO;AAAA,YAAA,CACR;AAAA,UAAA,EAAA,CACH;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,IAzCK,MAAM;AAAA,EAAA;AA4CjB;AAGA,SAAS,mBAAmB,OAA8C;AACxE,QAAM,EAAC,YAAA,IAAe,OAEhB,oBACH,gBAAgB,UAAU,gBAAgB,YAAY,MAAM,eAAe,SAAS,GACjF,cAAc,gBAAgB,aAC9B,mBACJ,MAAM,eAAe,WAAW,KAAK,CAAC,MAAM,UAAU,WAAW,CAAC,MAAM;AAE1E,SACET,2BAAAA;AAAAA,IAACI,GAAAA;AAAAA,IAAA;AAAA,MACC,SAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,IAAG;AAAA,MACH,SAAS,MAAM;AAAA,MACf,gBAAgB,MAAM;AAAA,MACtB,OAAO;AAAA,MACP,UAAS;AAAA,MACT,QACE,gBAAgB,UAChB,CAAC,oBACCJ,+BAACQ,GAAAA,MAAA,EAAK,SAAS,GACb,UAAAD,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,SAAQ,iBAAgB,OAAM,UAClC,UAAA;AAAA,QAAA9B,2BAAAA;AAAAA,UAACM,GAAAA;AAAAA,UAAA;AAAA,YACC,UAAU;AAAA,YACV,SAAS;AAAA,YACT,MAAK;AAAA,YACL,MAAK;AAAA,YACL,MAAK;AAAA,YACL,SAAS,MAAM;AAAA,YACf,UAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEX,MAAM,iBACLN,2BAAAA;AAAAA,UAACM,GAAAA;AAAAA,UAAA;AAAA,YACC,MAAMmD,MAAAA;AAAAA,YACN,UAAU;AAAA,YACV,SAAS;AAAA,YACT,MAAK;AAAA,YACL,MACE,MAAM,gBAAgB,SAAS,IAC3B,UAAU,MAAM,eAAe,MAAM,cACrC;AAAA,YAEN,MAAK;AAAA,YACL,SAAS,MAAM;AAAA,YACf,WAAW,eAAeH,GAAAA;AAAAA,YAC1B,UAAU,CAAC;AAAA,UAAA;AAAA,QAAA;AAAA,MACb,EAAA,CAEJ,EAAA,CACF;AAAA,MAIJ,UAAA/C,2BAAAA,KAACwB,GAAAA,KAAA,EAAI,SAAS,GAEX,UAAA;AAAA,QAAA,MAAM,UAAU,mCACf/B,+BAACQ,GAAAA,MAAA,EAAK,MAAK,WAAU,cAAc,GAAG,SAAS,GAAG,QAAM,IACtD,UAAAD,2BAAAA,KAACuB,GAAAA,QAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,UAAA9B,2BAAAA,IAAC0D,MAAAA,iBAAA,EAAgB,UAAU,GAAA,CAAI;AAAA,UAC/BnD,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,4BAEjC;AAAA,YACAT,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA,uFAAA,CAGf;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,SAIA,MAAM,UAAU,WAAW,MAAM,0BACjCT,+BAACQ,GAAAA,MAAA,EAAK,MAAK,WAAU,cAAc,GAAG,SAAS,GAAG,QAAM,IACtD,UAAAD,2BAAAA,KAACuB,GAAAA,QAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,UAAA9B,2BAAAA,IAACsD,GAAAA,SAAA,EAAQ,OAAK,IAAC,MAAM,GAAG;AAAA,UACxB/C,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,2BAEjC;AAAA,YACAF,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA;AAAA,cAAA;AAAA,cAEZ,MAAM,iBACL,MAAM,cAAc,SAAS,KAC7B,uBAAuB,MAAM,cAAc,MAAM,SAAS,MAAM,cAAc,SAAS,IAAI,MAAM,EAAE;AAAA,YAAA,EAAA,CACvG;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QAID,MAAM,UAAU,wCACdD,GAAAA,MAAA,EAAK,MAAK,YAAW,cAAc,GAAG,SAAS,GAAG,QAAM,IACvD,UAAAD,2BAAAA,KAACuB,GAAAA,QAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,UAAA9B,2BAAAA,IAACuD,MAAAA,kBAAA,EAAiB,UAAU,GAAA,CAAI;AAAA,UAChChD,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,gDAEjC;AAAA,2CACCA,GAAAA,MAAA,EAAK,MAAM,GACT,UAAA,MAAM,gBACH,mBAAmB,MAAM,cAAc,MAAM,SAAS,MAAM,cAAc,SAAS,IAAI,MAAM,EAAE,uDAC/F,oDAAA,CACN;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QAID,gBAAgB,eACfT,2BAAAA,IAACQ,SAAA,EAAK,MAAK,WAAU,cAAc,GAAG,SAAS,GAAG,QAAM,IACtD,UAAAD,2BAAAA,KAACuB,GAAAA,QAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,UAAA9B,2BAAAA,IAACsD,GAAAA,SAAA,EAAQ,OAAK,IAAC,MAAM,GAAG;AAAA,UACxBtD,2BAAAA,IAACK,GAAAA,SAAM,OAAO,GACZ,0CAACI,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA;AAAA,YAAA;AAAA,YACpB,MAAM,eAAe;AAAA,YAAO;AAAA,YACtC,MAAM,eAAe,SAAS,KAAK;AAAA,YAAI;AAAA,UAAA,EAAA,CAC1C,EAAA,CACF;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QAID,gBAAgB,WACfT,2BAAAA,IAACQ,SAAA,EAAK,MAAK,YAAW,cAAc,GAAG,SAAS,GAAG,QAAM,IACvD,UAAAD,2BAAAA,KAACuB,GAAAA,QAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,UAAA9B,2BAAAA,IAACuD,MAAAA,kBAAA,EAAiB,UAAU,GAAA,CAAI;AAAA,UAChChD,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,uCAEjC;AAAA,YACAT,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GACT,UAAA,MAAM,cACH,UAAU,MAAM,WAAW,KAC3B,oDAAA,CACN;AAAA,YACAT,2BAAAA,IAAC+B,GAAAA,KAAA,EAAI,WAAW,GACd,UAAA/B,2BAAAA;AAAAA,cAACM,GAAAA;AAAAA,cAAA;AAAA,gBACC,MAAMqD,MAAAA;AAAAA,gBACN,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,SAAS,MAAM;AAAA,cAAA;AAAA,YAAA,EACjB,CACF;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,SAIA,oBAAoB,gBAAgB,WACpCpD,2BAAAA,KAACF,GAAAA,SAAM,UAAU,GAAG,cAAc,GAAG,OAAO,GAAG,OAAO,EAAC,WAAW,YAChE,UAAA;AAAA,UAAAL,+BAAC+B,GAAAA,KAAA,EACC,UAAA/B,2BAAAA,IAAC4D,MAAAA,qBAAA,EAAoB,UAAU,IAAI,GACrC;AAAA,yCACCC,GAAAA,SAAA,EAAQ,MAAM,GACZ,UAAA,gBAAgB,SACb,iCACA,qCACN;AAAA,yCACCpD,GAAAA,MAAA,EAAK,MAAM,GACT,UAAA,gBAAgB,SACb,iDACA,8DAAA,CACN;AAAA,QAAA,GACF;AAAA,QAID,MAAM,iBACL,MAAM,cAAc,SAAS,MAC5B,gBAAgB,UAAU,gBAAgB,YACzCF,gCAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAE,2BAAAA,KAACsD,GAAAA,SAAA,EAAQ,MAAM,GAAG,UAAA;AAAA,YAAA;AAAA,YACL,MAAM,cAAc;AAAA,YAC9B,MAAM,UAAU,WAAW;AAAA,YAAI;AAAA,YAAW,MAAM,cAAc,SAAS,KAAK;AAAA,YAAK;AAAA,YAAI;AAAA,UAAA,GAExF;AAAA,UACC,CAAC,MAAM,UAAU,2CACf/B,GAAAA,MAAA,EAAK,OAAM,UAAS,UAAU,GAC7B,UAAA;AAAA,YAAA9B,2BAAAA;AAAAA,cAACwC,GAAAA;AAAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,OAAO,EAAC,SAAS,QAAA;AAAA,gBACjB,SAAS,CAAC,MAAM;AACI,oBAAE,cAAc,UAGhC,MAAM,iBAAiB,MAAM,kBAAkB,MAAM,aAAa,IAElE,MAAM,kBAAkB,CAAA,CAAE;AAAA,gBAE9B;AAAA,gBACA,SAAS,MAAM,eAAe,WAAW,MAAM,cAAc;AAAA,cAAA;AAAA,YAAA;AAAA,YAE/DxC,2BAAAA,IAAC+B,GAAAA,KAAA,EAAI,MAAM,GAAG,aAAa,GAAG,IAAG,SAAQ,SAAQ,cAC/C,UAAA/B,2BAAAA,IAACS,GAAAA,MAAA,EAAK,wBAAU,EAAA,CAClB;AAAA,UAAA,GACF;AAAA,UAED,MAAM,cAAc,IAAI,CAAC,UACxBT,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cAEC;AAAA,cACA,aAAa,CAAC,aAAa;AACrB,2BACF,MAAM,kBAAkB,CAAC,GAAG,MAAM,gBAAgB,KAAK,CAAC,IAExD,MAAM,kBAAkB,MAAM,eAAe,OAAO,CAAC4C,OAAMA,GAAE,OAAO,MAAM,EAAE,CAAC;AAAA,cAEjF;AAAA,cACA,UAAU,MAAM,eAAe,KAAK,CAACA,OAAMA,GAAE,OAAO,MAAM,EAAE;AAAA,YAAA;AAAA,YATvD,MAAM;AAAA,UAAA,CAWd;AAAA,QAAA,EAAA,CACH;AAAA,MAAA,EAAA,CAEN;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,SAAwB,sBAAsB;AAC5C,QAAM,eAAe,mBAAA;AAErB,MAAK,aAAa;AAIlB,WAAI,aAAa,aAER5C,2BAAAA,IAAC,oBAAA,EAAoB,GAAG,aAAA,CAAc,IAIxCA,2BAAAA,IAACM,GAAAA,QAAA,EAAO,MAAK,SAAQ,MAAK,mBAAkB,SAAS,aAAa,YAAY;AACvF;ACjVA,MAAM,eAAe,CAAC,UAIhB;AACJ,QAAM,OAAO,MAAM,MACb,UAAU,MAAM;AAEtB,SAAA+B,MAAAA,UAAU,MAAM;AAEd,UAAM,UAAU,KAAK,IAAI,MAAM,QAAQ,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;AACvD,aAAS,WACX,QAAQ,OAAO;AAAA,EAEnB,GAAG,CAAC,MAAM,MAAM,OAAO,OAAO,CAAC,GAG7B9B,2BAAAA,KAAAsB,qBAAA,EACE,UAAA;AAAA,IAAA7B,2BAAAA;AAAAA,MAACM,GAAAA;AAAAA,MAAA;AAAA,QACC,MAAMwD,MAAAA;AAAAA,QACN,MAAK;AAAA,QACL,SAAS;AAAA,QACT,OAAO,EAAC,QAAQ,UAAA;AAAA,QAChB,UAAU,QAAQ;AAAA,QAClB,SAAS,MAAM;AACb,kBAAQ,CAAC,MACA,KAAK,IAAI,MAAM,QAAQ,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC,CACpD;AAAA,QACH;AAAA,MAAA;AAAA,IAAA;AAAA,IAEFvD,2BAAAA,KAACwD,GAAAA,OAAA,EAAM,OAAK,IAAC,UAAA;AAAA,MAAA;AAAA,MACL,OAAO;AAAA,MAAE;AAAA,MAAE,MAAM;AAAA,IAAA,GACzB;AAAA,IACA/D,2BAAAA;AAAAA,MAACM,GAAAA;AAAAA,MAAA;AAAA,QACC,MAAM0D,MAAAA;AAAAA,QACN,MAAK;AAAA,QACL,SAAS;AAAA,QACT,OAAO,EAAC,QAAQ,UAAA;AAAA,QAChB,UAAU,QAAQ,MAAM,QAAQ;AAAA,QAChC,SAAS,MAAM;AACb,kBAAQ,CAAC,MACA,KAAK,IAAI,MAAM,QAAQ,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC,CACpD;AAAA,QACH;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;AC3CO,SAAS,iBAAiB,MAA0B;AACzD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,KAAK,QAAQ,IAAI,CAAC,WAAW;AAAA,MACnC,GAAG;AAAA,MACH,MAAMb,KAAAA,KAAA;AAAA,IAAK,EACX;AAAA,IACF,cAAc,KAAK,cAAc,IAAI,CAAC,gBAAgB;AAAA,MACpD,GAAG;AAAA,MACH,MAAMA,KAAAA,KAAA;AAAA,IAAK,EACX;AAAA,IACF,mBAAmB,KAAK,oBACpB;AAAA,MACE,GAAG,KAAK;AAAA,MACR,OAAO,KAAK,kBAAkB,OAAO,IAAI,CAAC,UAAU;AAAA,QAClD,GAAG;AAAA,QACH,MAAMA,KAAAA,KAAA;AAAA,MAAK,EACX;AAAA,IAAA,IAEJ;AAAA,EAAA;AAER;ACLA,SAAwB,uBAAuB;AAC7C,QAAM,gBAAgBlC,OAAAA,oBAChB,SAASiC,OAAAA,UAAU;AAAA,IACvB,YAAY;AAAA,EAAA,CACb,GAEK,CAAC,cAAc,mBAAmB,IAAI,gBAAgB,aAAa,GAGnE,aAAa,CAAC,CADS,yBAAA,EACa,MAAM,SAAS,WAEnD,CAAC,aAAa,cAAc,IAAIhD,MAAAA,SAAA,GAChC,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAsB,QAAQ,GAC9D,aAAa,gBAAgB,UAE7B,YAAY,aAAa;AAAA,IAC7B;AAAA,IACA,SAAS,cAAc;AAAA,EAAA,CACxB,GAEK,gBAAgBgB,MAAAA,QAAQ,MACrB,gBAAgB,UAAU,OAC7B,aAAa,IAAI,CAAC,cAAc;AAC9B,UAAM,WAAW,UAAU,MAAM;AAAA,MAC/B,CAAC,MAAM,EAAE,OAAO,UAAU,WAAW,EAAE,OAAO,UAAU,MAAM;AAAA,IAAA;AAEhE,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU,UAAU,MAAM;AAAA,MAC1B,cAAc,UAAU;AAAA,IAAA;AAAA,EAE5B,CAAC,IACD,QACH,CAAC,cAAc,UAAU,IAAI,CAAC,GAE3B,cAAc,MAAM;AACpB,oBAAgB,aAAW,eAAe,QAAQ;AAAA,EACxD,GAEM,aAAa,MAAM;AACnB,oBAAgB,YAAU,eAAe,MAAM;AAAA,EACrD;AAEA,iBAAe,gBAAgB;AAC7B,QAAK,eAEL;AAAA,qBAAe,SAAS;AAExB,UAAI;AACF,cAAM,KAAK,OAAO,YAAA;AAElB,sBAAc,QAAQ,CAAC,YAAY;AAEjC,gBAAM,WAAW,QAAQ,YAAY;AACrC,aAAG,MAAM,QAAQ,UAAU,KAAK,EAAC,KAAK,EAAC,UAAU,SAAA,GAAU;AAAA,QAC7D,CAAC,GAED,MAAM,GAAG,OAAO,EAAC,iBAAiB,GAAA,CAAM,GACxC,eAAe,MAAM;AAAA,MACvB,SAAS,OAAO;AACd,uBAAe,OAAO,GACtB,eAAe,KAAK;AAAA,MACtB;AAAA,IAAA;AAAA,EACF;AAEA,iBAAe,gBAAgB;AAC7B,QAAK,eAEL;AAAA,qBAAe,SAAS;AAExB,UAAI;AACF,cAAM,KAAK,OAAO,YAAA;AAElB,sBAAc,QAAQ,CAAC,YAAY;AAI/B,kBAAQ,YACR,QAAQ,YACR,0BAA0B,QAAQ,cAAc,QAAQ,SAAS,EAAE,KAEnE,GAAG,MAAM,QAAQ,UAAU,KAAK,EAAC,KAAK,EAAC,UAAU,QAAQ,SAAA,GAAU;AAAA,QAEvE,CAAC,GAED,MAAM,GAAG,OAAO,EAAC,iBAAiB,GAAA,CAAM,GACxC,eAAe,MAAM;AAAA,MACvB,SAAS,OAAO;AACd,uBAAe,OAAO,GACtB,eAAe,KAAK;AAAA,MACtB;AAAA,IAAA;AAAA,EACF;AAEA,iBAAe,eAAe;AAC5B,QAAK,eAEL;AAAA,qBAAe,SAAS;AAExB,UAAI;AACF,cAAM,KAAK,OAAO,YAAA;AAElB,sBAAc,QAAQ,CAAC,YAAY;AACjC,cAAI,CAAC,QAAQ,SAAU;AAEvB,gBAAM,eAAe,iBAAiB,QAAQ,QAAQ;AAGtD,aAAG,MAAM,QAAQ,UAAU,KAAK;AAAA,YAC9B,KAAK;AAAA,cACH,UAAU,QAAQ,YAAY,QAAQ,gBAAgB;AAAA,cACtD,QAAQ,QAAQ,SAAS;AAAA,cACzB,MAAM;AAAA,YAAA;AAAA,UACR,CACD;AAAA,QACH,CAAC,GAED,MAAM,GAAG,OAAO,EAAC,iBAAiB,GAAA,CAAM,GACxC,eAAe,MAAM;AAAA,MACvB,SAAS,OAAO;AACd,uBAAe,OAAO,GACtB,eAAe,KAAK;AAAA,MACtB;AAAA,IAAA;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AAEA,MAAM,kBAAkBF,OAAAA;AAAAA,EACtB,CAAC,kBACQ,cAAc;AAAA;AAAA,IACR;AAAA,IACX,CAAA;AAAA,IACA;AAAA,MACE,YAAY;AAAA,IAAA;AAAA,EACd;AAGN;AC3JA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,SACEhB,2BAAAA;AAAAA,IAACQ,GAAAA;AAAAA,IAAA;AAAA,MACC,IAAG;AAAA,MACH,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,QAAM;AAAA,MACN,MAAM,WAAW,YAAY;AAAA,MAC7B,OAAO;AAAA,QACL,QAAQ,WAAW,gBAAgB;AAAA,QACnC,SAAS,WAAW,MAAM;AAAA,MAAA;AAAA,MAG5B,UAAAD,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,KAAK,GAAG,OAAM,cAClB,UAAA;AAAA,QAAA9B,2BAAAA,IAAC+B,GAAAA,KAAA,EAAI,YAAY,GACf,UAAA/B,2BAAAA;AAAAA,UAACiE,GAAAA;AAAAA,UAAA;AAAA,YACC,SAAS;AAAA,YACT,UAAU,MAAM,SAAS,EAAE;AAAA,YAC3B;AAAA,YACA,MAAK;AAAA,UAAA;AAAA,QAAA,GAET;AAAA,QACA1D,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GAAG,MAAM,GACrB,UAAA;AAAA,UAAAL,2BAAAA,IAAC8B,GAAAA,MAAA,EAAK,OAAM,UAAS,KAAK,GACxB,0CAACrB,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YACnB,UAAA;AAAA,YAAA;AAAA,YAAM;AAAA,YAAG;AAAA,YAAM;AAAA,UAAA,EAAA,CAClB,EAAA,CACF;AAAA,yCACCA,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IACjB,UAAA,YAAA,CACH;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,SAAS,qBAAqB,OAAgD;AAC5E,QAAM,EAAC,YAAA,IAAe,OAEhB,iBAAiB,MAAM,eAAe,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,GAC1E,+BACJ,MAAM,eAAe;AAAA,IACnB,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,0BAA0B,EAAE,cAAc,EAAE,SAAS,EAAE;AAAA,EAAA,EAC1F,UAAU,GAER,iBAAiB,+BAA+B,GAChD,gBAA4B,iBAAiB,cAAc,cAC3D,CAAC,gBAAgB,iBAAiB,IAAIP,MAAAA,SAAqB,aAAa,GAExE,mBAAmB,gBAAgB,UAAU,gBAAgB,SAC7D,cAAc,gBAAgB,WAC9B,SAAS,gBAAgB,QACzB,YAAY,MAAM,UAAU,WAAW,MAAM,qBAE7C,aAAa,MAAM;AACvB,YAAQ,gBAAA;AAAA,MACN,KAAK;AACH,cAAM,cAAA;AACN;AAAA,MACF,KAAK;AACH,cAAM,cAAA;AACN;AAAA,MACF,KAAK;AACH,cAAM,aAAA;AACN;AAAA,IAEA;AAAA,EAEN;AAEA,SACEF,2BAAAA;AAAAA,IAACI,GAAAA;AAAAA,IAAA;AAAA,MACC,SAAO;AAAA,MACP,QAAO;AAAA,MACP,SAAS;AAAA,MACT,IAAG;AAAA,MACH,SAAS,MAAM;AAAA,MACf,gBAAgB,MAAM;AAAA,MACtB,OAAO;AAAA,MACP,UAAS;AAAA,MACT,QACE,CAAC,UACCJ,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,SAAS,GACb,UAAAD,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,SAAQ,YAAW,KAAK,GAC5B,UAAA;AAAA,QAAA9B,2BAAAA;AAAAA,UAACM,GAAAA;AAAAA,UAAA;AAAA,YACC,UAAU;AAAA,YACV,SAAS;AAAA,YACT,MAAK;AAAA,YACL,MAAK;AAAA,YACL,SAAS,MAAM;AAAA,YACf,UAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZN,2BAAAA;AAAAA,UAACM,GAAAA;AAAAA,UAAA;AAAA,YACC,MAAM4D,MAAAA;AAAAA,YACN,UAAU;AAAA,YACV,SAAS;AAAA,YACT,MAAK;AAAA,YACL,MAAK;AAAA,YACL,SAAS;AAAA,YACT,WAAW,eAAeZ,GAAAA;AAAAA,YAC1B,UAAU,CAAC,oBAAoB;AAAA,UAAA;AAAA,QAAA;AAAA,MACjC,EAAA,CACF,EAAA,CACF;AAAA,MAIJ,UAAA/C,2BAAAA,KAACwB,GAAAA,KAAA,EAAI,SAAS,GAEX,UAAA;AAAA,QAAA,4CACEvB,GAAAA,MAAA,EAAK,MAAK,WAAU,cAAc,GAAG,SAAS,GAAG,QAAM,IAAC,QAAQ,GAC/D,UAAAD,2BAAAA,KAACuB,GAAAA,QAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,UAAA9B,2BAAAA,IAACsD,GAAAA,SAAA,EAAQ,OAAK,IAAC,MAAM,GAAG;AAAA,UACxB/C,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,2BAEjC;AAAA,2CACCA,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,yBAAA,CAErB;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QAID,MAAM,UAAU,SACfT,2BAAAA,IAACQ,GAAAA,QAAK,MAAK,YAAW,cAAc,GAAG,SAAS,GAAG,QAAM,IAAC,QAAQ,GAChE,UAAAD,2BAAAA,KAACuB,GAAAA,QAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,UAAA9B,2BAAAA,IAACuD,MAAAA,kBAAA,EAAiB,UAAU,GAAA,CAAI;AAAA,UAChChD,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,4CAEjC;AAAA,YACAT,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA,oDAAA,CAAiD;AAAA,UAAA,EAAA,CAClE;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QAID,gBAAgB,aACfT,+BAACQ,GAAAA,QAAK,MAAK,WAAU,cAAc,GAAG,SAAS,GAAG,QAAM,IAAC,QAAQ,GAC/D,UAAAD,gCAACuB,GAAAA,QAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,UAAA9B,2BAAAA,IAACsD,GAAAA,SAAA,EAAQ,OAAK,IAAC,MAAM,GAAG;AAAA,UACxB/C,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,oBAEjC;AAAA,2CACCA,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,8BAAA,CAErB;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QAID,gBAAgB,WACfT,+BAACQ,GAAAA,QAAK,MAAK,YAAW,cAAc,GAAG,SAAS,GAAG,QAAM,IAAC,QAAQ,GAChE,UAAAD,gCAACuB,GAAAA,QAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,UAAA9B,2BAAAA,IAACuD,MAAAA,kBAAA,EAAiB,UAAU,GAAA,CAAI;AAAA,UAChChD,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,uCAEjC;AAAA,YACAT,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GACT,UAAA,MAAM,cACH,UAAU,MAAM,WAAW,KAC3B,oDAAA,CACN;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QAID,gBAAgB,UACfF,2BAAAA,KAACF,GAAAA,OAAA,EAAM,UAAU,GAAG,OAAO,GAAG,OAAO,EAAC,WAAW,SAAA,GAC/C,UAAA;AAAA,UAAAL,+BAAC+B,GAAAA,KAAA,EACC,UAAA/B,2BAAAA,IAAC4D,MAAAA,qBAAA,EAAoB,UAAU,IAAI,GACrC;AAAA,UACA5D,2BAAAA,IAAC6D,GAAAA,SAAA,EAAQ,MAAM,GAAG,UAAA,kBAAc;AAAA,yCAC/BpD,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,qCAAA,CAErB;AAAA,QAAA,GACF;AAAA,QAID,CAAC,UAAU,CAAC,aAAa,CAAC,MAAM,UAAU,SACzCF,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAE,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA;AAAA,YAAA;AAAA,YACZ;AAAA,YAAe;AAAA,YAAO,mBAAmB,IAAI,KAAK;AAAA,YAAI;AAAA,UAAA,GAC/D;AAAA,UAEAF,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACX,UAAA;AAAA,YAAA,kBACCL,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,UAAU,mBAAmB;AAAA,gBAC7B,UAAU;AAAA,gBACV,OAAM;AAAA,gBACN,OAAO;AAAA,gBACP,aAAY;AAAA,gBACZ,UAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAIdA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,UAAU,mBAAmB;AAAA,gBAC7B,UAAU;AAAA,gBACV,OAAM;AAAA,gBACN,OAAO;AAAA,gBACP,aAAY;AAAA,gBACZ,UAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAGZA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,UAAU,mBAAmB;AAAA,gBAC7B,UAAU;AAAA,gBACV,OAAM;AAAA,gBACN,OAAO;AAAA,gBACP,aAAY;AAAA,gBACZ,UAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ,EAAA,CACF;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,SAAwB,iBAAiB;AACvC,QAAM,iBAAiB,qBAAA;AAEvB,MAAK,eAAe;AAIpB,WAAI,eAAe,aAEVA,2BAAAA,IAAC,sBAAA,EAAsB,GAAG,eAAA,CAAgB,IAI5CA,2BAAAA,IAACM,GAAAA,QAAA,EAAO,MAAK,SAAQ,MAAK,iBAAgB,SAAS,eAAe,YAAY;AACvF;ACjRO,MAAM,6BAA2C;AAAA,EACtD,eAAe;AAAA,EACf,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,OAAO;AACT;AAMO,SAAS,kBAAkB,OAA6D;AAC7F,QAAM,KAAKoB,MAAAA,MAAA;AAEX,SACE1B,2BAAAA;AAAAA,IAACmE,GAAAA;AAAAA,IAAA;AAAA,MACC,QACEnE,2BAAAA,IAACM,GAAAA,QAAA,EAAO,MAAK,QAAO,MAAM8D,MAAAA,UAAU,MAAK,SAAQ,SAAS,GAAG,OAAO,EAAC,QAAQ,aAAY;AAAA,MAE3F;AAAA,MACA,MACEpE,2BAAAA,IAACqE,GAAAA,MAAA,EACE,UAAA,OAAO,QAAQ,kBAAkB,EAAE,IAAI,CAAC,CAAC,MAAM,EAAC,MAAA,CAAM,MACrDrE,2BAAAA;AAAAA,QAACsE,GAAAA;AAAAA,QAAA;AAAA,UAEC,WAAQ;AAAA,UACR,SAAS,MAAM,MAAM,QAAQ,IAAkB;AAAA,UAC/C,SAAS;AAAA,UACT,MAAK;AAAA,UACL,MAAM;AAAA,UACN,SAAS,SAAS,MAAM;AAAA,QAAA;AAAA,QANnB;AAAA,MAAA,CAQR,GACH;AAAA,MAEF,SAAS;AAAA,IAAA;AAAA,EAAA;AAGf;AC1CA,MAAM,aAAuB,MAC3BtE,2BAAAA;AAAAA,EAAC+B,GAAAA;AAAAA,EAAA;AAAA,IACC,OAAO;AAAA,MACL,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,WAAW;AAAA,IAAA;AAAA,IAGb,yCAACuB,GAAAA,SAAA,CAAA,CAAQ;AAAA,EAAA;AACX,GCVI,WAKD,CAAC,UAAU;AACd,QAAM,OAAO,MAAM;AACnB,yCACGxB,SAAA,EAAK,KAAK,GAAG,OAAM,UAAS,SAAS,GACpC,UAAA;AAAA,IAAA9B,2BAAAA,IAACS,GAAAA,MAAA,EAAK,OAAO,MAAM,QAAQ,KAAK,GAAG,OAAK,IACtC,UAAAT,2BAAAA,IAAC,MAAA,CAAA,CAAK,GACR;AAAA,IACAA,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,MAAM,QAAQ,GAAG,OAAO,MAAM,OACvC,UAAA,MAAM,KAAA,CACT;AAAA,EAAA,GACF;AAEJ;ACjBO,SAAS,eAAe,OAAgC;AAC7D,SACET,2BAAAA,IAAC,OAAA,EAAI,OAAM,8BAA6B,OAAM,OAAM,QAAO,OAAM,SAAQ,aAAa,GAAG,OACvF,UAAAA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,GAAE;AAAA,IAAA;AAAA,EAAA,GAEN;AAEJ;ACTO,SAAS,cAAc,OAAgC;AAC5D,SACEO,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAM;AAAA,MACN,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACP,GAAG;AAAA,MAEJ,UAAA;AAAA,QAAAP,2BAAAA,IAAC,QAAA,EAAK,GAAE,oCAAmC,MAAK,gBAAe;AAAA,QAC/DA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA,UAAA;AAAA,QAAA;AAAA,QAEPA,2BAAAA,IAAC,QAAA,EAAK,GAAE,uBAAsB,MAAK,eAAA,CAAe;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGxD;ACIO,SAAS,eAAe,SAAuD;AACpF,QAAM,SAAS,UAAA,GACT,QAAQuE,GAAAA,YACR,CAAC,aAAa,cAAc,IAAIrE,MAAAA,SAA2B,MAAM,GACjE,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAkB,IAAI,GAEtD,YAAY,SAAS,aAAa,IAElC,cAAcmB,MAAAA;AAAAA,IAClB,OAAO,UAA8B;AACnC,UAAI,CAAC,MAAM,SAAS;AACd,qBACF,MAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,aAAa;AAAA,UACb,QAAQ;AAAA,QAAA,CACT,GAEH,SAAS,UAAU,IAAI,MAAM,qBAAqB,CAAC;AACnD;AAAA,MACF;AAEA,UAAI,CAAC,MAAM,KAAK;AACV,qBACF,MAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,aAAa;AAAA,UACb,QAAQ;AAAA,QAAA,CACT,GAEH,SAAS,UAAU,IAAI,MAAM,0BAA0B,CAAC;AACxD;AAAA,MACF;AAEA,qBAAe,SAAS,GACxB,eAAe,IAAI;AAEnB,UAAI;AAEF,cAAM,WADW,MAAM,SAAS,QAAQ,MAAM,OAAO,GAC5B,MACnB,eAAe,iBAAiB,OAAO;AAE7C,eAAA,MAAM,OACH,MAAM,MAAM,GAAG,EACf,IAAI;AAAA,UACH,QAAQ,QAAQ;AAAA,UAChB,MAAM;AAAA,UACN,GAAI,QAAQ,MAAM,SAAS,EAAC,UAAU,QAAQ,KAAK,MAAA;AAAA,QAAK,CACzD,EACA,OAAO,EAAC,iBAAiB,GAAA,CAAM,GAElC,eAAe,SAAS,GACpB,aACF,MAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,aAAa;AAAA,UACb,QAAQ;AAAA,QAAA,CACT,GAGH,SAAS,YAAY,OAAO,GACrB;AAAA,MACT,SAAS,OAAO;AACd,uBAAe,OAAO,GACtB,eAAe,KAAK,GACpB,QAAQ,MAAM,iCAAiC,KAAK,GAChD,aACF,MAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,aAAa;AAAA,UACb,QAAQ;AAAA,QAAA,CACT,GAEH,SAAS,UAAU,KAAK;AACxB;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,OAAO,SAAS,SAAS;AAAA,EAAA;AAGpC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,gBAAgB;AAAA,EAAA;AAEjC;ACrGO,SAAS,oBACd,OACA,iBAAiB,6BACT;AACR,MAAI,UAAU;AAEd,MAAI,SAAS,OAAO,SAAU,UAAU;AACtC,UAAM,MAAM;AACZ,cAAU,IAAI,UAAU,MAAM,WAAW,IAAI,WAAW;AAAA,EAC1D,MAAW,QAAO,SAAU,aAC1B,UAAU;AAGZ,MAAI,CAAC;AACH,WAAO;AAGT,QAAM,QAAQ,QAAQ,MAAM,aAAa;AACzC,MAAI,SAAS,MAAM,CAAC;AAClB,WAAO,MAAM,CAAC;AAGhB,MAAI,QAAQ,SAAS,gBAAgB,GAAG;AACtC,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,MAAM,SAAS;AACjB,aAAO,MAAM,MAAM,SAAS,CAAC,EAAE,QAAQ,KAAK,EAAE,EAAE,KAAA;AAAA,EAEpD;AAEA,SAAO;AACT;AA0BA,eAAsB,gBACpB,SACgC;AAChC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE,SAEE,cAAc,UAAU,QACxB,sBAAsB,kBAAkB,KAAA;AAC9C,MAAI,UACA,WAAW,GACX,aAAa;AAEjB,QAAM,YAAY,CAAC,eAAyD;AAC1E,QAAI,aAAa,WAAW;AAAA,MAC1B,CAAC,UAAU,MAAM,SAAS,eAAe,MAAM,kBAAkB;AAAA,IAAA;AAGnE,WAAK,eACH,aAAa,WAAW,KAAK,CAAC,UAAU,MAAM,kBAAkB,mBAAmB,IAGjF,CAAC,cAAc,WAAW,SAAS,MACrC,aAAa,WAAW,WAAW,SAAS,CAAC,IAGxC;AAAA,EACT;AAEA,SAAO,WAAW,eAAa;AAC7B,QAAI;AACE,iBAAW,KACb,MAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAI,CAAC;AAI1D,YAAM,cADY,MAAM,SAAS,QAAQ,OAAO,GAEpC,KAAK,QAAQ,OAAO,CAAC,UAAiC,MAAM,SAAS,MAAM,KAAK,CAAA,GAEtF,aAAa,UAAU,UAAU;AAEvC,UAAI,CAAC,YAAY;AACf;AACA;AAAA,MACF;AASA,UAPA,aAAa,IACb,WAAW,YAEP,gBACF,aAAa,UAAU,GAGrB,WAAW,WAAW,SAAS;AAC7B,wBACF,aAAa,UAAU;AAEzB;AAAA,MACF;AAEA,UAAI,WAAW,WAAW;AACxB,eAAI,kBACF,eAAe,UAAU,GAEpB;AAAA,UACL,OAAO;AAAA,UACP,OAAO;AAAA,UACP,QAAQ;AAAA,QAAA;AAAA,IAGd,SAAS,OAAO;AACd,cAAQ,MAAM,kCAAkC,KAAK;AAAA,IACvD;AAEA;AAAA,EACF;AAEA,SAAI,CAAC,YAAY,CAAC,aACT;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EAAA,IAIR,SAAS,WAAW,cACf;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EAAA,IAIL;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EAAA;AAEZ;AAKA,eAAsB,gBACpB,QACA,OACA,OACe;AACf,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,qBAAqB;AAGvC,MAAI,MAAM,WAAW;AACnB,UAAM,IAAI,MAAM,mCAAmC,MAAM,MAAM,EAAE;AAGnE,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,sBAAsB;AAGxC,QAAM,aAAa,cAAc,KAAK;AACtC,MAAI,CAAC;AACH,UAAM,IAAI,MAAM,yBAAyB;AAG3C,QAAM,iBAAiB,kBAAkB,KAAK,GAAG;AAEjD,MAAI,cAAc,0BAA0B,UAAU,SAAS,MAAM,EAAE;AAEvE,MAAI,mBAAmB,YAAY,mBAAmB,OAAO;AAC3D,UAAM,QAAQ,YAAY,QAAQ,YAAY,GAAG;AACjD,mBAAe,UAAU,KAAK;AAAA,EAChC;AAEA,QAAM,WAAW,MAAM,MAAM,WAAW;AACxC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,4BAA4B,SAAS,UAAU,EAAE;AAGnE,QAAM,OAAO,MAAM,SAAS,KAAA,GACtB,UAAU,IAAI,gBAAgB,IAAI,GAElC,OAAO,SAAS,cAAc,GAAG;AACvC,OAAK,OAAO,SACZ,KAAK,WAAW,GAAG,MAAM,YAAY,UAAU,IAAI,MAAM,iBAAiB,IAAI,QAC9E,SAAS,KAAK,YAAY,IAAI,GAC9B,KAAK,MAAA,GACL,SAAS,KAAK,YAAY,IAAI,GAE9B,IAAI,gBAAgB,OAAO;AAC7B;ACbO,MAAM,0BAA0B;AAAA,EACrC,EAAC,OAAO,WAAW,MAAM,MAAM,OAAO,SAAA;AAAA,EACtC,EAAC,OAAO,WAAW,MAAM,MAAM,OAAO,SAAA;AAAA,EACtC,EAAC,OAAO,WAAW,MAAM,MAAM,OAAO,SAAA;AAAA,EACtC,EAAC,OAAO,cAAc,MAAM,MAAM,OAAO,SAAA;AAAA,EACzC,EAAC,OAAO,UAAU,MAAM,MAAM,OAAO,SAAA;AAAA,EACrC,EAAC,OAAO,UAAU,MAAM,MAAM,OAAO,SAAA;AAAA,EACrC,EAAC,OAAO,UAAU,MAAM,MAAM,OAAO,OAAA;AAAA,EACrC,EAAC,OAAO,WAAW,MAAM,MAAM,OAAO,OAAA;AAAA,EACtC,EAAC,OAAO,SAAS,MAAM,MAAM,OAAO,OAAA;AAAA,EACpC,EAAC,OAAO,WAAW,MAAM,MAAM,OAAO,OAAA;AAAA,EACtC,EAAC,OAAO,WAAW,MAAM,MAAM,OAAO,OAAA;AAAA,EACtC,EAAC,OAAO,WAAW,MAAM,MAAM,OAAO,OAAA;AAAA,EACtC,EAAC,OAAO,aAAa,MAAM,MAAM,OAAO,OAAA;AAAA,EACxC,EAAC,OAAO,aAAa,MAAM,MAAM,OAAO,OAAA;AAAA,EACxC,EAAC,OAAO,WAAW,MAAM,MAAM,OAAO,OAAA;AAAA,EACtC,EAAC,OAAO,UAAU,MAAM,MAAM,OAAO,OAAA;AAAA,EACrC,EAAC,OAAO,SAAS,MAAM,MAAM,OAAO,OAAA;AAAA,EACpC,EAAC,OAAO,SAAS,MAAM,MAAM,OAAO,OAAA;AAAA,EACpC,EAAC,OAAO,YAAY,MAAM,MAAM,OAAO,OAAA;AAAA,EACvC,EAAC,OAAO,UAAU,MAAM,MAAM,OAAO,OAAA;AAAA,EACrC,EAAC,OAAO,YAAY,MAAM,MAAM,OAAO,OAAA;AAAA,EACvC,EAAC,OAAO,aAAa,MAAM,MAAM,OAAO,OAAA;AAC1C;AAiCO,SAAS,kBAAkB,OAA2D;AAC3F,SAAO,MAAM,SAAS;AACxB;AAEO,SAAS,qBACd,OACiC;AACjC,SAAO,MAAM,SAAS;AACxB;ACzPA,MAAMmD,qBAAmBC,uBAAAA,QAAc,YAAA,EAAc,IAAI,CAAC,UAAU;AAAA,EAClE,OAAO;AAAA,EACP,OAAOA,uBAAAA,QAAc,cAAc,IAAI;AACzC,EAAE,GAEI,uBAAuB,wBAAwB,IAAI,CAAC,UAAU;AAAA,EAClE,OAAO,KAAK;AAAA,EACZ,OAAO,KAAK;AACd,EAAE;AAQF,SAAwB,iBAAiB,EAAC,OAAO,OAAO,WAAiB;AACvE,QAAM,SAAS,UAAA,GACT,QAAQF,GAAAA,YACR,WAAW,mBAAmB7C,MAAAA,MAAA,CAAO,IAErC,CAAC,iBAAiB,kBAAkB,IAAIxB,MAAAA,SAAS,EAAK,GACtD,CAAC,QAAQ,SAAS,IAAIA,MAAAA,SAAS,EAAE,GACjC,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAS,EAAE,GAC7C,CAAC,kBAAkB,mBAAmB,IAAIA,MAAAA;AAAAA,IAC9C;AAAA,EAAA,GAEI,CAACwE,OAAM,OAAO,IAAIxE,MAAAA,SAAS,EAAE,GAC7B,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAS,EAAK,GAChD,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAsB,IAAI,GAC5D,eAAe+B,MAAAA,OAAyB,IAAI,GAE5C,gBAAgB,OAAO,UACL,MAAM,OAAO,OAAO,OAAO,QAAQ,MAAM;AAAA,IAC7D,UAAU,KAAK;AAAA,EAAA,CAChB,GACoB,KAGjB,wBAAwB,YAAY;AACxC,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,sBAAsB;AAGxC,UAAM,cAAcyC,MAAK,KAAA,GACnB,sBAAsB,aAAa,KAAA;AAEzC,QAAI,cAAc,OAAO,KAAA;AAEzB,QAAI;AACF,UAAI;AACF,sBAAc,MAAM,cAAc,YAAY;AAAA,MAChD,SAAS,aAAa;AACpB,cAAA,MAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aAAa;AAAA,QAAA,CACd,GACD,gBAAgB,EAAK,GACf;AAAA,MACR;AAGF,UAAM,oBAAoB,QAAQ,MAAM,SAAS,aAAa;AAAA,MAC5D,eAAe;AAAA,MACf,MAAM;AAAA,MACN,WAAW;AAAA,IAAA,CACZ;AAED,UAAM,SAAS,MAAM,gBAAgB;AAAA,MACnC;AAAA,MACA,SAAS,MAAM;AAAA,MACf,WAAW;AAAA,MACX,mBAAmB;AAAA,MACnB,gBAAgB,CAAC,UAAU;AACzB,cAAM,eACJ,MAAM,OAAO,WAAW,CAAC,KACzB,MAAM,OAAO,QACb;AACF,cAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aAAa;AAAA,QAAA,CACd,GACD,MAAM,KAAK,GACX,QAAA;AAAA,MACF;AAAA,IAAA,CACD;AAED,QAAI,CAAC,OAAO,SAAS,CAAC,OAAO,OAAO;AAClC,YAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aACE;AAAA,MAAA,CACH,GACD,QAAA;AACA;AAAA,IACF;AAEA,QAAI,OAAO,WAAW,WAItB;AAAA,UAAI,OAAO,WAAW,aAAa;AACjC,cAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aACE;AAAA,QAAA,CACH,GACD,MAAM,OAAO,KAAK,GAClB,QAAA;AACA;AAAA,MACF;AAEA,YAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa;AAAA,MAAA,CACd,GAED,MAAM,OAAO,KAAK,GAClB,QAAA;AAAA,IAAQ;AAAA,EACV,GAEM,0BAA0B,YAAY;AAC1C,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,sBAAsB;AAIxC,UAAM,cADY,MAAM,SAAS,QAAQ,MAAM,OAAO,GACzB,KAAK,QAAQ,KAAK,CAAC,UAAU,MAAM,SAAS,OAAO;AAEhF,QAAI,CAAC,cAAc,CAAC,WAAW;AAC7B,YAAA,MAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aACE;AAAA,MAAA,CACH,GACK,IAAI,MAAM,sBAAsB;AAGxC,UAAM,kBAAkB,QAAQ,MAAM,SAAS,WAAW,IAAI;AAAA,MAC5D,eAAe,aAAa,KAAA;AAAA,MAC5B,MAAMA,MAAK,KAAA;AAAA,IAAK,CACjB;AAGD,UAAM,YAA0B;AAAA,MAC9B,MAAM;AAAA,MACN,IAHkB,cAAc,KAAK,IAAA,CAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,MAIrF,WAAW;AAAA,MACX,aAAa;AAAA,MACb,eAAe,aAAa,KAAA;AAAA,MAC5B,MAAMA,MAAK,KAAA;AAAA,MACX,QAAQ;AAAA,IAAA;AAGV,UAAM,KAAK;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,aAAa;AAAA,IAAA,CACd,GAED,MAAM,SAAS,GACf,QAAA;AAAA,EACF,GAEM,eAAe,YAAY;AAC/B,QAAI,CAAC,iBAAiB;AACpB,UAAI,CAAC,gBAAgB,CAAC,OAAO,QAAQ;AACnC,cAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aAAa;AAAA,QAAA,CACd;AACD;AAAA,MACF;AAEA,UAAI,OAAO,KAAA,KAAU,CAAC;AACpB,YAAI;AACG,cAAI,IAAI,OAAO,MAAM;AAAA,QAC5B,QAAQ;AACN,gBAAM,KAAK;AAAA,YACT,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,aAAa;AAAA,UAAA,CACd;AACD;AAAA,QACF;AAAA,IAEJ;AAEA,QAAI,CAACA,MAAK,QAAQ;AAChB,YAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa;AAAA,MAAA,CACd;AACD;AAAA,IACF;AAEA,QAAI,CAAC,aAAa,QAAQ;AACxB,YAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa;AAAA,MAAA,CACd;AACD;AAAA,IACF;AAEA,oBAAgB,EAAI;AAEpB,QAAI;AACE,wBACF,MAAM,4BAEN,MAAM,sBAAA;AAAA,IAEV,SAAS,OAAO;AACd,YAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa,oBAAoB,OAAO,6BAA6B;AAAA,MAAA,CACtE;AAAA,IACH,UAAA;AACE,sBAAgB,EAAK;AAAA,IACvB;AAAA,EACF;AAEA,SACE1E,2BAAAA;AAAAA,IAACI,GAAAA;AAAAA,IAAA;AAAA,MACC,IAAI;AAAA,MACJ,QAAO;AAAA,MACP;AAAA,MACA,OAAO;AAAA,MACP,gBAAgB;AAAA,MAEhB,UAAAG,2BAAAA,KAACF,GAAAA,OAAA,EAAM,SAAS,GAAG,OAAO,GACxB,UAAA;AAAA,QAAAE,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAE,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,cAAc,GACjC,UAAA;AAAA,YAAA9B,2BAAAA;AAAAA,cAACwC,GAAAA;AAAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,OAAO,EAAC,SAAS,QAAA;AAAA,gBACjB,SAAS;AAAA,gBACT,UAAU,CAAC,MAAM;AACf,qCAAmB,EAAE,cAAc,OAAO,GACtC,EAAE,cAAc,WAClB,UAAU,EAAE;AAAA,gBAEhB;AAAA,gBACA,UAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAEZxC,+BAAC8B,GAAAA,MAAA,EAAK,MAAM,GAAG,aAAa,GAC1B,UAAA9B,2BAAAA,IAACS,GAAAA,MAAA,EACC,UAAAT,2BAAAA,IAAC,SAAA,EAAM,SAAQ,0BAAyB,UAAA,qBAAiB,GAC3D,EAAA,CACF;AAAA,UAAA,GACF;AAAA,UACC,CAAC,mBACAO,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,YAAAE,2BAAAA,KAACC,GAAAA,MAAA,EAAK,SAAS,GAAG,cAAc,GAAG,MAAK,eAAc,QAAM,IAAC,QAAQ,GACnE,UAAA;AAAA,cAAAD,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,SAAQ,iBAC3B,UAAA;AAAA,gBAAA9B,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IACjB,yBAAe,aAAa,aAAa,IAAI,KAAK,mBAAA,CACrD;AAAA,gBACAT,2BAAAA;AAAAA,kBAACM,GAAAA;AAAAA,kBAAA;AAAA,oBACC,MAAMqE,MAAAA;AAAAA,oBACN,MAAK;AAAA,oBACL,MAAK;AAAA,oBACL,MAAK;AAAA,oBACL,UAAU;AAAA,oBACV,SAAS;AAAA,oBACT,SAAS,MAAM,aAAa,SAAS,MAAA;AAAA,oBACrC,UAAU;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACZ,GACF;AAAA,cACA3E,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,KAAK;AAAA,kBACL,MAAK;AAAA,kBACL,QAAO;AAAA,kBACP,OAAO,EAAC,SAAS,OAAA;AAAA,kBACjB,UAAU,CAAC,MAAM;AACX,sBAAE,OAAO,SAAS,EAAE,OAAO,MAAM,SAAS,KAAK,CAAC,iBAClD,gBAAgB,EAAE,OAAO,MAAM,CAAC,CAAC,GACjC,UAAU,EAAE;AAAA,kBAEhB;AAAA,gBAAA;AAAA,cAAA;AAAA,YACF,GACF;AAAA,YACAA,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,OAAO,EAAC,WAAW,SAAA,GAAW,UAAA,4BAAA,CAEnD;AAAA,YACAF,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,cAAAL,2BAAAA,IAAC+D,GAAAA,OAAA,EAAM,SAAQ,WAAU,UAAA,gBAAY;AAAA,cACrC/D,2BAAAA;AAAAA,gBAACuC,GAAAA;AAAAA,gBAAA;AAAA,kBACC,IAAG;AAAA,kBACH,aAAY;AAAA,kBACZ,OAAO;AAAA,kBACP,UAAU,CAAC,MAAM;AACf,8BAAU,EAAE,cAAc,KAAK,GAC/B,gBAAgB,IAAI;AAAA,kBACtB;AAAA,kBACA,UAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,YACZ,EAAA,CACF;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,GAEJ;AAAA,QAEAhC,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAL,2BAAAA,IAAC+D,GAAAA,OAAA,EAAM,SAAQ,gBAAe,UAAA,cAAU;AAAA,UACxC/D,2BAAAA;AAAAA,YAAC4E,GAAAA;AAAAA,YAAA;AAAA,cACC,IAAG;AAAA,cACH,OAAO,kBAAkB,SAAS;AAAA,cAClC,UAAU,CAAC,aAAa;AAEtB,sBAAM,YADU,kBAAkB,uBAAuBJ,oBAChC,KAAK,CAAC,QAAQ,IAAI,UAAU,QAAQ;AACzD,6BACF,oBAAoB,QAAQ,GAC5B,gBAAgB,SAAS,KAAK,GAC9B,QAAQ,SAAS,KAAK;AAAA,cAE1B;AAAA,cACA,SAAS,kBAAkB,uBAAuBA;AAAAA,cAClD,MAAMK,MAAAA;AAAAA,cACN,aAAY;AAAA,cACZ,cAAc,CAAC,OAAO,WACpB,OAAO,MAAM,YAAA,EAAc,QAAQ,MAAM,YAAA,CAAa,IAAI,MAC1D,OAAO,MAAM,YAAA,EAAc,QAAQ,MAAM,YAAA,CAAa,IAAI;AAAA,cAE5D,YAAU;AAAA,cACV,aAAa,CAAC,WACX,kBAAkB,uBAAuBL,oBAAkB;AAAA,gBAC1D,CAAC,MAAM,EAAE,UAAU;AAAA,cAAA,GAClB,SAAS;AAAA,cAEd,cAAc,CAAC,0CACZhE,GAAAA,MAAA,EAAK,WAAQ,UAAS,SAAS,GAAG,QAAQ,GAAG,MAAK,WACjD,UAAAD,2BAAAA,KAACE,GAAAA,QAAK,MAAM,GAAG,cAAa,YACzB,UAAA;AAAA,gBAAA,OAAO;AAAA,gBAAM;AAAA,gBAAG,OAAO;AAAA,gBAAM;AAAA,cAAA,EAAA,CAChC,EAAA,CACF;AAAA,cAEF,UAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ,GACF;AAAA,QAEAF,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAL,2BAAAA,IAAC+D,GAAAA,OAAA,EAAM,SAAQ,oBAAmB,UAAA,iBAAa;AAAA,UAC/C/D,2BAAAA;AAAAA,YAACuC,GAAAA;AAAAA,YAAA;AAAA,cACC,IAAG;AAAA,cACH,aAAY;AAAA,cACZ,OAAO;AAAA,cACP,UAAU,CAAC,MAAM;AACf,gCAAgB,EAAE,cAAc,KAAK,GACjC,oBAAoB,iBAAiB,UAAU,EAAE,cAAc,UACjE,oBAAoB,IAAI,IACpB,CAACmC,SAAQA,UAAS,iBAAiB,UACrC,QAAQ,EAAE;AAAA,cAGhB;AAAA,cACA,UAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ,GACF;AAAA,wCAEC5C,GAAAA,MAAA,EAAK,KAAK,GAAG,SAAQ,YAAW,WAAW,GAC1C,UAAA;AAAA,UAAA9B,2BAAAA,IAACM,GAAAA,QAAA,EAAO,MAAK,UAAS,MAAK,SAAQ,SAAS,SAAS,UAAU,aAAA,CAAc;AAAA,UAC7EN,2BAAAA;AAAAA,YAACM,GAAAA;AAAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,MAAK;AAAA,cACL,MACE,eACEN,2BAAAA;AAAAA,gBAACsD,GAAAA;AAAAA,gBAAA;AAAA,kBACC,OAAO;AAAA,oBACL,eAAe;AAAA,oBACf,SAAS;AAAA,oBACT,cAAc;AAAA,oBACd,OAAO;AAAA,oBACP,QAAQ;AAAA,oBACR,aAAa;AAAA,kBAAA;AAAA,gBACf;AAAA,cAAA,mCAGDqB,MAAAA,YAAA,EAAW;AAAA,cAGhB,SAAS;AAAA,cACT,UAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;AC3YA,MAAM,mBAAmBF,uBAAAA,QAAc,YAAA,EAAc,IAAI,CAAC,UAAU;AAAA,EAClE,OAAO;AAAA,EACP,OAAOA,uBAAAA,QAAc,cAAc,IAAI;AACzC,EAAE;AASF,SAAwB,kBAAkB,EAAC,OAAO,OAAO,UAAU,WAAiB;AAClF,QAAM,SAAS,aACT,QAAQF,GAAAA,YACR,WAAW,oBAAoB7C,MAAAA,MAAA,CAAO,IAEtC,kBACJ,MAAM,gBAAgB,oBACtB,MAAM,gBAAgB,0BACtB,MAAM,gBAAgB,iBAElB,CAAC,QAAQ,SAAS,IAAIxB,eAAS,EAAE,GACjC,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAS,MAAM,iBAAiB,EAAE,GACpE,CAAC,kBAAkB,mBAAmB,IAAIA,MAAAA;AAAAA,IAC9C,MAAM;AACJ,YAAM,WAAW,MAAM,eAAe,MAAM,GAAG,EAAE,CAAC,GAC5C,QAAQ,iBAAiB;AAAA,QAC7B,CAAC,QAAQ,IAAI,UAAU,MAAM,iBAAiB,IAAI,UAAU;AAAA,MAAA;AAE9D,UAAI,MAAO,QAAO;AAClB,UAAI,MAAM,MAAM;AACd,cAAM,cAAc,iBAAiB,KAAK,CAAC,QAAQ,IAAI,UAAU,MAAM,IAAI;AAC3E,YAAI,YAAa,QAAO;AAAA,MAC1B;AACA,aAAO;AAAA,IACT;AAAA,EAAA,GAEI,CAACwE,OAAM,OAAO,IAAIxE,MAAAA,SAAS,MAAM,QAAQ,EAAE,GAC3C,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAS,EAAK,GAChD,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAS,EAAK,GAC9C,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAsB,IAAI,GAC5D,eAAe+B,MAAAA,OAAyB,IAAI;AAElDI,QAAAA,UAAU,MAAM;AACd,oBAAgB,MAAM,iBAAiB,EAAE,GACzC,QAAQ,MAAM,QAAQ,EAAE,GACxB,UAAU,EAAE;AACZ,UAAM,WAAW,MAAM,eAAe,MAAM,GAAG,EAAE,CAAC,GAC5C,cAAc,iBAAiB;AAAA,MACnC,CAAC,QAAQ,IAAI,UAAU,MAAM,iBAAiB,IAAI,UAAU;AAAA,IAAA,GAExD,cAAc,MAAM,OAAO,iBAAiB,KAAK,CAAC,QAAQ,IAAI,UAAU,MAAM,IAAI,IAAI;AAC5F,wBAAoB,eAAe,eAAe,IAAI;AAAA,EACxD,GAAG,CAAC,OAAO,OAAO,MAAM,CAAC;AAEzB,QAAM,4BAA4B,YAAY;AAC5C,mBAAe,EAAI;AACnB,QAAI;AACF,YAAM,gBAAgB,QAAQ,OAAO,KAAK;AAAA,IAC5C,SAAS,OAAO;AACd,UAAI,eAAe,oBACf,QAAQ;AAER,uBAAiB,SACnB,eAAe,MAAM,SACjB,MAAM,QAAQ,SAAS,OAAO,MAChC,QAAQ,uBAED,UAAU,yBAAyB,UAAU,8BACtD,eAAe,OAAO,KAAK,GAC3B,QAAQ,oBAGV,MAAM,KAAK;AAAA,QACT;AAAA,QACA,QAAQ;AAAA,QACR,aAAa;AAAA,MAAA,CACd;AAAA,IACH,UAAA;AACE,qBAAe,EAAK;AAAA,IACtB;AAAA,EACF,GAEM,qBAAqB,MACrB,MAAM,MAAM,MAAM,WACb,GAAG,MAAM,QAAQ,IAAI,MAAM,iBAAiB,IAAI,SAElD,YAAY,MAAM,iBAAiB,IAAI,QAG1C,gBAAgB,OAAO,UACL,MAAM,OAAO,OAAO,OAAO,QAAQ,MAAM;AAAA,IAC7D,UAAU,KAAK;AAAA,EAAA,CAChB,GACoB,KAGjB,mBAAmB,YAAY;AACnC,QAAI,EAAA,CAAC,MAAM,OAAO,CAAC,MAAM;AACzB,UAAI;AACF,cAAM,kBAAkB,MAAM,SAAS,QAAQ,MAAM,OAAO;AAC5D,cAAM,OACH,MAAM,MAAM,GAAG,EACf,IAAI,EAAC,MAAM,gBAAgB,MAAM,QAAQ,gBAAgB,KAAK,OAAA,CAAO,EACrE,OAAA;AAAA,MACL,SAAS,cAAc;AACrB,gBAAQ,MAAM,iCAAiC,YAAY;AAAA,MAC7D;AAAA,EACF,GAEM,8BAA8B,YAAY;AAC9C,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,sBAAsB;AAGxC,UAAM,cAAcqC,MAAK,QACnB,sBAAsB,aAAa,KAAA,GAEnC,aAAa,MAAM;AAEzB,QAAI;AACF,YAAM,gBAAgB,QAAQ,MAAM,SAAS,UAAU;AAAA,IACzD,SAAS,aAAa;AACpB,YAAA,MAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa;AAAA,MAAA,CACd,GACD,gBAAgB,EAAK,GACf;AAAA,IACR;AAEA,QAAI,cAAc,OAAO,KAAA;AAEzB,QAAI;AACF,UAAI;AACF,sBAAc,MAAM,cAAc,YAAY;AAAA,MAChD,SAAS,aAAa;AACpB,cAAA,MAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aAAa;AAAA,QAAA,CACd,GACD,gBAAgB,EAAK,GACf;AAAA,MACR;AAGF,QAAI;AACF,YAAM,oBAAoB,QAAQ,MAAM,SAAS,aAAa;AAAA,QAC5D,eAAe;AAAA,QACf,MAAM;AAAA,QACN,WAAW;AAAA,MAAA,CACZ;AAAA,IACH,SAAS,OAAgB;AACvB,YAAA,MAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa,oBAAoB,OAAO,gCAAgC;AAAA,MAAA,CACzE,GACD,gBAAgB,EAAK,GACf;AAAA,IACR;AAEA,UAAM,SAAS,MAAM,gBAAgB;AAAA,MACnC;AAAA,MACA,SAAS,MAAM;AAAA,MACf,WAAW;AAAA,MACX,mBAAmB;AAAA,MACnB,gBAAgB,OAAO,iBAAiB;AACtC,cAAM,eACJ,aAAa,OAAO,WAAW,CAAC,KAChC,aAAa,OAAO,QACpB;AACF,cAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aAAa;AAAA,QAAA,CACd,GACD,MAAM,iBAAA,GACN,SAAS,cAAc,UAAU,GACjC,gBAAgB,EAAK;AAAA,MACvB;AAAA,IAAA,CACD;AAED,QAAI,CAAC,OAAO,SAAS,CAAC,OAAO,OAAO;AAClC,YAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aACE;AAAA,MAAA,CACH,GACD,gBAAgB,EAAK;AACrB;AAAA,IACF;AAEI,WAAO,WAAW,cAItB,MAAM,iBAAA,GAEF,OAAO,WAAW,cACpB,MAAM,KAAK;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,aACE;AAAA,IAAA,CACH,IAED,MAAM,KAAK;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,aAAa;AAAA,IAAA,CACd,GAGH,SAAS,OAAO,OAAO,UAAU,GACjC,gBAAgB,EAAK;AAAA,EACvB,GAEM,eAAe,YAAY;AAC/B,QAAI,CAACA,MAAK,QAAQ;AAChB,YAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa;AAAA,MAAA,CACd;AACD;AAAA,IACF;AAEA,QAAI,CAAC,aAAa,QAAQ;AACxB,YAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa;AAAA,MAAA,CACd;AACD;AAAA,IACF;AAEA,oBAAgB,EAAI;AAEpB,QAAI;AACF,UAAI,CAAC,MAAM;AACT,cAAM,IAAI,MAAM,sBAAsB;AAGxC,YAAM,kBAAkB,MAAM;AAC5B,YAAI,mBAAmB,CAAC,MAAM,GAAI,QAAO;AACzC,cAAM,aAAa,cAAc,KAAK;AACtC,YAAI,CAAC,WAAY,QAAO;AACxB,YAAI,MAAM,0BAA0B,UAAU,SAAS,MAAM,EAAE;AAC/D,YAAI,kBAAkB,KAAK,GAAG,WAAW,UAAU;AACjD,gBAAM,QAAQ,YAAY,QAAQ,YAAY,GAAG;AACjD,iBAAO,UAAU,KAAK;AAAA,QACxB;AACA,eAAO;AAAA,MACT,GAAA,GAEM,aACJ,iBAAiB,QAAS,OAAO,UAAU,OAAO,KAAA,MAAW;AAE/D,UAAI,CAAC,YAAY;AACf,cAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aACE;AAAA,QAAA,CACH,GACD,gBAAgB,EAAK;AACrB;AAAA,MACF;AAEA,UAAI,YAAY;AACd,YAAI,CAAC,gBAAgB,OAAO,KAAA;AAC1B,cAAI;AACG,gBAAI,IAAI,OAAO,MAAM;AAAA,UAC5B,QAAQ;AACN,kBAAM,KAAK;AAAA,cACT,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,aAAa;AAAA,YAAA,CACd,GACD,gBAAgB,EAAK;AACrB;AAAA,UACF;AAGF,YAAI,CAAC,gBAAgB,CAAC,OAAO,QAAQ;AACnC,gBAAM,KAAK;AAAA,YACT,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,aAAa;AAAA,UAAA,CACd,GACD,gBAAgB,EAAK;AACrB;AAAA,QACF;AAEA,cAAM,4BAAA;AAAA,MACR;AAEA,cAAA;AAAA,IACF,SAAS,OAAO;AACd,YAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAAA,CACvD;AAAA,IACH,UAAA;AACE,sBAAgB,EAAK;AAAA,IACvB;AAAA,EACF;AAEA,SACE1E,2BAAAA;AAAAA,IAACI,GAAAA;AAAAA,IAAA;AAAA,MACC,IAAI;AAAA,MACJ,QAAO;AAAA,MACP;AAAA,MACA,OAAO;AAAA,MACP,gBAAgB;AAAA,MAEhB,UAAAG,2BAAAA,KAACF,GAAAA,OAAA,EAAM,SAAS,GAAG,OAAO,GACxB,UAAA;AAAA,QAAAE,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAE,2BAAAA,KAACC,GAAAA,MAAA,EAAK,SAAS,GAAG,cAAc,GAAG,MAAK,eAAc,QAAM,IAAC,QAAQ,GACnE,UAAA;AAAA,YAAAD,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,SAAQ,iBAC3B,UAAA;AAAA,cAAA9B,2BAAAA,IAACS,GAAAA,MAAA,EAAM,+BAAmB,CAAE;AAAA,cAC5BF,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,KAAK,GACR,UAAA;AAAA,gBAAA,MAAM,WAAW,aAChB9B,2BAAAA;AAAAA,kBAACM,GAAAA;AAAAA,kBAAA;AAAA,oBACC,MACE,cACEN,2BAAAA;AAAAA,sBAACsD,GAAAA;AAAAA,sBAAA;AAAA,wBACC,OAAO;AAAA,0BACL,eAAe;AAAA,0BACf,SAAS;AAAA,0BACT,WAAW;AAAA,0BACX,OAAO;AAAA,0BACP,QAAQ;AAAA,wBAAA;AAAA,sBACV;AAAA,oBAAA,mCAGDwB,MAAAA,cAAA,EAAa;AAAA,oBAGlB,MAAK;AAAA,oBACL,MAAK;AAAA,oBACL,MAAK;AAAA,oBACL,UAAU;AAAA,oBACV,SAAS;AAAA,oBACT,SAAS;AAAA,oBACT,UAAU,eAAe;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAG7B9E,2BAAAA;AAAAA,kBAACM,GAAAA;AAAAA,kBAAA;AAAA,oBACC,MAAMqE,MAAAA;AAAAA,oBACN,MAAK;AAAA,oBACL,MAAK;AAAA,oBACL,MAAK;AAAA,oBACL,UAAU;AAAA,oBACV,SAAS;AAAA,oBACT,SAAS,MAAM,aAAa,SAAS,MAAA;AAAA,oBACrC,UAAU;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACZ,EAAA,CACF;AAAA,YAAA,GACF;AAAA,YACA3E,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,KAAK;AAAA,gBACL,MAAK;AAAA,gBACL,QAAO;AAAA,gBACP,OAAO,EAAC,SAAS,OAAA;AAAA,gBACjB,UAAU,CAAC,MAAM;AACX,oBAAE,OAAO,SAAS,EAAE,OAAO,MAAM,SAAS,KAAK,CAAC,iBAClD,gBAAgB,EAAE,OAAO,MAAM,CAAC,CAAC,GACjC,UAAU,EAAE;AAAA,gBAEhB;AAAA,cAAA;AAAA,YAAA;AAAA,YAED,gBACCO,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,OAAO,EAAC,WAAW,EAAA,GAAI,UAAA;AAAA,cAAA;AAAA,cAC/B,aAAa;AAAA,YAAA,EAAA,CAC1B;AAAA,UAAA,GAEJ;AAAA,UACAF,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,YAAAL,2BAAAA,IAAC+D,GAAAA,OAAA,EAAM,SAAQ,WAAU,UAAA,gBAAY;AAAA,YACrC/D,2BAAAA;AAAAA,cAACuC,GAAAA;AAAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,aAAY;AAAA,gBACZ,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM;AACf,4BAAU,EAAE,cAAc,KAAK,GAC/B,gBAAgB,IAAI;AAAA,gBACtB;AAAA,gBACA,UAAU;AAAA,cAAA;AAAA,YAAA;AAAA,2CAEX9B,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,4DAAA,CAErB;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,GACF;AAAA,QAEAF,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAL,2BAAAA,IAAC+D,GAAAA,OAAA,EAAM,SAAQ,gBAAe,UAAA,cAAU;AAAA,UACxC/D,2BAAAA;AAAAA,YAAC4E,GAAAA;AAAAA,YAAA;AAAA,cACC,IAAG;AAAA,cACH,OAAO,kBAAkB,SAAS;AAAA,cAClC,UAAU,CAAC,aAAa;AACtB,sBAAM,WAAW,iBAAiB,KAAK,CAAC,QAAQ,IAAI,UAAU,QAAQ;AAClE,6BACF,oBAAoB,QAAQ,GAC5B,gBAAgB,SAAS,KAAK,GAC9B,QAAQ,SAAS,KAAK;AAAA,cAE1B;AAAA,cACA,SAAS;AAAA,cACT,MAAMC,MAAAA;AAAAA,cACN,aAAY;AAAA,cACZ,cAAc,CAAC,OAAO,WACpB,OAAO,MAAM,YAAA,EAAc,QAAQ,MAAM,YAAA,CAAa,IAAI,MAC1D,OAAO,MAAM,YAAA,EAAc,QAAQ,MAAM,YAAA,CAAa,IAAI;AAAA,cAE5D,YAAU;AAAA,cACV,aAAa,CAAC,UAAU,iBAAiB,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK,GAAG,SAAS;AAAA,cAClF,cAAc,CAAC,0CACZrE,GAAAA,MAAA,EAAK,WAAQ,UAAS,SAAS,GAAG,QAAQ,GAAG,MAAK,WACjD,UAAAD,2BAAAA,KAACE,GAAAA,QAAK,MAAM,GAAG,cAAa,YACzB,UAAA;AAAA,gBAAA,OAAO;AAAA,gBAAM;AAAA,gBAAG,OAAO;AAAA,gBAAM;AAAA,cAAA,EAAA,CAChC,EAAA,CACF;AAAA,cAEF,UAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ,GACF;AAAA,QAEAF,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAL,2BAAAA,IAAC+D,GAAAA,OAAA,EAAM,SAAQ,oBAAmB,UAAA,iBAAa;AAAA,UAC/C/D,2BAAAA;AAAAA,YAACuC,GAAAA;AAAAA,YAAA;AAAA,cACC,IAAG;AAAA,cACH,aAAY;AAAA,cACZ,OAAO;AAAA,cACP,UAAU,CAAC,MAAM;AACf,gCAAgB,EAAE,cAAc,KAAK,GACjC,oBAAoB,iBAAiB,UAAU,EAAE,cAAc,UACjE,oBAAoB,IAAI,IACpB,CAACmC,SAAQA,UAAS,iBAAiB,UACrC,QAAQ,EAAE;AAAA,cAGhB;AAAA,cACA,UAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ,GACF;AAAA,wCAEC5C,GAAAA,MAAA,EAAK,KAAK,GAAG,SAAQ,YAAW,WAAW,GAC1C,UAAA;AAAA,UAAA9B,2BAAAA,IAACM,GAAAA,QAAA,EAAO,MAAK,UAAS,MAAK,SAAQ,SAAS,SAAS,UAAU,aAAA,CAAc;AAAA,UAC7EN,2BAAAA;AAAAA,YAACM,GAAAA;AAAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,MAAK;AAAA,cACL,MACE,eACEN,2BAAAA;AAAAA,gBAACsD,GAAAA;AAAAA,gBAAA;AAAA,kBACC,OAAO;AAAA,oBACL,eAAe;AAAA,oBACf,SAAS;AAAA,oBACT,cAAc;AAAA,oBACd,OAAO;AAAA,oBACP,QAAQ;AAAA,oBACR,aAAa;AAAA,kBAAA;AAAA,gBACf;AAAA,cAAA,IAGFqB,MAAAA;AAAAA,cAGJ,SAAS;AAAA,cACT,UAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;AC3dA,SAAS,UAAU;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmB;AACjB,QAAM,aAAa,CAAC,WACd,WAAW,aAEX,uBAAuB,QAAQ,oBAAoB,MAAM,MAAM,aAAa,OAAO,MAAM,KAGzF,WAAW,SAEX,uBAAuB,MAAM,MAC7B,oBAAoB,MAAM,MAC1B,aAAa,OAAO,MAAM,KAI5B,uBAAuB,MAAM,MAAM,oBAAoB,QAAQ,aAAa,OAAO,MAAM,IAIvF,sBAAsB,MACtB,MAAM,WAAW,8CAEhB7C,GAAAA,MAAA,EAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,IAAA9B,2BAAAA;AAAAA,MAACsD,GAAAA;AAAAA,MAAA;AAAA,QACC,OAAK;AAAA,QACL,OAAO;AAAA,UACL,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,eAAe;AAAA,UACf,SAAS;AAAA,UACT,cAAc;AAAA,QAAA;AAAA,MAChB;AAAA,IAAA;AAAA,mCAED7C,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,gBAAA,CAErB;AAAA,EAAA,EAAA,CACF,IAKFF,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,KAAK,GACR,UAAA;AAAA,IAAA,MAAM,WAAW,aAChB9B,2BAAAA;AAAAA,MAACM,GAAAA;AAAAA,MAAA;AAAA,QACC,MACE,uBAAuB,MAAM,KAC3BN,2BAAAA;AAAAA,UAACsD,GAAAA;AAAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,eAAe;AAAA,cACf,SAAS;AAAA,cACT,WAAW;AAAA,cACX,OAAO;AAAA,cACP,QAAQ;AAAA,YAAA;AAAA,UACV;AAAA,QAAA,mCAGDwB,MAAAA,cAAA,EAAa;AAAA,QAGlB,MAAM,WAAW,SAAY;AAAA,QAC7B,MAAK;AAAA,QACL,MAAK;AAAA,QACL,UAAU;AAAA,QACV,SAAS;AAAA,QACT,SAAS,MAAM,eAAe,KAAK;AAAA,QACnC,UAAU,WAAW,UAAU;AAAA,QAC/B,OAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAGV9E,2BAAAA;AAAAA,MAACM,GAAAA;AAAAA,MAAA;AAAA,QACC,qCAAOyE,MAAAA,UAAA,EAAS;AAAA,QAChB,MAAM,WAAW,SAAY;AAAA,QAC7B,MAAK;AAAA,QACL,MAAK;AAAA,QACL,UAAU;AAAA,QACV,SAAS;AAAA,QACT,UAAU,WAAW,MAAM;AAAA,QAC3B,SAAS,MAAM,eAAe,KAAK;AAAA,QACnC,OAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAER/E,2BAAAA;AAAAA,MAACM,GAAAA;AAAAA,MAAA;AAAA,QACC,MACE,oBAAoB,MAAM,KACxBN,2BAAAA;AAAAA,UAACsD,GAAAA;AAAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,eAAe;AAAA,cACf,SAAS;AAAA,cACT,WAAW;AAAA,cACX,OAAO;AAAA,cACP,QAAQ;AAAA,YAAA;AAAA,UACV;AAAA,QAAA,mCAGD0B,MAAAA,WAAA,EAAU;AAAA,QAGf,MAAM,WAAW,SAAY;AAAA,QAC7B,MAAK;AAAA,QACL,MAAK;AAAA,QACL,UAAU;AAAA,QACV,SAAS;AAAA,QACT,UAAU,WAAW,QAAQ;AAAA,QAC7B,SAAS,MAAM,iBAAiB,KAAK;AAAA,QACrC,OAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EACR,GACF;AAIJ,SACEhF,2BAAAA;AAAAA,IAACQ,GAAAA;AAAAA,IAAA;AAAA,MACC,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,MAAM,MAAM,WAAW,YAAY,YAAY;AAAA,MAC/C,QAAM;AAAA,MAEN,0CAACsB,SAAA,EAAK,OAAM,UAAS,SAAQ,iBAAgB,KAAK,GAChD,UAAA;AAAA,QAAAvB,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GAAG,MAAM,GACrB,UAAA;AAAA,UAAAE,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,YAAA9B,+BAACS,GAAAA,MAAA,EAAK,QAAO,YAAY,UAAA,MAAM,QAAQ,YAAW;AAAA,YAClDF,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA;AAAA,cAAA;AAAA,cACjB,oBAAoB,KAAK;AAAA,cAAE;AAAA,YAAA,GAC/B;AAAA,YACC,MAAM,WAAW,aAChBT,2BAAAA;AAAAA,cAACuD,MAAAA;AAAAA,cAAA;AAAA,gBACC,OAAO,EAAC,OAAO,6BAAA;AAAA,gBACf,cAAW;AAAA,gBACX,UAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ,GAEJ;AAAA,UACC,MAAM,iBACLhD,2BAAAA,KAACE,WAAK,MAAM,GAAG,OAAK,IAAC,UAAA;AAAA,YAAA;AAAA,YACR,MAAM;AAAA,UAAA,GACnB;AAAA,UAED,MAAM,WAAW,aAAa,MAAM,SACnCT,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAO,EAAC,OAAO,gCAC3B,gBAAM,MAAM,WAAW,CAAC,KAAK,MAAM,MAAM,QAAQ,0BAAA,CACpD;AAAA,QAAA,GAEJ;AAAA,QACC,oBAAA;AAAA,MAAoB,EAAA,CACvB;AAAA,IAAA;AAAA,EAAA;AAGN;AASA,SAAwB,kBAAkB;AAAA,EACxC;AAAA,EACA,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,iBAAiB;AACnB,GAA2B;AACzB,QAAM,SAAS,UAAA,GACT,QAAQ8D,GAAAA,SAAA,GACR,WAAW,sBAAsB7C,MAAAA,OAAO,IACxC,EAAC,gBAAe,eAAA,GAChB,CAAC,oBAAoB,qBAAqB,IAAIxB,MAAAA,SAAwB,IAAI,GAC1E,CAAC,iBAAiB,kBAAkB,IAAIA,MAAAA,SAAwB,IAAI,GACpE,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAyB,EAAE,GAC3D,CAAC,eAAe,gBAAgB,IAAIA,MAAAA,SAAoC,oBAAI,IAAA,CAAK,GACjF,CAAC,oBAAoB,qBAAqB,IAAIA,eAA8B,oBAAI,IAAA,CAAK,GACrF,CAAC,uBAAuB,wBAAwB,IAAIA,MAAAA,6BAA0B,IAAA,CAAK,GACnF,CAAC,eAAe,gBAAgB,IAAIA,MAAAA,SAA8B,IAAI,GACtE,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAA8B,IAAI,GAClE,CAAC,eAAe,gBAAgB,IAAIA,MAAAA,SAAS,EAAK,GAClD,CAAC,YAAY,aAAa,IAAIA,MAAAA,SAAS,EAAK,GAE5C,qBAAqB,GAMrB,gBAJ6B,cAE/B,MAAM,MAAM,QAAQ,OAAO,CAAC,UAAiC,MAAM,SAAS,MAAM,KAAK,CAAA,GAE3D;AAAA,IAC9B,CAAC,UACC,MAAM,OACL,MAAM,WAAW,WAAW,MAAM,WAAW,eAAe,MAAM,WAAW;AAAA,EAAA,GAG5E,YAAYgB,MAAAA,QAAQ,MAAM;AAC9B,UAAM,oBAAoB,aAAa,IAAI,CAAC,UAC1B,cAAc,IAAI,MAAM,EAAE,KACxB,KACnB,GAEK,sBAAsB,CAAC,WAAyB,mBAChD,CAAC,UAAU,MAAM,CAAC,UAAU,GAAG,WAAW,aAAa,IAClD,KAEF,eAAe,KAAK,CAAC,cAAc;AACxC,YAAM,cAAc,UAAU,SAAS,UAAU,MAC3C,kBAAkB,UAAU,kBAAkB,UAAU;AAC9D,aAAI,CAAC,eAAe,CAAC,kBACZ,KAEL,UAAU,WAAW,UAErB,UAAU,gBAAgB,oBAC1B,UAAU,gBAAgB,0BAC1B,UAAU,gBAAgB,kBAG1B,UAAU,WAAW;AAAA,IAI3B,CAAC,GAGG,6BAA6B,CACjC,YACA,mBAEK,WAAW,KACZ,WAAW,GAAG,WAAW,aAAa,IACjC,oBAAoB,YAAY,cAAc,IAEhD,eAAe,KAAK,CAAC,cAAc,UAAU,OAAO,WAAW,EAAE,IAJ7C,IAOvB,eAAe,YAAY,OAAO,CAAC,eACnC,WAAW,MAAM,WAAW,GAAG,WAAW,aAAa,IAClD,CAAC,oBAAoB,YAAY,iBAAiB,IAEpD,CAAC,2BAA2B,YAAY,iBAAiB,CACjE;AAED,WAAO,CAAC,GAAG,mBAAmB,GAAG,YAAY;AAAA,EAC/C,GAAG,CAAC,cAAc,aAAa,aAAa,CAAC;AAE7CmB,QAAAA,UAAU,MAAM;AACd,UAAM,0CAA0B,IAAA;AAEhC,iBAAa,QAAQ,CAAC,UAAU;AAE5B,YAAM,OACL,MAAM,gBAAgB,oBACrB,MAAM,gBAAgB,0BACtB,MAAM,gBAAgB,oBAExB,oBAAoB,IAAI,MAAM,EAAE;AAAA,IAEpC,CAAC,GAED,YAAY,QAAQ,CAAC,cAAc;AACjC,UAAI,UAAU,MAAM,UAAU,GAAG,WAAW,aAAa,GAAG;AAC1D,cAAM,YAAY,aAAa,KAAK,CAAC,OAAO;AAC1C,gBAAM,cAAc,GAAG,SAAS,UAAU,MACpC,kBAAkB,GAAG,kBAAkB,UAAU;AACvD,iBAAO,eAAe;AAAA,QACxB,CAAC;AACG,mBAAW,MACb,oBAAoB,IAAI,UAAU,EAAE;AAAA,MAExC;AAAA,IACF,CAAC,GAED,yBAAyB,CAAC,SAAS;AACjC,UAAI,SAAS;AACb,YAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,aAAA,oBAAoB,QAAQ,CAAC,OAAO;AAC7B,aAAK,IAAI,EAAE,MACd,QAAQ,IAAI,EAAE,GACd,SAAS;AAAA,MAEb,CAAC,GACM,SAAS,UAAU;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,WAAW,CAAC,GAE9BA,MAAAA,UAAU,MAAM;AAEd,QADwB,UAAU,OAAO,CAAC,UAAU,MAAM,WAAW,WAAW,EAC5D,WAAW,KAAK,CAAC,MAAM,WAAW,CAAC,MAAM;AAC3D;AAGF,UAAM,WAAW,YAAY,YAAY;AACvC,UAAI;AACF,cAAM,UAAU,MAAM,YAAY,KAAK;AACvC,YAAI,CAAC,QAAS;AAEd,cAAM,gBACJ,QAAQ,QAAQ,OAAO,CAAC,UAAiC,MAAM,SAAS,MAAM,KAAK,IAE/E,sBAAsB,CAC1B,WACA,sBAEI,CAAC,UAAU,MAAM,CAAC,UAAU,GAAG,WAAW,aAAa,IAClD,KAEF,kBAAkB,KAAK,CAAC,cAAc;AAC3C,gBAAM,cAAc,UAAU,SAAS,UAAU,MAC3C,kBAAkB,UAAU,kBAAkB,UAAU;AAC9D,iBAAI,CAAC,eAAe,CAAC,kBACZ,KAEL,UAAU,WAAW,UAErB,UAAU,gBAAgB,oBAC1B,UAAU,gBAAgB,0BAC1B,UAAU,gBAAgB,kBAG1B,UAAU,WAAW;AAAA,QAI3B,CAAC,GAGG,sBAAsB,oBAAI,IAAA;AAChC,sBAAc,QAAQ,CAAC,UAAU;AAE7B,gBAAM,OACL,MAAM,gBAAgB,oBACrB,MAAM,gBAAgB,0BACtB,MAAM,gBAAgB,oBAExB,oBAAoB,IAAI,MAAM,EAAE;AAAA,QAEpC,CAAC;AAED,cAAM,wBAAwB,CAAC,WAAyB,eAC/C,WAAW,KAAK,CAAC,OAAO;AAC7B,gBAAM,cAAc,GAAG,SAAS,UAAU,MACpC,kBAAkB,GAAG,kBAAkB,UAAU;AACvD,iBAAO,eAAe;AAAA,QACxB,CAAC;AAGH,uBAAe,CAAC,SACP,KAAK,OAAO,CAAC,cAAc;AAChC,cAAI,UAAU,MAAM,UAAU,GAAG,WAAW,aAAa,GAAG;AAC1D,kBAAM,WAAW,oBAAoB,WAAW,aAAa;AAC7D,gBAAI,UAAU;AACZ,oBAAM,YAAY,sBAAsB,WAAW,aAAa;AAC5D,yBAAW,OACb,oBAAoB,IAAI,UAAU,EAAE,GACpC,sBAAsB,CAAC,cAAc;AACnC,sBAAM,YAAY,UAAU,IAAI,UAAU,EAAE;AAC5C,oBAAI,WAAW;AACb,wBAAM,SAAS,IAAI,IAAI,SAAS;AAChC,yBAAA,OAAO,IAAI,UAAU,IAAI,SAAS,GAC3B;AAAA,gBACT;AACA,uBAAO;AAAA,cACT,CAAC;AAAA,YAEL;AACA,mBAAO,CAAC;AAAA,UACV;AACA,iBAAO;AAAA,QACT,CAAC,CACF,GAEG,oBAAoB,OAAO,KAC7B,yBAAyB,CAAC,YAAY;AACpC,gBAAM,UAAU,IAAI,IAAI,OAAO;AAC/B,iBAAA,oBAAoB,QAAQ,CAAC,OAAO,QAAQ,IAAI,EAAE,CAAC,GAC5C;AAAA,QACT,CAAC;AAAA,MAEL,SAAS,OAAO;AACd,gBAAQ,MAAM,iCAAiC,KAAK;AAAA,MACtD;AAAA,IACF,GAAG,GAAI;AAEP,WAAO,MAAM,cAAc,QAAQ;AAAA,EACrC,GAAG,CAAC,WAAW,OAAO,WAAW,CAAC;AAElC,QAAM,gBAAgB,UACnB;AAAA,IACC,CAAC,UACC,MAAM,WAAW,WAAW,MAAM,WAAW,eAAe,MAAM,WAAW;AAAA,EAAA,EAEhF,KAAK,CAACO,IAAG,MAAM;AACd,UAAM,SAAS,mBAAmB,IAAIA,GAAE,EAAE,KAAK,GACzC,SAAS,mBAAmB,IAAI,EAAE,EAAE,KAAK;AAE/C,QAAI,SAAS,KAAK,SAAS;AACzB,aAAO,SAAS;AAGlB,QAAI,SAAS,EAAG,QAAO;AACvB,QAAI,SAAS,EAAG,QAAO;AAEvB,UAAM,eAAeA,GAAE,WAAW,aAC5B,eAAe,EAAE,WAAW;AAClC,QAAI,gBAAgB,CAAC,aAAc,QAAO;AAC1C,QAAI,CAAC,gBAAgB,aAAc,QAAO;AAE1C,UAAM,mBACHA,GAAE,MAAMA,GAAE,GAAG,WAAW,aAAa,KAAOA,GAAE,MAAM,sBAAsB,IAAIA,GAAE,EAAE,GAC/E,mBACH,EAAE,MAAM,EAAE,GAAG,WAAW,aAAa,KAAO,EAAE,MAAM,sBAAsB,IAAI,EAAE,EAAE;AACrF,WAAI,oBAAoB,CAAC,mBAAyB,KAC9C,CAAC,oBAAoB,mBAAyB,IAE3C;AAAA,EACT,CAAC,GAEG,iBAAiB,OAAO,UAAwB;AACpD,QAAK,MAAM,IAEX;AAAA,4BAAsB,MAAM,EAAE;AAC9B,UAAI;AACF,cAAM,gBAAgB,QAAQ,OAAO,KAAK;AAAA,MAC5C,SAAS,OAAO;AACd,cAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aAAa,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QAAA,CACvD;AAAA,MACH,UAAA;AACE,8BAAsB,IAAI;AAAA,MAC5B;AAAA,IAAA;AAAA,EACF,GAEM,gBAAgB,YAAY;AAChC,QAAI,CAAC,iBAAiB,CAAC,cAAc,GAAI;AAEzC,UAAM,QAAQ;AACd,qBAAiB,IAAI,GACrB,mBAAmB,MAAM,EAAE;AAC3B,QAAI;AACF,UAAI,CAAC,MAAM;AACT,cAAM,IAAI,MAAM,sBAAsB;AAExC,YAAM,gBAAgB,QAAQ,MAAM,SAAS,MAAM,EAAE,GAGrD,MAAM,YAAY,KAAK,GAEvB,MAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,MAAA,CACT,GAED,eAAe,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,MAAM,EAAE,CAAC,GAC9D,iBAAiB,CAAC,SAAS;AACzB,cAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,eAAA,OAAO,OAAO,MAAM,EAAE,GACf;AAAA,MACT,CAAC,GACD,sBAAsB,CAAC,SAAS;AAC9B,cAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,eAAA,OAAO,OAAO,MAAM,EAAE,GACf;AAAA,MACT,CAAC,GACD,yBAAyB,CAAC,SAAS;AACjC,cAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,eAAA,QAAQ,OAAO,MAAM,EAAE,GAChB;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAAA,CACvD;AAAA,IACH,UAAA;AACE,yBAAmB,IAAI;AAAA,IACzB;AAAA,EACF,GAEM,iBAAiB,CAAC,UAAwB;AAC9C,mBAAe,CAAC,SAAS,CAAC,GAAG,MAAM,KAAK,CAAC,GACzC,sBAAsB,CAAC,SAAS;AAC9B,YAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,aAAA,OAAO,IAAI,MAAM,IAAI,KAAK,OAAO,CAAC,GAC3B;AAAA,IACT,CAAC,GACD,iBAAiB,EAAK;AAAA,EACxB,GAEM,oBAAoB,OAAO,cAA4B,eAAwB;AAC/E,mBACF,eAAe,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,UAAU,CAAC,GAChE,iBAAiB,CAAC,SAAS;AACzB,YAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,aAAA,OAAO,OAAO,UAAU,GACjB;AAAA,IACT,CAAC,GACD,sBAAsB,CAAC,SAAS;AAC9B,YAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,aAAA,OAAO,OAAO,UAAU,GACjB;AAAA,IACT,CAAC,GACD,yBAAyB,CAAC,SAAS;AACjC,YAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,aAAA,QAAQ,OAAO,UAAU,GAClB;AAAA,IACT,CAAC,IAGkB,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,aAAa,EAAE,IAGnE,eAAe,CAAC,SAAS,KAAK,IAAI,CAAC,MAAO,EAAE,OAAO,aAAa,KAAK,eAAe,CAAE,CAAC,IAEvF,iBAAiB,CAAC,SAAS;AACzB,YAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,aAAA,OAAO,IAAI,aAAa,IAAI,YAAY,GACjC;AAAA,IACT,CAAC,GAGH,sBAAsB,CAAC,SAAS;AAC9B,YAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,aAAA,OAAO,IAAI,aAAa,IAAI,KAAK,OAAO,CAAC,GAClC;AAAA,IACT,CAAC,GAED,eAAe,IAAI,GAGnB,MAAM,YAAY,KAAK;AAAA,EACzB,GAEM,sBAAsB,CAAC,UACvB,MAAM,MAAM,MAAM,GAAG,WAAW,aAAa,KAG7C,MAAM,MAAM,sBAAsB,IAAI,MAAM,EAAE,KAIhD,MAAM,gBAAgB,0BACtB,MAAM,gBAAgB,oBACtB,MAAM,gBAAgB,kBAEf,mBAEL,MAAM,gBAAgB,aACjB,aAEF;AAGT,MAAI,cAAc,WAAW,KAAK,CAAC;AACjC,WACErC,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,MAAAL,2BAAAA,IAAC8B,GAAAA,MAAA,EAAK,SAAQ,YACZ,UAAA9B,2BAAAA;AAAAA,QAACM,GAAAA;AAAAA,QAAA;AAAA,UACC,MAAM2E,MAAAA;AAAAA,UACN,MAAK;AAAA,UACL,MAAK;AAAA,UACL,SAAS,MAAM,iBAAiB,EAAI;AAAA,QAAA;AAAA,MAAA,GAExC;AAAA,qCACCzE,GAAAA,MAAA,EAAK,SAAS,GAAG,QAAQ,GAAG,MAAK,eAAc,QAAM,IACpD,yCAACC,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,8FAErB,GACF;AAAA,MACC,iBACCT,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA,OAAO;AAAA,UACP,SAAS,MAAM,iBAAiB,EAAK;AAAA,QAAA;AAAA,MAAA;AAAA,IACvC,GAEJ;AAIJ,QAAM,kBACJ,kBAAkB,CAAC,aAAa,cAAc,MAAM,GAAG,kBAAkB,IAAI,eACzE,gBAAgB,kBAAkB,cAAc,SAAS;AAE/D,SACEO,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,IAAAL,2BAAAA,IAAC8B,GAAAA,MAAA,EAAK,SAAQ,YACZ,UAAA9B,2BAAAA;AAAAA,MAACM,GAAAA;AAAAA,MAAA;AAAA,QACC,MAAM2E,MAAAA;AAAAA,QACN,MAAK;AAAA,QACL,MAAK;AAAA,QACL,SAAS,MAAM,iBAAiB,EAAI;AAAA,MAAA;AAAA,IAAA,GAExC;AAAA,IAEC,gBAAgB,IAAI,CAAC,UACpBjF,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QAEC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MATK,MAAM;AAAA,IAAA,CAWd;AAAA,IAEA,iBACCA,2BAAAA,IAAC8B,GAAAA,MAAA,EAAK,SAAQ,UACZ,UAAA9B,2BAAAA;AAAAA,MAACM,GAAAA;AAAAA,MAAA;AAAA,QACC,MAAM,aAAa4E,MAAAA,gBAAgBC,MAAAA;AAAAA,QACnC,MACE,aAAa,cAAc,QAAQ,cAAc,SAAS,kBAAkB;AAAA,QAE9E,MAAK;AAAA,QACL,MAAK;AAAA,QACL,SAAS,MAAM,cAAc,CAAC,UAAU;AAAA,MAAA;AAAA,IAAA,GAE5C;AAAA,IAGD,iBACCnF,2BAAAA;AAAAA,MAACI,GAAAA;AAAAA,MAAA;AAAA,QACC,SAAO;AAAA,QACP,IAAI;AAAA,QACJ,QAAO;AAAA,QACP,SAAS,MAAM,iBAAiB,IAAI;AAAA,QACpC,gBAAgB,MAAM,iBAAiB,IAAI;AAAA,QAC3C,OAAO;AAAA,QAEP,UAAAJ,2BAAAA;AAAAA,UAACQ,GAAAA;AAAAA,UAAA;AAAA,YACC,SAAS;AAAA,YACT,OAAO;AAAA,cACL,WAAW;AAAA,cACX,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,YAAA;AAAA,YAGlB,UAAAD,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,cAAAE,2BAAAA,KAACsD,GAAAA,SAAA,EAAQ,MAAM,GAAG,UAAA;AAAA,gBAAA;AAAA,gBAEf,cAAc,QAAQ,cAAc,iBAAiB;AAAA,gBAAW;AAAA,cAAA,GACnE;AAAA,cACA7D,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA,+BAA2B;AAAA,6CACzCJ,GAAAA,OAAA,EAAM,OAAO,GAAG,SAAS,GACxB,yCAAC0B,QAAA,EACC,UAAA/B,2BAAAA;AAAAA,gBAACM,GAAAA;AAAAA,gBAAA;AAAA,kBACC,MACE,oBAAoB,cAAc,KAChCN,2BAAAA;AAAAA,oBAACsD,GAAAA;AAAAA,oBAAA;AAAA,sBACC,OAAO;AAAA,wBACL,eAAe;AAAA,wBACf,SAAS;AAAA,wBACT,WAAW;AAAA,wBACX,OAAO;AAAA,wBACP,QAAQ;AAAA,sBAAA;AAAA,oBACV;AAAA,kBAAA,mCAGD0B,MAAAA,WAAA,EAAU;AAAA,kBAGf,UAAU;AAAA,kBACV,SAAS;AAAA,kBACT,MAAK;AAAA,kBACL,MAAK;AAAA,kBACL,SAAS;AAAA,kBACT,UAAU,oBAAoB;AAAA,gBAAA;AAAA,cAAA,GAElC,EAAA,CACF;AAAA,YAAA,EAAA,CACF;AAAA,UAAA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,IAIH,iBACChF,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,OAAO;AAAA,QACP,SAAS,MAAM,iBAAiB,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,IAIxC,eACCA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,OAAO;AAAA,QACP,UAAU;AAAA,QACV,SAAS,MAAM,eAAe,IAAI;AAAA,MAAA;AAAA,IAAA;AAAA,EACpC,GAEJ;AAEJ;ACvtBA,MAAM,qBAAqBC,MAAAA,cAAuC;AAAA,EAChE,aAAa;AAAA,EACb,gBAAgB,MACP;AAEX,CAAC,GAMY,sBAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,MAEID,2BAAAA,IAAC,mBAAmB,UAAnB,EAA4B,OAAO,EAAC,aAAa,eAAA,GAC/C,SAAA,CACH,GAIS,wBAAwB,MACnBG,MAAAA,WAAW,kBAAkB;ACpBxC,SAAS,YAAY,EAAC,QAAQ,eAAAiF,kBAA8C;AACjF,QAAM,eAAe,IAAI,gBAAA;AAEzB,MAAIA,eAAc,WAAW,YAAYA,eAAc,WAAW,OAAO;AACvE,UAAM,QAAQ,YAAY,QAAQA,eAAc,IAAI,GAAG;AACvD,iBAAa,IAAI,SAAS,KAAK;AAAA,EACjC;AAEA,SAAO,0BAA0BA,eAAc,EAAE,SAAS,YAAY;AACxE;ACXA,SAAwB,eAAe,EAAC,SAAe;AACrD,QAAM,EAAC,mBAAkB,sBAAA,GACnB,WAAW,iBAAiB1D,MAAAA,OAAO;AAEzC,SACE1B,+BAACI,GAAAA,UAAO,IAAI,UAAU,QAAO,iBAAgB,SAAS,MAAM,eAAe,EAAK,GAAG,OAAO,GACxF,yCAACC,GAAAA,OAAA,EAAM,SAAS,GACd,UAAAL,2BAAAA,IAAC,mBAAA,EAAkB,OAAc,EAAA,CACnC,EAAA,CACF;AAEJ;ACkCA,SAAS,oBAAoB,SAAS;AACpC,QAAM;AAAA,IACJ,aAAa;AAAA,IACb,SAAS;AAAA,IACT,QAAQ;AAAA,EACZ,IAAM,WAAW,CAAA,GAET,MADa,OAAO,SAAW,OAAe,OAAO,OAAO,oBAAqB,WAC9D,OAAO,mBAAmB;AAEnD,SADgB,KAAK,IAAI,KAAK,IAAI,GAAG,QAAQ,KAAK,MAAM,GAAG,IAAI,GAAG,GAAG,MAAM;AAE7E;AChEO,SAAS,cAAc,SAAyB;AACrD,MAAI,OAAO,WAAY,YAAY,OAAO,MAAM,OAAO;AACrD,WAAO;AAGT,QAAM,MAAM,CAAC,EAAE,UAAU,OACnB,OAAO,CAAC,EAAG,UAAU,OAAQ,KAC7B,OAAO,CAAC,CAAC,UAAU;AAGzB,MAAI,MAAM;AAEV,SAAI,MAAM,MACR,OAAO,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,MAG7C,OAAO,KAAK,OAAO,OAAO,OAAO,KAAK,MAAM,KAC5C,OAAO,KAAK,MACL;AACT;AAGO,SAAS,sBAAsB,SAAyB;AAC7D,QAAM,MAAM,KAAK,MAAM,UAAU,IAAI,EAClC,SAAA,EACA,SAAS,GAAG,GAAG,GACZ,OAAO,KAAK,MAAO,UAAU,OAAQ,EAAE,EAC1C,WACA,SAAS,GAAG,GAAG,GACZ,OAAO,KAAK,MAAM,UAAU,EAAE,EACjC,SAAA,EACA,SAAS,GAAG,GAAG;AAElB,SAAO,GAAG,GAAG,IAAI,IAAI,IAAI,IAAI;AAC/B;AAGO,SAAS,kBAAkB,MAAc;AAE9C,SADc,qDACD,KAAK,IAAI,KAAK,SAAS;AACtC;AAGO,SAAS,yBAAyB,MAAsB;AAC7D,QAAM,CAAC,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,MAAM;AAC3D,SAAO,KAAK,OAAO,KAAK,KAAK;AAC/B;AC7BA,SAAwB,oBAAoB,EAAC,OAAO,cAAc,KAAW;AAC3E,QAAM,SAAS,UAAA,GAET,EAAC,eAAA,IAAkB,sBAAA,GACnB,WAAW,sBAAsB0B,MAAAA,OAAO,IAExC,CAAC,eAAe,gBAAgB,IAAIxB,MAAAA;AAAAA,IAAiB,MACzD,sBAAsB,WAAW;AAAA,EAAA,GAE7B,CAAC,UAAU,WAAW,IAAIA,MAAAA,SAAiB,WAAW,GACtD,CAAC,YAAY,aAAa,IAAIA,MAAAA,SAAiB,EAAE,GAEjD,wBAAwBgB,MAAAA,QAAQ,OAAO,EAAC,GAAG,OAAO,WAAW,aAAY,CAAC,OAAO,QAAQ,CAAC,GAC1F,CAAC,QAAQ,SAAS,IAAIhB,MAAAA,SAAS,EAAK,GACpC,CAAC,oBAAoB,qBAAqB,IAAIA,MAAAA,SAAuB,IAAI,GACzE,aAAa,MAAM;AACvB,cAAU,EAAI,GACd,OACG,MAAM,MAAM,GAAI,EAChB,IAAI,EAAC,WAAW,SAAA,CAAS,EACzB,OAAO,EAAC,iBAAiB,GAAA,CAAM,EAC/B,KAAK,MAAM,KAAK,eAAe,EAAK,CAAC,EACrC,MAAM,qBAAqB,EAC3B,QAAQ,MAAM,KAAK,UAAU,EAAK,CAAC;AAAA,EACxC,GACM,QAAQ,MAAM,oBAAoB,EAAC,QAAQ,GAAE;AAEnD,MAAI;AAGF,UAAM;AAgBR,SACEF,2BAAAA;AAAAA,IAACI,GAAAA;AAAAA,IAAA;AAAA,MACC,IAAI;AAAA,MACJ,QAAO;AAAA,MACP,SAAS,MAAM,eAAe,EAAK;AAAA,MACnC,QACEJ,2BAAAA,IAACK,GAAAA,OAAA,EAAM,SAAS,GACd,UAAAL,2BAAAA;AAAAA,QAACM,GAAAA;AAAAA,QAAA;AAAA,UAEC,UAAU,eAAe;AAAA,UACzB,MAAK;AAAA,UACL,MAAK;AAAA,UACL,SAAS;AAAA,UACT,SAAS;AAAA,UACT,MAAK;AAAA,QAAA;AAAA,QAND;AAAA,MAAA,GAQR;AAAA,MAGF,UAAAC,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GAAG,SAAS,GACxB,UAAA;AAAA,QAAAE,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,YAEjC;AAAA,UACAT,2BAAAA,IAAC,gBAAA,EAAe,OAAc,OAAc,aAAW,GAAA,CAAC;AAAA,QAAA,GAC1D;AAAA,QACAO,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,QAEjC;AAAA,yCACC,gBAAA,EAAe,OAAO,uBAAuB,OAAc,aAAW,GAAA,CAAC;AAAA,QAAA,GAC1E;AAAA,uCAECJ,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAAL,2BAAAA,IAAC8B,SAAA,EAAK,OAAO,UAAU,SAAS,UAC9B,UAAA9B,+BAACS,GAAAA,QAAK,MAAM,GAAG,QAAO,YAAW,UAAA,MAEjC,GACF,EAAA,CACF;AAAA,QAEAF,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,2CAEjC;AAAA,UACAT,2BAAAA;AAAAA,YAACuC,GAAAA;AAAAA,YAAA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAY;AAAA,cACZ,UA9DgB,CAAC,UAA6C;AACtE,sBAAM,QAAQ,MAAM,cAAc;AAGlC,oBAFA,iBAAiB,KAAK,GAElB,kBAAkB,KAAK,GAAG;AAC5B,gCAAc,EAAE;AAChB,wBAAM,eAAe,yBAAyB,KAAK;AACnD,8BAAY,YAAY;AAAA,gBAC1B;AACE,gCAAc,qBAAqB;AAAA,cAEvC;AAAA,cAoDU,gBAAgB;AAAA,YAAA;AAAA,UAAA;AAAA,QAClB,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;ACvHO,SAAS,UAAU,OAAgC;AACxD,SACEvC,2BAAAA,IAAC,OAAA,EAAI,OAAM,8BAA6B,OAAM,OAAM,QAAO,OAAM,SAAQ,aAAa,GAAG,OACvF,UAAAA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAO,EAAC,SAAS,OAAA;AAAA,MACjB,GAAE;AAAA,IAAA;AAAA,EAAA,GAEN;AAEJ;ACQA,SAAwB,YAAY;AAAA,EAClC;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAOG;AACD,QAAM,SAAS,aACT,EAAC,YAAA,IAAe,sBAAA,GAEhB,UAAU,aAAa,KAAK,GAC5B,YAAYiC,MAAAA,OAA+B,IAAI,GAC/C,qBAAqBA,aAAuB,IAAI,GAChD,CAAC,OAAO,QAAQ,IAAI/B,MAAAA,SAAA,GAGpB,aAAagB,MAAAA,QAAQ,MAAM;AAC/B,QAAI;AACF,aAAO,cAAc,OAAO,CAAC,UAAU,UAAU,KAAK,CAAC;AAAA,IACzD,QAAY;AACV,eAAS,IAAI,UAAU,0BAA0B,CAAC;AAClD;AAAA,IACF;AAAA,EACF,GAAG,CAAC,KAAK,CAAC,GAEJkE,iBAAgBlE,MAAAA,QAAQ,MAAM;AAClC,QAAK;AACL,aAAO,sBAAsB,OAAO,UAAU;AAAA,EAChD,GAAG,CAAC,OAAO,UAAU,CAAC,GAEhB,MAAMA,MAAAA,QAAQ,MAAM;AACxB,QAAK,cACAkE;AACL,aAAO;AAAA,QACL,MAAM,YAAY,EAAC,eAAAA,gBAAe,QAAO;AAAA,QACzC,CAAC,MAAa;AACZ,mBAAS,CAAC;AAAA,QAEZ;AAAA,MAAA;AAAA,EAEJ,GAAG,CAACA,gBAAe,YAAY,MAAM,CAAC,GAEhC,SAASlE,MAAAA,QAAQ,MACd;AAAA,IACL,MAAM,aAAa,EAAC,OAAO,QAAQ,OAAO,gBAAe;AAAA,IACzD,CAAC,MAAa;AACZ,eAAS,CAAC;AAAA,IAEZ;AAAA,EAAA,GAED,CAAC,OAAO,QAAQ,cAAc,CAAC,GAE5B,cAAcA,MAAAA,QAAQ,MAAM;AAChC,QAAI;AAEF,aADY,IAAI,IAAI,GAAI,EACb,aAAa,IAAI,OAAO;AAAA,IACrC,QAAQ;AACN;AAAA,IACF;AAAA,EACF,GAAG,CAAC,GAAG,CAAC,GACF,WAAWA,MAAAA,QAAQ,MAAM;AAC7B,QAAK,cACDkE,gBAAe,WAAW;AAE9B,aAAO;AAAA,QACL,MAAM,YAAY,QAAQ,YAAY,GAAG;AAAA,QACzC,CAAC,MAAa;AACZ,mBAAS,CAAC;AAAA,QAEZ;AAAA,MAAA;AAAA,EAEJ,GAAG,CAAC,QAAQA,gBAAe,QAAQ,UAAU,CAAC,GACxC,SAOUlE,MAAAA,QAAQ,MAAM;AAC5B,QAAI;AACF,YAAM,gBAKF;AAAA,QACF,UAAU;AAAA,QACV,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,KAAK;AAAA,MAAA;AAGP,aAAI,gBACF,cAAc,WAAW,aACzB,cAAc,YAAY,aAC1B,cAAc,aAAa,cAGzB,aACF,cAAc,MAAM,WAGf,EAAC,GAAG,cAAA;AAAA,IACb,QAAQ;AACN;AAAA,IACF;AAAA,EACF,GAAG,CAAC,aAAa,QAAQ,CAAC,GAEpB,CAAC,OAAO,MAAM,KAAK,OAAO,MAAM,gBAAgB,QAAQ,MAAM,GAAG,EAAE,IAAI,MAAM,GAC7E,oBACJ,MAAM,qBAAqB,OAAO,MAAM,KAAK,IAAI,KAAK,IAAI,QAAQ;AACpE,MAAI,cAAc,KAAK,IAAI,kBAAkB,iBAAiB;AAC9D,SAAI,YACF,cAAc,MAAM;AAAA;AAAA,IAEhB,MAAM,mBAAmB;AAAA,MACzB,qBAMJX,2BAAAA,KAAAsB,WAAAA,UAAA,EACE,UAAA;AAAA,IAAAtB,2BAAAA;AAAAA,MAACC,GAAAA;AAAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,OAAO;AAAA,UACL;AAAA,UACA,UAAU;AAAA,UACV,GAAI,WAAW,EAAC,SAAS,QAAQ,YAAY,WAAA;AAAA,QAAU;AAAA,QAGxD,UAAA;AAAA,UAAA,OAAO,UACND,2BAAAA,KAAAsB,WAAAA,UAAA,EACG,UAAA;AAAA,YAAA,WACC7B,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,UAAU;AAAA,kBACV,KAAK;AAAA,kBACL,MAAM;AAAA,kBACN,QAAQ;AAAA,gBAAA;AAAA,cACV;AAAA,YAAA;AAAA,YAGJO,2BAAAA,KAAC8C,MAAAA,UAAA,EAAS,UAAU,MAClB,UAAA;AAAA,cAAArD,2BAAAA;AAAAA,gBAACqF,mBAAAA;AAAAA,gBAAA;AAAA,kBACC,QAAQ,UAAU,SAAY;AAAA,kBAC9B,KAAK;AAAA,kBACJ,GAAG;AAAA,kBACJ,aAAU;AAAA,kBACV;AAAA,kBACA;AAAA,kBACA,SAAQ;AAAA,kBACR,aAAY;AAAA,kBACZ,UAAU;AAAA,oBACR,aAAa;AAAA,oBACb,gBAAgB;AAAA,oBAChB,WAAW;AAAA,kBAAA;AAAA,kBAEb,OAAO;AAAA,kBACP,YAAY;AAAA,kBACZ,OAAO;AAAA,oBACL,GAAI,CAAC,WAAW,EAAC,QAAQ,OAAA;AAAA,oBACzB,OAAO;AAAA,oBACP,SAAS;AAAA,oBACT,WAAW;AAAA,oBACX,GAAI,WAAW,EAAC,WAAW,MAAA;AAAA,kBAAK;AAAA,gBAClC;AAAA,cAAA;AAAA,cAED;AAAA,YAAA,EAAA,CACH;AAAA,UAAA,GACF;AAAA,UAED,QACCrF,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,KAAK;AAAA,gBACL,MAAM;AAAA,gBACN,WAAW;AAAA,cAAA;AAAA,cAGb,UAAAO,2BAAAA,KAACE,GAAAA,MAAA,EAAK,OAAK,IACT,UAAA;AAAA,gBAAAT,2BAAAA,IAACuD,MAAAA,kBAAA,EAAiB,OAAO,EAAC,aAAa,YAAW;AAAA,gBACjD,OAAO,SAAU,YAAY,aAAa,SAAS,OAAO,MAAM,WAAY,WACzE,MAAM,UACN;AAAA,cAAA,EAAA,CACN;AAAA,YAAA;AAAA,UAAA,IAEA;AAAA,UACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGF,gBAAgB,oBACfvD,2BAAAA,IAAC,qBAAA,EAAoB,OAAc,aAAa,WAAW,SAAS,aAAa;AAAA,IAElF,gBAAgB,mBAAmBA,2BAAAA,IAAC,gBAAA,EAAe,MAAA,CAAc;AAAA,EAAA,GACpE;AAEJ;AAEO,SAAS,aAAa,OAA2B;AACtD,SAAO,MAAM,MAAM,0BAA0B;AAC/C;AC/NA,MAAM,yBAAyB,CAAC,IAAY,cAAsB;AAAA,EAChE,uCACG,MAAA,EAAG,UAAA;AAAA,IAAA;AAAA,IACuBA,2BAAAA,IAAC,UAAM,UAAA,SAAA,CAAS;AAAA,EAAA,GAC3C;AAAA,EAEF,0CACG,MAAA,EAAG,UAAA;AAAA,IAAA;AAAA,IACQA,2BAAAA,IAAC,UAAM,UAAA,GAAA,CAAG;AAAA,EAAA,GACtB;AAAA,EAEF,OAAO,MAAMA,+BAACsF,MAAAA,oBAAA,CAAA,CAAmB;AACnC;AAEO,SAAS,kBAAkB,OAA+B;AAC/D,QAAM,EAAC,QAAQ,MAAA,IAAS;AAExB,SACEtF,+BAACuF,OAAAA,wBAAsB,GAAG,uBAAuB,MAAM,KAAK,MAAM,KAAK,GAAG,QAAgB;AAE9F;ACxBO,SAAS,QAAQ,EAAC,QAAqB;AAC5C,QAAM,UAAUC,OAAAA,WAAW,IAAI;AAE/B,SAAOjF,2BAAAA,KAAC,QAAA,EAAK,OAAO,SAAU,UAAA;AAAA,IAAA;AAAA,IAAQ;AAAA,EAAA,GAAI;AAC5C;ACHO,SAAS,YAAY,OAAmE;AAC7F,QAAM,EAAC,UAAAkF,cAAY,OACb,YAAYA,aAAY,gBAAgBA,aAAYA,UAAS;AAEnE,SACEzF,2BAAAA;AAAAA,IAAC0F,GAAAA;AAAAA,IAAA;AAAA,MACC,SAAO;AAAA,MACP,QAAM;AAAA,MACN,SACE1F,2BAAAA,IAAC+B,QAAA,EAAI,SAAS,GACZ,yCAACtB,GAAAA,MAAA,EAAK,MAAM,GACT,UAAAgF,YACClF,2BAAAA,KAAAsB,WAAAA,UAAA,EAAE,UAAA;AAAA,QAAA;AAAA,QAAQ,aAAa7B,2BAAAA,IAAC,SAAA,EAAQ,MAAM,UAAA,CAAW;AAAA,MAAA,GAAG,IAEpDA,2BAAAA,IAAA6B,qBAAA,EAAE,UAAA,uBAAA,CAAoB,EAAA,CAE1B,GACF;AAAA,MAGF,UAAA7B,2BAAAA,IAAC2F,qBAAA,EAAa,MAAK,WAAU,QAAQ,CAACF,WAAU,OAAO,CAACA,WAAU,MAAM,GACtE,UAAAzF,+BAAC+E,MAAAA,YAAS,EAAA,CACZ;AAAA,IAAA;AAAA,EAAA;AAGN;ACxBO,SAAS,gBAAgB,OAAmE;AACjG,QAAM,EAAC,UAAAU,cAAY,OACb,YAAYA,aAAY,gBAAgBA,aAAYA,UAAS;AAEnE,SACEzF,2BAAAA;AAAAA,IAAC0F,GAAAA;AAAAA,IAAA;AAAA,MACC,SAAO;AAAA,MACP,QAAM;AAAA,MACN,SACE1F,2BAAAA,IAAC+B,QAAA,EAAI,SAAS,GACZ,yCAACtB,GAAAA,MAAA,EAAK,MAAM,GACT,UAAAgF,YACClF,2BAAAA,KAAAsB,WAAAA,UAAA,EAAE,UAAA;AAAA,QAAA;AAAA,QAAW,aAAa7B,2BAAAA,IAAC,SAAA,EAAQ,MAAM,UAAA,CAAW;AAAA,MAAA,GAAG,IAEvDA,2BAAAA,IAAA6B,qBAAA,EAAE,UAAA,gBAAA,CAAa,EAAA,CAEnB,GACF;AAAA,MAGF,UAAA7B,2BAAAA,IAAC2F,qBAAA,EAAa,MAAK,YAAW,QAAQ,CAACF,WAAU,OAAO,CAACA,WAAU,MAAM,GACvE,UAAAzF,+BAAC4F,MAAAA,eAAY,EAAA,CACf;AAAA,IAAA;AAAA,EAAA;AAGN;ACGO,SAAS,gBAAgB,OAA6B;AAC3D,QAAM,EAAC,MAAM,QAAQ,UAAU,YAAY,MAAA,IAAS,OAC9C,QACHC,OAAAA,SAAS,MAAM,KAAK,KAAKC,MAAAA,eAAe,MAAM,KAAK,KACpDC,kBAAAA,QAAS,MAAM,KAAK,KACpBC,kBAAAA,QAAS,MAAM,KAAK,IAChB,MAAM,QACN,MAEA,aAAa9E,MAAAA;AAAAA,IACjB,MAAM+E,OAAAA,0BAA0B,MAAM,sBAAsB,YAAY,MAAM,GAAG;AAAA,IACjF,CAAC,MAAM,sBAAsB,YAAY,MAAM,GAAG;AAAA,EAAA,GAE9C,EAAC,UAAU,UAAU,UAAA,IAAaC,QAAAA,cAAc,YAAY;AAAA,IAChE,WAAW;AAAA,IACX,UAAU;AAAA,IACV,UAAU;AAAA,EAAA,CACX,GAEK,SAAS,YAAY,OACzB3F,2BAAAA,KAACmC,GAAAA,QAAA,EAAO,OAAO,GACZ,UAAA;AAAA,IAAA,YAAY,SAAS,SAAS,KAAK1C,2BAAAA,IAACmG,OAAAA,2BAAwB,UAAoB;AAAA,IACjFnG,2BAAAA,IAAC,iBAAA,EAAgB,UAAU,SAAA,CAAU;AAAA,IACrCA,2BAAAA,IAAC,aAAA,EAAY,UAAU,SAAA,CAAU;AAAA,EAAA,GACnC;AAGF,SACEA,2BAAAA;AAAAA,IAACuF,OAAAA;AAAAA,IAAA;AAAA,MACE,GAAIa,OAAAA,4BAA4B,EAAC,UAAU,UAAU,UAAU,EAAC,MAAA,GAAO;AAAA,MACxE,eAAe;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAAA;AAGN;ACpDO,SAAS,oBACd,MACA,YACA,aACkC;AAClC,SAAI,SAAS,KACJ,KAGF,QAAU,cAAc,WAAW,QAAiB,eAAe;AAC5E;AAEA,SAAS,oBAAoB,OAA6B;AACxD,SAAO,CAAC,cACNpG,2BAAAA,IAACqG,OAAAA,YAAA,EAAW,QAAO,QAAO,QAAQ,EAAC,IAAI,MAAM,aAAa,GAAA,GACvD,oBAAU,UACb;AAEJ;AAEO,SAAS,gBAAgB,OAA6B;AAC3D,QAAM,EAAC,YAAY,aAAA,IAAgB,OAC7B,MAAM,cAAc,SAAS,cAAc,WAC3C,KAAK,aAAa,MAAM,IACxB,uBAAuBC,+BAAA,GACvB,SAASC,OAAAA,aACT,mBAAmBC,OAAAA,oBAAoB,EAAE,GACzC,gBAAgB,CAAA,EAAQ,cAAc,WAAW,QAAQ,OAAO,IAAI,WAAW,IAAI,IAEnF,mBAAmBtF,MAAAA,QAAQ,MAC1B,MAED,CAAC,cAAc,CAAC,gBACXlB,2BAAAA,IAAC,mBAAA,EAAkB,OAAO,IAAA,CAAuB,IAIxDA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,MAAM,oBAAoB,QAAW,YAAYyG,MAAAA,YAAY;AAAA,MAC7D;AAAA,MACA,QAAO;AAAA,MACP,OAAO;AAAA,MACP,UAAU;AAAA,IAAA;AAAA,EAAA,IAbG,MAgBhB,CAAC,eAAe,YAAY,kBAAkB,KAAK,oBAAoB,CAAC;AAE3E,SACEzG,2BAAAA;AAAAA,IAAC0G,OAAAA;AAAAA,IAAA;AAAA,MACC,sBAAoB;AAAA,MACpB,IAAI,oBAAoB,KAAK;AAAA,MAC7B,WAAQ;AAAA,MACR,WAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,MAAK;AAAA,MAEJ,UAAA;AAAA,IAAA;AAAA,EAAA;AAGP;AC1EA,MAAM,YAAY9E,iBAAAA,OAAOG,MAAG;AAAA;AAAA,aAEf,CAAC,UAAe,MAAM,MAAM,OAAO,MAAM,KAAK,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAM5C,CAAC,UAAe,MAAM,MAAM,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC;AAAA;AAAA,GAIjE,kBAGD,CAAC,UAAU;AACd,QAAM,SAASwE,OAAAA,UAAA;AACf,MAAI,CAAC,MAAM;AACT,0CAAQ,YAAA,EAAW;AAGrB,MAAI,CAAC,MAAM,YAAY;AACrB,WACEvG,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,QAAM,IAAC,QAAQ,GAAG,SAAS,GAC/B,UAAAR,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,+CAAiC,GAClD;AAIJ,QAAM,gBAAgBU,OAAAA,QAAQ,MAAM,cAAc,CAAA,CAAE;AACpD,SACEnB,2BAAAA,IAAC,WAAA,EACE,UAAA,eAAe,IAAI,CAAC,iBAAiB;AACpC,UAAM,aAAa,OAAO,IAAI,aAAa,IAAI;AAE/C,WACEA,2BAAAA;AAAAA,MAACQ,GAAAA;AAAAA,MAAA;AAAA,QAEC,cAAc;AAAA,QACd,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,OAAO,EAAC,UAAU,SAAA;AAAA,QAElB,yCAACuB,GAAAA,KAAA,EACC,UAAA/B,+BAAC,iBAAA,EAAgB,cAA4B,YAAwB,EAAA,CACvE;AAAA,MAAA;AAAA,MATK,aAAa;AAAA,IAAA;AAAA,EAYxB,CAAC,EAAA,CACH;AAEJ;AChDA,SAAwB,aAAa;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,QAAM,SAAS,UAAA,GACT,CAAC,OAAO,QAAQ,IAAIE,eAExB,oBAAoB,GAChB,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAAS,EAAI,GAC7C,QAAQqE,YAAA;AAEdlC,QAAAA,UAAU,MAAM;AACV,cAAU,wBAAwB,qBAEtC,SAAS,YAAY,SAAS,eAAe,SAAS;AAAA,EACxD,GAAG,CAAC,OAAO,YAAY,iBAAiB,CAAC;AAEzC,iBAAe,gBAAgB;AAC7B,QAAI,UAAU,UAAW;AAEzB,aAAS,qBAAqB;AAC9B,UAAM,SAAS,MAAM,YAAY,EAAC,QAAQ,OAAO,aAAY;AACzD,eAAW,MACb,MAAM,KAAK,EAAC,OAAO,8BAA8B,QAAQ,UAAA,CAAU,GACnE,kBAAA,KACS,WAAW,gBACpB,MAAM,KAAK;AAAA,MACT,OAAO;AAAA,MACP,aAAa;AAAA,MACb,QAAQ;AAAA,IAAA,CACT,GACD,kBAAA,MAEA,MAAM,KAAK,EAAC,OAAO,yBAAyB,QAAQ,QAAA,CAAQ,GAE5D,SAAS,gBAAgB;AAAA,EAE7B;AAEA,SACErC,2BAAAA;AAAAA,IAACI,GAAAA;AAAAA,IAAA;AAAA,MACC,SAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,IAAG;AAAA,MACH,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,OAAO;AAAA,MACP,UAAS;AAAA,MAET,UAAAJ,2BAAAA;AAAAA,QAACQ,GAAAA;AAAAA,QAAA;AAAA,UACC,SAAS;AAAA,UACT,OAAO;AAAA,YACL,WAAW;AAAA,YACX,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,gBAAgB;AAAA,UAAA;AAAA,UAGlB,UAAAD,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACX,UAAA;AAAA,YAAA,UAAU,wBACTE,2BAAAA,KAAAsB,WAAAA,UAAA,EACE,UAAA;AAAA,cAAA7B,2BAAAA,IAAC6D,GAAAA,SAAA,EAAQ,MAAM,GAAG,UAAA,oCAAgC;AAAA,6CACjD,YAAA,CAAA,CAAW;AAAA,YAAA,GACd;AAAA,YAED,UAAU,gBACTtD,2BAAAA,KAAAsB,WAAAA,UAAA,EACE,UAAA;AAAA,cAAA7B,2BAAAA,IAAC6D,GAAAA,SAAA,EAAQ,MAAM,GAAG,UAAA,0BAA2B;AAAA,cAC7CtD,gCAACE,GAAAA,QAAK,MAAM,GAAG,OAAO,EAAC,cAAc,UAAS,UAAA;AAAA,gBAAA;AAAA,gBACjC,YAAY;AAAA,gBAAO;AAAA,gBAAU,cAAc,WAAW,SAAS,KAAK;AAAA,gBAAK;AAAA,gBAAI;AAAA,cAAA,GAG1F;AAAA,cACAT,2BAAAA,IAAC,iBAAA,EAAgB,YAAwB,UAAU,CAAC,kBAAA,CAAmB;AAAA,YAAA,GACzE;AAAA,YAED,UAAU,aACTO,2BAAAA,KAAAsB,WAAAA,UAAA,EACE,UAAA;AAAA,cAAA7B,2BAAAA,IAAC6D,GAAAA,SAAA,EAAQ,MAAM,GAAG,UAAA,+CAA2C;AAAA,cAC7D7D,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA,+BAA2B;AAAA,cAC1CF,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GAAG,SAAS,GACxB,UAAA;AAAA,gBAAAE,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,IAAG,SACtB,UAAA;AAAA,kBAAA9B,2BAAAA;AAAAA,oBAACwC,GAAAA;AAAAA,oBAAA;AAAA,sBACC,SAAS;AAAA,sBACT,UAAU,MAAM,eAAe,CAAC,SAAS,CAAC,IAAI;AAAA,oBAAA;AAAA,kBAAA;AAAA,iDAE/C/B,GAAAA,MAAA,EAAK,OAAO,EAAC,QAAQ,SAAA,GAAW,UAAA,sBAAA,CAAmB;AAAA,gBAAA,GACtD;AAAA,gBACAF,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,IAAG,SACtB,UAAA;AAAA,kBAAA9B,2BAAAA,IAACwC,GAAAA,UAAA,EAAS,UAAQ,IAAC,SAAO,IAAC;AAAA,iDAC1B/B,GAAAA,MAAA,EAAK,OAAO,EAAC,QAAQ,SAAA,GAAW,UAAA,4BAAA,CAAyB;AAAA,gBAAA,GAC5D;AAAA,+CACCsB,GAAAA,KAAA,EACC,UAAA/B,2BAAAA;AAAAA,kBAACM,GAAAA;AAAAA,kBAAA;AAAA,oBACC,MAAM0E,MAAAA;AAAAA,oBACN,UAAU;AAAA,oBACV,SAAS;AAAA,oBACT,MAAK;AAAA,oBACL,MAAK;AAAA,oBACL,SAAS;AAAA,oBACT,UAAU,CAAC,uBAAuB,sBAAsB,YAAY,EAAE;AAAA,sBACpE,CAAC,MAAM,MAAM;AAAA,oBAAA;AAAA,kBACf;AAAA,gBAAA,EACF,CACF;AAAA,cAAA,EAAA,CACF;AAAA,YAAA,GACF;AAAA,YAED,UAAU,yBACTzE,2BAAAA,KAAAsB,WAAAA,UAAA,EACE,UAAA;AAAA,cAAA7B,2BAAAA,IAAC6D,GAAAA,SAAA,EAAQ,MAAM,GAAG,UAAA,qBAAiB;AAAA,6CAClC,YAAA,CAAA,CAAW;AAAA,YAAA,GACd;AAAA,YAED,UAAU,oBACTtD,2BAAAA,KAAAsB,WAAAA,UAAA,EACE,UAAA;AAAA,cAAA7B,2BAAAA,IAAC6D,GAAAA,SAAA,EAAQ,MAAM,GAAG,UAAA,yBAAqB;AAAA,cACvC7D,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA,4DAAA,CAAyD;AAAA,YAAA,EAAA,CAC1E;AAAA,UAAA,EAAA,CAEJ;AAAA,QAAA;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN;AC9IA,MAAM,mBAAmBO,OAAAA,gCAMvB,CAAC,EAAC,eAAe,GAAA,MACV,cAAc;AAAA;AAAA,EACR;AAAA,EACX,EAAC,GAAA;AAAA,EACD;AAAA,IACE,YAAY;AAAA,EAAA;AAEhB,CACD;ACfD,SAAwB,iBAAiB,KAAyB;AAChE,QAAM,KAAK,IAAI,WAAW,IAAI,OAAO,IAC/B,OAAO,IAAI,MAAM,aACnB,IAAI,KAAK,OAAO,IAAI,KAAK,UAAU,IAAI,GAAI,IAC3C,IAAI,KAAK,IAAI,cAAc,IAAI,cAAc,KAAK,IAAA,CAAK;AAE3D,SAAO;AAAA,IACL,OAAO,IAAI,YAAY,GAAG,MAAM,GAAG,EAAE;AAAA,IACrC;AAAA,IACA,YAAY,IAAI;AAAA,IAChB,WAAW;AAAA,IACX,UAAU,IAAI,MAAM,WAAW,cAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,IACnE,cAAc,IAAI,MAAM;AAAA,IACxB,cAAc,IAAI,MAAM;AAAA,IACxB,uBAAuB,IAAI,MAAM;AAAA,IACjC,uBAAuB,IAAI,MAAM;AAAA,IACjC,aACE,IAAI,MAAM,QAAQ,OAAO,CAAC,UAAiC,MAAM,SAAS,MAAM,KAAK,CAAA;AAAA,EAAC;AAE5F;ACLA,SAAwB,gBAAgB,OAA0B;AAChE,QAAM,gBAAgBC,OAAAA,oBAChB,QAAQsD,GAAAA,SAAA,GACR,SAAS,aAET,CAAC,YAAY,iBAAiB,IAAI;AAAA,IACtCrD,MAAAA,QAAQ,OAAO,EAAC,eAAe,IAAI,MAAM,MAAM,IAAA,IAAO,CAAC,eAAe,MAAM,MAAM,GAAG,CAAC;AAAA,EAAA,GAGlF,CAAC,eAAe,gBAAgB,IAAIhB,MAAAA,SAAS,MAAM,MAAM,KAAK,GAC9D,CAAC,UAAU,WAAW,IAAIA,MAAAA,SAAS,MAAM,MAAM,QAAQ,GACvD,WAAW,aAAa,cAAc,UAEtC,cAAc,iBAAiB,EAAC,GAAG,MAAM,OAAO,UAAS,GAEzD,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAA4B,MAAM,GAEtD,EAAC,aAAa,YAAA,IAAe,eAAe,EAAC,WAAW,IAAK;AAEnE,iBAAe,eAAe;AACxB,cAAU,WACd,SAAS,WAAW,GACpB,MAAM,YAAY,MAAM,KAAK,GAC7B,SAAS,MAAM;AAAA,EACjB;AAEA,WAAS,cAAc;AACrB,QAAI,UAAU,QAEd;AAAA,UAAI,UAAU;AACZ,iBAAS,SAAS;AAClB;AAAA,MACF;AAEA,YAAM,YAAA;AAAA,IAAY;AAAA,EACpB;AAEA,WAAS,aAAa,aAAsB;AACtC,cAAU,cAEV,eAAa,MAAM,eAEvB,SAAS,MAAM;AAAA,EACjB;AAEA,iBAAe,cAAc;AAC3B,QAAI,UAAU,QACd;AAAA,eAAS,QAAQ;AAEjB,UAAI;AACF,cAAM,OAAO,MAAM,MAAM,MAAM,GAAG,EAAE,IAAI,EAAC,UAAS,EAAE,UACpD,iBAAiB,CAAC,UAAU,EAAC,GAAG,MAAM,WAAU,GAChD,MAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,aAAa,cAAc,QAAQ;AAAA,UACnC,QAAQ;AAAA,QAAA,CACT,GACD,MAAM,YAAA;AAAA,MACR,SAAS,OAAO;AACd,cAAM,KAAK;AAAA,UACT,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aAAa,OAAO,SAAU,WAAW,QAAQ;AAAA,QAAA,CAClD,GACD,YAAY,cAAc,QAAQ;AAAA,MACpC;AAEA,eAAS,MAAM;AAAA,IAAA;AAAA,EACjB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AC7DA,MAAM,aAOD,CAAC,UACJF,2BAAAA,IAACsC,aAAA,EAAU,OAAO,MAAM,OAAO,aAAa,MAAM,aAAa,SAAS,MAAM,OAC5E,UAAAtC,2BAAAA;AAAAA,EAACuC,GAAAA;AAAAA,EAAA;AAAA,IACC,IAAI,MAAM;AAAA,IACV,OAAO,MAAM;AAAA,IACb,aAAa,MAAM;AAAA,IACnB,SAAS,MAAM;AAAA,IACf,UAAU,MAAM;AAAA,EAAA;AAClB,GACF,GAGI,eAA4C,CAAC,UAAU;AAC3D,QAAM,CAAC,KAAK,MAAM,IAAIrC,MAAAA,SAAmC,SAAS,GAC5D;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE,gBAAgB,KAAK,GAEnB,WAAW,UAAU,UAGrB,CAAC,iBAAiB,kBAAkB,IAAIA,MAAAA,SAAwB,IAAI,GACpE,cAAcyG,eAAAA,QAAM,OAAuB,IAAI;AACrD,SAAAtE,MAAAA,UAAU,MAAM;AACV,KAAC,YAAY,WAAW,EAAE,2BAA2B,YAAY,YAErE,mBAAmB,YAAY,QAAQ,sBAAA,EAAwB,MAAM;AAAA,EACvE,GAAG,CAAA,CAAE,GAGH9B,2BAAAA;AAAAA,IAACH,GAAAA;AAAAA,IAAA;AAAA,MACC,SAAO;AAAA,MACP,QAAQ,YAAY;AAAA,MACpB,SAAS;AAAA,MACT,IAAG;AAAA,MACH,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,OAAO;AAAA,MACP,UAAS;AAAA,MACT,QACEJ,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,SAAS,GACb,0CAACsB,GAAAA,MAAA,EAAK,SAAQ,iBAAgB,OAAM,UAClC,UAAA;AAAA,QAAAvB,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,KAAK,GACT,UAAA;AAAA,UAAA9B,2BAAAA;AAAAA,YAACM,GAAAA;AAAAA,YAAA;AAAA,cACC,MAAM0E,MAAAA;AAAAA,cACN,UAAU;AAAA,cACV,SAAS;AAAA,cACT,MAAK;AAAA,cACL,MAAK;AAAA,cACL,MAAK;AAAA,cACL,SAAS,MAAM,SAAS,UAAU;AAAA,cAClC,UAAU,YAAY;AAAA,YAAA;AAAA,UAAA;AAAA,UAExBhF,2BAAAA;AAAAA,YAACM,GAAAA;AAAAA,YAAA;AAAA,cACC,MAAM4D,MAAAA;AAAAA,cACN,UAAU;AAAA,cACV,SAAS;AAAA,cACT,MAAK;AAAA,cACL,MAAK;AAAA,cACL,MAAK;AAAA,cACL,SAAS;AAAA,cACT,UAAU,YAAY;AAAA,cACtB,WAAW,eAAeZ,GAAAA;AAAAA,YAAA;AAAA,UAAA;AAAA,QAC5B,GACF;AAAA,QACC,YACCtD,2BAAAA;AAAAA,UAACM,GAAAA;AAAAA,UAAA;AAAA,YACC,MAAMsG,MAAAA;AAAAA,YACN,UAAU;AAAA,YACV,SAAS;AAAA,YACT,MAAK;AAAA,YACL,MAAK;AAAA,YACL,MAAK;AAAA,YACL,SAAS;AAAA,YACT,WAAW,YAAYtD,GAAAA;AAAAA,YACvB,UAAU,YAAY;AAAA,UAAA;AAAA,QAAA;AAAA,MACxB,EAAA,CAEJ,EAAA,CACF;AAAA,MAID,UAAA;AAAA,QAAA,UAAU,cACTtD,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO,MAAM;AAAA,YACb,cAAc,MAAM,SAAS,MAAM;AAAA,YACnC;AAAA,YACA;AAAA,YACA,mBAAmB,MAAM;AACvB,oBAAM,YAAA;AAAA,YACR;AAAA,UAAA;AAAA,QAAA;AAAA,QAKH,UAAU,aACTA,2BAAAA;AAAAA,UAACI,GAAAA;AAAAA,UAAA;AAAA,YACC,SAAO;AAAA,YACP,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,IAAG;AAAA,YACH,SAAS,MAAM,aAAa,EAAK;AAAA,YACjC,gBAAgB,MAAM,aAAa,EAAK;AAAA,YACxC,OAAO;AAAA,YACP,UAAS;AAAA,YACT,QACEJ,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,SAAS,GACb,0CAACsB,GAAAA,MAAA,EAAK,SAAQ,iBAAgB,OAAM,UAClC,UAAA;AAAA,cAAA9B,2BAAAA;AAAAA,gBAACM,GAAAA;AAAAA,gBAAA;AAAA,kBACC,MAAMiD,MAAAA;AAAAA,kBACN,UAAU;AAAA,kBACV,SAAS;AAAA,kBACT,MAAK;AAAA,kBACL,MAAK;AAAA,kBACL,SAAS,MAAM,aAAa,EAAI;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEjC,YACCvD,2BAAAA;AAAAA,gBAACM,GAAAA;AAAAA,gBAAA;AAAA,kBACC,MAAMuG,MAAAA;AAAAA,kBACN,UAAU;AAAA,kBACV,SAAS;AAAA,kBACT,MAAK;AAAA,kBACL,MAAK;AAAA,kBACL,MAAK;AAAA,kBACL,SAAS,MAAM,aAAa,EAAK;AAAA,gBAAA;AAAA,cAAA;AAAA,YACnC,EAAA,CAEJ,EAAA,CACF;AAAA,YAGF,UAAA7G,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,SAAS,GACb,UAAAD,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,EAAC,WAAW,SAAA,GAAW,OAAO,GAC1C,UAAA;AAAA,cAAAL,2BAAAA,IAAC6D,GAAAA,SAAA,EAAQ,MAAM,GAAG,UAAA,gCAA4B;AAAA,cAC9C7D,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,UAAA,yCAAA,CAAsC;AAAA,YAAA,EAAA,CACvD,EAAA,CACF;AAAA,UAAA;AAAA,QAAA;AAAA,QAGJT,2BAAAA;AAAAA,UAACQ,GAAAA;AAAAA,UAAA;AAAA,YACC,SAAS;AAAA,YACT,QAAO;AAAA,YACP,OAAO;AAAA,cACL,eAAe;AAAA,YAAA;AAAA,YAGjB,UAAAD,2BAAAA;AAAAA,cAACuB,GAAAA;AAAAA,cAAA;AAAA,gBACC,QAAO;AAAA,gBACP,KAAK;AAAA,gBACL,WAAW,CAAC,UAAU,UAAU,KAAK;AAAA,gBACrC,OAAM;AAAA,gBACN,KAAK;AAAA,gBACL,OACE,OAAO,mBAAoB,WACvB;AAAA,kBACE,WAAW;AAAA,gBAAA,IAEb;AAAA,gBAGN,UAAA;AAAA,kBAAAvB,gCAACF,GAAAA,SAAM,OAAO,GAAG,MAAM,GAAG,QAAO,UAC/B,UAAA;AAAA,oBAAAL,2BAAAA,IAAC,aAAA,EAAY,OAAO,MAAM,OAAO,UAAU,MAAM,MAAM,YAAY,GAAA,CAAO;AAAA,oBACzE,QAAQ,aACPA,2BAAAA;AAAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,OAAO,MAAM;AAAA,wBACb,UAAQ;AAAA,wBACR,gBAAc;AAAA,wBACd,QACE,aAAa,eACb,MAAM,MAAM,MAAM,QAAQ;AAAA,0BACxB,CAAC,UAAiC,MAAM,SAAS;AAAA,wBAAA,KAEnD,CAAA;AAAA,sBAAC;AAAA,oBAAA;AAAA,kBAEL,GAEJ;AAAA,kDACCK,GAAAA,OAAA,EAAM,OAAO,GAAG,MAAM,GAAG,QAAO,UAC/B,UAAA;AAAA,oBAAAE,2BAAAA,KAACuG,GAAAA,SAAA,EAAQ,OAAO,GACd,UAAA;AAAA,sBAAA9G,2BAAAA;AAAAA,wBAAC+G,GAAAA;AAAAA,wBAAA;AAAA,0BACC,iBAAc;AAAA,0BACd,MAAMhC,MAAAA;AAAAA,0BACN,IAAG;AAAA,0BACH,OAAM;AAAA,0BACN,SAAS,MAAM,OAAO,SAAS;AAAA,0BAC/B,UAAU,QAAQ;AAAA,wBAAA;AAAA,sBAAA;AAAA,sBAEpB/E,2BAAAA;AAAAA,wBAAC+G,GAAAA;AAAAA,wBAAA;AAAA,0BACC,iBAAc;AAAA,0BACd,MAAMC,MAAAA;AAAAA,0BACN,IAAG;AAAA,0BACH,OAAO,WAAW,aAAa,IAAI,WAAW,MAAM,MAAM,EAAE;AAAA,0BAC5D,SAAS,MAAM,OAAO,YAAY;AAAA,0BAClC,UAAU,QAAQ;AAAA,wBAAA;AAAA,sBAAA;AAAA,oBACpB,GACF;AAAA,oBACAhH,2BAAAA;AAAAA,sBAACiH,GAAAA;AAAAA,sBAAA;AAAA,wBACC,mBAAgB;AAAA,wBAChB,IAAG;AAAA,wBACH,QAAQ,QAAQ;AAAA,wBAChB,OAAO,EAAC,WAAW,aAAA;AAAA,wBAEnB,UAAA1G,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,0BAAAL,2BAAAA;AAAAA,4BAAC;AAAA,4BAAA;AAAA,8BACC,OAAM;AAAA,8BACN,aAAY;AAAA,8BACZ,OAAO,YAAY;AAAA,8BACnB,SAAS,CAAC,MAAM,YAAY,EAAE,cAAc,KAAK;AAAA,8BACjD,UAAU,UAAU;AAAA,4BAAA;AAAA,0BAAA;AAAA,0BAEtBO,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACX,UAAA;AAAA,4BAAA,aAAa,YACZL,2BAAAA;AAAAA,8BAAC;AAAA,8BAAA;AAAA,gCACC,MAAM,aAAa,YAAY,QAAQ;AAAA,gCACvC,MAAMkH,MAAAA;AAAAA,gCACN,MAAM;AAAA,8BAAA;AAAA,4BAAA;AAAA,4BAGT,aAAa,yBACZlH,2BAAAA;AAAAA,8BAAC;AAAA,8BAAA;AAAA,gCACC,MAAM,mBAAmB,YAAY,qBAAqB;AAAA,gCAC1D,MAAM;AAAA,gCACN,MAAM;AAAA,8BAAA;AAAA,4BAAA;AAAA,4BAGT,aAAa,yBACZA,2BAAAA;AAAAA,8BAAC;AAAA,8BAAA;AAAA,gCACC,MAAM,eAAe,YAAY,qBAAqB;AAAA,gCACtD,MAAM;AAAA,gCACN,MAAM;AAAA,8BAAA;AAAA,4BAAA;AAAA,4BAGT,aAAa,gBACZA,2BAAAA;AAAAA,8BAAC;AAAA,8BAAA;AAAA,gCACC,MAAM,iBAAiB,YAAY,YAAY;AAAA,gCAC/C,MAAMmH,MAAAA;AAAAA,gCACN,MAAM;AAAA,8BAAA;AAAA,4BAAA;AAAA,4BAGVnH,2BAAAA;AAAAA,8BAAC;AAAA,8BAAA;AAAA,gCACC,MAAM,gBAAgB,YAAY,UAAU,mBAAmB,MAAM;AAAA,kCACnE,MAAM;AAAA,kCACN,OAAO;AAAA,kCACP,KAAK;AAAA,kCACL,MAAM;AAAA,kCACN,QAAQ;AAAA,kCACR,QAAQ;AAAA,gCAAA,CACT,CAAC;AAAA,gCACF,MAAMoH,MAAAA;AAAAA,gCACN,MAAM;AAAA,8BAAA;AAAA,4BAAA;AAAA,4BAERpH,+BAAC,YAAS,MAAM;AAAA,EAAa,YAAY,EAAE,IAAI,MAAMqH,MAAAA,SAAS,MAAM,GAAG;AAAA,4BACvErH,2BAAAA,IAAC,aAAA,EAAY,cAAc,YAAY,aAAA,CAAc;AAAA,0BAAA,EAAA,CACvD;AAAA,wBAAA,EAAA,CACF;AAAA,sBAAA;AAAA,oBAAA;AAAA,oBAEFA,2BAAAA;AAAAA,sBAACiH,GAAAA;AAAAA,sBAAA;AAAA,wBACC,mBAAgB;AAAA,wBAChB,IAAG;AAAA,wBACH,QAAQ,QAAQ;AAAA,wBAEhB,UAAAjH,2BAAAA,IAAC,iBAAA,EAAgB,YAAwB,UAAU,CAAC,kBAAA,CAAmB;AAAA,sBAAA;AAAA,oBAAA;AAAA,kBACzE,EAAA,CACF;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UACF;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAAA;AAGN,GAEM,cAAc,CAAC,EAAC,aAAA,MAChB,eACK,aAAa,IAAI,CAAC,UACvBA,2BAAAA;AAAAA,EAAC;AAAA,EAAA;AAAA,IAEC,MAAM,gBAAgB,aAAa,MAAM,MAAM,CAAC,MAAM,MAAM,EAAE;AAAA,IAC9D,MAAMqH,MAAAA;AAAAA,IACN,MAAM;AAAA,EAAA;AAAA,EAHD,MAAM;AAIb,CACD,IAEIrH,2BAAAA,IAAC,UAAA,EAAS,MAAM,kBAAkB,MAAMqH,MAAAA,SAAS,MAAM,EAAA,CAAG,GAG7D,eAAe,CAAC,WAA2B;AAC/C,UAAQ,QAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EAAA;AAEb,GC7VM,gBAAgB,CAAC,UAAuC;AAC5D,MAAI,CAAC,MAAM;AACT,WAAO;AAGT,QAAM,cAAc,iBAAiB,MAAM,KAAK;AAChD,SACE9G,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACX,UAAA;AAAA,IAAA,YAAY,SACXL,2BAAAA;AAAAA,MAACS,GAAAA;AAAAA,MAAA;AAAA,QACC,MAAM;AAAA,QACN,QAAO;AAAA,QACP,OAAO;AAAA,UACL,UAAU;AAAA,QAAA;AAAA,QAGX,UAAA,YAAY;AAAA,MAAA;AAAA,IAAA;AAAA,IAGjBF,2BAAAA,KAACmC,GAAAA,QAAA,EAAO,OAAO,GACZ,UAAA;AAAA,MAAA,aAAa,YACZ1C,2BAAAA,IAAC,UAAA,EAAS,MAAM,YAAY,UAAU,MAAMkH,MAAAA,WAAW,MAAM,GAAG,OAAK,GAAA,CAAC;AAAA,MAExElH,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAM,YAAY,UAAU,YAAA,EAAc,MAAM,GAAG,EAAE,CAAC;AAAA,UACtD,MAAMoH,MAAAA;AAAAA,UACN,MAAM;AAAA,UACN,OAAK;AAAA,QAAA;AAAA,MAAA;AAAA,MAEN,YAAY,SAAS,YAAY,GAAG,MAAM,GAAG,EAAE,KAC9CpH,2BAAAA,IAAC,UAAA,EAAS,MAAM,YAAY,GAAG,MAAM,GAAG,EAAE,GAAG,MAAMqH,MAAAA,SAAS,MAAM,GAAG,OAAK,GAAA,CAAC;AAAA,IAAA,EAAA,CAE/E;AAAA,EAAA,GACF;AAEJ,GC3BM,aAAazF,iBAAAA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6D1B,SAAwB,eAAe;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,CAAC,aAAa,cAAc,IAAI1B,MAAAA,SAAsB,EAAK,GAC3D,SAASyG,eAAAA,QAAM,YAAY,MAAM,WAAW,KAAK,GAAG,CAAC,UAAU,KAAK,CAAC,GACrE,OAAOA,eAAAA,QAAM,YAAY,MAAM,SAAS,KAAK,GAAG,CAAC,QAAQ,KAAK,CAAC,GAC/D,EAAC,gBAAA,IAAmB,6BAAA;AAE1B,MAAI,CAAC;AACH,WAAO;AAGT,QAAM,iBAAiB,kBAAkB,KAAK,GACxC,cAAc,MAAM;AACpB,oBAAgB,WAAW,SAAS,CAAC,kBACvC,eAAe,iBAAiB,IAEhC,eAAe,cAAc;AAAA,EAEjC;AACA,SACEpG,2BAAAA;AAAAA,IAACC,GAAAA;AAAAA,IAAA;AAAA,MACC,QAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO;AAAA,QACL,UAAU;AAAA,MAAA;AAAA,MAGX,UAAA;AAAA,QAAA,gBAAgB,WAAW,YAC1BR,2BAAAA;AAAAA,UAAC0F,GAAAA;AAAAA,UAAA;AAAA,YACC,SAAO;AAAA,YACP,SACE1F,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,SAAS,GAAG,QAAQ,GACxB,UAAAR,2BAAAA,IAAC,UAAA,EAAS,MAAMsH,MAAAA,UAAU,MAAK,0BAAyB,MAAM,GAAG,GACnE;AAAA,YAEF,WAAU;AAAA,YACV,oBAAoB,CAAC,OAAO,QAAQ;AAAA,YACpC,QAAM;AAAA,YAEN,UAAAtH,2BAAAA;AAAAA,cAACQ,GAAAA;AAAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO;AAAA,kBACL,cAAc;AAAA,kBACd,UAAU;AAAA,kBACV,MAAM;AAAA,kBACN,KAAK;AAAA,kBACL,QAAQ;AAAA,gBAAA;AAAA,gBAEV,SAAS;AAAA,gBACT,QAAM;AAAA,gBAEN,UAAAR,2BAAAA,IAACS,WAAK,OAAK,IAAC,MAAM,GAChB,UAAAT,2BAAAA,IAACsH,MAAAA,YAAS,EAAA,CACZ;AAAA,cAAA;AAAA,YAAA;AAAA,UACF;AAAA,QAAA;AAAA,QAGH,gBAAgB,WAAW,SAC1BtH,2BAAAA;AAAAA,UAAC0F,GAAAA;AAAAA,UAAA;AAAA,YACC,SAAO;AAAA,YACP,SACE1F,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,SAAS,GAAG,QAAQ,GACxB,UAAAR,2BAAAA,IAAC,UAAA,EAAS,MAAMsH,MAAAA,UAAU,MAAK,uBAAsB,MAAM,GAAG,GAChE;AAAA,YAEF,WAAU;AAAA,YACV,oBAAoB,CAAC,OAAO,QAAQ;AAAA,YACpC,QAAM;AAAA,YAEN,UAAAtH,2BAAAA;AAAAA,cAACQ,GAAAA;AAAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO;AAAA,kBACL,cAAc;AAAA,kBACd,UAAU;AAAA,kBACV,MAAM;AAAA,kBACN,KAAK;AAAA,kBACL,QAAQ;AAAA,gBAAA;AAAA,gBAEV,SAAS;AAAA,gBACT,QAAM;AAAA,gBAEN,UAAAR,2BAAAA,IAACS,GAAAA,MAAA,EAAK,OAAK,IAAC,MAAM,GAAG,QAAO,YAAW,OAAO,EAAC,OAAO,yBAAA,GAA2B,UAAA,MAAA,CAEjF;AAAA,cAAA;AAAA,YAAA;AAAA,UACF;AAAA,QAAA;AAAA,QAGJF,2BAAAA;AAAAA,UAACF,GAAAA;AAAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,QAAO;AAAA,YACP,OAAO;AAAA,cACL,kBAAkB;AAAA,YAAA;AAAA,YAGnB,UAAA;AAAA,cAAA,gBAAgB,qBACfL,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,SAAS,MAAM;AACb,mCAAe,cAAc;AAAA,kBAC/B;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGH,gBAAgB,iBACfA,2BAAAA,IAAC,aAAA,EAAY,OAAc,UAAQ,IAAC,kBAAkB,uBAAA,CAAwB,IAE9EO,gCAAC,YAAA,EAAW,SAAS,aACnB,UAAA;AAAA,gBAAAP,+BAAC,OAAA,EAAI,aAAS,IACZ,UAAAA,+BAACuH,MAAAA,YAAS,GACZ;AAAA,gBACC,aAAa,KAAK,IACjBvH,2BAAAA;AAAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,OAAO;AAAA,sBACL,aAAa;AAAA,sBACb,SAAS;AAAA,sBACT,YAAY;AAAA,sBACZ,gBAAgB;AAAA,oBAAA;AAAA,oBAGlB,UAAAA,2BAAAA,IAAC,WAAA,EAAU,OAAM,OAAM,QAAO,MAAA,CAAM;AAAA,kBAAA;AAAA,gBAAA,IAGtCA,2BAAAA,IAAC,gBAAA,EAAe,MAAA,CAAc;AAAA,cAAA,GAElC;AAAA,cAEFA,+BAAC,iBAAc,OAAc;AAAA,cAC7BO,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,OAAO;AAAA,oBACP,YAAY;AAAA,oBACZ,gBAAgB;AAAA,oBAChB,KAAK;AAAA,kBAAA;AAAA,kBAGN,UAAA;AAAA,oBAAA,YACCP,2BAAAA;AAAAA,sBAACM,GAAAA;AAAAA,sBAAA;AAAA,wBACC,MAAMsG,MAAAA;AAAAA,wBACN,UAAU;AAAA,wBACV,SAAS;AAAA,wBACT,MAAK;AAAA,wBACL,MAAK;AAAA,wBACL,OAAO,EAAC,MAAM,EAAA;AAAA,wBACd,MAAK;AAAA,wBACL,SAAS;AAAA,sBAAA;AAAA,oBAAA;AAAA,oBAGb5G,2BAAAA;AAAAA,sBAACM,GAAAA;AAAAA,sBAAA;AAAA,wBACC,MAAMyE,MAAAA;AAAAA,wBACN,UAAU;AAAA,wBACV,SAAS;AAAA,wBACT,MAAK;AAAA,wBACL,MAAK;AAAA,wBACL,OAAO,EAAC,MAAM,EAAA;AAAA,wBACd,SAAS;AAAA,sBAAA;AAAA,oBAAA;AAAA,kBACX;AAAA,gBAAA;AAAA,cAAA;AAAA,YACF;AAAA,UAAA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAAA;AAGN;AC9NA,SAAwB,cAAc,EAAC,UAAU,UAA6B;AAC5E,QAAM,EAAC,QAAQ,WAAW,aAAa,gBAAgB,SAAS,KAAA,IAAQ,UAAA,GAClE,CAAC,MAAM,OAAO,IAAI7E,MAAAA,SAAiB,CAAC,GACpC,YAAY,IACZ,YAAY,KAAK,MAAM,OAAO,SAAS,SAAS,IAAI,GACpD,CAAC,aAAa,cAAc,IAAIA,MAAAA,SAA4C,IAAI,GAChF,mBAAmBgB,MAAAA;AAAAA,IACvB,MAAM,OAAO,KAAK,CAAC0B,OAAMA,GAAE,QAAQ,aAAa,GAAG,KAAK;AAAA,IACxD,CAAC,aAAa,MAAM;AAAA,EAAA,GAGhB,YAAY,OAAO,WACnB,UAAU,YAAY;AAG5B,SACErC,gCAAC,qCAAkC,QACjC,UAAA;AAAA,IAAAA,2BAAAA,KAACF,GAAAA,OAAA,EAAM,SAAS,GAAG,OAAO,GAAG,OAAO,EAAC,WAAW,OAAA,GAC9C,UAAA;AAAA,MAAAE,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,SAAQ,iBAAgB,OAAM,UAClC,UAAA;AAAA,QAAAvB,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,UAAA9B,2BAAAA;AAAAA,YAACuC,GAAAA;AAAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP,MAAMyE,MAAAA;AAAAA,cACN,SAAS,CAAC,MACR,eAAe,EAAE,cAAc,KAAK;AAAA,cAEtC,aAAY;AAAA,YAAA;AAAA,UAAA;AAAA,UAEdhH,2BAAAA,IAAC,mBAAA,EAAkB,SAAkB,KAAA,CAAY;AAAA,UACjDA,2BAAAA,IAAC,cAAA,EAAa,MAAY,SAAkB,OAAO,UAAA,CAAW;AAAA,QAAA,GAChE;AAAA,SAhBU,WAAW,UAAU,WAiBhB,UACbO,gCAACmC,GAAAA,QAAA,EAAO,OAAO,GACb,UAAA;AAAA,UAAA1C,2BAAAA,IAAC,qBAAA,EAAoB;AAAA,yCACpB,gBAAA,EAAe;AAAA,yCACf,cAAA,CAAA,CAAa;AAAA,QAAA,EAAA,CAChB;AAAA,MAAA,GAEJ;AAAA,MACAO,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACX,UAAA;AAAA,QAAA,QAAQ,SAAS,KAChBE,2BAAAA,KAACwD,GAAAA,OAAA,EAAM,OAAK,IACT,UAAA;AAAA,UAAA,OAAO;AAAA,UAAO;AAAA,UAAO,OAAO,SAAS,IAAI,MAAM;AAAA,UAAM;AAAA,UACrD,cAAc,aAAa,WAAW,MAAM;AAAA,QAAA,GAC/C;AAAA,QAEF/D,2BAAAA;AAAAA,UAACwH,GAAAA;AAAAA,UAAA;AAAA,YACC,KAAK;AAAA,YACL,OAAO;AAAA,cACL,qBAAqB;AAAA,YAAA;AAAA,YAGtB,iBAAO,MAAM,WAAW,OAAO,EAAE,IAAI,CAAC,UACrCxH,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBAEC;AAAA,gBACA,QAAQ;AAAA,gBACR;AAAA,cAAA;AAAA,cAHK,MAAM;AAAA,YAAA,CAKd;AAAA,UAAA;AAAA,QAAA;AAAA,MACH,GACF;AAAA,MACC,4CAAc,YAAA,EAAW;AAAA,MAEzB,CAAC,aAAa,OAAO,WAAW,KAC/BA,+BAACQ,GAAAA,MAAA,EAAK,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,QAAM,IAAC,QAAQ,GAAG,MAAK,eACjE,UAAAR,2BAAAA,IAACS,SAAA,EAAK,OAAM,UAAS,OAAK,IAAC,MAAM,GAC9B,UAAA,cAAc,wBAAwB,WAAW,MAAM,6BAC1D,EAAA,CACF;AAAA,IAAA,GAEJ;AAAA,IACC,mDACE,cAAA,EAAa,aAAa,MAAM,eAAe,IAAI,GAAG,OAAO,iBAAA,CAAkB;AAAA,EAAA,GAEpF;AAEJ;AC7FA,MAAM,aAAqC,CAAC,WACnCT,2BAAAA,IAAC,iBAAc,OAAA,CAAgB,GAG3B,sBAAsB;AAAA,EACjC,MAAM;AAAA,EACN,OAAO;AACT;AAEA,SAAwB,iBAAiB,QAA4B;AACnE,QAAM,aAAa,OAAO,OAAO,QAAS,WAAW,OAAO,OAAO;AACnE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM,WAAW,QAAQ,oBAAoB;AAAA,IAC7C,OAAO,WAAW,SAAS,oBAAoB;AAAA,IAC/C,WAAW,CAAC,UAAeA,2BAAAA,IAAC,cAAY,GAAG,QAAS,GAAG,MAAA,CAAO;AAAA,EAAA;AAElE;ACnBO,MAAM,mBAAmB,CAAC,WAAyB;AACxD,QAAM,OAAOyH,OAAAA,eAAA;AAMb,SAAO,EAAC,iBAHN,CAAC,QAAQ,8BAA8B,UACvC,MAAM,OAAO,KAAK,CAAC,SAAS,OAAO,6BAA6B,SAAS,KAAK,IAAI,CAAC,EAAA;AAGvF,GCPM,OAAO,CAAC,WAAW,QAAQ,cAAc,UAAU,aAAa,UAAU,GACnE,yBAAyB,CAAC,UACrClG,OAAAA;AAAAA,EACEmG,OAAAA,YAAY,KAAK,IAAI,MAAM,OAAQ;AAAA,EACnC;AACF,GCFW,gBAAgB,CAAC,UAA+B;AAC3D,QAAM,SAAS,aACT,YAAYC,OAAAA,aAAA,GACZ,UAAUC,kBAAA,GACV,8BAA8B1G,MAAAA,QAAQ,MAAM;AAIhD,QACE,OAAO,MAAM,mBAAmB,UAChC,OAAO,MAAM,mBAAmB,WAAW;AAE3C,aAAO;AAGT,UAAM,QAAQ,OAAO,MAAM,mBAAmB;AAC9C,WAAI,CAAC,SAAS,MAAM,WAAW,IACtB,KAEF,MAAM,KAAK,CAAC,SAAS,KAAK,WAAW,WAAW;AAAA,EACzD,GAAG,CAAC,OAAO,MAAM,mBAAmB,QAAQ,OAAO,MAAM,mBAAmB,KAAK,CAAC,GAE5E,cAAcA,MAAAA;AAAAA,IAClB,MAAM,CAAC,CAAC,OAAO,YAAY,OAAO,WAAW,eAAe;AAAA,IAC5D,CAAC,OAAO,SAAS,OAAO,QAAQ,2BAA2B;AAAA,EAAA;AAE7D,SAAO2G,gBAAAA;AAAAA,IACL,cAAc,IAAI,SAAS,sBAAsB,OAAO,SAAS,OAAO,OAAO,KAAK;AAAA,IACpF,YAAY;AACV,YAAM,EAAC,KAAA,IAAQ,MAAM,OAAO,QAA0B;AAAA,QACpD,KAAK,sBAAsB,OAAO,SAAS,MAAO,OAAO;AAAA,QACzD,iBAAiB;AAAA,QACjB,QAAQ;AAAA,MAAA,CACT;AACD,aAAO,MAAM,MAAO,GAAI,EAAE,IAAI,EAAC,QAAQ,KAAK,QAAQ,KAAA,CAAK,EAAE,OAAO,EAAC,iBAAiB,IAAM;AAAA,IAC5F;AAAA,IACA,EAAC,iBAAiB,KAAM,mBAAmB,IAAM,kBAAkB,IAAA;AAAA,EAAI;AAE3E;AC9CsF,IAAI,KAAE,SAAS,GAAE;AAAC,MAAI,GAAE;AAAE,WAAS,EAAEC,IAAE;AAAC,QAAIC;AAAE,YAAOA,KAAE,EAAE,KAAK,MAAKD,EAAC,KAAG,MAAM,QAAM,EAAC,UAAS,IAAG,OAAM,KAAI,GAAEC;AAAA,EAAC;AAAC,MAAE,IAAG,IAAE,GAAG,YAAU,OAAO,OAAO,EAAE,SAAS,GAAE,EAAE,UAAU,cAAY,GAAE,EAAE,YAAU,GAAE,EAAE,2BAAyB,SAASC,IAAE;AAAC,WAAM,EAAC,UAAS,IAAG,OAAMA,GAAC;AAAA,EAAC;AAAE,MAAI,IAAE,EAAE;AAAU,SAAO,EAAE,oBAAkB,SAASA,IAAEF,IAAE;AAAC,WAAO,KAAK,MAAM,WAAWE,IAAEF,EAAC;AAAA,EAAC,GAAE,EAAE,SAAO,WAAU;AAAC,QAAIE,KAAE,KAAK,OAAMF,KAAE,KAAK,OAAMC,KAAED,GAAE,QAAOG,KAAEH,GAAE,UAASI,KAAEJ,GAAE;AAAY,WAAOE,GAAE,WAASE,KAAEA,GAAE,EAAC,OAAMF,GAAE,MAAK,CAAC,IAAE,OAAKD,KAAEA,GAAC,IAAGE,MAAG;AAAA,EAAI,GAAE;AAAC,GAAEH,MAAAA,aAAC,GAAE,IAAE,SAAS,GAAE,GAAE;AAAC,UAAO,EAAE,MAAI;AAAA,IAAE,KAAI;AAAQ,aAAM,EAAC,UAAS,IAAG,OAAM,EAAE,MAAK;AAAA,IAAE,KAAI;AAAQ,aAAM,EAAC,UAAS,IAAG,OAAM,KAAI;AAAA,IAAE;AAAQ,aAAO;AAAA,EAAC;AAAC;AAAE,SAAS,EAAE,GAAE;AAAC,MAAIlF,KAAEmF,MAAAA,WAAE,GAAE,EAAC,UAAS,IAAG,OAAM,KAAI,CAAC,GAAE,IAAEnF,GAAE,CAAC,GAAE,IAAEA,GAAE,CAAC,GAAE,IAAEqF,MAAAA,OAAE,IAAI;AAAE,WAAS,IAAG;AAAC,WAAO,IAAE,SAAS,GAAEF,IAAE;AAAC,QAAE,EAAC,MAAK,SAAQ,OAAM,EAAC,CAAC,GAAE,KAAG,EAAE,cAAY,EAAE,WAAW,GAAEA,EAAC;AAAA,IAAC,GAAE,SAASD,IAAE;AAAC,aAAOE,eAAAA,QAAE,cAAc,GAAE,EAAC,YAAW,GAAE,UAASF,GAAE,UAAS,QAAOA,GAAE,QAAO,aAAYA,GAAE,YAAW,CAAC;AAAA,IAAC;AAAE,QAAI;AAAA,EAAC;AAAC,MAAI,GAAE,IAAEI,MAAAA,YAAE,WAAU;AAAC,MAAE,UAAQ,EAAC,GAAG,EAAE,EAAC,MAAK,QAAO,CAAC;AAAA,EAAC,GAAE,CAAA,CAAE;AAAE,SAAM,EAAC,gBAAe,IAAE,EAAE,SAAe,MAAP,OAAS,KAAG,EAAE,UAAQ,EAAC,GAAG,EAAE,WAAU,UAAS,EAAE,UAAS,OAAM,EAAE,OAAM,OAAM,EAAC;AAAC;ACarrC,SAAS,kBAAkB,OAAc;AACvC,QAAM,EAAC,UAAU,eAAc,OACzB,EAAC,MAAM,cAAa3D,YAAA,GACpB,WAAWtC,aAAO,IAAI,GACtB,EAAC,eAAe,UAAU,OAAO,MAAA,IAASkG,EAAiB;AAAA,IAC/D,YAAY,CAAC,KAAK,cAAc;AAC9B,cAAQ,MAAM,IAAI,SAAA,CAAU,GAC5B,QAAQ,eAAe,eAAe,GACtC,QAAQ,MAAM,GAAG,GACjB,QAAQ,SAAA,GACJ,IAAI,UACN,QAAQ,eAAe,aAAa,GACpC,QAAQ,IAAI,IAAI,KAAK,GACrB,QAAQ,SAAA,IAEN,WAAW,mBACb,QAAQ,eAAe,0BAA0B,GACjD,QAAQ,IAAI,UAAU,cAAc,GACpC,QAAQ,aAEV,QAAQ,SAAA,GACR,UAAU;AAAA,QACR,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,4CACGrG,SAAA,EAAK,OAAM,UACV,UAAAvB,2BAAAA,KAACmC,GAAAA,QAAA,EAAO,OAAO,GAAG,UAAA;AAAA,UAAA;AAAA,UAEhB1C,2BAAAA;AAAAA,YAACM,GAAAA;AAAAA,YAAA;AAAA,cACC,SAAS;AAAA,cACT,UAAU;AAAA,cACV,OAAO,EAAC,WAAW,kBAAA;AAAA,cACnB,MAAK;AAAA,cACL,MAAM,WAAW;AAAA,cACjB,SAAS,MAAM;AACT,yBAAS,WACX8H,gCAAe,SAAS,SAAS;AAAA,kBAC/B,UAAU;AAAA,kBACV,YAAY;AAAA,kBACZ,OAAO;AAAA,gBAAA,CACR;AAAA,cAEL;AAAA,YAAA;AAAA,UAAA;AAAA,QACF,EAAA,CACF,EAAA,CACF;AAAA,MAAA,CAEH;AAAA,IACH;AAAA,EAAA,CACD,GACK,cAAc/G,MAAAA,YAAY,MAAM;AAEpCa,iBAAAA,MAAM,CAAC,IAAI,CAAC,GAEZ,MAAA;AAAA,EACF,GAAG,CAAC,KAAK,CAAC;AAEV,SAAI,WAEAlC,2BAAAA,IAACQ,SAAA,EAAK,KAAK,UAAU,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,QAAO,QAAO,QAAQ,GAAG,UAAS,QAC7E,UAAAR,2BAAAA,IAAC8B,GAAAA,MAAA,EAAK,SAAQ,cAAa,OAAM,UAAS,QAAO,QAC/C,UAAAvB,gCAACiH,GAAAA,MAAA,EAAK,SAAS,GAAG,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,GAChC,UAAA;AAAA,IAAAjH,2BAAAA,KAACsD,GAAAA,SAAA,EAAQ,IAAG,MAAK,UAAA;AAAA,MAAA;AAAA,MACX7D,2BAAAA,IAAC,UAAM,UAAA,KAAA,CAAK;AAAA,MAAO;AAAA,IAAA,GACzB;AAAA,IACC,OAAO,WACNA,2BAAAA,IAACQ,SAAA,EAAK,SAAS,GAAG,MAAK,YAAW,QAAQ,GAAG,QAAQ,GACnD,UAAAR,2BAAAA,IAACS,GAAAA,MAAA,EAAM,UAAA,MAAM,SAAQ,GACvB;AAAA,IAEFT,2BAAAA,IAAC0C,GAAAA,UACC,UAAA1C,+BAACM,GAAAA,QAAA,EAAO,SAAS,aAAa,MAAK,SAAQ,EAAA,CAC7C;AAAA,EAAA,EAAA,CACF,EAAA,CACF,GACF,IAIGN,2BAAAA,IAAC,iBAAe,UAAS;AAClC;AAEA,IAAA,sBAAegC,MAAAA,KAAK,iBAAiB;AC7F9B,MAAM,gBAAgB,MAEzBhC,+BAAC,OAAA,EAAI,OAAO,EAAC,SAAS,KACpB,UAAAA,2BAAAA;AAAAA,EAACQ,GAAAA;AAAAA,EAAA;AAAA,IACC,QAAQ;AAAA,IACR,QAAO;AAAA,IACP,OAAO,EAAC,aAAa,QAAQ,OAAO,QAAQ,cAAc,MAAA;AAAA,IAE1D,UAAAD,2BAAAA,KAACuB,GAAAA,QAAK,OAAM,UAAS,WAAU,UAAS,QAAO,QAAO,SAAQ,UAC5D,UAAA;AAAA,MAAA9B,2BAAAA,IAACsD,GAAAA,SAAA,EAAQ,OAAK,GAAA,CAAC;AAAA,MACftD,2BAAAA,IAAC+B,GAAAA,KAAA,EAAI,WAAW,GACd,UAAA/B,2BAAAA,IAACS,SAAA,EAAK,OAAM,UAAS,OAAK,IAAC,MAAM,GAAG,2BAEpC,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA,EAAA;AACF,GACF;ACLJ,SAAwB,QAAQ,OAAqB;AACnD,QAAM,EAAC,eAAA,IAAkB,OACnB,aAAaY,MAAAA,YAAY,MAAM,eAAe,SAAS,GAAG,CAAC,cAAc,CAAC,GAC1E,EAAC,oBAAmB,iBAAiB,MAAM,MAAM;AAEvD,+DAEI,UAAArB,2BAAAA,IAAC,OAAA,EAAI,OAAO,EAAC,SAAS,KACpB,UAAAA,2BAAAA;AAAAA,IAACQ,GAAAA;AAAAA,IAAA;AAAA,MACC,SAAQ;AAAA,MACR,QAAO;AAAA,MACP,OAAO;AAAA,QACL,aAAa;AAAA,QACb,OAAO;AAAA,QACP,WAAW;AAAA,MAAA;AAAA,MAEb,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,MACrB,QAAQ;AAAA,MACR,MAAK;AAAA,MAEL,yCAACsB,GAAAA,MAAA,EAAK,SAAQ,cAAa,OAAM,UAC/B,UAAAvB,2BAAAA,KAACiH,GAAAA,MAAA,EAAK,SAAS,GAAG,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,GAChC,UAAA;AAAA,QAAAxH,2BAAAA,IAAC0C,GAAAA,QAAA,EAAO,UAAU,GAChB,UAAA1C,2BAAAA,IAAC,OAAA,EAAI,OAAO,EAAC,QAAQ,OAAA,GACnB,UAAAA,2BAAAA,IAAC,SAAA,CAAA,CAAQ,GACX,GACF;AAAA,QACAA,2BAAAA,IAAC0C,GAAAA,QAAA,EAAO,UAAU,GAChB,yCAACmB,GAAAA,SAAA,EAAQ,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,kEAE7B,GACF;AAAA,QACA7D,+BAAC0C,GAAAA,QAAA,EAAO,UAAU,GACf,4BACC1C,2BAAAA,IAACM,WAAA,EAAO,MAAK,SAAQ,MAAM+H,MAAAA,UAAU,MAAK,iBAAgB,SAAS,YAAY,IAE/ErI,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAK,YACnD,UAAAR,+BAACS,GAAAA,MAAA,EAAK,UAAA,uFAGN,GACF,EAAA,CAEJ;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,IAAA;AAAA,EAAA,GAEJ,EAAA,CACF;AAEJ;AC7DO,SAAS,wBAAwB0C,OAAcmF,YAAmB,QAAc;AACrF,SAAO,IAAIC,KAAAA,WAIT,CAAC,eAAe;AAChB,UAAMC,YAAUC,QAAAA,QAAQ,aAAa;AAAA,MACnC,UAAUH;AAAA,MACV,MAAM;AAAA,MACN,kBAAkB;AAAA;AAAA,IAAA,CACnB,GAEK,iBAAiB,MAAM;AAC3B,iBAAW,KAAK;AAAA,QACd,MAAM;AAAA,QACN,IAAInF;AAAA,MAAA,CACL,GACD,WAAW,SAAA;AAAA,IACb,GAEM,eAAe,CAAC,SAAsB,WAAW,MAAM,IAAI,MAAM,KAAK,OAAO,OAAO,CAAC,GAErF,kBAAkB,CAAC,SAChB,WAAW,KAAK,EAAC,MAAM,YAAY,SAAS,KAAK,QAAO,GAG3D,iBAAiB,MAAM;AAC3BqF,gBAAQ,MAAA,GACR,WAAW,KAAK;AAAA,QACd,MAAM;AAAA,QACN,IAAIrF;AAAA,MAAA,CACL;AAAA,IACH,GAEM,gBAAgB,MAAM;AAC1BqF,gBAAQ,OAAA,GACR,WAAW,KAAK;AAAA,QACd,MAAM;AAAA,QACN,IAAIrF;AAAA,MAAA,CACL;AAAA,IACH;AAEA,WAAAqF,UAAQ,GAAG,WAAW,cAAc,GACpCA,UAAQ,GAAG,SAAS,YAAY,GAChCA,UAAQ,GAAG,YAAY,eAAe,GACtCA,UAAQ,GAAG,WAAW,cAAc,GACpCA,UAAQ,GAAG,UAAU,aAAa,GAE3B,MAAMA,UAAQ,MAAA;AAAA,EACvB,CAAC;AACH;AChDO,SAAS,cAAc,OAAoC;AAChE,MAAI,OAAO,SAAU,SAAU;AAC/B,QAAM,UAAU,MAAM,KAAA;AACtB,MAAI,CAAC,QAAQ,SAAS,IAAI,EAAG;AAC7B,QAAM,IAAI,OAAO,QAAQ,MAAM,GAAG,EAAE,CAAC;AACrC,MAAI,CAAC,OAAO,SAAS,CAAC,EAAG;AACzB,MAAI,UAAU,KAAK,MAAM,CAAC;AAE1B,SAAI,YAAY,MAAG,UAAU,IAAI,IAAI,KAAK,IACnC,GAAG,OAAO;AACnB;ACJA,SAAS,+BAA+B,UAA+B;AACrE,QAAM,SAAS,SAAS;AACxB,MAAK;AACL,eAAW,SAAS,QAAQ;AAC1B,YAAM,UAAW,MAAuD;AACxE,UAAI,CAAC,QAAS;AAEd,YAAM,KAAK,cAAc,QAAQ,iBAAiB,GAC5C,KAAK,cAAc,QAAQ,eAAe,GAC1C,IAAI,cAAc,QAAQ,KAAK;AAEjC,aAAI,QAAQ,oBAAoB,KAChC,OAAI,QAAQ,kBAAkB,KAC9B,MAAG,QAAQ,QAAQ;AAAA,IACzB;AACF;AAEA,SAAS,wBAAwB,MAAsB;AACrD,SAAO,KAAK,QAAQ,0BAA0B,CAAC,QAAQ,QAAQ;AAC7D,UAAM,IAAI,OAAO,GAAG;AACpB,QAAI,CAAC,OAAO,SAAS,CAAC,EAAG,QAAO;AAChC,QAAI,UAAU,KAAK,MAAM,CAAC;AAC1B,WAAI,YAAY,MAAG,UAAU,IAAI,IAAI,KAAK,IACnC,IAAI,OAAO;AAAA,EACpB,CAAC;AACH;AAEO,SAAS,aAAa,QAAsBrF,OAAc;AAC/D,SAAO,OAAO,WAAW,QAAQ;AAAA,IAC/B,KAAK,uBAAuB,OAAO,SAAS,OAAO,IAAIA,KAAI;AAAA,IAC3D,iBAAiB;AAAA,IACjB,QAAQ;AAAA,EAAA,CACT;AACH;AAEO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,SAAO,QAAQ,GAAG,EAAE;AAAA,IAClBuF,UAAAA,UAAU,CAAC,aACFC,KAAAA;AAAAA,MACL3F,KAAAA,GAAG,EAAC,MAAM,OAAgB,KAAK,UAAS;AAAA,MACxC,sBAAsB,MAAM,EAAE;AAAA,QAC5B0F,UAAAA,UAAU,CAAC,SAAS;AAClB,cAAI,CAAC,QAAQ,CAAC,KAAK;AACjB,mBAAOE,gBAAW,IAAI,MAAM,qBAAqB,CAAC;AAEpD,gBAAMzF,SAAO0F,KAAAA,QACP,UAAU;AACX,kBAAQ,UAAO,QAAQ,QAAQ,CAAC,EAAC,MAAM,QAAA,CAAQ,IACpD,QAAQ,MAAM,CAAC,EAAE,MAAM,UACvB,+BAA+B,OAAO;AAEtC,gBAAM,QAAQ;AAAA,YACZ,SAAS,wBAAwB,KAAK,UAAU,OAAO,CAAC;AAAA,YACxD,UAAU,SAAS,MAAM,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC;AAAA,UAAA,GAGrC,UAAU,OAAO,OAAA,EAAS;AAChC,iBAAOzH,KAAAA;AAAAA,YAAM,MACX,OAAO,WAAW,QAAQ;AAAA,cACxB,KAAK,sBAAsB,OAAO;AAAA,cAClC,iBAAiB;AAAA,cACjB,QAAQ;AAAA,cACR,SAAS;AAAA,gBACP,kBAAkB+B;AAAAA,gBAClB,gBAAgB;AAAA,cAAA;AAAA,cAElB;AAAA,YAAA,CACD;AAAA,UAAA,EACD;AAAA,YACA2F,UAAAA,SAAS,CAAC,WAAW;AACnB,oBAAM,QACH,UAAU,OAAO,WAAW,OAAO,QAAQ,CAAC,KAAK,OAAO,QAAQ,CAAC,EAAE,YACpE;AAEF,qBAAK,QAGE9F,KAAAA,GAAG,EAAC,MAAM,WAAoB,IAAIG,QAAM,MAAA,CAAM,IAF5CyF,KAAAA,WAAW,IAAI,MAAM,4BAA4B,CAAC;AAAA,YAG7D,CAAC;AAAA,UAAA;AAAA,QAEL,CAAC;AAAA,MAAA;AAAA,IACH,CAEH;AAAA,EAAA;AAEL;AAEO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,SAAO,SAAS,IAAI,EAAE;AAAA,IACpBF,UAAAA,UAAU,CAAC,gBACFC,KAAAA;AAAAA,MACL3F,KAAAA,GAAG,EAAC,MAAM,QAAiB,MAAM,aAAY;AAAA,MAC7C,sBAAsB,MAAM,EAAE;AAAA,QAC5B0F,UAAAA,UAAU,CAAC,SAAS;AAClB,cAAI,CAAC,QAAQ,CAAC,KAAK;AACjB,mBAAOE,gBAAW,MAAM,IAAI,MAAM,qBAAqB,CAAC;AAE1D,gBAAMzF,SAAO0F,KAAAA,QACP,OAAO;AACb,iBAAA,+BAA+B,IAAI,GAE5BF,KAAAA;AAAAA,YACL3F,KAAAA,GAAG,EAAC,MAAM,QAAA,MAAiBG,QAAK;AAAA,YAChC/B,KAAAA;AAAAA,cAAM,MACJ,OAAO,WAAW,QAUf;AAAA,gBACD,KAAK,uBAAuB,OAAO,OAAA,EAAS,OAAO;AAAA,gBACnD,iBAAiB;AAAA,gBACjB,QAAQ;AAAA,gBACR,SAAS;AAAA,kBACP,kBAAkB+B;AAAAA,kBAClB,gBAAgB;AAAA,gBAAA;AAAA,gBAElB;AAAA,cAAA,CACD;AAAA,YAAA,EACD;AAAA,cACA2F,mBAAS,CAAC,WACD,wBAAwB3F,QAAM,OAAO,OAAO,KAAK,IAAI,EAAE;AAAA;AAAA;AAAA;AAAA,gBAI5D2F,UAAAA,SAAS,CAAC,UACJ,MAAM,SAAS,YACV9F,KAAAA,GAAG,KAAK,IAEV+F,KAAAA,KAAK,8BAA8B,QAAQ5F,MAAe,CAAC,EAAE;AAAA;AAAA,kBAElE2F,UAAAA,SAAS,CAAC,QAAQ9F,KAAAA,GAAG,EAAC,GAAG,OAAO,OAAO,KAAI,CAAC;AAAA,gBAAA,CAE/C;AAAA;AAAA,gBAEDgG,UAAAA,WAAW,CAAC,QAEH,aAAa,QAAQ7F,MAAI,EAAE,KAAK8F,UAAAA,WAAWL,gBAAW,GAAG,CAAC,CAAC,CACnE;AAAA,cAAA,CAEJ;AAAA,YAAA;AAAA,UACH;AAAA,QAEJ,CAAC;AAAA,MAAA;AAAA,IACH,CAEH;AAAA,EAAA;AAEL;AAgBO,SAAS,UAAU,QAAsB,SAAiB;AAC/D,QAAM,EAAC,QAAA,IAAW,OAAO,OAAA;AACzB,SAAO,OAAO,QAAwB;AAAA,IACpC,KAAK,uBAAuB,OAAO,IAAI,OAAO;AAAA,IAC9C,iBAAiB;AAAA,IACjB,QAAQ;AAAA,EAAA,CACT;AACH;AAEA,SAAS,WAAW,QAAsBzF,OAAuC;AAE/E,MAAI,cACA,QAAQ,GACR,SACA;AACJ,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,mBAAgB,YAA0C,YAAY;AACpE,UAAI;AACF,iBAAS,MAAM,UAAU,QAAQA,KAAI;AAAA,MACvC,SAAS,KAAK;AACZ,eAAO,GAAG;AACV;AAAA,MACF;AACA,gBAAU,UAAU,OAAO,QAAQ,OAAO,KAAK,UAC3C,YACF,cAAc,YAAY,GAC1B,QAAQ,MAAM,IAEZ,QAAQ,OACV,cAAc,YAAY,GAC1B,OAAO,IAAI,MAAM,uBAAuB,CAAC,IAE3C;AAAA,IACF,GAAG,GAAI;AAAA,EACT,CAAC;AACH;AAEA,eAAe,8BACb,QACAA,OACA,YACA;AACA,MAAI,QACA;AACJ,MAAI;AACF,aAAS,MAAM,WAAW,QAAQA,KAAI;AAAA,EACxC,SAAS,KAAK;AACZ,WAAO,QAAQ,OAAO,GAAG;AAAA,EAC3B;AACA,MAAI;AACF,YAAQ,MAAM,SAAS,QAAQ,OAAO,KAAK,QAAQ;AAAA,EACrD,SAAS,KAAK;AACZ,WAAO,QAAQ,OAAO,GAAG;AAAA,EAC3B;AAEA,QAAM,MAAM;AAAA,IACV,KAAKA;AAAA,IACL,OAAO;AAAA,IACP,QAAQ,MAAM,KAAK;AAAA,IACnB,MAAM,MAAM;AAAA,IACZ,SAAS,MAAM,KAAK;AAAA,IACpB,YAAY,MAAM,KAAK,aAAa,CAAC,EAAE;AAAA,IACvC,UAAU,OAAO,KAAK;AAAA,EAAA;AAExB,SAAO,OAAO,gBAAgB,GAAG,EAAE,KAAK,MAC/B,GACR;AACH;AAEO,SAAS,SAAS,MAAY;AACnC,MAAI,OAAO,SAAW,OAAe,gBAAgB,OAAO,MAAM;AAChE,UAAM,cAAc,gBAAgB,CAAA,GAAI,IAAI;AAC5C,WAAOH,KAAAA,GAAG,WAAW;AAAA,EACvB;AACA,SAAO4F,gBAAW,IAAI,MAAM,cAAc,CAAC;AAC7C;AAEO,SAAS,QAAQ,KAAiC;AACvD,QAAM,QAAQ,IAAI,MAAM,aAAa;AACrC,MAAI,OAAO,OAAQ;AACjB,WAAOA,KAAAA,WAAW,KAAK;AAEzB,QAAM,aAAa,IAAI,KAAA;AACvB,MAAI;AACJ,MAAI;AACF,aAAS,IAAI,IAAI,UAAU;AAAA,EAC7B,QAAc;AACZ,WAAOA,KAAAA,WAAW,KAAK;AAAA,EACzB;AACA,SAAI,UAAU,CAAC,OAAO,SAAS,MAAM,cAAc,IAC1CA,gBAAW,KAAK,IAElB5F,KAAAA,GAAG,UAAU;AACtB;AAEA,SAAS,gBAAgB,MAAoC,MAAY;AACvE,MAAI,EAAA,OAAO,SAAW,OAAe,EAAE,gBAAgB,OAAO;AAG9D,WAAO;AAAA,MACL,MAAM,KAAK,qBAAqB,KAAQ,SAAY,KAAK;AAAA,MACzD,MAAM,KAAK;AAAA,IAAA;AAEf;AChSO,SAAS,WAAW,KAAsB;AAC/C,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,WAAO,UAAU,CAAC,CAAC,OAAO,SAAS,MAAM,cAAc;AAAA,EACzD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMO,SAAS,cAAc,OAAoC;AAChE,SACE,gBAAgB,SAChB,OAAO,MAAM,cAAe,YAC5B,OAAO,MAAM,cACb,MAAM,cAAc;AAExB;AC7BO,SAAS,oBAAoB,cAA4B;AAC9D,QAAM,QAAQ,MAAM,KAAK,aAAa,SAAS,CAAA,CAAE,GAC3C,QAAQ,MAAM,KAAK,aAAa,SAAS,CAAA,CAAE;AACjD,SAAI,SAAS,MAAM,SAAS,IACnB,QAAQ,QAAQ,KAAK,IAEvB,eAAe,KAAK,EAAE,KAAK,CAAC,QAAQ,IAAI,MAAM;AACvD;AAEA,SAAS,eAAe,OAA2B;AACjD,SAAO,QAAQ;AAAA,IACb,MAAM,IAAI,CAAC,SAAS;AAElB,UAAI,KAAK,SAAS,UAAU,KAAK,kBAAkB;AACjD,YAAI;AAEJ,YAAI;AACF,kBAAQ,KAAK,iBAAA;AAAA,QACf,QAAc;AACZ,iBAAO,CAAC,KAAK,WAAW;AAAA,QAC1B;AACA,eAAK,QAGE,MAAM,cAAc,KAAK,KAAK,IAAI,CAAC,KAAK,UAAA,CAAW,IAFjD,CAAA;AAAA,MAGX;AAGA,UAAI,KAAK,SAAS,QAAQ;AACxB,cAAM,OAAO,KAAK,UAAA;AAClB,eAAO,QAAQ,QAAQ,OAAO,CAAC,IAAI,IAAI,CAAA,CAAE;AAAA,MAC3C;AAGA,aAAO,IAAI,QAAQ,CAAC,YAAY,KAAK,YAAY,OAAO,CAAC,EAAE;AAAA,QAAK,CAAC,QAC/D,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,GAAG,eAAe,EAAC,MAAM,KAAK,MAAK,CAAC,IAAI,CAAA;AAAA,MAAC;AAAA,IAEjE,CAAC;AAAA,EAAA;AAEL;AAEA,SAAS,OAAO,OAAsD;AACpE,SAAO,MAAM;AACf;AACA,SAAS,YAAY,OAA2D;AAC9E,SAAO,MAAM;AACf;AAEA,SAAS,KAAK,OAA6B;AACzC,MAAI,OAAO,KAAK;AACd,WAAO,IAAI,QAAQ,CAAC,YAAY,MAAM,KAAK,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;AAG5E,MAAI,YAAY,KAAK,GAAG;AACtB,UAAM,MAAM,MAAM,aAAA;AAClB,WAAO,IAAI,QAAa,CAAC,YAAY,IAAI,YAAY,OAAO,CAAC,EAC1D,KAAK,CAAC,YAA+B,QAAQ,OAAO,CAAC,SAAS,CAAC,KAAK,KAAK,WAAW,GAAG,CAAC,CAAC,EACzF,KAAK,CAAC,YAAY,QAAQ,IAAI,QAAQ,IAAI,IAAI,CAAC,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAA,CAAM,CAAC;AAAA,EAC/E;AACA,SAAO,QAAQ,QAAQ,EAAE;AAC3B;ACrDA,SAAwB,aAAa;AAAA,EACnC,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AACF,GAAU;AACR,QAAM,eAAe3B,MAAAA;AAAAA,IACnB,CAAC,gBAAgB;AACV,mBAAa,OAChB,SAAS6H,OAAAA,WAAW,KAAK,CAACC,OAAAA,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAE1C,YAAY,QAAQ,eAAe,OACrC;AAAA,QACED,OAAAA,WAAW,KAAK;AAAA,UACdE,OAAAA,aAAa,EAAC,OAAO,CAAA,GAAI,OAAO,aAAY;AAAA,UAC5CC,OAAAA,IAAI,EAAC,OAAO,aAAa,OAAO,IAAM,MAAM,YAAY,OAAM,CAAC,OAAO,CAAC;AAAA,QAAA,CACxE;AAAA,MAAA,GAGL,eAAe,EAAK;AAAA,IACtB;AAAA,IACA,CAAC,UAAU,gBAAgB,aAAa;AAAA,EAAA;AAG1C,SAAOrJ,2BAAAA,IAAC,eAAA,EAAc,UAAU,cAAc,OAAA,CAAgB;AAChE;AC9BA,MAAM,eAAe4B,iBAAAA,OAAOxB,SAAM;AAAA;AAAA;AAAA;AAAA;AAMlC,SAAwB,aAAa;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEG;AACD,QAAM,KAAK,eAAesB,MAAAA,MAAA,CAAO,IAC3B,cAAcL,MAAAA,YAAY,MAAM,eAAe,EAAK,GAAG,CAAC,cAAc,CAAC;AAC7E,SACErB,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,sBAAoB;AAAA,MACpB,QAAO;AAAA,MACP;AAAA,MACA,SAAS;AAAA,MACT,OAAO;AAAA,MAEP,UAAAA,2BAAAA;AAAAA,QAACsJ;AAAAA,QAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN;ACjCO,MAAM,kBAAkB,CAAC,OAA2B,aAAwC;AACjG,QAAM,SAAS,UAAA;AACf,SAAOjI,MAAAA,YAAY,MAAM;AAClB,cAGL,SAAS6H,OAAAA,WAAW,KAAKC,OAAAA,OAAO,CAAC,GAC7B,MAAM,WACR,iBAAiB,QAAQ,MAAM,OAAO,GAEpC,MAAM,OACR,OAAO,OAAO,MAAM,GAAG;AAAA,EAE3B,GAAG,CAAC,OAAO,QAAQ,QAAQ,CAAC;AAC9B;ACdoCvH,iBAAAA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAoB9B,cAAcA,iBAAAA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCrBrB,cAAcA,iBAAAA,OAAOpB,OAAI;AAAA;AAAA;AAAA,GAKzB,cAAcoB,iBAAAA,OAAOE,OAAI;AAAA;AAAA;AAAA,GAKzB,cAAcF,iBAAAA,OAAOvB,QAAK;AAAA;AAAA;AAAA,GAK1B,cAAcuB,iBAAAA,OAAOa,OAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAYzB,iBAAiB,CAAC;AAAA,EAC7B,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,OAAO;AACT,MAKM;AAGJ,QAAM,mBAAmB,YAAY;AAErC,SACEzC,+BAAC,eAAY,MAAK,WAAU,SAAS,GAAG,QAAM,IAAC,QAAO,QACpD,0CAAC,aAAA,EAAY,OAAM,UAAS,SAAQ,iBAAgB,QAAO,QAAO,WAAU,OAAM,KAAK,GACrF,UAAA;AAAA,IAAAO,gCAAC,aAAA,EACC,UAAA;AAAA,MAAAP,2BAAAA,IAAC8B,GAAAA,MAAA,EAAK,SAAQ,UAAS,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,WAAW,CAAC,UAAU,UAAU,KAAK,GAC7E,UAAA9B,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GACV,UAAAF,2BAAAA,KAACmC,GAAAA,QAAA,EAAO,OAAO,GACZ,UAAA;AAAA,QAAA;AAAA,QACD1C,2BAAAA,IAAC,aAAA,EAAY,MAAM,GAAI,sBAAsB,MAAA,CAAM;AAAA,MAAA,EAAA,CACrD,GACF,GACF;AAAA,MAEAA,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,WAAW,GAAG,QAAQ,GAAG,QAAQ,GACrC,UAAAR,2BAAAA,IAACuJ,OAAAA,gBAAA,EAAe,OAAO,SAAA,CAAU,EAAA,CACnC;AAAA,IAAA,GACF;AAAA,IAEC,WACCvJ,2BAAAA;AAAAA,MAACM,GAAAA;AAAAA,MAAA;AAAA,QACC,UAAU;AAAA,QACV,MAAK;AAAA,QACL,MAAK;AAAA,QACL,MAAK;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,MAAA;AAAA,IAAA,IAEV;AAAA,EAAA,EAAA,CACN,EAAA,CACF;AAEJ,GChEM,SAAS,CAAC,EAAC,OAAO,SAAS,UAAU,UAAU,aAAmB;AACtE,QAAM,YAAYY,MAAAA,QAA0B,MACtC,OAAO,WAAW,cACb,wBAEL,OAAO,WAAW,uBACb,gCAEL,OAAO,WAAW,YACb,sBAEL,EAAA,OAAO,WAAW,WAGlB,OAAO,OAAO,SAAW,MAK5B,CAAC,KAAK,CAAC,GACJ,8BAA8BA,MAAAA,QAAiB,MAAM;AAIzD,QACE,OAAO,MAAM,mBAAmB,UAChC,OAAO,MAAM,mBAAmB,WAAW;AAE3C,aAAO;AAIT,UAAM,QAAQ,OAAO,MAAM,mBAAmB;AAC9C,WAAI,CAAC,SAAS,MAAM,WAAW,IACtB,KAEF,MAAM,KAAK,CAAC,SAAS,KAAK,WAAW,WAAW;AAAA,EACzD,GAAG,CAAC,OAAO,MAAM,mBAAmB,QAAQ,OAAO,MAAM,mBAAmB,KAAK,CAAC,GAC5E,UAAUe,aAAuB,IAAI,GACrC,UAAUA,MAAAA,OAAuB,IAAI,GACrC,qBAAqB,gBAAgB,OAAO,QAAQ;AAuB1D,SArBAI,MAAAA,UAAU,MAAM;AACd,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,YAAY,0CAEd,QAAQ,SAAS,cACnB,QAAQ,QAAQ,WAAW,YAAY,KAAK,GAE1C,SAAS,SAAS,cACpB,QAAQ,QAAQ,WAAW,YAAY,MAAM,UAAU,EAAI,CAAC;AAAA,EAEhE,GAAG,CAAA,CAAE,GAELA,MAAAA,UAAU,MAAM;AACd,QAAI,OAAO,WAAW;AACpB,YAAA,mBAAA,GAGM,IAAI,MAAM,MAAM,MAAM,QAAQ,UAAU,KAAK,GAAG,CAAC;AAAA,EAE3D,GAAG,CAAC,MAAM,MAAM,QAAQ,UAAU,OAAO,QAAQ,kBAAkB,CAAC,GAEhE,CAAC,SAAS,CAAC,MAAM,SACZ,OAGL,YAEArC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,UAAU;AAAA,MACV,UAAU,OAAO;AAAA,MACjB,MAAO,cAAc,MAAQ,aAAc;AAAA,MAC3C,UAAU,WAAW,SAAY,MAAM,mBAAA;AAAA,IAAmB;AAAA,EAAA,IAM9DO,2BAAAA,KAAC,aAAA,EAAY,OAAc,WAAW,QAAQ,WAC3C,UAAA;AAAA,IAAA,WAAWP,2BAAAA,IAAC,aAAA,EAAY,MAAK,cAAc,UAAA,SAAQ;AAAA,IACnD,+BACCA,2BAAAA;AAAAA,MAACQ,GAAAA;AAAAA,MAAA;AAAA,QACC,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,OAAO;AAAA,UACL,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,KAAK;AAAA,UACL,MAAM;AAAA,QAAA;AAAA,QAGR,UAAAR,2BAAAA,IAACS,WAAK,MAAM,GAAG,OAAO,EAAC,OAAO,0BAAyB,UAAA,sDAAA,CAEvD;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GAEJ;AAEJ;ACjHO,SAAS,qBAAqB,QAAgD;AACnF,SAAO,eAAe,OAAO,KAAK,MAAM,OAAO,KAAK;AACtD;AAEO,SAAS,eAAe,MAIpB;AACT,QAAM,EAAC,MAAM,QAAQ,cAAa,MAC5B,uBAAuB,UAAU,SAAS,UAAU,OACpD,sBAAsB,IAAI,UAAU,QACpC,UAAU,OAAO,KAAK,KAAK;AAEjC,SAAO;AAAA,IACL,sBAAsB,KAAK,eAAe,mBAAmB;AAAA,IAC7D,UAAU,qBAAqB,MAAM;AAAA,IACrC,sBAAsB,KAAK,SAAS,IAAI,mBAAmB,MAAM,OAAO;AAAA,IACxE,uBAAuB,KAAK,SAAS,oBAAoB;AAAA,EAAA,EAExD,OAAO,OAAO,EACd,KAAK,GAAG;AACb;AClBO,MAAM,aAAamB,iBAAAA,OAAO0C,GAAAA,QAAQ,EAAE,CAAC,EAAC,YAAW;AACtD,QAAM,EAAC,cAAa,MAAM,QACpB,OAAO,MAAM,OAAO,MAAM;AAGhC,SAAOkF,iBAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,sBAKa,eAAe,EAAC,MAAM,QAP3B,EAAC,OAAO,GAAG,OAAO,8BAOiB,UAAA,CAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoB/D,CAAC,GCrBY,oBAAoB7C,eAAAA,QAAM,WAAW,SAChD,OAEA,cACA;AACA,QAAM;AAAA,IACJ;AAAA,IACA,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,IACD,OACE,SAASjF,MAAAA,SACT,KAAK,UAAU,QAEf,eAAeiF,eAAAA,QAAM;AAAA,IACzB,CAAC,UAA+C;AAC1C,kBAAY,MAAM,OAAO,SAC3B,SAAS,MAAM,KAAK,MAAM,OAAO,KAAK,CAAC;AAAA,IAE3C;AAAA,IACA,CAAC,QAAQ;AAAA,EAAA,GAGL,UACJpG,2BAAAA,KAACuB,WAAK,OAAM,UAAS,SAAQ,cAE1B,UAAA;AAAA,IAAA,QACC9B,2BAAAA,IAAC+B,GAAAA,OAAI,aAAa,OAAO,QAAQ,QAC/B,UAAAxB,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,UACT,UAAA;AAAA,MAAAqF,MAAAA,eAAe,IAAI,KAAK;AAAA,MACxB2D,2BAAmB,IAAI,KAAKC,MAAAA,cAAc,IAAI;AAAA,IAAA,EAAA,CACjD,EAAA,CACF;AAAA,IAID,uCACEjJ,SAAA,EAAK,OAAO,WAAW,MAAM,UAAU,cAAa,YAClD,UAAA,KAAA,CACH;AAAA,EAAA,GAEJ;AAGF,SACEF,gCAAC,cAAY,GAAG,MAAM,SAAS,IAAI,UAAoB,KAAK,cACzD,UAAA;AAAA,IAAA;AAAA,IAGDP,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,eAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV,MAAK;AAAA,QACL,OAAM;AAAA,QACN;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ,CAAC,GChDK,WAAW4B,iBAAAA,OAAOpB,OAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAStB,aAAaoB,iBAAAA,OAAOtB,SAAM;AAAA;AAAA;AAAA,GAM1B,eAAe,CAAC,UACb,MAAM,UAAU;AAGzB,SAAS,kBACP,OAQA;AACA,QAAM,EAAC,OAAO,UAAU,aAAa,gBAAgB,UAAU,UAAU,OAAA,IAAU,OAC7E,CAAC,MAAM,OAAO,IAAIJ,MAAAA,SAAS,EAAK,GAChC,CAAC,aAAa,UAAU,IAAIA,MAAAA,SAAgC,IAAI,GAChE,WAAWgB,MAAAA,QAAQ,MAAM,kBAAkB,KAAK,GAAG,WAAW,UAAU,CAAC,KAAK,CAAC,GAC/E,EAAC,gBAAA,IAAmB,iBAAiB,MAAM,MAAM,GACjD,EAAC,aAAa,YAAA,IAAe,eAAe,EAAC,WAAW,GAAA,CAAK,GAE7D,UAAUG,MAAAA,YAAY,MAAM,SAAS6H,OAAAA,WAAW,KAAKC,OAAAA,MAAM,CAAA,CAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAE5E,eAAe9H,MAAAA,YAAY,YAAY;AAC3C,YAAQ,EAAK,GACb,MAAM,YAAY,KAAK;AAAA,EACzB,GAAG,CAAC,aAAa,KAAK,CAAC;AAEvB,SAAAgB,MAAAA,UAAU,MAAM;AACV,YAAQ,eACV,QAAQ,EAAK;AAAA,EAEjB,GAAG,CAAC,aAAa,IAAI,CAAC,GAEtBsH,GAAAA;AAAAA,IACE,MAAM,QAAQ,EAAK;AAAA,IACnB,MAAM,CAAC,WAAW;AAAA,EAAA,GAIlBpJ,2BAAAA,KAACmC,GAAAA,QAAA,EAAO,OAAO,GAAG,SAAS,GACxB,UAAA;AAAA,IAAA,YACC1C,2BAAAA;AAAAA,MAAC0F,GAAAA;AAAAA,MAAA;AAAA,QACC,SAAO;AAAA,QACP,SACE1F,2BAAAA,IAAC+B,QAAA,EAAI,SAAS,GACZ,UAAA/B,+BAACS,GAAAA,MAAA,EAAK,OAAK,IAAC,MAAM,GAAG,UAAA,yBAAA,CAErB,GACF;AAAA,QAEF,WAAU;AAAA,QACV,QAAM;AAAA,QAEN,yCAAC,UAAA,EAAS,QAAQ,GAAG,QAAQ,GAAG,QAAO,QAAO,MAAK,YACjD,UAAAT,2BAAAA,IAAC,cAAW,MAAMsH,MAAAA,UAAU,MAAK,SAAQ,MAAK,YAAW,EAAA,CAC3D;AAAA,MAAA;AAAA,IAAA;AAAA,IAGJtH,2BAAAA;AAAAA,MAAC4J,GAAAA;AAAAA,MAAA;AAAA,QACC,SAAO;AAAA,QACP,SACErJ,2BAAAA,KAAC8D,GAAAA,MAAA,EAAK,KAAK,YACT,UAAA;AAAA,UAAArE,2BAAAA,IAAC+B,GAAAA,KAAA,EAAI,SAAS,GACZ,UAAA/B,2BAAAA,IAAC+D,GAAAA,OAAA,EAAM,OAAK,IAAC,MAAM,GAAG,UAAA,UAAA,CAEtB,GACF;AAAA,UACA/D,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC;AAAA,cACA,MAAM2E,MAAAA;AAAAA,cACN;AAAA,cACA,MAAK;AAAA,cACL,UAAU;AAAA,cACV,UAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAEZ3E,2BAAAA;AAAAA,YAACsE,GAAAA;AAAAA,YAAA;AAAA,cACC,MAAM0C,MAAAA;AAAAA,cACN,MAAK;AAAA,cACL,SAAS,MAAM,eAAe,cAAc;AAAA,YAAA;AAAA,UAAA;AAAA,UAE7C,aAAa,KAAK,KACjBzG,2BAAAA,KAAAsB,WAAAA,UAAA,EACE,UAAA;AAAA,YAAA7B,2BAAAA;AAAAA,cAACsE,GAAAA;AAAAA,cAAA;AAAA,gBACC,MAAMuF,MAAAA;AAAAA,gBACN,MAAK;AAAA,gBACL,SAAS,MAAM,eAAe,gBAAgB;AAAA,cAAA;AAAA,YAAA;AAAA,YAEhD7J,2BAAAA;AAAAA,cAACsE,GAAAA;AAAAA,cAAA;AAAA,gBACC,MAAMO,MAAAA;AAAAA,gBACN,MAAK;AAAA,gBACL,SAAS,MAAM,eAAe,eAAe;AAAA,cAAA;AAAA,YAAA;AAAA,YAE/C7E,2BAAAA;AAAAA,cAACsE,GAAAA;AAAAA,cAAA;AAAA,gBACC,MAAMJ,MAAAA;AAAAA,gBACN,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT,UAAU,YAAY;AAAA,cAAA;AAAA,YAAA;AAAA,UACxB,GACF;AAAA,yCAED4F,GAAAA,aAAA,EAAY;AAAA,UACZ,mBACCvJ,2BAAAA,KAAAsB,qBAAA,EACE,UAAA;AAAA,YAAA7B,2BAAAA;AAAAA,cAACsE,GAAAA;AAAAA,cAAA;AAAA,gBACC,MAAM+D,MAAAA;AAAAA,gBACN,MAAK;AAAA,gBACL,SAAS,MAAM,eAAe,SAAS;AAAA,cAAA;AAAA,YAAA;AAAA,2CAExCyB,GAAAA,aAAA,CAAA,CAAY;AAAA,UAAA,GACf;AAAA,UAEF9J,2BAAAA;AAAAA,YAACsE,GAAAA;AAAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,MAAMyF,MAAAA;AAAAA,cACN,MAAK;AAAA,cACL,SAAS;AAAA,cACT,UAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ,GACF;AAAA,QAEF,QAAM;AAAA,QACN;AAAA,QAEA,UAAA/J,2BAAAA;AAAAA,UAACM,GAAAA;AAAAA,UAAA;AAAA,YACC,MAAM0J,MAAAA;AAAAA,YACN,MAAK;AAAA,YACL,UAAU;AAAA,YACV,SAAS,MAAM;AACb,6BAAe,EAAK,GACpB,QAAQ,EAAI;AAAA,YACd;AAAA,UAAA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;AAEA,IAAA,sBAAehI,MAAAA,KAAK,iBAAiB;ACzL9B,SAAS,iBAAiB,cAA4B,aAAsB;AACjF,QAAM,CAAC,UAAU,WAAW,IAAI9B,MAAAA,SAAwB,IAAI,GACtD,CAAC,mBAAmB,oBAAoB,IAAIA,MAAAA,SAAS,EAAK,GAC1D,CAAC,2BAA2B,4BAA4B,IAAIA,MAAAA,SAAS,EAAK;AAEhF,SAAAmC,MAAAA,UAAU,MAAM;AAEd,QAAI,aAAa,SAAS,OAAO;AAC/B,2BAAqB,EAAK,GAC1B,6BAA6B,EAAK,GAClC,YAAY,IAAI;AAChB,YAAM,MAAM,aAAa;AA0BzB,OAvBsB,YAAY;AAChC,6BAAqB,EAAI;AACzB,YAAI;AAEF,gBAAM,iBADW,MAAM,MAAM,KAAK,EAAC,QAAQ,QAAO,GACnB,QAAQ,IAAI,gBAAgB,GACrD,cAAc,gBAAgB,SAAS,eAAe,EAAE,IAAI;AAElE,+BAAqB,EAAK,GACtB,eACF,YAAY,WAAW,GAErB,gBAAgB,QAAQ,gBAAgB,UAE1C,6BAA6B,EAAI;AAAA,QAErC,QAAQ;AACN,kBAAQ,KAAK,uCAAuC,GAEpD,6BAA6B,EAAI,GACjC,qBAAqB,EAAK;AAAA,QAC5B;AAAA,MACF,GAAA;AAAA,IAGF;AACI,iBAAa,SAAS,UACxB,YAAY,aAAa,MAAM,CAAC,EAAE,IAAI;AAAA,EAE1C,GAAG,CAAC,aAAa,cAAc,aAAa,IAAI,CAAC,GAE1C;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;ACxCO,SAAS,iBAAiB,cAA4B;AAC3D,QAAM,CAAC,oBAAoB,qBAAqB,IAAInC,eAAoC,IAAI,GACtF,CAAC,mBAAmB,oBAAoB,IAAIA,MAAAA,SAAS,EAAK;AAChE,SAAAmC,MAAAA,UAAU,MAAM;AACd,QAAI,WAAW;AAEf,QAAI,aAAa,SAAS,QAAQ;AAChC,YAAM,OAAO,aAAa,MAAM,CAAC;AACjC,iBAAW,IAAI,gBAAgB,IAAI;AAAA,IACrC;AAcA,QAXI,aAAa,SAAS,UACxB,WAAW,aAAa,MAG1B,sBAAsB,CAAC,SAAS;AAAA,MAC9B,GAAG;AAAA,MACH,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,IAAA,EACR,GAEE,CAAC,iBAAiB,MAAM;AAE5B,yBAAqB,EAAI;AACzB,UAAM,eAAe,SAAS,cAAc,OAAO;AACnD,iBAAa,UAAU;AAEvB,UAAM,oBAAoB;AAAA,MACxB,MAAM;AACJ,6BAAqB,EAAK;AAAA,MAC5B;AAAA,MACA,MAAM;AACJ,cAAM,WAAW,aAAa,UACxB,QAAQ,aAAa,YACrB,SAAS,aAAa,aACtB,cAAc,SAAS,KAAK,UAAU,GACtC,cAAc,QAAQ;AAC5B,8BAAsB,CAAC,SACd;AAAA,UACL,GAAG;AAAA,UACH;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA,EAEH;AAAA,MACH;AAAA,IAAA,GAGI,eAAe,CAAC,YAA8B;AAClD,YAAM,kBAAkB,SAAS;AAC7B,kBACF,kBAAkB;AAAA,QAAQ,CAAC,aACzB,QAAQ,oBAAoB,kBAAkB,QAAQ;AAAA,MAAA,GAExD,QAAQ,UAAU,MAClB,QAAQ,MAAM,IACd,QAAQ,KAAA,IAEN,iBAAiB,WAAW,OAAO,KACrC,IAAI,gBAAgB,eAAe;AAAA,IAEvC;AACA,WAAA,kBAAkB,KAAK,MAAM,WAAW,MAAM,aAAa,YAAY,GAAG,CAAC,CAAC,GAE5E,aAAa,UAAU,MAAM;AAC3B,2BAAqB,EAAK,GAC1B,QAAQ,KAAK,8CAA8C,GAC3D,aAAa,YAAY;AAAA,IAC3B,GAEA,kBAAkB;AAAA,MAAQ,CAAC,aACzB,aAAa,iBAAiB,kBAAkB,QAAQ;AAAA,IAAA,GAE1D,aAAa,MAAM,UAEZ,MAAM;AACX,mBAAa,YAAY;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,aAAa,MAAM,YAAY,CAAC,GAE7B;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AC5FO,SAAS,6BACd,WACA,SAe2B;AAC3B,MAAI,CAAC,UAAU,WAAW,CAAC,UAAU;AACnC,WAAO;AAGT,QAAM,OAAO,UAAU,QAAQ,IACzB,UAAU,UAAU,WAAW,KAO/B,aAAa,CAAC,cAAsB,SAAoB;AAC5D,UAAM4H,oBAAmB,SAAS,oBAAoB,oBAChD,aAAaA,oBAAmB,KAAKA,oBAAmB,GAGxD,OAAO,SAAS,MAFR,aAAa,OAAO,OACpB,aAAa,OAAO,MAE5B,KAAM,eAAe,MAAO;AAClC,QAAI,UAAU,KAAK,MAAM,EAAE;AAE3B,WAAI,YAAY,MAAG,UAAU,KAAK,IAAI,KAAK,IACpC,GAAG,OAAO;AAAA,EACnB,GAEM,oBAAoB,CAAC,OAA2B,SAAwC;AAC5F,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,UAAU,MAAM,KAAA;AACtB,QAAI,QAAQ,SAAS,IAAI;AACvB,aAAO,cAAc,OAAO;AAE9B,QAAI,QAAQ,SAAS,GAAG,GAAG;AACzB,YAAM,IAAI,OAAO,QAAQ,MAAM,GAAG,EAAE,CAAC;AACrC,aAAK,OAAO,SAAS,CAAC,IACf,WAAW,GAAG,IAAI,IADO;AAAA,IAElC;AACA,WAAO;AAAA,EACT;AAKA,MAAI,UAAU,kBAAkB;AAC9B,UAAM,aAAa,UAAU,iBAAiB,OACxC,kBACJ,SAAS,UAAU,OAAO,kBAAkB,YAAY,GAAG,IAAI;AACjE,WAAO;AAAA,MACL,GAAG,UAAU;AAAA,MACb,mBACE,SAAS,UAAU,OACd,kBAAkB,UAAU,iBAAiB,mBAAmB,GAAG,KACpE,UAAU,iBAAiB,oBAC3B,UAAU,iBAAiB;AAAA,MACjC,iBACE,SAAS,UAAU,OACd,kBAAkB,UAAU,iBAAiB,iBAAiB,GAAG,KAClE,UAAU,iBAAiB,kBAC3B,UAAU,iBAAiB;AAAA,MACjC,OAAO,mBAAmB,GAAG,IAAI;AAAA,MACjC,SAAS,UAAU,iBAAiB,WAAW,GAAG,KAAK,MAAM,UAAU,GAAG,CAAC;AAAA,IAAA;AAAA,EAE/E;AAEA,QAAM,WAAW,UAAU,YAAY,EAAC,GAAG,IAAI,GAAG,GAAA,GAiB5C,eAAe,CAAC,UAAkB,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,KAAK,CAAC,GAIrE,kBAAkB,CAAC,UAGhB,GADW,UAAU,KAAK,OAAO,GAAG,OAAO,EAAE,KAAK,KAAK,IAAI,KAAK,IAAI,OACrD,OAAO,KAAK,KAG9B,oCAAoC,MASpC,mBAAmB,SAAS,oBAAoB,KAAK,GACrD,mBAAmB,UAAU,oBAAoB,GACjD,sCAAsC,KAAK;AAAA,IAC/C;AAAA,IACA,KAAK,IAAI,KAAM,OAAO,mBAAoB,gBAAgB;AAAA,EAAA,GAGtD,YAAY,oCAAoC,GAChD,aAAa,sCAAsC,GAEnD,aAAa;AAAA,IACjB,KAAK,IAAI,SAAS,IAAI,WAAW,MAAM,iCAAiC;AAAA,EAAA,GAEpE,YAAY;AAAA,IAChB,KAAK,IAAI,SAAS,IAAI,YAAY,MAAM,mCAAmC;AAAA,EAAA,GAGvE,QAAQ,SAAS,SAAS,KAC1B,UAAU,UAAU,OAAO,WAAW,YAAY,GAAG,IAAI,gBAAgB,UAAU,GACnF,UAAU,UAAU,OAAO,WAAW,WAAW,GAAG,IAAI,gBAAgB,SAAS,GACjF,QAAQ,UAAU,OAAO,WAAW,MAAM,GAAG,IAAI,GAAG,IAAI;AAW9D,SAT4C;AAAA,IAC1C,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB;AAAA,IACA,SAAS,GAAG,KAAK,MAAM,UAAU,GAAG,CAAC;AAAA,EAAA;AAIzC;ACnJA,SAAwB,YAAY,OAAe,KAAK,IAAO,KAAK,GAAG;AACrE,QAAM,SAAS,KAAK,MAAO;AAE3B,MAAI,KAAK,IAAI,KAAK,IAAI;AACpB,WAAO,QAAQ;AAGjB,QAAM,QAAQ,KACV,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI,IAC/C,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAC3D,MAAIC,KAAI;AACR,QAAM,IAAI,MAAM;AAEhB;AACE,aAAS,QACT,EAAEA;AAAA,SACK,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,UAAUA,KAAI,MAAM,SAAS;AAE7E,SAAO,MAAM,QAAQ,EAAE,IAAI,MAAM,MAAMA,EAAC;AAC1C;ACvBA,MAAM,aAAatI,iBAAAA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAwCpB,mBAAmBA,iBAAAA,OAAO;AAAA;AAAA;AAAA,aAGnB,CAAC,UAAU,MAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BtC,SAAwB,mBAAmB;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,CAAC,YAAY,aAAa,IAAI1B,MAAAA,SAAS,EAAK,GAC5C,CAAC,WAAW,YAAY,IAAIA,MAAAA,SAAS,EAAC,GAAG,GAAG,GAAG,EAAA,CAAE,GACjD,CAAC,eAAe,gBAAgB,IAAIA,MAAAA,SAAS,EAAC,GAAG,GAAG,GAAG,EAAA,CAAE,GACzD,eAAe+B,MAAAA,OAAuB,IAAI,GAC1C,qBAAqBA,MAAAA,OAA8B,IAAI,GACvD,CAAC,eAAe,gBAAgB,IAAI/B,MAAAA,SAAS,UAAU,YAAY,EAAC,GAAG,IAAI,GAAG,IAAG,GAEjF,WAAW,eACX,OAAO,UAAU,QAAQ,IACzB,UAAU,UAAU,WAAW,KAE/B,sBAAsB,CAAC,UAA6C;AACxE,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,UAAU,MAAM,KAAA;AACtB,QAAI,CAAC,QAAQ,SAAS,GAAG,EAAG,QAAO;AACnC,UAAM,MAAM,OAAO,QAAQ,MAAM,GAAG,EAAE,CAAC;AACvC,WAAK,OAAO,SAAS,GAAG,IACjB,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,MAAM,GAAG,CAAC,IADP;AAAA,EAEpC,GAEM,qBAAqBmB,MAAAA,YAAY,MAAM;AAC3C,UAAM,YAAY,cAAc;AAChC,QAAI,CAAC,UAAW,QAAO,EAAC,GAAG,GAAG,GAAG,GAAG,OAAO,GAAG,QAAQ,EAAA;AAEtD,UAAM,OAAO,UAAU,yBACjB,aAAa,KAAK,OAClB,aAAa,KAAK,QAElB,UAAU,iBAAiB,SAC3B,SAAS,SAAS,cAAc,GAChC,SAAS,SAAS,eAAe;AAEvC,QAAI,CAAC,UAAU,CAAC,UAAU,CAAC,cAAc,CAAC;AACxC,aAAO,EAAC,GAAG,GAAG,GAAG,GAAG,OAAO,YAAY,QAAQ,WAAA;AAIjD,UAAM,QAAQ,KAAK,IAAI,aAAa,QAAQ,aAAa,MAAM,GACzD,WAAW,SAAS,OACpB,WAAW,SAAS,OACpB,WAAW,aAAa,YAAY,GACpC,WAAW,aAAa,YAAY;AAE1C,WAAO,EAAC,GAAG,SAAS,GAAG,SAAS,OAAO,UAAU,QAAQ,SAAA;AAAA,EAC3D,GAAG,CAAC,cAAc,eAAe,CAAC,GAE5B,oBAAoB,CAAC,UAAoE;AAC7F,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,UAAU,MAAM,KAAA,GAChB,KAAK,QAAQ,SAAS,IAAI,GAC1B,MAAM,QAAQ,SAAS,GAAG,GAC1B,MAAM,OAAO,QAAQ,QAAQ,SAAS,EAAE,CAAC;AAC/C,WAAK,OAAO,SAAS,GAAG,IACpB,KAAW,EAAC,GAAG,KAAK,MAAM,KAAA,IAC1B,MAAY,EAAC,GAAG,KAAK,MAAM,IAAA,IACxB,OAH2B;AAAA,EAIpC,GAEM,qBAAqB,CAAC,YAAgC;AAC1D,UAAM,OAAO,cAAc,SAAS,sBAAA,GAC9B,IAAI,MAAM,SAAS,GACnB,IAAI,MAAM,UAAU,GACpB,aAAa,IAAI,GACjB,QAAQ,aAAa,OAAO,MAC5B,QAAQ,aAAa,OAAO,MAE5B,KAAK,kBAAkB,QAAQ,iBAAiB,GAChD,KAAK,kBAAkB,QAAQ,eAAe,GAC9C,KAAK,kBAAkB,QAAQ,KAAK,GACpC,gBAAgB,oBAAoB,QAAQ,OAAO,GAEnD,QAAQ,CAAC,GAAyC,SAAoB;AAC1E,UAAK;AACL,eAAI,EAAE,SAAS,MAAY,GAAG,EAAE,CAAC,MAC7B,SAAS,MAAY,GAAI,EAAE,IAAI,IAAK,KAAK,OACtC,GAAI,EAAE,IAAI,IAAK,KAAK;AAAA,IAC7B,GAEM,yBAAyB,MACzB,QAAQ,qBAAqB,SACxB,EAAC,MAAM,MAAM,IAAI,GAAG,GAAG,OAAO,QAAW,WAAW,kBAAA,IAEzD,QAAQ,qBAAqB,UACxB,EAAC,OAAO,MAAM,IAAI,GAAG,GAAG,MAAM,QAAW,WAAW,sBAEtD,EAAC,MAAM,OAAO,OAAO,QAAW,WAAW,qBAAA,GAG9C,uBAAuB,MACvB,QAAQ,mBAAmB,QACtB,EAAC,KAAK,MAAM,IAAI,GAAG,GAAG,QAAQ,OAAA,IAEnC,QAAQ,mBAAmB,WACtB,EAAC,QAAQ,MAAM,IAAI,GAAG,GAAG,KAAK,OAAA,IAEhC,EAAC,KAAK,OAAO,QAAQ,UAGxB,SAAS,uBAAA,GACT,SAAS,qBAAA;AAEf,QAAI,YAAY,OAAO;AACvB,WAAI,QAAQ,mBAAmB,aAC7B,YACE,QAAQ,qBAAqB,WAAW,0BAA0B,uBAG/D;AAAA,MACL,UAAU;AAAA,MACV,GAAG;AAAA,MACH,GAAG;AAAA,MACH;AAAA,MACA,OAAO,KAAK,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI;AAAA,MACpC,SAAS,iBAAiB;AAAA,MAC1B,QAAQ;AAAA,IAAA;AAAA,EAEZ,GAEM,oBAAoBA,MAAAA;AAAAA,IACxB,CAAC,iBAAkC;AAC7B,yBAAmB,WACrB,aAAa,mBAAmB,OAAO,GAEzC,mBAAmB,UAAU,WAAW,MAAM;AAC5C,iBAAS,YAAY;AAAA,MACvB,GAAG,GAAG;AAAA,IACR;AAAA,IACA,CAAC,QAAQ;AAAA,EAAA;AAGXgB,QAAAA,UAAU,MACD,MAAM;AACP,uBAAmB,WACrB,aAAa,mBAAmB,OAAO;AAAA,EAE3C,GACC,CAAA,CAAE,GAELA,MAAAA,UAAU,MAAM;AACV,KAAC,cAAc,UAAU,YAC3B,iBAAiB,UAAU,QAAQ;AAAA,EAEvC,GAAG,CAAC,UAAU,UAAU,UAAU,CAAC;AAEnC,QAAM,kBAAkBhB,MAAAA;AAAAA,IACtB,CAAC,MAAwB;AACvB,QAAE,kBACF,cAAc,EAAI,GAClB,aAAa,EAAC,GAAG,EAAE,SAAS,GAAG,EAAE,QAAA,CAAQ,GACzC,iBAAiB,EAAC,GAAG,SAAS,GAAG,GAAG,SAAS,GAAE;AAAA,IACjD;AAAA,IACA,CAAC,QAAQ;AAAA,EAAA,GAGL,kBAAkBA,MAAAA;AAAAA,IACtB,CAAC,MAAkB;AACjB,UAAI,CAAC,cAAc,CAAC,cAAc,QAAS;AAG3C,YAAM,OADY,aAAa,QACR,sBAAA,GACjB,UAAU,sBACV,WAAW,QAAQ,SAAS,KAAK,OACjC,WAAW,QAAQ,UAAU,KAAK,QAClC,KAAK,EAAE,UAAU,UAAU,GAC3B,KAAK,EAAE,UAAU,UAAU,GAE3B,gBAAiB,KAAK,WAAY,KAClC,gBAAiB,KAAK,WAAY;AAExC,UAAI,OAAO,cAAc,IAAI,eACzB,OAAO,cAAc,IAAI;AAE7B,aAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,CAAC,GACtC,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,CAAC,GAEtC,iBAAiB,EAAC,GAAG,MAAM,GAAG,KAAA,CAAK,GAEnC,kBAAkB;AAAA,QAChB,GAAG;AAAA,QACH,UAAU,EAAC,GAAG,MAAM,GAAG,KAAA;AAAA,MAAI,CAC5B;AAAA,IACH;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EACF,GAGI,gBAAgBA,MAAAA,YAAY,MAAM;AACtC,kBAAc,EAAK,GACf,mBAAmB,YACrB,aAAa,mBAAmB,OAAO,GACvC,mBAAmB,UAAU,OAE/B,SAAS;AAAA,MACP,GAAG;AAAA,MACH,UAAU;AAAA,IAAA,CACX;AAAA,EACH,GAAG,CAAC,WAAW,eAAe,QAAQ,CAAC;AAcvC,MAZAgB,MAAAA,UAAU,MAAM;AACd,QAAI;AACF,aAAA,SAAS,iBAAiB,aAAa,eAAe,GACtD,SAAS,iBAAiB,WAAW,aAAa,GAC3C,MAAM;AACX,iBAAS,oBAAoB,aAAa,eAAe,GACzD,SAAS,oBAAoB,WAAW,aAAa;AAAA,MACvD;AAAA,EAGJ,GAAG,CAAC,YAAY,iBAAiB,aAAa,CAAC,GAE3C,CAAC,UAAU;AACb,WAAO;AAGT,QAAM,mBAAmB,EAAQ,UAAU,kBACrC,mBAAmB,mBACpB,oBAAoB,UAAU,kBAAkB,OAAO,KAAK,UAC7D,SACE,aAAa,mBAAA,GACb,gBAAgB,WAAW,QAAQ,KAAK,WAAW,SAAS;AAwBlE,SACErC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,UAAU;AAAA,MACV,aAAa,mBAAmB,SAAY;AAAA,MAC5C,OA1BE,mBACK,mBAAmB,UAAU,gBAAiB,IAEnD,gBACK;AAAA,QACL,MAAM,GAAG,WAAW,IAAK,SAAS,IAAI,MAAO,WAAW,KAAK;AAAA,QAC7D,KAAK,GAAG,WAAW,IAAK,SAAS,IAAI,MAAO,WAAW,MAAM;AAAA,QAC7D,WAAW;AAAA,QACX,OAAO,GAAG,KAAK,IAAI,GAAI,OAAO,MAAO,WAAW,KAAK,CAAC;AAAA,QACtD,QAAQ,aAAa,aAAa;AAAA,MAAA,IAG/B;AAAA,QACL,MAAM,GAAG,SAAS,CAAC;AAAA,QACnB,KAAK,GAAG,SAAS,CAAC;AAAA,QAClB,WAAW;AAAA,QACX,OAAO,GAAG,IAAI;AAAA,QACd,QAAQ,aAAa,aAAa;AAAA,MAAA;AAAA,MAWlC,UAAAA,2BAAAA,IAAC,SAAI,KAAK,UAAU,UAAU,KAAI,aAAY,WAAW,GAAA,CAAO;AAAA,IAAA;AAAA,EAAA;AAGtE;AAUO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,CAAC,UAAU,WAAW,IAAIE,MAAAA,SAAS,UAAU,YAAY,EAAE,GAC3D,CAAC,UAAU,WAAW,IAAIA,MAAAA,SAAwB,IAAI,GACtD,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAS,EAAK,GAChD,CAAC,SAAS,UAAU,IAAIA,MAAAA,SAAyB,IAAI,GACrD,uBAAuB+B,MAAAA,OAA8B,IAAI,GACzD,CAAC,MAAM,OAAO,IAAI/B,MAAAA;AAAAA,IACtB,UAAU,mBAAmB,WAAW;AAAA,EAAA,GAGpC,gBAAgB+B,MAAAA,OAAO,EAAK,GAE5B,mBAAmB,CAAC,cACjB,UAAU,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM,KAAK,UAAU,SAAS,OAAO,GAGzF,cAAcZ,MAAAA;AAAAA,IAClB,CAAC,QAAgB;AAKf,UAJI,qBAAqB,WACvB,aAAa,qBAAqB,OAAO,GAGvC,CAAC,KAAK;AACR,oBAAY,IAAI,GAChB,WAAW,IAAI,GACf,gBAAgB,EAAK,GACrB,qBAAqB,IAAI,GACzB,cAAc,UAAU,IACxB,SAAS;AAAA,UACP,GAAG;AAAA,UACH,SAAS;AAAA,UACT,UAAU;AAAA,UACV,kBAAkB;AAAA,QAAA,CACnB;AACD;AAAA,MACF;AAEA,sBAAgB,EAAI,GACpB,WAAW,IAAI,GACf,YAAY,IAAI,GAEhB,qBAAqB,UAAU,WAAW,MAAM;AAC9C,YAAI;AAEF,gBAAM,WADS,IAAI,IAAI,GAAG,EACF,SAAS,YAAA;AACjC,cAAI,iBAAiB,QAAQ,GAAG;AAC9B,uBAAW,EAAI,GACf,YAAY,IAAI,GAChB,qBAAqB,IAAI;AACzB,kBAAM,MAAM,IAAI,MAAA;AAChB,gBAAI,SAAS,MAAM;AACjB,oBAAM,mBACJ,IAAI,gBAAgB,IAAI,gBAAgB,IAAI,eAAe,IAAI,gBAAgB;AACjF,4BAAc,UAAU,IACxB,SAAS;AAAA,gBACP,GAAG;AAAA,gBACH,SAAS;AAAA,gBACT,UAAU;AAAA,gBACV;AAAA,cAAA,CACD;AAAA,YACH,GACA,IAAI,UAAU,MAAM;AAClB,4BAAc,UAAU,IACxB,SAAS;AAAA,gBACP,GAAG;AAAA,gBACH,SAAS;AAAA,gBACT,UAAU;AAAA,gBACV,kBAAkB,UAAU;AAAA,cAAA,CAC7B;AAAA,YACH,GACA,IAAI,MAAM;AAAA,UACZ,OAAO;AACL,kBAAM,WACJ;AACF,uBAAW,EAAK,GAChB,YAAY,QAAQ,GACpB,qBAAqB,QAAQ,GAC7B,cAAc,UAAU,IACxB,SAAS;AAAA,cACP,GAAG;AAAA,cACH,SAAS;AAAA,cACT,UAAU;AAAA,cACV,kBAAkB;AAAA,cAClB,kBAAkB;AAAA,YAAA,CACnB;AAAA,UACH;AAAA,QACF,QAAQ;AACN,qBAAW,EAAK;AAChB,gBAAM,WAAW;AACjB,sBAAY,QAAQ,GACpB,qBAAqB,QAAQ,GAC7B,cAAc,UAAU,IACxB,SAAS;AAAA,YACP,GAAG;AAAA,YACH,SAAS;AAAA,YACT,UAAU;AAAA,YACV,kBAAkB;AAAA,YAClB,kBAAkB;AAAA,UAAA,CACnB;AAAA,QACH,UAAA;AACE,0BAAgB,EAAK;AAAA,QACvB;AAAA,MACF,GAAG,GAAG;AAAA,IACR;AAAA,IACA,CAAC,WAAW,UAAU,kBAAkB;AAAA,EAAA;AAG1CgB,QAAAA,UAAU,MACD,MAAM;AACP,yBAAqB,WACvB,aAAa,qBAAqB,OAAO;AAAA,EAE7C,GACC,CAAA,CAAE,GAELA,MAAAA,UAAU,MAAM;AACd,YAAQ,UAAU,mBAAmB,WAAW,QAAQ;AAAA,EAC1D,GAAG,CAAC,UAAU,gBAAgB,CAAC;AAE/B,QAAM,kBAAkB,CAAC,MAA2C;AAClE,UAAM,MAAM,EAAE,OAAO;AACrB,gBAAY,GAAG,GAEX,UAAU,YAAY,QAAQ,UAAU,aAC1C,cAAc,UAAU,IACxB,SAAS;AAAA,MACP,GAAG;AAAA,MACH,SAAS;AAAA,MACT,UAAU;AAAA,MACV,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,IAAA,CACnB,IAGH,YAAY,GAAG;AAAA,EACjB,GAEM,uBAAuB,CAAC,UAA8B;AAC1D,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,UAAU,MAAM,KAAA;AACtB,QAAI,CAAC,QAAQ,SAAS,GAAG,EAAG,QAAO;AACnC,UAAM,IAAI,OAAO,QAAQ,MAAM,GAAG,EAAE,CAAC;AACrC,WAAK,OAAO,SAAS,CAAC,IAElB,MAAM,KAAK,OAAO,GAAG,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC,IAD7B,OACiD,UAC1D,GAAG,CAAC,MAHqB;AAAA,EAIlC,GAEM,wBAAwB,CAAC,SAAsC;AAWnE,UAAM,SAA6B;AAAA,MACjC,GAXW,UAAU,oBACkB;AAAA,QACvC,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,QACjB,kBAAkB;AAAA,QAClB,mBAAmB;AAAA,QACnB,OAAO,GAAG,UAAU,QAAQ,EAAE;AAAA,QAC9B,SAAS,GAAG,KAAK,OAAO,UAAU,WAAW,OAAO,GAAG,CAAC;AAAA,MAAA;AAAA,MAKxD,GAAG;AAAA,IAAA;AAGL,aAAS;AAAA,MACP,GAAG;AAAA,MACH,SAAS;AAAA,MACT,kBAAkB;AAAA,QAChB,GAAG;AAAA,QACH,mBACE,qBAAqB,OAAO,iBAAiB,KAAK,OAAO;AAAA,QAC3D,iBAAiB,qBAAqB,OAAO,eAAe,KAAK,OAAO;AAAA,MAAA;AAAA,IAC1E,CACD;AAAA,EACH,GAEM,qBAAqB,MAAM;AAC/B,UAAM,YAAY,qBAAqB;AACvC,QAAI,CAAC,UAAW,QAAO,EAAC,GAAG,GAAG,GAAG,GAAG,OAAO,GAAG,QAAQ,EAAA;AAEtD,UAAM,OAAO,UAAU,yBACjB,aAAa,KAAK,OAClB,aAAa,KAAK,QAElB,UAAU,iBAAiB,SAC3B,SAAS,SAAS,cAAc,GAChC,SAAS,SAAS,eAAe;AAEvC,QAAI,CAAC,UAAU,CAAC,UAAU,CAAC,cAAc,CAAC;AACxC,aAAO,EAAC,GAAG,GAAG,GAAG,GAAG,OAAO,YAAY,QAAQ,WAAA;AAGjD,UAAM,QAAQ,KAAK,IAAI,aAAa,QAAQ,aAAa,MAAM,GACzD,WAAW,SAAS,OACpB,WAAW,SAAS,OACpB,WAAW,aAAa,YAAY,GACpC,WAAW,aAAa,YAAY;AAE1C,WAAO,EAAC,GAAG,SAAS,GAAG,SAAS,OAAO,UAAU,QAAQ,SAAA;AAAA,EAC3D;AAEA,SACE9B,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,IAAAE,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,MAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,UAAS,UAAA,uBAE/B;AAAA,qCACCA,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,iGAGrB;AAAA,MACAF,gCAACwB,GAAAA,OAAI,OAAO,EAAC,UAAU,YAAY,OAAO,UACxC,UAAA;AAAA,QAAA/B,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU;AAAA,YACV,aAAY;AAAA,YACZ,OAAO;AAAA,cACL,SAAS;AAAA,cACT,cACM,WAAiB,SACjB,YAAY,OAAa,SACtB;AAAA,cAET,QACM,YAAY,YAAY,KAAc,sBACtC,YAAY,KAAa,sBACtB;AAAA,cAET,cAAc;AAAA,cACd,OAAO;AAAA,cACP,UAAU;AAAA,cACV,WAAW;AAAA,cACX,UAAU;AAAA,YAAA;AAAA,UACZ;AAAA,QAAA;AAAA,SAEA,YAAY,gBAAgB,YAAY,SACxCO,2BAAAA;AAAAA,UAACwB,GAAAA;AAAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,KAAK;AAAA,cACL,WAAW;AAAA,cACX,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,KAAK;AAAA,YAAA;AAAA,YAGN,UAAA;AAAA,cAAA,YACC/B,2BAAAA;AAAAA,gBAACM,GAAAA;AAAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,MAAK;AAAA,kBACL,MAAK;AAAA,kBACL,SAAS,MAAM;AACb,gCAAY,EAAE,GACd,YAAY,EAAE;AAAA,kBAChB;AAAA,kBACA,UAAU;AAAA,kBACV,OAAO,EAAC,UAAU,QAAQ,QAAQ,OAAA;AAAA,gBAAM;AAAA,cAAA;AAAA,cAG3C,gBACCN,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,iBAErB;AAAA,cAED,YAAY,MAAQ,CAAC,gBACpBT,2BAAAA,IAAC4D,MAAAA,qBAAA,EAAoB,OAAO,EAAC,OAAO,WAAW,UAAU,OAAA,EAAM,CAAG;AAAA,cAEnE,YAAY,MAAS,CAAC,gBACrB5D,2BAAAA,IAACuD,MAAAA,kBAAA,EAAiB,OAAO,EAAC,OAAO,WAAW,UAAU,OAAA,EAAM,CAAG;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAEnE,GAEJ;AAAA,MACC,YACCvD,2BAAAA,IAACQ,SAAA,EAAK,SAAS,GAAG,MAAK,YAAW,QAAQ,GACxC,UAAAD,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,QAAA9B,+BAACuD,MAAAA,oBAAiB,OAAO,EAAC,OAAO,WAAW,YAAY,KAAI;AAAA,QAC5DvD,2BAAAA,IAACS,GAAAA,QAAK,MAAM,GAAG,OAAO,EAAC,OAAO,UAAA,GAC3B,UAAA,SAAA,CACH;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,IAAA,GAEJ;AAAA,IAEC,UAAU,YACTF,gCAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,MAAAL,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,SAAS,GAAG,MAAK,eAAc,QAAM,IAAC,QAAQ,GAClD,UAAAD,2BAAAA;AAAAA,QAACuB,GAAAA;AAAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,SAAQ;AAAA,UACR,KAAK;AAAA,UACL,OAAO,EAAC,UAAU,QAAQ,YAAY,aAAA;AAAA,UAEtC,UAAA;AAAA,YAAAvB,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GAAG,OAAO,EAAC,UAAU,KAAK,MAAM,EAAA,GAC5C,UAAA;AAAA,cAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,UAAS,UAAA,oBAE/B;AAAA,cACAF,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA;AAAA,gBAAA;AAAA,gBAC+C;AAAA,gBAClET,2BAAAA,IAAC,UAAK,UAAA,mBAAA,CAAgB;AAAA,gBAAO;AAAA,gBAAe;AAAA,gBAC5CA,2BAAAA;AAAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,QAAO;AAAA,oBACP,KAAI;AAAA,oBACL,UAAA;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEG;AAAA,cAAA,EAAA,CAEN;AAAA,YAAA,GACF;AAAA,YACAO,gCAACuB,GAAAA,QAAK,KAAK,GAAG,OAAO,EAAC,UAAU,UAC9B,UAAA;AAAA,cAAA9B,2BAAAA;AAAAA,gBAACM,GAAAA;AAAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,MAAM,SAAS,WAAW,YAAY;AAAA,kBACtC,SAAS,MAAM;AACb,4BAAQ,QAAQ,GAChB,SAAS,EAAC,GAAG,WAAW,SAAS,IAAM,kBAAkB,QAAU;AAAA,kBACrE;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEFN,2BAAAA;AAAAA,gBAACM,GAAAA;AAAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,MAAM,SAAS,WAAW,YAAY;AAAA,kBACtC,SAAS,MAAM;AACb,4BAAQ,QAAQ;AAChB,0BAAM,UAAU,6BAA6B,EAAC,GAAG,WAAW,SAAS,IAAK;AAC1E,0CAAsB,WAAW,EAAE;AAAA,kBACrC;AAAA,gBAAA;AAAA,cAAA;AAAA,YACF,EAAA,CACF;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA,GAEJ;AAAA,MAEC,SAAS,YACRN,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,SAAS,GAAG,MAAK,eAAc,QAAM,IAAC,QAAQ,GAClD,UAAAD,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,QAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,UAAS,UAAA,wBAE/B;AAAA,QACAF,2BAAAA,KAACiH,GAAAA,MAAA,EAAK,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,OAAO,EAAC,OAAO,UAC5C,UAAA;AAAA,UAAAjH,gCAACF,GAAAA,SAAM,OAAO,GAAG,OAAO,EAAC,UAAU,KACjC,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,oBAErB;AAAA,YACAF,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAO,UAAU,kBAAkB,oBAAoB;AAAA,gBACvD,UAAU,CAAC,MACT,sBAAsB;AAAA,kBACpB,kBAAmB,EAAE,OAAO,SAC1B;AAAA,gBAAA,CACH;AAAA,gBAEH,OAAO;AAAA,kBACL,OAAO;AAAA,kBACP,SAAS;AAAA,kBACT,QAAQ;AAAA,kBACR,cAAc;AAAA,gBAAA;AAAA,gBAGhB,UAAA;AAAA,kBAAAP,2BAAAA,IAAC,UAAA,EAAO,OAAM,QAAO,UAAA,QAAI;AAAA,kBACzBA,2BAAAA,IAAC,UAAA,EAAO,OAAM,UAAS,UAAA,UAAM;AAAA,kBAC7BA,2BAAAA,IAAC,UAAA,EAAO,OAAM,SAAQ,UAAA,QAAA,CAAK;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UAC7B,GACF;AAAA,UACAO,gCAACF,GAAAA,SAAM,OAAO,GAAG,OAAO,EAAC,UAAU,KACjC,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,uCAErB;AAAA,YACAT,2BAAAA;AAAAA,cAACuC,GAAAA;AAAAA,cAAA;AAAA,gBACC,OAAO,UAAU,kBAAkB,qBAAqB;AAAA,gBACxD,UAAU,CAAC,MACT,sBAAsB,EAAC,mBAAmB,EAAE,cAAc,MAAA,CAAM;AAAA,cAAA;AAAA,YAAA;AAAA,UAEpE,GACF;AAAA,UACAhC,gCAACF,GAAAA,SAAM,OAAO,GAAG,OAAO,EAAC,UAAU,KACjC,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,kBAErB;AAAA,YACAF,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAO,UAAU,kBAAkB,kBAAkB;AAAA,gBACrD,UAAU,CAAC,MACT,sBAAsB;AAAA,kBACpB,gBAAiB,EAAE,OAAO,SACxB;AAAA,gBAAA,CACH;AAAA,gBAEH,OAAO;AAAA,kBACL,OAAO;AAAA,kBACP,SAAS;AAAA,kBACT,QAAQ;AAAA,kBACR,cAAc;AAAA,gBAAA;AAAA,gBAGhB,UAAA;AAAA,kBAAAP,2BAAAA,IAAC,UAAA,EAAO,OAAM,OAAM,UAAA,OAAG;AAAA,kBACvBA,2BAAAA,IAAC,UAAA,EAAO,OAAM,UAAS,UAAA,UAAM;AAAA,kBAC7BA,2BAAAA,IAAC,UAAA,EAAO,OAAM,UAAS,UAAA,SAAA,CAAM;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UAC/B,GACF;AAAA,UACAO,gCAACF,GAAAA,SAAM,OAAO,GAAG,OAAO,EAAC,UAAU,KACjC,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,qCAErB;AAAA,YACAT,2BAAAA;AAAAA,cAACuC,GAAAA;AAAAA,cAAA;AAAA,gBACC,OAAO,UAAU,kBAAkB,mBAAmB;AAAA,gBACtD,UAAU,CAAC,MACT,sBAAsB,EAAC,iBAAiB,EAAE,cAAc,MAAA,CAAM;AAAA,cAAA;AAAA,YAAA;AAAA,UAElE,GACF;AAAA,UACAhC,gCAACF,GAAAA,SAAM,OAAO,GAAG,OAAO,EAAC,UAAU,KACjC,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,4BAErB;AAAA,YACAT,2BAAAA;AAAAA,cAACuC,GAAAA;AAAAA,cAAA;AAAA,gBACC,OAAO,UAAU,kBAAkB,SAAS,GAAG,UAAU,QAAQ,EAAE;AAAA,gBACnE,UAAU,CAAC,MAAM,sBAAsB,EAAC,OAAO,EAAE,cAAc,MAAA,CAAM;AAAA,cAAA;AAAA,YAAA;AAAA,UACvE,GACF;AAAA,UACAhC,gCAACF,GAAAA,SAAM,OAAO,GAAG,OAAO,EAAC,UAAU,KACjC,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,sBAErB;AAAA,YACAT,2BAAAA;AAAAA,cAACuC,GAAAA;AAAAA,cAAA;AAAA,gBACC,OACE,UAAU,kBAAkB,WAC5B,GAAG,KAAK,OAAO,UAAU,WAAW,OAAO,GAAG,CAAC;AAAA,gBAEjD,UAAU,CAAC,MAAM,sBAAsB,EAAC,SAAS,EAAE,cAAc,MAAA,CAAM;AAAA,cAAA;AAAA,YAAA;AAAA,UACzE,EAAA,CACF;AAAA,QAAA,GACF;AAAA,uCACC9B,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,4EAAA,CAErB;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,MAGD,SAAS,YACRF,2BAAAA,KAAAsB,WAAAA,UAAA,EACE,UAAA;AAAA,QAAAtB,gCAACwB,GAAAA,KAAA,EACC,UAAA;AAAA,UAAA/B,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,UAClB,WAAA,MAAM;AACN,kBAAM,UAAU,UAAU,QAAQ,IAC5B,WAAW,qBAAqB;AACtC,mBAAK,WAEE,SADI,KAAK,IAAI,GAAG,KAAK,MAAO,UAAU,MAAO,QAAQ,CAAC,CAC3C,OAFI,SAAS,OAAO;AAAA,UAGxC,KAAG,CACL;AAAA,UACAT,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,QAAQ,MAAM;AACZ,sBAAM,UAAU,UAAU,QAAQ,IAC5B,WAAW,qBAAqB;AACtC,uBAAK,WACE,KAAK,IAAI,GAAG,KAAK,MAAO,UAAU,MAAO,QAAQ,CAAC,IADnC;AAAA,cAExB,GAAA;AAAA,cACA,MAAM,MAAM;AACV,sBAAM,WAAW,qBAAqB;AACtC,uBAAK,WACE,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,IAAI,CAAC,IADxB;AAAA,cAExB,GAAA;AAAA,cACA,MAAM,MAAM;AACV,sBAAM,WAAW,qBAAqB;AACtC,uBAAK,WACE,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,GAAG,CAAC,IADvB;AAAA,cAExB,GAAA;AAAA,cACA,MAAM;AAAA,cACN,UAAU,CAAC,MAAM;AACf,sBAAM,MAAM,OAAO,EAAE,OAAO,KAAK,GAC3B,WAAW,mBAAA,EAAqB,OAChC,UAAU,WAAY,MAAM,WAAY,MAAM,KAC9C,aAAa,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,CAAC;AACpD,yBAAS;AAAA,kBACP,GAAG;AAAA,kBACH,MAAM;AAAA,gBAAA,CACP;AAAA,cACH;AAAA,YAAA;AAAA,UAAA;AAAA,QACF,GACF;AAAA,wCAEC+B,GAAAA,KAAA,EACC,UAAA;AAAA,UAAAxB,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,UAAS,UAAA;AAAA,YAAA;AAAA,YACnB,KAAK,OAAO,UAAU,WAAW,OAAO,GAAG;AAAA,YAAE;AAAA,UAAA,GACzD;AAAA,UACAT,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAO,UAAU,WAAW;AAAA,cAC5B,KAAK;AAAA,cACL,KAAK;AAAA,cACL,MAAM;AAAA,cACN,UAAU,CAAC,MACT,SAAS;AAAA,gBACP,GAAG;AAAA,gBACH,SAAS,OAAO,EAAE,OAAO,KAAK;AAAA,cAAA,CAC/B;AAAA,YAAA;AAAA,UAAA;AAAA,QAEL,EAAA,CACF;AAAA,MAAA,GACF;AAAA,MAGFA,2BAAAA,IAACQ,GAAAA,QAAK,SAAS,GAAG,MAAK,eAAc,QAAM,IAAC,QAAQ,GAClD,yCAACC,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IACjB,mBAAS,WACN,wDACA,8DACN,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;ACn2BA,MAAM,qBAAqBgE,uBAAAA,QAAc,YAAA,EAAc,IAAI,CAAC,UAAU;AAAA,EACpE,OAAO;AAAA,EACP,OAAOA,uBAAAA,QAAc,cAAc,IAAI;AACzC,EAAE,GAEI,qBAGF;AAAA,EACF,eAAe,wBAAwB,IAAI,CAAC,UAAU;AAAA,IACpD,OAAO,KAAK;AAAA,IACZ,OAAO,KAAK;AAAA,EAAA,EACZ;AAAA,EACF,WAAW;AAAA,EACX,UAAU;AACZ;AASA,SAAwB,iBAAiB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACF,GAQG;AACD,QAAM,QAAQ,OAAO,CAAC;AACtB,wCACGnC,OAAAA,WAAA,EAAU,OAAM,sCACf,UAAA/B,2BAAAA,KAACF,UAAA,EAAM,OAAO,GACZ,UAAA;AAAA,IAAAE,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UACV,UAAA;AAAA,MAAA9B,2BAAAA;AAAAA,QAACwC,GAAAA;AAAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,OAAO,EAAC,SAAS,QAAA;AAAA,UACjB,SAAS,CAAC,CAAC,OAAO;AAAA,UAClB,UAAU,MAAM;AAEZ,qBADE,QACO,EAAC,QAAQ,SAAS,IAAI,MAAM,KAAK,WAAW,aAE5C;AAAA,cACP,QAAQ;AAAA,cACR,IAAIW,KAAAA,KAAA;AAAA,cACJ,WAAW;AAAA,cACX,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,MAAM,eAAe;AAAA,gBACrB,eAAe,eAAe;AAAA,cAAA;AAAA,YAChC,CAV4D;AAAA,UAalE;AAAA,QAAA;AAAA,MAAA;AAAA,MAEFnD,+BAAC+B,GAAAA,KAAA,EAAI,MAAM,GAAG,aAAa,GACzB,UAAA/B,2BAAAA,IAACS,GAAAA,MAAA,EACC,UAAAT,2BAAAA,IAAC,SAAA,EAAM,SAAQ,YAAW,UAAA,qBAAiB,GAC7C,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IACC,SACCA,2BAAAA;AAAAA,MAAC4E,GAAAA;AAAAA,MAAA;AAAA,QACC,IAAI;AAAA,QACJ,OAAO,MAAM;AAAA,QACb,UAAU,CAAC,aACT,SAAS;AAAA,UACP,QAAQ;AAAA,UACR,IAAI,MAAM;AAAA,UACV,WAAW;AAAA,UACX,OAAO;AAAA,YACL,eAAe;AAAA,YACf,MAAMH,uBAAAA,QAAc,cAAc,QAAQ;AAAA,UAAA;AAAA,QAC5C,CACD;AAAA,QAEH,SAAS,mBAAmB,MAAM,IAAK;AAAA,QACvC,MAAMI,MAAAA;AAAAA,QACN,aAAY;AAAA,QACZ,cAAc,CAAC,OAAO,WACpB,OAAO,MAAM,YAAA,EAAc,QAAQ,MAAM,YAAA,CAAa,IAAI,MAC1D,OAAO,MAAM,YAAA,EAAc,QAAQ,MAAM,YAAA,CAAa,IAAI;AAAA,QAE5D,YAAU;AAAA,QACV,aAAa,CAAC,UACZ,mBAAmB,MAAM,IAAK,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK,GAAG,SAAS;AAAA,QAE3E,cAAc,CAAC,0CACZrE,GAAAA,MAAA,EAAK,WAAQ,UAAS,SAAS,GAAG,QAAQ,GAAG,MAAK,WACjD,UAAAD,2BAAAA,KAACE,GAAAA,QAAK,MAAM,GAAG,cAAa,YACzB,UAAA;AAAA,UAAA,OAAO;AAAA,UAAM;AAAA,UAAG,OAAO;AAAA,UAAM;AAAA,QAAA,EAAA,CAChC,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAEJ,EAAA,CAEJ,EAAA,CACF;AAEJ;AC/GA,SAAwB,qBAAqB;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAQG;AACD,QAAM,CAAC,OAAO,QAAQ,IAAIP,MAAAA,SAAS,CAAC,GAE9B,WAA0B;AAAA,IAC9B,SAAS;AAAA,IACT,WAAW,SAAS,KAAK;AAAA,IACzB,YAAY;AAAA,IACZ,QAAQ,WAAW,gBAAgB;AAAA,IACnC,cAAc;AAAA,EAAA,GAGV,mBAAmB,MAAM;AAC7B,aAAS,IAAI,GACb,WAAW,MAAM;AACf,eAAS,CAAC;AAAA,IACZ,GAAG,GAAG;AAAA,EACR;AAmBA,SACEF,2BAAAA,IAAC,WACC,UAAAO,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,KAAK,GAAG,SAAS,GAAG,OAAO,UAC/B,UAAA;AAAA,IAAA9B,2BAAAA;AAAAA,MAACwC,GAAAA;AAAAA,MAAA;AAAA,QACC;AAAA,QACA,UAAQ;AAAA,QACR;AAAA,QACA,UAxBe,MAAM;AACtB,qBACL,iBAAA,GACA,SAAS;AAAA,YACP;AAAA,YACA,OAAO,CAAC;AAAA,UAAA,CACT;AAAA,QACH;AAAA,QAkBQ;AAAA,MAAA;AAAA,IAAA;AAAA,IAEFjC,2BAAAA,KAACiH,GAAAA,MAAA,EAAK,KAAK,GACT,UAAA;AAAA,MAAAxH,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,QACnB,UAAA,YACH;AAAA,MApBN,OAAO,eAAgB,WACrBT,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IACjB,UAAA,YAAA,CACH,IAEA;AAAA,IAAA,EAAA,CAiBE;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;ACvEA,SAAwB,wBAAwB;AAc9C,SACET,2BAAAA,IAAC+B,GAAAA,KAAA,EAAI,SAAS,GAAG,OATa;AAAA,IAC9B,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,cAAc;AAAA,IACd,OAAO;AAAA,IACP,OAAO;AAAA,EAAA,GAKL,UAAAxB,2BAAAA,KAACuB,SAAA,EAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,IAAA9B,2BAAAA,IAACmK,MAAAA,mBAAA,EAAkB;AAAA,IACnBnK,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAjBY;AAAA,MAC/B,OAAO;AAAA,MACP,YAAY;AAAA,IAAA,GAeyB,UAAA,6CAAA,CAEjC;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;ACpBA,SAAwB,eAAe;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,mBAAmB,EAAE,OAAO,iBAAiB,OAAO,iBAAiB,OAAO,aAC5E,oBAAoB,CAAC,QAAQ;AACnC,SACEF,2BAAAA,KAACiH,GAAAA,MAAA,EAAK,KAAK,GACT,UAAA;AAAA,IAAAxH,2BAAAA,IAACS,GAAAA,MAAA,EAAK,QAAO,QAAO,UAAA,8BAA0B;AAAA,IAC9CT,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAI,GAAG,EAAE;AAAA,QACT,SAAS,OAAO;AAAA,QAChB,YAAW;AAAA,QACX,aACEO,2BAAAA,KAAAsB,qBAAA,EACE,UAAA;AAAA,UAAA7B,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,+DAErB;AAAA,UACAT,2BAAAA,IAACyC,GAAAA,QAAM,UAAA,uCAAA,CAAuC;AAAA,QAAA,GAChD;AAAA,QAEF;AAAA,QACA,QAAO;AAAA,MAAA;AAAA,IAAA;AAAA,IAER,QAAQ,oBACPzC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAI,GAAG,EAAE;AAAA,QACT,SAAS,OAAO;AAAA,QAChB,YAAW;AAAA,QACX,aACEO,2BAAAA,KAAAsB,qBAAA,EACE,UAAA;AAAA,UAAA7B,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,2CAErB;AAAA,UACAT,2BAAAA,IAACyC,GAAAA,QAAM,UAAA,qDAAA,CAAqD;AAAA,UAC5DlC,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA;AAAA,YAAA;AAAA,YACf;AAAA,YACJT,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,QAAO;AAAA,gBACP,KAAI;AAAA,gBACL,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAEI;AAAA,YAAI;AAAA,UAAA,EAAA,CAEX;AAAA,QAAA,GACF;AAAA,QAGF;AAAA,QACA,QAAO;AAAA,MAAA;AAAA,IAAA;AAAA,IAGV,oBACCA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAI,GAAG,EAAE;AAAA,QACT,SAAS;AAAA,QACT,YAAW;AAAA,QACX,aACEA,2BAAAA,IAAA6B,qBAAA,EACE,UAAAtB,2BAAAA,KAACE,WAAK,MAAM,GAAG,OAAK,IAAC,UAAA;AAAA,UAAA;AAAA,UAED;AAAA,UAClBT,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,QAAO;AAAA,cACP,KAAI;AAAA,cACL,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAEI;AAAA,UAAI;AAAA,QAAA,EAAA,CAEX,EAAA,CACF;AAAA,QAEF;AAAA,QACA,UAAQ;AAAA,MAAA;AAAA,IAAA,IAGVA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAI,GAAG,EAAE;AAAA,QACT,SAAS,OAAO;AAAA,QAChB,YAAW;AAAA,QACX,aACEO,2BAAAA,KAAAsB,qBAAA,EACE,UAAA;AAAA,UAAA7B,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA,qGAGrB;AAAA,UACAT,2BAAAA,IAACyC,GAAAA,QAAM,UAAA,qDAAA,CAAqD;AAAA,UAC5DlC,2BAAAA,KAACE,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA;AAAA,YAAA;AAAA,YACf;AAAA,YACJT,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,QAAO;AAAA,gBACP,KAAI;AAAA,gBACL,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAEI;AAAA,YAAI;AAAA,YACsD;AAAA,YAC/DA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,QAAO;AAAA,gBACP,KAAI;AAAA,gBACL,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAEI;AAAA,YAAI;AAAA,UAAA,EAAA,CAEX;AAAA,QAAA,GACF;AAAA,QAEF;AAAA,QACA,QAAO;AAAA,MAAA;AAAA,IAAA;AAAA,IAGV,mDAAqB,uBAAA,CAAA,CAAsB;AAAA,EAAA,GAC9C;AAEJ;AC7HO,MAAM,mBAAmB;AAAA,EAC9B,EAAC,OAAO,SAAS,OAAO,QAAA;AAAA,EACxB,EAAC,OAAO,SAAS,OAAO,aAAA;AAAA,EACxB,EAAC,OAAO,SAAS,OAAO,aAAA;AAC1B,GAEa,yBAAyB,CAAC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAOIA,2BAAAA;AAAAA,EAACsC,OAAAA;AAAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,aACE/B,2BAAAA,KAAAsB,qBAAA,EAAE,UAAA;AAAA,MAAA;AAAA,MACY;AAAA,MACZ7B,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,KAAI;AAAA,UACL,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAEI;AAAA,MAAI;AAAA,IAAA,GAEX;AAAA,IAGF,UAAAA,2BAAAA,IAAC8B,GAAAA,MAAA,EAAK,KAAK,GAAG,MAAM,QACjB,UAAA,iBAAiB,IAAI,CAAC,EAAC,OAAO,MAAA,GAAQ,UAAU;AAC/C,YAAM,UAAU,GAAG,EAAE,UAAU,KAAK;AAEpC,aAAI,QAAQ,yBAA+B,OAGzCvB,gCAACuB,GAAAA,QAAiB,OAAM,UAAS,KAAK,GACpC,UAAA;AAAA,QAAA9B,2BAAAA;AAAAA,UAACiE,GAAAA;AAAAA,UAAA;AAAA,YACC,SAAS,OAAO,wBAAwB;AAAA,YACxC,MAAK;AAAA,YACL,UAAU,CAAC,MACT,SAAS;AAAA,cACP,QAAQ;AAAA,cACR,OAAO,EAAE,cAAc;AAAA,YAAA,CACxB;AAAA,YAEH;AAAA,YACA,IAAI;AAAA,UAAA;AAAA,QAAA;AAAA,uCAELxD,GAAAA,MAAA,EAAK,IAAG,SAAQ,SAAS,SACvB,UAAA,MAAA,CACH;AAAA,MAAA,EAAA,GAfS,KAgBX;AAAA,IAEJ,CAAC,EAAA,CACH;AAAA,EAAA;AACF,GC7DE,uBAA4E;AAAA,EAChF,EAAC,OAAO,QAAQ,OAAO,OAAA;AAAA,EACvB,EAAC,OAAO,QAAQ,OAAO,OAAA;AAAA,EACvB,EAAC,OAAO,QAAQ,OAAO,OAAA;AAAA,EACvB,EAAC,OAAO,QAAQ,OAAO,OAAA;AAAA,EACvB,EAAC,OAAO,QAAQ,OAAO,OAAA;AAAA,EACvB,EAAC,OAAO,SAAS,OAAO,QAAA;AAAA,EACxB,EAAC,OAAO,SAAS,OAAO,QAAA;AAAA,EACxB,EAAC,OAAO,SAAS,OAAO,QAAA;AAC1B,GAEa,0BAA0B,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,MAIM;AAEJ,QAAM,iBAAiBS,MAAAA,QAAQ,MACD,OAAO,kBAAkB;AAAA,IACnD,CAAC,MAAM,MAAM,aAAa,MAAM;AAAA,EAAA,EAEP,SAAS,GACnC,CAAC,OAAO,iBAAiB,CAAC,GAEvB,CAAC,eAAe,gBAAgB,IAAIhB,MAAAA;AAAAA,IACxC,iBAAiB,aAAa;AAAA,EAAA,GAI1B,kBAAkB,CAAC,cAAyC;AAChE,UAAM,UAAU,OAAO,mBACjB,eAAe,QAAQ,SAAS,SAAS;AAG7C,aADE,eACO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO,QAAQ,OAAO,CAAC,MAAM,MAAM,SAAS;AAAA,IAAA,IAGrC;AAAA,MACP,QAAQ;AAAA,MACR,OAAO,CAAC,GAAG,SAAS,SAAS;AAAA,IAAA,CAJ9B;AAAA,EAOL,GAGM,mBAAmB,CAAC,SAAkC;AAC1D,qBAAiB,IAAI,GAGnB,SAFE,SAAS,aAEF;AAAA,MACP,QAAQ;AAAA,MACR,OAAO,OAAO,kBAAkB,OAAO,CAAC,MAAM,MAAM,aAAa,MAAM,YAAY;AAAA,IAAA,IAI5E;AAAA,MACP,QAAQ;AAAA,MACR,OAAO,OAAO,kBAAkB,OAAO,CAAC,MAAM,MAAM,SAAS;AAAA,IAAA,CAL9D;AAAA,EAQL;AACA,SACEF,2BAAAA,IAACK,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAAL,2BAAAA;AAAAA,IAACsC,OAAAA;AAAAA,IAAA;AAAA,MACC,OAAM;AAAA,MACN,aAAY;AAAA,MAEZ,UAAA/B,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GAEZ,UAAA;AAAA,QAAAE,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,KAAK,GACT,UAAA;AAAA,UAAAvB,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,YAAA9B,2BAAAA;AAAAA,cAACiE,GAAAA;AAAAA,cAAA;AAAA,gBACC,SAAS,kBAAkB;AAAA,gBAC3B,MAAK;AAAA,gBACL,UAAU,MAAM,iBAAiB,UAAU;AAAA,gBAC3C,OAAM;AAAA,gBACN,IAAI,GAAG,EAAE;AAAA,cAAA;AAAA,YAAA;AAAA,YAEXjE,2BAAAA,IAACS,GAAAA,QAAK,IAAG,SAAQ,SAAS,GAAG,EAAE,mBAAmB,UAAA,WAAA,CAElD;AAAA,UAAA,GACF;AAAA,UACAF,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,YAAA9B,2BAAAA;AAAAA,cAACiE,GAAAA;AAAAA,cAAA;AAAA,gBACC,SAAS,kBAAkB;AAAA,gBAC3B,MAAK;AAAA,gBACL,UAAU,MAAM,iBAAiB,UAAU;AAAA,gBAC3C,OAAM;AAAA,gBACN,IAAI,GAAG,EAAE;AAAA,cAAA;AAAA,YAAA;AAAA,YAEXjE,2BAAAA,IAACS,GAAAA,QAAK,IAAG,SAAQ,SAAS,GAAG,EAAE,mBAAmB,UAAA,WAAA,CAElD;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,GACF;AAAA,QAGC,kBAAkB,cACjBF,gCAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAE,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,GACzC,UAAA;AAAA,YAAA9B,2BAAAA;AAAAA,cAACwC,GAAAA;AAAAA,cAAA;AAAA,gBACC,IAAI,GAAG,EAAE;AAAA,gBACT,OAAO,EAAC,SAAS,QAAA;AAAA,gBACjB,SAAS,OAAO,kBAAkB,SAAS,SAAS;AAAA,gBACpD,UAAU,MAAM,gBAAgB,SAAS;AAAA,cAAA;AAAA,YAAA;AAAA,YAE3CxC,2BAAAA,IAACS,GAAAA,QAAK,IAAG,SAAQ,SAAS,GAAG,EAAE,aAAa,UAAA,gCAAA,CAE5C;AAAA,UAAA,GACF;AAAA,UACAF,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,GACzC,UAAA;AAAA,YAAA9B,2BAAAA;AAAAA,cAACwC,GAAAA;AAAAA,cAAA;AAAA,gBACC,IAAI,GAAG,EAAE;AAAA,gBACT,OAAO,EAAC,SAAS,QAAA;AAAA,gBACjB,SAAS,OAAO,kBAAkB,SAAS,YAAY;AAAA,gBACvD,UAAU,MAAM,gBAAgB,YAAY;AAAA,cAAA;AAAA,YAAA;AAAA,YAE9CxC,2BAAAA,IAACS,GAAAA,QAAK,IAAG,SAAQ,SAAS,GAAG,EAAE,yBAAyB,UAAA,mBAAA,CAExD;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,GACF;AAAA,QAID,kBAAkB,cACjBF,gCAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,UAAAL,+BAAC+D,GAAAA,OAAA,EAAM,MAAM,GAAG,OAAK,IAAC,UAAA,gCAEtB;AAAA,UACA/D,2BAAAA,IAAC8B,GAAAA,MAAA,EAAK,KAAK,GAAG,MAAK,QAChB,UAAA,qBAAqB,IAAI,CAAC,EAAC,OAAO,MAAA,MAAW;AAC5C,kBAAM,UAAU,GAAG,EAAE,gBAAgB,KAAK;AAC1C,mBACEvB,2BAAAA,KAACuB,GAAAA,MAAA,EAAiB,OAAM,UAAS,KAAK,GACpC,UAAA;AAAA,cAAA9B,2BAAAA;AAAAA,gBAACwC,GAAAA;AAAAA,gBAAA;AAAA,kBACC,IAAI;AAAA,kBACJ,OAAO,EAAC,SAAS,QAAA;AAAA,kBACjB,SAAS,OAAO,kBAAkB,SAAS,KAAK;AAAA,kBAChD,UAAU,MAAM,gBAAgB,KAAK;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEvCxC,2BAAAA,IAACS,GAAAA,QAAK,IAAG,SAAQ,SAAS,SAAS,MAAM,GACtC,UAAA,MAAA,CACH;AAAA,YAAA,EAAA,GATS,KAUX;AAAA,UAEJ,CAAC,EAAA,CACH;AAAA,UACAF,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,KAAK,GAAG,SAAS,CAAC,GAAG,GAAG,GAAG,CAAC,GAC/C,UAAA;AAAA,YAAA9B,2BAAAA;AAAAA,cAACwC,GAAAA;AAAAA,cAAA;AAAA,gBACC,IAAI,GAAG,EAAE;AAAA,gBACT,OAAO,EAAC,SAAS,QAAA;AAAA,gBACjB,SAAS,OAAO,kBAAkB,SAAS,YAAY;AAAA,gBACvD,UAAU,MAAM,gBAAgB,YAAY;AAAA,cAAA;AAAA,YAAA;AAAA,YAE9CxC,2BAAAA,IAACS,GAAAA,QAAK,IAAG,SAAQ,SAAS,GAAG,EAAE,yBAAyB,UAAA,mBAAA,CAExD;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ,GCnIM,uBAAuB;AAAA,EAC3B,EAAC,OAAO,SAAS,OAAO,QAAA;AAAA,EACxB,EAAC,OAAO,QAAQ,OAAO,OAAA;AAAA,EACvB,EAAC,OAAO,WAAW,OAAO,UAAA;AAC5B;AAMA,SAAS,yBACP,YAC6B;AAC7B,QAAM,aAAa,WAAW,SAAS,SAAS,GAC1C,yBAAyB,WAAW,KAAK,CAAC,MAAM,MAAM,aAAa,MAAM,YAAY;AAE3F,SAAI,cAAc,yBACT,WAAW,OAAO,CAAC,MAAM,MAAM,aAAa,MAAM,YAAY,IAGhE;AACT;AAQA,SAAwB,oBAAoB;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,QAAM,KAAKiB,MAAAA,SACL,CAAC,0BAA0B,2BAA2B,IAAIxB,MAAAA,SAAwB,IAAI,GACtF,+BAA+B+B,MAAAA,OAAuB,IAAI,GAC1D,2BAA2BA,MAAAA,OAAyB,IAAI,GACxD,iBAAiBA,MAAAA;AAAAA,IACrB,aAAa,kBAAkB,UAAU,aAAa,mCAClD;AAAA,MACE;AAAA,QACE,KAAKkB,KAAAA,KAAA;AAAA,QACL,MAAM;AAAA,QACN,eAAe,aAAa;AAAA,QAC5B,MAAMsB,uBAAAA,QAAc,cAAc,aAAa,gCAAgC;AAAA,MAAA;AAAA,IACjF,IAEF,CAAA;AAAA,EAAC,EACL,SAEI,CAAC,QAAQ,QAAQ,IAAIjD,MAAAA;AAAAA,IACzB,CAAC,MAAoB,WAA2C;AAC9D,cAAQ,OAAO,QAAA;AAAA,QACb,KAAK;AAEH,iBAAI,OAAO,UAAU,UACZ,OAAO,OAAO,CAAA,GAAI,MAAM;AAAA,YAC7B,eAAe,OAAO;AAAA,YACtB,mBAAmB,CAAA;AAAA,YACnB,qBAAqB;AAAA,YACrB,aAAa,KAAK,aAAa,OAAO,CAAC,EAAC,KAAA,MAAU,SAAS,eAAe;AAAA,YAC1E,eAAe;AAAA,YACf,eAAe;AAAA,YACf,YAAY;AAAA,UAAA,CACb,IAGI,OAAO,OAAO,CAAA,GAAI,MAAM;AAAA,YAC7B,eAAe,OAAO;AAAA,YACtB,mBAAmB,yBAAyB,aAAa,qBAAqB,CAAA,CAAE;AAAA,YAChF,qBAAqB,aAAa;AAAA,YAClC,aAAa,CAAC,GAAG,gBAAgB,GAAI,KAAK,eAAe,CAAA,CAAG;AAAA,UAAA,CAC7D;AAAA,QAEH,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH,iBAAO,OAAO,OAAO,CAAA,GAAI,MAAM,EAAC,CAAC,OAAO,MAAM,GAAG,OAAO,OAAM;AAAA,QAChE,KAAK;AACH,iBAAO,OAAO,OAAO,CAAA,GAAI,MAAM,EAAC,CAAC,OAAO,MAAM,GAAG,OAAO,OAAM;AAAA,QAChE,KAAK;AACH,iBAAO,OAAO,OAAO,CAAA,GAAI,MAAM,EAAC,CAAC,OAAO,MAAM,GAAG,OAAO,OAAM;AAAA,QAChE,KAAK;AACH,iBAAO,OAAO,OAAO,IAAI,MAAM,EAAC,WAAW,OAAO,OAAM;AAAA;AAAA,QAE1D,KAAK,SAAS;AACZ,gBAAM,cAAc,CAAC,GAAG,KAAK,WAAW,GAClC,iBAAiB,YAAY,UAAU,CAAC,EAAC,KAAA4I,KAAA,MAASA,SAAQ,OAAO,EAAE;AAEzE,kBAAQ,OAAO,WAAA;AAAA,YACb,KAAK;AAEH,kBAAI,mBAAmB,GAAI;AAC3B,0BAAY,KAAK;AAAA,gBACf,KAAK,OAAO;AAAA,gBACZ,GAAG,OAAO;AAAA,cAAA,CACe;AAC3B;AAAA,YACF,KAAK;AACH,kBAAI,mBAAmB,GAAI;AAC3B,0BAAY,cAAc,IAAI;AAAA,gBAC5B,GAAG,YAAY,cAAc;AAAA,gBAC7B,GAAG,OAAO;AAAA,cAAA;AAEZ;AAAA,YACF,KAAK;AACH,kBAAI,mBAAmB,GAAI;AAC3B,0BAAY,OAAO,gBAAgB,CAAC;AACpC;AAAA,UAAA;AAEJ,iBAAO,OAAO,OAAO,CAAA,GAAI,MAAM,EAAC,aAAY;AAAA,QAC9C;AAAA,QACA;AACE,iBAAO;AAAA,MAAA;AAAA,IAEb;AAAA,IACA;AAAA,MACE,eAAe,aAAa;AAAA,MAC5B,qBAAqB,aAAa;AAAA,MAClC,mBAAmB,yBAAyB,aAAa,qBAAqB,CAAA,CAAE;AAAA,MAChF,eAAe,QAAQ,oBAAoB,aAAa;AAAA,MACxD,eAAe,aAAa;AAAA,MAC5B,YAAY,aAAa,cAAc,CAAC,CAAC,QAAQ;AAAA,MACjD,iBAAiB,aAAa;AAAA,MAC9B,aAAa;AAAA,IAAA;AAAA,EACf,GAII,CAAC,iBAAiB,kBAAkB,IAAIlK,MAAAA,SAAwB,IAAI,GACpE,gBAAgB,aAAa,kBAC7B,uBAAuB,aAAa,kBAEpC,EAAC,UAAU,mBAAmB,8BAA6B;AAAA,IAC/D;AAAA,IACA;AAAA,EAAA,GAEI,EAAC,oBAAoB,uBAAuB,kBAAA,IAChD,iBAAiB,YAAY;AAE/BmC,QAAAA,UAAU,MAAM;AACV,gBACF,sBAAsB,CAAC,SAAS,EAAC,GAAG,KAAK,MAAM,SAAA,EAAU;AAAA,EAE7D,GAAG,CAAC,UAAU,qBAAqB,CAAC,GAEpCA,MAAAA,UAAU,MAAM;AACd,UAAM,mBAAmB,CAAC,aACpB,wBAAwB,WAAW,wBACrC;AAAA,MACE,mBAAmB,cAAc,QAAQ,CAAC,yCAAyC,cAAc,oBAAoB,CAAC;AAAA,IAAA,GAEjH,MAEF,IAGH,mBAAmB,CAAC,SACpB,kBAAkB,UAAa,QAAQ,gBAClC,MAGT;AAAA,MACE,cAAc,YAAY,IAAI,CAAC,qCAAqC,YAAY,aAAa,CAAC;AAAA,IAAA,GAEzF,KAGH,0BAA0B,CAAC,gBAC3B,OAAO,cAAc,eACvB,mBAAmB,0CAA0C,GACtD,MAEF;AAGT,QAAI,QAAQ;AACR,wBAAoB,SACtB,QAAQ,UAAU,6BAA6B,iBAAiB,mBAAmB,IAAI,KAErF,oBAAoB,aACtB,QAAQ,SAAS,iBAAiB,mBAAmB,QAAQ,IAE3D,oBAAoB,eAAe,SACrC,QAAQ,SAAS,wBAAwB,mBAAmB,WAAW,IAErE,SACF,mBAAmB,IAAI;AAAA,EAE3B,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB;AAAA,IACA,OAAO;AAAA,IACP;AAAA,EAAA,CACD;AAKD,QAAM,EAAC,wBAAwB,oBAAA,IAAuB,cAChD,aAAa,0BAA0B;AAU7C,MATAA,MAAAA,UAAU,MAAM;AACd,QAAI,YAAY;AACd,YAAM,EAAC,UAAU,UAAA,IAAa,mBAAmB,QAAQ,SAAS;AAAA,QAChE,kBAAkB,oBAAoB;AAAA,MAAA,CACvC;AACD,kBAAY,UAAU,SAAS;AAAA,IACjC;AAAA,EAEF,GAAG,CAAA,CAAE,GACD,WAAY,QAAO;AAEvB,QAAM,cAAc,OAAO,kBAAkB,UAAU,OAAO,kBAAkB,WAC1E,yBAAyB,OAAO,iBAAiB,OAAO,iBAAiB,OAAO,YAChF,yBAAyB,iBAAiB;AAAA,IAC9C,CAAC,OAAO,GAAG,UAAU,aAAa;AAAA,EAAA;AAEpC,SACErC,2BAAAA;AAAAA,IAACI,GAAAA;AAAAA,IAAA;AAAA,MACC,SAAO;AAAA,MACP,MAAI;AAAA,MACJ,IAAG;AAAA,MACH,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAO;AAAA,MACP;AAAA,MAEA,UAAAG,2BAAAA,KAACF,GAAAA,OAAA,EAAM,SAAS,GAAG,OAAO,GACtB,UAAA;AAAA,SAAA,mBAAmB,6BACnBL,2BAAAA,IAACQ,GAAAA,MAAA,EAAK,SAAS,GAAG,MAAK,YAAW,QAAQ,GAAG,cAAc,GACzD,UAAAD,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,KAAK,GAAG,OAAM,cAClB,UAAA;AAAA,UAAA9B,2BAAAA,IAACuD,MAAAA,kBAAA,EAAiB,OAAO,IAAI,QAAQ,IAAI;AAAA,UACzChD,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,YAAAL,+BAACS,GAAAA,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,UAAA,oBAEjC;AAAA,YACAT,2BAAAA,IAACS,GAAAA,MAAA,EAAK,MAAM,GAAI,6BAAmB,yBAAA,CAAyB;AAAA,UAAA,EAAA,CAC9D;AAAA,QAAA,EAAA,CACF,EAAA,CACF;AAAA,QAEFT,2BAAAA,IAAC+D,GAAAA,OAAA,EAAM,MAAM,GAAG,UAAA,kBAAc;AAAA,QAC9B/D,2BAAAA;AAAAA,UAACQ,GAAAA;AAAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,QAAM;AAAA,YACN,SAAS;AAAA,YACT,UAAU;AAAA,YACV,OAAO,EAAC,cAAc,YAAA;AAAA,YAEtB,UAAAD,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,KAAK,GACT,UAAA;AAAA,cAAA9B,2BAAAA,IAACqK,MAAAA,mBAAA,EAAkB,UAAS,MAAA,CAAM;AAAA,cAClC9J,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,gBAAAL,+BAACS,GAAAA,QAAK,cAAa,YAAW,IAAG,MAAK,MAAM,GACzC,UAAA,aAAa,SAAS,SAAS,aAAa,MAAM,CAAC,EAAE,OAAO,aAAa,KAC5E;AAAA,gBACAT,2BAAAA,IAACS,GAAAA,MAAA,EAAK,IAAG,KAAI,MAAM,GAAG,OAAK,IACxB,UAAA,aAAa,SAAS,SACnB,uBAAuB,YAAY,aAAa,MAAM,CAAC,EAAE,IAAI,CAAC,MAExD,oBAAoB,OACf,kBAAkB,YAAY,mBAAmB,IAAI,CAAC,MAE3D,oBACK,oCAEF,gCAEf;AAAA,gBACC,aAAa,SAAS,UACrBF,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACX,UAAA;AAAA,kBAAA,qBACCL,2BAAAA,IAACS,WAAK,IAAG,KAAI,MAAM,GAAG,OAAK,IAAC,UAAA,4BAAA,CAE5B;AAAA,kBAED,oBAAoB,YAAY,CAAC,mBAChCF,2BAAAA,KAACE,GAAAA,MAAA,EAAK,IAAG,KAAI,MAAM,GAAG,OAAK,IAAC,UAAA;AAAA,oBAAA;AAAA,oBACf,cAAc,mBAAmB,QAAQ;AAAA,kBAAA,EAAA,CACtD;AAAA,gBAAA,EAAA,CAEJ;AAAA,cAAA,EAAA,CAEJ;AAAA,YAAA,EAAA,CACF;AAAA,UAAA;AAAA,QAAA;AAAA,QAED,CAAC,uBACAF,2BAAAA,KAACF,YAAM,OAAO,GAAG,eAAe,GAC9B,UAAA;AAAA,UAAAL,2BAAAA;AAAAA,YAACsC,OAAAA;AAAAA,YAAA;AAAA,cACC,OAAM;AAAA,cACN,aACE/B,2BAAAA,KAAAsB,qBAAA,EAAE,UAAA;AAAA,gBAAA;AAAA,gBAEe;AAAA,gBACf7B,2BAAAA;AAAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,QAAO;AAAA,oBACP,KAAI;AAAA,oBACL,UAAA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAED,GACF;AAAA,cAGF,UAAAA,2BAAAA,IAAC8B,SAAA,EAAK,KAAK,GACR,UAAA,qBAAqB,IAAI,CAAC,EAAC,OAAO,MAAA,MAAW;AAC5C,sBAAM,UAAU,GAAG,EAAE,kBAAkB,KAAK;AAC5C,uBACEvB,2BAAAA,KAACuB,GAAAA,MAAA,EAAiB,OAAM,UAAS,KAAK,GACpC,UAAA;AAAA,kBAAA9B,2BAAAA;AAAAA,oBAACiE,GAAAA;AAAAA,oBAAA;AAAA,sBACC,SAAS,OAAO,kBAAkB;AAAA,sBAClC,MAAK;AAAA,sBACL,UAAU,CAAC,MACT,SAAS;AAAA,wBACP,QAAQ;AAAA,wBACR,OAAO,EAAE,cAAc;AAAA,sBAAA,CACxB;AAAA,sBAEH;AAAA,sBACA,IAAI;AAAA,oBAAA;AAAA,kBAAA;AAAA,iDAELxD,GAAAA,MAAA,EAAK,IAAG,SAAQ,SAAS,SACvB,UAAA,MAAA,CACH;AAAA,gBAAA,EAAA,GAfS,KAgBX;AAAA,cAEJ,CAAC,EAAA,CACH;AAAA,YAAA;AAAA,UAAA;AAAA,UAGD,CAAC,eACAF,2BAAAA,KAAAsB,WAAAA,UAAA,EACE,UAAA;AAAA,YAAA7B,2BAAAA,IAACsC,OAAAA,aAAU,OAAM,4BACf,UAAA/B,2BAAAA,KAACF,UAAA,EAAM,OAAO,GACZ,UAAA;AAAA,cAAAL,2BAAAA,IAAC,gBAAA,EAAe,IAAQ,QAAgB,SAAkB,UAAoB;AAAA,cAC7E,yBAAyB,KACxBA,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGJA,2BAAAA,IAAC,yBAAA,EAAwB,IAAQ,QAAgB,SAAA,CAAoB;AAAA,cACpE,CAAC,0BACAA,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,QAAQ,OAAO;AAAA,kBACf;AAAA,kBACA,aAAa,aAAa;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC5B,EAAA,CAEJ,EAAA,CACF;AAAA,YACAA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,oBAAoB;AAAA,cAAA;AAAA,YAAA;AAAA,UACtB,EAAA,CACF;AAAA,QAAA,GAEJ;AAAA,QAGFA,2BAAAA,IAAC+B,GAAAA,KAAA,EAAI,WAAW,GACd,UAAA/B,2BAAAA;AAAAA,UAACM,GAAAA;AAAAA,UAAA;AAAA,YACC,UACG,CAAC,eAAe,CAAC,0BAClB,oBAAoB,QACpB,qBACC,qBAAqB,CAAC;AAAA,YAEzB,MAAMqE,MAAAA;AAAAA,YACN,MAAK;AAAA,YACL,MAAK;AAAA,YACL,SAAS,MAAM;AACb,kBAAI,CAAC,iBAAiB;AACpB,sBAAM,EAAC,UAAU,UAAA,IAAa,mBAAmB,QAAQ,SAAS;AAAA,kBAChE,kBAAkB,oBAAoB;AAAA,gBAAA,CACvC;AACD,4BAAY,UAAU,SAAS;AAAA,cACjC;AAAA,YACF;AAAA,UAAA;AAAA,QAAA,EACF,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,SAAS,0BACP,QACA,SACmD;AACnD,QAAM,6BAAgF,CAAA;AACtF,SAAI,OAAO,iBACT,2BAA2B,KAAK,EAAC,QAAQ,SAAA,CAAS,GAEhD,OAAO,iBACT,2BAA2B,KAAK,EAAC,QAAQ,SAAA,CAAS,GAEhD,OAAO,eACL,QAAQ,cACV,2BAA2B,KAAK;AAAA,IAC9B,QAAQ;AAAA,IACR,sBAAsB,QAAQ,eAAe;AAAA,EAAA,CAC9C,IAED,QAAQ,MAAM,sDAAsD,IAGjE;AACT;AAEA,SAAS,mBACP,QACA,SACA,SAIA;AACA,QAAM,sBAAsB,OAAO,YAChC,OAA+B,oBAAoB,EACnD,IAAyD,CAAC,WAAW;AAAA,IACpE,MAAM,MAAM;AAAA,IACZ,eAAe,MAAM;AAAA,EAAA,EACrB,GAEE,SAAoD;AAAA,IACxD;AAAA,MACE,MAAM;AAAA,MACN,qBAAqB,oBAAoB,SAAS,IAAI,sBAAsB;AAAA,IAAA;AAAA,IAE9E,GAAG,OAAO,YAAY,OAAwB,iBAAiB,EAAE;AAAA,MAC/D,CAAC,KAAK,WACA,MAAM,iBAAiB,MAAM,QAAQ,MAAM,QAC7C,IAAI,KAAK;AAAA,QACP,KAAK,MAAM,KAAK;AAAA,QAChB,MAAM;AAAA,QACN,WAAW,MAAM,SAAS,cAAc,cAAc;AAAA,QACtD,eAAe,MAAM;AAAA,QACrB,MAAM,MAAM;AAAA,QACZ,iBAAiB,MAAM,SAAS;AAAA,MAAA,CACjC,GAEI;AAAA,MAET,CAAA;AAAA,IAAC;AAAA,EACH;AAGF,MAAI,OAAO,WAAW,UAAU;AAC9B,UAAM,kBAAmC,EAAC,GAAG,OAAO,WAAW,SAAS,MAClE,kBAAkB,6BAA6B,iBAAiB;AAAA,MACpE,kBAAkB,SAAS,oBAAoB;AAAA,MAC/C,OAAO;AAAA,IAAA,CACR;AACG,uBACF,OAAO,KAAK;AAAA,MACV,KAAK,OAAO,UAAU;AAAA,MACtB,kBAAkB;AAAA,IAAA,CACkC;AAAA,EAE1D;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,MACR,OAAO;AAAA,MACP,mBACE,OAAO,kBAAkB,SAAS,IAC9B,OAAO,kBAAkB,IAAI,CAAC,gBAAgB,EAAC,WAAA,EAAY,IAC3D;AAAA,MACN,4BAA4B,0BAA0B,QAAQ,OAAO;AAAA,MACrE,qBAAqB,OAAO;AAAA,MAC5B,eAAe,OAAO;AAAA,MACtB,iBAAiB,OAAO;AAAA,IAAA;AAAA,IAE1B,WAAW,OAAO,WAAW,WACxB,EAAC,GAAG,OAAO,WAAW,SAAS,OAChC;AAAA,EAAA;AAER;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAQG;AACD,SAAI,oBAAoB,gBAAgB,KAAc,OAEpD3E,2BAAAA;AAAAA,IAACsC,OAAAA;AAAAA,IAAA;AAAA,MACC,OAAM;AAAA,MACN,aACE/B,2BAAAA,KAAAsB,qBAAA,EAAE,UAAA;AAAA,QAAA;AAAA,QACiF;AAAA,QACjF7B,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,QAAO;AAAA,YACP,KAAI;AAAA,YACL,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,GACF;AAAA,MAGF,UAAAO,2BAAAA,KAACF,GAAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,QAAAL,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAW,OAAO,aAAa,EAAC,SAAS,GAAA;AAAA,YACzC,UAAU,CAAC,cAAc;AACvB,uBAAS,EAAC,QAAQ,aAAa,OAAO,WAAU;AAAA,YAClD;AAAA,YACA;AAAA,YACA,qBAAqB;AAAA,YACrB,iBAAiB;AAAA,UAAA;AAAA,QAAA;AAAA,QAElB,OAAO,WAAW,YACjB,aAAa,SAAS;AAAA,QAEtB,CAAC,OAAO,UAAU,oBAChBA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA,WAAW,OAAO;AAAA,YAClB,kBAAkB,mBAAmB;AAAA,YACrC,mBAAmB,CAAC,cAAc;AAChC,uBAAS,EAAC,QAAQ,aAAa,OAAO,WAAU;AAAA,YAClD;AAAA,YACA,qBAAqB;AAAA,YACrB,UAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ,EAAA,CAEN;AAAA,IAAA;AAAA,EAAA;AAGN;AAGA,MAAM,mBAAmBgC,MAAAA,KAAK,SAA0B;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOG;AAEDK,QAAAA,UAAU,MAAM;AACd,QAAI,SAAS,WAAW,aAAa,SAAS,QAAQ;AACpD,YAAM,OAAO,aAAa,MAAM,CAAC,GAC3B,MAAM,IAAI,gBAAgB,IAAI;AACpC,aAAA,SAAS,QAAQ,MAAM,KAEhB,MAAM;AACX,YAAI,gBAAgB,GAAG;AAAA,MACzB;AAAA,IACF;AAAA,EAEF,GAAG,CAAC,cAAc,QAAQ,CAAC;AAE3B,QAAM,aACJ,oBAAqB,QAA0C,mBAAmB;AAEpF,SACErC,2BAAAA;AAAAA,IAACQ,GAAAA;AAAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,QAAM;AAAA,MACN,OAAO;AAAA,QACL,UAAU;AAAA;AAAA,QAEV,SAAS;AAAA,QACT,gBAAgB;AAAA,MAAA;AAAA,MAIlB,UAAAD,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAK;AAAA,UACL,OAAO;AAAA,YACL,UAAU;AAAA;AAAA;AAAA,YAGV,OAAO,aAAa,SAAS;AAAA,YAC7B,aAAa,mBAAmB,OAAO,gBAAgB,IAAI;AAAA,YAC3D,GAAI,aAAa,EAAC,QAAQ,SAAS,WAAW,OAAA,IAAU,EAAC,WAAW,QAAA;AAAA,YACpE,UAAU;AAAA,UAAA;AAAA,UAGZ,UAAA;AAAA,YAAAP,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,KAAK;AAAA,gBACL,OAAO;AAAA,kBACL,UAAU;AAAA,kBACV,KAAK;AAAA,kBACL,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,WAAW;AAAA,kBACX,SAAS;AAAA,gBAAA;AAAA,cACX;AAAA,YAAA;AAAA,YAEFA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC;AAAA,gBACA,UAAU;AAAA,gBACV,cAAc;AAAA,gBACd,iBAAiB;AAAA,cAAA;AAAA,YAAA;AAAA,UACnB;AAAA,QAAA;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN,CAAC;AC7qBM,SAAS,cAAqB,WAAiC;AACpE,SAAO4B,wBAAO,SAA2B,EAA+B,CAAC,UAAU;AACjF,UAAM,SAAS;AAAA,MACb,OAAO,MAAM,UAAU,IAAI;AAAA,MAC3B,OAAO;AAAA,IAAA;AAGT,WAAO4H,iBAAAA;AAAAA,iCACsB,qBAAqB,MAAM,CAAC;AAAA;AAAA,uBAEtCc,GAAAA,IAAI,MAAM,MAAM,OAAO,OAAO,CAAC,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,mCAKrB,eAAe;AAAA,MACxC,MAAM,MAAM,MAAM,OAAO,MAAM;AAAA,MAC/B;AAAA,MACA,WAAW,MAAM,MAAM,OAAO;AAAA,IAAA,CAC/B,CAAC;AAAA;AAAA;AAAA,EAGR,CAAC;AACH;ACtBA,MAAM,0BAA0B,cAAc9J,OAAI,GAWrC,aAAa+J,MAAAA;AAAAA,EACxB,CAAC,EAAC,UAAU,MAAM,SAAS,QAAQ,aAAa,aAAa,WAAA,GAAa,iBAAiB;AACzF,UAAM,WAAWtI,MAAAA,OAAyB,IAAI,GACxC,gBAAgBZ,MAAAA,YAAwD,CAAC,UAAU;AACxE,YAAM,OAGV,QAAQ,UAAU,MAIxB,MAAM,WAAW,MAAM,YAAY,MAAM,QAAQ,OACpD,SAAS,QAAS,MAAA;AAAA,IAEtB,GAAG,CAAA,CAAE;AAEL,WACEd,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,KAAK;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA,UAAA;AAAA,UAAAP,2BAAAA,IAACwK,eAAA,EAAY,KAAK,SAAA,CAAU;AAAA,UAC3B;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF,GAEMA,gBAAc5I,iBAAAA,OAAO,MAAM,MAAM,EAAC,MAAM,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCpD/C,cAAcA,iBAAAA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASrB,QAAQA,iBAAAA,OAAO;AAAA;AAAA,GAQR,kBAAkB,CAAC,EAAC,UAAU,QAAQ,GAAG,YAAiC;AACrF,QAAM,UAAU,aAAaF,MAAAA,OAAO,IAC9B,WAAWO,aAAyB,IAAI,GACxC,eAAeZ,MAAAA;AAAAA,IACnB,CAAC,UAAU;AACL,kBACF,SAAS,MAAM,OAAO,KAAM;AAAA,IAEhC;AAAA,IACA,CAAC,QAAQ;AAAA,EAAA,GAEL,oBAAoBA,MAAAA,YAAY,MAAM,SAAS,SAAS,MAAA,GAAS,EAAE;AACzE,SACEd,2BAAAA,KAAC,OAAA,EAAM,SAAS,SACd,UAAA;AAAA,IAAAP,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,KAAK;AAAA,QACL,UAAU;AAAA,QACV,MAAK;AAAA,QACL,IAAI;AAAA,QACJ,UAAU;AAAA,QACV,OAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAERA,2BAAAA;AAAAA,MAACM,GAAAA;AAAAA,MAAA;AAAA,QACC,SAAS;AAAA,QACT,MAAK;AAAA,QACL,MAAK;AAAA,QACL,OAAO,EAAC,OAAO,OAAA;AAAA,QACd,GAAG;AAAA,MAAA;AAAA,IAAA;AAAA,EACN,GACF;AAEJ;AC5CA,SAAS,mBAAmB,QAAwB;AAClD,SAAO,OACJ,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,KAAA,EAAO,QAAQ,MAAM,EAAE,CAAC,EAC3C,KAAK,MAAM;AAChB;AAWA,SAAwB,kBAAkB,OAA+B;AACvE,QAAM,EAAC,gBAAgB,UAAU,UAAU,UAAU,YAAY,WAAU,OACrE,eAAee,MAAAA,YAAY,MAAM,eAAe,cAAc,GAAG,CAAC,cAAc,CAAC,GACjF,qBAAqBA,MAAAA,YAAY,MAAM,eAAe,SAAS,GAAG,CAAC,cAAc,CAAC,GAClF,EAAC,gBAAA,IAAmB,iBAAiB,MAAM,MAAM;AAEvD,SACErB,2BAAAA;AAAAA,IAACQ,GAAAA;AAAAA,IAAA;AAAA,MACC,QAAO;AAAA,MACP,MAAM,WAAW,gBAAgB;AAAA,MACjC,QAAM;AAAA,MACN,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,UAAU;AAAA,MACV,OAAO,WAAW,EAAC,aAAa,kBAAiB;AAAA,MAEjD,UAAAD,2BAAAA;AAAAA,QAACuB,GAAAA;AAAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,SAAQ;AAAA,UACR,KAAK;AAAA,UACL,WAAW,CAAC,UAAU,UAAU,KAAK;AAAA,UACrC,UAAU;AAAA,UACV,QAAO;AAAA,UAEP,UAAA;AAAA,YAAAvB,2BAAAA,KAACuB,GAAAA,MAAA,EAAK,OAAM,UAAS,SAAQ,cAAa,KAAK,GAAG,MAAM,GACtD,UAAA;AAAA,cAAA9B,2BAAAA,IAAC8B,GAAAA,MAAA,EAAK,SAAQ,UACZ,UAAA9B,2BAAAA,IAACS,GAAAA,MAAA,EAAK,OAAK,IACT,UAAAT,2BAAAA,IAACqK,MAAAA,mBAAA,CAAA,CAAkB,EAAA,CACrB,GACF;AAAA,cACArK,2BAAAA,IAAC8B,GAAAA,QAAK,SAAQ,UACZ,0CAACrB,GAAAA,MAAA,EAAK,MAAM,GAAG,OAAK,IAAC,UAAA;AAAA,gBAAA;AAAA,gBACb,mBAAmB,MAAM;AAAA,gBAAE;AAAA,cAAA,EAAA,CACnC,EAAA,CACF;AAAA,YAAA,GACF;AAAA,YACAF,2BAAAA,KAACmC,GAAAA,QAAA,EAAO,OAAO,GACb,UAAA;AAAA,cAAA1C,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC;AAAA,kBACA,MAAK;AAAA,kBACL,MAAK;AAAA,kBACL,MAAM2E,MAAAA;AAAAA,kBACN,MAAK;AAAA,kBACL;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEF3E,2BAAAA,IAACM,GAAAA,UAAO,MAAK,SAAQ,MAAM0G,MAAAA,YAAY,MAAK,UAAS,SAAS,aAAA,CAAc;AAAA,cAE3E,mBACChH,2BAAAA;AAAAA,gBAACM,GAAAA;AAAAA,gBAAA;AAAA,kBACC,SAAS;AAAA,kBACT,QAAQ;AAAA,kBACR,MAAM,aAAa,aAAa;AAAA,kBAChC,SAAS;AAAA,kBACT,MAAM+H,MAAAA;AAAAA,kBACN,MAAK;AAAA,kBACL,OAAM;AAAA,gBAAA;AAAA,cAAA;AAAA,YACR,EAAA,CAEJ;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN;AClCA,MAAM,gBAAuB;AAAA,EAC3B,cAAc;AAAA,EACd,cAAc;AAAA,EACd,OAAO;AACT;AAoBA,SAAwB,SAAS,OAAc;AAC7C,QAAM,QAAQ9D,GAAAA,YACR,eAAetC,MAAAA,OAAuB,IAAI,GAE1C,iBAAiBA,MAAAA,OAAsB,CAAA,CAAE,GACzC,CAAC,WAAW,YAAY,IAAI/B,MAAAA,SAAqC,IAAI,GAErE,qBAAqB+B,MAAAA;AAAAA,KACxB,MAAM;AACL,YAAM,UAAU,IAAIwI,aAAA;AACpB,aAAO;AAAA,QACL,YAAY,QAAQ,aAAA;AAAA,QACpB,cAAc,CAAC,UAAU,QAAQ,KAAK,KAAK;AAAA,MAAA;AAAA,IAE/C,GAAA;AAAA,EAAG,EACH,SAEI,YAAYxI,MAAAA,OAA4B,IAAI,GAC5C,sBAAsBA,MAAAA,OAAsB,IAAI,GAChD,CAAC,OAAO,QAAQ,IAAIT,MAAAA;AAAAA,IACxB,CAAC,MAAa,WAAgC;AAC5C,cAAQ,OAAO,QAAA;AAAA,QACb,KAAK;AACH,iBAAO,OAAO,OAAO,IAAI,eAAe,EAAC,cAAc,OAAO,OAAM;AAAA,QACtE,KAAK;AACH,iBAAO,OAAO,OAAO,CAAA,GAAI,MAAM,EAAC,cAAc,EAAC,UAAU,EAAA,GAAG;AAAA,QAC9D,KAAK,gBAAgB;AAEnB,gBAAM,EAAC,MAAM,QAAQ,GAAG,GAAG,YAAW;AACtC,iBAAO,OAAO,OAAO,CAAA,GAAI,MAAM;AAAA,YAC7B,cAAc;AAAA,cACZ,GAAG,KAAK;AAAA,cACR,UAAU,KAAK,aAAc;AAAA,cAC7B,GAAG;AAAA,YAAA;AAAA,UACL,CAC2C;AAAA,QAC/C;AAAA,QACA,KAAK;AACH,iBAAO,OAAO,OAAO,CAAA,GAAI,MAAM;AAAA,YAC7B,cAAc;AAAA,cACZ,GAAG,KAAK;AAAA,cACR,UAAU,OAAO;AAAA,YAAA;AAAA,UACnB,CAC2C;AAAA,QAC/C,KAAK;AAAA,QACL,KAAK;AAEH,iBAAA,UAAU,SAAS,eACnB,UAAU,UAAU,MACpB,oBAAoB,UAAU,MACvB;AAAA,QACT,KAAK,SAAS;AAEZ,oBAAU,SAAS,eACnB,UAAU,UAAU,MACpB,oBAAoB,UAAU;AAE9B,cAAI,QAAQ,OAAO;AACnB,iBAAI,cAAc,OAAO,KAAK,KAAK,kBAAkB,OAAO,UAAU,KAAK,MACzE,QAAQ,IAAI;AAAA,YACV;AAAA,UAAA,IAIG,OAAO,OAAO,CAAA,GAAI,eAAe,EAAC,OAAa;AAAA,QACxD;AAAA,QACA;AACE,iBAAO;AAAA,MAAA;AAAA,IAEb;AAAA,IACA;AAAA,MACE,cAAc;AAAA,MACd,cAAc;AAAA,MACd,OAAO;AAAA,IAAA;AAAA,EACT;AAKFa,QAAAA,UAAU,MAAM;AACd,UAAM,UAAU,MAAM;AAOpB,UALI,UAAU,WAAW,CAAC,UAAU,QAAQ,UAC1C,UAAU,QAAQ,YAAA,GAIhB,oBAAoB,WAAW,MAAM,OAAO,QAAQ,oBAAoB,SAAS;AACnF,cAAM,QAAQ,oBAAoB;AAClC,4BAAoB,UAAU,MAE9B,MAAM,OAAO,OAAO,KAAK,EAAE,MAAM,CAAC,QAAQ;AACxC,kBAAQ,KAAK,+CAA+C,GAAG;AAAA,QACjE,CAAC;AAAA,MACH;AAAA,IACF,GAEM,qBAAqB,MAAM;AAC/B,cAAA;AAAA,IACF;AAEA,WAAA,OAAO,iBAAiB,gBAAgB,kBAAkB,GAC1D,OAAO,iBAAiB,YAAY,kBAAkB,GAE/C,MAAM;AACX,aAAO,oBAAoB,gBAAgB,kBAAkB,GAC7D,OAAO,oBAAoB,YAAY,kBAAkB,GACzD,QAAA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,QAAQ,MAAM,OAAO,GAAG,CAAC;AAgBnC,QAAM,cAAc,CAClB,UACA,cACG;AACH,UAAM,EAAC,iBAAgB;AACvB,QAAI,CAAC,gBAAgB,UAAU,QAAS;AACxC,aAAS,EAAC,QAAQ,gBAAe;AACjC,QAAI;AAEJ,YAAQ,aAAa,MAAA;AAAA,MACnB,KAAK;AACH,2BAAmB,UAAU;AAAA,UAC3B,QAAQ,MAAM;AAAA,UACd,KAAK,aAAa;AAAA,UAClB;AAAA,UACA;AAAA,QAAA,CACD;AACD;AAAA,MACF,KAAK;AACH,2BAAmB,WAAW;AAAA,UAC5B,QAAQ,MAAM;AAAA,UACd,MAAM,aAAa,MAAM,CAAC;AAAA,UAC1B;AAAA,UACA;AAAA,QAAA,CACD,EAAE;AAAA,UACDqI,UAAAA;AAAAA,YACE,mBAAmB,WAAW;AAAA,cAC5BzH,UAAAA,IAAI,MAAM;AACJ,oCAAoB,YACtB,MAAM,OAAO,OAAO,oBAAoB,OAAO,GAC/C,oBAAoB,UAAU;AAAA,cAElC,CAAC;AAAA,YAAA;AAAA,UACH;AAAA,QACF;AAEF;AAAA,IAAA;AAEJ,cAAU,UAAU,iBAAiB,UAAU;AAAA,MAC7C,MAAM,CAAC,UAAU;AACf,gBAAQ,MAAM,MAAA;AAAA,UACZ,KAAK;AAEH,gCAAoB,UAAU,MAAM,MACpC,SAAS,EAAC,QAAQ,gBAAgB,GAAG,OAAM;AAC3C;AAAA,UACF,KAAK;AAAA,UACL,KAAK;AACH,qBAAS,EAAC,QAAQ,gBAAgB,GAAG,OAAM;AAC3C;AAAA,UACF,KAAK;AACH,qBAAS,EAAC,QAAQ,YAAY,SAAS,MAAM,SAAQ;AACrD;AAAA,UACF,KAAK;AACH,qBAAS,EAAC,QAAQ,YAAY,SAAS,KAAI,GAC3C,oBAAoB,UAAU,MAC9B,MAAM;AAAA,cACJiG,OAAAA,WAAW,KAAK;AAAA,gBACdE,oBAAa,EAAC,OAAO,CAAA,GAAG;AAAA,gBACxBC,OAAAA,IAAI,EAAC,OAAO,aAAa,OAAO,IAAM,MAAM,MAAM,MAAM,IAAA,GAAM,CAAC,OAAO,CAAC;AAAA,cAAA,CACxE;AAAA,YAAA;AAEH;AAAA,QAIA;AAAA,MAEN;AAAA,MACA,UAAU,MAAM,SAAS,EAAC,QAAQ,YAAW;AAAA,MAC7C,OAAO,CAAC,UAAU,SAAS,EAAC,QAAQ,SAAS,OAAO,SAAA,CAAS;AAAA,IAAA,CAC9D;AAAA,EACH,GAEM,mBAAmBhI,MAAAA,YAAY,MAAM;AACzC,UAAM,KAAK;AAAA,MACT,QAAQ;AAAA,MACR,OAAO,sCAAsC,MAAM,OAAO,mBAAmB,KAAK,IAAI,CAAC;AAAA,IAAA,CACxF;AAAA,EACH,GAAG,CAAC,MAAM,OAAO,mBAAmB,KAAK,CAAC,GAOpC,gBAAgB,CAAC,UACH,MAAM,KAAK,KAAK,EAAE,KAAK,CAAC,SACjC,CAAC,MAAM,OAAO,mBAAmB,KAAK,CAAC,iBAAiB;AAE7D,UAAM,UAAU,IAAI,aAAa,QAAQ,KAAK,IAAI,CAAC;AACnD,WAAO,IAAI,OAAO,OAAO,EAAE,KAAK,KAAK,IAAI;AAAA,EAC3C,CAAC,CACF,GAUG,eAAe,CAAC,UAA6B;AAC7C,kBAAc,KAAK,KACvB,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,OAAO,EAAC,MAAM,QAAQ,MAAA;AAAA,IAAK,CAC5B;AAAA,EACH,GAGM,cAA6D,CAAC,UAAU;AAI5E,QAHe,MAAM,OAGV,QAAQ,UAAU;AAC3B;AAGF,UAAM,eAAA,GACN,MAAM,gBAAA;AAGN,UAAM,OADJ,MAAM,iBAAkB,OAAmD,gBAClD,QAAQ,MAAM,GAAG,KAAA;AAC5C,QAAI,CAAC,WAAW,GAAG,GAAG;AACpB,YAAM,KAAK,EAAC,QAAQ,SAAS,OAAO,oCAAmC;AACvE;AAAA,IACF;AACA,aAAS,EAAC,QAAQ,eAAe,OAAO,EAAC,MAAM,OAAO,IAAA,GAAU;AAAA,EAClE,GAGM,aAAqD,CAAC,UAAU;AAGpE,QAFA,MAAM,kBACN,MAAM,gBAAA,GACF,cAAc,WAAW;AAC3B,uBAAA,GACA,aAAa,IAAI;AACjB;AAAA,IACF;AACA,iBAAa,IAAI,GACjB,oBAAoB,MAAM,YAAY,YAAa,EAAE,KAAK,CAAC,UAAU;AACnE,eAAS;AAAA,QACP,QAAQ;AAAA,QACR,OAAO,EAAC,MAAM,QAAQ,MAAA;AAAA,MAAK,CAC5B;AAAA,IACH,CAAC;AAAA,EACH,GAIM,iBAAyD,CAAC,UAAU;AACxE,UAAM,eAAA,GACN,MAAM,gBAAA;AAAA,EACR,GAEM,kBAA0D,CAAC,UAAU;AACzE,UAAM,mBACN,eAAe,QAAQ,KAAK,MAAM,MAAM;AACxC,UAAM,OAAO,MAAM,aAAa,QAAQ,CAAC,GAAG,MAItC,cAHY,MAAM,OAAO,mBAGA,KAAK,CAAC,iBAAiB;AAEpD,YAAM,UAAU,IAAI,aAAa,QAAQ,KAAK,IAAI,CAAC;AACnD,aAAO,IAAI,OAAO,OAAO,EAAE,KAAK,IAAI;AAAA,IACtC,CAAC;AAED,iBAAa,cAAc,UAAU,SAAS;AAAA,EAChD,GAEM,kBAA0D,CAAC,UAAU;AACzE,UAAM,gBAAA;AACN,UAAM,MAAM,eAAe,QAAQ,QAAQ,MAAM,MAAM;AACnD,UAAM,MACR,eAAe,QAAQ,OAAO,KAAK,CAAC,GAElC,eAAe,QAAQ,WAAW,KACpC,aAAa,IAAI;AAAA,EAErB;AAKA,MAAI,MAAM,UAAU,MAAM;AACxB,UAAM,QAAQ,MAAM;AACpB,WACEd,gCAACuB,GAAAA,QAAK,KAAK,GAAG,WAAU,UAAS,SAAQ,UAAS,OAAM,UACtD,UAAA;AAAA,MAAA9B,2BAAAA,IAACS,GAAAA,QAAK,MAAM,GAAG,OAAK,IAClB,UAAAT,2BAAAA,IAACuD,0BAAiB,EAAA,CACpB;AAAA,MACAvD,2BAAAA,IAACS,GAAAA,QAAK,UAAA,uBAAA,CAAoB;AAAA,MACzB,iBAAiB,SAAS,MAAM,WAC/BT,2BAAAA,IAACS,SAAA,EAAK,MAAM,GAAG,OAAK,IAAC,QAAO,YAAW,OAAO,EAAC,WAAW,SAAA,GACvD,gBAAM,SACT;AAAA,MAEFT,2BAAAA,IAACM,GAAAA,QAAA,EAAO,MAAK,uBAAsB,SAAS,MAAM,SAAS,EAAC,QAAQ,QAAA,CAAQ,EAAA,CAAG;AAAA,IAAA,GACjF;AAAA,EAEJ;AAGA,MAAI,MAAM,iBAAiB,MAAM;AAC/B,UAAM,EAAC,iBAAgB;AACvB,WACEN,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,UAAU,mBAAmB;AAAA,QAC7B,UAAU,aAAa;AAAA,QACvB,UAAU,aAAa,MAAM,QAAQ,aAAa;AAAA,MAAA;AAAA,IAAA;AAAA,EAGxD;AAGA,MAAI,MAAM,iBAAiB;AACzB,WACEA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,cAAc,MAAM;AAAA,QACpB,cAAc,MAAM;AAAA,QACpB,SAAS,MAAM;AAAA,QACf;AAAA,QACA,SAAS,MAAM,SAAS,EAAC,QAAQ,SAAQ;AAAA,MAAA;AAAA,IAAA;AAM/C,MAAI;AACA,gBAAW,OAAO,cAAc,UAAU,aAAa;AAE3D,QAAM,mBAAmB,MAAM,QAAQ,mBAAmB,SACtD,MAAM,OAAO,kBAAkB,KAAK,GAAG,IACvC;AAEJ,SACEO,2BAAAA,KAAAsB,qBAAA,EACE,UAAA;AAAA,IAAA7B,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,aAAa;AAAA,QACb,SAAS;AAAA,QACT,KAAK;AAAA,QAEJ,gBAAM,QACLA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,aAAa,MAAM;AAAA,YACnB,gBAAgB,MAAM;AAAA,YAEtB,UAAAA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,UAAU,MAAM;AAAA,gBAChB,OAAO,MAAM;AAAA,gBACb,UAAU,MAAM;AAAA,gBAChB,QAAQ,MAAM;AAAA,gBACd,SACEA,2BAAAA;AAAAA,kBAAC2K;AAAAA,kBAAA;AAAA,oBACC,QAAQ;AAAA,oBACR,OAAO,MAAM;AAAA,oBACb,aAAa,MAAM;AAAA,oBACnB,gBAAgB,MAAM;AAAA,oBACtB,UAAU,MAAM;AAAA,oBAChB,UAAU;AAAA,oBACV,UAAU,MAAM;AAAA,oBAChB,QAAQ,MAAM;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAChB;AAAA,YAAA;AAAA,UAEJ;AAAA,QAAA,IAGF3K,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,QAAQ;AAAA,YACR,UAAU,cAAc;AAAA,YACxB,UAAU;AAAA,YACV,UAAU,CAAC,CAAC,MAAM;AAAA,YAClB,gBAAgB,MAAM;AAAA,YACtB,YAAY,MAAM;AAAA,YAClB,QAAQ,MAAM;AAAA,UAAA;AAAA,QAAA;AAAA,MAChB;AAAA,IAAA;AAAA,IAGH,MAAM,gBAAgB,kBACrBA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,QAAQ,MAAM;AAAA,QACd,OAAO,MAAM;AAAA,QACb,UAAU,MAAM;AAAA,QAChB,gBAAgB,MAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EACxB,GAEJ;AAEJ;AC9dA,MAAM,QAAQ,CAAC,UAAsB;AACnC,QAAM,SAAS,aACT,uBAAuB,yBAAA,GACvB,sBAAsB,uBAAuB,MAAM,OAAO,KAAK,GAC/D,OAAO,cAAc,MAAM,WAAW,SAAY,qBAAqB,SAAS,MAAS,GACzF,CAAC,aAAa,cAAc,IAAI,kBAChC,EAAC,gBAAA,IAAmB,iBAAiB,MAAM,MAAM,GAEjD,QAAQ,qBAAqB,SAAS,oBAAoB,SAAS,KAAK;AAM9E,MAAI;AAEF,UAAM;AAER,QAAM,YAAY,qBAAqB,aAAa,oBAAoB;AAExE,wCACGQ,GAAAA,MAAA,EACC,UAAAR,2BAAAA,IAAC4K,qBAAA,EAAkB,YAAY,MAAM,YACnC,UAAA5K,2BAAAA,IAACqD,MAAAA,UAAA,EAAS,yCAAW,eAAA,CAAA,CAAc,GAChC,sBACCrD,2BAAAA,IAAC,eAAA,CAAA,CAAc,IAEfO,2BAAAA,KAAAsB,WAAAA,UAAA,EACG,UAAA;AAAA,IAAA,qBAAqB,MAAM,cAAc,CAAC,oBAAoB,QAC7D7B,2BAAAA,IAAC,SAAA,EAAQ,gBAAgC,QAAQ,MAAM,OAAA,CAAQ,IAE/DA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACE,GAAG;AAAA,QACJ,QAAQ,MAAM;AAAA,QACd,UAAU,MAAM;AAAA,QAChB;AAAA,QACA,SAAS,qBAAqB,MAAM;AAAA,QACpC,OAAO,oBAAoB;AAAA,QAC3B;AAAA,QACA;AAAA,QACA,YAAY,qBAAqB,MAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAI1C,gBAAgB,aAAa,mBAC5BA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,SAAS,qBAAqB,MAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EACtC,GAEJ,EAAA,CAEJ,GACF,GACF;AAEJ;AAEA,IAAA,UAAegC,MAAAA,KAAK,KAAK;ACzElB,SAAS,wBAAwB,QAAsB;AAC5D,SAAO;AAAA,IACL,YAAY;AAAA,MACV,OAAO,CAAC,UACNhC,2BAAAA,IAAC6K,WAAM,QAAQ,EAAC,GAAG,QAAQ,GAAG,MAAM,WAAW,QAAA,GAAW,GAAG,MAAA,CAAO;AAAA,IAAA;AAAA,IAGxE,SAAS;AAAA,MACP,QAAQ;AAAA,QACN,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,MAAM;AAAA,MAAA;AAAA,MAER,SAAS,CAAC,UAAuC;AAC/C,cAAM,EAAC,UAAU,YAAY,OAAA,IAAU;AACvC,eAAO;AAAA,UACL,OAAO,YAAY,cAAc;AAAA,UACjC,UAAU,SAAS,WAAW,MAAM,KAAK;AAAA,UACzC,OAAO,MAAM,aAAa7K,+BAAC,kBAAe,OAAc,OAAO,IAAI,IAAK;AAAA,QAAA;AAAA,MAE5E;AAAA,IAAA;AAAA,EACF;AAEJ;AC9BO,MAAM,iBAAiB;AAAA,EAC5B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,IACN;AAAA,MACE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,IAAI,CAAC,EAAC,MAAM,kBAAiB;AAAA,IAAA;AAAA,EAC/B;AAEJ,GAEM,WAAW;AAAA,EACf,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,IACN,EAAC,MAAM,UAAU,MAAM,KAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,OAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,YAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,iBAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,WAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,aAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,gBAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,OAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,SAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,cAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,YAAA;AAAA,EAAW;AAEtC,GAEM,gBAAgB;AAAA,EACpB,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,IACN,EAAC,MAAM,UAAU,MAAM,KAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,SAAA;AAAA,EAAQ;AAEnC,GAEM,yBAAyB;AAAA,EAC7B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,IACN,EAAC,MAAM,UAAU,MAAM,OAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,MAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,SAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,QAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,UAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,WAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,OAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,SAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,kBAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,aAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,KAAA;AAAA,IACvB,EAAC,MAAM,UAAU,MAAM,cAAA;AAAA,EAAa;AAExC,GAEM,sBAAsB;AAAA,EAC1B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,IACN,EAAC,MAAM,UAAU,MAAM,SAAA;AAAA,IACvB;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,IAAI,CAAC,EAAC,MAAM,2BAA0B;AAAA,IAAA;AAAA,EACxC;AAEJ,GAEM,eAAe;AAAA,EACnB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AAAA,IACN;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,IAAI,CAAC,EAAC,MAAM,aAAY;AAAA,IAAA;AAAA,IAE1B;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,IAAI,CAAC,EAAC,MAAM,kBAAiB;AAAA,IAAA;AAAA,IAE/B;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,EACR;AAEJ,GAEM,gBAAgB;AAAA,EACpB,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,IACN;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,EACR;AAEJ,GAEa,cAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GC3La,gBAA8B;AAAA,EACzC,mBAAmB,CAAA;AAAA,EACnB,aAAa;AAAA,EACb,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,8BAA8B,CAAA;AAAA,EAC9B,mBAAmB,CAAC,WAAW,SAAS;AAC1C;AAKA,SAAS,oBAAoB,QAE3B;AAEA,SAAI,OAAO,qBAAqB,OAAO,kBAAkB,SAAS,IACzD,EAAC,mBAAmB,OAAO,kBAAA,IAIhC,OAAO,gBAAgB,aAClB,EAAC,mBAAmB,CAAC,SAAS,MAGhC,EAAC,mBAAmB,GAAC;AAC9B;AAEO,MAAM,WAAW8K,OAAAA,aAA2C,CAAC,eAAe;AAEjF,MAAI,OAAO,cAAe,YAAY,mBAAmB,YAAY;AACnE,UAAM,2BAA2B,WAAW;AACvC,eAAW,kBACV,6BAA6B,eAC/B,WAAW,gBAAgB,UAEzB,6BAA6B,YAC/B,WAAW,gBAAgB;AAAA,EAGjC;AACA,QAAM,SAAuB;AAAA,IAC3B,GAAG;AAAA,IACH,GAAI,cAAc,CAAA;AAAA,IAClB,GAAG,oBAAoB,cAAc,CAAA,CAAE;AAAA,EAAA;AAEzC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,OAAO;AAAA,QACL,GAAG;AAAA,QACH;AAAA,UACE,GAAG;AAAA,UACH,GAAG,wBAAwB,MAAM;AAAA,QAAA;AAAA,MACnC;AAAA,IACF;AAAA,IAEF,OAAO,OAAO,SAAS,KAAQ,SAAY,CAAC,iBAAiB,MAAM,CAAC;AAAA,EAAA;AAExE,CAAC;;;","x_google_ignoreList":[48,72]}
1
+ {"version":3,"file":"index.js","sources":["../src/components/icons/ToolIcon.tsx","../src/context/DrmPlaybackWarningContext.tsx","../src/hooks/useClient.ts","../src/util/createSearchFilter.ts","../src/hooks/useAssets.ts","../src/hooks/useDialogState.ts","../src/actions/secrets.ts","../src/hooks/useSaveSecrets.ts","../src/util/constants.ts","../src/hooks/useSecretsDocumentValues.ts","../src/hooks/useSecretsFormState.ts","../src/util/readSecrets.ts","../src/components/MuxLogo.tsx","../src/components/ConfigureApi.styled.tsx","../src/components/FormField.tsx","../src/components/ConfigureApi.tsx","../src/util/assetTitlePlaceholder.ts","../src/util/parsers.ts","../src/actions/assets.ts","../src/hooks/useMuxAssets.ts","../src/hooks/useImportMuxAssets.ts","../src/hooks/useInView.ts","../src/util/getPlaybackPolicy.ts","../src/util/generateJwt.ts","../src/util/createUrlParamsObject.ts","../src/util/getAnimatedPosterSrc.ts","../src/util/getPosterSrc.ts","../src/util/tryWithSuspend.ts","../src/components/VideoThumbnail.tsx","../src/components/ImportVideosFromMux.tsx","../src/components/PageSelector.tsx","../src/util/addKeysToMuxData.ts","../src/hooks/useResyncMuxMetadata.ts","../src/components/ResyncMetadata.tsx","../src/components/SelectSortOptions.tsx","../src/components/SpinnerBox.tsx","../src/components/IconInfo.tsx","../src/components/icons/Resolution.tsx","../src/components/icons/StopWatch.tsx","../src/hooks/useResyncAsset.ts","../src/util/textTracks.ts","../src/util/types.ts","../src/components/AddCaptionDialog.tsx","../src/components/EditCaptionDialog.tsx","../src/components/TextTracksManager.tsx","../src/context/DialogStateContext.tsx","../src/util/getVideoSrc.ts","../src/components/CaptionsDialog.tsx","../node_modules/use-device-pixel-ratio/dist/index.module.js","../src/util/formatSeconds.ts","../src/components/EditThumbnailDialog.tsx","../src/components/icons/Audio.tsx","../src/components/VideoPlayer.tsx","../src/components/documentPreview/MissingSchemaType.tsx","../src/components/documentPreview/TimeAgo.tsx","../src/components/documentPreview/DraftStatus.tsx","../src/components/documentPreview/PublishedStatus.tsx","../src/components/documentPreview/PaneItemPreview.tsx","../src/components/documentPreview/DocumentPreview.tsx","../src/components/VideoDetails/VideoReferences.tsx","../src/components/VideoDetails/DeleteDialog.tsx","../src/hooks/useDocReferences.ts","../src/util/getVideoMetadata.ts","../src/components/VideoDetails/useVideoDetails.ts","../src/components/VideoDetails/VideoDetails.tsx","../src/components/VideoMetadata.tsx","../src/components/VideoInBrowser.tsx","../src/components/VideosBrowser.tsx","../src/components/StudioTool.tsx","../src/hooks/useAccessControl.ts","../src/hooks/useAssetDocumentValues.ts","../src/hooks/useMuxPolling.ts","../node_modules/use-error-boundary/lib/index.module.js","../src/components/ErrorBoundaryCard.tsx","../src/components/Input.styled.tsx","../src/components/Onboard.tsx","../src/clients/upChunkObservable.ts","../src/util/formatDriveShareLink.ts","../src/util/roundPxString.ts","../src/actions/upload.ts","../src/util/asserters.ts","../src/util/extractFiles.ts","../src/components/SelectAsset.tsx","../src/components/InputBrowser.tsx","../src/hooks/useCancelUpload.ts","../src/components/Player.styled.tsx","../src/components/UploadProgress.tsx","../src/components/Player.tsx","../src/components/withFocusRing/helpers.ts","../src/components/FileInputMenuItem.styled.tsx","../src/components/FileInputMenuItem.tsx","../src/components/PlayerActionsMenu.tsx","../src/hooks/useFetchFileSize.ts","../src/hooks/useMediaMetadata.ts","../src/util/convertWatermarkToMux.ts","../src/util/formatBytes.ts","../src/components/DraggableWatermark.tsx","../src/components/TextTracksEditor.tsx","../src/components/uploadConfiguration/PlaybackPolicyOption.tsx","../src/components/uploadConfiguration/PlaybackPolicyWarning.tsx","../src/components/uploadConfiguration/PlaybackPolicy.tsx","../src/components/uploadConfiguration/ResolutionTierSelector.tsx","../src/components/uploadConfiguration/StaticRenditionSelector.tsx","../src/components/UploadConfiguration.tsx","../src/components/withFocusRing/withFocusRing.ts","../src/components/Uploader.styled.tsx","../src/components/FileInputButton.tsx","../src/components/UploadPlaceholder.tsx","../src/components/Uploader.tsx","../src/components/Input.tsx","../src/plugin.tsx","../src/schema.ts","../src/_exports/index.ts"],"sourcesContent":["/**\n * Icon of a monitor with a play button.\n * Credits: material design icons & react-icons\n */\nconst ToolIcon = () => (\n <svg\n stroke=\"currentColor\"\n fill=\"currentColor\"\n strokeWidth=\"0\"\n viewBox=\"0 0 24 24\"\n height=\"1em\"\n width=\"1em\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z\" />\n </svg>\n)\n\nexport default ToolIcon\n","import {Button, Card, Dialog, Stack, Text} from '@sanity/ui'\nimport React, {createContext, useContext, useState} from 'react'\n\nimport {PluginConfig} from '../util/types'\n\nconst LOCAL_STORAGE_HAS_SHOWN_WARNING_KEY = 'mux-plugin-has-shown-drm-playback-warning'\n\ntype DrmPlaybackWarningContextContextProps = {\n hasShownWarning: boolean\n setHasWarnedAboutDrmPlayback: (b: boolean) => void\n}\n\nconst DrmPlaybackWarningContext = createContext<DrmPlaybackWarningContextContextProps>({\n hasShownWarning: false,\n setHasWarnedAboutDrmPlayback: () => {\n return null\n },\n})\n\ninterface DrmPlaybackWarningContextProviderProps {\n config?: PluginConfig\n children: React.ReactNode\n}\n\nexport const DrmPlaybackWarningContextProvider = ({\n config,\n children,\n}: DrmPlaybackWarningContextProviderProps) => {\n const warningDisabled = config?.disableDrmPlaybackWarning ?? false\n const hasWarned: boolean =\n warningDisabled || window.localStorage.getItem(LOCAL_STORAGE_HAS_SHOWN_WARNING_KEY) === 'true'\n const [hasWarnedAboutDrmPlayback, setHasWarnedAboutDrmPlayback] = useState(hasWarned)\n\n const setHasShownWarning = (b: boolean) => {\n window.localStorage.setItem(LOCAL_STORAGE_HAS_SHOWN_WARNING_KEY, b.toString())\n setHasWarnedAboutDrmPlayback(b)\n }\n return (\n <DrmPlaybackWarningContext.Provider\n value={{\n hasShownWarning: hasWarnedAboutDrmPlayback,\n setHasWarnedAboutDrmPlayback: setHasShownWarning,\n }}\n >\n {children}\n </DrmPlaybackWarningContext.Provider>\n )\n}\n\nexport const useDrmPlaybackWarningContext = () => {\n const context = useContext(DrmPlaybackWarningContext)\n return context\n}\n\nexport const DRMWarningDialog = ({onClose}: {onClose: () => void}) => {\n const {setHasWarnedAboutDrmPlayback} = useDrmPlaybackWarningContext()\n const _onClose = () => {\n setHasWarnedAboutDrmPlayback(true)\n onClose()\n }\n return (\n <Dialog\n open\n id=\"drm-playback-warn\"\n onClose={_onClose}\n header=\"DRM Playback Warning\"\n footer={\n <Stack padding={3}>\n <Button mode=\"ghost\" tone=\"primary\" onClick={_onClose} text=\"Ok\" />\n </Stack>\n }\n >\n <Stack space={3} padding={3}>\n <Card padding={[3, 3, 3]} radius={2}>\n <Stack space={3}>\n <Text size={1} weight=\"semibold\">\n DRM-protected playback will generate a license with a small associated cost. The\n plugin will attempt to play signed or public playback IDs instead whenever possible.\n </Text>\n </Stack>\n </Card>\n <Card padding={[3, 3, 3]} radius={2} tone=\"suggest\">\n <Stack space={3}>\n <Text size={1} weight=\"semibold\">\n This is a one time warning. If it persists, you can disable it from your plugin\n configuration.\n </Text>\n </Stack>\n </Card>\n </Stack>\n </Dialog>\n )\n}\n","// As it's required to specify the API Version this custom hook ensures it's all using the same version\nimport {useClient as useSanityClient} from 'sanity'\n\nexport const SANITY_API_VERSION = '2024-03-05'\n\nexport function useClient() {\n return useSanityClient({apiVersion: SANITY_API_VERSION})\n}\n","// Adaptation of Sanity's createSearchQuery for our limited use case:\n// https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/core/search/weighted/createSearchQuery.ts\nimport {compact, toLower, trim, uniq, words} from 'lodash'\n\nconst SPECIAL_CHARS = /([^!@#$%^&*(),\\\\/?\";:{}|[\\]+<>\\s-])+/g\nconst STRIP_EDGE_CHARS = /(^[.]+)|([.]+$)/\n\nfunction tokenize(string: string): string[] {\n return (string.match(SPECIAL_CHARS) || []).map((token) => token.replace(STRIP_EDGE_CHARS, ''))\n}\n\nfunction toGroqParams(terms: string[]): Record<string, string> {\n const params: Record<string, string> = {}\n return terms.reduce((acc, term, i) => {\n acc[`t${i}`] = `*${term}*` // \"t\" is short for term\n return acc\n }, params)\n}\n\n/**\n * Convert a string into an array of tokenized terms.\n *\n * Any (multi word) text wrapped in double quotes will be treated as \"phrases\", or separate tokens that\n * will not have its special characters removed.\n * E.g.`\"the\" \"fantastic mr\" fox fox book` =\\> [\"the\", `\"fantastic mr\"`, \"fox\", \"book\"]\n *\n * Phrases wrapped in quotes are assigned relevance scoring differently from regular words.\n *\n * @internal\n */\nfunction extractTermsFromQuery(query: string): string[] {\n const quotedQueries = [] as string[]\n const unquotedQuery = query.replace(/(\"[^\"]*\")/g, (match) => {\n if (words(match).length > 1) {\n quotedQueries.push(match)\n return ''\n }\n return match\n })\n\n // Lowercase and trim quoted queries\n const quotedTerms = quotedQueries.map((str) => trim(toLower(str)))\n\n /**\n * Convert (remaining) search query into an array of deduped, sanitized tokens.\n * All white space and special characters are removed.\n * e.g. \"The saint of Saint-Germain-des-Prés\" =\\> ['the', 'saint', 'of', 'germain', 'des', 'pres']\n */\n const remainingTerms = uniq(compact(tokenize(toLower(unquotedQuery))))\n\n return [...quotedTerms, ...remainingTerms]\n}\n\n/**\n * Create GROQ constraints, given search terms and the full spec of available document types and fields.\n * Essentially a large list of all possible fields (joined by logical OR) to match our search terms against.\n */\nfunction createConstraints(terms: string[], includeAssetId: boolean) {\n const searchPaths = includeAssetId ? ['filename', 'assetId'] : ['filename']\n const constraints = terms\n .map((_term, i) => searchPaths.map((joinedPath) => `${joinedPath} match $t${i}`))\n .filter((constraint) => constraint.length > 0)\n\n return constraints.map((constraint) => `(${constraint.join(' || ')})`)\n}\n\nexport function createSearchFilter(query: string) {\n const terms = extractTermsFromQuery(query)\n\n return {\n filter: createConstraints(terms, query.length >= 8), // if the search is big enough, include the assetId (mux id) in the results\n params: {\n ...toGroqParams(terms),\n },\n }\n}\n","import {useMemo, useState} from 'react'\nimport {collate, createHookFromObservableFactory, DocumentStore, useDocumentStore} from 'sanity'\n\nimport {SANITY_API_VERSION} from '../hooks/useClient'\nimport {createSearchFilter} from '../util/createSearchFilter'\nimport type {VideoAssetDocument} from '../util/types'\n\nexport const ASSET_SORT_OPTIONS = {\n createdDesc: {groq: '_createdAt desc', label: 'Newest first'},\n createdAsc: {groq: '_createdAt asc', label: 'First created (oldest)'},\n filenameAsc: {groq: 'filename asc', label: 'By filename (A-Z)'},\n filenameDesc: {groq: 'filename desc', label: 'By filename (Z-A)'},\n}\n\nexport type SortOption = keyof typeof ASSET_SORT_OPTIONS\n\nconst useAssetDocuments = createHookFromObservableFactory<\n VideoAssetDocument[],\n {\n documentStore: DocumentStore\n sort: SortOption\n searchQuery: string\n }\n>(({documentStore, sort, searchQuery}) => {\n const search = createSearchFilter(searchQuery)\n const filter = [`_type == \"mux.videoAsset\"`, ...search.filter].filter(Boolean).join(' && ')\n\n const sortFragment = ASSET_SORT_OPTIONS[sort].groq\n return documentStore.listenQuery(\n /* groq */ `*[${filter}] | order(${sortFragment})`,\n search.params,\n {\n apiVersion: SANITY_API_VERSION,\n }\n )\n})\n\nexport default function useAssets() {\n const documentStore = useDocumentStore()\n const [sort, setSort] = useState<SortOption>('createdDesc')\n const [searchQuery, setSearchQuery] = useState('')\n\n const [assetDocuments = [], isLoading] = useAssetDocuments(\n useMemo(() => ({documentStore, sort, searchQuery}), [documentStore, sort, searchQuery])\n )\n\n const assets = useMemo(\n () =>\n // Avoid displaying both drafts & published assets by collating them together and giving preference to drafts\n collate<VideoAssetDocument>(assetDocuments).map(\n (collated) =>\n ({\n ...(collated.draft || collated.published || {}),\n _id: collated.id,\n }) as VideoAssetDocument\n ),\n [assetDocuments]\n )\n\n return {\n assets,\n isLoading,\n sort,\n searchQuery,\n setSort,\n setSearchQuery,\n }\n}\n","// Handy little state machine to simplify managing which root level dialog to open\n\nimport {useState} from 'react'\n\nexport type DialogState = 'secrets' | 'select-video' | 'edit-thumbnail' | 'edit-captions' | false\n\nexport function useDialogState() {\n return useState<DialogState>(false)\n}\n\nexport type SetDialogState = ReturnType<typeof useDialogState>[1]\n","import {defer} from 'rxjs'\nimport type {SanityClient} from 'sanity'\n\ninterface SecretsDocument {\n _id: 'secrets.mux'\n _type: 'mux.apiKey'\n token: string\n secretKey: string\n enableSignedUrls: boolean\n signingKeyId: string\n signingKeyPrivate: string\n drmConfigId: string\n}\n// eslint-disable-next-line max-params\nexport function saveSecrets(\n client: SanityClient,\n token: string,\n secretKey: string,\n enableSignedUrls: boolean,\n signingKeyId: string,\n signingKeyPrivate: string,\n drmConfigId: string\n): Promise<SecretsDocument> {\n const doc: SecretsDocument = {\n _id: 'secrets.mux',\n _type: 'mux.apiKey',\n token,\n secretKey,\n enableSignedUrls,\n signingKeyId,\n signingKeyPrivate,\n drmConfigId,\n }\n doc.signingKeyId = enableSignedUrls ? signingKeyId : ''\n doc.signingKeyPrivate = enableSignedUrls ? signingKeyPrivate : ''\n\n return client.createOrReplace(doc)\n}\n\nexport async function createSigningKeys(client: SanityClient) {\n try {\n const {dataset} = client.config()\n const res = await client.request<{\n data: {private_key: string; id: string; created_at: string}\n }>({\n url: `/addons/mux/signing-keys/${dataset}`,\n withCredentials: true,\n method: 'POST',\n })\n return res\n } catch (error: any) {\n console.error('Error creating signing keys', error)\n const message =\n error.response?.statusCode === 401\n ? 'Unauthorized - Failed to create the Signing Key. Please ensure that the token has \"System\" permissions'\n : error.message\n throw new Error(message)\n }\n}\n\nexport function testSecrets(client: SanityClient) {\n const {dataset} = client.config()\n return client.request<{status: boolean}>({\n url: `/addons/mux/secrets/${dataset}/test`,\n withCredentials: true,\n method: 'GET',\n })\n}\n\nexport async function haveValidSigningKeys(\n client: SanityClient,\n signingKeyId: string,\n signingKeyPrivate: string\n) {\n if (!(signingKeyId && signingKeyPrivate)) {\n return false\n }\n\n const {dataset} = client.config()\n try {\n const res = await client.request<{data: {id: string; created_at: string}}>({\n url: `/addons/mux/signing-keys/${dataset}/${signingKeyId}`,\n withCredentials: true,\n method: 'GET',\n })\n //\n // if this signing key is valid it will return { data: { id: 'xxxx' } }\n //\n return !!(res.data && res.data.id)\n } catch (e) {\n console.error('Error fetching signingKeyId', signingKeyId, 'assuming it is not valid')\n return false\n }\n}\n\nexport function testSecretsObservable(client: SanityClient) {\n const {dataset} = client.config()\n return defer(() =>\n client.observable.request<{status: boolean}>({\n url: `/addons/mux/secrets/${dataset}/test`,\n withCredentials: true,\n method: 'GET',\n })\n )\n}\n","import {useCallback} from 'react'\nimport type {SanityClient} from 'sanity'\n\nimport {createSigningKeys, haveValidSigningKeys, saveSecrets, testSecrets} from '../actions/secrets'\nimport type {Secrets} from '../util/types'\n\nexport const useSaveSecrets = (client: SanityClient, secrets: Secrets) => {\n return useCallback(\n async ({\n token,\n secretKey,\n enableSignedUrls,\n drmConfigId,\n }: Pick<\n Secrets,\n 'token' | 'secretKey' | 'enableSignedUrls' | 'drmConfigId'\n >): Promise<Secrets> => {\n let {signingKeyId, signingKeyPrivate} = secrets\n\n try {\n await saveSecrets(\n client,\n token!,\n secretKey!,\n enableSignedUrls,\n signingKeyId!,\n signingKeyPrivate!,\n drmConfigId!\n )\n const valid = await testSecrets(client)\n if (!valid?.status && token && secretKey) {\n throw new Error('Invalid secrets')\n }\n } catch (err) {\n console.error('Error while trying to save secrets:', err)\n throw err\n }\n\n if (enableSignedUrls) {\n const hasValidSigningKeys = await haveValidSigningKeys(\n client,\n signingKeyId!,\n signingKeyPrivate!\n )\n\n if (!hasValidSigningKeys) {\n try {\n const {data} = await createSigningKeys(client)\n signingKeyId = data.id\n signingKeyPrivate = data.private_key\n await saveSecrets(\n client,\n token!,\n secretKey!,\n enableSignedUrls,\n signingKeyId,\n signingKeyPrivate,\n drmConfigId ?? ''\n )\n } catch (err: any) {\n // eslint-disable-next-line no-console\n console.log('Error while creating and saving signing key:', err?.message)\n throw err\n }\n }\n }\n return {\n token,\n secretKey,\n enableSignedUrls,\n signingKeyId,\n signingKeyPrivate,\n drmConfigId,\n }\n },\n [client, secrets]\n )\n}\n","export const name = 'mux-input' as const\n\n// Caching namespace, as suspend-react might be in use by other components on the page we must ensure we don't collide\nexport const cacheNs = 'sanity-plugin-mux-input' as const\n\nexport const muxSecretsDocumentId = 'secrets.mux' as const\n\nexport const DIALOGS_Z_INDEX = 60_000\n\nexport const THUMBNAIL_ASPECT_RATIO = 16 / 9\n\n/** To prevent excessive height, thumbnails and input should not go beyond to this aspect ratio. */\nexport const MIN_ASPECT_RATIO = 5 / 4\n\nexport const AUDIO_ASPECT_RATIO = 5 / 1\n","import {useMemo} from 'react'\nimport {useDocumentValues} from 'sanity'\n\nimport {muxSecretsDocumentId} from '../util/constants'\nimport type {Secrets} from '../util/types'\n\nconst path = [\n 'token',\n 'secretKey',\n 'enableSignedUrls',\n 'signingKeyId',\n 'signingKeyPrivate',\n 'drmConfigId',\n]\nexport const useSecretsDocumentValues = () => {\n const {error, isLoading, value} = useDocumentValues<Partial<Secrets> | null | undefined>(\n muxSecretsDocumentId,\n path\n )\n const cache = useMemo(() => {\n const exists = Boolean(value)\n const secrets: Secrets = {\n token: value?.token || null,\n secretKey: value?.secretKey || null,\n enableSignedUrls: value?.enableSignedUrls || false,\n signingKeyId: value?.signingKeyId || null,\n signingKeyPrivate: value?.signingKeyPrivate || null,\n drmConfigId: value?.drmConfigId || null,\n }\n return {\n isInitialSetup: !exists,\n needsSetup: !secrets?.token || !secrets?.secretKey,\n secrets,\n }\n }, [value])\n\n return {error, isLoading, value: cache}\n}\n","import {useReducer} from 'react'\n\nimport type {Secrets} from '../util/types'\n\nexport interface State\n extends Pick<Secrets, 'token' | 'secretKey' | 'enableSignedUrls' | 'drmConfigId'> {\n submitting: boolean\n error: string | null\n}\nexport type Action =\n | {type: 'submit'}\n | {type: 'error'; payload: string}\n | {type: 'reset'; payload: Secrets}\n | {type: 'change'; payload: {name: 'token'; value: string}}\n | {type: 'change'; payload: {name: 'secretKey'; value: string}}\n | {type: 'change'; payload: {name: 'enableSignedUrls'; value: boolean}}\n | {type: 'change'; payload: {name: 'drmConfigId'; value: string}}\nfunction init({token, secretKey, enableSignedUrls, drmConfigId}: Secrets): State {\n return {\n submitting: false,\n error: null,\n // Form inputs don't set the state back to null when clearing a field, but uses empty strings\n // This ensures the `dirty` check works correctly\n token: token ?? '',\n secretKey: secretKey ?? '',\n enableSignedUrls: enableSignedUrls ?? false,\n drmConfigId: drmConfigId ?? '',\n }\n}\nfunction reducer(state: State, action: Action) {\n switch (action?.type) {\n case 'submit':\n return {...state, submitting: true, error: null}\n case 'error':\n return {...state, submitting: false, error: action.payload}\n case 'reset':\n return init(action.payload)\n case 'change':\n return {...state, [action.payload.name]: action.payload.value}\n default:\n throw new Error(`Unknown action type: ${(action as unknown as Action)?.type}`)\n }\n}\n\nexport const useSecretsFormState = (secrets: Secrets) => useReducer(reducer, secrets, init)\n","// Utils with a readName prefix are suspendable and should only be called in the render body\n// Not inside event callbacks or a useEffect.\n// They may be called dynamically, unlike useEffect\n\n// @TODO rename to readSigningPair\n\nimport type {SanityClient} from 'sanity'\nimport {suspend} from 'suspend-react'\n\nimport {cacheNs} from '../util/constants'\nimport {type Secrets} from '../util/types'\n\nexport const _id = 'secrets.mux' as const\n\nexport function readSecrets(client: SanityClient): Secrets {\n const {projectId, dataset} = client.config()\n return suspend(async () => {\n const data = await client.fetch(\n /* groq */ `*[_id == $_id][0]{\n token,\n secretKey,\n enableSignedUrls,\n signingKeyId,\n signingKeyPrivate,\n drmConfigId\n }`,\n {_id}\n )\n return {\n token: data?.token || null,\n secretKey: data?.secretKey || null,\n enableSignedUrls: Boolean(data?.enableSignedUrls) || false,\n signingKeyId: data?.signingKeyId || null,\n signingKeyPrivate: data?.signingKeyPrivate || null,\n drmConfigId: data?.drmConfigId || null,\n }\n }, [cacheNs, _id, projectId, dataset])\n}\n","import {useTheme_v2} from '@sanity/ui'\nimport {CSSProperties, useId, useMemo} from 'react'\n\nexport interface Props {\n height?: number\n}\nexport default function MuxLogo({height = 26}: Props) {\n const id = useId()\n const theme = useTheme_v2()\n const fillColor = theme.color._dark ? 'white' : 'black'\n const titleId = useMemo(() => `${id}-title`, [id])\n\n const pathStyle: CSSProperties = {\n fillRule: 'nonzero',\n }\n\n return (\n <svg\n aria-labelledby={titleId}\n style={{height: `${height}px`}}\n viewBox=\"0 0 1600 500\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlSpace=\"preserve\"\n >\n <g id=\"Layer-1\" fill={fillColor}>\n <path\n d=\"M994.287,93.486c-17.121,-0 -31,-13.879 -31,-31c0,-17.121 13.879,-31 31,-31c17.121,-0 31,13.879 31,31c0,17.121 -13.879,31 -31,31m0,-93.486c-34.509,-0 -62.484,27.976 -62.484,62.486l0,187.511c0,68.943 -56.09,125.033 -125.032,125.033c-68.942,-0 -125.03,-56.09 -125.03,-125.033l0,-187.511c0,-34.51 -27.976,-62.486 -62.485,-62.486c-34.509,-0 -62.484,27.976 -62.484,62.486l0,187.511c0,137.853 112.149,250.003 249.999,250.003c137.851,-0 250.001,-112.15 250.001,-250.003l0,-187.511c0,-34.51 -27.976,-62.486 -62.485,-62.486\"\n style={pathStyle}\n />\n <path\n d=\"M1537.51,468.511c-17.121,-0 -31,-13.879 -31,-31c0,-17.121 13.879,-31 31,-31c17.121,-0 31,13.879 31,31c0,17.121 -13.879,31 -31,31m-275.883,-218.509l-143.33,143.329c-24.402,24.402 -24.402,63.966 0,88.368c24.402,24.402 63.967,24.402 88.369,-0l143.33,-143.329l143.328,143.329c24.402,24.4 63.967,24.402 88.369,-0c24.403,-24.402 24.403,-63.966 0.001,-88.368l-143.33,-143.329l0.001,-0.004l143.329,-143.329c24.402,-24.402 24.402,-63.965 0,-88.367c-24.402,-24.402 -63.967,-24.402 -88.369,-0l-143.329,143.328l-143.329,-143.328c-24.402,-24.401 -63.967,-24.402 -88.369,-0c-24.402,24.402 -24.402,63.965 0,88.367l143.329,143.329l0,0.004Z\"\n style={pathStyle}\n />\n <path\n d=\"M437.511,468.521c-17.121,-0 -31,-13.879 -31,-31c0,-17.121 13.879,-31 31,-31c17.121,-0 31,13.879 31,31c0,17.121 -13.879,31 -31,31m23.915,-463.762c-23.348,-9.672 -50.226,-4.327 -68.096,13.544l-143.331,143.329l-143.33,-143.329c-17.871,-17.871 -44.747,-23.216 -68.096,-13.544c-23.349,9.671 -38.574,32.455 -38.574,57.729l0,375.026c0,34.51 27.977,62.486 62.487,62.486c34.51,-0 62.486,-27.976 62.486,-62.486l0,-224.173l80.843,80.844c24.404,24.402 63.965,24.402 88.369,-0l80.843,-80.844l0,224.173c0,34.51 27.976,62.486 62.486,62.486c34.51,-0 62.486,-27.976 62.486,-62.486l0,-375.026c0,-25.274 -15.224,-48.058 -38.573,-57.729\"\n style={pathStyle}\n />\n </g>\n </svg>\n )\n}\n","import {styled} from 'styled-components'\n\nimport MuxLogo from './MuxLogo'\n\nconst Logo = styled.span`\n display: inline-block;\n height: 0.8em;\n margin-right: 1em;\n transform: translate(0.3em, -0.2em);\n`\n\nexport const Header = () => (\n <>\n <Logo>\n <MuxLogo height={13} />\n </Logo>\n API Credentials\n </>\n)\n","import {Box, Flex, Stack, Text} from '@sanity/ui'\nimport React, {memo} from 'react'\n\n// @TODO: get rid of this once v3 core is stable\n\nexport interface Props {\n children: React.ReactNode\n title: React.ReactNode\n description?: React.ReactNode\n inputId: string\n}\n\nfunction FormField(props: Props) {\n const {children, title, description, inputId} = props\n\n return (\n <Stack space={1}>\n <Flex align=\"flex-end\">\n <Box flex={1} paddingY={2}>\n <Stack space={2}>\n <Text as=\"label\" htmlFor={inputId} weight=\"semibold\" size={1}>\n {title || <em>Untitled</em>}\n </Text>\n\n {description && (\n <Text muted size={1}>\n {description}\n </Text>\n )}\n </Stack>\n </Box>\n </Flex>\n <div>{children}</div>\n </Stack>\n )\n}\n\nexport default memo(FormField)\n","import {\n Box,\n Button,\n Card,\n Checkbox,\n Code,\n Dialog,\n Flex,\n Inline,\n Stack,\n Text,\n TextInput,\n} from '@sanity/ui'\nimport {useCallback, useEffect, useId, useMemo, useRef} from 'react'\nimport {clear, preload} from 'suspend-react'\n\nimport {useClient} from '../hooks/useClient'\nimport type {SetDialogState} from '../hooks/useDialogState'\nimport {useDialogState} from '../hooks/useDialogState'\nimport {useSaveSecrets} from '../hooks/useSaveSecrets'\nimport {useSecretsDocumentValues} from '../hooks/useSecretsDocumentValues'\nimport {useSecretsFormState} from '../hooks/useSecretsFormState'\nimport {cacheNs, DIALOGS_Z_INDEX} from '../util/constants'\nimport {_id as secretsId} from '../util/readSecrets'\nimport type {Secrets} from '../util/types'\nimport {Header} from './ConfigureApi.styled'\nimport FormField from './FormField'\n\n// Props for the dialog component when used with external state management\nexport interface ConfigureApiDialogProps {\n setDialogState: SetDialogState\n secrets: Secrets\n}\n\nconst fieldNames = ['token', 'secretKey', 'enableSignedUrls', 'drmConfigId'] as const\n\n// Internal dialog component that can be used with external state\nexport function ConfigureApiDialog({secrets, setDialogState}: ConfigureApiDialogProps) {\n const client = useClient()\n const [state, dispatch] = useSecretsFormState(secrets)\n const hasSecretsInitially = useMemo(() => secrets.token && secrets.secretKey, [secrets])\n const handleClose = useCallback(() => setDialogState(false), [setDialogState])\n const dirty = useMemo(\n () =>\n secrets.token !== state.token ||\n secrets.secretKey !== state.secretKey ||\n secrets.enableSignedUrls !== state.enableSignedUrls ||\n secrets.drmConfigId !== state.drmConfigId,\n [secrets, state]\n )\n const id = `ConfigureApi${useId()}`\n const [tokenId, secretKeyId, enableSignedUrlsId, drmConfigIdId] = useMemo<typeof fieldNames>(\n () => fieldNames.map((field) => `${id}-${field}`) as unknown as typeof fieldNames,\n [id]\n )\n const firstField = useRef<HTMLInputElement>(null)\n const handleSaveSecrets = useSaveSecrets(client, secrets)\n const saving = useRef(false)\n\n const handleSubmit = useCallback(\n (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n\n if (!saving.current && event.currentTarget.reportValidity()) {\n saving.current = true\n dispatch({type: 'submit'})\n const {token, secretKey, enableSignedUrls, drmConfigId} = state\n handleSaveSecrets({token, secretKey, enableSignedUrls, drmConfigId})\n .then((savedSecrets) => {\n const {projectId, dataset} = client.config()\n clear([cacheNs, secretsId, projectId, dataset])\n preload(() => Promise.resolve(savedSecrets), [cacheNs, secretsId, projectId, dataset])\n setDialogState(false)\n })\n .catch((err) => dispatch({type: 'error', payload: err.message}))\n .finally(() => {\n saving.current = false\n })\n }\n },\n [client, dispatch, handleSaveSecrets, setDialogState, state]\n )\n const handleChangeToken = useCallback(\n (event: React.FormEvent<HTMLInputElement>) => {\n dispatch({\n type: 'change',\n payload: {name: 'token', value: event.currentTarget.value},\n })\n },\n [dispatch]\n )\n const handleChangeSecretKey = useCallback(\n (event: React.FormEvent<HTMLInputElement>) => {\n dispatch({\n type: 'change',\n payload: {name: 'secretKey', value: event.currentTarget.value},\n })\n },\n [dispatch]\n )\n const handleChangeEnableSignedUrls = useCallback(\n (event: React.FormEvent<HTMLInputElement>) => {\n dispatch({\n type: 'change',\n payload: {name: 'enableSignedUrls', value: event.currentTarget.checked},\n })\n },\n [dispatch]\n )\n const handleChangeDrmConfigId = useCallback(\n (event: React.FormEvent<HTMLInputElement>) => {\n dispatch({\n type: 'change',\n payload: {name: 'drmConfigId', value: event.currentTarget.value},\n })\n },\n [dispatch]\n )\n\n useEffect(() => {\n if (firstField.current) {\n firstField.current.focus()\n }\n }, [firstField])\n\n return (\n <Dialog\n animate\n id={id}\n onClose={handleClose}\n onClickOutside={handleClose}\n header={<Header />}\n zOffset={DIALOGS_Z_INDEX}\n position=\"fixed\"\n width={1}\n >\n <Box padding={3}>\n <form onSubmit={handleSubmit} noValidate>\n <Stack space={4}>\n {!hasSecretsInitially && (\n <Card padding={[3, 3, 3]} radius={2} shadow={1} tone=\"primary\">\n <Stack space={3}>\n <Text size={1}>\n To set up a new access token, go to your{' '}\n <a\n href=\"https://dashboard.mux.com/settings/access-tokens\"\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n >\n account on mux.com\n </a>\n .\n </Text>\n <Text size={1}>\n The access token needs permissions: <strong>Mux Video </strong>\n (Full Access) and <strong>Mux Data</strong> (Read)\n <br />\n To use Signed URLs, the token must also have System permissions.\n <br />\n The credentials will be stored safely in a hidden document only available to\n editors.\n </Text>\n </Stack>\n </Card>\n )}\n <FormField title=\"Access Token\" inputId={tokenId}>\n <TextInput\n id={tokenId}\n ref={firstField}\n onChange={handleChangeToken}\n type=\"text\"\n value={state.token ?? ''}\n required={!!state.secretKey || state.enableSignedUrls}\n />\n </FormField>\n <FormField title=\"Secret Key\" inputId={secretKeyId}>\n <TextInput\n id={secretKeyId}\n onChange={handleChangeSecretKey}\n type=\"text\"\n value={state.secretKey ?? ''}\n required={!!state.token || state.enableSignedUrls}\n />\n </FormField>\n\n <Stack space={4}>\n <Flex align=\"center\">\n <Checkbox\n id={enableSignedUrlsId}\n onChange={handleChangeEnableSignedUrls}\n checked={state.enableSignedUrls}\n style={{display: 'block'}}\n />\n <Box flex={1} paddingLeft={3}>\n <Text>\n <label htmlFor={enableSignedUrlsId}>Enable Signed Urls</label>\n </Text>\n </Box>\n </Flex>\n {secrets.signingKeyId && state.enableSignedUrls ? (\n <Card padding={[3, 3, 3]} radius={2} shadow={1} tone=\"caution\">\n <Stack space={3}>\n <Text size={1}>The signing key ID that Sanity will use is:</Text>\n <Code size={1}>{secrets.signingKeyId}</Code>\n <Text size={1}>\n This key is only used for previewing content in the Sanity UI.\n <br />\n You should generate a different key to use in your application server.\n </Text>\n </Stack>\n </Card>\n ) : null}\n </Stack>\n\n <FormField title=\"DRM Configuration ID\" inputId={drmConfigIdId}>\n <TextInput\n id={drmConfigIdId}\n onChange={handleChangeDrmConfigId}\n type=\"text\"\n value={state.drmConfigId ?? ''}\n required={false}\n />\n </FormField>\n <Card padding={[3, 3, 3]} radius={2} shadow={1} tone=\"neutral\">\n <Stack space={3}>\n <Text size={1}>\n DRM (Digital Rights Management) provides an extra layer of content security for\n video content streamed from Mux. For additional information check out our{' '}\n <a\n href=\"https://www.mux.com/docs/guides/protect-videos-with-drm#play-drm-protected-videos\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n DRM Guide\n </a>\n .\n </Text>\n <Text size={1}>\n <a\n href=\"https://www.mux.com/support/human\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Contact us\n </a>{' '}\n to get started using DRM.\n </Text>\n </Stack>\n </Card>\n\n <Inline space={2}>\n <Button\n text=\"Save\"\n disabled={!dirty}\n loading={state.submitting}\n tone=\"primary\"\n mode=\"default\"\n type=\"submit\"\n />\n <Button\n disabled={state.submitting}\n text=\"Cancel\"\n mode=\"bleed\"\n onClick={handleClose}\n />\n </Inline>\n {state.error && (\n <Card padding={[3, 3, 3]} radius={2} shadow={1} tone=\"critical\">\n <Text>{state.error}</Text>\n </Card>\n )}\n </Stack>\n </form>\n </Box>\n </Dialog>\n )\n}\n\n// Wrapper component that manages its own dialog state (used in VideosBrowser)\nexport default function ConfigureApi() {\n const [dialogOpen, setDialogOpen] = useDialogState()\n const secretDocumentValues = useSecretsDocumentValues()\n\n const openDialog = useCallback(() => setDialogOpen('secrets'), [setDialogOpen])\n\n if (dialogOpen === 'secrets') {\n return (\n <ConfigureApiDialog\n secrets={secretDocumentValues.value.secrets}\n setDialogState={setDialogOpen}\n />\n )\n }\n\n return <Button mode=\"bleed\" text=\"Configure plugin\" onClick={openDialog} />\n}\n","import {truncateString} from 'sanity'\n\n/**\n * Generates a placeholder title for a Mux asset when no title is available.\n * This format is used when importing assets that don't have a title in Mux.\n *\n * @param assetId - The Mux asset ID\n * @returns A placeholder title in the format \"Asset #[truncated-id]\"\n */\nexport function generateAssetPlaceholder(assetId: string): string {\n return `Asset #${truncateString(assetId, 15)}`\n}\n\n/**\n * Checks if a filename is empty or has the placeholder format.\n * This is used to determine if a video title should be updated during metadata sync.\n *\n * @param filename - The current filename/title of the video\n * @param assetId - The Mux asset ID to check against\n * @returns true if the filename is empty or matches the placeholder format\n */\nexport function isEmptyOrPlaceholderTitle(filename: string | undefined, assetId: string): boolean {\n // Check if filename is empty/undefined\n if (!filename || filename.trim() === '') {\n return true\n }\n\n // Check if filename matches the placeholder format for this asset\n const placeholder = generateAssetPlaceholder(assetId)\n return filename === placeholder\n}\n","import type {MuxAsset} from './types'\n\nexport function parseMuxDate(date: MuxAsset['created_at']): Date {\n return new Date(Number(date) * 1000)\n}\n","import type {SanityClient} from 'sanity'\n\nimport type {MuxAsset, VideoAssetDocument} from '../util/types'\n\nexport function deleteAssetOnMux(client: SanityClient, assetId: string) {\n const {dataset} = client.config()\n return client.request<void>({\n url: `/addons/mux/assets/${dataset}/${assetId}`,\n withCredentials: true,\n method: 'DELETE',\n })\n}\n\nexport async function deleteAsset({\n client,\n asset,\n deleteOnMux,\n}: {\n client: SanityClient\n asset: VideoAssetDocument\n deleteOnMux: boolean\n}) {\n if (!asset?._id) return true\n\n try {\n await client.delete(asset._id)\n } catch (error) {\n return 'failed-sanity'\n }\n\n if (deleteOnMux && asset?.assetId) {\n try {\n await deleteAssetOnMux(client, asset.assetId)\n } catch (error) {\n return 'failed-mux'\n }\n }\n\n return true\n}\n\nexport function getAsset(client: SanityClient, assetId: string) {\n const {dataset} = client.config()\n return client.request<{data: MuxAsset}>({\n url: `/addons/mux/assets/${dataset}/data/${assetId}`,\n withCredentials: true,\n method: 'GET',\n })\n}\n\nexport function listAssets(\n client: SanityClient,\n options: {limit?: number; cursor?: string | null}\n) {\n const {dataset} = client.config()\n const query: {limit?: string; cursor?: string} = {}\n\n if (options.limit) {\n query.limit = options.limit.toString()\n }\n if (options.cursor) {\n query.cursor = options.cursor\n }\n\n return client.request<{data: MuxAsset[]; next_cursor?: string | null}>({\n url: `/addons/mux/assets/${dataset}/data/list`,\n withCredentials: true,\n method: 'GET',\n query,\n })\n}\n\n/**\n * Adds a new text track to an existing asset using a VTT file URL\n */\nexport function addTextTrackFromUrl(\n client: SanityClient,\n assetId: string,\n vttUrl: string,\n options: {\n language_code: string\n name: string\n text_type?: 'subtitles'\n }\n) {\n const {dataset} = client.config()\n\n return client.request<{data: MuxAsset}>({\n url: `/addons/mux/assets/${dataset}/${assetId}/tracks`,\n withCredentials: true,\n method: 'POST',\n body: {\n url: vttUrl,\n type: 'text',\n language_code: options.language_code,\n name: options.name,\n text_type: options.text_type || 'subtitles',\n },\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n}\n\n/**\n * Generates subtitles automatically for an audio track\n */\nexport function generateSubtitles(\n client: SanityClient,\n assetId: string,\n audioTrackId: string,\n options: {\n language_code: string\n name: string\n }\n) {\n const {dataset} = client.config()\n return client.request<{data: MuxAsset}>({\n url: `/addons/mux/assets/${dataset}/${assetId}/tracks/${audioTrackId}/generate-subtitles`,\n withCredentials: true,\n method: 'POST',\n body: {\n generated_subtitles: [\n {\n language_code: options.language_code,\n name: options.name,\n },\n ],\n },\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n}\n\n/**\n * Deletes a text track from an asset\n */\nexport function deleteTextTrack(client: SanityClient, assetId: string, trackId: string) {\n const {dataset} = client.config()\n return client.request<{data: MuxAsset}>({\n url: `/addons/mux/assets/${dataset}/${assetId}/tracks/${trackId}`,\n withCredentials: true,\n method: 'DELETE',\n })\n}\n","import {useEffect, useState} from 'react'\nimport {defer, of, timer} from 'rxjs'\nimport {concatMap, expand, tap} from 'rxjs/operators'\nimport type {SanityClient} from 'sanity'\n\nimport {listAssets} from '../actions/assets'\nimport type {MuxAsset} from '../util/types'\n\nconst ASSETS_PER_PAGE = 100\n\ntype MuxAssetsState = {\n cursor: string | null\n loading: boolean\n data?: MuxAsset[]\n error?: FetchError\n hasSkippedAssetsWithoutPlayback?: boolean\n}\n\ntype FetchError =\n | {\n _tag: 'FetchError'\n }\n | {_tag: 'MuxError'; error: unknown}\n\ntype PageResult = (\n | {\n data: MuxAsset[]\n next_cursor: string | null\n }\n | {\n error: FetchError\n }\n) & {\n cursor: string | null\n}\n\n/**\n * @docs {@link https://docs.mux.com/api-reference#video/operation/list-assets}\n */\nasync function fetchMuxAssetsPage(\n client: SanityClient,\n cursor: string | null\n): Promise<PageResult> {\n try {\n const response = await listAssets(client, {\n limit: ASSETS_PER_PAGE,\n cursor,\n })\n\n return {\n cursor,\n data: response.data as MuxAsset[],\n next_cursor: response.next_cursor || null,\n }\n } catch (error) {\n return {\n cursor,\n error: {_tag: 'FetchError'},\n }\n }\n}\n\nfunction accumulateIntermediateState(\n currentState: MuxAssetsState,\n pageResult: PageResult\n): MuxAssetsState {\n const currentData = ('data' in currentState && currentState.data) || []\n const newAssets = ('data' in pageResult && pageResult.data) || []\n\n // Filter assets and check for skipped items\n const {validAssets, skippedInThisPage} = newAssets.reduce<{\n validAssets: MuxAsset[]\n skippedInThisPage: boolean\n }>(\n (acc, asset) => {\n const hasPlaybackIds = asset.playback_ids && asset.playback_ids.length > 0\n const isDuplicate = currentData.some((a) => a.id === asset.id)\n\n if (!hasPlaybackIds) {\n acc.skippedInThisPage = true\n }\n\n if (hasPlaybackIds && !isDuplicate) {\n acc.validAssets.push(asset)\n }\n\n return acc\n },\n {validAssets: [], skippedInThisPage: false}\n )\n\n return {\n ...currentState,\n data: [...currentData, ...validAssets],\n error:\n 'error' in pageResult\n ? pageResult.error\n : // Reset error if current page is successful\n undefined,\n cursor: 'next_cursor' in pageResult ? pageResult.next_cursor : pageResult.cursor,\n loading: true,\n hasSkippedAssetsWithoutPlayback:\n currentState.hasSkippedAssetsWithoutPlayback || skippedInThisPage,\n }\n}\n\nfunction hasMorePages(pageResult: PageResult) {\n return (\n typeof pageResult === 'object' && 'next_cursor' in pageResult && pageResult.next_cursor !== null\n )\n}\n\n/**\n * Fetches all assets from a Mux environment. Rules:\n * - One page at a time\n * - Uses cursor-based pagination\n * - We've finished fetching when `next_cursor` is null\n * - Rate limiting to one request per 2 seconds\n * - Update state while still fetching to give feedback to users\n */\nexport default function useMuxAssets({client, enabled}: {client: SanityClient; enabled: boolean}) {\n const [state, setState] = useState<MuxAssetsState>({loading: true, cursor: null})\n\n useEffect(() => {\n if (!enabled) return\n\n const subscription = defer(() =>\n fetchMuxAssetsPage(\n client,\n // When we've already successfully loaded before (fully or partially), we start from the next cursor to avoid re-fetching\n 'data' in state && state.data && state.data.length > 0 && !state.error ? state.cursor : null\n )\n )\n .pipe(\n // Here we use \"expand\" to recursively fetch next pages\n expand((pageResult) => {\n // if fetched page has next_cursor, we continue emitting, requesting the next page\n // after 2s to avoid rate limiting\n if (hasMorePages(pageResult)) {\n return timer(2000).pipe(\n concatMap(() =>\n // eslint-disable-next-line max-nested-callbacks\n defer(() =>\n fetchMuxAssetsPage(\n client,\n 'next_cursor' in pageResult ? pageResult.next_cursor : null\n )\n )\n )\n )\n }\n\n // Else, we stop emitting\n return of()\n }),\n\n // On each iteration, persist intermediate states to give feedback to users\n tap((pageResult) =>\n setState((prevState) => accumulateIntermediateState(prevState, pageResult))\n )\n )\n .subscribe({\n // Once done, let the user know we've stopped loading\n complete: () => {\n setState((prev) => ({\n ...prev,\n loading: false,\n }))\n },\n })\n\n // Unsubscribe on component unmount to prevent memory leaks or fetching unnecessarily\n // eslint-disable-next-line consistent-return\n return () => subscription.unsubscribe()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled])\n\n return state\n}\n","import {uuid} from '@sanity/uuid'\nimport {useMemo, useState} from 'react'\nimport {\n createHookFromObservableFactory,\n type DocumentStore,\n useClient,\n useDocumentStore,\n} from 'sanity'\n\nimport {generateAssetPlaceholder} from '../util/assetTitlePlaceholder'\nimport {parseMuxDate} from '../util/parsers'\nimport type {MuxAsset, VideoAssetDocument} from '../util/types'\nimport {SANITY_API_VERSION} from './useClient'\nimport useMuxAssets from './useMuxAssets'\nimport {useSecretsDocumentValues} from './useSecretsDocumentValues'\n\ntype ImportState = 'closed' | 'idle' | 'importing' | 'done' | 'error'\n\nexport type AssetInSanity = {\n uploadId: string\n assetId: string\n}\n\nexport default function useImportMuxAssets() {\n const documentStore = useDocumentStore()\n const client = useClient({\n apiVersion: SANITY_API_VERSION,\n })\n\n const [assetsInSanity, assetsInSanityLoading] = useAssetsInSanity(documentStore)\n\n const secretDocumentValues = useSecretsDocumentValues()\n const hasSecrets = !!secretDocumentValues.value.secrets?.secretKey\n\n const [importError, setImportError] = useState<unknown>()\n const [importState, setImportState] = useState<ImportState>('closed')\n const dialogOpen = importState !== 'closed'\n\n const muxAssets = useMuxAssets({\n client,\n enabled: hasSecrets && dialogOpen,\n })\n\n const missingAssets = useMemo(() => {\n return assetsInSanity && muxAssets.data\n ? muxAssets.data.filter((a) => !assetExistsInSanity(a, assetsInSanity))\n : undefined\n }, [assetsInSanity, muxAssets.data])\n\n const [selectedAssets, setSelectedAssets] = useState<MuxAsset[]>([])\n\n const closeDialog = () => {\n if (importState !== 'importing') setImportState('closed')\n }\n const openDialog = () => {\n if (importState === 'closed') setImportState('idle')\n }\n\n async function importAssets() {\n setImportState('importing')\n const documents = selectedAssets.flatMap((asset) => muxAssetToSanityDocument(asset) || [])\n\n const tx = client.transaction()\n documents.forEach((doc) => tx.create(doc))\n\n try {\n await tx.commit({returnDocuments: false})\n setSelectedAssets([])\n setImportState('done')\n } catch (error) {\n setImportState('error')\n setImportError(error)\n }\n }\n\n return {\n assetsInSanityLoading,\n closeDialog,\n dialogOpen,\n importState,\n importError,\n hasSecrets,\n importAssets,\n missingAssets,\n muxAssets,\n openDialog,\n selectedAssets,\n setSelectedAssets,\n }\n}\n\nfunction muxAssetToSanityDocument(asset: MuxAsset): VideoAssetDocument | undefined {\n const playbackId = (asset.playback_ids || []).find((p) => p.id)?.id\n\n if (!playbackId) return undefined\n\n return {\n _id: uuid(),\n _type: 'mux.videoAsset',\n _updatedAt: new Date().toISOString(),\n _createdAt: parseMuxDate(asset.created_at).toISOString(),\n assetId: asset.id,\n playbackId,\n filename: asset.meta?.title ?? generateAssetPlaceholder(asset.id),\n status: asset.status,\n data: asset,\n }\n}\n\nconst useAssetsInSanity = createHookFromObservableFactory<AssetInSanity[], DocumentStore>(\n (documentStore) => {\n return documentStore.listenQuery(\n /* groq */ `*[_type == \"mux.videoAsset\"] {\n \"uploadId\": coalesce(uploadId, data.upload_id),\n \"assetId\": coalesce(assetId, data.id),\n }`,\n {},\n {\n apiVersion: SANITY_API_VERSION,\n }\n )\n }\n)\n\nfunction assetExistsInSanity(asset: MuxAsset, existingAssets: AssetInSanity[]) {\n // Don't allow importing assets that are not ready\n if (asset.status !== 'ready') return false\n\n return existingAssets.some(\n (existing) => existing.assetId === asset.id || existing.uploadId === asset.upload_id\n )\n}\n","import {useEffect, useState} from 'react'\n\ntype IntersectionOptions = {\n root?: Element | null\n rootMargin?: string\n threshold?: number\n onChange?: (inView: boolean) => void\n}\n\nexport function useInView(\n ref: React.RefObject<HTMLDivElement | null>,\n options: IntersectionOptions = {}\n) {\n const [inView, setInView] = useState(false)\n\n useEffect(() => {\n if (!ref.current) return\n\n const observer = new IntersectionObserver(([entry], obs) => {\n // ==== from react-intersection-observer ====\n // While it would be nice if you could just look at isIntersecting to determine if the component is inside the viewport, browsers can't agree on how to use it.\n // -Firefox ignores `threshold` when considering `isIntersecting`, so it will never be false again if `threshold` is > 0\n const nowInView =\n entry.isIntersecting &&\n obs.thresholds.some((threshold) => entry.intersectionRatio >= threshold)\n\n // Update our state when observer callback fires\n setInView(nowInView)\n options?.onChange?.(nowInView)\n }, options)\n\n const toObserve = ref.current\n observer.observe(toObserve)\n\n // eslint-disable-next-line\n return () => {\n if (toObserve) observer.unobserve(toObserve)\n }\n }, [options, ref])\n\n return inView\n}\n","import type {\n AdvancedPlaybackPolicy,\n MuxPlaybackId,\n PlaybackPolicy,\n VideoAssetDocument,\n} from './types'\n\n/* - Returns the playback id of the asset based on the specified priority.\n By default chooses the \"strongest\" policy\n - Otherwise, returns the first playback id in the array.\n */\nexport function getPlaybackId(\n asset: Pick<VideoAssetDocument, 'data'>,\n priority: string[] = ['drm', 'signed', 'public']\n): string {\n try {\n if (!asset) {\n throw new TypeError('Tried to get playback Id with no asset')\n }\n\n const playbackIds = asset.data?.playback_ids\n if (playbackIds && playbackIds.length > 0) {\n for (const policy of priority) {\n const match = playbackIds.find((entry) => entry.policy === policy)\n if (match) {\n return match.id\n }\n }\n\n return playbackIds[0].id\n }\n\n throw new TypeError('Missing playbackId')\n } catch (e) {\n console.error('Asset is missing a playbackId', {asset}, e)\n throw e\n }\n}\n\nexport function getPlaybackPolicy(\n asset: Pick<VideoAssetDocument, 'data' | 'playbackId'>\n): MuxPlaybackId | undefined {\n return (\n asset.data?.playback_ids?.find(\n (playbackId) => getPlaybackId(asset, ['drm', 'signed', 'public']) === playbackId.id\n ) ?? {id: '', policy: 'public'}\n )\n}\n\nexport function getPlaybackPolicyById(\n asset: Pick<VideoAssetDocument, 'data'>,\n playbackId: string\n): MuxPlaybackId | undefined {\n return asset.data?.playback_ids?.find((entry) => playbackId === entry.id)\n}\n\nexport function hasPlaybackPolicy(\n data: Partial<{\n playback_policy?: PlaybackPolicy[]\n advanced_playback_policies: AdvancedPlaybackPolicy[]\n }>,\n policy: PlaybackPolicy\n) {\n return (\n (data.advanced_playback_policies &&\n data.advanced_playback_policies.find((p) => p.policy === policy)) ||\n data.playback_policy?.find((p) => p === policy)\n )\n}\n","import type {SanityClient} from 'sanity'\nimport {suspend} from 'suspend-react'\n\nimport {readSecrets} from './readSecrets'\nimport type {AnimatedThumbnailOptions, ThumbnailOptions} from './types'\n\nexport type Audience = 'g' | 's' | 't' | 'v' | 'd'\n\nexport type Payload<T extends Audience> = T extends 'g'\n ? AnimatedThumbnailOptions\n : T extends 's'\n ? never\n : T extends 't'\n ? ThumbnailOptions\n : T extends 'v'\n ? never\n : T extends 'd'\n ? never\n : never\n\n/**\n * Uses suspend. Call this with {@link tryWithSuspend} or rethrow the Promise\n */\nexport function generateJwt<T extends Audience>(\n client: SanityClient,\n playbackId: string,\n aud: T,\n payload?: Payload<T>\n): string {\n const {signingKeyId, signingKeyPrivate} = readSecrets(client)\n if (!signingKeyId) {\n throw new TypeError(\"Missing `signingKeyId`.\\n Check your plugin's configuration\")\n }\n if (!signingKeyPrivate) {\n throw new TypeError(\"Missing `signingKeyPrivate`.\\n Check your plugin's configuration\")\n }\n\n /* Using suspend means we need to use Suspense on parent components. \n Also, this will throw a Promise under the hood (apparently common in React), \n so if we want to catch errors we have to take this into account in catch blocks\n and rethrow promises. */\n // @ts-expect-error - handle missing typings for this package\n const {default: sign} = suspend(() => import('jsonwebtoken-esm/sign'), ['jsonwebtoken-esm/sign'])\n\n return sign(\n payload ? JSON.parse(JSON.stringify(payload, (_, v) => v ?? undefined)) : {},\n atob(signingKeyPrivate),\n {\n algorithm: 'RS256',\n keyid: signingKeyId,\n audience: aud,\n subject: playbackId,\n noTimestamp: true,\n expiresIn: '12h',\n }\n )\n}\n","import type {SanityClient} from 'sanity'\n\nimport {getPlaybackId} from '../util/getPlaybackPolicy'\nimport {Audience, generateJwt} from './generateJwt'\nimport {getPlaybackPolicyById} from './getPlaybackPolicy'\nimport type {AssetThumbnailOptions} from './types'\n\n/**\n * May throw a Promise. Call this with {@link tryWithSuspend} or rethrow the Promise\n */\nexport function createUrlParamsObject(\n client: SanityClient,\n asset: AssetThumbnailOptions['asset'],\n params: object,\n audience: Audience\n) {\n const playbackId = getPlaybackId(asset)\n\n let searchParams = new URLSearchParams(\n JSON.parse(JSON.stringify(params, (_, v) => v ?? undefined))\n )\n const playbackPolicy = getPlaybackPolicyById(asset, playbackId)?.policy\n if (playbackPolicy === 'signed' || playbackPolicy === 'drm') {\n const token = generateJwt(client, playbackId, audience, params)\n searchParams = new URLSearchParams({token})\n }\n\n return {playbackId, searchParams}\n}\n","import type {SanityClient} from 'sanity'\n\nimport {createUrlParamsObject} from './createUrlParamsObject'\nimport type {AnimatedThumbnailOptions, MuxAnimatedThumbnailUrl} from './types'\nimport {AssetThumbnailOptions} from './types'\n\nexport interface AnimatedPosterSrcOptions extends AnimatedThumbnailOptions {\n asset: AssetThumbnailOptions['asset']\n client: SanityClient\n}\n\nexport function getAnimatedPosterSrc({\n asset,\n client,\n height,\n width,\n start = asset.thumbTime ? Math.max(0, asset.thumbTime - 2.5) : 0,\n end = start + 5,\n fps = 15,\n}: AnimatedPosterSrcOptions): MuxAnimatedThumbnailUrl {\n const params = {height, width, start, end, fps}\n\n const {playbackId, searchParams} = createUrlParamsObject(client, asset, params, 'g')\n\n return `https://image.mux.com/${playbackId}/animated.gif?${searchParams}`\n}\n","import type {SanityClient} from 'sanity'\n\nimport {createUrlParamsObject} from './createUrlParamsObject'\nimport type {MuxThumbnailUrl, ThumbnailOptions} from './types'\nimport {AssetThumbnailOptions} from './types'\n\nexport interface PosterSrcOptions extends ThumbnailOptions {\n asset: AssetThumbnailOptions['asset']\n client: SanityClient\n}\n\nexport function getPosterSrc({\n asset,\n client,\n fit_mode,\n height,\n time = asset.thumbTime ?? undefined,\n width,\n}: PosterSrcOptions): MuxThumbnailUrl {\n const params = {fit_mode, height, width}\n if (time !== undefined) {\n ;(params as any).time = time\n }\n\n const {playbackId, searchParams} = createUrlParamsObject(client, asset, params, 't')\n\n return `https://image.mux.com/${playbackId}/thumbnail.png?${searchParams}`\n}\n","/**\n * When running `suspend()` from react-suspend a function may throw a Promise\n * causing unexpected behavior when catching.\n * @param block Your block of code that uses suspend\n * @param onError (optional) How to handle a regular Error\n * @returns Whatever is returned by the block if it succeeds, otherwise whatever is resolved by onError if defined\n * @throws rethrows the caught Promise to comply with Suspense logic\n */\nexport function tryWithSuspend<T, E>(\n block: () => T,\n onError?: (error: Error) => E\n): T | E | undefined {\n try {\n return block()\n } catch (errorOrPromise) {\n if (errorOrPromise instanceof Promise) {\n // react-suspend will throw a Promise\n throw errorOrPromise\n }\n return onError ? onError(errorOrPromise as Error) : undefined\n }\n}\n","import {ErrorOutlineIcon} from '@sanity/icons'\nimport {Box, Card, CardTone, Spinner, Stack, Text} from '@sanity/ui'\nimport {Suspense, useMemo, useRef, useState} from 'react'\nimport {styled} from 'styled-components'\n\nimport {useClient} from '../hooks/useClient'\nimport {useInView} from '../hooks/useInView'\nimport {THUMBNAIL_ASPECT_RATIO} from '../util/constants'\nimport {getAnimatedPosterSrc} from '../util/getAnimatedPosterSrc'\nimport {getPosterSrc} from '../util/getPosterSrc'\nimport {tryWithSuspend} from '../util/tryWithSuspend'\nimport {AssetThumbnailOptions, MuxAnimatedThumbnailUrl, MuxThumbnailUrl} from '../util/types'\n\nconst Image = styled.img`\n transition: opacity 0.175s ease-out 0s;\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n object-position: center center;\n`\n\ntype ImageStatus = 'loading' | 'error' | 'loaded'\n\nconst STATUS_TO_TONE: Record<ImageStatus, CardTone> = {\n loading: 'transparent',\n error: 'critical',\n loaded: 'default',\n}\n\nexport default function VideoThumbnail({\n asset,\n width,\n staticImage = false,\n}: {\n asset: AssetThumbnailOptions['asset']\n width?: number\n staticImage?: boolean\n}) {\n const posterWidth = width || 250\n const client = useClient()\n const ref = useRef<HTMLDivElement | null>(null)\n const inView = useInView(ref)\n\n const [status, setStatus] = useState<ImageStatus>('loading')\n const [error, setError] = useState<string | null>(null)\n\n const thumbnailSrc = useMemo(() => {\n return tryWithSuspend(\n () => {\n let thumbnail: MuxAnimatedThumbnailUrl | MuxThumbnailUrl | undefined\n\n if (staticImage) thumbnail = getPosterSrc({asset, client, width: posterWidth})\n else thumbnail = getAnimatedPosterSrc({asset, client, width: posterWidth})\n return thumbnail\n },\n (err: Error) => {\n handleError(err.message)\n return undefined\n }\n )\n }, [asset, client, posterWidth, staticImage])\n\n function handleLoad() {\n setStatus('loaded')\n }\n\n function handleError(err?: string) {\n setStatus('error')\n if (err) {\n setError(err)\n } else {\n setError('Failed loading thumbnail')\n }\n }\n\n return (\n <Suspense fallback={<span>Preparing thumbnail</span>}>\n <Card\n style={{\n aspectRatio: THUMBNAIL_ASPECT_RATIO,\n position: 'relative',\n maxWidth: width ? `${width}px` : undefined,\n width: '100%',\n flex: 1,\n }}\n border\n radius={2}\n ref={ref}\n tone={STATUS_TO_TONE[status]}\n >\n {inView ? (\n <>\n {status === 'loading' && (\n <Box\n style={{\n position: 'absolute',\n left: '50%',\n top: '50%',\n transform: 'translate(-50%, -50%)',\n }}\n >\n <Spinner />\n </Box>\n )}\n {status === 'error' && (\n <Stack\n space={4}\n style={{\n position: 'absolute',\n width: '100%',\n left: 0,\n top: '50%',\n transform: 'translateY(-50%)',\n justifyItems: 'center',\n }}\n >\n <Text size={4} muted>\n <ErrorOutlineIcon style={{fontSize: '1.75em'}} />\n </Text>\n <Text muted align=\"center\">\n {error}\n </Text>\n </Stack>\n )}\n <Image\n src={thumbnailSrc ?? undefined}\n alt={`Preview for ${staticImage ? 'image' : 'video'} ${asset.filename || asset.assetId}`}\n onLoad={handleLoad}\n onError={() => handleError()}\n style={{opacity: status === 'loaded' ? 1 : 0}}\n />\n </>\n ) : null}\n </Card>\n </Suspense>\n )\n}\n","import {\n CheckmarkCircleIcon,\n ErrorOutlineIcon,\n InfoOutlineIcon,\n RetrieveIcon,\n RetryIcon,\n} from '@sanity/icons'\nimport {\n Box,\n Button,\n Card,\n Checkbox,\n Code,\n Dialog,\n Flex,\n Heading,\n Spinner,\n Stack,\n Text,\n} from '@sanity/ui'\nimport {truncateString, useFormattedDuration} from 'sanity'\nimport {styled} from 'styled-components'\n\nimport useImportMuxAssets from '../hooks/useImportMuxAssets'\nimport {DIALOGS_Z_INDEX} from '../util/constants'\nimport type {MuxAsset} from '../util/types'\nimport VideoThumbnail from './VideoThumbnail'\n\nconst MissingAssetCheckbox = styled(Checkbox)`\n position: static !important;\n\n input::after {\n content: '';\n position: absolute;\n inset: 0;\n display: block;\n cursor: pointer;\n z-index: 1000;\n }\n`\n\nfunction MissingAsset({\n asset,\n selectAsset,\n selected,\n}: {\n asset: MuxAsset\n selectAsset: (selected: boolean) => void\n selected: boolean\n}) {\n const duration = useFormattedDuration(asset.duration * 1000)\n\n return (\n <Card\n key={asset.id}\n tone={selected ? 'positive' : undefined}\n border\n paddingX={2}\n paddingY={3}\n style={{position: 'relative'}}\n radius={1}\n >\n <Flex align=\"center\" gap={2}>\n <MissingAssetCheckbox\n checked={selected}\n onChange={(e) => {\n selectAsset(e.currentTarget.checked)\n }}\n aria-label={selected ? `Import video ${asset.id}` : `Skip import of video ${asset.id}`}\n />\n <VideoThumbnail\n asset={{\n assetId: asset.id,\n data: asset,\n filename: asset.id,\n playbackId: asset.playback_ids.find((p) => p.id)?.id,\n }}\n width={150}\n />\n <Stack space={2}>\n <Flex align=\"center\" gap={1}>\n <Code size={2}>{truncateString(asset.id, 15)}</Code>{' '}\n <Text muted size={2}>\n ({duration.formatted})\n </Text>\n </Flex>\n <Text size={1}>\n Uploaded at{' '}\n {new Date(Number(asset.created_at) * 1000).toLocaleDateString('en', {\n year: 'numeric',\n day: '2-digit',\n month: '2-digit',\n })}\n </Text>\n </Stack>\n </Flex>\n </Card>\n )\n}\n\n// eslint-disable-next-line complexity\nfunction ImportVideosDialog(props: ReturnType<typeof useImportMuxAssets>) {\n const {importState} = props\n\n const canTriggerImport =\n (importState === 'idle' || importState === 'error') && props.selectedAssets.length > 0\n const isImporting = importState === 'importing'\n const noAssetsToImport =\n props.missingAssets?.length === 0 && !props.muxAssets.loading && !props.assetsInSanityLoading\n\n return (\n <Dialog\n animate\n header={'Import videos from Mux'}\n zOffset={DIALOGS_Z_INDEX}\n id=\"video-details-dialog\"\n onClose={props.closeDialog}\n onClickOutside={props.closeDialog}\n width={1}\n position=\"fixed\"\n footer={\n importState !== 'done' &&\n !noAssetsToImport && (\n <Card padding={3}>\n <Flex justify=\"space-between\" align=\"center\">\n <Button\n fontSize={2}\n padding={3}\n mode=\"ghost\"\n text=\"Cancel\"\n tone=\"critical\"\n onClick={props.closeDialog}\n disabled={isImporting}\n />\n {props.missingAssets && (\n <Button\n icon={RetrieveIcon}\n fontSize={2}\n padding={3}\n mode=\"ghost\"\n text={\n props.selectedAssets?.length > 0\n ? `Import ${props.selectedAssets.length} video(s)`\n : 'No video(s) selected'\n }\n tone=\"positive\"\n onClick={props.importAssets}\n iconRight={isImporting && Spinner}\n disabled={!canTriggerImport}\n />\n )}\n </Flex>\n </Card>\n )\n }\n >\n <Box padding={3}>\n {/* WARNING: SKIPPED ASSETS WITHOUT PLAYBACK */}\n {props.muxAssets.hasSkippedAssetsWithoutPlayback && (\n <Card tone=\"caution\" marginBottom={5} padding={3} border>\n <Flex align=\"center\" gap={2}>\n <InfoOutlineIcon fontSize={36} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n Some videos were skipped\n </Text>\n <Text size={1}>\n Videos without playback IDs cannot be imported and have been excluded from the\n list.\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* LOADING ASSETS STATE */}\n {(props.muxAssets.loading || props.assetsInSanityLoading) && (\n <Card tone=\"primary\" marginBottom={5} padding={3} border>\n <Flex align=\"center\" gap={4}>\n <Spinner muted size={4} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n Loading assets from Mux\n </Text>\n <Text size={1}>\n This may take a while.\n {props.missingAssets &&\n props.missingAssets.length > 0 &&\n ` There are at least ${props.missingAssets.length} video${props.missingAssets.length > 1 ? 's' : ''} currently not in Sanity...`}\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* ERROR LOADING MUX */}\n {props.muxAssets.error && (\n <Card tone=\"critical\" marginBottom={5} padding={3} border>\n <Flex align=\"center\" gap={2}>\n <ErrorOutlineIcon fontSize={36} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n There was an error getting all data from Mux\n </Text>\n <Text size={1}>\n {props.missingAssets\n ? `But we've found ${props.missingAssets.length} video${props.missingAssets.length > 1 ? 's' : ''} not in Sanity, which you can start importing now.`\n : 'Please try again or contact a developer for help.'}\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* IMPORTING STATE */}\n {importState === 'importing' && (\n <Card tone=\"primary\" marginBottom={5} padding={3} border>\n <Flex align=\"center\" gap={4}>\n <Spinner muted size={4} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n Importing {props.selectedAssets.length} video\n {props.selectedAssets.length > 1 && 's'} from Mux\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* ERROR IMPORTING */}\n {importState === 'error' && (\n <Card tone=\"critical\" marginBottom={5} padding={3} border>\n <Flex align=\"center\" gap={2}>\n <ErrorOutlineIcon fontSize={36} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n There was an error importing videos\n </Text>\n <Text size={1}>\n {props.importError\n ? `Error: ${props.importError}`\n : 'Please try again or contact a developer for help.'}\n </Text>\n <Box marginTop={1}>\n <Button\n icon={RetryIcon}\n text=\"Retry\"\n tone=\"primary\"\n onClick={props.importAssets}\n />\n </Box>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* NO ASSETS TO IMPORT or SUCESS STATE */}\n {(noAssetsToImport || importState === 'done') && (\n <Stack paddingY={5} marginBottom={4} space={3} style={{textAlign: 'center'}}>\n <Box>\n <CheckmarkCircleIcon fontSize={48} />\n </Box>\n <Heading size={2}>\n {importState === 'done'\n ? `Videos imported successfully`\n : 'There are no Mux videos to import'}\n </Heading>\n <Text size={2}>\n {importState === 'done'\n ? 'You can now use them in your Sanity content.'\n : \"They're all in Sanity and ready to be used in your content.\"}\n </Text>\n </Stack>\n )}\n\n {/* MISSING ASSETS SELECTOR */}\n {props.missingAssets &&\n props.missingAssets.length > 0 &&\n (importState === 'idle' || importState === 'error') && (\n <Stack space={4}>\n <Heading size={1}>\n There are {props.missingAssets.length}\n {props.muxAssets.loading && '+'} Mux video{props.missingAssets.length > 1 && 's'}{' '}\n not in Sanity\n </Heading>\n {!props.muxAssets.loading && (\n <Flex align=\"center\" paddingX={2}>\n <Checkbox\n id=\"import-all\"\n style={{display: 'block'}}\n onClick={(e) => {\n const selectAll = e.currentTarget.checked\n if (selectAll) {\n // eslint-disable-next-line no-unused-expressions\n props.missingAssets && props.setSelectedAssets(props.missingAssets)\n } else {\n props.setSelectedAssets([])\n }\n }}\n checked={props.selectedAssets.length === props.missingAssets.length}\n />\n <Box flex={1} paddingLeft={3} as=\"label\" htmlFor=\"import-all\">\n <Text>Import all</Text>\n </Box>\n </Flex>\n )}\n {props.missingAssets.map((asset) => (\n <MissingAsset\n key={asset.id}\n asset={asset}\n selectAsset={(selected) => {\n if (selected) {\n props.setSelectedAssets([...props.selectedAssets, asset])\n } else {\n props.setSelectedAssets(props.selectedAssets.filter((a) => a.id !== asset.id))\n }\n }}\n selected={props.selectedAssets.some((a) => a.id === asset.id)}\n />\n ))}\n </Stack>\n )}\n </Box>\n </Dialog>\n )\n}\n\nexport default function ImportVideosFromMux() {\n const importAssets = useImportMuxAssets()\n\n if (!importAssets.hasSecrets) {\n return\n }\n\n if (importAssets.dialogOpen) {\n // eslint-disable-next-line consistent-return\n return <ImportVideosDialog {...importAssets} />\n }\n\n // eslint-disable-next-line consistent-return\n return <Button mode=\"bleed\" text=\"Import from Mux\" onClick={importAssets.openDialog} />\n}\n","import {ChevronLeftIcon, ChevronRightIcon} from '@sanity/icons'\nimport {Button, Label} from '@sanity/ui'\nimport {Dispatch, SetStateAction, useEffect} from 'react'\n\nconst PageSelector = (props: {\n page: number\n setPage: Dispatch<SetStateAction<number>>\n total: number\n}) => {\n const page = props.page\n const setPage = props.setPage\n\n useEffect(() => {\n // Constraint in bounds.\n const clamped = Math.min(props.total - 1, Math.max(0, page))\n if (page !== clamped) {\n setPage(clamped)\n }\n }, [page, props.total, setPage])\n\n return (\n <>\n <Button\n icon={ChevronLeftIcon}\n mode=\"bleed\"\n padding={3}\n style={{cursor: 'pointer'}}\n disabled={page <= 0}\n onClick={() => {\n setPage((p) => {\n return Math.min(props.total - 1, Math.max(0, p - 1))\n })\n }}\n />\n <Label muted>\n Page {page + 1}/{props.total}\n </Label>\n <Button\n icon={ChevronRightIcon}\n mode=\"bleed\"\n padding={3}\n style={{cursor: 'pointer'}}\n disabled={page >= props.total - 1}\n onClick={() => {\n setPage((p) => {\n return Math.min(props.total - 1, Math.max(0, p + 1))\n })\n }}\n />\n </>\n )\n}\n\nexport default PageSelector\n","import {uuid} from '@sanity/uuid'\n\nimport type {MuxAsset} from './types'\n\n/**\n * Adds _key to array items in MuxAsset data for Sanity compatibility.\n * Sanity requires _key on array items for proper editing support.\n */\nexport function addKeysToMuxData(data: MuxAsset): MuxAsset {\n return {\n ...data,\n tracks: data.tracks?.map((track) => ({\n ...track,\n _key: uuid(),\n })),\n playback_ids: data.playback_ids?.map((playbackId) => ({\n ...playbackId,\n _key: uuid(),\n })),\n static_renditions: data.static_renditions\n ? {\n ...data.static_renditions,\n files: data.static_renditions.files?.map((file) => ({\n ...file,\n _key: uuid(),\n })),\n }\n : undefined,\n }\n}\n","import {useMemo, useState} from 'react'\nimport {\n createHookFromObservableFactory,\n type DocumentStore,\n useClient,\n useDocumentStore,\n} from 'sanity'\n\nimport {addKeysToMuxData} from '../util/addKeysToMuxData'\nimport {isEmptyOrPlaceholderTitle} from '../util/assetTitlePlaceholder'\nimport type {MuxAsset, VideoAssetDocument} from '../util/types'\nimport {SANITY_API_VERSION} from './useClient'\nimport useMuxAssets from './useMuxAssets'\nimport {useSecretsDocumentValues} from './useSecretsDocumentValues'\n\ntype ResyncState = 'closed' | 'idle' | 'syncing' | 'done' | 'error'\n\nexport type MatchedAsset = {\n sanityDoc: VideoAssetDocument\n muxAsset: MuxAsset | undefined\n muxTitle: string | undefined\n currentTitle: string | undefined\n}\n\nexport default function useResyncMuxMetadata() {\n const documentStore = useDocumentStore()\n const client = useClient({\n apiVersion: SANITY_API_VERSION,\n })\n\n const [sanityAssets, sanityAssetsLoading] = useSanityAssets(documentStore)\n\n const secretDocumentValues = useSecretsDocumentValues()\n const hasSecrets = !!secretDocumentValues.value.secrets?.secretKey\n\n const [resyncError, setResyncError] = useState<unknown>()\n const [resyncState, setResyncState] = useState<ResyncState>('closed')\n const dialogOpen = resyncState !== 'closed'\n\n const muxAssets = useMuxAssets({\n client,\n enabled: hasSecrets && dialogOpen,\n })\n\n const matchedAssets = useMemo(() => {\n return sanityAssets && muxAssets.data\n ? sanityAssets.map((sanityDoc) => {\n const muxAsset = muxAssets.data?.find(\n (m) => m.id === sanityDoc.assetId || m.id === sanityDoc.data?.id\n )\n return {\n sanityDoc,\n muxAsset,\n muxTitle: muxAsset?.meta?.title,\n currentTitle: sanityDoc.filename,\n }\n })\n : undefined\n }, [sanityAssets, muxAssets.data])\n\n const closeDialog = () => {\n if (resyncState !== 'syncing') setResyncState('closed')\n }\n\n const openDialog = () => {\n if (resyncState === 'closed') setResyncState('idle')\n }\n\n async function syncAllVideos() {\n if (!matchedAssets) return\n\n setResyncState('syncing')\n\n try {\n const tx = client.transaction()\n\n matchedAssets.forEach((matched) => {\n // Update all videos with the Mux title, even if it's undefined/empty\n const newTitle = matched.muxTitle || ''\n tx.patch(matched.sanityDoc._id, {set: {filename: newTitle}})\n })\n\n await tx.commit({returnDocuments: false})\n setResyncState('done')\n } catch (error) {\n setResyncState('error')\n setResyncError(error)\n }\n }\n\n async function syncOnlyEmpty() {\n if (!matchedAssets) return\n\n setResyncState('syncing')\n\n try {\n const tx = client.transaction()\n\n matchedAssets.forEach((matched) => {\n // Only update if the current title is empty or has the placeholder format\n // AND there's a new title available from Mux\n if (\n matched.muxAsset &&\n matched.muxTitle &&\n isEmptyOrPlaceholderTitle(matched.currentTitle, matched.muxAsset.id)\n ) {\n tx.patch(matched.sanityDoc._id, {set: {filename: matched.muxTitle}})\n }\n })\n\n await tx.commit({returnDocuments: false})\n setResyncState('done')\n } catch (error) {\n setResyncState('error')\n setResyncError(error)\n }\n }\n\n async function syncFullData() {\n if (!matchedAssets) return\n\n setResyncState('syncing')\n\n try {\n const tx = client.transaction()\n\n matchedAssets.forEach((matched) => {\n if (!matched.muxAsset) return\n\n const dataWithKeys = addKeysToMuxData(matched.muxAsset)\n\n // Update all fields: filename, status, and full data from Mux\n tx.patch(matched.sanityDoc._id, {\n set: {\n filename: matched.muxTitle || matched.currentTitle || '',\n status: matched.muxAsset.status,\n data: dataWithKeys,\n },\n })\n })\n\n await tx.commit({returnDocuments: false})\n setResyncState('done')\n } catch (error) {\n setResyncState('error')\n setResyncError(error)\n }\n }\n\n return {\n sanityAssetsLoading,\n closeDialog,\n dialogOpen,\n resyncState,\n resyncError,\n hasSecrets,\n syncAllVideos,\n syncOnlyEmpty,\n syncFullData,\n matchedAssets,\n muxAssets,\n openDialog,\n }\n}\n\nconst useSanityAssets = createHookFromObservableFactory<VideoAssetDocument[], DocumentStore>(\n (documentStore) => {\n return documentStore.listenQuery(\n /* groq */ `*[_type == \"mux.videoAsset\"]`,\n {},\n {\n apiVersion: SANITY_API_VERSION,\n }\n )\n }\n)\n","import {CheckmarkCircleIcon, ErrorOutlineIcon, SyncIcon} from '@sanity/icons'\nimport {Box, Button, Card, Dialog, Flex, Heading, Radio, Spinner, Stack, Text} from '@sanity/ui'\nimport {useState} from 'react'\n\nimport useResyncMuxMetadata from '../hooks/useResyncMuxMetadata'\nimport {isEmptyOrPlaceholderTitle} from '../util/assetTitlePlaceholder'\nimport {DIALOGS_Z_INDEX} from '../util/constants'\n\ntype SyncOption = 'fillEmpty' | 'syncTitles' | 'fullResync'\n\ninterface OptionCardProps {\n id: SyncOption\n selected: boolean\n onSelect: (id: SyncOption) => void\n title: string\n count: number\n description: string\n disabled?: boolean\n}\n\nfunction OptionCard({\n id,\n selected,\n onSelect,\n title,\n count,\n description,\n disabled,\n}: OptionCardProps) {\n return (\n <Card\n as=\"label\"\n padding={3}\n radius={2}\n border\n tone={selected ? 'primary' : 'default'}\n style={{\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n }}\n >\n <Flex gap={3} align=\"flex-start\">\n <Box paddingTop={1}>\n <Radio\n checked={selected}\n onChange={() => onSelect(id)}\n disabled={disabled}\n name=\"sync-option\"\n />\n </Box>\n <Stack space={2} flex={1}>\n <Flex align=\"center\" gap={2}>\n <Text size={2} weight=\"semibold\">\n {title} ({count})\n </Text>\n </Flex>\n <Text size={1} muted>\n {description}\n </Text>\n </Stack>\n </Flex>\n </Card>\n )\n}\n\nfunction ResyncMetadataDialog(props: ReturnType<typeof useResyncMuxMetadata>) {\n const {resyncState} = props\n\n const videosToUpdate = props.matchedAssets?.filter((m) => m.muxAsset).length || 0\n const videosWithEmptyOrPlaceholder =\n props.matchedAssets?.filter(\n (m) => m.muxAsset && m.muxTitle && isEmptyOrPlaceholderTitle(m.currentTitle, m.muxAsset.id)\n ).length || 0\n\n const hasEmptyTitles = videosWithEmptyOrPlaceholder > 0\n const defaultOption: SyncOption = hasEmptyTitles ? 'fillEmpty' : 'syncTitles'\n const [selectedOption, setSelectedOption] = useState<SyncOption>(defaultOption)\n\n const canTriggerResync = resyncState === 'idle' || resyncState === 'error'\n const isResyncing = resyncState === 'syncing'\n const isDone = resyncState === 'done'\n const isLoading = props.muxAssets.loading || props.sanityAssetsLoading\n\n const handleSync = () => {\n switch (selectedOption) {\n case 'fillEmpty':\n props.syncOnlyEmpty()\n break\n case 'syncTitles':\n props.syncAllVideos()\n break\n case 'fullResync':\n props.syncFullData()\n break\n default:\n break\n }\n }\n\n return (\n <Dialog\n animate\n header=\"Sync with Mux\"\n zOffset={DIALOGS_Z_INDEX}\n id=\"resync-metadata-dialog\"\n onClose={props.closeDialog}\n onClickOutside={props.closeDialog}\n width={1}\n position=\"fixed\"\n footer={\n !isDone && (\n <Card padding={3}>\n <Flex justify=\"flex-end\" gap={2}>\n <Button\n fontSize={2}\n padding={3}\n mode=\"ghost\"\n text=\"Cancel\"\n onClick={props.closeDialog}\n disabled={isResyncing}\n />\n <Button\n icon={SyncIcon}\n fontSize={2}\n padding={3}\n text=\"Run sync\"\n tone=\"primary\"\n onClick={handleSync}\n iconRight={isResyncing && Spinner}\n disabled={!canTriggerResync || isLoading}\n />\n </Flex>\n </Card>\n )\n }\n >\n <Box padding={4}>\n {/* LOADING ASSETS STATE */}\n {isLoading && (\n <Card tone=\"primary\" marginBottom={4} padding={3} border radius={2}>\n <Flex align=\"center\" gap={4}>\n <Spinner muted size={4} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n Loading assets from Mux\n </Text>\n <Text size={1} muted>\n This may take a while.\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* ERROR LOADING MUX */}\n {props.muxAssets.error && (\n <Card tone=\"critical\" marginBottom={4} padding={3} border radius={2}>\n <Flex align=\"center\" gap={2}>\n <ErrorOutlineIcon fontSize={36} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n There was an error getting data from Mux\n </Text>\n <Text size={1}>Please try again or contact a developer for help.</Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* SYNCING STATE */}\n {resyncState === 'syncing' && (\n <Card tone=\"primary\" marginBottom={4} padding={3} border radius={2}>\n <Flex align=\"center\" gap={4}>\n <Spinner muted size={4} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n Syncing metadata\n </Text>\n <Text size={1} muted>\n Updating videos from Mux...\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* ERROR SYNCING */}\n {resyncState === 'error' && (\n <Card tone=\"critical\" marginBottom={4} padding={3} border radius={2}>\n <Flex align=\"center\" gap={2}>\n <ErrorOutlineIcon fontSize={36} />\n <Stack space={2}>\n <Text size={2} weight=\"semibold\">\n There was an error syncing metadata\n </Text>\n <Text size={1}>\n {props.resyncError\n ? `Error: ${props.resyncError}`\n : 'Please try again or contact a developer for help.'}\n </Text>\n </Stack>\n </Flex>\n </Card>\n )}\n\n {/* SUCCESS STATE */}\n {resyncState === 'done' && (\n <Stack paddingY={5} space={3} style={{textAlign: 'center'}}>\n <Box>\n <CheckmarkCircleIcon fontSize={48} />\n </Box>\n <Heading size={2}>Sync completed</Heading>\n <Text size={2} muted>\n Videos have been updated from Mux.\n </Text>\n </Stack>\n )}\n\n {/* OPTIONS */}\n {!isDone && !isLoading && !props.muxAssets.error && (\n <Stack space={4}>\n <Text size={1} muted>\n Found {videosToUpdate} video{videosToUpdate === 1 ? '' : 's'} linked to Mux.\n </Text>\n\n <Stack space={3}>\n {hasEmptyTitles && (\n <OptionCard\n id=\"fillEmpty\"\n selected={selectedOption === 'fillEmpty'}\n onSelect={setSelectedOption}\n title=\"Fill missing titles only\"\n count={videosWithEmptyOrPlaceholder}\n description=\"Updates only videos without a title or with placeholder titles (e.g., 'Asset #123') using the title from Mux.\"\n disabled={isResyncing}\n />\n )}\n\n <OptionCard\n id=\"syncTitles\"\n selected={selectedOption === 'syncTitles'}\n onSelect={setSelectedOption}\n title=\"Sync all titles\"\n count={videosToUpdate}\n description=\"Replaces the title in Sanity with the title from Mux for all videos.\"\n disabled={isResyncing}\n />\n\n <OptionCard\n id=\"fullResync\"\n selected={selectedOption === 'fullResync'}\n onSelect={setSelectedOption}\n title=\"Full resync\"\n count={videosToUpdate}\n description=\"Updates all fields from Mux including status, duration, tracks, captions, and renditions.\"\n disabled={isResyncing}\n />\n </Stack>\n </Stack>\n )}\n </Box>\n </Dialog>\n )\n}\n\nexport default function ResyncMetadata() {\n const resyncMetadata = useResyncMuxMetadata()\n\n if (!resyncMetadata.hasSecrets) {\n return\n }\n\n if (resyncMetadata.dialogOpen) {\n // eslint-disable-next-line consistent-return\n return <ResyncMetadataDialog {...resyncMetadata} />\n }\n\n // eslint-disable-next-line consistent-return\n return <Button mode=\"bleed\" text=\"Sync with Mux\" onClick={resyncMetadata.openDialog} />\n}\n","import {SortIcon} from '@sanity/icons'\nimport {Button, Menu, MenuButton, MenuItem, PopoverProps} from '@sanity/ui'\nimport {useId} from 'react'\n\nimport {ASSET_SORT_OPTIONS, SortOption} from '../hooks/useAssets'\n\nexport const CONTEXT_MENU_POPOVER_PROPS: PopoverProps = {\n constrainSize: true,\n placement: 'bottom',\n portal: true,\n width: 0,\n}\n\n/**\n * @sanity/ui components adapted from:\n * https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/pane/PaneContextMenuButton.tsx#L19\n */\nexport function SelectSortOptions(props: {sort: SortOption; setSort: (s: SortOption) => void}) {\n const id = useId()\n\n return (\n <MenuButton\n button={\n <Button text=\"Sort\" icon={SortIcon} mode=\"bleed\" padding={3} style={{cursor: 'pointer'}} />\n }\n id={id}\n menu={\n <Menu>\n {Object.entries(ASSET_SORT_OPTIONS).map(([type, {label}]) => (\n <MenuItem\n key={type}\n data-as=\"button\"\n onClick={() => props.setSort(type as SortOption)}\n padding={3}\n tone=\"default\"\n text={label}\n pressed={type === props.sort}\n />\n ))}\n </Menu>\n }\n popover={CONTEXT_MENU_POPOVER_PROPS}\n />\n )\n}\n","import {Box, Spinner} from '@sanity/ui'\n\nconst SpinnerBox: React.FC = () => (\n <Box\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '150px',\n }}\n >\n <Spinner />\n </Box>\n)\n\nexport default SpinnerBox\n","import {Flex, Text} from '@sanity/ui'\n\nconst IconInfo: React.FC<{\n text: string\n icon: React.FC\n size?: number\n muted?: boolean\n}> = (props) => {\n const Icon = props.icon\n return (\n <Flex gap={2} align=\"center\" padding={1}>\n <Text size={(props.size || 1) + 1} muted>\n <Icon />\n </Text>\n <Text size={props.size || 1} muted={props.muted}>\n {props.text}\n </Text>\n </Flex>\n )\n}\n\nexport default IconInfo\n","import type {SVGProps} from 'react'\n\nexport function ResolutionIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M20 9V6h-3V4h5v5h-2ZM2 9V4h5v2H4v3H2Zm15 11v-2h3v-3h2v5h-5ZM2 20v-5h2v3h3v2H2Zm4-4V8h12v8H6Zm2-2h8v-4H8v4Zm0 0v-4v4Z\"\n />\n </svg>\n )\n}\n","import type {SVGProps} from 'react'\n\nexport function StopWatchIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 512 512\"\n {...props}\n >\n <path d=\"M232 306.667h48V176h-48v130.667z\" fill=\"currentColor\" />\n <path\n d=\"M407.67 170.271l30.786-30.786-33.942-33.941-30.785 30.786C341.217 111.057 300.369 96 256 96 149.961 96 64 181.961 64 288s85.961 192 192 192 192-85.961 192-192c0-44.369-15.057-85.217-40.33-117.729zm-45.604 223.795C333.734 422.398 296.066 438 256 438s-77.735-15.602-106.066-43.934C121.602 365.735 106 328.066 106 288s15.602-77.735 43.934-106.066C178.265 153.602 215.934 138 256 138s77.734 15.602 106.066 43.934C390.398 210.265 406 247.934 406 288s-15.602 77.735-43.934 106.066z\"\n fill=\"currentColor\"\n />\n <path d=\"M192 32h128v48H192z\" fill=\"currentColor\" />\n </svg>\n )\n}\n","import {useToast} from '@sanity/ui'\nimport {useCallback, useState} from 'react'\n\nimport {getAsset} from '../actions/assets'\nimport {addKeysToMuxData} from '../util/addKeysToMuxData'\nimport type {MuxAsset, VideoAssetDocument} from '../util/types'\nimport {useClient} from './useClient'\n\ntype ResyncAssetState = 'idle' | 'syncing' | 'success' | 'error'\n\ninterface UseResyncAssetOptions {\n showToast?: boolean\n onSuccess?: (updatedData: MuxAsset) => void\n onError?: (error: unknown) => void\n}\n\ninterface UseResyncAssetReturn {\n resyncState: ResyncAssetState\n resyncError: unknown\n resyncAsset: (asset: VideoAssetDocument) => Promise<MuxAsset | undefined>\n isResyncing: boolean\n}\n\nexport function useResyncAsset(options?: UseResyncAssetOptions): UseResyncAssetReturn {\n const client = useClient()\n const toast = useToast()\n const [resyncState, setResyncState] = useState<ResyncAssetState>('idle')\n const [resyncError, setResyncError] = useState<unknown>(null)\n\n const showToast = options?.showToast ?? false\n\n const resyncAsset = useCallback(\n async (asset: VideoAssetDocument) => {\n if (!asset.assetId) {\n if (showToast) {\n toast.push({\n title: 'Cannot resync',\n description: 'Asset has no Mux ID',\n status: 'error',\n })\n }\n options?.onError?.(new Error('Asset has no Mux ID'))\n return undefined\n }\n\n if (!asset._id) {\n if (showToast) {\n toast.push({\n title: 'Cannot resync',\n description: 'Asset has no document ID',\n status: 'error',\n })\n }\n options?.onError?.(new Error('Asset has no document ID'))\n return undefined\n }\n\n setResyncState('syncing')\n setResyncError(null)\n\n try {\n const response = await getAsset(client, asset.assetId)\n const muxData = response.data\n const dataWithKeys = addKeysToMuxData(muxData)\n\n await client\n .patch(asset._id)\n .set({\n status: muxData.status,\n data: dataWithKeys,\n ...(muxData.meta?.title && {filename: muxData.meta.title}),\n })\n .commit({returnDocuments: false})\n\n setResyncState('success')\n if (showToast) {\n toast.push({\n title: 'Asset synced',\n description: 'Data has been updated from Mux',\n status: 'success',\n })\n }\n\n options?.onSuccess?.(muxData)\n return muxData\n } catch (error) {\n setResyncState('error')\n setResyncError(error)\n console.error('Failed to refresh asset data:', error)\n if (showToast) {\n toast.push({\n title: 'Sync failed',\n description: 'Could not sync asset from Mux',\n status: 'error',\n })\n }\n options?.onError?.(error)\n return undefined\n }\n },\n [client, toast, options, showToast]\n )\n\n return {\n resyncState,\n resyncError,\n resyncAsset,\n isResyncing: resyncState === 'syncing',\n }\n}\n","import type {SanityClient} from '@sanity/client'\n\nimport {getAsset} from '../actions/assets'\nimport {generateJwt} from './generateJwt'\nimport {getPlaybackId} from './getPlaybackPolicy'\nimport {getPlaybackPolicy} from './getPlaybackPolicy'\nimport type {MuxTextTrack, VideoAssetDocument} from './types'\n\nexport function extractErrorMessage(\n error: unknown,\n defaultMessage = 'Failed to process request'\n): string {\n let message = ''\n\n if (error && typeof error === 'object') {\n const err = error as {response?: {body?: {message?: string}}; message?: string}\n message = err.response?.body?.message || err.message || ''\n } else if (typeof error === 'string') {\n message = error\n }\n\n if (!message) {\n return defaultMessage\n }\n\n const match = message.match(/\\(([^)]+)\\)/)\n if (match && match[1]) {\n return match[1]\n }\n\n if (message.includes('responded with')) {\n const parts = message.split('(')\n if (parts.length > 1) {\n return parts[parts.length - 1].replace(')', '').trim()\n }\n }\n\n return message\n}\n\nexport interface PollTrackStatusOptions {\n client: SanityClient\n assetId: string\n trackName: string\n trackLanguageCode: string\n maxAttempts?: number\n onTrackFound?: (track: MuxTextTrack) => void\n onTrackErrored?: (track: MuxTextTrack) => void\n onTrackReady?: (track: MuxTextTrack) => void\n}\n\nexport interface PollTrackStatusResult {\n track: MuxTextTrack | undefined\n found: boolean\n status: 'ready' | 'preparing' | 'errored' | 'not-found'\n}\n\n/**\n * Polls Mux API to find and track the status of a newly added text track.\n * The track may be in \"preparing\" state initially, then become \"ready\" or \"errored\".\n *\n * @param options - Configuration options for polling\n * @returns Promise resolving to the poll result\n */\nexport async function pollTrackStatus(\n options: PollTrackStatusOptions\n): Promise<PollTrackStatusResult> {\n const {\n client,\n assetId,\n trackName,\n trackLanguageCode,\n maxAttempts = 10,\n onTrackFound,\n onTrackErrored,\n onTrackReady,\n } = options\n\n const trimmedName = trackName.trim()\n const trimmedLanguageCode = trackLanguageCode.trim()\n let newTrack: MuxTextTrack | undefined\n let attempts = 0\n let trackFound = false\n\n const findTrack = (textTracks: MuxTextTrack[]): MuxTextTrack | undefined => {\n let foundTrack = textTracks.find(\n (track) => track.name === trimmedName && track.language_code === trimmedLanguageCode\n )\n\n if (!foundTrack) {\n foundTrack = textTracks.find((track) => track.language_code === trimmedLanguageCode)\n }\n\n if (!foundTrack && textTracks.length > 0) {\n foundTrack = textTracks[textTracks.length - 1]\n }\n\n return foundTrack\n }\n\n while (attempts < maxAttempts) {\n try {\n if (attempts > 0) {\n await new Promise((resolve) => setTimeout(resolve, 1000))\n }\n\n const assetData = await getAsset(client, assetId)\n const textTracks =\n assetData.data.tracks?.filter((track): track is MuxTextTrack => track.type === 'text') || []\n\n const foundTrack = findTrack(textTracks)\n\n if (!foundTrack) {\n attempts++\n continue\n }\n\n trackFound = true\n newTrack = foundTrack\n\n if (onTrackFound) {\n onTrackFound(foundTrack)\n }\n\n if (foundTrack.status === 'ready') {\n if (onTrackReady) {\n onTrackReady(foundTrack)\n }\n break\n }\n\n if (foundTrack.status === 'errored') {\n if (onTrackErrored) {\n onTrackErrored(foundTrack)\n }\n return {\n track: foundTrack,\n found: true,\n status: 'errored',\n }\n }\n } catch (error) {\n console.error('Failed to fetch updated asset:', error)\n }\n\n attempts++\n }\n\n if (!newTrack || !trackFound) {\n return {\n track: undefined,\n found: false,\n status: 'not-found',\n }\n }\n\n if (newTrack.status === 'preparing') {\n return {\n track: newTrack,\n found: true,\n status: 'preparing',\n }\n }\n\n return {\n track: newTrack,\n found: true,\n status: 'ready',\n }\n}\n\n/**\n * May throw a Promise. Call this with {@link tryWithSuspend} or rethrow the Promise\n */\nexport async function downloadVttFile(\n client: SanityClient,\n asset: VideoAssetDocument,\n track: MuxTextTrack\n): Promise<void> {\n if (!track.id) {\n throw new Error('Track ID is missing')\n }\n\n if (track.status !== 'ready') {\n throw new Error(`Track is not ready yet. Status: ${track.status}`)\n }\n\n if (!asset.assetId) {\n throw new Error('Asset ID is required')\n }\n\n const playbackId = getPlaybackId(asset)\n if (!playbackId) {\n throw new Error('Playback ID is required')\n }\n\n const playbackPolicy = getPlaybackPolicy(asset)?.policy\n\n let downloadUrl = `https://stream.mux.com/${playbackId}/text/${track.id}.vtt`\n\n if (playbackPolicy === 'signed' || playbackPolicy === 'drm') {\n const token = generateJwt(client, playbackId, 'v')\n downloadUrl += `?token=${token}`\n }\n\n const response = await fetch(downloadUrl)\n if (!response.ok) {\n throw new Error(`Failed to download file: ${response.statusText}`)\n }\n\n const blob = await response.blob()\n const blobUrl = URL.createObjectURL(blob)\n\n const link = document.createElement('a')\n link.href = blobUrl\n link.download = `${asset.filename || 'captions'}-${track.language_code || 'en'}.vtt`\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n\n URL.revokeObjectURL(blobUrl)\n}\n","import type MuxPlayerElement from '@mux/mux-player'\nimport type {ObjectInputProps, PreviewLayoutKey, PreviewProps, SchemaType} from 'sanity'\nimport type {PartialDeep} from 'type-fest'\n\n/**\n * Standard static rendition options available for plugin configuration defaults\n */\nexport type StandardRendition = 'highest' | 'audio-only'\n\n/**\n * All static rendition resolution options supported by Mux\n */\nexport type StaticRenditionResolution =\n | 'highest'\n | 'audio-only'\n | '270p'\n | '360p'\n | '480p'\n | '540p'\n | '720p'\n | '1080p'\n | '1440p'\n | '2160p'\n\nexport interface MuxInputConfig {\n /**\n * Enable static renditions by default. Can be overwritten on a per-asset basis.\n * Supports:\n * - Standard mode: 'highest' (up to 4K MP4) and/or 'audio-only' (M4A)\n * - Advanced mode: Specific resolutions ('270p', '360p', '480p', '540p', '720p', '1080p', '1440p', '2160p') and/or 'audio-only'\n *\n * **Important**: 'highest' cannot be mixed with specific resolutions. If both are provided, only 'highest' will be used.\n *\n * @see {@link https://docs.mux.com/guides/video/enable-static-mp4-renditions}\n * @defaultValue []\n */\n static_renditions: StaticRenditionResolution[]\n\n /**\n * @deprecated Use `static_renditions` instead. This field is kept for backward compatibility.\n * Enable static renditions by setting this to 'standard'. Can be overwritten on a per-asset basis.\n * Requires `\"video_quality\": \"plus\"`\n * @see {@link https://docs.mux.com/guides/video/enable-static-mp4-renditions#why-enable-mp4-support}\n * @defaultValue 'none'\n */\n mp4_support: 'none' | 'standard'\n\n /**\n * Max resolution tier can be used to control the maximum resolution_tier your asset is encoded, stored, and streamed at.\n * Requires `\"video_quality\": \"plus\"`\n * @see {@link https://docs.mux.com/guides/stream-videos-in-4k}\n * @defaultValue '1080p'\n */\n max_resolution_tier: '2160p' | '1440p' | '1080p'\n\n /**\n * @deprecated Use {@link video_quality}\n * <br>\n * The encoding tier informs the cost, quality, and available platform features for the asset.\n * @see {@link https://docs.mux.com/guides/use-encoding-tiers}\n * @defaultValue 'smart'\n */\n encoding_tier?: 'baseline' | 'smart'\n\n /**\n * The video quality level informs the cost, quality, and available platform features for the asset.\n * @see {@link https://www.mux.com/docs/guides/use-video-quality-levels}\n * @defaultValue 'plus'\n */\n video_quality: 'basic' | 'plus' | 'premium'\n\n /**\n * Normalize the audio track loudness level.\n * @see {@link https://docs.mux.com/guides/adjust-audio-levels#how-to-turn-on-audio-normalization}\n * @defaultValue false\n */\n normalize_audio: boolean\n\n /**\n * Enables signed URLs by default, if you configured them with your API token.\n * @see {@link https://docs.mux.com/guides/secure-video-playback}\n * @defaultValue false\n */\n defaultSigned?: boolean\n\n /**\n * Enables public URLs by default.\n * @defaultValue true\n */\n defaultPublic?: boolean\n\n /**\n * Enables DRM Protection by default, if you configured your DRM Configuration Id.\n * @see {@link https://www.mux.com/docs/guides/protect-videos-with-drm}\n * @defaultValue true\n */\n defaultDrm?: boolean\n\n /**\n * Auto-generate captions for these languages by default.\n * Requires `\"video_quality\": \"plus\"`\n *\n * @see {@link https://docs.mux.com/guides/add-autogenerated-captions-and-use-transcripts}\n * @deprecated use `defaultAutogeneratedSubtitleLang` instead. Only a single autogenerated\n */\n defaultAutogeneratedSubtitleLangs?: SupportedMuxLanguage[]\n\n /**\n * Auto-generate captions for this language by default. Users can still\n * Requires `\"video_quality\": \"plus\"`\n *\n * @see {@link https://docs.mux.com/guides/add-autogenerated-captions-and-use-transcripts}\n */\n defaultAutogeneratedSubtitleLang?: SupportedMuxLanguage\n\n /**\n * Whether or not to allow content editors to override asset upload\n * configuration settings when uploading a video to Mux.\n *\n * @see {@link https://docs.mux.com/guides/secure-video-playback}\n * @defaultValue false\n */\n disableUploadConfig?: boolean\n\n /**\n * Whether or not to allow content editors to add text tracks alongside their\n * asset when uploading a video to Mux.\n *\n * @see {@link https://docs.mux.com/guides/secure-video-playback}\n * @defaultValue false\n */\n disableTextTrackConfig?: boolean\n\n /**\n * Whether or not to show the playback warning when trying to watch DRM content for the first time.\n *\n * @defaultValue false\n */\n disableDrmPlaybackWarning?: boolean\n\n /**\n * The mime types that are accepted by the input.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/accept}\n * @defaultValue ['video/*','audio/*']\n\n */\n acceptedMimeTypes?: ('audio/*' | 'video/*')[]\n\n /**\n * Maximum file size allowed for video uploads in bytes.\n * If not specified, no file size validation will be performed.\n *\n * @example 1024 * 1024 * 1024 // 1 GB\n * @defaultValue undefined\n */\n maxAssetFileSize?: number\n\n /**\n * Maximum video duration allowed in seconds.\n * If not specified, no duration validation will be performed.\n *\n * @example 2 * 60 * 60 // 2 hours\n * @defaultValue undefined\n */\n maxAssetDuration?: number\n\n /**\n * HLS.js configuration options to be passed to the Mux Player.\n * These options allow you to customize the underlying HLS.js playback engine behavior.\n *\n * @see {@link https://github.com/video-dev/hls.js/blob/master/docs/API.md#fine-tuning}\n * @defaultValue undefined\n * @example\n * ```ts\n * {\n * maxBufferLength: 30,\n * lowLatencyMode: true,\n * capLevelToPlayerSize: true\n * }\n * ```\n */\n hlsConfig?: MuxPlayerElement['_hlsConfig']\n}\n\nexport interface PluginConfig extends MuxInputConfig {\n /**\n * How the videos browser should appear as a studio tool in Sanity's top navigation\n *\n * Pass `false` if you want to disable it.\n * @defaultValue {title: 'Videos', icon: VideoIcon}\n **/\n tool:\n | false\n | {\n title?: string\n icon?: React.ComponentType\n }\n\n /**\n * The roles that are allowed to configure the plugin.\n *\n * If not set, all roles will be allowed to configure the plugin.\n * @defaultValue []\n */\n allowedRolesForConfiguration: string[]\n}\n\nexport const SUPPORTED_MUX_LANGUAGES = [\n {label: 'English', code: 'en', state: 'Stable'},\n {label: 'Spanish', code: 'es', state: 'Stable'},\n {label: 'Italian', code: 'it', state: 'Stable'},\n {label: 'Portuguese', code: 'pt', state: 'Stable'},\n {label: 'German', code: 'de', state: 'Stable'},\n {label: 'French', code: 'fr', state: 'Stable'},\n {label: 'Polish', code: 'pl', state: 'Beta'},\n {label: 'Russian', code: 'ru', state: 'Beta'},\n {label: 'Dutch', code: 'nl', state: 'Beta'},\n {label: 'Catalan', code: 'ca', state: 'Beta'},\n {label: 'Turkish', code: 'tr', state: 'Beta'},\n {label: 'Swedish', code: 'sv', state: 'Beta'},\n {label: 'Ukrainian', code: 'uk', state: 'Beta'},\n {label: 'Norwegian', code: 'no', state: 'Beta'},\n {label: 'Finnish', code: 'fi', state: 'Beta'},\n {label: 'Slovak', code: 'sk', state: 'Beta'},\n {label: 'Greek', code: 'el', state: 'Beta'},\n {label: 'Czech', code: 'cs', state: 'Beta'},\n {label: 'Croatian', code: 'hr', state: 'Beta'},\n {label: 'Danish', code: 'da', state: 'Beta'},\n {label: 'Romanian', code: 'ro', state: 'Beta'},\n {label: 'Bulgarian', code: 'bg', state: 'Beta'},\n] as const\n\nexport const VIDEO_QUALITY_LEVELS = [\n {label: 'Basic', value: 'basic'},\n {label: 'Plus', value: 'plus'},\n {label: 'Premium', value: 'premium'},\n] as const\n\nexport const SUPPORTED_MUX_LANGUAGES_VALUES = SUPPORTED_MUX_LANGUAGES.map((l) => l.code)\n\nexport type SupportedMuxLanguage = (typeof SUPPORTED_MUX_LANGUAGES_VALUES)[number]\n\nexport interface TextTrack {\n _id: string\n name: string\n}\n\nexport interface AutogeneratedTextTrack extends TextTrack {\n type: 'autogenerated'\n language_code: SupportedMuxLanguage\n}\n\nexport interface CustomTextTrack extends TextTrack {\n type: 'subtitles' | 'captions'\n language_code: string\n file: {\n contents: string\n type: string\n name: string\n size: number\n }\n}\n\nexport function isCustomTextTrack(track: Partial<UploadTextTrack>): track is CustomTextTrack {\n return track.type !== 'autogenerated'\n}\n\nexport function isAutogeneratedTrack(\n track: Partial<UploadTextTrack>\n): track is AutogeneratedTextTrack {\n return track.type === 'autogenerated'\n}\n\nexport type UploadTextTrack = AutogeneratedTextTrack | CustomTextTrack\n\n/**\n * Watermark configuration for UI (draggable position)\n */\nexport interface WatermarkConfig {\n enabled: boolean\n imageUrl?: string\n /**\n * Aspect ratio (width / height) of the watermark image.\n * Used to convert between our center-based UI coords and Mux overlay margins.\n */\n imageAspectRatio?: number\n /**\n * Optional explicit Mux `overlay_settings`.\n * When set, these values should be used as-is for the upload request and preview.\n * @see {@link https://www.mux.com/docs/guides/add-watermarks-to-your-videos}\n */\n overlay_settings?: MuxOverlaySettings\n position?: {\n x: number // percentage (0-100)\n y: number // percentage (0-100)\n }\n size?: number // percentage of video width (0-100)\n opacity?: number // 0-1 (converted to percentage string for Mux API)\n}\n\n/**\n * Mux overlay_settings format for watermark API\n * @see {@link https://www.mux.com/docs/guides/add-watermarks-to-your-videos}\n */\nexport interface MuxOverlaySettings {\n vertical_align: 'top' | 'middle' | 'bottom'\n vertical_margin: string // percentage (e.g., \"10%\") or pixels (e.g., \"40px\")\n horizontal_align: 'left' | 'center' | 'right'\n horizontal_margin: string // percentage (e.g., \"10%\") or pixels (e.g., \"40px\")\n width?: string // percentage (e.g., \"25%\") or pixels (e.g., \"80px\")\n height?: string // percentage or pixels\n opacity?: string // percentage string (e.g., \"90%\")\n}\n\nexport interface UploadConfig\n extends Pick<MuxInputConfig, 'max_resolution_tier' | 'normalize_audio' | 'video_quality'> {\n static_renditions: StaticRenditionResolution[]\n text_tracks: UploadTextTrack[]\n signed_policy: boolean\n public_policy: boolean\n watermark?: WatermarkConfig\n drm_policy: boolean\n}\n\n/**\n * Data sent to Mux to create a new asset.\n * @docs {@link https://docs.mux.com/api-reference#video/operation/create-direct-upload}\n */\nexport interface MuxNewAssetSettings\n extends Pick<MuxInputConfig, 'max_resolution_tier' | 'normalize_audio' | 'video_quality'> {\n /** Static renditions configuration for downloadable files */\n static_renditions?: {resolution: StaticRenditionResolution}[]\n /** An array of objects that each describe an input file to be used to create the asset.*/\n input?: {\n /** The URL of the file that Mux should download and use. */\n url?: string\n /** Generate subtitle tracks using automatic speech recognition with this configuration. This may only be provided for the first input object (the main input file). */\n generated_subtitles?: {\n /** A name for this subtitle track. */\n name: string\n /** Arbitrary metadata set for the subtitle track. Max 255 characters. */\n passthrough?: string\n /** The language to generate subtitles in. */\n language_code: SupportedMuxLanguage\n }[]\n /** The time offset in seconds from the beginning of the video indicating the clip's starting marker. */\n start_time?: number\n /** The time offset in seconds from the beginning of the video indicating the clip's ending marker. */\n end_time?: number\n /** This parameter is required for text type tracks. */\n type?: 'video' | 'audio' | 'text'\n /** Type of text track. This parameter only supports subtitles value. */\n text_type?: 'subtitles'\n /** The language code value must be a valid BCP 47 specification compliant value. */\n language_code?: string\n /** The name of the track containing a human-readable description. This value must be unique within each group of text or audio track types. */\n name?: string\n /** Indicates the track provides Subtitles for the Deaf or Hard-of-hearing (SDH). */\n closed_captions?: boolean\n /** This optional parameter should be used tracks with type of text and text_type set to subtitles. */\n passthrough?: string\n /** Overlay settings for watermarks. Used when adding a watermark image as a second input. */\n overlay_settings?: MuxOverlaySettings\n }[]\n\n /** An array of playback policy names that you want applied to this asset and available through playback_ids. */\n playback_policy?: PlaybackPolicy[]\n\n /** An array of playback policy objects that you want applied to this asset and available through playback_ids. advanced_playback_policies must be used instead of playback_policies when creating a DRM playback ID. */\n advanced_playback_policies: AdvancedPlaybackPolicy[]\n\n /** Arbitrary user-supplied metadata that will be included in the asset details and related webhooks. */\n passthrough?: string\n}\n\n/** Used by advanced_playback_policies, allows to define DRM config. */\nexport type AdvancedPlaybackPolicy = {\n policy: PlaybackPolicy\n drm_configuration_id?: string\n}\n\nexport interface Secrets {\n token: string | null\n secretKey: string | null\n enableSignedUrls: boolean\n signingKeyId: string | null\n signingKeyPrivate: string | null\n drmConfigId: string | null\n}\n\n// This narrowed type indicates that there may be assets that are signed, and we have the secrets to access them\n// enabledSignedUrls might be false but that's only relevant for future uploads and their playback policy\nexport interface SignableSecrets extends Omit<Secrets, 'signingKeyId' | 'signingKeyPrivate'> {\n signingKeyId: string\n signingKeyPrivate: string\n}\n\nexport type MuxImageOrigin = `https://image.mux.com`\nexport type MuxThumbnailUrl = `${MuxImageOrigin}/${string}/thumbnail.png?${string}`\nexport type MuxAnimatedThumbnailUrl = `${MuxImageOrigin}/${string}/animated.gif?${string}`\nexport type MuxStoryboardUrl = `${MuxImageOrigin}/${string}/storyboard.vtt?${string}`\nexport type MuxVideoOrigin = `https://stream.mux.com`\nexport type MuxVideoUrl = `${MuxVideoOrigin}/${string}.m3u8?${string}`\nexport type MuxApiUrl = MuxThumbnailUrl | MuxAnimatedThumbnailUrl | MuxStoryboardUrl | MuxVideoUrl\n\n// 'preserve' by default\n// @url: https://docs.mux.com/guides/video/get-images-from-a-video#thumbnail-query-string-parameters\nexport type FitMode = 'preserve' | 'crop' | 'smartcrop' | 'pad'\n\nexport interface ThumbnailOptions {\n fit_mode?: FitMode\n height?: number\n time?: number\n width?: number\n}\n\nexport interface AnimatedThumbnailOptions {\n // Starting time code for the animation, if no end is set it'll have a 5s duration\n // The start and end timecodes uses `asset.thumbTime` to create an iOS `Live Photo` effect by showing you the 5 secodnds before, and after, the thumb time`\n start?: number\n // End code, can't be longer than 10s after the start code\n end?: number\n // Max 640px, 320px by default\n width?: number\n // Preserves aspect ratio, like width, you can't set both the height and width, max 640\n height?: number\n // The fps is 15 by default, but can go up to 30\n fps?: number\n}\n\nexport interface AssetThumbnailOptions {\n asset: Pick<VideoAssetDocument, 'playbackId' | 'data' | 'thumbTime' | 'filename' | 'assetId'>\n}\n\nexport type PlaybackPolicy = 'signed' | 'public' | 'drm'\n\nexport interface MuxErrors {\n type: string\n messages: string[]\n}\n\nexport interface MuxPlaybackId {\n id: string\n policy: PlaybackPolicy\n}\n\nexport interface MuxVideoTrack {\n type: 'video'\n id: string\n max_width: number\n max_height: number\n // if the fps can't be reliably determined, this will be -1\n max_frame_rate: -1 | number\n // top-level duration is always set, while track level duration is not\n duration?: number\n}\nexport interface MuxAudioTrack {\n type: 'audio'\n id: string\n duration?: number\n max_channels: number\n max_channel_layout: 'stereo' | string\n}\nexport interface MuxTextTrack {\n type: 'text'\n id: string\n text_type?: 'subtitles'\n // https://docs.mux.com/api-reference/video#operation/list-assets:~:text=text%20type%20tracks.-,tracks%5B%5D.,text_source,-string\n text_source?:\n | 'uploaded'\n | 'embedded'\n | 'generated_live'\n | 'generated_live_final'\n | 'generated_vod'\n // BCP 47 language code\n language_code?: 'en' | 'en-US' | string\n // The name of the track containing a human-readable description. The hls manifest will associate a subtitle text track with this value\n name?: 'English' | string\n closed_captions?: boolean\n // Max 255 characters\n passthrough?: string\n status: 'preparing' | 'ready' | 'errored'\n error?: {\n type: string\n messages?: string[]\n }\n}\nexport type MuxTrack = MuxVideoTrack | MuxAudioTrack | MuxTextTrack\n// Typings lifted from https://docs.mux.com/api-reference/video#tag/assets\nexport interface MuxAsset {\n id: string\n /** In seconds (instead of JS's default milliseconds) */\n created_at: string\n status: 'preparing' | 'ready' | 'errored'\n duration: number\n max_stored_resolution: 'Audio only' | 'SD' | 'HD' | 'FHD' | 'UHD'\n // if the fps can't be reliably determined, this will be -1\n max_stored_frame_rate: -1 | number\n // The aspect ratio of the asset in the form of width:height, for example 16:9\n aspect_ratio: `${number}:${number}`\n playback_ids: MuxPlaybackId[]\n tracks: MuxTrack[]\n errors?: MuxErrors\n upload_id: string\n is_live?: boolean\n // We use passthrough to set the mux.videoAsset._id of the asset that originally uploaded the video\n passthrough: string\n live_stream_id?: string\n master?: {\n status: 'ready' | 'preparing' | 'errored'\n // Temporary URL to master MP4, expires after 24 hours\n url: string\n }\n master_access: 'temporary' | 'none'\n mp4_support: 'standard' | 'none'\n // Asset Identifier of the video used as the source for creating the clip.\n source_asset_id?: string\n // Normalize the audio track loudness level. This parameter is only applicable to on-demand (not live) assets., default false\n normalize_audio?: boolean\n // The object does not exist if no static renditions have been requested\n static_renditions?: {\n status: 'ready' | 'preparing' | 'disabled' | 'errored'\n files: {\n name: string\n ext: 'mp4' | 'm4a'\n height: number\n width: number\n bitrate: number\n filesize: string\n type: 'standard' | 'advanced'\n status: 'ready' | 'preparing' | 'skipped' | 'errored'\n resolution_tier?: string\n resolution?: string\n id: string\n passthrough?: string\n }[]\n }\n recording_times?: {\n started_at: string\n duration: number\n type: 'content' | 'slate'\n }[]\n // https://docs.mux.com/guides/video/minimize-processing-time\n non_standard_input_reasons?: {\n video_codec?: string\n audio_codec?: string\n video_gop_size?: 'high'\n video_frame_rate?: string\n video_resolution?: string\n video_bitrate?: 'high'\n pixel_aspect_ratio?: string\n video_edit_list?: 'non-standard'\n audio_edit_list?: 'non-standard'\n unexpected_media_file_parameters?: 'non-standard'\n test?: boolean\n }\n meta?: {\n title?: string\n }\n}\n\nexport interface VideoAssetDocument {\n _id: string\n _type: 'mux.videoAsset'\n _createdAt: string\n _updatedAt?: string\n status?: string\n assetId?: string\n playbackId?: string\n filename?: string\n thumbTime?: number\n // Docs for what goes in `data` https://docs.mux.com/api-reference/video#tag/assets\n data?: PartialDeep<MuxAsset>\n}\n\nexport type Reference = {_type: 'reference'; _ref: string}\n\n// @TODO add Reference, and ReferenceSchemaType in the generic\nexport type MuxInputProps = ObjectInputProps<{\n asset?: Reference\n}>\n\nexport interface MuxInputPreviewProps extends Omit<PreviewProps<PreviewLayoutKey>, 'value'> {\n schemaType: SchemaType\n value?: {\n asset?: Reference\n } | null\n}\n\n/** Whether the VideosBrowser was opened from a field in a document, or from the standalone studio tool */\nexport type PluginPlacement = 'input' | 'tool'\n","import {TranslateIcon, UploadIcon} from '@sanity/icons'\nimport {\n Autocomplete,\n Button,\n Card,\n Checkbox,\n Dialog,\n Flex,\n Label,\n Spinner,\n Stack,\n Text,\n TextInput,\n useToast,\n} from '@sanity/ui'\nimport LanguagesList from 'iso-639-1'\nimport {useId, useRef, useState} from 'react'\n\nimport {addTextTrackFromUrl, generateSubtitles, getAsset} from '../actions/assets'\nimport {useClient} from '../hooks/useClient'\nimport {addKeysToMuxData} from '../util/addKeysToMuxData'\nimport {extractErrorMessage, pollTrackStatus} from '../util/textTracks'\nimport {type MuxTextTrack, SUPPORTED_MUX_LANGUAGES, type VideoAssetDocument} from '../util/types'\n\nconst LANGUAGE_OPTIONS = LanguagesList.getAllCodes().map((code) => ({\n value: code,\n label: LanguagesList.getNativeName(code),\n}))\n\nconst MUX_LANGUAGE_OPTIONS = SUPPORTED_MUX_LANGUAGES.map((lang) => ({\n value: lang.code,\n label: lang.label,\n}))\n\nexport interface Props {\n asset: VideoAssetDocument\n onAdd: (track: MuxTextTrack) => void\n onClose: () => void\n}\n\nexport default function AddCaptionDialog({asset, onAdd, onClose}: Props) {\n const client = useClient()\n const toast = useToast()\n const dialogId = `AddCaptionDialog${useId()}`\n\n const [isAutogenerated, setIsAutogenerated] = useState(false)\n const [vttUrl, setVttUrl] = useState('')\n const [languageCode, setLanguageCode] = useState('')\n const [selectedLanguage, setSelectedLanguage] = useState<{value: string; label: string} | null>(\n null\n )\n const [name, setName] = useState('')\n const [isSubmitting, setIsSubmitting] = useState(false)\n const [selectedFile, setSelectedFile] = useState<File | null>(null)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const uploadVttFile = async (file: File): Promise<string> => {\n const assetDocument = await client.assets.upload('file', file, {\n filename: file.name,\n })\n return assetDocument.url\n }\n\n const refreshAssetData = async () => {\n if (!asset._id || !asset.assetId) return\n try {\n const latestAssetData = await getAsset(client, asset.assetId)\n const dataWithKeys = addKeysToMuxData(latestAssetData.data)\n await client\n .patch(asset._id)\n .set({data: dataWithKeys, status: latestAssetData.data.status})\n .commit({returnDocuments: false})\n } catch (refreshError) {\n console.error('Failed to refresh asset data:', refreshError)\n }\n }\n\n const handleAddTrackFromUrl = async () => {\n if (!asset.assetId) {\n throw new Error('Asset ID is required')\n }\n\n const trimmedName = name.trim()\n const trimmedLanguageCode = languageCode.trim()\n\n let vttUrlToUse = vttUrl.trim()\n\n if (selectedFile) {\n try {\n vttUrlToUse = await uploadVttFile(selectedFile)\n } catch (uploadError) {\n toast.push({\n title: 'Failed to upload caption file',\n status: 'error',\n description: 'Could not upload the caption file to Sanity. Please try again.',\n })\n setIsSubmitting(false)\n throw uploadError\n }\n }\n\n await addTextTrackFromUrl(client, asset.assetId, vttUrlToUse, {\n language_code: trimmedLanguageCode,\n name: trimmedName,\n text_type: 'subtitles',\n })\n\n const result = await pollTrackStatus({\n client,\n assetId: asset.assetId,\n trackName: trimmedName,\n trackLanguageCode: trimmedLanguageCode,\n onTrackErrored: async (track) => {\n const errorMessage =\n track.error?.messages?.[0] ||\n track.error?.type ||\n 'The track failed to download from the provided URL'\n toast.push({\n title: 'Caption track failed',\n status: 'error',\n description: errorMessage,\n })\n await refreshAssetData()\n onAdd(track)\n onClose()\n },\n })\n\n if (!result.found || !result.track) {\n toast.push({\n title: 'Caption track may have been added',\n status: 'warning',\n description:\n 'The track was created but its status could not be determined. It may still be processing. Please refresh the page to see if it appears.',\n })\n onClose()\n return\n }\n\n if (result.status === 'errored') {\n return\n }\n\n if (result.status === 'preparing') {\n toast.push({\n title: 'Caption track is processing',\n status: 'info',\n description:\n 'The track was created and is being processed. It will appear in the list shortly.',\n })\n await refreshAssetData()\n onAdd(result.track)\n onClose()\n return\n }\n\n await refreshAssetData()\n toast.push({\n title: 'Caption track added',\n status: 'success',\n description: 'Caption track added successfully',\n })\n\n onAdd(result.track)\n onClose()\n }\n\n const handleGenerateSubtitles = async () => {\n if (!asset.assetId) {\n throw new Error('Asset ID is required')\n }\n\n const assetData = await getAsset(client, asset.assetId)\n const audioTrack = assetData.data.tracks?.find((track) => track.type === 'audio')\n\n if (!audioTrack || !audioTrack.id) {\n toast.push({\n title: 'No audio track found',\n status: 'error',\n description:\n 'The asset does not have an audio track. Auto-generated subtitles require an audio track.',\n })\n throw new Error('No audio track found')\n }\n\n await generateSubtitles(client, asset.assetId, audioTrack.id, {\n language_code: languageCode.trim(),\n name: name.trim(),\n })\n\n const mockTrackId = `generating-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`\n const mockTrack: MuxTextTrack = {\n type: 'text',\n id: mockTrackId,\n text_type: 'subtitles',\n text_source: 'generated_live',\n language_code: languageCode.trim(),\n name: name.trim(),\n status: 'preparing',\n }\n\n toast.push({\n title: 'Generating subtitles',\n status: 'success',\n description: 'This may take a few minutes',\n })\n\n onAdd(mockTrack)\n onClose()\n }\n\n const handleSubmit = async () => {\n if (!isAutogenerated) {\n if (!selectedFile && !vttUrl.trim()) {\n toast.push({\n title: 'Caption file or URL required',\n status: 'error',\n description: 'Please select a VTT or SRT file or enter a caption file URL',\n })\n return\n }\n\n if (vttUrl.trim() && !selectedFile) {\n try {\n void new URL(vttUrl.trim())\n } catch {\n toast.push({\n title: 'Invalid URL',\n status: 'error',\n description:\n 'Please enter a valid URL (e.g., https://example.com/subtitles.vtt or subtitles.srt)',\n })\n return\n }\n }\n }\n\n if (!name.trim()) {\n toast.push({\n title: 'Audio name required',\n status: 'error',\n description: 'Please enter an audio name for this caption track',\n })\n return\n }\n\n if (!languageCode.trim()) {\n toast.push({\n title: 'Language code required',\n status: 'error',\n description: 'Please enter a language code (e.g., en, es, fr)',\n })\n return\n }\n\n setIsSubmitting(true)\n\n try {\n if (isAutogenerated) {\n await handleGenerateSubtitles()\n } else {\n await handleAddTrackFromUrl()\n }\n } catch (error) {\n toast.push({\n title: 'Failed to add caption track',\n status: 'error',\n description: extractErrorMessage(error, 'Failed to add caption track'),\n })\n } finally {\n setIsSubmitting(false)\n }\n }\n\n return (\n <Dialog\n id={dialogId}\n header=\"Add Caption Track\"\n onClose={onClose}\n width={1}\n onClickOutside={onClose}\n >\n <Stack padding={4} space={4}>\n <Stack space={2}>\n <Flex align=\"center\" marginBottom={3}>\n <Checkbox\n id=\"autogenerated-checkbox\"\n style={{display: 'block'}}\n checked={isAutogenerated}\n onChange={(e) => {\n setIsAutogenerated(e.currentTarget.checked)\n if (e.currentTarget.checked) {\n setVttUrl('')\n }\n }}\n disabled={isSubmitting}\n />\n <Flex flex={1} paddingLeft={2}>\n <Text>\n <label htmlFor=\"autogenerated-checkbox\">Generate captions</label>\n </Text>\n </Flex>\n </Flex>\n {!isAutogenerated && (\n <Stack space={2}>\n <Card padding={3} marginBottom={2} tone=\"transparent\" border radius={2}>\n <Flex align=\"center\" justify=\"space-between\">\n <Text size={1} muted>\n {selectedFile ? `Selected: ${selectedFile.name}` : 'No file selected'}\n </Text>\n <Button\n icon={UploadIcon}\n text=\"Select File\"\n mode=\"ghost\"\n tone=\"primary\"\n fontSize={1}\n padding={2}\n onClick={() => fileInputRef.current?.click()}\n disabled={isSubmitting}\n />\n </Flex>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".vtt,text/vtt,.srt,application/x-subrip\"\n style={{display: 'none'}}\n onChange={(e) => {\n if (e.target.files && e.target.files.length > 0 && !isSubmitting) {\n setSelectedFile(e.target.files[0])\n setVttUrl('')\n }\n }}\n />\n </Card>\n <Text size={1} muted style={{textAlign: 'center'}}>\n Or enter the caption file URL\n </Text>\n <Stack space={2}>\n <Label htmlFor=\"vtt-url\">Caption File URL (.vtt or .srt)</Label>\n <TextInput\n id=\"vtt-url\"\n placeholder=\"https://example.com/subtitles.vtt\"\n value={vttUrl}\n onChange={(e) => {\n setVttUrl(e.currentTarget.value)\n setSelectedFile(null)\n }}\n disabled={isSubmitting}\n />\n </Stack>\n </Stack>\n )}\n </Stack>\n\n <Stack space={2}>\n <Label htmlFor=\"caption-name\">Audio name</Label>\n <Autocomplete\n id=\"caption-name\"\n value={selectedLanguage?.value || ''}\n onChange={(newValue) => {\n const options = isAutogenerated ? MUX_LANGUAGE_OPTIONS : LANGUAGE_OPTIONS\n const selected = options.find((opt) => opt.value === newValue)\n if (selected) {\n setSelectedLanguage(selected)\n setLanguageCode(selected.value)\n setName(selected.label)\n }\n }}\n options={isAutogenerated ? MUX_LANGUAGE_OPTIONS : LANGUAGE_OPTIONS}\n icon={TranslateIcon}\n placeholder=\"Select language\"\n filterOption={(query, option) =>\n option.label.toLowerCase().indexOf(query.toLowerCase()) > -1 ||\n option.value.toLowerCase().indexOf(query.toLowerCase()) > -1\n }\n openButton\n renderValue={(value) =>\n (isAutogenerated ? MUX_LANGUAGE_OPTIONS : LANGUAGE_OPTIONS).find(\n (l) => l.value === value\n )?.label || value\n }\n renderOption={(option) => (\n <Card data-as=\"button\" padding={3} radius={2} tone=\"inherit\">\n <Text size={2} textOverflow=\"ellipsis\">\n {option.label} ({option.value})\n </Text>\n </Card>\n )}\n disabled={isSubmitting}\n />\n </Stack>\n\n <Stack space={2}>\n <Label htmlFor=\"caption-language\">Language Code</Label>\n <TextInput\n id=\"caption-language\"\n placeholder=\"en-US\"\n value={languageCode}\n onChange={(e) => {\n setLanguageCode(e.currentTarget.value)\n if (selectedLanguage && selectedLanguage.value !== e.currentTarget.value) {\n setSelectedLanguage(null)\n if (!name || name === selectedLanguage.label) {\n setName('')\n }\n }\n }}\n disabled={isSubmitting}\n />\n </Stack>\n\n <Flex gap={2} justify=\"flex-end\" marginTop={2}>\n <Button text=\"Cancel\" mode=\"ghost\" onClick={onClose} disabled={isSubmitting} />\n <Button\n text=\"Add Caption Track\"\n tone=\"primary\"\n icon={\n isSubmitting ? (\n <Spinner\n style={{\n verticalAlign: 'middle',\n display: 'inline-block',\n marginBottom: '-3px',\n width: '1em',\n height: '1em',\n marginRight: '-6px',\n }}\n />\n ) : (\n <UploadIcon />\n )\n }\n onClick={handleSubmit}\n disabled={isSubmitting}\n />\n </Flex>\n </Stack>\n </Dialog>\n )\n}\n","import {DownloadIcon, TranslateIcon, UploadIcon} from '@sanity/icons'\nimport {\n Autocomplete,\n Button,\n Card,\n Dialog,\n Flex,\n Label,\n Spinner,\n Stack,\n Text,\n TextInput,\n useToast,\n} from '@sanity/ui'\nimport LanguagesList from 'iso-639-1'\nimport {useEffect, useId, useRef, useState} from 'react'\n\nimport {addTextTrackFromUrl, deleteTextTrack, getAsset} from '../actions/assets'\nimport {useClient} from '../hooks/useClient'\nimport {addKeysToMuxData} from '../util/addKeysToMuxData'\nimport {generateJwt} from '../util/generateJwt'\nimport {getPlaybackId} from '../util/getPlaybackPolicy'\nimport {getPlaybackPolicy} from '../util/getPlaybackPolicy'\nimport {downloadVttFile, extractErrorMessage, pollTrackStatus} from '../util/textTracks'\nimport type {MuxTextTrack, VideoAssetDocument} from '../util/types'\n\nconst LANGUAGE_OPTIONS = LanguagesList.getAllCodes().map((code) => ({\n value: code,\n label: LanguagesList.getNativeName(code),\n}))\n\nexport interface Props {\n asset: VideoAssetDocument\n track: MuxTextTrack\n onUpdate: (track: MuxTextTrack, oldTrackId?: string) => void\n onClose: () => void\n}\n\nexport default function EditCaptionDialog({asset, track, onUpdate, onClose}: Props) {\n const client = useClient()\n const toast = useToast()\n const dialogId = `EditCaptionDialog${useId()}`\n\n const isAutogenerated =\n track.text_source === 'generated_live' ||\n track.text_source === 'generated_live_final' ||\n track.text_source === 'generated_vod'\n\n const [vttUrl, setVttUrl] = useState('')\n const [languageCode, setLanguageCode] = useState(track.language_code || '')\n const [selectedLanguage, setSelectedLanguage] = useState<{value: string; label: string} | null>(\n () => {\n const baseCode = track.language_code?.split('-')[0]\n const found = LANGUAGE_OPTIONS.find(\n (opt) => opt.value === track.language_code || opt.value === baseCode\n )\n if (found) return found\n if (track.name) {\n const foundByName = LANGUAGE_OPTIONS.find((opt) => opt.label === track.name)\n if (foundByName) return foundByName\n }\n return null\n }\n )\n const [name, setName] = useState(track.name || '')\n const [isSubmitting, setIsSubmitting] = useState(false)\n const [downloading, setDownloading] = useState(false)\n const [selectedFile, setSelectedFile] = useState<File | null>(null)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n useEffect(() => {\n setLanguageCode(track.language_code || '')\n setName(track.name || '')\n setVttUrl('')\n const baseCode = track.language_code?.split('-')[0]\n const foundByCode = LANGUAGE_OPTIONS.find(\n (opt) => opt.value === track.language_code || opt.value === baseCode\n )\n const foundByName = track.name ? LANGUAGE_OPTIONS.find((opt) => opt.label === track.name) : null\n setSelectedLanguage(foundByCode || foundByName || null)\n }, [track, asset, client])\n\n const handleDownloadCurrentFile = async () => {\n setDownloading(true)\n try {\n await downloadVttFile(client, asset, track)\n } catch (error) {\n let errorMessage = 'Please try again'\n let title = 'Failed to download VTT file'\n\n if (error instanceof Error) {\n errorMessage = error.message\n if (error.message.includes('Track')) {\n title = 'Cannot download'\n }\n } else if (error === 'Track ID is missing' || error === 'Track is not ready yet') {\n errorMessage = String(error)\n title = 'Cannot download'\n }\n\n toast.push({\n title,\n status: 'error',\n description: errorMessage,\n })\n } finally {\n setDownloading(false)\n }\n }\n\n const getCurrentFileName = () => {\n if (track.id && asset.filename) {\n return `${asset.filename}-${track.language_code || 'en'}.vtt`\n }\n return `captions-${track.language_code || 'en'}.vtt`\n }\n\n const uploadVttFile = async (file: File): Promise<string> => {\n const assetDocument = await client.assets.upload('file', file, {\n filename: file.name,\n })\n return assetDocument.url\n }\n\n const refreshAssetData = async () => {\n if (!asset._id || !asset.assetId) return\n try {\n const latestAssetData = await getAsset(client, asset.assetId)\n const dataWithKeys = addKeysToMuxData(latestAssetData.data)\n await client\n .patch(asset._id)\n .set({data: dataWithKeys, status: latestAssetData.data.status})\n .commit({returnDocuments: false})\n } catch (refreshError) {\n console.error('Failed to refresh asset data:', refreshError)\n }\n }\n\n const handleUpdateTrackWithNewUrl = async () => {\n if (!asset.assetId) {\n throw new Error('Asset ID is required')\n }\n\n const trimmedName = name.trim()\n const trimmedLanguageCode = languageCode.trim()\n\n const oldTrackId = track.id\n\n try {\n await deleteTextTrack(client, asset.assetId, oldTrackId)\n } catch (deleteError) {\n toast.push({\n title: 'Failed to delete old track',\n status: 'error',\n description: 'Could not delete the old track. Please try again or delete it manually.',\n })\n setIsSubmitting(false)\n throw deleteError\n }\n\n let vttUrlToUse = vttUrl.trim()\n\n if (selectedFile) {\n try {\n vttUrlToUse = await uploadVttFile(selectedFile)\n } catch (uploadError) {\n toast.push({\n title: 'Failed to upload VTT file',\n status: 'error',\n description: 'Could not upload the VTT file to Sanity. Please try again.',\n })\n setIsSubmitting(false)\n throw uploadError\n }\n }\n\n try {\n await addTextTrackFromUrl(client, asset.assetId, vttUrlToUse, {\n language_code: trimmedLanguageCode,\n name: trimmedName,\n text_type: 'subtitles',\n })\n } catch (error: unknown) {\n toast.push({\n title: 'Failed to update caption track',\n status: 'error',\n description: extractErrorMessage(error, 'Failed to update caption track'),\n })\n setIsSubmitting(false)\n throw error\n }\n\n const result = await pollTrackStatus({\n client,\n assetId: asset.assetId,\n trackName: trimmedName,\n trackLanguageCode: trimmedLanguageCode,\n onTrackErrored: async (erroredTrack) => {\n const errorMessage =\n erroredTrack.error?.messages?.[0] ||\n erroredTrack.error?.type ||\n 'The track failed to download from the provided URL'\n toast.push({\n title: 'Caption track failed',\n status: 'error',\n description: errorMessage,\n })\n await refreshAssetData()\n onUpdate(erroredTrack, oldTrackId)\n setIsSubmitting(false)\n },\n })\n\n if (!result.found || !result.track) {\n toast.push({\n title: 'Caption track may have been updated',\n status: 'warning',\n description:\n 'The track was updated but its status could not be determined. It may still be processing. Please refresh the page to see if it appears.',\n })\n setIsSubmitting(false)\n return\n }\n\n if (result.status === 'errored') {\n return\n }\n\n await refreshAssetData()\n\n if (result.status === 'preparing') {\n toast.push({\n title: 'Caption track is processing',\n status: 'info',\n description:\n 'The track was updated and is being processed. It will appear in the list shortly.',\n })\n } else {\n toast.push({\n title: 'Caption track updated',\n status: 'success',\n description: 'Caption track updated successfully',\n })\n }\n\n onUpdate(result.track, oldTrackId)\n setIsSubmitting(false)\n }\n\n const handleSubmit = async () => {\n if (!name.trim()) {\n toast.push({\n title: 'Audio name required',\n status: 'error',\n description: 'Please enter an audio name for this caption track',\n })\n return\n }\n\n if (!languageCode.trim()) {\n toast.push({\n title: 'Language code required',\n status: 'error',\n description: 'Please enter a language code (e.g., en, es, fr)',\n })\n return\n }\n\n setIsSubmitting(true)\n\n try {\n if (!asset.assetId) {\n throw new Error('Asset ID is required')\n }\n\n const originalVttUrl = (() => {\n if (isAutogenerated || !track.id) return ''\n const playbackId = getPlaybackId(asset)\n if (!playbackId) return ''\n let url = `https://stream.mux.com/${playbackId}/text/${track.id}.vtt`\n if (getPlaybackPolicy(asset)?.policy === 'signed') {\n const token = generateJwt(client, playbackId, 'v')\n url += `?token=${token}`\n }\n return url\n })()\n\n const urlChanged =\n selectedFile !== null || (vttUrl.trim() && vttUrl.trim() !== originalVttUrl)\n\n if (!urlChanged) {\n toast.push({\n title: 'No changes',\n status: 'info',\n description:\n 'Please provide a new VTT file or URL using the \"Replace\" button or URL field to update the track.',\n })\n setIsSubmitting(false)\n return\n }\n\n if (urlChanged) {\n if (!selectedFile && vttUrl.trim()) {\n try {\n void new URL(vttUrl.trim())\n } catch {\n toast.push({\n title: 'Invalid URL',\n status: 'error',\n description: 'Please enter a valid URL (e.g., https://example.com/subtitles.vtt)',\n })\n setIsSubmitting(false)\n return\n }\n }\n\n if (!selectedFile && !vttUrl.trim()) {\n toast.push({\n title: 'VTT file or URL required',\n status: 'error',\n description: 'Please select a VTT file or enter a VTT file URL',\n })\n setIsSubmitting(false)\n return\n }\n\n await handleUpdateTrackWithNewUrl()\n }\n\n onClose()\n } catch (error) {\n toast.push({\n title: 'Failed to update caption track',\n status: 'error',\n description: error instanceof Error ? error.message : 'Please try again',\n })\n } finally {\n setIsSubmitting(false)\n }\n }\n\n return (\n <Dialog\n id={dialogId}\n header=\"Edit Caption Track\"\n onClose={onClose}\n width={1}\n onClickOutside={onClose}\n >\n <Stack padding={4} space={4}>\n <Stack space={2}>\n <Card padding={3} marginBottom={2} tone=\"transparent\" border radius={2}>\n <Flex align=\"center\" justify=\"space-between\">\n <Text>{getCurrentFileName()}</Text>\n <Flex gap={2}>\n {track.status !== 'errored' && (\n <Button\n icon={\n downloading ? (\n <Spinner\n style={{\n verticalAlign: 'middle',\n display: 'inline-block',\n marginTop: '-2px',\n width: '0.5em',\n height: '0.5em',\n }}\n />\n ) : (\n <DownloadIcon />\n )\n }\n text=\"Download\"\n mode=\"ghost\"\n tone=\"primary\"\n fontSize={1}\n padding={2}\n onClick={handleDownloadCurrentFile}\n disabled={downloading || isSubmitting}\n />\n )}\n <Button\n icon={UploadIcon}\n text=\"Replace\"\n mode=\"ghost\"\n tone=\"primary\"\n fontSize={1}\n padding={2}\n onClick={() => fileInputRef.current?.click()}\n disabled={isSubmitting}\n />\n </Flex>\n </Flex>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".vtt,text/vtt\"\n style={{display: 'none'}}\n onChange={(e) => {\n if (e.target.files && e.target.files.length > 0 && !isSubmitting) {\n setSelectedFile(e.target.files[0])\n setVttUrl('')\n }\n }}\n />\n {selectedFile && (\n <Text size={1} muted style={{marginTop: 8}}>\n Selected: {selectedFile.name}\n </Text>\n )}\n </Card>\n <Stack space={2}>\n <Label htmlFor=\"vtt-url\">VTT File URL</Label>\n <TextInput\n id=\"vtt-url\"\n placeholder=\"https://example.com/subtitles.vtt\"\n value={vttUrl}\n onChange={(e) => {\n setVttUrl(e.currentTarget.value)\n setSelectedFile(null)\n }}\n disabled={isSubmitting}\n />\n <Text size={1} muted>\n Add a URL to replace the existing VTT file with a new one\n </Text>\n </Stack>\n </Stack>\n\n <Stack space={2}>\n <Label htmlFor=\"caption-name\">Audio name</Label>\n <Autocomplete\n id=\"caption-name\"\n value={selectedLanguage?.value || ''}\n onChange={(newValue) => {\n const selected = LANGUAGE_OPTIONS.find((opt) => opt.value === newValue)\n if (selected) {\n setSelectedLanguage(selected)\n setLanguageCode(selected.value)\n setName(selected.label)\n }\n }}\n options={LANGUAGE_OPTIONS}\n icon={TranslateIcon}\n placeholder=\"Select language\"\n filterOption={(query, option) =>\n option.label.toLowerCase().indexOf(query.toLowerCase()) > -1 ||\n option.value.toLowerCase().indexOf(query.toLowerCase()) > -1\n }\n openButton\n renderValue={(value) => LANGUAGE_OPTIONS.find((l) => l.value === value)?.label || value}\n renderOption={(option) => (\n <Card data-as=\"button\" padding={3} radius={2} tone=\"inherit\">\n <Text size={2} textOverflow=\"ellipsis\">\n {option.label} ({option.value})\n </Text>\n </Card>\n )}\n disabled={isSubmitting}\n />\n </Stack>\n\n <Stack space={2}>\n <Label htmlFor=\"caption-language\">Language Code</Label>\n <TextInput\n id=\"caption-language\"\n placeholder=\"en-US\"\n value={languageCode}\n onChange={(e) => {\n setLanguageCode(e.currentTarget.value)\n if (selectedLanguage && selectedLanguage.value !== e.currentTarget.value) {\n setSelectedLanguage(null)\n if (!name || name === selectedLanguage.label) {\n setName('')\n }\n }\n }}\n disabled={isSubmitting}\n />\n </Stack>\n\n <Flex gap={2} justify=\"flex-end\" marginTop={2}>\n <Button text=\"Cancel\" mode=\"ghost\" onClick={onClose} disabled={isSubmitting} />\n <Button\n text=\"Update Caption Track\"\n tone=\"primary\"\n icon={\n isSubmitting ? (\n <Spinner\n style={{\n verticalAlign: 'middle',\n display: 'inline-block',\n marginBottom: '-3px',\n width: '1em',\n height: '1em',\n marginRight: '-6px',\n }}\n />\n ) : (\n UploadIcon\n )\n }\n onClick={handleSubmit}\n disabled={isSubmitting}\n />\n </Flex>\n </Stack>\n </Dialog>\n )\n}\n","import {\n AddIcon,\n ChevronDownIcon,\n ChevronUpIcon,\n DownloadIcon,\n EditIcon,\n ErrorOutlineIcon,\n TrashIcon,\n} from '@sanity/icons'\nimport {Box, Button, Card, Dialog, Flex, Heading, Spinner, Stack, Text, useToast} from '@sanity/ui'\nimport {useEffect, useId, useMemo, useState} from 'react'\n\nimport {deleteTextTrack} from '../actions/assets'\nimport {useClient} from '../hooks/useClient'\nimport {useResyncAsset} from '../hooks/useResyncAsset'\nimport {downloadVttFile} from '../util/textTracks'\nimport type {MuxTextTrack, VideoAssetDocument} from '../util/types'\nimport AddCaptionDialog from './AddCaptionDialog'\nimport EditCaptionDialog from './EditCaptionDialog'\n\ninterface TrackCardProps {\n track: MuxTextTrack\n iconOnly: boolean\n downloadingTrackId: string | null\n deletingTrackId: string | null\n trackToEdit: MuxTextTrack | null\n getTrackSourceLabel: (track: MuxTextTrack) => string\n handleDownload: (track: MuxTextTrack) => void\n setTrackToEdit: (track: MuxTextTrack) => void\n setTrackToDelete: (track: MuxTextTrack) => void\n}\n\nfunction TrackCard({\n track,\n iconOnly,\n downloadingTrackId,\n deletingTrackId,\n trackToEdit,\n getTrackSourceLabel,\n handleDownload,\n setTrackToEdit,\n setTrackToDelete,\n}: TrackCardProps) {\n const isDisabled = (action: 'download' | 'edit' | 'delete') => {\n if (action === 'download') {\n return (\n downloadingTrackId !== null || deletingTrackId === track.id || trackToEdit?.id === track.id\n )\n }\n if (action === 'edit') {\n return (\n downloadingTrackId === track.id ||\n deletingTrackId === track.id ||\n trackToEdit?.id === track.id\n )\n }\n return (\n downloadingTrackId === track.id || deletingTrackId !== null || trackToEdit?.id === track.id\n )\n }\n\n const renderActionButtons = () => {\n if (track.status === 'preparing') {\n return (\n <Flex align=\"center\" gap={2}>\n <Spinner\n muted\n style={{\n width: '0.75em',\n height: '0.75em',\n verticalAlign: 'middle',\n display: 'inline-block',\n marginBottom: '-2px',\n }}\n />\n <Text size={1} muted>\n Processing...\n </Text>\n </Flex>\n )\n }\n\n return (\n <Flex gap={2}>\n {track.status !== 'errored' && (\n <Button\n icon={\n downloadingTrackId === track.id ? (\n <Spinner\n style={{\n verticalAlign: 'middle',\n display: 'inline-block',\n marginTop: '-2px',\n width: '0.5em',\n height: '0.5em',\n }}\n />\n ) : (\n <DownloadIcon />\n )\n }\n text={iconOnly ? undefined : 'Download'}\n mode=\"ghost\"\n tone=\"primary\"\n fontSize={1}\n padding={2}\n onClick={() => handleDownload(track)}\n disabled={isDisabled('download')}\n title=\"Download\"\n />\n )}\n <Button\n icon={<EditIcon />}\n text={iconOnly ? undefined : 'Edit'}\n mode=\"ghost\"\n tone=\"primary\"\n fontSize={1}\n padding={2}\n disabled={isDisabled('edit')}\n onClick={() => setTrackToEdit(track)}\n title=\"Edit\"\n />\n <Button\n icon={\n deletingTrackId === track.id ? (\n <Spinner\n style={{\n verticalAlign: 'middle',\n display: 'inline-block',\n marginTop: '-2px',\n width: '0.5em',\n height: '0.5em',\n }}\n />\n ) : (\n <TrashIcon />\n )\n }\n text={iconOnly ? undefined : 'Delete'}\n mode=\"ghost\"\n tone=\"critical\"\n fontSize={1}\n padding={2}\n disabled={isDisabled('delete')}\n onClick={() => setTrackToDelete(track)}\n title=\"Delete\"\n />\n </Flex>\n )\n }\n\n return (\n <Card\n padding={3}\n radius={2}\n tone={track.status === 'errored' ? 'caution' : 'transparent'}\n border\n >\n <Flex align=\"center\" justify=\"space-between\" gap={3}>\n <Stack space={2} flex={1}>\n <Flex align=\"center\" gap={2}>\n <Text weight=\"semibold\">{track.name || 'Untitled'}</Text>\n <Text size={1} muted>\n ({getTrackSourceLabel(track)})\n </Text>\n {track.status === 'errored' && (\n <ErrorOutlineIcon\n style={{color: 'var(--card-critical-color)'}}\n aria-label=\"Error\"\n fontSize={20}\n />\n )}\n </Flex>\n {track.language_code && (\n <Text size={1} muted>\n Language: {track.language_code}\n </Text>\n )}\n {track.status === 'errored' && track.error && (\n <Text size={1} style={{color: 'var(--card-critical-color)'}}>\n {track.error.messages?.[0] || track.error.type || 'Failed to process track'}\n </Text>\n )}\n </Stack>\n {renderActionButtons()}\n </Flex>\n </Card>\n )\n}\n\ninterface TextTracksManagerProps {\n asset: VideoAssetDocument\n iconOnly?: boolean\n tracks?: MuxTextTrack[]\n collapseTracks?: boolean\n}\n\nexport default function TextTracksManager({\n asset,\n iconOnly = false,\n tracks: propTracks,\n collapseTracks = false,\n}: TextTracksManagerProps) {\n const client = useClient()\n const toast = useToast()\n const dialogId = `DeleteCaptionDialog${useId()}`\n const {resyncAsset} = useResyncAsset()\n const [downloadingTrackId, setDownloadingTrackId] = useState<string | null>(null)\n const [deletingTrackId, setDeletingTrackId] = useState<string | null>(null)\n const [addedTracks, setAddedTracks] = useState<MuxTextTrack[]>([])\n const [updatedTracks, setUpdatedTracks] = useState<Map<string, MuxTextTrack>>(new Map())\n const [trackActivityOrder, setTrackActivityOrder] = useState<Map<string, number>>(new Map())\n const [autogeneratedTrackIds, setAutogeneratedTrackIds] = useState<Set<string>>(new Set())\n const [trackToDelete, setTrackToDelete] = useState<MuxTextTrack | null>(null)\n const [trackToEdit, setTrackToEdit] = useState<MuxTextTrack | null>(null)\n const [showAddDialog, setShowAddDialog] = useState(false)\n const [isExpanded, setIsExpanded] = useState(false)\n\n const MAX_VISIBLE_TRACKS = 4\n\n const realTracks: MuxTextTrack[] = propTracks\n ? propTracks\n : asset.data?.tracks?.filter((track): track is MuxTextTrack => track.type === 'text') || []\n\n const activeTracks = realTracks.filter(\n (track) =>\n track.id &&\n (track.status === 'ready' || track.status === 'preparing' || track.status === 'errored')\n )\n\n const allTracks = useMemo(() => {\n const tracksWithUpdates = activeTracks.map((track) => {\n const updated = updatedTracks.get(track.id)\n return updated || track\n })\n\n const isMockTrackReplaced = (mockTrack: MuxTextTrack, realTracksList: MuxTextTrack[]) => {\n if (!mockTrack.id || !mockTrack.id.startsWith('generating-')) {\n return false\n }\n return realTracksList.some((realTrack) => {\n const nameMatches = realTrack.name === mockTrack.name\n const languageMatches = realTrack.language_code === mockTrack.language_code\n if (!nameMatches || !languageMatches) {\n return false\n }\n if (realTrack.status === 'ready') {\n const isGenerated =\n realTrack.text_source === 'generated_live' ||\n realTrack.text_source === 'generated_live_final' ||\n realTrack.text_source === 'generated_vod'\n return isGenerated\n }\n if (realTrack.status === 'preparing') {\n return true\n }\n return false\n })\n }\n\n const isTrackAlreadyInRealTracks = (\n addedTrack: MuxTextTrack,\n realTracksList: MuxTextTrack[]\n ) => {\n if (!addedTrack.id) return false\n if (addedTrack.id.startsWith('generating-')) {\n return isMockTrackReplaced(addedTrack, realTracksList)\n }\n return realTracksList.some((realTrack) => realTrack.id === addedTrack.id)\n }\n\n const tracksToKeep = addedTracks.filter((addedTrack) => {\n if (addedTrack.id && addedTrack.id.startsWith('generating-')) {\n return !isMockTrackReplaced(addedTrack, tracksWithUpdates)\n }\n return !isTrackAlreadyInRealTracks(addedTrack, tracksWithUpdates)\n })\n\n return [...tracksWithUpdates, ...tracksToKeep]\n }, [activeTracks, addedTracks, updatedTracks])\n\n useEffect(() => {\n const newAutogeneratedIds = new Set<string>()\n\n activeTracks.forEach((track) => {\n if (\n track.id &&\n (track.text_source === 'generated_live' ||\n track.text_source === 'generated_live_final' ||\n track.text_source === 'generated_vod')\n ) {\n newAutogeneratedIds.add(track.id)\n }\n })\n\n addedTracks.forEach((mockTrack) => {\n if (mockTrack.id && mockTrack.id.startsWith('generating-')) {\n const realTrack = activeTracks.find((rt) => {\n const nameMatches = rt.name === mockTrack.name\n const languageMatches = rt.language_code === mockTrack.language_code\n return nameMatches && languageMatches\n })\n if (realTrack?.id) {\n newAutogeneratedIds.add(realTrack.id)\n }\n }\n })\n\n setAutogeneratedTrackIds((prev) => {\n let hasNew = false\n const updated = new Set(prev)\n newAutogeneratedIds.forEach((id) => {\n if (!prev.has(id)) {\n updated.add(id)\n hasNew = true\n }\n })\n return hasNew ? updated : prev\n })\n }, [activeTracks, addedTracks])\n\n useEffect(() => {\n const preparingTracks = allTracks.filter((track) => track.status === 'preparing')\n if (preparingTracks.length === 0 || !asset.assetId || !asset._id) {\n return undefined\n }\n\n const interval = setInterval(async () => {\n try {\n const muxData = await resyncAsset(asset)\n if (!muxData) return\n\n const fetchedTracks =\n muxData.tracks?.filter((track): track is MuxTextTrack => track.type === 'text') || []\n\n const isMockTrackReplaced = (\n mockTrack: MuxTextTrack,\n fetchedTracksList: MuxTextTrack[]\n ) => {\n if (!mockTrack.id || !mockTrack.id.startsWith('generating-')) {\n return false\n }\n return fetchedTracksList.some((realTrack) => {\n const nameMatches = realTrack.name === mockTrack.name\n const languageMatches = realTrack.language_code === mockTrack.language_code\n if (!nameMatches || !languageMatches) {\n return false\n }\n if (realTrack.status === 'ready') {\n const isGenerated =\n realTrack.text_source === 'generated_live' ||\n realTrack.text_source === 'generated_live_final' ||\n realTrack.text_source === 'generated_vod'\n return isGenerated\n }\n if (realTrack.status === 'preparing') {\n return true\n }\n return false\n })\n }\n\n const newAutogeneratedIds = new Set<string>()\n fetchedTracks.forEach((track) => {\n if (\n track.id &&\n (track.text_source === 'generated_live' ||\n track.text_source === 'generated_live_final' ||\n track.text_source === 'generated_vod')\n ) {\n newAutogeneratedIds.add(track.id)\n }\n })\n\n const findMatchingRealTrack = (mockTrack: MuxTextTrack, tracksList: MuxTextTrack[]) => {\n return tracksList.find((rt) => {\n const nameMatches = rt.name === mockTrack.name\n const languageMatches = rt.language_code === mockTrack.language_code\n return nameMatches && languageMatches\n })\n }\n\n setAddedTracks((prev) => {\n return prev.filter((mockTrack) => {\n if (mockTrack.id && mockTrack.id.startsWith('generating-')) {\n const replaced = isMockTrackReplaced(mockTrack, fetchedTracks)\n if (replaced) {\n const realTrack = findMatchingRealTrack(mockTrack, fetchedTracks)\n if (realTrack?.id) {\n newAutogeneratedIds.add(realTrack.id)\n setTrackActivityOrder((prevOrder) => {\n const mockOrder = prevOrder.get(mockTrack.id)\n if (mockOrder) {\n const newMap = new Map(prevOrder)\n newMap.set(realTrack.id, mockOrder)\n return newMap\n }\n return prevOrder\n })\n }\n }\n return !replaced\n }\n return true\n })\n })\n\n if (newAutogeneratedIds.size > 0) {\n setAutogeneratedTrackIds((prevIds) => {\n const updated = new Set(prevIds)\n newAutogeneratedIds.forEach((id) => updated.add(id))\n return updated\n })\n }\n } catch (error) {\n console.error('Failed to refresh asset data:', error)\n }\n }, 3000) // Poll every 3 seconds\n\n return () => clearInterval(interval)\n }, [allTracks, asset, resyncAsset])\n\n const visibleTracks = allTracks\n .filter(\n (track) =>\n track.status === 'ready' || track.status === 'preparing' || track.status === 'errored'\n )\n .sort((a, b) => {\n const orderA = trackActivityOrder.get(a.id) || 0\n const orderB = trackActivityOrder.get(b.id) || 0\n\n if (orderA > 0 && orderB > 0) {\n return orderB - orderA\n }\n\n if (orderA > 0) return -1\n if (orderB > 0) return 1\n\n const aIsPreparing = a.status === 'preparing'\n const bIsPreparing = b.status === 'preparing'\n if (aIsPreparing && !bIsPreparing) return -1\n if (!aIsPreparing && bIsPreparing) return 1\n\n const aIsAutogenerated =\n (a.id && a.id.startsWith('generating-')) || (a.id && autogeneratedTrackIds.has(a.id))\n const bIsAutogenerated =\n (b.id && b.id.startsWith('generating-')) || (b.id && autogeneratedTrackIds.has(b.id))\n if (aIsAutogenerated && !bIsAutogenerated) return -1\n if (!aIsAutogenerated && bIsAutogenerated) return 1\n\n return 0\n })\n\n const handleDownload = async (track: MuxTextTrack) => {\n if (!track.id) return\n\n setDownloadingTrackId(track.id)\n try {\n await downloadVttFile(client, asset, track)\n } catch (error) {\n toast.push({\n title: 'Failed to download VTT file',\n status: 'error',\n description: error instanceof Error ? error.message : 'Please try again',\n })\n } finally {\n setDownloadingTrackId(null)\n }\n }\n\n const confirmDelete = async () => {\n if (!trackToDelete || !trackToDelete.id) return\n\n const track = trackToDelete\n setTrackToDelete(null)\n setDeletingTrackId(track.id)\n try {\n if (!asset.assetId) {\n throw new Error('Asset ID is required')\n }\n await deleteTextTrack(client, asset.assetId, track.id)\n\n // Refresh asset data after deletion\n await resyncAsset(asset)\n\n toast.push({\n title: 'Successfully deleted caption track',\n status: 'success',\n })\n\n setAddedTracks((prev) => prev.filter((t) => t.id !== track.id))\n setUpdatedTracks((prev) => {\n const newMap = new Map(prev)\n newMap.delete(track.id)\n return newMap\n })\n setTrackActivityOrder((prev) => {\n const newMap = new Map(prev)\n newMap.delete(track.id)\n return newMap\n })\n setAutogeneratedTrackIds((prev) => {\n const updated = new Set(prev)\n updated.delete(track.id)\n return updated\n })\n } catch (error) {\n toast.push({\n title: 'Failed to delete caption track',\n status: 'error',\n description: error instanceof Error ? error.message : 'Please try again',\n })\n } finally {\n setDeletingTrackId(null)\n }\n }\n\n const handleAddTrack = (track: MuxTextTrack) => {\n setAddedTracks((prev) => [...prev, track])\n setTrackActivityOrder((prev) => {\n const newMap = new Map(prev)\n newMap.set(track.id, prev.size + 1)\n return newMap\n })\n setShowAddDialog(false)\n }\n\n const handleUpdateTrack = async (updatedTrack: MuxTextTrack, oldTrackId?: string) => {\n if (oldTrackId) {\n setAddedTracks((prev) => prev.filter((t) => t.id !== oldTrackId))\n setUpdatedTracks((prev) => {\n const newMap = new Map(prev)\n newMap.delete(oldTrackId)\n return newMap\n })\n setTrackActivityOrder((prev) => {\n const newMap = new Map(prev)\n newMap.delete(oldTrackId)\n return newMap\n })\n setAutogeneratedTrackIds((prev) => {\n const updated = new Set(prev)\n updated.delete(oldTrackId)\n return updated\n })\n }\n\n const isAddedTrack = addedTracks.some((t) => t.id === updatedTrack.id)\n\n if (isAddedTrack) {\n setAddedTracks((prev) => prev.map((t) => (t.id === updatedTrack.id ? updatedTrack : t)))\n } else {\n setUpdatedTracks((prev) => {\n const newMap = new Map(prev)\n newMap.set(updatedTrack.id, updatedTrack)\n return newMap\n })\n }\n\n setTrackActivityOrder((prev) => {\n const newMap = new Map(prev)\n newMap.set(updatedTrack.id, prev.size + 1)\n return newMap\n })\n\n setTrackToEdit(null)\n\n // Refresh asset data after update\n await resyncAsset(asset)\n }\n\n const getTrackSourceLabel = (track: MuxTextTrack) => {\n if (track.id && track.id.startsWith('generating-')) {\n return 'Auto-generated'\n }\n if (track.id && autogeneratedTrackIds.has(track.id)) {\n return 'Auto-generated'\n }\n if (\n track.text_source === 'generated_live_final' ||\n track.text_source === 'generated_live' ||\n track.text_source === 'generated_vod'\n ) {\n return 'Auto-generated'\n }\n if (track.text_source === 'uploaded') {\n return 'Uploaded'\n }\n return 'Custom'\n }\n\n if (visibleTracks.length === 0 && !showAddDialog) {\n return (\n <Stack space={3}>\n <Flex justify=\"flex-end\">\n <Button\n icon={AddIcon}\n text=\"Add Caption\"\n tone=\"primary\"\n onClick={() => setShowAddDialog(true)}\n />\n </Flex>\n <Card padding={4} radius={2} tone=\"transparent\" border>\n <Text size={1} muted>\n No captions available. Add captions when uploading a video or add them manually.\n </Text>\n </Card>\n {showAddDialog && (\n <AddCaptionDialog\n asset={asset}\n onAdd={handleAddTrack}\n onClose={() => setShowAddDialog(false)}\n />\n )}\n </Stack>\n )\n }\n\n const displayedTracks =\n collapseTracks && !isExpanded ? visibleTracks.slice(0, MAX_VISIBLE_TRACKS) : visibleTracks\n const hasMoreTracks = collapseTracks && visibleTracks.length > MAX_VISIBLE_TRACKS\n\n return (\n <Stack space={3}>\n <Flex justify=\"flex-end\">\n <Button\n icon={AddIcon}\n text=\"Add Caption\"\n tone=\"primary\"\n onClick={() => setShowAddDialog(true)}\n />\n </Flex>\n\n {displayedTracks.map((track) => (\n <TrackCard\n key={track.id}\n track={track}\n iconOnly={iconOnly}\n downloadingTrackId={downloadingTrackId}\n deletingTrackId={deletingTrackId}\n trackToEdit={trackToEdit}\n getTrackSourceLabel={getTrackSourceLabel}\n handleDownload={handleDownload}\n setTrackToEdit={setTrackToEdit}\n setTrackToDelete={setTrackToDelete}\n />\n ))}\n\n {hasMoreTracks && (\n <Flex justify=\"center\">\n <Button\n icon={isExpanded ? ChevronUpIcon : ChevronDownIcon}\n text={\n isExpanded ? 'Show less' : `Show ${visibleTracks.length - MAX_VISIBLE_TRACKS} more`\n }\n mode=\"ghost\"\n tone=\"primary\"\n onClick={() => setIsExpanded(!isExpanded)}\n />\n </Flex>\n )}\n\n {trackToDelete && (\n <Dialog\n animate\n id={dialogId}\n header=\"Delete track\"\n onClose={() => setTrackToDelete(null)}\n onClickOutside={() => setTrackToDelete(null)}\n width={1}\n >\n <Card\n padding={3}\n style={{\n minHeight: '150px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Stack space={3}>\n <Heading size={2}>\n Are you sure you want to delete &quot;\n {trackToDelete.name || trackToDelete.language_code || 'Untitled'}&quot;?\n </Heading>\n <Text size={2}>This action is irreversible</Text>\n <Stack space={4} marginY={4}>\n <Box>\n <Button\n icon={\n deletingTrackId === trackToDelete.id ? (\n <Spinner\n style={{\n verticalAlign: 'middle',\n display: 'inline-block',\n marginTop: '-2px',\n width: '0.5em',\n height: '0.5em',\n }}\n />\n ) : (\n <TrashIcon />\n )\n }\n fontSize={2}\n padding={3}\n text=\"Delete track\"\n tone=\"critical\"\n onClick={confirmDelete}\n disabled={deletingTrackId !== null}\n />\n </Box>\n </Stack>\n </Stack>\n </Card>\n </Dialog>\n )}\n\n {showAddDialog && (\n <AddCaptionDialog\n asset={asset}\n onAdd={handleAddTrack}\n onClose={() => setShowAddDialog(false)}\n />\n )}\n\n {trackToEdit && (\n <EditCaptionDialog\n asset={asset}\n track={trackToEdit}\n onUpdate={handleUpdateTrack}\n onClose={() => setTrackToEdit(null)}\n />\n )}\n </Stack>\n )\n}\n","import React, {createContext, useContext} from 'react'\n\nimport {type DialogState, type SetDialogState} from '../hooks/useDialogState'\n\ntype DialogStateContextProps = {\n dialogState: DialogState\n setDialogState: SetDialogState\n}\n\nconst DialogStateContext = createContext<DialogStateContextProps>({\n dialogState: false,\n setDialogState: () => {\n return null\n },\n})\n\ninterface DialogStateProviderProps extends DialogStateContextProps {\n children: React.ReactNode\n}\n\nexport const DialogStateProvider = ({\n dialogState,\n setDialogState,\n children,\n}: DialogStateProviderProps) => {\n return (\n <DialogStateContext.Provider value={{dialogState, setDialogState}}>\n {children}\n </DialogStateContext.Provider>\n )\n}\n\nexport const useDialogStateContext = () => {\n const context = useContext(DialogStateContext)\n return context\n}\n","import type {SanityClient} from 'sanity'\n\nimport {generateJwt} from './generateJwt'\nimport type {MuxPlaybackId, MuxVideoUrl} from './types'\n\ninterface VideoSrcOptions {\n muxPlaybackId: MuxPlaybackId\n client: SanityClient\n}\n\n/**\n * May throw a Promise. Call this with {@link tryWithSuspend} or rethrow the Promise\n */\nexport function getVideoSrc({client, muxPlaybackId}: VideoSrcOptions): MuxVideoUrl {\n const searchParams = new URLSearchParams()\n\n if (muxPlaybackId.policy === 'signed' || muxPlaybackId.policy === 'drm') {\n const token = generateJwt(client, muxPlaybackId.id, 'v')\n searchParams.set('token', token)\n }\n\n return `https://stream.mux.com/${muxPlaybackId.id}.m3u8?${searchParams}`\n}\n","import {Dialog, Stack} from '@sanity/ui'\nimport {useId} from 'react'\n\nimport {useDialogStateContext} from '../context/DialogStateContext'\nimport type {VideoAssetDocument} from '../util/types'\nimport TextTracksManager from './TextTracksManager'\n\nexport interface Props {\n asset: VideoAssetDocument\n}\n\nexport default function CaptionsDialog({asset}: Props) {\n const {setDialogState} = useDialogStateContext()\n const dialogId = `CaptionsDialog${useId()}`\n\n return (\n <Dialog id={dialogId} header=\"Edit Captions\" onClose={() => setDialogState(false)} width={1}>\n <Stack padding={4}>\n <TextTracksManager asset={asset} />\n </Stack>\n </Dialog>\n )\n}\n","import { useState, useEffect } from 'react';\n\n/**\r\n * Get the device pixel ratio, potentially rounded and capped.\r\n * Will emit new values if it changes.\r\n *\r\n * @param options\r\n * @returns The current device pixel ratio, or the default if none can be resolved\r\n */\n\nfunction useDevicePixelRatio(options) {\n const dpr = getDevicePixelRatio(options);\n const [currentDpr, setCurrentDpr] = useState(dpr);\n const {\n defaultDpr,\n maxDpr,\n round\n } = options || {};\n useEffect(() => {\n const canListen = typeof window !== 'undefined' && 'matchMedia' in window;\n\n if (!canListen) {\n return;\n }\n\n const updateDpr = () => setCurrentDpr(getDevicePixelRatio({\n defaultDpr,\n maxDpr,\n round\n }));\n\n const mediaMatcher = window.matchMedia(`screen and (resolution: ${currentDpr}dppx)`); // Safari 13.1 does not have `addEventListener`, but does have `addListener`\n\n if (mediaMatcher.addEventListener) {\n mediaMatcher.addEventListener('change', updateDpr);\n } else {\n mediaMatcher.addListener(updateDpr);\n }\n\n return () => {\n if (mediaMatcher.removeEventListener) {\n mediaMatcher.removeEventListener('change', updateDpr);\n } else {\n mediaMatcher.removeListener(updateDpr);\n }\n };\n }, [currentDpr, defaultDpr, maxDpr, round]);\n return currentDpr;\n}\n/**\r\n * Returns the current device pixel ratio (DPR) given the passed options\r\n *\r\n * @param options\r\n * @returns current device pixel ratio\r\n */\n\nfunction getDevicePixelRatio(options) {\n const {\n defaultDpr = 1,\n maxDpr = 3,\n round = true\n } = options || {};\n const hasDprProp = typeof window !== 'undefined' && typeof window.devicePixelRatio === 'number';\n const dpr = hasDprProp ? window.devicePixelRatio : defaultDpr;\n const rounded = Math.min(Math.max(1, round ? Math.floor(dpr) : dpr), maxDpr);\n return rounded;\n}\n\nexport { getDevicePixelRatio, useDevicePixelRatio };\n//# sourceMappingURL=index.module.js.map\n","/* eslint-disable */\n// From: https://stackoverflow.com/a/11486026/10433647\nexport function formatSeconds(seconds: number): string {\n if (typeof seconds !== 'number' || Number.isNaN(seconds)) {\n return ''\n }\n // Hours, minutes and seconds\n const hrs = ~~(seconds / 3600)\n const mins = ~~((seconds % 3600) / 60)\n const secs = ~~seconds % 60\n\n // Output like \"1:01\" or \"4:03:59\" or \"123:03:59\"\n let ret = ''\n\n if (hrs > 0) {\n ret += '' + hrs + ':' + (mins < 10 ? '0' : '')\n }\n\n ret += '' + mins + ':' + (secs < 10 ? '0' : '')\n ret += '' + secs\n return ret\n}\n\n// Output like \"05:14:01\"\nexport function formatSecondsToHHMMSS(seconds: number): string {\n const hrs = Math.floor(seconds / 3600)\n .toString()\n .padStart(2, '0')\n const mins = Math.floor((seconds % 3600) / 60)\n .toString()\n .padStart(2, '0')\n const secs = Math.floor(seconds % 60)\n .toString()\n .padStart(2, '0')\n\n return `${hrs}:${mins}:${secs}`\n}\n\n// Checks if time has a HH:MM:SS format like \"05:14:01\"\nexport function isValidTimeFormat(time: string) {\n const regex = /^([0-1]?[0-9]|2[0-3]):([0-5]?[0-9]):([0-5]?[0-9])$/\n return regex.test(time) || time === ''\n}\n\n// Converts a time like \"05:14:01\" to seconds\nexport function getSecondsFromTimeFormat(time: string): number {\n const [hh = 0, mm = 0, ss = 0] = time.split(':').map(Number)\n return hh * 3600 + mm * 60 + ss\n}\n","import {Button, Dialog, Flex, Stack, Text, TextInput} from '@sanity/ui'\nimport React, {useId, useMemo, useState} from 'react'\nimport {getDevicePixelRatio} from 'use-device-pixel-ratio'\n\nimport {useDialogStateContext} from '../context/DialogStateContext'\nimport {useClient} from '../hooks/useClient'\nimport {\n formatSecondsToHHMMSS,\n getSecondsFromTimeFormat,\n isValidTimeFormat,\n} from '../util/formatSeconds'\nimport type {VideoAssetDocument} from '../util/types'\nimport VideoThumbnail from './VideoThumbnail'\n\nexport interface Props {\n asset: VideoAssetDocument\n currentTime?: number\n}\n\nexport default function EditThumbnailDialog({asset, currentTime = 0}: Props) {\n const client = useClient()\n\n const {setDialogState} = useDialogStateContext()\n const dialogId = `EditThumbnailDialog${useId()}`\n\n const [timeFormatted, setTimeFormatted] = useState<string>(() =>\n formatSecondsToHHMMSS(currentTime)\n )\n const [nextTime, setNextTime] = useState<number>(currentTime)\n const [inputError, setInputError] = useState<string>('')\n\n const assetWithNewThumbnail = useMemo(() => ({...asset, thumbTime: nextTime}), [asset, nextTime])\n const [saving, setSaving] = useState(false)\n const [saveThumbnailError, setSaveThumbnailError] = useState<Error | null>(null)\n const handleSave = () => {\n setSaving(true)\n client\n .patch(asset._id!)\n .set({thumbTime: nextTime})\n .commit({returnDocuments: false})\n .then(() => void setDialogState(false))\n .catch(setSaveThumbnailError)\n .finally(() => void setSaving(false))\n }\n const width = 300 * getDevicePixelRatio({maxDpr: 2})\n\n if (saveThumbnailError) {\n // eslint-disable-next-line no-warning-comments\n // @TODO handle errors more gracefully\n throw saveThumbnailError\n }\n\n const handleInputChange = (event: React.FormEvent<HTMLInputElement>) => {\n const value = event.currentTarget.value\n setTimeFormatted(value)\n\n if (isValidTimeFormat(value)) {\n setInputError('')\n const totalSeconds = getSecondsFromTimeFormat(value)\n setNextTime(totalSeconds)\n } else {\n setInputError('Invalid time format')\n }\n }\n\n return (\n <Dialog\n id={dialogId}\n header=\"Edit thumbnail\"\n onClose={() => setDialogState(false)}\n footer={\n <Stack padding={3}>\n <Button\n key=\"thumbnail\"\n disabled={inputError !== ''}\n mode=\"ghost\"\n tone=\"primary\"\n loading={saving}\n onClick={handleSave}\n text=\"Set new thumbnail\"\n />\n </Stack>\n }\n >\n <Stack space={3} padding={3}>\n <Stack space={2}>\n <Text size={1} weight=\"semibold\">\n Current:\n </Text>\n <VideoThumbnail asset={asset} width={width} staticImage />\n </Stack>\n <Stack space={2}>\n <Text size={1} weight=\"semibold\">\n New:\n </Text>\n <VideoThumbnail asset={assetWithNewThumbnail} width={width} staticImage />\n </Stack>\n\n <Stack space={2}>\n <Flex align={'center'} justify={'center'}>\n <Text size={5} weight=\"semibold\">\n Or\n </Text>\n </Flex>\n </Stack>\n\n <Stack space={2}>\n <Text size={1} weight=\"semibold\">\n Selected time for thumbnail (hh:mm:ss):\n </Text>\n <TextInput\n size={1}\n value={timeFormatted}\n placeholder=\"hh:mm:ss\"\n onChange={handleInputChange}\n customValidity={inputError}\n />\n </Stack>\n </Stack>\n </Dialog>\n )\n}\n","import type {SVGProps} from 'react'\n\nexport function AudioIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n style={{opacity: '0.65'}}\n d=\"M10.75 19q.95 0 1.6-.65t.65-1.6V13h3v-2h-4v3.875q-.275-.2-.587-.288t-.663-.087q-.95 0-1.6.65t-.65 1.6t.65 1.6t1.6.65M6 22q-.825 0-1.412-.587T4 20V4q0-.825.588-1.412T6 2h8l6 6v12q0 .825-.587 1.413T18 22zm7-13V4H6v16h12V9zM6 4v5zv16z\"\n />\n </svg>\n )\n}\n","import {type MuxPlayerProps, type MuxPlayerRefAttributes} from '@mux/mux-player-react'\nimport MuxPlayer from '@mux/mux-player-react/lazy'\nimport {ErrorOutlineIcon} from '@sanity/icons'\nimport {Card, Text} from '@sanity/ui'\nimport {type PropsWithChildren, Suspense, useMemo, useRef, useState} from 'react'\n\nimport {useDialogStateContext} from '../context/DialogStateContext'\nimport {useClient} from '../hooks/useClient'\nimport {AUDIO_ASPECT_RATIO, MIN_ASPECT_RATIO} from '../util/constants'\nimport {generateJwt} from '../util/generateJwt'\nimport {getPlaybackId} from '../util/getPlaybackPolicy'\nimport {getPlaybackPolicyById} from '../util/getPlaybackPolicy'\nimport {getPosterSrc} from '../util/getPosterSrc'\nimport {getVideoSrc} from '../util/getVideoSrc'\nimport {tryWithSuspend} from '../util/tryWithSuspend'\nimport type {VideoAssetDocument} from '../util/types'\nimport CaptionsDialog from './CaptionsDialog'\nimport EditThumbnailDialog from './EditThumbnailDialog'\nimport {AudioIcon} from './icons/Audio'\n\nexport default function VideoPlayer({\n asset,\n thumbnailWidth = 250,\n children,\n hlsConfig,\n ...props\n}: PropsWithChildren<\n {\n asset: VideoAssetDocument\n thumbnailWidth?: number\n forceAspectRatio?: number\n hlsConfig?: MuxPlayerProps['_hlsConfig']\n } & Partial<Pick<MuxPlayerProps, 'autoPlay'>>\n>) {\n const client = useClient()\n const {dialogState} = useDialogStateContext()\n\n const isAudio = assetIsAudio(asset)\n const muxPlayer = useRef<MuxPlayerRefAttributes>(null)\n const playerContainerRef = useRef<HTMLDivElement>(null)\n const [error, setError] = useState<Error>()\n\n /* Playback ID that will be used to play the video */\n const playbackId = useMemo(() => {\n try {\n return getPlaybackId(asset, ['public', 'signed', 'drm'])\n } catch (e) {\n setError(new TypeError('Asset has no playback ID'))\n return undefined\n }\n }, [asset])\n\n const muxPlaybackId = useMemo(() => {\n if (!playbackId) return undefined\n return getPlaybackPolicyById(asset, playbackId)\n }, [asset, playbackId])\n\n const src = useMemo(() => {\n if (!playbackId) return undefined\n if (!muxPlaybackId) return undefined\n return tryWithSuspend(\n () => getVideoSrc({muxPlaybackId, client}),\n (e: Error) => {\n setError(e)\n return undefined\n }\n )\n }, [muxPlaybackId, playbackId, client])\n\n const poster = useMemo(() => {\n return tryWithSuspend(\n () => getPosterSrc({asset, client, width: thumbnailWidth}),\n (e: Error) => {\n setError(e)\n return undefined\n }\n )\n }, [asset, client, thumbnailWidth])\n\n const signedToken = useMemo(() => {\n try {\n const url = new URL(src!)\n return url.searchParams.get('token')\n } catch {\n return undefined\n }\n }, [src])\n const drmToken = useMemo(() => {\n if (!playbackId) return undefined\n if (muxPlaybackId?.policy !== 'drm') return undefined\n\n return tryWithSuspend(\n () => generateJwt(client, playbackId, 'd'),\n (e: Error) => {\n setError(e)\n return undefined\n }\n )\n }, [client, muxPlaybackId?.policy, playbackId])\n const tokens:\n | Partial<{\n playback?: string\n thumbnail?: string\n storyboard?: string\n drm?: string\n }>\n | undefined = useMemo(() => {\n try {\n const partialTokens: {\n playback?: string\n thumbnail?: string\n storyboard?: string\n drm?: string\n } = {\n playback: undefined,\n thumbnail: undefined,\n storyboard: undefined,\n drm: undefined,\n }\n\n if (signedToken) {\n partialTokens.playback = signedToken\n partialTokens.thumbnail = signedToken\n partialTokens.storyboard = signedToken\n }\n\n if (drmToken) {\n partialTokens.drm = drmToken\n }\n\n return {...partialTokens}\n } catch {\n return undefined\n }\n }, [signedToken, drmToken])\n\n const [width, height] = (asset?.data?.aspect_ratio ?? '16:9').split(':').map(Number)\n const targetAspectRatio =\n props.forceAspectRatio || (Number.isNaN(width) ? 16 / 9 : width / height)\n let aspectRatio = Math.max(MIN_ASPECT_RATIO, targetAspectRatio)\n if (isAudio) {\n aspectRatio = props.forceAspectRatio\n ? // Make it wider when forcing aspect ratio to balance with videos' rendering height (audio players overflow a bit)\n props.forceAspectRatio * 1.2\n : AUDIO_ASPECT_RATIO\n }\n\n /* We use Suspense here because `generateJwt` and related functions use suspend()\n under the hood */\n return (\n <>\n <Card\n ref={playerContainerRef}\n tone=\"transparent\"\n style={{\n aspectRatio: aspectRatio,\n position: 'relative',\n ...(isAudio && {display: 'flex', alignItems: 'flex-end'}),\n }}\n >\n {src && poster && (\n <>\n {isAudio && (\n <AudioIcon\n style={{\n padding: '0.5em',\n width: '2.2em',\n height: '2.2em',\n position: 'absolute',\n top: 0,\n left: 0,\n zIndex: 1,\n }}\n />\n )}\n <Suspense fallback={null}>\n <MuxPlayer\n poster={isAudio ? undefined : poster}\n ref={muxPlayer}\n {...props}\n playsInline\n playbackId={playbackId}\n tokens={tokens}\n preload=\"metadata\"\n crossOrigin=\"anonymous\"\n metadata={{\n player_name: 'Sanity Admin Dashboard',\n player_version: process.env.PKG_VERSION,\n page_type: 'Preview Player',\n }}\n audio={isAudio}\n _hlsConfig={hlsConfig}\n style={{\n ...(!isAudio && {height: '100%'}),\n width: '100%',\n display: 'block',\n objectFit: 'contain',\n ...(isAudio && {alignSelf: 'end'}),\n }}\n />\n {children}\n </Suspense>\n </>\n )}\n {error ? (\n <div\n style={{\n position: 'absolute',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n }}\n >\n <Text muted>\n <ErrorOutlineIcon style={{marginRight: '0.15em'}} />\n {typeof error === 'object' && 'message' in error && typeof error.message === 'string'\n ? error.message\n : 'Error loading video'}\n </Text>\n </div>\n ) : null}\n {children}\n </Card>\n\n {dialogState === 'edit-thumbnail' && (\n <EditThumbnailDialog asset={asset} currentTime={muxPlayer?.current?.currentTime} />\n )}\n {dialogState === 'edit-captions' && <CaptionsDialog asset={asset} />}\n </>\n )\n}\n\nexport function assetIsAudio(asset: VideoAssetDocument) {\n return asset.data?.max_stored_resolution === 'Audio only'\n}\n","// Adapted from https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/MissingSchemaType.tsx\nimport {WarningOutlineIcon} from '@sanity/icons'\nimport type {SanityDocument} from 'sanity'\nimport type {GeneralPreviewLayoutKey} from 'sanity'\nimport {SanityDefaultPreview} from 'sanity'\n\nexport interface MissingSchemaTypeProps {\n layout?: GeneralPreviewLayoutKey\n value: SanityDocument\n}\n\nconst getUnknownTypeFallback = (id: string, typeName: string) => ({\n title: (\n <em>\n No schema found for type <code>{typeName}</code>\n </em>\n ),\n subtitle: (\n <em>\n Document: <code>{id}</code>\n </em>\n ),\n media: () => <WarningOutlineIcon />,\n})\n\nexport function MissingSchemaType(props: MissingSchemaTypeProps) {\n const {layout, value} = props\n\n return (\n <SanityDefaultPreview {...getUnknownTypeFallback(value._id, value._type)} layout={layout} />\n )\n}\n","// Adapted from https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/TimeAgo.tsx\nimport {useTimeAgo} from 'sanity'\n\nexport interface TimeAgoProps {\n time: string | Date\n}\n\nexport function TimeAgo({time}: TimeAgoProps) {\n const timeAgo = useTimeAgo(time)\n\n return <span title={timeAgo}>{timeAgo} ago</span>\n}\n","// Adapted from https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/DraftStatus.tsx\nimport {EditIcon} from '@sanity/icons'\nimport {Box, Text, Tooltip} from '@sanity/ui'\nimport type {PreviewValue, SanityDocument} from 'sanity'\nimport {TextWithTone} from 'sanity'\n\nimport {TimeAgo} from './TimeAgo'\n\nexport function DraftStatus(props: {document?: PreviewValue | Partial<SanityDocument> | null}) {\n const {document} = props\n const updatedAt = document && '_updatedAt' in document && document._updatedAt\n\n return (\n <Tooltip\n animate\n portal\n content={\n <Box padding={2}>\n <Text size={1}>\n {document ? (\n <>Edited {updatedAt && <TimeAgo time={updatedAt} />}</>\n ) : (\n <>No unpublished edits</>\n )}\n </Text>\n </Box>\n }\n >\n <TextWithTone tone=\"caution\" dimmed={!document} muted={!document} size={1}>\n <EditIcon />\n </TextWithTone>\n </Tooltip>\n )\n}\n","// Adapted from https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/PublishedStatus.tsx\n\nimport {PublishIcon} from '@sanity/icons'\nimport {Box, Text, Tooltip} from '@sanity/ui'\nimport type {PreviewValue, SanityDocument} from 'sanity'\nimport {TextWithTone} from 'sanity'\n\nimport {TimeAgo} from './TimeAgo'\n\nexport function PublishedStatus(props: {document?: PreviewValue | Partial<SanityDocument> | null}) {\n const {document} = props\n const updatedAt = document && '_updatedAt' in document && document._updatedAt\n\n return (\n <Tooltip\n animate\n portal\n content={\n <Box padding={2}>\n <Text size={1}>\n {document ? (\n <>Published {updatedAt && <TimeAgo time={updatedAt} />}</>\n ) : (\n <>Not published</>\n )}\n </Text>\n </Box>\n }\n >\n <TextWithTone tone=\"positive\" dimmed={!document} muted={!document} size={1}>\n <PublishIcon />\n </TextWithTone>\n </Tooltip>\n )\n}\n","// Adapted from:\n// https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/paneItem/PaneItemPreview.tsx\nimport {Inline} from '@sanity/ui'\nimport {isNumber, isString} from 'lodash'\nimport {isValidElement, useMemo} from 'react'\nimport {useObservable} from 'react-rx'\nimport type {SanityDocument, SchemaType} from 'sanity'\nimport type {PreviewValue} from 'sanity'\nimport {\n type DocumentPresence,\n DocumentPreviewPresence,\n type DocumentPreviewStore,\n type GeneralPreviewLayoutKey,\n getPreviewStateObservable,\n getPreviewValueWithFallback,\n isRecord,\n SanityDefaultPreview,\n} from 'sanity'\n\nimport {DraftStatus} from './DraftStatus'\nimport {PublishedStatus} from './PublishedStatus'\n\nexport interface PaneItemPreviewState {\n isLoading?: boolean\n draft?: PreviewValue | Partial<SanityDocument> | null\n published?: PreviewValue | Partial<SanityDocument> | null\n}\n\nexport interface PaneItemPreviewProps {\n documentPreviewStore: DocumentPreviewStore\n icon: React.ComponentType | false\n layout: GeneralPreviewLayoutKey\n presence?: DocumentPresence[]\n schemaType: SchemaType\n value: SanityDocument\n}\n\nexport function PaneItemPreview(props: PaneItemPreviewProps) {\n const {icon, layout, presence, schemaType, value} = props\n const title =\n (isRecord(value.title) && isValidElement(value.title)) ||\n isString(value.title) ||\n isNumber(value.title)\n ? value.title\n : null\n\n const observable = useMemo(\n () => getPreviewStateObservable(props.documentPreviewStore, schemaType, value._id),\n [props.documentPreviewStore, schemaType, value._id]\n )\n const {snapshot, original, isLoading} = useObservable(observable, {\n isLoading: true,\n snapshot: null,\n original: null,\n })\n\n const status = isLoading ? null : (\n <Inline space={4}>\n {presence && presence.length > 0 && <DocumentPreviewPresence presence={presence} />}\n <PublishedStatus document={original} />\n <DraftStatus document={snapshot} />\n </Inline>\n )\n\n return (\n <SanityDefaultPreview\n {...(getPreviewValueWithFallback({snapshot, original, fallback: {title}}) as any)}\n isPlaceholder={isLoading}\n icon={icon}\n layout={layout}\n status={status}\n />\n )\n}\n","// Adapted from https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/paneItem/PaneItem.tsx\n\nimport {DocumentIcon} from '@sanity/icons'\nimport type {PropsWithChildren} from 'react'\nimport React, {useMemo} from 'react'\nimport type {CollatedHit, FIXME, SanityDocument, SchemaType} from 'sanity'\nimport {PreviewCard, useDocumentPresence, useDocumentPreviewStore, useSchema} from 'sanity'\nimport {IntentLink} from 'sanity/router'\n\nimport {MissingSchemaType} from './MissingSchemaType'\nimport {PaneItemPreview} from './PaneItemPreview'\n\ninterface DocumentPreviewProps {\n schemaType?: SchemaType\n documentPair: CollatedHit<SanityDocument>\n}\n\n/**\n * Return `false` if we explicitly disable the icon.\n * Otherwise return the passed icon or the schema type icon as a backup.\n */\nexport function getIconWithFallback(\n icon: React.ComponentType<any> | false | undefined,\n schemaType: SchemaType | undefined,\n defaultIcon: React.ComponentType<any>\n): React.ComponentType<any> | false {\n if (icon === false) {\n return false\n }\n\n return icon || ((schemaType && schemaType.icon) as any) || defaultIcon || false\n}\n\nfunction DocumentPreviewLink(props: DocumentPreviewProps) {\n return (linkProps: PropsWithChildren) => (\n <IntentLink intent=\"edit\" params={{id: props.documentPair.id}}>\n {linkProps.children}\n </IntentLink>\n )\n}\n\nexport function DocumentPreview(props: DocumentPreviewProps) {\n const {schemaType, documentPair} = props\n const doc = documentPair?.draft || documentPair?.published\n const id = documentPair.id || ''\n const documentPreviewStore = useDocumentPreviewStore()\n const schema = useSchema()\n const documentPresence = useDocumentPresence(id)\n const hasSchemaType = Boolean(schemaType && schemaType.name && schema.get(schemaType.name))\n\n const PreviewComponent = useMemo(() => {\n if (!doc) return null\n\n if (!schemaType || !hasSchemaType) {\n return <MissingSchemaType value={doc as SanityDocument} />\n }\n\n return (\n <PaneItemPreview\n documentPreviewStore={documentPreviewStore}\n icon={getIconWithFallback(undefined, schemaType, DocumentIcon)}\n schemaType={schemaType}\n layout=\"default\"\n value={doc}\n presence={documentPresence}\n />\n )\n }, [hasSchemaType, schemaType, documentPresence, doc, documentPreviewStore])\n\n return (\n <PreviewCard\n __unstable_focusRing\n as={DocumentPreviewLink(props) as FIXME}\n data-as=\"a\"\n data-ui=\"PaneItem\"\n padding={2}\n radius={2}\n tone=\"inherit\"\n >\n {PreviewComponent}\n </PreviewCard>\n )\n}\n","import type {SanityDocument} from '@sanity/client'\nimport {Box, Card, Text} from '@sanity/ui'\nimport {collate, useSchema} from 'sanity'\nimport {styled} from 'styled-components'\n\nimport {DocumentPreview} from '../documentPreview/DocumentPreview'\nimport SpinnerBox from '../SpinnerBox'\n\nconst Container = styled(Box)`\n * {\n color: ${(props: any) => props.theme.sanity.color.base.fg};\n }\n a {\n text-decoration: none;\n }\n h2 {\n font-size: ${(props: any) => props.theme.sanity.fonts.text.sizes[1]};\n }\n`\n\nconst VideoReferences: React.FC<{\n references?: SanityDocument[]\n isLoaded: boolean\n}> = (props) => {\n const schema = useSchema()\n if (!props.isLoaded) {\n return <SpinnerBox />\n }\n\n if (!props.references?.length) {\n return (\n <Card border radius={3} padding={3}>\n <Text size={2}>No documents are using this video</Text>\n </Card>\n )\n }\n\n const documentPairs = collate(props.references || [])\n return (\n <Container>\n {documentPairs?.map((documentPair) => {\n const schemaType = schema.get(documentPair.type)\n\n return (\n <Card\n key={documentPair.id}\n marginBottom={2}\n padding={2}\n radius={2}\n shadow={1}\n style={{overflow: 'hidden'}}\n >\n <Box>\n <DocumentPreview documentPair={documentPair} schemaType={schemaType} />\n </Box>\n </Card>\n )\n })}\n </Container>\n )\n}\n\nexport default VideoReferences\n","import {TrashIcon} from '@sanity/icons'\nimport {Box, Button, Card, Checkbox, Dialog, Flex, Heading, Stack, Text, useToast} from '@sanity/ui'\nimport {useEffect, useState} from 'react'\nimport type {SanityDocument} from 'sanity'\n\nimport {deleteAsset} from '../../actions/assets'\nimport {useClient} from '../../hooks/useClient'\nimport {DIALOGS_Z_INDEX} from '../../util/constants'\nimport type {VideoAssetDocument} from '../../util/types'\nimport SpinnerBox from '../SpinnerBox'\nimport VideoReferences from './VideoReferences'\n\nexport default function DeleteDialog({\n asset,\n references,\n referencesLoading,\n cancelDelete,\n succeededDeleting,\n}: {\n asset: VideoAssetDocument\n references?: SanityDocument[]\n referencesLoading: boolean\n cancelDelete: () => void\n succeededDeleting: () => void\n}) {\n const client = useClient()\n const [state, setState] = useState<\n 'processing_deletion' | 'checkingReferences' | 'error_deleting' | 'cantDelete' | 'confirm'\n >('checkingReferences')\n const [deleteOnMux, setDeleteOnMux] = useState(true)\n const toast = useToast()\n\n useEffect(() => {\n if (state !== 'checkingReferences' || referencesLoading) return\n\n setState(references?.length ? 'cantDelete' : 'confirm')\n }, [state, references, referencesLoading])\n\n async function confirmDelete() {\n if (state !== 'confirm') return\n\n setState('processing_deletion')\n const worked = await deleteAsset({client, asset, deleteOnMux})\n if (worked === true) {\n toast.push({title: 'Successfully deleted video', status: 'success'})\n succeededDeleting()\n } else if (worked === 'failed-mux') {\n toast.push({\n title: 'Deleted video in Sanity',\n description: \"But it wasn't deleted in Mux\",\n status: 'warning',\n })\n succeededDeleting()\n } else {\n toast.push({title: 'Failed deleting video', status: 'error'})\n\n setState('error_deleting')\n }\n }\n\n return (\n <Dialog\n animate\n header={'Delete video'}\n zOffset={DIALOGS_Z_INDEX}\n id=\"deleting-video-details-dialog\"\n onClose={cancelDelete}\n onClickOutside={cancelDelete}\n width={1}\n position=\"fixed\"\n >\n <Card\n padding={3}\n style={{\n minHeight: '150px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Stack space={3}>\n {state === 'checkingReferences' && (\n <>\n <Heading size={2}>Checking if video can be deleted</Heading>\n <SpinnerBox />\n </>\n )}\n {state === 'cantDelete' && (\n <>\n <Heading size={2}>Video can&apos;t be deleted</Heading>\n <Text size={2} style={{marginBottom: '2rem'}}>\n There are {references?.length} document{references && references.length > 0 && 's'}{' '}\n pointing to this video. Remove their references to this file or delete them before\n proceeding.\n </Text>\n <VideoReferences references={references} isLoaded={!referencesLoading} />\n </>\n )}\n {state === 'confirm' && (\n <>\n <Heading size={2}>Are you sure you want to delete this video?</Heading>\n <Text size={2}>This action is irreversible</Text>\n <Stack space={4} marginY={4}>\n <Flex align=\"center\" as=\"label\">\n <Checkbox\n checked={deleteOnMux}\n onChange={() => setDeleteOnMux((prev) => !prev)}\n />\n <Text style={{margin: '0 10px'}}>Delete asset on Mux</Text>\n </Flex>\n <Flex align=\"center\" as=\"label\">\n <Checkbox disabled checked />\n <Text style={{margin: '0 10px'}}>Delete video from dataset</Text>\n </Flex>\n <Box>\n <Button\n icon={TrashIcon}\n fontSize={2}\n padding={3}\n text=\"Delete video\"\n tone=\"critical\"\n onClick={confirmDelete}\n disabled={['processing_deletion', 'checkingReferences', 'cantDelete'].some(\n (s) => s === state\n )}\n />\n </Box>\n </Stack>\n </>\n )}\n {state === 'processing_deletion' && (\n <>\n <Heading size={2}>Deleting video...</Heading>\n <SpinnerBox />\n </>\n )}\n {state === 'error_deleting' && (\n <>\n <Heading size={2}>Something went wrong!</Heading>\n <Text size={2}>Try deleting the video again by clicking the button below</Text>\n </>\n )}\n </Stack>\n </Card>\n </Dialog>\n )\n}\n","import {createHookFromObservableFactory, DocumentStore, SanityDocument} from 'sanity'\n\nimport {SANITY_API_VERSION} from './useClient'\n\nconst useDocReferences = createHookFromObservableFactory<\n SanityDocument[],\n {\n documentStore: DocumentStore\n id: string\n }\n>(({documentStore, id}) => {\n return documentStore.listenQuery(\n /* groq */ '*[references($id)]{_id, _type, _rev, _updatedAt, _createdAt}',\n {id},\n {\n apiVersion: SANITY_API_VERSION,\n }\n )\n})\n\nexport default useDocReferences\n","import {formatSeconds} from './formatSeconds'\nimport type {MuxTextTrack, VideoAssetDocument} from './types'\n\nexport default function getVideoMetadata(doc: VideoAssetDocument) {\n const id = doc.assetId || doc._id || ''\n const date = doc.data?.created_at\n ? new Date(Number(doc.data.created_at) * 1000)\n : new Date(doc._createdAt || doc._updatedAt || Date.now())\n\n return {\n title: doc.filename || id.slice(0, 12),\n id: id,\n playbackId: doc.playbackId,\n createdAt: date,\n duration: doc.data?.duration ? formatSeconds(doc.data?.duration) : undefined,\n playback_ids: doc.data?.playback_ids,\n aspect_ratio: doc.data?.aspect_ratio,\n max_stored_resolution: doc.data?.max_stored_resolution,\n max_stored_frame_rate: doc.data?.max_stored_frame_rate,\n text_tracks:\n doc.data?.tracks?.filter((track): track is MuxTextTrack => track.type === 'text') || [],\n }\n}\n","import {useToast} from '@sanity/ui'\nimport {useMemo, useState} from 'react'\nimport {useDocumentStore} from 'sanity'\n\nimport {useClient} from '../../hooks/useClient'\nimport useDocReferences from '../../hooks/useDocReferences'\nimport {useResyncAsset} from '../../hooks/useResyncAsset'\nimport getVideoMetadata from '../../util/getVideoMetadata'\nimport {VideoAssetDocument} from '../../util/types'\n\ntype VideoDetailsState = 'idle' | 'saving' | 'deleting' | 'closing' | 'resyncing'\n\nexport interface VideoDetailsProps {\n closeDialog: () => void\n asset: VideoAssetDocument & {autoPlay?: boolean}\n}\n\nexport default function useVideoDetails(props: VideoDetailsProps) {\n const documentStore = useDocumentStore()\n const toast = useToast()\n const client = useClient()\n\n const [references, referencesLoading] = useDocReferences(\n useMemo(() => ({documentStore, id: props.asset._id}), [documentStore, props.asset._id])\n )\n\n const [originalAsset, setOriginalAsset] = useState(() => props.asset)\n const [filename, setFilename] = useState(props.asset.filename)\n const modified = filename !== originalAsset.filename\n\n const displayInfo = getVideoMetadata({...props.asset, filename})\n\n const [state, setState] = useState<VideoDetailsState>('idle')\n\n const {resyncAsset, isResyncing} = useResyncAsset({showToast: true})\n\n async function handleResync() {\n if (state !== 'idle') return\n setState('resyncing')\n await resyncAsset(props.asset)\n setState('idle')\n }\n\n function handleClose() {\n if (state !== 'idle') return\n\n if (modified) {\n setState('closing')\n return\n }\n\n props.closeDialog()\n }\n\n function confirmClose(shouldClose: boolean) {\n if (state !== 'closing') return\n\n if (shouldClose) props.closeDialog()\n\n setState('idle')\n }\n\n async function saveChanges() {\n if (state !== 'idle') return\n setState('saving')\n\n try {\n await client.patch(props.asset._id).set({filename}).commit()\n setOriginalAsset((prev) => ({...prev, filename}))\n toast.push({\n title: 'Video title updated',\n description: `New title: ${filename}`,\n status: 'success',\n })\n props.closeDialog()\n } catch (error) {\n toast.push({\n title: 'Failed updating file name',\n status: 'error',\n description: typeof error === 'string' ? error : 'Please try again',\n })\n setFilename(originalAsset.filename)\n }\n\n setState('idle')\n }\n\n return {\n references,\n referencesLoading,\n modified,\n filename,\n setFilename,\n displayInfo,\n state,\n setState,\n handleClose,\n confirmClose,\n saveChanges,\n handleResync,\n isResyncing,\n }\n}\n","import {\n CalendarIcon,\n CheckmarkIcon,\n ClockIcon,\n CropIcon,\n EditIcon,\n ErrorOutlineIcon,\n RevertIcon,\n SearchIcon,\n SyncIcon,\n TagIcon,\n TrashIcon,\n} from '@sanity/icons'\nimport {\n Button,\n Card,\n Dialog,\n Flex,\n Heading,\n Spinner,\n Stack,\n Tab,\n TabList,\n TabPanel,\n Text,\n TextInput,\n} from '@sanity/ui'\nimport React, {useEffect, useState} from 'react'\n\nimport {DIALOGS_Z_INDEX} from '../../util/constants'\nimport {MuxPlaybackId, MuxTextTrack, PlaybackPolicy} from '../../util/types'\nimport FormField from '../FormField'\nimport IconInfo from '../IconInfo'\nimport {ResolutionIcon} from '../icons/Resolution'\nimport {StopWatchIcon} from '../icons/StopWatch'\nimport TextTracksManager from '../TextTracksManager'\nimport VideoPlayer from '../VideoPlayer'\nimport DeleteDialog from './DeleteDialog'\nimport useVideoDetails, {VideoDetailsProps} from './useVideoDetails'\nimport VideoReferences from './VideoReferences'\n\nconst AssetInput: React.FC<{\n label: string\n description?: string\n placeholder?: string\n value: string\n onInput: (e: React.FormEvent<HTMLInputElement>) => void\n disabled?: boolean\n}> = (props) => (\n <FormField title={props.label} description={props.description} inputId={props.label}>\n <TextInput\n id={props.label}\n value={props.value}\n placeholder={props.placeholder}\n onInput={props.onInput}\n disabled={props.disabled}\n />\n </FormField>\n)\n\nconst VideoDetails: React.FC<VideoDetailsProps> = (props) => {\n const [tab, setTab] = useState<'details' | 'references'>('details')\n const {\n displayInfo,\n filename,\n modified,\n references,\n referencesLoading,\n setFilename,\n state,\n setState,\n handleClose,\n confirmClose,\n saveChanges,\n handleResync,\n isResyncing,\n } = useVideoDetails(props)\n\n const isSaving = state === 'saving'\n\n // Avoid layout shifts in large screens' 2-column dialog by setting their `minHeight` to the container's\n const [containerHeight, setContainerHeight] = useState<number | null>(null)\n const contentsRef = React.useRef<HTMLDivElement>(null)\n useEffect(() => {\n if (!contentsRef.current || !('getBoundingClientRect' in contentsRef.current)) return\n\n setContainerHeight(contentsRef.current.getBoundingClientRect().height)\n }, [])\n\n return (\n <Dialog\n animate\n header={displayInfo.title}\n zOffset={DIALOGS_Z_INDEX}\n id=\"video-details-dialog\"\n onClose={handleClose}\n onClickOutside={handleClose}\n width={2}\n position=\"fixed\"\n footer={\n <Card padding={3}>\n <Flex justify=\"space-between\" align=\"center\">\n <Flex gap={2}>\n <Button\n icon={TrashIcon}\n fontSize={2}\n padding={3}\n mode=\"bleed\"\n text=\"Delete\"\n tone=\"critical\"\n onClick={() => setState('deleting')}\n disabled={isSaving || isResyncing}\n />\n <Button\n icon={SyncIcon}\n fontSize={2}\n padding={3}\n mode=\"bleed\"\n text=\"Resync\"\n tone=\"primary\"\n onClick={handleResync}\n disabled={isSaving || isResyncing}\n iconRight={isResyncing && Spinner}\n />\n </Flex>\n {modified && (\n <Button\n icon={CheckmarkIcon}\n fontSize={2}\n padding={3}\n mode=\"ghost\"\n text=\"Save and close\"\n tone=\"positive\"\n onClick={saveChanges}\n iconRight={isSaving && Spinner}\n disabled={isSaving || isResyncing}\n />\n )}\n </Flex>\n </Card>\n }\n >\n {/* DELETION DIALOG */}\n {state === 'deleting' && (\n <DeleteDialog\n asset={props.asset}\n cancelDelete={() => setState('idle')}\n referencesLoading={referencesLoading}\n references={references}\n succeededDeleting={() => {\n props.closeDialog()\n }}\n />\n )}\n\n {/* CONFIRM CLOSING DIALOG */}\n {state === 'closing' && (\n <Dialog\n animate\n header={'You have unsaved changes'}\n zOffset={DIALOGS_Z_INDEX}\n id=\"closing-video-details-dialog\"\n onClose={() => confirmClose(false)}\n onClickOutside={() => confirmClose(false)}\n width={1}\n position=\"fixed\"\n footer={\n <Card padding={3}>\n <Flex justify=\"space-between\" align=\"center\">\n <Button\n icon={ErrorOutlineIcon}\n fontSize={2}\n padding={3}\n text=\"Discard changes\"\n tone=\"critical\"\n onClick={() => confirmClose(true)}\n />\n {modified && (\n <Button\n icon={RevertIcon}\n fontSize={2}\n padding={3}\n mode=\"ghost\"\n text=\"Keep editing\"\n tone=\"primary\"\n onClick={() => confirmClose(false)}\n />\n )}\n </Flex>\n </Card>\n }\n >\n <Card padding={5}>\n <Stack style={{textAlign: 'center'}} space={3}>\n <Heading size={2}>Unsaved changes will be lost</Heading>\n <Text size={2}>Are you sure you want to discard them?</Text>\n </Stack>\n </Card>\n </Dialog>\n )}\n <Card\n padding={4}\n sizing=\"border\"\n style={{\n containerType: 'inline-size',\n }}\n >\n <Flex\n sizing=\"border\"\n gap={4}\n direction={['column', 'column', 'row']}\n align=\"flex-start\"\n ref={contentsRef}\n style={\n typeof containerHeight === 'number'\n ? {\n minHeight: containerHeight,\n }\n : undefined\n }\n >\n <Stack space={4} flex={1} sizing=\"border\">\n <VideoPlayer asset={props.asset} autoPlay={props.asset.autoPlay || false} />\n {tab === 'details' && (\n <TextTracksManager\n asset={props.asset}\n iconOnly\n collapseTracks\n tracks={\n displayInfo?.text_tracks ||\n props.asset.data?.tracks?.filter(\n (track): track is MuxTextTrack => track.type === 'text'\n ) ||\n []\n }\n />\n )}\n </Stack>\n <Stack space={4} flex={1} sizing=\"border\">\n <TabList space={2}>\n <Tab\n aria-controls=\"details-panel\"\n icon={EditIcon}\n id=\"details-tab\"\n label=\"Details\"\n onClick={() => setTab('details')}\n selected={tab === 'details'}\n />\n <Tab\n aria-controls=\"references-panel\"\n icon={SearchIcon}\n id=\"references-tab\"\n label={`Used by ${references ? `(${references.length})` : ''}`}\n onClick={() => setTab('references')}\n selected={tab === 'references'}\n />\n </TabList>\n <TabPanel\n aria-labelledby=\"details-tab\"\n id=\"details-panel\"\n hidden={tab !== 'details'}\n style={{wordBreak: 'break-word'}}\n >\n <Stack space={4}>\n <AssetInput\n label=\"Video title or file name\"\n description=\"Not visible to users. Useful for finding videos later.\"\n value={filename || ''}\n onInput={(e) => setFilename(e.currentTarget.value)}\n disabled={state !== 'idle'}\n />\n <Stack space={3}>\n {displayInfo?.duration && (\n <IconInfo\n text={`Duration: ${displayInfo.duration}`}\n icon={ClockIcon}\n size={2}\n />\n )}\n {displayInfo?.max_stored_resolution && (\n <IconInfo\n text={`Max Resolution: ${displayInfo.max_stored_resolution}`}\n icon={ResolutionIcon}\n size={2}\n />\n )}\n {displayInfo?.max_stored_frame_rate && (\n <IconInfo\n text={`Frame rate: ${displayInfo.max_stored_frame_rate}`}\n icon={StopWatchIcon}\n size={2}\n />\n )}\n {displayInfo?.aspect_ratio && (\n <IconInfo\n text={`Aspect Ratio: ${displayInfo.aspect_ratio}`}\n icon={CropIcon}\n size={2}\n />\n )}\n <IconInfo\n text={`Uploaded on: ${displayInfo.createdAt.toLocaleDateString('en', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n hour12: true,\n })}`}\n icon={CalendarIcon}\n size={2}\n />\n <IconInfo text={`Mux ID: \\n${displayInfo.id}`} icon={TagIcon} size={2} />\n <PlaybackIds playback_ids={displayInfo.playback_ids} />\n </Stack>\n </Stack>\n </TabPanel>\n <TabPanel\n aria-labelledby=\"references-tab\"\n id=\"references-panel\"\n hidden={tab !== 'references'}\n >\n <VideoReferences references={references} isLoaded={!referencesLoading} />\n </TabPanel>\n </Stack>\n </Flex>\n </Card>\n </Dialog>\n )\n}\n\nconst PlaybackIds = ({playback_ids}: {playback_ids?: MuxPlaybackId[]}) => {\n if (playback_ids) {\n return playback_ids.map((entry) => (\n <IconInfo\n key={entry.id}\n text={`Playback ID [${policyToText(entry.policy)}]: ${entry.id}`}\n icon={TagIcon}\n size={2}\n />\n ))\n }\n return <IconInfo text={'No Playback ID'} icon={TagIcon} size={2} />\n}\n\nconst policyToText = (policy: PlaybackPolicy) => {\n switch (policy) {\n case 'drm':\n return 'DRM'\n case 'signed':\n return 'Signed'\n case 'public':\n return 'Public'\n default:\n return policy\n }\n}\nexport default VideoDetails\n","import {CalendarIcon, ClockIcon, TagIcon} from '@sanity/icons'\nimport {Inline, Stack, Text} from '@sanity/ui'\n\nimport getVideoMetadata from '../util/getVideoMetadata'\nimport type {VideoAssetDocument} from '../util/types'\nimport IconInfo from './IconInfo'\n\nconst VideoMetadata = (props: {asset: VideoAssetDocument}) => {\n if (!props.asset) {\n return null\n }\n\n const displayInfo = getVideoMetadata(props.asset)\n return (\n <Stack space={2}>\n {displayInfo.title && (\n <Text\n size={1}\n weight=\"semibold\"\n style={{\n wordWrap: 'break-word',\n }}\n >\n {displayInfo.title}\n </Text>\n )}\n <Inline space={3}>\n {displayInfo?.duration && (\n <IconInfo text={displayInfo.duration} icon={ClockIcon} size={1} muted />\n )}\n <IconInfo\n text={displayInfo.createdAt.toISOString().split('T')[0]}\n icon={CalendarIcon}\n size={1}\n muted\n />\n {displayInfo.title != displayInfo.id.slice(0, 12) && (\n <IconInfo text={displayInfo.id.slice(0, 12)} icon={TagIcon} size={1} muted />\n )}\n </Inline>\n </Stack>\n )\n}\n\nexport default VideoMetadata\n","import {CheckmarkIcon, EditIcon, LockIcon, PlayIcon} from '@sanity/icons'\nimport {Button, Card, Stack, Text, Tooltip} from '@sanity/ui'\nimport React, {useState} from 'react'\nimport {styled} from 'styled-components'\n\nimport {DRMWarningDialog, useDrmPlaybackWarningContext} from '../context/DrmPlaybackWarningContext'\nimport {THUMBNAIL_ASPECT_RATIO} from '../util/constants'\nimport {getPlaybackPolicy} from '../util/getPlaybackPolicy'\nimport {VideoAssetDocument} from '../util/types'\nimport IconInfo from './IconInfo'\nimport {AudioIcon} from './icons/Audio'\nimport VideoMetadata from './VideoMetadata'\nimport VideoPlayer, {assetIsAudio} from './VideoPlayer'\nimport VideoThumbnail from './VideoThumbnail'\n\nconst PlayButton = styled.button`\n display: block;\n padding: 0;\n margin: 0;\n border: none;\n border-radius: 0.1875rem;\n position: relative;\n cursor: pointer;\n\n &::after {\n content: '';\n background: var(--card-fg-color);\n opacity: 0;\n display: block;\n position: absolute;\n inset: 0;\n z-index: 10;\n transition: 0.15s ease-out;\n border-radius: inherit;\n }\n\n > div[data-play] {\n z-index: 11;\n opacity: 0;\n transition: 0.15s 0.05s ease-out;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n color: var(--card-fg-color);\n background: var(--card-bg-color);\n width: auto;\n height: 30%;\n aspect-ratio: 1;\n border-radius: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n box-sizing: border-box;\n > svg {\n display: block;\n width: 70%;\n height: auto;\n // Visual balance to center-align the icon\n transform: translateX(5%);\n }\n }\n\n &:hover,\n &:focus {\n &::after {\n opacity: 0.3;\n }\n > div[data-play] {\n opacity: 1;\n }\n }\n`\n\ntype RenderState = 'render-video' | 'pre-render-warn' | false\n\nexport default function VideoInBrowser({\n onSelect,\n onEdit,\n asset,\n}: {\n onSelect?: (asset: VideoAssetDocument) => void\n onEdit?: (asset: VideoAssetDocument) => void\n asset: VideoAssetDocument\n}) {\n const [renderVideo, setRenderVideo] = useState<RenderState>(false)\n const select = React.useCallback(() => onSelect?.(asset), [onSelect, asset])\n const edit = React.useCallback(() => onEdit?.(asset), [onEdit, asset])\n const {hasShownWarning} = useDrmPlaybackWarningContext()\n\n if (!asset) {\n return null\n }\n\n const playbackPolicy = getPlaybackPolicy(asset)\n const onClickPlay = () => {\n if (playbackPolicy?.policy === 'drm' && !hasShownWarning) {\n setRenderVideo('pre-render-warn')\n } else {\n setRenderVideo('render-video')\n }\n }\n return (\n <Card\n border\n padding={2}\n sizing=\"border\"\n radius={2}\n style={{\n position: 'relative',\n }}\n >\n {playbackPolicy?.policy === 'signed' && (\n <Tooltip\n animate\n content={\n <Card padding={2} radius={2}>\n <IconInfo icon={LockIcon} text=\"Signed playback policy\" size={2} />\n </Card>\n }\n placement=\"right\"\n fallbackPlacements={['top', 'bottom']}\n portal\n >\n <Card\n tone=\"caution\"\n style={{\n borderRadius: '100%',\n position: 'absolute',\n left: '1em',\n top: '1em',\n zIndex: 11,\n }}\n padding={2}\n border\n >\n <Text muted size={1}>\n <LockIcon />\n </Text>\n </Card>\n </Tooltip>\n )}\n {playbackPolicy?.policy === 'drm' && (\n <Tooltip\n animate\n content={\n <Card padding={2} radius={2}>\n <IconInfo icon={LockIcon} text=\"DRM playback policy\" size={2} />\n </Card>\n }\n placement=\"right\"\n fallbackPlacements={['top', 'bottom']}\n portal\n >\n <Card\n tone=\"caution\"\n style={{\n borderRadius: '0.25rem',\n position: 'absolute',\n left: '1em',\n top: '1em',\n zIndex: 11,\n }}\n padding={2}\n border\n >\n <Text muted size={1} weight=\"semibold\" style={{color: 'var(--card-icon-color)'}}>\n DRM\n </Text>\n </Card>\n </Tooltip>\n )}\n <Stack\n space={3}\n height=\"fill\"\n style={{\n gridTemplateRows: 'min-content min-content 1fr',\n }}\n >\n {renderVideo === 'pre-render-warn' && (\n <DRMWarningDialog\n onClose={() => {\n setRenderVideo('render-video')\n }}\n />\n )}\n {renderVideo === 'render-video' ? (\n <VideoPlayer asset={asset} autoPlay forceAspectRatio={THUMBNAIL_ASPECT_RATIO} />\n ) : (\n <PlayButton onClick={onClickPlay}>\n <div data-play>\n <PlayIcon />\n </div>\n {assetIsAudio(asset) ? (\n <div\n style={{\n aspectRatio: THUMBNAIL_ASPECT_RATIO,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <AudioIcon width=\"3em\" height=\"3em\" />\n </div>\n ) : (\n <VideoThumbnail asset={asset} />\n )}\n </PlayButton>\n )}\n <VideoMetadata asset={asset} />\n <div\n style={{\n display: 'flex',\n width: '100%',\n alignItems: 'flex-end',\n justifyContent: 'flex-start',\n gap: '.35rem',\n }}\n >\n {onSelect && (\n <Button\n icon={CheckmarkIcon}\n fontSize={2}\n padding={2}\n mode=\"ghost\"\n text=\"Select\"\n style={{flex: 1}}\n tone=\"positive\"\n onClick={select}\n />\n )}\n <Button\n icon={EditIcon}\n fontSize={2}\n padding={2}\n mode=\"ghost\"\n text=\"Details\"\n style={{flex: 1}}\n onClick={edit}\n />\n </div>\n </Stack>\n </Card>\n )\n}\n","import {SearchIcon} from '@sanity/icons'\nimport {Card, Flex, Grid, Inline, Label, Stack, Text, TextInput} from '@sanity/ui'\nimport {useMemo, useState} from 'react'\n\nimport {DrmPlaybackWarningContextProvider} from '../context/DrmPlaybackWarningContext'\nimport useAssets from '../hooks/useAssets'\nimport type {PluginConfig, VideoAssetDocument} from '../util/types'\nimport ConfigureApi from './ConfigureApi'\nimport ImportVideosFromMux from './ImportVideosFromMux'\nimport PageSelector from './PageSelector'\nimport ResyncMetadata from './ResyncMetadata'\nimport {SelectSortOptions} from './SelectSortOptions'\nimport SpinnerBox from './SpinnerBox'\nimport type {VideoDetailsProps} from './VideoDetails/useVideoDetails'\nimport VideoDetails from './VideoDetails/VideoDetails'\nimport VideoInBrowser from './VideoInBrowser'\n\nexport interface VideosBrowserProps {\n config: PluginConfig\n onSelect?: (asset: VideoAssetDocument) => void\n}\n\nexport default function VideosBrowser({onSelect, config}: VideosBrowserProps) {\n const {assets, isLoading, searchQuery, setSearchQuery, setSort, sort} = useAssets()\n const [page, setPage] = useState<number>(0)\n const pageLimit = 20\n const pageTotal = Math.floor(assets.length / pageLimit) + 1\n const [editedAsset, setEditedAsset] = useState<VideoDetailsProps['asset'] | null>(null)\n const freshEditedAsset = useMemo(\n () => assets.find((a) => a._id === editedAsset?._id) || editedAsset,\n [editedAsset, assets]\n )\n\n const pageStart = page * pageLimit\n const pageEnd = pageStart + pageLimit\n\n const placement = onSelect ? 'input' : 'tool'\n return (\n <DrmPlaybackWarningContextProvider config={config}>\n <Stack padding={4} space={4} style={{minHeight: '50vh'}}>\n <Flex justify=\"space-between\" align=\"center\">\n <Flex align=\"center\" gap={3}>\n <TextInput\n value={searchQuery}\n icon={SearchIcon}\n onInput={(e: React.FormEvent<HTMLInputElement>) =>\n setSearchQuery(e.currentTarget.value)\n }\n placeholder=\"Search videos\"\n />\n <SelectSortOptions setSort={setSort} sort={sort} />\n <PageSelector page={page} setPage={setPage} total={pageTotal} />\n </Flex>\n {placement === 'tool' && (\n <Inline space={2}>\n <ImportVideosFromMux />\n <ResyncMetadata />\n <ConfigureApi />\n </Inline>\n )}\n </Flex>\n <Stack space={3}>\n {assets?.length > 0 && (\n <Label muted>\n {assets.length} video{assets.length > 1 ? 's' : null}{' '}\n {searchQuery ? `matching \"${searchQuery}\"` : 'found'}\n </Label>\n )}\n <Grid\n gap={2}\n style={{\n gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))',\n }}\n >\n {assets.slice(pageStart, pageEnd).map((asset) => (\n <VideoInBrowser\n key={asset._id}\n asset={asset}\n onEdit={setEditedAsset}\n onSelect={onSelect}\n />\n ))}\n </Grid>\n </Stack>\n {isLoading && <SpinnerBox />}\n\n {!isLoading && assets.length === 0 && (\n <Card marginY={4} paddingX={4} paddingY={6} border radius={2} tone=\"transparent\">\n <Text align=\"center\" muted size={3}>\n {searchQuery ? `No videos found for \"${searchQuery}\"` : 'No videos in this dataset'}\n </Text>\n </Card>\n )}\n </Stack>\n {freshEditedAsset && (\n <VideoDetails closeDialog={() => setEditedAsset(null)} asset={freshEditedAsset} />\n )}\n </DrmPlaybackWarningContextProvider>\n )\n}\n","import type {Tool} from 'sanity'\n\nimport type {PluginConfig} from '../util/types'\nimport ToolIcon from './icons/ToolIcon'\nimport VideosBrowser from './VideosBrowser'\n\nconst StudioTool: React.FC<PluginConfig> = (config) => {\n return <VideosBrowser config={config} />\n}\n\nexport const DEFAULT_TOOL_CONFIG = {\n icon: ToolIcon,\n title: 'Videos',\n}\n\nexport default function createStudioTool(config: PluginConfig): Tool {\n const toolConfig = typeof config.tool === 'object' ? config.tool : DEFAULT_TOOL_CONFIG\n return {\n name: 'mux',\n icon: toolConfig.icon || DEFAULT_TOOL_CONFIG.icon,\n title: toolConfig.title || DEFAULT_TOOL_CONFIG.title,\n component: (props: any) => <StudioTool {...config} {...props} />,\n }\n}\n","import {useCurrentUser} from 'sanity'\n\nimport {PluginConfig} from '../util/types'\n\nexport const useAccessControl = (config: PluginConfig) => {\n const user = useCurrentUser()\n\n const hasConfigAccess =\n !config?.allowedRolesForConfiguration?.length ||\n user?.roles?.some((role) => config.allowedRolesForConfiguration.includes(role.name))\n\n return {hasConfigAccess}\n}\n","import {isReference} from 'sanity'\nimport {useDocumentValues} from 'sanity'\n\nimport type {Reference, VideoAssetDocument} from '../util/types'\n\nconst path = ['assetId', 'data', 'playbackId', 'status', 'thumbTime', 'filename']\nexport const useAssetDocumentValues = (asset: Reference | null | undefined) =>\n useDocumentValues<VideoAssetDocument | null | undefined>(\n isReference(asset) ? asset._ref! : '',\n path\n )\n","import {useMemo} from 'react'\nimport {useDataset, useProjectId} from 'sanity'\nimport useSWR from 'swr'\n\nimport {useClient} from '../hooks/useClient'\nimport type {MuxAsset, VideoAssetDocument} from '../util/types'\n\n// Poll MUX if it's preparing the main document or its own static renditions\nexport const useMuxPolling = (asset?: VideoAssetDocument) => {\n const client = useClient()\n const projectId = useProjectId()\n const dataset = useDataset()\n const isPreparingStaticRenditions = useMemo(() => {\n // Legacy: If static_renditions has a status field, it was created with mp4_support (deprecated)\n // We don't process this old format, just return false\n // Note: 'disabled' status is valid in the new format when no renditions were requested\n if (\n asset?.data?.static_renditions?.status &&\n asset?.data?.static_renditions?.status !== 'disabled'\n ) {\n return false\n }\n\n const files = asset?.data?.static_renditions?.files\n if (!files || files.length === 0) {\n return false\n }\n return files.some((file) => file.status === 'preparing')\n }, [asset?.data?.static_renditions?.status, asset?.data?.static_renditions?.files])\n\n const shouldFetch = useMemo(\n () => !!asset?.assetId && (asset?.status === 'preparing' || isPreparingStaticRenditions),\n [asset?.assetId, asset?.status, isPreparingStaticRenditions]\n )\n return useSWR(\n shouldFetch ? `/${projectId}/addons/mux/assets/${dataset}/data/${asset?.assetId}` : null,\n async () => {\n const {data} = await client.request<{data: MuxAsset}>({\n url: `/addons/mux/assets/${dataset}/data/${asset!.assetId}`,\n withCredentials: true,\n method: 'GET',\n })\n client.patch(asset!._id!).set({status: data.status, data}).commit({returnDocuments: false})\n },\n {refreshInterval: 2000, refreshWhenHidden: true, dedupingInterval: 1000}\n )\n}\n","import r,{PureComponent as t,useReducer as e,useRef as n,useCallback as o}from\"react\";var c=function(r){var t,e;function n(t){var e;return(e=r.call(this,t)||this).state={hasError:!1,error:null},e}e=r,(t=n).prototype=Object.create(e.prototype),t.prototype.constructor=t,t.__proto__=e,n.getDerivedStateFromError=function(r){return{hasError:!0,error:r}};var o=n.prototype;return o.componentDidCatch=function(r,t){return this.props.onDidCatch(r,t)},o.render=function(){var r=this.state,t=this.props,e=t.render,n=t.children,o=t.renderError;return r.hasError?o?o({error:r.error}):null:e?e():n||null},n}(t),u=function(r,t){switch(t.type){case\"catch\":return{didCatch:!0,error:t.error};case\"reset\":return{didCatch:!1,error:null};default:return r}};function a(t){var a=e(u,{didCatch:!1,error:null}),i=a[0],d=a[1],h=n(null);function l(){return e=function(r,e){d({type:\"catch\",error:r}),t&&t.onDidCatch&&t.onDidCatch(r,e)},function(t){return r.createElement(c,{onDidCatch:e,children:t.children,render:t.render,renderError:t.renderError})};var e}var p,s=o(function(){h.current=l(),d({type:\"reset\"})},[]);return{ErrorBoundary:(p=h.current,null!==p?p:(h.current=l(),h.current)),didCatch:i.didCatch,error:i.error,reset:s}}export default a;export{a as useErrorBoundary};\n//# sourceMappingURL=index.module.js.map\n","/* eslint-disable no-console */\nimport {Button, Card, Flex, Grid, Heading, Inline, Text, useToast} from '@sanity/ui'\nimport React, {memo, useCallback, useRef} from 'react'\nimport scrollIntoView from 'scroll-into-view-if-needed'\nimport {clear} from 'suspend-react'\nimport {useErrorBoundary} from 'use-error-boundary'\n\nimport {name} from '../util/constants'\nimport {type MuxInputProps} from '../util/types'\n\nexport interface Props extends Pick<MuxInputProps, 'schemaType'> {\n children: React.ReactNode\n}\nfunction ErrorBoundaryCard(props: Props) {\n const {children, schemaType} = props\n const {push: pushToast} = useToast()\n const errorRef = useRef(null)\n const {ErrorBoundary, didCatch, error, reset} = useErrorBoundary({\n onDidCatch: (err, errorInfo) => {\n console.group(err.toString())\n console.groupCollapsed('console.error')\n console.error(err)\n console.groupEnd()\n if (err.stack) {\n console.groupCollapsed('error.stack')\n console.log(err.stack)\n console.groupEnd()\n }\n if (errorInfo?.componentStack) {\n console.groupCollapsed('errorInfo.componentStack')\n console.log(errorInfo.componentStack)\n console.groupEnd()\n }\n console.groupEnd()\n pushToast({\n status: 'error',\n title: 'Plugin crashed',\n description: (\n <Flex align=\"center\">\n <Inline space={1}>\n An error happened while rendering\n <Button\n padding={1}\n fontSize={1}\n style={{transform: 'translateY(1px)'}}\n mode=\"ghost\"\n text={schemaType.title}\n onClick={() => {\n if (errorRef.current) {\n scrollIntoView(errorRef.current, {\n behavior: 'smooth',\n scrollMode: 'if-needed',\n block: 'center',\n })\n }\n }}\n />\n </Inline>\n </Flex>\n ),\n })\n },\n })\n const handleRetry = useCallback(() => {\n // Purge request cache before retrying, otherwise the cached errors will rethrow\n clear([name])\n\n reset()\n }, [reset])\n\n if (didCatch) {\n return (\n <Card ref={errorRef} paddingX={[2, 3, 4, 4]} height=\"fill\" shadow={1} overflow=\"auto\">\n <Flex justify=\"flex-start\" align=\"center\" height=\"fill\">\n <Grid columns={1} gap={[2, 3, 4, 4]}>\n <Heading as=\"h1\">\n The <code>{name}</code> plugin crashed\n </Heading>\n {error?.message && (\n <Card padding={3} tone=\"critical\" shadow={1} radius={2}>\n <Text>{error.message}</Text>\n </Card>\n )}\n <Inline>\n <Button onClick={handleRetry} text=\"Retry\" />\n </Inline>\n </Grid>\n </Flex>\n </Card>\n )\n }\n\n return <ErrorBoundary>{children}</ErrorBoundary>\n}\n\nexport default memo(ErrorBoundaryCard)\n","import {Box, Card, Flex, Spinner, Text} from '@sanity/ui'\n\nexport const InputFallback = () => {\n return (\n <div style={{padding: 1}}>\n <Card\n shadow={1}\n sizing=\"border\"\n style={{aspectRatio: '16/9', width: '100%', borderRadius: '1px'}}\n >\n <Flex align=\"center\" direction=\"column\" height=\"fill\" justify=\"center\">\n <Spinner muted />\n <Box marginTop={3}>\n <Text align=\"center\" muted size={1}>\n Loading…\n </Text>\n </Box>\n </Flex>\n </Card>\n </div>\n )\n}\n","import {PlugIcon} from '@sanity/icons'\nimport {Button, Card, Flex, Grid, Heading, Inline, Text} from '@sanity/ui'\nimport {useCallback} from 'react'\n\nimport {useAccessControl} from '../hooks/useAccessControl'\nimport type {SetDialogState} from '../hooks/useDialogState'\nimport {PluginConfig} from '../util/types'\nimport MuxLogo from './MuxLogo'\n\ninterface OnboardProps {\n setDialogState: SetDialogState\n config: PluginConfig\n}\n\nexport default function Onboard(props: OnboardProps) {\n const {setDialogState} = props\n const handleOpen = useCallback(() => setDialogState('secrets'), [setDialogState])\n const {hasConfigAccess} = useAccessControl(props.config)\n\n return (\n <>\n <div style={{padding: 2}}>\n <Card\n display=\"flex\"\n sizing=\"border\"\n style={{\n aspectRatio: '16/9',\n width: '100%',\n boxShadow: 'var(--card-bg-color) 0 0 0 2px',\n }}\n paddingX={[2, 3, 4, 4]}\n radius={1}\n tone=\"transparent\"\n >\n <Flex justify=\"flex-start\" align=\"center\">\n <Grid columns={1} gap={[2, 3, 4, 4]}>\n <Inline paddingY={1}>\n <div style={{height: '32px'}}>\n <MuxLogo />\n </div>\n </Inline>\n <Inline paddingY={1}>\n <Heading size={[0, 1, 2, 2]}>\n Upload and preview videos directly from your studio.\n </Heading>\n </Inline>\n <Inline paddingY={1}>\n {hasConfigAccess ? (\n <Button mode=\"ghost\" icon={PlugIcon} text=\"Configure API\" onClick={handleOpen} />\n ) : (\n <Card padding={[3, 3, 3]} radius={2} shadow={1} tone=\"critical\">\n <Text>\n You do not have access to configure the Mux API. Please contact your\n administrator.\n </Text>\n </Card>\n )}\n </Inline>\n </Grid>\n </Flex>\n </Card>\n </div>\n </>\n )\n}\n","import {UpChunk} from '@mux/upchunk'\nimport {Observable} from 'rxjs'\n\nexport function createUpChunkObservable(uuid: string, uploadUrl: string, source: File) {\n return new Observable<\n | {type: 'pause' | 'resume'; id: string}\n | {type: 'success'; id: string}\n | {type: 'progress'; percent: number}\n >((subscriber) => {\n const upchunk = UpChunk.createUpload({\n endpoint: uploadUrl,\n file: source,\n dynamicChunkSize: true, // changes the chunk size based on network speeds\n })\n\n const successHandler = () => {\n subscriber.next({\n type: 'success',\n id: uuid,\n })\n subscriber.complete()\n }\n\n const errorHandler = (data: CustomEvent) => subscriber.error(new Error(data.detail.message))\n\n const progressHandler = (data: CustomEvent) => {\n return subscriber.next({type: 'progress', percent: data.detail})\n }\n\n const offlineHandler = () => {\n upchunk.pause()\n subscriber.next({\n type: 'pause',\n id: uuid,\n })\n }\n\n const onlineHandler = () => {\n upchunk.resume()\n subscriber.next({\n type: 'resume',\n id: uuid,\n })\n }\n\n upchunk.on('success', successHandler)\n upchunk.on('error', errorHandler)\n upchunk.on('progress', progressHandler)\n upchunk.on('offline', offlineHandler)\n upchunk.on('online', onlineHandler)\n\n return () => upchunk.abort()\n })\n}\n","/**\n * Format Google Drive share links as Google Drive export links.\n * Supported formats:\n * - https://drive.google.com/uc?id=<ID>...\n * - https://drive.google.com/open?id=<ID>...\n * - https://drive.google.com/file/d/<ID>...\n * - https://drive.google.com/folder/<ID>...\n *\n * @param url Google Drive share link to format.\n * @returns Google Drive export link (URL passthrough if not share link).\n */\nexport function formatDriveShareLink(url: string): string {\n // Export link formatter.\n const formatExportLink = (id: string) => {\n return `https://drive.google.com/uc?export=download&id=${id}`\n }\n\n // URL formatting.\n try {\n // Parse URL.\n const trimmed = url.trim()\n const parsed = new URL(trimmed)\n\n // Enforce strict host name.\n if (parsed.hostname !== 'drive.google.com') {\n throw new Error('URL is not from Google Drive.')\n }\n\n // Look for ID in search parameters.\n const id = parsed.searchParams.get('id') || ''\n if (id.length) {\n return formatExportLink(id)\n }\n\n // Look for ID in path name.\n const path = parsed.pathname.split('/') || []\n\n // Path is /file/d/<ID>...\n if (path.includes('file') && path.includes('d')) {\n const index =\n path.findIndex((value: string) => {\n return value === 'd'\n }) + 1\n const fileId = path.at(index) || ''\n return formatExportLink(fileId)\n }\n\n // Path is /folder/<ID>...\n if (path.includes('folders')) {\n const index =\n path.findIndex((value: string) => {\n return value === 'folders'\n }) + 1\n const folderId = path.at(index) || ''\n return formatExportLink(folderId)\n }\n\n // URL not recognized.\n throw new Error('URL was not recognized.')\n } catch {\n // URL passthrough by default.\n return url\n }\n}\n","/**\n * Rounds the numeric part of a px string to the nearest integer.\n * Returns undefined if the value is not a valid px string or not a finite number.\n * Avoids sending 0px (and JS -0); snaps to ±1 instead.\n */\nexport function roundPxString(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n if (!trimmed.endsWith('px')) return undefined\n const n = Number(trimmed.slice(0, -2))\n if (!Number.isFinite(n)) return undefined\n let rounded = Math.round(n)\n // Avoid sending 0px (and JS -0); keep sign when negative.\n if (rounded === 0) rounded = n < 0 ? -1 : 1\n return `${rounded}px`\n}\n","import {uuid as generateUuid} from '@sanity/uuid'\nimport {concat, defer, from, type Observable, of, throwError} from 'rxjs'\nimport {catchError, mergeMap, mergeMapTo, switchMap} from 'rxjs/operators'\nimport type {SanityClient} from 'sanity'\n\nimport {createUpChunkObservable} from '../clients/upChunkObservable'\nimport {formatDriveShareLink} from '../util/formatDriveShareLink'\nimport {roundPxString} from '../util/roundPxString'\nimport type {MuxAsset, MuxNewAssetSettings, WatermarkConfig} from '../util/types'\nimport {getAsset} from './assets'\nimport {testSecretsObservable} from './secrets'\n\nfunction sanitizeOverlaySettingsInPlace(settings: MuxNewAssetSettings) {\n const inputs = settings.input\n if (!inputs) return\n for (const input of inputs) {\n const overlay = (input as {overlay_settings?: Record<string, unknown>}).overlay_settings\n if (!overlay) continue\n\n const hm = roundPxString(overlay.horizontal_margin)\n const vm = roundPxString(overlay.vertical_margin)\n const w = roundPxString(overlay.width)\n\n if (hm) overlay.horizontal_margin = hm\n if (vm) overlay.vertical_margin = vm\n if (w) overlay.width = w\n }\n}\n\nfunction sanitizePxStringsInJson(json: string): string {\n return json.replace(/\"(-?\\d+(?:\\.\\d+)?)px\"/g, (_match, num) => {\n const n = Number(num)\n if (!Number.isFinite(n)) return _match\n let rounded = Math.round(n)\n if (rounded === 0) rounded = n < 0 ? -1 : 1\n return `\"${rounded}px\"`\n })\n}\n\nexport function cancelUpload(client: SanityClient, uuid: string) {\n return client.observable.request({\n url: `/addons/mux/uploads/${client.config().dataset}/${uuid}`,\n withCredentials: true,\n method: 'DELETE',\n })\n}\n\nexport function uploadUrl({\n url,\n settings,\n client,\n watermark,\n}: {\n url: string\n settings: MuxNewAssetSettings\n client: SanityClient\n watermark?: WatermarkConfig\n}) {\n return testUrl(url).pipe(\n switchMap((validUrl) => {\n return concat(\n of({type: 'url' as const, url: validUrl}),\n testSecretsObservable(client).pipe(\n switchMap((json) => {\n if (!json || !json.status) {\n return throwError(new Error('Invalid credentials'))\n }\n const uuid = generateUuid()\n const muxBody = settings\n if (!muxBody.input) muxBody.input = [{type: 'video'}]\n muxBody.input[0].url = validUrl\n sanitizeOverlaySettingsInPlace(muxBody)\n\n const query = {\n muxBody: sanitizePxStringsInJson(JSON.stringify(muxBody)),\n filename: validUrl.split('/').slice(-1)[0],\n }\n\n const dataset = client.config().dataset\n return defer(() =>\n client.observable.request({\n url: `/addons/mux/assets/${dataset}`,\n withCredentials: true,\n method: 'POST',\n headers: {\n 'MUX-Proxy-UUID': uuid,\n 'Content-Type': 'application/json',\n },\n query,\n })\n ).pipe(\n mergeMap((result) => {\n const asset =\n (result && result.results && result.results[0] && result.results[0].document) ||\n null\n\n if (!asset) {\n return throwError(new Error('No asset document returned'))\n }\n return of({type: 'success' as const, id: uuid, asset})\n })\n )\n })\n )\n )\n })\n )\n}\n\nexport function uploadFile({\n settings,\n client,\n file,\n watermark,\n}: {\n settings: MuxNewAssetSettings\n client: SanityClient\n file: File\n watermark?: WatermarkConfig\n}) {\n return testFile(file).pipe(\n switchMap((fileOptions) => {\n return concat(\n of({type: 'file' as const, file: fileOptions}),\n testSecretsObservable(client).pipe(\n switchMap((json) => {\n if (!json || !json.status) {\n return throwError(() => new Error('Invalid credentials'))\n }\n const uuid = generateUuid()\n const body = settings\n sanitizeOverlaySettingsInPlace(body)\n\n return concat(\n of({type: 'uuid' as const, uuid}),\n defer(() =>\n client.observable.request<{\n sanityAssetId: string\n upload: {\n cors_origin: string\n id: string\n new_asset_settings: MuxNewAssetSettings\n status: 'waiting'\n timeout: number\n url: string\n }\n }>({\n url: `/addons/mux/uploads/${client.config().dataset}`,\n withCredentials: true,\n method: 'POST',\n headers: {\n 'MUX-Proxy-UUID': uuid,\n 'Content-Type': 'application/json',\n },\n body,\n })\n ).pipe(\n mergeMap((result) => {\n return createUpChunkObservable(uuid, result.upload.url, file).pipe(\n // eslint-disable-next-line no-warning-comments\n // @TODO type the observable events\n // eslint-disable-next-line max-nested-callbacks\n mergeMap((event) => {\n if (event.type !== 'success') {\n return of(event)\n }\n return from(updateAssetDocumentFromUpload(client, uuid, watermark)).pipe(\n // eslint-disable-next-line max-nested-callbacks\n mergeMap((doc) => of({...event, asset: doc}))\n )\n }),\n // eslint-disable-next-line max-nested-callbacks\n catchError((err) => {\n // Delete asset document\n return cancelUpload(client, uuid).pipe(mergeMapTo(throwError(err)))\n })\n )\n })\n )\n )\n })\n )\n )\n })\n )\n}\n\ntype UploadResponse = {\n data: {\n asset_id: string\n cors_origin: string\n id: string\n new_asset_settings: {\n static_renditions?: {resolution: string}[]\n passthrough: string\n playback_policies: ['public' | 'signed' | 'drm']\n }\n status: string\n timeout: number\n }\n}\nexport function getUpload(client: SanityClient, assetId: string) {\n const {dataset} = client.config()\n return client.request<UploadResponse>({\n url: `/addons/mux/uploads/${dataset}/${assetId}`,\n withCredentials: true,\n method: 'GET',\n })\n}\n\nfunction pollUpload(client: SanityClient, uuid: string): Promise<UploadResponse> {\n const maxTries = 10\n let pollInterval: number\n let tries = 0\n let assetId: string\n let upload: UploadResponse\n return new Promise((resolve, reject) => {\n pollInterval = (setInterval as typeof window.setInterval)(async () => {\n try {\n upload = await getUpload(client, uuid)\n } catch (err) {\n reject(err)\n return\n }\n assetId = upload && upload.data && upload.data.asset_id\n if (assetId) {\n clearInterval(pollInterval)\n resolve(upload)\n }\n if (tries > maxTries) {\n clearInterval(pollInterval)\n reject(new Error('Upload did not finish'))\n }\n tries++\n }, 2000)\n })\n}\n\nasync function updateAssetDocumentFromUpload(\n client: SanityClient,\n uuid: string,\n _watermark?: WatermarkConfig\n) {\n let upload: UploadResponse\n let asset: {data: MuxAsset}\n try {\n upload = await pollUpload(client, uuid)\n } catch (err) {\n return Promise.reject(err)\n }\n try {\n asset = await getAsset(client, upload.data.asset_id)\n } catch (err) {\n return Promise.reject(err)\n }\n\n const doc = {\n _id: uuid,\n _type: 'mux.videoAsset',\n status: asset.data.status,\n data: asset.data,\n assetId: asset.data.id,\n playbackId: asset.data.playback_ids[0].id,\n uploadId: upload.data.id,\n }\n return client.createOrReplace(doc).then(() => {\n return doc\n })\n}\n\nexport function testFile(file: File) {\n if (typeof window !== 'undefined' && file instanceof window.File) {\n const fileOptions = optionsFromFile({}, file)\n return of(fileOptions)\n }\n return throwError(new Error('Invalid file'))\n}\n\nexport function testUrl(url: string): Observable<string> {\n const error = new Error('Invalid URL')\n if (typeof url !== 'string') {\n return throwError(error)\n }\n let formattedUrl = url.trim()\n formattedUrl = formatDriveShareLink(formattedUrl)\n let parsed\n try {\n parsed = new URL(formattedUrl)\n } catch (err) {\n return throwError(error)\n }\n if (parsed && !parsed.protocol.match(/http:|https:/)) {\n return throwError(error)\n }\n return of(formattedUrl)\n}\n\nfunction optionsFromFile(opts: {preserveFilename?: boolean}, file: File) {\n if (typeof window === 'undefined' || !(file instanceof window.File)) {\n return undefined\n }\n return {\n name: opts.preserveFilename === false ? undefined : file.name,\n type: file.type,\n }\n}\n","import {ServerError} from '@sanity/client'\nimport {type InputProps, isObjectInputProps, type PreviewLayoutKey, type PreviewProps} from 'sanity'\n\nimport type {MuxInputPreviewProps, MuxInputProps} from './types'\n\nexport function isMuxInputProps(props: InputProps): props is MuxInputProps {\n return isObjectInputProps(props) && props.schemaType.type?.name === 'mux.video'\n}\n\nexport function isMuxInputPreviewProps(\n props: PreviewProps<PreviewLayoutKey>\n): props is MuxInputPreviewProps {\n return props.schemaType?.type?.name === 'mux.video'\n}\n\nexport function isValidUrl(url: string): boolean {\n try {\n const parsed = new URL(url)\n return parsed && !!parsed.protocol.match(/http:|https:/)\n } catch {\n return false\n }\n}\n\n/**\n * We consider a server error one with status code 5XX.\n * Used mainly to handle unknown Proxy issues.\n */\nexport function isServerError(error: Error): error is ServerError {\n return (\n 'statusCode' in error &&\n typeof error.statusCode === 'number' &&\n 500 <= error.statusCode &&\n error.statusCode <= 600\n )\n}\n","/**\n * Utilities for extracting files from dataTransfer in a predictable cross-browser fashion.\n * Also recursively extracts files from a directory\n * Inspired by https://github.com/component/normalized-upload\n */\n\nexport function extractDroppedFiles(dataTransfer: DataTransfer) {\n const files = Array.from(dataTransfer.files || [])\n const items = Array.from(dataTransfer.items || [])\n if (files && files.length > 0) {\n return Promise.resolve(files)\n }\n return normalizeItems(items).then((arr) => arr.flat())\n}\n\nfunction normalizeItems(items: DataTransferItem[]) {\n return Promise.all(\n items.map((item) => {\n // directory\n if (item.kind === 'file' && item.webkitGetAsEntry) {\n let entry: FileSystemEntry | File[] | null\n // Edge throws\n try {\n entry = item.webkitGetAsEntry()\n } catch (err) {\n return [item.getAsFile()]\n }\n if (!entry) {\n return []\n }\n return entry.isDirectory ? walk(entry) : [item.getAsFile()]\n }\n\n // file\n if (item.kind === 'file') {\n const file = item.getAsFile()\n return Promise.resolve(file ? [file] : [])\n }\n\n // others\n return new Promise((resolve) => item.getAsString(resolve)).then((str?: any) =>\n str ? [new File([str], 'unknown.txt', {type: item.type})] : []\n )\n })\n )\n}\n\nfunction isFile(entry: FileSystemEntry): entry is FileSystemFileEntry {\n return entry.isFile\n}\nfunction isDirectory(entry: FileSystemEntry): entry is FileSystemDirectoryEntry {\n return entry.isDirectory\n}\n\nfunction walk(entry: FileSystemEntry): any {\n if (isFile(entry)) {\n return new Promise((resolve) => entry.file(resolve)).then((file) => [file])\n }\n\n if (isDirectory(entry)) {\n const dir = entry.createReader()\n return new Promise<any>((resolve) => dir.readEntries(resolve))\n .then((entries: FileSystemEntry[]) => entries.filter((entr) => !entr.name.startsWith('.')))\n .then((entries) => Promise.all(entries.map(walk)).then((arr) => arr.flat()))\n }\n return Promise.resolve([])\n}\n","import {useCallback} from 'react'\nimport {PatchEvent, set, setIfMissing, unset} from 'sanity'\n\nimport type {SetDialogState} from '../hooks/useDialogState'\nimport type {MuxInputProps, PluginConfig, VideoAssetDocument} from '../util/types'\nimport VideosBrowser, {type VideosBrowserProps} from './VideosBrowser'\n\nexport interface Props extends Pick<MuxInputProps, 'onChange'> {\n asset?: VideoAssetDocument | null | undefined\n setDialogState: SetDialogState\n config: PluginConfig\n}\n\nexport default function SelectAssets({\n asset: selectedAsset,\n onChange,\n setDialogState,\n config,\n}: Props) {\n const handleSelect = useCallback<Required<VideosBrowserProps>['onSelect']>(\n (chosenAsset) => {\n if (!chosenAsset?._id) {\n onChange(PatchEvent.from([unset(['asset'])]))\n }\n if (chosenAsset._id !== selectedAsset?._id) {\n onChange(\n PatchEvent.from([\n setIfMissing({asset: {}, _type: 'mux.video'}),\n set({_type: 'reference', _weak: true, _ref: chosenAsset._id}, ['asset']),\n ])\n )\n }\n setDialogState(false)\n },\n [onChange, setDialogState, selectedAsset]\n )\n\n return <VideosBrowser onSelect={handleSelect} config={config} />\n}\n","import {Dialog} from '@sanity/ui'\nimport {useCallback, useId} from 'react'\nimport {styled} from 'styled-components'\n\nimport type {SetDialogState} from '../hooks/useDialogState'\nimport SelectAsset, {type Props as SelectAssetProps} from './SelectAsset'\n\n/** To prevent Content Layout Shift (CLS), ensure that the dialog always occupies the entire available height. */\nconst StyledDialog = styled(Dialog)`\n > div[data-ui='DialogCard'] > div[data-ui='Card'] {\n height: 100%;\n }\n`\n\nexport default function InputBrowser({\n setDialogState,\n asset,\n onChange,\n config,\n}: Pick<SelectAssetProps, 'onChange' | 'asset' | 'config'> & {\n setDialogState: SetDialogState\n}) {\n const id = `InputBrowser${useId()}`\n const handleClose = useCallback(() => setDialogState(false), [setDialogState])\n return (\n <StyledDialog\n __unstable_autoFocus\n header=\"Select video\"\n id={id}\n onClose={handleClose}\n width={2}\n >\n <SelectAsset\n config={config}\n asset={asset}\n onChange={onChange}\n setDialogState={setDialogState}\n />\n </StyledDialog>\n )\n}\n","import {useCallback} from 'react'\nimport {PatchEvent, unset} from 'sanity'\n\nimport {deleteAssetOnMux} from '../actions/assets'\nimport {useClient} from '../hooks/useClient'\nimport type {MuxInputProps, VideoAssetDocument} from '../util/types'\n\nexport const useCancelUpload = (asset: VideoAssetDocument, onChange: MuxInputProps['onChange']) => {\n const client = useClient()\n return useCallback(() => {\n if (!asset) {\n return\n }\n onChange(PatchEvent.from(unset()))\n if (asset.assetId) {\n deleteAssetOnMux(client, asset.assetId)\n }\n if (asset._id) {\n client.delete(asset._id)\n }\n }, [asset, client, onChange])\n}\n","import {Suspense, useState} from 'react'\nimport {styled} from 'styled-components'\n\nimport {useClient} from '../hooks/useClient'\nimport {getStoryboardSrc} from '../util/getStoryboardSrc'\nimport type {VideoAssetDocument} from '../util/types'\n\nexport const StyledCenterControls = styled.div`\n && {\n --media-background-color: transparent;\n --media-button-icon-width: 100%;\n --media-button-icon-height: auto;\n pointer-events: none;\n width: 100%;\n display: flex;\n flex-flow: row;\n align-items: center;\n justify-content: center;\n media-play-button {\n --media-control-background: transparent;\n --media-control-hover-background: transparent;\n padding: 0;\n width: max(27px, min(9%, 90px));\n }\n }\n`\n\nexport const TopControls = styled.div`\n position: absolute;\n top: 0;\n right: 0;\n justify-content: flex-end;\n button {\n height: auto;\n }\n`\n\nexport interface PosterImageProps {\n asset: VideoAssetDocument\n}\nexport interface ThumbnailsMetadataTrackProps {\n asset: VideoAssetDocument\n}\nexport function ThumbnailsMetadataTrack({asset}: ThumbnailsMetadataTrackProps) {\n const client = useClient()\n // Why useState instead of useMemo? Because we really really only want to run it exactly once and useMemo doesn't make that guarantee\n const [src] = useState<string>(() => getStoryboardSrc({asset, client}))\n\n return (\n /* We use Suspense here because `getStoryboardSrc` uses suspend() under the hood */\n <Suspense fallback={null}>\n <track label=\"thumbnails\" default kind=\"metadata\" src={src} />\n </Suspense>\n )\n}\n","// Lifted from sanity/form/inputs/files/common/UploadProgress\n\nimport {Button, Card, Code, Flex, Inline, Stack, Text} from '@sanity/ui'\nimport {LinearProgress} from 'sanity'\nimport {styled} from 'styled-components'\n\nexport const CardWrapper = styled(Card)`\n min-height: 82px;\n box-sizing: border-box;\n`\n\nexport const FlexWrapper = styled(Flex)`\n text-overflow: ellipsis;\n overflow: hidden;\n`\n\nexport const LeftSection = styled(Stack)`\n position: relative;\n width: 60%;\n`\n\nexport const CodeWrapper = styled(Code)`\n position: relative;\n width: 100%;\n\n code {\n overflow: hidden;\n text-overflow: ellipsis;\n position: relative;\n max-width: 200px;\n }\n`\n\nexport const UploadProgress = ({\n progress = 100,\n onCancel,\n filename,\n text = 'Uploading',\n}: {\n progress: number\n filename?: React.ReactNode\n onCancel?: React.MouseEventHandler<HTMLButtonElement>\n text?: React.ReactNode\n}) => {\n // Disable cancel button when upload is 90% or more complete\n // to prevent inconsistency between Mux and Sanity\n const isCancelDisabled = progress >= 90\n\n return (\n <CardWrapper tone=\"primary\" padding={4} border height=\"fill\">\n <FlexWrapper align=\"center\" justify=\"space-between\" height=\"fill\" direction=\"row\" gap={2}>\n <LeftSection>\n <Flex justify=\"center\" gap={[3, 3, 2, 2]} direction={['column', 'column', 'row']}>\n <Text size={1}>\n <Inline space={2}>\n {text}\n <CodeWrapper size={1}>{filename ? filename : '...'}</CodeWrapper>\n </Inline>\n </Text>\n </Flex>\n\n <Card marginTop={3} radius={5} shadow={1}>\n <LinearProgress value={progress} />\n </Card>\n </LeftSection>\n\n {onCancel ? (\n <Button\n fontSize={2}\n text=\"Cancel upload\"\n mode=\"ghost\"\n tone=\"critical\"\n onClick={onCancel}\n disabled={isCancelDisabled}\n />\n ) : null}\n </FlexWrapper>\n </CardWrapper>\n )\n}\n","import {Card, Text} from '@sanity/ui'\nimport React, {useEffect, useMemo, useRef} from 'react'\n\nimport {useCancelUpload} from '../hooks/useCancelUpload'\nimport type {MuxInputProps, PluginConfig, VideoAssetDocument} from '../util/types'\nimport {TopControls} from './Player.styled'\nimport {UploadProgress} from './UploadProgress'\nimport VideoPlayer from './VideoPlayer'\n\ninterface Props extends Pick<MuxInputProps, 'onChange' | 'readOnly'> {\n buttons?: React.ReactNode\n asset: VideoAssetDocument\n config?: PluginConfig\n}\n\nconst Player = ({asset, buttons, readOnly, onChange, config}: Props) => {\n const isLoading = useMemo<boolean | string>(() => {\n if (asset?.status === 'preparing') {\n return 'Preparing the video'\n }\n if (asset?.status === 'waiting_for_upload') {\n return 'Waiting for upload to start'\n }\n if (asset?.status === 'waiting') {\n return 'Processing upload'\n }\n if (asset?.status === 'ready') {\n return false\n }\n if (typeof asset?.status === 'undefined') {\n return false\n }\n\n return true\n }, [asset])\n const isPreparingStaticRenditions = useMemo<boolean>(() => {\n // Legacy: If static_renditions has a status field, it was created with mp4_support (deprecated)\n // We don't process this old format, just return false\n // Note: 'disabled' status is valid in the new format when no renditions were requested\n if (\n asset?.data?.static_renditions?.status &&\n asset?.data?.static_renditions?.status !== 'disabled'\n ) {\n return false\n }\n\n // Check if any file in static_renditions is still preparing\n const files = asset?.data?.static_renditions?.files\n if (!files || files.length === 0) {\n return false\n }\n return files.some((file) => file.status === 'preparing')\n }, [asset?.data?.static_renditions?.status, asset?.data?.static_renditions?.files])\n const playRef = useRef<HTMLDivElement>(null)\n const muteRef = useRef<HTMLDivElement>(null)\n const handleCancelUpload = useCancelUpload(asset, onChange)\n\n useEffect(() => {\n const style = document.createElement('style')\n style.innerHTML = 'button svg { vertical-align: middle; }'\n\n if (playRef.current?.shadowRoot) {\n playRef.current.shadowRoot.appendChild(style)\n }\n if (muteRef?.current?.shadowRoot) {\n muteRef.current.shadowRoot.appendChild(style.cloneNode(true))\n }\n }, [])\n\n useEffect(() => {\n if (asset?.status === 'errored') {\n handleCancelUpload()\n // eslint-disable-next-line no-warning-comments\n // @TODO use better error handling\n throw new Error(asset.data?.errors?.messages?.join(' '))\n }\n }, [asset.data?.errors?.messages, asset?.status, handleCancelUpload])\n\n if (!asset || !asset.status) {\n return null\n }\n\n if (isLoading) {\n return (\n <UploadProgress\n progress={100}\n filename={asset?.filename}\n text={(isLoading !== true && isLoading) || 'Waiting for Mux to complete the upload'}\n onCancel={readOnly ? undefined : () => handleCancelUpload()}\n />\n )\n }\n\n return (\n <VideoPlayer asset={asset} hlsConfig={config?.hlsConfig}>\n {buttons && <TopControls slot=\"top-chrome\">{buttons}</TopControls>}\n {isPreparingStaticRenditions && (\n <Card\n padding={2}\n radius={1}\n style={{\n background: 'var(--card-fg-color)',\n position: 'absolute',\n top: '0.5em',\n left: '0.5em',\n }}\n >\n <Text size={1} style={{color: 'var(--card-bg-color)'}}>\n MUX is preparing static renditions, please stand by\n </Text>\n </Card>\n )}\n </VideoPlayer>\n )\n}\n\nexport default Player\n","// todo: get these utils from @sanity/ui instead\nexport function focusRingBorderStyle(border: {color: string; width: number}): string {\n return `inset 0 0 0 ${border.width}px ${border.color}`\n}\n\nexport function focusRingStyle(opts: {\n base?: {bg: string}\n border?: {color: string; width: number}\n focusRing: {offset: number; width: number}\n}): string {\n const {base, border, focusRing} = opts\n const focusRingOutsetWidth = focusRing.offset + focusRing.width\n const focusRingInsetWidth = 0 - focusRing.offset\n const bgColor = base ? base.bg : 'var(--card-bg-color)'\n\n return [\n focusRingInsetWidth > 0 && `inset 0 0 0 ${focusRingInsetWidth}px var(--card-focus-ring-color)`,\n border && focusRingBorderStyle(border),\n focusRingInsetWidth < 0 && `0 0 0 ${0 - focusRingInsetWidth}px ${bgColor}`,\n focusRingOutsetWidth > 0 && `0 0 0 ${focusRingOutsetWidth}px var(--card-focus-ring-color)`,\n ]\n .filter(Boolean)\n .join(',')\n}\n","import {MenuItem} from '@sanity/ui'\nimport {css, styled} from 'styled-components'\n\nimport {focusRingStyle} from './withFocusRing/helpers'\n\nexport const FileButton = styled(MenuItem)(({theme}) => {\n const {focusRing} = theme.sanity\n const base = theme.sanity.color.base\n const border = {width: 1, color: 'var(--card-border-color)'}\n\n return css`\n position: relative;\n\n &:not([data-disabled='true']) {\n &:focus-within {\n box-shadow: ${focusRingStyle({base, border, focusRing})};\n }\n }\n\n & input {\n overflow: hidden;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n position: absolute;\n min-width: 0;\n display: block;\n appearance: none;\n padding: 0;\n margin: 0;\n border: 0;\n opacity: 0;\n }\n `\n})\n","import {Box, ButtonProps, Flex, Text} from '@sanity/ui'\nimport React, {createElement, isValidElement, useId} from 'react'\nimport {isValidElementType} from 'react-is'\n\nimport {FileButton} from './FileInputMenuItem.styled'\n\nexport interface FileInputMenuItemProps extends ButtonProps {\n accept?: string\n capture?: 'user' | 'environment'\n multiple?: boolean\n onSelect?: (files: File[]) => void\n disabled?: boolean\n}\n\nexport const FileInputMenuItem = React.forwardRef(function FileInputMenuItem(\n props: FileInputMenuItemProps &\n Omit<React.HTMLProps<HTMLButtonElement>, 'as' | 'ref' | 'type' | 'value' | 'onSelect'>,\n forwardedRef: React.ForwardedRef<HTMLInputElement>\n) {\n const {\n icon,\n id: idProp,\n accept,\n capture,\n fontSize,\n multiple,\n onSelect,\n space = 3,\n textAlign,\n text,\n disabled,\n ...rest\n } = props\n const idHook = useId()\n const id = idProp || idHook\n\n const handleChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n if (onSelect && event.target.files) {\n onSelect(Array.from(event.target.files))\n }\n },\n [onSelect]\n )\n\n const content = (\n <Flex align=\"center\" justify=\"flex-start\">\n {/* Icon */}\n {icon && (\n <Box marginRight={text ? space : undefined}>\n <Text size={fontSize}>\n {isValidElement(icon) && icon}\n {isValidElementType(icon) && createElement(icon)}\n </Text>\n </Box>\n )}\n\n {/* Text */}\n {text && (\n <Text align={textAlign} size={fontSize} textOverflow=\"ellipsis\">\n {text}\n </Text>\n )}\n </Flex>\n )\n\n return (\n <FileButton {...rest} htmlFor={id} disabled={disabled} ref={forwardedRef}>\n {content}\n\n {/* Visibly hidden input */}\n <input\n data-testid=\"file-button-input\"\n accept={accept}\n capture={capture}\n id={id}\n multiple={multiple}\n onChange={handleChange}\n type=\"file\"\n value=\"\"\n disabled={disabled}\n />\n </FileButton>\n )\n})\n","import {\n EllipsisHorizontalIcon,\n ImageIcon,\n LockIcon,\n PlugIcon,\n ResetIcon,\n SearchIcon,\n SyncIcon,\n TranslateIcon,\n UploadIcon,\n} from '@sanity/icons'\nimport {\n Box,\n Button,\n Card,\n Inline,\n Label,\n Menu,\n MenuDivider,\n MenuItem,\n Popover,\n Text,\n Tooltip,\n useClickOutsideEvent,\n} from '@sanity/ui'\nimport {memo, useCallback, useEffect, useMemo, useState} from 'react'\nimport {PatchEvent, unset} from 'sanity'\nimport {styled} from 'styled-components'\n\nimport {useAccessControl} from '../hooks/useAccessControl'\nimport {type DialogState, type SetDialogState} from '../hooks/useDialogState'\nimport {useResyncAsset} from '../hooks/useResyncAsset'\nimport {getPlaybackPolicy} from '../util/getPlaybackPolicy'\nimport type {MuxInputProps, PluginConfig, VideoAssetDocument} from '../util/types'\nimport {FileInputMenuItem} from './FileInputMenuItem'\n\nconst LockCard = styled(Card)`\n position: absolute;\n top: 0;\n left: 0;\n opacity: 0.6;\n mix-blend-mode: screen;\n background: transparent;\n`\n\nconst LockButton = styled(Button)`\n background: transparent;\n color: white;\n`\n\n// @TODO: add support for audio type (asset._type) when uploading an audio file so we can hide the thumbnail option.\nconst isVideoAsset = (asset: VideoAssetDocument) => {\n return asset._type === 'mux.videoAsset'\n}\n\nfunction PlayerActionsMenu(\n props: Pick<MuxInputProps, 'onChange' | 'readOnly'> & {\n asset: VideoAssetDocument\n onSelect: (files: File[]) => void\n dialogState: DialogState\n setDialogState: SetDialogState\n config: PluginConfig\n accept: string\n }\n) {\n const {asset, readOnly, dialogState, setDialogState, onChange, onSelect, accept} = props\n const [open, setOpen] = useState(false)\n const [menuElement, setMenuRef] = useState<HTMLDivElement | null>(null)\n const isSigned = useMemo(() => getPlaybackPolicy(asset)?.policy === 'signed', [asset])\n const {hasConfigAccess} = useAccessControl(props.config)\n const {resyncAsset, isResyncing} = useResyncAsset({showToast: true})\n\n const onReset = useCallback(() => onChange(PatchEvent.from(unset([]))), [onChange])\n\n const handleResync = useCallback(async () => {\n setOpen(false)\n await resyncAsset(asset)\n }, [resyncAsset, asset])\n\n useEffect(() => {\n if (open && dialogState) {\n setOpen(false)\n }\n }, [dialogState, open])\n\n useClickOutsideEvent(\n () => setOpen(false),\n () => [menuElement]\n )\n\n return (\n <Inline space={1} padding={2}>\n {isSigned && (\n <Tooltip\n animate\n content={\n <Box padding={2}>\n <Text muted size={1}>\n Signed playback policy\n </Text>\n </Box>\n }\n placement=\"right\"\n portal\n >\n <LockCard radius={2} margin={2} scheme=\"dark\" tone=\"positive\">\n <LockButton icon={LockIcon} mode=\"bleed\" tone=\"positive\" />\n </LockCard>\n </Tooltip>\n )}\n <Popover\n animate\n content={\n <Menu ref={setMenuRef}>\n <Box padding={2}>\n <Label muted size={1}>\n Replace\n </Label>\n </Box>\n <FileInputMenuItem\n accept={accept}\n icon={UploadIcon}\n onSelect={onSelect}\n text=\"Upload\"\n disabled={readOnly}\n fontSize={1}\n />\n <MenuItem\n icon={SearchIcon}\n text=\"Browse\"\n onClick={() => setDialogState('select-video')}\n />\n {isVideoAsset(asset) && (\n <>\n <MenuItem\n icon={ImageIcon}\n text=\"Thumbnail\"\n onClick={() => setDialogState('edit-thumbnail')}\n />\n <MenuItem\n icon={TranslateIcon}\n text=\"Captions\"\n onClick={() => setDialogState('edit-captions')}\n />\n <MenuItem\n icon={SyncIcon}\n text=\"Resync from Mux\"\n onClick={handleResync}\n disabled={readOnly || isResyncing}\n />\n </>\n )}\n <MenuDivider />\n {hasConfigAccess && (\n <>\n <MenuItem\n icon={PlugIcon}\n text=\"Configure API\"\n onClick={() => setDialogState('secrets')}\n />\n <MenuDivider />\n </>\n )}\n <MenuItem\n tone=\"critical\"\n icon={ResetIcon}\n text=\"Clear field\"\n onClick={onReset}\n disabled={readOnly}\n />\n </Menu>\n }\n portal\n open={open}\n >\n <Button\n icon={EllipsisHorizontalIcon}\n mode=\"ghost\"\n fontSize={1}\n onClick={() => {\n setDialogState(false)\n setOpen(true)\n }}\n />\n </Popover>\n </Inline>\n )\n}\n\nexport default memo(PlayerActionsMenu)\n","import {useEffect, useState} from 'react'\n\nimport {StagedUpload} from '../components/Uploader'\n\nexport function useFetchFileSize(stagedUpload: StagedUpload, maxFileSize?: number) {\n const [fileSize, setFileSize] = useState<number | null>(null)\n const [isLoadingFileSize, setIsLoadingFileSize] = useState(false)\n const [canSkipFileSizeValidation, setCanSkipFileSizeValidation] = useState(false)\n\n useEffect(() => {\n // Fetch URL Upload file size\n if (stagedUpload.type === 'url') {\n setIsLoadingFileSize(false)\n setCanSkipFileSizeValidation(false)\n setFileSize(null)\n const url = stagedUpload.url\n\n // Get file size from URL\n const fetchFileSize = async () => {\n setIsLoadingFileSize(true)\n try {\n const response = await fetch(url, {method: 'HEAD'})\n const contentLength = response.headers.get('content-length')\n const newFileSize = contentLength ? parseInt(contentLength, 10) : null\n\n setIsLoadingFileSize(false)\n if (newFileSize) {\n setFileSize(newFileSize)\n }\n if (newFileSize === null && maxFileSize !== undefined) {\n // Size unknown but size limit is configured - skip file size validation\n setCanSkipFileSizeValidation(true)\n }\n } catch {\n console.warn('Could not validate file size from URL')\n // Skip validation of file size, but still validate duration\n setCanSkipFileSizeValidation(true)\n setIsLoadingFileSize(false)\n }\n }\n\n fetchFileSize()\n }\n if (stagedUpload.type === 'file') {\n setFileSize(stagedUpload.files[0].size)\n }\n }, [maxFileSize, stagedUpload, stagedUpload.type])\n\n return {\n fileSize,\n isLoadingFileSize,\n canSkipFileSizeValidation,\n }\n}\n","import {useEffect, useState} from 'react'\n\nimport {StagedUpload} from '../components/Uploader'\n\nexport interface VideoAssetMetadata {\n width?: number\n height?: number\n isAudioOnly?: boolean\n duration?: number\n size?: number\n aspectRatio?: number\n}\n\nexport function useMediaMetadata(stagedUpload: StagedUpload) {\n const [videoAssetMetadata, setVideoAssetMetadata] = useState<VideoAssetMetadata | null>(null)\n const [isLoadingMetadata, setIsLoadingMetadata] = useState(false)\n useEffect(() => {\n let videoSrc = null\n // Validate file uploads\n if (stagedUpload.type === 'file') {\n const file = stagedUpload.files[0]\n videoSrc = URL.createObjectURL(file)\n }\n\n // Validate URL uploads\n if (stagedUpload.type === 'url') {\n videoSrc = stagedUpload.url\n }\n\n setVideoAssetMetadata((old) => ({\n ...old,\n duration: undefined,\n width: undefined,\n height: undefined,\n }))\n\n if (!videoSrc) return () => null\n\n setIsLoadingMetadata(true)\n const videoElement = document.createElement('video')\n videoElement.preload = 'metadata'\n\n const metadataListeners = [\n () => {\n setIsLoadingMetadata(false)\n },\n () => {\n const duration = videoElement.duration\n const width = videoElement.videoWidth\n const height = videoElement.videoHeight\n const isAudioOnly = width <= 0 && height <= 0\n const aspectRatio = width / height\n setVideoAssetMetadata((old) => {\n return {\n ...old,\n duration: duration,\n width: width,\n height: height,\n isAudioOnly: isAudioOnly,\n aspectRatio: aspectRatio,\n }\n })\n },\n ]\n\n const cleanupVideo = (videoEl: HTMLVideoElement) => {\n const currentVideoSrc = videoEl?.src\n if (videoEl) {\n metadataListeners.forEach((listener) =>\n videoEl.removeEventListener('loadedmetadata', listener)\n )\n videoEl.onerror = null\n videoEl.src = ''\n videoEl.load()\n }\n if (currentVideoSrc?.startsWith('blob:')) {\n URL.revokeObjectURL(currentVideoSrc)\n }\n }\n metadataListeners.push(() => setTimeout(() => cleanupVideo(videoElement), 0))\n\n videoElement.onerror = () => {\n setIsLoadingMetadata(false)\n console.warn('Could not read video metadata for validation')\n cleanupVideo(videoElement)\n }\n\n metadataListeners.forEach((listener) =>\n videoElement.addEventListener('loadedmetadata', listener)\n )\n videoElement.src = videoSrc\n\n return () => {\n cleanupVideo(videoElement)\n }\n }, [stagedUpload.type, stagedUpload])\n\n return {\n videoAssetMetadata,\n setVideoAssetMetadata,\n isLoadingMetadata,\n }\n}\n","import {roundPxString} from './roundPxString'\nimport type {MuxOverlaySettings, WatermarkConfig} from './types'\n\n/**\n * Converts a draggable watermark position (x, y percentages) to Mux's overlay_settings format.\n *\n * @param watermark - The watermark configuration with position, size, and opacity\n * @returns Mux overlay_settings object\n * @see {@link https://www.mux.com/docs/guides/add-watermarks-to-your-videos}\n */\nexport function convertWatermarkToMuxOverlay(\n watermark: WatermarkConfig,\n options?: {\n /**\n * Video aspect ratio (width / height). Needed for correct vertical positioning,\n * especially on vertical videos.\n */\n videoAspectRatio?: number\n /**\n * Unit to emit for margins/width when generating overlay_settings from Canvas mode.\n * - 'px' will generate pixel strings according to Mux's scaling rules:\n * values are applied as if the video were scaled to 1920x1080 (horizontal)\n * or 1080x1920 (vertical).\n * - '%' preserves existing behavior.\n */\n units?: '%' | 'px'\n }\n): MuxOverlaySettings | null {\n if (!watermark.enabled || !watermark.imageUrl) {\n return null\n }\n\n const size = watermark.size || 20\n const opacity = watermark.opacity ?? 0.7\n\n /**\n * Convert a percentage to whole-pixel string, using Mux's base dimensions:\n * - Horizontal video: 1920x1080\n * - Vertical video: 1080x1920\n */\n const toPxString = (valuePercent: number, axis: 'x' | 'y') => {\n const videoAspectRatio = options?.videoAspectRatio ?? 16 / 9\n const isVertical = videoAspectRatio > 0 && videoAspectRatio < 1\n const baseW = isVertical ? 1080 : 1920\n const baseH = isVertical ? 1920 : 1080\n const base = axis === 'x' ? baseW : baseH\n const px = (valuePercent / 100) * base\n let rounded = Math.round(px)\n // Avoid sending 0px (and JS -0); keep sign for negative margins.\n if (rounded === 0) rounded = px < 0 ? -1 : 1\n return `${rounded}px`\n }\n\n const normalizeToPixels = (value: string | undefined, axis: 'x' | 'y'): string | undefined => {\n if (!value) return value\n const trimmed = value.trim()\n if (trimmed.endsWith('px')) {\n return roundPxString(trimmed)\n }\n if (trimmed.endsWith('%')) {\n const n = Number(trimmed.slice(0, -1))\n if (!Number.isFinite(n)) return value\n return toPxString(n, axis)\n }\n return value\n }\n\n // If user provided explicit overlay settings, use them (Mux-documented format).\n // When `options.units === 'px'`, we normalize both % and px to whole-pixel strings,\n // honoring vertical vs horizontal video bases.\n if (watermark.overlay_settings) {\n const widthValue = watermark.overlay_settings.width\n const widthNormalized =\n options?.units === 'px' ? normalizeToPixels(widthValue, 'x') : widthValue\n return {\n ...watermark.overlay_settings,\n horizontal_margin:\n options?.units === 'px'\n ? (normalizeToPixels(watermark.overlay_settings.horizontal_margin, 'x') ??\n watermark.overlay_settings.horizontal_margin)\n : watermark.overlay_settings.horizontal_margin,\n vertical_margin:\n options?.units === 'px'\n ? (normalizeToPixels(watermark.overlay_settings.vertical_margin, 'y') ??\n watermark.overlay_settings.vertical_margin)\n : watermark.overlay_settings.vertical_margin,\n width: widthNormalized ?? `${size}%`,\n opacity: watermark.overlay_settings.opacity ?? `${Math.round(opacity * 100)}%`,\n }\n }\n\n const position = watermark.position || {x: 50, y: 50}\n\n /**\n * Our UI stores watermark position as the *center point* in percentages.\n * Mux margins are interpreted relative to an *edge* (based on align).\n *\n * To make \"corner\" placements match what the user dragged, we convert from\n * center-position to top-left margins by subtracting half the watermark size.\n *\n * Note: `size` is a percentage of video width. Mux `width` is also expressed\n * as a percentage of the video width, so we can reuse it for horizontal math.\n * For vertical math, we approximate using the same percentage to keep behavior\n * consistent with the current draggable UI (which also uses `size` in both axes\n * for bounds).\n */\n // Allow negative margins to compensate for rounding / letterboxing edge-cases.\n // We still clamp to a sane range so values don't explode.\n const clampPercent = (value: number) => Math.max(-100, Math.min(100, value))\n\n // Mux accepts percentage strings; avoid sending an exact \"0%\" by nudging to 0.01%.\n // This also handles the JS -0 edge case and tiny floating point remnants.\n const toPercentString = (value: number) => {\n const epsilon = 1e-9\n const isZeroish = value === 0 || Object.is(value, -0) || Math.abs(value) < epsilon\n return `${isZeroish ? 0.01 : value}%`\n }\n\n const watermarkWidthPercentOfVideoWidth = size\n\n /**\n * Convert watermark height into % of video height.\n * height% = (watermarkWidthPx / imageAspectRatio) / videoHeightPx\n * = (size% * videoWidthPx / imageAspectRatio) / videoHeightPx\n * = size% * (videoWidthPx/videoHeightPx) / imageAspectRatio\n * = size% * videoAspectRatio / imageAspectRatio\n */\n const videoAspectRatio = options?.videoAspectRatio ?? 16 / 9\n const imageAspectRatio = watermark.imageAspectRatio ?? 1\n const watermarkHeightPercentOfVideoHeight = Math.max(\n 0,\n Math.min(100, (size * videoAspectRatio) / imageAspectRatio)\n )\n\n const halfWidth = watermarkWidthPercentOfVideoWidth / 2\n const halfHeight = watermarkHeightPercentOfVideoHeight / 2\n\n const leftMargin = clampPercent(\n Math.min(position.x - halfWidth, 100 - watermarkWidthPercentOfVideoWidth)\n )\n const topMargin = clampPercent(\n Math.min(position.y - halfHeight, 100 - watermarkHeightPercentOfVideoHeight)\n )\n\n const units = options?.units ?? '%'\n const marginX = units === 'px' ? toPxString(leftMargin, 'x') : toPercentString(leftMargin)\n const marginY = units === 'px' ? toPxString(topMargin, 'y') : toPercentString(topMargin)\n const width = units === 'px' ? toPxString(size, 'x') : `${size}%`\n\n const overlaySettings: MuxOverlaySettings = {\n vertical_align: 'top',\n vertical_margin: marginY,\n horizontal_align: 'left',\n horizontal_margin: marginX,\n width,\n opacity: `${Math.round(opacity * 100)}%`,\n }\n\n return overlaySettings\n}\n","/* eslint-disable */\n// From: https://stackoverflow.com/questions/10420352/converting-file-size-in-bytes-to-human-readable-string\n/**\n * Format bytes as human-readable text.\n *\n * @param bytes Number of bytes.\n * @param si True to use metric (SI) units, aka powers of 1000. False to use\n * binary (IEC), aka powers of 1024.\n * @param dp Number of decimal places to display.\n *\n * @return Formatted string.\n */\nexport default function formatBytes(bytes: number, si = false, dp = 1) {\n const thresh = si ? 1000 : 1024\n\n if (Math.abs(bytes) < thresh) {\n return bytes + ' B'\n }\n\n const units = si\n ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']\n let u = -1\n const r = 10 ** dp\n\n do {\n bytes /= thresh\n ++u\n } while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1)\n\n return bytes.toFixed(dp) + ' ' + units[u]\n}\n","import {CheckmarkCircleIcon, ErrorOutlineIcon} from '@sanity/icons'\nimport {Box, Button, Card, Flex, Grid, Stack, Text, TextInput} from '@sanity/ui'\nimport {useCallback, useEffect, useRef, useState} from 'react'\nimport {styled} from 'styled-components'\n\nimport {convertWatermarkToMuxOverlay} from '../util/convertWatermarkToMux'\nimport type {MuxOverlaySettings, WatermarkConfig} from '../util/types'\n\nconst RangeInput = styled.input`\n width: 100%;\n height: 4px;\n border-radius: 2px;\n background: var(--card-border-color);\n outline: none;\n -webkit-appearance: none;\n appearance: none;\n\n &::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--card-focus-ring-color, #2276fc);\n cursor: pointer;\n border: 2px solid white;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n }\n\n &::-moz-range-thumb {\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--card-focus-ring-color, #2276fc);\n cursor: pointer;\n border: 2px solid white;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n }\n\n &:hover::-webkit-slider-thumb {\n background: var(--card-focus-ring-color, #1a5fc7);\n }\n\n &:hover::-moz-range-thumb {\n background: var(--card-focus-ring-color, #1a5fc7);\n }\n`\n\nconst WatermarkOverlay = styled.div<{$opacity: number}>`\n position: absolute;\n max-width: 200px;\n opacity: ${(props) => props.$opacity};\n cursor: move;\n user-select: none;\n z-index: 10;\n pointer-events: auto;\n\n img {\n width: 100%;\n height: auto;\n display: block;\n pointer-events: none;\n }\n\n &:hover {\n outline: 2px dashed rgba(255, 255, 255, 0.8);\n outline-offset: 4px;\n }\n`\n\ninterface DraggableWatermarkProps {\n watermark: WatermarkConfig\n onChange: (watermark: WatermarkConfig) => void\n containerRef?: React.RefObject<HTMLDivElement>\n videoElementRef?: React.RefObject<HTMLVideoElement>\n}\n\nexport default function DraggableWatermark({\n watermark,\n onChange,\n containerRef,\n videoElementRef,\n}: DraggableWatermarkProps) {\n const [isDragging, setIsDragging] = useState(false)\n const [dragStart, setDragStart] = useState({x: 0, y: 0})\n const [startPosition, setStartPosition] = useState({x: 0, y: 0})\n const watermarkRef = useRef<HTMLDivElement>(null)\n const debounceTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n const [localPosition, setLocalPosition] = useState(watermark.position || {x: 50, y: 50})\n\n const position = localPosition\n const size = watermark.size || 20\n const opacity = watermark.opacity ?? 0.7\n\n const parseOpacityPercent = (value: string | undefined): number | null => {\n if (!value) return null\n const trimmed = value.trim()\n if (!trimmed.endsWith('%')) return null\n const num = Number(trimmed.slice(0, -1))\n if (!Number.isFinite(num)) return null\n return Math.max(0, Math.min(1, num / 100))\n }\n\n const getVideoContentBox = useCallback(() => {\n const container = containerRef?.current\n if (!container) return {x: 0, y: 0, width: 0, height: 0}\n\n const rect = container.getBoundingClientRect()\n const containerW = rect.width\n const containerH = rect.height\n\n const videoEl = videoElementRef?.current\n const videoW = videoEl?.videoWidth || 0\n const videoH = videoEl?.videoHeight || 0\n\n if (!videoW || !videoH || !containerW || !containerH) {\n return {x: 0, y: 0, width: containerW, height: containerH}\n }\n\n // object-fit: contain sizing\n const scale = Math.min(containerW / videoW, containerH / videoH)\n const contentW = videoW * scale\n const contentH = videoH * scale\n const offsetX = (containerW - contentW) / 2\n const offsetY = (containerH - contentH) / 2\n\n return {x: offsetX, y: offsetY, width: contentW, height: contentH}\n }, [containerRef, videoElementRef])\n\n const parseOverlayValue = (value: string | undefined): {n: number; unit: '%' | 'px'} | null => {\n if (!value) return null\n const trimmed = value.trim()\n const px = trimmed.endsWith('px')\n const pct = trimmed.endsWith('%')\n const num = Number(trimmed.replace(/px|%/g, ''))\n if (!Number.isFinite(num)) return null\n if (px) return {n: num, unit: 'px'}\n if (pct) return {n: num, unit: '%'}\n return null\n }\n\n const computeManualStyle = (overlay: MuxOverlaySettings) => {\n const rect = containerRef?.current?.getBoundingClientRect()\n const w = rect?.width ?? 0\n const h = rect?.height ?? 0\n const isVertical = h > w\n const baseW = isVertical ? 1080 : 1920\n const baseH = isVertical ? 1920 : 1080\n\n const hm = parseOverlayValue(overlay.horizontal_margin)\n const vm = parseOverlayValue(overlay.vertical_margin)\n const ww = parseOverlayValue(overlay.width)\n const manualOpacity = parseOpacityPercent(overlay.opacity)\n\n const toCss = (v: {n: number; unit: '%' | 'px'} | null, axis: 'x' | 'y') => {\n if (!v) return undefined\n if (v.unit === '%') return `${v.n}%`\n if (axis === 'x') return `${(v.n * w) / baseW}px`\n return `${(v.n * h) / baseH}px`\n }\n\n const computeHorizontalStyle = () => {\n if (overlay.horizontal_align === 'left') {\n return {left: toCss(hm, 'x'), right: undefined, transform: 'translate(0, 0)'}\n }\n if (overlay.horizontal_align === 'right') {\n return {right: toCss(hm, 'x'), left: undefined, transform: 'translate(0, 0)'}\n }\n return {left: '50%', right: undefined, transform: 'translate(-50%, 0)'}\n }\n\n const computeVerticalStyle = () => {\n if (overlay.vertical_align === 'top') {\n return {top: toCss(vm, 'y'), bottom: undefined}\n }\n if (overlay.vertical_align === 'bottom') {\n return {bottom: toCss(vm, 'y'), top: undefined}\n }\n return {top: '50%', bottom: undefined}\n }\n\n const hStyle = computeHorizontalStyle()\n const vStyle = computeVerticalStyle()\n\n let transform = hStyle.transform\n if (overlay.vertical_align === 'middle') {\n transform =\n overlay.horizontal_align === 'center' ? 'translate(-50%, -50%)' : 'translate(0, -50%)'\n }\n\n return {\n position: 'absolute' as const,\n ...hStyle,\n ...vStyle,\n transform,\n width: ww ? toCss(ww, 'x') : `${size}%`,\n opacity: manualOpacity ?? opacity,\n cursor: 'default',\n }\n }\n\n const debouncedOnChange = useCallback(\n (newWatermark: WatermarkConfig) => {\n if (debounceTimeoutRef.current) {\n clearTimeout(debounceTimeoutRef.current)\n }\n debounceTimeoutRef.current = setTimeout(() => {\n onChange(newWatermark)\n }, 300)\n },\n [onChange]\n )\n\n useEffect(() => {\n return () => {\n if (debounceTimeoutRef.current) {\n clearTimeout(debounceTimeoutRef.current)\n }\n }\n }, [])\n\n useEffect(() => {\n if (!isDragging && watermark.position) {\n setLocalPosition(watermark.position)\n }\n }, [watermark.position, isDragging])\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault()\n setIsDragging(true)\n setDragStart({x: e.clientX, y: e.clientY})\n setStartPosition({x: position.x, y: position.y})\n },\n [position]\n )\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => {\n if (!isDragging || !containerRef?.current) return\n\n const container = containerRef.current\n const rect = container.getBoundingClientRect()\n const content = getVideoContentBox()\n const contentW = content.width || rect.width\n const contentH = content.height || rect.height\n const dx = e.clientX - dragStart.x\n const dy = e.clientY - dragStart.y\n\n const deltaXPercent = (dx / contentW) * 100\n const deltaYPercent = (dy / contentH) * 100\n\n let newX = startPosition.x + deltaXPercent\n let newY = startPosition.y + deltaYPercent\n\n newX = Math.max(0, Math.min(100, newX))\n newY = Math.max(0, Math.min(100, newY))\n\n setLocalPosition({x: newX, y: newY})\n\n debouncedOnChange({\n ...watermark,\n position: {x: newX, y: newY},\n })\n },\n [\n isDragging,\n dragStart,\n startPosition,\n containerRef,\n watermark,\n debouncedOnChange,\n getVideoContentBox,\n ]\n )\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false)\n if (debounceTimeoutRef.current) {\n clearTimeout(debounceTimeoutRef.current)\n debounceTimeoutRef.current = null\n }\n onChange({\n ...watermark,\n position: localPosition,\n })\n }, [watermark, localPosition, onChange])\n\n useEffect(() => {\n if (isDragging) {\n document.addEventListener('mousemove', handleMouseMove)\n document.addEventListener('mouseup', handleMouseUp)\n return () => {\n document.removeEventListener('mousemove', handleMouseMove)\n document.removeEventListener('mouseup', handleMouseUp)\n }\n }\n return undefined\n }, [isDragging, handleMouseMove, handleMouseUp])\n\n if (!watermark.imageUrl) {\n return null\n }\n\n const hasManualOverlay = Boolean(watermark.overlay_settings)\n const opacityForRender = hasManualOverlay\n ? (parseOpacityPercent(watermark.overlay_settings?.opacity) ?? opacity)\n : opacity\n const contentBox = getVideoContentBox()\n const hasContentBox = contentBox.width > 0 && contentBox.height > 0\n\n const computeWatermarkStyle = () => {\n if (hasManualOverlay) {\n return computeManualStyle(watermark.overlay_settings!)\n }\n if (hasContentBox) {\n return {\n left: `${contentBox.x + (position.x / 100) * contentBox.width}px`,\n top: `${contentBox.y + (position.y / 100) * contentBox.height}px`,\n transform: 'translate(-50%, -50%)',\n width: `${Math.max(1, (size / 100) * contentBox.width)}px`,\n cursor: isDragging ? 'grabbing' : 'grab',\n }\n }\n return {\n left: `${position.x}%`,\n top: `${position.y}%`,\n transform: 'translate(-50%, -50%)',\n width: `${size}%`,\n cursor: isDragging ? 'grabbing' : 'grab',\n }\n }\n\n return (\n <WatermarkOverlay\n ref={watermarkRef}\n $opacity={opacityForRender}\n onMouseDown={hasManualOverlay ? undefined : handleMouseDown}\n style={computeWatermarkStyle()}\n >\n <img src={watermark.imageUrl} alt=\"Watermark\" draggable={false} />\n </WatermarkOverlay>\n )\n}\n\ninterface WatermarkControlsProps {\n watermark: WatermarkConfig\n onChange: (watermark: WatermarkConfig) => void\n onValidationChange?: (error: string | null) => void\n previewContainerRef?: React.RefObject<HTMLDivElement | null>\n previewVideoRef?: React.RefObject<HTMLVideoElement | null>\n}\n\nexport function WatermarkControls({\n watermark,\n onChange,\n onValidationChange,\n previewContainerRef,\n previewVideoRef,\n}: WatermarkControlsProps) {\n const [urlInput, setUrlInput] = useState(watermark.imageUrl || '')\n const [urlError, setUrlError] = useState<string | null>(null)\n const [isValidating, setIsValidating] = useState(false)\n const [isValid, setIsValid] = useState<boolean | null>(null)\n const validationTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n const [mode, setMode] = useState<'canvas' | 'manual'>(\n watermark.overlay_settings ? 'manual' : 'canvas'\n )\n\n const isUpdatingRef = useRef(false)\n\n const isValidExtension = (extension: string) => {\n return extension.endsWith('.png') || extension.endsWith('.jpg') || extension.endsWith('.jpeg')\n }\n\n const validateUrl = useCallback(\n (url: string) => {\n if (validationTimeoutRef.current) {\n clearTimeout(validationTimeoutRef.current)\n }\n\n if (!url) {\n setUrlError(null)\n setIsValid(null)\n setIsValidating(false)\n onValidationChange?.(null)\n isUpdatingRef.current = true\n onChange({\n ...watermark,\n enabled: false,\n imageUrl: undefined,\n overlay_settings: undefined,\n })\n return\n }\n\n setIsValidating(true)\n setIsValid(null)\n setUrlError(null)\n\n validationTimeoutRef.current = setTimeout(() => {\n try {\n const urlObj = new URL(url)\n const pathname = urlObj.pathname.toLowerCase()\n if (isValidExtension(pathname)) {\n setIsValid(true)\n setUrlError(null)\n onValidationChange?.(null)\n const img = new Image()\n img.onload = () => {\n const imageAspectRatio =\n img.naturalWidth && img.naturalHeight ? img.naturalWidth / img.naturalHeight : 1\n isUpdatingRef.current = true\n onChange({\n ...watermark,\n enabled: true,\n imageUrl: url,\n imageAspectRatio,\n })\n }\n img.onerror = () => {\n isUpdatingRef.current = true\n onChange({\n ...watermark,\n enabled: true,\n imageUrl: url,\n imageAspectRatio: watermark.imageAspectRatio,\n })\n }\n img.src = url\n } else {\n const errorMsg =\n 'Mux only supports PNG and JPG watermark images. Please use a .png or .jpg file.'\n setIsValid(false)\n setUrlError(errorMsg)\n onValidationChange?.(errorMsg)\n isUpdatingRef.current = true\n onChange({\n ...watermark,\n enabled: false,\n imageUrl: undefined,\n imageAspectRatio: undefined,\n overlay_settings: undefined,\n })\n }\n } catch {\n setIsValid(false)\n const errorMsg = 'Please enter a valid URL (e.g., https://example.com/watermark.png)'\n setUrlError(errorMsg)\n onValidationChange?.(errorMsg)\n isUpdatingRef.current = true\n onChange({\n ...watermark,\n enabled: false,\n imageUrl: undefined,\n imageAspectRatio: undefined,\n overlay_settings: undefined,\n })\n } finally {\n setIsValidating(false)\n }\n }, 500)\n },\n [watermark, onChange, onValidationChange]\n )\n\n useEffect(() => {\n return () => {\n if (validationTimeoutRef.current) {\n clearTimeout(validationTimeoutRef.current)\n }\n }\n }, [])\n\n useEffect(() => {\n setMode(watermark.overlay_settings ? 'manual' : 'canvas')\n }, [watermark.overlay_settings])\n\n const handleUrlChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const url = e.target.value\n setUrlInput(url)\n\n if (watermark.imageUrl && url !== watermark.imageUrl) {\n isUpdatingRef.current = true\n onChange({\n ...watermark,\n enabled: false,\n imageUrl: undefined,\n imageAspectRatio: undefined,\n overlay_settings: undefined,\n })\n }\n\n validateUrl(url)\n }\n\n const normalizeZeroPercent = (value: string | undefined) => {\n if (!value) return value\n const trimmed = value.trim()\n if (!trimmed.endsWith('%')) return value\n const n = Number(trimmed.slice(0, -1))\n if (!Number.isFinite(n)) return value\n const epsilon = 1e-9\n if (n === 0 || Object.is(n, -0) || Math.abs(n) < epsilon) return '0.01%'\n return `${n}%`\n }\n\n const updateOverlaySettings = (next: Partial<MuxOverlaySettings>) => {\n const prev = watermark.overlay_settings\n const base: MuxOverlaySettings = prev ?? {\n vertical_align: 'bottom',\n vertical_margin: '2%',\n horizontal_align: 'right',\n horizontal_margin: '2%',\n width: `${watermark.size ?? 20}%`,\n opacity: `${Math.round((watermark.opacity ?? 0.7) * 100)}%`,\n }\n\n const merged: MuxOverlaySettings = {\n ...base,\n ...next,\n }\n\n onChange({\n ...watermark,\n enabled: true,\n overlay_settings: {\n ...merged,\n horizontal_margin:\n normalizeZeroPercent(merged.horizontal_margin) || merged.horizontal_margin,\n vertical_margin: normalizeZeroPercent(merged.vertical_margin) || merged.vertical_margin,\n },\n })\n }\n\n const getVideoContentBox = () => {\n const container = previewContainerRef?.current\n if (!container) return {x: 0, y: 0, width: 0, height: 0}\n\n const rect = container.getBoundingClientRect()\n const containerW = rect.width\n const containerH = rect.height\n\n const videoEl = previewVideoRef?.current\n const videoW = videoEl?.videoWidth || 0\n const videoH = videoEl?.videoHeight || 0\n\n if (!videoW || !videoH || !containerW || !containerH) {\n return {x: 0, y: 0, width: containerW, height: containerH}\n }\n\n const scale = Math.min(containerW / videoW, containerH / videoH)\n const contentW = videoW * scale\n const contentH = videoH * scale\n const offsetX = (containerW - contentW) / 2\n const offsetY = (containerH - contentH) / 2\n\n return {x: offsetX, y: offsetY, width: contentW, height: contentH}\n }\n\n return (\n <Stack space={3}>\n <Stack space={2}>\n <Text size={1} weight=\"medium\">\n Watermark Image URL\n </Text>\n <Text size={0} muted>\n Enter a URL to a PNG or JPG image. Mux will download this image and overlay it on your\n video.\n </Text>\n <Box style={{position: 'relative', width: '100%'}}>\n <input\n type=\"url\"\n value={urlInput}\n onChange={handleUrlChange}\n placeholder=\"https://example.com/watermark.png\"\n style={{\n padding: '8px 12px',\n paddingRight: (() => {\n if (urlInput) return '96px'\n if (isValid !== null) return '36px'\n return '12px'\n })(),\n border: (() => {\n if (urlError || isValid === false) return '1px solid #e74c3c'\n if (isValid === true) return '1px solid #4caf50'\n return '1px solid #ccc'\n })(),\n borderRadius: '4px',\n width: '100%',\n maxWidth: '100%',\n boxSizing: 'border-box',\n fontSize: '14px',\n }}\n />\n {(urlInput || isValidating || isValid !== null) && (\n <Box\n style={{\n position: 'absolute',\n right: '8px',\n top: '50%',\n transform: 'translateY(-50%)',\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n {urlInput && (\n <Button\n text=\"Clear\"\n mode=\"bleed\"\n tone=\"critical\"\n onClick={() => {\n setUrlInput('')\n validateUrl('')\n }}\n disabled={isValidating}\n style={{fontSize: '11px', height: '24px'}}\n />\n )}\n {isValidating && (\n <Text size={0} muted>\n Validating...\n </Text>\n )}\n {isValid === true && !isValidating && (\n <CheckmarkCircleIcon style={{color: '#4caf50', fontSize: '18px'}} />\n )}\n {isValid === false && !isValidating && (\n <ErrorOutlineIcon style={{color: '#e74c3c', fontSize: '18px'}} />\n )}\n </Box>\n )}\n </Box>\n {urlError && (\n <Card padding={2} tone=\"critical\" radius={2}>\n <Flex align=\"center\" gap={2}>\n <ErrorOutlineIcon style={{color: '#e74c3c', flexShrink: 0}} />\n <Text size={0} style={{color: '#e74c3c'}}>\n {urlError}\n </Text>\n </Flex>\n </Card>\n )}\n </Stack>\n\n {watermark.imageUrl && (\n <Stack space={2}>\n <Card padding={3} tone=\"transparent\" border radius={2}>\n <Flex\n align=\"center\"\n justify=\"space-between\"\n gap={3}\n style={{flexWrap: 'wrap', alignItems: 'flex-start'}}\n >\n <Stack space={2} style={{minWidth: 240, flex: 1}}>\n <Text size={1} weight=\"medium\">\n Positioning mode\n </Text>\n <Text size={0} muted>\n Choose between dragging on the canvas or manually editing the Mux{' '}\n <code>overlay_settings</code> fields (as in{' '}\n <a\n href=\"https://www.mux.com/docs/guides/add-watermarks-to-your-videos\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n the docs\n </a>\n ).\n </Text>\n </Stack>\n <Flex gap={2} style={{flexWrap: 'wrap'}}>\n <Button\n text=\"Canvas\"\n mode={mode === 'canvas' ? 'default' : 'ghost'}\n onClick={() => {\n setMode('canvas')\n onChange({...watermark, enabled: true, overlay_settings: undefined})\n }}\n />\n <Button\n text=\"Manual\"\n mode={mode === 'manual' ? 'default' : 'ghost'}\n onClick={() => {\n setMode('manual')\n const overlay = convertWatermarkToMuxOverlay({...watermark, enabled: true})\n updateOverlaySettings(overlay ?? {})\n }}\n />\n </Flex>\n </Flex>\n </Card>\n\n {mode === 'manual' && (\n <Card padding={3} tone=\"transparent\" border radius={2}>\n <Stack space={3}>\n <Text size={1} weight=\"medium\">\n Mux overlay_settings\n </Text>\n <Grid columns={[1, 2]} gap={3} style={{width: '100%'}}>\n <Stack space={2} style={{minWidth: 0}}>\n <Text size={0} muted>\n horizontal_align\n </Text>\n <select\n value={watermark.overlay_settings?.horizontal_align || 'right'}\n onChange={(e) =>\n updateOverlaySettings({\n horizontal_align: (e.target.value ||\n 'right') as MuxOverlaySettings['horizontal_align'],\n })\n }\n style={{\n width: '100%',\n padding: '8px 10px',\n border: '1px solid #ccc',\n borderRadius: 4,\n }}\n >\n <option value=\"left\">left</option>\n <option value=\"center\">center</option>\n <option value=\"right\">right</option>\n </select>\n </Stack>\n <Stack space={2} style={{minWidth: 0}}>\n <Text size={0} muted>\n horizontal_margin (e.g. 2% or 40px)\n </Text>\n <TextInput\n value={watermark.overlay_settings?.horizontal_margin || '2%'}\n onChange={(e) =>\n updateOverlaySettings({horizontal_margin: e.currentTarget.value})\n }\n />\n </Stack>\n <Stack space={2} style={{minWidth: 0}}>\n <Text size={0} muted>\n vertical_align\n </Text>\n <select\n value={watermark.overlay_settings?.vertical_align || 'bottom'}\n onChange={(e) =>\n updateOverlaySettings({\n vertical_align: (e.target.value ||\n 'bottom') as MuxOverlaySettings['vertical_align'],\n })\n }\n style={{\n width: '100%',\n padding: '8px 10px',\n border: '1px solid #ccc',\n borderRadius: 4,\n }}\n >\n <option value=\"top\">top</option>\n <option value=\"middle\">middle</option>\n <option value=\"bottom\">bottom</option>\n </select>\n </Stack>\n <Stack space={2} style={{minWidth: 0}}>\n <Text size={0} muted>\n vertical_margin (e.g. 2% or 40px)\n </Text>\n <TextInput\n value={watermark.overlay_settings?.vertical_margin || '2%'}\n onChange={(e) =>\n updateOverlaySettings({vertical_margin: e.currentTarget.value})\n }\n />\n </Stack>\n <Stack space={2} style={{minWidth: 0}}>\n <Text size={0} muted>\n width (e.g. 25% or 80px)\n </Text>\n <TextInput\n value={watermark.overlay_settings?.width || `${watermark.size ?? 20}%`}\n onChange={(e) => updateOverlaySettings({width: e.currentTarget.value})}\n />\n </Stack>\n <Stack space={2} style={{minWidth: 0}}>\n <Text size={0} muted>\n opacity (e.g. 90%)\n </Text>\n <TextInput\n value={\n watermark.overlay_settings?.opacity ||\n `${Math.round((watermark.opacity ?? 0.7) * 100)}%`\n }\n onChange={(e) => updateOverlaySettings({opacity: e.currentTarget.value})}\n />\n </Stack>\n </Grid>\n <Text size={0} muted>\n Margins and width accept either percentages or pixels, per the Mux guide.\n </Text>\n </Stack>\n </Card>\n )}\n\n {mode === 'canvas' && (\n <>\n <Box>\n <Text size={1} weight=\"medium\">\n {(() => {\n const sizePct = watermark.size || 20\n const contentW = getVideoContentBox().width\n if (!contentW) return `Size: ${sizePct}%`\n const px = Math.max(1, Math.round((sizePct / 100) * contentW))\n return `Size: ${px}px`\n })()}\n </Text>\n <RangeInput\n type=\"range\"\n value={(() => {\n const sizePct = watermark.size || 20\n const contentW = getVideoContentBox().width\n if (!contentW) return sizePct\n return Math.max(1, Math.round((sizePct / 100) * contentW))\n })()}\n min={(() => {\n const contentW = getVideoContentBox().width\n if (!contentW) return 5\n return Math.max(1, Math.round(contentW * 0.05))\n })()}\n max={(() => {\n const contentW = getVideoContentBox().width\n if (!contentW) return 50\n return Math.max(1, Math.round(contentW * 0.5))\n })()}\n step={1}\n onChange={(e) => {\n const raw = Number(e.target.value)\n const contentW = getVideoContentBox().width\n const nextPct = contentW ? (raw / contentW) * 100 : raw\n const clampedPct = Math.max(5, Math.min(50, nextPct))\n onChange({\n ...watermark,\n size: clampedPct,\n })\n }}\n />\n </Box>\n\n <Box>\n <Text size={1} weight=\"medium\">\n Opacity: {Math.round((watermark.opacity ?? 0.7) * 100)}%\n </Text>\n <RangeInput\n type=\"range\"\n value={watermark.opacity ?? 0.7}\n min={0}\n max={1}\n step={0.05}\n onChange={(e) =>\n onChange({\n ...watermark,\n opacity: Number(e.target.value),\n })\n }\n />\n </Box>\n </>\n )}\n\n <Card padding={2} tone=\"transparent\" border radius={2}>\n <Text size={0} muted>\n {mode === 'manual'\n ? 'Manual mode: edit the overlay_settings fields above'\n : '💡 Drag the watermark on the preview to position it'}\n </Text>\n </Card>\n </Stack>\n )}\n </Stack>\n )\n}\n","import {TranslateIcon} from '@sanity/icons'\nimport {Autocomplete, Box, Card, Checkbox, Flex, Stack, Text} from '@sanity/ui'\nimport {uuid} from '@sanity/uuid'\nimport LanguagesList from 'iso-639-1'\nimport {Dispatch} from 'react'\nimport {FormField} from 'sanity'\n\nimport {type PluginConfig, SUPPORTED_MUX_LANGUAGES, UploadTextTrack} from '../util/types'\n\nconst ALL_LANGUAGE_CODES = LanguagesList.getAllCodes().map((code) => ({\n value: code,\n label: LanguagesList.getNativeName(code),\n}))\n\nconst SUBTITLE_LANGUAGES: Record<\n Extract<UploadTextTrack, {language_code: any}>['type'],\n {value: string; label: string}[]\n> = {\n autogenerated: SUPPORTED_MUX_LANGUAGES.map((lang) => ({\n value: lang.code,\n label: lang.label,\n })),\n subtitles: ALL_LANGUAGE_CODES,\n captions: ALL_LANGUAGE_CODES,\n}\n\ntype TrackSubAction =\n | {subAction: 'add'; value: Partial<UploadTextTrack>}\n | {subAction: 'update'; value: Partial<UploadTextTrack>}\n | {subAction: 'delete'}\n\nexport type TrackAction = {action: 'track'; id: string} & TrackSubAction\n\nexport default function TextTracksEditor({\n tracks,\n dispatch,\n defaultLang,\n}: {\n /**\n * Although the schema for tracks is an array, which we'll eventually support to allow uploading\n * multiple custom subtitles, for now we only support a single auto-generated track.\n */\n tracks: (Partial<UploadTextTrack> & {_id: string})[]\n dispatch: Dispatch<TrackAction>\n defaultLang: PluginConfig['defaultAutogeneratedSubtitleLang']\n}) {\n const track = tracks[0]\n return (\n <FormField title=\"Auto-generated subtitle or caption\">\n <Stack space={2}>\n <Flex align=\"center\">\n <Checkbox\n id=\"include-autogenerated-track\"\n style={{display: 'block'}}\n checked={!!track?.language_code}\n onChange={() => {\n if (track) {\n dispatch({action: 'track', id: track._id, subAction: 'delete'})\n } else {\n dispatch({\n action: 'track',\n id: uuid(),\n subAction: 'add',\n value: {\n type: 'autogenerated',\n name: defaultLang || undefined,\n language_code: defaultLang || undefined,\n },\n })\n }\n }}\n />\n <Box flex={1} paddingLeft={3}>\n <Text>\n <label htmlFor=\"checkbox\">Generate captions</label>\n </Text>\n </Box>\n </Flex>\n {track && (\n <Autocomplete\n id={`text-tract-editor--language`}\n value={track.language_code}\n onChange={(newValue) =>\n dispatch({\n action: 'track',\n id: track._id,\n subAction: 'update',\n value: {\n language_code: newValue,\n name: LanguagesList.getNativeName(newValue),\n },\n })\n }\n options={SUBTITLE_LANGUAGES[track.type!]}\n icon={TranslateIcon}\n placeholder=\"Select language\"\n filterOption={(query, option) =>\n option.label.toLowerCase().indexOf(query.toLowerCase()) > -1 ||\n option.value.toLowerCase().indexOf(query.toLowerCase()) > -1\n }\n openButton\n renderValue={(value) =>\n SUBTITLE_LANGUAGES[track.type!].find((l) => l.value === value)?.label || value\n }\n renderOption={(option) => (\n <Card data-as=\"button\" padding={3} radius={2} tone=\"inherit\">\n <Text size={2} textOverflow=\"ellipsis\">\n {option.label} ({option.value})\n </Text>\n </Card>\n )}\n />\n )}\n </Stack>\n </FormField>\n )\n}\n","import {Checkbox, Flex, Grid, Text} from '@sanity/ui'\nimport {ActionDispatch, CSSProperties, ReactNode, useState} from 'react'\n\nimport {UploadConfigurationStateAction} from '../UploadConfiguration'\n\nexport default function PlaybackPolicyOption({\n id,\n checked,\n optionName,\n description,\n dispatch,\n action,\n disabled,\n}: {\n id: string\n checked: boolean\n optionName: string\n description: string | ReactNode\n dispatch: ActionDispatch<[action: UploadConfigurationStateAction]>\n action?: 'public_policy' | 'signed_policy' | 'drm_policy'\n disabled?: boolean\n}) {\n const [scale, setScale] = useState(1)\n\n const boxStyle: CSSProperties = {\n outline: '0.01rem solid grey',\n transform: `scale(${scale})`,\n transition: 'transform 0.1s ease-in-out',\n cursor: disabled ? 'not-allowed' : 'pointer',\n borderRadius: '0.25rem',\n }\n\n const triggerAnimation = () => {\n setScale(0.98)\n setTimeout(() => {\n setScale(1)\n }, 100)\n }\n\n const handleBoxClick = () => {\n if (!action) return\n triggerAnimation()\n dispatch({\n action,\n value: !checked,\n })\n }\n\n const descriptionJsx =\n typeof description === 'string' ? (\n <Text size={2} muted>\n {description}\n </Text>\n ) : (\n description\n )\n return (\n <label>\n <Flex gap={3} padding={3} style={boxStyle}>\n <Checkbox\n id={id}\n required\n checked={checked}\n onChange={handleBoxClick}\n disabled={disabled}\n />\n <Grid gap={3}>\n <Text size={3} weight=\"bold\">\n {optionName}\n </Text>\n {descriptionJsx}\n </Grid>\n </Flex>\n </label>\n )\n}\n","import {WarningFilledIcon} from '@sanity/icons'\nimport {Box, Flex, Text} from '@sanity/ui'\nimport {CSSProperties} from 'react'\n\nexport default function PlaybackPolicyWarning() {\n const textStyle: CSSProperties = {\n color: '#13141A',\n fontWeight: 500,\n }\n\n const boxStyle: CSSProperties = {\n outline: '0.01rem solid grey',\n backgroundColor: '#979cb0',\n borderRadius: '0.5rem',\n width: 'max-content',\n color: '#13141A',\n }\n\n return (\n <Box padding={2} style={boxStyle}>\n <Flex align=\"center\" gap={2}>\n <WarningFilledIcon />\n <Text size={1} style={textStyle}>\n Please select at least one Playback Policy\n </Text>\n </Flex>\n </Box>\n )\n}\n","import {Code, Grid, Text} from '@sanity/ui'\nimport {ActionDispatch} from 'react'\n\nimport {Secrets, UploadConfig} from '../../util/types'\nimport {UploadConfigurationStateAction} from '../UploadConfiguration'\nimport PlaybackPolicyOption from './PlaybackPolicyOption'\nimport PlaybackPolicyWarning from './PlaybackPolicyWarning'\n\nexport default function PlaybackPolicy({\n id,\n config,\n secrets,\n dispatch,\n}: {\n id: string\n config: UploadConfig\n secrets: Secrets\n dispatch: ActionDispatch<[action: UploadConfigurationStateAction]>\n}) {\n const noPolicySelected = !(config.public_policy || config.signed_policy || config.drm_policy)\n const drmPolicyDisabled = !secrets.drmConfigId\n return (\n <Grid gap={3}>\n <Text weight=\"bold\">Advanced Playback Policies</Text>\n <PlaybackPolicyOption\n id={`${id}--public`}\n checked={config.public_policy}\n optionName=\"Public\"\n description={\n <>\n <Text size={2} muted>\n Playback IDs are accessible by constructing an HLS URL like\n </Text>\n <Code>{'https://stream.mux.com/{PLAYBACK_ID}'}</Code>\n </>\n }\n dispatch={dispatch}\n action=\"public_policy\"\n />\n {secrets.enableSignedUrls && (\n <PlaybackPolicyOption\n id={`${id}--signed`}\n checked={config.signed_policy}\n optionName=\"Signed\"\n description={\n <>\n <Text size={2} muted>\n Playback IDs should be used with tokens\n </Text>\n <Code>{'https://stream.mux.com/{PLAYBACK_ID}?token={TOKEN}'}</Code>\n <Text size={2} muted>\n See{' '}\n <a\n href=\"https://www.mux.com/docs/guides/secure-video-playback\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Secure video playback\n </a>{' '}\n for details about creating tokens.\n </Text>\n </>\n }\n // See Secure video playback for details about creating tokens.\"\n dispatch={dispatch}\n action=\"signed_policy\"\n />\n )}\n {drmPolicyDisabled ? (\n <PlaybackPolicyOption\n id={`${id}--drm`}\n checked={false}\n optionName=\"DRM - Disabled\"\n description={\n <>\n <Text size={2} muted>\n To enable DRM add your DRM Configuration Id to your plugin configuration in the API\n Credentials view.{' '}\n <a\n href=\"https://www.mux.com/support/human\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Contact us\n </a>{' '}\n to get started using DRM.\n </Text>\n </>\n }\n dispatch={dispatch}\n disabled\n />\n ) : (\n <PlaybackPolicyOption\n id={`${id}--drm`}\n checked={config.drm_policy}\n optionName=\"DRM\"\n description={\n <>\n <Text size={2} muted>\n Playback IDs should be used with tokens as with Signed playback, but require extra\n configuration.\n </Text>\n <Code>{'https://stream.mux.com/{PLAYBACK_ID}?token={TOKEN}'}</Code>\n <Text size={2} muted>\n See{' '}\n <a\n href=\"https://www.mux.com/docs/guides/protect-videos-with-drm#play-drm-protected-videos\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Protect videos with DRM\n </a>{' '}\n for details about configuring your player for DRM playback and{' '}\n <a\n href=\"https://www.mux.com/docs/guides/secure-video-playback\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Secure video playback\n </a>{' '}\n for details about creating tokens.\n </Text>\n </>\n }\n dispatch={dispatch}\n action=\"drm_policy\"\n />\n )}\n {noPolicySelected && <PlaybackPolicyWarning />}\n </Grid>\n )\n}\n","import {Flex, Radio, Text} from '@sanity/ui'\nimport {ActionDispatch} from 'react'\nimport {FormField} from 'sanity'\n\nimport {type UploadConfig} from '../../util/types'\nimport {UploadConfigurationStateAction} from '../UploadConfiguration'\n\nexport const RESOLUTION_TIERS = [\n {value: '1080p', label: '1080p'},\n {value: '1440p', label: '1440p (2k)'},\n {value: '2160p', label: '2160p (4k)'},\n] as const satisfies {value: UploadConfig['max_resolution_tier']; label: string}[]\n\nexport const ResolutionTierSelector = ({\n id,\n config,\n dispatch,\n maxSupportedResolution,\n}: {\n id: string\n config: UploadConfig\n dispatch: ActionDispatch<[action: UploadConfigurationStateAction]>\n maxSupportedResolution: number\n}) => {\n return (\n <FormField\n title=\"Resolution Tier\"\n description={\n <>\n The maximum{' '}\n <a\n href=\"https://docs.mux.com/api-reference#video/operation/create-direct-upload\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n resolution_tier\n </a>{' '}\n your asset is encoded, stored, and streamed at.\n </>\n }\n >\n <Flex gap={3} wrap={'wrap'}>\n {RESOLUTION_TIERS.map(({value, label}, index) => {\n const inputId = `${id}--type-${value}`\n\n if (index > maxSupportedResolution) return null\n\n return (\n <Flex key={value} align=\"center\" gap={2}>\n <Radio\n checked={config.max_resolution_tier === value}\n name=\"asset-resolutiontier\"\n onChange={(e) =>\n dispatch({\n action: 'max_resolution_tier',\n value: e.currentTarget.value as UploadConfig['max_resolution_tier'],\n })\n }\n value={value}\n id={inputId}\n />\n <Text as=\"label\" htmlFor={inputId}>\n {label}\n </Text>\n </Flex>\n )\n })}\n </Flex>\n </FormField>\n )\n}\n","import {Checkbox, Flex, Label, Radio, Stack, Text} from '@sanity/ui'\nimport {ActionDispatch, useMemo, useState} from 'react'\nimport {FormField} from 'sanity'\n\nimport {type StaticRenditionResolution, type UploadConfig} from '../../util/types'\nimport {UploadConfigurationStateAction} from '../UploadConfiguration'\n\nconst ADVANCED_RESOLUTIONS: {value: StaticRenditionResolution; label: string}[] = [\n {value: '270p', label: '270p'},\n {value: '360p', label: '360p'},\n {value: '480p', label: '480p'},\n {value: '540p', label: '540p'},\n {value: '720p', label: '720p'},\n {value: '1080p', label: '1080p'},\n {value: '1440p', label: '1440p'},\n {value: '2160p', label: '2160p'},\n]\n\nexport const StaticRenditionSelector = ({\n id,\n config,\n dispatch,\n}: {\n id: string\n config: UploadConfig\n dispatch: ActionDispatch<[action: UploadConfigurationStateAction]>\n}) => {\n // Determine if user is in advanced mode based on selected renditions\n const isAdvancedMode = useMemo(() => {\n const specificResolutions = config.static_renditions.filter(\n (r) => r !== 'highest' && r !== 'audio-only'\n )\n return specificResolutions.length > 0\n }, [config.static_renditions])\n\n const [renditionMode, setRenditionMode] = useState<'standard' | 'advanced'>(\n isAdvancedMode ? 'advanced' : 'standard'\n )\n\n // Helper to toggle a rendition\n const toggleRendition = (rendition: StaticRenditionResolution) => {\n const current = config.static_renditions\n const hasRendition = current.includes(rendition)\n\n if (hasRendition) {\n dispatch({\n action: 'static_renditions',\n value: current.filter((r) => r !== rendition),\n })\n } else {\n dispatch({\n action: 'static_renditions',\n value: [...current, rendition],\n })\n }\n }\n\n // When switching modes, clear renditions that don't apply\n const handleModeChange = (mode: 'standard' | 'advanced') => {\n setRenditionMode(mode)\n if (mode === 'standard') {\n // Remove specific resolutions, keep only highest and audio-only\n dispatch({\n action: 'static_renditions',\n value: config.static_renditions.filter((r) => r === 'highest' || r === 'audio-only'),\n })\n } else {\n // Remove highest, keep specific resolutions and audio-only\n dispatch({\n action: 'static_renditions',\n value: config.static_renditions.filter((r) => r !== 'highest'),\n })\n }\n }\n return (\n <Stack space={3}>\n <FormField\n title=\"Static Renditions\"\n description=\"Generate downloadable MP4 or M4A files. Note: Mux will not upscale to produce MP4 renditions - renditions that would cause upscaling are skipped.\"\n >\n <Stack space={3}>\n {/* Mode Selector */}\n <Flex gap={3}>\n <Flex align=\"center\" gap={2}>\n <Radio\n checked={renditionMode === 'standard'}\n name=\"rendition-mode\"\n onChange={() => handleModeChange('standard')}\n value=\"standard\"\n id={`${id}--mode-standard`}\n />\n <Text as=\"label\" htmlFor={`${id}--mode-standard`}>\n Standard\n </Text>\n </Flex>\n <Flex align=\"center\" gap={2}>\n <Radio\n checked={renditionMode === 'advanced'}\n name=\"rendition-mode\"\n onChange={() => handleModeChange('advanced')}\n value=\"advanced\"\n id={`${id}--mode-advanced`}\n />\n <Text as=\"label\" htmlFor={`${id}--mode-advanced`}>\n Advanced\n </Text>\n </Flex>\n </Flex>\n\n {/* Standard Mode Options */}\n {renditionMode === 'standard' && (\n <Stack space={2}>\n <Flex align=\"center\" gap={2} padding={[0, 2]}>\n <Checkbox\n id={`${id}--highest`}\n style={{display: 'block'}}\n checked={config.static_renditions.includes('highest')}\n onChange={() => toggleRendition('highest')}\n />\n <Text as=\"label\" htmlFor={`${id}--highest`}>\n Highest Resolution (up to 4K)\n </Text>\n </Flex>\n <Flex align=\"center\" gap={2} padding={[0, 2]}>\n <Checkbox\n id={`${id}--audio-only-standard`}\n style={{display: 'block'}}\n checked={config.static_renditions.includes('audio-only')}\n onChange={() => toggleRendition('audio-only')}\n />\n <Text as=\"label\" htmlFor={`${id}--audio-only-standard`}>\n Audio Only (M4A)\n </Text>\n </Flex>\n </Stack>\n )}\n\n {/* Advanced Mode Options */}\n {renditionMode === 'advanced' && (\n <Stack space={2}>\n <Label size={1} muted>\n Select specific resolutions:\n </Label>\n <Flex gap={2} wrap=\"wrap\">\n {ADVANCED_RESOLUTIONS.map(({value, label}) => {\n const inputId = `${id}--resolution-${value}`\n return (\n <Flex key={value} align=\"center\" gap={2}>\n <Checkbox\n id={inputId}\n style={{display: 'block'}}\n checked={config.static_renditions.includes(value)}\n onChange={() => toggleRendition(value)}\n />\n <Text as=\"label\" htmlFor={inputId} size={1}>\n {label}\n </Text>\n </Flex>\n )\n })}\n </Flex>\n <Flex align=\"center\" gap={2} padding={[2, 2, 0, 2]}>\n <Checkbox\n id={`${id}--audio-only-advanced`}\n style={{display: 'block'}}\n checked={config.static_renditions.includes('audio-only')}\n onChange={() => toggleRendition('audio-only')}\n />\n <Text as=\"label\" htmlFor={`${id}--audio-only-advanced`}>\n Audio Only (M4A)\n </Text>\n </Flex>\n </Stack>\n )}\n </Stack>\n </FormField>\n </Stack>\n )\n}\n","import {DocumentVideoIcon, ErrorOutlineIcon, UploadIcon} from '@sanity/icons'\nimport {Box, Button, Card, Dialog, Flex, Label, Radio, Stack, Text} from '@sanity/ui'\nimport {uuid} from '@sanity/uuid'\nimport LanguagesList from 'iso-639-1'\nimport {memo, useEffect, useId, useReducer, useRef, useState} from 'react'\nimport {FormField} from 'sanity'\n\nimport {useFetchFileSize} from '../hooks/useFetchFileSize'\nimport {useMediaMetadata, type VideoAssetMetadata} from '../hooks/useMediaMetadata'\nimport {convertWatermarkToMuxOverlay} from '../util/convertWatermarkToMux'\nimport formatBytes from '../util/formatBytes'\nimport {formatSeconds} from '../util/formatSeconds'\nimport {\n type AutogeneratedTextTrack,\n type CustomTextTrack,\n isAutogeneratedTrack,\n isCustomTextTrack,\n type MuxNewAssetSettings,\n type PluginConfig,\n type Secrets,\n type StaticRenditionResolution,\n type SupportedMuxLanguage,\n type UploadConfig,\n type UploadTextTrack,\n WatermarkConfig,\n} from '../util/types'\nimport DraggableWatermark, {WatermarkControls} from './DraggableWatermark'\nimport TextTracksEditor, {type TrackAction} from './TextTracksEditor'\nimport PlaybackPolicy from './uploadConfiguration/PlaybackPolicy'\nimport {\n RESOLUTION_TIERS,\n ResolutionTierSelector,\n} from './uploadConfiguration/ResolutionTierSelector'\nimport {StaticRenditionSelector} from './uploadConfiguration/StaticRenditionSelector'\nimport type {StagedUpload} from './Uploader'\n\nexport type UploadConfigurationStateAction =\n | {action: 'video_quality'; value: UploadConfig['video_quality']}\n | {action: 'max_resolution_tier'; value: UploadConfig['max_resolution_tier']}\n | {action: 'static_renditions'; value: UploadConfig['static_renditions']}\n | {action: 'normalize_audio'; value: UploadConfig['normalize_audio']}\n | {action: 'signed_policy'; value: UploadConfig['signed_policy']}\n | {action: 'public_policy'; value: UploadConfig['public_policy']}\n | {action: 'drm_policy'; value: UploadConfig['drm_policy']}\n | {action: 'watermark'; value: WatermarkConfig}\n | TrackAction\n\nconst VIDEO_QUALITY_LEVELS = [\n {value: 'basic', label: 'Basic'},\n {value: 'plus', label: 'Plus'},\n {value: 'premium', label: 'Premium'},\n] as const satisfies {value: UploadConfig['video_quality']; label: string}[]\n\n/**\n * Sanitizes static renditions configuration to ensure 'highest' is not mixed with specific resolutions.\n * If both are present, only 'highest' (and 'audio-only' if present) will be kept.\n */\nfunction sanitizeStaticRenditions(\n renditions: StaticRenditionResolution[]\n): StaticRenditionResolution[] {\n const hasHighest = renditions.includes('highest')\n const hasSpecificResolutions = renditions.some((r) => r !== 'highest' && r !== 'audio-only')\n\n if (hasHighest && hasSpecificResolutions) {\n return renditions.filter((r) => r === 'highest' || r === 'audio-only')\n }\n\n return renditions\n}\n\n/**\n * The modal for configuring a staged upload. Handles triggering of the asset\n * upload, even if no modal needs to be shown.\n *\n * @returns\n */\nexport default function UploadConfiguration({\n stagedUpload,\n secrets,\n pluginConfig,\n startUpload,\n onClose,\n}: {\n stagedUpload: StagedUpload\n secrets: Secrets\n pluginConfig: PluginConfig\n startUpload: (settings: MuxNewAssetSettings, watermark: WatermarkConfig | undefined) => void\n onClose: () => void\n}) {\n const id = useId()\n const [watermarkValidationError, setWatermarkValidationError] = useState<string | null>(null)\n const watermarkPreviewContainerRef = useRef<HTMLDivElement>(null)\n const watermarkPreviewVideoRef = useRef<HTMLVideoElement>(null)\n const autoTextTracks = useRef<NonNullable<UploadConfig['text_tracks']>>(\n pluginConfig.video_quality === 'plus' && pluginConfig.defaultAutogeneratedSubtitleLang\n ? [\n {\n _id: uuid(),\n type: 'autogenerated',\n language_code: pluginConfig.defaultAutogeneratedSubtitleLang,\n name: LanguagesList.getNativeName(pluginConfig.defaultAutogeneratedSubtitleLang),\n } satisfies AutogeneratedTextTrack,\n ]\n : []\n ).current\n\n const [config, dispatch] = useReducer(\n (prev: UploadConfig, action: UploadConfigurationStateAction) => {\n switch (action.action) {\n case 'video_quality':\n // If video quality level switches to basic, remove plus-only features\n if (action.value === 'basic') {\n return Object.assign({}, prev, {\n video_quality: action.value,\n static_renditions: [],\n max_resolution_tier: '1080p',\n text_tracks: prev.text_tracks?.filter(({type}) => type !== 'autogenerated'),\n public_policy: true,\n signed_policy: false,\n drm_policy: false,\n })\n // If video quality level switches to plus, add back in default plus features\n }\n return Object.assign({}, prev, {\n video_quality: action.value,\n static_renditions: sanitizeStaticRenditions(pluginConfig.static_renditions || []),\n max_resolution_tier: pluginConfig.max_resolution_tier,\n text_tracks: [...autoTextTracks, ...(prev.text_tracks || [])],\n })\n\n case 'static_renditions':\n case 'max_resolution_tier':\n case 'normalize_audio':\n case 'signed_policy':\n return Object.assign({}, prev, {[action.action]: action.value})\n case 'public_policy':\n return Object.assign({}, prev, {[action.action]: action.value})\n case 'drm_policy':\n return Object.assign({}, prev, {[action.action]: action.value})\n case 'watermark':\n return Object.assign({}, prev, {watermark: action.value})\n // Updating individual tracks\n case 'track': {\n const text_tracks = [...prev.text_tracks]\n const target_track_i = text_tracks.findIndex(({_id}) => _id === action.id)\n // eslint-disable-next-line default-case\n switch (action.subAction) {\n case 'add':\n // Exit early if track already exists\n if (target_track_i !== -1) break\n text_tracks.push({\n _id: action.id,\n ...action.value,\n } as AutogeneratedTextTrack)\n break\n case 'update':\n if (target_track_i === -1) break\n text_tracks[target_track_i] = {\n ...text_tracks[target_track_i],\n ...action.value,\n } as UploadTextTrack\n break\n case 'delete':\n if (target_track_i === -1) break\n text_tracks.splice(target_track_i, 1)\n break\n }\n return Object.assign({}, prev, {text_tracks})\n }\n default:\n return prev\n }\n },\n {\n video_quality: pluginConfig.video_quality,\n max_resolution_tier: pluginConfig.max_resolution_tier,\n static_renditions: sanitizeStaticRenditions(pluginConfig.static_renditions || []),\n signed_policy: secrets.enableSignedUrls && pluginConfig.defaultSigned,\n public_policy: pluginConfig.defaultPublic,\n drm_policy: pluginConfig.defaultDrm && !!secrets.drmConfigId,\n normalize_audio: pluginConfig.normalize_audio,\n text_tracks: autoTextTracks,\n } as UploadConfig\n )\n\n // Video validations\n const [validationError, setValidationError] = useState<string | null>(null)\n const MAX_FILE_SIZE = pluginConfig.maxAssetFileSize\n const MAX_DURATION_SECONDS = pluginConfig.maxAssetDuration\n\n const {fileSize, isLoadingFileSize, canSkipFileSizeValidation} = useFetchFileSize(\n stagedUpload,\n MAX_FILE_SIZE\n )\n const {videoAssetMetadata, setVideoAssetMetadata, isLoadingMetadata} =\n useMediaMetadata(stagedUpload)\n\n useEffect(() => {\n if (fileSize) {\n setVideoAssetMetadata((old) => ({...old, size: fileSize}))\n }\n }, [fileSize, setVideoAssetMetadata])\n\n useEffect(() => {\n const validateDuration = (duration: number) => {\n if (MAX_DURATION_SECONDS && duration > MAX_DURATION_SECONDS) {\n setValidationError(\n `Video duration (${formatSeconds(duration)}) exceeds maximum allowed duration of ${formatSeconds(MAX_DURATION_SECONDS)}`\n )\n return false\n }\n return true\n }\n\n const validateFileSize = (size: number): boolean => {\n if (MAX_FILE_SIZE === undefined || size <= MAX_FILE_SIZE) {\n return true\n }\n\n setValidationError(\n `File size (${formatBytes(size)}) exceeds maximum allowed size of ${formatBytes(MAX_FILE_SIZE)}`\n )\n return false\n }\n\n const validateDrmAvailability = (isAudioOnly: boolean) => {\n if (config.drm_policy && isAudioOnly) {\n setValidationError('Audio-only asset cannot be DRM protected')\n return false\n }\n return true\n }\n\n let valid = true\n if (videoAssetMetadata?.size) {\n valid = valid && (canSkipFileSizeValidation || validateFileSize(videoAssetMetadata.size))\n }\n if (videoAssetMetadata?.duration) {\n valid = valid && validateDuration(videoAssetMetadata.duration)\n }\n if (videoAssetMetadata?.isAudioOnly != undefined) {\n valid = valid && validateDrmAvailability(videoAssetMetadata.isAudioOnly)\n }\n if (valid) {\n setValidationError(null)\n }\n }, [\n MAX_FILE_SIZE,\n MAX_DURATION_SECONDS,\n canSkipFileSizeValidation,\n videoAssetMetadata?.duration,\n videoAssetMetadata?.size,\n videoAssetMetadata?.height,\n videoAssetMetadata?.width,\n videoAssetMetadata,\n config.drm_policy,\n validationError,\n ])\n\n // If user-provided config is disabled, begin the upload immediately with\n // the developer-specified values from the schema or config or defaults.\n // This can include auto-generated subtitles!\n const {disableTextTrackConfig, disableUploadConfig} = pluginConfig\n const skipConfig = disableTextTrackConfig && disableUploadConfig\n useEffect(() => {\n if (skipConfig) {\n const {settings, watermark} = formatUploadConfig(config, secrets, {\n videoAspectRatio: videoAssetMetadata?.aspectRatio,\n })\n startUpload(settings, watermark)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n if (skipConfig) return null\n\n const basicConfig = config.video_quality !== 'plus' && config.video_quality !== 'premium'\n const playbackPolicySelected = config.public_policy || config.signed_policy || config.drm_policy\n const maxSupportedResolution = RESOLUTION_TIERS.findIndex(\n (rt) => rt.value === pluginConfig.max_resolution_tier\n )\n return (\n <Dialog\n animate\n open\n id=\"upload-configuration\"\n zOffset={1000}\n width={1}\n header=\"Configure Mux Upload\"\n onClose={onClose}\n >\n <Stack padding={4} space={2}>\n {(validationError || watermarkValidationError) && (\n <Card padding={3} tone=\"critical\" radius={2} marginBottom={2}>\n <Flex gap={2} align=\"flex-start\">\n <ErrorOutlineIcon width={20} height={20} />\n <Stack space={2}>\n <Text size={1} weight=\"semibold\">\n Validation Error\n </Text>\n <Text size={1}>{validationError || watermarkValidationError}</Text>\n </Stack>\n </Flex>\n </Card>\n )}\n <Label size={3}>FILE TO UPLOAD</Label>\n <Card\n tone=\"transparent\"\n border\n padding={3}\n paddingY={4}\n style={{borderRadius: '0.1865rem'}}\n >\n <Flex gap={2}>\n <DocumentVideoIcon fontSize=\"2em\" />\n <Stack space={2}>\n <Text textOverflow=\"ellipsis\" as=\"h2\" size={3}>\n {stagedUpload.type === 'file' ? stagedUpload.files[0].name : stagedUpload.url}\n </Text>\n <Text as=\"p\" size={1} muted>\n {stagedUpload.type === 'file'\n ? `Direct File Upload (${formatBytes(stagedUpload.files[0].size)})`\n : (() => {\n if (videoAssetMetadata?.size) {\n return `File From URL (${formatBytes(videoAssetMetadata.size)})`\n }\n if (isLoadingFileSize) {\n return 'File From URL (Loading size...)'\n }\n return 'File From URL (Unknown size)'\n })()}\n </Text>\n {stagedUpload.type === 'file' && (\n <Stack space={1}>\n {isLoadingMetadata && (\n <Text as=\"p\" size={1} muted>\n Reading video metadata...\n </Text>\n )}\n {videoAssetMetadata?.duration && !validationError && (\n <Text as=\"p\" size={1} muted>\n Duration: {formatSeconds(videoAssetMetadata.duration)}\n </Text>\n )}\n </Stack>\n )}\n </Stack>\n </Flex>\n </Card>\n {!disableUploadConfig && (\n <Stack space={3} paddingBottom={2}>\n <FormField\n title=\"Video Quality Level\"\n description={\n <>\n The video quality level informs the cost, quality, and available platform features\n for the asset.{' '}\n <a\n href=\"https://docs.mux.com/guides/use-encoding-tiers\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n See the Mux guide for more details.\n </a>\n </>\n }\n >\n <Flex gap={3}>\n {VIDEO_QUALITY_LEVELS.map(({value, label}) => {\n const inputId = `${id}--encodingtier-${value}`\n return (\n <Flex key={value} align=\"center\" gap={2}>\n <Radio\n checked={config.video_quality === value}\n name=\"asset-encodingtier\"\n onChange={(e) =>\n dispatch({\n action: 'video_quality' as const,\n value: e.currentTarget.value as UploadConfig['video_quality'],\n })\n }\n value={value}\n id={inputId}\n />\n <Text as=\"label\" htmlFor={inputId}>\n {label}\n </Text>\n </Flex>\n )\n })}\n </Flex>\n </FormField>\n\n {!basicConfig && (\n <>\n <FormField title=\"Additional Configuration\">\n <Stack space={3}>\n <PlaybackPolicy id={id} config={config} secrets={secrets} dispatch={dispatch} />\n {maxSupportedResolution > 0 && (\n <ResolutionTierSelector\n id={id}\n config={config}\n dispatch={dispatch}\n maxSupportedResolution={maxSupportedResolution}\n />\n )}\n <StaticRenditionSelector id={id} config={config} dispatch={dispatch} />\n {!disableTextTrackConfig && (\n <TextTracksEditor\n tracks={config.text_tracks}\n dispatch={dispatch}\n defaultLang={pluginConfig.defaultAutogeneratedSubtitleLang}\n />\n )}\n </Stack>\n </FormField>\n <WatermarkSection\n config={config}\n dispatch={dispatch}\n stagedUpload={stagedUpload}\n videoAssetMetadata={videoAssetMetadata}\n watermarkPreviewContainerRef={watermarkPreviewContainerRef}\n watermarkPreviewVideoRef={watermarkPreviewVideoRef}\n onValidationChange={setWatermarkValidationError}\n />\n </>\n )}\n </Stack>\n )}\n\n <Box marginTop={4}>\n <Button\n disabled={\n (!basicConfig && !playbackPolicySelected) ||\n validationError !== null ||\n isLoadingMetadata ||\n (isLoadingFileSize && !canSkipFileSizeValidation)\n }\n icon={UploadIcon}\n text=\"Upload\"\n tone=\"positive\"\n onClick={() => {\n if (!validationError) {\n const {settings, watermark} = formatUploadConfig(config, secrets, {\n videoAspectRatio: videoAssetMetadata?.aspectRatio,\n })\n startUpload(settings, watermark)\n }\n }}\n />\n </Box>\n </Stack>\n </Dialog>\n )\n}\n\nfunction setAdvancedPlaybackPolicy(\n config: UploadConfig,\n secrets: Secrets\n): MuxNewAssetSettings['advanced_playback_policies'] {\n const advanced_playback_policies: MuxNewAssetSettings['advanced_playback_policies'] = []\n if (config.public_policy) {\n advanced_playback_policies.push({policy: 'public'})\n }\n if (config.signed_policy) {\n advanced_playback_policies.push({policy: 'signed'})\n }\n if (config.drm_policy) {\n if (secrets.drmConfigId)\n advanced_playback_policies.push({\n policy: 'drm',\n drm_configuration_id: secrets.drmConfigId ?? undefined,\n })\n else {\n console.error('Selected DRM Policy but missing DRM Configuration Id')\n }\n }\n return advanced_playback_policies\n}\n\nfunction formatUploadConfig(\n config: UploadConfig,\n secrets: Secrets,\n options?: {videoAspectRatio?: number | null}\n): {\n settings: MuxNewAssetSettings\n watermark?: WatermarkConfig\n} {\n const generated_subtitles = config.text_tracks\n .filter<AutogeneratedTextTrack>(isAutogeneratedTrack)\n .map<{name: string; language_code: SupportedMuxLanguage}>((track) => ({\n name: track.name,\n language_code: track.language_code,\n }))\n\n const inputs: NonNullable<MuxNewAssetSettings['input']> = [\n {\n type: 'video',\n generated_subtitles: generated_subtitles.length > 0 ? generated_subtitles : undefined,\n },\n ...config.text_tracks.filter<CustomTextTrack>(isCustomTextTrack).reduce(\n (acc, track) => {\n if (track.language_code && track.file && track.name) {\n acc.push({\n url: track.file.contents,\n type: 'text',\n text_type: track.type === 'subtitles' ? 'subtitles' : undefined,\n language_code: track.language_code,\n name: track.name,\n closed_captions: track.type === 'captions',\n })\n }\n return acc\n },\n [] as NonNullable<MuxNewAssetSettings['input']>\n ),\n ]\n\n if (config.watermark?.imageUrl) {\n const watermarkForMux: WatermarkConfig = {...config.watermark, enabled: true}\n const overlaySettings = convertWatermarkToMuxOverlay(watermarkForMux, {\n videoAspectRatio: options?.videoAspectRatio ?? undefined,\n units: 'px',\n })\n if (overlaySettings) {\n inputs.push({\n url: config.watermark.imageUrl,\n overlay_settings: overlaySettings,\n } as NonNullable<MuxNewAssetSettings['input']>[number])\n }\n }\n\n return {\n settings: {\n input: inputs,\n static_renditions:\n config.static_renditions.length > 0\n ? config.static_renditions.map((resolution) => ({resolution}))\n : undefined,\n advanced_playback_policies: setAdvancedPlaybackPolicy(config, secrets),\n max_resolution_tier: config.max_resolution_tier,\n video_quality: config.video_quality,\n normalize_audio: config.normalize_audio,\n },\n watermark: config.watermark?.imageUrl\n ? ({...config.watermark, enabled: true} as WatermarkConfig)\n : undefined,\n }\n}\n\nfunction WatermarkSection({\n config,\n dispatch,\n stagedUpload,\n videoAssetMetadata,\n watermarkPreviewContainerRef,\n watermarkPreviewVideoRef,\n onValidationChange,\n}: {\n config: UploadConfig\n dispatch: (action: UploadConfigurationStateAction) => void\n stagedUpload: StagedUpload\n videoAssetMetadata: VideoAssetMetadata | null\n watermarkPreviewContainerRef: React.RefObject<HTMLDivElement | null>\n watermarkPreviewVideoRef: React.RefObject<HTMLVideoElement | null>\n onValidationChange: (error: string | null) => void\n}) {\n if (videoAssetMetadata?.isAudioOnly !== false) return null\n return (\n <FormField\n title=\"Watermark\"\n description={\n <>\n Add a watermark overlay to your video using Mux&apos;s native watermark support.{' '}\n <a\n href=\"https://www.mux.com/docs/guides/add-watermarks-to-your-videos\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Learn more about Mux watermarks.\n </a>\n </>\n }\n >\n <Stack space={3}>\n <WatermarkControls\n watermark={config.watermark || {enabled: false}}\n onChange={(watermark) => {\n dispatch({action: 'watermark', value: watermark})\n }}\n onValidationChange={onValidationChange}\n previewContainerRef={watermarkPreviewContainerRef}\n previewVideoRef={watermarkPreviewVideoRef}\n />\n {config.watermark?.imageUrl &&\n stagedUpload.type === 'file' &&\n // Canvas preview is only shown in \"Canvas\" mode (no explicit overlay_settings)\n !config.watermark.overlay_settings && (\n <WatermarkPreview\n stagedUpload={stagedUpload}\n watermark={config.watermark}\n videoAspectRatio={videoAssetMetadata.aspectRatio}\n onWatermarkChange={(watermark) => {\n dispatch({action: 'watermark', value: watermark})\n }}\n previewContainerRef={watermarkPreviewContainerRef}\n videoRef={watermarkPreviewVideoRef}\n />\n )}\n </Stack>\n </FormField>\n )\n}\n\n// Memoized preview component to prevent unnecessary re-renders\nconst WatermarkPreview = memo(function WatermarkPreview({\n stagedUpload,\n watermark,\n onWatermarkChange,\n videoAspectRatio,\n previewContainerRef,\n videoRef,\n}: {\n stagedUpload: StagedUpload\n watermark: WatermarkConfig\n onWatermarkChange: (watermark: WatermarkConfig) => void\n videoAspectRatio?: number | null\n previewContainerRef: React.RefObject<HTMLDivElement | null>\n videoRef: React.RefObject<HTMLVideoElement | null>\n}) {\n // Initialize video source only once\n useEffect(() => {\n if (videoRef.current && stagedUpload.type === 'file') {\n const file = stagedUpload.files[0]\n const url = URL.createObjectURL(file)\n videoRef.current.src = url\n\n return () => {\n URL.revokeObjectURL(url)\n }\n }\n return undefined\n }, [stagedUpload, videoRef])\n\n const isVertical =\n videoAspectRatio !== null && videoAspectRatio !== undefined && videoAspectRatio < 1\n\n return (\n <Card\n tone=\"transparent\"\n border\n style={{\n overflow: 'hidden',\n // For vertical videos, center the preview and limit its width\n display: 'flex',\n justifyContent: 'center',\n }}\n >\n {/* Inner container that exactly matches the video aspect ratio - no padding, no letterbox */}\n <div\n ref={previewContainerRef}\n style={{\n position: 'relative',\n // For vertical videos: limit width so the preview doesn't get too tall\n // For horizontal videos: use full width\n width: isVertical ? 'auto' : '100%',\n aspectRatio: videoAspectRatio ? String(videoAspectRatio) : '16/9',\n ...(isVertical ? {height: '400px', maxHeight: '50vh'} : {minHeight: '200px'}),\n overflow: 'hidden',\n }}\n >\n <video\n ref={videoRef}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n objectFit: 'fill',\n display: 'block',\n }}\n />\n <DraggableWatermark\n watermark={watermark}\n onChange={onWatermarkChange}\n containerRef={previewContainerRef as React.RefObject<HTMLDivElement>}\n videoElementRef={videoRef as React.RefObject<HTMLVideoElement>}\n />\n </div>\n </Card>\n )\n})\n","import {rem} from '@sanity/ui'\nimport type {ComponentType} from 'react'\nimport {css, styled} from 'styled-components'\n\nimport {focusRingBorderStyle, focusRingStyle} from './helpers'\n\nexport function withFocusRing<Props>(component: ComponentType<Props>) {\n return styled(component as unknown as any)<Props & {$border?: boolean}>((props) => {\n const border = {\n width: props.$border ? 1 : 0,\n color: 'var(--card-border-color)',\n }\n\n return css`\n --card-focus-box-shadow: ${focusRingBorderStyle(border)};\n\n border-radius: ${rem(props.theme.sanity.radius[1])};\n outline: none;\n box-shadow: var(--card-focus-box-shadow);\n\n &:focus {\n --card-focus-box-shadow: ${focusRingStyle({\n base: props.theme.sanity.color.base,\n border,\n focusRing: props.theme.sanity.focusRing,\n })};\n }\n `\n })\n}\n","/* eslint-disable no-nested-ternary */\nimport {Card, type CardTone} from '@sanity/ui'\nimport React, {forwardRef, useCallback, useRef} from 'react'\nimport {styled} from 'styled-components'\n\nimport {withFocusRing} from './withFocusRing'\n\nconst UploadCardWithFocusRing = withFocusRing(Card)\n\ninterface UploadCardProps {\n tone?: CardTone\n children: React.ReactNode\n onPaste: React.ClipboardEventHandler<HTMLInputElement>\n onDrop: React.DragEventHandler<HTMLDivElement>\n onDragOver: React.DragEventHandler<HTMLDivElement>\n onDragLeave: React.DragEventHandler<HTMLDivElement>\n onDragEnter: React.DragEventHandler<HTMLDivElement>\n}\nexport const UploadCard = forwardRef<HTMLDivElement, UploadCardProps>(\n ({children, tone, onPaste, onDrop, onDragEnter, onDragLeave, onDragOver}, forwardedRef) => {\n const inputRef = useRef<HTMLInputElement>(null)\n const handleKeyDown = useCallback<React.KeyboardEventHandler<HTMLDivElement>>((event) => {\n const target = event.target as HTMLElement\n\n // Don't steal focus when pasting into the VTT input\n if (target.closest('#vtt-url')) {\n return\n }\n\n if ((event.ctrlKey || event.metaKey) && event.key === 'v') {\n inputRef.current!.focus()\n }\n }, [])\n\n return (\n <UploadCardWithFocusRing\n tone={tone}\n ref={forwardedRef}\n padding={0}\n radius={2}\n shadow={0}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n onPaste={onPaste}\n onDrop={onDrop}\n onDragEnter={onDragEnter}\n onDragLeave={onDragLeave}\n onDragOver={onDragOver}\n >\n <HiddenInput ref={inputRef} />\n {children}\n </UploadCardWithFocusRing>\n )\n }\n)\n\nconst HiddenInput = styled.input.attrs({type: 'text'})`\n position: absolute;\n border: 0;\n color: white;\n opacity: 0;\n\n &:focus {\n outline: none;\n }\n`\n","import {Button, type ButtonProps} from '@sanity/ui'\nimport React, {useCallback, useId, useRef} from 'react'\nimport {styled} from 'styled-components'\n\nconst HiddenInput = styled.input`\n overflow: hidden;\n width: 0.1px;\n height: 0.1px;\n opacity: 0;\n position: absolute;\n z-index: -1;\n`\n\nconst Label = styled.label`\n position: relative;\n`\n\nexport interface FileInputButtonProps extends ButtonProps {\n onSelect: (files: FileList) => void\n accept: string\n}\nexport const FileInputButton = ({onSelect, accept, ...props}: FileInputButtonProps) => {\n const inputId = `FileSelect${useId()}`\n const inputRef = useRef<HTMLInputElement>(null)\n const handleSelect = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n (event) => {\n if (onSelect) {\n onSelect(event.target.files!)\n }\n },\n [onSelect]\n )\n const handleButtonClick = useCallback(() => inputRef.current?.click(), [])\n return (\n <Label htmlFor={inputId}>\n <HiddenInput\n accept={accept}\n ref={inputRef}\n tabIndex={0}\n type=\"file\"\n id={inputId}\n onChange={handleSelect}\n value=\"\"\n />\n <Button\n onClick={handleButtonClick}\n mode=\"default\"\n tone=\"primary\"\n style={{width: '100%'}}\n {...props}\n />\n </Label>\n )\n}\n","import {DocumentVideoIcon, PlugIcon, SearchIcon, UploadIcon} from '@sanity/icons'\nimport {Button, Card, Flex, Inline, Text} from '@sanity/ui'\nimport {useCallback} from 'react'\n\nimport {useAccessControl} from '../hooks/useAccessControl'\nimport type {SetDialogState} from '../hooks/useDialogState'\nimport {PluginConfig} from '../util/types'\nimport {FileInputButton, type FileInputButtonProps} from './FileInputButton'\n\nfunction formatAcceptString(accept: string): string {\n return accept\n .split(',')\n .map((type) => type.trim().replace('/*', ''))\n .join(' or ')\n}\n\ninterface UploadPlaceholderProps {\n setDialogState: SetDialogState\n readOnly: boolean\n hovering: boolean\n needsSetup: boolean\n onSelect: FileInputButtonProps['onSelect']\n config: PluginConfig\n accept: string\n}\nexport default function UploadPlaceholder(props: UploadPlaceholderProps) {\n const {setDialogState, readOnly, onSelect, hovering, needsSetup, accept} = props\n const handleBrowse = useCallback(() => setDialogState('select-video'), [setDialogState])\n const handleConfigureApi = useCallback(() => setDialogState('secrets'), [setDialogState])\n const {hasConfigAccess} = useAccessControl(props.config)\n\n return (\n <Card\n sizing=\"border\"\n tone={readOnly ? 'transparent' : 'inherit'}\n border\n radius={2}\n paddingX={3}\n paddingY={1}\n style={hovering ? {borderColor: 'transparent'} : undefined}\n >\n <Flex\n align=\"center\"\n justify=\"space-between\"\n gap={4}\n direction={['column', 'column', 'row']}\n paddingY={2}\n sizing=\"border\"\n >\n <Flex align=\"center\" justify=\"flex-start\" gap={2} flex={1}>\n <Flex justify=\"center\">\n <Text muted>\n <DocumentVideoIcon />\n </Text>\n </Flex>\n <Flex justify=\"center\">\n <Text size={1} muted>\n Drag {formatAcceptString(accept)} file or paste URL here\n </Text>\n </Flex>\n </Flex>\n <Inline space={2}>\n <FileInputButton\n accept={accept}\n mode=\"bleed\"\n tone=\"default\"\n icon={UploadIcon}\n text=\"Upload\"\n onSelect={onSelect}\n />\n <Button mode=\"bleed\" icon={SearchIcon} text=\"Select\" onClick={handleBrowse} />\n\n {hasConfigAccess && (\n <Button\n padding={3}\n radius={3}\n tone={needsSetup ? 'critical' : undefined}\n onClick={handleConfigureApi}\n icon={PlugIcon}\n mode=\"bleed\"\n title=\"Configure plugin credentials\"\n />\n )}\n </Inline>\n </Flex>\n </Card>\n )\n}\n","import {ErrorOutlineIcon} from '@sanity/icons'\nimport {Button, CardTone, Flex, Text, useToast} from '@sanity/ui'\nimport React, {useCallback, useEffect, useReducer, useRef, useState} from 'react'\nimport {type Observable, Subject, Subscription} from 'rxjs'\nimport {takeUntil, tap} from 'rxjs/operators'\nimport type {SanityClient} from 'sanity'\nimport {PatchEvent, set, setIfMissing} from 'sanity'\n\nimport {uploadFile, uploadUrl} from '../actions/upload'\nimport {DialogStateProvider} from '../context/DialogStateContext'\nimport {type DialogState, type SetDialogState} from '../hooks/useDialogState'\nimport {isServerError, isValidUrl} from '../util/asserters'\nimport {extractDroppedFiles} from '../util/extractFiles'\nimport {hasPlaybackPolicy} from '../util/getPlaybackPolicy'\nimport type {\n MuxInputProps,\n MuxNewAssetSettings,\n PluginConfig,\n Secrets,\n VideoAssetDocument,\n} from '../util/types'\nimport InputBrowser from './InputBrowser'\nimport Player from './Player'\nimport PlayerActionsMenu from './PlayerActionsMenu'\nimport UploadConfiguration from './UploadConfiguration'\nimport {UploadCard} from './Uploader.styled'\nimport UploadPlaceholder from './UploadPlaceholder'\nimport {UploadProgress} from './UploadProgress'\n\ninterface Props extends Pick<MuxInputProps, 'onChange' | 'readOnly'> {\n config: PluginConfig\n client: SanityClient\n secrets: Secrets\n asset: VideoAssetDocument | null | undefined\n dialogState: DialogState\n setDialogState: SetDialogState\n needsSetup: boolean\n}\n\nexport type StagedUpload = {type: 'file'; files: FileList | File[]} | {type: 'url'; url: string}\ntype UploadStatus = {\n progress: number\n file?: {name: string | undefined; type: string}\n uuid?: string\n url?: string\n}\n\ninterface State {\n stagedUpload: StagedUpload | null\n uploadStatus: UploadStatus | null\n error: Error | null\n}\n\nconst INITIAL_STATE: State = {\n stagedUpload: null,\n uploadStatus: null,\n error: null,\n}\n\ntype UploadFileEvent = ReturnType<typeof uploadFile> extends Observable<infer T> ? T : never\ntype UploadUrlEvent = ReturnType<typeof uploadUrl> extends Observable<infer T> ? T : never\ntype UploaderStateAction =\n | {action: 'stageUpload'; input: NonNullable<State['stagedUpload']>}\n | {action: 'commitUpload'}\n | ({action: 'progressInfo'} & (\n | Extract<UploadFileEvent, {type: 'uuid' | 'file'}>\n | Extract<UploadUrlEvent, {type: 'url'}>\n ))\n | {action: 'progress'; percent: number}\n | {action: 'error'; error: Error; settings: MuxNewAssetSettings}\n | {action: 'complete' | 'reset'}\n\n/**\n * The main interface for inputting a Mux Video. It handles staging an upload\n * file, setting its configuration, displaying upload progress, and showing\n * the preview player.\n */\nexport default function Uploader(props: Props) {\n const toast = useToast()\n const containerRef = useRef<HTMLDivElement>(null)\n\n const dragEnteredEls = useRef<EventTarget[]>([])\n const [dragState, setDragState] = useState<'valid' | 'invalid' | null>(null)\n\n const cancelUploadButton = useRef(\n (() => {\n const events$ = new Subject()\n return {\n observable: events$.asObservable(),\n handleClick: ((event) => events$.next(event)) as React.MouseEventHandler<HTMLButtonElement>,\n }\n })()\n ).current\n\n const uploadRef = useRef<Subscription | null>(null)\n const uploadingDocumentId = useRef<string | null>(null)\n const [state, dispatch] = useReducer(\n (prev: State, action: UploaderStateAction) => {\n switch (action.action) {\n case 'stageUpload':\n return Object.assign({}, INITIAL_STATE, {stagedUpload: action.input})\n case 'commitUpload':\n return Object.assign({}, prev, {uploadStatus: {progress: 0}})\n case 'progressInfo': {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {type, action: _, ...payload} = action\n return Object.assign({}, prev, {\n uploadStatus: {\n ...prev.uploadStatus,\n progress: prev.uploadStatus!.progress,\n ...payload,\n },\n } satisfies Pick<typeof prev, 'uploadStatus'>)\n }\n case 'progress':\n return Object.assign({}, prev, {\n uploadStatus: {\n ...prev.uploadStatus,\n progress: action.percent,\n },\n } satisfies Pick<typeof prev, 'uploadStatus'>)\n case 'reset':\n case 'complete':\n // Clear upload observable on completion\n uploadRef.current?.unsubscribe()\n uploadRef.current = null\n uploadingDocumentId.current = null\n return INITIAL_STATE\n case 'error': {\n // Clear upload observable on error\n uploadRef.current?.unsubscribe()\n uploadRef.current = null\n uploadingDocumentId.current = null\n\n let error = action.error\n if (isServerError(action.error) && hasPlaybackPolicy(action.settings, 'drm')) {\n error = new Error(\n 'Unknown Error while uploading DRM protected content. Make sure your DRM configuration ID is valid and set correctly'\n )\n }\n\n return Object.assign({}, INITIAL_STATE, {error: error})\n }\n default:\n return prev\n }\n },\n {\n stagedUpload: null,\n uploadStatus: null,\n error: null,\n }\n )\n\n // Make sure we close out the upload observer on dismount\n // and cleanup orphaned documents if upload was in progress\n useEffect(() => {\n const cleanup = () => {\n // Cancel subscription\n if (uploadRef.current && !uploadRef.current.closed) {\n uploadRef.current.unsubscribe()\n }\n\n // Delete orphaned document if upload was in progress and document is different from the saved asset\n if (uploadingDocumentId.current && props.asset?._id !== uploadingDocumentId.current) {\n const docId = uploadingDocumentId.current\n uploadingDocumentId.current = null\n\n props.client.delete(docId).catch((err) => {\n console.warn('Failed to cleanup orphaned upload document:', err)\n })\n }\n }\n\n const handleBeforeUnload = () => {\n cleanup()\n }\n\n window.addEventListener('beforeunload', handleBeforeUnload)\n window.addEventListener('pagehide', handleBeforeUnload)\n\n return () => {\n window.removeEventListener('beforeunload', handleBeforeUnload)\n window.removeEventListener('pagehide', handleBeforeUnload)\n cleanup()\n }\n }, [props.client, props.asset?._id])\n\n /* -------------------------------------------------------------------------- */\n /* Uploading */\n /* -------------------------------------------------------------------------- */\n\n /**\n * Begins a file or URL upload with the staged files or URL.\n *\n * Should only be called from the UploadConfiguration component, which provides\n * the Mux configuration for the direct asset upload.\n *\n * @param settings The Mux new_asset_settings object to send to Sanity\n * @param watermark Optional watermark configuration\n * @returns\n */\n const startUpload = (\n settings: MuxNewAssetSettings,\n watermark?: import('../util/types').WatermarkConfig\n ) => {\n const {stagedUpload} = state\n if (!stagedUpload || uploadRef.current) return\n dispatch({action: 'commitUpload'})\n let uploadObservable: Observable<UploadFileEvent | UploadUrlEvent>\n // eslint-disable-next-line default-case\n switch (stagedUpload.type) {\n case 'url':\n uploadObservable = uploadUrl({\n client: props.client,\n url: stagedUpload.url,\n settings,\n watermark,\n })\n break\n case 'file':\n uploadObservable = uploadFile({\n client: props.client,\n file: stagedUpload.files[0],\n settings,\n watermark,\n }).pipe(\n takeUntil(\n cancelUploadButton.observable.pipe(\n tap(() => {\n if (uploadingDocumentId.current) {\n props.client.delete(uploadingDocumentId.current)\n uploadingDocumentId.current = null\n }\n })\n )\n )\n )\n break\n }\n uploadRef.current = uploadObservable.subscribe({\n next: (event) => {\n switch (event.type) {\n case 'uuid':\n // Track the document ID for cleanup on unmount\n uploadingDocumentId.current = event.uuid\n dispatch({action: 'progressInfo', ...event})\n break\n case 'file':\n case 'url':\n dispatch({action: 'progressInfo', ...event})\n break\n case 'progress':\n dispatch({action: 'progress', percent: event.percent})\n break\n case 'success':\n dispatch({action: 'progress', percent: 100})\n uploadingDocumentId.current = null\n props.onChange(\n PatchEvent.from([\n setIfMissing({asset: {}}),\n set({_type: 'reference', _weak: true, _ref: event.asset._id}, ['asset']),\n ])\n )\n break\n case 'pause':\n case 'resume':\n default:\n break\n }\n },\n complete: () => dispatch({action: 'complete'}),\n error: (error) => dispatch({action: 'error', error, settings}),\n })\n }\n\n const invalidFileToast = useCallback(() => {\n toast.push({\n status: 'error',\n title: `Invalid file type. Accepted types: ${props.config.acceptedMimeTypes?.join(', ')}`,\n })\n }, [props.config.acceptedMimeTypes, toast])\n\n /**\n * Validates if any file in the provided FileList or File array has an unsupported MIME type\n * @param files - FileList or File array to validate\n * @returns true if any file has an invalid MIME type, false if all files are valid\n */\n const isInvalidFile = (files: FileList | File[]) => {\n const isInvalid = Array.from(files).some((file) => {\n return !props.config.acceptedMimeTypes?.some((acceptedType) => {\n // Convert mime type pattern to regex (e.g., 'audio/*' -> /^audio\\/.*$/)\n const pattern = `^${acceptedType.replace('*', '.*')}$`\n return new RegExp(pattern).test(file.type)\n })\n })\n\n return isInvalid\n }\n\n /* -------------------------- Upload Initialization ------------------------- */\n // The below populate the uploadInput state field, which then triggers the\n // upload configuration, or the startUpload function if no config is required.\n\n // Stages an upload from the file selector\n const handleUpload = (files: FileList | File[]) => {\n if (isInvalidFile(files)) return\n dispatch({\n action: 'stageUpload',\n input: {type: 'file', files},\n })\n }\n\n // Stages and validates an upload from pasting an asset URL\n const handlePaste: React.ClipboardEventHandler<HTMLInputElement> = (event) => {\n const target = event.target as HTMLElement\n\n // Ignore paste coming from the VTT URL input\n if (target.closest('#vtt-url')) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n const clipboardData =\n event.clipboardData || (window as Window & {clipboardData?: DataTransfer}).clipboardData\n const url = clipboardData?.getData('text')?.trim()\n if (!isValidUrl(url)) {\n toast.push({status: 'error', title: 'Invalid URL for Mux video input.'})\n return\n }\n dispatch({action: 'stageUpload', input: {type: 'url', url: url}})\n }\n\n // Stages and validates an upload from dragging+dropping files or folders\n const handleDrop: React.DragEventHandler<HTMLDivElement> = (event) => {\n event.preventDefault()\n event.stopPropagation()\n if (dragState === 'invalid') {\n invalidFileToast()\n setDragState(null)\n return\n }\n setDragState(null)\n extractDroppedFiles(event.nativeEvent.dataTransfer!).then((files) => {\n dispatch({\n action: 'stageUpload',\n input: {type: 'file', files},\n })\n })\n }\n\n /* ------------------------------- Drag State ------------------------------- */\n\n const handleDragOver: React.DragEventHandler<HTMLDivElement> = (event) => {\n event.preventDefault()\n event.stopPropagation()\n }\n\n const handleDragEnter: React.DragEventHandler<HTMLDivElement> = (event) => {\n event.stopPropagation()\n dragEnteredEls.current.push(event.target)\n const type = event.dataTransfer.items?.[0]?.type\n const mimeTypes = props.config.acceptedMimeTypes\n\n // Check if the dragged file type matches any of the accepted mime types\n const isValidType = mimeTypes?.some((acceptedType) => {\n // Convert mime type pattern to regex (e.g., 'video/*' -> /^video\\/.*$/)\n const pattern = `^${acceptedType.replace('*', '.*')}$`\n return new RegExp(pattern).test(type)\n })\n\n setDragState(isValidType ? 'valid' : 'invalid')\n }\n\n const handleDragLeave: React.DragEventHandler<HTMLDivElement> = (event) => {\n event.stopPropagation()\n const idx = dragEnteredEls.current.indexOf(event.target)\n if (idx > -1) {\n dragEnteredEls.current.splice(idx, 1)\n }\n if (dragEnteredEls.current.length === 0) {\n setDragState(null)\n }\n }\n\n /* -------------------------------- Rendering ------------------------------- */\n\n // Upload has errored\n if (state.error !== null) {\n const error = state.error\n return (\n <Flex gap={3} direction=\"column\" justify=\"center\" align=\"center\">\n <Text size={5} muted>\n <ErrorOutlineIcon />\n </Text>\n <Text>Something went wrong</Text>\n {error instanceof Error && error.message && (\n <Text size={1} muted weight=\"semibold\" style={{textAlign: 'center'}}>\n {error.message}\n </Text>\n )}\n <Button text=\"Upload another file\" onClick={() => dispatch({action: 'reset'})} />\n </Flex>\n )\n }\n\n // Upload is in progress\n if (state.uploadStatus !== null) {\n const {uploadStatus} = state\n return (\n <UploadProgress\n onCancel={cancelUploadButton.handleClick}\n progress={uploadStatus.progress}\n filename={uploadStatus.file?.name || uploadStatus.url}\n />\n )\n }\n\n // Upload needs configuration\n if (state.stagedUpload !== null) {\n return (\n <UploadConfiguration\n stagedUpload={state.stagedUpload}\n pluginConfig={props.config}\n secrets={props.secrets}\n startUpload={startUpload}\n onClose={() => dispatch({action: 'reset'})}\n />\n )\n }\n\n // Default: No staged upload\n let tone: CardTone | undefined\n if (dragState) tone = dragState === 'valid' ? 'positive' : 'critical'\n\n const acceptMimeString = props.config?.acceptedMimeTypes?.length\n ? props.config.acceptedMimeTypes.join(',')\n : 'video/*, audio/*'\n\n return (\n <>\n <UploadCard\n tone={tone}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDragEnter={handleDragEnter}\n onPaste={handlePaste}\n ref={containerRef}\n >\n {props.asset ? (\n <DialogStateProvider\n dialogState={props.dialogState}\n setDialogState={props.setDialogState}\n >\n <Player\n readOnly={props.readOnly}\n asset={props.asset}\n onChange={props.onChange}\n config={props.config}\n buttons={\n <PlayerActionsMenu\n accept={acceptMimeString}\n asset={props.asset}\n dialogState={props.dialogState}\n setDialogState={props.setDialogState}\n onChange={props.onChange}\n onSelect={handleUpload}\n readOnly={props.readOnly}\n config={props.config}\n />\n }\n />\n </DialogStateProvider>\n ) : (\n <UploadPlaceholder\n accept={acceptMimeString}\n hovering={dragState !== null}\n onSelect={handleUpload}\n readOnly={!!props.readOnly}\n setDialogState={props.setDialogState}\n needsSetup={props.needsSetup}\n config={props.config}\n />\n )}\n </UploadCard>\n {props.dialogState === 'select-video' && (\n <InputBrowser\n config={props.config}\n asset={props.asset}\n onChange={props.onChange}\n setDialogState={props.setDialogState}\n />\n )}\n </>\n )\n}\n","import {Card} from '@sanity/ui'\nimport {memo, Suspense} from 'react'\n\nimport {useAccessControl} from '../hooks/useAccessControl'\nimport {useAssetDocumentValues} from '../hooks/useAssetDocumentValues'\nimport {useClient} from '../hooks/useClient'\nimport {useDialogState} from '../hooks/useDialogState'\nimport {useMuxPolling} from '../hooks/useMuxPolling'\nimport {useSecretsDocumentValues} from '../hooks/useSecretsDocumentValues'\nimport type {MuxInputProps, PluginConfig} from '../util/types'\nimport {ConfigureApiDialog} from './ConfigureApi'\nimport ErrorBoundaryCard from './ErrorBoundaryCard'\nimport {InputFallback} from './Input.styled'\nimport Onboard from './Onboard'\nimport Uploader from './Uploader'\n\nexport interface InputProps extends MuxInputProps {\n config: PluginConfig\n}\nconst Input = (props: InputProps) => {\n const client = useClient()\n const secretDocumentValues = useSecretsDocumentValues()\n const assetDocumentValues = useAssetDocumentValues(props.value?.asset)\n const poll = useMuxPolling(props.readOnly ? undefined : assetDocumentValues?.value || undefined)\n const [dialogState, setDialogState] = useDialogState()\n const {hasConfigAccess} = useAccessControl(props.config)\n\n const error = secretDocumentValues.error || assetDocumentValues.error || poll.error /*||\n // @TODO move errored logic to Uploader, where handleRemoveVideo can be called\n (assetDocumentValues.value?.status === 'errored'\n ? new Error(assetDocumentValues.value.data?.errors?.messages?.join(' '))\n : undefined)\n // */\n if (error) {\n // @TODO deal with it more gracefully\n throw error\n }\n const isLoading = secretDocumentValues.isLoading || assetDocumentValues.isLoading\n\n return (\n <Card>\n <ErrorBoundaryCard schemaType={props.schemaType}>\n <Suspense fallback={<InputFallback />}>\n {isLoading ? (\n <InputFallback />\n ) : (\n <>\n {secretDocumentValues.value.needsSetup && !assetDocumentValues.value ? (\n <Onboard setDialogState={setDialogState} config={props.config} />\n ) : (\n <Uploader\n {...props}\n config={props.config}\n onChange={props.onChange}\n client={client}\n secrets={secretDocumentValues.value.secrets}\n asset={assetDocumentValues.value}\n dialogState={dialogState}\n setDialogState={setDialogState}\n needsSetup={secretDocumentValues.value.needsSetup}\n />\n )}\n\n {dialogState === 'secrets' && hasConfigAccess && (\n <ConfigureApiDialog\n setDialogState={setDialogState}\n secrets={secretDocumentValues.value.secrets}\n />\n )}\n </>\n )}\n </Suspense>\n </ErrorBoundaryCard>\n </Card>\n )\n}\n\nexport default memo(Input)\n","import Input from './components/Input'\nimport VideoThumbnail from './components/VideoThumbnail'\nimport type {MuxInputProps, PluginConfig, VideoAssetDocument} from './util/types'\n\nexport function muxVideoCustomRendering(config: PluginConfig) {\n return {\n components: {\n input: (props: MuxInputProps) => (\n <Input config={{...config, ...props.schemaType.options}} {...props} />\n ),\n },\n preview: {\n select: {\n filename: 'asset.filename',\n playbackId: 'asset.playbackId',\n status: 'asset.status',\n assetId: 'asset.assetId',\n thumbTime: 'asset.thumbTime',\n data: 'asset.data',\n },\n prepare: (asset: Partial<VideoAssetDocument>) => {\n const {filename, playbackId, status} = asset\n return {\n title: filename || playbackId || '',\n subtitle: status ? `status: ${status}` : null,\n media: asset.playbackId ? <VideoThumbnail asset={asset} width={64} /> : null,\n }\n },\n },\n }\n}\n","export const muxVideoSchema = {\n name: 'mux.video',\n type: 'object',\n title: 'Video asset reference',\n fields: [\n {\n title: 'Video',\n name: 'asset',\n type: 'reference',\n weak: true,\n to: [{type: 'mux.videoAsset'}],\n },\n ],\n}\n\nconst muxTrack = {\n name: 'mux.track',\n type: 'object',\n fields: [\n {type: 'string', name: 'id'},\n {type: 'string', name: 'type'},\n {type: 'number', name: 'max_width'},\n {type: 'number', name: 'max_frame_rate'},\n {type: 'number', name: 'duration'},\n {type: 'number', name: 'max_height'},\n {type: 'string', name: 'language_code'},\n {type: 'string', name: 'name'},\n {type: 'string', name: 'status'},\n {type: 'string', name: 'text_source'},\n {type: 'string', name: 'text_type'},\n ],\n}\n\nconst muxPlaybackId = {\n name: 'mux.playbackId',\n type: 'object',\n fields: [\n {type: 'string', name: 'id'},\n {type: 'string', name: 'policy'},\n ],\n}\n\nconst muxStaticRenditionFile = {\n name: 'mux.staticRenditionFile',\n type: 'object',\n fields: [\n {type: 'string', name: 'name'},\n {type: 'string', name: 'ext'},\n {type: 'number', name: 'height'},\n {type: 'number', name: 'width'},\n {type: 'number', name: 'bitrate'},\n {type: 'string', name: 'filesize'},\n {type: 'string', name: 'type'},\n {type: 'string', name: 'status'},\n {type: 'string', name: 'resolution_tier'},\n {type: 'string', name: 'resolution'},\n {type: 'string', name: 'id'},\n {type: 'string', name: 'passthrough'},\n ],\n}\n\nconst muxStaticRenditions = {\n name: 'mux.staticRenditions',\n type: 'object',\n fields: [\n {type: 'string', name: 'status'},\n {\n name: 'files',\n type: 'array',\n of: [{type: 'mux.staticRenditionFile'}],\n },\n ],\n}\n\nconst muxAssetData = {\n name: 'mux.assetData',\n title: 'Mux asset data',\n type: 'object',\n fields: [\n {\n type: 'string',\n name: 'resolution_tier',\n },\n {\n type: 'string',\n name: 'upload_id',\n },\n {\n type: 'string',\n name: 'created_at',\n },\n {\n type: 'string',\n name: 'id',\n },\n {\n type: 'string',\n name: 'status',\n },\n {\n type: 'string',\n name: 'max_stored_resolution',\n },\n {\n type: 'string',\n name: 'passthrough',\n },\n {\n type: 'string',\n name: 'encoding_tier',\n },\n {\n type: 'string',\n name: 'video_quality',\n },\n {\n type: 'string',\n name: 'master_access',\n },\n {\n type: 'string',\n name: 'aspect_ratio',\n },\n {\n type: 'number',\n name: 'duration',\n },\n {\n type: 'number',\n name: 'max_stored_frame_rate',\n },\n {\n type: 'string',\n name: 'mp4_support',\n },\n {\n type: 'string',\n name: 'max_resolution_tier',\n },\n {\n name: 'tracks',\n type: 'array',\n of: [{type: 'mux.track'}],\n },\n {\n name: 'playback_ids',\n type: 'array',\n of: [{type: 'mux.playbackId'}],\n },\n {\n name: 'static_renditions',\n type: 'mux.staticRenditions',\n },\n ],\n}\n\nconst muxVideoAsset = {\n name: 'mux.videoAsset',\n type: 'document',\n title: 'Video asset',\n fields: [\n {\n type: 'string',\n name: 'status',\n },\n {\n type: 'string',\n name: 'assetId',\n },\n {\n type: 'string',\n name: 'playbackId',\n },\n {\n type: 'string',\n name: 'filename',\n },\n {\n type: 'number',\n name: 'thumbTime',\n },\n {\n type: 'mux.assetData',\n name: 'data',\n },\n ],\n}\n\nexport const schemaTypes = [\n muxTrack,\n muxPlaybackId,\n muxStaticRenditionFile,\n muxStaticRenditions,\n muxAssetData,\n muxVideoAsset,\n]\n","import {definePlugin} from 'sanity'\n\nimport createStudioTool, {DEFAULT_TOOL_CONFIG} from '../components/StudioTool'\nimport {muxVideoCustomRendering} from '../plugin'\nimport {muxVideoSchema, schemaTypes} from '../schema'\nimport type {PluginConfig, StaticRenditionResolution} from '../util/types'\nexport type {VideoAssetDocument} from '../util/types'\n\nexport const defaultConfig: PluginConfig = {\n static_renditions: [],\n mp4_support: 'none',\n video_quality: 'plus',\n max_resolution_tier: '1080p',\n normalize_audio: false,\n defaultPublic: true,\n defaultSigned: false,\n defaultDrm: false,\n tool: DEFAULT_TOOL_CONFIG,\n allowedRolesForConfiguration: [],\n acceptedMimeTypes: ['video/*', 'audio/*'],\n}\n\n/**\n * Converts legacy mp4_support configuration to static_renditions format\n */\nfunction convertLegacyConfig(config: Partial<PluginConfig>): {\n static_renditions: StaticRenditionResolution[]\n} {\n // If static_renditions is already provided, use it\n if (config.static_renditions && config.static_renditions.length > 0) {\n return {static_renditions: config.static_renditions}\n }\n\n // Convert legacy mp4_support to static_renditions\n if (config.mp4_support === 'standard') {\n return {static_renditions: ['highest']}\n }\n\n return {static_renditions: []}\n}\n\nexport const muxInput = definePlugin<Partial<PluginConfig> | void>((userConfig) => {\n // TODO: Remove this on next major version when we end support for encoding_tier\n if (typeof userConfig === 'object' && 'encoding_tier' in userConfig) {\n const deprecated_encoding_tier = userConfig.encoding_tier\n if (!userConfig.video_quality) {\n if (deprecated_encoding_tier === 'baseline') {\n userConfig.video_quality = 'basic'\n }\n if (deprecated_encoding_tier === 'smart') {\n userConfig.video_quality = 'plus'\n }\n }\n }\n const config: PluginConfig = {\n ...defaultConfig,\n ...(userConfig || {}),\n ...convertLegacyConfig(userConfig || {}),\n }\n return {\n name: 'mux-input',\n schema: {\n types: [\n ...schemaTypes,\n {\n ...muxVideoSchema,\n ...muxVideoCustomRendering(config),\n },\n ],\n },\n tools: config.tool === false ? undefined : [createStudioTool(config)],\n }\n})\n"],"names":["jsx","createContext","useState","useContext","Dialog","Stack","Button","jsxs","Card","Text","useSanityClient","words","trim","toLower","uniq","compact","createHookFromObservableFactory","useDocumentStore","useMemo","collate","defer","useCallback","path","useDocumentValues","useReducer","suspend","useId","useTheme_v2","styled","Fragment","Flex","Box","memo","useRef","clear","secretsId","preload","useEffect","FormField","TextInput","Checkbox","Code","Inline","truncateString","a","expand","timer","concatMap","of","tap","useClient","uuid","Image","Suspense","Spinner","ErrorOutlineIcon","useFormattedDuration","RetrieveIcon","InfoOutlineIcon","RetryIcon","CheckmarkCircleIcon","Heading","ChevronLeftIcon","Label","ChevronRightIcon","Radio","SyncIcon","MenuButton","SortIcon","Menu","MenuItem","useToast","LANGUAGE_OPTIONS","LanguagesList","name","UploadIcon","Autocomplete","TranslateIcon","DownloadIcon","EditIcon","TrashIcon","AddIcon","ChevronUpIcon","ChevronDownIcon","muxPlaybackId","MuxPlayer","WarningOutlineIcon","SanityDefaultPreview","useTimeAgo","document","Tooltip","TextWithTone","PublishIcon","isRecord","isValidElement","isString","isNumber","getPreviewStateObservable","useObservable","DocumentPreviewPresence","getPreviewValueWithFallback","IntentLink","useDocumentPreviewStore","useSchema","useDocumentPresence","DocumentIcon","PreviewCard","React","CheckmarkIcon","RevertIcon","TabList","Tab","SearchIcon","TabPanel","ClockIcon","CropIcon","CalendarIcon","TagIcon","LockIcon","PlayIcon","Grid","useCurrentUser","isReference","useProjectId","useDataset","useSWR","t","e","r","n","o","useErrorBoundary","scrollIntoView","PlugIcon","uploadUrl","Observable","upchunk","UpChunk","switchMap","concat","throwError","generateUuid","mergeMap","from","catchError","mergeMapTo","PatchEvent","unset","setIfMissing","set","SelectAsset","LinearProgress","css","isValidElementType","createElement","useClickOutsideEvent","Popover","ImageIcon","MenuDivider","ResetIcon","EllipsisHorizontalIcon","videoAspectRatio","u","WarningFilledIcon","_id","DocumentVideoIcon","rem","forwardRef","HiddenInput","Subject","takeUntil","PlayerActionsMenu","ErrorBoundaryCard","Input","definePlugin"],"mappings":"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","x_google_ignoreList":[48,72]}