@sanity/cross-dataset-duplicator
2.1.32.1.4
dist/index.js.map~
dist/index.js.mapModified+1−1
Index: package/dist/index.js.map
===================================================================
--- package/dist/index.js.map
+++ package/dist/index.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.js","names":["PluginConfig","SECRET_NAMESPACE","DEFAULT_CONFIG","Required","apiVersion","tool","types","filter","follow","queries","migrationFilters","createContext","useContext","LayoutProps","DEFAULT_CONFIG","PluginConfig","CrossDatasetDuplicatorContext","ConfigProviderProps","pluginConfig","Required","useCrossDatasetDuplicatorConfig","ConfigProvider","props","$","_c","T0","t0","t1","rest","Provider","renderDefault","t2","CSSProperties","createInitialMessage","docCount","refsCount","message","join","stickyStyles","isDarkMode","position","top","zIndex","backgroundColor","extractWithPath","SanityClient","SanityDocument","PluginConfig","OptionsBag","fetchIds","client","pluginConfig","currentIds","Set","projection","getDocumentsInArray","options","Promise","collection","filter","Boolean","join","query","data","fetch","length","localCurrentIds","newDataIds","map","dataDoc","_id","id","size","has","push","add","all","doc","expr","references","flatMap","ref","value","newReferenceIds","referenceDocs","Array","from","seenIds","uniqueCollection","MigrationFilter","IsAllowedMigrationTargetOptions","migrationFilters","sourceProjectId","sourceDataset","targetProjectId","targetDataset","isAllowedMigrationTarget","options","migrationFilter","find","filter","targets","some","target","dataset","projectId","Card","Text","BadgeTone","ReactNode","FeedbackProps","children","tone","Feedback","props","$","_c","t0","undefined","t1","t2","isAssetId","Button","Card","Flex","Dispatch","SetStateAction","useState","PayloadItem","Action","ButtonItem","label","action","divider","buttons","shouldInclude","item","status","doc","_id","include","SelectButtonsProps","payload","setPayload","SelectButtons","props","$","_c","t0","length","every","_temp","disabledActions","setDisabledActions","t1","handleSelectButton","current","map","item_0","t2","button","includes","t3","InfoOutlineIcon","Box","Text","Badge","BadgeTone","Tooltip","StatusTones","EXISTS","OVERWRITE","UPDATE","CREATE","UNPUBLISHED","documentTones","assetTones","MessageTypes","documentMessages","assetMessages","assetStatus","StatusBadgeProps","isAsset","status","StatusBadge","props","$","_c","badgeTone","t0","Symbol","for","badgeText","badgeStatus","maxWidth","t1","t2","t3","t4","t5","isAssetId","isSanityFileAsset","SanityAssetDocument","SanityClient","ArrowRightIcon","LaunchIcon","SearchIcon","extractWithPath","Card","Container","Text","Box","Button","Label","Stack","Select","Flex","Checkbox","CardTone","useTheme","Spinner","getTheme_v2","dset","ChangeEvent","Fragment","useEffect","useEffectEvent","useMemo","useState","useClient","Preview","useSchema","useWorkspaces","WorkspaceSummary","SanityDocument","stickyStyles","createInitialMessage","getDocumentsInArray","isAllowedMigrationTarget","PluginConfig","Feedback","SelectButtons","StatusBadge","MessageTypes","DuplicatorProps","docs","token","pluginConfig","Required","onDuplicated","Promise","PayloadItem","doc","include","status","hasDraft","WorkspaceOption","disabled","Message","text","tone","isAssetDocument","_id","mapWithConcurrency","items","T","limit","fn","item","queue","work","shift","undefined","workers","Array","from","length","Math","min","all","SetMessage","msg","isRecord","value","Record","isUnknownArray","isArray","getErrorDescription","err","details","itemDescriptions","itemDescription","push","join","message","description","isReferenceMutationError","toLowerCase","includes","getMissingReferenceIds","missingIds","rawItems","error","refId","refRegex","match","exec","id","commitOneByOne","client","setMessage","onSuccess","successCount","failCount","tx","transaction","createOrReplace","commit","commitErr","console","ReferenceErrorOptions","transactionDocs","originClient","destinationClient","depth","excludedIds","Set","svgMaps","old","new","assetDownloadInit","url","typeIsFile","RequestInit","hostname","URL","endsWith","headers","Authorization","uploadAssetForRecovery","svgMap","downloadUrl","res","fetch","ok","Error","statusText","assetData","blob","assetDoc","assets","upload","filename","originalFilename","extension","remapSvgRefs","map","original","references","structuredClone","forEach","ref","newRefValue","find","asset","path","orderDocsDependenciesFirst","byId","Map","visiting","visited","ordered","visit","has","get","add","delete","handleReferenceError","options","inheritedSvgMaps","autoFetchIds","filter","blockedIds","missingDocs","fetchIds","fetchErr","existingIds","newMissingDocs","reverse","recoveredChunks","index","uploadErr","recoveredDocs","flat","remappedRecoveredDocs","remappedTransactionDocs","allDocs","retryTransaction","retryErr","Duplicator","props","$","_c","theme","isDarkMode","sanity","color","_dark","t0","apiVersion","schema","workspaces","projectId","sourceProjectId","dataset","sourceDataset","config","workspacesOptions","workspace","isSourceWorkspace","isAllowedMigration","migrationFilters","targetProjectId","targetDataset","currentWorkspace","workspace_0","destination","setDestination","_temp","t1","Symbol","for","payload","setPayload","isDuplicating","setIsDuplicating","isGathering","setIsGathering","t2","progress","setProgress","initialRefsCount","reduce","_temp2","hasReferences","t3","initialMessage","displayMessage","t4","updatePayloadStatuses","payloadActual","dest","name","payloadIds","_temp3","withConfig","destinationData","destinationById","_temp4","existingDoc","_updatedAt","Date","t5","nextDocs","initialPayload","_temp5","catch","initializePayload","t6","t7","t8","handleCheckbox","current","item_0","t9","handleReferences","docIds","_temp6","payloadDocs","draftDocs","_temp7","projection","draftDocsIds","_temp8","payloadShaped","doc_4","t10","handleDuplicate","assetsCount","_temp9","currentProgress","destinationClient_0","processDoc","doc_6","payloadIncludedDocs","_temp0","_temp1","t11","svgIdRemap","_temp10","transactionDocsMapped","size","doc_7","mappedDoc","doc_8","onCommitSuccess","t12","_temp11","_temp12","t13","String","handleChange","e","targeted","space_0","space","currentTarget","payloadCount","findIndex","_temp13","firstSvgIndex","_temp14","selectedDocumentsCount","_temp15","selectedAssetsCount","selectedTotal","destinationTitle","title","hasMultipleProjectIds","_temp16","Boolean","t14","headingText","buttonTextParts","buttonText","t15","t16","flex","t17","t18","T0","t19","t20","t21","T1","t22","space_2","t23","t24","t25","width","transform","transformOrigin","transition","boxSizing","t26","t27","t28","t29","doc_10","include_0","status_0","schemaType","_type","t30","t31","t32","t33","t34","space_1","item_6","item_5","doc_9","item_4","item_3","next","item_2","item_1","doc_5","_id_0","doc_3","doc_2","doc_1","doc_0","acc","Button","Stack","Box","Label","Text","Card","Flex","Grid","Container","TextInput","SubmitEvent","useState","useSchema","useClient","SanityDocument","PluginConfig","Duplicator","DuplicatorQueryProps","token","pluginConfig","Required","InitialData","docs","DuplicatorQuery","props","queries","preDefinedQueries","apiVersion","originClient","schema","schemaTypes","getTypeNames","value","setValue","fetched","setFetched","initialData","setInitialData","runQuery","res","fetch","registeredAndPublishedDocs","length","filter","doc","includes","_type","_id","startsWith","err","console","error","handleSubmit","e","HTMLFormElement","preventDefault","fontFamily","event","currentTarget","map","query","label","replace","Grid","Card","Container","Button","useState","useEffect","SanityDocument","useClient","DuplicatorProps","Duplicator","DuplicatorWrapper","props","$","_c","docs","token","pluginConfig","onDuplicated","t0","Symbol","for","inbound","setInbound","follow","apiVersion","mode","setMode","length","t1","client","t2","t3","fetchInbound","firstDocId","_id","includes","inboundReferences","fetch","id","catch","console","error","t4","t5","t6","t7","Button","Flex","useCallback","useClient","SECRET_NAMESPACE","ResetSecretProps","apiVersion","ResetSecret","t0","$","_c","t1","client","t2","delete","query","catch","console","error","handleClick","t3","Symbol","for","t4","useSecrets","SettingsView","Flex","Box","Spinner","SanityDocument","useCrossDatasetDuplicatorConfig","SECRET_NAMESPACE","DuplicatorQuery","DuplicatorWrapper","Feedback","ResetSecret","secretConfigKeys","key","title","description","Secrets","bearerToken","CrossDatasetDuplicatorProps","mode","docs","onDuplicated","Promise","CrossDatasetDuplicator","props","$","_c","pluginConfig","loading","secrets","t0","Symbol","for","_temp","t1","apiVersion","t2","length","CrossDatasetDuplicatorActionProps","CrossDatasetDuplicator","CrossDatasetDuplicatorAction","props","$","_c","docs","onDuplicated","t0","LaunchIcon","useState","DocumentActionProps","CrossDatasetDuplicatorAction","DuplicateToAction","props","draft","published","dialogOpen","setDialogOpen","disabled","Boolean","title","label","dialog","type","content","onClose","onHandle","icon","action","SanityDocument","Tool","CrossDatasetDuplicator","MultiToolConfig","docs","CrossDatasetDuplicatorProps","tool","CrossDatasetDuplicatorTool","props","$","_c","t0","options","t1","t2","undefined","t3","LaunchIcon","Tool","CrossDatasetDuplicatorTool","MultiToolConfig","crossDatasetDuplicatorTool","title","name","icon","component","options","docs","definePlugin","DuplicateToAction","ConfigProvider","DEFAULT_CONFIG","crossDatasetDuplicatorTool","PluginConfig","crossDatasetDuplicator","Partial","config","pluginConfig","types","name","tools","prev","tool","studio","components","layout","props","document","actions","schemaType","includes"],"sources":["../src/helpers/constants.ts","../src/context/ConfigProvider.tsx","../src/helpers/index.ts","../src/helpers/getDocumentsInArray.ts","../src/helpers/migrationFilters.ts","../src/components/Feedback.tsx","../src/components/SelectButtons.tsx","../src/components/StatusBadge.tsx","../src/components/Duplicator.tsx","../src/components/DuplicatorQuery.tsx","../src/components/DuplicatorWrapper.tsx","../src/components/ResetSecret.tsx","../src/components/CrossDatasetDuplicator.tsx","../src/components/CrossDatasetDuplicatorAction.tsx","../src/actions/DuplicateToAction.tsx","../src/components/CrossDatasetDuplicatorTool.tsx","../src/tool/index.ts","../src/plugin.tsx"],"sourcesContent":["import type {PluginConfig} from '../types'\n\nexport const SECRET_NAMESPACE = `CrossDatasetDuplicator`\n\nexport const DEFAULT_CONFIG: Required<PluginConfig> = {\n apiVersion: '2025-02-19',\n tool: true,\n types: [],\n filter: '',\n follow: ['outbound'],\n queries: [],\n migrationFilters: [],\n}\n","import {createContext, useContext} from 'react'\nimport type {LayoutProps} from 'sanity'\n\nimport {DEFAULT_CONFIG} from '../helpers/constants'\nimport type {PluginConfig} from '../types'\n\nconst CrossDatasetDuplicatorContext = createContext(DEFAULT_CONFIG)\n\ntype ConfigProviderProps = LayoutProps & {pluginConfig: Required<PluginConfig>}\n\n/**\n * Plugin config context hook from the Cross Dataset Duplicator plugin\n * @public\n */\nexport function useCrossDatasetDuplicatorConfig() {\n const pluginConfig = useContext(CrossDatasetDuplicatorContext)\n\n return pluginConfig\n}\n\nexport function ConfigProvider(props: ConfigProviderProps) {\n const {pluginConfig, ...rest} = props\n\n return (\n <CrossDatasetDuplicatorContext.Provider value={pluginConfig}>\n {props.renderDefault(rest)}\n </CrossDatasetDuplicatorContext.Provider>\n )\n}\n","import type {CSSProperties} from 'react'\n\nexport function createInitialMessage(docCount = 0, refsCount = 0): string {\n const message = [\n docCount === 1 ? `This Document contains` : `These ${docCount} Documents contain`,\n refsCount === 1 ? `1 Reference.` : `${refsCount} References.`,\n refsCount === 1 ? `That Document` : `Those Documents`,\n `may have References too. If referenced Documents do not exist at the target Destination, this transaction will fail.`,\n ]\n\n return message.join(` `)\n}\n\nexport const stickyStyles = (isDarkMode = true): CSSProperties => ({\n position: 'sticky',\n top: 0,\n zIndex: 100,\n backgroundColor: isDarkMode ? `rgba(10,10,10,0.95)` : `rgba(255,255,255,0.95)`,\n})\n","import {extractWithPath} from '@sanity/mutator'\nimport type {SanityClient, SanityDocument} from 'sanity'\n\nimport type {PluginConfig} from '../types'\n\ntype OptionsBag = {\n fetchIds: string[]\n client: SanityClient\n pluginConfig: PluginConfig\n currentIds?: Set<string> | null\n projection?: string\n}\n\n// Recursively fetch Documents from an array of _id's and their references\n// Heavy use of Set is to avoid recursively querying for id's already in the payload\nexport async function getDocumentsInArray(options: OptionsBag): Promise<SanityDocument[]> {\n const {fetchIds, client, pluginConfig, currentIds, projection} = options\n const collection: SanityDocument[] = []\n\n // Find initial docs\n const filter = ['_id in $fetchIds', pluginConfig.filter].filter(Boolean).join(' && ')\n const query = `*[${filter}]${projection ?? ``}`\n const data = await client.fetch<SanityDocument[]>(query, {\n fetchIds: fetchIds ?? [],\n })\n\n if (!data?.length) {\n return []\n }\n\n const localCurrentIds = currentIds ?? new Set<string>()\n\n // Find new ids in the returned data\n // Unless we started with an empty set, get the _ids from the data\n const newDataIds = new Set<string>(\n data\n .map((dataDoc) => dataDoc._id)\n .filter((id) => (currentIds?.size ? !localCurrentIds.has(id) : Boolean(id))),\n )\n\n if (newDataIds.size) {\n collection.push(...data)\n for (const id of newDataIds) {\n localCurrentIds.add(id)\n }\n\n // Check new data for more references\n await Promise.all(\n data.map(async (doc) => {\n const expr = `.._ref`\n const references = extractWithPath(expr, doc).flatMap((ref) =>\n typeof ref.value === 'string' ? [ref.value] : [],\n )\n\n if (references.length) {\n // Find references not already in the Collection\n const newReferenceIds = new Set<string>(\n references.filter((ref) => !localCurrentIds.has(ref)),\n )\n\n if (newReferenceIds.size) {\n // Recursive query for new documents\n const referenceDocs = await getDocumentsInArray({\n fetchIds: Array.from(newReferenceIds),\n currentIds: localCurrentIds,\n client,\n pluginConfig,\n })\n\n if (referenceDocs?.length) {\n collection.push(...referenceDocs)\n }\n }\n }\n }),\n )\n }\n\n // Create a unique array of documents, keeping the first occurrence of each _id\n const seenIds = new Set<string>()\n const uniqueCollection: SanityDocument[] = []\n\n for (const doc of collection) {\n if (doc && !seenIds.has(doc._id)) {\n seenIds.add(doc._id)\n uniqueCollection.push(doc)\n }\n }\n\n return uniqueCollection\n}\n","import type {MigrationFilter} from '../types'\n\ntype IsAllowedMigrationTargetOptions = {\n migrationFilters: MigrationFilter[] | undefined\n sourceProjectId: string | undefined\n sourceDataset: string | undefined\n targetProjectId: string\n targetDataset: string\n}\n\n/**\n * Determine whether a Workspace is an allowed Migration destination for the\n * current source Dataset, based on the optional `migrationFilters` config.\n *\n * If no filter is configured for the source Dataset, every target is allowed\n * (the default behaviour). When a filter is configured, only the listed targets\n * are allowed.\n */\nexport function isAllowedMigrationTarget(options: IsAllowedMigrationTargetOptions): boolean {\n const {migrationFilters, sourceProjectId, sourceDataset, targetProjectId, targetDataset} = options\n\n const migrationFilter = migrationFilters?.find((filter) => filter.sourceDataset === sourceDataset)\n\n // If no migrationFilter is configured for this dataset, allow all migration targets.\n if (!migrationFilter) {\n return true\n }\n\n return migrationFilter.targets.some((target) => {\n if (target.dataset !== targetDataset) {\n return false\n }\n\n // If a project ID is configured for the target, check that it matches.\n if (target.projectId) {\n return target.projectId === targetProjectId\n }\n\n // If a project ID is not configured for the target, only allow targets in\n // the same project as the source.\n return targetProjectId === sourceProjectId\n })\n}\n","import {Card, Text} from '@sanity/ui'\nimport type {BadgeTone} from '@sanity/ui'\nimport type {ReactNode} from 'react'\n\ntype FeedbackProps = {\n children?: ReactNode\n tone?: BadgeTone\n}\n\nexport default function Feedback(props: FeedbackProps) {\n const {children, tone = 'caution'} = props\n\n return (\n <Card padding={3} radius={2} shadow={1} tone={tone}>\n <Text size={1}>{children}</Text>\n </Card>\n )\n}\n","import {isAssetId} from '@sanity/asset-utils'\nimport {Button, Card, Flex} from '@sanity/ui'\nimport {type Dispatch, type SetStateAction, useState} from 'react'\n\nimport type {PayloadItem} from './Duplicator'\n\ntype Action = 'ALL' | 'NONE' | 'NEW' | 'EXISTING' | 'OLDER' | 'ASSETS' | 'DOCUMENTS'\n\ntype ButtonItem = {label: string; action: Action} | {divider: string}\n\nconst buttons: ButtonItem[] = [\n {label: 'All', action: 'ALL'},\n {label: 'None', action: 'NONE'},\n {divider: 'divider-1'},\n {label: 'New', action: 'NEW'},\n {label: 'Existing', action: 'EXISTING'},\n {label: 'Older', action: 'OLDER'},\n {divider: 'divider-2'},\n {label: 'Documents', action: 'DOCUMENTS'},\n {label: 'Assets', action: 'ASSETS'},\n]\n\nfunction shouldInclude(item: PayloadItem, action: Action): boolean {\n switch (action) {\n case 'ALL':\n return true\n case 'NONE':\n return false\n case 'NEW':\n return item.status === 'CREATE'\n case 'EXISTING':\n return item.status === 'EXISTS'\n case 'OLDER':\n return item.status === 'OVERWRITE'\n case 'ASSETS':\n return isAssetId(item.doc._id)\n case 'DOCUMENTS':\n return !isAssetId(item.doc._id)\n default:\n return item.include\n }\n}\n\ntype SelectButtonsProps = {\n payload: PayloadItem[]\n setPayload: Dispatch<SetStateAction<PayloadItem[]>>\n}\n\nexport default function SelectButtons(props: SelectButtonsProps) {\n const {payload, setPayload} = props\n const [disabledActions, setDisabledActions] = useState<Action[]>(() =>\n payload.length && payload.every((item) => item.include) ? ['ALL'] : [],\n )\n\n function handleSelectButton(action: Action) {\n if (!payload.length) return\n\n setPayload((current) =>\n current.map((item) => ({...item, include: shouldInclude(item, action)})),\n )\n setDisabledActions([action])\n }\n\n return (\n <Card padding={1} radius={3} shadow={1}>\n <Flex gap={2} wrap=\"wrap\">\n {buttons.map((button) =>\n 'action' in button ? (\n <Button\n key={button.action}\n fontSize={1}\n mode=\"bleed\"\n padding={2}\n text={button.label}\n disabled={disabledActions.includes(button.action)}\n onClick={() => handleSelectButton(button.action)}\n />\n ) : (\n <Card key={button.divider} borderLeft />\n ),\n )}\n </Flex>\n </Card>\n )\n}\n","import {InfoOutlineIcon} from '@sanity/icons/InfoOutline'\nimport {Box, Text, Badge} from '@sanity/ui'\nimport type {BadgeTone} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\n\ntype StatusTones = {\n EXISTS: BadgeTone\n OVERWRITE: BadgeTone\n UPDATE: BadgeTone\n CREATE: BadgeTone\n UNPUBLISHED: BadgeTone\n}\n\nconst documentTones: StatusTones = {\n EXISTS: `primary`,\n OVERWRITE: `critical`,\n UPDATE: `caution`,\n CREATE: `positive`,\n UNPUBLISHED: `caution`,\n}\n\nconst assetTones: StatusTones = {\n EXISTS: `critical`,\n OVERWRITE: `critical`,\n UPDATE: `critical`,\n CREATE: `positive`,\n UNPUBLISHED: `default`,\n}\n\nexport type MessageTypes = {\n EXISTS: string\n OVERWRITE: string\n UPDATE: string\n CREATE: string\n UNPUBLISHED: string\n}\n\nconst documentMessages: MessageTypes = {\n // Only happens once document is copied the first time, and _updatedAt is the same\n EXISTS: `This document already exists at the Destination with the same ID and Updated time.`,\n // Is true immediately after transaction as _updatedAt is updated by API after mutation\n // Is also true if the document at the destination has been manually modified\n // Presently, the plugin doesn't actually compare the two documents\n OVERWRITE: `A newer version of this document exists at the Destination, and it will be overwritten with this version.`,\n // Document at destination is older\n UPDATE: `An older version of this document exists at the Destination, and it will be overwritten with this version.`,\n // Document at destination doesn't exist\n CREATE: `This document will be created at the destination.`,\n UNPUBLISHED: `A Draft version of this Document exists in this Dataset, but only the Published version will be duplicated to the destination.`,\n}\n\nconst assetMessages: MessageTypes = {\n EXISTS: `This Asset already exists at the Destination`,\n OVERWRITE: `This Asset already exists at the Destination`,\n UPDATE: `This Asset already exists at the Destination`,\n CREATE: `This Asset does not yet exist at the Destination`,\n UNPUBLISHED: ``,\n}\n\nconst assetStatus: MessageTypes = {\n EXISTS: `RE-UPLOAD`,\n OVERWRITE: `RE-UPLOAD`,\n UPDATE: `RE-UPLOAD`,\n CREATE: `UPLOAD`,\n UNPUBLISHED: ``,\n}\n\ntype StatusBadgeProps = {\n isAsset: boolean\n status?: keyof MessageTypes\n}\n\nexport default function StatusBadge(props: StatusBadgeProps) {\n const {status, isAsset} = props\n\n if (!status) {\n return null\n }\n\n const badgeTone = isAsset ? assetTones[status] : documentTones[status]\n\n if (!badgeTone) {\n return (\n <Badge padding={2} fontSize={1}>\n Checking...\n </Badge>\n )\n }\n\n const badgeText = isAsset ? assetMessages[status] : documentMessages[status]\n const badgeStatus = isAsset ? assetStatus[status] : status\n\n return (\n <Tooltip\n content={\n <Box padding={3} style={{maxWidth: 200}}>\n <Text size={1}>{badgeText}</Text>\n </Box>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <Badge padding={3} fontSize={1} tone={badgeTone}>\n {badgeStatus}\n <Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>\n </Badge>\n </Tooltip>\n )\n}\n","import {isAssetId, isSanityFileAsset} from '@sanity/asset-utils'\nimport type {SanityAssetDocument, SanityClient} from '@sanity/client'\nimport {ArrowRightIcon} from '@sanity/icons/ArrowRight'\nimport {LaunchIcon} from '@sanity/icons/Launch'\nimport {SearchIcon} from '@sanity/icons/Search'\nimport {extractWithPath} from '@sanity/mutator'\nimport {\n Card,\n Container,\n Text,\n Box,\n Button,\n Label,\n Stack,\n Select,\n Flex,\n Checkbox,\n type CardTone,\n useTheme,\n Spinner,\n} from '@sanity/ui'\nimport {getTheme_v2} from '@sanity/ui/theme'\nimport {dset} from 'dset'\nimport {type ChangeEvent, Fragment, useEffect, useEffectEvent, useMemo, useState} from 'react'\nimport {\n useClient,\n Preview,\n useSchema,\n useWorkspaces,\n type WorkspaceSummary,\n type SanityDocument,\n} from 'sanity'\n\nimport {stickyStyles, createInitialMessage} from '../helpers'\nimport {getDocumentsInArray} from '../helpers/getDocumentsInArray'\nimport {isAllowedMigrationTarget} from '../helpers/migrationFilters'\nimport type {PluginConfig} from '../types'\nimport Feedback from './Feedback'\nimport SelectButtons from './SelectButtons'\nimport StatusBadge, {type MessageTypes} from './StatusBadge'\n\nexport type DuplicatorProps = {\n docs: SanityDocument[]\n token: string\n pluginConfig: Required<PluginConfig>\n onDuplicated?: () => Promise<void>\n}\n\nexport type PayloadItem = {\n doc: SanityDocument\n include: boolean\n status?: keyof MessageTypes\n hasDraft?: boolean\n}\n\ntype WorkspaceOption = WorkspaceSummary & {\n disabled: boolean\n}\n\ntype Message = {\n text: string\n tone: CardTone\n}\n\nfunction isAssetDocument(doc: SanityDocument): doc is SanityDocument & SanityAssetDocument {\n return isAssetId(doc._id)\n}\n\n// Run an async function over every item with a maximum concurrency\nasync function mapWithConcurrency<T>(\n items: T[],\n limit: number,\n fn: (item: T) => Promise<void>,\n): Promise<void> {\n const queue = [...items]\n\n async function work(): Promise<void> {\n const item = queue.shift()\n\n if (item === undefined) {\n return undefined\n }\n\n await fn(item)\n\n return work()\n }\n\n const workers = Array.from({length: Math.min(limit, queue.length)}, () => work())\n\n await Promise.all(workers)\n}\n\ntype SetMessage = (msg: Message) => void\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction isUnknownArray(value: unknown): value is unknown[] {\n return Array.isArray(value)\n}\n\n// Pull a human-readable description out of a Sanity mutation error.\n// Prefer the richest text available: item-level descriptions (which carry the\n// \"references non-existent document\" phrasing) over a possibly-generic top-level\n// `details.description` like \"Mutation(s) failed with N error(s)\".\nfunction getErrorDescription(err: unknown): string {\n if (!isRecord(err)) {\n return ''\n }\n\n const details = err['details']\n const itemDescriptions: string[] = []\n\n if (isRecord(details) && isUnknownArray(details['items'])) {\n for (const item of details['items']) {\n if (isRecord(item) && isRecord(item['error'])) {\n const itemDescription = item['error']['description']\n\n if (typeof itemDescription === 'string' && itemDescription) {\n itemDescriptions.push(itemDescription)\n }\n }\n }\n }\n\n if (itemDescriptions.length) {\n return itemDescriptions.join('\\n')\n }\n\n const message = err['message']\n\n if (typeof message === 'string' && message) {\n return message\n }\n\n if (isRecord(details)) {\n const description = details['description']\n\n if (typeof description === 'string') {\n return description\n }\n }\n\n return ''\n}\n\nfunction isReferenceMutationError(err: unknown): boolean {\n if (!isRecord(err)) {\n return false\n }\n\n const details = err['details']\n\n // Most reliable: structured mutation item type from the Content Lake API\n if (isRecord(details) && isUnknownArray(details['items'])) {\n for (const item of details['items']) {\n if (isRecord(item) && isRecord(item['error'])) {\n if (item['error']['type'] === 'documentReferenceDoesNotExistError') {\n return true\n }\n\n const itemDescription = item['error']['description']\n\n if (\n typeof itemDescription === 'string' &&\n (itemDescription.toLowerCase().includes('references non-existent document') ||\n itemDescription.toLowerCase().includes('reference non-existent'))\n ) {\n return true\n }\n }\n }\n }\n\n const description = getErrorDescription(err).toLowerCase()\n\n return (\n description.includes('references non-existent document') ||\n description.includes('reference non-existent')\n )\n}\n\n// Collect the _id's of referenced documents that are missing at the destination,\n// reading both the structured error payload and the human-readable description\nfunction getMissingReferenceIds(err: unknown, description: string): string[] {\n const missingIds: string[] = []\n\n const details = isRecord(err) ? err['details'] : undefined\n const rawItems = isRecord(details) ? details['items'] : undefined\n const items = isUnknownArray(rawItems) ? rawItems : []\n\n for (const item of items) {\n if (isRecord(item)) {\n const error = item['error']\n\n if (isRecord(error)) {\n // Sanity returns `referenceID`; keep the other spellings as fallbacks\n const refId = error['referenceID'] ?? error['referencedId'] ?? error['referenceId']\n\n if (typeof refId === 'string' && !missingIds.includes(refId)) {\n missingIds.push(refId)\n }\n }\n }\n }\n\n const refRegex = /references non-existent document [`'\"]?([^`'\"\\s)]+)[`'\"]?/gi\n let match = refRegex.exec(description)\n\n while (match !== null) {\n const id = match[1]\n\n if (id && !missingIds.includes(id)) {\n missingIds.push(id)\n }\n\n match = refRegex.exec(description)\n }\n\n return missingIds\n}\n\n// Commit documents individually so a single failing document doesn't block the rest.\n// Runs sequentially (concurrency 1) so referenced documents can land before the\n// documents that point at them.\nasync function commitOneByOne(\n docs: SanityDocument[],\n client: SanityClient,\n setMessage: SetMessage,\n onSuccess: () => void,\n): Promise<void> {\n let successCount = 0\n let failCount = 0\n\n await mapWithConcurrency(docs, 1, async (doc) => {\n try {\n const tx = client.transaction()\n tx.createOrReplace(doc)\n await tx.commit()\n successCount += 1\n } catch (commitErr) {\n failCount += 1\n console.error(`Failed to duplicate document \"${doc._id}\"`, commitErr)\n }\n })\n\n if (failCount === 0) {\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n onSuccess()\n\n return\n }\n\n setMessage({\n tone: 'critical',\n text: `Duplication finished with ${failCount} error(s). ${successCount} document(s) duplicated successfully.`,\n })\n\n if (successCount > 0) {\n onSuccess()\n }\n}\n\ntype ReferenceErrorOptions = {\n err: unknown\n transactionDocs: SanityDocument[]\n originClient: SanityClient\n destinationClient: SanityClient\n pluginConfig: Required<PluginConfig>\n token: string\n setMessage: SetMessage\n onSuccess: () => void\n /** Caps recursive recovery so a pathological reference loop can't hang forever */\n depth?: number\n /** Document ids the user explicitly deselected — never auto-commit these during recovery */\n excludedIds?: Set<string>\n /**\n * SVG _id remaps already applied by the caller. Recovered documents are fetched\n * fresh from the origin, so they still point at origin SVG _id's that only exist\n * at the destination under their uploaded _id.\n */\n svgMaps?: {old: string; new: string}[]\n}\n\n// Only attach the studio token when downloading from a Sanity host so a crafted\n// asset `url` cannot exfiltrate credentials to an attacker-controlled endpoint.\nfunction assetDownloadInit(url: string, token: string, typeIsFile: boolean): RequestInit {\n if (typeIsFile) {\n return {}\n }\n\n try {\n const {hostname} = new URL(url)\n\n if (hostname === 'cdn.sanity.io' || hostname.endsWith('.sanity.io')) {\n return {headers: {Authorization: `Bearer ${token}`}}\n }\n } catch {\n // Invalid URL — fetch without credentials\n }\n\n return {}\n}\n\n// Upload a recovered asset to the destination, rewriting url/path for the new dataset\nasync function uploadAssetForRecovery(\n doc: SanityDocument & SanityAssetDocument,\n destinationClient: SanityClient,\n token: string,\n): Promise<{docs: SanityDocument[]; svgMap?: {old: string; new: string}}> {\n const typeIsFile = isSanityFileAsset(doc)\n const downloadUrl = typeIsFile ? doc.url : `${doc.url}?dlRaw=true`\n\n const res = await fetch(downloadUrl, assetDownloadInit(downloadUrl, token, typeIsFile))\n\n if (!res.ok) {\n throw new Error(\n `Failed to download asset \"${doc._id}\" from origin (${res.status} ${res.statusText})`,\n )\n }\n\n const assetData = await res.blob()\n const assetDoc = await destinationClient.assets.upload(typeIsFile ? `file` : `image`, assetData, {\n filename: doc.originalFilename,\n })\n\n // Merge the original asset document's editorial metadata (e.g. `altText`) with\n // the uploaded asset's canonical fields, matching the main duplication path.\n // Keeping this to a single document at the uploaded `_id` avoids leaving an\n // orphaned asset behind when an SVG's `_id` changes on upload; references are\n // repointed via `svgMap`.\n return {\n docs: [{...doc, ...assetDoc}],\n svgMap: doc.extension === 'svg' ? {old: doc._id, new: assetDoc._id} : undefined,\n }\n}\n\n// Rewrite _ref values that point at remapped SVG asset ids.\n// Clones each doc so caller-held / payload objects are not mutated.\nfunction remapSvgRefs(\n docs: SanityDocument[],\n svgMaps: {old: string; new: string}[],\n): SanityDocument[] {\n if (!svgMaps.length) {\n return docs\n }\n\n return docs.map((original) => {\n const references = extractWithPath(`.._ref`, original)\n\n if (!references.length) {\n return original\n }\n\n const doc = structuredClone(original)\n\n references.forEach((ref) => {\n const newRefValue = svgMaps.find((asset) => asset.old === ref.value)?.new\n\n if (newRefValue) {\n dset(doc, ref.path.join('.'), newRefValue)\n }\n })\n\n return doc\n })\n}\n\n// Order docs so referenced documents come before the documents that point at\n// them. Used by the sequential one-by-one fallback where commit order matters.\nfunction orderDocsDependenciesFirst(docs: SanityDocument[]): SanityDocument[] {\n const byId = new Map(docs.map((doc) => [doc._id, doc]))\n const visiting = new Set<string>()\n const visited = new Set<string>()\n const ordered: SanityDocument[] = []\n\n function visit(id: string): void {\n if (visited.has(id) || visiting.has(id)) {\n return\n }\n\n const doc = byId.get(id)\n\n if (!doc) {\n return\n }\n\n visiting.add(id)\n\n for (const ref of extractWithPath(`.._ref`, doc)) {\n if (typeof ref.value === 'string') {\n visit(ref.value)\n }\n }\n\n visiting.delete(id)\n visited.add(id)\n ordered.push(doc)\n }\n\n for (const doc of docs) {\n visit(doc._id)\n }\n\n return ordered\n}\n\n// When a transaction fails because of missing references, fetch the referenced\n// documents (and their transitive refs) from the origin — respecting\n// pluginConfig.filter — upload any assets, then retry. Falls back to one-by-one\n// commits if the retry still fails.\nasync function handleReferenceError(options: ReferenceErrorOptions): Promise<void> {\n const {\n err,\n transactionDocs,\n originClient,\n destinationClient,\n pluginConfig,\n token,\n setMessage,\n onSuccess,\n depth = 0,\n excludedIds = new Set(),\n svgMaps: inheritedSvgMaps = [],\n } = options\n const description = getErrorDescription(err)\n const missingIds = getMissingReferenceIds(err, description)\n\n // If the only missing refs are ones the user deselected, surface that instead of\n // silently re-committing them\n const autoFetchIds = missingIds.filter((id) => !excludedIds.has(id))\n const blockedIds = missingIds.filter((id) => excludedIds.has(id))\n\n if (blockedIds.length && !autoFetchIds.length) {\n setMessage({\n tone: 'critical',\n text: `Duplication failed because deselected document(s) are still referenced: ${blockedIds.join(', ')}. Re-select them or remove the references.`,\n })\n\n return\n }\n\n if (!missingIds.length || depth >= 5) {\n // Couldn't parse the missing _id's (or we hit the recursion cap) — retry each document on its own\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(\n orderDocsDependenciesFirst(transactionDocs),\n destinationClient,\n setMessage,\n onSuccess,\n )\n\n return\n }\n\n setMessage({\n tone: 'default',\n text: `Fetching ${autoFetchIds.length} missing referenced document(s) and retrying...`,\n })\n\n let missingDocs: SanityDocument[] = []\n\n try {\n // Recursively gather referenced docs (and apply pluginConfig.filter), same\n // as the \"Gather References\" path — so nested refs aren't left behind\n missingDocs = await getDocumentsInArray({\n fetchIds: autoFetchIds,\n client: originClient,\n pluginConfig,\n })\n } catch (fetchErr) {\n setMessage({\n tone: 'critical',\n text:\n (fetchErr instanceof Error ? fetchErr.message : '') || description || 'Duplication Failed',\n })\n\n return\n }\n\n if (!missingDocs.length) {\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(\n orderDocsDependenciesFirst(transactionDocs),\n destinationClient,\n setMessage,\n onSuccess,\n )\n\n return\n }\n\n // Don't re-commit documents already in the failed transaction, or ones the\n // user explicitly deselected (including transitive refs of those)\n const existingIds = new Set(transactionDocs.map((doc) => doc._id))\n // Reverse so transitive refs (appended last by getDocumentsInArray) are processed first\n const newMissingDocs = [...missingDocs]\n .reverse()\n .filter((doc) => !existingIds.has(doc._id) && !excludedIds.has(doc._id))\n\n // Nothing new to add — retrying the same transaction would just loop until the depth cap\n if (!newMissingDocs.length) {\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(\n orderDocsDependenciesFirst(transactionDocs),\n destinationClient,\n setMessage,\n onSuccess,\n )\n\n return\n }\n\n setMessage({tone: 'default', text: `Duplicating ${newMissingDocs.length} missing document(s)...`})\n\n // Seed with the caller's remaps so recovered documents referencing an SVG that\n // was uploaded earlier are repointed at its destination _id, even when that\n // asset isn't re-fetched here (e.g. `pluginConfig.filter` excludes assets)\n const svgMaps: {old: string; new: string}[] = [...inheritedSvgMaps]\n\n // Process with the same concurrency limit as the main duplication path, while\n // writing into index slots so dependency-first order is preserved\n const recoveredChunks: SanityDocument[][] = Array.from({length: newMissingDocs.length}, () => [])\n\n try {\n await mapWithConcurrency(\n newMissingDocs.map((doc, index) => ({doc, index})),\n 3,\n async ({doc, index}) => {\n if (!isAssetDocument(doc)) {\n recoveredChunks[index] = [doc]\n\n return\n }\n\n const {docs, svgMap} = await uploadAssetForRecovery(doc, destinationClient, token)\n recoveredChunks[index] = docs\n\n if (svgMap) {\n svgMaps.push(svgMap)\n }\n },\n )\n } catch (uploadErr) {\n setMessage({\n tone: 'critical',\n text:\n (uploadErr instanceof Error ? uploadErr.message : '') ||\n description ||\n 'Duplication Failed',\n })\n\n return\n }\n\n const recoveredDocs = recoveredChunks.flat()\n\n // Remap SVG _ref's in both recovered and original transaction docs\n const remappedRecoveredDocs = remapSvgRefs(recoveredDocs, svgMaps)\n const remappedTransactionDocs = remapSvgRefs(transactionDocs, svgMaps)\n\n // Put recovered (referenced) docs first so sequential commits land\n // dependencies before the documents that point at them\n const allDocs = orderDocsDependenciesFirst([...remappedRecoveredDocs, ...remappedTransactionDocs])\n\n const retryTransaction = destinationClient.transaction()\n allDocs.forEach((doc) => retryTransaction.createOrReplace(doc))\n\n try {\n await retryTransaction.commit()\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n onSuccess()\n } catch (retryErr) {\n if (isReferenceMutationError(retryErr)) {\n // Another layer of missing refs — recurse with the expanded set\n await handleReferenceError({\n ...options,\n err: retryErr,\n transactionDocs: allDocs,\n depth: depth + 1,\n svgMaps,\n })\n\n return\n }\n\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(allDocs, destinationClient, setMessage, onSuccess)\n }\n}\n\nexport default function Duplicator(props: DuplicatorProps) {\n const {docs, token, pluginConfig, onDuplicated} = props\n const theme = useTheme()\n const isDarkMode = getTheme_v2({sanity: theme.sanity}).color._dark\n\n // Prepare origin (this Studio) client\n const originClient = useClient({apiVersion: pluginConfig.apiVersion})\n\n const schema = useSchema()\n\n // Create list of dataset options\n // and set initial value of dropdown\n const workspaces = useWorkspaces()\n const {projectId: sourceProjectId, dataset: sourceDataset} = originClient.config()\n const workspacesOptions: WorkspaceOption[] = workspaces.map((workspace) => {\n const isSourceWorkspace =\n workspace.projectId === sourceProjectId && workspace.dataset === sourceDataset\n const isAllowedMigration = isAllowedMigrationTarget({\n migrationFilters: pluginConfig.migrationFilters,\n sourceProjectId,\n sourceDataset,\n targetProjectId: workspace.projectId,\n targetDataset: workspace.dataset,\n })\n\n return {\n ...workspace,\n disabled: isSourceWorkspace || !isAllowedMigration,\n }\n })\n\n const currentWorkspace = workspacesOptions.find(\n (workspace) => workspace.projectId === sourceProjectId && workspace.dataset === sourceDataset,\n )\n\n const [destination, setDestination] = useState<WorkspaceOption | null>(\n workspaces.length ? (workspacesOptions.find((space) => !space.disabled) ?? null) : null,\n )\n const [message, setMessage] = useState<Message | null>(null)\n const [payload, setPayload] = useState<PayloadItem[]>([])\n\n const [isDuplicating, setIsDuplicating] = useState(false)\n const [isGathering, setIsGathering] = useState(false)\n const [progress, setProgress] = useState<[number, number]>([0, 0])\n\n // References found in the initial docs\n const initialRefsCount = useMemo(\n () => docs.reduce((acc, doc) => acc + extractWithPath(`.._ref`, doc).length, 0),\n [docs],\n )\n const hasReferences = initialRefsCount > 0\n const initialMessage: Message | null = hasReferences\n ? {tone: `caution`, text: createInitialMessage(docs.length, initialRefsCount)}\n : null\n const displayMessage = message ?? initialMessage\n\n // Check if payload documents exist at destination\n async function updatePayloadStatuses(payloadActual: PayloadItem[], dest: WorkspaceOption | null) {\n if (!payloadActual.length || !dest?.name) {\n return\n }\n\n const payloadIds = payloadActual.map(({doc}) => doc._id)\n const destinationClient = originClient.withConfig({\n dataset: dest.dataset,\n projectId: dest.projectId,\n })\n const destinationData = await destinationClient.fetch<SanityDocument[]>(\n `*[_id in $payloadIds]{ _id, _updatedAt }`,\n {payloadIds},\n )\n // Index the destination docs by `_id` so status updates stay O(n) instead\n // of O(n²) when looking them up for each payload item below.\n const destinationById = new Map(destinationData.map((doc) => [doc._id, doc]))\n\n setPayload(\n payloadActual.map((item) => {\n const existingDoc = destinationById.get(item.doc._id)\n let status: keyof MessageTypes = 'CREATE'\n\n if (existingDoc?._updatedAt && item.doc._updatedAt) {\n if (existingDoc._updatedAt === item.doc._updatedAt) {\n // Exact same document exists at destination\n // We don't compare by _rev because that is updated in a transaction\n status = `EXISTS`\n } else {\n status =\n new Date(existingDoc._updatedAt) > new Date(item.doc._updatedAt)\n ? // Document at destination is newer\n `OVERWRITE`\n : // Document at destination is older\n `UPDATE`\n }\n }\n\n return {...item, status}\n }),\n )\n }\n\n // Build the initial payload and check statuses at the current destination\n const initializePayload = useEffectEvent((nextDocs: SanityDocument[]) => {\n const initialPayload: PayloadItem[] = nextDocs.map((doc) => ({include: true, doc}))\n updatePayloadStatuses(initialPayload, destination).catch(console.error)\n })\n\n // Sync the payload with the docs prop and the destination dataset.\n // setPayload only runs after fetching document statuses from the\n // destination resolves, not synchronously within the effect.\n // See: https://github.com/facebook/react/issues/34743\n useEffect(() => {\n // oxlint-disable-next-line react/set-state-in-effect\n initializePayload(docs)\n }, [docs])\n\n function handleCheckbox(_id: string) {\n setPayload((current) =>\n current.map((item) => (item.doc._id === _id ? {...item, include: !item.include} : item)),\n )\n }\n\n // Find and recursively follow references beginning with this document\n async function handleReferences() {\n setIsGathering(true)\n\n try {\n const docIds = docs.map((doc) => doc._id)\n\n const payloadDocs = await getDocumentsInArray({\n fetchIds: docIds,\n client: originClient,\n pluginConfig,\n })\n const draftDocs = await getDocumentsInArray({\n fetchIds: docIds.map((id) => `drafts.${id}`),\n client: originClient,\n projection: `{_id}`,\n pluginConfig,\n })\n const draftDocsIds = new Set(draftDocs.map(({_id}) => _id))\n\n // Shape it up\n const payloadShaped: PayloadItem[] = payloadDocs.map((doc) => ({\n doc,\n // Include this in the transaction?\n include: true,\n // Does it exist at the destination?\n status: undefined,\n // Does it have any drafts?\n hasDraft: draftDocsIds.has(`drafts.${doc._id}`),\n }))\n\n setPayload(payloadShaped)\n updatePayloadStatuses(payloadShaped, destination).catch(console.error)\n } catch (err) {\n console.error(err)\n }\n\n setIsGathering(false)\n }\n\n // Duplicate payload to destination dataset\n async function handleDuplicate() {\n if (!destination) {\n return\n }\n\n setIsDuplicating(true)\n\n const assetsCount = payload.filter(({doc, include}) => include && isAssetId(doc._id)).length\n let currentProgress = 0\n setProgress([currentProgress, assetsCount])\n\n setMessage({text: 'Duplicating...', tone: `transparent`})\n\n const destinationClient = originClient.withConfig({\n apiVersion: pluginConfig.apiVersion,\n dataset: destination.dataset,\n projectId: destination.projectId,\n })\n\n const transactionDocs: SanityDocument[] = []\n const svgMaps: {old: string; new: string}[] = []\n\n // Upload assets and then add to transaction\n async function processDoc(doc: SanityDocument): Promise<void> {\n if (!isAssetDocument(doc)) {\n transactionDocs.push(doc)\n\n return\n }\n\n // Download and upload asset\n // Get the *original* image with this dlRaw param to create the same deterministic _id\n const typeIsFile = isSanityFileAsset(doc)\n const downloadUrl = typeIsFile ? doc.url : `${doc.url}?dlRaw=true`\n\n const res = await fetch(downloadUrl, assetDownloadInit(downloadUrl, token, typeIsFile))\n\n // Fail fast instead of uploading an error response (e.g. 401/403/404)\n // body as the asset's binary data.\n if (!res.ok) {\n throw new Error(\n `Failed to download asset \"${doc.originalFilename ?? doc._id}\" (${res.status} ${res.statusText})`,\n )\n }\n\n const assetData = await res.blob()\n\n const options = {filename: doc.originalFilename}\n const assetDoc = await destinationClient.assets.upload(\n typeIsFile ? `file` : `image`,\n assetData,\n options,\n )\n\n // SVG _id's need remapping before transaction\n if (doc.extension === 'svg') {\n svgMaps.push({old: doc._id, new: assetDoc._id})\n }\n\n // Merge the original asset document's editorial metadata (e.g. `altText`,\n // `title`) — which the upload response omits — with the canonical fields of\n // the freshly uploaded asset (`_id`, `url`, `path`, `assetId`, `sha1hash`,\n // ...). The uploaded values win, so `url`/`path` no longer reference the\n // origin dataset. For SVGs the uploaded `_id` differs from the source\n // (the file is sanitized on upload), so pushing a single merged document at\n // the new `_id` — and remapping references to it below — avoids leaving an\n // orphaned asset document behind at the original `_id`.\n transactionDocs.push({...doc, ...assetDoc})\n\n currentProgress += 1\n setMessage({\n text: `Duplicating ${currentProgress}/${assetsCount} Assets`,\n tone: 'default',\n })\n setProgress([currentProgress, assetsCount])\n }\n\n try {\n const payloadIncludedDocs = payload.filter((item) => item.include).map((item) => item.doc)\n\n // Promises are limited to three at once\n await mapWithConcurrency(payloadIncludedDocs, 3, processDoc)\n } catch (err) {\n console.error(err)\n setIsDuplicating(false)\n setProgress([0, 0])\n setMessage({\n tone: 'critical',\n text: err instanceof Error ? err.message : `Duplication Failed`,\n })\n\n return\n }\n\n // Remap SVG references to new _id's. SVG assets are sanitized on upload, so\n // their `_id` changes; references still pointing at the original `_id` must\n // be updated to the uploaded one.\n const svgIdRemap = new Map(svgMaps.map(({old, new: next}) => [old, next]))\n const transactionDocsMapped =\n svgIdRemap.size === 0\n ? transactionDocs\n : transactionDocs.map((doc) => {\n const references = extractWithPath(`.._ref`, doc)\n\n if (!references.length) {\n return doc\n }\n\n // Clone lazily before the first mutation: some of these docs are the\n // same objects held in React state (`payload`), and `dset` mutates in\n // place — which would corrupt state and trip up the React Compiler.\n let mappedDoc = doc\n\n references.forEach((ref) => {\n const newRefValue =\n typeof ref.value === 'string' ? svgIdRemap.get(ref.value) : undefined\n\n if (newRefValue) {\n if (mappedDoc === doc) {\n mappedDoc = structuredClone(doc)\n }\n\n dset(mappedDoc, ref.path.join('.'), newRefValue)\n }\n })\n\n return mappedDoc\n })\n\n // Create transaction\n const transaction = destinationClient.transaction()\n\n transactionDocsMapped.forEach((doc) => {\n transaction.createOrReplace(doc)\n })\n\n const onCommitSuccess = () => {\n updatePayloadStatuses(payload, destination).catch(console.error)\n }\n\n try {\n await transaction.commit()\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n\n onCommitSuccess()\n } catch (err) {\n if (isReferenceMutationError(err)) {\n await handleReferenceError({\n err,\n transactionDocs: transactionDocsMapped,\n originClient,\n destinationClient,\n pluginConfig,\n token,\n setMessage,\n onSuccess: onCommitSuccess,\n excludedIds: new Set(payload.filter((item) => !item.include).map((item) => item.doc._id)),\n svgMaps,\n })\n } else {\n const description = getErrorDescription(err)\n setMessage({\n tone: 'critical',\n text: description || `Duplication Failed`,\n })\n }\n }\n\n setIsDuplicating(false)\n setProgress([0, 0])\n if (onDuplicated) {\n try {\n await onDuplicated()\n } catch (error) {\n const text = error instanceof Error ? error.message : String(error)\n setMessage({tone: 'critical', text: `Error in onDuplicated hook: ${text}`})\n }\n }\n }\n\n function handleChange(e: ChangeEvent<HTMLSelectElement>) {\n if (!workspacesOptions.length) {\n return\n }\n\n const targeted = workspacesOptions.find((space) => space.name === e.currentTarget.value)\n\n if (targeted) {\n setDestination(targeted)\n updatePayloadStatuses(payload, targeted).catch(console.error)\n }\n }\n\n const payloadCount = payload.length\n const firstSvgIndex = payload.findIndex(({doc}) => doc['extension'] === 'svg')\n const selectedDocumentsCount = payload.filter(\n (item) => item.include && !isAssetId(item.doc._id),\n ).length\n const selectedAssetsCount = payload.filter(\n (item) => item.include && isAssetId(item.doc._id),\n ).length\n const selectedTotal = selectedDocumentsCount + selectedAssetsCount\n const destinationTitle = destination?.title ?? destination?.name\n const hasMultipleProjectIds =\n new Set(workspacesOptions.map((space) => space?.projectId).filter(Boolean)).size > 1\n\n const headingText = [selectedTotal, `/`, payloadCount, `Documents and Assets selected`].join(` `)\n\n const buttonTextParts = [`Duplicate`]\n\n if (selectedDocumentsCount > 0) {\n buttonTextParts.push(\n String(selectedDocumentsCount),\n selectedDocumentsCount === 1 ? `Document` : `Documents`,\n )\n }\n\n if (selectedAssetsCount > 0) {\n // Only join with \"and\" when documents are also part of the selection.\n if (selectedDocumentsCount > 0) {\n buttonTextParts.push(`and`)\n }\n\n buttonTextParts.push(\n String(selectedAssetsCount),\n selectedAssetsCount === 1 ? `Asset` : `Assets`,\n )\n }\n\n if (originClient.config().projectId !== destination?.projectId) {\n buttonTextParts.push(`between Projects`)\n }\n\n buttonTextParts.push(`to`, String(destinationTitle))\n\n const buttonText = buttonTextParts.join(` `)\n\n if (workspacesOptions.length < 2) {\n return (\n <Feedback tone=\"critical\">\n <code>sanity.config.ts</code> must contain at least two Workspaces to use this plugin.\n </Feedback>\n )\n }\n\n if (!destination) {\n return (\n <Feedback tone=\"critical\">\n No allowed Migration destinations are available for this Dataset. Check the{' '}\n <code>migrationFilters</code> plugin config, or add another Workspace as a valid target.\n </Feedback>\n )\n }\n\n return (\n <Container width={1}>\n <Card border>\n <Stack>\n <Card padding={4} style={stickyStyles(isDarkMode)}>\n <Stack gap={4}>\n <Flex gap={3}>\n <Stack style={{flex: 1}} gap={3}>\n <Label>Duplicate from</Label>\n <Select readOnly value={currentWorkspace?.name}>\n {currentWorkspace ? (\n <option value={currentWorkspace.name}>\n {currentWorkspace.title ?? currentWorkspace.name}\n {hasMultipleProjectIds ? ` (${currentWorkspace.projectId})` : ``}\n </option>\n ) : null}\n </Select>\n </Stack>\n <Box padding={4} paddingTop={5} paddingBottom={0}>\n <Text size={3}>\n <ArrowRightIcon />\n </Text>\n </Box>\n <Stack style={{flex: 1}} gap={3}>\n <Label>To Destination</Label>\n <Select onChange={handleChange}>\n {workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))}\n </Select>\n </Stack>\n </Flex>\n\n {isDuplicating && (\n <Card border radius={2}>\n <Card\n style={{\n width: '100%',\n // Guard against a 0-asset payload (progress[1] === 0),\n // which would make the ratio NaN and produce an invalid transform.\n transform: `scaleX(${progress[1] > 0 ? progress[0] / progress[1] : 0})`,\n transformOrigin: 'left',\n transition: 'transform .2s ease',\n boxSizing: 'border-box',\n }}\n padding={1}\n tone=\"positive\"\n />\n </Card>\n )}\n {payload.length > 0 && (\n <>\n <Label>{headingText}</Label>\n <SelectButtons payload={payload} setPayload={setPayload} />\n </>\n )}\n </Stack>\n </Card>\n <Card borderTop padding={4}>\n <Stack gap={3}>\n {displayMessage && (\n <Card padding={3} radius={2} shadow={1} tone={displayMessage.tone}>\n <Text size={1}>{displayMessage.text}</Text>\n </Card>\n )}\n {payload.length > 0 ? (\n <Stack>\n {payload.map(({doc, include, status, hasDraft}, index) => {\n const schemaType = schema.get(doc._type)\n\n return (\n <Fragment key={doc._id}>\n <Flex align=\"center\">\n <Checkbox checked={include} onChange={() => handleCheckbox(doc._id)} />\n <Box flex={1} paddingX={3}>\n {schemaType ? (\n <Preview value={doc} schemaType={schemaType} />\n ) : (\n <Card tone=\"caution\">Invalid schema type</Card>\n )}\n </Box>\n <Flex align=\"center\" gap={2}>\n {hasDraft ? <StatusBadge status=\"UNPUBLISHED\" isAsset={false} /> : null}\n <StatusBadge status={status} isAsset={isAssetId(doc._id)} />\n </Flex>\n </Flex>\n {doc['extension'] === 'svg' && index === firstSvgIndex && (\n <Card padding={3} radius={2} shadow={1} tone=\"caution\">\n <Text size={1}>\n Due to how SVGs are sanitized after first uploaded, duplicated SVG\n assets may have new <code>_id</code>'s at the destination. The newly\n generated <code>_id</code> will be the same in each duplication, but\n it will never be the same <code>_id</code> as the first time this\n Asset was uploaded. References to the asset will be updated to use the\n new <code>_id</code>.\n </Text>\n </Card>\n )}\n </Fragment>\n )\n })}\n </Stack>\n ) : (\n <Flex padding={4} align=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n )}\n <Stack gap={2}>\n {hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )}\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n </Stack>\n </Stack>\n </Card>\n </Stack>\n </Card>\n </Container>\n )\n}\n","import {Button, Stack, Box, Label, Text, Card, Flex, Grid, Container, TextInput} from '@sanity/ui'\nimport {type SubmitEvent, useState} from 'react'\nimport {useSchema, useClient, type SanityDocument} from 'sanity'\n\nimport type {PluginConfig} from '../types'\nimport Duplicator from './Duplicator'\n\ntype DuplicatorQueryProps = {\n token: string\n pluginConfig: Required<PluginConfig>\n}\n\ntype InitialData = {\n docs: SanityDocument[]\n}\n\nexport default function DuplicatorQuery(props: DuplicatorQueryProps) {\n const {token, pluginConfig} = props\n\n const {queries: preDefinedQueries, apiVersion} = pluginConfig\n const originClient = useClient({apiVersion})\n\n const schema = useSchema()\n const schemaTypes = schema.getTypeNames()\n\n const [value, setValue] = useState(``)\n const [fetched, setFetched] = useState(false)\n const [initialData, setInitialData] = useState<InitialData>({\n docs: [],\n })\n\n async function runQuery() {\n try {\n const res = await originClient.fetch<SanityDocument[]>(value)\n\n // Ensure queried docs are registered to the schema\n const registeredAndPublishedDocs = res.length\n ? res\n .filter((doc) => schemaTypes.includes(doc._type))\n .filter((doc) => !doc._id.startsWith(`drafts.`))\n : []\n\n setInitialData({\n docs: registeredAndPublishedDocs,\n })\n setFetched(true)\n } catch (err) {\n console.error(err)\n }\n }\n\n function handleSubmit(e?: SubmitEvent<HTMLFormElement>) {\n if (e) e.preventDefault()\n void runQuery()\n }\n\n return (\n <Card padding={[0, 0, 0, 5]}>\n <Container>\n <Grid gridTemplateColumns={[1, 1, 1, 2]} gap={[1, 1, 1, 4]}>\n <Box padding={[2, 2, 2, 0]}>\n <Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>\n {preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )}\n </Box>\n {fetched && initialData.docs.length < 1 && (\n <Container width={1}>\n <Card padding={5}>\n {value ? `No documents match this query` : `Start with a valid GROQ query`}\n </Card>\n </Container>\n )}\n {initialData.docs?.length > 0 && (\n <Duplicator docs={initialData.docs} token={token} pluginConfig={pluginConfig} />\n )}\n </Grid>\n </Container>\n </Card>\n )\n}\n","import {Grid, Card, Container, Button} from '@sanity/ui'\nimport {useState, useEffect} from 'react'\nimport {type SanityDocument, useClient} from 'sanity'\n\nimport type {DuplicatorProps} from './Duplicator'\nimport Duplicator from './Duplicator'\n\nexport default function DuplicatorWrapper(props: DuplicatorProps) {\n const {docs, token, pluginConfig, onDuplicated} = props\n const [inbound, setInbound] = useState<SanityDocument[]>([])\n const {follow, apiVersion} = pluginConfig\n\n // Make the first mode the default if there's only one\n const [mode, setMode] = useState<'inbound' | 'outbound'>(\n follow.length === 1 ? (follow[0] ?? 'outbound') : 'outbound',\n )\n const client = useClient({apiVersion})\n\n // \"Inbound\" will start with all documents that reference the first one\n // And then you can gather \"Outbound\" references thereafter\n useEffect(() => {\n async function fetchInbound() {\n const firstDocId = docs[0]?._id\n\n if (!follow.includes(`inbound`) || !firstDocId) {\n return\n }\n\n const inboundReferences = await client.fetch<SanityDocument[]>(`*[references($id)]`, {\n id: firstDocId,\n })\n setInbound([...docs, ...inboundReferences])\n }\n\n fetchInbound().catch(console.error)\n }, [client, docs, follow])\n\n return (\n <Container>\n {follow.length > 1 && (follow.includes(`inbound`) || follow.includes(`outbound`)) ? (\n <Card paddingX={4} paddingBottom={4} marginBottom={4} borderBottom>\n <Grid gridTemplateColumns={2} gap={4}>\n {follow.includes(`outbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'outbound'}\n onClick={() => setMode('outbound')}\n text=\"Outbound\"\n />\n ) : null}\n {follow.includes(`inbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'inbound'}\n onClick={() => setMode('inbound')}\n disabled={inbound.length === 0}\n text={inbound.length > 0 ? `Inbound (${inbound.length})` : 'No inbound references'}\n />\n ) : null}\n </Grid>\n </Card>\n ) : null}\n <Duplicator\n docs={mode === 'outbound' ? docs : inbound}\n token={token}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />\n </Container>\n )\n}\n","import {Button, Flex} from '@sanity/ui'\nimport {useCallback} from 'react'\nimport {useClient} from 'sanity'\n\nimport {SECRET_NAMESPACE} from '../helpers/constants'\n\ntype ResetSecretProps = {\n apiVersion: string\n}\n\nexport default function ResetSecret({apiVersion}: ResetSecretProps) {\n const client = useClient({apiVersion})\n\n const handleClick = useCallback(() => {\n client.delete({query: `*[_id == \"secrets.${SECRET_NAMESPACE}\"]`}).catch(console.error)\n }, [client])\n\n return (\n <Flex align=\"center\" justify=\"flex-end\" paddingX={[2, 2, 2, 5]} paddingY={5}>\n <Button\n text=\"Reset Secret\"\n onClick={handleClick}\n mode=\"ghost\"\n tone=\"critical\"\n fontSize={1}\n padding={2}\n />\n </Flex>\n )\n}\n","import {useSecrets, SettingsView} from '@sanity/studio-secrets'\nimport {Flex, Box, Spinner} from '@sanity/ui'\nimport type {SanityDocument} from 'sanity'\n\nimport {useCrossDatasetDuplicatorConfig} from '../context/ConfigProvider'\nimport {SECRET_NAMESPACE} from '../helpers/constants'\nimport DuplicatorQuery from './DuplicatorQuery'\nimport DuplicatorWrapper from './DuplicatorWrapper'\nimport Feedback from './Feedback'\nimport ResetSecret from './ResetSecret'\n\n// Check for auth secret (required for asset uploads)\nconst secretConfigKeys = [\n {\n key: 'bearerToken',\n title:\n 'An API token with Viewer permissions is required to duplicate the original files of assets, and will be used for all Duplications. Create one at sanity.io/manage',\n description: '',\n },\n]\n\ntype Secrets = {\n bearerToken?: string\n}\n\ntype CrossDatasetDuplicatorProps = {\n mode: 'tool' | 'action'\n docs: SanityDocument[]\n onDuplicated?: () => Promise<void>\n}\n\nexport default function CrossDatasetDuplicator(props: CrossDatasetDuplicatorProps) {\n const {mode, docs, onDuplicated} = props\n const pluginConfig = useCrossDatasetDuplicatorConfig()\n\n const {loading, secrets} = useSecrets<Secrets>(SECRET_NAMESPACE)\n\n if (loading) {\n return (\n <Flex justify=\"center\" align=\"center\">\n <Box padding={5}>\n <Spinner />\n </Box>\n </Flex>\n )\n }\n\n // A bearer token is required to duplicate assets, so the prompt cannot be\n // dismissed until one is saved\n if (!secrets?.bearerToken) {\n return (\n <SettingsView\n title=\"Token Required\"\n namespace={SECRET_NAMESPACE}\n keys={secretConfigKeys}\n onClose={() => null}\n />\n )\n }\n\n if (mode === 'tool' && pluginConfig) {\n return (\n <>\n <DuplicatorQuery token={secrets.bearerToken} pluginConfig={pluginConfig} />\n <ResetSecret apiVersion={pluginConfig.apiVersion} />\n </>\n )\n }\n\n if (!docs?.length) {\n return <Feedback>No docs passed into Duplicator Tool</Feedback>\n }\n\n if (!pluginConfig) {\n return <Feedback>No plugin config</Feedback>\n }\n\n return (\n <DuplicatorWrapper\n docs={docs}\n token={secrets.bearerToken}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />\n )\n}\n","import type {CrossDatasetDuplicatorActionProps} from '../types'\nimport CrossDatasetDuplicator from './CrossDatasetDuplicator'\n\n/**\n * Component to perform a migration from the Cross Dataset Duplicator plugin\n * @public\n */\nexport function CrossDatasetDuplicatorAction(props: CrossDatasetDuplicatorActionProps) {\n const {docs, onDuplicated} = props\n\n return <CrossDatasetDuplicator mode=\"action\" docs={docs} onDuplicated={onDuplicated} />\n}\n","import {LaunchIcon} from '@sanity/icons/Launch'\nimport {useState} from 'react'\nimport type {DocumentActionProps} from 'sanity'\n\nimport {CrossDatasetDuplicatorAction} from '../components/CrossDatasetDuplicatorAction'\n\n/**\n * Document action from the Cross Dataset Duplicator plugin\n * @public\n */\nexport const DuplicateToAction = (props: DocumentActionProps) => {\n const {draft, published} = props\n const [dialogOpen, setDialogOpen] = useState(false)\n\n return {\n disabled: Boolean(draft),\n title: draft ? `Document must be Published to begin` : null,\n label: 'Duplicate to...',\n dialog: dialogOpen &&\n published && {\n type: 'modal',\n title: 'Cross Dataset Duplicator',\n content: <CrossDatasetDuplicatorAction docs={[published]} />,\n onClose: () => setDialogOpen(false),\n },\n onHandle: () => setDialogOpen(true),\n icon: LaunchIcon,\n }\n}\n\nDuplicateToAction.action = 'duplicateTo'\n","import type {SanityDocument, Tool} from 'sanity'\n\nimport CrossDatasetDuplicator from './CrossDatasetDuplicator'\n\nexport type MultiToolConfig = {\n docs: SanityDocument[]\n}\n\ntype CrossDatasetDuplicatorProps = {\n tool: Tool<MultiToolConfig>\n}\n\nexport function CrossDatasetDuplicatorTool(props: CrossDatasetDuplicatorProps) {\n const {docs = []} = props.tool.options ?? {}\n\n return <CrossDatasetDuplicator mode=\"tool\" docs={docs} />\n}\n","import {LaunchIcon} from '@sanity/icons/Launch'\nimport type {Tool} from 'sanity'\n\nimport {\n CrossDatasetDuplicatorTool,\n type MultiToolConfig,\n} from '../components/CrossDatasetDuplicatorTool'\n\nexport const crossDatasetDuplicatorTool = (): Tool<MultiToolConfig> => ({\n title: 'Duplicator',\n name: 'duplicator',\n icon: LaunchIcon,\n component: CrossDatasetDuplicatorTool,\n options: {\n docs: [],\n },\n})\n","import {definePlugin} from 'sanity'\n\nimport {DuplicateToAction} from './actions/DuplicateToAction'\nimport {ConfigProvider} from './context/ConfigProvider'\nimport {DEFAULT_CONFIG} from './helpers/constants'\nimport {crossDatasetDuplicatorTool} from './tool'\nimport type {PluginConfig} from './types'\n\n/**\n * Plugin: Cross Dataset Duplicator\n * @public\n */\nexport const crossDatasetDuplicator = definePlugin<Partial<PluginConfig> | void>((config = {}) => {\n const pluginConfig = {...DEFAULT_CONFIG, ...config}\n const {types} = pluginConfig\n\n return {\n name: '@sanity/cross-dataset-duplicator',\n tools: (prev) => (pluginConfig.tool ? [...prev, crossDatasetDuplicatorTool()] : prev),\n studio: {\n components: {\n layout: (props) => <ConfigProvider {...props} pluginConfig={pluginConfig} />,\n },\n },\n document: {\n actions: (prev, {schemaType}) => {\n return types && types.includes(schemaType) ? [...prev, DuplicateToAction] : prev\n },\n },\n }\n})\n"],"mappings":";;;;;;;;;;;;;;;;AAEA,MAAaC,mBAAmB,0BAEnBC,iBAAyC;CACpDE,YAAY;CACZC,MAAM;CACNC,OAAO,CAAA;CACPC,QAAQ;CACRC,QAAQ,CAAC,UAAU;CACnBC,SAAS,CAAA;CACTC,kBAAkB,CAAA;AACpB,GCNMM,gCAAgCL,cAAcG,cAAc;;;;;AAQlE,SAAOM,kCAAA;CACyD,OAAzCR,WAAWI,6BAEzBE;AAAY;AAGrB,SAAOG,eAAAC,OAAA;CAAA,IAAAC,IAAAC,EAAA,CAAA,GAAAC,IAAAC,IAAAC;CAAA,IAAAJ,EAAA,OAAAD,OAAA;EACL,IAAA,EAAAJ,cAAA,GAAAU,SAAgCN;EAIFC,AAD3BE,KAAAT,8BAA6Ba,UAAiBX,KAAAA,cAC5CS,KAAAL,MAAKQ,cAAeF,IAAI,GAACL,EAAA,KAAAD,OAAAC,EAAA,KAAAE,IAAAF,EAAA,KAAAG,IAAAH,EAAA,KAAAI;CAAA,OAAAA,AAAAF,KAAAF,EAAA,IAAAG,KAAAH,EAAA,IAAAI,KAAAJ,EAAA;CAAA,IAAAQ;CACa,OADbR,EAAA,OAAAE,MAAAF,EAAA,OAAAG,MAAAH,EAAA,OAAAI,MAD5BI,KAAA,oBAAC,IAAD;EAA+Cb,OAAAA;EAC5CS,UAAAA;CADoC,CAAA,GAEEJ,EAAA,KAAAE,IAAAF,EAAA,KAAAG,IAAAH,EAAA,KAAAI,IAAAJ,EAAA,KAAAQ,MAAAA,KAAAR,EAAA,IAFzCQ;AAEyC;ACxB7C,SAAgBE,qBAAqBC,WAAW,GAAGC,YAAY,GAAW;CAQxE,OAAOC;EANLF,aAAa,IAAI,2BAA2B,SAASA,SAAQ;EAC7DC,cAAc,IAAI,iBAAiB,GAAGA,UAAS;EAC/CA,cAAc,IAAI,kBAAkB;EACpC;CAGKC,CAAO,CAACC,KAAK,GAAG;AACzB;AAEA,MAAaC,gBAAgBC,aAAa,QAAyB;CACjEC,UAAU;CACVC,KAAK;CACLC,QAAQ;CACRC,iBAAiBJ,aAAa,wBAAwB;AACxD;ACHA,eAAsBgB,oBAAoBC,SAAgD;CACxF,IAAM,EAACP,UAAUC,QAAQC,cAAcC,YAAYE,eAAcE,SAC3DE,aAA+B,CAAA,GAI/BI,QAAQ,KADC,CAAC,oBAAoBX,aAAaQ,MAAM,CAAC,CAACA,OAAOC,OAAO,CAAC,CAACC,KAAK,MAC3DF,EAAM,GAAIL,cAAc,MACrCS,OAAO,MAAMb,OAAOc,MAAwBF,OAAO,EACvDb,UAAUA,YAAY,CAAA,EACxB,CAAC;CAED,IAAI,CAACc,MAAME,QACT,OAAO,CAAA;CAGT,IAAMC,kBAAkBd,8BAAc,IAAIC,IAAY,GAIhDc,aAAa,IAAId,IACrBU,KACGK,KAAKC,YAAYA,QAAQC,GAAG,CAAC,CAC7BX,QAAQY,OAAQnB,YAAYoB,OAAO,CAACN,gBAAgBO,IAAIF,EAAE,IAAIX,EAAQW,EAAI,CAC/E;CAEA,IAAIJ,WAAWK,MAAM;EACnBd,WAAWgB,KAAK,GAAGX,IAAI;EACvB,KAAK,IAAMQ,MAAMJ,YACfD,gBAAgBS,IAAIJ,EAAE;EAIxB,MAAMd,QAAQmB,IACZb,KAAKK,IAAI,OAAOS,QAAQ;GAEtB,IAAME,aAAanC,gBAAgBkC,UAAMD,GAAG,CAAC,CAACG,SAASC,QACrD,OAAOA,IAAIC,SAAU,WAAW,CAACD,IAAIC,KAAK,IAAI,CAAA,CAChD;GAEA,IAAIH,WAAWd,QAAQ;IAErB,IAAMkB,kBAAkB,IAAI9B,IAC1B0B,WAAWpB,QAAQsB,QAAQ,CAACf,gBAAgBO,IAAIQ,GAAG,CAAC,CACtD;IAEA,IAAIE,gBAAgBX,MAAM;KAExB,IAAMY,gBAAgB,MAAM7B,oBAAoB;MAC9CN,UAAUoC,MAAMC,KAAKH,eAAe;MACpC/B,YAAYc;MACZhB;MACAC;KACF,CAAC;KAED,AAAIiC,eAAenB,UACjBP,WAAWgB,KAAK,GAAGU,aAAa;IAEpC;GACF;EACF,CAAC,CACH;CACF;CAGA,IAAMG,0BAAU,IAAIlC,IAAY,GAC1BmC,mBAAqC,CAAA;CAE3C,KAAK,IAAMX,OAAOnB,YAChB,AAAImB,OAAO,CAACU,QAAQd,IAAII,IAAIP,GAAG,MAC7BiB,QAAQZ,IAAIE,IAAIP,GAAG,GACnBkB,iBAAiBd,KAAKG,GAAG;CAI7B,OAAOW;AACT;;;;;;;;;ACxEA,SAAgBQ,yBAAyBC,SAAmD;CAC1F,IAAM,EAACN,kBAAkBC,iBAAiBC,eAAeC,iBAAiBC,kBAAiBE,SAErFC,kBAAkBP,kBAAkBQ,MAAMC,WAAWA,OAAOP,kBAAkBA,aAAa;CAOjG,OAJA,CAAKK,mBAIEA,gBAAgBG,QAAQC,MAAMC,WAC/BA,OAAOC,YAAYT,gBAKnBQ,OAAOE,YACFF,OAAOE,cAAcX,kBAKvBA,oBAAoBF,kBAVlB,EAWV;AACH;ACjCA,SAAeqB,SAAAC,OAAA;CAAA,IAAAC,IAAAC,EAAA,CAAA,GACb,EAAAL,UAAAC,MAAAK,OAAqCH,OAApBF,OAAAK,OAAAC,KAAAA,IAAA,YAAAD,IAAgBE;CAAA,AAAAJ,EAAA,OAAAJ,WAIGQ,KAAAJ,EAAA,MAAhCI,KAAA,oBAAC,MAAD;EAAY,MAAA;EAAIR;CAAX,CAAA,GAA2BI,EAAA,KAAAJ,UAAAI,EAAA,KAAAI;CAAA,IAAAC;CAC3B,OAD2BL,EAAA,OAAAI,MAAAJ,EAAA,OAAAH,QADlCQ,KAAA,oBAAC,MAAD;EAAe,SAAA;EAAW,QAAA;EAAW,QAAA;EAASR;EAC5CO,UAAAA;CADG,CAAA,GAEEJ,EAAA,KAAAI,IAAAJ,EAAA,KAAAH,MAAAG,EAAA,KAAAK,MAAAA,KAAAL,EAAA,IAFPK;AAEO;ACLX,MAAMc,UAAwB;CAC5B;EAACH,OAAO;EAAOC,QAAQ;CAAK;CAC5B;EAACD,OAAO;EAAQC,QAAQ;CAAM;CAC9B,EAACC,SAAS,YAAW;CACrB;EAACF,OAAO;EAAOC,QAAQ;CAAK;CAC5B;EAACD,OAAO;EAAYC,QAAQ;CAAU;CACtC;EAACD,OAAO;EAASC,QAAQ;CAAO;CAChC,EAACC,SAAS,YAAW;CACrB;EAACF,OAAO;EAAaC,QAAQ;CAAW;CACxC;EAACD,OAAO;EAAUC,QAAQ;CAAQ;AAAC;AAGrC,SAASG,cAAcC,MAAmBJ,QAAyB;CACjE,QAAQA,QAAR;EACE,KAAK,OACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,OACH,OAAOI,KAAKC,WAAW;EACzB,KAAK,YACH,OAAOD,KAAKC,WAAW;EACzB,KAAK,SACH,OAAOD,KAAKC,WAAW;EACzB,KAAK,UACH,OAAOhB,UAAUe,KAAKE,IAAIC,GAAG;EAC/B,KAAK,aACH,OAAO,CAAClB,UAAUe,KAAKE,IAAIC,GAAG;EAChC,SACE,OAAOH,KAAKI;CAChB;AACF;AAOA,SAAeI,cAAAC,OAAA;CAAA,IAAAC,IAAAC,EAAA,EAAA,GACb,EAAAL,SAAAC,eAA8BE,OAAKG;CAAA,AAAAF,EAAA,OAAAJ,UAEqCM,KAAAF,EAAA,MADPE,WAC/DN,QAAOO,UAAWP,QAAOQ,MAAOC,OAAsB,IAAtD,CAA2D,KAAK,IAAhE,CAAA,GAAsEL,EAAA,KAAAJ,SAAAI,EAAA,KAAAE;CADxE,IAAA,CAAAI,iBAAAC,sBAA8C1B,SAAmBqB,EAEjE,GAACM;CAAA,AAAAR,EAAA,OAAAJ,QAAAO,UAAAH,EAAA,OAAAH,cAEDW,KAAA,SAAAC,mBAAAvB,QAAA;EACOU,QAAOO,WAEZN,YAAWa,YACTA,QAAOC,KAAKC,YAAW;GAAA,GAAItB;GAAII,SAAWL,cAAcC,QAAMJ,MAAM;EAAC,EAAE,CACzE,GACAqB,mBAAmB,CAACrB,MAAM,CAAC;CAAC,GAC7Bc,EAAA,KAAAJ,QAAAO,QAAAH,EAAA,KAAAH,YAAAG,EAAA,KAAAQ,MAAAA,KAAAR,EAAA;CAPD,IAAAS,qBAAAD,IAOCK;CAAA,AAAAb,EAAA,OAAAM,mBAAAN,EAAA,OAAAS,sBAKMI,KAAAzB,QAAOuB,KAAKG,WACX,YAAYA,SACV,oBAAC,QAAD;EAEY,UAAA;EACL,MAAA;EACI,SAAA;EACH,MAAAA,OAAM7B;EACF,UAAAqB,gBAAeS,SAAUD,OAAM5B,MAAO;EACvC,eAAMuB,mBAAmBK,OAAM5B,MAAO;CAAC,GAN3C4B,OAAM5B,MAMqC,IAGlD,oBAAC,MAAD,EAA2B,YAAA,GAAU,GAA1B4B,OAAM3B,OAAoB,CAEzC,GAACa,EAAA,KAAAM,iBAAAN,EAAA,KAAAS,oBAAAT,EAAA,KAAAa,MAAAA,KAAAb,EAAA;CAAA,IAAAgB;CAEE,OAFFhB,EAAA,OAAAa,KAEEG,KAAAhB,EAAA,MAlBPgB,KAAA,oBAAC,MAAD;EAAe,SAAA;EAAW,QAAA;EAAW,QAAA;EACnC,UAAA,oBAAC,MAAD;GAAW,KAAA;GAAQ,MAAA;GAChBH,UAAAA;EADE,CAAA;CADF,CAAA,GAkBEb,EAAA,KAAAa,IAAAb,EAAA,KAAAgB,KAlBPA;AAkBO;AAlCI,SAAAX,QAAAf,MAAA;CAAA,OAG+BA,KAAII;AAAQ;ACtC1D,MAAMmC,gBAA6B;CACjCL,QAAQ;CACRC,WAAW;CACXC,QAAQ;CACRC,QAAQ;CACRC,aAAa;AACf,GAEME,aAA0B;CAC9BN,QAAQ;CACRC,WAAW;CACXC,QAAQ;CACRC,QAAQ;CACRC,aAAa;AACf,GAUMI,mBAAiC;CAErCR,QAAQ;CAIRC,WAAW;CAEXC,QAAQ;CAERC,QAAQ;CACRC,aAAa;AACf,GAEMK,gBAA8B;CAClCT,QAAQ;CACRC,WAAW;CACXC,QAAQ;CACRC,QAAQ;CACRC,aAAa;AACf,GAEMM,cAA4B;CAChCV,QAAQ;CACRC,WAAW;CACXC,QAAQ;CACRC,QAAQ;CACRC,aAAa;AACf;AAOA,SAAeU,YAAAC,OAAA;CAAA,IAAAC,IAAAC,EAAA,EAAA,GACb,EAAAJ,QAAAD,YAA0BG;CAE1B,IAAI,CAACF,QAAM,OACF;CAGT,IAAAK,YAAkBN,UAAUN,WAAWO,UAAUR,cAAcQ;CAE/D,IAAI,CAACK,WAAS;EAAA,IAAAC;EAIF,OAJEH,EAAA,OAAAI,OAAAC,IAAA,2BAAA,KAEVF,KAAA,oBAAC,OAAD;GAAgB,SAAA;GAAa,UAAA;GAAG,UAAA;EAA1B,CAAA,GAEEH,EAAA,KAAAG,MAAAA,KAAAH,EAAA,IAFRG;CAEQ;CAIZ,IAAAG,YAAkBV,UAAUH,cAAcI,UAAUL,iBAAiBK,SACrEU,cAAoBX,UAAUF,YAAYG,UAAtBA,QAAsCM;CAAA,AAAAH,EAAA,OAAAI,OAAAC,IAAA,2BAAA,KAK5BF,KAAA,EAAAK,UAAW,IAAG,GAACR,EAAA,KAAAG,MAAAA,KAAAH,EAAA;CAAA,IAAAS;CAAA,AAAAT,EAAA,OAAAM,YAEjCG,KAAAT,EAAA,MAFNS,KAAA,oBAAC,KAAD;EAAc,SAAA;EAAU,OAAAN;EACtB,UAAA,oBAAC,MAAD;GAAY,MAAA;GAAIG,UAAAA;EAAX,CAAA;CADH,CAAA,GAEEN,EAAA,KAAAM,WAAAN,EAAA,KAAAS;CAAA,IAAAC;CAAA,AAAAV,EAAA,OAAAI,OAAAC,IAAA,2BAAA,KAEYK,KAAA,CAAC,SAAS,MAAM,GAACV,EAAA,KAAAU,MAAAA,KAAAV,EAAA;CAAA,IAAAW;CAAA,AAAAX,EAAA,OAAAI,OAAAC,IAAA,2BAAA,KAMnCM,KAAA,oBAAC,KAAD;EAAiB,YAAA;EAAY,SAAA;EAAmB,IAAA;EAC9C,UAAA,oBAAC,iBAAD,CAAgB,CAAA;CADd,CAAA,GAEEX,EAAA,KAAAW,MAAAA,KAAAX,EAAA;CAAA,IAAAY;CAAA,AAAAZ,EAAA,OAAAO,eAAAP,EAAA,OAAAE,aAJRU,KAAA,qBAAC,OAAD;EAAgB,SAAA;EAAa,UAAA;EAASV,MAAAA;EAAtC,UAAA,CACGK,aACDI,EAFI;KAKEX,EAAA,KAAAO,aAAAP,EAAA,KAAAE,WAAAF,EAAA,KAAAY,MAAAA,KAAAZ,EAAA;CAAA,IAAAa;CACA,OADAb,EAAA,OAAAS,MAAAT,EAAA,QAAAY,MAfVC,KAAA,oBAAC,SAAD;EAEI,SAAAJ;EAIkB,oBAAAC;EACV,WAAA;EACV,QAAA;EAEAE,UAAAA;CAVM,CAAA,GAgBEZ,EAAA,KAAAS,IAAAT,EAAA,MAAAY,IAAAZ,EAAA,MAAAa,MAAAA,KAAAb,EAAA,KAhBVa;AAgBU;AC7Cd,SAAS8D,gBAAgBT,KAAkE;CACzF,OAAOpD,UAAUoD,IAAIU,GAAG;AAC1B;AAGA,eAAeC,mBACbC,OACAE,OACAC,IACe;CACf,IAAME,QAAQ,CAAC,GAAGL,KAAK;CAEvB,eAAeM,OAAsB;EACnC,IAAMF,OAAOC,MAAME,MAAM;EAErBH,aAASI,KAAAA,GAMb,OAFA,MAAML,GAAGC,IAAI,GAENE,KAAK;CACd;CAEA,IAAMG,UAAUC,MAAMC,KAAK,EAACC,QAAQC,KAAKC,IAAIZ,OAAOG,MAAMO,MAAM,EAAC,SAASN,KAAK,CAAC;CAEhF,MAAMpB,QAAQ6B,IAAIN,OAAO;AAC3B;AAIA,SAASS,SAASC,OAAkD;CAClE,OAAO,OAAOA,SAAU,cAAYA;AACtC;AAEA,SAASE,eAAeF,OAAoC;CAC1D,OAAOT,MAAMY,QAAQH,KAAK;AAC5B;AAMA,SAASI,oBAAoBC,KAAsB;CACjD,IAAI,CAACN,SAASM,GAAG,GACf,OAAO;CAGT,IAAMC,UAAUD,IAAI,SACdE,mBAA6B,CAAA;CAEnC,IAAIR,SAASO,OAAO,KAAKJ,eAAeI,QAAQ,KAAQ,GACjD;OAAA,IAAMrB,QAAQqB,QAAQ,OACzB,IAAIP,SAASd,IAAI,KAAKc,SAASd,KAAK,KAAQ,GAAG;GAC7C,IAAMuB,kBAAkBvB,KAAK,MAAS;GAEtC,AAAI,OAAOuB,mBAAoB,YAAYA,mBACzCD,iBAAiBE,KAAKD,eAAe;EAEzC;;CAIJ,IAAID,iBAAiBd,QACnB,OAAOc,iBAAiBG,KAAK,IAAI;CAGnC,IAAMC,UAAUN,IAAI;CAEpB,IAAI,OAAOM,WAAY,YAAYA,SACjC,OAAOA;CAGT,IAAIZ,SAASO,OAAO,GAAG;EACrB,IAAMM,cAAcN,QAAQ;EAE5B,IAAI,OAAOM,eAAgB,UACzB,OAAOA;CAEX;CAEA,OAAO;AACT;AAEA,SAASC,yBAAyBR,KAAuB;CACvD,IAAI,CAACN,SAASM,GAAG,GACf,OAAO;CAGT,IAAMC,UAAUD,IAAI;CAGpB,IAAIN,SAASO,OAAO,KAAKJ,eAAeI,QAAQ,KAAQ,GACjD;OAAA,IAAMrB,QAAQqB,QAAQ,OACzB,IAAIP,SAASd,IAAI,KAAKc,SAASd,KAAK,KAAQ,GAAG;GAC7C,IAAIA,KAAK,MAAS,SAAY,sCAC5B,OAAO;GAGT,IAAMuB,kBAAkBvB,KAAK,MAAS;GAEtC,IACE,OAAOuB,mBAAoB,aAC1BA,gBAAgBM,YAAY,CAAC,CAACC,SAAS,kCAAkC,KACxEP,gBAAgBM,YAAY,CAAC,CAACC,SAAS,wBAAwB,IAEjE,OAAO;EAEX;;CAIJ,IAAMH,cAAcR,oBAAoBC,GAAG,CAAC,CAACS,YAAY;CAEzD,OACEF,YAAYG,SAAS,kCAAkC,KACvDH,YAAYG,SAAS,wBAAwB;AAEjD;AAIA,SAASC,uBAAuBX,KAAcO,aAA+B;CAC3E,IAAMK,aAAuB,CAAA,GAEvBX,UAAUP,SAASM,GAAG,IAAIA,IAAI,UAAahB,KAAAA,GAC3C6B,WAAWnB,SAASO,OAAO,IAAIA,QAAQ,QAAWjB,KAAAA,GAClDR,QAAQqB,eAAegB,QAAQ,IAAIA,WAAW,CAAA;CAEpD,KAAK,IAAMjC,QAAQJ,OACjB,IAAIkB,SAASd,IAAI,GAAG;EAClB,IAAMkC,QAAQlC,KAAK;EAEnB,IAAIc,SAASoB,KAAK,GAAG;GAEnB,IAAMC,QAAQD,MAAM,eAAkBA,MAAM,gBAAmBA,MAAM;GAErE,AAAI,OAAOC,SAAU,YAAY,CAACH,WAAWF,SAASK,KAAK,KACzDH,WAAWR,KAAKW,KAAK;EAEzB;CACF;CAGF,IAAMC,WAAW,+DACbC,QAAQD,SAASE,KAAKX,WAAW;CAErC,OAAOU,UAAU,OAAM;EACrB,IAAME,KAAKF,MAAM;EAMjBA,AAJIE,MAAM,CAACP,WAAWF,SAASS,EAAE,KAC/BP,WAAWR,KAAKe,EAAE,GAGpBF,QAAQD,SAASE,KAAKX,WAAW;CACnC;CAEA,OAAOK;AACT;AAKA,eAAeQ,eACb/D,MACAgE,QACAC,YACAC,WACe;CACf,IAAIC,eAAe,GACfC,YAAY;CAchB,IAZA,MAAMlD,mBAAmBlB,MAAM,GAAG,OAAOO,QAAQ;EAC/C,IAAI;GACF,IAAM8D,KAAKL,OAAOM,YAAY;GAG9BH,AAFAE,GAAGE,gBAAgBhE,GAAG,GACtB,MAAM8D,GAAGG,OAAO,GAChBL,gBAAgB;EAClB,SAASM,WAAW;GAElBC,AADAN,aAAa,GACbM,QAAQjB,MAAM,iCAAiClD,IAAIU,IAAG,IAAKwD,SAAS;EACtE;CACF,CAAC,GAEGL,cAAc,GAAG;EAEnBF,AADAD,WAAW;GAAClD,MAAM;GAAYD,MAAM;EAAuB,CAAC,GAC5DoD,UAAU;EAEV;CACF;CAOA,AALAD,WAAW;EACTlD,MAAM;EACND,MAAM,6BAA6BsD,UAAS,aAAcD,aAAY;CACxE,CAAC,GAEGA,eAAe,KACjBD,UAAU;AAEd;AAyBA,SAASmB,kBAAkBC,KAAarF,OAAesF,YAAkC;CACvF,IAAIA,YACF,OAAO,CAAC;CAGV,IAAI;EACF,IAAM,EAACE,aAAY,IAAIC,IAAIJ,GAAG;EAE9B,IAAIG,aAAa,mBAAmBA,SAASE,SAAS,YAAY,GAChE,OAAO,EAACC,SAAS,EAACC,eAAe,UAAU5F,QAAO,EAAC;CAEvD,QAAQ,CACN;CAGF,OAAO,CAAC;AACV;AAGA,eAAe6F,uBACbvF,KACAuE,mBACA7E,OACwE;CACxE,IAAMsF,aAAanI,kBAAkBmD,GAAG,GAClCyF,cAAcT,aAAahF,IAAI+E,MAAM,GAAG/E,IAAI+E,IAAG,cAE/CW,MAAM,MAAMC,MAAMF,aAAaX,kBAAkBW,aAAa/F,OAAOsF,UAAU,CAAC;CAEtF,IAAI,CAACU,IAAIE,IACP,MAAUC,MACR,6BAA6B7F,IAAIU,IAAG,iBAAkBgF,IAAIxF,OAAM,GAAIwF,IAAII,WAAU,EACpF;CAGF,IAAMC,YAAY,MAAML,IAAIM,KAAK,GAC3BC,WAAW,MAAM1B,kBAAkB2B,OAAOC,OAAOnB,aAAa,SAAS,SAASe,WAAW,EAC/FK,UAAUpG,IAAIqG,iBAChB,CAAC;CAOD,OAAO;EACL5G,MAAM,CAAC;GAAC,GAAGO;GAAK,GAAGiG;EAAQ,CAAC;EAC5BT,QAAQxF,IAAIsG,cAAc,QAAQ;GAAC1B,KAAK5E,IAAIU;GAAKmE,KAAKoB,SAASvF;EAAG,IAAIU,KAAAA;CACxE;AACF;AAIA,SAASmF,aACP9G,MACAkF,SACkB;CAKlB,OAJKA,QAAQnD,SAIN/B,KAAK+G,KAAKC,aAAa;EAC5B,IAAMC,aAAavJ,gBAAgB,UAAUsJ,QAAQ;EAErD,IAAI,CAACC,WAAWlF,QACd,OAAOiF;EAGT,IAAMzG,MAAM2G,gBAAgBF,QAAQ;EAUpC,OARAC,WAAWE,SAASC,QAAQ;GAC1B,IAAMC,cAAcnC,QAAQoC,MAAMC,UAAUA,MAAMpC,QAAQiC,IAAI9E,KAAK,CAAC,EAAE8C;GAEtE,AAAIiC,eACF5I,KAAK8B,KAAK6G,IAAII,KAAKxE,KAAK,GAAG,GAAGqE,WAAW;EAE7C,CAAC,GAEM9G;CACT,CAAC,IArBQP;AAsBX;AAIA,SAASyH,2BAA2BzH,MAA0C;CAC5E,IAAM0H,OAAO,IAAIC,IAAI3H,KAAK+G,KAAKxG,QAAQ,CAACA,IAAIU,KAAKV,GAAG,CAAC,CAAC,GAChDqH,2BAAW,IAAI3C,IAAY,GAC3B4C,0BAAU,IAAI5C,IAAY,GAC1B6C,UAA4B,CAAA;CAElC,SAASC,MAAMjE,IAAkB;EAC/B,IAAI+D,QAAQG,IAAIlE,EAAE,KAAK8D,SAASI,IAAIlE,EAAE,GACpC;EAGF,IAAMvD,MAAMmH,KAAKO,IAAInE,EAAE;EAElBvD,SAILqH;YAASM,IAAIpE,EAAE;GAEf,KAAK,IAAMsD,OAAO1J,gBAAgB,UAAU6C,GAAG,GAC7C,AAAI,OAAO6G,IAAI9E,SAAU,YACvByF,MAAMX,IAAI9E,KAAK;GAMnBwF,AAFAF,SAASO,OAAOrE,EAAE,GAClB+D,QAAQK,IAAIpE,EAAE,GACdgE,QAAQ/E,KAAKxC,GAAG;EAVD;CAWjB;CAEA,KAAK,IAAMA,OAAOP,MAChB+H,MAAMxH,IAAIU,GAAG;CAGf,OAAO6G;AACT;AAMA,eAAeM,qBAAqBC,SAA+C;CACjF,IAAM,EACJ1F,KACAiC,iBACAC,cACAC,mBACA5E,cACAD,OACAgE,YACAC,WACAa,QAAQ,GACRC,8BAAc,IAAIC,IAAI,GACtBC,SAASoD,mBAAmB,CAAA,MAC1BD,SACEnF,cAAcR,oBAAoBC,GAAG,GACrCY,aAAaD,uBAAuBX,KAAKO,WAAW,GAIpDqF,eAAehF,WAAWiF,QAAQ1E,OAAO,CAACkB,YAAYgD,IAAIlE,EAAE,CAAC,GAC7D2E,aAAalF,WAAWiF,QAAQ1E,OAAOkB,YAAYgD,IAAIlE,EAAE,CAAC;CAEhE,IAAI2E,WAAW1G,UAAU,CAACwG,aAAaxG,QAAQ;EAC7CkC,WAAW;GACTlD,MAAM;GACND,MAAM,2EAA2E2H,WAAWzF,KAAK,IAAI,EAAC;EACxG,CAAC;EAED;CACF;CAEA,IAAI,CAACO,WAAWxB,UAAUgD,SAAS,GAAG;EAGpC,AADAd,WAAW;GAAClD,MAAM;GAAWD,MAAM;EAAkC,CAAC,GACtE,MAAMiD,eACJ0D,2BAA2B7C,eAAe,GAC1CE,mBACAb,YACAC,SACF;EAEA;CACF;CAEAD,WAAW;EACTlD,MAAM;EACND,MAAM,YAAYyH,aAAaxG,OAAM;CACvC,CAAC;CAED,IAAI2G,cAAgC,CAAA;CAEpC,IAAI;EAGFA,cAAc,MAAMlJ,oBAAoB;GACtCmJ,UAAUJ;GACVvE,QAAQa;GACR3E;EACF,CAAC;CACH,SAAS0I,UAAU;EACjB3E,WAAW;GACTlD,MAAM;GACND,OACG8H,oBAAoBxC,QAAQwC,SAAS3F,UAAU,OAAOC,eAAe;EAC1E,CAAC;EAED;CACF;CAEA,IAAI,CAACwF,YAAY3G,QAAQ;EAEvB,AADAkC,WAAW;GAAClD,MAAM;GAAWD,MAAM;EAAkC,CAAC,GACtE,MAAMiD,eACJ0D,2BAA2B7C,eAAe,GAC1CE,mBACAb,YACAC,SACF;EAEA;CACF;CAIA,IAAM2E,cAAc,IAAI5D,IAAIL,gBAAgBmC,KAAKxG,QAAQA,IAAIU,GAAG,CAAC,GAE3D6H,iBAAiB,CAAC,GAAGJ,WAAW,CAAC,CACpCK,QAAQ,CAAC,CACTP,QAAQjI,QAAQ,CAACsI,YAAYb,IAAIzH,IAAIU,GAAG,KAAK,CAAC+D,YAAYgD,IAAIzH,IAAIU,GAAG,CAAC;CAGzE,IAAI,CAAC6H,eAAe/G,QAAQ;EAE1B,AADAkC,WAAW;GAAClD,MAAM;GAAWD,MAAM;EAAkC,CAAC,GACtE,MAAMiD,eACJ0D,2BAA2B7C,eAAe,GAC1CE,mBACAb,YACAC,SACF;EAEA;CACF;CAEAD,WAAW;EAAClD,MAAM;EAAWD,MAAM,eAAegI,eAAe/G,OAAM;CAAyB,CAAC;CAKjG,IAAMmD,UAAwC,CAAC,GAAGoD,gBAAgB,GAI5DU,kBAAsCnH,MAAMC,KAAK,EAACC,QAAQ+G,eAAe/G,OAAM,SAAS,CAAA,CAAE;CAEhG,IAAI;EACF,MAAMb,mBACJ4H,eAAe/B,KAAKxG,KAAK0I,WAAW;GAAC1I;GAAK0I;EAAK,EAAE,GACjD,GACA,OAAO,EAAC1I,KAAK0I,YAAW;GACtB,IAAI,CAACjI,gBAAgBT,GAAG,GAAG;IACzByI,gBAAgBC,SAAS,CAAC1I,GAAG;IAE7B;GACF;GAEA,IAAM,EAACP,MAAM+F,WAAU,MAAMD,uBAAuBvF,KAAKuE,mBAAmB7E,KAAK;GAGjF,AAFA+I,gBAAgBC,SAASjJ,MAErB+F,UACFb,QAAQnC,KAAKgD,MAAM;EAEvB,CACF;CACF,SAASmD,WAAW;EAClBjF,WAAW;GACTlD,MAAM;GACND,OACGoI,qBAAqB9C,QAAQ8C,UAAUjG,UAAU,OAClDC,eACA;EACJ,CAAC;EAED;CACF;CAKA,IAAMmG,wBAAwBvC,aAHRkC,gBAAgBI,KAGKD,GAAejE,OAAO,GAC3DoE,0BAA0BxC,aAAalC,iBAAiBM,OAAO,GAI/DqE,UAAU9B,2BAA2B,CAAC,GAAG4B,uBAAuB,GAAGC,uBAAuB,CAAC,GAE3FE,mBAAmB1E,kBAAkBR,YAAY;CACvDiF,QAAQpC,SAAS5G,QAAQiJ,iBAAiBjF,gBAAgBhE,GAAG,CAAC;CAE9D,IAAI;EAGF2D,AAFA,MAAMsF,iBAAiBhF,OAAO,GAC9BP,WAAW;GAAClD,MAAM;GAAYD,MAAM;EAAuB,CAAC,GAC5DoD,UAAU;CACZ,SAASuF,UAAU;EACjB,IAAItG,yBAAyBsG,QAAQ,GAAG;GAEtC,MAAMrB,qBAAqB;IACzB,GAAGC;IACH1F,KAAK8G;IACL7E,iBAAiB2E;IACjBxE,OAAOA,QAAQ;IACfG;GACF,CAAC;GAED;EACF;EAGA,AADAjB,WAAW;GAAClD,MAAM;GAAWD,MAAM;EAAkC,CAAC,GACtE,MAAMiD,eAAewF,SAASzE,mBAAmBb,YAAYC,SAAS;CACxE;AACF;AAEA,SAAewF,WAAAC,OAAA;CAAA,IAAAC,IAAAC,EAAA,GAAA,GACb,EAAA7J,MAAAC,OAAAC,cAAAE,iBAAkDuJ,OAClDG,QAAcxL,SAAS,GACvByL,aAAmBvL,YAAY,EAAAwL,QAASF,MAAKE,OAAO,CAAC,CAAC,CAAAC,MAAMC,OAAMC;CAAA,AAAAP,EAAA,OAAA1J,aAAAkK,aAGED,KAAAP,EAAA,MAArCO,KAAA,EAAAC,YAAalK,aAAYkK,WAAW,GAACR,EAAA,KAAA1J,aAAAkK,YAAAR,EAAA,KAAAO;CAApE,IAAAtF,eAAqB7F,UAAUmL,EAAqC,GAEpEE,SAAenL,UAAU,GAIzBoL,aAAmBnL,cAAc,GACjC,EAAAoL,WAAAC,iBAAAC,SAAAC,kBAA6D7F,aAAY8F,OAAQ,GACjFC,oBAA6CN,WAAUvD,KAAK8D,cAAA;EAC1D,IAAAC,oBACED,UAASN,cAAeC,mBAAmBK,UAASJ,YAAaC,eACnEK,qBAA2BtL,yBAAyB;GAAAuL,kBAChC9K,aAAY8K;GAAiBR;GAAAE;GAAAO,iBAG9BJ,UAASN;GAAUW,eACrBL,UAASJ;EAC1B,CAAC;EAAC,OAEK;GAAA,GACFI;GAASjK,UACFkK,qBAAA,CAAsBC;EAClC;CAAC,CACF,GAEDI,mBAAyBP,kBAAiBtD,MACxC8D,gBAAeP,YAASN,cAAeC,mBAAmBK,YAASJ,YAAaC,aAClF,GAEA,CAAAW,aAAAC,kBAAsCvM,SACpCuL,WAAUvI,SAAW6I,kBAAiBtD,KAAMiE,OAAkC,KAAzD,OAArB,IACF,GACA,CAAAtI,SAAAgB,cAA8BlF,SAAyB,IAAI,GAACyM;CAAA,AAAA5B,EAAA,OAAA6B,OAAAC,IAAA,2BAAA,KACNF,KAAA,CAAA,GAAE5B,EAAA,KAAA4B,MAAAA,KAAA5B,EAAA;CAAxD,IAAA,CAAA+B,SAAAC,cAA8B7M,SAAwByM,EAAE,GAExD,CAAAK,eAAAC,oBAA0C/M,SAAS,EAAK,GACxD,CAAAgN,aAAAC,kBAAsCjN,SAAS,EAAK,GAACkN;CAAA,AAAArC,EAAA,OAAA6B,OAAAC,IAAA,2BAAA,KACMO,KAAA,CAAC,GAAG,CAAC,GAACrC,EAAA,KAAAqC,MAAAA,KAAArC,EAAA;CAAjE,IAAA,CAAAsC,UAAAC,eAAgCpN,SAA2BkN,EAAM,GAGjEG,mBACQpM,KAAIqM,OAAQC,QAA2D,CAAC,GAGhFC,gBAAsBH,mBAAmB,GAACI;CAAA,AAAA5C,EAAA,OAAA5J,KAAA+B,UAAA6H,EAAA,OAAA2C,iBAAA3C,EAAA,OAAAwC,oBACHI,KAAAD,gBAAA;EAAAxL,MAC5B;EAASD,MAAQvB,qBAAqBS,KAAI+B,QAASqK,gBAAgB;CACvE,IAFgC,MAE/BxC,EAAA,KAAA5J,KAAA+B,QAAA6H,EAAA,KAAA2C,eAAA3C,EAAA,KAAAwC,kBAAAxC,EAAA,KAAA4C,MAAAA,KAAA5C,EAAA;CACR,IAAA8C,iBAAuBzJ,WAAAwJ,IAAyBE;CAAA,AAAA/C,EAAA,OAAA/E,gBAAA+E,EAAA,OAAAgC,cAGhDe,KAAA,eAAAC,sBAAAC,eAAAC,MAAA;EACE,IAAI,CAACD,cAAa9K,UAAd,CAA0B+K,MAAIC,MAAM;EAIxC,IAAAC,aAAmBH,cAAa9F,IAAKkG,MAAkB,GAKvDE,kBAAwB,MAJEtI,aAAYqI,WAAY;GAAAzC,SACvCqC,KAAIrC;GAAQF,WACVuC,KAAIvC;EACjB,CAC8BzF,CAAiB,CAAAoB,MAC7C,4CACA,EAAA8G,WAAW,CACb,GAGAI,kBAAwB,IAAIzF,IAAIwF,gBAAepG,IAAKsG,MAAuB,CAAC;EAE5EzB,WACEiB,cAAa9F,KAAKxF,SAAA;GAChB,IAAA+L,cAAoBF,gBAAenF,IAAK1G,KAAIhB,IAAIU,GAAI,GACpDR,SAAiC;GAehC,OAbG6M,aAAWC,cAAgBhM,KAAIhB,IAAIgN,eACrC,AAKE9M,SALE6M,YAAWC,eAAgBhM,KAAIhB,IAAIgN,aAG5B9M,WAGPA,IAAI+M,KAAKF,YAAWC,UAAW,IAAI,IAAIC,KAAKjM,KAAIhB,IAAIgN,UAAW,IAA/D,cAAA,WAQC;IAAA,GAAIhM;IAAId;GAAQ;EAAC,CACzB,CACH;CAAC,GACFmJ,EAAA,KAAA/E,cAAA+E,EAAA,KAAAgC,YAAAhC,EAAA,MAAA+C,MAAAA,KAAA/C,EAAA;CAzCD,IAAAgD,wBAAAD,IAyCCc;CAAA,AAAA7D,EAAA,QAAAyB,eAAAzB,EAAA,QAAAgD,yBAGwCa,MAAAC,aAAA;EACvC,IAAAC,iBAAsCD,SAAQ3G,IAAK6G,MAA+B;EAClFhB,sBAAsBe,gBAAgBtC,WAAW,CAAC,CAAAwC,MAAOnJ,QAAOjB,KAAM;CAAC,GACxEmG,EAAA,MAAAyB,aAAAzB,EAAA,MAAAgD,uBAAAhD,EAAA,MAAA6D,MAAAA,KAAA7D,EAAA;CAHD,IAAAkE,oBAA0BjP,eAAe4O,EAGxC,GAACM;CAAA,AAAAnE,EAAA,QAAA5J,QAAA4J,EAAA,QAAAkE,qBAMQC,WAAA;EAERD,kBAAkB9N,IAAI;CAAC,GACxB4J,EAAA,MAAA5J,MAAA4J,EAAA,MAAAkE,mBAAAlE,EAAA,MAAAmE,MAAAA,KAAAnE,EAAA;CAAA,IAAAoE;CAHDpP,AAGCgL,EAAA,QAAA5J,OAAQgO,KAAApE,EAAA,OAANoE,KAAA,CAAChO,IAAI,GAAC4J,EAAA,MAAA5J,MAAA4J,EAAA,MAAAoE,KAHTpP,UAAUmP,IAGPC,EAAM;CAAC,IAAAC;CAAA,AAAArE,EAAA,QAAAgC,aAMTqC,KAAArE,EAAA,OAJDqE,KAAA,SAAAC,eAAAjN,KAAA;EACE2K,YAAWuC,YACTA,QAAOpH,KAAKqH,WAAW7M,OAAIhB,IAAIU,QAASA,MAAjB;GAAA,GAA2BM;GAAIf,SAAW,CAACe,OAAIf;EAAe,IAA9D4N,MAAgE,CACzF;CAAC,GACFxE,EAAA,MAAAgC,YAAAhC,EAAA,MAAAqE;CAJD,IAAAC,iBAAAD,IAICI;CAAA,AAAAzE,EAAA,QAAAyB,eAAAzB,EAAA,QAAA5J,QAAA4J,EAAA,QAAA/E,gBAAA+E,EAAA,QAAA1J,gBAAA0J,EAAA,QAAAgC,cAAAhC,EAAA,QAAAgD,yBAGDyB,KAAA,eAAAC,mBAAA;EACEtC,eAAe,EAAI;EAEnB,IAAA;GACE,IAAAuC,SAAevO,KAAI+G,IAAKyH,MAAgB,GAExCC,cAAoB,MAAMjP,oBAAoB;IAAAmJ,UAClC4F;IAAMvK,QACRa;IAAY3E;GAEtB,CAAC,GACDwO,YAAkB,MAAMlP,oBAAoB;IAAAmJ,UAChC4F,OAAMxH,IAAK4H,MAAsB;IAAC3K,QACpCa;IAAY+J,YACR;IAAO1O;GAErB,CAAC,GACD2O,eAAqB,IAAI5J,IAAIyJ,UAAS3H,IAAK+H,MAAc,CAAC,GAG1DC,gBAAqCN,YAAW1H,KAAKiI,WAAU;IAAAzO,KAC7DA;IAAGC,SAEM;IAAIC,QAELkB,KAAAA;IAASjB,UAEPmO,aAAY7G,IAAK,UAAUzH,MAAGU,KAAM;GAChD,EAAE;GAGF2L,AADAhB,WAAWmD,aAAa,GACxBnC,sBAAsBmC,eAAe1D,WAAW,CAAC,CAAAwC,MAAOnJ,QAAOjB,KAAM;EAAC,SAAAwL,KAAA;GAEtEvK,QAAOjB,MAAOd,GAAG;EAAC;EAGpBqJ,eAAe,EAAK;CAAC,GACtBpC,EAAA,MAAAyB,aAAAzB,EAAA,MAAA5J,MAAA4J,EAAA,MAAA/E,cAAA+E,EAAA,MAAA1J,cAAA0J,EAAA,MAAAgC,YAAAhC,EAAA,MAAAgD,uBAAAhD,EAAA,MAAAyE,MAAAA,KAAAzE,EAAA;CArCD,IAAA0E,mBAAAD,IAqCCY;CAAA,AAAArF,EAAA,QAAAyB,eAAAzB,EAAA,QAAAxJ,gBAAAwJ,EAAA,QAAA/E,gBAAA+E,EAAA,QAAA+B,WAAA/B,EAAA,QAAA1J,gBAAA0J,EAAA,QAAA3J,SAAA2J,EAAA,QAAAgD,yBAGDqC,MAAA,eAAAC,kBAAA;EACE,IAAI,CAAC7D,aAAW;EAIhBS,iBAAiB,EAAI;EAErB,IAAAqD,cAAoBxD,QAAOnD,OAAQ4G,MAAiD,CAAC,CAAArN,QACrFsN,kBAAsB;EAGtBpL,AAFAkI,YAAY,CAACkD,iBAAiBF,WAAW,CAAC,GAE1ClL,WAAW;GAAAnD,MAAO;GAAgBC,MAAQ;EAAa,CAAC;EAExD,IAAAuO,sBAA0BzK,aAAYqI,WAAY;GAAA9C,YACpClK,aAAYkK;GAAWK,SAC1BY,YAAWZ;GAAQF,WACjBc,YAAWd;EACxB,CAAC,GAED3F,kBAA0C,CAAA,GAC1CM,UAA8C,CAAA,GAG9CqK,aAAA,eAAAA,WAAAC,OAAA;GACE,IAAI,CAACxO,gBAAgBT,KAAG,GAAC;IACvBqE,gBAAe7B,KAAMxC,KAAG;IAAC;GAAA;GAO3B,IAAAgF,aAAmBnI,kBAAkBmD,KAAG,GACxCyF,cAAoBT,aAAahF,MAAG+E,MAAhB,GAA0B/E,MAAG+E,IAAI,cAErDW,MAAY,MAAMC,MAAMF,aAAaX,kBAAkBW,aAAa/F,OAAOsF,UAAU,CAAC;GAItF,IAAI,CAACU,IAAGE,IACN,MAAUC,MACR,6BAA6B7F,MAAGqG,oBAAqBrG,MAAGU,IAAI,KAAMgF,IAAGxF,OAAO,GAAIwF,IAAGI,WAAW,EAChG;GAGF,IAAAC,YAAkB,MAAML,IAAGM,KAAM,GAEjC8B,UAAgB,EAAA1B,UAAWpG,MAAGqG,iBAAiB,GAC/CJ,WAAiB,MAAM1B,oBAAiB2B,OAAOC,OAC7CnB,aAAA,SAAA,SACAe,WACA+B,OACF;GAsBA8D,AAnBI5L,MAAGsG,cAAe,SACpB3B,QAAOnC,KAAM;IAAAoC,KAAM5E,MAAGU;IAAImE,KAAOoB,SAAQvF;GAAI,CAAC,GAWhD2D,gBAAe7B,KAAM;IAAA,GAAIxC;IAAG,GAAKiG;GAAQ,CAAC,GAE1C6I,mBAAmB,GACnBpL,WAAW;IAAAnD,MACH,eAAeuO,gBAAe,GAAIF,YAAW;IAASpO,MACtD;GACR,CAAC,GACDoL,YAAY,CAACkD,iBAAiBF,WAAW,CAAC;EAAC;EAG7C,IAAA;GAIE,MAAMjO,mBAHsByK,QAAOnD,OAAQkH,MAAsB,CAAC,CAAA3I,IAAK4I,MAG9CF,GAAqB,GAAGF,UAAU;EAAC,SAAAK,KAAA;GACrDjN,IAAAA,QAAAA;GAIPsB,AAHAS,QAAOjB,MAAOd,KAAG,GACjBmJ,iBAAiB,EAAK,GACtBK,YAAY,CAAC,GAAG,CAAC,CAAC,GAClBlI,WAAW;IAAAlD,MACH;IAAUD,MACV6B,iBAAeyD,QAAQzD,MAAGM,UAA1B;GACR,CAAC;GAAC;EAAA;EAQJ,IAAA4M,aAAmB,IAAIlI,IAAIzC,QAAO6B,IAAK+I,OAAiC,CAAC,GACzEC,wBACEF,WAAUG,SAAU,IAApBpL,kBAEIA,gBAAemC,KAAKkJ,UAAA;GAClB,IAAAhJ,aAAmBvJ,gBAAgB,UAAU6C,KAAG;GAEhD,IAAI,CAAC0G,WAAUlF,QAAO,OACbxB;GAMT,IAAA2P,YAAgB3P;GAad,OAXF0G,WAAUE,SAASC,QAAA;IACjB,IAAAC,cACE,OAAOD,IAAG9E,SAAW,WAAWuN,WAAU5H,IAAKb,IAAG9E,KAAkB,IAApEX,KAAAA;IAEF,AAAI0F,gBACE6I,cAAc3P,UAChB2P,YAAYhJ,gBAAgB3G,KAAG,IAGjC9B,KAAKyR,WAAW9I,IAAGI,KAAKxE,KAAM,GAAG,GAAGqE,WAAW;GAChD,CACF,GAEM6I;EAAS,CACjB,GAGP5L,cAAoBQ,oBAAiBR,YAAa;EAElDyL,sBAAqB5I,SAASgJ,UAAA;GAC5B7L,YAAWC,gBAAiBhE,KAAG;EAAC,CACjC;EAED,IAAA6P,wBAAwB;GACtBxD,sBAAsBjB,SAASN,WAAW,CAAC,CAAAwC,MAAOnJ,QAAOjB,KAAM;EAAC;EAGlE,IAAA;GAIE2M,AAHA,MAAM9L,YAAWE,OAAQ,GACzBP,WAAW;IAAAlD,MAAO;IAAUD,MAAQ;GAAuB,CAAC,GAE5DsP,gBAAgB;EAAC,SAAAC,KAAA;GACV1N,IAAAA,QAAAA;GACP,IAAIQ,yBAAyBR,KAAG,GAC9B,MAAMyF,qBAAqB;IAAAzF,KACzBA;IAAGiC,iBACcmL;IAAqBlL;IAAAC,mBAEtCA;IAAiB5E;IAAAD;IAAAgE;IAAAC,WAINkM;IAAepL,aACb,IAAIC,IAAI0G,QAAOnD,OAAQ8H,OAAuB,CAAC,CAAAvJ,IAAKwJ,OAAsB,CAAC;IAACrL;GAE3F,CAAC;QAAC;IAEF,IAAAhC,cAAoBR,oBAAoBC,KAAG;IAC3CsB,WAAW;KAAAlD,MACH;KAAUD,MACVoC,eAAA;IACR,CAAC;GAAC;EACH;EAKH,IAFA4I,iBAAiB,EAAK,GACtBK,YAAY,CAAC,GAAG,CAAC,CAAC,GACd/L,cACF,IAAA;GACE,MAAMA,aAAa;EAAC,SAAAoQ,KAAA;GACb/M,IAAAA,QAAAA,KACP3C,OAAa2C,iBAAiB2C,QAAQ3C,MAAKR,UAAWwN,OAAOhN,KAAK;GAClEQ,WAAW;IAAAlD,MAAO;IAAUD,MAAQ,+BAA+BA;GAAM,CAAC;EAAC;CAE9E,GACF8I,EAAA,MAAAyB,aAAAzB,EAAA,MAAAxJ,cAAAwJ,EAAA,MAAA/E,cAAA+E,EAAA,MAAA+B,SAAA/B,EAAA,MAAA1J,cAAA0J,EAAA,MAAA3J,OAAA2J,EAAA,MAAAgD,uBAAAhD,EAAA,MAAAqF,OAAAA,MAAArF,EAAA;CAlLD,IAAAsF,kBAAAD,KAoLAyB,eAAA,SAAAA,aAAAC,GAAA;EACE,IAAI,CAAC/F,kBAAiB7I,QAAO;EAI7B,IAAA6O,WAAiBhG,kBAAiBtD,MAAMuJ,YAAWC,QAAK/D,SAAU4D,EAACI,cAAczO,KAAM;EAEvF,AAAIsO,aACFtF,eAAesF,QAAQ,GACvBhE,sBAAsBjB,SAASiF,QAAQ,CAAC,CAAA/C,MAAOnJ,QAAOjB,KAAM;CAC7D,GAGHuN,eAAqBrF,QAAO5J,QAAO6N;CAAA,AAAAhG,EAAA,QAAA+B,UAC2CiE,MAAAhG,EAAA,OAAxDgG,MAAAjE,QAAOsF,UAAWC,OAAqC,GAACtH,EAAA,MAAA+B,SAAA/B,EAAA,MAAAgG;CAA9E,IAAAuB,gBAAsBvB,KAAwDS;CAAA,AAAAzG,EAAA,QAAA+B,UAG7E0E,MAAAzG,EAAA,OAF8ByG,MAAA1E,QAAOnD,OACpC4I,OACF,GAACxH,EAAA,MAAA+B,SAAA/B,EAAA,MAAAyG;CAFD,IAAAgB,yBAA+BhB,IAE9BtO,QAAOyO;CAAA,AAAA5G,EAAA,QAAA+B,UAGP6E,MAAA5G,EAAA,OAF2B4G,MAAA7E,QAAOnD,OACjC8I,OACF,GAAC1H,EAAA,MAAA+B,SAAA/B,EAAA,MAAA4G;CAFD,IAAAe,sBAA4Bf,IAE3BzO,QACDyP,gBAAsBH,yBAAyBE,qBAC/CE,mBAAyBpG,aAAWqG,SAAWrG,aAAW0B,MAC1D4E,wBACE,IAAI1M,IAAI2F,kBAAiB7D,IAAK6K,OAA2B,CAAC,CAAApJ,OAAQqJ,OAAO,CAAC,CAAC,CAAA7B,OAAQ,GAAC8B;CAAA,AAAAlI,EAAA,QAAAoH,gBAAApH,EAAA,QAAA4H,iBAElEM,MAAA;EAACN;EAAe;EAAKR;EAAc;CAA+B,GAACpH,EAAA,MAAAoH,cAAApH,EAAA,MAAA4H,eAAA5H,EAAA,MAAAkI,OAAAA,MAAAlI,EAAA;CAAvF,IAAAmI,cAAoBD,IAAmE9O,KAAM,GAAG,GAACgP;CAAA,AAAApI,EAAA,QAAAyB,aAAAd,aAAAX,EAAA,QAAA6H,oBAAA7H,EAAA,QAAA/E,gBAAA+E,EAAA,QAAA2H,uBAAA3H,EAAA,QAAAyH,0BAEjGW,kBAAwB,CAAC,WAAW,GAEhCX,yBAAyB,KAC3BW,gBAAejP,KACb0N,OAAOY,sBAAsB,GAC7BA,2BAA2B,IAA3B,aAAA,WACF,GAGEE,sBAAsB,MAEpBF,yBAAyB,KAC3BW,gBAAejP,KAAM,KAAK,GAG5BiP,gBAAejP,KACb0N,OAAOc,mBAAmB,GAC1BA,wBAAwB,IAAxB,UAAA,QACF,IAGE1M,aAAY8F,OAAQ,CAAC,CAAAJ,cAAec,aAAWd,aACjDyH,gBAAejP,KAAM,kBAAkB,GAGzCiP,gBAAejP,KAAM,MAAM0N,OAAOgB,gBAAgB,CAAC,GAAC7H,EAAA,MAAAyB,aAAAd,WAAAX,EAAA,MAAA6H,kBAAA7H,EAAA,MAAA/E,cAAA+E,EAAA,MAAA2H,qBAAA3H,EAAA,MAAAyH,wBAAAzH,EAAA,MAAAoI,mBAAAA,kBAAApI,EAAA;CAEpD,IAAAqI,aAAmBD,gBAAehP,KAAM,GAAG;CAE3C,IAAI4H,kBAAiB7I,SAAU,GAAC;EAAA,IAAAmQ;EAIjB,OAJiBtI,EAAA,QAAA6B,OAAAC,IAAA,2BAAA,KAE5BwG,MAAA,qBAAC,UAAD;GAAe,MAAA;GAAf,UAAA,CACE,oBAAA,QAAA,EAAA,UAAM,mBAAuB,CAAA,GAAA,2DADtB;MAEEtI,EAAA,MAAAsI,OAAAA,MAAAtI,EAAA,KAFXsI;CAEW;CAIf,IAAI,CAAC7G,aAAW;EAAA,IAAA6G;EAKD,OALCtI,EAAA,QAAA6B,OAAAC,IAAA,2BAAA,KAEZwG,MAAA,qBAAC,UAAD;GAAe,MAAA;GAAf,UAAA;IAA0B;IACoD;IAC5E,oBAAA,QAAA,EAAA,UAAM,mBAAuB,CAAA;IAAA;GAFtB;MAGEtI,EAAA,MAAAsI,OAAAA,MAAAtI,EAAA,KAHXsI;CAGW;CAQkB,IAAAA,MAAA5S,aAAayK,UAAU,GAACoI;CAAA,AAAAvI,EAAA,QAAA6B,OAAAC,IAAA,2BAAA,KAG7ByG,MAAA,EAAAC,MAAO,EAAC,GAACxI,EAAA,MAAAuI,OAAAA,MAAAvI,EAAA;CAAA,IAAAyI;CAAA,AAAAzI,EAAA,QAAA6B,OAAAC,IAAA,2BAAA,KACrB2G,MAAA,oBAAC,OAAD,EAAA,UAAO,iBAAD,CAAA,GAAuBzI,EAAA,MAAAyI,OAAAA,MAAAzI,EAAA;CAAA,IAAA0I;CAAA,AAAA1I,EAAA,QAAA6B,OAAAC,IAAA,2BAAA,KAU/B4G,MAAA,oBAAC,KAAD;EAAc,SAAA;EAAe,YAAA;EAAkB,eAAA;EAC7C,UAAA,oBAAC,MAAD;GAAY,MAAA;GACV,UAAA,oBAAC,gBAAD,CAAe,CAAA;EADZ,CAAA;CADH,CAAA,GAIE1I,EAAA,MAAA0I,OAAAA,MAAA1I,EAAA;CACL,IAAA2I,KAAAtU,OAAKuU;CAAA,AAAA5I,EAAA,QAAA6B,OAAAC,IAAA,2BAAA,KAAQ8G,MAAA,EAAAJ,MAAO,EAAC,GAACxI,EAAA,MAAA4I,OAAAA,MAAA5I,EAAA;CAAO,IAAC8I;CAAA,AAAA9I,EAAA,QAAA6B,OAAAC,IAAA,2BAAA,KAC7BgH,MAAA,oBAAC,OAAD,EAAA,UAAO,iBAAD,CAAA,GAAuB9I,EAAA,MAAA8I,OAAAA,MAAA9I,EAAA;CAC5B,IAAA+I,KAAAzU,QACE0U,MAAAhI,kBAAiB7D,KAAK8L,YACrB,qBAAA,UAAA;EAAgC,OAAA/B,QAAK/D;EAAiB,UAAA+D,QAAKlQ;EAA3D,UAAA;GACGkQ,QAAKY,SAAUZ,QAAK/D;GACpB4E,wBAAA,KAA6Bb,QAAKvG,UAAU,KAA5C;GACAY,kBAAgB4B,SAAW+D,QAAK/D,QACjC5B,iBAAgBZ,cAAeuG,QAAKvG,YADnC,eAAA;EAIM;CAPIuG,GAAAA,QAAK/D,IAOT,CACV,GAAC+F;CAAA,AAAAlJ,EAAA,QAAA+I,MAAA/I,EAAA,QAAA8G,gBAAA9G,EAAA,QAAAgJ,OAVJE,MAAA,oBAAC,IAAD;EAAkBpC,UAAAA;EACfkC,UAAAA;CADI,CAAA,GAWEhJ,EAAA,MAAA+I,IAAA/I,EAAA,MAAA8G,cAAA9G,EAAA,MAAAgJ,KAAAhJ,EAAA,MAAAkJ,OAAAA,MAAAlJ,EAAA;CAAA,IAAAmJ;CAAA,AAAAnJ,EAAA,QAAA2I,MAAA3I,EAAA,QAAA4I,OAAA5I,EAAA,QAAA8I,OAAA9I,EAAA,QAAAkJ,OAbXC,MAAA,qBAAC,IAAD;EAAc,OAAAP;EAAgB,KAAAC;EAA9B,UAAA,CACEC,KACAI,GAFI;KAcElJ,EAAA,MAAA2I,IAAA3I,EAAA,MAAA4I,KAAA5I,EAAA,MAAA8I,KAAA9I,EAAA,MAAAkJ,KAAAlJ,EAAA,MAAAmJ,OAAAA,MAAAnJ,EAAA;CAAA,IAAAoJ;CAAA,AAAApJ,EAAA,QAAAiC,iBAAAjC,EAAA,QAAAsC,YAGT8G,MAAAnH,iBACC,oBAAC,MAAD;EAAM,QAAA;EAAe,QAAA;EACnB,UAAA,oBAAC,MAAD;GACS,OAAA;IAAAoH,OACE;IAAMC,WAGF,UAAUhH,SAAQ,KAAM,IAAIA,SAAQ,KAAMA,SAAQ,KAAxC,EAA+C;IAAGiH,iBACtD;IAAMC,YACX;IAAoBC,WACrB;GACb;GACS,SAAA;GACJ,MAAA;EAAU,CAAA;CAZd,CAAA,GAeNzJ,EAAA,MAAAiC,eAAAjC,EAAA,MAAAsC,UAAAtC,EAAA,MAAAoJ,OAAAA,MAAApJ,EAAA;CAAA,IAAA0J;CAAA,AAAA1J,EAAA,QAAAmI,eAAAnI,EAAA,QAAA+B,WAAA/B,EAAA,QAAAgC,cACA0H,MAAA3H,QAAO5J,SAAU,KAAjB,qBAAA,YAAA,EAAA,UAAA,CAEG,oBAAC,OAAD,EAAA,UAAQgQ,YAAF,CAAA,GACN,oBAAC,eAAD;EAAwBpG;EAAqBC;CAAU,CAAA,CAAI,EAAA,CAAA,GAE9DhC,EAAA,MAAAmI,aAAAnI,EAAA,MAAA+B,SAAA/B,EAAA,MAAAgC,YAAAhC,EAAA,MAAA0J,OAAAA,MAAA1J,EAAA;CAAA,IAAA2J;CAAA,AAAA3J,EAAA,QAAA8C,iBASA6G,MAAA3J,EAAA,OAJA2J,MAAA7G,kBACC,oBAAC,MAAD;EAAe,SAAA;EAAW,QAAA;EAAW,QAAA;EAAS,MAAAA,eAAc3L;EAC1D,UAAA,oBAAC,MAAD;GAAY,MAAA;GAAI2L,UAAAA,eAAc5L;EAAzB,CAAA;CADF,CAAA,GAGN8I,EAAA,MAAA8C,gBAAA9C,EAAA,MAAA2J;CAAA,IAAAC;CAAA,AAAA5J,EAAA,QAAAuH,iBAAAvH,EAAA,QAAAsE,kBAAAtE,EAAA,QAAA+B,WAAA/B,EAAA,QAAAS,UACAmJ,MAAA7H,QAAO5J,SAAU,IAChB,oBAAC,OAAD,EAAA,UACG4J,QAAO5E,KAAK0M,KAAAxK,UAAA;EAAC,IAAA,EAAA1I,KAAAmT,QAAAlT,SAAAmT,WAAAlT,QAAAmT,UAAAlT,aAAA+S,KACZI,aAAmBxJ,OAAMpC,IAAK1H,OAAGuT,KAAM;EAAC,OAGtC,qBAAC,UAAD,EAAA,UAAA,CACE,qBAAC,MAAD;GAAY,OAAA;GAAZ,UAAA;IACE,oBAAC,UAAD;KAAmBtT,SAAAA;KAAmB,gBAAM0N,eAAe3N,OAAGU,GAAI;IAAC,CAAA;IACnE,oBAAC,KAAD;KAAW,MAAA;KAAa,UAAA;KACrB4S,UAAAA,aACC,oBAAC,SAAD;MAAgBtT,OAAAA;MAAiBsT;KAAU,CAAA,IAE3C,oBAAC,MAAD;MAAW,MAAA;MAAU,UAAA;KAAhB,CAAA;IAJL,CAAA;IAOJ,qBAAC,MAAD;KAAY,OAAA;KAAc,KAAA;KAA1B,UAAA,CACGnT,WAAW,oBAAC,aAAD;MAAoB,QAAA;MAAuB,SAAA;KAAK,CAAA,IAA3D,MACD,oBAAC,aAAD;MAAqBD,QAAAA;MAAiB,SAAAtD,UAAUoD,OAAGU,GAAI;KAAC,CAAA,CAFrD;;GATF;EAcJV,CAAAA,GAAAA,OAAGsG,cAAkB,SAASoC,UAAUkI,iBACvC,oBAAC,MAAD;GAAe,SAAA;GAAW,QAAA;GAAW,QAAA;GAAQ,MAAA;GAC3C,UAAA,qBAAC,MAAD;IAAY,MAAA;IAAZ,UAAA;KAAe;KAEO,oBAAA,QAAA,EAAA,UAAM,MAAU,CAAA;KAAA;KAC1B,oBAAA,QAAA,EAAA,UAAM,MAAU,CAAA;KAAA;KACA,oBAAA,QAAA,EAAA,UAAM,MAAU,CAAA;KAAA;KAEtC,oBAAA,QAAA,EAAA,UAAM,MAAU,CAAA;KAAA;IANjB;;EADF,CAAA,CAhBA,EAAA,GAAM5Q,OAAGU,GAAT;CA2BE,CAEd,EAlCG,CAAA,IAqCN,oBAAC,MAAD;EAAe,SAAA;EAAS,OAAA;EAAiB,SAAA;EACvC,UAAA,oBAAC,SAAD,CAAQ,CAAA;CADL,CAAA,GAGN2I,EAAA,MAAAuH,eAAAvH,EAAA,MAAAsE,gBAAAtE,EAAA,MAAA+B,SAAA/B,EAAA,MAAAS,QAAAT,EAAA,MAAA4J,OAAAA,MAAA5J,EAAA;CAAA,IAAA6J;CAAA,AAAA7J,EAAA,QAAA0E,oBAAA1E,EAAA,QAAA2C,iBAAA3C,EAAA,QAAAiC,iBAAAjC,EAAA,QAAAmC,eAAAnC,EAAA,QAAA4H,iBAEEiC,MAAAlH,iBACC,oBAAC,QAAD;EACY,UAAA;EACD,SAAA;EACJ,MAAA;EACA,MAAA;EACC9O,MAAAA;EACG,eAAM,KAAK6Q,iBAAiB;EAChC,MAAA;EACK,UAAAzC,iBAAA,CAAkB2F,iBAAlBzF;CAA8C,CAAA,GAE3DnC,EAAA,MAAA0E,kBAAA1E,EAAA,MAAA2C,eAAA3C,EAAA,MAAAiC,eAAAjC,EAAA,MAAAmC,aAAAnC,EAAA,MAAA4H,eAAA5H,EAAA,MAAA6J,OAAAA,MAAA7J,EAAA;CAAA,IAAAmK;CAAA,AAAAnK,EAAA,QAAAsF,kBAMsC6E,MAAAnK,EAAA,OAA5BmK,YAAM,KAAK7E,gBAAgB,GAACtF,EAAA,MAAAsF,iBAAAtF,EAAA,MAAAmK;CAE3B,IAAAC,MAAAnI,iBAAA,CAAkB2F,iBAAlBzF,aAA8CkI;CAAA,AAAArK,EAAA,QAAAqI,cAAArI,EAAA,QAAAmK,OAAAnK,EAAA,QAAAoK,OAP1DC,MAAA,oBAAC,QAAD;EACY,UAAA;EACD,SAAA;EACJ,MAAA;EACCzW,MAAAA;EACG,SAAAuW;EACH9B,MAAAA;EACI,UAAA+B;CAA8C,CAAA,GACxDpK,EAAA,MAAAqI,YAAArI,EAAA,MAAAmK,KAAAnK,EAAA,MAAAoK,KAAApK,EAAA,MAAAqK,OAAAA,MAAArK,EAAA;CAAA,IAAAsK;CAAA,AAAAtK,EAAA,QAAA6J,OAAA7J,EAAA,QAAAqK,OArBJC,MAAA,qBAAC,OAAD;EAAY,KAAA;EAAZ,UAAA,CACGT,KAYDQ,GAbI;KAsBErK,EAAA,MAAA6J,KAAA7J,EAAA,MAAAqK,KAAArK,EAAA,MAAAsK,OAAAA,MAAAtK,EAAA;CAAA,IAAAuK;CAEL,OAFKvK,EAAA,QAAA2J,OAAA3J,EAAA,QAAA4J,OAAA5J,EAAA,QAAAsK,OAvEZC,MAAA,oBAAC,MAAD;EAAM,WAAA;EAAmB,SAAA;EACvB,UAAA,qBAAC,OAAD;GAAY,KAAA;GAAZ,UAAA;IACGZ;IAKAC;IA0CDU;GAhDI;;CADH,CAAA,GAyEEtK,EAAA,MAAA2J,KAAA3J,EAAA,MAAA4J,KAAA5J,EAAA,MAAAsK,KAAAtK,EAAA,MAAAuK,OAAAA,MAAAvK,EAAA,KAzIb,oBAAC,WAAD;EAAkB,OAAA;EAChB,UAAA,oBAAC,MAAD;GAAM,QAAA;GACJ,UAAA,qBAAC,OAAD,EAAA,UAAA,CACE,oBAAC,MAAD;IAAe,SAAA;IAAU,OAAAsI;IACvB,UAAA,qBAAC,OAAD;KAAY,KAAA;KAAZ,UAAA;MACE,qBAAC,MAAD;OAAW,KAAA;OAAX,UAAA;QACE,qBAAC,OAAD;SAAc,OAAAC;SAAgB,KAAA;SAA9B,UAAA,CACEE,KACA,oBAAC,QAAD;UAAQ,UAAA;UAAgB,OAAAlH,kBAAgB4B;UACrC5B,UAAAA,mBACC,qBAAA,UAAA;WAAe,OAAAA,iBAAgB4B;WAA/B,UAAA,CACG5B,iBAAgBuG,SAAUvG,iBAAgB4B,MAC1C4E,wBAAA,KAA6BxG,iBAAgBZ,UAAU,KAAvD,EACM;UAJV,CAAA,IAAA;SADI,CAAA,CAFH;;QAWN+H;QAKAS;OAjBG;;MAkCJC;MAiBAM;KApDG;;GADH,CAAA,GA6DLa,GA9DI,EAAA,CAAA;EADH,CAAA;CADG,CAAA;AA4IE;AA7iBD,SAAAvC,QAAAwC,SAAA;CAAA,OA8W8BtD,SAAKvG;AAAW;AA9W9C,SAAA+G,QAAA+C,QAAA;CAAA,OAyWD9S,OAAIf,WAAYrD,UAAUoE,OAAIhB,IAAIU,GAAI;AAAC;AAzWtC,SAAAmQ,QAAAkD,QAAA;CAAA,OAsWD/S,OAAIf,WAAJ,CAAiBrD,UAAUoE,OAAIhB,IAAIU,GAAI;AAAC;AAtWvC,SAAAiQ,QAAA/G,IAAA;CAoW4B,IAAA,EAAA5J,KAAAgU,UAAApK;CAAK,OAAK5J,MAAGsG,cAAkB;AAAK;AApWhE,SAAA0J,QAAAiE,QAAA;CAAA,OA8TsEjT,OAAIhB,IAAIU;AAAI;AA9TlF,SAAAqP,QAAAmE,QAAA;CAAA,OA8TyC,CAAClT,OAAIf;AAAQ;AA9TtD,SAAAsP,QAAA3F,IAAA;CAmQ6B,IAAA,EAAAhF,KAAAC,KAAAsP,SAAAvK;CAAgB,OAAK,CAAChF,KAAKuP,IAAI;AAAC;AAnQ7D,SAAA/E,OAAAgF,QAAA;CAAA,OAgPwEpT,OAAIhB;AAAI;AAhPhF,SAAAmP,OAAAkF,QAAA;CAAA,OAgP4CrT,OAAIf;AAAQ;AAhPxD,SAAA4O,OAAAjF,IAAA;CAyKyB,IAAA,EAAA5J,KAAAsU,OAAArU,YAAA2J;CAAc,OAAK3J,WAAWrD,UAAUoD,MAAGU,GAAI;AAAC;AAzKzE,SAAA6N,OAAA3E,IAAA;CA2ImC,IAAA,EAAAlJ,KAAA6T,UAAA3K;CAAK,OAAKlJ;AAAG;AA3IhD,SAAA0N,OAAA7K,IAAA;CAAA,OAsIsB,UAAUA;AAAI;AAtIpC,SAAA0K,OAAAuG,OAAA;CAAA,OA8HwBxU,MAAGU;AAAI;AA9H/B,SAAA2M,OAAAoH,OAAA;CAAA,OAsGkD;EAAAxU,SAAU;EAAID,KAAEA;CAAG;AAAC;AAtGtE,SAAA8M,OAAA4H,OAAA;CAAA,OAyEkD,CAAC1U,MAAGU,KAAMV,KAAG;AAAC;AAzEhE,SAAA0M,OAAA9C,IAAA;CA8D2B,IAAA,EAAA5J,KAAA2U,UAAA/K;CAAK,OAAK5J,MAAGU;AAAI;AA9D5C,SAAAqL,OAAA6I,KAAA5U,KAAA;CAAA,OA+CqB4U,MAAMzX,gBAAgB,UAAU6C,GAAG,CAAC,CAAAwB;AAAO;AA/ChE,SAAAwJ,QAAAuF,OAAA;CAAA,OAoC4C,CAACA,MAAKlQ;AAAS;ACrmB1E,SAAwB+V,gBAAgBC,OAA6B;CACnE,IAAM,EAACN,OAAOC,iBAAgBK,OAExB,EAACC,SAASC,mBAAmBC,eAAcR,cAC3CS,eAAef,UAAU,EAACc,WAAU,CAAC,GAGrCG,cADSlB,UACKiB,CAAM,CAACE,aAAa,GAElC,CAACC,OAAOC,YAAYtB,SAAS,EAAE,GAC/B,CAACuB,SAASC,cAAcxB,SAAS,EAAK,GACtC,CAACyB,aAAaC,kBAAkB1B,SAAsB,EAC1DW,MAAM,CAAA,EACR,CAAC;CAED,eAAegB,WAAW;EACxB,IAAI;GACF,IAAMC,MAAM,MAAMX,aAAaY,MAAwBR,KAAK,GAGtDS,6BAA6BF,IAAIG,SACnCH,IACGI,QAAQC,QAAQd,YAAYe,SAASD,IAAIE,KAAK,CAAC,CAAC,CAChDH,QAAQC,UAAQ,CAACA,MAAIG,IAAIC,WAAW,SAAS,CAAC,IACjD,CAAA;GAKJb,AAHAE,eAAe,EACbf,MAAMmB,2BACR,CAAC,GACDN,WAAW,EAAI;EACjB,SAASc,KAAK;GACZC,QAAQC,MAAMF,GAAG;EACnB;CACF;CAEA,SAASG,aAAaC,GAAkC;EAEtD,AADIA,KAAGA,EAAEE,eAAe,GACxB,SAAc;CAChB;CAEA,OACE,oBAAC,MAAD;EAAM,SAAS;GAAC;GAAG;GAAG;GAAG;EAAC;EACxB,UAAA,oBAAC,WAAD,EAAA,UACE,qBAAC,MAAD;GAAM,qBAAqB;IAAC;IAAG;IAAG;IAAG;GAAC;GAAG,KAAK;IAAC;IAAG;IAAG;IAAG;GAAC;GAAzD,UAAA;IACE,qBAAC,KAAD;KAAK,SAAS;MAAC;MAAG;MAAG;MAAG;KAAC;KAAzB,UAAA,CACE,oBAAC,MAAD;MAAM,SAAS;MAAG,QAAQ;MAAG,QAAA;MAC3B,UAAA,qBAAC,OAAD;OAAO,KAAK;OAAZ,UAAA;QACE,oBAAC,KAAD,EAAA,UACE,oBAAC,OAAD,EAAA,UAAO,0BAA8B,CAAA,EAClC,CAAA;QACL,oBAAC,KAAD,EAAA,UACE,oBAAC,MAAD,EAAA,UAAK,uJAGC,CAAA,EACH,CAAA;QACL,oBAAC,QAAD;SAAM,UAAUH;SACd,UAAA,qBAAC,MAAD,EAAA,UAAA,CACE,oBAAC,KAAD;UAAK,MAAM;UAAG,cAAc;UAC1B,UAAA,oBAAC,WAAD;WACE,OAAO,EAACI,YAAY,YAAW;WAC/B,UAAU;WACV,WAAWC,UAAUxB,SAASwB,MAAMC,cAAc1B,KAAK;WACvD,SAAS;WACT,aAAa;WACb,OAAOA,SAAS;UAAG,CAAA;SAElB,CAAA,GACL,oBAAC,QAAD;UACE,SAAS;UACT,UAAU;UACV,MAAK;UACL,eAAeoB,aAAa;UAC5B,MAAK;UACL,UAAU,CAACpB;SAAM,CAAA,CAEf,EAAA,CAAA;QACF,CAAA;OACD;;KACH,CAAA,GACLN,qBAAqBA,mBAAmBgB,SAAS,KAChD,oBAAC,MAAD;MAAM,WAAW;MAAG,SAAS;MAAG,QAAQ;MAAG,QAAA;MACzC,UAAA,oBAAC,KAAD,EAAA,UACE,qBAAC,OAAD;OAAO,KAAK;OAAZ,UAAA,CACE,oBAAC,KAAD,EAAA,UACE,oBAAC,OAAD,EAAA,UAAO,qBAAyB,CAAA,EAC7B,CAAA,GACL,oBAAC,OAAD;QAAO,KAAK;QACThB,UAAAA,kBAAkBiC,KAAKC,UACtB,oBAAC,QAAD;SAEE,SAAS;SACT,UAAU;SACV,MAAK;SACL,eAAe3B,SAAS,KAAK2B,MAAMA,MAAK,EAAG;SAC3C,MAAMA,MAAMC;QAAM,GALbD,MAAMC,MAAMC,QAAQ,QAAQ,GAAG,CAKlB,CAErB;OACI,CAAA,CACF;MACJ,CAAA,EAAA,CAAA;KACD,CAAA,CAEL;;IACJ5B,WAAWE,YAAYd,KAAKoB,SAAS,KACpC,oBAAC,WAAD;KAAW,OAAO;KAChB,UAAA,oBAAC,MAAD;MAAM,SAAS;MACZV,UAAAA,QAAQ,kCAAkC;KACvC,CAAA;IACG,CAAA;IAEZI,YAAYd,MAAMoB,SAAS,KAC1B,oBAAC,YAAD;KAAY,MAAMN,YAAYd;KAAaJ;KAAqBC;IAAa,CAAA;GAE3E;EACG,CAAA,EAAA,CAAA;CACP,CAAA;AAEV;AC/HA,SAAesD,kBAAAC,OAAA;CAAA,IAAAC,IAAAC,EAAA,EAAA,GACb,EAAAC,MAAAC,OAAAC,cAAAC,iBAAkDN,OAAKO;CAAA,AAAAN,EAAA,OAAAO,OAAAC,IAAA,2BAAA,KACEF,KAAA,CAAA,GAAEN,EAAA,KAAAM,MAAAA,KAAAN,EAAA;CAA3D,IAAA,CAAAS,SAAAC,cAA8BlB,SAA2Bc,EAAE,GAC3D,EAAAK,QAAAC,eAA6BR,cAG7B,CAAAS,MAAAC,WAAwBtB,SACtBmB,OAAMI,WAAY,IAAKJ,OAAM,MAAN,aAAvB,UACF,GAACK;CAAA,AAAAhB,EAAA,OAAAY,aACoCI,KAAAhB,EAAA,MAAZgB,KAAA,EAAAJ,WAAW,GAACZ,EAAA,KAAAY,YAAAZ,EAAA,KAAAgB;CAArC,IAAAC,SAAetB,UAAUqB,EAAY,GAACE,IAAAC;CAItC1B,AAJsCO,EAAA,OAAAiB,UAAAjB,EAAA,OAAAE,QAAAF,EAAA,OAAAW,UAI5BO,WAAA;EAcRE,CAAAA,eAbAA,eAAA;GACE,IAAAC,aAAmBnB,KAAI,EAAQ,EAAAoB;GAE/B,IAAI,CAACX,OAAMY,SAAU,SAAS,KAA1B,CAAgCF,YAAU;GAI9C,IAAAG,oBAA0B,MAAMP,OAAMQ,MAAyB,sBAAsB,EAAAC,IAC/EL,WACN,CAAC;GACDX,WAAW,CAAA,GAAIR,MAAI,GAAKsB,iBAAiB,CAAC;EAAC,EAAA,CAGhC,CAAC,CAAAG,MAAOC,QAAOC,KAAM;CAAC,GAClCV,KAAA;EAACF;EAAQf;EAAMS;CAAM,GAACX,EAAA,KAAAiB,QAAAjB,EAAA,KAAAE,MAAAF,EAAA,KAAAW,QAAAX,EAAA,KAAAkB,IAAAlB,EAAA,KAAAmB,OAAAD,KAAAlB,EAAA,IAAAmB,KAAAnB,EAAA,KAfzBP,UAAUyB,IAePC,EAAsB;CAAC,IAAAW;CAAA,AAAA9B,EAAA,OAAAW,UAAAX,EAAA,OAAAS,WAAAT,EAAA,QAAAa,QAIrBiB,KAAAnB,OAAMI,SAAU,MAAMJ,OAAMY,SAAU,SAAwC,KAA1BZ,OAAMY,SAAU,UAAU,KAC7E,oBAAC,MAAD;EAAgB,UAAA;EAAkB,eAAA;EAAiB,cAAA;EAAG,cAAA;EACpD,UAAA,qBAAC,MAAD;GAA2B,qBAAA;GAAQ,KAAA;GAAnC,UAAA,CACGZ,OAAMY,SAAU,UAQV,IAPL,oBAAC,QAAD;IACO,MAAA;IACA,MAAA;IACK,UAAAV,SAAS;IACV,eAAMC,QAAQ,UAAU;IAC5B,MAAA;GAAU,CAAA,IANlB,MASAH,OAAMY,SAAU,SASV,IARL,oBAAC,QAAD;IACO,MAAA;IACA,MAAA;IACK,UAAAV,SAAS;IACV,eAAMC,QAAQ,SAAS;IACtB,UAAAL,QAAOM,WAAY;IACvB,MAAAN,QAAOM,SAAU,IAAjB,YAAiCN,QAAOM,OAAO,KAA/C;GAA4E,CAAA,IAPrF,IAVE;;CADF,CAAA,IADN,MAwBOf,EAAA,KAAAW,QAAAX,EAAA,KAAAS,SAAAT,EAAA,MAAAa,MAAAb,EAAA,MAAA8B,MAAAA,KAAA9B,EAAA;CAEA,IAAA+B,KAAAlB,SAAS,aAATX,OAAAO,SAAoCuB;CAAA,AAAAhC,EAAA,QAAAK,gBAAAL,EAAA,QAAAI,gBAAAJ,EAAA,QAAA+B,MAAA/B,EAAA,QAAAG,SAD5C6B,KAAA,oBAAC,YAAD;EACQ,MAAAD;EACC5B;EACOC;EACAC;CAAY,CAAA,GAC1BL,EAAA,MAAAK,cAAAL,EAAA,MAAAI,cAAAJ,EAAA,MAAA+B,IAAA/B,EAAA,MAAAG,OAAAH,EAAA,MAAAgC,MAAAA,KAAAhC,EAAA;CAAA,IAAAiC;CACQ,OADRjC,EAAA,QAAA8B,MAAA9B,EAAA,QAAAgC,MA/BJC,KAAA,qBAAC,WAAD,EAAA,UAAA,CACGH,IAyBDE,EA1BQ,EAAA,CAAA,GAgCEhC,EAAA,MAAA8B,IAAA9B,EAAA,MAAAgC,IAAAhC,EAAA,MAAAiC,MAAAA,KAAAjC,EAAA,KAhCZiC;AAgCY;AC5DhB,SAAeQ,YAAAC,IAAA;CAAA,IAAAC,IAAAC,EAAA,CAAA,GAAqB,EAAAJ,eAAAE,IAA8BG;CAAA,AAAAF,EAAA,OAAAH,aAC3BK,KAAAF,EAAA,MAAZE,KAAA,EAAAL,WAAW,GAACG,EAAA,KAAAH,YAAAG,EAAA,KAAAE;CAArC,IAAAC,SAAeT,UAAUQ,EAAY,GAACE;CAAA,AAAAJ,EAAA,OAAAG,SAIrCC,KAAAJ,EAAA,MAF+BI,WAAA;EAC9BD,OAAME,OAAQ,EAAAC,OAAQ,qBAAqBX,iBAAgB,IAAI,CAAC,CAAC,CAAAY,MAAOC,QAAOC,KAAM;CAAC,GACvFT,EAAA,KAAAG,QAAAH,EAAA,KAAAI;CAFD,IAAAM,cAAoBN,IAERO;CAAA,AAAAX,EAAA,OAAAY,OAAAC,IAAA,2BAAA,KAGwCF,KAAA;EAAC;EAAG;EAAG;EAAG;CAAC,GAACX,EAAA,KAAAW,MAAAA,KAAAX,EAAA;CAAA,IAAAc;CASvD,OATuDd,EAAA,OAAAU,cASvDI,KAAAd,EAAA,MATPc,KAAA,oBAAC,MAAD;EAAY,OAAA;EAAiB,SAAA;EAAqB,UAAAH;EAAwB,UAAA;EACxE,UAAA,oBAAC,QAAD;GACO,MAAA;GACID,SAAAA;GACJ,MAAA;GACA,MAAA;GACK,UAAA;GACD,SAAA;EAAC,CAAA;CAPT,CAAA,GASEV,EAAA,KAAAU,aAAAV,EAAA,KAAAc,KATPA;AASO;ACfX,MAAMa,mBAAmB,CACvB;CACEC,KAAK;CACLC,OACE;CACFC,aAAa;AACf,CAAC;AAaH,SAAeQ,uBAAAC,OAAA;CAAA,IAAAC,IAAAC,EAAA,EAAA,GACb,EAAAP,MAAAC,MAAAC,iBAAmCG,OACnCG,eAAqBrB,gCAAgC,GAErD,EAAAsB,SAAAC,YAA2B7B,WAAoBO,gBAAgB;CAE/D,IAAIqB,SAAO;EAAA,IAAAE;EAMA,OANAL,EAAA,OAAAM,OAAAC,IAAA,2BAAA,KAEPF,KAAA,oBAAC,MAAD;GAAc,SAAA;GAAe,OAAA;GAC3B,UAAA,oBAAC,KAAD;IAAc,SAAA;IACZ,UAAA,oBAAC,SAAD,CAAQ,CAAA;GADN,CAAA;EADD,CAAA,GAIEL,EAAA,KAAAK,MAAAA,KAAAL,EAAA,IAJPK;CAIO;CAMX,IAAI,CAACD,SAAOZ,aAAa;EAAA,IAAAa;EAOnB,OAPmBL,EAAA,OAAAM,OAAAC,IAAA,2BAAA,KAErBF,KAAA,oBAAC,cAAD;GACQ,OAAA;GACKvB,WAAAA;GACLK,MAAAA;GACG,SAAAqB;EAAU,CAAA,GACnBR,EAAA,KAAAK,MAAAA,KAAAL,EAAA,IALFK;CAKE;CAIN,IAAIX,SAAS,UAATQ,cAA+B;EAAA,IAAAG;EAAA,AAAAL,EAAA,OAAAE,gBAAAF,EAAA,OAAAI,QAAAZ,eAG7Ba,KAAA,oBAAC,iBAAD;GAAwB,OAAAD,QAAOZ;GAA4BU;EAAY,CAAA,GAAIF,EAAA,KAAAE,cAAAF,EAAA,KAAAI,QAAAZ,aAAAQ,EAAA,KAAAK,MAAAA,KAAAL,EAAA;EAAA,IAAAS;EAAA,AAAAT,EAAA,OAAAE,aAAAQ,aACvBD,KAAAT,EAAA,MAApDS,KAAA,oBAAC,aAAD,EAAyB,YAAAP,aAAYQ,WAAW,CAAA,GAAIV,EAAA,KAAAE,aAAAQ,YAAAV,EAAA,KAAAS;EAAA,IAAAE;EACnD,OADmDX,EAAA,OAAAK,MAAAL,EAAA,OAAAS,MAFtDE,KAAA,qBAAA,YAAA,EAAA,UAAA,CACEN,IACAI,EAAoD,EAAA,CAAA,GACnDT,EAAA,KAAAK,IAAAL,EAAA,KAAAS,IAAAT,EAAA,KAAAW,MAAAA,KAAAX,EAAA,IAHHW;CAGG;CAIP,IAAI,CAAChB,MAAIiB,QAAQ;EAAA,IAAAP;EACgD,OADhDL,EAAA,QAAAM,OAAAC,IAAA,2BAAA,KACRF,KAAA,oBAAC,UAAD,EAAA,UAAU,sCAAD,CAAA,GAA+CL,EAAA,MAAAK,MAAAA,KAAAL,EAAA,KAAxDK;CAAwD;CAGjE,IAAI,CAACH,cAAY;EAAA,IAAAG;EAC6B,OAD7BL,EAAA,QAAAM,OAAAC,IAAA,2BAAA,KACRF,KAAA,oBAAC,UAAD,EAAA,UAAU,mBAAD,CAAA,GAA4BL,EAAA,MAAAK,MAAAA,KAAAL,EAAA,KAArCK;CAAqC;CAC7C,IAAAA;CAQG,OARHL,EAAA,QAAAL,QAAAK,EAAA,QAAAJ,gBAAAI,EAAA,QAAAE,gBAAAF,EAAA,QAAAI,QAAAZ,eAGCa,KAAA,oBAAC,mBAAD;EACQV;EACC,OAAAS,QAAOZ;EACAU;EACAN;CAAY,CAAA,GAC1BI,EAAA,MAAAL,MAAAK,EAAA,MAAAJ,cAAAI,EAAA,MAAAE,cAAAF,EAAA,MAAAI,QAAAZ,aAAAQ,EAAA,MAAAK,MAAAA,KAAAL,EAAA,KALFK;AAKE;AApDS,SAAAG,QAAA;CAAA,OAwBQ;AAAI;;;;;AChD3B,SAAOO,6BAAAC,OAAA;CAAA,IAAAC,IAAAC,EAAA,CAAA,GACL,EAAAC,MAAAC,iBAA6BJ,OAAKK;CAEqD,OAFrDJ,EAAA,OAAAE,QAAAF,EAAA,OAAAG,gBAE3BC,KAAA,oBAAC,wBAAD;EAA6B,MAAA;EAAeF;EAAoBC;CAAY,CAAA,GAAIH,EAAA,KAAAE,MAAAF,EAAA,KAAAG,cAAAH,EAAA,KAAAI,MAAAA,KAAAJ,EAAA,IAAhFI;AAAgF;;;;;ACAzF,MAAaK,qBAAqBC,UAA+B;CAC/D,IAAM,EAACC,OAAOC,cAAaF,OACrB,CAACG,YAAYC,iBAAiBR,SAAS,EAAK;CAElD,OAAO;EACLS,UAAUC,EAAQL;EAClBM,OAAON,QAAQ,wCAAwC;EACvDO,OAAO;EACPC,QAAQN,cACND,aAAa;GACXQ,MAAM;GACNH,OAAO;GACPI,SAAS,oBAAC,8BAAD,EAA8B,MAAM,CAACT,SAAS,EAAE,CAAA;GACzDU,eAAeR,cAAc,EAAK;EACpC;EACFS,gBAAgBT,cAAc,EAAI;EAClCU,MAAMnB;CACR;AACF;AAEAI,kBAAkBgB,SAAS;AClB3B,SAAOQ,2BAAAC,OAAA;CAAA,IAAAC,IAAAC,EAAA,CAAA,GAAAC;CAAA,AAAAF,EAAA,OAAAD,MAAAF,KAAAM,UACuCD,KAAAF,EAAA,MAAxBE,KAAAH,MAAKF,KAAKM,WAAV,CAAuB,GAACH,EAAA,KAAAD,MAAAF,KAAAM,SAAAH,EAAA,KAAAE;CAA5C,IAAA,EAAAP,MAAAS,OAAoBF,IAAwBG;CAAA,AAAAL,EAAA,OAAAI,KAA5BC,KAAAL,EAAA,MAATK,KAAAD,OAAAE,KAAAA,IAAA,CAAA,IAAAF,IAASJ,EAAA,KAAAI,IAAAJ,EAAA,KAAAK;CAAT,IAAAV,OAAAU,IAASE;CAEyC,OAFzCP,EAAA,OAAAL,OAEyCY,KAAAP,EAAA,MAAlDO,KAAA,oBAAC,wBAAD;EAA6B,MAAA;EAAaZ;CAAI,CAAA,GAAIK,EAAA,KAAAL,MAAAK,EAAA,KAAAO,KAAlDA;AAAkD;ACP3D,MAAaK,oCAA2D;CACtEC,OAAO;CACPC,MAAM;CACNC,MAAMP;CACNQ,WAAWN;CACXO,SAAS,EACPC,MAAM,CAAA,EACR;AACF,ICJaO,yBAAyBN,cAA4CQ,SAAS,CAAC,MAAM;CAChG,IAAMC,eAAe;EAAC,GAAGN;EAAgB,GAAGK;CAAM,GAC5C,EAACE,UAASD;CAEhB,OAAO;EACLE,MAAM;EACNC,QAAQC,SAAUJ,aAAaK,OAAO,CAAC,GAAGD,MAAMT,2BAA2B,CAAC,IAAIS;EAChFE,QAAQ,EACNC,YAAY,EACVC,SAASC,UAAU,oBAAC,gBAAD;GAAgB,GAAIA;GAAqBT;EAAa,CAAA,EAC3E,EACF;EACAU,UAAU,EACRC,UAAUP,MAAM,EAACQ,iBACRX,SAASA,MAAMY,SAASD,UAAU,IAAI,CAAC,GAAGR,MAAMZ,iBAAiB,IAAIY,KAEhF;CACF;AACF,CAAC"}
\ No newline at end of file
+{"version":3,"file":"index.js","names":["CrossDatasetDuplicatorContext.Provider","pluginConfig","props.renderDefault(rest)","<CrossDatasetDuplicatorContext.Provider value={pluginConfig}>\n {props.renderDefault(rest)}\n </CrossDatasetDuplicatorContext.Provider>","tone = 'caution'","<Text size={1}>{children}</Text>","<Card padding={3} radius={2} shadow={1} tone={tone}>\n <Text size={1}>{children}</Text>\n </Card>","() =>\n payload.length && payload.every((item) => item.include) ? ['ALL'] : []","payload.length","(item) => item.include","function handleSelectButton(action: Action) {\n if (!payload.length) return\n\n setPayload((current) =>\n current.map((item) => ({...item, include: shouldInclude(item, action)})),\n )\n setDisabledActions([action])\n }","length","item","buttons.map((button) =>\n 'action' in button ? (\n <Button\n key={button.action}\n fontSize={1}\n mode=\"bleed\"\n padding={2}\n text={button.label}\n disabled={disabledActions.includes(button.action)}\n onClick={() => handleSelectButton(button.action)}\n />\n ) : (\n <Card key={button.divider} borderLeft />\n ),\n )","<Card padding={1} radius={3} shadow={1}>\n <Flex gap={2} wrap=\"wrap\">\n {buttons.map((button) =>\n 'action' in button ? (\n <Button\n key={button.action}\n fontSize={1}\n mode=\"bleed\"\n padding={2}\n text={button.label}\n disabled={disabledActions.includes(button.action)}\n onClick={() => handleSelectButton(button.action)}\n />\n ) : (\n <Card key={button.divider} borderLeft />\n ),\n )}\n </Flex>\n </Card>","<Badge padding={2} fontSize={1}>\n Checking...\n </Badge>","{maxWidth: 200}","<Box padding={3} style={{maxWidth: 200}}>\n <Text size={1}>{badgeText}</Text>\n </Box>","['right', 'left']","<Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>","<Badge padding={3} fontSize={1} tone={badgeTone}>\n {badgeStatus}\n <Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>\n </Badge>","<Tooltip\n content={\n <Box padding={3} style={{maxWidth: 200}}>\n <Text size={1}>{badgeText}</Text>\n </Box>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <Badge padding={3} fontSize={1} tone={badgeTone}>\n {badgeStatus}\n <Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>\n </Badge>\n </Tooltip>","{apiVersion: pluginConfig.apiVersion}","apiVersion","workspace","(space) => !space.disabled","[]","[0, 0]","(acc, doc) => acc + extractWithPath(`.._ref`, doc).length","hasReferences\n ? {tone: `caution`, text: createInitialMessage(docs.length, initialRefsCount)}\n : null","length","async function updatePayloadStatuses(payloadActual: PayloadItem[], dest: WorkspaceOption | null) {\n if (!payloadActual.length || !dest?.name) {\n return\n }\n\n const payloadIds = payloadActual.map(({doc}) => doc._id)\n const destinationClient = originClient.withConfig({\n dataset: dest.dataset,\n projectId: dest.projectId,\n })\n const destinationData = await destinationClient.fetch<SanityDocument[]>(\n `*[_id in $payloadIds]{ _id, _updatedAt }`,\n {payloadIds},\n )\n // Index the destination docs by `_id` so status updates stay O(n) instead\n // of O(n²) when looking them up for each payload item below.\n const destinationById = new Map(destinationData.map((doc) => [doc._id, doc]))\n\n setPayload(\n payloadActual.map((item) => {\n const existingDoc = destinationById.get(item.doc._id)\n let status: keyof MessageTypes = 'CREATE'\n\n if (existingDoc?._updatedAt && item.doc._updatedAt) {\n if (existingDoc._updatedAt === item.doc._updatedAt) {\n // Exact same document exists at destination\n // We don't compare by _rev because that is updated in a transaction\n status = `EXISTS`\n } else {\n status =\n new Date(existingDoc._updatedAt) > new Date(item.doc._updatedAt)\n ? // Document at destination is newer\n `OVERWRITE`\n : // Document at destination is older\n `UPDATE`\n }\n }\n\n return {...item, status}\n }),\n )\n }","({doc}) => doc._id","(doc) => [doc._id, doc]","(nextDocs: SanityDocument[]) => {\n const initialPayload: PayloadItem[] = nextDocs.map((doc) => ({include: true, doc}))\n updatePayloadStatuses(initialPayload, destination).catch(console.error)\n }","(doc) => ({include: true, doc})","() => {\n // oxlint-disable-next-line react/set-state-in-effect\n initializePayload(docs)\n }","[docs]","function handleCheckbox(_id: string) {\n setPayload((current) =>\n current.map((item) => (item.doc._id === _id ? {...item, include: !item.include} : item)),\n )\n }","item","async function handleReferences() {\n setIsGathering(true)\n\n try {\n const docIds = docs.map((doc) => doc._id)\n\n const payloadDocs = await getDocumentsInArray({\n fetchIds: docIds,\n client: originClient,\n pluginConfig,\n })\n const draftDocs = await getDocumentsInArray({\n fetchIds: docIds.map((id) => `drafts.${id}`),\n client: originClient,\n projection: `{_id}`,\n pluginConfig,\n })\n const draftDocsIds = new Set(draftDocs.map(({_id}) => _id))\n\n // Shape it up\n const payloadShaped: PayloadItem[] = payloadDocs.map((doc) => ({\n doc,\n // Include this in the transaction?\n include: true,\n // Does it exist at the destination?\n status: undefined,\n // Does it have any drafts?\n hasDraft: draftDocsIds.has(`drafts.${doc._id}`),\n }))\n\n setPayload(payloadShaped)\n updatePayloadStatuses(payloadShaped, destination).catch(console.error)\n } catch (err) {\n console.error(err)\n }\n\n setIsGathering(false)\n }","(doc) => doc._id","(id) => `drafts.${id}`","({_id}) => _id","doc","err","async function handleDuplicate() {\n if (!destination) {\n return\n }\n\n setIsDuplicating(true)\n\n const assetsCount = payload.filter(({doc, include}) => include && isAssetId(doc._id)).length\n let currentProgress = 0\n setProgress([currentProgress, assetsCount])\n\n setMessage({text: 'Duplicating...', tone: `transparent`})\n\n const destinationClient = originClient.withConfig({\n apiVersion: pluginConfig.apiVersion,\n dataset: destination.dataset,\n projectId: destination.projectId,\n })\n\n const transactionDocs: SanityDocument[] = []\n const svgMaps: {old: string; new: string}[] = []\n\n // Upload assets and then add to transaction\n async function processDoc(doc: SanityDocument): Promise<void> {\n if (!isAssetDocument(doc)) {\n transactionDocs.push(doc)\n\n return\n }\n\n // Download and upload asset\n // Get the *original* image with this dlRaw param to create the same deterministic _id\n const typeIsFile = isSanityFileAsset(doc)\n const downloadUrl = typeIsFile ? doc.url : `${doc.url}?dlRaw=true`\n\n const res = await fetch(downloadUrl, assetDownloadInit(downloadUrl, token, typeIsFile))\n\n // Fail fast instead of uploading an error response (e.g. 401/403/404)\n // body as the asset's binary data.\n if (!res.ok) {\n throw new Error(\n `Failed to download asset \"${doc.originalFilename ?? doc._id}\" (${res.status} ${res.statusText})`,\n )\n }\n\n const assetData = await res.blob()\n\n const options = {filename: doc.originalFilename}\n const assetDoc = await destinationClient.assets.upload(\n typeIsFile ? `file` : `image`,\n assetData,\n options,\n )\n\n // SVG _id's need remapping before transaction\n if (doc.extension === 'svg') {\n svgMaps.push({old: doc._id, new: assetDoc._id})\n }\n\n // Merge the original asset document's editorial metadata (e.g. `altText`,\n // `title`) — which the upload response omits — with the canonical fields of\n // the freshly uploaded asset (`_id`, `url`, `path`, `assetId`, `sha1hash`,\n // ...). The uploaded values win, so `url`/`path` no longer reference the\n // origin dataset. For SVGs the uploaded `_id` differs from the source\n // (the file is sanitized on upload), so pushing a single merged document at\n // the new `_id` — and remapping references to it below — avoids leaving an\n // orphaned asset document behind at the original `_id`.\n transactionDocs.push({...doc, ...assetDoc})\n\n currentProgress += 1\n setMessage({\n text: `Duplicating ${currentProgress}/${assetsCount} Assets`,\n tone: 'default',\n })\n setProgress([currentProgress, assetsCount])\n }\n\n try {\n const payloadIncludedDocs = payload.filter((item) => item.include).map((item) => item.doc)\n\n // Promises are limited to three at once\n await mapWithConcurrency(payloadIncludedDocs, 3, processDoc)\n } catch (err) {\n console.error(err)\n setIsDuplicating(false)\n setProgress([0, 0])\n setMessage({\n tone: 'critical',\n text: err instanceof Error ? err.message : `Duplication Failed`,\n })\n\n return\n }\n\n // Remap SVG references to new _id's. SVG assets are sanitized on upload, so\n // their `_id` changes; references still pointing at the original `_id` must\n // be updated to the uploaded one.\n const svgIdRemap = new Map(svgMaps.map(({old, new: next}) => [old, next]))\n const transactionDocsMapped =\n svgIdRemap.size === 0\n ? transactionDocs\n : transactionDocs.map((doc) => {\n const references = extractWithPath(`.._ref`, doc)\n\n if (!references.length) {\n return doc\n }\n\n // Clone lazily before the first mutation: some of these docs are the\n // same objects held in React state (`payload`), and `dset` mutates in\n // place — which would corrupt state and trip up the React Compiler.\n let mappedDoc = doc\n\n references.forEach((ref) => {\n const newRefValue =\n typeof ref.value === 'string' ? svgIdRemap.get(ref.value) : undefined\n\n if (newRefValue) {\n if (mappedDoc === doc) {\n mappedDoc = structuredClone(doc)\n }\n\n dset(mappedDoc, ref.path.join('.'), newRefValue)\n }\n })\n\n return mappedDoc\n })\n\n // Create transaction\n const transaction = destinationClient.transaction()\n\n transactionDocsMapped.forEach((doc) => {\n transaction.createOrReplace(doc)\n })\n\n const onCommitSuccess = () => {\n updatePayloadStatuses(payload, destination).catch(console.error)\n }\n\n try {\n await transaction.commit()\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n\n onCommitSuccess()\n } catch (err) {\n if (isReferenceMutationError(err)) {\n await handleReferenceError({\n err,\n transactionDocs: transactionDocsMapped,\n originClient,\n destinationClient,\n pluginConfig,\n token,\n setMessage,\n onSuccess: onCommitSuccess,\n excludedIds: new Set(payload.filter((item) => !item.include).map((item) => item.doc._id)),\n svgMaps,\n })\n } else {\n const description = getErrorDescription(err)\n setMessage({\n tone: 'critical',\n text: description || `Duplication Failed`,\n })\n }\n }\n\n setIsDuplicating(false)\n setProgress([0, 0])\n if (onDuplicated) {\n try {\n await onDuplicated()\n } catch (error) {\n const text = error instanceof Error ? error.message : String(error)\n setMessage({tone: 'critical', text: `Error in onDuplicated hook: ${text}`})\n }\n }\n }","pluginConfig.apiVersion","({doc, include}) => include && isAssetId(doc._id)","destinationClient","(item) => item.include","(item) => item.doc","({old, new: next}) => [old, next]","(item) => !item.include","(item) => item.doc._id","error","space","payload.findIndex(({doc}) => doc['extension'] === 'svg')","({doc}) => doc['extension'] === 'svg'","payload.filter(\n (item) => item.include && !isAssetId(item.doc._id),\n )","(item) => item.include && !isAssetId(item.doc._id)","payload.filter(\n (item) => item.include && isAssetId(item.doc._id),\n )","(item) => item.include && isAssetId(item.doc._id)","(space) => space?.projectId","[selectedTotal, `/`, payloadCount, `Documents and Assets selected`]","projectId","<Feedback tone=\"critical\">\n <code>sanity.config.ts</code> must contain at least two Workspaces to use this plugin.\n </Feedback>","<Feedback tone=\"critical\">\n No allowed Migration destinations are available for this Dataset. Check the{' '}\n <code>migrationFilters</code> plugin config, or add another Workspace as a valid target.\n </Feedback>","{flex: 1}","<Label>Duplicate from</Label>","<Box padding={4} paddingTop={5} paddingBottom={0}>\n <Text size={3}>\n <ArrowRightIcon />\n </Text>\n </Box>","<Label>To Destination</Label>","<Select onChange={handleChange}>\n {workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))}\n </Select>","Select","workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))","<Stack style={{flex: 1}} gap={3}>\n <Label>To Destination</Label>\n <Select onChange={handleChange}>\n {workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))}\n </Select>\n </Stack>","Stack","3","isDuplicating && (\n <Card border radius={2}>\n <Card\n style={{\n width: '100%',\n // Guard against a 0-asset payload (progress[1] === 0),\n // which would make the ratio NaN and produce an invalid transform.\n transform: `scaleX(${progress[1] > 0 ? progress[0] / progress[1] : 0})`,\n transformOrigin: 'left',\n transition: 'transform .2s ease',\n boxSizing: 'border-box',\n }}\n padding={1}\n tone=\"positive\"\n />\n </Card>\n )","progress[1]","payload.length > 0 && (\n <>\n <Label>{headingText}</Label>\n <SelectButtons payload={payload} setPayload={setPayload} />\n </>\n )","payload.length","displayMessage && (\n <Card padding={3} radius={2} shadow={1} tone={displayMessage.tone}>\n <Text size={1}>{displayMessage.text}</Text>\n </Card>\n )","payload.length > 0 ? (\n <Stack>\n {payload.map(({doc, include, status, hasDraft}, index) => {\n const schemaType = schema.get(doc._type)\n\n return (\n <Fragment key={doc._id}>\n <Flex align=\"center\">\n <Checkbox checked={include} onChange={() => handleCheckbox(doc._id)} />\n <Box flex={1} paddingX={3}>\n {schemaType ? (\n <Preview value={doc} schemaType={schemaType} />\n ) : (\n <Card tone=\"caution\">Invalid schema type</Card>\n )}\n </Box>\n <Flex align=\"center\" gap={2}>\n {hasDraft ? <StatusBadge status=\"UNPUBLISHED\" isAsset={false} /> : null}\n <StatusBadge status={status} isAsset={isAssetId(doc._id)} />\n </Flex>\n </Flex>\n {doc['extension'] === 'svg' && index === firstSvgIndex && (\n <Card padding={3} radius={2} shadow={1} tone=\"caution\">\n <Text size={1}>\n Due to how SVGs are sanitized after first uploaded, duplicated SVG\n assets may have new <code>_id</code>'s at the destination. The newly\n generated <code>_id</code> will be the same in each duplication, but\n it will never be the same <code>_id</code> as the first time this\n Asset was uploaded. References to the asset will be updated to use the\n new <code>_id</code>.\n </Text>\n </Card>\n )}\n </Fragment>\n )\n })}\n </Stack>\n ) : (\n <Flex padding={4} align=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n )","{doc, include, status, hasDraft}","include","status","'extension'","hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )","() => void handleDuplicate()","<Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />","isDuplicating || !selectedTotal || isGathering","<Stack gap={2}>\n {hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )}\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n </Stack>","<Card borderTop padding={4}>\n <Stack gap={3}>\n {displayMessage && (\n <Card padding={3} radius={2} shadow={1} tone={displayMessage.tone}>\n <Text size={1}>{displayMessage.text}</Text>\n </Card>\n )}\n {payload.length > 0 ? (\n <Stack>\n {payload.map(({doc, include, status, hasDraft}, index) => {\n const schemaType = schema.get(doc._type)\n\n return (\n <Fragment key={doc._id}>\n <Flex align=\"center\">\n <Checkbox checked={include} onChange={() => handleCheckbox(doc._id)} />\n <Box flex={1} paddingX={3}>\n {schemaType ? (\n <Preview value={doc} schemaType={schemaType} />\n ) : (\n <Card tone=\"caution\">Invalid schema type</Card>\n )}\n </Box>\n <Flex align=\"center\" gap={2}>\n {hasDraft ? <StatusBadge status=\"UNPUBLISHED\" isAsset={false} /> : null}\n <StatusBadge status={status} isAsset={isAssetId(doc._id)} />\n </Flex>\n </Flex>\n {doc['extension'] === 'svg' && index === firstSvgIndex && (\n <Card padding={3} radius={2} shadow={1} tone=\"caution\">\n <Text size={1}>\n Due to how SVGs are sanitized after first uploaded, duplicated SVG\n assets may have new <code>_id</code>'s at the destination. The newly\n generated <code>_id</code> will be the same in each duplication, but\n it will never be the same <code>_id</code> as the first time this\n Asset was uploaded. References to the asset will be updated to use the\n new <code>_id</code>.\n </Text>\n </Card>\n )}\n </Fragment>\n )\n })}\n </Stack>\n ) : (\n <Flex padding={4} align=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n )}\n <Stack gap={2}>\n {hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )}\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n </Stack>\n </Stack>\n </Card>","stickyStyles(isDarkMode)","{doc}","{old, new: next}","{doc, include}","{_id}","_id","{apiVersion}","schema.getTypeNames()","{\n docs: [],\n }","function handleSubmit(e?: SubmitEvent<HTMLFormElement>) {\n if (e) e.preventDefault()\n void runQuery()\n }","(doc) => !doc._id.startsWith(`drafts.`)","err","[0, 0, 0, 5]","[1, 1, 1, 2]","[1, 1, 1, 4]","[2, 2, 2, 0]","<Box>\n <Label>Initial Documents Query</Label>\n </Box>","<Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>","{fontFamily: 'monospace'}","(event) => setValue(event.currentTarget.value)","<Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>","value ?? ``","() => handleSubmit()","<Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />","!value","<Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>","<Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>","preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )","<Box padding={[2, 2, 2, 0]}>\n <Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>\n {preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )}\n </Box>","fetched && initialData.docs.length < 1 && (\n <Container width={1}>\n <Card padding={5}>\n {value ? `No documents match this query` : `Start with a valid GROQ query`}\n </Card>\n </Container>\n )","docs","initialData.docs?.length > 0 && (\n <Duplicator docs={initialData.docs} token={token} pluginConfig={pluginConfig} />\n )","<Card padding={[0, 0, 0, 5]}>\n <Container>\n <Grid gridTemplateColumns={[1, 1, 1, 2]} gap={[1, 1, 1, 4]}>\n <Box padding={[2, 2, 2, 0]}>\n <Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>\n {preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )}\n </Box>\n {fetched && initialData.docs.length < 1 && (\n <Container width={1}>\n <Card padding={5}>\n {value ? `No documents match this query` : `Start with a valid GROQ query`}\n </Card>\n </Container>\n )}\n {initialData.docs?.length > 0 && (\n <Duplicator docs={initialData.docs} token={token} pluginConfig={pluginConfig} />\n )}\n </Grid>\n </Container>\n </Card>","doc","[]","{apiVersion}","() => {\n async function fetchInbound() {\n const firstDocId = docs[0]?._id\n\n if (!follow.includes(`inbound`) || !firstDocId) {\n return\n }\n\n const inboundReferences = await client.fetch<SanityDocument[]>(`*[references($id)]`, {\n id: firstDocId,\n })\n setInbound([...docs, ...inboundReferences])\n }\n\n fetchInbound().catch(console.error)\n }","[client, docs, follow]","docs[0]?._id","follow.length > 1 && (follow.includes(`inbound`) || follow.includes(`outbound`)) ? (\n <Card paddingX={4} paddingBottom={4} marginBottom={4} borderBottom>\n <Grid gridTemplateColumns={2} gap={4}>\n {follow.includes(`outbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'outbound'}\n onClick={() => setMode('outbound')}\n text=\"Outbound\"\n />\n ) : null}\n {follow.includes(`inbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'inbound'}\n onClick={() => setMode('inbound')}\n disabled={inbound.length === 0}\n text={inbound.length > 0 ? `Inbound (${inbound.length})` : 'No inbound references'}\n />\n ) : null}\n </Grid>\n </Card>\n ) : null","inbound.length","follow.length","<Duplicator\n docs={mode === 'outbound' ? docs : inbound}\n token={token}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />","mode === 'outbound' ? docs : inbound","<Container>\n {follow.length > 1 && (follow.includes(`inbound`) || follow.includes(`outbound`)) ? (\n <Card paddingX={4} paddingBottom={4} marginBottom={4} borderBottom>\n <Grid gridTemplateColumns={2} gap={4}>\n {follow.includes(`outbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'outbound'}\n onClick={() => setMode('outbound')}\n text=\"Outbound\"\n />\n ) : null}\n {follow.includes(`inbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'inbound'}\n onClick={() => setMode('inbound')}\n disabled={inbound.length === 0}\n text={inbound.length > 0 ? `Inbound (${inbound.length})` : 'No inbound references'}\n />\n ) : null}\n </Grid>\n </Card>\n ) : null}\n <Duplicator\n docs={mode === 'outbound' ? docs : inbound}\n token={token}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />\n </Container>","{apiVersion}: ResetSecretProps","{apiVersion}","() => {\n client.delete({query: `*[_id == \"secrets.${SECRET_NAMESPACE}\"]`}).catch(console.error)\n }","useCallback(() => {\n client.delete({query: `*[_id == \"secrets.${SECRET_NAMESPACE}\"]`}).catch(console.error)\n }, [client])","[2, 2, 2, 5]","<Flex align=\"center\" justify=\"flex-end\" paddingX={[2, 2, 2, 5]} paddingY={5}>\n <Button\n text=\"Reset Secret\"\n onClick={handleClick}\n mode=\"ghost\"\n tone=\"critical\"\n fontSize={1}\n padding={2}\n />\n </Flex>","<Flex justify=\"center\" align=\"center\">\n <Box padding={5}>\n <Spinner />\n </Box>\n </Flex>","<SettingsView\n title=\"Token Required\"\n namespace={SECRET_NAMESPACE}\n keys={secretConfigKeys}\n onClose={() => null}\n />","() => null","<DuplicatorQuery token={secrets.bearerToken} pluginConfig={pluginConfig} />","bearerToken","<ResetSecret apiVersion={pluginConfig.apiVersion} />","apiVersion","<>\n <DuplicatorQuery token={secrets.bearerToken} pluginConfig={pluginConfig} />\n <ResetSecret apiVersion={pluginConfig.apiVersion} />\n </>","<Feedback>No docs passed into Duplicator Tool</Feedback>","<Feedback>No plugin config</Feedback>","<DuplicatorWrapper\n docs={docs}\n token={secrets.bearerToken}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />","<CrossDatasetDuplicator mode=\"action\" docs={docs} onDuplicated={onDuplicated} />","props.tool.options ?? {}","options","docs = []","<CrossDatasetDuplicator mode=\"tool\" docs={docs} />"],"sources":["../src/helpers/constants.ts","../src/context/ConfigProvider.tsx","../src/helpers/index.ts","../src/helpers/getDocumentsInArray.ts","../src/helpers/migrationFilters.ts","../src/components/Feedback.tsx","../src/components/SelectButtons.tsx","../src/components/StatusBadge.tsx","../src/components/Duplicator.tsx","../src/components/DuplicatorQuery.tsx","../src/components/DuplicatorWrapper.tsx","../src/components/ResetSecret.tsx","../src/components/CrossDatasetDuplicator.tsx","../src/components/CrossDatasetDuplicatorAction.tsx","../src/actions/DuplicateToAction.tsx","../src/components/CrossDatasetDuplicatorTool.tsx","../src/tool/index.ts","../src/plugin.tsx"],"sourcesContent":["import type {PluginConfig} from '../types'\n\nexport const SECRET_NAMESPACE = `CrossDatasetDuplicator`\n\nexport const DEFAULT_CONFIG: Required<PluginConfig> = {\n apiVersion: '2025-02-19',\n tool: true,\n types: [],\n filter: '',\n follow: ['outbound'],\n queries: [],\n migrationFilters: [],\n}\n","import {createContext, useContext} from 'react'\nimport type {LayoutProps} from 'sanity'\n\nimport {DEFAULT_CONFIG} from '../helpers/constants'\nimport type {PluginConfig} from '../types'\n\nconst CrossDatasetDuplicatorContext = createContext(DEFAULT_CONFIG)\n\ntype ConfigProviderProps = LayoutProps & {pluginConfig: Required<PluginConfig>}\n\n/**\n * Plugin config context hook from the Cross Dataset Duplicator plugin\n * @public\n */\nexport function useCrossDatasetDuplicatorConfig() {\n const pluginConfig = useContext(CrossDatasetDuplicatorContext)\n\n return pluginConfig\n}\n\nexport function ConfigProvider(props: ConfigProviderProps) {\n const {pluginConfig, ...rest} = props\n\n return (\n <CrossDatasetDuplicatorContext.Provider value={pluginConfig}>\n {props.renderDefault(rest)}\n </CrossDatasetDuplicatorContext.Provider>\n )\n}\n","import type {CSSProperties} from 'react'\n\nexport function createInitialMessage(docCount = 0, refsCount = 0): string {\n const message = [\n docCount === 1 ? `This Document contains` : `These ${docCount} Documents contain`,\n refsCount === 1 ? `1 Reference.` : `${refsCount} References.`,\n refsCount === 1 ? `That Document` : `Those Documents`,\n `may have References too. If referenced Documents do not exist at the target Destination, this transaction will fail.`,\n ]\n\n return message.join(` `)\n}\n\nexport const stickyStyles = (isDarkMode = true): CSSProperties => ({\n position: 'sticky',\n top: 0,\n zIndex: 100,\n backgroundColor: isDarkMode ? `rgba(10,10,10,0.95)` : `rgba(255,255,255,0.95)`,\n})\n","import {extractWithPath} from '@sanity/mutator'\nimport type {SanityClient, SanityDocument} from 'sanity'\n\nimport type {PluginConfig} from '../types'\n\ntype OptionsBag = {\n fetchIds: string[]\n client: SanityClient\n pluginConfig: PluginConfig\n currentIds?: Set<string> | null\n projection?: string\n}\n\n// Recursively fetch Documents from an array of _id's and their references\n// Heavy use of Set is to avoid recursively querying for id's already in the payload\nexport async function getDocumentsInArray(options: OptionsBag): Promise<SanityDocument[]> {\n const {fetchIds, client, pluginConfig, currentIds, projection} = options\n const collection: SanityDocument[] = []\n\n // Find initial docs\n const filter = ['_id in $fetchIds', pluginConfig.filter].filter(Boolean).join(' && ')\n const query = `*[${filter}]${projection ?? ``}`\n const data = await client.fetch<SanityDocument[]>(query, {\n fetchIds: fetchIds ?? [],\n })\n\n if (!data?.length) {\n return []\n }\n\n const localCurrentIds = currentIds ?? new Set<string>()\n\n // Find new ids in the returned data\n // Unless we started with an empty set, get the _ids from the data\n const newDataIds = new Set<string>(\n data\n .map((dataDoc) => dataDoc._id)\n .filter((id) => (currentIds?.size ? !localCurrentIds.has(id) : Boolean(id))),\n )\n\n if (newDataIds.size) {\n collection.push(...data)\n for (const id of newDataIds) {\n localCurrentIds.add(id)\n }\n\n // Check new data for more references\n await Promise.all(\n data.map(async (doc) => {\n const expr = `.._ref`\n const references = extractWithPath(expr, doc).flatMap((ref) =>\n typeof ref.value === 'string' ? [ref.value] : [],\n )\n\n if (references.length) {\n // Find references not already in the Collection\n const newReferenceIds = new Set<string>(\n references.filter((ref) => !localCurrentIds.has(ref)),\n )\n\n if (newReferenceIds.size) {\n // Recursive query for new documents\n const referenceDocs = await getDocumentsInArray({\n fetchIds: Array.from(newReferenceIds),\n currentIds: localCurrentIds,\n client,\n pluginConfig,\n })\n\n if (referenceDocs?.length) {\n collection.push(...referenceDocs)\n }\n }\n }\n }),\n )\n }\n\n // Create a unique array of documents, keeping the first occurrence of each _id\n const seenIds = new Set<string>()\n const uniqueCollection: SanityDocument[] = []\n\n for (const doc of collection) {\n if (doc && !seenIds.has(doc._id)) {\n seenIds.add(doc._id)\n uniqueCollection.push(doc)\n }\n }\n\n return uniqueCollection\n}\n","import type {MigrationFilter} from '../types'\n\ntype IsAllowedMigrationTargetOptions = {\n migrationFilters: MigrationFilter[] | undefined\n sourceProjectId: string | undefined\n sourceDataset: string | undefined\n targetProjectId: string\n targetDataset: string\n}\n\n/**\n * Determine whether a Workspace is an allowed Migration destination for the\n * current source Dataset, based on the optional `migrationFilters` config.\n *\n * If no filter is configured for the source Dataset, every target is allowed\n * (the default behaviour). When a filter is configured, only the listed targets\n * are allowed.\n */\nexport function isAllowedMigrationTarget(options: IsAllowedMigrationTargetOptions): boolean {\n const {migrationFilters, sourceProjectId, sourceDataset, targetProjectId, targetDataset} = options\n\n const migrationFilter = migrationFilters?.find((filter) => filter.sourceDataset === sourceDataset)\n\n // If no migrationFilter is configured for this dataset, allow all migration targets.\n if (!migrationFilter) {\n return true\n }\n\n return migrationFilter.targets.some((target) => {\n if (target.dataset !== targetDataset) {\n return false\n }\n\n // If a project ID is configured for the target, check that it matches.\n if (target.projectId) {\n return target.projectId === targetProjectId\n }\n\n // If a project ID is not configured for the target, only allow targets in\n // the same project as the source.\n return targetProjectId === sourceProjectId\n })\n}\n","import {Card, Text} from '@sanity/ui'\nimport type {BadgeTone} from '@sanity/ui'\nimport type {ReactNode} from 'react'\n\ntype FeedbackProps = {\n children?: ReactNode\n tone?: BadgeTone\n}\n\nexport default function Feedback(props: FeedbackProps) {\n const {children, tone = 'caution'} = props\n\n return (\n <Card padding={3} radius={2} shadow={1} tone={tone}>\n <Text size={1}>{children}</Text>\n </Card>\n )\n}\n","import {isAssetId} from '@sanity/asset-utils'\nimport {Button, Card, Flex} from '@sanity/ui'\nimport {type Dispatch, type SetStateAction, useState} from 'react'\n\nimport type {PayloadItem} from './Duplicator'\n\ntype Action = 'ALL' | 'NONE' | 'NEW' | 'EXISTING' | 'OLDER' | 'ASSETS' | 'DOCUMENTS'\n\ntype ButtonItem = {label: string; action: Action} | {divider: string}\n\nconst buttons: ButtonItem[] = [\n {label: 'All', action: 'ALL'},\n {label: 'None', action: 'NONE'},\n {divider: 'divider-1'},\n {label: 'New', action: 'NEW'},\n {label: 'Existing', action: 'EXISTING'},\n {label: 'Older', action: 'OLDER'},\n {divider: 'divider-2'},\n {label: 'Documents', action: 'DOCUMENTS'},\n {label: 'Assets', action: 'ASSETS'},\n]\n\nfunction shouldInclude(item: PayloadItem, action: Action): boolean {\n switch (action) {\n case 'ALL':\n return true\n case 'NONE':\n return false\n case 'NEW':\n return item.status === 'CREATE'\n case 'EXISTING':\n return item.status === 'EXISTS'\n case 'OLDER':\n return item.status === 'OVERWRITE'\n case 'ASSETS':\n return isAssetId(item.doc._id)\n case 'DOCUMENTS':\n return !isAssetId(item.doc._id)\n default:\n return item.include\n }\n}\n\ntype SelectButtonsProps = {\n payload: PayloadItem[]\n setPayload: Dispatch<SetStateAction<PayloadItem[]>>\n}\n\nexport default function SelectButtons(props: SelectButtonsProps) {\n const {payload, setPayload} = props\n const [disabledActions, setDisabledActions] = useState<Action[]>(() =>\n payload.length && payload.every((item) => item.include) ? ['ALL'] : [],\n )\n\n function handleSelectButton(action: Action) {\n if (!payload.length) return\n\n setPayload((current) =>\n current.map((item) => ({...item, include: shouldInclude(item, action)})),\n )\n setDisabledActions([action])\n }\n\n return (\n <Card padding={1} radius={3} shadow={1}>\n <Flex gap={2} wrap=\"wrap\">\n {buttons.map((button) =>\n 'action' in button ? (\n <Button\n key={button.action}\n fontSize={1}\n mode=\"bleed\"\n padding={2}\n text={button.label}\n disabled={disabledActions.includes(button.action)}\n onClick={() => handleSelectButton(button.action)}\n />\n ) : (\n <Card key={button.divider} borderLeft />\n ),\n )}\n </Flex>\n </Card>\n )\n}\n","import {InfoOutlineIcon} from '@sanity/icons/InfoOutline'\nimport {Box, Text, Badge} from '@sanity/ui'\nimport type {BadgeTone} from '@sanity/ui'\nimport {Tooltip} from '@sanity/ui/tooltip'\n\ntype StatusTones = {\n EXISTS: BadgeTone\n OVERWRITE: BadgeTone\n UPDATE: BadgeTone\n CREATE: BadgeTone\n UNPUBLISHED: BadgeTone\n}\n\nconst documentTones: StatusTones = {\n EXISTS: `primary`,\n OVERWRITE: `critical`,\n UPDATE: `caution`,\n CREATE: `positive`,\n UNPUBLISHED: `caution`,\n}\n\nconst assetTones: StatusTones = {\n EXISTS: `critical`,\n OVERWRITE: `critical`,\n UPDATE: `critical`,\n CREATE: `positive`,\n UNPUBLISHED: `default`,\n}\n\nexport type MessageTypes = {\n EXISTS: string\n OVERWRITE: string\n UPDATE: string\n CREATE: string\n UNPUBLISHED: string\n}\n\nconst documentMessages: MessageTypes = {\n // Only happens once document is copied the first time, and _updatedAt is the same\n EXISTS: `This document already exists at the Destination with the same ID and Updated time.`,\n // Is true immediately after transaction as _updatedAt is updated by API after mutation\n // Is also true if the document at the destination has been manually modified\n // Presently, the plugin doesn't actually compare the two documents\n OVERWRITE: `A newer version of this document exists at the Destination, and it will be overwritten with this version.`,\n // Document at destination is older\n UPDATE: `An older version of this document exists at the Destination, and it will be overwritten with this version.`,\n // Document at destination doesn't exist\n CREATE: `This document will be created at the destination.`,\n UNPUBLISHED: `A Draft version of this Document exists in this Dataset, but only the Published version will be duplicated to the destination.`,\n}\n\nconst assetMessages: MessageTypes = {\n EXISTS: `This Asset already exists at the Destination`,\n OVERWRITE: `This Asset already exists at the Destination`,\n UPDATE: `This Asset already exists at the Destination`,\n CREATE: `This Asset does not yet exist at the Destination`,\n UNPUBLISHED: ``,\n}\n\nconst assetStatus: MessageTypes = {\n EXISTS: `RE-UPLOAD`,\n OVERWRITE: `RE-UPLOAD`,\n UPDATE: `RE-UPLOAD`,\n CREATE: `UPLOAD`,\n UNPUBLISHED: ``,\n}\n\ntype StatusBadgeProps = {\n isAsset: boolean\n status?: keyof MessageTypes\n}\n\nexport default function StatusBadge(props: StatusBadgeProps) {\n const {status, isAsset} = props\n\n if (!status) {\n return null\n }\n\n const badgeTone = isAsset ? assetTones[status] : documentTones[status]\n\n if (!badgeTone) {\n return (\n <Badge padding={2} fontSize={1}>\n Checking...\n </Badge>\n )\n }\n\n const badgeText = isAsset ? assetMessages[status] : documentMessages[status]\n const badgeStatus = isAsset ? assetStatus[status] : status\n\n return (\n <Tooltip\n content={\n <Box padding={3} style={{maxWidth: 200}}>\n <Text size={1}>{badgeText}</Text>\n </Box>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <Badge padding={3} fontSize={1} tone={badgeTone}>\n {badgeStatus}\n <Box marginLeft={2} display={'inline-block'} as=\"span\">\n <InfoOutlineIcon />\n </Box>\n </Badge>\n </Tooltip>\n )\n}\n","import {isAssetId, isSanityFileAsset} from '@sanity/asset-utils'\nimport type {SanityAssetDocument, SanityClient} from '@sanity/client'\nimport {ArrowRightIcon} from '@sanity/icons/ArrowRight'\nimport {LaunchIcon} from '@sanity/icons/Launch'\nimport {SearchIcon} from '@sanity/icons/Search'\nimport {extractWithPath} from '@sanity/mutator'\nimport {\n Card,\n Container,\n Text,\n Box,\n Button,\n Label,\n Stack,\n Select,\n Flex,\n Checkbox,\n type CardTone,\n useTheme,\n Spinner,\n} from '@sanity/ui'\nimport {getTheme_v2} from '@sanity/ui/theme'\nimport {dset} from 'dset'\nimport {type ChangeEvent, Fragment, useEffect, useEffectEvent, useMemo, useState} from 'react'\nimport {\n useClient,\n Preview,\n useSchema,\n useWorkspaces,\n type WorkspaceSummary,\n type SanityDocument,\n} from 'sanity'\n\nimport {stickyStyles, createInitialMessage} from '../helpers'\nimport {getDocumentsInArray} from '../helpers/getDocumentsInArray'\nimport {isAllowedMigrationTarget} from '../helpers/migrationFilters'\nimport type {PluginConfig} from '../types'\nimport Feedback from './Feedback'\nimport SelectButtons from './SelectButtons'\nimport StatusBadge, {type MessageTypes} from './StatusBadge'\n\nexport type DuplicatorProps = {\n docs: SanityDocument[]\n token: string\n pluginConfig: Required<PluginConfig>\n onDuplicated?: () => Promise<void>\n}\n\nexport type PayloadItem = {\n doc: SanityDocument\n include: boolean\n status?: keyof MessageTypes\n hasDraft?: boolean\n}\n\ntype WorkspaceOption = WorkspaceSummary & {\n disabled: boolean\n}\n\ntype Message = {\n text: string\n tone: CardTone\n}\n\nfunction isAssetDocument(doc: SanityDocument): doc is SanityDocument & SanityAssetDocument {\n return isAssetId(doc._id)\n}\n\n// Run an async function over every item with a maximum concurrency\nasync function mapWithConcurrency<T>(\n items: T[],\n limit: number,\n fn: (item: T) => Promise<void>,\n): Promise<void> {\n const queue = [...items]\n\n async function work(): Promise<void> {\n const item = queue.shift()\n\n if (item === undefined) {\n return undefined\n }\n\n await fn(item)\n\n return work()\n }\n\n const workers = Array.from({length: Math.min(limit, queue.length)}, () => work())\n\n await Promise.all(workers)\n}\n\ntype SetMessage = (msg: Message) => void\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction isUnknownArray(value: unknown): value is unknown[] {\n return Array.isArray(value)\n}\n\n// Pull a human-readable description out of a Sanity mutation error.\n// Prefer the richest text available: item-level descriptions (which carry the\n// \"references non-existent document\" phrasing) over a possibly-generic top-level\n// `details.description` like \"Mutation(s) failed with N error(s)\".\nfunction getErrorDescription(err: unknown): string {\n if (!isRecord(err)) {\n return ''\n }\n\n const details = err['details']\n const itemDescriptions: string[] = []\n\n if (isRecord(details) && isUnknownArray(details['items'])) {\n for (const item of details['items']) {\n if (isRecord(item) && isRecord(item['error'])) {\n const itemDescription = item['error']['description']\n\n if (typeof itemDescription === 'string' && itemDescription) {\n itemDescriptions.push(itemDescription)\n }\n }\n }\n }\n\n if (itemDescriptions.length) {\n return itemDescriptions.join('\\n')\n }\n\n const message = err['message']\n\n if (typeof message === 'string' && message) {\n return message\n }\n\n if (isRecord(details)) {\n const description = details['description']\n\n if (typeof description === 'string') {\n return description\n }\n }\n\n return ''\n}\n\nfunction isReferenceMutationError(err: unknown): boolean {\n if (!isRecord(err)) {\n return false\n }\n\n const details = err['details']\n\n // Most reliable: structured mutation item type from the Content Lake API\n if (isRecord(details) && isUnknownArray(details['items'])) {\n for (const item of details['items']) {\n if (isRecord(item) && isRecord(item['error'])) {\n if (item['error']['type'] === 'documentReferenceDoesNotExistError') {\n return true\n }\n\n const itemDescription = item['error']['description']\n\n if (\n typeof itemDescription === 'string' &&\n (itemDescription.toLowerCase().includes('references non-existent document') ||\n itemDescription.toLowerCase().includes('reference non-existent'))\n ) {\n return true\n }\n }\n }\n }\n\n const description = getErrorDescription(err).toLowerCase()\n\n return (\n description.includes('references non-existent document') ||\n description.includes('reference non-existent')\n )\n}\n\n// Collect the _id's of referenced documents that are missing at the destination,\n// reading both the structured error payload and the human-readable description\nfunction getMissingReferenceIds(err: unknown, description: string): string[] {\n const missingIds: string[] = []\n\n const details = isRecord(err) ? err['details'] : undefined\n const rawItems = isRecord(details) ? details['items'] : undefined\n const items = isUnknownArray(rawItems) ? rawItems : []\n\n for (const item of items) {\n if (isRecord(item)) {\n const error = item['error']\n\n if (isRecord(error)) {\n // Sanity returns `referenceID`; keep the other spellings as fallbacks\n const refId = error['referenceID'] ?? error['referencedId'] ?? error['referenceId']\n\n if (typeof refId === 'string' && !missingIds.includes(refId)) {\n missingIds.push(refId)\n }\n }\n }\n }\n\n const refRegex = /references non-existent document [`'\"]?([^`'\"\\s)]+)[`'\"]?/gi\n let match = refRegex.exec(description)\n\n while (match !== null) {\n const id = match[1]\n\n if (id && !missingIds.includes(id)) {\n missingIds.push(id)\n }\n\n match = refRegex.exec(description)\n }\n\n return missingIds\n}\n\n// Commit documents individually so a single failing document doesn't block the rest.\n// Runs sequentially (concurrency 1) so referenced documents can land before the\n// documents that point at them.\nasync function commitOneByOne(\n docs: SanityDocument[],\n client: SanityClient,\n setMessage: SetMessage,\n onSuccess: () => void,\n): Promise<void> {\n let successCount = 0\n let failCount = 0\n\n await mapWithConcurrency(docs, 1, async (doc) => {\n try {\n const tx = client.transaction()\n tx.createOrReplace(doc)\n await tx.commit()\n successCount += 1\n } catch (commitErr) {\n failCount += 1\n console.error(`Failed to duplicate document \"${doc._id}\"`, commitErr)\n }\n })\n\n if (failCount === 0) {\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n onSuccess()\n\n return\n }\n\n setMessage({\n tone: 'critical',\n text: `Duplication finished with ${failCount} error(s). ${successCount} document(s) duplicated successfully.`,\n })\n\n if (successCount > 0) {\n onSuccess()\n }\n}\n\ntype ReferenceErrorOptions = {\n err: unknown\n transactionDocs: SanityDocument[]\n originClient: SanityClient\n destinationClient: SanityClient\n pluginConfig: Required<PluginConfig>\n token: string\n setMessage: SetMessage\n onSuccess: () => void\n /** Caps recursive recovery so a pathological reference loop can't hang forever */\n depth?: number\n /** Document ids the user explicitly deselected — never auto-commit these during recovery */\n excludedIds?: Set<string>\n /**\n * SVG _id remaps already applied by the caller. Recovered documents are fetched\n * fresh from the origin, so they still point at origin SVG _id's that only exist\n * at the destination under their uploaded _id.\n */\n svgMaps?: {old: string; new: string}[]\n}\n\n// Only attach the studio token when downloading from a Sanity host so a crafted\n// asset `url` cannot exfiltrate credentials to an attacker-controlled endpoint.\nfunction assetDownloadInit(url: string, token: string, typeIsFile: boolean): RequestInit {\n if (typeIsFile) {\n return {}\n }\n\n try {\n const {hostname} = new URL(url)\n\n if (hostname === 'cdn.sanity.io' || hostname.endsWith('.sanity.io')) {\n return {headers: {Authorization: `Bearer ${token}`}}\n }\n } catch {\n // Invalid URL — fetch without credentials\n }\n\n return {}\n}\n\n// Upload a recovered asset to the destination, rewriting url/path for the new dataset\nasync function uploadAssetForRecovery(\n doc: SanityDocument & SanityAssetDocument,\n destinationClient: SanityClient,\n token: string,\n): Promise<{docs: SanityDocument[]; svgMap?: {old: string; new: string}}> {\n const typeIsFile = isSanityFileAsset(doc)\n const downloadUrl = typeIsFile ? doc.url : `${doc.url}?dlRaw=true`\n\n const res = await fetch(downloadUrl, assetDownloadInit(downloadUrl, token, typeIsFile))\n\n if (!res.ok) {\n throw new Error(\n `Failed to download asset \"${doc._id}\" from origin (${res.status} ${res.statusText})`,\n )\n }\n\n const assetData = await res.blob()\n const assetDoc = await destinationClient.assets.upload(typeIsFile ? `file` : `image`, assetData, {\n filename: doc.originalFilename,\n })\n\n // Merge the original asset document's editorial metadata (e.g. `altText`) with\n // the uploaded asset's canonical fields, matching the main duplication path.\n // Keeping this to a single document at the uploaded `_id` avoids leaving an\n // orphaned asset behind when an SVG's `_id` changes on upload; references are\n // repointed via `svgMap`.\n return {\n docs: [{...doc, ...assetDoc}],\n svgMap: doc.extension === 'svg' ? {old: doc._id, new: assetDoc._id} : undefined,\n }\n}\n\n// Rewrite _ref values that point at remapped SVG asset ids.\n// Clones each doc so caller-held / payload objects are not mutated.\nfunction remapSvgRefs(\n docs: SanityDocument[],\n svgMaps: {old: string; new: string}[],\n): SanityDocument[] {\n if (!svgMaps.length) {\n return docs\n }\n\n return docs.map((original) => {\n const references = extractWithPath(`.._ref`, original)\n\n if (!references.length) {\n return original\n }\n\n const doc = structuredClone(original)\n\n references.forEach((ref) => {\n const newRefValue = svgMaps.find((asset) => asset.old === ref.value)?.new\n\n if (newRefValue) {\n dset(doc, ref.path.join('.'), newRefValue)\n }\n })\n\n return doc\n })\n}\n\n// Order docs so referenced documents come before the documents that point at\n// them. Used by the sequential one-by-one fallback where commit order matters.\nfunction orderDocsDependenciesFirst(docs: SanityDocument[]): SanityDocument[] {\n const byId = new Map(docs.map((doc) => [doc._id, doc]))\n const visiting = new Set<string>()\n const visited = new Set<string>()\n const ordered: SanityDocument[] = []\n\n function visit(id: string): void {\n if (visited.has(id) || visiting.has(id)) {\n return\n }\n\n const doc = byId.get(id)\n\n if (!doc) {\n return\n }\n\n visiting.add(id)\n\n for (const ref of extractWithPath(`.._ref`, doc)) {\n if (typeof ref.value === 'string') {\n visit(ref.value)\n }\n }\n\n visiting.delete(id)\n visited.add(id)\n ordered.push(doc)\n }\n\n for (const doc of docs) {\n visit(doc._id)\n }\n\n return ordered\n}\n\n// When a transaction fails because of missing references, fetch the referenced\n// documents (and their transitive refs) from the origin — respecting\n// pluginConfig.filter — upload any assets, then retry. Falls back to one-by-one\n// commits if the retry still fails.\nasync function handleReferenceError(options: ReferenceErrorOptions): Promise<void> {\n const {\n err,\n transactionDocs,\n originClient,\n destinationClient,\n pluginConfig,\n token,\n setMessage,\n onSuccess,\n depth = 0,\n excludedIds = new Set(),\n svgMaps: inheritedSvgMaps = [],\n } = options\n const description = getErrorDescription(err)\n const missingIds = getMissingReferenceIds(err, description)\n\n // If the only missing refs are ones the user deselected, surface that instead of\n // silently re-committing them\n const autoFetchIds = missingIds.filter((id) => !excludedIds.has(id))\n const blockedIds = missingIds.filter((id) => excludedIds.has(id))\n\n if (blockedIds.length && !autoFetchIds.length) {\n setMessage({\n tone: 'critical',\n text: `Duplication failed because deselected document(s) are still referenced: ${blockedIds.join(', ')}. Re-select them or remove the references.`,\n })\n\n return\n }\n\n if (!missingIds.length || depth >= 5) {\n // Couldn't parse the missing _id's (or we hit the recursion cap) — retry each document on its own\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(\n orderDocsDependenciesFirst(transactionDocs),\n destinationClient,\n setMessage,\n onSuccess,\n )\n\n return\n }\n\n setMessage({\n tone: 'default',\n text: `Fetching ${autoFetchIds.length} missing referenced document(s) and retrying...`,\n })\n\n let missingDocs: SanityDocument[] = []\n\n try {\n // Recursively gather referenced docs (and apply pluginConfig.filter), same\n // as the \"Gather References\" path — so nested refs aren't left behind\n missingDocs = await getDocumentsInArray({\n fetchIds: autoFetchIds,\n client: originClient,\n pluginConfig,\n })\n } catch (fetchErr) {\n setMessage({\n tone: 'critical',\n text:\n (fetchErr instanceof Error ? fetchErr.message : '') || description || 'Duplication Failed',\n })\n\n return\n }\n\n if (!missingDocs.length) {\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(\n orderDocsDependenciesFirst(transactionDocs),\n destinationClient,\n setMessage,\n onSuccess,\n )\n\n return\n }\n\n // Don't re-commit documents already in the failed transaction, or ones the\n // user explicitly deselected (including transitive refs of those)\n const existingIds = new Set(transactionDocs.map((doc) => doc._id))\n // Reverse so transitive refs (appended last by getDocumentsInArray) are processed first\n const newMissingDocs = [...missingDocs]\n .reverse()\n .filter((doc) => !existingIds.has(doc._id) && !excludedIds.has(doc._id))\n\n // Nothing new to add — retrying the same transaction would just loop until the depth cap\n if (!newMissingDocs.length) {\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(\n orderDocsDependenciesFirst(transactionDocs),\n destinationClient,\n setMessage,\n onSuccess,\n )\n\n return\n }\n\n setMessage({tone: 'default', text: `Duplicating ${newMissingDocs.length} missing document(s)...`})\n\n // Seed with the caller's remaps so recovered documents referencing an SVG that\n // was uploaded earlier are repointed at its destination _id, even when that\n // asset isn't re-fetched here (e.g. `pluginConfig.filter` excludes assets)\n const svgMaps: {old: string; new: string}[] = [...inheritedSvgMaps]\n\n // Process with the same concurrency limit as the main duplication path, while\n // writing into index slots so dependency-first order is preserved\n const recoveredChunks: SanityDocument[][] = Array.from({length: newMissingDocs.length}, () => [])\n\n try {\n await mapWithConcurrency(\n newMissingDocs.map((doc, index) => ({doc, index})),\n 3,\n async ({doc, index}) => {\n if (!isAssetDocument(doc)) {\n recoveredChunks[index] = [doc]\n\n return\n }\n\n const {docs, svgMap} = await uploadAssetForRecovery(doc, destinationClient, token)\n recoveredChunks[index] = docs\n\n if (svgMap) {\n svgMaps.push(svgMap)\n }\n },\n )\n } catch (uploadErr) {\n setMessage({\n tone: 'critical',\n text:\n (uploadErr instanceof Error ? uploadErr.message : '') ||\n description ||\n 'Duplication Failed',\n })\n\n return\n }\n\n const recoveredDocs = recoveredChunks.flat()\n\n // Remap SVG _ref's in both recovered and original transaction docs\n const remappedRecoveredDocs = remapSvgRefs(recoveredDocs, svgMaps)\n const remappedTransactionDocs = remapSvgRefs(transactionDocs, svgMaps)\n\n // Put recovered (referenced) docs first so sequential commits land\n // dependencies before the documents that point at them\n const allDocs = orderDocsDependenciesFirst([...remappedRecoveredDocs, ...remappedTransactionDocs])\n\n const retryTransaction = destinationClient.transaction()\n allDocs.forEach((doc) => retryTransaction.createOrReplace(doc))\n\n try {\n await retryTransaction.commit()\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n onSuccess()\n } catch (retryErr) {\n if (isReferenceMutationError(retryErr)) {\n // Another layer of missing refs — recurse with the expanded set\n await handleReferenceError({\n ...options,\n err: retryErr,\n transactionDocs: allDocs,\n depth: depth + 1,\n svgMaps,\n })\n\n return\n }\n\n setMessage({tone: 'default', text: 'Retrying documents one by one...'})\n await commitOneByOne(allDocs, destinationClient, setMessage, onSuccess)\n }\n}\n\nexport default function Duplicator(props: DuplicatorProps) {\n const {docs, token, pluginConfig, onDuplicated} = props\n const theme = useTheme()\n const isDarkMode = getTheme_v2({sanity: theme.sanity}).color._dark\n\n // Prepare origin (this Studio) client\n const originClient = useClient({apiVersion: pluginConfig.apiVersion})\n\n const schema = useSchema()\n\n // Create list of dataset options\n // and set initial value of dropdown\n const workspaces = useWorkspaces()\n const {projectId: sourceProjectId, dataset: sourceDataset} = originClient.config()\n const workspacesOptions: WorkspaceOption[] = workspaces.map((workspace) => {\n const isSourceWorkspace =\n workspace.projectId === sourceProjectId && workspace.dataset === sourceDataset\n const isAllowedMigration = isAllowedMigrationTarget({\n migrationFilters: pluginConfig.migrationFilters,\n sourceProjectId,\n sourceDataset,\n targetProjectId: workspace.projectId,\n targetDataset: workspace.dataset,\n })\n\n return {\n ...workspace,\n disabled: isSourceWorkspace || !isAllowedMigration,\n }\n })\n\n const currentWorkspace = workspacesOptions.find(\n (workspace) => workspace.projectId === sourceProjectId && workspace.dataset === sourceDataset,\n )\n\n const [destination, setDestination] = useState<WorkspaceOption | null>(\n workspaces.length ? (workspacesOptions.find((space) => !space.disabled) ?? null) : null,\n )\n const [message, setMessage] = useState<Message | null>(null)\n const [payload, setPayload] = useState<PayloadItem[]>([])\n\n const [isDuplicating, setIsDuplicating] = useState(false)\n const [isGathering, setIsGathering] = useState(false)\n const [progress, setProgress] = useState<[number, number]>([0, 0])\n\n // References found in the initial docs\n const initialRefsCount = useMemo(\n () => docs.reduce((acc, doc) => acc + extractWithPath(`.._ref`, doc).length, 0),\n [docs],\n )\n const hasReferences = initialRefsCount > 0\n const initialMessage: Message | null = hasReferences\n ? {tone: `caution`, text: createInitialMessage(docs.length, initialRefsCount)}\n : null\n const displayMessage = message ?? initialMessage\n\n // Check if payload documents exist at destination\n async function updatePayloadStatuses(payloadActual: PayloadItem[], dest: WorkspaceOption | null) {\n if (!payloadActual.length || !dest?.name) {\n return\n }\n\n const payloadIds = payloadActual.map(({doc}) => doc._id)\n const destinationClient = originClient.withConfig({\n dataset: dest.dataset,\n projectId: dest.projectId,\n })\n const destinationData = await destinationClient.fetch<SanityDocument[]>(\n `*[_id in $payloadIds]{ _id, _updatedAt }`,\n {payloadIds},\n )\n // Index the destination docs by `_id` so status updates stay O(n) instead\n // of O(n²) when looking them up for each payload item below.\n const destinationById = new Map(destinationData.map((doc) => [doc._id, doc]))\n\n setPayload(\n payloadActual.map((item) => {\n const existingDoc = destinationById.get(item.doc._id)\n let status: keyof MessageTypes = 'CREATE'\n\n if (existingDoc?._updatedAt && item.doc._updatedAt) {\n if (existingDoc._updatedAt === item.doc._updatedAt) {\n // Exact same document exists at destination\n // We don't compare by _rev because that is updated in a transaction\n status = `EXISTS`\n } else {\n status =\n new Date(existingDoc._updatedAt) > new Date(item.doc._updatedAt)\n ? // Document at destination is newer\n `OVERWRITE`\n : // Document at destination is older\n `UPDATE`\n }\n }\n\n return {...item, status}\n }),\n )\n }\n\n // Build the initial payload and check statuses at the current destination\n const initializePayload = useEffectEvent((nextDocs: SanityDocument[]) => {\n const initialPayload: PayloadItem[] = nextDocs.map((doc) => ({include: true, doc}))\n updatePayloadStatuses(initialPayload, destination).catch(console.error)\n })\n\n // Sync the payload with the docs prop and the destination dataset.\n // setPayload only runs after fetching document statuses from the\n // destination resolves, not synchronously within the effect.\n // See: https://github.com/facebook/react/issues/34743\n useEffect(() => {\n // oxlint-disable-next-line react/set-state-in-effect\n initializePayload(docs)\n }, [docs])\n\n function handleCheckbox(_id: string) {\n setPayload((current) =>\n current.map((item) => (item.doc._id === _id ? {...item, include: !item.include} : item)),\n )\n }\n\n // Find and recursively follow references beginning with this document\n async function handleReferences() {\n setIsGathering(true)\n\n try {\n const docIds = docs.map((doc) => doc._id)\n\n const payloadDocs = await getDocumentsInArray({\n fetchIds: docIds,\n client: originClient,\n pluginConfig,\n })\n const draftDocs = await getDocumentsInArray({\n fetchIds: docIds.map((id) => `drafts.${id}`),\n client: originClient,\n projection: `{_id}`,\n pluginConfig,\n })\n const draftDocsIds = new Set(draftDocs.map(({_id}) => _id))\n\n // Shape it up\n const payloadShaped: PayloadItem[] = payloadDocs.map((doc) => ({\n doc,\n // Include this in the transaction?\n include: true,\n // Does it exist at the destination?\n status: undefined,\n // Does it have any drafts?\n hasDraft: draftDocsIds.has(`drafts.${doc._id}`),\n }))\n\n setPayload(payloadShaped)\n updatePayloadStatuses(payloadShaped, destination).catch(console.error)\n } catch (err) {\n console.error(err)\n }\n\n setIsGathering(false)\n }\n\n // Duplicate payload to destination dataset\n async function handleDuplicate() {\n if (!destination) {\n return\n }\n\n setIsDuplicating(true)\n\n const assetsCount = payload.filter(({doc, include}) => include && isAssetId(doc._id)).length\n let currentProgress = 0\n setProgress([currentProgress, assetsCount])\n\n setMessage({text: 'Duplicating...', tone: `transparent`})\n\n const destinationClient = originClient.withConfig({\n apiVersion: pluginConfig.apiVersion,\n dataset: destination.dataset,\n projectId: destination.projectId,\n })\n\n const transactionDocs: SanityDocument[] = []\n const svgMaps: {old: string; new: string}[] = []\n\n // Upload assets and then add to transaction\n async function processDoc(doc: SanityDocument): Promise<void> {\n if (!isAssetDocument(doc)) {\n transactionDocs.push(doc)\n\n return\n }\n\n // Download and upload asset\n // Get the *original* image with this dlRaw param to create the same deterministic _id\n const typeIsFile = isSanityFileAsset(doc)\n const downloadUrl = typeIsFile ? doc.url : `${doc.url}?dlRaw=true`\n\n const res = await fetch(downloadUrl, assetDownloadInit(downloadUrl, token, typeIsFile))\n\n // Fail fast instead of uploading an error response (e.g. 401/403/404)\n // body as the asset's binary data.\n if (!res.ok) {\n throw new Error(\n `Failed to download asset \"${doc.originalFilename ?? doc._id}\" (${res.status} ${res.statusText})`,\n )\n }\n\n const assetData = await res.blob()\n\n const options = {filename: doc.originalFilename}\n const assetDoc = await destinationClient.assets.upload(\n typeIsFile ? `file` : `image`,\n assetData,\n options,\n )\n\n // SVG _id's need remapping before transaction\n if (doc.extension === 'svg') {\n svgMaps.push({old: doc._id, new: assetDoc._id})\n }\n\n // Merge the original asset document's editorial metadata (e.g. `altText`,\n // `title`) — which the upload response omits — with the canonical fields of\n // the freshly uploaded asset (`_id`, `url`, `path`, `assetId`, `sha1hash`,\n // ...). The uploaded values win, so `url`/`path` no longer reference the\n // origin dataset. For SVGs the uploaded `_id` differs from the source\n // (the file is sanitized on upload), so pushing a single merged document at\n // the new `_id` — and remapping references to it below — avoids leaving an\n // orphaned asset document behind at the original `_id`.\n transactionDocs.push({...doc, ...assetDoc})\n\n currentProgress += 1\n setMessage({\n text: `Duplicating ${currentProgress}/${assetsCount} Assets`,\n tone: 'default',\n })\n setProgress([currentProgress, assetsCount])\n }\n\n try {\n const payloadIncludedDocs = payload.filter((item) => item.include).map((item) => item.doc)\n\n // Promises are limited to three at once\n await mapWithConcurrency(payloadIncludedDocs, 3, processDoc)\n } catch (err) {\n console.error(err)\n setIsDuplicating(false)\n setProgress([0, 0])\n setMessage({\n tone: 'critical',\n text: err instanceof Error ? err.message : `Duplication Failed`,\n })\n\n return\n }\n\n // Remap SVG references to new _id's. SVG assets are sanitized on upload, so\n // their `_id` changes; references still pointing at the original `_id` must\n // be updated to the uploaded one.\n const svgIdRemap = new Map(svgMaps.map(({old, new: next}) => [old, next]))\n const transactionDocsMapped =\n svgIdRemap.size === 0\n ? transactionDocs\n : transactionDocs.map((doc) => {\n const references = extractWithPath(`.._ref`, doc)\n\n if (!references.length) {\n return doc\n }\n\n // Clone lazily before the first mutation: some of these docs are the\n // same objects held in React state (`payload`), and `dset` mutates in\n // place — which would corrupt state and trip up the React Compiler.\n let mappedDoc = doc\n\n references.forEach((ref) => {\n const newRefValue =\n typeof ref.value === 'string' ? svgIdRemap.get(ref.value) : undefined\n\n if (newRefValue) {\n if (mappedDoc === doc) {\n mappedDoc = structuredClone(doc)\n }\n\n dset(mappedDoc, ref.path.join('.'), newRefValue)\n }\n })\n\n return mappedDoc\n })\n\n // Create transaction\n const transaction = destinationClient.transaction()\n\n transactionDocsMapped.forEach((doc) => {\n transaction.createOrReplace(doc)\n })\n\n const onCommitSuccess = () => {\n updatePayloadStatuses(payload, destination).catch(console.error)\n }\n\n try {\n await transaction.commit()\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n\n onCommitSuccess()\n } catch (err) {\n if (isReferenceMutationError(err)) {\n await handleReferenceError({\n err,\n transactionDocs: transactionDocsMapped,\n originClient,\n destinationClient,\n pluginConfig,\n token,\n setMessage,\n onSuccess: onCommitSuccess,\n excludedIds: new Set(payload.filter((item) => !item.include).map((item) => item.doc._id)),\n svgMaps,\n })\n } else {\n const description = getErrorDescription(err)\n setMessage({\n tone: 'critical',\n text: description || `Duplication Failed`,\n })\n }\n }\n\n setIsDuplicating(false)\n setProgress([0, 0])\n if (onDuplicated) {\n try {\n await onDuplicated()\n } catch (error) {\n const text = error instanceof Error ? error.message : String(error)\n setMessage({tone: 'critical', text: `Error in onDuplicated hook: ${text}`})\n }\n }\n }\n\n function handleChange(e: ChangeEvent<HTMLSelectElement>) {\n if (!workspacesOptions.length) {\n return\n }\n\n const targeted = workspacesOptions.find((space) => space.name === e.currentTarget.value)\n\n if (targeted) {\n setDestination(targeted)\n updatePayloadStatuses(payload, targeted).catch(console.error)\n }\n }\n\n const payloadCount = payload.length\n const firstSvgIndex = payload.findIndex(({doc}) => doc['extension'] === 'svg')\n const selectedDocumentsCount = payload.filter(\n (item) => item.include && !isAssetId(item.doc._id),\n ).length\n const selectedAssetsCount = payload.filter(\n (item) => item.include && isAssetId(item.doc._id),\n ).length\n const selectedTotal = selectedDocumentsCount + selectedAssetsCount\n const destinationTitle = destination?.title ?? destination?.name\n const hasMultipleProjectIds =\n new Set(workspacesOptions.map((space) => space?.projectId).filter(Boolean)).size > 1\n\n const headingText = [selectedTotal, `/`, payloadCount, `Documents and Assets selected`].join(` `)\n\n const buttonTextParts = [`Duplicate`]\n\n if (selectedDocumentsCount > 0) {\n buttonTextParts.push(\n String(selectedDocumentsCount),\n selectedDocumentsCount === 1 ? `Document` : `Documents`,\n )\n }\n\n if (selectedAssetsCount > 0) {\n // Only join with \"and\" when documents are also part of the selection.\n if (selectedDocumentsCount > 0) {\n buttonTextParts.push(`and`)\n }\n\n buttonTextParts.push(\n String(selectedAssetsCount),\n selectedAssetsCount === 1 ? `Asset` : `Assets`,\n )\n }\n\n if (originClient.config().projectId !== destination?.projectId) {\n buttonTextParts.push(`between Projects`)\n }\n\n buttonTextParts.push(`to`, String(destinationTitle))\n\n const buttonText = buttonTextParts.join(` `)\n\n if (workspacesOptions.length < 2) {\n return (\n <Feedback tone=\"critical\">\n <code>sanity.config.ts</code> must contain at least two Workspaces to use this plugin.\n </Feedback>\n )\n }\n\n if (!destination) {\n return (\n <Feedback tone=\"critical\">\n No allowed Migration destinations are available for this Dataset. Check the{' '}\n <code>migrationFilters</code> plugin config, or add another Workspace as a valid target.\n </Feedback>\n )\n }\n\n return (\n <Container width={1}>\n <Card border>\n <Stack>\n <Card padding={4} style={stickyStyles(isDarkMode)}>\n <Stack gap={4}>\n <Flex gap={3}>\n <Stack style={{flex: 1}} gap={3}>\n <Label>Duplicate from</Label>\n <Select readOnly value={currentWorkspace?.name}>\n {currentWorkspace ? (\n <option value={currentWorkspace.name}>\n {currentWorkspace.title ?? currentWorkspace.name}\n {hasMultipleProjectIds ? ` (${currentWorkspace.projectId})` : ``}\n </option>\n ) : null}\n </Select>\n </Stack>\n <Box padding={4} paddingTop={5} paddingBottom={0}>\n <Text size={3}>\n <ArrowRightIcon />\n </Text>\n </Box>\n <Stack style={{flex: 1}} gap={3}>\n <Label>To Destination</Label>\n <Select onChange={handleChange}>\n {workspacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.projectId})` : ``}\n {currentWorkspace?.name === space.name &&\n currentWorkspace.projectId === space.projectId\n ? ` (Current)`\n : ``}\n </option>\n ))}\n </Select>\n </Stack>\n </Flex>\n\n {isDuplicating && (\n <Card border radius={2}>\n <Card\n style={{\n width: '100%',\n // Guard against a 0-asset payload (progress[1] === 0),\n // which would make the ratio NaN and produce an invalid transform.\n transform: `scaleX(${progress[1] > 0 ? progress[0] / progress[1] : 0})`,\n transformOrigin: 'left',\n transition: 'transform .2s ease',\n boxSizing: 'border-box',\n }}\n padding={1}\n tone=\"positive\"\n />\n </Card>\n )}\n {payload.length > 0 && (\n <>\n <Label>{headingText}</Label>\n <SelectButtons payload={payload} setPayload={setPayload} />\n </>\n )}\n </Stack>\n </Card>\n <Card borderTop padding={4}>\n <Stack gap={3}>\n {displayMessage && (\n <Card padding={3} radius={2} shadow={1} tone={displayMessage.tone}>\n <Text size={1}>{displayMessage.text}</Text>\n </Card>\n )}\n {payload.length > 0 ? (\n <Stack>\n {payload.map(({doc, include, status, hasDraft}, index) => {\n const schemaType = schema.get(doc._type)\n\n return (\n <Fragment key={doc._id}>\n <Flex align=\"center\">\n <Checkbox checked={include} onChange={() => handleCheckbox(doc._id)} />\n <Box flex={1} paddingX={3}>\n {schemaType ? (\n <Preview value={doc} schemaType={schemaType} />\n ) : (\n <Card tone=\"caution\">Invalid schema type</Card>\n )}\n </Box>\n <Flex align=\"center\" gap={2}>\n {hasDraft ? <StatusBadge status=\"UNPUBLISHED\" isAsset={false} /> : null}\n <StatusBadge status={status} isAsset={isAssetId(doc._id)} />\n </Flex>\n </Flex>\n {doc['extension'] === 'svg' && index === firstSvgIndex && (\n <Card padding={3} radius={2} shadow={1} tone=\"caution\">\n <Text size={1}>\n Due to how SVGs are sanitized after first uploaded, duplicated SVG\n assets may have new <code>_id</code>'s at the destination. The newly\n generated <code>_id</code> will be the same in each duplication, but\n it will never be the same <code>_id</code> as the first time this\n Asset was uploaded. References to the asset will be updated to use the\n new <code>_id</code>.\n </Text>\n </Card>\n )}\n </Fragment>\n )\n })}\n </Stack>\n ) : (\n <Flex padding={4} align=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n )}\n <Stack gap={2}>\n {hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={() => void handleReferences()}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )}\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={() => void handleDuplicate()}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n </Stack>\n </Stack>\n </Card>\n </Stack>\n </Card>\n </Container>\n )\n}\n","import {Button, Stack, Box, Label, Text, Card, Flex, Grid, Container, TextInput} from '@sanity/ui'\nimport {type SubmitEvent, useState} from 'react'\nimport {useSchema, useClient, type SanityDocument} from 'sanity'\n\nimport type {PluginConfig} from '../types'\nimport Duplicator from './Duplicator'\n\ntype DuplicatorQueryProps = {\n token: string\n pluginConfig: Required<PluginConfig>\n}\n\ntype InitialData = {\n docs: SanityDocument[]\n}\n\nexport default function DuplicatorQuery(props: DuplicatorQueryProps) {\n const {token, pluginConfig} = props\n\n const {queries: preDefinedQueries, apiVersion} = pluginConfig\n const originClient = useClient({apiVersion})\n\n const schema = useSchema()\n const schemaTypes = schema.getTypeNames()\n\n const [value, setValue] = useState(``)\n const [fetched, setFetched] = useState(false)\n const [initialData, setInitialData] = useState<InitialData>({\n docs: [],\n })\n\n async function runQuery() {\n try {\n const res = await originClient.fetch<SanityDocument[]>(value)\n\n // Ensure queried docs are registered to the schema\n const registeredAndPublishedDocs = res.length\n ? res\n .filter((doc) => schemaTypes.includes(doc._type))\n .filter((doc) => !doc._id.startsWith(`drafts.`))\n : []\n\n setInitialData({\n docs: registeredAndPublishedDocs,\n })\n setFetched(true)\n } catch (err) {\n console.error(err)\n }\n }\n\n function handleSubmit(e?: SubmitEvent<HTMLFormElement>) {\n if (e) e.preventDefault()\n void runQuery()\n }\n\n return (\n <Card padding={[0, 0, 0, 5]}>\n <Container>\n <Grid gridTemplateColumns={[1, 1, 1, 2]} gap={[1, 1, 1, 4]}>\n <Box padding={[2, 2, 2, 0]}>\n <Card padding={4} radius={3} border>\n <Stack gap={4}>\n <Box>\n <Label>Initial Documents Query</Label>\n </Box>\n <Box>\n <Text>\n Start with a valid GROQ query to load initial documents. The query will need to\n return an Array of Objects. Drafts will be removed from the results.\n </Text>\n </Box>\n <form onSubmit={handleSubmit}>\n <Flex>\n <Box flex={1} paddingRight={2}>\n <TextInput\n style={{fontFamily: 'monospace'}}\n fontSize={2}\n onChange={(event) => setValue(event.currentTarget.value)}\n padding={4}\n placeholder={`*[_type == \"article\"]`}\n value={value ?? ``}\n />\n </Box>\n <Button\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => handleSubmit()}\n text=\"Query\"\n disabled={!value}\n />\n </Flex>\n </form>\n </Stack>\n </Card>\n {preDefinedQueries && preDefinedQueries?.length > 0 && (\n <Card marginTop={2} padding={4} radius={3} border>\n <Box>\n <Stack gap={4}>\n <Box>\n <Label>Predefined Queries</Label>\n </Box>\n <Stack gap={2}>\n {preDefinedQueries.map((query) => (\n <Button\n key={query.label.replace(/\\s+/g, '-')}\n padding={2}\n paddingX={4}\n tone=\"primary\"\n onClick={() => setValue(`*[${query.query}]`)}\n text={query.label}\n />\n ))}\n </Stack>\n </Stack>\n </Box>\n </Card>\n )}\n </Box>\n {fetched && initialData.docs.length < 1 && (\n <Container width={1}>\n <Card padding={5}>\n {value ? `No documents match this query` : `Start with a valid GROQ query`}\n </Card>\n </Container>\n )}\n {initialData.docs?.length > 0 && (\n <Duplicator docs={initialData.docs} token={token} pluginConfig={pluginConfig} />\n )}\n </Grid>\n </Container>\n </Card>\n )\n}\n","import {Grid, Card, Container, Button} from '@sanity/ui'\nimport {useState, useEffect} from 'react'\nimport {type SanityDocument, useClient} from 'sanity'\n\nimport type {DuplicatorProps} from './Duplicator'\nimport Duplicator from './Duplicator'\n\nexport default function DuplicatorWrapper(props: DuplicatorProps) {\n const {docs, token, pluginConfig, onDuplicated} = props\n const [inbound, setInbound] = useState<SanityDocument[]>([])\n const {follow, apiVersion} = pluginConfig\n\n // Make the first mode the default if there's only one\n const [mode, setMode] = useState<'inbound' | 'outbound'>(\n follow.length === 1 ? (follow[0] ?? 'outbound') : 'outbound',\n )\n const client = useClient({apiVersion})\n\n // \"Inbound\" will start with all documents that reference the first one\n // And then you can gather \"Outbound\" references thereafter\n useEffect(() => {\n async function fetchInbound() {\n const firstDocId = docs[0]?._id\n\n if (!follow.includes(`inbound`) || !firstDocId) {\n return\n }\n\n const inboundReferences = await client.fetch<SanityDocument[]>(`*[references($id)]`, {\n id: firstDocId,\n })\n setInbound([...docs, ...inboundReferences])\n }\n\n fetchInbound().catch(console.error)\n }, [client, docs, follow])\n\n return (\n <Container>\n {follow.length > 1 && (follow.includes(`inbound`) || follow.includes(`outbound`)) ? (\n <Card paddingX={4} paddingBottom={4} marginBottom={4} borderBottom>\n <Grid gridTemplateColumns={2} gap={4}>\n {follow.includes(`outbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'outbound'}\n onClick={() => setMode('outbound')}\n text=\"Outbound\"\n />\n ) : null}\n {follow.includes(`inbound`) ? (\n <Button\n mode=\"ghost\"\n tone=\"primary\"\n selected={mode === 'inbound'}\n onClick={() => setMode('inbound')}\n disabled={inbound.length === 0}\n text={inbound.length > 0 ? `Inbound (${inbound.length})` : 'No inbound references'}\n />\n ) : null}\n </Grid>\n </Card>\n ) : null}\n <Duplicator\n docs={mode === 'outbound' ? docs : inbound}\n token={token}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />\n </Container>\n )\n}\n","import {Button, Flex} from '@sanity/ui'\nimport {useCallback} from 'react'\nimport {useClient} from 'sanity'\n\nimport {SECRET_NAMESPACE} from '../helpers/constants'\n\ntype ResetSecretProps = {\n apiVersion: string\n}\n\nexport default function ResetSecret({apiVersion}: ResetSecretProps) {\n const client = useClient({apiVersion})\n\n const handleClick = useCallback(() => {\n client.delete({query: `*[_id == \"secrets.${SECRET_NAMESPACE}\"]`}).catch(console.error)\n }, [client])\n\n return (\n <Flex align=\"center\" justify=\"flex-end\" paddingX={[2, 2, 2, 5]} paddingY={5}>\n <Button\n text=\"Reset Secret\"\n onClick={handleClick}\n mode=\"ghost\"\n tone=\"critical\"\n fontSize={1}\n padding={2}\n />\n </Flex>\n )\n}\n","import {useSecrets, SettingsView} from '@sanity/studio-secrets'\nimport {Flex, Box, Spinner} from '@sanity/ui'\nimport type {SanityDocument} from 'sanity'\n\nimport {useCrossDatasetDuplicatorConfig} from '../context/ConfigProvider'\nimport {SECRET_NAMESPACE} from '../helpers/constants'\nimport DuplicatorQuery from './DuplicatorQuery'\nimport DuplicatorWrapper from './DuplicatorWrapper'\nimport Feedback from './Feedback'\nimport ResetSecret from './ResetSecret'\n\n// Check for auth secret (required for asset uploads)\nconst secretConfigKeys = [\n {\n key: 'bearerToken',\n title:\n 'An API token with Viewer permissions is required to duplicate the original files of assets, and will be used for all Duplications. Create one at sanity.io/manage',\n description: '',\n },\n]\n\ntype Secrets = {\n bearerToken?: string\n}\n\ntype CrossDatasetDuplicatorProps = {\n mode: 'tool' | 'action'\n docs: SanityDocument[]\n onDuplicated?: () => Promise<void>\n}\n\nexport default function CrossDatasetDuplicator(props: CrossDatasetDuplicatorProps) {\n const {mode, docs, onDuplicated} = props\n const pluginConfig = useCrossDatasetDuplicatorConfig()\n\n const {loading, secrets} = useSecrets<Secrets>(SECRET_NAMESPACE)\n\n if (loading) {\n return (\n <Flex justify=\"center\" align=\"center\">\n <Box padding={5}>\n <Spinner />\n </Box>\n </Flex>\n )\n }\n\n // A bearer token is required to duplicate assets, so the prompt cannot be\n // dismissed until one is saved\n if (!secrets?.bearerToken) {\n return (\n <SettingsView\n title=\"Token Required\"\n namespace={SECRET_NAMESPACE}\n keys={secretConfigKeys}\n onClose={() => null}\n />\n )\n }\n\n if (mode === 'tool' && pluginConfig) {\n return (\n <>\n <DuplicatorQuery token={secrets.bearerToken} pluginConfig={pluginConfig} />\n <ResetSecret apiVersion={pluginConfig.apiVersion} />\n </>\n )\n }\n\n if (!docs?.length) {\n return <Feedback>No docs passed into Duplicator Tool</Feedback>\n }\n\n if (!pluginConfig) {\n return <Feedback>No plugin config</Feedback>\n }\n\n return (\n <DuplicatorWrapper\n docs={docs}\n token={secrets.bearerToken}\n pluginConfig={pluginConfig}\n onDuplicated={onDuplicated}\n />\n )\n}\n","import type {CrossDatasetDuplicatorActionProps} from '../types'\nimport CrossDatasetDuplicator from './CrossDatasetDuplicator'\n\n/**\n * Component to perform a migration from the Cross Dataset Duplicator plugin\n * @public\n */\nexport function CrossDatasetDuplicatorAction(props: CrossDatasetDuplicatorActionProps) {\n const {docs, onDuplicated} = props\n\n return <CrossDatasetDuplicator mode=\"action\" docs={docs} onDuplicated={onDuplicated} />\n}\n","import {LaunchIcon} from '@sanity/icons/Launch'\nimport {useState} from 'react'\nimport type {DocumentActionProps} from 'sanity'\n\nimport {CrossDatasetDuplicatorAction} from '../components/CrossDatasetDuplicatorAction'\n\n/**\n * Document action from the Cross Dataset Duplicator plugin\n * @public\n */\nexport const DuplicateToAction = (props: DocumentActionProps) => {\n const {draft, published} = props\n const [dialogOpen, setDialogOpen] = useState(false)\n\n return {\n disabled: Boolean(draft),\n title: draft ? `Document must be Published to begin` : null,\n label: 'Duplicate to...',\n dialog: dialogOpen &&\n published && {\n type: 'modal',\n title: 'Cross Dataset Duplicator',\n content: <CrossDatasetDuplicatorAction docs={[published]} />,\n onClose: () => setDialogOpen(false),\n },\n onHandle: () => setDialogOpen(true),\n icon: LaunchIcon,\n }\n}\n\nDuplicateToAction.action = 'duplicateTo'\n","import type {SanityDocument, Tool} from 'sanity'\n\nimport CrossDatasetDuplicator from './CrossDatasetDuplicator'\n\nexport type MultiToolConfig = {\n docs: SanityDocument[]\n}\n\ntype CrossDatasetDuplicatorProps = {\n tool: Tool<MultiToolConfig>\n}\n\nexport function CrossDatasetDuplicatorTool(props: CrossDatasetDuplicatorProps) {\n const {docs = []} = props.tool.options ?? {}\n\n return <CrossDatasetDuplicator mode=\"tool\" docs={docs} />\n}\n","import {LaunchIcon} from '@sanity/icons/Launch'\nimport type {Tool} from 'sanity'\n\nimport {\n CrossDatasetDuplicatorTool,\n type MultiToolConfig,\n} from '../components/CrossDatasetDuplicatorTool'\n\nexport const crossDatasetDuplicatorTool = (): Tool<MultiToolConfig> => ({\n title: 'Duplicator',\n name: 'duplicator',\n icon: LaunchIcon,\n component: CrossDatasetDuplicatorTool,\n options: {\n docs: [],\n },\n})\n","import {definePlugin} from 'sanity'\n\nimport {DuplicateToAction} from './actions/DuplicateToAction'\nimport {ConfigProvider} from './context/ConfigProvider'\nimport {DEFAULT_CONFIG} from './helpers/constants'\nimport {crossDatasetDuplicatorTool} from './tool'\nimport type {PluginConfig} from './types'\n\n/**\n * Plugin: Cross Dataset Duplicator\n * @public\n */\nexport const crossDatasetDuplicator = definePlugin<Partial<PluginConfig> | void>((config = {}) => {\n const pluginConfig = {...DEFAULT_CONFIG, ...config}\n const {types} = pluginConfig\n\n return {\n name: '@sanity/cross-dataset-duplicator',\n tools: (prev) => (pluginConfig.tool ? [...prev, crossDatasetDuplicatorTool()] : prev),\n studio: {\n components: {\n layout: (props) => <ConfigProvider {...props} pluginConfig={pluginConfig} />,\n },\n },\n document: {\n actions: (prev, {schemaType}) => {\n return types && types.includes(schemaType) ? [...prev, DuplicateToAction] : prev\n },\n },\n }\n})\n"],"mappings":"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"}
\ No newline at end of file